[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Low-level CLX tests
Here's some simple CLX test cases I came up with while trying to
understand how CLX works and to check that my window manager and CLX
implementation behaved reasonably. I haven't made a test case that
does anything with color correctly yet, I'd appreciate receiving one.
This code is in the public domain.
;;; -*- Mode: Lisp; Package: xlib -*-
;;;
;;; Trivial test file for clx.
;;;
;;; Author: Timothy Freeman. Last Modified Sat Aug 26 02:55:58 1989
(in-package :xlib) (use-package :ergolisp)
(export '(clx-test))
(defun clx-test (host)
"Do something, anything, to check that this software works at least a little bit."
(let* ((display (open-display host))
(screen (display-default-screen display))
(root (screen-root screen))
(win (create-window :parent root :x 0 :y 0 :width 100 :height 100
:event-mask
'(:exposure :key-press)))
(gcontext (create-gcontext :drawable root :function boole-c1
:foreground 1 :background 0)))
(map-window win)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
(:exposure (window)
(draw-line win gcontext 0 0 100 100))
(:key-press ()
t))
(return (values))))
(close-display display))))
(defun cursor-test (host &optional (cursornum 0))
(let* ((display (open-display host))
(screen (display-default-screen display))
(root (screen-root screen))
(win (create-window :parent root :x 0 :y 0 :width 100 :height 100
:event-mask
'(:exposure :key-press :button-press)
:background 1))
(letter-font (open-font display "vtsingle"))
(gcontext (create-gcontext :drawable root :function boole-c1
:foreground 1 :background 0
:font letter-font))
(cursor-font (open-font display "cursor")))
(labels ((setf-cursornum (value)
(setq cursornum value)
(clear-area win)
(draw-glyphs win gcontext 0 40 (format nil "~s" cursornum))
(values)))
(map-window win)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
(:key-press ()
t)
(:button-press
(code)
(cond
((= code 1) (setq cursornum (+ cursornum 2)))
((= code 3) (setq cursornum (- cursornum 2))))
(setf-cursornum (min 254 (max 0 cursornum)))
(let ((cursor
(create-glyph-cursor
:source-font cursor-font
:source-char cursornum
:mask-font cursor-font
:mask-char (1+ cursornum)
:foreground
(make-color :red 0.0 :green 0.0 :blue 0.0)
:background
(make-color :red 1.0 :green 1.0 :blue 1.0))))
(setf (window-cursor win) cursor)
(free-cursor cursor))
nil))
(return (values))))
(close-display display)))))
(defun configure-notify-test (host)
(let* ((display (open-display host))
(screen (display-default-screen display))
(root (screen-root screen))
(win (create-window :parent root :x 0 :y 0 :width 100 :height 100
:event-mask
'(:exposure :key-press
:button-press
:structure-notify)))
(gcontext (create-gcontext :drawable root :function boole-c1
:foreground 1 :background 0)))
(map-window win)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
(:key-press (window)
(with-state (window)
(setf (drawable-width window) 100)
(setf (drawable-height
window) 100))
nil)
(:button-press (window)
t)
(:exposure (x y width height count)
(format t "Exposure, x = ~s, y = ~s, width = ~s, ~
height = ~s, count = ~s.~%"
x y width height count)
nil)
(:configure-notify (x y width height window
override-redirect-p)
(format t "Configure-notify, x = ~s, y = ~s, width = ~s, ~
height = ~s, override = ~s, window = ~s.~%"
x y width height override-redirect-p window)
nil))
(return (values))))
(close-display display))))
#|
(subwin-test "k.ergo.cs.cmu.edu")
|#
(defun subwin-test (host)
"Test that if X is a subwindow of Y and the mouse is in X and Y is unmapped,
X gets a leave-window event. This was a bug in X10. You'll have to
interrupt to get out of this function.
This function shows the bug has been fixed in X11, our version at least."
(let* ((display (open-display host))
(screen (display-default-screen display))
(root (screen-root screen))
(win (create-window :parent root :x 0 :y 0 :width 100 :height 100
:event-mask
'(:leave-window :enter-window)))
(win2 (create-window :parent win :x 0 :y 0 :width 50 :height 50
:event-mask
'(:leave-window :enter-window :key-press
:button-press)))
(win3 (create-window :parent win2 :x 0 :y 0 :width 25 :height 25
:event-mask
'(:leave-window :enter-window :key-press
:button-press)))
(gcontext (create-gcontext :drawable root :function boole-c1
:foreground 1 :background 0)))
(map-window win)
(map-window win2)
(map-window win3)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
((:enter-notify :leave-notify) (event-key x y window)
(format t "~s, x = ~s, y = ~s, win = ~s.~%"
event-key x y
(cond ((eq window win) "win")
((eq window win2) "win2")
(t window)))
nil)
((:key-press) (window)
(unmap-window win)))
(return (values))))
(close-display display))))
(defun resize-test (host)
"Verify that lowly mortals like me can use ResizeRedirect."
(let* ((display (open-display host))
(screen (display-default-screen display))
(root (screen-root screen))
(win (create-window :parent root :x 0 :y 0 :width 100 :height 100
:border-width 1
:event-mask '(:resize-redirect
:key-press
:button-press
:structure-notify)))
(gcontext (create-gcontext :drawable root :function boole-c1
:foreground 1 :background 0)))
(map-window win)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
((:button-press) ()
(setf (drawable-width win) 100)
(setf (drawable-height win) 100)
nil)
((:resize-request) (window width height)
(format t "Resize-request, width is ~s, height is ~s.~%"
width height)
(format t "Real width is ~s, real height is ~s.~%"
(drawable-width window)
(drawable-height window))
(let ((wor (window-override-redirect window)))
(setf (window-override-redirect window) :on)
(setf (drawable-width window) width)
(setf (drawable-height window) height)
(setf (window-override-redirect window) wor))
(format t "Real width is ~s, real height is ~s.~%"
(drawable-width window)
(drawable-height window))
nil)
((:configure-notify) (width height)
(format t "configure-notify, width is ~s, height is ~s.~%"
width height)
nil)
((:key-press) ()
(unmap-window win)
t))
(return (values))))
(close-display display))))
#|
(title-test "k.ergo.cs.cmu.edu")
|#
(defun title-test (host)
(let* ((display (open-display host))
(screen (display-default-screen display))
(root (screen-root screen))
(win (create-window :parent root :x 0 :y 0 :width 100 :height 100
:border-width 1
:event-mask '(:key-press
:button-press))))
(setf (wm-name win) "Tim's window")
(setf (wm-icon-name win) "Tim's icon")
(map-window win)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
((:button-press :key-press) (window)
(destroy-window window)
t))
(return (values))))
(close-display display))))
#|
(position-test "k.ergo.cs.cmu.edu")
|#
;;; Conclusion: For twm, wm-normal-hints is useless. The position
;;; and size are adjustable when the window is mapped iff the x and y
;;; are 0 and they aren't otherwise.
(defun position-test (host)
(let* ((display (open-display host))
(screen (display-default-screen display))
(root (screen-root screen))
(win (create-window :parent root :x 100 :y 0 :width 100 :height 100
:border-width 1
:event-mask '(:key-press
:button-press)))
(size-hints (make-wm-size-hints :user-specified-position-p nil
:user-specified-size-p nil
:width 300
:height 400
)))
(setf (wm-normal-hints win) size-hints)
(map-window win)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
((:button-press :key-press) (window)
(destroy-window window)
t))
(return (values))))
(close-display display))))
;;; Does the size that TWM uses depend on the size when the window was
;;; created or the size when it's mapped?
;;; Conclusion: it uses the size when created. It even ignores
;;; resizes to the window after it is mapped unless there is a sleep
;;; between mapping and resizing.
#|
(twm-size-test "k.ergo.cs.cmu.edu")
|#
(defun twm-size-test (host)
(let* ((display (open-display host))
(screen (display-default-screen display))
(root (screen-root screen))
(win (create-window :parent root :x 100 :y 0 :width 100 :height 100
:border-width 1
:event-mask '(:key-press
:button-press))))
(setf (drawable-width win) 400)
(setf (drawable-height win) 400)
(format t "Width is ~s.~%" (drawable-width win))
(map-window win)
(display-finish-output display)
(setf (drawable-width win) 400)
(setf (drawable-height win) 400)
(display-force-output display)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
((:button-press :key-press) (window)
(destroy-window window)
t))
(return (values))))
(close-display display))))
;;; Try out the colormap stuff. As a first attempt, I'll try doing
;;; the straightforward protocol requests instead of following the ICCCM.
;;; This doesn't work.
#|
(colormap-test "batcomputer.ergo.cs.cmu.edu" 1)
|#
(defun colormap-test (host &optional (screennum 0))
(let* ((display (open-display host))
(screen (nth screennum (display-roots display)))
(root (screen-root screen))
(colormap (create-colormap (window-visual root) root nil))
(pixel (elt (alloc-color-cells colormap 1) 0))
(gcontext (create-gcontext :drawable root :function boole-c1
:foreground pixel :background 0))
(win (create-window :parent root :x 100 :y 0 :width 100 :height 100
:border-width 1
:colormap colormap
:event-mask '(:key-press
:button-press
:exposure))))
(format t "Pixel is ~s.~%" pixel)
(display-force-output display)
(store-colors colormap `(,pixel "Green"))
(map-window win)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
((:button-press :key-press) (window)
(destroy-window window)
t)
((:exposure) (window)
(draw-line window gcontext 0 0 100 100)))
(return (values))))
(close-display display))))
(defun colormap-test (host &optional (screennum 0))
(let* ((display (open-display host))
(screen (nth screennum (display-roots display)))
(root (screen-root screen))
(colormap (create-colormap (window-visual root) root nil))
(pixel (elt (alloc-color-cells colormap 1) 0))
(gcontext (create-gcontext :drawable root :function boole-c1
:foreground pixel :background 0))
(win (create-window :parent root :x 100 :y 0 :width 100 :height 100
:border-width 1
:colormap colormap
:event-mask '(:key-press
:button-press
:exposure))))
(format t "Pixel is ~s.~%" pixel)
(display-force-output display)
(store-colors colormap `(,pixel "Green"))
(map-window win)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
((:button-press :key-press) (window)
(destroy-window window)
t)
((:exposure) (window)
(draw-line window gcontext 0 0 100 100)))
(return (values))))
(close-display display))))
;;; Or maybe I should modify the root's colormap?
#|
(colormap-test-2 "batcomputer.ergo.cs.cmu.edu" 1)
|#
(defun colormap-test-2 (host &optional (screennum 0))
(let* ((display (open-display host))
(screen (nth screennum (display-roots display)))
(root (screen-root screen))
(colormap (prog1 (window-colormap root) (display-finish-output display)))
(foo (prog1 (lookup-color colormap "green") (display-finish-output display)))
(pixel (elt (alloc-color-cells colormap 1) 0))
(gcontext (create-gcontext :drawable root :function boole-c1
:foreground pixel :background 0))
(win (create-window :parent root :x 100 :y 0 :width 100 :height 100
:border-width 1
:colormap colormap
:event-mask '(:key-press
:button-press
:exposure))))
(display-finish-output display)
(store-colors colormap `(,pixel ,(make-color :red 0.0 :green 1.0 :blue 1.0)))
(display-finish-output display)
(map-window win)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
((:button-press :key-press) (window)
(destroy-window window)
t)
((:exposure) (window)
(draw-line window gcontext 0 0 100 100)))
(return (values))))
(close-display display))))
#|
(transient-test "k.ergo.cs.cmu.edu")
|#
;;; Does WM_TRANSIENT_FOR really work? Yup.
(defun transient-test (host &optional (screennum 0))
(let* ((display (open-display host))
(screen (nth screennum (display-roots display)))
(root (screen-root screen))
(win (create-window :parent root :x 100 :y 0 :width 100 :height 100
:border-width 1
:event-mask '(:key-press
:button-press
:button-release)))
(menu (create-window :parent root :x 10 :y 10 :width 50 :height 50
:border-width 1
:event-mask '(:button-release))))
(map-window win)
; (setf (transient-for menu) win)
(setf (transient-for menu) root)
(unwind-protect
(loop
(when (event-case (display :discard-p t)
((:button-press) (window)
(when (eq window win) (map-window menu)))
((:button-release) (window)
(unmap-window menu))
((:key-press) (window)
(destroy-window window)
(destroy-window menu)
t))
(return (values))))
(close-display display))))