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