implemented for scheme48.

This commit is contained in:
frese 2001-08-22 11:57:51 +00:00
parent 6455adec4b
commit 42c8c9b37e
2 changed files with 575 additions and 466 deletions

View File

@ -1,390 +1,532 @@
#include "xlib.h" #include "xlib.h"
#include "scheme48.h"
static s48_value Sym_Wm_Hints, Sym_Size_Hints; s48_value scx_Iconify_Window (s48_value Xdisplay, s48_value w, s48_value scr) {
if (!XIconifyWindow (SCX_EXTRACT_DISPLAY(Xdisplay),
static s48_value P_Iconify_Window (w, scr) s48_value w, scr; { SCX_EXTRACT_WINDOW(w),
Check_Type (w, T_Window); s48_extract_integer(scr)))
if (!XIconifyWindow (WINDOW(w)->dpy, WINDOW(w)->win, return S48_FALSE;
Get_Screen_Number (WINDOW(w)->dpy, scr))) else
Primitive_Error ("cannot iconify window"); return S48_UNSPECIFIC;
return Void;
} }
static s48_value P_Withdraw_Window (w, scr) s48_value w, scr; { s48_value scx_Withdraw_Window (s48_value Xdisplay, s48_value w, s48_value scr) {
Check_Type (w, T_Window); if (!XWithdrawWindow (SCX_EXTRACT_DISPLAY(Xdisplay),
if (!XWithdrawWindow (WINDOW(w)->dpy, WINDOW(w)->win, SCX_EXTRACT_WINDOW(w),
Get_Screen_Number (WINDOW(w)->dpy, scr))) s48_extract_integer(scr)))
Primitive_Error ("cannot withdraw window"); return S48_FALSE;
return Void; else
return S48_UNSPECIFIC;
} }
static s48_value P_Reconfigure_Wm_Window (w, scr, conf) s48_value w, scr, conf; { s48_value scx_Reconfigure_Wm_Window (s48_value dpy, s48_value w, s48_value scr,
unsigned long mask; s48_value conf) {
XWindowChanges WC;
unsigned long mask = AList_To_XWindowChanges(conf, &WC);
Check_Type (w, T_Window); if (!XReconfigureWMWindow (SCX_EXTRACT_DISPLAY(dpy),
mask = Vector_To_Record (conf, Conf_Size, Sym_Conf, Conf_Rec); SCX_EXTRACT_WINDOW(w),
if (!XReconfigureWMWindow (WINDOW(w)->dpy, WINDOW(w)->win, s48_extract_integer(scr),
Get_Screen_Number (WINDOW(w)->dpy, scr), mask, &WC)) mask, &WC))
Primitive_Error ("cannot reconfigure window"); return S48_FALSE;
return Void; else
return S48_UNSPECIFIC;
} }
static s48_value P_Wm_Command (w) s48_value w; { s48_value scx_Wm_Command (s48_value dpy, s48_value w) {
int i, ac; int i, ac;
char **av; char** av;
s48_value s, ret, t; s48_value ret;
S48_DECLARE_GC_PROTECT(2); S48_DECLARE_GC_PROTECT(1);
Check_Type (w, T_Window); // Disable_Interrupts;
Disable_Interrupts; if (!XGetCommand (SCX_EXTRACT_DISPLAY(dpy),
if (!XGetCommand (WINDOW(w)->dpy, WINDOW(w)->win, &av, &ac)) SCX_EXTRACT_WINDOW(w),
&av, &ac))
ac = 0; ac = 0;
Enable_Interrupts; // Enable_Interrupts;
ret = t = P_Make_List (s48_enter_integer (ac), S48_NULL); ret = s48_make_vector(ac, S48_FALSE);
S48_GC_PROTECT_2 (ret, t); S48_GC_PROTECT_1 (ret);
for (i = 0; i < ac; i++, t = S48_CDR (t)) { for (i = 0; i < ac; i++) {
s = Make_String (av[i], strlen (av[i])); S48_VECTOR_SET(ret, i, s48_enter_string(av[i]));
S48_CAR (t) = s;
} }
S48_GC_UNPROTECT; S48_GC_UNPROTECT();
if (ac) XFreeStringList (av); if (ac) XFreeStringList (av);
return ret; return ret;
} }
static String_List_To_Text_Property (x, ret) s48_value x; XTextProperty *ret; { int String_Vector_To_Text_Property (s48_value x, XTextProperty* ret) {
register i, n; s48_value t = S48_FALSE;
register char **s; int i, n = S48_VECTOR_LENGTH(x);
s48_value t; char* s[n];
Alloca_Begin;
Check_List (x); for (i = 0; i < n; i++) {
n = Fast_Length (x); t = S48_VECTOR_REF(x, i);
Alloca (s, char**, n * sizeof (char *)); s[i] = S48_SYMBOL_P(t) ? s48_extract_symbol(t) : s48_extract_string(t);
for (i = 0; i < n; i++, x = S48_CDR (x)) { }
t = S48_CAR (x);
Get_Strsym_Stack (t, s[i]); return XStringListToTextProperty (s, n, ret);
} // Primitive_Error ("cannot create text property");
if (!XStringListToTextProperty (s, n, ret))
Primitive_Error ("cannot create text property");
Alloca_End;
} }
static s48_value Text_Property_To_String_List (p) XTextProperty *p; { s48_value Text_Property_To_String_Vector (XTextProperty *p) {
int n; int n, i;
register i; char **s;
char **s; s48_value ret;
s48_value x, ret, t; S48_DECLARE_GC_PROTECT(2);
S48_DECLARE_GC_PROTECT(2);
if (!XTextPropertyToStringList (p, &s, &n)) if (!XTextPropertyToStringList (p, &s, &n))
Primitive_Error ("cannot convert from text property"); return S48_FALSE;
ret = t = P_Make_List (s48_enter_integer (n), S48_NULL); // Primitive_Error ("cannot convert from text property");
S48_GC_PROTECT_2 (ret, t);
for (i = 0; i < n; i++, t = S48_CDR (t)) { ret = s48_make_vector(n, S48_FALSE);
x = Make_String (s[i], strlen (s[i])); S48_GC_PROTECT_1 (ret);
S48_CAR (t) = x; for (i = 0; i < n; i++) {
} S48_VECTOR_SET(ret, i, s48_enter_string(s[i]));
S48_GC_UNPROTECT; }
XFreeStringList (s); S48_GC_UNPROTECT();
return ret;
XFreeStringList (s);
return ret;
} }
static s48_value P_Get_Text_Property (w, a) s48_value w, a; { s48_value scx_Get_Text_Property (s48_value dpy, s48_value w, s48_value a) {
XTextProperty ret; XTextProperty ret;
Check_Type (w, T_Window); // Disable_Interrupts;
Check_Type (a, T_Atom); if (!XGetTextProperty (SCX_EXTRACT_DISPLAY(dpy),
Disable_Interrupts; SCX_EXTRACT_WINDOW(w),
if (!XGetTextProperty (WINDOW(w)->dpy, WINDOW(w)->win, &ret, &ret,
ATOM(a)->atom)) { SCX_EXTRACT_ATOM(a))) {
Enable_Interrupts; //Enable_Interrupts;
return S48_FALSE; 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_List (&ret); //Enable_Interrupts;
return Text_Property_To_String_Vector (&ret);
} }
static s48_value P_Set_Text_Property (w, prop, a) s48_value w, prop, a; { s48_value scx_Set_Text_Property (s48_value dpy, s48_value w, s48_value prop,
XTextProperty p; s48_value a) {
XTextProperty p;
Check_Type (w, T_Window);
Check_Type (a, T_Atom); if (!String_Vector_To_Text_Property (prop, &p))
String_List_To_Text_Property (prop, &p); return S48_FALSE;
XSetTextProperty (WINDOW(w)->dpy, WINDOW(w)->win, &p, ATOM(a)->atom);
XFree ((char *)p.value); XSetTextProperty (SCX_EXTRACT_DISPLAY(dpy),
return Void; SCX_EXTRACT_WINDOW(w),
&p, SCX_EXTRACT_ATOM(a));
XFree ((char *)p.value);
return S48_UNSPECIFIC;
} }
static s48_value P_Wm_Protocols (w) s48_value w; { s48_value scx_Wm_Protocols (s48_value Xdisplay, s48_value w) {
Atom *p; Atom *p;
int i, n; int i, n;
s48_value ret; s48_value ret;
S48_DECLARE_GC_PROTECT(1); S48_DECLARE_GC_PROTECT(1);
Check_Type (w, T_Window); //Disable_Interrupts;
Disable_Interrupts; if (!XGetWMProtocols (SCX_EXTRACT_DISPLAY(Xdisplay),
if (!XGetWMProtocols (WINDOW(w)->dpy, WINDOW(w)->win, &p, &n)) SCX_EXTRACT_WINDOW(w), &p, &n))
Primitive_Error ("cannot get WM protocols"); return S48_FALSE;
Enable_Interrupts; //Enable_Interrupts;
ret = s48_make_vector (n, S48_NULL);
S48_GC_PROTECT_1 (ret); ret = s48_make_vector (n, S48_NULL);
for (i = 0; i < n; i++) { S48_GC_PROTECT_1 (ret);
s48_value a; for (i = 0; i < n; i++) {
S48_VECTOR_SET(ret, i, SCX_ENTER_ATOM(p[i]));
a = Make_Atom (p[i]); }
S48_VECTOR_SET(ret, i, a;) XFree ((char *)p);
} S48_GC_UNPROTECT();
XFree ((char *)p); return ret;
S48_GC_UNPROTECT;
return ret;
} }
static s48_value P_Set_Wm_Protocols (w, v) s48_value w, v; { s48_value scx_Set_Wm_Protocols (s48_value Xdisplay, s48_value w, s48_value v) {
Atom *p; int i, n = S48_VECTOR_LENGTH(v);
int i, n; Atom p[n];
Alloca_Begin;
for (i = 0; i < n; i++)
Check_Type (w, T_Window); p[i] = SCX_EXTRACT_ATOM(S48_VECTOR_REF(v, i));
Check_Type (v, T_Vector);
n = S48_VECTOR_LENGTH(v); if (!XSetWMProtocols (SCX_EXTRACT_DISPLAY(Xdisplay),
Alloca (p, Atom*, n * sizeof (Atom)); SCX_EXTRACT_WINDOW(w),
for (i = 0; i < n; i++) { p, n))
s48_value a; return S48_FALSE;
a = S48_VECTOR_REF(v, i); else
Check_Type (a, T_Atom); return S48_UNSPECIFIC;
p[i] = ATOM(a)->atom;
}
if (!XSetWMProtocols (WINDOW(w)->dpy, WINDOW(w)->win, p, n))
Primitive_Error ("cannot set WM protocols");
Alloca_End;
return Void;
} }
static s48_value P_Wm_Class (w) s48_value w; { s48_value scx_Wm_Class (s48_value Xdisplay, s48_value w) {
s48_value ret, x; s48_value ret, x;
XClassHint c; XClassHint c;
S48_DECLARE_GC_PROTECT(1); S48_DECLARE_GC_PROTECT(1);
Check_Type (w, T_Window); // Elk says:
/* // > In X11.2 XGetClassHint() returns either 0 or Success, which happens
* In X11.2 XGetClassHint() returns either 0 or Success, which happens // > to be defined as 0. So until this bug is fixed, we must
* to be defined as 0. So until this bug is fixed, we must // > explicitly check whether the XClassHint structure has been filled.
* 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; c.res_name = c.res_class = 0;
(void)XGetClassHint (WINDOW(w)->dpy, WINDOW(w)->win, &c); // Disable_Interrupts;
Enable_Interrupts; if (!XGetClassHint (SCX_EXTRACT_DISPLAY(Xdisplay),
ret = s48_cons (S48_FALSE, S48_FALSE); SCX_EXTRACT_WINDOW(w), &c)) {
S48_GC_PROTECT_1 (ret); // Enable_Interrupts;
if (c.res_name) { return S48_FALSE;
x = Make_String (c.res_name, strlen (c.res_name)); }
S48_CAR (ret) = x; // Enable_Interrupts;
XFree (c.res_name);
} ret = s48_cons (S48_FALSE, S48_FALSE);
if (c.res_class) { S48_GC_PROTECT_1 (ret);
x = Make_String (c.res_class, strlen (c.res_class)); if (c.res_name) {
S48_CDR (ret) = x; S48_SET_CAR(ret, s48_enter_string(c.res_name));
XFree (c.res_class); XFree (c.res_name);
} }
S48_GC_UNPROTECT; if (c.res_class) {
return ret; S48_SET_CDR(ret, s48_enter_string(c.res_class));
XFree (c.res_class);
}
S48_GC_UNPROTECT();
return ret;
} }
static s48_value P_Set_Wm_Class (w, name, class) s48_value w, name, class; { s48_value scx_Set_Wm_Class (s48_value dpy, s48_value w, s48_value name,
XClassHint c; s48_value class) {
XClassHint c;
Check_Type (w, T_Window); c.res_name = s48_extract_string(name);
c.res_name = Get_Strsym (name); c.res_class = s48_extract_string(class);
c.res_class = Get_Strsym (class); XSetClassHint (SCX_EXTRACT_DISPLAY(dpy),
XSetClassHint (WINDOW(w)->dpy, WINDOW(w)->win, &c); SCX_EXTRACT_WINDOW(dpy),
return Void; &c);
return S48_UNSPECIFIC;
} }
static s48_value P_Set_Wm_Command (w, cmd) s48_value w, cmd; { s48_value scx_Set_Wm_Command (s48_value dpy, s48_value w, s48_value cmd) {
register i, n; int i, n = S48_VECTOR_LENGTH(cmd);
register char **argv; char *argv[n];
s48_value c; for (i = 0; i < n; i++)
Alloca_Begin; argv[i] = s48_extract_string(S48_VECTOR_REF(cmd, i));
Check_Type (w, T_Window); XSetCommand (SCX_EXTRACT_DISPLAY(dpy),
Check_List (cmd); SCX_EXTRACT_WINDOW(w),
n = Fast_Length (cmd); argv, n);
Alloca (argv, char**, n * sizeof (char *)); return S48_UNSPECIFIC;
for (i = 0; i < n; i++, cmd = S48_CDR (cmd)) {
c = S48_CAR (cmd);
Get_Strsym_Stack (c, argv[i]);
}
XSetCommand (WINDOW(w)->dpy, WINDOW(w)->win, argv, n);
Alloca_End;
return Void;
} }
static s48_value P_Wm_Hints (w) s48_value w; { s48_value scx_Wm_Hints (s48_value dpy, s48_value w) {
XWMHints *p; XWMHints* p = (XWMHints*)0;
s48_value res;
S48_DECLARE_GC_PROTECT(1);
Check_Type (w, T_Window); //Disable_Interrupts;
Disable_Interrupts; p = XGetWMHints (SCX_EXTRACT_DISPLAY(dpy),
p = XGetWMHints (WINDOW(w)->dpy, WINDOW(w)->win); SCX_EXTRACT_WINDOW(w));
Enable_Interrupts; //Enable_Interrupts;
if (p) { res = s48_make_vector(9, S48_NULL);
WMH = *p; if (p) {
XFree ((char *)p); S48_GC_PROTECT_1(res);
} else {
WMH.flags = 0;
}
return Record_To_Vector (Wm_Hints_Rec, Wm_Hints_Size, Sym_Wm_Hints,
WINDOW(w)->dpy, (unsigned long)WMH.flags);
}
static s48_value P_Set_Wm_Hints (w, h) s48_value w, h; {
unsigned long mask;
Check_Type (w, T_Window);
mask = Vector_To_Record (h, Wm_Hints_Size, Sym_Wm_Hints, Wm_Hints_Rec);
WMH.flags = mask;
XSetWMHints (WINDOW(w)->dpy, WINDOW(w)->win, &WMH);
return Void;
}
static s48_value P_Size_Hints (w, a) s48_value w, a; {
long supplied;
Check_Type (w, T_Window);
Check_Type (a, T_Atom);
Disable_Interrupts;
if (!XGetWMSizeHints (WINDOW(w)->dpy, WINDOW(w)->win, &SZH, &supplied,
ATOM(a)->atom))
SZH.flags = 0;
if (!(supplied & PBaseSize))
SZH.flags &= ~PBaseSize;
if (!(supplied & PWinGravity))
SZH.flags &= ~PWinGravity;
Enable_Interrupts;
if ((SZH.flags & (PPosition|USPosition)) == (PPosition|USPosition))
SZH.flags &= ~PPosition;
if ((SZH.flags & (PSize|USSize)) == (PSize|USSize))
SZH.flags &= ~PSize;
return Record_To_Vector (Size_Hints_Rec, Size_Hints_Size, Sym_Size_Hints,
WINDOW(w)->dpy, (unsigned long)SZH.flags);
}
static s48_value P_Set_Size_Hints (w, a, h) s48_value w, a, h; {
unsigned long mask;
Check_Type (w, T_Window);
Check_Type (a, T_Atom);
bzero ((char *)&SZH, sizeof (SZH)); /* Not portable? */
mask = Vector_To_Record (h, Size_Hints_Size, Sym_Size_Hints,
Size_Hints_Rec);
if ((mask & (PPosition|USPosition)) == (PPosition|USPosition))
mask &= ~PPosition;
if ((mask & (PSize|USSize)) == (PSize|USSize))
mask &= ~PSize;
SZH.flags = mask;
XSetWMSizeHints (WINDOW(w)->dpy, WINDOW(w)->win, &SZH, ATOM(a)->atom);
return Void;
}
static s48_value P_Icon_Sizes (w) s48_value w; {
XIconSize *p;
int i, n;
s48_value v;
S48_DECLARE_GC_PROTECT(1);
Check_Type (w, T_Window); if (p->flags && InputHint)
Disable_Interrupts; S48_VECTOR_SET(res, 0, S48_ENTER_BOOLEAN(p->input));
if (!XGetIconSizes (WINDOW(w)->dpy, WINDOW(w)->win, &p, &n)) if (p->flags && StateHint)
n = 0; S48_VECTOR_SET(res, 1, Bit_To_Symbol((unsigned long)p->initial_state,
Enable_Interrupts; Initial_State_Syms));
v = s48_make_vector (n, S48_NULL); if (p->flags && IconPixmapHint)
S48_GC_PROTECT_1 (v); S48_VECTOR_SET(res, 2, SCX_ENTER_PIXMAP(p->icon_pixmap));
for (i = 0; i < n; i++) { if (p->flags && IconWindowHint)
register XIconSize *q = &p[i]; S48_VECTOR_SET(res, 3, SCX_ENTER_WINDOW(p->icon_window));
s48_value t; if (p->flags && IconPositionHint) {
S48_VECTOR_SET(res, 4, s48_enter_integer(p->icon_x));
t = P_Make_List (s48_enter_integer (6), S48_NULL); S48_VECTOR_SET(res, 5, s48_enter_integer(p->icon_y));
S48_VECTOR_SET(v, i, t;)
S48_CAR (t) = s48_enter_integer (q->min_width); t = S48_CDR (t);
S48_CAR (t) = s48_enter_integer (q->min_height); t = S48_CDR (t);
S48_CAR (t) = s48_enter_integer (q->max_width); t = S48_CDR (t);
S48_CAR (t) = s48_enter_integer (q->max_height); t = S48_CDR (t);
S48_CAR (t) = s48_enter_integer (q->width_inc); t = S48_CDR (t);
S48_CAR (t) = s48_enter_integer (q->height_inc);
} }
S48_GC_UNPROTECT; if (p->flags && IconMaskHint)
if (n > 0) S48_VECTOR_SET(res, 6, SCX_ENTER_PIXMAP(p->icon_mask));
XFree ((char *)p); if (p->flags && WindowGroupHint)
return v; // Elk says a window-group is a window...??
S48_VECTOR_SET(res, 7, SCX_ENTER_WINDOW(p->window_group));
S48_VECTOR_SET(res, 8, S48_ENTER_BOOLEAN(p->flags && XUrgencyHint));
// XLib man-pages say this constant is called UrgencyHint !!
S48_GC_UNPROTECT();
}
return res;
} }
static s48_value P_Set_Icon_Sizes (w, v) s48_value w, v; { s48_value scx_Set_Wm_Hints (s48_value dpy, s48_value w, s48_value alist) {
register i, n; unsigned long mask = 0;
XIconSize *p; s48_value l, p, v;
Alloca_Begin; XWMHints WMH;
char* cname;
Check_Type (w, T_Window); for (l = alist; !S48_NULL_P(l); l = S48_CDR(l)) {
Check_Type (v, T_Vector); p = S48_CAR(l);
n = S48_VECTOR_LENGTH(v); v = S48_CDR(p);
Alloca (p, XIconSize*, n * sizeof (XIconSize)); cname = s48_extract_symbol(S48_CAR(p));
for (i = 0; i < n; i++) { if (strcmp(cname, "input?") == 0) {
register XIconSize *q = &p[i]; mask |= InputHint;
s48_value t; WMH.input = !S48_FALSE_P(v);
} else if (strcmp(cname, "initial-state") == 0) {
t = S48_VECTOR_REF(v, i); mask |= StateHint;
Check_List (t); WMH.initial_state = Symbol_To_Bit((unsigned long)s48_extract_integer(v),
if (Fast_Length (t) != 6) Initial_State_Syms);
Primitive_Error ("invalid argument: ~s", t); } else if (strcmp(cname, "icon-pixmap") == 0) {
q->min_width = (int)s48_extract_integer (S48_CAR (t)); t = S48_CDR (t); mask |= IconPixmapHint;
q->min_height = (int)s48_extract_integer (S48_CAR (t)); t = S48_CDR (t); WMH.icon_pixmap = SCX_EXTRACT_PIXMAP(v);
q->max_width = (int)s48_extract_integer (S48_CAR (t)); t = S48_CDR (t); } else if (strcmp(cname, "icon-window") == 0) {
q->max_height = (int)s48_extract_integer (S48_CAR (t)); t = S48_CDR (t); mask |= IconWindowHint;
q->width_inc = (int)s48_extract_integer (S48_CAR (t)); t = S48_CDR (t); WMH.icon_window = SCX_EXTRACT_WINDOW(v);
q->height_inc = (int)s48_extract_integer (S48_CAR (t)); } else if (strcmp(cname, "icon-x") == 0) {
mask |= IconPositionHint;
WMH.icon_x = (int)s48_extract_integer(v);
} else if (strcmp(cname, "icon-y") == 0) {
mask |= IconPositionHint;
WMH.icon_y = (int)s48_extract_integer(v);
} else if (strcmp(cname, "icon-mask") == 0) {
mask |= IconMaskHint;
WMH.icon_mask = SCX_EXTRACT_PIXMAP(v);
} else if (strcmp(cname, "window-group") == 0) {
mask |= WindowGroupHint;
WMH.window_group = SCX_EXTRACT_WINDOW(v);
} else if (strcmp(cname, "urgency") == 0) {
mask |= XUrgencyHint;
// XLib man-pages say this constant is called UrgencyHint !!
} }
XSetIconSizes (WINDOW(w)->dpy, WINDOW(w)->win, p, n); }
Alloca_End;
return Void; XSetWMHints(SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(w),
&WMH);
return S48_UNSPECIFIC;
} }
static s48_value P_Transient_For (w) s48_value w; { s48_value scx_Icon_Sizes (s48_value dpy, s48_value w) {
Window win; 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);
Disable_Interrupts; S48_VECTOR_SET(t, 0, s48_enter_integer (q->min_width));
if (!XGetTransientForHint (WINDOW(w)->dpy, WINDOW(w)->win, &win)) S48_VECTOR_SET(t, 1, s48_enter_integer (q->min_height));
win = None; S48_VECTOR_SET(t, 2, s48_enter_integer (q->max_width));
Enable_Interrupts; S48_VECTOR_SET(t, 3, s48_enter_integer (q->max_height));
return Make_Window (0, WINDOW(w)->dpy, win); S48_VECTOR_SET(t, 4, s48_enter_integer (q->width_inc));
S48_VECTOR_SET(t, 5, s48_enter_integer (q->height_inc));
}
S48_GC_UNPROTECT();
if (n > 0)
XFree ((char *)p);
return v;
} }
static s48_value P_Set_Transient_For (w, pw) s48_value w, pw; { s48_value scx_Set_Icon_Sizes (s48_value dpy, s48_value w, s48_value v) {
Check_Type (w, T_Window); int i, n = S48_VECTOR_LENGTH(v);
XSetTransientForHint (WINDOW(w)->dpy, WINDOW(w)->win, Get_Window (pw)); XIconSize p[n];
return Void;
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;
} }
elk_init_xlib_client () { s48_value scx_Transient_For(s48_value dpy, s48_value w) {
Define_Symbol (&Sym_Wm_Hints, "wm-hints"); Window win;
Define_Symbol (&Sym_Size_Hints, "size-hints");
Define_Primitive (P_Iconify_Window, "iconify-window", 2, 2, EVAL); //Disable_Interrupts;
Define_Primitive (P_Withdraw_Window, "withdraw-window", 2, 2, EVAL); if (!XGetTransientForHint(SCX_EXTRACT_DISPLAY(dpy),
Define_Primitive (P_Reconfigure_Wm_Window, SCX_EXTRACT_WINDOW(w),
"xlib-reconfigure-wm-window", 3, 3, EVAL); &win))
Define_Primitive (P_Wm_Command, "wm-command", 1, 1, EVAL); win = None;
Define_Primitive (P_Get_Text_Property,"get-text-property", 2, 2, EVAL); //Enable_Interrupts;
Define_Primitive (P_Set_Text_Property,"set-text-property!",3, 3, EVAL); return SCX_ENTER_WINDOW(win);
Define_Primitive (P_Wm_Protocols, "wm-protocols", 1, 1, EVAL); }
Define_Primitive (P_Set_Wm_Protocols, "set-wm-protocols!", 2, 2, EVAL);
Define_Primitive (P_Wm_Class, "wm-class", 1, 1, EVAL); s48_value scx_Set_Transient_For(s48_value dpy, s48_value w, s48_value pw) {
Define_Primitive (P_Set_Wm_Class, "set-wm-class!", 3, 3, EVAL); XSetTransientForHint (SCX_EXTRACT_DISPLAY(dpy),
Define_Primitive (P_Set_Wm_Command, "set-wm-command!", 2, 2, EVAL); SCX_EXTRACT_WINDOW(w),
Define_Primitive (P_Wm_Hints, "xlib-wm-hints", 1, 1, EVAL); SCX_EXTRACT_WINDOW(pw));
Define_Primitive (P_Set_Wm_Hints, "xlib-set-wm-hints!",2, 2, EVAL); return S48_UNSPECIFIC;
Define_Primitive (P_Size_Hints, "xlib-wm-size-hints",2, 2, EVAL); }
Define_Primitive (P_Set_Size_Hints,
"xlib-set-wm-size-hints!", 3, 3, EVAL); s48_value scx_Wm_Normal_Hints(s48_value dpy, s48_value win) {
Define_Primitive (P_Icon_Sizes, "icon-sizes", 1, 1, EVAL); XSizeHints SH;
Define_Primitive (P_Set_Icon_Sizes, "set-icon-sizes!", 2, 2, EVAL); long supplied;
Define_Primitive (P_Transient_For, "transient-for", 1, 1, EVAL); s48_value v;
Define_Primitive (P_Set_Transient_For,"set-transient-for!",2, 2, EVAL); S48_DECLARE_GC_PROTECT(1);
if (!XGetWMNormalHints(SCX_EXTRACT_DISPLAY(dpy),
SCX_EXTRACT_WINDOW(win),
&SH, &supplied))
SH.flags = 0;
v = s48_make_vector(19, S48_NULL);
S48_GC_PROTECT_1(v);
if ((SH.flags & PPosition) == PPosition) {
S48_VECTOR_SET(v, 0, s48_enter_integer(SH.x));
S48_VECTOR_SET(v, 1, s48_enter_integer(SH.y));
}
if ((SH.flags & PSize) == PSize) {
S48_VECTOR_SET(v, 2, s48_enter_integer(SH.width));
S48_VECTOR_SET(v, 3, s48_enter_integer(SH.height));
}
if ((SH.flags & USPosition) == USPosition) {
S48_VECTOR_SET(v, 0, s48_enter_integer(SH.x));
S48_VECTOR_SET(v, 1, s48_enter_integer(SH.y));
S48_VECTOR_SET(v, 4, S48_TRUE); // us-position -> #t
}
if ((SH.flags & USSize) == USSize) {
S48_VECTOR_SET(v, 2, s48_enter_integer(SH.width));
S48_VECTOR_SET(v, 3, s48_enter_integer(SH.height));
S48_VECTOR_SET(v, 5, S48_TRUE); // us-size -> #t
}
if ((SH.flags & PMinSize) == PMinSize) {
S48_VECTOR_SET(v, 6, s48_enter_integer(SH.min_width));
S48_VECTOR_SET(v, 7, s48_enter_integer(SH.min_height));
}
if ((SH.flags & PMaxSize) == PMaxSize) {
S48_VECTOR_SET(v, 8, s48_enter_integer(SH.max_width));
S48_VECTOR_SET(v, 9, s48_enter_integer(SH.max_height));
}
if ((SH.flags & PResizeInc) == PResizeInc) {
S48_VECTOR_SET(v, 10, s48_enter_integer(SH.width_inc));
S48_VECTOR_SET(v, 11, s48_enter_integer(SH.height_inc));
}
if ((SH.flags & PAspect) == PAspect) {
S48_VECTOR_SET(v, 12, s48_enter_integer(SH.min_aspect.x));
S48_VECTOR_SET(v, 13, s48_enter_integer(SH.min_aspect.y));
S48_VECTOR_SET(v, 14, s48_enter_integer(SH.max_aspect.x));
S48_VECTOR_SET(v, 15, s48_enter_integer(SH.max_aspect.y));
}
if ((SH.flags & PBaseSize) == PBaseSize) {
S48_VECTOR_SET(v, 16, s48_enter_integer(SH.base_width));
S48_VECTOR_SET(v, 17, s48_enter_integer(SH.base_height));
}
if ((SH.flags & PWinGravity) == PWinGravity) {
S48_VECTOR_SET(v, 18, Bit_To_Symbol(SH.win_gravity, Grav_Syms));
}
S48_GC_UNPROTECT();
return v;
}
s48_value scx_Set_Wm_Normal_Hints(s48_value dpy, s48_value win,
s48_value alist) {
XSizeHints SH;
long mask = 0;
s48_value l;
for (l = alist; !S48_NULL_P(l); l = S48_CDR(l)) {
s48_value p = S48_CAR(l);
char* name = s48_extract_string(S48_CAR(p));
s48_value v = S48_CDR(p);
if (strcmp(name, "x") == 0) {
mask |= PPosition; SH.x = s48_extract_integer(v);
}
if (strcmp(name, "y") == 0) {
mask |= PPosition; SH.y = s48_extract_integer(v);
}
if (strcmp(name, "width") == 0) {
mask |= PSize; SH.width = s48_extract_integer(v);
}
if (strcmp(name, "height") == 0) {
mask |= PSize; SH.height = s48_extract_integer(v);
}
if (strcmp(name, "min-width") == 0) {
mask |= PMinSize; SH.min_width = s48_extract_integer(v);
}
if (strcmp(name, "min-height") == 0) {
mask |= PMinSize; SH.min_height = s48_extract_integer(v);
}
if (strcmp(name, "max-width") == 0) {
mask |= PMaxSize; SH.max_width = s48_extract_integer(v);
}
if (strcmp(name, "max-height") == 0) {
mask |= PMaxSize; SH.max_height = s48_extract_integer(v);
}
if (strcmp(name, "width-inc") == 0) {
mask |= PResizeInc; SH.width_inc = s48_extract_integer(v);
}
if (strcmp(name, "height-inc") == 0) {
mask |= PResizeInc; SH.height_inc = s48_extract_integer(v);
}
if (strcmp(name, "min-aspect-x") == 0) {
mask |= PAspect; SH.min_aspect.x = s48_extract_integer(v);
}
if (strcmp(name, "min-aspect-y") == 0) {
mask |= PAspect; SH.min_aspect.y = s48_extract_integer(v);
}
if (strcmp(name, "max-aspect-x") == 0) {
mask |= PAspect; SH.max_aspect.x = s48_extract_integer(v);
}
if (strcmp(name, "max-aspect-y") == 0) {
mask |= PAspect; SH.max_aspect.y = s48_extract_integer(v);
}
if (strcmp(name, "base-width") == 0) {
mask |= PBaseSize; SH.base_width = s48_extract_integer(v);
}
if (strcmp(name, "base-height") == 0) {
mask |= PBaseSize; SH.base_height = s48_extract_integer(v);
}
if (strcmp(name, "gravity") == 0) {
mask |= PWinGravity; SH.win_gravity = Symbol_To_Bit(v, Grav_Syms);
}
}
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);
} }

View File

@ -1,159 +1,126 @@
#include "xlib.h" #include "xlib.h"
#include "scheme48.h"
#ifdef XLIB_RELEASE_5_OR_LATER //#ifdef XLIB_RELEASE_5_OR_LATER
// I don't know if XDisplayKeycodes() was already there in X11R4.
// else: dpy->min_keycode dpy->max_keycode
/* I don't know if XDisplayKeycodes() was already there in X11R4. s48_value scx_Display_Min_Keycode (s48_value d) {
*/ int mink, maxk;
static s48_value P_Display_Min_Keycode (d) s48_value d; { XDisplayKeycodes(SCX_EXTRACT_DISPLAY(d), &mink, &maxk);
int mink, maxk; return s48_enter_integer(mink);
Check_Type (d, T_Display);
XDisplayKeycodes(DISPLAY(d)->dpy, &mink, &maxk);
return s48_enter_integer (mink);
} }
static s48_value P_Display_Max_Keycode (d) s48_value d; { s48_value scx_Display_Max_Keycode (s48_value d) {
int mink, maxk; int mink, maxk;
XDisplayKeycodes(SCX_EXTRACT_DISPLAY(d), &mink, &maxk);
Check_Type (d, T_Display); return s48_enter_integer(maxk);
XDisplayKeycodes(DISPLAY(d)->dpy, &mink, &maxk);
return s48_enter_integer (maxk);
} }
#else //#ifdef XLIB_RELEASE_5_OR_LATER
static s48_value P_Display_Min_Keycode (d) s48_value d; { // I'm not sure if this works correctly in X11R4:
Check_Type (d, T_Display);
return s48_enter_integer (DISPLAY(d)->dpy->min_keycode); s48_value scx_Display_Keysyms_Per_Keycode (s48_value d) {
KeySym *ksyms;
int mink, maxk, ksyms_per_kode;
XDisplayKeycodes(SCX_EXTRACT_DISPLAY(d), &mink, &maxk);
ksyms = XGetKeyboardMapping(SCX_EXTRACT_DISPLAY(d), (KeyCode)mink,
maxk - mink + 1, &ksyms_per_kode);
return s48_enter_integer(ksyms_per_kode);
} }
static s48_value P_Display_Max_Keycode (d) s48_value d; { //#else
Check_Type (d, T_Display); //static s48_value P_Display_Keysyms_Per_Keycode (d) s48_value d; {
return s48_enter_integer (DISPLAY(d)->dpy->max_keycode); // Check_Type (d, T_Display);
} // // Force initialization:
#endif // Disable_Interrupts;
// (void)XKeycodeToKeysym (DISPLAY(d)->dpy, DISPLAY(d)->dpy->min_keycode, 0);
// Enable_Interrupts;
// return s48_enter_integer (DISPLAY(d)->dpy->keysyms_per_keycode);
//}
//#endif
#ifdef XLIB_RELEASE_5_OR_LATER s48_value scx_String_To_Keysym (s48_value s) {
KeySym k = XStringToKeysym (s48_extract_string(s));
/* I'm not sure if this works correctly in X11R4: return k == NoSymbol ? S48_FALSE : s48_enter_integer ((unsigned long)k);
*/
static s48_value P_Display_Keysyms_Per_Keycode (d) s48_value d; {
KeySym *ksyms;
int mink, maxk, ksyms_per_kode;
Check_Type (d, T_Display);
XDisplayKeycodes(DISPLAY(d)->dpy, &mink, &maxk);
ksyms = XGetKeyboardMapping(DISPLAY(d)->dpy, (KeyCode)mink,
maxk - mink + 1, &ksyms_per_kode);
return s48_enter_integer (ksyms_per_kode);
} }
#else s48_value scx_Keysym_To_String (s48_value k) {
static s48_value P_Display_Keysyms_Per_Keycode (d) s48_value d; { char* s = XKeysymToString ((KeySym)s48_extract_integer(k));
Check_Type (d, T_Display); return s ? s48_enter_string(s) : S48_FALSE;
/* Force initialization: */
Disable_Interrupts;
(void)XKeycodeToKeysym (DISPLAY(d)->dpy, DISPLAY(d)->dpy->min_keycode, 0);
Enable_Interrupts;
return s48_enter_integer (DISPLAY(d)->dpy->keysyms_per_keycode);
}
#endif
static s48_value P_String_To_Keysym (s) s48_value s; {
KeySym k;
k = XStringToKeysym (Get_Strsym (s));
return k == NoSymbol ? S48_FALSE : s48_enter_integer ((unsigned long)k);
} }
static s48_value P_Keysym_To_String (k) s48_value k; { s48_value scx_Keycode_To_Keysym (s48_value d, s48_value k, s48_value index) {
register char *s; KeySym ks;
//Disable_Interrupts;
s = XKeysymToString ((KeySym)s48_extract_integer (k)); ks = XKeycodeToKeysym(SCX_EXTRACT_DISPLAY(d),
return s ? Make_String (s, strlen (s)) : S48_FALSE; (int)s48_extract_integer (k),
(int)s48_extract_integer (index));
//Enable_Interrupts;
return s48_enter_integer((unsigned long)ks);
} }
static s48_value P_Keycode_To_Keysym (d, k, index) s48_value d, k, index; { s48_value scx_Keysym_To_Keycode (s48_value d, s48_value k) {
s48_value ret; KeyCode kc;
//Disable_Interrupts;
Check_Type (d, T_Display); kc = XKeysymToKeycode (SCX_EXTRACT_DISPLAY(d),
Disable_Interrupts; (KeySym)s48_extract_integer(k));
ret = s48_enter_integer ((unsigned long)XKeycodeToKeysym (DISPLAY(d)->dpy, //Enable_Interrupts;
(int)s48_extract_integer (k), (int)s48_extract_integer (index))); return s48_enter_integer(kc);
Enable_Interrupts;
return ret;
} }
static s48_value P_Keysym_To_Keycode (d, k) s48_value d, k; { s48_value scx_Lookup_String (s48_value d, s48_value k, s48_value mask) {
s48_value ret; XKeyEvent e;
char buf[1024];
int len;
KeySym keysym_return;
XComposeStatus status_return;
Check_Type (d, T_Display); e.display = SCX_EXTRACT_DISPLAY(d);
Disable_Interrupts; e.keycode = (int)s48_extract_integer(k);
ret = s48_enter_integer (XKeysymToKeycode (DISPLAY(d)->dpy, e.state = Symbols_To_Bits(mask, State_Syms);
(KeySym)s48_extract_integer (k))); //Disable_Interrupts;
Enable_Interrupts; len = XLookupString (&e, buf, 1024, &keysym_return, &status_return);
return ret; //Enable_Interrupts;
return s48_enter_string(buf); //is there a 0 at buf[len] ?
} }
static s48_value P_Lookup_String (d, k, mask) s48_value d, k, mask; { s48_value scx_Rebind_Keysym (s48_value d, s48_value k, s48_value mods,
XKeyEvent e; s48_value str) {
char buf[1024]; int i, n = S48_VECTOR_LENGTH(mods);
register len; KeySym p[n];
KeySym keysym_return;
XComposeStatus status_return;
Check_Type (d, T_Display); for (i = 0; i < n; i++)
e.display = DISPLAY(d)->dpy; p[i] = (KeySym)s48_extract_integer(S48_VECTOR_REF(mods, i));
e.keycode = (int)s48_extract_integer (k); XRebindKeysym (SCX_EXTRACT_DISPLAY(d),
e.state = Symbols_To_Bits (mask, 1, State_Syms); (KeySym)s48_extract_integer (k), p, n,
Disable_Interrupts; (unsigned char *)s48_extract_string(str),
len = XLookupString (&e, buf, 1024, &keysym_return, &status_return); S48_STRING_LENGTH(str));
Enable_Interrupts; return S48_UNSPECIFIC;
return Make_String (buf, len);
} }
static s48_value P_Rebind_Keysym (d, k, mods, str) s48_value d, k, mods, str; { s48_value scx_Refresh_Keyboard_Mapping (s48_value d, s48_value w,
KeySym *p; s48_value event) {
register i, n; static XMappingEvent fake;
Alloca_Begin;
Check_Type (d, T_Display); fake.type = MappingNotify;
Check_Type (str, T_String); fake.display = SCX_EXTRACT_DISPLAY(d);
Check_Type (mods, T_Vector); fake.window = SCX_EXTRACT_WINDOW(w);
n = S48_VECTOR_LENGTH(mods); fake.request = Symbol_To_Bit (event, Mapping_Syms);
Alloca (p, KeySym*, n * sizeof (KeySym)); XRefreshKeyboardMapping (&fake);
for (i = 0; i < n; i++) return S48_UNSPECIFIC;
p[i] = (KeySym)s48_extract_integer (VECTOR(mods)->data[i]);
XRebindKeysym (DISPLAY(d)->dpy, (KeySym)s48_extract_integer (k), p, n,
(unsigned char *)STRING(str)->data, STRING(str)->size);
Alloca_End;
return Void;
} }
static s48_value P_Refresh_Keyboard_Mapping (w, event) s48_value w, event; { scx_init_key () {
static XMappingEvent fake; S48_EXPORT_FUNCTION(scx_Display_Min_Keycode);
S48_EXPORT_FUNCTION(scx_Display_Max_Keycode);
Check_Type (w, T_Window); S48_EXPORT_FUNCTION(scx_Display_Keysyms_Per_Keycode);
fake.type = MappingNotify; S48_EXPORT_FUNCTION(scx_String_To_Keysym);
fake.display = WINDOW(w)->dpy; S48_EXPORT_FUNCTION(scx_Keysym_To_String);
fake.window = WINDOW(w)->win; S48_EXPORT_FUNCTION(scx_Keycode_To_Keysym);
fake.request = Symbols_To_Bits (event, 0, Mapping_Syms); S48_EXPORT_FUNCTION(scx_Keysym_To_Keycode);
XRefreshKeyboardMapping (&fake); S48_EXPORT_FUNCTION(scx_Lookup_String);
return Void; S48_EXPORT_FUNCTION(scx_Rebind_Keysym);
} S48_EXPORT_FUNCTION(scx_Refresh_Keyboard_Mapping);
elk_init_xlib_key () {
Define_Primitive (P_Display_Min_Keycode, "display-min-keycode",
1, 1, EVAL);
Define_Primitive (P_Display_Max_Keycode, "display-max-keycode",
1, 1, EVAL);
Define_Primitive (P_Display_Keysyms_Per_Keycode,
"display-keysyms-per-keycode", 1, 1, EVAL);
Define_Primitive (P_String_To_Keysym, "string->keysym", 1, 1, EVAL);
Define_Primitive (P_Keysym_To_String, "keysym->string", 1, 1, EVAL);
Define_Primitive (P_Keycode_To_Keysym, "keycode->keysym", 3, 3, EVAL);
Define_Primitive (P_Keysym_To_Keycode, "keysym->keycode", 2, 2, EVAL);
Define_Primitive (P_Lookup_String, "lookup-string", 3, 3, EVAL);
Define_Primitive (P_Rebind_Keysym, "rebind-keysym", 4, 4, EVAL);
Define_Primitive (P_Refresh_Keyboard_Mapping,
"refresh-keyboard-mapping", 2, 2, EVAL);
} }