diff options
author | Aurélien Aptel <aurelien.aptel@gmail.com> | 2010-10-13 01:24:11 +0200 |
---|---|---|
committer | Aurélien Aptel <aurelien.aptel@gmail.com> | 2010-10-13 01:24:11 +0200 |
commit | d693b304c78708acb911773fe24971ef969d237e (patch) | |
tree | f7fa22eb8a808124d3f4cb58ced79c94ea28384d /st.c | |
parent | 3a50a4fd931ed58454b680c9fc5c1bc2278e67f3 (diff) | |
download | st-d693b304c78708acb911773fe24971ef969d237e.tar.gz st-d693b304c78708acb911773fe24971ef969d237e.zip |
applied xclipboard patch. thx David Isaac Wolinsky.
Diffstat (limited to 'st.c')
-rw-r--r-- | st.c | 130 |
1 files changed, 124 insertions, 6 deletions
@@ -17,6 +17,7 @@ | |||
17 | #include <sys/wait.h> | 17 | #include <sys/wait.h> |
18 | #include <unistd.h> | 18 | #include <unistd.h> |
19 | #include <X11/Xlib.h> | 19 | #include <X11/Xlib.h> |
20 | #include <X11/Xatom.h> | ||
20 | #include <X11/keysym.h> | 21 | #include <X11/keysym.h> |
21 | #include <X11/Xutil.h> | 22 | #include <X11/Xutil.h> |
22 | 23 | ||
@@ -199,7 +200,8 @@ static void focus(XEvent *); | |||
199 | static void brelease(XEvent *); | 200 | static void brelease(XEvent *); |
200 | static void bpress(XEvent *); | 201 | static void bpress(XEvent *); |
201 | static void bmotion(XEvent *); | 202 | static void bmotion(XEvent *); |
202 | 203 | static void selection_notify(XEvent *); | |
204 | static void selection_request(XEvent *); | ||
203 | 205 | ||
204 | static void (*handler[LASTEvent])(XEvent *) = { | 206 | static void (*handler[LASTEvent])(XEvent *) = { |
205 | [KeyPress] = kpress, | 207 | [KeyPress] = kpress, |
@@ -212,6 +214,8 @@ static void (*handler[LASTEvent])(XEvent *) = { | |||
212 | [MotionNotify] = bmotion, | 214 | [MotionNotify] = bmotion, |
213 | [ButtonPress] = bpress, | 215 | [ButtonPress] = bpress, |
214 | [ButtonRelease] = brelease, | 216 | [ButtonRelease] = brelease, |
217 | [SelectionNotify] = selection_notify, | ||
218 | [SelectionRequest] = selection_request, | ||
215 | }; | 219 | }; |
216 | 220 | ||
217 | /* Globals */ | 221 | /* Globals */ |
@@ -278,15 +282,129 @@ static char *getseltext() { | |||
278 | return str; | 282 | return str; |
279 | } | 283 | } |
280 | 284 | ||
281 | /* TODO: use X11 clipboard */ | 285 | static void selection_notify(XEvent *e) { |
286 | unsigned long nitems; | ||
287 | unsigned long length; | ||
288 | int format, res; | ||
289 | unsigned char *data; | ||
290 | Atom type; | ||
291 | |||
292 | res = XGetWindowProperty(xw.dis, xw.win, XA_PRIMARY, 0, 0, False, | ||
293 | AnyPropertyType, &type, &format, &nitems, &length, &data); | ||
294 | switch(res) { | ||
295 | case BadAtom: | ||
296 | case BadValue: | ||
297 | case BadWindow: | ||
298 | fprintf(stderr, "Invalid paste, XGetWindowProperty0"); | ||
299 | return; | ||
300 | } | ||
301 | |||
302 | res = XGetWindowProperty(xw.dis, xw.win, XA_PRIMARY, 0, length, False, | ||
303 | AnyPropertyType, &type, &format, &nitems, &length, &data); | ||
304 | switch(res) { | ||
305 | case BadAtom: | ||
306 | case BadValue: | ||
307 | case BadWindow: | ||
308 | fprintf(stderr, "Invalid paste, XGetWindowProperty0"); | ||
309 | return; | ||
310 | } | ||
311 | |||
312 | if(data) { | ||
313 | ttywrite((const char *) data, nitems * format / 8); | ||
314 | XFree(data); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | static void selpaste() { | ||
319 | XConvertSelection(xw.dis, XA_PRIMARY, XA_STRING, XA_PRIMARY, xw.win, CurrentTime); | ||
320 | } | ||
321 | |||
322 | static void selection_request(XEvent *e) | ||
323 | { | ||
324 | XSelectionRequestEvent *xsre; | ||
325 | XSelectionEvent xev; | ||
326 | int res; | ||
327 | Atom xa_targets; | ||
328 | |||
329 | xsre = (XSelectionRequestEvent *) e; | ||
330 | xev.type = SelectionNotify; | ||
331 | xev.requestor = xsre->requestor; | ||
332 | xev.selection = xsre->selection; | ||
333 | xev.target = xsre->target; | ||
334 | xev.time = xsre->time; | ||
335 | /* reject */ | ||
336 | xev.property = None; | ||
337 | |||
338 | xa_targets = XInternAtom(xw.dis, "TARGETS", 0); | ||
339 | if(xsre->target == xa_targets) { | ||
340 | /* respond with the supported type */ | ||
341 | Atom string = XA_STRING; | ||
342 | res = XChangeProperty(xsre->display, xsre->requestor, xsre->property, XA_ATOM, 32, | ||
343 | PropModeReplace, (unsigned char *) &string, 1); | ||
344 | switch(res) { | ||
345 | case BadAlloc: | ||
346 | case BadAtom: | ||
347 | case BadMatch: | ||
348 | case BadValue: | ||
349 | case BadWindow: | ||
350 | fprintf(stderr, "Error in selection_request, TARGETS"); | ||
351 | break; | ||
352 | default: | ||
353 | xev.property = xsre->property; | ||
354 | } | ||
355 | } else if(xsre->target == XA_STRING) { | ||
356 | res = XChangeProperty(xsre->display, xsre->requestor, xsre->property, | ||
357 | xsre->target, 8, PropModeReplace, (unsigned char *) sel.clip, | ||
358 | strlen(sel.clip)); | ||
359 | switch(res) { | ||
360 | case BadAlloc: | ||
361 | case BadAtom: | ||
362 | case BadMatch: | ||
363 | case BadValue: | ||
364 | case BadWindow: | ||
365 | fprintf(stderr, "Error in selection_request, XA_STRING"); | ||
366 | break; | ||
367 | default: | ||
368 | xev.property = xsre->property; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | /* all done, send a notification to the listener */ | ||
373 | res = XSendEvent(xsre->display, xsre->requestor, True, 0, (XEvent *) &xev); | ||
374 | switch(res) { | ||
375 | case 0: | ||
376 | case BadValue: | ||
377 | case BadWindow: | ||
378 | fprintf(stderr, "Error in selection_requested, XSendEvent"); | ||
379 | } | ||
380 | } | ||
381 | |||
282 | static void selcopy(char *str) { | 382 | static void selcopy(char *str) { |
383 | /* register the selection for both the clipboard and the primary */ | ||
384 | Atom clipboard; | ||
385 | int res; | ||
386 | |||
283 | free(sel.clip); | 387 | free(sel.clip); |
284 | sel.clip = str; | 388 | sel.clip = str; |
285 | } | ||
286 | 389 | ||
287 | static void selpaste() { | 390 | res = XSetSelectionOwner(xw.dis, XA_PRIMARY, xw.win, CurrentTime); |
288 | if(sel.clip) | 391 | switch(res) { |
289 | ttywrite(sel.clip, strlen(sel.clip)); | 392 | case BadAtom: |
393 | case BadWindow: | ||
394 | fprintf(stderr, "Invalid copy, XSetSelectionOwner"); | ||
395 | return; | ||
396 | } | ||
397 | |||
398 | clipboard = XInternAtom(xw.dis, "CLIPBOARD", 0); | ||
399 | res = XSetSelectionOwner(xw.dis, clipboard, xw.win, CurrentTime); | ||
400 | switch(res) { | ||
401 | case BadAtom: | ||
402 | case BadWindow: | ||
403 | fprintf(stderr, "Invalid copy, XSetSelectionOwner"); | ||
404 | return; | ||
405 | } | ||
406 | |||
407 | XFlush(xw.dis); | ||
290 | } | 408 | } |
291 | 409 | ||
292 | /* TODO: doubleclick to select word */ | 410 | /* TODO: doubleclick to select word */ |