クリップボードの選択、つまりプライマリ選択を監視する XClient を構築しようとしています。添付のコードでは、実行中の xterm ウィンドウからの選択が十分に取得されています。ただし、他のアプリケーションからの選択の取得は機能しません。私はなぜなのか理解していない。誰でもアドバイスを提供できますか?
(コンパイルには 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);
}