2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
14 #include <Ecore_Input.h>
16 #include "ecore_xcb_private.h"
17 #include "Ecore_X_Atoms.h"
20 /** OpenBSD does not define CODESET
25 #define CODESET "INVALID"
29 static void _ecore_x_event_free_window_prop_name_class_change(void *data, void *ev);
30 static void _ecore_x_event_free_window_prop_title_change(void *data, void *ev);
31 static void _ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev);
32 static void _ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev);
33 static void _ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev);
34 static void _ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev);
37 static Ecore_X_Window _ecore_xcb_mouse_down_last_window = 0;
38 static Ecore_X_Window _ecore_xcb_mouse_down_last_last_window = 0;
39 static Ecore_X_Window _ecore_xcb_mouse_down_last_event_window = 0;
40 static Ecore_X_Window _ecore_xcb_mouse_down_last_last_event_window = 0;
41 static Ecore_X_Time _ecore_xcb_mouse_down_last_time = 0;
42 static Ecore_X_Time _ecore_xcb_mouse_down_last_last_time = 0;
43 static int _ecore_xcb_mouse_up_count = 0;
44 static int _ecore_xcb_mouse_down_did_triple = 0;
45 static int _ecore_xcb_last_event_mouse_move = 0;
46 static Ecore_Event *_ecore_xcb_last_event_mouse_move_event = NULL;
49 _ecore_x_event_free_mouse_move(void *data __UNUSED__, void *ev)
51 Ecore_Event_Mouse_Move *e;
54 if (_ecore_xcb_last_event_mouse_move)
56 _ecore_xcb_last_event_mouse_move_event = NULL;
57 _ecore_xcb_last_event_mouse_move = 0;
63 /* FIXME: roundtrip */
65 ecore_x_event_mask_set(Ecore_X_Window window,
66 Ecore_X_Event_Mask mask)
68 xcb_get_window_attributes_cookie_t cookie;
69 xcb_get_window_attributes_reply_t *reply;
73 window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
75 cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
76 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
79 value_list = mask | reply->your_event_mask;
80 xcb_change_window_attributes(_ecore_xcb_conn, window, XCB_CW_EVENT_MASK, &value_list);
84 /* FIXME: roundtrip */
86 ecore_x_event_mask_unset(Ecore_X_Window window,
87 Ecore_X_Event_Mask mask)
89 xcb_get_window_attributes_cookie_t cookie;
90 xcb_get_window_attributes_reply_t *reply;
94 window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
96 cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
97 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
100 value_list = reply->your_event_mask & ~mask;
101 xcb_change_window_attributes(_ecore_xcb_conn, window, XCB_CW_EVENT_MASK, &value_list);
107 _ecore_x_event_free_window_prop_name_class_change(void *data, void *ev)
109 Ecore_X_Event_Window_Prop_Name_Class_Change *e;
112 if (e->name) free(e->name);
113 if (e->clas) free(e->clas);
118 _ecore_x_event_free_window_prop_title_change(void *data, void *ev)
120 Ecore_X_Event_Window_Prop_Title_Change *e;
123 if (e->title) free(e->title);
128 _ecore_x_event_free_window_prop_visible_title_change(void *data, void *ev)
130 Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
133 if (e->title) free(e->title);
138 _ecore_x_event_free_window_prop_icon_name_change(void *data, void *ev)
140 Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
143 if (e->name) free(e->name);
148 _ecore_x_event_free_window_prop_visible_icon_name_change(void *data, void *ev)
150 Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
153 if (e->name) free(e->name);
158 _ecore_x_event_free_window_prop_client_machine_change(void *data, void *ev)
160 Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
163 if (e->name) free(e->name);
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;
196 _ecore_x_event_modifiers(unsigned int state)
198 unsigned int modifiers = 0;
200 if (state & ECORE_X_MODIFIER_SHIFT) modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
201 if (state & ECORE_X_MODIFIER_CTRL) modifiers |= ECORE_EVENT_MODIFIER_CTRL;
202 if (state & ECORE_X_MODIFIER_ALT) modifiers |= ECORE_EVENT_MODIFIER_ALT;
203 if (state & ECORE_X_MODIFIER_WIN) modifiers |= ECORE_EVENT_MODIFIER_WIN;
204 if (state & ECORE_X_LOCK_SCROLL) modifiers |= ECORE_EVENT_LOCK_SCROLL;
205 if (state & ECORE_X_LOCK_NUM) modifiers |= ECORE_EVENT_LOCK_NUM;
206 if (state & ECORE_X_LOCK_CAPS) modifiers |= ECORE_EVENT_LOCK_CAPS;
212 _ecore_mouse_move(unsigned int timestamp, unsigned int xmodifiers,
214 int x_root, int y_root,
215 unsigned int event_window,
217 unsigned int root_win,
220 Ecore_Event_Mouse_Move *e;
223 e = malloc(sizeof(Ecore_Event_Mouse_Move));
227 e->root_window = root_win;
228 e->timestamp = timestamp;
229 e->same_screen = same_screen;
230 e->event_window = event_window;
232 e->modifiers = _ecore_x_event_modifiers(xmodifiers);
238 event = ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, _ecore_x_event_free_mouse_move, NULL);
240 _ecore_xcb_event_last_time = timestamp;
241 _ecore_xcb_event_last_window = window;
242 _ecore_xcb_event_last_root_x = x_root;
243 _ecore_xcb_event_last_root_y = y_root;
245 _ecore_xcb_last_event_mouse_move_event = event;
249 _ecore_key_press(int event,
250 xcb_generic_event_t *ev)
254 const char *compose = NULL;
258 char keyname_buffer[256];
259 char compose_buffer[256];
261 XComposeStatus status;
264 _ecore_xcb_last_event_mouse_move = 0;
265 keyname = XKeysymToString(XKeycodeToKeysym(xevent->display,
266 xevent->keycode, 0));
269 snprintf(keyname_buffer, sizeof(keyname_buffer), "Keycode-%i", xevent->keycode);
270 keyname = keyname_buffer;
271 if (!keyname) return ;
280 #ifdef X_HAVE_UTF8_STRING
281 val = Xutf8LookupString(_ecore_x_ic, (XKeyEvent *)xevent, compose_buffer, sizeof(compose_buffer) - 1, &sym, &mbstatus);
283 val = XmbLookupString(_ecore_x_ic, (XKeyEvent *)xevent, compose_buffer, sizeof(compose_buffer) - 1, &sym, &mbstatus);
285 if (mbstatus == XBufferOverflow)
287 tmp = malloc(sizeof (char) * (val + 1));
292 #ifdef X_HAVE_UTF8_STRING
293 val = Xutf8LookupString(_ecore_x_ic, (XKeyEvent *)xevent, tmp, val, &sym, &mbstatus);
295 val = XmbLookupString(_ecore_x_ic, (XKeyEvent *)xevent, tmp, val, &sym, &mbstatus);
301 #ifndef X_HAVE_UTF8_STRING
302 compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", tmp);
312 compose_buffer[val] = 0;
313 #ifdef X_HAVE_UTF8_STRING
314 compose = compose_buffer;
316 compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer);
323 val = XLookupString(xevent, compose_buffer, sizeof(compose_buffer), &sym, &status);
326 compose_buffer[val] = 0;
327 compose = eina_str_convert(nl_langinfo(CODESET), "UTF-8", compose_buffer);
332 key = XKeysymToString(sym);
333 if (!key) key = keyname;
334 if (!key) goto on_error;
336 e = malloc(sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) + (compose ? strlen(compose) : 0) + 3);
337 if (!e) goto on_error;
339 e->keyname = (char*) (e + 1);
340 e->key = e->keyname + strlen(keyname) + 1;
341 e->compose = (compose) ? e->key + strlen(key) + 1 : NULL;
342 e->string = e->compose;
344 strcpy((char *) e->keyname, keyname);
345 strcpy((char *) e->key, key);
346 if (compose) strcpy((char *) e->compose, compose);
348 e->modifiers = _ecore_x_event_modifiers(xevent->state);
350 e->timestamp = xevent->time;
351 e->window = xevent->subwindow ? xevent->subwindow : xevent->window;
352 e->event_window = xevent->window;
353 e->same_screen = xevent->same_screen;
354 e->root_window = xevent->root;
356 ecore_event_add(event, e, NULL, NULL);
358 _ecore_xcb_event_last_time = e->timestamp;
365 static Ecore_Event_Mouse_Button*
366 _ecore_mouse_button(int event,
367 unsigned int timestamp, unsigned int xmodifiers,
368 unsigned int buttons,
370 int x_root, int y_root,
371 unsigned int event_window,
373 unsigned int root_win,
376 Ecore_Event_Mouse_Button *e;
378 e = malloc(sizeof(Ecore_Event_Mouse_Button));
382 e->root_window = root_win;
383 e->timestamp = timestamp;
384 e->same_screen = same_screen;
385 e->event_window = event_window;
387 e->buttons = buttons;
388 e->modifiers = _ecore_x_event_modifiers(xmodifiers);
396 if (event_window == window)
398 if (((int)(timestamp - _ecore_xcb_mouse_down_last_time) <=
399 (int)(1000 * _ecore_xcb_double_click_time)) &&
400 (window == _ecore_xcb_mouse_down_last_window) &&
401 (event_window == _ecore_xcb_mouse_down_last_event_window)
404 if (((int)(timestamp - _ecore_xcb_mouse_down_last_last_time) <=
405 (int)(2 * 1000 * _ecore_xcb_double_click_time)) &&
406 (window == _ecore_xcb_mouse_down_last_window) &&
407 (window == _ecore_xcb_mouse_down_last_last_window) &&
408 (event_window == _ecore_xcb_mouse_down_last_event_window) &&
409 (event_window == _ecore_xcb_mouse_down_last_last_event_window)
413 _ecore_xcb_mouse_down_did_triple = 1;
416 _ecore_xcb_mouse_down_did_triple = 0;
419 if (event == ECORE_EVENT_MOUSE_BUTTON_DOWN
422 _ecore_xcb_mouse_up_count = 0;
424 _ecore_xcb_event_last_time = e->timestamp;
425 _ecore_xcb_event_last_window = e->window;
426 _ecore_xcb_event_last_root_x = x_root;
427 _ecore_xcb_event_last_root_y = y_root;
429 ecore_event_add(event, e, NULL, NULL);
435 _ecore_x_event_handle_any_event(xcb_generic_event_t *event)
437 xcb_generic_event_t* ev = malloc(sizeof(xcb_generic_event_t));
438 memcpy(ev, event, sizeof(xcb_generic_event_t));
440 ecore_event_add(ECORE_X_EVENT_ANY, ev, NULL, NULL);
443 /* FIXME: handle this event */
445 _ecore_x_event_handle_key_press(xcb_generic_event_t *event)
447 _ecore_key_press(ECORE_EVENT_KEY_DOWN, event);
452 /* FIXME: handle this event */
454 _ecore_x_event_handle_key_release(xcb_generic_event_t *event)
456 _ecore_key_press(ECORE_EVENT_KEY_DOWN, event);
462 _ecore_x_event_handle_button_press(xcb_generic_event_t *event)
464 xcb_button_press_event_t *ev;
467 ev = (xcb_button_press_event_t *)event;
468 if ((ev->detail > 3) && (ev->detail < 8))
470 Ecore_Event_Mouse_Wheel *e;
472 e = malloc(sizeof(Ecore_Event_Mouse_Wheel));
475 e->timestamp = ev->time;
476 e->modifiers = _ecore_x_event_modifiers(ev->state);
479 case 4: e->direction = 0; e->z = -1; break;
480 case 5: e->direction = 0; e->z = 1; break;
481 case 6: e->direction = 1; e->z = -1; break;
482 case 7: e->direction = 1; e->z = 1; break;
483 default: e->direction = 0; e->z = 0; break;
488 e->root.x = ev->root_x;
489 e->root.y = ev->root_y;
492 e->window = ev->child;
494 e->window = ev->event;
496 e->event_window = ev->event;
497 e->same_screen = ev->same_screen;
498 e->root_window = ev->root;
499 _ecore_xcb_event_last_time = e->timestamp;
500 _ecore_xcb_event_last_window = e->window;
501 _ecore_xcb_event_last_root_x = e->root.x;
502 _ecore_xcb_event_last_root_y = e->root.y;
503 ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
504 for (i = 0; i < _ecore_window_grabs_num; i++)
506 if ((_ecore_window_grabs[i] == ev->event) ||
507 (_ecore_window_grabs[i] == ev->child))
511 if (_ecore_window_grab_replay_func)
512 replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
513 ECORE_EVENT_MOUSE_WHEEL,
515 /* FIXME: xcb_key_press_event_t does not save the */
516 /* connection. So I use the current one */
518 xcb_allow_events(_ecore_xcb_conn,
519 XCB_ALLOW_REPLAY_POINTER,
522 xcb_allow_events(_ecore_xcb_conn,
523 XCB_ALLOW_ASYNC_POINTER,
532 _ecore_mouse_move(ev->time, ev->state,
533 ev->event_x, ev->event_y,
534 ev->root_x, ev->root_y,
536 (ev->child ? ev->child : ev->event),
541 Ecore_Event_Mouse_Button *e;
542 Ecore_X_Window event_window;
543 Ecore_X_Window child_window;
545 if (_ecore_xcb_mouse_down_did_triple)
547 _ecore_xcb_mouse_down_last_window = 0;
548 _ecore_xcb_mouse_down_last_last_window = 0;
549 _ecore_xcb_mouse_down_last_event_window = 0;
550 _ecore_xcb_mouse_down_last_last_event_window = 0;
551 _ecore_xcb_mouse_down_last_time = 0;
552 _ecore_xcb_mouse_down_last_last_time = 0;
554 event_window = ev->child;
555 child_window = ev->child ? ev->child : ev->event;
557 e = _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_DOWN,
560 ev->event_x, ev->event_y,
561 ev->root_x, ev->root_y,
562 event_window, child_window,
563 ev->root, ev->same_screen);
566 for (i = 0; i < _ecore_window_grabs_num; i++)
568 if ((_ecore_window_grabs[i] == ev->event) ||
569 (_ecore_window_grabs[i] == ev->child))
573 if (_ecore_window_grab_replay_func)
574 replay = _ecore_window_grab_replay_func(_ecore_window_grab_replay_data,
575 ECORE_EVENT_MOUSE_BUTTON_DOWN,
577 /* FIXME: xcb_key_press_event_t does not save the */
578 /* connection. So I use the current one */
580 xcb_allow_events(_ecore_xcb_conn,
581 XCB_ALLOW_REPLAY_POINTER,
584 xcb_allow_events(_ecore_xcb_conn,
585 XCB_ALLOW_ASYNC_POINTER,
590 if (child_window == event_window)
592 if (!_ecore_xcb_mouse_down_did_triple)
594 _ecore_xcb_mouse_down_last_last_window = _ecore_xcb_mouse_down_last_window;
596 _ecore_xcb_mouse_down_last_window = ev->child;
598 _ecore_xcb_mouse_down_last_window = ev->event;
599 _ecore_xcb_mouse_down_last_last_event_window = _ecore_xcb_mouse_down_last_event_window;
600 _ecore_xcb_mouse_down_last_event_window = ev->event;
601 _ecore_xcb_mouse_down_last_last_time = _ecore_xcb_mouse_down_last_time;
602 _ecore_xcb_mouse_down_last_time = ev->time;
612 _ecore_x_event_handle_button_release(xcb_generic_event_t *event)
614 xcb_button_release_event_t *ev;
616 ev = (xcb_button_release_event_t *)event;
617 _ecore_xcb_last_event_mouse_move = 0;
618 /* filter out wheel buttons */
619 if ((ev->detail <= 3) || (ev->detail > 7))
621 _ecore_mouse_move(ev->time, ev->state,
622 ev->event_x, ev->event_y,
623 ev->root_x, ev->root_y,
625 (ev->child ? ev->child : ev->event),
629 _ecore_mouse_button(ECORE_EVENT_MOUSE_BUTTON_UP,
632 ev->event_x, ev->event_y,
633 ev->root_x, ev->root_y,
635 (ev->child ? ev->child : ev->event),
644 _ecore_x_event_handle_motion_notify(xcb_generic_event_t *event)
646 xcb_motion_notify_event_t *ev;
648 ev = (xcb_motion_notify_event_t *)event;
649 if (_ecore_xcb_last_event_mouse_move)
651 ecore_event_del(_ecore_xcb_last_event_mouse_move_event);
652 _ecore_xcb_last_event_mouse_move = 0;
653 _ecore_xcb_last_event_mouse_move_event = NULL;
656 _ecore_mouse_move(ev->time, ev->state,
657 ev->event_x, ev->event_y,
658 ev->root_x, ev->root_y,
660 (ev->child ? ev->child : ev->event),
664 _ecore_xcb_last_event_mouse_move = 1;
667 _ecore_x_dnd_drag(ev->root, ev->root_x, ev->root_y);
673 _ecore_x_event_handle_enter_notify(xcb_generic_event_t *event)
675 xcb_enter_notify_event_t *ev;
677 ev = (xcb_enter_notify_event_t *)event;
678 _ecore_xcb_last_event_mouse_move = 0;
681 _ecore_mouse_move(ev->time, ev->state,
682 ev->event_x, ev->event_y,
683 ev->root_x, ev->root_y,
685 (ev->child ? ev->child : ev->event),
687 ev->same_screen_focus);
690 Ecore_X_Event_Mouse_In *e;
692 e = calloc(1, sizeof(Ecore_X_Event_Mouse_In));
694 e->modifiers = _ecore_x_event_modifiers(ev->state);
697 e->root.x = ev->root_x;
698 e->root.y = ev->root_y;
699 if (ev->child) e->win = ev->child;
700 else e->win = ev->event;
701 e->same_screen = ev->same_screen_focus;
702 e->root_win = ev->root;
703 e->event_win = ev->event;
705 case XCB_NOTIFY_MODE_NORMAL:
706 e->mode = ECORE_X_EVENT_MODE_NORMAL;
708 case XCB_NOTIFY_MODE_GRAB:
709 e->mode = ECORE_X_EVENT_MODE_GRAB;
711 case XCB_NOTIFY_MODE_UNGRAB:
712 e->mode = ECORE_X_EVENT_MODE_UNGRAB;
715 e->mode = ECORE_X_EVENT_MODE_NORMAL;
718 switch (ev->detail) {
719 case XCB_NOTIFY_DETAIL_ANCESTOR:
720 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
722 case XCB_NOTIFY_DETAIL_VIRTUAL:
723 e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
725 case XCB_NOTIFY_DETAIL_INFERIOR:
726 e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
728 case XCB_NOTIFY_DETAIL_NONLINEAR:
729 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
731 case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
732 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
735 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
739 _ecore_xcb_event_last_time = e->time;
740 ecore_event_add(ECORE_X_EVENT_MOUSE_IN, e, NULL, NULL);
747 _ecore_x_event_handle_leave_notify(xcb_generic_event_t *event)
749 xcb_leave_notify_event_t *ev;
751 ev = (xcb_leave_notify_event_t *)event;
752 _ecore_xcb_last_event_mouse_move = 0;
755 _ecore_mouse_move(ev->time, ev->state,
756 ev->event_x, ev->event_y,
757 ev->root_x, ev->root_y,
759 (ev->child ? ev->child : ev->event),
761 ev->same_screen_focus);
764 Ecore_X_Event_Mouse_Out *e;
766 e = calloc(1, sizeof(Ecore_X_Event_Mouse_Out));
768 e->modifiers = _ecore_x_event_modifiers(ev->state);
771 e->root.x = ev->root_x;
772 e->root.y = ev->root_y;
773 if (ev->child) e->win = ev->child;
774 else e->win = ev->event;
775 e->same_screen = ev->same_screen_focus;
776 e->root_win = ev->root;
777 e->event_win = ev->event;
779 case XCB_NOTIFY_MODE_NORMAL:
780 e->mode = ECORE_X_EVENT_MODE_NORMAL;
782 case XCB_NOTIFY_MODE_GRAB:
783 e->mode = ECORE_X_EVENT_MODE_GRAB;
785 case XCB_NOTIFY_MODE_UNGRAB:
786 e->mode = ECORE_X_EVENT_MODE_UNGRAB;
789 e->mode = ECORE_X_EVENT_MODE_NORMAL;
792 switch (ev->detail) {
793 case XCB_NOTIFY_DETAIL_ANCESTOR:
794 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
796 case XCB_NOTIFY_DETAIL_VIRTUAL:
797 e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
799 case XCB_NOTIFY_DETAIL_INFERIOR:
800 e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
802 case XCB_NOTIFY_DETAIL_NONLINEAR:
803 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
805 case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
806 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
809 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
813 _ecore_xcb_event_last_time = e->time;
814 _ecore_xcb_event_last_window = e->win;
815 _ecore_xcb_event_last_root_x = e->root.x;
816 _ecore_xcb_event_last_root_y = e->root.y;
817 ecore_event_add(ECORE_X_EVENT_MOUSE_OUT, e, NULL, NULL);
824 _ecore_x_event_handle_focus_in(xcb_generic_event_t *event)
826 xcb_focus_in_event_t *ev;
827 Ecore_X_Event_Window_Focus_In *e;
829 ev = (xcb_focus_in_event_t *)event;
830 e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In));
834 case XCB_NOTIFY_MODE_NORMAL:
835 e->mode = ECORE_X_EVENT_MODE_NORMAL;
837 case XCB_NOTIFY_MODE_GRAB:
838 e->mode = ECORE_X_EVENT_MODE_GRAB;
840 case XCB_NOTIFY_MODE_UNGRAB:
841 e->mode = ECORE_X_EVENT_MODE_UNGRAB;
843 case XCB_NOTIFY_MODE_WHILE_GRABBED:
844 e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
847 switch (ev->detail) {
848 case XCB_NOTIFY_DETAIL_ANCESTOR:
849 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
851 case XCB_NOTIFY_DETAIL_VIRTUAL:
852 e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
854 case XCB_NOTIFY_DETAIL_INFERIOR:
855 e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
857 case XCB_NOTIFY_DETAIL_NONLINEAR:
858 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
860 case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
861 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
863 case XCB_NOTIFY_DETAIL_POINTER:
864 e->detail = ECORE_X_EVENT_DETAIL_POINTER;
866 case XCB_NOTIFY_DETAIL_POINTER_ROOT:
867 e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
869 case XCB_NOTIFY_DETAIL_NONE:
870 e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
873 e->time = _ecore_xcb_event_last_time;
874 _ecore_xcb_event_last_time = e->time;
875 ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, e, NULL, NULL);
881 _ecore_x_event_handle_focus_out(xcb_generic_event_t *event)
883 xcb_focus_out_event_t *ev;
884 Ecore_X_Event_Window_Focus_Out *e;
886 ev = (xcb_focus_out_event_t *)event;
887 e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out));
891 case XCB_NOTIFY_MODE_NORMAL:
892 e->mode = ECORE_X_EVENT_MODE_NORMAL;
894 case XCB_NOTIFY_MODE_GRAB:
895 e->mode = ECORE_X_EVENT_MODE_GRAB;
897 case XCB_NOTIFY_MODE_UNGRAB:
898 e->mode = ECORE_X_EVENT_MODE_UNGRAB;
900 case XCB_NOTIFY_MODE_WHILE_GRABBED:
901 e->mode = ECORE_X_EVENT_MODE_WHILE_GRABBED;
904 switch (ev->detail) {
905 case XCB_NOTIFY_DETAIL_ANCESTOR:
906 e->detail = ECORE_X_EVENT_DETAIL_ANCESTOR;
908 case XCB_NOTIFY_DETAIL_VIRTUAL:
909 e->detail = ECORE_X_EVENT_DETAIL_VIRTUAL;
911 case XCB_NOTIFY_DETAIL_INFERIOR:
912 e->detail = ECORE_X_EVENT_DETAIL_INFERIOR;
914 case XCB_NOTIFY_DETAIL_NONLINEAR:
915 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR;
917 case XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL:
918 e->detail = ECORE_X_EVENT_DETAIL_NON_LINEAR_VIRTUAL;
920 case XCB_NOTIFY_DETAIL_POINTER:
921 e->detail = ECORE_X_EVENT_DETAIL_POINTER;
923 case XCB_NOTIFY_DETAIL_POINTER_ROOT:
924 e->detail = ECORE_X_EVENT_DETAIL_POINTER_ROOT;
926 case XCB_NOTIFY_DETAIL_NONE:
927 e->detail = ECORE_X_EVENT_DETAIL_DETAIL_NONE;
930 e->time = _ecore_xcb_event_last_time;
931 _ecore_xcb_event_last_time = e->time;
932 ecore_event_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, e, NULL, NULL);
938 _ecore_x_event_handle_keymap_notify(xcb_generic_event_t *event)
940 /* FIXME: handle this event type */
946 _ecore_x_event_handle_expose(xcb_generic_event_t *event)
948 xcb_expose_event_t *ev;
949 Ecore_X_Event_Window_Damage *e;
951 ev = (xcb_expose_event_t *)event,
952 e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
955 e->time = _ecore_xcb_event_last_time;
960 e->count = ev->count;
961 ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
967 _ecore_x_event_handle_graphics_expose(xcb_generic_event_t *event)
969 xcb_graphics_exposure_event_t *ev;
970 Ecore_X_Event_Window_Damage *e;
972 ev = (xcb_graphics_exposure_event_t *)event;
973 e = calloc(1, sizeof(Ecore_X_Event_Window_Damage));
975 e->win = ev->drawable;
976 e->time = _ecore_xcb_event_last_time;
981 e->count = ev->count;
982 ecore_event_add(ECORE_X_EVENT_WINDOW_DAMAGE, e, NULL, NULL);
988 _ecore_x_event_handle_visibility_notify(xcb_generic_event_t *event)
990 xcb_visibility_notify_event_t *ev;
992 ev = (xcb_visibility_notify_event_t *)event;
993 if (ev->state != XCB_VISIBILITY_PARTIALLY_OBSCURED)
995 Ecore_X_Event_Window_Visibility_Change *e;
997 e = calloc(1, sizeof(Ecore_X_Event_Window_Visibility_Change));
1000 e->time = _ecore_xcb_event_last_time;
1001 if (ev->state == XCB_VISIBILITY_FULLY_OBSCURED)
1002 e->fully_obscured = 1;
1004 e->fully_obscured = 0;
1005 ecore_event_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, e, NULL, NULL);
1012 _ecore_x_event_handle_create_notify(xcb_generic_event_t *event)
1014 xcb_create_notify_event_t *ev;
1015 Ecore_X_Event_Window_Create *e;
1017 ev = (xcb_create_notify_event_t *)event;
1018 e = calloc(1, sizeof(Ecore_X_Event_Window_Create));
1020 e->win = ev->window;
1021 if (ev->override_redirect)
1025 e->time = _ecore_xcb_event_last_time;
1026 ecore_event_add(ECORE_X_EVENT_WINDOW_CREATE, e, NULL, NULL);
1032 _ecore_x_event_handle_destroy_notify(xcb_generic_event_t *event)
1034 xcb_destroy_notify_event_t *ev;
1035 Ecore_X_Event_Window_Destroy *e;
1037 ev = (xcb_destroy_notify_event_t *)event;
1038 e = calloc(1, sizeof(Ecore_X_Event_Window_Destroy));
1040 e->win = ev->window;
1041 e->time = _ecore_xcb_event_last_time;
1042 if (e->win == _ecore_xcb_event_last_window) _ecore_xcb_event_last_window = 0;
1043 ecore_event_add(ECORE_X_EVENT_WINDOW_DESTROY, e, NULL, NULL);
1049 _ecore_x_event_handle_unmap_notify(xcb_generic_event_t *event)
1051 xcb_unmap_notify_event_t *ev;
1052 Ecore_X_Event_Window_Hide *e;
1054 ev = (xcb_unmap_notify_event_t *)event;
1055 e = calloc(1, sizeof(Ecore_X_Event_Window_Hide));
1057 e->win = ev->window;
1058 e->time = _ecore_xcb_event_last_time;
1059 ecore_event_add(ECORE_X_EVENT_WINDOW_HIDE, e, NULL, NULL);
1065 _ecore_x_event_handle_map_notify(xcb_generic_event_t *event)
1067 xcb_map_notify_event_t *ev;
1068 Ecore_X_Event_Window_Show *e;
1070 ev = (xcb_map_notify_event_t *)event;
1071 e = calloc(1, sizeof(Ecore_X_Event_Window_Show));
1073 e->win = ev->window;
1074 e->time = _ecore_xcb_event_last_time;
1075 ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW, e, NULL, NULL);
1081 _ecore_x_event_handle_map_request(xcb_generic_event_t *event)
1083 xcb_map_request_event_t *ev;
1084 Ecore_X_Event_Window_Show_Request *e;
1086 ev = (xcb_map_request_event_t *)event;
1087 e = calloc(1, sizeof(Ecore_X_Event_Window_Show_Request));
1089 e->win = ev->window;
1090 e->parent = ev->parent;
1091 e->time = _ecore_xcb_event_last_time;
1092 ecore_event_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, e, NULL, NULL);
1098 _ecore_x_event_handle_reparent_notify(xcb_generic_event_t *event)
1100 xcb_reparent_notify_event_t *ev;
1101 Ecore_X_Event_Window_Reparent *e;
1103 ev = (xcb_reparent_notify_event_t *)event;
1104 e = calloc(1, sizeof(Ecore_X_Event_Window_Reparent));
1106 e->win = ev->window;
1107 e->parent = ev->parent;
1108 e->time = _ecore_xcb_event_last_time;
1109 ecore_event_add(ECORE_X_EVENT_WINDOW_REPARENT, e, NULL, NULL);
1115 _ecore_x_event_handle_configure_notify(xcb_generic_event_t *event)
1117 xcb_configure_notify_event_t *ev;
1118 Ecore_X_Event_Window_Configure *e;
1120 ev = (xcb_configure_notify_event_t *)event;
1121 e = calloc(1, sizeof(Ecore_X_Event_Window_Configure));
1123 e->win = ev->window;
1124 e->abovewin = ev->above_sibling;
1129 e->border = ev->border_width;
1130 e->override = ev->override_redirect;
1131 /* send_event is bit 7 (0x80) of response_type */
1132 e->from_wm = (ev->response_type & 0x80) ? 1 : 0;
1133 e->time = _ecore_xcb_event_last_time;
1134 ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE, e, NULL, NULL);
1140 _ecore_x_event_handle_configure_request(xcb_generic_event_t *event)
1142 xcb_configure_request_event_t *ev;
1143 Ecore_X_Event_Window_Configure_Request *e;
1145 ev = (xcb_configure_request_event_t *)event;
1146 e = calloc(1, sizeof(Ecore_X_Event_Window_Configure_Request));
1148 e->win = ev->window;
1149 e->abovewin = ev->sibling;
1154 e->border = ev->border_width;
1155 e->value_mask = ev->value_mask;
1156 switch (ev->stack_mode) {
1157 case XCB_STACK_MODE_ABOVE:
1158 e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1160 case XCB_STACK_MODE_BELOW:
1161 e->detail = ECORE_X_WINDOW_STACK_BELOW;
1163 case XCB_STACK_MODE_TOP_IF:
1164 e->detail = ECORE_X_WINDOW_STACK_TOP_IF;
1166 case XCB_STACK_MODE_BOTTOM_IF:
1167 e->detail = ECORE_X_WINDOW_STACK_BOTTOM_IF;
1169 case XCB_STACK_MODE_OPPOSITE:
1170 e->detail = ECORE_X_WINDOW_STACK_OPPOSITE;
1173 e->time = _ecore_xcb_event_last_time;
1174 ecore_event_add(ECORE_X_EVENT_WINDOW_CONFIGURE_REQUEST, e, NULL, NULL);
1180 _ecore_x_event_handle_gravity_notify(xcb_generic_event_t *event)
1182 /* FIXME: handle this event type */
1188 _ecore_x_event_handle_resize_request(xcb_generic_event_t *event)
1190 xcb_resize_request_event_t *ev;
1191 Ecore_X_Event_Window_Resize_Request *e;
1193 ev = (xcb_resize_request_event_t *)event;
1194 e = calloc(1, sizeof(Ecore_X_Event_Window_Resize_Request));
1196 e->win = ev->window;
1199 e->time = _ecore_xcb_event_last_time;
1200 ecore_event_add(ECORE_X_EVENT_WINDOW_RESIZE_REQUEST, e, NULL, NULL);
1206 _ecore_x_event_handle_circulate_notify(xcb_generic_event_t *event)
1208 xcb_circulate_notify_event_t *ev;
1209 Ecore_X_Event_Window_Stack *e;
1211 ev = (xcb_circulate_notify_event_t *)event;
1212 e = calloc(1, sizeof(Ecore_X_Event_Window_Stack));
1214 e->win = ev->window;
1215 e->event_win = ev->event;
1216 if (ev->place == XCB_PLACE_ON_TOP)
1217 e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1219 e->detail = ECORE_X_WINDOW_STACK_BELOW;
1220 e->time = _ecore_xcb_event_last_time;
1221 ecore_event_add(ECORE_X_EVENT_WINDOW_STACK, e, NULL, NULL);
1227 _ecore_x_event_handle_circulate_request(xcb_generic_event_t *event)
1229 xcb_circulate_request_event_t *ev;
1230 Ecore_X_Event_Window_Stack_Request *e;
1232 ev = (xcb_circulate_request_event_t *)event;
1233 e = calloc(1, sizeof(Ecore_X_Event_Window_Stack_Request));
1235 e->win = ev->window;
1236 e->parent = ev->event;
1237 if (ev->place == XCB_PLACE_ON_TOP)
1238 e->detail = ECORE_X_WINDOW_STACK_ABOVE;
1240 e->detail = ECORE_X_WINDOW_STACK_BELOW;
1241 e->time = _ecore_xcb_event_last_time;
1242 ecore_event_add(ECORE_X_EVENT_WINDOW_STACK_REQUEST, e, NULL, NULL);
1248 _ecore_x_event_handle_property_notify(xcb_generic_event_t *event)
1250 #if 0 /* for now i disabled this. nice idea though this is - it leaves a lot
1251 * to be desired for efficiency that is better left to the app layer
1253 if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLASS)
1255 Ecore_X_Event_Window_Prop_Name_Class_Change *e;
1257 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Name_Class_Change));
1259 ecore_x_window_prop_name_class_get(xevent->xproperty.window,
1260 &(e->name), &(e->clas));
1261 e->time = xevent->xproperty.time;
1262 _ecore_x_event_last_time = e->time;
1263 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_NAME_CLASS_CHANGE, e, _ecore_x_event_free_window_prop_name_class_change, NULL);
1265 else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_NAME))
1267 Ecore_X_Event_Window_Prop_Title_Change *e;
1269 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Title_Change));
1271 e->title = ecore_x_window_prop_title_get(xevent->xproperty.window);
1272 e->time = xevent->xproperty.time;
1273 _ecore_x_event_last_time = e->time;
1274 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_title_change, NULL);
1276 else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_NAME)
1278 Ecore_X_Event_Window_Prop_Visible_Title_Change *e;
1280 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Title_Change));
1282 e->title = ecore_x_window_prop_visible_title_get(xevent->xproperty.window);
1283 e->time = xevent->xproperty.time;
1284 _ecore_x_event_last_time = e->time;
1285 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_TITLE_CHANGE, e, _ecore_x_event_free_window_prop_visible_title_change, NULL);
1287 else if ((xevent->xproperty.atom == ECORE_X_ATOM_WM_ICON_NAME) || (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_ICON_NAME))
1289 Ecore_X_Event_Window_Prop_Icon_Name_Change *e;
1291 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Icon_Name_Change));
1293 e->name = ecore_x_window_prop_icon_name_get(xevent->xproperty.window);
1294 e->time = xevent->xproperty.time;
1295 _ecore_x_event_last_time = e->time;
1296 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_icon_name_change, NULL);
1298 else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME)
1300 Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change *e;
1302 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Visible_Icon_Name_Change));
1304 e->name = ecore_x_window_prop_visible_icon_name_get(xevent->xproperty.window);
1305 e->time = xevent->xproperty.time;
1306 _ecore_x_event_last_time = e->time;
1307 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_VISIBLE_ICON_NAME_CHANGE, e, _ecore_x_event_free_window_prop_visible_icon_name_change, NULL);
1309 else if (xevent->xproperty.atom == ECORE_X_ATOM_WM_CLIENT_MACHINE)
1311 Ecore_X_Event_Window_Prop_Client_Machine_Change *e;
1313 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Client_Machine_Change));
1315 e->name = ecore_x_window_prop_client_machine_get(xevent->xproperty.window);
1316 e->time = xevent->xproperty.time;
1317 _ecore_x_event_last_time = e->time;
1318 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_CLIENT_MACHINE_CHANGE, e, _ecore_x_event_free_window_prop_client_machine_change, NULL);
1320 else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_PID)
1322 Ecore_X_Event_Window_Prop_Pid_Change *e;
1324 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Pid_Change));
1326 e->pid = ecore_x_window_prop_pid_get(xevent->xproperty.window);
1327 e->time = xevent->xproperty.time;
1328 _ecore_x_event_last_time = e->time;
1329 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
1331 else if (xevent->xproperty.atom == ECORE_X_ATOM_NET_WM_DESKTOP)
1333 Ecore_X_Event_Window_Prop_Desktop_Change *e;
1335 e = calloc(1, sizeof(Ecore_X_Event_Window_Prop_Desktop_Change));
1337 e->desktop = ecore_x_window_prop_desktop_get(xevent->xproperty.window);
1338 ecore_event_add(ECORE_X_EVENT_WINDOW_PROP_PID_CHANGE, e, NULL, NULL);
1343 xcb_property_notify_event_t *ev;
1344 Ecore_X_Event_Window_Property *e;
1346 ev = (xcb_property_notify_event_t *)event;
1347 e = calloc(1,sizeof(Ecore_X_Event_Window_Property));
1349 e->win = ev->window;
1352 _ecore_xcb_event_last_time = e->time;
1353 ecore_event_add(ECORE_X_EVENT_WINDOW_PROPERTY, e, NULL, NULL);
1360 _ecore_x_event_handle_selection_clear(xcb_generic_event_t *event)
1362 xcb_selection_clear_event_t *ev;
1363 Ecore_X_Selection_Intern *d;
1364 Ecore_X_Event_Selection_Clear *e;
1367 ev = (xcb_selection_clear_event_t *)event;
1368 d = _ecore_x_selection_get(ev->selection);
1369 if (d && (ev->time > d->time))
1371 _ecore_x_selection_set(XCB_NONE, NULL, 0,
1375 /* Generate event for app cleanup */
1376 e = malloc(sizeof(Ecore_X_Event_Selection_Clear));
1379 e->atom = sel = ev->selection;
1380 if (sel == ECORE_X_ATOM_SELECTION_PRIMARY)
1381 e->selection = ECORE_X_SELECTION_PRIMARY;
1382 else if (sel == ECORE_X_ATOM_SELECTION_SECONDARY)
1383 e->selection = ECORE_X_SELECTION_SECONDARY;
1384 else if (sel == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1385 e->selection = ECORE_X_SELECTION_CLIPBOARD;
1387 e->selection = ECORE_X_SELECTION_OTHER;
1388 ecore_event_add(ECORE_X_EVENT_SELECTION_CLEAR, e, NULL, NULL);
1394 _ecore_x_event_handle_selection_request(xcb_generic_event_t *event)
1396 xcb_selection_request_event_t *ev;
1397 Ecore_X_Selection_Intern *sd;
1398 xcb_selection_notify_event_t sn_event;
1401 ev = (xcb_selection_request_event_t *)event;
1402 /* FIXME: is it the correct value ? */
1403 sn_event.response_type = XCB_SELECTION_NOTIFY;
1405 /* FIXME: is it the correct value ? */
1406 sn_event.sequence = 0;
1407 sn_event.time = XCB_CURRENT_TIME;
1408 sn_event.requestor = ev->requestor;
1409 sn_event.selection = ev->selection;
1410 sn_event.target = ev->target;
1412 if ((sd = _ecore_x_selection_get(ev->selection)) &&
1413 (sd->win == ev->owner))
1415 if (!ecore_x_selection_convert(ev->selection, ev->target,
1418 /* Refuse selection, conversion to requested target failed */
1419 sn_event.property = XCB_NONE;
1423 /* FIXME: This does not properly handle large data transfers */
1424 ecore_x_window_prop_property_set(ev->requestor,
1427 8, data, sd->length);
1428 sn_event.property = ev->property;
1434 sn_event.property = XCB_NONE;
1438 /* FIXME: I use _ecore_xcb_conn, as ev has no information on the connection */
1439 xcb_send_event(_ecore_xcb_conn, 0,
1440 ev->requestor, 0, (const char *)&sn_event);
1445 /* FIXME: round trip */
1447 _ecore_x_event_handle_selection_notify(xcb_generic_event_t *event)
1449 xcb_selection_notify_event_t *ev;
1450 Ecore_X_Event_Selection_Notify *e;
1451 unsigned char *data = NULL;
1452 Ecore_X_Atom selection;
1456 ev = (xcb_selection_notify_event_t *)event;
1457 selection = ev->selection;
1459 if (ev->target == ECORE_X_ATOM_SELECTION_TARGETS)
1461 ecore_x_window_prop_property_get_prefetch(ev->requestor,
1464 ecore_x_window_prop_property_get_fetch();
1465 format = ecore_x_window_prop_property_get(ev->requestor,
1471 if (!format) return;
1475 ecore_x_window_prop_property_get_prefetch(ev->requestor,
1477 XCB_GET_PROPERTY_TYPE_ANY);
1478 ecore_x_window_prop_property_get_fetch();
1479 format = ecore_x_window_prop_property_get(ev->requestor,
1485 if (!format) return;
1488 e = calloc(1, sizeof(Ecore_X_Event_Selection_Notify));
1490 e->win = ev->requestor;
1492 e->atom = selection;
1493 e->target = _ecore_x_selection_target_get(ev->target);
1495 if (selection == ECORE_X_ATOM_SELECTION_PRIMARY)
1496 e->selection = ECORE_X_SELECTION_PRIMARY;
1497 else if (selection == ECORE_X_ATOM_SELECTION_SECONDARY)
1498 e->selection = ECORE_X_SELECTION_SECONDARY;
1499 else if (selection == ECORE_X_ATOM_SELECTION_XDND)
1500 e->selection = ECORE_X_SELECTION_XDND;
1501 else if (selection == ECORE_X_ATOM_SELECTION_CLIPBOARD)
1502 e->selection = ECORE_X_SELECTION_CLIPBOARD;
1504 e->selection = ECORE_X_SELECTION_OTHER;
1506 e->data = _ecore_x_selection_parse(e->target, data, num_ret, format);
1508 ecore_event_add(ECORE_X_EVENT_SELECTION_NOTIFY, e, _ecore_x_event_free_selection_notify, NULL);
1514 _ecore_x_event_handle_colormap_notify(xcb_generic_event_t *event)
1516 xcb_colormap_notify_event_t *ev;
1517 Ecore_X_Event_Window_Colormap *e;
1519 ev = (xcb_colormap_notify_event_t *)event;
1520 e = calloc(1,sizeof(Ecore_X_Event_Window_Colormap));
1522 e->win = ev->window;
1523 e->cmap = ev->colormap;
1524 if (ev->state == XCB_COLORMAP_STATE_INSTALLED)
1528 e->time = _ecore_xcb_event_last_time;
1529 ecore_event_add(ECORE_X_EVENT_WINDOW_COLORMAP, e, NULL, NULL);
1535 _ecore_x_event_handle_client_message(xcb_generic_event_t *event)
1537 /* Special client message event handling here. need to put LOTS of if */
1538 /* checks here and generate synthetic events per special message known */
1539 /* otherwise generate generic client message event. this would handle*/
1540 /* netwm, ICCCM, gnomewm, old kde and mwm hint client message protocols */
1542 xcb_client_message_event_t *ev;
1544 ev = (xcb_client_message_event_t *)event;
1545 if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS) &&
1546 (ev->format == 32) &&
1547 (ev->data.data32[0] == (uint32_t)ECORE_X_ATOM_WM_DELETE_WINDOW))
1549 Ecore_X_Event_Window_Delete_Request *e;
1551 e = calloc(1, sizeof(Ecore_X_Event_Window_Delete_Request));
1553 e->win = ev->window;
1554 e->time = _ecore_xcb_event_last_time;
1555 ecore_event_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, e, NULL, NULL);
1558 else if ((ev->type == ECORE_X_ATOM_NET_WM_MOVERESIZE) &&
1559 (ev->format == 32) &&
1560 /* Ignore move and resize with keyboard */
1561 (ev->data.data32[2] < 9))
1563 Ecore_X_Event_Window_Move_Resize_Request *e;
1565 e = calloc(1, sizeof(Ecore_X_Event_Window_Move_Resize_Request));
1567 e->win = ev->window;
1568 e->x = ev->data.data32[0];
1569 e->y = ev->data.data32[1];
1570 e->direction = ev->data.data32[2];
1571 e->button = ev->data.data32[3];
1572 e->source = ev->data.data32[4];
1573 ecore_event_add(ECORE_X_EVENT_WINDOW_MOVE_RESIZE_REQUEST, e, NULL, NULL);
1576 /* Xdnd Client Message Handling Begin */
1577 /* Message Type: XdndEnter target */
1578 else if (ev->type == ECORE_X_ATOM_XDND_ENTER)
1580 Ecore_X_Event_Xdnd_Enter *e;
1581 Ecore_X_DND_Target *target;
1584 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Enter));
1587 target = _ecore_x_dnd_target_get();
1588 target->state = ECORE_X_DND_TARGET_ENTERED;
1590 target = _ecore_x_dnd_target_get();
1591 target->source = ev->data.data32[0];
1592 target->win = ev->window;
1593 target->version = ev->data.data32[1] >> 24;
1594 if (target->version > ECORE_X_DND_VERSION)
1596 WRN("DND: Requested version %d, we only support up to %d", target->version,
1597 ECORE_X_DND_VERSION);
1601 /* FIXME: roud trip, but I don't know how to suppress it */
1602 if ((three = ev->data.data32[1] & 0x1UL))
1604 /* source supports more than 3 types, fetch property */
1605 unsigned char *data;
1606 Ecore_X_Atom *types;
1611 ecore_x_window_prop_property_get_prefetch(target->source,
1612 ECORE_X_ATOM_XDND_TYPE_LIST,
1614 ecore_x_window_prop_property_get_fetch();
1615 format = ecore_x_window_prop_property_get(target->source,
1616 ECORE_X_ATOM_XDND_TYPE_LIST,
1623 ERR("DND: Could not fetch data type list from source window, aborting.");
1626 types = (Ecore_X_Atom *)data;
1627 e->types = calloc(num_ret, sizeof(char *));
1630 xcb_get_atom_name_cookie_t *cookies;
1632 cookies = (xcb_get_atom_name_cookie_t *)malloc(sizeof(xcb_get_atom_name_cookie_t) * num_ret);
1633 for (i = 0; i < num_ret; i++)
1634 cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, types[i]);
1635 for (i = 0; i < num_ret; i++)
1637 xcb_get_atom_name_reply_t *reply;
1640 reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL);
1643 name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1645 xcb_get_atom_name_name(reply),
1647 name[reply->name_len] = '\0';
1654 e->num_types = num_ret;
1660 e->types = calloc(3, sizeof(char *));
1663 xcb_get_atom_name_cookie_t cookies[3];
1665 for (i = 0; i < 3; i++)
1666 cookies[i] = xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[i + 2]);
1667 for (i = 0; i < 3; i++)
1669 xcb_get_atom_name_reply_t *reply;
1672 reply = xcb_get_atom_name_reply(_ecore_xcb_conn, cookies[i], NULL);
1673 if (reply && (ev->data.data32[i + 2]))
1675 name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1677 xcb_get_atom_name_name(reply),
1679 name[reply->name_len] = '\0';
1682 if (reply) free(reply);
1688 e->win = target->win;
1689 e->source = target->source;
1690 ecore_event_add(ECORE_X_EVENT_XDND_ENTER, e, _ecore_x_event_free_xdnd_enter, NULL);
1693 /* Message Type: XdndPosition target */
1694 else if (ev->type == ECORE_X_ATOM_XDND_POSITION)
1696 Ecore_X_Event_Xdnd_Position *e;
1697 Ecore_X_DND_Target *target;
1699 target = _ecore_x_dnd_target_get();
1700 if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1701 (target->win != ev->window))
1704 target->pos.x = (int16_t)ev->data.data32[2] >> 16;
1705 target->pos.y = (int16_t)ev->data.data32[2] & 0xFFFFUL;
1706 target->action = ev->data.data32[4]; /* Version 2 */
1708 target->time = (target->version >= 1) ?
1709 ev->data.data32[3] : XCB_CURRENT_TIME;
1711 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Position));
1713 e->win = target->win;
1714 e->source = target->source;
1715 e->position.x = target->pos.x;
1716 e->position.y = target->pos.y;
1717 e->action = target->action;
1718 ecore_event_add(ECORE_X_EVENT_XDND_POSITION, e, NULL, NULL);
1721 /* Message Type: XdndStatus source */
1722 else if (ev->type == ECORE_X_ATOM_XDND_STATUS)
1724 Ecore_X_Event_Xdnd_Status *e;
1725 Ecore_X_DND_Source *source;
1727 source = _ecore_x_dnd_source_get();
1728 /* Make sure source/target match */
1729 if ((source->win != ev->window ) ||
1730 (source->dest != ev->data.data32[0]))
1733 source->await_status = 0;
1735 source->will_accept = ev->data.data32[1] & 0x1UL;
1736 source->suppress = (ev->data.data32[1] & 0x2UL) ? 0 : 1;
1738 source->rectangle.x = (int16_t)ev->data.data32[2] >> 16;
1739 source->rectangle.y = (int16_t)ev->data.data32[2] & 0xFFFFUL;
1740 source->rectangle.width = (uint16_t)ev->data.data32[3] >> 16;
1741 source->rectangle.height = (uint16_t)ev->data.data32[3] & 0xFFFFUL;
1743 source->accepted_action = ev->data.data32[4];
1745 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Status));
1747 e->win = source->win;
1748 e->target = source->dest;
1749 e->will_accept = source->will_accept;
1750 e->rectangle.x = source->rectangle.x;
1751 e->rectangle.y = source->rectangle.y;
1752 e->rectangle.width = source->rectangle.width;
1753 e->rectangle.height = source->rectangle.height;
1754 e->action = source->accepted_action;
1756 ecore_event_add(ECORE_X_EVENT_XDND_STATUS, e, NULL, NULL);
1759 /* Message Type: XdndLeave target */
1760 /* Pretend the whole thing never happened, sort of */
1761 else if (ev->type == ECORE_X_ATOM_XDND_LEAVE)
1763 Ecore_X_Event_Xdnd_Leave *e;
1764 Ecore_X_DND_Target *target;
1766 target = _ecore_x_dnd_target_get();
1767 if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1768 (target->win != ev->window))
1771 target->state = ECORE_X_DND_TARGET_IDLE;
1773 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Leave));
1775 e->win = ev->window;
1776 e->source = ev->data.data32[0];
1777 ecore_event_add(ECORE_X_EVENT_XDND_LEAVE, e, NULL, NULL);
1780 /* Message Type: XdndDrop target */
1781 else if (ev->type == ECORE_X_ATOM_XDND_DROP)
1783 Ecore_X_Event_Xdnd_Drop *e;
1784 Ecore_X_DND_Target *target;
1786 target = _ecore_x_dnd_target_get();
1787 /* Match source/target */
1788 if ((target->source != (Ecore_X_Window)ev->data.data32[0]) ||
1789 (target->win != ev->window))
1792 target->time = (target->version >= 1) ?
1793 ev->data.data32[2] : _ecore_xcb_event_last_time;
1795 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Drop));
1797 e->win = target->win;
1798 e->source = target->source;
1799 e->action = target->action;
1800 e->position.x = target->pos.x;
1801 e->position.y = target->pos.y;
1802 ecore_event_add(ECORE_X_EVENT_XDND_DROP, e, NULL, NULL);
1805 /* Message Type: XdndFinished source */
1806 else if (ev->type == ECORE_X_ATOM_XDND_FINISHED)
1808 Ecore_X_Event_Xdnd_Finished *e;
1809 Ecore_X_DND_Source *source;
1810 uint8_t completed = 1;
1812 source = _ecore_x_dnd_source_get();
1813 /* Match source/target */
1814 if ((source->win != ev->window) ||
1815 (source->dest != ev->data.data32[0]))
1818 if ((source->version >= 5) && (ev->data.data32[1] & 0x1UL))
1820 /* Target successfully performed drop action */
1821 ecore_x_selection_xdnd_clear();
1822 source->state = ECORE_X_DND_SOURCE_IDLE;
1827 source->state = ECORE_X_DND_SOURCE_CONVERTING;
1829 /* FIXME: Probably need to add a timer to switch back to idle
1830 * and discard the selection data */
1833 e = calloc(1, sizeof(Ecore_X_Event_Xdnd_Finished));
1835 e->win = source->win;
1836 e->target = source->dest;
1837 e->completed = completed;
1838 if (source->version >= 5)
1840 source->accepted_action = ev->data.data32[2];
1841 e->action = source->accepted_action;
1845 source->accepted_action = 0;
1846 e->action = source->action;
1849 ecore_event_add(ECORE_X_EVENT_XDND_FINISHED, e, NULL, NULL);
1851 else if (ev->type == ECORE_X_ATOM_NET_WM_STATE)
1853 Ecore_X_Event_Window_State_Request *e;
1855 e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1857 e->win = ev->window;
1858 if (ev->data.data32[0] == 0)
1859 e->action = ECORE_X_WINDOW_STATE_ACTION_REMOVE;
1860 else if (ev->data.data32[0] == 1)
1861 e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1862 else if (ev->data.data32[0] == 2)
1863 e->action = ECORE_X_WINDOW_STATE_ACTION_TOGGLE;
1869 e->state[0] = _ecore_x_netwm_state_get(ev->data.data32[1]);
1870 if (e->state[0] == ECORE_X_WINDOW_STATE_UNKNOWN)
1872 xcb_get_atom_name_reply_t *reply;
1875 /* FIXME: round trip */
1876 reply = xcb_get_atom_name_reply(_ecore_xcb_conn,
1877 xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[1]),
1881 name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1883 xcb_get_atom_name_name(reply),
1885 name[reply->name_len] = '\0';
1886 ERR("Unknown state: %s", name);
1891 e->state[1] = _ecore_x_netwm_state_get(ev->data.data32[2]);
1892 if (e->state[1] == ECORE_X_WINDOW_STATE_UNKNOWN)
1894 xcb_get_atom_name_reply_t *reply;
1897 reply = xcb_get_atom_name_reply(_ecore_xcb_conn,
1898 xcb_get_atom_name_unchecked(_ecore_xcb_conn, ev->data.data32[2]),
1902 name = (char *)malloc(sizeof (char) * (reply->name_len + 1));
1904 xcb_get_atom_name_name(reply),
1906 name[reply->name_len] = '\0';
1907 WRN("Unknown state: %s", name);
1911 e->source = ev->data.data32[3];
1913 ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1915 else if ((ev->type == ECORE_X_ATOM_WM_CHANGE_STATE)
1916 && (ev->format == 32)
1917 && (ev->data.data32[0] == XCB_WM_HINT_STATE))
1919 Ecore_X_Event_Window_State_Request *e;
1921 e = calloc(1, sizeof(Ecore_X_Event_Window_State_Request));
1923 e->win = ev->window;
1924 e->action = ECORE_X_WINDOW_STATE_ACTION_ADD;
1925 e->state[0] = ECORE_X_WINDOW_STATE_ICONIFIED;
1927 ecore_event_add(ECORE_X_EVENT_WINDOW_STATE_REQUEST, e, NULL, NULL);
1929 else if ((ev->type == ECORE_X_ATOM_NET_WM_DESKTOP)
1930 && (ev->format == 32))
1932 Ecore_X_Event_Desktop_Change *e;
1934 e = calloc(1, sizeof(Ecore_X_Event_Desktop_Change));
1936 e->win = ev->window;
1937 e->desk = ev->data.data32[0];
1938 e->source = ev->data.data32[1];
1940 ecore_event_add(ECORE_X_EVENT_DESKTOP_CHANGE, e, NULL, NULL);
1942 else if ((ev->type == ECORE_X_ATOM_NET_REQUEST_FRAME_EXTENTS))
1944 Ecore_X_Event_Frame_Extents_Request *e;
1946 e = calloc(1, sizeof(Ecore_X_Event_Frame_Extents_Request));
1948 e->win = ev->window;
1950 ecore_event_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, e, NULL, NULL);
1952 else if ((ev->type == ECORE_X_ATOM_WM_PROTOCOLS)
1953 && ((Ecore_X_Atom)ev->data.data32[0] == ECORE_X_ATOM_NET_WM_PING)
1954 && (ev->format == 32))
1956 Ecore_X_Event_Ping *e;
1958 e = calloc(1, sizeof(Ecore_X_Event_Ping));
1960 e->win = ev->window;
1961 e->time = ev->data.data32[1];
1962 e->event_win = ev->data.data32[2];
1964 ecore_event_add(ECORE_X_EVENT_PING, e, NULL, NULL);
1966 else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO_BEGIN) &&
1969 _ecore_x_netwm_startup_info_begin(ev->window, (char *)ev->data.data8);
1971 else if ((ev->type == ECORE_X_ATOM_NET_STARTUP_INFO) &&
1974 _ecore_x_netwm_startup_info(ev->window, (char *)ev->data.data8);
1976 else if ((ev->type == 27777)
1977 && (ev->data.data32[0] == 0x7162534)
1978 && (ev->format == 32)
1979 && (ev->window == _ecore_xcb_private_window))
1981 /* a grab sync marker */
1982 if (ev->data.data32[1] == 0x10000001)
1983 _ecore_x_window_grab_remove(ev->data.data32[2]);
1984 else if (ev->data.data32[1] == 0x10000002)
1985 _ecore_x_key_grab_remove(ev->data.data32[2]);
1989 Ecore_X_Event_Client_Message *e;
1992 e = calloc(1, sizeof(Ecore_X_Event_Client_Message));
1994 e->win = ev->window;
1995 e->message_type = ev->type;
1996 e->format = ev->format;
1997 for (i = 0; i < 5; i++)
1998 e->data.l[i] = ev->data.data32[i];
2000 ecore_event_add(ECORE_X_EVENT_CLIENT_MESSAGE, e, NULL, NULL);
2007 _ecore_x_event_handle_mapping_notify(xcb_generic_event_t *event)
2009 /* FIXME: handle this event type */
2015 _ecore_x_event_handle_shape_change(xcb_generic_event_t *event)
2017 #ifdef ECORE_X_SHAPE
2018 xcb_shape_notify_event_t *ev;
2019 Ecore_X_Event_Window_Shape *e;
2021 ev = (xcb_shape_notify_event_t *)event;
2022 e = calloc(1, sizeof(Ecore_X_Event_Window_Shape));
2024 e->win = ev->affected_window;
2025 e->time = ev->server_time;
2026 ecore_event_add(ECORE_X_EVENT_WINDOW_SHAPE, e, NULL, NULL);
2027 #endif /* ECORE_X_SHAPE */
2033 _ecore_x_event_handle_screensaver_notify(xcb_generic_event_t *event)
2035 #ifdef ECORE_X_SCREENSAVER
2036 xcb_screensaver_notify_event_t *ev;
2037 Ecore_X_Event_Screensaver_Notify *e;
2039 ev = (xcb_screensaver_notify_event_t *)event;
2040 e = calloc(1, sizeof(Ecore_X_Event_Screensaver_Notify));
2042 e->win = ev->window;
2043 if (ev->state == XCB_SCREENSAVER_STATE_ON)
2048 ecore_event_add(ECORE_X_EVENT_SCREENSAVER_NOTIFY, e, NULL, NULL);
2049 #endif /* ECORE_X_SCREENSAVER */
2055 _ecore_x_event_handle_sync_counter(xcb_generic_event_t *event)
2058 xcb_sync_counter_notify_event_t *ev;
2059 Ecore_X_Event_Sync_Counter *e;
2061 ev = (xcb_sync_counter_notify_event_t *)event;
2062 e = calloc(1, sizeof(Ecore_X_Event_Sync_Counter));
2064 e->time = ev->timestamp;
2065 ecore_event_add(ECORE_X_EVENT_SYNC_COUNTER, e, NULL, NULL);
2066 #endif /* ECORE_X_SYNC */
2072 _ecore_x_event_handle_sync_alarm(xcb_generic_event_t *event)
2075 xcb_sync_alarm_notify_event_t *ev;
2076 Ecore_X_Event_Sync_Alarm *e;
2078 ev = (xcb_sync_alarm_notify_event_t *)event;
2079 e = calloc(1, sizeof(Ecore_X_Event_Sync_Alarm));
2081 e->time = ev->timestamp;
2082 e->alarm = ev->alarm;
2083 ecore_event_add(ECORE_X_EVENT_SYNC_ALARM, e, NULL, NULL);
2084 #endif /* ECORE_X_SYNC */
2089 /* FIXME: round trip */
2091 _ecore_x_event_handle_randr_change(xcb_generic_event_t *event)
2093 #ifdef ECORE_X_RANDR
2094 xcb_randr_screen_change_notify_event_t *ev;
2095 Ecore_X_Event_Screen_Change *e;
2097 ev = (xcb_randr_screen_change_notify_event_t *)event;
2099 if ((ev->response_type & ~0x80) != XCB_CONFIGURE_NOTIFY)
2101 xcb_query_extension_reply_t *rep;
2103 rep = xcb_query_extension_reply(_ecore_xcb_conn,
2104 xcb_query_extension_unchecked(_ecore_xcb_conn,
2110 (((ev->response_type & ~0x80) - rep->first_event) != XCB_RANDR_SCREEN_CHANGE_NOTIFY))
2111 WRN("ERROR: Can't update RandR config!");
2116 e = calloc(1, sizeof(Ecore_X_Event_Screen_Change));
2118 e->win = ev->request_window;
2120 e->width = ev->width;
2121 e->height = ev->height;
2122 ecore_event_add(ECORE_X_EVENT_SCREEN_CHANGE, e, NULL, NULL);
2123 #endif /* ECORE_X_RANDR */
2129 _ecore_x_event_handle_fixes_selection_notify(xcb_generic_event_t *event)
2131 #ifdef ECORE_X_FIXES
2132 /* Nothing here yet */
2133 #endif /* ECORE_X_FIXES */
2139 _ecore_x_event_handle_damage_notify(xcb_generic_event_t *event)
2141 #ifdef ECORE_XCBDAMAGE
2142 xcb_damage_notify_event_t *ev;
2143 Ecore_X_Event_Damage *e;
2145 ev = (xcb_damage_notify_event_t *)event;
2146 e = calloc(1, sizeof(Ecore_X_Event_Damage));
2149 e->level = ev->level;
2150 e->drawable = ev->drawable;
2151 e->damage = ev->damage;
2152 /* FIXME: XCB has no 'more' member in xcb_damage_notify_event_t */
2153 /* e->more = ev->more; */
2154 e->time = ev->timestamp;
2155 e->area.x = ev->area.x;
2156 e->area.y = ev->area.y;
2157 e->area.width = ev->area.width;
2158 e->area.height = ev->area.height;
2159 e->geometry.x = ev->geometry.x;
2160 e->geometry.y = ev->geometry.y;
2161 e->geometry.width = ev->geometry.width;
2162 e->geometry.height = ev->geometry.height;
2164 ecore_event_add(ECORE_X_EVENT_DAMAGE_NOTIFY, e, NULL, NULL);
2165 #endif /* ECORE_XCBDAMAGE */