[Spice-commits] 5 commits - common/client_marshallers.h common/Makefile.am common/meson.build common/messages.h python_modules/ptypes.py spice_codegen.py spice.proto

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Mar 18 13:08:52 UTC 2019


 common/Makefile.am          |   22 -
 common/client_marshallers.h |    2 
 common/meson.build          |   27 +-
 common/messages.h           |  493 --------------------------------------------
 python_modules/ptypes.py    |   64 +++++
 spice.proto                 |  192 ++++++++---------
 spice_codegen.py            |  108 +++++++--
 7 files changed, 284 insertions(+), 624 deletions(-)

New commits:
commit bd75d3f93433351456fdea19375b3eb527f2d931
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Thu Feb 21 09:30:54 2019 +0000

    Generate automatically most C message declarations
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Christophe Fergeau <cfergeau at redhat.com>

diff --git a/common/messages.h b/common/messages.h
index 36ee59d..5cda1d1 100644
--- a/common/messages.h
+++ b/common/messages.h
@@ -42,10 +42,6 @@
 
 SPICE_BEGIN_DECLS
 
-typedef struct SpiceMsgData {
-    uint8_t data[0];
-} SpiceMsgData;
-
 typedef struct SpiceMsgCompressedData {
     uint8_t type;
     uint32_t uncompressed_size;
@@ -53,438 +49,8 @@ typedef struct SpiceMsgCompressedData {
     uint8_t *compressed_data;
 } SpiceMsgCompressedData;
 
-typedef struct SpiceMsgEmpty {
-    uint8_t padding;
-} SpiceMsgEmpty;
-
-typedef struct SpiceMsgInputsInit {
-    uint32_t keyboard_modifiers;
-} SpiceMsgInputsInit;
-
-typedef struct SpiceMsgInputsKeyModifiers {
-    uint32_t modifiers;
-} SpiceMsgInputsKeyModifiers;
-
-typedef struct SpiceMsgMainMultiMediaTime {
-    uint32_t time;
-} SpiceMsgMainMultiMediaTime;
-
-typedef struct SpiceMigrationDstInfo {
-    uint16_t port;
-    uint16_t sport;
-    uint32_t host_size;
-    uint8_t *host_data;
-    uint32_t cert_subject_size;
-    uint8_t *cert_subject_data;
-} SpiceMigrationDstInfo;
-
-typedef struct SpiceMsgMainMigrationBegin {
-    SpiceMigrationDstInfo dst_info;
-} SpiceMsgMainMigrationBegin;
-
-typedef struct SpiceMsgMainMigrateBeginSeamless {
-    SpiceMigrationDstInfo dst_info;
-    uint32_t src_mig_version;
-} SpiceMsgMainMigrateBeginSeamless;
-
-typedef struct SpiceMsgcMainMigrateDstDoSeamless {
-    uint32_t src_version;
-} SpiceMsgcMainMigrateDstDoSeamless;
-
-typedef struct SpiceMsgMainMigrationSwitchHost {
-    uint16_t port;
-    uint16_t sport;
-    uint32_t host_size;
-    uint8_t *host_data;
-    uint32_t cert_subject_size;
-    uint8_t *cert_subject_data;
-} SpiceMsgMainMigrationSwitchHost;
-
-
-typedef struct SpiceMsgMigrate {
-    uint32_t flags;
-} SpiceMsgMigrate;
-
-typedef struct SpiceResourceID {
-    uint8_t type;
-    uint64_t id;
-} SpiceResourceID;
-
-typedef struct SpiceResourceList {
-    uint16_t count;
-    SpiceResourceID resources[0];
-} SpiceResourceList;
-
-typedef struct SpiceMsgSetAck {
-    uint32_t generation;
-    uint32_t window;
-} SpiceMsgSetAck;
-
-typedef struct SpiceMsgcAckSync {
-  uint32_t generation;
-} SpiceMsgcAckSync;
-
-typedef struct SpiceWaitForChannel {
-    uint8_t channel_type;
-    uint8_t channel_id;
-    uint64_t message_serial;
-} SpiceWaitForChannel;
-
-typedef struct SpiceMsgWaitForChannels {
-    uint8_t wait_count;
-    SpiceWaitForChannel wait_list[0];
-} SpiceMsgWaitForChannels;
-
-typedef struct SpiceChannelId {
-    uint8_t type;
-    uint8_t id;
-} SpiceChannelId;
-
-typedef struct SpiceMsgMainInit {
-    uint32_t session_id;
-    uint32_t display_channels_hint;
-    uint32_t supported_mouse_modes;
-    uint32_t current_mouse_mode;
-    uint32_t agent_connected;
-    uint32_t agent_tokens;
-    uint32_t multi_media_time;
-    uint32_t ram_hint;
-} SpiceMsgMainInit;
-
-typedef struct SpiceMsgDisconnect {
-    uint64_t time_stamp;
-    uint32_t reason; // SPICE_ERR_?
-} SpiceMsgDisconnect;
-
-typedef struct SpiceMsgNotify {
-    uint64_t time_stamp;
-    uint32_t severity;
-    uint32_t visibilty;
-    uint32_t what;
-    uint32_t message_len;
-    uint8_t message[0];
-} SpiceMsgNotify;
-
-typedef struct SpiceMsgChannels {
-    uint32_t num_of_channels;
-    SpiceChannelId channels[0];
-} SpiceMsgChannels;
-
-typedef struct SpiceMsgMainName {
-    uint32_t name_len;
-    uint8_t name[0];
-} SpiceMsgMainName;
-
-typedef struct SpiceMsgMainUuid {
-    uint8_t uuid[16];
-} SpiceMsgMainUuid;
-
-typedef struct SpiceMsgMainMouseMode {
-    uint32_t supported_modes;
-    uint32_t current_mode;
-} SpiceMsgMainMouseMode;
-
-typedef struct SpiceMsgPing {
-    uint32_t id;
-    uint64_t timestamp;
-    void *data;
-    uint32_t data_len;
-} SpiceMsgPing;
-
-typedef struct SpiceMsgMainAgentDisconnect {
-    uint32_t error_code; // SPICE_ERR_?
-} SpiceMsgMainAgentDisconnect;
-
 #define SPICE_AGENT_MAX_DATA_SIZE 2048
 
-typedef struct SpiceMsgMainAgentTokens {
-    uint32_t num_tokens;
-} SpiceMsgMainAgentTokens, SpiceMsgcMainAgentTokens, SpiceMsgcMainAgentStart;
-
-typedef struct SpiceMsgMainAgentTokens SpiceMsgMainAgentConnectedTokens;
-
-typedef struct SpiceMsgcClientInfo {
-    uint64_t cache_size;
-} SpiceMsgcClientInfo;
-
-typedef struct SpiceMsgcMainMouseModeRequest {
-    uint32_t mode;
-} SpiceMsgcMainMouseModeRequest;
-
-typedef struct SpiceCursor {
-    uint32_t flags;
-    SpiceCursorHeader header;
-    uint32_t data_size;
-    uint8_t *data;
-} SpiceCursor;
-
-typedef struct SpiceMsgDisplayMode {
-    uint32_t x_res;
-    uint32_t y_res;
-    uint32_t bits;
-} SpiceMsgDisplayMode;
-
-typedef struct SpiceMsgSurfaceCreate {
-    uint32_t surface_id;
-    uint32_t width;
-    uint32_t height;
-    uint32_t format;
-    uint32_t flags;
-} SpiceMsgSurfaceCreate;
-
-typedef struct SpiceMsgSurfaceDestroy {
-    uint32_t surface_id;
-} SpiceMsgSurfaceDestroy;
-
-typedef struct SpiceMsgDisplayBase {
-    uint32_t surface_id;
-    SpiceRect box;
-    SpiceClip clip;
-} SpiceMsgDisplayBase;
-
-typedef struct SpiceMsgDisplayDrawFill {
-    SpiceMsgDisplayBase base;
-    SpiceFill data;
-} SpiceMsgDisplayDrawFill;
-
-typedef struct SpiceMsgDisplayDrawOpaque {
-    SpiceMsgDisplayBase base;
-    SpiceOpaque data;
-} SpiceMsgDisplayDrawOpaque;
-
-typedef struct SpiceMsgDisplayDrawCopy {
-    SpiceMsgDisplayBase base;
-    SpiceCopy data;
-} SpiceMsgDisplayDrawCopy;
-
-typedef struct SpiceMsgDisplayDrawTransparent {
-    SpiceMsgDisplayBase base;
-    SpiceTransparent data;
-} SpiceMsgDisplayDrawTransparent;
-
-typedef struct SpiceMsgDisplayDrawAlphaBlend {
-    SpiceMsgDisplayBase base;
-    SpiceAlphaBlend data;
-} SpiceMsgDisplayDrawAlphaBlend;
-
-typedef struct SpiceMsgDisplayDrawComposite {
-    SpiceMsgDisplayBase base;
-    SpiceComposite data;
-} SpiceMsgDisplayDrawComposite;
-
-typedef struct SpiceMsgDisplayCopyBits {
-    SpiceMsgDisplayBase base;
-    SpicePoint src_pos;
-} SpiceMsgDisplayCopyBits;
-
-typedef SpiceMsgDisplayDrawCopy SpiceMsgDisplayDrawBlend;
-
-typedef struct SpiceMsgDisplayDrawRop3 {
-    SpiceMsgDisplayBase base;
-    SpiceRop3 data;
-} SpiceMsgDisplayDrawRop3;
-
-typedef struct SpiceMsgDisplayDrawBlackness {
-    SpiceMsgDisplayBase base;
-    SpiceBlackness data;
-} SpiceMsgDisplayDrawBlackness;
-
-typedef struct SpiceMsgDisplayDrawWhiteness {
-    SpiceMsgDisplayBase base;
-    SpiceWhiteness data;
-} SpiceMsgDisplayDrawWhiteness;
-
-typedef struct SpiceMsgDisplayDrawInvers {
-    SpiceMsgDisplayBase base;
-    SpiceInvers data;
-} SpiceMsgDisplayDrawInvers;
-
-typedef struct SpiceMsgDisplayDrawStroke {
-    SpiceMsgDisplayBase base;
-    SpiceStroke data;
-} SpiceMsgDisplayDrawStroke;
-
-typedef struct SpiceMsgDisplayDrawText {
-    SpiceMsgDisplayBase base;
-    SpiceText data;
-} SpiceMsgDisplayDrawText;
-
-typedef struct SpiceMsgDisplayInvalOne {
-    uint64_t id;
-} SpiceMsgDisplayInvalOne;
-
-typedef struct SpiceMsgDisplayStreamCreate {
-    uint32_t surface_id;
-    uint32_t id; /* Any number from 0 to SPICE_MAX_NUM_STREAMS - 1 */
-    uint32_t flags;
-    uint32_t codec_type;
-    uint64_t stamp;
-    uint32_t stream_width;
-    uint32_t stream_height;
-    uint32_t src_width;
-    uint32_t src_height;
-    SpiceRect dest;
-    SpiceClip clip;
-} SpiceMsgDisplayStreamCreate;
-
-typedef struct SpiceStreamDataHeader {
-    uint32_t id;
-    uint32_t multi_media_time;
-} SpiceStreamDataHeader;
-
-typedef struct SpiceMsgDisplayStreamData {
-    SpiceStreamDataHeader base;
-    uint32_t data_size;
-    uint8_t data[0];
-} SpiceMsgDisplayStreamData;
-
-typedef struct SpiceMsgDisplayStreamDataSized {
-    SpiceStreamDataHeader base;
-    uint32_t width;
-    uint32_t height;
-    SpiceRect dest;
-    uint32_t data_size;
-    uint8_t data[0];
-} SpiceMsgDisplayStreamDataSized;
-
-typedef struct SpiceMsgDisplayStreamClip {
-    uint32_t id;
-    SpiceClip clip;
-} SpiceMsgDisplayStreamClip;
-
-typedef struct SpiceMsgDisplayStreamDestroy {
-    uint32_t id;
-} SpiceMsgDisplayStreamDestroy;
-
-typedef struct SpiceMsgDisplayStreamActivateReport {
-    uint32_t stream_id;
-    uint32_t unique_id;
-    uint32_t max_window_size;
-    uint32_t timeout_ms;
-} SpiceMsgDisplayStreamActivateReport;
-
-typedef struct SpiceMsgcDisplayStreamReport {
-    uint32_t stream_id;
-    uint32_t unique_id;
-    uint32_t start_frame_mm_time;
-    uint32_t end_frame_mm_time;
-    uint32_t num_frames;
-    uint32_t num_drops;
-    int32_t last_frame_delay;
-    uint32_t audio_delay;
-} SpiceMsgcDisplayStreamReport;
-
-typedef struct SpiceMsgcDisplayGlDrawDone {
-} SpiceMsgcDisplayGlDrawDone;
-
-typedef struct SpiceMsgCursorInit {
-    SpicePoint16 position;
-    uint16_t trail_length;
-    uint16_t trail_frequency;
-    uint8_t visible;
-    SpiceCursor cursor;
-} SpiceMsgCursorInit;
-
-typedef struct SpiceMsgCursorSet {
-    SpicePoint16 position;
-    uint8_t visible;
-    SpiceCursor cursor;
-} SpiceMsgCursorSet;
-
-typedef struct SpiceMsgCursorMove {
-    SpicePoint16 position;
-} SpiceMsgCursorMove;
-
-typedef struct SpiceMsgCursorTrail {
-    uint16_t length;
-    uint16_t frequency;
-} SpiceMsgCursorTrail;
-
-typedef struct SpiceMsgcDisplayInit {
-    uint8_t pixmap_cache_id;
-    int64_t pixmap_cache_size; //in pixels
-    uint8_t glz_dictionary_id;
-    int32_t glz_dictionary_window_size;       // in pixels
-} SpiceMsgcDisplayInit;
-
-typedef struct SpiceMsgcKeyDown {
-    uint32_t code;
-} SpiceMsgcKeyDown;
-
-typedef struct SpiceMsgcKeyUp {
-    uint32_t code;
-} SpiceMsgcKeyUp;
-
-typedef struct SpiceMsgcKeyModifiers {
-    uint32_t modifiers;
-} SpiceMsgcKeyModifiers;
-
-typedef struct SpiceMsgcMouseMotion {
-    int32_t dx;
-    int32_t dy;
-    uint32_t buttons_state;
-} SpiceMsgcMouseMotion;
-
-typedef struct SpiceMsgcMousePosition {
-    uint32_t x;
-    uint32_t y;
-    uint32_t buttons_state;
-    uint8_t display_id;
-} SpiceMsgcMousePosition;
-
-typedef struct SpiceMsgcMousePress {
-    int32_t button;
-    int32_t buttons_state;
-} SpiceMsgcMousePress;
-
-typedef struct SpiceMsgcMouseRelease {
-    int32_t button;
-    int32_t buttons_state;
-} SpiceMsgcMouseRelease;
-
-typedef struct SpiceMsgAudioVolume {
-    uint8_t nchannels;
-    uint16_t volume[0];
-} SpiceMsgAudioVolume;
-
-typedef struct SpiceMsgAudioMute {
-    uint8_t mute;
-} SpiceMsgAudioMute;
-
-typedef struct SpiceMsgPlaybackMode {
-    uint32_t time;
-    uint32_t mode; //SPICE_AUDIO_DATA_MODE_?
-    uint8_t *data;
-    uint32_t data_size;
-} SpiceMsgPlaybackMode, SpiceMsgcRecordMode;
-
-typedef struct SpiceMsgPlaybackStart {
-    uint32_t channels;
-    uint32_t format; //SPICE_AUDIO_FMT_?
-    uint32_t frequency;
-    uint32_t time;
-} SpiceMsgPlaybackStart;
-
-typedef struct SpiceMsgPlaybackPacket {
-    uint32_t time;
-    uint8_t *data;
-    uint32_t data_size;
-} SpiceMsgPlaybackPacket, SpiceMsgcRecordPacket;
-
-typedef struct SpiceMsgPlaybackLatency {
-    uint32_t latency_ms;
-} SpiceMsgPlaybackLatency;
-
-typedef struct SpiceMsgRecordStart {
-    uint32_t channels;
-    uint32_t format; //SPICE_AUDIO_FMT_?
-    uint32_t frequency;
-} SpiceMsgRecordStart;
-
-typedef struct SpiceMsgcRecordStartMark {
-    uint32_t time;
-} SpiceMsgcRecordStartMark;
-
 #ifdef USE_SMARTCARD
 typedef struct SpiceMsgSmartcard {
     VSCMsgType type;
@@ -503,63 +69,14 @@ typedef struct SpiceMsgcSmartcard {
 } SpiceMsgcSmartcard;
 #endif
 
-typedef struct SpiceMsgDisplayHead {
-    uint32_t monitor_id;
-    uint32_t surface_id;
-    uint32_t width;
-    uint32_t height;
-    uint32_t x;
-    uint32_t y;
-    uint32_t flags;
-} SpiceHead;
-
-typedef struct SpiceMsgDisplayMonitorsConfig {
-    uint16_t count;
-    uint16_t max_allowed;
-    SpiceHead heads[0];
-} SpiceMsgDisplayMonitorsConfig;
-
-typedef struct SpiceMsgPortInit {
-    uint32_t name_size;
-    uint8_t *name;
-    uint8_t opened;
-} SpiceMsgPortInit;
-
-typedef struct SpiceMsgPortEvent {
-    uint8_t event;
-} SpiceMsgPortEvent;
-
-typedef struct SpiceMsgcPortEvent {
-    uint8_t event;
-} SpiceMsgcPortEvent;
-
-typedef struct SpiceMsgcDisplayPreferredVideoCodecType {
-    uint8_t num_of_codecs;
-    uint8_t codecs[0];
-} SpiceMsgcDisplayPreferredVideoCodecType;
-
-typedef struct SpiceMsgcDisplayPreferredCompression {
-    uint8_t image_compression;
-} SpiceMsgcDisplayPreferredCompression;
-
-typedef struct SpiceMsgDisplayGlScanoutUnix {
-    int drm_dma_buf_fd;
-    uint32_t width;
-    uint32_t height;
-    uint32_t stride;
-    uint32_t drm_fourcc_format;
-    uint32_t flags;
-} SpiceMsgDisplayGlScanoutUnix;
-
-typedef struct SpiceMsgDisplayGlDraw {
-    uint32_t x;
-    uint32_t y;
-    uint32_t w;
-    uint32_t h;
-} SpiceMsgDisplayGlDraw;
-
 #include <common/generated_messages.h>
 
+typedef SpiceMsgMainAgentTokens SpiceMsgcMainAgentTokens;
+typedef SpiceMsgMainAgentTokens SpiceMsgcMainAgentStart;
+typedef SpiceMsgDisplayDrawCopy SpiceMsgDisplayDrawBlend;
+typedef SpiceMsgPlaybackMode SpiceMsgcRecordMode;
+typedef SpiceMsgPlaybackPacket SpiceMsgcRecordPacket;
+
 SPICE_END_DECLS
 
 #endif // H_SPICE_COMMON_MESSAGES
diff --git a/spice.proto b/spice.proto
index 8148b2e..1f9f57b 100644
--- a/spice.proto
+++ b/spice.proto
@@ -106,11 +106,11 @@ flags16 mouse_mode {
 };
 
 message Empty {
-};
+} @declare;
 
 message Data {
     uint8 data[] @end @ctype(uint8_t);
-} @nocopy;
+} @nocopy @declare;
 
 enum8 data_compression_type {
     NONE,
@@ -138,36 +138,36 @@ struct ChannelWait {
     uint8 channel_type;
     uint8 channel_id;
     uint64 message_serial;
-} @ctype(SpiceWaitForChannel);
+} @ctype(SpiceWaitForChannel) @declare;
 
 channel BaseChannel {
  server:
     message {
         migrate_flags flags;
-    } migrate;
+    } @declare migrate;
 
     Data migrate_data;
 
     message {
         uint32 generation;
         uint32 window;
-    } set_ack;
+    } @declare set_ack;
 
     message {
         uint32 id;
         uint64 timestamp;
         uint8 data[] @ctype(uint8_t) @as_ptr(data_len);
-    } ping;
+    } @declare ping;
 
     message {
         uint8 wait_count;
         ChannelWait wait_list[wait_count] @end;
-    } wait_for_channels;
+    } @declare wait_for_channels;
 
     message {
         uint64 time_stamp;
         link_err reason;
-    } @ctype(SpiceMsgDisconnect) disconnecting;
+    } @ctype(SpiceMsgDisconnect) @declare disconnecting;
 
     message {
         uint64 time_stamp;
@@ -176,7 +176,7 @@ channel BaseChannel {
         uint32 what; /* error_code/warn_code/info_code */
         uint32 message_len;
         uint8 message[message_len] @end @nomarshal;
-    } notify;
+    } @declare notify;
 
     Data list; /* the msg body is SpiceSubMessageList */
 
@@ -185,7 +185,7 @@ channel BaseChannel {
  client:
     message {
         uint32 generation;
-    } ack_sync;
+    } @declare ack_sync;
 
     Empty ack;
 
@@ -207,7 +207,7 @@ channel BaseChannel {
 struct ChannelId {
     uint8 type;
     uint8 id;
-};
+} @declare;
 
 struct DstInfo {
     uint16 port;
@@ -216,13 +216,13 @@ struct DstInfo {
     uint8 *host_data[host_size] @zero_terminated @marshall @nonnull;
     uint32 cert_subject_size;
     uint8 *cert_subject_data[cert_subject_size] @zero_terminated @marshall;
-} @ctype(SpiceMigrationDstInfo);
+} @ctype(SpiceMigrationDstInfo) @declare;
 
 channel MainChannel : BaseChannel {
  server:
     message {
         DstInfo dst_info;
-    } @ctype(SpiceMsgMainMigrationBegin) migrate_begin = 101;
+    } @ctype(SpiceMsgMainMigrationBegin) @declare migrate_begin = 101;
 
     Empty migrate_cancel;
 
@@ -235,33 +235,33 @@ channel MainChannel : BaseChannel {
         uint32 agent_tokens;
         uint32 multi_media_time;
         uint32 ram_hint;
-    } init;
+    } @declare init;
 
     message {
         uint32 num_of_channels;
         ChannelId channels[num_of_channels] @end;
-    } @ctype(SpiceMsgChannels) channels_list;
+    } @ctype(SpiceMsgChannels) @declare channels_list;
 
     message {
         mouse_mode supported_modes;
         mouse_mode current_mode @unique_flag;
-    } mouse_mode;
+    } @declare mouse_mode;
 
     message {
         uint32 time;
-    } @ctype(SpiceMsgMainMultiMediaTime) multi_media_time;
+    } @ctype(SpiceMsgMainMultiMediaTime) @declare multi_media_time;
 
     Empty agent_connected;
 
     message {
         link_err error_code;
-    } @ctype(SpiceMsgMainAgentDisconnect) agent_disconnected;
+    } @ctype(SpiceMsgMainAgentDisconnect) @declare agent_disconnected;
 
     Data agent_data;
 
     message {
         uint32 num_tokens;
-    } @ctype(SpiceMsgMainAgentTokens) agent_token;
+    } @ctype(SpiceMsgMainAgentTokens) @declare agent_token;
 
     message {
         uint16 port;
@@ -270,27 +270,27 @@ channel MainChannel : BaseChannel {
         uint8 *host_data[host_size] @zero_terminated @marshall;
         uint32 cert_subject_size;
         uint8 *cert_subject_data[cert_subject_size] @zero_terminated  @marshall;
-    } @ctype(SpiceMsgMainMigrationSwitchHost) migrate_switch_host;
+    } @ctype(SpiceMsgMainMigrationSwitchHost) @declare migrate_switch_host;
 
     Empty migrate_end;
 
     message {
        uint32 name_len;
        uint8 name[name_len] @end;
-    } name;
+    } @declare name;
 
     message {
        uint8 uuid[16];
-    } uuid;
+    } @declare uuid;
 
     message {
         uint32 num_tokens;
-    } agent_connected_tokens;
+    } @declare agent_connected_tokens;
 
     message {
         DstInfo dst_info;
         uint32 src_mig_version;
-    } migrate_begin_seamless;
+    } @declare migrate_begin_seamless;
 
     Empty migrate_dst_seamless_ack;
     Empty migrate_dst_seamless_nack;
@@ -298,7 +298,7 @@ channel MainChannel : BaseChannel {
  client:
     message {
         uint64 cache_size;
-    } @ctype(SpiceMsgcClientInfo) client_info = 101;
+    } @ctype(SpiceMsgcClientInfo) @declare client_info = 101;
 
     Empty migrate_connected;
 
@@ -308,23 +308,23 @@ channel MainChannel : BaseChannel {
 
     message {
         mouse_mode mode;
-    } mouse_mode_request;
+    } @declare mouse_mode_request;
 
     message {
         uint32 num_tokens;
-    } agent_start;
+    } @ctype(SpiceMsgMainAgentTokens) @declare agent_start;
 
     Data agent_data;
 
     message {
         uint32 num_tokens;
-    } @ctype(SpiceMsgcMainAgentTokens) agent_token;
+    } @ctype(SpiceMsgMainAgentTokens) @declare agent_token;
 
     Empty migrate_end;
 
     message {
         uint32 src_version;
-    } migrate_dst_do_seamless;
+    } @declare migrate_dst_do_seamless;
 
     Empty migrate_connected_seamless;
 };
@@ -519,18 +519,18 @@ struct DisplayBase {
     uint32 surface_id;
     Rect box;
     Clip clip;
-} @ctype(SpiceMsgDisplayBase);
+} @ctype(SpiceMsgDisplayBase) @declare;
 
 struct ResourceID {
     uint8 type;  /* resource_type */
     uint64 id;
-};
+} @declare;
 
 struct WaitForChannel {
     uint8 channel_type;
     uint8 channel_id;
     uint64 message_serial;
-};
+} @declare;
 
 struct Palette {
     uint64 unique;
@@ -693,7 +693,7 @@ struct String {
 struct StreamDataHeader {
     stream_id_t id;
     uint32 multi_media_time;
-};
+} @declare;
 
 struct Head {
     uint32 monitor_id;
@@ -703,7 +703,7 @@ struct Head {
     uint32 x;
     uint32 y;
     uint32 flags;
-};
+} @declare;
 
 flags32 gl_scanout_flags {
     Y0TOP
@@ -715,19 +715,19 @@ channel DisplayChannel : BaseChannel {
         uint32 x_res;
         uint32 y_res;
         uint32 bits;
-    } mode = 101;
+    } @declare mode = 101;
 
     Empty mark;
     Empty reset;
     message {
         DisplayBase base;
         Point src_pos;
-    } copy_bits;
+    } @declare copy_bits;
 
     message {
         uint16 count;
         ResourceID resources[count] @end;
-    } @ctype(SpiceResourceList) inval_list;
+    } @ctype(SpiceResourceList) @declare inval_list;
 
     /* This message is used to invalidate the complete image cache
      * on the client.
@@ -739,11 +739,11 @@ channel DisplayChannel : BaseChannel {
     message {
         uint8 wait_count;
         WaitForChannel wait_list[wait_count] @end;
-    } @ctype(SpiceMsgWaitForChannels) inval_all_pixmaps;
+    } @ctype(SpiceMsgWaitForChannels) @declare inval_all_pixmaps;
 
     message {
         uint64 id;
-    } @ctype(SpiceMsgDisplayInvalOne) inval_palette;
+    } @ctype(SpiceMsgDisplayInvalOne) @declare inval_palette;
 
     Empty inval_all_palettes;
 
@@ -759,22 +759,22 @@ channel DisplayChannel : BaseChannel {
         uint32 src_height;
         Rect dest;
         Clip clip;
-    } stream_create = 122;
+    } @declare stream_create = 122;
 
     message {
         StreamDataHeader base;
         uint32 data_size;
         uint8 data[data_size] @end @nomarshal;
-    } stream_data;
+    } @declare stream_data;
 
     message {
         stream_id_t id;
         Clip clip;
-    } stream_clip;
+    } @declare stream_clip;
 
     message {
         stream_id_t id;
-    } stream_destroy;
+    } @declare stream_destroy;
 
     Empty stream_destroy_all;
 
@@ -785,7 +785,7 @@ channel DisplayChannel : BaseChannel {
             ropd rop_descriptor;
             QMask mask @outvar(mask);
         } data;
-    } draw_fill = 302;
+    } @declare draw_fill = 302;
 
     message {
         DisplayBase base;
@@ -797,7 +797,7 @@ channel DisplayChannel : BaseChannel {
             image_scale_mode scale_mode;
             QMask mask @outvar(mask);
         } data;
-    } draw_opaque;
+    } @declare draw_opaque;
 
     message {
         DisplayBase base;
@@ -808,7 +808,7 @@ channel DisplayChannel : BaseChannel {
             image_scale_mode scale_mode;
             QMask mask @outvar(mask);
         } data;
-    } draw_copy;
+    } @declare draw_copy;
 
     message {
         DisplayBase base;
@@ -819,28 +819,28 @@ channel DisplayChannel : BaseChannel {
             image_scale_mode scale_mode;
             QMask mask @outvar(mask);
         } @ctype(SpiceCopy) data;
-    } draw_blend;
+    } @ctype(SpiceMsgDisplayDrawCopy) draw_blend;
 
     message {
         DisplayBase base;
         struct Blackness {
             QMask mask @outvar(mask);
         } data;
-    } draw_blackness;
+    } @declare draw_blackness;
 
     message {
         DisplayBase base;
         struct Whiteness {
             QMask mask @outvar(mask);
         } data;
-    } draw_whiteness;
+    } @declare draw_whiteness;
 
     message {
         DisplayBase base;
         struct Invers {
             QMask mask @outvar(mask);
         } data;
-    } draw_invers;
+    } @declare draw_invers;
 
     message {
         DisplayBase base;
@@ -852,7 +852,7 @@ channel DisplayChannel : BaseChannel {
             image_scale_mode scale_mode;
             QMask mask @outvar(mask);
         } data;
-    } draw_rop3;
+    } @declare draw_rop3;
 
     message {
         DisplayBase base;
@@ -863,7 +863,7 @@ channel DisplayChannel : BaseChannel {
             uint16 fore_mode;
             uint16 back_mode;
         } data;
-    } draw_stroke;
+    } @declare draw_stroke;
 
     message {
         DisplayBase base;
@@ -875,7 +875,7 @@ channel DisplayChannel : BaseChannel {
             uint16 fore_mode;
             uint16 back_mode;
         } data;
-    } draw_text;
+    } @declare draw_text;
 
     message {
         DisplayBase base;
@@ -885,7 +885,7 @@ channel DisplayChannel : BaseChannel {
             uint32 src_color;
             uint32 true_color;
         } data;
-    } draw_transparent;
+    } @declare draw_transparent;
 
     message {
         DisplayBase base;
@@ -895,7 +895,7 @@ channel DisplayChannel : BaseChannel {
             Image *src_bitmap;
             Rect src_area;
         } data;
-    } draw_alpha_blend;
+    } @declare draw_alpha_blend;
 
     message {
         uint32 surface_id;
@@ -903,11 +903,11 @@ channel DisplayChannel : BaseChannel {
         uint32 height;
         surface_fmt format;
         surface_flags flags;
-    } @ctype(SpiceMsgSurfaceCreate) surface_create;
+    } @ctype(SpiceMsgSurfaceCreate) @declare surface_create;
 
     message {
         uint32 surface_id;
-    } @ctype(SpiceMsgSurfaceDestroy) surface_destroy;
+    } @ctype(SpiceMsgSurfaceDestroy) @declare surface_destroy;
 
     message {
         StreamDataHeader base;
@@ -916,13 +916,13 @@ channel DisplayChannel : BaseChannel {
         Rect dest;
         uint32 data_size;
         uint8 data[data_size] @end @nomarshal;
-    } stream_data_sized;
+    } @declare stream_data_sized;
 
     message {
         uint16 count;
         uint16 max_allowed;
         Head heads[count] @end;
-    } monitors_config;
+    } @declare monitors_config;
 
     message {
         DisplayBase base;
@@ -944,14 +944,14 @@ channel DisplayChannel : BaseChannel {
             Point16 src_origin;
             Point16 mask_origin;
         } data;
-    } draw_composite;
+    } @declare draw_composite;
 
     message {
         stream_id_t stream_id;
         uint32 unique_id;
         uint32 max_window_size;
         uint32 timeout_ms;
-    } stream_activate_report;
+    } @declare stream_activate_report;
 
     message {
         unix_fd drm_dma_buf_fd;
@@ -961,14 +961,14 @@ channel DisplayChannel : BaseChannel {
         /* specifies the format of drm_dma_buf_fd defined in drm_fourcc.h */
         uint32 drm_fourcc_format;
         gl_scanout_flags flags;
-    } gl_scanout_unix;
+    } @declare gl_scanout_unix;
 
     message {
         uint32 x;
         uint32 y;
         uint32 w;
         uint32 h;
-    } gl_draw;
+    } @declare gl_draw;
 
  client:
     message {
@@ -976,7 +976,7 @@ channel DisplayChannel : BaseChannel {
         int64 pixmap_cache_size; //in pixels
         uint8 glz_dictionary_id;
         int32 glz_dictionary_window_size;  // in pixels
-    } init = 101;
+    } @declare init = 101;
 
     message {
         stream_id_t stream_id;
@@ -1000,19 +1000,19 @@ channel DisplayChannel : BaseChannel {
         // the latency of the audio playback
         // If there is no audio playback, set it to 0xffffffffu
         uint32 audio_delay;
-    } stream_report;
+    } @declare stream_report;
 
     message {
         image_compression image_compression;
-    } preferred_compression;
+    } @declare preferred_compression;
 
     message {
-    } gl_draw_done;
+    } @declare gl_draw_done;
 
     message {
         uint8 num_of_codecs;
         video_codec_type codecs[num_of_codecs] @end;
-    } preferred_video_codec_type;
+    } @declare preferred_video_codec_type;
 };
 
 flags16 keyboard_modifier_flags {
@@ -1040,15 +1040,15 @@ channel InputsChannel : BaseChannel {
  client:
     message {
         uint32 code;
-    } @ctype(SpiceMsgcKeyDown) key_down = 101;
+    } @ctype(SpiceMsgcKeyDown) @declare key_down = 101;
 
     message {
         uint32 code;
-    } @ctype(SpiceMsgcKeyUp) key_up;
+    } @ctype(SpiceMsgcKeyUp) @declare key_up;
 
     message {
         keyboard_modifier_flags modifiers;
-    } @ctype(SpiceMsgcKeyModifiers) key_modifiers;
+    } @ctype(SpiceMsgcKeyModifiers) @declare key_modifiers;
 
     Data key_scancode;
 
@@ -1056,33 +1056,33 @@ channel InputsChannel : BaseChannel {
         int32 dx;
         int32 dy;
         mouse_button_mask buttons_state;
-    } @ctype(SpiceMsgcMouseMotion) mouse_motion = 111;
+    } @ctype(SpiceMsgcMouseMotion) @declare mouse_motion = 111;
 
     message {
         uint32 x;
         uint32 y;
         mouse_button_mask buttons_state;
         uint8 display_id;
-    } @ctype(SpiceMsgcMousePosition) mouse_position;
+    } @ctype(SpiceMsgcMousePosition) @declare mouse_position;
 
     message {
         mouse_button button;
         mouse_button_mask buttons_state;
-    } @ctype(SpiceMsgcMousePress) mouse_press;
+    } @ctype(SpiceMsgcMousePress) @declare mouse_press;
 
     message {
         mouse_button button;
         mouse_button_mask buttons_state;
-    } @ctype(SpiceMsgcMouseRelease) mouse_release;
+    } @ctype(SpiceMsgcMouseRelease) @declare mouse_release;
 
  server:
     message {
         keyboard_modifier_flags keyboard_modifiers;
-    } init = 101;
+    } @declare init = 101;
 
     message {
         keyboard_modifier_flags modifiers;
-    } key_modifiers;
+    } @declare key_modifiers;
 
     Empty mouse_motion_ack = 111;
 };
@@ -1119,7 +1119,7 @@ struct Cursor {
         CursorHeader header;
     } u @anon;
     uint8 data[] @as_ptr(data_size);
-};
+} @declare;
 
 channel CursorChannel : BaseChannel {
  server:
@@ -1129,7 +1129,7 @@ channel CursorChannel : BaseChannel {
         uint16 trail_frequency;
         uint8 visible;
         Cursor cursor;
-    } init = 101;
+    } @declare init = 101;
 
     Empty reset;
 
@@ -1137,22 +1137,22 @@ channel CursorChannel : BaseChannel {
         Point16 position;
         uint8 visible;
         Cursor cursor;
-    } set;
+    } @declare set;
 
     message {
         Point16 position;
-    } move;
+    } @declare move;
 
     Empty hide;
 
     message {
         uint16 length;
         uint16 frequency;
-    } trail;
+    } @declare trail;
 
     message {
         uint64 id;
-    } @ctype(SpiceMsgDisplayInvalOne) inval_one;
+    } @ctype(SpiceMsgDisplayInvalOne) @declare inval_one;
 
     Empty inval_all;
 };
@@ -1172,31 +1172,31 @@ enum16 audio_fmt {
 message AudioVolume {
     uint8 nchannels;
     uint16 volume[nchannels] @end;
-};
+} @declare;
 
 message AudioMute {
     uint8 mute;
-};
+} @declare;
 
 channel PlaybackChannel : BaseChannel {
  server:
     message {
         uint32 time;
         uint8 data[] @as_ptr(data_size);
-    } @ctype(SpiceMsgPlaybackPacket) data = 101;
+    } @ctype(SpiceMsgPlaybackPacket) @declare data = 101;
 
     message {
         uint32 time;
         audio_data_mode mode;
         uint8 data[] @as_ptr(data_size);
-    } mode;
+    } @declare mode;
 
     message {
        uint32 channels;
        audio_fmt format;
        uint32 frequency;
        uint32 time;
-    } start;
+    } @declare start;
 
     Empty stop;
     AudioVolume volume;
@@ -1204,7 +1204,7 @@ channel PlaybackChannel : BaseChannel {
 
     message {
         uint32 latency_ms;
-    } latency;
+    } @declare latency;
 };
 
 channel RecordChannel : BaseChannel {
@@ -1213,7 +1213,7 @@ channel RecordChannel : BaseChannel {
         uint32 channels;
         audio_fmt format;
         uint32 frequency;
-    } start = 101;
+    } @declare start = 101;
 
     Empty stop;
     AudioVolume volume;
@@ -1222,17 +1222,17 @@ channel RecordChannel : BaseChannel {
     message {
         uint32 time;
         uint8 data[] @nomarshal @as_ptr(data_size);
-    } @ctype(SpiceMsgcRecordPacket) data = 101;
+    } @ctype(SpiceMsgcPlaybackPacket) @declare data = 101;
 
     message {
         uint32 time;
         audio_data_mode mode;
         uint8 data[] @as_ptr(data_size);
-    } mode;
+    } @ctype(SpiceMsgPlaybackMode) @declare mode;
 
     message {
         uint32 time;
-    } start_mark;
+    } @declare start_mark;
 };
 
 channel TunnelChannel {
@@ -1338,16 +1338,16 @@ channel PortChannel : SpicevmcChannel {
  client:
     message {
         uint8 event;
-    } event = 201;
+    } @declare event = 201;
  server:
     message {
         uint32 name_size;
         uint8 *name[name_size] @zero_terminated @marshall @nonnull;
         uint8 opened;
-    } init = 201;
+    } @declare init = 201;
     message {
         uint8 event;
-    } event;
+    } @declare event;
 };
 
 channel WebDAVChannel : PortChannel {
commit 5f1f369e41973056a942f81743d9f6f273623663
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Mon Feb 18 16:29:35 2019 +0000

    Allow to generate C declarations for spice.proto
    
    Generate and include C declarations.
    Next patch will use this facility.
    Since none of the spice.proto types are decorated with @declare,
    adding the #include in messages.h won't have any bad consequences.
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Christophe Fergeau <cfergeau at redhat.com>

diff --git a/common/Makefile.am b/common/Makefile.am
index a104110..2dd6d04 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -109,8 +109,9 @@ MARSHALLERS_DEPS =					\
 
 # Note despite being autogenerated these are not part of CLEANFILES, they are
 # actually a part of EXTRA_DIST, to avoid the need for pyparser by end users
-generated_client_demarshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include common/messages.h $< $@ >/dev/null
+generated_client_demarshallers.c generated_messages.h: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include common/messages.h \
+	--generated-declaration-file generated_messages.h $< $@ >/dev/null
 
 generated_client_marshallers.c generated_client_marshallers.h: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
 	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include client_marshallers.h --client \
@@ -127,6 +128,7 @@ generated_server_marshallers.c generated_server_marshallers.h: $(top_srcdir)/spi
 EXTRA_DIST =				\
 	$(CLIENT_MARSHALLERS)		\
 	$(SERVER_MARSHALLERS)		\
+	generated_messages.h		\
 	meson.build			\
 	canvas_base.c			\
 	canvas_base.h			\
diff --git a/common/meson.build b/common/meson.build
index b1e58c5..2d76d2b 100644
--- a/common/meson.build
+++ b/common/meson.build
@@ -64,7 +64,15 @@ spice_common_dep = declare_dependency(link_with : spice_common_lib,
 #
 if spice_common_generate_client_code
   targets = [
-    ['client_demarshallers', spice_proto, 'generated_client_demarshallers.c', ['--generate-demarshallers', '--client', '--include', 'common/messages.h', '@INPUT@', '@OUTPUT@']],
+    ['client_demarshallers', spice_proto,
+      ['generated_client_demarshallers.c', 'generated_messages.h'],
+      ['--generate-demarshallers',
+        '--client',
+        '--include', 'common/messages.h',
+        '--generated-declaration-file', '@OUTPUT1@',
+        '@INPUT@', '@OUTPUT0@'
+      ]
+    ],
     ['client_marshallers', spice_proto,
       ['generated_client_marshallers.c', 'generated_client_marshallers.h'],
       ['--generate-marshallers', '--generate-header',
diff --git a/common/messages.h b/common/messages.h
index f740a8c..36ee59d 100644
--- a/common/messages.h
+++ b/common/messages.h
@@ -558,6 +558,8 @@ typedef struct SpiceMsgDisplayGlDraw {
     uint32_t h;
 } SpiceMsgDisplayGlDraw;
 
+#include <common/generated_messages.h>
+
 SPICE_END_DECLS
 
 #endif // H_SPICE_COMMON_MESSAGES
commit 3cd3886b27232028b0dca1346fc9bda2b7cf5ff9
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Mon Feb 18 16:16:21 2019 +0000

    codegen: Allows to generate C declarations automatically
    
    Allows to specify a @declare attribute for messages and structure
    that can generate the needed C structures.
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Christophe Fergeau <cfergeau at redhat.com>

diff --git a/python_modules/ptypes.py b/python_modules/ptypes.py
index 05c594e..b08170e 100644
--- a/python_modules/ptypes.py
+++ b/python_modules/ptypes.py
@@ -70,6 +70,8 @@ valid_attributes=set([
     'zero',
     # this attribute does not exist on the network, fill just structure with the value
     'virtual',
+    # generate C structure declarations from protocol definition
+    'declare',
 ])
 
 attributes_with_arguments=set([
@@ -483,6 +485,26 @@ class ArrayType(Type):
     def c_type(self):
         return self.element_type.c_type()
 
+    def generate_c_declaration(self, writer, member):
+        name = member.name
+        if member.has_attr("chunk"):
+            return writer.writeln('SpiceChunks *%s;' % name)
+        if member.has_attr("as_ptr"):
+            len_var = member.attributes["as_ptr"][0]
+            writer.writeln('uint32_t %s;' % len_var)
+            return writer.writeln('%s *%s;' % (self.c_type(), name))
+        if member.has_attr("to_ptr"):
+            return writer.writeln('%s *%s;' % (self.c_type(), name))
+        if member.has_attr("ptr_array"):
+            return writer.writeln('%s *%s[0];' % (self.c_type(), name))
+        if member.has_end_attr() or self.is_remaining_length():
+            return writer.writeln('%s %s[0];' % (self.c_type(), name))
+        if self.is_constant_length():
+            return writer.writeln('%s %s[%s];' % (self.c_type(), name, self.size))
+        if self.is_identifier_length():
+            return writer.writeln('%s *%s;' % (self.c_type(), name))
+        raise NotImplementedError('unknown array %s' % str(self))
+
 class PointerType(Type):
     def __init__(self, target_type):
         Type.__init__(self)
@@ -517,6 +539,15 @@ class PointerType(Type):
     def get_num_pointers(self):
         return 1
 
+    def generate_c_declaration(self, writer, member):
+        target_type = self.target_type
+        is_array = target_type.is_array()
+        if not is_array or target_type.is_identifier_length():
+            writer.writeln("%s *%s;" % (target_type.c_type(), member.name))
+            return
+        raise NotImplementedError('Some pointers to array declarations are not implemented %s' %
+member)
+
 class Containee:
     def __init__(self):
         self.attributes = {}
@@ -612,6 +643,14 @@ class Member(Containee):
             names = [prefix + "_" + name for name in names]
         return names
 
+    def generate_c_declaration(self, writer):
+        if self.has_attr("zero"):
+            return
+        if self.is_pointer() or self.is_array():
+            self.member_type.generate_c_declaration(writer, self)
+            return
+        return writer.writeln("%s %s;" % (self.member_type.c_type(), self.name))
+
 class SwitchCase:
     def __init__(self, values, member):
         self.values = values
@@ -735,6 +774,17 @@ class Switch(Containee):
             names = names + c.get_pointer_names(marshalled)
         return names
 
+    def generate_c_declaration(self, writer):
+        if self.has_attr("anon") and len(self.cases) == 1:
+            self.cases[0].member.generate_c_declaration(writer)
+            return
+        writer.writeln('union {')
+        writer.indent()
+        for m in self.cases:
+            m.member.generate_c_declaration(writer)
+        writer.unindent()
+        writer.writeln('} %s;' % self.name)
+
 class ContainerType(Type):
     def is_fixed_sizeof(self):
         for m in self.members:
@@ -845,6 +895,20 @@ class ContainerType(Type):
 
         return member
 
+    def generate_c_declaration(self, writer):
+        if not self.has_attr('declare'):
+            return
+        name = self.c_type()
+        writer.writeln('typedef struct %s {' % name)
+        writer.indent()
+        for m in self.members:
+            m.generate_c_declaration(writer)
+        if len(self.members) == 0:
+            # make sure generated structure are not empty
+            writer.writeln("char dummy[0];")
+        writer.unindent()
+        writer.writeln('} %s;' % name).newline()
+
 class StructType(ContainerType):
     def __init__(self, name, members, attribute_list):
         Type.__init__(self)
diff --git a/spice_codegen.py b/spice_codegen.py
index 54d655d..5846337 100755
--- a/spice_codegen.py
+++ b/spice_codegen.py
@@ -176,6 +176,8 @@ parser.add_option("--license", dest="license",
 parser.add_option("--generate-header",
                   action="store_true", dest="generate_header", default=False,
                   help="Generate also the header")
+parser.add_option("--generated-declaration-file", dest="generated_declaration_file", metavar="FILE",
+                  help="Name of the file to generate declarations")
 
 (options, args) = parser.parse_args()
 
@@ -257,6 +259,51 @@ else:
     print >> sys.stderr, "Invalid license specified: %s" % options.license
     sys.exit(1)
 
+all_structures = {}
+def generate_declaration(t, writer_top):
+    writer = codegen.CodeWriter()
+    try:
+        c_type = t.c_type()
+        t.generate_c_declaration(writer)
+        value = writer.getvalue().strip()
+        if not value:
+            return
+        if c_type in all_structures:
+            assert all_structures[c_type] == value, """Structure %s redefinition
+previous:
+%s
+---
+current:
+%s
+---""" % (c_type, all_structures[c_type], value)
+        else:
+            all_structures[c_type] = value
+            t.generate_c_declaration(writer_top)
+    except:
+        print >> sys.stderr, 'type %s' % t
+        print >> sys.stderr, writer.getvalue()
+        traceback.print_exc(sys.stderr)
+
+def generate_declarations():
+    writer = codegen.CodeWriter()
+    writer.public_suffix = options.suffix
+    writer.write(license)
+
+    # all types
+    for t in ptypes.get_named_types():
+        if isinstance(t, ptypes.StructType):
+            generate_declaration(t, writer)
+        if isinstance(t, ptypes.ChannelType):
+            for m in t.client_messages + t.server_messages:
+                generate_declaration(m.message_type, writer)
+
+    content = writer.getvalue()
+    write_content(options.generated_declaration_file, content,
+                  options.keep_identical_file)
+
+if options.generated_declaration_file:
+    generate_declarations()
+
 writer.public_suffix = options.suffix
 
 writer.writeln("/* this is a file autogenerated by spice_codegen.py */")
commit dac34baaab4500bdd7f73e2a62d9faab4f21c517
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Mon Feb 18 17:59:17 2019 +0000

    codegen: Generate headers while generating code
    
    Python script generates code and header together however allowed
    to save only one of them.
    Allows to save both of them together to reduce number of time
    we call Python script.
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Christophe Fergeau <cfergeau at redhat.com>

diff --git a/common/Makefile.am b/common/Makefile.am
index 622bf0b..a104110 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -112,21 +112,17 @@ MARSHALLERS_DEPS =					\
 generated_client_demarshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
 	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --client --include common/messages.h $< $@ >/dev/null
 
-generated_client_marshallers.h: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --client --include common/messages.h -H $< $@ >/dev/null
-
-generated_client_marshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include client_marshallers.h --client $< $@ >/dev/null
+generated_client_marshallers.c generated_client_marshallers.h: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers -P --include client_marshallers.h --client \
+	--generate-header $< $@ >/dev/null
 
 generated_server_demarshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
 	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-demarshallers --server --include common/messages.h $< $@ >/dev/null
 
 STRUCTS = -M String -M Rect -M Point -M DisplayBase -M Fill -M Opaque -M Copy -M Blend -M Blackness -M Whiteness -M Invers -M Rop3 -M Stroke -M Text -M Transparent -M AlphaBlend -M Composite
-generated_server_marshallers.c: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers $(STRUCTS) --server --include common/messages.h $< $@ >/dev/null
-
-generated_server_marshallers.h: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
-	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers $(STRUCTS) --server --include common/messages.h -H $< $@ >/dev/null
+generated_server_marshallers.c generated_server_marshallers.h: $(top_srcdir)/spice.proto $(MARSHALLERS_DEPS)
+	$(AM_V_GEN)$(PYTHON) $(top_srcdir)/spice_codegen.py --generate-marshallers $(STRUCTS) --server --include common/messages.h \
+    --generate-header $< $@ >/dev/null
 
 EXTRA_DIST =				\
 	$(CLIENT_MARSHALLERS)		\
diff --git a/common/client_marshallers.h b/common/client_marshallers.h
index f082934..b67b98e 100644
--- a/common/client_marshallers.h
+++ b/common/client_marshallers.h
@@ -21,9 +21,9 @@
 
 #include <spice/protocol.h>
 
+#include "messages.h"
 #include "common/generated_client_marshallers.h"
 #include "marshaller.h"
-#include "messages.h"
 
 SPICE_BEGIN_DECLS
 
diff --git a/common/meson.build b/common/meson.build
index 156297b..b1e58c5 100644
--- a/common/meson.build
+++ b/common/meson.build
@@ -65,8 +65,13 @@ spice_common_dep = declare_dependency(link_with : spice_common_lib,
 if spice_common_generate_client_code
   targets = [
     ['client_demarshallers', spice_proto, 'generated_client_demarshallers.c', ['--generate-demarshallers', '--client', '--include', 'common/messages.h', '@INPUT@', '@OUTPUT@']],
-    ['client_marshalers', spice_proto, 'generated_client_marshallers.c', ['--generate-marshallers', '-P', '--client', '--include', 'client_marshallers.h', '@INPUT@', '@OUTPUT@']],
-    ['client_marshallers_h', spice_proto, 'generated_client_marshallers.h', ['--generate-marshallers', '-P', '--client', '--include', 'common/messages.h', '-H', '@INPUT@', '@OUTPUT@']],
+    ['client_marshallers', spice_proto,
+      ['generated_client_marshallers.c', 'generated_client_marshallers.h'],
+      ['--generate-marshallers', '--generate-header',
+        '-P', '--client', '--include', 'client_marshallers.h',
+        '@INPUT@', '@OUTPUT0@'
+      ]
+    ]
   ]
 
   spice_common_client_sources = [
@@ -116,8 +121,12 @@ if spice_common_generate_server_code
 
   targets = [
     ['server_demarshallers', spice_proto, 'generated_server_demarshallers.c', ['--generate-demarshallers', '--server', '--include', 'common/messages.h', '@INPUT@', '@OUTPUT@']],
-    ['server_marshallers', spice_proto, 'generated_server_marshallers.c', ['--generate-marshallers', '--server'] + structs_args + ['--include', 'common/messages.h', '@INPUT@', '@OUTPUT@']],
-    ['server_marshallers_h', spice_proto, 'generated_server_marshallers.h', ['--generate-marshallers', '--server'] + structs_args + ['--include', 'common/messages.h', '-H', '@INPUT@', '@OUTPUT@']],
+    ['server_marshallers', spice_proto,
+      ['generated_server_marshallers.c', 'generated_server_marshallers.h'],
+      ['--generate-marshallers', '--generate-header',
+        '--server'] + structs_args + ['--include', 'common/messages.h', '@INPUT@', '@OUTPUT0@'
+      ]
+    ],
   ]
 
   spice_common_server_sources = []
diff --git a/spice_codegen.py b/spice_codegen.py
index 8049820..54d655d 100755
--- a/spice_codegen.py
+++ b/spice_codegen.py
@@ -173,6 +173,9 @@ parser.add_option("--suffix", dest="suffix",
                   help="set public symbol suffix", default="")
 parser.add_option("--license", dest="license",
                   help="license to use for generated file(s) (LGPL/BSD)", default="LGPL")
+parser.add_option("--generate-header",
+                  action="store_true", dest="generate_header", default=False,
+                  help="Generate also the header")
 
 (options, args) = parser.parse_args()
 
@@ -192,7 +195,11 @@ if proto == None:
 codegen.set_prefix(proto.name)
 writer = codegen.CodeWriter()
 writer.header = codegen.CodeWriter()
-writer.header.set_option("dest_file", dest_file)
+if options.generate_header:
+    filename = os.path.splitext(dest_file)[0] + '.h'
+    writer.header.set_option("dest_file", filename)
+else:
+    writer.header.set_option("dest_file", dest_file)
 writer.set_option("source", os.path.basename(proto_file))
 
 if options.license == "LGPL":
@@ -256,7 +263,7 @@ writer.writeln("/* this is a file autogenerated by spice_codegen.py */")
 writer.write(license)
 writer.header.writeln("/* this is a file autogenerated by spice_codegen.py */")
 writer.header.write(license)
-if not options.header and not options.generate_enums:
+if not options.generate_enums:
     writer.writeln("#ifdef HAVE_CONFIG_H")
     writer.writeln("#include <config.h>")
     writer.writeln("#endif")
@@ -311,4 +318,8 @@ if options.header:
 else:
     content = writer.getvalue()
 write_content(dest_file, content, options.keep_identical_file)
+if options.generate_header:
+    content = writer.header.getvalue()
+    filename = writer.header.options["dest_file"]
+    write_content(filename, content, options.keep_identical_file)
 sys.exit(0)
commit af66a4ccadfd271f198d81aa48fd475c15772237
Author: Frediano Ziglio <fziglio at redhat.com>
Date:   Mon Feb 18 09:49:39 2019 +0000

    codegen: Factor out a function to write output file
    
    This will be reused to generate C declaration automatically.
    
    Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
    Acked-by: Christophe Fergeau <cfergeau at redhat.com>

diff --git a/spice_codegen.py b/spice_codegen.py
index f3190da..8049820 100755
--- a/spice_codegen.py
+++ b/spice_codegen.py
@@ -105,6 +105,30 @@ def write_enums(writer, describe=False):
 
     writer.writeln("#endif /* _H_SPICE_ENUMS */")
 
+def write_content(dest_file, content, keep_identical_file):
+    if keep_identical_file:
+        try:
+            f = open(dest_file, 'rb')
+            old_content = f.read()
+            f.close()
+
+            if content == old_content:
+                six.print_("No changes to %s" % dest_file)
+                return
+
+        except IOError:
+            pass
+
+    f = open(dest_file, 'wb')
+    if six.PY3:
+        f.write(bytes(content, 'UTF-8'))
+    else:
+        f.write(content)
+    f.close()
+
+    six.print_("Wrote %s" % dest_file)
+
+
 parser = OptionParser(usage="usage: %prog [options] <protocol_file> <destination file>")
 parser.add_option("-e", "--generate-enums",
                   action="store_true", dest="generate_enums", default=False,
@@ -286,25 +310,5 @@ if options.header:
     content = writer.header.getvalue()
 else:
     content = writer.getvalue()
-if options.keep_identical_file:
-    try:
-        f = open(dest_file, 'rb')
-        old_content = f.read()
-        f.close()
-
-        if content == old_content:
-            six.print_("No changes to %s" % dest_file)
-            sys.exit(0)
-
-    except IOError:
-        pass
-
-f = open(dest_file, 'wb')
-if six.PY3:
-    f.write(bytes(content, 'UTF-8'))
-else:
-    f.write(content)
-f.close()
-
-six.print_("Wrote %s" % dest_file)
+write_content(dest_file, content, options.keep_identical_file)
 sys.exit(0)


More information about the Spice-commits mailing list