eolian: rename is_ref API to is_ptr to match syntax
[platform/upstream/efl.git] / src / lib / ecore_x / xcb / ecore_xcb_input.c
1 #include "ecore_xcb_private.h"
2 #ifdef ECORE_XCB_XINPUT
3 # include <xcb/xinput.h>
4 # include <xcb/xcb_event.h>
5 #endif
6
7 /* FIXME: this is a guess. can't find defines for touch events in xcb libs
8  * online */
9 /* these are not yet defined in xcb support for xi2 - so manually create */
10 #ifndef XCB_INPUT_DEVICE_TOUCH_BEGIN
11 #define XCB_INPUT_DEVICE_TOUCH_BEGIN    18
12 #endif
13 #ifndef XCB_INPUT_DEVICE_TOUCH_END
14 #define XCB_INPUT_DEVICE_TOUCH_END      19
15 #endif
16 #ifndef XCB_INPUT_DEVICE_TOUCH_UPDATE
17 #define XCB_INPUT_DEVICE_TOUCH_UPDATE   21
18 #endif
19
20 #ifndef XCB_INPUT_POINTER_EMULATED_MASK
21 #define XCB_INPUT_POINTER_EMULATED_MASK (1 << 16)
22 #endif
23
24 /* local variables */
25 static Eina_Bool _input_avail = EINA_FALSE;
26
27 /* external variables */
28 int _ecore_xcb_event_input = 0;
29
30 void
31 _ecore_xcb_input_init(void)
32 {
33    LOGFN(__FILE__, __LINE__, __FUNCTION__);
34
35 #ifdef ECORE_XCB_XINPUT
36    xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_input_id);
37 #endif
38 }
39
40 void
41 _ecore_xcb_input_finalize(void)
42 {
43 #ifdef ECORE_XCB_XINPUT
44    xcb_input_get_extension_version_cookie_t cookie;
45    xcb_input_get_extension_version_reply_t *reply;
46    char buff[128];
47 #endif
48
49    LOGFN(__FILE__, __LINE__, __FUNCTION__);
50
51 #ifdef ECORE_XCB_XINPUT
52    cookie =
53      xcb_input_get_extension_version_unchecked(_ecore_xcb_conn, 127, buff);
54    reply =
55      xcb_input_get_extension_version_reply(_ecore_xcb_conn, cookie, NULL);
56    if (reply)
57      {
58         _input_avail = EINA_TRUE;
59         free(reply);
60      }
61
62    if (_input_avail)
63      {
64         const xcb_query_extension_reply_t *ext_reply;
65
66         ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_input_id);
67         if (ext_reply)
68           _ecore_xcb_event_input = ext_reply->first_event;
69      }
70 #endif
71 }
72
73 void
74 _ecore_xcb_input_shutdown(void)
75 {
76    LOGFN(__FILE__, __LINE__, __FUNCTION__);
77 }
78
79 void
80 #ifdef ECORE_XCB_XINPUT
81 _ecore_xcb_input_handle_event(xcb_generic_event_t *event)
82 #else
83 _ecore_xcb_input_handle_event(xcb_generic_event_t * event EINA_UNUSED)
84 #endif
85 {
86 #ifdef ECORE_XCB_XINPUT
87    xcb_ge_event_t *ev;
88 #endif
89
90    LOGFN(__FILE__, __LINE__, __FUNCTION__);
91    CHECK_XCB_CONN;
92
93    /* FIXME: look at xlib ecore_x_xi2.c to copy logic in when i can find an
94     * xcb-input lib to test with */
95 #ifdef ECORE_XCB_XINPUT
96    ev = (xcb_ge_event_t *)event;
97    switch (ev->event_type)
98      {
99       case XCB_INPUT_DEVICE_MOTION_NOTIFY:
100           {
101              xcb_input_device_motion_notify_event_t *de;
102              unsigned int child_win = 0;
103
104              de = (xcb_input_device_motion_notify_event_t *)ev->pad1;
105              child_win = (de->child ? de->child : de->event);
106              _ecore_xcb_event_mouse_move(de->time, de->state, de->event_x,
107                                          de->event_y, de->root_x, de->root_y,
108                                          de->event, child_win, de->root,
109                                          de->same_screen, de->device_id,
110                                          1, 1, 1.0, 0.0,
111                                          de->event_x, de->event_y,
112                                          de->root_x, de->root_y);
113           }
114         break;
115
116       case XCB_INPUT_DEVICE_BUTTON_PRESS:
117           {
118              xcb_input_device_button_press_event_t *de;
119              unsigned int child_win = 0;
120
121              de = (xcb_input_device_button_press_event_t *)ev->pad1;
122              child_win = (de->child ? de->child : de->event);
123              _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN,
124                                            de->time, de->state, de->detail,
125                                            de->event_x, de->event_y,
126                                            de->root_x, de->root_y, de->event,
127                                            child_win, de->root,
128                                            de->same_screen, de->device_id,
129                                            1, 1, 1.0, 0.0,
130                                            de->event_x, de->event_y,
131                                            de->root_x, de->root_y);
132           }
133         break;
134
135       case XCB_INPUT_DEVICE_BUTTON_RELEASE:
136           {
137              xcb_input_device_button_release_event_t *de;
138              unsigned int child_win = 0;
139
140              de = (xcb_input_device_button_release_event_t *)ev->pad1;
141              child_win = (de->child ? de->child : de->event);
142              _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP,
143                                            de->time, de->state, de->detail,
144                                            de->event_x, de->event_y,
145                                            de->root_x, de->root_y, de->event,
146                                            child_win, de->root,
147                                            de->same_screen, de->device_id,
148                                            1, 1, 1.0, 0.0,
149                                            de->event_x, de->event_y,
150                                            de->root_x, de->root_y);
151           }
152         break;
153
154       case XCB_INPUT_DEVICE_TOUCH_UPDATE:
155           {
156              xcb_input_device_motion_notify_event_t *de;
157              unsigned int child_win = 0;
158
159              de = (xcb_input_device_motion_notify_event_t *)ev->pad1;
160              child_win = (de->child ? de->child : de->event);
161              _ecore_xcb_event_mouse_move(de->time, de->state, de->event_x,
162                                          de->event_y, de->root_x, de->root_y,
163                                          de->event, child_win, de->root,
164                                          de->same_screen, de->device_id,
165                                          1, 1, 1.0, 0.0,
166                                          de->event_x, de->event_y,
167                                          de->root_x, de->root_y);
168           }
169         break;
170
171       case XCB_INPUT_DEVICE_TOUCH_BEGIN:
172           {
173              xcb_input_device_button_press_event_t *de;
174              unsigned int child_win = 0;
175
176              de = (xcb_input_device_button_press_event_t *)ev->pad1;
177              child_win = (de->child ? de->child : de->event);
178              _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN,
179                                            de->time, de->state, de->detail,
180                                            de->event_x, de->event_y,
181                                            de->root_x, de->root_y, de->event,
182                                            child_win, de->root,
183                                            de->same_screen, de->device_id,
184                                            1, 1, 1.0, 0.0,
185                                            de->event_x, de->event_y,
186                                            de->root_x, de->root_y);
187           }
188         break;
189
190       case XCB_INPUT_DEVICE_TOUCH_END:
191           {
192              xcb_input_device_button_release_event_t *de;
193              unsigned int child_win = 0;
194
195              de = (xcb_input_device_button_release_event_t *)ev->pad1;
196              child_win = (de->child ? de->child : de->event);
197              _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP,
198                                            de->time, de->state, de->detail,
199                                            de->event_x, de->event_y,
200                                            de->root_x, de->root_y, de->event,
201                                            child_win, de->root,
202                                            de->same_screen, de->device_id,
203                                            1, 1, 1.0, 0.0,
204                                            de->event_x, de->event_y,
205                                            de->root_x, de->root_y);
206           }
207         break;
208
209       default:
210         break;
211      }
212 #endif
213 }
214
215 EAPI Eina_Bool
216 ecore_x_input_multi_select(Ecore_X_Window win)
217 {
218    Eina_Bool find = EINA_FALSE;
219 #ifdef ECORE_XCB_XINPUT
220    xcb_input_list_input_devices_cookie_t dcookie;
221    xcb_input_list_input_devices_reply_t *dreply;
222    xcb_input_device_info_iterator_t diter;
223 #endif
224
225    LOGFN(__FILE__, __LINE__, __FUNCTION__);
226    CHECK_XCB_CONN;
227
228    if (!_input_avail) return EINA_FALSE;
229
230    /* FIXME: i can't seemingly test this! no xcb input lib so can't look and
231     * test and look at types etc. - look at xlib code and copy logic over
232     * when we can */
233 #ifdef ECORE_XCB_XINPUT
234    dcookie = xcb_input_list_input_devices_unchecked(_ecore_xcb_conn);
235    dreply =
236      xcb_input_list_input_devices_reply(_ecore_xcb_conn, dcookie, NULL);
237    if (!dreply) return EINA_FALSE;
238
239    diter = xcb_input_list_input_devices_devices_iterator(dreply);
240    while (diter.rem)
241      {
242         xcb_input_device_info_t *dev;
243         const xcb_input_event_class_t iclass[] =
244           {
245              XCB_INPUT_DEVICE_BUTTON_PRESS,
246              XCB_INPUT_DEVICE_BUTTON_RELEASE,
247              XCB_INPUT_DEVICE_MOTION_NOTIFY,
248              XCB_INPUT_DEVICE_TOUCH_BEGIN,
249              XCB_INPUT_DEVICE_TOUCH_END,
250              XCB_INPUT_DEVICE_TOUCH_UPDATE
251           };
252
253         dev = diter.data;
254         if (dev->device_use == XCB_INPUT_DEVICE_USE_IS_X_EXTENSION_DEVICE)
255           {
256              DBG("Device %d", dev->device_id);
257              DBG("\tType: %d", dev->device_type);
258              DBG("\tNum Classes: %d", dev->num_class_info);
259              DBG("\tUse: %d", dev->device_use);
260
261              xcb_input_select_extension_event(_ecore_xcb_conn, win,
262                                               sizeof(iclass) / sizeof(xcb_input_event_class_t),
263                                               iclass);
264              find = EINA_TRUE;
265           }
266         xcb_input_device_info_next(&diter);
267      }
268    free(dreply);
269 #else
270    (void)win;
271 #endif
272
273    return find;
274 }
275
276 EAPI Eina_Bool 
277 ecore_x_input_raw_select(Ecore_X_Window win EINA_UNUSED)
278 {
279    /* NB: FIXME: This is just a placeholder. XCB does not have XInput2 yet */
280    return EINA_FALSE;
281 }
282
283 EAPI Eina_Bool
284 ecore_x_input_touch_devices_grab(Ecore_X_Window win EINA_UNUSED)
285 {
286    /* NB: FIXME: This is just a placeholder. XCB does not have XInput2 yet */
287    return EINA_FALSE;
288 }
289
290 EAPI Eina_Bool
291 ecore_x_input_touch_devices_ungrab(void)
292 {
293    /* NB: FIXME: This is just a placeholder. XCB does not have XInput2 yet */
294    return EINA_FALSE;
295 }