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