How to register events using libxcb-xinput

3

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)

c
linux
touch
x11
xcb
asked on Stack Overflow Sep 22, 2016 by freundTech

2 Answers

2

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.

answered on Stack Overflow Sep 25, 2016 by n. 'pronouns' m.
2

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.

answered on Stack Overflow Sep 27, 2016 by freundTech

User contributions licensed under CC BY-SA 3.0