如何使用 libxcb-xinput 注册事件

How to register events using libxcb-xinput

我正在尝试监听根 window 上的触摸事件(TOUCH_BEGIN、TOUCH_UPDATE、TOUCH_END 和 TOUCH_OWNERSHIP)。
触摸事件没有直接集成到 XCB 中,所以我必须使用输入扩展 (libxcb-xinput)。

我已经设法为来自输入扩展的事件设置了一个事件监听器,但我不知道如何注册我想监听的事件。

我尝试使用 xcb_input_xi_select_events(),但是该函数采用 xcb_input_event_mask_t 类型的参数,而包含事件掩码的枚举类型为 xcb_input_ xi_event_mask_t 并且没有明显的方法来转换它们。

出于这个原因,我认为 xcb_input_xi_select_events() 是错误的函数,但我不知道应该使用什么函数。

我的非工作代码目前看起来像这样:

xcb_input_event_mask_t mask[] = {
    XCB_INPUT_XI_EVENT_MASK_TOUCH_BEGIN
    | XCB_INPUT_XI_EVENT_MASK_TOUCH_END
    | XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE
    | XCB_INPUT_XI_EVENT_MASK_TOUCH_OWNERSHIP
};
xcb_input_xi_select_events(dpy, root, 4, mask);

核心在编译时抛出 "large integer implicitly truncated to unsigned type" 警告,在运行时仅抛出 "Failed request: (null), (null): 0x000000D5" 错误。

(我对 C 尤其是 XCB 很陌生,所以请原谅任何明显的错误)

您需要同时使用xcb_input_event_mask_txcb_input_xi_event_mask_t,方法如下:

struct {
    xcb_input_event_mask_t head;      // describes the subsequent xcb_input_xi_event_mask_t (or an array thereof)
    xcb_input_xi_event_mask_t mask;
} mask;

mask.head.deviceid = XCB_INPUT_DEVICE_ALL;
mask.head.mask_len = sizeof(mask.mask) / sizeof(uint32_t);

mask.mask = XCB_INPUT_XI_EVENT_MASK_TOUCH_BEGIN
| XCB_INPUT_XI_EVENT_MASK_TOUCH_END
| XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE
| XCB_INPUT_XI_EVENT_MASK_TOUCH_OWNERSHIP;

xcb_input_xi_select_events(dpy, root, 1, &mask.head);

免责声明:我从未使用过这个。我在 'net here. I tried to verify this usage against the source of xcb_input_xi_select_events here 上找到了一个用法示例,但它的代码 咒骂已删除 不可读。我完全不知道人们应该如何使用这个库。

我找到了解决方法。
非常感谢 https://github.com/eemikula/touchwm

const uint32_t mask[] = {
    XCB_INPUT_XI_EVENT_MASK_TOUCH_BEGIN
    | XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE
    | XCB_INPUT_XI_EVENT_MASK_TOUCH_END
    | XCB_INPUT_XI_EVENT_MASK_TOUCH_OWNERSHIP
};
const uint32_t modifiers[] = {XCB_INPUT_MODIFIER_MASK_ANY};

xcb_input_xi_passive_grab_device(
    dpy, 
    XCB_CURRENT_TIME, 
    root,
    XCB_CURSOR_NONE,
    0, // detail - as used by XIPassiveGrab
    XCB_INPUT_DEVICE_ALL_MASTER,
    1, // num_modifiers
    1, // mask_len
    XCB_INPUT_GRAB_TYPE_TOUCH_BEGIN,
    XCB_INPUT_GRAB_MODE_22_TOUCH,
    XCB_INPUT_GRAB_MODE_22_ASYNC,
    XCB_INPUT_GRAB_OWNER_NO_OWNER,
    mask,
    modifiers
);

它看起来有点神秘,但它确实有效。