fba9f14dd235dfbe8c88657a9f7695d0f20375b7
[profile/ivi/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->event_win = xevent->xdestroywindow.event;
838    e->time = _ecore_x_event_last_time;
839    if (e->win == _ecore_x_event_last_win) _ecore_x_event_last_win = 0;
840    ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);   
841 }
842
843 void
844 _ecore_x_event_handle_unmap_notify(XEvent *xevent)
845 {
846    Ecore_X_Event_Window_Hide *e;
847    
848    e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
849    if (!e) return;
850    e->win = xevent->xunmap.window;
851    e->event_win = xevent->xunmap.event;
852    e->time = _ecore_x_event_last_time;
853    ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
854 }
855
856 void
857 _ecore_x_event_handle_map_notify(XEvent *xevent)
858 {
859    Ecore_X_Event_Window_Show *e;
860    
861    e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
862    if (!e) return;
863    e->win = xevent->xmap.window;
864    e->event_win = xevent->xmap.event;
865    e->time = _ecore_x_event_last_time;
866    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
867 }
868
869 void
870 _ecore_x_event_handle_map_request(XEvent *xevent)
871 {
872    Ecore_X_Event_Window_Show_Request *e;
873    
874    e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
875    if (!e) return;
876    e->win = xevent->xmaprequest.window;
877    e->time = _ecore_x_event_last_time;
878    e->parent = xevent->xmaprequest.parent;
879    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
880 }
881
882 void
883 _ecore_x_event_handle_reparent_notify(XEvent *xevent)
884 {
885    Ecore_X_Event_Window_Reparent *e;
886    
887    e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
888    if (!e) return;
889    e->win = xevent->xreparent.window;
890    e->event_win = xevent->xreparent.event;
891    e->parent = xevent->xreparent.parent;
892    e->time = _ecore_x_event_last_time;
893    ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
894 }
895
896 void
897 _ecore_x_event_handle_configure_notify(XEvent *xevent)
898 {
899    Ecore_X_Event_Window_Configure *e;
900    
901    e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
902    if (!e) return;
903    e->win = xevent->xconfigure.window;
904    e->event_win = xevent->xconfigure.event;
905    e->abovewin = xevent->xconfigure.above;
906    e->x = xevent->xconfigure.x;
907    e->y = xevent->xconfigure.y;
908    e->w = xevent->xconfigure.width;
909    e->h = xevent->xconfigure.height;
910    e->border = xevent->xconfigure.border_width;
911    e->override = xevent->xconfigure.override_redirect;
912    e->from_wm = xevent->xconfigure.send_event;
913    e->time = _ecore_x_event_last_time;
914    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);      
915 }
916
917 void
918 _ecore_x_event_handle_configure_request(XEvent *xevent)
919 {
920    Ecore_X_Event_Window_Configure_Request *e;
921
922    e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
923    if (!e) return;
924    e->win = xevent->xconfigurerequest.window;
925    e->parent_win = xevent->xconfigurerequest.parent;
926    e->abovewin = xevent->xconfigurerequest.above;
927    e->x = xevent->xconfigurerequest.x;
928    e->y = xevent->xconfigurerequest.y;
929    e->w = xevent->xconfigurerequest.width;
930    e->h = xevent->xconfigurerequest.height;
931    e->border = xevent->xconfigurerequest.border_width;
932    e->value_mask = xevent->xconfigurerequest.value_mask;
933    e->time = _ecore_x_event_last_time;
934    if (xevent->xconfigurerequest.detail == Above)
935      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
936    else if (xevent->xconfigurerequest.detail == Below)
937      e->detail = ECORE_X_WINDOW_STACK_BELOW;
938    else if (xevent->xconfigurerequest.detail == TopIf)
939      e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
940    else if (xevent->xconfigurerequest.detail == BottomIf)
941      e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
942    else if (xevent->xconfigurerequest.detail == Opposite)
943      e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
944    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
945 }
946
947 void
948 _ecore_x_event_handle_gravity_notify(XEvent *xevent __UNUSED__)
949 {
950    /* FIXME: handle this event type */
951 }
952
953 void
954 _ecore_x_event_handle_resize_request(XEvent *xevent)
955 {
956    Ecore_X_Event_Window_Resize_Request *e;
957
958    e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
959    if (!e) return;
960    e->win = xevent->xresizerequest.window;
961    e->w = xevent->xresizerequest.width;
962    e->h = xevent->xresizerequest.height;
963    e->time = _ecore_x_event_last_time;
964    ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
965 }
966
967 void
968 _ecore_x_event_handle_circulate_notify(XEvent *xevent)
969 {
970    Ecore_X_Event_Window_Stack *e;
971    
972    e = calloc(1, sizeof(Ecore_X_Event_Window_Stack));
973    if (!e) return;
974    e->win = xevent->xcirculate.window;
975    e->event_win = xevent->xcirculate.event;
976    if (xevent->xcirculate.place == PlaceOnTop)
977      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
978    else
979      e->detail = ECORE_X_WINDOW_STACK_BELOW; 
980    e->time = _ecore_x_event_last_time;
981    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
982 }
983
984 void
985 _ecore_x_event_handle_circulate_request(XEvent *xevent)
986 {
987    Ecore_X_Event_Window_Stack_Request *e;
988    
989    e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request));
990    if (!e) return;
991    e->win = xevent->xcirculaterequest.window;
992    e->parent = xevent->xcirculaterequest.parent;
993    if (xevent->xcirculaterequest.place == PlaceOnTop)
994      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
995    else
996      e->detail = ECORE_X_WINDOW_STACK_BELOW; 
997    e->time = _ecore_x_event_last_time;
998    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
999 }
1000
1001 void
1002 _ecore_x_event_handle_property_notify(XEvent *xevent)
1003 {
1004 #if 0 /* for now i disabled this. nice idea though this is - it leaves a lot
1005        * to be desired for efficiency that is better left to the app layer
1006        */
1007    if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLASS)
1008      {
1009         Ecore_X_Event_Window_Prop_Name_Class_Change *e;
1010         
1011         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Name_Class_Change));
1012         if (!e) return;
1013         ecore_x_window_prop_name_class_get(xevent->xproperty.window, 
1014                                            &(e->name), &(e->clas));
1015    e->time = xevent->xproperty.time;
1016    _ecore_x_event_last_time = e->time;
1017         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE, e, _ecore_x_event_free_window_prop_name_class_change, NULL);
1018      }
1019    else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_NAME))
1020      {
1021         Ecore_X_Event_Window_Prop_Title_Change *e;
1022         
1023         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Title_Change));
1024         if (!e) return;
1025         e->title = ecore_x_window_prop_title_get(xevent->xproperty.window);
1026    e->time = xevent->xproperty.time;
1027    _ecore_x_event_last_time = e->time;
1028         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_title_change, NULL);
1029      }
1030    else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_NAME)
1031      {
1032         Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
1033         
1034         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Title_Change));
1035         if (!e) return;
1036         e->title = ecore_x_window_prop_visible_title_get(xevent->xproperty.window);
1037    e->time = xevent->xproperty.time;
1038    _ecore_x_event_last_time = e->time;
1039         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_visible_title_change, NULL);
1040      }
1041    else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_ICON_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_ICON_NAME))
1042      {
1043         Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
1044         
1045         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Icon_Name_Change));
1046         if (!e) return;
1047         e->name = ecore_x_window_prop_icon_name_get(xevent->xproperty.window);
1048    e->time = xevent->xproperty.time;
1049    _ecore_x_event_last_time = e->time;
1050         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_icon_name_change, NULL);
1051      }
1052    else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME)
1053      {
1054         Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
1055         
1056         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change));
1057         if (!e) return;
1058         e->name = ecore_x_window_prop_visible_icon_name_get(xevent->xproperty.window);
1059    e->time = xevent->xproperty.time;
1060    _ecore_x_event_last_time = e->time;
1061         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_visible_icon_name_change, NULL);
1062      }
1063    else if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
1064      {
1065         Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
1066         
1067         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Client_Machine_Change));
1068         if (!e) return;
1069         e->name = ecore_x_window_prop_client_machine_get(xevent->xproperty.window);
1070    e->time = xevent->xproperty.time;
1071    _ecore_x_event_last_time = e->time;
1072         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE, e, _ecore_x_event_free_window_prop_client_machine_change, NULL);
1073      }
1074    else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_PID)
1075      {
1076         Ecore_X_Event_Window_Prop_Pid_Change *e;
1077         
1078         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Pid_Change));
1079         if (!e) return;
1080         e->pid = ecore_x_window_prop_pid_get(xevent->xproperty.window);
1081    e->time = xevent->xproperty.time;
1082    _ecore_x_event_last_time = e->time;
1083         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
1084      }
1085    else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_DESKTOP)
1086      {
1087         Ecore_X_Event_Window_Prop_Desktop_Change *e;
1088         
1089         e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Desktop_Change));
1090         if (!e) return;
1091         e->desktop = ecore_x_window_prop_desktop_get(xevent->xproperty.window);
1092         ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
1093      }
1094    else 
1095 #endif     
1096    {
1097       Ecore_X_Event_Window_Property *e;
1098
1099       e = calloc(1,sizeof(Ecore_X_Event_Window_Property));
1100       if (!e) return;
1101       e->win = xevent->xproperty.window;
1102       e->atom = xevent->xproperty.atom;
1103       e->time = xevent->xproperty.time;
1104       _ecore_x_event_last_time = e->time;
1105       ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
1106    }
1107 }
1108
1109 void
1110 _ecore_x_event_handle_selection_clear(XEvent *xevent)
1111 {
1112    Ecore_X_Selection_Intern *d;
1113    Ecore_X_Event_Selection_Clear *e;
1114    Ecore_X_Atom sel;
1115
1116    if (!(d = _ecore_x_selection_get(xevent->xselectionclear.selection)))
1117      return;
1118    if (xevent->xselectionclear.time > d->time)
1119      {
1120         _ecore_x_selection_set(None, NULL, 0, 
1121                                xevent->xselectionclear.selection);
1122      }
1123
1124    /* Generate event for app cleanup */
1125    e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
1126    e->win = xevent->xselectionclear.window;
1127    e->time = xevent->xselectionclear.time;
1128    sel = xevent->xselectionclear.selection;
1129    if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
1130      e->selection = ECORE_X_SELECTION_PRIMARY;
1131    else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
1132      e->selection = ECORE_X_SELECTION_SECONDARY;
1133    else
1134      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1135    ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
1136
1137 }
1138
1139 void
1140 _ecore_x_event_handle_selection_request(XEvent *xevent)
1141 {
1142    Ecore_X_Event_Selection_Request  *e;
1143    Ecore_X_Selection_Intern         *sd;
1144    void                             *data;
1145
1146    /*
1147     * Generate a selection request event.
1148     */
1149    e = malloc(sizeof(Ecore_X_Event_Selection_Request));
1150    e->owner = xevent->xselectionrequest.owner;
1151    e->requestor = xevent->xselectionrequest.requestor;
1152    e->time = xevent->xselectionrequest.time;
1153    e->selection = xevent->xselectionrequest.selection;
1154    e->target = xevent->xselectionrequest.target;
1155    e->property = xevent->xselectionrequest.property;
1156    ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL);
1157
1158    if ((sd = _ecore_x_selection_get(xevent->xselectionrequest.selection)) &&
1159        (sd->win == xevent->xselectionrequest.owner))
1160      {
1161         Ecore_X_Selection_Intern *si;
1162
1163         si = _ecore_x_selection_get(xevent->xselectionrequest.selection);
1164         if (si->data)
1165           {
1166              Ecore_X_Atom property;
1167
1168              if (!ecore_x_selection_convert(xevent->xselectionrequest.selection,
1169                                             xevent->xselectionrequest.target,
1170                                             &data))
1171                {
1172                   /* Refuse selection, conversion to requested target failed */
1173                   property = None;
1174                }
1175              else
1176                {
1177                   /* FIXME: This does not properly handle large data transfers */
1178                   ecore_x_window_prop_property_set(xevent->xselectionrequest.requestor,
1179                                                    xevent->xselectionrequest.property,
1180                                                    xevent->xselectionrequest.target,
1181                                                    8, data, sd->length);
1182                   property = xevent->xselectionrequest.property;
1183                   free(data);
1184                }
1185
1186              ecore_x_selection_notify_send(xevent->xselectionrequest.requestor,
1187                                            xevent->xselectionrequest.selection,
1188                                            xevent->xselectionrequest.target,
1189                                            property,
1190                                            xevent->xselectionrequest.time);
1191           }
1192      }
1193    return;
1194 }
1195
1196 void
1197 _ecore_x_event_handle_selection_notify(XEvent *xevent)
1198 {
1199    Ecore_X_Event_Selection_Notify   *e;
1200    unsigned char                    *data = NULL;
1201    Ecore_X_Atom                     selection;
1202    int                              num_ret;
1203    int                              format;
1204
1205    selection = xevent->xselection.selection;
1206
1207    if (xevent->xselection.target == ECORE_X_ATOM_SELECTION_TARGETS)
1208      {
1209         format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
1210                                                 xevent->xselection.property,
1211                                                 XA_ATOM, 32, &data, &num_ret);
1212         if (!format)
1213           return;
1214      }
1215    else
1216      {
1217         format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
1218                                                 xevent->xselection.property,
1219                                                 AnyPropertyType, 8, &data,
1220                                                 &num_ret);
1221         if (!format)
1222           return;
1223      }
1224
1225    e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
1226    if (!e) return;
1227    e->win = xevent->xselection.requestor;
1228    e->time = xevent->xselection.time;
1229    e->target = _ecore_x_selection_target_get(xevent->xselection.target);
1230
1231    if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
1232      e->selection = ECORE_X_SELECTION_PRIMARY;
1233    else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
1234      e->selection = ECORE_X_SELECTION_SECONDARY;
1235    else if (selection == ECORE_X_ATOM_SELECTION_XDND)
1236      e->selection = ECORE_X_SELECTION_XDND;
1237    else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1238      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1239    else
1240      {
1241         free(e);
1242         return;
1243      }
1244    e->data = _ecore_x_selection_parse(e->target, data, num_ret, format);
1245
1246    ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, _ecore_x_event_free_selection_notify, NULL);
1247 }
1248
1249 void
1250 _ecore_x_event_handle_colormap_notify(XEvent *xevent)
1251 {
1252    Ecore_X_Event_Window_Colormap *e;
1253
1254    e = calloc(1,sizeof(Ecore_X_Event_Window_Colormap));
1255    if (!e) return;
1256    e->win = xevent->xcolormap.window;
1257    e->cmap = xevent->xcolormap.colormap;
1258    e->time = _ecore_x_event_last_time;
1259    if (xevent->xcolormap.state == ColormapInstalled)
1260       e->installed = 1;
1261    else
1262       e->installed = 0;
1263    ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
1264 }
1265
1266 void
1267 _ecore_x_event_handle_client_message(XEvent *xevent)
1268 {
1269    /* Special client message event handling here. need to put LOTS of if */
1270    /* checks here and generate synthetic events per special message known */
1271    /* otherwise generate generic client message event. this would handle*/
1272    /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
1273    if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS) &&
1274        (xevent->xclient.format == 32) &&
1275        (xevent->xclient.data.l[0] == (long)ECORE_X_ATOM_WM_DELETE_WINDOW))
1276      {
1277         Ecore_X_Event_Window_Delete_Request *e;
1278
1279         e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request));
1280         if (!e) return;
1281         e->win = xevent->xclient.window;
1282         e->time = _ecore_x_event_last_time;
1283         ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
1284      }
1285
1286    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
1287             (xevent->xclient.format == 32) &&
1288             /* Ignore move and resize with keyboard */
1289             (xevent->xclient.data.l[2] < 9))
1290      {
1291         Ecore_X_Event_Window_Move_Resize_Request *e;
1292
1293         e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
1294         if (!e) return;
1295         e->win = xevent->xclient.window;
1296         e->x = xevent->xclient.data.l[0];
1297         e->y = xevent->xclient.data.l[1];
1298         e->direction = xevent->xclient.data.l[2];
1299         e->button = xevent->xclient.data.l[3];
1300         e->source = xevent->xclient.data.l[4];
1301         ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
1302      }
1303
1304    /* Xdnd Client Message Handling Begin */
1305    /* Message Type: XdndEnter target */
1306    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_ENTER)
1307      {
1308         Ecore_X_Event_Xdnd_Enter *e;
1309         Ecore_X_DND_Target *target;
1310         unsigned long three;
1311
1312         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
1313         if (!e) return;
1314
1315         target = _ecore_x_dnd_target_get();
1316         target->state = ECORE_X_DND_TARGET_ENTERED;
1317         target->source = xevent->xclient.data.l[0];
1318         target->win = xevent->xclient.window;
1319         target->version = (int) (xevent->xclient.data.l[1] >> 24);
1320         if (target->version > ECORE_X_DND_VERSION)
1321           {
1322              printf("DND: Requested version %d, we only support up to %d\n", target->version,
1323                                                                              ECORE_X_DND_VERSION);
1324              return;
1325           }
1326
1327         if ((three = xevent->xclient.data.l[1] & 0x1UL))
1328           {
1329              /* source supports more than 3 types, fetch property */
1330              unsigned char *data;
1331              Ecore_X_Atom *types;
1332              int i, num_ret;
1333              if (!(ecore_x_window_prop_property_get(target->source, 
1334                                                     ECORE_X_ATOM_XDND_TYPE_LIST,
1335                                                     XA_ATOM,
1336                                                     32,
1337                                                     &data,
1338                                                     &num_ret)))
1339                {
1340                   printf("DND: Could not fetch data type list from source window, aborting.\n");
1341                   return;
1342                }
1343              types = (Ecore_X_Atom *)data;
1344              e->types = calloc(num_ret, sizeof(char *));
1345              if (e->types)
1346                {
1347                   for (i = 0; i < num_ret; i++)
1348                     e->types[i] = XGetAtomName(_ecore_x_disp, types[i]);
1349                }
1350              e->num_types = num_ret;
1351           }
1352         else
1353           {
1354              int i = 0;
1355
1356              e->types = calloc(3, sizeof(char *));
1357              if (e->types)
1358                {
1359                   while ((i < 3) && (xevent->xclient.data.l[i + 2]))
1360                     {
1361                        e->types[i] = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[i + 2]);
1362                        i++;
1363                     }
1364                }
1365              e->num_types = i;
1366           }
1367
1368         e->win = target->win;
1369         e->source = target->source;
1370         ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, _ecore_x_event_free_xdnd_enter, NULL);
1371      }
1372
1373    /* Message Type: XdndPosition target */
1374    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_POSITION)
1375      {
1376         Ecore_X_Event_Xdnd_Position *e;
1377         Ecore_X_DND_Target *target;
1378
1379         target = _ecore_x_dnd_target_get();
1380         if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
1381             (target->win != xevent->xclient.window))
1382           return;
1383
1384         target->pos.x = xevent->xclient.data.l[2] >> 16;
1385         target->pos.y = xevent->xclient.data.l[2] & 0xFFFFUL;
1386         target->action = xevent->xclient.data.l[4]; /* Version 2 */
1387
1388         target->time = (target->version >= 1) ? 
1389            (Time)xevent->xclient.data.l[3] : CurrentTime;
1390
1391         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
1392         if (!e) return;
1393         e->win = target->win;
1394         e->source = target->source;
1395         e->position.x = target->pos.x;
1396         e->position.y = target->pos.y;
1397         e->action = target->action;
1398         ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
1399      }
1400
1401    /* Message Type: XdndStatus source */
1402    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_STATUS)
1403      {
1404         Ecore_X_Event_Xdnd_Status *e;
1405         Ecore_X_DND_Source *source;
1406
1407         source = _ecore_x_dnd_source_get();
1408         /* Make sure source/target match */
1409         if ((source->win != xevent->xclient.window ) ||
1410             (source->dest != (Window)xevent->xclient.data.l[0]))
1411           return;
1412
1413         source->await_status = 0;
1414
1415         source->will_accept = xevent->xclient.data.l[1] & 0x1UL;
1416         source->suppress = (xevent->xclient.data.l[1] & 0x2UL) ? 0 : 1;
1417
1418         source->rectangle.x = xevent->xclient.data.l[2] >> 16;
1419         source->rectangle.y = xevent->xclient.data.l[2] & 0xFFFFUL;
1420         source->rectangle.width = xevent->xclient.data.l[3] >> 16;
1421         source->rectangle.height = xevent->xclient.data.l[3] & 0xFFFFUL;
1422
1423         source->accepted_action = xevent->xclient.data.l[4];
1424
1425         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
1426         if (!e) return;
1427         e->win = source->win;
1428         e->target = source->dest;
1429         e->will_accept = source->will_accept;
1430         e->rectangle.x = source->rectangle.x;
1431         e->rectangle.y = source->rectangle.y;
1432         e->rectangle.width = source->rectangle.width;
1433         e->rectangle.height = source->rectangle.height;
1434         e->action = source->accepted_action;
1435
1436         ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
1437      }
1438
1439    /* Message Type: XdndLeave target */
1440    /* Pretend the whole thing never happened, sort of */
1441    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_LEAVE)
1442      {
1443         Ecore_X_Event_Xdnd_Leave *e;
1444         Ecore_X_DND_Target *target;
1445
1446         target = _ecore_x_dnd_target_get();
1447         if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
1448             (target->win != xevent->xclient.window))
1449           return;
1450
1451         target->state = ECORE_X_DND_TARGET_IDLE;
1452
1453         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
1454         if (!e) return;
1455         e->win = xevent->xclient.window;
1456         e->source = (Window)xevent->xclient.data.l[0];
1457         ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
1458      }
1459
1460    /* Message Type: XdndDrop target */
1461    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_DROP)
1462      {
1463         Ecore_X_Event_Xdnd_Drop *e;
1464         Ecore_X_DND_Target *target;
1465
1466         target = _ecore_x_dnd_target_get();
1467         /* Match source/target */
1468         if ((target->source != (Window)xevent->xclient.data.l[0]) ||
1469             (target->win != xevent->xclient.window))
1470           return;
1471
1472         target->time = (target->version >= 1) ? 
1473            (Time)xevent->xclient.data.l[2] : _ecore_x_event_last_time;
1474
1475         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
1476         if (!e) return;
1477         e->win = target->win;
1478         e->source = target->source;
1479         e->action = target->action;
1480         e->position.x = target->pos.x;
1481         e->position.y = target->pos.y;
1482         ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
1483      }
1484
1485    /* Message Type: XdndFinished source */
1486    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_FINISHED)
1487      {
1488         Ecore_X_Event_Xdnd_Finished *e;
1489         Ecore_X_DND_Source *source;
1490         int completed = 1;
1491
1492         source = _ecore_x_dnd_source_get();
1493         /* Match source/target */
1494         if ((source->win != xevent->xclient.window) ||
1495             (source->dest != (Window)xevent->xclient.data.l[0]))
1496           return;
1497
1498         if ((source->version < 5) || (xevent->xclient.data.l[1] & 0x1UL))
1499           {
1500              /* Target successfully performed drop action */
1501              ecore_x_selection_xdnd_clear();
1502              source->state = ECORE_X_DND_SOURCE_IDLE;
1503           }
1504         else if (source->version >= 5)
1505           {
1506                completed = 0;
1507                source->state = ECORE_X_DND_SOURCE_CONVERTING;
1508
1509                /* FIXME: Probably need to add a timer to switch back to idle 
1510                 * and discard the selection data */
1511           } 
1512
1513         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished));
1514         if (!e) return;
1515         e->win = source->win;
1516         e->target = source->dest;
1517         e->completed = completed;
1518         if (source->version >= 5)
1519           {
1520              source->accepted_action = xevent->xclient.data.l[2];
1521              e->action = source->accepted_action;
1522           }
1523         else
1524           {
1525              source->accepted_action = 0;
1526              e->action = source->action;
1527           }
1528
1529         ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
1530      }
1531    else if (xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_STATE)
1532      {
1533         Ecore_X_Event_Window_State_Request *e;
1534
1535         e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1536         if (!e) return;
1537         e->win = xevent->xclient.window;
1538         if (xevent->xclient.data.l[0] == 0)
1539           e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
1540         else if (xevent->xclient.data.l[0] == 1)
1541           e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1542         else if (xevent->xclient.data.l[0] == 2)
1543           e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
1544         else
1545           {
1546              free(e);
1547              return;
1548           }
1549         e->state[0] = _ecore_x_netwm_state_get(xevent->xclient.data.l[1]);
1550         if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
1551           {
1552              char *name;
1553              name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[1]);
1554              if (name)
1555                printf("Unknown state: %s\n", name);
1556              XFree(name);
1557           }
1558         e->state[1] = _ecore_x_netwm_state_get(xevent->xclient.data.l[2]);
1559         if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
1560           {
1561              char *name;
1562              name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[2]);
1563              if (name)
1564                printf("Unknown state: %s\n", name);
1565              XFree(name);
1566           }
1567         e->source = xevent->xclient.data.l[3];
1568
1569         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1570      }
1571    else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_CHANGE_STATE)
1572             && (xevent->xclient.format == 32)
1573             && (xevent->xclient.data.l[0] == IconicState))
1574      {
1575         Ecore_X_Event_Window_State_Request *e;
1576
1577         e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1578         if (!e) return;
1579         e->win = xevent->xclient.window;
1580         e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1581         e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
1582
1583         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1584      }
1585    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_DESKTOP)
1586             && (xevent->xclient.format == 32))
1587      {
1588         Ecore_X_Event_Desktop_Change *e;
1589
1590         e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
1591         if (!e) return;
1592         e->win = xevent->xclient.window;
1593         e->desk = xevent->xclient.data.l[0];
1594         e->source = xevent->xclient.data.l[1];
1595
1596         ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
1597      }
1598    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS))
1599      {
1600         Ecore_X_Event_Frame_Extents_Request *e;
1601
1602         e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request));
1603         if (!e) return;
1604         e->win = xevent->xclient.window;
1605
1606         ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
1607      }
1608    else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS)
1609             && ((Ecore_X_Atom)xevent->xclient.data.l[0] == ECORE_X_ATOM_NET_WM_PING)
1610             && (xevent->xclient.format == 32))
1611      {
1612         Ecore_X_Event_Ping *e;
1613
1614         e = calloc(1, sizeof(Ecore_X_Event_Ping));
1615         if (!e) return;
1616         e->win = xevent->xclient.window;
1617         e->time = xevent->xclient.data.l[1];
1618         e->event_win = xevent->xclient.data.l[2];
1619
1620         ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
1621      }
1622    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
1623             (xevent->xclient.format == 8))
1624      {
1625         _ecore_x_netwm_startup_info_begin(xevent->xclient.window, xevent->xclient.data.b);
1626      }
1627    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_STARTUP_INFO) &&
1628             (xevent->xclient.format == 8))
1629      {
1630         _ecore_x_netwm_startup_info(xevent->xclient.window, xevent->xclient.data.b);
1631      }
1632    else if ((xevent->xclient.message_type == 27777)
1633             && (xevent->xclient.data.l[0] == 0x7162534)
1634             && (xevent->xclient.format == 32)
1635             && (xevent->xclient.window == _ecore_x_private_win))
1636      {
1637         /* a grab sync marker */
1638         if (xevent->xclient.data.l[1] == 0x10000001)
1639           _ecore_x_window_grab_remove(xevent->xclient.data.l[2]);
1640         else if (xevent->xclient.data.l[1] == 0x10000002)
1641           _ecore_x_key_grab_remove(xevent->xclient.data.l[2]);
1642      }
1643    else
1644      {
1645         Ecore_X_Event_Client_Message *e;
1646         int i;
1647
1648         e = calloc(1, sizeof(Ecore_X_Event_Client_Message));
1649         if (!e) return;
1650         e->win = xevent->xclient.window;
1651         e->message_type = xevent->xclient.message_type;
1652         e->format = xevent->xclient.format;
1653         for (i = 0; i < 5; i++) 
1654           e->data.l[i] = xevent->xclient.data.l[i];
1655
1656         ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
1657      }
1658 }
1659
1660 void
1661 _ecore_x_event_handle_mapping_notify(XEvent *xevent __UNUSED__)
1662 {
1663    /* FIXME: handle this event type */
1664 }
1665
1666 void
1667 _ecore_x_event_handle_shape_change(XEvent *xevent)
1668 {
1669    XShapeEvent *shape_event;
1670    Ecore_X_Event_Window_Shape *e;
1671    
1672    shape_event = (XShapeEvent *)xevent;
1673    e = calloc(1, sizeof(Ecore_X_Event_Window_Shape));
1674    if (!e) return;
1675    e->win = shape_event->window;
1676    e->time = shape_event->time;
1677    ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
1678 }
1679
1680 void
1681 _ecore_x_event_handle_screensaver_notify(XEvent *xevent)
1682 {
1683 #ifdef ECORE_XSS
1684    XScreenSaverNotifyEvent *screensaver_event;
1685    Ecore_X_Event_Screensaver_Notify *e;
1686    
1687    screensaver_event = (XScreenSaverNotifyEvent *)xevent;
1688    e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify));
1689    if (!e) return;
1690    e->win = screensaver_event->window;
1691    if (screensaver_event->state == ScreenSaverOn)
1692      e->on = 1;
1693   else 
1694      e->on = 0;
1695    e->time = screensaver_event->time;
1696    ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
1697 #else
1698    xevent = NULL;
1699 #endif   
1700 }
1701
1702 void
1703 _ecore_x_event_handle_sync_counter(XEvent *xevent)
1704 {
1705    XSyncCounterNotifyEvent *sync_counter_event;
1706    Ecore_X_Event_Sync_Counter *e;
1707    
1708    sync_counter_event = (XSyncCounterNotifyEvent *)xevent;
1709    e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter));
1710    if (!e) return;
1711    e->time = sync_counter_event->time;
1712    ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
1713 }
1714
1715 void
1716 _ecore_x_event_handle_sync_alarm(XEvent *xevent)
1717 {
1718    XSyncAlarmNotifyEvent *sync_alarm_event;
1719    Ecore_X_Event_Sync_Alarm *e;
1720
1721    sync_alarm_event = (XSyncAlarmNotifyEvent *)xevent;
1722
1723    e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm));
1724    if (!e) return;
1725    e->time = sync_alarm_event->time;
1726    e->alarm = sync_alarm_event->alarm;
1727    ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
1728 }
1729
1730 #ifdef ECORE_XRANDR
1731 void
1732 _ecore_x_event_handle_randr_change(XEvent *xevent)
1733 {
1734    XRRScreenChangeNotifyEvent *randr_event;
1735    Ecore_X_Event_Screen_Change *e;
1736
1737    randr_event = (XRRScreenChangeNotifyEvent *)xevent;
1738    if (!XRRUpdateConfiguration(xevent))
1739      printf("ERROR: Can't update RR config!\n");
1740
1741    e = calloc(1, sizeof(Ecore_X_Event_Screen_Change));
1742    if (!e) return;
1743    e->win = randr_event->window;
1744    e->root = randr_event->root;
1745    e->width = randr_event->width;
1746    e->height = randr_event->height;
1747    ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
1748 }
1749 #endif
1750
1751 #ifdef ECORE_XFIXES
1752 void
1753 _ecore_x_event_handle_fixes_selection_notify(XEvent *event)
1754 {
1755    /* Nothing here yet */
1756    event = NULL;
1757 }
1758 #endif
1759
1760 #ifdef ECORE_XDAMAGE
1761 void
1762 _ecore_x_event_handle_damage_notify(XEvent *event)
1763 {
1764    XDamageNotifyEvent *damage_event;
1765    Ecore_X_Event_Damage *e;
1766
1767    damage_event = (XDamageNotifyEvent *)event;
1768
1769    e = calloc(1, sizeof(Ecore_X_Event_Damage));
1770    if (!e) return;
1771
1772    e->level = damage_event->level;
1773    e->drawable = damage_event->drawable;
1774    e->damage = damage_event->damage;
1775    e->more = damage_event->more;
1776    e->time = damage_event->timestamp;
1777    e->area.x = damage_event->area.x;
1778    e->area.y = damage_event->area.y;
1779    e->area.width = damage_event->area.width;
1780    e->area.height = damage_event->area.height;
1781    e->geometry.x = damage_event->geometry.x;
1782    e->geometry.y = damage_event->geometry.y;
1783    e->geometry.width = damage_event->geometry.width;
1784    e->geometry.height = damage_event->geometry.height;
1785
1786    ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
1787 }
1788 #endif
1789