Landing changes from CHIMERA_M1_0_1_BRANCH. Not part of the normal build.

This commit is contained in:
bryner%netscape.com 2002-12-13 08:43:18 +00:00
Родитель cac25a75bc
Коммит a255586f6a
22 изменённых файлов: 2189 добавлений и 1504 удалений

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

@ -44,7 +44,7 @@ REQUIRES = xpcom \
nkcache \
locale \
pref \
appshell \
exthandler \
intl \
mimetype \
unicharutil \
@ -57,7 +57,6 @@ EXPORTS = \
GFX_LCPPSRCS = \
nsRegionMac.cpp \
nsWatchTask.cpp \
nsRepeater.cpp \
$(NULL)
@ -67,7 +66,6 @@ CPPSRCS = \
nsDeleteObserver.cpp \
nsDragService.cpp \
nsDragHelperService.cpp \
nsFilePicker.cpp \
nsLookAndFeel.cpp \
nsMacResources.cpp \
nsMenuX.cpp \
@ -80,6 +78,7 @@ CPPSRCS = \
$(NULL)
CMMSRCS = \
nsFilePicker.mm \
nsScrollbar.mm \
nsToolkit.mm \
nsAppShellCocoa.mm \

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

@ -35,6 +35,7 @@
*
* ***** END LICENSE BLOCK ***** */
#undef DARWIN
#import <Cocoa/Cocoa.h>
class nsIWidget;

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

@ -44,6 +44,7 @@
// interface may change, so this comment must be updated accordingly.)
//
#undef DARWIN
#import <Cocoa/Cocoa.h>
#include "nsAppShellCocoa.h"

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

@ -41,6 +41,7 @@
#include "nsISupports.h"
#include "nsBaseWidget.h"
#include "nsIPluginWidget.h"
#include "nsDeleteObserver.h"
#include "nsIEventSink.h"
@ -62,12 +63,13 @@
struct nsPluginPort;
#undef DARWIN
#import <Cocoa/Cocoa.h>
class nsChildView;
@interface ChildView : NSQuickDrawView<mozView>
@interface ChildView : NSQuickDrawView<mozView, NSTextInput>
{
NSWindow* mWindow; // shortcut to the top window, [WEAK]
@ -83,25 +85,16 @@ class nsChildView;
// Whether we're a plugin view.
BOOL mIsPluginView;
BOOL mLastKeyEventWasSentToCocoa;
NSEvent* mCurEvent; // only valid during a keyDown
// needed for NSTextInput implementation
NSRange mMarkedRange;
NSRange mSelectedRange;
BOOL mInComposition;
}
// sets up our view, attaching it to its owning gecko view
- (id) initWithGeckoChild:(nsChildView*)child eventSink:(nsIEventSink*)sink;
// convert from one event system to the other for event dispatching
- (void) convert:(NSEvent*)inEvent message:(PRInt32)inMsg toGeckoEvent:(nsInputEvent*)outGeckoEvent;
// create a gecko key event out of a cocoa event
- (void) convert:(NSEvent*)aKeyEvent message:(PRUint32)aMessage
isChar:(PRBool*)outIsChar
toGeckoEvent:(nsKeyEvent*)outGeckoEvent;
- (void) convert:(NSPoint)inPoint message:(PRInt32)inMsg
modifiers:(unsigned int)inMods toGeckoEvent:(nsInputEvent*)outGeckoEvent;
-(NSMenu*)getContextMenu;
-(void)setIsPluginView:(BOOL)aIsPlugin;
@end
@ -112,7 +105,11 @@ class nsChildView;
//
//-------------------------------------------------------------------------
class nsChildView : public nsBaseWidget, public nsDeleteObserved, public nsIKBStateControl, public nsIEventSink
class nsChildView : public nsBaseWidget,
public nsDeleteObserved,
public nsIPluginWidget,
public nsIKBStateControl,
public nsIEventSink
{
private:
typedef nsBaseWidget Inherited;
@ -178,8 +175,9 @@ public:
virtual nsIFontMetrics* GetFont(void);
NS_IMETHOD SetFont(const nsFont &aFont);
NS_IMETHOD Invalidate(PRBool aIsSynchronous);
NS_IMETHOD Invalidate(const nsRect &aRect,PRBool aIsSynchronous);
NS_IMETHOD InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous);
NS_IMETHOD Invalidate(const nsRect &aRect,PRBool aIsSynchronous);
NS_IMETHOD InvalidateRegion(const nsIRegion *aRegion, PRBool aIsSynchronous);
NS_IMETHOD Validate();
virtual void* GetNativeData(PRUint32 aDataType);
NS_IMETHOD SetColorMap(nsColorMap *aColorMap);
@ -190,7 +188,7 @@ public:
NS_IMETHOD EndResizingChildren(void);
static PRBool ConvertStatus(nsEventStatus aStatus);
NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus);
NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus);
virtual PRBool DispatchMouseEvent(nsMouseEvent &aEvent);
virtual void StartDraw(nsIRenderingContext* aRenderingContext = nsnull);
@ -199,9 +197,9 @@ public:
virtual void UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext);
virtual void ConvertToDeviceCoordinates(nscoord &aX, nscoord &aY);
void LocalToWindowCoordinate(nsPoint& aPoint) { ConvertToDeviceCoordinates(aPoint.x, aPoint.y); }
void LocalToWindowCoordinate(nscoord& aX, nscoord& aY) { ConvertToDeviceCoordinates(aX, aY); }
void LocalToWindowCoordinate(nsRect& aRect) { ConvertToDeviceCoordinates(aRect.x, aRect.y); }
void LocalToWindowCoordinate(nsPoint& aPoint) { ConvertToDeviceCoordinates(aPoint.x, aPoint.y); }
void LocalToWindowCoordinate(nscoord& aX, nscoord& aY) { ConvertToDeviceCoordinates(aX, aY); }
void LocalToWindowCoordinate(nsRect& aRect) { ConvertToDeviceCoordinates(aRect.x, aRect.y); }
NS_IMETHOD SetMenuBar(nsIMenuBar * aMenuBar);
NS_IMETHOD ShowMenuBar(PRBool aShow);
@ -216,17 +214,28 @@ public:
NS_IMETHOD GetAttention();
// nsIPluginWidget
NS_IMETHOD GetPluginClipRect(nsRect& outClipRect, nsPoint& outOrigin);
NS_IMETHOD StartDrawPlugin();
NS_IMETHOD EndDrawPlugin();
// Mac specific methods
virtual void CalcWindowRegions();
virtual PRBool PointInWidget(Point aThePoint);
virtual PRBool PointInWidget(Point aThePoint);
virtual PRBool DispatchWindowEvent(nsGUIEvent& event);
virtual PRBool DispatchWindowEvent(nsGUIEvent &event,nsEventStatus &aStatus);
virtual PRBool DispatchWindowEvent(nsGUIEvent& event);
virtual PRBool DispatchWindowEvent(nsGUIEvent &event,nsEventStatus &aStatus);
virtual void AcceptFocusOnClick(PRBool aBool) { mAcceptFocusOnClick = aBool;};
PRBool AcceptFocusOnClick() { return mAcceptFocusOnClick;};
void Flash(nsPaintEvent &aEvent);
void RemovedFromWindow();
void AddedToWindow();
void LiveResizeStarted();
void LiveResizeEnded();
public:
// nsIKBStateControl interface
NS_IMETHOD ResetInputState();
@ -260,23 +269,28 @@ public:
const char* gInstanceClassName;
#endif
id mView; // my parallel cocoa view, [STRONG]
id mView; // my parallel cocoa view, [STRONG]
NSView* mParentView;
NSView* mParentView;
nsIWidget* mParentWidget;
PRBool mDestroyCalled;
PRBool mDestructorCalled;
PRBool mVisible;
nsIFontMetrics* mFontMetrics;
nsIRenderingContext* mTempRenderingContext;
nsIFontMetrics* mFontMetrics;
PRBool mDrawing;
nsIRenderingContext* mTempRenderingContext;
PRBool mTempRenderingContextMadeHere;
PRPackedBool mDestroyCalled;
PRPackedBool mDestructorCalled;
PRPackedBool mVisible;
PRPackedBool mInWindow; // true if the widget is in a visible tab
PRPackedBool mDrawing;
PRPackedBool mTempRenderingContextMadeHere;
nsPluginPort* mPluginPort;
PRBool mAcceptFocusOnClick;
PRPackedBool mAcceptFocusOnClick;
PRPackedBool mLiveResizeInProgress;
PRPackedBool mPluginDrawing;
nsPluginPort* mPluginPort;
RgnHandle mVisRgn;
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -62,6 +62,7 @@
#include "nsPrimitiveHelpers.h"
#include "nsIImageMac.h"
#include "nsMemory.h"
#include "nsLinebreakConverter.h"
#include <Scrap.h>
@ -147,11 +148,21 @@ nsClipboard :: SetNativeClipboardData ( PRInt32 aWhichClipboard )
nsCOMPtr<nsISupports> genericDataWrapper;
errCode = mTransferable->GetTransferData ( flavorStr, getter_AddRefs(genericDataWrapper), &dataSize );
nsPrimitiveHelpers::CreateDataFromPrimitive ( flavorStr, genericDataWrapper, &data, dataSize );
// Convert unix to mac linebreaks, since mac linebreaks are required for clipboard compatibility.
// I'm making the assumption here that the substitution will be entirely in-place, since both
// types of line breaks are 1-byte.
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, data);
nsLinebreakConverter::ConvertUnicharLineBreaksInSitu(&castedUnicode,
nsLinebreakConverter::eLinebreakUnix,
nsLinebreakConverter::eLinebreakMac,
dataSize / sizeof(PRUnichar), nsnull);
errCode = PutOnClipboard ( macOSFlavor, data, dataSize );
if ( NS_SUCCEEDED(errCode) ) {
// we also need to put it on as 'TEXT' after doing the conversion to the platform charset.
char* plainTextData = nsnull;
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, data);
PRInt32 plainTextLen = 0;
nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText ( castedUnicode, dataSize / 2, &plainTextData, &plainTextLen );
if ( plainTextData ) {
@ -324,9 +335,22 @@ nsClipboard :: GetNativeClipboardData ( nsITransferable * aTransferable, PRInt32
// from MacOS line endings to DOM line endings.
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &clipboardData, &dataSize );
unsigned char *clipboardDataPtr = (unsigned char *) clipboardData;
// skip BOM (Byte Order Mark to distinguish little or big endian) in 'utxt'
// 10.2 puts BOM for 'utxt', we need to remove it here
// for little endian case, we also need to convert the data to big endian
// but we do not do that currently (need this in case 'utxt' is really in little endian)
if ( (macOSFlavor == 'utxt') &&
(dataSize > 2) &&
((clipboardDataPtr[0] == 0xFE && clipboardDataPtr[1] == 0xFF) ||
(clipboardDataPtr[0] == 0xFF && clipboardDataPtr[1] == 0xFE)) ) {
dataSize -= sizeof(PRUnichar);
clipboardDataPtr += sizeof(PRUnichar);
}
// put it into the transferable
nsCOMPtr<nsISupports> genericDataWrapper;
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, clipboardData, dataSize, getter_AddRefs(genericDataWrapper) );
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, clipboardDataPtr, dataSize, getter_AddRefs(genericDataWrapper) );
errCode = aTransferable->SetTransferData ( flavorStr, genericDataWrapper, dataSize );
}

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

@ -37,6 +37,7 @@
#ifndef MacWindow_h__
#define MacWindow_h__
#undef DARWIN
#import <Cocoa/Cocoa.h>

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

@ -1343,7 +1343,6 @@ NS_IMETHODIMP nsCocoaWindow::Resize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRIn
//-------------------------------------------------------------------------
NS_IMETHODIMP nsCocoaWindow::Resize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
{
printf("resizing to %d %d\n", aWidth, aHeight);
if ( mWindow ) {
NSRect newBounds = [mWindow frame];
newBounds.size.width = aWidth;
@ -1743,25 +1742,25 @@ void StopResizing ( )
- (void)windowDidBecomeMain:(NSNotification *)aNotification
{
printf("got activation\n");
//printf("got activation\n");
}
- (void)windowDidResignMain:(NSNotification *)aNotification
{
printf("got deactivate\n");
//printf("got deactivate\n");
}
- (void)windowDidBecomeKey:(NSNotification *)aNotification
{
printf("we're key window\n");
//printf("we're key window\n");
}
- (void)windowDidResignKey:(NSNotification *)aNotification
{
printf("we're not the key window\n");
//printf("we're not the key window\n");
}

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

@ -177,8 +177,6 @@ nsDragHelperService::Leave ( DragReference inDragRef, nsIEventSink *inSink )
PRBool handled = PR_FALSE;
inSink->DragEvent ( NS_DRAGDROP_EXIT, mouseLocGlobal.h, mouseLocGlobal.v, 0L, &handled );
::HideDragHilite ( inDragRef );
// we're _really_ done with it, so let go of the service.
mDragService = nsnull;

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

@ -43,6 +43,7 @@
// See associated header file for details
//
#include <Gestalt.h>
#include "nsDragService.h"
@ -57,13 +58,9 @@
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsPrimitiveHelpers.h"
#ifndef XP_MACOSX
#include "nsILocalFileMac.h"
#endif
#include "nsWatchTask.h"
// rjc
#include <Gestalt.h>
#include "nsIContent.h"
#include "nsIDOMNode.h"
#include "nsIDocument.h"
@ -75,9 +72,11 @@
#include "nsPoint.h"
#include "nsIWidget.h"
#include "nsCarbonHelpers.h"
#include "nsGfxUtils.h"
#include "nsIXULContent.h"
#include "nsIDOMElement.h"
#include "nsLinebreakConverter.h"
// we need our own stuff for MacOS because of nsIDragSessionMac.
@ -101,7 +100,8 @@ nsDragService::nsDragService()
mImageDraggingSupported = PR_TRUE;
}
#endif
//printf("Making drag service %X\n", this);
mDragSendDataUPP = NewDragSendDataUPP(DragSendDataProc);
}
@ -111,6 +111,8 @@ nsDragService::nsDragService()
//
nsDragService::~nsDragService()
{
//printf("Deleting drag service %X\n", this);
if ( mDragSendDataUPP )
::DisposeDragSendDataUPP(mDragSendDataUPP);
}
@ -214,6 +216,15 @@ nsDragService :: ComputeGlobalRectFromFrame ( nsIDOMNode* aDOMNode, Rect & outSc
NS_IMETHODIMP
nsDragService :: InvokeDragSession (nsIDOMNode *aDOMNode, nsISupportsArray * aTransferableArray, nsIScriptableRegion * aDragRgn, PRUint32 aActionType)
{
#ifdef MOZ_WIDGET_COCOA
nsGraphicsUtils::SetPortToKnownGoodPort();
GrafPtr port;
GDHandle handle;
::GetGWorld(&port, &handle);
if (!IsValidPort(port))
return NS_ERROR_FAILURE;
#endif
::InitCursor();
nsBaseDragService::InvokeDragSession ( aDOMNode, aTransferableArray, aDragRgn, aActionType );
@ -222,14 +233,10 @@ nsDragService :: InvokeDragSession (nsIDOMNode *aDOMNode, nsISupportsArray * aTr
if ( result != noErr )
return NS_ERROR_FAILURE;
mDragRef = theDragRef;
#if 1
printf("**** created drag ref %ld\n", theDragRef);
#if DEBUG
printf("**** created drag ref 0x%08X\n", theDragRef);
#endif
// add the flavors from the transferables. Cache this array for the send data proc
mDataItems = aTransferableArray;
RegisterDragItemsAndFlavors ( aTransferableArray ) ;
Rect frameRect = { 0, 0, 0, 0 };
RgnHandle theDragRgn = ::NewRgn();
::RectRgn(theDragRgn, &frameRect);
@ -247,13 +254,17 @@ printf("**** created drag ref %ld\n", theDragRef);
else
BuildDragRegion ( aDragRgn, aDOMNode, theDragRgn );
// add the flavors from the transferables. Cache this array for the send data proc
mDataItems = aTransferableArray;
RegisterDragItemsAndFlavors ( aTransferableArray, theDragRgn ) ;
// we have to synthesize the native event because we may be called from JavaScript
// through XPConnect. In that case, we only have a DOM event and no way to
// get to the native event. As a consequence, we just always fake it.
EventRecord theEvent;
theEvent.what = mouseDown;
theEvent.message = 0L;
theEvent.when = 0L;
theEvent.when = TickCount();
theEvent.modifiers = 0L;
// since we don't have the original mouseDown location, just assume the drag
@ -263,6 +274,7 @@ printf("**** created drag ref %ld\n", theDragRef);
// see it if you're paying attention, but who pays such close attention?
Rect dragRect;
::GetRegionBounds(theDragRgn, &dragRect);
theEvent.where.v = rint(dragRect.top + (dragRect.bottom - dragRect.top) / 2);
theEvent.where.h = rint(dragRect.left + (dragRect.right - dragRect.left) / 2);
@ -279,8 +291,8 @@ printf("**** created drag ref %ld\n", theDragRef);
// clean up after ourselves
::DisposeRgn ( theDragRgn );
result = ::DisposeDrag ( theDragRef );
#if DEBUG_DD
printf("**** disposing drag ref %ld\n", theDragRef);
#if DEBUG
printf("**** disposing drag ref 0x%08X\n", theDragRef);
#endif
NS_ASSERTION ( result == noErr, "Error disposing drag" );
mDragRef = 0L;
@ -308,6 +320,15 @@ nsDragService :: BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* in
if ( inRegion )
inRegion->GetRegion(getter_AddRefs(geckoRegion));
#ifdef MOZ_WIDGET_COCOA
nsGraphicsUtils::SetPortToKnownGoodPort();
GrafPtr port;
GDHandle handle;
::GetGWorld(&port, &handle);
if (!IsValidPort(port))
return NS_ERROR_FAILURE;
#endif
// create the drag region. Pull out the native mac region from the nsIRegion we're
// given, copy it, inset it one pixel, and subtract them so we're left with just an
// outline. Too bad we can't do this with gfx api's.
@ -320,11 +341,23 @@ nsDragService :: BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* in
::CopyRgn ( dragRegion, ioDragRgn );
::InsetRgn ( ioDragRgn, 1, 1 );
::DiffRgn ( dragRegion, ioDragRgn, ioDragRgn );
// now shift the region into global coordinates.
Point offsetFromLocalToGlobal = { 0, 0 };
::LocalToGlobal ( &offsetFromLocalToGlobal );
::OffsetRgn ( ioDragRgn, offsetFromLocalToGlobal.h, offsetFromLocalToGlobal.v );
// for cocoa, we have to transform this region into cocoa screen
// coordinates. Only the main screen is important in this caculation
// as that's where the 2 coord systems differ.
Rect regionBounds;
GetRegionBounds(ioDragRgn, &regionBounds);
GDHandle screenDevice = ::GetMainDevice();
Rect screenRect = (**screenDevice).gdRect;
// offset the rect
short screenHeight = screenRect.bottom - screenRect.top;
::OffsetRgn(ioDragRgn, 0, screenRect.top + (screenHeight - regionBounds.top) - regionBounds.top);
}
}
else {
@ -335,10 +368,21 @@ nsDragService :: BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* in
Point currMouse;
::GetMouse(&currMouse);
Rect frameRect = { currMouse.v, currMouse.h, currMouse.v + 25, currMouse.h + 100 };
if ( inNode )
if ( inNode ) {
useRectFromFrame = ComputeGlobalRectFromFrame ( inNode, frameRect );
else
}
else {
NS_WARNING ( "Can't find anything to get a drag rect from. I'm dyin' out here!" );
}
// for cocoa, we have to transform this region into cocoa screen
// coordinates. Only the main screen is important in this caculation
// as that's where the 2 coord systems differ.
GDHandle screenDevice = ::GetMainDevice();
Rect screenRect = (**screenDevice).gdRect;
// offset the rect
short screenHeight = screenRect.bottom - screenRect.top;
::OffsetRect(&frameRect, 0, screenRect.top + (screenHeight - frameRect.top) - frameRect.top);
if ( ioDragRgn ) {
RgnHandle frameRgn = ::NewRgn();
@ -371,10 +415,14 @@ nsDragService :: BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* in
// requested.
//
void
nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray )
nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray, RgnHandle inDragRgn )
{
const FlavorFlags flags = 0;
Rect dragRgnBounds = {0, 0, 0, 0};
if (inDragRgn)
GetRegionBounds(inDragRgn, &dragRgnBounds);
unsigned int numDragItems = 0;
inArray->Count ( &numDragItems ) ;
for ( int itemIndex = 0; itemIndex < numDragItems; ++itemIndex ) {
@ -393,19 +441,19 @@ nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray )
nsCOMPtr<nsISupports> genericWrapper;
flavorList->GetElementAt ( flavorIndex, getter_AddRefs(genericWrapper) );
nsCOMPtr<nsISupportsCString> currentFlavor ( do_QueryInterface(genericWrapper) );
if ( currentFlavor ) {
nsXPIDLCString flavorStr;
currentFlavor->ToString ( getter_Copies(flavorStr) );
FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr);
::AddDragItemFlavor ( mDragRef, itemIndex, macOSFlavor, NULL, 0, flags );
// If we advertise text/unicode, then make sure we add 'TEXT' to the list
// of flavors supported since we will do the conversion ourselves in GetDataForFlavor()
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
theMapper.MapMimeTypeToMacOSType(kTextMime);
::AddDragItemFlavor ( mDragRef, itemIndex, 'TEXT', NULL, 0, flags );
}
}
if ( currentFlavor ) {
nsXPIDLCString flavorStr;
currentFlavor->ToString ( getter_Copies(flavorStr) );
FlavorType macOSFlavor = theMapper.MapMimeTypeToMacOSType(flavorStr);
::AddDragItemFlavor ( mDragRef, itemIndex, macOSFlavor, NULL, 0, flags );
// If we advertise text/unicode, then make sure we add 'TEXT' to the list
// of flavors supported since we will do the conversion ourselves in GetDataForFlavor()
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
theMapper.MapMimeTypeToMacOSType(kTextMime);
::AddDragItemFlavor ( mDragRef, itemIndex, 'TEXT', NULL, 0, flags );
}
}
} // foreach flavor in item
} // if valid flavor list
@ -420,14 +468,15 @@ nsDragService :: RegisterDragItemsAndFlavors ( nsISupportsArray * inArray )
if ( mapping && mappingLen ) {
::AddDragItemFlavor ( mDragRef, itemIndex, nsMimeMapperMac::MappingFlavor(),
mapping, mappingLen, flags );
nsCRT::free ( mapping );
}
nsCRT::free ( mapping );
SetDragItemBounds(mDragRef, itemIndex, &dragRgnBounds);
}
} // foreach drag item
} // RegisterDragItemsAndFlavors
//
// GetData
//
@ -519,17 +568,29 @@ printf("looking for data in type %s, mac flavor %ld\n", NS_STATIC_CAST(const cha
// we have a HFSFlavor struct in |dataBuff|. Create an nsLocalFileMac object.
HFSFlavor* fileData = NS_REINTERPRET_CAST(HFSFlavor*, dataBuff);
NS_ASSERTION ( sizeof(HFSFlavor) == dataSize, "Ooops, we realy don't have a HFSFlavor" );
#ifndef XP_MACOSX
nsCOMPtr<nsILocalFileMac> file;
if ( NS_SUCCEEDED(NS_NewLocalFileWithFSSpec(&fileData->fileSpec, PR_TRUE, getter_AddRefs(file))) )
genericDataWrapper = do_QueryInterface(file);
#endif
}
else {
// we probably have some form of text. The DOM only wants LF, so convert k
// from MacOS line endings to DOM line endings.
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &dataBuff, NS_REINTERPRET_CAST(int*, &dataSize) );
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, dataBuff, dataSize, getter_AddRefs(genericDataWrapper) );
unsigned char *dataPtr = (unsigned char *) dataBuff;
// skip BOM (Byte Order Mark to distinguish little or big endian) in 'utxt'
// 10.2 puts BOM for 'utxt', we need to remove it here
// for little endian case, we also need to convert the data to big endian
// but we do not do that currently (need this in case 'utxt' is really in little endian)
if ( (macOSFlavor == 'utxt') &&
(dataSize > 2) &&
((dataPtr[0] == 0xFE && dataPtr[1] == 0xFF) ||
(dataPtr[0] == 0xFF && dataPtr[1] == 0xFE)) ) {
dataSize -= sizeof(PRUnichar);
dataPtr += sizeof(PRUnichar);
}
nsPrimitiveHelpers::CreatePrimitiveForData ( flavorStr, (void *) dataPtr, dataSize, getter_AddRefs(genericDataWrapper) );
}
// put it into the transferable.
@ -665,6 +726,7 @@ nsDragService :: DragSendDataProc ( FlavorType inFlavor, void* inRefCon, ItemRef
OSErr retVal = noErr;
nsDragService* self = NS_STATIC_CAST(nsDragService*, inRefCon);
NS_ASSERTION ( self, "Refcon not set correctly for DragSendDataProc" );
if ( self ) {
void* data = nsnull;
PRUint32 dataSize = 0;
@ -672,7 +734,7 @@ nsDragService :: DragSendDataProc ( FlavorType inFlavor, void* inRefCon, ItemRef
if ( retVal == noErr ) {
// make the data accessable to the DragManager
retVal = ::SetDragItemFlavorData ( inDragRef, inItemRef, inFlavor, data, dataSize, 0 );
NS_ASSERTION ( retVal == noErr, "SDIFD failed in DragSendDataProc" );
NS_ASSERTION ( retVal == noErr, "SetDragItemFlavorData failed in DragSendDataProc" );
}
nsMemory::Free ( data );
} // if valid refcon
@ -729,12 +791,21 @@ nsDragService :: GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference
nsCOMPtr<nsISupports> data;
if ( NS_SUCCEEDED(item->GetTransferData(actualFlavor, getter_AddRefs(data), outDataSize)) ) {
nsPrimitiveHelpers::CreateDataFromPrimitive ( actualFlavor, data, outData, *outDataSize );
// Convert unix to mac linebreaks, since mac linebreaks are required for clipboard compatibility.
// I'm making the assumption here that the substitution will be entirely in-place, since both
// types of line breaks are 1-byte.
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, *outData);
nsLinebreakConverter::ConvertUnicharLineBreaksInSitu(&castedUnicode,
nsLinebreakConverter::eLinebreakUnix,
nsLinebreakConverter::eLinebreakMac,
*outDataSize, nsnull);
// if required, do the extra work to convert unicode to plain text and replace the output
// values with the plain text.
if ( needToDoConversionToPlainText ) {
char* plainTextData = nsnull;
PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*, *outData);
PRInt32 plainTextLen = 0;
nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText ( castedUnicode, *outDataSize / 2, &plainTextData, &plainTextLen );
if ( *outData ) {

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

@ -85,7 +85,7 @@ private:
char* LookupMimeMappingsForItem ( DragReference inDragRef, ItemReference itemRef ) ;
void RegisterDragItemsAndFlavors ( nsISupportsArray * inArray ) ;
void RegisterDragItemsAndFlavors ( nsISupportsArray * inArray, RgnHandle inDragRgn ) ;
PRBool BuildDragRegion ( nsIScriptableRegion* inRegion, nsIDOMNode* inNode, RgnHandle ioDragRgn ) ;
OSErr GetDataForFlavor ( nsISupportsArray* inDragItems, DragReference inDragRef, unsigned int inItemIndex,
FlavorType inFlavor, void** outData, unsigned int * outSize ) ;

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

@ -1,750 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
*/
#include "nsCOMPtr.h"
#include "nsReadableUtils.h"
#include "nsNetUtil.h"
#include "nsIComponentManager.h"
#include "nsILocalFile.h"
#ifndef XP_MACOSX
#include "nsILocalFileMac.h"
#endif
#include "nsIURL.h"
#include "nsVoidArray.h"
#include "nsIFileChannel.h"
#include <InternetConfig.h>
#include "nsCarbonHelpers.h"
#include "nsFilePicker.h"
#include "nsWatchTask.h"
#include "nsIInternetConfigService.h"
#include "nsIMIMEInfo.h"
#include "nsIPlatformCharset.h"
#include "nsICharsetConverterManager.h"
#include "nsIFileURL.h"
//
// copied over from nsMacControl since we it's not being built.
//
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
static void GetFileSystemCharset(nsString & fileSystemCharset);
static void GetFileSystemCharset(nsString & fileSystemCharset)
{
static nsAutoString aCharset;
nsresult rv;
if (aCharset.Length() < 1) {
nsCOMPtr <nsIPlatformCharset> platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
rv = platformCharset->GetCharset(kPlatformCharsetSel_FileName, aCharset);
NS_ASSERTION(NS_SUCCEEDED(rv), "error getting platform charset");
if (NS_FAILED(rv))
aCharset.Assign(NS_LITERAL_STRING("x-mac-roman"));
}
fileSystemCharset = aCharset;
}
static void StringToStr255(const nsString& aText, Str255& aStr255) ;
static void StringToStr255(const nsString& aText, Str255& aStr255)
{
static nsIUnicodeEncoder* sUnicodeEncoder = nsnull;
nsresult rv = NS_OK;
// get file system charset and create a unicode encoder
if (!sUnicodeEncoder) {
nsAutoString fileSystemCharset;
GetFileSystemCharset(fileSystemCharset);
nsCOMPtr<nsICharsetConverterManager> ccm =
do_GetService(kCharsetConverterManagerCID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = ccm->GetUnicodeEncoder(&fileSystemCharset, &sUnicodeEncoder);
if (NS_SUCCEEDED(rv)) {
rv = sUnicodeEncoder->SetOutputErrorBehavior(nsIUnicodeEncoder::kOnError_Replace, nsnull, (PRUnichar)'?');
}
}
}
// converts from unicode to the file system charset
if (NS_SUCCEEDED(rv)) {
PRInt32 inLength = aText.Length();
PRInt32 outLength = 255;
rv = sUnicodeEncoder->Convert(aText.get(), &inLength, (char *) &aStr255[1], &outLength);
if (NS_SUCCEEDED(rv))
aStr255[0] = outLength;
}
if (NS_FAILED(rv)) {
// NS_ASSERTION(0, "error: charset covnersion");
NS_LossyConvertUCS2toASCII buffer(Substring(aText,0,254));
PRInt32 len = buffer.Length();
memcpy(&aStr255[1], buffer.get(), len);
aStr255[0] = len;
}
}
NS_IMPL_ISUPPORTS1(nsFilePicker, nsIFilePicker)
//-------------------------------------------------------------------------
//
// nsFilePicker constructor
//
//-------------------------------------------------------------------------
nsFilePicker::nsFilePicker()
: mAllFilesDisplayed(PR_TRUE)
{
NS_INIT_ISUPPORTS();
// Zero out the type lists
for (int i = 0; i < kMaxTypeListCount; i++)
mTypeLists[i] = 0L;
}
//-------------------------------------------------------------------------
//
// nsFilePicker destructor
//
//-------------------------------------------------------------------------
nsFilePicker::~nsFilePicker()
{
// Destroy any filters we have built
if ( mFilters.Count() ) {
for (int i = 0; i < kMaxTypeListCount; i++) {
if (mTypeLists[i])
DisposePtr((Ptr)mTypeLists[i]);
}
}
mFilters.Clear();
mTitles.Clear();
}
NS_IMETHODIMP
nsFilePicker::InitNative(nsIWidget *aParent, const PRUnichar *aTitle, PRInt16 aMode)
{
mTitle = aTitle;
mMode = aMode;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Ok's the dialog
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::OnOk()
{
mWasCancelled = PR_FALSE;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Cancel the dialog
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::OnCancel()
{
mWasCancelled = PR_TRUE;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Show - Display the file dialog
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::Show(PRInt16 *retval)
{
NS_ENSURE_ARG_POINTER(retval);
*retval = returnCancel;
nsString filterList;
char *filterBuffer = ToNewCString(filterList);
Str255 title;
Str255 defaultName;
StringToStr255(mTitle,title);
StringToStr255(mDefault,defaultName);
FSSpec theFile;
PRInt16 userClicksOK = returnCancel;
// XXX Ignore the filter list for now....
if (mMode == modeOpen || mMode == modeOpenMultiple)
userClicksOK = GetLocalFile(title, &theFile);
else if (mMode == modeSave)
userClicksOK = PutLocalFile(title, defaultName, &theFile);
else if (mMode == modeGetFolder)
userClicksOK = GetLocalFolder(title, &theFile);
// Clean up filter buffers
delete[] filterBuffer;
#ifndef XP_MACOSX
if (userClicksOK == returnOK || userClicksOK == returnReplace)
{
nsCOMPtr<nsILocalFile> localFile(do_CreateInstance("@mozilla.org/file/local;1"));
nsCOMPtr<nsILocalFileMac> macFile(do_QueryInterface(localFile));
nsresult rv = macFile->InitWithFSSpec(&theFile);
if (NS_FAILED(rv)) return rv;
mFile = do_QueryInterface(macFile);
}
#endif
*retval = userClicksOK;
return NS_OK;
}
//
// FileDialogEventHandlerProc
//
// An event filter proc for NavServices so the dialogs will be movable-modals.
//
static pascal void FileDialogEventHandlerProc( NavEventCallbackMessage msg, NavCBRecPtr cbRec, NavCallBackUserData data )
{
#if 0
switch ( msg ) {
case kNavCBEvent:
switch ( cbRec->eventData.eventDataParms.event->what ) {
case updateEvt:
WindowPtr window = reinterpret_cast<WindowPtr>(cbRec->eventData.eventDataParms.event->message);
nsMacWindow* macWindow = nsMacMessageSink::GetNSWindowFromMacWindow(window);
::BeginUpdate(window);
if (macWindow) {
EventRecord theEvent = *cbRec->eventData.eventDataParms.event;
macWindow->HandleOSEvent(theEvent);
}
::EndUpdate(window);
break;
}
break;
}
#endif
}
//
// IsFileInFilterList
//
// Check our |mTypeLists| list to see if the given type is in there.
//
Boolean
nsFilePicker :: IsTypeInFilterList ( ResType inType )
{
for ( int i = 0; i < mFilters.Count(); ++i ) {
for ( int j = 0; j < mTypeLists[i]->osTypeCount; ++j ) {
if ( mTypeLists[i]->osType[j] == inType )
return true;
} // foreach type w/in the group
} // for each filter group
return false;
} // IsFileInFilterList
Boolean
nsFilePicker :: IsExtensionInFilterList ( StrFileName & inFileName )
{
char extension[256];
// determine the extension from the file name
unsigned char* curr = &inFileName[inFileName[0]];
while ( curr != inFileName && *curr-- != '.' ) ;
if ( curr == inFileName ) // no '.' in string, fails this check
return false;
++curr; // we took one too many steps back
short extensionLen = (inFileName + inFileName[0]) - curr + 1;
strncpy ( extension, (char*)curr, extensionLen);
extension[extensionLen] = '\0';
// see if it is in our list
for ( int i = 0; i < mFlatFilters.Count(); ++i ) {
if ( mFlatFilters[i]->Equals(extension) )
return true;
}
return false;
}
//
// FileDialogFilterProc
//
// Called from navServices with our filePicker object as |callbackUD|, check our
// internal list to see if the file should be displayed.
//
pascal
Boolean
nsFilePicker :: FileDialogFilterProc ( AEDesc* theItem, void* theInfo,
NavCallBackUserData callbackUD, NavFilterModes filterMode )
{
Boolean shouldDisplay = true;
nsFilePicker* self = NS_REINTERPRET_CAST(nsFilePicker*, callbackUD);
if ( self && !self->mAllFilesDisplayed ) {
if ( theItem->descriptorType == typeFSS ) {
NavFileOrFolderInfo* info = NS_REINTERPRET_CAST ( NavFileOrFolderInfo*, theInfo );
if ( !info->isFolder ) {
// check it against our list. If that fails, check the extension directly
if ( ! self->IsTypeInFilterList(info->fileAndFolder.fileInfo.finderInfo.fdType) ) {
FSSpec fileSpec;
if ( ::AEGetDescData(theItem, &fileSpec, sizeof(FSSpec)) == noErr )
if ( ! self->IsExtensionInFilterList(fileSpec.name) )
shouldDisplay = false;
}
} // if file isn't a folder
} // if the item is an FSSpec
}
return shouldDisplay;
} // FileDialogFilterProc
//-------------------------------------------------------------------------
//
// GetFile
//
// Use NavServices to do a GetFile. Returns PR_TRUE if the user presses OK in the dialog. If
// they do so, the selected file is in the FSSpec.
//
//-------------------------------------------------------------------------
PRInt16
nsFilePicker::GetLocalFile(Str255 & inTitle, /* filter list here later */ FSSpec* outSpec)
{
PRInt16 retVal = returnCancel;
NavReplyRecord reply;
NavDialogOptions dialogOptions;
NavEventUPP eventProc = NewNavEventUPP(FileDialogEventHandlerProc); // doesn't really matter if this fails
NavObjectFilterUPP filterProc = NewNavObjectFilterUPP(FileDialogFilterProc); // doesn't really matter if this fails
OSErr anErr = NavGetDefaultDialogOptions(&dialogOptions);
if (anErr == noErr) {
// Set the options for how the get file dialog will appear
dialogOptions.dialogOptionFlags |= kNavNoTypePopup;
dialogOptions.dialogOptionFlags |= kNavDontAutoTranslate;
dialogOptions.dialogOptionFlags |= kNavDontAddTranslateItems;
dialogOptions.dialogOptionFlags ^= kNavAllowMultipleFiles;
::BlockMoveData(inTitle, dialogOptions.windowTitle, *inTitle + 1);
// sets up the |mTypeLists| array so the filter proc can use it
MapFilterToFileTypes();
// allow packages to be chosen if the filter is "*"
if ( mAllFilesDisplayed )
dialogOptions.dialogOptionFlags |= kNavSupportPackages;
// Display the get file dialog. Only use a filter proc if there are any
// filters registered.
nsWatchTask::GetTask().Suspend();
anErr = ::NavGetFile(
NULL,
&reply,
&dialogOptions,
eventProc,
NULL, // preview proc
mFilters.Count() ? filterProc : NULL,
NULL, //typeList,
this); // callbackUD - used by the filterProc
nsWatchTask::GetTask().Resume();
// See if the user has selected save
if (anErr == noErr && reply.validRecord) {
AEKeyword theKeyword;
DescType actualType;
Size actualSize;
FSSpec theFSSpec;
// Get the FSSpec for the file to be opened
anErr = AEGetNthPtr(&(reply.selection), 1, typeFSS, &theKeyword, &actualType,
&theFSSpec, sizeof(theFSSpec), &actualSize);
if (anErr == noErr)
{
*outSpec = theFSSpec; // Return the FSSpec
retVal = returnOK;
// Some housekeeping for Nav Services
::NavDisposeReply(&reply);
}
} // if user clicked OK
} // if can get dialog options
if ( eventProc )
::DisposeNavEventUPP(eventProc);
return retVal;
} // GetFile
//-------------------------------------------------------------------------
//
// GetFolder
//
// Use NavServices to do a PutFile. Returns PR_TRUE if the user presses OK in the dialog. If
// they do so, the folder location is in the FSSpec.
//
//-------------------------------------------------------------------------
PRInt16
nsFilePicker::GetLocalFolder(Str255 & inTitle, FSSpec* outSpec)
{
PRInt16 retVal = returnCancel;
NavReplyRecord reply;
NavDialogOptions dialogOptions;
NavEventUPP eventProc = NewNavEventUPP(FileDialogEventHandlerProc); // doesn't really matter if this fails
OSErr anErr = NavGetDefaultDialogOptions(&dialogOptions);
if (anErr == noErr) {
// Set the options for how the get file dialog will appear
dialogOptions.dialogOptionFlags |= kNavNoTypePopup;
dialogOptions.dialogOptionFlags |= kNavDontAutoTranslate;
dialogOptions.dialogOptionFlags |= kNavDontAddTranslateItems;
dialogOptions.dialogOptionFlags ^= kNavAllowMultipleFiles;
::BlockMoveData(inTitle, dialogOptions.windowTitle, *inTitle + 1);
// Display the get file dialog
nsWatchTask::GetTask().Suspend();
anErr = ::NavChooseFolder(
NULL,
&reply,
&dialogOptions,
eventProc,
NULL, // filter proc
NULL); // callbackUD
nsWatchTask::GetTask().Resume();
// See if the user has selected save
if (anErr == noErr && reply.validRecord) {
AEKeyword theKeyword;
DescType actualType;
Size actualSize;
FSSpec theFSSpec;
// Get the FSSpec for the file to be opened
anErr = AEGetNthPtr(&(reply.selection), 1, typeFSS, &theKeyword, &actualType,
&theFSSpec, sizeof(theFSSpec), &actualSize);
if (anErr == noErr) {
*outSpec = theFSSpec; // Return the FSSpec
retVal = returnOK;
// Some housekeeping for Nav Services
::NavDisposeReply(&reply);
}
} // if user clicked OK
} // if can get dialog options
if ( eventProc )
::DisposeNavEventUPP(eventProc);
return retVal;
} // GetFolder
PRInt16
nsFilePicker::PutLocalFile(Str255 & inTitle, Str255 & inDefaultName, FSSpec* outFileSpec)
{
PRInt16 retVal = returnCancel;
NavReplyRecord reply;
NavDialogOptions dialogOptions;
NavEventUPP eventProc = NewNavEventUPP(FileDialogEventHandlerProc); // doesn't really matter if this fails
OSType typeToSave = 'TEXT';
OSType creatorToSave = 'MOZZ';
OSErr anErr = NavGetDefaultDialogOptions(&dialogOptions);
if (anErr == noErr) {
// Set the options for how the get file dialog will appear
dialogOptions.dialogOptionFlags |= kNavNoTypePopup;
dialogOptions.dialogOptionFlags |= kNavDontAutoTranslate;
dialogOptions.dialogOptionFlags |= kNavDontAddTranslateItems;
dialogOptions.dialogOptionFlags ^= kNavAllowMultipleFiles;
::BlockMoveData(inTitle, dialogOptions.windowTitle, *inTitle + 1);
::BlockMoveData(inDefaultName, dialogOptions.savedFileName, *inDefaultName + 1);
// Display the get file dialog
nsWatchTask::GetTask().Suspend();
anErr = ::NavPutFile(
NULL,
&reply,
&dialogOptions,
eventProc,
typeToSave,
creatorToSave,
NULL); // callbackUD
nsWatchTask::GetTask().Resume();
// See if the user has selected save
if (anErr == noErr && reply.validRecord)
{
AEKeyword theKeyword;
DescType actualType;
Size actualSize;
FSSpec theFSSpec;
// Get the FSSpec for the file to be opened
anErr = AEGetNthPtr(&(reply.selection), 1, typeFSS, &theKeyword, &actualType,
&theFSSpec, sizeof(theFSSpec), &actualSize);
if (anErr == noErr) {
*outFileSpec = theFSSpec; // Return the FSSpec
if (reply.replacing)
retVal = returnReplace;
else
retVal = returnOK;
// Some housekeeping for Nav Services
::NavCompleteSave(&reply, kNavTranslateInPlace);
::NavDisposeReply(&reply);
}
} // if user clicked OK
} // if can get dialog options
if ( eventProc )
::DisposeNavEventUPP(eventProc);
return retVal;
}
//
// MapFilterToFileTypes
//
// Take the list of file types (in a nice win32-specific format) and ask IC to give us
// the MacOS file type codes for them.
//
void
nsFilePicker :: MapFilterToFileTypes ( )
{
nsCOMPtr<nsIInternetConfigService> icService ( do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID) );
NS_ASSERTION(icService, "Can't get InternetConfig Service, bailing out");
if ( !icService ) {
// We couldn't get the IC Service, bail. Since |mAllFilesDisplayed| is still
// set, the dialog will allow selection of all files.
return;
}
if (mFilters.Count())
{
// First we allocate the memory for the Mac type lists
for (PRUint32 loop1 = 0; loop1 < mFilters.Count() && loop1 < kMaxTypeListCount; loop1++)
{
mTypeLists[loop1] =
(NavTypeListPtr)NewPtrClear(sizeof(NavTypeList) + kMaxTypesPerFilter * sizeof(OSType));
if ( !mTypeLists[loop1] )
return; // don't worry, we'll clean up in the dtor
}
// Now loop through each of the filter strings
for (PRUint32 loop1 = 0; loop1 < mFilters.Count(); loop1++)
{
const nsString& filterWide = *mFilters[loop1];
char* filter = ToNewCString(filterWide);
NS_ASSERTION ( filterWide.Length(), "Oops. filepicker.properties not correctly installed");
if ( filterWide.Length() && filter )
{
PRUint32 filterIndex = 0; // Index into the filter string
PRUint32 typeTempIndex = 0; // Index into the temp string for a single filter type
PRUint32 typesInThisFilter = 0; // Count for # of types in this filter
bool finishedThisFilter = false; // Flag so we know when we're finsihed with the filter
char typeTemp[256];
char tempChar; // char we're currently looking at
// Loop through the characters of filter string. Every time we get to a
// semicolon (or a null, meaning we've hit the end of the full string)
// then we've found the filter and can pass it off to IC to get a macOS
// file type out of it.
do
{
tempChar = filter[filterIndex];
if ((tempChar == ';') || (tempChar == 0)) { // End of filter type reached
typeTemp[typeTempIndex] = '\0'; // null terminate
// to make it easier to match file extensions while we're filtering, flatten
// out the list. Ignore filters that are just "*" and also remove the
// leading "*" from filters we do add.
if ( strlen(typeTemp) > 1 )
mFlatFilters.AppendCString ( nsCString((char*)&typeTemp[1]) ); // cut out the "*"
// ask IC if it's not "all files" (designated by "*")
if ( !(typeTemp[1] == '\0' && typeTemp[0] == '*') ) {
mAllFilesDisplayed = PR_FALSE;
nsCOMPtr<nsIMIMEInfo> icEntry;
icService->GetMIMEInfoFromExtension(typeTemp, getter_AddRefs(icEntry));
if ( icEntry )
{
bool addToList = true;
OSType tempOSType;
icEntry->GetMacType(NS_REINTERPRET_CAST(PRUint32*, (&tempOSType)));
for (PRUint32 typeIndex = 0; typeIndex < typesInThisFilter; typeIndex++)
{
if (mTypeLists[loop1]->osType[typeIndex] == tempOSType)
{
addToList = false;
break;
}
}
if (addToList && typesInThisFilter < kMaxTypesPerFilter)
mTypeLists[loop1]->osType[typesInThisFilter++] = tempOSType;
}
} // if not "*"
typeTempIndex = 0; // Reset the temp string for the type
if (tempChar == '\0')
finishedThisFilter = true;
}
else
{
// strip out whitespace as we go
if ( tempChar != ' ' )
typeTemp[typeTempIndex++] = tempChar;
}
filterIndex++;
} while (!finishedThisFilter);
// Set how many OSTypes we actually found
mTypeLists[loop1]->osTypeCount = typesInThisFilter;
nsMemory :: Free ( NS_REINTERPRET_CAST(void*, filter) );
}
}
}
} // MapFilterToFileTypes
NS_IMETHODIMP nsFilePicker::GetFile(nsILocalFile **aFile)
{
NS_ENSURE_ARG_POINTER(aFile);
NS_IF_ADDREF(*aFile = mFile);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::GetFileURL(nsIFileURL **aFileURL)
{
NS_ENSURE_TRUE(mFile, NS_ERROR_FAILURE);
nsCOMPtr<nsIURI> uri;
NS_NewFileURI(getter_AddRefs(uri), mFile);
nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(uri));
NS_ENSURE_TRUE(fileURL, NS_ERROR_FAILURE);
NS_ADDREF(*aFileURL = fileURL);
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the file + path
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::SetDefaultString(const PRUnichar *aString)
{
mDefault = aString;
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::GetDefaultString(PRUnichar **aString)
{
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
//
// The default extension to use for files
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::GetDefaultExtension(PRUnichar **aExtension)
{
*aExtension = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::SetDefaultExtension(const PRUnichar *aExtension)
{
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set the display directory
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::SetDisplayDirectory(nsILocalFile *aDirectory)
{
mDisplayDirectory = aDirectory;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the display directory
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::GetDisplayDirectory(nsILocalFile **aDirectory)
{
*aDirectory = mDisplayDirectory;
NS_IF_ADDREF(*aDirectory);
return NS_OK;
}
NS_IMETHODIMP
nsFilePicker::AppendFilter(const PRUnichar *aTitle, const PRUnichar *aFilter)
{
mFilters.AppendString(nsDependentString(aFilter));
mTitles.AppendString(nsDependentString(aTitle));
return NS_OK;
}

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

@ -19,6 +19,9 @@
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
* Steve Dagley <sdagley@netscape.com>
* David Haas <haasd@cae.wisc.edu>
* Steve Dagley <sdagley@netscape.com>
*/
#ifndef nsFilePicker_h__
@ -28,13 +31,15 @@
#include "nsString.h"
#include "nsIFileChannel.h"
#include "nsILocalFile.h"
#include <Navigation.h>
#define kMaxTypeListCount 10
#define kMaxTypesPerFilter 9
//#include <Navigation.h>
class nsILocalFileMac;
@class NSArray;
/**
* Native Mac FileSelector wrapper
* Native Mac Cocoa FileSelector wrapper
*/
class nsFilePicker : public nsBaseFilePicker
@ -49,13 +54,15 @@ public:
NS_IMETHOD GetDefaultString(PRUnichar * *aDefaultString);
NS_IMETHOD SetDefaultString(const PRUnichar * aDefaultString);
NS_IMETHOD GetDefaultExtension(PRUnichar * *aDefaultExtension);
NS_IMETHOD GetFilterIndex(PRInt32 *aFilterIndex);
NS_IMETHOD SetFilterIndex(PRInt32 aFilterIndex);
NS_IMETHOD SetDefaultExtension(const PRUnichar * aDefaultExtension);
NS_IMETHOD GetDisplayDirectory(nsILocalFile * *aDisplayDirectory);
NS_IMETHOD SetDisplayDirectory(nsILocalFile * aDisplayDirectory);
NS_IMETHOD GetFile(nsILocalFile * *aFile);
NS_IMETHOD GetFileURL(nsIFileURL * *aFileURL);
NS_IMETHOD Show(PRInt16 *_retval);
NS_IMETHOD AppendFilter(const PRUnichar *aTitle, const PRUnichar *aFilter) ;
NS_IMETHOD AppendFilter(const PRUnichar *aTitle, const PRUnichar *aFilter);
protected:
@ -64,19 +71,14 @@ protected:
NS_IMETHOD OnOk();
NS_IMETHOD OnCancel();
// actual implementations of get/put dialogs using NavServices
PRInt16 PutLocalFile(Str255 & inTitle, Str255 & inDefaultName, FSSpec* outFileSpec) ;
PRInt16 GetLocalFile(Str255 & inTitle, FSSpec* outFileSpec);
PRInt16 GetLocalFolder(Str255 & inTitle, FSSpec* outFileSpec);
void MapFilterToFileTypes ( ) ;
Boolean IsTypeInFilterList ( ResType inType ) ;
Boolean IsExtensionInFilterList ( StrFileName & inFileName ) ;
// filter routine for file types
static pascal Boolean FileDialogFilterProc ( AEDesc* theItem, void* info,
NavCallBackUserData callbackUD,
NavFilterModes filterMode ) ;
// actual implementations of get/put dialogs using NSOpenPanel & NSSavePanel
// aFile is an existing but unspecified file. These functions must specify it.
PRInt16 PutLocalFile(const nsString& inTitle, const nsString& inDefaultName, nsILocalFileMac* aFile);
PRInt16 GetLocalFile(const nsString& inTitle, nsILocalFileMac* aFile);
PRInt16 GetLocalFolder(const nsString& inTitle, nsILocalFileMac* aFile);
NSArray *GenerateFilterList();
void SetDialogTitle(const nsString& inTitle, id aDialog);
NSString *PanelDefaultDirectory();
PRBool mWasCancelled;
PRBool mAllFilesDisplayed;
@ -88,9 +90,9 @@ protected:
nsStringArray mFilters;
nsStringArray mTitles;
nsCStringArray mFlatFilters; // all the filters from mFilters, but one per string
NavTypeListPtr mTypeLists[kMaxTypeListCount];
PRInt32 mSelectedType; //this is in some NS_IMETHODIMP, but otherwise unsed.
static OSType sCurrentProcessSignature;
};

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

@ -0,0 +1,511 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Stuart Parmenter <pavlov@netscape.com>
* Steve Dagley <sdagley@netscape.com>
* David Haas <haasd@cae.wisc.edu>
* Simon Fraser <sfraser@netscape.com>
*/
// Arrgh. Bitten by bug 154232 here.
// Need to undef DARWIN before including Cocoa & (by default) CoreFoundation
// so we can use CFURLGetFSRef.
#undef DARWIN
#include <Cocoa/Cocoa.h>
#define DARWIN
#include "nsCOMPtr.h"
#include "nsCRT.h"
#include "nsReadableUtils.h"
#include "nsNetUtil.h"
#include "nsIComponentManager.h"
#include "nsILocalFile.h"
#include "nsILocalFileMac.h"
#include "nsIURL.h"
#include "nsVoidArray.h"
#include "nsIFileURL.h"
#include "nsFilePicker.h"
NS_IMPL_ISUPPORTS1(nsFilePicker, nsIFilePicker)
//-------------------------------------------------------------------------
//
// nsFilePicker constructor
//
//-------------------------------------------------------------------------
nsFilePicker::nsFilePicker()
: mWasCancelled(PR_FALSE)
, mAllFilesDisplayed(PR_TRUE)
, mMode(0)
, mSelectedType(0)
{
NS_INIT_ISUPPORTS();
}
//-------------------------------------------------------------------------
//
// nsFilePicker destructor
//
//-------------------------------------------------------------------------
nsFilePicker::~nsFilePicker()
{
// string arrays clean themselves up
}
NS_IMETHODIMP
nsFilePicker::InitNative(nsIWidget *aParent, const PRUnichar *aTitle, PRInt16 aMode)
{
mTitle = aTitle;
mMode = aMode;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Ok's the dialog
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::OnOk()
{
mWasCancelled = PR_FALSE;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Cancel the dialog
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::OnCancel()
{
mWasCancelled = PR_TRUE;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Show - Display the file dialog
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::Show(PRInt16 *retval)
{
NS_ENSURE_ARG_POINTER(retval);
*retval = returnCancel;
PRInt16 userClicksOK = returnCancel;
nsCOMPtr<nsILocalFileMac> theFile(do_CreateInstance("@mozilla.org/file/local;1"));
if (!theFile)
return NS_ERROR_FAILURE;
//
// Random questions from DHH:
//
// Why do we pass mTitle, mDefault to the functions? Can GetLocalFile. PutLocalFile,
// and GetLocalFolder get called someplace else? It generates a bunch of warnings
// as it is right now.
//
// I think we could easily combine GetLocalFile and GetLocalFolder together, just
// setting panel pick options based on mMode. I didn't do it here b/c I wanted to
// make this look as much like Carbon nsFilePicker as possible.
//
//
switch (mMode)
{
case modeOpen:
case modeOpenMultiple:
userClicksOK = GetLocalFile(mTitle, theFile);
break;
case modeSave:
userClicksOK = PutLocalFile(mTitle, mDefault, theFile);
break;
case modeGetFolder:
userClicksOK = GetLocalFolder(mTitle, theFile);
break;
default:
NS_ASSERTION(0, "Unknown file picker mode");
break;
}
if (userClicksOK == returnOK || userClicksOK == returnReplace)
mFile = theFile;
*retval = userClicksOK;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// GetLocalFile
//
// Use OpenPanel to do a GetFile. Returns PR_TRUE if the user presses OK in the dialog. If
// they do so, the selected file is in the FSSpec.
//
//-------------------------------------------------------------------------
PRInt16
nsFilePicker::GetLocalFile(const nsString & inTitle, nsILocalFileMac* ioFile)
{
NS_ENSURE_ARG(ioFile);
PRInt16 retVal = (PRInt16)returnCancel;
NSOpenPanel *thePanel = [NSOpenPanel openPanel];
// Get filters
NSArray *filters = GenerateFilterList();
// Set the options for how the get file dialog will appear
SetDialogTitle(inTitle, thePanel);
[thePanel setAllowsMultipleSelection:NO]; //this is default - probably doesn't need to be set
[thePanel setCanSelectHiddenExtension:YES];
[thePanel setCanChooseDirectories:NO];
[thePanel setCanChooseFiles:YES];
[thePanel setResolvesAliases:YES]; //this is default - probably doesn't need to be set
// handle how we deal with packages.
if (filters)
[thePanel setTreatsFilePackagesAsDirectories:NO];
// set up default directory
NSString *theDir = PanelDefaultDirectory();
int result = [thePanel runModalForDirectory:theDir file:nil types:filters];
if (result == NSFileHandlingPanelCancelButton)
return retVal;
//get FSRef for file (we allow just 1, so that's all we get)
NSURL *theURL = [[thePanel URLs] objectAtIndex:0];
FSRef theFSRef;
if (::CFURLGetFSRef((CFURLRef)theURL, &theFSRef)) {
if (NS_SUCCEEDED(ioFile->InitWithFSRef(&theFSRef)))
retVal = returnOK;
}
return retVal;
} // GetFile
//-------------------------------------------------------------------------
//
// GetLocalFolder
//
// Use OpenPanel to do a GetFolder. Returns PR_TRUE if the user presses OK in the dialog. If
// they do so, the folder location is in the FSSpec.
//
// Note: Apparently, not used in Chimera. So it hasn't been tested. At all.
// Consider yourself warned.
//-------------------------------------------------------------------------
PRInt16
nsFilePicker::GetLocalFolder(const nsString & inTitle, nsILocalFileMac* ioFile)
{
NS_ENSURE_ARG(ioFile);
PRInt16 retVal = (PRInt16)returnCancel;
NSOpenPanel *thePanel = [NSOpenPanel openPanel];
// Set the options for how the get file dialog will appear
SetDialogTitle(inTitle, thePanel);
[thePanel setAllowsMultipleSelection:NO]; //this is default -probably doesn't need to be set
[thePanel setCanSelectHiddenExtension:YES];
[thePanel setCanChooseDirectories:YES];
[thePanel setCanChooseFiles:NO];
[thePanel setResolvesAliases:YES]; //this is default - probably doesn't need to be set
[thePanel setTreatsFilePackagesAsDirectories:YES]; //sure, we can pick packages.
// set up default directory
NSString *theDir = PanelDefaultDirectory();
int result = [thePanel runModalForDirectory:theDir file:nil types:nil];
if (result == NSFileHandlingPanelCancelButton)
return retVal;
//get FSRef for folder (we allow just 1, so that's all we get)
NSURL *theURL = [[thePanel URLs] objectAtIndex:0];
FSRef theFSRef;
if (::CFURLGetFSRef((CFURLRef)theURL, &theFSRef)) {
if (NS_SUCCEEDED(ioFile->InitWithFSRef(&theFSRef)))
retVal = returnOK;
}
return retVal;
} // GetFolder
//-------------------------------------------------------------------------
//
// PutLocalFile
//
// Use SavePanel to do a PutFile. Returns returnOK if the user presses OK in the dialog. If
// they do so, the folder location is in the FSSpec.
//
// Note: I don't think Chimera is using this at all. So - it hasn't been tested.
// If you end up calling it, let me know how it turns out.
//-------------------------------------------------------------------------
PRInt16
nsFilePicker::PutLocalFile(const nsString & inTitle, const nsString & inDefaultName, nsILocalFileMac* ioFile)
{
NS_ENSURE_ARG(ioFile);
PRInt16 retVal = returnCancel;
NSSavePanel *thePanel = [NSSavePanel savePanel];
// set up save panel options & whatnot.
SetDialogTitle(inTitle, thePanel);
// set up default file name
CFStringRef defaultFileNameRef = ::CFStringCreateWithCharacters(NULL,
(const UniChar *) inDefaultName.get(),
inDefaultName.Length());
if (!defaultFileNameRef) {
defaultFileNameRef = CFSTR(""); //empty strings ok - just can't be NULL.
CFRetain(defaultFileNameRef); //fake out so we can release it later without problems.
}
// set up default directory
NSString *theDir = PanelDefaultDirectory();
// load the panel.
int result = [thePanel runModalForDirectory:theDir file:(NSString *)defaultFileNameRef];
// clean up name
CFRelease (defaultFileNameRef);
if (result == NSFileHandlingPanelCancelButton)
return retVal;
// Get the FSRef for the directory where the file to be saved
NSURL *theURL = [NSURL fileURLWithPath:[thePanel directory]];
FSRef theFSRef;
if (::CFURLGetFSRef((CFURLRef)theURL, &theFSRef)) {
if (NS_SUCCEEDED(ioFile->InitWithFSRef(&theFSRef))) {
if (NS_SUCCEEDED(ioFile->Append(nsDependentString(::CFStringGetCharactersPtr((CFStringRef)[thePanel filename])))));
retVal = returnOK;
}
}
return retVal;
}
//-------------------------------------------------------------------------
//
// GenerateFilterList
//
// Take the list of file types (in a nice win32-specific format) and fills up
// an NSArray of them for the Open Panel. Cocoa's open panel doesn't recognize *
// as being equal to everything, so make sure there aren't any in mFlatFilter array.
//
//-------------------------------------------------------------------------
NSArray *
nsFilePicker::GenerateFilterList()
{
NSArray *filterArray = nil;
if (mFilters.Count() > 0)
{
// Set up our filter string
NSMutableString *giantFilterString = [[NSMutableString alloc] initWithString:@""];
if (!giantFilterString) //dang.
return filterArray;
// Loop through each of the filter strings
for (PRInt32 loop = 0; loop < mFilters.Count(); loop++)
{
nsString* filterWide = mFilters[loop];
if (filterWide && filterWide->Length() > 0)
[giantFilterString appendString:[NSString stringWithCharacters:filterWide->get() length:filterWide->Length()]];
}
// Now we clean stuff up. Get rid of white spaces, "*"'s, and the odd period or two.
NSCharacterSet *aSet = [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithString:@". *"]];
NSRange aRange = [giantFilterString rangeOfCharacterFromSet:aSet];
while (aRange.length) {
[giantFilterString replaceCharactersInRange:aRange withString:@""];
aRange = [giantFilterString rangeOfCharacterFromSet:aSet];
}
// OK, if string isn't empty we'll make a new filter list
if ([giantFilterString length] > 0)
// every time we find a semicolon, we've found a new filter.
// components SeparatedByString should do that for us.
filterArray = [[[NSArray alloc] initWithArray:[giantFilterString componentsSeparatedByString:@";"]] autorelease];
[giantFilterString release];
}
return filterArray;
} // GenerateFilterList
//-------------------------------------------------------------------------
//
// SetDialogTitle
//
// Sets the dialog title to whatever it should be. If it fails, eh,
// the OS will provide a sensible default.
//
//-------------------------------------------------------------------------
void
nsFilePicker::SetDialogTitle(const nsString& inTitle, id aPanel)
{
// XXX why not just make an NString* here?
CFStringRef titleRef = CFStringCreateWithCharacters(NULL,(const UniChar *) inTitle.get(), inTitle.Length());
if (titleRef)
[aPanel setTitle:(NSString *)titleRef];
CFRelease (titleRef);
}
//-------------------------------------------------------------------------
//
// PanelDefaultDirectory
//
// Converts path from an nsILocalFile into a NSString path
// If it fails, returns an empty string.
//
//-------------------------------------------------------------------------
NSString *
nsFilePicker::PanelDefaultDirectory()
{
NSString *directory = nil;
if (mDisplayDirectory) {
nsAutoString pathStr;
mDisplayDirectory->GetPath(pathStr);
directory = [[[NSString alloc] initWithCharacters:pathStr.get() length:nsCRT::strlen(pathStr.get())] autorelease];
}
return directory;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::GetFile(nsILocalFile **aFile)
{
NS_ENSURE_ARG_POINTER(aFile);
NS_IF_ADDREF(*aFile = mFile);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::GetFileURL(nsIFileURL **aFileURL)
{
NS_ENSURE_TRUE(mFile, NS_ERROR_FAILURE);
nsCOMPtr<nsIURI> uri;
NS_NewFileURI(getter_AddRefs(uri), mFile);
nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(uri));
NS_ENSURE_TRUE(fileURL, NS_ERROR_FAILURE);
NS_ADDREF(*aFileURL = fileURL);
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the file + path
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::SetDefaultString(const PRUnichar *aString)
{
mDefault = aString;
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::GetDefaultString(PRUnichar **aString)
{
return NS_ERROR_FAILURE;
}
//-------------------------------------------------------------------------
//
// The default extension to use for files
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::GetDefaultExtension(PRUnichar **aExtension)
{
*aExtension = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsFilePicker::SetDefaultExtension(const PRUnichar *aExtension)
{
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set the display directory
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::SetDisplayDirectory(nsILocalFile *aDirectory)
{
mDisplayDirectory = aDirectory;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the display directory
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::GetDisplayDirectory(nsILocalFile **aDirectory)
{
*aDirectory = mDisplayDirectory;
NS_IF_ADDREF(*aDirectory);
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Append an entry to the filters array
//
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsFilePicker::AppendFilter(const PRUnichar *aTitle, const PRUnichar *aFilter)
{
// XXX this assumes that these buffers outlive us. Might want to copy
// the strings.
mFilters.AppendString(nsDependentString(aFilter));
mTitles.AppendString(nsDependentString(aTitle));
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Get the filter index - do we still need this?
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::GetFilterIndex(PRInt32 *aFilterIndex)
{
*aFilterIndex = mSelectedType;
return NS_OK;
}
//-------------------------------------------------------------------------
//
// Set the filter index - do we still need this?
//
//-------------------------------------------------------------------------
NS_IMETHODIMP nsFilePicker::SetFilterIndex(PRInt32 aFilterIndex)
{
mSelectedType = aFilterIndex;
return NS_OK;
}

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

@ -114,16 +114,7 @@ nsresult nsLookAndFeel::NativeGetColor(const nsColorID aID, nscolor &aColor)
break;
case eColor_highlight: // CSS2 color
case eColor_TextSelectBackground:
RGBColor macColor;
GrafPtr thePort;
::GetPort(&thePort);
if (thePort)
{
::GetPortHiliteColor(thePort,&macColor);
aColor = NS_RGB(macColor.red>>8, macColor.green>>8, macColor.blue>>8);
}
else
aColor = NS_RGB(0x00,0x00,0x00);
res = GetMacBrushColor(kThemeBrushPrimaryHighlightColor, aColor, NS_RGB(0x00,0x00,0x00));
break;
case eColor_highlighttext: // CSS2 color
case eColor_TextSelectForeground:

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

@ -108,7 +108,10 @@ nsMimeMapperMac :: MapMimeTypeToMacOSType ( const char* aMimeStr, PRBool inAddIf
format = kScrapFlavorTypePicture;
else if ( PL_strcmp(aMimeStr, kUnicodeMime) == 0 )
format = kScrapFlavorTypeUnicode;
/*
else if ( PL_strcmp(aMimeStr, kURLMime) == 0 )
format = 'url ';
*/
else if ( inAddIfNotPresent ) {
// create the flavor based on the unique id in the lower two bytes and 'MZ' in the
// upper two bytes.

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

@ -215,6 +215,12 @@ nsNativeScrollbar::UpdateContentPosition(PRUint32 inNewPos)
if ( inNewPos == mValue || !mContent ) // break any possible recursion
return;
// guarantee |inNewPos| is in the range of [0, mMaxValue] so it's correctly unsigned
if ( (PRInt32)inNewPos < 0 )
inNewPos = 0;
else if ( inNewPos > mMaxValue )
inNewPos = mMaxValue;
// convert the int to a string
char buffer[20];
sprintf(buffer, "%d", inNewPos);
@ -249,8 +255,11 @@ nsNativeScrollbar::SetMaxRange(PRUint32 aEndRange)
{
mMaxValue = ((int)aEndRange) > 0 ? aEndRange : 10;
if ( GetControl() ) {
// Update the current value based on the new range. We need to recompute the
// float value in case we had to set the value to 0 because gecko cheated
// and set the position before it set the max value.
PRInt32 fullVisibleArea = mVisibleImageSize + mMaxValue;
[mView setFloatValue:[mView floatValue] knobProportion:(mVisibleImageSize / (float)fullVisibleArea)];
[mView setFloatValue:(mValue / (float)mMaxValue) knobProportion:(mVisibleImageSize / (float)fullVisibleArea)];
}
return NS_OK;
}
@ -291,10 +300,10 @@ nsNativeScrollbar::SetPosition(PRUint32 aPos)
// mValue = ((PRInt32)aPos) > mMaxValue ? mMaxValue : ((int)aPos);
mValue = aPos;
if ( mMaxValue )
[mView setFloatValue:(aPos / (float)mMaxValue)];
[mView setFloatValue:(mValue / (float)mMaxValue)];
else
[mView setFloatValue:0.0];
return NS_OK;
}
@ -324,8 +333,11 @@ nsNativeScrollbar::SetViewSize(PRUint32 aSize)
{
mVisibleImageSize = ((int)aSize) > 0 ? aSize : 1;
// Update the current value based on the new range. We need to recompute the
// float value in case we had to set the value to 0 because gecko cheated
// and set the position before it set the max value.
PRInt32 fullVisibleArea = mVisibleImageSize + mMaxValue;
[mView setFloatValue:[mView floatValue] knobProportion:(mVisibleImageSize / (float)fullVisibleArea)];
[mView setFloatValue:(mValue / (float)mMaxValue) knobProportion:(mVisibleImageSize / (float)fullVisibleArea)];
return NS_OK;
}

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

@ -40,6 +40,7 @@
#include "nsChildView.h"
#include "nsIScrollbar.h"
#import "mozView.h"
/**
@ -88,6 +89,10 @@ public:
NS_IMETHOD SetParameters(PRUint32 aMaxRange, PRUint32 aThumbSize,
PRUint32 aPosition, PRUint32 aLineIncrement);
// called from the ScrollbarView when someone hits a part
// of the scrollbar.
void DoScroll(NSScrollerPart inPart);
protected:
virtual PRBool IsVertical ( ) const = 0;
@ -97,19 +102,12 @@ protected:
virtual NSView* CreateCocoaView() ;
virtual GrafPtr GetQuickDrawPort() ;
private:
static
pascal void ScrollActionProc(ControlHandle, ControlPartCode);
void DoScrollAction(ControlPartCode);
// DATA
private:
PRInt32 mValue;
PRUint32 mMaxValue;
PRUint32 mVisibleImageSize;
PRUint32 mLineIncrement;
PRBool mMouseDownInScroll;
ControlPartCode mClickedPartCode;
static ControlActionUPP sControlActionProc; // we only need one of these
};
@ -137,27 +135,23 @@ protected:
@interface ScrollbarView : NSScroller
@interface ScrollbarView : NSScroller<mozView>
{
// Our window [WEAK]
// Our window [WEAK]
NSWindow* mWindow;
// the nsChildView that created the view. It retains this NSView, so
// the link back to it must be weak.
nsChildView* mGeckoChild;
// allows us to redispatch events back to a centralized location
//nsIEventSink* mEventSink;
// tag for our mouse enter/exit tracking rect
NSTrackingRectTag mMouseEnterExitTag;
// used to avoid move re-entrancy
BOOL mInMove;
// the nsScrollbar that created this view. It retains this NSView, so
// the link back to it must be weak. [WEAK]
nsScrollbar* mGeckoChild;
}
- (NSWindow*) getNativeWindow;
- (void) setNativeWindow: (NSWindow*)aWindow;
// default initializer
- (id)initWithFrame:(NSRect)frameRect geckoChild:(nsScrollbar*)inChild;
// overridden parent class initializer
- (id)initWithFrame:(NSRect)frameRect;
- (IBAction)scroll:(NSScroller*)sender;
@end
#endif // nsScrollbar_

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

@ -53,7 +53,6 @@ nsScrollbar::nsScrollbar()
, mMaxValue(0)
, mVisibleImageSize(0)
, mLineIncrement(0)
, mMouseDownInScroll(PR_FALSE)
, mClickedPartCode(0)
{
WIDGET_SET_CLASSNAME("nsScrollbar");
@ -83,7 +82,7 @@ nsScrollbar::CreateCocoaView ( )
orientation.size.width = 100;
orientation.size.height = 20;
}
return [[[ScrollbarView alloc] initWithFrame:orientation] autorelease];
return [[[ScrollbarView alloc] initWithFrame:orientation geckoChild:this] autorelease];
}
@ -95,85 +94,84 @@ nsScrollbar::GetQuickDrawPort ( )
return [parent qdPort];
}
/**-------------------------------------------------------------------------------
* ScrollActionProc Callback for TrackControl
* @update jrm 99/01/11
* @param ctrl - The Control being tracked
* @param part - Part of the control (arrow, thumb, gutter) being hit
*/
pascal
void nsScrollbar::ScrollActionProc(ControlHandle ctrl, ControlPartCode part)
//
// DoScroll
//
// Called from the action proc of the scrollbar, adjust the control's
// value as well as the value in the content node which communicates
// to gecko that the document is scrolling.
//
void
nsScrollbar::DoScroll(NSScrollerPart inPart)
{
nsScrollbar* me = (nsScrollbar*)(::GetControlReference(ctrl));
NS_ASSERTION(nsnull != me, "NULL nsScrollbar");
if (nsnull != me)
me->DoScrollAction(part);
}
/**-------------------------------------------------------------------------------
* ScrollActionProc Callback for TrackControl
* @update jrm 99/01/11
* @param part - Part of the control (arrow, thumb, gutter) being hit
*/
void nsScrollbar::DoScrollAction(ControlPartCode part)
{
PRUint32 pos;
PRUint32 incr;
PRUint32 visibleImageSize;
PRInt32 scrollBarMessage = 0;
GetPosition(pos);
GetLineIncrement(incr);
GetThumbSize(visibleImageSize);
switch(part)
{
case kControlUpButtonPart:
{
PRUint32 oldPos, newPos;
PRUint32 incr;
GetPosition(oldPos);
GetLineIncrement(incr);
switch ( inPart ) {
//
// For the up/down buttons, scroll up or down by the line height and
// update the attributes on the content node (the scroll frame listens
// for these attributes and will scroll accordingly). However,
// if we have a mediator, we're in an outliner and we have to scroll by
// lines. Outliner ignores the params to ScrollbarButtonPressed() except
// to check if one is greater than the other to indicate direction.
//
case NSScrollerDecrementLine: // scroll up/left
scrollBarMessage = NS_SCROLLBAR_LINE_PREV;
SetPosition(pos - incr);
break;
}
case kControlDownButtonPart:
newPos = oldPos - incr;
SetPosition(newPos);
break;
case NSScrollerIncrementLine: // scroll down/right
scrollBarMessage = NS_SCROLLBAR_LINE_NEXT;
SetPosition(pos + incr);
break;
case kControlPageUpPart:
newPos = oldPos + incr;
SetPosition(newPos);
break;
case NSScrollerDecrementPage: // scroll up a page
scrollBarMessage = NS_SCROLLBAR_PAGE_PREV;
SetPosition(pos - visibleImageSize);
break;
case kControlPageDownPart:
newPos = oldPos - mVisibleImageSize;
SetPosition(newPos);
break;
case NSScrollerIncrementPage: // scroll down a page
scrollBarMessage = NS_SCROLLBAR_PAGE_NEXT;
SetPosition(pos + visibleImageSize);
break;
case kControlIndicatorPart:
newPos = oldPos + mVisibleImageSize;
SetPosition(newPos);
break;
//
// The scroller handles changing the value on the thumb for
// us, so read it, convert it back to the range gecko is expecting,
// and tell the content.
//
case NSScrollerKnob:
case NSScrollerKnobSlot:
scrollBarMessage = NS_SCROLLBAR_POS;
SetPosition([mView intValue]);
break;
}
EndDraw();
newPos = (int) ([mView floatValue] * (mMaxValue-mVisibleImageSize));
SetPosition(newPos);
break;
default:
newPos = oldPos; // do nothing
}
// send event to scroll the parent
nsScrollbarEvent scrollBarEvent;
scrollBarEvent.eventStructType = NS_GUI_EVENT;
scrollBarEvent.widget = this;
scrollBarEvent.message = scrollBarMessage;
GetPosition(pos);
scrollBarEvent.position = pos;
Inherited::DispatchWindowEvent(scrollBarEvent);
// update the area of the parent uncovered by the scrolling
nsIWidget* parent = GetParent();
parent->Update();
NS_RELEASE(parent);
// update this scrollbar
Invalidate(PR_FALSE);
Update();
StartDraw();
nsScrollbarEvent scrollBarEvent;
scrollBarEvent.eventStructType = NS_GUI_EVENT;
scrollBarEvent.widget = this;
scrollBarEvent.message = scrollBarMessage;
GetPosition(newPos);
scrollBarEvent.position = newPos;
Inherited::DispatchWindowEvent(scrollBarEvent);
}
/**-------------------------------------------------------------------------------
* DispatchMouseEvent handle an event for this scrollbar
* @update dc 08/31/98
@ -195,10 +193,8 @@ PRBool nsScrollbar::DispatchMouseEvent(nsMouseEvent &aEvent)
NS_METHOD nsScrollbar::SetMaxRange(PRUint32 aEndRange)
{
mMaxValue = ((int)aEndRange) > 0 ? aEndRange : 10;
if ( GetControl() ) {
PRInt32 fullVisibleArea = mVisibleImageSize + mMaxValue;
[mView setFloatValue:[mView floatValue] knobProportion:(mVisibleImageSize / (float)fullVisibleArea)];
}
if ( GetControl() )
[mView setFloatValue:[mView floatValue] knobProportion:(mVisibleImageSize / (float)mMaxValue)];
return NS_OK;
}
@ -225,8 +221,8 @@ NS_METHOD nsScrollbar::SetPosition(PRUint32 aPos)
if ((PRInt32)aPos < 0)
aPos = 0;
mValue = ((PRInt32)aPos) > mMaxValue ? mMaxValue : ((int)aPos);
[mView setFloatValue:(aPos / (float)mMaxValue)];
mValue = aPos > mMaxValue ? mMaxValue : aPos;
[mView setFloatValue:(mValue / (float)(mMaxValue-mVisibleImageSize))];
return NS_OK;
}
@ -255,8 +251,8 @@ NS_METHOD nsScrollbar::SetThumbSize(PRUint32 aSize)
{
mVisibleImageSize = ((int)aSize) > 0 ? aSize : 1;
PRInt32 fullVisibleArea = mVisibleImageSize + mMaxValue;
[mView setFloatValue:[mView floatValue] knobProportion:(mVisibleImageSize / (float)fullVisibleArea)];
[mView setFloatValue:(mValue / (float)(mMaxValue-mVisibleImageSize))
knobProportion:(mVisibleImageSize / (float)mMaxValue)];
return NS_OK;
}
@ -305,10 +301,13 @@ NS_METHOD nsScrollbar::SetParameters(PRUint32 aMaxRange, PRUint32 aThumbSize,
PRUint32 aPosition, PRUint32 aLineIncrement)
{
SetLineIncrement(aLineIncrement);
SetPosition(aPosition);
mVisibleImageSize = aThumbSize; // needed by SetMaxRange
SetMaxRange(aMaxRange);
SetThumbSize(aThumbSize); // Needs to know the maximum value when calling Mac toolbox.
mVisibleImageSize = ((PRInt32)aThumbSize) > 0 ? aThumbSize : 1;
mMaxValue = ((PRInt32)aMaxRange) > 0 ? aMaxRange : 10;
mValue = aPosition > mMaxValue ? mMaxValue : aPosition;
[mView setFloatValue:(mValue / (float)(mMaxValue-mVisibleImageSize))
knobProportion:(mVisibleImageSize / (float)mMaxValue )];
return NS_OK;
}
@ -365,13 +364,39 @@ nsScrollbar::IsEnabled(PRBool *aState)
@implementation ScrollbarView
-(id)initWithFrame:(NSRect)aRect
//
// -initWithFrame:geckoChild
// Designated Initializer
//
// Init our superclass and make the connection to the gecko nsIWidget we're
// mirroring
//
- (id)initWithFrame:(NSRect)frameRect geckoChild:(nsScrollbar*)inChild
{
mInMove = NO;
[super initWithFrame: aRect];
[super initWithFrame:frameRect];
NS_ASSERTION(inChild, "Need to provide a tether between this and a nsChildView class");
mGeckoChild = inChild;
// make ourselves the target of the scroll and set the action message
[self setTarget:self];
[self setAction:@selector(scroll:)];
return self;
}
//
// -initWithFrame
//
// overridden parent class initializer
//
- (id)initWithFrame:(NSRect)frameRect
{
NS_WARNING("You're calling the wrong initializer. You really want -initWithFrame:geckoChild");
return [self initWithFrame:frameRect geckoChild:nsnull];
}
- (NSWindow*) getNativeWindow
{
NSWindow* currWin = [self window];
@ -386,31 +411,21 @@ nsScrollbar::IsEnabled(PRBool *aState)
mWindow = aWindow;
}
- (void)trackKnob:(NSEvent *)theEvent
//
// -widget
//
// return our gecko child view widget. Note this does not AddRef.
//
- (nsIWidget*) widget
{
printf("tracking knob\n");
[super trackKnob:theEvent];
printf("done tracking knob\n");
return NS_STATIC_CAST(nsIWidget*, mGeckoChild);
}
- (void)trackScrollButtons:(NSEvent *)theEvent
{
printf("tracking buttons");
[super trackScrollButtons:theEvent];
printf("done tracking buttons");
}
- (BOOL)isFlipped
{
return YES;
}
- (void)mouseDown:(NSEvent *)theEvent
{
printf("mouse down in scrollbar\n");
[super mouseDown:theEvent];
}
//
// -mouseMoved
@ -423,13 +438,21 @@ nsScrollbar::IsEnabled(PRBool *aState)
- (void)mouseMoved:(NSEvent*)theEvent
{
// do nothing
if (mInMove)
return;
mInMove = YES;
[super mouseMoved: theEvent];
mInMove = NO;
}
//
// -scroll
//
// the action message we've set up to be called when the scrollbar needs
// to adjust its value. Feed back into the owning widget to process
// how much to scroll and adjust the correct attributes.
//
- (IBAction)scroll:(NSScroller*)sender
{
if ( mGeckoChild )
mGeckoChild->DoScroll([sender hitPart]);
}
@end

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

@ -435,8 +435,8 @@ nsSound::GetSoundResourceName(const char* inSoundName, StringPtr outResourceName
if (NS_FAILED(rv))
return rv;
nsXPIDLCString newMailSound;
rv = icService->GetString(nsIInternetConfigService::eICString_NewMailSoundName, getter_Copies(newMailSound));
nsCAutoString newMailSound;
rv = icService->GetString(nsIInternetConfigService::eICString_NewMailSoundName, newMailSound);
if (NS_FAILED(rv))
return rv;
@ -855,7 +855,7 @@ nsMovieSoundRequest::Notify(nsITimer *timer)
if (!mMovie)
{
NS_ASSERTION(0, "nsMovieSoundRequest has no movie in timer callback");
return NS_OK;;
return NS_OK;
}
#ifdef SOUND_DEBUG

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

@ -39,7 +39,6 @@
#define TOOLKIT_H
#include "nsIToolkit.h"
#include "nsRepeater.h"
#include "nsCOMPtr.h"
#include "nsIEventQueueService.h"
@ -80,20 +79,11 @@ public:
NS_IMETHOD Init(PRThread *aThread);
// are there pending events on the toolkit's event queue?
PRBool ToolkitBusy();
public:
// Appearance Mgr
static bool HasAppearanceManager();
// helpers to determine if the app is in the fg or bg
static void AppInForeground ( ) ;
static void AppInBackground ( ) ;
static bool IsAppInForeground ( ) ;
protected:
static int QuartzChangedCallback(const char* pref, void* data);
static void SetupQuartzRendering();
bool mInited;
static bool sInForeground;
};

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

@ -35,7 +35,6 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsToolkit.h"
#include "nsWidgetAtoms.h"
@ -47,10 +46,9 @@
#include "nsIServiceManager.h"
#include "nsIPref.h"
#include "nsRepeater.h"
// for some reason, this must come last. otherwise the appshell
// component fails to instantiate correctly at runtime.
#undef DARWIN
#import <Cocoa/Cocoa.h>
static CFBundleRef getBundle(CFStringRef frameworkPath)
@ -70,7 +68,6 @@ static CFBundleRef getBundle(CFStringRef frameworkPath)
return bundle;
}
static void* getQDFunction(CFStringRef functionName)
{
static CFBundleRef systemBundle = getBundle(CFSTR("/System/Library/Frameworks/ApplicationServices.framework"));
@ -80,7 +77,6 @@ static void* getQDFunction(CFStringRef functionName)
}
//
// interface EventQueueHanlder
//
@ -89,11 +85,12 @@ static void* getQDFunction(CFStringRef functionName)
//
@interface EventQueueHandler : NSObject
{
nsIEventQueueService* mEventQueueService;
NSTimer* mEventTimer; // our timer [STRONG]
nsIEventQueue* mMainThreadEventQueue; // addreffed
NSTimer* mEventTimer; // our timer [STRONG]
}
- (void)eventTimer:(NSTimer *)theTimer;
- (PRBool)eventsArePending;
@end
@ -118,14 +115,26 @@ static PRUintn gToolkitTLSIndex = 0;
//
- (id)init
{
// lame, but we can't use an nsCOMPtr as a member variable
nsCOMPtr<nsIEventQueueService> service = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID);
mEventQueueService = service.get();
NS_IF_ADDREF(mEventQueueService);
if ( (self = [super init]) )
{
nsCOMPtr<nsIEventQueueService> service = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID);
if (!service) {
[self release];
return nil;
}
service->GetThreadEventQueue(NS_CURRENT_THREAD, &mMainThreadEventQueue); // addref
mEventTimer = [NSTimer scheduledTimerWithTimeInterval:0.005 target:self selector:@selector(eventTimer:) userInfo:nil
repeats:YES];
NS_ASSERTION(mEventTimer, "UH OH! couldn't create periodic event processing timer");
mEventTimer = [NSTimer scheduledTimerWithTimeInterval:0.005
target:self
selector:@selector(eventTimer:)
userInfo:nil
repeats:YES];
if (!mMainThreadEventQueue || !mEventTimer) {
[self release];
return nil;
}
}
return self;
}
@ -140,10 +149,12 @@ static PRUintn gToolkitTLSIndex = 0;
//
- (void) dealloc
{
printf("shutting down event queue\n");
if ( mEventTimer )
[mEventTimer release];
NS_IF_RELEASE(mEventQueueService);
#if DEBUG
printf("shutting down event queue\n");
#endif
[mEventTimer release];
NS_IF_RELEASE(mMainThreadEventQueue);
gEventQueueHandler = nsnull;
@ -157,49 +168,64 @@ printf("shutting down event queue\n");
// Called periodically to process PLEvents from the queue on the current thread
//
#define LOOP_THRESHOLD 20
#define MAX_PROCESS_EVENT_CALLS 20
//#define DEBUG_EVENT_TIMING
//#define TIMED_EVENT_PROCESSING
#define MAX_PLEVENT_TIME_MILLISECONDS 500
- (void)eventTimer:(NSTimer *)theTimer
{
if ( mEventQueueService ) {
nsCOMPtr<nsIEventQueue> queue;
mEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue));
if (queue) {
nsresult rv = NS_OK;
for (PRInt32 i = 0; i < LOOP_THRESHOLD; i++) {
PRBool pendingEvents = PR_FALSE;
queue->PendingEvents(&pendingEvents);
if (!pendingEvents)
break;
queue->ProcessPendingEvents();
NS_ASSERTION(NS_SUCCEEDED(rv), "Error processing PLEvents");
}
#ifdef DEBUG_EVENT_TIMING
AbsoluteTime startTime = ::UpTime();
#endif
if (mMainThreadEventQueue)
{
#ifdef TIMED_EVENT_PROCESSING
// the new way; process events until some time has elapsed, or there are
// no events left. UpTime() is a very low-overhead way to measure time.
AbsoluteTime bailTime = ::AddDurationToAbsolute(MAX_PLEVENT_TIME_MILLISECONDS * durationMillisecond, ::UpTime());
while (1)
{
PRBool pendingEvents = PR_FALSE;
mMainThreadEventQueue->PendingEvents(&pendingEvents);
if (!pendingEvents)
break;
mMainThreadEventQueue->ProcessPendingEvents();
AbsoluteTime now = ::UpTime();
if (UnsignedWideToUInt64(now) > UnsignedWideToUInt64(bailTime))
break;
}
}
EventRecord anEvent;
Repeater::DoIdlers(anEvent);
Repeater::DoRepeaters(anEvent);
}
//
// -eventsArePending
//
// See if events are pending on the event queue on the current thread.
//
- (PRBool)eventsArePending
{
PRBool pendingEvents = PR_FALSE;
if ( mEventQueueService ) {
nsCOMPtr<nsIEventQueue> queue;
mEventQueueService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue));
if (queue)
queue->PendingEvents(&pendingEvents);
#else
// the old way; process events 20 times. Can suck CPU, and make the app
// unresponsive
for (PRInt32 i = 0; i < MAX_PROCESS_EVENT_CALLS; i ++)
{
PRBool pendingEvents = PR_FALSE;
mMainThreadEventQueue->PendingEvents(&pendingEvents);
if (!pendingEvents)
break;
mMainThreadEventQueue->ProcessPendingEvents();
}
#endif
}
return pendingEvents;
#ifdef DEBUG_EVENT_TIMING
Nanoseconds duration = ::AbsoluteDeltaToNanoseconds(::UpTime(), startTime);
UInt32 milliseconds = UnsignedWideToUInt64(duration) / 1000000;
static UInt32 sMaxDuration = 0;
if (milliseconds > sMaxDuration)
sMaxDuration = milliseconds;
printf("Event handling took %u ms (max %u)\n", milliseconds, sMaxDuration);
#endif
}
@ -214,16 +240,22 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsToolkit, nsIToolkit);
// assume we begin as the fg app
bool nsToolkit::sInForeground = true;
static const char* gQuartzRenderingPref = "browser.quartz.enable";
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
nsToolkit::nsToolkit() : mInited(false)
nsToolkit::nsToolkit()
: mInited(false)
{
NS_INIT_ISUPPORTS();
if ( !gEventQueueHandler )
if (!gEventQueueHandler)
{
// autorelease this so that if Init is never called, it is not
// leaked. Init retains it.
gEventQueueHandler = [[[EventQueueHandler alloc] init] autorelease];
}
}
//-------------------------------------------------------------------------
@ -251,108 +283,77 @@ nsToolkit::~nsToolkit()
//-------------------------------------------------------------------------
NS_IMETHODIMP nsToolkit::Init(PRThread */*aThread*/)
{
if (gEventQueueHandler)
[gEventQueueHandler retain];
if (!gEventQueueHandler)
return NS_ERROR_FAILURE;
[gEventQueueHandler retain];
nsWidgetAtoms::AddRefAtoms();
#if TARGET_CARBON
// from Apple's technote
#if UNIVERSAL_INTERFACES_VERSION <= 0x4000
mInited = true;
SetupQuartzRendering();
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
if ( prefs )
prefs->RegisterCallback(gQuartzRenderingPref, QuartzChangedCallback, nsnull);
return NS_OK;
}
//
// QuartzChangedCallback
//
// The pref changed, reset the app to use quartz rendering as dictated by the pref
//
int nsToolkit::QuartzChangedCallback(const char* pref, void* data)
{
SetupQuartzRendering();
return NS_OK;
}
//
// SetupQuartzRendering
//
// Use apple's technote for 10.1.5 to turn on quartz rendering with CG metrics. This
// slows us down about 12% when turned on.
//
void nsToolkit::SetupQuartzRendering()
{
// from Apple's technote, yet un-numbered.
#if UNIVERSAL_INTERFACES_VERSION <= 0x0400
enum {
kQDDontChangeFlags = 0xFFFFFFFF, // don't change anything
kQDDontChangeFlags = 0xFFFFFFFF, // don't change anything
kQDUseDefaultTextRendering = 0, // bit 0
kQDUseTrueTypeScalerGlyphs = (1 << 0), // bit 1
kQDUseCGTextRendering = (1 << 1), // bit 2
kQDUseCGTextMetrics = (1 << 2)
};
#endif
const int kFlagsWeUse = kQDUseCGTextRendering | kQDUseCGTextMetrics;
// turn on quartz rendering if we find the symbol in the app framework. Just turn
// on the bits that we need, don't turn off what someone else might have wanted. If
// the pref isn't found, assume we want it on. That way, we have to explicitly put
// in a pref to disable it, rather than force everyone who wants it to carry around
// an extra pref.
//
// We use QD metrics for speed. i can't see any difference in layout with CG metrics.
typedef UInt32 (*qd_procptr)(UInt32);
qd_procptr SwapQDTextFlags = (qd_procptr) getQDFunction(CFSTR("SwapQDTextFlags"));
static qd_procptr SwapQDTextFlags = (qd_procptr) getQDFunction(CFSTR("SwapQDTextFlags"));
if ( SwapQDTextFlags ) {
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
if (!prefs)
return NS_OK;
return;
PRBool enableQuartz = PR_TRUE;
nsresult rv = prefs->GetBoolPref("browser.quartz.enable", &enableQuartz);
if ( NS_FAILED(rv) || enableQuartz ) {
UInt32 oldFlags = SwapQDTextFlags(kQDDontChangeFlags);
SwapQDTextFlags(oldFlags | kQDUseTrueTypeScalerGlyphs | kQDUseCGTextRendering);
}
nsresult rv = prefs->GetBoolPref(gQuartzRenderingPref, &enableQuartz);
UInt32 oldFlags = SwapQDTextFlags(kQDDontChangeFlags);
if ( NS_FAILED(rv) || enableQuartz )
SwapQDTextFlags(oldFlags | kFlagsWeUse);
else
SwapQDTextFlags(oldFlags & !kFlagsWeUse);
}
#endif
mInited = true;
return NS_OK;
}
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
PRBool nsToolkit::ToolkitBusy()
{
return (gEventQueueHandler) ? [gEventQueueHandler eventsArePending] : PR_FALSE;
}
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
bool nsToolkit::HasAppearanceManager()
{
#define APPEARANCE_MIN_VERSION 0x0110 // we require version 1.1
static bool inited = false;
static bool hasAppearanceManager = false;
if (inited)
return hasAppearanceManager;
inited = true;
SInt32 result;
if (::Gestalt(gestaltAppearanceAttr, &result) != noErr)
return false; // no Appearance Mgr
if (::Gestalt(gestaltAppearanceVersion, &result) != noErr)
return false; // still version 1.0
hasAppearanceManager = (result >= APPEARANCE_MIN_VERSION);
return hasAppearanceManager;
}
void
nsToolkit :: AppInForeground ( )
{
sInForeground = true;
}
void
nsToolkit :: AppInBackground ( )
{
sInForeground = false;
}
bool
nsToolkit :: IsAppInForeground ( )
{
return sInForeground;
}
//-------------------------------------------------------------------------
//
// Return the nsIToolkit for the current thread. If a toolkit does not