C 编程:检测鼠标指针移动

C 编程:检测鼠标指针移动

我正在做一个项目,需要仅当鼠标指针在一段时间内(例如 30 秒)没有移动时设置一个标志:如果鼠标空闲了 30 秒,则设置no_movementno_movement=true;)。

到目前为止,我知道 X window 服务器是许多桌面环境的后端,并且我知道在组织tronche.com(我从那里得知有一个名为的指针事件MotionNotify)。

使用apt show xserver-xorg | grep Version我发现我的系统上安装的 Xserver 版本是 1:7.7+22ubuntu1(在 Ubuntu 21.04 上)

获取鼠标指针移动反馈的推荐方法是什么?

感谢您花时间回复我。

答案1

X11 有相当完善的“事件掩码”文档

https://tronche.com/gui/x/xlib/events/mask.html

或者总是有XQueryPointer)..

// Try this C program as the basis of what you want todo..

    #include <stdio.h>
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/extensions/XInput2.h>

int main(int argc, char **argv)
{
    Display *display;
    Window root_window;

    /* Initialize (FIXME: no error checking). */
    display = XOpenDisplay(0);
    root_window = XRootWindow(display, 0);

    /* check XInput */
    int xi_opcode, event, error;
    if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) {
        fprintf(stderr, "Error: XInput extension is not supported!\n");
        return 1;
    }

    /* Check XInput 2.0 */
    int major = 2;
    int minor = 0;
    int retval = XIQueryVersion(display, &major, &minor);
    if (retval != Success) {
        fprintf(stderr, "Error: XInput 2.0 is not supported (ancient X11?)\n");
        return 1;
    }

    /*
     * Set mask to receive XI_RawMotion events. Because it's raw,
     * XWarpPointer() events are not included, you can use XI_Motion
     * instead.
     */
    unsigned char mask_bytes[(XI_LASTEVENT + 7) / 8] = {0};  /* must be zeroed! */
    XISetMask(mask_bytes, XI_RawMotion);

    /* Set mask to receive events from all master devices */
    XIEventMask evmasks[1];
    /* You can use XIAllDevices for XWarpPointer() */
    evmasks[0].deviceid = XIAllMasterDevices;
    evmasks[0].mask_len = sizeof(mask_bytes);
    evmasks[0].mask = mask_bytes;
    XISelectEvents(display, root_window, evmasks, 1);

    XEvent xevent;
    while (1) {
        XNextEvent(display, &xevent);

        if (xevent.xcookie.type != GenericEvent || xevent.xcookie.extension != xi_opcode) {
            /* not an XInput event */
            continue;
        }
        XGetEventData(display, &xevent.xcookie);
        if (xevent.xcookie.evtype != XI_RawMotion) {
            /*
             * Not an XI_RawMotion event (you may want to detect
             * XI_Motion as well, see comments above).
             */
            XFreeEventData(display, &xevent.xcookie);
            continue;
        }
        XFreeEventData(display, &xevent.xcookie);

        Window root_return, child_return;
        int root_x_return, root_y_return;
        int win_x_return, win_y_return;
        unsigned int mask_return;
        /*
         * We need:
         *     child_return - the active window under the cursor
         *     win_{x,y}_return - pointer coordinate with respect to root window
         */
        int retval = XQueryPointer(display, root_window, &root_return, &child_return,
                                   &root_x_return, &root_y_return,
                                   &win_x_return, &win_y_return,
                                   &mask_return);
        if (!retval) {
            /* pointer is not in the same screen, ignore */
            continue;
        }

        /* We used root window as its reference, so both should be the same */
        assert(root_x_return == win_x_return);
        assert(root_y_return == win_y_return);

        printf("root: x %d y %d\n", root_x_return, root_y_return);

        if (child_return) {
            int local_x, local_y;
            XTranslateCoordinates(display, root_window, child_return,
                                  root_x_return, root_y_return,
                                  &local_x, &local_y, &child_return);
            printf("local: x %d y %d\n\n", local_x, local_y);
        }
    }

    XCloseDisplay(display);

    return 0;
}

答案2

您可以使用 Xlib.h,但最重要的是在编译文件中必须输入链接器命令(-lX11)示例:https(gcc a.c -o find -lX11)您可以使用其他编译器,如 gcc、clang、cc 等。

我从以下来源获得信息:

  https://tronche.com/gui/x/xlib/display/display-macros.html
  https://www.x.org/releases/X11R7.5/doc/man/man3/XOpenDisplay.3.html#toc3
  https://www.unix.com/man-page/ultrix/3x11/defaultrootwindow/
  https://tronche.com/gui/x/xlib/window-information/XQueryPointer.html

代码:

#include <X11/Xlib.h>
#include <stdio.h>

int main(void){
        printf("\n GOOD\n******\n");
        Display *win = XOpenDisplay(NULL);
        Window screen = DefaultRootWindow(win);  // to To access the home screen 
        int x, y, winX, winY;
        unsigned int mask;
        Window child;
        XQueryPointer(win, screen, &screen, &child, &x, &y, &winX, &winY, &mask);
        printf("\nx => %d, y => %d\n", x, y);
        XCloseDisplay(win);
    return 0;
}

相关内容