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