#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 // 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); }