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