efl/legacy/ecore/src/lib/ecore_x/xcb/ecore_xcb_window_prop.c

872 lines
23 KiB
C

/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "ecore_xcb_private.h"
#include "Ecore_X_Atoms.h"
/*
* Set CARD32 (array) property
*/
EAPI void
ecore_x_window_prop_card32_set(Ecore_X_Window win,
Ecore_X_Atom atom,
unsigned int *val,
unsigned int num)
{
xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
atom, ECORE_X_ATOM_CARDINAL, 32, num, (const void *)val);
}
/**
* Sends the GetProperty request.
* @param window Window whose properties are requested.
* @param atom The atom.
*/
EAPI void
ecore_x_window_prop_card32_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_CARDINAL,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_window_prop_card32_get_prefetch().
*/
EAPI void
ecore_x_window_prop_card32_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 CARD32 (array) property
*
* At most len items are returned in val.
* If the property was successfully fetched the number of items stored in
* val is returned, otherwise -1 is returned.
* Note: Return value 0 means that the property exists but has no elements.
*/
EAPI int
ecore_x_window_prop_card32_get(Ecore_X_Window win __UNUSED__,
Ecore_X_Atom atom __UNUSED__,
unsigned int *val,
unsigned int len)
{
xcb_get_property_reply_t *reply;
reply = _ecore_xcb_reply_get();
if (!reply ||
(reply->type != ECORE_X_ATOM_CARDINAL) ||
(reply->format != 32))
return -1;
if (reply->value_len < len)
len = xcb_get_property_value_length(reply);
if (val)
memcpy(val, xcb_get_property_value(reply), len);
return (int)len;
}
/*
* Get CARD32 (array) property of any length
*
* If the property was successfully fetched the number of items stored in
* val is returned, otherwise -1 is returned.
* Note: Return value 0 means that the property exists but has no elements.
*/
EAPI int
ecore_x_window_prop_card32_list_get(Ecore_X_Window win __UNUSED__,
Ecore_X_Atom atom __UNUSED__,
unsigned int **plist)
{
xcb_get_property_reply_t *reply;
int num = -1;
if (plist)
*plist = NULL;
reply = _ecore_xcb_reply_get();
if (!reply)
return -1;
if ((reply->type == XCB_NONE) ||
(reply->value_len == 0))
num = 0;
else if ((reply->type == ECORE_X_ATOM_CARDINAL) &&
(reply->format == 32))
{
uint32_t *val;
num = xcb_get_property_value_length(reply);
if (plist)
{
val = (uint32_t *)malloc (num);
if (!val)
goto error;
memcpy(val, xcb_get_property_value(reply), num);
*plist = val;
}
}
error:
return num;
}
/*
* Set X ID (array) property
*/
EAPI void
ecore_x_window_prop_xid_set(Ecore_X_Window win,
Ecore_X_Atom atom,
Ecore_X_Atom type,
Ecore_X_ID *xids,
unsigned int num)
{
xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
atom, type, 32, num, xids);
}
/**
* Sends the GetProperty request.
* @param window Window whose properties are requested.
* @param atom The atom.
* @param type The atom type.
*/
EAPI void
ecore_x_window_prop_xid_get_prefetch(Ecore_X_Window window,
Ecore_X_Atom atom,
Ecore_X_Atom type)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
window,
atom,
type,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_window_prop_xid_get_prefetch().
*/
EAPI void
ecore_x_window_prop_xid_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 X ID (array) property
*
* At most len items are returned in val.
* If the property was successfully fetched the number of items stored in
* val is returned, otherwise -1 is returned.
* Note: Return value 0 means that the property exists but has no elements.
*/
EAPI int
ecore_x_window_prop_xid_get(Ecore_X_Window win __UNUSED__,
Ecore_X_Atom atom __UNUSED__,
Ecore_X_Atom type __UNUSED__,
Ecore_X_ID *xids,
unsigned int len)
{
xcb_get_property_reply_t *reply;
int num = len;
reply = _ecore_xcb_reply_get();
if (!reply)
return -1;
if (reply->type == XCB_NONE)
num = 0;
else if (reply->format == 32)
{
if (reply->value_len < len)
num = xcb_get_property_value_length(reply);
if (xids)
memcpy(xids, xcb_get_property_value(reply), num);
}
return num;
}
/*
* Get X ID (array) property
*
* If the property was successfully fetched the number of items stored in
* val is returned, otherwise -1 is returned.
* The returned array must be freed with free().
* Note: Return value 0 means that the property exists but has no elements.
*/
EAPI int
ecore_x_window_prop_xid_list_get(Ecore_X_Window win __UNUSED__,
Ecore_X_Atom atom __UNUSED__,
Ecore_X_Atom type __UNUSED__,
Ecore_X_ID **pxids)
{
xcb_get_property_reply_t *reply;
int num = -1;
if (pxids)
*pxids = NULL;
reply = _ecore_xcb_reply_get();
if (!reply)
return -1;
if ((reply->type == XCB_NONE) ||
(reply->value_len == 0))
num = 0;
else if ((reply->type == ECORE_X_ATOM_CARDINAL) &&
(reply->format == 32))
{
uint32_t *val;
num = xcb_get_property_value_length(reply);
if (pxids)
{
val = (uint32_t *)malloc (num);
if (!val)
return -1;
memcpy(val, xcb_get_property_value(reply), num);
*pxids = val;
}
}
return num;
}
/*
* Remove/add/toggle X ID list item.
*/
EAPI void
ecore_x_window_prop_xid_list_change(Ecore_X_Window win,
Ecore_X_Atom atom,
Ecore_X_Atom type,
Ecore_X_ID item,
int op)
{
Ecore_X_ID *lst;
int i;
int num;
num = ecore_x_window_prop_xid_list_get(win, atom, type, &lst);
if (num < 0)
return; /* Error - assuming invalid window */
/* Is it there? */
for (i = 0; i < num; i++)
{
if (lst[i] == item)
break;
}
if (i < num)
{
/* Was in list */
if (op == ECORE_X_PROP_LIST_ADD)
goto done;
/* Remove it */
num--;
for (; i < num; i++)
lst[i] = lst[i + 1];
}
else
{
/* Was not in list */
if (op == ECORE_X_PROP_LIST_REMOVE)
goto done;
/* Add it */
num++;
lst = realloc(lst, num * sizeof(Ecore_X_ID));
lst[i] = item;
}
ecore_x_window_prop_xid_set(win, atom, type, lst, num);
done:
if (lst)
free(lst);
}
/*
* Set Atom (array) property
*/
EAPI void
ecore_x_window_prop_atom_set(Ecore_X_Window win,
Ecore_X_Atom atom,
Ecore_X_Atom *list,
unsigned int num)
{
ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_ATOM, list, num);
}
/**
* Sends the GetProperty request.
* @param window Window whose properties are requested.
* @param atom Property atom.
*/
EAPI void
ecore_x_window_prop_atom_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_ATOM,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_window_prop_atom_get_prefetch().
*/
EAPI void
ecore_x_window_prop_atom_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 Atom (array) property
*
* At most len items are returned in val.
* If the property was successfully fetched the number of items stored in
* val is returned, otherwise -1 is returned.
* Note: Return value 0 means that the property exists but has no elements.
*/
EAPI int
ecore_x_window_prop_atom_get(Ecore_X_Window win,
Ecore_X_Atom atom,
Ecore_X_Atom *list,
unsigned int len)
{
return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_ATOM, list, len);
}
/*
* Get Atom (array) property
*
* If the property was successfully fetched the number of items stored in
* val is returned, otherwise -1 is returned.
* The returned array must be freed with free().
* Note: Return value 0 means that the property exists but has no elements.
*/
EAPI int
ecore_x_window_prop_atom_list_get(Ecore_X_Window win,
Ecore_X_Atom atom,
Ecore_X_Atom **plist)
{
return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_ATOM, plist);
}
/*
* Remove/add/toggle atom list item.
*/
EAPI void
ecore_x_window_prop_atom_list_change(Ecore_X_Window win,
Ecore_X_Atom atom,
Ecore_X_Atom item,
int op)
{
ecore_x_window_prop_xid_list_change(win, atom, ECORE_X_ATOM_ATOM, item, op);
}
/*
* Set Window (array) property
*/
EAPI void
ecore_x_window_prop_window_set(Ecore_X_Window win,
Ecore_X_Atom atom,
Ecore_X_Window *list,
unsigned int num)
{
ecore_x_window_prop_xid_set(win, atom, ECORE_X_ATOM_WINDOW, list, num);
}
/**
* Sends the GetProperty request.
* @param window Window whose properties are requested.
* @param atom The atom.
*/
EAPI void
ecore_x_window_prop_window_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_WINDOW,
0, 0x7fffffff);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_window_prop_window_get_prefetch().
*/
EAPI void
ecore_x_window_prop_window_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 Window (array) property
*
* At most len items are returned in val.
* If the property was successfully fetched the number of items stored in
* val is returned, otherwise -1 is returned.
* Note: Return value 0 means that the property exists but has no elements.
*/
EAPI int
ecore_x_window_prop_window_get(Ecore_X_Window win,
Ecore_X_Atom atom,
Ecore_X_Window *list,
unsigned int len)
{
return ecore_x_window_prop_xid_get(win, atom, ECORE_X_ATOM_WINDOW, list, len);
}
/*
* Get Window (array) property
*
* If the property was successfully fetched the number of items stored in
* val is returned, otherwise -1 is returned.
* The returned array must be freed with free().
* Note: Return value 0 means that the property exists but has no elements.
*/
EAPI int
ecore_x_window_prop_window_list_get(Ecore_X_Window win,
Ecore_X_Atom atom,
Ecore_X_Window **plist)
{
return ecore_x_window_prop_xid_list_get(win, atom, ECORE_X_ATOM_WINDOW, plist);
}
/**
* To be documented.
*
* FIXME: To be fixed.
*/
EAPI Ecore_X_Atom
ecore_x_window_prop_any_type(void)
{
return XCB_GET_PROPERTY_TYPE_ANY;
}
/**
* To be documented.
* @param window The window.
* @param property The property atom.
* @param type The type atom.
* @param size The size.
* @param data The data.
* @param number The size of the data.
*
* FIXME: To be fixed.
*/
EAPI void
ecore_x_window_prop_property_set(Ecore_X_Window window,
Ecore_X_Atom property,
Ecore_X_Atom type,
int size,
void *data,
int number)
{
if (window == 0) window = ((xcb_screen_t *)_ecore_xcb_screen)->root;
xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, window,
property, type,
size, number, data);
}
/**
* Sends the GetProperty request.
* @param window Window whose properties are requested.
* @param property Property atom.
* @param type Type atom.
*/
EAPI void
ecore_x_window_prop_property_get_prefetch(Ecore_X_Window window,
Ecore_X_Atom property,
Ecore_X_Atom type)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
property, type, 0, LONG_MAX);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_window_prop_property_get_prefetch().
*/
EAPI void
ecore_x_window_prop_property_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);
}
/**
* To be documented.
* @param window The window (Unused).
* @param property The property atom (Unused).
* @param type The type atom (Unused).
* @param size The size (Unused).
* @param data The returned data.
* @param num The size of the data.
* @return 1 on success, 0 otherwise.
*
* FIXME: To be fixed.
*/
EAPI int
ecore_x_window_prop_property_get(Ecore_X_Window window __UNUSED__,
Ecore_X_Atom property __UNUSED__,
Ecore_X_Atom type __UNUSED__,
int size __UNUSED__,
unsigned char **data,
int *num)
{
xcb_get_property_reply_t *reply;
/* make sure these are initialized */
if (num) *num = 0L;
if (data)
*data = NULL;
else /* we can't store the retrieved data, so just return */
return 0;
reply = _ecore_xcb_reply_get();
if (!reply)
return 0;
if ((reply->format != size) ||
(reply->value_len == 0))
return 0;
*data = malloc(reply->value_len);
if (!*data)
return 0;
memcpy(*data, xcb_get_property_value(reply),
xcb_get_property_value_length(reply));
if (num)
*num = reply->value_len;
return reply->format;
}
EAPI void
ecore_x_window_prop_property_del(Ecore_X_Window window,
Ecore_X_Atom property)
{
xcb_delete_property(_ecore_xcb_conn, window, property);
}
/**
* Sends the ListProperties request.
* @param window Window whose properties are requested.
*/
EAPI void
ecore_x_window_prop_list_prefetch(Ecore_X_Window window)
{
xcb_list_properties_cookie_t cookie;
cookie = xcb_list_properties_unchecked(_ecore_xcb_conn, window);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the ListProperties request sent by ecore_x_window_prop_list_prefetch().
*/
EAPI void
ecore_x_window_prop_list_fetch(void)
{
xcb_list_properties_cookie_t cookie;
xcb_list_properties_reply_t *reply;
cookie.sequence = _ecore_xcb_cookie_get();
reply = xcb_list_properties_reply(_ecore_xcb_conn, cookie, NULL);
_ecore_xcb_reply_cache(reply);
}
/**
* To be documented.
* @param window The window (Unused).
* @param num_ret The number of atoms.
* @return The returned atoms.
*
* FIXME: To be fixed.
*/
EAPI Ecore_X_Atom *
ecore_x_window_prop_list(Ecore_X_Window window __UNUSED__,
int *num_ret)
{
xcb_list_properties_reply_t *reply;
Ecore_X_Atom *atoms;
if (num_ret) *num_ret = 0;
reply = _ecore_xcb_reply_get();
if (!reply)
return NULL;
atoms = (Ecore_X_Atom *)malloc(reply->atoms_len * sizeof(Ecore_X_Atom));
if (!atoms)
return NULL;
memcpy(atoms,
xcb_list_properties_atoms(reply),
reply->atoms_len * sizeof(Ecore_X_Atom));
if(num_ret)
*num_ret = reply->atoms_len;
return atoms;
}
/**
* Set a window string property.
* @param win The window
* @param type The property
* @param str The string
*
* Set a window string property
*/
EAPI void
ecore_x_window_prop_string_set(Ecore_X_Window win,
Ecore_X_Atom type,
const char *str)
{
if (win == 0) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
type, ECORE_X_ATOM_UTF8_STRING,
8, strlen(str), str);
}
/**
* Sends the GetProperty request.
* @param window Window whose properties are requested.
* @param type The atom.
*/
EAPI void
ecore_x_window_prop_string_get_prefetch(Ecore_X_Window window,
Ecore_X_Atom type)
{
xcb_get_property_cookie_t cookie;
cookie = xcb_get_property_unchecked(_ecore_xcb_conn, 0,
window ? window : ((xcb_screen_t *)_ecore_xcb_screen)->root,
type, XCB_GET_PROPERTY_TYPE_ANY, 0L, 1000000L);
_ecore_xcb_cookie_cache(cookie.sequence);
}
/**
* Gets the reply of the GetProperty request sent by ecore_x_window_prop_string_get_prefetch().
*/
EAPI void
ecore_x_window_prop_string_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 a window string property.
* @param window The window
* @param type The property
*
* Return window string property of a window. String must be free'd when done.
*
* To use this function, you must call before, and in order,
* ecore_x_window_prop_string_get_prefetch(), which sends the GetProperty request,
* then ecore_x_window_prop_string_get_fetch(), which gets the reply.
*/
EAPI char *
ecore_x_window_prop_string_get(Ecore_X_Window window __UNUSED__,
Ecore_X_Atom type __UNUSED__)
{
xcb_get_property_reply_t *reply;
char *str = NULL;
reply = _ecore_xcb_reply_get();
if (!reply)
return NULL;
if (reply->type == ECORE_X_ATOM_UTF8_STRING)
{
int length;
length = reply->value_len;
str = (char *)malloc(length + 1);
memcpy(str,
xcb_get_property_value(reply),
length);
str[length] = '\0';
}
else
{
/* FIXME: to be done... */
/* #ifdef X_HAVE_UTF8_STRING */
/* s = Xutf8TextPropertyToTextList(_ecore_xcb_conn, &xtp, */
/* &list, &items); */
/* #else */
/* s = XmbTextPropertyToTextList(_ecore_xcb_conn, &xtp, */
/* &list, &items); */
/* #endif */
/* if ((s == XLocaleNotSupported) || */
/* (s == XNoMemory) || (s == XConverterNotFound)) */
/* { */
/* str = strdup((char *)xtp.value); */
/* } */
/* else if ((s >= Success) && (items > 0)) */
/* { */
/* str = strdup(list[0]); */
/* } */
/* if (list) */
/* XFreeStringList(list); */
}
return str;
}
/* FIXME : round trips because of GetWMProtocols */
/* should we rewrite its code ? */
EAPI int
ecore_x_window_prop_protocol_isset(Ecore_X_Window window,
Ecore_X_WM_Protocol protocol)
{
Ecore_X_Atom *protos;
Ecore_X_Atom proto;
uint32_t protos_count;
uint32_t i;
uint8_t ret = 0;
/* check for invalid values */
if (protocol >= ECORE_X_WM_PROTOCOL_NUM)
return ret;
proto = _ecore_xcb_atoms_wm_protocols[protocol];
if (!xcb_get_wm_protocols(_ecore_xcb_conn, window, &protos_count, &protos))
return ret;
for (i = 0; i < protos_count; i++)
if (protos[i] == proto)
{
ret = 1;
break;
}
free(protos);
return ret;
}
/**
* To be documented.
* @param window The window.
* @param num_ret The number of WM protocols.
* @return The returned WM protocols.
*
* FIXME: To be fixed.
*/
/* FIXME : round trips because of get_wm_protocols */
/* should we rewrite its code ? */
EAPI Ecore_X_WM_Protocol *
ecore_x_window_prop_protocol_list_get(Ecore_X_Window window,
int *num_ret)
{
Ecore_X_WM_Protocol *prot_ret = NULL;
Ecore_X_Atom *protos;
uint32_t protos_count;
uint32_t i;
if (!xcb_get_wm_protocols(_ecore_xcb_conn, window, &protos_count, &protos))
return NULL;
if ((!protos) || (protos_count <= 0)) return NULL;
prot_ret = calloc(1, protos_count * sizeof(Ecore_X_WM_Protocol));
if (!prot_ret)
{
free(protos);
return NULL;
}
for (i = 0; i < protos_count; i++)
{
Ecore_X_WM_Protocol j;
prot_ret[i] = -1;
for (j = 0; j < ECORE_X_WM_PROTOCOL_NUM; j++)
{
if (_ecore_xcb_atoms_wm_protocols[j] == protos[i])
prot_ret[i] = j;
}
}
free(protos);
*num_ret = protos_count;
return prot_ret;
}