Re: [dev] [st] Better selection support?

From: pancake <pancake_AT_youterm.com>
Date: Mon, 4 Apr 2011 19:56:02 +0200

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 <psabata_AT_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
>
>
Received on Mon Apr 04 2011 - 19:56:02 CEST

This archive was generated by hypermail 2.2.0 : Mon Apr 04 2011 - 20:00:06 CEST