winex11: Use format_entry to store cached XDND formats data.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f7ac2c7833
commit
d25c8c5770
|
@ -45,14 +45,7 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(xdnd);
|
WINE_DEFAULT_DEBUG_CHANNEL(xdnd);
|
||||||
|
|
||||||
typedef struct tagXDNDDATA
|
static struct format_entry *xdnd_formats, *xdnd_formats_end;
|
||||||
{
|
|
||||||
int cf_win;
|
|
||||||
HANDLE contents;
|
|
||||||
struct list entry;
|
|
||||||
} XDNDDATA, *LPXDNDDATA;
|
|
||||||
|
|
||||||
static struct list xdndData = LIST_INIT(xdndData);
|
|
||||||
static POINT XDNDxy = { 0, 0 };
|
static POINT XDNDxy = { 0, 0 };
|
||||||
static IDataObject XDNDDataObject;
|
static IDataObject XDNDDataObject;
|
||||||
static BOOL XDNDAccepted = FALSE;
|
static BOOL XDNDAccepted = FALSE;
|
||||||
|
@ -62,7 +55,6 @@ static HWND XDNDLastTargetWnd;
|
||||||
/* might be an ancestor of XDNDLastTargetWnd */
|
/* might be an ancestor of XDNDLastTargetWnd */
|
||||||
static HWND XDNDLastDropTargetWnd;
|
static HWND XDNDLastDropTargetWnd;
|
||||||
|
|
||||||
static void X11DRV_XDND_InsertXDNDData( UINT format, HANDLE contents );
|
|
||||||
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);
|
||||||
static BOOL X11DRV_XDND_HasHDROP(void);
|
static BOOL X11DRV_XDND_HasHDROP(void);
|
||||||
|
@ -529,7 +521,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)
|
||||||
{
|
{
|
||||||
struct format_entry *formats, *formats_end, *iter;
|
struct format_entry *formats;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
TRACE("count(%ld)\n", count);
|
TRACE("count(%ld)\n", count);
|
||||||
|
@ -537,41 +529,14 @@ static void X11DRV_XDND_ResolveProperty(Display *display, Window xwin, Time tm,
|
||||||
X11DRV_XDND_FreeDragDropOp(); /* Clear previously cached data */
|
X11DRV_XDND_FreeDragDropOp(); /* Clear previously cached data */
|
||||||
|
|
||||||
formats = import_xdnd_selection( display, xwin, x11drv_atom(XdndSelection), types, count, &size );
|
formats = import_xdnd_selection( display, xwin, x11drv_atom(XdndSelection), types, count, &size );
|
||||||
if (formats)
|
if (!formats) return;
|
||||||
{
|
|
||||||
formats_end = (struct format_entry *)((char *)formats + size);
|
|
||||||
for (iter = formats; iter < formats_end; iter = next_format( iter ))
|
|
||||||
{
|
|
||||||
HANDLE handle;
|
|
||||||
if ((handle = GlobalAlloc( GMEM_FIXED, iter->size )))
|
|
||||||
{
|
|
||||||
void *ptr = GlobalLock( handle );
|
|
||||||
memcpy( ptr, iter->data, iter->size );
|
|
||||||
GlobalUnlock( handle );
|
|
||||||
X11DRV_XDND_InsertXDNDData( iter->format, handle );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ((xdnd_formats = HeapAlloc( GetProcessHeap(), 0, size )))
|
||||||
/**************************************************************************
|
|
||||||
* X11DRV_XDND_InsertXDNDData
|
|
||||||
*
|
|
||||||
* Cache available XDND property
|
|
||||||
*/
|
|
||||||
static void X11DRV_XDND_InsertXDNDData( UINT format, HANDLE contents )
|
|
||||||
{
|
{
|
||||||
LPXDNDDATA current = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(XDNDDATA));
|
memcpy( xdnd_formats, formats, size );
|
||||||
|
xdnd_formats_end = (struct format_entry *)((char *)xdnd_formats + size);
|
||||||
if (current)
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&xdnd_cs);
|
|
||||||
current->cf_win = format;
|
|
||||||
current->contents = contents;
|
|
||||||
list_add_tail(&xdndData, ¤t->entry);
|
|
||||||
LeaveCriticalSection(&xdnd_cs);
|
|
||||||
}
|
}
|
||||||
|
free( formats );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -580,15 +545,15 @@ static void X11DRV_XDND_InsertXDNDData( UINT format, HANDLE contents )
|
||||||
*/
|
*/
|
||||||
static BOOL X11DRV_XDND_HasHDROP(void)
|
static BOOL X11DRV_XDND_HasHDROP(void)
|
||||||
{
|
{
|
||||||
LPXDNDDATA current = NULL;
|
struct format_entry *iter;
|
||||||
BOOL found = FALSE;
|
BOOL found = FALSE;
|
||||||
|
|
||||||
EnterCriticalSection(&xdnd_cs);
|
EnterCriticalSection(&xdnd_cs);
|
||||||
|
|
||||||
/* Find CF_HDROP type if any */
|
/* Find CF_HDROP type if any */
|
||||||
LIST_FOR_EACH_ENTRY(current, &xdndData, XDNDDATA, entry)
|
for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter ))
|
||||||
{
|
{
|
||||||
if (current->cf_win == CF_HDROP)
|
if (iter->format == CF_HDROP)
|
||||||
{
|
{
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -605,15 +570,15 @@ static BOOL X11DRV_XDND_HasHDROP(void)
|
||||||
*/
|
*/
|
||||||
static HRESULT X11DRV_XDND_SendDropFiles(HWND hwnd)
|
static HRESULT X11DRV_XDND_SendDropFiles(HWND hwnd)
|
||||||
{
|
{
|
||||||
|
struct format_entry *iter;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
LPXDNDDATA current = NULL;
|
|
||||||
BOOL found = FALSE;
|
BOOL found = FALSE;
|
||||||
|
|
||||||
EnterCriticalSection(&xdnd_cs);
|
EnterCriticalSection(&xdnd_cs);
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(current, &xdndData, XDNDDATA, entry)
|
for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter ))
|
||||||
{
|
{
|
||||||
if (current->cf_win == CF_HDROP)
|
if (iter->format == CF_HDROP)
|
||||||
{
|
{
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -621,13 +586,12 @@ static HRESULT X11DRV_XDND_SendDropFiles(HWND hwnd)
|
||||||
}
|
}
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
HGLOBAL dropHandle = GlobalAlloc(GMEM_FIXED, GlobalSize(current->contents));
|
HGLOBAL dropHandle = GlobalAlloc(GMEM_FIXED, iter->size);
|
||||||
if (dropHandle)
|
if (dropHandle)
|
||||||
{
|
{
|
||||||
RECT rect;
|
RECT rect;
|
||||||
DROPFILES *lpDrop = GlobalLock(dropHandle);
|
DROPFILES *lpDrop = GlobalLock(dropHandle);
|
||||||
memcpy(lpDrop, GlobalLock(current->contents), GlobalSize(current->contents));
|
memcpy(lpDrop, iter->data, iter->size);
|
||||||
GlobalUnlock(current->contents);
|
|
||||||
lpDrop->pt.x = XDNDxy.x;
|
lpDrop->pt.x = XDNDxy.x;
|
||||||
lpDrop->pt.y = XDNDxy.y;
|
lpDrop->pt.y = XDNDxy.y;
|
||||||
lpDrop->fNC = !(ScreenToClient(hwnd, &lpDrop->pt) &&
|
lpDrop->fNC = !(ScreenToClient(hwnd, &lpDrop->pt) &&
|
||||||
|
@ -662,20 +626,12 @@ static HRESULT X11DRV_XDND_SendDropFiles(HWND hwnd)
|
||||||
*/
|
*/
|
||||||
static void X11DRV_XDND_FreeDragDropOp(void)
|
static void X11DRV_XDND_FreeDragDropOp(void)
|
||||||
{
|
{
|
||||||
LPXDNDDATA next;
|
|
||||||
LPXDNDDATA current;
|
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
EnterCriticalSection(&xdnd_cs);
|
EnterCriticalSection(&xdnd_cs);
|
||||||
|
|
||||||
/** Free data cache */
|
HeapFree( GetProcessHeap(), 0, xdnd_formats );
|
||||||
LIST_FOR_EACH_ENTRY_SAFE(current, next, &xdndData, XDNDDATA, entry)
|
xdnd_formats = xdnd_formats_end = NULL;
|
||||||
{
|
|
||||||
list_remove(¤t->entry);
|
|
||||||
GlobalFree(current->contents);
|
|
||||||
HeapFree(GetProcessHeap(), 0, current);
|
|
||||||
}
|
|
||||||
|
|
||||||
XDNDxy.x = XDNDxy.y = 0;
|
XDNDxy.x = XDNDxy.y = 0;
|
||||||
XDNDLastTargetWnd = NULL;
|
XDNDLastTargetWnd = NULL;
|
||||||
|
@ -772,18 +728,18 @@ static HRESULT WINAPI XDNDDATAOBJECT_GetData(IDataObject *dataObject,
|
||||||
hr = IDataObject_QueryGetData(dataObject, formatEtc);
|
hr = IDataObject_QueryGetData(dataObject, formatEtc);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
XDNDDATA *current;
|
struct format_entry *iter;
|
||||||
LIST_FOR_EACH_ENTRY(current, &xdndData, XDNDDATA, entry)
|
|
||||||
|
for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter ))
|
||||||
{
|
{
|
||||||
if (current->cf_win == formatEtc->cfFormat)
|
if (iter->format == formatEtc->cfFormat)
|
||||||
{
|
{
|
||||||
pMedium->tymed = TYMED_HGLOBAL;
|
pMedium->tymed = TYMED_HGLOBAL;
|
||||||
pMedium->u.hGlobal = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, GlobalSize(current->contents));
|
pMedium->u.hGlobal = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, iter->size);
|
||||||
if (pMedium->u.hGlobal == NULL)
|
if (pMedium->u.hGlobal == NULL)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
memcpy(GlobalLock(pMedium->u.hGlobal), GlobalLock(current->contents), GlobalSize(current->contents));
|
memcpy(GlobalLock(pMedium->u.hGlobal), iter->data, iter->size);
|
||||||
GlobalUnlock(pMedium->u.hGlobal);
|
GlobalUnlock(pMedium->u.hGlobal);
|
||||||
GlobalUnlock(current->contents);
|
|
||||||
pMedium->pUnkForRelease = 0;
|
pMedium->pUnkForRelease = 0;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -803,8 +759,8 @@ static HRESULT WINAPI XDNDDATAOBJECT_GetDataHere(IDataObject *dataObject,
|
||||||
static HRESULT WINAPI XDNDDATAOBJECT_QueryGetData(IDataObject *dataObject,
|
static HRESULT WINAPI XDNDDATAOBJECT_QueryGetData(IDataObject *dataObject,
|
||||||
FORMATETC *formatEtc)
|
FORMATETC *formatEtc)
|
||||||
{
|
{
|
||||||
|
struct format_entry *iter;
|
||||||
char formatDesc[1024];
|
char formatDesc[1024];
|
||||||
XDNDDATA *current;
|
|
||||||
|
|
||||||
TRACE("(%p, %p={.tymed=0x%x, .dwAspect=%d, .cfFormat=%d}\n",
|
TRACE("(%p, %p={.tymed=0x%x, .dwAspect=%d, .cfFormat=%d}\n",
|
||||||
dataObject, formatEtc, formatEtc->tymed, formatEtc->dwAspect, formatEtc->cfFormat);
|
dataObject, formatEtc, formatEtc->tymed, formatEtc->dwAspect, formatEtc->cfFormat);
|
||||||
|
@ -819,9 +775,9 @@ static HRESULT WINAPI XDNDDATAOBJECT_QueryGetData(IDataObject *dataObject,
|
||||||
* and we have no way to implement them on XDnD anyway, so ignore them too.
|
* and we have no way to implement them on XDnD anyway, so ignore them too.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(current, &xdndData, XDNDDATA, entry)
|
for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter ))
|
||||||
{
|
{
|
||||||
if (current->cf_win == formatEtc->cfFormat)
|
if (iter->format == formatEtc->cfFormat)
|
||||||
{
|
{
|
||||||
TRACE("application found %s\n", formatDesc);
|
TRACE("application found %s\n", formatDesc);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -853,7 +809,8 @@ static HRESULT WINAPI XDNDDATAOBJECT_EnumFormatEtc(IDataObject *dataObject,
|
||||||
DWORD dwDirection,
|
DWORD dwDirection,
|
||||||
IEnumFORMATETC **ppEnumFormatEtc)
|
IEnumFORMATETC **ppEnumFormatEtc)
|
||||||
{
|
{
|
||||||
DWORD count;
|
struct format_entry *iter;
|
||||||
|
DWORD count = 0;
|
||||||
FORMATETC *formats;
|
FORMATETC *formats;
|
||||||
|
|
||||||
TRACE("(%p, %u, %p)\n", dataObject, dwDirection, ppEnumFormatEtc);
|
TRACE("(%p, %u, %p)\n", dataObject, dwDirection, ppEnumFormatEtc);
|
||||||
|
@ -864,16 +821,16 @@ static HRESULT WINAPI XDNDDATAOBJECT_EnumFormatEtc(IDataObject *dataObject,
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = list_count(&xdndData);
|
for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) count++;
|
||||||
|
|
||||||
formats = HeapAlloc(GetProcessHeap(), 0, count * sizeof(FORMATETC));
|
formats = HeapAlloc(GetProcessHeap(), 0, count * sizeof(FORMATETC));
|
||||||
if (formats)
|
if (formats)
|
||||||
{
|
{
|
||||||
XDNDDATA *current;
|
|
||||||
DWORD i = 0;
|
DWORD i = 0;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
LIST_FOR_EACH_ENTRY(current, &xdndData, XDNDDATA, entry)
|
for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter ))
|
||||||
{
|
{
|
||||||
formats[i].cfFormat = current->cf_win;
|
formats[i].cfFormat = iter->format;
|
||||||
formats[i].ptd = NULL;
|
formats[i].ptd = NULL;
|
||||||
formats[i].dwAspect = DVASPECT_CONTENT;
|
formats[i].dwAspect = DVASPECT_CONTENT;
|
||||||
formats[i].lindex = -1;
|
formats[i].lindex = -1;
|
||||||
|
|
Loading…
Reference in New Issue