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