| <?xml version='1.0' encoding='utf-8' ?> |
| <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ |
| <!ENTITY % BOOK_ENTITIES SYSTEM "Wayland.ent"> |
| %BOOK_ENTITIES; |
| ]> |
| <chapter id="chap-Protocol"> |
| <title>Wayland Protocol and Model of Operation</title> |
| <section id="sect-Protocol-Basic-Principles"> |
| <title>Basic Principles</title> |
| <para> |
| 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. |
| </para> |
| <para> |
| 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. |
| </para> |
| <para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| 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. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| The server will broadcast the presence of a number of global objects, |
| which in turn will broadcast their current state. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </section> |
| <section id="sect-Protocol-Code-Generation"> |
| <title>Code Generation</title> |
| <para> |
| The interfaces, requests and events are defined in |
| <filename>protocol/wayland.xml</filename>. |
| This xml is used to generate the function prototypes that can be used by |
| clients and compositors. |
| </para> |
| <para> |
| The protocol entry points are generated as inline functions which just |
| wrap the <function>wl_proxy_*</function> 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. |
| </para> |
| </section> |
| <section id="sect-Protocol-Wire-Format"> |
| <title>Wire Format</title> |
| <para> |
| The protocol is sent over a UNIX domain stream socket, where the endpoint |
| usually is named <systemitem class="service">wayland-0</systemitem> |
| (although it can be changed via <emphasis>WAYLAND_DISPLAY</emphasis> |
| in the environment). 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. Every message is |
| structured as 32-bit words, values are represented in the host's |
| byte-order. |
| </para> |
| <para> |
| The message header has 2 words in it: |
| <itemizedlist> |
| <listitem> |
| <para> |
| The first word is the sender's object ID (32-bit). |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| 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. |
| </para> |
| </listitem> |
| </itemizedlist> |
| 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. |
| </para> |
| <para> |
| |
| The representation of argument types are as follows: |
| <variablelist> |
| <varlistentry> |
| <term>int</term> |
| <term>uint</term> |
| <listitem> |
| <para> |
| The value is the 32-bit value of the signed/unsigned |
| int. |
| </para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term>fixed</term> |
| <listitem> |
| <para> |
| 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. |
| </para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term>string</term> |
| <listitem> |
| <para> |
| Starts with an unsigned 32-bit length, followed by the |
| string contents, including terminating null byte, then padding |
| to a 32-bit boundary. |
| </para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term>object</term> |
| <listitem> |
| <para> |
| 32-bit object ID. |
| </para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term>new_id</term> |
| <listitem> |
| <para> |
| The 32-bit object ID. On requests, the client |
| decides the ID. The only events with <type>new_id</type> are |
| advertisements of globals, and the server will use IDs below |
| 0x10000. |
| </para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term>array</term> |
| <listitem> |
| <para> |
| Starts with 32-bit array size in bytes, followed by the array |
| contents verbatim, and finally padding to a 32-bit boundary. |
| </para> |
| </listitem> |
| </varlistentry> |
| <varlistentry> |
| <term>fd</term> |
| <listitem> |
| <para> |
| The file descriptor is not stored in the message buffer, but in |
| the ancillary data of the UNIX domain socket message (msg_control). |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </para> |
| </section> |
| <xi:include href="ProtocolInterfaces.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/> |
| <section id="sect-Protocol-Versioning"> |
| <title>Versioning</title> |
| <para> |
| 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 verion 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. |
| </para> |
| <para> |
| In order to keep things sane, this has a few implications for |
| interface versions: |
| <itemizedlist> |
| <listitem> |
| <para> |
| The object creation hierarchy must be a tree. Otherwise, |
| infering object versions from the parent object becomes a much |
| more difficult to properly track. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| When the version of an interface increases, so does the version |
| of its parent (recursively until you get to a global interface) |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| 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. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </para> |
| <para> |
| 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. |
| </para> |
| <para> |
| 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. |
| </para> |
| </section> |
| <section id="sect-Protocol-Connect-Time"> |
| <title>Connect Time</title> |
| <para> |
| 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. |
| </para> |
| </section> |
| <section id="sect-Protocol-Security-and-Authentication"> |
| <title>Security and Authentication</title> |
| <para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| mostly about access to underlying buffers, need new drm auth |
| mechanism (the grant-to ioctl idea), need to check the cmd stream? |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| 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. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </section> |
| <section id="sect-Protocol-Creating-Objects"> |
| <title>Creating Objects</title> |
| <para> |
| 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-existant 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. Any ID allocation |
| algorithm that does not maintain this property is incompatible with |
| the implementation in libwayland. |
| </para> |
| </section> |
| <section id="sect-Protocol-Compositor"> |
| <title>Compositor</title> |
| <para> |
| The compositor is a global object, advertised at connect time. |
| </para> |
| <para> |
| See <xref linkend="protocol-spec-wl_compositor"/> for the |
| protocol description. |
| </para> |
| </section> |
| <section id="sect-Protocol-Surface"> |
| <title>Surfaces</title> |
| <para> |
| 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. |
| </para> |
| <para> |
| 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. |
| </para> |
| <para> |
| See <xref linkend="protocol-spec-wl_surface"/> for the protocol |
| description. |
| </para> |
| </section> |
| <section id="sect-Protocol-Input"> |
| <title>Input</title> |
| <para> |
| 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. |
| </para> |
| <para> |
| 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. |
| </para> |
| <para> |
| 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. |
| </para> |
| <para> |
| 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. |
| </para> |
| <para> |
| See <xref linkend="protocol-spec-wl_seat"/> for the |
| protocol description. |
| </para> |
| <para> |
| Talk about: |
| |
| <itemizedlist> |
| <listitem> |
| <para> |
| keyboard map, change events |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| xkb on Wayland |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| multi pointer Wayland |
| </para> |
| </listitem> |
| </itemizedlist> |
| </para> |
| <para> |
| 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. |
| </para> |
| <para> |
| The compositor will revert the pointer image back to a default image |
| when no surface has the pointer focus for that device. Clients can |
| revert the pointer image back to the default image by setting a NULL |
| image. |
| </para> |
| <para> |
| 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. Broken app, I suppose. |
| </para> |
| </section> |
| <section id="sect-Protocol-Output"> |
| <title>Output</title> |
| <para> |
| An output is a global object, advertised at connect time or as it |
| comes and goes. |
| </para> |
| <para> |
| See <xref linkend="protocol-spec-wl_output"/> for the protocol |
| description. |
| </para> |
| <para> |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para> |
| laid out in a big (compositor) coordinate system |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| basically xrandr over Wayland |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| geometry needs position in compositor coordinate system |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| events to advertise available modes, requests to move and change |
| modes |
| </para> |
| </listitem> |
| </itemizedlist> |
| </section> |
| <section id="sect-Protocol-data-sharing"> |
| <title>Data sharing between clients</title> |
| <para> |
| 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 |
| <function>wl_data_source</function> object and the clients |
| obtaining the data will see it as <function>wl_data_offer</function> |
| 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. |
| </para> |
| <para> |
| The next section explains the negotiation between data source and |
| data offer objects. <xref linkend="sect-Protocol-data-sharing-devices"/> |
| explains how these objects are created and passed to different |
| clients using the <function>wl_data_device</function> interface |
| that implements copy-paste and drag-and-drop support. |
| </para> |
| <para> |
| See <xref linkend="protocol-spec-wl_data_offer"/>, |
| <xref linkend="protocol-spec-wl_data_source"/>, |
| <xref linkend="protocol-spec-wl_data_device"/> and |
| <xref linkend="protocol-spec-wl_data_device_manager"/> for |
| protocol descriptions. |
| </para> |
| <para> |
| MIME is defined in RFC's 2045-2049. A |
| <ulink url="ftp://ftp.isi.edu/in-notes/iana/assignments/media-types/"> |
| registry of MIME types</ulink> is maintained by the Internet Assigned |
| Numbers Authority (IANA). |
| </para> |
| <section> |
| <title>Data negotiation</title> |
| <para> |
| A client providing data to other clients will create a <function>wl_data_source</function> |
| object and advertise the mime types for the formats it supports for |
| that data through the <function>wl_data_source.offer</function> |
| request. On the receiving end, the data offer object will generate one |
| <function>wl_data_offer.offer</function> event for each supported mime |
| type. |
| </para> |
| <para> |
| The actual data transfer happens when the receiving client sends a |
| <function>wl_data_offer.receive</function> request. This request takes |
| a mime type and a file descriptor as arguments. This request will generate a |
| <function>wl_data_source.send</function> 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. |
| </para> |
| </section> |
| <section id="sect-Protocol-data-sharing-devices"> |
| <title>Data devices</title> |
| <para> |
| Data devices glue data sources and offers together. A data device is |
| associated with a <function>wl_seat</function> and is obtained by the clients using the |
| <function>wl_data_device_manager</function> factory object, which is also responsible for |
| creating data sources. |
| </para> |
| <para> |
| Clients are informed of new data offers through the |
| <function>wl_data_device.data_offer</function> 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. |
| </para> |
| <section> |
| <title>Selection</title> |
| <para> |
| 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 |
| <function>wl_data_device.selection</function> event. This event is |
| also generated on a client immediately before it receives keyboard |
| focus. |
| </para> |
| <para> |
| The data offer is introduced with |
| <function>wl_data_device.data_offer</function> event before the |
| selection event. |
| </para> |
| </section> |
| <section> |
| <title>Drag and Drop</title> |
| <para> |
| A drag-and-drop operation is started using the |
| <function>wl_data_device.start_drag</function> 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 |
| <function>wl_data_device.enter</function> event. The data offer |
| is introduced to the client prior to the enter event with the |
| <function>wl_data_device.data_offer</function> event. |
| </para> |
| <para> |
| Clients are expected to provide feedback to the data sending client |
| by calling the <function>wl_data_offer.accept</function> 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 <function>wl_data_source.target</function> event with the |
| chosen mime type. |
| </para> |
| <para> |
| When the drag ends, the receiving client receives a |
| <function>wl_data_device.drop</function> event at which it is expected |
| to transfer the data using the |
| <function>wl_data_offer.receive</function> request. |
| </para> |
| </section> |
| </section> |
| </section> |
| </chapter> |