Improved text pasting on OS X

Support for UTF-8 and UTF-16 encodings should cover all cases of text pasting from clipboard
This commit is contained in:
alexey.lysiuk 2015-04-05 10:59:07 +03:00
parent 89054f5d60
commit 82f7b439c8

View file

@ -603,6 +603,15 @@ int I_FindAttr (findstate_t *fileinfo)
#ifdef __APPLE__
static PasteboardRef s_clipboard;
static CFDataRef GetPasteboardData(const PasteboardItemID itemID, const CFStringRef flavorType)
{
CFDataRef data = NULL;
const OSStatus result = PasteboardCopyItemFlavorData(s_clipboard, itemID, flavorType, &data);
return noErr == result ? data : NULL;
}
#endif // __APPLE__
// Clipboard support requires GTK+
@ -688,35 +697,36 @@ FString I_GetFromClipboard (bool use_primary_selection)
return FString();
}
CFArrayRef flavorTypeArray;
if (0 != PasteboardCopyItemFlavors(s_clipboard, itemID, &flavorTypeArray))
if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF8PlainText))
{
return FString();
result = reinterpret_cast<const char*>(CFDataGetBytePtr(data));
}
const CFIndex flavorCount = CFArrayGetCount(flavorTypeArray);
for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; ++flavorIndex)
else if (CFDataRef data = GetPasteboardData(itemID, kUTTypeUTF16PlainText))
{
const CFStringRef flavorType = static_cast<const CFStringRef>(
CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex));
#ifdef __LITTLE_ENDIAN__
static const CFStringEncoding ENCODING = kCFStringEncodingUTF16LE;
#else // __BIG_ENDIAN__
static const CFStringEncoding ENCODING = kCFStringEncodingUTF16BE;
#endif // __LITTLE_ENDIAN__
if (UTTypeConformsTo(flavorType, CFSTR("public.utf8-plain-text")))
if (const CFStringRef utf16 = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, data, ENCODING))
{
CFDataRef flavorData;
const CFRange range = { 0, CFStringGetLength(utf16) };
CFIndex bufferLength = 0;
if (0 == PasteboardCopyItemFlavorData(s_clipboard, itemID, flavorType, &flavorData))
if (CFStringGetBytes(utf16, range, kCFStringEncodingUTF8, '?', false, NULL, 0, &bufferLength) > 0)
{
result += reinterpret_cast<const char*>(CFDataGetBytePtr(flavorData));
UInt8* const buffer = reinterpret_cast<UInt8*>(result.LockNewBuffer(bufferLength));
CFStringGetBytes(utf16, range, kCFStringEncodingUTF8, '?', false, buffer, bufferLength, NULL);
result.UnlockBuffer();
}
CFRelease(flavorData);
CFRelease(utf16);
}
}
CFRelease(flavorTypeArray);
return result;
#endif
return "";