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