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