scx/c/xlib/client.c

512 lines
15 KiB
C

#include "xlib.h"
s48_value scx_Iconify_Window (s48_value Xdisplay, s48_value w, s48_value scr) {
if (!XIconifyWindow (SCX_EXTRACT_DISPLAY(Xdisplay),
SCX_EXTRACT_WINDOW(w),
s48_extract_integer(scr)))
return S48_FALSE;
else
return S48_UNSPECIFIC;
}
s48_value scx_Withdraw_Window (s48_value Xdisplay, s48_value w, s48_value scr) {
if (!XWithdrawWindow (SCX_EXTRACT_DISPLAY(Xdisplay),
SCX_EXTRACT_WINDOW(w),
s48_extract_integer(scr)))
return S48_FALSE;
else
return S48_UNSPECIFIC;
}
// defined in window.c
extern unsigned long Changes_To_XWindowChanges(s48_value conf,
XWindowChanges* WC);
s48_value scx_Reconfigure_Wm_Window (s48_value dpy, s48_value w, s48_value scr,
s48_value conf) {
XWindowChanges WC;
unsigned long mask = Changes_To_XWindowChanges(conf, &WC);
if (!XReconfigureWMWindow (SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w),
s48_extract_integer(scr),
mask, &WC))
return S48_FALSE;
else
return S48_UNSPECIFIC;
}
s48_value scx_Wm_Command (s48_value dpy, s48_value w) {
int i, ac;
char** av;
s48_value ret;
S48_DECLARE_GC_PROTECT(1);
// Disable_Interrupts;
if (!XGetCommand (SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w),
&av, &ac))
ac = 0;
// Enable_Interrupts;
ret = s48_make_vector(ac, S48_FALSE);
S48_GC_PROTECT_1 (ret);
for (i = 0; i < ac; i++) {
S48_VECTOR_SET(ret, i, s48_enter_string(av[i]));
}
S48_GC_UNPROTECT();
if (ac) XFreeStringList (av);
return ret;
}
int String_Vector_To_Text_Property (s48_value x, XTextProperty* ret) {
s48_value t = S48_FALSE;
int i, n = S48_VECTOR_LENGTH(x);
char* s[n];
for (i = 0; i < n; i++) {
t = S48_VECTOR_REF(x, i);
s[i] = s48_extract_string(t);
}
return XStringListToTextProperty (s, n, ret);
// Primitive_Error ("cannot create text property");
}
s48_value Text_Property_To_String_Vector (XTextProperty *p) {
int n, i;
char **s;
s48_value ret;
S48_DECLARE_GC_PROTECT(2);
if (!XTextPropertyToStringList (p, &s, &n))
return S48_FALSE;
// Primitive_Error ("cannot convert from text property");
ret = s48_make_vector(n, S48_FALSE);
S48_GC_PROTECT_1 (ret);
for (i = 0; i < n; i++) {
S48_VECTOR_SET(ret, i, s48_enter_string(s[i]));
}
S48_GC_UNPROTECT();
XFreeStringList (s);
return ret;
}
s48_value scx_Get_Text_Property (s48_value dpy, s48_value w, s48_value a) {
XTextProperty ret;
// Disable_Interrupts;
if (!XGetTextProperty (SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w),
&ret,
SCX_EXTRACT_ATOM(a))) {
//Enable_Interrupts;
return S48_TRUE; // little hack to distinguish between this error and a
// possible Text_Pr._To_S._L. error
}
//Enable_Interrupts;
return Text_Property_To_String_Vector (&ret);
}
s48_value scx_Set_Text_Property (s48_value dpy, s48_value w, s48_value prop,
s48_value a) {
XTextProperty p;
if (!String_Vector_To_Text_Property (prop, &p))
return S48_FALSE;
XSetTextProperty (SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w),
&p, SCX_EXTRACT_ATOM(a));
XFree ((char *)p.value);
return S48_UNSPECIFIC;
}
s48_value scx_Wm_Protocols (s48_value Xdisplay, s48_value w) {
Atom *p;
int i, n;
s48_value ret;
S48_DECLARE_GC_PROTECT(1);
//Disable_Interrupts;
if (!XGetWMProtocols (SCX_EXTRACT_DISPLAY(Xdisplay),
SCX_EXTRACT_WINDOW(w), &p, &n))
return S48_FALSE;
//Enable_Interrupts;
ret = s48_make_vector (n, S48_NULL);
S48_GC_PROTECT_1 (ret);
for (i = 0; i < n; i++) {
S48_VECTOR_SET(ret, i, SCX_ENTER_ATOM(p[i]));
}
XFree ((char *)p);
S48_GC_UNPROTECT();
return ret;
}
s48_value scx_Set_Wm_Protocols (s48_value Xdisplay, s48_value w, s48_value v) {
int i, n = S48_VECTOR_LENGTH(v);
Atom p[n];
for (i = 0; i < n; i++)
p[i] = SCX_EXTRACT_ATOM(S48_VECTOR_REF(v, i));
if (!XSetWMProtocols (SCX_EXTRACT_DISPLAY(Xdisplay),
SCX_EXTRACT_WINDOW(w),
p, n))
return S48_FALSE;
else
return S48_UNSPECIFIC;
}
s48_value scx_Wm_Class (s48_value Xdisplay, s48_value w) {
s48_value ret, x;
XClassHint c;
S48_DECLARE_GC_PROTECT(1);
// Elk says:
// > In X11.2 XGetClassHint() returns either 0 or Success, which happens
// > to be defined as 0. So until this bug is fixed, we must
// > explicitly check whether the XClassHint structure has been filled.
// but on the other hand, it doesn't even support X11.3, so I think
// <this> is fixed!
c.res_name = c.res_class = 0;
// Disable_Interrupts;
if (!XGetClassHint (SCX_EXTRACT_DISPLAY(Xdisplay),
SCX_EXTRACT_WINDOW(w), &c)) {
// Enable_Interrupts;
return S48_FALSE;
}
// Enable_Interrupts;
ret = s48_cons (S48_FALSE, S48_FALSE);
S48_GC_PROTECT_1 (ret);
if (c.res_name) {
S48_SET_CAR(ret, s48_enter_string(c.res_name));
XFree (c.res_name);
}
if (c.res_class) {
S48_SET_CDR(ret, s48_enter_string(c.res_class));
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;
}
s48_value scx_Set_Wm_Command (s48_value dpy, s48_value w, s48_value cmd) {
int i, n = S48_VECTOR_LENGTH(cmd);
char *argv[n];
for (i = 0; i < n; i++)
argv[i] = s48_extract_string(S48_VECTOR_REF(cmd, i));
XSetCommand (SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w),
argv, n);
return S48_UNSPECIFIC;
}
s48_value scx_Wm_Hints (s48_value dpy, s48_value w) {
XWMHints* p = (XWMHints*)0;
s48_value res;
S48_DECLARE_GC_PROTECT(1);
//Disable_Interrupts;
p = XGetWMHints (SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w));
//Enable_Interrupts;
res = s48_make_vector(9, S48_UNSPECIFIC);
if (p) {
S48_GC_PROTECT_1(res);
if (p->flags && InputHint)
S48_VECTOR_SET(res, 0, S48_ENTER_BOOLEAN(p->input));
if (p->flags && StateHint)
S48_VECTOR_SET(res, 1,
s48_enter_integer((unsigned long)p->initial_state));
if (p->flags && IconPixmapHint)
S48_VECTOR_SET(res, 2, SCX_ENTER_PIXMAP(p->icon_pixmap));
if (p->flags && IconWindowHint)
S48_VECTOR_SET(res, 3, SCX_ENTER_WINDOW(p->icon_window));
if (p->flags && IconPositionHint)
S48_VECTOR_SET(res, 4, s48_cons(s48_enter_fixnum(p->icon_x),
s48_enter_fixnum(p->icon_y)));
if (p->flags && IconMaskHint)
S48_VECTOR_SET(res, 5, SCX_ENTER_PIXMAP(p->icon_mask));
if (p->flags && WindowGroupHint)
// Elk says a window-group is a window...??
S48_VECTOR_SET(res, 6, SCX_ENTER_WINDOW(p->window_group));
S48_VECTOR_SET(res, 7, S48_ENTER_BOOLEAN(p->flags & XUrgencyHint));
// XLib man-pages say this constant is called UrgencyHint !!
res = s48_cons(s48_enter_integer(p->flags), res);
S48_GC_UNPROTECT();
}
XFree((char*)p);
return res;
}
s48_value scx_Set_Wm_Hints (s48_value dpy, s48_value w, s48_value hints) {
long mask = s48_extract_integer(S48_CAR(hints));
s48_value v = S48_CDR(hints);
XWMHints WMH;
if (mask & InputHint)
WMH.input = S48_EXTRACT_BOOLEAN(S48_VECTOR_REF(v, 0));
if (mask & StateHint)
WMH.initial_state = s48_extract_integer(S48_VECTOR_REF(v, 1));
if (mask & IconPixmapHint)
WMH.icon_pixmap = SCX_EXTRACT_PIXMAP(S48_VECTOR_REF(v, 2));
if (mask & IconWindowHint)
WMH.icon_window = SCX_EXTRACT_WINDOW(S48_VECTOR_REF(v, 3));
if (mask & IconPositionHint) {
WMH.icon_x = (int)s48_extract_integer(S48_CAR(S48_VECTOR_REF(v, 4)));
WMH.icon_y = (int)s48_extract_integer(S48_CDR(S48_VECTOR_REF(v, 4)));
}
if (mask & IconMaskHint)
WMH.icon_mask = SCX_EXTRACT_PIXMAP(S48_VECTOR_REF(v, 5));
if (mask & WindowGroupHint)
WMH.window_group = SCX_EXTRACT_WINDOW(S48_VECTOR_REF(v, 6));
if (mask & XUrgencyHint)
if (S48_FALSE == S48_EXTRACT_BOOLEAN(S48_VECTOR_REF(v, 7)))
mask = mask & (~XUrgencyHint);
WMH.flags = mask;
XSetWMHints(SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w),
&WMH);
return S48_UNSPECIFIC;
}
s48_value scx_Icon_Sizes (s48_value dpy, s48_value w) {
XIconSize *p;
int i, n;
s48_value v;
S48_DECLARE_GC_PROTECT(1);
//Disable_Interrupts;
if (!XGetIconSizes (SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w),
&p, &n))
n = 0;
//Enable_Interrupts;
v = s48_make_vector (n, S48_NULL);
S48_GC_PROTECT_1 (v);
for (i = 0; i < n; i++) {
XIconSize* q = &p[i];
s48_value t = s48_make_vector(6, S48_NULL);
S48_VECTOR_SET(v, i, t);
S48_VECTOR_SET(t, 0, s48_enter_fixnum(q->min_width));
S48_VECTOR_SET(t, 1, s48_enter_fixnum(q->min_height));
S48_VECTOR_SET(t, 2, s48_enter_fixnum(q->max_width));
S48_VECTOR_SET(t, 3, s48_enter_fixnum(q->max_height));
S48_VECTOR_SET(t, 4, s48_enter_fixnum(q->width_inc));
S48_VECTOR_SET(t, 5, s48_enter_fixnum(q->height_inc));
}
S48_GC_UNPROTECT();
if (n > 0)
XFree ((char *)p);
return v;
}
s48_value scx_Set_Icon_Sizes (s48_value dpy, s48_value w, s48_value v) {
int i, n = S48_VECTOR_LENGTH(v);
XIconSize p[n];
for (i = 0; i < n; i++) {
XIconSize *q = &p[i];
s48_value t = S48_VECTOR_REF(v, i);
q->min_width = (int)s48_extract_integer(S48_VECTOR_REF(t, 0));
q->min_height = (int)s48_extract_integer(S48_VECTOR_REF(t, 1));
q->max_width = (int)s48_extract_integer(S48_VECTOR_REF(t, 2));
q->max_height = (int)s48_extract_integer(S48_VECTOR_REF(t, 3));
q->width_inc = (int)s48_extract_integer(S48_VECTOR_REF(t, 4));
q->height_inc = (int)s48_extract_integer(S48_VECTOR_REF(t, 5));
}
XSetIconSizes (SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w),
p, n);
return S48_UNSPECIFIC;
}
s48_value scx_Transient_For(s48_value dpy, s48_value w) {
Window win;
//Disable_Interrupts;
if (!XGetTransientForHint(SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w),
&win))
win = None;
//Enable_Interrupts;
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_Wm_Normal_Hints(s48_value dpy, s48_value win) {
XSizeHints SH;
long supplied;
s48_value v;
S48_DECLARE_GC_PROTECT(1);
if (!XGetWMNormalHints(SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(win),
&SH, &supplied))
SH.flags = 0;
v = s48_make_vector(10, S48_NULL);
S48_GC_PROTECT_1(v);
if ((SH.flags & USPosition) != 0)
S48_VECTOR_SET(v, 0, S48_VECTOR_REF(v, 2));
if ((SH.flags & USSize) != 0)
S48_VECTOR_SET(v, 1, S48_VECTOR_REF(v, 3));
if (((SH.flags & PPosition) != 0) || ((SH.flags & USPosition) != 0))
S48_VECTOR_SET(v, 2, s48_cons(s48_enter_fixnum(SH.x),
s48_enter_fixnum(SH.y)));
if (((SH.flags & PSize) != 0) || ((SH.flags & USSize) != 0))
S48_VECTOR_SET(v, 3, s48_cons(s48_enter_fixnum(SH.width),
s48_enter_fixnum(SH.height)));
if ((SH.flags & PMinSize) != 0)
S48_VECTOR_SET(v, 4, s48_cons(s48_enter_fixnum(SH.min_width),
s48_enter_fixnum(SH.min_height)));
if ((SH.flags & PMaxSize) != 0)
S48_VECTOR_SET(v, 5, s48_cons(s48_enter_fixnum(SH.max_width),
s48_enter_fixnum(SH.max_height)));
if ((SH.flags & PResizeInc) != 0)
S48_VECTOR_SET(v, 6, s48_cons(s48_enter_fixnum(SH.width_inc),
s48_enter_fixnum(SH.height_inc)));
if ((SH.flags & PAspect) != 0)
S48_VECTOR_SET(v, 7,
s48_cons(s48_cons(s48_enter_fixnum(SH.min_aspect.x),
s48_enter_fixnum(SH.min_aspect.y)),
s48_cons(s48_enter_fixnum(SH.max_aspect.x),
s48_enter_fixnum(SH.max_aspect.y))));
if ((SH.flags & PBaseSize) != 0)
S48_VECTOR_SET(v, 8, s48_cons(s48_enter_fixnum(SH.base_width),
s48_enter_fixnum(SH.base_height)));
if ((SH.flags & PWinGravity) != 0)
S48_VECTOR_SET(v, 9, s48_enter_integer(SH.win_gravity));
v = s48_cons(s48_enter_integer(SH.flags), v);
S48_GC_UNPROTECT();
return v;
}
s48_value scx_Set_Wm_Normal_Hints(s48_value dpy, s48_value win,
s48_value hints) {
XSizeHints SH;
long mask = s48_extract_integer(S48_CAR(hints));
s48_value v = S48_CDR(hints);
if (mask & USPosition) {
SH.x = s48_extract_integer(S48_CAR(S48_VECTOR_REF(v, 0)));
SH.y = s48_extract_integer(S48_CDR(S48_VECTOR_REF(v, 0)));
}
if (mask & USSize) {
SH.width = s48_extract_integer(S48_CAR(S48_VECTOR_REF(v, 1)));
SH.height = s48_extract_integer(S48_CDR(S48_VECTOR_REF(v, 1)));
}
if (mask & PPosition) {
SH.x = s48_extract_integer(S48_CAR(S48_VECTOR_REF(v, 2)));
SH.y = s48_extract_integer(S48_CDR(S48_VECTOR_REF(v, 2)));
}
if (mask & PSize) {
SH.width = s48_extract_integer(S48_CAR(S48_VECTOR_REF(v, 3)));
SH.height = s48_extract_integer(S48_CDR(S48_VECTOR_REF(v, 3)));
}
if (mask & PMinSize) {
SH.min_width = s48_extract_integer(S48_CAR(S48_VECTOR_REF(v, 4)));
SH.min_height = s48_extract_integer(S48_CDR(S48_VECTOR_REF(v, 4)));
}
if (mask & PMaxSize) {
SH.max_width = s48_extract_integer(S48_CAR(S48_VECTOR_REF(v, 5)));
SH.max_height = s48_extract_integer(S48_CDR(S48_VECTOR_REF(v, 5)));
}
if (mask & PResizeInc) {
SH.width_inc = s48_extract_integer(S48_CAR(S48_VECTOR_REF(v, 6)));
SH.height_inc = s48_extract_integer(S48_CDR(S48_VECTOR_REF(v, 6)));
}
if (mask & PAspect) {
SH.min_aspect.x =
s48_extract_integer(S48_CAR(S48_CAR(S48_VECTOR_REF(v, 7))));
SH.min_aspect.y =
s48_extract_integer(S48_CDR(S48_CAR(S48_VECTOR_REF(v, 7))));
SH.max_aspect.x =
s48_extract_integer(S48_CAR(S48_CDR(S48_VECTOR_REF(v, 7))));
SH.max_aspect.y =
s48_extract_integer(S48_CDR(S48_CDR(S48_VECTOR_REF(v, 7))));
}
if (mask & PBaseSize) {
SH.base_width = s48_extract_integer(S48_CAR(S48_VECTOR_REF(v, 8)));
SH.base_height = s48_extract_integer(S48_CDR(S48_VECTOR_REF(v, 8)));
}
if (mask & PWinGravity)
SH.win_gravity = s48_extract_integer(S48_VECTOR_REF(v, 9));
SH.flags = mask;
XSetWMNormalHints(SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(win),
&SH);
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_Wm_Command);
S48_EXPORT_FUNCTION(scx_Get_Text_Property);
S48_EXPORT_FUNCTION(scx_Set_Text_Property);
S48_EXPORT_FUNCTION(scx_Wm_Protocols);
S48_EXPORT_FUNCTION(scx_Set_Wm_Protocols);
S48_EXPORT_FUNCTION(scx_Wm_Class);
S48_EXPORT_FUNCTION(scx_Set_Wm_Class);
S48_EXPORT_FUNCTION(scx_Set_Wm_Command);
S48_EXPORT_FUNCTION(scx_Wm_Hints);
S48_EXPORT_FUNCTION(scx_Set_Wm_Hints);
S48_EXPORT_FUNCTION(scx_Icon_Sizes);
S48_EXPORT_FUNCTION(scx_Set_Icon_Sizes);
S48_EXPORT_FUNCTION(scx_Transient_For);
S48_EXPORT_FUNCTION(scx_Set_Transient_For);
S48_EXPORT_FUNCTION(scx_Wm_Normal_Hints);
S48_EXPORT_FUNCTION(scx_Set_Wm_Normal_Hints);
}