diff options
author | Marc-André Lureau <marcandre.lureau@redhat.com> | 2011-02-13 19:10:50 +0100 |
---|---|---|
committer | Marc-André Lureau <marcandre.lureau@redhat.com> | 2011-02-19 00:01:29 +0100 |
commit | 1398b9bdd5e56a7348350262159dc527e94ce34f (patch) | |
tree | 7d999b974a7d6f00adaec8e76c3e3540b77378e0 | |
parent | b0aad552082fdfed6d6b9e91f3830f716f0c898a (diff) |
gtk: split agent msg to VD_AGENT_MAX_DATA_SIZE if required
Fix clipboard sharing of large objects
-rw-r--r-- | gtk/channel-main.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/gtk/channel-main.c b/gtk/channel-main.c index 35e5376..6121f20 100644 --- a/gtk/channel-main.c +++ b/gtk/channel-main.c @@ -582,22 +582,35 @@ static void agent_msg_queue(SpiceMainChannel *channel, int type, int size, void { spice_main_channel *c = channel->priv; spice_msg_out *out; - VDAgentMessage *msg; + VDAgentMessage msg; void *payload; + guint32 paysize; + guint8 *d = data; - out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MAIN_AGENT_DATA); - msg = (VDAgentMessage*) - spice_marshaller_reserve_space(out->marshaller, sizeof(VDAgentMessage)); - payload = (VDAgentMonitorsConfig*) - spice_marshaller_reserve_space(out->marshaller, size); + g_assert(VD_AGENT_MAX_DATA_SIZE > sizeof(VDAgentMessage)); // could be a static compilation check - msg->protocol = VD_AGENT_PROTOCOL; - msg->type = type; - msg->opaque = 0; - msg->size = size; - memcpy(payload, data, size); + msg.protocol = VD_AGENT_PROTOCOL; + msg.type = type; + msg.opaque = 0; + msg.size = size; + paysize = MIN(VD_AGENT_MAX_DATA_SIZE, size + sizeof(VDAgentMessage)); + out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MAIN_AGENT_DATA); + payload = spice_marshaller_reserve_space(out->marshaller, paysize); + memcpy(payload, &msg, sizeof(VDAgentMessage)); + memcpy(payload + sizeof(VDAgentMessage), d, paysize - sizeof(VDAgentMessage)); + size -= (paysize - sizeof(VDAgentMessage)); + d += (paysize - sizeof(VDAgentMessage)); g_queue_push_tail(c->agent_msg_queue, out); + + while ((paysize = MIN(VD_AGENT_MAX_DATA_SIZE, size)) > 0) { + out = spice_msg_out_new(SPICE_CHANNEL(channel), SPICE_MSGC_MAIN_AGENT_DATA); + payload = spice_marshaller_reserve_space(out->marshaller, paysize); + memcpy(payload, d, paysize); + g_queue_push_tail(c->agent_msg_queue, out); + size -= paysize; + d += paysize; + } } /* any context: the message is not flushed immediately, |