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