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