I am trying to build up an XClient that monitors clipboard selections, namely the PRIMARY Selection. With the attached code, the selections from running xterm windows are being retrieved satisfactorily. However retrieving the selections from other applications is never working. I do not understand why. Can anybody offer any advise?
(to compile use gcc -L/usr/X11R6/lib -lX11 [filename.cpp])
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char chr_title[] = { "COM Clipboard XClient" };
int main(int argc, char *argv[]) {
/*declarations */
Display *ads_display;
Window ds_window;
GC ds_gc;
XEvent ds_event;
XSizeHints ds_size_hints;
XWMHints ds_wm_hints;
int iml_screen;
unsigned long ull_foreground, ull_background;
int iml_i;
char chr_text[10];
int iml_done;
Atom ds_property;
/*initialisation*/
ads_display = XOpenDisplay(NULL);
assert(ads_display); //NULL pointer check
iml_screen = DefaultScreen(ads_display);
/* default pixel values */
ull_background = WhitePixel(ads_display, iml_screen);
ull_foreground = BlackPixel(ads_display, iml_screen);
/* default program-specified window position and size */
ds_size_hints.x = 200;
ds_size_hints.y = 300;
ds_size_hints.width = 350;
ds_size_hints.height = 250;
ds_size_hints.flags = PPosition | PSize;
ds_wm_hints.flags = InputHint;
ds_wm_hints.input = True;
fprintf(stderr, "\nCreating Simple Window");
ds_window = XCreateSimpleWindow(ads_display,
DefaultRootWindow(ads_display), ds_size_hints.x, ds_size_hints.y,
ds_size_hints.width, ds_size_hints.height, 5, ull_foreground,
ull_background);
XSetStandardProperties(ads_display, ds_window, chr_title, chr_title, None,
argv, argc, &ds_size_hints);
XSetWMHints(ads_display, ds_window, &ds_wm_hints);
/* GC creation and initialisation */
ds_gc = XCreateGC(ads_display, ds_window, 0, 0);
XSetBackground(ads_display, ds_gc, ull_background);
XSetForeground(ads_display, ds_gc, ull_foreground);
/* input event selection */
XSelectInput(ads_display, ds_window, ButtonPressMask | KeyPressMask
| ExposureMask | PropertyChangeMask);
/* window mapping */
XMapRaised(ads_display, ds_window);
/*main event-reading loop */
iml_done = 0;
while (iml_done == 0) {
/* read the next event */
XNextEvent(ads_display, &ds_event);
switch (ds_event.type) {
/* repaint window on expose events */
case Expose:
if (ds_event.xexpose.count == 0) {
XDrawImageString(ds_event.xexpose.display,
ds_event.xexpose.window, ds_gc, 50, 50, chr_title,
strlen(chr_title));
}
break;
/* process mouse-button presses */
case ButtonPress:
fprintf(stderr, "\nCalling XConvertSelection()...");
XConvertSelection(ads_display, XA_PRIMARY, XA_STRING, None,
ds_window, ds_event.xbutton.time);
XFlush(ads_display);
break;
case SelectionNotify:
fprintf(stderr, "\nSelection Notify Event:");
Atom type;
int format, result;
unsigned long len, bytes_left, dummy;
unsigned char *data;
result = XGetWindowProperty(ads_display, ds_window, XA_STRING, 0, 0, //off, len
0, // Delete 0==FALSE
AnyPropertyType, //flag
&type, // return type
&format, // return format
&len, &bytes_left, //that
&data);
fprintf(stderr, "\nReturn from XGetWindowProperty(): %d.", result);
fprintf(stderr, "\nType:%i Len:%lu Format:%i Byte_left:%lu",
(int) type, len, format, bytes_left);
// DATA is There
if (bytes_left > 0) {
result = XGetWindowProperty(ads_display, ds_window, XA_STRING,
0, bytes_left, 0, AnyPropertyType, &type, &format,
&len, &dummy, &data);
if (result == Success)
fprintf(stderr, "\nDATA:\n%s\n", data);
else
fprintf(stderr, "\nFAIL\n");
XFree(data);
} //end if (bytes_left > 0)
break;
}// end switch (ds_event.type)
} /* while (done == 0) */
/* termination */
XFreeGC(ads_display, ds_gc);
XDestroyWindow(ads_display, ds_window);
XCloseDisplay(ads_display);
exit(0);
}