mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-02-25 01:41:11 -05:00
doc: run docbook -> mdbook conversion tool
To reproduce this commit, delete the contents of the src directory and run the tool. Signed-off-by: Julian Orth <ju.orth@gmail.com>
This commit is contained in:
parent
cbc4bebf20
commit
b7690b4e4d
12 changed files with 1695 additions and 0 deletions
1
doc/book/.gitignore
vendored
Normal file
1
doc/book/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/book
|
||||||
9
doc/book/book.toml
Normal file
9
doc/book/book.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
[book]
|
||||||
|
title = "Wayland"
|
||||||
|
authors = ["Kristian Høgsberg"]
|
||||||
|
language = "en"
|
||||||
|
|
||||||
|
[output.html]
|
||||||
|
git-repository-url = "https://gitlab.freedesktop.org/wayland/wayland"
|
||||||
|
edit-url-template = "https://gitlab.freedesktop.org/wayland/wayland/-/edit/main/doc/book/{path}"
|
||||||
|
site-url = "/docs/book/"
|
||||||
215
doc/book/src/Architecture.md
Normal file
215
doc/book/src/Architecture.md
Normal file
|
|
@ -0,0 +1,215 @@
|
||||||
|
# Wayland Architecture
|
||||||
|
|
||||||
|
## X vs. Wayland Architecture
|
||||||
|
|
||||||
|
A good way to understand the Wayland architecture and how it is different from X
|
||||||
|
is to follow an event from the input device to the point where the change it
|
||||||
|
affects appears on screen.
|
||||||
|
|
||||||
|
This is where we are now with X:
|
||||||
|
|
||||||
|
**X architecture diagram**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
1. The kernel gets an event from an input device and sends it to X through the
|
||||||
|
evdev input driver. The kernel does all the hard work here by driving the
|
||||||
|
device and translating the different device specific event protocols to the
|
||||||
|
linux evdev input event standard.
|
||||||
|
|
||||||
|
2. The X server determines which window the event affects and sends it to the
|
||||||
|
clients that have selected for the event in question on that window. The X
|
||||||
|
server doesn't actually know how to do this right, since the window location
|
||||||
|
on screen is controlled by the compositor and may be transformed in a number
|
||||||
|
of ways that the X server doesn't understand (scaled down, rotated, wobbling,
|
||||||
|
etc).
|
||||||
|
|
||||||
|
3. The client looks at the event and decides what to do. Often the UI will have
|
||||||
|
to change in response to the event - perhaps a check box was clicked or the
|
||||||
|
pointer entered a button that must be highlighted. Thus the client sends a
|
||||||
|
rendering request back to the X server.
|
||||||
|
|
||||||
|
4. When the X server receives the rendering request, it sends it to the driver
|
||||||
|
to let it program the hardware to do the rendering. The X server also
|
||||||
|
calculates the bounding region of the rendering, and sends that to the
|
||||||
|
compositor as a damage event.
|
||||||
|
|
||||||
|
5. The damage event tells the compositor that something changed in the window
|
||||||
|
and that it has to recomposite the part of the screen where that window is
|
||||||
|
visible. The compositor is responsible for rendering the entire screen
|
||||||
|
contents based on its scenegraph and the contents of the X windows. Yet, it
|
||||||
|
has to go through the X server to render this.
|
||||||
|
|
||||||
|
6. The X server receives the rendering requests from the compositor and either
|
||||||
|
copies the compositor back buffer to the front buffer or does a pageflip. In
|
||||||
|
the general case, the X server has to do this step so it can account for
|
||||||
|
overlapping windows, which may require clipping and determine whether or not
|
||||||
|
it can page flip. However, for a compositor, which is always fullscreen, this
|
||||||
|
is another unnecessary context switch.
|
||||||
|
|
||||||
|
As suggested above, there are a few problems with this approach. The X server
|
||||||
|
doesn't have the information to decide which window should receive the event,
|
||||||
|
nor can it transform the screen coordinates to window-local coordinates. And
|
||||||
|
even though X has handed responsibility for the final painting of the screen to
|
||||||
|
the compositing manager, X still controls the front buffer and modesetting. Most
|
||||||
|
of the complexity that the X server used to handle is now available in the
|
||||||
|
kernel or self contained libraries (KMS, evdev, mesa, fontconfig, freetype,
|
||||||
|
cairo, Qt etc). In general, the X server is now just a middle man that
|
||||||
|
introduces an extra step between applications and the compositor and an extra
|
||||||
|
step between the compositor and the hardware.
|
||||||
|
|
||||||
|
In Wayland the compositor is the display server. We transfer the control of KMS
|
||||||
|
and evdev to the compositor. The Wayland protocol lets the compositor send the
|
||||||
|
input events directly to the clients and lets the client send the damage event
|
||||||
|
directly to the compositor:
|
||||||
|
|
||||||
|
**Wayland architecture diagram**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
1. The kernel gets an event and sends it to the compositor. This is similar to
|
||||||
|
the X case, which is great, since we get to reuse all the input drivers in
|
||||||
|
the kernel.
|
||||||
|
|
||||||
|
2. The compositor looks through its scenegraph to determine which window should
|
||||||
|
receive the event. The scenegraph corresponds to what's on screen and the
|
||||||
|
compositor understands the transformations that it may have applied to the
|
||||||
|
elements in the scenegraph. Thus, the compositor can pick the right window
|
||||||
|
and transform the screen coordinates to window-local coordinates, by applying
|
||||||
|
the inverse transformations. The types of transformation that can be applied
|
||||||
|
to a window is only restricted to what the compositor can do, as long as it
|
||||||
|
can compute the inverse transformation for the input events.
|
||||||
|
|
||||||
|
3. As in the X case, when the client receives the event, it updates the UI in
|
||||||
|
response. But in the Wayland case, the rendering happens in the client, and
|
||||||
|
the client just sends a request to the compositor to indicate the region that
|
||||||
|
was updated.
|
||||||
|
|
||||||
|
4. The compositor collects damage requests from its clients and then
|
||||||
|
recomposites the screen. The compositor can then directly issue an ioctl to
|
||||||
|
schedule a pageflip with KMS.
|
||||||
|
|
||||||
|
## Wayland Rendering
|
||||||
|
|
||||||
|
One of the details I left out in the above overview is how clients actually
|
||||||
|
render under Wayland. By removing the X server from the picture we also removed
|
||||||
|
the mechanism by which X clients typically render. But there's another mechanism
|
||||||
|
that we're already using with DRI2 under X: direct rendering. With direct
|
||||||
|
rendering, the client and the server share a video memory buffer. The client
|
||||||
|
links to a rendering library such as OpenGL that knows how to program the
|
||||||
|
hardware and renders directly into the buffer. The compositor in turn can take
|
||||||
|
the buffer and use it as a texture when it composites the desktop. After the
|
||||||
|
initial setup, the client only needs to tell the compositor which buffer to use
|
||||||
|
and when and where it has rendered new content into it.
|
||||||
|
|
||||||
|
This leaves an application with two ways to update its window contents:
|
||||||
|
|
||||||
|
1. Render the new content into a new buffer and tell the compositor to use that
|
||||||
|
instead of the old buffer. The application can allocate a new buffer every
|
||||||
|
time it needs to update the window contents or it can keep two (or more)
|
||||||
|
buffers around and cycle between them. The buffer management is entirely
|
||||||
|
under application control.
|
||||||
|
|
||||||
|
2. Render the new content into the buffer that it previously told the compositor
|
||||||
|
to to use. While it's possible to just render directly into the buffer shared
|
||||||
|
with the compositor, this might race with the compositor. What can happen is
|
||||||
|
that repainting the window contents could be interrupted by the compositor
|
||||||
|
repainting the desktop. If the application gets interrupted just after
|
||||||
|
clearing the window but before rendering the contents, the compositor will
|
||||||
|
texture from a blank buffer. The result is that the application window will
|
||||||
|
flicker between a blank window or half-rendered content. The traditional way
|
||||||
|
to avoid this is to render the new content into a back buffer and then copy
|
||||||
|
from there into the compositor surface. The back buffer can be allocated on
|
||||||
|
the fly and just big enough to hold the new content, or the application can
|
||||||
|
keep a buffer around. Again, this is under application control.
|
||||||
|
|
||||||
|
In either case, the application must tell the compositor which area of the
|
||||||
|
surface holds new contents. When the application renders directly to the shared
|
||||||
|
buffer, the compositor needs to be noticed that there is new content. But also
|
||||||
|
when exchanging buffers, the compositor doesn't assume anything changed, and
|
||||||
|
needs a request from the application before it will repaint the desktop. The
|
||||||
|
idea that even if an application passes a new buffer to the compositor, only a
|
||||||
|
small part of the buffer may be different, like a blinking cursor or a spinner.
|
||||||
|
|
||||||
|
## Accelerated GPU Buffer Exchange
|
||||||
|
|
||||||
|
Clients
|
||||||
|
[exchange](https://docs.kernel.org/userspace-api/dma-buf-alloc-exchange.html)
|
||||||
|
GPU buffers with the compositor as dma-buf file descriptors, which are universal
|
||||||
|
handles that are independent of any particular rendering API or memory
|
||||||
|
allocator. The
|
||||||
|
[linux-dmabuf-v1](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/stable/linux-dmabuf/linux-dmabuf-v1.xml)
|
||||||
|
protocol is used to turn one or more dma-buf FDs into a
|
||||||
|
[wl_buffer](https://wayland.app/protocols/wayland#wl_buffer).
|
||||||
|
|
||||||
|
If the client uses the
|
||||||
|
[Vulkan](https://docs.vulkan.org/spec/latest/chapters/VK_KHR_surface/wsi.html)
|
||||||
|
or
|
||||||
|
[EGL](https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_platform_wayland.txt)
|
||||||
|
(via
|
||||||
|
[wayland-egl](https://gitlab.freedesktop.org/wayland/wayland/-/tree/main/egl))
|
||||||
|
window-system integration (WSI), this is done transparently by the WSI.
|
||||||
|
|
||||||
|
Clients can alternatively allocate and import dma-bufs themselves using the GBM
|
||||||
|
library, Vulkan, udmabuf, or dma-buf heaps.
|
||||||
|
|
||||||
|
- Using GBM, the client can allocate a gbm_bo and export one or more dma-buf FDs
|
||||||
|
from it.
|
||||||
|
|
||||||
|
- Using Vulkan, the client can create a VkDeviceMemory object and use
|
||||||
|
[VK_EXT_external_memory_dma_buf](https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_external_memory_dma_buf.html)
|
||||||
|
and
|
||||||
|
[VK_EXT_image_drm_format_modifier](https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_image_drm_format_modifier.html)
|
||||||
|
to export a dma-buf FD from it.
|
||||||
|
|
||||||
|
- [udmabuf](https://lwn.net/Articles/749206/) can be used to create dma-buf FDs
|
||||||
|
from linear host memory.
|
||||||
|
|
||||||
|
- [Dma-buf heaps](https://docs.kernel.org/userspace-api/dma-buf-heaps.html) can
|
||||||
|
be used by privileged applications to create dma-buf FDs on embedded devices.
|
||||||
|
|
||||||
|
Compositors use
|
||||||
|
[VK_EXT_external_memory_dma_buf](https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_external_memory_dma_buf.html)
|
||||||
|
and
|
||||||
|
[VK_EXT_image_drm_format_modifier](https://docs.vulkan.org/refpages/latest/refpages/source/VK_EXT_image_drm_format_modifier.html)
|
||||||
|
or
|
||||||
|
[EGL_EXT_image_dma_buf_import](https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import.txt)
|
||||||
|
and
|
||||||
|
[EGL_EXT_image_dma_buf_import_modifiers](https://registry.khronos.org/EGL/extensions/EXT/EGL_EXT_image_dma_buf_import_modifiers.txt)
|
||||||
|
to import the dma-bufs provided by the client into their own Vulkan or EGL
|
||||||
|
renderers.
|
||||||
|
|
||||||
|
Clients do not need to wait for the GPU to finish rendering before submitting
|
||||||
|
dma-bufs to the compositor. Clients can use the
|
||||||
|
[linux-drm-syncobj-v1](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/linux-drm-syncobj/linux-drm-syncobj-v1.xml)
|
||||||
|
protocol to exchange DRM synchronization objects with the compositor. These
|
||||||
|
objects are used to asynchronously signal ownership transfer of buffers from
|
||||||
|
clients to the compositor and vice versa. The WSIs do this transparently.
|
||||||
|
|
||||||
|
If the linux-drm-syncobj-v1 protocol is not supported by the compositor, clients
|
||||||
|
and compositors can use the
|
||||||
|
[DMA_BUF_IOCTL_EXPORT_SYNC_FILE](https://docs.kernel.org/driver-api/dma-buf.html#c.dma_buf_export_sync_file)
|
||||||
|
and
|
||||||
|
[DMA_BUF_IOCTL_IMPORT_SYNC_FILE](https://docs.kernel.org/driver-api/dma-buf.html#c.dma_buf_import_sync_file)
|
||||||
|
ioctls to access and create implicit synchronization barriers.
|
||||||
|
|
||||||
|
## Display Programming
|
||||||
|
|
||||||
|
Compositors enumerate DRM KMS devices using
|
||||||
|
[udev](https://en.wikipedia.org/wiki/Udev). Udev also notifies compositors of
|
||||||
|
KMS device and display hotplug events.
|
||||||
|
|
||||||
|
Access to DRM KMS device ioctls is privileged. Since compositors usually run as
|
||||||
|
unprivileged applications, they typically gain access to a privileged file
|
||||||
|
descriptor using the
|
||||||
|
[TakeDevice](https://www.freedesktop.org/software/systemd/man/latest/org.freedesktop.login1.html#Session%20Objects)
|
||||||
|
method provided by logind.
|
||||||
|
|
||||||
|
Using the file descriptor, compositors use KMS
|
||||||
|
[ioctls](https://docs.kernel.org/gpu/drm-kms.html) to enumerate the available
|
||||||
|
displays.
|
||||||
|
|
||||||
|
Compositors use [atomic mode
|
||||||
|
setting](https://docs.kernel.org/gpu/drm-kms.html#atomic-mode-setting) to change
|
||||||
|
the buffer shown by the display, to change the display's resolution, to enable
|
||||||
|
or disable HDR, and so on.
|
||||||
100
doc/book/src/Color.md
Normal file
100
doc/book/src/Color.md
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
# Color management
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Color management in Wayland considers only displays. All pictures in Wayland are
|
||||||
|
always display-referred, meaning that the pixel values are intended as-is for
|
||||||
|
some specific display where they would produce the light emissions
|
||||||
|
([stimuli](https://cie.co.at/eilvterm/17-23-002)) the picture's author desired.
|
||||||
|
Wayland does not support displaying "raw" camera or scanner images as they are
|
||||||
|
not display-referred, nor are they even pictures without complex and subjective
|
||||||
|
processing.
|
||||||
|
|
||||||
|
Stimuli — the picture itself — are only half of the picture reproduction. The
|
||||||
|
other half is the environment where a display is viewed. A striking example is
|
||||||
|
comparing a brightly lit office to a dark movie theater, the stimuli required to
|
||||||
|
produce a good reading of the picture is greatly different. Therefore
|
||||||
|
display-referred does not include only the display but the viewing environment
|
||||||
|
as well.
|
||||||
|
|
||||||
|
Window systems have been very well capable of operating without any explicit
|
||||||
|
consideration to color management. This is because there used to be the implicit
|
||||||
|
assumption of the standard display, the sRGB display, which all computer
|
||||||
|
monitors implemented, more or less. The viewing environment was and still is
|
||||||
|
accounted by adjusting the display and/or the room to produce a workable
|
||||||
|
experience. Pictures are authored on a computer system by drawing, painting and
|
||||||
|
adjusting the picture until it looks right on the author's monitor. This
|
||||||
|
implicitly builds the standard display and environment assumption into the
|
||||||
|
picture data. Deviations from the sRGB specification were minor enough that they
|
||||||
|
often did not matter if not in a professional context like the printing
|
||||||
|
industry. Displaying video material required some more attention to the details,
|
||||||
|
because video and television standards differ enough from the sRGB display. What
|
||||||
|
really made explicit color management a hard requirement for entertainment is
|
||||||
|
the coming of wide color gamut (WCG) and high dynamic range (HDR) materials and
|
||||||
|
displays.
|
||||||
|
|
||||||
|
The color management design in Wayland follows the general Wayland design
|
||||||
|
principles: compositors tell clients what would be the optimal thing to do,
|
||||||
|
clients tell the compositors what kind of pictures they are actually producing,
|
||||||
|
and then compositors display those pictures the best they can.
|
||||||
|
|
||||||
|
## Protocol Interfaces
|
||||||
|
|
||||||
|
Color management interfaces in Wayland and divided into two protocols:
|
||||||
|
[color-management](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/tree/main/staging/color-management?ref_type=heads)
|
||||||
|
and
|
||||||
|
[color-representation](https://gitlab.freedesktop.org/wayland/wayland-protocols/-/tree/main/staging/color-representation?ref_type=heads).
|
||||||
|
They are designed to work together, but they can also be used independently when
|
||||||
|
the other one is not needed.
|
||||||
|
|
||||||
|
### Color-management
|
||||||
|
|
||||||
|
Color management protocol has two main purposes. First, it puts the
|
||||||
|
responsibility of color management on the compositor. This means that clients do
|
||||||
|
not necessarily need to care about color management at all, and can display just
|
||||||
|
fine by using the traditional standard display assumption even when the actual
|
||||||
|
display is wildly different. Clients can also choose to target some other
|
||||||
|
assumed display and let the compositor handle it, or they can explicitly render
|
||||||
|
for the actual display at hand. Second, when the window system has multiple
|
||||||
|
different monitors, and a wl_surface happens to span more than one monitor, the
|
||||||
|
compositor can display the surface content correctly on all spanned monitors
|
||||||
|
simultaneously, as much as physically possible.
|
||||||
|
|
||||||
|
Color-management protocol concentrates on colorimetry: when you have a pixel
|
||||||
|
with RGB values, what stimulus do those values represent. The stimulus
|
||||||
|
definition follows the CIE 1931 two-degree observer model. Some core concepts
|
||||||
|
here are color primaries, white point, transfer function, and dynamic range. The
|
||||||
|
viewing environment is represented in an extremely simplified way as the
|
||||||
|
reference white luminance. The connection between pixel RGB values and stimulus
|
||||||
|
plus viewing environment is recorded in an _image description_ object. Clients
|
||||||
|
can create image description objects and tag `wl_surface`s with them, to
|
||||||
|
indicate what kind of surface content there will be. Clients can also ask what
|
||||||
|
image description the compositor would prefer to have on the `wl_surface`, and
|
||||||
|
that preference can change over time, e.g. when the `wl_surface` is moved from
|
||||||
|
one `wl_output` to another. Following the compositor's preference may provide
|
||||||
|
advantages in image quality and power consumption.
|
||||||
|
|
||||||
|
Image description objects can come in two flavors: parametric and ICC-based. The
|
||||||
|
above was written with parametric image descriptions in mind, and they have
|
||||||
|
first-class support for HDR. ICC-based image descriptions are wrapping an ICC
|
||||||
|
profile and have no other data. ICC profiles are the standard tool for standard
|
||||||
|
dynamic range (SDR) display color management. This means the capabilities
|
||||||
|
between the two flavors differ, and one cannot always be replaced by the other.
|
||||||
|
Compositor support for each flavor is optional.
|
||||||
|
|
||||||
|
### Color-representation
|
||||||
|
|
||||||
|
Color-representation protocol deals with (potentially sub-sampled) YCbCr-RGB
|
||||||
|
conversion, quantization range, and the inclusion of alpha in the RGB color
|
||||||
|
channels, a.k.a. pre-multiplication. There are several different specifications
|
||||||
|
on how an YCbCr-like (including ICtCp) signal, with chroma sub-sampling or not,
|
||||||
|
is created from a full-resolution RGB image. Again, a client can tag a
|
||||||
|
`wl_surface` with color-representation metadata to tell the compositor what kind
|
||||||
|
of pixel data will be displayed through the wl_surface.
|
||||||
|
|
||||||
|
The main purpose of color-representation is to correctly off-load the YCbCr-RGB
|
||||||
|
conversion to the compositor, which can then opportunistically off-load it
|
||||||
|
further to very power-efficient fixed-function circuitry in a display
|
||||||
|
controller. This can significantly reduce power consumption when watching videos
|
||||||
|
compared to using a GPU for the same, and on some embedded hardware platforms it
|
||||||
|
is a hard requirement for processing high resolution video.
|
||||||
76
doc/book/src/Compositors.md
Normal file
76
doc/book/src/Compositors.md
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
# Types of Compositors
|
||||||
|
|
||||||
|
Compositors come in different types, depending on which role they play in the
|
||||||
|
overall architecture of the OS. For instance, a [system
|
||||||
|
compositor](#system-compositor) can be used for booting the system, handling
|
||||||
|
multiple user switching, a possible console terminal emulator and so forth. A
|
||||||
|
different compositor, a [session compositor](#session-compositor) would provide
|
||||||
|
the actual desktop environment. There are many ways for different types of
|
||||||
|
compositors to co-exist.
|
||||||
|
|
||||||
|
In this section, we introduce three types of Wayland compositors relying on
|
||||||
|
[libwayland-server](https://gitlab.freedesktop.org/wayland/wayland).
|
||||||
|
|
||||||
|
## System Compositor
|
||||||
|
|
||||||
|
A system compositor can run from early boot until shutdown. It effectively
|
||||||
|
replaces the kernel vt system, and can tie in with the systems graphical boot
|
||||||
|
setup and multiseat support.
|
||||||
|
|
||||||
|
A system compositor can host different types of session compositors, and let us
|
||||||
|
switch between multiple sessions (fast user switching, or secure/personal
|
||||||
|
desktop switching).
|
||||||
|
|
||||||
|
A linux implementation of a system compositor will typically use libudev, egl,
|
||||||
|
kms, evdev and cairo.
|
||||||
|
|
||||||
|
For fullscreen clients, the system compositor can reprogram the video scanout
|
||||||
|
address to read directly from the client provided buffer.
|
||||||
|
|
||||||
|
## Session Compositor
|
||||||
|
|
||||||
|
A session compositor is responsible for a single user session. If a system
|
||||||
|
compositor is present, the session compositor will run nested under the system
|
||||||
|
compositor. Nesting is feasible because the protocol is asynchronous; roundtrips
|
||||||
|
would be too expensive when nesting is involved. If no system compositor is
|
||||||
|
present, a session compositor can run directly on the hardware.
|
||||||
|
|
||||||
|
X applications can continue working under a session compositor by means of a
|
||||||
|
root-less X server that is activated on demand.
|
||||||
|
|
||||||
|
Possible examples for session compositors include
|
||||||
|
|
||||||
|
- gnome-shell
|
||||||
|
|
||||||
|
- moblin
|
||||||
|
|
||||||
|
- kwin
|
||||||
|
|
||||||
|
- kmscon
|
||||||
|
|
||||||
|
- rdp session
|
||||||
|
|
||||||
|
- Weston with X11 or Wayland backend is a session compositor nested in another
|
||||||
|
session compositor.
|
||||||
|
|
||||||
|
- fullscreen X session under Wayland
|
||||||
|
|
||||||
|
## Embedding Compositor
|
||||||
|
|
||||||
|
X11 lets clients embed windows from other clients, or lets clients copy pixmap
|
||||||
|
contents rendered by another client into their window. This is often used for
|
||||||
|
applets in a panel, browser plugins and similar. Wayland doesn't directly allow
|
||||||
|
this, but clients can communicate GEM buffer names out-of-band, for example,
|
||||||
|
using D-Bus, or command line arguments when the panel launches the applet.
|
||||||
|
Another option is to use a nested Wayland instance. For this, the Wayland server
|
||||||
|
will have to be a library that the host application links to. The host
|
||||||
|
application will then pass the Wayland server socket name to the embedded
|
||||||
|
application, and will need to implement the Wayland compositor interface. The
|
||||||
|
host application composites the client surfaces as part of it's window, that is,
|
||||||
|
in the web page or in the panel. The benefit of nesting the Wayland server is
|
||||||
|
that it provides the requests the embedded client needs to inform the host about
|
||||||
|
buffer updates and a mechanism for forwarding input events from the host
|
||||||
|
application.
|
||||||
|
|
||||||
|
An example for this kind of setup is firefox embedding the flash player as a
|
||||||
|
kind of special-purpose compositor.
|
||||||
214
doc/book/src/Content_Updates.md
Normal file
214
doc/book/src/Content_Updates.md
Normal file
|
|
@ -0,0 +1,214 @@
|
||||||
|
# Content Updates
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
In the Wayland protocol, requests are asynchronous but take effect immediately
|
||||||
|
when the compositor receives them. However, some requests on surfaces are not
|
||||||
|
applied immediately but are instead double-buffered to allow atomic changes.
|
||||||
|
These double-buffered changes are committed through the wl_surface.commit
|
||||||
|
request, which creates a Content Update.
|
||||||
|
|
||||||
|
Content Updates encapsulate all double-buffered state changes and can be applied
|
||||||
|
by the compositor. The complexity arises when considering subsurfaces, which can
|
||||||
|
operate in synchronized mode. When a subsurface is synchronized, its Content
|
||||||
|
Updates must be applied atomically together with the parent surface's state.
|
||||||
|
This synchronization can extend through an entire tree of subsurfaces, where
|
||||||
|
child subsurfaces inherit the synchronized behavior from their parents.
|
||||||
|
|
||||||
|
Historically, Content Updates from synchronized subsurfaces were merged into the
|
||||||
|
pending state of the parent surface on commit. However, the introduction of
|
||||||
|
constraints—which can defer the application of Content Updates—necessitated a
|
||||||
|
more sophisticated model. This led to the implementation of per-surface queues
|
||||||
|
of Content Updates, with dependencies between Content Updates across different
|
||||||
|
queues. This queuing model maintains backwards compatibility with the earlier
|
||||||
|
approach of merging Content Updates into the parent's pending state on commit.
|
||||||
|
|
||||||
|
The core protocol defines the semantics of Content Updates using per-surface
|
||||||
|
queues, but compositors that do not need to support constraints may implement
|
||||||
|
the simpler legacy model where synchronized subsurface states are merged
|
||||||
|
directly into the parent's pending state.
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
The core protocol specifies the behavior in wl_subsurface and wl_surface.commit.
|
||||||
|
The behavior can be summarized by the following rules:
|
||||||
|
|
||||||
|
1. Content Updates (CU) contain all double-buffered state of the surface and
|
||||||
|
selected state from their direct children.
|
||||||
|
|
||||||
|
2. Surfaces which are effectively synchronized create Synchronized Content
|
||||||
|
Updates (SCU), otherwise they create Desync Content Updates (DCU).
|
||||||
|
|
||||||
|
3. When a CU is created, it gets a dependency on the previous CU of the same
|
||||||
|
queues (if it exists).
|
||||||
|
|
||||||
|
4. When a CU is created, it gets a dependency on the last SCU of direct child
|
||||||
|
surfaces that are not reachable (if they exists).
|
||||||
|
|
||||||
|
5. The CUs and their dependencies form a DAG, where CUs are nodes and
|
||||||
|
dependencies are edges.
|
||||||
|
|
||||||
|
6. All DCUs starting from the front of the queues until the first SCU or the
|
||||||
|
back of the queue is reached are candidates.
|
||||||
|
|
||||||
|
7. If the maximal DAG that's reachable from a candidate (candidate DAG) does not
|
||||||
|
have any constraints, then this DAG can be applied.
|
||||||
|
|
||||||
|
8. A DAG is applied atomically by recursively applying a content update without
|
||||||
|
dependencies and removing it from the DAG.
|
||||||
|
|
||||||
|
9. Surfaces transition from effectively sync to effectively desync after their
|
||||||
|
parents.
|
||||||
|
|
||||||
|
10. When a surface transitions to effectively desync, all SCUs in its queue
|
||||||
|
which are not reachable by a DCU become DCUs.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
These examples should help to build an intuition for how content updates
|
||||||
|
actually behave. They cover the interesting edge cases, such as subsurfaces with
|
||||||
|
constraints, and transitioning from a sync subsurface to a desync one.
|
||||||
|
|
||||||
|
In all the examples below, the surface T1 refers to a toplevel surface, SS1
|
||||||
|
refers to a sub-surface which is a child of T1, and SS2 refers to a sub-surface
|
||||||
|
which is a child of SS1.
|
||||||
|
|
||||||
|
**Legend**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
**Simple Desynchronized Case**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
SS2 is effectively desynchronized and commits. This results in the
|
||||||
|
desynchronized content update (DCU) _1_.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
DCU _1_ is a candidate, and the candidate DAG reachable from DCU _1_ is only DCU
|
||||||
|
_1_ itself. DCU _1_ and thus the candidate DAG does not have any constraints and
|
||||||
|
can be applied.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The content updates of the candidate DAG get applied to the surface atomically.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
T1 commits a DCU with a _buffer-sync_ constraint. It is a candidate but its DAG
|
||||||
|
can't be applied because it contains a constraint.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
T1 commits another CU (DCU _3_) which is added at the end of the queue, with a
|
||||||
|
dependency to the previous CU (DCU _2_). Both DCU _2_ and DCU _3_ are
|
||||||
|
candidates, but both DAGs contain DCU _2_ with a constraint, and can't be
|
||||||
|
applied.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
When the constraint gets cleared, both DAGs can be applied to the surface
|
||||||
|
atomitcally (either only _2_, or _2_ and _3_).
|
||||||
|
|
||||||
|
**Simple Synchronized Case**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
SS1 and SS2 are effectively synchronized. SS2 commits SCU _1_.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
SS1 commits SCU _2_. The direct child surfaces SS2 has the last SCU _1_ in its
|
||||||
|
queue, which is not reachable. This creates a dependency from SCU _2_ to SCU
|
||||||
|
_1_.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
SS1 commits SCU _3_. The direct child surfaces SS2 has the last SCU _1_ in its
|
||||||
|
queue, which is already reachable by SCU _2_. No dependency to SCU _1_ is
|
||||||
|
created. A dependency to the previous CU of the same queue (SCU _2_) is created.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
T1 commit DCU _4_. It is a candidate, its DAG does not contain any constraint
|
||||||
|
and it can be applied.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The DAG gets applied to the surfaces atomically.
|
||||||
|
|
||||||
|
**Complex Synchronized Subsurface Case 1**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Every DCU (_1_ and _6_) contain CUs with constraints in their candidate DAG
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Waiting until the _buffer-sync_ constrain on CU _1_ is cleared, the candidate
|
||||||
|
DAG of CU _1_ does not contain constraints and can be applied
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
That leaves the candidate DAG of CU _6_ which still contains another CU with a
|
||||||
|
_buffer-sync_ constrain
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Waiting until the _buffer-sync_ constrain on CU _6_ is cleared, the candidate
|
||||||
|
DAG of _6_ does not contain CUs with constraints and can be applied.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
There is no DCU left and no constraint remaining. Nothing more can be applied
|
||||||
|
without a new CU.
|
||||||
|
|
||||||
|
**Complex Synchronized Subsurface Case 2**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Both DCUs (_1_ and _6_) have a reachable DAG containing CU _1_ with a constraint
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Waiting until the _buffer-sync_ constrain on _1_ is cleared, both DAGs contain
|
||||||
|
no CU with constraints and can be applied in any order
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
That leaves the same state as in the previous case
|
||||||
|
|
||||||
|
**Synchronized to Desynchronized Subsurface**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
There is one DCU (_4_) with its reachable DAG that cannot be applied because CU
|
||||||
|
_4_ contains a constraint
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Surface _SS1_ transitions from effectively synchronized to effectively
|
||||||
|
desynchronized. SCU _2_ is reachable by DCU _4_ so nothing changes.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Surface _SS1_ provides a new DCU (_5_) but because the CU before (_2_) is a
|
||||||
|
Synchronized CU, it is not a candidate
|
||||||
|
|
||||||
|
**Synchronized to Desynchronized Transition**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
There are four SCUs and all surfaces are effectively synchronized.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Surface _SS1_ transitions to effectively desynchronized and SCU _2_ becomes a
|
||||||
|
DCU because it is not reachable from a DCU
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Surface _SS2_ transitions to effectively desynchronized. SCUs _3_ and _4_ become
|
||||||
|
DCUs because they are not reachable from a DCU. SCU _1_ does not change because
|
||||||
|
it is reachable by DCU _2_.
|
||||||
11
doc/book/src/Foreword.md
Normal file
11
doc/book/src/Foreword.md
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Preface
|
||||||
|
|
||||||
|
This document describes the (i) Wayland architecture, (ii) Wayland model of
|
||||||
|
operation and (iii) its library API. Also, the Wayland protocol specification is
|
||||||
|
shown in the Appendix. This document is aimed primarily at Wayland developers
|
||||||
|
and those looking to program with it; it does not cover application development.
|
||||||
|
|
||||||
|
There have been many contributors to this document and since this is only the
|
||||||
|
first edition many errors are expected to be found. We appreciate corrections.
|
||||||
|
|
||||||
|
Yours, the Wayland open-source community November 2012
|
||||||
73
doc/book/src/Introduction.md
Normal file
73
doc/book/src/Introduction.md
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
# Introduction
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
Most Linux and Unix-based systems rely on the X Window System (or simply _X_) as
|
||||||
|
the low-level protocol for building bitmap graphics interfaces. On these
|
||||||
|
systems, the X stack has grown to encompass functionality arguably belonging in
|
||||||
|
client libraries, helper libraries, or the host operating system kernel. Support
|
||||||
|
for things like PCI resource management, display configuration management,
|
||||||
|
direct rendering, and memory management has been integrated into the X stack,
|
||||||
|
imposing limitations like limited support for standalone applications,
|
||||||
|
duplication in other projects (e.g. the Linux fb layer or the DirectFB project),
|
||||||
|
and high levels of complexity for systems combining multiple elements (for
|
||||||
|
example radeon memory map handling between the fb driver and X driver, or VT
|
||||||
|
switching).
|
||||||
|
|
||||||
|
Moreover, X has grown to incorporate modern features like offscreen rendering
|
||||||
|
and scene composition, but subject to the limitations of the X architecture. For
|
||||||
|
example, the X implementation of composition adds additional context switches
|
||||||
|
and makes things like input redirection difficult.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The diagram above illustrates the central role of the X server and compositor in
|
||||||
|
operations, and the steps required to get contents on to the screen.
|
||||||
|
|
||||||
|
Over time, X developers came to understand the shortcomings of this approach and
|
||||||
|
worked to split things up. Over the past several years, a lot of functionality
|
||||||
|
has moved out of the X server and into client-side libraries or kernel drivers.
|
||||||
|
One of the first components to move out was font rendering, with freetype and
|
||||||
|
fontconfig providing an alternative to the core X fonts. Direct rendering OpenGL
|
||||||
|
as a graphics driver in a client side library went through some iterations,
|
||||||
|
ending up as DRI2, which abstracted most of the direct rendering buffer
|
||||||
|
management from client code. Then cairo came along and provided a modern 2D
|
||||||
|
rendering library independent of X, and compositing managers took over control
|
||||||
|
of the rendering of the desktop as toolkits like GTK+ and Qt moved away from
|
||||||
|
using X APIs for rendering. Recently, memory and display management have moved
|
||||||
|
to the Linux kernel, further reducing the scope of X and its driver stack. The
|
||||||
|
end result is a highly modular graphics stack.
|
||||||
|
|
||||||
|
## The compositing manager as the display server
|
||||||
|
|
||||||
|
Wayland is a new display server and compositing protocol, and Weston is the
|
||||||
|
implementation of this protocol which builds on top of all the components above.
|
||||||
|
We are trying to distill out the functionality in the X server that is still
|
||||||
|
used by the modern Linux desktop. This turns out to be not a whole lot.
|
||||||
|
Applications can allocate their own off-screen buffers and render their window
|
||||||
|
contents directly, using hardware accelerated libraries like libGL, or high
|
||||||
|
quality software implementations like those found in Cairo. In the end, what’s
|
||||||
|
needed is a way to present the resulting window surface for display, and a way
|
||||||
|
to receive and arbitrate input among multiple clients. This is what Wayland
|
||||||
|
provides, by piecing together the components already in the eco-system in a
|
||||||
|
slightly different way.
|
||||||
|
|
||||||
|
X will always be relevant, in the same way Fortran compilers and VRML browsers
|
||||||
|
are, but it’s time that we think about moving it out of the critical path and
|
||||||
|
provide it as an optional component for legacy applications.
|
||||||
|
|
||||||
|
Overall, the philosophy of Wayland is to provide clients with a way to manage
|
||||||
|
windows and how their contents are displayed. Rendering is left to clients, and
|
||||||
|
system wide memory management interfaces are used to pass buffer handles between
|
||||||
|
clients and the compositing manager.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
The figure above illustrates how Wayland clients interact with a Wayland server.
|
||||||
|
Note that window management and composition are handled entirely in the server,
|
||||||
|
significantly reducing complexity while marginally improving performance through
|
||||||
|
reduced context switching. The resulting system is easier to build and extend
|
||||||
|
than a similar X system, because often changes need only be made in one place.
|
||||||
|
Or in the case of protocol extensions, two (rather than 3 or 4 in the X case
|
||||||
|
where window management and/or composition handling may also need to be
|
||||||
|
updated).
|
||||||
493
doc/book/src/Message_XML.md
Normal file
493
doc/book/src/Message_XML.md
Normal file
|
|
@ -0,0 +1,493 @@
|
||||||
|
# Message Definition Language
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The fundamentals of the Wayland protocol are explained in [Wayland Protocol and
|
||||||
|
Model of Operation](Protocol.md). This chapter formally defines the language
|
||||||
|
used to define Wayland protocols.
|
||||||
|
|
||||||
|
Wayland is an object-oriented protocol. Each object follows exactly one
|
||||||
|
interface. An interface is a collection of message and enumeration definitions.
|
||||||
|
A message can be either a request (sent by a client) or an event (sent by a
|
||||||
|
server). A message can have arguments. All arguments are typed.
|
||||||
|
|
||||||
|
## XML Elements
|
||||||
|
|
||||||
|
### protocol
|
||||||
|
|
||||||
|
```
|
||||||
|
protocol ::= (copyright?, description? interface+)
|
||||||
|
```
|
||||||
|
|
||||||
|
`protocol` is the root element in a Wayland protocol XML file. Code generation
|
||||||
|
tools may optionally use the protocol `name` in API symbol names. The XML file
|
||||||
|
name should be similar to the protocol name.
|
||||||
|
|
||||||
|
The description element should be used to document the intended purpose of the
|
||||||
|
protocol, give an overview, and give any development stage notices if
|
||||||
|
applicable.
|
||||||
|
|
||||||
|
The copyright element should be used to indicate the copyrights and the license
|
||||||
|
of the XML file.
|
||||||
|
|
||||||
|
**Required attributes**
|
||||||
|
|
||||||
|
`name`="`cname`"
|
||||||
|
: The name of the protocol (a.k.a protocol extension). cname-requirements
|
||||||
|
|
||||||
|
The name should be globally unique. Protocols to be included in
|
||||||
|
[wayland-protocols](https://gitlab.freedesktop.org/wayland/wayland-protocols)
|
||||||
|
must follow the naming rules set there. Other protocols should use a unique
|
||||||
|
prefix for the name, e.g. referring to the owning project's name.
|
||||||
|
|
||||||
|
### copyright
|
||||||
|
|
||||||
|
Parent elements: protocol
|
||||||
|
|
||||||
|
```
|
||||||
|
copyright ::= #PCDATA
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains free-form, pre-formatted text for copyright and license notices.
|
||||||
|
|
||||||
|
### description
|
||||||
|
|
||||||
|
Parent elements: protocol, interface, request, event, arg, enum, entry
|
||||||
|
|
||||||
|
```
|
||||||
|
description ::= #PCDATA
|
||||||
|
```
|
||||||
|
|
||||||
|
Contains human-readable documentation for its parent element. May contain
|
||||||
|
formatted text, including paragraphs and bulleted lists.
|
||||||
|
|
||||||
|
**Optional attributes**
|
||||||
|
|
||||||
|
`summary`="`summary`"
|
||||||
|
: A short (half a line at most) description of the documented element.
|
||||||
|
|
||||||
|
When a description element is used, it is recommended to not use the
|
||||||
|
`summary` attribute of the parent element.
|
||||||
|
|
||||||
|
### interface
|
||||||
|
|
||||||
|
Parent elements: protocol
|
||||||
|
|
||||||
|
```
|
||||||
|
interface ::= (description?, (request|event|enum)+)
|
||||||
|
```
|
||||||
|
|
||||||
|
An interface element contains the requests and events that form the interface.
|
||||||
|
Enumerations can also be defined with enum elements. These all belong into the
|
||||||
|
namespace of the interface. Code generation tools may use the interface `name`
|
||||||
|
in API symbol names.
|
||||||
|
|
||||||
|
Interfaces form an ancestry tree. Aside from
|
||||||
|
[wl_display](https://wayland.app/protocols/wayland#wl_display), new protocol
|
||||||
|
objects are always created through an existing protocol object that may be
|
||||||
|
referred to as _the factory object_. This can happen in one of two ways: the
|
||||||
|
factory object's interface either defines or does not define the new object's
|
||||||
|
interface.
|
||||||
|
|
||||||
|
When the factory interface defines the new object's interface, the new object
|
||||||
|
also inherits the factory object's interface version number. This number defines
|
||||||
|
the interface version of the new object. The factory object is referred to as
|
||||||
|
_the parent object_ and the factory interface is referred to as _the parent
|
||||||
|
interface_. This forms the ancestry tree of interfaces.
|
||||||
|
|
||||||
|
When the factory interface does not define the new object's interface, both the
|
||||||
|
interface name and the version must be communicated explicitly. The foremost
|
||||||
|
example of this is
|
||||||
|
[wl_registry.bind](https://wayland.app/protocols/wayland#wl_registry:request:bind).
|
||||||
|
In this case the terms "parent" or "ancestor" are not used. Interfaces that are
|
||||||
|
advertised through
|
||||||
|
[wl_registry](https://wayland.app/protocols/wayland#wl_registry) are called
|
||||||
|
_global interfaces_, or globals for short.
|
||||||
|
|
||||||
|
If objects having the interface can cause protocol errors, the protocol error
|
||||||
|
codes must be defined within the interface with an enum element with its `name`
|
||||||
|
set to `"error"`. Protocol error codes are always specific to the interface of
|
||||||
|
the object referred to in
|
||||||
|
[wl_display.error](https://wayland.app/protocols/wayland#wl_display:event:error).
|
||||||
|
|
||||||
|
The description element should be used to describe the purpose and the general
|
||||||
|
usage of the interface.
|
||||||
|
|
||||||
|
**Required attributes**
|
||||||
|
|
||||||
|
`name`="`cname`"
|
||||||
|
: The name of the interface. cname-requirements The name must be unique in the
|
||||||
|
protocol, and preferably it should also be globally unique to avoid API
|
||||||
|
conflicts in language bindings of multiple protocols.
|
||||||
|
|
||||||
|
Protocols to be included in
|
||||||
|
[wayland-protocols](https://gitlab.freedesktop.org/wayland/wayland-protocols)
|
||||||
|
must follow the interface naming rules set there. Other protocols should use
|
||||||
|
a unique prefix for the name, e.g. referring to the owning project's name.
|
||||||
|
|
||||||
|
`version`="`V`"
|
||||||
|
: The interface's latest version number `V` must be an integer greater than
|
||||||
|
zero. An interface element defines all versions of the interface from 1 to
|
||||||
|
`V` inclusive. The contents of each interface version are defined in each of
|
||||||
|
the request, event, enum and entry elements using the attributes `since` and
|
||||||
|
`deprecated-since`, and in the specification text.
|
||||||
|
|
||||||
|
When an interface is extended, the version number must be incremented on all
|
||||||
|
the interfaces part of the same interface ancestry tree. The exception to
|
||||||
|
this rule are interfaces which are forever stuck to version 1, which is
|
||||||
|
usually caused by having multiple parent interfaces with independent
|
||||||
|
ancestor global interfaces.
|
||||||
|
|
||||||
|
A protocol object may have any defined version of the interface. The version
|
||||||
|
of the object is determined at runtime either by inheritance from another
|
||||||
|
protocol object or explicitly.
|
||||||
|
|
||||||
|
It is possible for a protocol object to have a version higher than defined
|
||||||
|
by its interface. This may happen when the interface is stuck at version 1
|
||||||
|
as per above. It may also happen when a protocol XML file has not been
|
||||||
|
thoroughly updated as required. In such cases the object shall function as
|
||||||
|
with the highest defined interface version.
|
||||||
|
|
||||||
|
### request
|
||||||
|
|
||||||
|
Parent elements: interface
|
||||||
|
|
||||||
|
```
|
||||||
|
request ::= (description?, arg*)
|
||||||
|
```
|
||||||
|
|
||||||
|
Defines a request, a message from a client to a server. Requests are always
|
||||||
|
associated with a specific protocol object.
|
||||||
|
|
||||||
|
Requests are automatically assigned opcodes in the order they appear inside the
|
||||||
|
interface element. Therefore the only backwards-compatible way to add requests
|
||||||
|
to an interface is to add them to the end. Any event elements do not interfere
|
||||||
|
with request opcode assignments.
|
||||||
|
|
||||||
|
The arg elements declare the request's arguments. There can be 0 to 20 arguments
|
||||||
|
for a request. The order of arg inside the request element defines the order of
|
||||||
|
the arguments on the wire. All declared arguments are mandatory, and extra
|
||||||
|
arguments are not allowed on the wire.
|
||||||
|
|
||||||
|
The description element should be used to document the request.
|
||||||
|
|
||||||
|
**Required attributes**
|
||||||
|
|
||||||
|
`name`="`cname`"
|
||||||
|
: The name of the request. cname-requirements The name must be unique within
|
||||||
|
all requests and events in the containing interface.
|
||||||
|
|
||||||
|
Code and language binding generators may use the name in the API they
|
||||||
|
create. The `name` of the containing interface provides the namespace for
|
||||||
|
requests.
|
||||||
|
|
||||||
|
**Optional attributes**
|
||||||
|
|
||||||
|
`type`="`destructor`"
|
||||||
|
: When this attribute is present, the request is a destructor: it shall
|
||||||
|
destroy the protocol object it is sent on. Protocol IPC libraries may use
|
||||||
|
this for bookkeeping protocol object lifetimes.
|
||||||
|
|
||||||
|
Libwayland-client uses this information to ignore incoming events for
|
||||||
|
destroyed protocol objects. Such events may occur due to a natural race
|
||||||
|
condition between the client destroying a protocol object and the server
|
||||||
|
sending events before processing the destroy request.
|
||||||
|
|
||||||
|
`since`="`S`"
|
||||||
|
: `S` must be an integer greater than zero. If `since` is not specified,
|
||||||
|
`since="1"` is assumed.
|
||||||
|
|
||||||
|
This request was added in interface `version` `S`. The request does not
|
||||||
|
exist if the protocol object has a bound version smaller than `S`. Attempts
|
||||||
|
to use it in such a case shall raise the protocol error
|
||||||
|
`wl_display.error.invalid_method`.
|
||||||
|
|
||||||
|
`deprecated-since`="`D`"
|
||||||
|
: `D` must be an integer greater than the value of `since`. If
|
||||||
|
`deprecated-since` is not specified, then the request is not deprecated in
|
||||||
|
any version of the containing interface.
|
||||||
|
|
||||||
|
This request was deprecated in interface `version` `D` and above, and should
|
||||||
|
not be sent on protocol objects of such version. This is informational.
|
||||||
|
Compositors must still be prepared to handle the request unless specified
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
### event
|
||||||
|
|
||||||
|
Parent elements: interface
|
||||||
|
|
||||||
|
```
|
||||||
|
event ::= (description?, arg*)
|
||||||
|
```
|
||||||
|
|
||||||
|
Defines an event, a message from a server to a client. Events are always
|
||||||
|
associated with a specific protocol object.
|
||||||
|
|
||||||
|
Events are automatically assigned opcodes in the order they appear inside the
|
||||||
|
interface element. Therefore the only backwards-compatible way to add events to
|
||||||
|
an interface is to add them to the end. Any request elements do not interfere
|
||||||
|
with event opcode assignments.
|
||||||
|
|
||||||
|
The arg elements declare the event's arguments. There can be 0 to 20 arguments
|
||||||
|
for an event. The order of arg inside the event element defines the order of the
|
||||||
|
arguments on the wire. All declared arguments are mandatory, and extra arguments
|
||||||
|
are not allowed on the wire.
|
||||||
|
|
||||||
|
The description element should be used to document the event.
|
||||||
|
|
||||||
|
**Required attributes**
|
||||||
|
|
||||||
|
`name`="`cname`"
|
||||||
|
: The name of the event. cname-requirements The name must be unique within all
|
||||||
|
requests and events in the containing interface.
|
||||||
|
|
||||||
|
Code and language binding generators may use the name in the API they
|
||||||
|
create. The `name` of the containing interface provides the namespace for
|
||||||
|
events.
|
||||||
|
|
||||||
|
**Optional attributes**
|
||||||
|
|
||||||
|
`type`="`destructor`"
|
||||||
|
: When this attribute is present, the event is a destructor: it shall destroy
|
||||||
|
the protocol object it is sent on. Protocol IPC libraries may use this for
|
||||||
|
bookkeeping protocol object lifetimes.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> Destructor events are an underdeveloped feature in Wayland. They can be
|
||||||
|
> used only on client-created protocol objects, and it is the protocol
|
||||||
|
> designer's responsibility to design such a message exchange that race
|
||||||
|
> conditions cannot occur. The main problem would be a client sending a
|
||||||
|
> request at the same time as the server is sending a destructor event. The
|
||||||
|
> server will consider the protocol object to be already invalid or even
|
||||||
|
> recycled when it proceeds to process the request. This often results in
|
||||||
|
> protocol errors, but under specific conditions it might also result in
|
||||||
|
> silently incorrect behavior.
|
||||||
|
>
|
||||||
|
> Destructor events should not be used in new protocols. If a destructor
|
||||||
|
> event is necessary, the simplest way to avoid these problems is to have
|
||||||
|
> the interface not contain any requests.
|
||||||
|
|
||||||
|
`since`="`S`"
|
||||||
|
: `S` must be an integer greater than zero. If `since` is not specified,
|
||||||
|
`since="1"` is assumed.
|
||||||
|
|
||||||
|
This event was added in interface `version` `S`. The event does not exist if
|
||||||
|
the protocol object has a bound version smaller than `S`.
|
||||||
|
|
||||||
|
`deprecated-since`="`D`"
|
||||||
|
: `D` must be an integer greater than the value of `since`. If
|
||||||
|
`deprecated-since` is not specified, then the event is not deprecated in any
|
||||||
|
version of the containing interface.
|
||||||
|
|
||||||
|
This event was deprecated in interface `version` `D` and above, and should
|
||||||
|
not be sent on protocol objects of such version. This is informational.
|
||||||
|
Clients must still be prepared to receive this event unless otherwise
|
||||||
|
specified.
|
||||||
|
|
||||||
|
### arg
|
||||||
|
|
||||||
|
Parent elements: request, event
|
||||||
|
|
||||||
|
```
|
||||||
|
arg ::= description?
|
||||||
|
```
|
||||||
|
|
||||||
|
This element declares one argument for the request or the event.
|
||||||
|
|
||||||
|
**Required attributes**
|
||||||
|
|
||||||
|
`name`="`cname`"
|
||||||
|
: The name of the argument. cname-requirements The name must be unique within
|
||||||
|
all the arguments of the parent element.
|
||||||
|
|
||||||
|
`type`="`T`"
|
||||||
|
: The type `T` of the argument datum must be one of:
|
||||||
|
|
||||||
|
`int`
|
||||||
|
: 32-bit signed integer.
|
||||||
|
|
||||||
|
`uint`
|
||||||
|
: 32-bit unsigned integer.
|
||||||
|
|
||||||
|
`fixed`
|
||||||
|
: Signed 24.8-bit fixed-point value.
|
||||||
|
|
||||||
|
`string`
|
||||||
|
: UTF-8 encoded string value, NUL byte terminated. Interior NUL bytes are
|
||||||
|
not allowed.
|
||||||
|
|
||||||
|
`array`
|
||||||
|
: A byte array of arbitrary data.
|
||||||
|
|
||||||
|
`fd`
|
||||||
|
: A file descriptor.
|
||||||
|
|
||||||
|
The file descriptor must be open and valid on send. It is not possible
|
||||||
|
to pass a null value.
|
||||||
|
|
||||||
|
`new_id`
|
||||||
|
: Creates a new protocol object. A request or an event may have at most
|
||||||
|
one `new_id` argument.
|
||||||
|
|
||||||
|
If `interface` is specified, the new protocol object shall have the
|
||||||
|
specified interface, and the new object's (interface) version shall be
|
||||||
|
the version of the object on which the request or event is being sent.
|
||||||
|
|
||||||
|
If `interface` is not specified, the request shall implicitly have two
|
||||||
|
additional arguments: A `string` for an interface name, and a `uint` for
|
||||||
|
the new object's version. Leaving the interface unspecified is reserved
|
||||||
|
for special use,
|
||||||
|
[wl_registry.bind](https://wayland.app/protocols/wayland#wl_registry:request:bind)
|
||||||
|
for example.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> An event argument must always specify the `new_id` `interface`.
|
||||||
|
|
||||||
|
`object`
|
||||||
|
: Reference to an existing protocol object.
|
||||||
|
|
||||||
|
The attribute `interface` should be specified. Otherwise IPC libraries
|
||||||
|
cannot enforce the interface, and checking the interface falls on user
|
||||||
|
code and specification text.
|
||||||
|
|
||||||
|
**Optional attributes**
|
||||||
|
|
||||||
|
`summary`="`summary`"
|
||||||
|
: A short (half a line at most) description. This attribute should not be used
|
||||||
|
if a description is used.
|
||||||
|
|
||||||
|
`interface`="`iface`"
|
||||||
|
: If given, `iface` must be the `name` of some interface, and `type` of this
|
||||||
|
argument must be either `"object"` or `"new_id"`. This indicates that the
|
||||||
|
existing or new object must have the interface `iface`. Use for other
|
||||||
|
argument types is forbidden.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> If an interface from another protocol is used, then this creates a
|
||||||
|
> dependency between the protocols. If an application generates code for one
|
||||||
|
> protocol, then it must also generate code for all dependencies. Therefore
|
||||||
|
> this would not be a backwards compatible change.
|
||||||
|
|
||||||
|
`allow-null`="`true`" | "`false`"
|
||||||
|
: Whether the argument value can be null on send. Defaults to `"false"`,
|
||||||
|
meaning it is illegal to send a null value. Can be used only when `type` is
|
||||||
|
`"string"` or `"object"`.
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Even though this attribute can be used to forbid a compositor from sending
|
||||||
|
> a null object as an event argument, an IPC library implementation may not
|
||||||
|
> protect the client from receiving a null object. This can happen with
|
||||||
|
> libwayland-client when the client has destroyed the protocol object before
|
||||||
|
> dispatching an event that referred to it in an argument.
|
||||||
|
|
||||||
|
`enum`="`enum-cname-suffix`"
|
||||||
|
: If specified, indicates that the argument value should come from the enum
|
||||||
|
named `enum-cname-suffix`. If the enumeration is a bitfield, then `type`
|
||||||
|
must be `"uint"`. Otherwise `type` must be either `"uint"` or `"int"`.
|
||||||
|
|
||||||
|
The name `enum-cname-suffix` refers to an enum in the same interface by
|
||||||
|
default. If it is necessary to refer to an enumeration from another
|
||||||
|
interface, the interface name can be given with a period:
|
||||||
|
|
||||||
|
```
|
||||||
|
`enum`="`iface`.`enum-cname-suffix`"
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> This attribute alone does not automatically restrict the legal values for
|
||||||
|
> this argument. If values from outside of the enumeration need to be
|
||||||
|
> forbidden, that must be specified explicitly in the documentation.
|
||||||
|
>
|
||||||
|
> A common design pattern is to have the server advertise the supported
|
||||||
|
> enumeration or bit values with events and explicitly forbid clients from
|
||||||
|
> using any other values in requests. This also requires a protocol error
|
||||||
|
> code to be specified with the error enum to be raised if a client uses an
|
||||||
|
> illegal value, see [interface](#interface).
|
||||||
|
|
||||||
|
### enum
|
||||||
|
|
||||||
|
Parent elements: protocol
|
||||||
|
|
||||||
|
```
|
||||||
|
enum ::= (description?, entry*)
|
||||||
|
```
|
||||||
|
|
||||||
|
This tag defines an enumeration of integer values. Enumerations are merely a
|
||||||
|
syntactic construct to give names to arbitrary integer constants. Each constant
|
||||||
|
is listed as an entry with its name. There are two types of enumerations:
|
||||||
|
regular enumerations and bitfields.
|
||||||
|
|
||||||
|
Regular enumerations do not use `bitfield` attribute, or they set it to
|
||||||
|
`"false"`. The set of pre-defined values that belong to a regular enumeration is
|
||||||
|
exactly the set of values listed as entry elements after the protocol object
|
||||||
|
version is taken into account. See the entry attributes `since` and
|
||||||
|
`deprecated-since`.
|
||||||
|
|
||||||
|
Bitfields set `bitfield` to `"true"`. The set of values that belong to a
|
||||||
|
bitfield enumeration are all the values that can be formed by the bitwise-or
|
||||||
|
operator from the set of values listed as entry elements like in the regular
|
||||||
|
enumeration. Usually also zero is implicitly included.
|
||||||
|
|
||||||
|
All the values in a regular enumeration must be either signed or unsigned 32-bit
|
||||||
|
integers. All the values in a bitfield enumeration must be unsigned 32-bit
|
||||||
|
integers.
|
||||||
|
|
||||||
|
**Required attributes**
|
||||||
|
|
||||||
|
`name`="`cname-suffix`"
|
||||||
|
: The name of the enumeration. cname-suffix-requirements The name must be
|
||||||
|
unique within all enumerations in the containing interface. The name is used
|
||||||
|
as the namespace for all the contained entry elements.
|
||||||
|
|
||||||
|
**Optional attributes**
|
||||||
|
|
||||||
|
`since`="`S`"
|
||||||
|
: `S` must be an integer greater than zero. If `since` is not specified,
|
||||||
|
`since="1"` is assumed.
|
||||||
|
|
||||||
|
This enumeration was added in interface `version` `S`. The enumeration does
|
||||||
|
not exist if the protocol object has a bound version smaller than `S`.
|
||||||
|
|
||||||
|
`bitfield`="`true`" | "`false`"
|
||||||
|
: Specifies if this enumeration is a bitfield. Defaults to `"false"`.
|
||||||
|
|
||||||
|
### entry
|
||||||
|
|
||||||
|
Parent elements: enum
|
||||||
|
|
||||||
|
```
|
||||||
|
entry ::= description?
|
||||||
|
```
|
||||||
|
|
||||||
|
Defines a name for an integer constant and makes it part of the set of values of
|
||||||
|
the containing enumeration.
|
||||||
|
|
||||||
|
**Required attributes**
|
||||||
|
|
||||||
|
`name`="`cname-suffix`"
|
||||||
|
: The name of a value in an enumeration. cname-suffix-requirements The name
|
||||||
|
must be unique within all entry elements in the containing enum.
|
||||||
|
|
||||||
|
`value`="`V`"
|
||||||
|
: An integer value. The value can be given in decimal, hexadecimal, or octal
|
||||||
|
representation.
|
||||||
|
|
||||||
|
**Optional attributes**
|
||||||
|
|
||||||
|
`summary`="`summary`"
|
||||||
|
: A short (half a line at most) description. This attribute should not be used
|
||||||
|
if a description is used.
|
||||||
|
|
||||||
|
`since`="`S`"
|
||||||
|
: `S` must be an integer greater than zero. If `since` is not specified,
|
||||||
|
`since="1"` is assumed.
|
||||||
|
|
||||||
|
This value was added in interface `version` `S`.
|
||||||
|
|
||||||
|
`deprecated-since`="`D`"
|
||||||
|
: `D` must be an integer greater than the value of `since`. If
|
||||||
|
`deprecated-since` is not specified, then the value is not deprecated in any
|
||||||
|
version of the containing interface.
|
||||||
|
|
||||||
|
This value was removed in interface `version` `D`. This does not make the
|
||||||
|
value automatically illegal to use, see [arg](#arg) attribute `enum`.
|
||||||
371
doc/book/src/Protocol.md
Normal file
371
doc/book/src/Protocol.md
Normal file
|
|
@ -0,0 +1,371 @@
|
||||||
|
# Wayland Protocol and Model of Operation
|
||||||
|
|
||||||
|
## Basic Principles
|
||||||
|
|
||||||
|
The Wayland protocol is an asynchronous object oriented protocol. All requests
|
||||||
|
are method invocations on some object. The requests include an object ID that
|
||||||
|
uniquely identifies an object on the server. Each object implements an interface
|
||||||
|
and the requests include an opcode that identifies which method in the interface
|
||||||
|
to invoke.
|
||||||
|
|
||||||
|
The protocol is message-based. A message sent by a client to the server is
|
||||||
|
called request. A message from the server to a client is called event. A message
|
||||||
|
has a number of arguments, each of which has a certain type (see [Wire
|
||||||
|
Format](#wire-format) for a list of argument types).
|
||||||
|
|
||||||
|
Additionally, the protocol can specify `enum`s which associate names to specific
|
||||||
|
numeric enumeration values. These are primarily just descriptive in nature: at
|
||||||
|
the wire format level enums are just integers. But they also serve a secondary
|
||||||
|
purpose to enhance type safety or otherwise add context for use in language
|
||||||
|
bindings or other such code. This latter usage is only supported so long as code
|
||||||
|
written before these attributes were introduced still works after; in other
|
||||||
|
words, adding an enum should not break API, otherwise it puts backwards
|
||||||
|
compatibility at risk.
|
||||||
|
|
||||||
|
`enum`s can be defined as just a set of integers, or as bitfields. This is
|
||||||
|
specified via the `bitfield` boolean attribute in the `enum` definition. If this
|
||||||
|
attribute is true, the enum is intended to be accessed primarily using bitwise
|
||||||
|
operations, for example when arbitrarily many choices of the enum can be ORed
|
||||||
|
together; if it is false, or the attribute is omitted, then the enum arguments
|
||||||
|
are a just a sequence of numerical values.
|
||||||
|
|
||||||
|
The `enum` attribute can be used on either `uint` or `int` arguments, however if
|
||||||
|
the `enum` is defined as a `bitfield`, it can only be used on `uint` args.
|
||||||
|
|
||||||
|
The server sends back events to the client, each event is emitted from an
|
||||||
|
object. Events can be error conditions. The event includes the object ID and the
|
||||||
|
event opcode, from which the client can determine the type of event. Events are
|
||||||
|
generated both in response to requests (in which case the request and the event
|
||||||
|
constitutes a round trip) or spontaneously when the server state changes.
|
||||||
|
|
||||||
|
- State is broadcast on connect, events are sent out when state changes. Clients
|
||||||
|
must listen for these changes and cache the state. There is no need (or
|
||||||
|
mechanism) to query server state.
|
||||||
|
|
||||||
|
- The server will broadcast the presence of a number of global objects, which in
|
||||||
|
turn will broadcast their current state.
|
||||||
|
|
||||||
|
## Code Generation
|
||||||
|
|
||||||
|
The interfaces, requests and events are defined in
|
||||||
|
[protocol/wayland.xml](https://gitlab.freedesktop.org/wayland/wayland/-/blob/main/protocol/wayland.xml).
|
||||||
|
This xml is used to generate the function prototypes that can be used by clients
|
||||||
|
and compositors.
|
||||||
|
|
||||||
|
The protocol entry points are generated as inline functions which just wrap the
|
||||||
|
`wl_proxy_*` functions. The inline functions aren't part of the library ABI and
|
||||||
|
language bindings should generate their own stubs for the protocol entry points
|
||||||
|
from the xml.
|
||||||
|
|
||||||
|
## Wire Format
|
||||||
|
|
||||||
|
The protocol is sent over a UNIX domain stream socket, where the endpoint
|
||||||
|
usually is named `wayland-0` (although it can be changed via _WAYLAND_DISPLAY_
|
||||||
|
in the environment). Beginning in Wayland 1.15, implementations can optionally
|
||||||
|
support server socket endpoints located at arbitrary locations in the filesystem
|
||||||
|
by setting _WAYLAND_DISPLAY_ to the absolute path at which the server endpoint
|
||||||
|
listens. The socket may also be provided through file descriptor inheritance, in
|
||||||
|
which case _WAYLAND_SOCKET_ is set.
|
||||||
|
|
||||||
|
Every message is structured as 32-bit words; values are represented in the
|
||||||
|
host's byte-order. The message header has 2 words in it:
|
||||||
|
|
||||||
|
- The first word is the sender's object ID (32-bit).
|
||||||
|
|
||||||
|
- The second has 2 parts of 16-bit. The upper 16-bits are the message size in
|
||||||
|
bytes, starting at the header (i.e. it has a minimum value of 8).The lower is
|
||||||
|
the request/event opcode.
|
||||||
|
|
||||||
|
The payload describes the request/event arguments. Every argument is always
|
||||||
|
aligned to 32-bits. Where padding is required, the value of padding bytes is
|
||||||
|
undefined. There is no prefix that describes the type, but it is inferred
|
||||||
|
implicitly from the xml specification.
|
||||||
|
|
||||||
|
The representation of argument types are as follows:
|
||||||
|
|
||||||
|
int
|
||||||
|
uint
|
||||||
|
: The value is the 32-bit value of the signed/unsigned int.
|
||||||
|
|
||||||
|
fixed
|
||||||
|
: Signed 24.8 decimal numbers. It is a signed decimal type which offers a sign
|
||||||
|
bit, 23 bits of integer precision and 8 bits of decimal precision. This is
|
||||||
|
exposed as an opaque struct with conversion helpers to and from double and
|
||||||
|
int on the C API side.
|
||||||
|
|
||||||
|
string
|
||||||
|
: Starts with an unsigned 32-bit length (including null terminator), followed
|
||||||
|
by the UTF-8 encoded string contents, including terminating null byte, then
|
||||||
|
padding to a 32-bit boundary. A null value is represented with a length of
|
||||||
|
0. Interior null bytes are not permitted.
|
||||||
|
|
||||||
|
object
|
||||||
|
: 32-bit object ID. A null value is represented with an ID of 0.
|
||||||
|
|
||||||
|
new_id
|
||||||
|
: The 32-bit object ID. Generally, the interface used for the new object is
|
||||||
|
inferred from the xml, but in the case where it's not specified, a new_id is
|
||||||
|
preceded by a `string` specifying the interface name, and a `uint`
|
||||||
|
specifying the version.
|
||||||
|
|
||||||
|
array
|
||||||
|
: Starts with 32-bit array size in bytes, followed by the array contents
|
||||||
|
verbatim, and finally padding to a 32-bit boundary.
|
||||||
|
|
||||||
|
fd
|
||||||
|
: The file descriptor is not stored in the message buffer, but in the
|
||||||
|
ancillary data of the UNIX domain socket message (msg_control).
|
||||||
|
|
||||||
|
The protocol does not specify the exact position of the ancillary data in the
|
||||||
|
stream, except that the order of file descriptors is the same as the order of
|
||||||
|
messages and `fd` arguments within messages on the wire.
|
||||||
|
|
||||||
|
In particular, it means that any byte of the stream, even the message header,
|
||||||
|
may carry the ancillary data with file descriptors.
|
||||||
|
|
||||||
|
Clients and compositors should queue incoming data until they have whole
|
||||||
|
messages to process, as file descriptors may arrive earlier or later than the
|
||||||
|
corresponding data bytes.
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
Every interface is versioned and every protocol object implements a particular
|
||||||
|
version of its interface. For global objects, the maximum version supported by
|
||||||
|
the server is advertised with the global and the actual version of the created
|
||||||
|
protocol object is determined by the version argument passed to
|
||||||
|
wl_registry.bind(). For objects that are not globals, their version is inferred
|
||||||
|
from the object that created them.
|
||||||
|
|
||||||
|
In order to keep things sane, this has a few implications for interface
|
||||||
|
versions:
|
||||||
|
|
||||||
|
- The object creation hierarchy must be a tree. Otherwise, inferring object
|
||||||
|
versions from the parent object becomes a much more difficult to properly
|
||||||
|
track.
|
||||||
|
|
||||||
|
- When the version of an interface increases, so does the version of its parent
|
||||||
|
(recursively until you get to a global interface)
|
||||||
|
|
||||||
|
- A global interface's version number acts like a counter for all of its child
|
||||||
|
interfaces. Whenever a child interface gets modified, the global parent's
|
||||||
|
interface version number also increases (see above). The child interface then
|
||||||
|
takes on the same version number as the new version of its parent global
|
||||||
|
interface.
|
||||||
|
|
||||||
|
To illustrate the above, consider the wl_compositor interface. It has two
|
||||||
|
children, wl_surface and wl_region. As of wayland version 1.2, wl_surface and
|
||||||
|
wl_compositor are both at version 3. If something is added to the wl_region
|
||||||
|
interface, both wl_region and wl_compositor will get bumpped to version 4. If,
|
||||||
|
afterwards, wl_surface is changed, both wl_compositor and wl_surface will be at
|
||||||
|
version 5. In this way the global interface version is used as a sort of
|
||||||
|
"counter" for all of its child interfaces. This makes it very simple to know the
|
||||||
|
version of the child given the version of its parent. The child is at the
|
||||||
|
highest possible interface version that is less than or equal to its parent's
|
||||||
|
version.
|
||||||
|
|
||||||
|
It is worth noting a particular exception to the above versioning scheme. The
|
||||||
|
wl_display (and, by extension, wl_registry) interface cannot change because it
|
||||||
|
is the core protocol object and its version is never advertised nor is there a
|
||||||
|
mechanism to request a different version.
|
||||||
|
|
||||||
|
## Connect Time
|
||||||
|
|
||||||
|
There is no fixed connection setup information, the server emits multiple events
|
||||||
|
at connect time, to indicate the presence and properties of global objects:
|
||||||
|
outputs, compositor, input devices.
|
||||||
|
|
||||||
|
## Security and Authentication
|
||||||
|
|
||||||
|
- mostly about access to underlying buffers, need new drm auth mechanism (the
|
||||||
|
grant-to ioctl idea), need to check the cmd stream?
|
||||||
|
|
||||||
|
- getting the server socket depends on the compositor type, could be a system
|
||||||
|
wide name, through fd passing on the session dbus. or the client is forked by
|
||||||
|
the compositor and the fd is already opened.
|
||||||
|
|
||||||
|
## Creating Objects
|
||||||
|
|
||||||
|
Each object has a unique ID. The IDs are allocated by the entity creating the
|
||||||
|
object (either client or server). IDs allocated by the client are in the range
|
||||||
|
[1, 0xfeffffff] while IDs allocated by the server are in the range [0xff000000,
|
||||||
|
0xffffffff]. The 0 ID is reserved to represent a null or non-existent object.
|
||||||
|
For efficiency purposes, the IDs are densely packed in the sense that the ID N
|
||||||
|
will not be used until N-1 has been used. This ordering is not merely a
|
||||||
|
guideline, but a strict requirement, and there are implementations of the
|
||||||
|
protocol that rigorously enforce this rule, including the ubiquitous libwayland.
|
||||||
|
|
||||||
|
## Compositor
|
||||||
|
|
||||||
|
The compositor is a global object, advertised at connect time.
|
||||||
|
|
||||||
|
See [wl_compositor](https://wayland.app/protocols/wayland#wl_compositor) for the
|
||||||
|
protocol description.
|
||||||
|
|
||||||
|
## Surfaces
|
||||||
|
|
||||||
|
A surface manages a rectangular grid of pixels that clients create for
|
||||||
|
displaying their content to the screen. Clients don't know the global position
|
||||||
|
of their surfaces, and cannot access other clients' surfaces.
|
||||||
|
|
||||||
|
Once the client has finished writing pixels, it 'commits' the buffer; this
|
||||||
|
permits the compositor to access the buffer and read the pixels. When the
|
||||||
|
compositor is finished, it releases the buffer back to the client.
|
||||||
|
|
||||||
|
See [wl_surface](https://wayland.app/protocols/wayland#wl_surface) for the
|
||||||
|
protocol description.
|
||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
A seat represents a group of input devices including mice, keyboards and
|
||||||
|
touchscreens. It has a keyboard and pointer focus. Seats are global objects.
|
||||||
|
Pointer events are delivered in surface-local coordinates.
|
||||||
|
|
||||||
|
The compositor maintains an implicit grab when a button is pressed, to ensure
|
||||||
|
that the corresponding button release event gets delivered to the same surface.
|
||||||
|
But there is no way for clients to take an explicit grab. Instead, surfaces can
|
||||||
|
be mapped as 'popup', which combines transient window semantics with a pointer
|
||||||
|
grab.
|
||||||
|
|
||||||
|
To avoid race conditions, input events that are likely to trigger further
|
||||||
|
requests (such as button presses, key events, pointer motions) carry serial
|
||||||
|
numbers, and requests such as wl_surface.set_popup require that the serial
|
||||||
|
number of the triggering event is specified. The server maintains a
|
||||||
|
monotonically increasing counter for these serial numbers.
|
||||||
|
|
||||||
|
Input events also carry timestamps with millisecond granularity. Their base is
|
||||||
|
undefined, so they can't be compared against system time (as obtained with
|
||||||
|
clock_gettime or gettimeofday). They can be compared with each other though, and
|
||||||
|
for instance be used to identify sequences of button presses as double or triple
|
||||||
|
clicks.
|
||||||
|
|
||||||
|
See [wl_seat](https://wayland.app/protocols/wayland#wl_seat) for the protocol
|
||||||
|
description.
|
||||||
|
|
||||||
|
Talk about:
|
||||||
|
|
||||||
|
- keyboard map, change events
|
||||||
|
|
||||||
|
- xkb on Wayland
|
||||||
|
|
||||||
|
- multi pointer Wayland
|
||||||
|
|
||||||
|
A surface can change the pointer image when the surface is the pointer focus of
|
||||||
|
the input device. Wayland doesn't automatically change the pointer image when a
|
||||||
|
pointer enters a surface, but expects the application to set the cursor it wants
|
||||||
|
in response to the pointer focus and motion events. The rationale is that a
|
||||||
|
client has to manage changing pointer images for UI elements within the surface
|
||||||
|
in response to motion events anyway, so we'll make that the only mechanism for
|
||||||
|
setting or changing the pointer image. If the server receives a request to set
|
||||||
|
the pointer image after the surface loses pointer focus, the request is ignored.
|
||||||
|
To the client this will look like it successfully set the pointer image.
|
||||||
|
|
||||||
|
Setting the pointer image to NULL causes the cursor to be hidden.
|
||||||
|
|
||||||
|
The compositor will revert the pointer image back to a default image when no
|
||||||
|
surface has the pointer focus for that device.
|
||||||
|
|
||||||
|
What if the pointer moves from one window which has set a special pointer image
|
||||||
|
to a surface that doesn't set an image in response to the motion event? The new
|
||||||
|
surface will be stuck with the special pointer image. We can't just revert the
|
||||||
|
pointer image on leaving a surface, since if we immediately enter a surface that
|
||||||
|
sets a different image, the image will flicker. If a client does not set a
|
||||||
|
pointer image when the pointer enters a surface, the pointer stays with the
|
||||||
|
image set by the last surface that changed it, possibly even hidden. Such a
|
||||||
|
client is likely just broken.
|
||||||
|
|
||||||
|
## Output
|
||||||
|
|
||||||
|
An output is a global object, advertised at connect time or as it comes and
|
||||||
|
goes.
|
||||||
|
|
||||||
|
See [wl_output](https://wayland.app/protocols/wayland#wl_output) for the
|
||||||
|
protocol description.
|
||||||
|
|
||||||
|
- laid out in a big (compositor) coordinate system
|
||||||
|
|
||||||
|
- basically xrandr over Wayland
|
||||||
|
|
||||||
|
- geometry needs position in compositor coordinate system
|
||||||
|
|
||||||
|
- events to advertise available modes, requests to move and change modes
|
||||||
|
|
||||||
|
## Data sharing between clients
|
||||||
|
|
||||||
|
The Wayland protocol provides clients a mechanism for sharing data that allows
|
||||||
|
the implementation of copy-paste and drag-and-drop. The client providing the
|
||||||
|
data creates a `wl_data_source` object and the clients obtaining the data will
|
||||||
|
see it as `wl_data_offer` object. This interface allows the clients to agree on
|
||||||
|
a mutually supported mime type and transfer the data via a file descriptor that
|
||||||
|
is passed through the protocol.
|
||||||
|
|
||||||
|
The next section explains the negotiation between data source and data offer
|
||||||
|
objects. [Data devices](#data-devices) explains how these objects are created
|
||||||
|
and passed to different clients using the `wl_data_device` interface that
|
||||||
|
implements copy-paste and drag-and-drop support.
|
||||||
|
|
||||||
|
See [wl_data_offer](https://wayland.app/protocols/wayland#wl_data_offer),
|
||||||
|
[wl_data_source](https://wayland.app/protocols/wayland#wl_data_source),
|
||||||
|
[wl_data_device](https://wayland.app/protocols/wayland#wl_data_device) and
|
||||||
|
[wl_data_device_manager](https://wayland.app/protocols/wayland#wl_data_device_manager)
|
||||||
|
for protocol descriptions.
|
||||||
|
|
||||||
|
MIME is defined in RFC's 2045-2049. A [registry of MIME
|
||||||
|
types](https://www.iana.org/assignments/media-types/media-types.xhtml) is
|
||||||
|
maintained by the Internet Assigned Numbers Authority (IANA).
|
||||||
|
|
||||||
|
### Data negotiation
|
||||||
|
|
||||||
|
A client providing data to other clients will create a `wl_data_source` object
|
||||||
|
and advertise the mime types for the formats it supports for that data through
|
||||||
|
the `wl_data_source.offer` request. On the receiving end, the data offer object
|
||||||
|
will generate one `wl_data_offer.offer` event for each supported mime type.
|
||||||
|
|
||||||
|
The actual data transfer happens when the receiving client sends a
|
||||||
|
`wl_data_offer.receive` request. This request takes a mime type and a file
|
||||||
|
descriptor as arguments. This request will generate a `wl_data_source.send`
|
||||||
|
event on the sending client with the same arguments, and the latter client is
|
||||||
|
expected to write its data to the given file descriptor using the chosen mime
|
||||||
|
type.
|
||||||
|
|
||||||
|
### Data devices
|
||||||
|
|
||||||
|
Data devices glue data sources and offers together. A data device is associated
|
||||||
|
with a `wl_seat` and is obtained by the clients using the
|
||||||
|
`wl_data_device_manager` factory object, which is also responsible for creating
|
||||||
|
data sources.
|
||||||
|
|
||||||
|
Clients are informed of new data offers through the `wl_data_device.data_offer`
|
||||||
|
event. After this event is generated the data offer will advertise the available
|
||||||
|
mime types. New data offers are introduced prior to their use for copy-paste or
|
||||||
|
drag-and-drop.
|
||||||
|
|
||||||
|
#### Selection
|
||||||
|
|
||||||
|
Each data device has a selection data source. Clients create a data source
|
||||||
|
object using the device manager and may set it as the current selection for a
|
||||||
|
given data device. Whenever the current selection changes, the client with
|
||||||
|
keyboard focus receives a `wl_data_device.selection` event. This event is also
|
||||||
|
generated on a client immediately before it receives keyboard focus.
|
||||||
|
|
||||||
|
The data offer is introduced with `wl_data_device.data_offer` event before the
|
||||||
|
selection event.
|
||||||
|
|
||||||
|
#### Drag and Drop
|
||||||
|
|
||||||
|
A drag-and-drop operation is started using the `wl_data_device.start_drag`
|
||||||
|
request. This requests causes a pointer grab that will generate enter, motion
|
||||||
|
and leave events on the data device. A data source is supplied as argument to
|
||||||
|
start_drag, and data offers associated with it are supplied to clients surfaces
|
||||||
|
under the pointer in the `wl_data_device.enter` event. The data offer is
|
||||||
|
introduced to the client prior to the enter event with the
|
||||||
|
`wl_data_device.data_offer` event.
|
||||||
|
|
||||||
|
Clients are expected to provide feedback to the data sending client by calling
|
||||||
|
the `wl_data_offer.accept` request with a mime type it accepts. If none of the
|
||||||
|
advertised mime types is supported by the receiving client, it should supply
|
||||||
|
NULL to the accept request. The accept request causes the sending client to
|
||||||
|
receive a `wl_data_source.target` event with the chosen mime type.
|
||||||
|
|
||||||
|
When the drag ends, the receiving client receives a `wl_data_device.drop` event
|
||||||
|
at which it is expected to transfer the data using the `wl_data_offer.receive`
|
||||||
|
request.
|
||||||
12
doc/book/src/SUMMARY.md
Normal file
12
doc/book/src/SUMMARY.md
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Summary
|
||||||
|
|
||||||
|
[Foreword](Foreword.md)
|
||||||
|
|
||||||
|
- [Introduction](./Introduction.md)
|
||||||
|
- [Types of Compositors](./Compositors.md)
|
||||||
|
- [Wayland Architecture](./Architecture.md)
|
||||||
|
- [Wayland Protocol and Model of Operation](./Protocol.md)
|
||||||
|
- [Message Definition Language](./Message_XML.md)
|
||||||
|
- [X11 Application Support](./Xwayland.md)
|
||||||
|
- [Content Updates](./Content_Updates.md)
|
||||||
|
- [Color management](./Color.md)
|
||||||
120
doc/book/src/Xwayland.md
Normal file
120
doc/book/src/Xwayland.md
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
# X11 Application Support
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
Being able to run existing X11 applications is crucial for the adoption of
|
||||||
|
Wayland, especially on desktops, as there will always be X11 applications that
|
||||||
|
have not been or cannot be converted into Wayland applications, and throwing
|
||||||
|
them all away would be prohibitive. Therefore a Wayland compositor often needs
|
||||||
|
to support running X11 applications.
|
||||||
|
|
||||||
|
X11 and Wayland are different enough that there is no "simple" way to translate
|
||||||
|
between them. Most of X11 is uninteresting to a Wayland compositor. That,
|
||||||
|
combined with the gigantic implementation effort needed to support X11, makes it
|
||||||
|
intractable to just write X11 support directly in a Wayland compositor. The
|
||||||
|
implementation would be nothing short of a real X11 server.
|
||||||
|
|
||||||
|
Therefore, Wayland compositors should use Xwayland, the X11 server that lives in
|
||||||
|
the Xorg server source code repository and shares most of the implementation
|
||||||
|
with the Xorg server. Xwayland is a complete X11 server, just like Xorg is, but
|
||||||
|
instead of driving the displays and opening input devices, it acts as a Wayland
|
||||||
|
client. The rest of this chapter talks about how Xwayland works.
|
||||||
|
|
||||||
|
For integration and architecture reasons, while Xwayland is a Wayland client of
|
||||||
|
the Wayland compositor, the Wayland compositor is an X11 client of Xwayland.
|
||||||
|
This circular dependency requires special care from the Wayland compositor.
|
||||||
|
|
||||||
|
## Two Modes for Foreign Windows
|
||||||
|
|
||||||
|
In general, windows from a foreign window system can be presented in one of two
|
||||||
|
ways: rootless and rootful (not rootless).
|
||||||
|
|
||||||
|
In rootful mode, the foreign window system as a whole is represented as a window
|
||||||
|
(or more) of its own. You have a native window, inside which all the foreign
|
||||||
|
windows are. The advantage of this approach in Xwayland's case is that you can
|
||||||
|
run your favourite X11 window manager to manage your X11 applications. The
|
||||||
|
disadvantage is that the foreign windows do not integrate with the native
|
||||||
|
desktop. Therefore this mode is not usually used.
|
||||||
|
|
||||||
|
In rootless mode, each foreign window is a first-class resident among the native
|
||||||
|
windows. Foreign windows are not confined inside a native window but act as if
|
||||||
|
they were native windows. The advantage is that one can freely stack and mix
|
||||||
|
native and foreign windows, which is not possible in rootful mode. The
|
||||||
|
disadvantage is that this mode is harder to implement and fundamental
|
||||||
|
differences in window systems may prevent some things from working. With
|
||||||
|
rootless Xwayland, the Wayland compositor must take the role as the X11 window
|
||||||
|
manager, and one cannot use any other X11 window manager in its place.
|
||||||
|
|
||||||
|
This chapter concentrates on the rootless mode, and ignores the rootful mode.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
A Wayland compositor usually takes care of launching Xwayland. Xwayland works in
|
||||||
|
cooperation with a Wayland compositor as follows:
|
||||||
|
|
||||||
|
**Xwayland architecture diagram**
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
An X11 application connects to Xwayland just like it would connect to any X
|
||||||
|
server. Xwayland processes all the X11 requests. On the other end, Xwayland is a
|
||||||
|
Wayland client that connects to the Wayland compositor.
|
||||||
|
|
||||||
|
The X11 window manager (XWM) is an integral part of the Wayland compositor. XWM
|
||||||
|
uses the usual X11 window management protocol to manage all X11 windows in
|
||||||
|
Xwayland. Most importantly, XWM acts as a bridge between Xwayland window state
|
||||||
|
and the Wayland compositor's window manager (WWM). This way WWM can manage all
|
||||||
|
windows, both native Wayland and X11 (Xwayland) windows. This is very important
|
||||||
|
for a coherent user experience.
|
||||||
|
|
||||||
|
Since Xwayland uses Wayland for input and output, it does not have any use for
|
||||||
|
the device drivers that Xorg uses. None of the xf86-video-* or xf86-input-*
|
||||||
|
modules are used. There also is no configuration file for the Xwayland server.
|
||||||
|
For optional hardware accelerated rendering, Xwayland uses GLAMOR.
|
||||||
|
|
||||||
|
A Wayland compositor usually spawns only one Xwayland instance. This is because
|
||||||
|
many X11 applications assume they can communicate with other X11 applications
|
||||||
|
through the X server, and this requires a shared X server instance. This also
|
||||||
|
means that Xwayland does not protect nor isolate X11 clients from each other,
|
||||||
|
unless the Wayland compositor specifically chooses to break the X11 client
|
||||||
|
intercommunications by spawning application specific Xwayland instances. X11
|
||||||
|
clients are naturally isolated from Wayland clients.
|
||||||
|
|
||||||
|
Xwayland compatibility compared to a native X server will probably never reach
|
||||||
|
100%. Desktop environment (DE) components, specifically X11 window managers, are
|
||||||
|
practically never supported. An X11 window manager would not know about native
|
||||||
|
Wayland windows, so it could manage only X11 windows. On the other hand, there
|
||||||
|
must be an XWM that reserves the exclusive window manager role so that the
|
||||||
|
Wayland compositor could show the X11 windows appropriately. For other DE
|
||||||
|
components, like pagers and panels, adding the necessary interfaces to support
|
||||||
|
them in WWM through XWM is often considered not worthwhile.
|
||||||
|
|
||||||
|
## X Window Manager (XWM)
|
||||||
|
|
||||||
|
From the X11 point of view, the X window manager (XWM) living inside a Wayland
|
||||||
|
compositor is just like any other window manager. The difference is mostly in
|
||||||
|
which process it resides in, and the few extra conventions in the X11 protocol
|
||||||
|
to support Wayland window management (WWM) specifically.
|
||||||
|
|
||||||
|
There are two separate asynchronous communication channels between Xwayland and
|
||||||
|
a Wayland compositor: one uses the Wayland protocol, and the other one, solely
|
||||||
|
for XWM, uses X11 protocol. This setting demands great care from the XWM
|
||||||
|
implementation to avoid (random) deadlocks with Xwayland. It is often nearly
|
||||||
|
impossible to prove that synchronous or blocking X11 calls from XWM cannot cause
|
||||||
|
a deadlock, and therefore it is strongly recommended to make all X11
|
||||||
|
communications asynchronous. All Wayland communications are already asynchronous
|
||||||
|
by design.
|
||||||
|
|
||||||
|
### Window identification
|
||||||
|
|
||||||
|
In Xwayland, an X11 window may have a corresponding wl_surface object in
|
||||||
|
Wayland. The wl_surface object is used for input and output: it is referenced by
|
||||||
|
input events and used to provide the X11 window content to the Wayland
|
||||||
|
compositor. The X11 window and the wl_surface live in different protocol
|
||||||
|
streams, and they need to be matched for XWM to do its job.
|
||||||
|
|
||||||
|
When Xwayland creates a wl_surface on Wayland, it will also send an X11
|
||||||
|
ClientMessage of type atom "WL_SURFACE_ID" to the X11 window carrying the
|
||||||
|
wl_surface Wayland object ID as the first 32-bit data element. This is how XWM
|
||||||
|
can associate a wl_surface with an X11 window. Note that the request to create a
|
||||||
|
wl_surface and the ID message may arrive in any order in the Wayland compositor.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue