Globals
A compositor offers its services as globals. cl-wl binds them without registry bookkeeping. You name the proxy class you want, and cl-wl finds the global, picks the version and returns the proxy.
Binding one global
(wl:bind display 'wl-compositor) ; => #<WL-COMPOSITOR id 4 v6 …>
(wl:bind display 'wl-seat :version 9) ; at most version 9
(wl:bind display 'zxdg-decoration-manager-v1
:errorp nil) ; NIL if not offered
bind uses the highest version that the compositor, the bindings and
:version all allow. proxy-version tells you which version that was.
If the compositor does not offer the interface, bind signals
missing-global-error:
The compositor does not offer xdg_toplevel, so XDG-TOPLEVEL cannot be bound.
GLOBAL-VERSION tells whether a global is offered.
Pass :errorp nil for interfaces your program can do without, and check
for NIL.
If the compositor offers several globals of the interface, bind binds
the first one announced. Use bind-all or follow-globals for interfaces
with one global per device, such as wl_output and wl_seat.
Binding all of them
(wl:bind-all display 'wl-output :version 4) ; => list of WL-OUTPUT proxies
bind-all takes the same :version as bind and returns one proxy per
global offered now.
Asking what is offered
(wl:global-version display 'wl-seat) ; => 7, or NIL if not offered
(wl:list-globals display)
;; => (("wl_compositor" 4) ("wl_subcompositor" 1) ("wp_viewporter" 1) …)
(wl:find-proxy-class "xdg_wm_base") ; => XDG-WM-BASE, or NIL
(wl:interface-wire-name 'xdg-wm-base) ; => "xdg_wm_base"
(wl:supported-version 'xdg-toplevel) ; => 7, the newest the bindings know
list-globals returns (interface version) pairs in the order the
compositor announced them. The interface is the protocol name.
find-proxy-class maps a protocol name to its proxy class, or to NIL if no
loaded bindings define it. With it you can bind every global your loaded
bindings know about:
(loop for (name version) in (wl:list-globals display)
for class = (wl:find-proxy-class name)
when class
collect (wl:bind display class))
Globals that come and go
Monitors are plugged in and out, and seats can appear later. When that
happens the compositor announces new globals and withdraws old ones.
follow-globals binds every global of an interface, now and as they are
announced, and gives you each proxy as it arrives. When the compositor
withdraws a global, it gives the proxy back to you:
(defvar *follower*
(wl:follow-globals display 'wl-output
:version 4
:added (lambda (output)
(watch-output output))
:removed (lambda (output)
(forget-output output)
(wl:destroy-proxy output))))
:addedis called with each proxy. It is called at once, beforefollow-globalsreturns, for the globals offered now. For globals announced later, it is called while you dispatch events.:removedis called with the proxy when its global is withdrawn. The proxy is then yours to destroy.destroy-proxysendswl_output's release request when the proxy's version has it (version 3 and later) and otherwise destroys it on the client side. By default:removedis#'destroy-proxy.stop-followingends it. The proxies it bound stay yours.
follow-globals returns a global-follower. You can have several
followers, for the same interface or for different ones.
How it works
The first call to bind, bind-all, follow-globals, global-version or
list-globals on a display creates its wl_registry and makes a
roundtrip. The roundtrip ensures that the initial set of globals is
known. It also delivers any events that were pending at the time, so do
not be surprised if handlers you set earlier run during that first call.
Later calls reuse the registry and do not block.
The registry's global and global_remove events update the display's
list of globals as you dispatch. bind therefore always sees the current
set.
The registry is created with wl-display-get-registry like any other
object. You can still create registries of your own and handle their
:global events yourself. cl-wl's registry belongs to cl-wl: do not set
its handlers or destroy it.
Binding by hand
wl-registry-bind is available like every other request. Its new_id
has no fixed interface, so it takes the proxy class and version as
arguments:
(wl-registry-bind registry name 'wl-compositor 4) ; => #<WL-COMPOSITOR …>
It signals version-error if the version is newer than the bindings
support.