0

私は現在、Linuxの既存のすべてのウィンドウでマウスポインタの動きを監視する必要があるアプリケーションを作成しています。gnomeでUbuntu11.10を使用しています。必要なのは、画面上の任意の場所でのマウスポインタの動きに関する情報を取得することです。これを行うための既存のコードは次のとおりです。

void *MonitorOffline(void *threaddata)
{
    time_t      sTime, cTime;
    DISPLAY     *dsp = NULL;
    int         iError = 0;

    sTime = time(NULL);

    XSetErrorHandler(_invalid_window_handler);
    while (1) {
        XEvent event;
        cTime = time(NULL);
        if ((cTime - sTime) > OFFLINETIME) {
            log_msg("User %s is offline", cuserid(NULL));
            sTime = cTime;
        }
        iError = RegisterWinEvents(&dsp);
        if (iError) {
            log_quit("%s:%d : Error in RegisterWinEvents", __FUNCTION__,
                    __LINE__);
            break;
        }
        XNextEvent(dsp, &event);
        switch(event.type) {
            case KeyPress:
                printf("KeyPress Encountered\n");
                break;
                printf("KeyRelease Encountered\n");

                break;

            case ButtonPress:

                printf("ButtonPress Encountered\n");

                break;

            case ButtonRelease:

                printf("ButtonRelease Encountered\n");

                break;

            case MotionNotify:

                printf("MotionNotify Encountered\n");

                break;

            case EnterNotify:

                printf("EnterNotify Encountered\n");

                break;
            case LeaveNotify:

                printf("LeaveNotify Encountered\n");

                break;

        }
        XCloseDisplay (dsp);
        fflush(stdout);
    }
}

int RegisterWinEvents(DISPLAY   **dsp)
{
    Window window_id;
    char *win_name;
    int iError = 0;
    XSetWindowAttributes attr;
    XWindowAttributes wattr;
    Window root_return, parent_return;
    Window root;
    Window client;
    Window *children_return = NULL;
    unsigned int num_children = 0;
    Status status;
    int i;
    time_t t;

    iError = WDGetRoot(&root, dsp);

    if (iError == -1) {

        return -1;
    }
    status = XQueryTree (*dsp, root, &root_return,
            &parent_return, &children_return,
            &num_children);
    for(i = 0; i < num_children; i++)
    {
        attr.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask |
            ButtonReleaseMask | EnterWindowMask |
            LeaveWindowMask | PointerMotionMask |
            Button1MotionMask |
            Button2MotionMask | Button3MotionMask |
            Button4MotionMask | Button5MotionMask |
            ButtonMotionMask | KeymapStateMask |
            ExposureMask | VisibilityChangeMask |
            StructureNotifyMask | /* ResizeRedirectMask | */
            SubstructureNotifyMask | SubstructureRedirectMask |
            FocusChangeMask | PropertyChangeMask |
            ColormapChangeMask;// | OwnerGrabButtonMask;

        status = XGetWindowAttributes(*dsp, children_return[i], &wattr);
        if (wattr.all_event_masks & ButtonPressMask)
            attr.event_mask &= ~ButtonPressMask;
        attr.event_mask &= ~SubstructureRedirectMask;
        XSelectInput(*dsp, children_return[i], attr.event_mask);
    }
    XFree(children_return);
    return 0;
}

WINDOW WDGetRootWindow(DISPLAY* pDisplay, INT iScreen)
{
    return RootWindow(pDisplay,iScreen);
}

int WDGetRoot(Window *root, DISPLAY **pDisplay)
{
    INT iScreen = 0;
    setlocale(LC_CTYPE, "");

    //Initialize the Display
    if((*pDisplay = WDOpenDisplay(NULL))) {
        //Get the sceen associated with Display
        iScreen = WDGetScreenOfDisplay(*pDisplay);
        //Once we have the screen , we need to get the rootwindow associated
        //with the screen so that we can traverse the window tree and get the
        //window with current focus (the active window)
        *root = WDGetRootWindow(*pDisplay, iScreen);
    } else {
        return -1;
    }
    return 0;
}

上記のコードを使用すると、すべてのウィンドウのタイトルバーでマウスポインターの動きをキャプチャできますが、マウスポインターがウィンドウ内にある場合(たとえば、オフィスライターのテキスト部分など)は動きをキャプチャできません。ウィンドウ全体でマウスの動きをキャプチャするためにコードを追加するには、さらに何を追加する必要がありますか?

4

1 に答える 1

0

XQueiryPointerは、ウィンドウ内の座標を返すことができると主張しています。

XQueryPointer関数は...ルートウィンドウの原点を基準にしたポインター座標を返します。

XQueryTreeへの呼び出しと組み合わせて試してください

于 2012-06-07T13:07:51.677 に答える