Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_window_prop.c
1 #include "ecore_xcb_private.h"
2 #include <xcb/xcb_icccm.h>
3
4 EAPI int
5 ecore_x_window_prop_card32_get(Ecore_X_Window win,
6                                Ecore_X_Atom   atom,
7                                unsigned int  *val,
8                                unsigned int   len)
9 {
10    xcb_get_property_cookie_t cookie;
11    xcb_get_property_reply_t *reply;
12    int num = 0;
13
14    LOGFN(__FILE__, __LINE__, __FUNCTION__);
15    CHECK_XCB_CONN;
16
17    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom,
18                                        ECORE_X_ATOM_CARDINAL, 0, 0x7fffffff);
19    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
20    if (!reply) return -1;
21
22    if ((reply->type != ECORE_X_ATOM_CARDINAL) || (reply->format != 32))
23      num = -1;
24    else if (reply->value_len == 0)
25      num = 0;
26    else
27      {
28         if (reply->value_len < len)
29           len = reply->value_len;
30
31         if (val)
32           {
33              unsigned int i = 0;
34              unsigned char *v;
35
36              v = xcb_get_property_value(reply);
37              for (i = 0; i < len; i++)
38                val[i] = ((uint32_t *)v)[i];
39              num = len;
40           }
41      }
42
43    if (reply) free(reply);
44    return num;
45 }
46
47 EAPI void
48 ecore_x_window_prop_card32_set(Ecore_X_Window win,
49                                Ecore_X_Atom   atom,
50                                unsigned int  *val,
51                                unsigned int   num)
52 {
53    LOGFN(__FILE__, __LINE__, __FUNCTION__);
54    CHECK_XCB_CONN;
55
56 #if SIZEOF_INT == SIZEOF_LONG
57    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom,
58                        ECORE_X_ATOM_CARDINAL, 32, num, (unsigned char *)val);
59 //   ecore_x_flush();
60 #else
61    long *v2;
62    unsigned int i;
63
64    v2 = malloc(num * sizeof(long));
65    if (!v2) return;
66    for (i = 0; i < num; i++)
67      v2[i] = val[i];
68
69    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom,
70                        ECORE_X_ATOM_CARDINAL, 32, num, (unsigned char *)v2);
71    free(v2);
72 //   ecore_x_flush();
73 #endif
74 }
75
76 EAPI int
77 ecore_x_window_prop_card32_list_get(Ecore_X_Window win,
78                                     Ecore_X_Atom   atom,
79                                     unsigned int **list)
80 {
81    xcb_get_property_cookie_t cookie;
82    xcb_get_property_reply_t *reply;
83    int num = -1;
84
85    LOGFN(__FILE__, __LINE__, __FUNCTION__);
86    CHECK_XCB_CONN;
87
88    if (list) *list = NULL;
89
90    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom,
91                                        XCB_ATOM_CARDINAL, 0, 0x7fffffff);
92    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
93    if (!reply) return -1;
94
95    if ((reply->type != XCB_ATOM_CARDINAL) || (reply->format != 32))
96      num = -1;
97    else if ((reply->value_len == 0) || (!xcb_get_property_value(reply)))
98      num = 0;
99    else
100      {
101         num = reply->value_len;
102         if (list)
103           {
104              unsigned int *val;
105              void *data;
106              int i = 0;
107
108              val = malloc(num * sizeof(unsigned int));
109              if (!val)
110                {
111                   free(reply);
112                   return -1;
113                }
114              data = xcb_get_property_value(reply);
115              for (i = 0; i < num; i++)
116                val[i] = ((uint32_t *)data)[i];
117              *list = val;
118           }
119      }
120
121    free(reply);
122    return num;
123 }
124
125 EAPI int
126 ecore_x_window_prop_atom_get(Ecore_X_Window win,
127                              Ecore_X_Atom   atom,
128                              Ecore_X_Atom  *list,
129                              unsigned int   len)
130 {
131    LOGFN(__FILE__, __LINE__, __FUNCTION__);
132
133    return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_ATOM, list, len);
134 }
135
136 EAPI void
137 ecore_x_window_prop_atom_set(Ecore_X_Window win,
138                              Ecore_X_Atom   atom,
139                              Ecore_X_Atom  *list,
140                              unsigned int   num)
141 {
142    LOGFN(__FILE__, __LINE__, __FUNCTION__);
143
144    /* xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom,  */
145    /*                     ECORE_X_ATOM_ATOM, 32, num, list); */
146    ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_ATOM, list, num);
147 }
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    *xids,
154                             unsigned int   num)
155 {
156    LOGFN(__FILE__, __LINE__, __FUNCTION__);
157    CHECK_XCB_CONN;
158
159 #if SIZEOF_INT == SIZEOF_LONG
160    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom,
161                        type, 32, num, (unsigned char *)xids);
162 //   ecore_x_flush();
163 #else
164    long *v2;
165    unsigned int i;
166
167    v2 = malloc(num * sizeof(long));
168    if (!v2) return;
169    for (i = 0; i < num; i++)
170      v2[i] = xids[i];
171
172    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, atom,
173                        type, 32, num, (unsigned char *)v2);
174    free(v2);
175 //   ecore_x_flush();
176 #endif
177 }
178
179 EAPI int
180 ecore_x_window_prop_xid_get(Ecore_X_Window win,
181                             Ecore_X_Atom   atom,
182                             Ecore_X_Atom   type,
183                             Ecore_X_ID    *xids,
184                             unsigned int   len)
185 {
186    xcb_get_property_cookie_t cookie;
187    xcb_get_property_reply_t *reply;
188    int num = 0;
189
190    LOGFN(__FILE__, __LINE__, __FUNCTION__);
191    CHECK_XCB_CONN;
192
193    num = len;
194    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, type,
195                                        0, 0x7fffffff);
196    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
197    if (!reply) return -1;
198
199    if ((reply->type != type) || (reply->format != 32))
200      num = -1;
201    else if (reply->value_len == 0)
202      num = 0;
203    else
204      {
205         unsigned int i = 0;
206         unsigned char *v;
207
208         if (reply->value_len < len)
209           len = reply->value_len;
210
211         v = xcb_get_property_value(reply);
212         for (i = 0; i < len; i++)
213           xids[i] = ((uint32_t *)v)[i];
214
215         num = len;
216      }
217
218    if (reply) free(reply);
219    return num;
220 }
221
222 EAPI void
223 ecore_x_window_prop_string_set(Ecore_X_Window win,
224                                Ecore_X_Atom   type,
225                                const char    *str)
226 {
227    LOGFN(__FILE__, __LINE__, __FUNCTION__);
228    CHECK_XCB_CONN;
229
230    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win, type,
231                        ECORE_X_ATOM_UTF8_STRING, 8, strlen(str), str);
232 //   ecore_x_flush();
233 }
234
235 EAPI char *
236 ecore_x_window_prop_string_get(Ecore_X_Window win,
237                                Ecore_X_Atom   type)
238 {
239    xcb_get_property_cookie_t cookie;
240    xcb_get_property_reply_t *reply;
241    char *str = NULL;
242    int len = 0;
243
244    LOGFN(__FILE__, __LINE__, __FUNCTION__);
245    CHECK_XCB_CONN;
246
247    cookie =
248      xcb_get_property_unchecked(_ecore_xcb_conn, 0,
249                                 win ? win : ((xcb_screen_t *)_ecore_xcb_screen)->root,
250                                 type, XCB_GET_PROPERTY_TYPE_ANY, 0, 1000000L);
251    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
252    if (!reply) return NULL;
253
254    len = ((reply->value_len * reply->format) / 8);
255    str = (char *)malloc((len + 1) * sizeof(char));
256    memcpy(str, xcb_get_property_value(reply), len);
257    str[len] = '\0';
258
259    if (reply->type != ECORE_X_ATOM_UTF8_STRING)
260      {
261         Ecore_Xcb_Textproperty prop;
262         int count = 0;
263         char **list = NULL;
264         Eina_Bool ret = EINA_FALSE;
265
266         prop.value = strdup(str);
267         prop.nitems = len;
268         prop.encoding = reply->type;
269
270 #ifdef HAVE_ICONV
271         ret = _ecore_xcb_utf8_textproperty_to_textlist(&prop, &list, &count);
272 #else
273         ret = _ecore_xcb_mb_textproperty_to_textlist(&prop, &list, &count);
274 #endif
275         if (ret)
276           {
277              if (count > 0)
278                str = strdup(list[0]);
279              else
280                str = strdup((char *)prop.value);
281
282              if (list) free(list);
283           }
284         else
285           str = strdup((char *)prop.value);
286      }
287
288    free(reply);
289    return str;
290 }
291
292 EAPI int
293 ecore_x_window_prop_window_get(Ecore_X_Window  win,
294                                Ecore_X_Atom    atom,
295                                Ecore_X_Window *list,
296                                unsigned int    len)
297 {
298    LOGFN(__FILE__, __LINE__, __FUNCTION__);
299
300    return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_WINDOW, list, len);
301 }
302
303 EAPI void
304 ecore_x_window_prop_window_set(Ecore_X_Window  win,
305                                Ecore_X_Atom    atom,
306                                Ecore_X_Window *list,
307                                unsigned int    num)
308 {
309    LOGFN(__FILE__, __LINE__, __FUNCTION__);
310
311    ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_WINDOW, list, num);
312 }
313
314 EAPI int
315 ecore_x_window_prop_window_list_get(Ecore_X_Window   win,
316                                     Ecore_X_Atom     atom,
317                                     Ecore_X_Window **plst)
318 {
319    LOGFN(__FILE__, __LINE__, __FUNCTION__);
320
321    return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_WINDOW, plst);
322 }
323
324 EAPI Ecore_X_Atom
325 ecore_x_window_prop_any_type(void)
326 {
327    return XCB_ATOM_ANY;
328 }
329
330 EAPI void
331 ecore_x_window_prop_property_del(Ecore_X_Window win,
332                                  Ecore_X_Atom   property)
333 {
334    LOGFN(__FILE__, __LINE__, __FUNCTION__);
335    CHECK_XCB_CONN;
336
337    xcb_delete_property(_ecore_xcb_conn, win, property);
338 }
339
340 EAPI void
341 ecore_x_window_prop_property_set(Ecore_X_Window win,
342                                  Ecore_X_Atom   property,
343                                  Ecore_X_Atom   type,
344                                  int            size,
345                                  void          *data,
346                                  int            num)
347 {
348    LOGFN(__FILE__, __LINE__, __FUNCTION__);
349    CHECK_XCB_CONN;
350
351    if (win == 0)
352      win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
353
354    if (size != 32)
355      {
356         xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
357                             property, type, size, num, (unsigned char *)data);
358 //        ecore_x_flush();
359      }
360    else
361      {
362         uint32_t *dat;
363         int i = 0, *ptr;
364
365         dat = malloc(sizeof(uint32_t) * num);
366         if (dat)
367           {
368              for (ptr = (int *)data, i = 0; i < num; i++)
369                dat[i] = ptr[i];
370              xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
371                                  property, type, size, num,
372                                  (unsigned char *)dat);
373              free(dat);
374 //             ecore_x_flush();
375           }
376      }
377 }
378
379 EAPI int
380 ecore_x_window_prop_property_get(Ecore_X_Window  win,
381                                  Ecore_X_Atom    property,
382                                  Ecore_X_Atom    type,
383                                  int             size,
384                                  unsigned char **data,
385                                  int            *num)
386 {
387    xcb_get_property_cookie_t cookie;
388    xcb_get_property_reply_t *reply;
389    int format = 0;
390    unsigned int i = 0;
391    void *value;
392
393    LOGFN(__FILE__, __LINE__, __FUNCTION__);
394    CHECK_XCB_CONN;
395
396    if (num) *num = 0;
397
398    if (data)
399      *data = NULL;
400    else
401      return 0;
402
403    if (win == 0)
404      win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
405
406    cookie =
407      xcb_get_property_unchecked(_ecore_xcb_conn, 0, win,
408                                 property, type, 0, UINT_MAX);
409    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
410    if (!reply) return 0;
411    if ((reply->format != size) || (reply->value_len == 0))
412      {
413         free(reply);
414         return 0;
415      }
416
417    if (!(*data = malloc(reply->value_len * reply->format / 8)))
418      {
419         free(reply);
420         return 0;
421      }
422
423    value = xcb_get_property_value(reply);
424    switch (reply->format)
425      {
426       case 8:
427         for (i = 0; i < reply->value_len; i++)
428           (*data)[i] = ((unsigned char *)value)[i];
429         break;
430
431       case 16:
432         for (i = 0; i < reply->value_len; i++)
433           ((unsigned short *)*data)[i] = ((unsigned short *)value)[i];
434         break;
435
436       case 32:
437         for (i = 0; i < reply->value_len; i++)
438           ((unsigned int *)*data)[i] = ((uint32_t *)value)[i];
439         break;
440      }
441
442    if (num) *num = reply->value_len;
443    format = reply->format;
444    free(reply);
445    return format;
446 }
447
448 EAPI int
449 ecore_x_window_prop_atom_list_get(Ecore_X_Window win,
450                                   Ecore_X_Atom   atom,
451                                   Ecore_X_Atom **list)
452 {
453    LOGFN(__FILE__, __LINE__, __FUNCTION__);
454
455    return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_ATOM, list);
456 }
457
458 EAPI void
459 ecore_x_window_prop_atom_list_change(Ecore_X_Window win,
460                                      Ecore_X_Atom   atom,
461                                      Ecore_X_Atom   item,
462                                      int            op)
463 {
464    LOGFN(__FILE__, __LINE__, __FUNCTION__);
465    ecore_x_window_prop_xid_list_change(win, atom, ECORE_X_ATOM_ATOM, item, op);
466 }
467
468 EAPI int
469 ecore_x_window_prop_xid_list_get(Ecore_X_Window win,
470                                  Ecore_X_Atom   atom,
471                                  Ecore_X_Atom   type,
472                                  Ecore_X_ID   **xids)
473 {
474    xcb_get_property_cookie_t cookie;
475    xcb_get_property_reply_t *reply;
476    int num = -1;
477
478    LOGFN(__FILE__, __LINE__, __FUNCTION__);
479    CHECK_XCB_CONN;
480
481    if (xids) *xids = NULL;
482
483    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win, atom, type,
484                                        0, 0x7fffffff);
485    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
486    if (!reply) return -1;
487
488    if ((reply->type != type) || (reply->format != 32))
489      num = -1;
490    else if ((reply->value_len == 0) || (!xcb_get_property_value(reply)))
491      num = 0;
492    else
493      {
494         Ecore_X_Atom *alst;
495         void *val;
496
497         num = xcb_get_property_value_length(reply);
498         val = xcb_get_property_value(reply);
499         alst = malloc(num * sizeof(Ecore_X_ID));
500         if (alst)
501           {
502              int i = 0;
503
504              for (i = 0; i < num; i++)
505                alst[i] = ((uint32_t *)val)[i];
506              *xids = alst;
507           }
508      }
509
510    free(reply);
511    return num;
512 }
513
514 EAPI void
515 ecore_x_window_prop_xid_list_change(Ecore_X_Window win,
516                                     Ecore_X_Atom   atom,
517                                     Ecore_X_Atom   type,
518                                     Ecore_X_ID     item,
519                                     int            op)
520 {
521    Ecore_X_ID *lst;
522    int i = 0, num = 0;
523
524    LOGFN(__FILE__, __LINE__, __FUNCTION__);
525    CHECK_XCB_CONN;
526
527    num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst);
528    if (num < 0) return;
529
530    for (i = 0; i < num; i++)
531      {
532         if (lst[i] == item) break;
533      }
534
535    if (i < num)
536      {
537         if (op == ECORE_X_PROP_LIST_ADD)
538           goto done;
539         num--;
540         for (; i < num; i++)
541           lst[i] = lst[i + 1];
542      }
543    else
544      {
545         if (op == ECORE_X_PROP_LIST_REMOVE)
546           goto done;
547         num++;
548         lst = realloc(lst, num * sizeof(Ecore_X_ID));
549         lst[i] = item;
550      }
551    ecore_x_window_prop_xid_set(win, atom, type, lst, num);
552
553 done:
554    if (lst) free(lst);
555 }
556
557 EAPI Eina_Bool
558 ecore_x_window_prop_protocol_isset(Ecore_X_Window      win,
559                                    Ecore_X_WM_Protocol protocol)
560 {
561    Eina_Bool ret = EINA_FALSE;
562    Ecore_X_Atom proto;
563 #ifdef OLD_XCB_VERSION
564    xcb_get_wm_protocols_reply_t protos;
565 #else
566    xcb_icccm_get_wm_protocols_reply_t protos;
567 #endif
568    xcb_get_property_cookie_t cookie;
569    uint8_t reply;
570    uint32_t count = 0, i = 0;
571
572    LOGFN(__FILE__, __LINE__, __FUNCTION__);
573    CHECK_XCB_CONN;
574
575    if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE;
576
577    proto = _ecore_xcb_atoms_wm_protocol[protocol];
578 #ifdef OLD_XCB_VERSION
579    cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win,
580                                            ECORE_X_ATOM_WM_PROTOCOLS);
581    reply = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL);
582 #else
583    cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win,
584                                                  ECORE_X_ATOM_WM_PROTOCOLS);
585    reply = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie,
586                                             &protos, NULL);
587 #endif
588    if (!reply) return EINA_FALSE;
589
590    count = protos.atoms_len;
591    for (i = 0; i < count; i++)
592      {
593         if (protos.atoms[i] == proto)
594           {
595              ret = EINA_TRUE;
596              break;
597           }
598      }
599
600 #ifdef OLD_XCB_VERSION
601    xcb_get_wm_protocols_reply_wipe(&protos);
602 #else
603    xcb_icccm_get_wm_protocols_reply_wipe(&protos);
604 #endif
605    return ret;
606 }
607
608 EAPI Ecore_X_WM_Protocol *
609 ecore_x_window_prop_protocol_list_get(Ecore_X_Window win,
610                                       int           *num_ret)
611 {
612 #ifdef OLD_XCB_VERSION
613    xcb_get_wm_protocols_reply_t protos;
614 #else
615    xcb_icccm_get_wm_protocols_reply_t protos;
616 #endif
617    xcb_get_property_cookie_t cookie;
618    uint8_t reply;
619    uint32_t count = 0, i = 0;
620    Ecore_X_WM_Protocol *prot_ret = NULL;
621
622    LOGFN(__FILE__, __LINE__, __FUNCTION__);
623    CHECK_XCB_CONN;
624
625    if (!num_ret) return NULL;
626
627    *num_ret = 0;
628
629 #ifdef OLD_XCB_VERSION
630    cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win,
631                                            ECORE_X_ATOM_WM_PROTOCOLS);
632    reply = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL);
633 #else
634    cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win,
635                                                  ECORE_X_ATOM_WM_PROTOCOLS);
636    reply = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie,
637                                             &protos, NULL);
638 #endif
639    if (!reply) return NULL;
640
641    count = protos.atoms_len;
642    if (count <= 0)
643      {
644 #ifdef OLD_XCB_VERSION
645         xcb_get_wm_protocols_reply_wipe(&protos);
646 #else
647         xcb_icccm_get_wm_protocols_reply_wipe(&protos);
648 #endif
649         return NULL;
650      }
651
652    prot_ret = calloc(1, count * sizeof(Ecore_X_WM_Protocol));
653    if (!prot_ret)
654      {
655 #ifdef OLD_XCB_VERSION
656         xcb_get_wm_protocols_reply_wipe(&protos);
657 #else
658         xcb_icccm_get_wm_protocols_reply_wipe(&protos);
659 #endif
660         return NULL;
661      }
662
663    for (i = 0; i < count; i++)
664      {
665         Ecore_X_WM_Protocol j;
666
667         prot_ret[i] = -1;
668         for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++)
669           {
670              if (_ecore_xcb_atoms_wm_protocol[j] == protos.atoms[i])
671                prot_ret[i] = j;
672           }
673      }
674
675    if (num_ret) *num_ret = count;
676
677 #ifdef OLD_XCB_VERSION
678    xcb_get_wm_protocols_reply_wipe(&protos);
679 #else
680    xcb_icccm_get_wm_protocols_reply_wipe(&protos);
681 #endif
682    return prot_ret;
683 }
684
685 EAPI Ecore_X_Atom *
686 ecore_x_window_prop_list(Ecore_X_Window win,
687                          int           *num)
688 {
689    xcb_list_properties_cookie_t cookie;
690    xcb_list_properties_reply_t *reply;
691    xcb_atom_t *atm;
692    Ecore_X_Atom *atoms;
693    int i = 0;
694
695    LOGFN(__FILE__, __LINE__, __FUNCTION__);
696    CHECK_XCB_CONN;
697
698    if (num) *num = 0;
699
700    cookie = xcb_list_properties_unchecked(_ecore_xcb_conn, win);
701    reply = xcb_list_properties_reply(_ecore_xcb_conn, cookie, NULL);
702    if (!reply) return NULL;
703
704    atoms = (Ecore_X_Atom *)malloc(reply->atoms_len * sizeof(Ecore_X_Atom));
705    if (!atoms)
706      {
707         free(reply);
708         return NULL;
709      }
710
711    atm = xcb_list_properties_atoms(reply);
712    for (i = 0; i < reply->atoms_len; i++)
713      atoms[i] = atm[i];
714
715    if (num) *num = reply->atoms_len;
716    free(reply);
717
718    return atoms;
719 }
720