scx/scheme/xlib/window.scm

331 lines
13 KiB
Scheme

;; Author: David Frese
;; create-window takes an alist of names and values - see
;; change-window-attributes and configure-window. Mandatory arguments for
;; create-window are 'parent, 'width and 'height. Example:
;; (create-window 'parent root 'width 500 'height 300 '((border-width . 4)))
;; Returns the new window or raises an exception if something went wrong.
(define (create-window . args)
(let ((alist (named-args->alist args)))
(receive (x y width height border-width parent change-win-attr-list)
(alist-split alist '((x . 0) (y . 0) (width . #f) (height . #f)
(border-width . 2) (parent . #f)))
(let* ((change-win-attr-list
(map cons
(map car change-win-attr-list)
(map (lambda (obj)
(cond
((pixel? obj) (pixel-Xpixel obj))
((pixmap? obj) (pixmap-Xpixmap obj))
((colormap? obj) (colormap-Xcolormap obj))
;; cursor...??
(else obj)))
(map cdr change-win-attr-list))))
(display (window-display parent))
(Xwindow (%create-window (display-Xdisplay display)
(window-Xwindow parent)
x y width height border-width
change-win-attr-list)))
(if (= Xwindow 0)
(error "cannot create window")
(make-window Xwindow display #t))))))
(import-lambda-definition %create-window (Xdisplay Xparent x y width height
border-width attrAlist)
"scx_Create_Window")
;; change-window-attributes takes an alist of names and values...
;; names can be: background-pixmap, background-pixel, border-pixmap,
;; border-pixel, bit-gravity, gravity, backing-store, backing-planes,
;; backing-pixel, save-under, event-mask, do-not-propagate-mask,
;; override-redirect, colormap, cursor.
(define (change-window-attributes window . attrs)
(let* ((alist (named-args->alist attrs))
(prep-alist
(map cons
(map car alist)
(map (lambda (value)
(cond
;; Abstractions ?? :
((pixmap? value) (pixmap-Xpixmap value))
((pixel? value) (pixel-Xpixel value))
((colormap? value) (colormap-Xcolormap value))
;... ((cursor? value) (cursor-Xcursor value))
(else value)))
(map cdr alist)))))
(%change-window-attributes (window-Xwindow window)
(display-Xdisplay (window-display window))
prep-alist)))
(import-lambda-definition %change-window-attributes (Xwindow Xdisplay alist)
"scx_Change_Window_Attributes")
;; simple functions that use change-window-attributes
;; TODO: a caching system for multiple calls to these functions
(define (make-win-attr-setter name)
(lambda (window value)
(change-window-attributes window (list (cons name value)))))
(define set-window-background-pixmap! (make-win-attr-setter 'background-pixmap))
(define set-window-background-pixel! (make-win-attr-setter 'background-pixel))
(define set-window-border-pixmap! (make-win-attr-setter 'border-pixmap))
(define set-window-border-pixel! (make-win-attr-setter 'border-pixel))
(define set-window-bit-gravity! (make-win-attr-setter 'bit-gravity))
(define set-window-gravity! (make-win-attr-setter 'gravity))
(define set-window-backing-store! (make-win-attr-setter 'backing-store))
(define set-window-backing-planes! (make-win-attr-setter 'backing-planes))
(define set-window-backing-pixel! (make-win-attr-setter 'backing-pixel))
(define set-window-save-under! (make-win-attr-setter 'save-under))
(define set-window-event-mask! (make-win-attr-setter 'event-mask))
(define set-window-do-not-propagate-mask!
(make-win-attr-setter 'do-not-propagate-mask))
(define set-window-override-redirect! (make-win-attr-setter 'override-redirect))
(define set-window-colormap! (make-win-attr-setter 'colormap))
(define set-window-cursor! (make-win-attr-setter 'cursor))
;; get-window-attributes gives back the same attributes that
;; set-window-attributes sets and some more ...
(define (get-window-attributes window)
(let ((Xwindow (window-Xwindow window))
(Xdisplay (display-Xdisplay (window-display window))))
(let ((v (%get-window-attributes Xdisplay Xwindow)))
(if (not v)
(error "cannot get window attributes." window)
(let*
((comp (lambda (i f) (vector-set! v i (f (vector-ref v i)))))
(mod-v (begin
(comp 13 make-pixel) ;; backing-pixel
(comp 7 (lambda (Xwin) ;; root
(make-window Xwin (window-display window)
#f)))
(comp 15 (lambda (Xcolormap)
(make-colormap Xcolormap
(window-display window)
#f)))
;; font, visual ??
v))
(alist (map cons
'(x y width height border-width depth visual root
class bit-gravity win-gravity backing-store
backing-planes backing-pixel save-under colormap
map-installed map-state all-event-masks
your-event-mask do-not-propagate-mask
override-redirect screen
; screen not supported
)
(vector->list mod-v))))
alist)))))
(import-lambda-definition %get-window-attributes (Xdisplay Xwindow)
"scx_Get_Window_Attributes")
(define (make-win-attr-getter name)
(lambda (window)
(cdr (assq name (get-window-attributes window)))))
(define window-x (make-win-attr-getter 'x))
(define window-y (make-win-attr-getter 'y))
(define window-width (make-win-attr-getter 'width))
(define window-height (make-win-attr-getter 'height))
(define window-border-width (make-win-attr-getter 'border-width))
(define window-depth (make-win-attr-getter 'depth))
(define window-visual (make-win-attr-getter 'visual))
(define window-root (make-win-attr-getter 'root))
(define window-class (make-win-attr-getter 'class))
(define window-bit-gravity (make-win-attr-getter 'bit-gravity))
(define window-backing-store (make-win-attr-getter 'backing-store))
(define window-backing-planes (make-win-attr-getter 'backing-planes))
(define window-backing-pixel (make-win-attr-getter 'backing-pixel))
(define window-save-under (make-win-attr-getter 'save-under))
(define window-colormap (make-win-attr-getter 'colormap))
(define window-map-installed (make-win-attr-getter 'map-installed))
(define window-map-state (make-win-attr-getter 'map-state))
(define window-all-event-masks (make-win-attr-getter 'all-event-masks))
(define window-your-event-mask (make-win-attr-getter 'your-event-mask))
(define window-do-not-propagate-mask
(make-win-attr-getter 'do-not-propagate-mask))
(define window-override-redirect (make-win-attr-getter 'override-redirect))
;; This sets the window-attributes listed below - call like create-window.
(define (configure-window window . args)
(let* ((args (named-args->alist args))
(prep-alist (map cons
(map car args)
(map (lambda (val)
(if (window? val)
(window-Xwindow val)
val))
(map cdr args)))))
(%configure-window (window-Xwindow window)
(display-Xdisplay (window-display window))
prep-alist)))
(import-lambda-definition %configure-window (Xwindow Xdisplay alist)
"scx_Configure_Window")
;; the following mutators are based on configure-window
(define (make-win-configurer name)
(lambda (window value)
(configure-window window (list (cons name value)))))
(define set-window-x! (make-win-configurer 'x))
(define set-window-y! (make-win-configurer 'y))
(define set-window-width! (make-win-configurer 'width))
(define set-window-height! (make-win-configurer 'height))
(define set-window-border-width! (make-win-configurer 'border-width))
(define set-window-sibling! (make-win-configurer 'sibling))
(define set-window-stack-mode! (make-win-configurer 'stack-mode))
;; The map-window function maps the window and all of its subwindows that have
;; had map requests. See XMapWindow.
(define (map-window window)
(%map-window (window-Xwindow window)
(display-Xdisplay (window-display window))))
(import-lambda-definition %map-window (Xwindow Xdisplay)
"scx_Map_Window")
;; The unmap-window function unmaps the specified window and causes the
;; X server to generate an unmap-notify event. See XUnmapWindow.
(define (unmap-window window)
(%unmap-window (window-Xwindow window)
(display-Xdisplay (window-display window))))
(import-lambda-definition %unmap-window (Xwindow Xdisplay)
"scx_Unmap_Window")
;; The destroy-subwindows function destroys all inferior windows of the
;; specified window, in bottom-to-top stacking order. See XDestroySubWindows.
(define (destroy-subwindows window)
(%destroy-subwindows (window-Xwindow window)
(display-Xdisplay (window-display window))))
(import-lambda-definition %destroy-subwindows (Xwindow Xdisplay)
"scx_Destroy_Subwindows")
;; The map-subwindows function maps all subwindows for a specified window in
;; top-to-bottom stacking order. See XMapSubwindows
(define (map-subwindows window)
(%map-subwindows (window-Xwindow window)
(display-Xdisplay (window-display window))))
(import-lambda-definition %map-subwindows (Xwindow Xdisplay)
"scx_Map_Subwindows")
;; The unmap-subwindows function unmaps all subwindows for each subwindow
;; and expose events on formerly obscured windows. See XUnmapSubwindow.
(define (unmap-subwindows window)
(%unmap-subwindows (window-Xwindow window)
(display-Xdisplay (window-display window))))
(import-lambda-definition %unmap-subwindows (Xwindow Xdisplay)
"scx_Unmap_Subwindows")
;; See XCirculateSubwindows.
(define (circulate-subwindows window direction)
(%destroy-subwindows (window-Xwindow window)
(display-Xdisplay (window-display window))
(eq? direction 'lower-highest)))
; other is: 'raise-lower / exception??
(import-lambda-definition %circulate-subwindows (Xwindow Xdisplay dir)
"scx_Circulate_Subwindows")
;; The clear-window function clears the entire area in the specified window.
;; See XClearWindow.
(define (clear-window window)
(clear-area window 0 0 0 0 #f))
;; The raise-window (lower-window) function raises (lowers) the specified window
;; to the top (button) of the stack so that no sibling window obscures it (it
;; does not obscure any sibling windows). See XRaiseWindow.
(define (raise-window window)
(set-window-stack-mode! window 'above))
(define (lower-window window)
(set-window-stack-mode! window 'below))
;; The restack-windows function restacks the windows in the order specified,
;; from top to bottom. The stacking order of the first window in the windows
;; list is unaffected, but the other windows in the array are stacked underneath
;; the first window, in the order of the list. See XRestackWindows.
(define (restack-windows window-list)
(let loop ((w (car window-list))
(t (cdr window-list)))
(if (not (null? t))
(let ((n (car t)))
(set-window-sibling! n w)
(set-window-stack-mode! n 'below)
(loop n (cdr t))))))
;; query-tree returns a list of three elements: root window, parent window and
;; child windows of the given window. See XQueryTree.
(define (query-tree window)
(let* ((display (window-display window))
(res (%query-tree (window-Xwindow window)
(display-Xdisplay display))))
(list
(make-window (vector-ref res 0) display #f)
(make-window (vector-ref res 1) display #f)
(vector-map! (lambda (Xwindow)
(make-window Xwindow display #f))
(vector-ref res 2)))))
(import-lambda-definition %query-tree (Xwindow Xdisplay)
"scx_Query_Tree")
;; translate-coordinates takes the x and y coordinates relative to the source
;; window's origin and returns a list of three elements: the x and y coordinates
;; relative to the destination window's origin. If the source window and the
;; destination window are on different screens the result is #f. See
;; XTranslateCoordinates.
(define (translate-coordinates src-window x y dst-window)
(let* ((display (window-display src-window))
(res (%translate-coordinates
(display-Xdisplay display)
(window-Xwindow src-window)
x y
(window-Xwindow dst-window))))
(if res
(begin
(vector-set! res 2 (make-window (vector-ref res 2) display #f))
(vector->list res))
#f)))
(import-lambda-definition %translate-coordinates (Xdisplay srcXwindow x y
srcXwindow)
"scx_Translate_Coordinates")
;; query-pointer returns a list of eight elements: x and y coordinates, a
;; boolean indicating whether the pointer is on the same screen as the specified
;; window, the root window, the root window's x and y coordinates, the child
;; window and a list of modifier names (see grab-button). See XQueryPointer.
(define (query-pointer window)
(let* ((display (window-display window))
(res (%query-pointer (display-Xdisplay display)
(window-Xwindow window))))
(vector-set! res 3 (make-window (vector-ref res 3) display #f))
(vector-set! res 6 (make-window (vector-ref res 6) display #f))
(vector->list res)))
(import-lambda-definition %query-pointer (Xdisplay Xwindow)
"scx_Query_Pointer")