From 1835ae5713d21f98444bcd4044381e448c262e32 Mon Sep 17 00:00:00 2001 From: Thiago Mendes Date: Mon, 10 Jul 2017 13:56:18 -0500 Subject: [PATCH 2/3] Converting Spice_protocol.odt to Asciidoc https://bugs.freedesktop.org/show_bug.cgi?id=95258 --- docs/Makefile.am | 8 +- docs/Spice_protocol.adoc | 2728 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2734 insertions(+), 2 deletions(-) create mode 100644 docs/Spice_protocol.adoc diff --git a/docs/Makefile.am b/docs/Makefile.am index 107c7097..d8ee4cb7 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -5,12 +5,13 @@ EXTRA_DIST = \ spice_style.html \ spice_style.txt \ Spice_for_newbies.adoc \ + Spice_protocol.adoc \ $(NULL) if BUILD_MANUAL SUBDIRS = manual -all-local: spice_style.html Spice_for_newbies.html +all-local: spice_style.html Spice_for_newbies.html Spice_protocol.html spice_style.html: spice_style.txt $(AM_V_GEN) $(ASCIIDOC) -n $(ASCIIDOC_FLAGS) -o $@ $< @@ -18,7 +19,10 @@ spice_style.html: spice_style.txt Spice_for_newbies.html: Spice_for_newbies.adoc $(AM_V_GEN) $(ASCIIDOC) -n $(ASCIIDOC_FLAGS) -o $@ $< +Spice_protocol.html: Spice_protocol.adoc + $(AM_V_GEN) $(ASCIIDOC) -n $(ASCIIDOC_FLAGS) -o $@ $< + endif clean-local: - rm -f spice_style.html Spice_for_newbies.html + rm -f spice_style.html Spice_for_newbies.html Spice_protocol.html diff --git a/docs/Spice_protocol.adoc b/docs/Spice_protocol.adoc new file mode 100644 index 00000000..b258047e --- /dev/null +++ b/docs/Spice_protocol.adoc @@ -0,0 +1,2728 @@ += Spice remote computing protocol definition +:revnumber: v1.0 +:revdate: 01.01.2009 +:revremark: Draft 1 + +Copyright (C) 2009 Red Hat, Inc. + +Licensed under a Creative Commons Attribution-Share Alike 3.0 + +United States License (see +http://creativecommons.org/licenses/by-sa/3.0/us/legalcode) + + +:toc: + +== Introduction + +Spice protocol defines a set of protocol messages for accessing, controlling, +and receiving inputs from remote computing devices (e.g., keyboard, video, +mouse) across networks, and sending output to them. A controlled device can +reside on either side, client and/or server. In addition, the protocol defines +a set of calls for supporting migration of a remote server from one network +address to another. Encryption of transported data, with one exception, was +kept out of the protocol for maximum flexibility in choosing an encryption +method. Spice uses simple messaging and does not depend on any RPC standard or +a specific transport layer. + +Spice communication session is split into multiple communication channels +(e.g., every channel is a remote device) in order to have the ability to +control communication and execution of messages according to the channel type +(e.g. QoS encryption), and to add and remove communication channels during run +time (which is supported by spice protocol definition). The following +communication channels are defined in the current protocol definition: a). the +main channel serves as the main spice session connection b). display channel +for receiving remote display updates c). inputs channel for sending mouse and +keyboard events d). cursor channel for receiving pointer shape and position e). +Playback channel for receiving audio stream, and f). Record channel for sending +audio capture. More channel types will be added as the protocol evolves. Spice +also defines a set of protocol definitions for synchronizing channels` +execution on the remote site. + +== Common Protocol definition + +. Endianness ++ +Unless stated otherwise, all data structures are packed and byte and bit order +is in little endian format. ++ +. Data types ++ +.. UINT8 – 8 bits unsigned integer +.. INT16 – 16 bits signed integer +.. UINT16 – 16 bits unsigned integer +.. UINT32 – 32 bits unsigned integer +.. INT32 - 32 bits signed integer +.. UINT64 – 64 bits unsigned integer +.. ADDRESS - 64 bits unsigned integer, value is the offset of the addressed +data from the beginning of spice protocol message body (i.e., data following +RedDataHeader or RedSubMessage). +.. FIXED28_4 – 32 bits fixed point number. 28 high bits are signed integer. Low +4 bits is unsigned integer numerator of a fraction with denominator 16. +.. POINT ++ +INT32 x + +INT32 y + ++ +.. POINT16 ++ +INT16 x + +INT16 y + ++ +.. RECT ++ +INT32 top + +INT32 left + +INT32 bottom + +INT32 right + ++ +.. POINTFIX ++ +FIXED28_4 x + +FIXED28_4 y + ++ +. Protocol Magic number UINT8[4] ++ +RED_MAGIC = { 0x52, 0x45, 0x44, 0x51} ++ +. Protocol version ++ +Protocol version defined as two UINT32 values, major protocol version and +minor protocol version. Server and client having the same major version must +keep compatibility regardless of minor version (i.e., incrementing the major +version brakes compatibility). Major protocol version with "huge" value are +reserved for development purposes and are considered unsupported and +unreliable. "huge" values are defined as having bit 31 set. The minor protocol +version is incremented on every protocol change that does not break +compatibility. It is set to zero on major protocol version increment. ++ +.. Current Protocol version ++ +[source,c] +---- +RED_VERSION_MAJOR = 1 +RED_VERSION_MINOR = 0 +---- ++ +. Compatibility – UINT32[] ++ +In order to allow some degree of flexibility in client and server +implementation and in order to improve compatibility, spice protocol supports +bidirectional exchange of channels compatibilities. Compatibilities are +expressed in UINT32 vector that is split into two groups: common +compatibilities and channels compatibilities. Common compatibilities stands for +compatibilities shared by all channels, and channels compatibilities stands +for channel specific compatibilities. Splitting the vector into two types +allows us to add channel compatibilities independently. Each compatibility is +expressed using one or more bits in the compatibilities vector. ++ +. Channel types – UINT8 ++ +[source,c] +---- +RED_CHANNEL_MAIN = 1 +RED_CHANNEL_DISPLAY = 2 +RED_CHANNEL_INPUTS = 3 +RED_CHANNEL_CURSOR = 4 +RED_CHANNEL_PLAYBACK = 5 +RED_CHANNEL_RECORD = 6 +---- ++ +. Error codes UINT32 ++ +[source,c] +---- +RED_ERROR_OK = 0 +RED_ERROR_ERROR = 1 +RED_ERROR_INVALID_MAGIC = 2 +RED_ERROR_INVALID_DATA = 3 +RED_ERROR_VERSION_MISMATCH = 4 +RED_ERROR_NEED_SECURED = 5 +RED_ERROR_NEED_UNSECURED = 6 +RED_ERROR_PERMISSION_DENIED = 7 +RED_ERROR_BAD_CONNECTION_ID = 8 +RED_ERROR_CHANNEL_NOT_AVAILABLE = 9 +---- ++ +. Warning codes ++ +[source,c] +---- +RED_WARN_GENERAL = 0 +---- ++ +. Information codes ++ +[source,c] +---- +RED_INFO_GENERAL = 0 +---- ++ +. public key buffer size. ++ +[source,c] +---- +RED_TICKET_PUBKEY_BYTES = 162 /* size needed for holding 1024 bit RSA public +key in X.509 SubjectPublicKeyInfo format. */ +---- ++ +. Channel link: establishing a channel connection. ++ +.. Connection process ++ +The channel connection process is initiated by the client. The client sends +RedLinkMess. In response, the server sends RedLinkReply. When the client +receives RedLinkReply, it examines the error code and in case there is no +error it encrypts its password with public key received in RedLinkReply and +sends it to the server. The server receive the password and sends the link +result to the client. The client examines the link result, and in case the +result equals to RED_ERROR_OK, a valid connection is established. ++ +Channel connection for channel types other then RED_CHANNEL_MAIN is allowed +only after the client has active RED_CHANNEL_MAIN channel connection. Only one +RED_CHANNEL_MAIN connection is allowed, and this channel connection establishes +spice session with the remote server. ++ +.. Ticketing ++ +Ticketing is a mechanism implemented in spice to ensure connections are opened +only from authorized sources. To enable this mechanism a ticket is set in spice +server consisting of a password and time validity. After time validity passes, +the whole ticket is expired. The ticket is encrypted. To encrypt, server +generates a 1024 bit RSA key and send the public part to the client (via +RedLinkInfo). Client uses this key to encrypt the password and send it back to +server (after RedLinkMess). Server decrypt the password, compare it to ticket +and ensure it was received within the allowed time-frame. ++ +.. RedLinkMess definition. ++ +[source,c] +---- +UINT32 magic +---- ++ +value of this fields must be equal to RED_MAGIC ++ +[cols="2*"] +|=== +|UINT32 major_version +| value of this fields must be equal to RED_VERSION_MAJOR + +|UINT32 minor_version +|value of this fields must be equal to RED_VERSION_MINOR + +|UINT32 size +|number of bytes following this field to the end of this message. + +|UINT32 connection_id +|In case of a new session (i.e., channel type is RED_CHANNEL_MAIN) this field +is set to zero, and in response the server will allocate session id and will +send it via the RedLinkReply message. In case of all other channel types, this +field will be equal to the allocated session id. + +|UINT8 channel_type +|one of RED_CHANNEL_? + +|UINT8 channel_id +|channel id to connect to. This enables having multiple channels of the same +type. + +|UINT32 num_common_caps +|number of common client channel capabilities words + +|UINT32 num_channel_caps +|number of specific client channel capabilities words + +|UINT32 caps_offset +|location of the start of the capabilities vector given by the bytes offset +from the “ size” member (i.e., from the address of the “connection_id” member). +|=== ++ +.. RedLinkReply definition ++ +[cols="2*"] +|=== +|UINT32 magic +|value of this field must be equal to RED_MAGIC + +|UINT32 major_version +|server major protocol version. + +|UINT32 minor_version +|server minor protocol version. + +|UINT32 size +|number of bytes following this field to the end of this message. + +|UINT32 error +|Error codes (i.e., RED_ERROR_?) + +|UINT8[RED_TICKET_PUBKEY_BYTES] pub_key +|1024 bit RSA public key in X.509 SubjectPublicKeyInfo format. + +|UINT32 num_common_caps +|number of common server channel capabilities words + +|UINT32 num_channel_caps +|number of specific server channel capabilities words + +|UINT32 caps_offset +|location of the start of the capabilities vector given by the bytes offset +from the “ size” member (i.e., from the address of +the “connection_id” member) +|=== ++ +.. Encrypted Password ++ +Client sends RSA encrypted password, with public key received from server (in +RedLinkReply). Format is EME-OAEP as described in PKCS#1 v2.0 with SHA-1, MGF1 +and an empty encoding parameter. ++ +.. Link Result UINT32 ++ +The server sends link result error code (i.e., RED_ERROR_?) ++ +. Protocol message definition ++ +All messages transmitted after the link stage have a common message layout. It +begins with RedDataHeader which describes one main message and an optional sub +messages list. ++ +.. RedDataHeader ++ +[cols="2*"] +|=== +|UINT64 serial +|serial number of the message within the channel. Serial numbers start with a +value of 1 and are incremented on every message transmitted. + +|UINT16 type +|message type can be one that is accepted by all channel (e.g., RED_MIGRATE), +or specific to a channel type (e.g., RED_DISPLAY_MODE for display channel). + +|UINT32 size +|size of the message body in bytes. In case sub_list (see below) is not zero +then the actual main message size is sub_list. The message body follows +RedDataHeader + +|UINT32 sub_list +|optional sub-messages list. If this field is not zero then sub_list is the +offset in bytes to RedSubMessageList from the end of RedDataHeader. All +sub-messages need to be executed before the main message, and in the order they +appear in the sub-messageslist. +|=== ++ +.. RedSubMessageList ++ +[cols="2*"] +|=== +|UINT16 size +|number of sub-messages in this list. + +|UINT32[] sub_messages +|array of offsets to sub message, offset is number of bytes from the end of +RedDataHeader to start of RedSubMessage. +|=== ++ +.. RedSubMessage ++ +[cols="2*"] +|=== +|UINT16 type +|message type can be one that is accepted by all channel (e.g., RED_MIGRATE), +or specific to a channel type (e.g., RED_DISPLAY_MODE for display channel). + +|UINT32 size +|size of the message body in bytes. The message body follows RedSubMessage. +|=== ++ +. Common messages and messaging naming convention ++ +Messages types and message body structures are prefixed according to the +source of the message. The prefixes for messages sent from the server to the +client are RED for types and Red for structures. For messages sent from the +client the prefixes are REDC and Redc. ++ +. Server messages that are common to all channels ++ +[source,c] +---- +RED_MIGRATE = 1 +RED_MIGRATE_DATA = 2 +RED_SET_ACK = 3 +RED_PING = 4 +RED_WAIT_FOR_CHANNELS = 5 +RED_DISCONNECTING = 6 +RED_NOTIFY = 7 + +RED_FIRST_AVAIL_MESSAGE = 101 +---- ++ +Specific channel server messages start from RED_FIRST_AVAIL_MESSAGE. All +message types from RED_NOTIFY + 1 to RED_FIRST_AVAIL_MESSAGE – 1 are reserved +for further use. ++ +. Client messages that are common to all channels ++ +[source,c] +---- +REDC_ACK_SYNC = 1 +REDC_ACK = 2 +REDC_PONG = 3 +REDC_MIGRATE_FLUSH_MARK = 4 +REDC_MIGRATE_DATA = 5 +REDC_DISCONNECTING = 6 + +REDC_FIRST_AVAIL_MESSAGE = 101 +---- ++ +Specific channel client messages start from REDC_FIRST_AVAIL_MESSAGE. All +message types from REDC_ACK_SYNC+ 1 to REDC_FIRST_AVAIL_MESSAGE – 1 are +reserved for further use. ++ +. Messages acknowledgment. ++ +Spice provides a set of messages for requesting an acknowledgment on every one +or more messages that the client consumes. In order to request acknowledgment +messages, the server sends RED_SET_ACK with the requested acknowledgment +frequency – after how many received messages the client sends acknowledgment. . +In response, the client sends REDC_ACK_SYNC. From this point, for every +requested number of messages that the client receive, it will send a REDC_ACK +message. ++ +.. RED_SET_ACK, RedSetAck ++ +[cols="2*"] +|=== +|UINT32 generation +|the generation of the acknowledgment sequence. This value will be sent back by +REDC_ACK_SYNC. It is used for acknowledgment accounting synchronization. + +|UINT32 window +|the window size. Spice client will send acknowledgment for every “window” +messages. Zero window size will disable messages acknowledgment. +|=== ++ +.. REDC_ACK_SYNC, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|Spice client sends RedSetAck.generation in response to RED_SET_ACK +|=== ++ +.. REDC_ACK, VOID ++ +Spice client sends REDC_ACK message for every RedSetAck.window messages it +consumes. ++ +. Ping ++ +Spice protocol provides ping messages for debugging purpose. Spice server sends +RED_PING and the client responses with REDC_PONG. The server can measure round +trip time by subtracting current time with the time that is returned in +REDC_PONG message. ++ +.. RED_PING, RedPing ++ +[cols="2*"] +|=== +|UINT32 id +|the id of this message + +|UINT64 time +|time stamp of this message +|=== ++ +.. REDC_PONG, RedPong ++ +[cols="2*"] +|=== +|UINT32 id +|Spice client copies it from RedPing.id + +|UINT64 time +|Spice client copies it from RedPing.time +|=== ++ +. Channel migration ++ +Spice supports migration of Spice server. The following common messages +combined with specific main channel messages is used for migrating channels +connections between spice servers. We will refer these servers as source and +destination. Main channel is used for initiating and controlling the migration +process. The following describes the actual channel migration process. ++ +Channel migration process starts with sending RED_MIGRATE message from the +server. The client receives the message, examine the attached flags and: if the +server requests messages flush (i.e., RED_MIGRATE_NEED_FLUSH flag is on), the +client sends REDC_MIGRATE_FLUSH_MARK message to the server. This procedure can +be used to ensure safe delivery of all mid air messages before performing the +migration action. if the server requests data transfer (i.e., +RED_MIGRATE_NEED_DATA_TRANSFER flag is on), the client expects to receive one +last message from the server before migrating to destination. This message type +must be RED_MIGRATE_DATA type. The content of the received message will be +transmitted to the destination on connection swap. ++ +Afterward, the client swaps communication channels (i.e., starts using the +connection with the destination server). The client can close connection with +the source server only after all other channels also have finished the +migration process. If the server side has requested data transfer, the client +first transmits REDC_MIGRATE_DATA message containing the data received on +RED_MIGRATE_DATA. ++ +.. Migration flags ++ +[source,c] +---- +RED_MIGRATE_NEED_FLUSH = 1 +RED_MIGRATE_NEED_DATA_TRANSFER = 2 +---- ++ +.. RED_MIGRATE, RedMigrate ++ +[cols="2*"] +|=== +|UINT32 flags +|combination of red migration flags. +|=== ++ +... RED_MIGRATE_DATA, UINT8[] ++ +Server migrate data, body of this message is variable length raw data that is +determined by each channel type independently ++ +... REDC_MIGRATE_FLUSH_MARK, VOID ++ +This messages mark completion of client communication channel flushing. ++ +.. REDC_MIGRATE_DATA, UINT8[] ++ +Post migration data, sent by client to the destination, containing the data +sent by the source using the RED_MIGRATE_DATA message. ++ +[[channel_sync]] +. Channel synchronization ++ +Spice provides mechanism for synchronizing channels message execution on the +client side. The server sends RED_WAIT_FOR_CHANNELS message which contains a +list of channels messages to wait for (i.e., RedWaitForChannels). The Spice +client will wait for completion of all the messages that are in that list +before executing any more messages. ++ +.. RedWaitForChannel ++ +[cols="2*"] +|=== +|UINT8 type +|channel type (e.g., RED_CHANNEL_INPUTS) + +|UINT8 id +|channel id. + +|UIN64 serial +|message serial id (i.e, RedDataHeader.serial) to wait for +|=== ++ +... RED_WAIT_FOR_CHANNELS, RedWaitForChannels ++ +[cols="2*"] +|=== +|UINT8 wait_count +|number of items in wait_list + +|RedWaitForChannel[] wait_list +|list of channels to wait for. +|=== ++ +. Disconnect reason ++ +The following messages are used for notification about orderly disconnection +of the server or client. ++ +.. RED_DISCONNECTING, RedDisconnect ++ +[cols="2*"] +|=== +|UINT64 time_stamp +|time stamp of disconnect action on the server. + +|UINT32 reason +|disconnect reason, RED_ERROR_? +|=== ++ +.. REDC_DISCONNECTING, RedcDisconnect ++ +[cols="2*"] +|=== +|UINT64 time_stamp +|time stamp of disconnect action on the client. + +|UINT32 reason +|disconnect reason, RED_ERROR_? +|=== ++ +. Server notification ++ +Spice protocol defines message for delivering notifications to the client using +RED_NOTIFY message. Messages are categorized by severity and visibility. The +later can be used as hint for the way the message is displayed to the user. For +example high visibility notifications will trigger message box and low +visibility notifications will be directed to the log. ++ +.. RED_NOTIFY, RedNotify ++ +[cols="2*"] +|=== +|UINT64 time_stamp +|server side time stamp of this message. + +|UINT32 severity +|one of RED_NOTIFY_SEVERITY_? + +|UINT32 visibility +|one of RED_NOTIFY_VISIBILITY_? + +|UINT32 what +|one of RED_ERROR_?, RED_WARN_? Or RED_INFO_?, depending on severity. + +|UINT32 message_len +|size of message + +|UINT8[] message +|message string in UTF8. + +|UINT8 0 +|string zero termination +|=== + +== Main Channel definition + +. Server messages ++ +[source,c] +---- +RED_MAIN_MIGRATE_BEGIN = 101 +RED_MAIN_MIGRATE_CANCEL = 102 +RED_MAIN_INIT = 103 +RED_MAIN_CHANNELS_LIST = 104 +RED_MAIN_MOUSE_MODE = 105 +RED_MAIN_MULTI_MEDIA_TIME = 106 + +RED_MAIN_AGENT_CONNECTED = 107 +RED_MAIN_AGENT_DISCONNECTED = 108 +RED_MAIN_AGENT_DATA = 109 +RED_MAIN_AGENT_TOKEN = 110 +---- ++ +. Client messages ++ +[source,c] +---- +REDC_MAIN_RESERVED = 101 +REDC_MAIN_MIGRATE_READY = 102 +REDC_MAIN_MIGRATE_ERROR = 103 +REDC_MAIN_ATTACH_CHANNELS = 104 +REDC_MAIN_MOUSE_MODE_REQUEST = 105 + +REDC_MAIN_AGENT_START = 106 +REDC_MAIN_AGENT_DATA = 107 +REDC_MAIN_AGENT_TOKEN = 108 +---- ++ +. Migration control ++ +Spice migration control is performed using the main channel messages. Spice +server initiates migration process by sending RED_MAIN_MIGRATE_BEGIN message. +Once the client has completed its pre-migrate procedure it notifies the server +by transmitting REDC_MAIN_MIGRATE_READY message. In case of pre-migrate +procedure error, the client sends REDC_MAIN_MIGRATE_ERROR. Once the server +receives REDC_MAIN_MIGRATE_READY he can commence the migration process. The +server can send RED_MAIN_MIGRATE_CANCEL in order to instruct the client to +cancel the migration process. ++ +.. RED_MAIN_MIGRATE_BEGIN, RedMigrationBegin ++ +[cols="2*"] +|=== +|UINT16 port +|port of destination server + +|UINT16 sport +|secure port of destination server + +|UINT8[] host_name +|host name of destination server +|=== ++ +.. RED_MAIN_MIGRATE_CANCEL, VOID ++ +Instruct the client to cancel migration process ++ +.. REDC_MAIN_MIGRATE_READY, VOID ++ +Notify the server of successful completion of the pre-migrate stage ++ +.. REDC_MAIN_MIGRATE_ERROR, VOID ++ +Notify the server of pre-migrate stage error ++ +[[mouse_modes]] +. Mouse modes ++ +Spice protocol specifies two mouse modes, client mode and server mode. In +client mode, the affective mouse is the client side mouse: the client sends +mouse position within the display and the server sends mouse shape messages. In +server mode, the client sends relative mouse movements and the server sends +position and shape commands. Spice main channel is used for mouse mode control. ++ +.. Modes ++ +[source,c] +---- +RED_MOUSE_MODE_SERVER = 1 +RED_MOUSE_MODE_CLIENT = 2 +---- ++ +.. RED_MAIN_MOUSE_MODE, RedMouseMode ++ +Spice server sends this message on every mouse mode change ++ +[cols="2*"] +|=== +|UINT32 supported_modes +|current supported mouse mode, this is any combination of RED_MOUSE_MODE_? + +|UINT32 current_mode +|the current mouse mode. Can be one of RED_MOUSE_MODE_? +|=== ++ +.. REDC_MAIN_MOUSE_MODE_REQUEST, UINT32 ++ +Spice client sends this message to request specific mouse mode. It is not +guarantied that the server will accept the request. Only on receiving +RED_MOUSE_MODE message, the client can know of actual mouse mode change. ++ +[cols="2*"] +|=== +|UINT32 +|requested mode, one of RED_MOUSE_MODE_? +|=== ++ +. Main channel init message ++ +Spice server must send RedInit as the first transmitted message t and is +disallowed to send it at any other point. ++ +.. RED_MAIN_INIT, RedInit ++ +[cols="2*"] +|=== +|UINT32 session_id +|session id is generated by the server. This id will be send on every new +channel connection within this session (i.e., in RedLinkMess.connection_id). + +|UINT32 display_channels_hint +|optional hint of expected number of display channels. Zero is defined as an +invalid value + +|UINT32 supported_mouse_modes +|supported mouse modes. This is any combination of RED_MOUSE_MODE_? + +|UINT32 current_mouse_mode +|the current mouse mode, one of RED_MOUSE_MODE_? + +|UINT32 agent_connected +|current state of Spice agent (see <>), 0 and 1 stand +for disconnected and connected state respectively. + +|UINT32 agent_tokens +|number of available tokens for sending messages to Spice agent. + +|UINT32 multi_media_time +|current server multimedia time. The multimedia time is used for synchronizing +video (for more information see <>) + +|UINT32 ram_hint +|optional hint for help in determining global LZ compression dictionary size +(for more information see section <> in “Display +Channel”). +|=== ++ +. Server side channels notification ++ +In order to have the ability to dynamically attach to the server side channels, +Spice protocol includes RED_MAIN_CHANNELS_LIST message. This massage informs +the client of available channels in the server side. In response to this +message the client can decide to link with the new available channel(s). The +server must receive REDC_MAIN_ATTACH_CHANNELS before sending any +RED_MAIN_CHANNELS_LIST message. ++ +.. RED_MAIN_CHANNELS_LIST, RedChannels ++ +[cols="2*"] +|=== +|UINT32 num_of_channels +|number of channels in this list + +|RedChanneID[] channels +|vector of “num_of_channels” channel ids +|=== ++ +.. RedChanneID ++ +[cols="2*"] +|=== +|UINT8 type +|channel type, one of RED_CHANNEL_? channel types, except for RED_CHANNEL_MAIN + +|UINT8 id +|channel id +|=== ++ +[[multimedia_time]] +. Multimedia time ++ +Spice defines messages for setting multimedia time for synchronization of video +and audio streams. Two methods for updating multimedia time are supported. The +first method uses the time stamp of data that arrives on the playback +channel.The second method uses the main channel RED_MAIN_MULTI_MEDIA_TIME +message. The latter method is used when no active playback channel exist. ++ +.. RED_MAIN_MULTI_MEDIA_TIME, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|multimedia time +|=== ++ +[[spice_agent]] +. Spice agent ++ +Spice protocol defines a set of messages for bidirectional communication +channel between Spice client and spice client agent on the remote server. Spice +provides a communication channel only, the actual transferred data content is +opaque to the protocol. This channel can be used for various purposes, for +example, client-guest clipboard sharing, authentication and display +configuration. ++ +Spice client receives notifications of remote site agent connection as part of +the RED_MAIN_INIT message or by a specific server RED_MAIN_AGENT_CONNECTED. +Remote agent disconnection notification is delivered by +RED_MAIN_AGENT_DISCONNECTED message. A bidirectional tokens mechanism is used +in order to prevent blocking of the main channel with agent messages (e.g., in +case the agent stops consuming the data). Each side is not allowed to send more +messages than the tokens allocated to it by the other side. The number of +tokens that are allocated for the client is initialized from RED_MAIN_INIT +message, and farther allocation of tokens is done using RED_MAIN_AGENT_TOKEN. +Server tokens initial count is delivered in REDC_MAIN_AGENT_START message. This +message must be the first agent related message that the client sends to the +server. Farther tokens allocation for the server is done using +REDC_MAIN_AGENT_TOKEN. Actual data packets are delivered using +RED_MAIN_AGENT_DATA and REDC_MAIN_AGENT_DATA. ++ +.. Although agent messages are opaque for the protocol, agent data stream is +defined by Spice protocol in order to delineate messages. Still, the +client-server communication is independent from the agent channel, e.g., agent +protocol conflicts don't affect the rest of the channels. Agent stream is +defined as a run of messages having the following format: ++ +[cols="2*"] +|=== +|UINT32 protocol +|unique protocol of this message. The protocol id must be registered in order +to prevent conflicts. + +|UINT32 type +|protocol dependent message type. + +|UINT64 opaque +|protocol dependent opaque data. + +|UINT32 size +|size of data in bytes. + +|UINT8 data[0] +|data of this message. +|=== ++ +Client and server must continue processing unknown protocols messages or +messages having unknown type (i.e., receive and dump). ++ +.. RED_MAIN_AGENT_CONNECTED, VOID +.. RED_MAIN_AGENT_DISCONNECTED, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|disconnect error code RED_ERROR_? +|=== ++ +.. RED_AGENT_MAX_DATA_SIZE = 2048 +.. RED_MAIN_AGENT_DATA, UINT8[] ++ +Agent packet is the entire message body (i.e. RedDataHeader.size). The maximum +packet size is RED_AGENT_MAX_DATA_SIZE. ++ +.. RED_MAIN_AGENT_TOKEN, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|allocated tokens count for the client +|=== ++ +.. REDC_MAIN_AGENT_START, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|allocated tokens count for the server +|=== ++ +.. REDC_MAIN_AGENT_DATA, UINT8[] ++ +Agent packet is the entire message body (i.e. RedDataHeader.size). The maximum +packet size is RED_AGENT_MAX_DATA_SIZE. ++ +.. REDC_MAIN_AGENT_TOKEN, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|allocated tokens count for the server +|=== + +== Inputs channel definition + +Spice Inputs channel controls the server mouse and the keyboard. + +. Client messages ++ +[source,c] +---- +REDC_INPUTS_KEY_DOWN = 101 +REDC_INPUTS_KEY_UP = 102 +REDC_INPUTS_KEY_MODIFAIERS = 103 + +REDC_INPUTS_MOUSE_MOTION = 111 +REDC_INPUTS_MOUSE_POSITION = 112 +REDC_INPUTS_MOUSE_PRESS = 113 +REDC_INPUTS_MOUSE_RELEASE = 114 +---- ++ +. Server Messages ++ +[source,c] +---- +RED_INPUTS_INIT = 101 +RED_INPUTS_KEY_MODIFAIERS = 102 + +RED_INPUTS_MOUSE_MOTION_ACK = 111 +---- ++ +. Keyboard messages ++ +Spice supports sending keyboard key events and keyboard leds synchronization. +The client sends key event using REDC_INPUTS_KEY_DOWN and REDC_INPUTS_KEY_UP +messages. Key value is expressed using PC AT scan code (see +<>). Keyboard leds synchronization is done by sending +RED_INPUTS_KEY_MODIFAIERS message by the server or by sending +REDC_INPUTS_KEY_MODIFAIERS by the client, these messages contain keyboard leds +state. Keyboard modifiers is also sent by the server using RED_INPUTS_INIT, +this message must be sent as the first server message and the server mustn't +send it at any other point. ++ +.. Keyboard led bits ++ +[source,c] +---- +RED_SCROLL_LOCK_MODIFIER = 1 +RED_NUM_LOCK_MODIFIER = 2 +RED_CAPS_LOCK_MODIFIER = 4 +---- ++ +.. RED_INPUTS_INIT, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|any combination of keyboard led bits. If bit is set then the led is on. +|=== ++ +.. RED_INPUTS_KEY_MODIFAIERS, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|any combination of keyboard led bits. If bit is set then the led is on. +|=== ++ +.. REDC_INPUTS_KEY_MODIFAIERS, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|any combination of keyboard led bits. If bit is set then the led is on. +|=== ++ +[[key_code]] +.. KeyCode ++ +[cols="2*"] +|=== +|UINT8[4] +|the value of key code is a PC AT scan code. The code is composed by up to four +bytes for supporting extended codes. A code is terminated by a zero byte. +|=== ++ +.. REDC_INPUTS_KEY_DOWN, KeyCode ++ +[cols="2*"] +|=== +|KeyCode +|client sends this message to notify of key press event. +|=== ++ +.. REDC_INPUTS_KEY_UP, KeyCode ++ +KeyCode – client sends this message to notify of key release event. ++ +. Mouse messages ++ +spice support two modes of mouse operation: client mouse and server mouse (for +more information see <>). in server mouse mode the +client sends mouse motion message (i.e., redc_inputs_mouse_motion), and in +client mouse mode it sends position message (i.e., redc_inputs_mouse_position). +position message holds the position of the client mouse on the display and the +id of the display channel, which is derived from redlinkmess.channel_id. in +order to prevent flood of mouse motion/position events, the server sends +red_inputs_mouse_motion_ack message on every red_motion_ack_bunch messages it +receive. this mechanism allows the client to keep track on the server's +messages consumption rate and to change the event pushing policy according to +it. mouse button events are sent to the server using redc_inputs_mouse_press +and redc_inputs_mouse_release messages. ++ +.. Red Button ID ++ +[source,c] +---- +REDC_MOUSE_LBUTTON = 1, left button +REDC_MOUSE_MBUTTON = 2, middle button +REDC_MOUSE_RBUTTON = 3, right button +REDC_MOUSE_UBUTTON = 4, scroll up button +REDC_MOUSE_DBUTTON = 5, scroll down button +---- ++ +.. Buttons masks ++ +[source,c] +---- +REDC_LBUTTON_MASK = 1, left button mask +REDC_MBUTTON_MASK = 2, middle button mask +REDC_RBUTTON_MASK = 4, right button mask +---- ++ +.. RED_MOTION_ACK_BUNCH ++ +[source,c] +---- +RED_MOTION_ACK_BUNCH = 4 +---- ++ +.. REDC_INPUTS_MOUSE_MOTION, RedcMouseMotion ++ +[cols="2*"] +|=== +|INT32 dx +|number of pixels the mouse had moved on x axis + +|INT32 dy +|number of pixels the mouse had moved on y axis + +|UINT32 buttons_state +|any combination of buttons mask. Set bit describe pressed button and clear bit +describe unpressed button. + +|=== ++ +.. REDC_INPUTS_MOUSE_POSITION, RedcMousePosition ++ +[cols="2*"] +|=== +|UINT32 x +|position on x axis + +|UINT32 y +|position on y axis + +|UINT32 buttons_state +|any combination of buttons mask. Set bit describe pressed button and clear bit +describe unpressed button. + +|UINT8 display_id +|id of the display that client mouse is on. +|=== ++ +.. REDC_INPUTS_MOUSE_PRESS, RedcMousePress ++ +[cols="2*"] +|=== +|UINT32 button_id +|one of REDC_MOUSE_?BUTTON + +|UINT32 buttons_state +|any combination of buttons masks. Set bit describes pressed button, and clear +bit describes unpressed button. +|=== ++ +.. REDC_INPUTS_MOUSE_RELEASE, RedcMouseRelease ++ +[cols="2*"] +|=== +|UINT32 button_id +|one of REDC_MOUSE_?BUTTON + +|UINT32 buttons_state +|any combination of buttons mask. Set bit describes pressed button and clear +bit describes unpressed button. +|=== + +== Display channel definition + +Spice protocol defines a set of messages for supporting rendering of the remote +display area on the client display. The protocol supports rendering of graphics +primitives (e.g., lines, images) and video streams. The protocol also supports +caching of images and color palettes on the client side. Spice display channel +supports several images compression methods for reducing network traffic. + +. Server messages ++ +[source,c] +---- +RED_DISPLAY_MODE = 101 +RED_DISPLAY_MARK = 102 +RED_DISPLAY_RESET = 103 +RED_DISPLAY_COPY_BITS = 104 + +RED_DISPLAY_INVAL_LIST = 105 +RED_DISPLAY_INVAL_ALL_IMAGES = 106 +RED_DISPLAY_INVAL_PALETTE = 107 +RED_DISPLAY_INVAL_ALL_PALETTES = 108 + +RED_DISPLAY_STREAM_CREATE = 122 +RED_DISPLAY_STREAM_DATA = 123 +RED_DISPLAY_STREAM_CLIP = 124 +RED_DISPLAY_STREAM_DESTROY = 125 +RED_DISPLAY_STREAM_DESTROY_ALL = 126 + +RED_DISPLAY_DRAW_FILL = 302 +RED_DISPLAY_DRAW_OPAQUE = 303 +RED_DISPLAY_DRAW_COPY = 304 +RED_DISPLAY_DRAW_BLEND = 305 +RED_DISPLAY_DRAW_BLACKNESS = 306 +RED_DISPLAY_DRAW_WHITENESS = 307 +RED_DISPLAY_DRAW_INVERS = 308 +RED_DISPLAY_DRAW_ROP3 = 309 +RED_DISPLAY_DRAW_STROKE = 310 +RED_DISPLAY_DRAW_TEXT = 311 +RED_DISPLAY_DRAW_TRANSPARENT = 312 +RED_DISPLAY_DRAW_ALPHA_BLEND = 313 +---- ++ +. Client messages ++ +[source,c] +---- +REDC_DISPLAY_INIT = 101 +---- ++ +. Operation flow ++ +Spice server sends to the client a mode message using RED_DISPLAY_MODE for +specifying the current draw area size and format. In response the client +creates a draw area for rendering all the followed rendering commands sent by +the server. The client will expose the new remote display area content (i.e., +after mode command) only after it receives a mark command (i.e., +RED_DISPLAY_MARK) from the server. The server can send a reset command using +RED_DISPLAY_RESET to instruct the client to drop its draw area and palette +cache. Sending mode message is allowed only while no active draw area exists +on the client side. Sending reset message is allowed only while active draw +area exists on client side. Sending mark message is allowed only once, between +mode and reset messages. Draw commands, copy bits command and stream commands +are allowed only if the client have an active display area (i.e., between +RED_DISPLAY_MODE to RED_DISPLAY_RESET). ++ +On channel connection, the client optionally sends an init message, using +REDC_DISPLAY_INIT, in order to enable image caching and global dictionary +compression. The message includes the cache id and its size and the size of the +dictionary compression window. These sizes and id are determined by the client. +It is disallowed to send more then one init message. ++ +Color pallets cache are manged by the server. +Items cache insertion commands are sent as part of the rendering commands. +Cache items removal are sent explicitly using RED_DISPLAY_INVAL_LIST or +RED_DISPLAY_INVAL_LIST server messages. Resetting client caches is done by +sending RED_DISPLAY_INVAL_ALL_IMAGES or RED_DISPLAY_INVAL_ALL_PALETTES server +messages. ++ +. Draw area control ++ +.. RED_DISPLAY_MODE, RedMode ++ +[cols="2*"] +|=== +|UINT32 width +|width of the display area + +|UINT32 height +|height of the display area + +|UINT32 depth +|color depth of the display area. Valid values are 16bpp or 32bpp. +|=== ++ +.. RED_DISPLAY_MARK, VOID ++ +Mark the beginning of the display area visibility ++ +.. RED_DISPLAY_RESET, VOID ++ +Drop current display area of the channel and reset palette cache ++ +. Raster operation descriptor ++ +The following defines a set of flags for describing raster operations that can +be applied on a source image, source brush, destination and the result during a +rendering operation. Combination of those flags defines the necessary steps +that are needed to be preformed during a rendering operation. In the the +following definitions of rendering commands this combination is referred to by +'rop_descriptor'. ++ +[source,c] +---- +ROPD_INVERS_SRC = 1 +---- ++ +Source Image need to be inverted before rendering ++ +[source,c] +---- +ROPD_INVERS_BRUSH = 2 +---- ++ +Brush need to be inverted before rendering ++ +[source,c] +---- +ROPD_INVERS_DEST = 4 +---- ++ +Destination area need to be inverted before rendering ++ +[source,c] +---- +ROPD_OP_PUT = 8 +---- ++ +Copy operation should be used. ++ +[source,c] +---- +ROPD_OP_OR = 16 +---- ++ +OR operation should be used. ++ +[source,c] +---- +ROPD_OP_AND = 32 +---- ++ +AND operation should be used. ++ +[source,c] +---- +ROPD_OP_XOR = 64 +---- ++ +XOR operation should be used. ++ +[source,c] +---- +ROPD_OP_BLACKNESS = 128 +---- ++ +Destination pixel should be replaced by black ++ +[source,c] +---- +ROPD_OP_WHITENESS = 256 +---- ++ +Destination pixel should be replaced by white ++ +[source,c] +---- +ROPD_OP_INVERS = 512 +---- ++ +Destination pixel should be inverted ++ +[source,c] +---- +ROPD_INVERS_RES = 1024 +---- ++ +Result of the operation needs to be inverted ++ +OP_PUT, OP_OR, OP_AND, OP_XOR, OP_BLACKNESS, OP_WHITENESS, and OP_INVERS are +mutually exclusive ++ +OP_BLACKNESS, OP_WHITENESS, and OP_INVERS are exclusive ++ +. Raw raster image ++ +The following section describes Spice raw raster image (Pixmap). Pixmap is one +of several ways to transfer images in Spice protocol (for more information see +<>). ++ +.. Pixmap format types ++ +[source,c] +---- +PIXMAP_FORMAT_1BIT_LE = 1 +---- ++ +1 bit per pixel and bits order is little endian. Each pixel value is an index +in a color table. The color table size is 2. ++ +[source,c] +---- +PIXMAP_FORMAT_1BIT_BE = 2 +---- ++ +1 bit per pixel and bits order is big endian. Each pixel value is index in a +color table. The color table size is 2. ++ +[source,c] +---- +PIXMAP_FORMAT_4BIT_LE = 3 +---- ++ +4 bits per pixel and nibble order inside a byte is little endian. Each pixel +value is an index in a color table. The color table size is 16. ++ +[source,c] +---- +PIXMAP_FORMAT_4BIT_BE = 4 +---- ++ +4 bits per pixel and nibble order inside a byte is big endian. Each pixel value +is an index in a color table. The color table size is 16. ++ +[source,c] +---- +PIXMAP_FORMAT_8BIT = 5 +---- ++ +8 bits per pixel. Each pixel value is an index in a color table. The color +table size is 256. ++ +[source,c] +---- +PIXMAP_FORMAT_16BIT = 6 +---- ++ +pixel format is 16 bits RGB555. ++ +[source,c] +---- +PIXMAP_FORMAT_24BIT = 7 +---- ++ +pixel format is 24 bits RGB888. ++ +[source,c] +---- +PIXMAP_FORMAT_32BIT = 8 +---- ++ +pixel format is 32 bits RGB888. ++ +[source,c] +---- +PIXMAP_FORMAT_RGBA = 9 +---- ++ +pixel format is 32 bits ARGB8888. ++ +.. Palette ++ +[cols="2*"] +|=== +|UINT64 id +|unique id of the palette + +|UINT16 table_size +|number of entries in the color table + +|UINT32[] color_table +|each entry is RGB555 or RGB888 color depending on the current display area +mode. If display area mode color depth is 32, the effective format is RGB888. +If display area mode color depth is 16 the effective format is RGB555. +|=== ++ +.. Pixmap flags ++ +[source,c] +---- +PIXMAP_FLAG_PAL_CACHE_ME = 1 +---- ++ +Instruct the client to add the palette to cache ++ +[source,c] +---- +PIXMAP_FLAG_PAL_FROM_CACHE = 2 +---- ++ +Instruct the client to retrieve palette from cache. ++ +[source,c] +---- +PIXMAP_FLAG_TOP_DOWN = 4 +---- ++ +Pixmap lines are ordered from top to bottom (i.e., line 0 is the highest line). ++ +.. Pixmap ++ +[cols="2*"] +|=== +|UINT8 format +|one of PIXMAP_FORMAT_? + +|UINT8 flags +|combination of PIXMAP_FLAG_? + +|UINT32 width +|width of the pixmap + +|UINT32 height +|height of the pixmap + +|UINT32 stride +|number of bytes to add for moving from the beginning of line n to the +beginning of line n+1 +|=== ++ +[source,c] +---- +union { + ADDRESS palette; /* address of the color palette. Must be zero if no +color table is required for format */ +} +---- ++ +[cols="2*"] +|=== +|UINT64 palette_id +|id of the palette, valid if FLAG_PAL_FROM_CACHE is set + +|ADDRESS data +|address of line 0 of the pixmap. +|=== ++ +. LZ with palette ++ +This section describes a data structure that is combination of a color palette +and a compressed pixmap data. The pixmap is compressed using our implementation +of LZSS algorithm (see next section). Each decoded pixel value is an index in +the color palette. ++ +.. LZPalette Flags ++ +[source,c] +---- +LZPALETTE_FLAG_PAL_CACHE_ME = 1 +---- ++ +Instruct the client to add the palette to the cache ++ +[source,c] +---- +LZPALETTE_FLAG_PAL_FROM_CACHE = 2 +---- ++ +Instruct the client to retrieve palette from the cache. ++ +[source,c] +---- +LZPALETTE_FLAG_TOP_DOWN = 4 +---- ++ +pixmap lines are ordered from top to bottom (i.e. line 0 is the highest line). ++ +.. LZPalette ++ +[cols="2*"] +|=== +|UINT8 flags +|combination of LZPALETTE_FLAG_? + +|UINT32 data_size +|size of compressed data +|=== ++ +[source,c] +---- +union { + ADDRESS palette; /* address of the color palette (see Palette section +in “Raw raster image”). Zero value is disallowed. */ + UINT64 palette_id; /* id of the palette, valid if FLAG_PAL_FROM_CACHE +is set. */ +} +---- ++ +[cols="2*"] +|=== +|UINT8[] data +|compressed pixmap +|=== ++ +[[spice_image]] +. Spice Image ++ +The following section describes Spice image. Spice image is used in various +commands and data structures for representing a raster image. Spice image +supports several compression types in addition to the raw mode: Quic, LZ and +GLZ. Quic is a predictive coding algorithm. It is a generalization of SFALIC +from gray-scale to color images withe addition of RLE encoding. By LZ we refer +to the our implementation of the LZSS algorithm, which was adjusted for images +in different formats. By GLZ we refer to an extension of LZ that allows it to +use a dictionary that is based on a set of images and not just on the image +being compressed. ++ +.. Image types ++ +[source,c] +---- +IMAGE_TYPE_PIXMAP = 0 +IMAGE_TYPE_QUIC = 1 +IMAGE_TYPE_LZ_PLT = 100 +IMAGE_TYPE_LZ_RGB = 101 +IMAGE_TYPE_GLZ_RGB = 102 +IMAGE_TYPE_FROM_CACHE = 103 +---- ++ +.. Image flags ++ +IMAGE_FLAG_CACHE_ME = 1, this flag instruct the client to add the image to +image cache, cache key is ImageDescriptor.id (see below). ++ +.. ImageDescriptor ++ +[cols="2*"] +|=== +|UINT64 id +|unique id of the image + +|UINT8 type +|type of the image. One of IMAGE_TYPE_? + +|UINT8 flags +|any combination of IMAGE_FLAG_? + +|UINT32 width +|width of the image + +|UINT32 height +|height of the image +|=== ++ +.. Image data ++ +Image data follows ImageDescriptor and its content depends on +ImageDescriptor.type: ++ +* In case of PIXMAP – content is Pixmap. +* In case of QUIC – content is Quic compressed image. Data begins with the +size of the compressed data, represented by UINT32, followed by the compressed +data. +* In case of LZ_PLT – content is LZPalette. +* In case of LZ_RGB – content is LZ_RGB – LZ encoding of an RGB image. Data +begins with the size of the compressed data, represented by UINT32, followed +by the compressed data. +* In case of GLZ_RGB – content is GLZ_RGB – GLZ encoding of an RGB image. Data +begins with the size of the compressed data, represented by UINT32, , followed +by the compressed data. +* In case of FROM_CACHE – No image data. The client should use +ImageDescriptor.id to retrieve the relevant image from cache. ++ +. Glyph String ++ +Glyph string defines an array of glyphs for rendering. Glyphs in a string can +be in A1, A4 or A8 format (i.e., 1bpp, 4bpp, or 8bpp alpha mask). Every glyph +contains its rendering position on the destination draw area. ++ +.. RasterGlyph ++ +[cols="2*"] +|=== +|POINT render_pos +|location of the glyph on the draw area + +|POINT glyph_origin +|origin of the glyph. The origin is relative to the upper left corner of the +draw area. Positive value on x axis advances leftward and positive value on y +axis advances upward. + +|UINT16 width +|glyph's width + +|UINT16 height +|glyph's height + +|UINT8[] data +|alpha mask of the glyph. Actual mask data depends on the glyph string's flags. +If the format is A1 then the line stride is ALIGN(width, 8) / 8. If the format +is A4, the line stride is ALIGN(width, 2) / 2. If the format is A8, the line +stride is width. +|=== ++ +.. Glyph String flags ++ +[source,c] +---- +GLYPH_STRING_FLAG_RASTER_A1 = 1 +---- ++ +Glyphs type is 1bpp alpha value (i.e., 0 is transparent 1 is opaque) ++ +[source,c] +---- +GLYPH_STRING_FLAG_RASTER_A4 = 2 +---- ++ +Glyphs type is 4bpp alpha value (i.e., 0 is transparent 16 is opaque) ++ +[source,c] +---- +GLYPH_STRING_FLAG_RASTER_A8 = 4 +---- ++ +Glyphs type is 4bpp alpha value (i.e., 0 is transparent 256 is opaque) ++ +[source,c] +---- +GLYPH_STRING_FLAG_RASTER_TOP_DOWN = 8 +---- ++ +Line 0 is the top line of the mask ++ +.. GlyphString ++ +[cols="2*"] +|=== +|UINT16 length +|number of glyphs + +|UINT16 flags +|combination of GLYPH_STRING_FLAG_? + +|UINT8[] data +|glyphs +|=== ++ +. Data Types ++ +.. RectList ++ +[cols="2*"] +|=== +|UINT32 count +|number of RECT items in rects + +|RECT[] rects +|array of RECT +|=== ++ +.. Path segment flags ++ +[source,c] +---- +PATH_SEGMENT_FLAG_BEGIN = 1 +---- ++ +this segment begins a new path ++ +[source,c] +---- +PATH_SEGMENT_FLAG_END = 2 +---- ++ +this segment ends the current path ++ +[source,c] +---- +PATH_SEGMENT_FLAG_CLOSE = 8 +---- ++ +this segment closes the path and is invalid if PATH_SEGMENT_FLAG_END is not set ++ +[source,c] +---- +PATH_SEGMENT_FLAG_BEZIER = 16 +---- ++ +this segment content is a Bezier curve ++ +.. PathSeg ++ +[cols="2*"] +|=== +|UINT32 flags +|any combination of PATH_SEGMENT_FLAG_? + +|UINT32 count +|number of points in the segment + +|POINTFIX[] points +|segment points +|=== ++ +.. PathSegList ++ +List of PathSeg items. End of the list is reached if the sum of all previous +PathSegs' sizes is equal to list_size. Address of next segment is the address +of PathSeg.points[PathSeg.count] ++ +[cols="2*"] +|=== +|UINT32 list_size +|total size of in bytes of all PathSegs in the list, +|=== ++ +PathSeg seg0 – first path segment. ++ +.. Clip types ++ +[source,c] +---- +CLIP_TYPE_NONE = 0 +---- ++ +no clipping ++ +[source,c] +---- +CLIP_TYPE_RECTS = 1 +---- ++ +data is RectList and union of all rectangles in RectList is the effective clip ++ +[source,c] +---- +CLIP_TYPE_PATH = 2 +---- ++ +data is PathSegList and the figure described by PathSegList is the effective +clip ++ +.. Clip ++ +[cols="2*"] +|=== +|UIN32 type +|one of CLIP_TYPE_? + +|ADDRESS data +|address of clip data. The content depends on +|=== ++ +.. Mask flags ++ +[source,c] +---- +MASK_FLAG_INVERS = 1, the effective mask is the inverse of the mask +---- ++ +.. Mask ++ +[cols="2*"] +|=== +|UINT8 flags | flags of the mask, combination of MASK_FLAG_? + +|POINT position | origin of the mask in bitmap coordinates + +|ADDRESS bitmap | address of the mask's image, the format of the image must be +1bpp. If the bitmap is zero then no masking operation needs to be preformed. +|=== ++ +In all rendering commands, the mask must be big enough to cover the destination +rectangle ++ +.. Brush types ++ +[source,c] +---- +BRUSH_TYPE_NONE = 0 /* the brush is invalid */ +BRUSH_TYPE_SOLID = 1 /* the brush is solid RGB color */ +BRUSH_TYPE_PATTERN = 2 /* the brush is a pattern */ +---- ++ +.. Pattern ++ +[cols="2*"] +|=== +|ADDRESS image +|address of the pattern's Image + +|POINT position +|origin coordinates of the pattern in the image +|=== ++ +.. Brush ++ +[cols="2*"] +|=== +|UINT32 type +|one of BRUSH_TYPE_? +|=== ++ +[source,c] +---- +Union { + UINT32 color; */ RGB color. The format of the color depends on current +draw area mode.*/ + Pattern pattern; +} +---- ++ +.. Image scale mode ++ +The following defines the method for scaling image ++ +[source,c] +---- +IMAGE_SCALE_INTERPOLATE = 0 +---- ++ +The client is allowed to INTERPOLATE pixel color. ++ +[source,c] +---- +IMAGE_SCALE_NEAREST = 1 +---- ++ +The client must use the nearest pixel. ++ +.. LineAtrr flags ++ +[source,c] +---- +LINE_ATTR_FLAG_START_WITH_GAP = 4 +---- ++ +first style segment if gap (i.e., foreground) ++ +[source,c] +---- +LINE_ATTR_FLAG_STYLED = 8 +---- ++ +style member of LineAtrr is valid and contains effective line style for the +rendering operation. ++ +.. LineAtrr join style ++ +[source,c] +---- +LINE_ATTR_JOIN_ROUND = 0 +LINE_ATTR_JOIN_BEVEL = 1 +LINE_ATTR_JOIN_MITER = 2 +---- ++ +.. LineAtrr cap style ++ +[source,c] +---- +LINE_ATTR_CAP_ROUND = 0 +LINE_ATTR_CAP_SQUARE = 1 +LINE_ATTR_CAP_BUTT = 2 +---- ++ +.. LineAttr ++ +[cols="2*"] +|=== +|UINT8 flags +|combination of LINE_ATTR_? + +|UINT8 join_style +|one of LINE_ATTR_JOIN_? + +|UINT8 cap_style +|one of LINE_ATTR_CAP_? + +|UINT8 style_num_segments +|number of style segments in line style + +|FIXED28_4 width +|width of the line in pixels + +|FIXED28_4 miter_limit +|miter limit in pixels + +| ADDRESS style +|address of line style line style is array of FIXED28_4. The array defines +segments that each represents length of foreground or background pixels in the +style. If FLAG_START_WITH_GAP is defined then the first segment in the style is +background, otherwise it is foreground. Renderer uses this array of segments +repeatedly during rendering operation. +|=== ++ +. Rendering command ++ +.. RedDrawBase ++ +Common field to all rendering command ++ +[cols="2*"] +|=== +|RECT bounding_box +|the affected area on the display area + +|Clip clip +|the effective clip to set before rendering a command +|=== ++ +.. RED_DISPLAY_COPY_BITS ++ +[source,c] +---- +RedDrawBase +POINT source_position +---- ++ +Copy bits from the draw area to bounding_box on the draw area. Source area left +top corner is source_position and its height and width is equal to bounding_box +height and width. Source and destination rectangles can overlap. ++ +.. RED_DISPLAY_DRAW_FILL ++ +[source,c] +---- +RedDrawBase +Brush brush +UINT16 rop_descriptor +Mask mask +---- ++ +Fill bounding_box using brush as the fill pattern and rop_descriptor +instructions. If the mask is valid, it will limit the modified area (i.e., only +pixels on the destination area that their corresponding bits are set will be +affected). ++ +.. RED_DISPLAY_DRAW_OPAQUE ++ +[source,c] +---- +RedDrawBase +ADDRESS source_image +RECT source_area +Brush brush +UINT16 rop_descriptor +UINT8 scale_mode +Mask mask +---- ++ +Combine pixels from source_area in source_image with the brush's pattern using +rop_descriptor instructions. The result image will be rendered into +bounding_box. In case scaling of source image is required it will be performed +according to scale_mode and before the combination with brush pixels. If mask +is valid it will limit the modified area. ++ +.. RED_DISPLAY_DRAW_COPY ++ +[source,c] +---- +RedDrawBase +ADDRESS source_image +RECT source_area +UINT16 rop_descriptor +UINT8 scale_mode +Mask mask +---- ++ +Copy pixels from source_area in source_image to bounding_box using +rop_descriptor instructions. In case scaling of source image is required it +will be performed according to scale_mode and before the copying to the draw +area. If mask is valid it will limit the modified area. ++ +.. RED_DISPLAY_DRAW_BLEND ++ +[source,c] +---- +RedDrawBase +ADDRESS source_image +RECT source_area +UINT16 rop_descriptor +UINT8 scale_mode +Mask mask +---- ++ +Mixing pixels from source_area in source_image with bounding_box pixels on the +draw area using rop_descriptor instructions. In case scaling of source image is +required it will be performed according to scale_mode and before the mixing +with the draw area. If mask is valid it will limit the modified area. ++ +.. RED_DISPLAY_DRAW_BLACKNESS ++ +[source,c] +---- +RedDrawBase +Mask mask +---- ++ +Fill bounding_box with black pixels. If mask is valid it will limit the +modified area. ++ +.. RED_DISPLAY_DRAW_WHITENESS ++ +[source,c] +---- +RedDrawBase +Mask mask +---- ++ +Fill bounding_box with white pixels. If mask is valid it will limit the +modified area. ++ +.. RED_DISPLAY_DRAW_INVERS ++ +[source,c] +---- +RedDrawBase +Mask mask +---- ++ +Inverse all pixels in bounding_box. If mask is valid it will limit the modified +area. ++ +.. RED_DISPLAY_DRAW_ROP3 ++ +[source,c] +---- +RedDrawBase +ADDRESS source_image +RECT source_area +Brush brush +UINT8 rop3 +UINT8 scale_mode +Mask mask +---- ++ +Mix pixels from source_area in source_image, bounding_box pixels in the draw +area, and the brush pattern. The method for mixing three pixels into the +destination area (i.e., bounding_box) is defined by rop3 (i.e., ternary raster +operations). In case scaling of source image is required it will be performed +according to scale_mode and before the mixing. If mask is valid it will limit +the modified area. ++ +.. RED_DISPLAY_DRAW_TRANSPARENT ++ +[source,c] +---- +RedDrawBase +ADDRESS source_image +RECT source_area +UINT32 transparent_color +UINT32 transparent _true_color +---- ++ +Copy pixels from source_area on source_image to bounding_box on the draw area. +In case scaling of source image is required it will use IMAGE_SCALE_NEAREST. +Pixels with value equal to the transparent color will be masked out. +Transparent color is provided in two forms: true color (i.e., RGB888) and the +color in the original format (i.e., before compression) . ++ +.. RED_DISPLAY_DRAW_ALPHA_BLEND ++ +[source,c] +---- +RedDrawBase +UINT8 alpha +ADDRESS source_image +RECT source_area +---- ++ +Alpha blend source_area of source_image on bounding_box of draw area using +alpha value or alternatively per pixel alpha value. In case scaling of source +image is required, it will use IMAGE_SCALE_INTERPOLATE mode. Alpha value is +defined as 0 is full transparency and 255 is full opacity. Format of source +image can be pre-multiplied ARGB8888 for per pixel alpha value. ++ +New RGB color is defined as: ++ +[source,c] +---- +color' = (source_color * alpha) / 255 +alpha' = (source_alpha * alpha) / 255 +new_color = color' + ((255 - alpha' ) * destination_color) / 255 +---- ++ +.. RED_DISPLAY_DRAW_STROKE ++ +[source,c] +---- +RedDrawBase +ADDRESS path – address of the PathSegList that defines the path to render +LineAttr attr +Bush brush +UINT16 fore_mode - foreground rop_descriptor +UINT16 back_mode – background rop_descriptor +---- ++ +Render path using brush line attribute and rop descriptors. If the line is +styled (i.e., LINE_ATTR_FLAG_STYLED is set in attr.falgs) then background +(i.e., inverse of the style) is drawn using back_mode and the foreground is +drawn using fore_mode. If the line is not styled, the entire path is rendered +using fore_mode. ++ +.. RED_DISPLAY_DRAW_TEXT ++ +[source,c] +---- +RedDrawBase +ADDRESS string – address of GlyphString +RECT back_area +Brush fore_brush +Brush back_brush +UINT16 fore_mode +UINT16 back_mode +---- ++ +Render string of glyph on the display area using brush fore_brush and the +rop_descriptor fore_mode. If back_area is not empty the renderer fill back_area +on the display area prior to rendering the glyph string. back_area is filled +using back_brush and the rop_descriptor back_mode. ++ +. Video streaming commands ++ +Spice supports the creation of video streams by the server for rendering video +content on the client display area. Unlike other rendering commands, the +stream data can be compressed using lossy or video specific compression +algorithms. It is not required to render video frames as they arrive and it is +also allowed to drop video frames. This enables using video frames buffering +for having smoother playback and audio synchronization. Audio synchronization +is achieved by using time stamp that is attached to audio and video streams. +By using video streaming the network traffic can be dramatically reduced. When +the stream is created, the server sends create message using +RED_DISPLAY_STREAM_CREATE. After the server creates a stream he can send data +using RED_DISPLAY_STREAM_DATA, or set new stream clipping by sending clip +message using RED_DISPLAY_STREAM_CLIP. Once the server no longer needs the +stream, he can send destroy command using RED_DISPLAY_STREAM_DESTROY. The +server can also destroy all active streams by sending destroy all message using +RED_DISPLAY_STREAM_DESTROY_ALL. ++ +.. Stream flags ++ +[source,c] +---- +STREAM_FLAG_TOP_DOWN = 1 /* stream frame line order is from top to bottom */ +---- ++ +.. Codec types ++ +[source,c] +---- +STREAM_CODEC_TYPE_MJPEG = 1 /* this stream uses motion JPEG codec */ +---- ++ +.. RED_DISPLAY_STREAM_CREATE, RedStreamCreate ++ +[cols="2*"] +|=== +|UINT32 id +|id of the new stream. It is the server's responsibility to manage stream ids + +|UINT32 flags +|flags of the stream, any combination of STREAM_FLAG_? + +|UINT32 codec_type +|type of codec used for this stream, one of STREAM_CODEC_TYPE_? + +|UINT64 reserved +|must be zero + +|UINT32 stream_width +|width of the source frame. + +|UINT32 stream_height +|height of the source frame + +|UINT32 source_width +|actual frame width to use, must be less or equal to stream_width. + +|UINT32 source_height +|actual frame height to use, must be less or equal to stream_height. + +|RECT destination +|area to render into on the client display area + +|Clip clip +|clipping of the stream +|=== ++ +.. RED_DISPLAY_STREAM_DATA, RedStreamData ++ +[cols="2*"] +|=== +|UINT32 id +|stream id (i.e., RedStreamCreate.id) + +|UINT32 multimedia_time +|frame time stamp + +|UINT32 data_size +|stream data size to consume in bytes + +|UINT32 pad_size +|additional data padding in bytes + +|UINT8[] data +|stream data depending on RedStreamCreate.codec_type. Size of data is ( +data_size + pad_size) +|=== ++ +.. RED_DISPLAY_STREAM_CLIP, RedStreamClip ++ +[cols="2*"] +|=== +|UINT32 id +|stream id (i.e., RedStreamCreate.id) +|=== ++ +Clip clip – new clipping of the stream ++ +.. RED_DISPLAY_STREAM_DESTROY, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|id of stream to destroy +|=== ++ +.. RED_DISPLAY_STREAM_DESTROY_ALL, VOID ++ +Destroy all active streams ++ +. Cache control ++ +.. Resource type ++ +[source,c] +---- +RED_RES_TYPE_IMAGE = 1 +---- ++ +.. RedResourceID ++ +[cols="2*"] +|=== +|UINT8 type +|type of the resource, one of RED_RES_TYPE_? + +|UINT64 id +|id of the resource +|=== ++ +.. RedResourceList ++ +[cols="2*"] +|=== +|UINT16 count +|number of items in resources + +|RedResourceID[] resources +|list of resources id +|=== ++ +.. RED_DISPLAY_INVAL_LIST, RedResourceList ++ +[cols="2*"] +|=== +|RedResourceList +|list of resources to remove from cache +|=== ++ +.. RED_DISPLAY_INVAL_ALL_IMAGES, RedWaitForChannels ++ +Remove all images from the image cache. The client must use RedWaitForChannels +(for more info see <>) to synchronize +with other channels before clearing the cache. ++ +.. RED_DISPLAY_INVAL_PALETTE, UINT64 ++ +[cols="2*"] +|=== +|UINT64 id of palette +|client needs to remove palette with that id from the cache +|=== ++ +.. RED_DISPLAY_INVAL_ALL_PALETTES, VOID ++ +Remove all palettes from palette cache + +== Cursor channel definition + +Spice protocol defines a set of messages for controlling cursor shape and +position on the remote display area, cursor position messages are irrelevant +for client mouse mode (see <>). Spice protocol also +defines a set of messages for managing cursor shape cache on the client site. +Client must strictly obey all such instructions. The server sends +RED_CURSOR_INIT to set current pointer state (i.e., shape, position, visibility +etc.) and to clear shape cache. After the server sends init message it can send +any other cursor command except for RED_CURSOR_INIT. The server can send +RED_CURSOR_RESET message - this will disable the cursor and reset the cursor +cache. After this message the only valid message the server can send is +RED_CURSOR_INIT. The relevant remote display area for a cursor channel is the +one of the display channel that has the same channel id (i.e., +RedLinkMess.channel_id). + +. Server messages ++ +[source,c] +---- +RED_CURSOR_INIT = 101 +RED_CURSOR_RESET = 102 +RED_CURSOR_SET = 103 +RED_CURSOR_MOVE = 104 +RED_CURSOR_HIDE = 105 +RED_CURSOR_TRAIL = 106 +RED_CURSOR_INVAL_ONE = 107 +RED_CURSOR_INVAL_ALL = 108 +---- ++ +.. Cursors types ++ +[source,c] +---- +CURSOR_TYPE_ALPHA = 0 +CURSOR_TYPE_MONO = 1 +CURSOR_TYPE_COLOR4 = 2 +CURSOR_TYPE_COLOR8 = 3 +CURSOR_TYPE_COLOR16 = 4 +CURSOR_TYPE_COLOR24 = 5 +CURSOR_TYPE_COLOR32 = 6 +---- ++ +.. CursorHeader ++ +[cols="2*"] +|=== +|UINT64 unique +|unique identifier of the corresponding cursor shape. It is used for storing +and retrieving cursors from the cursor cache. + +|UINT16 type +|type of the shape, one of CURSOR_TYPE_? + +|UINT16 width +|width of the shape + +|UINT16 height +|height of the shape + +|UINT16 hot_spot_x +|position of hot spot on x axis + +|UINT16 hot_spot_y +|position of hot spot on y axis +|=== ++ +.. Cursor flags ++ +[source,c] +---- +CURSOR_FLAGS_NONE = 1 +---- ++ +set when RedCursor (see below) is invalid ++ +[source,c] +---- +CURSOR_CURSOR_FLAGS _CACHE_ME = 2 +---- ++ +set when the client should add this shape to the shapes cache. The client will +use CursorHeader.unique as cache key. ++ +[source,c] +---- +CURSOR_FLAGS_FROM_CACHE = 4 +---- ++ +set when the client should retrieve the cursor shape, using CursorHeader.unique +as key, from the shapes cache. In this case all fields of CursorHeader except +for 'unique' are invalid. ++ +.. RedCursor ++ +[cols="2*"] +|=== +|UINT32 flags +|any valid combination of RED_CURSOR_? + +|CursorHeader header +| + +|UINT8[] data +|actual cursor shape data, the size is determine by width, height and type from +CursorHeader. Next we will describe in detail the shape data format according +to cursor type: + +|ALPHA, alpha shape +|data contains pre-multiplied ARGB8888 pixmap. Line stride is is . + +|MONO, monochrome shape +|data contains two bitmaps with size * . The first bitmap is +AND mask and the second is XOR mask. Line stride is ALIGN(, 8) / 8. +Bits order within every byte is big endian. + +|COLOR4, 4 bits per pixel shape +|First data region is pixmap: the stride of the pixmap is ALIGN(width , 2) / 2; +every nibble is translated to a color usingthe color palette; Nibble order is +big endian. Second data region contain 16 colors palette: each entry is 32 bit +RGB color. Third region is a bitmap mask: line stride is ALIGN(, 8) / +8; bits order within every byte is big endian. + +|COLOR4, 8 bits per pixel shape +|First data region is pixmap: the stride of the pixmap is ; every byte +is translated to color using the color palette. Second data region contain 256 +colors palette: each entry is 32 bit RGB color. Third region is a bitmap mask: +line stride is ALIGN(, 8) / 8; bits order within every byte is big +endian. + +|COLOR16, 16 bits per pixel shape +|First data region is pixmap: the stride of the pixmap is ; every +UINT16 is RGB_555. Second region is a bitmap mask: line stride is +ALIGN(, 8) / 8; bits order within every byte is big endian. + +|COLOR24, 24 bits per pixel shape +|First data region is pixmap: the stride of the pixmap is ; every +UINT8[3] is RGB_888. Second region is a bitmap mask: line stride is +ALIGN(, 8) / 8; bits order within every byte is big endian. + +|COLOR32, 32 bits per pixel shape +|First data region is pixmap: the stride of the pixmap is ,;every +UINT32 is RGB_888. Second region is a bitmap mask: line stride is +ALIGN(, 8) / 8; bits order within every byte is big endian. +|=== ++ +For more deatails on drawing the cursor shape see <> ++ +.. RED_CURSOR_INIT, RedCursorInit ++ +[cols="2*"] +|=== +|POINT16 position +|position of mouse pointer on the relevant display area. Not relevant in +client mode. + +|UINT16 trail_length +|number of cursors in the trail excluding main cursor. + +|UINT16 trail_frequency +|millisecond interval between trail updates. + +|UIN8 visible +|if 1, the cursor is visible. If 0, the cursor is invisible. + +|RedCursor cursor +|current cursor shape +|=== ++ +.. RED_CURSOR_RESET, VOID ++ +.. RED_CURSOR_SET, RedCursorSet ++ +[cols="2*"] +|=== +|POINT16 position +|position of mouse pointer on the relevant display area. not relevant in client +mode. + +|UINT8 visible +|if 1, the cursor is visible. If 0, the cursor is invisible. + +|RedCursor cursor +|current cursor shape +|=== ++ +.. RED_CURSOR_MOVE, POINT16 ++ +[cols="2*"] +|=== +|POINT16 +|new mouse position. Not relevant in client mode. This message also implicitly +sets cursor visibility to 1. +|=== ++ +.. RED_CURSOR_HIDE, VOID ++ +Hide pointer on the relevant display area. ++ +.. RED_CURSOR_TRAIL ++ +[cols="2*"] +|=== +|UINT16 length +|number of cursors in the trail excluding main cursor. + +|UINT16 frequency +|millisecond interval between trail updates +|=== ++ +.. RED_CURSOR_INVAL_ONE, UINT64 ++ +[cols="2*"] +|=== +|UINT64 +|id of cursor shape to remove from the cursor cache +|=== ++ +.. RED_CURSOR_INVAL_ALL, VOLD ++ +Clear cursor cache ++ +[[cursor_shape]] +. Drawing the cursor shape according to the cursor type ++ +This section is relevant only for server mouse mode. Cursor shape positioning +on the display area is done by placing cursor hot spot on the current cursor +position. ++ +.. Alpha - no spacial handling, just bland the shape on the display area. ++ +.. Monochrome ++ +For each cleared bit in the AND mask clear the corresponding bits in the +relevant pixel on the display area +For each set bit in the XOR mask reverse the +corresponding bits in the relevant pixel on the display area ++ +.. Color ++ +If the source color is black and mask bit is set, NOP. +Else, if the source color is white and the mask bit is set, reverse all bits in +the relevant pixel on the display area. +Else, put source color. + +== Playback channel definition + +Spice supports sending audio streams for playback on the client side. An audio +stream is sent by the server in an audio packet using RED_PLAYBACK_DATA +message. The content of the audio packet is controlled by the playback mode +that the server sends using RED_PLAYBACK_MODE message. The server can start and +stop the stream using RED_PLAYBACK_START and RED_PLAYBACK_STOP messages. +Sending audio packet is allowed only between start and stop messages. Sending +start message is allowed only in stop state and after at least one mode message +was sent. Sending a stop message is allowed only during a start state. + +. Server messages ++ +[source,c] +---- +RED_PLAYBACK_DATA = 101 +RED_PLAYBACK_MODE = 102 +RED_PLAYBACK_START = 103 +RED_PLAYBACK_STOP = 104 +---- ++ +. Audio format ++ +[source,c] +---- +RED_PLAYBACK_FMT_S16 = 1 /* each channel sample is a 16 bit +signed integer */ +---- ++ +. Playback data mode ++ +Two types of data mode are available: (1) raw PCM data and (2) compressed data +in CELT 0_5_1 format. ++ +[source,c] +---- +RED_PLAYBACK_DATA_MODE_RAW = 1 +RED_PLAYBACK_DATA_MODE_CELT_0_5_1 = 2 +---- ++ +. Playback channel capabilities ++ +[source,c] +---- +RED_PLAYBACK_CAP_CELT_0_5_1 = 0 +---- ++ +Spice client needs to declare support of CELT_5_1 in channel capabilities in +order to allow the server to send playback packets in CELT_0_5_1 format. ++ +. RED_PLAYBACK_MODE, RedPlaybackMode ++ +[cols="2*"] +|=== +|UINT32 time +|server time stamp + +|UINT32 mode +|one of RED_PLAYBACK_DATA_MODE_? + +|UINT8[] data +|specific data, content depend on mode +|=== ++ +. RED_PLAYBACK_START, RedRecordStart ++ +[cols="2*"] +|=== +|UINT32 channels +|number of audio channels + +|UINT32 format +|one of RED_PLAYBACK_FMT_? + +|UINT32 frequency +|channel samples per second +|=== ++ +. RED_PLAYBACK_DATA, RedPlaybackPacket ++ +[cols="2*"] +|=== +|UINT32 time +|server time stamp + +|UINT8[] data +|playback data , content depend on mode +|=== ++ +. RED_PLAYBACK_STOP, VOID ++ +Stop current audio playback + +== Record Channel definition + +Spice supports transmitting of audio captured streams from the client to the +server. Spice server starts audio capturing using RED_RECORD_START message. +This message instructs the client to start transmitting captured audio . In +response, the client sends time stamp of the stream start using +REDC_RECORD_START_MARK. After the client sends start mark it can start +transmitting audio stream data using REDC_RECORD_DATA. One mode message must be +sent by the client before any other message using REDC_RECORD_MODE. This, in +order to inform the server on what type of data will be transferred. Mode +message can also be transmitted at any other time in order to switch the data +type delivered by REDC_RECORD_DATA. The Server can send RED_RECORD_STOP for +stopping captured audio streaming. Sending a start message is allowed only +while the stream is in stop state. Sending a stop message and data messages is +allowed only while the stream is in start state. Sending mark message is +allowed only between start message and the first data message. + +. Server messages ++ +[source,c] +---- +RED_RECORD_START = 101 +RED_RECORD_STOP = 102 +---- ++ +. Client messages ++ +[source,c] +---- +REDC_RECORD_DATA = 101 +REDC_RECORD_MODE = 102 +REDC_RECORD_START_MARK = 103 +---- ++ +. Audio format ++ +[source,c] +---- +RED_RECORD_FMT_S16 = 1 /* each channel sample is a 16 bit +signed integer */ +---- ++ +. Record data mode ++ +Two types of data mode are available: (1) raw PCM data (2) compressed data in +CELT 0.5.1 format. ++ +[source,c] +---- +RED_RECORD_DATA_MODE_RAW = 1 +RED_RECORD_DATA_MODE_CELT_0_5_1 = 2 +---- ++ +. Record channel capabilities ++ +[source,c] +---- +RED_PLAYBACK_CAP_CELT_0_5_1 = 0 +---- ++ +Spice server needs to declare support of CELT_5_1 in channel capabilities in +order to allow the client to send recorded packets in CELT_0_5_1 format. ++ +. REDC_RECORD_MODE, RedcRecordMode ++ +[cols="2*"] +|=== +|UINT32 time +|client time stamp + +|UINT32 mode +|one of RED_RECORD_DATA_MODE_? + +|UINT8[] data +|specific data, content depend on mode +|=== ++ +. RED_RECORD_START, RedRecordStart ++ +[cols="2*"] +|=== +|UINT32 channel +|number of audio channels + +|UINT32 format +|one of RED_AUDIO_FMT_? + +|UINT32 frequency +|channel samples per second +|=== ++ +. REDC_RECORD_START_MARK, UINT32 ++ +[cols="2*"] +|=== +|UINT32 +|client time stamp of stream start +|=== ++ +. REDC_RECORD_DATA, RedcRecordPacket ++ +[cols="2*"] +|=== +|UINT32 time +|client time stamp + +|UINT8[] data +|recorded data , content depend on mode +|=== ++ +. RED_RECORD_STOP, VOID ++ +Stop current audio capture -- 2.13.2