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