1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif /* ifdef HAVE_CONFIG_H */
4 
5 #include <stdlib.h>
6 #include <string.h>
7 
8 #include "Ecore.h"
9 #include "ecore_x_private.h"
10 #include "Ecore_X.h"
11 #include "Ecore_X_Atoms.h"
12 #include <inttypes.h>
13 #include <limits.h>
14 
15 #define _ATOM_SET_CARD32(win, atom, p_val, cnt)                               \
16   XChangeProperty(_ecore_x_disp, win, atom, XA_CARDINAL, 32, PropModeReplace, \
17                   (unsigned char *)p_val, cnt)
18 
19 /*
20  * Set CARD32 (array) property
21  */
22 EAPI void
ecore_x_window_prop_card32_set(Ecore_X_Window win,Ecore_X_Atom atom,unsigned int * val,unsigned int num)23 ecore_x_window_prop_card32_set(Ecore_X_Window win,
24                                Ecore_X_Atom atom,
25                                unsigned int *val,
26                                unsigned int num)
27 {
28 #if SIZEOF_INT == SIZEOF_LONG
29    _ATOM_SET_CARD32(win, atom, val, num);
30 #else /* if SIZEOF_INT == SIZEOF_LONG */
31    long *v2;
32    unsigned int i;
33 
34    LOGFN;
35    v2 = malloc(num * sizeof(long));
36    if (!v2)
37      return;
38 
39    for (i = 0; i < num; i++)
40      v2[i] = val[i];
41    _ATOM_SET_CARD32(win, atom, v2, num);
42    free(v2);
43 #endif /* if SIZEOF_INT == SIZEOF_LONG */
44    if (_ecore_xlib_sync) ecore_x_sync();
45 }
46 
47 /*
48  * Get CARD32 (array) property
49  *
50  * At most len items are returned in val.
51  * If the property was successfully fetched the number of items stored in
52  * val is returned, otherwise -1 is returned.
53  * Note: Return value 0 means that the property exists but has no elements.
54  */
55 EAPI int
ecore_x_window_prop_card32_get(Ecore_X_Window win,Ecore_X_Atom atom,unsigned int * val,unsigned int len)56 ecore_x_window_prop_card32_get(Ecore_X_Window win,
57                                Ecore_X_Atom atom,
58                                unsigned int *val,
59                                unsigned int len)
60 {
61    unsigned char *prop_ret;
62    Atom type_ret;
63    unsigned long bytes_after, num_ret;
64    int format_ret;
65    unsigned int i;
66    int num;
67 
68    LOGFN;
69    prop_ret = NULL;
70    if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
71                           XA_CARDINAL, &type_ret, &format_ret, &num_ret,
72                           &bytes_after, &prop_ret) != Success)
73      return -1;
74 
75    if (type_ret != XA_CARDINAL || format_ret != 32)
76      num = -1;
77    else if (num_ret == 0 || !prop_ret)
78      num = 0;
79    else
80      {
81         if (num_ret < len)
82           len = num_ret;
83 
84         if (val)
85           for (i = 0; i < len; i++)
86             val[i] = ((unsigned long *)prop_ret)[i];
87         num = len;
88      }
89 
90    if (_ecore_xlib_sync) ecore_x_sync();
91    if (prop_ret)
92      XFree(prop_ret);
93    return num;
94 }
95 
96 /*
97  * Get CARD32 (array) property of any length
98  *
99  * If the property was successfully fetched the number of items stored in
100  * val is returned, otherwise -1 is returned.
101  * Note: Return value 0 means that the property exists but has no elements.
102  */
103 EAPI int
ecore_x_window_prop_card32_list_get(Ecore_X_Window win,Ecore_X_Atom atom,unsigned int ** plst)104 ecore_x_window_prop_card32_list_get(Ecore_X_Window win,
105                                     Ecore_X_Atom atom,
106                                     unsigned int **plst)
107 {
108    unsigned char *prop_ret;
109    Atom type_ret;
110    unsigned long bytes_after, num_ret;
111    int format_ret;
112    unsigned int i, *val;
113    int num;
114 
115    LOGFN;
116    if (plst) *plst = NULL;
117    prop_ret = NULL;
118    if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
119                           XA_CARDINAL, &type_ret, &format_ret, &num_ret,
120                           &bytes_after, &prop_ret) != Success)
121      return -1;
122 
123    if ((type_ret != XA_CARDINAL) || (format_ret != 32))
124      num = -1;
125    else if ((num_ret == 0) || (!prop_ret))
126      num = 0;
127    else if (plst)
128      {
129         val = malloc(num_ret * sizeof(unsigned int));
130         if (!val)
131           {
132              if (prop_ret) XFree(prop_ret);
133              return -1;
134           }
135         for (i = 0; i < num_ret; i++)
136           val[i] = ((unsigned long *)prop_ret)[i];
137         num = num_ret;
138         *plst = val;
139      }
140    else
141      num = num_ret;
142 
143    if (_ecore_xlib_sync) ecore_x_sync();
144    if (prop_ret)
145      XFree(prop_ret);
146    return num;
147 }
148 
149 /*
150  * Set X ID (array) property
151  */
152 EAPI void
ecore_x_window_prop_xid_set(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Atom type,Ecore_X_ID * lst,unsigned int num)153 ecore_x_window_prop_xid_set(Ecore_X_Window win,
154                             Ecore_X_Atom atom,
155                             Ecore_X_Atom type,
156                             Ecore_X_ID *lst,
157                             unsigned int num)
158 {
159 #if SIZEOF_INT == SIZEOF_LONG
160    XChangeProperty(_ecore_x_disp, win, atom, type, 32, PropModeReplace,
161                    (unsigned char *)lst, num);
162 #else /* if SIZEOF_INT == SIZEOF_LONG */
163    unsigned long *pl;
164    unsigned int i;
165 
166    LOGFN;
167    pl = malloc(num * sizeof(unsigned long));
168    if (!pl)
169      return;
170 
171    for (i = 0; i < num; i++)
172      pl[i] = lst[i];
173    XChangeProperty(_ecore_x_disp, win, atom, type, 32, PropModeReplace,
174                    (unsigned char *)pl, num);
175    free(pl);
176 #endif /* if SIZEOF_INT == SIZEOF_LONG */
177    if (_ecore_xlib_sync) ecore_x_sync();
178 }
179 
180 /*
181  * Get X ID (array) property
182  *
183  * At most len items are returned in val.
184  * If the property was successfully fetched the number of items stored in
185  * val is returned, otherwise -1 is returned.
186  * Note: Return value 0 means that the property exists but has no elements.
187  */
188 EAPI int
ecore_x_window_prop_xid_get(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Atom type,Ecore_X_ID * lst,unsigned int len)189 ecore_x_window_prop_xid_get(Ecore_X_Window win,
190                             Ecore_X_Atom atom,
191                             Ecore_X_Atom type,
192                             Ecore_X_ID *lst,
193                             unsigned int len)
194 {
195    unsigned char *prop_ret;
196    Atom type_ret;
197    unsigned long bytes_after, num_ret;
198    int format_ret;
199    int num;
200    unsigned i;
201    Eina_Bool success;
202 
203    LOGFN;
204    prop_ret = NULL;
205    success = (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
206                           type, &type_ret, &format_ret, &num_ret,
207                           &bytes_after, &prop_ret) == Success);
208    if (_ecore_xlib_sync) ecore_x_sync();
209    if (!success) return -1;
210 
211    if (type_ret != type || format_ret != 32)
212      num = -1;
213    else if (num_ret == 0 || !prop_ret)
214      num = 0;
215    else
216      {
217         if (num_ret < len)
218           len = num_ret;
219 
220         if (lst)
221           for (i = 0; i < len; i++)
222             lst[i] = ((unsigned long *)prop_ret)[i];
223         num = len;
224      }
225 
226    if (prop_ret)
227      XFree(prop_ret);
228 
229    return num;
230 }
231 
232 /*
233  * Get X ID (array) property
234  *
235  * If the property was successfully fetched the number of items stored in
236  * val is returned, otherwise -1 is returned.
237  * The returned array must be freed with free().
238  * Note: Return value 0 means that the property exists but has no elements.
239  */
240 EAPI int
ecore_x_window_prop_xid_list_get(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Atom type,Ecore_X_ID ** val)241 ecore_x_window_prop_xid_list_get(Ecore_X_Window win,
242                                  Ecore_X_Atom atom,
243                                  Ecore_X_Atom type,
244                                  Ecore_X_ID **val)
245 {
246    unsigned char *prop_ret;
247    Atom type_ret;
248    unsigned long bytes_after, num_ret;
249    int format_ret;
250    Ecore_X_Atom *alst;
251    int num;
252    unsigned i;
253    Eina_Bool success;
254 
255    LOGFN;
256    if (val) *val = NULL;
257    prop_ret = NULL;
258    success = (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
259                           type, &type_ret, &format_ret, &num_ret,
260                           &bytes_after, &prop_ret) == Success);
261    if (_ecore_xlib_sync) ecore_x_sync();
262    if (!success) return -1;
263 
264    if (type_ret != type || format_ret != 32)
265      num = -1;
266    else if (num_ret == 0 || !prop_ret)
267      num = 0;
268    else if (val)
269      {
270         alst = malloc(num_ret * sizeof(Ecore_X_ID));
271         for (i = 0; i < num_ret; i++)
272           alst[i] = ((unsigned long *)prop_ret)[i];
273         num = num_ret;
274         *val = alst;
275      }
276    else
277      num = num_ret;
278 
279    if (prop_ret)
280      XFree(prop_ret);
281    return num;
282 }
283 
284 /*
285  * Remove/add/toggle X ID list item.
286  */
287 EAPI void
ecore_x_window_prop_xid_list_change(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Atom type,Ecore_X_ID item,int op)288 ecore_x_window_prop_xid_list_change(Ecore_X_Window win,
289                                     Ecore_X_Atom atom,
290                                     Ecore_X_Atom type,
291                                     Ecore_X_ID item,
292                                     int op)
293 {
294    Ecore_X_ID *lst, *temp;
295    int i, num;
296 
297    LOGFN;
298    num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst);
299    if (num < 0)
300      {
301         return; /* Error - assuming invalid window */
302      }
303 
304    /* Is it there? */
305    for (i = 0; i < num; i++)
306      {
307         if (lst[i] == item)
308           break;
309      }
310 
311    if (i < num)
312      {
313         /* Was in list */
314         if (op == ECORE_X_PROP_LIST_ADD)
315           goto done;  /* Remove it */
316 
317         num--;
318         for (; i < num; i++)
319           lst[i] = lst[i + 1];
320      }
321    else
322      {
323         /* Was not in list */
324         if (op == ECORE_X_PROP_LIST_REMOVE)
325           goto done;  /* Add it */
326 
327         num++;
328 
329         temp = lst;
330         lst = realloc(lst, num * sizeof(Ecore_X_ID));
331         if (lst)
332           {
333              lst[i] = item;
334           }
335         else
336           {
337              lst = temp;
338              num--;
339           }
340      }
341 
342    ecore_x_window_prop_xid_set(win, atom, type, lst, num);
343 
344 done:
345    if (lst)
346      free(lst);
347 }
348 
349 /*
350  * Set Atom (array) property
351  */
352 EAPI void
ecore_x_window_prop_atom_set(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Atom * lst,unsigned int num)353 ecore_x_window_prop_atom_set(Ecore_X_Window win,
354                              Ecore_X_Atom atom,
355                              Ecore_X_Atom *lst,
356                              unsigned int num)
357 {
358    LOGFN;
359    ecore_x_window_prop_xid_set(win, atom, XA_ATOM, lst, num);
360 }
361 
362 /*
363  * Get Atom (array) property
364  *
365  * At most len items are returned in val.
366  * If the property was successfully fetched the number of items stored in
367  * val is returned, otherwise -1 is returned.
368  * Note: Return value 0 means that the property exists but has no elements.
369  */
370 EAPI int
ecore_x_window_prop_atom_get(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Atom * lst,unsigned int len)371 ecore_x_window_prop_atom_get(Ecore_X_Window win,
372                              Ecore_X_Atom atom,
373                              Ecore_X_Atom *lst,
374                              unsigned int len)
375 {
376    int ret;
377    LOGFN;
378    ret = ecore_x_window_prop_xid_get(win, atom, XA_ATOM, lst, len);
379    return ret;
380 }
381 
382 /*
383  * Get Atom (array) property
384  *
385  * If the property was successfully fetched the number of items stored in
386  * val is returned, otherwise -1 is returned.
387  * The returned array must be freed with free().
388  * Note: Return value 0 means that the property exists but has no elements.
389  */
390 EAPI int
ecore_x_window_prop_atom_list_get(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Atom ** plst)391 ecore_x_window_prop_atom_list_get(Ecore_X_Window win,
392                                   Ecore_X_Atom atom,
393                                   Ecore_X_Atom **plst)
394 {
395    int ret;
396    LOGFN;
397    ret = ecore_x_window_prop_xid_list_get(win, atom, XA_ATOM, plst);
398    return ret;
399 }
400 
401 /*
402  * Remove/add/toggle atom list item.
403  */
404 EAPI void
ecore_x_window_prop_atom_list_change(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Atom item,int op)405 ecore_x_window_prop_atom_list_change(Ecore_X_Window win,
406                                      Ecore_X_Atom atom,
407                                      Ecore_X_Atom item,
408                                      int op)
409 {
410    LOGFN;
411    ecore_x_window_prop_xid_list_change(win, atom, XA_ATOM, item, op);
412 }
413 
414 /*
415  * Set Window (array) property
416  */
417 EAPI void
ecore_x_window_prop_window_set(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Window * lst,unsigned int num)418 ecore_x_window_prop_window_set(Ecore_X_Window win,
419                                Ecore_X_Atom atom,
420                                Ecore_X_Window *lst,
421                                unsigned int num)
422 {
423    LOGFN;
424    ecore_x_window_prop_xid_set(win, atom, XA_WINDOW, lst, num);
425 }
426 
427 /*
428  * Get Window (array) property
429  *
430  * At most len items are returned in val.
431  * If the property was successfully fetched the number of items stored in
432  * val is returned, otherwise -1 is returned.
433  * Note: Return value 0 means that the property exists but has no elements.
434  */
435 EAPI int
ecore_x_window_prop_window_get(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Window * lst,unsigned int len)436 ecore_x_window_prop_window_get(Ecore_X_Window win,
437                                Ecore_X_Atom atom,
438                                Ecore_X_Window *lst,
439                                unsigned int len)
440 {
441    int ret;
442    LOGFN;
443    ret = ecore_x_window_prop_xid_get(win, atom, XA_WINDOW, lst, len);
444    return ret;
445 }
446 
447 /*
448  * Get Window (array) property
449  *
450  * If the property was successfully fetched the number of items stored in
451  * val is returned, otherwise -1 is returned.
452  * The returned array must be freed with free().
453  * Note: Return value 0 means that the property exists but has no elements.
454  */
455 EAPI int
ecore_x_window_prop_window_list_get(Ecore_X_Window win,Ecore_X_Atom atom,Ecore_X_Window ** plst)456 ecore_x_window_prop_window_list_get(Ecore_X_Window win,
457                                     Ecore_X_Atom atom,
458                                     Ecore_X_Window **plst)
459 {
460    int ret;
461    LOGFN;
462    ret = ecore_x_window_prop_xid_list_get(win, atom, XA_WINDOW, plst);
463    return ret;
464 }
465 
466 EAPI Ecore_X_Atom
ecore_x_window_prop_any_type(void)467 ecore_x_window_prop_any_type(void)
468 {
469    return AnyPropertyType;
470 }
471 
472 /**
473  * @brief Set a property of Ecore_X_Window.
474  * @param win The window for which the property will be set.
475  * @param property The property of the window to be set.
476  * @param type The type of the property that will be set.
477  * @param size The size of the property that will be set.
478  * @param data The data of the property that will be set.
479  * @param number The size of data.
480  */
481 EAPI void
ecore_x_window_prop_property_set(Ecore_X_Window win,Ecore_X_Atom property,Ecore_X_Atom type,int size,void * data,int number)482 ecore_x_window_prop_property_set(Ecore_X_Window win,
483                                  Ecore_X_Atom property,
484                                  Ecore_X_Atom type,
485                                  int size,
486                                  void *data,
487                                  int number)
488 {
489    LOGFN;
490    if (win == 0)
491      win = DefaultRootWindow(_ecore_x_disp);
492 
493    if (size != 32)
494      XChangeProperty(_ecore_x_disp,
495                      win,
496                      property,
497                      type,
498                      size,
499                      PropModeReplace,
500                      (unsigned char *)data,
501                      number);
502    else
503      {
504         unsigned long *dat;
505         int i, *ptr;
506 
507         dat = malloc(sizeof(unsigned long) * number);
508         if (dat)
509           {
510              for (ptr = (int *)data, i = 0; i < number; i++)
511                dat[i] = ptr[i];
512              XChangeProperty(_ecore_x_disp, win, property, type, size,
513                              PropModeReplace, (unsigned char *)dat, number);
514              free(dat);
515           }
516      }
517    if (_ecore_xlib_sync) ecore_x_sync();
518 }
519 
520 /**
521  * @brief Get a property of Ecore_X_Window.
522  * @note If there aren't any data to be got the function return NULL.
523  *       If the function can't allocate the memory then 0 is returned.
524  * @param win The window for which the property will be got.
525  * @param property The property of the window that will be gotten.
526  * @param type The type of the property that will be gotten.
527  * @param size This parameter isn't in use.
528  * @param data The data of the property that will be gotten.
529  * @param num The size of property.
530  * @return size_ret The size of array that contains the property.
531  */
532 EAPI int
ecore_x_window_prop_property_get(Ecore_X_Window win,Ecore_X_Atom property,Ecore_X_Atom type,int size EINA_UNUSED,unsigned char ** data,int * num)533 ecore_x_window_prop_property_get(Ecore_X_Window win,
534                                  Ecore_X_Atom property,
535                                  Ecore_X_Atom type,
536                                  int size EINA_UNUSED,
537                                  unsigned char **data,
538                                  int *num)
539 {
540    Atom type_ret = 0;
541    int ret, size_ret = 0;
542    unsigned long num_ret = 0, bytes = 0, i;
543    unsigned char *prop_ret = NULL;
544 
545    /* make sure these are initialized */
546    if (num)
547      *num = 0;
548 
549    if (data)
550      *data = NULL;
551    else /* we can't store the retrieved data, so just return */
552      return 0;
553 
554    LOGFN;
555    if (!win)
556      win = DefaultRootWindow(_ecore_x_disp);
557 
558    ret = XGetWindowProperty(_ecore_x_disp, win, property, 0, LONG_MAX,
559                             False, type, &type_ret, &size_ret,
560                             &num_ret, &bytes, &prop_ret);
561    if (_ecore_xlib_sync) ecore_x_sync();
562    if (ret != Success)
563      return 0;
564    if ((!num_ret) || (size_ret <= 0))
565      {
566         XFree(prop_ret);
567         return 0;
568      }
569 
570    if (!(*data = malloc(num_ret * size_ret / 8)))
571      {
572         XFree(prop_ret);
573         return 0;
574      }
575 
576    switch (size_ret) {
577       case 8:
578         for (i = 0; i < num_ret; i++)
579           (*data)[i] = prop_ret[i];
580         break;
581 
582       case 16:
583         for (i = 0; i < num_ret; i++)
584           ((unsigned short *)*data)[i] = ((unsigned short *)prop_ret)[i];
585         break;
586 
587       case 32:
588         for (i = 0; i < num_ret; i++)
589           ((unsigned int *)*data)[i] = ((unsigned long *)prop_ret)[i];
590         break;
591      }
592 
593    XFree(prop_ret);
594 
595    if (num)
596      *num = num_ret;
597 
598    return size_ret;
599 }
600 
601 EAPI void
ecore_x_window_prop_property_del(Ecore_X_Window win,Ecore_X_Atom property)602 ecore_x_window_prop_property_del(Ecore_X_Window win,
603                                  Ecore_X_Atom property)
604 {
605    LOGFN;
606    XDeleteProperty(_ecore_x_disp, win, property);
607    if (_ecore_xlib_sync) ecore_x_sync();
608 }
609 
610 EAPI Ecore_X_Atom *
ecore_x_window_prop_list(Ecore_X_Window win,int * num_ret)611 ecore_x_window_prop_list(Ecore_X_Window win,
612                          int *num_ret)
613 {
614    Ecore_X_Atom *atoms;
615    Atom *atom_ret;
616    int num = 0, i;
617 
618    LOGFN;
619    if (num_ret)
620      *num_ret = 0;
621 
622    atom_ret = XListProperties(_ecore_x_disp, win, &num);
623    if (_ecore_xlib_sync) ecore_x_sync();
624    if (!atom_ret)
625      return NULL;
626 
627    atoms = malloc(num * sizeof(Ecore_X_Atom));
628    if (atoms)
629      {
630         for (i = 0; i < num; i++)
631           atoms[i] = atom_ret[i];
632         if (num_ret)
633           *num_ret = num;
634      }
635 
636    XFree(atom_ret);
637    return atoms;
638 }
639 
640 /**
641  * Set a window string property.
642  * @param win The window
643  * @param type The property
644  * @param str The string
645  *
646  * Set a window string property
647  */
648 EAPI void
ecore_x_window_prop_string_set(Ecore_X_Window win,Ecore_X_Atom type,const char * str)649 ecore_x_window_prop_string_set(Ecore_X_Window win,
650                                Ecore_X_Atom type,
651                                const char *str)
652 {
653    XTextProperty xtp;
654 
655    LOGFN;
656    if (win == 0)
657      win = DefaultRootWindow(_ecore_x_disp);
658 
659    xtp.value = (unsigned char *)str;
660    xtp.format = 8;
661    xtp.encoding = ECORE_X_ATOM_UTF8_STRING;
662    xtp.nitems = strlen(str);
663    XSetTextProperty(_ecore_x_disp, win, &xtp, type);
664    if (_ecore_xlib_sync) ecore_x_sync();
665 }
666 
667 /**
668  * Get a window string property.
669  * @param win The window
670  * @param type The property
671  * @return Window string property of a window. String must be free'd when done.
672  */
673 EAPI char *
ecore_x_window_prop_string_get(Ecore_X_Window win,Ecore_X_Atom type)674 ecore_x_window_prop_string_get(Ecore_X_Window win,
675                                Ecore_X_Atom type)
676 {
677    XTextProperty xtp;
678    char *str = NULL;
679 
680    LOGFN;
681    if (win == 0)
682      win = DefaultRootWindow(_ecore_x_disp);
683 
684    if (XGetTextProperty(_ecore_x_disp, win, &xtp, type))
685      {
686         int items;
687         char **list = NULL;
688         Status s;
689 
690         if (_ecore_xlib_sync) ecore_x_sync();
691         if (xtp.encoding == ECORE_X_ATOM_UTF8_STRING)
692           str = strdup((char *)xtp.value);
693         else
694           {
695 #ifdef X_HAVE_UTF8_STRING
696              s = Xutf8TextPropertyToTextList(_ecore_x_disp, &xtp,
697                                              &list, &items);
698 #else /* ifdef X_HAVE_UTF8_STRING */
699              s = XmbTextPropertyToTextList(_ecore_x_disp, &xtp,
700                                            &list, &items);
701 #endif /* ifdef X_HAVE_UTF8_STRING */
702              if (_ecore_xlib_sync) ecore_x_sync();
703              if ((s == XLocaleNotSupported) ||
704                  (s == XNoMemory) || (s == XConverterNotFound))
705                str = strdup((char *)xtp.value);
706              else if ((s >= Success) && (items > 0))
707                str = strdup(list[0]);
708 
709              if (list)
710                XFreeStringList(list);
711           }
712 
713         XFree(xtp.value);
714      }
715    return str;
716 }
717 
718 EAPI Eina_Bool
ecore_x_window_prop_protocol_isset(Ecore_X_Window win,Ecore_X_WM_Protocol protocol)719 ecore_x_window_prop_protocol_isset(Ecore_X_Window win,
720                                    Ecore_X_WM_Protocol protocol)
721 {
722    Atom proto, *protos = NULL;
723    int i, protos_count = 0;
724    Eina_Bool ret = EINA_FALSE;
725 
726    /* check for invalid values */
727    if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
728      return EINA_FALSE;
729 
730    LOGFN;
731    proto = _ecore_x_atoms_wm_protocols[protocol];
732 
733    ret = XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count);
734    if (_ecore_xlib_sync) ecore_x_sync();
735    if (!ret)
736      return ret;
737 
738    for (i = 0; i < protos_count; i++)
739      if (protos[i] == proto)
740        {
741           ret = EINA_TRUE;
742           break;
743        }
744 
745    XFree(protos);
746    return ret;
747 }
748 
749 /**
750  * @brief Get a array containing the protocols of @a win
751  * @note If there aren't any properties to be counted or any protocols to get
752  *       then the function returns NULL.
753  * @param win The window for which protocol list will be got.
754  * @param num_ret Contains the number of elements of the array to be returned.
755  * @return The array that contains the protocols.
756  */
757 EAPI Ecore_X_WM_Protocol *
ecore_x_window_prop_protocol_list_get(Ecore_X_Window win,int * num_ret)758 ecore_x_window_prop_protocol_list_get(Ecore_X_Window win,
759                                       int *num_ret)
760 {
761    Atom *protos = NULL;
762    int i, protos_count = 0;
763    Ecore_X_WM_Protocol *prot_ret = NULL;
764    Eina_Bool success;
765 
766    LOGFN;
767    success = XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count);
768    if (_ecore_xlib_sync) ecore_x_sync();
769    if (!success)
770      return NULL;
771 
772    if ((!protos) || (protos_count <= 0))
773      return NULL;
774 
775    prot_ret = calloc(1, protos_count * sizeof(Ecore_X_WM_Protocol));
776    if (!prot_ret)
777      {
778         XFree(protos);
779         return NULL;
780      }
781 
782    for (i = 0; i < protos_count; i++)
783      {
784         Ecore_X_WM_Protocol j;
785 
786         prot_ret[i] = -1;
787         for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++)
788           {
789              if (_ecore_x_atoms_wm_protocols[j] == protos[i])
790                prot_ret[i] = j;
791           }
792      }
793    XFree(protos);
794    *num_ret = protos_count;
795    return prot_ret;
796 }
797 
798