mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-20 23:37:33 +09:00
Issue #1751 -- Remove cocoa and uikit widget support code
This commit is contained in:
parent
a6ae35ba91
commit
3a4e65f1de
165 changed files with 4 additions and 42109 deletions
|
|
@ -1,775 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsClipboard.h"
|
||||
#include "nsString.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsPrimitiveHelpers.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsDragService.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
|
||||
using mozilla::gfx::DataSourceSurface;
|
||||
using mozilla::gfx::SourceSurface;
|
||||
using mozilla::LogLevel;
|
||||
|
||||
// Screenshots use the (undocumented) png pasteboard type.
|
||||
#define IMAGE_PASTEBOARD_TYPES NSTIFFPboardType, @"Apple PNG pasteboard type", nil
|
||||
|
||||
extern PRLogModuleInfo* sCocoaLog;
|
||||
|
||||
extern void EnsureLogInitialized();
|
||||
|
||||
mozilla::StaticRefPtr<nsITransferable> nsClipboard::sSelectionCache;
|
||||
|
||||
nsClipboard::nsClipboard()
|
||||
: mCachedClipboard(-1)
|
||||
, mChangeCount(0)
|
||||
, mIgnoreEmptyNotification(false)
|
||||
{
|
||||
EnsureLogInitialized();
|
||||
}
|
||||
|
||||
nsClipboard::~nsClipboard()
|
||||
{
|
||||
EmptyClipboard(kGlobalClipboard);
|
||||
EmptyClipboard(kFindClipboard);
|
||||
ClearSelectionCache();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsClipboard, nsIClipboard)
|
||||
|
||||
// We separate this into its own function because after an @try, all local
|
||||
// variables within that function get marked as volatile, and our C++ type
|
||||
// system doesn't like volatile things.
|
||||
static NSData*
|
||||
GetDataFromPasteboard(NSPasteboard* aPasteboard, NSString* aType)
|
||||
{
|
||||
NSData *data = nil;
|
||||
@try {
|
||||
data = [aPasteboard dataForType:aType];
|
||||
} @catch (NSException* e) {
|
||||
NS_WARNING(nsPrintfCString("Exception raised while getting data from the pasteboard: \"%s - %s\"",
|
||||
[[e name] UTF8String], [[e reason] UTF8String]).get());
|
||||
mozilla::Unused << e;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
nsClipboard::SetSelectionCache(nsITransferable *aTransferable)
|
||||
{
|
||||
sSelectionCache = aTransferable;
|
||||
}
|
||||
|
||||
void
|
||||
nsClipboard::ClearSelectionCache()
|
||||
{
|
||||
sSelectionCache = nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClipboard::SetNativeClipboardData(int32_t aWhichClipboard)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if ((aWhichClipboard != kGlobalClipboard && aWhichClipboard != kFindClipboard) || !mTransferable)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mIgnoreEmptyNotification = true;
|
||||
|
||||
NSDictionary* pasteboardOutputDict = PasteboardDictFromTransferable(mTransferable);
|
||||
if (!pasteboardOutputDict)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
unsigned int outputCount = [pasteboardOutputDict count];
|
||||
NSArray* outputKeys = [pasteboardOutputDict allKeys];
|
||||
NSPasteboard* cocoaPasteboard;
|
||||
if (aWhichClipboard == kFindClipboard) {
|
||||
cocoaPasteboard = [NSPasteboard pasteboardWithName:NSFindPboard];
|
||||
[cocoaPasteboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
||||
} else {
|
||||
// Write everything else out to the general pasteboard.
|
||||
cocoaPasteboard = [NSPasteboard generalPasteboard];
|
||||
[cocoaPasteboard declareTypes:outputKeys owner:nil];
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < outputCount; i++) {
|
||||
NSString* currentKey = [outputKeys objectAtIndex:i];
|
||||
id currentValue = [pasteboardOutputDict valueForKey:currentKey];
|
||||
if (aWhichClipboard == kFindClipboard) {
|
||||
if (currentKey == NSStringPboardType)
|
||||
[cocoaPasteboard setString:currentValue forType:currentKey];
|
||||
} else {
|
||||
if (currentKey == NSStringPboardType ||
|
||||
currentKey == kCorePboardType_url ||
|
||||
currentKey == kCorePboardType_urld ||
|
||||
currentKey == kCorePboardType_urln) {
|
||||
[cocoaPasteboard setString:currentValue forType:currentKey];
|
||||
} else if (currentKey == NSHTMLPboardType) {
|
||||
[cocoaPasteboard setString:(nsClipboard::WrapHtmlForSystemPasteboard(currentValue))
|
||||
forType:currentKey];
|
||||
} else {
|
||||
[cocoaPasteboard setData:currentValue forType:currentKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mCachedClipboard = aWhichClipboard;
|
||||
mChangeCount = [cocoaPasteboard changeCount];
|
||||
|
||||
mIgnoreEmptyNotification = false;
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsClipboard::TransferableFromPasteboard(nsITransferable *aTransferable, NSPasteboard *cocoaPasteboard)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
// get flavor list that includes all acceptable flavors (including ones obtained through conversion)
|
||||
nsCOMPtr<nsIArray> flavorList;
|
||||
nsresult rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
uint32_t flavorCount;
|
||||
flavorList->GetLength(&flavorCount);
|
||||
|
||||
for (uint32_t i = 0; i < flavorCount; i++) {
|
||||
nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
|
||||
if (!currentFlavor)
|
||||
continue;
|
||||
|
||||
nsXPIDLCString flavorStr;
|
||||
currentFlavor->ToString(getter_Copies(flavorStr)); // i has a flavr
|
||||
|
||||
// printf("looking for clipboard data of type %s\n", flavorStr.get());
|
||||
|
||||
NSString *pboardType = nil;
|
||||
if (nsClipboard::IsStringType(flavorStr, &pboardType)) {
|
||||
NSString* pString = [cocoaPasteboard stringForType:pboardType];
|
||||
if (!pString)
|
||||
continue;
|
||||
|
||||
NSData* stringData;
|
||||
if ([pboardType isEqualToString:NSRTFPboardType]) {
|
||||
stringData = [pString dataUsingEncoding:NSASCIIStringEncoding];
|
||||
} else {
|
||||
stringData = [pString dataUsingEncoding:NSUnicodeStringEncoding];
|
||||
}
|
||||
unsigned int dataLength = [stringData length];
|
||||
void* clipboardDataPtr = malloc(dataLength);
|
||||
if (!clipboardDataPtr)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
[stringData getBytes:clipboardDataPtr];
|
||||
|
||||
// The DOM only wants LF, so convert from MacOS line endings to DOM line endings.
|
||||
int32_t signedDataLength = dataLength;
|
||||
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(flavorStr, &clipboardDataPtr, &signedDataLength);
|
||||
dataLength = signedDataLength;
|
||||
|
||||
// skip BOM (Byte Order Mark to distinguish little or big endian)
|
||||
char16_t* clipboardDataPtrNoBOM = (char16_t*)clipboardDataPtr;
|
||||
if ((dataLength > 2) &&
|
||||
((clipboardDataPtrNoBOM[0] == 0xFEFF) ||
|
||||
(clipboardDataPtrNoBOM[0] == 0xFFFE))) {
|
||||
dataLength -= sizeof(char16_t);
|
||||
clipboardDataPtrNoBOM += 1;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, clipboardDataPtrNoBOM, dataLength,
|
||||
getter_AddRefs(genericDataWrapper));
|
||||
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLength);
|
||||
free(clipboardDataPtr);
|
||||
break;
|
||||
}
|
||||
else if (flavorStr.EqualsLiteral(kCustomTypesMime)) {
|
||||
NSString* type = [cocoaPasteboard availableTypeFromArray:[NSArray arrayWithObject:kCustomTypesPboardType]];
|
||||
if (!type) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSData* pasteboardData = GetDataFromPasteboard(cocoaPasteboard, type);
|
||||
if (!pasteboardData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned int dataLength = [pasteboardData length];
|
||||
void* clipboardDataPtr = malloc(dataLength);
|
||||
if (!clipboardDataPtr) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
[pasteboardData getBytes:clipboardDataPtr];
|
||||
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, clipboardDataPtr, dataLength,
|
||||
getter_AddRefs(genericDataWrapper));
|
||||
|
||||
aTransferable->SetTransferData(flavorStr, genericDataWrapper, dataLength);
|
||||
free(clipboardDataPtr);
|
||||
}
|
||||
else if (flavorStr.EqualsLiteral(kJPEGImageMime) ||
|
||||
flavorStr.EqualsLiteral(kJPGImageMime) ||
|
||||
flavorStr.EqualsLiteral(kPNGImageMime) ||
|
||||
flavorStr.EqualsLiteral(kGIFImageMime)) {
|
||||
// Figure out if there's data on the pasteboard we can grab (sanity check)
|
||||
NSString *type = [cocoaPasteboard availableTypeFromArray:[NSArray arrayWithObjects:IMAGE_PASTEBOARD_TYPES]];
|
||||
if (!type)
|
||||
continue;
|
||||
|
||||
// Read data off the clipboard
|
||||
NSData *pasteboardData = GetDataFromPasteboard(cocoaPasteboard, type);
|
||||
if (!pasteboardData)
|
||||
continue;
|
||||
|
||||
// Figure out what type we're converting to
|
||||
CFStringRef outputType = NULL;
|
||||
if (flavorStr.EqualsLiteral(kJPEGImageMime) ||
|
||||
flavorStr.EqualsLiteral(kJPGImageMime))
|
||||
outputType = CFSTR("public.jpeg");
|
||||
else if (flavorStr.EqualsLiteral(kPNGImageMime))
|
||||
outputType = CFSTR("public.png");
|
||||
else if (flavorStr.EqualsLiteral(kGIFImageMime))
|
||||
outputType = CFSTR("com.compuserve.gif");
|
||||
else
|
||||
continue;
|
||||
|
||||
// Use ImageIO to interpret the data on the clipboard and transcode.
|
||||
// Note that ImageIO, like all CF APIs, allows NULLs to propagate freely
|
||||
// and safely in most cases (like ObjC). A notable exception is CFRelease.
|
||||
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
(NSNumber*)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
|
||||
(type == NSTIFFPboardType ? @"public.tiff" : @"public.png"),
|
||||
kCGImageSourceTypeIdentifierHint, nil];
|
||||
|
||||
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)pasteboardData,
|
||||
(CFDictionaryRef)options);
|
||||
NSMutableData *encodedData = [NSMutableData data];
|
||||
CGImageDestinationRef dest = CGImageDestinationCreateWithData((CFMutableDataRef)encodedData,
|
||||
outputType,
|
||||
1, NULL);
|
||||
CGImageDestinationAddImageFromSource(dest, source, 0, NULL);
|
||||
bool successfullyConverted = CGImageDestinationFinalize(dest);
|
||||
|
||||
if (successfullyConverted) {
|
||||
// Put the converted data in a form Gecko can understand
|
||||
nsCOMPtr<nsIInputStream> byteStream;
|
||||
NS_NewByteInputStream(getter_AddRefs(byteStream), (const char*)[encodedData bytes],
|
||||
[encodedData length], NS_ASSIGNMENT_COPY);
|
||||
|
||||
aTransferable->SetTransferData(flavorStr, byteStream, sizeof(nsIInputStream*));
|
||||
}
|
||||
|
||||
if (dest)
|
||||
CFRelease(dest);
|
||||
if (source)
|
||||
CFRelease(source);
|
||||
|
||||
if (successfullyConverted)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClipboard::GetNativeClipboardData(nsITransferable* aTransferable, int32_t aWhichClipboard)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if ((aWhichClipboard != kGlobalClipboard && aWhichClipboard != kFindClipboard) || !aTransferable)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NSPasteboard* cocoaPasteboard;
|
||||
if (aWhichClipboard == kFindClipboard) {
|
||||
cocoaPasteboard = [NSPasteboard pasteboardWithName:NSFindPboard];
|
||||
} else {
|
||||
cocoaPasteboard = [NSPasteboard generalPasteboard];
|
||||
}
|
||||
if (!cocoaPasteboard)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get flavor list that includes all acceptable flavors (including ones obtained through conversion)
|
||||
nsCOMPtr<nsIArray> flavorList;
|
||||
nsresult rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
uint32_t flavorCount;
|
||||
flavorList->GetLength(&flavorCount);
|
||||
|
||||
// If we were the last ones to put something on the pasteboard, then just use the cached
|
||||
// transferable. Otherwise clear it because it isn't relevant any more.
|
||||
if (mCachedClipboard == aWhichClipboard &&
|
||||
mChangeCount == [cocoaPasteboard changeCount]) {
|
||||
if (mTransferable) {
|
||||
for (uint32_t i = 0; i < flavorCount; i++) {
|
||||
nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
|
||||
if (!currentFlavor)
|
||||
continue;
|
||||
|
||||
nsXPIDLCString flavorStr;
|
||||
currentFlavor->ToString(getter_Copies(flavorStr));
|
||||
|
||||
nsCOMPtr<nsISupports> dataSupports;
|
||||
uint32_t dataSize = 0;
|
||||
rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(dataSupports), &dataSize);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aTransferable->SetTransferData(flavorStr, dataSupports, dataSize);
|
||||
return NS_OK; // maybe try to fill in more types? Is there a point?
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
EmptyClipboard(aWhichClipboard);
|
||||
}
|
||||
|
||||
// at this point we can't satisfy the request from cache data so let's look
|
||||
// for things other people put on the system clipboard
|
||||
|
||||
return nsClipboard::TransferableFromPasteboard(aTransferable, cocoaPasteboard);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
// returns true if we have *any* of the passed in flavors available for pasting
|
||||
NS_IMETHODIMP
|
||||
nsClipboard::HasDataMatchingFlavors(const char** aFlavorList, uint32_t aLength,
|
||||
int32_t aWhichClipboard, bool* outResult)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
*outResult = false;
|
||||
|
||||
if ((aWhichClipboard != kGlobalClipboard) || !aFlavorList)
|
||||
return NS_OK;
|
||||
|
||||
// first see if we have data for this in our cached transferable
|
||||
if (mTransferable) {
|
||||
nsCOMPtr<nsIArray> transferableFlavorList;
|
||||
nsresult rv = mTransferable->FlavorsTransferableCanImport(getter_AddRefs(transferableFlavorList));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
uint32_t transferableFlavorCount;
|
||||
transferableFlavorList->GetLength(&transferableFlavorCount);
|
||||
for (uint32_t j = 0; j < transferableFlavorCount; j++) {
|
||||
nsCOMPtr<nsISupportsCString> currentTransferableFlavor =
|
||||
do_QueryElementAt(transferableFlavorList, j);
|
||||
if (!currentTransferableFlavor)
|
||||
continue;
|
||||
nsXPIDLCString transferableFlavorStr;
|
||||
currentTransferableFlavor->ToString(getter_Copies(transferableFlavorStr));
|
||||
|
||||
for (uint32_t k = 0; k < aLength; k++) {
|
||||
if (transferableFlavorStr.Equals(aFlavorList[k])) {
|
||||
*outResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSPasteboard* generalPBoard = [NSPasteboard generalPasteboard];
|
||||
|
||||
for (uint32_t i = 0; i < aLength; i++) {
|
||||
nsDependentCString mimeType(aFlavorList[i]);
|
||||
NSString *pboardType = nil;
|
||||
|
||||
if (nsClipboard::IsStringType(mimeType, &pboardType)) {
|
||||
NSString* availableType = [generalPBoard availableTypeFromArray:[NSArray arrayWithObject:pboardType]];
|
||||
if (availableType && [availableType isEqualToString:pboardType]) {
|
||||
*outResult = true;
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp(aFlavorList[i], kCustomTypesMime)) {
|
||||
NSString* availableType = [generalPBoard availableTypeFromArray:[NSArray arrayWithObject:kCustomTypesPboardType]];
|
||||
if (availableType) {
|
||||
*outResult = true;
|
||||
break;
|
||||
}
|
||||
} else if (!strcmp(aFlavorList[i], kJPEGImageMime) ||
|
||||
!strcmp(aFlavorList[i], kJPGImageMime) ||
|
||||
!strcmp(aFlavorList[i], kPNGImageMime) ||
|
||||
!strcmp(aFlavorList[i], kGIFImageMime)) {
|
||||
NSString* availableType = [generalPBoard availableTypeFromArray:
|
||||
[NSArray arrayWithObjects:IMAGE_PASTEBOARD_TYPES]];
|
||||
if (availableType) {
|
||||
*outResult = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClipboard::SupportsFindClipboard(bool *_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This function converts anything that other applications might understand into the system format
|
||||
// and puts it into a dictionary which it returns.
|
||||
// static
|
||||
NSDictionary*
|
||||
nsClipboard::PasteboardDictFromTransferable(nsITransferable* aTransferable)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (!aTransferable)
|
||||
return nil;
|
||||
|
||||
NSMutableDictionary* pasteboardOutputDict = [NSMutableDictionary dictionary];
|
||||
|
||||
nsCOMPtr<nsIArray> flavorList;
|
||||
nsresult rv = aTransferable->FlavorsTransferableCanExport(getter_AddRefs(flavorList));
|
||||
if (NS_FAILED(rv))
|
||||
return nil;
|
||||
|
||||
uint32_t flavorCount;
|
||||
flavorList->GetLength(&flavorCount);
|
||||
for (uint32_t i = 0; i < flavorCount; i++) {
|
||||
nsCOMPtr<nsISupportsCString> currentFlavor = do_QueryElementAt(flavorList, i);
|
||||
if (!currentFlavor)
|
||||
continue;
|
||||
|
||||
nsXPIDLCString flavorStr;
|
||||
currentFlavor->ToString(getter_Copies(flavorStr));
|
||||
|
||||
MOZ_LOG(sCocoaLog, LogLevel::Info, ("writing out clipboard data of type %s (%d)\n", flavorStr.get(), i));
|
||||
|
||||
NSString *pboardType = nil;
|
||||
|
||||
if (nsClipboard::IsStringType(flavorStr, &pboardType)) {
|
||||
void* data = nullptr;
|
||||
uint32_t dataSize = 0;
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize);
|
||||
nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize);
|
||||
|
||||
NSString* nativeString;
|
||||
if (data)
|
||||
nativeString = [NSString stringWithCharacters:(const unichar*)data length:(dataSize / sizeof(char16_t))];
|
||||
else
|
||||
nativeString = [NSString string];
|
||||
|
||||
// be nice to Carbon apps, normalize the receiver's contents using Form C.
|
||||
nativeString = [nativeString precomposedStringWithCanonicalMapping];
|
||||
|
||||
[pasteboardOutputDict setObject:nativeString forKey:pboardType];
|
||||
|
||||
free(data);
|
||||
}
|
||||
else if (flavorStr.EqualsLiteral(kCustomTypesMime)) {
|
||||
void* data = nullptr;
|
||||
uint32_t dataSize = 0;
|
||||
nsCOMPtr<nsISupports> genericDataWrapper;
|
||||
rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize);
|
||||
nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize);
|
||||
|
||||
if (data) {
|
||||
NSData* nativeData = [NSData dataWithBytes:data length:dataSize];
|
||||
|
||||
[pasteboardOutputDict setObject:nativeData forKey:kCustomTypesPboardType];
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
else if (flavorStr.EqualsLiteral(kPNGImageMime) || flavorStr.EqualsLiteral(kJPEGImageMime) ||
|
||||
flavorStr.EqualsLiteral(kJPGImageMime) || flavorStr.EqualsLiteral(kGIFImageMime) ||
|
||||
flavorStr.EqualsLiteral(kNativeImageMime)) {
|
||||
uint32_t dataSize = 0;
|
||||
nsCOMPtr<nsISupports> transferSupports;
|
||||
aTransferable->GetTransferData(flavorStr, getter_AddRefs(transferSupports), &dataSize);
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ptrPrimitive(do_QueryInterface(transferSupports));
|
||||
if (!ptrPrimitive)
|
||||
continue;
|
||||
|
||||
nsCOMPtr<nsISupports> primitiveData;
|
||||
ptrPrimitive->GetData(getter_AddRefs(primitiveData));
|
||||
|
||||
nsCOMPtr<imgIContainer> image(do_QueryInterface(primitiveData));
|
||||
if (!image) {
|
||||
NS_WARNING("Image isn't an imgIContainer in transferable");
|
||||
continue;
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> surface =
|
||||
image->GetFrame(imgIContainer::FRAME_CURRENT,
|
||||
imgIContainer::FLAG_SYNC_DECODE);
|
||||
if (!surface) {
|
||||
continue;
|
||||
}
|
||||
CGImageRef imageRef = NULL;
|
||||
rv = nsCocoaUtils::CreateCGImageFromSurface(surface, &imageRef);
|
||||
if (NS_FAILED(rv) || !imageRef) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert the CGImageRef to TIFF data.
|
||||
CFMutableDataRef tiffData = CFDataCreateMutable(kCFAllocatorDefault, 0);
|
||||
CGImageDestinationRef destRef = CGImageDestinationCreateWithData(tiffData,
|
||||
CFSTR("public.tiff"),
|
||||
1,
|
||||
NULL);
|
||||
CGImageDestinationAddImage(destRef, imageRef, NULL);
|
||||
bool successfullyConverted = CGImageDestinationFinalize(destRef);
|
||||
|
||||
CGImageRelease(imageRef);
|
||||
if (destRef)
|
||||
CFRelease(destRef);
|
||||
|
||||
if (!successfullyConverted) {
|
||||
if (tiffData)
|
||||
CFRelease(tiffData);
|
||||
continue;
|
||||
}
|
||||
|
||||
[pasteboardOutputDict setObject:(NSMutableData*)tiffData forKey:NSTIFFPboardType];
|
||||
if (tiffData)
|
||||
CFRelease(tiffData);
|
||||
}
|
||||
else if (flavorStr.EqualsLiteral(kFileMime)) {
|
||||
uint32_t len = 0;
|
||||
nsCOMPtr<nsISupports> genericFile;
|
||||
rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericFile), &len);
|
||||
if (NS_FAILED(rv)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> file(do_QueryInterface(genericFile));
|
||||
if (!file) {
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ptr(do_QueryInterface(genericFile));
|
||||
|
||||
if (ptr) {
|
||||
ptr->GetData(getter_AddRefs(genericFile));
|
||||
file = do_QueryInterface(genericFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoString fileURI;
|
||||
rv = file->GetPath(fileURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSString* str = nsCocoaUtils::ToNSString(fileURI);
|
||||
NSArray* fileList = [NSArray arrayWithObjects:str, nil];
|
||||
[pasteboardOutputDict setObject:fileList forKey:NSFilenamesPboardType];
|
||||
}
|
||||
else if (flavorStr.EqualsLiteral(kFilePromiseMime)) {
|
||||
[pasteboardOutputDict setObject:[NSArray arrayWithObject:@""] forKey:NSFilesPromisePboardType];
|
||||
}
|
||||
else if (flavorStr.EqualsLiteral(kURLMime)) {
|
||||
uint32_t len = 0;
|
||||
nsCOMPtr<nsISupports> genericURL;
|
||||
rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(genericURL), &len);
|
||||
nsCOMPtr<nsISupportsString> urlObject(do_QueryInterface(genericURL));
|
||||
|
||||
nsAutoString url;
|
||||
urlObject->GetData(url);
|
||||
|
||||
// A newline embedded in the URL means that the form is actually URL + title.
|
||||
int32_t newlinePos = url.FindChar(char16_t('\n'));
|
||||
if (newlinePos >= 0) {
|
||||
url.Truncate(newlinePos);
|
||||
|
||||
nsAutoString urlTitle;
|
||||
urlObject->GetData(urlTitle);
|
||||
urlTitle.Mid(urlTitle, newlinePos + 1, len - (newlinePos + 1));
|
||||
|
||||
NSString *nativeTitle = [[NSString alloc] initWithCharacters:reinterpret_cast<const unichar*>(urlTitle.get())
|
||||
length:urlTitle.Length()];
|
||||
// be nice to Carbon apps, normalize the receiver's contents using Form C.
|
||||
[pasteboardOutputDict setObject:[nativeTitle precomposedStringWithCanonicalMapping] forKey:kCorePboardType_urln];
|
||||
// Also put the title out as 'urld', since some recipients will look for that.
|
||||
[pasteboardOutputDict setObject:[nativeTitle precomposedStringWithCanonicalMapping] forKey:kCorePboardType_urld];
|
||||
[nativeTitle release];
|
||||
}
|
||||
|
||||
// The Finder doesn't like getting random binary data aka
|
||||
// Unicode, so change it into an escaped URL containing only
|
||||
// ASCII.
|
||||
nsAutoCString utf8Data = NS_ConvertUTF16toUTF8(url.get(), url.Length());
|
||||
nsAutoCString escData;
|
||||
NS_EscapeURL(utf8Data.get(), utf8Data.Length(), esc_OnlyNonASCII|esc_AlwaysCopy, escData);
|
||||
|
||||
// printf("Escaped url is %s, length %d\n", escData.get(), escData.Length());
|
||||
|
||||
NSString *nativeURL = [NSString stringWithUTF8String:escData.get()];
|
||||
[pasteboardOutputDict setObject:nativeURL forKey:kCorePboardType_url];
|
||||
}
|
||||
// If it wasn't a type that we recognize as exportable we don't put it on the system
|
||||
// clipboard. We'll just access it from our cached transferable when we need it.
|
||||
}
|
||||
|
||||
return pasteboardOutputDict;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
bool nsClipboard::IsStringType(const nsCString& aMIMEType, NSString** aPasteboardType)
|
||||
{
|
||||
if (aMIMEType.EqualsLiteral(kUnicodeMime)) {
|
||||
*aPasteboardType = NSStringPboardType;
|
||||
return true;
|
||||
} else if (aMIMEType.EqualsLiteral(kRTFMime)) {
|
||||
*aPasteboardType = NSRTFPboardType;
|
||||
return true;
|
||||
} else if (aMIMEType.EqualsLiteral(kHTMLMime)) {
|
||||
*aPasteboardType = NSHTMLPboardType;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
NSString* nsClipboard::WrapHtmlForSystemPasteboard(NSString* aString)
|
||||
{
|
||||
NSString* wrapped =
|
||||
[NSString stringWithFormat:
|
||||
@"<html>"
|
||||
"<head>"
|
||||
"<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">"
|
||||
"</head>"
|
||||
"<body>"
|
||||
"%@"
|
||||
"</body>"
|
||||
"</html>", aString];
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the transferable object
|
||||
*
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsClipboard::SetData(nsITransferable* aTransferable, nsIClipboardOwner* anOwner,
|
||||
int32_t aWhichClipboard)
|
||||
{
|
||||
NS_ASSERTION (aTransferable, "clipboard given a null transferable");
|
||||
|
||||
if (aWhichClipboard == kSelectionCache) {
|
||||
if (aTransferable) {
|
||||
SetSelectionCache(aTransferable);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (aTransferable == mTransferable && anOwner == mClipboardOwner) {
|
||||
return NS_OK;
|
||||
}
|
||||
bool selectClipPresent;
|
||||
SupportsSelectionClipboard(&selectClipPresent);
|
||||
bool findClipPresent;
|
||||
SupportsFindClipboard(&findClipPresent);
|
||||
if (!selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
EmptyClipboard(aWhichClipboard);
|
||||
|
||||
mClipboardOwner = anOwner;
|
||||
mTransferable = aTransferable;
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
if (mTransferable) {
|
||||
rv = SetNativeClipboardData(aWhichClipboard);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transferable object
|
||||
*
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsClipboard::GetData(nsITransferable* aTransferable, int32_t aWhichClipboard)
|
||||
{
|
||||
NS_ASSERTION (aTransferable, "clipboard given a null transferable");
|
||||
|
||||
bool selectClipPresent;
|
||||
SupportsSelectionClipboard(&selectClipPresent);
|
||||
bool findClipPresent;
|
||||
SupportsFindClipboard(&findClipPresent);
|
||||
if (!selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (aTransferable) {
|
||||
return GetNativeClipboardData(aTransferable, aWhichClipboard);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClipboard::EmptyClipboard(int32_t aWhichClipboard)
|
||||
{
|
||||
if (aWhichClipboard == kSelectionCache) {
|
||||
ClearSelectionCache();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool selectClipPresent;
|
||||
SupportsSelectionClipboard(&selectClipPresent);
|
||||
bool findClipPresent;
|
||||
SupportsFindClipboard(&findClipPresent);
|
||||
if (!selectClipPresent && !findClipPresent && aWhichClipboard != kGlobalClipboard) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (mIgnoreEmptyNotification) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mClipboardOwner) {
|
||||
mClipboardOwner->LosingOwnership(mTransferable);
|
||||
mClipboardOwner = nullptr;
|
||||
}
|
||||
|
||||
mTransferable = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClipboard::SupportsSelectionClipboard(bool* _retval)
|
||||
{
|
||||
*_retval = false; // we don't support the selection clipboard by default.
|
||||
return NS_OK;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue