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

344 lines
8.7 KiB
C

/*
* 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;
}
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
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;
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)) return 0;
if ((hint.flags & USPosition) || ((hint.flags & PPosition)))
{
if (*request_pos) *request_pos = 1;
}
else
{
if (*request_pos) *request_pos = 0;
}
if (hint.flags & PWinGravity)
{
if (*gravity) *gravity = hint.win_gravity;
}
else
{
if (*gravity) *gravity = ECORE_X_GRAVITY_NW;
}
if (hint.flags & PMinSize)
{
minw = hint.min_width;
minh = hint.min_height;
}
if (hint.flags & PMaxSize)
{
maxw = hint.max_width;
maxh = hint.max_height;
if (maxw < minw) maxw = minw;
if (maxh < minh) maxh = minh;
}
if (hint.flags & PBaseSize)
{
basew = hint.base_width;
baseh = hint.base_height;
if (basew > minw) minw = basew;
if (baseh > minh) minh = baseh;
}
if (hint.flags & PResizeInc)
{
stepx = hint.width_inc;
stepy = hint.height_inc;
if (stepx < 1) stepx = 1;
if (stepy < 1) stepy = 1;
}
if (hint.flags & PAspect)
{
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);
}
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;
}
/* FIXME: move these things in here as they are icccm related */
/* get/set wm protocols */
/* get/set title */
/* 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 */
/* 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 */
/* is which. also older kde hints too. we should try support as much */
/* as makese sense to support */