1188 lines
27 KiB
C
1188 lines
27 KiB
C
/*
|
|
* Copyright (C) 2004-2009 Kim Woelders
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies of the Software, its documentation and marketing & publicity
|
|
* materials, and acknowledgment shall be given in the documentation, materials
|
|
* and software packages that this Software was used.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
/*
|
|
* Stuff for compiling without ecore_x.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <X11/Xatom.h>
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
|
|
#include "config.h"
|
|
#include "e16-ecore_hints.h"
|
|
|
|
/* Window property change actions (must match _NET_WM_STATE_... ones) */
|
|
#define ECORE_X_PROP_LIST_REMOVE 0
|
|
#define ECORE_X_PROP_LIST_ADD 1
|
|
#define ECORE_X_PROP_LIST_TOGGLE 2
|
|
|
|
#ifdef USE_ECORE_X
|
|
|
|
extern Display *_ecore_x_disp;
|
|
|
|
void
|
|
ecore_x_icccm_state_set_iconic(Ecore_X_Window win)
|
|
{
|
|
ecore_x_icccm_state_set(win, ECORE_X_WINDOW_STATE_HINT_ICONIC);
|
|
}
|
|
|
|
void
|
|
ecore_x_icccm_state_set_normal(Ecore_X_Window win)
|
|
{
|
|
ecore_x_icccm_state_set(win, ECORE_X_WINDOW_STATE_HINT_NORMAL);
|
|
}
|
|
|
|
void
|
|
ecore_x_icccm_state_set_withdrawn(Ecore_X_Window win)
|
|
{
|
|
ecore_x_icccm_state_set(win, ECORE_X_WINDOW_STATE_HINT_WITHDRAWN);
|
|
}
|
|
|
|
#else /* USE_ECORE_X */
|
|
|
|
#define DEBUG_CHECK 0
|
|
#if DEBUG_CHECK
|
|
#include <assert.h>
|
|
#endif
|
|
#include "hints.h"
|
|
#include "xwin.h"
|
|
|
|
#define _ecore_x_disp disp
|
|
|
|
#define N_ITEMS(x) (sizeof(x)/sizeof(x[0]))
|
|
|
|
/*
|
|
* General stuff
|
|
*/
|
|
|
|
/*
|
|
* Send client message (format 32)
|
|
*/
|
|
int
|
|
ecore_x_client_message32_send(Window win, Atom type, long mask, long d0,
|
|
long d1, long d2, long d3, long d4)
|
|
{
|
|
XEvent xev;
|
|
|
|
xev.xclient.type = ClientMessage;
|
|
xev.xclient.window = win;
|
|
xev.xclient.message_type = type;
|
|
xev.xclient.format = 32;
|
|
xev.xclient.data.l[0] = d0;
|
|
xev.xclient.data.l[1] = d1;
|
|
xev.xclient.data.l[2] = d2;
|
|
xev.xclient.data.l[3] = d3;
|
|
xev.xclient.data.l[4] = d4;
|
|
|
|
return XSendEvent(_ecore_x_disp, win, False, mask, &xev);
|
|
}
|
|
|
|
/*
|
|
* Set CARD32 (array) property
|
|
*/
|
|
void
|
|
ecore_x_window_prop_card32_set(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
unsigned int *val, unsigned int num)
|
|
{
|
|
#if SIZEOF_INT == SIZEOF_LONG
|
|
XChangeProperty(_ecore_x_disp, win, atom, XA_CARDINAL, 32, PropModeReplace,
|
|
(unsigned char *)val, num);
|
|
#else
|
|
unsigned long *pl;
|
|
unsigned int i;
|
|
|
|
pl = malloc(num * sizeof(long));
|
|
if (!pl)
|
|
return;
|
|
for (i = 0; i < num; i++)
|
|
pl[i] = val[i];
|
|
XChangeProperty(_ecore_x_disp, win, atom, XA_CARDINAL, 32, PropModeReplace,
|
|
(unsigned char *)pl, num);
|
|
free(pl);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
int
|
|
ecore_x_window_prop_card32_get(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
unsigned int *val, unsigned int len)
|
|
{
|
|
unsigned char *prop_ret;
|
|
Atom type_ret;
|
|
unsigned long bytes_after, num_ret;
|
|
int format_ret;
|
|
unsigned int i;
|
|
int num;
|
|
|
|
prop_ret = NULL;
|
|
if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
|
|
XA_CARDINAL, &type_ret, &format_ret, &num_ret,
|
|
&bytes_after, &prop_ret) != Success)
|
|
return -1;
|
|
|
|
if (type_ret != XA_CARDINAL || format_ret != 32)
|
|
{
|
|
num = -1;
|
|
}
|
|
else if (num_ret == 0 || !prop_ret)
|
|
{
|
|
num = 0;
|
|
}
|
|
else
|
|
{
|
|
if (num_ret < len)
|
|
len = num_ret;
|
|
for (i = 0; i < len; i++)
|
|
val[i] = ((unsigned long *)prop_ret)[i];
|
|
num = len;
|
|
}
|
|
if (prop_ret)
|
|
XFree(prop_ret);
|
|
|
|
return num;
|
|
}
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
int
|
|
ecore_x_window_prop_card32_list_get(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
unsigned int **plst)
|
|
{
|
|
unsigned char *prop_ret;
|
|
Atom type_ret;
|
|
unsigned long bytes_after, num_ret;
|
|
int format_ret;
|
|
unsigned int i, *val;
|
|
int num;
|
|
|
|
*plst = NULL;
|
|
prop_ret = NULL;
|
|
if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
|
|
XA_CARDINAL, &type_ret, &format_ret, &num_ret,
|
|
&bytes_after, &prop_ret) != Success)
|
|
return -1;
|
|
|
|
if (type_ret != XA_CARDINAL || format_ret != 32)
|
|
{
|
|
num = -1;
|
|
}
|
|
else if (num_ret == 0 || !prop_ret)
|
|
{
|
|
num = 0;
|
|
}
|
|
else
|
|
{
|
|
val = (unsigned int *)malloc(num_ret * sizeof(unsigned int));
|
|
for (i = 0; i < num_ret; i++)
|
|
val[i] = ((unsigned long *)prop_ret)[i];
|
|
num = num_ret;
|
|
*plst = val;
|
|
}
|
|
if (prop_ret)
|
|
XFree(prop_ret);
|
|
|
|
return num;
|
|
}
|
|
|
|
#endif /* USE_ECORE_X */
|
|
|
|
/*
|
|
* Set simple string list property
|
|
*/
|
|
void
|
|
ecore_x_window_prop_string_list_set(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
char **lst, int num)
|
|
{
|
|
XTextProperty xtp;
|
|
|
|
if (XmbTextListToTextProperty(_ecore_x_disp, lst, num,
|
|
XStdICCTextStyle, &xtp) != Success)
|
|
return;
|
|
XSetTextProperty(_ecore_x_disp, win, &xtp, atom);
|
|
XFree(xtp.value);
|
|
}
|
|
|
|
/*
|
|
* Get simple string list property
|
|
*
|
|
* If the property was successfully fetched the number of items stored in
|
|
* lst is returned, otherwise -1 is returned.
|
|
* Note: Return value 0 means that the property exists but has no elements.
|
|
*/
|
|
int
|
|
ecore_x_window_prop_string_list_get(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
char ***plst)
|
|
{
|
|
char **pstr = NULL;
|
|
XTextProperty xtp;
|
|
int i, items;
|
|
char **list;
|
|
Status s;
|
|
|
|
*plst = NULL;
|
|
|
|
if (!XGetTextProperty(_ecore_x_disp, win, &xtp, atom))
|
|
return -1;
|
|
|
|
if (xtp.format == 8)
|
|
{
|
|
s = XmbTextPropertyToTextList(_ecore_x_disp, &xtp, &list, &items);
|
|
if (s == Success)
|
|
{
|
|
if (items > 0)
|
|
{
|
|
pstr = (char **)malloc(items * sizeof(char *));
|
|
for (i = 0; i < items; i++)
|
|
pstr[i] = (list[i] && (*list[i] || i < items - 1)) ?
|
|
strdup(list[i]) : NULL;
|
|
}
|
|
if (list)
|
|
XFreeStringList(list);
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
/* Bad format or XmbTextPropertyToTextList failed - Now what? */
|
|
pstr = (char **)malloc(sizeof(char *));
|
|
pstr[0] = (xtp.value) ? strdup((char *)xtp.value) : NULL;
|
|
items = 1;
|
|
|
|
done:
|
|
XFree(xtp.value);
|
|
|
|
*plst = pstr;
|
|
return items;
|
|
}
|
|
|
|
#ifndef USE_ECORE_X
|
|
|
|
/*
|
|
* Set simple string property
|
|
*/
|
|
void
|
|
ecore_x_window_prop_string_set(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
const char *str)
|
|
{
|
|
ecore_x_window_prop_string_list_set(win, atom, (char **)(&str), 1);
|
|
}
|
|
|
|
/*
|
|
* Get simple string property
|
|
*/
|
|
char *
|
|
ecore_x_window_prop_string_get(Ecore_X_Window win, Ecore_X_Atom atom)
|
|
{
|
|
XTextProperty xtp;
|
|
char *str;
|
|
int items;
|
|
char **list;
|
|
Status s;
|
|
|
|
if (!XGetTextProperty(_ecore_x_disp, win, &xtp, atom))
|
|
return NULL;
|
|
|
|
if (xtp.format == 8)
|
|
{
|
|
s = XmbTextPropertyToTextList(_ecore_x_disp, &xtp, &list, &items);
|
|
if ((s == Success) && (items > 0))
|
|
{
|
|
str = (*list) ? strdup(*list) : NULL;
|
|
XFreeStringList(list);
|
|
}
|
|
else
|
|
str = (xtp.value) ? strdup((char *)xtp.value) : NULL;
|
|
}
|
|
else
|
|
str = (xtp.value) ? strdup((char *)xtp.value) : NULL;
|
|
|
|
XFree(xtp.value);
|
|
|
|
return str;
|
|
}
|
|
|
|
/*
|
|
* Set UTF-8 string property
|
|
*/
|
|
static void
|
|
_ecore_x_window_prop_string_utf8_set(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
const char *str)
|
|
{
|
|
XChangeProperty(_ecore_x_disp, win, atom, ECORE_X_ATOM_UTF8_STRING, 8,
|
|
PropModeReplace, (unsigned char *)str, strlen(str));
|
|
}
|
|
|
|
/*
|
|
* Get UTF-8 string property
|
|
*/
|
|
static char *
|
|
_ecore_x_window_prop_string_utf8_get(Ecore_X_Window win, Ecore_X_Atom atom)
|
|
{
|
|
char *str;
|
|
unsigned char *prop_ret;
|
|
Atom type_ret;
|
|
unsigned long bytes_after, num_ret;
|
|
int format_ret;
|
|
|
|
str = NULL;
|
|
prop_ret = NULL;
|
|
XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
|
|
ECORE_X_ATOM_UTF8_STRING, &type_ret,
|
|
&format_ret, &num_ret, &bytes_after, &prop_ret);
|
|
if (prop_ret && num_ret > 0 && format_ret == 8)
|
|
{
|
|
str = (char *)malloc(num_ret + 1);
|
|
if (str)
|
|
{
|
|
memcpy(str, prop_ret, num_ret);
|
|
str[num_ret] = '\0';
|
|
}
|
|
}
|
|
if (prop_ret)
|
|
XFree(prop_ret);
|
|
|
|
return str;
|
|
}
|
|
|
|
/*
|
|
* Set X ID (array) property
|
|
*/
|
|
void
|
|
ecore_x_window_prop_xid_set(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
Ecore_X_Atom type, Ecore_X_ID * lst,
|
|
unsigned int num)
|
|
{
|
|
#if SIZEOF_INT == SIZEOF_LONG
|
|
XChangeProperty(_ecore_x_disp, win, atom, type, 32, PropModeReplace,
|
|
(unsigned char *)lst, num);
|
|
#else
|
|
unsigned long *pl;
|
|
unsigned int i;
|
|
|
|
pl = malloc(num * sizeof(long));
|
|
if (!pl)
|
|
return;
|
|
for (i = 0; i < num; i++)
|
|
pl[i] = lst[i];
|
|
XChangeProperty(_ecore_x_disp, win, atom, type, 32, PropModeReplace,
|
|
(unsigned char *)pl, num);
|
|
free(pl);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
int
|
|
ecore_x_window_prop_xid_get(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
Ecore_X_Atom type, Ecore_X_ID * lst,
|
|
unsigned int len)
|
|
{
|
|
unsigned char *prop_ret;
|
|
Atom type_ret;
|
|
unsigned long bytes_after, num_ret;
|
|
int format_ret;
|
|
int num;
|
|
unsigned i;
|
|
|
|
prop_ret = NULL;
|
|
if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
|
|
type, &type_ret, &format_ret, &num_ret,
|
|
&bytes_after, &prop_ret) != Success)
|
|
return -1;
|
|
|
|
if (type_ret != type || format_ret != 32)
|
|
{
|
|
num = -1;
|
|
}
|
|
else if (num_ret == 0 || !prop_ret)
|
|
{
|
|
num = 0;
|
|
}
|
|
else
|
|
{
|
|
if (num_ret < len)
|
|
len = num_ret;
|
|
for (i = 0; i < len; i++)
|
|
lst[i] = ((unsigned long *)prop_ret)[i];
|
|
num = len;
|
|
}
|
|
if (prop_ret)
|
|
XFree(prop_ret);
|
|
|
|
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.
|
|
*/
|
|
int
|
|
ecore_x_window_prop_xid_list_get(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
Ecore_X_Atom type, Ecore_X_ID ** val)
|
|
{
|
|
unsigned char *prop_ret;
|
|
Atom type_ret;
|
|
unsigned long bytes_after, num_ret;
|
|
int format_ret;
|
|
Ecore_X_Atom *alst;
|
|
int num;
|
|
unsigned i;
|
|
|
|
*val = NULL;
|
|
prop_ret = NULL;
|
|
if (XGetWindowProperty(_ecore_x_disp, win, atom, 0, 0x7fffffff, False,
|
|
type, &type_ret, &format_ret, &num_ret,
|
|
&bytes_after, &prop_ret) != Success)
|
|
return -1;
|
|
|
|
if (type_ret != type || format_ret != 32)
|
|
{
|
|
num = -1;
|
|
}
|
|
else if (num_ret == 0 || !prop_ret)
|
|
{
|
|
num = 0;
|
|
}
|
|
else
|
|
{
|
|
alst = (Ecore_X_Atom *) malloc(num_ret * sizeof(Ecore_X_ID));
|
|
for (i = 0; i < num_ret; i++)
|
|
alst[i] = ((unsigned long *)prop_ret)[i];
|
|
num = num_ret;
|
|
*val = alst;
|
|
}
|
|
if (prop_ret)
|
|
XFree(prop_ret);
|
|
|
|
return num;
|
|
}
|
|
|
|
/*
|
|
* Remove/add/toggle X ID list item.
|
|
*/
|
|
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, 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 = (Ecore_X_ID *) 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
|
|
*/
|
|
void
|
|
ecore_x_window_prop_atom_set(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
Ecore_X_Atom * lst, unsigned int num)
|
|
{
|
|
ecore_x_window_prop_xid_set(win, atom, XA_ATOM, lst, num);
|
|
}
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
int
|
|
ecore_x_window_prop_atom_get(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
Ecore_X_Atom * lst, unsigned int len)
|
|
{
|
|
return ecore_x_window_prop_xid_get(win, atom, XA_ATOM, lst, 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.
|
|
*/
|
|
int
|
|
ecore_x_window_prop_atom_list_get(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
Ecore_X_Atom ** plst)
|
|
{
|
|
return ecore_x_window_prop_xid_list_get(win, atom, XA_ATOM, plst);
|
|
}
|
|
|
|
/*
|
|
* Remove/add/toggle atom list item.
|
|
*/
|
|
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, XA_ATOM, item, op);
|
|
}
|
|
|
|
/*
|
|
* Set Window (array) property
|
|
*/
|
|
void
|
|
ecore_x_window_prop_window_set(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
Ecore_X_Window * lst, unsigned int num)
|
|
{
|
|
ecore_x_window_prop_xid_set(win, atom, XA_WINDOW, lst, num);
|
|
}
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
int
|
|
ecore_x_window_prop_window_get(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
Ecore_X_Window * lst, unsigned int len)
|
|
{
|
|
return ecore_x_window_prop_xid_get(win, atom, XA_WINDOW, lst, 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.
|
|
*/
|
|
int
|
|
ecore_x_window_prop_window_list_get(Ecore_X_Window win, Ecore_X_Atom atom,
|
|
Ecore_X_Window ** plst)
|
|
{
|
|
return ecore_x_window_prop_xid_list_get(win, atom, XA_WINDOW, plst);
|
|
}
|
|
|
|
#endif /* USE_ECORE_X */
|
|
|
|
#ifndef USE_ECORE_X
|
|
/*
|
|
* ICCCM stuff
|
|
*/
|
|
|
|
static const char *const atoms_icccm_names[] = {
|
|
/* *INDENT-OFF* */
|
|
|
|
/* ICCCM */
|
|
"WM_STATE",
|
|
"WM_WINDOW_ROLE",
|
|
"WM_CLIENT_LEADER",
|
|
"WM_COLORMAP_WINDOWS",
|
|
"WM_CHANGE_STATE",
|
|
"WM_PROTOCOLS",
|
|
"WM_DELETE_WINDOW",
|
|
"WM_TAKE_FOCUS",
|
|
#if 0
|
|
"WM_SAVE_YOURSELF",
|
|
#endif
|
|
|
|
/* Misc. */
|
|
"UTF8_STRING",
|
|
|
|
/* *INDENT-ON* */
|
|
};
|
|
unsigned int atoms_icccm[CHECK_COUNT_ICCCM];
|
|
|
|
void
|
|
ecore_x_icccm_init(void)
|
|
{
|
|
#if DEBUG_CHECK
|
|
assert(CHECK_COUNT_ICCCM == N_ITEMS(atoms_icccm));
|
|
#endif
|
|
AtomListIntern(atoms_icccm_names, N_ITEMS(atoms_icccm), atoms_icccm);
|
|
}
|
|
|
|
static void
|
|
ecore_x_icccm_state_set(Ecore_X_Window win, unsigned int state)
|
|
{
|
|
unsigned long c[2];
|
|
|
|
c[0] = state;
|
|
c[1] = 0;
|
|
XChangeProperty(_ecore_x_disp, win, ECORE_X_ATOM_WM_STATE,
|
|
ECORE_X_ATOM_WM_STATE, 32, PropModeReplace,
|
|
(unsigned char *)c, 2);
|
|
}
|
|
|
|
void
|
|
ecore_x_icccm_state_set_iconic(Ecore_X_Window win)
|
|
{
|
|
ecore_x_icccm_state_set(win, IconicState);
|
|
}
|
|
|
|
void
|
|
ecore_x_icccm_state_set_normal(Ecore_X_Window win)
|
|
{
|
|
ecore_x_icccm_state_set(win, NormalState);
|
|
}
|
|
|
|
void
|
|
ecore_x_icccm_state_set_withdrawn(Ecore_X_Window win)
|
|
{
|
|
ecore_x_icccm_state_set(win, WithdrawnState);
|
|
}
|
|
|
|
static void
|
|
ecore_x_icccm_client_message_send(Ecore_X_Window win,
|
|
Ecore_X_Atom atom, Ecore_X_Time ts)
|
|
{
|
|
ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS, NoEventMask,
|
|
atom, ts, 0, 0, 0);
|
|
}
|
|
|
|
void
|
|
ecore_x_icccm_delete_window_send(Ecore_X_Window win, Ecore_X_Time ts)
|
|
{
|
|
ecore_x_icccm_client_message_send(win, ECORE_X_ATOM_WM_DELETE_WINDOW, ts);
|
|
}
|
|
|
|
void
|
|
ecore_x_icccm_take_focus_send(Ecore_X_Window win, Ecore_X_Time ts)
|
|
{
|
|
ecore_x_icccm_client_message_send(win, ECORE_X_ATOM_WM_TAKE_FOCUS, ts);
|
|
}
|
|
|
|
#if 0
|
|
void
|
|
ecore_x_icccm_save_yourself_send(Ecore_X_Window win, Ecore_X_Time ts)
|
|
{
|
|
ecore_x_icccm_client_message_send(win, ECORE_X_ATOM_WM_SAVE_YOURSELF, ts);
|
|
}
|
|
#endif
|
|
|
|
void
|
|
ecore_x_icccm_title_set(Ecore_X_Window win, const char *title)
|
|
{
|
|
ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_NAME, title);
|
|
}
|
|
|
|
char *
|
|
ecore_x_icccm_title_get(Ecore_X_Window win)
|
|
{
|
|
return ecore_x_window_prop_string_get(win, ECORE_X_ATOM_WM_NAME);
|
|
}
|
|
|
|
void
|
|
ecore_x_icccm_name_class_set(Ecore_X_Window win, const char *name,
|
|
const char *clss)
|
|
{
|
|
XClassHint *xch;
|
|
|
|
xch = XAllocClassHint();
|
|
if (!xch)
|
|
return;
|
|
xch->res_name = (char *)name;
|
|
xch->res_class = (char *)clss;
|
|
XSetClassHint(_ecore_x_disp, win, xch);
|
|
XFree(xch);
|
|
}
|
|
|
|
void
|
|
ecore_x_icccm_name_class_get(Ecore_X_Window win, char **name, char **clss)
|
|
{
|
|
XClassHint xch;
|
|
|
|
*name = *clss = NULL;
|
|
xch.res_name = NULL;
|
|
xch.res_class = NULL;
|
|
if (XGetClassHint(_ecore_x_disp, win, &xch))
|
|
{
|
|
if (name && xch.res_name)
|
|
*name = strdup(xch.res_name);
|
|
if (clss && xch.res_class)
|
|
*clss = strdup(xch.res_class);
|
|
XFree(xch.res_name);
|
|
XFree(xch.res_class);
|
|
}
|
|
}
|
|
|
|
#endif /* USE_ECORE_X */
|
|
|
|
#ifndef USE_ECORE_X
|
|
/*
|
|
* _NET_WM hints (EWMH)
|
|
*/
|
|
|
|
static const char *const atoms_netwm_names[] = {
|
|
/* *INDENT-OFF* */
|
|
|
|
/* Window manager info */
|
|
"_NET_SUPPORTED",
|
|
"_NET_SUPPORTING_WM_CHECK",
|
|
|
|
/* Desktop status/requests */
|
|
"_NET_NUMBER_OF_DESKTOPS",
|
|
"_NET_VIRTUAL_ROOTS",
|
|
"_NET_DESKTOP_GEOMETRY",
|
|
"_NET_DESKTOP_NAMES",
|
|
"_NET_DESKTOP_VIEWPORT",
|
|
"_NET_WORKAREA",
|
|
"_NET_CURRENT_DESKTOP",
|
|
"_NET_SHOWING_DESKTOP",
|
|
|
|
"_NET_ACTIVE_WINDOW",
|
|
"_NET_CLIENT_LIST",
|
|
"_NET_CLIENT_LIST_STACKING",
|
|
|
|
/* Client window props/client messages */
|
|
"_NET_WM_NAME",
|
|
"_NET_WM_VISIBLE_NAME",
|
|
"_NET_WM_ICON_NAME",
|
|
"_NET_WM_VISIBLE_ICON_NAME",
|
|
|
|
"_NET_WM_DESKTOP",
|
|
|
|
"_NET_WM_WINDOW_TYPE",
|
|
"_NET_WM_WINDOW_TYPE_DESKTOP",
|
|
"_NET_WM_WINDOW_TYPE_DOCK",
|
|
"_NET_WM_WINDOW_TYPE_TOOLBAR",
|
|
"_NET_WM_WINDOW_TYPE_MENU",
|
|
"_NET_WM_WINDOW_TYPE_UTILITY",
|
|
"_NET_WM_WINDOW_TYPE_SPLASH",
|
|
"_NET_WM_WINDOW_TYPE_DIALOG",
|
|
"_NET_WM_WINDOW_TYPE_NORMAL",
|
|
|
|
"_NET_WM_STATE",
|
|
"_NET_WM_STATE_MODAL",
|
|
"_NET_WM_STATE_STICKY",
|
|
"_NET_WM_STATE_MAXIMIZED_VERT",
|
|
"_NET_WM_STATE_MAXIMIZED_HORZ",
|
|
"_NET_WM_STATE_SHADED",
|
|
"_NET_WM_STATE_SKIP_TASKBAR",
|
|
"_NET_WM_STATE_SKIP_PAGER",
|
|
"_NET_WM_STATE_HIDDEN",
|
|
"_NET_WM_STATE_FULLSCREEN",
|
|
"_NET_WM_STATE_ABOVE",
|
|
"_NET_WM_STATE_BELOW",
|
|
"_NET_WM_STATE_DEMANDS_ATTENTION",
|
|
|
|
"_NET_WM_ALLOWED_ACTIONS",
|
|
"_NET_WM_ACTION_MOVE",
|
|
"_NET_WM_ACTION_RESIZE",
|
|
"_NET_WM_ACTION_MINIMIZE",
|
|
"_NET_WM_ACTION_SHADE",
|
|
"_NET_WM_ACTION_STICK",
|
|
"_NET_WM_ACTION_MAXIMIZE_HORZ",
|
|
"_NET_WM_ACTION_MAXIMIZE_VERT",
|
|
"_NET_WM_ACTION_FULLSCREEN",
|
|
"_NET_WM_ACTION_CHANGE_DESKTOP",
|
|
"_NET_WM_ACTION_CLOSE",
|
|
"_NET_WM_ACTION_ABOVE",
|
|
"_NET_WM_ACTION_BELOW",
|
|
|
|
"_NET_WM_STRUT",
|
|
"_NET_WM_STRUT_PARTIAL",
|
|
|
|
"_NET_FRAME_EXTENTS",
|
|
|
|
"_NET_WM_ICON",
|
|
|
|
"_NET_WM_USER_TIME",
|
|
|
|
#if 0 /* Not used */
|
|
"_NET_WM_ICON_GEOMETRY",
|
|
"_NET_WM_PID",
|
|
"_NET_WM_HANDLED_ICONS",
|
|
|
|
"_NET_WM_PING",
|
|
#endif
|
|
"_NET_WM_SYNC_REQUEST",
|
|
"_NET_WM_SYNC_REQUEST_COUNTER",
|
|
|
|
"_NET_WM_WINDOW_OPACITY",
|
|
|
|
/* Misc window ops */
|
|
"_NET_CLOSE_WINDOW",
|
|
"_NET_MOVERESIZE_WINDOW",
|
|
"_NET_WM_MOVERESIZE",
|
|
"_NET_RESTACK_WINDOW",
|
|
|
|
#if 0 /* Not yet implemented */
|
|
"_NET_REQUEST_FRAME_EXTENTS",
|
|
#endif
|
|
|
|
/* Startup notification */
|
|
"_NET_STARTUP_ID",
|
|
"_NET_STARTUP_INFO_BEGIN",
|
|
"_NET_STARTUP_INFO",
|
|
|
|
/* *INDENT-ON* */
|
|
};
|
|
unsigned int atoms_netwm[CHECK_COUNT_NETWM];
|
|
|
|
void
|
|
ecore_x_netwm_init(void)
|
|
{
|
|
#if DEBUG_CHECK
|
|
assert(CHECK_COUNT_NETWM == N_ITEMS(atoms_netwm));
|
|
#endif
|
|
AtomListIntern(atoms_netwm_names, N_ITEMS(atoms_netwm), atoms_netwm);
|
|
}
|
|
|
|
/*
|
|
* WM identification
|
|
*/
|
|
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);
|
|
}
|
|
|
|
/*
|
|
* Desktop configuration and status
|
|
*/
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
void
|
|
ecore_x_netwm_desk_names_set(Ecore_X_Window root, const char **names,
|
|
unsigned int n_desks)
|
|
{
|
|
char ss[32], *buf;
|
|
const char *s;
|
|
unsigned int i;
|
|
int l, len;
|
|
|
|
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 = (char *)realloc(buf, len + l);
|
|
memcpy(buf + len, s, l);
|
|
len += l;
|
|
}
|
|
|
|
XChangeProperty(_ecore_x_disp, root, ECORE_X_ATOM_NET_DESKTOP_NAMES,
|
|
ECORE_X_ATOM_UTF8_STRING, 8, PropModeReplace,
|
|
(unsigned char *)buf, len);
|
|
|
|
free(buf);
|
|
}
|
|
|
|
void
|
|
ecore_x_netwm_desk_size_set(Ecore_X_Window root, unsigned int width,
|
|
unsigned int height)
|
|
{
|
|
unsigned int size[2];
|
|
|
|
size[0] = width;
|
|
size[1] = height;
|
|
ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_DESKTOP_GEOMETRY, size,
|
|
2);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
void
|
|
ecore_x_netwm_showing_desktop_set(Ecore_X_Window root, int on)
|
|
{
|
|
unsigned int val;
|
|
|
|
val = (on) ? 1 : 0;
|
|
ecore_x_window_prop_card32_set(root, ECORE_X_ATOM_NET_SHOWING_DESKTOP, &val,
|
|
1);
|
|
}
|
|
|
|
/*
|
|
* Client status
|
|
*/
|
|
|
|
/* Mapping order */
|
|
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);
|
|
}
|
|
|
|
/* Stacking order */
|
|
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);
|
|
}
|
|
|
|
void
|
|
ecore_x_netwm_client_active_set(Ecore_X_Window root, Ecore_X_Window win)
|
|
{
|
|
ecore_x_window_prop_window_set(root, ECORE_X_ATOM_NET_ACTIVE_WINDOW, &win,
|
|
1);
|
|
}
|
|
|
|
/*
|
|
* Client window properties
|
|
*/
|
|
|
|
void
|
|
ecore_x_netwm_name_set(Ecore_X_Window win, const char *name)
|
|
{
|
|
_ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_NAME, name);
|
|
}
|
|
|
|
int
|
|
ecore_x_netwm_name_get(Ecore_X_Window win, char **name)
|
|
{
|
|
char *s;
|
|
|
|
s = _ecore_x_window_prop_string_utf8_get(win, ECORE_X_ATOM_NET_WM_NAME);
|
|
*name = s;
|
|
|
|
return s != NULL;
|
|
}
|
|
|
|
void
|
|
ecore_x_netwm_visible_name_set(Ecore_X_Window win, const char *name)
|
|
{
|
|
_ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_VISIBLE_NAME,
|
|
name);
|
|
}
|
|
|
|
int
|
|
ecore_x_netwm_visible_name_get(Ecore_X_Window win, char **name)
|
|
{
|
|
char *s;
|
|
|
|
s = _ecore_x_window_prop_string_utf8_get(win,
|
|
ECORE_X_ATOM_NET_WM_VISIBLE_NAME);
|
|
*name = s;
|
|
|
|
return s != NULL;
|
|
}
|
|
|
|
void
|
|
ecore_x_netwm_icon_name_set(Ecore_X_Window win, const char *name)
|
|
{
|
|
_ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_WM_ICON_NAME,
|
|
name);
|
|
}
|
|
|
|
int
|
|
ecore_x_netwm_icon_name_get(Ecore_X_Window win, char **name)
|
|
{
|
|
char *s;
|
|
|
|
s = _ecore_x_window_prop_string_utf8_get(win, ECORE_X_ATOM_NET_WM_ICON_NAME);
|
|
*name = s;
|
|
|
|
return s != NULL;
|
|
}
|
|
|
|
void
|
|
ecore_x_netwm_visible_icon_name_set(Ecore_X_Window win, const char *name)
|
|
{
|
|
_ecore_x_window_prop_string_utf8_set(win,
|
|
ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME,
|
|
name);
|
|
}
|
|
|
|
int
|
|
ecore_x_netwm_visible_icon_name_get(Ecore_X_Window win, char **name)
|
|
{
|
|
char *s;
|
|
|
|
s = _ecore_x_window_prop_string_utf8_get(win,
|
|
ECORE_X_ATOM_NET_WM_VISIBLE_ICON_NAME);
|
|
*name = s;
|
|
|
|
return s != NULL;
|
|
}
|
|
|
|
void
|
|
ecore_x_netwm_desktop_set(Ecore_X_Window win, unsigned int desk)
|
|
{
|
|
ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_DESKTOP, &desk, 1);
|
|
}
|
|
|
|
int
|
|
ecore_x_netwm_desktop_get(Ecore_X_Window win, unsigned int *desk)
|
|
{
|
|
return ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_DESKTOP,
|
|
desk, 1);
|
|
}
|
|
|
|
int
|
|
ecore_x_netwm_user_time_get(Ecore_X_Window win, unsigned int *ts)
|
|
{
|
|
return ecore_x_window_prop_card32_get(win, ECORE_X_ATOM_NET_WM_USER_TIME,
|
|
ts, 1);
|
|
}
|
|
|
|
void
|
|
ecore_x_netwm_opacity_set(Ecore_X_Window win, unsigned int opacity)
|
|
{
|
|
ecore_x_window_prop_card32_set(win, ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
|
|
&opacity, 1);
|
|
}
|
|
|
|
int
|
|
ecore_x_netwm_opacity_get(Ecore_X_Window win, unsigned int *opacity)
|
|
{
|
|
return ecore_x_window_prop_card32_get(win,
|
|
ECORE_X_ATOM_NET_WM_WINDOW_OPACITY,
|
|
opacity, 1);
|
|
}
|
|
|
|
#if 0 /* Not used */
|
|
void
|
|
ecore_x_netwm_startup_id_set(Ecore_X_Window win, const char *id)
|
|
{
|
|
_ecore_x_window_prop_string_utf8_set(win, ECORE_X_ATOM_NET_STARTUP_ID, id);
|
|
}
|
|
#endif
|
|
|
|
int
|
|
ecore_x_netwm_startup_id_get(Ecore_X_Window win, char **id)
|
|
{
|
|
char *s;
|
|
|
|
s = _ecore_x_window_prop_string_utf8_get(win, ECORE_X_ATOM_NET_STARTUP_ID);
|
|
*id = s;
|
|
|
|
return s != NULL;
|
|
}
|
|
|
|
#endif /* USE_ECORE_X */
|