c - 如何使用 Xlib 监控 Linux 中现有窗口上的鼠标指针移动

标签 c xlib

我目前正在编写一个应用程序,需要监视 Linux 中所有现有窗口上的鼠标指针移动。我正在使用带有 gnome 的 Ubuntu 11.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;
}

通过上面的代码,我能够捕获所有窗口标题栏上的鼠标指针移动,但当鼠标指针位于窗口内部时无法捕获任何移动(例如办公室作家的文本部分等)。 我还需要在代码中添加哪些内容才能捕获鼠标在整个窗口中的移动?

最佳答案

XQueiryPointer声称能够返回窗口中的坐标。

The XQueryPointer function returns ... the pointer coordinates relative to the root window's origin.

尝试将其与对 XQueryTree 的调用结合起来

关于c - 如何使用 Xlib 监控 Linux 中现有窗口上的鼠标指针移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10931926/

相关文章:

c - 传递数组时在C中的函数参数中强制数组大小

c++ - 可以检查 ioctl 的权限

c++ - 无法调用结构内部的成员函数指针

windows - 如何将 XLib key 代码转换为 Microsoft 虚拟 key ?

c - Linux 中如何解决库间依赖关系?

C语言可以判断指针指向的内存是否可以访问吗?

c++ - 如何跟踪扩大的圆半径

c++ - XKB - 获取大写锁定掩码

c++ - 使用 X 时减少输入延迟

c++ - Xlib:XGetWindowAttributes 总是返回 1x1?