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