2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
6 #include "ecore_xcb_private.h"
7 #include "Ecore_X_Atoms.h"
10 /** OpenBSD does not define CODESET
15 #define CODESET "INVALID"
19 static void _ecore_x_event_free_window_prop_name_class_change(void *data, void *ev);
20 static void _ecore_x_event_free_window_prop_title_change(void *data, void *ev);
21 static void _ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev);
22 static void _ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev);
23 static void _ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev);
24 static void _ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev);
26 static void _ecore_x_event_free_key_down(void *data, void *ev);
27 static void _ecore_x_event_free_key_up(void *data, void *ev);
29 static Ecore_X_Window _ecore_xcb_mouse_down_last_window = 0;
30 static Ecore_X_Window _ecore_xcb_mouse_down_last_last_window = 0;
31 static Ecore_X_Window _ecore_xcb_mouse_down_last_event_window = 0;
32 static Ecore_X_Window _ecore_xcb_mouse_down_last_last_event_window = 0;
33 static Ecore_X_Time _ecore_xcb_mouse_down_last_time = 0;
34 static Ecore_X_Time _ecore_xcb_mouse_down_last_last_time = 0;
35 static int _ecore_xcb_mouse_up_count = 0;
36 static int _ecore_xcb_mouse_down_did_triple = 0;
39 /* FIXME: roundtrip */
41 ecore_x_event_mask_set(Ecore_X_Window window,
42 Ecore_X_Event_Mask mask)
44 xcb_get_window_attributes_cookie_t cookie;
45 xcb_get_window_attributes_reply_t *reply;
49 window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
51 cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
52 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
55 value_list = mask | reply->your_event_mask;
56 xcb_change_window_attributes(_ecore_xcb_conn, window, XCB_CW_EVENT_MASK, &value_list);
60 /* FIXME: roundtrip */
62 ecore_x_event_mask_unset(Ecore_X_Window window,
63 Ecore_X_Event_Mask mask)
65 xcb_get_window_attributes_cookie_t cookie;
66 xcb_get_window_attributes_reply_t *reply;
70 window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
72 cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
73 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
76 value_list = reply->your_event_mask & ~mask;
77 xcb_change_window_attributes(_ecore_xcb_conn, window, XCB_CW_EVENT_MASK, &value_list);
83 _ecore_x_event_free_window_prop_name_class_change(void *data, void *ev)
85 Ecore_X_Event_Window_Prop_Name_Class_Change *e;
88 if (e->name) free(e->name);
89 if (e->clas) free(e->clas);
94 _ecore_x_event_free_window_prop_title_change(void *data, void *ev)
96 Ecore_X_Event_Window_Prop_Title_Change *e;
99 if (e->title) free(e->title);
104 _ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev)
106 Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
109 if (e->title) free(e->title);
114 _ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev)
116 Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
119 if (e->name) free(e->name);
124 _ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev)
126 Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
129 if (e->name) free(e->name);
134 _ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev)
136 Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
139 if (e->name) free(e->name);
145 _ecore_x_event_free_key_down(void *data __UNUSED__, void *ev)
147 Ecore_X_Event_Key_Down *e;
150 if (e->keyname) free(e->keyname);
151 if (e->keysymbol) free(e->keysymbol);
152 if (e->key_compose) free(e->key_compose);
157 _ecore_x_event_free_key_up(void *data __UNUSED__, void *ev)
159 Ecore_X_Event_Key_Up *e;
162 if (e->keyname) free(e->keyname);
163 if (e->keysymbol) free(e->keysymbol);
164 if (e->key_compose) free(e->key_compose);
169 _ecore_x_event_free_xdnd_enter(void *data __UNUSED__, void *ev)
171 Ecore_X_Event_Xdnd_Enter *e;
175 for (i = 0; i < e->num_types; i++)
182 _ecore_x_event_free_selection_notify(void *data __UNUSED__, void *ev)
184 Ecore_X_Event_Selection_Notify *e;
185 Ecore_X_Selection_Data *sel;
195 /* FIXME: handle this event */
197 _ecore_x_event_handle_key_press(xcb_generic_event_t *event)
199 xcb_key_press_event_t *ev;
200 /* Ecore_X_Event_Key_Down *e; */
205 /* XComposeStatus status; */
207 ev = (xcb_key_press_event_t *)event;
208 /* e = calloc(1, sizeof(Ecore_X_Event_Key_Down)); */
209 /* if (!e) return; */
210 /* keyname = XKeysymToString(XKeycodeToKeysym(xevent->xkey.display, */
211 /* xevent->xkey.keycode, 0)); */
214 /* snprintf(buf, sizeof(buf), "Keycode-%i", xevent->xkey.keycode); */
217 /* e->keyname = strdup(keyname); */
218 /* if (!e->keyname) */
223 /* val = XLookupString((XKeyEvent *)xevent, buf, sizeof(buf), &sym, &status); */
227 /* e->key_compose = ecore_txt_convert(nl_langinfo(CODESET), "UTF-8", buf); */
229 /* else e->key_compose = NULL; */
230 /* keyname = XKeysymToString(sym); */
231 /* if (keyname) e->keysymbol = strdup(keyname); */
232 /* else e->keysymbol = strdup(e->keyname); */
233 /* if (!e->keysymbol) */
235 /* if (e->keyname) free(e->keyname); */
236 /* if (e->key_compose) free(e->key_compose); */
240 /* if (xevent->xkey.subwindow) e->win = xevent->xkey.subwindow; */
241 /* else e->win = xevent->xkey.window; */
242 /* e->event_win = xevent->xkey.window; */
243 /* e->time = xevent->xkey.time; */
244 /* e->modifiers = xevent->xkey.state; */
245 /* _ecore_x_event_last_time = e->time; */
246 /* ecore_event_add(ECORE_X_EVENT_KEY_DOWN, e, _ecore_x_event_free_key_down, NULL); */
249 /* FIXME: handle this event */
251 _ecore_x_event_handle_key_release(xcb_generic_event_t *event)
253 xcb_key_release_event_t *ev;
254 /* Ecore_X_Event_Key_Up *e; */
259 /* XComposeStatus status; */
261 ev = (xcb_key_release_event_t *)event;
262 /* e = calloc(1, sizeof(Ecore_X_Event_Key_Up)); */
263 /* if (!e) return; */
264 /* keyname = XKeysymToString(XKeycodeToKeysym(xevent->xkey.display, */
265 /* xevent->xkey.keycode, 0)); */
268 /* snprintf(buf, sizeof(buf), "Keycode-%i", xevent->xkey.keycode); */
271 /* e->keyname = strdup(keyname); */
272 /* if (!e->keyname) */
277 /* val = XLookupString((XKeyEvent *)xevent, buf, sizeof(buf), &sym, &status); */
281 /* e->key_compose = ecore_txt_convert("ISO8859-1", "UTF-8", buf); */
283 /* else e->key_compose = NULL; */
284 /* keyname = XKeysymToString(sym); */
285 /* if (keyname) e->keysymbol = strdup(keyname); */
286 /* else e->keysymbol = strdup(e->keyname); */
287 /* if (!e->keysymbol) */
289 /* if (e->keyname) free(e->keyname); */
290 /* if (e->key_compose) free(e->key_compose); */
294 /* if (xevent->xkey.subwindow) e->win = xevent->xkey.subwindow; */
295 /* else e->win = xevent->xkey.window; */
296 /* e->event_win = xevent->xkey.window; */
297 /* e->time = xevent->xkey.time; */
298 /* e->modifiers = xevent->xkey.state; */
299 /* _ecore_x_event_last_time = e->time; */
300 /* ecore_event_add(ECORE_X_EVENT_KEY_UP, e, _ecore_x_event_free_key_up, NULL); */
304 _ecore_x_event_handle_button_press(xcb_generic_event_t *event)
306 xcb_button_press_event_t *ev;
309 ev = (xcb_button_press_event_t *)event;
310 if ((ev->detail > 3) && (ev->detail < 8))
312 Ecore_X_Event_Mouse_Wheel *e;
314 e = malloc(sizeof(Ecore_X_Event_Mouse_Wheel));
319 e->modifiers = ev->state;
327 else if (ev->detail == 5)
332 else if (ev->detail == 6)
337 else if (ev->detail == 7)
344 e->root.x = ev->root_x;
345 e->root.y = ev->root_y;
352 e->event_win = ev->event;
353 e->same_screen = ev->same_screen;
354 e->root_win = ev->root;
356 _ecore_xcb_event_last_time = e->time;
357 _ecore_xcb_event_last_window = e->win;
358 _ecore_xcb_event_last_root_x = e->root.x;
359 _ecore_xcb_event_last_root_y = e->root.y;
360 ecore_event_add(ECORE_X_EVENT_MOUSE_WHEEL, e, NULL, NULL);
361 for (i = 0; i < _ecore_window_grabs_num; i++)
363 if ((_ecore_window_grabs[i] == ev->event) ||
364 (_ecore_window_grabs[i] == ev->child))
368 if (_ecore_window_grab_replay_func)
369 replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
370 ECORE_X_EVENT_MOUSE_WHEEL,
372 /* FIXME: xcb_key_press_event_t does not save the */
373 /* connection. So I use the current one */
375 xcb_allow_events(_ecore_xcb_conn,
376 XCB_ALLOW_REPLAY_POINTER,
379 xcb_allow_events(_ecore_xcb_conn,
380 XCB_ALLOW_ASYNC_POINTER,
389 Ecore_X_Event_Mouse_Move *e;
391 e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
393 e->modifiers = ev->state;
396 e->root.x = ev->root_x;
397 e->root.y = ev->root_y;
398 if (ev->child) e->win = ev->child;
399 else e->win = ev->event;
400 e->same_screen = ev->same_screen;
401 e->root_win = ev->root;
402 e->event_win = ev->event;
404 _ecore_xcb_event_last_time = e->time;
405 _ecore_xcb_event_last_window = e->win;
406 _ecore_xcb_event_last_root_x = e->root.x;
407 _ecore_xcb_event_last_root_y = e->root.y;
408 ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
411 Ecore_X_Event_Mouse_Button_Down *e;
413 if (_ecore_xcb_mouse_down_did_triple)
415 _ecore_xcb_mouse_down_last_window = 0;
416 _ecore_xcb_mouse_down_last_last_window = 0;
417 _ecore_xcb_mouse_down_last_event_window = 0;
418 _ecore_xcb_mouse_down_last_last_event_window = 0;
419 _ecore_xcb_mouse_down_last_time = 0;
420 _ecore_xcb_mouse_down_last_last_time = 0;
423 e = calloc(1, sizeof(Ecore_X_Event_Mouse_Button_Down));
425 e->button = ev->detail;
426 e->modifiers = ev->state;
429 e->root.x = ev->root_x;
430 e->root.y = ev->root_y;
431 if (ev->child) e->win = ev->child;
432 else e->win = ev->event;
433 e->same_screen = ev->same_screen;
434 e->root_win = ev->root;
435 e->event_win = ev->event;
437 if (e->win == e->event_win)
439 if (((int)(e->time - _ecore_xcb_mouse_down_last_time) <=
440 (int)(1000 * _ecore_xcb_double_click_time)) &&
441 (e->win == _ecore_xcb_mouse_down_last_window) &&
442 (e->event_win == _ecore_xcb_mouse_down_last_event_window)
445 if (((int)(e->time - _ecore_xcb_mouse_down_last_last_time) <=
446 (int)(2 * 1000 * _ecore_xcb_double_click_time)) &&
447 (e->win == _ecore_xcb_mouse_down_last_window) &&
448 (e->win == _ecore_xcb_mouse_down_last_last_window) &&
449 (e->event_win == _ecore_xcb_mouse_down_last_event_window) &&
450 (e->event_win == _ecore_xcb_mouse_down_last_last_event_window)
454 _ecore_xcb_mouse_down_did_triple = 1;
457 _ecore_xcb_mouse_down_did_triple = 0;
459 if (!e->double_click && !e->triple_click)
460 _ecore_xcb_mouse_up_count = 0;
461 _ecore_xcb_event_last_time = e->time;
462 _ecore_xcb_event_last_window = e->win;
463 _ecore_xcb_event_last_root_x = e->root.x;
464 _ecore_xcb_event_last_root_y = e->root.y;
465 ecore_event_add(ECORE_X_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
466 for (i = 0; i < _ecore_window_grabs_num; i++)
468 if ((_ecore_window_grabs[i] == ev->event) ||
469 (_ecore_window_grabs[i] == ev->child))
473 if (_ecore_window_grab_replay_func)
474 replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
475 ECORE_X_EVENT_MOUSE_BUTTON_DOWN,
477 /* FIXME: xcb_key_press_event_t does not save the */
478 /* connection. So I use the current one */
480 xcb_allow_events(_ecore_xcb_conn,
481 XCB_ALLOW_REPLAY_POINTER,
484 xcb_allow_events(_ecore_xcb_conn,
485 XCB_ALLOW_ASYNC_POINTER,
490 if (e->win == e->event_win)
492 if (!_ecore_xcb_mouse_down_did_triple)
494 _ecore_xcb_mouse_down_last_last_window = _ecore_xcb_mouse_down_last_window;
496 _ecore_xcb_mouse_down_last_window = ev->child;
498 _ecore_xcb_mouse_down_last_window = ev->event;
499 _ecore_xcb_mouse_down_last_last_event_window = _ecore_xcb_mouse_down_last_event_window;
500 _ecore_xcb_mouse_down_last_event_window = ev->event;
501 _ecore_xcb_mouse_down_last_last_time = _ecore_xcb_mouse_down_last_time;
502 _ecore_xcb_mouse_down_last_time = ev->time;
510 _ecore_x_event_handle_button_release(xcb_generic_event_t *event)
512 xcb_button_release_event_t *ev;
514 ev = (xcb_button_release_event_t *)event;
515 /* filter out wheel buttons */
516 if ((ev->detail <= 3) || (ev->detail > 7))
519 Ecore_X_Event_Mouse_Move *e;
521 e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
523 e->modifiers = ev->state;
526 e->root.x = ev->root_x;
527 e->root.y = ev->root_y;
528 if (ev->child) e->win = ev->child;
529 else e->win = ev->event;
530 e->same_screen = ev->same_screen;
531 e->root_win = ev->root;
532 e->event_win = ev->event;
534 _ecore_xcb_event_last_time = e->time;
535 _ecore_xcb_event_last_window = e->win;
536 _ecore_xcb_event_last_root_x = e->root.x;
537 _ecore_xcb_event_last_root_y = e->root.y;
538 ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
541 Ecore_X_Event_Mouse_Button_Up *e;
543 e = calloc(1, sizeof(Ecore_X_Event_Mouse_Button_Up));
545 e->button = ev->detail;
546 e->modifiers = ev->state;
549 e->root.x = ev->root_x;
550 e->root.y = ev->root_y;
551 if (ev->child) e->win = ev->child;
552 else e->win = ev->event;
553 e->same_screen = ev->same_screen;
554 e->root_win = ev->root;
555 e->event_win = ev->event;
557 _ecore_xcb_mouse_up_count++;
558 if (e->win == e->event_win)
560 if ((_ecore_xcb_mouse_up_count >= 2) &&
561 ((int)(e->time - _ecore_xcb_mouse_down_last_time) <=
562 (int)(1000 * _ecore_xcb_double_click_time)) &&
563 (e->win == _ecore_xcb_mouse_down_last_window) &&
564 (e->event_win == _ecore_xcb_mouse_down_last_event_window)
567 if ((_ecore_xcb_mouse_up_count >= 3) &&
568 ((int)(e->time - _ecore_xcb_mouse_down_last_last_time) <=
569 (int)(2 * 1000 * _ecore_xcb_double_click_time)) &&
570 (e->win == _ecore_xcb_mouse_down_last_window) &&
571 (e->win == _ecore_xcb_mouse_down_last_last_window) &&
572 (e->event_win == _ecore_xcb_mouse_down_last_event_window) &&
573 (e->event_win == _ecore_xcb_mouse_down_last_last_event_window)
577 _ecore_xcb_event_last_time = e->time;
578 _ecore_xcb_event_last_window = e->win;
579 _ecore_xcb_event_last_root_x = e->root.x;
580 _ecore_xcb_event_last_root_y = e->root.y;
581 ecore_event_add(ECORE_X_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
587 _ecore_x_event_handle_motion_notify(xcb_generic_event_t *event)
589 xcb_motion_notify_event_t *ev;
590 Ecore_X_Event_Mouse_Move *e;
592 ev = (xcb_motion_notify_event_t *)event;
593 e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
595 e->modifiers = ev->state;
598 e->root.x = ev->root_x;
599 e->root.y = ev->root_y;
600 if (ev->child) e->win = ev->child;
601 else e->win = ev->event;
602 e->same_screen = ev->same_screen;
603 e->root_win = ev->root;
604 e->event_win = ev->event;
606 _ecore_xcb_event_last_time = e->time;
607 _ecore_xcb_event_last_window = e->win;
608 _ecore_xcb_event_last_root_x = e->root.x;
609 _ecore_xcb_event_last_root_y = e->root.y;
612 _ecore_x_dnd_drag(e->root_win, e->root.x, e->root.y);
614 ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
618 _ecore_x_event_handle_enter_notify(xcb_generic_event_t *event)
620 xcb_enter_notify_event_t *ev;
622 ev = (xcb_enter_notify_event_t *)event;
625 Ecore_X_Event_Mouse_Move *e;
627 e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
629 e->modifiers = ev->state;
632 e->root.x = ev->root_x;
633 e->root.y = ev->root_y;
634 if (ev->child) e->win = ev->child;
635 else e->win = ev->event;
636 e->same_screen = ev->same_screen_focus;
637 e->root_win = ev->root;
638 e->event_win = ev->event;
640 _ecore_xcb_event_last_time = e->time;
641 _ecore_xcb_event_last_window = e->win;
642 _ecore_xcb_event_last_root_x = e->root.x;
643 _ecore_xcb_event_last_root_y = e->root.y;
644 ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
647 Ecore_X_Event_Mouse_In *e;
649 e = calloc(1, sizeof(Ecore_X_Event_Mouse_In));
651 e->modifiers = ev->state;
654 e->root.x = ev->root_x;
655 e->root.y = ev->root_y;
656 if (ev->child) e->win = ev->child;
657 else e->win = ev->event;
658 e->same_screen = ev->same_screen_focus;
659 e->root_win = ev->root;
660 e->event_win = ev->event;
662 case XCB_NOTIFY_MODE_NORMAL:
663 e->mode = ECORE_X_EVENT_MODE_NORMAL;
665 case XCB_NOTIFY_MODE_GRAB:
666 e->mode = ECORE_X_EVENT_MODE_GRAB;
668 case XCB_NOTIFY_MODE_UNGRAB:
669 e->mode = ECORE_X_EVENT_MODE_UNGRAB;
672 e->mode = ECORE_X_EVENT_MODE_NORMAL;
675 switch (ev->detail) {
676 case XCB_NOTIFY_DETAIL_ANCESTOR:
677 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
679 case XCB_NOTIFY_DETAIL_VIRTUAL:
680 e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
682 case XCB_NOTIFY_DETAIL_INFERIOR:
683 e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
685 case XCB_NOTIFY_DETAIL_NONLINEAR:
686 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
688 case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
689 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
692 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
696 _ecore_xcb_event_last_time = e->time;
697 ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
702 _ecore_x_event_handle_leave_notify(xcb_generic_event_t *event)
704 xcb_leave_notify_event_t *ev;
706 ev = (xcb_leave_notify_event_t *)event;
708 Ecore_X_Event_Mouse_Move *e;
710 e = calloc(1, sizeof(Ecore_X_Event_Mouse_Move));
712 e->modifiers = ev->state;
715 e->root.x = ev->root_x;
716 e->root.y = ev->root_y;
717 if (ev->child) e->win = ev->child;
718 else e->win = ev->event;
719 e->same_screen = ev->same_screen_focus;
720 e->root_win = ev->root;
721 e->event_win = ev->event;
723 _ecore_xcb_event_last_time = e->time;
724 _ecore_xcb_event_last_window = e->win;
725 _ecore_xcb_event_last_root_x = e->root.x;
726 _ecore_xcb_event_last_root_y = e->root.y;
727 ecore_event_add(ECORE_X_EVENT_MOUSE_MOVE, e, NULL, NULL);
730 Ecore_X_Event_Mouse_Out *e;
732 e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out));
734 e->modifiers = ev->state;
737 e->root.x = ev->root_x;
738 e->root.y = ev->root_y;
739 if (ev->child) e->win = ev->child;
740 else e->win = ev->event;
741 e->same_screen = ev->same_screen_focus;
742 e->root_win = ev->root;
743 e->event_win = ev->event;
745 case XCB_NOTIFY_MODE_NORMAL:
746 e->mode = ECORE_X_EVENT_MODE_NORMAL;
748 case XCB_NOTIFY_MODE_GRAB:
749 e->mode = ECORE_X_EVENT_MODE_GRAB;
751 case XCB_NOTIFY_MODE_UNGRAB:
752 e->mode = ECORE_X_EVENT_MODE_UNGRAB;
755 e->mode = ECORE_X_EVENT_MODE_NORMAL;
758 switch (ev->detail) {
759 case XCB_NOTIFY_DETAIL_ANCESTOR:
760 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
762 case XCB_NOTIFY_DETAIL_VIRTUAL:
763 e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
765 case XCB_NOTIFY_DETAIL_INFERIOR:
766 e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
768 case XCB_NOTIFY_DETAIL_NONLINEAR:
769 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
771 case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
772 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
775 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
779 _ecore_xcb_event_last_time = e->time;
780 _ecore_xcb_event_last_window = e->win;
781 _ecore_xcb_event_last_root_x = e->root.x;
782 _ecore_xcb_event_last_root_y = e->root.y;
783 ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
788 _ecore_x_event_handle_focus_in(xcb_generic_event_t *event)
790 xcb_focus_in_event_t *ev;
791 Ecore_X_Event_Window_Focus_In *e;
793 ev = (xcb_focus_in_event_t *)event;
794 e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In));
798 case XCB_NOTIFY_MODE_NORMAL:
799 e->mode = ECORE_X_EVENT_MODE_NORMAL;
801 case XCB_NOTIFY_MODE_GRAB:
802 e->mode = ECORE_X_EVENT_MODE_GRAB;
804 case XCB_NOTIFY_MODE_UNGRAB:
805 e->mode = ECORE_X_EVENT_MODE_UNGRAB;
807 case XCB_NOTIFY_MODE_WHILE_GRABBED:
808 e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
811 switch (ev->detail) {
812 case XCB_NOTIFY_DETAIL_ANCESTOR:
813 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
815 case XCB_NOTIFY_DETAIL_VIRTUAL:
816 e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
818 case XCB_NOTIFY_DETAIL_INFERIOR:
819 e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
821 case XCB_NOTIFY_DETAIL_NONLINEAR:
822 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
824 case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
825 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
827 case XCB_NOTIFY_DETAIL_POINTER:
828 e->detail = ECORE_X_EVENT_DETAIL_POINTER;
830 case XCB_NOTIFY_DETAIL_POINTER_ROOT:
831 e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
833 case XCB_NOTIFY_DETAIL_NONE:
834 e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
837 e->time = _ecore_xcb_event_last_time;
838 _ecore_xcb_event_last_time = e->time;
839 ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
843 _ecore_x_event_handle_focus_out(xcb_generic_event_t *event)
845 xcb_focus_out_event_t *ev;
846 Ecore_X_Event_Window_Focus_Out *e;
848 ev = (xcb_focus_out_event_t *)event;
849 e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out));
853 case XCB_NOTIFY_MODE_NORMAL:
854 e->mode = ECORE_X_EVENT_MODE_NORMAL;
856 case XCB_NOTIFY_MODE_GRAB:
857 e->mode = ECORE_X_EVENT_MODE_GRAB;
859 case XCB_NOTIFY_MODE_UNGRAB:
860 e->mode = ECORE_X_EVENT_MODE_UNGRAB;
862 case XCB_NOTIFY_MODE_WHILE_GRABBED:
863 e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
866 switch (ev->detail) {
867 case XCB_NOTIFY_DETAIL_ANCESTOR:
868 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
870 case XCB_NOTIFY_DETAIL_VIRTUAL:
871 e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
873 case XCB_NOTIFY_DETAIL_INFERIOR:
874 e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
876 case XCB_NOTIFY_DETAIL_NONLINEAR:
877 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
879 case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
880 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
882 case XCB_NOTIFY_DETAIL_POINTER:
883 e->detail = ECORE_X_EVENT_DETAIL_POINTER;
885 case XCB_NOTIFY_DETAIL_POINTER_ROOT:
886 e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
888 case XCB_NOTIFY_DETAIL_NONE:
889 e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
892 e->time = _ecore_xcb_event_last_time;
893 _ecore_xcb_event_last_time = e->time;
894 ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
898 _ecore_x_event_handle_keymap_notify(xcb_generic_event_t *event __UNUSED__)
900 /* FIXME: handle this event type */
904 _ecore_x_event_handle_expose(xcb_generic_event_t *event)
906 xcb_expose_event_t *ev;
907 Ecore_X_Event_Window_Damage *e;
909 ev = (xcb_expose_event_t *)event,
910 e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
913 e->time = _ecore_xcb_event_last_time;
918 e->count = ev->count;
919 ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
923 _ecore_x_event_handle_graphics_expose(xcb_generic_event_t *event)
925 xcb_graphics_exposure_event_t *ev;
926 Ecore_X_Event_Window_Damage *e;
928 ev = (xcb_graphics_exposure_event_t *)event;
929 e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
931 e->win = ev->drawable;
932 e->time = _ecore_xcb_event_last_time;
937 e->count = ev->count;
938 ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
942 _ecore_x_event_handle_visibility_notify(xcb_generic_event_t *event)
944 xcb_visibility_notify_event_t *ev;
946 ev = (xcb_visibility_notify_event_t *)event;
947 if (ev->state != XCB_VISIBILITY_PARTIALLY_OBSCURED)
949 Ecore_X_Event_Window_Visibility_Change *e;
951 e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change));
954 e->time = _ecore_xcb_event_last_time;
955 if (ev->state == XCB_VISIBILITY_FULLY_OBSCURED)
956 e->fully_obscured = 1;
958 e->fully_obscured = 0;
959 ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
964 _ecore_x_event_handle_create_notify(xcb_generic_event_t *event)
966 xcb_create_notify_event_t *ev;
967 Ecore_X_Event_Window_Create *e;
969 ev = (xcb_create_notify_event_t *)event;
970 e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
973 if (ev->override_redirect)
977 e->time = _ecore_xcb_event_last_time;
978 ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
982 _ecore_x_event_handle_destroy_notify(xcb_generic_event_t *event)
984 xcb_destroy_notify_event_t *ev;
985 Ecore_X_Event_Window_Destroy *e;
987 ev = (xcb_destroy_notify_event_t *)event;
988 e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy));
991 e->time = _ecore_xcb_event_last_time;
992 if (e->win == _ecore_xcb_event_last_window) _ecore_xcb_event_last_window = 0;
993 ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
997 _ecore_x_event_handle_unmap_notify(xcb_generic_event_t *event)
999 xcb_unmap_notify_event_t *ev;
1000 Ecore_X_Event_Window_Hide *e;
1002 ev = (xcb_unmap_notify_event_t *)event;
1003 e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
1005 e->win = ev->window;
1006 e->time = _ecore_xcb_event_last_time;
1007 ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
1011 _ecore_x_event_handle_map_notify(xcb_generic_event_t *event)
1013 xcb_map_notify_event_t *ev;
1014 Ecore_X_Event_Window_Show *e;
1016 ev = (xcb_map_notify_event_t *)event;
1017 e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
1019 e->win = ev->window;
1020 e->time = _ecore_xcb_event_last_time;
1021 ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
1025 _ecore_x_event_handle_map_request(xcb_generic_event_t *event)
1027 xcb_map_request_event_t *ev;
1028 Ecore_X_Event_Window_Show_Request *e;
1030 ev = (xcb_map_request_event_t *)event;
1031 e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
1033 e->win = ev->window;
1034 e->parent = ev->parent;
1035 e->time = _ecore_xcb_event_last_time;
1036 ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
1040 _ecore_x_event_handle_reparent_notify(xcb_generic_event_t *event)
1042 xcb_reparent_notify_event_t *ev;
1043 Ecore_X_Event_Window_Reparent *e;
1045 ev = (xcb_reparent_notify_event_t *)event;
1046 e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
1048 e->win = ev->window;
1049 e->parent = ev->parent;
1050 e->time = _ecore_xcb_event_last_time;
1051 ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
1055 _ecore_x_event_handle_configure_notify(xcb_generic_event_t *event)
1057 xcb_configure_notify_event_t *ev;
1058 Ecore_X_Event_Window_Configure *e;
1060 ev = (xcb_configure_notify_event_t *)event;
1061 e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
1063 e->win = ev->window;
1064 e->abovewin = ev->above_sibling;
1069 e->border = ev->border_width;
1070 e->override = ev->override_redirect;
1071 /* send_event is bit 7 (0x80) of response_type */
1072 e->from_wm = (ev->response_type & 0x80) ? 1 : 0;
1073 e->time = _ecore_xcb_event_last_time;
1074 ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
1078 _ecore_x_event_handle_configure_request(xcb_generic_event_t *event)
1080 xcb_configure_request_event_t *ev;
1081 Ecore_X_Event_Window_Configure_Request *e;
1083 ev = (xcb_configure_request_event_t *)event;
1084 e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
1086 e->win = ev->window;
1087 e->abovewin = ev->sibling;
1092 e->border = ev->border_width;
1093 e->value_mask = ev->value_mask;
1094 switch (ev->stack_mode) {
1095 case XCB_STACK_MODE_ABOVE:
1096 e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1098 case XCB_STACK_MODE_BELOW:
1099 e->detail = ECORE_X_WINDOW_STACK_BELOW;
1101 case XCB_STACK_MODE_TOP_IF:
1102 e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
1104 case XCB_STACK_MODE_BOTTOM_IF:
1105 e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
1107 case XCB_STACK_MODE_OPPOSITE:
1108 e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
1111 e->time = _ecore_xcb_event_last_time;
1112 ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
1116 _ecore_x_event_handle_gravity_notify(xcb_generic_event_t *event __UNUSED__)
1118 /* FIXME: handle this event type */
1122 _ecore_x_event_handle_resize_request(xcb_generic_event_t *event)
1124 xcb_resize_request_event_t *ev;
1125 Ecore_X_Event_Window_Resize_Request *e;
1127 ev = (xcb_resize_request_event_t *)event;
1128 e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
1130 e->win = ev->window;
1133 e->time = _ecore_xcb_event_last_time;
1134 ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
1138 _ecore_x_event_handle_circulate_notify(xcb_generic_event_t *event)
1140 xcb_circulate_notify_event_t *ev;
1141 Ecore_X_Event_Window_Stack *e;
1143 ev = (xcb_circulate_notify_event_t *)event;
1144 e = calloc(1, sizeof(Ecore_X_Event_Window_Stack));
1146 e->win = ev->window;
1147 e->event_win = ev->event;
1148 if (ev->place == XCB_PLACE_ON_TOP)
1149 e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1151 e->detail = ECORE_X_WINDOW_STACK_BELOW;
1152 e->time = _ecore_xcb_event_last_time;
1153 ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
1157 _ecore_x_event_handle_circulate_request(xcb_generic_event_t *event)
1159 xcb_circulate_request_event_t *ev;
1160 Ecore_X_Event_Window_Stack_Request *e;
1162 ev = (xcb_circulate_request_event_t *)event;
1163 e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request));
1165 e->win = ev->window;
1166 e->parent = ev->event;
1167 if (ev->place == XCB_PLACE_ON_TOP)
1168 e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1170 e->detail = ECORE_X_WINDOW_STACK_BELOW;
1171 e->time = _ecore_xcb_event_last_time;
1172 ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
1176 _ecore_x_event_handle_property_notify(xcb_generic_event_t *event)
1178 #if 0 /* for now i disabled this. nice idea though this is - it leaves a lot
1179 * to be desired for efficiency that is better left to the app layer
1181 if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLASS)
1183 Ecore_X_Event_Window_Prop_Name_Class_Change *e;
1185 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Name_Class_Change));
1187 ecore_x_window_prop_name_class_get(xevent->xproperty.window,
1188 &(e->name), &(e->clas));
1189 e->time = xevent->xproperty.time;
1190 _ecore_x_event_last_time = e->time;
1191 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE, e, _ecore_x_event_free_window_prop_name_class_change, NULL);
1193 else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_NAME))
1195 Ecore_X_Event_Window_Prop_Title_Change *e;
1197 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Title_Change));
1199 e->title = ecore_x_window_prop_title_get(xevent->xproperty.window);
1200 e->time = xevent->xproperty.time;
1201 _ecore_x_event_last_time = e->time;
1202 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_title_change, NULL);
1204 else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_NAME)
1206 Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
1208 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Title_Change));
1210 e->title = ecore_x_window_prop_visible_title_get(xevent->xproperty.window);
1211 e->time = xevent->xproperty.time;
1212 _ecore_x_event_last_time = e->time;
1213 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_visible_title_change, NULL);
1215 else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_ICON_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_ICON_NAME))
1217 Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
1219 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Icon_Name_Change));
1221 e->name = ecore_x_window_prop_icon_name_get(xevent->xproperty.window);
1222 e->time = xevent->xproperty.time;
1223 _ecore_x_event_last_time = e->time;
1224 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_icon_name_change, NULL);
1226 else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME)
1228 Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
1230 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change));
1232 e->name = ecore_x_window_prop_visible_icon_name_get(xevent->xproperty.window);
1233 e->time = xevent->xproperty.time;
1234 _ecore_x_event_last_time = e->time;
1235 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_visible_icon_name_change, NULL);
1237 else if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
1239 Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
1241 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Client_Machine_Change));
1243 e->name = ecore_x_window_prop_client_machine_get(xevent->xproperty.window);
1244 e->time = xevent->xproperty.time;
1245 _ecore_x_event_last_time = e->time;
1246 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE, e, _ecore_x_event_free_window_prop_client_machine_change, NULL);
1248 else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_PID)
1250 Ecore_X_Event_Window_Prop_Pid_Change *e;
1252 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Pid_Change));
1254 e->pid = ecore_x_window_prop_pid_get(xevent->xproperty.window);
1255 e->time = xevent->xproperty.time;
1256 _ecore_x_event_last_time = e->time;
1257 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
1259 else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_DESKTOP)
1261 Ecore_X_Event_Window_Prop_Desktop_Change *e;
1263 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Desktop_Change));
1265 e->desktop = ecore_x_window_prop_desktop_get(xevent->xproperty.window);
1266 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
1271 xcb_property_notify_event_t *ev;
1272 Ecore_X_Event_Window_Property *e;
1274 ev = (xcb_property_notify_event_t *)event;
1275 e = calloc(1,sizeof(Ecore_X_Event_Window_Property));
1277 e->win = ev->window;
1280 _ecore_xcb_event_last_time = e->time;
1281 ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
1286 _ecore_x_event_handle_selection_clear(xcb_generic_event_t *event)
1288 xcb_selection_clear_event_t *ev;
1289 Ecore_X_Selection_Intern *d;
1290 Ecore_X_Event_Selection_Clear *e;
1293 ev = (xcb_selection_clear_event_t *)event;
1294 if (!(d = _ecore_x_selection_get(ev->selection)))
1296 if (ev->time > d->time)
1298 _ecore_x_selection_set(XCB_NONE, NULL, 0,
1302 /* Generate event for app cleanup */
1303 e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
1306 sel = ev->selection;
1307 if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
1308 e->selection = ECORE_X_SELECTION_PRIMARY;
1309 else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
1310 e->selection = ECORE_X_SELECTION_SECONDARY;
1312 e->selection = ECORE_X_SELECTION_CLIPBOARD;
1313 ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
1318 _ecore_x_event_handle_selection_request(xcb_generic_event_t *event)
1320 xcb_selection_request_event_t *ev;
1321 Ecore_X_Selection_Intern *sd;
1322 xcb_selection_notify_event_t sn_event;
1325 ev = (xcb_selection_request_event_t *)event;
1326 /* FIXME: is it the correct value ? */
1327 sn_event.response_type = XCB_SELECTION_NOTIFY;
1329 /* FIXME: is it the correct value ? */
1330 sn_event.sequence = 0;
1331 sn_event.time = XCB_CURRENT_TIME;
1332 sn_event.requestor = ev->requestor;
1333 sn_event.selection = ev->selection;
1334 sn_event.target = ev->target;
1336 if ((sd = _ecore_x_selection_get(ev->selection)) &&
1337 (sd->win == ev->owner))
1339 if (!ecore_x_selection_convert(ev->selection, ev->target,
1342 /* Refuse selection, conversion to requested target failed */
1343 sn_event.property = XCB_NONE;
1347 /* FIXME: This does not properly handle large data transfers */
1348 ecore_x_window_prop_property_set(ev->requestor,
1351 8, data, sd->length);
1352 sn_event.property = ev->property;
1358 sn_event.property = XCB_NONE;
1362 /* FIXME: I use _ecore_xcb_conn, as ev has no information on the connection */
1363 xcb_send_event(_ecore_xcb_conn, 0,
1364 ev->requestor, 0, (const char *)&sn_event);
1367 /* FIXME: round trip */
1369 _ecore_x_event_handle_selection_notify(xcb_generic_event_t *event)
1371 xcb_selection_notify_event_t *ev;
1372 Ecore_X_Event_Selection_Notify *e;
1373 unsigned char *data = NULL;
1374 Ecore_X_Atom selection;
1378 ev = (xcb_selection_notify_event_t *)event;
1379 selection = ev->selection;
1381 if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS)
1383 ecore_x_window_prop_property_get_prefetch(ev->requestor,
1386 ecore_x_window_prop_property_get_fetch();
1387 format = ecore_x_window_prop_property_get(ev->requestor,
1393 if (!format) return;
1397 ecore_x_window_prop_property_get_prefetch(ev->requestor,
1399 XCB_GET_PROPERTY_TYPE_ANY);
1400 ecore_x_window_prop_property_get_fetch();
1401 format = ecore_x_window_prop_property_get(ev->requestor,
1407 if (!format) return;
1410 e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
1412 e->win = ev->requestor;
1414 e->target = _ecore_x_selection_target_get(ev->target);
1416 if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
1417 e->selection = ECORE_X_SELECTION_PRIMARY;
1418 else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
1419 e->selection = ECORE_X_SELECTION_SECONDARY;
1420 else if (selection == ECORE_X_ATOM_SELECTION_XDND)
1421 e->selection = ECORE_X_SELECTION_XDND;
1422 else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1423 e->selection = ECORE_X_SELECTION_CLIPBOARD;
1429 e->data = _ecore_x_selection_parse(e->target, data, num_ret, format);
1431 ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, _ecore_x_event_free_selection_notify, NULL);
1435 _ecore_x_event_handle_colormap_notify(xcb_generic_event_t *event)
1437 xcb_colormap_notify_event_t *ev;
1438 Ecore_X_Event_Window_Colormap *e;
1440 ev = (xcb_colormap_notify_event_t *)event;
1441 e = calloc(1,sizeof(Ecore_X_Event_Window_Colormap));
1443 e->win = ev->window;
1444 e->cmap = ev->colormap;
1445 if (ev->state == XCB_COLORMAP_STATE_INSTALLED)
1449 e->time = _ecore_xcb_event_last_time;
1450 ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
1454 _ecore_x_event_handle_client_message(xcb_generic_event_t *event)
1456 /* Special client message event handling here. need to put LOTS of if */
1457 /* checks here and generate synthetic events per special message known */
1458 /* otherwise generate generic client message event. this would handle*/
1459 /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
1461 xcb_client_message_event_t *ev;
1463 ev = (xcb_client_message_event_t *)event;
1464 if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) &&
1465 (ev->format == 32) &&
1466 (ev->data.data32[0] == (uint32_t)ECORE_X_ATOM_WM_DELETE_WINDOW))
1468 Ecore_X_Event_Window_Delete_Request *e;
1470 e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request));
1472 e->win = ev->window;
1473 e->time = _ecore_xcb_event_last_time;
1474 ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
1477 else if ((ev->type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
1478 (ev->format == 32) &&
1479 /* Ignore move and resize with keyboard */
1480 (ev->data.data32[2] < 9))
1482 Ecore_X_Event_Window_Move_Resize_Request *e;
1484 e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
1486 e->win = ev->window;
1487 e->x = ev->data.data32[0];
1488 e->y = ev->data.data32[1];
1489 e->direction = ev->data.data32[2];
1490 e->button = ev->data.data32[3];
1491 e->source = ev->data.data32[4];
1492 ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
1495 /* Xdnd Client Message Handling Begin */
1496 /* Message Type: XdndEnter target */
1497 else if (ev->type == ECORE_X_ATOM_XDND_ENTER)
1499 Ecore_X_Event_Xdnd_Enter *e;
1500 Ecore_X_DND_Target *target;
1503 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
1506 target = _ecore_x_dnd_target_get();
1507 target->state = ECORE_X_DND_TARGET_ENTERED;
1509 target = _ecore_x_dnd_target_get();
1510 target->source = ev->data.data32[0];
1511 target->win = ev->window;
1512 target->version = ev->data.data32[1] >> 24;
1513 if (target->version > ECORE_X_DND_VERSION)
1515 printf("DND: Requested version %d, we only support up to %d\n", target->version,
1516 ECORE_X_DND_VERSION);
1520 /* FIXME: roud trip, but I don't know how to suppress it */
1521 if ((three = ev->data.data32[1] & 0x1UL))
1523 /* source supports more than 3 types, fetch property */
1524 unsigned char *data;
1525 Ecore_X_Atom *types;
1530 ecore_x_window_prop_property_get_prefetch(target->source,
1531 ECORE_X_ATOM_XDND_TYPE_LIST,
1533 ecore_x_window_prop_property_get_fetch();
1534 format = ecore_x_window_prop_property_get(target->source,
1535 ECORE_X_ATOM_XDND_TYPE_LIST,
1542 printf("DND: Could not fetch data type list from source window, aborting.\n");
1545 types = (Ecore_X_Atom *)data;
1546 e->types = calloc(num_ret, sizeof(char *));
1549 xcb_get_atom_name_cookie_t *cookies;
1551 cookies = (xcb_get_atom_name_cookie_t *)malloc(sizeof(xcb_get_atom_name_cookie_t) * num_ret);
1552 for (i = 0; i < num_ret; i++)
1553 cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, types[i]);
1554 for (i = 0; i < num_ret; i++)
1556 xcb_get_atom_name_reply_t *reply;
1559 reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL);
1562 name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1564 xcb_get_atom_name_name(reply),
1566 name[reply->name_len] = '\0';
1573 e->num_types = num_ret;
1579 e->types = calloc(3, sizeof(char *));
1582 xcb_get_atom_name_cookie_t cookies[3];
1584 for (i = 0; i < 3; i++)
1585 cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[i + 2]);
1586 for (i = 0; i < 3; i++)
1588 xcb_get_atom_name_reply_t *reply;
1591 reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL);
1592 if (reply && (ev->data.data32[i + 2]))
1594 name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1596 xcb_get_atom_name_name(reply),
1598 name[reply->name_len] = '\0';
1601 if (reply) free(reply);
1607 e->win = target->win;
1608 e->source = target->source;
1609 ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, _ecore_x_event_free_xdnd_enter, NULL);
1612 /* Message Type: XdndPosition target */
1613 else if (ev->type == ECORE_X_ATOM_XDND_POSITION)
1615 Ecore_X_Event_Xdnd_Position *e;
1616 Ecore_X_DND_Target *target;
1618 target = _ecore_x_dnd_target_get();
1619 if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1620 (target->win != ev->window))
1623 target->pos.x = (int16_t)ev->data.data32[2] >> 16;
1624 target->pos.y = (int16_t)ev->data.data32[2] & 0xFFFFUL;
1625 target->action = ev->data.data32[4]; /* Version 2 */
1627 target->time = (target->version >= 1) ?
1628 ev->data.data32[3] : XCB_CURRENT_TIME;
1630 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
1632 e->win = target->win;
1633 e->source = target->source;
1634 e->position.x = target->pos.x;
1635 e->position.y = target->pos.y;
1636 e->action = target->action;
1637 ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
1640 /* Message Type: XdndStatus source */
1641 else if (ev->type == ECORE_X_ATOM_XDND_STATUS)
1643 Ecore_X_Event_Xdnd_Status *e;
1644 Ecore_X_DND_Source *source;
1646 source = _ecore_x_dnd_source_get();
1647 /* Make sure source/target match */
1648 if ((source->win != ev->window ) ||
1649 (source->dest != ev->data.data32[0]))
1652 source->await_status = 0;
1654 source->will_accept = ev->data.data32[1] & 0x1UL;
1655 source->suppress = (ev->data.data32[1] & 0x2UL) ? 0 : 1;
1657 source->rectangle.x = (int16_t)ev->data.data32[2] >> 16;
1658 source->rectangle.y = (int16_t)ev->data.data32[2] & 0xFFFFUL;
1659 source->rectangle.width = (uint16_t)ev->data.data32[3] >> 16;
1660 source->rectangle.height = (uint16_t)ev->data.data32[3] & 0xFFFFUL;
1662 source->accepted_action = ev->data.data32[4];
1664 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
1666 e->win = source->win;
1667 e->target = source->dest;
1668 e->will_accept = source->will_accept;
1669 e->rectangle.x = source->rectangle.x;
1670 e->rectangle.y = source->rectangle.y;
1671 e->rectangle.width = source->rectangle.width;
1672 e->rectangle.height = source->rectangle.height;
1673 e->action = source->accepted_action;
1675 ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
1678 /* Message Type: XdndLeave target */
1679 /* Pretend the whole thing never happened, sort of */
1680 else if (ev->type == ECORE_X_ATOM_XDND_LEAVE)
1682 Ecore_X_Event_Xdnd_Leave *e;
1683 Ecore_X_DND_Target *target;
1685 target = _ecore_x_dnd_target_get();
1686 if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1687 (target->win != ev->window))
1690 target->state = ECORE_X_DND_TARGET_IDLE;
1692 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
1694 e->win = ev->window;
1695 e->source = ev->data.data32[0];
1696 ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
1699 /* Message Type: XdndDrop target */
1700 else if (ev->type == ECORE_X_ATOM_XDND_DROP)
1702 Ecore_X_Event_Xdnd_Drop *e;
1703 Ecore_X_DND_Target *target;
1705 target = _ecore_x_dnd_target_get();
1706 /* Match source/target */
1707 if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1708 (target->win != ev->window))
1711 target->time = (target->version >= 1) ?
1712 ev->data.data32[2] : _ecore_xcb_event_last_time;
1714 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
1716 e->win = target->win;
1717 e->source = target->source;
1718 e->action = target->action;
1719 e->position.x = target->pos.x;
1720 e->position.y = target->pos.y;
1721 ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
1724 /* Message Type: XdndFinished source */
1725 else if (ev->type == ECORE_X_ATOM_XDND_FINISHED)
1727 Ecore_X_Event_Xdnd_Finished *e;
1728 Ecore_X_DND_Source *source;
1729 uint8_t completed = 1;
1731 source = _ecore_x_dnd_source_get();
1732 /* Match source/target */
1733 if ((source->win != ev->window) ||
1734 (source->dest != ev->data.data32[0]))
1737 if ((source->version >= 5) && (ev->data.data32[1] & 0x1UL))
1739 /* Target successfully performed drop action */
1740 ecore_x_selection_xdnd_clear();
1741 source->state = ECORE_X_DND_SOURCE_IDLE;
1746 source->state = ECORE_X_DND_SOURCE_CONVERTING;
1748 /* FIXME: Probably need to add a timer to switch back to idle
1749 * and discard the selection data */
1752 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished));
1754 e->win = source->win;
1755 e->target = source->dest;
1756 e->completed = completed;
1757 if (source->version >= 5)
1759 source->accepted_action = ev->data.data32[2];
1760 e->action = source->accepted_action;
1764 source->accepted_action = 0;
1765 e->action = source->action;
1768 ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
1770 else if (ev->type == ECORE_X_ATOM_NET_WM_STATE)
1772 Ecore_X_Event_Window_State_Request *e;
1774 e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1776 e->win = ev->window;
1777 if (ev->data.data32[0] == 0)
1778 e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
1779 else if (ev->data.data32[0] == 1)
1780 e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1781 else if (ev->data.data32[0] == 2)
1782 e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
1788 e->state[0] = _ecore_x_netwm_state_get(ev->data.data32[1]);
1789 if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
1791 xcb_get_atom_name_reply_t *reply;
1794 /* FIXME: round trip */
1795 reply = xcb_get_atom_name_reply(_ecore_xcb_conn,
1796 xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[1]),
1800 name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1802 xcb_get_atom_name_name(reply),
1804 name[reply->name_len] = '\0';
1805 printf("Unknown state: %s\n", name);
1810 e->state[1] = _ecore_x_netwm_state_get(ev->data.data32[2]);
1811 if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
1813 xcb_get_atom_name_reply_t *reply;
1816 reply = xcb_get_atom_name_reply(_ecore_xcb_conn,
1817 xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[2]),
1821 name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1823 xcb_get_atom_name_name(reply),
1825 name[reply->name_len] = '\0';
1826 printf("Unknown state: %s\n", name);
1830 e->source = ev->data.data32[3];
1832 ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1834 else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE)
1835 && (ev->format == 32)
1836 && (ev->data.data32[0] == XCB_WM_ICONIC_STATE))
1838 Ecore_X_Event_Window_State_Request *e;
1840 e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1842 e->win = ev->window;
1843 e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1844 e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
1846 ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1848 else if ((ev->type == ECORE_X_ATOM_NET_WM_DESKTOP)
1849 && (ev->format == 32))
1851 Ecore_X_Event_Desktop_Change *e;
1853 e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
1855 e->win = ev->window;
1856 e->desk = ev->data.data32[0];
1857 e->source = ev->data.data32[1];
1859 ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
1861 else if ((ev->type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS))
1863 Ecore_X_Event_Frame_Extents_Request *e;
1865 e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request));
1867 e->win = ev->window;
1869 ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
1871 else if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS)
1872 && ((Ecore_X_Atom)ev->data.data32[0] == ECORE_X_ATOM_NET_WM_PING)
1873 && (ev->format == 32))
1875 Ecore_X_Event_Ping *e;
1877 e = calloc(1, sizeof(Ecore_X_Event_Ping));
1879 e->win = ev->window;
1880 e->time = ev->data.data32[1];
1881 e->event_win = ev->data.data32[2];
1883 ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
1885 else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
1888 _ecore_x_netwm_startup_info_begin(ev->window, (char *)ev->data.data8);
1890 else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO) &&
1893 _ecore_x_netwm_startup_info(ev->window, (char *)ev->data.data8);
1895 else if ((ev->type == 27777)
1896 && (ev->data.data32[0] == 0x7162534)
1897 && (ev->format == 32)
1898 && (ev->window == _ecore_xcb_private_window))
1900 /* a grab sync marker */
1901 if (ev->data.data32[1] == 0x10000001)
1902 _ecore_x_window_grab_remove(ev->data.data32[2]);
1903 else if (ev->data.data32[1] == 0x10000002)
1904 _ecore_x_key_grab_remove(ev->data.data32[2]);
1908 Ecore_X_Event_Client_Message *e;
1911 e = calloc(1, sizeof(Ecore_X_Event_Client_Message));
1913 e->win = ev->window;
1914 e->message_type = ev->type;
1915 e->format = ev->format;
1916 for (i = 0; i < 5; i++)
1917 e->data.l[i] = ev->data.data32[i];
1919 ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
1924 _ecore_x_event_handle_mapping_notify(xcb_generic_event_t *event __UNUSED__)
1926 /* FIXME: handle this event type */
1930 _ecore_x_event_handle_shape_change(xcb_generic_event_t *event)
1932 #ifdef ECORE_X_SHAPE
1933 xcb_shape_notify_event_t *ev;
1934 Ecore_X_Event_Window_Shape *e;
1936 ev = (xcb_shape_notify_event_t *)event;
1937 e = calloc(1, sizeof(Ecore_X_Event_Window_Shape));
1939 e->win = ev->affected_window;
1940 e->time = ev->server_time;
1941 ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
1944 #endif /* ECORE_X_SHAPE */
1948 _ecore_x_event_handle_screensaver_notify(xcb_generic_event_t *event)
1950 #ifdef ECORE_X_SCREENSAVER
1951 xcb_screensaver_notify_event_t *ev;
1952 Ecore_X_Event_Screensaver_Notify *e;
1954 ev = (xcb_screensaver_notify_event_t *)event;
1955 e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify));
1957 e->win = ev->window;
1958 if (ev->state == XCB_SCREENSAVER_STATE_ON)
1963 ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
1966 #endif /* ECORE_X_SCREENSAVER */
1970 _ecore_x_event_handle_sync_counter(xcb_generic_event_t *event)
1973 xcb_sync_counter_notify_event_t *ev;
1974 Ecore_X_Event_Sync_Counter *e;
1976 ev = (xcb_sync_counter_notify_event_t *)event;
1977 e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter));
1979 e->time = ev->timestamp;
1980 ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
1983 #endif /* ECORE_X_SYNC */
1987 _ecore_x_event_handle_sync_alarm(xcb_generic_event_t *event)
1990 xcb_sync_alarm_notify_event_t *ev;
1991 Ecore_X_Event_Sync_Alarm *e;
1993 ev = (xcb_sync_alarm_notify_event_t *)event;
1994 e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm));
1996 e->time = ev->timestamp;
1997 e->alarm = ev->alarm;
1998 ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
2001 #endif /* ECORE_X_SYNC */
2004 /* FIXME: round trip */
2006 _ecore_x_event_handle_randr_change(xcb_generic_event_t *event)
2008 #ifdef ECORE_X_RANDR
2009 xcb_randr_screen_change_notify_event_t *ev;
2010 Ecore_X_Event_Screen_Change *e;
2012 ev = (xcb_randr_screen_change_notify_event_t *)event;
2014 if ((ev->response_type & ~0x80) != XCB_CONFIGURE_NOTIFY)
2016 xcb_query_extension_reply_t *rep;
2018 rep = xcb_query_extension_reply(_ecore_xcb_conn,
2019 xcb_query_extension_unchecked(_ecore_xcb_conn,
2025 (((ev->response_type & ~0x80) - rep->first_event) != XCB_RANDR_SCREEN_CHANGE_NOTIFY))
2026 printf("ERROR: Can't update RandR config!\n");
2031 e = calloc(1, sizeof(Ecore_X_Event_Screen_Change));
2033 e->win = ev->request_window;
2035 e->width = ev->width;
2036 e->height = ev->height;
2037 ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
2040 #endif /* ECORE_X_RANDR */
2044 _ecore_x_event_handle_fixes_selection_notify(xcb_generic_event_t *event)
2046 #ifdef ECORE_X_FIXES
2047 /* Nothing here yet */
2050 #endif /* ECORE_X_FIXES */
2054 _ecore_x_event_handle_damage_notify(xcb_generic_event_t *event)
2056 #ifdef ECORE_XCBDAMAGE
2057 xcb_damage_notify_event_t *ev;
2058 Ecore_X_Event_Damage *e;
2060 ev = (xcb_damage_notify_event_t *)event;
2061 e = calloc(1, sizeof(Ecore_X_Event_Damage));
2064 e->level = ev->level;
2065 e->drawable = ev->drawable;
2066 e->damage = ev->damage;
2067 /* FIXME: XCB has no 'more' member in xcb_damage_notify_event_t */
2068 /* e->more = ev->more; */
2069 e->time = ev->timestamp;
2070 e->area.x = ev->area.x;
2071 e->area.y = ev->area.y;
2072 e->area.width = ev->area.width;
2073 e->area.height = ev->area.height;
2074 e->geometry.x = ev->geometry.x;
2075 e->geometry.y = ev->geometry.y;
2076 e->geometry.width = ev->geometry.width;
2077 e->geometry.height = ev->geometry.height;
2079 ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
2082 #endif /* ECORE_XCBDAMAGE */