lib/wayland/src/root.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 //! The package lets a Zig program act as a client of a Wayland compositor, the
2 //! program that draws a Linux desktop: it frames the messages between the two,
3 //! names the objects those messages are about, passes open files across, and
4 //! sets up the shared memory that holds a window's pixels.
5 //!
6 //! A client and a compositor talk over a Unix domain socket, and every request
7 //! or event on it is a message about one object, named by a 32-bit id. Pixels
8 //! are too large to copy through the socket, so the client puts them in memory
9 //! both processes map and hands the compositor the open file behind that
10 //! memory. A client that runs for hours should keep a memory footprint fixed at
11 //! the size it had when it connected.
12 //!
13 //! Messages from asynchronous requests and events share one socket, together
14 //! with the open files some of them carry, and the kernel delivers the bytes in
15 //! pieces of its choosing, so a reader holds part of a message until the rest
16 //! arrives. An open file that crosses the socket is a kernel resource the
17 //! receiver now holds, so a reader that drops one and leaves it open leaks it.
18 //! The compositor acknowledges a client's delete some time after the client
19 //! sends it, so an id reused before that acknowledgement would name two objects
20 //! at once. The compositor reads a buffer after the client commits it, so a
21 //! client that writes new pixels into it too early changes an image the
22 //! compositor is still reading.
23 //!
24 //! The
25 //! [Wayland protocol](https://wayland.freedesktop.org/docs/book/Protocol.html)
26 //! answers these at the wire: each object follows an interface of numbered
27 //! requests and events, a message is an eight-byte header and a payload padded
28 //! to four bytes, open files ride beside the bytes as `SCM_RIGHTS` data on the
29 //! socket, and client and compositor draw ids from separate ranges. The package
30 //! takes the wire format and the interfaces themselves through request and
31 //! event tables (*generated protocol code*), generated from the upstream
32 //! protocol description of release 1.25.0, pinned by hash, and checked against
33 //! the output of the reference generator `wayland-scanner` 1.23.1.
34 //!
35 //! The package implements the wire in Zig, and the transport reads and writes
36 //! through an inbox and outbox (*transport ring*) the caller sizes before the
37 //! socket opens, holding one maximum-size message and one full batch of open
38 //! files by default. Every open file has one owner at each step (*descriptor
39 //! ownership*): a queued file passes to the transport once message validation
40 //! and room reservation succeed, and a received file the caller leaves untaken
41 //! is closed. Client ids come from a store allocated once (*object id pool*),
42 //! sized at 256 ids by default, which hands ids out and takes them back with no
43 //! further allocation and returns an id to reuse only after the compositor
44 //! acknowledges the delete. The client records each interface the compositor
45 //! advertises on its registry (*global*) in a separate store keyed by the
46 //! registry's name for it, kept apart from the objects the client creates. Each
47 //! pixel buffer is marked (*busy*) from the moment it is attached until the
48 //! compositor releases it: the compositor may still read it meanwhile, and the
49 //! client waits for the release before writing into it again. The protocol
50 //! object that names an open file to the compositor lives only as long as it
51 //! takes to create one buffer from it, and the mapping stays with the buffer.
52 //!
53 //! - *wire message*: one request or event on the socket, an eight-byte header
54 //! giving the object id, the opcode and the total size, followed by a payload
55 //! padded to four bytes.
56 //! - *object id*: the 32-bit name of one protocol object, where a client picks
57 //! ids below 0xff000000 and the compositor picks the rest.
58 //! - *shared memory pool*: the protocol object that names an open file to the
59 //! compositor, out of which one buffer is created and which the client
60 //! destroys at once, leaving the buffer live.
61
62 pub const connection = @import("connection.zig");
63 pub const ids = @import("ids.zig");
64 pub const protocol = @import("protocol/root.zig");
65 pub const runtime = @import("runtime/root.zig");
66 pub const shm = @import("shm/root.zig");
67 pub const stream = @import("stream/root.zig");
68 pub const transport = @import("transport.zig");
69 pub const wire = @import("wire.zig");
70
71 pub const Transport = transport.Transport;
72 pub const TransportLimits = transport.Limits;
73 pub const TransportCapacity = transport.Capacity;
74 pub const TransportCapacityError = transport.CapacityError;
75 pub const TransportStorageError = transport.StorageError;
76 pub const TransportStatus = transport.Status;
77 pub const ClientIdLimits = ids.Limits;
78 pub const ClientIdCapacity = ids.Capacity;
79 pub const ClientIdCapacityError = ids.CapacityError;
80 pub const ClientIdStorageError = ids.StorageError;
81 pub const ClientIdStorageStatus = ids.Status;
82 pub const default_client_id_count = ids.default_client_id_count;
83 pub const default_transport_byte_count = transport.default_byte_count;
84 pub const default_transport_descriptor_count = transport.default_descriptor_count;
85 pub const ProcessEnvironmentLimits = connection.ProcessEnvironmentLimits;
86 pub const ProcessEnvironmentCapacity = connection.ProcessEnvironmentCapacity;
87 pub const ProcessEnvironmentCapacityError = connection.ProcessEnvironmentCapacityError;
88 pub const process_environment_capacity = connection.process_environment_capacity;
89 pub const connect = connection.connect;
90 pub const connectNamed = connection.connectNamed;