我正在编写一个纯Xlib应用程序,并希望将XInput2扩展用于RawMotion事件.如果我在设置掩码时使用XISelectEvents,且任何XI2事件大于XI_PropertyEvent,则会出现问题.例如,如果我使用XISetMask(mask, XI_Motion);,它就会正常工作,而不是使用XISetMask(mask, XI_RawMotion);.此外,无论传递的设备ID如何,也不管设置为掩码的其他事件类型如何,错误都会出现.为什么会发生这种事呢?

代码示例:

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

int main() {
    Display* display = XOpenDisplay(nullptr);

    int screen_num = DefaultScreen(display);

    Window window = XCreateSimpleWindow(
            display,
            RootWindow(display, screen_num),
            0, 0,
            640, 480,
            4,
            16711680,
            WhitePixel(display, screen_num)
    );
    XSelectInput(display, window, KeyPressMask);

    int major_opcode, first_event, first_error;
    XQueryExtension(display, "XInputExtension", &major_opcode, &first_event, &first_error);

    unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {0, };
    XISetMask(mask, XI_RawMotion);

    XIEventMask event_mask;
    event_mask.deviceid = XIAllDevices;
    event_mask.mask_len = sizeof(mask);
    event_mask.mask = mask;

    XISelectEvents(display, window, &event_mask, 1);

    XMapWindow(display, window);
    XFlush(display);

    while (true) {
        XEvent ev;
        XNextEvent(display, &ev);
        if (ev.type == KeyPress && ev.xkey.keycode == 9) {
            break;
        }
    }
    XUnmapWindow(display, window);
    XFlush(display);
    XDestroyWindow(display, window);
    XCloseDisplay(display);
    return 0;
}

错误:

X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  131 (XInputExtension)
  Minor opcode of failed request:  46 ()
  Value in failed request:  0xd
  Serial number of failed request:  16
  Current serial number in output stream:  17

推荐答案

问题是,带有原始事件的XInput2调用XISelectEvents只有在传递根窗口时才起作用.因此,解决方案是使用XISelectEvents(display, DefaultRootWindow(display), &event_mask, 1);

C++相关问答推荐

如何在C中只使用一个带双方括号([i][j])访问语法的malloc来分配动态大小的2d数组?

将指针作为参数传递给函数

如何在C中引发/处理自定义信号?

限制不同类型的限定符

Vcpkg的配置文件

处理来自浏览器的HTTP请求

当内存来自Malloc时,将char*转换为另一个指针类型是否违反了严格的别名规则?

试图创建一个基本的Word克隆,但遇到了障碍

为什么这个分配做得不好呢?

C语言中浮点数的取整方式浮点数尾数超过23位时如何取整剩余部分

为什么我在C代码中得到一个不完整的类型?

如何将大写/小写土耳其字母相互转换?

在C程序中使用Beaglebone Black UART的问题

向左移位3如何得到以字节为单位的位数?

Linux/C:带有子进程的进程在添加waitid后都挂起

如何在C中处理流水线中的a、n命令?

Malloc和对齐

Ubuntu编译:C中的文件格式无法识别错误

从管道读取数据时丢失

strlen 可以是[[未排序]]吗?