Vincent Povirk : winex11.drv: Don' t join INCR data until the transfer finishes.
Alexandre Julliard
julliard at winehq.org
Tue Jan 15 13:46:17 CST 2013
Module: wine
Branch: master
Commit: 9dcc21e3e79bf4b3dcfab233fb57348112de31d5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9dcc21e3e79bf4b3dcfab233fb57348112de31d5
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Mon Jan 14 13:35:53 2013 -0600
winex11.drv: Don't join INCR data until the transfer finishes.
---
dlls/winex11.drv/clipboard.c | 68 +++++++++++++++++++++++++++++++++--------
1 files changed, 54 insertions(+), 14 deletions(-)
diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 0df355a..730b6c9 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -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;
More information about the wine-cvs
mailing list