Nexoniarz is the sole author and SchOS was never published under Apache-2.0, so this is a straight relicence. LICENSE is the FSF GPLv2 text, every first-party SPDX header moves to GPL-2.0-or-later, and NOTICE, README.md, docs/licensing.md and the site say so. projects/schfs-linux follows the rest of the tree. The GPL gives copyleft: a fork has to ship its source. It also lifts the old "Linux drivers, never" rule, since GPL-2.0-only code combines with GPL-2.0-or-later. "Or later" leaves room for GPLv3, but one binary still has to pick one version, so docs/licensing.md now keeps Apache-2.0 and GPLv3 code out of the kernel to keep Linux code possible there. BSD 4-clause code goes from "avoid" to "no", because the advertising clause is GPL-incompatible. LDLS still ships no .ko. That boundary is now project policy rather than a legal requirement, and ldls.md, devices.md and licensing.md section 6 say so. refmod declares license=GPL, and ldls-check passes (27 checks). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
128 lines
4.5 KiB
C
128 lines
4.5 KiB
C
/* 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 <stdint.h>
|
|
|
|
#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 */
|