Ken Thomases : winemac: Put clipboard formats synthesized from other standard clipboard formats at the end of the list .
Alexandre Julliard
julliard at winehq.org
Fri Nov 22 10:23:07 CST 2013
Module: wine
Branch: master
Commit: eac789c6dad79ef017a298e403292cf908af5809
URL: http://source.winehq.org/git/wine.git/?a=commit;h=eac789c6dad79ef017a298e403292cf908af5809
Author: Ken Thomases <ken at 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);
+ }
}
}
}
More information about the wine-cvs
mailing list