Initialize Tizen 2.3
[framework/uifw/ecore.git] / wearable / src / lib / ecore_x / xcb / ecore_xcb_window.c
1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #ifdef STDC_HEADERS
6 # include <stdlib.h>
7 # include <stddef.h>
8 #else
9 # ifdef HAVE_STDLIB_H
10 #  include <stdlib.h>
11 # endif
12 #endif
13 #ifdef HAVE_ALLOCA_H
14 # include <alloca.h>
15 #elif !defined alloca
16 # ifdef __GNUC__
17 #  define alloca __builtin_alloca
18 # elif defined _AIX
19 #  define alloca __alloca
20 # elif defined _MSC_VER
21 #  include <malloc.h>
22 #  define alloca _alloca
23 # elif !defined HAVE_ALLOCA
24 #  ifdef  __cplusplus
25 extern "C"
26 #  endif
27 void *alloca (size_t);
28 # endif
29 #endif
30
31 #include "ecore_xcb_private.h"
32 #ifdef ECORE_XCB_RENDER
33 # include <xcb/render.h>
34 #endif
35 #ifdef ECORE_XCB_SHAPE
36 # include <xcb/shape.h>
37 #endif
38 #ifdef ECORE_XCB_XPRINT
39 #include <xcb/xprint.h>
40 #endif
41
42 /* local function prototypes */
43 static Ecore_X_Window _ecore_xcb_window_argb_internal_new(Ecore_X_Window parent,
44                                                           int            x,
45                                                           int            y,
46                                                           int            w,
47                                                           int            h,
48                                                           uint8_t        override_redirect,
49                                                           uint8_t        save_under);
50 static Ecore_X_Window _ecore_xcb_window_at_xy_get(Ecore_X_Window  base,
51                                                   int             bx,
52                                                   int             by,
53                                                   int             x,
54                                                   int             y,
55                                                   Ecore_X_Window *skip,
56                                                   int             skip_num);
57 static int               _ecore_xcb_window_modifiers_get(unsigned int state);
58 static xcb_visualtype_t *_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id);
59 #ifdef ECORE_XCB_XPRINT
60 static xcb_screen_t     *_ecore_xcb_window_screen_of_display(int screen);
61 #endif
62
63 /* local variables */
64 static int ignore_num = 0;
65 static Ecore_X_Window *ignore_list = NULL;
66
67 /* external variables */
68 int _ecore_xcb_button_grabs_num = 0;
69 int _ecore_xcb_key_grabs_num = 0;
70 Ecore_X_Window *_ecore_xcb_button_grabs = NULL;
71 Ecore_X_Window *_ecore_xcb_key_grabs = NULL;
72 Eina_Bool (*_ecore_xcb_window_grab_replay_func)(void *data,
73                                                 int   type,
74                                                 void *event);
75 void *_ecore_xcb_window_grab_replay_data;
76
77 /**
78  * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
79  *
80  * Functions that can be used to create an X window.
81  */
82
83 /**
84  * Creates a new window.
85  * @param   parent The parent window to use.  If @p parent is @c 0, the root
86  *                 window of the default display is used.
87  * @param   x      X position.
88  * @param   y      Y position.
89  * @param   w      Width.
90  * @param   h      Height.
91  * @return  The new window handle.
92  * @ingroup Ecore_X_Window_Create_Group
93  */
94 EAPI Ecore_X_Window
95 ecore_x_window_new(Ecore_X_Window parent,
96                    int            x,
97                    int            y,
98                    int            w,
99                    int            h)
100 {
101    Ecore_X_Window win;
102    uint32_t mask, mask_list[9];
103
104    LOGFN(__FILE__, __LINE__, __FUNCTION__);
105    CHECK_XCB_CONN;
106
107    if (parent == 0)
108      parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
109
110    /* NB: Order here is very important due to xcb_cw_t enum */
111    mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
112            XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
113            XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK |
114            XCB_CW_DONT_PROPAGATE);
115
116    mask_list[0] = XCB_BACK_PIXMAP_NONE;
117    mask_list[1] = 0;
118    mask_list[2] = XCB_GRAVITY_NORTH_WEST;
119    mask_list[3] = XCB_GRAVITY_NORTH_WEST;
120    mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
121    mask_list[5] = 0;
122    mask_list[6] = 0;
123    mask_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
124                    XCB_EVENT_MASK_BUTTON_PRESS |
125                    XCB_EVENT_MASK_BUTTON_RELEASE |
126                    XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
127                    XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
128                    XCB_EVENT_MASK_VISIBILITY_CHANGE |
129                    XCB_EVENT_MASK_STRUCTURE_NOTIFY |
130                    XCB_EVENT_MASK_FOCUS_CHANGE |
131                    XCB_EVENT_MASK_PROPERTY_CHANGE |
132                    XCB_EVENT_MASK_COLOR_MAP_CHANGE);
133    mask_list[8] = XCB_EVENT_MASK_NO_EVENT;
134
135    win = xcb_generate_id(_ecore_xcb_conn);
136    xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
137                      win, parent, x, y, w, h, 0,
138                      XCB_WINDOW_CLASS_INPUT_OUTPUT,
139                      XCB_COPY_FROM_PARENT, mask, mask_list);
140
141    if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
142      ecore_x_window_defaults_set(win);
143
144    return win;
145 }
146
147 /**
148  * Creates a window with the override redirect attribute set to @c True.
149  * @param   parent The parent window to use.  If @p parent is @c 0, the root
150  *                 window of the default display is used.
151  * @param   x      X position.
152  * @param   y      Y position.
153  * @param   w      Width.
154  * @param   h      Height.
155  * @return  The new window handle.
156  * @ingroup Ecore_X_Window_Create_Group
157  */
158 EAPI Ecore_X_Window
159 ecore_x_window_override_new(Ecore_X_Window parent,
160                             int            x,
161                             int            y,
162                             int            w,
163                             int            h)
164 {
165    Ecore_X_Window win;
166    uint32_t mask, mask_list[9];
167
168    LOGFN(__FILE__, __LINE__, __FUNCTION__);
169    CHECK_XCB_CONN;
170
171    if (parent == 0)
172      parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
173
174    /* NB: Order here is very important due to xcb_cw_t enum */
175    mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
176            XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
177            XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK |
178            XCB_CW_DONT_PROPAGATE);
179
180    mask_list[0] = XCB_BACK_PIXMAP_NONE;
181    mask_list[1] = 0;
182    mask_list[2] = XCB_GRAVITY_NORTH_WEST;
183    mask_list[3] = XCB_GRAVITY_NORTH_WEST;
184    mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
185    mask_list[5] = 1;
186    mask_list[6] = 0;
187    mask_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
188                    XCB_EVENT_MASK_BUTTON_PRESS |
189                    XCB_EVENT_MASK_BUTTON_RELEASE |
190                    XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
191                    XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
192                    XCB_EVENT_MASK_VISIBILITY_CHANGE |
193                    XCB_EVENT_MASK_STRUCTURE_NOTIFY |
194                    XCB_EVENT_MASK_FOCUS_CHANGE |
195                    XCB_EVENT_MASK_PROPERTY_CHANGE |
196                    XCB_EVENT_MASK_COLOR_MAP_CHANGE);
197    mask_list[8] = XCB_EVENT_MASK_NO_EVENT;
198
199    win = xcb_generate_id(_ecore_xcb_conn);
200    xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
201                      win, parent, x, y, w, h, 0,
202                      XCB_WINDOW_CLASS_INPUT_OUTPUT,
203                      XCB_COPY_FROM_PARENT, mask, mask_list);
204
205    return win;
206 }
207
208 /**
209  * Creates a new input window.
210  * @param   parent The parent window to use.    If @p parent is @c 0, the root
211  *                 window of the default display is used.
212  * @param   x      X position.
213  * @param   y      Y position.
214  * @param   w      Width.
215  * @param   h      Height.
216  * @return  The new window.
217  * @ingroup Ecore_X_Window_Create_Group
218  */
219 EAPI Ecore_X_Window
220 ecore_x_window_input_new(Ecore_X_Window parent,
221                          int            x,
222                          int            y,
223                          int            w,
224                          int            h)
225 {
226    Ecore_X_Window win;
227    uint32_t mask, mask_list[3];
228
229    LOGFN(__FILE__, __LINE__, __FUNCTION__)
230    CHECK_XCB_CONN;
231
232    if (parent == 0)
233      parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
234
235    /* NB: Order here is very important due to xcb_cw_t enum */
236    mask = (XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK |
237            XCB_CW_DONT_PROPAGATE);
238
239    mask_list[0] = 1;
240    mask_list[1] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
241                    XCB_EVENT_MASK_BUTTON_PRESS |
242                    XCB_EVENT_MASK_BUTTON_RELEASE |
243                    XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
244                    XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
245                    XCB_EVENT_MASK_VISIBILITY_CHANGE |
246                    XCB_EVENT_MASK_STRUCTURE_NOTIFY |
247                    XCB_EVENT_MASK_FOCUS_CHANGE |
248                    XCB_EVENT_MASK_PROPERTY_CHANGE |
249                    XCB_EVENT_MASK_COLOR_MAP_CHANGE);
250    mask_list[2] = XCB_EVENT_MASK_NO_EVENT;
251
252    win = xcb_generate_id(_ecore_xcb_conn);
253    xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
254                      win, parent, x, y, w, h, 0,
255                      XCB_WINDOW_CLASS_INPUT_ONLY,
256                      XCB_COPY_FROM_PARENT, mask, mask_list);
257
258    return win;
259 }
260
261 /**
262  * Creates a new window.
263  * @param   parent The parent window to use.  If @p parent is @c 0, the root
264  *                 window of the default display is used.
265  * @param   x      X position.
266  * @param   y      Y position.
267  * @param   w      Width.
268  * @param   h      Height.
269  * @return  The new window handle.
270  * @ingroup Ecore_X_Window_Create_Group
271  */
272 EAPI Ecore_X_Window
273 ecore_x_window_manager_argb_new(Ecore_X_Window parent,
274                                 int            x,
275                                 int            y,
276                                 int            w,
277                                 int            h)
278 {
279    Ecore_X_Window win = 0;
280
281    LOGFN(__FILE__, __LINE__, __FUNCTION__);
282
283    win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0);
284
285    return win;
286 }
287
288 /**
289  * Creates a new window.
290  * @param   parent The parent window to use.  If @p parent is @c 0, the root
291  *                 window of the default display is used.
292  * @param   x      X position.
293  * @param   y      Y position.
294  * @param   w      Width.
295  * @param   h      Height.
296  * @return  The new window handle.
297  * @ingroup Ecore_X_Window_Create_Group
298  */
299 EAPI Ecore_X_Window
300 ecore_x_window_argb_new(Ecore_X_Window parent,
301                         int            x,
302                         int            y,
303                         int            w,
304                         int            h)
305 {
306    Ecore_X_Window win = 0;
307
308    LOGFN(__FILE__, __LINE__, __FUNCTION__);
309
310    win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 0, 0);
311
312    return win;
313 }
314
315 /**
316  * Creates a window with the override redirect attribute set to @c True.
317  * @param   parent The parent window to use.  If @p parent is @c 0, the root
318  *                 window of the default display is used.
319  * @param   x      X position.
320  * @param   y      Y position.
321  * @param   w      Width.
322  * @param   h      Height.
323  * @return  The new window handle.
324  * @ingroup Ecore_X_Window_Create_Group
325  */
326 EAPI Ecore_X_Window
327 ecore_x_window_override_argb_new(Ecore_X_Window parent,
328                                  int            x,
329                                  int            y,
330                                  int            w,
331                                  int            h)
332 {
333    Ecore_X_Window win = 0;
334
335    LOGFN(__FILE__, __LINE__, __FUNCTION__);
336
337    win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0);
338
339    return win;
340 }
341
342 /**
343  * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions
344  *
345  * Functions to destroy X windows.
346  */
347
348 /**
349  * Deletes the given window.
350  * @param   win The given window.
351  * @ingroup Ecore_X_Window_Destroy_Group
352  */
353 EAPI void
354 ecore_x_window_free(Ecore_X_Window win)
355 {
356    LOGFN(__FILE__, __LINE__, __FUNCTION__);
357    CHECK_XCB_CONN;
358
359    if (win)
360      {
361         /* xcb_destroy_notify_event_t ev; */
362         /* Ecore_X_Window root; */
363
364           /* if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1) */
365           /*   root = ((xcb_screen_t *)_ecore_xcb_screen)->root; */
366           /* else  */
367           /*   { */
368           /*      xcb_get_geometry_cookie_t cookie; */
369           /*      xcb_get_geometry_reply_t *reply; */
370
371      /*      cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); */
372                  /*      reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); */
373      /*      if (!reply) return; */
374                    /*      root = reply->root; */
375      /*      free(reply); */
376                      /*   } */
377
378      /* memset(&ev, 0, sizeof(xcb_destroy_notify_event_t)); */
379
380                        /* ev.response_type = XCB_DESTROY_NOTIFY; */
381      /* ev.window = win; */
382                          /* ev.event = root; */
383
384      /* xcb_send_event(_ecore_xcb_conn, 0, root,  */
385                            /*                XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |  */
386      /*                XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,  */
387                              /*                (const char *)&ev); */
388
389         xcb_destroy_window(_ecore_xcb_conn, win);
390 //        ecore_x_flush();
391      }
392 }
393
394 /**
395  * Sends a delete request to the given window.
396  * @param   win The given window.
397  * @ingroup Ecore_X_Window_Destroy_Group
398  */
399 EAPI void
400 ecore_x_window_delete_request_send(Ecore_X_Window win)
401 {
402    LOGFN(__FILE__, __LINE__, __FUNCTION__);
403
404    if (!win) return;
405    ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
406                                  XCB_EVENT_MASK_NO_EVENT,
407                                  ECORE_X_ATOM_WM_DELETE_WINDOW,
408                                  XCB_CURRENT_TIME, 0, 0, 0);
409 }
410
411 EAPI void
412 ecore_x_window_configure(Ecore_X_Window                win,
413                          Ecore_X_Window_Configure_Mask mask,
414                          int                           x,
415                          int                           y,
416                          int                           w,
417                          int                           h,
418                          int                           border_width,
419                          Ecore_X_Window                sibling,
420                          int                           stack_mode)
421 {
422    uint16_t vmask = 0;
423    uint32_t vlist[7];
424    unsigned int i = 0;
425
426    LOGFN(__FILE__, __LINE__, __FUNCTION__);
427    CHECK_XCB_CONN;
428
429    if (!win) return;
430
431    if (mask & XCB_CONFIG_WINDOW_X)
432      {
433         vmask |= XCB_CONFIG_WINDOW_X;
434         vlist[i++] = x;
435      }
436    if (mask & XCB_CONFIG_WINDOW_Y)
437      {
438         vmask |= XCB_CONFIG_WINDOW_Y;
439         vlist[i++] = y;
440      }
441    if (mask & XCB_CONFIG_WINDOW_WIDTH)
442      {
443         vmask |= XCB_CONFIG_WINDOW_WIDTH;
444         vlist[i++] = w;
445      }
446    if (mask & XCB_CONFIG_WINDOW_HEIGHT)
447      {
448         vmask |= XCB_CONFIG_WINDOW_HEIGHT;
449         vlist[i++] = h;
450      }
451    if (mask & XCB_CONFIG_WINDOW_BORDER_WIDTH)
452      {
453         vmask |= XCB_CONFIG_WINDOW_BORDER_WIDTH;
454         vlist[i++] = border_width;
455      }
456    if (mask & XCB_CONFIG_WINDOW_SIBLING)
457      {
458         vmask |= XCB_CONFIG_WINDOW_SIBLING;
459         vlist[i++] = sibling;
460      }
461    if (mask & XCB_CONFIG_WINDOW_STACK_MODE)
462      {
463         vmask |= XCB_CONFIG_WINDOW_STACK_MODE;
464         vlist[i++] = stack_mode;
465      }
466
467    xcb_configure_window(_ecore_xcb_conn, win, vmask,
468                         (const uint32_t *)&vlist);
469 //   ecore_x_flush();
470 }
471
472 /**
473  * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
474  *
475  * Functions that change or retrieve the geometry of X windows.
476  */
477
478 /**
479  * Moves a window to the position @p x, @p y.
480  *
481  * The position is relative to the upper left hand corner of the
482  * parent window.
483  *
484  * @param   win The window to move.
485  * @param   x   X position.
486  * @param   y   Y position.
487  * @ingroup Ecore_X_Window_Geometry_Group
488  */
489 EAPI void
490 ecore_x_window_move(Ecore_X_Window win,
491                     int            x,
492                     int            y)
493 {
494    uint32_t list[2], mask;
495
496    LOGFN(__FILE__, __LINE__, __FUNCTION__);
497    CHECK_XCB_CONN;
498
499    if (!win) return;
500
501    mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y);
502    list[0] = x;
503    list[1] = y;
504
505    xcb_configure_window(_ecore_xcb_conn, win, mask,
506                         (const uint32_t *)&list);
507 //   ecore_x_flush();
508 }
509
510 /**
511  * Resizes a window.
512  * @param   win The window to resize.
513  * @param   w   New width of the window.
514  * @param   h   New height of the window.
515  * @ingroup Ecore_X_Window_Geometry_Group
516  */
517 EAPI void
518 ecore_x_window_resize(Ecore_X_Window win,
519                       int            w,
520                       int            h)
521 {
522    uint32_t list[2], mask;
523
524    LOGFN(__FILE__, __LINE__, __FUNCTION__);
525    CHECK_XCB_CONN;
526
527    if (!win) return;
528    if (w < 1) w = 1;
529    if (h < 1) h = 1;
530
531    mask = (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
532    list[0] = w;
533    list[1] = h;
534
535    xcb_configure_window(_ecore_xcb_conn, win, mask,
536                         (const uint32_t *)&list);
537 //   ecore_x_flush();
538 }
539
540 /**
541  * Moves and resizes a window.
542  * @param   win The window to move and resize.
543  * @param   x   New X position of the window.
544  * @param   y   New Y position of the window.
545  * @param   w   New width of the window.
546  * @param   h   New height of the window.
547  * @ingroup Ecore_X_Window_Geometry_Group
548  */
549 EAPI void
550 ecore_x_window_move_resize(Ecore_X_Window win,
551                            int            x,
552                            int            y,
553                            int            w,
554                            int            h)
555 {
556    uint32_t list[4], mask;
557
558    LOGFN(__FILE__, __LINE__, __FUNCTION__);
559    CHECK_XCB_CONN;
560
561    if (!win) return;
562    if (w < 1) w = 1;
563    if (h < 1) h = 1;
564
565    mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
566            XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
567    list[0] = x;
568    list[1] = y;
569    list[2] = w;
570    list[3] = h;
571
572    xcb_configure_window(_ecore_xcb_conn, win, mask,
573                         (const uint32_t *)&list);
574 //   ecore_x_flush();
575 }
576
577 /**
578  * Retrieves the width of the border of the given window.
579  * @param   win The given window.
580  * @return  Width of the border of @p win.
581  * @ingroup Ecore_X_Window_Geometry_Group
582  */
583 EAPI int
584 ecore_x_window_border_width_get(Ecore_X_Window win)
585 {
586    LOGFN(__FILE__, __LINE__, __FUNCTION__);
587
588    if (!win) return 0;
589    return ecore_x_drawable_border_width_get(win);
590 }
591
592 /**
593  * Sets the width of the border of the given window.
594  * @param   win The given window.
595  * @param   width The new border width.
596  * @ingroup Ecore_X_Window_Geometry_Group
597  */
598 EAPI void
599 ecore_x_window_border_width_set(Ecore_X_Window win,
600                                 int            border_width)
601 {
602    uint32_t list;
603
604    LOGFN(__FILE__, __LINE__, __FUNCTION__);
605    CHECK_XCB_CONN;
606
607    if (!win) return;
608
609    list = border_width;
610
611    xcb_configure_window(_ecore_xcb_conn, win,
612                         XCB_CONFIG_WINDOW_BORDER_WIDTH, &list);
613 //   ecore_x_flush();
614 }
615
616 /**
617  * @defgroup Ecore_X_Window_Z_Order_Group X Window Z Order Functions
618  *
619  * Functions that change the Z order of X windows.
620  */
621
622 /**
623  * Raises the given window.
624  * @param   win The window to raise.
625  * @ingroup Ecore_X_Window_Z_Order_Group
626  */
627 EAPI void
628 ecore_x_window_raise(Ecore_X_Window win)
629 {
630    uint32_t list[] = { XCB_STACK_MODE_ABOVE };
631
632    LOGFN(__FILE__, __LINE__, __FUNCTION__);
633    CHECK_XCB_CONN;
634
635    xcb_configure_window(_ecore_xcb_conn, win,
636                         XCB_CONFIG_WINDOW_STACK_MODE, list);
637 //   ecore_x_flush();
638 }
639
640 /**
641  * Lowers the given window.
642  * @param   win The window to lower.
643  * @ingroup Ecore_X_Window_Z_Order_Group
644  */
645 EAPI void
646 ecore_x_window_lower(Ecore_X_Window win)
647 {
648    uint32_t list[] = { XCB_STACK_MODE_BELOW };
649
650    LOGFN(__FILE__, __LINE__, __FUNCTION__);
651    CHECK_XCB_CONN;
652
653    xcb_configure_window(_ecore_xcb_conn, win,
654                         XCB_CONFIG_WINDOW_STACK_MODE, list);
655 //   ecore_x_flush();
656 }
657
658 /**
659  * Retrieves the depth of the given window.
660  * @param  win The given window.
661  * @return Depth of the window.
662  */
663 EAPI int
664 ecore_x_window_depth_get(Ecore_X_Window win)
665 {
666    LOGFN(__FILE__, __LINE__, __FUNCTION__);
667
668    return ecore_x_drawable_depth_get(win);
669 }
670
671 /**
672  * @defgroup Ecore_X_Window_Properties_Group X Window Property Functions
673  *
674  * Functions that set window properties.
675  */
676
677 /**
678  * Sets the default properties for the given window.
679  *
680  * The default properties set for the window are @c WM_CLIENT_MACHINE and
681  * @c _NET_WM_PID.
682  *
683  * @param   win The given window.
684  * @ingroup Ecore_X_Window_Properties_Group
685  */
686 EAPI void
687 ecore_x_window_defaults_set(Ecore_X_Window win)
688 {
689    char buff[MAXHOSTNAMELEN], **argv;
690    int argc;
691    pid_t pid;
692
693    LOGFN(__FILE__, __LINE__, __FUNCTION__);
694    CHECK_XCB_CONN;
695
696    gethostname(buff, MAXHOSTNAMELEN);
697    buff[MAXHOSTNAMELEN - 1] = '\0';
698
699    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
700                        ECORE_X_ATOM_WM_CLIENT_MACHINE, ECORE_X_ATOM_STRING,
701                        8, strlen(buff), buff);
702
703    pid = getpid();
704    ecore_x_netwm_pid_set(win, pid);
705    ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_NORMAL);
706    ecore_app_args_get(&argc, &argv);
707    ecore_x_icccm_command_set(win, argc, argv);
708 }
709
710 /**
711  * @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions
712  *
713  * Functions to access and change the visibility of X windows.
714  */
715
716 /**
717  * Shows a window.
718  *
719  * Synonymous to "mapping" a window in X Window System terminology.
720  *
721  * @param   win The window to show.
722  * @ingroup Ecore_X_Window_Visibility
723  */
724 EAPI void
725 ecore_x_window_show(Ecore_X_Window win)
726 {
727    LOGFN(__FILE__, __LINE__, __FUNCTION__);
728    CHECK_XCB_CONN;
729
730    if (win)
731      xcb_map_window(_ecore_xcb_conn, win);
732 }
733
734 /**
735  * Hides a window.
736  *
737  * Synonymous to "unmapping" a window in X Window System terminology.
738  *
739  * @param   win The window to hide.
740  * @ingroup Ecore_X_Window_Visibility
741  */
742 EAPI void
743 ecore_x_window_hide(Ecore_X_Window win)
744 {
745    LOGFN(__FILE__, __LINE__, __FUNCTION__);
746    CHECK_XCB_CONN;
747
748    if (win)
749      {
750         xcb_unmap_notify_event_t ev;
751         Ecore_X_Window root;
752
753         if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1)
754           root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
755         else
756           {
757              xcb_get_geometry_cookie_t cookie;
758              xcb_get_geometry_reply_t *reply;
759
760              cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
761              reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL);
762              if (!reply) return;
763              root = reply->root;
764              free(reply);
765           }
766
767         memset(&ev, 0, sizeof(xcb_unmap_notify_event_t));
768
769         ev.response_type = XCB_UNMAP_NOTIFY;
770         ev.window = win;
771         ev.event = root;
772         ev.from_configure = 0;
773
774         xcb_send_event(_ecore_xcb_conn, 0, root,
775                        (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
776                         XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT),
777                        (const char *)&ev);
778
779         xcb_unmap_window(_ecore_xcb_conn, win);
780 //        ecore_x_flush();
781      }
782 }
783
784 /**
785  * @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions
786  *
787  * Functions that give the focus to an X Window.
788  */
789
790 /**
791  * Sets the focus to the window @p win.
792  * @param   win The window to focus.
793  * @ingroup Ecore_X_Window_Focus_Functions
794  */
795 EAPI void
796 ecore_x_window_focus(Ecore_X_Window win)
797 {
798    LOGFN(__FILE__, __LINE__, __FUNCTION__);
799    CHECK_XCB_CONN;
800
801    if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
802
803    xcb_set_input_focus(_ecore_xcb_conn,
804                        XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME);
805 //   ecore_x_flush();
806 }
807
808 /**
809  * Sets the focus to the given window at a specific time.
810  * @param   win The window to focus.
811  * @param   t   When to set the focus to the window.
812  * @ingroup Ecore_X_Window_Focus_Functions
813  */
814 EAPI void
815 ecore_x_window_focus_at_time(Ecore_X_Window win,
816                              Ecore_X_Time   time __UNUSED__)
817 {
818    LOGFN(__FILE__, __LINE__, __FUNCTION__);
819    CHECK_XCB_CONN;
820
821    if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
822    xcb_set_input_focus(_ecore_xcb_conn, 
823                        XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME);
824 //   ecore_x_flush();
825 }
826
827 /**
828  * @defgroup Ecore_X_Window_Parent_Group X Window Parent Functions
829  *
830  * Functions that retrieve or changes the parent window of a window.
831  */
832
833 /**
834  * Moves a window to within another window at a given position.
835  * @param   win        The window to reparent.
836  * @param   new_parent The new parent window.
837  * @param   x          X position within new parent window.
838  * @param   y          Y position within new parent window.
839  * @ingroup Ecore_X_Window_Parent_Group
840  */
841 EAPI void
842 ecore_x_window_reparent(Ecore_X_Window win,
843                         Ecore_X_Window parent,
844                         int            x,
845                         int            y)
846 {
847    LOGFN(__FILE__, __LINE__, __FUNCTION__);
848    CHECK_XCB_CONN;
849
850    if (parent == 0)
851      parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
852
853    xcb_reparent_window(_ecore_xcb_conn, win, parent, x, y);
854 //   ecore_x_flush();
855 }
856
857 EAPI void
858 ecore_x_window_pixmap_set(Ecore_X_Window win,
859                           Ecore_X_Pixmap pixmap)
860 {
861    uint32_t list;
862
863    LOGFN(__FILE__, __LINE__, __FUNCTION__);
864    CHECK_XCB_CONN;
865
866    list = pixmap;
867
868    xcb_change_window_attributes(_ecore_xcb_conn, win,
869                                 XCB_CW_BACK_PIXMAP, &list);
870 //   ecore_x_flush();
871 }
872
873 /**
874  * Sets the background color of the given window.
875  * @param win   The given window
876  * @param r     red value (0...65536, 16 bits)
877  * @param g     green value (0...65536, 16 bits)
878  * @param b     blue value (0...65536, 16 bits)
879  */
880 EAPI void
881 ecore_x_window_background_color_set(Ecore_X_Window win,
882                                     unsigned short red,
883                                     unsigned short green,
884                                     unsigned short blue)
885 {
886    xcb_alloc_color_cookie_t cookie;
887    xcb_alloc_color_reply_t *reply;
888    uint32_t list;
889
890    LOGFN(__FILE__, __LINE__, __FUNCTION__);
891    CHECK_XCB_CONN;
892
893    cookie =
894      xcb_alloc_color_unchecked(_ecore_xcb_conn,
895                                ((xcb_screen_t *)_ecore_xcb_screen)->default_colormap,
896                                red, green, blue);
897    reply = xcb_alloc_color_reply(_ecore_xcb_conn, cookie, NULL);
898    if (!reply) return;
899    list = reply->pixel;
900    free(reply);
901
902    xcb_change_window_attributes(_ecore_xcb_conn, win,
903                                 XCB_CW_BACK_PIXEL, &list);
904 //   ecore_x_flush();
905 }
906
907 EAPI void
908 ecore_x_window_pixel_gravity_set(Ecore_X_Window  win,
909                                  Ecore_X_Gravity gravity)
910 {
911    uint32_t list;
912
913    LOGFN(__FILE__, __LINE__, __FUNCTION__);
914    CHECK_XCB_CONN;
915
916    list = gravity;
917
918    xcb_change_window_attributes(_ecore_xcb_conn, win,
919                                 XCB_CW_BIT_GRAVITY, &list);
920 //   ecore_x_flush();
921 }
922
923 EAPI void
924 ecore_x_window_gravity_set(Ecore_X_Window  win,
925                            Ecore_X_Gravity gravity)
926 {
927    uint32_t list;
928
929    LOGFN(__FILE__, __LINE__, __FUNCTION__);
930    CHECK_XCB_CONN;
931
932    list = gravity;
933
934    xcb_change_window_attributes(_ecore_xcb_conn, win,
935                                 XCB_CW_WIN_GRAVITY, &list);
936 //   ecore_x_flush();
937 }
938
939 EAPI void
940 ecore_x_window_override_set(Ecore_X_Window win,
941                             Eina_Bool      override)
942 {
943    uint32_t list;
944
945    LOGFN(__FILE__, __LINE__, __FUNCTION__);
946    CHECK_XCB_CONN;
947
948    list = override;
949
950    xcb_change_window_attributes(_ecore_xcb_conn, win,
951                                 XCB_CW_OVERRIDE_REDIRECT, &list);
952 //   ecore_x_flush();
953 }
954
955 /**
956  * @brief Show the cursor on a window of type Ecore_X_Window.
957  * @param win The window for which the cursor will be showed.
958  * @param show Enables the show of the cursor on the window if equals EINA_TRUE, disables if equals EINA_FALSE.
959  */
960 EAPI void
961 ecore_x_window_cursor_show(Ecore_X_Window win,
962                            Eina_Bool      show)
963 {
964    uint32_t list = 0;
965
966    LOGFN(__FILE__, __LINE__, __FUNCTION__);
967    CHECK_XCB_CONN;
968
969    if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
970
971    if (!show)
972      {
973         Ecore_X_Cursor cursor;
974         Ecore_X_Pixmap p, m;
975         Ecore_X_GC gc;
976         xcb_point_t point;
977
978         p = xcb_generate_id(_ecore_xcb_conn);
979         xcb_create_pixmap(_ecore_xcb_conn, 1, p, win, 1, 1);
980         m = xcb_generate_id(_ecore_xcb_conn);
981         xcb_create_pixmap(_ecore_xcb_conn, 1, m, win, 1, 1);
982         gc = xcb_generate_id(_ecore_xcb_conn);
983         xcb_create_gc(_ecore_xcb_conn, gc, win, 0, NULL);
984         xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list);
985         point.x = 0;
986         point.y = 0;
987         xcb_poly_point(_ecore_xcb_conn, XCB_COORD_MODE_ORIGIN,
988                        win, gc, 1, &point);
989         xcb_free_gc(_ecore_xcb_conn, gc);
990
991         cursor = xcb_generate_id(_ecore_xcb_conn);
992         xcb_create_cursor(_ecore_xcb_conn, cursor,
993                           p, m, 0, 0, 0, 0, 0, 0, 0, 0);
994         list = cursor;
995
996         xcb_change_window_attributes(_ecore_xcb_conn, win,
997                                      XCB_CW_CURSOR, &list);
998
999         xcb_free_cursor(_ecore_xcb_conn, cursor);
1000         xcb_free_pixmap(_ecore_xcb_conn, m);
1001         xcb_free_pixmap(_ecore_xcb_conn, p);
1002      }
1003    else
1004      {
1005         xcb_change_window_attributes(_ecore_xcb_conn, win,
1006                                      XCB_CW_CURSOR, &list);
1007      }
1008 //   ecore_x_flush();
1009 }
1010
1011 EAPI void
1012 ecore_x_window_cursor_set(Ecore_X_Window win,
1013                           Ecore_X_Cursor cursor)
1014 {
1015    uint32_t list;
1016
1017    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1018    CHECK_XCB_CONN;
1019
1020    list = cursor;
1021
1022    xcb_change_window_attributes(_ecore_xcb_conn, win, XCB_CW_CURSOR, &list);
1023 //   ecore_x_flush();
1024 }
1025
1026 EAPI void
1027 ecore_x_window_container_manage(Ecore_X_Window win)
1028 {
1029    uint32_t list;
1030
1031    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1032    CHECK_XCB_CONN;
1033
1034    list = (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
1035            XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
1036
1037    xcb_change_window_attributes(_ecore_xcb_conn, win,
1038                                 XCB_CW_EVENT_MASK, &list);
1039 //   ecore_x_flush();
1040 }
1041
1042 EAPI void
1043 ecore_x_window_client_manage(Ecore_X_Window win)
1044 {
1045    uint32_t list;
1046
1047    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1048    CHECK_XCB_CONN;
1049
1050    list = (XCB_EVENT_MASK_VISIBILITY_CHANGE |
1051            XCB_EVENT_MASK_FOCUS_CHANGE |
1052            XCB_EVENT_MASK_PROPERTY_CHANGE |
1053            XCB_EVENT_MASK_COLOR_MAP_CHANGE |
1054            XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1055            XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
1056
1057    xcb_change_window_attributes(_ecore_xcb_conn, win,
1058                                 XCB_CW_EVENT_MASK, &list);
1059
1060 #ifdef ECORE_XCB_SHAPE
1061    xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE);
1062 #endif
1063 //   ecore_x_flush();
1064 }
1065
1066 EAPI void
1067 ecore_x_window_sniff(Ecore_X_Window win)
1068 {
1069    uint32_t list;
1070
1071    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1072    CHECK_XCB_CONN;
1073
1074    list = (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1075            XCB_EVENT_MASK_PROPERTY_CHANGE);
1076
1077    xcb_change_window_attributes(_ecore_xcb_conn, win,
1078                                 XCB_CW_EVENT_MASK, &list);
1079 //   ecore_x_flush();
1080 }
1081
1082 EAPI void
1083 ecore_x_window_unsniff(Ecore_X_Window win)
1084 {
1085    uint32_t list;
1086
1087    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1088 ///TODO: implement xcb
1089 //   ecore_x_flush();
1090 }
1091
1092 EAPI void
1093 ecore_x_window_client_sniff(Ecore_X_Window win)
1094 {
1095    uint32_t list;
1096
1097    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1098    CHECK_XCB_CONN;
1099
1100    list = (XCB_EVENT_MASK_VISIBILITY_CHANGE |
1101            XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1102            XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1103            XCB_EVENT_MASK_FOCUS_CHANGE |
1104            XCB_EVENT_MASK_PROPERTY_CHANGE |
1105            XCB_EVENT_MASK_COLOR_MAP_CHANGE);
1106
1107    xcb_change_window_attributes(_ecore_xcb_conn, win,
1108                                 XCB_CW_EVENT_MASK, &list);
1109 #ifdef ECORE_XCB_SHAPE
1110    xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE);
1111 #endif
1112 //   ecore_x_flush();
1113 }
1114
1115 EAPI void
1116 ecore_x_window_area_clear(Ecore_X_Window win,
1117                           int            x,
1118                           int            y,
1119                           int            w,
1120                           int            h)
1121 {
1122    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1123    CHECK_XCB_CONN;
1124
1125    xcb_clear_area(_ecore_xcb_conn, 0, win, x, y, w, h);
1126 //   ecore_x_flush();
1127 }
1128
1129 EAPI void
1130 ecore_x_window_area_expose(Ecore_X_Window win,
1131                            int            x,
1132                            int            y,
1133                            int            w,
1134                            int            h)
1135 {
1136    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1137    CHECK_XCB_CONN;
1138
1139    xcb_clear_area(_ecore_xcb_conn, 1, win, x, y, w, h);
1140 //   ecore_x_flush();
1141 }
1142
1143 EAPI void
1144 ecore_x_window_save_set_add(Ecore_X_Window win)
1145 {
1146    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1147    CHECK_XCB_CONN;
1148
1149    xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, win);
1150 }
1151
1152 EAPI void
1153 ecore_x_window_save_set_del(Ecore_X_Window win)
1154 {
1155    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1156    CHECK_XCB_CONN;
1157
1158    xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, win);
1159 }
1160
1161 /**
1162  * gets the window that has focus.
1163  * @return  The window that has focus.
1164  * @ingroup Ecore_X_Window_Focus_Functions
1165  */
1166 EAPI Ecore_X_Window
1167 ecore_x_window_focus_get(void)
1168 {
1169    xcb_get_input_focus_cookie_t cookie;
1170    xcb_get_input_focus_reply_t *reply;
1171    Ecore_X_Window focus = 0;
1172
1173    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1174    CHECK_XCB_CONN;
1175
1176    cookie = xcb_get_input_focus_unchecked(_ecore_xcb_conn);
1177    reply = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie, NULL);
1178    if (!reply) return 0;
1179    focus = reply->focus;
1180    free(reply);
1181    return focus;
1182 }
1183
1184 EAPI int
1185 ecore_x_window_argb_get(Ecore_X_Window win)
1186 {
1187    uint8_t ret = 0;
1188 #ifdef ECORE_XCB_RENDER
1189    Ecore_X_Visual visual;
1190 #endif
1191
1192    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1193    CHECK_XCB_CONN;
1194
1195 //   if (!win) return ret;
1196
1197 #ifdef ECORE_XCB_RENDER
1198    /* grab the window's visual */
1199    visual = _ecore_xcb_window_visual_get(win);
1200
1201    /* check if this visual supports alpha */
1202    ret = _ecore_xcb_render_visual_supports_alpha(visual);
1203 #endif
1204
1205    return ret;
1206 }
1207
1208 EAPI Eina_Bool
1209 ecore_x_window_manage(Ecore_X_Window win)
1210 {
1211    xcb_get_window_attributes_cookie_t cookie;
1212    xcb_get_window_attributes_reply_t *reply;
1213    xcb_void_cookie_t change_cookie;
1214    xcb_generic_error_t *err;
1215    uint32_t list;
1216
1217    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1218    CHECK_XCB_CONN;
1219
1220    cookie = xcb_get_window_attributes(_ecore_xcb_conn, win);
1221    reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
1222    if (!reply) return EINA_FALSE;
1223
1224    ecore_x_sync(); // needed
1225
1226    list = (XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
1227            XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_RESIZE_REDIRECT |
1228            XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
1229            XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1230            XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1231            XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
1232            reply->your_event_mask);
1233    free(reply);
1234
1235    change_cookie = xcb_change_window_attributes(_ecore_xcb_conn, win,
1236                                                 XCB_CW_EVENT_MASK, &list);
1237
1238    ecore_x_sync(); // needed
1239
1240    err = xcb_request_check(_ecore_xcb_conn, change_cookie);
1241    if (err)
1242      {
1243         _ecore_xcb_error_handle(err);
1244         free(err);
1245         return EINA_FALSE;
1246      }
1247
1248    return EINA_TRUE;
1249 }
1250
1251 EAPI Eina_Bool
1252 ecore_x_window_attributes_get(Ecore_X_Window             win,
1253                               Ecore_X_Window_Attributes *att_ret)
1254 {
1255    xcb_get_window_attributes_cookie_t cookie;
1256    xcb_get_window_attributes_reply_t *reply;
1257    xcb_get_geometry_cookie_t gcookie;
1258    xcb_get_geometry_reply_t *greply;
1259
1260    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1261    CHECK_XCB_CONN;
1262
1263    cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win);
1264    reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
1265    if (!reply) return EINA_FALSE;
1266
1267    memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
1268
1269    if (reply->map_state != XCB_MAP_STATE_UNMAPPED)
1270      att_ret->visible = EINA_TRUE;
1271
1272    if (reply->map_state == XCB_MAP_STATE_VIEWABLE)
1273      att_ret->viewable = EINA_TRUE;
1274
1275    if (reply->override_redirect)
1276      att_ret->override = EINA_TRUE;
1277
1278    if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY)
1279      att_ret->input_only = EINA_TRUE;
1280
1281    if (reply->save_under)
1282      att_ret->save_under = EINA_TRUE;
1283
1284    att_ret->event_mask.mine = reply->your_event_mask;
1285    att_ret->event_mask.all = reply->all_event_masks;
1286    att_ret->event_mask.no_propagate = reply->do_not_propagate_mask;
1287    att_ret->window_gravity = reply->win_gravity;
1288    att_ret->pixel_gravity = reply->bit_gravity;
1289    att_ret->colormap = reply->colormap;
1290    att_ret->visual = _ecore_xcb_window_find_visual_by_id(reply->visual);
1291
1292    free(reply);
1293
1294    gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
1295    greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL);
1296    if (!greply) return EINA_TRUE;
1297
1298    /* xcb_translate_coordinates_reply_t *trans; */
1299    /* xcb_query_tree_cookie_t tcookie; */
1300    /* xcb_query_tree_reply_t *treply; */
1301
1302    /* tcookie = xcb_query_tree(_ecore_xcb_conn, win); */
1303    /* treply = xcb_query_tree_reply(_ecore_xcb_conn, tcookie, NULL); */
1304
1305    /* trans =  */
1306    /*   xcb_translate_coordinates_reply(_ecore_xcb_conn,  */
1307    /*                                   xcb_translate_coordinates(_ecore_xcb_conn,  */
1308    /*                                                             win, treply->parent, greply->x, greply->y), NULL); */
1309    /* free(treply); */
1310
1311    att_ret->root = greply->root;
1312    att_ret->depth = greply->depth;
1313 //   att_ret->x = trans->dst_x;
1314 //   att_ret->y = trans->dst_y;
1315    att_ret->x = greply->x;
1316    att_ret->y = greply->y;
1317    att_ret->w = greply->width;
1318    att_ret->h = greply->height;
1319    att_ret->border = greply->border_width;
1320
1321 //   free(trans);
1322
1323    free(greply);
1324    return EINA_TRUE;
1325 }
1326
1327 /**
1328  * Retrieves the size of the given window.
1329  * @param   win The given window.
1330  * @param   w   Pointer to an integer into which the width is to be stored.
1331  * @param   h   Pointer to an integer into which the height is to be stored.
1332  * @ingroup Ecore_X_Window_Geometry_Group
1333  */
1334 EAPI void
1335 ecore_x_window_size_get(Ecore_X_Window win,
1336                         int           *width,
1337                         int           *height)
1338 {
1339    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1340    CHECK_XCB_CONN;
1341
1342    if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1343    ecore_x_drawable_geometry_get(win, NULL, NULL, width, height);
1344 }
1345
1346 /**
1347  * Set if a window should be ignored.
1348  * @param   win The given window.
1349  * @param   ignore if to ignore
1350  */
1351 EAPI void
1352 ecore_x_window_ignore_set(Ecore_X_Window win,
1353                           int            ignore)
1354 {
1355    int i = 0, j = 0, count = 0;
1356
1357    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1358    CHECK_XCB_CONN;
1359
1360    if (ignore)
1361      {
1362         if (ignore_list)
1363           {
1364              for (i = 0; i < ignore_num; i++)
1365                if (win == ignore_list[i]) return;
1366
1367              ignore_list =
1368                realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
1369              if (!ignore_list) return;
1370
1371              ignore_list[ignore_num++] = win;
1372           }
1373         else
1374           {
1375              ignore_num = 0;
1376              ignore_list = malloc(sizeof(Ecore_X_Window));
1377              if (!ignore_list) return;
1378              ignore_list[ignore_num++] = win;
1379           }
1380      }
1381    else
1382      {
1383         if (!ignore_list) return;
1384         for (count = ignore_num, i = 0, j = 0; i < count; i++)
1385           {
1386              if (win != ignore_list[i])
1387                ignore_list[j++] = ignore_list[i];
1388              else
1389                ignore_num--;
1390           }
1391         if (ignore_num <= 0)
1392           {
1393              free(ignore_list);
1394              ignore_list = NULL;
1395              return;
1396           }
1397
1398         ignore_list =
1399           realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
1400      }
1401 }
1402
1403 /**
1404  * Get the ignore list
1405  * @param   num number of windows in the list
1406  * @return  list of windows to ignore
1407  */
1408 EAPI Ecore_X_Window *
1409 ecore_x_window_ignore_list(int *num)
1410 {
1411    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1412
1413    if (num) *num = ignore_num;
1414    return ignore_list;
1415 }
1416
1417 /**
1418  * Get a list of all the root windows on the server.
1419  *
1420  * @note   The returned array will need to be freed after use.
1421  * @param  num_ret Pointer to integer to put number of windows returned in.
1422  * @return An array of all the root windows.  @c NULL is returned if memory
1423  *         could not be allocated for the list, or if @p num_ret is @c NULL.
1424  */
1425 EAPI Ecore_X_Window *
1426 ecore_x_window_root_list(int *num_ret)
1427 {
1428    xcb_screen_iterator_t iter;
1429    uint8_t i, num;
1430    Ecore_X_Window *roots = NULL;
1431 #ifdef ECORE_XCB_XPRINT
1432    const xcb_query_extension_reply_t *ext_reply;
1433 #endif
1434
1435    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1436    CHECK_XCB_CONN;
1437
1438    if (!num_ret) return NULL;
1439    if (num_ret) *num_ret = 0;
1440
1441    /* if (xcb_connection_has_error(_ecore_xcb_conn))  */
1442    /*   { */
1443    /*      DBG("XCB Connection Has Error !!!"); */
1444    /*      return NULL; */
1445    /*   } */
1446
1447    num = ecore_x_screen_count_get();
1448
1449 #ifdef ECORE_XCB_XPRINT
1450    ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_x_print_id);
1451    if ((ext_reply) && (ext_reply->present))
1452      {
1453         xcb_x_print_print_query_screens_cookie_t cookie;
1454         xcb_x_print_print_query_screens_reply_t *reply;
1455
1456         cookie = xcb_x_print_print_query_screens_unchecked(_ecore_xcb_conn);
1457         reply =
1458           xcb_x_print_print_query_screens_reply(_ecore_xcb_conn, cookie, NULL);
1459         if (reply)
1460           {
1461              xcb_window_t *screens;
1462              int psnum = 0, overlap = 0, j = 0, k = 0;
1463
1464              psnum = xcb_x_print_print_query_screens_roots_length(reply);
1465              screens = xcb_x_print_print_query_screens_roots(reply);
1466              for (i = 0; i < num; i++)
1467                {
1468                   for (j = 0; j < psnum; j++)
1469                     {
1470                        xcb_screen_t *s;
1471
1472                        if ((s = _ecore_xcb_window_screen_of_display(i)))
1473                          {
1474                             if (s->root == screens[j])
1475                               overlap++;
1476                          }
1477                     }
1478                }
1479              if (!(roots = malloc((num - overlap)
1480                                   * sizeof(Ecore_X_Window)))) return NULL;
1481              for (i = 0; i < num; i++)
1482                {
1483                   Eina_Bool is_print = EINA_FALSE;
1484
1485                   for (j = 0; j < psnum; j++)
1486                     {
1487                        xcb_screen_t *s;
1488
1489                        if ((s = _ecore_xcb_window_screen_of_display(i)))
1490                          {
1491                             if (s->root == screens[j])
1492                               {
1493                                  is_print = EINA_TRUE;
1494                                  break;
1495                               }
1496                          }
1497                     }
1498                   if (!is_print)
1499                     {
1500                        xcb_screen_t *s;
1501
1502                        if ((s = _ecore_xcb_window_screen_of_display(i)))
1503                          {
1504                             roots[k] = s->root;
1505                             k++;
1506                          }
1507                     }
1508                }
1509              if (num_ret) *num_ret = k;
1510              free(reply);
1511           }
1512         else
1513           {
1514              /* Fallback to default method */
1515               iter =
1516                 xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
1517               if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
1518               if (num_ret) *num_ret = num;
1519               for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
1520                 roots[i] = iter.data->root;
1521           }
1522      }
1523    else
1524      {
1525         /* Fallback to default method */
1526          iter =
1527            xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
1528          if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
1529          if (num_ret) *num_ret = num;
1530          for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
1531            roots[i] = iter.data->root;
1532      }
1533 #else
1534    iter =
1535      xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
1536    if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
1537    if (num_ret) *num_ret = num;
1538    for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
1539      roots[i] = iter.data->root;
1540 #endif
1541
1542    return roots;
1543 }
1544
1545 EAPI Ecore_X_Window *
1546 ecore_x_window_children_get(Ecore_X_Window win,
1547                             int           *num)
1548 {
1549    xcb_query_tree_cookie_t cookie;
1550    xcb_query_tree_reply_t *reply;
1551    Ecore_X_Window *windows = NULL;
1552
1553    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1554    CHECK_XCB_CONN;
1555
1556    if (num) *num = 0;
1557    cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, win);
1558    reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
1559    if (!reply) return NULL;
1560
1561    if (num) *num = reply->children_len;
1562    if (reply->children_len > 0)
1563      {
1564         windows = malloc(sizeof(Ecore_X_Window) * reply->children_len);
1565         if (windows)
1566           {
1567              unsigned int i = 0;
1568              xcb_window_t *w;
1569
1570              w = xcb_query_tree_children(reply);
1571              for (i = 0; i < reply->children_len; i++)
1572                windows[i] = w[i];
1573           }
1574      }
1575
1576    free(reply);
1577    return windows;
1578 }
1579
1580 /**
1581  * Retrieves the root window a given window is on.
1582  * @param   win The window to get the root window of
1583  * @return  The root window of @p win
1584  * @ingroup Ecore_X_Window_Geometry_Group
1585  */
1586 EAPI Ecore_X_Window
1587 ecore_x_window_root_get(Ecore_X_Window win)
1588 {
1589    xcb_get_geometry_cookie_t gcookie;
1590    xcb_get_geometry_reply_t *greply;
1591    Ecore_X_Window window = 0;
1592
1593    /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
1594    CHECK_XCB_CONN;
1595
1596    gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
1597    greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL);
1598    if (!greply) return 0;
1599    window = greply->root;
1600    free(greply);
1601
1602    return window;
1603 }
1604
1605 EAPI Ecore_X_Window
1606 ecore_x_window_root_first_get(void)
1607 {
1608    return ((xcb_screen_t *)_ecore_xcb_screen)->root;
1609 }
1610
1611 /**
1612  * Retrieves the geometry of the given window.
1613  *
1614  * Note that the x & y coordingates are relative to your parent.  In
1615  * particular for reparenting window managers - relative to you window border.
1616  * If you want screen coordinates either walk the window tree to the root,
1617  * else for ecore_evas applications see ecore_evas_geometry_get().  Elementary
1618  * applications can use elm_win_screen_position_get().
1619  *
1620  * @param   win The given window.
1621  * @param   x   Pointer to an integer in which the X position is to be stored.
1622  * @param   y   Pointer to an integer in which the Y position is to be stored.
1623  * @param   w   Pointer to an integer in which the width is to be stored.
1624  * @param   h   Pointer to an integer in which the height is to be stored.
1625  * @ingroup Ecore_X_Window_Geometry_Group
1626  */
1627 EAPI void
1628 ecore_x_window_geometry_get(Ecore_X_Window win,
1629                             int           *x,
1630                             int           *y,
1631                             int           *w,
1632                             int           *h)
1633 {
1634    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1635    CHECK_XCB_CONN;
1636
1637    if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1638    ecore_x_drawable_geometry_get(win, x, y, w, h);
1639 }
1640
1641 /**
1642  * Retrieves the top, visible window at the given location.
1643  * @param   x The given X position.
1644  * @param   y The given Y position.
1645  * @return  The window at that position.
1646  * @ingroup Ecore_X_Window_Geometry_Group
1647  */
1648 EAPI Ecore_X_Window
1649 ecore_x_window_at_xy_get(int x,
1650                          int y)
1651 {
1652    Ecore_X_Window root, win = 0;
1653
1654    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1655    CHECK_XCB_CONN;
1656
1657    root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1658
1659    ecore_x_grab();
1660    win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
1661    ecore_x_ungrab();
1662
1663    return win ? win : root;
1664 }
1665
1666 /**
1667  * Retrieves the top, visible window at the given location,
1668  * but skips the windows in the list.
1669  * @param   x The given X position.
1670  * @param   y The given Y position.
1671  * @param   skip The list of windows to be skipped.
1672  * @param   skip_num The number of windows to be skipped.
1673  * @return  The window at that position.
1674  * @ingroup Ecore_X_Window_Geometry_Group
1675  */
1676 EAPI Ecore_X_Window
1677 ecore_x_window_at_xy_with_skip_get(int             x,
1678                                    int             y,
1679                                    Ecore_X_Window *skip,
1680                                    int             skip_num)
1681 {
1682    Ecore_X_Window root, win = 0;
1683
1684    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1685    CHECK_XCB_CONN;
1686
1687    root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1688
1689    ecore_x_grab();
1690    win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
1691    ecore_x_ungrab();
1692
1693    return win ? win : root;
1694 }
1695
1696 EAPI Ecore_X_Window
1697 ecore_x_window_at_xy_begin_get(Ecore_X_Window begin,
1698                                int            x,
1699                                int            y)
1700 {
1701    Ecore_X_Window win = 0;
1702
1703    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1704    CHECK_XCB_CONN;
1705
1706    ecore_x_grab();
1707    win = _ecore_xcb_window_at_xy_get(begin, 0, 0, x, y, NULL, 0);
1708    ecore_x_ungrab();
1709
1710    return win ? win : begin;
1711 }
1712
1713 /**
1714  * Retrieves the parent window of the given window.
1715  * @param   win The given window.
1716  * @return  The parent window of @p win.
1717  * @ingroup Ecore_X_Window_Parent_Group
1718  */
1719 EAPI Ecore_X_Window
1720 ecore_x_window_parent_get(Ecore_X_Window win)
1721 {
1722    xcb_query_tree_cookie_t cookie;
1723    xcb_query_tree_reply_t *reply;
1724    Ecore_X_Window window = 0;
1725
1726    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1727    CHECK_XCB_CONN;
1728
1729 //   if (!win) return 0;
1730    cookie = xcb_query_tree(_ecore_xcb_conn, win);
1731    reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
1732    if (!reply) return 0;
1733    window = reply->parent;
1734    free(reply);
1735
1736    return window;
1737 }
1738
1739 /**
1740  * Finds out whether the given window is currently visible.
1741  * @param   win The given window.
1742  * @return  1 if the window is visible, otherwise 0.
1743  * @ingroup Ecore_X_Window_Visibility_Group
1744  */
1745 EAPI int
1746 ecore_x_window_visible_get(Ecore_X_Window win)
1747 {
1748    xcb_get_window_attributes_cookie_t cookie;
1749    xcb_get_window_attributes_reply_t *reply;
1750    int ret = EINA_FALSE;
1751
1752    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1753    CHECK_XCB_CONN;
1754
1755    cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win);
1756    reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
1757    if (!reply) return EINA_FALSE;
1758
1759    if (reply->map_state == XCB_MAP_STATE_VIEWABLE)
1760      ret = EINA_TRUE;
1761
1762    free(reply);
1763    return ret;
1764 }
1765
1766 EAPI void
1767 ecore_x_window_button_grab(Ecore_X_Window     win,
1768                            int                button,
1769                            Ecore_X_Event_Mask mask,
1770                            int                mod,
1771                            int                any_mod)
1772 {
1773    int i = 0;
1774    uint16_t m, locks[8], ev;
1775    uint8_t b;
1776    Ecore_X_Window *t;
1777
1778    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1779    CHECK_XCB_CONN;
1780
1781    b = button;
1782    if (b == 0)
1783      b = XCB_BUTTON_INDEX_ANY;
1784
1785    m = _ecore_xcb_window_modifiers_get(mod);
1786    if (any_mod) m = XCB_MOD_MASK_ANY;
1787
1788    locks[0] = 0;
1789    locks[1] = ECORE_X_LOCK_CAPS;
1790    locks[2] = ECORE_X_LOCK_NUM;
1791    locks[3] = ECORE_X_LOCK_SCROLL;
1792    locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1793    locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1794    locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1795    locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1796
1797    ev = mask;
1798    for (i = 0; i < 8; i++)
1799      xcb_grab_button(_ecore_xcb_conn, 0, win, ev,
1800                      XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
1801                      XCB_NONE, XCB_NONE, b, m | locks[i]);
1802
1803    _ecore_xcb_button_grabs_num++;
1804    t = realloc(_ecore_xcb_button_grabs,
1805                _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window));
1806    if (!t) return;
1807
1808    _ecore_xcb_button_grabs = t;
1809    _ecore_xcb_button_grabs[_ecore_xcb_button_grabs_num - 1] = win;
1810 }
1811
1812 EAPI void
1813 ecore_x_window_button_ungrab(Ecore_X_Window win,
1814                              int            button,
1815                              int            mod,
1816                              int            any_mod)
1817 {
1818    int i = 0;
1819    uint16_t m = 0, locks[8];
1820    uint8_t b;
1821
1822    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1823    CHECK_XCB_CONN;
1824
1825    b = button;
1826    if (b == 0) b = XCB_BUTTON_INDEX_ANY;
1827
1828    m = _ecore_xcb_window_modifiers_get(mod);
1829    if (any_mod) m = XCB_MOD_MASK_ANY;
1830
1831    locks[0] = 0;
1832    locks[1] = ECORE_X_LOCK_CAPS;
1833    locks[2] = ECORE_X_LOCK_NUM;
1834    locks[3] = ECORE_X_LOCK_SCROLL;
1835    locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1836    locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1837    locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1838    locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1839
1840    for (i = 0; i < 8; i++)
1841      xcb_ungrab_button(_ecore_xcb_conn, b, win, m | locks[i]);
1842
1843    _ecore_xcb_sync_magic_send(1, win);
1844 }
1845
1846 EAPI void
1847 ecore_x_window_key_grab(Ecore_X_Window win,
1848                         const char    *key,
1849                         int            mod,
1850                         int            any_mod)
1851 {
1852    xcb_keycode_t keycode = XCB_NO_SYMBOL;
1853    uint16_t m = 0, locks[8];
1854    int i = 0;
1855    Ecore_X_Window *t;
1856
1857    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1858    CHECK_XCB_CONN;
1859
1860    keycode = _ecore_xcb_keymap_string_to_keycode(key);
1861    if (keycode == XCB_NO_SYMBOL) return;
1862
1863    m = _ecore_xcb_window_modifiers_get(mod);
1864    if (any_mod) m = XCB_MOD_MASK_ANY;
1865
1866    locks[0] = 0;
1867    locks[1] = ECORE_X_LOCK_CAPS;
1868    locks[2] = ECORE_X_LOCK_NUM;
1869    locks[3] = ECORE_X_LOCK_SCROLL;
1870    locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1871    locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1872    locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1873    locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1874
1875    for (i = 0; i < 8; i++)
1876      xcb_grab_key(_ecore_xcb_conn, 0, win, m | locks[i],
1877                   keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
1878    _ecore_xcb_key_grabs_num++;
1879    t = realloc(_ecore_xcb_key_grabs,
1880                _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window));
1881    if (!t) return;
1882    _ecore_xcb_key_grabs = t;
1883    _ecore_xcb_key_grabs[_ecore_xcb_key_grabs_num - 1] = win;
1884 }
1885
1886 EAPI void
1887 ecore_x_window_key_ungrab(Ecore_X_Window win,
1888                           const char    *key,
1889                           int            mod,
1890                           int            any_mod)
1891 {
1892    xcb_keycode_t keycode = XCB_NO_SYMBOL;
1893    uint16_t m = 0, locks[8];
1894    int i = 0;
1895
1896    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1897    CHECK_XCB_CONN;
1898
1899    keycode = _ecore_xcb_keymap_string_to_keycode(key);
1900    if (keycode == XCB_NO_SYMBOL) return;
1901
1902    m = _ecore_xcb_window_modifiers_get(mod);
1903    if (any_mod) m = XCB_MOD_MASK_ANY;
1904
1905    locks[0] = 0;
1906    locks[1] = ECORE_X_LOCK_CAPS;
1907    locks[2] = ECORE_X_LOCK_NUM;
1908    locks[3] = ECORE_X_LOCK_SCROLL;
1909    locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1910    locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1911    locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1912    locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1913
1914    for (i = 0; i < 8; i++)
1915      xcb_ungrab_key(_ecore_xcb_conn, keycode, win, m | locks[i]);
1916
1917    _ecore_xcb_sync_magic_send(2, win);
1918 }
1919
1920 /* local functions */
1921 Ecore_X_Window
1922 _ecore_xcb_window_root_of_screen_get(int screen)
1923 {
1924    xcb_screen_iterator_t iter;
1925
1926    CHECK_XCB_CONN;
1927    iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
1928    for (; iter.rem; --screen, xcb_screen_next(&iter))
1929      if (screen == 0)
1930        {
1931           xcb_screen_t *s;
1932
1933           if ((s = iter.data))
1934             return s->root;
1935        }
1936    return 0;
1937 }
1938
1939 static Ecore_X_Window
1940 _ecore_xcb_window_argb_internal_new(Ecore_X_Window parent,
1941                                     int            x,
1942                                     int            y,
1943                                     int            w,
1944                                     int            h,
1945                                     uint8_t        override_redirect,
1946                                     uint8_t        save_under)
1947 {
1948    Ecore_X_Window win = 0;
1949 #ifdef ECORE_XCB_RENDER
1950    uint32_t value_list[10];
1951    uint32_t value_mask;
1952    uint32_t vis;
1953    Ecore_X_Colormap colormap;
1954 #endif
1955
1956    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1957    CHECK_XCB_CONN;
1958
1959 #ifdef ECORE_XCB_RENDER
1960    if (parent == 0)
1961      parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1962
1963    vis =
1964      _ecore_xcb_render_find_visual_id(XCB_RENDER_PICT_TYPE_DIRECT, EINA_TRUE);
1965
1966    colormap = xcb_generate_id(_ecore_xcb_conn);
1967    xcb_create_colormap(_ecore_xcb_conn, XCB_COLORMAP_ALLOC_NONE,
1968                        colormap, parent, vis);
1969
1970    value_mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
1971                  XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
1972                  XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER |
1973                  XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE | XCB_CW_COLORMAP);
1974
1975    value_list[0] = XCB_BACK_PIXMAP_NONE;
1976    value_list[1] = 0;
1977    value_list[2] = XCB_GRAVITY_NORTH_WEST;
1978    value_list[3] = XCB_GRAVITY_NORTH_WEST;
1979    value_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
1980    value_list[5] = override_redirect;
1981    value_list[6] = save_under;
1982    value_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
1983                     XCB_EVENT_MASK_BUTTON_PRESS |
1984                     XCB_EVENT_MASK_BUTTON_RELEASE |
1985                     XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
1986                     XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
1987                     XCB_EVENT_MASK_VISIBILITY_CHANGE |
1988                     XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1989                     XCB_EVENT_MASK_FOCUS_CHANGE |
1990                     XCB_EVENT_MASK_PROPERTY_CHANGE |
1991                     XCB_EVENT_MASK_COLOR_MAP_CHANGE);
1992    value_list[8] = XCB_EVENT_MASK_NO_EVENT;
1993    value_list[9] = colormap;
1994
1995    win = xcb_generate_id(_ecore_xcb_conn);
1996    xcb_create_window(_ecore_xcb_conn, 32, win, parent, x, y, w, h, 0,
1997                      XCB_WINDOW_CLASS_INPUT_OUTPUT, vis, value_mask,
1998                      value_list);
1999
2000    xcb_free_colormap(_ecore_xcb_conn, colormap);
2001
2002    if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
2003      ecore_x_window_defaults_set(win);
2004 #endif
2005
2006    return win;
2007 }
2008
2009 static Ecore_X_Window
2010 _ecore_xcb_window_at_xy_get(Ecore_X_Window  base,
2011                             int             bx,
2012                             int             by,
2013                             int             x,
2014                             int             y,
2015                             Ecore_X_Window *skip,
2016                             int             skip_num)
2017 {
2018    xcb_query_tree_cookie_t cookie;
2019    xcb_query_tree_reply_t *reply;
2020    Ecore_X_Window *windows = NULL;
2021    int wx, wy, ww, wh, num, i = 0;
2022    Eina_Bool skipit = EINA_FALSE;
2023
2024    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2025    CHECK_XCB_CONN;
2026
2027    if (!ecore_x_window_visible_get(base)) return 0;
2028
2029    ecore_x_window_geometry_get(base, &wx, &wy, &ww, &wh);
2030    wx += bx;
2031    wy += by;
2032
2033    if (!((x >= wx) && (y >= wy) && (x < (wx + ww)) && (y < (wy + wh))))
2034      return 0;
2035
2036    cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, base);
2037    reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
2038    if (!reply) return 0;
2039
2040    num = reply->children_len;
2041    windows = xcb_query_tree_children(reply);
2042
2043    for (i = (num - 1); i >= 0; --i)
2044      {
2045         skipit = EINA_FALSE;
2046
2047         if (skip)
2048           {
2049              int j = 0;
2050
2051              for (j = 0; j < skip_num; j++)
2052                {
2053                   if (windows[i] == skip[j])
2054                     {
2055                        skipit = EINA_TRUE;
2056                        goto onward;
2057                     }
2058                }
2059           }
2060 onward:
2061         if (!skipit)
2062           {
2063              Ecore_X_Window child = 0;
2064
2065              child =
2066                _ecore_xcb_window_at_xy_get(windows[i],
2067                                            wx, wy, x, y, skip, skip_num);
2068              if (child)
2069                {
2070                   if (reply) free(reply);
2071                   return child;
2072                }
2073           }
2074      }
2075
2076    if (reply) free(reply);
2077    return base;
2078 }
2079
2080 Ecore_X_Visual
2081 _ecore_xcb_window_visual_get(Ecore_X_Window win)
2082 {
2083    xcb_get_window_attributes_cookie_t cookie;
2084    xcb_get_window_attributes_reply_t *reply;
2085    Ecore_X_Visual visual = 0;
2086
2087    CHECK_XCB_CONN;
2088
2089    cookie = xcb_get_window_attributes(_ecore_xcb_conn, win);
2090    reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
2091    if (!reply) return 0;
2092    visual = _ecore_xcb_window_find_visual_by_id(reply->visual);
2093    free(reply);
2094
2095    return visual;
2096 }
2097
2098 void
2099 _ecore_xcb_window_button_grab_remove(Ecore_X_Window win)
2100 {
2101    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2102    CHECK_XCB_CONN;
2103
2104    if (_ecore_xcb_button_grabs_num > 0)
2105      {
2106         int i = 0, shuffle = 0;
2107
2108         for (i = 0; i < _ecore_xcb_button_grabs_num; i++)
2109           {
2110              if (shuffle)
2111                _ecore_xcb_button_grabs[i - 1] = _ecore_xcb_button_grabs[i];
2112
2113              if ((!shuffle) && (_ecore_xcb_button_grabs[i] == win))
2114                shuffle = 1;
2115           }
2116
2117         if (shuffle)
2118           {
2119              Ecore_X_Window *t;
2120
2121              _ecore_xcb_button_grabs_num--;
2122              if (_ecore_xcb_button_grabs_num <= 0)
2123                {
2124                   free(_ecore_xcb_button_grabs);
2125                   _ecore_xcb_button_grabs = NULL;
2126                   return;
2127                }
2128
2129              t = realloc(_ecore_xcb_button_grabs,
2130                          _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window));
2131              if (!t) return;
2132              _ecore_xcb_button_grabs = t;
2133           }
2134      }
2135 }
2136
2137 void
2138 _ecore_xcb_window_key_grab_remove(Ecore_X_Window win)
2139 {
2140    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2141    CHECK_XCB_CONN;
2142
2143    if (_ecore_xcb_key_grabs_num > 0)
2144      {
2145         int i = 0, shuffle = 0;
2146
2147         for (i = 0; i < _ecore_xcb_key_grabs_num; i++)
2148           {
2149              if (shuffle)
2150                _ecore_xcb_key_grabs[i - 1] = _ecore_xcb_key_grabs[i];
2151
2152              if ((!shuffle) && (_ecore_xcb_key_grabs[i] == win))
2153                shuffle = 1;
2154           }
2155
2156         if (shuffle)
2157           {
2158              Ecore_X_Window *t;
2159
2160              _ecore_xcb_key_grabs_num--;
2161              if (_ecore_xcb_key_grabs_num <= 0)
2162                {
2163                   free(_ecore_xcb_key_grabs);
2164                   _ecore_xcb_key_grabs = NULL;
2165                   return;
2166                }
2167
2168              t = realloc(_ecore_xcb_key_grabs,
2169                          _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window));
2170              if (!t) return;
2171              _ecore_xcb_key_grabs = t;
2172           }
2173      }
2174 }
2175
2176 void
2177 _ecore_xcb_window_grab_allow_events(Ecore_X_Window event_win,
2178                                     Ecore_X_Window child_win,
2179                                     int            type,
2180                                     void          *event,
2181                                     Ecore_X_Time   timestamp)
2182 {
2183    int i = 0;
2184
2185    LOGFN(__FILE__, __LINE__, __FUNCTION__);
2186    CHECK_XCB_CONN;
2187
2188    for (i = 0; i < _ecore_xcb_button_grabs_num; i++)
2189      {
2190         if ((_ecore_xcb_button_grabs[i] == event_win) ||
2191             (_ecore_xcb_button_grabs[i] == child_win))
2192           {
2193              Eina_Bool replay = EINA_FALSE;
2194
2195              if (_ecore_xcb_window_grab_replay_func)
2196                {
2197                   replay =
2198                     _ecore_xcb_window_grab_replay_func(_ecore_xcb_window_grab_replay_data,
2199                                                        type, event);
2200                }
2201              if (replay)
2202                {
2203                   xcb_allow_events(_ecore_xcb_conn,
2204                                    XCB_ALLOW_REPLAY_POINTER, timestamp);
2205                }
2206              else
2207                {
2208                   xcb_allow_events(_ecore_xcb_conn,
2209                                    XCB_ALLOW_ASYNC_POINTER, timestamp);
2210                }
2211              break;
2212           }
2213      }
2214 }
2215
2216 static int
2217 _ecore_xcb_window_modifiers_get(unsigned int state)
2218 {
2219    int xmodifiers = 0;
2220
2221    if (state & ECORE_EVENT_MODIFIER_SHIFT)
2222      xmodifiers |= ECORE_X_MODIFIER_SHIFT;
2223    if (state & ECORE_EVENT_MODIFIER_CTRL)
2224      xmodifiers |= ECORE_X_MODIFIER_CTRL;
2225    if (state & ECORE_EVENT_MODIFIER_ALT)
2226      xmodifiers |= ECORE_X_MODIFIER_ALT;
2227    if (state & ECORE_EVENT_MODIFIER_WIN)
2228      xmodifiers |= ECORE_X_MODIFIER_WIN;
2229    if (state & ECORE_EVENT_MODIFIER_ALTGR)
2230      xmodifiers |= ECORE_X_MODIFIER_ALTGR;
2231    if (state & ECORE_EVENT_LOCK_SCROLL)
2232      xmodifiers |= ECORE_X_LOCK_SCROLL;
2233    if (state & ECORE_EVENT_LOCK_NUM)
2234      xmodifiers |= ECORE_X_LOCK_NUM;
2235    if (state & ECORE_EVENT_LOCK_CAPS)
2236      xmodifiers |= ECORE_X_LOCK_CAPS;
2237    if (state & ECORE_EVENT_LOCK_SHIFT)
2238      xmodifiers |= ECORE_X_LOCK_SHIFT;
2239
2240    return xmodifiers;
2241 }
2242
2243 static xcb_visualtype_t *
2244 _ecore_xcb_window_find_visual_by_id(xcb_visualid_t id)
2245 {
2246    xcb_depth_iterator_t diter;
2247    xcb_visualtype_iterator_t viter;
2248
2249    CHECK_XCB_CONN;
2250    diter = xcb_screen_allowed_depths_iterator(_ecore_xcb_screen);
2251    for (; diter.rem; xcb_depth_next(&diter))
2252      {
2253         viter = xcb_depth_visuals_iterator(diter.data);
2254         for (; viter.rem; xcb_visualtype_next(&viter))
2255           {
2256              if (viter.data->visual_id == id)
2257                return viter.data;
2258           }
2259      }
2260    return 0;
2261 }
2262
2263 #ifdef ECORE_XCB_XPRINT
2264 static xcb_screen_t *
2265 _ecore_xcb_window_screen_of_display(int screen)
2266 {
2267    xcb_screen_iterator_t iter;
2268
2269    CHECK_XCB_CONN;
2270    iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
2271    for (; iter.rem; --screen, xcb_screen_next(&iter))
2272      if (screen == 0)
2273        return iter.data;
2274
2275    return NULL;
2276 }
2277
2278 #endif