Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_events.c
1 #include "ecore_xcb_private.h"
2 //#include "Ecore_X_Atoms.h"
3 #include <langinfo.h>
4 #include <xcb/xcb_icccm.h>
5 #include <xcb/xcb_event.h>
6 # ifdef ECORE_XCB_DAMAGE
7 #  include <xcb/damage.h>
8 # endif
9 # ifdef ECORE_XCB_RANDR
10 #  include <xcb/randr.h>
11 # endif
12 # ifdef ECORE_XCB_SCREENSAVER
13 #  include <xcb/screensaver.h>
14 # endif
15 # ifdef ECORE_XCB_SYNC
16 #  include <xcb/sync.h>
17 # endif
18 # ifdef ECORE_XCB_XFIXES
19 #  include <xcb/xfixes.h>
20 # endif
21 # ifdef ECORE_XCB_XGESTURE
22 #  include <xcb/gesture.h>
23 # endif
24
25 #ifndef CODESET
26 # define CODESET "INVALID"
27 #endif
28
29 typedef struct _Ecore_X_Mouse_Down_Info
30 {
31    EINA_INLIST;
32    int            dev;
33    Ecore_X_Time   last_time;
34    Ecore_X_Time   last_last_time;
35    Ecore_X_Window last_win;
36    Ecore_X_Window last_last_win;
37    Ecore_X_Window last_event_win;
38    Ecore_X_Window last_last_event_win;
39    Eina_Bool      did_double : 1;
40    Eina_Bool      did_triple : 1;
41 } Ecore_X_Mouse_Down_Info;
42
43 /* local function prototypes */
44 static void                     _ecore_xcb_event_handle_any_event(xcb_generic_event_t *event);
45 static void                     _ecore_xcb_event_handle_key_press(xcb_generic_event_t *event);
46 static void                     _ecore_xcb_event_handle_key_release(xcb_generic_event_t *event);
47 static void                     _ecore_xcb_event_handle_button_press(xcb_generic_event_t *event);
48 static void                     _ecore_xcb_event_handle_button_release(xcb_generic_event_t *event);
49 static void                     _ecore_xcb_event_handle_motion_notify(xcb_generic_event_t *event);
50 static void                     _ecore_xcb_event_handle_enter_notify(xcb_generic_event_t *event);
51 static void                     _ecore_xcb_event_handle_leave_notify(xcb_generic_event_t *event);
52 static void                     _ecore_xcb_event_handle_keymap_notify(xcb_generic_event_t *event);
53 static void                     _ecore_xcb_event_handle_focus_in(xcb_generic_event_t *event);
54 static void                     _ecore_xcb_event_handle_focus_out(xcb_generic_event_t *event);
55 static void                     _ecore_xcb_event_handle_expose(xcb_generic_event_t *event);
56 static void                     _ecore_xcb_event_handle_graphics_exposure(xcb_generic_event_t *event);
57 static void                     _ecore_xcb_event_handle_visibility_notify(xcb_generic_event_t *event);
58 static void                     _ecore_xcb_event_handle_create_notify(xcb_generic_event_t *event);
59 static void                     _ecore_xcb_event_handle_destroy_notify(xcb_generic_event_t *event);
60 static void                     _ecore_xcb_event_handle_map_notify(xcb_generic_event_t *event);
61 static void                     _ecore_xcb_event_handle_unmap_notify(xcb_generic_event_t *event);
62 static void                     _ecore_xcb_event_handle_map_request(xcb_generic_event_t *event);
63 static void                     _ecore_xcb_event_handle_reparent_notify(xcb_generic_event_t *event);
64 static void                     _ecore_xcb_event_handle_configure_notify(xcb_generic_event_t *event);
65 static void                     _ecore_xcb_event_handle_configure_request(xcb_generic_event_t *event);
66 static void                     _ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event);
67 static void                     _ecore_xcb_event_handle_resize_request(xcb_generic_event_t *event);
68 static void                     _ecore_xcb_event_handle_circulate_notify(xcb_generic_event_t *event);
69 static void                     _ecore_xcb_event_handle_circulate_request(xcb_generic_event_t *event);
70 static void                     _ecore_xcb_event_handle_property_notify(xcb_generic_event_t *event);
71 static void                     _ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event);
72 static void                     _ecore_xcb_event_handle_selection_request(xcb_generic_event_t *event);
73 static void                     _ecore_xcb_event_handle_selection_notify(xcb_generic_event_t *event);
74 static void                     _ecore_xcb_event_handle_colormap_notify(xcb_generic_event_t *event);
75 static void                     _ecore_xcb_event_handle_client_message(xcb_generic_event_t *event);
76 static void                     _ecore_xcb_event_handle_mapping_notify(xcb_generic_event_t *event);
77 static void                     _ecore_xcb_event_handle_damage_notify(xcb_generic_event_t *event);
78 static void                     _ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event);
79 static void                     _ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event);
80 static void                     _ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event);
81 static void                     _ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event);
82 static void                     _ecore_xcb_event_handle_randr_output_property_change(xcb_generic_event_t *event);
83 static void                     _ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event);
84 #ifdef ECORE_XCB_XGESTURE
85 static void                     _ecore_xcb_event_handle_gesture_notify_flick(xcb_generic_event_t *event);
86 static void                     _ecore_xcb_event_handle_gesture_notify_pan(xcb_generic_event_t *event);
87 static void                     _ecore_xcb_event_handle_gesture_notify_pinchrotation(xcb_generic_event_t *event);
88 static void                     _ecore_xcb_event_handle_gesture_notify_tap(xcb_generic_event_t *event);
89 static void                     _ecore_xcb_event_handle_gesture_notify_tapnhold(xcb_generic_event_t *event);
90 static void                     _ecore_xcb_event_handle_gesture_notify_hold(xcb_generic_event_t *event);
91 static void                     _ecore_xcb_event_handle_gesture_notify_group(xcb_generic_event_t *event);
92 #endif
93 #ifdef ECORE_XCB_SHAPE
94 static void                     _ecore_xcb_event_handle_shape_change(xcb_generic_event_t *event);
95 #endif
96 static void                     _ecore_xcb_event_handle_sync_counter(xcb_generic_event_t *event);
97 static void                     _ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event);
98 static void                     _ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event __UNUSED__);
99 static void                     _ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event);
100 static void                     _ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event);
101 static void                     _ecore_xcb_event_handle_input_event(xcb_generic_event_t *event);
102
103 static void                     _ecore_xcb_event_key_press(xcb_generic_event_t *event);
104 static void                     _ecore_xcb_event_key_release(xcb_generic_event_t *event);
105 static void                     _ecore_xcb_event_mouse_move_free(void *data __UNUSED__,
106                                                                  void *event);
107 static Ecore_X_Event_Mode       _ecore_xcb_event_mode_get(uint8_t mode);
108 static Ecore_X_Event_Detail     _ecore_xcb_event_detail_get(uint8_t detail);
109 static void                     _ecore_xcb_event_xdnd_enter_free(void *data __UNUSED__,
110                                                                  void *event);
111 static void                     _ecore_xcb_event_selection_notify_free(void *data __UNUSED__,
112                                                                        void *event);
113 static void                     _ecore_xcb_event_generic_event_free(void *data,
114                                                                     void *event);
115 static void                     _ecore_xcb_event_mouse_down_info_clear(void);
116 static Ecore_X_Mouse_Down_Info *_ecore_xcb_event_mouse_down_info_get(int dev);
117
118 /* local variables */
119 static Eina_Bool _ecore_xcb_event_last_mouse_move = EINA_FALSE;
120 //static Ecore_Event *_ecore_xcb_event_last_mouse_move_event = NULL;
121 static Eina_Inlist *_ecore_xcb_mouse_down_info_list = NULL;
122 static Ecore_X_Time _ecore_xcb_event_last_time;
123 static Ecore_X_Window _ecore_xcb_event_last_window = 0;
124
125 /* public variables */
126 int16_t _ecore_xcb_event_last_root_x = 0;
127 int16_t _ecore_xcb_event_last_root_y = 0;
128
129 EAPI int ECORE_X_EVENT_ANY = 0;
130 EAPI int ECORE_X_EVENT_MOUSE_IN = 0;
131 EAPI int ECORE_X_EVENT_MOUSE_OUT = 0;
132 EAPI int ECORE_X_EVENT_WINDOW_FOCUS_IN = 0;
133 EAPI int ECORE_X_EVENT_WINDOW_FOCUS_OUT = 0;
134 EAPI int ECORE_X_EVENT_WINDOW_KEYMAP = 0;
135 EAPI int ECORE_X_EVENT_WINDOW_DAMAGE = 0;
136 EAPI int ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE = 0;
137 EAPI int ECORE_X_EVENT_WINDOW_CREATE = 0;
138 EAPI int ECORE_X_EVENT_WINDOW_DESTROY = 0;
139 EAPI int ECORE_X_EVENT_WINDOW_HIDE = 0;
140 EAPI int ECORE_X_EVENT_WINDOW_SHOW = 0;
141 EAPI int ECORE_X_EVENT_WINDOW_SHOW_REQUEST = 0;
142 EAPI int ECORE_X_EVENT_WINDOW_REPARENT = 0;
143 EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE = 0;
144 EAPI int ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST = 0;
145 EAPI int ECORE_X_EVENT_WINDOW_GRAVITY = 0;
146 EAPI int ECORE_X_EVENT_WINDOW_RESIZE_REQUEST = 0;
147 EAPI int ECORE_X_EVENT_WINDOW_STACK = 0;
148 EAPI int ECORE_X_EVENT_WINDOW_STACK_REQUEST = 0;
149 EAPI int ECORE_X_EVENT_WINDOW_PROPERTY = 0;
150 EAPI int ECORE_X_EVENT_WINDOW_COLORMAP = 0;
151 EAPI int ECORE_X_EVENT_WINDOW_MAPPING = 0;
152 EAPI int ECORE_X_EVENT_MAPPING_CHANGE = 0;
153 EAPI int ECORE_X_EVENT_SELECTION_CLEAR = 0;
154 EAPI int ECORE_X_EVENT_SELECTION_REQUEST = 0;
155 EAPI int ECORE_X_EVENT_SELECTION_NOTIFY = 0;
156 EAPI int ECORE_X_EVENT_FIXES_SELECTION_NOTIFY = 0;
157 EAPI int ECORE_X_EVENT_CLIENT_MESSAGE = 0;
158 EAPI int ECORE_X_EVENT_WINDOW_SHAPE = 0;
159 EAPI int ECORE_X_EVENT_SCREENSAVER_NOTIFY = 0;
160 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_FLICK = 0;
161 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PAN = 0;
162 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION = 0;
163 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAP = 0;
164 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD = 0;
165 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_HOLD = 0;
166 EAPI int ECORE_X_EVENT_GESTURE_NOTIFY_GROUP = 0;
167 EAPI int ECORE_X_EVENT_SYNC_COUNTER = 0;
168 EAPI int ECORE_X_EVENT_SYNC_ALARM = 0;
169 EAPI int ECORE_X_EVENT_SCREEN_CHANGE = 0;
170 EAPI int ECORE_X_EVENT_DAMAGE_NOTIFY = 0;
171 EAPI int ECORE_X_EVENT_RANDR_CRTC_CHANGE = 0;
172 EAPI int ECORE_X_EVENT_RANDR_OUTPUT_CHANGE = 0;
173 EAPI int ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY = 0;
174 EAPI int ECORE_X_EVENT_WINDOW_DELETE_REQUEST = 0;
175 EAPI int ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST = 0;
176 EAPI int ECORE_X_EVENT_WINDOW_STATE_REQUEST = 0;
177 EAPI int ECORE_X_EVENT_FRAME_EXTENTS_REQUEST = 0;
178 EAPI int ECORE_X_EVENT_PING = 0;
179 EAPI int ECORE_X_EVENT_DESKTOP_CHANGE = 0;
180 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_NEW = 0;
181 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE = 0;
182 EAPI int ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE = 0;
183 EAPI int ECORE_X_EVENT_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
1039    ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
1040 }
1041
1042 static void
1043 _ecore_xcb_event_handle_map_request(xcb_generic_event_t *event)
1044 {
1045    xcb_map_request_event_t *ev;
1046    Ecore_X_Event_Window_Show_Request *e;
1047
1048    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1049    ev = (xcb_map_request_event_t *)event;
1050    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request)))) return;
1051
1052    e->win = ev->window;
1053    e->parent = ev->parent;
1054    e->time = _ecore_xcb_event_last_time;
1055
1056    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
1057 }
1058
1059 static void
1060 _ecore_xcb_event_handle_reparent_notify(xcb_generic_event_t *event)
1061 {
1062    xcb_reparent_notify_event_t *ev;
1063    Ecore_X_Event_Window_Reparent *e;
1064
1065    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1066    ev = (xcb_reparent_notify_event_t *)event;
1067    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent)))) return;
1068
1069    e->win = ev->window;
1070    e->event_win = ev->event;
1071    e->parent = ev->parent;
1072    e->time = _ecore_xcb_event_last_time;
1073
1074    ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
1075 }
1076
1077 static void
1078 _ecore_xcb_event_handle_configure_notify(xcb_generic_event_t *event)
1079 {
1080    xcb_configure_notify_event_t *ev;
1081    Ecore_X_Event_Window_Configure *e;
1082
1083    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1084    ev = (xcb_configure_notify_event_t *)event;
1085    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Configure)))) return;
1086
1087    e->win = ev->window;
1088    e->event_win = ev->event;
1089    e->abovewin = ev->above_sibling;
1090    e->x = ev->x;
1091    e->y = ev->y;
1092    e->w = ev->width;
1093    e->h = ev->height;
1094    e->border = ev->border_width;
1095    e->override = ev->override_redirect;
1096    /* send_event is bit 7 (0x80) of response_type */
1097    e->from_wm = ((ev->response_type & 0x80) ? 1 : 0);
1098    e->time = _ecore_xcb_event_last_time;
1099
1100    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
1101 }
1102
1103 static void
1104 _ecore_xcb_event_handle_configure_request(xcb_generic_event_t *event)
1105 {
1106    xcb_configure_request_event_t *ev;
1107    Ecore_X_Event_Window_Configure_Request *e;
1108
1109    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1110    ev = (xcb_configure_request_event_t *)event;
1111    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request))))
1112      return;
1113
1114    e->win = ev->window;
1115    e->parent_win = ev->parent;
1116    e->abovewin = ev->sibling;
1117    e->x = ev->x;
1118    e->y = ev->y;
1119    e->w = ev->width;
1120    e->h = ev->height;
1121    e->border = ev->border_width;
1122    e->value_mask = ev->value_mask;
1123    switch (ev->stack_mode)
1124      {
1125       case XCB_STACK_MODE_ABOVE:
1126         e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1127         break;
1128
1129       case XCB_STACK_MODE_BELOW:
1130         e->detail = ECORE_X_WINDOW_STACK_BELOW;
1131         break;
1132
1133       case XCB_STACK_MODE_TOP_IF:
1134         e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
1135         break;
1136
1137       case XCB_STACK_MODE_BOTTOM_IF:
1138         e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
1139         break;
1140
1141       case XCB_STACK_MODE_OPPOSITE:
1142         e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
1143         break;
1144      }
1145    e->time = _ecore_xcb_event_last_time;
1146
1147    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
1148 }
1149
1150 static void
1151 _ecore_xcb_event_handle_gravity_notify(xcb_generic_event_t *event __UNUSED__)
1152 {
1153 /*
1154    xcb_gravity_notify_event_t *ev;
1155    Ecore_X_Event_Window_Gravity *e;
1156
1157    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1158    ev = (xcb_gravity_notify_event_t *)event;
1159    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Gravity)))) return;
1160
1161    e->win = ev->window;
1162    e->event_win = ev->event;
1163    e->time = _ecore_xcb_event_last_time;
1164
1165    ecore_event_add(ECORE_X_EVENT_WINDOW_GRAVITY, e, NULL, NULL);
1166  */
1167 }
1168
1169 static void
1170 _ecore_xcb_event_handle_resize_request(xcb_generic_event_t *event)
1171 {
1172    xcb_resize_request_event_t *ev;
1173    Ecore_X_Event_Window_Resize_Request *e;
1174
1175    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1176    ev = (xcb_resize_request_event_t *)event;
1177    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request)))) return;
1178
1179    e->win = ev->window;
1180    e->w = ev->width;
1181    e->h = ev->height;
1182    e->time = _ecore_xcb_event_last_time;
1183
1184    ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
1185 }
1186
1187 static void
1188 _ecore_xcb_event_handle_circulate_notify(xcb_generic_event_t *event)
1189 {
1190    xcb_circulate_notify_event_t *ev;
1191    Ecore_X_Event_Window_Stack *e;
1192
1193    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1194    ev = (xcb_circulate_notify_event_t *)event;
1195    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Stack)))) return;
1196
1197    e->win = ev->window;
1198    e->event_win = ev->event;
1199    if (ev->place == XCB_PLACE_ON_TOP)
1200      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1201    else
1202      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1203    e->time = _ecore_xcb_event_last_time;
1204
1205    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
1206 }
1207
1208 static void
1209 _ecore_xcb_event_handle_circulate_request(xcb_generic_event_t *event)
1210 {
1211    xcb_circulate_request_event_t *ev;
1212    Ecore_X_Event_Window_Stack_Request *e;
1213
1214    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1215    ev = (xcb_circulate_request_event_t *)event;
1216    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request)))) return;
1217
1218    e->win = ev->window;
1219    e->parent = ev->event;
1220    if (ev->place == XCB_PLACE_ON_TOP)
1221      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1222    else
1223      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1224    e->time = _ecore_xcb_event_last_time;
1225
1226    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
1227 }
1228
1229 static void
1230 _ecore_xcb_event_handle_property_notify(xcb_generic_event_t *event)
1231 {
1232    xcb_property_notify_event_t *ev;
1233    Ecore_X_Event_Window_Property *e;
1234
1235    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1236    ev = (xcb_property_notify_event_t *)event;
1237    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Property)))) return;
1238
1239    e->win = ev->window;
1240    e->atom = ev->atom;
1241    e->time = ev->time;
1242    _ecore_xcb_event_last_time = e->time;
1243
1244    ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
1245 }
1246
1247 static void
1248 _ecore_xcb_event_handle_selection_clear(xcb_generic_event_t *event)
1249 {
1250    xcb_selection_clear_event_t *ev;
1251    Ecore_X_Event_Selection_Clear *e;
1252    Ecore_X_Atom sel;
1253
1254    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1255
1256    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1257    ev = (xcb_selection_clear_event_t *)event;
1258    if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Clear)))) return;
1259
1260    e->win = ev->owner;
1261    e->atom = sel = ev->selection;
1262    if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
1263      e->selection = ECORE_X_SELECTION_PRIMARY;
1264    else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
1265      e->selection = ECORE_X_SELECTION_SECONDARY;
1266    else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1267      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1268    else
1269      e->selection = ECORE_X_SELECTION_OTHER;
1270    e->time = ev->time;
1271
1272    ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
1273 }
1274
1275 static void
1276 _ecore_xcb_event_handle_selection_request(xcb_generic_event_t *event)
1277 {
1278    xcb_selection_request_event_t *ev;
1279    Ecore_X_Event_Selection_Request *e;
1280    Ecore_X_Selection_Intern *sd;
1281
1282    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1283
1284    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1285    ev = (xcb_selection_request_event_t *)event;
1286    if (!(e = malloc(sizeof(Ecore_X_Event_Selection_Request)))) return;
1287
1288    e->owner = ev->owner;
1289    e->requestor = ev->requestor;
1290    e->selection = ev->selection;
1291    e->target = ev->target;
1292    e->property = ev->property;
1293    e->time = ev->time;
1294
1295    ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL);
1296
1297    if ((sd = _ecore_xcb_selection_get(ev->selection)) &&
1298        (sd->win == ev->owner))
1299      {
1300         Ecore_X_Selection_Intern *si;
1301
1302         si = _ecore_xcb_selection_get(ev->selection);
1303         if (si->data)
1304           {
1305              Ecore_X_Atom property = XCB_NONE, type;
1306              void *data = NULL;
1307              int len = 0, typesize = 0;
1308
1309              type = ev->target;
1310              typesize = 8;
1311              len = sd->length;
1312
1313              if (!ecore_x_selection_convert(ev->selection, ev->target,
1314                                             &data, &len, &type, &typesize))
1315                property = XCB_NONE;
1316              else if (data)
1317                {
1318                   ecore_x_window_prop_property_set(ev->requestor, ev->property,
1319                                                    type, typesize, data, len);
1320                   property = ev->property;
1321                   free(data);
1322                }
1323              ecore_x_selection_notify_send(ev->requestor, ev->selection,
1324                                            ev->target, property, ev->time);
1325           }
1326      }
1327 }
1328
1329 static void
1330 _ecore_xcb_event_handle_selection_notify(xcb_generic_event_t *event)
1331 {
1332    xcb_selection_notify_event_t *ev;
1333    Ecore_X_Event_Selection_Notify *e;
1334    unsigned char *data = NULL;
1335    Ecore_X_Atom selection;
1336    int num = 0, format = 0;
1337
1338    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1339
1340    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1341    ev = (xcb_selection_notify_event_t *)event;
1342    selection = ev->selection;
1343    if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS)
1344      {
1345         format =
1346           ecore_x_window_prop_property_get(ev->requestor, ev->property,
1347                                            XCB_ATOM_ATOM, 32, &data, &num);
1348         if (!format)
1349           {
1350              /* fallback if targets handling is not working and try get the
1351               * selection directly */
1352              xcb_convert_selection(_ecore_xcb_conn, ev->requestor,
1353                                    selection, selection,
1354                                    ECORE_X_ATOM_UTF8_STRING, XCB_CURRENT_TIME);
1355              return;
1356           }
1357      }
1358    else
1359      {
1360         format =
1361           ecore_x_window_prop_property_get(ev->requestor, ev->property,
1362                                            XCB_GET_PROPERTY_TYPE_ANY, 8,
1363                                            &data, &num);
1364         if (!format) return;
1365      }
1366
1367    e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
1368    if (!e) return;
1369    e->win = ev->requestor;
1370    e->time = ev->time;
1371    e->atom = selection;
1372    e->target = _ecore_xcb_selection_target_get(ev->target);
1373
1374    if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
1375      e->selection = ECORE_X_SELECTION_PRIMARY;
1376    else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
1377      e->selection = ECORE_X_SELECTION_SECONDARY;
1378    else if (selection == ECORE_X_ATOM_SELECTION_XDND)
1379      e->selection = ECORE_X_SELECTION_XDND;
1380    else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1381      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1382    else
1383      e->selection = ECORE_X_SELECTION_OTHER;
1384
1385    e->data = _ecore_xcb_selection_parse(e->target, data, num, format);
1386
1387    ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e,
1388                    _ecore_xcb_event_selection_notify_free, NULL);
1389 }
1390
1391 static void
1392 _ecore_xcb_event_handle_colormap_notify(xcb_generic_event_t *event)
1393 {
1394    xcb_colormap_notify_event_t *ev;
1395    Ecore_X_Event_Window_Colormap *e;
1396
1397    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1398    ev = (xcb_colormap_notify_event_t *)event;
1399    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Colormap)))) return;
1400
1401    e->win = ev->window;
1402    e->cmap = ev->colormap;
1403    if (ev->state == XCB_COLORMAP_STATE_INSTALLED)
1404      e->installed = 1;
1405    else
1406      e->installed = 0;
1407    e->time = _ecore_xcb_event_last_time;
1408
1409    ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
1410 }
1411
1412 static void
1413 _ecore_xcb_event_handle_client_message(xcb_generic_event_t *event)
1414 {
1415    xcb_client_message_event_t *ev;
1416
1417    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1418    ev = (xcb_client_message_event_t *)event;
1419
1420    /* Special client message event handling here. need to put LOTS of if */
1421    /* checks here and generate synthetic events per special message known */
1422    /* otherwise generate generic client message event. this would handle*/
1423    /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
1424
1425    if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) && (ev->format == 32) &&
1426        (ev->data.data32[0] == ECORE_X_ATOM_WM_DELETE_WINDOW))
1427      {
1428         Ecore_X_Event_Window_Delete_Request *e;
1429
1430         if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request))))
1431           return;
1432         e->win = ev->window;
1433         e->time = _ecore_xcb_event_last_time;
1434         ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
1435      }
1436    else if ((ev->type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
1437             (ev->format == 32) && (ev->data.data32[2] < 9))
1438      {
1439         Ecore_X_Event_Window_Move_Resize_Request *e;
1440
1441         if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request))))
1442           return;
1443         e->win = ev->window;
1444         e->x = ev->data.data32[0];
1445         e->y = ev->data.data32[1];
1446         e->direction = ev->data.data32[2];
1447         e->button = ev->data.data32[3];
1448         e->source = ev->data.data32[4];
1449         ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
1450      }
1451    else if (ev->type == ECORE_X_ATOM_XDND_ENTER)
1452      {
1453         Ecore_X_Event_Xdnd_Enter *e;
1454         Ecore_X_DND_Target *target;
1455
1456         DBG("Got Xdnd Enter Event");
1457         if (!(e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter)))) return;
1458         target = _ecore_xcb_dnd_target_get();
1459         target->state = ECORE_X_DND_TARGET_ENTERED;
1460         target->source = ev->data.data32[0];
1461         target->win = ev->window;
1462         target->version = (int)(ev->data.data32[1] >> 24);
1463         if (target->version > ECORE_X_DND_VERSION)
1464           {
1465              WRN("DND: Requested version %d but we only support up to %d",
1466                  target->version, ECORE_X_DND_VERSION);
1467              free(e);
1468              return;
1469           }
1470         if (ev->data.data32[1] & 0x1UL)
1471           {
1472              unsigned char *data;
1473              Ecore_X_Atom *types;
1474              int num_ret = 0;
1475
1476              if (!ecore_x_window_prop_property_get(target->source,
1477                                                    ECORE_X_ATOM_XDND_TYPE_LIST,
1478                                                    ECORE_X_ATOM_ATOM, 32,
1479                                                    &data, &num_ret))
1480                {
1481                   WRN("DND: Could not fetch data type list from source window");
1482                   free(e);
1483                   return;
1484                }
1485              types = (Ecore_X_Atom *)data;
1486              e->types = calloc(num_ret, sizeof(char *));
1487              if (e->types)
1488                {
1489                   int i = 0;
1490
1491                   for (i = 0; i < num_ret; i++)
1492                     e->types[i] = ecore_x_atom_name_get(types[i]);
1493                }
1494              e->num_types = num_ret;
1495           }
1496         else
1497           {
1498              int i = 0;
1499
1500              e->types = calloc(3, sizeof(char *));
1501              if (e->types)
1502                {
1503                   while ((i < 3) && (ev->data.data32[i + 2]))
1504                     {
1505                        e->types[i] =
1506                          ecore_x_atom_name_get(ev->data.data32[i + 2]);
1507                        i++;
1508                     }
1509                }
1510              e->num_types = i;
1511           }
1512
1513         e->win = target->win;
1514         e->source = target->source;
1515         ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e,
1516                         _ecore_xcb_event_xdnd_enter_free, NULL);
1517      }
1518    else if (ev->type == ECORE_X_ATOM_XDND_POSITION)
1519      {
1520         Ecore_X_Event_Xdnd_Position *e;
1521         Ecore_X_DND_Target *target;
1522
1523         DBG("Got Xdnd Position Event");
1524         target = _ecore_xcb_dnd_target_get();
1525         if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1526             (target->win != ev->window)) return;
1527         target->pos.x = ev->data.data32[2] >> 16;
1528         target->pos.y = ev->data.data32[2] & 0xFFFFUL;
1529         target->action = ev->data.data32[4];
1530         target->time = (target->version >= 1) ?
1531           (Ecore_X_Time)ev->data.data32[3] : XCB_CURRENT_TIME;
1532
1533         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
1534         if (!e) return;
1535         e->win = target->win;
1536         e->source = target->source;
1537         e->position.x = target->pos.x;
1538         e->position.y = target->pos.y;
1539         e->action = target->action;
1540         ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
1541      }
1542    else if (ev->type == ECORE_X_ATOM_XDND_STATUS)
1543      {
1544         Ecore_X_Event_Xdnd_Status *e;
1545         Ecore_X_DND_Source *source;
1546
1547         DBG("Got Xdnd Status Event");
1548         source = _ecore_xcb_dnd_source_get();
1549         if ((source->win != ev->window) ||
1550             (source->dest != (Ecore_X_Window)ev->data.data32[0]))
1551           return;
1552
1553         source->await_status = 0;
1554         source->will_accept = ev->data.data32[1] & 0x1UL;
1555         source->suppress = (ev->data.data32[1] & 0x2UL) ? 0 : 1;
1556         source->rectangle.x = ev->data.data32[2] >> 16;
1557         source->rectangle.y = ev->data.data32[2] & 0xFFFFUL;
1558         source->rectangle.width = ev->data.data32[3] >> 16;
1559         source->rectangle.height = ev->data.data32[3] & 0xFFFFUL;
1560         source->accepted_action = ev->data.data32[4];
1561
1562         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
1563         if (!e) return;
1564         e->win = source->win;
1565         e->target = source->dest;
1566         e->will_accept = source->will_accept;
1567         e->rectangle.x = source->rectangle.x;
1568         e->rectangle.y = source->rectangle.y;
1569         e->rectangle.width = source->rectangle.width;
1570         e->rectangle.height = source->rectangle.height;
1571         e->action = source->accepted_action;
1572
1573         ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
1574      }
1575    else if (ev->type == ECORE_X_ATOM_XDND_LEAVE)
1576      {
1577         Ecore_X_Event_Xdnd_Leave *e;
1578         Ecore_X_DND_Target *target;
1579
1580         DBG("Got Xdnd Leave Event");
1581         target = _ecore_xcb_dnd_target_get();
1582         if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1583             (target->win != ev->window))
1584           return;
1585         target->state = ECORE_X_DND_TARGET_IDLE;
1586         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
1587         if (!e) return;
1588         e->win = ev->window;
1589         e->source = (Ecore_X_Window)ev->data.data32[0];
1590         ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
1591      }
1592    else if (ev->type == ECORE_X_ATOM_XDND_DROP)
1593      {
1594         Ecore_X_Event_Xdnd_Drop *e;
1595         Ecore_X_DND_Target *target;
1596
1597         DBG("Got Xdnd Drop Event");
1598         target = _ecore_xcb_dnd_target_get();
1599         if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1600             (target->win != ev->window))
1601           return;
1602         target->time = (target->version >= 1) ?
1603           (Ecore_X_Time)ev->data.data32[2] : _ecore_xcb_event_last_time;
1604
1605         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
1606         if (!e) return;
1607         e->win = target->win;
1608         e->source = target->source;
1609         e->action = target->action;
1610         e->position.x = target->pos.x;
1611         e->position.y = target->pos.y;
1612         ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
1613      }
1614    else if (ev->type == ECORE_X_ATOM_XDND_FINISHED)
1615      {
1616         Ecore_X_Event_Xdnd_Finished *e;
1617         Ecore_X_DND_Source *source;
1618         Eina_Bool completed = EINA_TRUE;
1619
1620         DBG("Got Xdnd Finished Event");
1621         source = _ecore_xcb_dnd_source_get();
1622         if ((source->win != ev->window) ||
1623             (source->dest != (Ecore_X_Window)ev->data.data32[0]))
1624           return;
1625         if ((source->version < 5) || (ev->data.data32[1] & 0x1UL))
1626           {
1627              ecore_x_selection_xdnd_clear();
1628              source->state = ECORE_X_DND_SOURCE_IDLE;
1629           }
1630         else if (source->version >= 5)
1631           {
1632              completed = EINA_FALSE;
1633              source->state = ECORE_X_DND_SOURCE_CONVERTING;
1634              /* FIXME: Probably need to add a timer to switch back to idle
1635               * and discard the selection data */
1636           }
1637
1638         if (!(e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished))))
1639           return;
1640         e->win = source->win;
1641         e->target = source->dest;
1642         e->completed = completed;
1643         if (source->version >= 5)
1644           {
1645              source->accepted_action = ev->data.data32[2];
1646              e->action = source->accepted_action;
1647           }
1648         else
1649           {
1650              source->accepted_action = 0;
1651              e->action = source->action;
1652           }
1653         ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
1654      }
1655    else if (ev->type == ECORE_X_ATOM_NET_WM_STATE)
1656      {
1657         Ecore_X_Event_Window_State_Request *e;
1658
1659         if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request))))
1660           return;
1661         e->win = ev->window;
1662         if (ev->data.data32[0] == 0)
1663           e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
1664         else if (ev->data.data32[0] == 1)
1665           e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1666         else if (ev->data.data32[0] == 2)
1667           e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
1668         else
1669           {
1670              free(e);
1671              return;
1672           }
1673         e->state[0] = _ecore_xcb_netwm_window_state_get(ev->data.data32[1]);
1674         if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
1675           {
1676              /* FIXME */
1677           }
1678         e->state[1] = _ecore_xcb_netwm_window_state_get(ev->data.data32[2]);
1679         if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
1680           {
1681              /* FIXME */
1682           }
1683         e->source = ev->data.data32[3];
1684         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1685      }
1686 #ifdef OLD_XCB_VERSION
1687    else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) &&
1688             (ev->format == 32) && (ev->data.data32[0] == XCB_WM_STATE_ICONIC))
1689 #else
1690    else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE) && (ev->format == 32) &&
1691             (ev->data.data32[0] == XCB_ICCCM_WM_STATE_ICONIC))
1692 #endif
1693      {
1694         Ecore_X_Event_Window_State_Request *e;
1695
1696         if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request))))
1697           return;
1698         e->win = ev->window;
1699         e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1700         e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
1701         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1702      }
1703    else if ((ev->type == ECORE_X_ATOM_NET_WM_DESKTOP) && (ev->format == 32))
1704      {
1705         Ecore_X_Event_Desktop_Change *e;
1706
1707         if (!(e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change))))
1708           return;
1709         e->win = ev->window;
1710         e->desk = ev->data.data32[0];
1711         e->source = ev->data.data32[1];
1712         ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
1713      }
1714    else if (ev->type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS)
1715      {
1716         Ecore_X_Event_Frame_Extents_Request *e;
1717
1718         if (!(e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request))))
1719           return;
1720         e->win = ev->window;
1721         ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
1722      }
1723    else if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) &&
1724             ((Ecore_X_Atom)ev->data.data32[0] == ECORE_X_ATOM_NET_WM_PING) &&
1725             (ev->format == 32))
1726      {
1727         Ecore_X_Event_Ping *e;
1728         Ecore_X_Window root = 0;
1729         int count = 0;
1730
1731         if (!(e = calloc(1, sizeof(Ecore_X_Event_Ping)))) return;
1732         e->win = ev->window;
1733         e->time = ev->data.data32[1];
1734         e->event_win = ev->data.data32[2];
1735         ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
1736
1737         CHECK_XCB_CONN;
1738
1739         count = xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn));
1740         if (count > 1)
1741           root = ecore_x_window_root_get(e->win);
1742         else
1743           root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1744
1745         if (ev->window != root)
1746           {
1747              ev->window = root;
1748              xcb_send_event(_ecore_xcb_conn, 0, root,
1749                             (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
1750                              XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY),
1751                             (const char *)&ev);
1752 //             ecore_x_flush();
1753           }
1754      }
1755    else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
1756             (ev->format == 8))
1757      {
1758         _ecore_xcb_netwm_startup_info_begin(ev->window, ev->data.data8[0]);
1759      }
1760    else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO) && (ev->format == 8))
1761      {
1762         _ecore_xcb_netwm_startup_info(ev->window, ev->data.data8[0]);
1763      }
1764    else if ((ev->type == 27777) && (ev->data.data32[0] == 0x7162534) &&
1765             (ev->format == 32)) // && (ev->window = _private_window))
1766      {
1767         if (ev->data.data32[1] == 0x10000001)
1768           _ecore_xcb_window_button_grab_remove(ev->data.data32[2]);
1769         else if (ev->data.data32[1] == 0x10000002)
1770           _ecore_xcb_window_key_grab_remove(ev->data.data32[2]);
1771      }
1772    else
1773      {
1774         Ecore_X_Event_Client_Message *e;
1775         int i = 0;
1776
1777         if (!(e = calloc(1, sizeof(Ecore_X_Event_Client_Message))))
1778           return;
1779
1780         e->win = ev->window;
1781         e->message_type = ev->type;
1782         e->format = ev->format;
1783         for (i = 0; i < 5; i++)
1784           e->data.l[i] = ev->data.data32[i];
1785         ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
1786      }
1787 }
1788
1789 static void
1790 _ecore_xcb_event_handle_mapping_notify(xcb_generic_event_t *event)
1791 {
1792    xcb_mapping_notify_event_t *ev;
1793    Ecore_X_Event_Mapping_Change *e;
1794
1795    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1796
1797    ev = (xcb_mapping_notify_event_t *)event;
1798    if (!(e = calloc(1, sizeof(Ecore_X_Event_Mapping_Change)))) return;
1799
1800    _ecore_xcb_keymap_refresh(ev);
1801    _ecore_xcb_modifiers_get();
1802
1803    switch (ev->request)
1804      {
1805       case XCB_MAPPING_MODIFIER:
1806         e->type = ECORE_X_MAPPING_MODIFIER;
1807         break;
1808
1809       case XCB_MAPPING_KEYBOARD:
1810         e->type = ECORE_X_MAPPING_KEYBOARD;
1811         break;
1812
1813       case XCB_MAPPING_POINTER:
1814       default:
1815         e->type = ECORE_X_MAPPING_MOUSE;
1816         break;
1817      }
1818    e->keycode = ev->first_keycode;
1819    e->num = ev->count;
1820
1821    ecore_event_add(ECORE_X_EVENT_MAPPING_CHANGE, e, NULL, NULL);
1822 }
1823
1824 static void
1825 _ecore_xcb_event_handle_damage_notify(xcb_generic_event_t *event)
1826 {
1827 #ifdef ECORE_XCB_DAMAGE
1828    xcb_damage_notify_event_t *ev;
1829    Ecore_X_Event_Damage *e;
1830 #endif
1831
1832    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1833
1834    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1835 #ifdef ECORE_XCB_DAMAGE
1836    ev = (xcb_damage_notify_event_t *)event;
1837    if (!(e = calloc(1, sizeof(Ecore_X_Event_Damage)))) return;
1838
1839    e->level = ev->level;
1840    e->drawable = ev->drawable;
1841    e->damage = ev->damage;
1842    e->time = ev->timestamp;
1843    e->area.x = ev->area.x;
1844    e->area.y = ev->area.y;
1845    e->area.width = ev->area.width;
1846    e->area.height = ev->area.height;
1847    e->geometry.x = ev->geometry.x;
1848    e->geometry.y = ev->geometry.y;
1849    e->geometry.width = ev->geometry.width;
1850    e->geometry.height = ev->geometry.height;
1851
1852    ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
1853 #endif
1854 }
1855
1856 static void
1857 _ecore_xcb_event_handle_randr_change(xcb_generic_event_t *event)
1858 {
1859 #ifdef ECORE_XCB_RANDR
1860    xcb_randr_screen_change_notify_event_t *ev;
1861    Ecore_X_Event_Screen_Change *e;
1862 #endif
1863
1864    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1865 #ifdef ECORE_XCB_RANDR
1866    ev = (xcb_randr_screen_change_notify_event_t *)event;
1867    if (!(e = calloc(1, sizeof(Ecore_X_Event_Screen_Change)))) return;
1868
1869    e->win = ev->request_window;
1870    e->root = ev->root;
1871    e->size.width = ev->width;
1872    e->size.height = ev->height;
1873    e->time = ev->timestamp;
1874    e->config_time = ev->config_timestamp;
1875    e->size.width_mm = ev->mwidth;
1876    e->size.height_mm = ev->mheight;
1877    e->orientation = ev->rotation;
1878    e->subpixel_order = ev->subpixel_order;
1879
1880    ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
1881 #endif
1882 }
1883
1884 static void
1885 _ecore_xcb_event_handle_randr_notify(xcb_generic_event_t *event)
1886 {
1887 #ifdef ECORE_XCB_RANDR
1888    xcb_randr_notify_event_t *ev;
1889 #endif
1890
1891    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
1892 #ifdef ECORE_XCB_RANDR
1893    ev = (xcb_randr_notify_event_t *)event;
1894    switch (ev->subCode)
1895      {
1896       case XCB_RANDR_NOTIFY_CRTC_CHANGE:
1897         _ecore_xcb_event_handle_randr_crtc_change(event);
1898         break;
1899
1900       case XCB_RANDR_NOTIFY_OUTPUT_CHANGE:
1901         _ecore_xcb_event_handle_randr_output_change(event);
1902         break;
1903
1904       case XCB_RANDR_NOTIFY_OUTPUT_PROPERTY:
1905         _ecore_xcb_event_handle_randr_output_property_change(event);
1906         break;
1907
1908       default:
1909         break;
1910      }
1911 #endif
1912 }
1913
1914 static void
1915 _ecore_xcb_event_handle_randr_crtc_change(xcb_generic_event_t *event)
1916 {
1917 #ifdef ECORE_XCB_RANDR
1918    xcb_randr_notify_event_t *ev;
1919    Ecore_X_Event_Randr_Crtc_Change *e;
1920 #endif
1921
1922 #ifdef ECORE_XCB_RANDR
1923    ev = (xcb_randr_notify_event_t *)event;
1924    if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change))))
1925      return;
1926
1927    e->win = ev->u.cc.window;
1928    e->crtc = ev->u.cc.crtc;
1929    e->mode = ev->u.cc.mode;
1930    e->orientation = ev->u.cc.rotation;
1931    e->geo.x = ev->u.cc.x;
1932    e->geo.y = ev->u.cc.y;
1933    e->geo.w = ev->u.cc.width;
1934    e->geo.h = ev->u.cc.height;
1935
1936    ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL);
1937 #endif
1938 }
1939
1940 static void
1941 _ecore_xcb_event_handle_randr_output_change(xcb_generic_event_t *event)
1942 {
1943 #ifdef ECORE_XCB_RANDR
1944    xcb_randr_notify_event_t *ev;
1945    Ecore_X_Event_Randr_Output_Change *e;
1946 #endif
1947
1948 #ifdef ECORE_XCB_RANDR
1949    ev = (xcb_randr_notify_event_t *)event;
1950    if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Change))))
1951      return;
1952
1953    e->win = ev->u.oc.window;
1954    e->output = ev->u.oc.output;
1955    e->crtc = ev->u.oc.crtc;
1956    e->mode = ev->u.oc.mode;
1957    e->orientation = ev->u.oc.rotation;
1958    e->connection = ev->u.oc.connection;
1959    e->subpixel_order = ev->u.oc.subpixel_order;
1960
1961    ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, e, NULL, NULL);
1962 #endif
1963 }
1964
1965 static void
1966 _ecore_xcb_event_handle_randr_output_property_change(xcb_generic_event_t *event)
1967 {
1968 #ifdef ECORE_XCB_RANDR
1969    xcb_randr_notify_event_t *ev;
1970    Ecore_X_Event_Randr_Output_Property_Notify *e;
1971 #endif
1972
1973 #ifdef ECORE_XCB_RANDR
1974    ev = (xcb_randr_notify_event_t *)event;
1975    if (!(e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Property_Notify))))
1976      return;
1977
1978    e->win = ev->u.op.window;
1979    e->output = ev->u.op.output;
1980    e->property = ev->u.op.atom;
1981    e->time = ev->u.op.timestamp;
1982    if (ev->u.op.status == XCB_PROPERTY_NEW_VALUE)
1983      e->state = ECORE_X_RANDR_PROPERTY_CHANGE_ADD;
1984    else
1985      e->state = ECORE_X_RANDR_PROPERTY_CHANGE_DEL;
1986
1987    ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, e, NULL, NULL);
1988 #endif
1989 }
1990
1991 static void
1992 _ecore_xcb_event_handle_screensaver_notify(xcb_generic_event_t *event)
1993 {
1994 #ifdef ECORE_XCB_SCREENSAVER
1995    xcb_screensaver_notify_event_t *ev;
1996    Ecore_X_Event_Screensaver_Notify *e;
1997 #endif
1998
1999    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2000 #ifdef ECORE_XCB_SCREENSAVER
2001    ev = (xcb_screensaver_notify_event_t *)event;
2002    if (!(e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify)))) return;
2003
2004    e->win = ev->window;
2005    e->on = EINA_FALSE;
2006    if ((ev->state == XCB_SCREENSAVER_STATE_ON) ||
2007        (ev->state == XCB_SCREENSAVER_STATE_CYCLE)) e->on = EINA_TRUE;
2008    e->time = ev->time;
2009
2010    ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
2011 #endif
2012 }
2013
2014 #ifdef ECORE_XCB_XGESTURE
2015 static void
2016 _ecore_xcb_event_handle_gesture_notify_flick(xcb_generic_event_t *event)
2017 {
2018    xcb_gesture_notify_flick_event_t *ev;
2019    Ecore_X_Event_Gesture_Notify_Flick *e;
2020
2021    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2022    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2023    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2024
2025    ev = (xcb_gesture_notify_flick_event_t *)event;
2026    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Flick)))) return;
2027
2028    e->win = ev->window;
2029    e->time = ev->time;
2030    e->subtype = ev->kind;
2031    e->num_fingers = ev->num_finger;
2032    e->distance = ev->distance;
2033    e->duration = ev->duration;
2034    e->direction = ev->direction;
2035    e->angle = XFixedToDouble(ev->angle);
2036
2037    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_FLICK, e, NULL, NULL);
2038 }
2039
2040 static void
2041 _ecore_xcb_event_handle_gesture_notify_pan(xcb_generic_event_t *event)
2042 {
2043    xcb_gesture_notify_pan_event_t *ev;
2044    Ecore_X_Event_Gesture_Notify_Pan *e;
2045
2046    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2047    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2048    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2049
2050    ev = (xcb_gesture_notify_pan_event_t *)event;
2051    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Pan)))) return;
2052
2053    e->win = ev->window;
2054    e->time = ev->time;
2055    e->subtype = ev->kind;
2056    e->num_fingers = ev->num_finger;
2057    e->dx = ev->dx;
2058    e->dy = ev->dy;
2059    e->distance = ev->distance;
2060    e->duration = ev->duration;
2061    e->direction = ev->direction;
2062
2063    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PAN, e, NULL, NULL);
2064 }
2065
2066 static void
2067 _ecore_xcb_event_handle_gesture_notify_pinchrotation(xcb_generic_event_t *event)
2068 {
2069    xcb_gesture_notify_pinch_rotation_event_t *ev;
2070    Ecore_X_Event_Gesture_Notify_PinchRotation *e;
2071
2072    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2073    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2074    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2075
2076    ev = (xcb_gesture_notify_pinch_rotation_event_t *)event;
2077    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_PinchRotation)))) return;
2078
2079    e->win = ev->window;
2080    e->time = ev->time;
2081    e->subtype = ev->kind;
2082    e->num_fingers = ev->num_finger;
2083    e->distance = ev->distance;
2084    e->cx = ev->cx;
2085    e->cy = ev->cy;
2086    e->zoom = XFixedToDouble(ev->zoom);
2087    e->angle = XFixedToDouble(ev->angle);
2088
2089    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION, e, NULL, NULL);
2090 }
2091
2092 static void
2093 _ecore_xcb_event_handle_gesture_notify_tap(xcb_generic_event_t *event)
2094 {
2095    xcb_gesture_notify_tap_event_t *ev;
2096    Ecore_X_Event_Gesture_Notify_Tap *e;
2097
2098    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2099    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2100    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2101
2102    ev = (xcb_gesture_notify_tap_event_t *)event;
2103    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Tap)))) return;
2104
2105    e->win = ev->window;
2106    e->time = ev->time;
2107    e->subtype = ev->kind;
2108    e->num_fingers = ev->num_finger;
2109    e->cx = ev->cx;
2110    e->cy = ev->cy;
2111    e->tap_repeat = ev->tap_repeat;
2112    e->interval = ev->interval;
2113
2114    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAP, e, NULL, NULL);
2115 }
2116
2117 static void
2118 _ecore_xcb_event_handle_gesture_notify_tapnhold(xcb_generic_event_t *event)
2119 {
2120    xcb_gesture_notify_tap_n_hold_event_t *ev;
2121    Ecore_X_Event_Gesture_Notify_TapNHold *e;
2122
2123    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2124    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2125    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2126
2127    ev = (xcb_gesture_notify_tap_n_hold_event_t *)event;
2128    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_TapNHold)))) return;
2129
2130    e->win = ev->window;
2131    e->time = ev->time;
2132    e->subtype = ev->kind;
2133    e->num_fingers = ev->num_finger;
2134    e->cx = ev->cx;
2135    e->cy = ev->cy;
2136    e->interval = ev->interval;
2137    e->hold_time = ev->holdtime;
2138
2139    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD, e, NULL, NULL);
2140 }
2141
2142 static void
2143  _ecore_xcb_event_handle_gesture_notify_hold(xcb_generic_event_t *event)
2144 {
2145    xcb_gesture_notify_hold_event_t *ev;
2146    Ecore_X_Event_Gesture_Notify_Hold *e;
2147
2148    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2149    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2150    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2151
2152    ev = (xcb_gesture_notify_hold_event_t *)event;
2153    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Hold)))) return;
2154
2155    e->win = ev->window;
2156    e->time = ev->time;
2157    e->subtype = ev->kind;
2158    e->num_fingers = ev->num_finger;
2159    e->cx = ev->cx;
2160    e->cy = ev->cy;
2161    e->hold_time = ev->holdtime;
2162
2163    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_HOLD, e, NULL, NULL);
2164 }
2165
2166 static void
2167  _ecore_xcb_event_handle_gesture_notify_group(xcb_generic_event_t *event)
2168 {
2169    xcb_gesture_notify_group_event_t *ev;
2170    Ecore_X_Event_Gesture_Notify_Group *e;
2171
2172    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2173    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2174    fprintf(stderr, "[ECORE_XCB][%s]...\n", __FUNCTION__);
2175
2176    ev = (xcb_gesture_notify_group_event_t *)event;
2177    if (!(e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Group)))) return;
2178
2179    e->win = ev->window;
2180    e->time = ev->time;
2181    e->subtype = ev->kind;
2182    e->num_groups = ev->num_group;
2183    e->group_id = ev->groupid;
2184
2185    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_GROUP, e, NULL, NULL);
2186 }
2187 #endif
2188
2189 #ifdef ECORE_XCB_SHAPE
2190 static void
2191 _ecore_xcb_event_handle_shape_change(xcb_generic_event_t *event)
2192 {
2193    xcb_shape_notify_event_t *ev;
2194    Ecore_X_Event_Window_Shape *e;
2195
2196    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2197    ev = (xcb_shape_notify_event_t *)event;
2198    if (!(e = calloc(1, sizeof(Ecore_X_Event_Window_Shape)))) return;
2199
2200    e->win = ev->affected_window;
2201    e->time = ev->server_time;
2202    switch (ev->shape_kind)
2203      {
2204       case XCB_SHAPE_SK_BOUNDING:
2205         e->type = ECORE_X_SHAPE_BOUNDING;
2206         break;
2207
2208       case XCB_SHAPE_SK_CLIP:
2209         e->type = ECORE_X_SHAPE_CLIP;
2210         break;
2211
2212       case XCB_SHAPE_SK_INPUT:
2213         e->type = ECORE_X_SHAPE_INPUT;
2214         break;
2215
2216       default:
2217         break;
2218      }
2219    e->x = ev->extents_x;
2220    e->y = ev->extents_y;
2221    e->w = ev->extents_width;
2222    e->h = ev->extents_height;
2223    e->shaped = ev->shaped;
2224
2225    ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
2226 }
2227
2228 #endif
2229
2230 static void
2231 _ecore_xcb_event_handle_sync_counter(xcb_generic_event_t *event)
2232 {
2233 #ifdef ECORE_XCB_SYNC
2234    xcb_sync_counter_notify_event_t *ev;
2235    Ecore_X_Event_Sync_Counter *e;
2236 #endif
2237
2238    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2239
2240 #ifdef ECORE_XCB_SYNC
2241    ev = (xcb_sync_counter_notify_event_t *)event;
2242    if (!(e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter)))) return;
2243
2244    e->time = ev->timestamp;
2245
2246    ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
2247 #endif
2248 }
2249
2250 static void
2251 _ecore_xcb_event_handle_sync_alarm(xcb_generic_event_t *event)
2252 {
2253 #ifdef ECORE_XCB_SYNC
2254    xcb_sync_alarm_notify_event_t *ev;
2255    Ecore_X_Event_Sync_Alarm *e;
2256 #endif
2257
2258    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2259 #ifdef ECORE_XCB_SYNC
2260    ev = (xcb_sync_alarm_notify_event_t *)event;
2261    if (!(e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm)))) return;
2262
2263    e->time = ev->timestamp;
2264    e->alarm = ev->alarm;
2265
2266    ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
2267 #endif
2268 }
2269
2270 static void
2271 _ecore_xcb_event_handle_xfixes_selection_notify(xcb_generic_event_t *event)
2272 {
2273 #ifdef ECORE_XCB_XFIXES
2274    Ecore_X_Event_Fixes_Selection_Notify *e;
2275    Ecore_X_Atom sel;
2276    xcb_xfixes_selection_notify_event_t *ev;
2277 #endif
2278
2279    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2280 #ifdef ECORE_XCB_XFIXES
2281    ev = (xcb_xfixes_selection_notify_event_t *)event;
2282
2283    if (!(e = calloc(1, sizeof(*e)))) return;
2284
2285    e->win = ev->window;
2286    e->owner = ev->owner;
2287    e->time = ev->timestamp;
2288    e->selection_time = ev->selection_timestamp;
2289    e->atom = sel = ev->selection;
2290    if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
2291      e->selection = ECORE_X_SELECTION_PRIMARY;
2292    else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
2293      e->selection = ECORE_X_SELECTION_SECONDARY;
2294    else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
2295      e->selection = ECORE_X_SELECTION_CLIPBOARD;
2296    else
2297      e->selection = ECORE_X_SELECTION_OTHER;
2298    e->reason = ev->subtype;
2299
2300    ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL);
2301 #endif
2302 }
2303
2304 static void
2305 _ecore_xcb_event_handle_xfixes_cursor_notify(xcb_generic_event_t *event __UNUSED__)
2306 {
2307    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2308 //  FIXME: TBD
2309 }
2310
2311 static void
2312 _ecore_xcb_event_handle_generic_event(xcb_generic_event_t *event)
2313 {
2314    xcb_ge_event_t *ev;
2315    Ecore_X_Event_Generic *e;
2316
2317    ev = (xcb_ge_event_t *)event;
2318
2319    /* pad0 *IS* extension - bug in xcb */
2320    if (ev->pad0 == _ecore_xcb_event_input)
2321      {
2322         _ecore_xcb_event_handle_input_event(event);
2323 // FIXME: should we generate generic events as WELL as input events?
2324 //        return;
2325      }
2326
2327    if (!(e = calloc(1, sizeof(Ecore_X_Event_Generic))))
2328      return;
2329
2330    DBG("Handle Generic Event: %d", ev->event_type);
2331
2332    e->cookie = ev->sequence;
2333    /* NB: These are bugs in xcb ge_event structure. The struct should have a
2334     * field for extension & data, but does not.
2335     *
2336     * XCB people have been notified of this issue */
2337    e->extension = ev->pad0;
2338    /* e->data = ev->pad1; */
2339    if (ev->length > 0)
2340      {
2341         int len = ev->length * sizeof(int);
2342         e->data = malloc(len);
2343         if (e->data) memcpy(e->data, &(event[1]), len);
2344      }
2345
2346    e->evtype = ev->event_type;
2347
2348    ecore_event_add(ECORE_X_EVENT_GENERIC, e,
2349                    _ecore_xcb_event_generic_event_free, e->data);
2350 }
2351
2352 static void
2353 _ecore_xcb_event_handle_input_event(xcb_generic_event_t *event)
2354 {
2355    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2356
2357    _ecore_xcb_input_handle_event(event);
2358 }
2359
2360 static void
2361 _ecore_xcb_event_key_press(xcb_generic_event_t *event)
2362 {
2363    Ecore_Event_Key *e;
2364    xcb_keysym_t sym = XCB_NO_SYMBOL;
2365    xcb_keycode_t keycode = 0;
2366    xcb_key_press_event_t *xevent;
2367    char *keyname = NULL, *key = NULL;
2368    char *compose = NULL;
2369    char compose_buffer[256];
2370    int val = 0;
2371
2372    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2373
2374    xevent = (xcb_key_press_event_t *)event;
2375    keycode = xevent->detail;
2376
2377    sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, xevent->state);
2378    keyname = _ecore_xcb_keymap_keysym_to_string(sym);
2379    if (!keyname)
2380      {
2381         char buff[256];
2382
2383         snprintf(buff, sizeof(buff), "Keycode-%i", keycode);
2384         keyname = buff;
2385      }
2386
2387    val =
2388      _ecore_xcb_keymap_lookup_string(keycode, xevent->state, compose_buffer,
2389                                      sizeof(compose_buffer), &sym);
2390    if (val > 0)
2391      {
2392         compose_buffer[val] = 0;
2393         compose =
2394           eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer);
2395         if (!compose)
2396           ERR("Ecore_X cannot convert input key string '%s' to UTF-8. "
2397               "Is Eina built with iconv support?", compose_buffer);
2398      }
2399
2400    key = _ecore_xcb_keymap_keysym_to_string(sym);
2401    if (!key) key = keyname;
2402
2403    e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) +
2404               (compose ? strlen(compose) : 0) + 3);
2405    if (e)
2406      {
2407         e->keyname = (char *)(e + 1);
2408         e->key = e->keyname + strlen(keyname) + 1;
2409
2410         e->compose = NULL;
2411         if (compose) e->compose = (e->key + strlen(key) + 1);
2412         e->string = e->compose;
2413
2414         strcpy((char *)e->keyname, keyname);
2415         strcpy((char *)e->key, key);
2416         if (compose) strcpy((char *)e->compose, compose);
2417
2418         e->modifiers = _ecore_xcb_events_modifiers_get(xevent->state);
2419         e->timestamp = xevent->time;
2420         e->window = xevent->child ? xevent->child : xevent->event;
2421         e->event_window = xevent->event;
2422         e->same_screen = xevent->same_screen;
2423         e->root_window = xevent->root;
2424
2425         DBG("Sending Key Down Event: %s", e->keyname);
2426         ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL);
2427      }
2428    _ecore_xcb_event_last_time = xevent->time;
2429 }
2430
2431 static void
2432 _ecore_xcb_event_key_release(xcb_generic_event_t *event)
2433 {
2434    Ecore_Event_Key *e;
2435    xcb_keysym_t sym = XCB_NO_SYMBOL;
2436    xcb_keycode_t keycode = 0;
2437    xcb_key_release_event_t *xevent;
2438    char *keyname = NULL, *key = NULL;
2439    char *compose = NULL;
2440    char compose_buffer[256];
2441    int val = 0;
2442
2443    _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2444
2445    xevent = (xcb_key_release_event_t *)event;
2446    keycode = xevent->detail;
2447
2448    sym = _ecore_xcb_keymap_keycode_to_keysym(keycode, xevent->state);
2449    keyname = _ecore_xcb_keymap_keysym_to_string(sym);
2450    if (!keyname)
2451      {
2452         char buff[256];
2453
2454         snprintf(buff, sizeof(buff), "Keycode-%i", keycode);
2455         keyname = buff;
2456      }
2457
2458    val =
2459      _ecore_xcb_keymap_lookup_string(keycode, xevent->state, compose_buffer,
2460                                      sizeof(compose_buffer), &sym);
2461    if (val > 0)
2462      {
2463         compose_buffer[val] = 0;
2464         compose =
2465           eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer);
2466 //        tmp = compose;
2467      }
2468
2469    key = _ecore_xcb_keymap_keysym_to_string(sym);
2470    if (!key) key = keyname;
2471
2472    e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) +
2473               (compose ? strlen(compose) : 0) + 3);
2474    if (e)
2475      {
2476         e->keyname = (char *)(e + 1);
2477         e->key = e->keyname + strlen(keyname) + 1;
2478
2479         e->compose = NULL;
2480         if (compose) e->compose = (e->key + strlen(key) + 1);
2481         e->string = e->compose;
2482
2483         strcpy((char *)e->keyname, keyname);
2484         strcpy((char *)e->key, key);
2485         if (compose) strcpy((char *)e->compose, compose);
2486
2487         e->modifiers = _ecore_xcb_events_modifiers_get(xevent->state);
2488         e->timestamp = xevent->time;
2489         e->window = xevent->child ? xevent->child : xevent->event;
2490         e->event_window = xevent->event;
2491         e->same_screen = xevent->same_screen;
2492         e->root_window = xevent->root;
2493
2494         ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL);
2495      }
2496    _ecore_xcb_event_last_time = xevent->time;
2497 }
2498
2499 void
2500 _ecore_xcb_event_mouse_move(uint16_t     timestamp,
2501                             uint16_t     modifiers,
2502                             int16_t      x,
2503                             int16_t      y,
2504                             int16_t      root_x,
2505                             int16_t      root_y,
2506                             xcb_window_t event_win,
2507                             xcb_window_t win,
2508                             xcb_window_t root_win,
2509                             uint8_t      same_screen,
2510                             int          dev,
2511                             double       radx,
2512                             double       rady,
2513                             double       pressure,
2514                             double       angle,
2515                             int16_t      mx,
2516                             int16_t      my,
2517                             int16_t      mrx,
2518                             int16_t      mry)
2519 {
2520    Ecore_Event_Mouse_Move *e;
2521    Ecore_Event *event;
2522
2523    if (!(e = malloc(sizeof(Ecore_Event_Mouse_Move)))) return;
2524
2525    e->window = win;
2526    e->root_window = root_win;
2527    e->timestamp = timestamp;
2528    e->same_screen = same_screen;
2529    e->event_window = event_win;
2530    e->modifiers = _ecore_xcb_events_modifiers_get(modifiers);
2531    e->x = x;
2532    e->y = y;
2533    e->root.x = root_x;
2534    e->root.y = root_y;
2535    e->multi.device = dev;
2536    e->multi.radius = ((radx + rady) / 2);
2537    e->multi.radius_x = radx;
2538    e->multi.radius_y = rady;
2539    e->multi.pressure = pressure;
2540    e->multi.angle = angle;
2541    e->multi.x = mx;
2542    e->multi.y = my;
2543    e->multi.root.x = mrx;
2544    e->multi.root.y = mry;
2545
2546    event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e,
2547                            _ecore_xcb_event_mouse_move_free, NULL);
2548
2549    _ecore_xcb_event_last_time = e->timestamp;
2550    _ecore_xcb_event_last_window = e->window;
2551    _ecore_xcb_event_last_root_x = root_x;
2552    _ecore_xcb_event_last_root_y = root_y;
2553 //   _ecore_xcb_event_last_mouse_move_event = event;
2554 }
2555
2556 static void
2557 _ecore_xcb_event_mouse_move_free(void *data __UNUSED__,
2558                                  void *event)
2559 {
2560    Ecore_Event_Mouse_Move *ev;
2561
2562    ev = event;
2563 //   if (_ecore_xcb_event_last_mouse_move_event)
2564 //     {
2565 //        _ecore_xcb_event_last_mouse_move = EINA_FALSE;
2566 //        _ecore_xcb_event_last_mouse_move_event = NULL;
2567 //     }
2568    if (ev) free(ev);
2569 }
2570
2571 Ecore_Event_Mouse_Button *
2572 _ecore_xcb_event_mouse_button(int          event,
2573                               uint16_t     timestamp,
2574                               uint16_t     modifiers,
2575                               xcb_button_t buttons,
2576                               int16_t      x,
2577                               int16_t      y,
2578                               int16_t      root_x,
2579                               int16_t      root_y,
2580                               xcb_window_t event_win,
2581                               xcb_window_t win,
2582                               xcb_window_t root_win,
2583                               uint8_t      same_screen,
2584                               int          dev,
2585                               double       radx,
2586                               double       rady,
2587                               double       pressure,
2588                               double       angle,
2589                               int16_t      mx,
2590                               int16_t      my,
2591                               int16_t      mrx,
2592                               int16_t      mry)
2593 {
2594    Ecore_Event_Mouse_Button *e;
2595    Ecore_X_Mouse_Down_Info *info = NULL;
2596
2597    if (!(e = malloc(sizeof(Ecore_Event_Mouse_Button)))) return NULL;
2598
2599    e->window = win;
2600    e->root_window = root_win;
2601    e->timestamp = timestamp;
2602    e->same_screen = same_screen;
2603    e->event_window = event_win;
2604    e->buttons = buttons;
2605    e->modifiers = _ecore_xcb_events_modifiers_get(modifiers);
2606    e->double_click = 0;
2607    e->triple_click = 0;
2608    e->x = x;
2609    e->y = y;
2610    e->root.x = root_x;
2611    e->root.y = root_y;
2612
2613    if ((info = _ecore_xcb_event_mouse_down_info_get(dev)))
2614      {
2615         if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
2616             (info->did_triple))
2617           {
2618              info->last_win = 0;
2619              info->last_last_win = 0;
2620              info->last_event_win = 0;
2621              info->last_time = 0;
2622              info->last_last_time = 0;
2623           }
2624         if (event_win == win)
2625           {
2626              if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN)
2627                {
2628                   if (((int)(timestamp - info->last_time) <=
2629                        (int)(1000 * _ecore_xcb_double_click_time)) &&
2630                       (win == info->last_win) &&
2631                       (event_win == info->last_event_win))
2632                     {
2633                        e->double_click = 1;
2634                        info->did_double = EINA_TRUE;
2635                     }
2636                   else
2637                     {
2638                        info->did_double = EINA_FALSE;
2639                        info->did_triple = EINA_FALSE;
2640                     }
2641                   if (((int)(timestamp - info->last_last_time) <=
2642                        (int)(2 * 1000 * _ecore_xcb_double_click_time)) &&
2643                       (win == info->last_win) &&
2644                       (win == info->last_last_win) &&
2645                       (event_win == info->last_event_win) &&
2646                       (event_win == info->last_last_event_win))
2647                     {
2648                        e->triple_click = 1;
2649                        info->did_triple = EINA_TRUE;
2650                     }
2651                   else
2652                     info->did_triple = EINA_FALSE;
2653                }
2654              else
2655                {
2656                   if (info->did_double) e->double_click = 1;
2657                   if (info->did_triple) e->triple_click = 1;
2658                }
2659           }
2660      }
2661
2662    /* NB: Comment out right now because _ecore_xcb_mouse_up_count is
2663     * only used here...nowhere else in the code */
2664
2665    /* if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&  */
2666    /*     (!e->double_click) && (!e->triple_click)) */
2667    /*   _ecore_xcb_mouse_up_count = 0; */
2668
2669    e->multi.device = dev;
2670    e->multi.radius = ((radx + rady) / 2);
2671    e->multi.radius_x = radx;
2672    e->multi.radius_y = rady;
2673    e->multi.pressure = pressure;
2674    e->multi.angle = angle;
2675    e->multi.x = mx;
2676    e->multi.y = my;
2677    e->multi.root.x = mrx;
2678    e->multi.root.y = mry;
2679
2680    _ecore_xcb_event_last_time = e->timestamp;
2681    _ecore_xcb_event_last_window = e->window;
2682    _ecore_xcb_event_last_root_x = root_x;
2683    _ecore_xcb_event_last_root_y = root_y;
2684
2685    ecore_event_add(event, e, NULL, NULL);
2686
2687    if ((info) && (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
2688        (win == event_win) && (!info->did_triple))
2689      {
2690         info->last_last_win = info->last_win;
2691         info->last_win = win;
2692         info->last_last_event_win = info->last_event_win;
2693         info->last_event_win = event_win;
2694         info->last_last_time = info->last_time;
2695         info->last_time = timestamp;
2696      }
2697
2698    return e;
2699 }
2700
2701 static Ecore_X_Event_Mode
2702 _ecore_xcb_event_mode_get(uint8_t mode)
2703 {
2704    switch (mode)
2705      {
2706       case XCB_NOTIFY_MODE_NORMAL:
2707         return ECORE_X_EVENT_MODE_NORMAL;
2708
2709       case XCB_NOTIFY_MODE_WHILE_GRABBED:
2710         return ECORE_X_EVENT_MODE_WHILE_GRABBED;
2711
2712       case XCB_NOTIFY_MODE_GRAB:
2713         return ECORE_X_EVENT_MODE_GRAB;
2714
2715       case XCB_NOTIFY_MODE_UNGRAB:
2716         return ECORE_X_EVENT_MODE_UNGRAB;
2717
2718       default:
2719         return ECORE_X_EVENT_MODE_NORMAL;
2720      }
2721 }
2722
2723 static Ecore_X_Event_Detail
2724 _ecore_xcb_event_detail_get(uint8_t detail)
2725 {
2726    switch (detail)
2727      {
2728       case XCB_NOTIFY_DETAIL_ANCESTOR:
2729         return ECORE_X_EVENT_DETAIL_ANCESTOR;
2730
2731       case XCB_NOTIFY_DETAIL_VIRTUAL:
2732         return ECORE_X_EVENT_DETAIL_VIRTUAL;
2733
2734       case XCB_NOTIFY_DETAIL_INFERIOR:
2735         return ECORE_X_EVENT_DETAIL_INFERIOR;
2736
2737       case XCB_NOTIFY_DETAIL_NONLINEAR:
2738         return ECORE_X_EVENT_DETAIL_NON_LINEAR;
2739
2740       case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
2741         return ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
2742
2743       case XCB_NOTIFY_DETAIL_POINTER:
2744         return ECORE_X_EVENT_DETAIL_POINTER;
2745
2746       case XCB_NOTIFY_DETAIL_POINTER_ROOT:
2747         return ECORE_X_EVENT_DETAIL_POINTER_ROOT;
2748
2749       case XCB_NOTIFY_DETAIL_NONE:
2750       default:
2751         return ECORE_X_EVENT_DETAIL_ANCESTOR;
2752      }
2753 }
2754
2755 static void
2756 _ecore_xcb_event_xdnd_enter_free(void *data __UNUSED__,
2757                                  void *event)
2758 {
2759    Ecore_X_Event_Xdnd_Enter *e;
2760    int i = 0;
2761
2762    e = event;
2763    for (i = 0; i < e->num_types; i++)
2764      free(e->types[i]);
2765    free(e->types);
2766    free(e);
2767 }
2768
2769 static void
2770 _ecore_xcb_event_selection_notify_free(void *data __UNUSED__,
2771                                        void *event)
2772 {
2773    Ecore_X_Event_Selection_Notify *e;
2774    Ecore_X_Selection_Data *sel;
2775
2776    e = event;
2777    if (!(sel = e->data)) return;
2778    if (sel->free) sel->free(sel);
2779    free(e->target);
2780    free(e);
2781 }
2782
2783 static void
2784 _ecore_xcb_event_generic_event_free(void *data,
2785                                     void *event)
2786 {
2787    Ecore_X_Event_Generic *e;
2788
2789    e = (Ecore_X_Event_Generic *)event;
2790    if (e->data) free(data);
2791    free(e);
2792 }
2793
2794 static void
2795 _ecore_xcb_event_mouse_down_info_clear(void)
2796 {
2797    Eina_Inlist *l;
2798    Ecore_X_Mouse_Down_Info *info = NULL;
2799
2800    l = _ecore_xcb_mouse_down_info_list;
2801    while (l)
2802      {
2803         info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info);
2804         l = eina_inlist_remove(l, l);
2805         free(info);
2806      }
2807    _ecore_xcb_mouse_down_info_list = NULL;
2808 }
2809
2810 static Ecore_X_Mouse_Down_Info *
2811 _ecore_xcb_event_mouse_down_info_get(int dev)
2812 {
2813    Eina_Inlist *l;
2814    Ecore_X_Mouse_Down_Info *info = NULL;
2815
2816    l = _ecore_xcb_mouse_down_info_list;
2817    EINA_INLIST_FOREACH(l, info)
2818      if (info->dev == dev) return info;
2819
2820    if (!(info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info)))) return NULL;
2821
2822    info->dev = dev;
2823    l = eina_inlist_append(l, (Eina_Inlist *)info);
2824    _ecore_xcb_mouse_down_info_list = l;
2825
2826    return info;
2827 }
2828