2 * _NET_WM... aka Extended Window Manager Hint (EWMH) functions.
7 #endif /* ifdef HAVE_CONFIG_H */
13 #include "ecore_x_private.h"
16 typedef struct _Ecore_X_Startup_Info Ecore_X_Startup_Info;
18 struct _Ecore_X_Startup_Info
29 /* These are the sequence info fields */
42 static void _ecore_x_window_prop_string_utf8_set(Ecore_X_Window win,
45 static char * _ecore_x_window_prop_string_utf8_get(Ecore_X_Window win,
48 static int _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info);
49 static int _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info,
52 static void _ecore_x_netwm_startup_info_free(void *data);
57 #define _ATOM_SET_UTF8_STRING_LIST(win, atom, string, cnt)\
58 XChangeProperty(_ecore_x_disp,\
61 ECORE_X_ATOM_UTF8_STRING,\
64 (unsigned char *)string,\
71 static Eina_Hash *startup_info = NULL;
74 ecore_x_netwm_init(void)
76 LOGFN(__FILE__, __LINE__, __FUNCTION__);
77 startup_info = eina_hash_string_superfast_new(
78 _ecore_x_netwm_startup_info_free);
79 } /* ecore_x_netwm_init */
82 ecore_x_netwm_shutdown(void)
84 LOGFN(__FILE__, __LINE__, __FUNCTION__);
86 eina_hash_free(startup_info);
89 } /* ecore_x_netwm_shutdown */
95 ecore_x_netwm_wm_identify(Ecore_X_Window root, Ecore_X_Window check,
98 LOGFN(__FILE__, __LINE__, __FUNCTION__);
99 ecore_x_window_prop_window_set(root,
100 ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK,
103 ecore_x_window_prop_window_set(check,
104 ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK,
107 _ecore_x_window_prop_string_utf8_set(check,
108 ECORE_X_ATOM_NET_WM_NAME,
110 /* This one isn't mandatory */
111 _ecore_x_window_prop_string_utf8_set(root,
112 ECORE_X_ATOM_NET_WM_NAME,
114 } /* ecore_x_netwm_wm_identify */
117 * Set supported atoms
120 ecore_x_netwm_supported_set(Ecore_X_Window root,
121 Ecore_X_Atom *supported,
124 LOGFN(__FILE__, __LINE__, __FUNCTION__);
125 ecore_x_window_prop_atom_set(root,
126 ECORE_X_ATOM_NET_SUPPORTED,
129 } /* ecore_x_netwm_supported_set */
132 ecore_x_netwm_supported_get(Ecore_X_Window root,
133 Ecore_X_Atom **supported,
144 LOGFN(__FILE__, __LINE__, __FUNCTION__);
145 num_ret = ecore_x_window_prop_atom_list_get(root, ECORE_X_ATOM_NET_SUPPORTED,
154 } /* ecore_x_netwm_supported_get */
157 * Desktop configuration and status
160 ecore_x_netwm_desk_count_set(Ecore_X_Window root, unsigned int n_desks)
162 LOGFN(__FILE__, __LINE__, __FUNCTION__);
163 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS,
165 } /* ecore_x_netwm_desk_count_set */
168 ecore_x_netwm_desk_roots_set(Ecore_X_Window root,
169 Ecore_X_Window *vroots, unsigned int n_desks)
171 LOGFN(__FILE__, __LINE__, __FUNCTION__);
172 ecore_x_window_prop_window_set(root,
173 ECORE_X_ATOM_NET_VIRTUAL_ROOTS,
176 } /* ecore_x_netwm_desk_roots_set */
179 ecore_x_netwm_desk_names_set(Ecore_X_Window root,
180 const char **names, unsigned int n_desks)
187 LOGFN(__FILE__, __LINE__, __FUNCTION__);
191 for (i = 0; i < n_desks; i++)
193 s = (names) ? names[i] : NULL;
196 /* Default to "Desk-<number>" */
197 sprintf(ss, "Desk-%d", i);
202 buf = realloc(buf, len + l);
203 memcpy(buf + len, s, l);
207 _ATOM_SET_UTF8_STRING_LIST(root, ECORE_X_ATOM_NET_DESKTOP_NAMES, buf, len);
210 } /* ecore_x_netwm_desk_names_set */
213 ecore_x_netwm_desk_size_set(Ecore_X_Window root, unsigned int width,
216 unsigned int size[2];
218 LOGFN(__FILE__, __LINE__, __FUNCTION__);
221 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_GEOMETRY, size,
223 } /* ecore_x_netwm_desk_size_set */
226 ecore_x_netwm_desk_viewports_set(Ecore_X_Window root,
227 unsigned int *origins, unsigned int n_desks)
229 LOGFN(__FILE__, __LINE__, __FUNCTION__);
230 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_VIEWPORT,
231 origins, 2 * n_desks);
232 } /* ecore_x_netwm_desk_viewports_set */
235 ecore_x_netwm_desk_layout_set(Ecore_X_Window root, int orientation,
236 int columns, int rows,
239 unsigned int layout[4];
241 LOGFN(__FILE__, __LINE__, __FUNCTION__);
242 layout[0] = orientation;
245 layout[3] = starting_corner;
246 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT,
248 } /* ecore_x_netwm_desk_layout_set */
251 ecore_x_netwm_desk_workareas_set(Ecore_X_Window root,
252 unsigned int *areas, unsigned int n_desks)
254 LOGFN(__FILE__, __LINE__, __FUNCTION__);
255 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_WORKAREA, areas,
257 } /* ecore_x_netwm_desk_workareas_set */
260 ecore_x_netwm_desk_current_set(Ecore_X_Window root, unsigned int desk)
262 LOGFN(__FILE__, __LINE__, __FUNCTION__);
263 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_CURRENT_DESKTOP, &desk,
265 } /* ecore_x_netwm_desk_current_set */
268 ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, int on)
272 LOGFN(__FILE__, __LINE__, __FUNCTION__);
274 ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, &val,
276 } /* ecore_x_netwm_showing_desktop_set */
284 ecore_x_netwm_client_list_set(Ecore_X_Window root,
285 Ecore_X_Window *p_clients, unsigned int n_clients)
287 LOGFN(__FILE__, __LINE__, __FUNCTION__);
288 ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST,
289 p_clients, n_clients);
290 } /* ecore_x_netwm_client_list_set */
294 ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root,
295 Ecore_X_Window *p_clients,
296 unsigned int n_clients)
298 LOGFN(__FILE__, __LINE__, __FUNCTION__);
299 ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_CLIENT_LIST_STACKING,
300 p_clients, n_clients);
301 } /* ecore_x_netwm_client_list_stacking_set */
304 ecore_x_netwm_client_active_set(Ecore_X_Window root, Ecore_X_Window win)
306 LOGFN(__FILE__, __LINE__, __FUNCTION__);
307 ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_ACTIVE_WINDOW,
309 } /* ecore_x_netwm_client_active_set */
312 ecore_x_netwm_client_active_request(Ecore_X_Window root,
315 Ecore_X_Window current_win)
319 LOGFN(__FILE__, __LINE__, __FUNCTION__);
321 root = DefaultRootWindow(_ecore_x_disp);
323 xev.xclient.type = ClientMessage;
324 xev.xclient.display = _ecore_x_disp;
325 xev.xclient.window = win;
326 xev.xclient.message_type = ECORE_X_ATOM_NET_ACTIVE_WINDOW;
327 xev.xclient.format = 32;
328 xev.xclient.data.l[0] = type;
329 xev.xclient.data.l[1] = CurrentTime;
330 xev.xclient.data.l[2] = current_win;
331 xev.xclient.data.l[3] = 0;
332 xev.xclient.data.l[4] = 0;
334 XSendEvent(_ecore_x_disp, root, False,
335 SubstructureRedirectMask | SubstructureNotifyMask, &xev);
336 } /* ecore_x_netwm_client_active_request */
339 ecore_x_netwm_name_set(Ecore_X_Window win, const char *name)
341 LOGFN(__FILE__, __LINE__, __FUNCTION__);
342 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_NAME, name);
343 } /* ecore_x_netwm_name_set */
346 ecore_x_netwm_name_get(Ecore_X_Window win, char **name)
348 LOGFN(__FILE__, __LINE__, __FUNCTION__);
350 *name = _ecore_x_window_prop_string_utf8_get(win,
351 ECORE_X_ATOM_NET_WM_NAME);
354 } /* ecore_x_netwm_name_get */
357 ecore_x_netwm_startup_id_set(Ecore_X_Window win, const char *id)
359 LOGFN(__FILE__, __LINE__, __FUNCTION__);
360 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_STARTUP_ID, id);
361 } /* ecore_x_netwm_startup_id_set */
364 ecore_x_netwm_startup_id_get(Ecore_X_Window win, char **id)
366 LOGFN(__FILE__, __LINE__, __FUNCTION__);
368 *id = _ecore_x_window_prop_string_utf8_get(win,
369 ECORE_X_ATOM_NET_STARTUP_ID);
372 } /* ecore_x_netwm_startup_id_get */
375 ecore_x_netwm_visible_name_set(Ecore_X_Window win, const char *name)
377 LOGFN(__FILE__, __LINE__, __FUNCTION__);
378 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
380 } /* ecore_x_netwm_visible_name_set */
383 ecore_x_netwm_visible_name_get(Ecore_X_Window win, char **name)
385 LOGFN(__FILE__, __LINE__, __FUNCTION__);
387 *name = _ecore_x_window_prop_string_utf8_get(
389 ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
392 } /* ecore_x_netwm_visible_name_get */
395 ecore_x_netwm_icon_name_set(Ecore_X_Window win, const char *name)
397 LOGFN(__FILE__, __LINE__, __FUNCTION__);
398 _ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME,
400 } /* ecore_x_netwm_icon_name_set */
403 ecore_x_netwm_icon_name_get(Ecore_X_Window win, char **name)
405 LOGFN(__FILE__, __LINE__, __FUNCTION__);
407 *name = _ecore_x_window_prop_string_utf8_get(
409 ECORE_X_ATOM_NET_WM_ICON_NAME);
412 } /* ecore_x_netwm_icon_name_get */
415 ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win, const char *name)
417 LOGFN(__FILE__, __LINE__, __FUNCTION__);
418 _ecore_x_window_prop_string_utf8_set(win,
419 ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
421 } /* ecore_x_netwm_visible_icon_name_set */
424 ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win, char **name)
426 LOGFN(__FILE__, __LINE__, __FUNCTION__);
428 *name = _ecore_x_window_prop_string_utf8_get(
430 ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
433 } /* ecore_x_netwm_visible_icon_name_get */
436 ecore_x_netwm_desktop_set(Ecore_X_Window win, unsigned int desk)
438 LOGFN(__FILE__, __LINE__, __FUNCTION__);
439 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
440 } /* ecore_x_netwm_desktop_set */
443 ecore_x_netwm_desktop_get(Ecore_X_Window win, unsigned int *desk)
448 LOGFN(__FILE__, __LINE__, __FUNCTION__);
449 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP,
455 return ret == 1 ? 1 : 0;
456 } /* ecore_x_netwm_desktop_get */
459 * _NET_WM_STRUT is deprecated
462 ecore_x_netwm_strut_set(Ecore_X_Window win, int left, int right,
465 unsigned int strut[4];
467 LOGFN(__FILE__, __LINE__, __FUNCTION__);
472 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
473 } /* ecore_x_netwm_strut_set */
476 * _NET_WM_STRUT is deprecated
479 ecore_x_netwm_strut_get(Ecore_X_Window win, int *left, int *right,
480 int *top, int *bottom)
483 unsigned int strut[4];
485 LOGFN(__FILE__, __LINE__, __FUNCTION__);
486 ret = ecore_x_window_prop_card32_get(win,
487 ECORE_X_ATOM_NET_WM_STRUT,
506 } /* ecore_x_netwm_strut_get */
509 ecore_x_netwm_strut_partial_set(Ecore_X_Window win,
523 unsigned int strut[12];
525 LOGFN(__FILE__, __LINE__, __FUNCTION__);
530 strut[4] = left_start_y;
531 strut[5] = left_end_y;
532 strut[6] = right_start_y;
533 strut[7] = right_end_y;
534 strut[8] = top_start_x;
535 strut[9] = top_end_x;
536 strut[10] = bottom_start_x;
537 strut[11] = bottom_end_x;
538 ecore_x_window_prop_card32_set(win,
539 ECORE_X_ATOM_NET_WM_STRUT_PARTIAL,
542 } /* ecore_x_netwm_strut_partial_set */
545 ecore_x_netwm_strut_partial_get(Ecore_X_Window win,
560 unsigned int strut[12];
562 LOGFN(__FILE__, __LINE__, __FUNCTION__);
563 ret = ecore_x_window_prop_card32_get(win,
564 ECORE_X_ATOM_NET_WM_STRUT_PARTIAL,
583 *left_start_y = strut[4];
586 *left_end_y = strut[5];
589 *right_start_y = strut[6];
592 *right_end_y = strut[7];
595 *top_start_x = strut[8];
598 *top_end_x = strut[9];
601 *bottom_start_x = strut[10];
604 *bottom_end_x = strut[11];
607 } /* ecore_x_netwm_strut_partial_get */
610 ecore_x_netwm_icons_get(Ecore_X_Window win, Ecore_X_Icon **icon, int *num)
612 unsigned int *data, *p;
614 unsigned int len, icons, i;
617 LOGFN(__FILE__, __LINE__, __FUNCTION__);
624 num_ret = ecore_x_window_prop_card32_list_get(win, ECORE_X_ATOM_NET_WM_ICON,
638 /* Check how many icons there are */
645 if ((p - data) > num_ret)
653 if ((p - data) == num_ret)
659 /* If the user doesn't want the icons, return */
666 /* Allocate memory */
667 *icon = malloc(icons * sizeof(Ecore_X_Icon));
674 /* Fetch the icons */
676 for (i = 0; i < icons; i++)
678 unsigned int *ps, *pd, *pe;
681 ((*icon)[i]).width = p[0];
682 ((*icon)[i]).height = p[1];
684 ((*icon)[i]).data = malloc(len * sizeof(unsigned int));
685 if (!((*icon)[i]).data)
688 free(((*icon)[--i]).data);
694 pd = ((*icon)[i]).data;
697 for (; ps < pe; ps++)
699 unsigned int r, g, b, a;
701 a = (*ps >> 24) & 0xff;
702 r = (((*ps >> 16) & 0xff) * a) / 255;
703 g = (((*ps >> 8) & 0xff) * a) / 255;
704 b = (((*ps) & 0xff) * a) / 255;
705 *pd = (a << 24) | (r << 16) | (g << 8) | (b);
714 } /* ecore_x_netwm_icons_get */
717 ecore_x_netwm_icon_geometry_set(Ecore_X_Window win,
723 unsigned int geometry[4];
725 LOGFN(__FILE__, __LINE__, __FUNCTION__);
729 geometry[3] = height;
730 ecore_x_window_prop_card32_set(win,
731 ECORE_X_ATOM_NET_WM_ICON_GEOMETRY,
734 } /* ecore_x_netwm_icon_geometry_set */
737 ecore_x_netwm_icon_geometry_get(Ecore_X_Window win,
744 unsigned int geometry[4];
746 LOGFN(__FILE__, __LINE__, __FUNCTION__);
747 ret = ecore_x_window_prop_card32_get(win,
748 ECORE_X_ATOM_NET_WM_ICON_GEOMETRY,
761 *width = geometry[2];
764 *height = geometry[3];
767 } /* ecore_x_netwm_icon_geometry_get */
770 ecore_x_netwm_pid_set(Ecore_X_Window win, int pid)
774 LOGFN(__FILE__, __LINE__, __FUNCTION__);
776 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_PID,
778 } /* ecore_x_netwm_pid_set */
781 ecore_x_netwm_pid_get(Ecore_X_Window win, int *pid)
786 LOGFN(__FILE__, __LINE__, __FUNCTION__);
787 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_PID,
792 return ret == 1 ? 1 : 0;
793 } /* ecore_x_netwm_pid_get */
796 ecore_x_netwm_handled_icons_set(Ecore_X_Window win)
798 LOGFN(__FILE__, __LINE__, __FUNCTION__);
799 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
801 } /* ecore_x_netwm_handled_icons_set */
804 ecore_x_netwm_handled_icons_get(Ecore_X_Window win)
807 LOGFN(__FILE__, __LINE__, __FUNCTION__);
808 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
810 return ret == 0 ? 1 : 0;
811 } /* ecore_x_netwm_handled_icons_get */
814 ecore_x_netwm_user_time_set(Ecore_X_Window win, unsigned int time)
816 LOGFN(__FILE__, __LINE__, __FUNCTION__);
817 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_USER_TIME,
819 } /* ecore_x_netwm_user_time_set */
822 ecore_x_netwm_user_time_get(Ecore_X_Window win, unsigned int *time)
827 LOGFN(__FILE__, __LINE__, __FUNCTION__);
828 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME,
833 return ret == 1 ? 1 : 0;
834 } /* ecore_x_netwm_user_time_get */
837 _ecore_x_netwm_state_get(Ecore_X_Atom a)
839 if (a == ECORE_X_ATOM_NET_WM_STATE_MODAL)
840 return ECORE_X_WINDOW_STATE_MODAL;
841 else if (a == ECORE_X_ATOM_NET_WM_STATE_STICKY)
842 return ECORE_X_WINDOW_STATE_STICKY;
843 else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
844 return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
845 else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
846 return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
847 else if (a == ECORE_X_ATOM_NET_WM_STATE_SHADED)
848 return ECORE_X_WINDOW_STATE_SHADED;
849 else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
850 return ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
851 else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
852 return ECORE_X_WINDOW_STATE_SKIP_PAGER;
853 else if (a == ECORE_X_ATOM_NET_WM_STATE_HIDDEN)
854 return ECORE_X_WINDOW_STATE_HIDDEN;
855 else if (a == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
856 return ECORE_X_WINDOW_STATE_FULLSCREEN;
857 else if (a == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
858 return ECORE_X_WINDOW_STATE_ABOVE;
859 else if (a == ECORE_X_ATOM_NET_WM_STATE_BELOW)
860 return ECORE_X_WINDOW_STATE_BELOW;
861 else if (a == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
862 return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION;
864 return ECORE_X_WINDOW_STATE_UNKNOWN;
865 } /* _ecore_x_netwm_state_get */
868 _ecore_x_netwm_state_atom_get(Ecore_X_Window_State s)
872 case ECORE_X_WINDOW_STATE_MODAL:
873 return ECORE_X_ATOM_NET_WM_STATE_MODAL;
875 case ECORE_X_WINDOW_STATE_STICKY:
876 return ECORE_X_ATOM_NET_WM_STATE_STICKY;
878 case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
879 return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT;
881 case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
882 return ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ;
884 case ECORE_X_WINDOW_STATE_SHADED:
885 return ECORE_X_ATOM_NET_WM_STATE_SHADED;
887 case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
888 return ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR;
890 case ECORE_X_WINDOW_STATE_SKIP_PAGER:
891 return ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER;
893 case ECORE_X_WINDOW_STATE_HIDDEN:
894 return ECORE_X_ATOM_NET_WM_STATE_HIDDEN;
896 case ECORE_X_WINDOW_STATE_FULLSCREEN:
897 return ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN;
899 case ECORE_X_WINDOW_STATE_ABOVE:
900 return ECORE_X_ATOM_NET_WM_STATE_ABOVE;
902 case ECORE_X_WINDOW_STATE_BELOW:
903 return ECORE_X_ATOM_NET_WM_STATE_BELOW;
905 case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION:
906 return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
911 } /* _ecore_x_netwm_state_atom_get */
914 ecore_x_netwm_window_state_set(Ecore_X_Window win,
915 Ecore_X_Window_State *state,
921 LOGFN(__FILE__, __LINE__, __FUNCTION__);
924 ecore_x_window_prop_property_del(win, ECORE_X_ATOM_NET_WM_STATE);
928 set = malloc(num * sizeof(Ecore_X_Atom));
932 for (i = 0; i < num; i++)
933 set[i] = _ecore_x_netwm_state_atom_get(state[i]);
935 ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_STATE, set, num);
938 } /* ecore_x_netwm_window_state_set */
941 ecore_x_netwm_window_state_get(Ecore_X_Window win,
942 Ecore_X_Window_State **state,
948 LOGFN(__FILE__, __LINE__, __FUNCTION__);
955 num_ret = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_STATE,
962 *state = malloc(num_ret * sizeof(Ecore_X_Window_State));
964 for (i = 0; i < num_ret; ++i)
965 (*state)[i] = _ecore_x_netwm_state_get(atoms[i]);
973 } /* ecore_x_netwm_window_state_get */
975 static Ecore_X_Window_Type
976 _ecore_x_netwm_window_type_type_get(Ecore_X_Atom atom)
978 if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP)
979 return ECORE_X_WINDOW_TYPE_DESKTOP;
980 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK)
981 return ECORE_X_WINDOW_TYPE_DOCK;
982 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR)
983 return ECORE_X_WINDOW_TYPE_TOOLBAR;
984 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU)
985 return ECORE_X_WINDOW_TYPE_MENU;
986 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY)
987 return ECORE_X_WINDOW_TYPE_UTILITY;
988 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH)
989 return ECORE_X_WINDOW_TYPE_SPLASH;
990 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG)
991 return ECORE_X_WINDOW_TYPE_DIALOG;
992 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL)
993 return ECORE_X_WINDOW_TYPE_NORMAL;
994 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
995 return ECORE_X_WINDOW_TYPE_DROPDOWN_MENU;
996 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU)
997 return ECORE_X_WINDOW_TYPE_POPUP_MENU;
998 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP)
999 return ECORE_X_WINDOW_TYPE_TOOLTIP;
1000 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION)
1001 return ECORE_X_WINDOW_TYPE_NOTIFICATION;
1002 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO)
1003 return ECORE_X_WINDOW_TYPE_COMBO;
1004 else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND)
1005 return ECORE_X_WINDOW_TYPE_DND;
1007 return ECORE_X_WINDOW_TYPE_UNKNOWN;
1008 } /* _ecore_x_netwm_window_type_type_get */
1011 _ecore_x_netwm_window_type_atom_get(Ecore_X_Window_Type type)
1015 case ECORE_X_WINDOW_TYPE_DESKTOP:
1016 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP;
1018 case ECORE_X_WINDOW_TYPE_DOCK:
1019 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK;
1021 case ECORE_X_WINDOW_TYPE_TOOLBAR:
1022 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR;
1024 case ECORE_X_WINDOW_TYPE_MENU:
1025 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU;
1027 case ECORE_X_WINDOW_TYPE_UTILITY:
1028 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY;
1030 case ECORE_X_WINDOW_TYPE_SPLASH:
1031 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH;
1033 case ECORE_X_WINDOW_TYPE_DIALOG:
1034 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG;
1036 case ECORE_X_WINDOW_TYPE_NORMAL:
1037 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL;
1039 case ECORE_X_WINDOW_TYPE_DROPDOWN_MENU:
1040 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DROPDOWN_MENU;
1042 case ECORE_X_WINDOW_TYPE_POPUP_MENU:
1043 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_POPUP_MENU;
1045 case ECORE_X_WINDOW_TYPE_TOOLTIP:
1046 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLTIP;
1048 case ECORE_X_WINDOW_TYPE_NOTIFICATION:
1049 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NOTIFICATION;
1051 case ECORE_X_WINDOW_TYPE_COMBO:
1052 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_COMBO;
1054 case ECORE_X_WINDOW_TYPE_DND:
1055 return ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DND;
1060 } /* _ecore_x_netwm_window_type_atom_get */
1063 * FIXME: We should set WM_TRANSIENT_FOR if type is ECORE_X_WINDOW_TYPE_TOOLBAR
1064 * , ECORE_X_WINDOW_TYPE_MENU or ECORE_X_WINDOW_TYPE_DIALOG
1067 ecore_x_netwm_window_type_set(Ecore_X_Window win, Ecore_X_Window_Type type)
1071 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1072 atom = _ecore_x_netwm_window_type_atom_get(type);
1073 ecore_x_window_prop_atom_set(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1075 } /* ecore_x_netwm_window_type_set */
1077 /* FIXME: Maybe return 0 on some conditions? */
1079 ecore_x_netwm_window_type_get(Ecore_X_Window win, Ecore_X_Window_Type *type)
1082 Ecore_X_Atom *atoms = NULL;
1084 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1086 *type = ECORE_X_WINDOW_TYPE_NORMAL;
1088 num = ecore_x_window_prop_atom_list_get(win,
1089 ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1091 if ((type) && (num >= 1) && (atoms))
1092 *type = _ecore_x_netwm_window_type_type_get(atoms[0]);
1099 } /* ecore_x_netwm_window_type_get */
1102 ecore_x_netwm_window_types_get(Ecore_X_Window win, Ecore_X_Window_Type **types)
1105 Ecore_X_Atom *atoms = NULL;
1106 Ecore_X_Window_Type *atoms2 = NULL;
1108 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1112 num = ecore_x_window_prop_atom_list_get(win,
1113 ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1115 if ((num <= 0) || (!atoms))
1123 atoms2 = malloc(num * sizeof(Ecore_X_Window_Type));
1127 for (i = 0; i < num; i++)
1128 atoms2[i] = _ecore_x_netwm_window_type_type_get(atoms[i]);
1136 } /* ecore_x_netwm_window_types_get */
1139 _ecore_x_netwm_action_atom_get(Ecore_X_Action action)
1143 case ECORE_X_ACTION_MOVE:
1144 return ECORE_X_ATOM_NET_WM_ACTION_MOVE;
1146 case ECORE_X_ACTION_RESIZE:
1147 return ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
1149 case ECORE_X_ACTION_MINIMIZE:
1150 return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
1152 case ECORE_X_ACTION_SHADE:
1153 return ECORE_X_ATOM_NET_WM_ACTION_SHADE;
1155 case ECORE_X_ACTION_STICK:
1156 return ECORE_X_ATOM_NET_WM_ACTION_STICK;
1158 case ECORE_X_ACTION_MAXIMIZE_HORZ:
1159 return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
1161 case ECORE_X_ACTION_MAXIMIZE_VERT:
1162 return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
1164 case ECORE_X_ACTION_FULLSCREEN:
1165 return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
1167 case ECORE_X_ACTION_CHANGE_DESKTOP:
1168 return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
1170 case ECORE_X_ACTION_CLOSE:
1171 return ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
1173 case ECORE_X_ACTION_ABOVE:
1174 return ECORE_X_ATOM_NET_WM_ACTION_ABOVE;
1176 case ECORE_X_ACTION_BELOW:
1177 return ECORE_X_ATOM_NET_WM_ACTION_BELOW;
1182 } /* _ecore_x_netwm_action_atom_get */
1184 /* FIXME: Get complete list */
1186 ecore_x_netwm_allowed_action_isset(Ecore_X_Window win, Ecore_X_Action action)
1188 int num, i, ret = 0;
1189 Ecore_X_Atom *atoms, atom;
1191 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1192 num = ecore_x_window_prop_atom_list_get(win, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
1197 atom = _ecore_x_netwm_action_atom_get(action);
1199 for (i = 0; i < num; ++i)
1201 if (atom == atoms[i])
1210 } /* ecore_x_netwm_allowed_action_isset */
1212 /* FIXME: Set complete list */
1214 ecore_x_netwm_allowed_action_set(Ecore_X_Window win,
1215 Ecore_X_Action *action,
1221 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1224 ecore_x_window_prop_property_del(win,
1225 ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS);
1229 set = malloc(num * sizeof(Ecore_X_Atom));
1233 for (i = 0; i < num; i++)
1234 set[i] = _ecore_x_netwm_action_atom_get(action[i]);
1236 ecore_x_window_prop_atom_set(win,
1237 ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
1242 } /* ecore_x_netwm_allowed_action_set */
1245 ecore_x_netwm_allowed_action_get(Ecore_X_Window win,
1246 Ecore_X_Action **action,
1250 Ecore_X_Atom *atoms;
1252 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1259 num_ret = ecore_x_window_prop_atom_list_get(
1261 ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
1268 *action = malloc(num_ret * sizeof(Ecore_X_Action));
1270 for (i = 0; i < num_ret; ++i)
1271 (*action)[i] = _ecore_x_netwm_action_atom_get(atoms[i]);
1279 } /* ecore_x_netwm_allowed_action_get */
1282 ecore_x_netwm_opacity_set(Ecore_X_Window win, unsigned int opacity)
1284 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1285 ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
1287 } /* ecore_x_netwm_opacity_set */
1290 ecore_x_netwm_opacity_get(Ecore_X_Window win, unsigned int *opacity)
1295 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1296 ret = ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
1301 return ret == 1 ? 1 : 0;
1302 } /* ecore_x_netwm_opacity_get */
1305 ecore_x_netwm_frame_size_set(Ecore_X_Window win, int fl, int fr, int ft, int fb)
1307 unsigned int frames[4];
1309 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1314 ecore_x_window_prop_card32_set(win,
1315 ECORE_X_ATOM_NET_FRAME_EXTENTS,
1318 } /* ecore_x_netwm_frame_size_set */
1321 ecore_x_netwm_frame_size_get(Ecore_X_Window win,
1328 unsigned int frames[4];
1330 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1331 ret = ecore_x_window_prop_card32_get(win,
1332 ECORE_X_ATOM_NET_FRAME_EXTENTS,
1351 } /* ecore_x_netwm_frame_size_get */
1354 ecore_x_netwm_sync_counter_get(Ecore_X_Window win,
1355 Ecore_X_Sync_Counter *counter)
1360 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1361 ret = ecore_x_window_prop_card32_get(
1363 ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
1370 return ret == 1 ? 1 : 0;
1371 } /* ecore_x_netwm_sync_counter_get */
1374 ecore_x_netwm_ping_send(Ecore_X_Window win)
1381 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1382 xev.xclient.type = ClientMessage;
1383 xev.xclient.display = _ecore_x_disp;
1384 xev.xclient.window = win;
1385 xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
1386 xev.xclient.format = 32;
1387 xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_PING;
1388 xev.xclient.data.l[1] = _ecore_x_event_last_time;
1389 xev.xclient.data.l[2] = win;
1390 xev.xclient.data.l[3] = 0;
1391 xev.xclient.data.l[4] = 0;
1393 XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
1394 } /* ecore_x_netwm_ping_send */
1397 ecore_x_netwm_sync_request_send(Ecore_X_Window win, unsigned int serial)
1405 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1406 XSyncIntToValue(&value, (int)serial);
1408 xev.xclient.type = ClientMessage;
1409 xev.xclient.display = _ecore_x_disp;
1410 xev.xclient.window = win;
1411 xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
1412 xev.xclient.format = 32;
1413 xev.xclient.data.l[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
1414 xev.xclient.data.l[1] = _ecore_x_event_last_time;
1415 xev.xclient.data.l[2] = XSyncValueLow32(value);
1416 xev.xclient.data.l[3] = XSyncValueHigh32(value);
1417 xev.xclient.data.l[4] = 0;
1419 XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
1420 } /* ecore_x_netwm_sync_request_send */
1423 ecore_x_netwm_state_request_send(Ecore_X_Window win,
1424 Ecore_X_Window root,
1425 Ecore_X_Window_State s1,
1426 Ecore_X_Window_State s2,
1434 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1436 root = DefaultRootWindow(_ecore_x_disp);
1438 xev.xclient.type = ClientMessage;
1439 xev.xclient.serial = 0;
1440 xev.xclient.send_event = True;
1441 xev.xclient.display = _ecore_x_disp;
1442 xev.xclient.window = win;
1443 xev.xclient.format = 32;
1444 xev.xclient.message_type = ECORE_X_ATOM_NET_WM_STATE;
1445 xev.xclient.data.l[0] = !!set;
1446 xev.xclient.data.l[1] = _ecore_x_netwm_state_atom_get(s1);
1447 xev.xclient.data.l[2] = _ecore_x_netwm_state_atom_get(s2);
1448 /* 1 == normal client, if someone wants to use this
1449 * function in a pager, this should be 2 */
1450 xev.xclient.data.l[3] = 1;
1451 xev.xclient.data.l[4] = 0;
1453 XSendEvent(_ecore_x_disp, root, False,
1454 SubstructureNotifyMask | SubstructureRedirectMask, &xev);
1455 } /* ecore_x_netwm_state_request_send */
1458 ecore_x_netwm_desktop_request_send(Ecore_X_Window win,
1459 Ecore_X_Window root,
1460 unsigned int desktop)
1467 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1469 root = DefaultRootWindow(_ecore_x_disp);
1471 xev.xclient.type = ClientMessage;
1472 xev.xclient.serial = 0;
1473 xev.xclient.send_event = True;
1474 xev.xclient.display = _ecore_x_disp;
1475 xev.xclient.window = win;
1476 xev.xclient.format = 32;
1477 xev.xclient.message_type = ECORE_X_ATOM_NET_WM_DESKTOP;
1478 xev.xclient.data.l[0] = desktop;
1480 XSendEvent(_ecore_x_disp, root, False,
1481 SubstructureNotifyMask | SubstructureRedirectMask, &xev);
1482 } /* ecore_x_netwm_desktop_request_send */
1485 _ecore_x_netwm_startup_info_begin(Ecore_X_Window win __UNUSED__,
1486 char *data __UNUSED__)
1489 Ecore_X_Startup_Info *info;
1490 unsigned char *exists = 0;
1495 info = eina_hash_find(startup_info, (void *)win);
1499 WRN("Already got info for win: 0x%x", win);
1500 _ecore_x_netwm_startup_info_free(info);
1503 info = calloc(1, sizeof(Ecore_X_Startup_Info));
1509 info->buffer_size = 161;
1510 info->buffer = calloc(info->buffer_size, sizeof(char));
1513 _ecore_x_netwm_startup_info_free(info);
1517 memcpy(info->buffer, data, 20);
1519 info->buffer[info->length] = 0;
1521 eina_hash_modify(startup_info, (void *)info->win, info);
1523 eina_hash_add(startup_info, (void *)info->win, info);
1525 if (strlen(info->buffer) != 20)
1526 /* We have a '\0' in there, the message is done */
1527 _ecore_x_netwm_startup_info_process(info);
1531 } /* _ecore_x_netwm_startup_info_begin */
1534 _ecore_x_netwm_startup_info(Ecore_X_Window win __UNUSED__,
1535 char *data __UNUSED__)
1538 Ecore_X_Startup_Info *info;
1544 info = eina_hash_find(startup_info, (void *)win);
1548 if ((info->length + 20) > info->buffer_size)
1550 info->buffer_size += 160;
1551 info->buffer = realloc(info->buffer, info->buffer_size * sizeof(char));
1554 eina_hash_del(startup_info, (void *)info->win);
1555 _ecore_x_netwm_startup_info_free(info);
1560 memcpy(info->buffer + info->length, data, 20);
1561 p = info->buffer + info->length;
1563 info->buffer[info->length] = 0;
1564 if (strlen(p) != 20)
1565 /* We have a '\0' in there, the message is done */
1566 _ecore_x_netwm_startup_info_process(info);
1570 } /* _ecore_x_netwm_startup_info */
1573 * Set UTF-8 string property
1576 _ecore_x_window_prop_string_utf8_set(Ecore_X_Window win, Ecore_X_Atom atom,
1579 XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8,
1580 PropModeReplace, (unsigned char *)str, strlen(str));
1581 } /* _ecore_x_window_prop_string_utf8_set */
1584 * Get UTF-8 string property
1587 _ecore_x_window_prop_string_utf8_get(Ecore_X_Window win, Ecore_X_Atom atom)
1590 unsigned char *prop_ret;
1592 unsigned long bytes_after, num_ret;
1597 XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
1598 ECORE_X_ATOM_UTF8_STRING, &type_ret,
1599 &format_ret, &num_ret, &bytes_after, &prop_ret);
1600 if (prop_ret && num_ret > 0 && format_ret == 8)
1602 str = malloc(num_ret + 1);
1605 memcpy(str, prop_ret, num_ret);
1606 str[num_ret] = '\0';
1614 } /* _ecore_x_window_prop_string_utf8_get */
1618 * Process startup info
1621 _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info)
1623 Ecore_X_Event_Startup_Sequence *e;
1627 p = strchr(info->buffer, ':');
1630 eina_hash_del(startup_info, (void *)info->win);
1631 _ecore_x_netwm_startup_info_free(info);
1636 if (!strcmp(info->buffer, "new"))
1639 event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
1641 event = ECORE_X_EVENT_STARTUP_SEQUENCE_NEW;
1645 else if (!strcmp(info->buffer, "change"))
1646 event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
1647 else if (!strcmp(info->buffer, "remove"))
1648 event = ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE;
1651 eina_hash_del(startup_info, (void *)info->win);
1652 _ecore_x_netwm_startup_info_free(info);
1658 if (!_ecore_x_netwm_startup_info_parse(info, p))
1660 eina_hash_del(startup_info, (void *)info->win);
1661 _ecore_x_netwm_startup_info_free(info);
1667 e = calloc(1, sizeof(Ecore_X_Event_Startup_Sequence));
1670 eina_hash_del(startup_info, (void *)info->win);
1671 _ecore_x_netwm_startup_info_free(info);
1676 ecore_event_add(event, e, NULL, NULL);
1679 if (event == ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE)
1681 eina_hash_del(startup_info, (void *)info->win);
1682 _ecore_x_netwm_startup_info_free(info);
1686 /* Discard buffer */
1688 info->buffer[0] = 0;
1692 } /* _ecore_x_netwm_startup_info_process */
1695 * Parse startup info
1698 _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info, char *data)
1702 int in_quot_sing, in_quot_dbl, escaped;
1708 while (*data == ' ') data++;
1711 data = strchr(key, '=');
1726 if ((pp - value) >= 1024)
1735 else if (in_quot_sing)
1739 else if (*p == '\'')
1747 else if (in_quot_dbl)
1751 else if (*p == '\"')
1763 else if (*p == '\'')
1765 else if (*p == '\"')
1778 if ((in_quot_dbl) || (in_quot_sing))
1785 if (!strcmp(key, "ID"))
1787 if ((info->id) && (strcmp(info->id, value)))
1790 info->id = strdup(value);
1791 p = strstr(value, "_TIME");
1793 info->timestamp = atoi(p + 5);
1795 else if (!strcmp(key, "NAME"))
1800 info->name = strdup(value);
1802 else if (!strcmp(key, "SCREEN"))
1803 info->screen = atoi(value);
1804 else if (!strcmp(key, "BIN"))
1809 info->bin = strdup(value);
1811 else if (!strcmp(key, "ICON"))
1816 info->icon = strdup(value);
1818 else if (!strcmp(key, "DESKTOP"))
1819 info->desktop = atoi(value);
1820 else if (!strcmp(key, "TIMESTAMP"))
1822 if (!info->timestamp)
1823 info->timestamp = atoi(value);
1825 else if (!strcmp(key, "DESCRIPTION"))
1827 if (info->description)
1828 free(info->description);
1830 info->description = strdup(value);
1832 else if (!strcmp(key, "WMCLASS"))
1835 free(info->wmclass);
1837 info->wmclass = strdup(value);
1839 else if (!strcmp(key, "SILENT"))
1840 info->silent = atoi(value);
1842 ERR("Ecore X Sequence, Unknown: %s=%s", key, value);
1848 } /* _ecore_x_netwm_startup_info_parse */
1853 * Free startup info struct
1856 _ecore_x_netwm_startup_info_free(void *data)
1858 Ecore_X_Startup_Info *info;
1879 if (info->description)
1880 free(info->description);
1883 free(info->wmclass);
1886 } /* _ecore_x_netwm_startup_info_free */
1889 * Is screen composited?
1892 ecore_x_screen_is_composited(int screen)
1895 static Ecore_X_Atom atom = None;
1898 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1899 snprintf(buf, sizeof(buf), "_NET_WM_CM_S%i", screen);
1901 atom = XInternAtom(_ecore_x_disp, buf, False);
1906 win = XGetSelectionOwner(_ecore_x_disp, atom);
1909 } /* ecore_x_screen_is_composited */
1912 ecore_x_screen_is_composited_set(int screen, Ecore_X_Window win)
1914 static Ecore_X_Atom atom = None;
1917 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1918 snprintf(buf, sizeof(buf), "_NET_WM_CM_S%i", screen);
1920 atom = XInternAtom(_ecore_x_disp, buf, False);
1925 XSetSelectionOwner(_ecore_x_disp, atom, win, _ecore_x_event_last_time);
1926 } /* ecore_x_screen_is_composited_set */