Module: wine
Branch: master
Commit: eac789c6dad79ef017a298e403292cf908af5809
URL: http://source.winehq.org/git/wine.git/?a=commit;h=eac789c6dad79ef017a298e40…
Author: Ken Thomases <ken(a)codeweavers.com>
Date: Fri Nov 22 04:31:48 2013 -0600
winemac: Put clipboard formats synthesized from other standard clipboard formats at the end of the list.
---
dlls/winemac.drv/clipboard.c | 77 +++++++++++++++++++++++++++++++++++------
1 files changed, 65 insertions(+), 12 deletions(-)
diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c
index 0b13df9..fe42023 100644
--- a/dlls/winemac.drv/clipboard.c
+++ b/dlls/winemac.drv/clipboard.c
@@ -1724,6 +1724,7 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard)
CFIndex count;
CFMutableArrayRef formats;
CFIndex i;
+ WINE_CLIPFORMAT* format;
TRACE("pasteboard %p\n", pasteboard);
@@ -1754,29 +1755,81 @@ CFArrayRef macdrv_copy_pasteboard_formats(CFTypeRef pasteboard)
for (i = 0; i < count; i++)
{
CFStringRef type = CFArrayGetValueAtIndex(types, i);
- WINE_CLIPFORMAT* format;
+ BOOL found = FALSE;
format = NULL;
while ((format = format_for_type(format, type)))
{
- TRACE("for type %s got format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));
+ /* Suppose type is "public.utf8-plain-text". format->format_id will be each of
+ CF_TEXT, CF_OEMTEXT, and CF_UNICODETEXT in turn. We want to look up the natural
+ type for each of those IDs (e.g. CF_TEXT -> "org.winehq.builtin.text") and then see
+ if that type is present in the pasteboard. If it is, then we don't want to add the
+ format to the list yet because it would be out of order.
+
+ For example, if a Mac app put "public.utf8-plain-text" and "public.tiff" on the
+ pasteboard, then we want the Win32 clipboard formats to be CF_TEXT, CF_OEMTEXT, and
+ CF_UNICODETEXT, and CF_TIFF, in that order. All of the text formats belong before
+ CF_TIFF because the Mac app expressed that text was "better" than the TIFF. In
+ this case, as soon as we encounter "public.utf8-plain-text" we should add all of
+ the associated text format IDs.
+
+ But if a Wine process put "org.winehq.builtin.unicodetext",
+ "public.utf8-plain-text", "public.utf16-plain-text", and "public.tiff", then we
+ want the clipboard formats to be CF_UNICODETEXT, CF_TIFF, CF_TEXT, and CF_OEMTEXT,
+ in that order. The Windows program presumably added CF_UNICODETEXT and CF_TIFF.
+ We're synthesizing CF_TEXT and CF_OEMTEXT from CF_UNICODETEXT but we want them to
+ come after the non-synthesized CF_TIFF. In this case, we don't want to add the
+ text formats upon encountering "public.utf8-plain-text",
+
+ We tell the two cases apart by seeing that one of the natural types for the text
+ formats (i.e. "org.winehq.builtin.unicodetext") is present on the pasteboard.
+ "found" indicates that. */
+
+ if (!format->synthesized)
+ {
+ TRACE("for type %s got primary format %p/%s\n", debugstr_cf(type), format, debugstr_format(format->format_id));
+ CFArrayAppendValue(formats, (void*)format->format_id);
+ found = TRUE;
+ }
+ else if (!found && format->natural_format &&
+ CFArrayContainsValue(types, CFRangeMake(0, count), format->natural_format->type))
+ {
+ TRACE("for type %s deferring synthesized formats because type %s is also present\n",
+ debugstr_cf(type), debugstr_cf(format->natural_format->type));
+ found = TRUE;
+ }
+ }
- if (format->synthesized)
+ if (!found)
+ {
+ while ((format = format_for_type(format, type)))
{
/* Don't override a real value with a synthesized value. */
if (!CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id))
+ {
+ 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);
+ }
}
- else
+ }
+ }
+
+ /* Now go back through the types adding the synthesized formats that we deferred before. */
+ for (i = 0; i < count; i++)
+ {
+ CFStringRef type = CFArrayGetValueAtIndex(types, i);
+
+ format = NULL;
+ while ((format = format_for_type(format, type)))
+ {
+ if (format->synthesized)
{
- /* If the type was already in the array, it must have been synthesized
- because this one's real. Remove the synthesized entry in favor of
- this one. */
- CFIndex index = CFArrayGetFirstIndexOfValue(formats, CFRangeMake(0, CFArrayGetCount(formats)),
- (void*)format->format_id);
- if (index != kCFNotFound)
- CFArrayRemoveValueAtIndex(formats, index);
- CFArrayAppendValue(formats, (void*)format->format_id);
+ /* Don't override a real value with a synthesized value. */
+ if (!CFArrayContainsValue(formats, CFRangeMake(0, CFArrayGetCount(formats)), (void*)format->format_id))
+ {
+ 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);
+ }
}
}
}
Module: wine
Branch: master
Commit: ee53ea4b933f1c794d236d5424a3c6ded124a9c1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ee53ea4b933f1c794d236d542…
Author: Ken Thomases <ken(a)codeweavers.com>
Date: Fri Nov 22 04:31:42 2013 -0600
winemac: Add a function to find the "natural" clipboard format entry for a format ID.
---
dlls/winemac.drv/clipboard.c | 44 +++++++++++++++++++++++++++--------------
1 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/dlls/winemac.drv/clipboard.c b/dlls/winemac.drv/clipboard.c
index f428ab6..039cccd 100644
--- a/dlls/winemac.drv/clipboard.c
+++ b/dlls/winemac.drv/clipboard.c
@@ -394,6 +394,27 @@ done:
/**************************************************************************
+ * natural_format_for_format
+ *
+ * Find the "natural" format for this format_id (the one which isn't
+ * synthesized from another type).
+ */
+static WINE_CLIPFORMAT* natural_format_for_format(UINT format_id)
+{
+ WINE_CLIPFORMAT *format;
+
+ LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry)
+ if (format->format_id == format_id && !format->synthesized) break;
+
+ if (&format->entry == &format_list)
+ format = NULL;
+
+ TRACE("%s -> %p/%s\n", debugstr_format(format_id), format, debugstr_cf(format ? format->type : NULL));
+ return format;
+}
+
+
+/**************************************************************************
* convert_text
*
* Convert string data between code pages or to/from wide characters. The
@@ -1984,12 +2005,8 @@ BOOL CDECL macdrv_SetClipboardData(UINT format_id, HANDLE data, BOOL owner)
window = macdrv_get_cocoa_window(GetAncestor(hwnd_owner, GA_ROOT), FALSE);
TRACE("format_id %s data %p owner %d hwnd_owner %p window %p)\n", debugstr_format(format_id), data, owner, hwnd_owner, window);
- /* Find the "natural" format for this format_id (the one which isn't
- synthesized from another type). */
- LIST_FOR_EACH_ENTRY(format, &format_list, WINE_CLIPFORMAT, entry)
- if (format->format_id == format_id && !format->synthesized) break;
-
- if (&format->entry == &format_list && !(format = insert_clipboard_format(format_id, NULL)))
+ format = natural_format_for_format(format_id);
+ if (!format && !(format = insert_clipboard_format(format_id, NULL)))
{
WARN("Failed to register clipboard format %s\n", debugstr_format(format_id));
return FALSE;
@@ -2165,16 +2182,13 @@ BOOL query_pasteboard_data(HWND hwnd, CFStringRef type)
pasteboard would also have data for "public.utf8-plain-text" and we wouldn't be here.) If
"org.winehq.builtin.text" is not on the pasteboard, then one of the other text formats is
presumably responsible for the promise that we're trying to satisfy, so we keep looking. */
- LIST_FOR_EACH_ENTRY(base_format, &format_list, WINE_CLIPFORMAT, entry)
+ if ((base_format = natural_format_for_format(format->format_id)) &&
+ CFArrayContainsValue(types, range, base_format->type))
{
- if (base_format->format_id == format->format_id && !base_format->synthesized &&
- CFArrayContainsValue(types, range, base_format->type))
- {
- TRACE("Sending WM_RENDERFORMAT message for format %s to hwnd %p\n", debugstr_format(base_format->format_id), hwnd);
- SendMessageW(hwnd, WM_RENDERFORMAT, base_format->format_id, 0);
- ret = TRUE;
- goto done;
- }
+ TRACE("Sending WM_RENDERFORMAT message for format %s to hwnd %p\n", debugstr_format(format->format_id), hwnd);
+ SendMessageW(hwnd, WM_RENDERFORMAT, format->format_id, 0);
+ ret = TRUE;
+ goto done;
}
}