Unfortunatelly, many X applications aren't compatible with just UTF8_STRING,
so we'll have to do a little more. The patch below checks COMPOUND_TEXT,
UTF8_STRING and XA_STRING targets. It makes it more complicated and possibly
ugly, but it works...
It would be nice to respond with all three supported types to TARGETS,
I suppose. I'm not sure how to do that correctly, though.
-- Petr
--- st.c | 75 ++++++++++++++++++++++++++++++++++++++++++++---------------------- 1 files changed, 50 insertions(+), 25 deletions(-) diff --git a/st.c b/st.c index a6fb766..61b53b0 100644 --- a/st.c +++ b/st.c @@ -41,6 +41,11 @@ #define DRAW_BUF_SIZ 1024 #define UTF_SIZ 4 +/* Selection requests */ +#define REQ_CTEXT 1 +#define REQ_USTR 2 +#define REQ_STR 3 + #define SERRNO strerror(errno) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) < (b) ? (b) : (a)) @@ -145,6 +150,12 @@ typedef struct { } font, bfont; } DC; +typedef struct { + Atom ctext; + Atom ustr; + Atom str; +} SelectionTargets; + /* TODO: use better name for vars... */ typedef struct { int mode; @@ -152,7 +163,8 @@ typedef struct { int ex, ey; struct {int x, y;} b, e; char *clip; - Atom xtarget; + SelectionTargets tgt; + Atom deftgt; } Selection; #include "config.h" @@ -219,7 +231,7 @@ static void selrequest(XEvent *); static void selinit(void); static inline int selected(int, int); static void selcopy(void); -static void selpaste(void); +static void selpaste(Atom); static int utf8decode(char *, long *); static int utf8encode(long *, char *); @@ -371,9 +383,10 @@ selinit(void) { sel.mode = 0; sel.bx = -1; sel.clip = NULL; - sel.xtarget = XInternAtom(xw.dpy, "UTF8_STRING", 0); - if(sel.xtarget == None) - sel.xtarget = XA_STRING; + sel.tgt.ctext = XInternAtom(xw.dpy, "COMPOUND_TEXT", 0); + sel.tgt.ustr = XInternAtom(xw.dpy, "UTF8_STRING", 0); + sel.tgt.str = XA_STRING; + sel.deftgt = sel.tgt.ctext; } static inline int @@ -439,25 +452,35 @@ selnotify(XEvent *e) { int format; unsigned char *data; Atom type; - - ofs = 0; - do { - if(XGetWindowProperty(xw.dpy, xw.win, XA_PRIMARY, ofs, BUFSIZ/4, - False, AnyPropertyType, &type, &format, - &nitems, &rem, &data)) { - fprintf(stderr, "Clipboard allocation failed\n"); - return; - } - ttywrite((const char *) data, nitems * format / 8); - XFree(data); - /* number of 32-bit chunks returned */ - ofs += nitems * format / 32; - } while(rem > 0); + static int req = REQ_CTEXT; + + if (req == REQ_CTEXT && (*e).xselection.property == None) { + selpaste(sel.tgt.ustr); + req = REQ_USTR; + } else if (req == REQ_USTR && (*e).xselection.property == None) { + selpaste(sel.tgt.str); + req = REQ_STR; + } else { + ofs = 0; + do { + if(XGetWindowProperty(xw.dpy, xw.win, XA_PRIMARY, ofs, BUFSIZ/4, + False, AnyPropertyType, &type, &format, + &nitems, &rem, &data)) { + fprintf(stderr, "Clipboard allocation failed\n"); + return; + } + ttywrite((const char *) data, nitems * format / 8); + XFree(data); + /* number of 32-bit chunks returned */ + ofs += nitems * format / 32; + } while(rem > 0); + req = REQ_CTEXT; + } } void -selpaste() { - XConvertSelection(xw.dpy, XA_PRIMARY, sel.xtarget, XA_PRIMARY, xw.win, CurrentTime); +selpaste(Atom target) { + XConvertSelection(xw.dpy, XA_PRIMARY, target, XA_PRIMARY, xw.win, CurrentTime); } void @@ -478,12 +501,14 @@ selrequest(XEvent *e) { xa_targets = XInternAtom(xw.dpy, "TARGETS", 0); if(xsre->target == xa_targets) { /* respond with the supported type */ - Atom string = sel.xtarget; + Atom string = sel.deftgt; XChangeProperty(xsre->display, xsre->requestor, xsre->property, XA_ATOM, 32, PropModeReplace, (unsigned char *) &string, 1); xev.property = xsre->property; - } else if(xsre->target == sel.xtarget) { + } else if(xsre->target == sel.tgt.ctext || + xsre->target == sel.tgt.ustr || + xsre->target == sel.tgt.str) { XChangeProperty(xsre->display, xsre->requestor, xsre->property, xsre->target, 8, PropModeReplace, (unsigned char *) sel.clip, strlen(sel.clip)); @@ -520,7 +545,7 @@ brelease(XEvent *e) { if(sel.bx==sel.ex && sel.by==sel.ey) { sel.bx = -1; if(b==2) - selpaste(); + selpaste(sel.deftgt); } else { if(b==1) selcopy(); @@ -1784,7 +1809,7 @@ kpress(XEvent *ev) { break; case XK_Insert: if(shift) - selpaste(); + selpaste(sel.deftgt); break; case XK_Return: if(IS_SET(MODE_CRLF)) -- 1.7.4Received on Mon Apr 04 2011 - 19:09:25 CEST
This archive was generated by hypermail 2.2.0 : Mon Apr 04 2011 - 19:12:02 CEST