bf6799a9b37302b1c4fea5238988740c7e9fe143
[framework/uifw/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_events.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include "Ecore.h"
6 #include "ecore_xcb_private.h"
7 #include "Ecore_X_Atoms.h"
8
9
10 /** OpenBSD does not define CODESET
11  * FIXME ??
12  */
13
14 #ifndef CODESET
15 #define CODESET "INVALID"
16 #endif
17
18 #if 0
19 static void _ecore_x_event_free_window_prop_name_class_change(void *data, void *ev);
20 static void _ecore_x_event_free_window_prop_title_change(void *data, void *ev);
21 static void _ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev);
22 static void _ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev);
23 static void _ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev);
24 static void _ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev);
25 #endif
26 static void _ecore_x_event_free_key_down(void *data, void *ev);
27 static void _ecore_x_event_free_key_up(void *data, void *ev);
28
29 static Ecore_X_Window _ecore_xcb_mouse_down_last_window = 0;
30 static Ecore_X_Window _ecore_xcb_mouse_down_last_last_window = 0;
31 static Ecore_X_Window _ecore_xcb_mouse_down_last_event_window = 0;
32 static Ecore_X_Window _ecore_xcb_mouse_down_last_last_event_window = 0;
33 static Ecore_X_Time   _ecore_xcb_mouse_down_last_time = 0;
34 static Ecore_X_Time   _ecore_xcb_mouse_down_last_last_time = 0;
35 static int            _ecore_xcb_mouse_up_count = 0;
36 static int            _ecore_xcb_mouse_down_did_triple = 0;
37
38
39 /* FIXME: roundtrip */
40 EAPI void
41 ecore_x_event_mask_set(Ecore_X_Window     window,
42                        Ecore_X_Event_Mask mask)
43 {
44    xcb_get_window_attributes_cookie_t cookie;
45    xcb_get_window_attributes_reply_t *reply;
46    uint32_t                           value_list;
47
48    if (!window)
49       window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
50
51    cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
52    reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
53    if (!reply) return;
54
55    value_list = mask | reply->your_event_mask;
56    xcb_change_window_attributes(_ecore_xcb_conn, window, XCB_CW_EVENT_MASK, &value_list);
57    free(reply);
58 }
59
60 /* FIXME: roundtrip */
61 EAPI void
62 ecore_x_event_mask_unset(Ecore_X_Window     window,
63                          Ecore_X_Event_Mask mask)
64 {
65    xcb_get_window_attributes_cookie_t cookie;
66    xcb_get_window_attributes_reply_t *reply;
67    uint32_t value_list;
68
69    if (!window)
70       window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
71
72    cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
73    reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
74    if (!reply) return;
75
76    value_list = reply->your_event_mask & ~mask;
77    xcb_change_window_attributes(_ecore_xcb_conn, window, XCB_CW_EVENT_MASK, &value_list);
78    free(reply);
79 }
80
81 #if 0
82 static void
83 _ecore_x_event_free_window_prop_name_class_change(void *data, void *ev)
84 {
85    Ecore_X_Event_Window_Prop_Name_Class_Change *e;
86
87    e = ev;
88    if (e->name) free(e->name);
89    if (e->clas) free(e->clas);
90    free(e);
91 }
92
93 static void
94 _ecore_x_event_free_window_prop_title_change(void *data, void *ev)
95 {
96    Ecore_X_Event_Window_Prop_Title_Change *e;
97
98    e = ev;
99    if (e->title) free(e->title);
100    free(e);
101 }
102
103 static void
104 _ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev)
105 {
106    Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
107
108    e = ev;
109    if (e->title) free(e->title);
110    free(e);
111 }
112
113 static void
114 _ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev)
115 {
116    Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
117
118    e = ev;
119    if (e->name) free(e->name);
120    free(e);
121 }
122
123 static void
124 _ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev)
125 {
126    Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
127
128    e = ev;
129    if (e->name) free(e->name);
130    free(e);
131 }
132
133 static void
134 _ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev)
135 {
136    Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
137
138    e = ev;
139    if (e->name) free(e->name);
140    free(e);
141 }
142 #endif
143
144 static void
145 _ecore_x_event_free_key_down(void *data __UNUSED__, void *ev)
146 {
147    Ecore_X_Event_Key_Down *e;
148
149    e = ev;
150    if (e->keyname) free(e->keyname);
151    if (e->keysymbol) free(e->keysymbol);
152    if (e->key_compose) free(e->key_compose);
153    free(e);
154 }
155
156 static void
157 _ecore_x_event_free_key_up(void *data __UNUSED__, void *ev)
158 {
159    Ecore_X_Event_Key_Up *e;
160
161    e = ev;
162    if (e->keyname) free(e->keyname);
163    if (e->keysymbol) free(e->keysymbol);
164    if (e->key_compose) free(e->key_compose);
165    free(e);
166 }
167
168 static void
169 _ecore_x_event_free_xdnd_enter(void *data __UNUSED__, void *ev)
170 {
171    Ecore_X_Event_Xdnd_Enter *e;
172    int                       i;
173
174    e = ev;
175    for (i = 0; i < e->num_types; i++)
176      free(e->types[i]);
177    free(e->types);
178    free(e);
179 }
180
181 static void
182 _ecore_x_event_free_selection_notify(void *data __UNUSED__, void *ev)
183 {
184    Ecore_X_Event_Selection_Notify *e;
185    Ecore_X_Selection_Data         *sel;
186
187    e = ev;
188    sel = e->data;
189    if (sel->free)
190      sel->free(sel);
191    free(e->target);
192    free(e);
193 }
194
195 /* FIXME: handle this event */
196 void
197 _ecore_x_event_handle_key_press(xcb_generic_event_t *event)
198 {
199    xcb_key_press_event_t  *ev;
200 /*    Ecore_X_Event_Key_Down *e; */
201 /*    char                   *keyname; */
202 /*    int                     val; */
203 /*    char                    buf[256]; */
204 /*    KeySym                  sym; */
205 /*    XComposeStatus          status; */
206
207    ev = (xcb_key_press_event_t *)event;
208 /*    e = calloc(1, sizeof(Ecore_X_Event_Key_Down)); */
209 /*    if (!e) return; */
210 /*    keyname = XKeysymToString(XKeycodeToKeysym(xevent->xkey.display,  */
211 /*                                            xevent->xkey.keycode, 0)); */
212 /*    if (!keyname) */
213 /*      { */
214 /*      snprintf(buf, sizeof(buf), "Keycode-%i", xevent->xkey.keycode); */
215 /*      keyname = buf; */
216 /*      } */
217 /*    e->keyname = strdup(keyname); */
218 /*    if (!e->keyname) */
219 /*      { */
220 /*      free(e); */
221 /*      return; */
222 /*      } */
223 /*    val = XLookupString((XKeyEvent *)xevent, buf, sizeof(buf), &sym, &status); */
224 /*    if (val > 0) */
225 /*      { */
226 /*      buf[val] = 0; */
227 /*      e->key_compose = ecore_txt_convert(nl_langinfo(CODESET), "UTF-8", buf); */
228 /*      } */
229 /*    else e->key_compose = NULL; */
230 /*    keyname = XKeysymToString(sym); */
231 /*    if (keyname) e->keysymbol = strdup(keyname); */
232 /*    else e->keysymbol = strdup(e->keyname); */
233 /*    if (!e->keysymbol) */
234 /*      { */
235 /*      if (e->keyname) free(e->keyname); */
236 /*      if (e->key_compose) free(e->key_compose); */
237 /*      free(e); */
238 /*      return; */
239 /*      } */
240 /*    if (xevent->xkey.subwindow) e->win = xevent->xkey.subwindow; */
241 /*    else e->win = xevent->xkey.window; */
242 /*    e->event_win = xevent->xkey.window; */
243 /*    e->time = xevent->xkey.time; */
244 /*    e->modifiers = xevent->xkey.state; */
245 /*    _ecore_x_event_last_time = e->time; */
246 /*    ecore_event_add(ECORE_X_EVENT_KEY_DOWN, e, _ecore_x_event_free_key_down, NULL); */
247 }
248
249 /* FIXME: handle this event */
250 void
251 _ecore_x_event_handle_key_release(xcb_generic_event_t *event)
252 {
253    xcb_key_release_event_t *ev;
254 /*    Ecore_X_Event_Key_Up    *e; */
255 /*    char                   *keyname; */
256 /*    int                     val; */
257 /*    char                    buf[256]; */
258 /*    KeySym                  sym; */
259 /*    XComposeStatus          status; */
260
261    ev = (xcb_key_release_event_t *)event;
262 /*    e = calloc(1, sizeof(Ecore_X_Event_Key_Up)); */
263 /*    if (!e) return; */
264 /*    keyname = XKeysymToString(XKeycodeToKeysym(xevent->xkey.display,  */
265 /*                                            xevent->xkey.keycode, 0)); */
266 /*    if (!keyname) */
267 /*      { */
268 /*      snprintf(buf, sizeof(buf), "Keycode-%i", xevent->xkey.keycode); */
269 /*      keyname = buf; */
270 /*      } */
271 /*    e->keyname = strdup(keyname); */
272 /*    if (!e->keyname) */
273 /*      { */
274 /*      free(e); */
275 /*      return; */
276 /*      } */
277 /*    val = XLookupString((XKeyEvent *)xevent, buf, sizeof(buf), &sym, &status); */
278 /*    if (val > 0) */
279 /*      { */
280 /*      buf[val] = 0; */
281 /*      e->key_compose = ecore_txt_convert("ISO8859-1", "UTF-8", buf); */
282 /*      } */
283 /*    else e->key_compose = NULL; */
284 /*    keyname = XKeysymToString(sym); */
285 /*    if (keyname) e->keysymbol = strdup(keyname); */
286 /*    else e->keysymbol = strdup(e->keyname); */
287 /*    if (!e->keysymbol) */
288 /*      { */
289 /*      if (e->keyname) free(e->keyname); */
290 /*      if (e->key_compose) free(e->key_compose); */
291 /*      free(e); */
292 /*      return; */
293 /*      } */
294 /*    if (xevent->xkey.subwindow) e->win = xevent->xkey.subwindow; */
295 /*    else e->win = xevent->xkey.window; */
296 /*    e->event_win = xevent->xkey.window; */
297 /*    e->time = xevent->xkey.time; */
298 /*    e->modifiers = xevent->xkey.state; */
299 /*    _ecore_x_event_last_time = e->time; */
300 /*    ecore_event_add(ECORE_X_EVENT_KEY_UP, e, _ecore_x_event_free_key_up, NULL); */
301 }
302
303 void
304 _ecore_x_event_handle_button_press(xcb_generic_event_t *event)
305 {
306    xcb_button_press_event_t *ev;
307    int                       i;
308
309    ev = (xcb_button_press_event_t *)event;
310    if ((ev->detail > 3) && (ev->detail < 8))
311      {
312         Ecore_X_Event_Mouse_Wheel *e;
313
314         e = malloc(sizeof(Ecore_X_Event_Mouse_Wheel));
315
316         if (!e)
317           return;
318
319         e->modifiers = ev->state;
320         e->direction = 0;
321         e->z = 0;
322         if      (ev->detail == 4)
323           {
324              e->direction = 0;
325              e->z = -1;
326           }
327         else if (ev->detail == 5)
328           {
329              e->direction = 0;
330              e->z = 1;
331           }
332         else if (ev->detail == 6)
333           {
334              e->direction = 1;
335              e->z = -1;
336           }
337         else if (ev->detail == 7)
338           {
339              e->direction = 1;
340              e->z = 1;
341           }
342         e->x = ev->event_x;
343         e->y = ev->event_y;
344         e->root.x = ev->root_x;
345         e->root.y = ev->root_y;
346
347         if (ev->child)
348           e->win = ev->child;
349         else
350           e->win = ev->event;
351
352         e->event_win = ev->event;
353         e->same_screen = ev->same_screen;
354         e->root_win = ev->root;
355         e->time = ev->time;
356         _ecore_xcb_event_last_time = e->time;
357         _ecore_xcb_event_last_window = e->win;
358         _ecore_xcb_event_last_root_x = e->root.x;
359         _ecore_xcb_event_last_root_y = e->root.y;
360         ecore_event_add(ECORE_X_EVENT_MOUSE_WHEEL, e, NULL, NULL);
361         for (i = 0; i < _ecore_window_grabs_num; i++)
362           {
363              if ((_ecore_window_grabs[i] == ev->event) ||
364                  (_ecore_window_grabs[i] == ev->child))
365                {
366                   int replay = 0;
367
368                   if (_ecore_window_grab_replay_func)
369                     replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
370                                                             ECORE_X_EVENT_MOUSE_WHEEL,
371                                                             e);
372                   /* FIXME: xcb_key_press_event_t does not save the */
373                   /* connection. So I use the current one */
374                   if (replay)
375                     xcb_allow_events(_ecore_xcb_conn,
376                                      XCB_ALLOW_REPLAY_POINTER,
377                                      ev->time);
378                   else
379                     xcb_allow_events(_ecore_xcb_conn,
380                                      XCB_ALLOW_ASYNC_POINTER,
381                                      ev->time);
382                   break;
383                }
384           }
385      }
386    else
387      {
388           {
389              Ecore_X_Event_Mouse_Move *e;
390
391              e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
392              if (!e) return;
393              e->modifiers = ev->state;
394              e->x = ev->event_x;
395              e->y = ev->event_y;
396              e->root.x = ev->root_x;
397              e->root.y = ev->root_y;
398              if (ev->child) e->win = ev->child;
399              else e->win = ev->event;
400              e->same_screen = ev->same_screen;
401              e->root_win = ev->root;
402              e->event_win = ev->event;
403              e->time = ev->time;
404              _ecore_xcb_event_last_time = e->time;
405              _ecore_xcb_event_last_window = e->win;
406              _ecore_xcb_event_last_root_x = e->root.x;
407              _ecore_xcb_event_last_root_y = e->root.y;
408              ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
409           }
410           {
411              Ecore_X_Event_Mouse_Button_Down *e;
412
413             if (_ecore_xcb_mouse_down_did_triple)
414               {
415                  _ecore_xcb_mouse_down_last_window = 0;
416                  _ecore_xcb_mouse_down_last_last_window = 0;
417                  _ecore_xcb_mouse_down_last_event_window = 0;
418                  _ecore_xcb_mouse_down_last_last_event_window = 0;
419                  _ecore_xcb_mouse_down_last_time = 0;
420                  _ecore_xcb_mouse_down_last_last_time = 0;
421               }
422
423              e = calloc(1, sizeof(Ecore_X_Event_Mouse_Button_Down));
424              if (!e) return;
425              e->button = ev->detail;
426              e->modifiers = ev->state;
427              e->x = ev->event_x;
428              e->y = ev->event_y;
429              e->root.x = ev->root_x;
430              e->root.y = ev->root_y;
431              if (ev->child) e->win = ev->child;
432              else e->win = ev->event;
433              e->same_screen = ev->same_screen;
434              e->root_win = ev->root;
435              e->event_win = ev->event;
436              e->time = ev->time;
437              if (e->win == e->event_win)
438                {
439                   if (((int)(e->time - _ecore_xcb_mouse_down_last_time) <=
440                        (int)(1000 * _ecore_xcb_double_click_time)) &&
441                       (e->win == _ecore_xcb_mouse_down_last_window) &&
442                       (e->event_win == _ecore_xcb_mouse_down_last_event_window)
443                       )
444                     e->double_click = 1;
445                   if (((int)(e->time - _ecore_xcb_mouse_down_last_last_time) <=
446                        (int)(2 * 1000 * _ecore_xcb_double_click_time)) &&
447                       (e->win == _ecore_xcb_mouse_down_last_window) &&
448                       (e->win == _ecore_xcb_mouse_down_last_last_window) &&
449                       (e->event_win == _ecore_xcb_mouse_down_last_event_window) &&
450                       (e->event_win == _ecore_xcb_mouse_down_last_last_event_window)
451                       )
452                     {
453                         e->triple_click = 1;
454                        _ecore_xcb_mouse_down_did_triple = 1;
455                     }
456                   else
457                     _ecore_xcb_mouse_down_did_triple = 0;
458                }
459              if (!e->double_click && !e->triple_click)
460                _ecore_xcb_mouse_up_count = 0;
461              _ecore_xcb_event_last_time = e->time;
462              _ecore_xcb_event_last_window = e->win;
463              _ecore_xcb_event_last_root_x = e->root.x;
464              _ecore_xcb_event_last_root_y = e->root.y;
465              ecore_event_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
466              for (i = 0; i < _ecore_window_grabs_num; i++)
467                {
468                   if ((_ecore_window_grabs[i] == ev->event) ||
469                       (_ecore_window_grabs[i] == ev->child))
470                     {
471                        int replay = 0;
472
473                        if (_ecore_window_grab_replay_func)
474                          replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
475                                                                  ECORE_X_EVENT_MOUSE_BUTTON_DOWN,
476                                                                  e);
477                        /* FIXME: xcb_key_press_event_t does not save the */
478                        /* connection. So I use the current one */
479                        if (replay)
480                          xcb_allow_events(_ecore_xcb_conn,
481                                           XCB_ALLOW_REPLAY_POINTER,
482                                           ev->time);
483                        else
484                          xcb_allow_events(_ecore_xcb_conn,
485                                           XCB_ALLOW_ASYNC_POINTER,
486                                           ev->time);
487                        break;
488                     }
489                }
490              if (e->win == e->event_win)
491                {
492                   if (!_ecore_xcb_mouse_down_did_triple)
493                     {
494                        _ecore_xcb_mouse_down_last_last_window = _ecore_xcb_mouse_down_last_window;
495                        if (ev->child)
496                          _ecore_xcb_mouse_down_last_window = ev->child;
497                        else
498                          _ecore_xcb_mouse_down_last_window = ev->event;
499                        _ecore_xcb_mouse_down_last_last_event_window = _ecore_xcb_mouse_down_last_event_window;
500                        _ecore_xcb_mouse_down_last_event_window = ev->event;
501                        _ecore_xcb_mouse_down_last_last_time = _ecore_xcb_mouse_down_last_time;
502                        _ecore_xcb_mouse_down_last_time = ev->time;
503                     }
504                }
505           }
506      }
507 }
508
509 void
510 _ecore_x_event_handle_button_release(xcb_generic_event_t *event)
511 {
512    xcb_button_release_event_t *ev;
513
514    ev = (xcb_button_release_event_t *)event;
515    /* filter out wheel buttons */
516    if ((ev->detail <= 3) || (ev->detail > 7))
517      {
518           {
519              Ecore_X_Event_Mouse_Move *e;
520
521              e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
522              if (!e) return;
523              e->modifiers = ev->state;
524              e->x = ev->event_x;
525              e->y = ev->event_y;
526              e->root.x = ev->root_x;
527              e->root.y = ev->root_y;
528              if (ev->child) e->win = ev->child;
529              else e->win = ev->event;
530              e->same_screen = ev->same_screen;
531              e->root_win = ev->root;
532              e->event_win = ev->event;
533              e->time = ev->time;
534              _ecore_xcb_event_last_time = e->time;
535              _ecore_xcb_event_last_window = e->win;
536              _ecore_xcb_event_last_root_x = e->root.x;
537              _ecore_xcb_event_last_root_y = e->root.y;
538              ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
539           }
540           {
541              Ecore_X_Event_Mouse_Button_Up *e;
542
543              e = calloc(1, sizeof(Ecore_X_Event_Mouse_Button_Up));
544              if (!e) return;
545              e->button = ev->detail;
546              e->modifiers = ev->state;
547              e->x = ev->event_x;
548              e->y = ev->event_y;
549              e->root.x = ev->root_x;
550              e->root.y = ev->root_y;
551              if (ev->child) e->win = ev->child;
552              else e->win = ev->event;
553              e->same_screen = ev->same_screen;
554              e->root_win = ev->root;
555              e->event_win = ev->event;
556              e->time = ev->time;
557              _ecore_xcb_mouse_up_count++;
558              if (e->win == e->event_win)
559                {
560                   if ((_ecore_xcb_mouse_up_count >= 2) &&
561                       ((int)(e->time - _ecore_xcb_mouse_down_last_time) <=
562                        (int)(1000 * _ecore_xcb_double_click_time)) &&
563                       (e->win == _ecore_xcb_mouse_down_last_window) &&
564                       (e->event_win == _ecore_xcb_mouse_down_last_event_window)
565                       )
566                     e->double_click = 1;
567                   if ((_ecore_xcb_mouse_up_count >= 3) &&
568                      ((int)(e->time - _ecore_xcb_mouse_down_last_last_time) <=
569                        (int)(2 * 1000 * _ecore_xcb_double_click_time)) &&
570                       (e->win == _ecore_xcb_mouse_down_last_window) &&
571                       (e->win == _ecore_xcb_mouse_down_last_last_window) &&
572                       (e->event_win == _ecore_xcb_mouse_down_last_event_window) &&
573                       (e->event_win == _ecore_xcb_mouse_down_last_last_event_window)
574                       )
575                     e->triple_click = 1;
576                }
577              _ecore_xcb_event_last_time = e->time;
578              _ecore_xcb_event_last_window = e->win;
579              _ecore_xcb_event_last_root_x = e->root.x;
580              _ecore_xcb_event_last_root_y = e->root.y;
581              ecore_event_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
582           }
583      }
584 }
585
586 void
587 _ecore_x_event_handle_motion_notify(xcb_generic_event_t *event)
588 {
589    xcb_motion_notify_event_t *ev;
590    Ecore_X_Event_Mouse_Move  *e;
591
592    ev = (xcb_motion_notify_event_t *)event;
593    e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
594    if (!e) return;
595    e->modifiers = ev->state;
596    e->x = ev->event_x;
597    e->y = ev->event_y;
598    e->root.x = ev->root_x;
599    e->root.y = ev->root_y;
600    if (ev->child) e->win = ev->child;
601    else e->win = ev->event;
602    e->same_screen = ev->same_screen;
603    e->root_win = ev->root;
604    e->event_win = ev->event;
605    e->time = ev->time;
606    _ecore_xcb_event_last_time = e->time;
607    _ecore_xcb_event_last_window = e->win;
608    _ecore_xcb_event_last_root_x = e->root.x;
609    _ecore_xcb_event_last_root_y = e->root.y;
610
611    /* Xdnd handling */
612    _ecore_x_dnd_drag(e->root_win, e->root.x, e->root.y);
613
614    ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
615 }
616
617 void
618 _ecore_x_event_handle_enter_notify(xcb_generic_event_t *event)
619 {
620    xcb_enter_notify_event_t *ev;
621
622    ev = (xcb_enter_notify_event_t *)event;
623
624      {
625         Ecore_X_Event_Mouse_Move *e;
626
627         e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
628         if (!e) return;
629         e->modifiers = ev->state;
630         e->x = ev->event_x;
631         e->y = ev->event_y;
632         e->root.x = ev->root_x;
633         e->root.y = ev->root_y;
634         if (ev->child) e->win = ev->child;
635         else e->win = ev->event;
636         e->same_screen = ev->same_screen_focus;
637         e->root_win = ev->root;
638         e->event_win = ev->event;
639         e->time = ev->time;
640         _ecore_xcb_event_last_time = e->time;
641         _ecore_xcb_event_last_window = e->win;
642         _ecore_xcb_event_last_root_x = e->root.x;
643         _ecore_xcb_event_last_root_y = e->root.y;
644         ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
645      }
646      {
647         Ecore_X_Event_Mouse_In *e;
648
649         e = calloc(1, sizeof(Ecore_X_Event_Mouse_In));
650         if (!e) return;
651         e->modifiers = ev->state;
652         e->x = ev->event_x;
653         e->y = ev->event_y;
654         e->root.x = ev->root_x;
655         e->root.y = ev->root_y;
656         if (ev->child) e->win = ev->child;
657         else e->win = ev->event;
658         e->same_screen = ev->same_screen_focus;
659         e->root_win = ev->root;
660         e->event_win = ev->event;
661         switch (ev->mode) {
662         case XCB_NOTIFY_MODE_NORMAL:
663           e->mode = ECORE_X_EVENT_MODE_NORMAL;
664           break;
665         case XCB_NOTIFY_MODE_GRAB:
666           e->mode = ECORE_X_EVENT_MODE_GRAB;
667           break;
668         case XCB_NOTIFY_MODE_UNGRAB:
669           e->mode = ECORE_X_EVENT_MODE_UNGRAB;
670           break;
671         default:
672           e->mode = ECORE_X_EVENT_MODE_NORMAL;
673           break;
674         }
675         switch (ev->detail) {
676         case XCB_NOTIFY_DETAIL_ANCESTOR:
677           e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
678           break;
679         case XCB_NOTIFY_DETAIL_VIRTUAL:
680           e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
681           break;
682         case XCB_NOTIFY_DETAIL_INFERIOR:
683           e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
684           break;
685         case XCB_NOTIFY_DETAIL_NONLINEAR:
686           e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
687           break;
688         case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
689           e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
690           break;
691         default:
692           e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
693           break;
694         }
695         e->time = ev->time;
696         _ecore_xcb_event_last_time = e->time;
697         ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
698      }
699 }
700
701 void
702 _ecore_x_event_handle_leave_notify(xcb_generic_event_t *event)
703 {
704    xcb_leave_notify_event_t *ev;
705
706    ev = (xcb_leave_notify_event_t *)event;
707      {
708         Ecore_X_Event_Mouse_Move *e;
709
710         e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
711         if (!e) return;
712         e->modifiers = ev->state;
713         e->x = ev->event_x;
714         e->y = ev->event_y;
715         e->root.x = ev->root_x;
716         e->root.y = ev->root_y;
717         if (ev->child) e->win = ev->child;
718         else e->win = ev->event;
719         e->same_screen = ev->same_screen_focus;
720         e->root_win = ev->root;
721         e->event_win = ev->event;
722         e->time = ev->time;
723         _ecore_xcb_event_last_time = e->time;
724         _ecore_xcb_event_last_window = e->win;
725         _ecore_xcb_event_last_root_x = e->root.x;
726         _ecore_xcb_event_last_root_y = e->root.y;
727         ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
728      }
729      {
730         Ecore_X_Event_Mouse_Out *e;
731
732         e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out));
733         if (!e) return;
734         e->modifiers = ev->state;
735         e->x = ev->event_x;
736         e->y = ev->event_y;
737         e->root.x = ev->root_x;
738         e->root.y = ev->root_y;
739         if (ev->child) e->win = ev->child;
740         else e->win = ev->event;
741         e->same_screen = ev->same_screen_focus;
742         e->root_win = ev->root;
743         e->event_win = ev->event;
744         switch (ev->mode) {
745         case XCB_NOTIFY_MODE_NORMAL:
746           e->mode = ECORE_X_EVENT_MODE_NORMAL;
747           break;
748         case XCB_NOTIFY_MODE_GRAB:
749           e->mode = ECORE_X_EVENT_MODE_GRAB;
750           break;
751         case XCB_NOTIFY_MODE_UNGRAB:
752           e->mode = ECORE_X_EVENT_MODE_UNGRAB;
753           break;
754         default:
755           e->mode = ECORE_X_EVENT_MODE_NORMAL;
756           break;
757         }
758         switch (ev->detail) {
759         case XCB_NOTIFY_DETAIL_ANCESTOR:
760           e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
761           break;
762         case XCB_NOTIFY_DETAIL_VIRTUAL:
763           e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
764           break;
765         case XCB_NOTIFY_DETAIL_INFERIOR:
766           e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
767           break;
768         case XCB_NOTIFY_DETAIL_NONLINEAR:
769           e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
770           break;
771         case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
772           e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
773           break;
774         default:
775           e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
776           break;
777         }
778         e->time = ev->time;
779         _ecore_xcb_event_last_time = e->time;
780         _ecore_xcb_event_last_window = e->win;
781         _ecore_xcb_event_last_root_x = e->root.x;
782         _ecore_xcb_event_last_root_y = e->root.y;
783         ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
784      }
785 }
786
787 void
788 _ecore_x_event_handle_focus_in(xcb_generic_event_t *event)
789 {
790    xcb_focus_in_event_t          *ev;
791    Ecore_X_Event_Window_Focus_In *e;
792
793    ev = (xcb_focus_in_event_t *)event;
794    e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In));
795    if (!e) return;
796    e->win = ev->event;
797    switch (ev->mode) {
798    case XCB_NOTIFY_MODE_NORMAL:
799      e->mode = ECORE_X_EVENT_MODE_NORMAL;
800      break;
801    case XCB_NOTIFY_MODE_GRAB:
802      e->mode = ECORE_X_EVENT_MODE_GRAB;
803      break;
804    case XCB_NOTIFY_MODE_UNGRAB:
805      e->mode = ECORE_X_EVENT_MODE_UNGRAB;
806      break;
807    case XCB_NOTIFY_MODE_WHILE_GRABBED:
808      e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
809      break;
810    }
811    switch (ev->detail) {
812    case XCB_NOTIFY_DETAIL_ANCESTOR:
813      e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
814      break;
815    case XCB_NOTIFY_DETAIL_VIRTUAL:
816      e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
817      break;
818    case XCB_NOTIFY_DETAIL_INFERIOR:
819      e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
820      break;
821    case XCB_NOTIFY_DETAIL_NONLINEAR:
822      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
823      break;
824    case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
825      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
826      break;
827    case XCB_NOTIFY_DETAIL_POINTER:
828      e->detail = ECORE_X_EVENT_DETAIL_POINTER;
829      break;
830    case XCB_NOTIFY_DETAIL_POINTER_ROOT:
831      e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
832      break;
833    case XCB_NOTIFY_DETAIL_NONE:
834      e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
835      break;
836    }
837    e->time = _ecore_xcb_event_last_time;
838    _ecore_xcb_event_last_time = e->time;
839    ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
840 }
841
842 void
843 _ecore_x_event_handle_focus_out(xcb_generic_event_t *event)
844 {
845    xcb_focus_out_event_t            *ev;
846    Ecore_X_Event_Window_Focus_Out *e;
847
848    ev = (xcb_focus_out_event_t *)event;
849    e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out));
850    if (!e) return;
851    e->win = ev->event;
852    switch (ev->mode) {
853    case XCB_NOTIFY_MODE_NORMAL:
854      e->mode = ECORE_X_EVENT_MODE_NORMAL;
855      break;
856    case XCB_NOTIFY_MODE_GRAB:
857      e->mode = ECORE_X_EVENT_MODE_GRAB;
858      break;
859    case XCB_NOTIFY_MODE_UNGRAB:
860      e->mode = ECORE_X_EVENT_MODE_UNGRAB;
861      break;
862    case XCB_NOTIFY_MODE_WHILE_GRABBED:
863      e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
864      break;
865    }
866    switch (ev->detail) {
867    case XCB_NOTIFY_DETAIL_ANCESTOR:
868      e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
869      break;
870    case XCB_NOTIFY_DETAIL_VIRTUAL:
871      e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
872      break;
873    case XCB_NOTIFY_DETAIL_INFERIOR:
874      e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
875      break;
876    case XCB_NOTIFY_DETAIL_NONLINEAR:
877      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
878      break;
879    case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
880      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
881      break;
882    case XCB_NOTIFY_DETAIL_POINTER:
883      e->detail = ECORE_X_EVENT_DETAIL_POINTER;
884      break;
885    case XCB_NOTIFY_DETAIL_POINTER_ROOT:
886      e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
887      break;
888    case XCB_NOTIFY_DETAIL_NONE:
889      e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
890      break;
891    }
892    e->time = _ecore_xcb_event_last_time;
893    _ecore_xcb_event_last_time = e->time;
894    ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
895 }
896
897 void
898 _ecore_x_event_handle_keymap_notify(xcb_generic_event_t *event __UNUSED__)
899 {
900    /* FIXME: handle this event type */
901 }
902
903 void
904 _ecore_x_event_handle_expose(xcb_generic_event_t *event)
905 {
906    xcb_expose_event_t            *ev;
907    Ecore_X_Event_Window_Damage *e;
908
909    ev = (xcb_expose_event_t *)event,
910    e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
911    if (!e) return;
912    e->win = ev->window;
913    e->time = _ecore_xcb_event_last_time;
914    e->x = ev->x;
915    e->y = ev->y;
916    e->w = ev->width;
917    e->h = ev->height;
918    e->count = ev->count;
919    ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
920 }
921
922 void
923 _ecore_x_event_handle_graphics_expose(xcb_generic_event_t *event)
924 {
925    xcb_graphics_exposure_event_t *ev;
926    Ecore_X_Event_Window_Damage *e;
927
928    ev = (xcb_graphics_exposure_event_t *)event;
929    e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
930    if (!e) return;
931    e->win = ev->drawable;
932    e->time = _ecore_xcb_event_last_time;
933    e->x = ev->x;
934    e->y = ev->y;
935    e->w = ev->width;
936    e->h = ev->height;
937    e->count = ev->count;
938    ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
939 }
940
941 void
942 _ecore_x_event_handle_visibility_notify(xcb_generic_event_t *event)
943 {
944    xcb_visibility_notify_event_t *ev;
945
946    ev = (xcb_visibility_notify_event_t *)event;
947    if (ev->state != XCB_VISIBILITY_PARTIALLY_OBSCURED)
948    {
949       Ecore_X_Event_Window_Visibility_Change *e;
950
951       e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change));
952       if (!e) return;
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       ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
960    }
961 }
962
963 void
964 _ecore_x_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    ev = (xcb_create_notify_event_t *)event;
970    e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
971    if (!e) return;
972    e->win = ev->window;
973    if (ev->override_redirect)
974       e->override = 1;
975    else
976       e->override = 0;
977    e->time = _ecore_xcb_event_last_time;
978    ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
979 }
980
981 void
982 _ecore_x_event_handle_destroy_notify(xcb_generic_event_t *event)
983 {
984    xcb_destroy_notify_event_t     *ev;
985    Ecore_X_Event_Window_Destroy *e;
986
987    ev = (xcb_destroy_notify_event_t *)event;
988    e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy));
989    if (!e) return;
990    e->win =  ev->window;
991    e->time = _ecore_xcb_event_last_time;
992    if (e->win == _ecore_xcb_event_last_window) _ecore_xcb_event_last_window = 0;
993    ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
994 }
995
996 void
997 _ecore_x_event_handle_unmap_notify(xcb_generic_event_t *event)
998 {
999    xcb_unmap_notify_event_t    *ev;
1000    Ecore_X_Event_Window_Hide *e;
1001
1002    ev = (xcb_unmap_notify_event_t *)event;
1003    e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
1004    if (!e) return;
1005    e->win = ev->window;
1006    e->time = _ecore_xcb_event_last_time;
1007    ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
1008 }
1009
1010 void
1011 _ecore_x_event_handle_map_notify(xcb_generic_event_t *event)
1012 {
1013    xcb_map_notify_event_t      *ev;
1014    Ecore_X_Event_Window_Show *e;
1015
1016    ev = (xcb_map_notify_event_t *)event;
1017    e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
1018    if (!e) return;
1019    e->win = ev->window;
1020    e->time = _ecore_xcb_event_last_time;
1021    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
1022 }
1023
1024 void
1025 _ecore_x_event_handle_map_request(xcb_generic_event_t *event)
1026 {
1027    xcb_map_request_event_t             *ev;
1028    Ecore_X_Event_Window_Show_Request *e;
1029
1030    ev = (xcb_map_request_event_t *)event;
1031    e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
1032    if (!e) return;
1033    e->win = ev->window;
1034    e->parent = ev->parent;
1035    e->time = _ecore_xcb_event_last_time;
1036    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
1037 }
1038
1039 void
1040 _ecore_x_event_handle_reparent_notify(xcb_generic_event_t *event)
1041 {
1042    xcb_reparent_notify_event_t     *ev;
1043    Ecore_X_Event_Window_Reparent *e;
1044
1045    ev = (xcb_reparent_notify_event_t *)event;
1046    e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
1047    if (!e) return;
1048    e->win = ev->window;
1049    e->parent = ev->parent;
1050    e->time = _ecore_xcb_event_last_time;
1051    ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
1052 }
1053
1054 void
1055 _ecore_x_event_handle_configure_notify(xcb_generic_event_t *event)
1056 {
1057    xcb_configure_notify_event_t     *ev;
1058    Ecore_X_Event_Window_Configure *e;
1059
1060    ev = (xcb_configure_notify_event_t *)event;
1061    e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
1062    if (!e) return;
1063    e->win = ev->window;
1064    e->abovewin = ev->above_sibling;
1065    e->x = ev->x;
1066    e->y = ev->y;
1067    e->w = ev->width;
1068    e->h = ev->height;
1069    e->border = ev->border_width;
1070    e->override = ev->override_redirect;
1071    /* send_event is bit 7 (0x80) of response_type */
1072    e->from_wm = (ev->response_type & 0x80) ? 1 : 0;
1073    e->time = _ecore_xcb_event_last_time;
1074    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
1075 }
1076
1077 void
1078 _ecore_x_event_handle_configure_request(xcb_generic_event_t *event)
1079 {
1080    xcb_configure_request_event_t            *ev;
1081    Ecore_X_Event_Window_Configure_Request *e;
1082
1083    ev = (xcb_configure_request_event_t *)event;
1084    e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
1085    if (!e) return;
1086    e->win = ev->window;
1087    e->abovewin = ev->sibling;
1088    e->x = ev->x;
1089    e->y = ev->y;
1090    e->w = ev->width;
1091    e->h = ev->height;
1092    e->border = ev->border_width;
1093    e->value_mask = ev->value_mask;
1094    switch (ev->stack_mode) {
1095    case XCB_STACK_MODE_ABOVE:
1096      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1097      break;
1098    case XCB_STACK_MODE_BELOW:
1099      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1100      break;
1101    case XCB_STACK_MODE_TOP_IF:
1102      e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
1103      break;
1104    case XCB_STACK_MODE_BOTTOM_IF:
1105      e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
1106      break;
1107    case XCB_STACK_MODE_OPPOSITE:
1108      e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
1109      break;
1110    }
1111    e->time = _ecore_xcb_event_last_time;
1112    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
1113 }
1114
1115 void
1116 _ecore_x_event_handle_gravity_notify(xcb_generic_event_t *event __UNUSED__)
1117 {
1118    /* FIXME: handle this event type */
1119 }
1120
1121 void
1122 _ecore_x_event_handle_resize_request(xcb_generic_event_t *event)
1123 {
1124    xcb_resize_request_event_t            *ev;
1125    Ecore_X_Event_Window_Resize_Request *e;
1126
1127    ev = (xcb_resize_request_event_t *)event;
1128    e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
1129    if (!e) return;
1130    e->win = ev->window;
1131    e->w = ev->width;
1132    e->h = ev->height;
1133    e->time = _ecore_xcb_event_last_time;
1134    ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
1135 }
1136
1137 void
1138 _ecore_x_event_handle_circulate_notify(xcb_generic_event_t *event)
1139 {
1140    xcb_circulate_notify_event_t *ev;
1141    Ecore_X_Event_Window_Stack *e;
1142
1143    ev = (xcb_circulate_notify_event_t *)event;
1144    e = calloc(1, sizeof(Ecore_X_Event_Window_Stack));
1145    if (!e) return;
1146    e->win = ev->window;
1147    e->event_win = ev->event;
1148    if (ev->place == XCB_PLACE_ON_TOP)
1149      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1150    else
1151      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1152    e->time = _ecore_xcb_event_last_time;
1153    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
1154 }
1155
1156 void
1157 _ecore_x_event_handle_circulate_request(xcb_generic_event_t *event)
1158 {
1159    xcb_circulate_request_event_t        *ev;
1160    Ecore_X_Event_Window_Stack_Request *e;
1161
1162    ev = (xcb_circulate_request_event_t *)event;
1163    e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request));
1164    if (!e) return;
1165    e->win = ev->window;
1166    e->parent = ev->event;
1167    if (ev->place == XCB_PLACE_ON_TOP)
1168      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1169    else
1170      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1171    e->time = _ecore_xcb_event_last_time;
1172    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
1173 }
1174
1175 void
1176 _ecore_x_event_handle_property_notify(xcb_generic_event_t *event)
1177 {
1178 #if 0 /* for now i disabled this. nice idea though this is - it leaves a lot
1179        * to be desired for efficiency that is better left to the app layer
1180        */
1181    if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLASS)
1182      {
1183         Ecore_X_Event_Window_Prop_Name_Class_Change *e;
1184
1185         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Name_Class_Change));
1186         if (!e) return;
1187         ecore_x_window_prop_name_class_get(xevent->xproperty.window,
1188                                            &(e->name), &(e->clas));
1189    e->time = xevent->xproperty.time;
1190    _ecore_x_event_last_time = e->time;
1191         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE, e, _ecore_x_event_free_window_prop_name_class_change, NULL);
1192      }
1193    else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_NAME))
1194      {
1195         Ecore_X_Event_Window_Prop_Title_Change *e;
1196
1197         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Title_Change));
1198         if (!e) return;
1199         e->title = ecore_x_window_prop_title_get(xevent->xproperty.window);
1200    e->time = xevent->xproperty.time;
1201    _ecore_x_event_last_time = e->time;
1202         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_title_change, NULL);
1203      }
1204    else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_NAME)
1205      {
1206         Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
1207
1208         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Title_Change));
1209         if (!e) return;
1210         e->title = ecore_x_window_prop_visible_title_get(xevent->xproperty.window);
1211    e->time = xevent->xproperty.time;
1212    _ecore_x_event_last_time = e->time;
1213         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_visible_title_change, NULL);
1214      }
1215    else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_ICON_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_ICON_NAME))
1216      {
1217         Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
1218
1219         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Icon_Name_Change));
1220         if (!e) return;
1221         e->name = ecore_x_window_prop_icon_name_get(xevent->xproperty.window);
1222    e->time = xevent->xproperty.time;
1223    _ecore_x_event_last_time = e->time;
1224         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_icon_name_change, NULL);
1225      }
1226    else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME)
1227      {
1228         Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
1229
1230         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change));
1231         if (!e) return;
1232         e->name = ecore_x_window_prop_visible_icon_name_get(xevent->xproperty.window);
1233    e->time = xevent->xproperty.time;
1234    _ecore_x_event_last_time = e->time;
1235         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_visible_icon_name_change, NULL);
1236      }
1237    else if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
1238      {
1239         Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
1240
1241         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Client_Machine_Change));
1242         if (!e) return;
1243         e->name = ecore_x_window_prop_client_machine_get(xevent->xproperty.window);
1244    e->time = xevent->xproperty.time;
1245    _ecore_x_event_last_time = e->time;
1246         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE, e, _ecore_x_event_free_window_prop_client_machine_change, NULL);
1247      }
1248    else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_PID)
1249      {
1250         Ecore_X_Event_Window_Prop_Pid_Change *e;
1251
1252         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Pid_Change));
1253         if (!e) return;
1254         e->pid = ecore_x_window_prop_pid_get(xevent->xproperty.window);
1255    e->time = xevent->xproperty.time;
1256    _ecore_x_event_last_time = e->time;
1257         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
1258      }
1259    else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_DESKTOP)
1260      {
1261         Ecore_X_Event_Window_Prop_Desktop_Change *e;
1262
1263         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Desktop_Change));
1264         if (!e) return;
1265         e->desktop = ecore_x_window_prop_desktop_get(xevent->xproperty.window);
1266         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
1267      }
1268    else
1269 #endif
1270    {
1271       xcb_property_notify_event_t     *ev;
1272       Ecore_X_Event_Window_Property *e;
1273
1274       ev = (xcb_property_notify_event_t *)event;
1275       e = calloc(1,sizeof(Ecore_X_Event_Window_Property));
1276       if (!e) return;
1277       e->win = ev->window;
1278       e->atom = ev->atom;
1279       e->time = ev->time;
1280       _ecore_xcb_event_last_time = e->time;
1281       ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
1282    }
1283 }
1284
1285 void
1286 _ecore_x_event_handle_selection_clear(xcb_generic_event_t *event)
1287 {
1288    xcb_selection_clear_event_t     *ev;
1289    Ecore_X_Selection_Intern      *d;
1290    Ecore_X_Event_Selection_Clear *e;
1291    Ecore_X_Atom                   sel;
1292
1293    ev = (xcb_selection_clear_event_t *)event;
1294    if (!(d = _ecore_x_selection_get(ev->selection)))
1295      return;
1296    if (ev->time > d->time)
1297      {
1298         _ecore_x_selection_set(XCB_NONE, NULL, 0,
1299                                ev->selection);
1300      }
1301
1302    /* Generate event for app cleanup */
1303    e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
1304    e->win = ev->owner;
1305    e->time = ev->time;
1306    sel = ev->selection;
1307    if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
1308      e->selection = ECORE_X_SELECTION_PRIMARY;
1309    else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
1310      e->selection = ECORE_X_SELECTION_SECONDARY;
1311    else
1312      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1313    ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
1314
1315 }
1316
1317 void
1318 _ecore_x_event_handle_selection_request(xcb_generic_event_t *event)
1319 {
1320    xcb_selection_request_event_t *ev;
1321    Ecore_X_Selection_Intern    *sd;
1322    xcb_selection_notify_event_t   sn_event;
1323    void                          *data;
1324
1325    ev = (xcb_selection_request_event_t *)event;
1326    /* FIXME: is it the correct value ? */
1327    sn_event.response_type = XCB_SELECTION_NOTIFY;
1328    sn_event.pad0 = 0;
1329    /* FIXME: is it the correct value ? */
1330    sn_event.sequence = 0;
1331    sn_event.time = XCB_CURRENT_TIME;
1332    sn_event.requestor = ev->requestor;
1333    sn_event.selection = ev->selection;
1334    sn_event.target = ev->target;
1335
1336    if ((sd = _ecore_x_selection_get(ev->selection)) &&
1337        (sd->win == ev->owner))
1338      {
1339         if (!ecore_x_selection_convert(ev->selection, ev->target,
1340                                        &data))
1341           {
1342              /* Refuse selection, conversion to requested target failed */
1343              sn_event.property = XCB_NONE;
1344           }
1345         else
1346           {
1347              /* FIXME: This does not properly handle large data transfers */
1348              ecore_x_window_prop_property_set(ev->requestor,
1349                                               ev->property,
1350                                               ev->target,
1351                                               8, data, sd->length);
1352              sn_event.property = ev->property;
1353              free(data);
1354           }
1355      }
1356    else
1357      {
1358         sn_event.property = XCB_NONE;
1359         return;
1360      }
1361
1362    /* FIXME: I use _ecore_xcb_conn, as ev has no information on the connection */
1363    xcb_send_event(_ecore_xcb_conn, 0,
1364                   ev->requestor, 0, (const char *)&sn_event);
1365 }
1366
1367 /* FIXME: round trip */
1368 void
1369 _ecore_x_event_handle_selection_notify(xcb_generic_event_t *event)
1370 {
1371    xcb_selection_notify_event_t   *ev;
1372    Ecore_X_Event_Selection_Notify *e;
1373    unsigned char                 *data = NULL;
1374    Ecore_X_Atom                   selection;
1375    int                            num_ret;
1376    uint8_t                        format;
1377
1378    ev = (xcb_selection_notify_event_t *)event;
1379    selection = ev->selection;
1380
1381    if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS)
1382      {
1383         ecore_x_window_prop_property_get_prefetch(ev->requestor,
1384                                                   ev->property,
1385                                                   ECORE_X_ATOM_ATOM);
1386         ecore_x_window_prop_property_get_fetch();
1387         format = ecore_x_window_prop_property_get(ev->requestor,
1388                                                   ev->property,
1389                                                   ECORE_X_ATOM_ATOM,
1390                                                   32,
1391                                                   &data,
1392                                                   &num_ret);
1393         if (!format) return;
1394      }
1395    else
1396      {
1397         ecore_x_window_prop_property_get_prefetch(ev->requestor,
1398                                                   ev->property,
1399                                                   XCB_GET_PROPERTY_TYPE_ANY);
1400         ecore_x_window_prop_property_get_fetch();
1401         format = ecore_x_window_prop_property_get(ev->requestor,
1402                                                   ev->property,
1403                                                   ECORE_X_ATOM_ATOM,
1404                                                   8,
1405                                                   &data,
1406                                                   &num_ret);
1407         if (!format) return;
1408      }
1409
1410    e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
1411    if (!e) return;
1412    e->win = ev->requestor;
1413    e->time = ev->time;
1414    e->target = _ecore_x_selection_target_get(ev->target);
1415
1416    if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
1417      e->selection = ECORE_X_SELECTION_PRIMARY;
1418    else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
1419      e->selection = ECORE_X_SELECTION_SECONDARY;
1420    else if (selection == ECORE_X_ATOM_SELECTION_XDND)
1421      e->selection = ECORE_X_SELECTION_XDND;
1422    else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1423      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1424    else
1425      {
1426         free(e);
1427         return;
1428      }
1429    e->data = _ecore_x_selection_parse(e->target, data, num_ret, format);
1430
1431    ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, _ecore_x_event_free_selection_notify, NULL);
1432 }
1433
1434 void
1435 _ecore_x_event_handle_colormap_notify(xcb_generic_event_t *event)
1436 {
1437    xcb_colormap_notify_event_t     *ev;
1438    Ecore_X_Event_Window_Colormap *e;
1439
1440    ev = (xcb_colormap_notify_event_t *)event;
1441    e = calloc(1,sizeof(Ecore_X_Event_Window_Colormap));
1442    if (!e) return;
1443    e->win = ev->window;
1444    e->cmap = ev->colormap;
1445    if (ev->state == XCB_COLORMAP_STATE_INSTALLED)
1446       e->installed = 1;
1447    else
1448       e->installed = 0;
1449    e->time = _ecore_xcb_event_last_time;
1450    ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
1451 }
1452
1453 void
1454 _ecore_x_event_handle_client_message(xcb_generic_event_t *event)
1455 {
1456    /* Special client message event handling here. need to put LOTS of if */
1457    /* checks here and generate synthetic events per special message known */
1458    /* otherwise generate generic client message event. this would handle*/
1459    /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
1460
1461    xcb_client_message_event_t *ev;
1462
1463    ev = (xcb_client_message_event_t *)event;
1464    if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) &&
1465        (ev->format == 32) &&
1466        (ev->data.data32[0] == (uint32_t)ECORE_X_ATOM_WM_DELETE_WINDOW))
1467      {
1468         Ecore_X_Event_Window_Delete_Request *e;
1469
1470         e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request));
1471         if (!e) return;
1472         e->win = ev->window;
1473         e->time = _ecore_xcb_event_last_time;
1474         ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
1475      }
1476
1477    else if ((ev->type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
1478             (ev->format == 32) &&
1479             /* Ignore move and resize with keyboard */
1480             (ev->data.data32[2] < 9))
1481      {
1482         Ecore_X_Event_Window_Move_Resize_Request *e;
1483
1484         e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
1485         if (!e) return;
1486         e->win = ev->window;
1487         e->x = ev->data.data32[0];
1488         e->y = ev->data.data32[1];
1489         e->direction = ev->data.data32[2];
1490         e->button = ev->data.data32[3];
1491         e->source = ev->data.data32[4];
1492         ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
1493      }
1494
1495    /* Xdnd Client Message Handling Begin */
1496    /* Message Type: XdndEnter target */
1497    else if (ev->type == ECORE_X_ATOM_XDND_ENTER)
1498      {
1499         Ecore_X_Event_Xdnd_Enter *e;
1500         Ecore_X_DND_Target       *target;
1501         uint32_t                  three;
1502
1503         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
1504         if (!e) return;
1505
1506         target = _ecore_x_dnd_target_get();
1507         target->state = ECORE_X_DND_TARGET_ENTERED;
1508
1509         target = _ecore_x_dnd_target_get();
1510         target->source = ev->data.data32[0];
1511         target->win = ev->window;
1512         target->version = ev->data.data32[1] >> 24;
1513         if (target->version > ECORE_X_DND_VERSION)
1514           {
1515              printf("DND: Requested version %d, we only support up to %d\n", target->version,
1516                     ECORE_X_DND_VERSION);
1517              return;
1518           }
1519
1520         /* FIXME: roud trip, but I don't know how to suppress it */
1521         if ((three = ev->data.data32[1] & 0x1UL))
1522           {
1523              /* source supports more than 3 types, fetch property */
1524              unsigned char *data;
1525              Ecore_X_Atom  *types;
1526              int            num_ret;
1527              int            i;
1528              uint8_t        format;
1529
1530              ecore_x_window_prop_property_get_prefetch(target->source,
1531                                                        ECORE_X_ATOM_XDND_TYPE_LIST,
1532                                                        ECORE_X_ATOM_ATOM);
1533              ecore_x_window_prop_property_get_fetch();
1534              format = ecore_x_window_prop_property_get(target->source,
1535                                                        ECORE_X_ATOM_XDND_TYPE_LIST,
1536                                                        ECORE_X_ATOM_ATOM,
1537                                                        32,
1538                                                        &data,
1539                                                        &num_ret);
1540              if (!format)
1541                {
1542                   printf("DND: Could not fetch data type list from source window, aborting.\n");
1543                   return;
1544                }
1545              types = (Ecore_X_Atom *)data;
1546              e->types = calloc(num_ret, sizeof(char *));
1547              if (e->types)
1548                {
1549                   xcb_get_atom_name_cookie_t *cookies;
1550
1551                   cookies = (xcb_get_atom_name_cookie_t *)malloc(sizeof(xcb_get_atom_name_cookie_t) * num_ret);
1552                   for (i = 0; i < num_ret; i++)
1553                     cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, types[i]);
1554                   for (i = 0; i < num_ret; i++)
1555                     {
1556                        xcb_get_atom_name_reply_t *reply;
1557                        char                      *name;
1558
1559                        reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL);
1560                        if (reply)
1561                          {
1562                             name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1563                             memcpy(name,
1564                                    xcb_get_atom_name_name(reply),
1565                                    reply->name_len);
1566                             name[reply->name_len] = '\0';
1567                             e->types[i] = name;
1568                             free(reply);
1569                          }
1570                     }
1571                   free(cookies);
1572                }
1573              e->num_types = num_ret;
1574           }
1575         else
1576           {
1577              int i = 0;
1578
1579              e->types = calloc(3, sizeof(char *));
1580              if (e->types)
1581                {
1582                   xcb_get_atom_name_cookie_t cookies[3];
1583
1584                   for (i = 0; i < 3; i++)
1585                     cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[i + 2]);
1586                   for (i = 0; i < 3; i++)
1587                     {
1588                        xcb_get_atom_name_reply_t *reply;
1589                        char                      *name;
1590
1591                        reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL);
1592                        if (reply && (ev->data.data32[i + 2]))
1593                          {
1594                             name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1595                             memcpy(name,
1596                                    xcb_get_atom_name_name(reply),
1597                                    reply->name_len);
1598                             name[reply->name_len] = '\0';
1599                             e->types[i] = name;
1600                          }
1601                        if (reply) free(reply);
1602                     }
1603                }
1604              e->num_types = i;
1605           }
1606
1607         e->win = target->win;
1608         e->source = target->source;
1609         ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, _ecore_x_event_free_xdnd_enter, NULL);
1610      }
1611
1612    /* Message Type: XdndPosition target */
1613    else if (ev->type == ECORE_X_ATOM_XDND_POSITION)
1614      {
1615         Ecore_X_Event_Xdnd_Position *e;
1616         Ecore_X_DND_Target          *target;
1617
1618         target = _ecore_x_dnd_target_get();
1619         if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1620             (target->win != ev->window))
1621           return;
1622
1623         target->pos.x = (int16_t)ev->data.data32[2] >> 16;
1624         target->pos.y = (int16_t)ev->data.data32[2] & 0xFFFFUL;
1625         target->action = ev->data.data32[4]; /* Version 2 */
1626
1627         target->time = (target->version >= 1) ?
1628            ev->data.data32[3] : XCB_CURRENT_TIME;
1629
1630         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
1631         if (!e) return;
1632         e->win = target->win;
1633         e->source = target->source;
1634         e->position.x = target->pos.x;
1635         e->position.y = target->pos.y;
1636         e->action = target->action;
1637         ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
1638      }
1639
1640    /* Message Type: XdndStatus source */
1641    else if (ev->type == ECORE_X_ATOM_XDND_STATUS)
1642      {
1643         Ecore_X_Event_Xdnd_Status *e;
1644         Ecore_X_DND_Source        *source;
1645
1646         source = _ecore_x_dnd_source_get();
1647         /* Make sure source/target match */
1648         if ((source->win != ev->window ) ||
1649             (source->dest != ev->data.data32[0]))
1650           return;
1651
1652         source->await_status = 0;
1653
1654         source->will_accept = ev->data.data32[1] & 0x1UL;
1655         source->suppress = (ev->data.data32[1] & 0x2UL) ? 0 : 1;
1656
1657         source->rectangle.x = (int16_t)ev->data.data32[2] >> 16;
1658         source->rectangle.y = (int16_t)ev->data.data32[2] & 0xFFFFUL;
1659         source->rectangle.width = (uint16_t)ev->data.data32[3] >> 16;
1660         source->rectangle.height = (uint16_t)ev->data.data32[3] & 0xFFFFUL;
1661
1662         source->accepted_action = ev->data.data32[4];
1663
1664         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
1665         if (!e) return;
1666         e->win = source->win;
1667         e->target = source->dest;
1668         e->will_accept = source->will_accept;
1669         e->rectangle.x = source->rectangle.x;
1670         e->rectangle.y = source->rectangle.y;
1671         e->rectangle.width = source->rectangle.width;
1672         e->rectangle.height = source->rectangle.height;
1673         e->action = source->accepted_action;
1674
1675         ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
1676      }
1677
1678    /* Message Type: XdndLeave target */
1679    /* Pretend the whole thing never happened, sort of */
1680    else if (ev->type == ECORE_X_ATOM_XDND_LEAVE)
1681      {
1682         Ecore_X_Event_Xdnd_Leave *e;
1683         Ecore_X_DND_Target       *target;
1684
1685         target = _ecore_x_dnd_target_get();
1686         if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1687             (target->win != ev->window))
1688           return;
1689
1690         target->state = ECORE_X_DND_TARGET_IDLE;
1691
1692         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
1693         if (!e) return;
1694         e->win = ev->window;
1695         e->source = ev->data.data32[0];
1696         ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
1697      }
1698
1699    /* Message Type: XdndDrop target */
1700    else if (ev->type == ECORE_X_ATOM_XDND_DROP)
1701      {
1702         Ecore_X_Event_Xdnd_Drop *e;
1703         Ecore_X_DND_Target      *target;
1704
1705         target = _ecore_x_dnd_target_get();
1706         /* Match source/target */
1707         if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1708             (target->win != ev->window))
1709           return;
1710
1711         target->time = (target->version >= 1) ?
1712            ev->data.data32[2] : _ecore_xcb_event_last_time;
1713
1714         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
1715         if (!e) return;
1716         e->win = target->win;
1717         e->source = target->source;
1718         e->action = target->action;
1719         e->position.x = target->pos.x;
1720         e->position.y = target->pos.y;
1721         ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
1722      }
1723
1724    /* Message Type: XdndFinished source */
1725    else if (ev->type == ECORE_X_ATOM_XDND_FINISHED)
1726      {
1727         Ecore_X_Event_Xdnd_Finished *e;
1728         Ecore_X_DND_Source          *source;
1729         uint8_t                        completed = 1;
1730
1731         source = _ecore_x_dnd_source_get();
1732         /* Match source/target */
1733         if ((source->win != ev->window) ||
1734             (source->dest != ev->data.data32[0]))
1735           return;
1736
1737         if ((source->version >= 5) && (ev->data.data32[1] & 0x1UL))
1738           {
1739              /* Target successfully performed drop action */
1740              ecore_x_selection_xdnd_clear();
1741              source->state = ECORE_X_DND_SOURCE_IDLE;
1742           }
1743         else
1744           {
1745                completed = 0;
1746                source->state = ECORE_X_DND_SOURCE_CONVERTING;
1747
1748                /* FIXME: Probably need to add a timer to switch back to idle
1749                 * and discard the selection data */
1750           }
1751
1752         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished));
1753         if (!e) return;
1754         e->win = source->win;
1755         e->target = source->dest;
1756         e->completed = completed;
1757         if (source->version >= 5)
1758           {
1759              source->accepted_action = ev->data.data32[2];
1760              e->action = source->accepted_action;
1761           }
1762         else
1763           {
1764              source->accepted_action = 0;
1765              e->action = source->action;
1766           }
1767
1768         ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
1769      }
1770    else if (ev->type == ECORE_X_ATOM_NET_WM_STATE)
1771      {
1772         Ecore_X_Event_Window_State_Request *e;
1773
1774         e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1775         if (!e) return;
1776         e->win = ev->window;
1777         if (ev->data.data32[0] == 0)
1778           e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
1779         else if (ev->data.data32[0] == 1)
1780           e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1781         else if (ev->data.data32[0] == 2)
1782           e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
1783         else
1784           {
1785              free(e);
1786              return;
1787           }
1788         e->state[0] = _ecore_x_netwm_state_get(ev->data.data32[1]);
1789         if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
1790           {
1791              xcb_get_atom_name_reply_t *reply;
1792              char                      *name;
1793
1794              /* FIXME: round trip */
1795              reply = xcb_get_atom_name_reply(_ecore_xcb_conn,
1796                                              xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[1]),
1797                                              NULL);
1798              if (reply)
1799                {
1800                  name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1801                  memcpy(name,
1802                         xcb_get_atom_name_name(reply),
1803                         reply->name_len);
1804                  name[reply->name_len] = '\0';
1805                  printf("Unknown state: %s\n", name);
1806                  free(name);
1807                  free(reply);
1808                }
1809           }
1810         e->state[1] = _ecore_x_netwm_state_get(ev->data.data32[2]);
1811         if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
1812           {
1813              xcb_get_atom_name_reply_t *reply;
1814              char                      *name;
1815
1816              reply = xcb_get_atom_name_reply(_ecore_xcb_conn,
1817                                              xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[2]),
1818                                              NULL);
1819              if (reply)
1820                {
1821                  name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1822                  memcpy(name,
1823                         xcb_get_atom_name_name(reply),
1824                         reply->name_len);
1825                  name[reply->name_len] = '\0';
1826                  printf("Unknown state: %s\n", name);
1827                  free(name);
1828                }
1829           }
1830         e->source = ev->data.data32[3];
1831
1832         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1833      }
1834    else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE)
1835             && (ev->format == 32)
1836             && (ev->data.data32[0] == XCB_WM_ICONIC_STATE))
1837      {
1838         Ecore_X_Event_Window_State_Request *e;
1839
1840         e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1841         if (!e) return;
1842         e->win = ev->window;
1843         e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1844         e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
1845
1846         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1847      }
1848    else if ((ev->type == ECORE_X_ATOM_NET_WM_DESKTOP)
1849             && (ev->format == 32))
1850      {
1851         Ecore_X_Event_Desktop_Change *e;
1852
1853         e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
1854         if (!e) return;
1855         e->win = ev->window;
1856         e->desk = ev->data.data32[0];
1857         e->source = ev->data.data32[1];
1858
1859         ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
1860      }
1861    else if ((ev->type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS))
1862      {
1863         Ecore_X_Event_Frame_Extents_Request *e;
1864
1865         e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request));
1866         if (!e) return;
1867         e->win = ev->window;
1868
1869         ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
1870      }
1871    else if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS)
1872             && ((Ecore_X_Atom)ev->data.data32[0] == ECORE_X_ATOM_NET_WM_PING)
1873             && (ev->format == 32))
1874      {
1875         Ecore_X_Event_Ping *e;
1876
1877         e = calloc(1, sizeof(Ecore_X_Event_Ping));
1878         if (!e) return;
1879         e->win = ev->window;
1880         e->time = ev->data.data32[1];
1881         e->event_win = ev->data.data32[2];
1882
1883         ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
1884      }
1885    else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
1886             (ev->format == 8))
1887      {
1888         _ecore_x_netwm_startup_info_begin(ev->window, (char *)ev->data.data8);
1889      }
1890    else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO) &&
1891             (ev->format == 8))
1892      {
1893         _ecore_x_netwm_startup_info(ev->window, (char *)ev->data.data8);
1894      }
1895    else if ((ev->type == 27777)
1896             && (ev->data.data32[0] == 0x7162534)
1897             && (ev->format == 32)
1898             && (ev->window == _ecore_xcb_private_window))
1899      {
1900         /* a grab sync marker */
1901         if (ev->data.data32[1] == 0x10000001)
1902           _ecore_x_window_grab_remove(ev->data.data32[2]);
1903         else if (ev->data.data32[1] == 0x10000002)
1904           _ecore_x_key_grab_remove(ev->data.data32[2]);
1905      }
1906    else
1907      {
1908         Ecore_X_Event_Client_Message *e;
1909         int i;
1910
1911         e = calloc(1, sizeof(Ecore_X_Event_Client_Message));
1912         if (!e) return;
1913         e->win = ev->window;
1914         e->message_type = ev->type;
1915         e->format = ev->format;
1916         for (i = 0; i < 5; i++)
1917           e->data.l[i] = ev->data.data32[i];
1918
1919         ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
1920      }
1921 }
1922
1923 void
1924 _ecore_x_event_handle_mapping_notify(xcb_generic_event_t *event __UNUSED__)
1925 {
1926    /* FIXME: handle this event type */
1927 }
1928
1929 void
1930 _ecore_x_event_handle_shape_change(xcb_generic_event_t *event)
1931 {
1932 #ifdef ECORE_X_SHAPE
1933    xcb_shape_notify_event_t     *ev;
1934    Ecore_X_Event_Window_Shape *e;
1935
1936    ev = (xcb_shape_notify_event_t *)event;
1937    e = calloc(1, sizeof(Ecore_X_Event_Window_Shape));
1938    if (!e) return;
1939    e->win = ev->affected_window;
1940    e->time = ev->server_time;
1941    ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
1942 #else
1943    event = NULL;
1944 #endif /* ECORE_X_SHAPE */
1945 }
1946
1947 void
1948 _ecore_x_event_handle_screensaver_notify(xcb_generic_event_t *event)
1949 {
1950 #ifdef ECORE_X_SCREENSAVER
1951    xcb_screensaver_notify_event_t     *ev;
1952    Ecore_X_Event_Screensaver_Notify *e;
1953
1954    ev = (xcb_screensaver_notify_event_t *)event;
1955    e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify));
1956    if (!e) return;
1957    e->win = ev->window;
1958    if (ev->state == XCB_SCREENSAVER_STATE_ON)
1959      e->on = 1;
1960    else
1961      e->on = 0;
1962    e->time = ev->time;
1963    ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
1964 #else
1965    event = NULL;
1966 #endif /* ECORE_X_SCREENSAVER */
1967 }
1968
1969 void
1970 _ecore_x_event_handle_sync_counter(xcb_generic_event_t *event)
1971 {
1972 #ifdef ECORE_X_SYNC
1973    xcb_sync_counter_notify_event_t *ev;
1974    Ecore_X_Event_Sync_Counter    *e;
1975
1976    ev = (xcb_sync_counter_notify_event_t *)event;
1977    e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter));
1978    if (!e) return;
1979    e->time = ev->timestamp;
1980    ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
1981 #else
1982    event = NULL;
1983 #endif /* ECORE_X_SYNC */
1984 }
1985
1986 void
1987 _ecore_x_event_handle_sync_alarm(xcb_generic_event_t *event)
1988 {
1989 #ifdef ECORE_X_SYNC
1990    xcb_sync_alarm_notify_event_t *ev;
1991    Ecore_X_Event_Sync_Alarm    *e;
1992
1993    ev = (xcb_sync_alarm_notify_event_t *)event;
1994    e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm));
1995    if (!e) return;
1996    e->time = ev->timestamp;
1997    e->alarm = ev->alarm;
1998    ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
1999 #else
2000    event = NULL;
2001 #endif /* ECORE_X_SYNC */
2002 }
2003
2004 /* FIXME: round trip */
2005 void
2006 _ecore_x_event_handle_randr_change(xcb_generic_event_t *event)
2007 {
2008 #ifdef ECORE_X_RANDR
2009    xcb_randr_screen_change_notify_event_t *ev;
2010    Ecore_X_Event_Screen_Change            *e;
2011
2012    ev = (xcb_randr_screen_change_notify_event_t *)event;
2013
2014    if ((ev->response_type & ~0x80) != XCB_CONFIGURE_NOTIFY)
2015      {
2016        xcb_query_extension_reply_t *rep;
2017
2018        rep = xcb_query_extension_reply(_ecore_xcb_conn,
2019                                        xcb_query_extension_unchecked(_ecore_xcb_conn,
2020                                                                      strlen("randr"),
2021                                                                      "randr"),
2022                                        NULL);
2023
2024      if ((!rep) ||
2025          (((ev->response_type & ~0x80) - rep->first_event) != XCB_RANDR_SCREEN_CHANGE_NOTIFY))
2026        printf("ERROR: Can't update RandR config!\n");
2027      if (rep)
2028        free(rep);
2029      }
2030
2031    e = calloc(1, sizeof(Ecore_X_Event_Screen_Change));
2032    if (!e) return;
2033    e->win = ev->request_window;
2034    e->root = ev->root;
2035    e->width = ev->width;
2036    e->height = ev->height;
2037    ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
2038 #else
2039    event = NULL;
2040 #endif /* ECORE_X_RANDR */
2041 }
2042
2043 void
2044 _ecore_x_event_handle_fixes_selection_notify(xcb_generic_event_t *event)
2045 {
2046 #ifdef ECORE_X_FIXES
2047    /* Nothing here yet */
2048 #else
2049    event = NULL;
2050 #endif /* ECORE_X_FIXES */
2051 }
2052
2053 void
2054 _ecore_x_event_handle_damage_notify(xcb_generic_event_t *event)
2055 {
2056 #ifdef ECORE_XCBDAMAGE
2057    xcb_damage_notify_event_t *ev;
2058    Ecore_X_Event_Damage      *e;
2059
2060    ev = (xcb_damage_notify_event_t *)event;
2061    e = calloc(1, sizeof(Ecore_X_Event_Damage));
2062    if (!e) return;
2063
2064    e->level = ev->level;
2065    e->drawable = ev->drawable;
2066    e->damage = ev->damage;
2067    /* FIXME: XCB has no 'more' member in xcb_damage_notify_event_t */
2068 /*    e->more = ev->more; */
2069    e->time = ev->timestamp;
2070    e->area.x = ev->area.x;
2071    e->area.y = ev->area.y;
2072    e->area.width = ev->area.width;
2073    e->area.height = ev->area.height;
2074    e->geometry.x = ev->geometry.x;
2075    e->geometry.y = ev->geometry.y;
2076    e->geometry.width = ev->geometry.width;
2077    e->geometry.height = ev->geometry.height;
2078
2079    ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
2080 #else
2081    event = NULL;
2082 #endif /* ECORE_XCBDAMAGE */
2083 }