Module: wine Branch: master Commit: fcaeffb7b494acc5acd5af165b7f5cf1a6080986 URL: http://source.winehq.org/git/wine.git/?a=commit;h=fcaeffb7b494acc5acd5af165b...
Author: Kusanagi Kouichi slash@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",