summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2011-02-13 19:10:50 +0100
committerMarc-André Lureau <marcandre.lureau@redhat.com>2011-02-19 00:01:29 +0100
commit1398b9bdd5e56a7348350262159dc527e94ce34f (patch)
tree7d999b974a7d6f00adaec8e76c3e3540b77378e0
parentb0aad552082fdfed6d6b9e91f3830f716f0c898a (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.c35
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,