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