[PATCH 12/15] winemac: Change macdrv_copy_pasteboard_formats() to return a C array instead of a CFArray.

Ken Thomases ken at codeweavers.com
Sun Oct 23 13:03:31 CDT 2016


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 <ken at codeweavers.com>
---
 dlls/winemac.drv/clipboard.c | 83 +++++++++++++++++++++++++++++++++++---------
 dlls/winemac.drv/dragdrop.c  |  9 +++--
 dlls/winemac.drv/macdrv.h    |  2 +-
 3 files changed, 72 insertions(+), 22 deletions(-)

diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c
index c196e93..eba426a 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);
+    seen_formats = CFSetCreateMutable(NULL, count, NULL);
+    if (!seen_formats)
+    {
+        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,26 +1389,65 @@ 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 ad0bc8c..e089018 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 bfdffc8..c29ea15 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;
-- 
2.8.2




More information about the wine-patches mailing list