Copy'n'paste (340071) and drag'n'drop (340890) between Mozilla app running natively and Mozilla app running under Rosetta translation does not work [properly]. Byte-swap UTF-16 text in private flavors when running under Rosetta. r=josh sr=pink a/1.8.1=me

This commit is contained in:
mark%moxienet.com 2006-06-15 17:13:59 +00:00
Родитель a40af53e5c
Коммит 34b5a77a24
4 изменённых файлов: 126 добавлений и 3 удалений

Просмотреть файл

@ -68,11 +68,16 @@
#include "nsStylClipboardUtils.h"
#include "nsLinebreakConverter.h"
#include "nsAutoPtr.h"
#include "nsIServiceManager.h"
#include "nsIMacUtils.h"
#include <Scrap.h>
#include <Script.h>
#include <TextEdit.h>
static const PRUint32 kPrivateFlavorMask = 0xffff0000;
static const PRUint32 kPrivateFlavorTag = 'MZ..' & kPrivateFlavorMask;
//
@ -330,10 +335,30 @@ nsresult
nsClipboard :: PutOnClipboard ( ResType inFlavor, const void* inData, PRInt32 inLen )
{
nsresult errCode = NS_OK;
void* data = (void*) inData;
if ((inFlavor & kPrivateFlavorMask) == kPrivateFlavorTag) {
// Byte-swap private flavors if running translated
nsCOMPtr<nsIMacUtils> macUtils =
do_GetService("@mozilla.org/xpcom/mac-utils;1");
PRBool isTranslated;
if (macUtils &&
NS_SUCCEEDED(macUtils->GetIsTranslated(&isTranslated)) &&
isTranslated) {
data = nsMemory::Alloc(inLen);
if (!data)
return NS_ERROR_OUT_OF_MEMORY;
swab(inData, data, inLen);
}
}
ScrapRef scrap;
::GetCurrentScrap(&scrap);
::PutScrapFlavor( scrap, inFlavor, kScrapFlavorMaskNone, inLen, inData );
::PutScrapFlavor( scrap, inFlavor, kScrapFlavorMaskNone, inLen, data );
if (data != inData)
nsMemory::Free(data);
return errCode;
@ -557,6 +582,26 @@ nsClipboard :: GetDataOffClipboard ( ResType inMacFlavor, void** outData, PRInt3
return NS_ERROR_FAILURE;
}
if ((inMacFlavor & kPrivateFlavorMask) == kPrivateFlavorTag) {
// Byte-swap private flavors if running translated
nsCOMPtr<nsIMacUtils> macUtils =
do_GetService("@mozilla.org/xpcom/mac-utils;1");
PRBool isTranslated;
if (macUtils &&
NS_SUCCEEDED(macUtils->GetIsTranslated(&isTranslated)) &&
isTranslated) {
char* swappedData = (char*) nsMemory::Alloc(dataSize);
if (!swappedData) {
nsMemory::Free(dataBuff);
return NS_ERROR_OUT_OF_MEMORY;
}
swab(dataBuff, swappedData, dataSize);
nsMemory::Free(dataBuff);
dataBuff = swappedData;
}
}
// put it into the transferable
if ( outDataSize )
*outDataSize = dataSize;

Просмотреть файл

@ -60,6 +60,7 @@
#include "nsCRT.h"
#include "nsPrimitiveHelpers.h"
#include "nsLinebreakConverter.h"
#include "nsIMacUtils.h"
#include "nsIContent.h"
#include "nsIDOMNode.h"
@ -104,6 +105,9 @@ GetPrimaryFrameFor(nsIContent* aContent)
return result;
}
static const PRUint32 kPrivateFlavorMask = 0xffff0000;
static const PRUint32 kPrivateFlavorTag = 'MZ..' & kPrivateFlavorMask;
static void
SetPortToKnownGoodPort()
@ -793,6 +797,26 @@ nsDragService::DragSendDataProc(FlavorType inFlavor, void* inRefCon, ItemReferen
PRUint32 dataSize = 0;
retVal = dragService->GetDataForFlavor(dragService->mDataItems, inDragRef, inItemRef, inFlavor, &data, &dataSize);
if ( retVal == noErr ) {
if ((inFlavor & kPrivateFlavorMask) == kPrivateFlavorTag) {
// Byte-swap private flavors if running translated
nsCOMPtr<nsIMacUtils> macUtils =
do_GetService("@mozilla.org/xpcom/mac-utils;1");
PRBool isTranslated;
if (macUtils &&
NS_SUCCEEDED(macUtils->GetIsTranslated(&isTranslated)) &&
isTranslated) {
char* swappedData = (char*) nsMemory::Alloc(dataSize);
if (!swappedData) {
nsMemory::Free(data);
return notEnoughMemoryErr;
}
else {
swab(data, swappedData, dataSize);
nsMemory::Free(data);
data = swappedData;
}
}
}
// make the data accessible to the DragManager
retVal = ::SetDragItemFlavorData ( inDragRef, inItemRef, inFlavor, data, dataSize, 0 );
NS_ASSERTION ( retVal == noErr, "SDIFD failed in DragSendDataProc" );
@ -1095,7 +1119,27 @@ nsDragService::ExtractDataFromOS ( DragReference inDragRef, ItemReference inItem
buff = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(buffSize + 1));
if ( buff ) {
err = ::GetFlavorData ( inDragRef, inItemRef, inFlavor, buff, &buffSize, 0 );
if ( err ) {
if (err == noErr) {
if ((inFlavor & kPrivateFlavorMask) == kPrivateFlavorTag) {
// Byte-swap private flavors if running translated
nsCOMPtr<nsIMacUtils> macUtils =
do_GetService("@mozilla.org/xpcom/mac-utils;1");
PRBool isTranslated;
if (macUtils &&
NS_SUCCEEDED(macUtils->GetIsTranslated(&isTranslated)) &&
isTranslated) {
char* swappedData = (char*) nsMemory::Alloc(buffSize);
if (!swappedData)
retval = NS_ERROR_OUT_OF_MEMORY;
else {
swab(buff, swappedData, buffSize);
nsMemory::Free(buff);
buff = swappedData;
}
}
}
}
else {
#ifdef NS_DEBUG
printf("nsDragService: Error getting data out of drag manager, #%d\n", err);
#endif

Просмотреть файл

@ -41,7 +41,7 @@
* nsIMacUtils: Generic globally-available Mac-specific utilities.
*/
[scriptable, uuid(59BE3453-873B-450D-8DB8-2643E08A00BE)]
[scriptable, uuid(F6FC107C-5CBA-4C5C-A35E-B69D580D1DB6)]
interface nsIMacUtils : nsISupports
{
/**
@ -49,4 +49,9 @@ interface nsIMacUtils : nsISupports
* ppc and x86 (universal binary).
*/
readonly attribute boolean isUniversalBinary;
/**
* True when running under binary translation (Rosetta).
*/
readonly attribute boolean isTranslated;
};

Просмотреть файл

@ -40,6 +40,7 @@
#include <CoreFoundation/CoreFoundation.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/sysctl.h>
#include <mach-o/fat.h>
NS_IMPL_ISUPPORTS1(nsMacUtilsImpl, nsIMacUtils)
@ -123,3 +124,31 @@ done:
return NS_OK;
}
/* readonly attribute boolean isTranslated; */
// True when running under binary translation (Rosetta).
NS_IMETHODIMP nsMacUtilsImpl::GetIsTranslated(PRBool *aIsTranslated)
{
#ifdef __ppc__
static PRBool sInitialized = PR_FALSE;
// Initialize sIsNative to 1. If the sysctl fails because it doesn't
// exist, then translation is not possible, so the process must not be
// running translated.
static PRInt32 sIsNative = 1;
if (!sInitialized) {
size_t sz = sizeof(sIsNative);
sysctlbyname("sysctl.proc_native", &sIsNative, &sz, NULL, 0);
sInitialized = PR_TRUE;
}
*aIsTranslated = !sIsNative;
#else
// Translation only exists for ppc code. Other architectures aren't
// translated.
*aIsTranslated = PR_FALSE;
#endif
return NS_OK;
}