#include #include #include #include #include /************************************************************************************************************/ /* _ ********************************************************************************************************/ /************************************************************************************************************/ static void _loop (void); static void _init (void); static void _reset (void); static void _event (xcb_ge_generic_event_t *x_ev); /************************************************************************************************************/ /************************************************************************************************************/ /************************************************************************************************************/ static xcb_connection_t *_x_con = NULL; static xcb_screen_t *_x_scr = NULL; static xcb_window_t _x_win = 0; /************************************************************************************************************/ /************************************************************************************************************/ /************************************************************************************************************/ int main(int argc, char **argv) { _init(); _loop(); _reset(); } /************************************************************************************************************/ /* _ ********************************************************************************************************/ /************************************************************************************************************/ static void _event(xcb_ge_generic_event_t *x_ev) { xcb_input_touch_begin_event_t *x_ev_b = (xcb_input_touch_begin_event_t*)x_ev; xcb_input_touch_ownership_event_t *x_ev_o = (xcb_input_touch_ownership_event_t*)x_ev; switch (x_ev->event_type) { case XCB_INPUT_TOUCH_BEGIN: if (x_ev_b->event == _x_win) { printf("begin - %lu\n", x_ev_b->detail); } break; case XCB_INPUT_TOUCH_END: if (x_ev_b->event == _x_win) { printf("end - %lu\n", x_ev_b->detail); } break; case XCB_INPUT_TOUCH_UPDATE: printf("update - %lu\n", x_ev_b->detail); break; case XCB_INPUT_TOUCH_OWNERSHIP: if (x_ev_b->event == _x_win) { printf("ownership - %lu\n", x_ev_o->touchid); } break; } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ static void _init(void) { /* xcb session */ _x_con = xcb_connect(NULL, NULL); _x_scr = xcb_setup_roots_iterator(xcb_get_setup(_x_con)).data; /* xcb window */ uint32_t mask_vals[2]; mask_vals[0] = _x_scr->white_pixel; mask_vals[1] = XCB_EVENT_MASK_EXPOSURE; _x_win = xcb_generate_id(_x_con); xcb_create_window( _x_con, XCB_COPY_FROM_PARENT, _x_win, _x_scr->root, 0, 0, 400, 400, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, _x_scr->root_visual, XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, mask_vals); xcb_map_window(_x_con, _x_win); /* xinput extension */ /* https://lwn.net/Articles/475886/ */ /* https://github.com/freedesktop/xcb-proto/blob/master/src/xinput.xml */ /* thanks you random citizens */ /* https://searchcode.com/file/635605507/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp/ */ /* https://stackoverflow.com/questions/39641675/how-to-register-events-using-libxcb-xinput */ struct { xcb_input_event_mask_t head; xcb_input_xi_event_mask_t mask; } mask; mask.head.deviceid = XCB_INPUT_DEVICE_ALL_MASTER; mask.head.mask_len = 1; 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(_x_con, _x_win, 1, (xcb_input_event_mask_t*)(&mask)); /* end */ xcb_flush(_x_con); } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ static void _loop(void) { xcb_generic_event_t *x_ev; while ((x_ev = xcb_wait_for_event(_x_con))) { switch (x_ev->response_type & ~0x80) { case XCB_EXPOSE: break; case XCB_GE_GENERIC: _event((xcb_ge_generic_event_t*)x_ev); break; } free(x_ev); xcb_flush(_x_con); } } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ static void _reset(void) { xcb_unmap_window(_x_con, _x_win); xcb_destroy_window(_x_con, _x_win); xcb_disconnect(_x_con); }