summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@redhat.com>2011-03-31 20:13:49 +0200
committerMarc-André Lureau <marcandre.lureau@redhat.com>2011-03-31 20:15:07 +0200
commitcf7b7bfdf572fc08f5e03e268e6f928980b15739 (patch)
treeed5f1d26dadb7fac5bd48e8e4e0811e9770c2fc9 /gtk
parent7ce7221a73c404fa9e80e3d1bffec064fea719fb (diff)
gtk: fix handling of incoming large clipboard data
The main fix was probably the agent_msg_pos guin8 -> guint, although I modified the code for more clarity
Diffstat (limited to 'gtk')
-rw-r--r--gtk/channel-main.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/gtk/channel-main.c b/gtk/channel-main.c
index ff784b9..a995fd3 100644
--- a/gtk/channel-main.c
+++ b/gtk/channel-main.c
@@ -58,7 +58,7 @@ struct spice_main_channel {
int agent_tokens;
VDAgentMessage agent_msg; /* partial msg reconstruction */
guint8 *agent_msg_data;
- uint8_t agent_msg_pos;
+ guint agent_msg_pos;
uint8_t agent_msg_size;
uint32_t agent_caps[VD_AGENT_CAPS_SIZE];
struct {
@@ -1159,6 +1159,8 @@ static void main_agent_handle_msg(SpiceChannel *channel,
spice_main_channel *c = SPICE_MAIN_CHANNEL(channel)->priv;
guint8 selection = VD_AGENT_CLIPBOARD_SELECTION_CLIPBOARD;
+ g_return_if_fail(msg->protocol == VD_AGENT_PROTOCOL);
+
switch (msg->type) {
case VD_AGENT_CLIPBOARD_RELEASE:
case VD_AGENT_CLIPBOARD_REQUEST:
@@ -1260,7 +1262,7 @@ static void main_agent_handle_msg(SpiceChannel *channel,
}
/* coroutine context */
-static void main_handle_agent_data_msg(SpiceChannel *channel, guint* msg_size, guchar** msg_pos)
+static void main_handle_agent_data_msg(SpiceChannel* channel, int* msg_size, guchar** msg_pos)
{
spice_main_channel *c = SPICE_MAIN_CHANNEL(channel)->priv;
int n;
@@ -1274,7 +1276,6 @@ static void main_handle_agent_data_msg(SpiceChannel *channel, guint* msg_size, g
if (c->agent_msg_pos == sizeof(VDAgentMessage)) {
SPICE_DEBUG("agent msg start: msg_size=%d, protocol=%d, type=%d",
c->agent_msg.size, c->agent_msg.protocol, c->agent_msg.type);
- g_return_if_fail(c->agent_msg.protocol == VD_AGENT_PROTOCOL);
g_return_if_fail(c->agent_msg_data == NULL);
c->agent_msg_data = g_malloc(c->agent_msg.size);
}
@@ -1300,23 +1301,26 @@ static void main_handle_agent_data_msg(SpiceChannel *channel, guint* msg_size, g
static void main_handle_agent_data(SpiceChannel *channel, spice_msg_in *in)
{
spice_main_channel *c = SPICE_MAIN_CHANNEL(channel)->priv;
- VDAgentMessage *msg;
- guint msg_size;
- guchar* msg_pos;
+ guint8 *data;
int len;
- msg = spice_msg_in_raw(in, &len);
- msg_size = msg->size;
- msg_pos = msg->data;
+ /* shortcut to avoid extra message allocation & copy if possible */
+ if (c->agent_msg_pos == 0) {
+ VDAgentMessage *msg;
+ guint msg_size;
- if (c->agent_msg_pos == 0 &&
- msg_size + sizeof(VDAgentMessage) == len) {
- main_agent_handle_msg(channel, msg, msg + 1);
- return;
+ msg = spice_msg_in_raw(in, &len);
+ msg_size = msg->size;
+
+ if (msg_size + sizeof(VDAgentMessage) == len) {
+ main_agent_handle_msg(channel, msg, msg->data);
+ return;
+ }
}
- while (msg_size > 0) {
- main_handle_agent_data_msg(channel, &msg_size, &msg_pos);
+ data = spice_msg_in_raw(in, &len);
+ while (len > 0) {
+ main_handle_agent_data_msg(channel, &len, &data);
}
}