#include "Ecore.h" #include "ecore_x_private.h" #include "Ecore_X.h" #include #include static Ecore_X_Atom _ecore_x_window_prop_state_atom_get(Ecore_X_Window_State s); Ecore_X_Atom ecore_x_window_prop_any_type(void) { return AnyPropertyType; } /** * To be documented. * * FIXME: To be fixed. */ void ecore_x_window_prop_property_set(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, void *data, int number) { if (win == 0) win = DefaultRootWindow(_ecore_x_disp); if (size != 32) XChangeProperty(_ecore_x_disp, win, property, type, size, PropModeReplace, (unsigned char *)data, number); else { unsigned long *dat; int i, *ptr; dat = malloc(sizeof(unsigned long) * number); if (dat) { for (ptr = (int *)data, i = 0; i < number; i++) dat[i] = ptr[i]; XChangeProperty(_ecore_x_disp, win, property, type, size, PropModeReplace, (unsigned char *)dat, number); free(dat); } } } /** * To be documented. * * FIXME: To be fixed. */ int ecore_x_window_prop_property_get(Ecore_X_Window win, Ecore_X_Atom property, Ecore_X_Atom type, int size, unsigned char **data, int *num) { Atom type_ret = 0; int ret, size_ret = 0; unsigned long num_ret = 0, bytes = 0, i; unsigned char *prop_ret = NULL; if (!win) win = DefaultRootWindow(_ecore_x_disp); ret = XGetWindowProperty(_ecore_x_disp, win, property, 0, LONG_MAX, False, type, &type_ret, &size_ret, &num_ret, &bytes, &prop_ret); if (ret != Success) { *data = NULL; return 0; } if (size != size_ret || !num_ret) { XFree(prop_ret); *data = NULL; return 0; } if (!(*data = malloc(num_ret * size / 8))) { XFree(prop_ret); return 0; } for (i = 0; i < num_ret; i++) switch (size) { case 8: (*data)[i] = prop_ret[i]; break; case 16: ((uint16_t *) *data)[i] = ((uint16_t *) prop_ret)[i]; break; case 32: ((uint32_t *) *data)[i] = ((uint32_t *) prop_ret)[i]; break; } XFree(prop_ret); *num = num_ret; return 1; } void ecore_x_window_prop_property_del(Ecore_X_Window win, Ecore_X_Atom property) { XDeleteProperty(_ecore_x_disp, win, property); } #if 0 /* * I see no purpose for a ecore_x_window_prop_property_notify(). * Commenting out for now, suggest to remove it entirely. * /Kim */ /** * Send a property notify to a window. * @param win The window * @param type Type of notification * @param data The data * * Send a property notify to a window. */ void ecore_x_window_prop_property_notify(Ecore_X_Window win, const char *type, long *data) { Ecore_X_Atom tmp; XClientMessageEvent xev; tmp = XInternAtom(_ecore_x_disp, type, False); xev.type = PropertyNotify; xev.display = _ecore_x_disp; xev.window = win; xev.message_type = tmp; xev.format = 32; xev.data.l[0] = data[0]; xev.data.l[1] = data[1]; xev.data.l[2] = data[2]; xev.data.l[3] = data[3]; xev.data.l[4] = data[4]; XSendEvent(_ecore_x_disp, DefaultRootWindow(_ecore_x_disp), False, (SubstructureNotifyMask | SubstructureRedirectMask), (XEvent *)&xev); } #endif /** * Set a window string property. * @param win The window * @param type The property * @param str The string * * Set a window string property */ void ecore_x_window_prop_string_set(Ecore_X_Window win, Ecore_X_Atom type, char *str) { XTextProperty xtp; if (win == 0) win = DefaultRootWindow(_ecore_x_disp); xtp.value = str; xtp.format = 8; xtp.encoding = _ecore_x_atom_utf8_string; xtp.nitems = strlen(str); XSetTextProperty(_ecore_x_disp, win, &xtp, type); } /** * Get a window string property. * @param win The window * @param type The property * * Return window string property of a window. String must be free'd when done. */ char * ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom type) { XTextProperty xtp; char *str = NULL; if (win == 0) win = DefaultRootWindow(_ecore_x_disp); if (XGetTextProperty(_ecore_x_disp, win, &xtp, type)) { int items; char **list; Status s; if (xtp.format == 8) { s = XmbTextPropertyToTextList(_ecore_x_disp, &xtp, &list, &items); if ((s == Success) && (items > 0)) { str = strdup(*list); XFreeStringList(list); } else str = strdup((char *)xtp.value); } else str = strdup((char *)xtp.value); XFree(xtp.value); } return str; } /** * Set a window title. * @param win The window * @param t The title string * * Set a window title */ void ecore_x_window_prop_title_set(Ecore_X_Window win, const char *t) { char *list[1]; XTextProperty xprop; list[0] = (char *) t; /* Xlib may not like the UTF8 String */ /* ecore_x_window_prop_string_set(win, _ecore_x_atom_wm_name, (char *)t); */ if (XStringListToTextProperty(list, 1, &xprop)) { XSetWMName(_ecore_x_disp, win, &xprop); XFree(xprop.value); } ecore_x_window_prop_string_set(win, _ecore_x_atom_net_wm_name, (char *)t); } /** * Get a window title. * @param win The window * @return The windows title string * * Return the title of a window. String must be free'd when done with. */ char * ecore_x_window_prop_title_get(Ecore_X_Window win) { char *title; title = ecore_x_window_prop_string_get(win, _ecore_x_atom_net_wm_name); if (!title) title = ecore_x_window_prop_string_get(win, _ecore_x_atom_wm_name); return title; } /** * Sets the WM_COMMAND property for @a win. * * @param win The window. * @param argc Number of arguments. * @param argv Arguments. */ void ecore_x_window_prop_command_set(Ecore_X_Window win, int argc, char **argv) { XSetCommand(_ecore_x_disp, win, argv, argc); } /** * Get the WM_COMMAND property for @a win. * * Return the command of a window. String must be free'd when done with. * * @param win The window. * @param argc Number of arguments. * @param argv Arguments. */ void ecore_x_window_prop_command_get(Ecore_X_Window win, int *argc, char ***argv) { XGetCommand(_ecore_x_disp, win, argv, argc); } /** * Set a window visible title. * @param win The window * @param t The visible title string * * Set a window visible title */ void ecore_x_window_prop_visible_title_set(Ecore_X_Window win, const char *t) { ecore_x_window_prop_string_set(win, _ecore_x_atom_net_wm_visible_name, (char *)t); } /** * Get a window visible title. * @param win The window * @return The windows visible title string * * Return the visible title of a window. String must be free'd when done with. */ char * ecore_x_window_prop_visible_title_get(Ecore_X_Window win) { char *title; title = ecore_x_window_prop_string_get(win, _ecore_x_atom_net_wm_visible_name); return title; } /** * Set a window icon name. * @param win The window * @param t The icon name string * * Set a window icon name */ void ecore_x_window_prop_icon_name_set(Ecore_X_Window win, const char *t) { ecore_x_window_prop_string_set(win, _ecore_x_atom_wm_icon_name, (char *)t); ecore_x_window_prop_string_set(win, _ecore_x_atom_net_wm_icon_name, (char *)t); } /** * Get a window icon name. * @param win The window * @return The windows icon name string * * Return the icon name of a window. String must be free'd when done with. */ char * ecore_x_window_prop_icon_name_get(Ecore_X_Window win) { char *name; name = ecore_x_window_prop_string_get(win, _ecore_x_atom_net_wm_icon_name); if (!name) name = ecore_x_window_prop_string_get(win, _ecore_x_atom_wm_icon_name); return name; } /** * Set a window visible icon name. * @param win The window * @param t The visible icon name string * * Set a window visible icon name */ void ecore_x_window_prop_visible_icon_name_set(Ecore_X_Window win, const char *t) { ecore_x_window_prop_string_set(win, _ecore_x_atom_net_wm_visible_icon_name, (char *)t); } /** * Get a window visible icon name. * @param win The window * @return The windows visible icon name string * * Return the visible icon name of a window. String must be free'd when done with. */ char * ecore_x_window_prop_visible_icon_name_get(Ecore_X_Window win) { char *name; name = ecore_x_window_prop_string_get(win, _ecore_x_atom_net_wm_visible_icon_name); return name; } /** * Get a window client machine string. * @param win The window * @return The windows client machine string * * Return the client machine of a window. String must be free'd when done with. */ char * ecore_x_window_prop_client_machine_get(Ecore_X_Window win) { char *name; name = ecore_x_window_prop_string_get(win, _ecore_x_atom_wm_client_machine); return name; } /** * Get a windows process id * @param win The window * @return The windows process id * * Return the process id of a window. */ pid_t ecore_x_window_prop_pid_get(Ecore_X_Window win) { int num = 0; pid_t pid = 0; unsigned char *tmp = NULL; ecore_x_window_prop_property_get(win, _ecore_x_atom_net_wm_pid, XA_CARDINAL, 32, &tmp, &num); if ((num) && (tmp)) { pid = (pid_t)(*tmp); free(tmp); } return pid; } /** * Set a window name & class. * @param win The window * @param n The name string * @param c The class string * * Set a window name * class */ void ecore_x_window_prop_name_class_set(Ecore_X_Window win, const char *n, const char *c) { XClassHint *xch; xch = XAllocClassHint(); if (!xch) return; xch->res_name = (char *)n; xch->res_class = (char *)c; XSetClassHint(_ecore_x_disp, win, xch); XFree(xch); } /** * Get a window name & class. * @param win The window * @param n Name string * @param c Class string * * Get a windows name and class property. strings must be free'd when done * with. */ void ecore_x_window_prop_name_class_get(Ecore_X_Window win, char **n, char **c) { XClassHint xch; if (n) *n = NULL; if (c) *c = NULL; if (XGetClassHint(_ecore_x_disp, win, &xch)) { if (n) { if (xch.res_name) *n = strdup(xch.res_name); } if (c) { if (xch.res_class) *c = strdup(xch.res_class); } XFree(xch.res_name); XFree(xch.res_class); } } /** * Set or unset a wm protocol property. * @param win The Window * @param protocol The protocol to enable/disable * @param on On/Off * */ void ecore_x_window_prop_protocol_set(Ecore_X_Window win, Ecore_X_WM_Protocol protocol, int on) { Atom *protos = NULL; Atom proto; int protos_count = 0; int already_set = 0; int i; proto = _ecore_x_atoms_wm_protocols[protocol]; if (!XGetWMProtocols(_ecore_x_disp, win, &protos, &protos_count)) { protos = NULL; protos_count = 0; } for (i = 0; i < protos_count; i++) { if (protos[i] == proto) { already_set = 1; break; } } if (on) { Atom *new_protos = NULL; if (already_set) goto leave; new_protos = malloc((protos_count + 1) * sizeof(Atom)); if (!new_protos) goto leave; for (i = 0; i < protos_count; i++) new_protos[i] = protos[i]; new_protos[protos_count] = proto; XSetWMProtocols(_ecore_x_disp, win, new_protos, protos_count + 1); free(new_protos); } else { if (!already_set) goto leave; for (i = 0; i < protos_count; i++) { if (protos[i] == proto) { int j; for (j = i + 1; j < protos_count; j++) protos[j - 1] = protos[j]; if (protos_count > 1) XSetWMProtocols(_ecore_x_disp, win, protos, protos_count - 1); else XDeleteProperty(_ecore_x_disp, win, _ecore_x_atom_wm_protocols); goto leave; } } } leave: if (protos) XFree(protos); } /** * To be documented. * * FIXME: To be fixed. */ void ecore_x_window_prop_min_size_set(Ecore_X_Window win, int w, int h) { XSizeHints hints; long ret; memset(&hints, 0, sizeof(XSizeHints)); XGetWMNormalHints(_ecore_x_disp, win, &hints, &ret); hints.flags |= PMinSize | PSize; hints.min_width = w; hints.min_height = h; XSetWMNormalHints(_ecore_x_disp, win, &hints); } /** * To be documented. * * FIXME: To be fixed. */ void ecore_x_window_prop_max_size_set(Ecore_X_Window win, int w, int h) { XSizeHints hints; long ret; memset(&hints, 0, sizeof(XSizeHints)); XGetWMNormalHints(_ecore_x_disp, win, &hints, &ret); hints.flags |= PMaxSize | PSize; hints.max_width = w; hints.max_height = h; XSetWMNormalHints(_ecore_x_disp, win, &hints); } /** * To be documented. * * FIXME: To be fixed. */ void ecore_x_window_prop_base_size_set(Ecore_X_Window win, int w, int h) { XSizeHints hints; long ret; memset(&hints, 0, sizeof(XSizeHints)); XGetWMNormalHints(_ecore_x_disp, win, &hints, &ret); hints.flags |= PBaseSize | PSize; hints.base_width = w; hints.base_height = h; XSetWMNormalHints(_ecore_x_disp, win, &hints); } /** * To be documented. * * FIXME: To be fixed. */ void ecore_x_window_prop_step_size_set(Ecore_X_Window win, int x, int y) { XSizeHints hints; long ret; memset(&hints, 0, sizeof(XSizeHints)); XGetWMNormalHints(_ecore_x_disp, win, &hints, &ret); hints.flags |= PResizeInc; hints.width_inc = x; hints.height_inc = y; XSetWMNormalHints(_ecore_x_disp, win, &hints); } /** * To be documented. * * FIXME: To be fixed. */ void ecore_x_window_prop_xy_set(Ecore_X_Window win, int x, int y) { XSizeHints hints; long ret; memset(&hints, 0, sizeof(XSizeHints)); XGetWMNormalHints(_ecore_x_disp, win, &hints, &ret); hints.flags |= PPosition | USPosition; hints.x = x; hints.y = y; XMoveWindow(_ecore_x_disp, win, x, y); XSetWMNormalHints(_ecore_x_disp, win, &hints); } /** * Sets the sticky state for @a win. * @param win The window * @param on Boolean representing the sticky state */ void ecore_x_window_prop_sticky_set(Ecore_X_Window win, int on) { unsigned long val = 0xffffffff; int ret, num = 0; unsigned char *data = NULL; if (on) { ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_desktop, XA_CARDINAL, 32, &val, 1); ecore_x_window_prop_state_set(win, ECORE_X_WINDOW_STATE_STICKY); return; } ecore_x_window_prop_state_unset(win, ECORE_X_WINDOW_STATE_STICKY); ret = ecore_x_window_prop_property_get(0, _ecore_x_atom_net_current_desktop, XA_CARDINAL, 32, &data, &num); if (!ret || !num) return; ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_desktop, XA_CARDINAL, 32, data, 1); free(data); } /** * Sets the input mode for @a win * @param win The Window * @param mode The input mode. See the description of * #_Ecore_X_Window_Input_Mode for details. * @return 1 if the input mode could be set, else 0 */ int ecore_x_window_prop_input_mode_set(Ecore_X_Window win, Ecore_X_Window_Input_Mode mode) { XWMHints *hints; if (!(hints = XGetWMHints(_ecore_x_disp, win))) if (!(hints = XAllocWMHints())) return 0; hints->flags |= InputHint; hints->input = (mode == ECORE_X_WINDOW_INPUT_MODE_PASSIVE || mode == ECORE_X_WINDOW_INPUT_MODE_ACTIVE_LOCAL); XSetWMHints(_ecore_x_disp, win, hints); XFree(hints); ecore_x_window_prop_protocol_set(win, ECORE_X_WM_PROTOCOL_TAKE_FOCUS, (mode == ECORE_X_WINDOW_INPUT_MODE_ACTIVE_LOCAL || mode == ECORE_X_WINDOW_INPUT_MODE_ACTIVE_GLOBAL)); return 1; } /** * Set the initial state of an Ecore_X_Window. * * @param win The window whose initial state is set. * @param withdrawn The window's new initial state. * * @return 1 if the input mode could be set, else 0 * */ int ecore_x_window_prop_initial_state_set(Ecore_X_Window win, Ecore_X_Window_State_Hint state) { XWMHints *hints; if (!(hints = XGetWMHints(_ecore_x_disp, win))) if (!(hints = XAllocWMHints())) return 0; switch (state) { case ECORE_X_WINDOW_STATE_HINT_NONE: hints->flags &= ~StateHint; break; case ECORE_X_WINDOW_STATE_HINT_WITHDRAWN: hints->initial_state = WithdrawnState; hints->flags |= StateHint; break; case ECORE_X_WINDOW_STATE_HINT_NORMAL: hints->initial_state = NormalState; hints->flags |= StateHint; break; case ECORE_X_WINDOW_STATE_HINT_ICONIC: hints->initial_state = IconicState; hints->flags |= StateHint; break; } XSetWMHints(_ecore_x_disp, win, hints); XFree(hints); return 1; } /** * To be documented. * * FIXME: To be fixed. */ void ecore_x_window_prop_borderless_set(Ecore_X_Window win, int borderless) { unsigned int data[5] = {0, 0, 0, 0, 0}; data[0] = 2; /* just set the decorations hint! */ data[2] = !borderless; ecore_x_window_prop_property_set(win, _ecore_x_atom_motif_wm_hints, _ecore_x_atom_motif_wm_hints, 32, (void *)data, 5); } /** * Puts @a win in the desired layer. This currently works with * windowmanagers that are Gnome-compliant or support NetWM. * * Normally you will use this function with one of the predefined * layer constants: * ECORE_X_WINDOW_LAYER_BELOW - for windows to be stacked below * ECORE_X_WINDOW_LAYER_ABOVE - for windows to be stacked on top * ECORE_X_WINDOW_LAYER_NORMAL - for windows to be put in the default layer * @param win * @param layer If < 3, @a win will be put below all other windows. * If > 5, @a win will be "always-on-top" * If = 4, @a win will be put in the default layer. * Acceptable values range from 1 to 255 (0 reserved for * desktop windows) * @return 1 if the state could be set else 0 */ int ecore_x_window_prop_layer_set(Ecore_X_Window win, int layer) { if (layer <= 0 || layer > 255) return 0; if (layer < 3) /* below */ ecore_x_window_prop_state_set(win, ECORE_X_WINDOW_STATE_BELOW); else if (layer > 5) /* above */ ecore_x_window_prop_state_set(win, ECORE_X_WINDOW_STATE_ABOVE); else if (layer == 4) { ecore_x_window_prop_state_unset(win, ECORE_X_WINDOW_STATE_BELOW); ecore_x_window_prop_state_unset(win, ECORE_X_WINDOW_STATE_ABOVE); } /* set the gnome atom */ ecore_x_window_prop_property_set(win, _ecore_x_atom_win_layer, XA_CARDINAL, 32, &layer, 1); return 1; } /** * Set the withdrawn state of an Ecore_X_Window. * @param win The window whose withdrawn state is set. * @param withdrawn The window's new withdrawn state. */ void ecore_x_window_prop_withdrawn_set(Ecore_X_Window win, int withdrawn) { #if 0 XWMHints hints; long ret; memset(&hints, 0, sizeof(XWMHints)); XGetWMNormalHints(_ecore_x_disp, win, (XSizeHints *) &hints, &ret); if (!withdrawn) hints.initial_state &= ~WithdrawnState; else hints.initial_state |= WithdrawnState; hints.flags = WindowGroupHint | StateHint; XSetWMHints(_ecore_x_disp, win, &hints); XSetWMNormalHints(_ecore_x_disp, win, (XSizeHints *) &hints); #else if (withdrawn) ecore_x_window_prop_initial_state_set(win, ECORE_X_WINDOW_STATE_HINT_WITHDRAWN); else ecore_x_window_prop_initial_state_set(win, ECORE_X_WINDOW_STATE_HINT_NONE); #endif } /** * Request the window manager to change this windows desktop. * @param win The Window * @param desktop The desktop number. */ void ecore_x_window_prop_desktop_request(Ecore_X_Window win, long desktop) { XEvent xev; memset(&xev, 0, sizeof(XEvent)); xev.xclient.type = ClientMessage; xev.xclient.display = _ecore_x_disp; xev.xclient.window = win; xev.xclient.message_type = _ecore_x_atom_net_wm_desktop; xev.xclient.format = 32; xev.xclient.data.l[0] = desktop; XSendEvent(_ecore_x_disp, DefaultRootWindow(_ecore_x_disp), False, SubstructureNotifyMask | SubstructureRedirectMask, &xev); } /** * Request the window manager to change this window's state. * * Use this function to request the window manager to change the * specified window's state after it has been displayed (mapped). * * @param win The Window * @param state The requested state * @param action The action to perform: 0 - unset, 1 - set, 2 - toggle */ void ecore_x_window_prop_state_request(Ecore_X_Window win, Ecore_X_Window_State state, int action) { XEvent xev; if (action < 0 || action > 2) return; xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; xev.xclient.display = _ecore_x_disp; xev.xclient.window = win; xev.xclient.format = 32; switch (state) { case ECORE_X_WINDOW_STATE_ICONIFIED: if (action == 0) { XMapWindow(_ecore_x_disp, win); return; } if (action != 1) return; xev.xclient.message_type = _ecore_x_atom_wm_change_state; xev.xclient.data.l[0] = IconicState; break; default: /* The _NET_WM_STATE_... hints */ xev.xclient.message_type = _ecore_x_atom_net_wm_state; xev.xclient.data.l[0] = action; xev.xclient.data.l[1] = _ecore_x_window_prop_state_atom_get(state); break; } XSendEvent(_ecore_x_disp, DefaultRootWindow(_ecore_x_disp), False, SubstructureNotifyMask | SubstructureRedirectMask, &xev); } /** * Used by the window manager, or client prior mapping, to set window desktop. * @param win The Window * @param desktop The desktop number. * * Used by the window manager, or client prior mapping, to set window desktop. */ void ecore_x_window_prop_desktop_set(Ecore_X_Window win, long desktop) { ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_desktop, XA_CARDINAL, 32, &desktop, 1); } /** * Get the current desktop of a window * @param win The Window * * Get the current desktop of a window */ long ecore_x_window_prop_desktop_get(Ecore_X_Window win) { int num; unsigned char *tmp; long desktop = -1; ecore_x_window_prop_property_get(win, _ecore_x_atom_net_wm_desktop, XA_CARDINAL, 32, &tmp, &num); if ((tmp) && (num)) { desktop = *(long *)tmp; free(tmp); } return desktop; } static Ecore_X_Atom _ecore_x_window_prop_type_atom_get(Ecore_X_Window_Type type) { switch (type) { case ECORE_X_WINDOW_TYPE_DESKTOP: return _ecore_x_atom_net_wm_window_type_desktop; case ECORE_X_WINDOW_TYPE_DOCK: return _ecore_x_atom_net_wm_window_type_dock; case ECORE_X_WINDOW_TYPE_TOOLBAR: return _ecore_x_atom_net_wm_window_type_toolbar; case ECORE_X_WINDOW_TYPE_MENU: return _ecore_x_atom_net_wm_window_type_menu; case ECORE_X_WINDOW_TYPE_UTILITY: return _ecore_x_atom_net_wm_window_type_utility; case ECORE_X_WINDOW_TYPE_SPLASH: return _ecore_x_atom_net_wm_window_type_splash; case ECORE_X_WINDOW_TYPE_DIALOG: return _ecore_x_atom_net_wm_window_type_dialog; case ECORE_X_WINDOW_TYPE_NORMAL: return _ecore_x_atom_net_wm_window_type_normal; default: return 0; } } /** * Set a window's type. * @param win The Window * @param type The Type * * Set a windows type. */ void ecore_x_window_prop_window_type_set(Ecore_X_Window win, Ecore_X_Window_Type type) { Atom a; a = _ecore_x_window_prop_type_atom_get(type); if (a) ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_window_type, XA_ATOM, 32, (unsigned char*)&a, 1); } #if 0 /** * Change a window's type. * @param win The Window * @param type The Type * * Change a windows type. */ void ecore_x_window_prop_window_type_set(Ecore_X_Window win, Ecore_X_Atom type) { int num; unsigned char *data = NULL; if (ecore_x_window_prop_property_get(win, _ecore_x_atom_net_wm_window_type, XA_ATOM, 32, &data, &num)) XFree(data); data = malloc(sizeof(Ecore_X_Atom)); if (data) { ((Atom *)data)[0] = type; ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_window_type, XA_ATOM, 32, data, 1); } free(data); } #endif static Ecore_X_Atom _ecore_x_window_prop_state_atom_get(Ecore_X_Window_State s) { switch(s) { case ECORE_X_WINDOW_STATE_MODAL: return _ecore_x_atom_net_wm_state_modal; case ECORE_X_WINDOW_STATE_STICKY: return _ecore_x_atom_net_wm_state_sticky; case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT: return _ecore_x_atom_net_wm_state_maximized_vert; case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ: return _ecore_x_atom_net_wm_state_maximized_horz; case ECORE_X_WINDOW_STATE_SHADED: return _ecore_x_atom_net_wm_state_shaded; case ECORE_X_WINDOW_STATE_SKIP_TASKBAR: return _ecore_x_atom_net_wm_state_skip_taskbar; case ECORE_X_WINDOW_STATE_SKIP_PAGER: return _ecore_x_atom_net_wm_state_skip_pager; case ECORE_X_WINDOW_STATE_HIDDEN: return _ecore_x_atom_net_wm_state_skip_pager; case ECORE_X_WINDOW_STATE_FULLSCREEN: return _ecore_x_atom_net_wm_state_fullscreen; case ECORE_X_WINDOW_STATE_ABOVE: return _ecore_x_atom_net_wm_state_above; case ECORE_X_WINDOW_STATE_BELOW: return _ecore_x_atom_net_wm_state_below; default: return 0; } } /** * Set a state for a window * @param win The Window whose properties will be changed * @param s The state to be set for this window * * Adds the state to the window's properties if not already included. */ void ecore_x_window_prop_state_set(Ecore_X_Window win, Ecore_X_Window_State s) { int num = 0, i; unsigned char *old_data = NULL; unsigned char *data = NULL; Atom *oldset = NULL; Atom *newset = NULL; Ecore_X_Atom state; state = _ecore_x_window_prop_state_atom_get(s); ecore_x_window_prop_property_get(win, _ecore_x_atom_net_wm_state, XA_ATOM, 32, &old_data, &num); oldset = (Atom *) old_data; newset = calloc(num + 1, sizeof(Atom)); if (!newset) return; data = (unsigned char *) newset; for (i = 0; i < num; ++i) { if (oldset[i] == state) { XFree(old_data); free(data); return; } newset[i] = oldset[i]; } newset[num] = state; ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_state, XA_ATOM, 32, data, num + 1); XFree(old_data); free(data); } /** * Check if a state is set for a window. * @param win The window to be checked * @param s The state whose state will be checked * @return 1 if the state has been set for this window, 0 otherwise. * * This function will look up the window's properties to determine * if a particular state is set for that window. */ int ecore_x_window_prop_state_isset(Ecore_X_Window win, Ecore_X_Window_State s) { int num, i, ret = 0; unsigned char *data; Atom *states; Ecore_X_Atom state; state = _ecore_x_window_prop_state_atom_get(s); if (!ecore_x_window_prop_property_get(win, _ecore_x_atom_net_wm_state, XA_ATOM, 32, &data, &num)) return ret; states = (Atom *) data; for (i = 0; i < num; ++i) { if(states[i] == state) { ret = 1; break; } } XFree(data); return ret; } /** * Remove the specified state from a window. * @param win The window whose properties will be changed * @param s The state to be deleted from the window's properties * * Checks if the specified state is set for the window, and if so, deletes * that state from the window's properties. */ void ecore_x_window_prop_state_unset(Ecore_X_Window win, Ecore_X_Window_State s) { int num = 0, i, j = 0; unsigned char *old_data = NULL; unsigned char *data = NULL; Atom *oldset = NULL; Atom *newset = NULL; Ecore_X_Atom state ; state = _ecore_x_window_prop_state_atom_get(s); if (!ecore_x_window_prop_state_isset(win, s)) { return; } ecore_x_window_prop_property_get(win, _ecore_x_atom_net_wm_state, XA_ATOM, 32, &old_data, &num); oldset = (Atom *) old_data; newset = calloc(num - 1, sizeof(Atom)); data = (unsigned char *) newset; for (i = 0; i < num; ++i) if (oldset[i] != state) newset[j++] = oldset[i]; ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_state, XA_ATOM, 32, data, j); XFree(oldset); free(newset); } #if 0 void ecore_x_window_prop_window_type_utility_set(Ecore_X_Window win) { ecore_x_window_prop_window_type_set(win, _ecore_x_atom_net_wm_window_type_utility); } /** * Set a window as a splash type. * @param win The Window * * Set a window as a splash type. */ void ecore_x_window_prop_window_type_splash_set(Ecore_X_Window win) { ecore_x_window_prop_window_type_set(win, _ecore_x_atom_net_wm_window_type_splash); } /** * Set a window as a dialog type. * @param win The Window * * Set a window as a dialog type. */ void ecore_x_window_prop_window_type_dialog_set(Ecore_X_Window win) { ecore_x_window_prop_window_type_set(win, _ecore_x_atom_net_wm_window_type_dialog); } /** * Set a window as a normal type. * @param win The Window * * Set a window as a normal type. */ void ecore_x_window_prop_window_type_normal_set(Ecore_X_Window win) { ecore_x_window_prop_window_type_set(win, _ecore_x_atom_net_wm_window_type_normal); } #endif /** * Set the requested opacity of the window * @param win The window whose opacity will be set * @param opacity The opacity value to be applied to the window * * This only has an effect if the Composite extension is present and * a compositing manager is running. This hint is still pending approval * as part of the EWMH specification. The value supplied should be an * integer between 0 and 255, with 255 representing full opacity. */ void ecore_x_window_prop_window_opacity_set(Ecore_X_Window win, int opacity) { unsigned long o_val; double tmp; if (opacity < 0) opacity = 0; else if (opacity > 255) opacity = 255; tmp = (double) opacity/255. * 4294967295.; o_val = (unsigned long) tmp; ecore_x_window_prop_property_set(win, _ecore_x_atom_net_wm_window_opacity, XA_CARDINAL, 32, &o_val, 1); } /** * Get the current opacity value of the window * @param win The window whose opacity is being requested * @return An int between 0 and 255 representing the window's opacity value, * or -1 if the property is not found. */ int ecore_x_window_prop_window_opacity_get(Ecore_X_Window win) { unsigned char *data = NULL; unsigned long lval; int ret_val = -1; int num; if(ecore_x_window_prop_property_get(win, _ecore_x_atom_net_wm_window_opacity, XA_CARDINAL, 32, &data, &num)) { if (data && num) { lval = *(unsigned long *) data; ret_val = (int) ((double) lval / 4294967295. * 255.); } } return ret_val; }