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