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