libei/proto/ei.proto
Peter Hutterer 29da572dca proto: separate pre-connection properties into ConfigureProperty
This is primarily for namespacing: where a portal sets some properties
it needs to do so *before* the Connect event. By moving this out to a
different namespace we can separate this easier, avoiding a portal
accidentally sending a property event after it has already passed the fd
to the client.

Fixes #23
2022-09-07 10:07:56 +10:00

388 lines
9.9 KiB
Protocol Buffer

syntax = "proto3";
/**
* EI Protocol Specification
*
* This protocol is an internal implementation detail and subject to change
* at any time. This specification is for developers of libei only.
*
* ClientMessage → sent from the client to the server
* ServerMessage → sent from the server to the client
*
* A normal sequence consists of:
* [0. - proxy configures connection, see the section below]
* 1. - client establishes connection to server
* 2. - client sends "Connect"
* 2.a - server replies with "Connected" or
* 2.b - server replies with "Disconnected" and closes its end of the socket
* 3. - server sends "AddSeat" (once or multiple times)
* 4. - client sends "BindSeat" for each seat
* 5. - server sends "DeviceAdded" for any device on this seat
* 6. - server sends "DeviceResumed"
* 7. - client sends "StartEmulating" to notify the server emulation starts
* 8. - client sends "PointerRelative" or any other event
* 9. - client sends "StopEmulating" to notify the server emulation starts
* 10. - client sends "CloseDevice"
* 11. - client sends "Disconnect" and closes its end of the socket
*
* The server may send Disconnect at any time.
* The server may send SeatRemoved for a device at any time.
* The server may send DeviceSuspended for any currently resumed device at any time.
* The server may send DeviceRemoved for a device at any time.
*
* Where a connection error occurs, the library (libei or libeis) will
* unroll the state as seen from the API.
*
* Pre-configuring a connection
* ----------------------------
*
* Where a proxy is in place (e.g. a portal), the client connection can be
* pre-configured to match the permissions model. The proxy opens or obtains a
* socket to the server, writes the Configure* messages onto that socket and
* then passes the fd to the client to create a libei context from that.
*
* The proxy can force a client name and/or restrict other options. This is
* invisible to the client, it does not know what restrictions are in place.
*
* Configure messages may only be sent before the client connection. Sending
* Configure messages after a client has connected will be silently ignored.
*/
/* Request the server version. This request MAY be sent at any time and/or
* multiple times and the server always replies with the server's highest
* supported version, see Version.
*
* To avoid roundtrips during the initial connection, an EIS implementation
* *SHOULD* send a Version message immediately. A client thus may not need to
* request the version.
*
* The "ei" field is the constant string "EI" and helps identifying
* this connection in debugging tools.
*/
message GetVersion {
string ei = 1; /* always "EI" */
}
/* Start a transaction of one or more Configure* messages, using the given protocol version.
* This MUST be the first Configure message sent and the transaction MUST be
* concluded by a ConfigureFinish message.
*
* Multiple transactions are permitted.
*/
message ConfigureStart {
uint32 version = 1; /* Must be equal or less to the server's GetVersion response */
}
/* Signals the end of Configure transaction. Typically, this indicates that the
* connection will be passed to a diffent process (e.g. from a portal to the
* actual EI client).
*
* A new Configure transaction (with a different version, if applicable) may
* start after this transaction.
*/
message ConfigureFinish {
}
/* ConfigureName *must* be sent before the Connect event. Once a name is set,
* subsequent attempts to change the name are ignored, including the name
* provided in the Connect message.
*/
message ConfigureName {
string name = 1;
}
/* Changes the capability policy and allows or denies specific capabilities.
* By default, a client starts with all capabilities permitted. If one or more
* ConfigureCapabilities messages are sent, the allowed capabilities is the
* binary AND of all allowed_capabilities masks.
*
* In other words, it is only possible to remove a capability with
* (subsequent) ConfigureCapabilities messages.
*/
message ConfigureCapabilities {
uint32 allowed_capabilities = 2;
}
/**
* ConfigureProperty *must* be sent before the Connect event. Once the client
* is connected or if sent outside a ConfigureStart/ConfigureFinish
* transaction, this message is ignored.
*/
message ConfigureProperty {
string name = 1;
string value = 2;
uint32 permissions = 3;
}
message Connect {
uint32 version = 1; /* Must be equal or less to the server's GetVersion response */
string name = 2;
bool is_sender = 3;
}
message ConnectDone {
}
message Disconnect {
}
message BindSeat {
uint32 seatid = 1;
uint32 capabilities = 2;
}
message CloseDevice {
uint32 deviceid = 1;
}
message PointerRelative {
uint32 deviceid = 1;
double x = 2;
double y = 3;
}
message PointerAbsolute {
uint32 deviceid = 1;
double x = 2;
double y = 3;
}
message PointerScroll {
uint32 deviceid = 1;
double x = 2;
double y = 3;
}
message PointerScrollDiscrete {
uint32 deviceid = 1;
double x = 2;
double y = 3;
}
message PointerScrollStop {
uint32 deviceid = 1;
bool x = 2;
bool y = 3;
bool is_cancel = 4;
}
message PointerButton {
uint32 deviceid = 1;
uint32 button = 2;
bool state = 3;
}
message KeyboardKey {
uint32 deviceid = 1;
uint32 key = 2;
bool state = 3;
}
message TouchDown {
uint32 deviceid = 1;
uint32 touchid = 2;
double x = 5;
double y = 6;
}
message TouchMotion {
uint32 deviceid = 1;
uint32 touchid = 2;
double x = 5;
double y = 6;
}
message TouchUp {
uint32 deviceid = 1;
uint32 touchid = 2;
}
message StartEmulating {
uint32 deviceid = 1;
}
message StopEmulating {
uint32 deviceid = 1;
}
message Frame {
uint32 deviceid = 1;
uint64 timestamp = 2;
}
message SetProperty {
string name = 1;
string value = 2;
uint32 permissions = 3;
}
message ClientMessage {
oneof msg {
/* Client setup and configuration */
Connect connect = 1;
ConnectDone connect_done = 2;
Disconnect disconnect = 3;
BindSeat bind_seat = 4;
CloseDevice close_device = 6;
SetProperty set_property = 9;
GetVersion get_version = 10;
/* Events */
StartEmulating start_emulating = 20;
StopEmulating stop_emulating = 21;
PointerRelative pointer_relative = 22;
PointerAbsolute pointer_absolute = 23;
PointerScroll pointer_scroll = 24;
PointerScrollDiscrete pointer_scroll_discrete = 25;
PointerScrollStop pointer_scroll_stop = 26;
PointerButton pointer_button = 27;
KeyboardKey keyboard_key = 28;
TouchDown touch_down = 29;
TouchMotion touch_motion = 30;
TouchUp touch_up = 31;
Frame frame = 32;
/* Pre-connection configuration */
ConfigureStart configure_start = 100;
ConfigureFinish configure_finish = 101;
ConfigureName configure_name = 102;
ConfigureCapabilities configure_capabilities = 103;
ConfigureProperty configure_property = 104;
}
}
/**
* The highest version number supported by the server. This message SHOULD be
* sent by the EIS implementation immediately after a socket is
* created/obtained. This avoids roundtrips between the server and the client
* on connection.
*
* This message MAY be sent at any other time.
* This message MUST be sent in response to a GetVersion request.
*
* The "eis" field is the constant string "EIS" and helps identifying
* this connection in debugging tools.
*
* The content of this message never changes.
*/
message Version {
uint32 version = 1;
string eis = 2; /* always "EIS" */
}
message Connected {
}
message Disconnected {
}
message Property {
string name = 1;
string value = 2;
uint32 permissions = 3;
}
message SeatAdded {
uint32 seatid = 1;
uint32 capabilities = 2;
string name = 3;
}
message SeatRemoved {
uint32 seatid = 1;
}
message DeviceAdded {
uint32 deviceid = 1;
uint32 capabilities = 2;
string name = 6;
uint32 seatid = 7;
uint32 type = 8;
uint32 width = 9;
uint32 height = 10;
}
message DeviceKeymap {
uint32 deviceid = 1;
uint32 keymap_type = 2;
uint32 keymap_size = 3;
/* keymap itself is passed as fd */
}
message DeviceRegion {
uint32 deviceid = 1;
uint32 offset_x = 2;
uint32 offset_y = 3;
uint32 width = 4;
uint32 height = 5;
double scale = 6;
}
message DeviceDone {
uint32 deviceid = 1;
}
message DeviceRemoved {
uint32 deviceid = 1;
}
message DeviceResumed {
uint32 deviceid = 1;
}
message DevicePaused {
uint32 deviceid = 1;
}
message KeyboardModifiers {
uint32 deviceid = 1;
uint32 depressed = 2;
uint32 locked = 3;
uint32 latched = 4;
uint32 group = 5;
}
message ServerMessage {
oneof msg {
/* Server setup and configuration */
Connected connected = 2;
Disconnected disconnected = 3;
SeatAdded seat_added = 4;
SeatRemoved seat_removed = 5;
DeviceAdded device_added = 6;
DeviceRegion device_region = 7;
DeviceKeymap device_keymap = 8;
DeviceDone device_done = 9;
DeviceRemoved device_removed = 10;
DeviceResumed device_resumed = 11;
DevicePaused device_paused = 12;
KeyboardModifiers keyboard_modifiers = 13;
Property property = 14;
Version version = 15;
/* Events */
StartEmulating start_emulating = 20;
StopEmulating stop_emulating = 21;
PointerRelative pointer_relative = 22;
PointerAbsolute pointer_absolute = 23;
PointerScroll pointer_scroll = 24;
PointerScrollDiscrete pointer_scroll_discrete = 25;
PointerScrollStop pointer_scroll_stop = 26;
PointerButton pointer_button = 27;
KeyboardKey keyboard_key = 28;
TouchDown touch_down = 29;
TouchMotion touch_motion = 30;
TouchUp touch_up = 31;
Frame frame = 32;
}
}
/* Protobuf-C only works correctly if the length of the next message is
* known, so we need to prefix *every* message with our packed size.
* This message is used by server and client but it's an implementation
* detail, not a part of the actual protocol.
*/
message Packet {
fixed32 length = 1;
}