从xterm以外的应用程序中检索选择数据

时间:2013-07-18 12:38:19

标签: selection clipboard xterm x11

我正在尝试构建一个监视剪贴板选择的XClient,即PRIMARY Selection。使用附加的代码,可以令人满意地检索运行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);
}

1 个答案:

答案 0 :(得分:0)

尝试打印出您的SelectionNotify事件字段,也许那里的属性为None,因为选择不存在或者不是STRING格式? 也许点击你的窗口会引起焦点,一些应用程序会丢弃PRIMARY吗?

How does X11 clipboard handle multiple data formats?可能是Python的一个有用的片段,用于检查可用的选择。