/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * The Schcom wire protocol. * * Versioned from the first commit, because SchWM and SchDE are separate * programs: the protocol is a real compatibility surface on day one, not after * the fact. A client sends SCHCOM_OP_HELLO with the version it speaks and the * compositor either acknowledges it or closes the connection. Nothing else is * accepted before the handshake. * * The shape is deliberately Wayland's, because Wayland support is intended * later and it is MIT-licensed, so it can be linked (see the licensing note in * the README). Borrowed, specifically: * * - a surface is not a window. It is a rectangle of pixels with no policy * attached; placement belongs to SchWM. * - a buffer is attached to a surface and nothing appears until COMMIT. * Atomicity is the whole point: a client that is halfway through drawing * must never be shown. * - the compositor tells the client when to draw again (FRAME), rather than * the client drawing whenever it likes. That is what stops a fast client * from burning the machine rendering frames nobody sees. * * Where it deliberately differs, for now: a buffer is a System V shared memory * id passed as an integer, not a file descriptor passed over SCM_RIGHTS. * SCM_RIGHTS is the Wayland-compatible route and the kernel supports it, but an * integer needs no ancillary-data handling on either side and this is v0. The * message carries a `handle_kind` field so the switch does not become a * protocol break. */ #ifndef SCHCOM_PROTO_H #define SCHCOM_PROTO_H #include #define SCHCOM_SOCKET_PATH "/tmp/schcom.sock" /* Bumped on any incompatible change. v0 is provisional in the SchAPI sense: * nothing here is frozen until 1.0. */ #define SCHCOM_VERSION 0u enum schcom_op { /* client -> compositor */ SCHCOM_OP_HELLO = 1, SCHCOM_OP_CREATE_SURFACE = 2, SCHCOM_OP_COMMIT = 3, SCHCOM_OP_DESTROY = 4, /* compositor -> client */ SCHCOM_OP_HELLO_ACK = 128, SCHCOM_OP_SURFACE = 129, /* the buffer for a CREATE_SURFACE */ SCHCOM_OP_FRAME = 130, /* draw again now */ SCHCOM_OP_INPUT = 131, SCHCOM_OP_ERROR = 132, }; /* How the pixels are shared. Only SHMID exists today; the field exists so that * adding SCM_RIGHTS later is a new value rather than a new protocol. */ enum schcom_handle_kind { SCHCOM_HANDLE_SHMID = 1, SCHCOM_HANDLE_FD = 2, /* reserved: passed over SCM_RIGHTS */ }; /* Every message begins with this. `length` counts the header itself, so a * reader can skip a message it does not understand instead of losing sync -- * which is what lets an old compositor talk to a newer client at all. */ struct schcom_header { uint32_t op; uint32_t length; uint32_t serial; /* echoed in the reply, 0 for events */ uint32_t surface; /* surface id, 0 where not applicable */ }; struct schcom_hello { struct schcom_header hdr; uint32_t version; uint32_t pad; }; struct schcom_create_surface { struct schcom_header hdr; uint32_t width; uint32_t height; int32_t x; /* v0: the client asks. SchWM will own this later. */ int32_t y; }; /* The compositor's answer: here is your surface id and where its pixels live. * Always 32-bit XRGB8888, stride in bytes, because a client that has to * negotiate a format before it can draw a rectangle is a client that cannot be * written in an afternoon. Format negotiation is a v1 problem. */ struct schcom_surface { struct schcom_header hdr; uint32_t handle_kind; uint32_t handle; /* shm id when handle_kind == SHMID */ uint32_t width; uint32_t height; uint32_t stride; uint32_t size; }; /* Nothing is shown until this arrives. The damage rectangle is advisory: the * compositor may repaint more, never less. */ struct schcom_commit { struct schcom_header hdr; int32_t x, y; uint32_t width, height; }; /* Raw-ish input, already routed to the surface that should have it. Codes are * the Linux input event codes the kernel's /dev/input/eventN already speaks -- * translating them here would mean inventing a second table to disagree with * the first. */ struct schcom_input { struct schcom_header hdr; uint32_t type; /* EV_KEY, EV_REL, ... */ uint32_t code; int32_t value; int32_t x, y; /* pointer position at the time of the event */ }; struct schcom_error { struct schcom_header hdr; uint32_t code; uint32_t pad; }; #endif /* SCHCOM_PROTO_H */