Fix bug 279510: remove all the pre-Carbon code and TARGET_CARBON #idfefs from widget. Patch by Ludovic Hirlimann <qa-mozilla@hirlimann.net>, r=pink, sr=me

This commit is contained in:
smfr%smfr.org 2005-01-28 17:59:37 +00:00
Родитель 5a324456a7
Коммит 8eaec170ab
36 изменённых файлов: 85 добавлений и 5131 удалений

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

@ -1,102 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mike Pinkerton (pinkerton@netscape.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "DefProcFakery.h"
#pragma options align=mac68k
typedef struct {
short jmpInstr;
Ptr jmpAddr;
Handle mSystemDefProc;
} JmpRecord, *JmpPtr, **JmpHandle;
#pragma options align=reset
Boolean
DefProcFakery :: CreateDefProc( RoutineDescriptor* inRoutineAddr, Handle inSystemDefProc, Handle* outDefProcHandle )
{
*outDefProcHandle = ::NewHandle(sizeof(JmpRecord));
if ( !*outDefProcHandle )
return false;
JmpHandle jh = (JmpHandle) *outDefProcHandle;
(**jh).jmpInstr = 0x4EF9; // jump instruction
(**jh).jmpAddr = (Ptr) inRoutineAddr; // where to jump to
(**jh).mSystemDefProc = inSystemDefProc; // the system defproc, so we can get it later
::HLockHi((Handle)jh);
return true;
}
//
// GetSystemDefProc
//
// Returns the system defProc stashed in the fake defproc from when it was created
//
Handle
DefProcFakery :: GetSystemDefProc ( Handle inFakedDefProc )
{
Handle sysDefProc = NULL;
JmpHandle jH = (JmpHandle) inFakedDefProc;
if ( jH )
sysDefProc = (**jH).mSystemDefProc;
return sysDefProc;
} // GetSystemDefProc
//
// DestroyDefProc
//
// Delete the def proc and the routine descriptor associated with it
//
void
DefProcFakery :: DestroyDefProc ( Handle inFakedDefProc )
{
JmpHandle jh = (JmpHandle) inFakedDefProc;
::DisposeRoutineDescriptor ( (RoutineDescriptor*)((**jh).jmpAddr) );
::DisposeHandle ( inFakedDefProc );
} // DestroyDefProc

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

@ -1,70 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mike Pinkerton (pinkerton@netscape.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef DefProcFakery_h__
#define DefProcFakery_h__
#include <Resources.h>
//
// DefProcFakery
//
// There are times where we want to replace the standard defProc for a
// menu or a window, but don't want to go through the hassle of creating
// a stand-alone MDEF/WDEF/etc. This routine will build up a Handle that
// can replace a standard sytem defProc handle and calls into the code
// specified by |inRoutineAddr|.
//
namespace DefProcFakery
{
// Create a handle that looks like a code resource and stash |inRoutineAddr| into it
// so we can divert the defProc into our code.
Boolean CreateDefProc( RoutineDescriptor* inRoutineAddr, Handle inSystemDefProc, Handle* outDefProcHandle ) ;
// Retrieve the system defproc stashed away in the create call
Handle GetSystemDefProc ( Handle inFakedDefProc ) ;
// Delete the def proc and the routine descriptor associated with it
void DestroyDefProc ( Handle inFakedDefProc ) ;
}
#endif

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

@ -185,17 +185,7 @@ NS_IMETHODIMP nsAppShell::Spindown(void)
nsAppShell::nsAppShell()
{
#if TARGET_CARBON
mInitializedToolbox = PR_TRUE;
#else
// The toolbox initialization code has moved to NSStdLib (InitializeToolbox)
if (!mInitializedToolbox)
{
InitializeMacToolbox();
mInitializedToolbox = PR_TRUE;
}
#endif
mRefCnt = 0;
mExitCalled = PR_FALSE;
}

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

@ -61,7 +61,8 @@ NS_IMETHODIMP nsBidiKeyboard::IsLangRTL(PRBool *aIsRTL)
static fpKLGetKeyboardLayoutProperty_type fpKLGetKeyboardLayoutProperty = NULL;
if (!checked) {
CFBundleRef bundle = ::CFBundleGetBundleWithIdentifier(CFSTR("com.apple.Carbon"));
CFBundleRef bundle =
::CFBundleGetBundleWithIdentifier(CFSTR("com.apple.Carbon"));
if (bundle) {
fpKLGetCurrentKeyboardLayout =
::CFBundleGetFunctionPointerForName(bundle, CFSTR("KLGetCurrentKeyboardLayout"));

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

@ -35,10 +35,9 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsButton.h"
#if TARGET_CARBON || (UNIVERSAL_INTERFACES_VERSION >= 0x0330)
#include <ControlDefinitions.h>
#endif
#include "nsButton.h"
NS_IMPL_ADDREF(nsButton)
NS_IMPL_RELEASE(nsButton)

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

@ -36,9 +36,8 @@
* ***** END LICENSE BLOCK ***** */
#include "nsCheckButton.h"
#if TARGET_CARBON
#include <ControlDefinitions.h>
#endif
NS_IMPL_ADDREF(nsCheckButton)
NS_IMPL_RELEASE(nsCheckButton)

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

@ -114,11 +114,7 @@ nsClipboard :: SetNativeClipboardData ( PRInt32 aWhichClipboard )
nsMimeMapperMac theMapper;
#if TARGET_CARBON
::ClearCurrentScrap();
#else
::ZeroScrap();
#endif
// get flavor list that includes all flavors that can be written (including ones
// obtained through conversion)
@ -284,15 +280,9 @@ nsClipboard :: PutOnClipboard ( ResType inFlavor, const void* inData, PRInt32 in
{
nsresult errCode = NS_OK;
#if TARGET_CARBON
ScrapRef scrap;
::GetCurrentScrap(&scrap);
::PutScrapFlavor( scrap, inFlavor, kScrapFlavorMaskNone, inLen, inData );
#else
long numBytes = ::PutScrap ( inLen, inFlavor, inData );
if ( numBytes != noErr )
errCode = NS_ERROR_FAILURE;
#endif
return errCode;
@ -426,7 +416,6 @@ nsClipboard :: GetNativeClipboardData ( nsITransferable * aTransferable, PRInt32
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks ( flavorStr, &clipboardData, &dataSize );
unsigned char *clipboardDataPtr = (unsigned char *) clipboardData;
#if TARGET_CARBON
// 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
@ -438,7 +427,6 @@ nsClipboard :: GetNativeClipboardData ( nsITransferable * aTransferable, PRInt32
dataSize -= sizeof(PRUnichar);
clipboardDataPtr += sizeof(PRUnichar);
}
#endif
// put it into the transferable
nsCOMPtr<nsISupports> genericDataWrapper;
@ -476,7 +464,6 @@ nsClipboard :: GetDataOffClipboard ( ResType inMacFlavor, void** outData, PRInt3
*outDataSize = 0;
#if TARGET_CARBON
ScrapRef scrap;
long dataSize;
OSStatus err;
@ -506,32 +493,6 @@ nsClipboard :: GetDataOffClipboard ( ResType inMacFlavor, void** outData, PRInt3
*outDataSize = dataSize;
*outData = dataBuff;
}
#else
long clipResult = ::GetScrap(NULL, inMacFlavor, &offsetUnused);
if ( clipResult > 0 ) {
Handle dataHand = ::NewHandle(0);
if ( !dataHand )
return NS_ERROR_OUT_OF_MEMORY;
long dataSize = ::GetScrap ( dataHand, inMacFlavor, &offsetUnused );
NS_ASSERTION(dataSize > 0, "nsClipboard:: Error getting data off the clipboard, size negative");
if ( dataSize > 0 ) {
char* dataBuff = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(dataSize));
if ( !dataBuff )
return NS_ERROR_OUT_OF_MEMORY;
::HLock(dataHand);
::BlockMoveData ( *dataHand, dataBuff, dataSize );
::HUnlock(dataHand);
::DisposeHandle(dataHand);
if ( outDataSize )
*outDataSize = dataSize;
*outData = dataBuff;
}
else
return NS_ERROR_FAILURE;
}
#endif /* TARGET_CARBON */
return NS_OK;
} // GetDataOffClipboard
@ -613,7 +574,6 @@ nsClipboard :: CheckIfFlavorPresent ( ResType inMacFlavor )
{
PRBool retval = PR_FALSE;
#if TARGET_CARBON
ScrapRef scrap = nsnull;
OSStatus err = ::GetCurrentScrap(&scrap);
if ( scrap ) {
@ -637,12 +597,5 @@ nsClipboard :: CheckIfFlavorPresent ( ResType inMacFlavor )
}
}
#else
long offsetUnused = 0;
long clipResult = ::GetScrap(NULL, inMacFlavor, &offsetUnused);
if ( clipResult > 0 )
retval = PR_TRUE; // we found one!
#endif
return retval;
} // CheckIfFlavorPresent

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

@ -639,7 +639,6 @@ nsDragService::GetData ( nsITransferable * aTransferable, PRUint32 aItemIndex )
nsLinebreakHelpers::ConvertPlatformToDOMLinebreaks(flavorStr.get(), &dataBuff, NS_REINTERPRET_CAST(int*, &dataSize));
unsigned char *dataPtr = (unsigned char *) dataBuff;
#if TARGET_CARBON
// 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
@ -651,7 +650,6 @@ nsDragService::GetData ( nsITransferable * aTransferable, PRUint32 aItemIndex )
dataSize -= sizeof(PRUnichar);
dataPtr += sizeof(PRUnichar);
}
#endif
nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr.get(), (void *) dataPtr, dataSize, getter_AddRefs(genericDataWrapper));
}

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

@ -1,589 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsDynamicMDEF.h"
#include "prinrval.h"
#include "nsCOMPtr.h"
#include "nsIDOMElement.h"
#include "nsIDOMNode.h"
#include "nsMenuBar.h"
#include "nsIMenuBar.h"
#include "DefProcFakery.h"
#include "nsGUIEvent.h"
#include <Resources.h>
#include <MixedMode.h>
extern nsWeakPtr gMacMenubar;
// needed for CallMenuDefProc() to work correctly
#pragma options align=mac68k
// Caching the Mac menu
nsVoidArray gPreviousMenuHandleStack; // hold MenuHandles
nsMenuStack gPreviousMenuStack; // weak refs
nsWeakPtr gPreviousMenuBar; // weak ref
MenuHandle gSizedMenu = nsnull;
extern Handle gMDEF;
bool gTested = false;
MenuHandle gCachedMenuHandle = nsnull;
PRUint16 gCachedMenuID = 0;
extern PRInt16 gMenuDepth; // volital running total
extern PRInt16 gCurrentMenuDepth; // The menu depth that is currently shown
extern MenuHandle gLevel2HierMenu;
extern MenuHandle gLevel3HierMenu;
extern MenuHandle gLevel4HierMenu;
extern MenuHandle gLevel5HierMenu;
PRUint32 gCurrentMenuItem = 0; // 1 based ala MacOS
PRUint32 gCurrentTopLevelMenuIndex = 0;
MenuHandle gPreviousTopLevelMenuHandle = nsnull;
nsIMenu * gPreviousTopLevelMenu = nsnull;
nsIMenu * gPreviousMenu = nsnull;
MenuHandle gPreviousMenuHandle = nsnull;
//------------------------------------------------------------------------------
nsMenuStack::nsMenuStack()
{
}
nsMenuStack::~nsMenuStack()
{
}
nsresult
nsMenuStack::GetMenuAt(PRInt32 aIndex, nsIMenu **outMenu)
{
// I'd prefer to fix the caller, but this will be safe
nsCOMPtr<nsISupports> elementPtr = getter_AddRefs(mMenuArray.ElementAt(aIndex));
if (!elementPtr)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(elementPtr);
return weakRef->QueryReferent(NS_GET_IID(nsIMenu), NS_REINTERPRET_CAST(void**, outMenu));
}
PRBool
nsMenuStack::HaveMenuAt(PRInt32 aIndex)
{
// I'd prefer to fix the caller, but this will be safe
nsCOMPtr<nsISupports> elementPtr = getter_AddRefs(mMenuArray.ElementAt(aIndex));
if (!elementPtr)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIWeakReference> weakRef = do_QueryInterface(elementPtr);
nsCOMPtr<nsIMenu> theMenu = do_QueryReferent(weakRef);
return (theMenu.get() != nsnull);
}
PRBool nsMenuStack::RemoveMenuAt(PRInt32 aIndex)
{
return mMenuArray.RemoveElementAt(aIndex);
}
PRBool nsMenuStack::InsertMenuAt(nsIMenu* inMenuItem, PRInt32 aIndex)
{
nsCOMPtr<nsISupportsWeakReference> weakRefFactory = do_QueryInterface(inMenuItem);
if (!weakRefFactory) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsISupports> observerRef = getter_AddRefs(NS_STATIC_CAST(nsISupports*, NS_GetWeakReference(weakRefFactory)));
if (!observerRef) return NS_ERROR_NULL_POINTER;
return mMenuArray.InsertElementAt(observerRef, aIndex);
}
#pragma mark -
//------------------------------------------------------------------------------
// Internal functions
void nsDynamicChooseItem(
MenuHandle theMenu,
Rect * menuRect,
Point hitPt,
short * whichItem);
void nsDynamicSizeTheMenu(
MenuHandle theMenu);
void nsBuildMenu(
MenuHandle theMenu,
PRBool isChild);
void nsPushMenu(
nsIMenu * aMenu);
void nsPopMenu(
nsIMenu ** aMenu);
void nsPushMenuHandle(
MenuHandle aMenu);
void nsPopMenuHandle(
MenuHandle * aMenu);
void nsCallSystemMDEF(
short message,
MenuHandle theMenu,
Rect * menuRect,
Point hitPt,
short * whichItem);
void nsDoMagic(
MenuHandle theMenu);
void nsPostBuild(
nsIMenu * menu,
MenuHandle theMenu,
PRBool isChild);
bool nsIsHierChild(
MenuHandle theMenu);
void nsCheckDestroy(
MenuHandle theMenu,
short * whichItem);
//void TestPreviousMenuStackUnwind(nsIMenu * aMenuJustBuilt, MenuHandle aMenuHandleJustBuilt);
//void TestCheckDestroy(MenuHandle theMenu, short * whichItem);
//void TestPostBuild(nsIMenu * menu, MenuHandle theMenu, PRBool isChild);
//------------------------------------------------------------------------------
pascal void nsDynamicMDEFMain(
short message,
MenuHandle theMenu,
Rect * menuRect,
Point hitPt,
short * whichItem)
{
switch (message) {
case kMenuDrawMsg:
//printf(" Draw passed in menu is = %d \n", *theMenu);
//printf(" t= %d l= %d b= %d r= %d\n", (*menuRect).top, (*menuRect).left, (*menuRect).bottom, (*menuRect).right);
//printf(" Point.v = %d Point.h = %d\n", hitPt.v, hitPt.h);
//printf(" whichItem = %d \n", *whichItem);
//printf(" theMenu.menuID = %d \n", (**theMenu).menuID);
nsCheckDestroy(theMenu, whichItem);
break;
case kMenuChooseMsg:
// Keep track of currently chosen item
nsDynamicChooseItem(theMenu, menuRect, hitPt, whichItem);
return; // Yes, intentional return as CallSystemMDEF has happened already
break;
case kMenuSizeMsg:
//printf("Size passed in menu is = %d \n", *theMenu);
//printf(" t= %d l= %d b= %d r= %d \n", (*menuRect).top, (*menuRect).left, (*menuRect).bottom ,(*menuRect).right);
//printf(" Point.v = %d Point.h = %d \n", hitPt.v, hitPt.h);
//printf(" whichItem = %d \n", *whichItem);
//printf(" theMenu.menuID = %d \n", (**theMenu).menuID);
nsCheckDestroy(theMenu, whichItem);
// Need to make sure that we rebuild the menu every time...
if (gPreviousMenuHandleStack.Count())
{
nsCOMPtr<nsIMenu> menu;
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(menu));
// nsIMenu * menu = (nsIMenu *) gPreviousMenuStack[gPreviousMenuStack.Count() - 1];
MenuHandle menuHandle = (MenuHandle) gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1];
//printf(" gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
//printf(" gPreviousMenuHandleStack.Count() = %d \n", gPreviousMenuHandleStack.Count());
if( menu && menuHandle ) {
if( menuHandle == theMenu ) {
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(menu));
if(listener) {
//printf("MenuPop \n");
nsMenuEvent mevent(NS_MENU_SELECTED);
mevent.time = PR_IntervalNow();
// UNDO
listener->MenuDeselected(mevent);
//gPreviousMenuStack.RemoveElementAt(gPreviousMenuStack.Count() - 1);
gPreviousMenuStack.RemoveMenuAt(gPreviousMenuStack.Count() - 1);
//NS_IF_RELEASE(menu);
//printf("%d items now on gPreviousMenuStack \n", gPreviousMenuStack.Count());
gPreviousMenuHandleStack.RemoveElementAt(gPreviousMenuHandleStack.Count() - 1);
}
}
}
}
nsDynamicSizeTheMenu(theMenu);
break;
}
nsCallSystemMDEF(message, theMenu, menuRect, hitPt, whichItem);
// Force a size message next time we draw this menu
if(message == kMenuDrawMsg) {
#if !TARGET_CARBON
(**theMenu).menuWidth = -1;
(**theMenu).menuHeight = -1;
#endif
}
}
//------------------------------------------------------------------------------
void nsCheckDestroy(MenuHandle theMenu, short * whichItem)
{
// Determine if we have unselected the previous popup. If so we need to
// destroy it now.
bool changeOccured = true;
bool isChild = false;
if(gCurrentMenuItem == *whichItem)
changeOccured = false;
if(gPreviousMenuHandleStack.Count() == 0 || !gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1])
changeOccured = false;
if(nsIsHierChild(theMenu))
isChild = true;
if(changeOccured && !isChild) {
nsPreviousMenuStackUnwind(nsnull, theMenu);
if(gCurrentMenuDepth > 1)
gCurrentMenuDepth--;
}
}
//------------------------------------------------------------------------------
void nsDynamicChooseItem(
MenuHandle theMenu,
Rect * menuRect,
Point hitPt,
short * whichItem)
{
//printf("enter DynamicChooseItem \n");
nsCallSystemMDEF(kMenuChooseMsg, theMenu, menuRect, hitPt, whichItem);
nsCheckDestroy(theMenu, whichItem);
gCurrentMenuItem = *whichItem;
//printf("exit DynamicChooseItem \n");
}
//------------------------------------------------------------------------------
void nsDynamicSizeTheMenu(
MenuHandle theMenu)
{
//printf("enter DynamicSizeTheMenu \n");
nsDoMagic(theMenu);
//printf("exit DynamicSizeTheMenu \n");
}
//------------------------------------------------------------------------------
bool nsIsHierChild(MenuHandle theMenu)
{
if(theMenu == gLevel2HierMenu) {
if(gCurrentMenuDepth <= 2) return true;
} else if(theMenu == gLevel3HierMenu) {
if(gCurrentMenuDepth <= 3) return true;
} else if(theMenu == gLevel4HierMenu) {
if(gCurrentMenuDepth <= 4) return true;
} else if(theMenu == gLevel5HierMenu) {
if(gCurrentMenuDepth <= 5) return true;
}
return false;
}
//------------------------------------------------------------------------------
void nsDoMagic(MenuHandle theMenu)
{
//printf("DoMagic \n");
// ask if this is a child of the previous menu
PRBool isChild = PR_FALSE;
if (gPreviousMenuStack.Count() > 0)
{
if (gPreviousMenuStack.HaveMenuAt(gPreviousMenuStack.Count() - 1)) {
if(nsIsHierChild(theMenu)) {
isChild = PR_TRUE;
}
}
}
if(theMenu == gLevel2HierMenu) {
gCurrentMenuDepth = 2;
} else if(theMenu == gLevel3HierMenu) {
gCurrentMenuDepth = 3;
} else if(theMenu == gLevel4HierMenu) {
gCurrentMenuDepth = 4;
} else if(theMenu == gLevel5HierMenu) {
gCurrentMenuDepth = 5;
} else {
gCurrentMenuDepth = 1;
}
nsBuildMenu(theMenu, isChild);
}
//------------------------------------------------------------------------------
void nsBuildMenu(MenuHandle theMenu, PRBool isChild)
{
// printf("enter BuildMenu \n");
nsCOMPtr<nsIMenuBar> menubar = do_QueryReferent(gMacMenubar);
if (!menubar || !theMenu) {
return;
}
nsMenuEvent mevent(NS_MENU_SELECTED);
mevent.time = PR_IntervalNow();
mevent.mCommand = (PRUint32) theMenu;
// If toplevel
if( gCurrentMenuDepth < 2 ) {
PRUint32 numMenus = 0;
menubar->GetMenuCount(numMenus);
numMenus--;
for(PRInt32 i = numMenus; i >= 0; i--) {
nsCOMPtr<nsIMenu> menu;
menubar->GetMenuAt(i, *getter_AddRefs(menu));
if(menu) {
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(menu));
if(listener) {
// Reset menu depth count
gMenuDepth = 0;
nsEventStatus status = listener->MenuSelected(mevent);
if(status != nsEventStatus_eIgnore)
{
nsPostBuild(menu, theMenu, isChild);
gPreviousTopLevelMenuHandle = theMenu;
gPreviousTopLevelMenu = menu;
gPreviousMenuBar = do_GetWeakReference(menubar);
//printf("exit BuildMenu \n");
return;
}
}
}
}
} else {
// Not top level, so we can't use recursive MenuSelect <sigh>
// We must use the previously chosen menu item in combination
// with the current menu to determine what menu needs to be constructed
//printf("gCurrentMenuItem = %d \n", gCurrentMenuItem);
if (gCurrentMenuItem){
if (gPreviousMenuStack.Count() > 0)
{
nsCOMPtr<nsIMenu> prevMenu;
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(prevMenu));
//nsIMenu * prevMenu = (nsIMenu *) gPreviousMenuStack[gPreviousMenuStack.Count() - 1];
//printf("gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count() );
if(prevMenu)
{
nsCOMPtr<nsISupports> supports;
prevMenu->GetItemAt(gCurrentMenuItem - 1, *getter_AddRefs(supports));
nsCOMPtr<nsIMenu> menu = do_QueryInterface(supports);
if (menu)
{
nsCOMPtr<nsIMenuListener> menulistener = do_QueryInterface(menu);
menulistener->MenuSelected(mevent);
nsPostBuild(menu, theMenu, isChild);
}
}
}
}
}
//printf("exit BuildMenu \n");
}
//------------------------------------------------------------------------------
void nsPostBuild(nsIMenu * menu, MenuHandle theMenu, PRBool isChild)
{
// it is built now
if (isChild || (gPreviousMenuHandleStack.Count() == 0 ||
gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1] != theMenu))
{
nsPushMenu(menu);
nsPushMenuHandle(theMenu);
//printf("Push: %d items in gMenuHandleStack \n", gMenuHandleStack.Count());
}
}
//------------------------------------------------------------------------------
void nsCallSystemMDEF(
short message,
MenuHandle theMenu,
Rect * menuRect,
Point hitPt,
short * whichItem)
{
// extract the real system mdef out of the fake one we've stored in the menu
Handle fakedMDEF = (**theMenu).menuProc;
Handle systemDefProc = DefProcFakery::GetSystemDefProc ( fakedMDEF );
SInt8 state = ::HGetState(systemDefProc);
::HLock(systemDefProc);
// can't use NewMenuDefProc() here because the routine descriptor has to use kM68kISA
CallMenuDefProc((RoutineDescriptorPtr)*systemDefProc, message, theMenu, menuRect, hitPt, whichItem);
::HSetState(systemDefProc, state);
return;
}
//------------------------------------------------------------------------------
void nsPushMenu(nsIMenu *aMenu)
{
gPreviousMenuStack.InsertMenuAt(aMenu, gPreviousMenuStack.Count());
}
//------------------------------------------------------------------------------
void nsPopMenu(nsIMenu ** aMenu)
{
if(gPreviousMenuStack.Count() > 0)
{
// *aMenu = (nsIMenu *) gPreviousMenuStack[gPreviousMenuStack.Count() - 1];
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, aMenu);
gPreviousMenuStack.RemoveMenuAt(gPreviousMenuStack.Count() - 1);
} else
*aMenu = nsnull;
}
//------------------------------------------------------------------------------
void nsPreviousMenuStackUnwind(nsIMenu * aMenuJustBuilt, MenuHandle aMenuHandleJustBuilt)
{
//PRBool shouldReleaseMenubar = PR_FALSE;
//printf("PreviousMenuStackUnwind called \n");
//printf("%d items on gPreviousMenuStack \n", gPreviousMenuStack.Count());
while (gPreviousMenuHandleStack.Count())
{
nsCOMPtr<nsIMenu> menu; // = (nsIMenu *) gPreviousMenuStack[gPreviousMenuStack.Count() - 1];
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(menu));
MenuHandle menuHandle = (MenuHandle) gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1];
if (menu)
{
//printf(" gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
//printf(" gPreviousMenuHandleStack.Count() = %d \n", gPreviousMenuHandleStack.Count());
if( menuHandle ) {
if( menuHandle != aMenuHandleJustBuilt ) {
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(menu));
if(listener) {
nsMenuEvent mevent(NS_MENU_SELECTED);
mevent.time = PR_IntervalNow();
// UNDO
listener->MenuDeselected(mevent);
//gPreviousMenuStack.RemoveElementAt(gPreviousMenuStack.Count() - 1);
gPreviousMenuStack.RemoveMenuAt(gPreviousMenuStack.Count() - 1);
// NS_IF_RELEASE(menu);
//shouldReleaseMenubar = PR_TRUE;
//printf("%d items now on gPreviousMenuStack \n", gPreviousMenuStack.Count());
gPreviousMenuHandleStack.RemoveElementAt(gPreviousMenuHandleStack.Count() - 1);
}
}
else {
//printf(" gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
//printf(" gPreviousMenuHandleStack.Count() = %d \n", gPreviousMenuHandleStack.Count());
// we are the aMenuHandleJustBuilt
return;
}
}
}
else
{
// remove the weak ref
gPreviousMenuStack.RemoveMenuAt(gPreviousMenuStack.Count() - 1);
NS_ASSERTION(menuHandle != aMenuHandleJustBuilt, "Got the menu handle just built");
if( menuHandle )
gPreviousMenuHandleStack.RemoveElementAt(gPreviousMenuHandleStack.Count() - 1);
}
}
// relinquish hold of the menubar _after_ releasing the menu so it can finish
// unregistering itself.
//if ( shouldReleaseMenubar )
// gPreviousMenuBar = nsnull;
//printf(" gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
//printf(" gPreviousMenuHandleStack.Count() = %d \n", gPreviousMenuHandleStack.Count());
}
//------------------------------------------------------------------------------
void nsPushMenuHandle(MenuHandle aMenu)
{
gPreviousMenuHandleStack.AppendElement(aMenu);
}
//------------------------------------------------------------------------------
void nsPopMenuHandle(MenuHandle * aMenu)
{
if (gPreviousMenuHandleStack.Count() > 0)
{
*aMenu = (MenuHandle) gPreviousMenuHandleStack[gPreviousMenuHandleStack.Count() - 1];
gPreviousMenuHandleStack.RemoveElementAt(gPreviousMenuHandleStack.Count() - 1);
}
}
#pragma options align=reset

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

@ -1,125 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// MDEF for doing dynamic menu construction
#ifndef nsDynamicMDEF_h__
#define nsDynamicMDEF_h__
#include "nsSupportsArray.h"
#include "nsIMenu.h"
#include <Menus.h>
pascal void nsDynamicMDEFMain(
short message,
MenuHandle theMenu,
Rect * menuRect,
Point hitPt,
short * whichItem);
void nsPreviousMenuStackUnwind(
nsIMenu * aMenuJustBuilt,
MenuHandle aMenuHandleJustBuilt);
// helper class useful for counting instances
class nsInstanceCounter
{
public:
nsInstanceCounter(const char* inDesc)
: mInstanceCount(0)
, mDescription(inDesc)
{
}
~nsInstanceCounter()
{
printf("%s %ld\n", mDescription, mInstanceCount);
}
nsInstanceCounter& operator ++() // prefix
{
++ mInstanceCount;
return *this;
}
nsInstanceCounter& operator -- () // prefix
{
-- mInstanceCount;
return *this;
}
protected:
PRInt32 mInstanceCount;
const char* mDescription;
};
//------------------------------------------------------------------------------
class nsMenuStack
{
public:
nsMenuStack();
~nsMenuStack();
PRInt32 Count()
{
PRUint32 num;
mMenuArray.Count(&num);
return (PRInt32)num;
}
// returns addreffed nsIMenu
nsresult GetMenuAt(PRInt32 aIndex, nsIMenu **outMenu);
PRBool HaveMenuAt(PRInt32 aIndex);
PRBool RemoveMenuAt(PRInt32 aIndex); // no release
PRBool InsertMenuAt(nsIMenu* aElement, PRInt32 aIndex); // no addrefs; weak ref.
protected:
nsSupportsArray mMenuArray; // array of weak refs to nsIMenus
};
#endif nsDynamicMDEF_h__

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

@ -90,11 +90,7 @@ protected:
PRInt16 PutLocalFile(const nsString& inTitle, const nsString& inDefaultName, nsILocalFile** outFile);
void MapFilterToFileTypes ( ) ;
#if TARGET_CARBON
void SetupFormatMenuItems (NavDialogCreationOptions* dialogCreateOptions) ;
#else
void SetupFormatMenuItems (NavDialogOptions* dialogOptions) ;
#endif
Boolean IsTypeInFilterList ( ResType inType ) ;
Boolean IsExtensionInFilterList ( StrFileName & inFileName ) ;
void HandleShowPopupMenuSelect( NavCBRecPtr callBackParms ) ;

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

@ -48,9 +48,7 @@
#include "nsIServiceManager.h"
#include "nsIPlatformCharset.h"
#if TARGET_CARBON || (UNIVERSAL_INTERFACES_VERSION >= 0x0330)
#include <ControlDefinitions.h>
#endif
#include <Appearance.h>
#include <TextUtils.h>
@ -366,9 +364,6 @@ void nsMacControl::SetupMacControlFont()
NS_PRECONDITION(mContext != nsnull, "No context metrics in SetupMacControlFont");
TextStyle theStyle;
#if !TARGET_CARBON
nsFontUtils::GetNativeTextStyle(*mFontMetrics, *mContext, theStyle);
#endif
// if needed, impose a min size of 9pt on the control font
if (theStyle.tsSize < 9)
theStyle.tsSize = 9;
@ -472,96 +467,10 @@ void nsMacControl::Str255ToString(const Str255& aStr255, nsString& aText)
void nsMacControl::NSStringSetControlTitle(ControlHandle theControl, nsString title)
{
#if TARGET_CARBON
// wow, it sure is nice being able to use core foundation ;)
CFStringRef str = CFStringCreateWithCharacters(NULL, (const UniChar*)title.get(), title.Length());
SetControlTitleWithCFString(theControl, str);
CFRelease(str);
#else
TextStyle theStyle;
ScriptCode fontScript;
OSErr err;
UnicodeToTextRunInfo unicodeTextRunInfo;
const PRUnichar* unicodeText;
char* scriptRunText;
size_t unicodeTextLengthInBytes, unicodeTextReadInBytes,
scriptRunTextSizeInBytes, scriptRunTextLengthInBytes,
scriptCodeRunListLength;
ScriptCodeRun convertedTextScript;
NS_PRECONDITION(mFontMetrics != nsnull, "nsMacControl::NSStringSetControlTitle: no Font Metrics");
//
// determine the script of the font that the control is supposed to be drawn in
//
#if !TARGET_CARBON
nsFontUtils::GetNativeTextStyle(*mFontMetrics, *mContext, theStyle);
#endif
fontScript = ::FontToScript(theStyle.tsFont);
//
// create a Unicode Conveter object (from Unicode -> font)
//
err = ::CreateUnicodeToTextRunInfoByScriptCode(1,&fontScript,&unicodeTextRunInfo);
NS_ASSERTION(err==noErr,"nsMacControl::NSStringSetControlTitle: CreateUnicodeToTextRunInfoByScriptCode failed.");
if (err!=noErr) { return; }
//
// get the Unicode text and prepare buffers
//
unicodeText = title.get();
unicodeTextLengthInBytes = title.Length() * sizeof(PRUnichar);
scriptRunTextSizeInBytes = unicodeTextLengthInBytes * 2;
scriptRunText = new char[scriptRunTextSizeInBytes];
//
// convert from Unicode to script run
//
err = ::ConvertFromUnicodeToScriptCodeRun(unicodeTextRunInfo,
unicodeTextLengthInBytes,NS_REINTERPRET_CAST(const PRUint16*, unicodeText),
0, /* no flags */
0,NULL,NULL,NULL, /* no offset arrays */
scriptRunTextSizeInBytes,&unicodeTextReadInBytes,&scriptRunTextLengthInBytes,
scriptRunText,
1 /* count of scrip runs*/,&scriptCodeRunListLength,&convertedTextScript);
if (err!=noErr)
{
//
// the font script is not capable of rendering this string, we need to find an installed
// script that can
//
err = ::CreateUnicodeToTextRunInfoByScriptCode(0,NULL,&unicodeTextRunInfo);
NS_ASSERTION(err==noErr,"nsMacControl::NSStringSetControlTitle: CreateUnicodeToTextRunInfoByScriptCode failed.");
if (err!=noErr) { return; }
//
// convert from Unicode to script run
//
err = ::ConvertFromUnicodeToScriptCodeRun(unicodeTextRunInfo,
unicodeTextLengthInBytes,NS_REINTERPRET_CAST(const PRUint16*, unicodeText),
0, /* no flags */
0,NULL,NULL,NULL, /* no offset arrays */
scriptRunTextSizeInBytes,&unicodeTextReadInBytes,&scriptRunTextLengthInBytes,
scriptRunText,
1 /* count of scrip runs*/,&scriptCodeRunListLength,&convertedTextScript);
NS_ASSERTION(err==noErr,"nsMacControl::NSStringSetControlTitle: CreateUnicodeToTextRunInfoByScriptCode failed.");
if (err!=noErr) { delete [] scriptRunText; return;}
}
scriptRunText[scriptRunTextLengthInBytes] = 0; // null terminate
if (convertedTextScript.script!=fontScript)
SetupMacControlFontForScript(convertedTextScript.script);
//
// set the control title
//
::SetControlTitle(theControl,c2pstr(scriptRunText));
delete [] scriptRunText;
#endif
}
//-------------------------------------------------------------------------
//
@ -578,9 +487,6 @@ void nsMacControl::SetupMacControlFontForScript(short theScript)
NS_PRECONDITION(mFontMetrics != nsnull, "No font metrics in SetupMacControlFont");
NS_PRECONDITION(mContext != nsnull, "No context metrics in SetupMacControlFont");
#if !TARGET_CARBON
nsFontUtils::GetNativeTextStyle(*mFontMetrics, *mContext, theStyle);
#endif
//
// take the script and select and override font

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

@ -95,46 +95,6 @@ static void ConvertKeyEventToContextMenuEvent(const nsKeyEvent* inKeyEvent, nsMo
static inline PRBool IsContextMenuKey(const nsKeyEvent& inKeyEvent);
#if !TARGET_CARBON
//
// ScrollActionProc
//
// Called from ::TrackControl(), this senses which part of the phantom
// scrollbar the click from the wheelMouse driver was in and sends
// the correct NS_MOUSE_SCROLL event into Gecko. We have to retrieve the
// mouse location from the event dispatcher because it will
// just be the location of the phantom scrollbar, not actually the real
// mouse position.
//
static pascal void ScrollActionProc(ControlHandle ctrl, ControlPartCode partCode)
{
switch (partCode)
{
case kControlUpButtonPart:
case kControlDownButtonPart:
case kControlPageUpPart:
case kControlPageDownPart:
PhantomScrollbarData* data = NS_REINTERPRET_CAST(PhantomScrollbarData*, ::GetControlReference(ctrl));
if ( data && (data->mWidgetToGetEvent || gEventDispatchHandler.GetActive()) ) {
WindowRef window = (**ctrl).contrlOwner;
StPortSetter portSetter(window);
StOriginSetter originSetter(window);
PRBool scrollByLine = !(partCode == kControlPageUpPart || partCode == kControlPageDownPart);
PRInt32 delta =
(partCode == kControlUpButtonPart || partCode == kControlPageUpPart) ? -1 : 1;
nsIWidget* widget = data->mWidgetToGetEvent ?
data->mWidgetToGetEvent : gEventDispatchHandler.GetActive();
Point thePoint = gEventDispatchHandler.GetGlobalPoint();
::GlobalToLocal(&thePoint);
HandleScrollEvent ( kEventMouseWheelAxisY, scrollByLine, delta, thePoint, widget );
}
break;
}
}
#endif
//
// HandleScrollEvent
//
@ -465,9 +425,6 @@ nsMacEventHandler::nsMacEventHandler(nsMacWindow* aTopLevelWidget)
mIMEIsComposing = PR_FALSE;
mIMECompositionStr = nsnull;
#if !TARGET_CARBON
mControlActionProc = NewControlActionUPP(ScrollActionProc);
#endif
}
@ -479,12 +436,6 @@ nsMacEventHandler::~nsMacEventHandler()
delete mIMECompositionStr;
mIMECompositionStr = nsnull;
}
#if !TARGET_CARBON
if ( mControlActionProc ) {
DisposeControlActionUPP(mControlActionProc);
mControlActionProc = nsnull;
}
#endif
}
@ -1597,33 +1548,6 @@ PRBool nsMacEventHandler::HandleMouseDownEvent(EventRecord& aOSEvent)
ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, mouseButton);
#if !TARGET_CARBON
// Check if the mousedown is in our window's phantom scrollbar. If so, track
// the movement of the mouse. The scrolling code is in the action proc.
Point local = aOSEvent.where;
::GlobalToLocal ( &local );
ControlHandle scrollbar;
ControlPartCode partCode = ::FindControl(local, whichWindow, &scrollbar);
if ( partCode >= kControlUpButtonPart && partCode <= kControlPageDownPart && scrollbar ) {
PhantomScrollbarData* data = NS_REINTERPRET_CAST(PhantomScrollbarData*, ::GetControlReference(scrollbar));
if ( data && data->mTag == PhantomScrollbarData::kUniqueTag ) {
#if USEMOUSEPOSITIONFORSCROLLWHEEL
// Uncomment this in order to set the widget to scroll the widget the mouse is over. However,
// we end up getting an idle event while scrolling quickly with the wheel, and the end result
// is that our idle-time mouseMove event kicks in a moves where we think the mouse is to where
// the scrollwheel driver has convinced the OS the mouse really is. Net result: we lose track
// of the widget and scrolling stops until you stop the wheel and move it again :(
data->mWidgetToGetEvent = gEventDispatchHandler.GetWidgetPointed(); // tell action proc which widget to use
#endif
::TrackControl(scrollbar, local, mControlActionProc);
data->mWidgetToGetEvent = nsnull;
break;
}
}
#endif
nsCOMPtr<nsIWidget> kungFuDeathGrip ( mouseEvent.widget ); // ensure widget doesn't go away
nsWindow* widgetHit = NS_STATIC_CAST(nsWindow*, mouseEvent.widget); // while we're processing event
if (widgetHit)
@ -1670,13 +1594,10 @@ PRBool nsMacEventHandler::HandleMouseDownEvent(EventRecord& aOSEvent)
break;
}
#if TARGET_CARBON
case inToolbarButton: // we get this part on Mac OS X only
gEventDispatchHandler.DispatchGuiEvent(mTopLevelWidget, NS_OS_TOOLBAR);
retVal = PR_TRUE;
break;
#endif
}
return retVal;
}

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

@ -51,15 +51,6 @@
class nsWindow;
class nsMacWindow;
#if !TARGET_CARBON
// On OS9, we can't rely on the mouse location from the OS when we're
// tracking the scrollwheel. That's because most drivers patch the OS
// to make everyone think the mouse is hovering over the up/down scroll
// arrow. As a result, we have to track it ourselves to get the correct
// local mouse coordinate when determining where the mouse is for
// scrolling. Luckily, OSX doesn't have this insanity.
#define TRACK_MOUSE_LOC 1
#endif
#if UNIVERSAL_INTERFACES_VERSION < 0x0337
enum {
@ -70,28 +61,6 @@ typedef UInt16 EventMouseWheelAxis;
#endif
#if !TARGET_CARBON
//
// struct PhantomScrollbarData
//
// When creating the phantom scrollbar for a Gecko instance, create
// one of these structures and stick it in the control's refCon. It
// is used not only to identify our scrollbar from any others, but
// also to pass data to the scrollbar's action proc about which
// widget is the one the mouse is over.
//
struct PhantomScrollbarData
{
PhantomScrollbarData ( )
: mTag(kUniqueTag), mWidgetToGetEvent(nsnull) { }
enum ResType { kUniqueTag = 'mozz' };
ResType mTag; // should always be kUniqueTag
nsIWidget* mWidgetToGetEvent; // for the action proc, the widget to get the event
};
#endif
//-------------------------------------------------------------------------
//
@ -207,10 +176,6 @@ protected:
protected:
static PRBool sMouseInWidgetHit;
static PRBool sInBackground;
#if !TARGET_CARBON
ControlActionUPP mControlActionProc;
#endif
nsMacWindow* mTopLevelWidget;
RgnHandle mUpdateRgn;

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

@ -86,7 +86,7 @@
//#include "nsISocketTransportService.h"
//include "nsIFileTransportService.h"
#if TARGET_CARBON && !XP_MACOSX
#if !XP_MACOSX
#include "MenuSharing.h"
#endif
@ -158,7 +158,7 @@ extern nsIWidget * gRollupWidget;
#pragma mark -
#if TARGET_CARBON && !XP_MACOSX
#if !XP_MACOSX
#pragma mark MenuSharingToolkitSupport
//=================================================================
static pascal void ErrorDialog (Str255 s)
@ -199,7 +199,7 @@ nsMacMessagePump::nsMacMessagePump(nsToolkit *aToolkit)
// startup the watch cursor idle time vbl task
nsWatchTask::GetTask().Start();
#if TARGET_CARBON && !XP_MACOSX
#if !XP_MACOSX
// added to support Menu Sharing API. Initializes the Menu Sharing API.
InitSharedMenus (ErrorDialog, EventFilter);
#endif
@ -383,11 +383,6 @@ PRBool nsMacMessagePump::GetEvent(EventRecord &theEvent)
::SetEventMask(everyEvent); // we need keyUp events
PRBool haveEvent = ::WaitNextEvent(everyEvent, &theEvent, sleepTime, mouseRgn);
#if !TARGET_CARBON
if (haveEvent && ::TSMEvent(&theEvent) )
haveEvent = PR_FALSE;
#endif
nsWatchTask::GetTask().EventLoopReached();
return haveEvent;
@ -698,12 +693,6 @@ PRBool nsMacMessagePump::DoMouseDown(EventRecord &anEvent)
Boolean haveEvent;
EventRecord updateEvent;
haveEvent = ::WaitNextEvent(updateMask, &updateEvent, 0, nil);
#if !TARGET_CARBON
if (haveEvent && TSMEvent(&updateEvent))
{
haveEvent = PR_FALSE;
}
#endif
if (haveEvent)
DoUpdate(updateEvent);
}
@ -772,14 +761,12 @@ PRBool nsMacMessagePump::DoMouseDown(EventRecord &anEvent)
nsWatchTask::GetTask().Resume();
break;
#if TARGET_CARBON
case inToolbarButton: // Mac OS X only
nsWatchTask::GetTask().Suspend();
nsGraphicsUtils::SafeSetPortWindowPort(whichWindow);
handled = DispatchOSEventToRaptor(anEvent, whichWindow);
nsWatchTask::GetTask().Resume();
break;
#endif
}
@ -839,13 +826,8 @@ PRBool nsMacMessagePump::DoMouseMove(EventRecord &anEvent)
/* Disable mouse moved events for windowshaded windows -- this prevents tooltips
from popping up in empty space.
*/
#if TARGET_CARBON
if (whichWindow == nil || !::IsWindowCollapsed(whichWindow))
handled = DispatchOSEventToRaptor(anEvent, whichWindow);
#else
if (whichWindow == nil || !::EmptyRgn(((WindowRecord *) whichWindow)->contRgn))
handled = DispatchOSEventToRaptor(anEvent, whichWindow);
#endif
return handled;
}
@ -888,19 +870,7 @@ PRBool nsMacMessagePump::DoKey(EventRecord &anEvent)
//-------------------------------------------------------------------------
PRBool nsMacMessagePump::DoDisk(const EventRecord& anEvent)
{
#if !TARGET_CARBON
if (HiWord(anEvent.message) != noErr)
{
// Error mounting disk. Ask if user wishes to format it.
Point pt = {120, 120}; // System 7 will auto-center dialog
::DILoad();
::DIBadMount(pt, (SInt32) anEvent.message);
::DIUnload();
}
return PR_TRUE;
#else
return PR_FALSE;
#endif
}
@ -993,7 +963,7 @@ void nsMacMessagePump::DoIdle(EventRecord &anEvent)
// send mouseMove event
static Point lastWhere = {0, 0};
#if TARGET_CARBON && !XP_MACOSX
#if !XP_MACOSX
if ( nsToolkit::IsAppInForeground() )
{
// Shared Menu support - note we hardcode first menu ID available as 31000

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

@ -300,15 +300,12 @@ pascal OSErr nsMacTSMMessagePump::UpdateHandler(const AppleEvent *theAppleEvent,
if (err!=noErr)
return err;
#if TARGET_CARBON
ScriptLanguageRecord scriptLangRec;
err = AEGetDescData(&slr, (void *) &scriptLangRec, sizeof(ScriptLanguageRecord));
if (err!=noErr)
return err;
textScript = scriptLangRec.fScript;
#else
textScript = ((ScriptLanguageRecord *)(*(slr.dataHandle)))->fScript;
#endif
NS_ASSERTION( (textScript < smUninterp), "Illegal script code");
NS_ASSERTION(textScript == (ScriptCode)::GetScriptManagerVariable(smKeyScript) , "wrong script code");
@ -329,7 +326,6 @@ pascal OSErr nsMacTSMMessagePump::UpdateHandler(const AppleEvent *theAppleEvent,
if (err==errAEDescNotFound) {
hiliteRangePtr=NULL;
} else if (err==noErr) {
#if TARGET_CARBON
Size hiliteRangeSize = ::AEGetDescDataSize(&hiliteRangeArray);
hiliteRangePtr = (TextRangeArray *) NewPtr(hiliteRangeSize);
if (!hiliteRangePtr)
@ -339,15 +335,10 @@ pascal OSErr nsMacTSMMessagePump::UpdateHandler(const AppleEvent *theAppleEvent,
DisposePtr((Ptr) hiliteRangePtr);
return err;
}
#else
::HLock(hiliteRangeArray.dataHandle);
hiliteRangePtr=(TextRangeArray*)*(hiliteRangeArray.dataHandle);
#endif
} else {
return err;
}
#if TARGET_CARBON
nsCAutoString mbcsText;
Size text_size = ::AEGetDescDataSize(&text);
mbcsText.SetCapacity(text_size+1);
@ -358,14 +349,6 @@ pascal OSErr nsMacTSMMessagePump::UpdateHandler(const AppleEvent *theAppleEvent,
return err;
}
mbcsTextPtr[text_size]=0;
#else
nsCAutoString mbcsText;
Size text_size = ::GetHandleSize(text.dataHandle);
mbcsText.SetCapacity(text_size+1);
char* mbcsTextPtr = mbcsText.BeginWriting();
strncpy(mbcsTextPtr, *(text.dataHandle), text_size);
mbcsTextPtr[text_size]=0;
#endif
//
// must pass HandleUpdateInputArea a null-terminated multibyte string, the text size must include the terminator
@ -379,13 +362,8 @@ pascal OSErr nsMacTSMMessagePump::UpdateHandler(const AppleEvent *theAppleEvent,
//
// clean up
//
#if TARGET_CARBON
if (hiliteRangePtr)
DisposePtr((Ptr) hiliteRangePtr);
#else
if (hiliteRangePtr)
::HUnlock(hiliteRangeArray.dataHandle);
#endif
(void)AEDisposeDesc(&text);
(void)AEDisposeDesc(&hiliteRangeArray);
@ -424,19 +402,13 @@ static OSErr AETextToString(AEDesc &aAEDesc, nsString& aOutString, Size& text_si
text_size = 0;
aOutString.Truncate(0);
#if TARGET_CARBON
text_size = ::AEGetDescDataSize(&aAEDesc) / 2;
aOutString.SetLength(text_size + 1);
unicodeTextPtr = aOutString.BeginWriting();
err = AEGetDescData(&aAEDesc, (void *) unicodeTextPtr, text_size * 2);
if (err!=noErr)
return err;
#else
text_size = ::GetHandleSize(aAEDesc.dataHandle) / 2;
aOutString.SetLength(text_size + 1);
unicodeTextPtr = aOutString.BeginWriting();
memcpy(unicodeTextPtr, *(aAEDesc.dataHandle), text_size * 2);
#endif
unicodeTextPtr[text_size ] = PRUnichar('\0'); // null terminate it.
return noErr;
@ -479,7 +451,7 @@ pascal OSErr nsMacTSMMessagePump::UnicodeUpdateHandler(const AppleEvent *theAppl
}
else if (noErr == err)
{
#if TARGET_CARBON
Size hiliteRangeSize = ::AEGetDescDataSize(&hiliteRangeArray);
hiliteRangePtr = (TextRangeArray *) NewPtr(hiliteRangeSize);
if (!hiliteRangePtr)
@ -492,10 +464,6 @@ pascal OSErr nsMacTSMMessagePump::UnicodeUpdateHandler(const AppleEvent *theAppl
{
goto err1;
}
#else
::HLock(hiliteRangeArray.dataHandle);
hiliteRangePtr = (TextRangeArray*)*(hiliteRangeArray.dataHandle);
#endif
}
else
{
@ -521,13 +489,8 @@ pascal OSErr nsMacTSMMessagePump::UnicodeUpdateHandler(const AppleEvent *theAppl
// clean up
//
err1:
#if TARGET_CARBON
if (hiliteRangePtr)
::DisposePtr((Ptr)hiliteRangePtr);
#else
if (hiliteRangePtr)
::HUnlock(hiliteRangeArray.dataHandle);
#endif
err2:
(void)::AEDisposeDesc(&hiliteRangeArray);

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

@ -48,27 +48,17 @@
#include "nsGUIEvent.h"
#include "nsCarbonHelpers.h"
#include "nsGfxUtils.h"
#include "DefProcFakery.h"
#include "nsMacResources.h"
#include "nsIRollupListener.h"
#include "nsCRT.h"
#include "nsWidgetSupport.h"
#if TARGET_CARBON
#include <CFString.h>
#endif
#include <Gestalt.h>
#include <Quickdraw.h>
#include <MacWindows.h>
#if UNIVERSAL_INTERFACES_VERSION < 0x0340
enum {
kEventWindowConstrain = 83
};
const UInt32 kWindowLiveResizeAttribute = (1L << 28);
#endif
static const char sScreenManagerContractID[] = "@mozilla.org/gfx/screenmanager;1";
// from MacHeaders.c
@ -83,10 +73,6 @@ static const char sScreenManagerContractID[] = "@mozilla.org/gfx/screenmanager;1
extern nsIRollupListener * gRollupListener;
extern nsIWidget * gRollupWidget;
#if !TARGET_CARBON
pascal long BorderlessWDEF ( short inCode, WindowPtr inWindow, short inMessage, long inParam ) ;
long CallSystemWDEF ( short inCode, WindowPtr inWindow, short inMessage, long inParam ) ;
#endif
#define kWindowPositionSlop 20
@ -194,10 +180,6 @@ nsMacWindow::nsMacWindow() : Inherited()
, mResizeIsFromUs(PR_FALSE)
, mShown(PR_FALSE)
, mMacEventHandler(nsnull)
#if !TARGET_CARBON
, mPhantomScrollbar(nsnull)
, mPhantomScrollbarData(nsnull)
#endif
{
mMacEventHandler.reset(new nsMacEventHandler(this));
WIDGET_SET_CLASSNAME("nsMacWindow");
@ -223,13 +205,6 @@ nsMacWindow::~nsMacWindow()
if ( mWindowType == eWindowType_popup )
RemoveBorderlessDefProc ( mWindowPtr );
#if !TARGET_CARBON
// cleanup the struct we hang off the scrollbar's refcon
if ( mPhantomScrollbar ) {
::SetControlReference(mPhantomScrollbar, (long)nsnull);
delete mPhantomScrollbarData;
}
#endif
// clean up DragManager stuff
if ( mDragTrackingHandlerUPP ) {
@ -601,7 +576,6 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent,
}
#if TARGET_CARBON
pascal OSStatus
nsMacWindow :: ScrollEventHandler ( EventHandlerCallRef inHandlerChain, EventRef inEvent, void* userData )
@ -704,7 +678,6 @@ nsMacWindow :: WindowEventHandler ( EventHandlerCallRef inHandlerChain, EventRef
} // WindowEventHandler
#endif
//-------------------------------------------------------------------------
@ -735,17 +708,6 @@ NS_IMETHODIMP nsMacWindow::Create(nsNativeWidget aNativeParent, // this is a w
void
nsMacWindow :: InstallBorderlessDefProc ( WindowPtr inWindow )
{
#if !TARGET_CARBON
// stash the real WDEF so we can call it later
Handle systemPopupWDEF = ((WindowPeek)inWindow)->windowDefProc;
// load the stub WDEF and stash it away. If this fails, we'll just use the normal one.
WindowDefUPP wdef = NewWindowDefUPP( BorderlessWDEF );
Handle fakedDefProc;
DefProcFakery::CreateDefProc ( wdef, systemPopupWDEF, &fakedDefProc );
if ( fakedDefProc )
((WindowPeek)inWindow)->windowDefProc = fakedDefProc;
#endif
} // InstallBorderlessDefProc
@ -759,12 +721,6 @@ nsMacWindow :: InstallBorderlessDefProc ( WindowPtr inWindow )
void
nsMacWindow :: RemoveBorderlessDefProc ( WindowPtr inWindow )
{
#if !TARGET_CARBON
Handle fakedProc = ((WindowPeek)inWindow)->windowDefProc;
Handle oldProc = DefProcFakery::GetSystemDefProc(fakedProc);
DefProcFakery::DestroyDefProc ( fakedProc );
((WindowPeek)inWindow)->windowDefProc = oldProc;
#endif
}
@ -775,13 +731,11 @@ nsMacWindow :: RemoveBorderlessDefProc ( WindowPtr inWindow )
//-------------------------------------------------------------------------
NS_IMETHODIMP nsMacWindow::Show(PRBool bState)
{
#if TARGET_CARBON
// Mac OS X sheet support
nsIWidget *parentWidget = mParent;
nsCOMPtr<nsPIWidgetMac> piParentWidget ( do_QueryInterface(parentWidget) );
WindowRef parentWindowRef = (parentWidget) ?
reinterpret_cast<WindowRef>(parentWidget->GetNativeData(NS_NATIVE_DISPLAY)) : nsnull;
#endif
Inherited::Show(bState);
@ -789,7 +743,6 @@ NS_IMETHODIMP nsMacWindow::Show(PRBool bState)
// necessary activate/deactivate events. Calling ::ShowHide() is
// not adequate, unless we don't want activation (popups). (pinkerton).
if ( bState && !mBounds.IsEmpty() ) {
#if TARGET_CARBON
if ( mIsSheet && parentWindowRef ) {
WindowPtr top = GetWindowTop(parentWindowRef);
if (piParentWidget)
@ -809,7 +762,6 @@ NS_IMETHODIMP nsMacWindow::Show(PRBool bState)
gEventDispatchHandler.DispatchGuiEvent(this, NS_ACTIVATE);
}
else
#endif
if ( mAcceptsActivation )
::ShowWindow(mWindowPtr);
else {
@ -834,7 +786,6 @@ NS_IMETHODIMP nsMacWindow::Show(PRBool bState)
NS_IF_RELEASE(gRollupListener);
NS_IF_RELEASE(gRollupWidget);
}
#if TARGET_CARBON
// Mac OS X sheet support
if (mIsSheet) {
if (piParentWidget)
@ -878,7 +829,6 @@ NS_IMETHODIMP nsMacWindow::Show(PRBool bState)
}
}
else
#endif
if ( mWindowPtr ) {
::HideWindow(mWindowPtr);
}
@ -1075,11 +1025,8 @@ NS_IMETHODIMP nsMacWindow::Move(PRInt32 aX, PRInt32 aY)
// coordinates (within a pixel or two) as a window's current location, it will
// move to (0,0,-1,-1). The fix is to not move the window if we're already
// there. (radar# 2669004)
#if TARGET_CARBON
const PRInt32 kMoveThreshold = 2;
#else
const PRInt32 kMoveThreshold = 0;
#endif
Rect currBounds;
::GetWindowBounds ( mWindowPtr, kWindowGlobalPortRgn, &currBounds );
if ( abs(currBounds.left-aX) > kMoveThreshold || abs(currBounds.top-aY) > kMoveThreshold ) {
@ -1784,62 +1731,3 @@ void nsMacWindow::IsActive(PRBool* aActive)
}
#if !TARGET_CARBON
// needed for CallWindowDefProc() to work correctly
#pragma options align=mac68k
//
// BorderlessWDEF
//
// The window defproc for borderless windows.
//
// NOTE: Assumes the window was created with a variant of |plainDBox| so our
// content/structure adjustments work correctly.
//
pascal long
BorderlessWDEF ( short inCode, WindowPtr inWindow, short inMessage, long inParam )
{
switch ( inMessage ) {
case kWindowMsgDraw:
case kWindowMsgDrawGrowOutline:
case kWindowMsgGetFeatures:
break;
default:
return CallSystemWDEF(inCode, inWindow, inMessage, inParam);
break;
}
return 0;
}
//
// CallSystemWDEF
//
// We really don't want to reinvent the wheel, so call back into the system wdef we have
// stashed away.
//
long
CallSystemWDEF ( short inCode, WindowPtr inWindow, short inMessage, long inParam )
{
// extract the real system wdef out of the fake one we've stored in the window
Handle fakedWDEF = ((WindowPeek)inWindow)->windowDefProc;
Handle systemDefProc = DefProcFakery::GetSystemDefProc ( fakedWDEF );
SInt8 state = ::HGetState(systemDefProc);
::HLock(systemDefProc);
long retval = CallWindowDefProc( (RoutineDescriptorPtr)*systemDefProc, inCode, inWindow, inMessage, inParam);
::HSetState(systemDefProc, state);
return retval;
}
#pragma options align=reset
#endif

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

@ -49,9 +49,8 @@ using std::auto_ptr;
#include "nsPIWidgetMac.h"
#include "nsPIEventSinkStandalone.h"
#if TARGET_CARBON
#include <CarbonEvents.h>
#endif
class nsMacEventHandler;
struct PhantomScrollbarData;
@ -147,12 +146,11 @@ protected:
DragTrackingHandlerUPP mDragTrackingHandlerUPP;
DragReceiveHandlerUPP mDragReceiveHandlerUPP;
#if TARGET_CARBON
pascal static OSStatus WindowEventHandler ( EventHandlerCallRef inHandlerChain,
EventRef inEvent, void* userData ) ;
pascal static OSStatus ScrollEventHandler ( EventHandlerCallRef inHandlerChain,
EventRef inEvent, void* userData ) ;
#endif
PRPackedBool mWindowMadeHere; // true if we created the window
PRPackedBool mIsSheet; // true if the window is a sheet (Mac OS X)
@ -167,10 +165,6 @@ protected:
auto_ptr<nsMacEventHandler> mMacEventHandler;
nsIWidget *mOffsetParent;
#if !TARGET_CARBON
ControlHandle mPhantomScrollbar; // a native scrollbar for the scrollwheel
PhantomScrollbarData* mPhantomScrollbarData;
#endif
};
#endif // MacWindow_h__

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

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

@ -1,174 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsMenu_h__
#define nsMenu_h__
#include "nsCOMPtr.h"
#include "nsIMenu.h"
#include "nsSupportsArray.h"
#include "nsIMenuListener.h"
#include "nsIChangeManager.h"
#include "nsWeakReference.h"
#include <Menus.h>
#include <UnicodeConverter.h>
class nsIMenuBar;
class nsIMenuListener;
// temporary hack to get apple menu -- sfraser, approved saari
#define APPLE_MENU_HACK 1
#ifdef APPLE_MENU_HACK
extern const PRInt16 kMacMenuID;
extern const PRInt16 kAppleMenuID;
#endif /* APPLE_MENU_HACK */
//static PRInt16 mMacMenuIDCount; // use GetUniqueMenuID()
extern PRInt16 mMacMenuIDCount;// = kMacMenuID;
class nsMenu : public nsIMenu,
public nsIMenuListener,
public nsIChangeObserver,
public nsSupportsWeakReference
{
public:
nsMenu();
virtual ~nsMenu();
NS_DECL_ISUPPORTS
NS_DECL_NSICHANGEOBSERVER
// nsIMenuListener methods
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow,
void* unused, void * aDocShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
nsEventStatus CheckRebuild(PRBool & aMenuEvent);
nsEventStatus SetRebuild(PRBool aMenuEvent);
// nsIMenu Methods
NS_IMETHOD Create ( nsISupports * aParent, const nsAString &aLabel, const nsAString &aAccessKey,
nsIChangeManager* aManager, nsIDocShell* aShell, nsIContent* aNode ) ;
NS_IMETHOD GetParent(nsISupports *&aParent);
NS_IMETHOD GetLabel(nsString &aText);
NS_IMETHOD SetLabel(const nsAString &aText);
NS_IMETHOD GetAccessKey(nsString &aText);
NS_IMETHOD SetAccessKey(const nsAString &aText);
NS_IMETHOD AddItem(nsISupports* aText);
NS_IMETHOD AddSeparator();
NS_IMETHOD GetItemCount(PRUint32 &aCount);
NS_IMETHOD GetItemAt(const PRUint32 aPos, nsISupports *& aMenuItem);
NS_IMETHOD InsertItemAt(const PRUint32 aPos, nsISupports * aMenuItem);
NS_IMETHOD RemoveItem(const PRUint32 aPos);
NS_IMETHOD RemoveAll();
NS_IMETHOD GetNativeData(void** aData);
NS_IMETHOD SetNativeData(void* aData);
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD GetMenuContent(nsIContent ** aMenuNode);
NS_IMETHOD SetEnabled(PRBool aIsEnabled);
NS_IMETHOD GetEnabled(PRBool* aIsEnabled);
NS_IMETHOD IsHelpMenu(PRBool* aIsEnabled);
//
NS_IMETHOD AddMenuItem(nsIMenuItem * aMenuItem);
NS_IMETHOD AddMenu(nsIMenu * aMenu);
// MacSpecific
static PRInt16 GetUniqueMenuID()
{
if (mMacMenuIDCount == 32767)
mMacMenuIDCount = 256;
return mMacMenuIDCount++;
}
protected:
nsString mLabel;
PRUint32 mNumMenuItems;
nsSupportsArray mMenuItemsArray; // array holds refs
nsISupports* mParent; // weak, my parent owns me
nsIChangeManager* mManager; // weak ref, it will outlive us
nsWeakPtr mDocShellWeakRef; // weak ref to docshell
nsCOMPtr<nsIContent> mMenuContent; // the |menu| tag, strong ref
nsCOMPtr<nsIMenuListener> mListener;
bool mConstructed;
// MacSpecific
PRInt16 mMacMenuID;
MenuHandle mMacMenuHandle;
UnicodeToTextRunInfo mUnicodeTextRunConverter;
PRInt16 mHelpMenuOSItemsCount;
PRPackedBool mIsHelpMenu;
PRPackedBool mIsEnabled;
PRPackedBool mDestroyHandlerCalled;
PRPackedBool mNeedsRebuild;
nsresult GetNextVisibleMenu(nsIMenu** outNextVisibleMenu);
// fetch the content node associated with the menupopup item
void GetMenuPopupContent ( nsIContent** aResult ) ;
PRBool IsSpecialHierarchicalMenu ( PRInt32 inMenuId ) ;
// fire handlers for oncreate/ondestroy
PRBool OnDestroy() ;
PRBool OnCreate() ;
PRBool OnDestroyed() ;
PRBool OnCreated() ;
void LoadMenuItem ( nsIMenu* pParentMenu, nsIContent* menuitemContent);
void LoadSubMenu( nsIMenu * pParentMenu, nsIContent* menuitemContent);
void LoadSeparator ( nsIContent* menuitemContent );
nsEventStatus HelpMenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow,
void* unused, void* aDocShell);
MenuHandle NSStringNewMenu(short menuID, nsString& menuTitle);
private:
};
#endif // nsMenu_h__

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

@ -1,902 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsIServiceManager.h"
#include "nsIComponentManager.h"
#include "nsINameSpaceManager.h"
#include "nsIMenu.h"
#include "nsIMenuItem.h"
#include "nsIContent.h"
#include "nsMenuBar.h"
#include "nsDynamicMDEF.h"
#include "nsISupports.h"
#include "nsIWidget.h"
#include "nsGUIEvent.h"
#include "nsString.h"
#include "nsIDocument.h"
#include "nsIDocShell.h"
#include "nsIDocumentViewer.h"
#include "nsIDocumentObserver.h"
#include "nsWidgetAtoms.h"
#include "nsIDOMDocument.h"
#include <Menus.h>
#include <TextUtils.h>
#include <Balloons.h>
#ifndef XP_MACOSX
#include <Traps.h>
#endif
#include <Resources.h>
#include <Appearance.h>
#include "nsMacResources.h"
#include "DefProcFakery.h"
Handle gMDEF = nsnull;
nsWeakPtr gMacMenubar;
nsWeakPtr gOriginalMenuBar;
bool gFirstMenuBar = true;
// The four Golden Hierarchical Child Menus
MenuHandle gLevel2HierMenu = nsnull;
MenuHandle gLevel3HierMenu = nsnull;
MenuHandle gLevel4HierMenu = nsnull;
MenuHandle gLevel5HierMenu = nsnull;
extern nsMenuStack gPreviousMenuStack;
extern PRInt16 gCurrentMenuDepth;
// #if APPLE_MENU_HACK
#include "nsMenu.h" // need to get APPLE_MENU_HACK macro
// #endif
// CIDs
#include "nsWidgetsCID.h"
static NS_DEFINE_CID(kMenuCID, NS_MENU_CID);
void InstallDefProc( short dpPath, ResType dpType, short dpID, Ptr dpAddr);
PRInt32 gMenuBarCounter = 0;
NS_IMPL_ISUPPORTS5(nsMenuBar, nsIMenuBar, nsIMenuListener, nsIDocumentObserver, nsIChangeManager, nsISupportsWeakReference)
//
// nsMenuBar constructor
//
nsMenuBar::nsMenuBar()
{
gCurrentMenuDepth = 1;
nsPreviousMenuStackUnwind(nsnull, nsnull);
mNumMenus = 0;
mParent = nsnull;
mIsMenuBarAdded = PR_FALSE;
mUnicodeTextRunConverter = nsnull;
mOriginalMacMBarHandle = nsnull;
mMacMBarHandle = nsnull;
mDocument = nsnull;
mOriginalMacMBarHandle = ::GetMenuBar();
Handle tmp = ::GetMenuBar();
::SetMenuBar(tmp);
this->SetNativeData((void*)tmp);
::ClearMenuBar();
mRefCnt = 1; // NS_GetWeakReference does an addref then a release, so this +1 is needed
gMacMenubar = do_GetWeakReference((nsIMenuBar *)this);
mRefCnt = 0;
// copy from nsMenu.cpp
ScriptCode ps[1];
ps[0] = ::GetScriptManagerVariable(smSysScript);
OSErr err = ::CreateUnicodeToTextRunInfoByScriptCode(0x80000000, ps, &mUnicodeTextRunConverter);
NS_ASSERTION(err==noErr,"nsMenu::nsMenu: CreateUnicodeToTextRunInfoByScriptCode failed.");
++gMenuBarCounter;
}
//
// nsMenuBar destructor
//
nsMenuBar::~nsMenuBar()
{
mMenusArray.Clear(); // release all menus
OSErr err = ::DisposeUnicodeToTextRunInfo(&mUnicodeTextRunConverter);
NS_ASSERTION(err==noErr,"nsMenu::~nsMenu: DisposeUnicodeToTextRunInfo failed.");
// make sure we unregister ourselves as a document observer
if ( mDocument ) {
nsCOMPtr<nsIDocumentObserver> observer ( do_QueryInterface(NS_STATIC_CAST(nsIMenuBar*,this)) );
mDocument->RemoveObserver(observer);
}
--gMenuBarCounter;
if(gMenuBarCounter == 1) {
nsCOMPtr<nsIMenuBar> menubar = do_QueryReferent(gOriginalMenuBar);
if(menubar)
menubar->Paint();
}
::DisposeHandle(mOriginalMacMBarHandle);
::DisposeHandle(mMacMBarHandle);
}
nsEventStatus
nsMenuBar::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
// Dispatch menu event
nsEventStatus eventStatus = nsEventStatus_eIgnore;
PRUint32 numItems;
mMenusArray.Count(&numItems);
for (PRUint32 i = numItems; i > 0; --i)
{
nsCOMPtr<nsISupports> menuSupports = getter_AddRefs(mMenusArray.ElementAt(i - 1));
nsCOMPtr<nsIMenuListener> menuListener = do_QueryInterface(menuSupports);
if(menuListener)
{
eventStatus = menuListener->MenuItemSelected(aMenuEvent);
if(nsEventStatus_eIgnore != eventStatus)
return eventStatus;
}
}
return eventStatus;
}
nsEventStatus
nsMenuBar::MenuSelected(const nsMenuEvent & aMenuEvent)
{
// Dispatch event
nsEventStatus eventStatus = nsEventStatus_eIgnore;
nsCOMPtr<nsIMenuListener> menuListener;
nsCOMPtr<nsIMenu> theMenu;
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(theMenu));
menuListener = do_QueryInterface(theMenu);
if (menuListener) {
//TODO: MenuSelected is the right thing to call...
//eventStatus = menuListener->MenuSelected(aMenuEvent);
eventStatus = menuListener->MenuItemSelected(aMenuEvent);
if (nsEventStatus_eIgnore != eventStatus)
return eventStatus;
} else {
// If it's the help menu, gPreviousMenuStack won't be accurate so we need to get the listener a different way
// We'll do it the old fashioned way of looping through and finding it
PRUint32 numItems;
mMenusArray.Count(&numItems);
for (PRUint32 i = numItems; i > 0; --i)
{
nsCOMPtr<nsISupports> menuSupports = getter_AddRefs(mMenusArray.ElementAt(i - 1));
nsCOMPtr<nsIMenuListener> thisListener = do_QueryInterface(menuSupports);
if (thisListener)
{
//TODO: MenuSelected is the right thing to call...
//eventStatus = menuListener->MenuSelected(aMenuEvent);
eventStatus = thisListener->MenuItemSelected(aMenuEvent);
if(nsEventStatus_eIgnore != eventStatus)
return eventStatus;
}
}
}
return eventStatus;
}
nsEventStatus
nsMenuBar::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
nsEventStatus
nsMenuBar::CheckRebuild(PRBool & aNeedsRebuild)
{
aNeedsRebuild = PR_TRUE;
return nsEventStatus_eIgnore;
}
nsEventStatus
nsMenuBar::SetRebuild(PRBool aNeedsRebuild)
{
return nsEventStatus_eIgnore;
}
void
nsMenuBar :: GetDocument ( nsIDocShell* inDocShell, nsIDocument** outDocument )
{
*outDocument = nsnull;
if ( inDocShell ) {
nsCOMPtr<nsIContentViewer> cv;
inDocShell->GetContentViewer(getter_AddRefs(cv));
if (cv) {
// get the document
nsCOMPtr<nsIDocumentViewer> docv(do_QueryInterface(cv));
if (!docv)
return;
docv->GetDocument(outDocument); // addrefs
}
}
}
//
// RegisterAsDocumentObserver
//
// Name says it all.
//
void
nsMenuBar :: RegisterAsDocumentObserver ( nsIDocShell* inDocShell )
{
nsCOMPtr<nsIDocument> doc;
GetDocument(inDocShell, getter_AddRefs(doc));
if (!doc)
return;
// register ourselves
nsCOMPtr<nsIDocumentObserver> observer ( do_QueryInterface(NS_STATIC_CAST(nsIMenuBar*,this)) );
doc->AddObserver(observer);
// also get pointer to doc, just in case docshell goes away
// we can still remove ourself as doc observer directly from doc
mDocument = doc;
} // RegisterAsDocumentObesrver
nsEventStatus
nsMenuBar::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWindow,
void * menubarNode, void * aDocShell )
{
mDocShellWeakRef = do_GetWeakReference(NS_STATIC_CAST(nsIDocShell*, aDocShell));
nsIDOMNode* aDOMNode = NS_STATIC_CAST(nsIDOMNode*, menubarNode);
mMenuBarContent = do_QueryInterface(aDOMNode); // strong ref
if(gFirstMenuBar) {
gOriginalMenuBar = do_GetWeakReference((nsIMenuBar *)this);
gFirstMenuBar = false;
// Add the 4 Golden Hierarchical Menus to the MenuList
MenuHandle macMenuHandle = ::NewMenu(2, "\psubmenu");
if(macMenuHandle) {
// get our fake MDEF ready to be stashed into every menu that comes our way.
// if we fail creating it, we're probably so doomed there's no point in going
// on.
if ( !gMDEF ) {
MenuDefUPP mdef = NewMenuDefProc( nsDynamicMDEFMain );
Boolean success = DefProcFakery::CreateDefProc( mdef, (**macMenuHandle).menuProc, &gMDEF );
if ( !success )
::ExitToShell();
}
gLevel2HierMenu = macMenuHandle;
(**macMenuHandle).menuProc = gMDEF;
(**macMenuHandle).menuWidth = -1;
(**macMenuHandle).menuHeight = -1;
::InsertMenu(macMenuHandle, hierMenu);
}
macMenuHandle = ::NewMenu(3, "\psubmenu");
if(macMenuHandle) {
gLevel3HierMenu = macMenuHandle;
(**macMenuHandle).menuProc = gMDEF;
(**macMenuHandle).menuWidth = -1;
(**macMenuHandle).menuHeight = -1;
::InsertMenu(macMenuHandle, hierMenu);
}
macMenuHandle = ::NewMenu(4, "\psubmenu");
if(macMenuHandle) {
gLevel4HierMenu = macMenuHandle;
(**macMenuHandle).menuProc = gMDEF;
(**macMenuHandle).menuWidth = -1;
(**macMenuHandle).menuHeight = -1;
::InsertMenu(macMenuHandle, hierMenu);
}
macMenuHandle = ::NewMenu(5, "\psubmenu");
if(macMenuHandle) {
gLevel5HierMenu = macMenuHandle;
(**macMenuHandle).menuProc = gMDEF;
(**macMenuHandle).menuWidth = -1;
(**macMenuHandle).menuHeight = -1;
::InsertMenu(macMenuHandle, hierMenu);
}
} else {
::InsertMenu(gLevel2HierMenu, hierMenu);
::InsertMenu(gLevel3HierMenu, hierMenu);
::InsertMenu(gLevel4HierMenu, hierMenu);
::InsertMenu(gLevel5HierMenu, hierMenu);
}
Create(aParentWindow);
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocShellWeakRef);
if (docShell)
RegisterAsDocumentObserver(docShell);
// set this as a nsMenuListener on aParentWindow
aParentWindow->AddMenuListener((nsIMenuListener *)this);
PRUint32 count = mMenuBarContent->GetChildCount();
for ( PRUint32 i = 0; i < count; ++i ) {
nsIContent *menu = mMenuBarContent->GetChildAt(i);
if ( menu ) {
if (menu->Tag() == nsWidgetAtoms::menu &&
menu->IsContentOfType(nsIContent::eXUL)) {
nsAutoString menuName;
nsAutoString menuAccessKey(NS_LITERAL_STRING(" "));
menu->GetAttr(kNameSpaceID_None, nsWidgetAtoms::label, menuName);
menu->GetAttr(kNameSpaceID_None, nsWidgetAtoms::accesskey, menuAccessKey);
// Don't create the whole menu yet, just add in the top level names
// Create nsMenu, the menubar will own it
nsCOMPtr<nsIMenu> pnsMenu ( do_CreateInstance(kMenuCID) );
if ( pnsMenu ) {
pnsMenu->Create(NS_STATIC_CAST(nsIMenuBar*, this), menuName, menuAccessKey,
NS_STATIC_CAST(nsIChangeManager *, this),
NS_REINTERPRET_CAST(nsIDocShell*, aDocShell), menu);
// Make nsMenu a child of nsMenuBar. nsMenuBar takes ownership
AddMenu(pnsMenu);
nsAutoString menuIDstring;
menu->GetAttr(kNameSpaceID_None, nsWidgetAtoms::id, menuIDstring);
if ( menuIDstring.EqualsLiteral("menu_Help") ) {
nsMenuEvent event;
MenuHandle handle = nsnull;
::HMGetHelpMenuHandle(&handle);
event.mCommand = (unsigned int) handle;
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(pnsMenu));
listener->MenuSelected(event);
}
}
}
}
} // for each menu
// Give the aParentWindow this nsMenuBar to hold onto.
// The parent takes ownership
aParentWindow->SetMenuBar(this);
Handle tempMenuBar = ::GetMenuBar(); // Get a copy of the menu list
SetNativeData((void*)tempMenuBar);
return nsEventStatus_eIgnore;
}
nsEventStatus
nsMenuBar::MenuDestruct(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
//
// Create the proper widget
//
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::Create(nsIWidget *aParent)
{
SetParent(aParent);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::GetParent(nsIWidget *&aParent)
{
NS_IF_ADDREF(aParent = mParent);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::SetParent(nsIWidget *aParent)
{
mParent = aParent; // weak ref
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::AddMenu(nsIMenu * aMenu)
{
// XXX add to internal data structure
nsCOMPtr<nsISupports> supports = do_QueryInterface(aMenu);
if(supports)
mMenusArray.AppendElement(supports); // owner
#ifdef APPLE_MENU_HACK
if (mNumMenus == 0)
{
Str32 menuStr = { 1, 0x14 };
MenuHandle appleMenu = ::NewMenu(kAppleMenuID, menuStr);
if (appleMenu)
{
// this code reads the "label" attribute from the <menuitem/> with
// id="aboutName" and puts its label in the Apple Menu
nsAutoString label;
nsCOMPtr<nsIContent> menu;
aMenu->GetMenuContent(getter_AddRefs(menu));
if (menu) {
nsCOMPtr<nsIDocument> doc = menu->GetDocument();
if (doc) {
nsCOMPtr<nsIDOMDocument> domdoc ( do_QueryInterface(doc) );
if ( domdoc ) {
nsCOMPtr<nsIDOMElement> aboutMenuItem;
domdoc->GetElementById(NS_LITERAL_STRING("aboutName"), getter_AddRefs(aboutMenuItem));
if (aboutMenuItem)
aboutMenuItem->GetAttribute(NS_LITERAL_STRING("label"), label);
}
}
}
::AppendMenu(appleMenu, "\pa");
MenuHelpers::SetMenuItemText(appleMenu, 1, label, mUnicodeTextRunConverter);
::AppendMenu(appleMenu, "\p-");
::AppendResMenu(appleMenu, 'DRVR');
::InsertMenu(appleMenu, 0);
}
}
#endif
MenuHandle menuHandle = nsnull;
aMenu->GetNativeData((void**)&menuHandle);
mNumMenus++;
PRBool helpMenu;
aMenu->IsHelpMenu(&helpMenu);
if(!helpMenu) {
nsCOMPtr<nsIContent> menu;
aMenu->GetMenuContent(getter_AddRefs(menu));
nsAutoString menuHidden;
menu->GetAttr(kNameSpaceID_None, nsWidgetAtoms::hidden, menuHidden);
if( !menuHidden.EqualsLiteral("true"))
::InsertMenu(menuHandle, 0);
}
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::GetMenuCount(PRUint32 &aCount)
{
aCount = mNumMenus;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::GetMenuAt(const PRUint32 aCount, nsIMenu *& aMenu)
{
aMenu = NULL;
nsCOMPtr<nsISupports> supports = getter_AddRefs(mMenusArray.ElementAt(aCount));
if (!supports) return NS_OK;
return CallQueryInterface(supports, &aMenu); // addref
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::InsertMenuAt(const PRUint32 aCount, nsIMenu *& aMenu)
{
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::RemoveMenu(const PRUint32 aCount)
{
mMenusArray.RemoveElementAt(aCount);
::DrawMenuBar();
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::RemoveAll()
{
NS_ASSERTION(0, "Not implemented!");
// mMenusArray.Clear(); // maybe?
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::GetNativeData(void *& aData)
{
aData = (void *) mMacMBarHandle;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::SetNativeData(void* aData)
{
Handle menubarHandle = (Handle)aData;
if(mMacMBarHandle && mMacMBarHandle != menubarHandle)
::DisposeHandle(mMacMBarHandle);
mMacMBarHandle = menubarHandle;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuBar::Paint()
{
gMacMenubar = do_GetWeakReference((nsIMenuBar *)this);
::SetMenuBar(mMacMBarHandle);
// Now we have blown away the merged Help menu, so we have to rebuild it
PRUint32 numItems;
mMenusArray.Count(&numItems);
for (PRInt32 i = numItems - 1; i >= 0; --i)
{
nsCOMPtr<nsISupports> thisItem = getter_AddRefs(mMenusArray.ElementAt(i));
nsCOMPtr<nsIMenu> menu = do_QueryInterface(thisItem);
PRBool isHelpMenu = PR_FALSE;
if (menu)
menu->IsHelpMenu(&isHelpMenu);
if (isHelpMenu)
{
MenuHandle helpMenuHandle = nil;
::HMGetHelpMenuHandle(&helpMenuHandle);
menu->SetNativeData((void*)helpMenuHandle);
nsMenuEvent event;
event.mCommand = (unsigned int) helpMenuHandle;
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(menu);
listener->MenuSelected(event);
}
}
::DrawMenuBar();
return NS_OK;
}
#pragma mark -
//
// nsIDocumentObserver
// this is needed for menubar changes
//
NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(nsMenuBar)
NS_IMPL_NSIDOCUMENTOBSERVER_REFLOW_STUB(nsMenuBar)
NS_IMPL_NSIDOCUMENTOBSERVER_STATE_STUB(nsMenuBar)
NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(nsMenuBar)
NS_IMETHODIMP
nsMenuBar::BeginUpdate( nsIDocument * aDocument, nsUpdateType aUpdateType )
{
return NS_OK;
}
NS_IMETHODIMP
nsMenuBar::EndUpdate( nsIDocument * aDocument, nsUpdateType aUpdateType )
{
return NS_OK;
}
NS_IMETHODIMP
nsMenuBar::CharacterDataChanged( nsIDocument * aDocument, nsIContent * aContent, PRBool aAppend)
{
return NS_OK;
}
NS_IMETHODIMP
nsMenuBar::ContentAppended( nsIDocument * aDocument, nsIContent * aContainer,
PRInt32 aNewIndexInContainer)
{
if ( aContainer == mMenuBarContent ) {
//Register(aContainer, );
//InsertMenu ( aNewIndexInContainer );
}
else {
nsCOMPtr<nsIChangeObserver> obs;
Lookup ( aContainer, getter_AddRefs(obs) );
if ( obs )
obs->ContentInserted ( aDocument, aContainer, aNewIndexInContainer );
else {
nsCOMPtr<nsIContent> parent = aContainer->GetParent();
if(parent) {
Lookup ( parent, getter_AddRefs(obs) );
if ( obs )
obs->ContentInserted ( aDocument, aContainer, aNewIndexInContainer );
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsMenuBar::DocumentWillBeDestroyed( nsIDocument * aDocument )
{
mDocument = nsnull; // just for yucks
return NS_OK;
}
NS_IMETHODIMP
nsMenuBar::AttributeChanged( nsIDocument * aDocument, nsIContent * aContent, PRInt32 aNameSpaceID,
nsIAtom * aAttribute, PRInt32 aModType )
{
// lookup and dispatch to registered thang.
nsCOMPtr<nsIChangeObserver> obs;
Lookup ( aContent, getter_AddRefs(obs) );
if ( obs )
obs->AttributeChanged ( aDocument, aNameSpaceID, aAttribute );
return NS_OK;
}
NS_IMETHODIMP
nsMenuBar::ContentRemoved( nsIDocument * aDocument, nsIContent * aContainer,
nsIContent * aChild, PRInt32 aIndexInContainer )
{
if ( aContainer == mMenuBarContent ) {
Unregister(aChild);
RemoveMenu ( aIndexInContainer );
}
else {
nsCOMPtr<nsIChangeObserver> obs;
Lookup ( aContainer, getter_AddRefs(obs) );
if ( obs )
obs->ContentRemoved ( aDocument, aChild, aIndexInContainer );
else {
nsCOMPtr<nsIContent> parent = aContainer->GetParent();
if(parent) {
Lookup ( parent, getter_AddRefs(obs) );
if ( obs )
obs->ContentRemoved ( aDocument, aChild, aIndexInContainer );
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsMenuBar::ContentInserted( nsIDocument * aDocument, nsIContent * aContainer,
nsIContent * aChild, PRInt32 aIndexInContainer )
{
if ( aContainer == mMenuBarContent ) {
//Register(aChild, );
//InsertMenu ( aIndexInContainer );
}
else {
nsCOMPtr<nsIChangeObserver> obs;
Lookup ( aContainer, getter_AddRefs(obs) );
if ( obs )
obs->ContentInserted ( aDocument, aChild, aIndexInContainer );
else {
nsCOMPtr<nsIContent> parent = aContainer->GetParent();
if(parent) {
Lookup ( parent, getter_AddRefs(obs) );
if ( obs )
obs->ContentInserted ( aDocument, aChild, aIndexInContainer );
}
}
}
return NS_OK;
}
#pragma mark -
//
// nsIChangeManager
//
// We don't use a |nsSupportsHashtable| because we know that the lifetime of all these items
// is bouded by the lifetime of the menubar. No need to add any more strong refs to the
// picture because the containment hierarchy already uses strong refs.
//
NS_IMETHODIMP
nsMenuBar :: Register ( nsIContent *aContent, nsIChangeObserver *aMenuObject )
{
nsVoidKey key ( aContent );
mObserverTable.Put ( &key, aMenuObject );
return NS_OK;
}
NS_IMETHODIMP
nsMenuBar :: Unregister ( nsIContent *aContent )
{
nsVoidKey key ( aContent );
mObserverTable.Remove ( &key );
return NS_OK;
}
NS_IMETHODIMP
nsMenuBar :: Lookup ( nsIContent *aContent, nsIChangeObserver **_retval )
{
*_retval = nsnull;
nsVoidKey key ( aContent );
*_retval = NS_REINTERPRET_CAST(nsIChangeObserver*, mObserverTable.Get(&key));
NS_IF_ADDREF ( *_retval );
return NS_OK;
}
#pragma mark -
//
// SetMenuItemText
//
// A utility routine for handling unicode->OS text conversions for setting the item
// text in a menu.
//
void
MenuHelpers :: SetMenuItemText ( MenuHandle inMacMenuHandle, short inMenuItem, const nsString& inMenuString,
const UnicodeToTextRunInfo inConverter )
{
// ::TruncString() doesn't take the number of characters to truncate to, it takes a pixel with
// to fit the string in. Ugh. I talked it over with sfraser and we couldn't come up with an
// easy way to compute what this should be given the system font, etc, so we're just going
// to hard code it to something reasonable and bigger fonts will just have to deal.
const short kMaxItemPixelWidth = 300;
short themeFontID;
SInt16 themeFontSize;
Style themeFontStyle;
char* scriptRunText = ConvertToScriptRun ( inMenuString, inConverter, &themeFontID,
&themeFontSize, &themeFontStyle );
if ( scriptRunText ) {
// convert it to a pascal string
Str255 menuTitle;
short scriptRunTextLength = strlen(scriptRunText);
if (scriptRunTextLength > 255)
scriptRunTextLength = 255;
BlockMoveData(scriptRunText, &menuTitle[1], scriptRunTextLength);
menuTitle[0] = scriptRunTextLength;
// if the item text is too long, truncate it.
::TruncString ( kMaxItemPixelWidth, menuTitle, truncMiddle );
::SetMenuItemText(inMacMenuHandle, inMenuItem, menuTitle);
OSErr err = ::SetMenuItemFontID(inMacMenuHandle, inMenuItem, themeFontID);
nsMemory::Free(scriptRunText);
}
} // SetMenuItemText
//
// ConvertToScriptRun
//
// Converts unicode to a single script run and extract the relevant font information. The
// caller is responsible for deleting the memory allocated by this call with |nsMemory::Free()|.
// Returns |nsnull| if an error occurred.
//
char*
MenuHelpers :: ConvertToScriptRun ( const nsString & inStr, const UnicodeToTextRunInfo inConverter,
short* outFontID, SInt16* outFontSize, Style* outFontStyle )
{
//
// extract the Unicode text from the nsString and convert it into a single script run
//
const PRUnichar* unicodeText = inStr.get();
size_t unicodeTextLengthInBytes = inStr.Length() * sizeof(PRUnichar);
size_t scriptRunTextSizeInBytes = unicodeTextLengthInBytes * 2;
char* scriptRunText = NS_REINTERPRET_CAST(char*, nsMemory::Alloc(scriptRunTextSizeInBytes + sizeof(char)));
if ( !scriptRunText )
return nsnull;
ScriptCodeRun convertedTextScript;
size_t unicdeTextReadInBytes, scriptRunTextLengthInBytes, scriptCodeRunListLength;
OSErr err = ::ConvertFromUnicodeToScriptCodeRun(inConverter, unicodeTextLengthInBytes,
NS_REINTERPRET_CAST(const PRUint16*, unicodeText),
0, /* no flags*/
0,NULL,NULL,NULL, /* no offset arrays */
scriptRunTextSizeInBytes,&unicdeTextReadInBytes,&scriptRunTextLengthInBytes,
scriptRunText,
1 /* count of script runs*/,&scriptCodeRunListLength,&convertedTextScript);
NS_ASSERTION(err==noErr,"nsMenu::NSStringSetMenuItemText: ConvertFromUnicodeToScriptCodeRun failed.");
if ( err ) { nsMemory::Free(scriptRunText); return nsnull; }
scriptRunText[scriptRunTextLengthInBytes] = '\0'; // null terminate
//
// get a font from the script code
//
Str255 themeFontName;
err = ::GetThemeFont(kThemeSystemFont, convertedTextScript.script, themeFontName, outFontSize, outFontStyle);
NS_ASSERTION(err==noErr,"nsMenu::NSStringSetMenuItemText: GetThemeFont failed.");
if ( err ) { nsMemory::Free(scriptRunText); return nsnull; }
::GetFNum(themeFontName, outFontID);
return scriptRunText;
} // ConvertToScriptRun
//
// DocShellToPresContext
//
// Helper to dig out a pres context from a docshell. A common thing to do before
// sending an event into the dom.
//
nsresult
MenuHelpers :: DocShellToPresContext (nsIDocShell* inDocShell, nsPresContext** outContext )
{
NS_ENSURE_ARG_POINTER(outContext);
*outContext = nsnull;
if (!inDocShell)
return NS_ERROR_INVALID_ARG;
nsresult retval = NS_OK;
nsCOMPtr<nsIContentViewer> contentViewer;
inDocShell->GetContentViewer(getter_AddRefs(contentViewer));
if ( contentViewer ) {
nsCOMPtr<nsIDocumentViewer> docViewer ( do_QueryInterface(contentViewer) );
if ( docViewer )
docViewer->GetPresContext(*outContext); // AddRefs for us
else
retval = NS_ERROR_FAILURE;
}
else
retval = NS_ERROR_FAILURE;
return retval;
} // DocShellToPresContext

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

@ -1,149 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsMenuBar_h__
#define nsMenuBar_h__
#include "nsIMenuBar.h"
#include "nsIMenuListener.h"
#include "nsIDocumentObserver.h"
#include "nsIChangeManager.h"
#include "nsPresContext.h"
#include "nsSupportsArray.h"
#include "nsVoidArray.h"
#include "nsHashtable.h"
#include "nsWeakReference.h"
#include <MacTypes.h>
#include <UnicodeConverter.h>
extern nsWeakPtr gMacMenubar;
class nsIWidget;
class nsIDocument;
namespace MenuHelpers
{
// utility routine for getting a PresContext out of a docShell
nsresult DocShellToPresContext ( nsIDocShell* inDocShell, nsPresContext** outContext ) ;
// utility routine for handling unicode->OS text conversions for setting the item
// text in a menu.
void SetMenuItemText ( MenuHandle macMenuHandle, short menuItem, const nsString& text,
const UnicodeToTextRunInfo converter ) ;
// Converts unicode to a single script run and extract the relevant font information. The
// caller is responsible for deleting the memory allocated by this call with |nsMemory::Free()|.
// Returns |nsnull| if an error occurred.
char* ConvertToScriptRun ( const nsString & inStr, const UnicodeToTextRunInfo inConverter,
short* outFontID, SInt16* outFontSize, Style* outFontStyle ) ;
}
/**
* Native Mac MenuBar wrapper
*/
class nsMenuBar : public nsIMenuBar,
public nsIMenuListener,
public nsIDocumentObserver,
public nsIChangeManager,
public nsSupportsWeakReference
{
public:
nsMenuBar();
virtual ~nsMenuBar();
NS_DECL_ISUPPORTS
NS_DECL_NSICHANGEMANAGER
// nsIMenuListener interface
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow,
void* aDOMNode, void * aDocShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
nsEventStatus CheckRebuild(PRBool & aMenuEvent);
nsEventStatus SetRebuild(PRBool aMenuEvent);
// nsIDocumentObserver
NS_DECL_NSIDOCUMENTOBSERVER
NS_IMETHOD Create(nsIWidget * aParent);
// nsIMenuBar Methods
NS_IMETHOD GetParent(nsIWidget *&aParent);
NS_IMETHOD SetParent(nsIWidget * aParent);
NS_IMETHOD AddMenu(nsIMenu * aMenu);
NS_IMETHOD GetMenuCount(PRUint32 &aCount);
NS_IMETHOD GetMenuAt(const PRUint32 aCount, nsIMenu *& aMenu);
NS_IMETHOD InsertMenuAt(const PRUint32 aCount, nsIMenu *& aMenu);
NS_IMETHOD RemoveMenu(const PRUint32 aCount);
NS_IMETHOD RemoveAll();
NS_IMETHOD GetNativeData(void*& aData);
NS_IMETHOD Paint();
NS_IMETHOD SetNativeData(void* aData);
protected:
void GetDocument ( nsIDocShell* inDocShell, nsIDocument** outDocument ) ;
void RegisterAsDocumentObserver ( nsIDocShell* inDocShell ) ;
nsHashtable mObserverTable; // stores observers for content change notification
PRUint32 mNumMenus;
nsSupportsArray mMenusArray; // holds refs
nsCOMPtr<nsIContent> mMenuBarContent; // menubar content node, strong ref
nsIWidget * mParent; // weak ref
PRBool mIsMenuBarAdded;
nsWeakPtr mDocShellWeakRef; // weak ref to docshell
nsIDocument * mDocument; // pointer to doc
// Mac Specific
Handle mMacMBarHandle;
Handle mOriginalMacMBarHandle;
UnicodeToTextRunInfo mUnicodeTextRunConverter;
};
#endif // nsMenuBar_h__

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

@ -45,7 +45,6 @@
#include "nsMenuBarX.h"
#include "nsMenuX.h"
#include "nsDynamicMDEF.h"
#include "nsISupports.h"
#include "nsIWidget.h"
@ -65,6 +64,7 @@
#include <Resources.h>
#include <Appearance.h>
#include <Gestalt.h>
#include "nsMacResources.h"
#include "nsGUIEvent.h"
@ -148,11 +148,6 @@ nsMenuBarX::MenuSelected(const nsMenuEvent & aMenuEvent)
nsCOMPtr<nsIMenuListener> menuListener;
//((nsISupports*)mMenuVoidArray[i-1])->QueryInterface(NS_GET_IID(nsIMenuListener), (void**)&menuListener);
//printf("gPreviousMenuStack.Count() = %d \n", gPreviousMenuStack.Count());
#if !TARGET_CARBON
nsCOMPtr<nsIMenu> theMenu;
gPreviousMenuStack.GetMenuAt(gPreviousMenuStack.Count() - 1, getter_AddRefs(theMenu));
menuListener = do_QueryInterface(theMenu);
#endif
if (menuListener) {
//TODO: MenuSelected is the right thing to call...
//eventStatus = menuListener->MenuSelected(aMenuEvent);
@ -499,9 +494,6 @@ nsMenuBarX::MenuConstruct( const nsMenuEvent & aMenuEvent, nsIWidget* aParentWin
if ( menuIDstring.EqualsLiteral("menu_Help") ) {
nsMenuEvent event;
MenuHandle handle = nsnull;
#if !TARGET_CARBON
::HMGetHelpMenuHandle(&handle);
#endif
event.mCommand = (unsigned int) handle;
nsCOMPtr<nsIMenuListener> listener(do_QueryInterface(pnsMenu));
listener->MenuSelected(event);

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

@ -1,435 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCOMPtr.h"
#include "nsIDocumentViewer.h"
#include "nsIContent.h"
#include "nsPresContext.h"
#include "nsMenuBar.h" // for MenuHelpers namespace
#include "nsMenuItem.h"
#include "nsIMenu.h"
#include "nsIMenuBar.h"
#include "nsIWidget.h"
#include "nsIMenuListener.h"
#include "nsDynamicMDEF.h"
#include "nsGUIEvent.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsINameSpaceManager.h"
#include "nsWidgetAtoms.h"
#include "nsIServiceManager.h"
#if DEBUG
nsInstanceCounter gMenuItemCounter("nsMenuItem");
#endif
NS_IMPL_ISUPPORTS4(nsMenuItem, nsIMenuItem, nsIMenuListener, nsIChangeObserver, nsISupportsWeakReference)
//
// nsMenuItem constructor
//
nsMenuItem::nsMenuItem()
{
mMenuParent = nsnull;
mIsSeparator = PR_FALSE;
mKeyEquivalent.AssignLiteral(" ");
mEnabled = PR_TRUE;
mIsChecked = PR_FALSE;
mMenuType = eRegular;
#if DEBUG
++gMenuItemCounter;
#endif
}
//
// nsMenuItem destructor
//
nsMenuItem::~nsMenuItem()
{
mManager->Unregister(mContent);
#if DEBUG
--gMenuItemCounter;
#endif
}
NS_METHOD nsMenuItem::Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator,
EMenuItemType aItemType, PRBool aEnabled,
nsIChangeManager* aManager, nsIDocShell* aShell, nsIContent* aNode )
{
mContent = aNode; // addref
mMenuParent = aParent; // weak
mDocShellWeakRef = do_GetWeakReference(aShell);
mEnabled = aEnabled;
mMenuType = aItemType;
// register for AttributeChanged messages
mManager = aManager;
nsCOMPtr<nsIChangeObserver> obs = do_QueryInterface(NS_STATIC_CAST(nsIChangeObserver*,this));
mManager->Register(mContent, obs); // does not addref this
mIsSeparator = aIsSeparator;
mLabel = aLabel;
return NS_OK;
}
NS_METHOD
nsMenuItem::GetLabel(nsString &aText)
{
aText = mLabel;
return NS_OK;
}
NS_METHOD
nsMenuItem::GetEnabled(PRBool *aIsEnabled)
{
*aIsEnabled = mEnabled;
return NS_OK;
}
NS_METHOD nsMenuItem::SetChecked(PRBool aIsEnabled)
{
mIsChecked = aIsEnabled;
// update the content model. This will also handle unchecking our siblings
// if we are a radiomenu
mContent->SetAttr(kNameSpaceID_None, nsWidgetAtoms::checked,
mIsChecked ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false"), PR_TRUE);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetChecked(PRBool *aIsEnabled)
{
*aIsEnabled = mIsChecked;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetMenuItemType(EMenuItemType *aType)
{
*aType = mMenuType;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetTarget(nsIWidget *& aTarget)
{
NS_IF_ADDREF(aTarget = mTarget);
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetNativeData(void *& aData)
{
//aData = (void *)mMenu;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::AddMenuListener(nsIMenuListener * aMenuListener)
{
mXULCommandListener = aMenuListener; // addref
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::RemoveMenuListener(nsIMenuListener * aMenuListener)
{
if (mXULCommandListener.get() == aMenuListener)
mXULCommandListener = nsnull;
return NS_OK;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::IsSeparator(PRBool & aIsSep)
{
aIsSep = mIsSeparator;
return NS_OK;
}
//-------------------------------------------------------------------------
// nsIMenuListener interface
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::MenuItemSelected(const nsMenuEvent & aMenuEvent)
{
switch ( mMenuType ) {
case eCheckbox:
SetChecked(!mIsChecked);
break;
case eRadio:
{
// we only want to muck with things if we were selected and we're not
// already checked.
if ( mIsChecked )
break;
SetChecked(PR_TRUE);
break;
}
case eRegular:
break; // do nothing special
} // which menu type
DoCommand();
return nsEventStatus_eConsumeNoDefault;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::MenuSelected(const nsMenuEvent & aMenuEvent)
{
//if(mXULCommandListener)
// return mXULCommandListener->MenuSelected(aMenuEvent);
DoCommand();
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
// nsIMenuListener interface
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::MenuDeselected(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::MenuConstruct(
const nsMenuEvent & aMenuEvent,
nsIWidget * aParentWindow,
void * menuNode,
void * aDocShell)
{
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::MenuDestruct(const nsMenuEvent & aMenuEvent)
{
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::CheckRebuild(PRBool & aNeedsRebuild)
{
aNeedsRebuild = PR_TRUE;
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
nsEventStatus nsMenuItem::SetRebuild(PRBool aNeedsRebuild)
{
//mNeedsRebuild = aNeedsRebuild;
return nsEventStatus_eIgnore;
}
//-------------------------------------------------------------------------
/**
* Executes the "cached" JavaScript Command
* @return NS_OK if the command was executed properly, otherwise an error code
*/
NS_METHOD nsMenuItem::DoCommand()
{
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr<nsPresContext> presContext;
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocShellWeakRef);
if (!docShell)
return nsEventStatus_eConsumeNoDefault;
MenuHelpers::DocShellToPresContext(docShell, getter_AddRefs(presContext));
nsEventStatus status = nsEventStatus_eIgnore;
nsMouseEvent event;
event.eventStructType = NS_MOUSE_EVENT;
event.message = NS_XUL_COMMAND;
// See if we have a command element. If so, we execute on the command instead
// of on our content element.
nsAutoString command;
mContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::command, command);
if (!command.IsEmpty()) {
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(mContent->GetDocument()));
nsCOMPtr<nsIDOMElement> commandElt;
domDoc->GetElementById(command, getter_AddRefs(commandElt));
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
if (commandContent)
commandContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
}
else
mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
return nsEventStatus_eConsumeNoDefault;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetModifiers(PRUint8 * aModifiers)
{
nsresult res = NS_OK;
*aModifiers = mModifiers;
return res;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::SetModifiers(PRUint8 aModifiers)
{
nsresult res = NS_OK;
mModifiers = aModifiers;
return res;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::SetShortcutChar(const nsString &aText)
{
nsresult res = NS_OK;
mKeyEquivalent = aText;
return res;
}
//-------------------------------------------------------------------------
NS_METHOD nsMenuItem::GetShortcutChar(nsString &aText)
{
nsresult res = NS_OK;
aText = mKeyEquivalent;
return res;
}
//
// UncheckRadioSiblings
//
// walk the sibling list looking for nodes with the same name and
// uncheck them all.
//
void
nsMenuItem :: UncheckRadioSiblings ( nsIContent* inCheckedContent )
{
nsAutoString myGroupName;
inCheckedContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::name, myGroupName);
if ( ! myGroupName.Length() ) // no groupname, nothing to do
return;
nsCOMPtr<nsIContent> parent;
inCheckedContent->GetParent(getter_AddRefs(parent));
if ( !parent )
return;
// loop over siblings
PRUint32 count = parent->GetChildCount();
for ( PRUint32 i = 0; i < count; ++i ) {
nsIContent *sibling = parent->GetChildAt(i);
if ( sibling ) {
if ( sibling != inCheckedContent ) { // skip this node
// if the current sibling is in the same group, clear it
nsAutoString currGroupName;
sibling->GetAttr(kNameSpaceID_None, nsWidgetAtoms::name, currGroupName);
if ( currGroupName == myGroupName )
sibling->SetAttr(kNameSpaceID_None, nsWidgetAtoms::checked, NS_LITERAL_STRING("false"), PR_TRUE);
}
}
} // for each sibling
} // UncheckRadioSiblings
#pragma mark -
//
// nsIChangeObserver
//
NS_IMETHODIMP
nsMenuItem :: AttributeChanged ( nsIDocument *aDocument, PRInt32 aNameSpaceID, nsIAtom *aAttribute )
{
if (aAttribute == nsWidgetAtoms::checked) {
// if we're a radio menu, uncheck our sibling radio items. No need to
// do any of this if we're just a normal check menu.
if ( mMenuType == eRadio ) {
nsAutoString checked;
mContent->GetAttr(kNameSpaceID_None, nsWidgetAtoms::checked, checked);
if (checked.EqualsLiteral("true") )
UncheckRadioSiblings(mContent);
}
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE);
}
else if (aAttribute == nsWidgetAtoms::disabled || aAttribute == nsWidgetAtoms::hidden ||
aAttribute == nsWidgetAtoms::collapsed || aAttribute == nsWidgetAtoms::label ) {
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE);
}
return NS_OK;
} // AttributeChanged
NS_IMETHODIMP
nsMenuItem :: ContentRemoved(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
{
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE);
return NS_OK;
} // ContentRemoved
NS_IMETHODIMP
nsMenuItem :: ContentInserted(nsIDocument *aDocument, nsIContent *aChild, PRInt32 aIndexInContainer)
{
nsCOMPtr<nsIMenuListener> listener = do_QueryInterface(mMenuParent);
listener->SetRebuild(PR_TRUE);
return NS_OK;
} // ContentInserted

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

@ -1,123 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* 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 mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsMenuItem_h__
#define nsMenuItem_h__
#include "nsIMenuItem.h"
#include "nsString.h"
#include "nsIMenuListener.h"
#include "nsIChangeManager.h"
#include "nsWeakReference.h"
class nsIMenu;
class nsIWidget;
/**
* Native Motif MenuItem wrapper
*/
class nsMenuItem : public nsIMenuItem,
public nsIMenuListener,
public nsIChangeObserver,
public nsSupportsWeakReference
{
public:
nsMenuItem();
virtual ~nsMenuItem();
// nsISupports
NS_DECL_ISUPPORTS
NS_DECL_NSICHANGEOBSERVER
// nsIMenuItem Methods
NS_IMETHOD Create ( nsIMenu* aParent, const nsString & aLabel, PRBool aIsSeparator,
EMenuItemType aItemType, PRBool aEnabled,
nsIChangeManager* aManager, nsIDocShell* aShell, nsIContent* aNode ) ;
NS_IMETHOD GetLabel(nsString &aText);
NS_IMETHOD SetShortcutChar(const nsString &aText);
NS_IMETHOD GetShortcutChar(nsString &aText);
NS_IMETHOD GetEnabled(PRBool *aIsEnabled);
NS_IMETHOD SetChecked(PRBool aIsEnabled);
NS_IMETHOD GetChecked(PRBool *aIsEnabled);
NS_IMETHOD GetMenuItemType(EMenuItemType *aIsCheckbox);
NS_IMETHOD GetTarget(nsIWidget *& aTarget);
NS_IMETHOD GetNativeData(void*& aData);
NS_IMETHOD AddMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD RemoveMenuListener(nsIMenuListener * aMenuListener);
NS_IMETHOD IsSeparator(PRBool & aIsSep);
NS_IMETHOD DoCommand();
NS_IMETHOD SetModifiers(PRUint8 aModifiers);
NS_IMETHOD GetModifiers(PRUint8 * aModifiers);
// nsIMenuListener interface
nsEventStatus MenuItemSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuSelected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuDeselected(const nsMenuEvent & aMenuEvent);
nsEventStatus MenuConstruct(const nsMenuEvent & aMenuEvent, nsIWidget * aParentWindow,
void * menuNode, void * aDocShell);
nsEventStatus MenuDestruct(const nsMenuEvent & aMenuEvent);
nsEventStatus CheckRebuild(PRBool & aMenuEvent);
nsEventStatus SetRebuild(PRBool aMenuEvent);
protected:
void UncheckRadioSiblings ( nsIContent* inCheckedElement ) ;
nsString mLabel;
nsString mKeyEquivalent;
nsIMenu* mMenuParent; // weak, parent owns us
nsIChangeManager* mManager; // weak
nsCOMPtr<nsIWidget> mTarget; // never set?
nsCOMPtr<nsIMenuListener> mXULCommandListener;
nsWeakPtr mDocShellWeakRef; // weak ref to docshell
nsCOMPtr<nsIContent> mContent;
PRUint8 mModifiers;
PRPackedBool mIsSeparator;
PRPackedBool mEnabled;
PRPackedBool mIsChecked;
EMenuItemType mMenuType;
};
#endif // nsMenuItem_h__

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

@ -41,14 +41,16 @@
#include "nsPresContext.h"
#include "nsMenuBarX.h" // for MenuHelpers namespace
#include "nsMenuX.h"
#include "nsMenuItemX.h"
#include "nsWidgetAtoms.h"
#include "nsIMenu.h"
#include "nsIMenuBar.h"
#include "nsIWidget.h"
#include "nsIMenuListener.h"
#include "nsDynamicMDEF.h"
#include "nsINameSpaceManager.h"
#include "nsWidgetAtoms.h"
#include "nsIServiceManager.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"

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

@ -70,7 +70,6 @@
#include "nsGUIEvent.h"
#include "nsDynamicMDEF.h"
#include "nsCRT.h"

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

@ -57,6 +57,41 @@ class nsIMenuListener;
//static PRInt16 mMacMenuIDCount; // use GetUniqueMenuID()
extern PRInt16 mMacMenuIDCount;// = kMacMenuID;
#if DEBUG
// utility instance counter class
class nsInstanceCounter
{
public:
nsInstanceCounter(const char* inDesc)
: mInstanceCount(0)
, mDescription(inDesc)
{
}
~nsInstanceCounter()
{
printf("%s %ld\n", mDescription, mInstanceCount);
}
nsInstanceCounter& operator ++() // prefix
{
++ mInstanceCount;
return *this;
}
nsInstanceCounter& operator -- () // prefix
{
-- mInstanceCount;
return *this;
}
protected:
PRInt32 mInstanceCount;
const char* mDescription;
};
#endif
class nsMenuX : public nsIMenu,
public nsIMenuListener,

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

@ -36,11 +36,10 @@
* ***** END LICENSE BLOCK ***** */
#include <ControlDefinitions.h>
#include "nsNativeScrollbar.h"
#include "nsIDeviceContext.h"
#if TARGET_CARBON || (UNIVERSAL_INTERFACES_VERSION >= 0x0330)
#include <ControlDefinitions.h>
#endif
#include "nsWidgetAtoms.h"
#include "nsWatchTask.h"
@ -102,9 +101,9 @@ nsNativeScrollbar::nsNativeScrollbar()
, mContent(nsnull)
, mMediator(nsnull)
, mScrollbar(nsnull)
, mLineIncrement(0)
, mMaxValue(0)
, mVisibleImageSize(0)
, mLineIncrement(0)
, mMouseDownInScroll(PR_FALSE)
, mClickedPartCode(0)
{
@ -494,11 +493,7 @@ nsNativeScrollbar::GetNarrowSize(PRInt32* outSize)
if ( *outSize )
return NS_ERROR_FAILURE;
SInt32 width = 0;
#if TARGET_CARBON
::GetThemeMetric(kThemeMetricScrollBarWidth, &width);
#else
width = 16;
#endif
*outSize = width;
return NS_OK;
}

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

@ -51,10 +51,8 @@ nsresult CreateStylFromScriptRuns(ScriptCodeRun *scriptCodeRuns,
nsMemory::Alloc(scrpRecLen));
NS_ENSURE_TRUE(scrpRec, NS_ERROR_OUT_OF_MEMORY);
OSErr err = noErr;
#if TARGET_CARBON
OSErr err = noErr;
Str255 themeFontName;
#endif
SInt16 textSize;
Style textStyle;
short fontFamilyID;
@ -75,8 +73,7 @@ nsresult CreateStylFromScriptRuns(ScriptCodeRun *scriptCodeRuns,
scrpRec->scrpNStyles = scriptRunOutLen;
for (ItemCount i = 0; i < scriptRunOutLen; i++) {
scrpRec->scrpStyleTab[i].scrpStartChar = scriptCodeRuns[i].offset;
#if TARGET_CARBON
err = ::GetThemeFont(
kThemeApplicationFont,
scriptCodeRuns[i].script,
@ -87,15 +84,6 @@ nsresult CreateStylFromScriptRuns(ScriptCodeRun *scriptCodeRuns,
break;
::GetFNum(themeFontName, &fontFamilyID);
#else
// kThemeApplicationFont cannot be used on MacOS 9
// use script manager to get the application font instead
fontFamilyID = NS_STATIC_CAST(short,
::GetScriptVariable(scriptCodeRuns[i].script, smScriptAppFond));
textSize = NS_STATIC_CAST(SInt16,
::GetScriptVariable(scriptCodeRuns[i].script, smScriptAppFondSize));
textStyle = normal;
#endif
::TextFont(fontFamilyID);
::TextSize(textSize);

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

@ -41,14 +41,12 @@
#include <ToolUtils.h>
#include <Appearance.h>
#include <ControlDefinitions.h>
#include <memory>
using std::auto_ptr;
#if TARGET_CARBON || (UNIVERSAL_INTERFACES_VERSION >= 0x0330)
#include <ControlDefinitions.h>
#endif
NS_IMPL_ADDREF(nsTextWidget)
NS_IMPL_RELEASE(nsTextWidget)
@ -310,15 +308,10 @@ PRBool nsTextWidget::DispatchWindowEvent(nsGUIEvent &aEvent)
selectionLen + 1);
// copy it to the scrapMgr
#if TARGET_CARBON
::ClearCurrentScrap();
ScrapRef scrap;
::GetCurrentScrap(&scrap);
::PutScrapFlavor(scrap, 'TEXT', 0L /* ??? */, selectionLen, cRepOfSelection.get());
#else
::ZeroScrap();
::PutScrap ( selectionLen, 'TEXT', cRepOfSelection.get() );
#endif
// if we're cutting, remove the text from the widget
if ( menuItem == cmd_Cut ) {
unused = 0;
@ -335,7 +328,6 @@ PRBool nsTextWidget::DispatchWindowEvent(nsGUIEvent &aEvent)
{
long scrapOffset;
Handle scrapH = ::NewHandle(0);
#if TARGET_CARBON
ScrapRef scrap;
OSStatus err;
err = ::GetCurrentScrap(&scrap);
@ -344,10 +336,6 @@ PRBool nsTextWidget::DispatchWindowEvent(nsGUIEvent &aEvent)
// XXX uhh.. i don't think this is right..
long scrapLen = scrapOffset;
if ( scrapOffset > 0 )
#else
long scrapLen = ::GetScrap(scrapH, 'TEXT', &scrapOffset);
if (scrapLen > 0)
#endif
{
::HLock(scrapH);

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

@ -82,10 +82,6 @@ void nsMacNSPREventQueueHandler::StartPumping()
{
++mRefCnt;
NS_LOG_ADDREF(this, mRefCnt, "nsMacNSPREventQueueHandler", sizeof(*this));
#if !TARGET_CARBON
StartRepeating();
#endif
}
//-------------------------------------------------------------------------
@ -97,9 +93,6 @@ PRBool nsMacNSPREventQueueHandler::StopPumping()
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "nsMacNSPREventQueueHandler");
if (mRefCnt == 0) {
#if !TARGET_CARBON
StopRepeating();
#endif
return PR_TRUE;
}
}
@ -362,10 +355,6 @@ OSErr nsMacMemoryCushion::Init(Size bufferSize, Size reserveSize)
// make this purgable
::HPurge(mBufferHandle);
#if !TARGET_CARBON
::SetGrowZone(NewGrowZoneProc(GrowZoneProc));
#endif
return noErr;
}

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

@ -121,32 +121,6 @@ int nsToolkitBase::QuartzChangedCallback(const char* pref, void* data)
return NS_OK;
}
static CFBundleRef GetBundle(CFStringRef frameworkPath)
{
CFBundleRef bundle = NULL;
// Make a CFURLRef from the CFString representation of the bundle's path.
// See the Core Foundation URL Services chapter for details.
CFURLRef bundleURL = CFURLCreateWithFileSystemPath(NULL, frameworkPath, kCFURLPOSIXPathStyle, true);
if (bundleURL != NULL) {
bundle = CFBundleCreate(NULL, bundleURL);
if (bundle != NULL)
CFBundleLoadExecutable(bundle);
CFRelease(bundleURL);
}
return bundle;
}
static void* GetQDFunction(CFStringRef functionName)
{
static CFBundleRef systemBundle = GetBundle(CFSTR("/System/Library/Frameworks/ApplicationServices.framework"));
if (systemBundle)
return CFBundleGetFunctionPointerForName(systemBundle, functionName);
return NULL;
}
//
// SetupQuartzRendering
//
@ -155,7 +129,7 @@ static void* GetQDFunction(CFStringRef functionName)
//
void nsToolkitBase::SetupQuartzRendering()
{
// from Apple's technote, yet un-numbered.
// from Apple's technote at http://developer.apple.com/qa/qa2001/qa1193.html
#if UNIVERSAL_INTERFACES_VERSION <= 0x0400
enum {
kQDDontChangeFlags = 0xFFFFFFFF, // don't change anything
@ -167,37 +141,31 @@ void nsToolkitBase::SetupQuartzRendering()
#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.
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
if (!prefs)
return;
typedef UInt32 (*qd_procptr)(UInt32);
static qd_procptr SwapQDTextFlagsProc = (qd_procptr)GetQDFunction(CFSTR("SwapQDTextFlags"));
if (SwapQDTextFlagsProc)
{
nsCOMPtr<nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID);
if (!prefs)
return;
PRBool enableQuartz = PR_TRUE;
nsresult rv = prefs->GetBoolPref(kQuartzRenderingPref, &enableQuartz);
UInt32 oldFlags = SwapQDTextFlagsProc(kQDDontChangeFlags);
if (NS_FAILED(rv) || enableQuartz) {
SwapQDTextFlagsProc(oldFlags | kFlagsWeUse);
// the system defaults to not anti-aliasing small fonts, but some people
// think it looks better that way. If the pref is set, turn them on
PRBool antiAliasAllFontSizes = PR_FALSE;
rv = prefs->GetBoolPref(kAllFontSizesPref, &antiAliasAllFontSizes);
if (NS_SUCCEEDED(rv) && antiAliasAllFontSizes)
SetOutlinePreferred(true);
}
else
SwapQDTextFlagsProc(oldFlags & !kFlagsWeUse);
PRBool enableQuartz = PR_TRUE;
nsresult rv = prefs->GetBoolPref(kQuartzRenderingPref, &enableQuartz);
UInt32 oldFlags = QDSwapTextFlags(kQDDontChangeFlags);
if (NS_FAILED(rv) || enableQuartz) {
QDSwapTextFlags(oldFlags | kFlagsWeUse);
// the system defaults to not anti-aliasing small fonts, but some people
// think it looks better that way. If the pref is set, turn them on
PRBool antiAliasAllFontSizes = PR_FALSE;
rv = prefs->GetBoolPref(kAllFontSizesPref, &antiAliasAllFontSizes);
if (NS_SUCCEEDED(rv) && antiAliasAllFontSizes)
SetOutlinePreferred(true);
}
else
QDSwapTextFlags(oldFlags & !kFlagsWeUse);
}

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

@ -52,20 +52,14 @@
#include "nsFilePicker.h"
#include "nsNativeScrollbar.h"
#if TARGET_CARBON
#include "nsMenuBarX.h"
#include "nsMenuX.h"
#include "nsMenuItemX.h"
#define nsMenuBar nsMenuBarX
#define nsMenu nsMenuX
#define nsMenuItem nsMenuItemX
#else
#include "nsMenuBar.h"
#include "nsMenu.h"
#include "nsMenuItem.h"
#endif
#include "nsClipboard.h"
#include "nsClipboardHelper.h"

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

@ -104,13 +104,9 @@ static const int kSpinCursorFirstFrame = 200;
// Routines for iterating over the rects of a region. Carbon and pre-Carbon
// do this differently so provide a way to do both.
#if TARGET_CARBON
static RegionToRectsUPP sUpdateRectProc = nsnull;
static RegionToRectsUPP sAddRectToArrayProc = nsnull;
static RegionToRectsUPP sCountRectProc = nsnull;
#else
void EachRegionRect (RgnHandle r, void (* proc)(Rect *, void *), void* data) ;
#endif
#pragma mark -
@ -142,11 +138,9 @@ static Boolean caps_lock()
static void FlushCurPortBuffer()
{
#if TARGET_CARBON
CGrafPtr curPort;
::GetPort((GrafPtr*)&curPort);
::QDFlushPortBuffer(curPort, nil); // OK to call on 9/carbon (does nothing)
#endif
}
static void blinkRect(const Rect* r, PRBool isPaint)
@ -162,11 +156,8 @@ static void blinkRect(const Rect* r, PRBool isPaint)
if (isPaint)
{
Pattern grayPattern;
#if TARGET_CARBON
::GetQDGlobalsGray(&grayPattern);
#else
grayPattern = qd.gray;
#endif
::ForeColor(blackColor);
::BackColor(whiteColor);
@ -206,11 +197,8 @@ static void blinkRgn(RgnHandle rgn, PRBool isPaint)
if (isPaint)
{
Pattern grayPattern;
#if TARGET_CARBON
::GetQDGlobalsGray(&grayPattern);
#else
grayPattern = qd.gray;
#endif
::ForeColor(blackColor);
::BackColor(whiteColor);
@ -294,13 +282,11 @@ nsWindow::nsWindow() : nsBaseWidget() , nsDeleteObserved(this), nsIKBStateContro
AcceptFocusOnClick(PR_TRUE);
#if TARGET_CARBON
if ( !sUpdateRectProc ) {
sUpdateRectProc = NewRegionToRectsUPP ( PaintUpdateRectProc );
sAddRectToArrayProc = NewRegionToRectsUPP ( AddRectToArrayProc );
sCountRectProc = NewRegionToRectsUPP ( CountRectProc );
}
#endif
}
@ -1311,7 +1297,6 @@ NS_IMETHODIMP nsWindow::Update()
#pragma mark -
#if TARGET_CARBON
//
@ -1387,7 +1372,6 @@ nsWindow::CountRectProc (UInt16 message, RgnHandle rgn, const Rect *inDirtyRect,
}
#endif
//
// UpdateRect
@ -1511,12 +1495,10 @@ else
if (!::EmptyRgn(updateRgn))
{
#if TARGET_CARBON
// Ref: http://developer.apple.com/technotes/tn/tn2051.html
// short-circuit QD's implicit LockPortBits()
// Note: MUST unlock before exiting this scope (see below)
::LockPortBits(::GetWindowPort(mWindowPtr));
#endif
#if DEBUG
// measure the time it takes to refresh the window, if the control key is down.
@ -1534,7 +1516,6 @@ else
int numRects = 0;
#if TARGET_CARBON
QDRegionToRects ( updateRgn, kQDParseRegionFromTopLeft, sCountRectProc, &numRects );
if ( numRects <= kMaxUpdateRects ) {
Rect rectList[kMaxUpdateRects];
@ -1566,39 +1547,6 @@ else
::GetRegionBounds(updateRgn, &boundingBox);
PaintUpdateRect ( &boundingBox, this );
}
#else
EachRegionRect ( updateRgn, CountRect, &numRects );
if ( numRects <= kMaxUpdateRects ) {
Rect rectList[kMaxUpdateRects];
TRectArray rectWrapper ( rectList );
// compile a list of rectangles
EachRegionRect ( updateRgn, AddRectToArray, &rectWrapper );
// amalgamate adjoining rects into a single rect. This
// may over-draw a little, but will prevent us from going down into
// the layout engine for lots of little 1-pixel wide rects.
if ( numRects > 1 )
CombineRects ( rectWrapper );
// now paint 'em! (|numRects| may be invalid now, so check count again). If
// we're above a certain threshold, just bail and do bounding box
if ( rectWrapper.Count() < kRectsBeforeBoundingBox ) {
for ( int i = 0; i < rectWrapper.Count(); ++i )
PaintUpdateRect ( &rectList[i], this );
}
else {
Rect boundingBox;
::GetRegionBounds(updateRgn, &boundingBox);
PaintUpdateRect ( &boundingBox, this );
}
}
else {
Rect boundingBox;
::GetRegionBounds(updateRgn, &boundingBox);
PaintUpdateRect ( &boundingBox, this );
}
#endif
#if DEBUG
if (measure_duration) {
@ -1611,12 +1559,10 @@ else
if (regionToValidate)
::CopyRgn(updateRgn, regionToValidate);
#if TARGET_CARBON
// Ref: http://developer.apple.com/technotes/tn/tn2051.html
// short-circuit QD's implicit LockPortBits()
// Note: unlock before exiting (locked above)
::UnlockPortBits(::GetWindowPort(mWindowPtr));
#endif
}
@ -1804,115 +1750,8 @@ void nsWindow::UpdateWidget(nsRect& aRect, nsIRenderingContext* aContext)
void
nsWindow::ScrollBits ( Rect & inRectToScroll, PRInt32 inLeftDelta, PRInt32 inTopDelta )
{
#if TARGET_CARBON
::ScrollWindowRect ( mWindowPtr, &inRectToScroll, inLeftDelta, inTopDelta,
kScrollWindowInvalidate, NULL );
#else
// Get Frame in local coords from clip rect (there might be a border around view)
StRegionFromPool clipRgn;
if ( !clipRgn ) return;
::GetClip(clipRgn);
::SectRgn(clipRgn, mVisRegion, clipRgn);
StRegionFromPool localVisRgn;
if ( !localVisRgn ) return;
Rect frame;
::GetRegionBounds(clipRgn, &frame);
StRegionFromPool totalVisRgn;
if ( !totalVisRgn ) return;
::RectRgn(totalVisRgn, &frame);
// compute the source and destination of copybits
Rect source = inRectToScroll;
SectRect(&source, &frame, &source);
Rect dest = source;
::OffsetRect(&dest, inLeftDelta, inTopDelta);
// compute the area that is to be updated by subtracting the dest from the visible area
StRegionFromPool destRgn;
if ( !destRgn ) return;
::RectRgn(destRgn, &dest);
StRegionFromPool updateRgn;
if ( !updateRgn ) return;
::RectRgn(updateRgn, &frame);
::DiffRgn (updateRgn, destRgn, updateRgn);
if(::EmptyRgn(mWindowPtr->visRgn))
{
::CopyBits (
&mWindowPtr->portBits,
&mWindowPtr->portBits,
&source,
&dest,
srcCopy,
nil);
}
else
{
// compute the non-visible region by subtracting what's currently
// visible (the window's visRgn) from the whole area we're updating
StRegionFromPool nonVisibleRgn;
if ( !nonVisibleRgn ) return;
::DiffRgn ( totalVisRgn, mWindowPtr->visRgn, nonVisibleRgn );
// compute the extra area that may need to be updated
// scoll the non-visible region to determine what needs updating
::OffsetRgn ( nonVisibleRgn, inLeftDelta, inTopDelta );
// calculate a mask region to not copy the non-visble portions of the window from the port
StRegionFromPool copyMaskRgn;
if ( !copyMaskRgn ) return;
::DiffRgn(totalVisRgn, nonVisibleRgn, copyMaskRgn);
// use copybits to simulate a ScrollRect()
RGBColor black = { 0, 0, 0 };
RGBColor white = { 0xFFFF, 0xFFFF, 0xFFFF } ;
::RGBForeColor(&black);
::RGBBackColor(&white);
::PenNormal();
::CopyBits (
&mWindowPtr->portBits,
&mWindowPtr->portBits,
&source,
&dest,
srcCopy,
copyMaskRgn);
// union the update regions together and invalidate them
::UnionRgn(nonVisibleRgn, updateRgn, updateRgn);
}
// If the region to be scrolled contains regions which are currently dirty,
// we must scroll those too, and union them with the updateRgn.
// get a copy of the dirty region.
::BeginUpdate(mWindowPtr);
::CopyRgn(mWindowPtr->visRgn, localVisRgn); // re-use localVisRgn
::EndUpdate(mWindowPtr);
StRegionFromPool dirtyRgn;
if (!dirtyRgn) return;
// get only the part of the dirtyRgn that intersects the frame
::SectRgn(localVisRgn, totalVisRgn, dirtyRgn);
// offset by the amount scrolled
::OffsetRgn(dirtyRgn, inLeftDelta, inTopDelta);
// now intersect with the frame again
::SectRgn(dirtyRgn, totalVisRgn, dirtyRgn);
// and add it to the dirty region
::UnionRgn(updateRgn, dirtyRgn, updateRgn);
// we also need to re-dirty the dirty rgn outside out frame,
// since BeginUpdate/EndUpdate cleared it.
::DiffRgn(localVisRgn, totalVisRgn, localVisRgn);
// and add it to the dirty region
::UnionRgn(updateRgn, localVisRgn, updateRgn);
::InvalWindowRgn(mWindowPtr, updateRgn);
#endif // !TARGET_CARBON
}
@ -2658,101 +2497,3 @@ NS_IMETHODIMP nsWindow::CancelIMEComposition() {
return NS_ERROR_NOT_IMPLEMENTED;
}
#if !TARGET_CARBON
void EachRegionRect (RgnHandle r, void (* proc)(Rect *, void *), void* data) ;
//
// Written by Hugh Fisher, March 1993.
// Used w/out asking his permission.
//
// This can go away when we get an api on nsIRegion to create one from
// a RgnHandle. Then we can use nsIRegion::GetRects to do the work for us.
//
void
EachRegionRect (RgnHandle r, void (* proc)(Rect *, void *), void* inData)
{
#define EndMark 32767
#define MaxY 32767
#define StackMax 1024
typedef struct {
short size;
Rect bbox;
short data[];
} ** Internal;
Internal region;
short width, xAdjust, y, index, x1, x2, x;
Rect box;
short stackStorage[1024];
short * buffer;
region = (Internal)r;
/* Check for plain rectangle */
if ((**region).size == 10) {
proc(&(**region).bbox, inData);
return;
}
/* Got to scale x coordinates into range 0..something */
xAdjust = (**region).bbox.left;
width = (**region).bbox.right - xAdjust;
/* Most regions will be less than 1024 pixels wide */
if (width < StackMax)
buffer = stackStorage;
else {
buffer = (short *)PR_Malloc(width * 2);
if (buffer == NULL)
/* Truly humungous region or very low on memory.
Quietly doing nothing seems to be the
traditional Quickdraw response. */
return;
}
/* Initialise scan line list to bottom edges */
for (x = (**region).bbox.left; x < (**region).bbox.right; x++)
buffer[x - xAdjust] = MaxY;
index = 0;
/* Loop until we hit an empty scan line */
while ((**region).data[index] != EndMark) {
y = (**region).data[index];
index ++;
/* Loop through horizontal runs on this line */
while ((**region).data[index] != EndMark) {
x1 = (**region).data[index];
index ++;
x2 = (**region).data[index];
index ++;
x = x1;
while (x < x2) {
if (buffer[x - xAdjust] < y) {
/* We have a bottom edge - how long for? */
box.left = x;
box.top = buffer[x - xAdjust];
while (x < x2 && buffer[x - xAdjust] == box.top) {
buffer[x - xAdjust] = MaxY;
x ++;
}
/* Pass to client proc */
box.right = x;
box.bottom = y;
proc(&box, inData);
} else {
/* This becomes a top edge */
buffer[x - xAdjust] = y;
x ++;
}
}
}
index ++;
}
/* Clean up after ourselves */
if (width >= StackMax)
PR_Free((void *)buffer);
#undef EndMark
#undef MaxY
#undef StackMax
}
#endif

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

@ -282,11 +282,10 @@ protected:
// Routines for iterating over the rects of a region. Carbon and pre-Carbon
// do this differently so provide a way to do both.
#if TARGET_CARBON
static OSStatus PaintUpdateRectProc (UInt16 message, RgnHandle rgn, const Rect *rect, void *refCon);
static OSStatus AddRectToArrayProc (UInt16 message, RgnHandle rgn, const Rect *rect, void *refCon);
static OSStatus CountRectProc (UInt16 message, RgnHandle rgn, const Rect *rect, void *refCon);
#endif
static void PaintUpdateRect (Rect * r, void* data) ;
static void AddRectToArray (Rect * r, void* data) ;