diff options
Diffstat (limited to 'spice1.proto')
-rw-r--r-- | spice1.proto | 943 |
1 files changed, 943 insertions, 0 deletions
diff --git a/spice1.proto b/spice1.proto new file mode 100644 index 0000000..6adf312 --- /dev/null +++ b/spice1.proto @@ -0,0 +1,943 @@ +/* built in types: + int8, uint8, 16, 32, 64 +*/ + +typedef fixed28_4 int32 @ctype(SPICE_FIXED28_4); + +struct Point { + int32 x; + int32 y; +}; + +struct Point16 { + int16 x; + int16 y; +}; + +struct PointFix { + fixed28_4 x; + fixed28_4 y; +}; + +struct Rect { + int32 top; + int32 left; + int32 bottom; + int32 right; +}; + +enum32 link_err { + OK, + ERROR, + INVALID_MAGIC, + INVALID_DATA, + VERSION_MISMATCH, + NEED_SECURED, + NEED_UNSECURED, + PERMISSION_DENIED, + BAD_CONNECTION_ID, + CHANNEL_NOT_AVAILABLE +}; + +enum32 warn_code { + WARN_GENERAL +} @prefix(SPICE_); + +enum32 info_code { + INFO_GENERAL +} @prefix(SPICE_); + +flags32 migrate_flags { + NEED_FLUSH, + NEED_DATA_TRANSFER +} @prefix(SPICE_MIGRATE_); + +enum32 notify_severity { + INFO, + WARN, + ERROR, +}; + +enum32 notify_visibility { + LOW, + MEDIUM, + HIGH, +}; + +flags32 mouse_mode { + SERVER, + CLIENT, +}; + +enum16 pubkey_type { + INVALID, + RSA, + RSA2, + DSA, + DSA1, + DSA2, + DSA3, + DSA4, + DH, + EC, +}; + +message Empty { +}; + +message Data { + uint8 data[] @end @ctype(uint8_t); +} @nocopy; + +struct ChannelWait { + uint8 channel_type; + uint8 channel_id; + uint64 message_serial; +} @ctype(SpiceWaitForChannel); + +channel BaseChannel { + server: + message { + migrate_flags flags; + } migrate; + + Data migrate_data; + + message { + uint32 generation; + uint32 window; + } set_ack; + + message { + uint32 id; + uint64 timestamp; + uint8 data[] @ctype(uint8_t) @as_ptr(data_len); + } ping; + + message { + uint8 wait_count; + ChannelWait wait_list[wait_count] @end; + } wait_for_channels; + + message { + uint64 time_stamp; + link_err reason; + } @ctype(SpiceMsgDisconnect) disconnecting; + + message { + uint64 time_stamp; + notify_severity severity; + notify_visibility visibilty; + uint32 what; /* error_code/warn_code/info_code */ + uint32 message_len; + uint8 message[message_len] @end @nomarshal; + uint8 zero @end @ctype(uint8_t) @nomarshal; + } notify; + + client: + message { + uint32 generation; + } ack_sync; + + Empty ack; + + message { + uint32 id; + uint64 timestamp; + } @ctype(SpiceMsgPing) pong; + + Empty migrate_flush_mark; + + Data migrate_data; + + message { + uint64 time_stamp; + link_err reason; + } @ctype(SpiceMsgDisconnect) disconnecting; +}; + +struct ChannelId { + uint8 type; + uint8 id; +}; + +struct DstInfo { + uint16 port; + uint16 sport; + uint32 host_offset @zero; + uint32 host_size; + pubkey_type pub_key_type @minor(1); + uint32 pub_key_offset @minor(1) @zero; + uint32 pub_key_size @minor(1); + uint8 host_data[host_size] @as_ptr @zero_terminated; + uint8 pub_key_data[pub_key_size] @minor(1) @as_ptr @zero_terminated; +} @ctype(SpiceMigrationDstInfo); + +channel MainChannel : BaseChannel { + server: + message { + DstInfo dst_info; + } @ctype(SpiceMsgMainMigrationBegin) migrate_begin = 101; + + Empty migrate_cancel; + + message { + uint32 session_id; + uint32 display_channels_hint; + uint32 supported_mouse_modes; + uint32 current_mouse_mode; + uint32 agent_connected; + uint32 agent_tokens; + uint32 multi_media_time; + uint32 ram_hint; + } init; + + message { + uint32 num_of_channels; + ChannelId channels[num_of_channels] @end; + } @ctype(SpiceMsgChannels) channels_list; + + message { + mouse_mode supported_modes; + mouse_mode current_mode @unique_flag; + } mouse_mode; + + message { + uint32 time; + } @ctype(SpiceMsgMainMultiMediaTime) multi_media_time; + + Empty agent_connected; + + message { + link_err error_code; + } @ctype(SpiceMsgMainAgentDisconnect) agent_disconnected; + + Data agent_data; + + message { + uint32 num_tokens; + } @ctype(SpiceMsgMainAgentTokens) agent_token; + + message { + uint16 port; + uint16 sport; + uint32 host_offset @zero; + uint32 host_size; + uint32 cert_subject_offset @zero; + uint32 cert_subject_size; + uint8 host_data[host_size] @as_ptr @zero_terminated; + uint8 cert_subject_data[cert_subject_size] @as_ptr @zero_terminated; + } @ctype(SpiceMsgMainMigrationSwitchHost) migrate_switch_host; + + client: + message { + uint64 cache_size; + } @ctype(SpiceMsgcClientInfo) client_info = 101; + + Empty migrate_connected; + + Empty migrate_connect_error; + + Empty attach_channels; + + message { + mouse_mode mode; + } mouse_mode_request; + + message { + uint32 num_tokens; + } agent_start; + + Data agent_data; + + message { + uint32 num_tokens; + } @ctype(SpiceMsgcMainAgentTokens) agent_token; +}; + +enum32 clip_type { + NONE, + RECTS +}; + +flags32 path_flags { /* TODO: C enum names changes */ + BEGIN = 0, + END = 1, + CLOSE = 3, + BEZIER = 4, +} @prefix(SPICE_PATH_); + +enum32 video_codec_type { + MJPEG = 1, +}; + +flags32 stream_flags { + TOP_DOWN = 0, +}; + +enum32 brush_type { + NONE, + SOLID, + PATTERN, +}; + +flags8 mask_flags { + INVERS, +}; + +enum8 image_type { + BITMAP, + QUIC, + RESERVED, + LZ_PLT = 100, + LZ_RGB, + GLZ_RGB, + FROM_CACHE, +}; + +flags8 image_flags { + CACHE_ME, +}; + +enum8 bitmap_fmt { + INVALID, + 1BIT_LE, + 1BIT_BE, + 4BIT_LE, + 4BIT_BE, + 8BIT /* 8bit indexed mode */, + 16BIT, /* 0555 mode */ + 24BIT /* 3 byte, brg */, + 32BIT /* 4 byte, xrgb in little endian format */, + RGBA /* 4 byte, argb in little endian format */ +}; + +flags8 bitmap_flags { + PAL_CACHE_ME, + PAL_FROM_CACHE, + TOP_DOWN, +}; + +enum8 image_scale_mode { + INTERPOLATE, + NEAREST, +}; + +flags16 ropd { + INVERS_SRC, + INVERS_BRUSH, + INVERS_DEST, + OP_PUT, + OP_OR, + OP_AND, + OP_XOR, + OP_BLACKNESS, + OP_WHITENESS, + OP_INVERS, + INVERS_RES, +}; + +flags8 line_flags { + STYLED = 3, + START_WITH_GAP = 2, +}; + +enum8 line_cap { + ROUND, + SQUARE, + BUTT, +}; + +enum8 line_join { + ROUND, + BEVEL, + MITER, +}; + +flags16 string_flags { + RASTER_A1, + RASTER_A4, + RASTER_A8, + RASTER_TOP_DOWN, +}; + +enum8 resource_type { + INVALID, + PIXMAP +} @prefix(SPICE_RES_TYPE_); + +struct ClipRects { + uint32 num_rects; + Rect rects[num_rects] @end; +}; + +struct PathSegment { + path_flags flags; + uint32 count; + PointFix points[count] @end; +} @ctype(SpicePathSeg); + +struct Path { + uint32 segments_size @bytes_count(num_segments); + PathSegment segments[bytes(segments_size, num_segments)] @ptr_array; +}; + +struct Clip { + clip_type type; + switch (type) { + case RECTS: + ClipRects *rects @outvar(cliprects); + default: + uint64 data @zero; + } u @anon; +}; + +struct DisplayBase { + uint32 surface_id @virtual(0); + Rect box; + Clip clip; +} @ctype(SpiceMsgDisplayBase); + +struct ResourceID { + uint8 type; + uint64 id; +}; + +struct WaitForChannel { + uint8 channel_type; + uint8 channel_id; + uint64 message_serial; +}; + +struct Palette { + uint64 unique; + uint16 num_ents; + uint32 ents[num_ents] @end; +}; + +struct BitmapData { + bitmap_fmt format; + bitmap_flags flags; + uint32 x; + uint32 y; + uint32 stride; + switch (flags) { + case PAL_FROM_CACHE: + uint64 palette_id; + default: + Palette *palette @outvar(bitmap); + } pal @anon; + uint8 *data[image_size(8, stride, y)] @chunk; /* pointer to array, not array of pointers as in C */ +} @ctype(SpiceBitmap); + +struct BinaryData { + uint32 data_size; + uint8 data[data_size] @nomarshal @chunk; +} @ctype(SpiceQUICData); + +struct LZPLTData { + bitmap_flags flags; + uint32 data_size; + switch (flags) { + case PAL_FROM_CACHE: + uint64 palette_id; + default: + Palette *palette @nonnull @outvar(lzplt); + } pal @anon; + uint8 data[data_size] @nomarshal @chunk; +}; + +struct Image { + struct ImageDescriptor { + uint64 id; + image_type type; + image_flags flags; + uint32 width; + uint32 height; + } descriptor; + + switch (descriptor.type) { + case BITMAP: + BitmapData bitmap; + case QUIC: + BinaryData quic; + case LZ_RGB: + case GLZ_RGB: + BinaryData lz_rgb; + case LZ_PLT: + LZPLTData lz_plt; + } u; +}; + +struct Pattern { + Image *pat @nonnull; + Point pos; +}; + +struct Brush { + brush_type type; + switch (type) { + case SOLID: + uint32 color; + case PATTERN: + Pattern pattern; + } u @fixedsize; +}; + +struct QMask { + mask_flags flags; + Point pos; + Image *bitmap; +}; + +struct LineAttr { + line_flags flags; + line_join join_style @zero; + line_cap end_style @zero; + uint8 style_nseg; + fixed28_4 width @zero; + fixed28_4 miter_limit @zero; + fixed28_4 *style[style_nseg]; +}; + +struct RasterGlyphA1 { + Point render_pos; + Point glyph_origin; + uint16 width; + uint16 height; + uint8 data[image_size(1, width, height)] @end; +} @ctype(SpiceRasterGlyph); + +struct RasterGlyphA4 { + Point render_pos; + Point glyph_origin; + uint16 width; + uint16 height; + uint8 data[image_size(4, width, height)] @end; +} @ctype(SpiceRasterGlyph); + +struct RasterGlyphA8 { + Point render_pos; + Point glyph_origin; + uint16 width; + uint16 height; + uint8 data[image_size(8, width, height)] @end; +} @ctype(SpiceRasterGlyph); + +struct String { + uint16 length; + string_flags flags; /* Special: Only one of a1/a4/a8 set */ + switch (flags) { + case RASTER_A1: + RasterGlyphA1 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array; + case RASTER_A4: + RasterGlyphA4 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array; + case RASTER_A8: + RasterGlyphA8 glyphs[length] @ctype(SpiceRasterGlyph) @ptr_array; + } u @anon; +}; + +struct StreamDataHeader { + uint32 id; + uint32 multi_media_time; +}; + +channel DisplayChannel : BaseChannel { + server: + message { + uint32 x_res; + uint32 y_res; + uint32 bits; + } mode = 101; + + Empty mark; + Empty reset; + + message { + DisplayBase base; + Point src_pos; + } copy_bits; + + message { + uint16 count; + ResourceID resources[count] @end; + } @ctype(SpiceResourceList) inval_list; + + message { + uint8 wait_count; + WaitForChannel wait_list[wait_count] @end; + } @ctype(SpiceMsgWaitForChannels) inval_all_pixmaps; + + message { + uint64 id; + } @ctype(SpiceMsgDisplayInvalOne) inval_palette; + + Empty inval_all_palettes; + + message { + uint32 surface_id @virtual(0); + uint32 id; + stream_flags flags; + video_codec_type codec_type; + uint64 stamp; + uint32 stream_width; + uint32 stream_height; + uint32 src_width; + uint32 src_height; + Rect dest; + Clip clip; + } stream_create = 122; + + message { + StreamDataHeader base; + uint32 data_size; + uint32 pad_size @zero; + uint8 data[data_size] @end @nomarshal; + /* Ignore: uint8 padding[pad_size] */ + } stream_data; + + message { + uint32 id; + Clip clip; + } stream_clip; + + message { + uint32 id; + } stream_destroy; + + Empty stream_destroy_all; + + message { + DisplayBase base; + struct Fill { + Brush brush @outvar(brush); + uint16 rop_descriptor; + QMask mask @outvar(mask); + } data; + } draw_fill = 302; + + message { + DisplayBase base; + struct Opaque { + Image *src_bitmap; + Rect src_area; + Brush brush; + ropd rop_descriptor; + image_scale_mode scale_mode; + QMask mask @outvar(mask); + } data; + } draw_opaque; + + message { + DisplayBase base; + struct Copy { + Image *src_bitmap; + Rect src_area; + ropd rop_descriptor; + image_scale_mode scale_mode; + QMask mask @outvar(mask); + } data; + } draw_copy; + + message { + DisplayBase base; + struct Blend { + Image *src_bitmap; + Rect src_area; + ropd rop_descriptor; + image_scale_mode scale_mode; + QMask mask @outvar(mask); + } @ctype(SpiceCopy) data; + } draw_blend; + + message { + DisplayBase base; + struct Blackness { + QMask mask @outvar(mask); + } data; + } draw_blackness; + + message { + DisplayBase base; + struct Whiteness { + QMask mask @outvar(mask); + } data; + } draw_whiteness; + + message { + DisplayBase base; + struct Invers { + QMask mask @outvar(mask); + } data; + } draw_invers; + + message { + DisplayBase base; + struct Rop3 { + Image *src_bitmap; + Rect src_area; + Brush brush; + uint8 rop3; + image_scale_mode scale_mode; + QMask mask @outvar(mask); + } data; + } draw_rop3; + + message { + DisplayBase base; + struct Stroke { + Path *path; + LineAttr attr; + Brush brush; + uint16 fore_mode; + uint16 back_mode; + } data; + } draw_stroke; + + message { + DisplayBase base; + struct Text { + String *str; + Rect back_area; + Brush fore_brush @outvar(fore_brush); + Brush back_brush @outvar(back_brush); + uint16 fore_mode; + uint16 back_mode; + } data; + } draw_text; + + message { + DisplayBase base; + struct Transparent { + Image *src_bitmap; + Rect src_area; + uint32 src_color; + uint32 true_color; + } data; + } draw_transparent; + + message { + DisplayBase base; + struct AlphaBlend { + int8 alpha_flags @virtual(0); + uint8 alpha; + Image *src_bitmap; + Rect src_area; + } data; + } draw_alpha_blend; + + client: + message { + uint8 pixmap_cache_id; + int64 pixmap_cache_size; //in pixels + uint8 glz_dictionary_id; + int32 glz_dictionary_window_size; // in pixels + } init = 101; +}; + +flags32 keyboard_modifier_flags { + SCROLL_LOCK, + NUM_LOCK, + CAPS_LOCK +}; + +enum32 mouse_button { + INVALID, + LEFT, + MIDDLE, + RIGHT, + UP, + DOWN, +}; + +flags32 mouse_button_mask { + LEFT, + MIDDLE, + RIGHT +}; + +channel InputsChannel : BaseChannel { + client: + message { + uint32 code; + } @ctype(SpiceMsgcKeyDown) key_down = 101; + + message { + uint32 code; + } @ctype(SpiceMsgcKeyUp) key_up; + + message { + keyboard_modifier_flags modifiers; + } @ctype(SpiceMsgcKeyModifiers) key_modifiers; + + message { + int32 dx; + int32 dy; + mouse_button_mask buttons_state; + } @ctype(SpiceMsgcMouseMotion) mouse_motion = 111; + + message { + uint32 x; + uint32 y; + mouse_button_mask buttons_state; + uint8 display_id; + } @ctype(SpiceMsgcMousePosition) mouse_position; + + message { + mouse_button button; + mouse_button_mask buttons_state; + } @ctype(SpiceMsgcMousePress) mouse_press; + + message { + mouse_button button; + mouse_button_mask buttons_state; + } @ctype(SpiceMsgcMouseRelease) mouse_release; + + server: + message { + keyboard_modifier_flags keyboard_modifiers; + } init = 101; + + message { + keyboard_modifier_flags modifiers; + } key_modifiers; + + Empty mouse_motion_ack = 111; +}; + +enum16 cursor_type { + ALPHA, + MONO, + COLOR4, + COLOR8, + COLOR16, + COLOR24, + COLOR32, +}; + +flags32 cursor_flags { + NONE, /* Means no cursor */ + CACHE_ME, + FROM_CACHE, +}; + +struct CursorHeader { + uint64 unique; + cursor_type type; + uint16 width; + uint16 height; + uint16 hot_spot_x; + uint16 hot_spot_y; +}; + +struct Cursor { + cursor_flags flags; + CursorHeader header; + uint8 data[] @as_ptr(data_size); +}; + +channel CursorChannel : BaseChannel { + server: + message { + Point16 position; + uint16 trail_length; + uint16 trail_frequency; + uint8 visible; + Cursor cursor; + } init = 101; + + Empty reset; + + message { + Point16 position; + uint8 visible; + Cursor cursor; + } set; + + message { + Point16 position; + } move; + + Empty hide; + + message { + uint16 length; + uint16 frequency; + } trail; + + message { + uint64 id; + } @ctype(SpiceMsgDisplayInvalOne) inval_one; + + Empty inval_all; +}; + +enum32 audio_data_mode { + INVALID, + RAW, + CELT_0_5_1, + OPUS, +}; + +enum32 audio_fmt { + INVALID, + S16, +}; + +channel PlaybackChannel : BaseChannel { + server: + message { + uint32 time; + uint8 data[] @as_ptr(data_size); + } @ctype(SpiceMsgPlaybackPacket) data = 101; + + message { + uint32 time; + audio_data_mode mode; + uint8 data[] @as_ptr(data_size); + } mode; + + message { + uint32 channels; + audio_fmt format; + uint32 frequency; + uint32 time; + } start; + + Empty stop; +}; + +channel RecordChannel : BaseChannel { + server: + message { + uint32 channels; + audio_fmt format; + uint32 frequency; + } start = 101; + + Empty stop; + client: + message { + uint32 time; + uint8 data[] @nomarshal @as_ptr(data_size); + } @ctype(SpiceMsgcRecordPacket) data = 101; + + message { + uint32 time; + audio_data_mode mode; + uint8 data[] @as_ptr(data_size); + } mode; + + message { + uint32 time; + } start_mark; +}; + +protocol Spice { + MainChannel main = 1; + DisplayChannel display; + InputsChannel inputs; + CursorChannel cursor; + PlaybackChannel playback; + RecordChannel record; +}; |