2 * _NET_WM... aka Extended Window Manager Hint (EWMH) functions.
14 #include "ecore_x_private.h"
17 typedef struct _Ecore_X_Startup_Info Ecore_X_Startup_Info;
19 struct _Ecore_X_Startup_Info
30 /* These are the sequence info fields */
43 static void _ecore_x_window_prop_string_utf8_set(Ecore_X_Window win,
46 static char *_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win,
49 static int _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info);
50 static int _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info,
53 static void _ecore_x_netwm_startup_info_free(void *data);
58 #define _ATOM_SET_UTF8_STRING_LIST(win, atom, string, cnt) \
59 XChangeProperty(_ecore_x_disp, \
62 ECORE_X_ATOM_UTF8_STRING, \
65 (unsigned char *)string, \
72 static Eina_Hash *startup_info = NULL;
75 ecore_x_netwm_init(void)
77 LOGFN(__FILE__, __LINE__, __FUNCTION__);
78 startup_info = eina_hash_string_superfast_new(
79 _ecore_x_netwm_startup_info_free);
83 ecore_x_netwm_shutdown(void)
85 LOGFN(__FILE__, __LINE__, __FUNCTION__);
87 eina_hash_free(startup_info);
96 ecore_x_netwm_wm_identify(Ecore_X_Window root,
100 LOGFN(__FILE__, __LINE__, __FUNCTION__);
101 ecore_x_window_prop_window_set(check,
102 ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK,
105 _ecore_x_window_prop_string_utf8_set(check,
106 ECORE_X_ATOM_NET_WM_NAME,
108 /* This one isn't mandatory */
109 _ecore_x_window_prop_string_utf8_set(root,
110 ECORE_X_ATOM_NET_WM_NAME,
112 ecore_x_window_prop_window_set(root,
113 ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK,
119 * Set supported atoms
122 ecore_x_netwm_supported_set(Ecore_X_Window root,
123 Ecore_X_Atom *supported,
126 LOGFN(__FILE__, __LINE__, __FUNCTION__);
127 ecore_x_window_prop_atom_set(root,
128 ECORE_X_ATOM_NET_SUPPORTED,
134 ecore_x_netwm_supported_get(Ecore_X_Window root,
135 Ecore_X_Atom **supported,
146 LOGFN(__FILE__, __LINE__, __FUNCTION__);
147 num_ret = ecore_x_window_prop_atom_list_get(root, ECORE_X_ATOM_NET_SUPPORTED,
159 * Desktop configuration and status
162 ecore_x_netwm_desk_count_set(Ecore_X_Window root,
163 unsigned int n_desks)
165 LOGFN(__FILE__, __LINE__, __FUNCTION__);
166 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS,
171 ecore_x_netwm_desk_roots_set(Ecore_X_Window root,
172 Ecore_X_Window *vroots,
173 unsigned int n_desks)
175 LOGFN(__FILE__, __LINE__, __FUNCTION__);
176 ecore_x_window_prop_window_set(root,
177 ECORE_X_ATOM_NET_VIRTUAL_ROOTS,
183 ecore_x_netwm_desk_names_set(Ecore_X_Window root,
185 unsigned int n_desks)
187 char ss[32], *buf, *t;
192 LOGFN(__FILE__, __LINE__, __FUNCTION__);
196 for (i = 0; i < n_desks; i++)
198 s = (names) ? names[i] : NULL;
201 /* Default to "Desk-<number>" */
202 sprintf(ss, "Desk-%d", i);
207 t = realloc(buf, len + l);
211 memcpy(buf + len, s, l);
216 _ATOM_SET_UTF8_STRING_LIST(root, ECORE_X_ATOM_NET_DESKTOP_NAMES, buf, len);
222 ecore_x_netwm_desk_size_set(Ecore_X_Window root,
226 unsigned int size[2];
228 LOGFN(__FILE__, __LINE__, __FUNCTION__);
231 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_GEOMETRY, size,
236 ecore_x_netwm_desk_viewports_set(Ecore_X_Window root,
237 unsigned int *origins,
238 unsigned int n_desks)
240 LOGFN(__FILE__, __LINE__, __FUNCTION__);
241 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_VIEWPORT,
242 origins, 2 * n_desks);
246 ecore_x_netwm_desk_layout_set(Ecore_X_Window root,
252 unsigned int layout[4];
254 LOGFN(__FILE__, __LINE__, __FUNCTION__);
255 layout[0] = orientation;
258 layout[3] = starting_corner;
259 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT,
264 ecore_x_netwm_desk_workareas_set(Ecore_X_Window root,
266 unsigned int n_desks)
268 LOGFN(__FILE__, __LINE__, __FUNCTION__);
269 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_WORKAREA, areas,
274 ecore_x_netwm_desk_workareas_get(Ecore_X_Window root, unsigned int *n_desks)
277 unsigned int *areas = NULL;
279 if (!root) root = DefaultRootWindow(_ecore_x_disp);
281 ret = ecore_x_window_prop_card32_list_get(root, ECORE_X_ATOM_NET_WORKAREA,
285 if (n_desks) *n_desks = 0;
288 if (n_desks) *n_desks = ret / 4;
293 ecore_x_netwm_desk_current_set(Ecore_X_Window root,
296 LOGFN(__FILE__, __LINE__, __FUNCTION__);
297 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_CURRENT_DESKTOP, &desk,
302 ecore_x_netwm_showing_desktop_set(Ecore_X_Window root,
307 LOGFN(__FILE__, __LINE__, __FUNCTION__);
309 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, &val,
319 ecore_x_netwm_client_list_set(Ecore_X_Window root,
320 Ecore_X_Window *p_clients,
321 unsigned int n_clients)
323 LOGFN(__FILE__, __LINE__, __FUNCTION__);
324 ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST,
325 p_clients, n_clients);
330 ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root,
331 Ecore_X_Window *p_clients,
332 unsigned int n_clients)
334 LOGFN(__FILE__, __LINE__, __FUNCTION__);
335 ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST_STACKING,
336 p_clients, n_clients);
340 ecore_x_netwm_client_active_set(Ecore_X_Window root,
343 LOGFN(__FILE__, __LINE__, __FUNCTION__);
344 ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_ACTIVE_WINDOW,
349 ecore_x_netwm_client_active_request(Ecore_X_Window root,
352 Ecore_X_Window current_win)
356 LOGFN(__FILE__, __LINE__, __FUNCTION__);
358 root = DefaultRootWindow(_ecore_x_disp);
360 xev.xclient.type = ClientMessage;
361 xev.xclient.display = _ecore_x_disp;
362 xev.xclient.window = win;
363 xev.xclient.message_type = ECORE_X_ATOM_NET_ACTIVE_WINDOW;
364 xev.xclient.format = 32;
365 xev.xclient.data.l[0] = type;
366 xev.xclient.data.l[1] = CurrentTime;
367 xev.xclient.data.l[2] = current_win;
368 xev.xclient.data.l[3] = 0;
369 xev.xclient.data.l[4] = 0;
371 XSendEvent(_ecore_x_disp, root, False,
372 SubstructureRedirectMask | SubstructureNotifyMask, &xev);
376 ecore_x_netwm_name_set(Ecore_X_Window win,
379 LOGFN(__FILE__, __LINE__, __FUNCTION__);
380 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_NAME, name);
384 ecore_x_netwm_name_get(Ecore_X_Window win,
387 LOGFN(__FILE__, __LINE__, __FUNCTION__);
389 *name = _ecore_x_window_prop_string_utf8_get(win,
390 ECORE_X_ATOM_NET_WM_NAME);
396 ecore_x_netwm_startup_id_set(Ecore_X_Window win,
399 LOGFN(__FILE__, __LINE__, __FUNCTION__);
400 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_STARTUP_ID, id);
404 ecore_x_netwm_startup_id_get(Ecore_X_Window win,
407 LOGFN(__FILE__, __LINE__, __FUNCTION__);
409 *id = _ecore_x_window_prop_string_utf8_get(win,
410 ECORE_X_ATOM_NET_STARTUP_ID);
416 ecore_x_netwm_visible_name_set(Ecore_X_Window win,
419 LOGFN(__FILE__, __LINE__, __FUNCTION__);
420 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
425 ecore_x_netwm_visible_name_get(Ecore_X_Window win,
428 LOGFN(__FILE__, __LINE__, __FUNCTION__);
430 *name = _ecore_x_window_prop_string_utf8_get(
432 ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
438 ecore_x_netwm_icon_name_set(Ecore_X_Window win,
441 LOGFN(__FILE__, __LINE__, __FUNCTION__);
442 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME,
447 ecore_x_netwm_icon_name_get(Ecore_X_Window win,
450 LOGFN(__FILE__, __LINE__, __FUNCTION__);
452 *name = _ecore_x_window_prop_string_utf8_get(
454 ECORE_X_ATOM_NET_WM_ICON_NAME);
460 ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win,
463 LOGFN(__FILE__, __LINE__, __FUNCTION__);
464 _ecore_x_window_prop_string_utf8_set(win,
465 ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
470 ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win,
473 LOGFN(__FILE__, __LINE__, __FUNCTION__);
475 *name = _ecore_x_window_prop_string_utf8_get(
477 ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
483 ecore_x_netwm_desktop_set(Ecore_X_Window win,
486 LOGFN(__FILE__, __LINE__, __FUNCTION__);
487 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
491 ecore_x_netwm_desktop_get(Ecore_X_Window win,
497 LOGFN(__FILE__, __LINE__, __FUNCTION__);
498 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP,
504 return ret == 1 ? EINA_TRUE : EINA_FALSE;
508 * _NET_WM_STRUT is deprecated
511 ecore_x_netwm_strut_set(Ecore_X_Window win,
517 unsigned int strut[4];
519 LOGFN(__FILE__, __LINE__, __FUNCTION__);
524 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
528 * _NET_WM_STRUT is deprecated
531 ecore_x_netwm_strut_get(Ecore_X_Window win,
538 unsigned int strut[4];
540 LOGFN(__FILE__, __LINE__, __FUNCTION__);
541 ret = ecore_x_window_prop_card32_get(win,
542 ECORE_X_ATOM_NET_WM_STRUT,
564 ecore_x_netwm_strut_partial_set(Ecore_X_Window win,
578 unsigned int strut[12];
580 LOGFN(__FILE__, __LINE__, __FUNCTION__);
585 strut[4] = left_start_y;
586 strut[5] = left_end_y;
587 strut[6] = right_start_y;
588 strut[7] = right_end_y;
589 strut[8] = top_start_x;
590 strut[9] = top_end_x;
591 strut[10] = bottom_start_x;
592 strut[11] = bottom_end_x;
593 ecore_x_window_prop_card32_set(win,
594 ECORE_X_ATOM_NET_WM_STRUT_PARTIAL,
600 ecore_x_netwm_strut_partial_get(Ecore_X_Window win,
615 unsigned int strut[12];
617 LOGFN(__FILE__, __LINE__, __FUNCTION__);
618 ret = ecore_x_window_prop_card32_get(win,
619 ECORE_X_ATOM_NET_WM_STRUT_PARTIAL,
638 *left_start_y = strut[4];
641 *left_end_y = strut[5];
644 *right_start_y = strut[6];
647 *right_end_y = strut[7];
650 *top_start_x = strut[8];
653 *top_end_x = strut[9];
656 *bottom_start_x = strut[10];
659 *bottom_end_x = strut[11];
665 ecore_x_netwm_icons_set(Ecore_X_Window win,
669 unsigned int *data, *p, *p2;
670 unsigned int i, size, x, y;
672 LOGFN(__FILE__, __LINE__, __FUNCTION__);
674 for (i = 0; i < (unsigned int)num; i++)
676 size += 2 + (icon[i].width * icon[i].height);
678 data = malloc(size * sizeof(unsigned int));
681 for (i = 0; i < (unsigned int)num; i++)
683 p[0] = icon[i].width;
684 p[1] = icon[i].height;
687 for (y = 0; y < icon[i].height; y++)
689 for (x = 0; x < icon[i].width; x++)
691 unsigned int r, g, b, a;
693 a = (*p2 >> 24) & 0xff;
694 r = (*p2 >> 16) & 0xff;
695 g = (*p2 >> 8 ) & 0xff;
697 if ((a > 0) && (a < 255))
704 *p = (a << 24) | (r << 16) | (g << 8) | b;
710 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_ICON,
716 ecore_x_netwm_icons_get(Ecore_X_Window win,
720 unsigned int *data, *p;
722 unsigned int len, icons, i;
725 LOGFN(__FILE__, __LINE__, __FUNCTION__);
732 num_ret = ecore_x_window_prop_card32_list_get(win, ECORE_X_ATOM_NET_WM_ICON,
746 /* Check how many icons there are */
753 if ((p - data) > num_ret)
761 if ((p - data) == num_ret)
767 /* If the user doesn't want the icons, return */
774 /* Allocate memory */
775 *icon = malloc(icons * sizeof(Ecore_X_Icon));
782 /* Fetch the icons */
784 for (i = 0; i < icons; i++)
786 unsigned int *ps, *pd, *pe;
789 ((*icon)[i]).width = p[0];
790 ((*icon)[i]).height = p[1];
792 ((*icon)[i]).data = malloc(len * sizeof(unsigned int));
793 if (!((*icon)[i]).data)
796 free(((*icon)[--i]).data);
802 pd = ((*icon)[i]).data;
805 for (; ps < pe; ps++)
807 unsigned int r, g, b, a;
809 a = (*ps >> 24) & 0xff;
810 r = (((*ps >> 16) & 0xff) * a) / 255;
811 g = (((*ps >> 8) & 0xff) * a) / 255;
812 b = (((*ps) & 0xff) * a) / 255;
813 *pd = (a << 24) | (r << 16) | (g << 8) | (b);
825 ecore_x_netwm_icon_geometry_set(Ecore_X_Window win,
831 unsigned int geometry[4];
833 LOGFN(__FILE__, __LINE__, __FUNCTION__);
837 geometry[3] = height;
838 ecore_x_window_prop_card32_set(win,
839 ECORE_X_ATOM_NET_WM_ICON_GEOMETRY,
845 ecore_x_netwm_icon_geometry_get(Ecore_X_Window win,
852 unsigned int geometry[4];
854 LOGFN(__FILE__, __LINE__, __FUNCTION__);
855 ret = ecore_x_window_prop_card32_get(win,
856 ECORE_X_ATOM_NET_WM_ICON_GEOMETRY,
869 *width = geometry[2];
872 *height = geometry[3];
878 ecore_x_netwm_pid_set(Ecore_X_Window win,
883 LOGFN(__FILE__, __LINE__, __FUNCTION__);
885 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_PID,
890 ecore_x_netwm_pid_get(Ecore_X_Window win,
896 LOGFN(__FILE__, __LINE__, __FUNCTION__);
897 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID,
902 return ret == 1 ? EINA_TRUE : EINA_FALSE;
906 ecore_x_netwm_handled_icons_set(Ecore_X_Window win)
908 LOGFN(__FILE__, __LINE__, __FUNCTION__);
909 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
914 ecore_x_netwm_handled_icons_get(Ecore_X_Window win)
917 LOGFN(__FILE__, __LINE__, __FUNCTION__);
918 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
920 return ret == 0 ? EINA_TRUE : EINA_FALSE;
924 ecore_x_netwm_user_time_set(Ecore_X_Window win,
927 LOGFN(__FILE__, __LINE__, __FUNCTION__);
928 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME,
933 ecore_x_netwm_user_time_get(Ecore_X_Window win,
939 LOGFN(__FILE__, __LINE__, __FUNCTION__);
940 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME,
945 return ret == 1 ? EINA_TRUE : EINA_FALSE;
949 _ecore_x_netwm_state_get(Ecore_X_Atom a)
951 if (a == ECORE_X_ATOM_NET_WM_STATE_MODAL)
952 return ECORE_X_WINDOW_STATE_MODAL;
953 else if (a == ECORE_X_ATOM_NET_WM_STATE_STICKY)
954 return ECORE_X_WINDOW_STATE_STICKY;
955 else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
956 return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
957 else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
958 return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
959 else if (a == ECORE_X_ATOM_NET_WM_STATE_SHADED)
960 return ECORE_X_WINDOW_STATE_SHADED;
961 else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
962 return ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
963 else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
964 return ECORE_X_WINDOW_STATE_SKIP_PAGER;
965 else if (a == ECORE_X_ATOM_NET_WM_STATE_HIDDEN)
966 return ECORE_X_WINDOW_STATE_HIDDEN;
967 else if (a == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
968 return ECORE_X_WINDOW_STATE_FULLSCREEN;
969 else if (a == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
970 return ECORE_X_WINDOW_STATE_ABOVE;
971 else if (a == ECORE_X_ATOM_NET_WM_STATE_BELOW)
972 return ECORE_X_WINDOW_STATE_BELOW;
973 else if (a == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
974 return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION;
976 return ECORE_X_WINDOW_STATE_UNKNOWN;
980 _ecore_x_netwm_state_atom_get(Ecore_X_Window_State s)
984 case ECORE_X_WINDOW_STATE_MODAL:
985 return ECORE_X_ATOM_NET_WM_STATE_MODAL;
987 case ECORE_X_WINDOW_STATE_STICKY:
988 return ECORE_X_ATOM_NET_WM_STATE_STICKY;
990 case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
991 return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
993 case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
994 return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
996 case ECORE_X_WINDOW_STATE_SHADED:
997 return ECORE_X_ATOM_NET_WM_STATE_SHADED;
999 case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
1000 return ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
1002 case ECORE_X_WINDOW_STATE_SKIP_PAGER:
1003 return ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
1005 case ECORE_X_WINDOW_STATE_HIDDEN:
1006 return ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
1008 case ECORE_X_WINDOW_STATE_FULLSCREEN:
1009 return ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
1011 case ECORE_X_WINDOW_STATE_ABOVE:
1012 return ECORE_X_ATOM_NET_WM_STATE_ABOVE;
1014 case ECORE_X_WINDOW_STATE_BELOW:
1015 return ECORE_X_ATOM_NET_WM_STATE_BELOW;
1017 case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION:
1018 return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
1026 ecore_x_netwm_window_state_set(Ecore_X_Window win,
1027 Ecore_X_Window_State *state,
1033 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1036 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_NET_WM_STATE);
1040 set = malloc(num * sizeof(Ecore_X_Atom));
1044 for (i = 0; i < num; i++)
1045 set[i] = _ecore_x_netwm_state_atom_get(state[i]);
1047 ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_STATE, set, num);
1053 ecore_x_netwm_window_state_get(Ecore_X_Window win,
1054 Ecore_X_Window_State **state,
1058 Ecore_X_Atom *atoms;
1060 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1067 num_ret = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_STATE,
1074 *state = malloc(num_ret * sizeof(Ecore_X_Window_State));
1076 for (i = 0; i < num_ret; ++i)
1077 (*state)[i] = _ecore_x_netwm_state_get(atoms[i]);
1087 static Ecore_X_Window_Type
1088 _ecore_x_netwm_window_type_type_get(Ecore_X_Atom atom)
1090 if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP)
1091 return ECORE_X_WINDOW_TYPE_DESKTOP;
1092 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK)
1093 return ECORE_X_WINDOW_TYPE_DOCK;
1094 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR)
1095 return ECORE_X_WINDOW_TYPE_TOOLBAR;
1096 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU)
1097 return ECORE_X_WINDOW_TYPE_MENU;
1098 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY)
1099 return ECORE_X_WINDOW_TYPE_UTILITY;
1100 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH)
1101 return ECORE_X_WINDOW_TYPE_SPLASH;
1102 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG)
1103 return ECORE_X_WINDOW_TYPE_DIALOG;
1104 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL)
1105 return ECORE_X_WINDOW_TYPE_NORMAL;
1106 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
1107 return ECORE_X_WINDOW_TYPE_DROPDOWN_MENU;
1108 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU)
1109 return ECORE_X_WINDOW_TYPE_POPUP_MENU;
1110 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP)
1111 return ECORE_X_WINDOW_TYPE_TOOLTIP;
1112 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION)
1113 return ECORE_X_WINDOW_TYPE_NOTIFICATION;
1114 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO)
1115 return ECORE_X_WINDOW_TYPE_COMBO;
1116 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND)
1117 return ECORE_X_WINDOW_TYPE_DND;
1119 return ECORE_X_WINDOW_TYPE_UNKNOWN;
1123 _ecore_x_netwm_window_type_atom_get(Ecore_X_Window_Type type)
1127 case ECORE_X_WINDOW_TYPE_DESKTOP:
1128 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
1130 case ECORE_X_WINDOW_TYPE_DOCK:
1131 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
1133 case ECORE_X_WINDOW_TYPE_TOOLBAR:
1134 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
1136 case ECORE_X_WINDOW_TYPE_MENU:
1137 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
1139 case ECORE_X_WINDOW_TYPE_UTILITY:
1140 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
1142 case ECORE_X_WINDOW_TYPE_SPLASH:
1143 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
1145 case ECORE_X_WINDOW_TYPE_DIALOG:
1146 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
1148 case ECORE_X_WINDOW_TYPE_NORMAL:
1149 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
1151 case ECORE_X_WINDOW_TYPE_DROPDOWN_MENU:
1152 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU;
1154 case ECORE_X_WINDOW_TYPE_POPUP_MENU:
1155 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU;
1157 case ECORE_X_WINDOW_TYPE_TOOLTIP:
1158 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP;
1160 case ECORE_X_WINDOW_TYPE_NOTIFICATION:
1161 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION;
1163 case ECORE_X_WINDOW_TYPE_COMBO:
1164 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO;
1166 case ECORE_X_WINDOW_TYPE_DND:
1167 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND;
1175 * FIXME: We should set WM_TRANSIENT_FOR if type is ECORE_X_WINDOW_TYPE_TOOLBAR
1176 * , ECORE_X_WINDOW_TYPE_MENU or ECORE_X_WINDOW_TYPE_DIALOG
1179 ecore_x_netwm_window_type_set(Ecore_X_Window win,
1180 Ecore_X_Window_Type type)
1184 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1185 atom = _ecore_x_netwm_window_type_atom_get(type);
1186 ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1190 /* FIXME: Maybe return 0 on some conditions? */
1192 ecore_x_netwm_window_type_get(Ecore_X_Window win,
1193 Ecore_X_Window_Type *type)
1196 Ecore_X_Atom *atoms = NULL;
1198 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1200 *type = ECORE_X_WINDOW_TYPE_NORMAL;
1202 num = ecore_x_window_prop_atom_list_get(win,
1203 ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1205 if ((type) && (num >= 1) && (atoms))
1206 *type = _ecore_x_netwm_window_type_type_get(atoms[0]);
1216 ecore_x_netwm_window_types_get(Ecore_X_Window win,
1217 Ecore_X_Window_Type **types)
1220 Ecore_X_Atom *atoms = NULL;
1221 Ecore_X_Window_Type *atoms2 = NULL;
1223 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1227 num = ecore_x_window_prop_atom_list_get(win,
1228 ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1230 if ((num <= 0) || (!atoms))
1238 atoms2 = malloc(num * sizeof(Ecore_X_Window_Type));
1242 for (i = 0; i < num; i++)
1243 atoms2[i] = _ecore_x_netwm_window_type_type_get(atoms[i]);
1254 _ecore_x_netwm_action_atom_get(Ecore_X_Action action)
1258 case ECORE_X_ACTION_MOVE:
1259 return ECORE_X_ATOM_NET_WM_ACTION_MOVE;
1261 case ECORE_X_ACTION_RESIZE:
1262 return ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
1264 case ECORE_X_ACTION_MINIMIZE:
1265 return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
1267 case ECORE_X_ACTION_SHADE:
1268 return ECORE_X_ATOM_NET_WM_ACTION_SHADE;
1270 case ECORE_X_ACTION_STICK:
1271 return ECORE_X_ATOM_NET_WM_ACTION_STICK;
1273 case ECORE_X_ACTION_MAXIMIZE_HORZ:
1274 return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
1276 case ECORE_X_ACTION_MAXIMIZE_VERT:
1277 return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
1279 case ECORE_X_ACTION_FULLSCREEN:
1280 return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
1282 case ECORE_X_ACTION_CHANGE_DESKTOP:
1283 return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
1285 case ECORE_X_ACTION_CLOSE:
1286 return ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
1288 case ECORE_X_ACTION_ABOVE:
1289 return ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
1291 case ECORE_X_ACTION_BELOW:
1292 return ECORE_X_ATOM_NET_WM_ACTION_BELOW;
1299 /* FIXME: Get complete list */
1301 ecore_x_netwm_allowed_action_isset(Ecore_X_Window win,
1302 Ecore_X_Action action)
1305 Ecore_X_Atom *atoms, atom;
1306 Eina_Bool ret = EINA_FALSE;
1308 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1309 num = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1314 atom = _ecore_x_netwm_action_atom_get(action);
1316 for (i = 0; i < num; ++i)
1318 if (atom == atoms[i])
1329 /* FIXME: Set complete list */
1331 ecore_x_netwm_allowed_action_set(Ecore_X_Window win,
1332 Ecore_X_Action *action,
1338 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1341 ecore_x_window_prop_property_del(win,
1342 ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS);
1346 set = malloc(num * sizeof(Ecore_X_Atom));
1350 for (i = 0; i < num; i++)
1351 set[i] = _ecore_x_netwm_action_atom_get(action[i]);
1353 ecore_x_window_prop_atom_set(win,
1354 ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
1362 ecore_x_netwm_allowed_action_get(Ecore_X_Window win,
1363 Ecore_X_Action **action,
1367 Ecore_X_Atom *atoms;
1369 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1376 num_ret = ecore_x_window_prop_atom_list_get(
1378 ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
1385 *action = malloc(num_ret * sizeof(Ecore_X_Action));
1387 for (i = 0; i < num_ret; ++i)
1388 (*action)[i] = _ecore_x_netwm_action_atom_get(atoms[i]);
1399 ecore_x_netwm_opacity_set(Ecore_X_Window win,
1400 unsigned int opacity)
1402 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1403 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
1408 ecore_x_netwm_opacity_get(Ecore_X_Window win,
1409 unsigned int *opacity)
1414 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1415 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
1420 return ret == 1 ? EINA_TRUE : EINA_FALSE;
1424 ecore_x_netwm_frame_size_set(Ecore_X_Window win,
1430 unsigned int frames[4];
1432 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1437 ecore_x_window_prop_card32_set(win,
1438 ECORE_X_ATOM_NET_FRAME_EXTENTS,
1444 ecore_x_netwm_frame_size_get(Ecore_X_Window win,
1451 unsigned int frames[4];
1453 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1454 ret = ecore_x_window_prop_card32_get(win,
1455 ECORE_X_ATOM_NET_FRAME_EXTENTS,
1477 ecore_x_netwm_sync_counter_get(Ecore_X_Window win,
1478 Ecore_X_Sync_Counter *counter)
1483 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1484 ret = ecore_x_window_prop_card32_get(
1486 ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
1493 return ret == 1 ? EINA_TRUE : EINA_FALSE;
1497 ecore_x_netwm_ping_send(Ecore_X_Window win)
1504 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1505 xev.xclient.type = ClientMessage;
1506 xev.xclient.display = _ecore_x_disp;
1507 xev.xclient.window = win;
1508 xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
1509 xev.xclient.format = 32;
1510 xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_PING;
1511 xev.xclient.data.l[1] = _ecore_x_event_last_time;
1512 xev.xclient.data.l[2] = win;
1513 xev.xclient.data.l[3] = 0;
1514 xev.xclient.data.l[4] = 0;
1516 XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
1520 ecore_x_netwm_sync_request_send(Ecore_X_Window win,
1521 unsigned int serial)
1529 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1530 XSyncIntToValue(&value, (int)serial);
1532 xev.xclient.type = ClientMessage;
1533 xev.xclient.display = _ecore_x_disp;
1534 xev.xclient.window = win;
1535 xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
1536 xev.xclient.format = 32;
1537 xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
1538 xev.xclient.data.l[1] = _ecore_x_event_last_time;
1539 xev.xclient.data.l[2] = XSyncValueLow32(value);
1540 xev.xclient.data.l[3] = XSyncValueHigh32(value);
1541 xev.xclient.data.l[4] = 0;
1543 XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
1547 ecore_x_netwm_state_request_send(Ecore_X_Window win,
1548 Ecore_X_Window root,
1549 Ecore_X_Window_State s1,
1550 Ecore_X_Window_State s2,
1558 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1560 root = DefaultRootWindow(_ecore_x_disp);
1562 xev.xclient.type = ClientMessage;
1563 xev.xclient.serial = 0;
1564 xev.xclient.send_event = True;
1565 xev.xclient.display = _ecore_x_disp;
1566 xev.xclient.window = win;
1567 xev.xclient.format = 32;
1568 xev.xclient.message_type = ECORE_X_ATOM_NET_WM_STATE;
1569 xev.xclient.data.l[0] = !!set;
1570 xev.xclient.data.l[1] = _ecore_x_netwm_state_atom_get(s1);
1571 xev.xclient.data.l[2] = _ecore_x_netwm_state_atom_get(s2);
1572 /* 1 == normal client, if someone wants to use this
1573 * function in a pager, this should be 2 */
1574 xev.xclient.data.l[3] = 1;
1575 xev.xclient.data.l[4] = 0;
1577 XSendEvent(_ecore_x_disp, root, False,
1578 SubstructureNotifyMask | SubstructureRedirectMask, &xev);
1582 ecore_x_netwm_desktop_request_send(Ecore_X_Window win,
1583 Ecore_X_Window root,
1584 unsigned int desktop)
1591 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1593 root = DefaultRootWindow(_ecore_x_disp);
1595 xev.xclient.type = ClientMessage;
1596 xev.xclient.serial = 0;
1597 xev.xclient.send_event = True;
1598 xev.xclient.display = _ecore_x_disp;
1599 xev.xclient.window = win;
1600 xev.xclient.format = 32;
1601 xev.xclient.message_type = ECORE_X_ATOM_NET_WM_DESKTOP;
1602 xev.xclient.data.l[0] = desktop;
1604 XSendEvent(_ecore_x_disp, root, False,
1605 SubstructureNotifyMask | SubstructureRedirectMask, &xev);
1609 ecore_x_netwm_moveresize_request_send(Ecore_X_Window win,
1612 Ecore_X_Netwm_Direction direction,
1613 unsigned int button)
1620 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1621 xev.xclient.window = win;
1622 xev.xclient.type = ClientMessage;
1623 xev.xclient.message_type = ECORE_X_ATOM_NET_WM_MOVERESIZE;
1624 xev.xclient.format = 32;
1625 xev.xclient.data.l[0] = x;
1626 xev.xclient.data.l[1] = y;
1627 xev.xclient.data.l[2] = direction;
1628 xev.xclient.data.l[3] = button;
1629 xev.xclient.data.l[4] = 1;
1631 XSendEvent(_ecore_x_disp, win, False,
1632 SubstructureNotifyMask | SubstructureRedirectMask, &xev);
1636 _ecore_x_netwm_startup_info_begin(Ecore_X_Window win __UNUSED__,
1637 char *data __UNUSED__)
1640 Ecore_X_Startup_Info *info;
1641 unsigned char *exists = 0;
1646 info = eina_hash_find(startup_info, (void *)win);
1650 WRN("Already got info for win: 0x%x", win);
1651 _ecore_x_netwm_startup_info_free(info);
1654 info = calloc(1, sizeof(Ecore_X_Startup_Info));
1660 info->buffer_size = 161;
1661 info->buffer = calloc(info->buffer_size, sizeof(char));
1664 _ecore_x_netwm_startup_info_free(info);
1668 memcpy(info->buffer, data, 20);
1670 info->buffer[info->length] = 0;
1672 eina_hash_modify(startup_info, (void *)info->win, info);
1674 eina_hash_add(startup_info, (void *)info->win, info);
1676 if (strlen(info->buffer) != 20)
1677 /* We have a '\0' in there, the message is done */
1678 _ecore_x_netwm_startup_info_process(info);
1685 _ecore_x_netwm_startup_info(Ecore_X_Window win __UNUSED__,
1686 char *data __UNUSED__)
1689 Ecore_X_Startup_Info *info;
1695 info = eina_hash_find(startup_info, (void *)win);
1699 if ((info->length + 20) > info->buffer_size)
1701 info->buffer_size += 160;
1702 info->buffer = realloc(info->buffer, info->buffer_size * sizeof(char));
1705 eina_hash_del(startup_info, (void *)info->win);
1706 _ecore_x_netwm_startup_info_free(info);
1711 memcpy(info->buffer + info->length, data, 20);
1712 p = info->buffer + info->length;
1714 info->buffer[info->length] = 0;
1715 if (strlen(p) != 20)
1716 /* We have a '\0' in there, the message is done */
1717 _ecore_x_netwm_startup_info_process(info);
1724 * Set UTF-8 string property
1727 _ecore_x_window_prop_string_utf8_set(Ecore_X_Window win,
1731 XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8,
1732 PropModeReplace, (unsigned char *)str, strlen(str));
1736 * Get UTF-8 string property
1739 _ecore_x_window_prop_string_utf8_get(Ecore_X_Window win,
1743 unsigned char *prop_ret;
1745 unsigned long bytes_after, num_ret;
1750 XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
1751 ECORE_X_ATOM_UTF8_STRING, &type_ret,
1752 &format_ret, &num_ret, &bytes_after, &prop_ret);
1753 if (prop_ret && num_ret > 0 && format_ret == 8)
1755 str = malloc(num_ret + 1);
1758 memcpy(str, prop_ret, num_ret);
1759 str[num_ret] = '\0';
1771 * Process startup info
1774 _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info)
1776 Ecore_X_Event_Startup_Sequence *e;
1780 p = strchr(info->buffer, ':');
1783 eina_hash_del(startup_info, (void *)info->win);
1784 _ecore_x_netwm_startup_info_free(info);
1789 if (!strcmp(info->buffer, "new"))
1792 event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
1794 event = ECORE_X_EVENT_STARTUP_SEQUENCE_NEW;
1798 else if (!strcmp(info->buffer, "change"))
1799 event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
1800 else if (!strcmp(info->buffer, "remove"))
1801 event = ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE;
1804 eina_hash_del(startup_info, (void *)info->win);
1805 _ecore_x_netwm_startup_info_free(info);
1811 if (!_ecore_x_netwm_startup_info_parse(info, p))
1813 eina_hash_del(startup_info, (void *)info->win);
1814 _ecore_x_netwm_startup_info_free(info);
1820 e = calloc(1, sizeof(Ecore_X_Event_Startup_Sequence));
1823 eina_hash_del(startup_info, (void *)info->win);
1824 _ecore_x_netwm_startup_info_free(info);
1829 ecore_event_add(event, e, NULL, NULL);
1832 if (event == ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE)
1834 eina_hash_del(startup_info, (void *)info->win);
1835 _ecore_x_netwm_startup_info_free(info);
1839 /* Discard buffer */
1841 info->buffer[0] = 0;
1848 * Parse startup info
1851 _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info,
1856 int in_quot_sing, in_quot_dbl, escaped;
1862 while (*data == ' ')
1866 data = strchr(key, '=');
1881 if ((pp - value) >= 1024)
1890 else if (in_quot_sing)
1894 else if (*p == '\'')
1902 else if (in_quot_dbl)
1906 else if (*p == '\"')
1918 else if (*p == '\'')
1920 else if (*p == '\"')
1933 if ((in_quot_dbl) || (in_quot_sing))
1940 if (!strcmp(key, "ID"))
1942 if ((info->id) && (strcmp(info->id, value)))
1945 info->id = strdup(value);
1946 p = strstr(value, "_TIME");
1948 info->timestamp = atoi(p + 5);
1950 else if (!strcmp(key, "NAME"))
1955 info->name = strdup(value);
1957 else if (!strcmp(key, "SCREEN"))
1958 info->screen = atoi(value);
1959 else if (!strcmp(key, "BIN"))
1964 info->bin = strdup(value);
1966 else if (!strcmp(key, "ICON"))
1971 info->icon = strdup(value);
1973 else if (!strcmp(key, "DESKTOP"))
1974 info->desktop = atoi(value);
1975 else if (!strcmp(key, "TIMESTAMP"))
1977 if (!info->timestamp)
1978 info->timestamp = atoi(value);
1980 else if (!strcmp(key, "DESCRIPTION"))
1982 if (info->description)
1983 free(info->description);
1985 info->description = strdup(value);
1987 else if (!strcmp(key, "WMCLASS"))
1990 free(info->wmclass);
1992 info->wmclass = strdup(value);
1994 else if (!strcmp(key, "SILENT"))
1995 info->silent = atoi(value);
1997 ERR("Ecore X Sequence, Unknown: %s=%s", key, value);
2008 * Free startup info struct
2011 _ecore_x_netwm_startup_info_free(void *data)
2013 Ecore_X_Startup_Info *info;
2034 if (info->description)
2035 free(info->description);
2038 free(info->wmclass);
2044 * Is screen composited?
2047 ecore_x_screen_is_composited(int screen)
2050 static Ecore_X_Atom atom = None;
2053 LOGFN(__FILE__, __LINE__, __FUNCTION__);
2054 snprintf(buf, sizeof(buf), "_NET_WM_CM_S%i", screen);
2056 atom = XInternAtom(_ecore_x_disp, buf, False);
2061 win = XGetSelectionOwner(_ecore_x_disp, atom);
2063 return (win != None) ? EINA_TRUE : EINA_FALSE;
2067 ecore_x_screen_is_composited_set(int screen,
2070 static Ecore_X_Atom atom = None;
2073 LOGFN(__FILE__, __LINE__, __FUNCTION__);
2074 snprintf(buf, sizeof(buf), "_NET_WM_CM_S%i", screen);
2076 atom = XInternAtom(_ecore_x_disp, buf, False);
2081 XSetSelectionOwner(_ecore_x_disp, atom, win, _ecore_x_event_last_time);