1 #include "ecore_xcb_private.h"
2 #ifdef ECORE_XCB_RENDER
3 # include <xcb/render.h>
6 # include <xcb/shape.h>
9 /* local function prototypes */
10 static Ecore_X_Window _ecore_xcb_window_argb_internal_new(Ecore_X_Window parent,
15 uint8_t override_redirect,
17 static Ecore_X_Window _ecore_xcb_window_at_xy_get(Ecore_X_Window base,
24 static int _ecore_xcb_window_modifiers_get(unsigned int state);
25 static xcb_visualtype_t *_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id);
28 static int ignore_num = 0;
29 static Ecore_X_Window *ignore_list = NULL;
31 /* external variables */
32 int _ecore_xcb_button_grabs_num = 0;
33 int _ecore_xcb_key_grabs_num = 0;
34 Ecore_X_Window *_ecore_xcb_button_grabs = NULL;
35 Ecore_X_Window *_ecore_xcb_key_grabs = NULL;
36 Eina_Bool (*_ecore_xcb_window_grab_replay_func)(void *data,
39 void *_ecore_xcb_window_grab_replay_data;
42 * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
43 * @ingroup Ecore_X_Group
45 * Functions that can be used to create an X window.
49 ecore_x_window_full_new(Ecore_X_Window parent, int x, int y, int w, int h, Ecore_X_Visual *visual, Ecore_X_Colormap colormap, int depth EINA_UNUSED, Eina_Bool override)
52 uint32_t mask, mask_list[10];
53 xcb_visualtype_t *vis;
55 LOGFN(__FILE__, __LINE__, __FUNCTION__);
59 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
61 vis = (xcb_visualtype_t *)visual;
63 /* NB: Order here is very important due to xcb_cw_t enum */
64 mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
65 XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
66 XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK |
67 XCB_CW_DONT_PROPAGATE | XCB_CW_COLORMAP);
69 mask_list[0] = XCB_BACK_PIXMAP_NONE;
71 mask_list[2] = XCB_GRAVITY_NORTH_WEST;
72 mask_list[3] = XCB_GRAVITY_NORTH_WEST;
73 mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
74 mask_list[5] = override;
76 mask_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
77 XCB_EVENT_MASK_BUTTON_PRESS |
78 XCB_EVENT_MASK_BUTTON_RELEASE |
79 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
80 XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
81 XCB_EVENT_MASK_VISIBILITY_CHANGE |
82 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
83 XCB_EVENT_MASK_FOCUS_CHANGE |
84 XCB_EVENT_MASK_PROPERTY_CHANGE |
85 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
86 mask_list[8] = XCB_EVENT_MASK_NO_EVENT;
87 mask_list[9] = colormap;
89 win = xcb_generate_id(_ecore_xcb_conn);
90 xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
91 win, parent, x, y, w, h, 0,
92 XCB_WINDOW_CLASS_INPUT_OUTPUT,
93 vis ? vis->visual_id : XCB_COPY_FROM_PARENT,
96 if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
97 ecore_x_window_defaults_set(win);
103 * Creates a new window.
104 * @param parent The parent window to use. If @p parent is @c 0, the root
105 * window of the default display is used.
106 * @param x X position.
107 * @param y Y position.
110 * @return The new window handle.
111 * @ingroup Ecore_X_Window_Create_Group
114 ecore_x_window_new(Ecore_X_Window parent, int x, int y, int w, int h)
117 uint32_t mask, mask_list[9];
119 LOGFN(__FILE__, __LINE__, __FUNCTION__);
123 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
125 /* NB: Order here is very important due to xcb_cw_t enum */
126 mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
127 XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
128 XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK |
129 XCB_CW_DONT_PROPAGATE);
131 mask_list[0] = XCB_BACK_PIXMAP_NONE;
133 mask_list[2] = XCB_GRAVITY_NORTH_WEST;
134 mask_list[3] = XCB_GRAVITY_NORTH_WEST;
135 mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
138 mask_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
139 XCB_EVENT_MASK_BUTTON_PRESS |
140 XCB_EVENT_MASK_BUTTON_RELEASE |
141 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
142 XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
143 XCB_EVENT_MASK_VISIBILITY_CHANGE |
144 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
145 XCB_EVENT_MASK_FOCUS_CHANGE |
146 XCB_EVENT_MASK_PROPERTY_CHANGE |
147 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
148 mask_list[8] = XCB_EVENT_MASK_NO_EVENT;
150 win = xcb_generate_id(_ecore_xcb_conn);
151 xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
152 win, parent, x, y, w, h, 0,
153 XCB_WINDOW_CLASS_INPUT_OUTPUT,
154 XCB_COPY_FROM_PARENT, mask, mask_list);
156 if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
157 ecore_x_window_defaults_set(win);
163 * Creates a window with the override redirect attribute set to @c True.
164 * @param parent The parent window to use. If @p parent is @c 0, the root
165 * window of the default display is used.
166 * @param x X position.
167 * @param y Y position.
170 * @return The new window handle.
171 * @ingroup Ecore_X_Window_Create_Group
174 ecore_x_window_override_new(Ecore_X_Window parent, int x, int y, int w, int h)
177 uint32_t mask, mask_list[9];
179 LOGFN(__FILE__, __LINE__, __FUNCTION__);
183 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
185 /* NB: Order here is very important due to xcb_cw_t enum */
186 mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
187 XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
188 XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK |
189 XCB_CW_DONT_PROPAGATE);
191 mask_list[0] = XCB_BACK_PIXMAP_NONE;
193 mask_list[2] = XCB_GRAVITY_NORTH_WEST;
194 mask_list[3] = XCB_GRAVITY_NORTH_WEST;
195 mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
198 mask_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
199 XCB_EVENT_MASK_BUTTON_PRESS |
200 XCB_EVENT_MASK_BUTTON_RELEASE |
201 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
202 XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
203 XCB_EVENT_MASK_VISIBILITY_CHANGE |
204 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
205 XCB_EVENT_MASK_FOCUS_CHANGE |
206 XCB_EVENT_MASK_PROPERTY_CHANGE |
207 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
208 mask_list[8] = XCB_EVENT_MASK_NO_EVENT;
210 win = xcb_generate_id(_ecore_xcb_conn);
211 xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
212 win, parent, x, y, w, h, 0,
213 XCB_WINDOW_CLASS_INPUT_OUTPUT,
214 XCB_COPY_FROM_PARENT, mask, mask_list);
220 * Creates a new input window.
221 * @param parent The parent window to use. If @p parent is @c 0, the root
222 * window of the default display is used.
223 * @param x X position.
224 * @param y Y position.
227 * @return The new window.
228 * @ingroup Ecore_X_Window_Create_Group
231 ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h)
234 uint32_t mask, mask_list[3];
236 LOGFN(__FILE__, __LINE__, __FUNCTION__)
240 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
242 /* NB: Order here is very important due to xcb_cw_t enum */
243 mask = (XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK |
244 XCB_CW_DONT_PROPAGATE);
247 mask_list[1] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
248 XCB_EVENT_MASK_BUTTON_PRESS |
249 XCB_EVENT_MASK_BUTTON_RELEASE |
250 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
251 XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
252 XCB_EVENT_MASK_VISIBILITY_CHANGE |
253 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
254 XCB_EVENT_MASK_FOCUS_CHANGE |
255 XCB_EVENT_MASK_PROPERTY_CHANGE |
256 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
257 mask_list[2] = XCB_EVENT_MASK_NO_EVENT;
259 win = xcb_generate_id(_ecore_xcb_conn);
260 xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
261 win, parent, x, y, w, h, 0,
262 XCB_WINDOW_CLASS_INPUT_ONLY,
263 XCB_COPY_FROM_PARENT, mask, mask_list);
269 * Creates a new window.
270 * @param parent The parent window to use. If @p parent is @c 0, the root
271 * window of the default display is used.
272 * @param x X position.
273 * @param y Y position.
276 * @return The new window handle.
277 * @ingroup Ecore_X_Window_Create_Group
280 ecore_x_window_manager_argb_new(Ecore_X_Window parent, int x, int y, int w, int h)
282 Ecore_X_Window win = 0;
284 LOGFN(__FILE__, __LINE__, __FUNCTION__);
286 win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0);
292 * Creates a new window.
293 * @param parent The parent window to use. If @p parent is @c 0, the root
294 * window of the default display is used.
295 * @param x X position.
296 * @param y Y position.
299 * @return The new window handle.
300 * @ingroup Ecore_X_Window_Create_Group
303 ecore_x_window_argb_new(Ecore_X_Window parent, int x, int y, int w, int h)
305 Ecore_X_Window win = 0;
307 LOGFN(__FILE__, __LINE__, __FUNCTION__);
309 win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 0, 0);
315 * Creates a window with the override redirect attribute set to @c True.
316 * @param parent The parent window to use. If @p parent is @c 0, the root
317 * window of the default display is used.
318 * @param x X position.
319 * @param y Y position.
322 * @return The new window handle.
323 * @ingroup Ecore_X_Window_Create_Group
326 ecore_x_window_override_argb_new(Ecore_X_Window parent, int x, int y, int w, int h)
328 Ecore_X_Window win = 0;
330 LOGFN(__FILE__, __LINE__, __FUNCTION__);
332 win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0);
338 ecore_x_window_permanent_new(Ecore_X_Window parent, Ecore_X_Atom unique_atom)
340 Ecore_X_Window win, win2, realwin = 0;
341 uint32_t mask, mask_list[9];
342 xcb_get_property_reply_t *reply;
343 xcb_get_property_cookie_t cookie;
344 unsigned long ldata, *datap;
346 LOGFN(__FILE__, __LINE__, __FUNCTION__);
348 if (!_ecore_xcb_conn) return 0;
352 xcb_grab_server(_ecore_xcb_conn);
354 xcb_get_property_unchecked(_ecore_xcb_conn, 0, parent, unique_atom,
355 ECORE_X_ATOM_WINDOW, 0, 0x7fffffff);
356 reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
359 if ((reply->type == ECORE_X_ATOM_WINDOW) && (reply->format == 32) &&
360 (reply->value_len == 1) &&
361 ((datap = (unsigned long *)xcb_get_property_value(reply))))
363 win = (Ecore_X_Window)(*datap);
366 xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, unique_atom,
367 ECORE_X_ATOM_WINDOW, 0, 0x7fffffff);
368 reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
371 if ((reply->type == ECORE_X_ATOM_WINDOW) &&
372 (reply->format == 32) && (reply->value_len == 1) &&
373 ((datap = (unsigned long *)xcb_get_property_value(reply))))
375 win2 = (Ecore_X_Window)(*datap);
377 if (win2 == win) realwin = win;
386 xcb_ungrab_server(_ecore_xcb_conn);
387 xcb_flush(_ecore_xcb_conn);
390 mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
391 XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
392 XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK |
393 XCB_CW_DONT_PROPAGATE);
394 mask_list[0] = XCB_BACK_PIXMAP_NONE;
396 mask_list[2] = XCB_GRAVITY_NORTH_WEST;
397 mask_list[3] = XCB_GRAVITY_NORTH_WEST;
398 mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
401 mask_list[7] = XCB_EVENT_MASK_NO_EVENT;
402 mask_list[8] = XCB_EVENT_MASK_NO_EVENT;
403 win = xcb_generate_id(_ecore_xcb_conn);
404 xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
405 win, parent, -77, -77, 7, 7, 0,
406 XCB_WINDOW_CLASS_INPUT_OUTPUT,
407 XCB_COPY_FROM_PARENT, mask, mask_list);
408 ldata = (unsigned long)win;
409 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE,
410 win, unique_atom,ECORE_X_ATOM_WINDOW, 32, 1,
411 (unsigned char *)ldata);
412 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE,
414 ECORE_X_ATOM_WINDOW, 32, 1, (unsigned char *)ldata);
415 xcb_set_close_down_mode(_ecore_xcb_conn, XCB_CLOSE_DOWN_RETAIN_PERMANENT);
416 xcb_ungrab_server(_ecore_xcb_conn);
417 xcb_flush(_ecore_xcb_conn);
423 * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions
424 * @ingroup Ecore_X_Group
426 * Functions to destroy X windows.
430 * Deletes the given window.
431 * @param win The given window.
432 * @ingroup Ecore_X_Window_Destroy_Group
435 ecore_x_window_free(Ecore_X_Window win)
437 LOGFN(__FILE__, __LINE__, __FUNCTION__);
442 /* xcb_destroy_notify_event_t ev; */
443 /* Ecore_X_Window root; */
445 /* if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1) */
446 /* root = ((xcb_screen_t *)_ecore_xcb_screen)->root; */
449 /* xcb_get_geometry_cookie_t cookie; */
450 /* xcb_get_geometry_reply_t *reply; */
452 /* cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); */
453 /* reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); */
454 /* if (!reply) return; */
455 /* root = reply->root; */
459 /* memset(&ev, 0, sizeof(xcb_destroy_notify_event_t)); */
461 /* ev.response_type = XCB_DESTROY_NOTIFY; */
462 /* ev.window = win; */
463 /* ev.event = root; */
465 /* xcb_send_event(_ecore_xcb_conn, 0, root, */
466 /* XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | */
467 /* XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, */
468 /* (const char *)&ev); */
470 xcb_destroy_window(_ecore_xcb_conn, win);
476 * Sends a delete request to the given window.
477 * @param win The given window.
478 * @ingroup Ecore_X_Window_Destroy_Group
481 ecore_x_window_delete_request_send(Ecore_X_Window win)
483 LOGFN(__FILE__, __LINE__, __FUNCTION__);
486 ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
487 XCB_EVENT_MASK_NO_EVENT,
488 ECORE_X_ATOM_WM_DELETE_WINDOW,
489 XCB_CURRENT_TIME, 0, 0, 0);
493 ecore_x_window_configure(Ecore_X_Window win,
494 Ecore_X_Window_Configure_Mask mask,
500 Ecore_X_Window sibling,
507 LOGFN(__FILE__, __LINE__, __FUNCTION__);
512 if (mask & XCB_CONFIG_WINDOW_X)
514 vmask |= XCB_CONFIG_WINDOW_X;
517 if (mask & XCB_CONFIG_WINDOW_Y)
519 vmask |= XCB_CONFIG_WINDOW_Y;
522 if (mask & XCB_CONFIG_WINDOW_WIDTH)
524 vmask |= XCB_CONFIG_WINDOW_WIDTH;
527 if (mask & XCB_CONFIG_WINDOW_HEIGHT)
529 vmask |= XCB_CONFIG_WINDOW_HEIGHT;
532 if (mask & XCB_CONFIG_WINDOW_BORDER_WIDTH)
534 vmask |= XCB_CONFIG_WINDOW_BORDER_WIDTH;
535 vlist[i++] = border_width;
537 if (mask & XCB_CONFIG_WINDOW_SIBLING)
539 vmask |= XCB_CONFIG_WINDOW_SIBLING;
540 vlist[i++] = sibling;
542 if (mask & XCB_CONFIG_WINDOW_STACK_MODE)
544 vmask |= XCB_CONFIG_WINDOW_STACK_MODE;
545 vlist[i++] = stack_mode;
548 xcb_configure_window(_ecore_xcb_conn, win, vmask,
549 (const uint32_t *)&vlist);
554 * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
555 * @ingroup Ecore_X_Group
557 * Functions that change or retrieve the geometry of X windows.
561 * Moves a window to the position @p x, @p y.
563 * The position is relative to the upper left hand corner of the
566 * @param win The window to move.
567 * @param x X position.
568 * @param y Y position.
569 * @ingroup Ecore_X_Window_Geometry_Group
572 ecore_x_window_move(Ecore_X_Window win,
576 uint32_t list[2], mask;
578 LOGFN(__FILE__, __LINE__, __FUNCTION__);
583 mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y);
587 xcb_configure_window(_ecore_xcb_conn, win, mask,
588 (const uint32_t *)&list);
594 * @param win The window to resize.
595 * @param w New width of the window.
596 * @param h New height of the window.
597 * @ingroup Ecore_X_Window_Geometry_Group
600 ecore_x_window_resize(Ecore_X_Window win,
604 uint32_t list[2], mask;
606 LOGFN(__FILE__, __LINE__, __FUNCTION__);
613 mask = (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
617 xcb_configure_window(_ecore_xcb_conn, win, mask,
618 (const uint32_t *)&list);
623 * Moves and resizes a window.
624 * @param win The window to move and resize.
625 * @param x New X position of the window.
626 * @param y New Y position of the window.
627 * @param w New width of the window.
628 * @param h New height of the window.
629 * @ingroup Ecore_X_Window_Geometry_Group
632 ecore_x_window_move_resize(Ecore_X_Window win,
638 uint32_t list[4], mask;
640 LOGFN(__FILE__, __LINE__, __FUNCTION__);
647 mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
648 XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
654 xcb_configure_window(_ecore_xcb_conn, win, mask,
655 (const uint32_t *)&list);
660 * Retrieves the width of the border of the given window.
661 * @param win The given window.
662 * @return Width of the border of @p win.
663 * @ingroup Ecore_X_Window_Geometry_Group
666 ecore_x_window_border_width_get(Ecore_X_Window win)
668 LOGFN(__FILE__, __LINE__, __FUNCTION__);
671 return ecore_x_drawable_border_width_get(win);
675 * Sets the width of the border of the given window.
676 * @param win The given window.
677 * @param width The new border width.
678 * @ingroup Ecore_X_Window_Geometry_Group
681 ecore_x_window_border_width_set(Ecore_X_Window win,
686 LOGFN(__FILE__, __LINE__, __FUNCTION__);
693 xcb_configure_window(_ecore_xcb_conn, win,
694 XCB_CONFIG_WINDOW_BORDER_WIDTH, &list);
699 * @defgroup Ecore_X_Window_Z_Order_Group X Window Z Order Functions
700 * @ingroup Ecore_X_Group
702 * Functions that change the Z order of X windows.
706 * Raises the given window.
707 * @param win The window to raise.
708 * @ingroup Ecore_X_Window_Z_Order_Group
711 ecore_x_window_raise(Ecore_X_Window win)
713 uint32_t list[] = { XCB_STACK_MODE_ABOVE };
715 LOGFN(__FILE__, __LINE__, __FUNCTION__);
718 xcb_configure_window(_ecore_xcb_conn, win,
719 XCB_CONFIG_WINDOW_STACK_MODE, list);
724 * Lowers the given window.
725 * @param win The window to lower.
726 * @ingroup Ecore_X_Window_Z_Order_Group
729 ecore_x_window_lower(Ecore_X_Window win)
731 uint32_t list[] = { XCB_STACK_MODE_BELOW };
733 LOGFN(__FILE__, __LINE__, __FUNCTION__);
736 xcb_configure_window(_ecore_xcb_conn, win,
737 XCB_CONFIG_WINDOW_STACK_MODE, list);
742 * Retrieves the depth of the given window.
743 * @param win The given window.
744 * @return Depth of the window.
747 ecore_x_window_depth_get(Ecore_X_Window win)
749 LOGFN(__FILE__, __LINE__, __FUNCTION__);
751 return ecore_x_drawable_depth_get(win);
755 * @defgroup Ecore_X_Window_Properties_Group X Window Property Functions
756 * @ingroup Ecore_X_Group
758 * Functions that set window properties.
762 * Sets the default properties for the given window.
764 * The default properties set for the window are @c WM_CLIENT_MACHINE and
767 * @param win The given window.
768 * @ingroup Ecore_X_Window_Properties_Group
771 ecore_x_window_defaults_set(Ecore_X_Window win)
773 char buff[MAXHOSTNAMELEN], **argv;
777 LOGFN(__FILE__, __LINE__, __FUNCTION__);
780 gethostname(buff, MAXHOSTNAMELEN);
781 buff[MAXHOSTNAMELEN - 1] = '\0';
783 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
784 ECORE_X_ATOM_WM_CLIENT_MACHINE, ECORE_X_ATOM_STRING,
785 8, strlen(buff), buff);
788 ecore_x_netwm_pid_set(win, pid);
789 ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_NORMAL);
790 ecore_app_args_get(&argc, &argv);
791 ecore_x_icccm_command_set(win, argc, argv);
795 * @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions
796 * @ingroup Ecore_X_Group
798 * Functions to access and change the visibility of X windows.
804 * Synonymous to "mapping" a window in X Window System terminology.
806 * @param win The window to show.
807 * @ingroup Ecore_X_Window_Visibility
810 ecore_x_window_show(Ecore_X_Window win)
812 LOGFN(__FILE__, __LINE__, __FUNCTION__);
816 xcb_map_window(_ecore_xcb_conn, win);
822 * Synonymous to "unmapping" a window in X Window System terminology.
824 * @param win The window to hide.
825 * @ingroup Ecore_X_Window_Visibility
828 ecore_x_window_hide(Ecore_X_Window win)
830 LOGFN(__FILE__, __LINE__, __FUNCTION__);
835 xcb_unmap_notify_event_t ev;
838 if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1)
839 root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
842 xcb_get_geometry_cookie_t cookie;
843 xcb_get_geometry_reply_t *reply;
845 cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
846 reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL);
852 xcb_unmap_window(_ecore_xcb_conn, win);
853 memset(&ev, 0, sizeof(xcb_unmap_notify_event_t));
855 ev.response_type = XCB_UNMAP_NOTIFY;
858 ev.from_configure = 0;
860 xcb_send_event(_ecore_xcb_conn, 0, root,
861 (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
862 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT),
870 * @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions
871 * @ingroup Ecore_X_Group
873 * Functions that give the focus to an X Window.
877 * Sets the focus to the window @p win.
878 * @param win The window to focus.
879 * @ingroup Ecore_X_Window_Focus_Functions
882 ecore_x_window_focus(Ecore_X_Window win)
884 LOGFN(__FILE__, __LINE__, __FUNCTION__);
887 if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
889 xcb_set_input_focus(_ecore_xcb_conn,
890 XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME);
895 * Sets the focus to the given window at a specific time.
896 * @param win The window to focus.
897 * @param t When to set the focus to the window.
898 * @ingroup Ecore_X_Window_Focus_Functions
901 ecore_x_window_focus_at_time(Ecore_X_Window win,
902 Ecore_X_Time time EINA_UNUSED)
904 LOGFN(__FILE__, __LINE__, __FUNCTION__);
907 if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
908 xcb_set_input_focus(_ecore_xcb_conn,
909 XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME);
914 * @defgroup Ecore_X_Window_Parent_Group X Window Parent Functions
915 * @ingroup Ecore_X_Group
917 * Functions that retrieve or changes the parent window of a window.
921 * Moves a window to within another window at a given position.
922 * @param win The window to reparent.
923 * @param new_parent The new parent window.
924 * @param x X position within new parent window.
925 * @param y Y position within new parent window.
926 * @ingroup Ecore_X_Window_Parent_Group
929 ecore_x_window_reparent(Ecore_X_Window win,
930 Ecore_X_Window parent,
934 LOGFN(__FILE__, __LINE__, __FUNCTION__);
938 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
940 xcb_reparent_window(_ecore_xcb_conn, win, parent, x, y);
945 ecore_x_window_pixmap_set(Ecore_X_Window win,
946 Ecore_X_Pixmap pixmap)
950 LOGFN(__FILE__, __LINE__, __FUNCTION__);
955 xcb_change_window_attributes(_ecore_xcb_conn, win,
956 XCB_CW_BACK_PIXMAP, &list);
961 * Sets the background color of the given window.
962 * @param win The given window
963 * @param r red value (0...65536, 16 bits)
964 * @param g green value (0...65536, 16 bits)
965 * @param b blue value (0...65536, 16 bits)
968 ecore_x_window_background_color_set(Ecore_X_Window win,
970 unsigned short green,
973 xcb_alloc_color_cookie_t cookie;
974 xcb_alloc_color_reply_t *reply;
977 LOGFN(__FILE__, __LINE__, __FUNCTION__);
981 xcb_alloc_color_unchecked(_ecore_xcb_conn,
982 ((xcb_screen_t *)_ecore_xcb_screen)->default_colormap,
984 reply = xcb_alloc_color_reply(_ecore_xcb_conn, cookie, NULL);
989 xcb_change_window_attributes(_ecore_xcb_conn, win,
990 XCB_CW_BACK_PIXEL, &list);
995 ecore_x_window_pixel_gravity_set(Ecore_X_Window win,
996 Ecore_X_Gravity gravity)
1000 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1005 xcb_change_window_attributes(_ecore_xcb_conn, win,
1006 XCB_CW_BIT_GRAVITY, &list);
1011 ecore_x_window_gravity_set(Ecore_X_Window win,
1012 Ecore_X_Gravity gravity)
1016 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1021 xcb_change_window_attributes(_ecore_xcb_conn, win,
1022 XCB_CW_WIN_GRAVITY, &list);
1027 ecore_x_window_override_set(Ecore_X_Window win,
1032 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1037 xcb_change_window_attributes(_ecore_xcb_conn, win,
1038 XCB_CW_OVERRIDE_REDIRECT, &list);
1043 * @brief Show the cursor on a window of type Ecore_X_Window.
1044 * @param win The window for which the cursor will be showed.
1045 * @param show Enables the show of the cursor on the window if equals EINA_TRUE, disables if equals EINA_FALSE.
1048 ecore_x_window_cursor_show(Ecore_X_Window win,
1053 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1056 if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1060 Ecore_X_Cursor cursor;
1061 Ecore_X_Pixmap p, m;
1065 p = xcb_generate_id(_ecore_xcb_conn);
1066 xcb_create_pixmap(_ecore_xcb_conn, 1, p, win, 1, 1);
1067 m = xcb_generate_id(_ecore_xcb_conn);
1068 xcb_create_pixmap(_ecore_xcb_conn, 1, m, win, 1, 1);
1069 gc = xcb_generate_id(_ecore_xcb_conn);
1070 xcb_create_gc(_ecore_xcb_conn, gc, win, 0, NULL);
1071 xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list);
1074 xcb_poly_point(_ecore_xcb_conn, XCB_COORD_MODE_ORIGIN,
1075 win, gc, 1, &point);
1076 xcb_free_gc(_ecore_xcb_conn, gc);
1078 cursor = xcb_generate_id(_ecore_xcb_conn);
1079 xcb_create_cursor(_ecore_xcb_conn, cursor,
1080 p, m, 0, 0, 0, 0, 0, 0, 0, 0);
1083 xcb_change_window_attributes(_ecore_xcb_conn, win,
1084 XCB_CW_CURSOR, &list);
1086 xcb_free_cursor(_ecore_xcb_conn, cursor);
1087 xcb_free_pixmap(_ecore_xcb_conn, m);
1088 xcb_free_pixmap(_ecore_xcb_conn, p);
1092 xcb_change_window_attributes(_ecore_xcb_conn, win,
1093 XCB_CW_CURSOR, &list);
1099 ecore_x_window_cursor_set(Ecore_X_Window win,
1100 Ecore_X_Cursor cursor)
1104 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1109 xcb_change_window_attributes(_ecore_xcb_conn, win, XCB_CW_CURSOR, &list);
1114 ecore_x_window_container_manage(Ecore_X_Window win)
1118 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1121 list = (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
1122 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
1124 xcb_change_window_attributes(_ecore_xcb_conn, win,
1125 XCB_CW_EVENT_MASK, &list);
1130 ecore_x_window_client_manage(Ecore_X_Window win)
1134 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1137 list = (XCB_EVENT_MASK_VISIBILITY_CHANGE |
1138 XCB_EVENT_MASK_FOCUS_CHANGE |
1139 XCB_EVENT_MASK_PROPERTY_CHANGE |
1140 XCB_EVENT_MASK_COLOR_MAP_CHANGE |
1141 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1142 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
1144 xcb_change_window_attributes(_ecore_xcb_conn, win,
1145 XCB_CW_EVENT_MASK, &list);
1147 #ifdef ECORE_XCB_SHAPE
1148 xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE);
1154 ecore_x_window_sniff(Ecore_X_Window win)
1158 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1161 list = (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1162 XCB_EVENT_MASK_PROPERTY_CHANGE);
1164 xcb_change_window_attributes(_ecore_xcb_conn, win,
1165 XCB_CW_EVENT_MASK, &list);
1170 ecore_x_window_client_sniff(Ecore_X_Window win)
1174 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1177 list = (XCB_EVENT_MASK_VISIBILITY_CHANGE |
1178 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1179 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1180 XCB_EVENT_MASK_FOCUS_CHANGE |
1181 XCB_EVENT_MASK_PROPERTY_CHANGE |
1182 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
1184 xcb_change_window_attributes(_ecore_xcb_conn, win,
1185 XCB_CW_EVENT_MASK, &list);
1186 #ifdef ECORE_XCB_SHAPE
1187 xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE);
1193 ecore_x_window_area_clear(Ecore_X_Window win,
1199 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1202 xcb_clear_area(_ecore_xcb_conn, 0, win, x, y, w, h);
1207 ecore_x_window_area_expose(Ecore_X_Window win,
1213 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1216 xcb_clear_area(_ecore_xcb_conn, 1, win, x, y, w, h);
1221 ecore_x_window_save_set_add(Ecore_X_Window win)
1223 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1226 xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, win);
1230 ecore_x_window_save_set_del(Ecore_X_Window win)
1232 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1235 xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, win);
1239 * gets the window that has focus.
1240 * @return The window that has focus.
1241 * @ingroup Ecore_X_Window_Focus_Functions
1244 ecore_x_window_focus_get(void)
1246 xcb_get_input_focus_cookie_t cookie;
1247 xcb_get_input_focus_reply_t *reply;
1248 Ecore_X_Window focus = 0;
1250 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1253 cookie = xcb_get_input_focus_unchecked(_ecore_xcb_conn);
1254 reply = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie, NULL);
1255 if (!reply) return 0;
1256 focus = reply->focus;
1262 ecore_x_window_argb_get(Ecore_X_Window win)
1265 #ifdef ECORE_XCB_RENDER
1266 Ecore_X_Visual visual;
1269 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1272 // if (!win) return ret;
1274 #ifdef ECORE_XCB_RENDER
1275 /* grab the window's visual */
1276 visual = _ecore_xcb_window_visual_get(win);
1278 /* check if this visual supports alpha */
1279 ret = _ecore_xcb_render_visual_supports_alpha(visual);
1286 ecore_x_window_manage(Ecore_X_Window win)
1288 xcb_get_window_attributes_cookie_t cookie;
1289 xcb_get_window_attributes_reply_t *reply;
1290 xcb_void_cookie_t change_cookie;
1291 xcb_generic_error_t *err;
1294 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1297 cookie = xcb_get_window_attributes(_ecore_xcb_conn, win);
1298 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
1299 if (!reply) return EINA_FALSE;
1301 ecore_x_sync(); // needed
1303 list = (XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
1304 XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_RESIZE_REDIRECT |
1305 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
1306 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1307 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1308 XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
1309 reply->your_event_mask);
1312 change_cookie = xcb_change_window_attributes(_ecore_xcb_conn, win,
1313 XCB_CW_EVENT_MASK, &list);
1315 ecore_x_sync(); // needed
1317 err = xcb_request_check(_ecore_xcb_conn, change_cookie);
1320 _ecore_xcb_error_handle(err);
1329 ecore_x_window_attributes_get(Ecore_X_Window win,
1330 Ecore_X_Window_Attributes *att_ret)
1332 xcb_get_window_attributes_cookie_t cookie;
1333 xcb_get_window_attributes_reply_t *reply;
1334 xcb_get_geometry_cookie_t gcookie;
1335 xcb_get_geometry_reply_t *greply;
1337 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1340 cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win);
1341 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
1342 if (!reply) return EINA_FALSE;
1344 memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
1346 if (reply->map_state != XCB_MAP_STATE_UNMAPPED)
1347 att_ret->visible = EINA_TRUE;
1349 if (reply->map_state == XCB_MAP_STATE_VIEWABLE)
1350 att_ret->viewable = EINA_TRUE;
1352 if (reply->override_redirect)
1353 att_ret->override = EINA_TRUE;
1355 if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY)
1356 att_ret->input_only = EINA_TRUE;
1358 if (reply->save_under)
1359 att_ret->save_under = EINA_TRUE;
1361 att_ret->event_mask.mine = reply->your_event_mask;
1362 att_ret->event_mask.all = reply->all_event_masks;
1363 att_ret->event_mask.no_propagate = reply->do_not_propagate_mask;
1364 att_ret->window_gravity = reply->win_gravity;
1365 att_ret->pixel_gravity = reply->bit_gravity;
1366 att_ret->colormap = reply->colormap;
1367 att_ret->visual = _ecore_xcb_window_find_visual_by_id(reply->visual);
1371 gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
1372 greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL);
1373 if (!greply) return EINA_TRUE;
1375 /* xcb_translate_coordinates_reply_t *trans; */
1376 /* xcb_query_tree_cookie_t tcookie; */
1377 /* xcb_query_tree_reply_t *treply; */
1379 /* tcookie = xcb_query_tree(_ecore_xcb_conn, win); */
1380 /* treply = xcb_query_tree_reply(_ecore_xcb_conn, tcookie, NULL); */
1383 /* xcb_translate_coordinates_reply(_ecore_xcb_conn, */
1384 /* xcb_translate_coordinates(_ecore_xcb_conn, */
1385 /* win, treply->parent, greply->x, greply->y), NULL); */
1388 att_ret->root = greply->root;
1389 att_ret->depth = greply->depth;
1390 // att_ret->x = trans->dst_x;
1391 // att_ret->y = trans->dst_y;
1392 att_ret->x = greply->x;
1393 att_ret->y = greply->y;
1394 att_ret->w = greply->width;
1395 att_ret->h = greply->height;
1396 att_ret->border = greply->border_width;
1405 * Retrieves the size of the given window.
1406 * @param win The given window.
1407 * @param w Pointer to an integer into which the width is to be stored.
1408 * @param h Pointer to an integer into which the height is to be stored.
1409 * @ingroup Ecore_X_Window_Geometry_Group
1412 ecore_x_window_size_get(Ecore_X_Window win,
1416 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1419 if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1420 ecore_x_drawable_geometry_get(win, NULL, NULL, width, height);
1424 * Set if a window should be ignored.
1425 * @param win The given window.
1426 * @param ignore if to ignore
1429 ecore_x_window_ignore_set(Ecore_X_Window win,
1432 int i = 0, j = 0, count = 0;
1433 Ecore_X_Window *temp = ignore_list;
1435 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1442 for (i = 0; i < ignore_num; i++)
1443 if (win == ignore_list[i]) return;
1446 realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
1453 ignore_list[ignore_num++] = win;
1458 ignore_list = malloc(sizeof(Ecore_X_Window));
1459 if (!ignore_list) return;
1460 ignore_list[ignore_num++] = win;
1465 if (!ignore_list) return;
1466 for (count = ignore_num, i = 0, j = 0; i < count; i++)
1468 if (win != ignore_list[i])
1469 ignore_list[j++] = ignore_list[i];
1473 if (ignore_num <= 0)
1481 realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
1488 * Get the ignore list
1489 * @param num number of windows in the list
1490 * @return list of windows to ignore
1492 EAPI Ecore_X_Window *
1493 ecore_x_window_ignore_list(int *num)
1495 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1497 if (num) *num = ignore_num;
1502 * Get a list of all the root windows on the server.
1504 * @note The returned array will need to be freed after use.
1505 * @param num_ret Pointer to integer to put number of windows returned in.
1506 * @return An array of all the root windows. @c NULL is returned if memory
1507 * could not be allocated for the list, or if @p num_ret is @c NULL.
1509 EAPI Ecore_X_Window *
1510 ecore_x_window_root_list(int *num_ret)
1512 xcb_screen_iterator_t iter;
1514 Ecore_X_Window *roots = NULL;
1516 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1519 if (!num_ret) return NULL;
1520 if (num_ret) *num_ret = 0;
1522 /* if (xcb_connection_has_error(_ecore_xcb_conn)) */
1524 /* DBG("XCB Connection Has Error !!!"); */
1528 num = ecore_x_screen_count_get();
1530 iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
1531 if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
1532 if (num_ret) *num_ret = num;
1533 for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
1534 roots[i] = iter.data->root;
1539 EAPI Ecore_X_Window *
1540 ecore_x_window_children_get(Ecore_X_Window win,
1543 xcb_query_tree_cookie_t cookie;
1544 xcb_query_tree_reply_t *reply;
1545 Ecore_X_Window *windows = NULL;
1547 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1551 cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, win);
1552 reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
1553 if (!reply) return NULL;
1555 if (num) *num = reply->children_len;
1556 if (reply->children_len > 0)
1558 windows = malloc(sizeof(Ecore_X_Window) * reply->children_len);
1564 w = xcb_query_tree_children(reply);
1565 for (i = 0; i < reply->children_len; i++)
1575 * Retrieves the root window a given window is on.
1576 * @param win The window to get the root window of
1577 * @return The root window of @p win
1578 * @ingroup Ecore_X_Window_Geometry_Group
1581 ecore_x_window_root_get(Ecore_X_Window win)
1583 xcb_get_geometry_cookie_t gcookie;
1584 xcb_get_geometry_reply_t *greply;
1585 Ecore_X_Window window = 0;
1587 /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
1590 gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
1591 greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL);
1592 if (!greply) return 0;
1593 window = greply->root;
1600 ecore_x_window_root_first_get(void)
1602 return ((xcb_screen_t *)_ecore_xcb_screen)->root;
1606 * Retrieves the geometry of the given window.
1608 * Note that the x & y coordingates are relative to your parent. In
1609 * particular for reparenting window managers - relative to you window border.
1610 * If you want screen coordinates either walk the window tree to the root,
1611 * else for ecore_evas applications see ecore_evas_geometry_get(). Elementary
1612 * applications can use elm_win_screen_position_get().
1614 * @param win The given window.
1615 * @param x Pointer to an integer in which the X position is to be stored.
1616 * @param y Pointer to an integer in which the Y position is to be stored.
1617 * @param w Pointer to an integer in which the width is to be stored.
1618 * @param h Pointer to an integer in which the height is to be stored.
1619 * @ingroup Ecore_X_Window_Geometry_Group
1622 ecore_x_window_geometry_get(Ecore_X_Window win,
1628 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1631 if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1632 ecore_x_drawable_geometry_get(win, x, y, w, h);
1636 * Retrieves the top, visible window at the given location.
1637 * @param x The given X position.
1638 * @param y The given Y position.
1639 * @return The window at that position.
1640 * @ingroup Ecore_X_Window_Geometry_Group
1643 ecore_x_window_at_xy_get(int x,
1646 Ecore_X_Window root, win = 0;
1648 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1651 root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1654 win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
1657 return win ? win : root;
1661 * Retrieves the top, visible window at the given location,
1662 * but skips the windows in the list.
1663 * @param x The given X position.
1664 * @param y The given Y position.
1665 * @param skip The list of windows to be skipped.
1666 * @param skip_num The number of windows to be skipped.
1667 * @return The window at that position.
1668 * @ingroup Ecore_X_Window_Geometry_Group
1671 ecore_x_window_at_xy_with_skip_get(int x,
1673 Ecore_X_Window *skip,
1676 Ecore_X_Window root, win = 0;
1678 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1681 root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1684 win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
1687 return win ? win : root;
1691 ecore_x_window_at_xy_begin_get(Ecore_X_Window begin,
1695 Ecore_X_Window win = 0;
1697 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1701 win = _ecore_xcb_window_at_xy_get(begin, 0, 0, x, y, NULL, 0);
1704 return win ? win : begin;
1708 * Retrieves the parent window of the given window.
1709 * @param win The given window.
1710 * @return The parent window of @p win.
1711 * @ingroup Ecore_X_Window_Parent_Group
1714 ecore_x_window_parent_get(Ecore_X_Window win)
1716 xcb_query_tree_cookie_t cookie;
1717 xcb_query_tree_reply_t *reply;
1718 Ecore_X_Window window = 0;
1720 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1723 // if (!win) return 0;
1724 cookie = xcb_query_tree(_ecore_xcb_conn, win);
1725 reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
1726 if (!reply) return 0;
1727 window = reply->parent;
1734 * Finds out whether the given window is currently visible.
1735 * @param win The given window.
1736 * @return 1 if the window is visible, otherwise 0.
1737 * @ingroup Ecore_X_Window_Visibility_Group
1740 ecore_x_window_visible_get(Ecore_X_Window win)
1742 xcb_get_window_attributes_cookie_t cookie;
1743 xcb_get_window_attributes_reply_t *reply;
1744 int ret = EINA_FALSE;
1746 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1749 cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win);
1750 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
1751 if (!reply) return EINA_FALSE;
1753 if (reply->map_state == XCB_MAP_STATE_VIEWABLE)
1761 ecore_x_window_button_grab(Ecore_X_Window win,
1763 Ecore_X_Event_Mask mask,
1768 uint16_t m, locks[8], ev;
1772 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1777 b = XCB_BUTTON_INDEX_ANY;
1779 m = _ecore_xcb_window_modifiers_get(mod);
1780 if (any_mod) m = XCB_MOD_MASK_ANY;
1783 locks[1] = ECORE_X_LOCK_CAPS;
1784 locks[2] = ECORE_X_LOCK_NUM;
1785 locks[3] = ECORE_X_LOCK_SCROLL;
1786 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1787 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1788 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1789 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1792 for (i = 0; i < 8; i++)
1793 xcb_grab_button(_ecore_xcb_conn, 0, win, ev,
1794 XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
1795 XCB_NONE, XCB_NONE, b, m | locks[i]);
1797 _ecore_xcb_button_grabs_num++;
1798 t = realloc(_ecore_xcb_button_grabs,
1799 _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window));
1802 _ecore_xcb_button_grabs = t;
1803 _ecore_xcb_button_grabs[_ecore_xcb_button_grabs_num - 1] = win;
1807 ecore_x_window_button_ungrab(Ecore_X_Window win,
1813 uint16_t m = 0, locks[8];
1816 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1820 if (b == 0) b = XCB_BUTTON_INDEX_ANY;
1822 m = _ecore_xcb_window_modifiers_get(mod);
1823 if (any_mod) m = XCB_MOD_MASK_ANY;
1826 locks[1] = ECORE_X_LOCK_CAPS;
1827 locks[2] = ECORE_X_LOCK_NUM;
1828 locks[3] = ECORE_X_LOCK_SCROLL;
1829 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1830 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1831 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1832 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1834 for (i = 0; i < 8; i++)
1835 xcb_ungrab_button(_ecore_xcb_conn, b, win, m | locks[i]);
1837 _ecore_xcb_sync_magic_send(1, win);
1841 ecore_x_window_key_grab(Ecore_X_Window win,
1846 xcb_keycode_t keycode = XCB_NO_SYMBOL;
1847 uint16_t m = 0, locks[8];
1851 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1854 keycode = _ecore_xcb_keymap_string_to_keycode(key);
1855 if (keycode == XCB_NO_SYMBOL) return;
1857 m = _ecore_xcb_window_modifiers_get(mod);
1858 if (any_mod) m = XCB_MOD_MASK_ANY;
1861 locks[1] = ECORE_X_LOCK_CAPS;
1862 locks[2] = ECORE_X_LOCK_NUM;
1863 locks[3] = ECORE_X_LOCK_SCROLL;
1864 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1865 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1866 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1867 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1869 for (i = 0; i < 8; i++)
1870 xcb_grab_key(_ecore_xcb_conn, 0, win, m | locks[i],
1871 keycode, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
1872 _ecore_xcb_key_grabs_num++;
1873 t = realloc(_ecore_xcb_key_grabs,
1874 _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window));
1876 _ecore_xcb_key_grabs = t;
1877 _ecore_xcb_key_grabs[_ecore_xcb_key_grabs_num - 1] = win;
1881 ecore_x_window_key_ungrab(Ecore_X_Window win,
1886 xcb_keycode_t keycode = XCB_NO_SYMBOL;
1887 uint16_t m = 0, locks[8];
1890 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1893 keycode = _ecore_xcb_keymap_string_to_keycode(key);
1894 if (keycode == XCB_NO_SYMBOL) return;
1896 m = _ecore_xcb_window_modifiers_get(mod);
1897 if (any_mod) m = XCB_MOD_MASK_ANY;
1900 locks[1] = ECORE_X_LOCK_CAPS;
1901 locks[2] = ECORE_X_LOCK_NUM;
1902 locks[3] = ECORE_X_LOCK_SCROLL;
1903 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1904 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1905 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1906 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1908 for (i = 0; i < 8; i++)
1909 xcb_ungrab_key(_ecore_xcb_conn, keycode, win, m | locks[i]);
1911 _ecore_xcb_sync_magic_send(2, win);
1914 /* local functions */
1916 _ecore_xcb_window_root_of_screen_get(int screen)
1918 xcb_screen_iterator_t iter;
1921 iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
1922 for (; iter.rem; --screen, xcb_screen_next(&iter))
1927 if ((s = iter.data))
1933 static Ecore_X_Window
1934 _ecore_xcb_window_argb_internal_new(Ecore_X_Window parent,
1939 uint8_t override_redirect,
1942 Ecore_X_Window win = 0;
1943 #ifdef ECORE_XCB_RENDER
1944 uint32_t value_list[10];
1945 uint32_t value_mask;
1947 Ecore_X_Colormap colormap;
1950 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1953 #ifdef ECORE_XCB_RENDER
1955 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1958 _ecore_xcb_render_find_visual_id(XCB_RENDER_PICT_TYPE_DIRECT, EINA_TRUE);
1960 colormap = xcb_generate_id(_ecore_xcb_conn);
1961 xcb_create_colormap(_ecore_xcb_conn, XCB_COLORMAP_ALLOC_NONE,
1962 colormap, parent, vis);
1964 value_mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
1965 XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
1966 XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER |
1967 XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE | XCB_CW_COLORMAP);
1969 value_list[0] = XCB_BACK_PIXMAP_NONE;
1971 value_list[2] = XCB_GRAVITY_NORTH_WEST;
1972 value_list[3] = XCB_GRAVITY_NORTH_WEST;
1973 value_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
1974 value_list[5] = override_redirect;
1975 value_list[6] = save_under;
1976 value_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
1977 XCB_EVENT_MASK_BUTTON_PRESS |
1978 XCB_EVENT_MASK_BUTTON_RELEASE |
1979 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
1980 XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
1981 XCB_EVENT_MASK_VISIBILITY_CHANGE |
1982 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1983 XCB_EVENT_MASK_FOCUS_CHANGE |
1984 XCB_EVENT_MASK_PROPERTY_CHANGE |
1985 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
1986 value_list[8] = XCB_EVENT_MASK_NO_EVENT;
1987 value_list[9] = colormap;
1989 win = xcb_generate_id(_ecore_xcb_conn);
1990 xcb_create_window(_ecore_xcb_conn, 32, win, parent, x, y, w, h, 0,
1991 XCB_WINDOW_CLASS_INPUT_OUTPUT, vis, value_mask,
1994 xcb_free_colormap(_ecore_xcb_conn, colormap);
1996 if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
1997 ecore_x_window_defaults_set(win);
2003 static Ecore_X_Window
2004 _ecore_xcb_window_at_xy_get(Ecore_X_Window base,
2009 Ecore_X_Window *skip,
2012 xcb_query_tree_cookie_t cookie;
2013 xcb_query_tree_reply_t *reply;
2014 Ecore_X_Window *windows = NULL;
2015 int wx, wy, ww, wh, num, i = 0;
2016 Eina_Bool skipit = EINA_FALSE;
2018 LOGFN(__FILE__, __LINE__, __FUNCTION__);
2021 if (!ecore_x_window_visible_get(base)) return 0;
2023 ecore_x_window_geometry_get(base, &wx, &wy, &ww, &wh);
2027 if (!((x >= wx) && (y >= wy) && (x < (wx + ww)) && (y < (wy + wh))))
2030 cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, base);
2031 reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
2032 if (!reply) return 0;
2034 num = reply->children_len;
2035 windows = xcb_query_tree_children(reply);
2037 for (i = (num - 1); i >= 0; --i)
2039 skipit = EINA_FALSE;
2045 for (j = 0; j < skip_num; j++)
2047 if (windows[i] == skip[j])
2057 Ecore_X_Window child = 0;
2060 _ecore_xcb_window_at_xy_get(windows[i],
2061 wx, wy, x, y, skip, skip_num);
2064 if (reply) free(reply);
2070 if (reply) free(reply);
2075 _ecore_xcb_window_visual_get(Ecore_X_Window win)
2077 xcb_get_window_attributes_cookie_t cookie;
2078 xcb_get_window_attributes_reply_t *reply;
2079 Ecore_X_Visual visual = 0;
2083 cookie = xcb_get_window_attributes(_ecore_xcb_conn, win);
2084 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
2085 if (!reply) return 0;
2086 visual = _ecore_xcb_window_find_visual_by_id(reply->visual);
2093 _ecore_xcb_window_button_grab_remove(Ecore_X_Window win)
2095 LOGFN(__FILE__, __LINE__, __FUNCTION__);
2098 if (_ecore_xcb_button_grabs_num > 0)
2100 int i = 0, shuffle = 0;
2102 for (i = 0; i < _ecore_xcb_button_grabs_num; i++)
2105 _ecore_xcb_button_grabs[i - 1] = _ecore_xcb_button_grabs[i];
2107 if ((!shuffle) && (_ecore_xcb_button_grabs[i] == win))
2115 _ecore_xcb_button_grabs_num--;
2116 if (_ecore_xcb_button_grabs_num <= 0)
2118 free(_ecore_xcb_button_grabs);
2119 _ecore_xcb_button_grabs = NULL;
2123 t = realloc(_ecore_xcb_button_grabs,
2124 _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window));
2126 _ecore_xcb_button_grabs = t;
2132 _ecore_xcb_window_key_grab_remove(Ecore_X_Window win)
2134 LOGFN(__FILE__, __LINE__, __FUNCTION__);
2137 if (_ecore_xcb_key_grabs_num > 0)
2139 int i = 0, shuffle = 0;
2141 for (i = 0; i < _ecore_xcb_key_grabs_num; i++)
2144 _ecore_xcb_key_grabs[i - 1] = _ecore_xcb_key_grabs[i];
2146 if ((!shuffle) && (_ecore_xcb_key_grabs[i] == win))
2154 _ecore_xcb_key_grabs_num--;
2155 if (_ecore_xcb_key_grabs_num <= 0)
2157 free(_ecore_xcb_key_grabs);
2158 _ecore_xcb_key_grabs = NULL;
2162 t = realloc(_ecore_xcb_key_grabs,
2163 _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window));
2165 _ecore_xcb_key_grabs = t;
2171 _ecore_xcb_window_grab_allow_events(Ecore_X_Window event_win,
2172 Ecore_X_Window child_win,
2175 Ecore_X_Time timestamp)
2179 LOGFN(__FILE__, __LINE__, __FUNCTION__);
2182 for (i = 0; i < _ecore_xcb_button_grabs_num; i++)
2184 if ((_ecore_xcb_button_grabs[i] == event_win) ||
2185 (_ecore_xcb_button_grabs[i] == child_win))
2187 Eina_Bool replay = EINA_FALSE;
2189 if (_ecore_xcb_window_grab_replay_func)
2192 _ecore_xcb_window_grab_replay_func(_ecore_xcb_window_grab_replay_data,
2197 xcb_allow_events(_ecore_xcb_conn,
2198 XCB_ALLOW_REPLAY_POINTER, timestamp);
2202 xcb_allow_events(_ecore_xcb_conn,
2203 XCB_ALLOW_ASYNC_POINTER, timestamp);
2211 _ecore_xcb_window_modifiers_get(unsigned int state)
2215 if (state & ECORE_EVENT_MODIFIER_SHIFT)
2216 xmodifiers |= ECORE_X_MODIFIER_SHIFT;
2217 if (state & ECORE_EVENT_MODIFIER_CTRL)
2218 xmodifiers |= ECORE_X_MODIFIER_CTRL;
2219 if (state & ECORE_EVENT_MODIFIER_ALT)
2220 xmodifiers |= ECORE_X_MODIFIER_ALT;
2221 if (state & ECORE_EVENT_MODIFIER_WIN)
2222 xmodifiers |= ECORE_X_MODIFIER_WIN;
2223 if (state & ECORE_EVENT_MODIFIER_ALTGR)
2224 xmodifiers |= ECORE_X_MODIFIER_ALTGR;
2225 if (state & ECORE_EVENT_LOCK_SCROLL)
2226 xmodifiers |= ECORE_X_LOCK_SCROLL;
2227 if (state & ECORE_EVENT_LOCK_NUM)
2228 xmodifiers |= ECORE_X_LOCK_NUM;
2229 if (state & ECORE_EVENT_LOCK_CAPS)
2230 xmodifiers |= ECORE_X_LOCK_CAPS;
2231 if (state & ECORE_EVENT_LOCK_SHIFT)
2232 xmodifiers |= ECORE_X_LOCK_SHIFT;
2237 static xcb_visualtype_t *
2238 _ecore_xcb_window_find_visual_by_id(xcb_visualid_t id)
2240 xcb_depth_iterator_t diter;
2241 xcb_visualtype_iterator_t viter;
2244 diter = xcb_screen_allowed_depths_iterator(_ecore_xcb_screen);
2245 for (; diter.rem; xcb_depth_next(&diter))
2247 viter = xcb_depth_visuals_iterator(diter.data);
2248 for (; viter.rem; xcb_visualtype_next(&viter))
2250 if (viter.data->visual_id == id)