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