[RFC wayland] System compositor protocol
jason at jlekstrand.net
Fri Aug 23 14:55:41 PDT 2013
I am in the process of picking back up the old idea of system compositors.
I am not, at the moment, looking for a review of the code; simply a review
of the concept and the proposed protocol. If you would like to look at my
implementation or try it out, it can be found in the system-compositor
branch of my personal [weston fork on github].
What follows is what I envision for system compositors. (Others may have a
different idea which is why I'm writing this RFC email.) The basic idea
behind a system compositor is to provide an interface for compositors whose
only job it is to display other compositors or other stand-alone
full-screen interfaces. I image three primary purposes for system
1. As an abstraction layer. Every time someone wants to write a RDP
server, VNC server, android backend, or the like the standard answer is
"write it as a weston plugin". The problem with this is that, to my
knowledge, none of the major desktop environments (GNOME, KDE, EFL,
etc.) plan to run their compositor as a weston shell plugin. This makes
a weston plugin a poor solution in the long term. On the other hand, a
system compositor is fairly simple to implement and provides a backend
to any compositor that can run on top of a system compositor.
2. Simple full-screen clients. With standard VTs going the way of the dodo
bird (see also [David Herrmann's work on logind]), we will need a way
for displaying simple full-screen programs such as splashscreens without
every single one of them knowing how to talk DRM/KMS directly. David
has proposed to use a system compositor (which he calls wlsystemc in his
post) so these types of programs can be written as simple wayland
clients. My github repository contains the (almost trivial)
modifications to simple-shm that make it in to one such client.
3. As a DRM/KMS backend for other compositors. Manually dealing with
DRM/KMS isn't actually all that many lines and all of the big
compositors (mutter, Kwin, EFL, etc.) will do it themselves. However,
for people who want to write their own simple compositor, it can be a
bit tricky to get right and raises the barrier to entry. The protocol
I'm proposing is sufficiently powerful to provide most of the basic
multi-output support and modesetting that is needed for a simple
compositor. This means that all a potential compositor writer has to do
is write a system compositor client and they can let someone else get
the KMS details right.
While it sounds like a big task, implementing a system compositor isn't
that bad. The simplest system compositor is one that can simply display
surfaces. In order to do that, you need to implement the following
* wl_shm (along with wl_shm_pool and a SHM-based wl_buffer)
None of those are particularly difficult or complicated to implement. The
hardest is probably wl_surface and that's not terrible.
For input you have two options. The first, most obvious option is to
implement wl_seat and its child interfaces. Second, I have considered the
idea of a wl_raw_input interface (only for system compositors) that simply
provides evdev file descriptors to the client. This would allow for raw
input processing without having to worry about things like weston-launch.
Also the system compositor *may* be able to handle the FD muting etc. for
playing nice with logind. (I'm not sure on that one yet, I'd have to ask
One more note on input: I do NOT expect the system compositor to do any
significant input processing. Even if the child compositor is getting its
events through wl_seat, I expect them to be about as raw as possible. In
particular, this is not where things like pointer acceleration should be
handled. Once we get a pointer_grab interface working, I expect any
compositor that runs on top of a system compositor to attempt a pointer
grab almost immediately and do its own pointer handling from there.
Otherwise it is impossible for the client compositor to re-arrange the
outputs without additional protocol.
Along with the basics as described above, a system compositor could
optionally implement additional interfaces to provide aditional
functionality. For example:
* A RDP system compositor could implement wl_data_device to allow for
drag-and-drop and clipboard sharing between host and client.
* A system compositor could expose wl_subcompositor and use subsurfaces to
allow the client compositor to take advangage of hardware compositing.
Note that this is not as simple as it sounds because hardware frequently
has limits on the number, size, and placement of such overlays and there
is currently no way to communicate that information through the
subsurface protocol. Therefore, the system compositor could find itself
doing a full composite anyway.
* A wl_user_switcher interface could be created for login managers. This
steps on logind a bit, but someone may find it useful.
That is about all I have to say for now on the subject. If you want to
check out my current implementation you can look at my github as I said
above. As of right now, I have multi-monitor weston running inside of my
weston-based system compositor. Also, I have simple-shm modified to act as
a simple system compositor client if finds the wl_system_compositor global.
The only mode that works right now is "center" but I'm working on getting
the others to work.
I appreciate any questions or comments you may have on either the main
ideas (above) or the protocol (below).
<interface name="wl_system_compositor" version="1">
<description summary="Displays a single surface per output">
Displays a single surface per output.
This interface can only be bound to by one client at a time.
<description summary="different method to set the surface fullscreen">
Hints to indicate to the compositor how to deal with a conflict
between the dimensions of the surface and the dimensions of the
output. The compositor is free to ignore this parameter.
<entry name="default" value="0" summary="no preference, apply default policy"/>
<entry name="scale" value="1" summary="scale, preserve the surface's aspect ratio and center on output"/>
<entry name="driver" value="2" summary="switch output mode to the smallest mode that can fit the surface, add black borders to compensate size mismatch"/>
<entry name="fill" value="3" summary="no upscaling, center on output and add black borders to compensate size mismatch"/>
<description summary="present surface for display">
This requests the system compositor to display surface on output.
Each client of the system compositor can have at most one surface
per output at any one time. Subsequent requests with the same
output replace the surface bound to that output. The same surface
may be presented on multiple outputs.
If the output is null, the compositor will present the surface on
whatever display (or displays) it thinks best. In particular, this
may replace any or all surfaces currently presented so it should
not be used in combination with placing surfaces on specific
The method specifies how the surface is to be persented. These
methods are identical to those in wl_shell_surface.set_fullscreen.
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="method" type="uint"/>
<arg name="framerate" type="uint"/>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
More information about the wayland-devel