/* window.c * * $Id$ * * Copyright 1990, 1991, 1992, 1993, 1994, 1995, Oliver Laumann, Berlin * Copyright 2002, 2003 Sam Hocevar , Paris * * This software was derived from Elk 1.2, which was Copyright 1987, 1988, * 1989, Nixdorf Computer AG and TELES GmbH, Berlin (Elk 1.2 has been written * by Oliver Laumann for TELES Telematic Services, Berlin, in a joint project * between TELES and Nixdorf Microprocessor Engineering, Berlin). * * Oliver Laumann, TELES GmbH, Nixdorf Computer AG and Sam Hocevar, as co- * owners or individual owners of copyright in this software, grant to any * person or company a worldwide, royalty free, license to * * i) copy this software, * ii) prepare derivative works based on this software, * iii) distribute copies of this software or derivative works, * iv) perform this software, or * v) display this software, * * provided that this notice is not removed and that neither Oliver Laumann * nor Teles nor Nixdorf are deemed to have made any representations as to * the suitability of this software for any purpose nor are held responsible * for any defects of this software. * * THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ #include "xlib.h" static Object Sym_Set_Attr, Sym_Get_Attr, Sym_Geo; Object Sym_Conf; Generic_Predicate (Window) Generic_Equal_Dpy (Window, WINDOW, win) Generic_Print (Window, "#[window %lu]", WINDOW(x)->win) Generic_Get_Display (Window, WINDOW) Object Make_Window (int finalize, Display *dpy, Window win) { Object w; if (win == None) return Sym_None; if (win == PointerRoot) return Intern ("pointer-root"); w = Find_Object (T_Window, (GENERIC)dpy, Match_X_Obj, win); if (Nullp (w)) { w = Alloc_Object (sizeof (struct S_Window), T_Window, 0); WINDOW(w)->tag = Null; WINDOW(w)->win = win; WINDOW(w)->dpy = dpy; WINDOW(w)->free = 0; WINDOW(w)->finalize = finalize; Register_Object (w, (GENERIC)dpy, finalize ? P_Destroy_Window : (PFO)0, 0); } return w; } Window Get_Window (Object w) { if (EQ(w, Sym_None)) return None; Check_Type (w, T_Window); return WINDOW(w)->win; } Drawable Get_Drawable (Object d, Display **dpyp) { if (TYPE(d) == T_Window) { *dpyp = WINDOW(d)->dpy; return (Drawable)WINDOW(d)->win; } else if (TYPE(d) == T_Pixmap) { *dpyp = PIXMAP(d)->dpy; return (Drawable)PIXMAP(d)->pm; } Wrong_Type_Combination (d, "drawable"); /*NOTREACHED*/ } static Object P_Create_Window (Object parent, Object x, Object y, Object width, Object height, Object border_width, Object attr) { unsigned long mask; Window win; Check_Type (parent, T_Window); mask = Vector_To_Record (attr, Set_Attr_Size, Sym_Set_Attr, Set_Attr_Rec); if ((win = XCreateWindow (WINDOW(parent)->dpy, WINDOW(parent)->win, Get_Integer (x), Get_Integer (y), Get_Integer (width), Get_Integer (height), Get_Integer (border_width), CopyFromParent, CopyFromParent, CopyFromParent, mask, &SWA)) == 0) Primitive_Error ("cannot create window"); return Make_Window (1, WINDOW(parent)->dpy, win); } static Object P_Configure_Window (Object w, Object conf) { unsigned long mask; Check_Type (w, T_Window); mask = Vector_To_Record (conf, Conf_Size, Sym_Conf, Conf_Rec); XConfigureWindow (WINDOW(w)->dpy, WINDOW(w)->win, mask, &WC); return Void; } static Object P_Change_Window_Attributes (Object w, Object attr) { unsigned long mask; Check_Type (w, T_Window); mask = Vector_To_Record (attr, Set_Attr_Size, Sym_Set_Attr, Set_Attr_Rec); XChangeWindowAttributes (WINDOW(w)->dpy, WINDOW(w)->win, mask, &SWA); return Void; } static Object P_Get_Window_Attributes (Object w) { Check_Type (w, T_Window); XGetWindowAttributes (WINDOW(w)->dpy, WINDOW(w)->win, &WA); return Record_To_Vector (Win_Attr_Rec, Win_Attr_Size, Sym_Get_Attr, WINDOW(w)->dpy, ~0L); } static Object P_Get_Geometry (Object d) { Display *dpy; Drawable dr = Get_Drawable (d, &dpy); /* GEO.width, GEO.height, etc. should really be unsigned, not int. */ XGetGeometry (dpy, dr, &GEO.root, &GEO.x, &GEO.y, (unsigned *)&GEO.width, (unsigned *)&GEO.height, (unsigned *)&GEO.border_width, (unsigned *)&GEO.depth); return Record_To_Vector (Geometry_Rec, Geometry_Size, Sym_Geo, dpy, ~0L); } static Object P_Map_Window (Object w) { Check_Type (w, T_Window); XMapWindow (WINDOW(w)->dpy, WINDOW(w)->win); return Void; } static Object P_Unmap_Window (Object w) { Check_Type (w, T_Window); XUnmapWindow (WINDOW(w)->dpy, WINDOW(w)->win); return Void; } Object P_Destroy_Window (Object w) { Check_Type (w, T_Window); if (!WINDOW(w)->free) XDestroyWindow (WINDOW(w)->dpy, WINDOW(w)->win); Deregister_Object (w); WINDOW(w)->free = 1; return Void; } static Object P_Destroy_Subwindows (Object w) { Check_Type (w, T_Window); XDestroySubwindows (WINDOW(w)->dpy, WINDOW(w)->win); return Void; } static Object P_Map_Subwindows (Object w) { Check_Type (w, T_Window); XMapSubwindows (WINDOW(w)->dpy, WINDOW(w)->win); return Void; } static Object P_Unmap_Subwindows (Object w) { Check_Type (w, T_Window); XUnmapSubwindows (WINDOW(w)->dpy, WINDOW(w)->win); return Void; } static Object P_Circulate_Subwindows (Object w, Object dir) { Check_Type (w, T_Window); XCirculateSubwindows (WINDOW(w)->dpy, WINDOW(w)->win, Symbols_To_Bits (dir, 0, Circulate_Syms)); return Void; } static Object P_Query_Tree (Object w) { Window root, parent, *children; Display *dpy; unsigned int i, n; Object v, ret; GC_Node2; Check_Type (w, T_Window); dpy = WINDOW(w)->dpy; Disable_Interrupts; XQueryTree (dpy, WINDOW(w)->win, &root, &parent, &children, &n); Enable_Interrupts; v = ret = Null; GC_Link2 (v, ret); v = Make_Window (0, dpy, root); ret = Cons (v, Null); v = Make_Window (0, dpy, parent); ret = Cons (v, ret); v = Make_Vector (n, Null); for (i = 0; i < n; i++) { Object x; x = Make_Window (0, dpy, children[i]); VECTOR(v)->data[i] = x; } ret = Cons (v, ret); GC_Unlink; return ret; } static Object P_Translate_Coordinates (Object src, Object x, Object y, Object dst) { int rx, ry; Window child; Object l, t, z; GC_Node3; Check_Type (src, T_Window); Check_Type (dst, T_Window); if (!XTranslateCoordinates (WINDOW(src)->dpy, WINDOW(src)->win, WINDOW(dst)->win, Get_Integer (x), Get_Integer (y), &rx, &ry, &child)) return False; l = t = P_Make_List (Make_Integer (3), Null); GC_Link3 (l, t, dst); Car (t) = Make_Integer (rx); t = Cdr (t); Car (t) = Make_Integer (ry), t = Cdr (t); z = Make_Window (0, WINDOW(dst)->dpy, child); Car (t) = z; GC_Unlink; return l; } static Object P_Query_Pointer (Object win) { Object l, t, z; Bool ret; Window root, child; int r_x, r_y, x, y; unsigned int mask; GC_Node3; Check_Type (win, T_Window); ret = XQueryPointer (WINDOW(win)->dpy, WINDOW(win)->win, &root, &child, &r_x, &r_y, &x, &y, &mask); t = l = P_Make_List (Make_Integer (8), Null); GC_Link3 (l, t, win); Car (t) = Make_Integer (x); t = Cdr (t); Car (t) = Make_Integer (y); t = Cdr (t); Car (t) = ret ? True : False; t = Cdr (t); z = Make_Window (0, WINDOW(win)->dpy, root); Car (t) = z; t = Cdr (t); Car (t) = Make_Integer (r_x); t = Cdr (t); Car (t) = Make_Integer (r_y); t = Cdr (t); z = Make_Window (0, WINDOW(win)->dpy, child); Car (t) = z; t = Cdr (t); z = Bits_To_Symbols ((unsigned long)mask, 1, State_Syms); Car (t) = z; GC_Unlink; return l; } void elk_init_xlib_window () { Define_Symbol (&Sym_Set_Attr, "set-window-attributes"); Define_Symbol (&Sym_Get_Attr, "get-window-attributes"); Define_Symbol (&Sym_Conf, "window-configuration"); Define_Symbol (&Sym_Geo, "geometry"); Generic_Define (Window, "window", "window?"); Define_Primitive (P_Window_Display, "window-display", 1, 1, EVAL); Define_Primitive (P_Create_Window, "xlib-create-window", 7, 7, EVAL); Define_Primitive (P_Configure_Window, "xlib-configure-window", 2, 2, EVAL); Define_Primitive (P_Change_Window_Attributes, "xlib-change-window-attributes", 2, 2, EVAL); Define_Primitive (P_Get_Window_Attributes, "xlib-get-window-attributes", 1, 1, EVAL); Define_Primitive (P_Get_Geometry, "xlib-get-geometry",1, 1, EVAL); Define_Primitive (P_Map_Window, "map-window", 1, 1, EVAL); Define_Primitive (P_Unmap_Window, "unmap-window", 1, 1, EVAL); Define_Primitive (P_Circulate_Subwindows, "circulate-subwindows", 2, 2, EVAL); Define_Primitive (P_Destroy_Window, "destroy-window", 1, 1, EVAL); Define_Primitive (P_Destroy_Subwindows, "destroy-subwindows", 1, 1, EVAL); Define_Primitive (P_Map_Subwindows, "map-subwindows", 1, 1, EVAL); Define_Primitive (P_Unmap_Subwindows, "unmap-subwindows", 1, 1, EVAL); Define_Primitive (P_Query_Tree, "query-tree", 1, 1, EVAL); Define_Primitive (P_Translate_Coordinates, "translate-coordinates", 4, 4, EVAL); Define_Primitive (P_Query_Pointer, "query-pointer", 1, 1, EVAL); }