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