enlightenment/src/icccm.c

533 lines
13 KiB
C

#include "e.h"
#include "border.h"
#include "icccm.h"
#include "util.h"
/* Motif window hints */
#define MWM_HINTS_FUNCTIONS (1L << 0)
#define MWM_HINTS_DECORATIONS (1L << 1)
#define MWM_HINTS_INPUT_MODE (1L << 2)
#define MWM_HINTS_STATUS (1L << 3)
/* bit definitions for MwmHints.functions */
#define MWM_FUNC_ALL (1L << 0)
#define MWM_FUNC_RESIZE (1L << 1)
#define MWM_FUNC_MOVE (1L << 2)
#define MWM_FUNC_MINIMIZE (1L << 3)
#define MWM_FUNC_MAXIMIZE (1L << 4)
#define MWM_FUNC_CLOSE (1L << 5)
/* bit definitions for MwmHints.decorations */
#define MWM_DECOR_ALL (1L << 0)
#define MWM_DECOR_BORDER (1L << 1)
#define MWM_DECOR_RESIZEH (1L << 2)
#define MWM_DECOR_TITLE (1L << 3)
#define MWM_DECOR_MENU (1L << 4)
#define MWM_DECOR_MINIMIZE (1L << 5)
#define MWM_DECOR_MAXIMIZE (1L << 6)
/* bit definitions for MwmHints.inputMode */
#define MWM_INPUT_MODELESS 0
#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
#define MWM_INPUT_SYSTEM_MODAL 2
#define MWM_INPUT_FULL_APPLICATION_MODAL 3
#define PROP_MWM_HINTS_ELEMENTS 5
/* Motif window hints */
typedef struct _mwmhints
{
int flags;
int functions;
int decorations;
int inputMode;
int status;
}
MWMHints;
void
e_icccm_move_resize(Window win, int x, int y, int w, int h)
{
e_window_send_event_move_resize(win, x, y, w, h);
}
void
e_icccm_delete(Window win)
{
static Atom a_wm_delete_window = 0;
static Atom a_wm_protocols = 0;
int *props;
int size;
int del_win = 0;
E_ATOM(a_wm_delete_window, "WM_DELETE_WINDOW");
E_ATOM(a_wm_protocols, "WM_PROTOCOLS");
props = e_window_property_get(win, a_wm_protocols, XA_ATOM, &size);
if (props)
{
int i, num;
num = size / sizeof(int);
for (i = 0; i < num; i++)
{
if (props[i] == (int)a_wm_delete_window) del_win = 1;
}
FREE(props);
}
if (del_win)
{
unsigned int data[5];
data[0] = a_wm_delete_window;
data[1] = CurrentTime;
e_window_send_client_message(win, a_wm_protocols, 32, data);
}
else
{
e_window_kill_client(win);
}
}
void
e_icccm_state_mapped(Window win)
{
static Atom a_wm_state = 0;
unsigned int data[2];
E_ATOM(a_wm_state, "WM_STATE");
data[0] = NormalState;
data[1] = 0;
e_window_property_set(win, a_wm_state, a_wm_state, 32, data, 2);
}
void
e_icccm_state_iconified(Window win)
{
static Atom a_wm_state = 0;
unsigned int data[2];
E_ATOM(a_wm_state, "WM_STATE");
data[0] = IconicState;
data[1] = 0;
e_window_property_set(win, a_wm_state, a_wm_state, 32, data, 2);
}
void
e_icccm_state_withdrawn(Window win)
{
static Atom a_wm_state = 0;
unsigned int data[2];
E_ATOM(a_wm_state, "WM_STATE");
data[0] = WithdrawnState;
data[1] = 0;
e_window_property_set(win, a_wm_state, a_wm_state, 32, data, 2);
}
void
e_icccm_adopt(Window win)
{
e_window_add_to_save_set(win);
}
void
e_icccm_release(Window win)
{
e_window_del_from_save_set(win);
}
void
e_icccm_get_pos_info(Window win, E_Border *b)
{
XSizeHints hint;
int mask;
if (e_window_get_wm_size_hints(win, &hint, &mask))
{
if ((hint.flags & USPosition) || ((hint.flags & PPosition)))
{
int x, y, w, h;
printf("%li %li\n", hint.flags & USPosition, hint.flags & PPosition);
b->client.pos.requested = 1;
b->client.pos.gravity = NorthWestGravity;
if (hint.flags & PWinGravity)
b->client.pos.gravity = hint.win_gravity;
x = y = w = h = 0;
e_window_get_geometry(win, &x, &y, &w, &h);
b->client.pos.x = x;
b->client.pos.y = y;
}
else
{
b->client.pos.requested = 0;
}
}
}
void
e_icccm_get_size_info(Window win, E_Border *b)
{
int base_w, base_h, min_w, min_h, max_w, max_h, grav, step_w, step_h;
double aspect_min, aspect_max;
int mask;
XSizeHints hint;
grav = NorthWestGravity;
mask = 0;
min_w = 0;
min_h = 0;
max_w = 65535;
max_h = 65535;
aspect_min = 0.0;
aspect_max = 999999.0;
step_w = 1;
step_h = 1;
base_w = 0;
base_h = 0;
if (e_window_get_wm_size_hints(win, &hint, &mask))
{
if (hint.flags & PMinSize)
{
min_w = hint.min_width;
min_h = hint.min_height;
}
if (hint.flags & PMaxSize)
{
max_w = hint.max_width;
max_h = hint.max_height;
if (max_w < min_w) max_w = min_w;
if (max_h < min_h) max_h = min_h;
}
if (hint.flags & PResizeInc)
{
step_w = hint.width_inc;
step_h = hint.height_inc;
if (step_w < 1) step_w = 1;
if (step_h < 1) step_h = 1;
}
if (hint.flags & PBaseSize)
{
base_w = hint.base_width;
base_h = hint.base_height;
if (base_w > max_w) max_w = base_w;
if (base_h > max_h) max_h = base_h;
}
else
{
base_w = min_w;
base_h = min_h;
}
if (hint.flags & PAspect)
{
if (hint.min_aspect.y > 0)
aspect_min = ((double)hint.min_aspect.x) / ((double)hint.min_aspect.y);
if (hint.max_aspect.y > 0)
aspect_max = ((double)hint.max_aspect.x) / ((double)hint.max_aspect.y);
}
}
b->client.min.w = min_w;
b->client.min.h = min_h;
b->client.max.w = max_w;
b->client.max.h = max_h;
b->client.base.w = base_w;
b->client.base.h = base_h;
b->client.step.w = step_w;
b->client.step.h = step_h;
b->client.min.aspect = aspect_min;
b->client.max.aspect = aspect_max;
b->changed = 1;
}
void
e_icccm_get_mwm_hints(Window win, E_Border *b)
{
static Atom a_motif_wm_hints = 0;
MWMHints *mwmhints;
int size;
E_ATOM(a_motif_wm_hints, "_MOTIF_WM_HINTS");
mwmhints = e_window_property_get(win, a_motif_wm_hints, a_motif_wm_hints, &size);
if (mwmhints)
{
int num;
num = size / sizeof(int);
if (num < PROP_MWM_HINTS_ELEMENTS)
{
FREE(mwmhints);
return;
}
if (mwmhints->flags & MWM_HINTS_DECORATIONS)
{
b->client.border = 0;
b->client.handles = 0;
b->client.titlebar = 0;
if (mwmhints->decorations & MWM_DECOR_ALL)
{
b->client.border = 1;
b->client.handles = 1;
b->client.titlebar = 1;
}
if (mwmhints->decorations & MWM_DECOR_BORDER) b->client.border = 1;
if (mwmhints->decorations & MWM_DECOR_RESIZEH) b->client.handles = 1;
if (mwmhints->decorations & MWM_DECOR_TITLE) b->client.titlebar = 1;
e_border_apply_border(b);
}
FREE(mwmhints);
}
}
void
e_icccm_get_layer(Window win, E_Border *b)
{
static Atom a_win_layer = 0;
int *props;
int size;
E_ATOM(a_win_layer, "_WIN_LAYER");
props = e_window_property_get(win, a_win_layer, XA_CARDINAL, &size);
if (props)
{
int num;
num = size / sizeof(int);
if (num > 0) b->client.layer = props[0];
FREE(props);
}
}
void
e_icccm_get_title(Window win, E_Border *b)
{
char *title;
title = e_window_get_title(win);
if (b->client.title)
{
if ((title) && (!strcmp(title, b->client.title))) return;
b->changed = 1;
FREE(b->client.title);
}
b->client.title = NULL;
if (title) b->client.title = title;
else e_strdup(b->client.title, "No Title");
}
void
e_icccm_get_class(Window win, E_Border *b)
{
IF_FREE(b->client.name);
IF_FREE(b->client.class);
b->client.name = NULL;
b->client.class = NULL;
e_window_get_name_class(win, &(b->client.name), &(b->client.class));
if (!b->client.name) e_strdup(b->client.name, "Unknown");
if (!b->client.class) e_strdup(b->client.class, "Unknown");
}
void
e_icccm_get_hints(Window win, E_Border *b)
{
e_window_get_hints(win, &(b->client.takes_focus),
&(b->client.initial_state), NULL, NULL, NULL,
&(b->client.group));
}
void
e_icccm_get_machine(Window win, E_Border *b)
{
IF_FREE(b->client.machine);
b->client.machine = NULL;
b->client.machine = e_window_get_machine(win);
}
void
e_icccm_get_command(Window win, E_Border *b)
{
IF_FREE(b->client.command);
b->client.command = NULL;
b->client.command = e_window_get_command(win);
}
void
e_icccm_get_icon_name(Window win, E_Border *b)
{
IF_FREE(b->client.icon_name);
b->client.icon_name = NULL;
b->client.icon_name = e_window_get_icon_name(win);
}
void
e_icccm_get_state(Window win, E_Border *b)
{
}
void
e_icccm_set_frame_size(Window win, int l, int r, int t, int b)
{
static Atom a_e_frame_size = 0;
int props[4];
E_ATOM(a_e_frame_size, "_E_FRAME_SIZE");
props[0] = l;
props[1] = r;
props[2] = t;
props[3] = b;
e_window_property_set(win, a_e_frame_size, XA_CARDINAL, 32, props, 4);
}
void
e_icccm_set_desk_area(Window win, int ax, int ay)
{
static Atom a_win_area = 0;
int props[2];
E_ATOM(a_win_area, "_WIN_AREA");
props[0] = ax;
props[1] = ay;
e_window_property_set(win, a_win_area, XA_CARDINAL, 32, props, 2);
}
void
e_icccm_set_desk_area_size(Window win, int ax, int ay)
{
static Atom a_win_area_count = 0;
int props[2];
E_ATOM(a_win_area_count, "_WIN_AREA_COUNT");
props[0] = ax;
props[1] = ay;
e_window_property_set(win, a_win_area_count, XA_CARDINAL, 32, props, 2);
}
void
e_icccm_set_desk(Window win, int d)
{
static Atom a_win_workspace = 0;
int props[2];
E_ATOM(a_win_workspace, "_WIN_WORKSPACE");
props[0] = d;
e_window_property_set(win, a_win_workspace, XA_CARDINAL, 32, props, 1);
}
int
e_icccm_is_shaped(Window win)
{
int w, h, num;
int shaped = 1;
XRectangle *rect;
e_window_get_geometry(win, NULL, NULL, &w, &h);
rect = e_window_get_shape_rectangles(win, &num);
if (!rect) return 1;
if ((num == 1) &&
(rect[0].x == 0) && (rect[0].y == 0) &&
(rect[0].width == w) && (rect[0].height == h))
shaped = 0;
XFree(rect);
return shaped;
}
void
e_icccm_handle_property_change(Atom a, E_Border *b)
{
static Atom a_wm_normal_hints = 0;
static Atom a_motif_wm_hints = 0;
static Atom a_wm_name = 0;
static Atom a_wm_class = 0;
static Atom a_wm_hints = 0;
static Atom a_wm_client_machine = 0;
static Atom a_wm_command = 0;
static Atom a_wm_icon_name = 0;
static Atom a_wm_state = 0;
E_ATOM(a_wm_normal_hints, "WM_NORMAL_HINTS");
E_ATOM(a_motif_wm_hints, "_MOTIF_WM_HINTS");
E_ATOM(a_wm_name, "WM_NAME");
E_ATOM(a_wm_class, "WM_CLASS");
E_ATOM(a_wm_hints, "WM_HINTS");
E_ATOM(a_wm_client_machine, "WM_CLIENT_MACHINE");
E_ATOM(a_wm_command, "WM_COMMAND");
E_ATOM(a_wm_icon_name, "WM_ICON_NAME");
E_ATOM(a_wm_state, "WM_STATE");
if (a == a_wm_normal_hints) e_icccm_get_size_info(b->win.client, b);
else if (a == a_motif_wm_hints) e_icccm_get_mwm_hints(b->win.client, b);
else if (a == a_wm_name) e_icccm_get_title(b->win.client, b);
else if (a == a_wm_class) e_icccm_get_class(b->win.client, b);
else if (a == a_wm_hints) e_icccm_get_hints(b->win.client, b);
else if (a == a_wm_client_machine) e_icccm_get_machine(b->win.client, b);
else if (a == a_wm_command) e_icccm_get_command(b->win.client, b);
else if (a == a_wm_icon_name) e_icccm_get_icon_name(b->win.client, b);
else if (a == a_wm_state) e_icccm_get_state(b->win.client, b);
}
void
e_icccm_handle_client_message(Ev_Message *e)
{
return;
UN(e);
}
void
e_icccm_advertise_e_compat(void)
{
}
void
e_icccm_advertise_mwm_compat(void)
{
static Atom a_motif_wm_info = 0;
int props[2];
E_ATOM(a_motif_wm_info, "_MOTIF_WM_INFO");
props[0] = 2;
props[0] = e_window_root();
e_window_property_set(0, a_motif_wm_info, a_motif_wm_info, 32, props, 2);
}
void
e_icccm_advertise_gnome_compat(void)
{
static Atom a_win_supporting_wm_check = 0;
static Atom a_win_protocols = 0;
static Atom a_win_wm_name = 0;
static Atom a_win_wm_version = 0;
static Atom a_win_layer = 0;
int props[32];
Window win;
E_ATOM(a_win_protocols, "_WIN_PROTOCOLS");
E_ATOM(a_win_layer, "_WIN_LAYER");
props[0] = a_win_protocols;
e_window_property_set(0, a_win_protocols, XA_ATOM, 32, props, 1);
E_ATOM(a_win_wm_name, "_WIN_WM_NAME");
e_window_property_set(0, a_win_wm_name, XA_STRING, 8, "Enlightenment", strlen("Enlightenment"));
E_ATOM(a_win_wm_version, "_WIN_WM_VERSION");
e_window_property_set(0, a_win_wm_version, XA_STRING, 8, "0.17.0", strlen("0.17.0"));
E_ATOM(a_win_supporting_wm_check, "_WIN_SUPPORTING_WM_CHECK");
win = e_window_override_new(0, 0, 0, 7, 7);
props[0] = win;
e_window_property_set(win, a_win_supporting_wm_check, XA_CARDINAL, 32, props, 1);
e_window_property_set(0, a_win_supporting_wm_check, XA_CARDINAL, 32, props, 1);
}
void
e_icccm_advertise_kde_compat(void)
{
}
void
e_icccm_advertise_net_compat(void)
{
}