391 lines
12 KiB
C
391 lines
12 KiB
C
#include "xlib.h"
|
|
|
|
static s48_value Sym_Wm_Hints, Sym_Size_Hints;
|
|
|
|
static s48_value P_Iconify_Window (w, scr) s48_value w, scr; {
|
|
Check_Type (w, T_Window);
|
|
if (!XIconifyWindow (WINDOW(w)->dpy, WINDOW(w)->win,
|
|
Get_Screen_Number (WINDOW(w)->dpy, scr)))
|
|
Primitive_Error ("cannot iconify window");
|
|
return Void;
|
|
}
|
|
|
|
static s48_value P_Withdraw_Window (w, scr) s48_value w, scr; {
|
|
Check_Type (w, T_Window);
|
|
if (!XWithdrawWindow (WINDOW(w)->dpy, WINDOW(w)->win,
|
|
Get_Screen_Number (WINDOW(w)->dpy, scr)))
|
|
Primitive_Error ("cannot withdraw window");
|
|
return Void;
|
|
}
|
|
|
|
static s48_value P_Reconfigure_Wm_Window (w, scr, conf) s48_value w, scr, conf; {
|
|
unsigned long mask;
|
|
|
|
Check_Type (w, T_Window);
|
|
mask = Vector_To_Record (conf, Conf_Size, Sym_Conf, Conf_Rec);
|
|
if (!XReconfigureWMWindow (WINDOW(w)->dpy, WINDOW(w)->win,
|
|
Get_Screen_Number (WINDOW(w)->dpy, scr), mask, &WC))
|
|
Primitive_Error ("cannot reconfigure window");
|
|
return Void;
|
|
}
|
|
|
|
static s48_value P_Wm_Command (w) s48_value w; {
|
|
int i, ac;
|
|
char **av;
|
|
s48_value s, ret, t;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
Check_Type (w, T_Window);
|
|
Disable_Interrupts;
|
|
if (!XGetCommand (WINDOW(w)->dpy, WINDOW(w)->win, &av, &ac))
|
|
ac = 0;
|
|
Enable_Interrupts;
|
|
ret = t = P_Make_List (s48_enter_integer (ac), S48_NULL);
|
|
S48_GC_PROTECT_2 (ret, t);
|
|
for (i = 0; i < ac; i++, t = S48_CDR (t)) {
|
|
s = Make_String (av[i], strlen (av[i]));
|
|
S48_CAR (t) = s;
|
|
}
|
|
S48_GC_UNPROTECT;
|
|
if (ac) XFreeStringList (av);
|
|
return ret;
|
|
}
|
|
|
|
static String_List_To_Text_Property (x, ret) s48_value x; XTextProperty *ret; {
|
|
register i, n;
|
|
register char **s;
|
|
s48_value t;
|
|
Alloca_Begin;
|
|
|
|
Check_List (x);
|
|
n = Fast_Length (x);
|
|
Alloca (s, char**, n * sizeof (char *));
|
|
for (i = 0; i < n; i++, x = S48_CDR (x)) {
|
|
t = S48_CAR (x);
|
|
Get_Strsym_Stack (t, s[i]);
|
|
}
|
|
if (!XStringListToTextProperty (s, n, ret))
|
|
Primitive_Error ("cannot create text property");
|
|
Alloca_End;
|
|
}
|
|
|
|
static s48_value Text_Property_To_String_List (p) XTextProperty *p; {
|
|
int n;
|
|
register i;
|
|
char **s;
|
|
s48_value x, ret, t;
|
|
S48_DECLARE_GC_PROTECT(2);
|
|
|
|
if (!XTextPropertyToStringList (p, &s, &n))
|
|
Primitive_Error ("cannot convert from text property");
|
|
ret = t = P_Make_List (s48_enter_integer (n), S48_NULL);
|
|
S48_GC_PROTECT_2 (ret, t);
|
|
for (i = 0; i < n; i++, t = S48_CDR (t)) {
|
|
x = Make_String (s[i], strlen (s[i]));
|
|
S48_CAR (t) = x;
|
|
}
|
|
S48_GC_UNPROTECT;
|
|
XFreeStringList (s);
|
|
return ret;
|
|
}
|
|
|
|
static s48_value P_Get_Text_Property (w, a) s48_value w, a; {
|
|
XTextProperty ret;
|
|
|
|
Check_Type (w, T_Window);
|
|
Check_Type (a, T_Atom);
|
|
Disable_Interrupts;
|
|
if (!XGetTextProperty (WINDOW(w)->dpy, WINDOW(w)->win, &ret,
|
|
ATOM(a)->atom)) {
|
|
Enable_Interrupts;
|
|
return S48_FALSE;
|
|
}
|
|
Enable_Interrupts;
|
|
return Text_Property_To_String_List (&ret);
|
|
}
|
|
|
|
static s48_value P_Set_Text_Property (w, prop, a) s48_value w, prop, a; {
|
|
XTextProperty p;
|
|
|
|
Check_Type (w, T_Window);
|
|
Check_Type (a, T_Atom);
|
|
String_List_To_Text_Property (prop, &p);
|
|
XSetTextProperty (WINDOW(w)->dpy, WINDOW(w)->win, &p, ATOM(a)->atom);
|
|
XFree ((char *)p.value);
|
|
return Void;
|
|
}
|
|
|
|
static s48_value P_Wm_Protocols (w) s48_value w; {
|
|
Atom *p;
|
|
int i, n;
|
|
s48_value ret;
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
|
|
Check_Type (w, T_Window);
|
|
Disable_Interrupts;
|
|
if (!XGetWMProtocols (WINDOW(w)->dpy, WINDOW(w)->win, &p, &n))
|
|
Primitive_Error ("cannot get WM protocols");
|
|
Enable_Interrupts;
|
|
ret = s48_make_vector (n, S48_NULL);
|
|
S48_GC_PROTECT_1 (ret);
|
|
for (i = 0; i < n; i++) {
|
|
s48_value a;
|
|
|
|
a = Make_Atom (p[i]);
|
|
S48_VECTOR_SET(ret, i, a;)
|
|
}
|
|
XFree ((char *)p);
|
|
S48_GC_UNPROTECT;
|
|
return ret;
|
|
}
|
|
|
|
static s48_value P_Set_Wm_Protocols (w, v) s48_value w, v; {
|
|
Atom *p;
|
|
int i, n;
|
|
Alloca_Begin;
|
|
|
|
Check_Type (w, T_Window);
|
|
Check_Type (v, T_Vector);
|
|
n = S48_VECTOR_LENGTH(v);
|
|
Alloca (p, Atom*, n * sizeof (Atom));
|
|
for (i = 0; i < n; i++) {
|
|
s48_value a;
|
|
a = S48_VECTOR_REF(v, i);
|
|
Check_Type (a, T_Atom);
|
|
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 ret, x;
|
|
XClassHint c;
|
|
S48_DECLARE_GC_PROTECT(1);
|
|
|
|
Check_Type (w, T_Window);
|
|
/*
|
|
* 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.
|
|
*/
|
|
c.res_name = c.res_class = 0;
|
|
Disable_Interrupts;
|
|
(void)XGetClassHint (WINDOW(w)->dpy, WINDOW(w)->win, &c);
|
|
Enable_Interrupts;
|
|
ret = s48_cons (S48_FALSE, S48_FALSE);
|
|
S48_GC_PROTECT_1 (ret);
|
|
if (c.res_name) {
|
|
x = Make_String (c.res_name, strlen (c.res_name));
|
|
S48_CAR (ret) = x;
|
|
XFree (c.res_name);
|
|
}
|
|
if (c.res_class) {
|
|
x = Make_String (c.res_class, strlen (c.res_class));
|
|
S48_CDR (ret) = x;
|
|
XFree (c.res_class);
|
|
}
|
|
S48_GC_UNPROTECT;
|
|
return ret;
|
|
}
|
|
|
|
static s48_value P_Set_Wm_Class (w, name, class) s48_value w, name, class; {
|
|
XClassHint c;
|
|
|
|
Check_Type (w, T_Window);
|
|
c.res_name = Get_Strsym (name);
|
|
c.res_class = Get_Strsym (class);
|
|
XSetClassHint (WINDOW(w)->dpy, WINDOW(w)->win, &c);
|
|
return Void;
|
|
}
|
|
|
|
static s48_value P_Set_Wm_Command (w, cmd) s48_value w, cmd; {
|
|
register i, n;
|
|
register char **argv;
|
|
s48_value c;
|
|
Alloca_Begin;
|
|
|
|
Check_Type (w, T_Window);
|
|
Check_List (cmd);
|
|
n = Fast_Length (cmd);
|
|
Alloca (argv, char**, n * sizeof (char *));
|
|
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; {
|
|
XWMHints *p;
|
|
|
|
Check_Type (w, T_Window);
|
|
Disable_Interrupts;
|
|
p = XGetWMHints (WINDOW(w)->dpy, WINDOW(w)->win);
|
|
Enable_Interrupts;
|
|
if (p) {
|
|
WMH = *p;
|
|
XFree ((char *)p);
|
|
} 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);
|
|
Disable_Interrupts;
|
|
if (!XGetIconSizes (WINDOW(w)->dpy, WINDOW(w)->win, &p, &n))
|
|
n = 0;
|
|
Enable_Interrupts;
|
|
v = s48_make_vector (n, S48_NULL);
|
|
S48_GC_PROTECT_1 (v);
|
|
for (i = 0; i < n; i++) {
|
|
register XIconSize *q = &p[i];
|
|
s48_value t;
|
|
|
|
t = P_Make_List (s48_enter_integer (6), S48_NULL);
|
|
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 (n > 0)
|
|
XFree ((char *)p);
|
|
return v;
|
|
}
|
|
|
|
static s48_value P_Set_Icon_Sizes (w, v) s48_value w, v; {
|
|
register i, n;
|
|
XIconSize *p;
|
|
Alloca_Begin;
|
|
|
|
Check_Type (w, T_Window);
|
|
Check_Type (v, T_Vector);
|
|
n = S48_VECTOR_LENGTH(v);
|
|
Alloca (p, XIconSize*, n * sizeof (XIconSize));
|
|
for (i = 0; i < n; i++) {
|
|
register XIconSize *q = &p[i];
|
|
s48_value t;
|
|
|
|
t = S48_VECTOR_REF(v, i);
|
|
Check_List (t);
|
|
if (Fast_Length (t) != 6)
|
|
Primitive_Error ("invalid argument: ~s", t);
|
|
q->min_width = (int)s48_extract_integer (S48_CAR (t)); t = S48_CDR (t);
|
|
q->min_height = (int)s48_extract_integer (S48_CAR (t)); t = S48_CDR (t);
|
|
q->max_width = (int)s48_extract_integer (S48_CAR (t)); t = S48_CDR (t);
|
|
q->max_height = (int)s48_extract_integer (S48_CAR (t)); t = S48_CDR (t);
|
|
q->width_inc = (int)s48_extract_integer (S48_CAR (t)); t = S48_CDR (t);
|
|
q->height_inc = (int)s48_extract_integer (S48_CAR (t));
|
|
}
|
|
XSetIconSizes (WINDOW(w)->dpy, WINDOW(w)->win, p, n);
|
|
Alloca_End;
|
|
return Void;
|
|
}
|
|
|
|
static s48_value P_Transient_For (w) s48_value w; {
|
|
Window win;
|
|
|
|
Disable_Interrupts;
|
|
if (!XGetTransientForHint (WINDOW(w)->dpy, WINDOW(w)->win, &win))
|
|
win = None;
|
|
Enable_Interrupts;
|
|
return Make_Window (0, WINDOW(w)->dpy, win);
|
|
}
|
|
|
|
static s48_value P_Set_Transient_For (w, pw) s48_value w, pw; {
|
|
Check_Type (w, T_Window);
|
|
XSetTransientForHint (WINDOW(w)->dpy, WINDOW(w)->win, Get_Window (pw));
|
|
return Void;
|
|
}
|
|
|
|
elk_init_xlib_client () {
|
|
Define_Symbol (&Sym_Wm_Hints, "wm-hints");
|
|
Define_Symbol (&Sym_Size_Hints, "size-hints");
|
|
Define_Primitive (P_Iconify_Window, "iconify-window", 2, 2, EVAL);
|
|
Define_Primitive (P_Withdraw_Window, "withdraw-window", 2, 2, EVAL);
|
|
Define_Primitive (P_Reconfigure_Wm_Window,
|
|
"xlib-reconfigure-wm-window", 3, 3, EVAL);
|
|
Define_Primitive (P_Wm_Command, "wm-command", 1, 1, EVAL);
|
|
Define_Primitive (P_Get_Text_Property,"get-text-property", 2, 2, EVAL);
|
|
Define_Primitive (P_Set_Text_Property,"set-text-property!",3, 3, EVAL);
|
|
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);
|
|
Define_Primitive (P_Set_Wm_Class, "set-wm-class!", 3, 3, EVAL);
|
|
Define_Primitive (P_Set_Wm_Command, "set-wm-command!", 2, 2, EVAL);
|
|
Define_Primitive (P_Wm_Hints, "xlib-wm-hints", 1, 1, EVAL);
|
|
Define_Primitive (P_Set_Wm_Hints, "xlib-set-wm-hints!",2, 2, EVAL);
|
|
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);
|
|
Define_Primitive (P_Icon_Sizes, "icon-sizes", 1, 1, EVAL);
|
|
Define_Primitive (P_Set_Icon_Sizes, "set-icon-sizes!", 2, 2, EVAL);
|
|
Define_Primitive (P_Transient_For, "transient-for", 1, 1, EVAL);
|
|
Define_Primitive (P_Set_Transient_For,"set-transient-for!",2, 2, EVAL);
|
|
}
|