#include "xlib.h" #include "scheme48.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 = 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_enter_integer(p->icon_x)); S48_VECTOR_SET(res, 5, s48_enter_integer(p->icon_y)); } if (p->flags && IconMaskHint) S48_VECTOR_SET(res, 6, SCX_ENTER_PIXMAP(p->icon_mask)); if (p->flags && WindowGroupHint) // 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(); } XFree((char*)p); return res; } s48_value scx_Set_Wm_Hints (s48_value dpy, s48_value w, s48_value alist) { unsigned long mask = 0; s48_value l, p, v; XWMHints WMH; char* cname; for (l = alist; !S48_NULL_P(l); l = S48_CDR(l)) { p = S48_CAR(l); v = S48_CDR(p); cname = s48_extract_symbol(S48_CAR(p)); if (strcmp(cname, "input?") == 0) { mask |= InputHint; WMH.input = !S48_FALSE_P(v); } else if (strcmp(cname, "initial-state") == 0) { mask |= StateHint; WMH.initial_state = Symbol_To_Bit((unsigned long)s48_extract_integer(v), Initial_State_Syms); } else if (strcmp(cname, "icon-pixmap") == 0) { mask |= IconPixmapHint; WMH.icon_pixmap = SCX_EXTRACT_PIXMAP(v); } else if (strcmp(cname, "icon-window") == 0) { mask |= IconWindowHint; WMH.icon_window = SCX_EXTRACT_WINDOW(v); } 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 !! } } 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(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); }