Little test that I made to figure out how use the Xinput extension of X11 with XCB.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
4.6KB

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <xcb/xcb.h>
  5. #include <xcb/xinput.h>
  6. /************************************************************************************************************/
  7. /* _ ********************************************************************************************************/
  8. /************************************************************************************************************/
  9. static void _loop (void);
  10. static void _init (void);
  11. static void _reset (void);
  12. static void _event (xcb_ge_generic_event_t *x_ev);
  13. /************************************************************************************************************/
  14. /************************************************************************************************************/
  15. /************************************************************************************************************/
  16. static xcb_connection_t *_x_con = NULL;
  17. static xcb_screen_t *_x_scr = NULL;
  18. static xcb_window_t _x_win = 0;
  19. /************************************************************************************************************/
  20. /************************************************************************************************************/
  21. /************************************************************************************************************/
  22. int
  23. main(int argc, char **argv)
  24. {
  25. _init();
  26. _loop();
  27. _reset();
  28. }
  29. /************************************************************************************************************/
  30. /* _ ********************************************************************************************************/
  31. /************************************************************************************************************/
  32. static void
  33. _event(xcb_ge_generic_event_t *x_ev)
  34. {
  35. xcb_input_touch_begin_event_t *x_ev_b = (xcb_input_touch_begin_event_t*)x_ev;
  36. xcb_input_touch_ownership_event_t *x_ev_o = (xcb_input_touch_ownership_event_t*)x_ev;
  37. switch (x_ev->event_type) {
  38. case XCB_INPUT_TOUCH_BEGIN:
  39. if (x_ev_b->event == _x_win) {
  40. printf("begin - %lu\n", x_ev_b->detail);
  41. }
  42. break;
  43. case XCB_INPUT_TOUCH_END:
  44. if (x_ev_b->event == _x_win) {
  45. printf("end - %lu\n", x_ev_b->detail);
  46. }
  47. break;
  48. case XCB_INPUT_TOUCH_UPDATE:
  49. printf("update - %lu\n", x_ev_b->detail);
  50. break;
  51. case XCB_INPUT_TOUCH_OWNERSHIP:
  52. if (x_ev_b->event == _x_win) {
  53. printf("ownership - %lu\n", x_ev_o->touchid);
  54. }
  55. break;
  56. }
  57. }
  58. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  59. static void
  60. _init(void)
  61. {
  62. /* xcb session */
  63. _x_con = xcb_connect(NULL, NULL);
  64. _x_scr = xcb_setup_roots_iterator(xcb_get_setup(_x_con)).data;
  65. /* xcb window */
  66. uint32_t mask_vals[2];
  67. mask_vals[0] = _x_scr->white_pixel;
  68. mask_vals[1] = XCB_EVENT_MASK_EXPOSURE;
  69. _x_win = xcb_generate_id(_x_con);
  70. xcb_create_window(
  71. _x_con,
  72. XCB_COPY_FROM_PARENT,
  73. _x_win,
  74. _x_scr->root,
  75. 0, 0,
  76. 400, 400,
  77. 0,
  78. XCB_WINDOW_CLASS_INPUT_OUTPUT,
  79. _x_scr->root_visual,
  80. XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
  81. mask_vals);
  82. xcb_map_window(_x_con, _x_win);
  83. /* xinput extension */
  84. /* https://lwn.net/Articles/475886/ */
  85. /* https://github.com/freedesktop/xcb-proto/blob/master/src/xinput.xml */
  86. /* thanks you random citizens */
  87. /* https://searchcode.com/file/635605507/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp/ */
  88. /* https://stackoverflow.com/questions/39641675/how-to-register-events-using-libxcb-xinput */
  89. struct {
  90. xcb_input_event_mask_t head;
  91. xcb_input_xi_event_mask_t mask;
  92. } mask;
  93. mask.head.deviceid = XCB_INPUT_DEVICE_ALL_MASTER;
  94. mask.head.mask_len = 1;
  95. mask.mask =
  96. XCB_INPUT_XI_EVENT_MASK_TOUCH_BEGIN |
  97. XCB_INPUT_XI_EVENT_MASK_TOUCH_END |
  98. XCB_INPUT_XI_EVENT_MASK_TOUCH_UPDATE |
  99. XCB_INPUT_XI_EVENT_MASK_TOUCH_OWNERSHIP;
  100. xcb_input_xi_select_events(_x_con, _x_win, 1, (xcb_input_event_mask_t*)(&mask));
  101. /* end */
  102. xcb_flush(_x_con);
  103. }
  104. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  105. static void
  106. _loop(void)
  107. {
  108. xcb_generic_event_t *x_ev;
  109. while ((x_ev = xcb_wait_for_event(_x_con))) {
  110. switch (x_ev->response_type & ~0x80) {
  111. case XCB_EXPOSE:
  112. break;
  113. case XCB_GE_GENERIC:
  114. _event((xcb_ge_generic_event_t*)x_ev);
  115. break;
  116. }
  117. free(x_ev);
  118. xcb_flush(_x_con);
  119. }
  120. }
  121. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  122. static void
  123. _reset(void)
  124. {
  125. xcb_unmap_window(_x_con, _x_win);
  126. xcb_destroy_window(_x_con, _x_win);
  127. xcb_disconnect(_x_con);
  128. }