448 lines
17 KiB
Scheme
448 lines
17 KiB
Scheme
;; Author: David Frese
|
|
|
|
;; create-window creates an unmapped subwindow for a specified parent
|
|
;; window. depth can be 'copy-from-parent. class can be one of
|
|
;; 'input-output, 'input-only or 'copy-from-parent. visual can be
|
|
;; 'copy-from-parent too (see create-simple-window). See
|
|
;; change-window-attributes and make-set-window-attribute-alist for
|
|
;; the attributes argument.
|
|
|
|
(define (create-window parent x y width height border-width depth class
|
|
visual set-window-attribute-alist)
|
|
(let ((attribs (set-window-attribute-alist->vector
|
|
set-window-attribute-alist))
|
|
(depth (cond
|
|
((eq? depth 'copy-from-parent) #f)
|
|
((number? depth) depth)
|
|
(else (error "invalid depth" depth))))
|
|
(class (case class
|
|
((input-output) 0)
|
|
((input-only) 1)
|
|
((copy-from-parent) 2)
|
|
(else (error "invalid class specifier" class))))
|
|
(visual (cond
|
|
((eq? visual 'copy-from-parent) #f)
|
|
((visual? visual) (visual-Xvisual visual))
|
|
(else (error "invalid visual") visual)))
|
|
(display (window-display parent)))
|
|
(let ((Xwindow (%create-window
|
|
(display-Xdisplay display)
|
|
(window-Xwindow parent)
|
|
x y width height border-width
|
|
depth class visual
|
|
attribs)))
|
|
(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 depth class Xvisual attribs)
|
|
"scx_Create_Window")
|
|
|
|
;; create-simple-window calls create-window with the default value 1
|
|
;; for border-width, 0 for x and y, and 'copy-from-parent for depth,
|
|
;; class and visual.
|
|
|
|
(define (create-simple-window parent width height
|
|
set-window-attribute-alist)
|
|
(create-window parent 0 0 width height 1
|
|
'copy-from-parent 'copy-from-parent 'copy-from-parent
|
|
set-window-attribute-alist))
|
|
|
|
;; *** change-window-attributes **************************************
|
|
|
|
;; enumerated type for window attributes that can be changed in
|
|
;; create-window and with change-window-attributes.
|
|
|
|
(define-enumerated-type set-window-attribute :set-window-attribute
|
|
set-window-attribute?
|
|
set-window-attributes
|
|
set-window-attribute-name
|
|
set-window-attribute-index
|
|
;; don't change the order of the attributes!
|
|
;; special values: background-pixmap can be a pixmap,
|
|
;; 'parent-relative or 'none. border-pixmap can be a pixmap or
|
|
;; 'copy-from-parent.
|
|
(background-pixmap background-pixel border-pixmap border-pixel
|
|
bit-gravity gravity backing-store backing-planes backing-pixel
|
|
override-redirect save-under event-mask do-not-propagate-mask colormap
|
|
cursor))
|
|
|
|
(define set-window-attribute-alist->vector
|
|
(make-enum-alist->vector
|
|
set-window-attributes set-window-attribute-index
|
|
(lambda (i)
|
|
(case i
|
|
((0) (lambda (background)
|
|
(cond
|
|
((pixmap? background) (pixmap-Xpixmap background))
|
|
((eq? background 'parent-relative) background)
|
|
((none-resource? background) 0)
|
|
(else (error "invalid background pixmap"
|
|
background)))))
|
|
((1) pixel-Xpixel)
|
|
((2) (lambda (border)
|
|
(cond
|
|
((pixmap? border) (pixmap-Xpixmap border))
|
|
((eq? border 'copy-from-parent) border)
|
|
(else (error "invalid border pixmap"
|
|
border)))))
|
|
((3) pixel-Xpixel)
|
|
((8) pixel-Xpixel)
|
|
((9) (lambda (override-redirect)
|
|
(if override-redirect 1 0)))
|
|
((10) (lambda (save-under)
|
|
(if save-under 1 0)))
|
|
((13) colormap-Xcolormap)
|
|
((14) cursor-Xcursor)
|
|
(else (lambda (x) x))))))
|
|
|
|
;; a macro for an easier creation of such an alist.
|
|
|
|
(define set-window-attribute-by-name
|
|
(let* ((attributes (vector->list set-window-attributes))
|
|
(alist (map cons (map set-window-attribute-name
|
|
attributes)
|
|
attributes)))
|
|
(lambda (name)
|
|
(let ((r (assq name alist)))
|
|
(if r
|
|
(cdr r)
|
|
(error "attribute name not defined" name))))))
|
|
|
|
;(define-syntax make-set-window-attribute-alist
|
|
; (syntax-rules ()
|
|
; ((make-set-window-attribute-alist) '())
|
|
; ((make-set-window-attribute-alist 'item)
|
|
; `(cons (cons ,(set-window-attribute-by-name (car item))
|
|
; ,(cadr item))
|
|
; '()))
|
|
; ((make-set-window-attribute-alist item1 item2 ...)
|
|
; (cons (cons (set-window-attribute-by-name (car item1))
|
|
; (cadr item1))
|
|
; (make-set-window-attribute-alist item2 ...)))))
|
|
|
|
;; change-window-attributes takes an alist of set-window-attributes
|
|
;; mapping to specific values. See XChangeWindowAttributes.
|
|
|
|
(define (change-window-attributes window set-window-attribute-alist)
|
|
(%change-window-attributes (window-Xwindow window)
|
|
(display-Xdisplay (window-display window))
|
|
(set-window-attribute-alist->vector
|
|
set-window-attribute-alist)))
|
|
|
|
(import-lambda-definition %change-window-attributes (Xwindow Xdisplay attribs)
|
|
"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 attribute)
|
|
(lambda (window value)
|
|
(change-window-attributes window (list (cons attribute value)))))
|
|
|
|
(define set-window-background-pixmap!
|
|
(make-win-attr-setter (set-window-attribute background-pixmap)))
|
|
(define set-window-background-pixel!
|
|
(make-win-attr-setter (set-window-attribute background-pixel)))
|
|
(define set-window-border-pixmap!
|
|
(make-win-attr-setter (set-window-attribute border-pixmap)))
|
|
(define set-window-border-pixel!
|
|
(make-win-attr-setter (set-window-attribute border-pixel)))
|
|
(define set-window-bit-gravity!
|
|
(make-win-attr-setter (set-window-attribute bit-gravity)))
|
|
(define set-window-gravity!
|
|
(make-win-attr-setter (set-window-attribute gravity)))
|
|
(define set-window-backing-store!
|
|
(make-win-attr-setter (set-window-attribute backing-store)))
|
|
(define set-window-backing-planes!
|
|
(make-win-attr-setter (set-window-attribute backing-planes)))
|
|
(define set-window-backing-pixel!
|
|
(make-win-attr-setter (set-window-attribute backing-pixel)))
|
|
(define set-window-save-under!
|
|
(make-win-attr-setter (set-window-attribute save-under)))
|
|
(define set-window-event-mask!
|
|
(make-win-attr-setter (set-window-attribute event-mask)))
|
|
(define set-window-do-not-propagate-mask!
|
|
(make-win-attr-setter (set-window-attribute do-not-propagate-mask)))
|
|
(define set-window-override-redirect!
|
|
(make-win-attr-setter (set-window-attribute override-redirect)))
|
|
(define set-window-colormap!
|
|
(make-win-attr-setter (set-window-attribute colormap)))
|
|
(define set-window-cursor!
|
|
(make-win-attr-setter (set-window-attribute cursor)))
|
|
|
|
;; *** configure-window **********************************************
|
|
;; an enumerated type for configure-window (see XConfigureWindow)
|
|
|
|
(define-enumerated-type window-change :window-change
|
|
window-change?
|
|
window-changes
|
|
window-change-name
|
|
window-change-index
|
|
; do not change this order
|
|
; sibling is a window, stack-mode can be one of 'above, 'below,
|
|
; 'top-if, 'buttom-if and 'opposite.
|
|
(x y width height border-width sibling stack-mode))
|
|
|
|
(define window-change-alist->vector
|
|
(make-enum-alist->vector
|
|
window-changes window-change-index
|
|
(lambda (i)
|
|
(case i
|
|
((5) window-Xwindow)
|
|
(else (lambda (x) x))))))
|
|
|
|
;; This sets the window-attributes listed above
|
|
|
|
(define (configure-window window window-change-alist)
|
|
(%configure-window (window-Xwindow window)
|
|
(display-Xdisplay (window-display window))
|
|
(window-change-alist->vector
|
|
window-change-alist)))
|
|
|
|
(import-lambda-definition %configure-window (Xwindow Xdisplay changes)
|
|
"scx_Configure_Window")
|
|
|
|
;; the following mutators are based on configure-window
|
|
|
|
(define (make-win-configurer change)
|
|
(lambda (window value)
|
|
(configure-window window (list (cons change value)))))
|
|
|
|
(define set-window-x! (make-win-configurer (window-change x)))
|
|
(define set-window-y! (make-win-configurer (window-change y)))
|
|
(define set-window-width! (make-win-configurer (window-change width)))
|
|
(define set-window-height! (make-win-configurer (window-change height)))
|
|
(define set-window-border-width!
|
|
(make-win-configurer (window-change border-width)))
|
|
(define set-window-sibling! (make-win-configurer (window-change sibling)))
|
|
(define set-window-stack-mode!
|
|
(make-win-configurer (window-change stack-mode)))
|
|
|
|
;; *** get-window-attributes *****************************************
|
|
;; get-window-attributes returns attributes of the specified window.
|
|
|
|
(define-enumerated-type window-attribute :window-attribute
|
|
window-attribute?
|
|
window-attributes
|
|
window-attribute-name
|
|
window-attribute-index
|
|
;; don't change the order of the attributes!
|
|
;; screen is not supported yet - so it will be always #f
|
|
(x y width height border-width depth visual root class bit-gravity
|
|
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))
|
|
|
|
(define vector->window-attribute-alist
|
|
(make-vector->enum-alist
|
|
window-attributes
|
|
(lambda (i display)
|
|
(case i
|
|
((13) (lambda (Xpixel) ; backing-pixel
|
|
(make-pixel Xpixel #f #f)))
|
|
((7) (lambda (Xwindow) ; root
|
|
(make-window Xwindow display #f)))
|
|
((15) (lambda (Xcolormap)
|
|
(make-colormap Xcolormap display #f)))
|
|
((6) make-visual)
|
|
(else (lambda (x) x))))))
|
|
|
|
(define (get-window-attributes window)
|
|
(let ((Xwindow (window-Xwindow window))
|
|
(Xdisplay (display-Xdisplay (window-display window))))
|
|
(let ((values (%get-window-attributes Xdisplay Xwindow)))
|
|
(if (not values)
|
|
(error "cannot get window attributes." window)
|
|
(vector->window-attribute-alist values (window-display window))))))
|
|
|
|
(import-lambda-definition %get-window-attributes (Xdisplay Xwindow)
|
|
"scx_Get_Window_Attributes")
|
|
|
|
(define (make-win-attr-getter attribute)
|
|
(lambda (window)
|
|
(cdr (assq attribute (get-window-attributes window)))))
|
|
|
|
(define window-x (make-win-attr-getter (window-attribute x)))
|
|
(define window-y (make-win-attr-getter (window-attribute y)))
|
|
(define window-width (make-win-attr-getter (window-attribute width)))
|
|
(define window-height (make-win-attr-getter (window-attribute height)))
|
|
(define window-border-width
|
|
(make-win-attr-getter (window-attribute border-width)))
|
|
(define window-depth (make-win-attr-getter (window-attribute depth)))
|
|
(define window-visual (make-win-attr-getter (window-attribute visual)))
|
|
(define window-root (make-win-attr-getter (window-attribute root)))
|
|
(define window-class (make-win-attr-getter (window-attribute class)))
|
|
(define window-bit-gravity
|
|
(make-win-attr-getter (window-attribute bit-gravity)))
|
|
(define window-gravity
|
|
(make-win-attr-getter (window-attribute gravity)))
|
|
(define window-backing-store
|
|
(make-win-attr-getter (window-attribute backing-store)))
|
|
(define window-backing-planes
|
|
(make-win-attr-getter (window-attribute backing-planes)))
|
|
(define window-backing-pixel
|
|
(make-win-attr-getter (window-attribute backing-pixel)))
|
|
(define window-save-under (make-win-attr-getter (window-attribute save-under)))
|
|
(define window-colormap (make-win-attr-getter (window-attribute colormap)))
|
|
(define window-map-installed
|
|
(make-win-attr-getter (window-attribute map-installed)))
|
|
(define window-map-state (make-win-attr-getter (window-attribute map-state)))
|
|
(define window-all-event-masks
|
|
(make-win-attr-getter (window-attribute all-event-masks)))
|
|
(define window-your-event-mask
|
|
(make-win-attr-getter (window-attribute your-event-mask)))
|
|
(define window-do-not-propagate-mask
|
|
(make-win-attr-getter (window-attribute do-not-propagate-mask)))
|
|
(define window-override-redirect
|
|
(make-win-attr-getter (window-attribute override-redirect)))
|
|
|
|
;; 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->list (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")
|