#include #include #include void show_targets(Display *dpy, Window w, Atom p) { Atom type, *targets; int di; unsigned long i, nitems, dul; unsigned char *prop_ret = NULL; char *an = NULL; /* Read the first 1024 atoms from this list of atoms. We don't * expect the selection owner to be able to convert to more than * 1024 different targets. :-) */ XGetWindowProperty(dpy, w, p, 0, 1024 * sizeof(Atom), False, XA_ATOM, &type, &di, &nitems, &dul, &prop_ret); printf("Targets:\n"); targets = (Atom *)prop_ret; for (i = 0; i < nitems; i++) { an = XGetAtomName(dpy, targets[i]); printf(" '%s'\n", an); if (an) XFree(an); } XFree(prop_ret); //XDeleteProperty(dpy, w, p); } void show_utf8_prop(Display *dpy, Window w, Atom p) { Atom da, incr, type; int di; unsigned long size, dul; unsigned char *prop_ret = NULL; /* Dummy call to get type and size. */ XGetWindowProperty(dpy, w, p, 0, 0, False, AnyPropertyType, &type, &di, &dul, &size, &prop_ret); XFree(prop_ret); incr = XInternAtom(dpy, "INCR", False); if (type == incr) { printf("Data too large and INCR mechanism not implemented\n"); return; } /* Read the data in one go. */ printf("Property size: %lu\n", size); XGetWindowProperty(dpy, w, p, 0, size, False, AnyPropertyType, &da, &di, &dul, &dul, &prop_ret); printf("%s", prop_ret); fflush(stdout); XFree(prop_ret); /* Signal the selection owner that we have successfully read the * data. */ XDeleteProperty(dpy, w, p); } int main() { Display *dpy; Window target_window, root; int screen; Atom sel, targets, target_property, utf8; XEvent ev; XSelectionEvent *sev; dpy = XOpenDisplay(NULL); if (!dpy) { fprintf(stderr, "Could not open X display\n"); return 1; } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); sel = XInternAtom(dpy, "CLIPBOARD", False); targets = XInternAtom(dpy, "TARGETS", False); utf8 = XInternAtom(dpy, "UTF8_STRING", False); target_property = XInternAtom(dpy, "PENGUIN", False); target_window = XCreateSimpleWindow(dpy, root, -10, -10, 1, 1, 0, 0, 0); XConvertSelection(dpy, sel, targets, target_property, target_window, CurrentTime); int stage = 0; for (;;) { XNextEvent(dpy, &ev); switch (ev.type) { case SelectionNotify: sev = (XSelectionEvent *)&ev.xselection; if (sev->property == None) { printf("Conversion could not be performed.\n"); return 1; } else { if (stage == 0) { show_targets(dpy, target_window, target_property); /* Request conversion to UTF-8. Not all owners will be able to fulfill that request. */ XConvertSelection(dpy, sel, utf8, target_property, target_window, CurrentTime); stage = 1; } else { show_utf8_prop(dpy, target_window, target_property); return 0; } } break; } } }