Ken Thomases : winemac: Implement GetClipboardData() with support for text formats.

Alexandre Julliard julliard at winehq.org
Mon Mar 11 16:24:52 CDT 2013


Module: wine
Branch: master
Commit: 764a8edb0991b2aaca225923e00f4a1cb8d92e53
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=764a8edb0991b2aaca225923e00f4a1cb8d92e53

Author: Ken Thomases <ken at codeweavers.com>
Date:   Sun Mar 10 22:58:18 2013 -0500

winemac: Implement GetClipboardData() with support for text formats.

---

 dlls/winemac.drv/clipboard.c       |   67 ++++++++++++++++++++++++++++++++++++
 dlls/winemac.drv/cocoa_clipboard.m |   28 +++++++++++++++
 dlls/winemac.drv/macdrv_cocoa.h    |    1 +
 dlls/winemac.drv/winemac.drv.spec  |    1 +
 4 files changed, 97 insertions(+), 0 deletions(-)

diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c
index 2c07fc8..9ae9e9c 100644
--- a/dlls/winemac.drv/clipboard.c
+++ b/dlls/winemac.drv/clipboard.c
@@ -738,6 +738,73 @@ UINT CDECL macdrv_EnumClipboardFormats(UINT prev_format)
 
 
 /**************************************************************************
+ *              GetClipboardData (MACDRV.@)
+ */
+HANDLE CDECL macdrv_GetClipboardData(UINT desired_format)
+{
+    CFArrayRef types;
+    CFIndex count;
+    CFIndex i;
+    CFStringRef type, best_type;
+    WINE_CLIPFORMAT* best_format = NULL;
+    HANDLE data = NULL;
+
+    TRACE("desired_format %s\n", debugstr_format(desired_format));
+
+    types = macdrv_copy_pasteboard_types();
+    if (!types)
+    {
+        WARN("Failed to copy pasteboard types\n");
+        return NULL;
+    }
+
+    count = CFArrayGetCount(types);
+    TRACE("got %ld types\n", count);
+
+    for (i = 0; (!best_format || best_format->synthesized) && i < count; i++)
+    {
+        WINE_CLIPFORMAT* format;
+
+        type = CFArrayGetValueAtIndex(types, i);
+
+        format = NULL;
+        while ((!best_format || best_format->synthesized) && (format = format_for_type(format, type)))
+        {
+            TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format ? format->format_id : 0));
+
+            if (format->format_id == desired_format)
+            {
+                /* The best format is the matching one which is not synthesized.  Failing that,
+                   the best format is the first matching synthesized format. */
+                if (!format->synthesized || !best_format)
+                {
+                    best_type = type;
+                    best_format = format;
+                }
+            }
+        }
+    }
+
+    if (best_format)
+    {
+        CFDataRef pasteboard_data = macdrv_copy_pasteboard_data(best_type);
+
+        TRACE("got pasteboard data for type %s: %s\n", debugstr_cf(best_type), debugstr_cf(pasteboard_data));
+
+        if (pasteboard_data)
+        {
+            data = best_format->import_func(pasteboard_data);
+            CFRelease(pasteboard_data);
+        }
+    }
+
+    CFRelease(types);
+    TRACE(" -> %p\n", data);
+    return data;
+}
+
+
+/**************************************************************************
  *              IsClipboardFormatAvailable (MACDRV.@)
  */
 BOOL CDECL macdrv_IsClipboardFormatAvailable(UINT desired_format)
diff --git a/dlls/winemac.drv/cocoa_clipboard.m b/dlls/winemac.drv/cocoa_clipboard.m
index f9f9c6a..753a497 100644
--- a/dlls/winemac.drv/cocoa_clipboard.m
+++ b/dlls/winemac.drv/cocoa_clipboard.m
@@ -50,3 +50,31 @@ CFArrayRef macdrv_copy_pasteboard_types(void)
     [pool release];
     return ret;
 }
+
+
+/***********************************************************************
+ *              macdrv_copy_pasteboard_data
+ *
+ * Returns the pasteboard data for a specified type, or NULL on error or
+ * if there's no such type on the pasteboard.  The caller is responsible
+ * for releasing the returned data object with CFRelease().
+ */
+CFDataRef macdrv_copy_pasteboard_data(CFStringRef type)
+{
+    __block NSData* ret = nil;
+
+    OnMainThread(^{
+        @try
+        {
+            NSPasteboard* pb = [NSPasteboard generalPasteboard];
+            if ([pb availableTypeFromArray:[NSArray arrayWithObject:(NSString*)type]])
+                ret = [[pb dataForType:(NSString*)type] copy];
+        }
+        @catch (id e)
+        {
+            ERR(@"Exception discarded while copying pasteboard types: %@\n", e);
+        }
+    });
+
+    return (CFDataRef)ret;
+}
diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h
index 3bb03d6..e36c301 100644
--- a/dlls/winemac.drv/macdrv_cocoa.h
+++ b/dlls/winemac.drv/macdrv_cocoa.h
@@ -275,6 +275,7 @@ extern CFDataRef macdrv_copy_keyboard_layout(CGEventSourceKeyboardType* keyboard
 
 /* clipboard */
 extern CFArrayRef macdrv_copy_pasteboard_types(void) DECLSPEC_HIDDEN;
+extern CFDataRef macdrv_copy_pasteboard_data(CFStringRef type) DECLSPEC_HIDDEN;
 
 
 /* opengl */
diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec
index 3bbaac2..d1195f1 100644
--- a/dlls/winemac.drv/winemac.drv.spec
+++ b/dlls/winemac.drv/winemac.drv.spec
@@ -16,6 +16,7 @@
 @ cdecl EnumClipboardFormats(long) macdrv_EnumClipboardFormats
 @ cdecl EnumDisplayMonitors(long ptr ptr long) macdrv_EnumDisplayMonitors
 @ cdecl EnumDisplaySettingsEx(ptr long ptr long) macdrv_EnumDisplaySettingsEx
+@ cdecl GetClipboardData(long) macdrv_GetClipboardData
 @ cdecl GetCursorPos(ptr) macdrv_GetCursorPos
 @ cdecl GetKeyboardLayout(long) macdrv_GetKeyboardLayout
 @ cdecl GetKeyboardLayoutName(ptr) macdrv_GetKeyboardLayoutName




More information about the wine-cvs mailing list