aboutsummaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorAurélien Aptel <aurelien.aptel@gmail.com>2010-10-13 01:24:11 +0200
committerAurélien Aptel <aurelien.aptel@gmail.com>2010-10-13 01:24:11 +0200
commitd693b304c78708acb911773fe24971ef969d237e (patch)
treef7fa22eb8a808124d3f4cb58ced79c94ea28384d /st.c
parent3a50a4fd931ed58454b680c9fc5c1bc2278e67f3 (diff)
downloadst-d693b304c78708acb911773fe24971ef969d237e.tar.gz
st-d693b304c78708acb911773fe24971ef969d237e.zip
applied xclipboard patch. thx David Isaac Wolinsky.
Diffstat (limited to 'st.c')
-rw-r--r--st.c130
1 files changed, 124 insertions, 6 deletions
diff --git a/st.c b/st.c
index 5d5ac30..e636b63 100644
--- a/st.c
+++ b/st.c
@@ -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 *);
199static void brelease(XEvent *); 200static void brelease(XEvent *);
200static void bpress(XEvent *); 201static void bpress(XEvent *);
201static void bmotion(XEvent *); 202static void bmotion(XEvent *);
202 203static void selection_notify(XEvent *);
204static void selection_request(XEvent *);
203 205
204static void (*handler[LASTEvent])(XEvent *) = { 206static 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 */ 285static 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
318static void selpaste() {
319 XConvertSelection(xw.dis, XA_PRIMARY, XA_STRING, XA_PRIMARY, xw.win, CurrentTime);
320}
321
322static 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
282static void selcopy(char *str) { 382static 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
287static 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 */