svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_window_prop.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "ecore_xcb_private.h"
9 #include "Ecore_X_Atoms.h"
10
11
12 /*
13  * Set CARD32 (array) property
14  */
15 EAPI void
16 ecore_x_window_prop_card32_set(Ecore_X_Window win,
17                                Ecore_X_Atom   atom,
18                                unsigned int  *val,
19                                unsigned int   num)
20 {
21    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
22                        atom, ECORE_X_ATOM_CARDINAL, 32, num, (const void *)val);
23 }
24
25 /**
26  * Sends the GetProperty request.
27  * @param window Window whose properties are requested.
28  * @param atom   The atom.
29  */
30 EAPI void
31 ecore_x_window_prop_card32_get_prefetch(Ecore_X_Window window,
32                                         Ecore_X_Atom atom)
33 {
34    xcb_get_property_cookie_t cookie;
35
36    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
37                                        window,
38                                        atom,
39                                        ECORE_X_ATOM_CARDINAL,
40                                        0, 0x7fffffff);
41    _ecore_xcb_cookie_cache(cookie.sequence);
42 }
43
44
45 /**
46  * Gets the reply of the GetProperty request sent by ecore_x_window_prop_card32_get_prefetch().
47  */
48 EAPI void
49 ecore_x_window_prop_card32_get_fetch(void)
50 {
51    xcb_get_property_cookie_t cookie;
52    xcb_get_property_reply_t *reply;
53
54    cookie.sequence = _ecore_xcb_cookie_get();
55    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
56    _ecore_xcb_reply_cache(reply);
57 }
58
59 /*
60  * Get CARD32 (array) property
61  *
62  * At most len items are returned in val.
63  * If the property was successfully fetched the number of items stored in
64  * val is returned, otherwise -1 is returned.
65  * Note: Return value 0 means that the property exists but has no elements.
66  */
67 EAPI int
68 ecore_x_window_prop_card32_get(Ecore_X_Window win __UNUSED__,
69                                Ecore_X_Atom   atom __UNUSED__,
70                                unsigned int  *val,
71                                unsigned int   len)
72 {
73    xcb_get_property_reply_t *reply;
74
75    reply = _ecore_xcb_reply_get();
76    if (!reply ||
77        (reply->type != ECORE_X_ATOM_CARDINAL) ||
78        (reply->format != 32))
79       return -1;
80
81    if (reply->value_len < len)
82      len = xcb_get_property_value_length(reply);
83
84    if (val)
85       memcpy(val, xcb_get_property_value(reply), len);
86
87    return (int)len;
88 }
89
90 /*
91  * Get CARD32 (array) property of any length
92  *
93  * If the property was successfully fetched the number of items stored in
94  * val is returned, otherwise -1 is returned.
95  * Note: Return value 0 means that the property exists but has no elements.
96  */
97 EAPI int
98 ecore_x_window_prop_card32_list_get(Ecore_X_Window win __UNUSED__,
99                                     Ecore_X_Atom   atom __UNUSED__,
100                                     unsigned int **plist)
101 {
102    xcb_get_property_reply_t *reply;
103    int                       num = -1;
104
105    if (plist)
106       *plist = NULL;
107
108    reply = _ecore_xcb_reply_get();
109    if (!reply)
110       return -1;
111
112    if ((reply->type == XCB_NONE) ||
113        (reply->value_len == 0))
114       num = 0;
115    else if ((reply->type == ECORE_X_ATOM_CARDINAL) &&
116             (reply->format == 32))
117      {
118        uint32_t *val;
119
120        num = xcb_get_property_value_length(reply);
121        if (plist)
122          {
123             val = (uint32_t *)malloc (num);
124             if (!val)
125                goto error;
126
127             memcpy(val, xcb_get_property_value(reply), num);
128             *plist = val;
129          }
130      }
131
132  error:
133
134    return num;
135 }
136
137 /*
138  * Set X ID (array) property
139  */
140 EAPI void
141 ecore_x_window_prop_xid_set(Ecore_X_Window win,
142                             Ecore_X_Atom   atom,
143                             Ecore_X_Atom   type,
144                             Ecore_X_ID    *xids,
145                             unsigned int   num)
146 {
147    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
148                        atom, type, 32, num, xids);
149 }
150
151 /**
152  * Sends the GetProperty request.
153  * @param window Window whose properties are requested.
154  * @param atom   The atom.
155  * @param type   The atom type.
156  */
157 EAPI void
158 ecore_x_window_prop_xid_get_prefetch(Ecore_X_Window window,
159                                      Ecore_X_Atom   atom,
160                                      Ecore_X_Atom   type)
161 {
162    xcb_get_property_cookie_t cookie;
163
164    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
165                                        window,
166                                        atom,
167                                        type,
168                                        0, 0x7fffffff);
169    _ecore_xcb_cookie_cache(cookie.sequence);
170 }
171
172
173 /**
174  * Gets the reply of the GetProperty request sent by ecore_x_window_prop_xid_get_prefetch().
175  */
176 EAPI void
177 ecore_x_window_prop_xid_get_fetch(void)
178 {
179    xcb_get_property_cookie_t cookie;
180    xcb_get_property_reply_t *reply;
181
182    cookie.sequence = _ecore_xcb_cookie_get();
183    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
184    _ecore_xcb_reply_cache(reply);
185 }
186
187 /*
188  * Get X ID (array) property
189  *
190  * At most len items are returned in val.
191  * If the property was successfully fetched the number of items stored in
192  * val is returned, otherwise -1 is returned.
193  * Note: Return value 0 means that the property exists but has no elements.
194  */
195 EAPI int
196 ecore_x_window_prop_xid_get(Ecore_X_Window win __UNUSED__,
197                             Ecore_X_Atom   atom __UNUSED__,
198                             Ecore_X_Atom   type __UNUSED__,
199                             Ecore_X_ID    *xids,
200                             unsigned int   len)
201 {
202    xcb_get_property_reply_t *reply;
203    int                       num = len;
204
205    reply = _ecore_xcb_reply_get();
206    if (!reply)
207       return -1;
208
209    if (reply->type == XCB_NONE)
210       num = 0;
211    else if (reply->format == 32)
212      {
213         if (reply->value_len < len)
214           num = xcb_get_property_value_length(reply);
215
216         if (xids)
217            memcpy(xids, xcb_get_property_value(reply), num);
218      }
219
220    return num;
221 }
222
223 /*
224  * Get X ID (array) property
225  *
226  * If the property was successfully fetched the number of items stored in
227  * val is returned, otherwise -1 is returned.
228  * The returned array must be freed with free().
229  * Note: Return value 0 means that the property exists but has no elements.
230  */
231 EAPI int
232 ecore_x_window_prop_xid_list_get(Ecore_X_Window win __UNUSED__,
233                                  Ecore_X_Atom   atom __UNUSED__,
234                                  Ecore_X_Atom   type __UNUSED__,
235                                  Ecore_X_ID   **pxids)
236 {
237    xcb_get_property_reply_t *reply;
238    int                       num = -1;
239
240    if (pxids)
241       *pxids = NULL;
242
243    reply = _ecore_xcb_reply_get();
244    if (!reply)
245       return -1;
246
247    if ((reply->type == XCB_NONE) ||
248        (reply->value_len == 0))
249       num = 0;
250    else if ((reply->type == ECORE_X_ATOM_CARDINAL) &&
251             (reply->format == 32))
252      {
253        uint32_t *val;
254
255        num = xcb_get_property_value_length(reply);
256        if (pxids)
257          {
258             val = (uint32_t *)malloc (num);
259             if (!val)
260                return -1;
261
262             memcpy(val, xcb_get_property_value(reply), num);
263             *pxids = val;
264          }
265      }
266
267    return num;
268 }
269
270 /*
271  * Remove/add/toggle X ID list item.
272  */
273 EAPI void
274 ecore_x_window_prop_xid_list_change(Ecore_X_Window win,
275                                     Ecore_X_Atom   atom,
276                                     Ecore_X_Atom   type,
277                                     Ecore_X_ID     item,
278                                     int            op)
279 {
280    Ecore_X_ID *lst;
281    int         i;
282    int         num;
283
284    num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst);
285    if (num < 0)
286       return;                   /* Error - assuming invalid window */
287
288    /* Is it there? */
289    for (i = 0; i < num; i++)
290      {
291         if (lst[i] == item)
292            break;
293      }
294
295    if (i < num)
296      {
297         /* Was in list */
298         if (op == ECORE_X_PROP_LIST_ADD)
299            goto done;
300         /* Remove it */
301         num--;
302         for (; i < num; i++)
303            lst[i] = lst[i + 1];
304      }
305    else
306      {
307         /* Was not in list */
308         if (op == ECORE_X_PROP_LIST_REMOVE)
309            goto done;
310         /* Add it */
311         num++;
312         lst = realloc(lst, num * sizeof(Ecore_X_ID));
313         lst[i] = item;
314      }
315
316    ecore_x_window_prop_xid_set(win, atom, type, lst, num);
317
318  done:
319    if (lst)
320       free(lst);
321 }
322
323 /*
324  * Set Atom (array) property
325  */
326 EAPI void
327 ecore_x_window_prop_atom_set(Ecore_X_Window win,
328                              Ecore_X_Atom   atom,
329                              Ecore_X_Atom  *list,
330                              unsigned int   num)
331 {
332    ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_ATOM, list, num);
333 }
334
335 /**
336  * Sends the GetProperty request.
337  * @param window Window whose properties are requested.
338  * @param atom   Property atom.
339  */
340 EAPI void
341 ecore_x_window_prop_atom_get_prefetch(Ecore_X_Window window,
342                                       Ecore_X_Atom   atom)
343 {
344    xcb_get_property_cookie_t cookie;
345
346    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
347                                        window,
348                                        atom,
349                                        ECORE_X_ATOM_ATOM,
350                                        0, 0x7fffffff);
351    _ecore_xcb_cookie_cache(cookie.sequence);
352 }
353
354
355 /**
356  * Gets the reply of the GetProperty request sent by ecore_x_window_prop_atom_get_prefetch().
357  */
358 EAPI void
359 ecore_x_window_prop_atom_get_fetch(void)
360 {
361    xcb_get_property_cookie_t cookie;
362    xcb_get_property_reply_t *reply;
363
364    cookie.sequence = _ecore_xcb_cookie_get();
365    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
366    _ecore_xcb_reply_cache(reply);
367 }
368
369 /*
370  * Get Atom (array) property
371  *
372  * At most len items are returned in val.
373  * If the property was successfully fetched the number of items stored in
374  * val is returned, otherwise -1 is returned.
375  * Note: Return value 0 means that the property exists but has no elements.
376  */
377 EAPI int
378 ecore_x_window_prop_atom_get(Ecore_X_Window win,
379                              Ecore_X_Atom   atom,
380                              Ecore_X_Atom  *list,
381                              unsigned int len)
382 {
383    return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_ATOM, list, len);
384 }
385
386 /*
387  * Get Atom (array) property
388  *
389  * If the property was successfully fetched the number of items stored in
390  * val is returned, otherwise -1 is returned.
391  * The returned array must be freed with free().
392  * Note: Return value 0 means that the property exists but has no elements.
393  */
394 EAPI int
395 ecore_x_window_prop_atom_list_get(Ecore_X_Window win,
396                                   Ecore_X_Atom   atom,
397                                   Ecore_X_Atom **plist)
398 {
399    return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_ATOM, plist);
400 }
401
402 /*
403  * Remove/add/toggle atom list item.
404  */
405 EAPI void
406 ecore_x_window_prop_atom_list_change(Ecore_X_Window win,
407                                      Ecore_X_Atom   atom,
408                                      Ecore_X_Atom   item,
409                                      int            op)
410 {
411    ecore_x_window_prop_xid_list_change(win, atom, ECORE_X_ATOM_ATOM, item, op);
412 }
413
414 /*
415  * Set Window (array) property
416  */
417 EAPI void
418 ecore_x_window_prop_window_set(Ecore_X_Window  win,
419                                Ecore_X_Atom    atom,
420                                Ecore_X_Window *list,
421                                unsigned int    num)
422 {
423    ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_WINDOW, list, num);
424 }
425
426 /**
427  * Sends the GetProperty request.
428  * @param window Window whose properties are requested.
429  * @param atom   The atom.
430  */
431 EAPI void
432 ecore_x_window_prop_window_get_prefetch(Ecore_X_Window window,
433                                         Ecore_X_Atom   atom)
434 {
435    xcb_get_property_cookie_t cookie;
436
437    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
438                                        window,
439                                        atom,
440                                        ECORE_X_ATOM_WINDOW,
441                                        0, 0x7fffffff);
442    _ecore_xcb_cookie_cache(cookie.sequence);
443 }
444
445
446 /**
447  * Gets the reply of the GetProperty request sent by ecore_x_window_prop_window_get_prefetch().
448  */
449 EAPI void
450 ecore_x_window_prop_window_get_fetch(void)
451 {
452    xcb_get_property_cookie_t cookie;
453    xcb_get_property_reply_t *reply;
454
455    cookie.sequence = _ecore_xcb_cookie_get();
456    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
457    _ecore_xcb_reply_cache(reply);
458 }
459
460 /*
461  * Get Window (array) property
462  *
463  * At most len items are returned in val.
464  * If the property was successfully fetched the number of items stored in
465  * val is returned, otherwise -1 is returned.
466  * Note: Return value 0 means that the property exists but has no elements.
467  */
468 EAPI int
469 ecore_x_window_prop_window_get(Ecore_X_Window  win,
470                                Ecore_X_Atom    atom,
471                                Ecore_X_Window *list,
472                                unsigned int    len)
473 {
474    return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_WINDOW, list, len);
475 }
476
477 /*
478  * Get Window (array) property
479  *
480  * If the property was successfully fetched the number of items stored in
481  * val is returned, otherwise -1 is returned.
482  * The returned array must be freed with free().
483  * Note: Return value 0 means that the property exists but has no elements.
484  */
485 EAPI int
486 ecore_x_window_prop_window_list_get(Ecore_X_Window   win,
487                                     Ecore_X_Atom     atom,
488                                     Ecore_X_Window **plist)
489 {
490    return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_WINDOW, plist);
491 }
492
493 /**
494  * To be documented.
495  *
496  * FIXME: To be fixed.
497  */
498 EAPI Ecore_X_Atom
499 ecore_x_window_prop_any_type(void)
500 {
501    return XCB_GET_PROPERTY_TYPE_ANY;
502 }
503
504 /**
505  * To be documented.
506  * @param window   The window.
507  * @param property The property atom.
508  * @param type     The type atom.
509  * @param size     The size.
510  * @param data     The data.
511  * @param number   The size of the data.
512  *
513  * FIXME: To be fixed.
514  */
515 EAPI void
516 ecore_x_window_prop_property_set(Ecore_X_Window window,
517                                  Ecore_X_Atom   property,
518                                  Ecore_X_Atom   type,
519                                  int            size,
520                                  void          *data,
521                                  int            number)
522 {
523    if (window == 0) window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
524    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
525                        property, type,
526                        size, number, data);
527 }
528
529 /**
530  * Sends the GetProperty request.
531  * @param window   Window whose properties are requested.
532  * @param property Property atom.
533  * @param type     Type atom.
534  */
535 EAPI void
536 ecore_x_window_prop_property_get_prefetch(Ecore_X_Window window,
537                                           Ecore_X_Atom   property,
538                                           Ecore_X_Atom   type)
539 {
540    xcb_get_property_cookie_t cookie;
541
542    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
543                                        window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
544                                        property, type, 0, LONG_MAX);
545    _ecore_xcb_cookie_cache(cookie.sequence);
546 }
547
548
549 /**
550  * Gets the reply of the GetProperty request sent by ecore_x_window_prop_property_get_prefetch().
551  */
552 EAPI void
553 ecore_x_window_prop_property_get_fetch(void)
554 {
555    xcb_get_property_cookie_t cookie;
556    xcb_get_property_reply_t *reply;
557
558    cookie.sequence = _ecore_xcb_cookie_get();
559    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
560    _ecore_xcb_reply_cache(reply);
561 }
562
563 /**
564  * To be documented.
565  * @param window   The window (Unused).
566  * @param property The property atom (Unused).
567  * @param type     The type atom (Unused).
568  * @param size     The size (Unused).
569  * @param data     The returned data.
570  * @param num      The size of the data.
571  * @return         1 on success, 0 otherwise.
572  *
573  * FIXME: To be fixed.
574  */
575 EAPI int
576 ecore_x_window_prop_property_get(Ecore_X_Window  window __UNUSED__,
577                                  Ecore_X_Atom    property __UNUSED__,
578                                  Ecore_X_Atom    type __UNUSED__,
579                                  int             size __UNUSED__,
580                                  unsigned char **data,
581                                  int            *num)
582 {
583    xcb_get_property_reply_t *reply;
584
585    /* make sure these are initialized */
586    if (num) *num = 0L;
587
588    if (data)
589      *data = NULL;
590    else /* we can't store the retrieved data, so just return */
591      return 0;
592
593    reply = _ecore_xcb_reply_get();
594    if (!reply)
595      return 0;
596
597    if ((reply->format != size) ||
598        (reply->value_len == 0))
599       return 0;
600
601    *data = malloc(reply->value_len);
602    if (!*data)
603       return 0;
604
605    memcpy(*data, xcb_get_property_value(reply), 
606           xcb_get_property_value_length(reply));
607
608    if (num)
609       *num = reply->value_len;
610
611    return reply->format;
612 }
613
614 EAPI void
615 ecore_x_window_prop_property_del(Ecore_X_Window window,
616                                  Ecore_X_Atom   property)
617 {
618    xcb_delete_property(_ecore_xcb_conn, window, property);
619 }
620
621 /**
622  * Sends the ListProperties request.
623  * @param window Window whose properties are requested.
624  */
625 EAPI void
626 ecore_x_window_prop_list_prefetch(Ecore_X_Window window)
627 {
628    xcb_list_properties_cookie_t cookie;
629
630    cookie = xcb_list_properties_unchecked(_ecore_xcb_conn, window);
631    _ecore_xcb_cookie_cache(cookie.sequence);
632 }
633
634
635 /**
636  * Gets the reply of the ListProperties request sent by ecore_x_window_prop_list_prefetch().
637  */
638 EAPI void
639 ecore_x_window_prop_list_fetch(void)
640 {
641    xcb_list_properties_cookie_t cookie;
642    xcb_list_properties_reply_t *reply;
643
644    cookie.sequence = _ecore_xcb_cookie_get();
645    reply = xcb_list_properties_reply(_ecore_xcb_conn, cookie, NULL);
646    _ecore_xcb_reply_cache(reply);
647 }
648
649
650 /**
651  * To be documented.
652  * @param window  The window (Unused).
653  * @param num_ret The number of atoms.
654  * @return        The returned atoms.
655  *
656  * FIXME: To be fixed.
657  */
658 EAPI Ecore_X_Atom *
659 ecore_x_window_prop_list(Ecore_X_Window window __UNUSED__,
660                          int           *num_ret)
661 {
662    xcb_list_properties_reply_t *reply;
663    Ecore_X_Atom                *atoms;
664
665    if (num_ret) *num_ret = 0;
666
667    reply = _ecore_xcb_reply_get();
668    if (!reply)
669       return NULL;
670
671    atoms = (Ecore_X_Atom *)malloc(reply->atoms_len * sizeof(Ecore_X_Atom));
672    if (!atoms)
673       return NULL;
674    memcpy(atoms,
675           xcb_list_properties_atoms(reply),
676           reply->atoms_len * sizeof(Ecore_X_Atom));
677    if(num_ret)
678      *num_ret = reply->atoms_len;
679
680    return atoms;
681 }
682
683 /**
684  * Set a window string property.
685  * @param win The window
686  * @param type The property
687  * @param str The string
688  *
689  * Set a window string property
690  */
691 EAPI void
692 ecore_x_window_prop_string_set(Ecore_X_Window win,
693                                Ecore_X_Atom   type,
694                                const char    *str)
695 {
696    if (win == 0) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
697    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
698                      type, ECORE_X_ATOM_UTF8_STRING,
699                      8, strlen(str), str);
700 }
701
702 /**
703  * Sends the GetProperty request.
704  * @param window Window whose properties are requested.
705  * @param type   The atom.
706  */
707 EAPI void
708 ecore_x_window_prop_string_get_prefetch(Ecore_X_Window window,
709                                         Ecore_X_Atom   type)
710 {
711    xcb_get_property_cookie_t cookie;
712
713    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
714                                        window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
715                                        type, XCB_GET_PROPERTY_TYPE_ANY, 0L, 1000000L);
716    _ecore_xcb_cookie_cache(cookie.sequence);
717 }
718
719
720 /**
721  * Gets the reply of the GetProperty request sent by ecore_x_window_prop_string_get_prefetch().
722  */
723 EAPI void
724 ecore_x_window_prop_string_get_fetch(void)
725 {
726    xcb_get_property_cookie_t cookie;
727    xcb_get_property_reply_t *reply;
728
729    cookie.sequence = _ecore_xcb_cookie_get();
730    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
731    _ecore_xcb_reply_cache(reply);
732 }
733
734 /**
735  * Get a window string property.
736  * @param window The window
737  * @param type The property
738  *
739  * Return window string property of a window. String must be free'd when done.
740  *
741  * To use this function, you must call before, and in order,
742  * ecore_x_window_prop_string_get_prefetch(), which sends the GetProperty request,
743  * then ecore_x_window_prop_string_get_fetch(), which gets the reply.
744  */
745 EAPI char *
746 ecore_x_window_prop_string_get(Ecore_X_Window window __UNUSED__,
747                                Ecore_X_Atom   type __UNUSED__)
748 {
749    xcb_get_property_reply_t *reply;
750    char                     *str = NULL;
751
752    reply = _ecore_xcb_reply_get();
753    if (!reply)
754      return NULL;
755
756    if (reply->type == ECORE_X_ATOM_UTF8_STRING)
757      {
758         int length;
759
760         length = reply->value_len;
761         str = (char *)malloc(length + 1);
762         memcpy(str,
763                xcb_get_property_value(reply),
764                length);
765         str[length] = '\0';
766      }
767    else
768      {
769        /* FIXME: to be done... */
770
771 /* #ifdef X_HAVE_UTF8_STRING */
772 /*         s = Xutf8TextPropertyToTextList(_ecore_xcb_conn, &xtp, */
773 /*                                         &list, &items); */
774 /* #else */
775 /*         s = XmbTextPropertyToTextList(_ecore_xcb_conn, &xtp, */
776 /*                                       &list, &items); */
777 /* #endif */
778 /*         if ((s == XLocaleNotSupported) || */
779 /*             (s == XNoMemory) || (s == XConverterNotFound)) */
780 /*           { */
781 /*              str = strdup((char *)xtp.value); */
782 /*           } */
783 /*         else if ((s >= Success) && (items > 0)) */
784 /*           { */
785 /*              str = strdup(list[0]); */
786 /*           } */
787 /*         if (list) */
788 /*            XFreeStringList(list); */
789      }
790
791    return str;
792 }
793
794 /* FIXME : round trips because of GetWMProtocols */
795 /*         should we rewrite its code ? */
796 EAPI int
797 ecore_x_window_prop_protocol_isset(Ecore_X_Window      window,
798                                    Ecore_X_WM_Protocol protocol)
799 {
800    xcb_get_property_cookie_t    cookie;
801    xcb_get_wm_protocols_reply_t protocols;
802    Ecore_X_Atom                 proto;
803    uint32_t                     i;
804    uint8_t                      ret = 0;
805
806    /* check for invalid values */
807    if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
808         return ret;
809
810    proto = _ecore_xcb_atoms_wm_protocols[protocol];
811
812    cookie = xcb_get_wm_protocols(_ecore_xcb_conn, window, ECORE_X_ATOM_WM_PROTOCOLS);
813
814    if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protocols, NULL))
815      return ret;
816
817    for (i = 0; i < protocols.atoms_len; i++)
818      if (protocols.atoms[i] == proto)
819        {
820           ret = 1;
821           break;
822        }
823
824    xcb_get_wm_protocols_reply_wipe(&protocols);
825
826    return ret;
827 }
828
829 /**
830  * To be documented.
831  * @param window  The window.
832  * @param num_ret The number of WM protocols.
833  * @return        The returned WM protocols.
834  *
835  * FIXME: To be fixed.
836  */
837
838 /* FIXME : round trips because of get_wm_protocols */
839 /*         should we rewrite its code ? */
840
841 EAPI Ecore_X_WM_Protocol *
842 ecore_x_window_prop_protocol_list_get(Ecore_X_Window window,
843                                       int           *num_ret)
844 {
845    xcb_get_property_cookie_t    cookie;
846    xcb_get_wm_protocols_reply_t protocols;
847    Ecore_X_WM_Protocol         *prot_ret = NULL;
848    uint32_t                     protos_count;
849    uint32_t                     i;
850
851    cookie = xcb_get_wm_protocols(_ecore_xcb_conn, window, ECORE_X_ATOM_WM_PROTOCOLS);
852
853    if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protocols, NULL))
854       return NULL;
855
856    if ((protocols.atoms_len <= 0)) return NULL;
857
858    prot_ret = calloc(1, protocols.atoms_len * sizeof(Ecore_X_WM_Protocol));
859    if (!prot_ret)
860      {
861         xcb_get_wm_protocols_reply_wipe(&protocols);
862         return NULL;
863      }
864    for (i = 0; i < protocols.atoms_len; i++)
865      {
866         Ecore_X_WM_Protocol j;
867
868         prot_ret[i] = -1;
869         for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++)
870           {
871              if (_ecore_xcb_atoms_wm_protocols[j] == protocols.atoms[i])
872                prot_ret[i] = j;
873           }
874      }
875    xcb_get_wm_protocols_reply_wipe(&protocols);
876    *num_ret = protos_count;
877
878    return prot_ret;
879 }