#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; } s48_value scx_Reconfigure_Wm_Window (s48_value dpy, s48_value w, s48_value scr, s48_value conf) { XWindowChanges WC; unsigned long mask = 0;//AList_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_SYMBOL_P(t) ? s48_extract_symbol(t) : 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 // 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_NULL); 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, Bit_To_Symbol((unsigned long)p->initial_state, Initial_State_Syms)); 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_integer(p->icon_x), s48_enter_integer(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 !! 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 = 0; XWMHints WMH; int i; for (i=0; i<8; i++) { s48_value value = S48_VECTOR_REF(hints, i); if (S48_FALSE != value) { switch (i) { case 0: mask |= InputHint; WMH.input = (Bool)s48_extract_integer(value); break; case 1: mask |= StateHint; WMH.initial_state = Symbol_To_Bit(value, Initial_State_Syms); break; case 2: mask |= IconPixmapHint; WMH.icon_pixmap = SCX_EXTRACT_PIXMAP(value); break; case 3: mask |= IconWindowHint; WMH.icon_window = SCX_EXTRACT_WINDOW(value); break; case 4: mask |= IconPositionHint; WMH.icon_x = (int)s48_extract_integer(S48_CAR(value)); WMH.icon_y = (int)s48_extract_integer(S48_CDR(value)); break; case 5: mask |= IconMaskHint; WMH.icon_mask = SCX_EXTRACT_PIXMAP(value); break; case 6: mask |= WindowGroupHint; WMH.window_group = SCX_EXTRACT_WINDOW(value); break; case 7: mask |= s48_extract_integer(value) ? XUrgencyHint : 0; // XLib man-pages say this constant is called UrgencyHint !! } } } 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_integer (q->min_width)); S48_VECTOR_SET(t, 1, s48_enter_integer (q->min_height)); S48_VECTOR_SET(t, 2, s48_enter_integer (q->max_width)); S48_VECTOR_SET(t, 3, s48_enter_integer (q->max_height)); 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; } 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 & PPosition) != 0) || ((SH.flags & USPosition) != 0)) S48_VECTOR_SET(v, 2, s48_cons(s48_enter_integer(SH.x), s48_enter_integer(SH.y))); if (((SH.flags & PSize) != 0) || ((SH.flags & USSize) != 0)) S48_VECTOR_SET(v, 3, s48_cons(s48_enter_integer(SH.width), s48_enter_integer(SH.height))); 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 & PMinSize) != 0) S48_VECTOR_SET(v, 4, s48_cons(s48_enter_integer(SH.min_width), s48_enter_integer(SH.min_height))); if ((SH.flags & PMaxSize) != 0) S48_VECTOR_SET(v, 5, s48_cons(s48_enter_integer(SH.max_width), s48_enter_integer(SH.max_height))); if ((SH.flags & PResizeInc) != 0) S48_VECTOR_SET(v, 6, s48_cons(s48_enter_integer(SH.width_inc), s48_enter_integer(SH.height_inc))); if ((SH.flags & PAspect) != 0) S48_VECTOR_SET(v, 7, s48_cons(s48_cons(s48_enter_integer(SH.min_aspect.x), s48_enter_integer(SH.min_aspect.y)), s48_cons(s48_enter_integer(SH.max_aspect.x), s48_enter_integer(SH.max_aspect.y)))); if ((SH.flags & PBaseSize) != 0) S48_VECTOR_SET(v, 8, s48_cons(s48_enter_integer(SH.base_width), s48_enter_integer(SH.base_height))); if ((SH.flags & PWinGravity) != 0) 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 hints) { XSizeHints SH; long mask = 0; int i; for (i=0; i<10; i++) { s48_value v = S48_VECTOR_REF(hints, i); switch (i) { case 0: mask |= USPosition; SH.x = s48_extract_integer(S48_CAR(v)); SH.y = s48_extract_integer(S48_CDR(v)); break; case 1: mask |= USSize; SH.width = s48_extract_integer(S48_CAR(v)); SH.height = s48_extract_integer(S48_CDR(v)); break; case 2: mask |= PPosition; SH.x = s48_extract_integer(S48_CAR(v)); SH.y = s48_extract_integer(S48_CDR(v)); break; case 3: mask |= PSize; SH.width = s48_extract_integer(S48_CAR(v)); SH.height = s48_extract_integer(S48_CDR(v)); break; case 4: mask |= PMinSize; SH.min_width = s48_extract_integer(S48_CAR(v)); SH.min_height = s48_extract_integer(S48_CDR(v)); break; case 5: mask |= PMaxSize; SH.max_width = s48_extract_integer(S48_CAR(v)); SH.max_height = s48_extract_integer(S48_CDR(v)); break; case 6: mask |= PResizeInc; SH.width_inc = s48_extract_integer(S48_CAR(v)); SH.height_inc = s48_extract_integer(S48_CDR(v)); break; case 7: mask |= 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 8: mask |= PBaseSize; SH.base_width = s48_extract_integer(S48_CAR(v)); SH.base_height = s48_extract_integer(S48_CDR(v)); break; case 9: 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); }