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

428 lines
10 KiB
C
Raw Normal View History

/*
* Various ICCCM related functions.
*
* This is ALL the code involving anything ICCCM related. for both WM and
* client.
*/
#include "Ecore.h"
#include "ecore_x_private.h"
#include "Ecore_X.h"
void
ecore_x_icccm_state_set(Ecore_X_Window win, Ecore_X_Window_State_Hint state)
{
unsigned long c[2];
if (state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
c[0] = WithdrawnState;
else if (state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
c[0] = NormalState;
else if (state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
c[0] = IconicState;
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_delete_window_send(Ecore_X_Window win, Ecore_X_Time t)
{
ecore_x_client_message32_send(win, _ecore_x_atom_wm_protocols,
_ecore_x_atom_wm_delete_window,
CurrentTime, 0, 0, 0);
}
void
ecore_x_icccm_take_focus_send(Ecore_X_Window win, Ecore_X_Time t)
{
ecore_x_client_message32_send(win, _ecore_x_atom_wm_protocols,
_ecore_x_atom_wm_take_focus,
CurrentTime, 0, 0, 0);
}
void
ecore_x_icccm_save_yourself_send(Ecore_X_Window win, Ecore_X_Time t)
{
ecore_x_client_message32_send(win, _ecore_x_atom_wm_protocols,
_ecore_x_atom_wm_save_yourself,
CurrentTime, 0, 0, 0);
}
void
ecore_x_icccm_move_resize_send(Ecore_X_Window win,
int x, int y, int w, int h)
{
XEvent ev;
ev.type = ConfigureNotify;
ev.xconfigure.display = _ecore_x_disp;
ev.xconfigure.event = win;
ev.xconfigure.window = win;
ev.xconfigure.x = x;
ev.xconfigure.y = y;
ev.xconfigure.width = w;
ev.xconfigure.height = h;
ev.xconfigure.border_width = 0;
ev.xconfigure.above = win;
ev.xconfigure.override_redirect = False;
XSendEvent(_ecore_x_disp, win, False, StructureNotifyMask, &ev);
}
void
ecore_x_icccm_hints_set(Ecore_X_Window win,
int accepts_focus,
Ecore_X_Window_State_Hint initial_state,
Ecore_X_Pixmap icon_pixmap,
Ecore_X_Pixmap icon_mask,
Ecore_X_Window icon_window,
Ecore_X_Window window_group,
int is_urgent)
{
XWMHints *hints;
hints = XAllocWMHints();
if (!hints) return;
hints->flags = InputHint | StateHint;
hints->input = accepts_focus;
if (initial_state == ECORE_X_WINDOW_STATE_HINT_WITHDRAWN)
hints->initial_state = WithdrawnState;
else if (initial_state == ECORE_X_WINDOW_STATE_HINT_NORMAL)
hints->initial_state = NormalState;
else if (initial_state == ECORE_X_WINDOW_STATE_HINT_ICONIC)
hints->initial_state = IconicState;
if (icon_pixmap != 0)
{
hints->icon_pixmap = icon_pixmap;
hints->flags |= IconPixmapHint;
}
if (icon_mask != 0)
{
hints->icon_mask = icon_mask;
hints->flags |= IconMaskHint;
}
if (icon_window != 0)
{
hints->icon_window = icon_window;
hints->flags |= IconWindowHint;
}
if (window_group != 0)
{
hints->window_group = window_group;
hints->flags |= WindowGroupHint;
}
if (is_urgent)
hints->flags |= XUrgencyHint;
XSetWMHints(_ecore_x_disp, win, hints);
XFree(hints);
}
int
ecore_x_icccm_hints_get(Ecore_X_Window win,
int *accepts_focus,
Ecore_X_Window_State_Hint *initial_state,
Ecore_X_Pixmap *icon_pixmap,
Ecore_X_Pixmap *icon_mask,
Ecore_X_Window *icon_window,
Ecore_X_Window *window_group,
int *is_urgent)
{
XWMHints *hints;
if (accepts_focus) *accepts_focus = 0;
if (initial_state) *initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
if (icon_pixmap) *icon_pixmap = 0;
if (icon_mask) *icon_mask = 0;
if (icon_window) *icon_window = 0;
if (window_group) *window_group = 0;
if (is_urgent) *is_urgent = 0;
hints = XGetWMHints(_ecore_x_disp, win);
if (hints)
{
if ((hints->flags & InputHint) && (accepts_focus))
{
if (hints->input)
*accepts_focus = 1;
else
*accepts_focus = 0;
}
if ((hints->flags & StateHint) && (initial_state))
{
if (hints->initial_state == WithdrawnState)
*initial_state = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
else if (hints->initial_state == NormalState)
*initial_state = ECORE_X_WINDOW_STATE_HINT_NORMAL;
else if (hints->initial_state == IconicState)
*initial_state = ECORE_X_WINDOW_STATE_HINT_ICONIC;
}
if ((hints->flags & IconPixmapHint) && (icon_pixmap))
{
*icon_pixmap = hints->icon_pixmap;
}
if ((hints->flags & IconMaskHint) && (icon_mask))
{
*icon_mask = hints->icon_pixmap;
}
if ((hints->flags & IconWindowHint) && (icon_window))
{
*icon_window = hints->icon_window;
}
if ((hints->flags & WindowGroupHint) && (window_group))
{
*window_group = hints->window_group;
}
if ((hints->flags & XUrgencyHint) && (is_urgent))
{
*is_urgent = 1;
}
XFree(hints);
return 1;
}
return 0;
}
2004-11-01 20:03:27 -08:00
void
ecore_x_icccm_size_pos_hints_set(Ecore_X_Window win,
int request_pos,
Ecore_X_Gravity gravity,
int min_w, int min_h,
int max_w, int max_h,
int base_w, int base_h,
int step_x, int step_y,
double min_aspect,
double max_aspect)
{
/* FIXME: working here */
XSizeHints hint;
hint.flags = 0;
if (request_pos)
{
hint.flags |= USPosition;
}
if (gravity != ECORE_X_GRAVITY_NW)
{
hint.flags |= PWinGravity;
hint.win_gravity = gravity;
}
if ((min_w > 0) || (min_h > 0))
{
hint.flags |= PMinSize;
hint.min_width = min_w;
hint.min_height = min_h;
}
if ((max_w > 0) || (max_h > 0))
{
hint.flags |= PMaxSize;
hint.max_width = max_w;
hint.max_height = max_h;
}
if ((base_w > 0) || (base_h > 0))
{
hint.flags |= PBaseSize;
hint.base_width = base_w;
hint.base_height = base_h;
}
if ((step_x > 1) || (step_y > 1))
{
hint.flags |= PResizeInc;
hint.width_inc = step_x;
hint.height_inc = step_y;
}
if ((min_aspect > 0.0) || (max_aspect > 0.0))
{
hint.flags |= PAspect;
hint.min_aspect.x = min_aspect * 10000;
hint.min_aspect.x = 10000;
hint.max_aspect.x = max_aspect * 10000;
hint.max_aspect.x = 10000;
}
XSetWMNormalHints(_ecore_x_disp, win, &hint);
}
int
2004-11-01 20:03:27 -08:00
ecore_x_icccm_size_pos_hints_get(Ecore_X_Window win,
int *request_pos,
Ecore_X_Gravity *gravity,
int *min_w, int *min_h,
int *max_w, int *max_h,
int *base_w, int *base_h,
int *step_x, int *step_y,
double *min_aspect,
double *max_aspect)
{
XSizeHints hint;
long mask;
2004-11-01 20:03:27 -08:00
int minw = 0, minh = 0;
int maxw = 32767, maxh = 32767;
int basew = 0, baseh = 0;
int stepx = 1, stepy = 1;
double mina = 0.0, maxa = 0.0;
if (XGetWMNormalHints(_ecore_x_disp, win, &hint, &mask) < Success) return 0;
if ((hint.flags & USPosition) || ((hint.flags & PPosition)))
{
if (request_pos) *request_pos = 1;
}
else
{
if (request_pos) *request_pos = 0;
}
2004-11-01 20:03:27 -08:00
if (hint.flags & PWinGravity)
{
if (gravity) *gravity = hint.win_gravity;
}
2004-11-01 20:03:27 -08:00
else
{
if (gravity) *gravity = ECORE_X_GRAVITY_NW;
}
2004-11-01 20:03:27 -08:00
if (hint.flags & PMinSize)
{
minw = hint.min_width;
minh = hint.min_height;
}
if (hint.flags & PMaxSize)
{
2004-11-01 20:03:27 -08:00
maxw = hint.max_width;
maxh = hint.max_height;
if (maxw < minw) maxw = minw;
if (maxh < minh) maxh = minh;
}
if (hint.flags & PBaseSize)
{
2004-11-01 20:03:27 -08:00
basew = hint.base_width;
baseh = hint.base_height;
if (basew > minw) minw = basew;
if (baseh > minh) minh = baseh;
}
2004-11-01 20:03:27 -08:00
if (hint.flags & PResizeInc)
{
2004-11-01 20:03:27 -08:00
stepx = hint.width_inc;
stepy = hint.height_inc;
if (stepx < 1) stepx = 1;
if (stepy < 1) stepy = 1;
}
if (hint.flags & PAspect)
{
2004-11-01 20:03:27 -08:00
if (hint.min_aspect.y > 0)
mina = ((double)hint.min_aspect.x) / ((double)hint.min_aspect.y);
if (hint.max_aspect.y > 0)
maxa = ((double)hint.max_aspect.x) / ((double)hint.max_aspect.y);
}
2004-11-01 20:03:27 -08:00
if (min_w) *min_w = minw;
if (min_h) *min_h = minh;
if (max_w) *max_w = maxw;
if (max_h) *max_h = maxh;
if (base_w) *base_w = basew;
if (base_h) *base_h = baseh;
if (step_x) *step_x = stepx;
if (step_y) *step_y = stepy;
if (min_aspect) *min_aspect = mina;
if (max_aspect) *max_aspect = maxa;
return 1;
}
void
ecore_x_icccm_title_set(Ecore_X_Window win, const char *t)
{
char *list[1];
XTextProperty xprop;
int ret;
#ifdef X_HAVE_UTF8_STRING
list[0] = strdup(t);
ret = Xutf8TextListToTextProperty(_ecore_x_disp, list, 1, XUTF8StringStyle, &xprop);
#else
list[0] = strdup(t);
ret = XmbTextListToTextProperty(_ecore_x_disp, list, 1, XStdICCTextStyle, &xprop);
#endif
if (ret >= Success)
{
XSetWMName(_ecore_x_disp, win, &xprop);
XFree(xprop.value);
}
else
{
if (XStringListToTextProperty(list, 1, &xprop) >= Success)
{
XSetWMName(_ecore_x_disp, win, &xprop);
XFree(xprop.value);
}
}
free(list[0]);
}
char *
ecore_x_icccm_title_get(Ecore_X_Window win)
{
XTextProperty xprop;
if (XGetWMName(_ecore_x_disp, win, &xprop) >= Success)
{
if (xprop.value)
{
char **list = NULL;
char *t = NULL;
int num = 0;
if (xprop.encoding == _ecore_x_atom_string)
{
t = strdup(xprop.value);
}
else if (xprop.encoding == _ecore_x_atom_utf8_string)
{
t = strdup(xprop.value);
}
else
{
int ret;
#ifdef X_HAVE_UTF8_STRING
ret = Xutf8TextPropertyToTextList(_ecore_x_disp, &xprop,
&list, &num);
#else
ret = XmbTextPropertyToTextList(_ecore_x_disp, &xprop,
&list, &num);
#endif
if ((ret == XLocaleNotSupported) ||
(ret == XNoMemory) ||
(ret == XConverterNotFound))
{
t = strdup(xprop.value);
}
else if (ret >= Success)
{
if ((num >= 1) && (list))
{
/* FIXME: convert to utf8 */
t = strdup(list[0]);
}
if (list) XFreeStringList(list);
}
}
XFree(xprop.value);
return t;
}
}
return NULL;
}
/* FIXME: move these things in here as they are icccm related */
/* get/set wm protocols */
/* get/set name/class */
/* get/set machine */
/* get/set command */
/* get/set icon name */
/* get/set colormap windows */
/* get/set window role */
/* get/set client leader */
/* get/set transient for */
/* send iconify request */
2004-11-01 20:03:27 -08:00
/* FIXME: there are older E hints, gnome hints and mwm hints and new netwm */
/* hints. each should go in their own file/section so we know which */
2004-11-01 20:03:27 -08:00
/* is which. also older kde hints too. we should try support as much */
/* as makese sense to support */