From 782959168abb12142a1c3b677742283484c3bd1c Mon Sep 17 00:00:00 2001 From: Ken Thomases Date: Sun, 23 Oct 2016 13:03:31 -0500 Subject: [PATCH] winemac: Change macdrv_copy_pasteboard_formats() to return a C array instead of a CFArray. Renamed it to macdrv_get_pasteboard_formats(), since the "copy" was meant to convey Core Foundation ownership semantics which no longer apply. Signed-off-by: Ken Thomases Signed-off-by: Alexandre Julliard --- dlls/winemac.drv/clipboard.c | 87 ++++++++++++++++++++++++++++-------- dlls/winemac.drv/dragdrop.c | 9 ++-- dlls/winemac.drv/macdrv.h | 2 +- 3 files changed, 74 insertions(+), 24 deletions(-) diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c index c196e9327bb..eba426a3ce1 100644 --- a/dlls/winemac.drv/clipboard.c +++ b/dlls/winemac.drv/clipboard.c @@ -1303,17 +1303,17 @@ BOOL macdrv_pasteboard_has_format(CFTypeRef pasteboard, UINT desired_format) /************************************************************************** - * macdrv_copy_pasteboard_formats + * get_formats_for_pasteboard */ -CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) +static WINE_CLIPFORMAT** get_formats_for_pasteboard(CFTypeRef pasteboard, UINT *num_formats) { CFArrayRef types; - CFIndex count; - CFMutableArrayRef formats; - CFIndex i; - WINE_CLIPFORMAT* format; + CFIndex count, i; + CFMutableSetRef seen_formats; + WINE_CLIPFORMAT** formats; + UINT pos; - TRACE("pasteboard %p\n", pasteboard); + TRACE("pasteboard %s\n", debugstr_cf(pasteboard)); types = macdrv_copy_pasteboard_types(pasteboard); if (!types) @@ -1331,19 +1331,29 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) return NULL; } - formats = CFArrayCreateMutable(NULL, 0, NULL); - if (!formats) + seen_formats = CFSetCreateMutable(NULL, count, NULL); + if (!seen_formats) { - WARN("Failed to allocate formats array\n"); + WARN("Failed to allocate seen formats set\n"); CFRelease(types); return NULL; } + formats = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*formats)); + if (!formats) + { + WARN("Failed to allocate formats array\n"); + CFRelease(types); + CFRelease(seen_formats); + return NULL; + } + + pos = 0; for (i = 0; i < count; i++) { CFStringRef type = CFArrayGetValueAtIndex(types, i); + WINE_CLIPFORMAT* format = format_for_type(type); - format = format_for_type(type); if (!format) { TRACE("ignoring type %s\n", debugstr_cf(type)); @@ -1353,7 +1363,8 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) if (!format->synthesized) { TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - CFArrayAppendValue(formats, (void*)format->format_id); + CFSetAddValue(seen_formats, (void*)format->format_id); + formats[pos++] = format; } else if (format->natural_format && CFArrayContainsValue(types, CFRangeMake(0, count), format->natural_format->type)) @@ -1361,7 +1372,7 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) TRACE("for type %s deferring synthesized formats because type %s is also present\n", debugstr_cf(type), debugstr_cf(format->natural_format->type)); } - else if (CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id)) + else if (CFSetContainsValue(seen_formats, (void*)format->format_id)) { TRACE("for type %s got duplicate synthesized format %p/%s; skipping\n", debugstr_cf(type), format, debugstr_format(format->format_id)); @@ -1369,7 +1380,8 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) else { TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - CFArrayAppendValue(formats, (void*)format->format_id); + CFSetAddValue(seen_formats, (void*)format->format_id); + formats[pos++] = format; } } @@ -1377,25 +1389,64 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) for (i = 0; i < count; i++) { CFStringRef type = CFArrayGetValueAtIndex(types, i); + WINE_CLIPFORMAT* format = format_for_type(type); - format = format_for_type(type); if (!format) continue; if (!format->synthesized) continue; /* Don't duplicate a real value with a synthesized value. */ - if (CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id)) continue; + if (CFSetContainsValue(seen_formats, (void*)format->format_id)) continue; TRACE("for type %s got synthesized format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id)); - CFArrayAppendValue(formats, (void*)format->format_id); + CFSetAddValue(seen_formats, (void*)format->format_id); + formats[pos++] = format; } CFRelease(types); + CFRelease(seen_formats); - TRACE(" -> %s\n", debugstr_cf(formats)); + if (!pos) + { + HeapFree(GetProcessHeap(), 0, formats); + formats = NULL; + } + + *num_formats = pos; return formats; } +/************************************************************************** + * macdrv_get_pasteboard_formats + */ +UINT* macdrv_get_pasteboard_formats(CFTypeRef pasteboard, UINT* num_formats) +{ + WINE_CLIPFORMAT** formats; + UINT count, i; + UINT* format_ids; + + formats = get_formats_for_pasteboard(pasteboard, &count); + if (!formats) + return NULL; + + format_ids = HeapAlloc(GetProcessHeap(), 0, count); + if (!format_ids) + { + WARN("Failed to allocate formats IDs array\n"); + HeapFree(GetProcessHeap(), 0, formats); + return NULL; + } + + for (i = 0; i < count; i++) + format_ids[i] = formats[i]->format_id; + + HeapFree(GetProcessHeap(), 0, formats); + + *num_formats = count; + return format_ids; +} + + /************************************************************************** * Mac User Driver Clipboard Exports **************************************************************************/ diff --git a/dlls/winemac.drv/dragdrop.c b/dlls/winemac.drv/dragdrop.c index ad0bc8ccccb..e0890183bc0 100644 --- a/dlls/winemac.drv/dragdrop.c +++ b/dlls/winemac.drv/dragdrop.c @@ -185,7 +185,7 @@ static HRESULT WINAPI dddo_EnumFormatEtc(IDataObject* iface, DWORD direction, IEnumFORMATETC** enumFormatEtc) { DragDropDataObject *This = impl_from_IDataObject(iface); - CFArrayRef formats; + UINT *formats, count; HRESULT hr; TRACE("This %p direction %u enumFormatEtc %p\n", This, direction, enumFormatEtc); @@ -196,10 +196,9 @@ static HRESULT WINAPI dddo_EnumFormatEtc(IDataObject* iface, DWORD direction, return E_NOTIMPL; } - formats = macdrv_copy_pasteboard_formats(This->pasteboard); + formats = macdrv_get_pasteboard_formats(This->pasteboard, &count); if (formats) { - INT count = CFArrayGetCount(formats); FORMATETC *formatEtcs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(FORMATETC)); if (formatEtcs) { @@ -207,7 +206,7 @@ static HRESULT WINAPI dddo_EnumFormatEtc(IDataObject* iface, DWORD direction, for (i = 0; i < count; i++) { - formatEtcs[i].cfFormat = (UINT)CFArrayGetValueAtIndex(formats, i); + formatEtcs[i].cfFormat = formats[i]; formatEtcs[i].ptd = NULL; formatEtcs[i].dwAspect = DVASPECT_CONTENT; formatEtcs[i].lindex = -1; @@ -220,7 +219,7 @@ static HRESULT WINAPI dddo_EnumFormatEtc(IDataObject* iface, DWORD direction, else hr = E_OUTOFMEMORY; - CFRelease(formats); + HeapFree(GetProcessHeap(), 0, formats); } else hr = SHCreateStdEnumFmtEtc(0, NULL, enumFormatEtc); diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index bfdffc86283..c29ea15f781 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -199,7 +199,7 @@ static inline RECT rect_from_cgrect(CGRect cgrect) extern const char *debugstr_format(UINT id) DECLSPEC_HIDDEN; extern HANDLE macdrv_get_pasteboard_data(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN; extern BOOL macdrv_pasteboard_has_format(CFTypeRef pasteboard, UINT desired_format) DECLSPEC_HIDDEN; -extern CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard) DECLSPEC_HIDDEN; +extern UINT* macdrv_get_pasteboard_formats(CFTypeRef pasteboard, UINT* num_formats) DECLSPEC_HIDDEN; extern BOOL query_drag_operation(macdrv_query* query) DECLSPEC_HIDDEN; extern BOOL query_drag_exited(macdrv_query* query) DECLSPEC_HIDDEN;