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)
You need to use xcb_input_event_mask_t
and xcb_input_xi_event_mask_t
together, in the following way:
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);
Disclaimer: I have never used this. I have found one single usage example on the 'net here. I tried to verify this usage against the source of xcb_input_xi_select_events
here but its code is expletive deleted unreadable. I have not a slightest idea how exactly people should be able to use this library.
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.
User contributions licensed under CC BY-SA 3.0