1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif /* ifdef HAVE_CONFIG_H */
4 
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 
9 #include <langinfo.h>
10 
11 #include "Ecore.h"
12 #include "ecore_private.h"
13 #include "ecore_x_private.h"
14 #include "Ecore_X.h"
15 #include "Ecore_X_Atoms.h"
16 
17 /** OpenBSD does not define CODESET
18  * FIXME ??
19  */
20 
21 #ifndef CODESET
22 #define CODESET "INVALID"
23 #endif /* ifndef CODESET */
24 
25 typedef struct _Ecore_X_Mouse_Down_Info
26 {
27    EINA_INLIST;
28    int       dev;
29    Window    last_win;
30    Window    last_last_win;
31    Window    last_event_win;
32    Window    last_last_event_win;
33    Time      last_time;
34    Time      last_last_time;
35    Eina_Bool did_double : 1;
36    Eina_Bool did_triple : 1;
37 } Ecore_X_Mouse_Down_Info;
38 
39 static Eina_Bool               _ecore_x_last_event_mouse_move         = EINA_FALSE;
40 static Ecore_Event            *_ecore_x_last_event_mouse_move_event   = NULL;
41 static Ecore_Event_Mouse_Move *_ecore_x_last_event_mouse_move_event_e = NULL;
42 static Eina_Inlist            *_ecore_x_mouse_down_info_list          = NULL;
43 
44 #ifdef ECORE_XKB
45 static Eina_Hash *emitted_events = NULL;
46 #endif
47 
48 static void
_ecore_x_mouse_down_info_clear(void)49 _ecore_x_mouse_down_info_clear(void)
50 {
51    Eina_Inlist *l = _ecore_x_mouse_down_info_list;
52    Ecore_X_Mouse_Down_Info *info = NULL;
53    while (l)
54      {
55         info = EINA_INLIST_CONTAINER_GET(l, Ecore_X_Mouse_Down_Info);
56         l = eina_inlist_remove(l, l);
57         free(info);
58      }
59    _ecore_x_mouse_down_info_list = NULL;
60 }
61 
62 void
_ecore_x_events_init(void)63 _ecore_x_events_init(void)
64 {
65    //Actually, Nothing to do.
66 #ifdef ECORE_XKB
67    emitted_events = eina_hash_int64_new(NULL);
68 #endif
69 }
70 
71 void
_ecore_x_events_shutdown(void)72 _ecore_x_events_shutdown(void)
73 {
74    _ecore_x_mouse_down_info_clear();
75 #ifdef ECORE_XKB
76    eina_hash_free(emitted_events);
77 #endif
78 }
79 
80 static Ecore_X_Mouse_Down_Info *
_ecore_x_mouse_down_info_get(int dev)81 _ecore_x_mouse_down_info_get(int dev)
82 {
83    Eina_Inlist *l = _ecore_x_mouse_down_info_list;
84    Ecore_X_Mouse_Down_Info *info = NULL;
85 
86    //Return the exist info
87    EINA_INLIST_FOREACH(l, info)
88      if (info->dev == dev) return info;
89 
90    //New Device. Add it.
91    info = calloc(1, sizeof(Ecore_X_Mouse_Down_Info));
92    if (!info) return NULL;
93 
94    info->dev = dev;
95    l = eina_inlist_append(l, (Eina_Inlist *)info);
96    _ecore_x_mouse_down_info_list = l;
97    return info;
98 }
99 
100 static void
_ecore_x_event_free_mouse_move(void * data EINA_UNUSED,void * ev)101 _ecore_x_event_free_mouse_move(void *data EINA_UNUSED,
102                                void *ev)
103 {
104    Ecore_Event_Mouse_Move *e;
105 
106    e = ev;
107    if (_ecore_x_last_event_mouse_move)
108      {
109         _ecore_x_last_event_mouse_move_event = NULL;
110         _ecore_x_last_event_mouse_move_event_e = NULL;
111         _ecore_x_last_event_mouse_move = EINA_FALSE;
112      }
113 
114    free(e);
115 }
116 
117 EAPI void
ecore_x_event_mask_set(Ecore_X_Window w,Ecore_X_Event_Mask mask)118 ecore_x_event_mask_set(Ecore_X_Window w,
119                        Ecore_X_Event_Mask mask)
120 {
121    XWindowAttributes attr;
122    XSetWindowAttributes s_attr;
123 
124    LOGFN;
125 
126    EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
127 
128    if (!w)
129      w = DefaultRootWindow(_ecore_x_disp);
130 
131    memset(&attr, 0, sizeof(XWindowAttributes));
132    XGetWindowAttributes(_ecore_x_disp, w, &attr);
133    if (_ecore_xlib_sync) ecore_x_sync();
134    s_attr.event_mask = mask | attr.your_event_mask;
135    XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
136    if (_ecore_xlib_sync) ecore_x_sync();
137 }
138 
139 EAPI void
ecore_x_event_mask_unset(Ecore_X_Window w,Ecore_X_Event_Mask mask)140 ecore_x_event_mask_unset(Ecore_X_Window w,
141                          Ecore_X_Event_Mask mask)
142 {
143    XWindowAttributes attr;
144    XSetWindowAttributes s_attr;
145 
146    LOGFN;
147 
148    EINA_SAFETY_ON_NULL_RETURN(_ecore_x_disp);
149 
150    if (!w)
151      w = DefaultRootWindow(_ecore_x_disp);
152 
153    memset(&attr, 0, sizeof(XWindowAttributes));
154    XGetWindowAttributes(_ecore_x_disp, w, &attr);
155    if (_ecore_xlib_sync) ecore_x_sync();
156    s_attr.event_mask = attr.your_event_mask & ~mask;
157    XChangeWindowAttributes(_ecore_x_disp, w, CWEventMask, &s_attr);
158    if (_ecore_xlib_sync) ecore_x_sync();
159 }
160 
161 static void
_ecore_x_event_free_xdnd_enter(void * data EINA_UNUSED,void * ev)162 _ecore_x_event_free_xdnd_enter(void *data EINA_UNUSED,
163                                void *ev)
164 {
165    Ecore_X_Event_Xdnd_Enter *e;
166    int i;
167 
168    e = ev;
169    for (i = 0; i < e->num_types; i++)
170      XFree(e->types[i]);
171    free(e->types);
172    free(e);
173 }
174 
175 static void
_ecore_x_event_free_selection_notify(void * data EINA_UNUSED,void * ev)176 _ecore_x_event_free_selection_notify(void *data EINA_UNUSED,
177                                      void *ev)
178 {
179    Ecore_X_Event_Selection_Notify *e;
180    Ecore_X_Selection_Data *sel;
181 
182    e = ev;
183    sel = e->data;
184    if (sel->free)
185      sel->free(sel);
186 
187    free(e->target);
188    free(e);
189 }
190 
191 static unsigned int
_ecore_x_event_modifiers(unsigned int state)192 _ecore_x_event_modifiers(unsigned int state)
193 {
194    unsigned int modifiers = 0;
195 
196    if (state & ECORE_X_MODIFIER_SHIFT)
197      modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
198 
199    if (state & ECORE_X_MODIFIER_CTRL)
200      modifiers |= ECORE_EVENT_MODIFIER_CTRL;
201 
202    if (state & ECORE_X_MODIFIER_ALT)
203      modifiers |= ECORE_EVENT_MODIFIER_ALT;
204 
205    if (state & ECORE_X_MODIFIER_WIN)
206      modifiers |= ECORE_EVENT_MODIFIER_WIN;
207 
208    if (state & ECORE_X_MODIFIER_ALTGR)
209      modifiers |= ECORE_EVENT_MODIFIER_ALTGR;
210 
211    if (state & ECORE_X_LOCK_SCROLL)
212      modifiers |= ECORE_EVENT_LOCK_SCROLL;
213 
214    if (state & ECORE_X_LOCK_NUM)
215      modifiers |= ECORE_EVENT_LOCK_NUM;
216 
217    if (state & ECORE_X_LOCK_CAPS)
218      modifiers |= ECORE_EVENT_LOCK_CAPS;
219 
220    if (state & ECORE_X_LOCK_SHIFT)
221      modifiers |= ECORE_EVENT_LOCK_SHIFT;
222 
223    return modifiers;
224 }
225 
226 void
_ecore_mouse_move(unsigned int timestamp,unsigned int xmodifiers,int x,int y,int x_root,int y_root,unsigned int event_window,unsigned int window,unsigned int root_win,int same_screen,int dev,double radx,double rady,double pressure,double angle,double mx,double my,double mrx,double mry)227 _ecore_mouse_move(unsigned int timestamp,
228                   unsigned int xmodifiers,
229                   int x,
230                   int y,
231                   int x_root,
232                   int y_root,
233                   unsigned int event_window,
234                   unsigned int window,
235                   unsigned int root_win,
236                   int same_screen,
237                   int dev,
238                   double radx,
239                   double rady,
240                   double pressure,
241                   double angle,
242                   double mx,
243                   double my,
244                   double mrx,
245                   double mry)
246 {
247    Ecore_Event_Mouse_Move *e;
248    Ecore_Event *event;
249 
250    e = calloc(1, sizeof(Ecore_Event_Mouse_Move));
251    if (!e)
252      return;
253 
254    e->window = window;
255    e->root_window = root_win;
256    e->timestamp = timestamp;
257    e->same_screen = same_screen;
258    e->event_window = event_window;
259 
260    e->modifiers = _ecore_x_event_modifiers(xmodifiers);
261    e->x = x;
262    e->y = y;
263    e->root.x = x_root;
264    e->root.y = y_root;
265 
266    e->multi.device = dev;
267    e->multi.radius = (radx + rady) / 2;
268    e->multi.radius_x = radx;
269    e->multi.radius_y = rady;
270    e->multi.pressure = pressure;
271    e->multi.angle = angle;
272    e->multi.x = mx;
273    e->multi.y = my;
274    e->multi.root.x = mrx;
275    e->multi.root.y = mry;
276 
277    event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE,
278                            e,
279                            _ecore_x_event_free_mouse_move,
280                            NULL);
281 
282    _ecore_x_event_last_time = timestamp;
283    _ecore_x_event_last_win = window;
284    _ecore_x_event_last_root_x = x_root;
285    _ecore_x_event_last_root_y = y_root;
286 
287    _ecore_x_last_event_mouse_move_event = event;
288    _ecore_x_last_event_mouse_move_event_e = e;
289 }
290 
291 static void
_ecore_x_event_free_axis_update_event(void * data EINA_UNUSED,void * ev)292 _ecore_x_event_free_axis_update_event(void *data EINA_UNUSED, void *ev)
293 {
294    Ecore_Event_Axis_Update *e = ev;
295    if (e) free(e->axis);
296    free(e);
297 }
298 
299 void
_ecore_x_axis_update(Ecore_Window window,Ecore_Window event_window,Ecore_Window root_window,unsigned int timestamp,int devid,int toolid,int naxis,Ecore_Axis * axis)300 _ecore_x_axis_update(Ecore_Window window,
301                      Ecore_Window event_window,
302                      Ecore_Window root_window,
303                      unsigned int timestamp,
304                      int devid,
305                      int toolid,
306                      int naxis,
307                      Ecore_Axis *axis)
308 {
309    Ecore_Event_Axis_Update *e;
310    int i;
311 
312    e = calloc(1, sizeof(Ecore_Event_Axis_Update));
313    if (!e)
314      {
315         if (axis) free(axis);
316         return;
317      }
318 
319    e->window = window;
320    e->event_window = event_window;
321    e->root_window = root_window;
322 
323    e->timestamp = timestamp;
324 
325    e->device = devid;
326    e->toolid = toolid;
327 
328    e->naxis = naxis;
329    e->axis = axis;
330 
331    INF("Axis update [%d] (%d) with %d events:", ECORE_EVENT_AXIS_UPDATE, e->device, e->naxis);
332    for (i = 0; i < naxis; i++)
333      {
334         INF("AXIS %d = %f", e->axis[i].label, e->axis[i].value);
335      }
336 
337    ecore_event_add(ECORE_EVENT_AXIS_UPDATE, e, _ecore_x_event_free_axis_update_event, NULL);
338 
339    _ecore_x_event_last_time = timestamp;
340 }
341 
342 static void
_ecore_key_press(int event,XKeyEvent * xevent)343 _ecore_key_press(int event,
344                  XKeyEvent *xevent)
345 {
346    Ecore_Event_Key *e;
347    char *compose = NULL;
348    char *tmp = NULL;
349    char *keyname;
350    char *key = NULL;
351    char keyname_buffer[256];
352    char compose_buffer[256];
353    KeySym sym, sym2 = 0;
354    XComposeStatus status;
355    int val;
356    int key_len, keyname_len, compose_len;
357 
358    _ecore_x_last_event_mouse_move = EINA_FALSE;
359    sym = _ecore_x_XKeycodeToKeysym(xevent->display, xevent->keycode, 0);
360    keyname = XKeysymToString(sym);
361 
362    if (!keyname)
363      {
364         snprintf(keyname_buffer,
365                  sizeof(keyname_buffer),
366                  "Keycode-%i",
367                  xevent->keycode);
368         keyname = keyname_buffer;
369      }
370 
371    key = NULL;
372    compose = NULL;
373    val = XLookupString(xevent,
374                        compose_buffer,
375                        sizeof(compose_buffer),
376                        &sym2,
377                        &status);
378 
379    if (sym != sym2)
380      key = XKeysymToString(sym2);
381    if (!key)
382      key = keyname;
383 
384    if (val > 0)
385      {
386         compose_buffer[val] = 0;
387         compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8",
388                                    compose_buffer);
389         if (!compose)
390           ERR("Ecore_X cannot convert input key string '%s' to UTF-8. "
391               "Is Eina built with iconv support?", compose_buffer);
392         tmp = compose;
393      }
394 
395    key_len = strlen(key);
396    keyname_len = strlen(keyname);
397    compose_len = (compose) ? strlen(compose) : 0;
398 
399    e = calloc(1, sizeof(Ecore_Event_Key) + key_len + keyname_len +
400               compose_len + 3);
401    if (!e)
402      goto on_error;
403 
404    e->keyname = (char *)(e + 1);
405    e->key = e->keyname + keyname_len + 1;
406    e->compose = (compose) ? e->key + key_len + 1 : NULL;
407    e->string = e->compose;
408 
409    strcpy((char *)e->keyname, keyname);
410    strcpy((char *)e->key, key);
411    if (compose)
412      strcpy((char *)e->compose, compose);
413 
414    e->modifiers = _ecore_x_event_modifiers(xevent->state);
415 
416    e->timestamp = xevent->time;
417    e->window = xevent->subwindow ? xevent->subwindow : xevent->window;
418    e->event_window = xevent->window;
419    e->same_screen = xevent->same_screen;
420    e->root_window = xevent->root;
421    e->keycode = xevent->keycode;
422 
423    ecore_event_add(event, e, NULL, NULL);
424 
425    _ecore_x_event_last_time = e->timestamp;
426 
427 on_error:
428    if (tmp)
429      free(tmp);
430 }
431 
432 Ecore_Event_Mouse_Button *
_ecore_mouse_button(int event,unsigned int timestamp,unsigned int xmodifiers,unsigned int buttons,int x,int y,int x_root,int y_root,unsigned int event_window,unsigned int window,unsigned int root_win,int same_screen,int dev,double radx,double rady,double pressure,double angle,double mx,double my,double mrx,double mry)433 _ecore_mouse_button(int event,
434                     unsigned int timestamp,
435                     unsigned int xmodifiers,
436                     unsigned int buttons,
437                     int x,
438                     int y,
439                     int x_root,
440                     int y_root,
441                     unsigned int event_window,
442                     unsigned int window,
443                     unsigned int root_win,
444                     int same_screen,
445                     int dev,
446                     double radx,
447                     double rady,
448                     double pressure,
449                     double angle,
450                     double mx,
451                     double my,
452                     double mrx,
453                     double mry)
454 {
455    Ecore_Event_Mouse_Button *e;
456 
457    e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
458    if (!e)
459      return NULL;
460 
461    e->window = window;
462    e->root_window = root_win;
463    e->timestamp = timestamp;
464    e->same_screen = same_screen;
465    e->event_window = event_window;
466 
467    e->buttons = buttons;
468    e->modifiers = _ecore_x_event_modifiers(xmodifiers);
469    e->double_click = 0;
470    e->triple_click = 0;
471    e->x = x;
472    e->y = y;
473    e->root.x = x_root;
474    e->root.y = y_root;
475 
476    Ecore_X_Mouse_Down_Info *down_info = _ecore_x_mouse_down_info_get(dev);
477 
478    if (down_info)
479      {
480         //If mouse cancel event occred, should reset down info related with double & triple click
481         if (event == ECORE_EVENT_MOUSE_BUTTON_CANCEL)
482           {
483              down_info->last_win = 0;
484              down_info->last_last_win = 0;
485              down_info->last_event_win = 0;
486              down_info->last_last_event_win = 0;
487              down_info->last_time = 0;
488              down_info->last_last_time = 0;
489              down_info->did_double = EINA_FALSE;
490              down_info->did_triple = EINA_FALSE;
491           }
492         if ((event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
493             down_info->did_triple)
494           {
495              down_info->last_win = 0;
496              down_info->last_last_win = 0;
497              down_info->last_event_win = 0;
498              down_info->last_last_event_win = 0;
499              down_info->last_time = 0;
500              down_info->last_last_time = 0;
501           }
502         if (event_window == window)
503           {
504              if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN)
505                {
506                   //Check Double Clicked
507                   if (((int)(timestamp - down_info->last_time) <=
508                        (int)(1000 * _ecore_x_double_click_time)) &&
509                       (window == down_info->last_win) &&
510                       (event_window == down_info->last_event_win))
511                     {
512                        e->double_click = 1;
513                        down_info->did_double = EINA_TRUE;
514                     }
515                   else
516                     {
517                        down_info->did_double = EINA_FALSE;
518                        down_info->did_triple = EINA_FALSE;
519                     }
520 
521                   //Check Triple Clicked
522                   if (((int)(timestamp - down_info->last_last_time) <=
523                        (int)(2 * 1000 * _ecore_x_double_click_time)) &&
524                       (window == down_info->last_win) &&
525                       (window == down_info->last_last_win) &&
526                       (event_window == down_info->last_event_win) &&
527                       (event_window == down_info->last_last_event_win)
528                       )
529                     {
530                        e->triple_click = 1;
531                        down_info->did_triple = EINA_TRUE;
532                     }
533                   else
534                     {
535                        down_info->did_triple = EINA_FALSE;
536                     }
537                }
538              else if (event == ECORE_EVENT_MOUSE_BUTTON_UP)
539                {
540                   if (down_info->did_double)
541                     e->double_click = 1;
542                   if (down_info->did_triple)
543                     e->triple_click = 1;
544                }
545           }
546      }
547 
548    /* NB: Block commented out as _ecore_x_mouse_up_count appears to have
549     * no use. The variable is also commented out above. This code block is
550     * the only place that this variable is used, and appears to serve no
551     * purpose. - dh
552       if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN
553        && !e->double_click
554        && !e->triple_click)
555       _ecore_x_mouse_up_count = 0;
556     */
557 
558    e->multi.device = dev;
559    e->multi.radius = (radx + rady) / 2;
560    e->multi.radius_x = radx;
561    e->multi.radius_y = rady;
562    e->multi.pressure = pressure;
563    e->multi.angle = angle;
564    e->multi.x = mx;
565    e->multi.y = my;
566    e->multi.root.x = mrx;
567    e->multi.root.y = mry;
568 
569    _ecore_x_event_last_time = e->timestamp;
570    _ecore_x_event_last_win = e->window;
571    _ecore_x_event_last_root_x = x_root;
572    _ecore_x_event_last_root_y = y_root;
573 
574    ecore_event_add(event, e, NULL, NULL);
575 
576    if ((down_info) &&
577        (event == ECORE_EVENT_MOUSE_BUTTON_DOWN) &&
578        (window == event_window) &&
579        (!down_info->did_triple))
580      {
581         down_info->last_last_win = down_info->last_win;
582         down_info->last_win = window;
583         down_info->last_last_event_win = down_info->last_event_win;
584         down_info->last_event_win = event_window;
585         down_info->last_last_time = down_info->last_time;
586         down_info->last_time = timestamp;
587      }
588 
589    return e;
590 }
591 
592 void
_ecore_x_event_handle_any_event(XEvent * xevent)593 _ecore_x_event_handle_any_event(XEvent *xevent)
594 {
595    XEvent *ev = malloc(sizeof(XEvent));
596    if (!ev) return;
597    memcpy(ev, xevent, sizeof(XEvent));
598    ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL);
599 }
600 
601 void
_ecore_x_event_handle_key_press(XEvent * xevent)602 _ecore_x_event_handle_key_press(XEvent *xevent)
603 {
604    _ecore_key_press(ECORE_EVENT_KEY_DOWN, (XKeyEvent *)xevent);
605 }
606 
607 void
_ecore_x_event_handle_key_release(XEvent * xevent)608 _ecore_x_event_handle_key_release(XEvent *xevent)
609 {
610    _ecore_key_press(ECORE_EVENT_KEY_UP, (XKeyEvent *)xevent);
611 }
612 
613 void
_ecore_x_event_handle_button_press(XEvent * xevent)614 _ecore_x_event_handle_button_press(XEvent *xevent)
615 {
616    int i;
617 
618    INF("ButtonEvent:press time=%u x=%d y=%d button=%d", (unsigned int)xevent->xbutton.time, (int)xevent->xbutton.x, (int)xevent->xbutton.y, xevent->xbutton.button);
619 
620    _ecore_x_last_event_mouse_move = EINA_FALSE;
621    if ((xevent->xbutton.button > 3) && (xevent->xbutton.button < 8))
622      {
623         Ecore_Event_Mouse_Wheel *e;
624 
625         e = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
626         if (!e)
627           return;
628 
629         e->timestamp = xevent->xbutton.time;
630         e->modifiers = _ecore_x_event_modifiers(xevent->xbutton.state);
631         switch (xevent->xbutton.button)
632           {
633            case 4: e->direction = 0; e->z = -1; break;
634 
635            case 5: e->direction = 0; e->z = 1; break;
636 
637            case 6: e->direction = 1; e->z = -1; break;
638 
639            case 7: e->direction = 1; e->z = 1; break;
640 
641            default: e->direction = 0; e->z = 0; break;
642           }
643 
644         e->x = xevent->xbutton.x;
645         e->y = xevent->xbutton.y;
646         e->root.x = xevent->xbutton.x_root;
647         e->root.y = xevent->xbutton.y_root;
648 
649         if (xevent->xbutton.subwindow)
650           e->window = xevent->xbutton.subwindow;
651         else
652           e->window = xevent->xbutton.window;
653 
654         e->event_window = xevent->xbutton.window;
655         e->same_screen = xevent->xbutton.same_screen;
656         e->root_window = xevent->xbutton.root;
657 
658         _ecore_x_event_last_time = e->timestamp;
659         _ecore_x_event_last_win = e->window;
660         _ecore_x_event_last_root_x = xevent->xbutton.x_root;
661         _ecore_x_event_last_root_y = xevent->xbutton.y_root;
662         ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
663 
664         for (i = 0; i < _ecore_window_grabs_num; i++)
665           {
666              if ((_ecore_window_grabs[i].win == xevent->xbutton.window) ||
667                  (_ecore_window_grabs[i].win == xevent->xbutton.subwindow))
668                {
669                   Eina_Bool replay = EINA_FALSE;
670 
671                   if (_ecore_window_grab_replay_func)
672                     replay = _ecore_window_grab_replay_func(
673                         _ecore_window_grab_replay_data,
674                         ECORE_EVENT_MOUSE_WHEEL,
675                         e);
676 
677                   if (replay)
678                     XAllowEvents(xevent->xbutton.display,
679                                  ReplayPointer, xevent->xbutton.time);
680                   else
681                     XAllowEvents(xevent->xbutton.display,
682                                  AsyncPointer, xevent->xbutton.time);
683 
684                   break;
685                }
686           }
687      }
688    else
689      {
690         {
691            _ecore_mouse_move(xevent->xbutton.time, xevent->xbutton.state,
692                              xevent->xbutton.x, xevent->xbutton.y,
693                              xevent->xbutton.x_root, xevent->xbutton.y_root,
694                              xevent->xbutton.window,
695                              (xevent->xbutton.subwindow ? xevent->xbutton.
696                               subwindow : xevent->xbutton.window),
697                              xevent->xbutton.root,
698                              xevent->xbutton.same_screen,
699                              0, 1, 1,
700                              1.0, // pressure
701                              0.0, // angle
702                              xevent->xbutton.x, xevent->xbutton.y,
703                              xevent->xbutton.x_root, xevent->xbutton.y_root);
704         }
705         {
706            Ecore_Event_Mouse_Button *e;
707            int event_window;
708            int window;
709 
710            window =
711              (xevent->xbutton.subwindow ? xevent->xbutton.subwindow : xevent->
712               xbutton.window);
713            event_window = xevent->xbutton.window;
714 
715            e = _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN,
716                                    xevent->xbutton.time,
717                                    xevent->xbutton.state,
718                                    xevent->xbutton.button,
719                                    xevent->xbutton.x,
720                                    xevent->xbutton.y,
721                                    xevent->xbutton.x_root,
722                                    xevent->xbutton.y_root,
723                                    event_window,
724                                    window,
725                                    xevent->xbutton.root,
726                                    xevent->xbutton.same_screen,
727                                    0,
728                                    1,
729                                    1,
730                                    1.0,
731 // pressure
732                                    0.0,
733 // angle
734                                    xevent->xbutton.x,
735                                    xevent->xbutton.y,
736                                    xevent->xbutton.x_root,
737                                    xevent->xbutton.y_root);
738            if (e)
739              for (i = 0; i < _ecore_window_grabs_num; i++)
740                {
741                   if ((_ecore_window_grabs[i].win == xevent->xbutton.window) ||
742                       (_ecore_window_grabs[i].win == xevent->xbutton.subwindow))
743                     {
744                        Eina_Bool replay = EINA_FALSE;
745 
746                        if (_ecore_window_grab_replay_func)
747                          replay = _ecore_window_grab_replay_func(
748                              _ecore_window_grab_replay_data,
749                              ECORE_EVENT_MOUSE_BUTTON_DOWN,
750                              e);
751 
752                        if (replay)
753                          XAllowEvents(xevent->xbutton.display,
754                                       ReplayPointer, xevent->xbutton.time);
755                        else
756                          XAllowEvents(xevent->xbutton.display,
757                                       AsyncPointer, xevent->xbutton.time);
758 
759                        break;
760                     }
761                }
762         }
763      }
764 }
765 
766 void
_ecore_x_event_handle_button_release(XEvent * xevent)767 _ecore_x_event_handle_button_release(XEvent *xevent)
768 {
769    _ecore_x_last_event_mouse_move = EINA_FALSE;
770    INF("ButtonEvent:release time=%u x=%d y=%d button=%d", (unsigned int)xevent->xbutton.time, (int)xevent->xbutton.x, (int)xevent->xbutton.y, xevent->xbutton.button);
771    /* filter out wheel buttons */
772    if ((xevent->xbutton.button <= 3) || (xevent->xbutton.button > 7))
773      {
774         _ecore_mouse_move(xevent->xbutton.time, xevent->xbutton.state,
775                           xevent->xbutton.x, xevent->xbutton.y,
776                           xevent->xbutton.x_root, xevent->xbutton.y_root,
777                           xevent->xbutton.window,
778                           (xevent->xbutton.subwindow ? xevent->xbutton.
779                            subwindow : xevent->xbutton.window),
780                           xevent->xbutton.root,
781                           xevent->xbutton.same_screen,
782                           0, 1, 1,
783                           1.0, // pressure
784                           0.0, // angle
785                           xevent->xbutton.x, xevent->xbutton.y,
786                           xevent->xbutton.x_root, xevent->xbutton.y_root);
787 
788         _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP,
789                             xevent->xbutton.time, xevent->xbutton.state,
790                             xevent->xbutton.button,
791                             xevent->xbutton.x, xevent->xbutton.y,
792                             xevent->xbutton.x_root, xevent->xbutton.y_root,
793                             xevent->xbutton.window,
794                             (xevent->xbutton.subwindow ? xevent->xbutton.
795                              subwindow : xevent->xbutton.window),
796                             xevent->xbutton.root,
797                             xevent->xbutton.same_screen,
798                             0, 1, 1,
799                             1.0, // pressure
800                             0.0, // angle
801                             xevent->xbutton.x, xevent->xbutton.y,
802                             xevent->xbutton.x_root, xevent->xbutton.y_root);
803      }
804 }
805 
806 void
_ecore_x_event_handle_motion_notify(XEvent * xevent)807 _ecore_x_event_handle_motion_notify(XEvent *xevent)
808 {
809    if (_ecore_x_last_event_mouse_move)
810      {
811         Ecore_Event_Mouse_Move *e = _ecore_x_last_event_mouse_move_event_e;
812 
813         if ((e) &&
814             (xevent->xmotion.window == e->event_window) &&
815             (xevent->xmotion.root == e->root_window) &&
816             (xevent->xmotion.same_screen == e->same_screen) &&
817             (_ecore_x_event_modifiers(xevent->xmotion.state) == e->modifiers))
818           {
819              if (((xevent->xmotion.subwindow) &&
820                   (xevent->xmotion.subwindow == e->window)) ||
821                  ((!xevent->xmotion.subwindow) &&
822                   (xevent->xmotion.window == e->window)))
823                {
824                   // XXX: shouldn't we store event history in the new event
825                   // with prior x,y,timestamp (all else assumed the same)
826                   ecore_event_del(_ecore_x_last_event_mouse_move_event);
827                   _ecore_x_last_event_mouse_move = EINA_FALSE;
828                   _ecore_x_last_event_mouse_move_event = NULL;
829                }
830           }
831      }
832 
833    _ecore_mouse_move(xevent->xmotion.time, xevent->xmotion.state,
834                      xevent->xmotion.x, xevent->xmotion.y,
835                      xevent->xmotion.x_root, xevent->xmotion.y_root,
836                      xevent->xmotion.window,
837                      (xevent->xmotion.subwindow ? xevent->xmotion.subwindow :
838                       xevent->xmotion.window),
839                      xevent->xmotion.root,
840                      xevent->xmotion.same_screen,
841                      0, 1, 1,
842                      1.0,   // pressure
843                      0.0,   // angle
844                      xevent->xmotion.x, xevent->xmotion.y,
845                      xevent->xmotion.x_root, xevent->xmotion.y_root);
846 
847    _ecore_x_last_event_mouse_move = EINA_TRUE;
848 
849    /* Xdnd handling */
850    _ecore_x_dnd_drag(xevent->xmotion.root,
851                      xevent->xmotion.x_root,
852                      xevent->xmotion.y_root);
853 }
854 
855 void
_ecore_x_event_handle_enter_notify(XEvent * xevent)856 _ecore_x_event_handle_enter_notify(XEvent *xevent)
857 {
858    _ecore_x_last_event_mouse_move = EINA_FALSE;
859    {
860       _ecore_mouse_move(xevent->xcrossing.time, xevent->xcrossing.state,
861                         xevent->xcrossing.x, xevent->xcrossing.y,
862                         xevent->xcrossing.x_root, xevent->xcrossing.y_root,
863                         xevent->xcrossing.window,
864                         (xevent->xcrossing.subwindow ? xevent->xcrossing.
865                          subwindow : xevent->xcrossing.window),
866                         xevent->xcrossing.root,
867                         xevent->xcrossing.same_screen,
868                         0, 1, 1,
869                         1.0, // pressure
870                         0.0, // angle
871                         xevent->xcrossing.x, xevent->xcrossing.y,
872                         xevent->xcrossing.x_root, xevent->xcrossing.y_root);
873    }
874    {
875       Ecore_X_Event_Mouse_In *e;
876 
877       e = calloc(1, sizeof(Ecore_X_Event_Mouse_In));
878       if (!e)
879         return;
880 
881       e->modifiers = _ecore_x_event_modifiers(xevent->xcrossing.state);
882       e->x = xevent->xcrossing.x;
883       e->y = xevent->xcrossing.y;
884       e->root.x = xevent->xcrossing.x_root;
885       e->root.y = xevent->xcrossing.y_root;
886       if (xevent->xcrossing.subwindow)
887         e->win = xevent->xcrossing.subwindow;
888       else
889         e->win = xevent->xcrossing.window;
890 
891       e->same_screen = xevent->xcrossing.same_screen;
892       e->root_win = xevent->xcrossing.root;
893       e->event_win = xevent->xcrossing.window;
894 
895       if (xevent->xcrossing.mode == NotifyNormal)
896         e->mode = ECORE_X_EVENT_MODE_NORMAL;
897       else if (xevent->xcrossing.mode == NotifyGrab)
898         e->mode = ECORE_X_EVENT_MODE_GRAB;
899       else if (xevent->xcrossing.mode == NotifyUngrab)
900         e->mode = ECORE_X_EVENT_MODE_UNGRAB;
901 
902       if (xevent->xcrossing.detail == NotifyAncestor)
903         e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
904       else if (xevent->xcrossing.detail == NotifyVirtual)
905         e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
906       else if (xevent->xcrossing.detail == NotifyInferior)
907         e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
908       else if (xevent->xcrossing.detail == NotifyNonlinear)
909         e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
910       else if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
911         e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
912 
913       e->time = xevent->xcrossing.time;
914       _ecore_x_event_last_time = e->time;
915       ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
916    }
917 }
918 
919 void
_ecore_x_event_handle_leave_notify(XEvent * xevent)920 _ecore_x_event_handle_leave_notify(XEvent *xevent)
921 {
922    _ecore_x_last_event_mouse_move = EINA_FALSE;
923    {
924       _ecore_mouse_move(xevent->xcrossing.time, xevent->xcrossing.state,
925                         xevent->xcrossing.x, xevent->xcrossing.y,
926                         xevent->xcrossing.x_root, xevent->xcrossing.y_root,
927                         xevent->xcrossing.window,
928                         (xevent->xcrossing.subwindow ? xevent->xcrossing.
929                          subwindow : xevent->xcrossing.window),
930                         xevent->xcrossing.root,
931                         xevent->xcrossing.same_screen,
932                         0, 1, 1,
933                         1.0, // pressure
934                         0.0, // angle
935                         xevent->xcrossing.x, xevent->xcrossing.y,
936                         xevent->xcrossing.x_root, xevent->xcrossing.y_root);
937    }
938    {
939       Ecore_X_Event_Mouse_Out *e;
940 
941       e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out));
942       if (!e)
943         return;
944 
945       e->modifiers = _ecore_x_event_modifiers(xevent->xcrossing.state);
946       e->x = xevent->xcrossing.x;
947       e->y = xevent->xcrossing.y;
948       e->root.x = xevent->xcrossing.x_root;
949       e->root.y = xevent->xcrossing.y_root;
950       if (xevent->xcrossing.subwindow)
951         e->win = xevent->xcrossing.subwindow;
952       else
953         e->win = xevent->xcrossing.window;
954 
955       e->same_screen = xevent->xcrossing.same_screen;
956       e->root_win = xevent->xcrossing.root;
957       e->event_win = xevent->xcrossing.window;
958 
959       if (xevent->xcrossing.mode == NotifyNormal)
960         e->mode = ECORE_X_EVENT_MODE_NORMAL;
961       else if (xevent->xcrossing.mode == NotifyGrab)
962         e->mode = ECORE_X_EVENT_MODE_GRAB;
963       else if (xevent->xcrossing.mode == NotifyUngrab)
964         e->mode = ECORE_X_EVENT_MODE_UNGRAB;
965 
966       if (xevent->xcrossing.detail == NotifyAncestor)
967         e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
968       else if (xevent->xcrossing.detail == NotifyVirtual)
969         e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
970       else if (xevent->xcrossing.detail == NotifyInferior)
971         e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
972       else if (xevent->xcrossing.detail == NotifyNonlinear)
973         e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
974       else if (xevent->xcrossing.detail == NotifyNonlinearVirtual)
975         e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
976 
977       e->time = xevent->xcrossing.time;
978       _ecore_x_event_last_time = e->time;
979       _ecore_x_event_last_win = e->win;
980       _ecore_x_event_last_root_x = e->root.x;
981       _ecore_x_event_last_root_y = e->root.y;
982       ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
983    }
984 }
985 
986 void
_ecore_x_event_handle_focus_in(XEvent * xevent)987 _ecore_x_event_handle_focus_in(XEvent *xevent)
988 {
989    Ecore_X_Event_Window_Focus_In *e;
990 
991    _ecore_x_last_event_mouse_move = EINA_FALSE;
992 
993    e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In));
994    if (!e)
995      return;
996 
997    e->win = xevent->xfocus.window;
998 
999    if (xevent->xfocus.mode == NotifyNormal)
1000      e->mode = ECORE_X_EVENT_MODE_NORMAL;
1001    else if (xevent->xfocus.mode == NotifyWhileGrabbed)
1002      e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
1003    else if (xevent->xfocus.mode == NotifyGrab)
1004      e->mode = ECORE_X_EVENT_MODE_GRAB;
1005    else if (xevent->xfocus.mode == NotifyUngrab)
1006      e->mode = ECORE_X_EVENT_MODE_UNGRAB;
1007 
1008    if (xevent->xfocus.detail == NotifyAncestor)
1009      e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
1010    else if (xevent->xfocus.detail == NotifyVirtual)
1011      e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
1012    else if (xevent->xfocus.detail == NotifyInferior)
1013      e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
1014    else if (xevent->xfocus.detail == NotifyNonlinear)
1015      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
1016    else if (xevent->xfocus.detail == NotifyNonlinearVirtual)
1017      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
1018    else if (xevent->xfocus.detail == NotifyPointer)
1019      e->detail = ECORE_X_EVENT_DETAIL_POINTER;
1020    else if (xevent->xfocus.detail == NotifyPointerRoot)
1021      e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
1022    else if (xevent->xfocus.detail == NotifyDetailNone)
1023      e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
1024 
1025    e->time = _ecore_x_event_last_time;
1026    ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
1027 }
1028 
1029 void
_ecore_x_event_handle_focus_out(XEvent * xevent)1030 _ecore_x_event_handle_focus_out(XEvent *xevent)
1031 {
1032    Ecore_X_Event_Window_Focus_Out *e;
1033 
1034    _ecore_x_last_event_mouse_move = EINA_FALSE;
1035 
1036    e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out));
1037    if (!e)
1038      return;
1039 
1040    e->win = xevent->xfocus.window;
1041 
1042    if (xevent->xfocus.mode == NotifyNormal)
1043      e->mode = ECORE_X_EVENT_MODE_NORMAL;
1044    else if (xevent->xfocus.mode == NotifyWhileGrabbed)
1045      e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
1046    else if (xevent->xfocus.mode == NotifyGrab)
1047      e->mode = ECORE_X_EVENT_MODE_GRAB;
1048    else if (xevent->xfocus.mode == NotifyUngrab)
1049      e->mode = ECORE_X_EVENT_MODE_UNGRAB;
1050 
1051    if (xevent->xfocus.detail == NotifyAncestor)
1052      e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
1053    else if (xevent->xfocus.detail == NotifyVirtual)
1054      e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
1055    else if (xevent->xfocus.detail == NotifyInferior)
1056      e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
1057    else if (xevent->xfocus.detail == NotifyNonlinear)
1058      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
1059    else if (xevent->xfocus.detail == NotifyNonlinearVirtual)
1060      e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
1061    else if (xevent->xfocus.detail == NotifyPointer)
1062      e->detail = ECORE_X_EVENT_DETAIL_POINTER;
1063    else if (xevent->xfocus.detail == NotifyPointerRoot)
1064      e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
1065    else if (xevent->xfocus.detail == NotifyDetailNone)
1066      e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
1067 
1068    e->time = _ecore_x_event_last_time;
1069    ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
1070 }
1071 
1072 void
_ecore_x_event_handle_keymap_notify(XEvent * xevent EINA_UNUSED)1073 _ecore_x_event_handle_keymap_notify(XEvent *xevent EINA_UNUSED)
1074 {
1075    _ecore_x_last_event_mouse_move = EINA_FALSE;
1076    /* FIXME: handle this event type */
1077 }
1078 
1079 void
_ecore_x_event_handle_expose(XEvent * xevent)1080 _ecore_x_event_handle_expose(XEvent *xevent)
1081 {
1082    Ecore_X_Event_Window_Damage *e;
1083 
1084    _ecore_x_last_event_mouse_move = EINA_FALSE;
1085    e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
1086    if (!e)
1087      return;
1088 
1089    e->win = xevent->xexpose.window;
1090    e->time = _ecore_x_event_last_time;
1091    e->x = xevent->xexpose.x;
1092    e->y = xevent->xexpose.y;
1093    e->w = xevent->xexpose.width;
1094    e->h = xevent->xexpose.height;
1095    e->count = xevent->xexpose.count;
1096    ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
1097 }
1098 
1099 void
_ecore_x_event_handle_graphics_expose(XEvent * xevent)1100 _ecore_x_event_handle_graphics_expose(XEvent *xevent)
1101 {
1102    Ecore_X_Event_Window_Damage *e;
1103 
1104    _ecore_x_last_event_mouse_move = EINA_FALSE;
1105    e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
1106    if (!e)
1107      return;
1108 
1109    e->win = xevent->xgraphicsexpose.drawable;
1110    e->time = _ecore_x_event_last_time;
1111    e->x = xevent->xgraphicsexpose.x;
1112    e->y = xevent->xgraphicsexpose.y;
1113    e->w = xevent->xgraphicsexpose.width;
1114    e->h = xevent->xgraphicsexpose.height;
1115    e->count = xevent->xgraphicsexpose.count;
1116    ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
1117 }
1118 
1119 void
_ecore_x_event_handle_visibility_notify(XEvent * xevent)1120 _ecore_x_event_handle_visibility_notify(XEvent *xevent)
1121 {
1122    _ecore_x_last_event_mouse_move = EINA_FALSE;
1123 //   if (xevent->xvisibility.state != VisibilityPartiallyObscured)
1124    {
1125       Ecore_X_Event_Window_Visibility_Change *e;
1126 
1127       e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change));
1128       if (!e)
1129         return;
1130 
1131       e->win = xevent->xvisibility.window;
1132       e->time = _ecore_x_event_last_time;
1133       if (xevent->xvisibility.state == VisibilityFullyObscured)
1134         e->fully_obscured = 1;
1135       else
1136         e->fully_obscured = 0;
1137 
1138       ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
1139    }
1140 }
1141 
1142 void
_ecore_x_event_handle_create_notify(XEvent * xevent)1143 _ecore_x_event_handle_create_notify(XEvent *xevent)
1144 {
1145    Ecore_X_Event_Window_Create *e;
1146 
1147    _ecore_x_last_event_mouse_move = EINA_FALSE;
1148    e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
1149    if (!e)
1150      return;
1151 
1152    e->win = xevent->xcreatewindow.window;
1153    e->parent = xevent->xcreatewindow.parent;
1154    if (xevent->xcreatewindow.override_redirect)
1155      e->override = 1;
1156    else
1157      e->override = 0;
1158 
1159    e->x = xevent->xcreatewindow.x;
1160    e->y = xevent->xcreatewindow.y;
1161    e->w = xevent->xcreatewindow.width;
1162    e->h = xevent->xcreatewindow.height;
1163    e->border = xevent->xcreatewindow.border_width;
1164    e->time = _ecore_x_event_last_time;
1165    ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
1166 }
1167 
1168 void
_ecore_x_event_handle_destroy_notify(XEvent * xevent)1169 _ecore_x_event_handle_destroy_notify(XEvent *xevent)
1170 {
1171    Ecore_X_Event_Window_Destroy *e;
1172 
1173    _ecore_x_last_event_mouse_move = EINA_FALSE;
1174    e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy));
1175    if (!e)
1176      return;
1177 
1178    e->win = xevent->xdestroywindow.window;
1179    e->event_win = xevent->xdestroywindow.event;
1180    e->time = _ecore_x_event_last_time;
1181    if (e->win == _ecore_x_event_last_win)
1182      _ecore_x_event_last_win = 0;
1183 
1184    ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
1185    while (_ecore_x_window_grab_remove(e->win, -1, 0, 0));
1186    while (_ecore_x_key_grab_remove(e->win, NULL, 0, 0));
1187 }
1188 
1189 void
_ecore_x_event_handle_unmap_notify(XEvent * xevent)1190 _ecore_x_event_handle_unmap_notify(XEvent *xevent)
1191 {
1192    Ecore_X_Event_Window_Hide *e;
1193 
1194    _ecore_x_last_event_mouse_move = EINA_FALSE;
1195    e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
1196    if (!e)
1197      return;
1198 
1199    e->win = xevent->xunmap.window;
1200    e->event_win = xevent->xunmap.event;
1201    e->time = _ecore_x_event_last_time;
1202    e->send_event = xevent->xunmap.send_event;
1203    ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
1204 }
1205 
1206 void
_ecore_x_event_handle_map_notify(XEvent * xevent)1207 _ecore_x_event_handle_map_notify(XEvent *xevent)
1208 {
1209    Ecore_X_Event_Window_Show *e;
1210 
1211    _ecore_x_last_event_mouse_move = EINA_FALSE;
1212    e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
1213    if (!e)
1214      return;
1215 
1216    e->win = xevent->xmap.window;
1217    e->event_win = xevent->xmap.event;
1218    e->time = _ecore_x_event_last_time;
1219    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
1220 }
1221 
1222 void
_ecore_x_event_handle_map_request(XEvent * xevent)1223 _ecore_x_event_handle_map_request(XEvent *xevent)
1224 {
1225    Ecore_X_Event_Window_Show_Request *e;
1226 
1227    _ecore_x_last_event_mouse_move = EINA_FALSE;
1228    e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
1229    if (!e)
1230      return;
1231 
1232    e->win = xevent->xmaprequest.window;
1233    e->time = _ecore_x_event_last_time;
1234    e->parent = xevent->xmaprequest.parent;
1235    ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
1236 }
1237 
1238 void
_ecore_x_event_handle_reparent_notify(XEvent * xevent)1239 _ecore_x_event_handle_reparent_notify(XEvent *xevent)
1240 {
1241    Ecore_X_Event_Window_Reparent *e;
1242 
1243    _ecore_x_last_event_mouse_move = EINA_FALSE;
1244    e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
1245    if (!e)
1246      return;
1247 
1248    e->win = xevent->xreparent.window;
1249    e->event_win = xevent->xreparent.event;
1250    e->parent = xevent->xreparent.parent;
1251    e->time = _ecore_x_event_last_time;
1252    ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
1253 }
1254 
1255 void
_ecore_x_event_handle_configure_notify(XEvent * xevent)1256 _ecore_x_event_handle_configure_notify(XEvent *xevent)
1257 {
1258    Ecore_X_Event_Window_Configure *e;
1259 
1260    _ecore_x_last_event_mouse_move = EINA_FALSE;
1261    e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
1262    if (!e)
1263      return;
1264 
1265    e->win = xevent->xconfigure.window;
1266    e->event_win = xevent->xconfigure.event;
1267    e->abovewin = xevent->xconfigure.above;
1268    e->x = xevent->xconfigure.x;
1269    e->y = xevent->xconfigure.y;
1270    e->w = xevent->xconfigure.width;
1271    e->h = xevent->xconfigure.height;
1272    e->border = xevent->xconfigure.border_width;
1273    e->override = xevent->xconfigure.override_redirect;
1274    e->from_wm = xevent->xconfigure.send_event;
1275    e->time = _ecore_x_event_last_time;
1276    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
1277 }
1278 
1279 void
_ecore_x_event_handle_configure_request(XEvent * xevent)1280 _ecore_x_event_handle_configure_request(XEvent *xevent)
1281 {
1282    Ecore_X_Event_Window_Configure_Request *e;
1283 
1284    _ecore_x_last_event_mouse_move = EINA_FALSE;
1285    e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
1286    if (!e)
1287      return;
1288 
1289    e->win = xevent->xconfigurerequest.window;
1290    e->parent_win = xevent->xconfigurerequest.parent;
1291    e->abovewin = xevent->xconfigurerequest.above;
1292    e->x = xevent->xconfigurerequest.x;
1293    e->y = xevent->xconfigurerequest.y;
1294    e->w = xevent->xconfigurerequest.width;
1295    e->h = xevent->xconfigurerequest.height;
1296    e->border = xevent->xconfigurerequest.border_width;
1297    e->value_mask = xevent->xconfigurerequest.value_mask;
1298    e->time = _ecore_x_event_last_time;
1299 
1300    if (xevent->xconfigurerequest.detail == Above)
1301      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1302    else if (xevent->xconfigurerequest.detail == Below)
1303      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1304    else if (xevent->xconfigurerequest.detail == TopIf)
1305      e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
1306    else if (xevent->xconfigurerequest.detail == BottomIf)
1307      e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
1308    else if (xevent->xconfigurerequest.detail == Opposite)
1309      e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
1310 
1311    ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
1312 }
1313 
1314 void
_ecore_x_event_handle_gravity_notify(XEvent * xevent EINA_UNUSED)1315 _ecore_x_event_handle_gravity_notify(XEvent *xevent EINA_UNUSED)
1316 {
1317    _ecore_x_last_event_mouse_move = EINA_FALSE;
1318    /* FIXME: handle this event type */
1319 }
1320 
1321 void
_ecore_x_event_handle_resize_request(XEvent * xevent)1322 _ecore_x_event_handle_resize_request(XEvent *xevent)
1323 {
1324    Ecore_X_Event_Window_Resize_Request *e;
1325 
1326    _ecore_x_last_event_mouse_move = EINA_FALSE;
1327    e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
1328    if (!e)
1329      return;
1330 
1331    e->win = xevent->xresizerequest.window;
1332    e->w = xevent->xresizerequest.width;
1333    e->h = xevent->xresizerequest.height;
1334    e->time = _ecore_x_event_last_time;
1335    ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
1336 }
1337 
1338 void
_ecore_x_event_handle_circulate_notify(XEvent * xevent)1339 _ecore_x_event_handle_circulate_notify(XEvent *xevent)
1340 {
1341    Ecore_X_Event_Window_Stack *e;
1342 
1343    _ecore_x_last_event_mouse_move = EINA_FALSE;
1344    e = calloc(1, sizeof(Ecore_X_Event_Window_Stack));
1345    if (!e)
1346      return;
1347 
1348    e->win = xevent->xcirculate.window;
1349    e->event_win = xevent->xcirculate.event;
1350    if (xevent->xcirculate.place == PlaceOnTop)
1351      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1352    else
1353      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1354 
1355    e->time = _ecore_x_event_last_time;
1356    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
1357 }
1358 
1359 void
_ecore_x_event_handle_circulate_request(XEvent * xevent)1360 _ecore_x_event_handle_circulate_request(XEvent *xevent)
1361 {
1362    Ecore_X_Event_Window_Stack_Request *e;
1363 
1364    _ecore_x_last_event_mouse_move = EINA_FALSE;
1365    e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request));
1366    if (!e)
1367      return;
1368 
1369    e->win = xevent->xcirculaterequest.window;
1370    e->parent = xevent->xcirculaterequest.parent;
1371    if (xevent->xcirculaterequest.place == PlaceOnTop)
1372      e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1373    else
1374      e->detail = ECORE_X_WINDOW_STACK_BELOW;
1375 
1376    e->time = _ecore_x_event_last_time;
1377    ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
1378 }
1379 
1380 void
_ecore_x_event_handle_property_notify(XEvent * xevent)1381 _ecore_x_event_handle_property_notify(XEvent *xevent)
1382 {
1383    _ecore_x_last_event_mouse_move = EINA_FALSE;
1384    {
1385       Ecore_X_Event_Window_Property *e;
1386 
1387       e = calloc(1, sizeof(Ecore_X_Event_Window_Property));
1388       if (!e)
1389         return;
1390 
1391       e->win = xevent->xproperty.window;
1392       e->atom = xevent->xproperty.atom;
1393       e->time = xevent->xproperty.time;
1394       e->state = !!xevent->xproperty.state;
1395       _ecore_x_event_last_time = e->time;
1396       ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
1397    }
1398 }
1399 
1400 void
_ecore_x_event_handle_selection_clear(XEvent * xevent)1401 _ecore_x_event_handle_selection_clear(XEvent *xevent)
1402 {
1403    Ecore_X_Selection_Intern *d;
1404    Ecore_X_Event_Selection_Clear *e;
1405    Ecore_X_Atom sel;
1406 
1407    LOGFN;
1408    _ecore_x_last_event_mouse_move = EINA_FALSE;
1409    d = _ecore_x_selection_get(xevent->xselectionclear.selection);
1410    if (d && (xevent->xselectionclear.time <= d->time)) return;
1411 /* errr..... why? paranoia.
1412    if (d && (xevent->xselectionclear.time > d->time))
1413      {
1414         _ecore_x_selection_set(None, NULL, 0,
1415                                xevent->xselectionclear.selection);
1416      }
1417  */
1418 /* Generate event for app cleanup */
1419    e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
1420    e->win = xevent->xselectionclear.window;
1421    e->time = xevent->xselectionclear.time;
1422    e->atom = sel = xevent->xselectionclear.selection;
1423    if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
1424      e->selection = ECORE_X_SELECTION_PRIMARY;
1425    else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
1426      e->selection = ECORE_X_SELECTION_SECONDARY;
1427    else if (sel == ECORE_X_ATOM_SELECTION_XDND)
1428      e->selection = ECORE_X_SELECTION_XDND;
1429    else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1430      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1431    else
1432      e->selection = ECORE_X_SELECTION_OTHER;
1433 
1434    ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
1435 }
1436 
1437 void
_ecore_x_event_handle_selection_request(XEvent * xevent)1438 _ecore_x_event_handle_selection_request(XEvent *xevent)
1439 {
1440    Ecore_X_Event_Selection_Request *e;
1441    Ecore_X_Selection_Intern *sd;
1442    void *data = NULL;
1443    int len;
1444    int typesize;
1445 
1446    LOGFN;
1447    _ecore_x_last_event_mouse_move = EINA_FALSE;
1448    /*
1449     * Generate a selection request event.
1450     */
1451    e = malloc(sizeof(Ecore_X_Event_Selection_Request));
1452    e->owner = xevent->xselectionrequest.owner;
1453    e->requestor = xevent->xselectionrequest.requestor;
1454    e->time = xevent->xselectionrequest.time;
1455    e->selection = xevent->xselectionrequest.selection;
1456    e->target = xevent->xselectionrequest.target;
1457    e->property = xevent->xselectionrequest.property;
1458    ecore_event_add(ECORE_X_EVENT_SELECTION_REQUEST, e, NULL, NULL);
1459 
1460    if ((sd = _ecore_x_selection_get(xevent->xselectionrequest.selection)) &&
1461        (sd->win == xevent->xselectionrequest.owner))
1462      {
1463         Ecore_X_Selection_Intern *si;
1464 
1465         si = _ecore_x_selection_get(xevent->xselectionrequest.selection);
1466         if (si->data)
1467           {
1468              Ecore_X_Atom property = None;
1469              Ecore_X_Atom type;
1470 
1471              /* Set up defaults for strings first */
1472              type = xevent->xselectionrequest.target;
1473              typesize = 8;
1474              len = sd->length;
1475 
1476              if (!ecore_x_selection_convert(xevent->xselectionrequest.selection,
1477                                             xevent->xselectionrequest.target,
1478                                             &data, &len, &type, &typesize))
1479                /* Refuse selection, conversion to requested target failed */
1480                property = None;
1481              else if (data)
1482                {
1483                   /* FIXME: This does not properly handle large data transfers */
1484                   ecore_x_window_prop_property_set(
1485                     xevent->xselectionrequest.requestor,
1486                     xevent->xselectionrequest.
1487                     property,
1488                     type,
1489                     typesize,
1490                     data,
1491                     len);
1492                   property = xevent->xselectionrequest.property;
1493                   free(data);
1494                }
1495 
1496              ecore_x_selection_notify_send(xevent->xselectionrequest.requestor,
1497                                            xevent->xselectionrequest.selection,
1498                                            xevent->xselectionrequest.target,
1499                                            property,
1500                                            xevent->xselectionrequest.time);
1501           }
1502      }
1503 }
1504 
1505 void
_ecore_x_event_handle_selection_notify(XEvent * xevent)1506 _ecore_x_event_handle_selection_notify(XEvent *xevent)
1507 {
1508    Ecore_X_Event_Selection_Notify *e;
1509    unsigned char *data = NULL;
1510    Ecore_X_Atom selection;
1511    int num_ret, format;
1512 
1513    LOGFN;
1514    _ecore_x_last_event_mouse_move = EINA_FALSE;
1515    selection = xevent->xselection.selection;
1516 
1517    if (xevent->xselection.target == ECORE_X_ATOM_SELECTION_TARGETS)
1518      {
1519         format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
1520                                                   xevent->xselection.property,
1521                                                   XA_ATOM, 32, &data, &num_ret);
1522         if (!format)
1523           {
1524              /* fallback if targets handling is not working and try get the
1525               * selection directly */
1526              XConvertSelection(_ecore_x_disp, selection,
1527                                ECORE_X_ATOM_UTF8_STRING,
1528                                selection,
1529                                xevent->xselection.requestor,
1530                                CurrentTime);
1531              if (data) free(data);
1532              return;
1533           }
1534      }
1535    else
1536      {
1537         format = ecore_x_window_prop_property_get(xevent->xselection.requestor,
1538                                                   xevent->xselection.property,
1539                                                   AnyPropertyType, 8, &data,
1540                                                   &num_ret);
1541         if (!format) return;
1542      }
1543 
1544    e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
1545    if (!e)
1546      {
1547         if (data) free(data);
1548         return;
1549      }
1550 
1551    e->win = xevent->xselection.requestor;
1552    e->time = xevent->xselection.time;
1553    e->atom = selection;
1554    e->property = xevent->xselection.property;
1555    e->target = _ecore_x_selection_target_get(xevent->xselection.target);
1556 
1557    if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
1558      e->selection = ECORE_X_SELECTION_PRIMARY;
1559    else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
1560      e->selection = ECORE_X_SELECTION_SECONDARY;
1561    else if (selection == ECORE_X_ATOM_SELECTION_XDND)
1562      e->selection = ECORE_X_SELECTION_XDND;
1563    else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1564      e->selection = ECORE_X_SELECTION_CLIPBOARD;
1565    else
1566      e->selection = ECORE_X_SELECTION_OTHER;
1567 
1568    e->data = _ecore_x_selection_parse(e->target, data, num_ret, format);
1569 
1570    ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e,
1571                    _ecore_x_event_free_selection_notify, NULL);
1572 }
1573 
1574 void
_ecore_x_event_handle_colormap_notify(XEvent * xevent)1575 _ecore_x_event_handle_colormap_notify(XEvent *xevent)
1576 {
1577    Ecore_X_Event_Window_Colormap *e;
1578 
1579    _ecore_x_last_event_mouse_move = EINA_FALSE;
1580    e = calloc(1, sizeof(Ecore_X_Event_Window_Colormap));
1581    if (!e)
1582      return;
1583 
1584    e->win = xevent->xcolormap.window;
1585    e->cmap = xevent->xcolormap.colormap;
1586    e->time = _ecore_x_event_last_time;
1587    if (xevent->xcolormap.state == ColormapInstalled)
1588      e->installed = EINA_TRUE;
1589    else
1590      e->installed = EINA_FALSE;
1591 
1592    ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
1593 }
1594 
1595 void
_ecore_x_event_handle_client_message(XEvent * xevent)1596 _ecore_x_event_handle_client_message(XEvent *xevent)
1597 {
1598    _ecore_x_last_event_mouse_move = EINA_FALSE;
1599    /* Special client message event handling here. need to put LOTS of if */
1600    /* checks here and generate synthetic events per special message known */
1601    /* otherwise generate generic client message event. this would handle*/
1602    /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
1603    if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS) &&
1604        (xevent->xclient.format == 32) &&
1605        (xevent->xclient.data.l[0] == (long)ECORE_X_ATOM_WM_DELETE_WINDOW))
1606      {
1607         Ecore_X_Event_Window_Delete_Request *e;
1608 
1609         e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request));
1610         if (!e)
1611           return;
1612 
1613         e->win = xevent->xclient.window;
1614         e->time = _ecore_x_event_last_time;
1615         ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
1616      }
1617    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
1618             (xevent->xclient.format == 32) &&
1619 /* Ignore move and resize with keyboard */
1620             (xevent->xclient.data.l[2] < 9))
1621      {
1622         Ecore_X_Event_Window_Move_Resize_Request *e;
1623 
1624         e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
1625         if (!e)
1626           return;
1627 
1628         e->win = xevent->xclient.window;
1629         e->x = xevent->xclient.data.l[0];
1630         e->y = xevent->xclient.data.l[1];
1631         e->direction = xevent->xclient.data.l[2];
1632         e->button = xevent->xclient.data.l[3];
1633         e->source = xevent->xclient.data.l[4];
1634         ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
1635      }
1636    /* Xdnd Client Message Handling Begin */
1637    /* Message Type: XdndEnter target */
1638    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_ENTER)
1639      {
1640         Ecore_X_Event_Xdnd_Enter *e;
1641         Ecore_X_DND_Target *target;
1642 
1643         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
1644         if (!e) return;
1645 
1646         LOGFN;
1647 
1648         target = _ecore_x_dnd_target_get();
1649         target->state = ECORE_X_DND_TARGET_ENTERED;
1650         target->source = xevent->xclient.data.l[0];
1651         target->win = xevent->xclient.window;
1652         target->version = (int)(xevent->xclient.data.l[1] >> 24);
1653         if (target->version > ECORE_X_DND_VERSION)
1654           {
1655              WRN("DND: Requested version %d, we only support up to %d",
1656                  target->version, ECORE_X_DND_VERSION);
1657              free(e);
1658              return;
1659           }
1660 
1661         if (xevent->xclient.data.l[1] & 0x1UL)
1662           {
1663              /* source supports more than 3 types, fetch property */
1664              unsigned char *data;
1665              Ecore_X_Atom *types;
1666              int i, num_ret;
1667 
1668              LOGFN;
1669              if (!(ecore_x_window_prop_property_get(target->source,
1670                                                     ECORE_X_ATOM_XDND_TYPE_LIST,
1671                                                     XA_ATOM,
1672                                                     32, &data, &num_ret)))
1673                {
1674                   WRN(
1675                     "DND: Could not fetch data type list from source window, aborting.");
1676                   if (data) free(data);
1677                   free(e);
1678                   return;
1679                }
1680 
1681              types = (Ecore_X_Atom *)data;
1682              e->types = calloc(num_ret, sizeof(char *));
1683              if (e->types)
1684                {
1685                   LOGFN;
1686                   for (i = 0; i < num_ret; i++)
1687                     e->types[i] = XGetAtomName(_ecore_x_disp, types[i]);
1688                }
1689 
1690              e->num_types = num_ret;
1691              if (data) free(data);
1692           }
1693         else
1694           {
1695              int i = 0;
1696 
1697              e->types = calloc(3, sizeof(char *));
1698              if (e->types)
1699                {
1700                   LOGFN;
1701                   while ((i < 3) && (xevent->xclient.data.l[i + 2]))
1702                     {
1703                        e->types[i] = XGetAtomName(_ecore_x_disp,
1704                                                   xevent->xclient.data.l[i + 2]);
1705                        i++;
1706                     }
1707                }
1708 
1709              e->num_types = i;
1710           }
1711 
1712         e->win = target->win;
1713         e->source = target->source;
1714         ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e,
1715                         _ecore_x_event_free_xdnd_enter, NULL);
1716      }
1717    /* Message Type: XdndPosition target */
1718    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_POSITION)
1719      {
1720         Ecore_X_Event_Xdnd_Position *e;
1721         Ecore_X_DND_Target *target;
1722 
1723         LOGFN;
1724 
1725         target = _ecore_x_dnd_target_get();
1726         if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
1727             (target->win != xevent->xclient.window))
1728           return;
1729 
1730         target->pos.x = xevent->xclient.data.l[2] >> 16;
1731         target->pos.y = xevent->xclient.data.l[2] & 0xFFFFUL;
1732         target->action = xevent->xclient.data.l[4]; /* Version 2 */
1733 
1734         target->time = (target->version >= 1) ?
1735           (Time)xevent->xclient.data.l[3] : CurrentTime;
1736 
1737         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
1738         if (!e) return;
1739 
1740         e->win = target->win;
1741         e->source = target->source;
1742         e->position.x = target->pos.x;
1743         e->position.y = target->pos.y;
1744         e->action = target->action;
1745         ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
1746      }
1747    /* Message Type: XdndStatus source */
1748    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_STATUS)
1749      {
1750         Ecore_X_Event_Xdnd_Status *e;
1751         Ecore_X_DND_Source *source;
1752 
1753         LOGFN;
1754 
1755         source = _ecore_x_dnd_source_get();
1756         /* Make sure source/target match */
1757         if ((source->win != xevent->xclient.window) ||
1758             (source->dest != (Window)xevent->xclient.data.l[0]))
1759           return;
1760 
1761         source->await_status = 0;
1762 
1763         source->will_accept = xevent->xclient.data.l[1] & 0x1UL;
1764         source->suppress = (xevent->xclient.data.l[1] & 0x2UL) ? 0 : 1;
1765 
1766         source->rectangle.x = xevent->xclient.data.l[2] >> 16;
1767         source->rectangle.y = xevent->xclient.data.l[2] & 0xFFFFUL;
1768         source->rectangle.width = xevent->xclient.data.l[3] >> 16;
1769         source->rectangle.height = xevent->xclient.data.l[3] & 0xFFFFUL;
1770 
1771         source->accepted_action = xevent->xclient.data.l[4];
1772 
1773         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
1774         if (!e) return;
1775 
1776         e->win = source->win;
1777         e->target = source->dest;
1778         e->will_accept = source->will_accept;
1779         e->rectangle.x = source->rectangle.x;
1780         e->rectangle.y = source->rectangle.y;
1781         e->rectangle.width = source->rectangle.width;
1782         e->rectangle.height = source->rectangle.height;
1783         e->action = source->accepted_action;
1784 
1785         ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
1786      }
1787    /* Message Type: XdndLeave target */
1788    /* Pretend the whole thing never happened, sort of */
1789    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_LEAVE)
1790      {
1791         Ecore_X_Event_Xdnd_Leave *e;
1792         Ecore_X_DND_Target *target;
1793 
1794         LOGFN;
1795 
1796         target = _ecore_x_dnd_target_get();
1797         if ((target->source != (Ecore_X_Window)xevent->xclient.data.l[0]) ||
1798             (target->win != xevent->xclient.window))
1799           return;
1800 
1801         target->state = ECORE_X_DND_TARGET_IDLE;
1802 
1803         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
1804         if (!e) return;
1805 
1806         e->win = xevent->xclient.window;
1807         e->source = (Window)xevent->xclient.data.l[0];
1808         ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
1809      }
1810    /* Message Type: XdndDrop target */
1811    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_DROP)
1812      {
1813         Ecore_X_Event_Xdnd_Drop *e;
1814         Ecore_X_DND_Target *target;
1815 
1816         LOGFN;
1817 
1818         target = _ecore_x_dnd_target_get();
1819         /* Match source/target */
1820         if ((target->source != (Window)xevent->xclient.data.l[0]) ||
1821             (target->win != xevent->xclient.window))
1822           return;
1823 
1824         target->time = (target->version >= 1) ?
1825           (Time)xevent->xclient.data.l[2] : _ecore_x_event_last_time;
1826 
1827         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
1828         if (!e) return;
1829 
1830         e->win = target->win;
1831         e->source = target->source;
1832         e->action = target->action;
1833         e->position.x = target->pos.x;
1834         e->position.y = target->pos.y;
1835         ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
1836      }
1837    /* Message Type: XdndFinished source */
1838    else if (xevent->xclient.message_type == ECORE_X_ATOM_XDND_FINISHED)
1839      {
1840         Ecore_X_Event_Xdnd_Finished *e;
1841         Ecore_X_DND_Source *source;
1842         Eina_Bool completed = EINA_TRUE;
1843 
1844         LOGFN;
1845 
1846         source = _ecore_x_dnd_source_get();
1847         /* Match source/target */
1848         if ((source->win != xevent->xclient.window) ||
1849             (source->dest != (Window)xevent->xclient.data.l[0]))
1850           return;
1851 
1852         if ((source->version < 5) || (xevent->xclient.data.l[1] & 0x1UL))
1853           {
1854              LOGFN;
1855              /* Target successfully performed drop action */
1856              ecore_x_selection_xdnd_clear();
1857              source->state = ECORE_X_DND_SOURCE_IDLE;
1858           }
1859         else if (source->version >= 5)
1860           {
1861              completed = EINA_FALSE;
1862              source->state = ECORE_X_DND_SOURCE_CONVERTING;
1863 
1864              /* FIXME: Probably need to add a timer to switch back to idle
1865               * and discard the selection data */
1866           }
1867 
1868         e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished));
1869         if (!e) return;
1870 
1871         e->win = source->win;
1872         e->target = source->dest;
1873         e->completed = completed;
1874         if (source->version >= 5)
1875           {
1876              source->accepted_action = xevent->xclient.data.l[2];
1877              e->action = source->accepted_action;
1878           }
1879         else
1880           {
1881              source->accepted_action = 0;
1882              e->action = source->action;
1883           }
1884 
1885         ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
1886      }
1887    else if (xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_STATE)
1888      {
1889         Ecore_X_Event_Window_State_Request *e;
1890 
1891         e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1892         if (!e) return;
1893 
1894         e->win = xevent->xclient.window;
1895         if (xevent->xclient.data.l[0] == 0)
1896           e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
1897         else if (xevent->xclient.data.l[0] == 1)
1898           e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1899         else if (xevent->xclient.data.l[0] == 2)
1900           e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
1901         else
1902           {
1903              free(e);
1904              return;
1905           }
1906 
1907         LOGFN;
1908         e->state[0] = _ecore_x_netwm_state_get(xevent->xclient.data.l[1]);
1909         if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
1910           {
1911 //	     char *name;
1912              LOGFN;
1913 
1914 //	     name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[1]);
1915 //	     if (name) ERR("Unknown state: %s", name);
1916 //	     XFree(name);
1917           }
1918         e->state[1] = _ecore_x_netwm_state_get(xevent->xclient.data.l[2]);
1919         if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
1920           {
1921 //	     char *name;
1922              LOGFN;
1923 
1924 //	     name = XGetAtomName(_ecore_x_disp, xevent->xclient.data.l[2]);
1925 //	     if (name) ERR("Unknown state: %s", name);
1926 //	     XFree(name);
1927           }
1928 
1929         e->source = xevent->xclient.data.l[3];
1930 
1931         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1932      }
1933    else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_CHANGE_STATE)
1934             && (xevent->xclient.format == 32)
1935             && (xevent->xclient.data.l[0] == IconicState))
1936      {
1937         Ecore_X_Event_Window_State_Request *e;
1938 
1939         e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1940         if (!e)
1941           return;
1942 
1943         e->win = xevent->xclient.window;
1944         e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1945         e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
1946 
1947         ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1948      }
1949    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_WM_DESKTOP)
1950             && (xevent->xclient.format == 32))
1951      {
1952         Ecore_X_Event_Desktop_Change *e;
1953 
1954         e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
1955         if (!e)
1956           return;
1957 
1958         e->win = xevent->xclient.window;
1959         e->desk = xevent->xclient.data.l[0];
1960         e->source = xevent->xclient.data.l[1];
1961 
1962         ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
1963      }
1964    else if (xevent->xclient.message_type ==
1965             ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS)
1966      {
1967         Ecore_X_Event_Frame_Extents_Request *e;
1968 
1969         e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request));
1970         if (!e)
1971           return;
1972 
1973         e->win = xevent->xclient.window;
1974 
1975         ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
1976      }
1977    else if ((xevent->xclient.message_type == ECORE_X_ATOM_WM_PROTOCOLS)
1978             && ((Ecore_X_Atom)xevent->xclient.data.l[0] ==
1979                 ECORE_X_ATOM_NET_WM_PING)
1980             && (xevent->xclient.format == 32))
1981      {
1982         Ecore_X_Event_Ping *e;
1983         Ecore_X_Window root = 0;
1984 
1985         e = calloc(1, sizeof(Ecore_X_Event_Ping));
1986         if (!e)
1987           return;
1988 
1989         e->win = xevent->xclient.window;
1990         e->time = xevent->xclient.data.l[1];
1991         e->event_win = xevent->xclient.data.l[2];
1992 
1993         /* send a reply anyway - we are alive... eventloop at least */
1994         ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
1995         if (ScreenCount(_ecore_x_disp) > 1)
1996           {
1997              LOGFN;
1998              root = ecore_x_window_root_get(e->win);
1999           }
2000         else
2001           root = DefaultRootWindow(_ecore_x_disp);
2002 
2003         if (xevent->xclient.window != root)
2004           {
2005              xevent->xclient.window = root;
2006              XSendEvent(_ecore_x_disp, root, False,
2007                         SubstructureRedirectMask | SubstructureNotifyMask,
2008                         xevent);
2009              if (_ecore_xlib_sync) ecore_x_sync();
2010           }
2011      }
2012    else if ((xevent->xclient.message_type ==
2013              ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
2014             (xevent->xclient.format == 8))
2015      _ecore_x_netwm_startup_info_begin(xevent->xclient.window,
2016                                        xevent->xclient.data.b);
2017    else if ((xevent->xclient.message_type == ECORE_X_ATOM_NET_STARTUP_INFO) &&
2018             (xevent->xclient.format == 8))
2019      _ecore_x_netwm_startup_info(xevent->xclient.window,
2020                                  xevent->xclient.data.b);
2021    else if ((xevent->xclient.message_type == 27777)
2022             && (xevent->xclient.data.l[0] == 0x7162534)
2023             && (xevent->xclient.format == 32)
2024             && (xevent->xclient.window == _ecore_x_private_win))
2025      {
2026         int val = xevent->xclient.data.l[1] & 0xff;
2027         int anymod = (xevent->xclient.data.l[1] >> 8) & 0xff;
2028         int mod = xevent->xclient.data.l[4];
2029         int b = xevent->xclient.data.l[3];
2030         Ecore_X_Window swin = xevent->xclient.data.l[2];
2031 
2032         /* a grab sync marker */
2033         if (val == 1)
2034           {
2035              _ecore_x_window_grab_remove(swin, b, mod, anymod);
2036           }
2037         else if (val == 2)
2038           {
2039              const char *str;
2040 
2041              str = ecore_x_keysym_string_get(b);
2042              if (str) _ecore_x_key_grab_remove(swin, str, mod, anymod);
2043           }
2044      }
2045    else
2046      {
2047         Ecore_X_Event_Client_Message *e;
2048         int i;
2049 
2050         e = calloc(1, sizeof(Ecore_X_Event_Client_Message));
2051         if (!e)
2052           return;
2053 
2054         e->win = xevent->xclient.window;
2055         e->message_type = xevent->xclient.message_type;
2056         e->format = xevent->xclient.format;
2057         e->time = _ecore_x_event_last_time;
2058         for (i = 0; i < 5; i++)
2059           e->data.l[i] = xevent->xclient.data.l[i];
2060 
2061         ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
2062      }
2063 }
2064 
2065 void
_ecore_x_event_handle_mapping_notify(XEvent * xevent)2066 _ecore_x_event_handle_mapping_notify(XEvent *xevent)
2067 {
2068    Ecore_X_Event_Mapping_Change *e;
2069    static unsigned long last_serial;
2070    int type;
2071 
2072    _ecore_x_last_event_mouse_move = EINA_FALSE;
2073 
2074    switch (xevent->xmapping.request)
2075      {
2076       case MappingModifier:
2077         type = ECORE_X_MAPPING_MODIFIER;
2078         break;
2079 
2080       case MappingKeyboard:
2081         if ((last_serial && (xevent->xmapping.serial == last_serial))) return;
2082         type = ECORE_X_MAPPING_KEYBOARD;
2083         last_serial = xevent->xmapping.serial;
2084         break;
2085 
2086       case MappingPointer:
2087       default:
2088         type = ECORE_X_MAPPING_MOUSE;
2089         break;
2090      }
2091 
2092    _ecore_x_window_grab_suspend();
2093    _ecore_x_key_grab_suspend();
2094 
2095    XRefreshKeyboardMapping((XMappingEvent *)xevent);
2096    _ecore_x_modifiers_get();
2097 
2098    _ecore_x_window_grab_resume();
2099    _ecore_x_key_grab_resume();
2100    e = calloc(1, sizeof(Ecore_X_Event_Mapping_Change));
2101    if (!e) return;
2102    e->type = type;
2103    e->keycode = xevent->xmapping.first_keycode;
2104    e->num = xevent->xmapping.count;
2105    ecore_event_add(ECORE_X_EVENT_MAPPING_CHANGE, e, NULL, NULL);
2106 }
2107 
2108 void
_ecore_x_event_handle_shape_change(XEvent * xevent)2109 _ecore_x_event_handle_shape_change(XEvent *xevent)
2110 {
2111    XShapeEvent *shape_event;
2112    Ecore_X_Event_Window_Shape *e;
2113 
2114    _ecore_x_last_event_mouse_move = EINA_FALSE;
2115    shape_event = (XShapeEvent *)xevent;
2116    e = calloc(1, sizeof(Ecore_X_Event_Window_Shape));
2117    if (!e)
2118      return;
2119 
2120    e->win = shape_event->window;
2121    e->time = shape_event->time;
2122    switch (shape_event->kind)
2123      {
2124       case ShapeBounding:
2125         e->type = ECORE_X_SHAPE_BOUNDING;
2126         break;
2127 
2128       case ShapeClip:
2129         e->type = ECORE_X_SHAPE_CLIP;
2130         break;
2131 
2132       case ShapeInput:
2133         e->type = ECORE_X_SHAPE_INPUT;
2134         break;
2135 
2136       default:
2137         break;
2138      }
2139    e->x = shape_event->x;
2140    e->y = shape_event->y;
2141    e->w = shape_event->width;
2142    e->h = shape_event->height;
2143    e->shaped = shape_event->shaped;
2144    ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
2145 }
2146 
2147 void
_ecore_x_event_handle_screensaver_notify(XEvent * xevent)2148 _ecore_x_event_handle_screensaver_notify(XEvent *xevent)
2149 {
2150 #ifdef ECORE_XSS
2151    XScreenSaverNotifyEvent *screensaver_event;
2152    Ecore_X_Event_Screensaver_Notify *e;
2153 
2154    _ecore_x_last_event_mouse_move = EINA_FALSE;
2155    screensaver_event = (XScreenSaverNotifyEvent *)xevent;
2156    e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify));
2157    if (!e)
2158      return;
2159 
2160    e->win = screensaver_event->window;
2161    if ((screensaver_event->state == ScreenSaverOn) ||
2162        (screensaver_event->state == ScreenSaverCycle))
2163      e->on = EINA_TRUE;
2164    else
2165      e->on = EINA_FALSE;
2166 
2167    e->time = screensaver_event->time;
2168    ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
2169 #else /* ifdef ECORE_XSS */
2170    (void) xevent;
2171 #endif /* ifdef ECORE_XSS */
2172 }
2173 
2174 void
_ecore_x_event_handle_sync_counter(XEvent * xevent)2175 _ecore_x_event_handle_sync_counter(XEvent *xevent)
2176 {
2177    XSyncCounterNotifyEvent *sync_counter_event;
2178    Ecore_X_Event_Sync_Counter *e;
2179 
2180    _ecore_x_last_event_mouse_move = EINA_FALSE;
2181    sync_counter_event = (XSyncCounterNotifyEvent *)xevent;
2182    e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter));
2183    if (!e)
2184      return;
2185 
2186    e->time = sync_counter_event->time;
2187    ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
2188 }
2189 
2190 void
_ecore_x_event_handle_sync_alarm(XEvent * xevent)2191 _ecore_x_event_handle_sync_alarm(XEvent *xevent)
2192 {
2193    XSyncAlarmNotifyEvent *sync_alarm_event;
2194    Ecore_X_Event_Sync_Alarm *e;
2195 
2196    _ecore_x_last_event_mouse_move = EINA_FALSE;
2197    sync_alarm_event = (XSyncAlarmNotifyEvent *)xevent;
2198 
2199    e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm));
2200    if (!e)
2201      return;
2202 
2203    e->time = sync_alarm_event->time;
2204    e->alarm = sync_alarm_event->alarm;
2205    ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
2206 }
2207 
2208 #ifdef ECORE_XRANDR
2209 void
_ecore_x_event_handle_randr_change(XEvent * xevent)2210 _ecore_x_event_handle_randr_change(XEvent *xevent)
2211 {
2212    XRRScreenChangeNotifyEvent *randr_event;
2213    Ecore_X_Event_Screen_Change *e;
2214 
2215    _ecore_x_last_event_mouse_move = EINA_FALSE;
2216    randr_event = (XRRScreenChangeNotifyEvent *)xevent;
2217    if (!XRRUpdateConfiguration(xevent))
2218      ERR("Can't update RR config!");
2219 
2220    e = calloc(1, sizeof(Ecore_X_Event_Screen_Change));
2221    if (!e)
2222      return;
2223 
2224    e->win = randr_event->window;
2225    e->root = randr_event->root;
2226    e->size.width = randr_event->width;
2227    e->size.height = randr_event->height;
2228    e->time = randr_event->timestamp;
2229    e->config_time = randr_event->config_timestamp;
2230    e->size.width_mm = randr_event->mwidth;
2231    e->size.height_mm = randr_event->mheight;
2232    e->orientation = randr_event->rotation;
2233    e->subpixel_order = randr_event->subpixel_order;
2234    ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
2235 }
2236 
2237 static void
_ecore_x_event_handle_randr_notify_crtc_change(const XRRNotifyEvent * xevent)2238 _ecore_x_event_handle_randr_notify_crtc_change(const XRRNotifyEvent *xevent)
2239 {
2240    const XRRCrtcChangeNotifyEvent *randr_event;
2241    Ecore_X_Event_Randr_Crtc_Change *e;
2242 
2243    randr_event = (const XRRCrtcChangeNotifyEvent *)xevent;
2244 
2245    e = calloc(1, sizeof(Ecore_X_Event_Randr_Crtc_Change));
2246    if (!e)
2247      return;
2248 
2249    e->win = randr_event->window;
2250    e->crtc = randr_event->crtc;
2251    e->mode = randr_event->mode;
2252    e->orientation = randr_event->rotation;
2253    e->geo.x = randr_event->x;
2254    e->geo.y = randr_event->y;
2255    e->geo.w = randr_event->width;
2256    e->geo.h = randr_event->height;
2257    ecore_event_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, e, NULL, NULL);
2258 }
2259 
2260 static void
_ecore_x_event_handle_randr_notify_output_change(const XRRNotifyEvent * xevent)2261 _ecore_x_event_handle_randr_notify_output_change(const XRRNotifyEvent *xevent)
2262 {
2263    const XRROutputChangeNotifyEvent *randr_event;
2264    Ecore_X_Event_Randr_Output_Change *e;
2265 
2266    randr_event = (const XRROutputChangeNotifyEvent *)xevent;
2267 
2268    e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Change));
2269    if (!e)
2270      return;
2271 
2272    e->win = randr_event->window;
2273    e->output = randr_event->output;
2274    e->crtc = randr_event->crtc;
2275    e->mode = randr_event->mode;
2276    e->orientation = randr_event->rotation;
2277    e->connection = randr_event->connection;
2278    e->subpixel_order = randr_event->subpixel_order;
2279    ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, e, NULL, NULL);
2280 }
2281 
2282 static void
_ecore_x_event_handle_randr_notify_output_property(const XRRNotifyEvent * xevent)2283 _ecore_x_event_handle_randr_notify_output_property(const XRRNotifyEvent *xevent)
2284 {
2285    const XRROutputPropertyNotifyEvent *randr_event;
2286    Ecore_X_Event_Randr_Output_Property_Notify *e;
2287 
2288    randr_event = (const XRROutputPropertyNotifyEvent *)xevent;
2289 
2290    e = calloc(1, sizeof(Ecore_X_Event_Randr_Output_Property_Notify));
2291    if (!e)
2292      return;
2293 
2294    e->win = randr_event->window;
2295    e->output = randr_event->output;
2296    e->property = randr_event->property;
2297    e->time = randr_event->timestamp;
2298    if (randr_event->state == PropertyNewValue)
2299      e->state = ECORE_X_RANDR_PROPERTY_CHANGE_ADD;
2300    else
2301      e->state = ECORE_X_RANDR_PROPERTY_CHANGE_DEL;
2302    ecore_event_add(ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, e, NULL, NULL);
2303 }
2304 
2305 void
_ecore_x_event_handle_randr_notify(XEvent * xevent)2306 _ecore_x_event_handle_randr_notify(XEvent *xevent)
2307 {
2308    const XRRNotifyEvent *randr_event;
2309 
2310    _ecore_x_last_event_mouse_move = EINA_FALSE;
2311    randr_event = (const XRRNotifyEvent *)xevent;
2312    LOGFN;
2313    switch (randr_event->subtype)
2314      {
2315       case RRNotify_CrtcChange:
2316         _ecore_x_event_handle_randr_notify_crtc_change(randr_event);
2317         break;
2318 
2319       case RRNotify_OutputChange:
2320         _ecore_x_event_handle_randr_notify_output_change(randr_event);
2321         break;
2322 
2323       case RRNotify_OutputProperty:
2324         _ecore_x_event_handle_randr_notify_output_property(randr_event);
2325         break;
2326 
2327       default:
2328         ERR("Unknown XRandR RRNotify subtype: %d.",
2329             randr_event->subtype);
2330         break;
2331      }
2332 }
2333 
2334 #endif /* ifdef ECORE_XRANDR */
2335 
2336 #ifdef ECORE_XFIXES
2337 void
_ecore_x_event_handle_fixes_selection_notify(XEvent * event)2338 _ecore_x_event_handle_fixes_selection_notify(XEvent *event)
2339 {
2340    XFixesSelectionNotifyEvent *notify_event =
2341      (XFixesSelectionNotifyEvent *)event;
2342    Ecore_X_Event_Fixes_Selection_Notify *e;
2343    Ecore_X_Atom sel;
2344 
2345    _ecore_x_last_event_mouse_move = EINA_FALSE;
2346    /* Nothing here yet */
2347 
2348    e = calloc(1, sizeof(*e));
2349    if (!e)
2350      return;
2351 
2352    e->win = notify_event->window;
2353    e->owner = notify_event->owner;
2354    e->time = notify_event->timestamp;
2355    e->selection_time = notify_event->selection_timestamp;
2356    e->atom = sel = notify_event->selection;
2357    if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
2358      e->selection = ECORE_X_SELECTION_PRIMARY;
2359    else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
2360      e->selection = ECORE_X_SELECTION_SECONDARY;
2361    else if (sel == ECORE_X_ATOM_SELECTION_XDND)
2362      e->selection = ECORE_X_SELECTION_XDND;
2363    else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
2364      e->selection = ECORE_X_SELECTION_CLIPBOARD;
2365    else
2366      e->selection = ECORE_X_SELECTION_OTHER;
2367    e->reason = notify_event->subtype;
2368 
2369    ecore_event_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY, e, NULL, NULL);
2370 }
2371 
2372 #endif /* ifdef ECORE_XFIXES */
2373 
2374 #ifdef ECORE_XDAMAGE
2375 void
_ecore_x_event_handle_damage_notify(XEvent * event)2376 _ecore_x_event_handle_damage_notify(XEvent *event)
2377 {
2378    XDamageNotifyEvent *damage_event;
2379    Ecore_X_Event_Damage *e;
2380 
2381    _ecore_x_last_event_mouse_move = EINA_FALSE;
2382    damage_event = (XDamageNotifyEvent *)event;
2383 
2384    e = calloc(1, sizeof(Ecore_X_Event_Damage));
2385    if (!e)
2386      return;
2387 
2388    e->level = damage_event->level;
2389    e->drawable = damage_event->drawable;
2390    e->damage = damage_event->damage;
2391    e->more = damage_event->more;
2392    e->time = damage_event->timestamp;
2393    e->area.x = damage_event->area.x;
2394    e->area.y = damage_event->area.y;
2395    e->area.width = damage_event->area.width;
2396    e->area.height = damage_event->area.height;
2397    e->geometry.x = damage_event->geometry.x;
2398    e->geometry.y = damage_event->geometry.y;
2399    e->geometry.width = damage_event->geometry.width;
2400    e->geometry.height = damage_event->geometry.height;
2401 
2402    ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
2403 }
2404 
2405 #endif /* ifdef ECORE_XDAMAGE */
2406 
2407 static void
_ecore_x_event_free_generic_event(void * data,void * ev)2408 _ecore_x_event_free_generic_event(void *data,
2409                                   void *ev)
2410 {
2411    Ecore_X_Event_Generic *e = (Ecore_X_Event_Generic *)ev;
2412 
2413    if (data)
2414      {
2415         if (e->data)
2416           XFreeEventData(_ecore_x_disp, (XGenericEventCookie *)data);
2417         free(data);
2418      }
2419    free(e);
2420 }
2421 
2422 void
_ecore_x_event_handle_generic_event(XEvent * event)2423 _ecore_x_event_handle_generic_event(XEvent *event)
2424 {
2425    XGenericEvent *generic_event;
2426    Ecore_X_Event_Generic *e;
2427    XGenericEventCookie *data;
2428 
2429    LOGFN;
2430    generic_event = (XGenericEvent *)event;
2431 
2432 #ifdef ECORE_XPRESENT
2433    if (generic_event->extension == _ecore_x_present_major)
2434      {
2435         _ecore_x_present_handler(generic_event);
2436         return;
2437      }
2438 #endif
2439 
2440    e = calloc(1, sizeof(Ecore_X_Event_Generic));
2441    if (!e)
2442      return;
2443 
2444    if (XGetEventData(_ecore_x_disp, &(event->xcookie)))
2445      {
2446         e->cookie = event->xcookie.cookie;
2447         e->data = event->xcookie.data;
2448      }
2449    else
2450      {
2451         e->cookie = 0;
2452         e->data = NULL;
2453      }
2454 
2455    e->extension = generic_event->extension;
2456    e->evtype = generic_event->evtype;
2457 #ifdef ECORE_XI2
2458    if (e->extension == _ecore_x_xi2_opcode)
2459      _ecore_x_input_handler(event);
2460 #endif /* ifdef ECORE_XI2 */
2461    data = malloc(sizeof(XGenericEventCookie));
2462    if (data) memcpy(data, &(event->xcookie), sizeof(XGenericEventCookie));
2463    ecore_event_add(ECORE_X_EVENT_GENERIC,
2464                    e,
2465                    _ecore_x_event_free_generic_event,
2466                    data);
2467 }
2468 
2469 #ifdef ECORE_XKB
2470 
2471 void
free_hash(void * userdata EINA_UNUSED,void * funcdata EINA_UNUSED)2472 free_hash(void *userdata EINA_UNUSED, void *funcdata EINA_UNUSED)
2473 {
2474    eina_hash_del_by_data(emitted_events, (void*) 1);
2475 }
2476 
2477 void
_ecore_x_event_handle_xkb(XEvent * xevent)2478 _ecore_x_event_handle_xkb(XEvent *xevent)
2479 {
2480    XkbEvent *xkbev;
2481 
2482    xkbev = (XkbEvent *) xevent;
2483 
2484 
2485    if (xkbev->any.xkb_type == XkbStateNotify)
2486      {
2487         Ecore_X_Event_Xkb *e;
2488 
2489         if (eina_hash_find(emitted_events, &xkbev->state.serial)) return;
2490 
2491         e = calloc(1, sizeof(Ecore_X_Event_Xkb));
2492         if (!e)
2493           return;
2494 
2495         e->group = xkbev->state.group;
2496         e->base_group = xkbev->state.base_group;
2497         e->latched_group = xkbev->state.latched_group;
2498         e->locked_group = xkbev->state.locked_group;
2499 
2500         e->mods = xkbev->state.mods;
2501         e->base_mods = xkbev->state.base_mods;
2502         e->latched_mods = xkbev->state.latched_mods;
2503         e->locked_mods = xkbev->state.locked_mods;
2504         ecore_event_add(ECORE_X_EVENT_XKB_STATE_NOTIFY, e, free_hash, NULL);
2505         eina_hash_add(emitted_events, &xkbev->state.serial, (void*) 1);
2506      }
2507    else if ((xkbev->any.xkb_type == XkbNewKeyboardNotify) ||
2508             (xkbev->any.xkb_type == XkbMapNotify))
2509      {
2510         if (eina_hash_find(emitted_events, &xkbev->state.serial)) return;
2511 
2512         if (xkbev->any.xkb_type == XkbMapNotify)
2513           {
2514              XkbMapNotifyEvent *xkbmapping = (XkbMapNotifyEvent *)xkbev;
2515 
2516              _ecore_x_window_grab_suspend();
2517              _ecore_x_key_grab_suspend();
2518              XkbGetMap(_ecore_x_disp, XkbAllMapComponentsMask,
2519                        xkbmapping->device);
2520              XkbRefreshKeyboardMapping(xkbmapping);
2521              _ecore_x_modifiers_get();
2522              _ecore_x_window_grab_resume();
2523              _ecore_x_key_grab_resume();
2524           }
2525         else
2526           {
2527              XkbNewKeyboardNotifyEvent *xkbnkn = (void*)xkbev;
2528              if (!(xkbnkn->changed & XkbNKN_KeycodesMask)) return;
2529           }
2530         ecore_event_add(ECORE_X_EVENT_XKB_NEWKBD_NOTIFY, NULL, free_hash, NULL);
2531         eina_hash_add(emitted_events, &xkbev->new_kbd.serial, (void*) 1);
2532      }
2533 }
2534 #endif /* ifdef ECORE_XKB */
2535