All that x11 crap hurts my mind. I just wish some day we can rid off all this and cleanup our apps.
On 04/04/2011, at 19:09, Petr Sabata <psab...@redhat.com> wrote: > 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.4 > >