[PATCH 05/11] winemac: Use unixlib interface for macdrv_dnd_get_data.
Jacek Caban
wine at gitlab.winehq.org
Thu Jun 2 19:51:20 CDT 2022
From: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
---
dlls/winemac.drv/clipboard.c | 29 ++++++++++++++---------------
dlls/winemac.drv/dragdrop.c | 24 ++++++++++++++++++++++--
dlls/winemac.drv/macdrv.h | 2 +-
dlls/winemac.drv/macdrv_main.c | 1 +
dlls/winemac.drv/unixlib.h | 10 ++++++++++
5 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c
index f46bb389cc9..8a795e61724 100644
--- a/dlls/winemac.drv/clipboard.c
+++ b/dlls/winemac.drv/clipboard.c
@@ -1128,24 +1128,26 @@ static CFDataRef export_unicodetext_to_utf16(void *data, size_t size)
/**************************************************************************
- * macdrv_get_pasteboard_data
+ * macdrv_dnd_get_data
*/
-HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format)
+NTSTATUS macdrv_dnd_get_data(void *arg)
{
+ struct dnd_get_data_params *params = arg;
+ CFTypeRef pasteboard = pasteboard_from_handle(params->handle);
CFArrayRef types;
CFIndex count;
CFIndex i;
CFStringRef type, best_type;
WINE_CLIPFORMAT* best_format = NULL;
- HANDLE data = NULL;
+ NTSTATUS status = STATUS_SUCCESS;
- TRACE("pasteboard %p, desired_format %s\n", pasteboard, debugstr_format(desired_format));
+ TRACE("pasteboard %p, desired_format %s\n", pasteboard, debugstr_format(params->format));
types = macdrv_copy_pasteboard_types(pasteboard);
if (!types)
{
WARN("Failed to copy pasteboard types\n");
- return NULL;
+ return STATUS_NO_MEMORY;
}
count = CFArrayGetCount(types);
@@ -1161,7 +1163,7 @@ HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format)
{
TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));
- if (format->format_id == desired_format)
+ if (format->format_id == params->format)
{
/* The best format is the matching one which is not synthesized. Failing that,
the best format is the first matching synthesized format. */
@@ -1183,15 +1185,12 @@ HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format)
if (pasteboard_data)
{
size_t size;
- void *import = best_format->import_func(pasteboard_data, &size), *ptr;
+ void *import = best_format->import_func(pasteboard_data, &size);
if (import)
{
- data = GlobalAlloc(GMEM_FIXED, size);
- if (data && (ptr = GlobalLock(data)))
- {
- memcpy(ptr, import, size);
- GlobalUnlock(data);
- }
+ if (size > params->size) status = STATUS_BUFFER_OVERFLOW;
+ else memcpy(params->data, import, size);
+ params->size = size;
free(import);
}
CFRelease(pasteboard_data);
@@ -1199,8 +1198,8 @@ HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format)
}
CFRelease(types);
- TRACE(" -> %p\n", data);
- return data;
+ TRACE(" -> %#x\n", status);
+ return status;
}
diff --git a/dlls/winemac.drv/dragdrop.c b/dlls/winemac.drv/dragdrop.c
index 962a9d8c24b..aec8b1f4790 100644
--- a/dlls/winemac.drv/dragdrop.c
+++ b/dlls/winemac.drv/dragdrop.c
@@ -24,6 +24,8 @@
#define NONAMELESSUNION
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#include "macdrv.h"
#define COBJMACROS
@@ -92,6 +94,24 @@ static inline DragDropDataObject *impl_from_IDataObject(IDataObject *iface)
}
+static HANDLE get_pasteboard_data(UINT64 pasteboard, UINT desired_format)
+{
+ struct dnd_get_data_params params = { .handle = pasteboard, .format = desired_format, .size = 2048 };
+ HANDLE handle;
+ NTSTATUS status;
+
+ for (;;)
+ {
+ if (!(handle = GlobalAlloc(GMEM_FIXED, params.size))) return 0;
+ params.data = GlobalLock(handle);
+ status = MACDRV_CALL(dnd_get_data, ¶ms);
+ GlobalUnlock(handle);
+ if (!status) return GlobalReAlloc(handle, params.size, 0);
+ GlobalFree(handle);
+ if (status != STATUS_BUFFER_OVERFLOW) return 0;
+ }
+}
+
static HRESULT WINAPI dddo_QueryInterface(IDataObject* iface, REFIID riid, LPVOID *ppvObj)
{
DragDropDataObject *This = impl_from_IDataObject(iface);
@@ -148,7 +168,7 @@ static HRESULT WINAPI dddo_GetData(IDataObject* iface, FORMATETC* formatEtc, STG
if (SUCCEEDED(hr))
{
medium->tymed = TYMED_HGLOBAL;
- medium->u.hGlobal = macdrv_get_pasteboard_data((void *)(UINT_PTR)This->pasteboard, formatEtc->cfFormat);
+ medium->u.hGlobal = get_pasteboard_data(This->pasteboard, formatEtc->cfFormat);
medium->pUnkForRelease = NULL;
hr = medium->u.hGlobal ? S_OK : E_OUTOFMEMORY;
}
@@ -454,7 +474,7 @@ NTSTATUS WINAPI macdrv_dnd_query_drop(void *arg, ULONG size)
hwnd = GetParent(hwnd);
if (hwnd)
{
- HDROP hdrop = macdrv_get_pasteboard_data((void *)(UINT_PTR)params->handle, CF_HDROP);
+ HDROP hdrop = get_pasteboard_data(params->handle, CF_HDROP);
DROPFILES *dropfiles = GlobalLock(hdrop);
if (dropfiles)
{
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h
index 4c1a21a3fe8..a841465486e 100644
--- a/dlls/winemac.drv/macdrv.h
+++ b/dlls/winemac.drv/macdrv.h
@@ -255,7 +255,6 @@ extern void macdrv_displays_changed(const macdrv_event *event) DECLSPEC_HIDDEN;
extern void macdrv_UpdateClipboard(void) DECLSPEC_HIDDEN;
extern BOOL query_pasteboard_data(HWND hwnd, CFStringRef type) DECLSPEC_HIDDEN;
extern void macdrv_lost_pasteboard_ownership(HWND hwnd) DECLSPEC_HIDDEN;
-extern HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN;
extern struct opengl_funcs *macdrv_wine_get_wgl_driver(UINT version) DECLSPEC_HIDDEN;
extern const struct vulkan_funcs *macdrv_wine_get_vulkan_driver(UINT version) DECLSPEC_HIDDEN;
@@ -285,6 +284,7 @@ extern NTSTATUS WINAPI macdrv_ime_query_char_rect(void *params, ULONG size) DECL
/* unixlib interface */
+extern NTSTATUS macdrv_dnd_get_data(void *arg) DECLSPEC_HIDDEN;
extern NTSTATUS macdrv_dnd_get_formats(void *arg) DECLSPEC_HIDDEN;
extern NTSTATUS macdrv_dnd_have_format(void *arg) DECLSPEC_HIDDEN;
extern NTSTATUS macdrv_dnd_release(void *arg) DECLSPEC_HIDDEN;
diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c
index a0b29604e62..61195d408c8 100644
--- a/dlls/winemac.drv/macdrv_main.c
+++ b/dlls/winemac.drv/macdrv_main.c
@@ -630,6 +630,7 @@ static NTSTATUS macdrv_ime_using_input_method(void *arg)
const unixlib_entry_t __wine_unix_call_funcs[] =
{
+ macdrv_dnd_get_data,
macdrv_dnd_get_formats,
macdrv_dnd_have_format,
macdrv_dnd_release,
diff --git a/dlls/winemac.drv/unixlib.h b/dlls/winemac.drv/unixlib.h
index b29bf99e7f4..0bfc61321d0 100644
--- a/dlls/winemac.drv/unixlib.h
+++ b/dlls/winemac.drv/unixlib.h
@@ -21,6 +21,7 @@
enum macdrv_funcs
{
+ unix_dnd_get_data,
unix_dnd_get_formats,
unix_dnd_have_format,
unix_dnd_release,
@@ -37,6 +38,15 @@ enum macdrv_funcs
extern NTSTATUS unix_call(enum macdrv_funcs code, void *params) DECLSPEC_HIDDEN;
#define MACDRV_CALL(func, params) unix_call( unix_ ## func, params )
+/* macdrv_dnd_get_data params */
+struct dnd_get_data_params
+{
+ UINT64 handle;
+ UINT format;
+ size_t size;
+ void *data;
+};
+
/* macdrv_dnd_get_formats params */
struct dnd_get_formats_params
{
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/177
More information about the wine-devel
mailing list