0

我正在尝试为游戏编写插件,我需要读取鼠标按钮的状态,而不是阻止或“吃掉”事件。由于 root 访问权限,直接读取 /dev/input 不是一个选项。我越接近我需要的是以下代码:

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


int main (int argc, char **argv)
{
Display *display;
XEvent ev;

display = XOpenDisplay(NULL);
Window window = RootWindow(display, XDefaultScreen(display));

XSelectInput(display, window, ButtonPressMask | ButtonReleaseMask);
XGrabButton(display, Button1, AnyModifier, window, False, ButtonPressMask | ButtonReleaseMask, GrabModeSync, GrabModeAsync, None, None);

while(1) {

XAllowEvents(display, ReplayPointer, CurrentTime);
    if(XCheckTypedEvent(display, ButtonPress ,&ev))
    {
        printf("Button pressed\n");
    }
    else if(XCheckTypedEvent(display, ButtonRelease ,&ev))
    {
        printf("Button relised\n");
    }

}

return 0;
}

问题是,通过设置 GrabModeSync 并将 XAllowEvents 与 ReplayPointer 一起使用,我能够传递事件,但我只能获得 ButtonPress。ButtonRelease 从未被捕获,但我需要它。GrabModeAsync 捕获这两个事件但“吃掉”点击。任何人都可以提出解决方案吗?10倍

4

1 回答 1

1

对于在寻找类似问题的解决方案时可能偶然发现这篇文章的人来说,这对我有用。

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

static void select_events(Display *dpy, Window win)
{
    XIEventMask evmasks[1];
    unsigned char mask1[(XI_LASTEVENT + 7)/8];

    memset(mask1, 0, sizeof(mask1));

    /* select for button and key events from all master devices */
    XISetMask(mask1, XI_RawButtonPress);
    XISetMask(mask1, XI_RawButtonRelease);

    evmasks[0].deviceid = XIAllMasterDevices;
    evmasks[0].mask_len = sizeof(mask1);
    evmasks[0].mask = mask1;

    XISelectEvents(dpy, win, evmasks, 1);
    XFlush(dpy);
}

int main(){
Display *dpy;
XEvent ev;
XIEvent *xi_event;
XIRawEvent *xev;


XGenericEventCookie *cookie = &ev.xcookie;
dpy = XOpenDisplay(NULL);
select_events(dpy, DefaultRootWindow(dpy));
    int count = 0;
    while(1){
       if (XCheckTypedEvent(dpy, GenericEvent ,&ev)){

        if (cookie->type != GenericEvent ||
            !XGetEventData(dpy, cookie)){
            continue;
            }


        xi_event = (XIEvent *) cookie->data;
        xev = (XIRawEvent *) xi_event;
        switch (cookie->evtype) {
            case XI_RawButtonPress:
                printf("Button pressed %d %d\n", xev->detail, ++count);
                break;
            case XI_RawButtonRelease:
                printf("Button released %d %d\n", xev->detail, count);
                break;
            }

        XFreeEventData(dpy, cookie);
        }
    }

    return 1;
}
于 2020-04-28T07:02:46.927 回答