#include <math.h>
#include <errno.h>
#include <assert.h>
+#include <ctype.h>
+
+#include <unistd.h>
#include <X11/X.h>
#include <X11/Intrinsic.h>
/*
* ICCCM-required cut buffer initialisation.
*/
+ static const unsigned char emptystring[] = {0};
XChangeProperty(disp, root, XA_CUT_BUFFER0,
- XA_STRING, 8, PropModeAppend, "", 0);
+ XA_STRING, 8, PropModeAppend, emptystring, 0);
XChangeProperty(disp, root, XA_CUT_BUFFER1,
- XA_STRING, 8, PropModeAppend, "", 0);
+ XA_STRING, 8, PropModeAppend, emptystring, 0);
XChangeProperty(disp, root, XA_CUT_BUFFER2,
- XA_STRING, 8, PropModeAppend, "", 0);
+ XA_STRING, 8, PropModeAppend, emptystring, 0);
XChangeProperty(disp, root, XA_CUT_BUFFER3,
- XA_STRING, 8, PropModeAppend, "", 0);
+ XA_STRING, 8, PropModeAppend, emptystring, 0);
XChangeProperty(disp, root, XA_CUT_BUFFER4,
- XA_STRING, 8, PropModeAppend, "", 0);
+ XA_STRING, 8, PropModeAppend, emptystring, 0);
XChangeProperty(disp, root, XA_CUT_BUFFER5,
- XA_STRING, 8, PropModeAppend, "", 0);
+ XA_STRING, 8, PropModeAppend, emptystring, 0);
XChangeProperty(disp, root, XA_CUT_BUFFER6,
- XA_STRING, 8, PropModeAppend, "", 0);
+ XA_STRING, 8, PropModeAppend, emptystring, 0);
XChangeProperty(disp, root, XA_CUT_BUFFER7,
- XA_STRING, 8, PropModeAppend, "", 0);
+ XA_STRING, 8, PropModeAppend, emptystring, 0);
/*
* Rotate the cut buffers and add our text in CUT_BUFFER0.
*/
}
Atom convert_sel_outer(Window requestor, Atom target, Atom property) {
+ /*
+ * ICCCM 2.2 says that obsolete clients requesting the selection
+ * request may not specify a property name under which they want
+ * the data written to their window; selection owners are
+ * encouraged to support such clients by reusing the selection
+ * target name as the property.
+ */
+ if (property == None)
+ property = target;
+
if (target == multiple_atom) {
/*
* Support for the MULTIPLE selection type, since it's
int size = sel_delta;
Atom actual_type;
int actual_format, i;
- long nitems, bytes_after, nread;
+ unsigned long nitems, bytes_after, nread;
unsigned char *data;
Atom *adata;
adata = (Atom *)data;
- for (i = 0; i+1 < nitems; i += 2) {
+ for (i = 0; i+1 < (long)nitems; i += 2) {
if (adata[i+1] != (Atom)None) /* ICCCM says this isn't allowed */
adata[i+1] = convert_sel_inner(requestor, adata[i],
adata[i+1]);
return;
}
} else {
+ int have_ownership = True;
+
switch (ev.type) {
case SelectionClear:
/* Selection has been cleared by another app. */
- return;
+ have_ownership = False;
+ break;
case SelectionRequest:
- e2.xselection.type = SelectionNotify;
- e2.xselection.requestor = ev.xselectionrequest.requestor;
- e2.xselection.selection = ev.xselectionrequest.selection;
- e2.xselection.target = ev.xselectionrequest.target;
- e2.xselection.time = ev.xselectionrequest.time;
- e2.xselection.property =
- convert_sel_outer(ev.xselectionrequest.requestor,
- ev.xselectionrequest.target,
- ev.xselectionrequest.property);
- XSendEvent (disp, ev.xselectionrequest.requestor,
- False, 0, &e2);
+ if (have_ownership) {
+ e2.xselection.type = SelectionNotify;
+ e2.xselection.requestor = ev.xselectionrequest.requestor;
+ e2.xselection.selection = ev.xselectionrequest.selection;
+ e2.xselection.target = ev.xselectionrequest.target;
+ e2.xselection.time = ev.xselectionrequest.time;
+ e2.xselection.property =
+ convert_sel_outer(ev.xselectionrequest.requestor,
+ ev.xselectionrequest.target,
+ ev.xselectionrequest.property);
+ XSendEvent (disp, ev.xselectionrequest.requestor,
+ False, 0, &e2);
+ }
break;
case PropertyNotify:
for (i = j = 0; i < nincrs; i++) {
nincrs = j;
break;
}
+ if (nincrs == 0 && !have_ownership)
+ return;
}
}
}
void do_paste(Window window, Atom property, int cutbuffer) {
Atom actual_type;
int actual_format, i;
- long nitems, bytes_after, nread;
+ unsigned long nitems, bytes_after, nread;
unsigned char *data;
int incremental = False;
XEvent ev;