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 xcb_icccm_get_text_property_reply_t prop;
173 LOGFN(__FILE__, __LINE__, __FUNCTION__);
176 if (!win) return NULL;
177 cookie = xcb_icccm_get_wm_name_unchecked(_ecore_xcb_conn, win);
178 ret = xcb_icccm_get_wm_name_reply(_ecore_xcb_conn, cookie, &prop, NULL);
179 if (ret == 0) return NULL;
180 if (prop.name_len < 1)
182 xcb_icccm_get_text_property_reply_wipe(&prop);
186 if (!(title = malloc((prop.name_len + 1) * sizeof(char *))))
188 xcb_icccm_get_text_property_reply_wipe(&prop);
191 memcpy(title, prop.name, sizeof(char *) * prop.name_len);
192 title[prop.name_len] = '\0';
194 if (prop.encoding != ECORE_X_ATOM_UTF8_STRING)
196 Ecore_Xcb_Textproperty tp;
199 Eina_Bool ret = EINA_FALSE;
201 tp.value = strdup(title);
202 tp.nitems = prop.name_len;
203 tp.encoding = prop.encoding;
205 ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count);
207 ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count);
212 title = strdup(list[0]);
214 if (list) free(list);
218 xcb_icccm_get_text_property_reply_wipe(&prop);
223 ecore_x_icccm_title_set(Ecore_X_Window win,
226 Ecore_Xcb_Textproperty prop;
228 Eina_Bool ret = EINA_FALSE;
230 LOGFN(__FILE__, __LINE__, __FUNCTION__);
236 list[0] = strdup(title);
239 ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle,
242 ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle,
248 xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8,
249 strlen(prop.value), prop.value);
250 if (prop.value) free(prop.value);
253 xcb_icccm_set_wm_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING, 8,
254 strlen(title), title);
259 * Get a window name & class.
260 * @param win The window
261 * @param n The name string
262 * @param c The class string
264 * Get a window name * class
267 ecore_x_icccm_name_class_get(Ecore_X_Window win,
271 xcb_get_property_cookie_t cookie;
272 xcb_icccm_get_wm_class_reply_t prop;
275 LOGFN(__FILE__, __LINE__, __FUNCTION__);
278 if (name) *name = NULL;
279 if (class) *class = NULL;
281 cookie = xcb_icccm_get_wm_class_unchecked(_ecore_xcb_conn, win);
282 ret = xcb_icccm_get_wm_class_reply(_ecore_xcb_conn, cookie, &prop, NULL);
283 if (ret == 0) return;
285 if (name) *name = strdup(prop.instance_name);
286 if (class) *class = strdup(prop.class_name);
288 xcb_icccm_get_wm_class_reply_wipe(&prop);
292 * Set a window name & class.
293 * @param win The window
294 * @param n The name string
295 * @param c The class string
297 * Set a window name * class
300 ecore_x_icccm_name_class_set(Ecore_X_Window win,
304 char *class_string, *s;
305 int length_name = 0, length_class = 0;
307 LOGFN(__FILE__, __LINE__, __FUNCTION__);
310 if (name) length_name = strlen(name);
311 if (class) length_class = strlen(class);
313 (char *)malloc(sizeof(char) * (length_name + length_class + 2));
314 if (!class_string) return;
320 s += length_name + 1;
330 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
331 ECORE_X_ATOM_WM_CLASS, ECORE_X_ATOM_STRING, 8,
332 length_name + length_class + 2, (void *)class_string);
337 * Specify that a window is transient for another top-level window and should be handled accordingly.
338 * @param win the transient window
339 * @param forwin the toplevel window
342 ecore_x_icccm_transient_for_set(Ecore_X_Window win,
343 Ecore_X_Window forwindow)
345 LOGFN(__FILE__, __LINE__, __FUNCTION__);
348 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
349 ECORE_X_ATOM_WM_TRANSIENT_FOR, ECORE_X_ATOM_WINDOW, 32,
350 1, (void *)&forwindow);
354 * Remove the transient_for setting from a window.
355 * @param win The window
358 ecore_x_icccm_transient_for_unset(Ecore_X_Window win)
360 LOGFN(__FILE__, __LINE__, __FUNCTION__);
362 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_TRANSIENT_FOR);
366 * Get the window this window is transient for, if any.
367 * @param win The window to check
368 * @return The window ID of the top-level window, or 0 if the property does not exist.
371 ecore_x_icccm_transient_for_get(Ecore_X_Window win)
373 Ecore_X_Window forwin = 0;
374 xcb_get_property_cookie_t cookie;
376 LOGFN(__FILE__, __LINE__, __FUNCTION__);
379 cookie = xcb_icccm_get_wm_transient_for_unchecked(_ecore_xcb_conn, win);
380 xcb_icccm_get_wm_transient_for_reply(_ecore_xcb_conn, cookie, &forwin, NULL);
386 * Get the window role.
387 * @param win The window
388 * @return The window's role string.
391 ecore_x_icccm_window_role_get(Ecore_X_Window win)
393 LOGFN(__FILE__, __LINE__, __FUNCTION__);
395 return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_WINDOW_ROLE);
399 * Set the window role hint.
400 * @param win The window
401 * @param role The role string
404 ecore_x_icccm_window_role_set(Ecore_X_Window win,
407 LOGFN(__FILE__, __LINE__, __FUNCTION__);
409 ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_WINDOW_ROLE, role);
413 * Get the window's client leader.
414 * @param win The window
415 * @return The window's client leader window, or 0 if unset
418 ecore_x_icccm_client_leader_get(Ecore_X_Window win)
420 Ecore_X_Window leader;
422 LOGFN(__FILE__, __LINE__, __FUNCTION__);
424 if (ecore_x_window_prop_window_get(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
432 * Set the window's client leader.
433 * @param win The window
434 * @param l The client leader window
436 * All non-transient top-level windows created by an app other than
437 * the main window must have this property set to the app's main window.
440 ecore_x_icccm_client_leader_set(Ecore_X_Window win,
441 Ecore_X_Window leader)
443 LOGFN(__FILE__, __LINE__, __FUNCTION__);
445 ecore_x_window_prop_window_set(win, ECORE_X_ATOM_WM_CLIENT_LEADER,
449 EAPI Ecore_X_Window_State_Hint
450 ecore_x_icccm_state_get(Ecore_X_Window win)
452 xcb_get_property_cookie_t cookie;
453 xcb_get_property_reply_t *reply;
454 Ecore_X_Window_State_Hint hint = ECORE_X_WINDOW_STATE_HINT_NONE;
457 LOGFN(__FILE__, __LINE__, __FUNCTION__);
461 xcb_get_property_unchecked(_ecore_xcb_conn, 0, win,
462 ECORE_X_ATOM_WM_STATE, ECORE_X_ATOM_WM_STATE,
464 reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
465 if (!reply) return hint;
466 if ((reply->type == 0) || (reply->format != 8) || (reply->value_len != 2))
472 prop = (uint8_t *)xcb_get_property_value(reply);
475 case XCB_ICCCM_WM_STATE_WITHDRAWN:
476 hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
479 case XCB_ICCCM_WM_STATE_NORMAL:
480 hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
483 case XCB_ICCCM_WM_STATE_ICONIC:
484 hint = ECORE_X_WINDOW_STATE_HINT_ICONIC;
496 ecore_x_icccm_state_set(Ecore_X_Window win,
497 Ecore_X_Window_State_Hint state)
499 xcb_icccm_wm_hints_t hints;
501 LOGFN(__FILE__, __LINE__, __FUNCTION__);
504 xcb_icccm_wm_hints_set_none(&hints);
506 hints.flags = XCB_ICCCM_WM_HINT_STATE;
508 if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
509 xcb_icccm_wm_hints_set_withdrawn(&hints);
510 else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
511 xcb_icccm_wm_hints_set_normal(&hints);
512 else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
513 xcb_icccm_wm_hints_set_iconic(&hints);
515 xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints);
519 ecore_x_icccm_delete_window_send(Ecore_X_Window win,
522 LOGFN(__FILE__, __LINE__, __FUNCTION__);
523 ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
524 ECORE_X_EVENT_MASK_NONE,
525 ECORE_X_ATOM_WM_DELETE_WINDOW, t, 0, 0, 0);
529 ecore_x_icccm_hints_set(Ecore_X_Window win,
530 Eina_Bool accepts_focus,
531 Ecore_X_Window_State_Hint initial_state,
532 Ecore_X_Pixmap icon_pixmap,
533 Ecore_X_Pixmap icon_mask,
534 Ecore_X_Window icon_window,
535 Ecore_X_Window window_group,
538 xcb_icccm_wm_hints_t hints;
540 LOGFN(__FILE__, __LINE__, __FUNCTION__);
543 xcb_icccm_wm_hints_set_none(&hints);
544 xcb_icccm_wm_hints_set_input(&hints, accepts_focus);
546 if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
547 xcb_icccm_wm_hints_set_withdrawn(&hints);
548 else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
549 xcb_icccm_wm_hints_set_normal(&hints);
550 else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
551 xcb_icccm_wm_hints_set_iconic(&hints);
553 if (icon_pixmap != 0)
554 xcb_icccm_wm_hints_set_icon_pixmap(&hints, icon_pixmap);
556 xcb_icccm_wm_hints_set_icon_mask(&hints, icon_mask);
557 if (icon_window != 0)
558 xcb_icccm_wm_hints_set_icon_window(&hints, icon_window);
559 if (window_group != 0)
560 xcb_icccm_wm_hints_set_window_group(&hints, window_group);
562 xcb_icccm_wm_hints_set_urgency(&hints);
564 xcb_icccm_set_wm_hints(_ecore_xcb_conn, win, &hints);
568 ecore_x_icccm_hints_get(Ecore_X_Window win,
569 Eina_Bool *accepts_focus,
570 Ecore_X_Window_State_Hint *initial_state,
571 Ecore_X_Pixmap *icon_pixmap,
572 Ecore_X_Pixmap *icon_mask,
573 Ecore_X_Window *icon_window,
574 Ecore_X_Window *window_group,
575 Eina_Bool *is_urgent)
577 xcb_get_property_cookie_t cookie;
578 xcb_icccm_wm_hints_t hints;
581 LOGFN(__FILE__, __LINE__, __FUNCTION__);
584 if (accepts_focus) *accepts_focus = EINA_TRUE;
585 if (initial_state) *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
586 if (icon_pixmap) *icon_pixmap = 0;
587 if (icon_mask) *icon_mask = 0;
588 if (icon_window) *icon_window = 0;
589 if (window_group) *window_group = 0;
590 if (is_urgent) *is_urgent = EINA_FALSE;
592 xcb_icccm_wm_hints_set_none(&hints);
593 cookie = xcb_icccm_get_wm_hints_unchecked(_ecore_xcb_conn, win);
594 ret = xcb_icccm_get_wm_hints_reply(_ecore_xcb_conn, cookie, &hints, NULL);
595 if (!ret) return EINA_FALSE;
597 if ((hints.flags & XCB_ICCCM_WM_HINT_INPUT) && (accepts_focus))
600 *accepts_focus = EINA_TRUE;
602 *accepts_focus = EINA_FALSE;
605 if ((hints.flags & XCB_ICCCM_WM_HINT_STATE) && (initial_state))
607 if (hints.initial_state == XCB_ICCCM_WM_STATE_WITHDRAWN)
608 *initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
609 else if (hints.initial_state == XCB_ICCCM_WM_STATE_NORMAL)
610 *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
611 else if (hints.initial_state == XCB_ICCCM_WM_STATE_ICONIC)
612 *initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
615 if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_PIXMAP) && (icon_pixmap))
616 *icon_pixmap = hints.icon_pixmap;
618 if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_MASK) && (icon_mask))
619 *icon_mask = hints.icon_mask;
621 if ((hints.flags & XCB_ICCCM_WM_HINT_ICON_WINDOW) && (icon_window))
622 *icon_window = hints.icon_window;
624 if ((hints.flags & XCB_ICCCM_WM_HINT_WINDOW_GROUP) && (window_group))
625 *window_group = hints.window_group;
627 if ((hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY) && (is_urgent))
628 *is_urgent = EINA_TRUE;
634 * Get a window icon name.
635 * @param win The window
636 * @return The windows icon name string
638 * Return the icon name of a window. String must be free'd when done with.
641 ecore_x_icccm_icon_name_get(Ecore_X_Window win)
643 xcb_get_property_cookie_t cookie;
644 xcb_icccm_get_text_property_reply_t prop;
648 LOGFN(__FILE__, __LINE__, __FUNCTION__);
651 if (!win) return NULL;
653 cookie = xcb_icccm_get_wm_icon_name_unchecked(_ecore_xcb_conn, win);
654 ret = xcb_icccm_get_wm_icon_name_reply(_ecore_xcb_conn, cookie, &prop, NULL);
655 if (ret == 0) return NULL;
657 if (prop.name_len < 1)
659 xcb_icccm_get_text_property_reply_wipe(&prop);
663 if (!(tmp = malloc((prop.name_len + 1) * sizeof(char *))))
665 xcb_icccm_get_text_property_reply_wipe(&prop);
668 memcpy(tmp, prop.name, sizeof(char *) * prop.name_len);
669 tmp[prop.name_len] = '\0';
671 if (prop.encoding != ECORE_X_ATOM_UTF8_STRING)
673 Ecore_Xcb_Textproperty tp;
676 Eina_Bool ret = EINA_FALSE;
678 tp.value = strdup(tmp);
679 tp.nitems = prop.name_len;
680 tp.encoding = prop.encoding;
682 ret = _ecore_xcb_utf8_textproperty_to_textlist(&tp, &list, &count);
684 ret = _ecore_xcb_mb_textproperty_to_textlist(&tp, &list, &count);
689 tmp = strdup(list[0]);
691 if (list) free(list);
695 xcb_icccm_get_text_property_reply_wipe(&prop);
700 * Set a window icon name.
701 * @param win The window
702 * @param t The icon name string
704 * Set a window icon name
707 ecore_x_icccm_icon_name_set(Ecore_X_Window win,
710 Ecore_Xcb_Textproperty prop;
712 Eina_Bool ret = EINA_FALSE;
714 LOGFN(__FILE__, __LINE__, __FUNCTION__);
717 if ((!win) || (!name)) return;
720 list[0] = strdup(name);
723 ret = _ecore_xcb_utf8_textlist_to_textproperty(list, 1, XcbUTF8StringStyle,
726 ret = _ecore_xcb_mb_textlist_to_textproperty(list, 1, XcbStdICCTextStyle,
732 xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
733 8, strlen(prop.value), prop.value);
734 if (prop.value) free(prop.value);
737 xcb_icccm_set_wm_icon_name(_ecore_xcb_conn, win, ECORE_X_ATOM_STRING,
738 8, strlen(name), name);
744 ecore_x_icccm_iconic_request_send(Ecore_X_Window win,
747 xcb_client_message_event_t ev;
749 LOGFN(__FILE__, __LINE__, __FUNCTION__);
753 if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
755 memset(&ev, 0, sizeof(xcb_client_message_event_t));
757 ev.response_type = XCB_CLIENT_MESSAGE;
760 ev.type = ECORE_X_ATOM_WM_CHANGE_STATE;
761 ev.data.data32[0] = XCB_ICCCM_WM_STATE_ICONIC;
763 xcb_send_event(_ecore_xcb_conn, 0, root,
764 (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
765 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT),
771 * Set or unset a wm protocol property.
772 * @param win The Window
773 * @param protocol The protocol to enable/disable
777 ecore_x_icccm_protocol_set(Ecore_X_Window win,
778 Ecore_X_WM_Protocol protocol,
782 xcb_get_property_cookie_t cookie;
783 xcb_icccm_get_wm_protocols_reply_t protos;
784 int i = 0, count = 0, set = 0;
786 LOGFN(__FILE__, __LINE__, __FUNCTION__);
789 if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return;
790 proto = _ecore_xcb_atoms_wm_protocol[protocol];
791 cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto);
792 if (!xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &protos, NULL))
795 count = protos.atoms_len;
797 for (i = 0; i < count; i++)
799 if (protos.atoms[i] == proto)
810 Ecore_X_Atom *atoms = NULL;
812 atoms = malloc((count + 1) * sizeof(Ecore_X_Atom));
815 for (i = 0; i < count; i++)
816 atoms[i] = protos.atoms[i];
817 atoms[count] = proto;
818 xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win,
819 ECORE_X_ATOM_WM_PROTOCOLS,
829 for (i = 0; i < count; i++)
831 if (protos.atoms[i] == proto)
835 for (j = (i + 1); j < count; j++)
836 protos.atoms[j - 1] = protos.atoms[j];
838 xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win,
839 ECORE_X_ATOM_WM_PROTOCOLS,
840 count - 1, protos.atoms);
842 ecore_x_window_prop_property_del(win,
843 ECORE_X_ATOM_WM_PROTOCOLS);
850 xcb_icccm_get_wm_protocols_reply_wipe(&protos);
854 * Determines whether a protocol is set for a window.
855 * @param win The Window
856 * @param protocol The protocol to query
857 * @return 1 if the protocol is set, else 0.
860 ecore_x_icccm_protocol_isset(Ecore_X_Window win,
861 Ecore_X_WM_Protocol protocol)
864 Eina_Bool ret = EINA_FALSE;
865 xcb_get_property_cookie_t cookie;
866 xcb_icccm_get_wm_protocols_reply_t reply;
870 LOGFN(__FILE__, __LINE__, __FUNCTION__);
873 if (protocol >= ECORE_X_WM_PROTOCOL_NUM) return EINA_FALSE;
875 proto = _ecore_xcb_atoms_wm_protocol[protocol];
876 cookie = xcb_icccm_get_wm_protocols_unchecked(_ecore_xcb_conn, win, proto);
877 val = xcb_icccm_get_wm_protocols_reply(_ecore_xcb_conn, cookie, &reply, NULL);
878 if (!val) return EINA_FALSE;
880 for (i = 0; i < reply.atoms_len; i++)
881 if (reply.atoms[i] == proto)
887 xcb_icccm_get_wm_protocols_reply_wipe(&reply);
893 * Set protocol atoms explicitly
894 * @param win The Window
895 * @param protos An array of protocol atoms
896 * @param num the number of members of the array
899 ecore_x_icccm_protocol_atoms_set(Ecore_X_Window win,
900 Ecore_X_Atom *protos,
903 LOGFN(__FILE__, __LINE__, __FUNCTION__);
907 xcb_icccm_set_wm_protocols(_ecore_xcb_conn, win,
908 ECORE_X_ATOM_WM_PROTOCOLS, num, protos);
910 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_PROTOCOLS);
914 ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win,
915 Eina_Bool *request_pos,
916 Ecore_X_Gravity *gravity,
928 xcb_size_hints_t hints;
929 xcb_get_property_cookie_t cookie;
931 int32_t minw = 0, minh = 0;
932 int32_t maxw = 32767, maxh = 32767;
933 int32_t basew = -1, baseh = -1;
934 int32_t stepx = -1, stepy = -1;
935 double mina = 0.0, maxa = 0.0;
937 LOGFN(__FILE__, __LINE__, __FUNCTION__);
940 if (request_pos) *request_pos = EINA_FALSE;
941 if (gravity) *gravity = ECORE_X_GRAVITY_NW;
942 if (min_w) *min_w = minw;
943 if (min_h) *min_h = minh;
944 if (max_w) *max_w = maxw;
945 if (max_h) *max_h = maxh;
946 if (base_w) *base_w = basew;
947 if (base_h) *base_h = baseh;
948 if (step_x) *step_x = stepx;
949 if (step_y) *step_y = stepy;
950 if (min_aspect) *min_aspect = mina;
951 if (max_aspect) *max_aspect = maxa;
953 cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win);
954 ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie,
956 if (!ret) return EINA_FALSE;
958 if ((hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION) ||
959 (hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION))
961 if (request_pos) *request_pos = EINA_TRUE;
964 if (hints.flags & XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY)
966 if (gravity) *gravity = hints.win_gravity;
969 if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE)
971 minw = hints.min_width;
972 minh = hints.min_height;
975 if (hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE)
977 maxw = hints.max_width;
978 maxh = hints.max_height;
979 if (maxw < minw) maxw = minw;
980 if (maxh < minh) maxh = minh;
983 if (hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE)
985 basew = hints.base_width;
986 baseh = hints.base_height;
987 if (basew > minw) minw = basew;
988 if (baseh > minh) minh = baseh;
991 if (hints.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC)
993 stepx = hints.width_inc;
994 stepy = hints.height_inc;
995 if (stepx < 1) stepx = 1;
996 if (stepy < 1) stepy = 1;
999 if (hints.flags & XCB_ICCCM_SIZE_HINT_P_ASPECT)
1001 if (hints.min_aspect_den > 0)
1002 mina = ((double)hints.min_aspect_num) / ((double)hints.min_aspect_den);
1004 if (hints.max_aspect_den > 0)
1005 maxa = ((double)hints.max_aspect_num) / ((double)hints.max_aspect_den);
1008 if (min_w) *min_w = minw;
1009 if (min_h) *min_h = minh;
1010 if (max_w) *max_w = maxw;
1011 if (max_h) *max_h = maxh;
1012 if (base_w) *base_w = basew;
1013 if (base_h) *base_h = baseh;
1014 if (step_x) *step_x = stepx;
1015 if (step_y) *step_y = stepy;
1016 if (min_aspect) *min_aspect = mina;
1017 if (max_aspect) *max_aspect = maxa;
1023 ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win,
1024 Eina_Bool request_pos,
1025 Ecore_X_Gravity gravity,
1037 xcb_get_property_cookie_t cookie;
1038 xcb_size_hints_t hints;
1041 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1044 cookie = xcb_icccm_get_wm_normal_hints_unchecked(_ecore_xcb_conn, win);
1045 ret = xcb_icccm_get_wm_normal_hints_reply(_ecore_xcb_conn, cookie,
1047 if (!ret) memset(&hints, 0, sizeof(xcb_size_hints_t));
1052 hints.flags |= XCB_ICCCM_SIZE_HINT_US_POSITION;
1054 if (gravity != ECORE_X_GRAVITY_NW)
1055 xcb_icccm_size_hints_set_win_gravity(&hints, gravity);
1056 if ((min_w > 0) || (min_h > 0))
1057 xcb_icccm_size_hints_set_min_size(&hints, min_w, min_h);
1058 if ((max_w > 0) || (max_h > 0))
1059 xcb_icccm_size_hints_set_max_size(&hints, max_w, max_h);
1060 if ((base_w > 0) || (base_h > 0))
1061 xcb_icccm_size_hints_set_base_size(&hints, base_w, base_h);
1062 if ((step_x > 1) || (step_y > 1))
1063 xcb_icccm_size_hints_set_resize_inc(&hints, step_x, step_y);
1064 if ((min_aspect > 0.0) || (max_aspect > 0.0))
1065 xcb_icccm_size_hints_set_aspect(&hints,
1066 (int32_t)(min_aspect * 10000), 10000,
1067 (int32_t)(max_aspect * 10000), 10000);
1069 xcb_icccm_set_wm_normal_hints(_ecore_xcb_conn, win, &hints);
1073 ecore_x_icccm_move_resize_send(Ecore_X_Window win,
1079 xcb_configure_notify_event_t ev;
1081 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1086 memset(&ev, 0, sizeof(xcb_configure_notify_event_t));
1088 ev.response_type = XCB_CONFIGURE_NOTIFY;
1091 ev.above_sibling = XCB_NONE;
1096 ev.border_width = 0;
1097 ev.override_redirect = 0;
1099 xcb_send_event(_ecore_xcb_conn, 0, win,
1100 XCB_EVENT_MASK_STRUCTURE_NOTIFY, (const char *)&ev);
1105 * Get a window client machine string.
1106 * @param win The window
1107 * @return The windows client machine string
1109 * Return the client machine of a window. String must be free'd when done with.
1112 ecore_x_icccm_client_machine_get(Ecore_X_Window win)
1114 xcb_get_property_cookie_t cookie;
1115 xcb_icccm_get_text_property_reply_t prop;
1119 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1122 cookie = xcb_icccm_get_wm_client_machine_unchecked(_ecore_xcb_conn, win);
1123 ret = xcb_icccm_get_wm_client_machine_reply(_ecore_xcb_conn, cookie,
1125 if (ret == 0) return NULL;
1127 tmp = malloc((prop.name_len + 1) * sizeof(char *));
1130 xcb_icccm_get_text_property_reply_wipe(&prop);
1133 memcpy(tmp, prop.name, sizeof(char *) * prop.name_len);
1134 tmp[prop.name_len] = '\0';
1136 xcb_icccm_get_text_property_reply_wipe(&prop);
1142 ecore_x_icccm_take_focus_send(Ecore_X_Window win,
1145 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1148 ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
1149 XCB_EVENT_MASK_NO_EVENT,
1150 ECORE_X_ATOM_WM_TAKE_FOCUS, t, 0, 0, 0);
1154 ecore_x_icccm_save_yourself_send(Ecore_X_Window win,
1157 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1158 ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
1159 XCB_EVENT_MASK_NO_EVENT,
1160 ECORE_X_ATOM_WM_SAVE_YOURSELF, t, 0, 0, 0);
1164 * Add a subwindow to the list of windows that need a different colormap installed.
1165 * @param win The toplevel window
1166 * @param subwin The subwindow to be added to the colormap windows list
1169 ecore_x_icccm_colormap_window_set(Ecore_X_Window win,
1170 Ecore_X_Window subwin)
1173 unsigned char *odata = NULL, *data = NULL;
1174 Ecore_X_Window *newset = NULL, *oldset = NULL;
1176 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1178 if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1179 ECORE_X_ATOM_WINDOW, 32, &odata, &num))
1181 if (!(newset = calloc(1, sizeof(Ecore_X_Window)))) return;
1184 data = (unsigned char *)newset;
1188 if (!(newset = calloc(num + 1, sizeof(Ecore_X_Window)))) return;
1189 oldset = (Ecore_X_Window *)odata;
1190 for (i = 0; i < num; i++)
1192 if (oldset[i] == subwin)
1194 if (odata) free(odata);
1199 newset[i] = oldset[i];
1201 newset[num++] = subwin;
1202 if (odata) free(odata);
1203 data = (unsigned char *)newset;
1205 ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1206 ECORE_X_ATOM_WINDOW, 32, data, num);
1211 * Remove a window from the list of colormap windows.
1212 * @param win The toplevel window
1213 * @param subwin The window to be removed from the colormap window list.
1216 ecore_x_icccm_colormap_window_unset(Ecore_X_Window win,
1217 Ecore_X_Window subwin)
1219 int num = 0, i = 0, j = 0, k = 0;
1220 unsigned char *odata = NULL, *data = NULL;
1221 Ecore_X_Window *newset = NULL, *oldset = NULL;
1223 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1225 if (!ecore_x_window_prop_property_get(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1226 ECORE_X_ATOM_WINDOW, 32, &odata, &num))
1229 oldset = (Ecore_X_Window *)odata;
1230 for (i = 0; i < num; i++)
1232 if (oldset[i] == subwin)
1236 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS);
1237 if (odata) free(odata);
1243 newset = calloc(num - 1, sizeof(Ecore_X_Window));
1244 data = (unsigned char *)newset;
1245 for (j = 0; j < num; ++j)
1246 if (oldset[j] != subwin)
1247 newset[k++] = oldset[j];
1249 ecore_x_window_prop_property_set(win, ECORE_X_ATOM_WM_COLORMAP_WINDOWS,
1250 ECORE_X_ATOM_WINDOW, 32, data, k);
1251 if (odata) free(odata);
1258 if (odata) free(odata);