winex11: Merge converting the selection and importing it.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-09-21 12:01:15 +09:00
parent b19e99397f
commit 2215d770c5
4 changed files with 34 additions and 61 deletions

View File

@ -1225,17 +1225,32 @@ static HANDLE import_data( Atom type, const void *data, size_t size )
/************************************************************************** /**************************************************************************
* import_selection * import_selection
* *
* Import a selection target, depending on its type. * Import the specified format from the selection and return a global handle to the data.
*/ */
static HANDLE import_selection( Display *display, Window win, Atom prop, struct clipboard_format *format ) static HANDLE import_selection( Display *display, Window win, Atom selection,
struct clipboard_format *format )
{ {
unsigned char *data; unsigned char *data;
unsigned long size; unsigned long size;
Atom type; Atom prop, type;
HANDLE ret; HANDLE ret;
if (!format->import) return 0; if (!format->import) return 0;
if (!X11DRV_CLIPBOARD_ReadProperty( display, win, prop, &type, &data, &size )) return 0;
TRACE( "import %s from %s win %lx to format %s\n",
debugstr_xatom( format->atom ), debugstr_xatom( selection ),
win, debugstr_format( format->id ) );
if ((prop = convert_selection( display, win, selection, format->atom )) == None)
{
TRACE( "failed to convert selection\n" );
return 0;
}
if (!X11DRV_CLIPBOARD_ReadProperty( display, win, prop, &type, &data, &size ))
{
TRACE( "failed to read property\n" );
return 0;
}
ret = format->import( type, data, size ); ret = format->import( type, data, size );
HeapFree( GetProcessHeap(), 0, data ); HeapFree( GetProcessHeap(), 0, data );
return ret; return ret;
@ -1247,12 +1262,13 @@ static HANDLE import_selection( Display *display, Window win, Atom prop, struct
* *
* Import the X selection into the clipboard format registered for the given X target. * Import the X selection into the clipboard format registered for the given X target.
*/ */
HANDLE X11DRV_CLIPBOARD_ImportSelection(Display *display, Atom target, Window win, Atom prop, UINT *windowsFormat) HANDLE X11DRV_CLIPBOARD_ImportSelection( Display *display, Window win, Atom selection,
Atom target, UINT *windowsFormat )
{ {
struct clipboard_format *format = X11DRV_CLIPBOARD_LookupProperty( NULL, target ); struct clipboard_format *format = X11DRV_CLIPBOARD_LookupProperty( NULL, target );
if (!format) return 0; if (!format) return 0;
*windowsFormat = format->id; *windowsFormat = format->id;
return import_selection( display, win, prop, format ); return import_selection( display, win, selection, format );
} }
@ -1872,9 +1888,7 @@ static int X11DRV_CLIPBOARD_QueryAvailableData(Display *display)
static BOOL X11DRV_CLIPBOARD_ReadSelectionData(Display *display, LPWINE_CLIPDATA lpData) static BOOL X11DRV_CLIPBOARD_ReadSelectionData(Display *display, LPWINE_CLIPDATA lpData)
{ {
BOOL bRet = FALSE; BOOL bRet = FALSE;
Atom prop; HANDLE hData;
TRACE("%04x\n", lpData->wFormatID);
if (!lpData->lpFormat) if (!lpData->lpFormat)
{ {
@ -1892,28 +1906,9 @@ static BOOL X11DRV_CLIPBOARD_ReadSelectionData(Display *display, LPWINE_CLIPDATA
return FALSE; return FALSE;
} }
TRACE("Requesting conversion of %s property %s from selection type %08x\n", hData = import_selection( display, w, selectionCacheSrc, lpData->lpFormat );
debugstr_format( lpData->lpFormat->id ), debugstr_xatom( lpData->lpFormat->atom ), if (hData)
(UINT)selectionCacheSrc); bRet = X11DRV_CLIPBOARD_InsertClipboardData(lpData->wFormatID, hData, lpData->lpFormat, TRUE);
prop = convert_selection( display, w, selectionCacheSrc, lpData->lpFormat->atom );
if (prop != None)
{
/*
* Read the contents of the X selection property
* into WINE's clipboard cache and converting the
* data format if necessary.
*/
HANDLE hData = import_selection( display, w, prop, lpData->lpFormat );
if (hData)
bRet = X11DRV_CLIPBOARD_InsertClipboardData(lpData->wFormatID, hData, lpData->lpFormat, TRUE);
else
TRACE("Import function failed\n");
}
else
{
TRACE("Failed to convert selection\n");
}
} }
else else
{ {
@ -1937,8 +1932,6 @@ static BOOL X11DRV_CLIPBOARD_GetProperty(Display *display, Window w, Atom prop,
unsigned long pos = 0, nitems, remain, count; unsigned long pos = 0, nitems, remain, count;
unsigned char *val = NULL, *buffer; unsigned char *val = NULL, *buffer;
TRACE( "Reading property %s from X window %lx\n", debugstr_xatom( prop ), w );
for (;;) for (;;)
{ {
if (XGetWindowProperty(display, w, prop, pos, INT_MAX / 4, False, if (XGetWindowProperty(display, w, prop, pos, INT_MAX / 4, False,
@ -1971,6 +1964,9 @@ static BOOL X11DRV_CLIPBOARD_GetProperty(Display *display, Window w, Atom prop,
pos += count / sizeof(int); pos += count / sizeof(int);
} }
TRACE( "got property %s type %s format %u len %lu from window %lx\n",
debugstr_xatom( prop ), debugstr_xatom( *atype ), aformat, *datasize, w );
/* Delete the property on the window now that we are done /* Delete the property on the window now that we are done
* This will send a PropertyNotify event to the selection owner. */ * This will send a PropertyNotify event to the selection owner. */
XDeleteProperty(display, w, prop); XDeleteProperty(display, w, prop);

View File

@ -239,7 +239,8 @@ extern void X11DRV_XDND_EnterEvent( HWND hWnd, XClientMessageEvent *event ) DECL
extern void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN; extern void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
extern void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN; extern void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
extern void X11DRV_XDND_LeaveEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN; extern void X11DRV_XDND_LeaveEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
extern HANDLE X11DRV_CLIPBOARD_ImportSelection(Display *d, Atom target, Window w, Atom prop, UINT *windowsFormat) DECLSPEC_HIDDEN; extern HANDLE X11DRV_CLIPBOARD_ImportSelection( Display *display, Window win, Atom selection,
Atom target, UINT *windowsFormat ) DECLSPEC_HIDDEN;
/************************************************************************** /**************************************************************************
* X11 GDI driver * X11 GDI driver
@ -453,7 +454,6 @@ enum x11drv_atoms
XATOM_XdndActionAsk, XATOM_XdndActionAsk,
XATOM_XdndActionPrivate, XATOM_XdndActionPrivate,
XATOM_XdndSelection, XATOM_XdndSelection,
XATOM_XdndTarget,
XATOM_XdndTypeList, XATOM_XdndTypeList,
XATOM_HTML_Format, XATOM_HTML_Format,
XATOM_WCF_BITMAP, XATOM_WCF_BITMAP,

View File

@ -167,7 +167,6 @@ static const char * const atom_names[NB_XATOMS - FIRST_XATOM] =
"XdndActionAsk", "XdndActionAsk",
"XdndActionPrivate", "XdndActionPrivate",
"XdndSelection", "XdndSelection",
"XdndTarget",
"XdndTypeList", "XdndTypeList",
"HTML Format", "HTML Format",
"WCF_BITMAP", "WCF_BITMAP",

View File

@ -49,10 +49,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(xdnd); WINE_DEFAULT_DEBUG_CHANNEL(xdnd);
/* Maximum wait time for selection notify */
#define SELECTION_RETRIES 500 /* wait for .1 seconds */
#define SELECTION_WAIT 1000 /* us */
typedef struct tagXDNDDATA typedef struct tagXDNDDATA
{ {
int cf_win; int cf_win;
@ -496,9 +492,7 @@ void X11DRV_XDND_LeaveEvent( HWND hWnd, XClientMessageEvent *event )
static void X11DRV_XDND_ResolveProperty(Display *display, Window xwin, Time tm, static void X11DRV_XDND_ResolveProperty(Display *display, Window xwin, Time tm,
Atom *types, unsigned long count) Atom *types, unsigned long count)
{ {
unsigned int i, j; unsigned int i;
BOOL res;
XEvent xe;
XDNDDATA *current, *next; XDNDDATA *current, *next;
BOOL haveHDROP = FALSE; BOOL haveHDROP = FALSE;
@ -516,24 +510,8 @@ static void X11DRV_XDND_ResolveProperty(Display *display, Window xwin, Time tm,
if (types[i] == 0) if (types[i] == 0)
continue; continue;
XConvertSelection(display, x11drv_atom(XdndSelection), types[i], contents = X11DRV_CLIPBOARD_ImportSelection( display, xwin, x11drv_atom(XdndSelection),
x11drv_atom(XdndTarget), xwin, /*tm*/CurrentTime); types[i], &windowsFormat );
/*
* Wait for SelectionNotify
*/
for (j = 0; j < SELECTION_RETRIES; j++)
{
res = XCheckTypedWindowEvent(display, xwin, SelectionNotify, &xe);
if (res && xe.xselection.selection == x11drv_atom(XdndSelection)) break;
usleep(SELECTION_WAIT);
}
if (xe.xselection.property == None)
continue;
contents = X11DRV_CLIPBOARD_ImportSelection(display, types[i], xwin, x11drv_atom(XdndTarget), &windowsFormat);
if (contents) if (contents)
X11DRV_XDND_InsertXDNDData(types[i], windowsFormat, contents); X11DRV_XDND_InsertXDNDData(types[i], windowsFormat, contents);
} }