Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore_x / xlib / ecore_x_events.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif /* ifdef HAVE_CONFIG_H */
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8
9 #include <langinfo.h>
10
11 #include "Ecore.h"
12 #include "ecore_private.h"
13 #include "ecore_x_private.h"
14 #include "Ecore_X.h"
15 #include "Ecore_X_Atoms.h"
16
17 /** OpenBSD does not define CODESET
18  * FIXME ??
19  */
20
21 #ifndef CODESET
22 #define CODESET "INVALID"
23 #endif /* ifndef CODESET */
24
25 typedef struct _Ecore_X_Mouse_Down_Info
26 {
27    EINA_INLIST;
28    int       dev;
29    Window    last_win;
30    Window    last_last_win;
31    Window    last_event_win;
32    Window    last_last_event_win;
33    Time      last_time;
34    Time      last_last_time;
35    Eina_Bool did_double : 1;
36    Eina_Bool did_triple : 1;
37 } Ecore_X_Mouse_Down_Info;
38
39 static int _ecore_x_last_event_mouse_move = 0;
40 static Ecore_Event *_ecore_x_last_event_mouse_move_event = NULL;
41 static Eina_Inlist *_ecore_x_mouse_down_info_list = NULL;
42
43 static void
44 _ecore_x_mouse_down_info_clear(void)
45 {
46    Eina_Inlist *l = _ecore_x_mouse_down_info_list;
47    Ecore_X_Mouse_Down_Info *info = NULL;
48    while (l)
49      {
50         info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info);
51         l = eina_inlist_remove(l, l);
52         free(info);
53      }
54    _ecore_x_mouse_down_info_list = NULL;
55 }
56
57 void
58 _ecore_x_events_init(void)
59 {
60    //Actually, Nothing to do.
61 }
62
63 void
64 _ecore_x_events_shutdown(void)
65 {
66    _ecore_x_mouse_down_info_clear();
67 }
68
69 static Ecore_X_Mouse_Down_Info *
70 _ecore_x_mouse_down_info_get(int dev)
71 {
72    Eina_Inlist *l = _ecore_x_mouse_down_info_list;
73    Ecore_X_Mouse_Down_Info *info = NULL;
74
75    //Return the exist info
76    EINA_INLIST_FOREACH(l, info)
77      if (info->dev == dev) return info;
78
79    //New Device. Add it.
80    info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info));
81    if (!info) return NULL;
82
83    info->dev = dev;
84    l = eina_inlist_append(l, (Eina_Inlist *)info);
85    _ecore_x_mouse_down_info_list = l;
86    return info;
87 }
88
89 static void
90 _ecore_x_event_free_mouse_move(void *data __UNUSED__,
91                                void *ev)
92 {
93    Ecore_Event_Mouse_Move *e;
94
95    e = ev;
96    if (_ecore_x_last_event_mouse_move)
97      {
98         _ecore_x_last_event_mouse_move_event = NULL;
99         _ecore_x_last_event_mouse_move = 0;
100      }
101
102    free(e);
103 }
104
105 EAPI void
106 ecore_x_event_mask_set(Ecore_X_Window w,
107                        Ecore_X_Event_Mask mask)
108 {
109    XWindowAttributes attr;
110    XSetWindowAttributes s_attr;
111
112    LOGFN(__FILE__, __LINE__, __FUNCTION__);
113    if (!w)
114      w = DefaultRootWindow(_ecore_x_disp);
115
116    memset(&attr, 0, sizeof(XWindowAttributes));
117    XGetWindowAttributes(_ecore_x_disp, w, &attr);
118    s_attr.event_mask = mask | attr.your_event_mask;
119    XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
120 }
121
122 EAPI void
123 ecore_x_event_mask_unset(Ecore_X_Window w,
124                          Ecore_X_Event_Mask mask)
125 {
126    XWindowAttributes attr;
127    XSetWindowAttributes s_attr;
128
129    LOGFN(__FILE__, __LINE__, __FUNCTION__);
130    if (!w)
131      w = DefaultRootWindow(_ecore_x_disp);
132
133    memset(&attr, 0, sizeof(XWindowAttributes));
134    XGetWindowAttributes(_ecore_x_disp, w, &attr);
135    s_attr.event_mask = attr.your_event_mask & ~mask;
136    XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
137 }
138
139 static void
140 _ecore_x_event_free_xdnd_enter(void *data __UNUSED__,
141                                void *ev)
142 {
143    Ecore_X_Event_Xdnd_Enter *e;
144    int i;
145
146    e = ev;
147    for (i = 0; i < e->num_types; i++)
148      XFree(e->types[i]);
149    free(e->types);
150    free(e);
151 }
152
153 static void
154 _ecore_x_event_free_selection_notify(void *data __UNUSED__,
155                                      void *ev)
156 {
157    Ecore_X_Event_Selection_Notify *e;
158    Ecore_X_Selection_Data *sel;
159
160    e = ev;
161    sel = e->data;
162    if (sel->free)
163      sel->free(sel);
164
165    free(e->target);
166    free(e);
167 }
168
169 static unsigned int
170 _ecore_x_event_modifiers(unsigned int state)
171 {
172    unsigned int modifiers = 0;
173
174    if (state & ECORE_X_MODIFIER_SHIFT)
175      modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
176
177    if (state & ECORE_X_MODIFIER_CTRL)
178      modifiers |= ECORE_EVENT_MODIFIER_CTRL;
179
180    if (state & ECORE_X_MODIFIER_ALT)
181      modifiers |= ECORE_EVENT_MODIFIER_ALT;
182
183    if (state & ECORE_X_MODIFIER_WIN)
184      modifiers |= ECORE_EVENT_MODIFIER_WIN;
185
186    if (state & ECORE_X_MODIFIER_ALTGR)
187      modifiers |= ECORE_EVENT_MODIFIER_ALTGR;
188
189    if (state & ECORE_X_LOCK_SCROLL)
190      modifiers |= ECORE_EVENT_LOCK_SCROLL;
191
192    if (state & ECORE_X_LOCK_NUM)
193      modifiers |= ECORE_EVENT_LOCK_NUM;
194
195    if (state & ECORE_X_LOCK_CAPS)
196      modifiers |= ECORE_EVENT_LOCK_CAPS;
197
198    if (state & ECORE_X_LOCK_SHIFT)
199      modifiers |= ECORE_EVENT_LOCK_SHIFT;
200
201    return modifiers;
202 }
203
204 void
205 _ecore_mouse_move(unsigned int timestamp,
206                   unsigned int xmodifiers,
207                   int x,
208                   int y,
209                   int x_root,
210                   int y_root,
211                   unsigned int event_window,
212                   unsigned int window,
213                   unsigned int root_win,
214                   int same_screen,
215                   int dev,
216                   double radx,
217                   double rady,
218                   double pressure,
219                   double angle,
220                   double mx,
221                   double my,
222                   double mrx,
223                   double mry)
224 {
225    Ecore_Event_Mouse_Move *e;
226    Ecore_Event *event;
227
228    e = malloc(sizeof(Ecore_Event_Mouse_Move));
229    if (!e)
230      return;
231
232    e->window = window;
233    e->root_window = root_win;
234    e->timestamp = timestamp;
235    e->same_screen = same_screen;
236    e->event_window = event_window;
237
238    e->modifiers = _ecore_x_event_modifiers(xmodifiers);
239    e->x = x;
240    e->y = y;
241    e->root.x = x_root;
242    e->root.y = y_root;
243
244    e->multi.device = dev;
245    e->multi.radius = (radx + rady) / 2;
246    e->multi.radius_x = radx;
247    e->multi.radius_y = rady;
248    e->multi.pressure = pressure;
249    e->multi.angle = angle;
250    e->multi.x = mx;
251    e->multi.y = my;
252    e->multi.root.x = mrx;
253    e->multi.root.y = mry;
254
255    event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE,
256                            e,
257                            _ecore_x_event_free_mouse_move,
258                            NULL);
259
260    _ecore_x_event_last_time = timestamp;
261    _ecore_x_event_last_win = window;
262    _ecore_x_event_last_root_x = x_root;
263    _ecore_x_event_last_root_y = y_root;
264
265    _ecore_x_last_event_mouse_move_event = event;
266 }
267
268 static void
269 _ecore_key_press(int event,
270                  XKeyEvent *xevent)
271 {
272    Ecore_Event_Key *e;
273    char *compose = NULL;
274    char *tmp = NULL;
275    char *keyname;
276    char *key;
277    char keyname_buffer[256];
278    char compose_buffer[256];
279    KeySym sym;
280    XComposeStatus status;
281    int val;
282
283    _ecore_x_last_event_mouse_move = 0;
284    keyname = XKeysymToString(_ecore_x_XKeycodeToKeysym(xevent->display,
285                                                        xevent->keycode, 0));
286    if (!keyname)
287      {
288         snprintf(keyname_buffer,
289                  sizeof(keyname_buffer),
290                  "Keycode-%i",
291                  xevent->keycode);
292         keyname = keyname_buffer;
293      }
294
295    sym = 0;
296    key = NULL;
297    compose = NULL;
298    val = XLookupString(xevent,
299                        compose_buffer,
300                        sizeof(compose_buffer),
301                        &sym,
302                        &status);
303    if (val > 0)
304      {
305         compose_buffer[val] = 0;
306         compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8",
307                                    compose_buffer);
308         if (!compose)
309           ERR("Ecore_X cannot convert input key string '%s' to UTF-8. "
310               "Is Eina built with iconv support?", compose_buffer);
311         tmp = compose;
312      }
313
314    key = XKeysymToString(sym);
315    if (!key)
316      key = keyname;
317
318    e =
319      malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) +
320             (compose ? strlen(compose) : 0) + 3);
321    if (!e)
322      goto on_error;
323
324    e->keyname = (char *)(e + 1);
325    e->key = e->keyname + strlen(keyname) + 1;
326    e->compose = (compose) ? e->key + strlen(key) + 1 : NULL;
327    e->string = e->compose;
328
329    strcpy((char *)e->keyname, keyname);
330    strcpy((char *)e->key, key);
331    if (compose)
332      strcpy((char *)e->compose, compose);
333
334    e->modifiers = _ecore_x_event_modifiers(xevent->state);
335
336    e->timestamp = xevent->time;
337    e->window = xevent->subwindow ? xevent->subwindow : xevent->window;
338    e->event_window = xevent->window;
339    e->same_screen = xevent->same_screen;
340    e->root_window = xevent->root;
341
342    ecore_event_add(event, e, NULL, NULL);
343
344    _ecore_x_event_last_time = e->timestamp;
345
346 on_error:
347    if (tmp)
348      free(tmp);
349 }
350
351 Ecore_Event_Mouse_Button *
352 _ecore_mouse_button(int event,
353                     unsigned int timestamp,
354                     unsigned int xmodifiers,
355                     unsigned int buttons,
356                     int x,
357                     int y,
358                     int x_root,
359                     int y_root,
360                     unsigned int event_window,
361                     unsigned int window,
362                     unsigned int root_win,
363                     int same_screen,
364                     int dev,
365                     double radx,
366                     double rady,
367                     double pressure,
368                     double angle,
369                     double mx,
370                     double my,
371                     double mrx,
372                     double mry)
373 {
374    Ecore_Event_Mouse_Button *e;
375
376    e = malloc(sizeof(Ecore_Event_Mouse_Button));
377    if (!e)
378      return NULL;
379
380    e->window = window;
381    e->root_window = root_win;
382    e->timestamp = timestamp;
383    e->same_screen = same_screen;
384    e->event_window = event_window;
385
386    e->buttons = buttons;
387    e->modifiers = _ecore_x_event_modifiers(xmodifiers);
388    e->double_click = 0;
389    e->triple_click = 0;
390    e->x = x;
391    e->y = y;
392    e->root.x = x_root;
393    e->root.y = y_root;
394
395    Ecore_X_Mouse_Down_Info *down_info = _ecore_x_mouse_down_info_get(dev);
396
397    if (down_info)
398      {
399         if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
400             down_info->did_triple)
401           {
402              down_info->last_win = 0;
403              down_info->last_last_win = 0;
404              down_info->last_event_win = 0;
405              down_info->last_last_event_win = 0;
406              down_info->last_time = 0;
407              down_info->last_last_time = 0;
408           }
409         if (event_window == window)
410           {
411              if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN)
412                {
413                   //Check Double Clicked
414                   if (((int)(timestamp - down_info->last_time) <=
415                        (int)(1000 * _ecore_x_double_click_time)) &&
416                       (window == down_info->last_win) &&
417                       (event_window == down_info->last_event_win))
418                     {
419                        e->double_click = 1;
420                        down_info->did_double = EINA_TRUE;
421                     }
422                   else
423                     {
424                        down_info->did_double = EINA_FALSE;
425                        down_info->did_triple = EINA_FALSE;
426                     }
427
428                   //Check Triple Clicked
429                   if (((int)(timestamp - down_info->last_last_time) <=
430                        (int)(2 * 1000 * _ecore_x_double_click_time)) &&
431                       (window == down_info->last_win) &&
432                       (window == down_info->last_last_win) &&
433                       (event_window == down_info->last_event_win) &&
434                       (event_window == down_info->last_last_event_win)
435                       )
436                     {
437                        e->triple_click = 1;
438                        down_info->did_triple = EINA_TRUE;
439                     }
440                   else
441                     {
442                        down_info->did_triple = EINA_FALSE;
443                     }
444                }
445              else
446                {
447                   if (down_info->did_double)
448                     e->double_click = 1;
449                   if (down_info->did_triple)
450                     e->triple_click = 1;
451                }
452           }
453      }
454
455    /* NB: Block commented out as _ecore_x_mouse_up_count appears to have
456     * no use. The variable is also commented out above. This code block is
457     * the only place that this variable is used, and appears to serve no
458     * purpose. - dh
459       if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN
460        && !e->double_click
461        && !e->triple_click)
462       _ecore_x_mouse_up_count = 0;
463     */
464
465    e->multi.device = dev;
466    e->multi.radius = (radx + rady) / 2;
467    e->multi.radius_x = radx;
468    e->multi.radius_y = rady;
469    e->multi.pressure = pressure;
470    e->multi.angle = angle;
471    e->multi.x = mx;
472    e->multi.y = my;
473    e->multi.root.x = mrx;
474    e->multi.root.y = mry;
475
476    _ecore_x_event_last_time = e->timestamp;
477    _ecore_x_event_last_win = e->window;
478    _ecore_x_event_last_root_x = x_root;
479    _ecore_x_event_last_root_y = y_root;
480
481    ecore_event_add(event, e, NULL, NULL);
482
483    if ((down_info) &&
484        (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
485        (window == event_window) &&
486        (!down_info->did_triple))
487      {
488         down_info->last_last_win = down_info->last_win;
489         down_info->last_win = window;
490         down_info->last_last_event_win = down_info->last_event_win;
491         down_info->last_event_win = event_window;
492         down_info->last_last_time = down_info->last_time;
493         down_info->last_time = timestamp;
494      }
495
496    return e;
497 }
498
499 void
500 _ecore_x_event_handle_any_event(XEvent *xevent)
501 {
502    XEvent *ev = malloc(sizeof(XEvent));
503    if (!ev) return;
504    memcpy(ev, xevent, sizeof(XEvent));
505    ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL);
506 }
507
508 void
509 _ecore_x_event_handle_key_press(XEvent *xevent)
510 {
511    _ecore_key_press(ECORE_EVENT_KEY_DOWN, (XKeyEvent *)xevent);
512 }
513
514 void
515 _ecore_x_event_handle_key_release(XEvent *xevent)
516 {
517    _ecore_key_press(ECORE_EVENT_KEY_UP, (XKeyEvent *)xevent);
518 }
519
520 void
521 _ecore_x_event_handle_button_press(XEvent *xevent)
522 {
523    int i;
524
525    _ecore_x_last_event_mouse_move = 0;
526    if ((xevent->xbutton.button > 3) && (xevent->xbutton.button < 8))
527      {
528         Ecore_Event_Mouse_Wheel *e;
529
530         e = malloc(sizeof(Ecore_Event_Mouse_Wheel));
531         if (!e)
532           return;
533
534         e->timestamp = xevent->xbutton.time;
535         e->modifiers = _ecore_x_event_modifiers(xevent->xbutton.state);
536         switch (xevent->xbutton.button)
537           {
538            case 4: e->direction = 0; e->z = -1; break;
539
540            case 5: e->direction = 0; e->z = 1; break;
541
542            case 6: e->direction = 1; e->z = -1; break;
543
544            case 7: e->direction = 1; e->z = 1; break;
545
546            default: e->direction = 0; e->z = 0; break;
547           }
548
549         e->x = xevent->xbutton.x;
550         e->y = xevent->xbutton.y;
551         e->root.x = xevent->xbutton.x_root;
552         e->root.y = xevent->xbutton.y_root;
553
554         if (xevent->xbutton.subwindow)
555           e->window = xevent->xbutton.subwindow;
556         else
557           e->window = xevent->xbutton.window;
558
559         e->event_window = xevent->xbutton.window;
560         e->same_screen = xevent->xbutton.same_screen;
561         e->root_window = xevent->xbutton.root;
562
563         _ecore_x_event_last_time = e->timestamp;
564         _ecore_x_event_last_win = e->window;
565         _ecore_x_event_last_root_x = xevent->xbutton.x_root;
566         _ecore_x_event_last_root_y = xevent->xbutton.y_root;
567         ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
568
569         for (i = 0; i < _ecore_window_grabs_num; i++)
570           {
571              if ((_ecore_window_grabs[i] == xevent->xbutton.window) ||
572                  (_ecore_window_grabs[i] == xevent->xbutton.subwindow))
573                {
574                   Eina_Bool replay = EINA_FALSE;
575
576                   if (_ecore_window_grab_replay_func)
577                     replay = _ecore_window_grab_replay_func(
578                         _ecore_window_grab_replay_data,
579                         ECORE_EVENT_MOUSE_WHEEL,
580                         e);
581
582                   if (replay)
583                     XAllowEvents(xevent->xbutton.display,
584                                  ReplayPointer, xevent->xbutton.time);
585                   else
586                     XAllowEvents(xevent->xbutton.display,
587                                  AsyncPointer, xevent->xbutton.time);
588
589                   break;
590                }
591           }
592      }
593    else
594      {
595         {
596            _ecore_mouse_move(xevent->xbutton.time, xevent->xbutton.state,
597                              xevent->xbutton.x, xevent->xbutton.y,
598                              xevent->xbutton.x_root, xevent->xbutton.y_root,
599                              xevent->xbutton.window,
600                              (xevent->xbutton.subwindow ? xevent->xbutton.
601                               subwindow : xevent->xbutton.window),
602                              xevent->xbutton.root,
603                              xevent->xbutton.same_screen,
604                              0, 1, 1,
605                              1.0, // pressure
606                              0.0, // angle
607                              xevent->xbutton.x, xevent->xbutton.y,
608                              xevent->xbutton.x_root, xevent->xbutton.y_root);
609         }
610         {
611            Ecore_Event_Mouse_Button *e;
612            int event_window;
613            int window;
614
615            window =
616              (xevent->xbutton.subwindow ? xevent->xbutton.subwindow : xevent->
617               xbutton.window);
618            event_window = xevent->xbutton.window;
619
620            e = _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN,
621                                    xevent->xbutton.time,
622                                    xevent->xbutton.state,
623                                    xevent->xbutton.button,
624                                    xevent->xbutton.x,
625                                    xevent->xbutton.y,
626                                    xevent->xbutton.x_root,
627                                    xevent->xbutton.y_root,
628                                    event_window,
629                                    window,
630                                    xevent->xbutton.root,
631                                    xevent->xbutton.same_screen,
632                                    0,
633                                    1,
634                                    1,
635                                    1.0,
636 // pressure
637                                    0.0,
638 // angle
639                                    xevent->xbutton.x,
640                                    xevent->xbutton.y,
641                                    xevent->xbutton.x_root,
642                                    xevent->xbutton.y_root);
643            if (e)
644              for (i = 0; i < _ecore_window_grabs_num; i++)
645                {
646                   if ((_ecore_window_grabs[i] == xevent->xbutton.window) ||
647                       (_ecore_window_grabs[i] == xevent->xbutton.subwindow))
648                     {
649                        Eina_Bool replay = EINA_FALSE;
650
651                        if (_ecore_window_grab_replay_func)
652                          replay = _ecore_window_grab_replay_func(
653                              _ecore_window_grab_replay_data,
654                              ECORE_EVENT_MOUSE_BUTTON_DOWN,
655                              e);
656
657                        if (replay)
658                          XAllowEvents(xevent->xbutton.display,
659                                       ReplayPointer, xevent->xbutton.time);
660                        else
661                          XAllowEvents(xevent->xbutton.display,
662                                       AsyncPointer, xevent->xbutton.time);
663
664                        break;
665                     }
666                }
667         }
668      }
669 }
670
671 void
672 _ecore_x_event_handle_button_release(XEvent *xevent)
673 {
674    _ecore_x_last_event_mouse_move = 0;
675    /* filter out wheel buttons */
676    if ((xevent->xbutton.button <= 3) || (xevent->xbutton.button > 7))
677      {
678         _ecore_mouse_move(xevent->xbutton.time, xevent->xbutton.state,
679                           xevent->xbutton.x, xevent->xbutton.y,
680                           xevent->xbutton.x_root, xevent->xbutton.y_root,
681                           xevent->xbutton.window,
682                           (xevent->xbutton.subwindow ? xevent->xbutton.
683                            subwindow : xevent->xbutton.window),
684                           xevent->xbutton.root,
685                           xevent->xbutton.same_screen,
686                           0, 1, 1,
687                           1.0, // pressure
688                           0.0, // angle
689                           xevent->xbutton.x, xevent->xbutton.y,
690                           xevent->xbutton.x_root, xevent->xbutton.y_root);
691
692         _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP,
693                             xevent->xbutton.time, xevent->xbutton.state,
694                             xevent->xbutton.button,
695                             xevent->xbutton.x, xevent->xbutton.y,
696                             xevent->xbutton.x_root, xevent->xbutton.y_root,
697                             xevent->xbutton.window,
698                             (xevent->xbutton.subwindow ? xevent->xbutton.
699                              subwindow : xevent->xbutton.window),
700                             xevent->xbutton.root,
701                             xevent->xbutton.same_screen,
702                             0, 1, 1,
703                             1.0, // pressure
704                             0.0, // angle
705                             xevent->xbutton.x, xevent->xbutton.y,
706                             xevent->xbutton.x_root, xevent->xbutton.y_root);
707      }
708 }
709
710 void
711 _ecore_x_event_handle_motion_notify(XEvent *xevent)
712 {
713 /*
714    if (_ecore_x_last_event_mouse_move)
715      {
716         ecore_event_del(_ecore_x_last_event_mouse_move_event);
717         _ecore_x_last_event_mouse_move = 0;
718         _ecore_x_last_event_mouse_move_event = NULL;
719      }
720  */
721    _ecore_mouse_move(xevent->xmotion.time, xevent->xmotion.state,
722                      xevent->xmotion.x, xevent->xmotion.y,
723                      xevent->xmotion.x_root, xevent->xmotion.y_root,
724                      xevent->xmotion.window,
725                      (xevent->xmotion.subwindow ? xevent->xmotion.subwindow :
726                       xevent->xmotion.window),
727                      xevent->xmotion.root,
728                      xevent->xmotion.same_screen,
729                      0, 1, 1,
730                      1.0,   // pressure
731                      0.0,   // angle
732                      xevent->xmotion.x, xevent->xmotion.y,
733                      xevent->xmotion.x_root, xevent->xmotion.y_root);
734
735    _ecore_x_last_event_mouse_move = 1;
736
737    /* Xdnd handling */
738    _ecore_x_dnd_drag(xevent->xmotion.root,
739                      xevent->xmotion.x_root,
740                      xevent->xmotion.y_root);
741 }
742
743 void
744 _ecore_x_event_handle_enter_notify(XEvent *xevent)
745 {
746    _ecore_x_last_event_mouse_move = 0;
747    {
748       _ecore_mouse_move(xevent->xcrossing.time, xevent->xcrossing.state,
749                         xevent->xcrossing.x, xevent->xcrossing.y,
750                         xevent->xcrossing.x_root, xevent->xcrossing.y_root,
751                         xevent->xcrossing.window,
752                         (xevent->xcrossing.subwindow ? xevent->xcrossing.
753                          subwindow : xevent->xcrossing.window),
754                         xevent->xcrossing.root,
755                         xevent->xcrossing.same_screen,
756                         0, 1, 1,
757                         1.0, // pressure
758                         0.0, // angle
759                         xevent->xcrossing.x, xevent->xcrossing.y,
760                         xevent->xcrossing.x_root, xevent->xcrossing.y_root);
761    }
762    {
763       Ecore_X_Event_Mouse_In *e;
764
765       e = calloc(1, sizeof(Ecore_X_Event_Mouse_In));
766       if (!e)
767         return;
768
769       e->modifiers = _ecore_x_event_modifiers(xevent->xcrossing.state);
770       e->x = xevent->xcrossing.x;
771       e->y = xevent->xcrossing.y;
772       e->root.x = xevent->xcrossing.x_root;
773       e->root.y = xevent->xcrossing.y_root;
774       if (xevent->xcrossing.subwindow)
775         e->win = xevent->xcrossing.subwindow;
776       else
777         e->win = xevent->xcrossing.window;
778
779       e->same_screen = xevent->xcrossing.same_screen;
780       e->root_win = xevent->xcrossing.root;
781       e->event_win = xevent->xcrossing.window;
782
783       if (xevent->xcrossing.mode == NotifyNormal)
784         e->mode = ECORE_X_EVENT_MODE_NORMAL;
785       else if (xevent->xcrossing.mode == NotifyGrab)
786         e->mode = ECORE_X_EVENT_MODE_GRAB;
787       else if (xevent->xcrossing.mode == NotifyUngrab)
788         e->mode = ECORE_X_EVENT_MODE_UNGRAB;
789
790       if (xevent->xcrossing.detail == NotifyAncestor)
791         e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
792       else if (xevent->xcrossing.detail == NotifyVirtual)
793         e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
794       else if (xevent->xcrossing.detail == NotifyInferior)
795         e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
796       else if (xevent->xcrossing.detail == NotifyNonlinear)
797         e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
798       else if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
799         e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
800
801       e->time = xevent->xcrossing.time;
802       _ecore_x_event_last_time = e->time;
803       ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
804    }
805 }
806
807 void
808 _ecore_x_event_handle_leave_notify(XEvent *xevent)
809 {
810    _ecore_x_last_event_mouse_move = 0;
811    {
812       _ecore_mouse_move(xevent->xcrossing.time, xevent->xcrossing.state,
813                         xevent->xcrossing.x, xevent->xcrossing.y,
814                         xevent->xcrossing.x_root, xevent->xcrossing.y_root,
815                         xevent->xcrossing.window,
816                         (xevent->xcrossing.subwindow ? xevent->xcrossing.
817                          subwindow : xevent->xcrossing.window),
818                         xevent->xcrossing.root,
819                         xevent->xcrossing.same_screen,
820                         0, 1, 1,
821                         1.0, // pressure
822                         0.0, // angle
823                         xevent->xcrossing.x, xevent->xcrossing.y,
824                         xevent->xcrossing.x_root, xevent->xcrossing.y_root);
825    }
826    {
827       Ecore_X_Event_Mouse_Out *e;
828
829       e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out));
830       if (!e)
831         return;
832
833       e->modifiers = _ecore_x_event_modifiers(xevent->xcrossing.state);
834       e->x = xevent->xcrossing.x;
835       e->y = xevent->xcrossing.y;
836       e->root.x = xevent->xcrossing.x_root;
837       e->root.y = xevent->xcrossing.y_root;
838       if (xevent->xcrossing.subwindow)
839         e->win = xevent->xcrossing.subwindow;
840       else
841         e->win = xevent->xcrossing.window;
842
843       e->same_screen = xevent->xcrossing.same_screen;
844       e->root_win = xevent->xcrossing.root;
845       e->event_win = xevent->xcrossing.window;
846
847       if (xevent->xcrossing.mode == NotifyNormal)
848         e->mode = ECORE_X_EVENT_MODE_NORMAL;
849       else if (xevent->xcrossing.mode == NotifyGrab)
850         e->mode = ECORE_X_EVENT_MODE_GRAB;
851       else if (xevent->xcrossing.mode == NotifyUngrab)
852         e->mode = ECORE_X_EVENT_MODE_UNGRAB;
853
854       if (xevent->xcrossing.detail == NotifyAncestor)
855         e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
856       else if (xevent->xcrossing.detail == NotifyVirtual)
857         e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
858       else if (xevent->xcrossing.detail == NotifyInferior)
859         e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
860       else if (xevent->xcrossing.detail == NotifyNonlinear)
861         e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
862       else if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
863         e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
864
865       e->time = xevent->xcrossing.time;
866       _ecore_x_event_last_time = e->time;
867       _ecore_x_event_last_win = e->win;
868       _ecore_x_event_last_root_x = e->root.x;
869       _ecore_x_event_last_root_y = e->root.y;
870       ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
871    }
872 }
873
874 void
875 _ecore_x_event_handle_focus_in(XEvent *xevent)
876 {
877    Ecore_X_Event_Window_Focus_In *e;
878
879    _ecore_x_last_event_mouse_move = 0;
880
881    e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In));
882    if (!e)
883      return;
884
885    e->win = xevent->xfocus.window;
886
887    if (xevent->xfocus.mode == NotifyNormal)
888      e->mode = ECORE_X_EVENT_MODE_NORMAL;
889    else if (xevent->xfocus.mode == NotifyWhileGrabbed)
890      e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
891    else if (xevent->xfocus.mode == NotifyGrab)
892      e->mode = ECORE_X_EVENT_MODE_GRAB;
893    else if (xevent->xfocus.mode == NotifyUngrab)
894      e->mode = ECORE_X_EVENT_MODE_UNGRAB;
895
896    if (xevent->xfocus.detail == NotifyAncestor)
897      e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
898    else if (xevent->xfocus.detail == NotifyVirtual)
899      e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
900    else if (xevent->xfocus.detail == NotifyInferior)
901      e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
902    else if (xevent->xfocus.detail == NotifyNonlinear)
903      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
904    else if (xevent->xfocus.detail == NotifyNonlinearVirtual)
905      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
906    else if (xevent->xfocus.detail == NotifyPointer)
907      e->detail = ECORE_X_EVENT_DETAIL_POINTER;
908    else if (xevent->xfocus.detail == NotifyPointerRoot)
909      e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
910    else if (xevent->xfocus.detail == NotifyDetailNone)
911      e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
912
913    e->time = _ecore_x_event_last_time;
914    _ecore_x_event_last_time = e->time;
915    ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
916 }
917
918 void
919 _ecore_x_event_handle_focus_out(XEvent *xevent)
920 {
921    Ecore_X_Event_Window_Focus_Out *e;
922
923    _ecore_x_last_event_mouse_move = 0;
924
925    e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out));
926    if (!e)
927      return;
928
929    e->win = xevent->xfocus.window;
930
931    if (xevent->xfocus.mode == NotifyNormal)
932      e->mode = ECORE_X_EVENT_MODE_NORMAL;
933    else if (xevent->xfocus.mode == NotifyWhileGrabbed)
934      e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
935    else if (xevent->xfocus.mode == NotifyGrab)
936      e->mode = ECORE_X_EVENT_MODE_GRAB;
937    else if (xevent->xfocus.mode == NotifyUngrab)
938      e->mode = ECORE_X_EVENT_MODE_UNGRAB;
939
940    if (xevent->xfocus.detail == NotifyAncestor)
941      e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
942    else if (xevent->xfocus.detail == NotifyVirtual)
943      e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
944    else if (xevent->xfocus.detail == NotifyInferior)
945      e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
946    else if (xevent->xfocus.detail == NotifyNonlinear)
947      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
948    else if (xevent->xfocus.detail == NotifyNonlinearVirtual)
949      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
950    else if (xevent->xfocus.detail == NotifyPointer)
951      e->detail = ECORE_X_EVENT_DETAIL_POINTER;
952    else if (xevent->xfocus.detail == NotifyPointerRoot)
953      e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
954    else if (xevent->xfocus.detail == NotifyDetailNone)
955      e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
956
957    e->time = _ecore_x_event_last_time;
958    _ecore_x_event_last_time = e->time;
959    ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
960 }
961
962 void
963 _ecore_x_event_handle_keymap_notify(XEvent *xevent __UNUSED__)
964 {
965    _ecore_x_last_event_mouse_move = 0;
966    /* FIXME: handle this event type */
967 }
968
969 void
970 _ecore_x_event_handle_expose(XEvent *xevent)
971 {
972    Ecore_X_Event_Window_Damage *e;
973
974    _ecore_x_last_event_mouse_move = 0;
975    e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
976    if (!e)
977      return;
978
979    e->win = xevent->xexpose.window;
980    e->time = _ecore_x_event_last_time;
981    e->x = xevent->xexpose.x;
982    e->y = xevent->xexpose.y;
983    e->w = xevent->xexpose.width;
984    e->h = xevent->xexpose.height;
985    e->count = xevent->xexpose.count;
986    ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
987 }
988
989 void
990 _ecore_x_event_handle_graphics_expose(XEvent *xevent)
991 {
992    Ecore_X_Event_Window_Damage *e;
993
994    _ecore_x_last_event_mouse_move = 0;
995    e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
996    if (!e)
997      return;
998
999    e->win = xevent->xgraphicsexpose.drawable;
1000    e->time = _ecore_x_event_last_time;
1001    e->x = xevent->xgraphicsexpose.x;
1002    e->y = xevent->xgraphicsexpose.y;
1003    e->w = xevent->xgraphicsexpose.width;
1004    e->h = xevent->xgraphicsexpose.height;
1005    e->count = xevent->xgraphicsexpose.count;
1006    ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
1007 }
1008
1009 void
1010 _ecore_x_event_handle_visibility_notify(XEvent *xevent)
1011 {
1012    _ecore_x_last_event_mouse_move = 0;
1013 //   if (xevent->xvisibility.state != VisibilityPartiallyObscured)
1014    {
1015       Ecore_X_Event_Window_Visibility_Change *e;
1016
1017       e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change));
1018       if (!e)
1019         return;
1020
1021       e->win = xevent->xvisibility.window;
1022       e->time = _ecore_x_event_last_time;
1023       if (xevent->xvisibility.state == VisibilityFullyObscured)
1024         e->fully_obscured = 1;
1025       else
1026         e->fully_obscured = 0;
1027
1028       ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
1029    }
1030 }
1031
1032 void
1033 _ecore_x_event_handle_create_notify(XEvent *xevent)
1034 {
1035    Ecore_X_Event_Window_Create *e;
1036
1037    _ecore_x_last_event_mouse_move = 0;
1038    e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
1039    if (!e)
1040      return;
1041
1042    e->win = xevent->xcreatewindow.window;
1043    e->parent = xevent->xcreatewindow.parent;
1044    if (xevent->xcreatewindow.override_redirect)
1045      e->override = 1;
1046    else
1047      e->override = 0;
1048
1049    e->x = xevent->xcreatewindow.x;
1050    e->y = xevent->xcreatewindow.y;
1051    e->w = xevent->xcreatewindow.width;
1052    e->h = xevent->xcreatewindow.height;
1053    e->border = xevent->xcreatewindow.border_width;
1054    e->time = _ecore_x_event_last_time;
1055    ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
1056 }
1057
1058 void
1059 _ecore_x_event_handle_destroy_notify(XEvent *xevent)
1060 {
1061    Ecore_X_Event_Window_Destroy *e;
1062
1063    _ecore_x_last_event_mouse_move = 0;
1064    e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy));
1065    if (!e)
1066      return;
1067
1068    e->win = xevent->xdestroywindow.window;
1069    e->event_win = xevent->xdestroywindow.event;
1070    e->time = _ecore_x_event_last_time;
1071    if (e->win == _ecore_x_event_last_win)
1072      _ecore_x_event_last_win = 0;
1073
1074    ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
1075 }
1076
1077 void
1078 _ecore_x_event_handle_unmap_notify(XEvent *xevent)
1079 {
1080    Ecore_X_Event_Window_Hide *e;
1081
1082    _ecore_x_last_event_mouse_move = 0;
1083    e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
1084    if (!e)
1085      return;
1086
1087    e->win = xevent->xunmap.window;
1088    e->event_win = xevent->xunmap.event;
1089    e->time = _ecore_x_event_last_time;
1090    ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
1091 }
1092
1093 void
1094 _ecore_x_event_handle_map_notify(XEvent *xevent)
1095 {
1096    Ecore_X_Event_Window_Show *e;
1097
1098    _ecore_x_last_event_mouse_move = 0;
1099    e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
1100    if (!e)
1101      return;
1102
1103    e->win = xevent->xmap.window;
1104    e->event_win = xevent->xmap.event;
1105    e->time = _ecore_x_event_last_time;
1106    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
1107 }
1108
1109 void
1110 _ecore_x_event_handle_map_request(XEvent *xevent)
1111 {
1112    Ecore_X_Event_Window_Show_Request *e;
1113
1114    _ecore_x_last_event_mouse_move = 0;
1115    e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
1116    if (!e)
1117      return;
1118
1119    e->win = xevent->xmaprequest.window;
1120    e->time = _ecore_x_event_last_time;
1121    e->parent = xevent->xmaprequest.parent;
1122    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
1123 }
1124
1125 void
1126 _ecore_x_event_handle_reparent_notify(XEvent *xevent)
1127 {
1128    Ecore_X_Event_Window_Reparent *e;
1129
1130    _ecore_x_last_event_mouse_move = 0;
1131    e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
1132    if (!e)
1133      return;
1134
1135    e->win = xevent->xreparent.window;
1136    e->event_win = xevent->xreparent.event;
1137    e->parent = xevent->xreparent.parent;
1138    e->time = _ecore_x_event_last_time;
1139    ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
1140 }
1141
1142 void
1143 _ecore_x_event_handle_configure_notify(XEvent *xevent)
1144 {
1145    Ecore_X_Event_Window_Configure *e;
1146
1147    _ecore_x_last_event_mouse_move = 0;
1148    e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
1149    if (!e)
1150      return;
1151
1152    e->win = xevent->xconfigure.window;
1153    e->event_win = xevent->xconfigure.event;
1154    e->abovewin = xevent->xconfigure.above;
1155    e->x = xevent->xconfigure.x;
1156    e->y = xevent->xconfigure.y;
1157    e->w = xevent->xconfigure.width;
1158    e->h = xevent->xconfigure.height;
1159    e->border = xevent->xconfigure.border_width;
1160    e->override = xevent->xconfigure.override_redirect;
1161    e->from_wm = xevent->xconfigure.send_event;
1162    e->time = _ecore_x_event_last_time;
1163    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
1164 }
1165
1166 void
1167 _ecore_x_event_handle_configure_request(XEvent *xevent)
1168 {
1169    Ecore_X_Event_Window_Configure_Request *e;
1170
1171    _ecore_x_last_event_mouse_move = 0;
1172    e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
1173    if (!e)
1174      return;
1175
1176    e->win = xevent->xconfigurerequest.window;
1177    e->parent_win = xevent->xconfigurerequest.parent;
1178    e->abovewin = xevent->xconfigurerequest.above;
1179    e->x = xevent->xconfigurerequest.x;
1180    e->y = xevent->xconfigurerequest.y;
1181    e->w = xevent->xconfigurerequest.width;
1182    e->h = xevent->xconfigurerequest.height;
1183    e->border = xevent->xconfigurerequest.border_width;
1184    e->value_mask = xevent->xconfigurerequest.value_mask;
1185    e->time = _ecore_x_event_last_time;
1186
1187    if (xevent->xconfigurerequest.detail == Above)
1188      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1189    else if (xevent->xconfigurerequest.detail == Below)
1190      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1191    else if (xevent->xconfigurerequest.detail == TopIf)
1192      e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
1193    else if (xevent->xconfigurerequest.detail == BottomIf)
1194      e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
1195    else if (xevent->xconfigurerequest.detail == Opposite)
1196      e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
1197
1198    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
1199 }
1200
1201 void
1202 _ecore_x_event_handle_gravity_notify(XEvent *xevent __UNUSED__)
1203 {
1204    _ecore_x_last_event_mouse_move = 0;
1205    /* FIXME: handle this event type */
1206 }
1207
1208 void
1209 _ecore_x_event_handle_resize_request(XEvent *xevent)
1210 {
1211    Ecore_X_Event_Window_Resize_Request *e;
1212
1213    _ecore_x_last_event_mouse_move = 0;
1214    e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
1215    if (!e)
1216      return;
1217
1218    e->win = xevent->xresizerequest.window;
1219    e->w = xevent->xresizerequest.width;
1220    e->h = xevent->xresizerequest.height;
1221    e->time = _ecore_x_event_last_time;
1222    ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
1223 }
1224
1225 void
1226 _ecore_x_event_handle_circulate_notify(XEvent *xevent)
1227 {
1228    Ecore_X_Event_Window_Stack *e;
1229
1230    _ecore_x_last_event_mouse_move = 0;
1231    e = calloc(1, sizeof(Ecore_X_Event_Window_Stack));
1232    if (!e)
1233      return;
1234
1235    e->win = xevent->xcirculate.window;
1236    e->event_win = xevent->xcirculate.event;
1237    if (xevent->xcirculate.place == PlaceOnTop)
1238      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1239    else
1240      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1241
1242    e->time = _ecore_x_event_last_time;
1243    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
1244 }
1245
1246 void
1247 _ecore_x_event_handle_circulate_request(XEvent *xevent)
1248 {
1249    Ecore_X_Event_Window_Stack_Request *e;
1250
1251    _ecore_x_last_event_mouse_move = 0;
1252    e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request));
1253    if (!e)
1254      return;
1255
1256    e->win = xevent->xcirculaterequest.window;
1257    e->parent = xevent->xcirculaterequest.parent;
1258    if (xevent->xcirculaterequest.place == PlaceOnTop)
1259      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1260    else
1261      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1262
1263    e->time = _ecore_x_event_last_time;
1264    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
1265 }
1266
1267 void
1268 _ecore_x_event_handle_property_notify(XEvent *xevent)
1269 {
1270    _ecore_x_last_event_mouse_move = 0;
1271    {
1272       Ecore_X_Event_Window_Property *e;
1273
1274       e = calloc(1, sizeof(Ecore_X_Event_Window_Property));
1275       if (!e)
1276         return;
1277
1278       e->win = xevent->xproperty.window;
1279       e->atom = xevent->xproperty.atom;
1280       e->time = xevent->xproperty.time;
1281       _ecore_x_event_last_time = e->time;
1282       ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
1283    }
1284 }
1285
1286 void
1287 _ecore_x_event_handle_selection_clear(XEvent *xevent)
1288 {
1289 //   Ecore_X_Selection_Intern *d;
1290    Ecore_X_Event_Selection_Clear *e;
1291    Ecore_X_Atom sel;
1292
1293    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1294    _ecore_x_last_event_mouse_move = 0;
1295 /* errr..... why? paranoia.
1296    d = _ecore_x_selection_get(xevent->xselectionclear.selection);
1297    if (d && (xevent->xselectionclear.time > d->time))
1298      {
1299         _ecore_x_selection_set(None, NULL, 0,
1300                                xevent->xselectionclear.selection);
1301      }
1302  */
1303 /* Generate event for app cleanup */
1304    e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
1305    e->win = xevent->xselectionclear.window;
1306    e->time = xevent->xselectionclear.time;
1307    e->atom = sel = xevent->xselectionclear.selection;
1308    if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
1309      e->selection = ECORE_X_SELECTION_PRIMARY;
1310    else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
1311      e->selection = ECORE_X_SELECTION_SECONDARY;
1312    else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1313      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1314    else
1315      e->selection = ECORE_X_SELECTION_OTHER;
1316
1317    ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
1318 }
1319
1320 void
1321 _ecore_x_event_handle_selection_request(XEvent *xevent)
1322 {
1323    Ecore_X_Event_Selection_Request *e;
1324    Ecore_X_Selection_Intern *sd;
1325    void *data = NULL;
1326    int len;
1327    int typesize;
1328
1329    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1330    _ecore_x_last_event_mouse_move = 0;
1331    /*
1332     * Generate a selection request event.
1333     */
1334    e = malloc(sizeof(Ecore_X_Event_Selection_Request));
1335    e->owner = xevent->xselectionrequest.owner;
1336    e->requestor = xevent->xselectionrequest.requestor;
1337    e->time = xevent->xselectionrequest.time;
1338    e->selection = xevent->xselectionrequest.selection;
1339    e->target = xevent->xselectionrequest.target;
1340    e->property = xevent->xselectionrequest.property;
1341    ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL);
1342
1343    if ((sd = _ecore_x_selection_get(xevent->xselectionrequest.selection)) &&
1344        (sd->win == xevent->xselectionrequest.owner))
1345      {
1346         Ecore_X_Selection_Intern *si;
1347
1348         si = _ecore_x_selection_get(xevent->xselectionrequest.selection);
1349         if (si->data)
1350           {
1351              Ecore_X_Atom property = None;
1352              Ecore_X_Atom type;
1353
1354              /* Set up defaults for strings first */
1355              type = xevent->xselectionrequest.target;
1356              typesize = 8;
1357              len = sd->length;
1358
1359              if (!ecore_x_selection_convert(xevent->xselectionrequest.selection,
1360                                             xevent->xselectionrequest.target,
1361                                             &data, &len, &type, &typesize))
1362                /* Refuse selection, conversion to requested target failed */
1363                property = None;
1364              else if (data)
1365                {
1366                   /* FIXME: This does not properly handle large data transfers */
1367                   ecore_x_window_prop_property_set(
1368                     xevent->xselectionrequest.requestor,
1369                     xevent->xselectionrequest.
1370                     property,
1371                     type,
1372                     typesize,
1373                     data,
1374                     len);
1375                   property = xevent->xselectionrequest.property;
1376                   free(data);
1377                }
1378
1379              ecore_x_selection_notify_send(xevent->xselectionrequest.requestor,
1380                                            xevent->xselectionrequest.selection,
1381                                            xevent->xselectionrequest.target,
1382                                            property,
1383                                            xevent->xselectionrequest.time);
1384           }
1385      }
1386 }
1387
1388 void
1389 _ecore_x_event_handle_selection_notify(XEvent *xevent)
1390 {
1391    Ecore_X_Event_Selection_Notify *e;
1392    unsigned char *data = NULL;
1393    Ecore_X_Atom selection;
1394    int num_ret, format;
1395
1396    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1397    _ecore_x_last_event_mouse_move = 0;
1398    selection = xevent->xselection.selection;
1399
1400    if (xevent->xselection.target == ECORE_X_ATOM_SELECTION_TARGETS)
1401      {
1402         format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
1403                                                   xevent->xselection.property,
1404                                                   XA_ATOM, 32, &data, &num_ret);
1405         if (!format)
1406           {
1407              /* fallback if targets handling is not working and try get the
1408               * selection directly */
1409              XConvertSelection(_ecore_x_disp, selection,
1410                                ECORE_X_ATOM_UTF8_STRING,
1411                                selection,
1412                                xevent->xselection.requestor,
1413                                CurrentTime);
1414              return;
1415           }
1416      }
1417    else
1418      {
1419         format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
1420                                                   xevent->xselection.property,
1421                                                   AnyPropertyType, 8, &data,
1422                                                   &num_ret);
1423         if (!format)
1424           return;
1425      }
1426
1427    e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
1428    if (!e)
1429      return;
1430
1431    e->win = xevent->xselection.requestor;
1432    e->time = xevent->xselection.time;
1433    e->atom = selection;
1434    e->target = _ecore_x_selection_target_get(xevent->xselection.target);
1435
1436    if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
1437      e->selection = ECORE_X_SELECTION_PRIMARY;
1438    else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
1439      e->selection = ECORE_X_SELECTION_SECONDARY;
1440    else if (selection == ECORE_X_ATOM_SELECTION_XDND)
1441      e->selection = ECORE_X_SELECTION_XDND;
1442    else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1443      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1444    else
1445      e->selection = ECORE_X_SELECTION_OTHER;
1446
1447    e->data = _ecore_x_selection_parse(e->target, data, num_ret, format);
1448
1449    ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e,
1450                    _ecore_x_event_free_selection_notify, NULL);
1451 }
1452
1453 void
1454 _ecore_x_event_handle_colormap_notify(XEvent *xevent)
1455 {
1456    Ecore_X_Event_Window_Colormap *e;
1457
1458    _ecore_x_last_event_mouse_move = 0;
1459    e = calloc(1, sizeof(Ecore_X_Event_Window_Colormap));
1460    if (!e)
1461      return;
1462
1463    e->win = xevent->xcolormap.window;
1464    e->cmap = xevent->xcolormap.colormap;
1465    e->time = _ecore_x_event_last_time;
1466    if (xevent->xcolormap.state == ColormapInstalled)
1467      e->installed = EINA_TRUE;
1468    else
1469      e->installed = EINA_FALSE;
1470
1471    ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
1472 }
1473
1474 void
1475 _ecore_x_event_handle_client_message(XEvent *xevent)
1476 {
1477    _ecore_x_last_event_mouse_move = 0;
1478    /* Special client message event handling here. need to put LOTS of if */
1479    /* checks here and generate synthetic events per special message known */
1480    /* otherwise generate generic client message event. this would handle*/
1481    /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
1482    if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS) &&
1483        (xevent->xclient.format == 32) &&
1484        (xevent->xclient.data.l[0] == (long)ECORE_X_ATOM_WM_DELETE_WINDOW))
1485      {
1486         Ecore_X_Event_Window_Delete_Request *e;
1487
1488         e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request));
1489         if (!e)
1490           return;
1491
1492         e->win = xevent->xclient.window;
1493         e->time = _ecore_x_event_last_time;
1494         ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
1495      }
1496    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
1497             (xevent->xclient.format == 32) &&
1498 /* Ignore move and resize with keyboard */
1499             (xevent->xclient.data.l[2] < 9))
1500      {
1501         Ecore_X_Event_Window_Move_Resize_Request *e;
1502
1503         e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
1504         if (!e)
1505           return;
1506
1507         e->win = xevent->xclient.window;
1508         e->x = xevent->xclient.data.l[0];
1509         e->y = xevent->xclient.data.l[1];
1510         e->direction = xevent->xclient.data.l[2];
1511         e->button = xevent->xclient.data.l[3];
1512         e->source = xevent->xclient.data.l[4];
1513         ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
1514      }
1515    /* Xdnd Client Message Handling Begin */
1516    /* Message Type: XdndEnter target */
1517    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_ENTER)
1518      {
1519         Ecore_X_Event_Xdnd_Enter *e;
1520         Ecore_X_DND_Target *target;
1521
1522         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
1523         if (!e) return;
1524
1525         LOGFN(__FILE__, __LINE__, __FUNCTION__);
1526
1527         target = _ecore_x_dnd_target_get();
1528         target->state = ECORE_X_DND_TARGET_ENTERED;
1529         target->source = xevent->xclient.data.l[0];
1530         target->win = xevent->xclient.window;
1531         target->version = (int)(xevent->xclient.data.l[1] >> 24);
1532         if (target->version > ECORE_X_DND_VERSION)
1533           {
1534              WRN("DND: Requested version %d, we only support up to %d",
1535                  target->version, ECORE_X_DND_VERSION);
1536              free(e);
1537              return;
1538           }
1539
1540         if (xevent->xclient.data.l[1] & 0x1UL)
1541           {
1542              /* source supports more than 3 types, fetch property */
1543              unsigned char *data;
1544              Ecore_X_Atom *types;
1545              int i, num_ret;
1546
1547              LOGFN(__FILE__, __LINE__, __FUNCTION__);
1548              if (!(ecore_x_window_prop_property_get(target->source,
1549                                                     ECORE_X_ATOM_XDND_TYPE_LIST,
1550                                                     XA_ATOM,
1551                                                     32, &data, &num_ret)))
1552                {
1553                   WRN(
1554                     "DND: Could not fetch data type list from source window, aborting.");
1555                   free(e);
1556                   return;
1557                }
1558
1559              types = (Ecore_X_Atom *)data;
1560              e->types = calloc(num_ret, sizeof(char *));
1561              if (e->types)
1562                {
1563                   LOGFN(__FILE__, __LINE__, __FUNCTION__);
1564                   for (i = 0; i < num_ret; i++)
1565                     e->types[i] = XGetAtomName(_ecore_x_disp, types[i]);
1566                }
1567
1568              e->num_types = num_ret;
1569           }
1570         else
1571           {
1572              int i = 0;
1573
1574              e->types = calloc(3, sizeof(char *));
1575              if (e->types)
1576                {
1577                   LOGFN(__FILE__, __LINE__, __FUNCTION__);
1578                   while ((i < 3) && (xevent->xclient.data.l[i + 2]))
1579                     {
1580                        e->types[i] = XGetAtomName(_ecore_x_disp,
1581                                                   xevent->xclient.data.l[i + 2]);
1582                        i++;
1583                     }
1584                }
1585
1586              e->num_types = i;
1587           }
1588
1589         e->win = target->win;
1590         e->source = target->source;
1591         ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e,
1592                         _ecore_x_event_free_xdnd_enter, NULL);
1593      }
1594    /* Message Type: XdndPosition target */
1595    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_POSITION)
1596      {
1597         Ecore_X_Event_Xdnd_Position *e;
1598         Ecore_X_DND_Target *target;
1599
1600         LOGFN(__FILE__, __LINE__, __FUNCTION__);
1601
1602         target = _ecore_x_dnd_target_get();
1603         if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
1604             (target->win != xevent->xclient.window))
1605           return;
1606
1607         target->pos.x = xevent->xclient.data.l[2] >> 16;
1608         target->pos.y = xevent->xclient.data.l[2] & 0xFFFFUL;
1609         target->action = xevent->xclient.data.l[4]; /* Version 2 */
1610
1611         target->time = (target->version >= 1) ?
1612           (Time)xevent->xclient.data.l[3] : CurrentTime;
1613
1614         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
1615         if (!e) return;
1616
1617         e->win = target->win;
1618         e->source = target->source;
1619         e->position.x = target->pos.x;
1620         e->position.y = target->pos.y;
1621         e->action = target->action;
1622         ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
1623      }
1624    /* Message Type: XdndStatus source */
1625    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_STATUS)
1626      {
1627         Ecore_X_Event_Xdnd_Status *e;
1628         Ecore_X_DND_Source *source;
1629
1630         LOGFN(__FILE__, __LINE__, __FUNCTION__);
1631
1632         source = _ecore_x_dnd_source_get();
1633         /* Make sure source/target match */
1634         if ((source->win != xevent->xclient.window) ||
1635             (source->dest != (Window)xevent->xclient.data.l[0]))
1636           return;
1637
1638         source->await_status = 0;
1639
1640         source->will_accept = xevent->xclient.data.l[1] & 0x1UL;
1641         source->suppress = (xevent->xclient.data.l[1] & 0x2UL) ? 0 : 1;
1642
1643         source->rectangle.x = xevent->xclient.data.l[2] >> 16;
1644         source->rectangle.y = xevent->xclient.data.l[2] & 0xFFFFUL;
1645         source->rectangle.width = xevent->xclient.data.l[3] >> 16;
1646         source->rectangle.height = xevent->xclient.data.l[3] & 0xFFFFUL;
1647
1648         source->accepted_action = xevent->xclient.data.l[4];
1649
1650         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
1651         if (!e) return;
1652
1653         e->win = source->win;
1654         e->target = source->dest;
1655         e->will_accept = source->will_accept;
1656         e->rectangle.x = source->rectangle.x;
1657         e->rectangle.y = source->rectangle.y;
1658         e->rectangle.width = source->rectangle.width;
1659         e->rectangle.height = source->rectangle.height;
1660         e->action = source->accepted_action;
1661
1662         ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
1663      }
1664    /* Message Type: XdndLeave target */
1665    /* Pretend the whole thing never happened, sort of */
1666    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_LEAVE)
1667      {
1668         Ecore_X_Event_Xdnd_Leave *e;
1669         Ecore_X_DND_Target *target;
1670
1671         LOGFN(__FILE__, __LINE__, __FUNCTION__);
1672
1673         target = _ecore_x_dnd_target_get();
1674         if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
1675             (target->win != xevent->xclient.window))
1676           return;
1677
1678         target->state = ECORE_X_DND_TARGET_IDLE;
1679
1680         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
1681         if (!e) return;
1682
1683         e->win = xevent->xclient.window;
1684         e->source = (Window)xevent->xclient.data.l[0];
1685         ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
1686      }
1687    /* Message Type: XdndDrop target */
1688    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_DROP)
1689      {
1690         Ecore_X_Event_Xdnd_Drop *e;
1691         Ecore_X_DND_Target *target;
1692
1693         LOGFN(__FILE__, __LINE__, __FUNCTION__);
1694
1695         target = _ecore_x_dnd_target_get();
1696         /* Match source/target */
1697         if ((target->source != (Window)xevent->xclient.data.l[0]) ||
1698             (target->win != xevent->xclient.window))
1699           return;
1700
1701         target->time = (target->version >= 1) ?
1702           (Time)xevent->xclient.data.l[2] : _ecore_x_event_last_time;
1703
1704         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
1705         if (!e) return;
1706
1707         e->win = target->win;
1708         e->source = target->source;
1709         e->action = target->action;
1710         e->position.x = target->pos.x;
1711         e->position.y = target->pos.y;
1712         ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
1713      }
1714    /* Message Type: XdndFinished source */
1715    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_FINISHED)
1716      {
1717         Ecore_X_Event_Xdnd_Finished *e;
1718         Ecore_X_DND_Source *source;
1719         Eina_Bool completed = EINA_TRUE;
1720
1721         LOGFN(__FILE__, __LINE__, __FUNCTION__);
1722
1723         source = _ecore_x_dnd_source_get();
1724         /* Match source/target */
1725         if ((source->win != xevent->xclient.window) ||
1726             (source->dest != (Window)xevent->xclient.data.l[0]))
1727           return;
1728
1729         if ((source->version < 5) || (xevent->xclient.data.l[1] & 0x1UL))
1730           {
1731              LOGFN(__FILE__, __LINE__, __FUNCTION__);
1732              /* Target successfully performed drop action */
1733              ecore_x_selection_xdnd_clear();
1734              source->state = ECORE_X_DND_SOURCE_IDLE;
1735           }
1736         else if (source->version >= 5)
1737           {
1738              completed = EINA_FALSE;
1739              source->state = ECORE_X_DND_SOURCE_CONVERTING;
1740
1741              /* FIXME: Probably need to add a timer to switch back to idle
1742               * and discard the selection data */
1743           }
1744
1745         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished));
1746         if (!e) return;
1747
1748         e->win = source->win;
1749         e->target = source->dest;
1750         e->completed = completed;
1751         if (source->version >= 5)
1752           {
1753              source->accepted_action = xevent->xclient.data.l[2];
1754              e->action = source->accepted_action;
1755           }
1756         else
1757           {
1758              source->accepted_action = 0;
1759              e->action = source->action;
1760           }
1761
1762         ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
1763      }
1764    else if (xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_STATE)
1765      {
1766         Ecore_X_Event_Window_State_Request *e;
1767
1768         e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1769         if (!e) return;
1770
1771         e->win = xevent->xclient.window;
1772         if (xevent->xclient.data.l[0] == 0)
1773           e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
1774         else if (xevent->xclient.data.l[0] == 1)
1775           e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1776         else if (xevent->xclient.data.l[0] == 2)
1777           e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
1778         else
1779           {
1780              free(e);
1781              return;
1782           }
1783
1784         LOGFN(__FILE__, __LINE__, __FUNCTION__);
1785         e->state[0] = _ecore_x_netwm_state_get(xevent->xclient.data.l[1]);
1786         if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
1787           {
1788 //           char *name;
1789              LOGFN(__FILE__, __LINE__, __FUNCTION__);
1790
1791 //           name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[1]);
1792 //           if (name) ERR("Unknown state: %s", name);
1793 //           XFree(name);
1794           }
1795         e->state[1] = _ecore_x_netwm_state_get(xevent->xclient.data.l[2]);
1796         if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
1797           {
1798 //           char *name;
1799              LOGFN(__FILE__, __LINE__, __FUNCTION__);
1800
1801 //           name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[2]);
1802 //           if (name) ERR("Unknown state: %s", name);
1803 //           XFree(name);
1804           }
1805
1806         e->source = xevent->xclient.data.l[3];
1807
1808         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1809      }
1810    else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_CHANGE_STATE)
1811             && (xevent->xclient.format == 32)
1812             && (xevent->xclient.data.l[0] == IconicState))
1813      {
1814         Ecore_X_Event_Window_State_Request *e;
1815
1816         e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1817         if (!e)
1818           return;
1819
1820         e->win = xevent->xclient.window;
1821         e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1822         e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
1823
1824         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1825      }
1826    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_DESKTOP)
1827             && (xevent->xclient.format == 32))
1828      {
1829         Ecore_X_Event_Desktop_Change *e;
1830
1831         e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
1832         if (!e)
1833           return;
1834
1835         e->win = xevent->xclient.window;
1836         e->desk = xevent->xclient.data.l[0];
1837         e->source = xevent->xclient.data.l[1];
1838
1839         ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
1840      }
1841    else if ((xevent->xclient.message_type ==
1842              ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS))
1843      {
1844         Ecore_X_Event_Frame_Extents_Request *e;
1845
1846         e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request));
1847         if (!e)
1848           return;
1849
1850         e->win = xevent->xclient.window;
1851
1852         ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
1853      }
1854    else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS)
1855             && ((Ecore_X_Atom)xevent->xclient.data.l[0] ==
1856                 ECORE_X_ATOM_NET_WM_PING)
1857             && (xevent->xclient.format == 32))
1858      {
1859         Ecore_X_Event_Ping *e;
1860         Ecore_X_Window root = 0;
1861
1862         e = calloc(1, sizeof(Ecore_X_Event_Ping));
1863         if (!e)
1864           return;
1865
1866         e->win = xevent->xclient.window;
1867         e->time = xevent->xclient.data.l[1];
1868         e->event_win = xevent->xclient.data.l[2];
1869
1870         /* send a reply anyway - we are alive... eventloop at least */
1871         ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
1872         if (ScreenCount(_ecore_x_disp) > 1)
1873           {
1874              LOGFN(__FILE__, __LINE__, __FUNCTION__);
1875              root = ecore_x_window_root_get(e->win);
1876           }
1877         else
1878           root = DefaultRootWindow(_ecore_x_disp);
1879
1880         if (xevent->xclient.window != root)
1881           {
1882              xevent->xclient.window = root;
1883              XSendEvent(_ecore_x_disp, root, False,
1884                         SubstructureRedirectMask | SubstructureNotifyMask,
1885                         xevent);
1886           }
1887      }
1888    else if ((xevent->xclient.message_type ==
1889              ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
1890             (xevent->xclient.format == 8))
1891      _ecore_x_netwm_startup_info_begin(xevent->xclient.window,
1892                                        xevent->xclient.data.b);
1893    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_STARTUP_INFO) &&
1894             (xevent->xclient.format == 8))
1895      _ecore_x_netwm_startup_info(xevent->xclient.window,
1896                                  xevent->xclient.data.b);
1897    else if ((xevent->xclient.message_type == 27777)
1898             && (xevent->xclient.data.l[0] == 0x7162534)
1899             && (xevent->xclient.format == 32)
1900             && (xevent->xclient.window == _ecore_x_private_win))
1901      {
1902         /* a grab sync marker */
1903         if (xevent->xclient.data.l[1] == 0x10000001)
1904           _ecore_x_window_grab_remove(xevent->xclient.data.l[2]);
1905         else if (xevent->xclient.data.l[1] == 0x10000002)
1906           _ecore_x_key_grab_remove(xevent->xclient.data.l[2]);
1907      }
1908    else
1909      {
1910         Ecore_X_Event_Client_Message *e;
1911         int i;
1912
1913         e = calloc(1, sizeof(Ecore_X_Event_Client_Message));
1914         if (!e)
1915           return;
1916
1917         e->win = xevent->xclient.window;
1918         e->message_type = xevent->xclient.message_type;
1919         e->format = xevent->xclient.format;
1920         for (i = 0; i < 5; i++)
1921           e->data.l[i] = xevent->xclient.data.l[i];
1922
1923         ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
1924      }
1925 }
1926
1927 void
1928 _ecore_x_event_handle_mapping_notify(XEvent *xevent)
1929 {
1930    Ecore_X_Event_Mapping_Change *e;
1931
1932    _ecore_x_last_event_mouse_move = 0;
1933    XRefreshKeyboardMapping((XMappingEvent *)xevent);
1934    _ecore_x_modifiers_get();
1935    e = calloc(1, sizeof(Ecore_X_Event_Mapping_Change));
1936    if (!e) return;
1937    switch (xevent->xmapping.request)
1938      {
1939       case MappingModifier:
1940         e->type = ECORE_X_MAPPING_MODIFIER;
1941         break;
1942
1943       case MappingKeyboard:
1944         e->type = ECORE_X_MAPPING_KEYBOARD;
1945         break;
1946
1947       case MappingPointer:
1948       default:
1949         e->type = ECORE_X_MAPPING_MOUSE;
1950         break;
1951      }
1952    e->keycode = xevent->xmapping.first_keycode;
1953    e->num = xevent->xmapping.count;
1954    ecore_event_add(ECORE_X_EVENT_MAPPING_CHANGE, e, NULL, NULL);
1955 }
1956
1957 void
1958 _ecore_x_event_handle_shape_change(XEvent *xevent)
1959 {
1960    XShapeEvent *shape_event;
1961    Ecore_X_Event_Window_Shape *e;
1962
1963    _ecore_x_last_event_mouse_move = 0;
1964    shape_event = (XShapeEvent *)xevent;
1965    e = calloc(1, sizeof(Ecore_X_Event_Window_Shape));
1966    if (!e)
1967      return;
1968
1969    e->win = shape_event->window;
1970    e->time = shape_event->time;
1971    switch (shape_event->kind)
1972      {
1973       case ShapeBounding:
1974         e->type = ECORE_X_SHAPE_BOUNDING;
1975         break;
1976
1977       case ShapeClip:
1978         e->type = ECORE_X_SHAPE_CLIP;
1979         break;
1980
1981       case ShapeInput:
1982         e->type = ECORE_X_SHAPE_INPUT;
1983         break;
1984
1985       default:
1986         break;
1987      }
1988    e->x = shape_event->x;
1989    e->y = shape_event->y;
1990    e->w = shape_event->width;
1991    e->h = shape_event->height;
1992    e->shaped = shape_event->shaped;
1993    ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
1994 }
1995
1996 void
1997 _ecore_x_event_handle_screensaver_notify(XEvent *xevent)
1998 {
1999 #ifdef ECORE_XSS
2000    XScreenSaverNotifyEvent *screensaver_event;
2001    Ecore_X_Event_Screensaver_Notify *e;
2002
2003    _ecore_x_last_event_mouse_move = 0;
2004    screensaver_event = (XScreenSaverNotifyEvent *)xevent;
2005    e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify));
2006    if (!e)
2007      return;
2008
2009    e->win = screensaver_event->window;
2010    if ((screensaver_event->state == ScreenSaverOn) ||
2011        (screensaver_event->state == ScreenSaverCycle))
2012      e->on = EINA_TRUE;
2013    else
2014      e->on = EINA_FALSE;
2015
2016    e->time = screensaver_event->time;
2017    ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
2018 #else /* ifdef ECORE_XSS */
2019    xevent = NULL;
2020 #endif /* ifdef ECORE_XSS */
2021 }
2022
2023 void
2024 _ecore_x_event_handle_sync_counter(XEvent *xevent)
2025 {
2026    XSyncCounterNotifyEvent *sync_counter_event;
2027    Ecore_X_Event_Sync_Counter *e;
2028
2029    _ecore_x_last_event_mouse_move = 0;
2030    sync_counter_event = (XSyncCounterNotifyEvent *)xevent;
2031    e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter));
2032    if (!e)
2033      return;
2034
2035    e->time = sync_counter_event->time;
2036    ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
2037 }
2038
2039 void
2040 _ecore_x_event_handle_sync_alarm(XEvent *xevent)
2041 {
2042    XSyncAlarmNotifyEvent *sync_alarm_event;
2043    Ecore_X_Event_Sync_Alarm *e;
2044
2045    _ecore_x_last_event_mouse_move = 0;
2046    sync_alarm_event = (XSyncAlarmNotifyEvent *)xevent;
2047
2048    e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm));
2049    if (!e)
2050      return;
2051
2052    e->time = sync_alarm_event->time;
2053    e->alarm = sync_alarm_event->alarm;
2054    ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
2055 }
2056
2057 #ifdef ECORE_XRANDR
2058 void
2059 _ecore_x_event_handle_randr_change(XEvent *xevent)
2060 {
2061    XRRScreenChangeNotifyEvent *randr_event;
2062    Ecore_X_Event_Screen_Change *e;
2063
2064    _ecore_x_last_event_mouse_move = 0;
2065    randr_event = (XRRScreenChangeNotifyEvent *)xevent;
2066    if (!XRRUpdateConfiguration(xevent))
2067      ERR("Can't update RR config!");
2068
2069    e = calloc(1, sizeof(Ecore_X_Event_Screen_Change));
2070    if (!e)
2071      return;
2072
2073    e->win = randr_event->window;
2074    e->root = randr_event->root;
2075    e->size.width = randr_event->width;
2076    e->size.height = randr_event->height;
2077    e->time = randr_event->timestamp;
2078    e->config_time = randr_event->config_timestamp;
2079    e->size.width_mm = randr_event->mwidth;
2080    e->size.height_mm = randr_event->mheight;
2081    e->orientation = randr_event->rotation;
2082    e->subpixel_order = randr_event->subpixel_order;
2083    ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
2084 }
2085
2086 static void
2087 _ecore_x_event_handle_randr_notify_crtc_change(const XRRNotifyEvent *xevent)
2088 {
2089    const XRRCrtcChangeNotifyEvent *randr_event;
2090    Ecore_X_Event_Randr_Crtc_Change *e;
2091
2092    randr_event = (const XRRCrtcChangeNotifyEvent *)xevent;
2093
2094    e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change));
2095    if (!e)
2096      return;
2097
2098    e->win = randr_event->window;
2099    e->crtc = randr_event->crtc;
2100    e->mode = randr_event->mode;
2101    e->orientation = randr_event->rotation;
2102    e->geo.x = randr_event->x;
2103    e->geo.y = randr_event->y;
2104    e->geo.w = randr_event->width;
2105    e->geo.h = randr_event->height;
2106    ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL);
2107 }
2108
2109 static void
2110 _ecore_x_event_handle_randr_notify_output_change(const XRRNotifyEvent *xevent)
2111 {
2112    const XRROutputChangeNotifyEvent *randr_event;
2113    Ecore_X_Event_Randr_Output_Change *e;
2114
2115    randr_event = (const XRROutputChangeNotifyEvent *)xevent;
2116
2117    e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Change));
2118    if (!e)
2119      return;
2120
2121    e->win = randr_event->window;
2122    e->output = randr_event->output;
2123    e->crtc = randr_event->crtc;
2124    e->mode = randr_event->mode;
2125    e->orientation = randr_event->rotation;
2126    e->connection = randr_event->connection;
2127    e->subpixel_order = randr_event->subpixel_order;
2128    ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, e, NULL, NULL);
2129 }
2130
2131 static void
2132 _ecore_x_event_handle_randr_notify_output_property(const XRRNotifyEvent *xevent)
2133 {
2134    const XRROutputPropertyNotifyEvent *randr_event;
2135    Ecore_X_Event_Randr_Output_Property_Notify *e;
2136
2137    randr_event = (const XRROutputPropertyNotifyEvent *)xevent;
2138
2139    e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Property_Notify));
2140    if (!e)
2141      return;
2142
2143    e->win = randr_event->window;
2144    e->output = randr_event->output;
2145    e->property = randr_event->property;
2146    e->time = randr_event->timestamp;
2147    if (randr_event->state == PropertyNewValue)
2148      e->state = ECORE_X_RANDR_PROPERTY_CHANGE_ADD;
2149    else
2150      e->state = ECORE_X_RANDR_PROPERTY_CHANGE_DEL;
2151    ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, e, NULL, NULL);
2152 }
2153
2154 void
2155 _ecore_x_event_handle_randr_notify(XEvent *xevent)
2156 {
2157    const XRRNotifyEvent *randr_event;
2158
2159    _ecore_x_last_event_mouse_move = 0;
2160    randr_event = (const XRRNotifyEvent *)xevent;
2161    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2162    switch (randr_event->subtype)
2163      {
2164       case RRNotify_CrtcChange:
2165         _ecore_x_event_handle_randr_notify_crtc_change(randr_event);
2166         break;
2167
2168       case RRNotify_OutputChange:
2169         _ecore_x_event_handle_randr_notify_output_change(randr_event);
2170         break;
2171
2172       case RRNotify_OutputProperty:
2173         _ecore_x_event_handle_randr_notify_output_property(randr_event);
2174         break;
2175
2176       default:
2177         ERR("Unknown XRandR RRNotify subtype: %d.",
2178             randr_event->subtype);
2179         break;
2180      }
2181 }
2182
2183 #endif /* ifdef ECORE_XRANDR */
2184
2185 #ifdef ECORE_XFIXES
2186 void
2187 _ecore_x_event_handle_fixes_selection_notify(XEvent *event)
2188 {
2189    XFixesSelectionNotifyEvent *notify_event =
2190      (XFixesSelectionNotifyEvent *)event;
2191    Ecore_X_Event_Fixes_Selection_Notify *e;
2192    Ecore_X_Atom sel;
2193
2194    _ecore_x_last_event_mouse_move = 0;
2195    /* Nothing here yet */
2196
2197    e = calloc(1, sizeof(*e));
2198    if (!e)
2199      return;
2200
2201    e->win = notify_event->window;
2202    e->owner = notify_event->owner;
2203    e->time = notify_event->timestamp;
2204    e->selection_time = notify_event->selection_timestamp;
2205    e->atom = sel = notify_event->selection;
2206    if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
2207      e->selection = ECORE_X_SELECTION_PRIMARY;
2208    else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
2209      e->selection = ECORE_X_SELECTION_SECONDARY;
2210    else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
2211      e->selection = ECORE_X_SELECTION_CLIPBOARD;
2212    else
2213      e->selection = ECORE_X_SELECTION_OTHER;
2214    e->reason = notify_event->subtype;
2215
2216    ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL);
2217 }
2218
2219 #endif /* ifdef ECORE_XFIXES */
2220
2221 #ifdef ECORE_XDAMAGE
2222 void
2223 _ecore_x_event_handle_damage_notify(XEvent *event)
2224 {
2225    XDamageNotifyEvent *damage_event;   
2226    Ecore_X_Event_Damage *e;
2227
2228    _ecore_x_last_event_mouse_move = 0;
2229    damage_event = (XDamageNotifyEvent *)event;
2230
2231    e = calloc(1, sizeof(Ecore_X_Event_Damage));
2232    if (!e)
2233      return;
2234
2235    e->level = damage_event->level;
2236    e->drawable = damage_event->drawable;
2237    e->damage = damage_event->damage;
2238    e->more = damage_event->more;
2239    e->time = damage_event->timestamp;
2240    e->area.x = damage_event->area.x;
2241    e->area.y = damage_event->area.y;
2242    e->area.width = damage_event->area.width;
2243    e->area.height = damage_event->area.height;
2244    e->geometry.x = damage_event->geometry.x;
2245    e->geometry.y = damage_event->geometry.y;
2246    e->geometry.width = damage_event->geometry.width;
2247    e->geometry.height = damage_event->geometry.height;
2248
2249    ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
2250 }
2251
2252 #endif /* ifdef ECORE_XDAMAGE */
2253
2254 static void
2255 _ecore_x_event_free_generic_event(void *data,
2256                                   void *ev)
2257 {
2258 #ifdef ECORE_XI2
2259    Ecore_X_Event_Generic *e = (Ecore_X_Event_Generic *)ev;
2260
2261    if (data)
2262      {
2263         if (e->data)
2264           XFreeEventData(_ecore_x_disp, (XGenericEventCookie *)data);
2265         free(data);
2266      }
2267    free(e);
2268 #else
2269    return;
2270    data = NULL; ev = NULL;
2271 #endif /* ifdef ECORE_XI2 */
2272 }
2273
2274 void
2275 _ecore_x_event_handle_generic_event(XEvent *event)
2276 {
2277 #ifdef ECORE_XI2
2278    XGenericEvent *generic_event;
2279    Ecore_X_Event_Generic *e;
2280    XGenericEventCookie *data;
2281
2282    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2283    generic_event = (XGenericEvent *)event;
2284
2285    e = calloc(1, sizeof(Ecore_X_Event_Generic));
2286    if (!e)
2287      return;
2288
2289    if (XGetEventData(_ecore_x_disp, &(event->xcookie)))
2290      {
2291         e->cookie = event->xcookie.cookie;
2292         e->data = event->xcookie.data;
2293      }
2294    else
2295      {
2296         e->cookie = 0;
2297         e->data = NULL;
2298      }
2299
2300    e->extension = generic_event->extension;
2301    e->evtype = generic_event->evtype;
2302
2303    if (e->extension == _ecore_x_xi2_opcode)
2304      _ecore_x_input_handler(event);
2305
2306    data = malloc(sizeof(XGenericEventCookie));
2307    if (data) memcpy(data, &(event->xcookie), sizeof(XGenericEventCookie));
2308    ecore_event_add(ECORE_X_EVENT_GENERIC,
2309                    e,
2310                    _ecore_x_event_free_generic_event,
2311                    data);
2312 #else
2313    return;
2314    event = NULL;
2315 #endif /* ifdef ECORE_XI2 */
2316 }
2317
2318 #ifdef ECORE_XGESTURE
2319 void
2320 _ecore_x_event_handle_gesture_notify_flick(XEvent *xevent)
2321 {
2322    XGestureNotifyFlickEvent *xfe;
2323    Ecore_X_Event_Gesture_Notify_Flick *e;
2324
2325    _ecore_x_last_event_mouse_move = 0;
2326    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2327
2328    xfe = (XGestureNotifyFlickEvent *)xevent;
2329    e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Flick));
2330    if (!e)
2331      return;
2332
2333    e->win = xfe->window;
2334    e->time = xfe->time;
2335    e->subtype = xfe->kind;
2336    e->num_fingers = xfe->num_finger;
2337    e->distance = xfe->distance;
2338    e->duration = xfe->duration;
2339    e->direction = xfe->direction;
2340    e->angle = XFixedToDouble(xfe->angle);
2341
2342    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_FLICK, e, NULL, NULL);
2343 }
2344
2345 void
2346 _ecore_x_event_handle_gesture_notify_pan(XEvent *xevent)
2347 {
2348    XGestureNotifyPanEvent *xpe;
2349    Ecore_X_Event_Gesture_Notify_Pan *e;
2350
2351    _ecore_x_last_event_mouse_move = 0;
2352    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2353
2354    xpe = (XGestureNotifyPanEvent *)xevent;
2355    e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Pan));
2356    if (!e)
2357      return;
2358
2359    e->win = xpe->window;
2360    e->time = xpe->time;
2361    e->subtype = xpe->kind;
2362    e->num_fingers = xpe->num_finger;
2363    e->dx = xpe->dx;
2364    e->dy = xpe->dy;
2365    e->distance = xpe->distance;
2366    e->duration = xpe->duration;
2367    e->direction = xpe->direction;
2368
2369    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PAN, e, NULL, NULL);
2370 }
2371
2372 void
2373 _ecore_x_event_handle_gesture_notify_pinchrotation(XEvent *xevent)
2374 {
2375    XGestureNotifyPinchRotationEvent *xpre;
2376    Ecore_X_Event_Gesture_Notify_PinchRotation *e;
2377
2378    _ecore_x_last_event_mouse_move = 0;
2379    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2380
2381    xpre = (XGestureNotifyPinchRotationEvent *)xevent;
2382    e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_PinchRotation));
2383    if (!e)
2384      return;
2385
2386    e->win = xpre->window;
2387    e->time = xpre->time;
2388    e->subtype = xpre->kind;
2389    e->num_fingers = xpre->num_finger;
2390    e->distance = xpre->distance;
2391    e->cx = xpre->cx;
2392    e->cy = xpre->cy;
2393    e->zoom = XFixedToDouble(xpre->zoom);
2394    e->angle = XFixedToDouble(xpre->angle);
2395
2396    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_PINCHROTATION, e, NULL, NULL);
2397 }
2398
2399 void
2400 _ecore_x_event_handle_gesture_notify_tap(XEvent *xevent)
2401 {
2402    XGestureNotifyTapEvent *xte;
2403    Ecore_X_Event_Gesture_Notify_Tap *e;
2404
2405    _ecore_x_last_event_mouse_move = 0;
2406    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2407
2408    xte = (XGestureNotifyTapEvent *)xevent;
2409    e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Tap));
2410    if (!e)
2411      return;
2412
2413    e->win = xte->window;
2414    e->time = xte->time;
2415    e->subtype = xte->kind;
2416    e->num_fingers = xte->num_finger;
2417    e->cx = xte->cx;
2418    e->cy = xte->cy;
2419    e->tap_repeat = xte->tap_repeat;
2420    e->interval = xte->interval;
2421
2422    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAP, e, NULL, NULL);
2423 }
2424
2425 void
2426 _ecore_x_event_handle_gesture_notify_tapnhold(XEvent *xevent)
2427 {
2428    XGestureNotifyTapNHoldEvent *xthe;
2429    Ecore_X_Event_Gesture_Notify_TapNHold *e;
2430
2431    _ecore_x_last_event_mouse_move = 0;
2432    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2433
2434    xthe = (XGestureNotifyTapNHoldEvent *)xevent;
2435    e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_TapNHold));
2436    if (!e)
2437      return;
2438
2439    e->win = xthe->window;
2440    e->time = xthe->time;
2441    e->subtype = xthe->kind;
2442    e->num_fingers = xthe->num_finger;
2443    e->cx = xthe->cx;
2444    e->cy = xthe->cy;
2445    e->interval = xthe->interval;
2446    e->hold_time = xthe->holdtime;
2447
2448    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_TAPNHOLD, e, NULL, NULL);
2449 }
2450
2451 void
2452 _ecore_x_event_handle_gesture_notify_hold(XEvent *xevent)
2453 {
2454    XGestureNotifyHoldEvent *xhe;
2455    Ecore_X_Event_Gesture_Notify_Hold *e;
2456
2457    _ecore_x_last_event_mouse_move = 0;
2458    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2459
2460    xhe = (XGestureNotifyHoldEvent *)xevent;
2461    e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Hold));
2462    if (!e)
2463      return;
2464
2465    e->win = xhe->window;
2466    e->time = xhe->time;
2467    e->subtype = xhe->kind;
2468    e->num_fingers = xhe->num_finger;
2469    e->cx = xhe->cx;
2470    e->cy = xhe->cy;
2471    e->hold_time = xhe->holdtime;
2472
2473    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_HOLD, e, NULL, NULL);
2474 }
2475
2476 void
2477 _ecore_x_event_handle_gesture_notify_group(XEvent *xevent)
2478 {
2479    XGestureNotifyGroupEvent *xge;
2480    Ecore_X_Event_Gesture_Notify_Group *e;
2481
2482    _ecore_x_last_event_mouse_move = 0;
2483    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2484
2485    xge = (XGestureNotifyGroupEvent *)xevent;
2486    e = calloc(1, sizeof(Ecore_X_Event_Gesture_Notify_Group));
2487    if (!e)
2488      return;
2489
2490    e->win = xge->window;
2491    e->time = xge->time;
2492    e->subtype = xge->kind;
2493    e->num_groups = xge->num_group;
2494    e->group_id = xge->groupid;
2495
2496    ecore_event_add(ECORE_X_EVENT_GESTURE_NOTIFY_GROUP, e, NULL, NULL);
2497 }
2498
2499 #endif /* ifdef ECORE_XGESTURE */
2500 #ifdef ECORE_XKB
2501 void
2502 _ecore_x_event_handle_xkb(XEvent *xevent)
2503 {
2504    XkbEvent *xkbev;
2505    Ecore_X_Event_Xkb *e;
2506    
2507    xkbev = (XkbEvent *) xevent;
2508    e = calloc(1, sizeof(Ecore_X_Event_Xkb));
2509    if (!e)
2510      return;
2511    e->group = xkbev->state.group;
2512    if (xkbev->any.xkb_type == XkbStateNotify)
2513      ecore_event_add(ECORE_X_EVENT_XKB_STATE_NOTIFY, e, NULL, NULL);
2514    else if ((xkbev->any.xkb_type == XkbNewKeyboardNotify) ||
2515             (xkbev->any.xkb_type == XkbMapNotify))
2516      {
2517         if (xkbev->any.xkb_type == XkbMapNotify)
2518           {
2519              XkbMapNotifyEvent *xkbmapping;
2520
2521              xkbmapping = (XkbMapNotifyEvent *)xkbev;
2522              XkbRefreshKeyboardMapping(xkbmapping);
2523           }
2524         ecore_event_add(ECORE_X_EVENT_XKB_NEWKBD_NOTIFY, e, NULL, NULL);
2525      }
2526 }
2527 #endif /* ifdef ECORE_XKB */