Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore_x / xcb / ecore_xcb_icccm.c
1 #include "ecore_xcb_private.h"
2 #include <xcb/xcb_icccm.h>
3
4 EAPI void
5 ecore_x_icccm_init(void)
6 {
7 }
8
9 /**
10  * Sets the WM_COMMAND property for @a win.
11  *
12  * @param win  The window.
13  * @param argc Number of arguments.
14  * @param argv Arguments.
15  */
16 EAPI void
17 ecore_x_icccm_command_set(Ecore_X_Window win,
18                           int            argc,
19                           char         **argv)
20 {
21    void *buf;
22    char *b;
23    int nbytes, i;
24
25    LOGFN(__FILE__, __LINE__, __FUNCTION__);
26    CHECK_XCB_CONN;
27
28    for (i = 0, nbytes = 0; i < argc; i++) 
29      if (argv[i]) nbytes += strlen(argv[i]) + 1;
30
31    buf = malloc(sizeof(char) * nbytes);
32    if (!buf) return;
33
34    b = (char *)buf;
35    for (i = 0; i < argc; i++)
36      {
37         if (argv[i])
38           {
39              strcpy(b, argv[i]);
40              b += strlen(argv[i]) + 1;
41           }
42         else
43           *b++ = '\0';
44      }
45    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
46                        ECORE_X_ATOM_WM_COMMAND, ECORE_X_ATOM_STRING, 8,
47                        nbytes, buf);
48    free(buf);
49 }
50
51 /**
52  * Get the WM_COMMAND property for @a win.
53  *
54  * Return the command of a window. String must be free'd when done with.
55  *
56  * @param win  The window.
57  * @param argc Number of arguments.
58  * @param argv Arguments.
59  */
60 EAPI void
61 ecore_x_icccm_command_get(Ecore_X_Window win,
62                           int           *argc,
63                           char        ***argv)
64 {
65    xcb_get_property_cookie_t cookie;
66    xcb_get_property_reply_t *reply;
67    int len = 0;
68    char **v, *data, *cp, *start;
69    int c = 0, i = 0, j = 0;
70
71    LOGFN(__FILE__, __LINE__, __FUNCTION__);
72    CHECK_XCB_CONN;
73
74    if (argc) *argc = 0;
75    if (argv) *argv = NULL;
76
77    cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win,
78                                        ECORE_X_ATOM_WM_COMMAND,
79                                        XCB_GET_PROPERTY_TYPE_ANY,
80                                        0, 1000000L);
81    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
82    if (!reply) return;
83
84    if ((reply->type != ECORE_X_ATOM_STRING) || (reply->format != 8))
85      {
86         free(reply);
87         return;
88      }
89
90    len = reply->value_len;
91    if (len < 1)
92      {
93         free(reply);
94         return;
95      }
96
97    data = (char *)xcb_get_property_value(reply);
98    if (len && (data[len - 1] == '\0'))
99      len--;
100
101    c = 1;
102    for (cp = (char *)data, i = len; i > 0; cp++, i--)
103      if (*cp == '\0') c++;
104
105    v = (char **)malloc((c + 1) * sizeof(char *));
106    if (!v)
107      {
108         free(reply);
109         return;
110      }
111
112    start = (char *)malloc((len + 1) * sizeof(char));
113    if (!start)
114      {
115         free(reply);
116         free(v);
117         return;
118      }
119
120    memcpy(start, (char *)data, len);
121    start[len] = '\0';
122    for (cp = start, i = len + 1, j = 0; i > 0; cp++, i--)
123      {
124         if (*cp == '\0')
125           {
126              v[j] = start;
127              start = (cp + 1);
128              j++;
129           }
130      }
131
132    if (c < 1)
133      {
134         free(reply);
135         free(v);
136         return;
137      }
138
139    if (argc) *argc = c;
140
141    if (argv)
142      {
143         (*argv) = malloc(c * sizeof(char *));
144         if (!*argv)
145           {
146              free(reply);
147              free(v);
148              if (argc) *argc = 0;
149              return;
150           }
151
152         for (i = 0; i < c; i++)
153           {
154              if (v[i])
155                (*argv)[i] = strdup(v[i]);
156              else
157                (*argv)[i] = strdup("");
158           }
159      }
160
161    free(reply);
162    free(v);
163 }
164
165 EAPI char *
166 ecore_x_icccm_title_get(Ecore_X_Window win)
167 {
168    xcb_get_property_cookie_t cookie;
169 #ifdef OLD_XCB_VERSION
170    xcb_get_text_property_reply_t prop;
171 #else
172    xcb_icccm_get_text_property_reply_t prop;
173 #endif
174    uint8_t ret = 0;
175    char *title = NULL;
176
177    LOGFN(__FILE__, __LINE__, __FUNCTION__);
178    CHECK_XCB_CONN;
179
180    if (!win) return NULL;
181 #ifdef OLD_XCB_VERSION
182    cookie = xcb_get_wm_name_unchecked(_ecore_xcb_conn, win);
183    ret = xcb_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL);
184 #else
185    cookie = xcb_icccm_get_wm_name_unchecked(_ecore_xcb_conn, win);
186    ret = xcb_icccm_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL);
187 #endif
188    if (ret == 0) return NULL;
189    if (prop.name_len < 1)
190      {
191 #ifdef OLD_XCB_VERSION
192         xcb_get_text_property_reply_wipe(&prop);
193 #else
194         xcb_icccm_get_text_property_reply_wipe(&prop);
195 #endif
196         return NULL;
197      }
198
199    if (!(title = malloc((prop.name_len + 1) * sizeof(char *))))
200      {
201 #ifdef OLD_XCB_VERSION
202         xcb_get_text_property_reply_wipe(&prop);
203 #else
204         xcb_icccm_get_text_property_reply_wipe(&prop);
205 #endif
206         return NULL;
207      }
208    memcpy(title, prop.name, sizeof(char *) * prop.name_len);
209    title[prop.name_len] = '\0';
210
211    if (prop.encoding != ECORE_X_ATOM_UTF8_STRING)
212      {
213         Ecore_Xcb_Textproperty tp;
214         int count = 0;
215         char **list = NULL;
216         Eina_Bool ret = EINA_FALSE;
217
218         tp.value = strdup(title);
219         tp.nitems = prop.name_len;
220         tp.encoding = prop.encoding;
221 #ifdef HAVE_ICONV
222         ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count);
223 #else
224         ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count);
225 #endif
226         if (ret)
227           {
228              if (count > 0)
229                title = strdup(list[0]);
230
231              if (list) free(list);
232           }
233      }
234
235 #ifdef OLD_XCB_VERSION
236    xcb_get_text_property_reply_wipe(&prop);
237 #else
238    xcb_icccm_get_text_property_reply_wipe(&prop);
239 #endif
240    return title;
241 }
242
243 EAPI void
244 ecore_x_icccm_title_set(Ecore_X_Window win,
245                         const char    *title)
246 {
247    Ecore_Xcb_Textproperty prop;
248    char *list[1];
249    Eina_Bool ret = EINA_FALSE;
250
251    LOGFN(__FILE__, __LINE__, __FUNCTION__);
252    CHECK_XCB_CONN;
253
254    if (!title) return;
255
256    prop.value = NULL;
257    list[0] = strdup(title);
258
259 #ifdef HAVE_ICONV
260    ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle,
261                                                   &prop);
262 #else
263    ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle,
264                                                 &prop);
265 #endif
266
267    if (ret)
268      {
269 #ifdef OLD_XCB_VERSION
270         xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
271                         strlen(prop.value), prop.value);
272 #else
273         xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8,
274                               strlen(prop.value), prop.value);
275 #endif
276         if (prop.value) free(prop.value);
277      }
278    else
279 #ifdef OLD_XCB_VERSION
280      xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
281                      strlen(title), title);
282 #else
283      xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8,
284                            strlen(title), title);
285 #endif
286    free(list[0]);
287 }
288
289 /**
290  * Get a window name & class.
291  * @param win The window
292  * @param n The name string
293  * @param c The class string
294  *
295  * Get a window name * class
296  */
297 EAPI void
298 ecore_x_icccm_name_class_get(Ecore_X_Window win,
299                              char         **name,
300                              char         **class)
301 {
302    xcb_get_property_cookie_t cookie;
303 #ifdef OLD_XCB_VERSION
304    xcb_get_wm_class_reply_t prop;
305 #else
306    xcb_icccm_get_wm_class_reply_t prop;
307 #endif
308    uint8_t ret = 0;
309
310    LOGFN(__FILE__, __LINE__, __FUNCTION__);
311    CHECK_XCB_CONN;
312
313    if (name) *name = NULL;
314    if (class) *class = NULL;
315
316 #ifdef OLD_XCB_VERSION
317    cookie = xcb_get_wm_class_unchecked(_ecore_xcb_conn, win);
318    ret = xcb_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL);
319 #else
320    cookie = xcb_icccm_get_wm_class_unchecked(_ecore_xcb_conn, win);
321    ret = xcb_icccm_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL);
322 #endif
323    if (ret == 0) return;
324
325    if (name) *name = strdup(prop.instance_name);
326    if (class) *class = strdup(prop.class_name);
327
328 #ifdef OLD_XCB_VERSION
329    xcb_get_wm_class_reply_wipe(&prop);
330 #else
331    xcb_icccm_get_wm_class_reply_wipe(&prop);
332 #endif
333 }
334
335 /**
336  * Set a window name & class.
337  * @param win The window
338  * @param n The name string
339  * @param c The class string
340  *
341  * Set a window name * class
342  */
343 EAPI void
344 ecore_x_icccm_name_class_set(Ecore_X_Window win,
345                              const char    *name,
346                              const char    *class)
347 {
348    char *class_string, *s;
349    int length_name, length_class;
350
351    LOGFN(__FILE__, __LINE__, __FUNCTION__);
352    CHECK_XCB_CONN;
353
354    length_name = strlen(name);
355    length_class = strlen(class);
356    class_string =
357      (char *)malloc(sizeof(char) * (length_name + length_class + 2));
358    if (!class_string) return;
359
360    s = class_string;
361    if (length_name)
362      {
363         strcpy(s, name);
364         s += length_name + 1;
365      }
366    else
367      *s++ = '\0';
368
369    if (length_class)
370      strcpy(s, class);
371    else
372      *s = '\0';
373
374    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
375                        ECORE_X_ATOM_WM_CLASS, ECORE_X_ATOM_STRING, 8,
376                        length_name + length_class + 2, (void *)class_string);
377    free(class_string);
378 }
379
380 /**
381  * Specify that a window is transient for another top-level window and should be handled accordingly.
382  * @param win the transient window
383  * @param forwin the toplevel window
384  */
385 EAPI void
386 ecore_x_icccm_transient_for_set(Ecore_X_Window win,
387                                 Ecore_X_Window forwindow)
388 {
389    LOGFN(__FILE__, __LINE__, __FUNCTION__);
390    CHECK_XCB_CONN;
391
392    xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
393                        ECORE_X_ATOM_WM_TRANSIENT_FOR, ECORE_X_ATOM_WINDOW, 32,
394                        1, (void *)&forwindow);
395 }
396
397 /**
398  * Remove the transient_for setting from a window.
399  * @param win The window
400  */
401 EAPI void
402 ecore_x_icccm_transient_for_unset(Ecore_X_Window win)
403 {
404    LOGFN(__FILE__, __LINE__, __FUNCTION__);
405
406    ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_TRANSIENT_FOR);
407 }
408
409 /**
410  * Get the window this window is transient for, if any.
411  * @param win The window to check
412  * @return The window ID of the top-level window, or 0 if the property does not exist.
413  */
414 EAPI Ecore_X_Window
415 ecore_x_icccm_transient_for_get(Ecore_X_Window win)
416 {
417    Ecore_X_Window forwin = 0;
418    xcb_get_property_cookie_t cookie;
419
420    LOGFN(__FILE__, __LINE__, __FUNCTION__);
421    CHECK_XCB_CONN;
422
423 #ifdef OLD_XCB_VERSION
424    cookie = xcb_get_wm_transient_for_unchecked(_ecore_xcb_conn, win);
425    xcb_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL);
426 #else
427    cookie = xcb_icccm_get_wm_transient_for_unchecked(_ecore_xcb_conn, win);
428    xcb_icccm_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL);
429 #endif
430
431    return forwin;
432 }
433
434 /**
435  * Get the window role.
436  * @param win The window
437  * @return The window's role string.
438  */
439 EAPI char *
440 ecore_x_icccm_window_role_get(Ecore_X_Window win)
441 {
442    LOGFN(__FILE__, __LINE__, __FUNCTION__);
443
444    return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE);
445 }
446
447 /**
448  * Set the window role hint.
449  * @param win The window
450  * @param role The role string
451  */
452 EAPI void
453 ecore_x_icccm_window_role_set(Ecore_X_Window win,
454                               const char    *role)
455 {
456    LOGFN(__FILE__, __LINE__, __FUNCTION__);
457
458    ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE, role);
459 }
460
461 /**
462  * Get the window's client leader.
463  * @param win The window
464  * @return The window's client leader window, or 0 if unset
465  */
466 EAPI Ecore_X_Window
467 ecore_x_icccm_client_leader_get(Ecore_X_Window win)
468 {
469    Ecore_X_Window leader;
470
471    LOGFN(__FILE__, __LINE__, __FUNCTION__);
472
473    if (ecore_x_window_prop_window_get(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
474                                       &leader, 1) > 0)
475      return leader;
476
477    return 0;
478 }
479
480 /**
481  * Set the window's client leader.
482  * @param win The window
483  * @param l The client leader window
484  *
485  * All non-transient top-level windows created by an app other than
486  * the main window must have this property set to the app's main window.
487  */
488 EAPI void
489 ecore_x_icccm_client_leader_set(Ecore_X_Window win,
490                                 Ecore_X_Window leader)
491 {
492    LOGFN(__FILE__, __LINE__, __FUNCTION__);
493
494    ecore_x_window_prop_window_set(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
495                                   &leader, 1);
496 }
497
498 EAPI Ecore_X_Window_State_Hint
499 ecore_x_icccm_state_get(Ecore_X_Window win)
500 {
501    xcb_get_property_cookie_t cookie;
502    xcb_get_property_reply_t *reply;
503    Ecore_X_Window_State_Hint hint = ECORE_X_WINDOW_STATE_HINT_NONE;
504    uint8_t *prop;
505
506    LOGFN(__FILE__, __LINE__, __FUNCTION__);
507    CHECK_XCB_CONN;
508
509    cookie =
510      xcb_get_property_unchecked(_ecore_xcb_conn, 0, win,
511                                 ECORE_X_ATOM_WM_STATE, ECORE_X_ATOM_WM_STATE,
512                                 0L, 0x7fffffff);
513    reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
514    if (!reply) return hint;
515    if ((reply->type == 0) || (reply->format != 8) || (reply->value_len != 2))
516      {
517         free(reply);
518         return hint;
519      }
520
521    prop = (uint8_t *)xcb_get_property_value(reply);
522 #ifdef OLD_XCB_VERSION
523    switch (prop[0])
524      {
525       case XCB_WM_STATE_WITHDRAWN:
526         hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
527         break;
528
529       case XCB_WM_STATE_NORMAL:
530         hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
531         break;
532
533       case XCB_WM_STATE_ICONIC:
534         hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
535         break;
536
537       default:
538         break;
539      }
540 #else
541    switch (prop[0])
542      {
543       case XCB_ICCCM_WM_STATE_WITHDRAWN:
544         hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
545         break;
546
547       case XCB_ICCCM_WM_STATE_NORMAL:
548         hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
549         break;
550
551       case XCB_ICCCM_WM_STATE_ICONIC:
552         hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
553         break;
554
555       default:
556         break;
557      }
558 #endif
559
560    free(reply);
561    return hint;
562 }
563
564 EAPI void
565 ecore_x_icccm_state_set(Ecore_X_Window            win,
566                         Ecore_X_Window_State_Hint state)
567 {
568 #ifdef OLD_XCB_VERSION
569    xcb_wm_hints_t hints;
570 #else
571    xcb_icccm_wm_hints_t hints;
572 #endif
573
574    LOGFN(__FILE__, __LINE__, __FUNCTION__);
575    CHECK_XCB_CONN;
576
577 #ifdef OLD_XCB_VERSION
578    xcb_wm_hints_set_none(&hints);
579
580    hints.flags = XCB_WM_HINT_STATE;
581
582    if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
583      xcb_wm_hints_set_withdrawn(&hints);
584    else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
585      xcb_wm_hints_set_normal(&hints);
586    else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
587      xcb_wm_hints_set_iconic(&hints);
588
589    xcb_set_wm_hints(_ecore_xcb_conn, win, &hints);
590 #else
591    xcb_icccm_wm_hints_set_none(&hints);
592
593    hints.flags = XCB_ICCCM_WM_HINT_STATE;
594
595    if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
596      xcb_icccm_wm_hints_set_withdrawn(&hints);
597    else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
598      xcb_icccm_wm_hints_set_normal(&hints);
599    else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
600      xcb_icccm_wm_hints_set_iconic(&hints);
601
602    xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints);
603 #endif
604 }
605
606 EAPI void
607 ecore_x_icccm_delete_window_send(Ecore_X_Window win,
608                                  Ecore_X_Time   t)
609 {
610    LOGFN(__FILE__, __LINE__, __FUNCTION__);
611    ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
612                                  ECORE_X_EVENT_MASK_NONE,
613                                  ECORE_X_ATOM_WM_DELETE_WINDOW, t, 0, 0, 0);
614 }
615
616 EAPI void
617 ecore_x_icccm_hints_set(Ecore_X_Window            win,
618                         Eina_Bool                 accepts_focus,
619                         Ecore_X_Window_State_Hint initial_state,
620                         Ecore_X_Pixmap            icon_pixmap,
621                         Ecore_X_Pixmap            icon_mask,
622                         Ecore_X_Window            icon_window,
623                         Ecore_X_Window            window_group,
624                         Eina_Bool                 is_urgent)
625 {
626 #ifdef OLD_XCB_VERSION
627    xcb_wm_hints_t hints;
628 #else
629    xcb_icccm_wm_hints_t hints;
630 #endif
631
632    LOGFN(__FILE__, __LINE__, __FUNCTION__);
633    CHECK_XCB_CONN;
634
635 #ifdef OLD_XCB_VERSION
636    xcb_wm_hints_set_none(&hints);
637    xcb_wm_hints_set_input(&hints, accepts_focus);
638
639    if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
640      xcb_wm_hints_set_withdrawn(&hints);
641    else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
642      xcb_wm_hints_set_normal(&hints);
643    else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
644      xcb_wm_hints_set_iconic(&hints);
645
646    if (icon_pixmap != 0) xcb_wm_hints_set_icon_pixmap(&hints, icon_pixmap);
647    if (icon_mask != 0) xcb_wm_hints_set_icon_mask(&hints, icon_mask);
648    if (icon_window != 0) xcb_wm_hints_set_icon_window(&hints, icon_window);
649    if (window_group != 0) xcb_wm_hints_set_window_group(&hints, window_group);
650    if (is_urgent) xcb_wm_hints_set_urgency(&hints);
651
652    xcb_set_wm_hints(_ecore_xcb_conn, win, &hints);
653 #else
654    xcb_icccm_wm_hints_set_none(&hints);
655    xcb_icccm_wm_hints_set_input(&hints, accepts_focus);
656
657    if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
658      xcb_icccm_wm_hints_set_withdrawn(&hints);
659    else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
660      xcb_icccm_wm_hints_set_normal(&hints);
661    else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
662      xcb_icccm_wm_hints_set_iconic(&hints);
663
664    if (icon_pixmap != 0)
665      xcb_icccm_wm_hints_set_icon_pixmap(&hints, icon_pixmap);
666    if (icon_mask != 0)
667      xcb_icccm_wm_hints_set_icon_mask(&hints, icon_mask);
668    if (icon_window != 0)
669      xcb_icccm_wm_hints_set_icon_window(&hints, icon_window);
670    if (window_group != 0)
671      xcb_icccm_wm_hints_set_window_group(&hints, window_group);
672    if (is_urgent)
673      xcb_icccm_wm_hints_set_urgency(&hints);
674
675    xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints);
676 #endif
677 }
678
679 EAPI Eina_Bool
680 ecore_x_icccm_hints_get(Ecore_X_Window             win,
681                         Eina_Bool                 *accepts_focus,
682                         Ecore_X_Window_State_Hint *initial_state,
683                         Ecore_X_Pixmap            *icon_pixmap,
684                         Ecore_X_Pixmap            *icon_mask,
685                         Ecore_X_Window            *icon_window,
686                         Ecore_X_Window            *window_group,
687                         Eina_Bool                 *is_urgent)
688 {
689    xcb_get_property_cookie_t cookie;
690 #ifdef OLD_XCB_VERSION
691    xcb_wm_hints_t hints;
692 #else
693    xcb_icccm_wm_hints_t hints;
694 #endif
695    uint8_t ret = 0;
696
697    LOGFN(__FILE__, __LINE__, __FUNCTION__);
698    CHECK_XCB_CONN;
699
700    if (accepts_focus) *accepts_focus = EINA_TRUE;
701    if (initial_state) *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
702    if (icon_pixmap) *icon_pixmap = 0;
703    if (icon_mask) *icon_mask = 0;
704    if (icon_window) *icon_window = 0;
705    if (window_group) *window_group = 0;
706    if (is_urgent) *is_urgent = EINA_FALSE;
707
708 #ifdef OLD_XCB_VERSION
709    xcb_wm_hints_set_none(&hints);
710    cookie = xcb_get_wm_hints_unchecked(_ecore_xcb_conn, win);
711    ret = xcb_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL);
712 #else
713    xcb_icccm_wm_hints_set_none(&hints);
714    cookie = xcb_icccm_get_wm_hints_unchecked(_ecore_xcb_conn, win);
715    ret = xcb_icccm_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL);
716 #endif
717    if (!ret) return EINA_FALSE;
718
719 #ifdef OLD_XCB_VERSION
720    if ((hints.flags & XCB_WM_HINT_INPUT) && (accepts_focus))
721 #else
722    if ((hints.flags & XCB_ICCCM_WM_HINT_INPUT) && (accepts_focus))
723 #endif
724      {
725         if (hints.input)
726           *accepts_focus = EINA_TRUE;
727         else
728           *accepts_focus = EINA_FALSE;
729      }
730
731 #ifdef OLD_XCB_VERSION
732    if ((hints.flags & XCB_WM_HINT_STATE) && (initial_state))
733      {
734         if (hints.initial_state == XCB_WM_STATE_WITHDRAWN)
735           *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
736         else if (hints.initial_state == XCB_WM_STATE_NORMAL)
737           *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
738         else if (hints.initial_state == XCB_WM_STATE_ICONIC)
739           *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
740      }
741
742    if ((hints.flags & XCB_WM_HINT_ICON_PIXMAP) && (icon_pixmap))
743      *icon_pixmap = hints.icon_pixmap;
744
745    if ((hints.flags & XCB_WM_HINT_ICON_MASK) && (icon_mask))
746      *icon_mask = hints.icon_mask;
747
748    if ((hints.flags & XCB_WM_HINT_ICON_WINDOW) && (icon_window))
749      *icon_window = hints.icon_window;
750
751    if ((hints.flags & XCB_WM_HINT_WINDOW_GROUP) && (window_group))
752      *window_group = hints.window_group;
753
754    if ((hints.flags & XCB_WM_HINT_X_URGENCY) && (is_urgent))
755      *is_urgent = EINA_TRUE;
756 #else
757    if ((hints.flags & XCB_ICCCM_WM_HINT_STATE) && (initial_state))
758      {
759         if (hints.initial_state == XCB_ICCCM_WM_STATE_WITHDRAWN)
760           *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
761         else if (hints.initial_state == XCB_ICCCM_WM_STATE_NORMAL)
762           *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
763         else if (hints.initial_state == XCB_ICCCM_WM_STATE_ICONIC)
764           *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
765      }
766
767    if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_PIXMAP) && (icon_pixmap))
768      *icon_pixmap = hints.icon_pixmap;
769
770    if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_MASK) && (icon_mask))
771      *icon_mask = hints.icon_mask;
772
773    if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_WINDOW) && (icon_window))
774      *icon_window = hints.icon_window;
775
776    if ((hints.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP) && (window_group))
777      *window_group = hints.window_group;
778
779    if ((hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY) && (is_urgent))
780      *is_urgent = EINA_TRUE;
781 #endif
782
783    return EINA_TRUE;
784 }
785
786 /**
787  * Get a window icon name.
788  * @param win The window
789  * @return The windows icon name string
790  *
791  * Return the icon name of a window. String must be free'd when done with.
792  */
793 EAPI char *
794 ecore_x_icccm_icon_name_get(Ecore_X_Window win)
795 {
796    xcb_get_property_cookie_t cookie;
797 #ifdef OLD_XCB_VERSION
798    xcb_get_text_property_reply_t prop;
799 #else
800    xcb_icccm_get_text_property_reply_t prop;
801 #endif
802    uint8_t ret = 0;
803    char *tmp = NULL;
804
805    LOGFN(__FILE__, __LINE__, __FUNCTION__);
806    CHECK_XCB_CONN;
807
808    if (!win) return NULL;
809
810 #ifdef OLD_XCB_VERSION
811    cookie = xcb_get_wm_icon_name_unchecked(_ecore_xcb_conn, win);
812    ret = xcb_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL);
813 #else
814    cookie = xcb_icccm_get_wm_icon_name_unchecked(_ecore_xcb_conn, win);
815    ret = xcb_icccm_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL);
816 #endif
817    if (ret == 0) return NULL;
818
819    if (prop.name_len < 1)
820      {
821 #ifdef OLD_XCB_VERSION
822         xcb_get_text_property_reply_wipe(&prop);
823 #else
824         xcb_icccm_get_text_property_reply_wipe(&prop);
825 #endif
826         return NULL;
827      }
828
829    if (!(tmp = malloc((prop.name_len + 1) * sizeof(char *))))
830      {
831 #ifdef OLD_XCB_VERSION
832         xcb_get_text_property_reply_wipe(&prop);
833 #else
834         xcb_icccm_get_text_property_reply_wipe(&prop);
835 #endif
836         return NULL;
837      }
838    memcpy(tmp, prop.name, sizeof(char *) * prop.name_len);
839    tmp[prop.name_len] = '\0';
840
841    if (prop.encoding != ECORE_X_ATOM_UTF8_STRING)
842      {
843         Ecore_Xcb_Textproperty tp;
844         int count = 0;
845         char **list = NULL;
846         Eina_Bool ret = EINA_FALSE;
847
848         tp.value = strdup(tmp);
849         tp.nitems = prop.name_len;
850         tp.encoding = prop.encoding;
851 #ifdef HAVE_ICONV
852         ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count);
853 #else
854         ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count);
855 #endif
856         if (ret)
857           {
858              if (count > 0)
859                tmp = strdup(list[0]);
860
861              if (list) free(list);
862           }
863      }
864
865 #ifdef OLD_XCB_VERSION
866    xcb_get_text_property_reply_wipe(&prop);
867 #else
868    xcb_icccm_get_text_property_reply_wipe(&prop);
869 #endif
870    return tmp;
871 }
872
873 /**
874  * Set a window icon name.
875  * @param win The window
876  * @param t The icon name string
877  *
878  * Set a window icon name
879  */
880 EAPI void
881 ecore_x_icccm_icon_name_set(Ecore_X_Window win,
882                             const char    *name)
883 {
884    Ecore_Xcb_Textproperty prop;
885    char *list[1];
886    Eina_Bool ret = EINA_FALSE;
887
888    LOGFN(__FILE__, __LINE__, __FUNCTION__);
889    CHECK_XCB_CONN;
890
891    if ((!win) || (!name)) return;
892
893    prop.value = NULL;
894    list[0] = strdup(name);
895
896 #ifdef HAVE_ICONV
897    ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle,
898                                                   &prop);
899 #else
900    ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle,
901                                                 &prop);
902 #endif
903
904    if (ret)
905      {
906 #ifdef OLD_XCB_VERSION
907         xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
908                              strlen(prop.value), prop.value);
909 #else
910         xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
911                                    8, strlen(prop.value), prop.value);
912 #endif
913         if (prop.value) free(prop.value);
914      }
915    else
916 #ifdef OLD_XCB_VERSION
917      xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
918                           strlen(name), name);
919 #else
920      xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
921                                 8, strlen(name), name);
922 #endif
923
924    free(list[0]);
925 }
926
927 EAPI void
928 ecore_x_icccm_iconic_request_send(Ecore_X_Window win,
929                                   Ecore_X_Window root)
930 {
931    xcb_client_message_event_t ev;
932
933    LOGFN(__FILE__, __LINE__, __FUNCTION__);
934    CHECK_XCB_CONN;
935
936    if (!win) return;
937    if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
938
939    memset(&ev, 0, sizeof(xcb_client_message_event_t));
940
941    ev.response_type = XCB_CLIENT_MESSAGE;
942    ev.format = 32;
943    ev.window = win;
944    ev.type = ECORE_X_ATOM_WM_CHANGE_STATE;
945 #ifdef OLD_XCB_VERSION
946    ev.data.data32[0] = XCB_WM_STATE_ICONIC;
947 #else
948    ev.data.data32[0] = XCB_ICCCM_WM_STATE_ICONIC;
949 #endif
950
951    xcb_send_event(_ecore_xcb_conn, 0, root,
952                   (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
953                    XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT),
954                   (const char *)&ev);
955 //   ecore_x_flush();
956 }
957
958 /**
959  * Set or unset a wm protocol property.
960  * @param win The Window
961  * @param protocol The protocol to enable/disable
962  * @param on On/Off
963  */
964 EAPI void
965 ecore_x_icccm_protocol_set(Ecore_X_Window      win,
966                            Ecore_X_WM_Protocol protocol,
967                            Eina_Bool           on)
968 {
969    Ecore_X_Atom proto;
970    xcb_get_property_cookie_t cookie;
971 #ifdef OLD_XCB_VERSION
972    xcb_get_wm_protocols_reply_t protos;
973 #else
974    xcb_icccm_get_wm_protocols_reply_t protos;
975 #endif
976    int i = 0, count = 0, set = 0;
977
978    LOGFN(__FILE__, __LINE__, __FUNCTION__);
979    CHECK_XCB_CONN;
980
981    if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return;
982    proto = _ecore_xcb_atoms_wm_protocol[protocol];
983 #ifdef OLD_XCB_VERSION
984    cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto);
985    if (!xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL))
986 #else
987    cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto);
988    if (!xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL))
989 #endif
990      count = 0;
991    else
992      count = protos.atoms_len;
993
994    for (i = 0; i < count; i++)
995      {
996         if (protos.atoms[i] == proto)
997           {
998              set = 1;
999              break;
1000           }
1001      }
1002
1003    if (on)
1004      {
1005         if (!set)
1006           {
1007              Ecore_X_Atom *atoms = NULL;
1008
1009              atoms = malloc((count + 1) * sizeof(Ecore_X_Atom));
1010              if (atoms)
1011                {
1012                   for (i = 0; i < count; i++)
1013                     atoms[i] = protos.atoms[i];
1014                   atoms[count] = proto;
1015 #ifdef OLD_XCB_VERSION
1016                   xcb_set_wm_protocols(_ecore_xcb_conn,
1017                                        ECORE_X_ATOM_WM_PROTOCOLS,
1018                                        win, count, atoms);
1019 #else
1020                   xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, 
1021                                              ECORE_X_ATOM_WM_PROTOCOLS,
1022                                              count, atoms);
1023 #endif
1024                   free(atoms);
1025                }
1026           }
1027      }
1028    else
1029      {
1030         if (set)
1031           {
1032              for (i = 0; i < count; i++)
1033                {
1034                   if (protos.atoms[i] == proto)
1035                     {
1036                        int j = 0;
1037
1038                        for (j = (i + 1); j < count; j++)
1039                          protos.atoms[j - 1] = protos.atoms[j];
1040                        if (count > 1)
1041 #ifdef OLD_XCB_VERSION
1042                          xcb_set_wm_protocols(_ecore_xcb_conn,
1043                                               ECORE_X_ATOM_WM_PROTOCOLS,
1044                                               win, count - 1, protos.atoms);
1045 #else
1046                          xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, 
1047                                                     ECORE_X_ATOM_WM_PROTOCOLS,
1048                                                     count - 1, protos.atoms);
1049 #endif
1050                        else
1051                          ecore_x_window_prop_property_del(win,
1052                                                           ECORE_X_ATOM_WM_PROTOCOLS);
1053                        break;
1054                     }
1055                }
1056           }
1057      }
1058
1059 #ifdef OLD_XCB_VERSION
1060    xcb_get_wm_protocols_reply_wipe(&protos);
1061 #else
1062    xcb_icccm_get_wm_protocols_reply_wipe(&protos);
1063 #endif
1064 }
1065
1066 /**
1067  * Determines whether a protocol is set for a window.
1068  * @param win The Window
1069  * @param protocol The protocol to query
1070  * @return 1 if the protocol is set, else 0.
1071  */
1072 EAPI Eina_Bool
1073 ecore_x_icccm_protocol_isset(Ecore_X_Window      win,
1074                              Ecore_X_WM_Protocol protocol)
1075 {
1076    Ecore_X_Atom proto;
1077    Eina_Bool ret = EINA_FALSE;
1078    xcb_get_property_cookie_t cookie;
1079 #ifdef OLD_XCB_VERSION
1080    xcb_get_wm_protocols_reply_t reply;
1081 #else
1082    xcb_icccm_get_wm_protocols_reply_t reply;
1083 #endif
1084    uint8_t val = 0;
1085    unsigned int i = 0;
1086
1087    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1088    CHECK_XCB_CONN;
1089
1090    if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE;
1091
1092    proto = _ecore_xcb_atoms_wm_protocol[protocol];
1093 #ifdef OLD_XCB_VERSION
1094    cookie = xcb_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto);
1095    val = xcb_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL);
1096 #else
1097    cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto);
1098    val = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL);
1099 #endif
1100    if (!val) return EINA_FALSE;
1101
1102    for (i = 0; i < reply.atoms_len; i++)
1103      if (reply.atoms[i] == proto)
1104        {
1105           ret = EINA_TRUE;
1106           break;
1107        }
1108
1109 #ifdef OLD_XCB_VERSION
1110    xcb_get_wm_protocols_reply_wipe(&reply);
1111 #else
1112    xcb_icccm_get_wm_protocols_reply_wipe(&reply);
1113 #endif
1114
1115    return ret;
1116 }
1117
1118 /**
1119  * Set protocol atoms explicitly
1120  * @param win The Window
1121  * @param protos An array of protocol atoms
1122  * @param num the number of members of the array
1123  */
1124 EAPI void
1125 ecore_x_icccm_protocol_atoms_set(Ecore_X_Window win,
1126                                  Ecore_X_Atom  *protos,
1127                                  int            num)
1128 {
1129    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1130    CHECK_XCB_CONN;
1131
1132    if (num > 0)
1133 #ifdef OLD_XCB_VERSION
1134      xcb_set_wm_protocols(_ecore_xcb_conn, ECORE_X_ATOM_WM_PROTOCOLS,
1135                           win, num, protos);
1136 #else
1137      xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win, 
1138                                 ECORE_X_ATOM_WM_PROTOCOLS, num, protos);
1139 #endif
1140    else
1141      ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_PROTOCOLS);
1142 }
1143
1144 EAPI Eina_Bool
1145 ecore_x_icccm_size_pos_hints_get(Ecore_X_Window   win,
1146                                  Eina_Bool       *request_pos,
1147                                  Ecore_X_Gravity *gravity,
1148                                  int             *min_w,
1149                                  int             *min_h,
1150                                  int             *max_w,
1151                                  int             *max_h,
1152                                  int             *base_w,
1153                                  int             *base_h,
1154                                  int             *step_x,
1155                                  int             *step_y,
1156                                  double          *min_aspect,
1157                                  double          *max_aspect)
1158 {
1159    xcb_size_hints_t hints;
1160    xcb_get_property_cookie_t cookie;
1161    uint8_t ret = 0;
1162    int32_t minw = 0, minh = 0;
1163    int32_t maxw = 32767, maxh = 32767;
1164    int32_t basew = -1, baseh = -1;
1165    int32_t stepx = -1, stepy = -1;
1166    double mina = 0.0, maxa = 0.0;
1167
1168    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1169    CHECK_XCB_CONN;
1170
1171    if (request_pos) *request_pos = EINA_FALSE;
1172    if (gravity) *gravity = ECORE_X_GRAVITY_NW;
1173    if (min_w) *min_w = minw;
1174    if (min_h) *min_h = minh;
1175    if (max_w) *max_w = maxw;
1176    if (max_h) *max_h = maxh;
1177    if (base_w) *base_w = basew;
1178    if (base_h) *base_h = baseh;
1179    if (step_x) *step_x = stepx;
1180    if (step_y) *step_y = stepy;
1181    if (min_aspect) *min_aspect = mina;
1182    if (max_aspect) *max_aspect = maxa;
1183
1184 #ifdef OLD_XCB_VERSION
1185    cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win);
1186    ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL);
1187 #else
1188    cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win);
1189    ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie,
1190                                              &hints, NULL);
1191 #endif
1192    if (!ret) return EINA_FALSE;
1193
1194 #ifdef OLD_XCB_VERSION
1195    if ((hints.flags & XCB_SIZE_HINT_US_POSITION) ||
1196        (hints.flags & XCB_SIZE_HINT_P_POSITION))
1197 #else
1198    if ((hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION) ||
1199        (hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION))
1200 #endif
1201      {
1202         if (request_pos) *request_pos = EINA_TRUE;
1203      }
1204
1205 #ifdef OLD_XCB_VERSION
1206    if (hints.flags & XCB_SIZE_HINT_P_WIN_GRAVITY)
1207 #else
1208    if (hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY)
1209 #endif
1210      {
1211         if (gravity) *gravity = hints.win_gravity;
1212      }
1213
1214 #ifdef OLD_XCB_VERSION
1215    if (hints.flags & XCB_SIZE_HINT_P_MIN_SIZE)
1216 #else
1217    if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE)
1218 #endif
1219      {
1220         minw = hints.min_width;
1221         minh = hints.min_height;
1222      }
1223
1224 #ifdef OLD_XCB_VERSION
1225    if (hints.flags & XCB_SIZE_HINT_P_MAX_SIZE)
1226 #else
1227    if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE)
1228 #endif
1229      {
1230         maxw = hints.max_width;
1231         maxh = hints.max_height;
1232         if (maxw < minw) maxw = minw;
1233         if (maxh < minh) maxh = minh;
1234      }
1235
1236 #ifdef OLD_XCB_VERSION
1237    if (hints.flags & XCB_SIZE_HINT_BASE_SIZE)
1238 #else
1239    if (hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE)
1240 #endif
1241      {
1242         basew = hints.base_width;
1243         baseh = hints.base_height;
1244         if (basew > minw) minw = basew;
1245         if (baseh > minh) minh = baseh;
1246      }
1247
1248 #ifdef OLD_XCB_VERSION
1249    if (hints.flags & XCB_SIZE_HINT_P_RESIZE_INC)
1250 #else
1251    if (hints.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC)
1252 #endif
1253      {
1254         stepx = hints.width_inc;
1255         stepy = hints.height_inc;
1256         if (stepx < 1) stepx = 1;
1257         if (stepy < 1) stepy = 1;
1258      }
1259
1260 #ifdef OLD_XCB_VERSION
1261    if (hints.flags & XCB_SIZE_HINT_P_ASPECT)
1262 #else
1263    if (hints.flags & XCB_ICCCM_SIZE_HINT_P_ASPECT)
1264 #endif
1265      {
1266         if (hints.min_aspect_den > 0)
1267           mina = ((double)hints.min_aspect_num) / ((double)hints.min_aspect_den);
1268
1269         if (hints.max_aspect_den > 0)
1270           maxa = ((double)hints.max_aspect_num) / ((double)hints.max_aspect_den);
1271      }
1272
1273    if (min_w) *min_w = minw;
1274    if (min_h) *min_h = minh;
1275    if (max_w) *max_w = maxw;
1276    if (max_h) *max_h = maxh;
1277    if (base_w) *base_w = basew;
1278    if (base_h) *base_h = baseh;
1279    if (step_x) *step_x = stepx;
1280    if (step_y) *step_y = stepy;
1281    if (min_aspect) *min_aspect = mina;
1282    if (max_aspect) *max_aspect = maxa;
1283
1284    return EINA_TRUE;
1285 }
1286
1287 EAPI void
1288 ecore_x_icccm_size_pos_hints_set(Ecore_X_Window  win,
1289                                  Eina_Bool       request_pos,
1290                                  Ecore_X_Gravity gravity,
1291                                  int             min_w,
1292                                  int             min_h,
1293                                  int             max_w,
1294                                  int             max_h,
1295                                  int             base_w,
1296                                  int             base_h,
1297                                  int             step_x,
1298                                  int             step_y,
1299                                  double          min_aspect,
1300                                  double          max_aspect)
1301 {
1302    xcb_get_property_cookie_t cookie;
1303    xcb_size_hints_t hints;
1304    uint8_t ret = 0;
1305
1306    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1307    CHECK_XCB_CONN;
1308
1309 #ifdef OLD_XCB_VERSION
1310    cookie = xcb_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win);
1311    ret = xcb_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL);
1312 #else
1313    cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win);
1314    ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie,
1315                                              &hints, NULL);
1316 #endif
1317    if (!ret) memset(&hints, 0, sizeof(xcb_size_hints_t));
1318
1319    hints.flags = 0;
1320
1321 #ifdef OLD_XCB_VERSION
1322    if (request_pos)
1323      hints.flags |= XCB_SIZE_HINT_US_POSITION;
1324
1325    if (gravity != ECORE_X_GRAVITY_NW)
1326      xcb_size_hints_set_win_gravity(&hints, gravity);
1327    if ((min_w > 0) || (min_h > 0))
1328      xcb_size_hints_set_min_size(&hints, min_w, min_h);
1329    if ((max_w > 0) || (max_h > 0))
1330      xcb_size_hints_set_max_size(&hints, max_w, max_h);
1331    if ((base_w > 0) || (base_h > 0))
1332      xcb_size_hints_set_base_size(&hints, base_w, base_h);
1333    if ((step_x > 1) || (step_y > 1))
1334      xcb_size_hints_set_resize_inc(&hints, step_x, step_y);
1335    if ((min_aspect > 0.0) || (max_aspect > 0.0))
1336      xcb_size_hints_set_aspect(&hints,
1337                                (int32_t)(min_aspect * 10000), 10000,
1338                                (int32_t)(max_aspect * 10000), 10000);
1339
1340    xcb_set_wm_normal_hints(_ecore_xcb_conn, win, &hints);
1341 #else
1342    if (request_pos)
1343      hints.flags |= XCB_ICCCM_SIZE_HINT_US_POSITION;
1344
1345    if (gravity != ECORE_X_GRAVITY_NW)
1346      xcb_icccm_size_hints_set_win_gravity(&hints, gravity);
1347    if ((min_w > 0) || (min_h > 0))
1348      xcb_icccm_size_hints_set_min_size(&hints, min_w, min_h);
1349    if ((max_w > 0) || (max_h > 0))
1350      xcb_icccm_size_hints_set_max_size(&hints, max_w, max_h);
1351    if ((base_w > 0) || (base_h > 0))
1352      xcb_icccm_size_hints_set_base_size(&hints, base_w, base_h);
1353    if ((step_x > 1) || (step_y > 1))
1354      xcb_icccm_size_hints_set_resize_inc(&hints, step_x, step_y);
1355    if ((min_aspect > 0.0) || (max_aspect > 0.0))
1356      xcb_icccm_size_hints_set_aspect(&hints,
1357                                      (int32_t)(min_aspect * 10000), 10000,
1358                                      (int32_t)(max_aspect * 10000), 10000);
1359
1360    xcb_icccm_set_wm_normal_hints(_ecore_xcb_conn, win, &hints);
1361 #endif
1362 }
1363
1364 EAPI void
1365 ecore_x_icccm_move_resize_send(Ecore_X_Window win,
1366                                int            x,
1367                                int            y,
1368                                int            w,
1369                                int            h)
1370 {
1371    xcb_configure_notify_event_t ev;
1372
1373    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1374    CHECK_XCB_CONN;
1375
1376    if (!win) return;
1377
1378    memset(&ev, 0, sizeof(xcb_configure_notify_event_t));
1379
1380    ev.response_type = XCB_CONFIGURE_NOTIFY;
1381    ev.event = win;
1382    ev.window = win;
1383    ev.above_sibling = XCB_NONE;
1384    ev.x = x;
1385    ev.y = y;
1386    ev.width = w;
1387    ev.height = h;
1388    ev.border_width = 0;
1389    ev.override_redirect = 0;
1390
1391    xcb_send_event(_ecore_xcb_conn, 0, win,
1392                   XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *)&ev);
1393 //   ecore_x_flush();
1394 }
1395
1396 /**
1397  * Get a window client machine string.
1398  * @param win The window
1399  * @return The windows client machine string
1400  *
1401  * Return the client machine of a window. String must be free'd when done with.
1402  */
1403 EAPI char *
1404 ecore_x_icccm_client_machine_get(Ecore_X_Window win)
1405 {
1406    xcb_get_property_cookie_t cookie;
1407 #ifdef OLD_XCB_VERSION
1408    xcb_get_text_property_reply_t prop;
1409 #else
1410    xcb_icccm_get_text_property_reply_t prop;
1411 #endif
1412    uint8_t ret = 0;
1413    char *tmp = NULL;
1414
1415    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1416    CHECK_XCB_CONN;
1417
1418 #ifdef OLD_XCB_VERSION
1419    cookie = xcb_get_wm_client_machine_unchecked(_ecore_xcb_conn, win);
1420    ret = xcb_get_wm_client_machine_reply(_ecore_xcb_conn, cookie, &prop, NULL);
1421 #else
1422    cookie = xcb_icccm_get_wm_client_machine_unchecked(_ecore_xcb_conn, win);
1423    ret = xcb_icccm_get_wm_client_machine_reply(_ecore_xcb_conn, cookie,
1424                                                &prop, NULL);
1425 #endif
1426    if (ret == 0) return NULL;
1427
1428    tmp = malloc((prop.name_len + 1) * sizeof(char *));
1429    if (!tmp)
1430      {
1431 #ifdef OLD_XCB_VERSION
1432         xcb_get_text_property_reply_wipe(&prop);
1433 #else
1434         xcb_icccm_get_text_property_reply_wipe(&prop);
1435 #endif
1436         return NULL;
1437      }
1438    memcpy(tmp, prop.name, sizeof(char *) * prop.name_len);
1439    tmp[prop.name_len] = '\0';
1440
1441 #ifdef OLD_XCB_VERSION
1442    xcb_get_text_property_reply_wipe(&prop);
1443 #else
1444    xcb_icccm_get_text_property_reply_wipe(&prop);
1445 #endif
1446
1447    return tmp;
1448 }
1449
1450 EAPI void
1451 ecore_x_icccm_take_focus_send(Ecore_X_Window win,
1452                               Ecore_X_Time   t)
1453 {
1454    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1455    CHECK_XCB_CONN;
1456
1457    ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
1458                                  XCB_EVENT_MASK_NO_EVENT,
1459                                  ECORE_X_ATOM_WM_TAKE_FOCUS, t, 0, 0, 0);
1460 }
1461
1462 EAPI void
1463 ecore_x_icccm_save_yourself_send(Ecore_X_Window win,
1464                                  Ecore_X_Time   t)
1465 {
1466    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1467    ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
1468                                  XCB_EVENT_MASK_NO_EVENT,
1469                                  ECORE_X_ATOM_WM_SAVE_YOURSELF, t, 0, 0, 0);
1470 }
1471
1472 /**
1473  * Add a subwindow to the list of windows that need a different colormap installed.
1474  * @param win The toplevel window
1475  * @param subwin The subwindow to be added to the colormap windows list
1476  */
1477 EAPI void
1478 ecore_x_icccm_colormap_window_set(Ecore_X_Window win,
1479                                   Ecore_X_Window subwin)
1480 {
1481    int num = 0, i = 0;
1482    unsigned char *odata = NULL, *data = NULL;
1483    Ecore_X_Window *newset = NULL, *oldset = NULL;
1484
1485    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1486
1487    if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1488                                          ECORE_X_ATOM_WINDOW, 32, &odata, &num))
1489      {
1490         if (!(newset = calloc(1, sizeof(Ecore_X_Window)))) return;
1491         newset[0] = subwin;
1492         num = 1;
1493         data = (unsigned char *)newset;
1494      }
1495    else
1496      {
1497         if (!(newset = calloc(num + 1, sizeof(Ecore_X_Window)))) return;
1498         oldset = (Ecore_X_Window *)odata;
1499         for (i = 0; i < num; i++)
1500           {
1501              if (oldset[i] == subwin)
1502                {
1503                   if (odata) free(odata);
1504                   odata = NULL;
1505                   free(newset);
1506                   return;
1507                }
1508              newset[i] = oldset[i];
1509           }
1510         newset[num++] = subwin;
1511         if (odata) free(odata);
1512         data = (unsigned char *)newset;
1513      }
1514    ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1515                                     ECORE_X_ATOM_WINDOW, 32, data, num);
1516    free(newset);
1517 }
1518
1519 /**
1520  * Remove a window from the list of colormap windows.
1521  * @param win The toplevel window
1522  * @param subwin The window to be removed from the colormap window list.
1523  */
1524 EAPI void
1525 ecore_x_icccm_colormap_window_unset(Ecore_X_Window win,
1526                                     Ecore_X_Window subwin)
1527 {
1528    int num = 0, i = 0, j = 0, k = 0;
1529    unsigned char *odata = NULL, *data = NULL;
1530    Ecore_X_Window *newset = NULL, *oldset = NULL;
1531
1532    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1533
1534    if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1535                                          ECORE_X_ATOM_WINDOW, 32, &odata, &num))
1536      return;
1537
1538    oldset = (Ecore_X_Window *)odata;
1539    for (i = 0; i < num; i++)
1540      {
1541         if (oldset[i] == subwin)
1542           {
1543              if (num == 1)
1544                {
1545                   ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS);
1546                   if (odata) free(odata);
1547                   odata = NULL;
1548                   return;
1549                }
1550              else
1551                {
1552                   newset = calloc(num - 1, sizeof(Ecore_X_Window));
1553                   data = (unsigned char *)newset;
1554                   for (j = 0; j < num; ++j)
1555                     if (oldset[j] != subwin)
1556                       newset[k++] = oldset[j];
1557
1558                   ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1559                                                    ECORE_X_ATOM_WINDOW, 32, data, k);
1560                   if (odata) free(odata);
1561                   odata = NULL;
1562                   free(newset);
1563                   return;
1564                }
1565           }
1566      }
1567    if (odata) free(odata);
1568 }
1569