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