scx/c/xlib/client.c

484 lines
14 KiB
C

#include "xlib.h"
s48_value scx_Iconify_Window(s48_value display, s48_value w, s48_value scr) {
if (!XIconifyWindow(scx_extract_display(display),
scx_extract_window(w),
s48_extract_integer(scr)))
return S48_FALSE;
return S48_UNSPECIFIC;
}
s48_value scx_Withdraw_Window(s48_value display, s48_value w, s48_value scr) {
if (!XWithdrawWindow(scx_extract_display(display),
scx_extract_window(w),
s48_extract_integer(scr)))
return S48_FALSE;
return S48_UNSPECIFIC;
}
s48_value scx_Reconfigure_Wm_Window(s48_value dpy, s48_value w, s48_value scr,
s48_value conf) {
XWindowChanges WC;
unsigned long mask = scx_extract_window_changes(conf, &WC);
if (!XReconfigureWMWindow(scx_extract_display(dpy),
scx_extract_window(w),
s48_extract_integer(scr),
mask, &WC))
return S48_FALSE;
return S48_UNSPECIFIC;
}
s48_value scx_Get_Wm_Command(s48_value dpy, s48_value w) {
int i, ac;
char** av;
s48_value ret = S48_NULL;
S48_DECLARE_GC_PROTECT(1);
if (!XGetCommand (scx_extract_display(dpy),
scx_extract_window(w),
&av, &ac))
return S48_FALSE;
S48_GC_PROTECT_1(ret);
for (i = ac-1; i >= 0; i--)
ret = s48_cons(s48_enter_string(av[i]), ret);
S48_GC_UNPROTECT();
if (av != NULL) XFreeStringList(av);
return ret;
}
s48_value scx_Set_Wm_Command(s48_value dpy, s48_value w, s48_value cmd) {
int i, n = s48_list_length(cmd);
char *argv[n];
for (i = 0; i < n; i++) {
argv[i] = s48_extract_string(S48_CAR(cmd));
cmd = S48_CDR(cmd);
}
XSetCommand(scx_extract_display(dpy),
scx_extract_window(w),
argv, n);
return S48_UNSPECIFIC;
}
s48_value scx_Get_Wm_Protocols(s48_value display, s48_value w) {
Atom *p;
int i, n;
s48_value ret = S48_NULL;
S48_DECLARE_GC_PROTECT(1);
if (!XGetWMProtocols (scx_extract_display(display),
scx_extract_window(w), &p, &n))
return S48_FALSE;
S48_GC_PROTECT_1(ret);
for (i = n-1; i >= 0; i--)
ret = s48_cons(scx_enter_atom(p[i]), ret);
S48_GC_UNPROTECT();
XFree((char *)p);
return ret;
}
s48_value scx_Set_Wm_Protocols (s48_value display, s48_value w, s48_value v) {
int i, n = s48_list_length(v);
Atom p[n];
for (i = 0; i < n; i++) {
p[i] = scx_extract_atom(S48_CAR(v));
v = S48_CDR(v);
}
if (!XSetWMProtocols (scx_extract_display(display),
scx_extract_window(w),
p, n))
return S48_FALSE;
return S48_UNSPECIFIC;
}
s48_value scx_Get_Wm_Class (s48_value display, s48_value w) {
s48_value ret, x;
XClassHint c;
S48_DECLARE_GC_PROTECT(1);
c.res_name = c.res_class = 0;
if (!XGetClassHint(scx_extract_display(display),
scx_extract_window(w), &c))
return S48_FALSE;
ret = s48_cons(S48_FALSE, S48_FALSE);
S48_GC_PROTECT_1(ret);
S48_SET_CAR(ret, s48_enter_string(c.res_name));
S48_SET_CDR(ret, s48_enter_string(c.res_class));
XFree(c.res_name);
XFree(c.res_class);
S48_GC_UNPROTECT();
return ret;
}
s48_value scx_Set_Wm_Class(s48_value dpy, s48_value w, s48_value name,
s48_value class) {
XClassHint c;
c.res_name = s48_extract_string(name);
c.res_class = s48_extract_string(class);
XSetClassHint(scx_extract_display(dpy),
scx_extract_window(dpy),
&c);
return S48_UNSPECIFIC;
}
#define scx_extract_initial_state(x) S48_EXTRACT_ENUM(x, "scx-initial-state")
#define scx_enter_initial_state(x) S48_ENTER_ENUM(x, "scx-initial-states")
#define scx_extract_wm_hint(x) S48_EXTRACT_ENUM(x, "scx-wm-hint")
#define scx_enter_wm_hint(x) S48_ENTER_ENUM(x, "scx-wm-hints")
s48_value scx_enter_wm_hint_alist(XWMHints* p) {
s48_value res = S48_NULL, t = S48_FALSE;
S48_DECLARE_GC_PROTECT(2);
S48_GC_PROTECT_2(res, t);
if (p->flags & InputHint) {
t = scx_enter_wm_hint(0); t = s48_cons(t, S48_ENTER_BOOLEAN(p->input));
res = s48_cons(t, res);
}
if (p->flags & StateHint) {
t = scx_enter_wm_hint(1);
t = s48_cons(t, scx_enter_initial_state(p->initial_state));
res = s48_cons(t, res);
}
if (p->flags & IconPixmapHint) {
t = scx_enter_wm_hint(2);
t = s48_cons(t, scx_enter_pixmap(p->icon_pixmap));
res = s48_cons(t, res);
}
if (p->flags & IconWindowHint) {
t = scx_enter_wm_hint(3);
t = s48_cons(t, scx_enter_window(p->icon_window));
res = s48_cons(t, res);
}
if (p->flags & IconPositionHint) {
t = s48_enter_integer(p->icon_y);
t = s48_cons(s48_enter_integer(p->icon_x), t);
t = s48_cons(scx_enter_wm_hint(4), t);
res = s48_cons(t, res);
}
if (p->flags & IconMaskHint) {
t = scx_enter_wm_hint(5);
t = s48_cons(t, scx_enter_pixmap(p->icon_mask));
res = s48_cons(t, res);
}
if (p->flags & WindowGroupHint) {
t = scx_enter_wm_hint(6);
t = s48_cons(t, scx_enter_window(p->window_group));
res = s48_cons(t, res);
}
t = scx_enter_wm_hint(8);
t = s48_cons(t, S48_ENTER_BOOLEAN(p->flags & XUrgencyHint));
res = s48_cons(t, res);
S48_GC_UNPROTECT();
return res;
}
void scx_extract_wm_hint_alist(s48_value alist, XWMHints* p) {
p->flags = 0;
while (alist != S48_NULL) {
int h = scx_extract_wm_hint(S48_CAR(S48_CAR(alist)));
s48_value v = S48_CDR(S48_CAR(alist));
p->flags |= (1L << h);
switch (1L << h) {
case InputHint:
p->input = S48_EXTRACT_BOOLEAN(v);
break;
case StateHint:
p->initial_state = scx_extract_initial_state(v);
break;
case IconPixmapHint:
p->icon_pixmap = scx_extract_pixmap(v);
break;
case IconWindowHint:
p->icon_window = scx_extract_window(v);
break;
case IconPositionHint:
p->icon_x = s48_extract_integer(S48_CAR(v));
p->icon_y = s48_extract_integer(S48_CDR(v));
break;
case IconMaskHint:
p->icon_mask = scx_extract_pixmap(v);
break;
case WindowGroupHint:
p->window_group = scx_extract_window(v);
break;
case XUrgencyHint:
if (v == S48_FALSE)
p->flags &= ~XUrgencyHint;
break;
}
alist = S48_CDR(alist);
}
}
s48_value scx_Get_Wm_Hints(s48_value dpy, s48_value w) {
XWMHints* p;
s48_value res = S48_NULL;
p = XGetWMHints(scx_extract_display(dpy),
scx_extract_window(w));
if (p) {
res = scx_enter_wm_hint_alist(p);
XFree(p);
} else
return S48_FALSE;
return res;
}
s48_value scx_Set_Wm_Hints (s48_value dpy, s48_value w, s48_value hints) {
XWMHints WMH;
scx_extract_wm_hint_alist(hints, &WMH);
XSetWMHints(scx_extract_display(dpy),
scx_extract_window(w),
&WMH);
return S48_UNSPECIFIC;
}
s48_value scx_Get_Transient_For(s48_value dpy, s48_value w) {
Window win;
if (!XGetTransientForHint(scx_extract_display(dpy),
scx_extract_window(w),
&win))
return S48_FALSE;
return scx_enter_window(win);
}
s48_value scx_Set_Transient_For(s48_value dpy, s48_value w, s48_value pw) {
XSetTransientForHint(scx_extract_display(dpy),
scx_extract_window(w),
scx_extract_window(pw));
return S48_UNSPECIFIC;
}
s48_value scx_Get_Text_Property(s48_value dpy, s48_value w, s48_value a) {
XTextProperty ret;
s48_value res = S48_FALSE;
if (!XGetTextProperty (scx_extract_display(dpy),
scx_extract_window(w),
&ret,
scx_extract_atom(a)))
return S48_FALSE;
res = scx_enter_property(ret.encoding, ret.format, ret.value, ret.nitems);
XFree(ret.value);
return res;
}
s48_value scx_Set_Text_Property(s48_value dpy, s48_value w, s48_value prop,
s48_value a) {
XTextProperty p;
scx_extract_property(prop, &p.encoding, &p.format,
(char**)&p.value,
(int*)&p.nitems);
XSetTextProperty(scx_extract_display(dpy),
scx_extract_window(w),
&p, scx_extract_atom(a));
return S48_UNSPECIFIC;
}
#define scx_extract_size_hint(h) S48_EXTRACT_ENUM(h, "scx-size-hint")
#define scx_enter_size_hint(h) S48_ENTER_ENUM(h, "scx-size-hints")
s48_value scx_enter_size_hint_alist(XSizeHints* sh) {
int i;
s48_value res = S48_NULL, v = S48_FALSE, t = S48_FALSE;
S48_DECLARE_GC_PROTECT(3);
S48_GC_PROTECT_3(res, v, t);
for (i = 0; i < 10; i++) {
if (sh->flags & (1L << i)) {
switch (1L << i) {
case USPosition: case PPosition:
v = s48_enter_integer(sh->x);
v = s48_cons(v, s48_enter_integer(sh->y));
break;
case USSize: case PSize:
v = s48_enter_integer(sh->width);
v = s48_cons(v, s48_enter_integer(sh->height));
break;
case PMinSize:
v = s48_enter_integer(sh->min_width);
v = s48_cons(v, s48_enter_integer(sh->min_height));
break;
case PMaxSize:
v = s48_enter_integer(sh->max_width);
v = s48_cons(v, s48_enter_integer(sh->max_width));
break;
case PResizeInc:
v = s48_enter_integer(sh->width_inc);
v = s48_cons(v, s48_enter_integer(sh->height_inc));
break;
case PAspect:
v = s48_enter_integer(sh->min_aspect.x);
v = s48_cons(v, s48_enter_integer(sh->min_aspect.y));
t = s48_enter_integer(sh->max_aspect.x);
t = s48_cons(t, s48_enter_integer(sh->max_aspect.y));
v = s48_cons(v, t);
break;
case PBaseSize:
v = s48_enter_integer(sh->base_width);
v = s48_cons(v, s48_enter_integer(sh->base_height));
break;
case PWinGravity:
v = scx_enter_win_gravity(sh->win_gravity);
break;
default: v = S48_FALSE;
}
t = scx_enter_size_hint(i);
t = s48_cons(t, v);
res = s48_cons(t, res);
}
}
S48_GC_UNPROTECT();
return res;
}
void scx_extract_size_hint_alist(s48_value l, XSizeHints* sh) {
sh->flags = 0;
for (; l != S48_NULL; l = S48_CDR(l)) {
int m = scx_extract_size_hint(S48_CAR(S48_CAR(l)));
s48_value v = S48_CDR(S48_CAR(l));
sh->flags |= (1L << m);
switch (1L << m) {
case USPosition: case PPosition:
sh->x = s48_extract_integer(S48_CAR(v));
sh->y = s48_extract_integer(S48_CDR(v));
break;
case USSize: case PSize:
sh->width = s48_extract_integer(S48_CAR(v));
sh->height = s48_extract_integer(S48_CDR(v));
break;
case PMinSize:
sh->min_width = s48_extract_integer(S48_CAR(v));
sh->min_height = s48_extract_integer(S48_CDR(v));
break;
case PMaxSize:
sh->max_width = s48_extract_integer(S48_CAR(v));
sh->max_height = s48_extract_integer(S48_CDR(v));
break;
case PResizeInc:
sh->width_inc = s48_extract_integer(S48_CAR(v));
sh->height_inc = s48_extract_integer(S48_CDR(v));
break;
case PAspect:
sh->min_aspect.x = s48_extract_integer(S48_CAR(S48_CAR(v)));
sh->min_aspect.y = s48_extract_integer(S48_CDR(S48_CAR(v)));
sh->max_aspect.x = s48_extract_integer(S48_CAR(S48_CDR(v)));
sh->max_aspect.y = s48_extract_integer(S48_CDR(S48_CDR(v)));
break;
case PBaseSize:
sh->base_width = s48_extract_integer(S48_CAR(v));
sh->base_height = s48_extract_integer(S48_CDR(v));
break;
case PWinGravity:
sh->win_gravity = scx_extract_win_gravity(v);
break;
}
}
}
s48_value scx_Get_Wm_Normal_Hints(s48_value dpy, s48_value win) {
XSizeHints SH;
long supplied_by_user;
if (!XGetWMNormalHints(scx_extract_display(dpy),
scx_extract_window(win),
&SH, &supplied_by_user))
return S48_FALSE;
// ignoring supplied_by_user ... ?!
return scx_enter_size_hint_alist(&SH);
}
s48_value scx_Set_Wm_Normal_Hints(s48_value dpy, s48_value win,
s48_value hints) {
XSizeHints SH;
scx_extract_size_hint_alist(hints, &SH);
XSetWMNormalHints(scx_extract_display(dpy),
scx_extract_window(win),
&SH);
return S48_UNSPECIFIC;
}
s48_value scx_enter_icon_size(XIconSize* is) {
s48_value res = s48_make_record(s48_get_imported_binding("scx-icon-size"));
S48_DECLARE_GC_PROTECT(1);
S48_GC_PROTECT_1(res);
S48_RECORD_SET(res, 0, s48_enter_integer(is->min_width));
S48_RECORD_SET(res, 1, s48_enter_integer(is->min_height));
S48_RECORD_SET(res, 2, s48_enter_integer(is->max_width));
S48_RECORD_SET(res, 3, s48_enter_integer(is->max_height));
S48_RECORD_SET(res, 4, s48_enter_integer(is->width_inc));
S48_RECORD_SET(res, 5, s48_enter_integer(is->height_inc));
S48_GC_UNPROTECT();
return res;
}
void scx_extract_icon_size(s48_value r, XIconSize* is) {
s48_check_record_type(r, s48_get_imported_binding("scx-icon-size"));
is->min_width = s48_extract_integer(S48_RECORD_REF(r, 0));
is->min_height = s48_extract_integer(S48_RECORD_REF(r, 1));
is->max_width = s48_extract_integer(S48_RECORD_REF(r, 2));
is->max_height = s48_extract_integer(S48_RECORD_REF(r, 3));
is->width_inc = s48_extract_integer(S48_RECORD_REF(r, 4));
is->height_inc = s48_extract_integer(S48_RECORD_REF(r, 5));
}
s48_value scx_Get_Icon_Sizes(s48_value dpy, s48_value w) {
XIconSize *p;
int i, n;
s48_value v = S48_NULL;
S48_DECLARE_GC_PROTECT(1);
if (!XGetIconSizes (scx_extract_display(dpy),
scx_extract_window(w),
&p, &n))
return S48_FALSE;
S48_GC_PROTECT_1(v);
for (i = n-1; i >= 0; i--)
v = s48_cons(scx_enter_icon_size(&p[i]), v);
S48_GC_UNPROTECT();
XFree((char *)p);
return v;
}
s48_value scx_Set_Icon_Sizes(s48_value dpy, s48_value w, s48_value v) {
int i, n = s48_list_length(v);
XIconSize p[n];
for (i = 0; i < n; i++) {
scx_extract_icon_size(S48_CAR(v), &p[i]);
v = S48_CDR(v);
}
XSetIconSizes(scx_extract_display(dpy),
scx_extract_window(w),
p, n);
return S48_UNSPECIFIC;
}
scx_init_client() {
S48_EXPORT_FUNCTION(scx_Iconify_Window);
S48_EXPORT_FUNCTION(scx_Withdraw_Window);
S48_EXPORT_FUNCTION(scx_Reconfigure_Wm_Window);
S48_EXPORT_FUNCTION(scx_Get_Wm_Command);
S48_EXPORT_FUNCTION(scx_Get_Text_Property);
S48_EXPORT_FUNCTION(scx_Set_Text_Property);
S48_EXPORT_FUNCTION(scx_Get_Wm_Protocols);
S48_EXPORT_FUNCTION(scx_Set_Wm_Protocols);
S48_EXPORT_FUNCTION(scx_Get_Wm_Class);
S48_EXPORT_FUNCTION(scx_Set_Wm_Class);
S48_EXPORT_FUNCTION(scx_Set_Wm_Command);
S48_EXPORT_FUNCTION(scx_Get_Wm_Hints);
S48_EXPORT_FUNCTION(scx_Set_Wm_Hints);
S48_EXPORT_FUNCTION(scx_Get_Transient_For);
S48_EXPORT_FUNCTION(scx_Set_Transient_For);
S48_EXPORT_FUNCTION(scx_Get_Wm_Normal_Hints);
S48_EXPORT_FUNCTION(scx_Set_Wm_Normal_Hints);
S48_EXPORT_FUNCTION(scx_Get_Icon_Sizes);
S48_EXPORT_FUNCTION(scx_Set_Icon_Sizes);
}