In preparation for moving the PE side DND code to win32u/user32 and factoring it between drivers.
-- v2: winex11: Allocate the XDND data object dynamically. winex11: Use IDataObject to get CF_HDROP format for WM_DROPFILES. winex11: Cleanup variable names in X11DRV_XDND_SendDropFiles. winex11: Use the IDataObject interface to check for CF_HDROP format. winex11: Cleanup XDND IDataObject methods and variables. winex11: Move the XDND IDataObject implementation around.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/xdnd.c | 490 ++++++++++++++++++++-------------------- 1 file changed, 244 insertions(+), 246 deletions(-)
diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index edf47d9be2e..7b9b50ecd87 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -60,6 +60,250 @@ static struct format_entry *next_format( struct format_entry *entry ) return (struct format_entry *)&entry->data[(entry->size + 7) & ~7]; }
+/************************************************************************** + * X11DRV_XDND_DescribeClipboardFormat + */ +static void X11DRV_XDND_DescribeClipboardFormat(int cfFormat, char *buffer, int size) +{ +#define D(x) case x: lstrcpynA(buffer, #x, size); return; + switch (cfFormat) + { + D(CF_TEXT) + D(CF_BITMAP) + D(CF_METAFILEPICT) + D(CF_SYLK) + D(CF_DIF) + D(CF_TIFF) + D(CF_OEMTEXT) + D(CF_DIB) + D(CF_PALETTE) + D(CF_PENDATA) + D(CF_RIFF) + D(CF_WAVE) + D(CF_UNICODETEXT) + D(CF_ENHMETAFILE) + D(CF_HDROP) + D(CF_LOCALE) + D(CF_DIBV5) + } +#undef D + + if (CF_PRIVATEFIRST <= cfFormat && cfFormat <= CF_PRIVATELAST) + { + lstrcpynA(buffer, "some private object", size); + return; + } + if (CF_GDIOBJFIRST <= cfFormat && cfFormat <= CF_GDIOBJLAST) + { + lstrcpynA(buffer, "some GDI object", size); + return; + } + + GetClipboardFormatNameA(cfFormat, buffer, size); +} + +/* The IDataObject singleton we feed to OLE follows */ + +static HRESULT WINAPI XDNDDATAOBJECT_QueryInterface(IDataObject *dataObject, + REFIID riid, void **ppvObject) +{ + TRACE("(%p, %s, %p)\n", dataObject, debugstr_guid(riid), ppvObject); + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDataObject)) + { + *ppvObject = dataObject; + IDataObject_AddRef(dataObject); + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI XDNDDATAOBJECT_AddRef(IDataObject *dataObject) +{ + TRACE("(%p)\n", dataObject); + return 2; +} + +static ULONG WINAPI XDNDDATAOBJECT_Release(IDataObject *dataObject) +{ + TRACE("(%p)\n", dataObject); + return 1; +} + +static HRESULT WINAPI XDNDDATAOBJECT_GetData(IDataObject *dataObject, + FORMATETC *formatEtc, + STGMEDIUM *pMedium) +{ + HRESULT hr; + char formatDesc[1024]; + + TRACE("(%p, %p, %p)\n", dataObject, formatEtc, pMedium); + X11DRV_XDND_DescribeClipboardFormat(formatEtc->cfFormat, + formatDesc, sizeof(formatDesc)); + TRACE("application is looking for %s\n", formatDesc); + + hr = IDataObject_QueryGetData(dataObject, formatEtc); + if (SUCCEEDED(hr)) + { + struct format_entry *iter; + + for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) + { + if (iter->format == formatEtc->cfFormat) + { + pMedium->tymed = TYMED_HGLOBAL; + pMedium->hGlobal = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, iter->size); + if (pMedium->hGlobal == NULL) + return E_OUTOFMEMORY; + memcpy(GlobalLock(pMedium->hGlobal), iter->data, iter->size); + GlobalUnlock(pMedium->hGlobal); + pMedium->pUnkForRelease = 0; + return S_OK; + } + } + } + return hr; +} + +static HRESULT WINAPI XDNDDATAOBJECT_GetDataHere(IDataObject *dataObject, + FORMATETC *formatEtc, + STGMEDIUM *pMedium) +{ + FIXME("(%p, %p, %p): stub\n", dataObject, formatEtc, pMedium); + return DATA_E_FORMATETC; +} + +static HRESULT WINAPI XDNDDATAOBJECT_QueryGetData(IDataObject *dataObject, + FORMATETC *formatEtc) +{ + struct format_entry *iter; + char formatDesc[1024]; + + TRACE("(%p, %p={.tymed=0x%lx, .dwAspect=%ld, .cfFormat=%d}\n", + dataObject, formatEtc, formatEtc->tymed, formatEtc->dwAspect, formatEtc->cfFormat); + X11DRV_XDND_DescribeClipboardFormat(formatEtc->cfFormat, formatDesc, sizeof(formatDesc)); + + if (formatEtc->tymed && !(formatEtc->tymed & TYMED_HGLOBAL)) + { + FIXME("only HGLOBAL medium types supported right now\n"); + return DV_E_TYMED; + } + /* Windows Explorer ignores .dwAspect and .lindex for CF_HDROP, + * and we have no way to implement them on XDnD anyway, so ignore them too. + */ + + for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) + { + if (iter->format == formatEtc->cfFormat) + { + TRACE("application found %s\n", formatDesc); + return S_OK; + } + } + TRACE("application didn't find %s\n", formatDesc); + return DV_E_FORMATETC; +} + +static HRESULT WINAPI XDNDDATAOBJECT_GetCanonicalFormatEtc(IDataObject *dataObject, + FORMATETC *formatEtc, + FORMATETC *formatEtcOut) +{ + FIXME("(%p, %p, %p): stub\n", dataObject, formatEtc, formatEtcOut); + formatEtcOut->ptd = NULL; + return E_NOTIMPL; +} + +static HRESULT WINAPI XDNDDATAOBJECT_SetData(IDataObject *dataObject, + FORMATETC *formatEtc, + STGMEDIUM *pMedium, BOOL fRelease) +{ + FIXME("(%p, %p, %p, %s): stub\n", dataObject, formatEtc, + pMedium, fRelease?"TRUE":"FALSE"); + return E_NOTIMPL; +} + +static HRESULT WINAPI XDNDDATAOBJECT_EnumFormatEtc(IDataObject *dataObject, + DWORD dwDirection, + IEnumFORMATETC **ppEnumFormatEtc) +{ + struct format_entry *iter; + DWORD count = 0; + FORMATETC *formats; + + TRACE("(%p, %lu, %p)\n", dataObject, dwDirection, ppEnumFormatEtc); + + if (dwDirection != DATADIR_GET) + { + FIXME("only the get direction is implemented\n"); + return E_NOTIMPL; + } + + for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) count++; + + formats = HeapAlloc(GetProcessHeap(), 0, count * sizeof(FORMATETC)); + if (formats) + { + DWORD i = 0; + HRESULT hr; + for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) + { + formats[i].cfFormat = iter->format; + formats[i].ptd = NULL; + formats[i].dwAspect = DVASPECT_CONTENT; + formats[i].lindex = -1; + formats[i].tymed = TYMED_HGLOBAL; + i++; + } + hr = SHCreateStdEnumFmtEtc(count, formats, ppEnumFormatEtc); + HeapFree(GetProcessHeap(), 0, formats); + return hr; + } + else + return E_OUTOFMEMORY; +} + +static HRESULT WINAPI XDNDDATAOBJECT_DAdvise(IDataObject *dataObject, + FORMATETC *formatEtc, DWORD advf, + IAdviseSink *adviseSink, + DWORD *pdwConnection) +{ + FIXME("(%p, %p, %lu, %p, %p): stub\n", dataObject, formatEtc, advf, + adviseSink, pdwConnection); + return OLE_E_ADVISENOTSUPPORTED; +} + +static HRESULT WINAPI XDNDDATAOBJECT_DUnadvise(IDataObject *dataObject, + DWORD dwConnection) +{ + FIXME("(%p, %lu): stub\n", dataObject, dwConnection); + return OLE_E_ADVISENOTSUPPORTED; +} + +static HRESULT WINAPI XDNDDATAOBJECT_EnumDAdvise(IDataObject *dataObject, + IEnumSTATDATA **pEnumAdvise) +{ + FIXME("(%p, %p): stub\n", dataObject, pEnumAdvise); + return OLE_E_ADVISENOTSUPPORTED; +} + +static IDataObjectVtbl xdndDataObjectVtbl = +{ + XDNDDATAOBJECT_QueryInterface, + XDNDDATAOBJECT_AddRef, + XDNDDATAOBJECT_Release, + XDNDDATAOBJECT_GetData, + XDNDDATAOBJECT_GetDataHere, + XDNDDATAOBJECT_QueryGetData, + XDNDDATAOBJECT_GetCanonicalFormatEtc, + XDNDDATAOBJECT_SetData, + XDNDDATAOBJECT_EnumFormatEtc, + XDNDDATAOBJECT_DAdvise, + XDNDDATAOBJECT_DUnadvise, + XDNDDATAOBJECT_EnumDAdvise +}; + +static IDataObject XDNDDataObject = { &xdndDataObjectVtbl }; +
/* Based on functions in dlls/ole32/ole2.c */ static HANDLE get_droptarget_local_handle(HWND hwnd) @@ -477,252 +721,6 @@ static void X11DRV_XDND_FreeDragDropOp(void) LeaveCriticalSection(&xdnd_cs); }
- -/************************************************************************** - * X11DRV_XDND_DescribeClipboardFormat - */ -static void X11DRV_XDND_DescribeClipboardFormat(int cfFormat, char *buffer, int size) -{ -#define D(x) case x: lstrcpynA(buffer, #x, size); return; - switch (cfFormat) - { - D(CF_TEXT) - D(CF_BITMAP) - D(CF_METAFILEPICT) - D(CF_SYLK) - D(CF_DIF) - D(CF_TIFF) - D(CF_OEMTEXT) - D(CF_DIB) - D(CF_PALETTE) - D(CF_PENDATA) - D(CF_RIFF) - D(CF_WAVE) - D(CF_UNICODETEXT) - D(CF_ENHMETAFILE) - D(CF_HDROP) - D(CF_LOCALE) - D(CF_DIBV5) - } -#undef D - - if (CF_PRIVATEFIRST <= cfFormat && cfFormat <= CF_PRIVATELAST) - { - lstrcpynA(buffer, "some private object", size); - return; - } - if (CF_GDIOBJFIRST <= cfFormat && cfFormat <= CF_GDIOBJLAST) - { - lstrcpynA(buffer, "some GDI object", size); - return; - } - - GetClipboardFormatNameA(cfFormat, buffer, size); -} - - -/* The IDataObject singleton we feed to OLE follows */ - -static HRESULT WINAPI XDNDDATAOBJECT_QueryInterface(IDataObject *dataObject, - REFIID riid, void **ppvObject) -{ - TRACE("(%p, %s, %p)\n", dataObject, debugstr_guid(riid), ppvObject); - if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDataObject)) - { - *ppvObject = dataObject; - IDataObject_AddRef(dataObject); - return S_OK; - } - *ppvObject = NULL; - return E_NOINTERFACE; -} - -static ULONG WINAPI XDNDDATAOBJECT_AddRef(IDataObject *dataObject) -{ - TRACE("(%p)\n", dataObject); - return 2; -} - -static ULONG WINAPI XDNDDATAOBJECT_Release(IDataObject *dataObject) -{ - TRACE("(%p)\n", dataObject); - return 1; -} - -static HRESULT WINAPI XDNDDATAOBJECT_GetData(IDataObject *dataObject, - FORMATETC *formatEtc, - STGMEDIUM *pMedium) -{ - HRESULT hr; - char formatDesc[1024]; - - TRACE("(%p, %p, %p)\n", dataObject, formatEtc, pMedium); - X11DRV_XDND_DescribeClipboardFormat(formatEtc->cfFormat, - formatDesc, sizeof(formatDesc)); - TRACE("application is looking for %s\n", formatDesc); - - hr = IDataObject_QueryGetData(dataObject, formatEtc); - if (SUCCEEDED(hr)) - { - struct format_entry *iter; - - for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) - { - if (iter->format == formatEtc->cfFormat) - { - pMedium->tymed = TYMED_HGLOBAL; - pMedium->hGlobal = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, iter->size); - if (pMedium->hGlobal == NULL) - return E_OUTOFMEMORY; - memcpy(GlobalLock(pMedium->hGlobal), iter->data, iter->size); - GlobalUnlock(pMedium->hGlobal); - pMedium->pUnkForRelease = 0; - return S_OK; - } - } - } - return hr; -} - -static HRESULT WINAPI XDNDDATAOBJECT_GetDataHere(IDataObject *dataObject, - FORMATETC *formatEtc, - STGMEDIUM *pMedium) -{ - FIXME("(%p, %p, %p): stub\n", dataObject, formatEtc, pMedium); - return DATA_E_FORMATETC; -} - -static HRESULT WINAPI XDNDDATAOBJECT_QueryGetData(IDataObject *dataObject, - FORMATETC *formatEtc) -{ - struct format_entry *iter; - char formatDesc[1024]; - - TRACE("(%p, %p={.tymed=0x%lx, .dwAspect=%ld, .cfFormat=%d}\n", - dataObject, formatEtc, formatEtc->tymed, formatEtc->dwAspect, formatEtc->cfFormat); - X11DRV_XDND_DescribeClipboardFormat(formatEtc->cfFormat, formatDesc, sizeof(formatDesc)); - - if (formatEtc->tymed && !(formatEtc->tymed & TYMED_HGLOBAL)) - { - FIXME("only HGLOBAL medium types supported right now\n"); - return DV_E_TYMED; - } - /* Windows Explorer ignores .dwAspect and .lindex for CF_HDROP, - * and we have no way to implement them on XDnD anyway, so ignore them too. - */ - - for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) - { - if (iter->format == formatEtc->cfFormat) - { - TRACE("application found %s\n", formatDesc); - return S_OK; - } - } - TRACE("application didn't find %s\n", formatDesc); - return DV_E_FORMATETC; -} - -static HRESULT WINAPI XDNDDATAOBJECT_GetCanonicalFormatEtc(IDataObject *dataObject, - FORMATETC *formatEtc, - FORMATETC *formatEtcOut) -{ - FIXME("(%p, %p, %p): stub\n", dataObject, formatEtc, formatEtcOut); - formatEtcOut->ptd = NULL; - return E_NOTIMPL; -} - -static HRESULT WINAPI XDNDDATAOBJECT_SetData(IDataObject *dataObject, - FORMATETC *formatEtc, - STGMEDIUM *pMedium, BOOL fRelease) -{ - FIXME("(%p, %p, %p, %s): stub\n", dataObject, formatEtc, - pMedium, fRelease?"TRUE":"FALSE"); - return E_NOTIMPL; -} - -static HRESULT WINAPI XDNDDATAOBJECT_EnumFormatEtc(IDataObject *dataObject, - DWORD dwDirection, - IEnumFORMATETC **ppEnumFormatEtc) -{ - struct format_entry *iter; - DWORD count = 0; - FORMATETC *formats; - - TRACE("(%p, %lu, %p)\n", dataObject, dwDirection, ppEnumFormatEtc); - - if (dwDirection != DATADIR_GET) - { - FIXME("only the get direction is implemented\n"); - return E_NOTIMPL; - } - - for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) count++; - - formats = HeapAlloc(GetProcessHeap(), 0, count * sizeof(FORMATETC)); - if (formats) - { - DWORD i = 0; - HRESULT hr; - for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) - { - formats[i].cfFormat = iter->format; - formats[i].ptd = NULL; - formats[i].dwAspect = DVASPECT_CONTENT; - formats[i].lindex = -1; - formats[i].tymed = TYMED_HGLOBAL; - i++; - } - hr = SHCreateStdEnumFmtEtc(count, formats, ppEnumFormatEtc); - HeapFree(GetProcessHeap(), 0, formats); - return hr; - } - else - return E_OUTOFMEMORY; -} - -static HRESULT WINAPI XDNDDATAOBJECT_DAdvise(IDataObject *dataObject, - FORMATETC *formatEtc, DWORD advf, - IAdviseSink *adviseSink, - DWORD *pdwConnection) -{ - FIXME("(%p, %p, %lu, %p, %p): stub\n", dataObject, formatEtc, advf, - adviseSink, pdwConnection); - return OLE_E_ADVISENOTSUPPORTED; -} - -static HRESULT WINAPI XDNDDATAOBJECT_DUnadvise(IDataObject *dataObject, - DWORD dwConnection) -{ - FIXME("(%p, %lu): stub\n", dataObject, dwConnection); - return OLE_E_ADVISENOTSUPPORTED; -} - -static HRESULT WINAPI XDNDDATAOBJECT_EnumDAdvise(IDataObject *dataObject, - IEnumSTATDATA **pEnumAdvise) -{ - FIXME("(%p, %p): stub\n", dataObject, pEnumAdvise); - return OLE_E_ADVISENOTSUPPORTED; -} - -static IDataObjectVtbl xdndDataObjectVtbl = -{ - XDNDDATAOBJECT_QueryInterface, - XDNDDATAOBJECT_AddRef, - XDNDDATAOBJECT_Release, - XDNDDATAOBJECT_GetData, - XDNDDATAOBJECT_GetDataHere, - XDNDDATAOBJECT_QueryGetData, - XDNDDATAOBJECT_GetCanonicalFormatEtc, - XDNDDATAOBJECT_SetData, - XDNDDATAOBJECT_EnumFormatEtc, - XDNDDATAOBJECT_DAdvise, - XDNDDATAOBJECT_DUnadvise, - XDNDDATAOBJECT_EnumDAdvise -}; - -static IDataObject XDNDDataObject = { &xdndDataObjectVtbl }; - NTSTATUS WINAPI x11drv_dnd_post_drop( void *args, ULONG size ) { UINT drop_size = size - offsetof(struct dnd_post_drop_params, drop);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/xdnd.c | 261 +++++++++++++++++----------------------- 1 file changed, 111 insertions(+), 150 deletions(-)
diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index 7b9b50ecd87..4bc7a32f1e8 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -33,7 +33,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(xdnd);
static struct format_entry *xdnd_formats, *xdnd_formats_end; static POINT XDNDxy = { 0, 0 }; -static IDataObject XDNDDataObject; +static IDataObject xdnd_data_object; static BOOL XDNDAccepted = FALSE; static DWORD XDNDDropEffect = DROPEFFECT_NONE; /* the last window the mouse was over */ @@ -60,130 +60,108 @@ static struct format_entry *next_format( struct format_entry *entry ) return (struct format_entry *)&entry->data[(entry->size + 7) & ~7]; }
-/************************************************************************** - * X11DRV_XDND_DescribeClipboardFormat - */ -static void X11DRV_XDND_DescribeClipboardFormat(int cfFormat, char *buffer, int size) +static const char *debugstr_format( int format ) { -#define D(x) case x: lstrcpynA(buffer, #x, size); return; - switch (cfFormat) - { - D(CF_TEXT) - D(CF_BITMAP) - D(CF_METAFILEPICT) - D(CF_SYLK) - D(CF_DIF) - D(CF_TIFF) - D(CF_OEMTEXT) - D(CF_DIB) - D(CF_PALETTE) - D(CF_PENDATA) - D(CF_RIFF) - D(CF_WAVE) - D(CF_UNICODETEXT) - D(CF_ENHMETAFILE) - D(CF_HDROP) - D(CF_LOCALE) - D(CF_DIBV5) - } -#undef D - - if (CF_PRIVATEFIRST <= cfFormat && cfFormat <= CF_PRIVATELAST) - { - lstrcpynA(buffer, "some private object", size); - return; - } - if (CF_GDIOBJFIRST <= cfFormat && cfFormat <= CF_GDIOBJLAST) + WCHAR buffer[256]; + switch (format) { - lstrcpynA(buffer, "some GDI object", size); - return; +#define X(x) case x: return #x; + X(CF_TEXT) + X(CF_BITMAP) + X(CF_METAFILEPICT) + X(CF_SYLK) + X(CF_DIF) + X(CF_TIFF) + X(CF_OEMTEXT) + X(CF_DIB) + X(CF_PALETTE) + X(CF_PENDATA) + X(CF_RIFF) + X(CF_WAVE) + X(CF_UNICODETEXT) + X(CF_ENHMETAFILE) + X(CF_HDROP) + X(CF_LOCALE) + X(CF_DIBV5) +#undef X }
- GetClipboardFormatNameA(cfFormat, buffer, size); + if (CF_PRIVATEFIRST <= format && format <= CF_PRIVATELAST) return "some private object"; + if (CF_GDIOBJFIRST <= format && format <= CF_GDIOBJLAST) return "some GDI object"; + GetClipboardFormatNameW( format, buffer, sizeof(buffer) ); + return debugstr_w( buffer ); }
+ /* The IDataObject singleton we feed to OLE follows */
-static HRESULT WINAPI XDNDDATAOBJECT_QueryInterface(IDataObject *dataObject, - REFIID riid, void **ppvObject) +static HRESULT WINAPI data_object_QueryInterface( IDataObject *iface, REFIID iid, void **obj ) { - TRACE("(%p, %s, %p)\n", dataObject, debugstr_guid(riid), ppvObject); - if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDataObject)) + TRACE( "iface %p, iid %s, obj %p\n", iface, debugstr_guid(iid), obj ); + + if (IsEqualIID( iid, &IID_IUnknown ) || IsEqualIID( iid, &IID_IDataObject )) { - *ppvObject = dataObject; - IDataObject_AddRef(dataObject); + IDataObject_AddRef( iface ); + *obj = iface; return S_OK; } - *ppvObject = NULL; + + *obj = NULL; + WARN( "%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid) ); return E_NOINTERFACE; }
-static ULONG WINAPI XDNDDATAOBJECT_AddRef(IDataObject *dataObject) +static ULONG WINAPI data_object_AddRef( IDataObject *iface ) { - TRACE("(%p)\n", dataObject); + TRACE( "iface %p\n", iface ); return 2; }
-static ULONG WINAPI XDNDDATAOBJECT_Release(IDataObject *dataObject) +static ULONG WINAPI data_object_Release( IDataObject *iface ) { - TRACE("(%p)\n", dataObject); + TRACE( "iface %p\n", iface ); return 1; }
-static HRESULT WINAPI XDNDDATAOBJECT_GetData(IDataObject *dataObject, - FORMATETC *formatEtc, - STGMEDIUM *pMedium) +static HRESULT WINAPI data_object_GetData( IDataObject *iface, FORMATETC *format, STGMEDIUM *medium ) { + struct format_entry *iter; HRESULT hr; - char formatDesc[1024];
- TRACE("(%p, %p, %p)\n", dataObject, formatEtc, pMedium); - X11DRV_XDND_DescribeClipboardFormat(formatEtc->cfFormat, - formatDesc, sizeof(formatDesc)); - TRACE("application is looking for %s\n", formatDesc); + TRACE( "iface %p, format %p (%s), medium %p\n", iface, format, debugstr_format(format->cfFormat), medium );
- hr = IDataObject_QueryGetData(dataObject, formatEtc); - if (SUCCEEDED(hr)) - { - struct format_entry *iter; + if (FAILED(hr = IDataObject_QueryGetData( iface, format ))) return hr;
- for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) + for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) + { + if (iter->format == format->cfFormat) { - if (iter->format == formatEtc->cfFormat) - { - pMedium->tymed = TYMED_HGLOBAL; - pMedium->hGlobal = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, iter->size); - if (pMedium->hGlobal == NULL) - return E_OUTOFMEMORY; - memcpy(GlobalLock(pMedium->hGlobal), iter->data, iter->size); - GlobalUnlock(pMedium->hGlobal); - pMedium->pUnkForRelease = 0; - return S_OK; - } + medium->tymed = TYMED_HGLOBAL; + medium->hGlobal = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, iter->size ); + if (medium->hGlobal == NULL) return E_OUTOFMEMORY; + memcpy( GlobalLock( medium->hGlobal ), iter->data, iter->size ); + GlobalUnlock( medium->hGlobal ); + medium->pUnkForRelease = 0; + return S_OK; } } - return hr; + + return DATA_E_FORMATETC; }
-static HRESULT WINAPI XDNDDATAOBJECT_GetDataHere(IDataObject *dataObject, - FORMATETC *formatEtc, - STGMEDIUM *pMedium) +static HRESULT WINAPI data_object_GetDataHere( IDataObject *iface, FORMATETC *format, STGMEDIUM *medium ) { - FIXME("(%p, %p, %p): stub\n", dataObject, formatEtc, pMedium); + FIXME( "iface %p, format %p, medium %p stub!\n", iface, format, medium ); return DATA_E_FORMATETC; }
-static HRESULT WINAPI XDNDDATAOBJECT_QueryGetData(IDataObject *dataObject, - FORMATETC *formatEtc) +static HRESULT WINAPI data_object_QueryGetData( IDataObject *iface, FORMATETC *format ) { struct format_entry *iter; - char formatDesc[1024];
- TRACE("(%p, %p={.tymed=0x%lx, .dwAspect=%ld, .cfFormat=%d}\n", - dataObject, formatEtc, formatEtc->tymed, formatEtc->dwAspect, formatEtc->cfFormat); - X11DRV_XDND_DescribeClipboardFormat(formatEtc->cfFormat, formatDesc, sizeof(formatDesc)); + TRACE( "iface %p, format %p (%s)\n", iface, format, debugstr_format(format->cfFormat) );
- if (formatEtc->tymed && !(formatEtc->tymed & TYMED_HGLOBAL)) + if (format->tymed && !(format->tymed & TYMED_HGLOBAL)) { FIXME("only HGLOBAL medium types supported right now\n"); return DV_E_TYMED; @@ -194,45 +172,39 @@ static HRESULT WINAPI XDNDDATAOBJECT_QueryGetData(IDataObject *dataObject,
for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) { - if (iter->format == formatEtc->cfFormat) + if (iter->format == format->cfFormat) { - TRACE("application found %s\n", formatDesc); + TRACE("application found %s\n", debugstr_format(format->cfFormat)); return S_OK; } } - TRACE("application didn't find %s\n", formatDesc); + TRACE("application didn't find %s\n", debugstr_format(format->cfFormat)); return DV_E_FORMATETC; }
-static HRESULT WINAPI XDNDDATAOBJECT_GetCanonicalFormatEtc(IDataObject *dataObject, - FORMATETC *formatEtc, - FORMATETC *formatEtcOut) +static HRESULT WINAPI data_object_GetCanonicalFormatEtc( IDataObject *iface, FORMATETC *format, FORMATETC *out ) { - FIXME("(%p, %p, %p): stub\n", dataObject, formatEtc, formatEtcOut); - formatEtcOut->ptd = NULL; + FIXME( "iface %p, format %p, out %p stub!\n", iface, format, out ); + out->ptd = NULL; return E_NOTIMPL; }
-static HRESULT WINAPI XDNDDATAOBJECT_SetData(IDataObject *dataObject, - FORMATETC *formatEtc, - STGMEDIUM *pMedium, BOOL fRelease) +static HRESULT WINAPI data_object_SetData( IDataObject *iface, FORMATETC *format, STGMEDIUM *medium, BOOL release ) { - FIXME("(%p, %p, %p, %s): stub\n", dataObject, formatEtc, - pMedium, fRelease?"TRUE":"FALSE"); + FIXME( "iface %p, format %p, medium %p, release %u stub!\n", iface, format, medium, release ); return E_NOTIMPL; }
-static HRESULT WINAPI XDNDDATAOBJECT_EnumFormatEtc(IDataObject *dataObject, - DWORD dwDirection, - IEnumFORMATETC **ppEnumFormatEtc) +static HRESULT WINAPI data_object_EnumFormatEtc( IDataObject *iface, DWORD direction, IEnumFORMATETC **out ) { struct format_entry *iter; - DWORD count = 0; + DWORD i = 0, count = 0; FORMATETC *formats; + HRESULT hr;
- TRACE("(%p, %lu, %p)\n", dataObject, dwDirection, ppEnumFormatEtc); + TRACE( "iface %p, direction %lu, out %p\n", iface, direction, out );
- if (dwDirection != DATADIR_GET) + if (direction != DATADIR_GET) { FIXME("only the get direction is implemented\n"); return E_NOTIMPL; @@ -240,70 +212,59 @@ static HRESULT WINAPI XDNDDATAOBJECT_EnumFormatEtc(IDataObject *dataObject,
for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) count++;
- formats = HeapAlloc(GetProcessHeap(), 0, count * sizeof(FORMATETC)); - if (formats) + if (!(formats = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*formats) ))) return E_OUTOFMEMORY; + + for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter ), i++) { - DWORD i = 0; - HRESULT hr; - for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) - { - formats[i].cfFormat = iter->format; - formats[i].ptd = NULL; - formats[i].dwAspect = DVASPECT_CONTENT; - formats[i].lindex = -1; - formats[i].tymed = TYMED_HGLOBAL; - i++; - } - hr = SHCreateStdEnumFmtEtc(count, formats, ppEnumFormatEtc); - HeapFree(GetProcessHeap(), 0, formats); - return hr; + formats[i].cfFormat = iter->format; + formats[i].ptd = NULL; + formats[i].dwAspect = DVASPECT_CONTENT; + formats[i].lindex = -1; + formats[i].tymed = TYMED_HGLOBAL; } - else - return E_OUTOFMEMORY; + + hr = SHCreateStdEnumFmtEtc( count, formats, out ); + HeapFree( GetProcessHeap(), 0, formats ); + return hr; }
-static HRESULT WINAPI XDNDDATAOBJECT_DAdvise(IDataObject *dataObject, - FORMATETC *formatEtc, DWORD advf, - IAdviseSink *adviseSink, - DWORD *pdwConnection) +static HRESULT WINAPI data_object_DAdvise( IDataObject *iface, FORMATETC *format, DWORD flags, + IAdviseSink *sink, DWORD *connection ) { - FIXME("(%p, %p, %lu, %p, %p): stub\n", dataObject, formatEtc, advf, - adviseSink, pdwConnection); + FIXME( "iface %p, format %p, flags %#lx, sink %p, connection %p stub!\n", + iface, format, flags, sink, connection ); return OLE_E_ADVISENOTSUPPORTED; }
-static HRESULT WINAPI XDNDDATAOBJECT_DUnadvise(IDataObject *dataObject, - DWORD dwConnection) +static HRESULT WINAPI data_object_DUnadvise( IDataObject *iface, DWORD connection ) { - FIXME("(%p, %lu): stub\n", dataObject, dwConnection); + FIXME( "iface %p, connection %lu stub!\n", iface, connection ); return OLE_E_ADVISENOTSUPPORTED; }
-static HRESULT WINAPI XDNDDATAOBJECT_EnumDAdvise(IDataObject *dataObject, - IEnumSTATDATA **pEnumAdvise) +static HRESULT WINAPI data_object_EnumDAdvise( IDataObject *iface, IEnumSTATDATA **advise ) { - FIXME("(%p, %p): stub\n", dataObject, pEnumAdvise); + FIXME( "iface %p, advise %p stub!\n", iface, advise ); return OLE_E_ADVISENOTSUPPORTED; }
-static IDataObjectVtbl xdndDataObjectVtbl = +static IDataObjectVtbl data_object_vtbl = { - XDNDDATAOBJECT_QueryInterface, - XDNDDATAOBJECT_AddRef, - XDNDDATAOBJECT_Release, - XDNDDATAOBJECT_GetData, - XDNDDATAOBJECT_GetDataHere, - XDNDDATAOBJECT_QueryGetData, - XDNDDATAOBJECT_GetCanonicalFormatEtc, - XDNDDATAOBJECT_SetData, - XDNDDATAOBJECT_EnumFormatEtc, - XDNDDATAOBJECT_DAdvise, - XDNDDATAOBJECT_DUnadvise, - XDNDDATAOBJECT_EnumDAdvise + data_object_QueryInterface, + data_object_AddRef, + data_object_Release, + data_object_GetData, + data_object_GetDataHere, + data_object_QueryGetData, + data_object_GetCanonicalFormatEtc, + data_object_SetData, + data_object_EnumFormatEtc, + data_object_DAdvise, + data_object_DUnadvise, + data_object_EnumDAdvise, };
-static IDataObject XDNDDataObject = { &xdndDataObjectVtbl }; - +static IDataObject xdnd_data_object = { &data_object_vtbl };
/* Based on functions in dlls/ole32/ole2.c */ static HANDLE get_droptarget_local_handle(HWND hwnd) @@ -449,7 +410,7 @@ NTSTATUS WINAPI x11drv_dnd_position_event( void *arg, ULONG size ) if (dropTarget) { DWORD effect_ignore = effect; - hr = IDropTarget_DragEnter(dropTarget, &XDNDDataObject, + hr = IDropTarget_DragEnter(dropTarget, &xdnd_data_object, MK_LBUTTON, pointl, &effect_ignore); if (hr == S_OK) { @@ -516,7 +477,7 @@ NTSTATUS WINAPI x11drv_dnd_drop_event( void *args, ULONG size )
pointl.x = XDNDxy.x; pointl.y = XDNDxy.y; - hr = IDropTarget_Drop(dropTarget, &XDNDDataObject, MK_LBUTTON, + hr = IDropTarget_Drop(dropTarget, &xdnd_data_object, MK_LBUTTON, pointl, &effect); if (hr == S_OK) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/xdnd.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index 4bc7a32f1e8..7a7ac9c2783 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -586,21 +586,11 @@ NTSTATUS WINAPI x11drv_dnd_enter_event( void *args, ULONG size ) */ static BOOL X11DRV_XDND_HasHDROP(void) { - struct format_entry *iter; + FORMATETC format = {.cfFormat = CF_HDROP}; BOOL found = FALSE;
EnterCriticalSection(&xdnd_cs); - - /* Find CF_HDROP type if any */ - for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) - { - if (iter->format == CF_HDROP) - { - found = TRUE; - break; - } - } - + found = xdnd_formats && SUCCEEDED(IDataObject_QueryGetData( &xdnd_data_object, &format )); LeaveCriticalSection(&xdnd_cs);
return found;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/xdnd.c | 49 +++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 26 deletions(-)
diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index 7a7ac9c2783..dff9a276a3e 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -604,6 +604,7 @@ static HRESULT X11DRV_XDND_SendDropFiles(HWND hwnd) struct format_entry *iter; HRESULT hr; BOOL found = FALSE; + HGLOBAL hglobal;
EnterCriticalSection(&xdnd_cs);
@@ -615,36 +616,32 @@ static HRESULT X11DRV_XDND_SendDropFiles(HWND hwnd) break; } } - if (found) + if (!found) hr = E_FAIL; + else if (!(hglobal = GlobalAlloc( GMEM_FIXED, iter->size ))) hr = HRESULT_FROM_WIN32(GetLastError()); + else { - HGLOBAL dropHandle = GlobalAlloc(GMEM_FIXED, iter->size); - if (dropHandle) - { - RECT rect; - DROPFILES *lpDrop = GlobalLock(dropHandle); - memcpy(lpDrop, iter->data, iter->size); - lpDrop->pt.x = XDNDxy.x; - lpDrop->pt.y = XDNDxy.y; - lpDrop->fNC = !(ScreenToClient(hwnd, &lpDrop->pt) && - GetClientRect(hwnd, &rect) && - PtInRect(&rect, lpDrop->pt)); - TRACE("Sending WM_DROPFILES: hWnd=0x%p, fNC=%d, x=%ld, y=%ld, files=%p(%s)\n", hwnd, - lpDrop->fNC, lpDrop->pt.x, lpDrop->pt.y, ((char*)lpDrop) + lpDrop->pFiles, - debugstr_w((WCHAR*)(((char*)lpDrop) + lpDrop->pFiles))); - GlobalUnlock(dropHandle); - if (PostMessageW(hwnd, WM_DROPFILES, (WPARAM)dropHandle, 0)) - hr = S_OK; - else - { - hr = HRESULT_FROM_WIN32(GetLastError()); - GlobalFree(dropHandle); - } - } + DROPFILES *drop = GlobalLock( hglobal ); + void *files; + RECT rect; + + memcpy( drop, iter->data, iter->size ); + files = (char *)drop + drop->pFiles; + drop->pt.x = XDNDxy.x; + drop->pt.y = XDNDxy.y; + drop->fNC = !ScreenToClient( hwnd, &drop->pt ) || !GetClientRect( hwnd, &rect ) || !PtInRect( &rect, drop->pt ); + + TRACE( "Sending WM_DROPFILES: hwnd %p, pt %s, fNC %u, files %p (%s)\n", hwnd, + wine_dbgstr_point( &drop->pt), drop->fNC, files, debugstr_w(files) ); + GlobalUnlock( hglobal ); + + if (PostMessageW( hwnd, WM_DROPFILES, (WPARAM)hglobal, 0 )) + hr = S_OK; else + { hr = HRESULT_FROM_WIN32(GetLastError()); + GlobalFree( hglobal ); + } } - else - hr = E_FAIL;
LeaveCriticalSection(&xdnd_cs);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/xdnd.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-)
diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index dff9a276a3e..2f3e23aef29 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -601,45 +601,33 @@ static BOOL X11DRV_XDND_HasHDROP(void) */ static HRESULT X11DRV_XDND_SendDropFiles(HWND hwnd) { - struct format_entry *iter; + FORMATETC format = {.cfFormat = CF_HDROP}; + STGMEDIUM medium; HRESULT hr; - BOOL found = FALSE; - HGLOBAL hglobal;
EnterCriticalSection(&xdnd_cs);
- for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) - { - if (iter->format == CF_HDROP) - { - found = TRUE; - break; - } - } - if (!found) hr = E_FAIL; - else if (!(hglobal = GlobalAlloc( GMEM_FIXED, iter->size ))) hr = HRESULT_FROM_WIN32(GetLastError()); - else + if (!xdnd_formats) hr = E_FAIL; + else if (SUCCEEDED(hr = IDataObject_GetData( &xdnd_data_object, &format, &medium ))) { - DROPFILES *drop = GlobalLock( hglobal ); - void *files; + DROPFILES *drop = GlobalLock( medium.hGlobal ); + void *files = (char *)drop + drop->pFiles; RECT rect;
- memcpy( drop, iter->data, iter->size ); - files = (char *)drop + drop->pFiles; drop->pt.x = XDNDxy.x; drop->pt.y = XDNDxy.y; drop->fNC = !ScreenToClient( hwnd, &drop->pt ) || !GetClientRect( hwnd, &rect ) || !PtInRect( &rect, drop->pt );
TRACE( "Sending WM_DROPFILES: hwnd %p, pt %s, fNC %u, files %p (%s)\n", hwnd, wine_dbgstr_point( &drop->pt), drop->fNC, files, debugstr_w(files) ); - GlobalUnlock( hglobal ); + GlobalUnlock( medium.hGlobal );
- if (PostMessageW( hwnd, WM_DROPFILES, (WPARAM)hglobal, 0 )) + if (PostMessageW( hwnd, WM_DROPFILES, (WPARAM)medium.hGlobal, 0 )) hr = S_OK; else { hr = HRESULT_FROM_WIN32(GetLastError()); - GlobalFree( hglobal ); + GlobalFree( medium.hGlobal ); } }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/xdnd.c | 119 +++++++++++++++++++++++++++------------- 1 file changed, 82 insertions(+), 37 deletions(-)
diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c index 2f3e23aef29..a898caa98b6 100644 --- a/dlls/winex11.drv/xdnd.c +++ b/dlls/winex11.drv/xdnd.c @@ -31,9 +31,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(xdnd);
-static struct format_entry *xdnd_formats, *xdnd_formats_end; static POINT XDNDxy = { 0, 0 }; -static IDataObject xdnd_data_object; +static IDataObject *xdnd_data_object; static BOOL XDNDAccepted = FALSE; static DWORD XDNDDropEffect = DROPEFFECT_NONE; /* the last window the mouse was over */ @@ -92,17 +91,30 @@ static const char *debugstr_format( int format ) return debugstr_w( buffer ); }
+struct data_object +{ + IDataObject IDataObject_iface; + LONG refcount; + + struct format_entry *entries_end; + struct format_entry entries[]; +};
-/* The IDataObject singleton we feed to OLE follows */ +static struct data_object *data_object_from_IDataObject( IDataObject *iface ) +{ + return CONTAINING_RECORD( iface, struct data_object, IDataObject_iface ); +}
static HRESULT WINAPI data_object_QueryInterface( IDataObject *iface, REFIID iid, void **obj ) { - TRACE( "iface %p, iid %s, obj %p\n", iface, debugstr_guid(iid), obj ); + struct data_object *object = data_object_from_IDataObject( iface ); + + TRACE( "object %p, iid %s, obj %p\n", object, debugstr_guid(iid), obj );
if (IsEqualIID( iid, &IID_IUnknown ) || IsEqualIID( iid, &IID_IDataObject )) { - IDataObject_AddRef( iface ); - *obj = iface; + IDataObject_AddRef( &object->IDataObject_iface ); + *obj = &object->IDataObject_iface; return S_OK; }
@@ -113,26 +125,32 @@ static HRESULT WINAPI data_object_QueryInterface( IDataObject *iface, REFIID iid
static ULONG WINAPI data_object_AddRef( IDataObject *iface ) { - TRACE( "iface %p\n", iface ); - return 2; + struct data_object *object = data_object_from_IDataObject( iface ); + ULONG ref = InterlockedIncrement( &object->refcount ); + TRACE( "object %p increasing refcount to %lu.\n", object, ref ); + return ref; }
static ULONG WINAPI data_object_Release( IDataObject *iface ) { - TRACE( "iface %p\n", iface ); - return 1; + struct data_object *object = data_object_from_IDataObject( iface ); + ULONG ref = InterlockedDecrement( &object->refcount ); + TRACE( "object %p decreasing refcount to %lu.\n", object, ref ); + if (!ref) free( object ); + return ref; }
static HRESULT WINAPI data_object_GetData( IDataObject *iface, FORMATETC *format, STGMEDIUM *medium ) { + struct data_object *object = data_object_from_IDataObject( iface ); struct format_entry *iter; HRESULT hr;
- TRACE( "iface %p, format %p (%s), medium %p\n", iface, format, debugstr_format(format->cfFormat), medium ); + TRACE( "object %p, format %p (%s), medium %p\n", object, format, debugstr_format(format->cfFormat), medium );
if (FAILED(hr = IDataObject_QueryGetData( iface, format ))) return hr;
- for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) + for (iter = object->entries; iter < object->entries_end; iter = next_format( iter )) { if (iter->format == format->cfFormat) { @@ -151,15 +169,17 @@ static HRESULT WINAPI data_object_GetData( IDataObject *iface, FORMATETC *format
static HRESULT WINAPI data_object_GetDataHere( IDataObject *iface, FORMATETC *format, STGMEDIUM *medium ) { - FIXME( "iface %p, format %p, medium %p stub!\n", iface, format, medium ); + struct data_object *object = data_object_from_IDataObject( iface ); + FIXME( "object %p, format %p, medium %p stub!\n", object, format, medium ); return DATA_E_FORMATETC; }
static HRESULT WINAPI data_object_QueryGetData( IDataObject *iface, FORMATETC *format ) { + struct data_object *object = data_object_from_IDataObject( iface ); struct format_entry *iter;
- TRACE( "iface %p, format %p (%s)\n", iface, format, debugstr_format(format->cfFormat) ); + TRACE( "object %p, format %p (%s)\n", object, format, debugstr_format(format->cfFormat) );
if (format->tymed && !(format->tymed & TYMED_HGLOBAL)) { @@ -170,7 +190,7 @@ static HRESULT WINAPI data_object_QueryGetData( IDataObject *iface, FORMATETC *f * and we have no way to implement them on XDnD anyway, so ignore them too. */
- for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) + for (iter = object->entries; iter < object->entries_end; iter = next_format( iter )) { if (iter->format == format->cfFormat) { @@ -184,25 +204,28 @@ static HRESULT WINAPI data_object_QueryGetData( IDataObject *iface, FORMATETC *f
static HRESULT WINAPI data_object_GetCanonicalFormatEtc( IDataObject *iface, FORMATETC *format, FORMATETC *out ) { - FIXME( "iface %p, format %p, out %p stub!\n", iface, format, out ); + struct data_object *object = data_object_from_IDataObject( iface ); + FIXME( "object %p, format %p, out %p stub!\n", object, format, out ); out->ptd = NULL; return E_NOTIMPL; }
static HRESULT WINAPI data_object_SetData( IDataObject *iface, FORMATETC *format, STGMEDIUM *medium, BOOL release ) { - FIXME( "iface %p, format %p, medium %p, release %u stub!\n", iface, format, medium, release ); + struct data_object *object = data_object_from_IDataObject( iface ); + FIXME( "object %p, format %p, medium %p, release %u stub!\n", object, format, medium, release ); return E_NOTIMPL; }
static HRESULT WINAPI data_object_EnumFormatEtc( IDataObject *iface, DWORD direction, IEnumFORMATETC **out ) { + struct data_object *object = data_object_from_IDataObject( iface ); struct format_entry *iter; DWORD i = 0, count = 0; FORMATETC *formats; HRESULT hr;
- TRACE( "iface %p, direction %lu, out %p\n", iface, direction, out ); + TRACE( "object %p, direction %lu, out %p\n", object, direction, out );
if (direction != DATADIR_GET) { @@ -210,11 +233,11 @@ static HRESULT WINAPI data_object_EnumFormatEtc( IDataObject *iface, DWORD direc return E_NOTIMPL; }
- for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter )) count++; + for (iter = object->entries; iter < object->entries_end; iter = next_format( iter )) count++;
if (!(formats = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*formats) ))) return E_OUTOFMEMORY;
- for (iter = xdnd_formats; iter < xdnd_formats_end; iter = next_format( iter ), i++) + for (iter = object->entries; iter < object->entries_end; iter = next_format( iter ), i++) { formats[i].cfFormat = iter->format; formats[i].ptd = NULL; @@ -231,20 +254,23 @@ static HRESULT WINAPI data_object_EnumFormatEtc( IDataObject *iface, DWORD direc static HRESULT WINAPI data_object_DAdvise( IDataObject *iface, FORMATETC *format, DWORD flags, IAdviseSink *sink, DWORD *connection ) { - FIXME( "iface %p, format %p, flags %#lx, sink %p, connection %p stub!\n", - iface, format, flags, sink, connection ); + struct data_object *object = data_object_from_IDataObject( iface ); + FIXME( "object %p, format %p, flags %#lx, sink %p, connection %p stub!\n", + object, format, flags, sink, connection ); return OLE_E_ADVISENOTSUPPORTED; }
static HRESULT WINAPI data_object_DUnadvise( IDataObject *iface, DWORD connection ) { - FIXME( "iface %p, connection %lu stub!\n", iface, connection ); + struct data_object *object = data_object_from_IDataObject( iface ); + FIXME( "object %p, connection %lu stub!\n", object, connection ); return OLE_E_ADVISENOTSUPPORTED; }
static HRESULT WINAPI data_object_EnumDAdvise( IDataObject *iface, IEnumSTATDATA **advise ) { - FIXME( "iface %p, advise %p stub!\n", iface, advise ); + struct data_object *object = data_object_from_IDataObject( iface ); + FIXME( "object %p, advise %p stub!\n", object, advise ); return OLE_E_ADVISENOTSUPPORTED; }
@@ -264,7 +290,20 @@ static IDataObjectVtbl data_object_vtbl = data_object_EnumDAdvise, };
-static IDataObject xdnd_data_object = { &data_object_vtbl }; +static HRESULT data_object_create( UINT entries_size, const struct format_entry *entries, IDataObject **out ) +{ + struct data_object *object; + + if (!(object = calloc( 1, sizeof(*object) + entries_size ))) return E_OUTOFMEMORY; + object->IDataObject_iface.lpVtbl = &data_object_vtbl; + object->refcount = 1; + + object->entries_end = (struct format_entry *)((char *)object->entries + entries_size); + memcpy( object->entries, entries, entries_size ); + *out = &object->IDataObject_iface; + + return S_OK; +}
/* Based on functions in dlls/ole32/ole2.c */ static HANDLE get_droptarget_local_handle(HWND hwnd) @@ -410,7 +449,7 @@ NTSTATUS WINAPI x11drv_dnd_position_event( void *arg, ULONG size ) if (dropTarget) { DWORD effect_ignore = effect; - hr = IDropTarget_DragEnter(dropTarget, &xdnd_data_object, + hr = IDropTarget_DragEnter(dropTarget, xdnd_data_object, MK_LBUTTON, pointl, &effect_ignore); if (hr == S_OK) { @@ -477,7 +516,7 @@ NTSTATUS WINAPI x11drv_dnd_drop_event( void *args, ULONG size )
pointl.x = XDNDxy.x; pointl.y = XDNDxy.y; - hr = IDropTarget_Drop(dropTarget, &xdnd_data_object, MK_LBUTTON, + hr = IDropTarget_Drop(dropTarget, xdnd_data_object, MK_LBUTTON, pointl, &effect); if (hr == S_OK) { @@ -569,14 +608,17 @@ NTSTATUS WINAPI x11drv_dnd_enter_event( void *args, ULONG size ) { UINT formats_size = size - offsetof(struct dnd_enter_event_params, entries); struct dnd_enter_event_params *params = args; + IDataObject *object; + XDNDAccepted = FALSE; X11DRV_XDND_FreeDragDropOp(); /* Clear previously cached data */
- if ((xdnd_formats = HeapAlloc( GetProcessHeap(), 0, formats_size ))) - { - memcpy( xdnd_formats, params->entries, formats_size ); - xdnd_formats_end = (struct format_entry *)((char *)xdnd_formats + formats_size); - } + if (FAILED(data_object_create( formats_size, params->entries, &object ))) return STATUS_NO_MEMORY; + + EnterCriticalSection( &xdnd_cs ); + xdnd_data_object = object; + LeaveCriticalSection( &xdnd_cs ); + return STATUS_SUCCESS; }
@@ -590,7 +632,7 @@ static BOOL X11DRV_XDND_HasHDROP(void) BOOL found = FALSE;
EnterCriticalSection(&xdnd_cs); - found = xdnd_formats && SUCCEEDED(IDataObject_QueryGetData( &xdnd_data_object, &format )); + found = xdnd_data_object && SUCCEEDED(IDataObject_QueryGetData( xdnd_data_object, &format )); LeaveCriticalSection(&xdnd_cs);
return found; @@ -607,8 +649,8 @@ static HRESULT X11DRV_XDND_SendDropFiles(HWND hwnd)
EnterCriticalSection(&xdnd_cs);
- if (!xdnd_formats) hr = E_FAIL; - else if (SUCCEEDED(hr = IDataObject_GetData( &xdnd_data_object, &format, &medium ))) + if (!xdnd_data_object) hr = E_FAIL; + else if (SUCCEEDED(hr = IDataObject_GetData( xdnd_data_object, &format, &medium ))) { DROPFILES *drop = GlobalLock( medium.hGlobal ); void *files = (char *)drop + drop->pFiles; @@ -646,8 +688,11 @@ static void X11DRV_XDND_FreeDragDropOp(void)
EnterCriticalSection(&xdnd_cs);
- HeapFree( GetProcessHeap(), 0, xdnd_formats ); - xdnd_formats = xdnd_formats_end = NULL; + if (xdnd_data_object) + { + IDataObject_Release( xdnd_data_object ); + xdnd_data_object = NULL; + }
XDNDxy.x = XDNDxy.y = 0; XDNDLastTargetWnd = NULL;