ecore: Fix support for intl keyboards
[framework/uifw/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_events.c
1 #include "ecore_xcb_private.h"
2 //#include "Ecore_X_Atoms.h"
3 #include <langinfo.h>
4 #include <xcb/xcb_icccm.h>
5 #include <xcb/xcb_event.h>
6 # ifdef ECORE_XCB_DAMAGE
7 #  include <xcb/damage.h>
8 # endif
9 # ifdef ECORE_XCB_RANDR
10 #  include <xcb/randr.h>
11 # endif
12 # ifdef ECORE_XCB_SCREENSAVER
13 #  include <xcb/screensaver.h>
14 # endif
15 # ifdef ECORE_XCB_SYNC
16 #  include <xcb/sync.h>
17 # endif
18 # ifdef ECORE_XCB_XFIXES
19 #  include <xcb/xfixes.h>
20 # endif
21 # ifdef ECORE_XCB_XGESTURE
22 #  include <xcb/gesture.h>
23 # endif
24
25 #ifndef CODESET
26 # define CODESET "INVALID"
27 #endif
28
29 typedef struct _Ecore_X_Mouse_Down_Info
30 {
31    EINA_INLIST;
32    int            dev;
33    Ecore_X_Time   last_time;
34    Ecore_X_Time   last_last_time;
35    Ecore_X_Window last_win;
36    Ecore_X_Window last_last_win;
37    Ecore_X_Window last_event_win;
38    Ecore_X_Window last_last_event_win;
39    Eina_Bool      did_double : 1;
40    Eina_Bool      did_triple : 1;
41 } Ecore_X_Mouse_Down_Info;
42
43 /* local function prototypes */
44 static void                     _ecore_xcb_event_handle_any_event(xcb_generic_event_t *event);
45 static void                     _ecore_xcb_event_handle_key_press(xcb_generic_event_t *event);
46 static void                     _ecore_xcb_event_handle_key_release(xcb_generic_event_t *event);
47 static void                     _ecore_xcb_event_handle_button_press(xcb_generic_event_t *event);
48 static void                     _ecore_xcb_event_handle_button_release(xcb_generic_event_t *event);
49 static void                     _ecore_xcb_event_handle_motion_notify(xcb_generic_event_t *event);
50 static void                     _ecore_xcb_event_handle_enter_notify(xcb_generic_event_t *event);
51 static void                     _ecore_xcb_event_handle_leave_notify(xcb_generic_event_t *event);
52 static void                     _ecore_xcb_event_handle_keymap_notify(xcb_generic_event_t *event);
53 static void                     _ecore_xcb_event_handle_focus_in(xcb_generic_event_t *event);
54 static void                     _ecore_xcb_event_handle_focus_out(xcb_generic_event_t *event);
55 static void                     _ecore_xcb_event_handle_expose(xcb_generic_event_t *event);
56 static void                     _ecore_xcb_event_handle_graphics_exposure(xcb_generic_event_t *event);
57 static void                     _ecore_xcb_event_handle_visibility_notify(xcb_generic_event_t *event);
58 static void                     _ecore_xcb_event_handle_create_notify(xcb_generic_event_t *event);
59 static void                     _ecore_xcb_event_handle_destroy_notify(xcb_generic_event_t *event);
60 static void                     _ecore_xcb_event_handle_map_notify(xcb_generic_event_t *event);
61 static void                     _ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event);
62 static void                     _ecore_xcb_event_handle_map_request(xcb_generic_event_t *event);
63 static void                     _ecore_xcb_event_handle_reparent_notify(xcb_generic_event_t *event);
64 static void                     _ecore_xcb_event_handle_configure_notify(xcb_generic_event_t *event);
65 static void                     _ecore_xcb_event_handle_configure_request(xcb_generic_event_t *event);
66 static void                     _ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event);
67 static void                     _ecore_xcb_event_handle_resize_request(xcb_generic_event_t *event);
68 static void                     _ecore_xcb_event_handle_circulate_notify(xcb_generic_event_t *event);
69 static void                     _ecore_xcb_event_handle_circulate_request(xcb_generic_event_t *event);
70 static void                     _ecore_xcb_event_handle_property_notify(xcb_generic_event_t *event);
71 static void                     _ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event);
72 static void                     _ecore_xcb_event_handle_selection_request(xcb_generic_event_t *event);
73 static void                     _ecore_xcb_event_handle_selection_notify(xcb_generic_event_t *event);
74 static void                     _ecore_xcb_event_handle_colormap_notify(xcb_generic_event_t *event);
75 static void                     _ecore_xcb_event_handle_client_message(xcb_generic_event_t *event);
76 static void                     _ecore_xcb_event_handle_mapping_notify(xcb_generic_event_t *event);
77 static void                     _ecore_xcb_event_handle_damage_notify(xcb_generic_event_t *event);
78 static void                     _ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event);
79 static void                     _ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event);
80 static void                     _ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event);
81 static void                     _ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event);
82 static void                     _ecore_xcb_event_handle_randr_output_property_change(xcb_generic_event_t *event);
83 static void                     _ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event);
84 #ifdef ECORE_XCB_XGESTURE
85 static void                     _ecore_xcb_event_handle_gesture_notify_flick(xcb_generic_event_t *event);
86 static void                     _ecore_xcb_event_handle_gesture_notify_pan(xcb_generic_event_t *event);
87 static void                     _ecore_xcb_event_handle_gesture_notify_pinchrotation(xcb_generic_event_t *event);
88 static void                     _ecore_xcb_event_handle_gesture_notify_tap(xcb_generic_event_t *event);
89 static void                     _ecore_xcb_event_handle_gesture_notify_tapnhold(xcb_generic_event_t *event);
90 static void                     _ecore_xcb_event_handle_gesture_notify_hold(xcb_generic_event_t *event);
91 static void                     _ecore_xcb_event_handle_gesture_notify_group(xcb_generic_event_t *event);
92 #endif
93 #ifdef ECORE_XCB_SHAPE
94 static void                     _ecore_xcb_event_handle_shape_change(xcb_generic_event_t *event);
95 #endif
96 static void                     _ecore_xcb_event_handle_sync_counter(xcb_generic_event_t *event);
97 static void                     _ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event);
98 static void                     _ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event __UNUSED__);
99 static void                     _ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event);
100 static void                     _ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event);
101 static void                     _ecore_xcb_event_handle_input_event(xcb_generic_event_t *event);
102
103 static void                     _ecore_xcb_event_key_press(xcb_generic_event_t *event);
104 static void                     _ecore_xcb_event_key_release(xcb_generic_event_t *event);
105 static void                     _ecore_xcb_event_mouse_move_free(void *data __UNUSED__,
106                                                                  void *event);
107 static Ecore_X_Event_Mode       _ecore_xcb_event_mode_get(uint8_t mode);
108 static Ecore_X_Event_Detail     _ecore_xcb_event_detail_get(uint8_t detail);
109 static void                     _ecore_xcb_event_xdnd_enter_free(void *data __UNUSED__,
110                                                                  void *event);
111 static void                     _ecore_xcb_event_selection_notify_free(void *data __UNUSED__,
112                                                                        void *event);
113 static void                     _ecore_xcb_event_generic_event_free(void *data,
114                                                                     void *event);
115 static void                     _ecore_xcb_event_mouse_down_info_clear(void);
116 static Ecore_X_Mouse_Down_Info *_ecore_xcb_event_mouse_down_info_get(int dev);
117
118 /* local variables */
119 static Eina_Bool _ecore_xcb_event_last_mouse_move = EINA_FALSE;
120 //static Ecore_Event *_ecore_xcb_event_last_mouse_move_event = NULL;
121 static Eina_Inlist *_ecore_xcb_mouse_down_info_list = NULL;
122 static Ecore_X_Time _ecore_xcb_event_last_time;
123 static Ecore_X_Window _ecore_xcb_event_last_window = 0;
124
125 /* public variables */
126 int16_t _ecore_xcb_event_last_root_x = 0;
127 int16_t _ecore_xcb_event_last_root_y = 0;
128
129 EAPI int ECORE_X_EVENT_ANY = 0;
130 EAPI int ECORE_X_EVENT_MOUSE_IN = 0;
131 EAPI int ECORE_X_EVENT_MOUSE_OUT = 0;
132 EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0;
133 EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0;
134 EAPI int ECORE_X_EVENT_WINDOW_KEYMAP = 0;
135 EAPI int ECORE_X_EVENT_WINDOW_DAMAGE = 0;
136 EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0;
137 EAPI int ECORE_X_EVENT_WINDOW_CREATE = 0;
138 EAPI int ECORE_X_EVENT_WINDOW_DESTROY = 0;
139 EAPI int ECORE_X_EVENT_WINDOW_HIDE = 0;
140 EAPI int ECORE_X_EVENT_WINDOW_SHOW = 0;
141 EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0;
142 EAPI int ECORE_X_EVENT_WINDOW_REPARENT = 0;
143 EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE = 0;
144 EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0;
145 EAPI int ECORE_X_EVENT_WINDOW_GRAVITY = 0;
146 EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0;
147 EAPI int ECORE_X_EVENT_WINDOW_STACK = 0;
148 EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0;
149 EAPI int ECORE_X_EVENT_WINDOW_PROPERTY = 0;
150 EAPI int ECORE_X_EVENT_WINDOW_COLORMAP = 0;
151 EAPI int ECORE_X_EVENT_WINDOW_MAPPING = 0;
152 EAPI int ECORE_X_EVENT_MAPPING_CHANGE = 0;
153 EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
154 EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
155 EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
156 EAPI int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = 0;
157 EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
158 EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
159 EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
160 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_FLICK = 0;
161 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PAN = 0;
162 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = 0;
163 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAP = 0;
164 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = 0;
165 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = 0;
166 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 0;
167 EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0;
168 EAPI int ECORE_X_EVENT_SYNC_ALARM = 0;
169 EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0;
170 EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0;
171 EAPI int ECORE_X_EVENT_RANDR_CRTC_CHANGE = 0;
172 EAPI int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = 0;
173 EAPI int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = 0;
174 EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0;
175 EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0;
176 EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0;
177 EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0;
178 EAPI int ECORE_X_EVENT_PING = 0;
179 EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0;
180 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0;
181 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0;
182 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0;
183 EAPI int ECORE_X_EVENT_GENERIC = 0;
184
185 void
186 _ecore_xcb_events_init(void)
187 {
188    LOGFN(__FILE__, __LINE__, __FUNCTION__);
189
190    if (!ECORE_X_EVENT_ANY)
191      {
192         ECORE_X_EVENT_ANY = ecore_event_type_new();
193         ECORE_X_EVENT_MOUSE_IN = ecore_event_type_new();
194         ECORE_X_EVENT_MOUSE_OUT = ecore_event_type_new();
195         ECORE_X_EVENT_WINDOW_FOCUS_IN = ecore_event_type_new();
196         ECORE_X_EVENT_WINDOW_FOCUS_OUT = ecore_event_type_new();
197         ECORE_X_EVENT_WINDOW_KEYMAP = ecore_event_type_new();
198         ECORE_X_EVENT_WINDOW_DAMAGE = ecore_event_type_new();
199         ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = ecore_event_type_new();
200         ECORE_X_EVENT_WINDOW_CREATE = ecore_event_type_new();
201         ECORE_X_EVENT_WINDOW_DESTROY = ecore_event_type_new();
202         ECORE_X_EVENT_WINDOW_HIDE = ecore_event_type_new();
203         ECORE_X_EVENT_WINDOW_SHOW = ecore_event_type_new();
204         ECORE_X_EVENT_WINDOW_SHOW_REQUEST = ecore_event_type_new();
205         ECORE_X_EVENT_WINDOW_REPARENT = ecore_event_type_new();
206         ECORE_X_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
207         ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = ecore_event_type_new();
208         ECORE_X_EVENT_WINDOW_GRAVITY = ecore_event_type_new();
209         ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = ecore_event_type_new();
210         ECORE_X_EVENT_WINDOW_STACK = ecore_event_type_new();
211         ECORE_X_EVENT_WINDOW_STACK_REQUEST = ecore_event_type_new();
212         ECORE_X_EVENT_WINDOW_PROPERTY = ecore_event_type_new();
213         ECORE_X_EVENT_WINDOW_COLORMAP = ecore_event_type_new();
214         ECORE_X_EVENT_WINDOW_MAPPING = ecore_event_type_new();
215         ECORE_X_EVENT_MAPPING_CHANGE = ecore_event_type_new();
216         ECORE_X_EVENT_SELECTION_CLEAR = ecore_event_type_new();
217         ECORE_X_EVENT_SELECTION_REQUEST = ecore_event_type_new();
218         ECORE_X_EVENT_SELECTION_NOTIFY = ecore_event_type_new();
219         ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = ecore_event_type_new();
220         ECORE_X_EVENT_CLIENT_MESSAGE = ecore_event_type_new();
221         ECORE_X_EVENT_WINDOW_SHAPE = ecore_event_type_new();
222         ECORE_X_EVENT_SCREENSAVER_NOTIFY = ecore_event_type_new();
223         ECORE_X_EVENT_GESTURE_NOTIFY_FLICK = ecore_event_type_new();
224         ECORE_X_EVENT_GESTURE_NOTIFY_PAN = ecore_event_type_new();
225         ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = ecore_event_type_new();
226         ECORE_X_EVENT_GESTURE_NOTIFY_TAP = ecore_event_type_new();
227         ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = ecore_event_type_new();
228         ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = ecore_event_type_new();
229         ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = ecore_event_type_new();
230         ECORE_X_EVENT_SYNC_COUNTER = ecore_event_type_new();
231         ECORE_X_EVENT_SYNC_ALARM = ecore_event_type_new();
232         ECORE_X_EVENT_SCREEN_CHANGE = ecore_event_type_new();
233         ECORE_X_EVENT_RANDR_CRTC_CHANGE = ecore_event_type_new();
234         ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = ecore_event_type_new();
235         ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = ecore_event_type_new();
236         ECORE_X_EVENT_DAMAGE_NOTIFY = ecore_event_type_new();
237         ECORE_X_EVENT_WINDOW_DELETE_REQUEST = ecore_event_type_new();
238         ECORE_X_EVENT_DESKTOP_CHANGE = ecore_event_type_new();
239         ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = ecore_event_type_new();
240         ECORE_X_EVENT_WINDOW_STATE_REQUEST = ecore_event_type_new();
241         ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = ecore_event_type_new();
242         ECORE_X_EVENT_PING = ecore_event_type_new();
243         ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = ecore_event_type_new();
244         ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = ecore_event_type_new();
245         ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = ecore_event_type_new();
246         ECORE_X_EVENT_GENERIC = ecore_event_type_new();
247      }
248 }
249
250 void
251 _ecore_xcb_events_shutdown(void)
252 {
253    LOGFN(__FILE__, __LINE__, __FUNCTION__);
254
255    _ecore_xcb_event_mouse_down_info_clear();
256
257    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
258 //   if (_ecore_xcb_event_last_mouse_move_event)
259 //     {
260 //        ecore_event_del(_ecore_xcb_event_last_mouse_move_event);
261 //        _ecore_xcb_event_last_mouse_move_event = NULL;
262 //     }
263 }
264
265 void
266 _ecore_xcb_events_handle(xcb_generic_event_t *ev)
267 {
268    uint8_t response = 0;
269
270 //   LOGFN(__FILE__, __LINE__, __FUNCTION__);
271    CHECK_XCB_CONN;
272
273    /* strip highest bit (set if event is generated) */
274    response = (ev->response_type & ~0x80);
275    if (response == 0)
276      {
277         xcb_generic_error_t *err;
278
279         err = (xcb_generic_error_t *)ev;
280
281         /* NB: There is no way to check access of destroyed windows,
282          * so trap those cases and ignore. We also ignore BadValue from
283          * xcb_grab/ungrab_button (happens when we are using any_mod)
284          * and a few others */
285 #ifdef OLD_XCB_VERSION
286         if (err->error_code == XCB_EVENT_ERROR_BAD_WINDOW) return;
287         else if (err->error_code == XCB_EVENT_ERROR_BAD_MATCH)
288           {
289              if ((err->major_code == XCB_SET_INPUT_FOCUS) ||
290                  (err->major_code == XCB_CONFIGURE_WINDOW))
291                return;
292           }
293         else if (err->error_code == XCB_EVENT_ERROR_BAD_VALUE)
294           {
295              if ((err->major_code == XCB_KILL_CLIENT) ||
296                  (err->major_code == XCB_GRAB_BUTTON) ||
297                  (err->major_code == XCB_UNGRAB_BUTTON))
298                return;
299           }
300 #else
301         if (err->error_code == XCB_WINDOW) return;
302         else if (err->error_code == XCB_MATCH)
303           {
304              if ((err->major_code == XCB_SET_INPUT_FOCUS) ||
305                  (err->major_code == XCB_CONFIGURE_WINDOW))
306                return;
307           }
308         else if (err->error_code == XCB_VALUE)
309           {
310              if ((err->major_code == XCB_KILL_CLIENT) ||
311                  (err->major_code == XCB_GRAB_BUTTON) ||
312                  (err->major_code == XCB_UNGRAB_BUTTON))
313                return;
314           }
315 #endif
316         WRN("Got Event Error:");
317         WRN("\tMajor Code: %d", err->major_code);
318         WRN("\tMinor Code: %d", err->minor_code);
319         WRN("\tRequest: %s", xcb_event_get_request_label(err->major_code));
320         WRN("\tError: %s", xcb_event_get_error_label(err->error_code));
321         if (err->error_code == 2) // bad value
322           WRN("\tValue: %d", ((xcb_value_error_t *)err)->bad_value);
323         else if (err->error_code == 8) // bad match
324           WRN("\tMatch: %d", ((xcb_match_error_t *)err)->bad_value);
325
326         if (err->major_code == XCB_SEND_EVENT)
327           {
328              WRN("\tSend Event Error");
329              WRN("\t\tSeq: %d", ev->sequence);
330              WRN("\t\tFull Seq: %d", ev->full_sequence);
331              WRN("\t\tType: %d", ev->response_type);
332           }
333         /* if (err->major_code == 148)  */
334         /*   { */
335         /*      printf("GOT 148 Error\n"); */
336         /*   } */
337         return;
338      }
339
340    /* FIXME: Filter event for xim when xcb supports xim */
341
342    _ecore_xcb_event_handle_any_event(ev);
343
344    if (response == XCB_KEY_PRESS)
345      _ecore_xcb_event_handle_key_press(ev);
346    else if (response == XCB_KEY_RELEASE)
347      _ecore_xcb_event_handle_key_release(ev);
348    else if (response == XCB_BUTTON_PRESS)
349      _ecore_xcb_event_handle_button_press(ev);
350    else if (response == XCB_BUTTON_RELEASE)
351      _ecore_xcb_event_handle_button_release(ev);
352    else if (response == XCB_MOTION_NOTIFY)
353      _ecore_xcb_event_handle_motion_notify(ev);
354    else if (response == XCB_ENTER_NOTIFY)
355      _ecore_xcb_event_handle_enter_notify(ev);
356    else if (response == XCB_LEAVE_NOTIFY)
357      _ecore_xcb_event_handle_leave_notify(ev);
358    else if (response == XCB_KEYMAP_NOTIFY)
359      _ecore_xcb_event_handle_keymap_notify(ev);
360    else if (response == XCB_FOCUS_IN)
361      _ecore_xcb_event_handle_focus_in(ev);
362    else if (response == XCB_FOCUS_OUT)
363      _ecore_xcb_event_handle_focus_out(ev);
364    else if (response == XCB_EXPOSE)
365      _ecore_xcb_event_handle_expose(ev);
366    else if (response == XCB_GRAPHICS_EXPOSURE)
367      _ecore_xcb_event_handle_graphics_exposure(ev);
368    else if (response == XCB_VISIBILITY_NOTIFY)
369      _ecore_xcb_event_handle_visibility_notify(ev);
370    else if (response == XCB_CREATE_NOTIFY)
371      _ecore_xcb_event_handle_create_notify(ev);
372    else if (response == XCB_DESTROY_NOTIFY)
373      _ecore_xcb_event_handle_destroy_notify(ev);
374    else if (response == XCB_MAP_NOTIFY)
375      _ecore_xcb_event_handle_map_notify(ev);
376    else if (response == XCB_UNMAP_NOTIFY)
377      _ecore_xcb_event_handle_unmap_notify(ev);
378    else if (response == XCB_MAP_REQUEST)
379      _ecore_xcb_event_handle_map_request(ev);
380    else if (response == XCB_REPARENT_NOTIFY)
381      _ecore_xcb_event_handle_reparent_notify(ev);
382    else if (response == XCB_CONFIGURE_NOTIFY)
383      _ecore_xcb_event_handle_configure_notify(ev);
384    else if (response == XCB_CONFIGURE_REQUEST)
385      _ecore_xcb_event_handle_configure_request(ev);
386    else if (response == XCB_GRAVITY_NOTIFY)
387      _ecore_xcb_event_handle_gravity_notify(ev);
388    else if (response == XCB_RESIZE_REQUEST)
389      _ecore_xcb_event_handle_resize_request(ev);
390    else if (response == XCB_CIRCULATE_NOTIFY)
391      _ecore_xcb_event_handle_circulate_notify(ev);
392    else if (response == XCB_CIRCULATE_REQUEST)
393      _ecore_xcb_event_handle_circulate_request(ev);
394    else if (response == XCB_PROPERTY_NOTIFY)
395      _ecore_xcb_event_handle_property_notify(ev);
396    else if (response == XCB_SELECTION_CLEAR)
397      _ecore_xcb_event_handle_selection_clear(ev);
398    else if (response == XCB_SELECTION_REQUEST)
399      _ecore_xcb_event_handle_selection_request(ev);
400    else if (response == XCB_SELECTION_NOTIFY)
401      _ecore_xcb_event_handle_selection_notify(ev);
402    else if (response == XCB_COLORMAP_NOTIFY)
403      _ecore_xcb_event_handle_colormap_notify(ev);
404    else if (response == XCB_CLIENT_MESSAGE)
405      _ecore_xcb_event_handle_client_message(ev);
406    else if (response == XCB_MAPPING_NOTIFY)
407      _ecore_xcb_event_handle_mapping_notify(ev);
408    else if (response == 35) /* GenericEvent == 35 */
409      _ecore_xcb_event_handle_generic_event(ev);
410 #ifdef ECORE_XCB_DAMAGE
411    else if ((_ecore_xcb_event_damage >= 0) &&
412             (response == (_ecore_xcb_event_damage + XCB_DAMAGE_NOTIFY)))
413      _ecore_xcb_event_handle_damage_notify(ev);
414 #endif
415 #ifdef ECORE_XCB_RANDR
416    else if ((_ecore_xcb_event_randr >= 0) &&
417             (response ==
418              _ecore_xcb_event_randr + XCB_RANDR_SCREEN_CHANGE_NOTIFY))
419      _ecore_xcb_event_handle_randr_change(ev);
420    else if ((_ecore_xcb_event_randr >= 0) &&
421             (response == (_ecore_xcb_event_randr + XCB_RANDR_NOTIFY)))
422      _ecore_xcb_event_handle_randr_notify(ev);
423 #endif
424 #ifdef ECORE_XCB_SCREENSAVER
425    else if ((_ecore_xcb_event_screensaver >= 0) &&
426             (response ==
427              _ecore_xcb_event_screensaver + XCB_SCREENSAVER_NOTIFY))
428      _ecore_xcb_event_handle_screensaver_notify(ev);
429 #endif
430 #ifdef ECORE_XCB_XGESTURE
431    else if ((_ecore_xcb_event_gesture >= 0) && 
432             (response == 
433                 _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_FLICK))
434      _ecore_xcb_event_handle_gesture_notify_flick(ev);
435    else if ((_ecore_xcb_event_gesture >= 0) && 
436             (response == 
437                 _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_PAN))
438      _ecore_xcb_event_handle_gesture_notify_pan(ev);
439    else if ((_ecore_xcb_event_gesture >= 0) && 
440             (response == 
441                 _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_PINCH_ROTATION))
442      _ecore_xcb_event_handle_gesture_notify_pinchrotation(ev);
443    else if ((_ecore_xcb_event_gesture >= 0) && 
444             (response == 
445                 _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_TAP))
446      _ecore_xcb_event_handle_gesture_notify_tap(ev);
447    else if ((_ecore_xcb_event_gesture >= 0) && 
448             (response == 
449                 _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_TAP_N_HOLD))
450      _ecore_xcb_event_handle_gesture_notify_tapnhold(ev);
451    else if ((_ecore_xcb_event_gesture >= 0) && 
452             (response == 
453                 _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_HOLD))
454      _ecore_xcb_event_handle_gesture_notify_hold(ev);
455    else if ((_ecore_xcb_event_gesture >= 0) && 
456             (response == 
457                 _ecore_xcb_event_gesture + XCB_GESTURE_NOTIFY_GROUP))
458      _ecore_xcb_event_handle_gesture_notify_group(ev);
459 #endif
460 #ifdef ECORE_XCB_SHAPE
461    else if ((_ecore_xcb_event_shape >= 0) &&
462             (response == (_ecore_xcb_event_shape + XCB_SHAPE_NOTIFY)))
463      _ecore_xcb_event_handle_shape_change(ev);
464 #endif
465 #ifdef ECORE_XCB_SYNC
466    else if ((_ecore_xcb_event_sync >= 0) &&
467             (response == (_ecore_xcb_event_sync + XCB_SYNC_COUNTER_NOTIFY)))
468      _ecore_xcb_event_handle_sync_counter(ev);
469    else if ((_ecore_xcb_event_sync >= 0) &&
470             (response == (_ecore_xcb_event_sync + XCB_SYNC_ALARM_NOTIFY)))
471      _ecore_xcb_event_handle_sync_alarm(ev);
472 #endif
473 #ifdef ECORE_XCB_XFIXES
474    else if ((_ecore_xcb_event_xfixes >= 0) &&
475             (response ==
476              _ecore_xcb_event_xfixes + XCB_XFIXES_SELECTION_NOTIFY))
477      _ecore_xcb_event_handle_xfixes_selection_notify(ev);
478    else if ((_ecore_xcb_event_xfixes >= 0) &&
479             (response == (_ecore_xcb_event_xfixes + XCB_XFIXES_CURSOR_NOTIFY)))
480      _ecore_xcb_event_handle_xfixes_cursor_notify(ev);
481 #endif
482 }
483
484 Ecore_X_Time
485 _ecore_xcb_events_last_time_get(void)
486 {
487    LOGFN(__FILE__, __LINE__, __FUNCTION__);
488
489    return _ecore_xcb_event_last_time;
490 }
491
492 EAPI void
493 ecore_x_event_mask_set(Ecore_X_Window     win,
494                        Ecore_X_Event_Mask mask)
495 {
496    xcb_get_window_attributes_cookie_t cookie;
497    xcb_get_window_attributes_reply_t *reply;
498    uint32_t list;
499
500    LOGFN(__FILE__, __LINE__, __FUNCTION__);
501    CHECK_XCB_CONN;
502
503    if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
504    cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win);
505    reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
506    if (!reply) return;
507
508    list = (mask | reply->your_event_mask);
509    free(reply);
510    xcb_change_window_attributes(_ecore_xcb_conn, win,
511                                 XCB_CW_EVENT_MASK, &list);
512 //   ecore_x_flush();
513 }
514
515 EAPI void
516 ecore_x_event_mask_unset(Ecore_X_Window     win,
517                          Ecore_X_Event_Mask mask)
518 {
519    xcb_get_window_attributes_cookie_t cookie;
520    xcb_get_window_attributes_reply_t *reply;
521    uint32_t list;
522
523    LOGFN(__FILE__, __LINE__, __FUNCTION__);
524    CHECK_XCB_CONN;
525
526    if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
527    cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win);
528    reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
529    if (!reply) return;
530
531    list = (reply->your_event_mask & ~mask);
532    free(reply);
533    xcb_change_window_attributes(_ecore_xcb_conn, win,
534                                 XCB_CW_EVENT_MASK, &list);
535 //   ecore_x_flush();
536 }
537
538 unsigned int
539 _ecore_xcb_events_modifiers_get(unsigned int state)
540 {
541    unsigned int modifiers = 0;
542
543    LOGFN(__FILE__, __LINE__, __FUNCTION__);
544
545    if (state & ECORE_X_MODIFIER_SHIFT)
546      modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
547    if (state & ECORE_X_MODIFIER_CTRL)
548      modifiers |= ECORE_EVENT_MODIFIER_CTRL;
549    if (state & ECORE_X_MODIFIER_ALT)
550      modifiers |= ECORE_EVENT_MODIFIER_ALT;
551    if (state & ECORE_X_MODIFIER_WIN)
552      modifiers |= ECORE_EVENT_MODIFIER_WIN;
553    if (state & ECORE_X_MODIFIER_MODE)
554      modifiers |= ECORE_EVENT_MODIFIER_MODE;
555    if (state & ECORE_X_LOCK_SCROLL)
556      modifiers |= ECORE_EVENT_LOCK_SCROLL;
557    if (state & ECORE_X_LOCK_CAPS)
558      modifiers |= ECORE_EVENT_LOCK_CAPS;
559    if (state & ECORE_X_LOCK_NUM)
560      modifiers |= ECORE_EVENT_LOCK_NUM;
561    if (state & ECORE_X_LOCK_SHIFT)
562      modifiers |= ECORE_EVENT_LOCK_SHIFT;
563
564    return modifiers;
565 }
566
567 /* local functions */
568 static void
569 _ecore_xcb_event_handle_any_event(xcb_generic_event_t *event)
570 {
571    xcb_generic_event_t *ev;
572
573 //   LOGFN(__FILE__, __LINE__, __FUNCTION__);
574
575    ev = malloc(sizeof(xcb_generic_event_t));
576    if (!ev) return;
577
578    memcpy(ev, event, sizeof(xcb_generic_event_t));
579    ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL);
580 }
581
582 static void
583 _ecore_xcb_event_handle_key_press(xcb_generic_event_t *event)
584 {
585    _ecore_xcb_event_key_press(event);
586 }
587
588 static void
589 _ecore_xcb_event_handle_key_release(xcb_generic_event_t *event)
590 {
591    _ecore_xcb_event_key_release(event);
592 }
593
594 static void
595 _ecore_xcb_event_handle_button_press(xcb_generic_event_t *event)
596 {
597    xcb_button_press_event_t *ev;
598
599    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
600
601    ev = (xcb_button_press_event_t *)event;
602    if ((ev->detail > 3) && (ev->detail < 8))
603      {
604         Ecore_Event_Mouse_Wheel *e;
605
606         if (!(e = malloc(sizeof(Ecore_Event_Mouse_Wheel)))) return;
607
608         e->timestamp = ev->time;
609         e->modifiers = _ecore_xcb_events_modifiers_get(ev->state);
610         switch (ev->detail)
611           {
612            case 4:
613              e->direction = 0;
614              e->z = -1;
615              break;
616
617            case 5:
618              e->direction = 0;
619              e->z = 1;
620              break;
621
622            case 6:
623              e->direction = 1;
624              e->z = -1;
625              break;
626
627            case 7:
628              e->direction = 1;
629              e->z = 1;
630              break;
631
632            default:
633              e->direction = 0;
634              e->z = 0;
635              break;
636           }
637         e->x = ev->event_x;
638         e->y = ev->event_y;
639         e->root.x = ev->root_x;
640         e->root.y = ev->root_y;
641         if (ev->child)
642           e->window = ev->child;
643         else
644           e->window = ev->event;
645
646         e->event_window = ev->event;
647         e->same_screen = ev->same_screen;
648         e->root_window = ev->root;
649
650         _ecore_xcb_event_last_time = e->timestamp;
651         _ecore_xcb_event_last_window = e->window;
652         _ecore_xcb_event_last_root_x = e->root.x;
653         _ecore_xcb_event_last_root_y = e->root.y;
654
655         ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
656
657         _ecore_xcb_window_grab_allow_events(ev->event, ev->child,
658                                             ECORE_EVENT_MOUSE_WHEEL,
659                                             e, ev->time);
660      }
661    else
662      {
663         Ecore_Event_Mouse_Button *e;
664         unsigned int child_win = 0;
665
666         child_win = (ev->child ? ev->child : ev->event);
667
668         _ecore_xcb_event_mouse_move(ev->time, ev->state,
669                                     ev->event_x, ev->event_y,
670                                     ev->root_x, ev->root_y,
671                                     ev->event, child_win,
672                                     ev->root, ev->same_screen,
673                                     0, 1, 1, 1.0, 0.0,
674                                     ev->event_x, ev->event_y,
675                                     ev->root_x, ev->root_y);
676
677         e = _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN,
678                                           ev->time,
679                                           ev->state, ev->detail,
680                                           ev->event_x, ev->event_y,
681                                           ev->root_x, ev->root_y, ev->event,
682                                           child_win,
683                                           ev->root, ev->same_screen,
684                                           0, 1, 1, 1.0, 0.0,
685                                           ev->event_x, ev->event_y,
686                                           ev->root_x, ev->root_y);
687         if (e)
688           _ecore_xcb_window_grab_allow_events(ev->event, ev->child,
689                                               ECORE_EVENT_MOUSE_BUTTON_DOWN,
690                                               e, ev->time);
691      }
692 }
693
694 static void
695 _ecore_xcb_event_handle_button_release(xcb_generic_event_t *event)
696 {
697    xcb_button_release_event_t *ev;
698
699    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
700    ev = (xcb_button_release_event_t *)event;
701    if ((ev->detail <= 3) || (ev->detail > 7))
702      {
703         _ecore_xcb_event_mouse_move(ev->time, ev->state,
704                                     ev->event_x, ev->event_y,
705                                     ev->root_x, ev->root_y,
706                                     ev->event,
707                                     (ev->child ? ev->child : ev->event),
708                                     ev->root, ev->same_screen,
709                                     0, 1, 1, 1.0, 0.0,
710                                     ev->event_x, ev->event_y,
711                                     ev->root_x, ev->root_y);
712
713         _ecore_xcb_event_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP, ev->time,
714                                       ev->state, ev->detail,
715                                       ev->event_x, ev->event_y, ev->root_x,
716                                       ev->root_y, ev->event,
717                                       (ev->child ? ev->child : ev->event),
718                                       ev->root, ev->same_screen,
719                                       0, 1, 1, 1.0, 0.0,
720                                       ev->event_x, ev->event_y,
721                                       ev->root_x, ev->root_y);
722      }
723 }
724
725 static void
726 _ecore_xcb_event_handle_motion_notify(xcb_generic_event_t *event)
727 {
728    xcb_motion_notify_event_t *ev;
729
730    ev = (xcb_motion_notify_event_t *)event;
731
732    /* if (_ecore_xcb_event_last_mouse_move_event)  */
733    /*   { */
734    /*      ecore_event_del(_ecore_xcb_event_last_mouse_move_event); */
735    /*      _ecore_xcb_event_last_mouse_move = EINA_FALSE; */
736    /*      _ecore_xcb_event_last_mouse_move_event = NULL; */
737    /*   } */
738
739    _ecore_xcb_event_mouse_move(ev->time, ev->state,
740                                ev->event_x, ev->event_y,
741                                ev->root_x, ev->root_y,
742                                ev->event,
743                                (ev->child ? ev->child : ev->event),
744                                ev->root, ev->same_screen,
745                                0, 1, 1, 1.0, 0.0,
746                                ev->event_x, ev->event_y,
747                                ev->root_x, ev->root_y);
748    _ecore_xcb_event_last_mouse_move = EINA_TRUE;
749
750    _ecore_xcb_dnd_drag(ev->root, ev->root_x, ev->root_y);
751 }
752
753 static void
754 _ecore_xcb_event_handle_enter_notify(xcb_generic_event_t *event)
755 {
756    xcb_enter_notify_event_t *ev;
757    Ecore_X_Event_Mouse_In *e;
758
759    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
760    ev = (xcb_enter_notify_event_t *)event;
761
762    _ecore_xcb_event_mouse_move(ev->time, ev->state,
763                                ev->event_x, ev->event_y,
764                                ev->root_x, ev->root_y,
765                                ev->event,
766                                (ev->child ? ev->child : ev->event),
767                                ev->root, ev->same_screen_focus,
768                                0, 1, 1, 1.0, 0.0,
769                                ev->event_x, ev->event_y,
770                                ev->root_x, ev->root_y);
771
772    if (!(e = calloc(1, sizeof(Ecore_X_Event_Mouse_In)))) return;
773
774    e->modifiers = _ecore_xcb_events_modifiers_get(ev->state);
775    e->x = ev->event_x;
776    e->y = ev->event_y;
777    e->root.x = ev->root_x;
778    e->root.y = ev->root_y;
779    if (ev->child)
780      e->win = ev->child;
781    else
782      e->win = ev->event;
783    e->event_win = ev->event;
784    e->same_screen = ev->same_screen_focus;
785    e->root_win = ev->root;
786    e->mode = _ecore_xcb_event_mode_get(ev->mode);
787    e->detail = _ecore_xcb_event_detail_get(ev->detail);
788    e->time = ev->time;
789    _ecore_xcb_event_last_time = e->time;
790
791    ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
792 }
793
794 static void
795 _ecore_xcb_event_handle_leave_notify(xcb_generic_event_t *event)
796 {
797    xcb_leave_notify_event_t *ev;
798    Ecore_X_Event_Mouse_Out *e;
799
800    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
801    ev = (xcb_enter_notify_event_t *)event;
802
803    _ecore_xcb_event_mouse_move(ev->time, ev->state,
804                                ev->event_x, ev->event_y,
805                                ev->root_x, ev->root_y,
806                                ev->event,
807                                (ev->child ? ev->child : ev->event),
808                                ev->root, ev->same_screen_focus,
809                                0, 1, 1, 1.0, 0.0,
810                                ev->event_x, ev->event_y,
811                                ev->root_x, ev->root_y);
812
813    if (!(e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out)))) return;
814
815    e->modifiers = _ecore_xcb_events_modifiers_get(ev->state);
816    e->x = ev->event_x;
817    e->y = ev->event_y;
818    e->root.x = ev->root_x;
819    e->root.y = ev->root_y;
820    if (ev->child)
821      e->win = ev->child;
822    else
823      e->win = ev->event;
824    e->event_win = ev->event;
825    e->same_screen = ev->same_screen_focus;
826    e->root_win = ev->root;
827    e->mode = _ecore_xcb_event_mode_get(ev->mode);
828    e->detail = _ecore_xcb_event_detail_get(ev->detail);
829
830    e->time = ev->time;
831    _ecore_xcb_event_last_time = e->time;
832    _ecore_xcb_event_last_window = e->win;
833    _ecore_xcb_event_last_root_x = e->root.x;
834    _ecore_xcb_event_last_root_y = e->root.y;
835
836    ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
837 }
838
839 static void
840 _ecore_xcb_event_handle_keymap_notify(xcb_generic_event_t *event __UNUSED__)
841 {
842 //   LOGFN(__FILE__, __LINE__, __FUNCTION__);
843
844      // FIXME: handle this event type
845        _ecore_xcb_event_last_mouse_move = EINA_FALSE;
846 }
847
848 static void
849 _ecore_xcb_event_handle_focus_in(xcb_generic_event_t *event)
850 {
851    xcb_focus_in_event_t *ev;
852    Ecore_X_Event_Window_Focus_In *e;
853
854    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
855    ev = (xcb_focus_in_event_t *)event;
856    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In)))) return;
857
858    e->win = ev->event;
859    e->mode = _ecore_xcb_event_mode_get(ev->mode);
860    e->detail = _ecore_xcb_event_detail_get(ev->detail);
861
862    e->time = _ecore_xcb_event_last_time;
863    _ecore_xcb_event_last_time = e->time;
864
865    ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
866 }
867
868 static void
869 _ecore_xcb_event_handle_focus_out(xcb_generic_event_t *event)
870 {
871    xcb_focus_out_event_t *ev;
872    Ecore_X_Event_Window_Focus_Out *e;
873
874    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
875    ev = (xcb_focus_out_event_t *)event;
876    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out)))) return;
877
878    e->win = ev->event;
879    e->mode = _ecore_xcb_event_mode_get(ev->mode);
880    e->detail = _ecore_xcb_event_detail_get(ev->detail);
881
882    e->time = _ecore_xcb_event_last_time;
883    _ecore_xcb_event_last_time = e->time;
884
885    ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
886 }
887
888 static void
889 _ecore_xcb_event_handle_expose(xcb_generic_event_t *event)
890 {
891    xcb_expose_event_t *ev;
892    Ecore_X_Event_Window_Damage *e;
893
894    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
895    ev = (xcb_expose_event_t *)event;
896    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)))) return;
897
898    e->win = ev->window;
899    e->time = _ecore_xcb_event_last_time;
900    e->x = ev->x;
901    e->y = ev->y;
902    e->w = ev->width;
903    e->h = ev->height;
904    e->count = ev->count;
905
906    ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
907 }
908
909 static void
910 _ecore_xcb_event_handle_graphics_exposure(xcb_generic_event_t *event)
911 {
912    xcb_graphics_exposure_event_t *ev;
913    Ecore_X_Event_Window_Damage *e;
914
915    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
916    ev = (xcb_graphics_exposure_event_t *)event;
917    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Damage)))) return;
918
919    e->win = ev->drawable;
920    e->x = ev->x;
921    e->y = ev->y;
922    e->w = ev->width;
923    e->h = ev->height;
924    e->count = ev->count;
925    e->time = _ecore_xcb_event_last_time;
926
927    ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
928 }
929
930 static void
931 _ecore_xcb_event_handle_visibility_notify(xcb_generic_event_t *event)
932 {
933    xcb_visibility_notify_event_t *ev;
934    Ecore_X_Event_Window_Visibility_Change *e;
935
936    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
937    ev = (xcb_visibility_notify_event_t *)event;
938    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change))))
939      return;
940
941    e->win = ev->window;
942    e->time = _ecore_xcb_event_last_time;
943    if (ev->state == XCB_VISIBILITY_FULLY_OBSCURED)
944      e->fully_obscured = 1;
945    else
946      e->fully_obscured = 0;
947
948    ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
949 }
950
951 static void
952 _ecore_xcb_event_handle_create_notify(xcb_generic_event_t *event)
953 {
954    xcb_create_notify_event_t *ev;
955    Ecore_X_Event_Window_Create *e;
956
957    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
958    ev = (xcb_create_notify_event_t *)event;
959    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Create)))) return;
960
961    e->win = ev->window;
962    e->parent = ev->parent;
963    if (ev->override_redirect)
964      e->override = 1;
965    else
966      e->override = 0;
967    e->x = ev->x;
968    e->y = ev->y;
969    e->w = ev->width;
970    e->h = ev->height;
971    e->border = ev->border_width;
972    e->time = _ecore_xcb_event_last_time;
973
974    ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
975 }
976
977 static void
978 _ecore_xcb_event_handle_destroy_notify(xcb_generic_event_t *event)
979 {
980    xcb_destroy_notify_event_t *ev;
981    Ecore_X_Event_Window_Destroy *e;
982
983    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
984    ev = (xcb_destroy_notify_event_t *)event;
985    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy)))) return;
986
987    e->win = ev->window;
988    e->event_win = ev->event;
989    if (e->win == _ecore_xcb_event_last_window)
990      _ecore_xcb_event_last_window = 0;
991    e->time = _ecore_xcb_event_last_time;
992
993    ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
994 }
995
996 static void
997 _ecore_xcb_event_handle_map_notify(xcb_generic_event_t *event)
998 {
999    xcb_map_notify_event_t *ev;
1000    Ecore_X_Event_Window_Show *e;
1001
1002    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1003    ev = (xcb_map_notify_event_t *)event;
1004    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Show)))) return;
1005
1006    e->win = ev->window;
1007    e->event_win = ev->event;
1008    e->time = _ecore_xcb_event_last_time;
1009
1010    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
1011 }
1012
1013 static void
1014 _ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event)
1015 {
1016    xcb_unmap_notify_event_t *ev;
1017    Ecore_X_Event_Window_Hide *e;
1018
1019    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1020    ev = (xcb_unmap_notify_event_t *)event;
1021    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Hide)))) return;
1022
1023    e->win = ev->window;
1024    e->event_win = ev->event;
1025    e->time = _ecore_xcb_event_last_time;
1026
1027    ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
1028 }
1029
1030 static void
1031 _ecore_xcb_event_handle_map_request(xcb_generic_event_t *event)
1032 {
1033    xcb_map_request_event_t *ev;
1034    Ecore_X_Event_Window_Show_Request *e;
1035
1036    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1037    ev = (xcb_map_request_event_t *)event;
1038    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request)))) return;
1039
1040    e->win = ev->window;
1041    e->parent = ev->parent;
1042    e->time = _ecore_xcb_event_last_time;
1043
1044    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
1045 }
1046
1047 static void
1048 _ecore_xcb_event_handle_reparent_notify(xcb_generic_event_t *event)
1049 {
1050    xcb_reparent_notify_event_t *ev;
1051    Ecore_X_Event_Window_Reparent *e;
1052
1053    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1054    ev = (xcb_reparent_notify_event_t *)event;
1055    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent)))) return;
1056
1057    e->win = ev->window;
1058    e->event_win = ev->event;
1059    e->parent = ev->parent;
1060    e->time = _ecore_xcb_event_last_time;
1061
1062    ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
1063 }
1064
1065 static void
1066 _ecore_xcb_event_handle_configure_notify(xcb_generic_event_t *event)
1067 {
1068    xcb_configure_notify_event_t *ev;
1069    Ecore_X_Event_Window_Configure *e;
1070
1071    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1072    ev = (xcb_configure_notify_event_t *)event;
1073    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Configure)))) return;
1074
1075    e->win = ev->window;
1076    e->event_win = ev->event;
1077    e->abovewin = ev->above_sibling;
1078    e->x = ev->x;
1079    e->y = ev->y;
1080    e->w = ev->width;
1081    e->h = ev->height;
1082    e->border = ev->border_width;
1083    e->override = ev->override_redirect;
1084    /* send_event is bit 7 (0x80) of response_type */
1085    e->from_wm = ((ev->response_type & 0x80) ? 1 : 0);
1086    e->time = _ecore_xcb_event_last_time;
1087
1088    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
1089 }
1090
1091 static void
1092 _ecore_xcb_event_handle_configure_request(xcb_generic_event_t *event)
1093 {
1094    xcb_configure_request_event_t *ev;
1095    Ecore_X_Event_Window_Configure_Request *e;
1096
1097    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1098    ev = (xcb_configure_request_event_t *)event;
1099    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request))))
1100      return;
1101
1102    e->win = ev->window;
1103    e->parent_win = ev->parent;
1104    e->abovewin = ev->sibling;
1105    e->x = ev->x;
1106    e->y = ev->y;
1107    e->w = ev->width;
1108    e->h = ev->height;
1109    e->border = ev->border_width;
1110    e->value_mask = ev->value_mask;
1111    switch (ev->stack_mode)
1112      {
1113       case XCB_STACK_MODE_ABOVE:
1114         e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1115         break;
1116
1117       case XCB_STACK_MODE_BELOW:
1118         e->detail = ECORE_X_WINDOW_STACK_BELOW;
1119         break;
1120
1121       case XCB_STACK_MODE_TOP_IF:
1122         e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
1123         break;
1124
1125       case XCB_STACK_MODE_BOTTOM_IF:
1126         e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
1127         break;
1128
1129       case XCB_STACK_MODE_OPPOSITE:
1130         e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
1131         break;
1132      }
1133    e->time = _ecore_xcb_event_last_time;
1134
1135    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
1136 }
1137
1138 static void
1139 _ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event __UNUSED__)
1140 {
1141 /*
1142    xcb_gravity_notify_event_t *ev;
1143    Ecore_X_Event_Window_Gravity *e;
1144
1145    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1146    ev = (xcb_gravity_notify_event_t *)event;
1147    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Gravity)))) return;
1148
1149    e->win = ev->window;
1150    e->event_win = ev->event;
1151    e->time = _ecore_xcb_event_last_time;
1152
1153    ecore_event_add(ECORE_X_EVENT_WINDOW_GRAVITY, e, NULL, NULL);
1154  */
1155 }
1156
1157 static void
1158 _ecore_xcb_event_handle_resize_request(xcb_generic_event_t *event)
1159 {
1160    xcb_resize_request_event_t *ev;
1161    Ecore_X_Event_Window_Resize_Request *e;
1162
1163    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1164    ev = (xcb_resize_request_event_t *)event;
1165    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request)))) return;
1166
1167    e->win = ev->window;
1168    e->w = ev->width;
1169    e->h = ev->height;
1170    e->time = _ecore_xcb_event_last_time;
1171
1172    ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
1173 }
1174
1175 static void
1176 _ecore_xcb_event_handle_circulate_notify(xcb_generic_event_t *event)
1177 {
1178    xcb_circulate_notify_event_t *ev;
1179    Ecore_X_Event_Window_Stack *e;
1180
1181    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1182    ev = (xcb_circulate_notify_event_t *)event;
1183    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Stack)))) return;
1184
1185    e->win = ev->window;
1186    e->event_win = ev->event;
1187    if (ev->place == XCB_PLACE_ON_TOP)
1188      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1189    else
1190      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1191    e->time = _ecore_xcb_event_last_time;
1192
1193    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
1194 }
1195
1196 static void
1197 _ecore_xcb_event_handle_circulate_request(xcb_generic_event_t *event)
1198 {
1199    xcb_circulate_request_event_t *ev;
1200    Ecore_X_Event_Window_Stack_Request *e;
1201
1202    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1203    ev = (xcb_circulate_request_event_t *)event;
1204    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request)))) return;
1205
1206    e->win = ev->window;
1207    e->parent = ev->event;
1208    if (ev->place == XCB_PLACE_ON_TOP)
1209      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1210    else
1211      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1212    e->time = _ecore_xcb_event_last_time;
1213
1214    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
1215 }
1216
1217 static void
1218 _ecore_xcb_event_handle_property_notify(xcb_generic_event_t *event)
1219 {
1220    xcb_property_notify_event_t *ev;
1221    Ecore_X_Event_Window_Property *e;
1222
1223    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1224    ev = (xcb_property_notify_event_t *)event;
1225    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Property)))) return;
1226
1227    e->win = ev->window;
1228    e->atom = ev->atom;
1229    e->time = ev->time;
1230    _ecore_xcb_event_last_time = e->time;
1231
1232    ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
1233 }
1234
1235 static void
1236 _ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event)
1237 {
1238    xcb_selection_clear_event_t *ev;
1239    Ecore_X_Event_Selection_Clear *e;
1240    Ecore_X_Atom sel;
1241
1242    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1243
1244    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1245    ev = (xcb_selection_clear_event_t *)event;
1246    if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Clear)))) return;
1247
1248    e->win = ev->owner;
1249    e->atom = sel = ev->selection;
1250    if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
1251      e->selection = ECORE_X_SELECTION_PRIMARY;
1252    else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
1253      e->selection = ECORE_X_SELECTION_SECONDARY;
1254    else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1255      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1256    else
1257      e->selection = ECORE_X_SELECTION_OTHER;
1258    e->time = ev->time;
1259
1260    ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
1261 }
1262
1263 static void
1264 _ecore_xcb_event_handle_selection_request(xcb_generic_event_t *event)
1265 {
1266    xcb_selection_request_event_t *ev;
1267    Ecore_X_Event_Selection_Request *e;
1268    Ecore_X_Selection_Intern *sd;
1269
1270    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1271
1272    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1273    ev = (xcb_selection_request_event_t *)event;
1274    if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Request)))) return;
1275
1276    e->owner = ev->owner;
1277    e->requestor = ev->requestor;
1278    e->selection = ev->selection;
1279    e->target = ev->target;
1280    e->property = ev->property;
1281    e->time = ev->time;
1282
1283    ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL);
1284
1285    if ((sd = _ecore_xcb_selection_get(ev->selection)) &&
1286        (sd->win == ev->owner))
1287      {
1288         Ecore_X_Selection_Intern *si;
1289
1290         si = _ecore_xcb_selection_get(ev->selection);
1291         if (si->data)
1292           {
1293              Ecore_X_Atom property = XCB_NONE, type;
1294              void *data = NULL;
1295              int len = 0, typesize = 0;
1296
1297              type = ev->target;
1298              typesize = 8;
1299              len = sd->length;
1300
1301              if (!ecore_x_selection_convert(ev->selection, ev->target,
1302                                             &data, &len, &type, &typesize))
1303                property = XCB_NONE;
1304              else if (data)
1305                {
1306                   ecore_x_window_prop_property_set(ev->requestor, ev->property,
1307                                                    type, typesize, data, len);
1308                   property = ev->property;
1309                   free(data);
1310                }
1311              ecore_x_selection_notify_send(ev->requestor, ev->selection,
1312                                            ev->target, property, ev->time);
1313           }
1314      }
1315 }
1316
1317 static void
1318 _ecore_xcb_event_handle_selection_notify(xcb_generic_event_t *event)
1319 {
1320    xcb_selection_notify_event_t *ev;
1321    Ecore_X_Event_Selection_Notify *e;
1322    unsigned char *data = NULL;
1323    Ecore_X_Atom selection;
1324    int num = 0, format = 0;
1325
1326    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1327
1328    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1329    ev = (xcb_selection_notify_event_t *)event;
1330    selection = ev->selection;
1331    if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS)
1332      {
1333         format =
1334           ecore_x_window_prop_property_get(ev->requestor, ev->property,
1335                                            XCB_ATOM_ATOM, 32, &data, &num);
1336         if (!format) return;
1337      }
1338    else
1339      {
1340         format =
1341           ecore_x_window_prop_property_get(ev->requestor, ev->property,
1342                                            XCB_GET_PROPERTY_TYPE_ANY, 8,
1343                                            &data, &num);
1344         if (!format) return;
1345      }
1346
1347    e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
1348    if (!e) return;
1349    e->win = ev->requestor;
1350    e->time = ev->time;
1351    e->atom = selection;
1352    e->target = _ecore_xcb_selection_target_get(ev->target);
1353
1354    if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
1355      e->selection = ECORE_X_SELECTION_PRIMARY;
1356    else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
1357      e->selection = ECORE_X_SELECTION_SECONDARY;
1358    else if (selection == ECORE_X_ATOM_SELECTION_XDND)
1359      e->selection = ECORE_X_SELECTION_XDND;
1360    else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1361      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1362    else
1363      e->selection = ECORE_X_SELECTION_OTHER;
1364
1365    e->data = _ecore_xcb_selection_parse(e->target, data, num, format);
1366
1367    ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e,
1368                    _ecore_xcb_event_selection_notify_free, NULL);
1369 }
1370
1371 static void
1372 _ecore_xcb_event_handle_colormap_notify(xcb_generic_event_t *event)
1373 {
1374    xcb_colormap_notify_event_t *ev;
1375    Ecore_X_Event_Window_Colormap *e;
1376
1377    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1378    ev = (xcb_colormap_notify_event_t *)event;
1379    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Colormap)))) return;
1380
1381    e->win = ev->window;
1382    e->cmap = ev->colormap;
1383    if (ev->state == XCB_COLORMAP_STATE_INSTALLED)
1384      e->installed = 1;
1385    else
1386      e->installed = 0;
1387    e->time = _ecore_xcb_event_last_time;
1388
1389    ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
1390 }
1391
1392 static void
1393 _ecore_xcb_event_handle_client_message(xcb_generic_event_t *event)
1394 {
1395    xcb_client_message_event_t *ev;
1396
1397    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1398    ev = (xcb_client_message_event_t *)event;
1399
1400    /* Special client message event handling here. need to put LOTS of if */
1401    /* checks here and generate synthetic events per special message known */
1402    /* otherwise generate generic client message event. this would handle*/
1403    /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
1404
1405    if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) && (ev->format == 32) &&
1406        (ev->data.data32[0] == ECORE_X_ATOM_WM_DELETE_WINDOW))
1407      {
1408         Ecore_X_Event_Window_Delete_Request *e;
1409
1410         if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request))))
1411           return;
1412         e->win = ev->window;
1413         e->time = _ecore_xcb_event_last_time;
1414         ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
1415      }
1416    else if ((ev->type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
1417             (ev->format == 32) && (ev->data.data32[2] < 9))
1418      {
1419         Ecore_X_Event_Window_Move_Resize_Request *e;
1420
1421         if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request))))
1422           return;
1423         e->win = ev->window;
1424         e->x = ev->data.data32[0];
1425         e->y = ev->data.data32[1];
1426         e->direction = ev->data.data32[2];
1427         e->button = ev->data.data32[3];
1428         e->source = ev->data.data32[4];
1429         ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
1430      }
1431    else if (ev->type == ECORE_X_ATOM_XDND_ENTER)
1432      {
1433         Ecore_X_Event_Xdnd_Enter *e;
1434         Ecore_X_DND_Target *target;
1435
1436         DBG("Got Xdnd Enter Event");
1437         if (!(e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter)))) return;
1438         target = _ecore_xcb_dnd_target_get();
1439         target->state = ECORE_X_DND_TARGET_ENTERED;
1440         target->source = ev->data.data32[0];
1441         target->win = ev->window;
1442         target->version = (int)(ev->data.data32[1] >> 24);
1443         if (target->version > ECORE_X_DND_VERSION)
1444           {
1445              WRN("DND: Requested version %d but we only support up to %d",
1446                  target->version, ECORE_X_DND_VERSION);
1447              free(e);
1448              return;
1449           }
1450         if (ev->data.data32[1] & 0x1UL)
1451           {
1452              unsigned char *data;
1453              Ecore_X_Atom *types;
1454              int num_ret = 0;
1455
1456              if (!ecore_x_window_prop_property_get(target->source,
1457                                                    ECORE_X_ATOM_XDND_TYPE_LIST,
1458                                                    ECORE_X_ATOM_ATOM, 32,
1459                                                    &data, &num_ret))
1460                {
1461                   WRN("DND: Could not fetch data type list from source window");
1462                   free(e);
1463                   return;
1464                }
1465              types = (Ecore_X_Atom *)data;
1466              e->types = calloc(num_ret, sizeof(char *));
1467              if (e->types)
1468                {
1469                   int i = 0;
1470
1471                   for (i = 0; i < num_ret; i++)
1472                     e->types[i] = ecore_x_atom_name_get(types[i]);
1473                }
1474              e->num_types = num_ret;
1475           }
1476         else
1477           {
1478              int i = 0;
1479
1480              e->types = calloc(3, sizeof(char *));
1481              if (e->types)
1482                {
1483                   while ((i < 3) && (ev->data.data32[i + 2]))
1484                     {
1485                        e->types[i] =
1486                          ecore_x_atom_name_get(ev->data.data32[i + 2]);
1487                        i++;
1488                     }
1489                }
1490              e->num_types = i;
1491           }
1492
1493         e->win = target->win;
1494         e->source = target->source;
1495         ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e,
1496                         _ecore_xcb_event_xdnd_enter_free, NULL);
1497      }
1498    else if (ev->type == ECORE_X_ATOM_XDND_POSITION)
1499      {
1500         Ecore_X_Event_Xdnd_Position *e;
1501         Ecore_X_DND_Target *target;
1502
1503         DBG("Got Xdnd Position Event");
1504         target = _ecore_xcb_dnd_target_get();
1505         if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1506             (target->win != ev->window)) return;
1507         target->pos.x = ev->data.data32[2] >> 16;
1508         target->pos.y = ev->data.data32[2] & 0xFFFFUL;
1509         target->action = ev->data.data32[4];
1510         target->time = (target->version >= 1) ?
1511           (Ecore_X_Time)ev->data.data32[3] : XCB_CURRENT_TIME;
1512
1513         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
1514         if (!e) return;
1515         e->win = target->win;
1516         e->source = target->source;
1517         e->position.x = target->pos.x;
1518         e->position.y = target->pos.y;
1519         e->action = target->action;
1520         ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
1521      }
1522    else if (ev->type == ECORE_X_ATOM_XDND_STATUS)
1523      {
1524         Ecore_X_Event_Xdnd_Status *e;
1525         Ecore_X_DND_Source *source;
1526
1527         DBG("Got Xdnd Status Event");
1528         source = _ecore_xcb_dnd_source_get();
1529         if ((source->win != ev->window) ||
1530             (source->dest != (Ecore_X_Window)ev->data.data32[0]))
1531           return;
1532
1533         source->await_status = 0;
1534         source->will_accept = ev->data.data32[1] & 0x1UL;
1535         source->suppress = (ev->data.data32[1] & 0x2UL) ? 0 : 1;
1536         source->rectangle.x = ev->data.data32[2] >> 16;
1537         source->rectangle.y = ev->data.data32[2] & 0xFFFFUL;
1538         source->rectangle.width = ev->data.data32[3] >> 16;
1539         source->rectangle.height = ev->data.data32[3] & 0xFFFFUL;
1540         source->accepted_action = ev->data.data32[4];
1541
1542         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
1543         if (!e) return;
1544         e->win = source->win;
1545         e->target = source->dest;
1546         e->will_accept = source->will_accept;
1547         e->rectangle.x = source->rectangle.x;
1548         e->rectangle.y = source->rectangle.y;
1549         e->rectangle.width = source->rectangle.width;
1550         e->rectangle.height = source->rectangle.height;
1551         e->action = source->accepted_action;
1552
1553         ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
1554      }
1555    else if (ev->type == ECORE_X_ATOM_XDND_LEAVE)
1556      {
1557         Ecore_X_Event_Xdnd_Leave *e;
1558         Ecore_X_DND_Target *target;
1559
1560         DBG("Got Xdnd Leave Event");
1561         target = _ecore_xcb_dnd_target_get();
1562         if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1563             (target->win != ev->window))
1564           return;
1565         target->state = ECORE_X_DND_TARGET_IDLE;
1566         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
1567         if (!e) return;
1568         e->win = ev->window;
1569         e->source = (Ecore_X_Window)ev->data.data32[0];
1570         ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
1571      }
1572    else if (ev->type == ECORE_X_ATOM_XDND_DROP)
1573      {
1574         Ecore_X_Event_Xdnd_Drop *e;
1575         Ecore_X_DND_Target *target;
1576
1577         DBG("Got Xdnd Drop Event");
1578         target = _ecore_xcb_dnd_target_get();
1579         if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1580             (target->win != ev->window))
1581           return;
1582         target->time = (target->version >= 1) ?
1583           (Ecore_X_Time)ev->data.data32[2] : _ecore_xcb_event_last_time;
1584
1585         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
1586         if (!e) return;
1587         e->win = target->win;
1588         e->source = target->source;
1589         e->action = target->action;
1590         e->position.x = target->pos.x;
1591         e->position.y = target->pos.y;
1592         ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
1593      }
1594    else if (ev->type == ECORE_X_ATOM_XDND_FINISHED)
1595      {
1596         Ecore_X_Event_Xdnd_Finished *e;
1597         Ecore_X_DND_Source *source;
1598         Eina_Bool completed = EINA_TRUE;
1599
1600         DBG("Got Xdnd Finished Event");
1601         source = _ecore_xcb_dnd_source_get();
1602         if ((source->win != ev->window) ||
1603             (source->dest != (Ecore_X_Window)ev->data.data32[0]))
1604           return;
1605         if ((source->version < 5) || (ev->data.data32[1] & 0x1UL))
1606           {
1607              ecore_x_selection_xdnd_clear();
1608              source->state = ECORE_X_DND_SOURCE_IDLE;
1609           }
1610         else if (source->version >= 5)
1611           {
1612              completed = EINA_FALSE;
1613              source->state = ECORE_X_DND_SOURCE_CONVERTING;
1614              /* FIXME: Probably need to add a timer to switch back to idle
1615               * and discard the selection data */
1616           }
1617
1618         if (!(e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished))))
1619           return;
1620         e->win = source->win;
1621         e->target = source->dest;
1622         e->completed = completed;
1623         if (source->version >= 5)
1624           {
1625              source->accepted_action = ev->data.data32[2];
1626              e->action = source->accepted_action;
1627           }
1628         else
1629           {
1630              source->accepted_action = 0;
1631              e->action = source->action;
1632           }
1633         ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
1634      }
1635    else if (ev->type == ECORE_X_ATOM_NET_WM_STATE)
1636      {
1637         Ecore_X_Event_Window_State_Request *e;
1638
1639         if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request))))
1640           return;
1641         e->win = ev->window;
1642         if (ev->data.data32[0] == 0)
1643           e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
1644         else if (ev->data.data32[0] == 1)
1645           e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1646         else if (ev->data.data32[0] == 2)
1647           e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
1648         else
1649           {
1650              free(e);
1651              return;
1652           }
1653         e->state[0] = _ecore_xcb_netwm_window_state_get(ev->data.data32[1]);
1654         if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
1655           {
1656              /* FIXME */
1657           }
1658         e->state[1] = _ecore_xcb_netwm_window_state_get(ev->data.data32[2]);
1659         if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
1660           {
1661              /* FIXME */
1662           }
1663         e->source = ev->data.data32[3];
1664         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1665      }
1666 #ifdef OLD_XCB_VERSION
1667    else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) &&
1668             (ev->format == 32) && (ev->data.data32[0] == XCB_WM_STATE_ICONIC))
1669 #else
1670    else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) && (ev->format == 32) &&
1671             (ev->data.data32[0] == XCB_ICCCM_WM_STATE_ICONIC))
1672 #endif
1673      {
1674         Ecore_X_Event_Window_State_Request *e;
1675
1676         if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request))))
1677           return;
1678         e->win = ev->window;
1679         e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1680         e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
1681         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1682      }
1683    else if ((ev->type == ECORE_X_ATOM_NET_WM_DESKTOP) && (ev->format == 32))
1684      {
1685         Ecore_X_Event_Desktop_Change *e;
1686
1687         if (!(e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change))))
1688           return;
1689         e->win = ev->window;
1690         e->desk = ev->data.data32[0];
1691         e->source = ev->data.data32[1];
1692         ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
1693      }
1694    else if (ev->type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS)
1695      {
1696         Ecore_X_Event_Frame_Extents_Request *e;
1697
1698         if (!(e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request))))
1699           return;
1700         e->win = ev->window;
1701         ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
1702      }
1703    else if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) &&
1704             ((Ecore_X_Atom)ev->data.data32[0] == ECORE_X_ATOM_NET_WM_PING) &&
1705             (ev->format == 32))
1706      {
1707         Ecore_X_Event_Ping *e;
1708         Ecore_X_Window root = 0;
1709         int count = 0;
1710
1711         if (!(e = calloc(1, sizeof(Ecore_X_Event_Ping)))) return;
1712         e->win = ev->window;
1713         e->time = ev->data.data32[1];
1714         e->event_win = ev->data.data32[2];
1715         ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
1716
1717         CHECK_XCB_CONN;
1718
1719         count = xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn));
1720         if (count > 1)
1721           root = ecore_x_window_root_get(e->win);
1722         else
1723           root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1724
1725         if (ev->window != root)
1726           {
1727              ev->window = root;
1728              xcb_send_event(_ecore_xcb_conn, 0, root,
1729                             (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
1730                              XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY),
1731                             (const char *)&ev);
1732 //             ecore_x_flush();
1733           }
1734      }
1735    else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
1736             (ev->format == 8))
1737      {
1738         _ecore_xcb_netwm_startup_info_begin(ev->window, ev->data.data8[0]);
1739      }
1740    else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO) && (ev->format == 8))
1741      {
1742         _ecore_xcb_netwm_startup_info(ev->window, ev->data.data8[0]);
1743      }
1744    else if ((ev->type == 27777) && (ev->data.data32[0] == 0x7162534) &&
1745             (ev->format == 32)) // && (ev->window = _private_window))
1746      {
1747         if (ev->data.data32[1] == 0x10000001)
1748           _ecore_xcb_window_button_grab_remove(ev->data.data32[2]);
1749         else if (ev->data.data32[1] == 0x10000002)
1750           _ecore_xcb_window_key_grab_remove(ev->data.data32[2]);
1751      }
1752    else
1753      {
1754         Ecore_X_Event_Client_Message *e;
1755         int i = 0;
1756
1757         if (!(e = calloc(1, sizeof(Ecore_X_Event_Client_Message))))
1758           return;
1759
1760         e->win = ev->window;
1761         e->message_type = ev->type;
1762         e->format = ev->format;
1763         for (i = 0; i < 5; i++)
1764           e->data.l[i] = ev->data.data32[i];
1765         ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
1766      }
1767 }
1768
1769 static void
1770 _ecore_xcb_event_handle_mapping_notify(xcb_generic_event_t *event)
1771 {
1772    xcb_mapping_notify_event_t *ev;
1773    Ecore_X_Event_Mapping_Change *e;
1774
1775    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1776
1777    ev = (xcb_mapping_notify_event_t *)event;
1778    if (!(e = calloc(1, sizeof(Ecore_X_Event_Mapping_Change)))) return;
1779
1780    _ecore_xcb_keymap_refresh(ev);
1781    _ecore_xcb_modifiers_get();
1782
1783    switch (ev->request)
1784      {
1785       case XCB_MAPPING_MODIFIER:
1786         e->type = ECORE_X_MAPPING_MODIFIER;
1787         break;
1788
1789       case XCB_MAPPING_KEYBOARD:
1790         e->type = ECORE_X_MAPPING_KEYBOARD;
1791         break;
1792
1793       case XCB_MAPPING_POINTER:
1794       default:
1795         e->type = ECORE_X_MAPPING_MOUSE;
1796         break;
1797      }
1798    e->keycode = ev->first_keycode;
1799    e->num = ev->count;
1800
1801    ecore_event_add(ECORE_X_EVENT_MAPPING_CHANGE, e, NULL, NULL);
1802 }
1803
1804 static void
1805 _ecore_xcb_event_handle_damage_notify(xcb_generic_event_t *event)
1806 {
1807 #ifdef ECORE_XCB_DAMAGE
1808    xcb_damage_notify_event_t *ev;
1809    Ecore_X_Event_Damage *e;
1810 #endif
1811
1812    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1813
1814    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1815 #ifdef ECORE_XCB_DAMAGE
1816    ev = (xcb_damage_notify_event_t *)event;
1817    if (!(e = calloc(1, sizeof(Ecore_X_Event_Damage)))) return;
1818
1819    e->level = ev->level;
1820    e->drawable = ev->drawable;
1821    e->damage = ev->damage;
1822    e->time = ev->timestamp;
1823    e->area.x = ev->area.x;
1824    e->area.y = ev->area.y;
1825    e->area.width = ev->area.width;
1826    e->area.height = ev->area.height;
1827    e->geometry.x = ev->geometry.x;
1828    e->geometry.y = ev->geometry.y;
1829    e->geometry.width = ev->geometry.width;
1830    e->geometry.height = ev->geometry.height;
1831
1832    ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
1833 #endif
1834 }
1835
1836 static void
1837 _ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event)
1838 {
1839 #ifdef ECORE_XCB_RANDR
1840    xcb_randr_screen_change_notify_event_t *ev;
1841    Ecore_X_Event_Screen_Change *e;
1842 #endif
1843
1844    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1845 #ifdef ECORE_XCB_RANDR
1846    ev = (xcb_randr_screen_change_notify_event_t *)event;
1847    if (!(e = calloc(1, sizeof(Ecore_X_Event_Screen_Change)))) return;
1848
1849    e->win = ev->request_window;
1850    e->root = ev->root;
1851    e->size.width = ev->width;
1852    e->size.height = ev->height;
1853    e->time = ev->timestamp;
1854    e->config_time = ev->config_timestamp;
1855    e->size.width_mm = ev->mwidth;
1856    e->size.height_mm = ev->mheight;
1857    e->orientation = ev->rotation;
1858    e->subpixel_order = ev->subpixel_order;
1859
1860    ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
1861 #endif
1862 }
1863
1864 static void
1865 _ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event)
1866 {
1867 #ifdef ECORE_XCB_RANDR
1868    xcb_randr_notify_event_t *ev;
1869 #endif
1870
1871    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1872 #ifdef ECORE_XCB_RANDR
1873    ev = (xcb_randr_notify_event_t *)event;
1874    switch (ev->subCode)
1875      {
1876       case XCB_RANDR_NOTIFY_CRTC_CHANGE:
1877         _ecore_xcb_event_handle_randr_crtc_change(event);
1878         break;
1879
1880       case XCB_RANDR_NOTIFY_OUTPUT_CHANGE:
1881         _ecore_xcb_event_handle_randr_output_change(event);
1882         break;
1883
1884       case XCB_RANDR_NOTIFY_OUTPUT_PROPERTY:
1885         _ecore_xcb_event_handle_randr_output_property_change(event);
1886         break;
1887
1888       default:
1889         break;
1890      }
1891 #endif
1892 }
1893
1894 static void
1895 _ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event)
1896 {
1897 #ifdef ECORE_XCB_RANDR
1898    xcb_randr_notify_event_t *ev;
1899    Ecore_X_Event_Randr_Crtc_Change *e;
1900 #endif
1901
1902 #ifdef ECORE_XCB_RANDR
1903    ev = (xcb_randr_notify_event_t *)event;
1904    if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change))))
1905      return;
1906
1907    e->win = ev->u.cc.window;
1908    e->crtc = ev->u.cc.crtc;
1909    e->mode = ev->u.cc.mode;
1910    e->orientation = ev->u.cc.rotation;
1911    e->geo.x = ev->u.cc.x;
1912    e->geo.y = ev->u.cc.y;
1913    e->geo.w = ev->u.cc.width;
1914    e->geo.h = ev->u.cc.height;
1915
1916    ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL);
1917 #endif
1918 }
1919
1920 static void
1921 _ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event)
1922 {
1923 #ifdef ECORE_XCB_RANDR
1924    xcb_randr_notify_event_t *ev;
1925    Ecore_X_Event_Randr_Output_Change *e;
1926 #endif
1927
1928 #ifdef ECORE_XCB_RANDR
1929    ev = (xcb_randr_notify_event_t *)event;
1930    if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change))))
1931      return;
1932
1933    e->win = ev->u.oc.window;
1934    e->output = ev->u.oc.output;
1935    e->crtc = ev->u.oc.crtc;
1936    e->mode = ev->u.oc.mode;
1937    e->orientation = ev->u.oc.rotation;
1938    e->connection = ev->u.oc.connection;
1939    e->subpixel_order = ev->u.oc.subpixel_order;
1940
1941    ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, e, NULL, NULL);
1942 #endif
1943 }
1944
1945 static void
1946 _ecore_xcb_event_handle_randr_output_property_change(xcb_generic_event_t *event)
1947 {
1948 #ifdef ECORE_XCB_RANDR
1949    xcb_randr_notify_event_t *ev;
1950    Ecore_X_Event_Randr_Output_Property_Notify *e;
1951 #endif
1952
1953 #ifdef ECORE_XCB_RANDR
1954    ev = (xcb_randr_notify_event_t *)event;
1955    if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Property_Notify))))
1956      return;
1957
1958    e->win = ev->u.op.window;
1959    e->output = ev->u.op.output;
1960    e->property = ev->u.op.atom;
1961    e->time = ev->u.op.timestamp;
1962    if (ev->u.op.status == XCB_PROPERTY_NEW_VALUE)
1963      e->state = ECORE_X_RANDR_PROPERTY_CHANGE_ADD;
1964    else
1965      e->state = ECORE_X_RANDR_PROPERTY_CHANGE_DEL;
1966
1967    ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, e, NULL, NULL);
1968 #endif
1969 }
1970
1971 static void
1972 _ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event)
1973 {
1974 #ifdef ECORE_XCB_SCREENSAVER
1975    xcb_screensaver_notify_event_t *ev;
1976    Ecore_X_Event_Screensaver_Notify *e;
1977 #endif
1978
1979    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1980 #ifdef ECORE_XCB_SCREENSAVER
1981    ev = (xcb_screensaver_notify_event_t *)event;
1982    if (!(e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify)))) return;
1983
1984    e->win = ev->window;
1985    e->on = EINA_FALSE;
1986    if (ev->state == XCB_SCREENSAVER_STATE_ON) e->on = EINA_TRUE;
1987    e->time = ev->time;
1988
1989    ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
1990 #endif
1991 }
1992
1993 #ifdef ECORE_XCB_XGESTURE
1994 static void
1995 _ecore_xcb_event_handle_gesture_notify_flick(xcb_generic_event_t *event)
1996 {
1997    xcb_gesture_notify_flick_event_t *ev;
1998    Ecore_X_Event_Gesture_Notify_Flick *e;
1999
2000    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2001    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2002    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2003
2004    ev = (xcb_gesture_notify_flick_event_t *)event;
2005    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Flick)))) return;
2006
2007    e->win = ev->window;
2008    e->time = ev->time;
2009    e->subtype = ev->kind;
2010    e->num_fingers = ev->num_finger;
2011    e->distance = ev->distance;
2012    e->duration = ev->duration;
2013    e->direction = ev->direction;
2014    e->angle = XFixedToDouble(ev->angle);
2015
2016    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_FLICK, e, NULL, NULL);
2017 }
2018
2019 static void
2020 _ecore_xcb_event_handle_gesture_notify_pan(xcb_generic_event_t *event)
2021 {
2022    xcb_gesture_notify_pan_event_t *ev;
2023    Ecore_X_Event_Gesture_Notify_Pan *e;
2024
2025    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2026    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2027    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2028
2029    ev = (xcb_gesture_notify_pan_event_t *)event;
2030    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Pan)))) return;
2031
2032    e->win = ev->window;
2033    e->time = ev->time;
2034    e->subtype = ev->kind;
2035    e->num_fingers = ev->num_finger;
2036    e->dx = ev->dx;
2037    e->dy = ev->dy;
2038    e->distance = ev->distance;
2039    e->duration = ev->duration;
2040    e->direction = ev->direction;
2041
2042    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PAN, e, NULL, NULL);
2043 }
2044
2045 static void
2046 _ecore_xcb_event_handle_gesture_notify_pinchrotation(xcb_generic_event_t *event)
2047 {
2048    xcb_gesture_notify_pinch_rotation_event_t *ev;
2049    Ecore_X_Event_Gesture_Notify_PinchRotation *e;
2050
2051    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2052    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2053    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2054
2055    ev = (xcb_gesture_notify_pinch_rotation_event_t *)event;
2056    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_PinchRotation)))) return;
2057
2058    e->win = ev->window;
2059    e->time = ev->time;
2060    e->subtype = ev->kind;
2061    e->num_fingers = ev->num_finger;
2062    e->distance = ev->distance;
2063    e->cx = ev->cx;
2064    e->cy = ev->cy;
2065    e->zoom = XFixedToDouble(ev->zoom);
2066    e->angle = XFixedToDouble(ev->angle);
2067
2068    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION, e, NULL, NULL);
2069 }
2070
2071 static void
2072 _ecore_xcb_event_handle_gesture_notify_tap(xcb_generic_event_t *event)
2073 {
2074    xcb_gesture_notify_tap_event_t *ev;
2075    Ecore_X_Event_Gesture_Notify_Tap *e;
2076
2077    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2078    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2079    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2080
2081    ev = (xcb_gesture_notify_tap_event_t *)event;
2082    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Tap)))) return;
2083
2084    e->win = ev->window;
2085    e->time = ev->time;
2086    e->subtype = ev->kind;
2087    e->num_fingers = ev->num_finger;
2088    e->cx = ev->cx;
2089    e->cy = ev->cy;
2090    e->tap_repeat = ev->tap_repeat;
2091    e->interval = ev->interval;
2092
2093    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAP, e, NULL, NULL);
2094 }
2095
2096 static void
2097 _ecore_xcb_event_handle_gesture_notify_tapnhold(xcb_generic_event_t *event)
2098 {
2099    xcb_gesture_notify_tap_n_hold_event_t *ev;
2100    Ecore_X_Event_Gesture_Notify_TapNHold *e;
2101
2102    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2103    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2104    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2105
2106    ev = (xcb_gesture_notify_tap_n_hold_event_t *)event;
2107    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_TapNHold)))) return;
2108
2109    e->win = ev->window;
2110    e->time = ev->time;
2111    e->subtype = ev->kind;
2112    e->num_fingers = ev->num_finger;
2113    e->cx = ev->cx;
2114    e->cy = ev->cy;
2115    e->interval = ev->interval;
2116    e->hold_time = ev->holdtime;
2117
2118    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD, e, NULL, NULL);
2119 }
2120
2121 static void
2122  _ecore_xcb_event_handle_gesture_notify_hold(xcb_generic_event_t *event)
2123 {
2124    xcb_gesture_notify_hold_event_t *ev;
2125    Ecore_X_Event_Gesture_Notify_Hold *e;
2126
2127    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2128    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2129    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2130
2131    ev = (xcb_gesture_notify_hold_event_t *)event;
2132    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Hold)))) return;
2133
2134    e->win = ev->window;
2135    e->time = ev->time;
2136    e->subtype = ev->kind;
2137    e->num_fingers = ev->num_finger;
2138    e->cx = ev->cx;
2139    e->cy = ev->cy;
2140    e->hold_time = ev->holdtime;
2141
2142    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_HOLD, e, NULL, NULL);
2143 }
2144
2145 static void
2146  _ecore_xcb_event_handle_gesture_notify_group(xcb_generic_event_t *event)
2147 {
2148    xcb_gesture_notify_group_event_t *ev;
2149    Ecore_X_Event_Gesture_Notify_Group *e;
2150
2151    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2152    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2153    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2154
2155    ev = (xcb_gesture_notify_group_event_t *)event;
2156    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Group)))) return;
2157
2158    e->win = ev->window;
2159    e->time = ev->time;
2160    e->subtype = ev->kind;
2161    e->num_groups = ev->num_group;
2162    e->group_id = ev->groupid;
2163
2164    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_GROUP, e, NULL, NULL);
2165 }
2166 #endif
2167
2168 #ifdef ECORE_XCB_SHAPE
2169 static void
2170 _ecore_xcb_event_handle_shape_change(xcb_generic_event_t *event)
2171 {
2172    xcb_shape_notify_event_t *ev;
2173    Ecore_X_Event_Window_Shape *e;
2174
2175    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2176    ev = (xcb_shape_notify_event_t *)event;
2177    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Shape)))) return;
2178
2179    e->win = ev->affected_window;
2180    e->time = ev->server_time;
2181    switch (ev->shape_kind)
2182      {
2183       case XCB_SHAPE_SK_BOUNDING:
2184         e->type = ECORE_X_SHAPE_BOUNDING;
2185         break;
2186
2187       case XCB_SHAPE_SK_CLIP:
2188         e->type = ECORE_X_SHAPE_CLIP;
2189         break;
2190
2191       case XCB_SHAPE_SK_INPUT:
2192         e->type = ECORE_X_SHAPE_INPUT;
2193         break;
2194
2195       default:
2196         break;
2197      }
2198    e->x = ev->extents_x;
2199    e->y = ev->extents_y;
2200    e->w = ev->extents_width;
2201    e->h = ev->extents_height;
2202    e->shaped = ev->shaped;
2203
2204    ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
2205 }
2206
2207 #endif
2208
2209 static void
2210 _ecore_xcb_event_handle_sync_counter(xcb_generic_event_t *event)
2211 {
2212 #ifdef ECORE_XCB_SYNC
2213    xcb_sync_counter_notify_event_t *ev;
2214    Ecore_X_Event_Sync_Counter *e;
2215 #endif
2216
2217    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2218
2219 #ifdef ECORE_XCB_SYNC
2220    ev = (xcb_sync_counter_notify_event_t *)event;
2221    if (!(e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter)))) return;
2222
2223    e->time = ev->timestamp;
2224
2225    ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
2226 #endif
2227 }
2228
2229 static void
2230 _ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event)
2231 {
2232 #ifdef ECORE_XCB_SYNC
2233    xcb_sync_alarm_notify_event_t *ev;
2234    Ecore_X_Event_Sync_Alarm *e;
2235 #endif
2236
2237    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2238 #ifdef ECORE_XCB_SYNC
2239    ev = (xcb_sync_alarm_notify_event_t *)event;
2240    if (!(e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm)))) return;
2241
2242    e->time = ev->timestamp;
2243    e->alarm = ev->alarm;
2244
2245    ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
2246 #endif
2247 }
2248
2249 static void
2250 _ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event)
2251 {
2252 #ifdef ECORE_XCB_XFIXES
2253    Ecore_X_Event_Fixes_Selection_Notify *e;
2254    Ecore_X_Atom sel;
2255    xcb_xfixes_selection_notify_event_t *ev;
2256 #endif
2257
2258    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2259 #ifdef ECORE_XCB_XFIXES
2260    ev = (xcb_xfixes_selection_notify_event_t *)event;
2261
2262    if (!(e = calloc(1, sizeof(*e)))) return;
2263
2264    e->win = ev->window;
2265    e->owner = ev->owner;
2266    e->time = ev->timestamp;
2267    e->selection_time = ev->selection_timestamp;
2268    e->atom = sel = ev->selection;
2269    if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
2270      e->selection = ECORE_X_SELECTION_PRIMARY;
2271    else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
2272      e->selection = ECORE_X_SELECTION_SECONDARY;
2273    else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
2274      e->selection = ECORE_X_SELECTION_CLIPBOARD;
2275    else
2276      e->selection = ECORE_X_SELECTION_OTHER;
2277    e->reason = ev->subtype;
2278
2279    ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL);
2280 #endif
2281 }
2282
2283 static void
2284 _ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event __UNUSED__)
2285 {
2286    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2287 //  FIXME: TBD
2288 }
2289
2290 static void
2291 _ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event)
2292 {
2293    xcb_ge_event_t *ev;
2294    Ecore_X_Event_Generic *e;
2295
2296    ev = (xcb_ge_event_t *)event;
2297
2298    /* pad0 *IS* extension - bug in xcb */
2299    if (ev->pad0 == _ecore_xcb_event_input)
2300      {
2301         _ecore_xcb_event_handle_input_event(event);
2302 // FIXME: should we generate generic events as WELL as input events?
2303 //        return;
2304      }
2305
2306    if (!(e = calloc(1, sizeof(Ecore_X_Event_Generic))))
2307      return;
2308
2309    DBG("Handle Generic Event: %d", ev->event_type);
2310
2311    e->cookie = ev->sequence;
2312    /* NB: These are bugs in xcb ge_event structure. The struct should have a
2313     * field for extension & data, but does not.
2314     *
2315     * XCB people have been notified of this issue */
2316    e->extension = ev->pad0;
2317    /* e->data = ev->pad1; */
2318    if (ev->length > 0)
2319      {
2320         int len = ev->length * sizeof(int);
2321         e->data = malloc(len);
2322         if (e->data) memcpy(e->data, &(event[1]), len);
2323      }
2324
2325    e->evtype = ev->event_type;
2326
2327    ecore_event_add(ECORE_X_EVENT_GENERIC, e,
2328                    _ecore_xcb_event_generic_event_free, e->data);
2329 }
2330
2331 static void
2332 _ecore_xcb_event_handle_input_event(xcb_generic_event_t *event)
2333 {
2334    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2335
2336    _ecore_xcb_input_handle_event(event);
2337 }
2338
2339 static void
2340 _ecore_xcb_event_key_press(xcb_generic_event_t *event)
2341 {
2342    Ecore_Event_Key *e;
2343    xcb_keysym_t sym = XCB_NO_SYMBOL;
2344    xcb_keycode_t keycode = 0;
2345    xcb_key_press_event_t *xevent;
2346    char *keyname = NULL, *key = NULL;
2347    char *compose = NULL;
2348    char compose_buffer[256];
2349    int val = 0;
2350
2351    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2352
2353    xevent = (xcb_key_press_event_t *)event;
2354    keycode = xevent->detail;
2355
2356    sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, xevent->state);
2357    keyname = _ecore_xcb_keymap_keysym_to_string(sym);
2358    if (!keyname)
2359      {
2360         char buff[256];
2361
2362         snprintf(buff, sizeof(buff), "Keycode-%i", keycode);
2363         keyname = buff;
2364      }
2365
2366    val =
2367      _ecore_xcb_keymap_lookup_string(keycode, xevent->state, compose_buffer,
2368                                      sizeof(compose_buffer), &sym);
2369    if (val > 0)
2370      {
2371         compose_buffer[val] = 0;
2372         compose =
2373           eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer);
2374         if (!compose)
2375           ERR("Ecore_X cannot convert input key string '%s' to UTF-8. "
2376               "Is Eina built with iconv support?", compose_buffer);
2377      }
2378
2379    key = _ecore_xcb_keymap_keysym_to_string(sym);
2380    if (!key) key = keyname;
2381
2382    e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) +
2383               (compose ? strlen(compose) : 0) + 3);
2384    if (e)
2385      {
2386         e->keyname = (char *)(e + 1);
2387         e->key = e->keyname + strlen(keyname) + 1;
2388
2389         e->compose = NULL;
2390         if (compose) e->compose = (e->key + strlen(key) + 1);
2391         e->string = e->compose;
2392
2393         strcpy((char *)e->keyname, keyname);
2394         strcpy((char *)e->key, key);
2395         if (compose) strcpy((char *)e->compose, compose);
2396
2397         e->modifiers = _ecore_xcb_events_modifiers_get(xevent->state);
2398         e->timestamp = xevent->time;
2399         e->window = xevent->child ? xevent->child : xevent->event;
2400         e->event_window = xevent->event;
2401         e->same_screen = xevent->same_screen;
2402         e->root_window = xevent->root;
2403
2404         DBG("Sending Key Down Event: %s", e->keyname);
2405         ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL);
2406      }
2407    _ecore_xcb_event_last_time = xevent->time;
2408 }
2409
2410 static void
2411 _ecore_xcb_event_key_release(xcb_generic_event_t *event)
2412 {
2413    Ecore_Event_Key *e;
2414    xcb_keysym_t sym = XCB_NO_SYMBOL;
2415    xcb_keycode_t keycode = 0;
2416    xcb_key_release_event_t *xevent;
2417    char *keyname = NULL, *key = NULL;
2418    char *compose = NULL;
2419    char compose_buffer[256];
2420    int val = 0;
2421
2422    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2423
2424    xevent = (xcb_key_release_event_t *)event;
2425    keycode = xevent->detail;
2426
2427    sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, xevent->state);
2428    keyname = _ecore_xcb_keymap_keysym_to_string(sym);
2429    if (!keyname)
2430      {
2431         char buff[256];
2432
2433         snprintf(buff, sizeof(buff), "Keycode-%i", keycode);
2434         keyname = buff;
2435      }
2436
2437    val =
2438      _ecore_xcb_keymap_lookup_string(keycode, xevent->state, compose_buffer,
2439                                      sizeof(compose_buffer), &sym);
2440    if (val > 0)
2441      {
2442         compose_buffer[val] = 0;
2443         compose =
2444           eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer);
2445 //        tmp = compose;
2446      }
2447
2448    key = _ecore_xcb_keymap_keysym_to_string(sym);
2449    if (!key) key = keyname;
2450
2451    e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) +
2452               (compose ? strlen(compose) : 0) + 3);
2453    if (e)
2454      {
2455         e->keyname = (char *)(e + 1);
2456         e->key = e->keyname + strlen(keyname) + 1;
2457
2458         e->compose = NULL;
2459         if (compose) e->compose = (e->key + strlen(key) + 1);
2460         e->string = e->compose;
2461
2462         strcpy((char *)e->keyname, keyname);
2463         strcpy((char *)e->key, key);
2464         if (compose) strcpy((char *)e->compose, compose);
2465
2466         e->modifiers = _ecore_xcb_events_modifiers_get(xevent->state);
2467         e->timestamp = xevent->time;
2468         e->window = xevent->child ? xevent->child : xevent->event;
2469         e->event_window = xevent->event;
2470         e->same_screen = xevent->same_screen;
2471         e->root_window = xevent->root;
2472
2473         ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL);
2474      }
2475    _ecore_xcb_event_last_time = xevent->time;
2476 }
2477
2478 void
2479 _ecore_xcb_event_mouse_move(uint16_t     timestamp,
2480                             uint16_t     modifiers,
2481                             int16_t      x,
2482                             int16_t      y,
2483                             int16_t      root_x,
2484                             int16_t      root_y,
2485                             xcb_window_t event_win,
2486                             xcb_window_t win,
2487                             xcb_window_t root_win,
2488                             uint8_t      same_screen,
2489                             int          dev,
2490                             double       radx,
2491                             double       rady,
2492                             double       pressure,
2493                             double       angle,
2494                             int16_t      mx,
2495                             int16_t      my,
2496                             int16_t      mrx,
2497                             int16_t      mry)
2498 {
2499    Ecore_Event_Mouse_Move *e;
2500    Ecore_Event *event;
2501
2502    if (!(e = malloc(sizeof(Ecore_Event_Mouse_Move)))) return;
2503
2504    e->window = win;
2505    e->root_window = root_win;
2506    e->timestamp = timestamp;
2507    e->same_screen = same_screen;
2508    e->event_window = event_win;
2509    e->modifiers = _ecore_xcb_events_modifiers_get(modifiers);
2510    e->x = x;
2511    e->y = y;
2512    e->root.x = root_x;
2513    e->root.y = root_y;
2514    e->multi.device = dev;
2515    e->multi.radius = ((radx + rady) / 2);
2516    e->multi.radius_x = radx;
2517    e->multi.radius_y = rady;
2518    e->multi.pressure = pressure;
2519    e->multi.angle = angle;
2520    e->multi.x = mx;
2521    e->multi.y = my;
2522    e->multi.root.x = mrx;
2523    e->multi.root.y = mry;
2524
2525    event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e,
2526                            _ecore_xcb_event_mouse_move_free, NULL);
2527
2528    _ecore_xcb_event_last_time = e->timestamp;
2529    _ecore_xcb_event_last_window = e->window;
2530    _ecore_xcb_event_last_root_x = root_x;
2531    _ecore_xcb_event_last_root_y = root_y;
2532 //   _ecore_xcb_event_last_mouse_move_event = event;
2533 }
2534
2535 static void
2536 _ecore_xcb_event_mouse_move_free(void *data __UNUSED__,
2537                                  void *event)
2538 {
2539    Ecore_Event_Mouse_Move *ev;
2540
2541    ev = event;
2542 //   if (_ecore_xcb_event_last_mouse_move_event)
2543 //     {
2544 //        _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2545 //        _ecore_xcb_event_last_mouse_move_event = NULL;
2546 //     }
2547    if (ev) free(ev);
2548 }
2549
2550 Ecore_Event_Mouse_Button *
2551 _ecore_xcb_event_mouse_button(int          event,
2552                               uint16_t     timestamp,
2553                               uint16_t     modifiers,
2554                               xcb_button_t buttons,
2555                               int16_t      x,
2556                               int16_t      y,
2557                               int16_t      root_x,
2558                               int16_t      root_y,
2559                               xcb_window_t event_win,
2560                               xcb_window_t win,
2561                               xcb_window_t root_win,
2562                               uint8_t      same_screen,
2563                               int          dev,
2564                               double       radx,
2565                               double       rady,
2566                               double       pressure,
2567                               double       angle,
2568                               int16_t      mx,
2569                               int16_t      my,
2570                               int16_t      mrx,
2571                               int16_t      mry)
2572 {
2573    Ecore_Event_Mouse_Button *e;
2574    Ecore_X_Mouse_Down_Info *info = NULL;
2575
2576    if (!(e = malloc(sizeof(Ecore_Event_Mouse_Button)))) return NULL;
2577
2578    e->window = win;
2579    e->root_window = root_win;
2580    e->timestamp = timestamp;
2581    e->same_screen = same_screen;
2582    e->event_window = event_win;
2583    e->buttons = buttons;
2584    e->modifiers = _ecore_xcb_events_modifiers_get(modifiers);
2585    e->double_click = 0;
2586    e->triple_click = 0;
2587    e->x = x;
2588    e->y = y;
2589    e->root.x = root_x;
2590    e->root.y = root_y;
2591
2592    if ((info = _ecore_xcb_event_mouse_down_info_get(dev)))
2593      {
2594         if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
2595             (info->did_triple))
2596           {
2597              info->last_win = 0;
2598              info->last_last_win = 0;
2599              info->last_event_win = 0;
2600              info->last_time = 0;
2601              info->last_last_time = 0;
2602           }
2603         if (event_win == win)
2604           {
2605              if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN)
2606                {
2607                   if (((int)(timestamp - info->last_time) <=
2608                        (int)(1000 * _ecore_xcb_double_click_time)) &&
2609                       (win == info->last_win) &&
2610                       (event_win == info->last_event_win))
2611                     {
2612                        e->double_click = 1;
2613                        info->did_double = EINA_TRUE;
2614                     }
2615                   else
2616                     {
2617                        info->did_double = EINA_FALSE;
2618                        info->did_triple = EINA_FALSE;
2619                     }
2620                   if (((int)(timestamp - info->last_last_time) <=
2621                        (int)(2 * 1000 * _ecore_xcb_double_click_time)) &&
2622                       (win == info->last_win) &&
2623                       (win == info->last_last_win) &&
2624                       (event_win == info->last_event_win) &&
2625                       (event_win == info->last_last_event_win))
2626                     {
2627                        e->triple_click = 1;
2628                        info->did_triple = EINA_TRUE;
2629                     }
2630                   else
2631                     info->did_triple = EINA_FALSE;
2632                }
2633              else
2634                {
2635                   if (info->did_double) e->double_click = 1;
2636                   if (info->did_triple) e->triple_click = 1;
2637                }
2638           }
2639      }
2640
2641    /* NB: Comment out right now because _ecore_xcb_mouse_up_count is
2642     * only used here...nowhere else in the code */
2643
2644    /* if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&  */
2645    /*     (!e->double_click) && (!e->triple_click)) */
2646    /*   _ecore_xcb_mouse_up_count = 0; */
2647
2648    e->multi.device = dev;
2649    e->multi.radius = ((radx + rady) / 2);
2650    e->multi.radius_x = radx;
2651    e->multi.radius_y = rady;
2652    e->multi.pressure = pressure;
2653    e->multi.angle = angle;
2654    e->multi.x = mx;
2655    e->multi.y = my;
2656    e->multi.root.x = mrx;
2657    e->multi.root.y = mry;
2658
2659    _ecore_xcb_event_last_time = e->timestamp;
2660    _ecore_xcb_event_last_window = e->window;
2661    _ecore_xcb_event_last_root_x = root_x;
2662    _ecore_xcb_event_last_root_y = root_y;
2663
2664    ecore_event_add(event, e, NULL, NULL);
2665
2666    if ((info) && (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
2667        (win == event_win) && (!info->did_triple))
2668      {
2669         info->last_last_win = info->last_win;
2670         info->last_win = win;
2671         info->last_last_event_win = info->last_event_win;
2672         info->last_event_win = event_win;
2673         info->last_last_time = info->last_time;
2674         info->last_time = timestamp;
2675      }
2676
2677    return e;
2678 }
2679
2680 static Ecore_X_Event_Mode
2681 _ecore_xcb_event_mode_get(uint8_t mode)
2682 {
2683    switch (mode)
2684      {
2685       case XCB_NOTIFY_MODE_NORMAL:
2686         return ECORE_X_EVENT_MODE_NORMAL;
2687
2688       case XCB_NOTIFY_MODE_WHILE_GRABBED:
2689         return ECORE_X_EVENT_MODE_WHILE_GRABBED;
2690
2691       case XCB_NOTIFY_MODE_GRAB:
2692         return ECORE_X_EVENT_MODE_GRAB;
2693
2694       case XCB_NOTIFY_MODE_UNGRAB:
2695         return ECORE_X_EVENT_MODE_UNGRAB;
2696
2697       default:
2698         return ECORE_X_EVENT_MODE_NORMAL;
2699      }
2700 }
2701
2702 static Ecore_X_Event_Detail
2703 _ecore_xcb_event_detail_get(uint8_t detail)
2704 {
2705    switch (detail)
2706      {
2707       case XCB_NOTIFY_DETAIL_ANCESTOR:
2708         return ECORE_X_EVENT_DETAIL_ANCESTOR;
2709
2710       case XCB_NOTIFY_DETAIL_VIRTUAL:
2711         return ECORE_X_EVENT_DETAIL_VIRTUAL;
2712
2713       case XCB_NOTIFY_DETAIL_INFERIOR:
2714         return ECORE_X_EVENT_DETAIL_INFERIOR;
2715
2716       case XCB_NOTIFY_DETAIL_NONLINEAR:
2717         return ECORE_X_EVENT_DETAIL_NON_LINEAR;
2718
2719       case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
2720         return ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
2721
2722       case XCB_NOTIFY_DETAIL_POINTER:
2723         return ECORE_X_EVENT_DETAIL_POINTER;
2724
2725       case XCB_NOTIFY_DETAIL_POINTER_ROOT:
2726         return ECORE_X_EVENT_DETAIL_POINTER_ROOT;
2727
2728       case XCB_NOTIFY_DETAIL_NONE:
2729       default:
2730         return ECORE_X_EVENT_DETAIL_ANCESTOR;
2731      }
2732 }
2733
2734 static void
2735 _ecore_xcb_event_xdnd_enter_free(void *data __UNUSED__,
2736                                  void *event)
2737 {
2738    Ecore_X_Event_Xdnd_Enter *e;
2739    int i = 0;
2740
2741    e = event;
2742    for (i = 0; i < e->num_types; i++)
2743      free(e->types[i]);
2744    free(e->types);
2745    free(e);
2746 }
2747
2748 static void
2749 _ecore_xcb_event_selection_notify_free(void *data __UNUSED__,
2750                                        void *event)
2751 {
2752    Ecore_X_Event_Selection_Notify *e;
2753    Ecore_X_Selection_Data *sel;
2754
2755    e = event;
2756    if (!(sel = e->data)) return;
2757    if (sel->free) sel->free(sel);
2758    free(e->target);
2759    free(e);
2760 }
2761
2762 static void
2763 _ecore_xcb_event_generic_event_free(void *data,
2764                                     void *event)
2765 {
2766    Ecore_X_Event_Generic *e;
2767
2768    e = (Ecore_X_Event_Generic *)event;
2769    if (e->data) free(data);
2770    free(e);
2771 }
2772
2773 static void
2774 _ecore_xcb_event_mouse_down_info_clear(void)
2775 {
2776    Eina_Inlist *l;
2777    Ecore_X_Mouse_Down_Info *info = NULL;
2778
2779    l = _ecore_xcb_mouse_down_info_list;
2780    while (l)
2781      {
2782         info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info);
2783         l = eina_inlist_remove(l, l);
2784         free(info);
2785      }
2786    _ecore_xcb_mouse_down_info_list = NULL;
2787 }
2788
2789 static Ecore_X_Mouse_Down_Info *
2790 _ecore_xcb_event_mouse_down_info_get(int dev)
2791 {
2792    Eina_Inlist *l;
2793    Ecore_X_Mouse_Down_Info *info = NULL;
2794
2795    l = _ecore_xcb_mouse_down_info_list;
2796    EINA_INLIST_FOREACH(l, info)
2797      if (info->dev == dev) return info;
2798
2799    if (!(info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info)))) return NULL;
2800
2801    info->dev = dev;
2802    l = eina_inlist_append(l, (Eina_Inlist *)info);
2803    _ecore_xcb_mouse_down_info_list = l;
2804
2805    return info;
2806 }
2807