/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* Portions copyright Metrowerks Corporation. */ // A a temporary solution, some lines have been out-commented // with the tag //¥¥¥ REVISIT NOVA MERGE ¥¥¥ // // =========================================================================== // UApp.cp // main and CFrontApp's methods // Created by atotic, June 6th, 1994 // =========================================================================== //#define DONT_DO_MOZILLA_PROFILE //#define PROFILE_UPDATE_MENUS #ifdef MOZ_FULLCIRCLE #include "fullsoft.h" #endif #include "uapp.h" #include "CAppleEventHandler.h" //#include "shist.h" #include #include // macfe //#include "NavigationServicesSupport.h" #include "earlmgr.h" #include "macutil.h" #include "macgui.h" // HyperStyle #include "CBookmarksAttachment.h" #include "CToolsAttachment.h" #include "CFontMenuAttachment.h" #include "CRecentEditMenuAttachment.h" #include "BookmarksFile.h" #include "mprint.h" #include "mimages.h" #include "mplugin.h" #include "prpriv.h" #include "URDFUtilities.h" // for LaunchURL #include "CAutoPtrXP.h" #if defined (JAVA) #include "mjava.h" #endif #if defined (OJI) #include "jvmmgr.h" #endif #include "mregistr.h" #include "resae.h" #include "resgui.h" #include "uerrmgr.h" #include "ufilemgr.h" #include "msv2dsk.h" #include "mversion.h" #include "xp_trace.h" #include "CTargetedUpdateMenuRegistry.h" #include "UDesktop.h" #include "CNavCenterWindow.h" #include "UDeferredTask.h" #include "URobustCreateWindow.h" #include "URDFUtilities.h" #ifdef MOZ_MAIL_NEWS #include "CMessageFolder.h" #include "UNewFolderDialog.h" #endif #include "LMenuSharing.h" #define MENU_SHARING_FIRST 40 #ifndef NSPR20 #include "CNetwork.h" #endif #include "CEnvironment.h" #include "CWindowMenu.h" #include "CHistoryMenu.h" #include "CNSMenuBarManager.h" #ifdef MOZ_MAIL_NEWS #include "CThreadWindow.h" #include "CMailProgressWindow.h" #include "UMailFolderMenus.h" #endif #include "UTearOffPalette.h" #include "CPaneEnabler.h" #include "CApplicationEventAttachment.h" #include "CCloseAllAttachment.h" #include "CNSContextCallbacks.h" #include "CBrowserContext.h" #include "prgc.h" #include "java.h" #include "secrng.h" #include "secnav.h" #include "mkutils.h" // only for FREEIF() macro. JRM 96/10/17 #include "CEditorWindow.h" #include "CEditView.h" #include "meditdlg.h" #ifdef MOZ_MAIL_NEWS #include "MailNewsSearch.h" #include "MailNewsFilters.h" #include "MailNewsAddressBook.h" #include "CCheckMailContext.h" #endif // MOZ_MAIL_NEWS #include "StBlockingDialogHandler.h" #include "CSecureAttachment.h" //#include "VTSMProxy.h" #include "LTSMSupport.h" #include "CMouseDispatcher.h" #include "CSuspenderResumer.h" #if defined(MOZ_MAIL_COMPOSE) || defined(MOZ_MAIL_NEWS) #include "MailNewsClasses.h" #include "msgcom.h" #include "MailNewsgroupWindow_Defines.h" #endif #include "BrowserClasses.h" //#include "CBrowserView.h" // need for CFrontApp::EventKeyUp() 1997-02-24 mjc #include "CKeyUpReceiver.h" // need in CFrontApp::EventKeyUp() #include "CToolbarModeManager.h" #include "CMozillaToolbarPrefsProxy.h" #include "CSharedPatternWorld.h" #include "InternetConfig.h" #include "il_strm.h" /* Image Library stream converters. */ #ifdef MOCHA //#include "libmocha.h" #include "CMochaHacks.h" #endif PRThread* mozilla_thread; PREventQueue *mozilla_event_queue = NULL; #if defined (JAVA) #include "MFramePeer.h" #endif #include "CLibMsgPeriodical.h" // Netscape #ifndef GLHIST_H #include "glhist.h" #endif #include "edtplug.h" #include "m_cvstrm.h" #include "prefapi.h" #include "NSReg.h" #ifdef MOZ_SMARTUPDATE #include "softupdt.h" #endif #include // HERE ONLY UNTIL NAV SERVICES CODE MERGED INTO TIP Boolean SimpleOpenDlog ( short numTypes, const OSType typeList[], FSSpec* outFSSpec ) ; CAutoPtr CFrontApp::sRDFContext; // Now we modify the frequency with which we call WaitNextEvent to try // to minimize the time we spend in this expensive function. The strategy // is two-fold: // 1. If we are in the foreground, and there are no pending user // events (determined with OSEventAvail), then only call WNE every // kWNETicksInterval (4) ticks. // Note that OSEvent avail only knows about the Operating System // event queue, which contains these events: // mouseDown, mouseUp, keyDown, keyUp, autoKey, diskEvent // // If we are in the background, we are nice to front apps and // call WNE every time. // // 2. We also adjust the sleep time (the value passed to WNE to determine // how long it is before the Event Manager returns control to us). // This is done on EventSuspend and EventResume. We set the sleep time // to 0 in the foreground, and 4 in the background. #define DAVIDM_SPEED2 // Comment out to remove this WNE wrapper code //====================================================================================== // PROFILE //====================================================================================== //#define PROFILE_LOCALLY 1 #if defined(PROFILE) || defined (PROFILE_LOCALLY) #include // Define this if you want to start profiling when the Caps Lock // key is pressed. Usually that's what you want: press Caps Lock, // start the command you want to profile, release Caps Lock when // the command is done. It works for all the major commands: // display a page, send a mail, save an attachment, etc... #define PROFILE_ON_CAPSLOCK // Define this if you want to let the profiler run while you're // spending time in other apps. Usually you don't. //#define PROFILE_WAITNEXTEVENT // Legacy stuff: profiles CFrontApp::UpdateMenus(). // Don't use other profile methods at the same time. //#define PROFILE_UPDATE_MENUS //--------------------------------------------- // Paste these in the file you want to profile // The code to be profiled must be in a project // with "Emit profiler calls" turned on. // // Example: // ProfileStart() // ... // ProfileSuspend() // ... // ProfileResume() // ... // ProfileStop() // // If you want to start the profile when Caps Lock // is pressed, you can use: // // if (IsThisKeyDown(0x39)) // caps lock // ProfileStart() // //--------------------------------------------- extern void ProfileStart(); extern void ProfileStop(); extern void ProfileSuspend(); extern void ProfileResume(); extern Boolean ProfileInProgress(); //--------------------------------------------- static Boolean sProfileInProgress = false; void ProfileStart() { if (! sProfileInProgress) { sProfileInProgress = true; if (ProfilerInit(collectDetailed, microsecondsTimeBase, 2000, 100)) return; ProfilerSetStatus(true); } } void ProfileStop() { if (sProfileInProgress) { ProfilerDump("\pMozilla Profile"); ProfilerTerm(); sProfileInProgress = false; } } void ProfileSuspend() { if (sProfileInProgress) ProfilerSetStatus(false); } void ProfileResume() { if (sProfileInProgress) ProfilerSetStatus(true); } Boolean ProfileInProgress() { return sProfileInProgress; } #endif // PROFILE //====================================================================================== #ifdef FORTEZZA #include "ssl.h" #endif #include #include "CPrefsDialog.h" #include "UProcessUtils.h" // for LaunchApplication #ifdef MOZ_OFFLINE #include "UOffline.h" #endif #define LICENSE_REVISION 7 extern NET_StreamClass *IL_NewStream(int, void *, URL_Struct *, MWContext *); extern void TrySetCursor( int whichCursor ); list CFrontApp::sCommandsToUpdateBeforeSelectingMenu; CFrontApp* CFrontApp::sApplication = NULL; CAppleEventHandler* CAppleEventHandler::sAppleEventHandler = NULL; short CFrontApp::sHelpMenuOrigLength = 4; short CFrontApp::sHelpMenuItemCount = 0; double CFrontApp::sHRes = 1.0; double CFrontApp::sVRes = 1.0; static PA_InitData parser_initdata; static void InitDebugging(); static void ConfirmWeWillRun(); static Boolean NetscapeIsRunning(ProcessSerialNumber& psn); static Boolean LicenseHasExpired(); static void CheckForOtherNetscapes(); static void AssertAppearanceLib(); static const OSType kConferenceAppSig = 'Ncq¹'; static const OSType kCalendarAppSig = 'NScl'; static const OSType kImportAppSig = 'NSi2'; static const OSType kAOLInstantMessengerSig = 'Oscr'; #ifdef EDITOR static void OpenEditURL(const char* url){ if ( url != NULL ) { URL_Struct * request = NET_CreateURLStruct ( url, NET_NORMAL_RELOAD ); if ( request ) CEditorWindow::MakeEditWindow( NULL, request ); } } #endif // EDITOR //====================================== class LTimerCallback: public LPeriodical // class that keeps track of xp timeout callbacks //====================================== { public: LTimerCallback( TimeoutCallbackFunction func, void* closure, uint32 msecs ); void SpendTime( const EventRecord& inMacEvent ); static LArray* sTimerList; protected: UInt32 fFireTime; TimeoutCallbackFunction fFireFunc; void* fClosure; }; LArray* LTimerCallback::sTimerList = NULL; //----------------------------------- LTimerCallback::LTimerCallback( TimeoutCallbackFunction func, void* closure, uint32 msecs ) : LPeriodical() //----------------------------------- { UInt32 ticks = ::TickCount(); // ¥Êcalculate the fire time in ticks from now fFireTime = ticks + ceil(((double)msecs / 100.0) * 6.0); fFireFunc = func; fClosure = closure; this->StartIdling(); } //----------------------------------- void LTimerCallback::SpendTime( const EventRecord& inMacEvent ) //----------------------------------- { UInt32 ticks = inMacEvent.when; if ( ticks >= fFireTime ) { // 97-06-18 pkc -- Remove this from sTimerList first because when we call // fFireFunc could possibly cause a call to FE_ClearTimeout on this // remove from timer list before deleting LTimerCallback::sTimerList->Remove(&this); // let's just say that the fFireFunc gives time to repeaters... // We don't want this one going off again before it is deleted! fFireTime = LONG_MAX; if ( fFireFunc ) (*fFireFunc)( fClosure ); delete this; } } //----------------------------------- void* FE_SetTimeout( TimeoutCallbackFunction func, void* closure, uint32 msecs ) // this function should register a function that will // be called after the specified interval of time has // elapsed. This function should return an id // that can be passed to FE_ClearTimer to cancel // the timer request. // // func: The function to be invoked upon expiration of // the timer interval // closure: Data to be passed as the only argument to "func" // msecs: The number of milli-seconds in the interval //----------------------------------- { Try_ { LTimerCallback* t = new LTimerCallback( func, closure, msecs ); // insert timer callback into list try { if (!LTimerCallback::sTimerList) LTimerCallback::sTimerList = new LArray(sizeof(LTimerCallback*)); LTimerCallback::sTimerList->InsertItemsAt(1, LArray::index_Last, &t); } catch (...) { } return t; } Catch_( inErr ) { return NULL; } EndCatch_ } //----------------------------------- void FE_ClearTimeout( void* timer_id ) // This function cancels a timer that has previously been set. // Callers should not pass in NULL or a timer_id that has already expired. //----------------------------------- { XP_ASSERT( timer_id ); LTimerCallback* timer = (LTimerCallback*)timer_id; if (LTimerCallback::sTimerList) { if (LTimerCallback::sTimerList->FetchIndexOf(&timer) > LArray::index_Bad) { // this LTimerCallback is in timer list // remove from timer list before deleting LTimerCallback::sTimerList->Remove(&timer); delete timer; } } } #pragma mark - #if 0 void Assert68020() { long response = 0; OSErr err = ::Gestalt (gestaltQuickdrawVersion, &response); if (err || response == gestaltOriginalQD) { ::Alert (14000, NULL); ::ExitToShell (); } } void AssertSystem7() { long response = 0; OSErr err = ::Gestalt (gestaltSystemVersion, &response); if (err || response < 0x700) { ::Alert (14001, NULL); ::ExitToShell (); } } #endif static void AssertAppearanceLib ( ) { if ( ! UEnvironment::HasFeature(env_HasAppearance) ) { ::InitCursor(); ::Alert (14004, NULL); ::ExitToShell (); } } static void RequiredGutsNotFoundAlert() { Str255 gutsFolderName; GetIndString(gutsFolderName, 14000, 1); ParamText(gutsFolderName, NULL, NULL, NULL); Alert (14002, NULL); ExitToShell(); } static void AssertRequiredGuts() { // Initialize the "CPrefs::NetscapeFolder" and "CPrefs::RequiredGutsFolder" // static variables early for use by the XP strings code in "errmgr.cp." short vRefNum; long dirID; if (HGetVol(NULL, &vRefNum, &dirID) != noErr) ExitToShell(); FSSpec netscapeFolderSpec; if (CFileMgr::FolderSpecFromFolderID(vRefNum, dirID, netscapeFolderSpec) != noErr) RequiredGutsNotFoundAlert(); try { CPrefs::Initialize(); } catch (...) { RequiredGutsNotFoundAlert(); } CPrefs::SetFolderSpec(netscapeFolderSpec, CPrefs::NetscapeFolder); FSSpec gutsFolderSpec; // Build a partial path to the guts folder starting from a folder we know (the Netscape folder) Str255 partialPath; { // Get the name of the guts folder Str255 gutsFolderName; GetIndString(gutsFolderName, 14000, 1); // partialPath = ":" + netscapeFolderSpec.name + ":" + gutsFolderName; // ( this may _look_ cumbersome, but it's really the most space and time efficient way to catentate 4 pstrings ) int dest=0; partialPath[++dest] = ':'; for ( int src=0; srcaddress ) ) type = MWContextMail; else if ( MSG_RequiresNewsWindow( url->address ) ) type = MWContextNews; else if (MSG_RequiresBrowserWindow(url->address)) type = MWContextBrowser; else return FALSE; return TRUE; } return FALSE; } #endif // MOZ_MAIL_NEWS extern "C" { void InitializeASLM(); void CleanupASLM(); } #pragma mark - //====================================== class CResumeEventAttachment : public LAttachment // This silly class fixes a weird bug where the app doesnÕt // get resume events after being sent a getURL AppleEvent. // This attachment will run whenever we get an event, so // we can check to see if the event is not a resume event, // target is nil (meaning we havenÕt received a resume // event yet), and weÕre in the foreground (meaning we got // switched in without getting the event). If all those // are true, we can resume ourselves so we wonÕt crash // because target is nil. //====================================== { public: CResumeEventAttachment(CFrontApp* app) : LAttachment(msg_Event), fApp(app) {} protected: virtual void ExecuteSelf(MessageT inMessage, void* ioParam); private: CFrontApp* fApp; }; //----------------------------------- void CResumeEventAttachment::ExecuteSelf(MessageT inMessage, void* ioParam) //----------------------------------- { EventRecord* event = (EventRecord*) ioParam; // // Do quick tests first to see if we should // go ahead and check if weÕre in the foreground. // if (inMessage == msg_Event && event->what != osEvt && LCommander::GetTarget() == nil) { ProcessSerialNumber frontProcess; ProcessSerialNumber currentProcess; GetFrontProcess(&frontProcess); GetCurrentProcess(¤tProcess); Boolean result = false; SameProcess(&frontProcess, ¤tProcess, &result); if (result) { // // WeÕre in the foreground, so synthesize // a resume event and process it. // EventRecord resumeEvent; memset(&resumeEvent, 0, sizeof(EventRecord)); resumeEvent.what = osEvt; resumeEvent.message = suspendResumeMessage << 24; resumeEvent.message |= resumeFlag; fApp->DispatchEvent(resumeEvent); } } } #pragma mark - //====================================== class CSplashScreen : public LWindow //====================================== { public: enum { class_ID = 'Spls' }; CSplashScreen(LStream* inStream); virtual ~CSplashScreen(); virtual void SetDescriptor(ConstStringPtr inDescriptor); protected: virtual void FinishCreateSelf(void); LCaption* mStatusCaption; CResPicture* mBackPicture; LFile* mPictureResourceFile; }; #pragma mark - //====================================== // CLASS CFrontApp //====================================== //----------------------------------- CFrontApp::CFrontApp() //----------------------------------- : fCurrentMbar(cBrowserMenubar) , fWantedMbar(fCurrentMbar) , fStartupAborted(false) , fProperStartup(false) , mSplashScreen(NULL) #ifdef MOZ_MAIL_NEWS , mLibMsgPeriodical(NULL) #endif // MOZ_MAIL_NEWS , mConferenceApplicationExists(false) , mJavaEnabled(false) , mHasBookmarksMenu(false) , mHasFrontierMenuSharing(false) , mMouseRgnH( NewRgn() ) // Performance // We really should be adjusting this dynamically { // Set environment features CEnvironment::SetAllFeatures(); // Static data members sApplication = this; // Add CApplicationEventAttachment AddAttachment(new CApplicationEventAttachment); // Add CCloseAllAttachment AddAttachment(new CCloseAllAttachment(CLOSE_WINDOW, CLOSE_ALL_WINDOWS)); // Inherited data members mSleepTime = 1; // Indicate we don't want to be able to quit yet fSafeToQuit = false; fUserWantsToQuit = false; // Toolbox qd.randSeed = TickCount(); // Toolbox AddAttachment(new LClipboard()); AddAttachment(new CSecureAttachment); AddAttachment(new CResumeEventAttachment(this)); #ifdef MOZ_MAIL_NEWS // create CLibMsgPeriodical mLibMsgPeriodical = new CLibMsgPeriodical; mLibMsgPeriodical->StartIdling(); #endif // MOZ_MAIL_NEWS // // Initial inline support (TSM) // LTSMSupport::Initialize(); UHTMLPrinting::InitCustomPageSetup(); #ifdef MOZ_SMARTUPDATE SU_Startup(); #endif NR_StartupRegistry(); // ¥ PowerPlant initialization UScreenPort::Initialize(); #if defined(MOZ_MAIL_NEWS) || defined(MOZ_MAIL_COMPOSE) RegisterAllMailNewsClasses(); #endif // MOZ_MAIL_NEWS RegisterAllBrowserClasses(); ShowSplashScreen(); InitUTearOffPalette(this); CTearOffManager::GetDefaultManager()->AddListener(this); // ¥Ênetwork #ifndef NSPR20 CNetworkDriver::CreateNetworkDriver(); #endif TheEarlManager.StartRepeating(); // WTSMManager::Initialize(); // AddAttachment(new VTSMDoEvent(msg_Event)); HyperStyle::InitHyperStyle(); // ¥ parser parser_initdata.output_func = LO_ProcessTag; // ¥Êparsers // mime parsers NET_RegisterMIMEDecoders(); // external objects go to disk NET_RegisterContentTypeConverter ("*", FO_PRESENT, nil, NewFilePipe); NET_RegisterContentTypeConverter ("*", FO_SAVE_AS, nil, NewFilePipe); FSSpec spec; mImportModuleExists = CFileMgr::FindApplication(kImportAppSig, spec) == noErr; mAOLMessengerExists = CFileMgr::FindApplication(kAOLInstantMessengerSig, spec) == noErr; // Record whether the conference application exists. We do this once here // instead of lots 'o times in FindCommandStatus so searching for an app // doesn't slow us to a crawl (especially when searchin on network volumes). // One drawback of course, is that when the app is installed or removed, // the menu won't be enabled or disabled until the user quits and restarts // the app. This behavior is different than the pref panel for controlling // whether conference launches on startup or not (but that occurence of // FindApplication isn't called many times/sec either). mConferenceApplicationExists = (CFileMgr::FindApplication(kConferenceAppSig, spec) == noErr); } //----------------------------------- CFrontApp::~CFrontApp() //----------------------------------- { // Save the current visibility information if ( CPrefs::GetLong( CPrefs::StartupAsWhat ) == STARTUP_VISIBLE) { long winRecord = 0; CMediatedWindow* theWindow; CWindowIterator iter(WindowType_Any); while (iter.Next(theWindow)) { switch(theWindow->GetWindowType()) { #if 0 case WindowType_MailNews: winRecord |= (MAIL_STARTUP_ID | NEWS_STARTUP_ID); break; case WindowType_Address: winRecord |= ADDRESS_STARTUP_ID; break; #endif case WindowType_Browser: winRecord |= BROWSER_STARTUP_ID; break; case WindowType_NavCenter: winRecord |= NAVCENTER_STARTUP_ID; break; default: break; } } if (winRecord != 0) CPrefs::SetLong(winRecord, CPrefs::StartupBitfield); } { // This really comes from ~LCommander. This gets // executed after our destructor, and deletes all the windows // We need windows to be deleted before we are done, // because window destruction callbacks reference the app! // DO NOT DO THIS (IT CAUSES UNNECESSARY DEBUG BREAKS): SetTarget(this); // tj, 5/1/96 // // We must close the windows explicitly, so that each window // can interrupt its context (XP_InterruptContext) while the // window is still completely alive // // Hmmmmm ... better be a hair more careful about traversing that window list. // DDM 21-JUN-96 WindowRef macWindow = LMGetWindowList(); while (macWindow) { LWindow *ppWindow = LWindow::FetchWindowObject(macWindow); if (ppWindow) { ppWindow->DoClose(); // Start over at the beginning of the list. // This is possibly slow but definitely safe, i.e. we're not using // a block of memory that's been deleted. macWindow = LMGetWindowList(); } else // Skip to the next window in the list. macWindow = GetNextWindow(macWindow); } // Delete all SubCommanders LArrayIterator iterator(mSubCommanders); LCommander *theSub; while (iterator.Next(&theSub)) delete theSub; } HyperStyle::FinishHyperStyle(); LTSMSupport::DoQuit( 0 ); // WTSMManager::Quit(); // UpdateMenus(); TrySetCursor( watchCursor ); // XP_Saves GH_SaveGlobalHistory(); GH_FreeGlobalHistory(); #ifdef MOZ_MAIL_NEWS NET_SaveNewsrcFileMappings(); CAddressBookManager::CloseAddressBookManager(); CCheckMailContext::Release(this); #endif // MOZ_MAIL_NEWS //----- // We just closed all the windows but we now have to wait for the callbacks // in order to really delete the different contexts. That's because // CNSContext::NoMoreUsers() calls ET_RemoveWindowContext() which posts // an event which calls MochaDone() asynchronously and deletes the context.. // // NOTE: CCheckMailContext::Release() also posts an event in order to delete // its context. So make sure that PR_ProcessPendingEvents() is always // executed after window->DoClose(), CCheckMailContext::Release() or any // other destructor function which deletes a context. A symptom of not // deleting the context is that newsgroups which have been unsubscribed // in the Message Center reappear when launching the application again. PR_ProcessPendingEvents(mozilla_event_queue); //----- #ifndef NSPR20 if (gNetDriver && !fStartupAborted) { extern const char* CacheFilePrefix; NET_CleanupCacheDirectory( "", CacheFilePrefix ); NET_ShutdownNetLib(); delete gNetDriver; gNetDriver = NULL; } #else if (!fStartupAborted) { extern const char* CacheFilePrefix; NET_CleanupCacheDirectory( "", CacheFilePrefix ); NET_ShutdownNetLib(); } #endif if (!fStartupAborted) CPrefs::DoWrite(); #ifdef MOZ_MAIL_NEWS delete mLibMsgPeriodical; #endif // MOZ_MAIL_NEWS SetCursor( &qd.arrow ); // remove anything we left in the Temporary Items:nscomm40 folder CFileMgr::DeleteCommTemporaryItems(); NR_ShutdownRegistry(); #ifdef MOZ_SMARTUPDATE SU_Shutdown(); #endif // MOZ_SMARTUPDATE ET_FinishMocha(); LJ_ShutdownJava(); // shutdown plugins NPL_Shutdown(); DisposeRgn(mMouseRgnH); // Un-init RDF URDFUtilities::ShutdownRDF(); sApplication = NULL; } // CFrontApp::~CFrontApp() //----------------------------------- void CFrontApp::Initialize() //----------------------------------- { // this will always succeed since we require AppearanceLib. ::RegisterAppearanceClient(); // Insert commands to update before seleting menu into list sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Redo); sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Close); sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Undo); sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Cut); sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Copy); sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Paste); sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_Clear); sCommandsToUpdateBeforeSelectingMenu.push_front(cmd_SelectAll); new CNSContextCallbacks; LDocApplication::Initialize(); CMouseDispatcher* md = new CMouseDispatcher; AddAttachment(md); // 97-09-11 pchen -- setup prefs proxy for CToolbarModeManager so that knows // how to get Communicator toolbar style pref CMozillaToolbarPrefsProxy* prefsProxy = new CMozillaToolbarPrefsProxy(); CToolbarModeManager::SetPrefsProxy(prefsProxy); // Register callback function when browser.chrome.toolbar_style // pref changes PREF_RegisterCallback("browser.chrome.toolbar_style", CToolbarModeManager::BroadcastToolbarModeChange, (void*)NULL); // 97-05-12 pkc -- setup sHRes and sVRes data members CGrafPtr wMgrPort; GetCWMgrPort(&wMgrPort); sHRes = (**wMgrPort->portPixMap).hRes / 0x00010000; // convert from Fixed to floating point sVRes = (**wMgrPort->portPixMap).vRes / 0x00010000; // convert from Fixed to floating point // 97-08-23 pchen -- register us as listener to LGrowZone LGrowZone::GetGrowZone()->AddListener(this); } // CFrontApp::Initialize() void CFrontApp::RegisterMimeType(CMimeMapper * mapper) { CMimeMapper::LoadAction loadAction = mapper->GetLoadAction(); CStr255 mimeName = mapper->GetMimeName(); CStr255 pluginName = mapper->GetPluginName(); void* pdesc = nil; if (pluginName.Length() > 0) pdesc = GetPluginDesc(pluginName); switch (loadAction) { case CMimeMapper::Internal: // Disable the previous plug-in, if any if (pdesc) NPL_EnablePluginType(mimeName, pdesc, false); #ifdef OLD_IMAGE_LIB if (mimeName == IMAGE_GIF || mimeName == IMAGE_JPG || mimeName == IMAGE_XBM || mimeName == IMAGE_PNG) NET_RegisterContentTypeConverter(mimeName, FO_PRESENT, nil, IL_ViewStream); #endif #ifdef MOZ_MAIL_NEWS // BinHex decoder is in mail/news code, right? else if (mimeName == APPLICATION_BINHEX) NET_RegisterContentTypeConverter(APPLICATION_BINHEX, FO_PRESENT, nil, fe_MakeBinHexDecodeStream); #endif // MOZ_MAIL_NEWS break; case CMimeMapper::Plugin: // // pdesc can be nil when reading prefs on startup -- that's OK, // the plug-in code in mplugin.cp will take care of registration. // bing: Alternatively, we could call NPL_EnablePluginType(true) // here and set up the new description and extensions below. // if (pdesc) NPL_RegisterPluginType(mimeName, mapper->GetExtensions(), mapper->GetDescription(), nil, pdesc, true); return; // XP code will take care of the cdata #ifdef ANTHRAX case CMimeMapper::Applet: NPL_RegisterAppletType(mimeName, mapper->GetAppletName()); break; #endif default: // Disable the previous plug-in, if any if (pdesc) NPL_EnablePluginType(mimeName, pdesc, false); // // NewFilePipe will look at the mapper list and // decide whether it should launch an app or save. // NET_RegisterContentTypeConverter(mimeName, FO_PRESENT, nil, NewFilePipe); break; } CStr255 extensions = mapper->GetExtensions(); CStr255 mimetype = mapper->GetMimeName(); NET_cdataCommit(mimetype, extensions); // Special case for View Source // montulli knows why is this if (mimetype == HTML_VIEWER_APPLICATION_MIME_TYPE) { if (loadAction == CMimeMapper::Internal) { NET_RegisterContentTypeConverter (TEXT_HTML, FO_VIEW_SOURCE, NULL, INTL_ConvCharCode); NET_RegisterContentTypeConverter (INTERNAL_PARSER, FO_VIEW_SOURCE,TEXT_HTML, net_ColorHTMLStream); NET_RegisterContentTypeConverter ("*", FO_VIEW_SOURCE, TEXT_PLAIN, net_ColorHTMLStream); NET_RegisterContentTypeConverter (MESSAGE_RFC822, FO_VIEW_SOURCE, NULL, INTL_ConvCharCode); // added by ftang. copy from libnet #ifdef UNIX NET_RegisterContentTypeConverter (MESSAGE_NEWS, FO_VIEW_SOURCE, NULL, INTL_ConvCharCode); // added by ftang. copy from libnet #ifdef UNIX } else // Pipe to disk for launching { NET_RegisterContentTypeConverter (INTERNAL_PARSER, FO_VIEW_SOURCE, nil, NewFilePipe); NET_RegisterContentTypeConverter (TEXT_HTML, FO_VIEW_SOURCE, nil, NewFilePipe); NET_RegisterContentTypeConverter ("*", FO_VIEW_SOURCE, nil, NewFilePipe); } } // We need to add the description, too, which unfortunately requires // looking the cinfo up AGAIN and setting the desc field... char* description = (char*) mapper->GetDescription(); XP_ASSERT(description); if (description) { NET_cdataStruct temp; NET_cdataStruct* cdata; char* mimetype = (char*) mimeName; XP_BZERO(&temp, sizeof(temp)); temp.ci.type = mimetype; cdata = NET_cdataExist(&temp); XP_ASSERT(cdata); if (cdata) StrAllocCopy(cdata->ci.desc, description); } } // NetLib Internals! extern char * XP_AppName; extern char * XP_AppVersion; extern char * XP_AppCodeName; extern char * XP_AppLanguage; extern char * XP_AppPlatform; // Creates a path suitable for use by XP_FILE_OPEN, and xpHotlist file spec char* GetBookmarksPath( FSSpec& spec, Boolean useDefault ) { if ( useDefault ) { spec = CPrefs::GetFilePrototype( CPrefs::MainFolder ); ::GetIndString( spec.name, 300, bookmarkFile ); } char* newPath = CFileMgr::GetURLFromFileSpec( spec ); if ( newPath ) ::BlockMoveData( newPath + 7, newPath, strlen( newPath )-6 ); // Hack, gets rid of the file:/// return newPath; } void CFrontApp::InitBookmarks() { CBookmarksAttachment *attachment = new CBookmarksAttachment; AddAttachment( attachment ); // Bookmark commands UpdateMenus(); } // static int CFrontApp::SetBooleanWithPref(const char *prefName, void *boolPtr) { XP_Bool currentValue = *(Boolean *)boolPtr; PREF_GetBoolPref(prefName, ¤tValue); *(Boolean *)boolPtr = currentValue; return 0; } // This is called right after startup for us to do our initialization. If // the user wants to open/print a document then this will be the file // spec. Otherwise it's nil (normal startup) void CFrontApp::ProperStartup( FSSpec* file, short fileType ) { LFile* prefsFile = NULL; Boolean gotPrefsFile = false; static Boolean properStartup = FALSE; if ( fStartupAborted ) return; if ( properStartup ) { if ( fileType == FILE_TYPE_ODOC || fileType == FILE_TYPE_GETURL || fileType == FILE_TYPE_LDIF) DoOpenDoc( file, fileType ); // Cannot open the Profile Manager while app is running if ( (fileType == FILE_TYPE_PROFILES ) || (fileType == STARTUP_TYPE_NETPROFILE) ) ErrorManager::PlainAlert(ERROR_OPEN_PROFILE_MANAGER); return; } properStartup = TRUE; // Initialize all the modules, // Read generic prefs (which will LoadState all the modules) // Then start the modules and managers NET_InitFileFormatTypes(NULL, NULL); // Needs to be initialized before prefs are read in. SECNAV_InitConfigObject(); // ditto CPrefs::PrefErr abortStartup = CPrefs::eOK; SplashProgress( GetPString(MAC_PROGRESS_PREFS)); if ((fileType == FILE_TYPE_PREFS) && file) { gotPrefsFile = true; prefsFile = new LFile(*file); } // Once we get to this point it's safe to quit fSafeToQuit = true; #ifdef DEBUG // hack to show the profile manager stuff when a modifier key is down KeyMap theKeys; GetKeys(theKeys); if (theKeys[1] & 0x00008000) // is the command key down { prefsFile = NULL; fileType = FILE_TYPE_PROFILES; } #endif abortStartup = CPrefs::DoRead( prefsFile, fileType ); if (( abortStartup == CPrefs::eAbort ) || fUserWantsToQuit) { fStartupAborted = true; DoQuit(); return; } #ifdef MOZ_FULLCIRCLE // Full Circle initialization must happen once the current // profile is known, such that the prefs calls work. XP_Bool fullcircle_enable = TRUE; PREF_GetBoolPref("general.fullcircle_enable", &fullcircle_enable); if ( fullcircle_enable ) { FCInitialize(); } #endif if ( fileType == FILE_TYPE_ASW && file ) abortStartup = CPrefs::eRunAccountSetup; XP_Bool startupFlag; mHasFrontierMenuSharing = (!(PREF_GetBoolPref("browser.mac.no_menu_sharing", &startupFlag) == PREF_NOERROR && startupFlag)); mHasBookmarksMenu = (!(PREF_GetBoolPref("browser.mac.no_bookmarks_menu", &startupFlag) == PREF_NOERROR && startupFlag)); #ifndef MOZ_MAIL_NEWS #ifdef SERVER_ON_RESTART_HACK // not needed in Nova. // Do this after we read prefs: { // Check to see what mail.server_type is and what mail.server_type_on_restart is. // Must be careful because our auto admin tool may have created a "Big Brother" // preference file that locks mail.server_type. If this is the case we must // discard whatever mail.server_type_on_restart is. If the admin hasn't // locked this preference then we use mail.server_type_on_restart (this is what // gets set in the preference dialog). int32 mailServerType, mailServerTypeOnRestart; PREF_GetIntPref("mail.server_type" , &mailServerType); PREF_GetIntPref("mail.server_type_on_restart" , &mailServerTypeOnRestart); // The default value of the latter is -1, of the former, 0 (POP3). // Neither of these should NEVER be set to -1 after we run the first time. if (-1 == mailServerTypeOnRestart) mailServerTypeOnRestart = mailServerType; else mailServerType = mailServerTypeOnRestart; // Write the adjusted values back to the prefs database. if (!PREF_PrefIsLocked("mail.server_type")) PREF_SetIntPref("mail.server_type" , mailServerType); PREF_SetIntPref("mail.server_type_on_restart" , mailServerTypeOnRestart); } #endif #endif // MOZ_MAIL_NEWS // Set the state of network.online to match offline.startup_mode Int32 startupNetworkState; enum {kOnlineState, kOfflineState, kAskUserForState}; PREF_GetIntPref("offline.startup_mode" , &startupNetworkState); switch (startupNetworkState) { case kOnlineState: PREF_SetBoolPref("network.online" , true); break; case kOfflineState: PREF_SetBoolPref("network.online" , false); break; case kAskUserForState: { XP_Bool onlineLastTime; PREF_GetBoolPref("network.online" , &onlineLastTime); XP_Bool locked = PREF_PrefIsLocked("offline.startup_mode"); enum { eAskMeDialog = 12009, eWorkOnline, eWorkOffline, eSetPref }; StDialogHandler handler(eAskMeDialog, nil); LWindow *dialog = handler.GetDialog(); LGARadioButton *onRButton = (LGARadioButton *)dialog->FindPaneByID(eWorkOnline); XP_ASSERT(onRButton); LGARadioButton *offRButton = (LGARadioButton *)dialog->FindPaneByID(eWorkOffline); XP_ASSERT(offRButton); if (onlineLastTime) { onRButton->SetValue(true); } else { offRButton->SetValue(true); } LGACheckbox *setPrefBox = (LGACheckbox *)dialog->FindPaneByID(eSetPref); XP_ASSERT(setPrefBox); if (locked) { setPrefBox->Disable(); } // Run the dialog MessageT message = msg_Nothing; do { message = handler.DoDialog(); } while (msg_OK != message); XP_Bool goOnline = onRButton->GetValue(); if (setPrefBox->GetValue()) { int32 newPrefValue = goOnline ? kOnlineState: kOfflineState; PREF_SetIntPref("offline.startup_mode", newPrefValue); } if (goOnline) { PREF_SetBoolPref("network.online" , true); } else { PREF_SetBoolPref("network.online" , false); } } break; } #if defined (OJI) // beard: On the Mac, there's no interface for this yet, so we want to turn it on. PREF_SetBoolPref("security.enable_java", TRUE); #endif SetBooleanWithPref("security.enable_java", &mJavaEnabled); PREF_RegisterCallback("security.enable_java", SetBooleanWithPref, (void*)&mJavaEnabled); // Set CSharedPatternWorld::sUseUtilityPattern from pref XP_Bool useUtilityPattern; int prefResult = PREF_GetBoolPref("browser.mac.use_utility_pattern", &useUtilityPattern); if (prefResult == PREF_NOERROR && useUtilityPattern) { // Just for grins, check to see if utility pattern exists PixPatHandle thePattern = NULL; thePattern = ::GetPixPat(cUtilityPatternResID); if (thePattern) { CSharedPatternWorld::sUseUtilityPattern = true; ::DisposePixPat(thePattern); } } // NETLIB wait until we've read prefs to determine what to set up CStr255 tmp; // It is a good idea to allocate enough space for strings. // Before today, we were not doing so. This was evil... // So, XP_ALLOC now takes tmp.Length() + 1 as an argument // instead of XP_ALLOC. // dkc 1/25/96 ::GetIndString( tmp, ID_STRINGS, APPNAME_STRING_INDEX ); XP_AppName = (char*)XP_ALLOC( tmp.Length() + 1); sprintf( XP_AppName, tmp ); ::GetIndString( tmp, ID_STRINGS, APPLANGUAGE_STRING_INDEX ); XP_AppLanguage = (char*)XP_ALLOC( tmp.Length() + 1); sprintf( XP_AppLanguage, tmp ); ::GetIndString( tmp, ID_STRINGS, APPVERSION_STRING_INDEX ); // Admin Kit: support optional user-agent suffix { char* suffix; if ( PREF_CopyConfigString("user_agent", &suffix) == PREF_NOERROR ) { tmp = tmp + "C-" + suffix; XP_FREE(suffix); } } CStr255 tmp2; #ifdef powerc ::GetIndString( tmp2, ID_STRINGS, USERAGENT_PPC_STRING_INDEX ); #else ::GetIndString( tmp2, ID_STRINGS, USERAGENT_68K_STRING_INDEX ); #endif tmp = tmp + " "; tmp = tmp + tmp2; char* securityText = "X"; XP_AppVersion = (char*)XP_ALLOC( tmp.Length() + strlen( securityText ) + 1); sprintf( XP_AppVersion, tmp, securityText ); ::GetIndString( tmp2, ID_STRINGS, APPCODENAME_STRING_INDEX ); XP_AppCodeName = (char*)XP_ALLOC( tmp2.Length() + 1); sprintf( XP_AppCodeName, tmp2 ); #ifdef powerc XP_AppPlatform = "MacPPC"; #else XP_AppPlatform = "Mac68k"; #endif SplashProgress( GetPString(MAC_PROGRESS_NET) ); NET_InitNetLib (CPrefs::GetLong( CPrefs::BufferSize ), CPrefs::GetLong( CPrefs::Connections ) ); SECNAV_EarlyInit(); NET_ChangeMaxNumberOfConnections(50); RNG_SystemInfoForRNG(); // 1998.01.12 pchen and 1998.02.23 rjc // RDF now uses NetLib. Netlib initializes history. RDF reimplements // history. Looks like History initialization has been changed to work // correctly. Also, GH_InitGlobalHistory() can be safely called twice. URDFUtilities::StartupRDF(); // Load the .jsc startup file, if necessary (autoadmin added 2/11/98 arshad) //¥¥¥ REVISIT NOVA MERGE ¥¥¥ NET_DownloadAutoAdminCfgFile(); // Install Help and Directory menus InstallMenus(); // arshad - taken from line 1317, moved here for autoadmin to update menus (re: bug 88421) // 1998-03-17 pchen -- Moved this code here to fix Communicator menu // Polaris: remove Calendar/3270 items if they're not installed // (?? maybe these are always available for Polaris (autoadmin lib) // so users get helpful error messages if they try them..?) if (CWindowMenu::sWindowMenu) { FSSpec fspec; #if 0 if ( CFileMgr::FindApplication(kCalendarAppSig, fspec) != noErr ) (CWindowMenu::sWindowMenu)->RemoveCommand(cmd_LaunchCalendar); if ( ! FE_IsNetcasterInstalled() ) (CWindowMenu::sWindowMenu)->RemoveCommand(cmd_LaunchNetcaster); if ( ! Find3270Applet(fspec) ) (CWindowMenu::sWindowMenu)->RemoveCommand(cmd_Launch3270); #endif if ( CFileMgr::FindApplication(kAOLInstantMessengerSig, fspec) != noErr ) (CWindowMenu::sWindowMenu)->RemoveCommand(cmd_LaunchAOLInstantMessenger); } SECNAV_Init(); SECNAV_RunInitialSecConfig(); // call after SECNAV_Init() // Must not call SECNAV_SecurityVersion before SECNAV_Init(). securityText = SECNAV_SecurityVersion( PR_FALSE ); XP_FREE(XP_AppVersion); XP_AppVersion = (char*)XP_ALLOC( tmp.Length() + strlen( securityText ) + 1); sprintf( XP_AppVersion, tmp, securityText ); #ifdef MOZ_MAIL_NEWS NET_ReadNewsrcFileMappings(); #endif SplashProgress( GetPString(MAC_PROGRESS_BOOKMARK)); InitBookmarks(); // Create the NSPR event queue mozilla_event_queue = PR_CreateEventQueue("Mozilla Event Queue", mozilla_thread); NPL_Init(); // plugins LM_InitMocha(); // mocha, mocha, mocha // The tools menus must be created after the plugins are read in. #ifdef EDITOR CToolsAttachment *attachment = new CToolsAttachment; if ( attachment ) AddAttachment( attachment ); // Tools menu CFontMenuAttachment *fontattachment = new CFontMenuAttachment; if ( fontattachment ) AddAttachment( fontattachment ); // Font menu CRecentEditMenuAttachment *recentattachment = new CRecentEditMenuAttachment; if ( recentattachment ) AddAttachment( recentattachment ); #endif // EDITOR UpdateMenus(); #if defined (JAVA) // Initialize the java runtime, start the MToolkit thread running // to keep the network alive. For now, we have to temporarily // enable java to make sure that the runtime bootstraps itself // minimally. // dkc 3-18-96 this->SplashProgress( GetPString(MAC_PROGRESS_JAVAINIT)); LJ_SetJavaEnabled((PRBool)CPrefs::GetBoolean(CPrefs::EnableJava)); #endif /* defined (JAVA) */ #if defined(EDITOR) && defined(MOZ_JAVA) EDTPLUG_RegisterEditURLCallback(&OpenEditURL); #endif // EDITOR && MOZ_JAVA /* Okay, this is hacky, but necessary. It is extremely important that the Macintosh reclaims memory. So, we want the finalizer to be at as high a priority as possible. */ if ((PR_GetGCInfo() != NULL) && (PR_GetGCInfo()->finalizer != NULL)) #ifndef NSPR20 PR_SetThreadPriority(PR_GetGCInfo()->finalizer, 31); #else PR_SetThreadPriority(PR_GetGCInfo()->finalizer, PR_PRIORITY_URGENT); #endif DestroySplashScreen(); if ( abortStartup == CPrefs::eRunAccountSetup ) file = NULL; Boolean agreedToLicense = AgreedToLicense( file, fileType ); if ( abortStartup == CPrefs::eRunAccountSetup ) LaunchAccountSetup(); #ifdef MOZ_MAIL_NEWS // This is for Biff notification. // It should come after menus and after prefs are read in and probably // after the online/offline determination is made. CCheckMailContext::Initialize(this); // we are the owner/user #endif // MOZ_MAIL_NEWS #ifdef MOZ_LOC_INDEP InitializeLocationIndependence(); #endif #ifdef MOZ_MAIL_NEWS SplashProgress( GetPString(MAC_PROGRESS_ADDRESS) ); CAddressBookManager::OpenAddressBookManager(); #endif // MOZ_MAIL_NEWS NET_FinishInitNetLib(); // This was commented out - anyone know why? if (agreedToLicense) CreateStartupEnvironment(! gotPrefsFile); fProperStartup = true; } // CFrontApp::ProperStartup Boolean CFrontApp::AgreedToLicense( FSSpec* fileSpec, short fileType ) { // ML License clicker moved to installer so just open DoOpenDoc( fileSpec, fileType ); return true; } // Called when application starts up without any documents // Reads in the default preferences doc, and then creates a default browser window void CFrontApp::StartUp() { ProperStartup( NULL, FILE_TYPE_PREFS ); // CMailNewsFolderWindow::FindAndShow(true); } pascal void colorPopupMDEFProc(short message, MenuHandle theMenu, Rect *menuRect, Point hitPt, short *whichItem); // openStartupWindows is only false if we started comm from a desktop icon // and don't want the prefs-specified components to open up void CFrontApp::CreateStartupEnvironment(Boolean openStartupWindows) { #ifdef EDITOR // Composer's color picker MDEF Handle stubMDEFH; MenuDefUPP colorMdefUPP; // load/lock (but DON'T detach) MDEF stub and set it to call appropriate routine if ( (stubMDEFH = Get1Resource( 'MDEF', 20000 )) != NULL) { HNoPurge((Handle)stubMDEFH); HUnlock((Handle)stubMDEFH); MoveHHi((Handle)stubMDEFH); HLock((Handle)stubMDEFH); if ( (colorMdefUPP = NewMenuDefProc(colorPopupMDEFProc)) != NULL) { *(ProcPtr *)(*stubMDEFH + 6L) = (ProcPtr)colorMdefUPP; } } #endif XP_Bool startupFlag; // handle new startup preferences CommandT command = cmd_Nothing; // check to see if we need to bring up a new browser window at startup if (PREF_GetBoolPref("general.startup.browser", &startupFlag) == PREF_NOERROR) { if (startupFlag) { // Only create a new browser window if the startupFlag indicates // that we should and there are no delayed URLs (which could happen // if a 'GURL' or 'OURL' event is handled while the profile dialog // or license dialog is waiting to be dismissed) and there are no // open browser windows (which could happen if an 'odoc' event // was processed prior to CreateStartupEnvironment being called). // These guards will ensure that we don't open any unnecessary blank // browser windows at startup. CMediatedWindow* window = CWindowMediator::GetWindowMediator()->FetchTopWindow( WindowType_Browser, regularLayerType, true); UInt32 howMany = CURLDispatcher::CountDelayedURLs(); if (openStartupWindows && !window && !CURLDispatcher::CountDelayedURLs()) MakeNewDocument(); } } #if 0 if (PREF_GetBoolPref("general.startup.netcaster", &startupFlag) == PREF_NOERROR) { if (openStartupWindows && startupFlag) ObeyCommand(cmd_LaunchNetcaster, NULL); } #endif startupFlag = false; if (HasFrontierMenuSharing()) { AddAttachment(new LMenuSharingAttachment( msg_AnyMessage, TRUE, MENU_SHARING_FIRST ) ); // Menu Sharing } #ifdef MOZ_MAIL_NEWS // check to see if we need to bring up mail window at startup if (PREF_GetBoolPref("general.startup.mail", &startupFlag) == PREF_NOERROR) { if (openStartupWindows && startupFlag) ObeyCommand(cmd_Inbox, NULL); } // check to see if we need to bring up news window at startup if (PREF_GetBoolPref("general.startup.news", &startupFlag) == PREF_NOERROR) { if (openStartupWindows && startupFlag) ObeyCommand(cmd_NewsGroups, NULL); } #endif // MOZ_MAIL_NEWS #ifdef EDITOR // check to see if we need to bring up an editor window at startup if (PREF_GetBoolPref("general.startup.editor", &startupFlag) == PREF_NOERROR) { if (openStartupWindows && startupFlag) ObeyCommand(cmd_NewWindowEditor, NULL); } #endif #if !defined(MOZ_LITE) && !defined(MOZ_MEDIUM) // check to see if we need to launch conference at startup if (PREF_GetBoolPref("general.startup.conference", &startupFlag) == PREF_NOERROR) { if (openStartupWindows && startupFlag) ObeyCommand(cmd_LaunchConference, NULL); } // check to see if we need to launch calendar at startup if (PREF_GetBoolPref("general.startup.calendar", &startupFlag) == PREF_NOERROR) { if (openStartupWindows && startupFlag) ObeyCommand(cmd_LaunchCalendar, NULL); } // check to see if we need to launch AOL Instant Messenger at startup if (PREF_GetBoolPref("general.startup.AIM", &startupFlag) == PREF_NOERROR) { if (openStartupWindows && startupFlag) ObeyCommand(cmd_LaunchAOLInstantMessenger, NULL); } #endif // !MOZ_LITE && !MOZ_MEDIUM #ifdef MOZ_TASKBAR if (PREF_GetBoolPref("taskbar.mac.is_open", &startupFlag) == PREF_NOERROR) { if (openStartupWindows && startupFlag) ObeyCommand(cmd_ToggleTaskBar, NULL); } #endif // MOZ_TASKBAR } // OpenDocument asserts that there is a preference document read in, // because we cannot do any document operations before preferences are // initialized. Pref documents are read automatically in assertion // Hyper document is read in here void CFrontApp::OpenDocument( FSSpec* inFileSpec ) { FInfo fndrInfo; short fileType; OSErr err = ::FSpGetFInfo( inFileSpec, &fndrInfo ); //what to do on error? // ¥Êhow silly is this? if ( emPrefsType == fndrInfo.fdType ) fileType = FILE_TYPE_PREFS; else if ( emProfileType == fndrInfo.fdType ) fileType = FILE_TYPE_PROFILES; else if ( 'ASWl' == fndrInfo.fdType ) fileType = FILE_TYPE_ASW; else if ( emLDIFType == fndrInfo.fdType) fileType = FILE_TYPE_LDIF; else if (emNetprofileType == fndrInfo.fdType) fileType = STARTUP_TYPE_NETPROFILE; else fileType = FILE_TYPE_ODOC; ProperStartup( inFileSpec, fileType ); } void CFrontApp::DoOpenDoc( FSSpec* inFileSpec, short fileType ) { switch ( fileType ) { case FILE_TYPE_ODOC: if ( inFileSpec ) OpenLocalURL(inFileSpec ); break; case FILE_TYPE_LDIF: #ifdef MOZ_MAIL_NEWS if (inFileSpec) CAddressBookManager::ImportLDIF(*inFileSpec); break; #endif // MOZ_MAIL_NEWS case FILE_TYPE_PREFS: case FILE_TYPE_PROFILES: break; case FILE_TYPE_GETURL: case FILE_TYPE_NONE: break; } } // Opens up a bookmark file void CFrontApp::OpenBookmarksFile( FSSpec* inFileSpec, CBrowserWindow * /*win*/, Boolean /*delayed*/) { Try_ { vector url(500); OSErr err = ReadBookmarksFile(url, *inFileSpec); ThrowIfOSErr_(err); URL_Struct * request = NET_CreateURLStruct( url.begin(), NET_DONT_RELOAD ); CURLDispatcher::DispatchURL(request, NULL); } Catch_(inErr) {} EndCatch_ } // Opens a local file. If it is a bookmark, load the URL stored in it void CFrontApp::OpenLocalURL( FSSpec* inFileSpec , CBrowserWindow * win, char * mime_type, Boolean delayed) { if (inFileSpec == NULL) return; Boolean dummy, dummy2; // Resolve the aliases OSErr err = ::ResolveAliasFile(inFileSpec,TRUE,&dummy,&dummy2); // If we are a bookmark file, open a bookmark FInfo info; err = ::FSpGetFInfo (inFileSpec, &info); if ((info.fdType == emBookmarkFile) && (mime_type == NULL)) { OpenBookmarksFile( inFileSpec, win, delayed); return; } // If we are a help file, open a help document if ((info.fdType == emHelpType) && (mime_type == NULL)) { char * help_id = NULL; char * map_file_url = CFileMgr::GetURLFromFileSpec(*inFileSpec); DebugStr("\pNot implemented"); //¥¥¥ NET_GetHTMLHelpFileFromMapFile(*CBookmarksContext::GetInstance(), // Will this work? //¥¥¥ map_file_url, help_id, NULL); FREEIF( help_id ); FREEIF( map_file_url ); return; } #ifdef MOZ_MAIL_NEWS // If we are mailbox file at the root of the local mail hierarchy, we can assume that it's an // imported mailbox created by the import module. Then just update the folder tree (the new mailbox // will appear in the folder hierarchy). FSSpec mailFolderSpec = CPrefs::GetFilePrototype(CPrefs::MailFolder); if (mailFolderSpec.vRefNum == inFileSpec->vRefNum && mailFolderSpec.parID == inFileSpec->parID) { Assert_(false); //MSG_UpdateFolderTree(); not checked in yet by phil. return; } #endif //MOZ_MAIL_NEWS // Open it by loading the URL into specified window char* localURL; if (win == NULL) win = CBrowserWindow::FindAndPrepareEmpty(true); if (win != NULL) { localURL = CFileMgr::GetURLFromFileSpec(*inFileSpec); URL_Struct * request = NET_CreateURLStruct (localURL, NET_DONT_RELOAD); if (localURL) XP_FREE(localURL); ThrowIfNil_(request); request->content_type = mime_type; // if (delayed) // win->StartLatentLoading(request); // else // win->StartLoadingURL (request, FO_CACHE_AND_PRESENT); // FIX ME!!! Hook up latent loading!!! CBrowserContext* theContext = (CBrowserContext*)win->GetWindowContext(); theContext->SwitchLoadURL(request, FO_CACHE_AND_PRESENT); } } void CFrontApp::PrintDocument(FSSpec* inFileSpec) { ProperStartup( inFileSpec, FILE_TYPE_ODOC ); PrintDocument( inFileSpec ); } // --------------------------------------------------------------------------- // ¥ ClickMenuBar // --------------------------------------------------------------------------- // Respond to a mouse click in the menu bar. // // Also, we do a targeted update of menus before calling MenuSelect void CFrontApp::ClickMenuBar( const EventRecord& inMacEvent) { StUnhiliteMenu unhiliter; // Destructor unhilites menu title Int32 menuChoice; CTargetedUpdateMenuRegistry::SetCommands(sCommandsToUpdateBeforeSelectingMenu); CTargetedUpdateMenuRegistry::UpdateMenus(); CommandT menuCmd = LMenuBar::GetCurrentMenuBar()-> MenuCommandSelection(inMacEvent, menuChoice); if (menuCmd != cmd_Nothing) { SignalIf_(LCommander::GetTarget() == nil); LCommander::SetUpdateCommandStatus(true); LCommander::GetTarget()->ProcessCommand(menuCmd, &menuChoice); } } // --------------------------------------------------------------------------- // ¥ UpdateMenus // --------------------------------------------------------------------------- // Update the status of all menu items // // General Strategy: // (1) Designate every Menu as "unused". // (2) Iterate through all menu commands, asking the Target chain for // the status of each one. Enable/Disable, mark, and adjust the // name of each menu accordingly. Enabling any item in a Menu // designates that Menu as "used". // (3) Iterate through each menu, asking for the status of a special // synthetic command that indicates the entire menu. At this time, // Commanders can perform operations that affect the menu as a whole. // Menus that are desinated "used" are enabled; "unused" ones // are disabled. // // Changes from LEventDispatcher::UpdateMenus(): // // - We maintain a list of commands to update and a bool to indicate // whether to update just those commands or all commands. This is // useful for targeting specific commands to update without having // to pay the price for updating hundreds of commands. The registry // of commands is maintained separately from CFrontApp. The general // pattern is that the client which calls UpdateMenus will stuff // it's commands in the registry and then call UpdateMenus. // // One limitation of this targeted updating is that it is possible // that a menu which should be disabled because there are no enabled // items might still be enabled. However, given that the typical // // - We call UpdateMenusSelf() to get some more work done. // // - We cache some stuff during UpdateMenus void CFrontApp::UpdateMenus() { #ifdef PROFILE_UPDATE_MENUS StProfileSection profileThis("\pprofile", 1000, 100); #endif // UDesktop::StUseFrontWindowIsModalCache theFrontWindowIsModalCache; #ifdef EDITOR CAutoPtr stCharCache; CEditView *editViewCommander = dynamic_cast(LCommander::GetTarget()); if ( editViewCommander ) stCharCache.reset(new CEditView::StUseCharFormattingCache(*editViewCommander)); #endif LMenuBar *theMenuBar = LMenuBar::GetCurrentMenuBar(); Int16 menuItem; MenuHandle macMenuH = nil; LMenu *theMenu; CommandT theCommand; Boolean isEnabled; Boolean usesMark; Char16 mark; Str255 itemName; LCommander *theTarget = LCommander::GetTarget(); theMenu = nil; // Designate each menu as "unused" while (theMenuBar->FindNextMenu(theMenu)) { theMenu->SetUsed(false); } // Loop thru each menu item that has an // associated command while (theMenuBar->FindNextCommand(menuItem, macMenuH, theMenu, theCommand)) { // Don't change menu item state for // special commands (all negative // values except cmd_UseMenuItem) // or for commands which are not // in the registry when we are // supposed to only update commands // which are in the registry. if ((theCommand > 0 || theCommand == cmd_UseMenuItem) && (!CTargetedUpdateMenuRegistry::UseRegistryToUpdateMenus() || CTargetedUpdateMenuRegistry::CommandInRegistry(theCommand))) { // For commands that depend on the menu // item, get synthetic command number if (theCommand == cmd_UseMenuItem) { theCommand = theMenu->SyntheticCommandFromIndex(menuItem); } // Ask Target if command is enabled, // if the menu item should be marked, // and if the name should be changed isEnabled = false; usesMark = false; itemName[0] = 0; if (theTarget != nil) { theTarget->ProcessCommandStatus(theCommand, isEnabled, usesMark, mark, itemName); } // Adjust the state of each menu item as needed. // Also designate as "used" the Menu containing an // enabled item. if (isEnabled) { ::EnableItem(macMenuH, menuItem); theMenu->SetUsed(true); } else { ::DisableItem(macMenuH, menuItem); } if (usesMark) { ::SetItemMark(macMenuH, menuItem, mark); } if (itemName[0] > 0) { ::SetMenuItemText(macMenuH, menuItem, itemName); } } else if (theCommand < 0 || CTargetedUpdateMenuRegistry::UseRegistryToUpdateMenus()) { // Don't change state of items with // negative command numbers or // when the registry is in use. if (theMenu->ItemIsEnabled(menuItem)) { theMenu->SetUsed(true); } } else { // Item has command number 0 ::DisableItem(macMenuH, menuItem); } } if (theTarget != nil) { // Loop thru each menu theMenu = nil; while (theMenuBar->FindNextMenu(theMenu)) { // The "command" for an entire Menu is the synthetic command // number for item zero (negative number that has the Menu ID // in the high word and 0 in the low word. theCommand = theMenu->SyntheticCommandFromIndex(0); // The Target chain now has the opportunity to do something // to the Menu as a whole, as a call for this special // synthetic command is made only once for each menu. // For example, a text handling Commander could put a check // mark next to the current font in a Fonts menu. // // The isEnabled parameter [outEnabled as an argument to // FindCommandStatus()] should be set to true to enable // a menu that does not contain commands that have // already been explicitly enabled. For example, a Fonts // menu typically has no associated commands (the menu // items all use synthetic commands), so a Commander // must set outEnabled to true when asked the status // of the synthetic command corresponding the Fonts menu. // // The mark information is ignored, as is the itemName. // It would be possible to use the itemName to facilitate // dynamic changing of menu titles. However, this is bad // interface design which we don't want to encourage. isEnabled = false; theTarget->ProcessCommandStatus(theCommand, isEnabled, usesMark, mark, itemName); // Menu is "used" if it contains commands that were // explicity enabled in the loop above, or if this // last call passes back "true" for isEnabled. if (isEnabled) { theMenu->SetUsed(true); } // Enable all "used" Menus and disable "unused" ones // To avoid unnecessary redraws, we invalidate the menu // bar only if a Menu's enableFlags changes (which means // that its state has changed). macMenuH = theMenu->GetMacMenuH(); Uint32 originalFlags = (**macMenuH).enableFlags; if (theMenu->IsUsed()) { ::EnableItem(macMenuH, 0); } else { if (!CTargetedUpdateMenuRegistry::UseRegistryToUpdateMenus()) { // When we are using the registry, it is OK to enable // menus that are now used, but it is inappropriate // to disable menus, since we did not update the command // status of all menu items and therefore we do not have // enough information to disable the whole menu, ::DisableItem(macMenuH, 0); } } if (originalFlags != (**macMenuH).enableFlags) { ::InvalMenuBar(); } } } UpdateMenusSelf(); } void CFrontApp::UpdateMenusSelf() { if (CWindowMenu::sWindowMenu) (CWindowMenu::sWindowMenu)->Update(); if (CHistoryMenu::sHistoryMenu) (CHistoryMenu::sHistoryMenu)->Update(); CBookmarksAttachment::UpdateMenu(); #ifdef EDITOR CToolsAttachment::UpdateMenu(); CRecentEditMenuAttachment::UpdateMenu(); #endif // EDITOR UpdateHierarchicalMenus(); CPaneEnabler::UpdatePanes(); #ifdef MOZ_MAIL_NEWS CMailFolderMixin::UpdateMailFolderMixinsNow(); #endif // MOZ_MAIL_NEWS } void CFrontApp::UpdateHierarchicalMenus() // This is called after LEventDispatcher::UpdateMenus(), and enables parent // items of any used submenu. { if (!LCommander::GetTarget()) return; Int16 menuItem; MenuHandle macMenuH = nil; LMenu *theMenu; CommandT theCommand; LMenuBar *theMenuBar = LMenuBar::GetCurrentMenuBar(); while (theMenuBar->FindNextCommand(menuItem, macMenuH, theMenu, theCommand)) { short menuChar; ::GetItemCmd(macMenuH, menuItem, &menuChar); if (menuChar != hMenuCmd) continue; // We have an item item with the "hierarchical" flag. // If we have a hierarchal menu that HAS a command number (ie CommandFromIndex // returns something greater than zero) then we're going to trust that it // has been properly enabled already. If we don't give the root menu item the // benefit of the doubt then we could end up accidentally enabling it if it has // more than 31 items in its sub menu if (theMenu->CommandFromIndex(menuItem) < 0) { // Find the child menu, see if LEventDispatcher::UpdateMenus() has // marked it as "used", and if so, make sure we enable this item short childMenuID; ::GetItemMark(macMenuH, menuItem, &childMenuID); LMenu* childMenu = theMenuBar->FetchMenu(childMenuID); if (childMenu && childMenu->IsUsed()) { ::EnableItem(macMenuH, menuItem); theMenu->SetUsed(true); } } } // Now make sure entire menus get enabled. while (theMenuBar->FindNextMenu(theMenu)) { macMenuH = theMenu->GetMacMenuH(); Uint32 originalFlags = (**macMenuH).enableFlags; if (theMenu->IsUsed()) ::EnableItem(macMenuH, 0); else ::DisableItem(macMenuH, 0); if (originalFlags != (**macMenuH).enableFlags) ::InvalMenuBar(); } } // CFrontApp::UpdateHierarchicalMenus /* App::::MakeNewDocument Called by PowerPlant when a user chooses "New" Returns a window (which is also a model object) in this case. Will change. Is recordable. */ LModelObject* CFrontApp::MakeNewDocument() { try { enum { kBlankPage, kHomePage, kLastPage }; int32 prefValue = kHomePage; int prefResult = PREF_GetIntPref("browser.startup.page", &prefValue); if (prefResult != PREF_NOERROR) { prefValue = kHomePage; } URL_Struct* theURL; switch (prefValue) { case kBlankPage: theURL = nil; break; case kLastPage: char urlBuffer[1024]; if (GH_GetMRUPage(urlBuffer, 1024)) { theURL = NET_CreateURLStruct(urlBuffer, NET_DONT_RELOAD); } else { theURL = nil; //theURL = NET_CreateURLStruct(urlBuffer, NET_DONT_RELOAD); } break; case kHomePage: default: { CStr255 url = CPrefs::GetString(CPrefs::HomePage); if (url.Length() > 0) theURL = NET_CreateURLStruct(url, NET_DONT_RELOAD); else theURL = nil; } break; } CURLDispatcher::DispatchURL(theURL, NULL, false, true); } catch (...) { } return NULL; } // // ChooseDocument // // Picks a document, and opens it in a window (uses existing window if one is open). This // takes advantage of the new NavigationServices stuff if it is available. // void CFrontApp::ChooseDocument() { static const OSType myTypes[] = { 'TEXT', 'JPEG', 'GIFf'}; UDesktop::Deactivate(); // Always bracket this FSSpec fileSpec; Boolean fileSelected = SimpleOpenDlog ( 3, myTypes, &fileSpec ); if ( fileSelected ) OpenDocument(&fileSpec); UDesktop::Activate(); } // ChooseDocument CFrontApp* CFrontApp::GetApplication() { return sApplication; } // ¥¥ commands void CFrontApp::ProcessCommandStatus(CommandT inCommand,Boolean &outEnabled, Boolean &outUsesMark, Char16 &outMark, Str255 outName) { if (GetState() == programState_Quitting) // If we are quitting, all commands are disabled { outEnabled = FALSE; return; } else LApplication::ProcessCommandStatus(inCommand,outEnabled, outUsesMark,outMark, outName); } //----------------------------------- void CFrontApp::FindCommandStatus( CommandT command, Boolean& enabled, Boolean& usesMark, Char16& mark, Str255 outName ) //----------------------------------- { // Allow only close and quit if memory is low. if (Memory_MemoryIsLow()) { if (command != cmd_Quit) // cmd_Close and cmd_CloseAll will also be avail., from elsewhere. enabled = FALSE; else LDocApplication::FindCommandStatus (command, enabled, usesMark, mark, outName); return; } // Do not enable menus behind modal dialogs if (IsFrontWindowModal()) // Only enable quit when front window is modal { if (command != cmd_Quit) enabled = FALSE; else LDocApplication::FindCommandStatus (command, enabled, usesMark, mark, outName); return; } usesMark = FALSE; switch ( command ) { case cmd_GoForward: if (CApplicationEventAttachment::CurrentEventHasModifiers(optionKey)) { LString::CopyPStr(::GetPString(MENU_FORWARD_ONE_HOST), outName); } else { LString::CopyPStr(::GetPString(MENU_FORWARD), outName); } break; case cmd_GoBack: if (CApplicationEventAttachment::CurrentEventHasModifiers(optionKey)) { LString::CopyPStr(::GetPString(MENU_BACK_ONE_HOST), outName); } else { LString::CopyPStr(::GetPString(MENU_BACK), outName); } break; case cmd_ShowJavaConsole: #if defined (JAVA) usesMark = true; mark = LJ_IsConsoleShowing() ? 0x12 : 0; enabled = mJavaEnabled; #endif /* defined (JAVA) */ #if defined (OJI) usesMark = true; mark = JVM_IsConsoleVisible() ? 0x12 : 0; enabled = mJavaEnabled; #endif /* defined (OJI) */ break; #ifdef EDITOR // case cmd_New_Document_Heirarchical_Menu: case cmd_NewWindowEditor: case cmd_NewWindowEditorIFF: case cmd_New_Document_Template: case cmd_New_Document_Wizard: case cmd_OpenFileEditor: case cmd_EditEditor: #endif // EDITOR #ifdef MOZ_MAIL_NEWS case cmd_MailNewsFolderWindow: case cmd_NewsGroups: // case cmd_GetNewMail: case cmd_Inbox: case cmd_MailNewsSearch: case cmd_MailFilters: case cmd_SearchAddresses: case cmd_AddressBookWindow: case cmd_NewFolder: #endif // MOZ_MAIL_NEWS #if defined(MOZ_MAIL_COMPOSE) || defined(MOZ_MAIL_NEWS) case cmd_NewMailMessage: #endif // MOZ_MAIL_COMPOSE #ifdef EDITOR case cmd_OpenURLEditor: #endif // EDITOR case cmd_BrowserWindow: case cmd_Preferences: case 19896: /*cmd_NetToggle*/ case cmd_OpenURL: // case cmd_EditGeneral: case cmd_EditNetwork: case cmd_EditSecurity: // old mail/news stuff // case cmd_MailWindow: // case cmd_NewsWindow: // case cmd_MailTo: case cmd_CoBrandLogo: case cmd_AboutPlugins: #if 0 case cmd_LaunchCalendar: case cmd_Launch3270: case cmd_LaunchNetcaster: case cmd_LaunchConference: enabled = mConferenceApplicationExists; break; #endif #ifdef FORTEZZA case cmd_FortezzaCard: case cmd_FortezzaChange: case cmd_FortezzaView: case cmd_FortezzaInfo: case cmd_FortezzaLogout: #endif // FORTEZZA enabled = TRUE; break; case cmd_BookmarksWindow: case cmd_HistoryWindow: enabled = !Memory_MemoryIsLow(); break; case cmd_LaunchImportModule: enabled = mImportModuleExists; break; case cmd_New: case cmd_Open: enabled = !Memory_MemoryIsLow(); break; #ifdef MOZ_TASKBAR case cmd_ToggleTaskBar: enabled = TRUE; CTaskBarListener::GetToggleTaskBarWindowMenuItemName(outName); break; #endif // MOZ_TASKBAR #ifdef MOZ_OFFLINE // Online/Offline mode case cmd_ToggleOffline: case cmd_SynchronizeForOffline: enabled = TRUE; UOffline::FindOfflineCommandStatus(command, enabled, outName); break; #endif // MOZ_OFFLINE default: ResIDT menuID; Int16 menuItem; if (IsSyntheticCommand(command, menuID, menuItem) && menuID == cWindowMenuID) // --ML 4.0b2 Disable all Window menu items without a command number // (i.e. Conference, Calendar, IBM, History) enabled = FALSE; // the code below was used ifndef MAILNEWS // else if ((command > cmd_WINDOW_MENU_BASE) && (command < cmd_WINDOW_MENU_BASE_LAST)) // enabled = TRUE; else LDocApplication::FindCommandStatus (command, enabled, usesMark, mark, outName); } } // CFrontApp::FindCommandStatus extern void NET_ToggleTrace(); //----------------------------------- Boolean CFrontApp::ObeyCommand(CommandT inCommand, void* ioParam) //----------------------------------- { Boolean bCommandHandled = true; switch ( inCommand ) { case cmd_BrowserWindow: /* URL_Struct* theURL = NULL; CURLDispatcher* theDispatcher = CURLDispatcher::GetURLDispatcher(); Assert_(theDispatcher != NULL); theDispatcher->DispatchToView(NULL, theURL, FO_CACHE_AND_PRESENT); */ // this code is stolen from the editor button, below! Thanks Kathy! // get the front window so we know if an browser window is already in the front CMediatedWindow *wp, *browserwin; CWindowIterator iterAny(WindowType_Any); iterAny.Next(wp); CWindowIterator iter(WindowType_Browser); iter.Next(browserwin); if (browserwin && (wp == browserwin)) { // count the number of windows; stuff current browser window into browserwin // put the window we want to be frontmost into wp (reuse) // spec says to cycle through all windows of our type so we bring the // backmost-window to the front and push the others down in the stack int numWindows = 1; while (iter.Next(wp)) { numWindows++; browserwin = wp; } if (numWindows == 1) browserwin = NULL; // set to NULL so we create new window below } // if no browser in front window bring the frontmost browser window to front // if browser is in front select the window determined above and we're done! if (browserwin) { browserwin->Show(); browserwin->Select(); break; } else // let's make a new one { MakeNewDocument(); } break; case 19896: /*cmd_NetToggle*/ NET_ToggleTrace(); break; case cmd_ShowJavaConsole: #if defined (JAVA) { if (LJ_IsConsoleShowing()) LJ_HideConsole(); else LJ_ShowConsole(); } #endif /* defined (JAVA) */ #if defined (OJI) JVM_ToggleConsole(); #endif /* defined (OJI) */ break; case cmd_HistoryWindow: { CNavCenterWindow* navCenter = dynamic_cast(URobustCreateWindow::CreateWindow(CNavCenterWindow::res_ID, this)); RDF_Resource top = RDF_GetResource(NULL, "NC:History", false); navCenter->BuildHTPane ( top ); navCenter->Show(); } break; case cmd_BookmarksWindow: { CNavCenterWindow* navCenter = dynamic_cast(URobustCreateWindow::CreateWindow(CNavCenterWindow::res_ID, this)); RDF_Resource top = RDF_GetResource(NULL, "NC:Bookmarks", false); navCenter->BuildHTPane ( top ); navCenter->Show(); } break; case cmd_NCOpenNewWindow: { HT_Resource node = reinterpret_cast(ioParam); if ( node ) { CNavCenterWindow* navCenter = dynamic_cast(URobustCreateWindow::CreateWindow(CNavCenterWindow::res_ID, this)); navCenter->BuildHTPane ( node ); navCenter->Show(); } } break; #if defined(MOZ_MAIL_COMPOSE) || defined(MOZ_MAIL_NEWS) case cmd_NewMailMessage: MSG_MailDocument(NULL); break; #endif // MOZ_MAIL_COMPOSE || MOZ_MAIL_NEWS case cmd_OpenURL: DoOpenURLDialog(); break; #ifdef EDITOR case cmd_OpenURLEditor: DoOpenURLDialogInEditor(); break; case cmd_New_Document_Template: { CStr255 urlString = CPrefs::GetString(CPrefs::EditorNewDocTemplateLocation); if ( urlString != CStr255::sEmptyString ) { URL_Struct* theURL = NET_CreateURLStruct(urlString, NET_DONT_RELOAD); if (theURL) CURLDispatcher::DispatchURL(theURL, NULL, false, true); } } break; case cmd_New_Document_Wizard: char* url; if (PREF_CopyConfigString("internal_url.page_from_wizard.url", &url) == PREF_NOERROR) { URL_Struct* theURL = NET_CreateURLStruct(url, NET_DONT_RELOAD); if (theURL) CURLDispatcher::DispatchURL(theURL, NULL, false, true); } break; case cmd_NewWindowEditorIFF: { // get the front window so we know if an editor window is already in the front CMediatedWindow *wp, *editwin; CWindowIterator iterAny(WindowType_Any); iterAny.Next(wp); CWindowIterator iter(WindowType_Editor); iter.Next(editwin); if ( editwin && ( wp == editwin ) ) { // count the number of windows; stuff current editor window into editwin // put the window we want to be frontmost into wp (reuse) // spec says to cycle through all windows of our type so we bring the // backmost-window to the front and push the others down in the stack int numWindows = 1; while ( iter.Next(wp) ) { numWindows++; editwin = wp; } if ( numWindows == 1 ) editwin = NULL; // set to NULL so we create new window below } // if no editor in front window bring the frontmost editor window to front // if editor is in front select the window determined above and we're done! if ( editwin ) { editwin->Show(); editwin->Select(); break; } // else continue below } case cmd_NewWindowEditor: CEditorWindow::MakeEditWindow( NULL, NULL ); break; case cmd_OpenFileEditor: { // StandardFileReply myReply; static const OSType myTypes[] = { 'TEXT'}; UDesktop::Deactivate(); // Always bracket this FSSpec fileSpec; Boolean fileSelected = SimpleOpenDlog ( 1, myTypes, &fileSpec ); UDesktop::Activate(); if (!fileSelected) return TRUE; // we handled it... we just didn't do anything! char* localURL = CFileMgr::GetURLFromFileSpec(fileSpec); if (localURL == NULL) return TRUE; NET_cinfo *cinfo = NET_cinfo_find_type (localURL); if (cinfo && cinfo->type && (!strcasecomp (cinfo->type, TEXT_HTML) || !strcasecomp (cinfo->type, UNKNOWN_CONTENT_TYPE) || !strcasecomp (cinfo->type, TEXT_PLAIN))) { URL_Struct * request = NET_CreateURLStruct ( localURL, NET_NORMAL_RELOAD ); if ( request ) CEditorWindow::MakeEditWindow( NULL, request ); } else { ErrorManager::PlainAlert( NOT_HTML ); } XP_FREE(localURL); } break; case cmd_EditEditor: CPrefsDialog::EditPrefs( CPrefsDialog::eExpandEditor, PrefPaneID::eEditor_Main, CPrefsDialog::eIgnore); break; #endif case cmd_Preferences: CPrefsDialog::EditPrefs(); break; #ifdef MOZ_MAIL_NEWS case cmd_NewsGroups: case cmd_MailNewsFolderWindow: { CMailNewsFolderWindow::FindAndShow(true, inCommand); break; } case cmd_GetNewMail: // If it came here, we must assume there are no mail/news windows. // So open the inbox First. CThreadWindow* tw = CThreadWindow::ShowInbox(cmd_GetNewMail); break; case cmd_Inbox: CThreadWindow::ShowInbox(cmd_Nothing); break; case cmd_MailTo: { MSG_Mail(NULL); // Crashes now, libmsg error } break; #endif // MOZ_MAIL_NEWS case cmd_AboutPlugins: DoGetURL( "about:plugins" ); break; #if 0 case cmd_LaunchConference: LaunchExternalApp(kConferenceAppSig, CONFERENCE_APP_NAME); break; // --ML Polaris case cmd_LaunchCalendar: LaunchExternalApp(kCalendarAppSig, CALENDAR_APP_NAME); break; case cmd_Launch3270: Launch3270Applet(); break; case cmd_LaunchNetcaster: LaunchNetcaster(); break; #endif case cmd_LaunchImportModule: LaunchExternalApp(kImportAppSig, IMPORT_APP_NAME); break; case cmd_LaunchAOLInstantMessenger: LaunchExternalApp(kAOLInstantMessengerSig, AIM_APP_NAME); break; #ifdef FORTEZZA case cmd_FortezzaCard: SSL_FortezzaMenu(NULL,SSL_FORTEZZA_CARD_SELECT); break; case cmd_FortezzaChange: // er, excuse me, mr fortezza, but CHyperWin::Show() might return NULL.... CHyperWin* win = GetFrontHyperWin(); if (win) SSL_FortezzaMenu(win->fHyperView->GetContext(),SSL_FORTEZZA_CHANGE_PERSONALITY); break; case cmd_FortezzaView: CHyperWin* win = GetFrontHyperWin(); if (win) SSL_FortezzaMenu(win->fHyperView->GetContext(),SSL_FORTEZZA_VIEW_PERSONALITY); break; case cmd_FortezzaInfo: SSL_FortezzaMenu(NULL,SSL_FORTEZZA_CARD_INFO); break; case cmd_FortezzaLogout: /* sBookMarkContext */ SSL_FortezzaMenu(NULL,SSL_FORTEZZA_LOGOUT); break; #endif #ifdef MOZ_MAIL_NEWS // This really shouldn't be here, but since the mail/news windows are not up yet, // it's here for testing case cmd_MailNewsSearch: CSearchWindowManager::ShowSearchWindow(); break; case cmd_MailFilters: CFiltersWindowManager::ShowFiltersWindow(); break; case cmd_AddressBookWindow: CAddressBookManager::ShowAddressBookWindow(); break; case cmd_NewFolder: { CMessageFolder folder(nil); UFolderDialogs::ConductNewFolderDialog(folder); break; } // case cmd_SearchAddresses: // CSearchWindowManager::ShowSearchAddressesWindow(); // break; #endif // MOZ_MAIL_NEWS #ifdef MOZ_TASKBAR case cmd_ToggleTaskBar: CTaskBarListener::ToggleTaskBarWindow(); break; #endif // MOZ_TASKBAR #ifdef MOZ_OFFLINE // Online/Offline mode case cmd_ToggleOffline: UOffline::ObeyToggleOfflineCommand(); break; case cmd_SynchronizeForOffline: UOffline::ObeySynchronizeCommand(); break; #endif // MOZ_OFFLINE default: { // Spinning icon if ( inCommand == LOGO_BUTTON || inCommand == cmd_CoBrandLogo ) DoOpenLogoURL( inCommand ); else if (!CWindowMenu::ObeyWindowCommand(inCommand)) { ResIDT menuID = ( HiWord( -inCommand ) ); Int16 itemNum = ( LoWord( -inCommand ) ); if ( menuID == kHMHelpMenuID ) { itemNum -= sHelpMenuOrigLength; DoHelpMenuItem( itemNum ); } else bCommandHandled = LDocApplication::ObeyCommand(inCommand, ioParam); } break; } } // switch return bCommandHandled; } // CFrontApp::ObeyCommand //----------------------------------- void CFrontApp::DoOpenDirectoryURL( CommandT menuCommand ) //----------------------------------- { #if 0 CStr255 urlString; Boolean isMenuCommand = (menuCommand >= DIR_MENU_BASE); short stringID = isMenuCommand ? DIR_MENU_BASE : DIR_BUTTON_BASE; char* url; if ( PREF_CopyIndexConfigString( isMenuCommand ? "menu.places.item" : "toolbar.places.item", menuCommand - stringID, "url", &url) == PREF_NOERROR ) { DoGetURL(url); XP_FREE(url); } #endif } void CFrontApp::DoOpenLogoURL( CommandT menuCommand ) { // Admin Kit: Handle co-brand button char* url; if ( menuCommand == LOGO_BUTTON && PREF_CopyConfigString("toolbar.logo.url", &url) == PREF_NOERROR ) { DoGetURL(url); XP_FREE(url); } else { StringHandle handle = GetString( LOGO_BUTTON_URL_RESID ); CStr255 urlString = *((unsigned char**)handle); if ( urlString != CStr255::sEmptyString ) DoGetURL( (unsigned char*)urlString ); } } void CFrontApp::DoWindowsMenu(CommandT inCommand) { Int32 index = inCommand - cmd_WINDOW_MENU_BASE; LWindow * win; if (fWindowsMenu.FetchItemAt(index, &win)) win->Select(); } // DoGetURL loads the given url into the frontmost window, or new one if there is no frontmost // Provides a bottleneck for UI generated requests to load a URL void CFrontApp::DoGetURL( const cstring & url, const char* inReferrer, const char* inTarget ) { // Check for kiosk mode and bail if it's set so that the user can't manually // go to a different URL. Note that this does NOT prevent dispatching to a different // URL from the content. if (CAppleEventHandler::GetKioskMode() == KioskOn) return; if (CFrontApp::GetApplication()->HasProperlyStartedUp()) { // HT may want a crack at this URL for handling ftp/aft/etc. If it doesn't want it, // do the normal dispatch. It's ok to call this again after calling // URDFUtilities::LaunchNode(). Both are quick. (pinkerton) if ( !URDFUtilities::LaunchURL(url) ) { URL_Struct* theURL = NET_CreateURLStruct(url, NET_DONT_RELOAD); if (theURL) { if ( inTarget ) theURL->window_target = strdup(inTarget); if ( inReferrer ) theURL->referer = strdup(inReferrer); CURLDispatcher::DispatchURL(theURL, NULL); } } } } //----------------------------------------------------------------------------- // Chenge of address // AppleEvents has moved to CAppleEventHandler.cp // C Hull //----------------------------------------------------------------------------- /*------------------------------------------------ AppleEvent Dispach Here In: & AppleEvent/ Evenc coming in & ReplyEvent/ Reply event back to sender & Descriptor/ Not sure why this was extracted, but OK. AppleEvent/ ID The event Out: Event Handled by the sAppleEvents entity ------------------------------------------------*/ void CFrontApp::HandleAppleEvent( const AppleEvent& inAppleEvent, AppleEvent& outAEReply, AEDesc& outResult, long inAENumber) { XP_TRACE(("Handling event %d", inAENumber)); Try_ { if ( CAppleEventHandler::sAppleEventHandler == NULL ) new CAppleEventHandler; ThrowIfNil_(CAppleEventHandler::sAppleEventHandler); CAppleEventHandler::sAppleEventHandler->HandleAppleEvent(inAppleEvent, outAEReply, outResult, inAENumber); } Catch_( inErr ) {} EndCatch_ } void CFrontApp::GetAEProperty(DescType inProperty, const AEDesc &inRequestedType, AEDesc &outPropertyDesc) const { try { if (CAppleEventHandler::sAppleEventHandler == NULL) new CAppleEventHandler; ThrowIfNil_(CAppleEventHandler::sAppleEventHandler); CAppleEventHandler::sAppleEventHandler->GetAEProperty(inProperty, inRequestedType, outPropertyDesc); } catch(...) {} } void CFrontApp::SetAEProperty(DescType inProperty, const AEDesc &inRequestedType, AEDesc &outPropertyDesc) { try { if (CAppleEventHandler::sAppleEventHandler == NULL) new CAppleEventHandler; ThrowIfNil_(CAppleEventHandler::sAppleEventHandler); CAppleEventHandler::sAppleEventHandler->SetAEProperty(inProperty, inRequestedType, outPropertyDesc); } catch(...) {} } //----------------------------------------------------------------------------- // Printing //----------------------------------------------------------------------------- //----------------------------------- void CFrontApp::SetupPage() //----------------------------------- { THPrint hPrintRec; Boolean havePrinter; hPrintRec = CPrefs::GetPrintRecord(); havePrinter = hPrintRec != 0; if (havePrinter) { UPrintingMgr::ValidatePrintRecord( hPrintRec ); if ( UPrintingMgr::OpenPrinter() ) { UDesktop::Deactivate(); UHTMLPrinting::OpenPageSetup( hPrintRec ); UDesktop::Activate(); UPrintingMgr::ClosePrinter(); } else havePrinter = false; } if ( !havePrinter ) FE_Alert( NULL, GetPString ( NO_PRINTER_RESID ) ); } // CFrontApp::SetupPage //----------------------------------------------------------------------------- // Menubar management //----------------------------------------------------------------------------- void CFrontApp::SetMenubar( ResIDT mbar, Boolean inUpdateNow ) { fWantedMbar = mbar; if (inUpdateNow) { UpdateMenus(); } } void CFrontApp::InstallMenus() { // Menu creation must go here, because until now, the menu bar has not // been created. (see LApplication::Run()) CHistoryMenu* historyMenu = new CHistoryMenu(cHistoryMenuID); CWindowMenu* windowMenu = new CWindowMenu(cWindowMenuID); // create CNSMenuBarManager new CNSMenuBarManager(CWindowMediator::GetWindowMediator()); LMenuBar::GetCurrentMenuBar()->InstallMenu(historyMenu, InstallMenu_AtEnd); CBookmarksAttachment::InstallMenus(); LMenuBar::GetCurrentMenuBar()->InstallMenu(windowMenu, InstallMenu_AtEnd); CWindowMediator::GetWindowMediator()->AddListener(windowMenu); // Admin Kit friendly Help and Places menus: labels and URLs are // initialized in config.js and may be overridden by config file. MenuHandle balloonMenuH; HMGetHelpMenuHandle( &balloonMenuH ); if ( balloonMenuH ) { sHelpMenuOrigLength = CountMItems(balloonMenuH); sHelpMenuItemCount = BuildConfigurableMenu( balloonMenuH, "menu.help.item", HELP_URLS_MENU_STRINGS ); } /* NOTE: Places menu is installed in CBookmarksAttachment::InstallMenus(), which calls back to BuildConfigurableMenu. */ } int CFrontApp::BuildConfigurableMenu(MenuHandle menu, const char* xp_name, short stringsID) { CStr255 entry; short i; // Append configurable items first for (i = 1; i <= 25; i++) { char* label; if ( PREF_CopyIndexConfigString(xp_name, i - 1, "label", &label) == PREF_NOERROR ) { entry = label; XP_FREE(label); if (entry.IsEmpty()) // blank entry marks end of menu break; StripChar(entry, '&'); // strip ampersands from label AppendMenu(menu, entry); } else break; } // Then append fixed items, if any (i.e. About Netscape) if (stringsID > 0) { CStringListRsrc menuStrings( stringsID ); for (short j = 1; j < menuStrings.CountStrings() + 1; j++) { menuStrings.GetString( j, entry ); AppendMenu(menu, entry); } } return i - 1; } void CFrontApp::DoHelpMenuItem( short itemNum ) { // use configurable URL if defined, else use built-in URL char* url; if ( itemNum <= sHelpMenuItemCount && PREF_CopyIndexConfigString("menu.help.item", itemNum - 1, "url", &url) == PREF_NOERROR ) { DoGetURL( url ); XP_FREE(url); } else { CStr255 urlString; GetIndString( urlString, HELP_URLS_RESID, itemNum - sHelpMenuItemCount ); if ( urlString != CStr255::sEmptyString ) DoGetURL( (unsigned char*)urlString ); } } extern pascal long MDEF_MenuKey( long theMessage, short theModifiers, MenuHandle hMenu ); //----------------------------------- void CFrontApp::EventKeyDown( const EventRecord& inMacEvent ) // ¥ we override this to patch Mercutio in //----------------------------------- { CommandT keyCommand = cmd_Nothing; Int32 menuChoice = 0; // Remap function keys. Is there a better way? jrm 97/04/03 switch ((inMacEvent.message & keyCodeMask) >> 8) { case vkey_F1: keyCommand = cmd_Undo; break; case vkey_F2: keyCommand = cmd_Cut; break; case vkey_F3: keyCommand = cmd_Copy; break; case vkey_F4: keyCommand = cmd_Paste; break; default: // Modal dialogs might have OK/cancel buttons, and handle their own keys. // So only convert to command when front window is not modal if ((inMacEvent.modifiers & cmdKey) && (inMacEvent.message & charCodeMask) == '.') { if (!IsFrontWindowModal()) keyCommand = cmd_Stop; } // Check if the keystroke is a Menu Equivalent else if (LMenuBar::GetCurrentMenuBar()->CouldBeKeyCommand(inMacEvent)) { CTargetedUpdateMenuRegistry::SetCommands(CFrontApp::GetCommandsToUpdateBeforeSelectingMenu()); CTargetedUpdateMenuRegistry::UpdateMenus(); menuChoice = MDEF_MenuKey( inMacEvent.message, inMacEvent.modifiers, ::GetMenu( 666 ) ); // If menuChoice is 0, then a modifer key may have been held down that // didn't map to a known command-key equivalent (e.g. cmd-opt-n). // In this case, we will try again with just the cmdKey. Recall that // this is what the Finder does (with cmd-n for New Folder, for instance). // It makes especially good sense when you think about the fact that since // the command and option keys are close, users sometimes accidently hit both. // Without this "fix", cmd_Nothing would be returned. if (menuChoice == 0) { EventModifiers modifiers = cmdKey; menuChoice = MDEF_MenuKey(inMacEvent.message, modifiers, ::GetMenu( 666 )); } if ( HiWord( menuChoice ) != 0 ) keyCommand = LMenuBar::GetCurrentMenuBar()->FindCommand( HiWord(menuChoice), LoWord(menuChoice)); } } SignalIf_(LCommander::GetTarget() == nil); // Don't allow quit events if it isn't safe to quit but remember the request if ((keyCommand == cmd_Quit) && !fSafeToQuit) { keyCommand = cmd_Nothing; fUserWantsToQuit = true; } if (keyCommand != cmd_Nothing) { LCommander::SetUpdateCommandStatus( true ); LCommander::GetTarget()->ProcessCommand(keyCommand, &menuChoice); ::HiliteMenu( 0 ); } else LCommander::GetTarget()->ProcessKeyPress(inMacEvent); } // CFrontApp::EventKeyDown //----------------------------------------------------------------------------- // About Box & Splash Screen //----------------------------------------------------------------------------- void CFrontApp::ShowAboutBox() { DoGetURL( "about:" ); } void* FE_AboutData( const char* which, char** data_ret, int32* length_ret, char** content_type_ret ) { char* ss = NULL; // security string, of course Handle data = NULL; try { // Nuke the ismap portion so we can hide the url const char* ismap = strrchr( (char*)which, '?' ); CStr255 dataName = which ? which : ""; if ( ismap ) { ismap++; for ( int i = 1; i <= dataName.Length(); i++ ) if (dataName[i] == '?') { dataName[0] = i - 1; break; } } Boolean doSprintf = FALSE; /* about: 128 text of about box, includes logo about:logo 129 picture for about box about:plugins 130 list of installed plug-ins about:authors 131 text for authors box about:authors? 132 text for team box about:teamlogo 133 picture for team box about:mailintro 134 about:rsalogo 135 picture for rsa logo about:mozilla 136 mozilla easter egg about:hype 137 hype sound about:license 2890 license text */ if ( dataName == "" ) { data = ::GetResource( 'TEXT', ABOUT_ABOUTPAGE_TEXT ); *content_type_ret = TEXT_MDL; doSprintf = true; } else if ( dataName == "logo" ) { data = ::GetResource ( 'Tang', ABOUT_BIGLOGO_TANG ); *content_type_ret = IMAGE_GIF; } else if ( dataName == "plugins" ) { data = ::GetResource ( 'TEXT', ABOUT_PLUGINS_TEXT ); *content_type_ret = TEXT_MDL; } else if ( dataName == "authors" ) { data = ::GetResource ( 'TEXT', ABOUT_AUTHORS_TEXT ); *content_type_ret = TEXT_MDL; } else if ( dataName == "mailintro" ) { data = ::GetResource( 'TEXT', ABOUT_MAIL_TEXT ); *content_type_ret = TEXT_MDL; } else if ( dataName == "rsalogo" ) { data = ::GetResource ('Tang', ABOUT_RSALOGO_TANG); *content_type_ret = IMAGE_GIF; } else if ( dataName == "javalogo" ) { data = ::GetResource ('Tang', ABOUT_JAVALOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "qtlogo") { data = ::GetResource ('Tang', ABOUT_QTLOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "insologo") { data = ::GetResource ('Tang', ABOUT_INSOLOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "litronic") { data = ::GetResource ('Tang', ABOUT_LITRONIC_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "mclogo") { data = ::GetResource ('Tang', ABOUT_MCLOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "mmlogo") { data = ::GetResource ('Tang', ABOUT_MMLOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "ncclogo") { data = ::GetResource ('Tang', ABOUT_NCCLOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "odilogo") { data = ::GetResource ('Tang', ABOUT_ODILOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "symlogo") { data = ::GetResource ('Tang', ABOUT_SYMLOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "tdlogo") { data = ::GetResource ('Tang', ABOUT_TDLOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "visilogo") { data = ::GetResource ('Tang', ABOUT_VISILOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "visilogo") { data = ::GetResource ('Tang', ABOUT_VISILOGO_TANG); *content_type_ret = IMAGE_GIF; } else if (dataName == "coslogo") { data = ::GetResource ('Tang', ABOUT_COSLOGO_TANG); *content_type_ret = IMAGE_JPG; } #ifdef FORTEZZA else if (dataName == "litronic") { data = ::GetResource ('Tang', ABOUT_LITRONIC_TANG); *content_type_ret = IMAGE_GIF; } #endif else if (dataName == "mozilla") { data = ::GetResource ( 'TEXT', ABOUT_MOZILLA_TEXT ); *content_type_ret = TEXT_MDL; } else if (dataName == "hype") { data = ::GetResource ( 'Tang', ABOUT_HYPE_TANG ); *content_type_ret = AUDIO_BASIC; } else if ( dataName == "license" ) { data = ::GetResource ('TEXT', ABOUT_LICENSE); *content_type_ret = TEXT_PLAIN; } else if ( dataName == "custom" ) // optional resource added by EKit { data = ::GetResource ( 'TEXT', ABOUT_CUSTOM_TEXT ); *content_type_ret = TEXT_PLAIN; } #ifdef EDITOR else if ( dataName == "editfilenew" ) { data = ::GetResource ( 'TEXT', ABOUT_NEW_DOCUMENT ); *content_type_ret = TEXT_HTML; } #endif else if ( dataName == "flamer" ) { data = ::GetResource ('Tang', ABOUT_MOZILLA_FLAME); *content_type_ret = IMAGE_GIF; } else if ( dataName == "history.gif" ) // NavCenter GIFs { data = ::GetResource ('Tang', ABOUT_HISTORYGIF_TANG); *content_type_ret = IMAGE_GIF; } else if ( dataName == "personal.gif" ) { data = ::GetResource ('Tang', ABOUT_PERSONALGIF_TANG); *content_type_ret = IMAGE_GIF; } else if ( dataName == "search.gif" ) { data = ::GetResource ('Tang', ABOUT_SEARCHGIF_TANG); *content_type_ret = IMAGE_GIF; } else if ( dataName == "sitemap.gif" ) { data = ::GetResource ('Tang', ABOUT_SITEMAPGIF_TANG); *content_type_ret = IMAGE_GIF; } else if ( dataName == "file.gif" ) { data = ::GetResource ('Tang', ABOUT_FILESGIF_TANG); *content_type_ret = IMAGE_GIF; } else if ( dataName == "guide.gif" ) { data = ::GetResource ('Tang', ABOUT_GUIDEGIF_TANG); *content_type_ret = IMAGE_GIF; } else { data = ::GetResource ('TEXT', ABOUT_BLANK_TEXT); *content_type_ret = TEXT_MDL; } // prepare the arguments and return if ( data ) { UInt32 dataSize; ::DetachResource( data ); ::HNoPurge( data ); ::MoveHHi( data ); dataSize = GetHandleSize(data); if ( doSprintf ) { // Security stuff ( 3 strings -> 1 ). |s1| and |s2| may be NULL if we are running with // Mozilla (no security). PR_smprintf() won't die unless |s0| is null, so we check for that. char* s0 = (char *)GetCString(SECURITY_LEVEL_RESID ); char* s1 = SECNAV_SecurityVersion( PR_TRUE ); char* s2 = SECNAV_SSLCapabilities(); ThrowIfNil_(s0); CAutoPtrXP secStr = PR_smprintf( s0, s1, s2 ); ThrowIfNil_(secStr.get()); // Version CStr255 vers; ::GetIndString( vers, ID_STRINGS, APPVERSION_STRING_INDEX ); // Assure that data terminates with nul by appending the NULL string { dataSize += 1; SetHandleSize( data, dataSize); OSErr err = MemError(); ThrowIfOSErr_(err); (*data)[dataSize-1] = '\0'; } // Create the final string ::HLock(data); CAutoPtrXP finalStr = PR_smprintf((char*)*data, (char*)vers, (char*)vers, (char*)secStr.get()); ::HUnlock(data); ThrowIfNil_(finalStr.get()); // Make handle out of final string dataSize = strlen(finalStr.get()) + 1; Handle finalHandle = ::NewHandle( dataSize ); ThrowIfNil_(finalHandle); ::BlockMoveData( finalStr.get(), *finalHandle, dataSize ); // Exchange ::DisposeHandle(data); data = finalHandle; } *data_ret = *data; *length_ret = dataSize; } else { XP_ASSERT(0); *data_ret = NULL; *length_ret = 0; *content_type_ret = NULL; } } catch(...) { Assert_(false); if (data != NULL) { ::DisposeHandle(data); data = NULL; } if (ss != NULL) XP_FREE(ss); *data_ret = NULL; *length_ret = 0; *content_type_ret = NULL; } if (data) ::HLock(data); return data; } void FE_FreeAboutData( void* data, const char* /*which*/ ) { if ( !data ) return; Handle h = (Handle)data; DisposeHandle( h ); } // =========================================================================== // ¥ Main Program // =========================================================================== XP_BEGIN_PROTOS OSErr InitLibraryManager(size_t poolsize, int zoneType, int memType); void CleanupLibraryManager(void); XP_END_PROTOS extern void Memory_DoneWithMemory(); extern UInt8 MemoryCacheFlusher(size_t size); extern void PreAllocationHook(void); const Size cSystemHeapFudgeFactor = 96 * 1024; void main( void ) { SetDebugThrow_(debugAction_Nothing); #ifdef DEBUG //SetDebugSignal_(debugAction_SourceDebugger); // SysBreak broken in MetroNub 1.3.2 SetDebugSignal_(debugAction_LowLevelDebugger); #else SetDebugSignal_(debugAction_Nothing); #endif CFrontApp* app = NULL; // System Heap check hack Handle sysHandle = ::NewHandleSys(cSystemHeapFudgeFactor); if (sysHandle) ::DisposeHandle(sysHandle); Size maxBlockSize = ::FreeMemSys(); if (maxBlockSize < cSystemHeapFudgeFactor) ::ExitToShell(); // Initialize the tracing package if we're debugging #ifdef DEBUG XP_TraceInit(); #endif // pkc -- instantiate main thread object. As side effect, NSPR will create new // subheap if this is the first allocation call, ie, if no static initializers // did an allocation. //----------------------------------- // NOTE: SetApplLimit and MaxApplZone are called from NSPR! // in MacintoshInitializeMemory() //----------------------------------- // ¥Êinitialize QuickDraw UQDGlobals::InitializeToolbox( &qd ); // Preference library needs to be initialized at this point because // the msglib thread constructor is making a prefapi call PREF_Init(NULL); #if __MC68K__ { // Bug #58086: this hack locks the "Enable Java" preference `off' and // must be removed when Java works for 68K. static const char* inline_javascript_text ="lockPref(\"security.enable_java\", false)"; PREF_EvaluateJSBuffer(inline_javascript_text, strlen(inline_javascript_text)); } #else #if !defined (OJI) // ¥ double check to make sure we have Java installed DisableJavaIfNotAvailable(); #endif #endif // NSPR/MOCHA Initialization #ifndef NSPR20 PR_Init("Navigator", 0,0,0); #endif mozilla_thread = PR_CurrentThread(); #ifdef NSPR20 PR_SetThreadGCAble(); #endif // ¥ initialize the memory manager // it's important that this is done VERY early Memory_InitializeMemory(); // ¥Êinit environment and do sanity checking. Will exitToShell if conditions not met. ConfirmWeWillRun(); RNG_RNGInit(); // This needs to be called before the main loop ProcessSerialNumber psn; if (NetscapeIsRunning(psn)) { ErrorManager::PlainAlert(NO_TWO_NETSCAPES_RESID); SetFrontProcess(&psn); } else { #if defined(PROFILE) || defined (PROFILE_LOCALLY) #ifndef DONT_DO_MOZILLA_PROFILE StartProfiling(); #endif #endif // NET_ToggleTrace(); app = new CFrontApp; #if defined(QAP_BUILD) QAP_AssistHook (kQAPAppToForeground, 0, NULL, 0, 0); #endif app->Run(); #if defined(QAP_BUILD) QAP_AssistHook (kQAPAppToBackground, 0, NULL, 0, 0); #endif delete app; #if defined(PROFILE) || defined (PROFILE_LOCALLY) #ifndef DONT_DO_MOZILLA_PROFILE StopProfiling(); #endif #endif } Memory_DoneWithMemory(); // do this at the very end, god knows who's fetching prefs during cleanup PREF_Cleanup(); } static void InitDebugging() { // ¥Êdebugging Setup } static void ConfirmWeWillRun() { UEnvironment::InitEnvironment(); AssertAppearanceLib(); // make sure AppearanceLib is installed AssertRequiredGuts(); } //----------------------------------- static Boolean NetscapeIsRunning(ProcessSerialNumber& psn) // True if other versions of Netscape are running //----------------------------------- { OSErr err; ProcessInfoRec info; ProcessSerialNumber myPsn; ::GetCurrentProcess(&myPsn); psn.highLongOfPSN = 0; psn.lowLongOfPSN = kNoProcess; do { err = GetNextProcess(&psn); if( err == noErr ) { info.processInfoLength = sizeof(ProcessInfoRec); info.processName = NULL; info.processAppSpec = NULL; err= GetProcessInformation(&psn, &info); } if ((err == noErr) && ((psn.highLongOfPSN != myPsn.highLongOfPSN) || (psn.lowLongOfPSN != myPsn.lowLongOfPSN)) && (info.processSignature == emSignature || info.processSignature == 'MOSM')) return TRUE; } while (err == noErr); return FALSE; } //----------------------------------- Boolean CFrontApp::AttemptQuitSelf(long /*inSaveOption*/) //----------------------------------- { #ifdef MOZ_OFFLINE XP_Bool value; PREF_GetBoolPref("offline.prompt_synch_on_exit", &value); if (value) { // Put up dialog StDialogHandler aHandler(20004, NULL); LWindow* dialog = aHandler.GetDialog(); // Get the window title to use later in the progress dialog. Str255 windowTitle; dialog->GetDescriptor(windowTitle); // Run the dialog MessageT message; do { message = aHandler.DoDialog(); } while ((message != 'Yes ') && (message != 'No ') && (message != msg_Cancel)); // Use the result if (message == 'Yes ') UOffline::ObeySynchronizeCommand(UOffline::syncModal); if (message == msg_Cancel) return false; } #endif // MOZ_OFFLINE return true; } //----------------------------------- void CFrontApp::DoQuit( Int32 inSaveOption) //----------------------------------- { LDocApplication::DoQuit(inSaveOption); if (mState == programState_Quitting) CDeferredTaskManager::DoQuit(inSaveOption); // if (mState == programState_Quitting) // LTSMSupport::DoQuit(inSaveOption); } //----------------------------------- void CFrontApp::DispatchEvent( const EventRecord& inMacEvent) // From IM-Text 7-22 //----------------------------------- { try { try { if(! LTSMSupport::TSMEvent(inMacEvent)) LDocApplication::DispatchEvent(inMacEvent); } catch (int err) // some people do throw-em! Also "throw memFullErr" will come here. { throw (OSErr)err; } } // Here we catch anything thrown from anywhere. (OSErr and ExceptionCode). // STR# 7098 is reserved for just this purpose. See ns/cmd/macfe/restext/macfe.r // These alerts all use ALRT_ErrorOccurred. See ns/cmd/macfe/rsrc/MacDialogs.rsrc. // The value of ALRT_ErrorOccurred is in reserr.h // The alert says // "Your last command could not be completed because " // "(Error code )" catch (OSErr err) { DisplayErrorDialog ( err ); } catch (ExceptionCode err) { DisplayExceptionCodeDialog ( err ); } } // --------------------------------------------------------------------------- // ¥ AdjustCursor // From IM-Text 7-22 // --------------------------------------------------------------------------- void CFrontApp::AdjustCursor( const EventRecord& inMacEvent ) { #if defined (JAVA) if ( UsingCustomAWTFrameCursor() ) return; #endif /* defined (JAVA) */ // Find out where the mouse is WindowPtr macWindowP; Point globalMouse = inMacEvent.where; Int16 thePart = ::FindWindow( globalMouse, &macWindowP ); Boolean useArrow = TRUE; // Assume cursor will be the Arrow LWindow* theWindow = NULL; if ( macWindowP ) { // Mouse is inside a Window theWindow = LWindow::FetchWindowObject( macWindowP ); } if (( theWindow ) && (theWindow->IsActive() || theWindow->HasAttribute(windAttr_GetSelectClick)) && // adjust inactive window if one click away - mjc theWindow->IsEnabled() ) { // Mouse is inside an active and enabled // PowerPlant Window. Let the Window // adjust the cursor shape. // Get mouse location in Port coords Point portMouse = globalMouse; theWindow->GlobalToPortPoint( portMouse ); theWindow->AdjustCursor( portMouse, inMacEvent ); useArrow = FALSE; } if ( useArrow ) { // Window didn't set the cursor // Default cursor is the arrow ::SetCursor( &UQDGlobals::GetQDGlobals()->arrow ); } // // Rather than trying to calculate an accurate mouse region, // we define a region that contains just the one pixel where // the mouse is located. This is quick, and handles the common // case where this application is in the foreground but the user // isn't doing anything. However, any mouse movement will generate // a mouse-moved event. // ::SetRectRgn( mMouseRgnH, globalMouse.h, globalMouse.v, globalMouse.h + 1, globalMouse.v + 1 ); } void CFrontApp::EventSuspend (const EventRecord &inMacEvent) { CSuspenderResumer::Suspend(); #ifdef MOZ_MAIL_NEWS CCheckMailContext::SuspendResume(); // Stop all current notification of mail #endif // MOZ_MAIL_NEWS CPluginView::BroadcastPluginEvent(inMacEvent); // Tell plug-ins about the suspend LDocApplication::EventSuspend(inMacEvent); // Do the suspend #if defined(QAP_BUILD) QAP_AssistHook (kQAPAppToBackground, 0, NULL, 0, 0); #endif #ifdef DAVIDM_SPEED2 SetSleepTime(4); // be more friendly in the background #endif } void CFrontApp::EventResume(const EventRecord &inMacEvent) { CSuspenderResumer::Resume(); LDocApplication::EventResume(inMacEvent); // Do the resume CPluginView::BroadcastPluginEvent(inMacEvent); // Tell plug-ins about the resume #ifdef MOZ_MAIL_NEWS CCheckMailContext::SuspendResume(); // Reset mail notification #endif // MOZ_MAIL_NEWS CInternetConfigInterface::ResumeEvent(); // check is InternetConfig changed #if defined(QAP_BUILD) QAP_AssistHook (kQAPAppToForeground, 0, NULL, 0, 0); #endif #ifdef DAVIDM_SPEED2 SetSleepTime(1); // let's go faster #endif } void CFrontApp::EventKeyUp(const EventRecord &inMacEvent) { // // Pass key ups down to the target if itÕs a plug-in. The static variable // sPluginTarget is maintained by CPluginViews when they become or are no // longer the target. (We know calling ProcessKeyPress for a key up is OK // because CPluginView overrides it.) // CPluginView* pluginTarget = CPluginView::sPluginTarget; if (pluginTarget != NULL && pluginTarget == sTarget) pluginTarget->ProcessKeyPress(inMacEvent); else { /* if it's a CKeyUpReceiver, send the key up. We used to send keyups to * targets if a browser view was on duty, which had two disadvantages: it required * any potential targets in a browser view to handle a key up, and sometimes * the commander chain would be incorrect so key ups were sent to a target in a * view that was not on duty. */ if (dynamic_cast(sTarget)) sTarget->ProcessKeyPress(inMacEvent); /* // Pass key ups down to the target if it has a super commander which is // a browser view. Key up events must be sent to mocha. 1997-02-24 mjc if (CBrowserView::sOnDutyBrowserView != NULL) sTarget->ProcessKeyPress(inMacEvent); */ } } // A C interface to ProcessNextEvent, which needs to be called when waiting for // the .jsc file to load at startup extern "C" { void FEU_StayingAlive(); } void FEU_StayingAlive() { CFrontApp::GetApplication()->ProcessNextEvent(); } void CFrontApp::ProcessNextEvent() { #ifdef PROFILE #ifdef PROFILE_ON_CAPSLOCK if (IsThisKeyDown(0x39)) // caps lock ProfileStart(); else ProfileStop(); #endif // PROFILE_ON_CAPSLOCK #endif // PROFILE #ifdef DAVIDM_SPEED2 static UInt32 sNextWNETicks = 0; const UInt32 kWNETicksInterval = 4; #endif try { // Handle all pending NSPR events PR_ProcessPendingEvents(mozilla_event_queue); } catch (OSErr err) { DisplayErrorDialog ( err ); } catch (ExceptionCode err) { DisplayExceptionCodeDialog ( err ); } // The block surrounded by *** ... from LApplication::ProcessNextEvent() *** // is identical to LApplication::ProcessNextEvent with one exception: // the EventRecord is declared static in order to persist across calls // to ProcessNextEvent to prevent dangling references to the event // recorded by CApplicationEventAttachment (read the usage notes for // CApplicationEventAttachment). // *** Begin block from LApplication::ProcessNextEvent() *** static EventRecord macEvent; Boolean haveUserEvent = true; // so we call WNE every time in the background // When on duty (application is in the foreground), adjust the // cursor shape before waiting for the next event. Except for the // very first time, this is the same as adjusting the cursor // after every event. if (IsOnDuty()) { // Plug-ins and Java need key up events, which are masked by default // (the event mask lomem is set to everyEvent - keyUp). To ensure // that itÕs always set to mask out nothing, reset it here every time // before we call WaitNextEvent. // SetEventMask(everyEvent); // Calling OSEventAvail with a zero event mask will always // pass back a null event. However, it fills the EventRecord // with the information we need to set the cursor shape-- // the mouse location in global coordinates and the state // of the modifier keys. haveUserEvent = ::OSEventAvail(everyEvent, &macEvent); AdjustCursor(macEvent); } #ifdef DAVIDM_SPEED2 #ifndef NSPR20 CSelectObject socketToCallWith; Boolean doWNE = haveUserEvent || ::LMGetTicks() > sNextWNETicks || ( gNetDriver && !gNetDriver->CanCallNetlib(socketToCallWith) ); #else Boolean doWNE = haveUserEvent || ::LMGetTicks() > sNextWNETicks || NET_PollSockets(); #endif // NSPR_20 SetUpdateCommandStatus(false); if ( doWNE ) { #endif // DAVIDM_SPEED2 // Retrieve the next event. Context switch could happen here. #ifdef PROFILE #ifndef PROFILE_WAITNEXTEVENT ProfileSuspend(); #endif // PROFILE_WAITNEXTEVENT #endif // PROFILE Boolean gotEvent = ::WaitNextEvent(everyEvent, &macEvent, mSleepTime, mMouseRgnH); #ifdef PROFILE #ifndef PROFILE_WAITNEXTEVENT ProfileResume(); #endif // PROFILE_WAITNEXTEVENT #endif // PROFILE // Let Attachments process the event. Continue with normal // event dispatching unless suppressed by an Attachment. if (LAttachable::ExecuteAttachments(msg_Event, &macEvent)) { if (gotEvent) { DispatchEvent(macEvent); } else { UseIdleTime(macEvent); } } #ifdef DAVIDM_SPEED2 sNextWNETicks = ::LMGetTicks() + kWNETicksInterval; } #endif // DAVIDM_SPEED2 LPeriodical::DevoteTimeToRepeaters(macEvent); // Update status of menu items if (IsOnDuty() && GetUpdateCommandStatus()) { UpdateMenus(); } // *** End block from LApplication::ProcessNextEvent() *** } void CFrontApp::DoOpenURLDialog(void) { StBlockingDialogHandler theHandler(liLoadItemWind, this); LWindow* theDialog = theHandler.GetDialog(); LEditField* theEdit = (LEditField*)theDialog->FindPaneByID('edit'); Assert_(theEdit != NULL); theDialog->SetLatentSub(theEdit); theDialog->Show(); MessageT theMessage = msg_Nothing; while ((theMessage != msg_Cancel) && (theMessage != msg_OK)) theMessage = theHandler.DoDialog(); if (theMessage == msg_OK) { cstring curl; CStr255 purl; theEdit->GetDescriptor(purl); CleanUpLocationString (purl); curl = (unsigned char*)purl; DoGetURL(curl); } } #ifdef EDITOR void CFrontApp::DoOpenURLDialogInEditor(void) { StBlockingDialogHandler theHandler(liLoadItemWind, this); LWindow* theDialog = theHandler.GetDialog(); LEditField* theEdit = (LEditField*)theDialog->FindPaneByID('edit'); Assert_(theEdit != NULL); theDialog->SetLatentSub(theEdit); theDialog->Show(); MessageT theMessage = msg_Nothing; while ((theMessage != msg_Cancel) && (theMessage != msg_OK)) theMessage = theHandler.DoDialog(); if (theMessage == msg_OK) { cstring curl; CStr255 purl; // we really should try to do better parsing here theEdit->GetDescriptor( purl ); CleanUpLocationString( purl ); curl = (unsigned char*)purl; URL_Struct* theURL = NET_CreateURLStruct( curl, NET_DONT_RELOAD ); if ( theURL ) CEditorWindow::MakeEditWindow( NULL, theURL ); } } #endif // EDITOR void CFrontApp::ShowSplashScreen() { // Register the splash screen first so that we can show it. RegisterClass_(CSplashScreen); RegisterClass_(CResPicture); mSplashScreen = (CSplashScreen*)LWindow::CreateWindow(2891, this); mSplashScreen->Show(); mSplashScreen->UpdatePort(); } void CFrontApp::DestroySplashScreen() { delete mSplashScreen; mSplashScreen = NULL; } void CFrontApp::SplashProgress(CStr255 inMessage) { if (sApplication->mSplashScreen != NULL) sApplication->mSplashScreen->SetDescriptor(inMessage); } //----------------------------------- void CFrontApp::ListenToMessage(MessageT inMessage, void * ioParam) //----------------------------------- { switch (inMessage) { #ifdef MOZ_MAIL_NEWS case cmd_GetNewMail: case cmd_NewsGroups: case cmd_MailNewsFolderWindow: #endif // MOZ_MAIL_NEWS #ifdef EDITOR case cmd_NewWindowEditorIFF: // case cmd_NewMailMessage: #endif // EDITOR #ifdef MOZ_MAIL_NEWS case cmd_ToggleOffline: #endif // MOZ_MAIL_NEWS case cmd_BrowserWindow: ObeyCommand(inMessage); break; case msg_GrowZone: MemoryIsLow(); // 1998.01.12 pchen -- replicate fix for bug #85275 // We don't know how much memory was freed, so just set bytes freed to 0 *((Int32 *)ioParam) = 0; break; default: break; } } void CFrontApp::LaunchExternalApp(OSType inAppSig, ResIDT inAppNameStringResourceID) { Assert_(inAppNameStringResourceID); FSSpec appSpec; OSErr err = CFileMgr::FindApplication(inAppSig, appSpec); CStr255 theAppName(::GetCString(inAppNameStringResourceID)); CStr255 theMessage; if (err == noErr) { ProcessSerialNumber psn; err = UProcessUtils::LaunchApplication( appSpec, launchContinue + launchNoFileFlags, psn); } switch (err) { case noErr: break; case memFullErr: case memFragErr: theMessage = ::GetCString(MEMORY_ERROR_LAUNCH); ::StringParamText(theMessage, theAppName); ErrorManager::PlainAlert(theMessage); break; case fnfErr: theMessage = ::GetCString(FNF_ERROR_LAUNCH); ::StringParamText(theMessage, theAppName); ErrorManager::PlainAlert(theMessage); break; default: theMessage = ::GetCString(MISC_ERROR_LAUNCH); ::StringParamText(theMessage, theAppName); ErrorManager::PlainAlert(theMessage); break; } } #if MOZ_3270_APPLET // Tries to find local file 3270/HE3270EN.HTM Boolean CFrontApp::Find3270Applet(FSSpec& tn3270File) { Boolean found = false; FSSpec appFolder = CPrefs::GetFilePrototype( CPrefs::NetscapeFolder ); CStr255 folderName; ::GetIndString( folderName, 300, ibm3270Folder ); if ( CFileMgr::FindWFolderInFolder(appFolder.vRefNum, appFolder.parID, folderName, &tn3270File.vRefNum, &tn3270File.parID) == noErr ) { ::GetIndString( tn3270File.name, 300, ibm3270File ); found = CFileMgr::FileExists(tn3270File); } return found; } void CFrontApp::Launch3270Applet() { Boolean ok = false; FSSpec tn3270File; if ( Find3270Applet(tn3270File) ) { char* url = CFileMgr::GetURLFromFileSpec(tn3270File); if (url) { // Opens the URL in a new window (copied from DoGetURL) // !! winfe opens a window with no toolbars, if we care. URL_Struct* theURL = NET_CreateURLStruct(url, NET_DONT_RELOAD); if (FE_MakeNewWindow(NULL, theURL, NULL, NULL) != NULL) ok = true; free(url); } } if (!ok) { ErrorManager::PlainAlert(ERROR_LAUNCH_IBM3270); } } #endif /* MOZ_3270_APPLET */ FSSpec CFrontApp::CreateAccountSetupSpec() { FSSpec asw; asw = CPrefs::GetFilePrototype( CPrefs::NetscapeFolder ); ::GetIndString( asw.name, 300, aswName ); return asw; } Boolean CFrontApp::LaunchAccountSetup() { FSSpec tmp = CreateAccountSetupSpec(); LFile aswFile( tmp ); Handle alias; OSErr err; FSSpec startAswFile; Boolean wasChanged; #ifdef DEBUG try { #endif aswFile.OpenResourceFork( fsRdPerm ); #ifdef DEBUG } catch ( ... ) { StandardFileReply reply; AliasHandle alias; SFTypeList types; UDesktop::Deactivate(); ::StandardGetFile( NULL, -1, types, &reply ); UDesktop::Activate(); if ( reply.sfGood ) { LFile startFile( reply.sfFile ); aswFile.CreateNewFile( emSignature, 'ASWl', smSystemScript ); aswFile.OpenResourceFork( fsWrPerm ); alias = startFile.MakeAlias(); if ( alias ) AddResource( (Handle)alias, 'alis', 1, reply.sfFile.name ); aswFile.CloseResourceFork(); aswFile.OpenResourceFork( fsRdPerm ); } } #endif DEBUG alias = ::Get1Resource( 'alis', 1 ); if ( !alias ) return FALSE; err = ::ResolveAlias( NULL, (AliasHandle)alias, &startAswFile, &wasChanged ); if ( err == noErr ) { CFrontApp::GetApplication()->SendAEOpenDoc( startAswFile ); return TRUE; } return FALSE; } #if 0 static void launchNetcasterCallback(void* closure); static void launchNetcasterCallback(void* /*closure*/) { FE_RunNetcaster(NULL); } // Launch Netcaster on a timeout to avoid interfering with other components because // it is slow to start up. void CFrontApp::LaunchNetcaster() { FE_SetTimeout(launchNetcasterCallback, NULL, 0); } // We keep track of the Netcaster context in the app so we can assure ourselves // that only one Netcaster context will be open at any given time. These calls // are used by FE_RunNetcaster to either launch Netcaster (if the netcaster context // is NULL) or to activate its window (if not). The alternative would have been // to use named contexts; the disadvantage is that the Netcaster window could be // spoofed, and that we would have a performance hit whenever the Netcaster object // were referenced (such as from JS). - EA //----------------------------------- MWContext *CFrontApp::GetNetcasterContext() //----------------------------------- { return mNetcasterContext; } //----------------------------------- void CFrontApp::SetNetcasterContext(MWContext *context) //----------------------------------- { mNetcasterContext = context; } #endif // 97-08-23 pchen -- This method should be called when we're "low on memory." // For now, we just call LJ_ShutdownJava(). //----------------------------------- void CFrontApp::MemoryIsLow() //----------------------------------- { #if defined (JAVA) // Call LJ_ShutdownJava() if Java is running if (LJ_GetJavaStatus() == LJJavaStatus_Running) LJ_ShutdownJava(); #endif /* defined (JAVA) */ } #pragma mark - //====================================== // class CSplashScreen //====================================== extern Boolean pref_FindAutoAdminLib(FSSpec& spec); CSplashScreen::CSplashScreen(LStream* inStream) : LWindow(inStream) { mStatusCaption = NULL; mPictureResourceFile = NULL; } CSplashScreen::~CSplashScreen() { ResIDT thePicID = mBackPicture->GetPictureID(); // this returns the picture that has already been loaded by the picture pane PicHandle thePicHandle = ::GetPicture(thePicID); if (thePicHandle != NULL) ::ReleaseResource((Handle)thePicHandle); if (mPictureResourceFile) { mPictureResourceFile->CloseResourceFork(); delete mPictureResourceFile; } } void CSplashScreen::SetDescriptor(ConstStringPtr inDescriptor) { mStatusCaption->SetDescriptor(inDescriptor); // we're relying on the fact that the splash window has erase on // update set so that the old caption gets erased in the window's // background color (which we're assuming to be black) mStatusCaption->UpdatePort(); } void CSplashScreen::FinishCreateSelf(void) { LWindow::FinishCreateSelf(); mStatusCaption = (LCaption*)FindPaneByID(1); Assert_(mStatusCaption != NULL); mBackPicture = (CResPicture*)FindPaneByID(2); Assert_(mBackPicture != NULL); // choose the b/w or color splash screen ResIDT thePicID = (GetDepth(GetDeepestDevice()) == 1) ? 129 : 128; // If AutoAdminLib is installed, then load the Communicator Pro // splash screen from the library's resource fork. // Otherwise, picture comes from app resource. try { FSSpec autoAdminLib; if ( pref_FindAutoAdminLib(autoAdminLib) ) { mPictureResourceFile = new LFile(autoAdminLib); mPictureResourceFile->OpenResourceFork(fsRdPerm); mBackPicture->SetResFileID( mPictureResourceFile->GetResourceForkRefNum() ); } } catch (...) { } mBackPicture->SetPictureID(thePicID); } // // THIS IS HERE ONLY AS A PLACEHOLDER UNTIL I PUT THE NAV-SERVICES CODE INTO THE SOURCE TREE.... // DO NOT RELY ON THIS IMPLEMENTATION OR EVEN THAT THIS ROUTINE USES THE SF PACKAGE // Boolean SimpleOpenDlog ( short numTypes, const OSType typeList[], FSSpec* outFSSpec ) { Boolean fileSelected = false; StandardFileReply myReply; if (CApplicationEventAttachment::CurrentEventHasModifiers(optionKey)) ::StandardGetFile(NULL, numTypes, typeList, &myReply); else ::StandardGetFile(NULL, -1, NULL, &myReply); fileSelected = myReply.sfGood; *outFSSpec = myReply.sfFile; return fileSelected; } // SimpleOpenDialog