0

クリップボードの選択、つまりプライマリ選択を監視する 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);
}
4

1 に答える 1

0

SelectionNotify イベント フィールドを印刷してみてください。選択が存在しないか、STRING 形式でないため、プロパティが None になっている可能性があります。ウィンドウをクリックするとフォーカスが外れ、一部のアプリがプライマリをドロップする可能性がありますか?

X11 クリップボードは複数のデータ形式をどのように処理しますか? 利用可能な選択を検査するための Python の便利なスニペットかもしれません。

于 2013-07-22T20:33:07.817 に答える