svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_netwm.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 /*
6  * _NET_WM... aka Extended Window Manager Hint (EWMH) functions.
7  */
8
9 #include <stdio.h>
10 #include <string.h>
11
12 #include "ecore_xcb_private.h"
13 #include "Ecore_X_Atoms.h"
14
15
16 /**
17  * @defgroup Ecore_X_NetWM_Group Extended Window Manager Hint (EWMH) functions
18  *
19  * Functions related to the Extended Window Manager Hint (EWMH).
20  */
21
22
23 typedef struct _Ecore_X_Startup_Info Ecore_X_Startup_Info;
24
25 struct _Ecore_X_Startup_Info
26 {
27    Ecore_X_Window win;
28
29    int   init;
30
31    int   buffer_size;
32    char *buffer;
33
34    int   length;
35
36    /* These are the sequence info fields */
37    char *id;
38    char *name;
39    int   screen;
40    char *bin;
41    char *icon;
42    int   desktop;
43    int   timestamp;
44    char *description;
45    char *wmclass;
46    int   silent;
47 };
48
49 #if 0
50 static void  _ecore_x_window_prop_string_utf8_get_prefetch(Ecore_X_Window window, Ecore_X_Atom atom);
51 static void  _ecore_x_window_prop_string_utf8_get_fetch(void);
52 #endif
53 static void  _ecore_x_window_prop_string_utf8_set(Ecore_X_Window window, Ecore_X_Atom atom, const char *str);
54 static char *_ecore_x_window_prop_string_utf8_get(Ecore_X_Window window, Ecore_X_Atom atom);
55 #if 0 /* Unused */
56 static int   _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info);
57 static int   _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info, char *data);
58 #endif
59 static void  _ecore_x_netwm_startup_info_free(void *data);
60
61 /*
62  * Local variables
63  */
64
65 static Eina_Hash *startup_info = NULL;
66
67 /**
68  * Initialize the NetWM module
69  */
70 EAPI void
71 ecore_x_netwm_init(void)
72 {
73    startup_info = eina_hash_string_superfast_new(_ecore_x_netwm_startup_info_free);
74 }
75
76 /**
77  * Shutdown the NetWM module
78  */
79 EAPI void
80 ecore_x_netwm_shutdown(void)
81 {
82    if (startup_info)
83      eina_hash_free(startup_info);
84    startup_info = NULL;
85 }
86
87 /**
88  * Set the _NET_SUPPORTING_WM_CHECK property.
89  * @param root    The root window.
90  * @param check   The child window.
91  * @param wm_name The name of the Window Manager.
92  *
93  * Set the _NET_SUPPORTING_WM_CHECK property on the @p root window to be
94  * the ID of the child window @p check created by the Window Manager.
95  * @p check also have the _NET_WM_NAME property set to the name
96  * @p wm_name of the Window Manager.
97  *
98  * The Window MUST call that function to indicate that a compliant
99  * window manager is active.
100  * @ingroup Ecore_X_NetWM_Group
101  */
102 EAPI void
103 ecore_x_netwm_wm_identify(Ecore_X_Window root,
104                           Ecore_X_Window check,
105                           const char    *wm_name)
106 {
107    ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1);
108    ecore_x_window_prop_window_set(check, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1);
109    _ecore_x_window_prop_string_utf8_set(check, ECORE_X_ATOM_NET_WM_NAME, wm_name);
110    /* This one isn't mandatory */
111    _ecore_x_window_prop_string_utf8_set(root, ECORE_X_ATOM_NET_WM_NAME, wm_name);
112 }
113
114 /**
115  * Set the _NET_SUPPORTED property.
116  * @param root      The root window.
117  * @param supported The supported hints.
118  * @param num       The number of hints.
119  *
120  * Set the _NET_SUPPORTED property on the @p root window. The hints
121  * that the Window Manager supports are stored in @p supported.
122  *
123  * The Window Manager MUST set this property to indicate which hints
124  * it supports.
125  * @ingroup Ecore_X_NetWM_Group
126  */
127 EAPI void
128 ecore_x_netwm_supported_set(Ecore_X_Window root,
129                             Ecore_X_Atom  *supported,
130                             int            num)
131 {
132    ecore_x_window_prop_atom_set(root, ECORE_X_ATOM_NET_SUPPORTED, supported, num);
133 }
134
135 /**
136  * Sends the GetProperty request.
137  * @param root The root window
138  * @ingroup Ecore_X_NetWM_Group
139  */
140 EAPI void
141 ecore_x_netwm_supported_get_prefetch(Ecore_X_Window root)
142 {
143    xcb_get_property_cookie_t cookie;
144
145    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, root,
146                                        ECORE_X_ATOM_NET_SUPPORTED, ECORE_X_ATOM_ATOM,
147                                        0, 0x7fffffff);
148    _ecore_xcb_cookie_cache(cookie.sequence);
149 }
150
151 /**
152  * Gets the reply of the GetProperty request sent by ecore_x_netwm_supported_get_prefetch().
153  * @ingroup Ecore_X_NetWM_Group
154  */
155 EAPI void
156 ecore_x_netwm_supported_get_fetch(void)
157 {
158    xcb_get_property_cookie_t cookie;
159    xcb_get_property_reply_t *reply;
160
161    cookie.sequence = _ecore_xcb_cookie_get();
162    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
163    _ecore_xcb_reply_cache(reply);
164 }
165
166 /**
167  * Get the hints supported by the Window Manager.
168  * @param root      The root window.
169  * @param supported The supported hints.
170  * @param num       The number of atoms.
171  * @return          1 on success, 0 otherwise.
172  *
173  * Get the hints supported by the Window Manager. @p root is the root
174  * window. The hints are stored in @p supported. The number of hints
175  * is stored in @p num.
176  *
177  * To use this function, you must call before, and in order,
178  * ecore_x_netwm_supported_get_prefetch(), which sends the GetProperty request,
179  * then ecore_x_netwm_supported_get_fetch(), which gets the reply.
180  * @ingroup Ecore_X_NetWM_Group
181  */
182 EAPI int
183 ecore_x_netwm_supported_get(Ecore_X_Window root,
184                             Ecore_X_Atom **supported,
185                             int           *num)
186 {
187    int num_ret;
188
189    if (num) *num = 0UL;
190    if (supported) *supported = NULL;
191
192    num_ret = ecore_x_window_prop_xid_list_get(root,
193                                               ECORE_X_ATOM_NET_SUPPORTED,
194                                               ECORE_X_ATOM_ATOM,
195                                               supported);
196    if (num_ret <= 0)
197       return 0;
198
199    if (num) *num = (uint32_t)num_ret;
200    return 1;
201 }
202
203 /**
204  * Set the _NET_NUMBER_OF_DESKTOPS property.
205  * @param root The root window.
206  * @param n_desks The number of desktops.
207  *
208  * Set the number of desktops @p n_desks of the Window Manager by
209  * sending the _NET_NUMBER_OF_DESKTOPS to the @p root window.
210  *
211  * The Window Manager SHOULD set and update this property to indicate
212  * the number of virtual desktops. A Pager can request a change in the
213  * number of desktops by using that function.
214  * @ingroup Ecore_X_NetWM_Group
215  */
216 EAPI void
217 ecore_x_netwm_desk_count_set(Ecore_X_Window root,
218                              unsigned int   n_desks)
219 {
220    ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS,
221                                   &n_desks, 1);
222 }
223
224 /**
225  * Set the _NET_VIRTUAL_ROOTS property.
226  * @param root    The root window.
227  * @param vroots  The virtual root windows.
228  * @param n_desks The number of desks.
229  *
230  * Set the number of virtual desktops by sending the
231  * _NET_VIRTUAL_ROOTS property to the @p root window. @p vroots is an
232  * array of window and @p n_desks is the number of windows.
233  *
234  * A Window Manager that implements virtual desktops by reparent
235  * client windows to a child of the root window MUST use that
236  * function.
237  * @ingroup Ecore_X_NetWM_Group
238  */
239 EAPI void
240 ecore_x_netwm_desk_roots_set(Ecore_X_Window  root,
241                              Ecore_X_Window *vroots,
242                              unsigned int    n_desks)
243 {
244    ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_VIRTUAL_ROOTS, vroots, n_desks);
245 }
246
247 /**
248  * Set the _NET_DESKTOP_NAMES property.
249  * @param root    The root window.
250  * @param names   The names of the virtual desktops.
251  * @param n_desks The number of virtual desktops.
252  *
253  * Set the name of each virtual desktop by sending the
254  * _NET_DESKTOP_NAMES to the @p root window. @p names are the names of
255  * the virtual desktops and @p n_desks is the number of virtual
256  * desktops.
257  *
258  * A Pager MAY use that function. @p n_desks may be different from the
259  * one passed to ecore_x_netwm_desk_count_set().  If it less or equal,
260  * then the desktops with high numbers are unnamed. If it is larger,
261  * then the excess names are considered to be reserved in case the
262  * number of desktops is increased.
263  * @ingroup Ecore_X_NetWM_Group
264  */
265 EAPI void
266 ecore_x_netwm_desk_names_set(Ecore_X_Window root,
267                              const char   **names,
268                              unsigned int   n_desks)
269 {
270    char        ss[32];
271    char       *buf;
272    const char *s;
273    uint32_t    i;
274    uint32_t    len;
275    uint32_t    l;
276
277    buf = NULL;
278    len = 0;
279
280    for (i = 0; i < n_desks; i++)
281      {
282         s = (names) ? names[i] : NULL;
283         if (!s)
284           {
285              /* Default to "Desk-<number>" */
286              sprintf(ss, "Desk-%d", i);
287              s = ss;
288           }
289
290         l = strlen(s) + 1;
291         buf = realloc(buf, len + l);
292         memcpy(buf + len, s, l);
293         len += l;
294      }
295
296    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, root,
297                        ECORE_X_ATOM_NET_DESKTOP_NAMES,
298                        ECORE_X_ATOM_UTF8_STRING,
299                        8, len, (const void *)buf);
300    free(buf);
301 }
302
303 /**
304  * Set the _NET_DESKTOP_GEOMETRY property.
305  * @param root   The root window.
306  * @param width  The width of the desktop.
307  * @param height The height of the desktop.
308  *
309  * Set the common @p width and @p height of all desktops by sending
310  * the _NET_DESKTOP_GEOMETRY to the @p root window.
311  *
312  * This size is equal to the screen size if the Window Manager doesn't
313  * support large desktops, otherwise it's equal to the virtual size of
314  * the desktop. The Window Manager SHOULD set this property. A Pager
315  * can request a change in the desktop geometry by using this
316  * function.
317  * @ingroup Ecore_X_NetWM_Group
318  */
319 EAPI void
320 ecore_x_netwm_desk_size_set(Ecore_X_Window root,
321                             unsigned int   width,
322                             unsigned int   height)
323 {
324    uint32_t size[2];
325
326    size[0] = width;
327    size[1] = height;
328    ecore_x_window_prop_card32_set(root,
329                                   ECORE_X_ATOM_NET_DESKTOP_GEOMETRY,
330                                   size, 2);
331 }
332
333 /**
334  * Set the _NET_DESKTOP_VIEWPORT property.
335  * @param root    The root window.
336  * @param origins An array of paris of coordiantes.
337  * @param n_desks The number of virtual desktops.
338  *
339  * Set the top left corner of each desktop's viewport by sending the
340  * _NET_DESKTOP_VIEWPORT property to the @p root window. @p origins
341  * contains each pair of X coordinate and Y coordinate of the top left
342  * corner of each desktop's viewport.
343  *
344  * If the Window Manager does not support large desktops, the
345  * coordinates MUST be (0,0). A Pager can request to change the
346  * viewport for the current desktop by using this function.
347  * @ingroup Ecore_X_NetWM_Group
348  */
349 EAPI void
350 ecore_x_netwm_desk_viewports_set(Ecore_X_Window root,
351                                  unsigned int  *origins,
352                                  unsigned int   n_desks)
353 {
354    ecore_x_window_prop_card32_set(root,
355                                   ECORE_X_ATOM_NET_DESKTOP_VIEWPORT,
356                                   origins, 2 * n_desks);
357 }
358
359 /**
360  * Set the _NET_DESKTOP_LAYOUT property.
361  * @param root The root window.
362  * @param orientation
363  * @param columns
364  * @param rows
365  * @param starting_corner
366  *
367  * Set the layout of virtual desktops relative to each other by
368  * sending the _NET_DESKTOP_LAYOUT to the @p root window.
369  * @p orientation defines the orientation of the virtual desktop. 0
370  * means horizontal layout, 1 means vertical layout. @p columns is
371  * the number of desktops in the X direction and @p rows is the number
372  * in the Y direction. @p starting_corner is the corner containing the
373  * first desktop. The values for @p starting_corner are 0 (top-left),
374  * 1 (top-right), 2 (bottom-right) and 3 (bottom-left).
375  *
376  * When the orientation is horizontal the desktops are laid out in
377  * rows, with the first desktop in the specified starting corner. So a
378  * layout with four columns and three rows starting in
379  * the top-left corner looks like this:
380  *
381  * +--+--+--+--+
382  * | 0| 1| 2| 3|
383  * +--+--+--+--+
384  * | 4| 5| 6| 7|
385  * +--+--+--+--+
386  * | 8| 9|10|11|
387  * +--+--+--+--+
388  *
389  * With @p starting_corner being bottom-right, it looks like this:
390  *
391  * +--+--+--+--+
392  * |11|10| 9| 8|
393  * +--+--+--+--+
394  * | 7| 6| 5| 4|
395  * +--+--+--+--+
396  * | 3| 2| 1| 0|
397  * +--+--+--+--+
398  *
399  * When the orientation is vertical the layout with four columns and
400  * three rows starting in the top-left corner looks like:
401  *
402  * +--+--+--+--+
403  * | 0| 3| 6| 9|
404  * +--+--+--+--+
405  * | 1| 4| 7|10|
406  * +--+--+--+--+
407  * | 2| 5| 8|11|
408  * +--+--+--+--+
409  *
410  * With @p starting_corner  being top-right, it looks like:
411  *
412  * +--+--+--+--+
413  * | 9| 6| 3| 0|
414  * +--+--+--+--+
415  * |10| 7| 4| 1|
416  * +--+--+--+--+
417  * |11| 8| 5| 2|
418  * +--+--+--+--+
419  *
420  * This function MUST be used by a Pager and NOT by the Window
421  * Manager. When using this function, the Pager must own a manager
422  * selection.
423  * @ingroup Ecore_X_NetWM_Group
424  */
425 EAPI void
426 ecore_x_netwm_desk_layout_set(Ecore_X_Window root,
427                               int            orientation,
428                               int            columns,
429                               int            rows,
430                               int            starting_corner)
431 {
432    uint32_t layout[4];
433
434    layout[0] = orientation;
435    layout[1] = columns;
436    layout[2] = rows;
437    layout[3] = starting_corner;
438    ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT, layout, 4);
439 }
440
441 /**
442  * Set the _NET_WORKAREA property.
443  * @param root    The root window.
444  * @param areas   An array of areas.
445  * @param n_desks The number of desks.
446  *
447  * Set the work area for each desktop by sending the _NET_WORKAREA
448  * property to the @p root window. An area contains the geometry (X
449  * and Y coordinates, width and height). These geometries are
450  * specified relative to the viewport on each desktop and specify an
451  * area that is completely contained within the viewport. @p areas
452  * stores these geometries. @p n_desks is the number of geometry to
453  * set.
454  *
455  * This function MUST be set by the Window Manager. It is used by
456  * desktop applications to place desktop icons appropriately.
457  * @ingroup Ecore_X_NetWM_Group
458  */
459 EAPI void
460 ecore_x_netwm_desk_workareas_set(Ecore_X_Window root,
461                                  unsigned int  *areas,
462                                  unsigned int   n_desks)
463 {
464    ecore_x_window_prop_card32_set(root,
465                                   ECORE_X_ATOM_NET_WORKAREA,
466                                   areas, 4 * n_desks);
467 }
468
469 /**
470  * Set the _NET_CURRENT_DESKTOP property.
471  * @param root The root window.
472  * @param desk The index of the current desktop.
473  *
474  * Set the current desktop by sending the _NET_CURRENT_DESKTOP to the
475  * @p root window. @p deskmust be an integer number between 0 and the
476  * number of desks (set by ecore_x_netwm_desk_count_set()) -1.
477  *
478  * This function MUST be called by the Window Manager. If a Pagerwants
479  * to switch to naother desktop, it MUST call that function.
480  * @ingroup Ecore_X_NetWM_Group
481  */
482 EAPI void
483 ecore_x_netwm_desk_current_set(Ecore_X_Window root,
484                                unsigned int   desk)
485 {
486    ecore_x_window_prop_card32_set(root,
487                                   ECORE_X_ATOM_NET_CURRENT_DESKTOP,
488                                   &desk, 1);
489 }
490
491 /**
492  * Set the _NET_SHOWING_DESKTOP property.
493  * @param root The root window
494  * @param on   0 to hide the desktop, non 0 to show it.
495  *
496  * Set or unset the desktop in a "showing mode" by sending the
497  * _NET_SHOWING_DESKTOP property to the @p root window. If @p on is 0,
498  * the windows are hidden and the desktop background is displayed and
499  * focused.
500  *
501  * If a Pager wants to enter or leave the mode, it MUST use this
502  * function.
503  * @ingroup Ecore_X_NetWM_Group
504  */
505 EAPI void
506 ecore_x_netwm_showing_desktop_set(Ecore_X_Window root,
507                                   int            on)
508 {
509    uint32_t val;
510
511    val = (on) ? 1 : 0;
512    ecore_x_window_prop_card32_set(root,
513                                   ECORE_X_ATOM_NET_SHOWING_DESKTOP,
514                                   &val, 1);
515 }
516
517 /*
518  * Client status
519  */
520
521 /**
522  * Set the _NET_CLIENT_LIST property.
523  * @param root The root window.
524  * @param p_clients An array of windows.
525  * @param n_clients The number of windows.
526  *
527  * Map all the X windows managed by the window manager from the oldest
528  * to the newest by sending the _NET_CLIENT_LIST property to the
529  * @p root window. The X windows are stored in @p p_clients and their
530  * number in @p n_clients.
531  *
532  * This function SHOULD be called by the Window Manager.
533  * @ingroup Ecore_X_NetWM_Group
534  */
535 EAPI void
536 ecore_x_netwm_client_list_set(Ecore_X_Window  root,
537                               Ecore_X_Window *p_clients,
538                               unsigned int    n_clients)
539 {
540    ecore_x_window_prop_window_set(root,
541                                   ECORE_X_ATOM_NET_CLIENT_LIST,
542                                   p_clients, n_clients);
543 }
544
545 /**
546  * Set the _NET_CLIENT_LIST_STACKING property.
547  * @param root The root window.
548  * @param p_clients An array of windows.
549  * @param n_clients The number of windows.
550  *
551  * Stack all the X windows managed by the window manager from bottom
552  * to top order by sending the _NET_CLIENT_LIST_STACKING property to the
553  * @p root window. The X windows are stored in @p p_clients and their
554  * number in @p n_clients.
555  *
556  * This function SHOULD be called by the Window Manager.
557  * @ingroup Ecore_X_NetWM_Group
558  */
559 EAPI void
560 ecore_x_netwm_client_list_stacking_set(Ecore_X_Window  root,
561                                        Ecore_X_Window *p_clients,
562                                        unsigned int    n_clients)
563 {
564    ecore_x_window_prop_window_set(root,
565                                   ECORE_X_ATOM_NET_CLIENT_LIST_STACKING,
566                                   p_clients, n_clients);
567 }
568
569 /**
570  * Set the _NET_ACTIVE_WINDOW property.
571  * @param root   The root window.
572  * @param window The widow to activate.
573  *
574  * Activate @p window by sending the _NET_ACTIVE_WINDOW property to
575  * the @p root window.
576  *
577  * If a Client wants to activate another window, it MUST call this
578  * function.
579  * @ingroup Ecore_X_NetWM_Group
580  */
581 EAPI void
582 ecore_x_netwm_client_active_set(Ecore_X_Window root,
583                                 Ecore_X_Window window)
584 {
585    ecore_x_window_prop_window_set(root,
586                                   ECORE_X_ATOM_NET_ACTIVE_WINDOW,
587                                   &window, 1);
588 }
589
590 /**
591  * Set the _NET_WM_NAME property.
592  * @param window The widow to activate.
593  * @param name   The title name of the window.
594  *
595  * Set the title name of @p window to @p name by sending the
596  * _NET_WM_NAME property to @p window.
597  *
598  * The Client SHOULD set the title of @p window in UTF-8 encoding. If
599  * set, the Window Manager should use this in preference to WM_NAME.
600  * @ingroup Ecore_X_NetWM_Group
601  */
602 EAPI void
603 ecore_x_netwm_name_set(Ecore_X_Window window,
604                        const char    *name)
605 {
606    _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_NAME, name);
607 }
608
609 /**
610  * Sends the GetProperty request.
611  * @param window The window.
612  * @ingroup Ecore_X_NetWM_Group
613  */
614 EAPI void
615 ecore_x_netwm_name_get_prefetch(Ecore_X_Window window)
616 {
617    xcb_get_property_cookie_t cookie;
618
619    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
620                                        ECORE_X_ATOM_NET_WM_NAME, ECORE_X_ATOM_UTF8_STRING,
621                                        0, 0x7fffffff);
622    _ecore_xcb_cookie_cache(cookie.sequence);
623 }
624
625 /**
626  * Gets the reply of the GetProperty request sent by ecore_x_netwm_name_get_prefetch().
627  * @ingroup Ecore_X_NetWM_Group
628  */
629 EAPI void
630 ecore_x_netwm_name_get_fetch(void)
631 {
632    xcb_get_property_cookie_t cookie;
633    xcb_get_property_reply_t *reply;
634
635    cookie.sequence = _ecore_xcb_cookie_get();
636    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
637    _ecore_xcb_reply_cache(reply);
638 }
639
640 /**
641  * Get the title of a window.
642  * @param window The window.
643  * @param name   The title name.
644  * @return       Returns always 1.
645  *
646  * Retrieve the title name of @p window and store it in @p name. The
647  * function returns always 1.
648  *
649  * To use this function, you must call before, and in order,
650  * ecore_x_netwm_name_get_prefetch(), which sends the GetProperty request,
651  * then ecore_x_netwm_name_get_fetch(), which gets the reply.
652  * @ingroup Ecore_X_NetWM_Group
653  */
654 EAPI int
655 ecore_x_netwm_name_get(Ecore_X_Window window,
656                        char         **name)
657 {
658    if (name)
659      *name = _ecore_x_window_prop_string_utf8_get(window, ECORE_X_ATOM_NET_WM_NAME);
660    return 1;
661 }
662
663 /**
664  * Set the _NET_STARTUP_ID property.
665  * @param window The window.
666  * @param id     The ID name.
667  *
668  * Set the ID @p id used for the startup sequence by sending the
669  * property _NET_STARTUP_ID to @p window. The ID name should be
670  * encoded in UTF-8.
671  *
672  * If a new value for the property is set, the Window Manager
673  * should update the window's status accordingly (update its virtual
674  * desktop, etc.).
675  * @ingroup Ecore_X_NetWM_Group
676  */
677 EAPI void
678 ecore_x_netwm_startup_id_set(Ecore_X_Window window,
679                              const char    *id)
680 {
681    _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_STARTUP_ID, id);
682 }
683
684 /**
685  * Sends the GetProperty request.
686  * @param window The window.
687  * @ingroup Ecore_X_NetWM_Group
688  */
689 EAPI void
690 ecore_x_netwm_startup_id_get_prefetch(Ecore_X_Window window)
691 {
692    xcb_get_property_cookie_t cookie;
693
694    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
695                                        ECORE_X_ATOM_NET_STARTUP_ID, ECORE_X_ATOM_UTF8_STRING,
696                                        0, 0x7fffffff);
697    _ecore_xcb_cookie_cache(cookie.sequence);
698 }
699
700 /**
701  * Gets the reply of the GetProperty request sent by ecore_x_netwm_startup_id_get_prefetch().
702  * @ingroup Ecore_X_NetWM_Group
703  */
704 EAPI void
705 ecore_x_netwm_startup_id_get_fetch(void)
706 {
707    xcb_get_property_cookie_t cookie;
708    xcb_get_property_reply_t *reply;
709
710    cookie.sequence = _ecore_xcb_cookie_get();
711    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
712    _ecore_xcb_reply_cache(reply);
713 }
714
715 /**
716  * Get the startup ID name of a window.
717  * @param window The window
718  * @param id     The ID name
719  * @return       Return always 1.
720  *
721  * To use this function, you must call before, and in order,
722  * ecore_x_netwm_startup_id_get_prefetch(), which sends the GetProperty request,
723  * then ecore_x_netwm_startup_id_get_fetch(), which gets the reply.
724  * @ingroup Ecore_X_NetWM_Group
725  */
726 EAPI int
727 ecore_x_netwm_startup_id_get(Ecore_X_Window window,
728                              char         **id)
729 {
730    if (id)
731      *id = _ecore_x_window_prop_string_utf8_get(window, ECORE_X_ATOM_NET_STARTUP_ID);
732    return 1;
733 }
734
735 /**
736  * Set the _NET_WM_VISIBLE_NAME property.
737  * @param window The widow to activate.
738  * @param name   The title name of the window.
739  *
740  * Set the title name of @p window to @p name by sending the
741  * _NET_WM_VISIBLE_NAME property to @p window, when the Window Manager
742  * displays a window name other than by calling
743  * ecore_x_netwm_name_set().
744  *
745  * The Client SHOULD set the title of @p window in UTF-8
746  * encoding. This function is used for displaying title windows like
747  * [xterm1], [xterm2], ... thereby allowing Pagers to display the same
748  * title as the Window Manager.
749  * @ingroup Ecore_X_NetWM_Group
750  */
751 EAPI void
752 ecore_x_netwm_visible_name_set(Ecore_X_Window window,
753                                const char    *name)
754 {
755    _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
756                                         name);
757 }
758
759 /**
760  * Sends the GetProperty request.
761  * @param window The window.
762  * @ingroup Ecore_X_NetWM_Group
763  */
764 EAPI void
765 ecore_x_netwm_visible_name_get_prefetch(Ecore_X_Window window)
766 {
767    xcb_get_property_cookie_t cookie;
768
769    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
770                                        ECORE_X_ATOM_NET_WM_VISIBLE_NAME, ECORE_X_ATOM_UTF8_STRING,
771                                        0, 0x7fffffff);
772    _ecore_xcb_cookie_cache(cookie.sequence);
773 }
774
775 /**
776  * Gets the reply of the GetProperty request sent by ecore_x_netwm_visible_name_get_prefetch().
777  * @ingroup Ecore_X_NetWM_Group
778  */
779 EAPI void
780 ecore_x_netwm_visible_name_get_fetch(void)
781 {
782    xcb_get_property_cookie_t cookie;
783    xcb_get_property_reply_t *reply;
784
785    cookie.sequence = _ecore_xcb_cookie_get();
786    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
787    _ecore_xcb_reply_cache(reply);
788 }
789
790 /**
791  * Get the visible title of a window.
792  * @param window The window.
793  * @param name   The title name.
794  * @return       Returns always 1.
795  *
796  * Retrieve the visible title name of @p window and store it in @p name. The
797  * function returns always 1.
798  * @param window The window
799  *
800  * To use this function, you must call before, and in order,
801  * ecore_x_netwm_visible_name_get_prefetch(), which sends the GetProperty request,
802  * then ecore_x_netwm_visible_name_get_fetch(), which gets the reply.
803  * @ingroup Ecore_X_NetWM_Group
804  */
805 EAPI int
806 ecore_x_netwm_visible_name_get(Ecore_X_Window window,
807                                char         **name)
808 {
809    if (name)
810      *name = _ecore_x_window_prop_string_utf8_get(window,
811                                                   ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
812    return 1;
813 }
814
815 /**
816  * Set the _NET_WM_ICON_NAME property.
817  * @param window The widow to activate.
818  * @param name   The icon name of the window.
819  *
820  * Set the icon name of @p window to @p name by sending the
821  * _NET_WM_ICON_NAME property to @p window.
822  *
823  * The Client SHOULD set the title of @p window in UTF-8 encoding. If
824  * set, the Window Manager should use this in preference to WM_ICON_NAME.
825  * @ingroup Ecore_X_NetWM_Group
826  */
827 EAPI void
828 ecore_x_netwm_icon_name_set(Ecore_X_Window window,
829                             const char    *name)
830 {
831    _ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_ICON_NAME,
832                                         name);
833 }
834
835 /**
836  * Sends the GetProperty request.
837  * @param window The window.
838  * @ingroup Ecore_X_NetWM_Group
839  */
840 EAPI void
841 ecore_x_netwm_icon_name_get_prefetch(Ecore_X_Window window)
842 {
843    xcb_get_property_cookie_t cookie;
844
845    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
846                                        ECORE_X_ATOM_NET_WM_ICON_NAME, ECORE_X_ATOM_UTF8_STRING,
847                                        0, 0x7fffffff);
848    _ecore_xcb_cookie_cache(cookie.sequence);
849 }
850
851 /**
852  * Gets the reply of the GetProperty request sent by ecore_x_netwm_icon_name_get_prefetch().
853  * @ingroup Ecore_X_NetWM_Group
854  */
855 EAPI void
856 ecore_x_netwm_icon_name_get_fetch(void)
857 {
858    xcb_get_property_cookie_t cookie;
859    xcb_get_property_reply_t *reply;
860
861    cookie.sequence = _ecore_xcb_cookie_get();
862    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
863    _ecore_xcb_reply_cache(reply);
864 }
865
866 /**
867  * Get the icon name of a window.
868  * @param window The window.
869  * @param name   The icon name.
870  * @return       Returns always 1.
871  *
872  * Retrieve the icon name of @p window and store it in @p name. The
873  * function returns always 1.
874  *
875  * To use this function, you must call before, and in order,
876  * ecore_x_netwm_icon_name_get_prefetch(), which sends the GetProperty request,
877  * then ecore_x_netwm_icon_name_get_fetch(), which gets the reply.
878  * @ingroup Ecore_X_NetWM_Group
879  */
880 EAPI int
881 ecore_x_netwm_icon_name_get(Ecore_X_Window window,
882                             char         **name)
883 {
884    if (name)
885      *name = _ecore_x_window_prop_string_utf8_get(window,
886                                                   ECORE_X_ATOM_NET_WM_ICON_NAME);
887    return 1;
888 }
889
890 /**
891  * Set the _NET_WM_VISIBLE_ICON_NAME property.
892  * @param window The widow to activate.
893  * @param name   The title name of the window.
894  *
895  * Set the icon name of @p window to @p name by sending the
896  * _NET_WM_VISIBLE_ICON_NAME property to @p window, when the Window Manager
897  * displays a icon name other than by calling
898  * ecore_x_netwm_icon_name_set().
899  *
900  * The Client SHOULD set the icon name in UTF-8
901  * encoding. The Window Manager MUST use this function is it display
902  * an icon name other than with ecore_x_netwm_icon_name_set().
903  * @ingroup Ecore_X_NetWM_Group
904  */
905 EAPI void
906 ecore_x_netwm_visible_icon_name_set(Ecore_X_Window window,
907                                     const char    *name)
908 {
909    _ecore_x_window_prop_string_utf8_set(window,
910                                         ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
911                                         name);
912 }
913
914 /**
915  * Sends the GetProperty request.
916  * @param window The window.
917  * @ingroup Ecore_X_NetWM_Group
918  */
919 EAPI void
920 ecore_x_netwm_visible_icon_name_get_prefetch(Ecore_X_Window window)
921 {
922    xcb_get_property_cookie_t cookie;
923
924    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
925                                        ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME, ECORE_X_ATOM_UTF8_STRING,
926                                        0, 0x7fffffff);
927    _ecore_xcb_cookie_cache(cookie.sequence);
928 }
929
930 /**
931  * Gets the reply of the GetProperty request sent by ecore_x_netwm_visible_icon_name_get_prefetch().
932  * @ingroup Ecore_X_NetWM_Group
933  */
934 EAPI void
935 ecore_x_netwm_visible_icon_name_get_fetch(void)
936 {
937    xcb_get_property_cookie_t cookie;
938    xcb_get_property_reply_t *reply;
939
940    cookie.sequence = _ecore_xcb_cookie_get();
941    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
942    _ecore_xcb_reply_cache(reply);
943 }
944
945 /**
946  * Get the visible icon name of a window.
947  * @param window The window.
948  * @param name   The icon name.
949  * @return       Returns always 1.
950  *
951  * Retrieve the visible icon name of @p window and store it in
952  * @p name. The function returns always 1.
953  *
954  * To use this function, you must call before, and in order,
955  * ecore_x_netwm_visible_icon_name_get_prefetch(), which sends the GetProperty request,
956  * then ecore_x_netwm_visible_icon_name_get_fetch(), which gets the reply.
957  * @ingroup Ecore_X_NetWM_Group
958  */
959 EAPI int
960 ecore_x_netwm_visible_icon_name_get(Ecore_X_Window window,
961                                     char         **name)
962 {
963    if (name)
964      *name = _ecore_x_window_prop_string_utf8_get(window,
965                                                   ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
966    return 1;
967 }
968
969 /**
970  * Set the _NET_WM_DESKTOP property.
971  * @param window The window.
972  * @param desk   The desktop index.
973  *
974  * Set on which desktop the @p window is in by sending the
975  * _NET_WM_DESKTOP property to @p window. @p desk is the index of
976  * the desktop, starting from 0. To indicate that the window should
977  * appear on all desktops, @p desk must be equal to 0xFFFFFFFF.
978  *
979  * A Client MAY choose not to set this property, in which case the
980  * Window Manager SHOULD place it as it wishes.
981  *
982  * The Window Manager should honor _NET_WM_DESKTOP whenever a
983  * withdrawn window requests to be mapped.
984  *
985  * A Client can request a change of desktop for a non-withdrawn window
986  * by sending a _NET_WM_DESKTOP client message to the root window.
987  * @ingroup Ecore_X_NetWM_Group
988  */
989 EAPI void
990 ecore_x_netwm_desktop_set(Ecore_X_Window window,
991                           unsigned int   desk)
992 {
993    ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
994 }
995
996 /**
997  * Sends the GetProperty request.
998  * @param window The window.
999  * @ingroup Ecore_X_NetWM_Group
1000  */
1001 EAPI void
1002 ecore_x_netwm_desktop_get_prefetch(Ecore_X_Window window)
1003 {
1004    xcb_get_property_cookie_t cookie;
1005
1006    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1007                                        ECORE_X_ATOM_NET_WM_DESKTOP, ECORE_X_ATOM_CARDINAL,
1008                                        0, 0x7fffffff);
1009    _ecore_xcb_cookie_cache(cookie.sequence);
1010 }
1011
1012 /**
1013  * Gets the reply of the GetProperty request sent by ecore_x_netwm_desktop_get_prefetch().
1014  * @ingroup Ecore_X_NetWM_Group
1015  */
1016 EAPI void
1017 ecore_x_netwm_desktop_get_fetch(void)
1018 {
1019    xcb_get_property_cookie_t cookie;
1020    xcb_get_property_reply_t *reply;
1021
1022    cookie.sequence = _ecore_xcb_cookie_get();
1023    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1024    _ecore_xcb_reply_cache(reply);
1025 }
1026
1027 /**
1028  * Get the visible icon name of a window.
1029  * @param window The window.
1030  * @param desk   The desktop index.
1031  * @return       1 on success, 0 otherwise.
1032  *
1033  * Retrieve the desktop index in which @p window is displayed and
1034  * store it in @p desk. If @p desk value is 0xFFFFFFFF, the window
1035  * appears on all desktops. The function returns 1 on success, 0
1036  * otherwise.
1037  *
1038  * To use this function, you must call before, and in order,
1039  * ecore_x_netwm_desktop_get_prefetch(), which sends the GetProperty request,
1040  * then ecore_x_netwm_desktop_get_fetch(), which gets the reply.
1041  * @ingroup Ecore_X_NetWM_Group
1042  */
1043 EAPI int
1044 ecore_x_netwm_desktop_get(Ecore_X_Window window,
1045                           unsigned int *desk)
1046 {
1047    int      ret;
1048    uint32_t tmp;
1049
1050    ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_DESKTOP,
1051                                         &tmp, 1);
1052
1053    if (desk) *desk = tmp;
1054    return (ret == 1) ? 1 : 0;
1055 }
1056
1057 /**
1058  * Set the _NET_WM_STRUT property.
1059  * @param window The window
1060  * @param left   The number of pixels at the left of the screen.
1061  * @param right  The number of pixels at the right of the screen.
1062  * @param top    The number of pixels at the top of the screen.
1063  * @param bottom The number of pixels at the bottom of the screen.
1064  *
1065  * Set space at the edje of the screen by sending the _NET_WM_STRUT
1066  * property to @p window if @p window is to reserve that space.
1067  * @p left, @p right, @p top and @p bottom are respectively the number
1068  * of pixels at the left, right, top and bottom of the screen.
1069  *
1070  * This property is deprecated and ecore_x_netwm_strut_partial_set()
1071  * should be used instead. However, Clients MAY set this property in
1072  * addition to _NET_WM_STRUT_PARTIAL to ensure backward compatibility
1073  * with Window Managers supporting older versions of the
1074  * Specification.
1075  * @ingroup Ecore_X_NetWM_Group
1076  */
1077 EAPI void
1078 ecore_x_netwm_strut_set(Ecore_X_Window window,
1079                         int            left,
1080                         int            right,
1081                         int            top,
1082                         int            bottom)
1083 {
1084    uint32_t strut[4];
1085
1086    strut[0] = left;
1087    strut[1] = right;
1088    strut[2] = top;
1089    strut[3] = bottom;
1090    ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
1091 }
1092
1093 /**
1094  * Sends the GetProperty request.
1095  * @param window The window.
1096  * @ingroup Ecore_X_NetWM_Group
1097  */
1098 EAPI void
1099 ecore_x_netwm_strut_get_prefetch(Ecore_X_Window window)
1100 {
1101    xcb_get_property_cookie_t cookie;
1102
1103    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1104                                        ECORE_X_ATOM_NET_WM_STRUT, ECORE_X_ATOM_CARDINAL,
1105                                        0, 0x7fffffff);
1106    _ecore_xcb_cookie_cache(cookie.sequence);
1107 }
1108
1109 /**
1110  * Gets the reply of the GetProperty request sent by ecore_x_strut_get_prefetch().
1111  * @ingroup Ecore_X_NetWM_Group
1112  */
1113 EAPI void
1114 ecore_x_netwm_strut_get_fetch(void)
1115 {
1116    xcb_get_property_cookie_t cookie;
1117    xcb_get_property_reply_t *reply;
1118
1119    cookie.sequence = _ecore_xcb_cookie_get();
1120    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1121    _ecore_xcb_reply_cache(reply);
1122 }
1123
1124 /*
1125  * _NET_WM_STRUT is deprecated
1126  */
1127
1128 /**
1129  * Get the space at the edje of the screen.
1130  * @param window The window
1131  * @param left   The number of pixels at the left of the screen.
1132  * @param right  The number of pixels at the right of the screen.
1133  * @param top    The number of pixels at the top of the screen.
1134  * @param bottom The number of pixels at the bottom of the screen.
1135  * @return       1 on success, 0 otherwise.
1136  *
1137  * Retrieve the space at the edje of the screen if @p window is to
1138  * reserve such space. The number of pixels at the left, right, top
1139  * and bottom of the screen are respectively stored in @p left,
1140  * @p right, @p top and @p bottom. This function returns 1 on success,
1141  * 0 otherwise.
1142  *
1143  * This property is deprecated. See ecore_x_netwm_strut_set() for more
1144  * informations.
1145  *
1146  * To use this function, you must call before, and in order,
1147  * ecore_x_netwm_strut_get_prefetch(), which sends the GetProperty request,
1148  * then ecore_x_netwm_strut_get_fetch(), which gets the reply.
1149  * @ingroup Ecore_X_NetWM_Group
1150  */
1151 EAPI int
1152 ecore_x_netwm_strut_get(Ecore_X_Window window,
1153                         int           *left,
1154                         int           *right,
1155                         int           *top,
1156                         int           *bottom)
1157 {
1158    uint32_t strut[4];
1159    int      ret = 0;
1160
1161    ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
1162    if (ret != 4)
1163      return 0;
1164
1165    if (left)   *left   = strut[0];
1166    if (right)  *right  = strut[1];
1167    if (top)    *top    = strut[2];
1168    if (bottom) *bottom = strut[3];
1169
1170    return 1;
1171 }
1172
1173 /**
1174  * Set the _NET_WM_STRUT_PARTIAL property.
1175  * @param window         The window
1176  * @param left           The number of pixels at the left of the screen.
1177  * @param right          The number of pixels at the right of the screen.
1178  * @param top            The number of pixels at the top of the screen.
1179  * @param bottom         The number of pixels at the bottom of the screen.
1180  * @param left_start_y   The number of pixels.
1181  * @param left_end_y     The number of pixels.
1182  * @param right_start_y  The number of pixels.
1183  * @param right_end_y    The number of pixels.
1184  * @param top_start_x    The number of pixels.
1185  * @param top_end_x      The number of pixels.
1186  * @param bottom_start_x The number of pixels.
1187  * @param bottom_end_x   The number of pixels.
1188  *
1189  * Set space at the edje of the screen by sending the
1190  * _NET_WM_STRUT_PARTIAL property to @p window if @p window is to
1191  * reserve that space. @p left, @p right, @p top and @p bottom are
1192  * respectively the number of pixels at the left, right, top and
1193  * bottom of the screen.
1194  *
1195  * TODO: more description for that function.
1196  * @ingroup Ecore_X_NetWM_Group
1197  */
1198 EAPI void
1199 ecore_x_netwm_strut_partial_set(Ecore_X_Window window,
1200                                 int            left,
1201                                 int            right,
1202                                 int            top,
1203                                 int            bottom,
1204                                 int            left_start_y,
1205                                 int            left_end_y,
1206                                 int            right_start_y,
1207                                 int            right_end_y,
1208                                 int            top_start_x,
1209                                 int            top_end_x,
1210                                 int            bottom_start_x,
1211                                 int            bottom_end_x)
1212 {
1213    unsigned int strut[12];
1214
1215    strut[0] = left;
1216    strut[1] = right;
1217    strut[2] = top;
1218    strut[3] = bottom;
1219    strut[4] = left_start_y;
1220    strut[5] = left_end_y;
1221    strut[6] = right_start_y;
1222    strut[7] = right_end_y;
1223    strut[8] = top_start_x;
1224    strut[9] = top_end_x;
1225    strut[10] = bottom_start_x;
1226    strut[11] = bottom_end_x;
1227    ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12);
1228 }
1229
1230 /**
1231  * Sends the GetProperty request.
1232  * @param window The window.
1233  * @ingroup Ecore_X_NetWM_Group
1234  */
1235 EAPI void
1236 ecore_x_netwm_strut_partial_get_prefetch(Ecore_X_Window window)
1237 {
1238    xcb_get_property_cookie_t cookie;
1239
1240    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1241                                        ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, ECORE_X_ATOM_CARDINAL,
1242                                        0, 0x7fffffff);
1243    _ecore_xcb_cookie_cache(cookie.sequence);
1244 }
1245
1246 /**
1247  * Gets the reply of the GetProperty request sent by ecore_x_strut_partial_get_prefetch().
1248  * @ingroup Ecore_X_NetWM_Group
1249  */
1250 EAPI void
1251 ecore_x_netwm_strut_partial_get_fetch(void)
1252 {
1253    xcb_get_property_cookie_t cookie;
1254    xcb_get_property_reply_t *reply;
1255
1256    cookie.sequence = _ecore_xcb_cookie_get();
1257    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1258    _ecore_xcb_reply_cache(reply);
1259 }
1260
1261 /**
1262  * Get the space at the edje of the screen of a window.
1263  * @param window         The window
1264  * @param left           The number of pixels at the left of the screen.
1265  * @param right          The number of pixels at the right of the screen.
1266  * @param top            The number of pixels at the top of the screen.
1267  * @param bottom         The number of pixels at the bottom of the screen.
1268  * @param left_start_y   The number of pixels.
1269  * @param left_end_y     The number of pixels.
1270  * @param right_start_y  The number of pixels.
1271  * @param right_end_y    The number of pixels.
1272  * @param top_start_x    The number of pixels.
1273  * @param top_end_x      The number of pixels.
1274  * @param bottom_start_x The number of pixels.
1275  * @param bottom_end_x   The number of pixels.
1276  *
1277  * Retrieve the space at the edje of the screen if @p window is to
1278  * reserve such space. The number of pixels at the left, right, top
1279  * and bottom of the screen are respectively stored in @p left,
1280  * @p right, @p top and @p bottom. This function returns 1 on success,
1281  * 0 otherwise.
1282  *
1283  * TODO: more description for that function.
1284  *
1285  * To use this function, you must call before, and in order,
1286  * ecore_x_netwm_strut_partial_get_prefetch(), which sends the GetProperty request,
1287  * then ecore_x_netwm_strut_partial_get_fetch(), which gets the reply.
1288  * @ingroup Ecore_X_NetWM_Group
1289  */
1290 EAPI int
1291 ecore_x_netwm_strut_partial_get(Ecore_X_Window window,
1292                                 int           *left,
1293                                 int           *right,
1294                                 int           *top,
1295                                 int           *bottom,
1296                                 int           *left_start_y,
1297                                 int           *left_end_y,
1298                                 int           *right_start_y,
1299                                 int           *right_end_y,
1300                                 int           *top_start_x,
1301                                 int           *top_end_x,
1302                                 int           *bottom_start_x,
1303                                 int           *bottom_end_x)
1304 {
1305    uint32_t strut[12];
1306    int      ret = 0;
1307
1308    ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12);
1309    if (ret != 12)
1310      return 0;
1311
1312    if (left)           *left           = strut[0];
1313    if (right)          *right          = strut[1];
1314    if (top)            *top            = strut[2];
1315    if (bottom)         *bottom         = strut[3];
1316    if (left_start_y)   *left_start_y   = strut[4];
1317    if (left_end_y)     *left_end_y     = strut[5];
1318    if (right_start_y)  *right_start_y  = strut[6];
1319    if (right_end_y)    *right_end_y    = strut[7];
1320    if (top_start_x)    *top_start_x    = strut[8];
1321    if (top_end_x)      *top_end_x      = strut[9];
1322    if (bottom_start_x) *bottom_start_x = strut[10];
1323    if (bottom_end_x)   *bottom_end_x   = strut[11];
1324    return 1;
1325 }
1326
1327 /**
1328  * Sends the GetProperty request.
1329  * @param window The window.
1330  * @ingroup Ecore_X_NetWM_Group
1331  */
1332 EAPI void
1333 ecore_x_netwm_icons_get_prefetch(Ecore_X_Window window)
1334 {
1335    xcb_get_property_cookie_t cookie;
1336
1337    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1338                                        ECORE_X_ATOM_NET_WM_ICON, ECORE_X_ATOM_CARDINAL,
1339                                        0, 0x7fffffff);
1340    _ecore_xcb_cookie_cache(cookie.sequence);
1341 }
1342
1343 /**
1344  * Gets the reply of the GetProperty request sent by ecore_x_icons_get_prefetch().
1345  * @ingroup Ecore_X_NetWM_Group
1346  */
1347 EAPI void
1348 ecore_x_netwm_icons_get_fetch(void)
1349 {
1350    xcb_get_property_cookie_t cookie;
1351    xcb_get_property_reply_t *reply;
1352
1353    cookie.sequence = _ecore_xcb_cookie_get();
1354    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1355    _ecore_xcb_reply_cache(reply);
1356 }
1357
1358 /**
1359  * Retrieve hte possible icons of a window.
1360  * @param window The window
1361  * @param icon   An array of icons.
1362  * @param num    The number of icons.
1363  * @return       1 on success, 0 otherwise.
1364  *
1365  * Retrieve an array of possible icons of @p window. The icons are
1366  * stored in @p icon and their number in @p num.
1367  *
1368  * To use this function, you must call before, and in order,
1369  * ecore_x_netwm_icons_get_prefetch(), which sends the GetProperty request,
1370  * then ecore_x_netwm_icons_get_fetch(), which gets the reply.
1371  * @ingroup Ecore_X_NetWM_Group
1372  */
1373 EAPI int
1374 ecore_x_netwm_icons_get(Ecore_X_Window window,
1375                         Ecore_X_Icon **icon,
1376                         int           *num)
1377 {
1378    uint32_t *data;
1379    uint32_t *p;
1380    uint32_t *src;
1381    uint32_t  icons;
1382    uint32_t  len;
1383    uint32_t  i;
1384    int       num_ret;
1385
1386    if (num) *num = 0UL;
1387    if (icon) *icon = NULL;
1388
1389    num_ret = ecore_x_window_prop_card32_list_get(window,
1390                                                  ECORE_X_ATOM_NET_WM_ICON,
1391                                                  &data);
1392    if ((num_ret <= 0) || !data)
1393      return 0;
1394
1395    if (num_ret < 2)
1396      {
1397         free(data);
1398         return 0;
1399      }
1400
1401    /* Check how many icons there are */
1402    icons = 0;
1403    p = data;
1404    while (p)
1405      {
1406         len = p[0] * p[1];
1407         p += (len + 2);
1408         if ((p - data) > num_ret)
1409           {
1410              free(data);
1411              return 0;
1412           }
1413         icons++;
1414
1415         if ((p - data) == num_ret)
1416           p = NULL;
1417      }
1418    if (num) *num = icons;
1419
1420    /* If the user doesn't want the icons, return */
1421    if (!icon)
1422      {
1423         free(data);
1424         return 1;
1425      }
1426
1427    /* Allocate memory */
1428    *icon = malloc(icons * sizeof(Ecore_X_Icon));
1429    if (!(*icon))
1430      {
1431         free(data);
1432         return 0;
1433      }
1434
1435    /* Fetch the icons */
1436    p = data;
1437    for (i = 0; i < icons; i++)
1438      {
1439         uint32_t *ps, *pd, *pe;
1440
1441         len = p[0] * p[1];
1442         ((*icon)[i]).width = p[0];
1443         ((*icon)[i]).height = p[1];
1444         src = &(p[2]);
1445         ((*icon)[i]).data = malloc(len * sizeof(uint32_t));
1446         if (!((*icon)[i]).data)
1447           {
1448              while (i)
1449                free(((*icon)[--i]).data);
1450              free(*icon);
1451              free(data);
1452              return 0;
1453           }
1454
1455         pd = ((*icon)[i]).data;
1456         ps = src;
1457         pe = ps + len;
1458         for (; ps < pe; ps++)
1459           {
1460              uint32_t r, g, b, a;
1461
1462              a = (*ps >> 24) & 0xff;
1463              r = (((*ps >> 16) & 0xff) * a) / 255;
1464              g = (((*ps >>  8) & 0xff) * a) / 255;
1465              b = (((*ps      ) & 0xff) * a) / 255;
1466              *pd = (a << 24) | (r << 16) | (g << 8) | (b);
1467              pd++;
1468           }
1469         p += (len + 2);
1470      }
1471
1472    free(data);
1473
1474    return 1;
1475 }
1476
1477 /**
1478  * Set the _NET_WM_ICON_GEOMETRY property.
1479  * @param window The window.
1480  * @param x      The X coordinate of the icon.
1481  * @param y      The Y coordinate of the icon.
1482  * @param width  The width of the icon.
1483  * @param height The height of the icon.
1484  *
1485  * Set the geometry of the icon of @p window by sending the
1486  * _NET_WM_ICON_GEOMETRY property to @p window. @p x, @p y, @p width
1487  * and @p height specify respectively the X coordinate, the Y
1488  * coordinate, the width and the height of the icon.
1489  *
1490  * Stand alone tools like a taskbar or an iconbox MAY use this
1491  * function. This functions makes possible for a Window Manager to
1492  * display a nice animation like morphing the window into its icon.
1493  * @ingroup Ecore_X_NetWM_Group
1494  */
1495 EAPI void
1496 ecore_x_netwm_icon_geometry_set(Ecore_X_Window window,
1497                                 int            x,
1498                                 int            y,
1499                                 int            width,
1500                                 int            height)
1501 {
1502    uint32_t geometry[4];
1503
1504    geometry[0] = (uint32_t)x;
1505    geometry[1] = (uint32_t)y;
1506    geometry[2] = (uint32_t)width;
1507    geometry[3] = (uint32_t)height;
1508    ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4);
1509 }
1510
1511 /**
1512  * Sends the GetProperty request.
1513  * @param window The window.
1514  * @ingroup Ecore_X_NetWM_Group
1515  */
1516 EAPI void
1517 ecore_x_netwm_icon_geometry_get_prefetch(Ecore_X_Window window)
1518 {
1519    xcb_get_property_cookie_t cookie;
1520
1521    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1522                                        ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, ECORE_X_ATOM_CARDINAL,
1523                                        0, 0x7fffffff);
1524    _ecore_xcb_cookie_cache(cookie.sequence);
1525 }
1526
1527 /**
1528  * Gets the reply of the GetProperty request sent by ecore_x_icon_geometry_get_prefetch().
1529  * @ingroup Ecore_X_NetWM_Group
1530  */
1531 EAPI void
1532 ecore_x_netwm_icon_geometry_get_fetch(void)
1533 {
1534    xcb_get_property_cookie_t cookie;
1535    xcb_get_property_reply_t *reply;
1536
1537    cookie.sequence = _ecore_xcb_cookie_get();
1538    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1539    _ecore_xcb_reply_cache(reply);
1540 }
1541
1542 /**
1543  * Get the geometry of an icon.
1544  * @param window The window
1545  * @param x      x
1546  * @param x      The X coordinate of the icon.
1547  * @param y      The Y coordinate of the icon.
1548  * @param width  The width of the icon.
1549  * @param height The height of the icon.
1550  * @return       1 on success, 0 othrwise.
1551  *
1552  * Retrieve the geometry of the icon of @p window. The geometry is
1553  * stored in @p x, @p y, @p width and @p height. The function returns
1554  * 1 on success, 0 otherwise.
1555  *
1556  * To use this function, you must call before, and in order,
1557  * ecore_x_netwm_icon_geometry_get_prefetch(), which sends the GetProperty request,
1558  * then ecore_x_netwm_icon_geometry_get_fetch(), which gets the reply.
1559  * @ingroup Ecore_X_NetWM_Group
1560  */
1561 EAPI int
1562 ecore_x_netwm_icon_geometry_get(Ecore_X_Window window,
1563                                 int           *x,
1564                                 int           *y,
1565                                 int           *width,
1566                                 int           *height)
1567 {
1568    uint32_t geometry[4];
1569    int      ret;
1570
1571    ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4);
1572    if (ret != 4)
1573      return 0;
1574
1575    if (x)      *x      = geometry[0];
1576    if (y)      *y      = geometry[1];
1577    if (width)  *width  = geometry[2];
1578    if (height) *height = geometry[3];
1579
1580    return 1;
1581 }
1582
1583 /**
1584  * Set the _NET_WM_PID property.
1585  * @param window The window.
1586  * @param pid    The process ID.
1587  *
1588  * Set the process ID of the client owning @p window by sending the
1589  * _NET_WM_PID property to @p window.
1590  *
1591  * This function MAY be used by the Window Manager to kill windows
1592  * which do not respond to the _NET_WM_PING protocol.
1593  *
1594  * If _NET_WM_PID is set, the ICCCM-specified property
1595  * WM_CLIENT_MACHINE MUST also be set.
1596  * @ingroup Ecore_X_NetWM_Group
1597  */
1598 EAPI void
1599 ecore_x_netwm_pid_set(Ecore_X_Window window,
1600                       int            pid)
1601 {
1602    unsigned int tmp;
1603
1604    tmp = pid;
1605    ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_PID,
1606                                   &tmp, 1);
1607 }
1608
1609 /**
1610  * Sends the GetProperty request.
1611  * @param window The window.
1612  * @ingroup Ecore_X_NetWM_Group
1613  */
1614 EAPI void
1615 ecore_x_netwm_pid_get_prefetch(Ecore_X_Window window)
1616 {
1617    xcb_get_property_cookie_t cookie;
1618
1619    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1620                                        ECORE_X_ATOM_NET_WM_PID, ECORE_X_ATOM_CARDINAL,
1621                                        0, 0x7fffffff);
1622    _ecore_xcb_cookie_cache(cookie.sequence);
1623 }
1624
1625 /**
1626  * Gets the reply of the GetProperty request sent by ecore_x_pid_get_prefetch().
1627  * @ingroup Ecore_X_NetWM_Group
1628  */
1629 EAPI void
1630 ecore_x_netwm_pid_get_fetch(void)
1631 {
1632    xcb_get_property_cookie_t cookie;
1633    xcb_get_property_reply_t *reply;
1634
1635    cookie.sequence = _ecore_xcb_cookie_get();
1636    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1637    _ecore_xcb_reply_cache(reply);
1638 }
1639
1640 /**
1641  * Get the process ID of a client window.
1642  * @param window The window.
1643  * @param pid    The process ID.
1644  * @return       1 on success, 0 otherwise.
1645  *
1646  * Retrieve the process ID of @p window and store it in @p pid. This
1647  * function returns 1 on success, 0 otherwise.
1648  *
1649  * To use this function, you must call before, and in order,
1650  * ecore_x_netwm_pid_get_prefetch(), which sends the GetProperty request,
1651  * then ecore_x_netwm_pid_get_fetch(), which gets the reply.
1652  * @ingroup Ecore_X_NetWM_Group
1653  */
1654 EAPI int
1655 ecore_x_netwm_pid_get(Ecore_X_Window window,
1656                       int           *pid)
1657 {
1658    int ret;
1659    uint32_t tmp;
1660
1661    ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_PID,
1662                                         &tmp, 1);
1663    if (pid) *pid = tmp;
1664
1665    return (ret == 1) ? 1 : 0;
1666 }
1667
1668 /**
1669  * Set the _NET_WM_HANDLED_ICONS property.
1670  * @param window The window.
1671  *
1672  * Indicate to the Window Manager that it does not need to provide
1673  * icons for the iconified @p window by sending the
1674  * _NET_WM_HANDLED_ICONS property to @p window.
1675  *
1676  * This function can be used by a Pager on one of its own toplevel
1677  * windows (for example if the Client is a taskbar and provides
1678  * buttons for iconified windows).
1679  * @ingroup Ecore_X_NetWM_Group
1680  */
1681 EAPI void
1682 ecore_x_netwm_handled_icons_set(Ecore_X_Window window)
1683 {
1684    ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
1685                                   NULL, 0);
1686 }
1687
1688 /**
1689  * Sends the GetProperty request.
1690  * @param window The window.
1691  * @ingroup Ecore_X_NetWM_Group
1692  */
1693 EAPI void
1694 ecore_x_netwm_handled_icons_get_prefetch(Ecore_X_Window window)
1695 {
1696    xcb_get_property_cookie_t cookie;
1697
1698    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1699                                        ECORE_X_ATOM_NET_WM_HANDLED_ICONS, ECORE_X_ATOM_CARDINAL,
1700                                        0, 0x7fffffff);
1701    _ecore_xcb_cookie_cache(cookie.sequence);
1702 }
1703
1704 /**
1705  * Gets the reply of the GetProperty request sent by ecore_x_handled_icons_get_prefetch().
1706  * @ingroup Ecore_X_NetWM_Group
1707  */
1708 EAPI void
1709 ecore_x_netwm_handled_icons_get_fetch(void)
1710 {
1711    xcb_get_property_cookie_t cookie;
1712    xcb_get_property_reply_t *reply;
1713
1714    cookie.sequence = _ecore_xcb_cookie_get();
1715    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1716    _ecore_xcb_reply_cache(reply);
1717 }
1718
1719 /**
1720  * Return wheter the Client handles icons or not.
1721  * @param window The window.
1722  * @return       1 if icons are handled, 0 otherwise.
1723  *
1724  * Return whether the client handles icons or not if @p window is
1725  * iconified.
1726  *
1727  * To use this function, you must call before, and in order,
1728  * ecore_x_netwm_handled_icons_get_prefetch(), which sends the GetProperty request,
1729  * then ecore_x_netwm_handled_icons_get_fetch(), which gets the reply.
1730  * @ingroup Ecore_X_NetWM_Group
1731  */
1732 EAPI int
1733 ecore_x_netwm_handled_icons_get(Ecore_X_Window window)
1734 {
1735    int ret = 0;
1736    ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
1737                                         NULL, 0);
1738    return (ret == 0) ? 1 : 0;
1739 }
1740
1741 /**
1742  * Set the _NET_WM_USER_TIME property.
1743  * @param window The window.
1744  * @param time   The last user activity time in the window.
1745  *
1746  * Set the XServer time at which last user activity in @p window took
1747  * place by sending the _NET_WM_USER_TIME property to @p window. @p
1748  * time contains that XServer time in seconds.
1749  *
1750  * This function allows a Window Manager to alter the focus, stacking,
1751  * and/or placement behavior of windows when they are mapped depending
1752  * on whether the new window was created by a user action or is a
1753  * "pop-up" window activated by a timer or some other event.
1754  * @ingroup Ecore_X_NetWM_Group
1755  */
1756 EAPI void
1757 ecore_x_netwm_user_time_set(Ecore_X_Window window,
1758                             unsigned int   time)
1759 {
1760    ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_USER_TIME,
1761                                   &time, 1);
1762 }
1763
1764 /**
1765  * Sends the GetProperty request.
1766  * @param window The window.
1767  * @ingroup Ecore_X_NetWM_Group
1768  */
1769 EAPI void
1770 ecore_x_netwm_user_time_get_prefetch(Ecore_X_Window window)
1771 {
1772    xcb_get_property_cookie_t cookie;
1773
1774    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1775                                        ECORE_X_ATOM_NET_WM_USER_TIME, ECORE_X_ATOM_CARDINAL,
1776                                        0, 0x7fffffff);
1777    _ecore_xcb_cookie_cache(cookie.sequence);
1778 }
1779
1780 /**
1781  * Gets the reply of the GetProperty request sent by ecore_x_netwm_user_time_get_prefetch().
1782  * @ingroup Ecore_X_NetWM_Group
1783  */
1784 EAPI void
1785 ecore_x_netwm_user_time_get_fetch(void)
1786 {
1787    xcb_get_property_cookie_t cookie;
1788    xcb_get_property_reply_t *reply;
1789
1790    cookie.sequence = _ecore_xcb_cookie_get();
1791    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1792    _ecore_xcb_reply_cache(reply);
1793 }
1794
1795 /**
1796  * Get the last user activity time in the window.
1797  * @param window The window.
1798  * @param time   The returned time.
1799  * @return       1 on success, 0 otherwise.
1800  *
1801  * Return the XServer time at which last user activity in @p window
1802  * took place. The time is stored in @p time.
1803  *
1804  * To use this function, you must call before, and in order,
1805  * ecore_x_netwm_user_time_get_prefetch(), which sends the GetProperty request,
1806  * then ecore_x_netwm_user_time_get_fetch(), which gets the reply.
1807  * @ingroup Ecore_X_NetWM_Group
1808  */
1809 EAPI int
1810 ecore_x_netwm_user_time_get(Ecore_X_Window window,
1811                             unsigned int  *time)
1812 {
1813    int ret;
1814    uint32_t tmp;
1815
1816    ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_USER_TIME,
1817                                         &tmp, 1);
1818    if (time) *time = tmp;
1819    return (ret == 1) ? 1 : 0;
1820 }
1821
1822 Ecore_X_Window_State
1823 _ecore_x_netwm_state_get(Ecore_X_Atom a)
1824 {
1825    if (a == ECORE_X_ATOM_NET_WM_STATE_MODAL)
1826      return ECORE_X_WINDOW_STATE_MODAL;
1827    else if (a == ECORE_X_ATOM_NET_WM_STATE_STICKY)
1828      return ECORE_X_WINDOW_STATE_STICKY;
1829    else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
1830      return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
1831    else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
1832      return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
1833    else if (a == ECORE_X_ATOM_NET_WM_STATE_SHADED)
1834      return ECORE_X_WINDOW_STATE_SHADED;
1835    else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
1836      return ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
1837    else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
1838      return ECORE_X_WINDOW_STATE_SKIP_PAGER;
1839    else if (a == ECORE_X_ATOM_NET_WM_STATE_HIDDEN)
1840      return ECORE_X_WINDOW_STATE_HIDDEN;
1841    else if (a == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
1842      return ECORE_X_WINDOW_STATE_FULLSCREEN;
1843    else if (a == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
1844      return ECORE_X_WINDOW_STATE_ABOVE;
1845    else if (a == ECORE_X_ATOM_NET_WM_STATE_BELOW)
1846      return ECORE_X_WINDOW_STATE_BELOW;
1847    else if (a == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
1848      return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION;
1849    else
1850      return ECORE_X_WINDOW_STATE_UNKNOWN;
1851 }
1852
1853 static Ecore_X_Atom
1854 _ecore_x_netwm_state_atom_get(Ecore_X_Window_State s)
1855 {
1856    switch(s)
1857      {
1858       case ECORE_X_WINDOW_STATE_MODAL:
1859          return ECORE_X_ATOM_NET_WM_STATE_MODAL;
1860       case ECORE_X_WINDOW_STATE_STICKY:
1861          return ECORE_X_ATOM_NET_WM_STATE_STICKY;
1862       case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
1863          return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
1864       case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
1865          return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
1866       case ECORE_X_WINDOW_STATE_SHADED:
1867          return ECORE_X_ATOM_NET_WM_STATE_SHADED;
1868       case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
1869          return ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
1870       case ECORE_X_WINDOW_STATE_SKIP_PAGER:
1871          return ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
1872       case ECORE_X_WINDOW_STATE_HIDDEN:
1873          return ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
1874       case ECORE_X_WINDOW_STATE_FULLSCREEN:
1875          return ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
1876       case ECORE_X_WINDOW_STATE_ABOVE:
1877          return ECORE_X_ATOM_NET_WM_STATE_ABOVE;
1878       case ECORE_X_WINDOW_STATE_BELOW:
1879          return ECORE_X_ATOM_NET_WM_STATE_BELOW;
1880       case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION:
1881          return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
1882       default:
1883          return 0;
1884      }
1885 }
1886
1887 /**
1888  * Set the _NET_WM_STATE property.
1889  * @param window The window.
1890  * @param state  An array of window hints.
1891  * @param num    The number of hints.
1892  *
1893  * Set a list of hints describing @p window state by sending the
1894  * _NET_WM_STATE property to @p window. The hints are stored in the
1895  * array @p state. @p num must contain the number of hints.
1896  *
1897  * The Window Manager SHOULD honor _NET_WM_STATE whenever a withdrawn
1898  * window requests to be mapped. A Client wishing to change the state
1899  * of a window MUST send a _NET_WM_STATE client message to the root
1900  * window. The Window Manager MUST keep this property updated to
1901  * reflect the current state of the window.
1902  * @ingroup Ecore_X_NetWM_Group
1903  */
1904 EAPI void
1905 ecore_x_netwm_window_state_set(Ecore_X_Window        window,
1906                                Ecore_X_Window_State *state,
1907                                unsigned int          num)
1908 {
1909    Ecore_X_Atom  *set;
1910    uint32_t       i;
1911
1912    if (!num)
1913      {
1914         ecore_x_window_prop_property_del(window, ECORE_X_ATOM_NET_WM_STATE);
1915         return;
1916      }
1917
1918    set = malloc(num * sizeof(Ecore_X_Atom));
1919    if (!set) return;
1920
1921    for (i = 0; i < num; i++)
1922      set[i] = _ecore_x_netwm_state_atom_get(state[i]);
1923
1924    ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_STATE, set, num);
1925
1926    free(set);
1927 }
1928
1929 /**
1930  * Sends the GetProperty request.
1931  * @param window The window.
1932  * @ingroup Ecore_X_NetWM_Group
1933  */
1934 EAPI void
1935 ecore_x_netwm_window_state_get_prefetch(Ecore_X_Window window)
1936 {
1937    xcb_get_property_cookie_t cookie;
1938
1939    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
1940                                        ECORE_X_ATOM_NET_WM_STATE, ECORE_X_ATOM_ATOM,
1941                                        0, 0x7fffffff);;
1942    _ecore_xcb_cookie_cache(cookie.sequence);
1943 }
1944
1945 /**
1946  * Gets the reply of the GetProperty request sent by ecore_x_window_state_get_prefetch().
1947  * @ingroup Ecore_X_NetWM_Group
1948  */
1949 EAPI void
1950 ecore_x_netwm_window_state_get_fetch(void)
1951 {
1952    xcb_get_property_cookie_t cookie;
1953    xcb_get_property_reply_t *reply;
1954
1955    cookie.sequence = _ecore_xcb_cookie_get();
1956    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
1957    _ecore_xcb_reply_cache(reply);
1958 }
1959
1960 /**
1961  * Get the hints describing the window state.
1962  * @param window The window.
1963  * @param state  The returned hins.
1964  * @param num    The number of hints.
1965  * @return       1 on success, 0 otherwise.
1966  *
1967  * Retrieve the hints describing @p window state. The state is
1968  * returned in @p state. The nummber of hints is stored in @p
1969  * num. This function returns 1 on success, 0 otherwise.
1970  *
1971  * To use this function, you must call before, and in order,
1972  * ecore_x_netwm_window_state_get_prefetch(), which sends the GetProperty request,
1973  * then ecore_x_netwm_window_state_get_fetch(), which gets the reply.
1974  * @ingroup Ecore_X_NetWM_Group
1975  */
1976 EAPI int
1977 ecore_x_netwm_window_state_get(Ecore_X_Window         window,
1978                                Ecore_X_Window_State **state,
1979                                unsigned int          *num)
1980 {
1981    Ecore_X_Atom *atoms;
1982    int           num_ret;
1983    int           i;
1984
1985    if (num) *num = 0;
1986    if (state) *state = NULL;
1987
1988    num_ret = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_STATE,
1989                                                &atoms);
1990    if (num_ret <= 0)
1991       return 0;
1992
1993    if (state)
1994      {
1995         *state = malloc(num_ret * sizeof(Ecore_X_Window_State));
1996         if (*state)
1997           for (i = 0; i < num_ret; ++i)
1998             (*state)[i] = _ecore_x_netwm_state_get(atoms[i]);
1999
2000         if (num) *num = num_ret;
2001      }
2002
2003    free(atoms);
2004
2005    return 1;
2006 }
2007
2008 static Ecore_X_Window_Type
2009 _ecore_x_netwm_window_type_type_get(Ecore_X_Atom atom)
2010 {
2011    if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP)
2012      return ECORE_X_WINDOW_TYPE_DESKTOP;
2013    else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK)
2014      return ECORE_X_WINDOW_TYPE_DOCK;
2015    else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR)
2016      return ECORE_X_WINDOW_TYPE_TOOLBAR;
2017    else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU)
2018      return ECORE_X_WINDOW_TYPE_MENU;
2019    else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY)
2020      return ECORE_X_WINDOW_TYPE_UTILITY;
2021    else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH)
2022      return ECORE_X_WINDOW_TYPE_SPLASH;
2023    else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG)
2024      return ECORE_X_WINDOW_TYPE_DIALOG;
2025    else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL)
2026      return ECORE_X_WINDOW_TYPE_NORMAL;
2027    else
2028      return ECORE_X_WINDOW_TYPE_UNKNOWN;
2029 }
2030
2031 static Ecore_X_Atom
2032 _ecore_x_netwm_window_type_atom_get(Ecore_X_Window_Type type)
2033 {
2034    switch (type)
2035      {
2036       case ECORE_X_WINDOW_TYPE_DESKTOP:
2037          return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
2038       case ECORE_X_WINDOW_TYPE_DOCK:
2039          return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
2040       case ECORE_X_WINDOW_TYPE_TOOLBAR:
2041          return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
2042       case ECORE_X_WINDOW_TYPE_MENU:
2043          return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
2044       case ECORE_X_WINDOW_TYPE_UTILITY:
2045          return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
2046       case ECORE_X_WINDOW_TYPE_SPLASH:
2047          return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
2048       case ECORE_X_WINDOW_TYPE_DIALOG:
2049          return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
2050       case ECORE_X_WINDOW_TYPE_NORMAL:
2051          return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
2052       default:
2053          return 0;
2054      }
2055 }
2056
2057 /*
2058  * FIXME: We should set WM_TRANSIENT_FOR if type is ECORE_X_WINDOW_TYPE_TOOLBAR
2059  * , ECORE_X_WINDOW_TYPE_MENU or ECORE_X_WINDOW_TYPE_DIALOG
2060  */
2061
2062 /**
2063  * Set the _NET_WM_WINDOW_TYPE property.
2064  * @param window The window.
2065  * @param type   The functional type of the window.
2066  *
2067  * Set the functional @p type of @p window by sending _NET_WM_WINDOW_TYPE
2068  * property to @p window.
2069  *
2070  * This property SHOULD be set by the Client before mapping. This
2071  * property SHOULD be used by the window manager in determining the
2072  * decoration, stacking position and other behavior of the window. The
2073  * Client SHOULD specify window types in order of preference (the first
2074  * being most preferable).
2075  *
2076  * This hint is intended to replace the MOTIF hints.
2077  * @ingroup Ecore_X_NetWM_Group
2078  */
2079 EAPI void
2080 ecore_x_netwm_window_type_set(Ecore_X_Window      window,
2081                               Ecore_X_Window_Type type)
2082 {
2083    Ecore_X_Atom atom;
2084
2085    atom = _ecore_x_netwm_window_type_atom_get(type);
2086    ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
2087                                 &atom, 1);
2088 }
2089
2090 /**
2091  * Sends the GetProperty request.
2092  * @param window The window.
2093  * @ingroup Ecore_X_NetWM_Group
2094  */
2095 EAPI void
2096 ecore_x_netwm_window_type_get_prefetch(Ecore_X_Window window)
2097 {
2098    xcb_get_property_cookie_t cookie;
2099
2100    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
2101                                        ECORE_X_ATOM_NET_WM_WINDOW_TYPE, ECORE_X_ATOM_ATOM,
2102                                        0, 0x7fffffff);
2103    _ecore_xcb_cookie_cache(cookie.sequence);
2104 }
2105
2106 /**
2107  * Gets the reply of the GetProperty request sent by ecore_x_window_type_get_prefetch().
2108  * @ingroup Ecore_X_NetWM_Group
2109  */
2110 EAPI void
2111 ecore_x_netwm_window_type_get_fetch(void)
2112 {
2113    xcb_get_property_cookie_t cookie;
2114    xcb_get_property_reply_t *reply;
2115
2116    cookie.sequence = _ecore_xcb_cookie_get();
2117    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
2118    _ecore_xcb_reply_cache(reply);
2119 }
2120
2121 /* FIXME: Maybe return 0 on some conditions? */
2122
2123 /**
2124  * Get the functional type of a window.
2125  * @param window The window.
2126  * @param type   The function type of the window.
2127  * @return       1 on success, 0 otherwise.
2128  *
2129  * Retrieve the functional type of @p window. The type is stored in
2130  * @p type. This function returns 1 on success, 0 otherwise.
2131  *
2132  * To use this function, you must call before, and in order,
2133  * ecore_x_netwm_window_type_get_prefetch(), which sends the GetProperty request,
2134  * then ecore_x_netwm_window_type_get_fetch(), which gets the reply.
2135  * @ingroup Ecore_X_NetWM_Group
2136  */
2137 EAPI int
2138 ecore_x_netwm_window_type_get(Ecore_X_Window       window,
2139                               Ecore_X_Window_Type *type)
2140 {
2141    Ecore_X_Atom *atoms;
2142    int           num;
2143    int           i;
2144
2145    if (type) *type = ECORE_X_WINDOW_TYPE_NORMAL;
2146
2147    num = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
2148                                            &atoms);
2149    if (num < 0)
2150      {
2151         /* IMO this is not the place to mix netwm and icccm /kwo */
2152         /* Check if WM_TRANSIENT_FOR is set */
2153
2154         /* Disable it for xcb */
2155
2156 /*      if ((type) && (ecore_x_icccm_transient_for_get(window))) */
2157 /*        *type = ECORE_X_WINDOW_TYPE_DIALOG; */
2158 /*      return 1; */
2159      }
2160
2161    if (type)
2162      {
2163         for (i = 0; i < num; ++i)
2164           {
2165              *type = _ecore_x_netwm_window_type_type_get(atoms[i]);
2166              if (*type != ECORE_X_WINDOW_TYPE_UNKNOWN)
2167                break;
2168           }
2169      }
2170
2171    free(atoms);
2172
2173    return 1;
2174 }
2175
2176 static Ecore_X_Atom
2177 _ecore_x_netwm_action_atom_get(Ecore_X_Action action)
2178 {
2179    switch (action)
2180      {
2181       case ECORE_X_ACTION_MOVE:
2182          return ECORE_X_ATOM_NET_WM_ACTION_MOVE;
2183       case ECORE_X_ACTION_RESIZE:
2184          return ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
2185       case ECORE_X_ACTION_MINIMIZE:
2186          return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
2187       case ECORE_X_ACTION_SHADE:
2188          return ECORE_X_ATOM_NET_WM_ACTION_SHADE;
2189       case ECORE_X_ACTION_STICK:
2190          return ECORE_X_ATOM_NET_WM_ACTION_STICK;
2191       case ECORE_X_ACTION_MAXIMIZE_HORZ:
2192          return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
2193       case ECORE_X_ACTION_MAXIMIZE_VERT:
2194          return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
2195       case ECORE_X_ACTION_FULLSCREEN:
2196          return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
2197       case ECORE_X_ACTION_CHANGE_DESKTOP:
2198          return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
2199       case ECORE_X_ACTION_CLOSE:
2200          return ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
2201       case ECORE_X_ACTION_ABOVE:
2202          return ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
2203       case ECORE_X_ACTION_BELOW:
2204          return ECORE_X_ATOM_NET_WM_ACTION_BELOW;
2205       default:
2206          return 0;
2207      }
2208 }
2209
2210 /**
2211  * Sends the GetProperty request.
2212  * @param window The window.
2213  * @ingroup Ecore_X_NetWM_Group
2214  */
2215 EAPI void
2216 ecore_x_netwm_allowed_action_get_prefetch(Ecore_X_Window window)
2217 {
2218    xcb_get_property_cookie_t cookie;
2219
2220    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
2221                                        ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, ECORE_X_ATOM_ATOM,
2222                                        0, 0x7fffffff);
2223    _ecore_xcb_cookie_cache(cookie.sequence);
2224 }
2225
2226 /**
2227  * Gets the reply of the GetProperty request sent by ecore_x_allowed_action_get_prefetch().
2228  * @ingroup Ecore_X_NetWM_Group
2229  */
2230 EAPI void
2231 ecore_x_netwm_allowed_action_get_fetch(void)
2232 {
2233    xcb_get_property_cookie_t cookie;
2234    xcb_get_property_reply_t *reply;
2235
2236    cookie.sequence = _ecore_xcb_cookie_get();
2237    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
2238    _ecore_xcb_reply_cache(reply);
2239 }
2240
2241 /* FIXME: Get complete list */
2242
2243 /**
2244  * Check whether an action is supported by a window.
2245  * @param window The window
2246  * @param action The action
2247  * @return       1 if set, 0 otherwise.
2248  *
2249  * Return whether the user operation @p action is supported by the
2250  * Window Manager for @p window.
2251  *
2252  * To use this function, you must call before, and in order,
2253  * ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request,
2254  * then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply.
2255  * @ingroup Ecore_X_NetWM_Group
2256  */
2257 EAPI int
2258 ecore_x_netwm_allowed_action_isset(Ecore_X_Window window,
2259                                    Ecore_X_Action action)
2260 {
2261    Ecore_X_Atom *atoms;
2262    Ecore_X_Atom  atom;
2263    int           num;
2264    int           ret = 0;
2265    int           i;
2266
2267    num = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
2268                                            &atoms);
2269    if (num <= 0)
2270      return ret;
2271
2272    atom = _ecore_x_netwm_action_atom_get(action);
2273
2274    for (i = 0; i < num; ++i)
2275      {
2276         if (atom == atoms[i])
2277           {
2278              ret = 1;
2279              break;
2280           }
2281      }
2282
2283    free(atoms);
2284
2285    return ret;
2286 }
2287
2288 /* FIXME: Set complete list */
2289 /**
2290  * Set the _NET_WM_ALLOWED_ACTIONS property.
2291  * @param window The window.
2292  * @param action An array of allowed actions.
2293  * @param num    The number of actions.
2294  *
2295  * Set the user operations that the Window Manager supports for
2296  * @p window by sending the _NET_WM_ALLOWED_ACTIONS property to
2297  * @p window. @p action stores @p num actions.
2298  *
2299  * To use this function, you must call before, and in order,
2300  * ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request,
2301  * then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply.
2302  * @ingroup Ecore_X_NetWM_Group
2303  */
2304 EAPI void
2305 ecore_x_netwm_allowed_action_set(Ecore_X_Window  window,
2306                                  Ecore_X_Action *action,
2307                                  unsigned int    num)
2308 {
2309    Ecore_X_Atom  *set;
2310    unsigned int   i;
2311
2312    if (!num)
2313      {
2314         ecore_x_window_prop_property_del(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS);
2315         return;
2316      }
2317
2318    set = malloc(num * sizeof(Ecore_X_Atom));
2319    if (!set) return;
2320
2321    for (i = 0; i < num; i++)
2322      set[i] = _ecore_x_netwm_action_atom_get(action[i]);
2323
2324    ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, set, num);
2325
2326    free(set);
2327 }
2328
2329 /**
2330  * Get the allowed actions supported by a window.
2331  * @param window The window.
2332  * @param action The returned array of the actions.
2333  * @param num    The number of actions.
2334  * @return       1 on success, 0 otherwise.
2335  *
2336  * Retrieve the user operations that the Window Manager supports for
2337  * @p window and store them in @p action. The number of actions is
2338  * stored in @p num. This function returns 1 on success, 0 otherwise.
2339  *
2340  * To use this function, you must call before, and in order,
2341  * ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request,
2342  * then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply.
2343  * @ingroup Ecore_X_NetWM_Group
2344  */
2345 EAPI int
2346 ecore_x_netwm_allowed_action_get(Ecore_X_Window   window,
2347                                  Ecore_X_Action **action,
2348                                  unsigned int    *num)
2349 {
2350    Ecore_X_Atom *atoms;
2351    int           num_ret;
2352    int           i;
2353
2354    if (num) *num = 0;
2355    if (action) *action = NULL;
2356
2357    num_ret = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
2358                                                &atoms);
2359    if (num_ret <= 0)
2360       return 0;
2361
2362    if (action)
2363      {
2364         *action = malloc(num_ret * sizeof(Ecore_X_Action));
2365         if (*action)
2366           for (i = 0; i < num_ret; ++i)
2367             (*action)[i] = _ecore_x_netwm_action_atom_get(atoms[i]);
2368
2369         if (num) *num = num_ret;
2370      }
2371
2372    free(atoms);
2373
2374    return 1;
2375 }
2376
2377 /**
2378  * Set the _NET_WM_WINDOW_OPACITY property.
2379  * @param window  The window.
2380  * @param opacity The opacity value.
2381  *
2382  * Set the desired opacity of @p window by sending the
2383  * _NET_WM_WINDOW_OPACITY property to @p window. @p opacity is 0 for a
2384  * transparent window and 0xffffffff for an opaque window. @p opacity
2385  * must be multiplied with the original alpha value of @p window
2386  * (which is 1 for visuals not including an alpha component) so that
2387  * @p window content is modulated by the opacity value.
2388  *
2389  * Window Managers acting as compositing managers MAY take this into
2390  * account when displaying a window. Window Managers MUST forward the
2391  * value of this property to any enclosing frame window.  This
2392  * property MAY change while the window is mapped and the Window
2393  * Manager MUST respect changes while the window is mapped.
2394  * @ingroup Ecore_X_NetWM_Group
2395  */
2396 EAPI void
2397 ecore_x_netwm_opacity_set(Ecore_X_Window window,
2398                           unsigned int   opacity)
2399 {
2400    uint32_t op = opacity;
2401    ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
2402                                   &op, 1);
2403 }
2404
2405 /**
2406  * Sends the GetProperty request.
2407  * @param window The window.
2408  * @ingroup Ecore_X_NetWM_Group
2409  */
2410 EAPI void
2411 ecore_x_netwm_opacity_get_prefetch(Ecore_X_Window window)
2412 {
2413    xcb_get_property_cookie_t cookie;
2414
2415    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
2416                                        ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, ECORE_X_ATOM_CARDINAL,
2417                                        0, 0x7fffffff);
2418    _ecore_xcb_cookie_cache(cookie.sequence);
2419 }
2420
2421 /**
2422  * Gets the reply of the GetProperty request sent by ecore_x_netwm_opacity_get_prefetch().
2423  * @ingroup Ecore_X_NetWM_Group
2424  */
2425 EAPI void
2426 ecore_x_netwm_opacity_get_fetch(void)
2427 {
2428    xcb_get_property_cookie_t cookie;
2429    xcb_get_property_reply_t *reply;
2430
2431    cookie.sequence = _ecore_xcb_cookie_get();
2432    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
2433    _ecore_xcb_reply_cache(reply);
2434 }
2435
2436 /**
2437  * Get the opacity value of a window.
2438  * @param window  The window.
2439  * @param opacity The returned opacity.
2440  * @return        1 on success, 0 otherwise.
2441  *
2442  * Retriee the opacity value of @p window and store it in
2443  * @p opacity. This function returns 1 on sucess, 0 otherwise.
2444  *
2445  * To use this function, you must call before, and in order,
2446  * ecore_x_netwm_opacity_get_prefetch(), which sends the GetProperty request,
2447  * then ecore_x_netwm_opacity_get_fetch(), which gets the reply.
2448  * @ingroup Ecore_X_NetWM_Group
2449  */
2450 EAPI int
2451 ecore_x_netwm_opacity_get(Ecore_X_Window window,
2452                           unsigned int  *opacity)
2453 {
2454    int ret;
2455    unsigned int tmp;
2456
2457    ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
2458                                         &tmp, 1);
2459    if (opacity) *opacity = tmp;
2460    return ret == 1 ? 1 : 0;
2461 }
2462
2463 /**
2464  * Set the _NET_FRAME_EXTENTS property.
2465  * @param window The window.
2466  * @param fl     The number of pixels of the left border of the window.
2467  * @param fr     The number of pixels of the right border of the window.
2468  * @param ft     The number of pixels of the top border of the window.
2469  * @param fb     The number of pixels of the bottom border of the window.
2470  *
2471  * Set the border witdh of @p window by sending the _NET_FRAME_EXTENTS
2472  * property to @p window. @p fl, @p fr, @p ft and @p fb are respectively
2473  * the number of pixels of the left, right, top and bottom border of
2474  * @p window.
2475  *
2476  * The Window Manager MUST set _NET_FRAME_EXTENTS to the extents of
2477  * the window's frame.
2478  * @ingroup Ecore_X_NetWM_Group
2479  */
2480 EAPI void
2481 ecore_x_netwm_frame_size_set(Ecore_X_Window window,
2482                              int            fl,
2483                              int            fr,
2484                              int            ft,
2485                              int            fb)
2486 {
2487    uint32_t frames[4];
2488
2489    frames[0] = fl;
2490    frames[1] = fr;
2491    frames[2] = ft;
2492    frames[3] = fb;
2493    ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4);
2494 }
2495
2496 /**
2497  * Sends the GetProperty request.
2498  * @param window The window.
2499  * @ingroup Ecore_X_NetWM_Group
2500  */
2501 EAPI void
2502 ecore_x_netwm_frame_size_get_prefetch(Ecore_X_Window window)
2503 {
2504    xcb_get_property_cookie_t cookie;
2505
2506    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
2507                                        ECORE_X_ATOM_NET_FRAME_EXTENTS, ECORE_X_ATOM_CARDINAL,
2508                                        0, 0x7fffffff);
2509    _ecore_xcb_cookie_cache(cookie.sequence);
2510 }
2511
2512 /**
2513  * Gets the reply of the GetProperty request sent by ecore_x_netwm_frame_size_get_prefetch().
2514  * @ingroup Ecore_X_NetWM_Group
2515  */
2516 EAPI void
2517 ecore_x_netwm_frame_size_get_fetch(void)
2518 {
2519    xcb_get_property_cookie_t cookie;
2520    xcb_get_property_reply_t *reply;
2521
2522    cookie.sequence = _ecore_xcb_cookie_get();
2523    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
2524    _ecore_xcb_reply_cache(reply);
2525 }
2526
2527 /**
2528  * Get the frame extent of a window.
2529  * @param window  The window.
2530  * @param fl      The number of pixels of the left border of the window.
2531  * @param fr      The number of pixels of the right border of the window.
2532  * @param ft      The number of pixels of the top border of the window.
2533  * @param fb      The number of pixels of the bottom border of the window.
2534  * @return        1 on success, 0 otherwise.
2535  *
2536  * Retrieve the frame extents of @p window. The number of pixels of
2537  * the left, right, top and bottom border of @p window are
2538  * respectively stored in @p fl, @p fr, @p ft anfd @p fb. TYhis
2539  * function retuirns 1 on success, 0 otherwise.
2540  *
2541  * To use this function, you must call before, and in order,
2542  * ecore_x_netwm_frame_size_get_prefetch(), which sends the GetProperty request,
2543  * then ecore_x_netwm_frame_size_get_fetch(), which gets the reply.
2544  * @ingroup Ecore_X_NetWM_Group
2545  */
2546 EAPI int
2547 ecore_x_netwm_frame_size_get(Ecore_X_Window window,
2548                              int           *fl,
2549                              int           *fr,
2550                              int           *ft,
2551                              int           *fb)
2552 {
2553    uint32_t frames[4];
2554    int      ret = 0;
2555
2556    ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4);
2557    if (ret != 4)
2558      return 0;
2559
2560    if (fl) *fl = frames[0];
2561    if (fr) *fr = frames[1];
2562    if (ft) *ft = frames[2];
2563    if (fb) *fb = frames[3];
2564    return 1;
2565 }
2566
2567 /**
2568  * Sends the GetProperty request.
2569  * @param window The window.
2570  * @ingroup Ecore_X_NetWM_Group
2571  */
2572 EAPI void
2573 ecore_x_netwm_sync_counter_get_prefetch(Ecore_X_Window window)
2574 {
2575    xcb_get_property_cookie_t cookie;
2576
2577    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
2578                                        ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, ECORE_X_ATOM_CARDINAL,
2579                                        0, 0x7fffffff);
2580    _ecore_xcb_cookie_cache(cookie.sequence);
2581 }
2582
2583 /**
2584  * Gets the reply of the GetProperty request sent by ecore_x_netwm_sync_counter_get_prefetch().
2585  * @ingroup Ecore_X_NetWM_Group
2586  */
2587 EAPI void
2588 ecore_x_netwm_sync_counter_get_fetch(void)
2589 {
2590    xcb_get_property_cookie_t cookie;
2591    xcb_get_property_reply_t *reply;
2592
2593    cookie.sequence = _ecore_xcb_cookie_get();
2594    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
2595    _ecore_xcb_reply_cache(reply);
2596 }
2597
2598 /**
2599  * Get the X ID of a X Sync counter.
2600  * @param window  The window.
2601  * @param counter The X ID of the Sync counter.
2602  * @return        1 on success, 0 otherwise.
2603  *
2604  * Retrieve the X ID of the X Sync counter of @p window and store it
2605  * in @p counter. This function returns 1 on success, 0 otherwise.
2606  *
2607  * To use this function, you must call before, and in order,
2608  * ecore_x_netwm_frame_size_get_prefetch(), which sends the GetProperty request,
2609  * then ecore_x_netwm_frame_size_get_fetch(), which gets the reply.
2610  * @ingroup Ecore_X_NetWM_Group
2611  */
2612 EAPI int
2613 ecore_x_netwm_sync_counter_get(Ecore_X_Window        window,
2614                                Ecore_X_Sync_Counter *counter)
2615 {
2616    int          ret;
2617    unsigned int tmp;
2618
2619    ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
2620                                         &tmp, 1);
2621
2622    if (counter) *counter = tmp;
2623    return (ret == 1) ? 1 : 0;
2624 }
2625
2626 /**
2627  * Send a _NET_WM_PING property event.
2628  * @param window The window.
2629  *
2630  * Send a ClientMessage event from @p window with the _NET_WM_PING
2631  * property set.
2632  * @ingroup Ecore_X_NetWM_Group
2633  */
2634 EAPI void
2635 ecore_x_netwm_ping_send(Ecore_X_Window window)
2636 {
2637    xcb_client_message_event_t ev;
2638
2639    if (!window) return;
2640
2641    ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
2642    ev.format = 32;
2643    ev.sequence = 0;
2644    ev.window = window;
2645    ev.type = ECORE_X_ATOM_WM_PROTOCOLS;
2646    ev.data.data32[0] = ECORE_X_ATOM_NET_WM_PING;
2647    ev.data.data32[1] = _ecore_xcb_event_last_time;
2648    ev.data.data32[2] = window;
2649    ev.data.data32[3] = 0;
2650    ev.data.data32[4] = 0;
2651    ev.data.data32[5] = 0;
2652
2653    xcb_send_event(_ecore_xcb_conn, 0, window, XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
2654 }
2655
2656 /**
2657  * Send a _NET_WM_SYNC_REQUEST property event.
2658  * @param window The window.
2659  * @param serial The update request number.
2660  *
2661  * Send a ClientMessage event from @p window with the _NET_WM_SYNC_REQUEST
2662  * property set.
2663  * @ingroup Ecore_X_NetWM_Group
2664  */
2665 EAPI void
2666 ecore_x_netwm_sync_request_send(Ecore_X_Window window,
2667                                 unsigned int   serial)
2668 {
2669    xcb_client_message_event_t ev;
2670
2671    if (!window) return;
2672
2673    ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
2674    ev.format = 32;
2675    ev.window = window;
2676    ev.type = ECORE_X_ATOM_WM_PROTOCOLS;
2677    ev.data.data32[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
2678    ev.data.data32[1] = _ecore_xcb_event_last_time;
2679    ev.data.data32[2] = serial;
2680    /* FIXME: imho, the following test is useless as serial is non negative */
2681    /* should we remove it ? */
2682    ev.data.data32[3] = (serial < 0) ? ~0L : 0L;
2683    ev.data.data32[4] = 0;
2684
2685    xcb_send_event(_ecore_xcb_conn, 0, window, 0, (const char *)&ev);
2686 }
2687
2688 /**
2689  * Send a _NET_WM_STATE property event.
2690  * @param window The window.
2691  * @param root   The root window.
2692  * @param s1     The first state to alter.
2693  * @param s2     The second state to alter.
2694  * @param set    0 to unset the property, set it otherwise.
2695  *
2696  * Send a ClientMessage event from @p window to the @p root window
2697  * with the _NET_WM_STATE property set. This change the state of a
2698  * mapped window. @p s1 is the first state to alter. @p s2 is the
2699  * second state to alter. If @p set value is 0, the property is
2700  * removed (or unset), otherwise, the property is set.
2701  * @ingroup Ecore_X_NetWM_Group
2702  */
2703 EAPI void
2704 ecore_x_netwm_state_request_send(Ecore_X_Window       window,
2705                                  Ecore_X_Window       root,
2706                                  Ecore_X_Window_State s1,
2707                                  Ecore_X_Window_State s2,
2708                                  int                  set)
2709 {
2710    xcb_client_message_event_t ev;
2711
2712    if (!window) return;
2713    if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
2714
2715    ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
2716    ev.format = 32;
2717    ev.window = window;
2718    ev.type = ECORE_X_ATOM_NET_WM_STATE;
2719    ev.data.data32[0] = !!set;
2720    ev.data.data32[1] = _ecore_x_netwm_state_atom_get(s1);
2721    ev.data.data32[2] = _ecore_x_netwm_state_atom_get(s2);
2722    /* 1 == normal client, if someone wants to use this
2723     * function in a pager, this should be 2 */
2724    ev.data.data32[3] = 1;
2725    ev.data.data32[4] = 0;
2726
2727    xcb_send_event(_ecore_xcb_conn, 0, root,
2728                   XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
2729                   (const char *)&ev);
2730 }
2731
2732 /**
2733  * Send a _NET_WM_DESKTOP property event.
2734  * @param window  The window.
2735  * @param root    The root window.
2736  * @param desktop The new desktop index.
2737  *
2738  * Send a ClientMessage event from @p window to the @p root window
2739  * with the _NET_WM_DESKTOP property set. This change the state of a
2740  * non-withdrawn window. @p desktop is the new desktop index to set.
2741  * @ingroup Ecore_X_NetWM_Group
2742  */
2743 EAPI void
2744 ecore_x_netwm_desktop_request_send(Ecore_X_Window window,
2745                                    Ecore_X_Window root,
2746                                    unsigned int   desktop)
2747 {
2748    xcb_client_message_event_t ev;
2749
2750    if (!window) return;
2751    if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
2752
2753    ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
2754    ev.format = 32;
2755    ev.window = window;
2756    ev.type = ECORE_X_ATOM_NET_WM_DESKTOP;
2757    ev.data.data32[0] = desktop;
2758
2759    xcb_send_event(_ecore_xcb_conn, 0, root,
2760                   XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
2761                   (const char *)&ev);
2762 }
2763
2764 int
2765 _ecore_x_netwm_startup_info_begin(Ecore_X_Window window,
2766                                   char          *data)
2767 {
2768 #if 0
2769    Ecore_X_Startup_Info *info;
2770    unsigned char        exists = 0;
2771
2772    if (!startup_info) return 0;
2773    info = eina_hash_find(startup_info, (void *)window);
2774    if (info)
2775      {
2776         exists = 1;
2777         INF("Already got info for win: 0x%x", window);
2778         _ecore_x_netwm_startup_info_free(info);
2779      }
2780    info = calloc(1, sizeof(Ecore_X_Startup_Info));
2781    if (!info) return 0;
2782    info->win = win;
2783    info->length = 0;
2784    info->buffer_size = 161;
2785    info->buffer = calloc(info->buffer_size, sizeof(char));
2786    if (!info->buffer)
2787      {
2788         _ecore_x_netwm_startup_info_free(info);
2789         return 0;
2790      }
2791    memcpy(info->buffer, data, 20);
2792    info->length += 20;
2793    info->buffer[info->length] = 0;
2794    if (exists)
2795      eina_hash_modify(startup_info, (void *)info->win, info);
2796    else
2797      eina_hash_add(startup_info, (void *)info->win, info);
2798    if (strlen(info->buffer) != 20)
2799      {
2800         /* We have a '\0' in there, the message is done */
2801         _ecore_x_netwm_startup_info_process(info);
2802      }
2803 #else
2804    window = XCB_NONE;
2805    data = NULL;
2806 #endif
2807
2808    return 1;
2809 }
2810
2811 int
2812 _ecore_x_netwm_startup_info(Ecore_X_Window window,
2813                             char          *data)
2814 {
2815 #if 0
2816    Ecore_X_Startup_Info *info;
2817    char *p;
2818
2819    if (!startup_info) return 0;
2820    info = eina_hash_find(startup_info, (void *)window);
2821    if (!info) return 0;
2822    if ((info->length + 20) > info->buffer_size)
2823      {
2824         info->buffer_size += 160;
2825         info->buffer = realloc(info->buffer, info->buffer_size * sizeof(char));
2826         if (!info->buffer)
2827           {
2828              eina_hash_del(startup_info, (void *)info->win);
2829              _ecore_x_netwm_startup_info_free(info);
2830              return 0;
2831           }
2832      }
2833    memcpy(info->buffer + info->length, data, 20);
2834    p = info->buffer + info->length;
2835    info->length += 20;
2836    info->buffer[info->length] = 0;
2837    if (strlen(p) != 20)
2838      {
2839         /* We have a '\0' in there, the message is done */
2840         _ecore_x_netwm_startup_info_process(info);
2841      }
2842 #else
2843    window = XCB_NONE;
2844    data = NULL;
2845 #endif
2846
2847    return 1;
2848 }
2849
2850 /*
2851  * Set UTF-8 string property
2852  */
2853 static void
2854 _ecore_x_window_prop_string_utf8_set(Ecore_X_Window window,
2855                                      Ecore_X_Atom   atom,
2856                                      const char    *str)
2857 {
2858    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
2859                        atom, ECORE_X_ATOM_UTF8_STRING,
2860                        8, strlen(str), str);
2861 }
2862
2863 static void
2864 _ecore_x_window_prop_string_utf8_get_prefetch(Ecore_X_Window window,
2865                                               Ecore_X_Atom atom)
2866 {
2867    xcb_get_property_cookie_t cookie;
2868
2869    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
2870                                        atom, ECORE_X_ATOM_UTF8_STRING,
2871                                        0, 0x7fffffff);
2872    _ecore_xcb_cookie_cache(cookie.sequence);
2873 }
2874
2875 /*
2876  * Get UTF-8 string property
2877  * call _ecore_x_window_prop_string_utf8_get_prefetch() before.
2878  */
2879 static char *
2880 _ecore_x_window_prop_string_utf8_get(Ecore_X_Window window __UNUSED__,
2881                                      Ecore_X_Atom   atom __UNUSED__)
2882 {
2883    xcb_get_property_reply_t *reply;
2884    char                     *str;
2885    int                       length;
2886
2887    reply = _ecore_xcb_reply_get((Ecore_Xcb_Reply_Cb)xcb_get_property_reply);
2888    if (!reply) return NULL;
2889
2890    if ((reply->format != 8) ||
2891        (reply->value_len <= 0))
2892      {
2893        free(reply);
2894        return NULL;
2895      }
2896
2897    length = reply->value_len;
2898    str = (char *)malloc (sizeof (char) * (length + 1));
2899    if (!str)
2900      {
2901         free(reply);
2902         return NULL;
2903      }
2904    memcpy(str, xcb_get_property_value(reply), length);
2905    str[length] = '\0';
2906
2907    free(reply);
2908    return str;
2909 }
2910
2911 #if 0 /* Unused */
2912 /*
2913  * Process startup info
2914  */
2915 static int
2916 _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info)
2917 {
2918    Ecore_X_Event_Startup_Sequence *e;
2919    int                             event;
2920    char                           *p;
2921
2922    p = strchr(info->buffer, ':');
2923    if (!p)
2924      {
2925         eina_hash_del(startup_info, (void *)info->win);
2926         _ecore_x_netwm_startup_info_free(info);
2927         return 0;
2928      }
2929    *p = 0;
2930    if (!strcmp(info->buffer, "new"))
2931      {
2932         if (info->init)
2933           event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
2934         else
2935           event = ECORE_X_EVENT_STARTUP_SEQUENCE_NEW;
2936         info->init = 1;
2937      }
2938    else if (!strcmp(info->buffer, "change"))
2939      {
2940         event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
2941      }
2942    else if (!strcmp(info->buffer, "remove"))
2943      event = ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE;
2944    else
2945      {
2946         eina_hash_del(startup_info, (void *)info->win);
2947         _ecore_x_netwm_startup_info_free(info);
2948         return 0;
2949      }
2950
2951    p++;
2952
2953    if (!_ecore_x_netwm_startup_info_parse(info, p))
2954      {
2955         eina_hash_del(startup_info, (void *)info->win);
2956         _ecore_x_netwm_startup_info_free(info);
2957         return 0;
2958      }
2959
2960    if (info->init)
2961      {
2962         e = calloc(1, sizeof(Ecore_X_Event_Startup_Sequence));
2963         if (!e)
2964           {
2965              eina_hash_del(startup_info, (void *)info->win);
2966              _ecore_x_netwm_startup_info_free(info);
2967              return 0;
2968           }
2969         e->win = info->win;
2970         ecore_event_add(event, e, NULL, NULL);
2971      }
2972
2973    if (event == ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE)
2974      {
2975         eina_hash_del(startup_info, (void *)info->win);
2976         _ecore_x_netwm_startup_info_free(info);
2977      }
2978    else
2979      {
2980         /* Discard buffer */
2981         info->length = 0;
2982         info->buffer[0] = 0;
2983      }
2984    return 1;
2985 }
2986
2987 /*
2988  * Parse startup info
2989  */
2990 static int
2991 _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info,
2992                                   char                 *data)
2993 {
2994
2995    while (*data)
2996      {
2997         int in_quot_sing, in_quot_dbl, escaped;
2998         char *p, *pp;
2999         char *key;
3000         char value[1024];
3001
3002         /* Skip space */
3003         while (*data == ' ') data++;
3004         /* Get key */
3005         key = data;
3006         data = strchr(key, '=');
3007         if (!data) return 0;
3008         *data = 0;
3009         data++;
3010
3011         /* Get value */
3012         p = data;
3013         pp = value;
3014         in_quot_dbl = 0;
3015         in_quot_sing = 0;
3016         escaped = 0;
3017         while (*p)
3018           {
3019              if ((pp - value) >= 1024) return 0;
3020              if (escaped)
3021                {
3022                   *pp = *p;
3023                   pp++;
3024                   escaped = 0;
3025                }
3026              else if (in_quot_sing)
3027                {
3028                   if (*p == '\\')
3029                     escaped = 1;
3030                   else if (*p == '\'')
3031                     in_quot_sing = 0;
3032                   else
3033                     {
3034                        *pp = *p;
3035                        pp++;
3036                     }
3037                }
3038              else if (in_quot_dbl)
3039                {
3040                   if (*p == '\\')
3041                     escaped = 1;
3042                   else if (*p == '\"')
3043                     in_quot_dbl = 0;
3044                   else
3045                     {
3046                        *pp = *p;
3047                        pp++;
3048                     }
3049                }
3050              else
3051                {
3052                   if (*p == '\\')
3053                     escaped = 1;
3054                   else if (*p == '\'')
3055                     in_quot_sing = 1;
3056                   else if (*p == '\"')
3057                     in_quot_dbl = 1;
3058                   else if (*p == ' ')
3059                     {
3060                        break;
3061                     }
3062                   else
3063                     {
3064                        *pp = *p;
3065                        pp++;
3066                     }
3067                }
3068              p++;
3069           }
3070         if ((in_quot_dbl) || (in_quot_sing)) return 0;
3071         data = p;
3072         *pp = 0;
3073
3074         /* Parse info */
3075         if (!strcmp(key, "ID"))
3076           {
3077              if ((info->id) && (strcmp(info->id, value))) return 0;
3078              info->id = strdup(value);
3079              p = strstr(value, "_TIME");
3080              if (p)
3081                {
3082                   info->timestamp = atoi(p + 5);
3083                }
3084           }
3085         else if (!strcmp(key, "NAME"))
3086           {
3087              if (info->name) free(info->name);
3088              info->name = strdup(value);
3089           }
3090         else if (!strcmp(key, "SCREEN"))
3091           {
3092              info->screen = atoi(value);
3093           }
3094         else if (!strcmp(key, "BIN"))
3095           {
3096              if (info->bin) free(info->bin);
3097              info->bin = strdup(value);
3098           }
3099         else if (!strcmp(key, "ICON"))
3100           {
3101              if (info->icon) free(info->icon);
3102              info->icon = strdup(value);
3103           }
3104         else if (!strcmp(key, "DESKTOP"))
3105           {
3106              info->desktop = atoi(value);
3107           }
3108         else if (!strcmp(key, "TIMESTAMP"))
3109           {
3110              if (!info->timestamp)
3111                info->timestamp = atoi(value);
3112           }
3113         else if (!strcmp(key, "DESCRIPTION"))
3114           {
3115              if (info->description) free(info->description);
3116              info->description = strdup(value);
3117           }
3118         else if (!strcmp(key, "WMCLASS"))
3119           {
3120              if (info->wmclass) free(info->wmclass);
3121              info->wmclass = strdup(value);
3122           }
3123         else if (!strcmp(key, "SILENT"))
3124           {
3125              info->silent = atoi(value);
3126           }
3127         else
3128           {
3129              WRN("Ecore X Sequence, Unknown: %s=%s", key, value);
3130           }
3131      }
3132    if (!info->id) return 0;
3133    return 1;
3134 }
3135 #endif
3136
3137 /*
3138  * Free startup info struct
3139  */
3140 static void
3141 _ecore_x_netwm_startup_info_free(void *data)
3142 {
3143    Ecore_X_Startup_Info *info;
3144
3145    info = data;
3146    if (!info) return;
3147    if (info->buffer) free(info->buffer);
3148    if (info->id) free(info->id);
3149    if (info->name) free(info->name);
3150    if (info->bin) free(info->bin);
3151    if (info->icon) free(info->icon);
3152    if (info->description) free(info->description);
3153    if (info->wmclass) free(info->wmclass);
3154    free(info);
3155 }
3156
3157 /*
3158  * Is screen composited?
3159  */
3160
3161 /* FIXME: one round trip can be removed. Can we keep it ? */
3162
3163 /**
3164  * Check whether a screen is composited or not.
3165  * @param screen The screen index.
3166  *
3167  * Return 1 if @p screen is composited, 0 otherwise.
3168  * @ingroup Ecore_X_NetWM_Group
3169  */
3170 EAPI int
3171 ecore_x_screen_is_composited(int screen)
3172 {
3173    char                             buf[32];
3174    xcb_intern_atom_cookie_t         cookie_atom;
3175    xcb_get_selection_owner_cookie_t cookie_owner;
3176    xcb_intern_atom_reply_t         *reply_atom;
3177    xcb_get_selection_owner_reply_t *reply_owner;
3178    Ecore_X_Window                   window;
3179    Ecore_X_Atom                     atom;
3180
3181    snprintf(buf, sizeof(buf), "_NET_WM_CM_S%d", screen);
3182    cookie_atom = xcb_intern_atom_unchecked(_ecore_xcb_conn, 1,
3183                                            strlen(buf), buf);
3184    reply_atom = xcb_intern_atom_reply(_ecore_xcb_conn, cookie_atom, NULL);
3185    if (!reply_atom) return 0;
3186    atom = reply_atom->atom;
3187    free(reply_atom);
3188
3189    cookie_owner = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, atom);
3190    reply_owner = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie_owner, NULL);
3191    if (!reply_owner) return 0;
3192
3193    window = reply_owner->owner;
3194    free(reply_owner);
3195
3196    return window != XCB_NONE;
3197 }