Kusanagi Kouichi : winex11: Implement large data transfers.

Alexandre Julliard julliard at winehq.org
Thu Nov 6 08:25:56 CST 2008


Module: wine
Branch: master
Commit: fcaeffb7b494acc5acd5af165b7f5cf1a6080986
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=fcaeffb7b494acc5acd5af165b7f5cf1a6080986

Author: Kusanagi Kouichi <slash at ma.neweb.ne.jp>
Date:   Fri Oct 31 12:18:00 2008 +0900

winex11: Implement large data transfers.

---

 dlls/winex11.drv/clipboard.c   |  105 ++++++++++++++++++++++++++++++++++-----
 dlls/winex11.drv/x11drv.h      |    1 +
 dlls/winex11.drv/x11drv_main.c |    1 +
 3 files changed, 93 insertions(+), 14 deletions(-)

diff --git a/dlls/winex11.drv/clipboard.c b/dlls/winex11.drv/clipboard.c
index 8a35a0b..ec7d5ab 100644
--- a/dlls/winex11.drv/clipboard.c
+++ b/dlls/winex11.drv/clipboard.c
@@ -325,7 +325,7 @@ static Window thread_selection_wnd(void)
         XSetWindowAttributes attr;
 
         attr.event_mask = (ExposureMask | KeyPressMask | KeyReleaseMask | PointerMotionMask |
-                       ButtonPressMask | ButtonReleaseMask | EnterWindowMask);
+                       ButtonPressMask | ButtonReleaseMask | EnterWindowMask | PropertyChangeMask);
 
         wine_tsx11_lock();
         w = XCreateWindow(thread_data->display, root_window, 0, 0, 1, 1, 0, screen_depth,
@@ -1231,15 +1231,17 @@ static HANDLE X11DRV_CLIPBOARD_ImportCompoundText(Display *display, Window w, At
     HANDLE hUnicodeText;
     XTextProperty txtprop;
 
-    wine_tsx11_lock();
-    if (!XGetTextProperty(display, w, &txtprop, prop))
+    if (!X11DRV_CLIPBOARD_ReadProperty(display, w, prop, &txtprop.value, &txtprop.nitems))
     {
-        wine_tsx11_unlock();
         return 0;
     }
 
+    txtprop.encoding = x11drv_atom(COMPOUND_TEXT);
+    txtprop.format = 8;
+    wine_tsx11_lock();
     XmbTextPropertyToTextList(display, &txtprop, &srcstr, &count);
     wine_tsx11_unlock();
+    HeapFree(GetProcessHeap(), 0, txtprop.value);
 
     TRACE("Importing %d line(s)\n", count);
 
@@ -1276,7 +1278,6 @@ static HANDLE X11DRV_CLIPBOARD_ImportCompoundText(Display *display, Window w, At
 
     wine_tsx11_lock();
     XFreeStringList(srcstr);
-    XFree(txtprop.value);
     wine_tsx11_unlock();
 
     return hUnicodeText;
@@ -2017,27 +2018,23 @@ static BOOL X11DRV_CLIPBOARD_ReadSelectionData(Display *display, LPWINE_CLIPDATA
 
 
 /**************************************************************************
- *		X11DRV_CLIPBOARD_ReadProperty
- *  Reads the contents of the X selection property.
+ *		X11DRV_CLIPBOARD_GetProperty
+ *  Gets type, data and size.
  */
-static BOOL X11DRV_CLIPBOARD_ReadProperty(Display *display, Window w, Atom prop,
-    unsigned char** data, unsigned long* datasize)
+static BOOL X11DRV_CLIPBOARD_GetProperty(Display *display, Window w, Atom prop,
+    Atom *atype, unsigned char** data, unsigned long* datasize)
 {
-    Atom atype = AnyPropertyType;
     int aformat;
     unsigned long pos = 0, nitems, remain, count;
     unsigned char *val = NULL, *buffer;
 
-    if (prop == None)
-        return FALSE;
-
     TRACE("Reading property %lu from X window %lx\n", prop, w);
 
     for (;;)
     {
         wine_tsx11_lock();
         if (XGetWindowProperty(display, w, prop, pos, INT_MAX / 4, False,
-                               AnyPropertyType, &atype, &aformat, &nitems, &remain, &buffer) != Success)
+                               AnyPropertyType, atype, &aformat, &nitems, &remain, &buffer) != Success)
         {
             wine_tsx11_unlock();
             WARN("Failed to read property\n");
@@ -2079,6 +2076,86 @@ static BOOL X11DRV_CLIPBOARD_ReadProperty(Display *display, Window w, Atom prop,
 
 
 /**************************************************************************
+ *		X11DRV_CLIPBOARD_ReadProperty
+ *  Reads the contents of the X selection property.
+ */
+static BOOL X11DRV_CLIPBOARD_ReadProperty(Display *display, Window w, Atom prop,
+    unsigned char** data, unsigned long* datasize)
+{
+    Atom atype;
+    XEvent xe;
+
+    if (prop == None)
+        return FALSE;
+
+    if (!X11DRV_CLIPBOARD_GetProperty(display, w, prop, &atype, data, datasize))
+        return FALSE;
+
+    wine_tsx11_lock();
+    while (XCheckTypedWindowEvent(display, w, PropertyNotify, &xe))
+        ;
+    wine_tsx11_unlock();
+
+    if (atype == x11drv_atom(INCR))
+    {
+        unsigned char *buf = *data;
+        unsigned long bufsize = 0;
+
+        for (;;)
+        {
+            int i;
+            unsigned char *prop_data, *tmp;
+            unsigned long prop_size;
+
+            /* Wait until PropertyNotify is received */
+            for (i = 0; i < SELECTION_RETRIES; i++)
+            {
+                Bool res;
+
+                wine_tsx11_lock();
+                res = XCheckTypedWindowEvent(display, w, PropertyNotify, &xe);
+                wine_tsx11_unlock();
+                if (res && xe.xproperty.atom == prop &&
+                    xe.xproperty.state == PropertyNewValue)
+                    break;
+                usleep(SELECTION_WAIT);
+            }
+
+            if (i >= SELECTION_RETRIES ||
+                !X11DRV_CLIPBOARD_GetProperty(display, w, prop, &atype, &prop_data, &prop_size))
+            {
+                HeapFree(GetProcessHeap(), 0, buf);
+                return FALSE;
+            }
+
+            /* Retrieved entire data. */
+            if (prop_size == 0)
+            {
+                HeapFree(GetProcessHeap(), 0, prop_data);
+                *data = buf;
+                *datasize = bufsize;
+                return TRUE;
+            }
+
+            tmp = HeapReAlloc(GetProcessHeap(), 0, buf, bufsize + prop_size + 1);
+            if (!tmp)
+            {
+                HeapFree(GetProcessHeap(), 0, buf);
+                return FALSE;
+            }
+
+            buf = tmp;
+            memcpy(buf + bufsize, prop_data, prop_size + 1);
+            bufsize += prop_size;
+            HeapFree(GetProcessHeap(), 0, prop_data);
+        }
+    }
+
+    return TRUE;
+}
+
+
+/**************************************************************************
  *		CLIPBOARD_SerializeMetafile
  */
 static HANDLE X11DRV_CLIPBOARD_SerializeMetafile(INT wformat, HANDLE hdata, LPDWORD lpcbytes, BOOL out)
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 90ec95a..8a5a4b5 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -580,6 +580,7 @@ enum x11drv_atoms
     FIRST_XATOM = XA_LAST_PREDEFINED + 1,
     XATOM_CLIPBOARD = FIRST_XATOM,
     XATOM_COMPOUND_TEXT,
+    XATOM_INCR,
     XATOM_MULTIPLE,
     XATOM_SELECTION_DATA,
     XATOM_TARGETS,
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 1569481..c0c07c5 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -115,6 +115,7 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
 {
     "CLIPBOARD",
     "COMPOUND_TEXT",
+    "INCR",
     "MULTIPLE",
     "SELECTION_DATA",
     "TARGETS",




More information about the wine-cvs mailing list