344 lines
8.7 KiB
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 */
|