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:09:25 CEST
This archive was generated by hypermail 2.2.0 : Mon Apr 04 2011 - 19:12:02 CEST