freundTech freundTech - 2 months ago 13
C Question

How to register events using libxcb-xinput

I'm trying to listen to touch events (TOUCH_BEGIN, TOUCH_UPDATE, TOUCH_END and TOUCH_OWNERSHIP) on the root window.

Touch events aren't directly integrated into XCB, so I have to use the input extension (libxcb-xinput).

I already managed to set up an event listener for events coming from the input extension, but I can't figure out how to register what events I want to listen to.

I tried using xcb_input_xi_select_events(), however that function takes a parameter of type xcb_input_event_mask_t, while the enum containing the event masks is of type xcb_input_xi_event_mask_t and there is no obvious way to cast them.

For that reason I think that xcb_input_xi_select_events() is the wrong function, but I have no idea what function to use instead.

My non working code currently looks like that:

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);


The core throws a "large integer implicitly truncated to unsigned type" warning at compile time and just a "Failed request: (null), (null): 0x000000D5" error at runtime.

(I'm pretty new to C and especially XCB, so please forgive any obvious errors)

Answer

I found a solution to this.
Big thanks to 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
);

It looks a bit cryptic, but it works.

Comments