Getting Started
Requirements
- SBCL.
- For
cl-windowing/wayland: a Wayland compositor and libwayland-client. Keyboards also need libxkbcommon, and cursor themes libwayland-cursor.- Debian and Ubuntu:
libwayland-client0 libwayland-cursor0 libxkbcommon0
- Debian and Ubuntu:
- For
cl-windowing/win32: Windows 10 version 1607 or later. It needs nothing beyond Windows' own DLLs. - For
cl-windowing/vulkan: the Vulkan loader and a driver that presents to Wayland or Windows.- Debian and Ubuntu:
libvulkan1, withmesa-vulkan-driversfor Mesa's drivers, lavapipe included.
- Debian and Ubuntu:
The Lisp dependencies, cl-wl,
cl-xkbcommon,
cl-win32,
cl-threads,
cl-vk and
cl-ffi, are pinned by commit in the
stiftfile and fetched with stift.
The ASDF systems
| System | What it is | Load it when |
|---|---|---|
cl-windowing |
The backend-independent API: window systems, windows, events. It cannot open windows alone. | Never on its own. The others load it. |
cl-windowing/wayland |
The Wayland backend. | You run on Wayland. |
cl-windowing/win32 |
The Windows backend. | You run on Windows. |
cl-windowing/vulkan |
Vulkan surfaces for windows, through cl-vk. | You use Vulkan directly. cl-gfx loads it for you. |
cl-windowing/test |
The test suite. | You work on cl-windowing. |
Load the backend for your platform. cl-windowing itself never depends on
a backend or on Vulkan.
A complete program
This opens a window, draws a dark blue background into it with cl-gfx, and runs until the window is closed or Escape is pressed:
(asdf:load-system :cl-windowing/wayland) ; on Windows, :cl-windowing/win32
(asdf:load-system :cl-gfx/windowing)
(defpackage #:example
(:use #:cl)
(:local-nicknames (#:win #:cl-windowing)
(#:gfx #:cl-gfx)))
(in-package #:example)
(defun run ()
(win:with-window-system (window-system)
(win:with-window (window window-system :title "Hello" :width 800 :height 600)
(gfx:with-device (device :present-to window-system)
(let ((surface (gfx:create-surface device window))
(event (win:make-event)))
(loop
(win:process-events window-system)
(loop while (win:poll-event window-system event)
do (case (win:event-type event)
(:close (return-from run))
(:key-press (when (eq (win:event-key event) :escape)
(return-from run)))))
(gfx:with-frame (frame device)
(let ((texture (gfx:acquire-surface-texture surface frame)))
(when texture
(gfx:with-render-pass (pass frame :color ((texture :clear '(0.1 0.2 0.3 1))))
;; Draw here.
))))))))))
(run)
What happens:
with-window-systemconnects to the compositor, with the platform's backend::wayland, or:win32on Windows.with-windowcreates the window. Nothing is visible yet.- Each turn of the loop,
process-eventshandles what the compositor sent without waiting, andpoll-eventhands out the events one by one. - cl-gfx draws a frame. Until the window system has given the window its
first size,
acquire-surface-texturereturnsniland nothing is drawn. After that, the first frame makes the window appear. The surface follows the window's size and scale by itself; see Resizing and Scaling. - Leaving
runcloses the device, then destroys the window, then disconnects. The forms are nested so that this is the order.
The frame is paced by the display, because cl-gfx surfaces present in
:fifo mode by default, so the loop does not spin.
In a larger program, events and rendering usually run on two threads. See Threads.
Using it from the REPL
Everything that with-window-system and with-window do can be done step
by step:
(defvar *ws* (win:open-window-system))
(defvar *w* (win:create-window *ws* :title "REPL"))
(win:process-events *ws* :timeout 1)
(win:window-configured-p *w*) ; => T
(win:window-size *w*) ; => 800, 600 where the compositor keeps the size asked for
(setf (win:window-title *w*) "Renamed")
(win:destroy-window *w*)
(win:close-window-system *ws*)
The window system expects answers. A compositor may decide that a client
that does not call process-events for a while is not responding.
Running the tests
cd cl-windowing
stift test
asdf:test-system signals an error if any test fails, so the command exits unsuccessfully.
- On Linux, the protocol tests run against cl-wl's in-process compositor,
cl-wl/test-compositor. They need only libwayland (libwayland-client0 libwayland-server0 libwayland-cursor0) and no running compositor. - The Vulkan tests start a headless Weston (
weston) and present to it. They need a Vulkan driver that presents to Wayland, such as lavapipe. - When the Khronos validation layer is installed
(
vulkan-validationlayers), the Vulkan tests run under it and fail on any error it reports. - On Windows, the suite tests
cl-windowing/win32against the desktop: it opens windows, so it needs a desktop session. The clipboard test uses the desktop's clipboard and puts back the text it held, so it needs the session unlocked; the test of capturing the pointer moves the real pointer, and puts it back afterwards.
CI runs the suite on SBCL, on Linux. The Windows backend is tested on Windows, outside CI.