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