59d2324684916eab70b59ec839a5dfa9cba99476
[profile/ivi/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_window.c
1 #include <string.h>
2
3 #include <Ecore.h>
4
5 #include "ecore_xcb_private.h"
6 #include "Ecore_X_Atoms.h"
7
8 static int ignore_num = 0;
9 static Ecore_X_Window *ignore_list = NULL;
10
11 static Ecore_X_Window      _ecore_x_window_at_xy_get(Ecore_X_Window  base,
12                                                      int16_t         base_x,
13                                                      int16_t         base_y,
14                                                      int16_t         x,
15                                                      int16_t         y,
16                                                      Ecore_X_Window *skip,
17                                                      int             skip_num);
18
19 #ifdef ECORE_XCB_RENDER
20 static Ecore_X_Window      _ecore_x_window_argb_internal_new(Ecore_X_Window parent,
21                                                              int16_t        x,
22                                                              int16_t        y,
23                                                              uint16_t       w,
24                                                              uint16_t       h,
25                                                              uint8_t        override_redirect,
26                                                              uint8_t        save_under);
27 #endif /* ECORE_XCB_RENDER */
28
29 /**
30  * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
31  *
32  * Functions that can be used to create an X window.
33  */
34
35 /**
36  * Creates a new window.
37  * @param   parent The parent window to use.  If @p parent is @c 0, the root
38  *                 window of the default display is used.
39  * @param   x      X position.
40  * @param   y      Y position.
41  * @param   w      Width.
42  * @param   h      Height.
43  * @return  The new window handle.
44  * @ingroup Ecore_X_Window_Create_Group
45  */
46 EAPI Ecore_X_Window
47 ecore_x_window_new(Ecore_X_Window parent,
48                    int            x,
49                    int            y,
50                    int            width,
51                    int            height)
52 {
53    uint32_t value_list[9];
54    Ecore_X_Window window;
55    xcb_visualid_t vis = { XCB_WINDOW_CLASS_COPY_FROM_PARENT };
56    uint32_t value_mask;
57
58    if (parent == 0)
59       parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
60
61    value_mask =
62       XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
63       XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_OVERRIDE_REDIRECT |
64       XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
65
66    value_list[0] = XCB_NONE;
67    value_list[1] = 0;
68    value_list[2] = XCB_GRAVITY_NORTH_WEST;
69    value_list[3] = XCB_GRAVITY_NORTH_WEST;
70    value_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
71    value_list[5] = 0;
72    value_list[6] = 0;
73    value_list[7] =
74       XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
75       XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
76       XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
77       XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
78       XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
79       XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE |
80       XCB_EVENT_MASK_COLOR_MAP_CHANGE;
81    value_list[8] = XCB_EVENT_MASK_NO_EVENT;
82
83    window = xcb_generate_id(_ecore_xcb_conn);
84    xcb_create_window(_ecore_xcb_conn,
85                      XCB_WINDOW_CLASS_COPY_FROM_PARENT,
86                      window, parent, x, y, width, height, 0,
87                      XCB_WINDOW_CLASS_INPUT_OUTPUT,
88                      vis,
89                      value_mask,
90                      value_list);
91
92    if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
93       ecore_x_window_defaults_set(window);
94
95    return window;
96 } /* ecore_x_window_new */
97
98 /**
99  * Creates a window with the override redirect attribute set to @c True.
100  * @param   parent The parent window to use.  If @p parent is @c 0, the root
101  *                 window of the default display is used.
102  * @param   x      X position.
103  * @param   y      Y position.
104  * @param   w      Width.
105  * @param   h      Height.
106  * @return  The new window handle.
107  * @ingroup Ecore_X_Window_Create_Group
108  */
109 EAPI Ecore_X_Window
110 ecore_x_window_override_new(Ecore_X_Window parent,
111                             int            x,
112                             int            y,
113                             int            width,
114                             int            height)
115 {
116    uint32_t value_list[9];
117    Ecore_X_Window window;
118    xcb_visualid_t vis = { XCB_WINDOW_CLASS_COPY_FROM_PARENT };
119    uint32_t value_mask;
120
121    if (parent == 0)
122       parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
123
124    value_mask =
125       XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
126       XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_OVERRIDE_REDIRECT |
127       XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
128
129    value_list[0] = XCB_NONE;
130    value_list[1] = 0;
131    value_list[2] = XCB_GRAVITY_NORTH_WEST;
132    value_list[3] = XCB_GRAVITY_NORTH_WEST;
133    value_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
134    value_list[5] = 1;
135    value_list[6] = 0;
136    value_list[7] =
137       XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
138       XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
139       XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
140       XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
141       XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
142       XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE |
143       XCB_EVENT_MASK_COLOR_MAP_CHANGE;
144    value_list[8] = XCB_EVENT_MASK_NO_EVENT;
145
146    window = xcb_generate_id(_ecore_xcb_conn);
147    xcb_create_window(_ecore_xcb_conn,
148                      XCB_WINDOW_CLASS_COPY_FROM_PARENT,
149                      window, parent, x, y, width, height, 0,
150                      XCB_WINDOW_CLASS_INPUT_OUTPUT,
151                      vis,
152                      value_mask,
153                      value_list);
154    return window;
155 } /* ecore_x_window_override_new */
156
157 /**
158  * Creates a new input window.
159  * @param   parent The parent window to use.    If @p parent is @c 0, the root
160  *                 window of the default display is used.
161  * @param   x      X position.
162  * @param   y      Y position.
163  * @param   w      Width.
164  * @param   h      Height.
165  * @return  The new window.
166  * @ingroup Ecore_X_Window_Create_Group
167  */
168 EAPI Ecore_X_Window
169 ecore_x_window_input_new(Ecore_X_Window parent,
170                          int            x,
171                          int            y,
172                          int            width,
173                          int            height)
174 {
175    uint32_t value_list[3];
176    Ecore_X_Window window;
177    xcb_visualid_t vis = { XCB_WINDOW_CLASS_COPY_FROM_PARENT };
178    uint32_t value_mask;
179
180    if (parent == 0)
181       parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
182
183    value_mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
184
185    value_list[0] = 1;
186    value_list[1] =
187       XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
188       XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
189       XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
190       XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
191       XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
192       XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE |
193       XCB_EVENT_MASK_COLOR_MAP_CHANGE;
194    value_list[2] = XCB_EVENT_MASK_NO_EVENT;
195
196    window = xcb_generate_id(_ecore_xcb_conn);
197    xcb_create_window(_ecore_xcb_conn,
198                      XCB_WINDOW_CLASS_COPY_FROM_PARENT,
199                      window, parent, x, y, width, height, 0,
200                      XCB_WINDOW_CLASS_INPUT_OUTPUT,
201                      vis,
202                      value_mask,
203                      value_list);
204
205    if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
206      {
207      }
208
209    return window;
210 } /* ecore_x_window_input_new */
211
212 /**
213  * Creates a new window.
214  * @param   parent The parent window to use.  If @p parent is @c 0, the root
215  *                 window of the default display is used.
216  * @param   x      X position.
217  * @param   y      Y position.
218  * @param   width  Width.
219  * @param   height Height.
220  * @return         The new window handle.
221  * @ingroup Ecore_X_Window_Create_Group
222  */
223 EAPI Ecore_X_Window
224 ecore_x_window_manager_argb_new(Ecore_X_Window parent,
225                                 int            x,
226                                 int            y,
227                                 int            width,
228                                 int            height)
229 {
230    Ecore_X_Window window = 0;
231
232 #ifdef ECORE_XCB_RENDER
233    window = _ecore_x_window_argb_internal_new(parent,
234                                               x, y, width, height,
235                                               1, 0);
236 #endif /* ECORE_XCB_RENDER */
237
238    return window;
239 } /* ecore_x_window_manager_argb_new */
240
241 /**
242  * Creates a new window.
243  * @param   parent The parent window to use.  If @p parent is @c 0, the root
244  *                 window of the default display is used.
245  * @param   x      X position.
246  * @param   y      Y position.
247  * @param   width  Width.
248  * @param   height Height.
249  * @return         The new window handle.
250  * @ingroup Ecore_X_Window_Create_Group
251  */
252 EAPI Ecore_X_Window
253 ecore_x_window_argb_new(Ecore_X_Window parent,
254                         int            x,
255                         int            y,
256                         int            width,
257                         int            height)
258 {
259    Ecore_X_Window window = 0;
260
261 #ifdef ECORE_XCB_RENDER
262    window = _ecore_x_window_argb_internal_new(parent,
263                                               x, y, width, height,
264                                               0, 0);
265 #endif /* ECORE_XCB_RENDER */
266
267    return window;
268 } /* ecore_x_window_argb_new */
269
270 /**
271  * Creates a window with the override redirect attribute set to @c True.
272  * @param   parent The parent window to use.  If @p parent is @c 0, the root
273  *                 window of the default display is used.
274  * @param   x      X position.
275  * @param   y      Y position.
276  * @param   width  Width.
277  * @param   height Height.
278  * @return         The new window handle.
279  * @ingroup Ecore_X_Window_Create_Group
280  */
281 EAPI Ecore_X_Window
282 ecore_x_window_override_argb_new(Ecore_X_Window parent,
283                                  int            x,
284                                  int            y,
285                                  int            width,
286                                  int            height)
287 {
288    Ecore_X_Window window = 0;
289
290 #ifdef ECORE_XCB_RENDER
291    window = _ecore_x_window_argb_internal_new(parent,
292                                               x, y, width, height,
293                                               1, 0);
294 #endif /* ECORE_XCB_RENDER */
295
296    return window;
297 } /* ecore_x_window_override_argb_new */
298
299 /**
300  * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions
301  *
302  * Functions to destroy X windows.
303  */
304
305 /**
306  * Deletes the given window.
307  * @param   window The given window.
308  * @ingroup Ecore_X_Window_Destroy_Group
309  */
310 EAPI void
311 ecore_x_window_free(Ecore_X_Window window)
312 {
313    /* sorry sir, deleting the root window doesn't sound like
314     * a smart idea.
315     */
316    if (window)
317       xcb_destroy_window(_ecore_xcb_conn, window);
318 } /* ecore_x_window_free */
319
320 /**
321  * Sends a delete request to the given window.
322  * @param   window The given window.
323  * @ingroup Ecore_X_Window_Destroy_Group
324  */
325 EAPI void
326 ecore_x_window_delete_request_send(Ecore_X_Window window)
327 {
328    xcb_client_message_event_t ev;
329
330    /* sorry sir, deleting the root window doesn't sound like
331     * a smart idea.
332     */
333    if (window == 0)
334       return;
335
336    ev.response_type = XCB_CLIENT_MESSAGE;
337    ev.format = 32;
338    ev.sequence = 0;
339    ev.window = window;
340    ev.type = ECORE_X_ATOM_WM_PROTOCOLS;
341    ev.data.data32[0] = ECORE_X_ATOM_WM_DELETE_WINDOW;
342    ev.data.data32[1] = XCB_CURRENT_TIME;
343
344    xcb_send_event(_ecore_xcb_conn, 0, window,
345                   XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
346 } /* ecore_x_window_delete_request_send */
347
348 /**
349  * @defgroup Ecore_X_Window_Configure_Group X Window Configure Functions
350  *
351  * Functions to configure X windows.
352  */
353
354 /**
355  * Configures the given window with the given mask.
356  * @param   window       The given window.
357  * @param   mask         The given mask.
358  * @param   x            The X coordinate of the window.
359  * @param   y            The Y coordinate of the window.
360  * @param   width        The width of the window.
361  * @param   height       The height of the window.
362  * @param   border_width The border width of the window.
363  * @param   sibling      The sibling window of the window.
364  * @param   stack_mode   The stack mode of the window.
365  * @ingroup Ecore_X_Window_Configure_Group
366  */
367 EAPI void
368 ecore_x_window_configure(Ecore_X_Window                window,
369                          Ecore_X_Window_Configure_Mask mask,
370                          int                           x,
371                          int                           y,
372                          int                           width,
373                          int                           height,
374                          int                           border_width,
375                          Ecore_X_Window                sibling,
376                          int                           stack_mode)
377 {
378    uint32_t *value_list;
379    uint32_t value_mask;
380    int length = 0;
381
382    if (!window)
383       return;
384
385    value_mask = mask;
386    for (; value_mask; value_mask >>= 1)
387       if (value_mask & 1)
388          length++;
389
390    value_list = (uint32_t *)malloc(sizeof(uint32_t) * length);
391    if (!value_list)
392       return;
393
394    value_mask = mask;
395    for (; value_mask; value_mask >>= 1, value_list++)
396       if (value_mask & 1)
397         {
398            switch (value_mask) {
399               case XCB_CONFIG_WINDOW_X:
400                  *value_list = x;
401                  break;
402
403               case XCB_CONFIG_WINDOW_Y:
404                  *value_list = y;
405                  break;
406
407               case XCB_CONFIG_WINDOW_WIDTH:
408                  *value_list = width;
409                  break;
410
411               case XCB_CONFIG_WINDOW_HEIGHT:
412                  *value_list = height;
413                  break;
414
415               case XCB_CONFIG_WINDOW_BORDER_WIDTH:
416                  *value_list = border_width;
417                  break;
418
419               case XCB_CONFIG_WINDOW_SIBLING:
420                  *value_list = sibling;
421                  break;
422
423               case XCB_CONFIG_WINDOW_STACK_MODE:
424                  *value_list = stack_mode;
425                  break;
426              } /* switch */
427         }
428
429    xcb_configure_window(_ecore_xcb_conn, window, mask, value_list);
430    free(value_list);
431 } /* ecore_x_window_configure */
432
433 /**
434  * Moves a window to the position @p x, @p y.
435  *
436  * The position is relative to the upper left hand corner of the
437  * parent window.
438  *
439  * @param   window The window to move.
440  * @param   x      X position.
441  * @param   y      Y position.
442  * @ingroup Ecore_X_Window_Configure_Group
443  */
444 EAPI void
445 ecore_x_window_move(Ecore_X_Window window,
446                     int            x,
447                     int            y)
448 {
449    uint32_t value_list[2];
450    uint32_t value_mask;
451
452    if (!window)
453       return;
454
455    value_mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
456
457    value_list[0] = x;
458    value_list[1] = y;
459
460    xcb_configure_window(_ecore_xcb_conn, window, value_mask, value_list);
461 } /* ecore_x_window_move */
462
463 /**
464  * Resizes a window.
465  * @param   window The window to resize.
466  * @param   width  New width of the window.
467  * @param   height New height of the window.
468  * @ingroup Ecore_X_Window_Configure_Group
469  */
470 EAPI void
471 ecore_x_window_resize(Ecore_X_Window window,
472                       int            width,
473                       int            height)
474 {
475    uint32_t value_list[2];
476    uint32_t value_mask;
477
478    if (!window)
479       return;
480
481    if (width < 1)
482       width = 1;
483
484    if (height < 1)
485       height = 1;
486
487    value_mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
488
489    value_list[0] = width;
490    value_list[1] = height;
491
492    xcb_configure_window(_ecore_xcb_conn, window, value_mask, value_list);
493 } /* ecore_x_window_resize */
494
495 /**
496  * Moves and resizes a window.
497  * @param   window The window to move and resize.
498  * @param   x      New X position of the window.
499  * @param   y      New Y position of the window.
500  * @param   width  New width of the window.
501  * @param   height New height of the window.
502  * @ingroup Ecore_X_Window_Configure_Group
503  */
504 EAPI void
505 ecore_x_window_move_resize(Ecore_X_Window window,
506                            int            x,
507                            int            y,
508                            int            width,
509                            int            height)
510 {
511    uint32_t value_list[4];
512    uint32_t value_mask;
513
514    if (!window)
515       return;
516
517    if (width < 1)
518       width = 1;
519
520    if (height < 1)
521       height = 1;
522
523    value_mask =
524       XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
525       XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
526
527    value_list[0] = x;
528    value_list[1] = y;
529    value_list[2] = width;
530    value_list[3] = height;
531
532    xcb_configure_window(_ecore_xcb_conn, window, value_mask, value_list);
533 } /* ecore_x_window_move_resize */
534
535 /**
536  * Sets the width of the border of the given window.
537  * @param   window       The given window.
538  * @param   border_width The new border width.
539  * @ingroup Ecore_X_Window_Configure_Group
540  */
541 EAPI void
542 ecore_x_window_border_width_set(Ecore_X_Window window,
543                                 int            border_width)
544 {
545    uint32_t value_list;
546
547    /* doesn't make sense to call this on a root window */
548    if (!window)
549       return;
550
551    value_list = border_width;
552
553    xcb_configure_window(_ecore_xcb_conn, window, XCB_CONFIG_WINDOW_BORDER_WIDTH, &value_list);
554 } /* ecore_x_window_border_width_set */
555
556 /**
557  * Raises the given window.
558  * @param   window The window to raise.
559  * @ingroup Ecore_X_Window_Configure_Group
560  */
561 EAPI void
562 ecore_x_window_raise(Ecore_X_Window window)
563 {
564    uint32_t value_list;
565
566    if (!window)
567       return;
568
569    value_list = XCB_STACK_MODE_ABOVE;
570
571    xcb_configure_window(_ecore_xcb_conn, window, XCB_CONFIG_WINDOW_STACK_MODE, &value_list);
572 } /* ecore_x_window_raise */
573
574 /**
575  * Lowers the given window.
576  * @param   window The window to lower.
577  * @ingroup Ecore_X_Window_Configure_Group
578  */
579 EAPI void
580 ecore_x_window_lower(Ecore_X_Window window)
581 {
582    uint32_t value_list;
583
584    if (!window)
585       return;
586
587    value_list = XCB_STACK_MODE_BELOW;
588
589    xcb_configure_window(_ecore_xcb_conn, window, XCB_CONFIG_WINDOW_STACK_MODE, &value_list);
590 } /* ecore_x_window_lower */
591
592 /**
593  * @defgroup Ecore_X_Window_Change_Properties_Group X Window Change Property Functions
594  *
595  * Functions that change window properties.
596  */
597
598 /**
599  * Sets the default properties for the given window.
600  *
601  * The default properties set for the window are @c WM_CLIENT_MACHINE and
602  * @c _NET_WM_PID.
603  *
604  * @param   window The given window.
605  * @ingroup Ecore_X_Window_Change_Property_Group
606  */
607 EAPI void
608 ecore_x_window_defaults_set(Ecore_X_Window window)
609 {
610    char buf[MAXHOSTNAMELEN];
611    pid_t pid;
612    int argc;
613    char **argv;
614
615    /*
616     * Set WM_CLIENT_MACHINE.
617     */
618    gethostname(buf, MAXHOSTNAMELEN);
619    buf[MAXHOSTNAMELEN - 1] = '\0';
620    /* The ecore function uses UTF8 which Xlib may not like (especially
621     * with older clients) */
622    /* ecore_xcb_window_prop_string_set(win, ECORE_X_ATOM_WM_CLIENT_MACHINE,
623                                   (char *)buf); */
624    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
625                        ECORE_X_ATOM_WM_CLIENT_MACHINE,
626                        ECORE_X_ATOM_STRING,
627                        8, strlen(buf), buf);
628
629    /*
630     * Set _NET_WM_PID
631     */
632    pid = getpid();
633    ecore_x_netwm_pid_set(window, pid);
634
635    ecore_x_netwm_window_type_set(window, ECORE_X_WINDOW_TYPE_NORMAL);
636
637    ecore_app_args_get(&argc, &argv);
638    ecore_x_icccm_command_set(window, argc, argv);
639 } /* ecore_x_window_defaults_set */
640
641 /**
642  * @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions
643  *
644  * Functions to change the visibility of X windows.
645  */
646
647 /**
648  * Shows a window.
649  *
650  * Synonymous to "mapping" a window in X Window System terminology.
651  *
652  * @param   window The window to show.
653  * @ingroup Ecore_X_Window_Visibility_Group
654  */
655 EAPI void
656 ecore_x_window_show(Ecore_X_Window window)
657 {
658    xcb_map_window(_ecore_xcb_conn, window);
659 } /* ecore_x_window_show */
660
661 /**
662  * Hides a window.
663  *
664  * Synonymous to "unmapping" a window in X Window System terminology.
665  *
666  * @param   window The window to hide.
667  * @ingroup Ecore_X_Window_Visibility_Group
668  */
669 EAPI void
670 ecore_x_window_hide(Ecore_X_Window window)
671 {
672    xcb_unmap_notify_event_t ev;
673    Ecore_X_Window root;
674
675    /* ICCCM: SEND unmap event... */
676    root = window;
677    /* FIXME: is it correct ? */
678    if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1)
679       root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
680    else
681      {
682         xcb_get_geometry_cookie_t cookie;
683         xcb_get_geometry_reply_t *rep;
684         Ecore_X_Drawable draw;
685
686         /* FIXME: can we avoid round trips, here ? */
687         draw = window;
688         cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, draw);
689         rep = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL);
690         if (!rep)
691            return;
692
693         root = rep->root;
694         free(rep);
695      }
696
697    ev.response_type = XCB_UNMAP_NOTIFY;
698    ev.pad0 = 0;
699    ev.sequence = 0;
700    ev.event = root;
701    ev.window = window;
702    ev.from_configure = 0;
703
704    xcb_send_event(_ecore_xcb_conn, 0, root,
705                   XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
706                   (const char *)&ev);
707    xcb_unmap_window(_ecore_xcb_conn, window);
708 } /* ecore_x_window_hide */
709
710 /**
711  * @defgroup Ecore_X_Window_Input_Focus_Group X Window Input Focus Functions
712  *
713  * Functions that manage the focus of an X Window.
714  */
715
716 /**
717  * Sets the focus to the window @p window.
718  * @param   window The window to focus.
719  * @ingroup Ecore_X_Window_Input_Focus_Group
720  */
721 EAPI void
722 ecore_x_window_focus(Ecore_X_Window window)
723 {
724    Ecore_X_Time time = XCB_CURRENT_TIME;
725
726    if (window == 0)
727       window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
728
729    /* xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_NONE, win, time); */
730    xcb_set_input_focus(_ecore_xcb_conn,
731                        XCB_INPUT_FOCUS_POINTER_ROOT, window, time);
732 } /* ecore_x_window_focus */
733
734 /**
735  * Sets the focus to the given window at a specific time.
736  * @param   window The window to focus.
737  * @param   time   When to set the focus to the window.
738  * @ingroup Ecore_X_Window_Input_Focus_Group
739  */
740 EAPI void
741 ecore_x_window_focus_at_time(Ecore_X_Window window,
742                              Ecore_X_Time   time)
743 {
744    if (window == 0)
745       window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
746
747    /* xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_NONE, win, time); */
748    xcb_set_input_focus(_ecore_xcb_conn,
749                        XCB_INPUT_FOCUS_POINTER_ROOT, window, time);
750 } /* ecore_x_window_focus_at_time */
751
752 /**
753  * @defgroup Ecore_X_Window_Reparent_Group X Window Reparent Functions
754  *
755  * Functions that retrieve or changes the parent window of a window.
756  */
757
758 /**
759  * Moves a window to within another window at a given position.
760  * @param   window     The window to reparent.
761  * @param   new_parent The new parent window.
762  * @param   x          X position within new parent window.
763  * @param   y          Y position within new parent window.
764  * @ingroup Ecore_X_Window_Reparent_Group
765  */
766 EAPI void
767 ecore_x_window_reparent(Ecore_X_Window window,
768                         Ecore_X_Window new_parent,
769                         int            x,
770                         int            y)
771 {
772    if (new_parent == 0)
773       new_parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
774
775    xcb_reparent_window(_ecore_xcb_conn, window, new_parent, x, y);
776 } /* ecore_x_window_reparent */
777
778 /**
779  * @defgroup Ecore_X_Window_Change_Attributes_Group X Window Change Attributes Functions
780  *
781  * Functions that change the attributes of a window.
782  */
783
784 /**
785  * Sets the background pixmap of the given window.
786  * @param   window The given window.
787  * @param   pixmap The pixmap to set to.
788  * @ingroup Ecore_X_Window_Change_Attributes_Group
789  */
790 EAPI void
791 ecore_x_window_pixmap_set(Ecore_X_Window window,
792                           Ecore_X_Pixmap pixmap)
793 {
794    uint32_t value_list;
795
796    value_list = pixmap;
797    xcb_change_window_attributes(_ecore_xcb_conn, window,
798                                 XCB_CW_BACK_PIXMAP, &value_list);
799 } /* ecore_x_window_pixmap_set */
800
801 /**
802  * Sets the background color of the given window.
803  * @param   window The given window.
804  * @param   red    The red component of the color to set to.
805  * @param   green  The green component of the color to set to.
806  * @param   blue   The blue component of the color to set to.
807  * @ingroup Ecore_X_Window_Change_Attributes_Group
808  */
809 EAPI void
810 ecore_x_window_background_color_set(Ecore_X_Window window,
811                                     unsigned short red,
812                                     unsigned short green,
813                                     unsigned short blue)
814 {
815    xcb_alloc_color_cookie_t cookie;
816    xcb_alloc_color_reply_t *rep;
817    uint32_t value_list;
818
819    /* FIXME: should I provide a reply, and not the color components, here ? */
820    /*        (because of roundtrips) */
821    cookie = xcb_alloc_color_unchecked(_ecore_xcb_conn,
822                                       ((xcb_screen_t *)_ecore_xcb_screen)->default_colormap,
823                                       red, green, blue);
824    rep = xcb_alloc_color_reply(_ecore_xcb_conn, cookie, NULL);
825    if (!rep)
826       return;
827
828    value_list = rep->pixel;
829    xcb_change_window_attributes(_ecore_xcb_conn, window,
830                                 XCB_CW_BACK_PIXEL, &value_list);
831    free(rep);
832 } /* ecore_x_window_background_color_set */
833
834 /**
835  * Sets the bit gravity of the given window.
836  * @param   window  The given window.
837  * @param   gravity The gravity.
838  * @ingroup Ecore_X_Window_Change_Attributes_Group
839  */
840 EAPI void
841 ecore_x_window_pixel_gravity_set(Ecore_X_Window  window,
842                                  Ecore_X_Gravity gravity)
843 {
844    uint32_t value_list;
845
846    value_list = gravity;
847    xcb_change_window_attributes(_ecore_xcb_conn, window,
848                                 XCB_CW_BIT_GRAVITY, &value_list);
849 } /* ecore_x_window_pixel_gravity_set */
850
851 /**
852  * Sets the gravity of the given window.
853  * @param   window  The given window.
854  * @param   gravity The gravity.
855  * @ingroup Ecore_X_Window_Change_Attributes_Group
856  */
857 EAPI void
858 ecore_x_window_gravity_set(Ecore_X_Window  window,
859                            Ecore_X_Gravity gravity)
860 {
861    uint32_t value_list;
862
863    value_list = gravity;
864    xcb_change_window_attributes(_ecore_xcb_conn, window,
865                                 XCB_CW_WIN_GRAVITY, &value_list);
866 } /* ecore_x_window_gravity_set */
867
868 /**
869  * Sets the override attribute of the given window.
870  * @param   window            The given window.
871  * @param   override_redirect The override_redirect boolean.
872  * @ingroup Ecore_X_Window_Change_Attributes_Group
873  */
874 EAPI void
875 ecore_x_window_override_set(Ecore_X_Window window,
876                             int            override_redirect)
877 {
878    uint32_t value_list;
879
880    value_list = override_redirect;
881    xcb_change_window_attributes(_ecore_xcb_conn, window,
882                                 XCB_CW_OVERRIDE_REDIRECT, &value_list);
883 } /* ecore_x_window_override_set */
884
885 /**
886  * Shows the cursor of the given window.
887  * @param   window The given window.
888  * @param   show   If set to @c 0, hide the cursor. Show it otherwise.
889  * @ingroup Ecore_X_Window_Change_Attributes_Group
890  */
891 EAPI void
892 ecore_x_window_cursor_show(Ecore_X_Window window,
893                            int            show)
894 {
895    if (window == 0)
896       window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
897
898    if (!show)
899      {
900         Ecore_X_Cursor cursor;
901         Ecore_X_Drawable draw;
902         Ecore_X_Pixmap pixmap;
903         Ecore_X_Pixmap mask;
904         Ecore_X_GC gc;
905         xcb_point_t point;
906         uint32_t value_list;
907
908         draw = window;
909         pixmap = xcb_generate_id(_ecore_xcb_conn);
910         xcb_create_pixmap(_ecore_xcb_conn,
911                           1, pixmap, draw,
912                           1, 1);
913         mask = xcb_generate_id(_ecore_xcb_conn);
914         xcb_create_pixmap(_ecore_xcb_conn,
915                           1, mask, draw,
916                           1, 1);
917
918         gc = xcb_generate_id(_ecore_xcb_conn);
919         xcb_create_gc (_ecore_xcb_conn, gc, draw, 0, NULL);
920         value_list = 0;
921         xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &value_list);
922
923         draw = mask;
924         point.x = 0;
925         point.y = 0;
926         xcb_poly_point(_ecore_xcb_conn, XCB_COORD_MODE_ORIGIN, draw,
927                        gc, 1, &point);
928
929         xcb_free_gc(_ecore_xcb_conn, gc);
930
931         cursor = xcb_generate_id(_ecore_xcb_conn);
932         xcb_create_cursor(_ecore_xcb_conn, cursor,
933                           pixmap, mask,
934                           0, 0, 0,
935                           0, 0, 0,
936                           0, 0);
937         value_list = cursor;
938         xcb_change_window_attributes(_ecore_xcb_conn, window,
939                                      XCB_CW_CURSOR, &value_list);
940
941         xcb_free_cursor(_ecore_xcb_conn, cursor);
942         xcb_free_pixmap(_ecore_xcb_conn, mask);
943         xcb_free_pixmap(_ecore_xcb_conn, pixmap);
944      }
945    else
946      {
947         uint32_t value_list;
948
949         value_list = 0;
950         xcb_change_window_attributes(_ecore_xcb_conn, window,
951                                      XCB_CW_CURSOR, &value_list);
952      }
953 } /* ecore_x_window_cursor_show */
954
955 /**
956  * Sets the cursor of the given window.
957  * @param   window The given window.
958  * @param   cursor The given cursor.
959  * @ingroup Ecore_X_Window_Change_Attributes_Group
960  */
961 EAPI void
962 ecore_x_window_cursor_set(Ecore_X_Window window,
963                           Ecore_X_Cursor cursor)
964 {
965    uint32_t value_list;
966
967    value_list = cursor;
968    xcb_change_window_attributes(_ecore_xcb_conn, window,
969                                 XCB_CW_CURSOR, &value_list);
970 } /* ecore_x_window_cursor_set */
971
972 /**
973  * Todo
974  * @param   window The given window.
975  * @ingroup Ecore_X_Window_Change_Attributes_Group
976  */
977 EAPI void
978 ecore_x_window_container_manage(Ecore_X_Window window)
979 {
980    uint32_t value_list;
981
982    value_list =
983       XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
984       XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
985    xcb_change_window_attributes(_ecore_xcb_conn, window,
986                                 XCB_CW_EVENT_MASK, &value_list);
987 } /* ecore_x_window_container_manage */
988
989 /**
990  * Todo
991  * @param   window The given window.
992  * @ingroup Ecore_X_Window_Change_Attributes_Group
993  */
994 EAPI void
995 ecore_x_window_client_manage(Ecore_X_Window window)
996 {
997    uint32_t value_list;
998
999    value_list =
1000       XCB_EVENT_MASK_VISIBILITY_CHANGE |
1001 /*      XCB_EVENT_MASK_RESIZE_REDIRECT | */
1002       XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1003       XCB_EVENT_MASK_FOCUS_CHANGE |
1004       XCB_EVENT_MASK_PROPERTY_CHANGE |
1005       XCB_EVENT_MASK_COLOR_MAP_CHANGE;
1006    xcb_change_window_attributes(_ecore_xcb_conn, window,
1007                                 XCB_CW_EVENT_MASK, &value_list);
1008 #ifdef ECORE_XCB_SHAPE
1009    xcb_shape_select_input(_ecore_xcb_conn, window, 1);
1010 #endif /* ECORE_XCB_SHAPE */
1011 } /* ecore_x_window_client_manage */
1012
1013 /**
1014  * Todo
1015  * @param   window The given window.
1016  * @ingroup Ecore_X_Window_Change_Attributes_Group
1017  */
1018 EAPI void
1019 ecore_x_window_sniff(Ecore_X_Window window)
1020 {
1021    uint32_t value_list;
1022
1023    value_list =
1024       XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1025       XCB_EVENT_MASK_PROPERTY_CHANGE;
1026    xcb_change_window_attributes(_ecore_xcb_conn, window,
1027                                 XCB_CW_EVENT_MASK, &value_list);
1028 } /* ecore_x_window_sniff */
1029
1030 /**
1031  * Todo
1032  * @param   window The given window.
1033  * @ingroup Ecore_X_Window_Change_Attributes_Group
1034  */
1035 EAPI void
1036 ecore_x_window_client_sniff(Ecore_X_Window window)
1037 {
1038    uint32_t value_list;
1039
1040    value_list =
1041       XCB_EVENT_MASK_VISIBILITY_CHANGE |
1042       XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1043       XCB_EVENT_MASK_FOCUS_CHANGE |
1044       XCB_EVENT_MASK_PROPERTY_CHANGE |
1045       XCB_EVENT_MASK_COLOR_MAP_CHANGE;
1046    xcb_change_window_attributes(_ecore_xcb_conn, window,
1047                                 XCB_CW_EVENT_MASK, &value_list);
1048 #ifdef ECORE_XCB_SHAPE
1049    xcb_shape_select_input(_ecore_xcb_conn, window, 1);
1050 #endif /* ECORE_XCB_SHAPE */
1051 } /* ecore_x_window_client_sniff */
1052
1053 /**
1054  * Clears an area of the given window.
1055  * @param   window  The given window.
1056  * @param   x            The X coordinate of the area.
1057  * @param   y            The Y coordinate of the area.
1058  * @param   width        The width of the area.
1059  * @param   height       The height of the area.
1060  * @ingroup Ecore_X_Window_Clear_Area_Group
1061  */
1062 EAPI void
1063 ecore_x_window_area_clear(Ecore_X_Window window,
1064                           int            x,
1065                           int            y,
1066                           int            width,
1067                           int            height)
1068 {
1069    xcb_clear_area(_ecore_xcb_conn, 0, window, x, y, width, height);
1070 } /* ecore_x_window_area_clear */
1071
1072 /**
1073  * Exposes an area of the given window.
1074  * @param   window  The given window.
1075  * @param   x            The X coordinate of the area.
1076  * @param   y            The Y coordinate of the area.
1077  * @param   width        The width of the area.
1078  * @param   height       The height of the area.
1079  * @ingroup Ecore_X_Window_Clear_Area_Group
1080  */
1081 EAPI void
1082 ecore_x_window_area_expose(Ecore_X_Window window,
1083                            int            x,
1084                            int            y,
1085                            int            width,
1086                            int            height)
1087 {
1088    xcb_clear_area(_ecore_xcb_conn, 1, window, x, y, width, height);
1089 } /* ecore_x_window_area_expose */
1090
1091 /**
1092  * @defgroup Ecore_X_Window_Save_Set_Group X Window Change Save Set Functions
1093  *
1094  * Functions that either inserts or deletes the specified window from
1095  * the client's save-set.
1096  */
1097
1098 /**
1099  * Inserts the window in the client's save-set.
1100  * @param   window The window to insert in the client's save-set.
1101  * @ingroup Ecore_X_Window_Save_Set_Group
1102  */
1103 EAPI void
1104 ecore_x_window_save_set_add(Ecore_X_Window window)
1105 {
1106    xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, window);
1107 } /* ecore_x_window_save_set_add */
1108
1109 /**
1110  * Deletes the window from the client's save-set.
1111  * @param   window The window to delete from the client's save-set.
1112  * @ingroup Ecore_X_Window_Save_Set_Group
1113  */
1114 EAPI void
1115 ecore_x_window_save_set_del(Ecore_X_Window window)
1116 {
1117    xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, window);
1118 } /* ecore_x_window_save_set_del */
1119
1120 /******************************
1121 *
1122 * Request that have a reply
1123 *
1124 ******************************/
1125
1126 /**
1127  * Sends the GetInputFocus request.
1128  * @ingroup Ecore_X_Window_Input_Focus_Group
1129  */
1130 EAPI void
1131 ecore_x_get_input_focus_prefetch(void)
1132 {
1133    xcb_get_input_focus_cookie_t cookie;
1134
1135    cookie = xcb_get_input_focus_unchecked(_ecore_xcb_conn);
1136    _ecore_xcb_cookie_cache(cookie.sequence);
1137 } /* ecore_x_get_input_focus_prefetch */
1138
1139 /**
1140  * Gets the reply of the GetInputFocus request sent by ecore_x_get_input_focus_prefetch().
1141  * @ingroup Ecore_X_Window_Input_Focus_Group
1142  */
1143 EAPI void
1144 ecore_x_get_input_focus_fetch(void)
1145 {
1146    xcb_get_input_focus_cookie_t cookie;
1147    xcb_get_input_focus_reply_t *reply;
1148
1149    cookie.sequence = _ecore_xcb_cookie_get();
1150    reply = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie, NULL);
1151    _ecore_xcb_reply_cache(reply);
1152 } /* ecore_x_get_input_focus_fetch */
1153
1154 /**
1155  * Gets the window that has focus.
1156  * @return  The window that has focus.
1157  *
1158  * Returns the window that has the focus. If an error aoocured, @c 0
1159  * is returned, otherwise the function returns the window that has focus.
1160  *
1161  * To use this function, you must call before, and in order,
1162  * ecore_x_get_input_focus_prefetch(), which sends the GetInputFocus request,
1163  * then ecore_x_get_input_focus_fetch(), which gets the reply.
1164  * @ingroup Ecore_X_Window_Input_Focus_Group
1165  */
1166 EAPI Ecore_X_Window
1167 ecore_x_window_focus_get(void)
1168 {
1169    xcb_get_input_focus_reply_t *reply;
1170    Ecore_X_Window window = 0;
1171
1172    reply = _ecore_xcb_reply_get();
1173    if (!reply)
1174       return window;
1175
1176    return reply->focus;
1177 } /* ecore_x_window_focus_get */
1178
1179 /**
1180  * @defgroup Ecore_X_Window_Get_Attributes_Group X Window Get Attributes Functions
1181  *
1182  * Functions that get the attributes of a window.
1183  */
1184
1185 /**
1186  * Sends the GetWindowAttributes request.
1187  * @ingroup Ecore_X_Window_Get_Attributes_Group
1188  */
1189 EAPI void
1190 ecore_x_get_window_attributes_prefetch(Ecore_X_Window window)
1191 {
1192    xcb_get_window_attributes_cookie_t cookie;
1193
1194    cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, window);
1195    _ecore_xcb_cookie_cache(cookie.sequence);
1196 } /* ecore_x_get_window_attributes_prefetch */
1197
1198 /**
1199  * Gets the reply of the GetWindowAttributes request sent by ecore_x_get_window_attributes_prefetch().
1200  * @ingroup Ecore_X_Window_Get_Attributes_Group
1201  */
1202 EAPI void
1203 ecore_x_get_window_attributes_fetch(void)
1204 {
1205    xcb_get_window_attributes_cookie_t cookie;
1206    xcb_get_window_attributes_reply_t *reply;
1207
1208    cookie.sequence = _ecore_xcb_cookie_get();
1209    reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
1210    _ecore_xcb_reply_cache(reply);
1211 } /* ecore_x_get_window_attributes_fetch */
1212
1213 /**
1214  * Retrieves the attributes of a window.
1215  * @param windows Unused.
1216  * @param att_ret Pointer to an Ecore_X_Window_Attributes
1217  *                  structure in which the attributes of a window
1218  *                  are to be stored.
1219  *
1220  * Retrieves the attributes of a window. If
1221  * @p att_ret is @c NULL, the function does nothing. If an error
1222  * occurred, @p att_ret is set to 0. Otherwise, the @p att_ret structure
1223  * is filled with the attributes os the requested window.
1224  *
1225  * To use this function, you must call before, and in order,
1226  * ecore_x_get_window_attributes_prefetch(), which sends the GetWindowAttributes request,
1227  * then ecore_x_get_window_attributes_fetch(), which gets the reply.
1228  * @ingroup Ecore_X_Window_Get_Attributes_Group
1229  */
1230 EAPI int
1231 ecore_x_window_attributes_get(Ecore_X_Window window      __UNUSED__,
1232                               Ecore_X_Window_Attributes *att_ret)
1233 {
1234    xcb_get_window_attributes_reply_t *reply;
1235
1236    if (!att_ret)
1237       return 0;
1238
1239    reply = _ecore_xcb_reply_get();
1240    if (!reply)
1241       return 0;
1242
1243    memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
1244
1245    if (reply->map_state != XCB_MAP_STATE_UNMAPPED)
1246       att_ret->visible = 1;
1247
1248    if (reply->map_state == XCB_MAP_STATE_VIEWABLE)
1249       att_ret->viewable = 1;
1250
1251    if (reply->override_redirect)
1252       att_ret->override = 1;
1253
1254    if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY)
1255       att_ret->input_only = 1;
1256
1257    if (reply->save_under)
1258       att_ret->save_under = 1;
1259
1260    att_ret->event_mask.mine = reply->your_event_mask;
1261    att_ret->event_mask.all = reply->all_event_masks;
1262    att_ret->event_mask.no_propagate = reply->do_not_propagate_mask;
1263    att_ret->window_gravity = reply->win_gravity;
1264    att_ret->pixel_gravity = reply->bit_gravity;
1265    att_ret->colormap = reply->colormap;
1266    att_ret->visual = reply->visual;
1267
1268    return 1;
1269 } /* ecore_x_window_attributes_get */
1270
1271 /**
1272  * Finds out whether the given window is currently visible.
1273  * @param  window Unused.
1274  * @return        1 if the window is visible, otherwise 0.
1275  *
1276  * Finds out whether the given window is currently visible.
1277  * If an error occurred, or if the window is not visible, 0 is
1278  * returned. Otherwise 1 is returned.
1279  *
1280  * To use this function, you must call before, and in order,
1281  * ecore_x_get_window_attributes_prefetch(), which sends the GetWindowAttributes request,
1282  * then ecore_x_get_window_attributes_fetch(), which gets the reply.
1283  * @ingroup Ecore_X_Window_Get_Attributes_Group
1284  */
1285 EAPI int
1286 ecore_x_window_visible_get(Ecore_X_Window window __UNUSED__)
1287 {
1288    xcb_get_window_attributes_reply_t *reply;
1289
1290    reply = _ecore_xcb_reply_get();
1291    if (!reply)
1292       return 0;
1293
1294    return (reply->map_state == XCB_MAP_STATE_VIEWABLE) ? 1 : 0;
1295 } /* ecore_x_window_visible_get */
1296
1297 /**
1298  * Sends the QueryPointer request.
1299  * @ingroup Ecore_X_Window_Parent_Group
1300  */
1301 EAPI void
1302 ecore_x_pointer_xy_get_prefetch(Ecore_X_Window window)
1303 {
1304    xcb_query_pointer_cookie_t cookie;
1305
1306    cookie = xcb_query_pointer_unchecked(_ecore_xcb_conn, window);
1307    _ecore_xcb_cookie_cache(cookie.sequence);
1308 } /* ecore_x_pointer_xy_get_prefetch */
1309
1310 /**
1311  * Gets the reply of the QueryPointer request sent by ecore_x_query_pointer_prefetch().
1312  * @ingroup Ecore_X_Window_Parent_Group
1313  */
1314 EAPI void
1315 ecore_x_pointer_xy_get_fetch(void)
1316 {
1317    xcb_query_pointer_cookie_t cookie;
1318    xcb_query_pointer_reply_t *reply;
1319
1320    cookie.sequence = _ecore_xcb_cookie_get();
1321    reply = xcb_query_pointer_reply(_ecore_xcb_conn, cookie, NULL);
1322    _ecore_xcb_reply_cache(reply);
1323 } /* ecore_x_pointer_xy_get_fetch */
1324
1325 /**
1326  * Retrieves the coordinates of the pointer.
1327  * @param window Unused.
1328  * @param x      The X coordinate of the pointer.
1329  * @param y      The Y coordinate of the pointer.
1330  *
1331  * Retrieves the coordinates of the pointer.
1332  * If the window used in
1333  * ecore_x_query_pointer_prefetch() is not on the same screen than
1334  * the root window or if an error occured, @p x and @p y  are set
1335  * to 0. Otherwise, they are respectively set to the X and Y
1336  * coordinates of the pointer.
1337  *
1338  * To use this function, you must call before, and in order,
1339  * ecore_x_query_pointer_prefetch(), which sends the QueryPointer request,
1340  * then ecore_x_query_pointer_fetch(), which gets the reply.
1341  * @ingroup Ecore_X_Window_Parent_Group
1342  */
1343 EAPI void
1344 ecore_x_pointer_xy_get(Ecore_X_Window window __UNUSED__,
1345                        int                  *x,
1346                        int                  *y)
1347 {
1348    xcb_query_pointer_reply_t *reply;
1349
1350    reply = _ecore_xcb_reply_get();
1351    if (!reply)
1352      {
1353         if (x)
1354            *x = 0;
1355
1356         if (y)
1357            *y = 0;
1358
1359         return;
1360      }
1361
1362    if (x)
1363       *x = reply->win_x;
1364
1365    if (y)
1366       *y = reply->win_y;
1367 } /* ecore_x_pointer_xy_get */
1368
1369 /**
1370  * Sends the QueryTree request.
1371  * @ingroup Ecore_X_Window_Parent_Group
1372  */
1373 EAPI void
1374 ecore_x_query_tree_prefetch(Ecore_X_Window window)
1375 {
1376    xcb_query_tree_cookie_t cookie;
1377
1378    cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, window);
1379    _ecore_xcb_cookie_cache(cookie.sequence);
1380 } /* ecore_x_query_tree_prefetch */
1381
1382 /**
1383  * Gets the reply of the QueryTree request sent by ecore_x_query_tree_prefetch().
1384  * @ingroup Ecore_X_Window_Parent_Group
1385  */
1386 EAPI void
1387 ecore_x_query_tree_fetch(void)
1388 {
1389    xcb_query_tree_cookie_t cookie;
1390    xcb_query_tree_reply_t *reply;
1391
1392    cookie.sequence = _ecore_xcb_cookie_get();
1393    reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
1394    _ecore_xcb_reply_cache(reply);
1395 } /* ecore_x_query_tree_fetch */
1396
1397 /**
1398  * Retrieves the parent window of the given window.
1399  * @param   window Unused.
1400  * @return         The parent window of @p window.
1401  *
1402  * Retrieves the parent window of the given window. If
1403  * an error occured, @c 0 is returned.
1404  *
1405  * To use this function, you must call before, and in order,
1406  * ecore_x_query_tree_prefetch(), which sends the QueryTree request,
1407  * then ecore_x_query_tree_fetch(), which gets the reply.
1408  * @ingroup Ecore_X_Window_Parent_Group
1409  */
1410 EAPI Ecore_X_Window
1411 ecore_x_window_parent_get(Ecore_X_Window window __UNUSED__)
1412 {
1413    xcb_query_tree_reply_t *reply;
1414
1415    reply = _ecore_xcb_reply_get();
1416    if (!reply)
1417       return 0;
1418
1419    return reply->parent;
1420 } /* ecore_x_window_parent_get */
1421
1422 /**
1423  * Retrieves the children windows of the given window.
1424  * @param   window Unused.
1425  * @param   num    children windows count.
1426  * @return         The children windows.
1427  *
1428  * Retrieves the children windows of the given window. If
1429  * an error occured, @c 0 is returned.
1430  *
1431  * To use this function, you must call before, and in order,
1432  * ecore_x_query_tree_prefetch(), which sends the QueryTree request,
1433  * then ecore_x_query_tree_fetch(), which gets the reply.
1434  * @ingroup Ecore_X_Window_Parent_Group
1435  */
1436 EAPI Ecore_X_Window *
1437 ecore_x_window_children_get(Ecore_X_Window window __UNUSED__,
1438                             int                  *num)
1439 {
1440    xcb_query_tree_reply_t *reply;
1441    Ecore_X_Window *windows = NULL;
1442
1443    if (num)
1444       *num = 0;
1445
1446    reply = _ecore_xcb_reply_get();
1447    if (!reply)
1448       return NULL;
1449
1450    windows = malloc(sizeof(Ecore_X_Window) * reply->children_len);
1451    if (!windows)
1452       return NULL;
1453
1454    if (num)
1455       *num = reply->children_len;
1456
1457    memcpy(windows,
1458           xcb_query_tree_children(reply),
1459           sizeof(Ecore_X_Window) * reply->children_len);
1460
1461    return windows;
1462 } /* ecore_x_window_children_get */
1463
1464 /* FIXME: I've tried to remove the round trips. 3 cookies are */
1465 /*        created at the beginning of the function. Because of */
1466 /*        the recursivity of the algo, I can't find better trick */
1467 static Ecore_X_Window
1468 _ecore_x_window_at_xy_get(Ecore_X_Window  base,
1469                           int16_t         base_x,
1470                           int16_t         base_y,
1471                           int16_t         x,
1472                           int16_t         y,
1473                           Ecore_X_Window *skip,
1474                           int             skip_num)
1475 {
1476    xcb_get_window_attributes_cookie_t cookie_get_window_attributes;
1477    xcb_get_geometry_cookie_t cookie_get_geometry;
1478    xcb_query_tree_cookie_t cookie_query_tree;
1479    xcb_get_window_attributes_reply_t *reply_get_window_attributes;
1480    xcb_get_geometry_reply_t *reply_get_geometry;
1481    xcb_query_tree_reply_t *reply_query_tree;
1482    Ecore_X_Window window = 0;
1483    Ecore_X_Window child = 0;
1484    int16_t win_x;
1485    int16_t win_y;
1486    uint16_t win_width;
1487    uint16_t win_height;
1488    xcb_window_t *wins = NULL;
1489    int tree_c_len;
1490    int i;
1491
1492    cookie_get_window_attributes = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, base);
1493    cookie_get_geometry = xcb_get_geometry_unchecked(_ecore_xcb_conn, base);
1494    cookie_query_tree = xcb_query_tree_unchecked(_ecore_xcb_conn, base);
1495
1496    reply_get_window_attributes = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie_get_window_attributes, NULL);
1497    if (!reply_get_window_attributes)
1498      {
1499         reply_get_geometry = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_get_geometry, NULL);
1500         if (reply_get_geometry)
1501            free(reply_get_geometry);
1502
1503         reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL);
1504         if (reply_query_tree)
1505            free(reply_query_tree);
1506
1507         return window;
1508      }
1509
1510    if (reply_get_window_attributes->map_state != XCB_MAP_STATE_VIEWABLE)
1511      {
1512         free(reply_get_window_attributes);
1513         reply_get_geometry = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_get_geometry, NULL);
1514         if (reply_get_geometry)
1515            free(reply_get_geometry);
1516
1517         reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL);
1518         if (reply_query_tree)
1519            free(reply_query_tree);
1520
1521         return window;
1522      }
1523
1524    free(reply_get_window_attributes);
1525
1526    reply_get_geometry = xcb_get_geometry_reply(_ecore_xcb_conn, cookie_get_geometry, NULL);
1527    if (!reply_get_geometry)
1528      {
1529         reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL);
1530         if (reply_query_tree)
1531            free(reply_query_tree);
1532
1533         return window;
1534      }
1535
1536    win_x = reply_get_geometry->x;
1537    win_y = reply_get_geometry->y;
1538    win_width = reply_get_geometry->width;
1539    win_height = reply_get_geometry->height;
1540
1541    free(reply_get_geometry);
1542
1543    win_x += base_x;
1544    win_y += base_y;
1545
1546    if (!((x >= win_x) &&
1547          (y >= win_y) &&
1548          (x < (int16_t)(win_x + win_width)) &&
1549          (y < (int16_t)(win_y + win_height))))
1550      {
1551         reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL);
1552         if (reply_query_tree)
1553            free(reply_query_tree);
1554
1555         return window;
1556      }
1557
1558    reply_query_tree = xcb_query_tree_reply(_ecore_xcb_conn, cookie_query_tree, NULL);
1559    if (!reply_query_tree)
1560      {
1561         if (skip)
1562           {
1563              int i;
1564
1565              for (i = 0; i < skip_num; i++)
1566                 if (base == skip[i])
1567                    return window;
1568
1569           }
1570
1571         return base;
1572      }
1573
1574    wins = xcb_query_tree_children(reply_query_tree);
1575    tree_c_len = xcb_query_tree_children_length(reply_query_tree);
1576    for(i = 0; i < tree_c_len; i++)
1577      {
1578         if (skip)
1579           {
1580              int j;
1581
1582              for (j = 0; j < skip_num; j++)
1583                 if (wins[i] == skip[j])
1584                    continue;
1585
1586           }
1587
1588         child = _ecore_x_window_at_xy_get(wins[i], win_x, win_y, x, y, skip, skip_num);
1589         if (child)
1590           {
1591              free(reply_query_tree);
1592
1593              return child;
1594           }
1595      }
1596
1597    if (skip)
1598      {
1599         int i;
1600
1601         for (i = 0; i < skip_num; i++)
1602            if (base == skip[i])
1603              {
1604                 /* We return 0. child has an xid equal to 0 */
1605                 free(reply_query_tree);
1606                 return child;
1607              }
1608
1609      }
1610
1611    free(reply_query_tree);
1612
1613    return base;
1614 } /* _ecore_x_window_at_xy_get */
1615
1616 /**
1617  * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
1618  *
1619  * Functions that change or retrieve the geometry of X windows.
1620  */
1621
1622 /**
1623  * Retrieves the top, visible window at the given location.
1624  * @param   x The given X position.
1625  * @param   y The given Y position.
1626  * @return    The window at that position.
1627  * @ingroup Ecore_X_Window_Geometry_Group
1628  */
1629 EAPI Ecore_X_Window
1630 ecore_x_window_at_xy_get(int x,
1631                          int y)
1632 {
1633    Ecore_X_Window window;
1634    Ecore_X_Window root;
1635
1636    /* FIXME: Proper function to determine current root/virtual root
1637     * window missing here */
1638    root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1639
1640    ecore_x_grab();
1641    window = _ecore_x_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
1642    ecore_x_ungrab();
1643
1644    return window ? window : root;
1645 } /* ecore_x_window_at_xy_get */
1646
1647 /**
1648  * Retrieves the top, visible window at the given location,
1649  * but skips the windows in the list.
1650  * @param   x The given X position.
1651  * @param   y The given Y position.
1652  * @return    The window at that position.
1653  * @ingroup Ecore_X_Window_Geometry_Group
1654  */
1655 EAPI Ecore_X_Window
1656 ecore_x_window_at_xy_with_skip_get(int             x,
1657                                    int             y,
1658                                    Ecore_X_Window *skip,
1659                                    int             skip_num)
1660 {
1661    Ecore_X_Window window;
1662    Ecore_X_Window root;
1663
1664    /* FIXME: Proper function to determine current root/virtual root
1665     * window missing here */
1666    root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1667
1668    ecore_x_grab();
1669    window = _ecore_x_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
1670    ecore_x_ungrab();
1671
1672    return window ? window : root;
1673 } /* ecore_x_window_at_xy_with_skip_get */
1674
1675 /**
1676  * Retrieves the top, visible window at the given location,
1677  * but begins at the @p begin window instead of the root one.
1678  * @param   begin The window from which we begin.
1679  * @param   x     The given X position.
1680  * @param   y     The given Y position.
1681  * @return        The window at that position.
1682  * @ingroup Ecore_X_Window_Geometry_Group
1683  */
1684 EAPI Ecore_X_Window
1685 ecore_x_window_at_xy_begin_get(Ecore_X_Window begin,
1686                                int            x,
1687                                int            y)
1688 {
1689    Ecore_X_Window window;
1690
1691    ecore_x_grab();
1692    window = _ecore_x_window_at_xy_get(begin, 0, 0, x, y, NULL, 0);
1693    ecore_x_ungrab();
1694
1695    return window ? window : begin;
1696 } /* ecore_x_window_at_xy_begin_get */
1697
1698 /* FIXME: Should I provide the replies (or the cookies), instead of
1699           creating them in the function ? */
1700 #ifdef ECORE_XCB_RENDER
1701 static Ecore_X_Window
1702 _ecore_x_window_argb_internal_new(Ecore_X_Window parent,
1703                                   int16_t        x,
1704                                   int16_t        y,
1705                                   uint16_t       w,
1706                                   uint16_t       h,
1707                                   uint8_t        override_redirect,
1708                                   uint8_t        save_under)
1709 {
1710    uint32_t value_list[10];
1711    xcb_depth_iterator_t iter_depth;
1712    xcb_visualtype_iterator_t iter_visualtype;
1713    xcb_render_query_pict_formats_cookie_t cookie_pict_format;
1714    xcb_render_query_pict_formats_reply_t *rep_pict_format;
1715    Ecore_X_Screen *screen = NULL;
1716    Ecore_X_Window win = { 0 };
1717    xcb_visualid_t vis = { 0 };
1718    Ecore_X_Colormap colormap;
1719    uint32_t value_mask;
1720
1721    cookie_pict_format = xcb_render_query_pict_formats_unchecked(_ecore_xcb_conn);
1722
1723    if (parent == 0)
1724      {
1725         parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1726         screen = ((xcb_screen_t *)_ecore_xcb_screen);
1727      }
1728    else
1729      {
1730         xcb_screen_iterator_t iter_screen;
1731         xcb_get_geometry_reply_t *rep;
1732         Ecore_X_Drawable draw;
1733         Ecore_X_Window root;
1734
1735         draw = parent;
1736         rep = xcb_get_geometry_reply(_ecore_xcb_conn,
1737                                      xcb_get_geometry_unchecked(_ecore_xcb_conn,
1738                                                                 draw),
1739                                      NULL);
1740         if (!rep)
1741            return win;
1742
1743         root = rep->root;
1744
1745         free(rep);
1746
1747         for (; iter_screen.rem; xcb_screen_next(&iter_screen))
1748           {
1749              if (iter_screen.data->root == root)
1750                {
1751                   screen = iter_screen.data;
1752                }
1753           }
1754      }
1755
1756    if (!screen)
1757       return win;
1758
1759    /* we get the X visual types */
1760    iter_depth = xcb_screen_allowed_depths_iterator(screen);
1761    for (; iter_depth.rem; xcb_depth_next(&iter_depth)) {
1762         if (iter_depth.data->depth == 32)
1763           {
1764              iter_visualtype = xcb_depth_visuals_iterator(iter_depth.data);
1765              break;
1766           }
1767      }
1768
1769    /* we get the X render visual id */
1770    rep_pict_format = xcb_render_query_pict_formats_reply(_ecore_xcb_conn,
1771                                                          cookie_pict_format,
1772                                                          NULL);
1773    if (!rep_pict_format)
1774       return win;
1775
1776    for (; iter_visualtype.rem; xcb_visualtype_next(&iter_visualtype)) {
1777         if (iter_visualtype.data->_class == XCB_VISUAL_CLASS_TRUE_COLOR)
1778           {
1779              xcb_render_pictforminfo_iterator_t iter_forminfo;
1780              xcb_render_pictscreen_iterator_t iter_pictscreen;
1781              xcb_render_pictformat_t pict_format = { 0 };
1782
1783              iter_forminfo = xcb_render_query_pict_formats_formats_iterator(rep_pict_format);
1784              for (; iter_forminfo.rem; xcb_render_pictforminfo_next(&iter_forminfo)) {
1785                   if (iter_forminfo.data->type == XCB_RENDER_PICT_TYPE_DIRECT &&
1786                       iter_forminfo.data->direct.alpha_mask && iter_forminfo.data->depth == 32)
1787                     {
1788                        pict_format = iter_forminfo.data->id;
1789                        break;
1790                     }
1791                }
1792              if (pict_format == 0)
1793                {
1794                   free(rep_pict_format);
1795                   return win;
1796                }
1797
1798              iter_pictscreen = xcb_render_query_pict_formats_screens_iterator(rep_pict_format);
1799              for (; iter_pictscreen.rem; xcb_render_pictscreen_next(&iter_pictscreen)) {
1800                   xcb_render_pictdepth_iterator_t iter_depth;
1801
1802                   iter_depth = xcb_render_pictscreen_depths_iterator(iter_pictscreen.data);
1803                   for (; iter_depth.rem; xcb_render_pictdepth_next(&iter_depth)) {
1804                        xcb_render_pictvisual_iterator_t iter_visual;
1805
1806                        iter_visual = xcb_render_pictdepth_visuals_iterator(iter_depth.data);
1807                        for (; iter_visual.rem; xcb_render_pictvisual_next(&iter_visual)) {
1808                             if ((iter_visual.data->visual == iter_visualtype.data->visual_id) &&
1809                                 (pict_format == iter_visual.data->format))
1810                               {
1811                                  vis = iter_visual.data->visual;
1812                                  break;
1813                               }
1814                          }
1815                     }
1816                }
1817           }
1818      }
1819
1820    free(rep_pict_format);
1821
1822    if (vis == 0)
1823       return win;
1824
1825    colormap = xcb_generate_id(_ecore_xcb_conn);
1826    xcb_create_colormap(_ecore_xcb_conn, XCB_COLORMAP_ALLOC_NONE, colormap, parent, vis);
1827
1828    value_mask =
1829       XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
1830       XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | XCB_CW_OVERRIDE_REDIRECT |
1831       XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE |
1832       XCB_CW_COLORMAP;
1833
1834    value_list[0] = XCB_NONE;
1835    value_list[1] = 0;
1836    value_list[2] = XCB_GRAVITY_NORTH_WEST;
1837    value_list[3] = XCB_GRAVITY_NORTH_WEST;
1838    value_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
1839    value_list[5] = override_redirect;
1840    value_list[6] = save_under;
1841    value_list[7] =
1842       XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
1843       XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE |
1844       XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
1845       XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
1846       XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1847       XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_PROPERTY_CHANGE |
1848       XCB_EVENT_MASK_COLOR_MAP_CHANGE;
1849    value_list[8] = XCB_EVENT_MASK_NO_EVENT;
1850    value_list[9] = colormap;
1851
1852    win = xcb_generate_id(_ecore_xcb_conn);
1853    xcb_create_window(_ecore_xcb_conn,
1854                      32, /* depth */
1855                      win, parent,
1856                      x, y, w, h, 0,
1857                      XCB_WINDOW_CLASS_INPUT_OUTPUT,
1858                      vis,
1859                      value_mask,
1860                      value_list);
1861
1862    xcb_free_colormap(_ecore_xcb_conn, colormap);
1863
1864    if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
1865       ecore_x_window_defaults_set(win);
1866
1867    return win;
1868 } /* _ecore_x_window_argb_internal_new */
1869
1870 #endif /* ECORE_XCB_RENDER */
1871
1872 /* FIXME: round trip */
1873 EAPI int
1874 ecore_x_window_argb_get(Ecore_X_Window win)
1875 {
1876    uint8_t ret = 0;
1877 #ifdef ECORE_XCB_RENDER
1878    xcb_render_pictforminfo_iterator_t iter_forminfo;
1879    xcb_render_pictscreen_iterator_t iter_pictscreen;
1880    xcb_render_pictformat_t pict_format = { 0 };
1881    xcb_render_query_pict_formats_reply_t *rep_pictformat;
1882    xcb_get_window_attributes_reply_t *rep;
1883    xcb_visualid_t visual;
1884
1885    rep = xcb_get_window_attributes_reply(_ecore_xcb_conn,
1886                                          xcb_get_window_attributes_unchecked(_ecore_xcb_conn,
1887                                                                              win),
1888                                          NULL);
1889    if (!rep)
1890       return ret;
1891
1892    visual = rep->visual;
1893
1894    free(rep);
1895
1896    rep_pictformat = xcb_render_query_pict_formats_reply(_ecore_xcb_conn,
1897                                                         xcb_render_query_pict_formats_unchecked(_ecore_xcb_conn),
1898                                                         NULL);
1899    if (!rep_pictformat)
1900       return ret;
1901
1902    iter_forminfo = xcb_render_query_pict_formats_formats_iterator(rep_pictformat);
1903    for (; iter_forminfo.rem; xcb_render_pictforminfo_next(&iter_forminfo))
1904      {
1905         if ((iter_forminfo.data->type == XCB_RENDER_PICT_TYPE_DIRECT) &&
1906             (iter_forminfo.data->direct.alpha_mask))
1907           {
1908              pict_format = iter_forminfo.data->id;
1909              break;
1910           }
1911      }
1912    if (pict_format == 0)
1913      {
1914         free(rep_pictformat);
1915
1916         return ret;
1917      }
1918
1919    iter_pictscreen = xcb_render_query_pict_formats_screens_iterator(rep_pictformat);
1920    for (; iter_pictscreen.rem; xcb_render_pictscreen_next(&iter_pictscreen))
1921      {
1922         xcb_render_pictdepth_iterator_t iter_depth;
1923
1924         iter_depth = xcb_render_pictscreen_depths_iterator(iter_pictscreen.data);
1925         for (; iter_depth.rem; xcb_render_pictdepth_next(&iter_depth))
1926           {
1927              xcb_render_pictvisual_iterator_t iter_visual;
1928
1929              iter_visual = xcb_render_pictdepth_visuals_iterator(iter_depth.data);
1930              for (; iter_visual.rem; xcb_render_pictvisual_next(&iter_visual))
1931                {
1932                   if ((iter_visual.data->visual == visual) &&
1933                       (pict_format == iter_visual.data->format))
1934                     {
1935                        ret = 1;
1936                        break;
1937                     }
1938                }
1939           }
1940      }
1941
1942    free(rep_pictformat);
1943 #endif /* ECORE_XCB_RENDER */
1944
1945    return ret;
1946 } /* ecore_x_window_argb_get */
1947
1948 /**
1949  * Set if a window should be ignored.
1950  * @param   window The given window.
1951  * @param   ignore if to ignore
1952  */
1953 EAPI void
1954 ecore_x_window_ignore_set(Ecore_X_Window window,
1955                           int            ignore)
1956 {
1957    int i, j;
1958
1959    if (ignore)
1960      {
1961         if (ignore_list)
1962           {
1963              for (i = 0; i < ignore_num; i++)
1964                {
1965                   if (window == ignore_list[i])
1966                      return;
1967                }
1968              ignore_list = realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
1969              if (!ignore_list)
1970                 return;
1971
1972              ignore_list[ignore_num++] = window;
1973           }
1974         else
1975           {
1976              ignore_num = 0;
1977              ignore_list = malloc(sizeof(Ecore_X_Window));
1978              ignore_list[ignore_num++] = window;
1979           }
1980      }
1981    else
1982      {
1983         if (!ignore_list)
1984            return;
1985
1986         for (i = 0, j = 0; i < ignore_num; i++)
1987           {
1988              if (window != ignore_list[i])
1989                 ignore_list[i] = ignore_list[j++];
1990              else
1991                 ignore_num--;
1992           }
1993         ignore_list = realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
1994      }
1995 } /* ecore_x_window_ignore_set */
1996
1997 /**
1998  * Get the ignore list
1999  * @param   num number of windows in the list
2000  * @return  list of windows to ignore
2001  */
2002 EAPI Ecore_X_Window *
2003 ecore_x_window_ignore_list(int *num)
2004 {
2005    if (num)
2006       *num = ignore_num;
2007
2008    return ignore_list;
2009 } /* ecore_x_window_ignore_list */
2010
2011 /**
2012  * Retrieves the size of the given window.
2013  * @param   win The given window.
2014  * @param   w   Pointer to an integer into which the width is to be stored.
2015  * @param   h   Pointer to an integer into which the height is to be stored.
2016  *
2017  * To use this function, you must call before, and in order,
2018  * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request,
2019  * then ecore_x_drawable_geometry_get_fetch(), which gets the reply.
2020  * @ingroup Ecore_X_Window_Geometry_Group
2021  */
2022 EAPI void
2023 ecore_x_window_size_get(Ecore_X_Window window,
2024                         int           *width,
2025                         int           *height)
2026 {
2027    if (window == 0)
2028       window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
2029
2030    ecore_x_drawable_geometry_get(window, NULL, NULL, width, height);
2031 } /* ecore_x_window_size_get */
2032
2033 /**
2034  * Retrieves the geometry of the given window.
2035  * @param   win The given window.
2036  * @param   x   Pointer to an integer in which the X position is to be stored.
2037  * @param   y   Pointer to an integer in which the Y position is to be stored.
2038  * @param   w   Pointer to an integer in which the width is to be stored.
2039  * @param   h   Pointer to an integer in which the height is to be stored.
2040  *
2041  * To use this function, you must call before, and in order,
2042  * ecore_x_drawable_geometry_get_prefetch(), which sends the GetGeometry request,
2043  * then ecore_x_drawable_geometry_get_fetch(), which gets the reply.
2044  * @ingroup Ecore_X_Window_Geometry_Group
2045  */
2046 EAPI void
2047 ecore_x_window_geometry_get(Ecore_X_Window window,
2048                             int           *x,
2049                             int           *y,
2050                             int           *width,
2051                             int           *height)
2052 {
2053    if (!window)
2054       window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
2055
2056    ecore_x_drawable_geometry_get(window, x, y, width, height);
2057 } /* ecore_x_window_geometry_get */
2058
2059 /**
2060  * Retrieves the width of the border of the given window.
2061  * @param   win The given window.
2062  * @return  Width of the border of @p win.
2063  * @ingroup Ecore_X_Window_Geometry_Group
2064  */
2065 EAPI int
2066 ecore_x_window_border_width_get(Ecore_X_Window win)
2067 {
2068    /* doesn't make sense to call this on a root window */
2069    if (!win)
2070       return 0;
2071
2072    return ecore_x_drawable_border_width_get(win);
2073 } /* ecore_x_window_border_width_get */
2074
2075 /**
2076  * Retrieves the depth of the given window.
2077  * @param  win The given window.
2078  * @return Depth of the window.
2079  */
2080 EAPI int
2081 ecore_x_window_depth_get(Ecore_X_Window win)
2082 {
2083    return ecore_x_drawable_depth_get(win);
2084 } /* ecore_x_window_depth_get */
2085