#include #include #include #include "selections.h" #include "xatoms.h" void selection_get(struct selection_info *si, Display *dpy, Window w, Atom name, Atom type, Time time) { si->state = ss_waiting; si->name = name; si->w = w; XDeleteProperty(dpy, w, name); /* send a selection request */ XConvertSelection( dpy, name, type, name, w, time); } bool selection_process(struct selection_info *si, XEvent *xev, void **buf, int *len) { unsigned long r_items, r_size; unsigned char *r_buffer; switch(xev->type) { case SelectionNotify: if (si->state != ss_waiting) return false; break; case PropertyNotify: if (si->state != ss_waiting_incr && si->state != ss_waiting) return false; if(xev->xproperty.state != PropertyNewValue || xev->xproperty.window != si->w || xev->xproperty.atom != si->name) return false; break; default: return false; } /* find the size and format of the data in property */ int ret = XGetWindowProperty(xev->xany.display, si->w, si->name, 0, ULONG_MAX, True, AnyPropertyType, &si->type, &si->format, &r_items, &r_size, &r_buffer); if(ret != Success) { si->state = ss_error; si->error = "XGetWindowProperty Failed"; fprintf(stderr, "%s\n", si->error); return true; } if (si->type == XA_INCR) { *len = 0; *buf = NULL; if(r_items > 0) { si->state = ss_error; si->error = "INCR of nonzero size seen."; fprintf(stderr, "%s\n", si->error); } else si->state = ss_waiting_incr; XFree(r_buffer); return true; } else si->state = ss_done; /* set the length of the returned data */ *len = r_items; *buf = r_buffer; return true; }