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