Получить состояние кнопки мыши неблокирующим linux - PullRequest
0 голосов
/ 21 апреля 2020

Я пытаюсь написать плагин для игры, и мне нужно прочитать состояние кнопки мыши, а не блокировать или «съедать» события. Непосредственное чтение / dev / input не является опцией из-за доступа root. Чем ближе я подошел к тому, что мне нужно, так это следующий код:

#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;
}

Проблема в том, что, установив GrabModeSyn c и используя XAllowEvents с ReplayPointer, я могу передать событие, но получаю только ButtonPress , ButtonRelease никогда не захватывается, но мне это нужно. GrabModeAsyn c фиксирует оба события, но «съедает» щелчки. Кто-нибудь может предложить решение? 10x

1 Ответ

1 голос
/ 28 апреля 2020

Для тех, кто может наткнуться на этот пост, когда ищет решение по подобной проблеме, вот что сработало для меня.

#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;
}
...