efl/legacy/ecore/src/lib/ecore_x/ecore_xcb_netwm.c

3198 lines
93 KiB
C

/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
/*
* _NET_WM... aka Extended Window Manager Hint (EWMH) functions.
*/
#include "Ecore_Data.h"
#include "ecore_xcb_private.h"
#include "Ecore_X_Atoms.h"
/**
* @defgroup Ecore_X_NetWM_Group Extended Window Manager Hint (EWMH) functions
*
* Functions related to the Extended Window Manager Hint (EWMH).
*/
typedef struct _Ecore_X_Startup_Info Ecore_X_Startup_Info;
struct _Ecore_X_Startup_Info
{
Ecore_X_Window win;
int init;
int buffer_size;
char *buffer;
int length;
/* These are the sequence info fields */
char *id;
char *name;
int screen;
char *bin;
char *icon;
int desktop;
int timestamp;
char *description;
char *wmclass;
int silent;
};
#if 0
static void _ecore_x_window_prop_string_utf8_get_prefetch(Ecore_X_Window window, Ecore_X_Atom atom);
static void _ecore_x_window_prop_string_utf8_get_fetch(void);
#endif
static void _ecore_x_window_prop_string_utf8_set(Ecore_X_Window window, Ecore_X_Atom atom, const char *str);
static char *_ecore_x_window_prop_string_utf8_get(Ecore_X_Window window, Ecore_X_Atom atom);
#if 0 /* Unused */
static int _ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info);
static int _ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info, char *data);
#endif
static void _ecore_x_netwm_startup_info_free(void *data);
/*
* Local variables
*/
static Ecore_Hash *startup_info = NULL;
/**
* Initialize the NetWM module
*/
EAPI void
ecore_x_netwm_init(void)
{
startup_info = ecore_hash_new(ecore_direct_hash, ecore_direct_compare);
if (startup_info)
{
ecore_hash_free_value_cb_set(startup_info, _ecore_x_netwm_startup_info_free);
}
}
/**
* Shutdown the NetWM module
*/
EAPI void
ecore_x_netwm_shutdown(void)
{
if (startup_info)
ecore_hash_destroy(startup_info);
startup_info = NULL;
}
/**
* Set the _NET_SUPPORTING_WM_CHECK property.
* @param root The root window.
* @param check The child window.
* @param wm_name The name of the Window Manager.
*
* Set the _NET_SUPPORTING_WM_CHECK property on the @p root window to be
* the ID of the child window @p check created by the Window Manager.
* @p check also have the _NET_WM_NAME property set to the name
* @p wm_name of the Window Manager.
*
* The Window MUST call that function to indicate that a compliant
* window manager is active.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_wm_identify(Ecore_X_Window root,
Ecore_X_Window check,
const char *wm_name)
{
ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1);
ecore_x_window_prop_window_set(check, ECORE_X_ATOM_NET_SUPPORTING_WM_CHECK, &check, 1);
_ecore_x_window_prop_string_utf8_set(check, ECORE_X_ATOM_NET_WM_NAME, wm_name);
/* This one isn't mandatory */
_ecore_x_window_prop_string_utf8_set(root, ECORE_X_ATOM_NET_WM_NAME, wm_name);
}
/**
* Set the _NET_SUPPORTED property.
* @param root The root window.
* @param supported The supported hints.
* @param num The number of hints.
*
* Set the _NET_SUPPORTED property on the @p root window. The hints
* that the Window Manager supports are stored in @p supported.
*
* The Window Manager MUST set this property to indicate which hints
* it supports.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_supported_set(Ecore_X_Window root,
Ecore_X_Atom *supported,
int num)
{
ecore_x_window_prop_atom_set(root, ECORE_X_ATOM_NET_SUPPORTED, supported, num);
}
/**
* Sends the GetProperty request.
* @param root The root window
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_supported_get_prefetch(Ecore_X_Window root)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, root,
ECORE_X_ATOM_NET_SUPPORTED, ECORE_X_ATOM_ATOM,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_supported_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_supported_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the hints supported by the Window Manager.
* @param root The root window.
* @param supported The supported hints.
* @param num The number of atoms.
* @return 1 on success, 0 otherwise.
*
* Get the hints supported by the Window Manager. @p root is the root
* window. The hints are stored in @p supported. The number of hints
* is stored in @p num.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_supported_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_supported_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_supported_get(Ecore_X_Window root,
Ecore_X_Atom **supported,
int *num)
{
int num_ret;
if (num) *num = 0UL;
if (supported) *supported = NULL;
num_ret = ecore_x_window_prop_xid_list_get(root,
ECORE_X_ATOM_NET_SUPPORTED,
ECORE_X_ATOM_ATOM,
supported);
if (num_ret <= 0)
return 0;
if (num) *num = (uint32_t)num_ret;
return 1;
}
/**
* Set the _NET_NUMBER_OF_DESKTOPS property.
* @param root The root window.
* @param n_desks The number of desktops.
*
* Set the number of desktops @p n_desks of the Window Manager by
* sending the _NET_NUMBER_OF_DESKTOPS to the @p root window.
*
* The Window Manager SHOULD set and update this property to indicate
* the number of virtual desktops. A Pager can request a change in the
* number of desktops by using that function.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desk_count_set(Ecore_X_Window root,
unsigned int n_desks)
{
ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_NUMBER_OF_DESKTOPS,
&n_desks, 1);
}
/**
* Set the _NET_VIRTUAL_ROOTS property.
* @param root The root window.
* @param vroots The virtual root windows.
* @param n_desks The number of desks.
*
* Set the number of virtual desktops by sending the
* _NET_VIRTUAL_ROOTS property to the @p root window. @p vroots is an
* array of window and @p n_desks is the number of windows.
*
* A Window Manager that implements virtual desktops by reparent
* client windows to a child of the root window MUST use that
* function.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desk_roots_set(Ecore_X_Window root,
Ecore_X_Window *vroots,
unsigned int n_desks)
{
ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_VIRTUAL_ROOTS, vroots, n_desks);
}
/**
* Set the _NET_DESKTOP_NAMES property.
* @param root The root window.
* @param names The names of the virtual desktops.
* @param n_desks The number of virtual desktops.
*
* Set the name of each virtual desktop by sending the
* _NET_DESKTOP_NAMES to the @p root window. @p names are the names of
* the virtual desktops and @p n_desks is the number of virtual
* desktops.
*
* A Pager MAY use that function. @p n_desks may be different from the
* one passed to ecore_x_netwm_desk_count_set(). If it less or equal,
* then the desktops with high numbers are unnamed. If it is larger,
* then the excess names are considered to be reserved in case the
* number of desktops is increased.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desk_names_set(Ecore_X_Window root,
const char **names,
unsigned int n_desks)
{
char ss[32];
char *buf;
const char *s;
uint32_t i;
uint32_t len;
uint32_t l;
buf = NULL;
len = 0;
for (i = 0; i < n_desks; i++)
{
s = (names) ? names[i] : NULL;
if (!s)
{
/* Default to "Desk-<number>" */
sprintf(ss, "Desk-%d", i);
s = ss;
}
l = strlen(s) + 1;
buf = realloc(buf, len + l);
memcpy(buf + len, s, l);
len += l;
}
xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, root,
ECORE_X_ATOM_NET_DESKTOP_NAMES,
ECORE_X_ATOM_UTF8_STRING,
8, len, (const void *)buf);
free(buf);
}
/**
* Set the _NET_DESKTOP_GEOMETRY property.
* @param root The root window.
* @param width The width of the desktop.
* @param height The height of the desktop.
*
* Set the common @p width and @p height of all desktops by sending
* the _NET_DESKTOP_GEOMETRY to the @p root window.
*
* This size is equal to the screen size if the Window Manager doesn't
* support large desktops, otherwise it's equal to the virtual size of
* the desktop. The Window Manager SHOULD set this property. A Pager
* can request a change in the desktop geometry by using this
* function.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desk_size_set(Ecore_X_Window root,
unsigned int width,
unsigned int height)
{
uint32_t size[2];
size[0] = width;
size[1] = height;
ecore_x_window_prop_card32_set(root,
ECORE_X_ATOM_NET_DESKTOP_GEOMETRY,
size, 2);
}
/**
* Set the _NET_DESKTOP_VIEWPORT property.
* @param root The root window.
* @param origins An array of paris of coordiantes.
* @param n_desks The number of virtual desktops.
*
* Set the top left corner of each desktop's viewport by sending the
* _NET_DESKTOP_VIEWPORT property to the @p root window. @p origins
* contains each pair of X coordinate and Y coordinate of the top left
* corner of each desktop's viewport.
*
* If the Window Manager does not support large desktops, the
* coordinates MUST be (0,0). A Pager can request to change the
* viewport for the current desktop by using this function.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desk_viewports_set(Ecore_X_Window root,
unsigned int *origins,
unsigned int n_desks)
{
ecore_x_window_prop_card32_set(root,
ECORE_X_ATOM_NET_DESKTOP_VIEWPORT,
origins, 2 * n_desks);
}
/**
* Set the _NET_DESKTOP_LAYOUT property.
* @param root The root window.
* @param orientation
* @param columns
* @param rows
* @param starting_corner
*
* Set the layout of virtual desktops relative to each other by
* sending the _NET_DESKTOP_LAYOUT to the @p root window.
* @p orientation defines the orientation of the virtual desktop. 0
* means horizontal layout, 1 means vertical layout. @p columns is
* the number of desktops in the X direction and @p rows is the number
* in the Y direction. @p starting_corner is the corner containing the
* first desktop. The values for @p starting_corner are 0 (top-left),
* 1 (top-right), 2 (bottom-right) and 3 (bottom-left).
*
* When the orientation is horizontal the desktops are laid out in
* rows, with the first desktop in the specified starting corner. So a
* layout with four columns and three rows starting in
* the top-left corner looks like this:
*
* +--+--+--+--+
* | 0| 1| 2| 3|
* +--+--+--+--+
* | 4| 5| 6| 7|
* +--+--+--+--+
* | 8| 9|10|11|
* +--+--+--+--+
*
* With @p starting_corner being bottom-right, it looks like this:
*
* +--+--+--+--+
* |11|10| 9| 8|
* +--+--+--+--+
* | 7| 6| 5| 4|
* +--+--+--+--+
* | 3| 2| 1| 0|
* +--+--+--+--+
*
* When the orientation is vertical the layout with four columns and
* three rows starting in the top-left corner looks like:
*
* +--+--+--+--+
* | 0| 3| 6| 9|
* +--+--+--+--+
* | 1| 4| 7|10|
* +--+--+--+--+
* | 2| 5| 8|11|
* +--+--+--+--+
*
* With @p starting_corner being top-right, it looks like:
*
* +--+--+--+--+
* | 9| 6| 3| 0|
* +--+--+--+--+
* |10| 7| 4| 1|
* +--+--+--+--+
* |11| 8| 5| 2|
* +--+--+--+--+
*
* This function MUST be used by a Pager and NOT by the Window
* Manager. When using this function, the Pager must own a manager
* selection.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desk_layout_set(Ecore_X_Window root,
int orientation,
int columns,
int rows,
int starting_corner)
{
uint32_t layout[4];
layout[0] = orientation;
layout[1] = columns;
layout[2] = rows;
layout[3] = starting_corner;
ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_LAYOUT, layout, 4);
}
/**
* Set the _NET_WORKAREA property.
* @param root The root window.
* @param areas An array of areas.
* @param n_desks The number of desks.
*
* Set the work area for each desktop by sending the _NET_WORKAREA
* property to the @p root window. An area contains the geometry (X
* and Y coordinates, width and height). These geometries are
* specified relative to the viewport on each desktop and specify an
* area that is completely contained within the viewport. @p areas
* stores these geometries. @p n_desks is the number of geometry to
* set.
*
* This function MUST be set by the Window Manager. It is used by
* desktop applications to place desktop icons appropriately.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desk_workareas_set(Ecore_X_Window root,
unsigned int *areas,
unsigned int n_desks)
{
ecore_x_window_prop_card32_set(root,
ECORE_X_ATOM_NET_WORKAREA,
areas, 4 * n_desks);
}
/**
* Set the _NET_CURRENT_DESKTOP property.
* @param root The root window.
* @param desk The index of the current desktop.
*
* Set the current desktop by sending the _NET_CURRENT_DESKTOP to the
* @p root window. @p deskmust be an integer number between 0 and the
* number of desks (set by ecore_x_netwm_desk_count_set()) -1.
*
* This function MUST be called by the Window Manager. If a Pagerwants
* to switch to naother desktop, it MUST call that function.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desk_current_set(Ecore_X_Window root,
unsigned int desk)
{
ecore_x_window_prop_card32_set(root,
ECORE_X_ATOM_NET_CURRENT_DESKTOP,
&desk, 1);
}
/**
* Set the _NET_SHOWING_DESKTOP property.
* @param root The root window
* @param on 0 to hide the desktop, non 0 to show it.
*
* Set or unset the desktop in a "showing mode" by sending the
* _NET_SHOWING_DESKTOP property to the @p root window. If @p on is 0,
* the windows are hidden and the desktop background is displayed and
* focused.
*
* If a Pager wants to enter or leave the mode, it MUST use this
* function.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_showing_desktop_set(Ecore_X_Window root,
int on)
{
uint32_t val;
val = (on) ? 1 : 0;
ecore_x_window_prop_card32_set(root,
ECORE_X_ATOM_NET_SHOWING_DESKTOP,
&val, 1);
}
/*
* Client status
*/
/**
* Set the _NET_CLIENT_LIST property.
* @param root The root window.
* @param p_clients An array of windows.
* @param n_clients The number of windows.
*
* Map all the X windows managed by the window manager from the oldest
* to the newest by sending the _NET_CLIENT_LIST property to the
* @p root window. The X windows are stored in @p p_clients and their
* number in @p n_clients.
*
* This function SHOULD be called by the Window Manager.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_client_list_set(Ecore_X_Window root,
Ecore_X_Window *p_clients,
unsigned int n_clients)
{
ecore_x_window_prop_window_set(root,
ECORE_X_ATOM_NET_CLIENT_LIST,
p_clients, n_clients);
}
/**
* Set the _NET_CLIENT_LIST_STACKING property.
* @param root The root window.
* @param p_clients An array of windows.
* @param n_clients The number of windows.
*
* Stack all the X windows managed by the window manager from bottom
* to top order by sending the _NET_CLIENT_LIST_STACKING property to the
* @p root window. The X windows are stored in @p p_clients and their
* number in @p n_clients.
*
* This function SHOULD be called by the Window Manager.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_client_list_stacking_set(Ecore_X_Window root,
Ecore_X_Window *p_clients,
unsigned int n_clients)
{
ecore_x_window_prop_window_set(root,
ECORE_X_ATOM_NET_CLIENT_LIST_STACKING,
p_clients, n_clients);
}
/**
* Set the _NET_ACTIVE_WINDOW property.
* @param root The root window.
* @param window The widow to activate.
*
* Activate @p window by sending the _NET_ACTIVE_WINDOW property to
* the @p root window.
*
* If a Client wants to activate another window, it MUST call this
* function.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_client_active_set(Ecore_X_Window root,
Ecore_X_Window window)
{
ecore_x_window_prop_window_set(root,
ECORE_X_ATOM_NET_ACTIVE_WINDOW,
&window, 1);
}
/**
* Set the _NET_WM_NAME property.
* @param window The widow to activate.
* @param name The title name of the window.
*
* Set the title name of @p window to @p name by sending the
* _NET_WM_NAME property to @p window.
*
* The Client SHOULD set the title of @p window in UTF-8 encoding. If
* set, the Window Manager should use this in preference to WM_NAME.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_name_set(Ecore_X_Window window,
const char *name)
{
_ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_NAME, name);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_name_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_NAME, ECORE_X_ATOM_UTF8_STRING,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_name_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_name_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the title of a window.
* @param window The window.
* @param name The title name.
* @return Returns always 1.
*
* Retrieve the title name of @p window and store it in @p name. The
* function returns always 1.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_name_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_name_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_name_get(Ecore_X_Window window,
char **name)
{
if (name)
*name = _ecore_x_window_prop_string_utf8_get(window, ECORE_X_ATOM_NET_WM_NAME);
return 1;
}
/**
* Set the _NET_STARTUP_ID property.
* @param window The window.
* @param id The ID name.
*
* Set the ID @p id used for the startup sequence by sending the
* property _NET_STARTUP_ID to @p window. The ID name should be
* encoded in UTF-8.
*
* If a new value for the property is set, the Window Manager
* should update the window's status accordingly (update its virtual
* desktop, etc.).
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_startup_id_set(Ecore_X_Window window,
const char *id)
{
_ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_STARTUP_ID, id);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_startup_id_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_STARTUP_ID, ECORE_X_ATOM_UTF8_STRING,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_startup_id_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_startup_id_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the startup ID name of a window.
* @param window The window
* @param id The ID name
* @return Return always 1.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_startup_id_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_startup_id_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_startup_id_get(Ecore_X_Window window,
char **id)
{
if (id)
*id = _ecore_x_window_prop_string_utf8_get(window, ECORE_X_ATOM_NET_STARTUP_ID);
return 1;
}
/**
* Set the _NET_WM_VISIBLE_NAME property.
* @param window The widow to activate.
* @param name The title name of the window.
*
* Set the title name of @p window to @p name by sending the
* _NET_WM_VISIBLE_NAME property to @p window, when the Window Manager
* displays a window name other than by calling
* ecore_x_netwm_name_set().
*
* The Client SHOULD set the title of @p window in UTF-8
* encoding. This function is used for displaying title windows like
* [xterm1], [xterm2], ... thereby allowing Pagers to display the same
* title as the Window Manager.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_visible_name_set(Ecore_X_Window window,
const char *name)
{
_ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
name);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_visible_name_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_VISIBLE_NAME, ECORE_X_ATOM_UTF8_STRING,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_visible_name_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_visible_name_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the visible title of a window.
* @param window The window.
* @param name The title name.
* @return Returns always 1.
*
* Retrieve the visible title name of @p window and store it in @p name. The
* function returns always 1.
* @param window The window
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_visible_name_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_visible_name_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_visible_name_get(Ecore_X_Window window,
char **name)
{
if (name)
*name = _ecore_x_window_prop_string_utf8_get(window,
ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
return 1;
}
/**
* Set the _NET_WM_ICON_NAME property.
* @param window The widow to activate.
* @param name The icon name of the window.
*
* Set the icon name of @p window to @p name by sending the
* _NET_WM_ICON_NAME property to @p window.
*
* The Client SHOULD set the title of @p window in UTF-8 encoding. If
* set, the Window Manager should use this in preference to WM_ICON_NAME.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_icon_name_set(Ecore_X_Window window,
const char *name)
{
_ecore_x_window_prop_string_utf8_set(window, ECORE_X_ATOM_NET_WM_ICON_NAME,
name);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_icon_name_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_ICON_NAME, ECORE_X_ATOM_UTF8_STRING,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_icon_name_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_icon_name_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the icon name of a window.
* @param window The window.
* @param name The icon name.
* @return Returns always 1.
*
* Retrieve the icon name of @p window and store it in @p name. The
* function returns always 1.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_icon_name_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_icon_name_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_icon_name_get(Ecore_X_Window window,
char **name)
{
if (name)
*name = _ecore_x_window_prop_string_utf8_get(window,
ECORE_X_ATOM_NET_WM_ICON_NAME);
return 1;
}
/**
* Set the _NET_WM_VISIBLE_ICON_NAME property.
* @param window The widow to activate.
* @param name The title name of the window.
*
* Set the icon name of @p window to @p name by sending the
* _NET_WM_VISIBLE_ICON_NAME property to @p window, when the Window Manager
* displays a icon name other than by calling
* ecore_x_netwm_icon_name_set().
*
* The Client SHOULD set the icon name in UTF-8
* encoding. The Window Manager MUST use this function is it display
* an icon name other than with ecore_x_netwm_icon_name_set().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_visible_icon_name_set(Ecore_X_Window window,
const char *name)
{
_ecore_x_window_prop_string_utf8_set(window,
ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
name);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_visible_icon_name_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME, ECORE_X_ATOM_UTF8_STRING,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_visible_icon_name_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_visible_icon_name_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the visible icon name of a window.
* @param window The window.
* @param name The icon name.
* @return Returns always 1.
*
* Retrieve the visible icon name of @p window and store it in
* @p name. The function returns always 1.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_visible_icon_name_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_visible_icon_name_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_visible_icon_name_get(Ecore_X_Window window,
char **name)
{
if (name)
*name = _ecore_x_window_prop_string_utf8_get(window,
ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
return 1;
}
/**
* Set the _NET_WM_DESKTOP property.
* @param window The window.
* @param desk The desktop index.
*
* Set on which desktop the @p window is in by sending the
* _NET_WM_DESKTOP property to @p window. @p desk is the index of
* the desktop, starting from 0. To indicate that the window should
* appear on all desktops, @p desk must be equal to 0xFFFFFFFF.
*
* A Client MAY choose not to set this property, in which case the
* Window Manager SHOULD place it as it wishes.
*
* The Window Manager should honor _NET_WM_DESKTOP whenever a
* withdrawn window requests to be mapped.
*
* A Client can request a change of desktop for a non-withdrawn window
* by sending a _NET_WM_DESKTOP client message to the root window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desktop_set(Ecore_X_Window window,
unsigned int desk)
{
ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desktop_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_DESKTOP, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_desktop_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desktop_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the visible icon name of a window.
* @param window The window.
* @param desk The desktop index.
* @return 1 on success, 0 otherwise.
*
* Retrieve the desktop index in which @p window is displayed and
* store it in @p desk. If @p desk value is 0xFFFFFFFF, the window
* appears on all desktops. The function returns 1 on success, 0
* otherwise.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_desktop_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_desktop_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_desktop_get(Ecore_X_Window window,
unsigned int *desk)
{
int ret;
uint32_t tmp;
ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_DESKTOP,
&tmp, 1);
if (desk) *desk = tmp;
return (ret == 1) ? 1 : 0;
}
/**
* Set the _NET_WM_STRUT property.
* @param window The window
* @param left The number of pixels at the left of the screen.
* @param right The number of pixels at the right of the screen.
* @param top The number of pixels at the top of the screen.
* @param bottom The number of pixels at the bottom of the screen.
*
* Set space at the edje of the screen by sending the _NET_WM_STRUT
* property to @p window if @p window is to reserve that space.
* @p left, @p right, @p top and @p bottom are respectively the number
* of pixels at the left, right, top and bottom of the screen.
*
* This property is deprecated and ecore_x_netwm_strut_partial_set()
* should be used instead. However, Clients MAY set this property in
* addition to _NET_WM_STRUT_PARTIAL to ensure backward compatibility
* with Window Managers supporting older versions of the
* Specification.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_strut_set(Ecore_X_Window window,
int left,
int right,
int top,
int bottom)
{
uint32_t strut[4];
strut[0] = left;
strut[1] = right;
strut[2] = top;
strut[3] = bottom;
ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_strut_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_STRUT, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_strut_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_strut_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/*
* _NET_WM_STRUT is deprecated
*/
/**
* Get the space at the edje of the screen.
* @param window The window
* @param left The number of pixels at the left of the screen.
* @param right The number of pixels at the right of the screen.
* @param top The number of pixels at the top of the screen.
* @param bottom The number of pixels at the bottom of the screen.
* @return 1 on success, 0 otherwise.
*
* Retrieve the space at the edje of the screen if @p window is to
* reserve such space. The number of pixels at the left, right, top
* and bottom of the screen are respectively stored in @p left,
* @p right, @p top and @p bottom. This function returns 1 on success,
* 0 otherwise.
*
* This property is deprecated. See ecore_x_netwm_strut_set() for more
* informations.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_strut_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_strut_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_strut_get(Ecore_X_Window window,
int *left,
int *right,
int *top,
int *bottom)
{
uint32_t strut[4];
int ret = 0;
ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_STRUT, strut, 4);
if (ret != 4)
return 0;
if (left) *left = strut[0];
if (right) *right = strut[1];
if (top) *top = strut[2];
if (bottom) *bottom = strut[3];
return 1;
}
/**
* Set the _NET_WM_STRUT_PARTIAL property.
* @param window The window
* @param left The number of pixels at the left of the screen.
* @param right The number of pixels at the right of the screen.
* @param top The number of pixels at the top of the screen.
* @param bottom The number of pixels at the bottom of the screen.
* @param left_start_y The number of pixels.
* @param left_end_y The number of pixels.
* @param right_start_y The number of pixels.
* @param right_end_y The number of pixels.
* @param top_start_x The number of pixels.
* @param top_end_x The number of pixels.
* @param bottom_start_x The number of pixels.
* @param bottom_end_x The number of pixels.
*
* Set space at the edje of the screen by sending the
* _NET_WM_STRUT_PARTIAL property to @p window if @p window is to
* reserve that space. @p left, @p right, @p top and @p bottom are
* respectively the number of pixels at the left, right, top and
* bottom of the screen.
*
* TODO: more description for that function.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_strut_partial_set(Ecore_X_Window window,
int left,
int right,
int top,
int bottom,
int left_start_y,
int left_end_y,
int right_start_y,
int right_end_y,
int top_start_x,
int top_end_x,
int bottom_start_x,
int bottom_end_x)
{
unsigned int strut[12];
strut[0] = left;
strut[1] = right;
strut[2] = top;
strut[3] = bottom;
strut[4] = left_start_y;
strut[5] = left_end_y;
strut[6] = right_start_y;
strut[7] = right_end_y;
strut[8] = top_start_x;
strut[9] = top_end_x;
strut[10] = bottom_start_x;
strut[11] = bottom_end_x;
ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_strut_partial_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_strut_partial_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_strut_partial_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the space at the edje of the screen of a window.
* @param window The window
* @param left The number of pixels at the left of the screen.
* @param right The number of pixels at the right of the screen.
* @param top The number of pixels at the top of the screen.
* @param bottom The number of pixels at the bottom of the screen.
* @param left_start_y The number of pixels.
* @param left_end_y The number of pixels.
* @param right_start_y The number of pixels.
* @param right_end_y The number of pixels.
* @param top_start_x The number of pixels.
* @param top_end_x The number of pixels.
* @param bottom_start_x The number of pixels.
* @param bottom_end_x The number of pixels.
*
* Retrieve the space at the edje of the screen if @p window is to
* reserve such space. The number of pixels at the left, right, top
* and bottom of the screen are respectively stored in @p left,
* @p right, @p top and @p bottom. This function returns 1 on success,
* 0 otherwise.
*
* TODO: more description for that function.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_strut_partial_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_strut_partial_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_strut_partial_get(Ecore_X_Window window,
int *left,
int *right,
int *top,
int *bottom,
int *left_start_y,
int *left_end_y,
int *right_start_y,
int *right_end_y,
int *top_start_x,
int *top_end_x,
int *bottom_start_x,
int *bottom_end_x)
{
uint32_t strut[12];
int ret = 0;
ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_STRUT_PARTIAL, strut, 12);
if (ret != 12)
return 0;
if (left) *left = strut[0];
if (right) *right = strut[1];
if (top) *top = strut[2];
if (bottom) *bottom = strut[3];
if (left_start_y) *left_start_y = strut[4];
if (left_end_y) *left_end_y = strut[5];
if (right_start_y) *right_start_y = strut[6];
if (right_end_y) *right_end_y = strut[7];
if (top_start_x) *top_start_x = strut[8];
if (top_end_x) *top_end_x = strut[9];
if (bottom_start_x) *bottom_start_x = strut[10];
if (bottom_end_x) *bottom_end_x = strut[11];
return 1;
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_icons_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_ICON, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_icons_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_icons_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Retrieve hte possible icons of a window.
* @param window The window
* @param icon An array of icons.
* @param num The number of icons.
* @return 1 on success, 0 otherwise.
*
* Retrieve an array of possible icons of @p window. The icons are
* stored in @p icon and their number in @p num.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_icons_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_icons_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_icons_get(Ecore_X_Window window,
Ecore_X_Icon **icon,
int *num)
{
uint32_t *data;
uint32_t *p;
uint32_t *src;
uint32_t icons;
uint32_t len;
uint32_t i;
int num_ret;
if (num) *num = 0UL;
if (icon) *icon = NULL;
num_ret = ecore_x_window_prop_card32_list_get(window,
ECORE_X_ATOM_NET_WM_ICON,
&data);
if ((num_ret <= 0) || !data)
return 0;
if (num_ret < 2)
{
free(data);
return 0;
}
/* Check how many icons there are */
icons = 0;
p = data;
while (p)
{
len = p[0] * p[1];
p += (len + 2);
if ((p - data) > num_ret)
{
free(data);
return 0;
}
icons++;
if ((p - data) == num_ret)
p = NULL;
}
if (num) *num = icons;
/* If the user doesn't want the icons, return */
if (!icon)
{
free(data);
return 1;
}
/* Allocate memory */
*icon = malloc(icons * sizeof(Ecore_X_Icon));
if (!(*icon))
{
free(data);
return 0;
}
/* Fetch the icons */
p = data;
for (i = 0; i < icons; i++)
{
uint32_t *ps, *pd, *pe;
len = p[0] * p[1];
((*icon)[i]).width = p[0];
((*icon)[i]).height = p[1];
src = &(p[2]);
((*icon)[i]).data = malloc(len * sizeof(uint32_t));
if (!((*icon)[i]).data)
{
while (i)
free(((*icon)[--i]).data);
free(*icon);
free(data);
return 0;
}
pd = ((*icon)[i]).data;
ps = src;
pe = ps + len;
for (; ps < pe; ps++)
{
uint32_t r, g, b, a;
a = (*ps >> 24) & 0xff;
r = (((*ps >> 16) & 0xff) * a) / 255;
g = (((*ps >> 8) & 0xff) * a) / 255;
b = (((*ps ) & 0xff) * a) / 255;
*pd = (a << 24) | (r << 16) | (g << 8) | (b);
pd++;
}
p += (len + 2);
}
free(data);
return 1;
}
/**
* Set the _NET_WM_ICON_GEOMETRY property.
* @param window The window.
* @param x The X coordinate of the icon.
* @param y The Y coordinate of the icon.
* @param width The width of the icon.
* @param height The height of the icon.
*
* Set the geometry of the icon of @p window by sending the
* _NET_WM_ICON_GEOMETRY property to @p window. @p x, @p y, @p width
* and @p height specify respectively the X coordinate, the Y
* coordinate, the width and the height of the icon.
*
* Stand alone tools like a taskbar or an iconbox MAY use this
* function. This functions makes possible for a Window Manager to
* display a nice animation like morphing the window into its icon.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_icon_geometry_set(Ecore_X_Window window,
int x,
int y,
int width,
int height)
{
uint32_t geometry[4];
geometry[0] = (uint32_t)x;
geometry[1] = (uint32_t)y;
geometry[2] = (uint32_t)width;
geometry[3] = (uint32_t)height;
ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_icon_geometry_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_icon_geometry_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_icon_geometry_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the geometry of an icon.
* @param window The window
* @param x x
* @param x The X coordinate of the icon.
* @param y The Y coordinate of the icon.
* @param width The width of the icon.
* @param height The height of the icon.
* @return 1 on success, 0 othrwise.
*
* Retrieve the geometry of the icon of @p window. The geometry is
* stored in @p x, @p y, @p width and @p height. The function returns
* 1 on success, 0 otherwise.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_icon_geometry_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_icon_geometry_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_icon_geometry_get(Ecore_X_Window window,
int *x,
int *y,
int *width,
int *height)
{
uint32_t geometry[4];
int ret;
ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_ICON_GEOMETRY, geometry, 4);
if (ret != 4)
return 0;
if (x) *x = geometry[0];
if (y) *y = geometry[1];
if (width) *width = geometry[2];
if (height) *height = geometry[3];
return 1;
}
/**
* Set the _NET_WM_PID property.
* @param window The window.
* @param pid The process ID.
*
* Set the process ID of the client owning @p window by sending the
* _NET_WM_PID property to @p window.
*
* This function MAY be used by the Window Manager to kill windows
* which do not respond to the _NET_WM_PING protocol.
*
* If _NET_WM_PID is set, the ICCCM-specified property
* WM_CLIENT_MACHINE MUST also be set.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_pid_set(Ecore_X_Window window,
int pid)
{
unsigned int tmp;
tmp = pid;
ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_PID,
&tmp, 1);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_pid_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_PID, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_pid_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_pid_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the process ID of a client window.
* @param window The window.
* @param pid The process ID.
* @return 1 on success, 0 otherwise.
*
* Retrieve the process ID of @p window and store it in @p pid. This
* function returns 1 on success, 0 otherwise.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_pid_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_pid_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_pid_get(Ecore_X_Window window,
int *pid)
{
int ret;
uint32_t tmp;
ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_PID,
&tmp, 1);
if (pid) *pid = tmp;
return (ret == 1) ? 1 : 0;
}
/**
* Set the _NET_WM_HANDLED_ICONS property.
* @param window The window.
*
* Indicate to the Window Manager that it does not need to provide
* icons for the iconified @p window by sending the
* _NET_WM_HANDLED_ICONS property to @p window.
*
* This function can be used by a Pager on one of its own toplevel
* windows (for example if the Client is a taskbar and provides
* buttons for iconified windows).
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_handled_icons_set(Ecore_X_Window window)
{
ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
NULL, 0);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_handled_icons_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_HANDLED_ICONS, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_handled_icons_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_handled_icons_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Return wheter the Client handles icons or not.
* @param window The window.
* @return 1 if icons are handled, 0 otherwise.
*
* Return whether the client handles icons or not if @p window is
* iconified.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_handled_icons_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_handled_icons_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_handled_icons_get(Ecore_X_Window window)
{
int ret = 0;
ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_HANDLED_ICONS,
NULL, 0);
return (ret == 0) ? 1 : 0;
}
/**
* Set the _NET_WM_USER_TIME property.
* @param window The window.
* @param time The last user activity time in the window.
*
* Set the XServer time at which last user activity in @p window took
* place by sending the _NET_WM_USER_TIME property to @p window. @p
* time contains that XServer time in seconds.
*
* This function allows a Window Manager to alter the focus, stacking,
* and/or placement behavior of windows when they are mapped depending
* on whether the new window was created by a user action or is a
* "pop-up" window activated by a timer or some other event.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_user_time_set(Ecore_X_Window window,
unsigned int time)
{
ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_USER_TIME,
&time, 1);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_user_time_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_USER_TIME, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_user_time_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_user_time_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the last user activity time in the window.
* @param window The window.
* @param time The returned time.
* @return 1 on success, 0 otherwise.
*
* Return the XServer time at which last user activity in @p window
* took place. The time is stored in @p time.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_user_time_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_user_time_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_user_time_get(Ecore_X_Window window,
unsigned int *time)
{
int ret;
uint32_t tmp;
ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_USER_TIME,
&tmp, 1);
if (time) *time = tmp;
return (ret == 1) ? 1 : 0;
}
Ecore_X_Window_State
_ecore_x_netwm_state_get(Ecore_X_Atom a)
{
if (a == ECORE_X_ATOM_NET_WM_STATE_MODAL)
return ECORE_X_WINDOW_STATE_MODAL;
else if (a == ECORE_X_ATOM_NET_WM_STATE_STICKY)
return ECORE_X_WINDOW_STATE_STICKY;
else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_VERT)
return ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
else if (a == ECORE_X_ATOM_NET_WM_STATE_MAXIMIZED_HORZ)
return ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
else if (a == ECORE_X_ATOM_NET_WM_STATE_SHADED)
return ECORE_X_WINDOW_STATE_SHADED;
else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_TASKBAR)
return ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
else if (a == ECORE_X_ATOM_NET_WM_STATE_SKIP_PAGER)
return ECORE_X_WINDOW_STATE_SKIP_PAGER;
else if (a == ECORE_X_ATOM_NET_WM_STATE_HIDDEN)
return ECORE_X_WINDOW_STATE_HIDDEN;
else if (a == ECORE_X_ATOM_NET_WM_STATE_FULLSCREEN)
return ECORE_X_WINDOW_STATE_FULLSCREEN;
else if (a == ECORE_X_ATOM_NET_WM_STATE_ABOVE)
return ECORE_X_WINDOW_STATE_ABOVE;
else if (a == ECORE_X_ATOM_NET_WM_STATE_BELOW)
return ECORE_X_WINDOW_STATE_BELOW;
else if (a == ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION)
return ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION;
else
return ECORE_X_WINDOW_STATE_UNKNOWN;
}
static Ecore_X_Atom
_ecore_x_netwm_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_HIDDEN;
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;
case ECORE_X_WINDOW_STATE_DEMANDS_ATTENTION:
return ECORE_X_ATOM_NET_WM_STATE_DEMANDS_ATTENTION;
default:
return 0;
}
}
/**
* Set the _NET_WM_STATE property.
* @param window The window.
* @param state An array of window hints.
* @param num The number of hints.
*
* Set a list of hints describing @p window state by sending the
* _NET_WM_STATE property to @p window. The hints are stored in the
* array @p state. @p num must contain the number of hints.
*
* The Window Manager SHOULD honor _NET_WM_STATE whenever a withdrawn
* window requests to be mapped. A Client wishing to change the state
* of a window MUST send a _NET_WM_STATE client message to the root
* window. The Window Manager MUST keep this property updated to
* reflect the current state of the window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_window_state_set(Ecore_X_Window window,
Ecore_X_Window_State *state,
unsigned int num)
{
Ecore_X_Atom *set;
uint32_t i;
if (!num)
{
ecore_x_window_prop_property_del(window, ECORE_X_ATOM_NET_WM_STATE);
return;
}
set = malloc(num * sizeof(Ecore_X_Atom));
if (!set) return;
for (i = 0; i < num; i++)
set[i] = _ecore_x_netwm_state_atom_get(state[i]);
ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_STATE, set, num);
free(set);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_window_state_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_STATE, ECORE_X_ATOM_ATOM,
0, 0x7fffffff);;
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_window_state_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_window_state_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the hints describing the window state.
* @param window The window.
* @param state The returned hins.
* @param num The number of hints.
* @return 1 on success, 0 otherwise.
*
* Retrieve the hints describing @p window state. The state is
* returned in @p state. The nummber of hints is stored in @p
* num. This function returns 1 on success, 0 otherwise.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_window_state_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_window_state_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_window_state_get(Ecore_X_Window window,
Ecore_X_Window_State **state,
unsigned int *num)
{
Ecore_X_Atom *atoms;
int num_ret;
int i;
if (num) *num = 0;
if (state) *state = NULL;
num_ret = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_STATE,
&atoms);
if (num_ret <= 0)
return 0;
if (state)
{
*state = malloc(num_ret * sizeof(Ecore_X_Window_State));
if (*state)
for (i = 0; i < num_ret; ++i)
(*state)[i] = _ecore_x_netwm_state_get(atoms[i]);
if (num) *num = num_ret;
}
free(atoms);
return 1;
}
static Ecore_X_Window_Type
_ecore_x_netwm_window_type_type_get(Ecore_X_Atom atom)
{
if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DESKTOP)
return ECORE_X_WINDOW_TYPE_DESKTOP;
else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DOCK)
return ECORE_X_WINDOW_TYPE_DOCK;
else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_TOOLBAR)
return ECORE_X_WINDOW_TYPE_TOOLBAR;
else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_MENU)
return ECORE_X_WINDOW_TYPE_MENU;
else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_UTILITY)
return ECORE_X_WINDOW_TYPE_UTILITY;
else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_SPLASH)
return ECORE_X_WINDOW_TYPE_SPLASH;
else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_DIALOG)
return ECORE_X_WINDOW_TYPE_DIALOG;
else if (atom == ECORE_X_ATOM_NET_WM_WINDOW_TYPE_NORMAL)
return ECORE_X_WINDOW_TYPE_NORMAL;
else
return ECORE_X_WINDOW_TYPE_UNKNOWN;
}
static Ecore_X_Atom
_ecore_x_netwm_window_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;
}
}
/*
* FIXME: We should set WM_TRANSIENT_FOR if type is ECORE_X_WINDOW_TYPE_TOOLBAR
* , ECORE_X_WINDOW_TYPE_MENU or ECORE_X_WINDOW_TYPE_DIALOG
*/
/**
* Set the _NET_WM_WINDOW_TYPE property.
* @param window The window.
* @param type The functional type of the window.
*
* Set the functional @p type of @p window by sending _NET_WM_WINDOW_TYPE
* property to @p window.
*
* This property SHOULD be set by the Client before mapping. This
* property SHOULD be used by the window manager in determining the
* decoration, stacking position and other behavior of the window. The
* Client SHOULD specify window types in order of preference (the first
* being most preferable).
*
* This hint is intended to replace the MOTIF hints.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_window_type_set(Ecore_X_Window window,
Ecore_X_Window_Type type)
{
Ecore_X_Atom atom;
atom = _ecore_x_netwm_window_type_atom_get(type);
ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
&atom, 1);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_window_type_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_WINDOW_TYPE, ECORE_X_ATOM_ATOM,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_window_type_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_window_type_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/* FIXME: Maybe return 0 on some conditions? */
/**
* Get the functional type of a window.
* @param window The window.
* @param type The function type of the window.
* @return 1 on success, 0 otherwise.
*
* Retrieve the functional type of @p window. The type is stored in
* @p type. This function returns 1 on success, 0 otherwise.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_window_type_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_window_type_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_window_type_get(Ecore_X_Window window,
Ecore_X_Window_Type *type)
{
Ecore_X_Atom *atoms;
int num;
int i;
if (type) *type = ECORE_X_WINDOW_TYPE_NORMAL;
num = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_WINDOW_TYPE,
&atoms);
if (num < 0)
{
/* IMO this is not the place to mix netwm and icccm /kwo */
/* Check if WM_TRANSIENT_FOR is set */
/* Disable it for xcb */
/* if ((type) && (ecore_x_icccm_transient_for_get(window))) */
/* *type = ECORE_X_WINDOW_TYPE_DIALOG; */
/* return 1; */
}
if (type)
{
for (i = 0; i < num; ++i)
{
*type = _ecore_x_netwm_window_type_type_get(atoms[i]);
if (*type != ECORE_X_WINDOW_TYPE_UNKNOWN)
break;
}
}
free(atoms);
return 1;
}
static Ecore_X_Atom
_ecore_x_netwm_action_atom_get(Ecore_X_Action action)
{
switch (action)
{
case ECORE_X_ACTION_MOVE:
return ECORE_X_ATOM_NET_WM_ACTION_MOVE;
case ECORE_X_ACTION_RESIZE:
return ECORE_X_ATOM_NET_WM_ACTION_RESIZE;
case ECORE_X_ACTION_MINIMIZE:
return ECORE_X_ATOM_NET_WM_ACTION_MINIMIZE;
case ECORE_X_ACTION_SHADE:
return ECORE_X_ATOM_NET_WM_ACTION_SHADE;
case ECORE_X_ACTION_STICK:
return ECORE_X_ATOM_NET_WM_ACTION_STICK;
case ECORE_X_ACTION_MAXIMIZE_HORZ:
return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_HORZ;
case ECORE_X_ACTION_MAXIMIZE_VERT:
return ECORE_X_ATOM_NET_WM_ACTION_MAXIMIZE_VERT;
case ECORE_X_ACTION_FULLSCREEN:
return ECORE_X_ATOM_NET_WM_ACTION_FULLSCREEN;
case ECORE_X_ACTION_CHANGE_DESKTOP:
return ECORE_X_ATOM_NET_WM_ACTION_CHANGE_DESKTOP;
case ECORE_X_ACTION_CLOSE:
return ECORE_X_ATOM_NET_WM_ACTION_CLOSE;
default:
return 0;
}
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_allowed_action_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, ECORE_X_ATOM_ATOM,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_allowed_action_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_allowed_action_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/* FIXME: Get complete list */
/**
* Check whether an action is supported by a window.
* @param window The window
* @param action The action
* @return 1 if set, 0 otherwise.
*
* Return whether the user operation @p action is supported by the
* Window Manager for @p window.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_allowed_action_isset(Ecore_X_Window window,
Ecore_X_Action action)
{
Ecore_X_Atom *atoms;
Ecore_X_Atom atom;
int num;
int ret = 0;
int i;
num = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
&atoms);
if (num <= 0)
return ret;
atom = _ecore_x_netwm_action_atom_get(action);
for (i = 0; i < num; ++i)
{
if (atom == atoms[i])
{
ret = 1;
break;
}
}
free(atoms);
return ret;
}
/* FIXME: Set complete list */
/**
* Set the _NET_WM_ALLOWED_ACTIONS property.
* @param window The window.
* @param action An array of allowed actions.
* @param num The number of actions.
*
* Set the user operations that the Window Manager supports for
* @p window by sending the _NET_WM_ALLOWED_ACTIONS property to
* @p window. @p action stores @p num actions.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_allowed_action_set(Ecore_X_Window window,
Ecore_X_Action *action,
unsigned int num)
{
Ecore_X_Atom *set;
unsigned int i;
if (!num)
{
ecore_x_window_prop_property_del(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS);
return;
}
set = malloc(num * sizeof(Ecore_X_Atom));
if (!set) return;
for (i = 0; i < num; i++)
set[i] = _ecore_x_netwm_action_atom_get(action[i]);
ecore_x_window_prop_atom_set(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS, set, num);
free(set);
}
/**
* Get the allowed actions supported by a window.
* @param window The window.
* @param action The returned array of the actions.
* @param num The number of actions.
* @return 1 on success, 0 otherwise.
*
* Retrieve the user operations that the Window Manager supports for
* @p window and store them in @p action. The number of actions is
* stored in @p num. This function returns 1 on success, 0 otherwise.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_allowed_action_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_allowed_action_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_allowed_action_get(Ecore_X_Window window,
Ecore_X_Action **action,
unsigned int *num)
{
Ecore_X_Atom *atoms;
int num_ret;
int i;
if (num) *num = 0;
if (action) *action = NULL;
num_ret = ecore_x_window_prop_atom_list_get(window, ECORE_X_ATOM_NET_WM_ALLOWED_ACTIONS,
&atoms);
if (num_ret <= 0)
return 0;
if (action)
{
*action = malloc(num_ret * sizeof(Ecore_X_Action));
if (*action)
for (i = 0; i < num_ret; ++i)
(*action)[i] = _ecore_x_netwm_action_atom_get(atoms[i]);
if (num) *num = num_ret;
}
free(atoms);
return 1;
}
/**
* Set the _NET_WM_WINDOW_OPACITY property.
* @param window The window.
* @param opacity The opacity value.
*
* Set the desired opacity of @p window by sending the
* _NET_WM_WINDOW_OPACITY property to @p window. @p opacity is 0 for a
* transparent window and 0xffffffff for an opaque window. @p opacity
* must be multiplied with the original alpha value of @p window
* (which is 1 for visuals not including an alpha component) so that
* @p window content is modulated by the opacity value.
*
* Window Managers acting as compositing managers MAY take this into
* account when displaying a window. Window Managers MUST forward the
* value of this property to any enclosing frame window. This
* property MAY change while the window is mapped and the Window
* Manager MUST respect changes while the window is mapped.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_opacity_set(Ecore_X_Window window,
unsigned int opacity)
{
uint32_t op = opacity;
ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
&op, 1);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_opacity_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_WINDOW_OPACITY, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_opacity_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_opacity_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the opacity value of a window.
* @param window The window.
* @param opacity The returned opacity.
* @return 1 on success, 0 otherwise.
*
* Retriee the opacity value of @p window and store it in
* @p opacity. This function returns 1 on sucess, 0 otherwise.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_opacity_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_opacity_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_opacity_get(Ecore_X_Window window,
unsigned int *opacity)
{
int ret;
unsigned int tmp;
ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
&tmp, 1);
if (opacity) *opacity = tmp;
return ret == 1 ? 1 : 0;
}
/**
* Set the _NET_FRAME_EXTENTS property.
* @param window The window.
* @param fl The number of pixels of the left border of the window.
* @param fr The number of pixels of the right border of the window.
* @param ft The number of pixels of the top border of the window.
* @param fb The number of pixels of the bottom border of the window.
*
* Set the border witdh of @p window by sending the _NET_FRAME_EXTENTS
* property to @p window. @p fl, @p fr, @p ft and @p fb are respectively
* the number of pixels of the left, right, top and bottom border of
* @p window.
*
* The Window Manager MUST set _NET_FRAME_EXTENTS to the extents of
* the window's frame.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_frame_size_set(Ecore_X_Window window,
int fl,
int fr,
int ft,
int fb)
{
uint32_t frames[4];
frames[0] = fl;
frames[1] = fr;
frames[2] = ft;
frames[3] = fb;
ecore_x_window_prop_card32_set(window, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4);
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_frame_size_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_FRAME_EXTENTS, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_frame_size_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_frame_size_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the frame extent of a window.
* @param window The window.
* @param fl The number of pixels of the left border of the window.
* @param fr The number of pixels of the right border of the window.
* @param ft The number of pixels of the top border of the window.
* @param fb The number of pixels of the bottom border of the window.
* @return 1 on success, 0 otherwise.
*
* Retrieve the frame extents of @p window. The number of pixels of
* the left, right, top and bottom border of @p window are
* respectively stored in @p fl, @p fr, @p ft anfd @p fb. TYhis
* function retuirns 1 on success, 0 otherwise.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_frame_size_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_frame_size_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_frame_size_get(Ecore_X_Window window,
int *fl,
int *fr,
int *ft,
int *fb)
{
uint32_t frames[4];
int ret = 0;
ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_FRAME_EXTENTS, frames, 4);
if (ret != 4)
return 0;
if (fl) *fl = frames[0];
if (fr) *fr = frames[1];
if (ft) *ft = frames[2];
if (fb) *fb = frames[3];
return 1;
}
/**
* Sends the GetProperty request.
* @param window The window.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_sync_counter_get_prefetch(Ecore_X_Window window)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER, ECORE_X_ATOM_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_netwm_sync_counter_get_prefetch().
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_sync_counter_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* Get the X ID of a X Sync counter.
* @param window The window.
* @param counter The X ID of the Sync counter.
* @return 1 on success, 0 otherwise.
*
* Retrieve the X ID of the X Sync counter of @p window and store it
* in @p counter. This function returns 1 on success, 0 otherwise.
*
* To use this function, you must call before, and in order,
* ecore_x_netwm_frame_size_get_prefetch(), which sends the GetProperty request,
* then ecore_x_netwm_frame_size_get_fetch(), which gets the reply.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_netwm_sync_counter_get(Ecore_X_Window window,
Ecore_X_Sync_Counter *counter)
{
int ret;
unsigned int tmp;
ret = ecore_x_window_prop_card32_get(window, ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
&tmp, 1);
if (counter) *counter = tmp;
return (ret == 1) ? 1 : 0;
}
/**
* Send a _NET_WM_PING property event.
* @param window The window.
*
* Send a ClientMessage event from @p window with the _NET_WM_PING
* property set.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_ping_send(Ecore_X_Window window)
{
xcb_client_message_event_t ev;
if (!window) return;
ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
ev.format = 32;
ev.sequence = 0;
ev.window = window;
ev.type = ECORE_X_ATOM_WM_PROTOCOLS;
ev.data.data32[0] = ECORE_X_ATOM_NET_WM_PING;
ev.data.data32[1] = XCB_CURRENT_TIME;
ev.data.data32[2] = window;
ev.data.data32[3] = 0;
ev.data.data32[4] = 0;
ev.data.data32[5] = 0;
xcb_send_event(_ecore_xcb_conn, 0, window, XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
}
/**
* Send a _NET_WM_SYNC_REQUEST property event.
* @param window The window.
* @param serial The update request number.
*
* Send a ClientMessage event from @p window with the _NET_WM_SYNC_REQUEST
* property set.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_sync_request_send(Ecore_X_Window window,
unsigned int serial)
{
xcb_client_message_event_t ev;
if (!window) return;
ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
ev.format = 32;
ev.window = window;
ev.type = ECORE_X_ATOM_WM_PROTOCOLS;
ev.data.data32[0] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
ev.data.data32[1] = XCB_CURRENT_TIME;
ev.data.data32[2] = serial;
/* FIXME: imho, the following test is useless as serial is non negative */
/* should we remove it ? */
ev.data.data32[3] = (serial < 0) ? ~0L : 0L;
ev.data.data32[4] = 0;
xcb_send_event(_ecore_xcb_conn, 0, window, 0, (const char *)&ev);
}
/**
* Send a _NET_WM_STATE property event.
* @param window The window.
* @param root The root window.
* @param s1 The first state to alter.
* @param s2 The second state to alter.
* @param set 0 to unset the property, set it otherwise.
*
* Send a ClientMessage event from @p window to the @p root window
* with the _NET_WM_STATE property set. This change the state of a
* mapped window. @p s1 is the first state to alter. @p s2 is the
* second state to alter. If @p set value is 0, the property is
* removed (or unset), otherwise, the property is set.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_state_request_send(Ecore_X_Window window,
Ecore_X_Window root,
Ecore_X_Window_State s1,
Ecore_X_Window_State s2,
int set)
{
xcb_client_message_event_t ev;
if (!window) return;
if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
ev.format = 32;
ev.window = window;
ev.type = ECORE_X_ATOM_NET_WM_STATE;
ev.data.data32[0] = !!set;
ev.data.data32[1] = _ecore_x_netwm_state_atom_get(s1);
ev.data.data32[2] = _ecore_x_netwm_state_atom_get(s2);
/* 1 == normal client, if someone wants to use this
* function in a pager, this should be 2 */
ev.data.data32[3] = 1;
ev.data.data32[4] = 0;
xcb_send_event(_ecore_xcb_conn, 0, root,
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
(const char *)&ev);
}
/**
* Send a _NET_WM_DESKTOP property event.
* @param window The window.
* @param root The root window.
* @param desktop The new desktop index.
*
* Send a ClientMessage event from @p window to the @p root window
* with the _NET_WM_DESKTOP property set. This change the state of a
* non-withdrawn window. @p desktop is the new desktop index to set.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI void
ecore_x_netwm_desktop_request_send(Ecore_X_Window window,
Ecore_X_Window root,
unsigned int desktop)
{
xcb_client_message_event_t ev;
if (!window) return;
if (!root) root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
ev.response_type = XCB_CLIENT_MESSAGE | 0x80;
ev.format = 32;
ev.window = window;
ev.type = ECORE_X_ATOM_NET_WM_DESKTOP;
ev.data.data32[0] = desktop;
xcb_send_event(_ecore_xcb_conn, 0, root,
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
(const char *)&ev);
}
int
_ecore_x_netwm_startup_info_begin(Ecore_X_Window window,
char *data)
{
#if 0
Ecore_X_Startup_Info *info;
if (!startup_info) return 0;
info = ecore_hash_get(startup_info, (void *)window);
if (info)
{
printf("Already got info for win: 0x%x\n", window);
_ecore_x_netwm_startup_info_free(info);
}
info = calloc(1, sizeof(Ecore_X_Startup_Info));
if (!info) return 0;
info->win = win;
info->length = 0;
info->buffer_size = 161;
info->buffer = calloc(info->buffer_size, sizeof(char));
if (!info->buffer)
{
_ecore_x_netwm_startup_info_free(info);
return 0;
}
memcpy(info->buffer, data, 20);
info->length += 20;
info->buffer[info->length] = 0;
ecore_hash_set(startup_info, (void *)info->win, info);
if (strlen(info->buffer) != 20)
{
/* We have a '\0' in there, the message is done */
_ecore_x_netwm_startup_info_process(info);
}
#else
window = XCB_NONE;
data = NULL;
#endif
return 1;
}
int
_ecore_x_netwm_startup_info(Ecore_X_Window window,
char *data)
{
#if 0
Ecore_X_Startup_Info *info;
char *p;
if (!startup_info) return 0;
info = ecore_hash_get(startup_info, (void *)window);
if (!info) return 0;
if ((info->length + 20) > info->buffer_size)
{
info->buffer_size += 160;
info->buffer = realloc(info->buffer, info->buffer_size * sizeof(char));
if (!info->buffer)
{
ecore_hash_remove(startup_info, (void *)info->win);
_ecore_x_netwm_startup_info_free(info);
return 0;
}
}
memcpy(info->buffer + info->length, data, 20);
p = info->buffer + info->length;
info->length += 20;
info->buffer[info->length] = 0;
if (strlen(p) != 20)
{
/* We have a '\0' in there, the message is done */
_ecore_x_netwm_startup_info_process(info);
}
#else
window = XCB_NONE;
data = NULL;
#endif
return 1;
}
/*
* Set UTF-8 string property
*/
static void
_ecore_x_window_prop_string_utf8_set(Ecore_X_Window window,
Ecore_X_Atom atom,
const char *str)
{
xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
atom, ECORE_X_ATOM_UTF8_STRING,
8, strlen(str), str);
}
#if 0
static void
_ecore_x_window_prop_string_utf8_get_prefetch(Ecore_X_Window window,
Ecore_X_Atom atom)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0, window,
atom, ECORE_X_ATOM_UTF8_STRING,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
static void
_ecore_x_window_prop_string_utf8_get_fetch(void)
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_get_property_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
#endif
/*
* Get UTF-8 string property
*/
static char *
_ecore_x_window_prop_string_utf8_get(Ecore_X_Window window __UNUSED__,
Ecore_X_Atom atom __UNUSED__)
{
xcb_get_property_reply_t *reply;
char *str;
int length;
reply = _ecore_xcb_reply_get();
if (!reply) return NULL;
if ((reply->format != 8) ||
(reply->value_len <= 0))
return NULL;
length = reply->value_len;
str = (char *)malloc (sizeof (char) * (length + 1));
if (!str)
{
return NULL;
}
memcpy(str, xcb_get_property_value(reply), length);
str[length] = '\0';
return str;
}
#if 0 /* Unused */
/*
* Process startup info
*/
static int
_ecore_x_netwm_startup_info_process(Ecore_X_Startup_Info *info)
{
Ecore_X_Event_Startup_Sequence *e;
int event;
char *p;
p = strchr(info->buffer, ':');
if (!p)
{
ecore_hash_remove(startup_info, (void *)info->win);
_ecore_x_netwm_startup_info_free(info);
return 0;
}
*p = 0;
if (!strcmp(info->buffer, "new"))
{
if (info->init)
event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
else
event = ECORE_X_EVENT_STARTUP_SEQUENCE_NEW;
info->init = 1;
}
else if (!strcmp(info->buffer, "change"))
{
event = ECORE_X_EVENT_STARTUP_SEQUENCE_CHANGE;
}
else if (!strcmp(info->buffer, "remove"))
event = ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE;
else
{
ecore_hash_remove(startup_info, (void *)info->win);
_ecore_x_netwm_startup_info_free(info);
return 0;
}
p++;
if (!_ecore_x_netwm_startup_info_parse(info, p))
{
ecore_hash_remove(startup_info, (void *)info->win);
_ecore_x_netwm_startup_info_free(info);
return 0;
}
if (info->init)
{
e = calloc(1, sizeof(Ecore_X_Event_Startup_Sequence));
if (!e)
{
ecore_hash_remove(startup_info, (void *)info->win);
_ecore_x_netwm_startup_info_free(info);
return 0;
}
e->win = info->win;
ecore_event_add(event, e, NULL, NULL);
}
if (event == ECORE_X_EVENT_STARTUP_SEQUENCE_REMOVE)
{
ecore_hash_remove(startup_info, (void *)info->win);
_ecore_x_netwm_startup_info_free(info);
}
else
{
/* Discard buffer */
info->length = 0;
info->buffer[0] = 0;
}
return 1;
}
/*
* Parse startup info
*/
static int
_ecore_x_netwm_startup_info_parse(Ecore_X_Startup_Info *info,
char *data)
{
while (*data)
{
int in_quot_sing, in_quot_dbl, escaped;
char *p, *pp;
char *key;
char value[1024];
/* Skip space */
while (*data == ' ') data++;
/* Get key */
key = data;
data = strchr(key, '=');
if (!data) return 0;
*data = 0;
data++;
/* Get value */
p = data;
pp = value;
in_quot_dbl = 0;
in_quot_sing = 0;
escaped = 0;
while (*p)
{
if ((pp - value) >= 1024) return 0;
if (escaped)
{
*pp = *p;
pp++;
escaped = 0;
}
else if (in_quot_sing)
{
if (*p == '\\')
escaped = 1;
else if (*p == '\'')
in_quot_sing = 0;
else
{
*pp = *p;
pp++;
}
}
else if (in_quot_dbl)
{
if (*p == '\\')
escaped = 1;
else if (*p == '\"')
in_quot_dbl = 0;
else
{
*pp = *p;
pp++;
}
}
else
{
if (*p == '\\')
escaped = 1;
else if (*p == '\'')
in_quot_sing = 1;
else if (*p == '\"')
in_quot_dbl = 1;
else if (*p == ' ')
{
break;
}
else
{
*pp = *p;
pp++;
}
}
p++;
}
if ((in_quot_dbl) || (in_quot_sing)) return 0;
data = p;
*pp = 0;
/* Parse info */
if (!strcmp(key, "ID"))
{
if ((info->id) && (strcmp(info->id, value))) return 0;
info->id = strdup(value);
p = strstr(value, "_TIME");
if (p)
{
info->timestamp = atoi(p + 5);
}
}
else if (!strcmp(key, "NAME"))
{
if (info->name) free(info->name);
info->name = strdup(value);
}
else if (!strcmp(key, "SCREEN"))
{
info->screen = atoi(value);
}
else if (!strcmp(key, "BIN"))
{
if (info->bin) free(info->bin);
info->bin = strdup(value);
}
else if (!strcmp(key, "ICON"))
{
if (info->icon) free(info->icon);
info->icon = strdup(value);
}
else if (!strcmp(key, "DESKTOP"))
{
info->desktop = atoi(value);
}
else if (!strcmp(key, "TIMESTAMP"))
{
if (!info->timestamp)
info->timestamp = atoi(value);
}
else if (!strcmp(key, "DESCRIPTION"))
{
if (info->description) free(info->description);
info->description = strdup(value);
}
else if (!strcmp(key, "WMCLASS"))
{
if (info->wmclass) free(info->wmclass);
info->wmclass = strdup(value);
}
else if (!strcmp(key, "SILENT"))
{
info->silent = atoi(value);
}
else
{
printf("Ecore X Sequence, Unknown: %s=%s\n", key, value);
}
}
if (!info->id) return 0;
return 1;
}
#endif
/*
* Free startup info struct
*/
static void
_ecore_x_netwm_startup_info_free(void *data)
{
Ecore_X_Startup_Info *info;
info = data;
if (!info) return;
if (info->buffer) free(info->buffer);
if (info->id) free(info->id);
if (info->name) free(info->name);
if (info->bin) free(info->bin);
if (info->icon) free(info->icon);
if (info->description) free(info->description);
if (info->wmclass) free(info->wmclass);
free(info);
}
/*
* Is screen composited?
*/
/* FIXME: one round trip can be removed. Can we keep it ? */
/**
* Check whether a screen is composited or not.
* @param screen The screen index.
*
* Return 1 if @p screen is composited, 0 otherwise.
* @ingroup Ecore_X_NetWM_Group
*/
EAPI int
ecore_x_screen_is_composited(int screen)
{
char buf[32];
xcb_intern_atom_cookie_t cookie_atom;
xcb_get_selection_owner_cookie_t cookie_owner;
xcb_intern_atom_reply_t *reply_atom;
xcb_get_selection_owner_reply_t *reply_owner;
Ecore_X_Window window;
Ecore_X_Atom atom;
snprintf(buf, sizeof(buf), "_NET_WM_CM_S%d", screen);
cookie_atom = xcb_intern_atom_unchecked(_ecore_xcb_conn, 1,
strlen(buf), buf);
reply_atom = xcb_intern_atom_reply(_ecore_xcb_conn, cookie_atom, NULL);
if (!reply_atom) return 0;
atom = reply_atom->atom;
free(reply_atom);
cookie_owner = xcb_get_selection_owner_unchecked(_ecore_xcb_conn, atom);
reply_owner = xcb_get_selection_owner_reply(_ecore_xcb_conn, cookie_owner, NULL);
if (!reply_owner) return 0;
window = reply_owner->owner;
free(reply_owner);
return window != XCB_NONE;
}