1 #include "ecore_xcb_private.h"
2 #include <xcb/xcb_icccm.h>
5 ecore_x_icccm_init(void)
10 * Sets the WM_COMMAND property for @a win.
12 * @param win The window.
13 * @param argc Number of arguments.
14 * @param argv Arguments.
17 ecore_x_icccm_command_set(Ecore_X_Window win,
25 LOGFN(__FILE__, __LINE__, __FUNCTION__);
28 for (i = 0, nbytes = 0; i < argc; i++)
29 if (argv[i]) nbytes += strlen(argv[i]) + 1;
31 buf = malloc(sizeof(char) * nbytes);
35 for (i = 0; i < argc; i++)
40 b += strlen(argv[i]) + 1;
45 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
46 ECORE_X_ATOM_WM_COMMAND, ECORE_X_ATOM_STRING, 8,
52 * Get the WM_COMMAND property for @a win.
54 * Return the command of a window. String must be free'd when done with.
56 * @param win The window.
57 * @param argc Number of arguments.
58 * @param argv Arguments.
61 ecore_x_icccm_command_get(Ecore_X_Window win,
65 xcb_get_property_cookie_t cookie;
66 xcb_get_property_reply_t *reply;
68 char **v, *data, *cp, *start;
69 int c = 0, i = 0, j = 0;
71 LOGFN(__FILE__, __LINE__, __FUNCTION__);
75 if (argv) *argv = NULL;
77 cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, win,
78 ECORE_X_ATOM_WM_COMMAND,
79 XCB_GET_PROPERTY_TYPE_ANY,
81 reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
84 if ((reply->type != ECORE_X_ATOM_STRING) || (reply->format != 8))
90 len = reply->value_len;
97 data = (char *)xcb_get_property_value(reply);
98 if (len && (data[len - 1] == '\0'))
102 for (cp = (char *)data, i = len; i > 0; cp++, i--)
103 if (*cp == '\0') c++;
105 v = (char **)malloc((c + 1) * sizeof(char *));
112 start = (char *)malloc((len + 1) * sizeof(char));
120 memcpy(start, (char *)data, len);
122 for (cp = start, i = len + 1, j = 0; i > 0; cp++, i--)
143 (*argv) = malloc(c * sizeof(char *));
152 for (i = 0; i < c; i++)
155 (*argv)[i] = strdup(v[i]);
157 (*argv)[i] = strdup("");
166 ecore_x_icccm_title_get(Ecore_X_Window win)
168 xcb_get_property_cookie_t cookie;
169 #ifdef OLD_XCB_VERSION
170 xcb_get_text_property_reply_t prop;
172 xcb_icccm_get_text_property_reply_t prop;
177 LOGFN(__FILE__, __LINE__, __FUNCTION__);
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);
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);
188 if (ret == 0) return NULL;
189 if (prop.name_len < 1)
191 #ifdef OLD_XCB_VERSION
192 xcb_get_text_property_reply_wipe(&prop);
194 xcb_icccm_get_text_property_reply_wipe(&prop);
199 if (!(title = malloc((prop.name_len + 1) * sizeof(char *))))
201 #ifdef OLD_XCB_VERSION
202 xcb_get_text_property_reply_wipe(&prop);
204 xcb_icccm_get_text_property_reply_wipe(&prop);
208 memcpy(title, prop.name, sizeof(char *) * prop.name_len);
209 title[prop.name_len] = '\0';
211 if (prop.encoding != ECORE_X_ATOM_UTF8_STRING)
213 Ecore_Xcb_Textproperty tp;
216 Eina_Bool ret = EINA_FALSE;
218 tp.value = strdup(title);
219 tp.nitems = prop.name_len;
220 tp.encoding = prop.encoding;
222 ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count);
224 ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count);
229 title = strdup(list[0]);
231 if (list) free(list);
235 #ifdef OLD_XCB_VERSION
236 xcb_get_text_property_reply_wipe(&prop);
238 xcb_icccm_get_text_property_reply_wipe(&prop);
244 ecore_x_icccm_title_set(Ecore_X_Window win,
247 Ecore_Xcb_Textproperty prop;
249 Eina_Bool ret = EINA_FALSE;
251 LOGFN(__FILE__, __LINE__, __FUNCTION__);
257 list[0] = strdup(title);
260 ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle,
263 ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle,
269 #ifdef OLD_XCB_VERSION
270 xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
271 strlen(prop.value), prop.value);
273 xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8,
274 strlen(prop.value), prop.value);
276 if (prop.value) free(prop.value);
279 #ifdef OLD_XCB_VERSION
280 xcb_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
281 strlen(title), title);
283 xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8,
284 strlen(title), title);
290 * Get a window name & class.
291 * @param win The window
292 * @param n The name string
293 * @param c The class string
295 * Get a window name * class
298 ecore_x_icccm_name_class_get(Ecore_X_Window win,
302 xcb_get_property_cookie_t cookie;
303 #ifdef OLD_XCB_VERSION
304 xcb_get_wm_class_reply_t prop;
306 xcb_icccm_get_wm_class_reply_t prop;
310 LOGFN(__FILE__, __LINE__, __FUNCTION__);
313 if (name) *name = NULL;
314 if (class) *class = NULL;
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);
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);
323 if (ret == 0) return;
325 if (name) *name = strdup(prop.instance_name);
326 if (class) *class = strdup(prop.class_name);
328 #ifdef OLD_XCB_VERSION
329 xcb_get_wm_class_reply_wipe(&prop);
331 xcb_icccm_get_wm_class_reply_wipe(&prop);
336 * Set a window name & class.
337 * @param win The window
338 * @param n The name string
339 * @param c The class string
341 * Set a window name * class
344 ecore_x_icccm_name_class_set(Ecore_X_Window win,
348 char *class_string, *s;
349 int length_name, length_class;
351 LOGFN(__FILE__, __LINE__, __FUNCTION__);
354 length_name = strlen(name);
355 length_class = strlen(class);
357 (char *)malloc(sizeof(char) * (length_name + length_class + 2));
358 if (!class_string) return;
364 s += length_name + 1;
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);
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
386 ecore_x_icccm_transient_for_set(Ecore_X_Window win,
387 Ecore_X_Window forwindow)
389 LOGFN(__FILE__, __LINE__, __FUNCTION__);
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);
398 * Remove the transient_for setting from a window.
399 * @param win The window
402 ecore_x_icccm_transient_for_unset(Ecore_X_Window win)
404 LOGFN(__FILE__, __LINE__, __FUNCTION__);
406 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_TRANSIENT_FOR);
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.
415 ecore_x_icccm_transient_for_get(Ecore_X_Window win)
417 Ecore_X_Window forwin = 0;
418 xcb_get_property_cookie_t cookie;
420 LOGFN(__FILE__, __LINE__, __FUNCTION__);
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);
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);
435 * Get the window role.
436 * @param win The window
437 * @return The window's role string.
440 ecore_x_icccm_window_role_get(Ecore_X_Window win)
442 LOGFN(__FILE__, __LINE__, __FUNCTION__);
444 return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE);
448 * Set the window role hint.
449 * @param win The window
450 * @param role The role string
453 ecore_x_icccm_window_role_set(Ecore_X_Window win,
456 LOGFN(__FILE__, __LINE__, __FUNCTION__);
458 ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE, role);
462 * Get the window's client leader.
463 * @param win The window
464 * @return The window's client leader window, or 0 if unset
467 ecore_x_icccm_client_leader_get(Ecore_X_Window win)
469 Ecore_X_Window leader;
471 LOGFN(__FILE__, __LINE__, __FUNCTION__);
473 if (ecore_x_window_prop_window_get(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
481 * Set the window's client leader.
482 * @param win The window
483 * @param l The client leader window
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.
489 ecore_x_icccm_client_leader_set(Ecore_X_Window win,
490 Ecore_X_Window leader)
492 LOGFN(__FILE__, __LINE__, __FUNCTION__);
494 ecore_x_window_prop_window_set(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
498 EAPI Ecore_X_Window_State_Hint
499 ecore_x_icccm_state_get(Ecore_X_Window win)
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;
506 LOGFN(__FILE__, __LINE__, __FUNCTION__);
510 xcb_get_property_unchecked(_ecore_xcb_conn, 0, win,
511 ECORE_X_ATOM_WM_STATE, ECORE_X_ATOM_WM_STATE,
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))
521 prop = (uint8_t *)xcb_get_property_value(reply);
522 #ifdef OLD_XCB_VERSION
525 case XCB_WM_STATE_WITHDRAWN:
526 hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
529 case XCB_WM_STATE_NORMAL:
530 hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
533 case XCB_WM_STATE_ICONIC:
534 hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
543 case XCB_ICCCM_WM_STATE_WITHDRAWN:
544 hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
547 case XCB_ICCCM_WM_STATE_NORMAL:
548 hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
551 case XCB_ICCCM_WM_STATE_ICONIC:
552 hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
565 ecore_x_icccm_state_set(Ecore_X_Window win,
566 Ecore_X_Window_State_Hint state)
568 #ifdef OLD_XCB_VERSION
569 xcb_wm_hints_t hints;
571 xcb_icccm_wm_hints_t hints;
574 LOGFN(__FILE__, __LINE__, __FUNCTION__);
577 #ifdef OLD_XCB_VERSION
578 xcb_wm_hints_set_none(&hints);
580 hints.flags = XCB_WM_HINT_STATE;
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);
589 xcb_set_wm_hints(_ecore_xcb_conn, win, &hints);
591 xcb_icccm_wm_hints_set_none(&hints);
593 hints.flags = XCB_ICCCM_WM_HINT_STATE;
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);
602 xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints);
607 ecore_x_icccm_delete_window_send(Ecore_X_Window win,
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);
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,
626 #ifdef OLD_XCB_VERSION
627 xcb_wm_hints_t hints;
629 xcb_icccm_wm_hints_t hints;
632 LOGFN(__FILE__, __LINE__, __FUNCTION__);
635 #ifdef OLD_XCB_VERSION
636 xcb_wm_hints_set_none(&hints);
637 xcb_wm_hints_set_input(&hints, accepts_focus);
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);
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);
652 xcb_set_wm_hints(_ecore_xcb_conn, win, &hints);
654 xcb_icccm_wm_hints_set_none(&hints);
655 xcb_icccm_wm_hints_set_input(&hints, accepts_focus);
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);
664 if (icon_pixmap != 0)
665 xcb_icccm_wm_hints_set_icon_pixmap(&hints, icon_pixmap);
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);
673 xcb_icccm_wm_hints_set_urgency(&hints);
675 xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints);
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)
689 xcb_get_property_cookie_t cookie;
690 #ifdef OLD_XCB_VERSION
691 xcb_wm_hints_t hints;
693 xcb_icccm_wm_hints_t hints;
697 LOGFN(__FILE__, __LINE__, __FUNCTION__);
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;
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);
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);
717 if (!ret) return EINA_FALSE;
719 #ifdef OLD_XCB_VERSION
720 if ((hints.flags & XCB_WM_HINT_INPUT) && (accepts_focus))
722 if ((hints.flags & XCB_ICCCM_WM_HINT_INPUT) && (accepts_focus))
726 *accepts_focus = EINA_TRUE;
728 *accepts_focus = EINA_FALSE;
731 #ifdef OLD_XCB_VERSION
732 if ((hints.flags & XCB_WM_HINT_STATE) && (initial_state))
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;
742 if ((hints.flags & XCB_WM_HINT_ICON_PIXMAP) && (icon_pixmap))
743 *icon_pixmap = hints.icon_pixmap;
745 if ((hints.flags & XCB_WM_HINT_ICON_MASK) && (icon_mask))
746 *icon_mask = hints.icon_mask;
748 if ((hints.flags & XCB_WM_HINT_ICON_WINDOW) && (icon_window))
749 *icon_window = hints.icon_window;
751 if ((hints.flags & XCB_WM_HINT_WINDOW_GROUP) && (window_group))
752 *window_group = hints.window_group;
754 if ((hints.flags & XCB_WM_HINT_X_URGENCY) && (is_urgent))
755 *is_urgent = EINA_TRUE;
757 if ((hints.flags & XCB_ICCCM_WM_HINT_STATE) && (initial_state))
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;
767 if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_PIXMAP) && (icon_pixmap))
768 *icon_pixmap = hints.icon_pixmap;
770 if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_MASK) && (icon_mask))
771 *icon_mask = hints.icon_mask;
773 if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_WINDOW) && (icon_window))
774 *icon_window = hints.icon_window;
776 if ((hints.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP) && (window_group))
777 *window_group = hints.window_group;
779 if ((hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY) && (is_urgent))
780 *is_urgent = EINA_TRUE;
787 * Get a window icon name.
788 * @param win The window
789 * @return The windows icon name string
791 * Return the icon name of a window. String must be free'd when done with.
794 ecore_x_icccm_icon_name_get(Ecore_X_Window win)
796 xcb_get_property_cookie_t cookie;
797 #ifdef OLD_XCB_VERSION
798 xcb_get_text_property_reply_t prop;
800 xcb_icccm_get_text_property_reply_t prop;
805 LOGFN(__FILE__, __LINE__, __FUNCTION__);
808 if (!win) return NULL;
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);
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);
817 if (ret == 0) return NULL;
819 if (prop.name_len < 1)
821 #ifdef OLD_XCB_VERSION
822 xcb_get_text_property_reply_wipe(&prop);
824 xcb_icccm_get_text_property_reply_wipe(&prop);
829 if (!(tmp = malloc((prop.name_len + 1) * sizeof(char *))))
831 #ifdef OLD_XCB_VERSION
832 xcb_get_text_property_reply_wipe(&prop);
834 xcb_icccm_get_text_property_reply_wipe(&prop);
838 memcpy(tmp, prop.name, sizeof(char *) * prop.name_len);
839 tmp[prop.name_len] = '\0';
841 if (prop.encoding != ECORE_X_ATOM_UTF8_STRING)
843 Ecore_Xcb_Textproperty tp;
846 Eina_Bool ret = EINA_FALSE;
848 tp.value = strdup(tmp);
849 tp.nitems = prop.name_len;
850 tp.encoding = prop.encoding;
852 ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count);
854 ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count);
859 tmp = strdup(list[0]);
861 if (list) free(list);
865 #ifdef OLD_XCB_VERSION
866 xcb_get_text_property_reply_wipe(&prop);
868 xcb_icccm_get_text_property_reply_wipe(&prop);
874 * Set a window icon name.
875 * @param win The window
876 * @param t The icon name string
878 * Set a window icon name
881 ecore_x_icccm_icon_name_set(Ecore_X_Window win,
884 Ecore_Xcb_Textproperty prop;
886 Eina_Bool ret = EINA_FALSE;
888 LOGFN(__FILE__, __LINE__, __FUNCTION__);
891 if ((!win) || (!name)) return;
894 list[0] = strdup(name);
897 ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle,
900 ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle,
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);
910 xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
911 8, strlen(prop.value), prop.value);
913 if (prop.value) free(prop.value);
916 #ifdef OLD_XCB_VERSION
917 xcb_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
920 xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
921 8, strlen(name), name);
928 ecore_x_icccm_iconic_request_send(Ecore_X_Window win,
931 xcb_client_message_event_t ev;
933 LOGFN(__FILE__, __LINE__, __FUNCTION__);
937 if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
939 memset(&ev, 0, sizeof(xcb_client_message_event_t));
941 ev.response_type = XCB_CLIENT_MESSAGE;
944 ev.type = ECORE_X_ATOM_WM_CHANGE_STATE;
945 #ifdef OLD_XCB_VERSION
946 ev.data.data32[0] = XCB_WM_STATE_ICONIC;
948 ev.data.data32[0] = XCB_ICCCM_WM_STATE_ICONIC;
951 xcb_send_event(_ecore_xcb_conn, 0, root,
952 (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
953 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT),
959 * Set or unset a wm protocol property.
960 * @param win The Window
961 * @param protocol The protocol to enable/disable
965 ecore_x_icccm_protocol_set(Ecore_X_Window win,
966 Ecore_X_WM_Protocol protocol,
970 xcb_get_property_cookie_t cookie;
971 #ifdef OLD_XCB_VERSION
972 xcb_get_wm_protocols_reply_t protos;
974 xcb_icccm_get_wm_protocols_reply_t protos;
976 int i = 0, count = 0, set = 0;
978 LOGFN(__FILE__, __LINE__, __FUNCTION__);
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))
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))
992 count = protos.atoms_len;
994 for (i = 0; i < count; i++)
996 if (protos.atoms[i] == proto)
1007 Ecore_X_Atom *atoms = NULL;
1009 atoms = malloc((count + 1) * sizeof(Ecore_X_Atom));
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,
1020 xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win,
1021 ECORE_X_ATOM_WM_PROTOCOLS,
1032 for (i = 0; i < count; i++)
1034 if (protos.atoms[i] == proto)
1038 for (j = (i + 1); j < count; j++)
1039 protos.atoms[j - 1] = protos.atoms[j];
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);
1046 xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win,
1047 ECORE_X_ATOM_WM_PROTOCOLS,
1048 count - 1, protos.atoms);
1051 ecore_x_window_prop_property_del(win,
1052 ECORE_X_ATOM_WM_PROTOCOLS);
1059 #ifdef OLD_XCB_VERSION
1060 xcb_get_wm_protocols_reply_wipe(&protos);
1062 xcb_icccm_get_wm_protocols_reply_wipe(&protos);
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.
1073 ecore_x_icccm_protocol_isset(Ecore_X_Window win,
1074 Ecore_X_WM_Protocol protocol)
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;
1082 xcb_icccm_get_wm_protocols_reply_t reply;
1087 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1090 if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE;
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);
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);
1100 if (!val) return EINA_FALSE;
1102 for (i = 0; i < reply.atoms_len; i++)
1103 if (reply.atoms[i] == proto)
1109 #ifdef OLD_XCB_VERSION
1110 xcb_get_wm_protocols_reply_wipe(&reply);
1112 xcb_icccm_get_wm_protocols_reply_wipe(&reply);
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
1125 ecore_x_icccm_protocol_atoms_set(Ecore_X_Window win,
1126 Ecore_X_Atom *protos,
1129 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1133 #ifdef OLD_XCB_VERSION
1134 xcb_set_wm_protocols(_ecore_xcb_conn, ECORE_X_ATOM_WM_PROTOCOLS,
1137 xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win,
1138 ECORE_X_ATOM_WM_PROTOCOLS, num, protos);
1141 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_PROTOCOLS);
1145 ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win,
1146 Eina_Bool *request_pos,
1147 Ecore_X_Gravity *gravity,
1159 xcb_size_hints_t hints;
1160 xcb_get_property_cookie_t cookie;
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;
1168 LOGFN(__FILE__, __LINE__, __FUNCTION__);
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;
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);
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,
1192 if (!ret) return EINA_FALSE;
1194 #ifdef OLD_XCB_VERSION
1195 if ((hints.flags & XCB_SIZE_HINT_US_POSITION) ||
1196 (hints.flags & XCB_SIZE_HINT_P_POSITION))
1198 if ((hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION) ||
1199 (hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION))
1202 if (request_pos) *request_pos = EINA_TRUE;
1205 #ifdef OLD_XCB_VERSION
1206 if (hints.flags & XCB_SIZE_HINT_P_WIN_GRAVITY)
1208 if (hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY)
1211 if (gravity) *gravity = hints.win_gravity;
1214 #ifdef OLD_XCB_VERSION
1215 if (hints.flags & XCB_SIZE_HINT_P_MIN_SIZE)
1217 if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE)
1220 minw = hints.min_width;
1221 minh = hints.min_height;
1224 #ifdef OLD_XCB_VERSION
1225 if (hints.flags & XCB_SIZE_HINT_P_MAX_SIZE)
1227 if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE)
1230 maxw = hints.max_width;
1231 maxh = hints.max_height;
1232 if (maxw < minw) maxw = minw;
1233 if (maxh < minh) maxh = minh;
1236 #ifdef OLD_XCB_VERSION
1237 if (hints.flags & XCB_SIZE_HINT_BASE_SIZE)
1239 if (hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE)
1242 basew = hints.base_width;
1243 baseh = hints.base_height;
1244 if (basew > minw) minw = basew;
1245 if (baseh > minh) minh = baseh;
1248 #ifdef OLD_XCB_VERSION
1249 if (hints.flags & XCB_SIZE_HINT_P_RESIZE_INC)
1251 if (hints.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC)
1254 stepx = hints.width_inc;
1255 stepy = hints.height_inc;
1256 if (stepx < 1) stepx = 1;
1257 if (stepy < 1) stepy = 1;
1260 #ifdef OLD_XCB_VERSION
1261 if (hints.flags & XCB_SIZE_HINT_P_ASPECT)
1263 if (hints.flags & XCB_ICCCM_SIZE_HINT_P_ASPECT)
1266 if (hints.min_aspect_den > 0)
1267 mina = ((double)hints.min_aspect_num) / ((double)hints.min_aspect_den);
1269 if (hints.max_aspect_den > 0)
1270 maxa = ((double)hints.max_aspect_num) / ((double)hints.max_aspect_den);
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;
1288 ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win,
1289 Eina_Bool request_pos,
1290 Ecore_X_Gravity gravity,
1302 xcb_get_property_cookie_t cookie;
1303 xcb_size_hints_t hints;
1306 LOGFN(__FILE__, __LINE__, __FUNCTION__);
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);
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,
1317 if (!ret) memset(&hints, 0, sizeof(xcb_size_hints_t));
1321 #ifdef OLD_XCB_VERSION
1323 hints.flags |= XCB_SIZE_HINT_US_POSITION;
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);
1340 xcb_set_wm_normal_hints(_ecore_xcb_conn, win, &hints);
1343 hints.flags |= XCB_ICCCM_SIZE_HINT_US_POSITION;
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);
1360 xcb_icccm_set_wm_normal_hints(_ecore_xcb_conn, win, &hints);
1365 ecore_x_icccm_move_resize_send(Ecore_X_Window win,
1371 xcb_configure_notify_event_t ev;
1373 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1378 memset(&ev, 0, sizeof(xcb_configure_notify_event_t));
1380 ev.response_type = XCB_CONFIGURE_NOTIFY;
1383 ev.above_sibling = XCB_NONE;
1388 ev.border_width = 0;
1389 ev.override_redirect = 0;
1391 xcb_send_event(_ecore_xcb_conn, 0, win,
1392 XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *)&ev);
1397 * Get a window client machine string.
1398 * @param win The window
1399 * @return The windows client machine string
1401 * Return the client machine of a window. String must be free'd when done with.
1404 ecore_x_icccm_client_machine_get(Ecore_X_Window win)
1406 xcb_get_property_cookie_t cookie;
1407 #ifdef OLD_XCB_VERSION
1408 xcb_get_text_property_reply_t prop;
1410 xcb_icccm_get_text_property_reply_t prop;
1415 LOGFN(__FILE__, __LINE__, __FUNCTION__);
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);
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,
1426 if (ret == 0) return NULL;
1428 tmp = malloc((prop.name_len + 1) * sizeof(char *));
1431 #ifdef OLD_XCB_VERSION
1432 xcb_get_text_property_reply_wipe(&prop);
1434 xcb_icccm_get_text_property_reply_wipe(&prop);
1438 memcpy(tmp, prop.name, sizeof(char *) * prop.name_len);
1439 tmp[prop.name_len] = '\0';
1441 #ifdef OLD_XCB_VERSION
1442 xcb_get_text_property_reply_wipe(&prop);
1444 xcb_icccm_get_text_property_reply_wipe(&prop);
1451 ecore_x_icccm_take_focus_send(Ecore_X_Window win,
1454 LOGFN(__FILE__, __LINE__, __FUNCTION__);
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);
1463 ecore_x_icccm_save_yourself_send(Ecore_X_Window win,
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);
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
1478 ecore_x_icccm_colormap_window_set(Ecore_X_Window win,
1479 Ecore_X_Window subwin)
1482 unsigned char *odata = NULL, *data = NULL;
1483 Ecore_X_Window *newset = NULL, *oldset = NULL;
1485 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1487 if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1488 ECORE_X_ATOM_WINDOW, 32, &odata, &num))
1490 if (!(newset = calloc(1, sizeof(Ecore_X_Window)))) return;
1493 data = (unsigned char *)newset;
1497 if (!(newset = calloc(num + 1, sizeof(Ecore_X_Window)))) return;
1498 oldset = (Ecore_X_Window *)odata;
1499 for (i = 0; i < num; i++)
1501 if (oldset[i] == subwin)
1503 if (odata) free(odata);
1508 newset[i] = oldset[i];
1510 newset[num++] = subwin;
1511 if (odata) free(odata);
1512 data = (unsigned char *)newset;
1514 ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1515 ECORE_X_ATOM_WINDOW, 32, data, num);
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.
1525 ecore_x_icccm_colormap_window_unset(Ecore_X_Window win,
1526 Ecore_X_Window subwin)
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;
1532 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1534 if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1535 ECORE_X_ATOM_WINDOW, 32, &odata, &num))
1538 oldset = (Ecore_X_Window *)odata;
1539 for (i = 0; i < num; i++)
1541 if (oldset[i] == subwin)
1545 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS);
1546 if (odata) free(odata);
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];
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);
1567 if (odata) free(odata);