winex11.drv: Don't join INCR data until the transfer finishes.
This commit is contained in:
parent
a71443a884
commit
9dcc21e3e7
|
@ -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
|
||||
* Reads the contents of the X selection property.
|
||||
|
@ -2368,13 +2374,21 @@ static BOOL X11DRV_CLIPBOARD_ReadProperty(Display *display, Window w, Atom prop,
|
|||
|
||||
if (atype == x11drv_atom(INCR))
|
||||
{
|
||||
unsigned char *buf = *data;
|
||||
unsigned char *buf;
|
||||
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 (;;)
|
||||
{
|
||||
int i;
|
||||
unsigned char *prop_data, *tmp;
|
||||
unsigned char *prop_data;
|
||||
unsigned long prop_size;
|
||||
|
||||
/* Wait until PropertyNotify is received */
|
||||
|
@ -2392,32 +2406,58 @@ static BOOL X11DRV_CLIPBOARD_ReadProperty(Display *display, Window w, Atom prop,
|
|||
if (i >= SELECTION_RETRIES ||
|
||||
!X11DRV_CLIPBOARD_GetProperty(display, w, prop, &atype, &prop_data, &prop_size))
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
return FALSE;
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Retrieved entire data. */
|
||||
if (prop_size == 0)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, prop_data);
|
||||
*data = buf;
|
||||
*datasize = bufsize;
|
||||
return TRUE;
|
||||
res = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = HeapReAlloc(GetProcessHeap(), 0, buf, bufsize + prop_size + 1);
|
||||
if (!tmp)
|
||||
packet = HeapAlloc(GetProcessHeap(), 0, sizeof(*packet));
|
||||
if (!packet)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
HeapFree(GetProcessHeap(), 0, prop_data);
|
||||
return FALSE;
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
buf = tmp;
|
||||
memcpy(buf + bufsize, prop_data, prop_size + 1);
|
||||
packet->size = prop_size;
|
||||
packet->data = prop_data;
|
||||
list_add_tail(&packets, &packet->entry);
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue