typedef struct {
void (*msgc_ack_sync)(SpiceMarshaller *m, const SpiceMsgcAckSync *msg);
void (*msg_SpiceMsgEmpty)(SpiceMarshaller *m, const SpiceMsgEmpty *msg);
void (*msgc_pong)(SpiceMarshaller *m, const SpiceMsgPing *msg);
void (*msg_SpiceMsgData)(SpiceMarshaller *m, const SpiceMsgData *msg);
void (*msgc_disconnecting)(SpiceMarshaller *m, const SpiceMsgDisconnect *msg);
void (*msgc_main_client_info)(SpiceMarshaller *m, const SpiceMsgcClientInfo *msg);
void (*msgc_main_mouse_mode_request)(SpiceMarshaller *m, const SpiceMsgcMainMouseModeRequest *msg);
void (*msgc_main_agent_start)(SpiceMarshaller *m, const SpiceMsgMainAgentTokens *msg);
void (*msgc_main_agent_token)(SpiceMarshaller *m, const SpiceMsgMainAgentTokens *msg);
void (*msgc_main_migrate_dst_do_seamless)(SpiceMarshaller *m, const SpiceMsgcMainMigrateDstDoSeamless *msg);
void (*msgc_main_client_capability)(SpiceMarshaller *m, const SpiceMsgcMainClientCapability *msg);
void (*msgc_display_init)(SpiceMarshaller *m, const SpiceMsgcDisplayInit *msg);
void (*msgc_display_stream_report)(SpiceMarshaller *m, const SpiceMsgcDisplayStreamReport *msg);
void (*msgc_display_preferred_compression)(SpiceMarshaller *m, const SpiceMsgcDisplayPreferredCompression *msg);
void (*msgc_display_gl_draw_done)(SpiceMarshaller *m, const SpiceMsgcDisplayGlDrawDone *msg);
void (*msgc_display_preferred_video_codec_type)(SpiceMarshaller *m, const SpiceMsgcDisplayPreferredVideoCodecType *msg);
void (*msgc_display_client_draw_ack)(SpiceMarshaller *m, const SpiceMsgcDisplayClientDrawAck *msg);
void (*msgc_inputs_key_down)(SpiceMarshaller *m, const SpiceMsgcKeyDown *msg);
void (*msgc_inputs_key_up)(SpiceMarshaller *m, const SpiceMsgcKeyUp *msg);
void (*msgc_inputs_key_modifiers)(SpiceMarshaller *m, const SpiceMsgcKeyModifiers *msg);
void (*msgc_inputs_mouse_motion)(SpiceMarshaller *m, const SpiceMsgcMouseMotion *msg);
void (*msgc_inputs_mouse_position)(SpiceMarshaller *m, const SpiceMsgcMousePosition *msg);
void (*msgc_inputs_mouse_press)(SpiceMarshaller *m, const SpiceMsgcMousePress *msg);
void (*msgc_inputs_mouse_release)(SpiceMarshaller *m, const SpiceMsgcMouseRelease *msg);
void (*msgc_record_data)(SpiceMarshaller *m, const SpiceMsgPlaybackPacket *msg);
void (*msgc_record_mode)(SpiceMarshaller *m, const SpiceMsgPlaybackMode *msg);
void (*msgc_record_start_mark)(SpiceMarshaller *m, const SpiceMsgcRecordStartMark *msg);
#ifdef USE_SMARTCARD
void (*msgc_smartcard_data)(SpiceMarshaller *m, const VSCMsgHeader *msg);
#endif /* USE_SMARTCARD */
void (*msg_SpiceMsgCompressedData)(SpiceMarshaller *m, const SpiceMsgCompressedData *msg);
void (*msgc_port_event)(SpiceMarshaller *m, const SpiceMsgcPortEvent *msg);
} SpiceMessageMarshallers;
SpiceMessageMarshallers * spice_message_marshallers_get(void)
{
static SpiceMessageMarshallers marshallers = {0};
marshallers.msg_SpiceMsgCompressedData = spice_marshall_SpiceMsgCompressedData;
marshallers.msg_SpiceMsgData = spice_marshall_SpiceMsgData;
marshallers.msg_SpiceMsgEmpty = spice_marshall_SpiceMsgEmpty;
marshallers.msgc_ack_sync = spice_marshall_msgc_ack_sync;
marshallers.msgc_disconnecting = spice_marshall_msgc_disconnecting;
marshallers.msgc_display_client_draw_ack = spice_marshall_msgc_display_client_draw_ack;
marshallers.msgc_display_gl_draw_done = spice_marshall_msgc_display_gl_draw_done;
marshallers.msgc_display_init = spice_marshall_msgc_display_init;
marshallers.msgc_display_preferred_compression = spice_marshall_msgc_display_preferred_compression;
marshallers.msgc_display_preferred_video_codec_type = spice_marshall_msgc_display_preferred_video_codec_type;
marshallers.msgc_display_stream_report = spice_marshall_msgc_display_stream_report;
marshallers.msgc_inputs_key_down = spice_marshall_msgc_inputs_key_down;
marshallers.msgc_inputs_key_modifiers = spice_marshall_msgc_inputs_key_modifiers;
marshallers.msgc_inputs_key_up = spice_marshall_msgc_inputs_key_up;
marshallers.msgc_inputs_mouse_motion = spice_marshall_msgc_inputs_mouse_motion;
marshallers.msgc_inputs_mouse_position = spice_marshall_msgc_inputs_mouse_position;
marshallers.msgc_inputs_mouse_press = spice_marshall_msgc_inputs_mouse_press;
marshallers.msgc_inputs_mouse_release = spice_marshall_msgc_inputs_mouse_release;
marshallers.msgc_main_agent_start = spice_marshall_msgc_main_agent_start;
marshallers.msgc_main_agent_token = spice_marshall_msgc_main_agent_token;
marshallers.msgc_main_client_capability = spice_marshall_msgc_main_client_capability;
marshallers.msgc_main_client_info = spice_marshall_msgc_main_client_info;
marshallers.msgc_main_migrate_dst_do_seamless = spice_marshall_msgc_main_migrate_dst_do_seamless;
marshallers.msgc_main_mouse_mode_request = spice_marshall_msgc_main_mouse_mode_request;
marshallers.msgc_pong = spice_marshall_msgc_pong;
marshallers.msgc_port_event = spice_marshall_msgc_port_event;
marshallers.msgc_record_data = spice_marshall_msgc_record_data;
marshallers.msgc_record_mode = spice_marshall_msgc_record_mode;
marshallers.msgc_record_start_mark = spice_marshall_msgc_record_start_mark;
#ifdef USE_SMARTCARD
marshallers.msgc_smartcard_data = spice_marshall_msgc_smartcard_data;
#endif /* USE_SMARTCARD */
return &marshallers;
}
struct _SpiceChannelPrivate {...SpiceMessageMarshallers *marshallers;...}
/* coroutine context */
static void spice_channel_send_link(SpiceChannel *channel)
{
...
switch (protocol) {
case 1: /* protocol 1 == major 1, old 0.4 protocol, last active minor */
g_critical("deprecated major %d", protocol);
return;
case SPICE_VERSION_MAJOR: /* protocol 2 == current */
c->link_hdr.major_version = SPICE_VERSION_MAJOR;
c->link_hdr.minor_version = SPICE_VERSION_MINOR;
c->parser = spice_get_server_channel_parser(c->channel_type, NULL);
c->marshallers = spice_message_marshallers_get();
break;
default:
g_critical("unknown major %d", protocol);
return;
}
...
}
#ifndef H_SPICE_COMMON_CLIENT_MARSHALLERS
#define H_SPICE_COMMON_CLIENT_MARSHALLERS
#include
#include "messages.h"
#include "common/generated_client_marshallers.h"
#include "marshaller.h"
SPICE_BEGIN_DECLS
SpiceMessageMarshallers *spice_message_marshallers_get(void);
SPICE_END_DECLS
#endif
如
static SpiceMsgOut* mouse_position(SpiceInputsChannel *channel)
{
SpiceInputsChannelPrivate *c = channel->priv;
SpiceMsgcMousePosition position;
SpiceMsgOut *msg;
if (c->dpy == -1)
return NULL;
/* CHANNEL_DEBUG(channel, "%s: +%d+%d", __FUNCTION__, c->x, c->y); */
position.buttons_state = c->bs;
position.x = c->x;
position.y = c->y;
position.display_id = c->dpy;
msg = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_INPUTS_MOUSE_POSITION);
msg->marshallers->msgc_inputs_mouse_position(msg->marshaller, &position);
c->motion_count++;
c->dpy = -1;
return msg;
}