Commit 9dcc21e3 authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

winex11.drv: Don't join INCR data until the transfer finishes.

parent a71443a8
...@@ -2347,6 +2347,12 @@ static BOOL X11DRV_CLIPBOARD_GetProperty(Display *display, Window w, Atom prop, ...@@ -2347,6 +2347,12 @@ static BOOL X11DRV_CLIPBOARD_GetProperty(Display *display, Window w, Atom prop,
} }
struct clipboard_data_packet {
struct list entry;
unsigned long size;
unsigned char *data;
};
/************************************************************************** /**************************************************************************
* X11DRV_CLIPBOARD_ReadProperty * X11DRV_CLIPBOARD_ReadProperty
* Reads the contents of the X selection property. * Reads the contents of the X selection property.
...@@ -2368,13 +2374,21 @@ static BOOL X11DRV_CLIPBOARD_ReadProperty(Display *display, Window w, Atom prop, ...@@ -2368,13 +2374,21 @@ static BOOL X11DRV_CLIPBOARD_ReadProperty(Display *display, Window w, Atom prop,
if (atype == x11drv_atom(INCR)) if (atype == x11drv_atom(INCR))
{ {
unsigned char *buf = *data; unsigned char *buf;
unsigned long bufsize = 0; unsigned long bufsize = 0;
struct list packets;
struct clipboard_data_packet *packet, *packet2;
BOOL res;
HeapFree(GetProcessHeap(), 0, *data);
*data = NULL;
list_init(&packets);
for (;;) for (;;)
{ {
int i; int i;
unsigned char *prop_data, *tmp; unsigned char *prop_data;
unsigned long prop_size; unsigned long prop_size;
/* Wait until PropertyNotify is received */ /* Wait until PropertyNotify is received */
...@@ -2392,32 +2406,58 @@ static BOOL X11DRV_CLIPBOARD_ReadProperty(Display *display, Window w, Atom prop, ...@@ -2392,32 +2406,58 @@ static BOOL X11DRV_CLIPBOARD_ReadProperty(Display *display, Window w, Atom prop,
if (i >= SELECTION_RETRIES || if (i >= SELECTION_RETRIES ||
!X11DRV_CLIPBOARD_GetProperty(display, w, prop, &atype, &prop_data, &prop_size)) !X11DRV_CLIPBOARD_GetProperty(display, w, prop, &atype, &prop_data, &prop_size))
{ {
HeapFree(GetProcessHeap(), 0, buf); res = FALSE;
return FALSE; break;
} }
/* Retrieved entire data. */ /* Retrieved entire data. */
if (prop_size == 0) if (prop_size == 0)
{ {
HeapFree(GetProcessHeap(), 0, prop_data); HeapFree(GetProcessHeap(), 0, prop_data);
*data = buf; res = TRUE;
*datasize = bufsize; break;
return TRUE;
} }
tmp = HeapReAlloc(GetProcessHeap(), 0, buf, bufsize + prop_size + 1); packet = HeapAlloc(GetProcessHeap(), 0, sizeof(*packet));
if (!tmp) if (!packet)
{ {
HeapFree(GetProcessHeap(), 0, buf);
HeapFree(GetProcessHeap(), 0, prop_data); HeapFree(GetProcessHeap(), 0, prop_data);
return FALSE; res = FALSE;
break;
} }
buf = tmp; packet->size = prop_size;
memcpy(buf + bufsize, prop_data, prop_size + 1); packet->data = prop_data;
list_add_tail(&packets, &packet->entry);
bufsize += prop_size; bufsize += prop_size;
HeapFree(GetProcessHeap(), 0, prop_data);
} }
if (res)
{
buf = HeapAlloc(GetProcessHeap(), 0, bufsize + 1);
if (buf)
{
unsigned long bytes_copied = 0;
*datasize = bufsize;
LIST_FOR_EACH_ENTRY( packet, &packets, struct clipboard_data_packet, entry)
{
memcpy(&buf[bytes_copied], packet->data, packet->size);
bytes_copied += packet->size;
}
buf[bufsize] = 0;
*data = buf;
}
else
res = FALSE;
}
LIST_FOR_EACH_ENTRY_SAFE( packet, packet2, &packets, struct clipboard_data_packet, entry)
{
HeapFree(GetProcessHeap(), 0, packet->data);
HeapFree(GetProcessHeap(), 0, packet);
}
return res;
} }
return TRUE; return TRUE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment