diff --git a/mozilla/xpfe/appshell/src/nsCommandLineServiceMac.cpp b/mozilla/xpfe/appshell/src/nsCommandLineServiceMac.cpp index 9eff366ad71..6f32d89babe 100644 --- a/mozilla/xpfe/appshell/src/nsCommandLineServiceMac.cpp +++ b/mozilla/xpfe/appshell/src/nsCommandLineServiceMac.cpp @@ -17,7 +17,8 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Contributor(s): + * Contributor(s): + * Simon Fraser * Pierre Phaneuf */ @@ -43,889 +44,19 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "nsIDOMWindow.h" #include "jsapi.h" +#include "nsAEEventHandling.h" + // NSPR #include "prmem.h" #include "plstr.h" #include "prenv.h" #include "pprio.h" // PR_Init_Log -// Universal -#include -#include -#include -#include -#include // For the display notice event -#include -#include -#include - -// PowerPlant -#ifdef MOZ_POWERPLANT -#include -#include -#endif // MOZ_POWERPLANT - #include "nsAppShellCIDs.h" static NS_DEFINE_IID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID); -// Global buffers for command-line arguments and parsing. -#define MAX_BUF 512 -#define MAX_TOKENS 20 -static char* argBuffer = nsnull; // the command line itself -static char** args = nsnull; // array of pointers into argBuffer - static nsIWebShellWindow* FindWebShellWindow(nsIXULWindowCallbacks* cb); -//======================================================================================== -class nsAppleEventHandler -//======================================================================================== -{ - - -public: - enum KioskEnum - { - KioskOff = 0 - , KioskOn = 1 - }; - - nsAppleEventHandler(); - virtual ~nsAppleEventHandler(); - - static nsAppleEventHandler* Get() - { - if (!sAppleEventHandler) - new nsAppleEventHandler(); - return sAppleEventHandler; - } - - void SetStartedUp(PRBool inStarted) { mStartedUp = inStarted; } - - // --- Top Level Apple Event Handling - - virtual OSErr HandleAppleEvent(const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc &outResult, - SInt32 inAENumber); - virtual OSErr GetAEProperty(DescType inProperty, - const AEDesc &inRequestedType, - AEDesc &outPropertyDesc) const; - virtual OSErr SetAEProperty(DescType inProperty, - const AEDesc &inRequestedType, - AEDesc &outPropertyDesc); - - // --- AEOM support - OSErr GetSubModelByUniqueID(DescType inModelID, - const AEDesc &inKeyData, - AEDesc &outToken) const; - - static KioskEnum GetKioskMode(){return sAppleEventHandler->mKioskMode;} - -private: - - - OSErr HandleAEOpenOrPrintDoc( - const AppleEvent &inAppleEvent, - AppleEvent& outAEReply, - SInt32 inAENumber); - - OSErr HandleOpen1Doc(const FSSpec& inFileSpec, - OSType fileType); - - OSErr HandlePrint1Doc(const FSSpec& inFileSpec, - OSType fileType); - - PRBool EnsureCommandLine(); - - OSErr AddToCommandLine(const char* inArgText); - - OSErr AddToCommandLine(const char* inOptionString, - const FSSpec& inFileSpec); - - void AddToEnvironmentVars(const char* inArgText); - - OSErr DispatchURLToNewBrowser(const char* url); - - OSErr HandleOpenURLEvent(const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc &outResult, - SInt32 inAENumber); -// spy Apple Event suite -// file/URL opening + misc - OSErr HandleGetURLEvent(const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc &outResult, - SInt32 inAENumber); - -// Netscape suite - OSErr HandleDoJavascriptEvent(const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc &outResult, - SInt32 inAENumber); - - static pascal OSErr AppleEventHandler( - const AppleEvent* inAppleEvent, - AppleEvent* outAEReply, - UInt32 inRefCon); - -protected: - KioskEnum mKioskMode; - PRBool mStartedUp; - static nsAppleEventHandler* sAppleEventHandler; // One and only instance of AEvents - -}; // class nsAppleEventHandler - -//======================================================================================== -class MoreExtractFromAEDesc -// Apple event helpers -- extension of UExtractFromAEDesc.h -// All the miscellaneous AppleEvent helper routines. -//======================================================================================== -{ -public: - - // -------------------------------------------------------------- - /* Given an AppleEvent, locate a string given a keyword and - return the string - In: Event to search - AEKeyword assocaated with the string - C string ptr - Out: Pointer to a newly created C string returned */ - // -------------------------------------------------------------- - static void GetCString(const AppleEvent &inAppleEvent, AEKeyword keyword, - char * & s, Boolean inThrowIfError = true); - - // -------------------------------------------------------------- - /* Given an AEDesc of type typeChar, return it's string. - In: AEDesc containing a string - C string ptr - Out: Pointer to a newly created C string returned */ - // -------------------------------------------------------------- - static void TheCString(const AEDesc &inDesc, char * & outPtr); - - // -------------------------------------------------------------- - /* Add an error string and error code to an AppleEvent. - Typically used when constructing the return event when an - error occured - In: Apple Event to append to - Error string - Error code - Out: keyErrorNum and keyErrorSting AEDescs are added to the Event. */ - // -------------------------------------------------------------- - static void MakeErrorReturn(AppleEvent &event, ConstStr255Param errorString, - OSErr errorCode); - - // -------------------------------------------------------------- - /* Display an error dialog if the given AppleEvent contains - a keyErrorNumber. a keyErrorString is optional and will be - displayed if present - In: Apple Event - Out: Error dialog displayed if error data present. */ - // -------------------------------------------------------------- - static Boolean DisplayErrorReply(AppleEvent &reply); - - // -------------------------------------------------------------- - /* Return the process serial number of the sending process. - In: Apple Event send by some app. - Out: ProcessSerialNumber of the sending app. */ - // -------------------------------------------------------------- - static ProcessSerialNumber ExtractAESender(const AppleEvent &inAppleEvent); - - static void DispatchURLDirectly(const AppleEvent &inAppleEvent); -}; // class MoreExtractFromAEDesc - - -//======================================================================================== -class AEUtilities -// Some more simple Apple Event utility routines. -//======================================================================================== -{ -public: - - // -------------------------------------------------------------- - /* CreateAppleEvent - Create a new Apple Event from scratch. - In: Apple Event suite - Apple Event ID - Ptr to return Apple Event - ProcessSerialNumber of the target app to send event to. - Out:A new Apple Event is created. More data may be added to - the event simply by calling AEPutParamDesc or AEPutParamPtr */ - // -------------------------------------------------------------- - static OSErr CreateAppleEvent(OSType suite, OSType id, - AppleEvent &event, ProcessSerialNumber targetPSN); - - // -------------------------------------------------------------- - /* Check to see if there is an error in the given AEvent. - We simply return an OSError equiv to the error value - in the event. If none exists (or an error took place - during access) we return 0. - In: Apple Event to test - Out:Error value returned */ - // -------------------------------------------------------------- - static OSErr EventHasErrorReply(AppleEvent & reply); - -}; // AEUtilities - -//======================================================================================== -// Implementation of nsAppleEventHandler -//======================================================================================== - -#pragma mark - - -nsAppleEventHandler* nsAppleEventHandler::sAppleEventHandler = nsnull; - -//---------------------------------------------------------------------------------------- -nsAppleEventHandler::nsAppleEventHandler() -//---------------------------------------------------------------------------------------- -: mKioskMode(KioskOff) // We assume not operating in kiosk mode unless told otherwise -, mStartedUp(PR_FALSE) -{ - // We're a singleton class - sAppleEventHandler = this; - - // We must not throw out of here. - try - { -#ifdef MOZ_POWERPLANT - UAppleEventsMgr::InstallAEHandlers( - NewAEEventHandlerProc(nsAppleEventHandler::AppleEventHandler)); -#endif - } - catch(...) - { - } -} - -//---------------------------------------------------------------------------------------- -nsAppleEventHandler::~nsAppleEventHandler() -//---------------------------------------------------------------------------------------- -{ - // We're a singleton class - sAppleEventHandler = nsnull; -} - -//---------------------------------------------------------------------------------------- -pascal OSErr nsAppleEventHandler::AppleEventHandler( - const AppleEvent* inAppleEvent, - AppleEvent* outAEReply, - UInt32 inRefCon) -// This is the function that gets installed as the AE callback. -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - // We must not throw out of here. - try - { -#ifdef MOZ_POWERPLANT - StAEDescriptor resultDesc; - err = sAppleEventHandler->HandleAppleEvent( - *inAppleEvent, *outAEReply, resultDesc, inRefCon); -#endif - } - catch(...) - { - err = errAEEventNotHandled; - } - return err; -} // nsAppleEventHandler::AppleEventHandler - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleAppleEvent( - const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc &outResult, - SInt32 inAENumber) -// nsAppleEventHandler::HandleAppleEvent -// AppleEvent Dispach Here -// In: & AppleEvent Incoming apple event -// & ReplyEvent Reply event we can attach result info to -// & Descriptor OUtgoing descriptor -// AppleEvent ID The Apple Event ID we were called with. -// Out: Event Handled by CAppleEvent -//---------------------------------------------------------------------------------------- -{ -#ifdef MOZ_POWERPLANT - OSErr err = errAEEventNotHandled; - switch (inAENumber) - { - case AE_GetURL: - case AE_OpenURL: - case ae_OpenApp: - case ae_OpenDoc: - case ae_PrintDoc: - case ae_Quit: - break; - - default: - // Ignore all apple events handled by this handler except get url, open - // url and the required suite until we have properly started up. - if (!mStartedUp) - return errAEEventNotHandled; - break; - } - - switch (inAENumber) - { - - case ae_OpenApp: - err = noErr; - break; - - case ae_Quit: - { - nsresult rv; - NS_WITH_SERVICE(nsIAppShellService, appShellService, kAppShellServiceCID, &rv); - if (NS_FAILED(rv)) - return errAEEventNotHandled; - appShellService->Quit(); - break; - } - case ae_OpenDoc: - case ae_PrintDoc: - err = HandleAEOpenOrPrintDoc(inAppleEvent, outAEReply, inAENumber); - break; - - // ### Mac URL standard Suite - // ----------------------------------------------------------- - case AE_GetURL: // Direct object - url, cwin - HyperWindow - err = HandleGetURLEvent( inAppleEvent, outAEReply, outResult, inAENumber ); - break; - - // ### Spyglass Suite - // ----------------------------------------------------------- - case AE_OpenURL: - err = HandleOpenURLEvent( inAppleEvent, outAEReply, outResult, inAENumber ); - break; - - - // ### Netscape Experimental Suite - // ----------------------------------------------------------- - case AE_DoJavascript: - err = HandleDoJavascriptEvent( inAppleEvent, outAEReply, outResult, inAENumber ); - break; - - // ### If all else fails behave like a word processor - // ----------------------------------------------------------- - default: - NS_NOTYETIMPLEMENTED("Write Me"); - //CFrontApp::sApplication->LDocApplication::HandleAppleEvent( inAppleEvent, outAEReply, outResult, inAENumber ); - break; - } -#endif - return noErr; -} // nsAppleEventHandler::HandleAppleEvent - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleAEOpenOrPrintDoc( - const AppleEvent &inAppleEvent, - AppleEvent& /* outAEReply */, - SInt32 inAENumber) -//---------------------------------------------------------------------------------------- -{ - AEDescList docList; - OSErr err = ::AEGetParamDesc(&inAppleEvent, keyDirectObject, - typeAEList, &docList); - if (err) return err; - - SInt32 numDocs; - err = ::AECountItems(&docList, &numDocs); - if (err) - goto Clean; - - // Loop through all items in the list - // Extract descriptor for the document - // Coerce descriptor data into a FSSpec - // Dispatch the print or open to the appropriate routine - for (int i = 1; i <= numDocs; i++) - { - AEKeyword keyWord; - DescType descType; - FSSpec spec; - Size theSize; - err = ::AEGetNthPtr(&docList, i, typeFSS, &keyWord, &descType, - (Ptr) &spec, sizeof(FSSpec), &theSize); - if (err) - goto Clean; - - nsFileSpec nsspec(spec); - CInfoPBRec info; - nsspec.GetCatInfo(info); - OSType fileType = info.hFileInfo.ioFlFndrInfo.fdType; -#ifdef MOZ_POWERPLANT - if (inAENumber == ae_OpenDoc) - err = HandleOpen1Doc(spec, fileType); - else - err = HandlePrint1Doc(spec, fileType); -#endif - } -Clean: - ::AEDisposeDesc(&docList); - return err; -} // nsAppleEventHandler::HandleAEOpenOrPrintDoc - -//---------------------------------------------------------------------------------------- -PRBool nsAppleEventHandler::EnsureCommandLine() -//---------------------------------------------------------------------------------------- -{ - if (argBuffer) - return PR_TRUE; - argBuffer = new char[MAX_BUF]; - if (!argBuffer) - return PR_FALSE; - PL_strcpy(argBuffer, "mozilla"); // argv[0] - return PR_TRUE; -} - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec) -//---------------------------------------------------------------------------------------- -{ - // Convert the filespec to a URL - nsFileSpec nsspec(inFileSpec); - nsFileURL fileAsURL(nsspec); - PL_strcat(argBuffer, " "); - AddToCommandLine(inOptionString); - AddToCommandLine(fileAsURL.GetAsString()); - return noErr; -} - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::AddToCommandLine(const char* inArgText) -//---------------------------------------------------------------------------------------- -{ - if (!EnsureCommandLine()) - return memFullErr; - if (*inArgText != ' ') - PL_strcat(argBuffer, " "); - PL_strcat(argBuffer, inArgText); - return noErr; -} - -//---------------------------------------------------------------------------------------- -void nsAppleEventHandler::AddToEnvironmentVars(const char* inArgText) -//---------------------------------------------------------------------------------------- -{ - (void)PR_PutEnv(inArgText); -} - -//---------------------------------------------------------------------------------------- -static nsresult openWindow( const char *chrome, const PRUnichar *url ) -//---------------------------------------------------------------------------------------- -{ - nsresult rv; - NS_WITH_SERVICE(nsIAppShellService, appShellService, kAppShellServiceCID, &rv) - if (NS_SUCCEEDED(rv)) - { - nsCOMPtr hiddenWindow; - JSContext *jsContext; - rv = appShellService->GetHiddenWindowAndJSContext( getter_AddRefs( hiddenWindow ), - &jsContext ); - if (NS_SUCCEEDED(rv)) - { - void *stackPtr; - jsval *argv = JS_PushArguments( jsContext, - &stackPtr, - "sssW", - chrome, - "_blank", - "chrome,dialog=no,all", - url ); - if(argv) - { - nsCOMPtr newWindow; - rv = hiddenWindow->OpenDialog( jsContext, - argv, - 4, - getter_AddRefs( newWindow ) ); - JS_PopArguments( jsContext, stackPtr ); - } - } - } - return rv; -} - - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleOpen1Doc(const FSSpec& inFileSpec, OSType inFileType) -//---------------------------------------------------------------------------------------- -{ - if (!mStartedUp) - { - // Is it the right type to be a command-line file? - if (inFileType == 'TEXT' || inFileType == 'CMDL') - { - // Can we open the file? - nsInputFileStream s(inFileSpec); - if (s.is_open()) - { - Boolean foundArgs = false; - Boolean foundEnv = false; - char chars[1024]; - const char* kCommandLinePrefix = "ARGS:"; - const char* kEnvVarLinePrefix = "ENV:"; - s.readline(chars, sizeof(chars)); - - do - { // See if there are any command line or environment var settings - if (PL_strstr(chars, kCommandLinePrefix) == chars) - { - (void)AddToCommandLine(chars + PL_strlen(kCommandLinePrefix)); - foundArgs = true; - } - else if (PL_strstr(chars, kEnvVarLinePrefix) == chars) - { - (void)AddToEnvironmentVars(chars + PL_strlen(kEnvVarLinePrefix)); - foundEnv = true; - } - - // Clear the buffer and get the next line from the command line file - chars[0] = '\0'; - s.readline(chars, sizeof(chars)); - } while (PL_strlen(chars)); - - // If we found any environment vars we need to re-init NSPR's logging - // so that it knows what the new vars are - if (foundEnv) - PR_Init_Log(); - - // If we found a command line or environment vars we want to return now - // raather than trying to open the file as a URL - if (foundArgs || foundEnv) - return noErr; - } - } - // If it's not a command-line argument, and we are starting up the application, - // add a command-line "-url" argument to the global list. This means that if - // the app is opened with documents on the mac, they'll be handled the same - // way as if they had been typed on the command line in Unix or DOS. - return AddToCommandLine("-url", inFileSpec); - } - // Final case: we're not just starting up. How do we handle this? - nsFileSpec fileSpec(inFileSpec); - nsFileURL fileURL(fileSpec); - nsString urlString(fileURL.GetURLString()); - nsresult rv; - rv = openWindow( "chrome://navigator/content", urlString.GetUnicode() ); - if (NS_FAILED(rv)) - return errAEEventNotHandled; - return noErr; -} // nsAppleEventHandler::HandleOpen1Doc - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandlePrint1Doc(const FSSpec& inFileSpec, OSType fileType) -//---------------------------------------------------------------------------------------- -{ - // If we are starting up the application, - // add a command-line "-print" argument to the global list. This means that if - // the app is opened with documents on the mac, they'll be handled the same - // way as if they had been typed on the command line in Unix or DOS. - if (!mStartedUp) - return AddToCommandLine("-print", inFileSpec); - // Final case: we're not just starting up. How do we handle this? - NS_NOTYETIMPLEMENTED("Write Me"); - return errAEEventNotHandled; -} - -/*##########################################################################*/ -/* ---- Mac URL standard, supported by many apps ---- */ -/*##########################################################################*/ - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::DispatchURLToNewBrowser(const char* url) -//---------------------------------------------------------------------------------------- -{ - OSErr err; - if (mStartedUp) - { - nsresult rv; - rv = openWindow( "chrome://navigator/content", nsString(url).GetUnicode() ); - if (NS_FAILED(rv)) - return errAEEventNotHandled; - } - else - err = AddToCommandLine(url); - return err; -} // nsAppleEventHandler::DispatchURLToNewBrowser - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleGetURLEvent( - const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc& outResult, - SInt32 /*inAENumber*/) -// nsAppleEventHandler::HandleGetURLEvent Suite:URL -// Dispach the URL event to the correct window and let the -// window handle the event. -// -//GetURL: Loads the URL (optionaly to disk) -// -// GetURL string -- The url -// [to file specification] -- file the URL should be loaded into -// [inside reference] -- Window the URL should be loaded to -// [from string] -- Refererer, to be sent with the HTTP request -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - char* url = nsnull; - MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, url); - if (!url) - return errAEParamMissed; - err = DispatchURLToNewBrowser(url); - PR_DELETE(url); - return err; -} // nsAppleEventHandler::HandleGetURLEvent - -/*##########################################################################*/ -/* ---- The Spyglass Suite ---- */ -/*##########################################################################*/ - -#define errMakeNewWindow 100 - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleOpenURLEvent( - const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc& outResult, - SInt32 /*inAENumber*/) -// nsAppleEventHandler::HandleOpenURLEvent Suite:Spyglass -// Open to a URL -// In: Incoming apple event, reply event, outtgoing descriptor, eventID -// -// Flavors of OpenURL -// #define AE_spy_openURL 'OURL' // typeChar OpenURL -// AE_spy_openURL_into // typeFSS into -// AE_spy_openURL_wind // typeLongInteger windowID -// AE_spy_openURL_flag // typeLongInteger flags -// 4 bits used. -// 1 = -// 2 = -// 4 = -// 8 = Open into editor window -// AE_spy_openURL_post // typeWildCard post data -// AE_spy_openURL_mime // typeChar MIME type -// AE_spy_openURL_prog // typePSN Progress app -// -// Just like with GetURL, figure out the window, and let it handle the load -// Arguments we care about: AE_spy_openURL_wind -// -// Out: OpenURLEvent handled -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - char* url = nsnull; - MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, url); - if (!url) - return errAEParamMissed; - err = DispatchURLToNewBrowser(url); - PR_DELETE(url); - return err; -} // nsAppleEventHandler::HandleOpenURLEvent - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleDoJavascriptEvent( - const AppleEvent& inAppleEvent, - AppleEvent& /*outAEReply*/, - AEDesc& /*outResult*/, - SInt32 /*inAENumber*/) -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - // Get the direct object - the string to execute. - char *scriptText = nsnull; - MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, scriptText); - if (!scriptText) - return errAEParamMissed; - const char* kJavascriptPrefix = "javascript:"; - char* url = (char*)PR_MALLOC(PL_strlen(scriptText) + PL_strlen(kJavascriptPrefix) + 2); - if (!url) - { - PR_FREEIF(scriptText); - return memFullErr; - } - PL_strcpy(url, kJavascriptPrefix); - PL_strcat(url, scriptText); - PR_FREEIF(scriptText); - err = DispatchURLToNewBrowser(url); -Clean: - PR_FREEIF(url); - return err; -} - -/*##########################################################################*/ -/* ---- Apple Event Object Model support ---- */ -/*##########################################################################*/ - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::GetSubModelByUniqueID(DescType inModelID, const AEDesc &inKeyData, AEDesc &outToken) const -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - NS_NOTYETIMPLEMENTED("Write Me"); -#if 0 - switch (inModelID) - { - case cWindow: // The hyperwindows have unique IDs that can be resolved - // FFFFFFFFF is the front window, 0 is a new window - Int32 windowID; - UExtractFromAEDesc::TheInt32(inKeyData, windowID); - LWindow* foundWindow = CBrowserWindow::GetWindowByID(windowID); - if (foundWindow == nsnull) - ThrowOSErr_(errAENoSuchObject); - else - { - NS_NOTYETIMPLEMENTED("Write Me"); -// CFrontApp::sApplication->PutInToken(foundWindow, outToken); - } - break; - default: - NS_NOTYETIMPLEMENTED("Write Me"); -// CFrontApp::sApplication->LDocApplication::GetSubModelByUniqueID(inModelID, inKeyData, outToken); - break; - } -#endif // 0 - return err; -} - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::GetAEProperty(DescType inProperty, - const AEDesc &inRequestedType, - AEDesc &outPropertyDesc) const -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - NS_NOTYETIMPLEMENTED("Write Me"); -#if 0 - - switch (inProperty) - { - case AE_www_typeApplicationAlert: // application that handles alerts - err = ::AECreateDesc(typeType, &ErrorManager::sAlertApp, - sizeof(ErrorManager::sAlertApp), &outPropertyDesc); - ThrowIfOSErr_(err); - break; - - case AE_www_typeKioskMode: - err = ::AECreateDesc(typeLongInteger, (const void *)mKioskMode, - sizeof(mKioskMode), &outPropertyDesc); - break; - - default: - NS_NOTYETIMPLEMENTED("Write Me"); -// CFrontApp::sApplication->LApplication::GetAEProperty(inProperty, inRequestedType, outPropertyDesc); - break; - } -#endif // 0 - return err; -} - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::SetAEProperty(DescType inProperty, - const AEDesc &inValue, - AEDesc &outPropertyDesc) -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - NS_NOTYETIMPLEMENTED("Write Me"); -#if 0 - switch (inProperty) - { - case AE_www_typeApplicationAlert: // application that handles alerts - try - { - OSType newSig; - UExtractFromAEDesc::TheType(inValue, newSig); - ErrorManager::sAlertApp = newSig; - } - catch(...) // In case of error, revert to self - { - ErrorManager::sAlertApp = emSignature; - } - break; - case AE_www_typeKioskMode: - try - { - Boolean menuBarModeChangeBroadcasted = false; - Int32 kMode; - UExtractFromAEDesc::TheInt32(inValue, kMode); - - if ((kMode == KioskOn) && (mKioskMode != KioskOn)) - { - mKioskMode = KioskOn; - // SetMenubar(KIOSK_MENUBAR); еее this is currently handled by the chrome structure, below - // BUT, they want three states for menu bars, and the field is only a boolean - - CMediatedWindow* theIterWindow = nsnull; - DataIDT windowType = WindowType_Browser; - CWindowIterator theWindowIterator(windowType); - - while (theWindowIterator.Next(theIterWindow)) - { - CBrowserWindow* theBrowserWindow = dynamic_cast(theIterWindow); - if (theBrowserWindow != nil) - { - Chrome aChrome; - theBrowserWindow->GetChromeInfo(&aChrome); - aChrome.show_button_bar = 0; - aChrome.show_url_bar = 0; - aChrome.show_directory_buttons = 0; - aChrome.show_security_bar = 0; - aChrome.show_menu = 0; // еее this isn't designed correctly! deeje 97-03-13 - - // Make sure we only broadcast the menubar mode change once! - theBrowserWindow->SetChromeInfo(&aChrome, !menuBarModeChangeBroadcasted); - if (!menuBarModeChangeBroadcasted) - { - menuBarModeChangeBroadcasted = true; - } - } - } - } - else if ((kMode == KioskOff) && (mKioskMode != KioskOff)) - { - mKioskMode = KioskOff; - // SetMenubar(MAIN_MENUBAR); еее this is currently handled by the chrome structure, below - // BUT, they want three states for menu bars, and the field is only a boolean - - CMediatedWindow* theIterWindow = nsnull; - DataIDT windowType = WindowType_Browser; - CWindowIterator theWindowIterator(windowType); - - while (theWindowIterator.Next(theIterWindow)) - { - CBrowserWindow* theBrowserWindow = dynamic_cast(theIterWindow); - if (theBrowserWindow != nil) - { - Chrome aChrome; - theBrowserWindow->GetChromeInfo(&aChrome); - aChrome.show_button_bar = CPrefs::GetBoolean(CPrefs::ShowToolbar); - aChrome.show_url_bar = CPrefs::GetBoolean(CPrefs::ShowURL); - aChrome.show_directory_buttons = CPrefs::GetBoolean(CPrefs::ShowDirectory); - aChrome.show_security_bar = CPrefs::GetBoolean(CPrefs::ShowToolbar) || CPrefs::GetBoolean(CPrefs::ShowURL); - aChrome.show_menu = 1; // еее this isn't designed correctly! deeje 97-03-13 - - // Make sure we only broadcast the menubar mode change once! - theBrowserWindow->SetChromeInfo(&aChrome, !menuBarModeChangeBroadcasted); - if (!menuBarModeChangeBroadcasted) - { - menuBarModeChangeBroadcasted = true; - } - } - } - } - - } - catch(...) - {} - break; - default: - NS_NOTYETIMPLEMENTED("Write Me"); -// CFrontApp::sApplication->LApplication::SetAEProperty(inProperty, inValue, outPropertyDesc); - break; - } -#endif // 0 - return err; -} - //---------------------------------------------------------------------------------------- // The return value has been AddRefed. Callers should release it. nsIWebShellWindow* FindWebShellWindow(nsIXULWindowCallbacks* inCallbacks) @@ -967,322 +98,328 @@ nsIWebShellWindow* FindWebShellWindow(nsIXULWindowCallbacks* inCallbacks) return aWindow; } -//======================================================================================== -// Implementation of MoreExtractFromAEDesc -// Apple event helpers -- extension of UExtractFromAEDesc.h -// All the miscelaneous AppleEvent helper routines. -//======================================================================================== - #pragma mark - + +// the static instance +nsMacCommandLine nsMacCommandLine::sMacCommandLine; + + //---------------------------------------------------------------------------------------- -void MoreExtractFromAEDesc::GetCString(const AppleEvent &inAppleEvent, - AEKeyword keyword, char * & s, Boolean inThrowIfError) -// Given an AppleEvent, locate a string given a keyword and -// return the string -// In: Event to search -// AEKeyword assocaated with the string -// C string ptr -// Out: Pointer to a newly created C string returned +nsMacCommandLine::nsMacCommandLine() +: mArgBuffer(NULL) +, mArgs(NULL) +, mStartedUp(PR_FALSE) //---------------------------------------------------------------------------------------- { - s = nil; -#ifdef MOZ_POWERPLANT - StAEDescriptor desc; - OSErr err = ::AEGetParamDesc(&inAppleEvent,keyword,typeWildCard,&desc.mDesc); - - if (err) { - if (inThrowIfError) - ThrowIfOSErr_(err); - else - return; - } - TheCString(desc, s); -#endif +} + + +//---------------------------------------------------------------------------------------- +nsMacCommandLine::~nsMacCommandLine() +//---------------------------------------------------------------------------------------- +{ +} + + +//---------------------------------------------------------------------------------------- +nsresult nsMacCommandLine::Initialize(int& argc, char**& argv) +//---------------------------------------------------------------------------------------- +{ + typedef char* charP; + mArgs = new charP[kMaxTokens]; + mArgs[0] = nsnull; + argc = 0; + argv = mArgs; + + // Set up AppleEvent handling. + OSErr err = CreateAEHandlerClasses(false); + if (err != noErr) return NS_ERROR_FAILURE; + + // Snarf all the odoc and pdoc apple-events. + // + // 1. If they are odoc for 'CMDL' documents, read them into the buffer ready for + // parsing (concatenating multiple files). + // + // 2. If they are any other kind of document, convert them into -url command-line + // parameters or -print parameters, with file URLs. + + EventRecord anEvent; + for (short i = 1; i < 5; i++) + ::WaitNextEvent(0, &anEvent, 0, nsnull); + + while (::EventAvail(highLevelEventMask, &anEvent)) + { + ::WaitNextEvent(highLevelEventMask, &anEvent, 0, nsnull); + if (anEvent.what == kHighLevelEvent) + err = ::AEProcessAppleEvent(&anEvent); + } + + + // we've started up now + mStartedUp = PR_TRUE; + + if (!mArgBuffer) // no arguments from anywhere + return NS_OK; + + // Release some unneeded memory + char* oldBuffer = mArgBuffer; + mArgBuffer = new char[PL_strlen(mArgBuffer) + 1]; + PL_strcpy(mArgBuffer, oldBuffer); + delete [] oldBuffer; + + // Parse the buffer. + int rowNumber = 0; + char* strtokFirstParam = mArgBuffer; + while (argc < kMaxTokens) + { + // Get the next token. Initialize strtok by passing the string the + // first time. Subsequently, pass nil. + char* nextToken = strtok(strtokFirstParam, " \t\n\r"); + mArgs[argc] = nextToken; + if (!nextToken) + break; + // Loop + argc++; + strtokFirstParam = nsnull; + } + + // Release the unneeded memory. + if (argc < kMaxTokens) + { + charP* oldArgs = mArgs; + int arraySize = 1 + argc; + mArgs = new charP[arraySize]; + memcpy(mArgs, oldArgs, arraySize * sizeof(charP)); + delete [] oldArgs; + argv = mArgs; + } + + return NS_OK; +} + + +//---------------------------------------------------------------------------------------- +PRBool nsMacCommandLine::EnsureCommandLine() +//---------------------------------------------------------------------------------------- +{ + if (mArgBuffer) + return PR_TRUE; + + mArgBuffer = new char[kMaxBufferSize]; + if (!mArgBuffer) + return PR_FALSE; + + PL_strcpy(mArgBuffer, "mozilla"); // argv[0] + return PR_TRUE; +} + + +//---------------------------------------------------------------------------------------- +nsresult nsMacCommandLine::AddToCommandLine(const char* inArgText) +//---------------------------------------------------------------------------------------- +{ + if (!EnsureCommandLine()) + return NS_ERROR_OUT_OF_MEMORY; + + if (*inArgText != ' ') + PL_strcat(mArgBuffer, " "); + PL_strcat(mArgBuffer, inArgText); + return NS_OK; +} + + +//---------------------------------------------------------------------------------------- +nsresult nsMacCommandLine::AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec) +//---------------------------------------------------------------------------------------- +{ + if (!EnsureCommandLine()) + return NS_ERROR_OUT_OF_MEMORY; + + // Convert the filespec to a URL + nsFileSpec nsspec(inFileSpec); + nsFileURL fileAsURL(nsspec); + PL_strcat(mArgBuffer, " "); + AddToCommandLine(inOptionString); + AddToCommandLine(fileAsURL.GetAsString()); + return NS_OK; } //---------------------------------------------------------------------------------------- -void MoreExtractFromAEDesc::TheCString(const AEDesc &inDesc, char * & outPtr) -// Given an AEDesc of type typeChar, return its string. -// In: AEDesc containing a string -// C string ptr -// Out: Pointer to a newly created C string returned +nsresult nsMacCommandLine::AddToEnvironmentVars(const char* inArgText) //---------------------------------------------------------------------------------------- { - outPtr = nil; - Handle dataH; - AEDesc coerceDesc = {typeNull, nil}; - if (inDesc.descriptorType == typeChar) - { -#if TARGET_CARBON - DebugStr("\pAppleEvent support needs fixing under Carbon"); -#else - dataH = inDesc.dataHandle; // Descriptor is the type we want# -#endif - } - else - { - // Try to coerce to the desired type - if (AECoerceDesc(&inDesc, typeChar, &coerceDesc) == noErr) - { - // Coercion succeeded -#if TARGET_CARBON - DebugStr("\pAppleEvent support needs fixing under Carbon"); -#else - dataH = coerceDesc.dataHandle; -#endif + (void)PR_PutEnv(inArgText); + return NS_OK; +} - } - else - return; - } - - PRInt32 strLength = GetHandleSize(dataH); - outPtr = (char *)PR_MALLOC(strLength+1); // +1 for nsnull ending - if (!outPtr) - return; - // Terminate the string - BlockMoveData(*dataH, outPtr, strLength); - outPtr[strLength] = 0; - - if (coerceDesc.dataHandle != nil) - AEDisposeDesc(&coerceDesc); + +//---------------------------------------------------------------------------------------- +OSErr nsMacCommandLine::HandleOpenOneDoc(const FSSpec& inFileSpec, OSType inFileType) +//---------------------------------------------------------------------------------------- +{ + if (!mStartedUp) + { + // Is it the right type to be a command-line file? + if (inFileType == 'TEXT' || inFileType == 'CMDL') + { + // Can we open the file? + nsInputFileStream s(inFileSpec); + if (s.is_open()) + { + Boolean foundArgs = false; + Boolean foundEnv = false; + char chars[1024]; + const char* kCommandLinePrefix = "ARGS:"; + const char* kEnvVarLinePrefix = "ENV:"; + s.readline(chars, sizeof(chars)); + + do + { // See if there are any command line or environment var settings + if (PL_strstr(chars, kCommandLinePrefix) == chars) + { + (void)AddToCommandLine(chars + PL_strlen(kCommandLinePrefix)); + foundArgs = true; + } + else if (PL_strstr(chars, kEnvVarLinePrefix) == chars) + { + (void)AddToEnvironmentVars(chars + PL_strlen(kEnvVarLinePrefix)); + foundEnv = true; + } + + // Clear the buffer and get the next line from the command line file + chars[0] = '\0'; + s.readline(chars, sizeof(chars)); + } while (PL_strlen(chars)); + + // If we found any environment vars we need to re-init NSPR's logging + // so that it knows what the new vars are + if (foundEnv) + PR_Init_Log(); + + // If we found a command line or environment vars we want to return now + // raather than trying to open the file as a URL + if (foundArgs || foundEnv) + return noErr; + } + } + // If it's not a command-line argument, and we are starting up the application, + // add a command-line "-url" argument to the global list. This means that if + // the app is opened with documents on the mac, they'll be handled the same + // way as if they had been typed on the command line in Unix or DOS. + return AddToCommandLine("-url", inFileSpec); + } + // Final case: we're not just starting up. How do we handle this? + nsFileSpec fileSpec(inFileSpec); + nsFileURL fileURL(fileSpec); + nsString urlString(fileURL.GetURLString()); + nsresult rv; + rv = OpenWindow( "chrome://navigator/content", urlString.GetUnicode() ); + if (NS_FAILED(rv)) + return errAEEventNotHandled; + return noErr; +} + + + +//---------------------------------------------------------------------------------------- +OSErr nsMacCommandLine::HandlePrintOneDoc(const FSSpec& inFileSpec, OSType fileType) +//---------------------------------------------------------------------------------------- +{ + // If we are starting up the application, + // add a command-line "-print" argument to the global list. This means that if + // the app is opened with documents on the mac, they'll be handled the same + // way as if they had been typed on the command line in Unix or DOS. + if (!mStartedUp) + return AddToCommandLine("-print", inFileSpec); + + // Final case: we're not just starting up. How do we handle this? + NS_NOTYETIMPLEMENTED("Write Me"); + return errAEEventNotHandled; +} + + + +//---------------------------------------------------------------------------------------- +nsresult nsMacCommandLine::OpenWindow(const char *chrome, const PRUnichar *url) +//---------------------------------------------------------------------------------------- +{ + nsresult rv; + NS_WITH_SERVICE(nsIAppShellService, appShellService, kAppShellServiceCID, &rv) + if (NS_SUCCEEDED(rv)) + { + nsCOMPtr hiddenWindow; + JSContext *jsContext; + rv = appShellService->GetHiddenWindowAndJSContext( getter_AddRefs( hiddenWindow ), + &jsContext ); + if (NS_SUCCEEDED(rv)) + { + void *stackPtr; + jsval *argv = JS_PushArguments( jsContext, + &stackPtr, + "sssW", + chrome, + "_blank", + "chrome,dialog=no,all", + url ); + if(argv) + { + nsCOMPtr newWindow; + rv = hiddenWindow->OpenDialog( jsContext, + argv, + 4, + getter_AddRefs( newWindow ) ); + JS_PopArguments( jsContext, stackPtr ); + } + } + } + return rv; } //---------------------------------------------------------------------------------------- -void MoreExtractFromAEDesc::MakeErrorReturn( - AppleEvent &event, - ConstStr255Param errorString, - OSErr errorCode) -// Add an error string and error code to an AppleEvent. -// Typically used when constructing the return event when an -// error occured -// In: Apple Event to append to -// Error string -// Error code -// Out: keyErrorNum and keyErrorSting AEDescs are added to the Event. +OSErr nsMacCommandLine::DispatchURLToNewBrowser(const char* url) //---------------------------------------------------------------------------------------- { -#ifdef MOZ_POWERPLANT - StAEDescriptor errorNum(errorCode); - StAEDescriptor errorText((ConstStringPtr)errorString); - // We can ignore the errors. If error occurs, it only means that the reply is not handled - OSErr err = ::AEPutParamDesc(&event, keyErrorNumber, &errorNum.mDesc); - err = ::AEPutParamDesc(&event, keyErrorString, &errorText.mDesc); -#endif + OSErr err; + if (mStartedUp) + { + nsresult rv; + rv = OpenWindow("chrome://navigator/content", nsAutoString(url).GetUnicode()); + if (NS_FAILED(rv)) + return errAEEventNotHandled; + } + else + err = AddToCommandLine(url); + + return err; } //---------------------------------------------------------------------------------------- -Boolean MoreExtractFromAEDesc::DisplayErrorReply(AppleEvent &reply) -// Display an error dialog if the given AppleEvent contains -// a keyErrorNumber. a keyErrorString is optional and will be -// displayed if present -// In: Apple Event -// Out: Error dialog displayed if error data present. +OSErr nsMacCommandLine::Quit(TAskSave askSave) //---------------------------------------------------------------------------------------- { - DescType realType; - Size actualSize; - OSErr errNumber; - Str255 errorString; - // First check for errors - errNumber = AEUtilities::EventHasErrorReply(reply); - if (errNumber == noErr) - return false; - - // server returned an error, so get error string - OSErr err = ::AEGetParamPtr(&reply, keyErrorString, typeChar, - &realType, &errorString[1], sizeof(errorString)-1, - &actualSize); - if (err == noErr) - { - errorString[0] = actualSize > 255 ? 255 : actualSize; - NS_NOTYETIMPLEMENTED("Write Me"); -// ErrorManager::ErrorNotify(errNumber, errorString); - } - else - { - NS_NOTYETIMPLEMENTED("Write Me"); -// ErrorManager::ErrorNotify(errNumber, (unsigned char *)*GetString(AE_ERR_RESID)); - } - return TRUE; + nsresult rv; + NS_WITH_SERVICE(nsIAppShellService, appShellService, kAppShellServiceCID, &rv); + if (NS_FAILED(rv)) + return errAEEventNotHandled; + + (void)appShellService->Quit(); + return noErr; } -//---------------------------------------------------------------------------------------- -ProcessSerialNumber MoreExtractFromAEDesc::ExtractAESender(const AppleEvent &inAppleEvent) -// Return the process serial number of the sending process. -// In: Apple Event send by some app. -// Out: ProcessSerialNumber of the sending app. -//---------------------------------------------------------------------------------------- -{ - Size realSize; - DescType realType; - TargetID target; - ProcessSerialNumber psn; - - OSErr err = AEGetAttributePtr(&inAppleEvent, keyAddressAttr, typeTargetID, &realType, - &target, sizeof(target), &realSize); - // ThrowIfOSErr_(err); - err = ::GetProcessSerialNumberFromPortName(&target.name,&psn); - // ThrowIfOSErr_(err); - return psn; -} - -//---------------------------------------------------------------------------------------- -void MoreExtractFromAEDesc::DispatchURLDirectly(const AppleEvent &inAppleEvent) -//---------------------------------------------------------------------------------------- -{ - char *url = nsnull; - MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, url); - // ThrowIfNil_(url); - NS_NOTYETIMPLEMENTED("Write Me"); -#if 0 - URL_Struct * request = NET_CreateURLStruct(url, NET_DONT_RELOAD); - PR_DELETE(url); - ThrowIfNil_(request); - request->internal_url = TRUE; // for attachments in mailto: urls. - CURLDispatcher::DispatchURL(request, nsnull); -#endif -} //======================================================================================== -// Implementation of AEUtilities -// Some more simple Apple Event utility routines. -//======================================================================================== - -#pragma mark - - -//---------------------------------------------------------------------------------------- -OSErr AEUtilities::CreateAppleEvent(OSType suite, OSType id, - AppleEvent &event, ProcessSerialNumber targetPSN) -// CreateAppleEvent -// Create a new Apple Event from scratch. -// In: Apple Event suite -// Apple Event ID -// Ptr to return Apple Event -// ProcessSerialNumber of the target app to send event to. -// Out:A new Apple Event is created. More data may be added to -// the event simply by calling AEPutParamDesc or AEPutParamPtr -//---------------------------------------------------------------------------------------- -{ - AEAddressDesc progressApp; - OSErr err = ::AECreateDesc(typeProcessSerialNumber, &targetPSN, - sizeof(targetPSN), &progressApp); - if (err) - return err; - err = ::AECreateAppleEvent(suite, id, - &progressApp, - kAutoGenerateReturnID, - kAnyTransactionID, - &event); - AEDisposeDesc(&progressApp); - return err; -} - -//---------------------------------------------------------------------------------------- -OSErr AEUtilities::EventHasErrorReply(AppleEvent & reply) -// Check to see if there is an error in the given AEvent. -// We simply return an OSError equiv to the error value -// in the event. If none exists (or an error took place -// during access) we return 0. -// In: Apple Event to test -// Out:Error value returned -//---------------------------------------------------------------------------------------- -{ - if (reply.descriptorType == typeNull) - return noErr; - - SInt32 errNumber; - Size realSize; - DescType realType; - OSErr err = ::AEGetParamPtr(&reply, keyErrorNumber, typeLongInteger, - &realType, &errNumber, sizeof(errNumber), - &realSize); - if (err == noErr) - return errNumber; - else - return noErr; -} - -//======================================================================================== -// InitializeMacCommandLine +// InitializeMacCommandLine // The only external entry point to this file. //======================================================================================== #pragma mark - //---------------------------------------------------------------------------------------- -void InitializeMacCommandLine(int& argc, char**& argv) +nsresult InitializeMacCommandLine(int& argc, char**& argv) //---------------------------------------------------------------------------------------- { - typedef char* charP; - args = new charP[MAX_TOKENS]; - args[0] = nsnull; - argc = 0; - argv = args; - - // Set up AppleEvent handling. - - nsAppleEventHandler* handler = nsAppleEventHandler::Get(); - if (!handler) - return; - - // Snarf all the odoc and pdoc apple-events. - // - // 1. If they are odoc for 'CMDL' documents, read them into the buffer ready for - // parsing (concatenating multiple files). - // - // 2. If they are any other kind of document, convert them into -url command-line - // parameters or -print parameters, with file URLs. - - EventRecord anEvent; - for (int i = 1; i < 5; i++) - ::WaitNextEvent(0, &anEvent, 0, nsnull); - - while (::EventAvail(highLevelEventMask, &anEvent)) - { - ::WaitNextEvent(highLevelEventMask, &anEvent, 0, nsnull); - if (anEvent.what == kHighLevelEvent) - OSErr err = ::AEProcessAppleEvent(&anEvent); - } - // Now we've grabbed all the initial high-level events, and written them into - // the command-line buffer as url commands, parse the buffer. - - handler->SetStartedUp(PR_TRUE); - if (!argBuffer) - return; - - // Release some unneeded memory - char* oldBuffer = argBuffer; - argBuffer = new char[PL_strlen(argBuffer) + 1]; - PL_strcpy(argBuffer, oldBuffer); - delete [] oldBuffer; - - // Parse the buffer. - int rowNumber = 0; - char* strtokFirstParam = argBuffer; - while (argc < MAX_TOKENS) - { - // Get the next token. Initialize strtok by passing the string the - // first time. Subsequently, pass nil. - char* nextToken = strtok(strtokFirstParam, " \t\n\r"); - args[argc] = nextToken; - if (!nextToken) - break; - // Loop - argc++; - strtokFirstParam = nsnull; - } - - // Release the unneeded memory. - if (argc < MAX_TOKENS) - { - charP* oldArgs = args; - int arraySize = 1 + argc; - args = new charP[arraySize]; - memcpy(args, oldArgs, arraySize * sizeof(charP)); - delete [] oldArgs; - argv = args; - } + nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine(); + return cmdLine.Initialize(argc, argv); } // InitializeMac diff --git a/mozilla/xpfe/appshell/src/nsCommandLineServiceMac.h b/mozilla/xpfe/appshell/src/nsCommandLineServiceMac.h index 5cbf68f21a5..098852a48d7 100644 --- a/mozilla/xpfe/appshell/src/nsCommandLineServiceMac.h +++ b/mozilla/xpfe/appshell/src/nsCommandLineServiceMac.h @@ -22,4 +22,77 @@ // Special stuff for the Macintosh implementation of command-line service. -void InitializeMacCommandLine(int& argc, char**& argv); +#ifndef nsCommandLineServiceMac_h_ +#define nsCommandLineServiceMac_h_ + +#include + +#include "nscore.h" +#include "nsError.h" + +#include "nsAEDefs.h" + +#ifdef __cplusplus + +class nsMacCommandLine +{ +public: + + + enum + { + kMaxBufferSize = 512, + kMaxTokens = 20 + }; + + nsMacCommandLine(); + ~nsMacCommandLine(); + + nsresult Initialize(int& argc, char**& argv); + + PRBool EnsureCommandLine(); + nsresult AddToCommandLine(const char* inArgText); + nsresult AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec); + nsresult AddToEnvironmentVars(const char* inArgText); + + OSErr HandleOpenOneDoc(const FSSpec& inFileSpec, OSType inFileType); + OSErr HandlePrintOneDoc(const FSSpec& inFileSpec, OSType fileType); + + OSErr DispatchURLToNewBrowser(const char* url); + + OSErr Quit(TAskSave askSave); + +protected: + + nsresult OpenWindow(const char *chrome, const PRUnichar *url); + + char* mArgBuffer; // the command line itself + char** mArgs; // array of pointers into argBuffer + + PRBool mStartedUp; + +public: + + static nsMacCommandLine& GetMacCommandLine() { return sMacCommandLine; } + +private: + + static nsMacCommandLine sMacCommandLine; + +}; + +#endif //__cplusplus + + +#ifdef __cplusplus +extern "C" { +#endif + +nsresult InitializeMacCommandLine(int& argc, char**& argv); + +#ifdef __cplusplus +} +#endif + + +#endif // nsCommandLineServiceMac_h_ diff --git a/mozilla/xpfe/bootstrap/nsAppRunner.cpp b/mozilla/xpfe/bootstrap/nsAppRunner.cpp index a44c43e287a..e9fb391d6be 100644 --- a/mozilla/xpfe/bootstrap/nsAppRunner.cpp +++ b/mozilla/xpfe/bootstrap/nsAppRunner.cpp @@ -470,15 +470,13 @@ static nsresult main1(int argc, char* argv[], nsISplashScreen *splashScreen ) #if XP_MAC stTSMCloser tsmCloser; - InitializeMacCommandLine( argc, argv); - + rv = InitializeMacCommandLine( argc, argv); + NS_ASSERTION(NS_SUCCEEDED(rv), "Initializing AppleEvents failed"); #endif // XXX: This call will be replaced by a registry initialization... NS_SetupRegistry_1(); - // Start up the core services: - // Initialize the cmd line service NS_WITH_SERVICE(nsICmdLineService, cmdLineArgs, kCmdLineServiceCID, &rv); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get command line service"); diff --git a/mozilla/xpfe/components/startup/src/nsCommandLineServiceMac.cpp b/mozilla/xpfe/components/startup/src/nsCommandLineServiceMac.cpp index 9eff366ad71..6f32d89babe 100644 --- a/mozilla/xpfe/components/startup/src/nsCommandLineServiceMac.cpp +++ b/mozilla/xpfe/components/startup/src/nsCommandLineServiceMac.cpp @@ -17,7 +17,8 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Contributor(s): + * Contributor(s): + * Simon Fraser * Pierre Phaneuf */ @@ -43,889 +44,19 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "nsIDOMWindow.h" #include "jsapi.h" +#include "nsAEEventHandling.h" + // NSPR #include "prmem.h" #include "plstr.h" #include "prenv.h" #include "pprio.h" // PR_Init_Log -// Universal -#include -#include -#include -#include -#include // For the display notice event -#include -#include -#include - -// PowerPlant -#ifdef MOZ_POWERPLANT -#include -#include -#endif // MOZ_POWERPLANT - #include "nsAppShellCIDs.h" static NS_DEFINE_IID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID); -// Global buffers for command-line arguments and parsing. -#define MAX_BUF 512 -#define MAX_TOKENS 20 -static char* argBuffer = nsnull; // the command line itself -static char** args = nsnull; // array of pointers into argBuffer - static nsIWebShellWindow* FindWebShellWindow(nsIXULWindowCallbacks* cb); -//======================================================================================== -class nsAppleEventHandler -//======================================================================================== -{ - - -public: - enum KioskEnum - { - KioskOff = 0 - , KioskOn = 1 - }; - - nsAppleEventHandler(); - virtual ~nsAppleEventHandler(); - - static nsAppleEventHandler* Get() - { - if (!sAppleEventHandler) - new nsAppleEventHandler(); - return sAppleEventHandler; - } - - void SetStartedUp(PRBool inStarted) { mStartedUp = inStarted; } - - // --- Top Level Apple Event Handling - - virtual OSErr HandleAppleEvent(const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc &outResult, - SInt32 inAENumber); - virtual OSErr GetAEProperty(DescType inProperty, - const AEDesc &inRequestedType, - AEDesc &outPropertyDesc) const; - virtual OSErr SetAEProperty(DescType inProperty, - const AEDesc &inRequestedType, - AEDesc &outPropertyDesc); - - // --- AEOM support - OSErr GetSubModelByUniqueID(DescType inModelID, - const AEDesc &inKeyData, - AEDesc &outToken) const; - - static KioskEnum GetKioskMode(){return sAppleEventHandler->mKioskMode;} - -private: - - - OSErr HandleAEOpenOrPrintDoc( - const AppleEvent &inAppleEvent, - AppleEvent& outAEReply, - SInt32 inAENumber); - - OSErr HandleOpen1Doc(const FSSpec& inFileSpec, - OSType fileType); - - OSErr HandlePrint1Doc(const FSSpec& inFileSpec, - OSType fileType); - - PRBool EnsureCommandLine(); - - OSErr AddToCommandLine(const char* inArgText); - - OSErr AddToCommandLine(const char* inOptionString, - const FSSpec& inFileSpec); - - void AddToEnvironmentVars(const char* inArgText); - - OSErr DispatchURLToNewBrowser(const char* url); - - OSErr HandleOpenURLEvent(const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc &outResult, - SInt32 inAENumber); -// spy Apple Event suite -// file/URL opening + misc - OSErr HandleGetURLEvent(const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc &outResult, - SInt32 inAENumber); - -// Netscape suite - OSErr HandleDoJavascriptEvent(const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc &outResult, - SInt32 inAENumber); - - static pascal OSErr AppleEventHandler( - const AppleEvent* inAppleEvent, - AppleEvent* outAEReply, - UInt32 inRefCon); - -protected: - KioskEnum mKioskMode; - PRBool mStartedUp; - static nsAppleEventHandler* sAppleEventHandler; // One and only instance of AEvents - -}; // class nsAppleEventHandler - -//======================================================================================== -class MoreExtractFromAEDesc -// Apple event helpers -- extension of UExtractFromAEDesc.h -// All the miscellaneous AppleEvent helper routines. -//======================================================================================== -{ -public: - - // -------------------------------------------------------------- - /* Given an AppleEvent, locate a string given a keyword and - return the string - In: Event to search - AEKeyword assocaated with the string - C string ptr - Out: Pointer to a newly created C string returned */ - // -------------------------------------------------------------- - static void GetCString(const AppleEvent &inAppleEvent, AEKeyword keyword, - char * & s, Boolean inThrowIfError = true); - - // -------------------------------------------------------------- - /* Given an AEDesc of type typeChar, return it's string. - In: AEDesc containing a string - C string ptr - Out: Pointer to a newly created C string returned */ - // -------------------------------------------------------------- - static void TheCString(const AEDesc &inDesc, char * & outPtr); - - // -------------------------------------------------------------- - /* Add an error string and error code to an AppleEvent. - Typically used when constructing the return event when an - error occured - In: Apple Event to append to - Error string - Error code - Out: keyErrorNum and keyErrorSting AEDescs are added to the Event. */ - // -------------------------------------------------------------- - static void MakeErrorReturn(AppleEvent &event, ConstStr255Param errorString, - OSErr errorCode); - - // -------------------------------------------------------------- - /* Display an error dialog if the given AppleEvent contains - a keyErrorNumber. a keyErrorString is optional and will be - displayed if present - In: Apple Event - Out: Error dialog displayed if error data present. */ - // -------------------------------------------------------------- - static Boolean DisplayErrorReply(AppleEvent &reply); - - // -------------------------------------------------------------- - /* Return the process serial number of the sending process. - In: Apple Event send by some app. - Out: ProcessSerialNumber of the sending app. */ - // -------------------------------------------------------------- - static ProcessSerialNumber ExtractAESender(const AppleEvent &inAppleEvent); - - static void DispatchURLDirectly(const AppleEvent &inAppleEvent); -}; // class MoreExtractFromAEDesc - - -//======================================================================================== -class AEUtilities -// Some more simple Apple Event utility routines. -//======================================================================================== -{ -public: - - // -------------------------------------------------------------- - /* CreateAppleEvent - Create a new Apple Event from scratch. - In: Apple Event suite - Apple Event ID - Ptr to return Apple Event - ProcessSerialNumber of the target app to send event to. - Out:A new Apple Event is created. More data may be added to - the event simply by calling AEPutParamDesc or AEPutParamPtr */ - // -------------------------------------------------------------- - static OSErr CreateAppleEvent(OSType suite, OSType id, - AppleEvent &event, ProcessSerialNumber targetPSN); - - // -------------------------------------------------------------- - /* Check to see if there is an error in the given AEvent. - We simply return an OSError equiv to the error value - in the event. If none exists (or an error took place - during access) we return 0. - In: Apple Event to test - Out:Error value returned */ - // -------------------------------------------------------------- - static OSErr EventHasErrorReply(AppleEvent & reply); - -}; // AEUtilities - -//======================================================================================== -// Implementation of nsAppleEventHandler -//======================================================================================== - -#pragma mark - - -nsAppleEventHandler* nsAppleEventHandler::sAppleEventHandler = nsnull; - -//---------------------------------------------------------------------------------------- -nsAppleEventHandler::nsAppleEventHandler() -//---------------------------------------------------------------------------------------- -: mKioskMode(KioskOff) // We assume not operating in kiosk mode unless told otherwise -, mStartedUp(PR_FALSE) -{ - // We're a singleton class - sAppleEventHandler = this; - - // We must not throw out of here. - try - { -#ifdef MOZ_POWERPLANT - UAppleEventsMgr::InstallAEHandlers( - NewAEEventHandlerProc(nsAppleEventHandler::AppleEventHandler)); -#endif - } - catch(...) - { - } -} - -//---------------------------------------------------------------------------------------- -nsAppleEventHandler::~nsAppleEventHandler() -//---------------------------------------------------------------------------------------- -{ - // We're a singleton class - sAppleEventHandler = nsnull; -} - -//---------------------------------------------------------------------------------------- -pascal OSErr nsAppleEventHandler::AppleEventHandler( - const AppleEvent* inAppleEvent, - AppleEvent* outAEReply, - UInt32 inRefCon) -// This is the function that gets installed as the AE callback. -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - // We must not throw out of here. - try - { -#ifdef MOZ_POWERPLANT - StAEDescriptor resultDesc; - err = sAppleEventHandler->HandleAppleEvent( - *inAppleEvent, *outAEReply, resultDesc, inRefCon); -#endif - } - catch(...) - { - err = errAEEventNotHandled; - } - return err; -} // nsAppleEventHandler::AppleEventHandler - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleAppleEvent( - const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc &outResult, - SInt32 inAENumber) -// nsAppleEventHandler::HandleAppleEvent -// AppleEvent Dispach Here -// In: & AppleEvent Incoming apple event -// & ReplyEvent Reply event we can attach result info to -// & Descriptor OUtgoing descriptor -// AppleEvent ID The Apple Event ID we were called with. -// Out: Event Handled by CAppleEvent -//---------------------------------------------------------------------------------------- -{ -#ifdef MOZ_POWERPLANT - OSErr err = errAEEventNotHandled; - switch (inAENumber) - { - case AE_GetURL: - case AE_OpenURL: - case ae_OpenApp: - case ae_OpenDoc: - case ae_PrintDoc: - case ae_Quit: - break; - - default: - // Ignore all apple events handled by this handler except get url, open - // url and the required suite until we have properly started up. - if (!mStartedUp) - return errAEEventNotHandled; - break; - } - - switch (inAENumber) - { - - case ae_OpenApp: - err = noErr; - break; - - case ae_Quit: - { - nsresult rv; - NS_WITH_SERVICE(nsIAppShellService, appShellService, kAppShellServiceCID, &rv); - if (NS_FAILED(rv)) - return errAEEventNotHandled; - appShellService->Quit(); - break; - } - case ae_OpenDoc: - case ae_PrintDoc: - err = HandleAEOpenOrPrintDoc(inAppleEvent, outAEReply, inAENumber); - break; - - // ### Mac URL standard Suite - // ----------------------------------------------------------- - case AE_GetURL: // Direct object - url, cwin - HyperWindow - err = HandleGetURLEvent( inAppleEvent, outAEReply, outResult, inAENumber ); - break; - - // ### Spyglass Suite - // ----------------------------------------------------------- - case AE_OpenURL: - err = HandleOpenURLEvent( inAppleEvent, outAEReply, outResult, inAENumber ); - break; - - - // ### Netscape Experimental Suite - // ----------------------------------------------------------- - case AE_DoJavascript: - err = HandleDoJavascriptEvent( inAppleEvent, outAEReply, outResult, inAENumber ); - break; - - // ### If all else fails behave like a word processor - // ----------------------------------------------------------- - default: - NS_NOTYETIMPLEMENTED("Write Me"); - //CFrontApp::sApplication->LDocApplication::HandleAppleEvent( inAppleEvent, outAEReply, outResult, inAENumber ); - break; - } -#endif - return noErr; -} // nsAppleEventHandler::HandleAppleEvent - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleAEOpenOrPrintDoc( - const AppleEvent &inAppleEvent, - AppleEvent& /* outAEReply */, - SInt32 inAENumber) -//---------------------------------------------------------------------------------------- -{ - AEDescList docList; - OSErr err = ::AEGetParamDesc(&inAppleEvent, keyDirectObject, - typeAEList, &docList); - if (err) return err; - - SInt32 numDocs; - err = ::AECountItems(&docList, &numDocs); - if (err) - goto Clean; - - // Loop through all items in the list - // Extract descriptor for the document - // Coerce descriptor data into a FSSpec - // Dispatch the print or open to the appropriate routine - for (int i = 1; i <= numDocs; i++) - { - AEKeyword keyWord; - DescType descType; - FSSpec spec; - Size theSize; - err = ::AEGetNthPtr(&docList, i, typeFSS, &keyWord, &descType, - (Ptr) &spec, sizeof(FSSpec), &theSize); - if (err) - goto Clean; - - nsFileSpec nsspec(spec); - CInfoPBRec info; - nsspec.GetCatInfo(info); - OSType fileType = info.hFileInfo.ioFlFndrInfo.fdType; -#ifdef MOZ_POWERPLANT - if (inAENumber == ae_OpenDoc) - err = HandleOpen1Doc(spec, fileType); - else - err = HandlePrint1Doc(spec, fileType); -#endif - } -Clean: - ::AEDisposeDesc(&docList); - return err; -} // nsAppleEventHandler::HandleAEOpenOrPrintDoc - -//---------------------------------------------------------------------------------------- -PRBool nsAppleEventHandler::EnsureCommandLine() -//---------------------------------------------------------------------------------------- -{ - if (argBuffer) - return PR_TRUE; - argBuffer = new char[MAX_BUF]; - if (!argBuffer) - return PR_FALSE; - PL_strcpy(argBuffer, "mozilla"); // argv[0] - return PR_TRUE; -} - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec) -//---------------------------------------------------------------------------------------- -{ - // Convert the filespec to a URL - nsFileSpec nsspec(inFileSpec); - nsFileURL fileAsURL(nsspec); - PL_strcat(argBuffer, " "); - AddToCommandLine(inOptionString); - AddToCommandLine(fileAsURL.GetAsString()); - return noErr; -} - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::AddToCommandLine(const char* inArgText) -//---------------------------------------------------------------------------------------- -{ - if (!EnsureCommandLine()) - return memFullErr; - if (*inArgText != ' ') - PL_strcat(argBuffer, " "); - PL_strcat(argBuffer, inArgText); - return noErr; -} - -//---------------------------------------------------------------------------------------- -void nsAppleEventHandler::AddToEnvironmentVars(const char* inArgText) -//---------------------------------------------------------------------------------------- -{ - (void)PR_PutEnv(inArgText); -} - -//---------------------------------------------------------------------------------------- -static nsresult openWindow( const char *chrome, const PRUnichar *url ) -//---------------------------------------------------------------------------------------- -{ - nsresult rv; - NS_WITH_SERVICE(nsIAppShellService, appShellService, kAppShellServiceCID, &rv) - if (NS_SUCCEEDED(rv)) - { - nsCOMPtr hiddenWindow; - JSContext *jsContext; - rv = appShellService->GetHiddenWindowAndJSContext( getter_AddRefs( hiddenWindow ), - &jsContext ); - if (NS_SUCCEEDED(rv)) - { - void *stackPtr; - jsval *argv = JS_PushArguments( jsContext, - &stackPtr, - "sssW", - chrome, - "_blank", - "chrome,dialog=no,all", - url ); - if(argv) - { - nsCOMPtr newWindow; - rv = hiddenWindow->OpenDialog( jsContext, - argv, - 4, - getter_AddRefs( newWindow ) ); - JS_PopArguments( jsContext, stackPtr ); - } - } - } - return rv; -} - - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleOpen1Doc(const FSSpec& inFileSpec, OSType inFileType) -//---------------------------------------------------------------------------------------- -{ - if (!mStartedUp) - { - // Is it the right type to be a command-line file? - if (inFileType == 'TEXT' || inFileType == 'CMDL') - { - // Can we open the file? - nsInputFileStream s(inFileSpec); - if (s.is_open()) - { - Boolean foundArgs = false; - Boolean foundEnv = false; - char chars[1024]; - const char* kCommandLinePrefix = "ARGS:"; - const char* kEnvVarLinePrefix = "ENV:"; - s.readline(chars, sizeof(chars)); - - do - { // See if there are any command line or environment var settings - if (PL_strstr(chars, kCommandLinePrefix) == chars) - { - (void)AddToCommandLine(chars + PL_strlen(kCommandLinePrefix)); - foundArgs = true; - } - else if (PL_strstr(chars, kEnvVarLinePrefix) == chars) - { - (void)AddToEnvironmentVars(chars + PL_strlen(kEnvVarLinePrefix)); - foundEnv = true; - } - - // Clear the buffer and get the next line from the command line file - chars[0] = '\0'; - s.readline(chars, sizeof(chars)); - } while (PL_strlen(chars)); - - // If we found any environment vars we need to re-init NSPR's logging - // so that it knows what the new vars are - if (foundEnv) - PR_Init_Log(); - - // If we found a command line or environment vars we want to return now - // raather than trying to open the file as a URL - if (foundArgs || foundEnv) - return noErr; - } - } - // If it's not a command-line argument, and we are starting up the application, - // add a command-line "-url" argument to the global list. This means that if - // the app is opened with documents on the mac, they'll be handled the same - // way as if they had been typed on the command line in Unix or DOS. - return AddToCommandLine("-url", inFileSpec); - } - // Final case: we're not just starting up. How do we handle this? - nsFileSpec fileSpec(inFileSpec); - nsFileURL fileURL(fileSpec); - nsString urlString(fileURL.GetURLString()); - nsresult rv; - rv = openWindow( "chrome://navigator/content", urlString.GetUnicode() ); - if (NS_FAILED(rv)) - return errAEEventNotHandled; - return noErr; -} // nsAppleEventHandler::HandleOpen1Doc - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandlePrint1Doc(const FSSpec& inFileSpec, OSType fileType) -//---------------------------------------------------------------------------------------- -{ - // If we are starting up the application, - // add a command-line "-print" argument to the global list. This means that if - // the app is opened with documents on the mac, they'll be handled the same - // way as if they had been typed on the command line in Unix or DOS. - if (!mStartedUp) - return AddToCommandLine("-print", inFileSpec); - // Final case: we're not just starting up. How do we handle this? - NS_NOTYETIMPLEMENTED("Write Me"); - return errAEEventNotHandled; -} - -/*##########################################################################*/ -/* ---- Mac URL standard, supported by many apps ---- */ -/*##########################################################################*/ - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::DispatchURLToNewBrowser(const char* url) -//---------------------------------------------------------------------------------------- -{ - OSErr err; - if (mStartedUp) - { - nsresult rv; - rv = openWindow( "chrome://navigator/content", nsString(url).GetUnicode() ); - if (NS_FAILED(rv)) - return errAEEventNotHandled; - } - else - err = AddToCommandLine(url); - return err; -} // nsAppleEventHandler::DispatchURLToNewBrowser - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleGetURLEvent( - const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc& outResult, - SInt32 /*inAENumber*/) -// nsAppleEventHandler::HandleGetURLEvent Suite:URL -// Dispach the URL event to the correct window and let the -// window handle the event. -// -//GetURL: Loads the URL (optionaly to disk) -// -// GetURL string -- The url -// [to file specification] -- file the URL should be loaded into -// [inside reference] -- Window the URL should be loaded to -// [from string] -- Refererer, to be sent with the HTTP request -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - char* url = nsnull; - MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, url); - if (!url) - return errAEParamMissed; - err = DispatchURLToNewBrowser(url); - PR_DELETE(url); - return err; -} // nsAppleEventHandler::HandleGetURLEvent - -/*##########################################################################*/ -/* ---- The Spyglass Suite ---- */ -/*##########################################################################*/ - -#define errMakeNewWindow 100 - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleOpenURLEvent( - const AppleEvent &inAppleEvent, - AppleEvent &outAEReply, - AEDesc& outResult, - SInt32 /*inAENumber*/) -// nsAppleEventHandler::HandleOpenURLEvent Suite:Spyglass -// Open to a URL -// In: Incoming apple event, reply event, outtgoing descriptor, eventID -// -// Flavors of OpenURL -// #define AE_spy_openURL 'OURL' // typeChar OpenURL -// AE_spy_openURL_into // typeFSS into -// AE_spy_openURL_wind // typeLongInteger windowID -// AE_spy_openURL_flag // typeLongInteger flags -// 4 bits used. -// 1 = -// 2 = -// 4 = -// 8 = Open into editor window -// AE_spy_openURL_post // typeWildCard post data -// AE_spy_openURL_mime // typeChar MIME type -// AE_spy_openURL_prog // typePSN Progress app -// -// Just like with GetURL, figure out the window, and let it handle the load -// Arguments we care about: AE_spy_openURL_wind -// -// Out: OpenURLEvent handled -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - char* url = nsnull; - MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, url); - if (!url) - return errAEParamMissed; - err = DispatchURLToNewBrowser(url); - PR_DELETE(url); - return err; -} // nsAppleEventHandler::HandleOpenURLEvent - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::HandleDoJavascriptEvent( - const AppleEvent& inAppleEvent, - AppleEvent& /*outAEReply*/, - AEDesc& /*outResult*/, - SInt32 /*inAENumber*/) -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - // Get the direct object - the string to execute. - char *scriptText = nsnull; - MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, scriptText); - if (!scriptText) - return errAEParamMissed; - const char* kJavascriptPrefix = "javascript:"; - char* url = (char*)PR_MALLOC(PL_strlen(scriptText) + PL_strlen(kJavascriptPrefix) + 2); - if (!url) - { - PR_FREEIF(scriptText); - return memFullErr; - } - PL_strcpy(url, kJavascriptPrefix); - PL_strcat(url, scriptText); - PR_FREEIF(scriptText); - err = DispatchURLToNewBrowser(url); -Clean: - PR_FREEIF(url); - return err; -} - -/*##########################################################################*/ -/* ---- Apple Event Object Model support ---- */ -/*##########################################################################*/ - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::GetSubModelByUniqueID(DescType inModelID, const AEDesc &inKeyData, AEDesc &outToken) const -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - NS_NOTYETIMPLEMENTED("Write Me"); -#if 0 - switch (inModelID) - { - case cWindow: // The hyperwindows have unique IDs that can be resolved - // FFFFFFFFF is the front window, 0 is a new window - Int32 windowID; - UExtractFromAEDesc::TheInt32(inKeyData, windowID); - LWindow* foundWindow = CBrowserWindow::GetWindowByID(windowID); - if (foundWindow == nsnull) - ThrowOSErr_(errAENoSuchObject); - else - { - NS_NOTYETIMPLEMENTED("Write Me"); -// CFrontApp::sApplication->PutInToken(foundWindow, outToken); - } - break; - default: - NS_NOTYETIMPLEMENTED("Write Me"); -// CFrontApp::sApplication->LDocApplication::GetSubModelByUniqueID(inModelID, inKeyData, outToken); - break; - } -#endif // 0 - return err; -} - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::GetAEProperty(DescType inProperty, - const AEDesc &inRequestedType, - AEDesc &outPropertyDesc) const -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - NS_NOTYETIMPLEMENTED("Write Me"); -#if 0 - - switch (inProperty) - { - case AE_www_typeApplicationAlert: // application that handles alerts - err = ::AECreateDesc(typeType, &ErrorManager::sAlertApp, - sizeof(ErrorManager::sAlertApp), &outPropertyDesc); - ThrowIfOSErr_(err); - break; - - case AE_www_typeKioskMode: - err = ::AECreateDesc(typeLongInteger, (const void *)mKioskMode, - sizeof(mKioskMode), &outPropertyDesc); - break; - - default: - NS_NOTYETIMPLEMENTED("Write Me"); -// CFrontApp::sApplication->LApplication::GetAEProperty(inProperty, inRequestedType, outPropertyDesc); - break; - } -#endif // 0 - return err; -} - -//---------------------------------------------------------------------------------------- -OSErr nsAppleEventHandler::SetAEProperty(DescType inProperty, - const AEDesc &inValue, - AEDesc &outPropertyDesc) -//---------------------------------------------------------------------------------------- -{ - OSErr err = noErr; - NS_NOTYETIMPLEMENTED("Write Me"); -#if 0 - switch (inProperty) - { - case AE_www_typeApplicationAlert: // application that handles alerts - try - { - OSType newSig; - UExtractFromAEDesc::TheType(inValue, newSig); - ErrorManager::sAlertApp = newSig; - } - catch(...) // In case of error, revert to self - { - ErrorManager::sAlertApp = emSignature; - } - break; - case AE_www_typeKioskMode: - try - { - Boolean menuBarModeChangeBroadcasted = false; - Int32 kMode; - UExtractFromAEDesc::TheInt32(inValue, kMode); - - if ((kMode == KioskOn) && (mKioskMode != KioskOn)) - { - mKioskMode = KioskOn; - // SetMenubar(KIOSK_MENUBAR); еее this is currently handled by the chrome structure, below - // BUT, they want three states for menu bars, and the field is only a boolean - - CMediatedWindow* theIterWindow = nsnull; - DataIDT windowType = WindowType_Browser; - CWindowIterator theWindowIterator(windowType); - - while (theWindowIterator.Next(theIterWindow)) - { - CBrowserWindow* theBrowserWindow = dynamic_cast(theIterWindow); - if (theBrowserWindow != nil) - { - Chrome aChrome; - theBrowserWindow->GetChromeInfo(&aChrome); - aChrome.show_button_bar = 0; - aChrome.show_url_bar = 0; - aChrome.show_directory_buttons = 0; - aChrome.show_security_bar = 0; - aChrome.show_menu = 0; // еее this isn't designed correctly! deeje 97-03-13 - - // Make sure we only broadcast the menubar mode change once! - theBrowserWindow->SetChromeInfo(&aChrome, !menuBarModeChangeBroadcasted); - if (!menuBarModeChangeBroadcasted) - { - menuBarModeChangeBroadcasted = true; - } - } - } - } - else if ((kMode == KioskOff) && (mKioskMode != KioskOff)) - { - mKioskMode = KioskOff; - // SetMenubar(MAIN_MENUBAR); еее this is currently handled by the chrome structure, below - // BUT, they want three states for menu bars, and the field is only a boolean - - CMediatedWindow* theIterWindow = nsnull; - DataIDT windowType = WindowType_Browser; - CWindowIterator theWindowIterator(windowType); - - while (theWindowIterator.Next(theIterWindow)) - { - CBrowserWindow* theBrowserWindow = dynamic_cast(theIterWindow); - if (theBrowserWindow != nil) - { - Chrome aChrome; - theBrowserWindow->GetChromeInfo(&aChrome); - aChrome.show_button_bar = CPrefs::GetBoolean(CPrefs::ShowToolbar); - aChrome.show_url_bar = CPrefs::GetBoolean(CPrefs::ShowURL); - aChrome.show_directory_buttons = CPrefs::GetBoolean(CPrefs::ShowDirectory); - aChrome.show_security_bar = CPrefs::GetBoolean(CPrefs::ShowToolbar) || CPrefs::GetBoolean(CPrefs::ShowURL); - aChrome.show_menu = 1; // еее this isn't designed correctly! deeje 97-03-13 - - // Make sure we only broadcast the menubar mode change once! - theBrowserWindow->SetChromeInfo(&aChrome, !menuBarModeChangeBroadcasted); - if (!menuBarModeChangeBroadcasted) - { - menuBarModeChangeBroadcasted = true; - } - } - } - } - - } - catch(...) - {} - break; - default: - NS_NOTYETIMPLEMENTED("Write Me"); -// CFrontApp::sApplication->LApplication::SetAEProperty(inProperty, inValue, outPropertyDesc); - break; - } -#endif // 0 - return err; -} - //---------------------------------------------------------------------------------------- // The return value has been AddRefed. Callers should release it. nsIWebShellWindow* FindWebShellWindow(nsIXULWindowCallbacks* inCallbacks) @@ -967,322 +98,328 @@ nsIWebShellWindow* FindWebShellWindow(nsIXULWindowCallbacks* inCallbacks) return aWindow; } -//======================================================================================== -// Implementation of MoreExtractFromAEDesc -// Apple event helpers -- extension of UExtractFromAEDesc.h -// All the miscelaneous AppleEvent helper routines. -//======================================================================================== - #pragma mark - + +// the static instance +nsMacCommandLine nsMacCommandLine::sMacCommandLine; + + //---------------------------------------------------------------------------------------- -void MoreExtractFromAEDesc::GetCString(const AppleEvent &inAppleEvent, - AEKeyword keyword, char * & s, Boolean inThrowIfError) -// Given an AppleEvent, locate a string given a keyword and -// return the string -// In: Event to search -// AEKeyword assocaated with the string -// C string ptr -// Out: Pointer to a newly created C string returned +nsMacCommandLine::nsMacCommandLine() +: mArgBuffer(NULL) +, mArgs(NULL) +, mStartedUp(PR_FALSE) //---------------------------------------------------------------------------------------- { - s = nil; -#ifdef MOZ_POWERPLANT - StAEDescriptor desc; - OSErr err = ::AEGetParamDesc(&inAppleEvent,keyword,typeWildCard,&desc.mDesc); - - if (err) { - if (inThrowIfError) - ThrowIfOSErr_(err); - else - return; - } - TheCString(desc, s); -#endif +} + + +//---------------------------------------------------------------------------------------- +nsMacCommandLine::~nsMacCommandLine() +//---------------------------------------------------------------------------------------- +{ +} + + +//---------------------------------------------------------------------------------------- +nsresult nsMacCommandLine::Initialize(int& argc, char**& argv) +//---------------------------------------------------------------------------------------- +{ + typedef char* charP; + mArgs = new charP[kMaxTokens]; + mArgs[0] = nsnull; + argc = 0; + argv = mArgs; + + // Set up AppleEvent handling. + OSErr err = CreateAEHandlerClasses(false); + if (err != noErr) return NS_ERROR_FAILURE; + + // Snarf all the odoc and pdoc apple-events. + // + // 1. If they are odoc for 'CMDL' documents, read them into the buffer ready for + // parsing (concatenating multiple files). + // + // 2. If they are any other kind of document, convert them into -url command-line + // parameters or -print parameters, with file URLs. + + EventRecord anEvent; + for (short i = 1; i < 5; i++) + ::WaitNextEvent(0, &anEvent, 0, nsnull); + + while (::EventAvail(highLevelEventMask, &anEvent)) + { + ::WaitNextEvent(highLevelEventMask, &anEvent, 0, nsnull); + if (anEvent.what == kHighLevelEvent) + err = ::AEProcessAppleEvent(&anEvent); + } + + + // we've started up now + mStartedUp = PR_TRUE; + + if (!mArgBuffer) // no arguments from anywhere + return NS_OK; + + // Release some unneeded memory + char* oldBuffer = mArgBuffer; + mArgBuffer = new char[PL_strlen(mArgBuffer) + 1]; + PL_strcpy(mArgBuffer, oldBuffer); + delete [] oldBuffer; + + // Parse the buffer. + int rowNumber = 0; + char* strtokFirstParam = mArgBuffer; + while (argc < kMaxTokens) + { + // Get the next token. Initialize strtok by passing the string the + // first time. Subsequently, pass nil. + char* nextToken = strtok(strtokFirstParam, " \t\n\r"); + mArgs[argc] = nextToken; + if (!nextToken) + break; + // Loop + argc++; + strtokFirstParam = nsnull; + } + + // Release the unneeded memory. + if (argc < kMaxTokens) + { + charP* oldArgs = mArgs; + int arraySize = 1 + argc; + mArgs = new charP[arraySize]; + memcpy(mArgs, oldArgs, arraySize * sizeof(charP)); + delete [] oldArgs; + argv = mArgs; + } + + return NS_OK; +} + + +//---------------------------------------------------------------------------------------- +PRBool nsMacCommandLine::EnsureCommandLine() +//---------------------------------------------------------------------------------------- +{ + if (mArgBuffer) + return PR_TRUE; + + mArgBuffer = new char[kMaxBufferSize]; + if (!mArgBuffer) + return PR_FALSE; + + PL_strcpy(mArgBuffer, "mozilla"); // argv[0] + return PR_TRUE; +} + + +//---------------------------------------------------------------------------------------- +nsresult nsMacCommandLine::AddToCommandLine(const char* inArgText) +//---------------------------------------------------------------------------------------- +{ + if (!EnsureCommandLine()) + return NS_ERROR_OUT_OF_MEMORY; + + if (*inArgText != ' ') + PL_strcat(mArgBuffer, " "); + PL_strcat(mArgBuffer, inArgText); + return NS_OK; +} + + +//---------------------------------------------------------------------------------------- +nsresult nsMacCommandLine::AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec) +//---------------------------------------------------------------------------------------- +{ + if (!EnsureCommandLine()) + return NS_ERROR_OUT_OF_MEMORY; + + // Convert the filespec to a URL + nsFileSpec nsspec(inFileSpec); + nsFileURL fileAsURL(nsspec); + PL_strcat(mArgBuffer, " "); + AddToCommandLine(inOptionString); + AddToCommandLine(fileAsURL.GetAsString()); + return NS_OK; } //---------------------------------------------------------------------------------------- -void MoreExtractFromAEDesc::TheCString(const AEDesc &inDesc, char * & outPtr) -// Given an AEDesc of type typeChar, return its string. -// In: AEDesc containing a string -// C string ptr -// Out: Pointer to a newly created C string returned +nsresult nsMacCommandLine::AddToEnvironmentVars(const char* inArgText) //---------------------------------------------------------------------------------------- { - outPtr = nil; - Handle dataH; - AEDesc coerceDesc = {typeNull, nil}; - if (inDesc.descriptorType == typeChar) - { -#if TARGET_CARBON - DebugStr("\pAppleEvent support needs fixing under Carbon"); -#else - dataH = inDesc.dataHandle; // Descriptor is the type we want# -#endif - } - else - { - // Try to coerce to the desired type - if (AECoerceDesc(&inDesc, typeChar, &coerceDesc) == noErr) - { - // Coercion succeeded -#if TARGET_CARBON - DebugStr("\pAppleEvent support needs fixing under Carbon"); -#else - dataH = coerceDesc.dataHandle; -#endif + (void)PR_PutEnv(inArgText); + return NS_OK; +} - } - else - return; - } - - PRInt32 strLength = GetHandleSize(dataH); - outPtr = (char *)PR_MALLOC(strLength+1); // +1 for nsnull ending - if (!outPtr) - return; - // Terminate the string - BlockMoveData(*dataH, outPtr, strLength); - outPtr[strLength] = 0; - - if (coerceDesc.dataHandle != nil) - AEDisposeDesc(&coerceDesc); + +//---------------------------------------------------------------------------------------- +OSErr nsMacCommandLine::HandleOpenOneDoc(const FSSpec& inFileSpec, OSType inFileType) +//---------------------------------------------------------------------------------------- +{ + if (!mStartedUp) + { + // Is it the right type to be a command-line file? + if (inFileType == 'TEXT' || inFileType == 'CMDL') + { + // Can we open the file? + nsInputFileStream s(inFileSpec); + if (s.is_open()) + { + Boolean foundArgs = false; + Boolean foundEnv = false; + char chars[1024]; + const char* kCommandLinePrefix = "ARGS:"; + const char* kEnvVarLinePrefix = "ENV:"; + s.readline(chars, sizeof(chars)); + + do + { // See if there are any command line or environment var settings + if (PL_strstr(chars, kCommandLinePrefix) == chars) + { + (void)AddToCommandLine(chars + PL_strlen(kCommandLinePrefix)); + foundArgs = true; + } + else if (PL_strstr(chars, kEnvVarLinePrefix) == chars) + { + (void)AddToEnvironmentVars(chars + PL_strlen(kEnvVarLinePrefix)); + foundEnv = true; + } + + // Clear the buffer and get the next line from the command line file + chars[0] = '\0'; + s.readline(chars, sizeof(chars)); + } while (PL_strlen(chars)); + + // If we found any environment vars we need to re-init NSPR's logging + // so that it knows what the new vars are + if (foundEnv) + PR_Init_Log(); + + // If we found a command line or environment vars we want to return now + // raather than trying to open the file as a URL + if (foundArgs || foundEnv) + return noErr; + } + } + // If it's not a command-line argument, and we are starting up the application, + // add a command-line "-url" argument to the global list. This means that if + // the app is opened with documents on the mac, they'll be handled the same + // way as if they had been typed on the command line in Unix or DOS. + return AddToCommandLine("-url", inFileSpec); + } + // Final case: we're not just starting up. How do we handle this? + nsFileSpec fileSpec(inFileSpec); + nsFileURL fileURL(fileSpec); + nsString urlString(fileURL.GetURLString()); + nsresult rv; + rv = OpenWindow( "chrome://navigator/content", urlString.GetUnicode() ); + if (NS_FAILED(rv)) + return errAEEventNotHandled; + return noErr; +} + + + +//---------------------------------------------------------------------------------------- +OSErr nsMacCommandLine::HandlePrintOneDoc(const FSSpec& inFileSpec, OSType fileType) +//---------------------------------------------------------------------------------------- +{ + // If we are starting up the application, + // add a command-line "-print" argument to the global list. This means that if + // the app is opened with documents on the mac, they'll be handled the same + // way as if they had been typed on the command line in Unix or DOS. + if (!mStartedUp) + return AddToCommandLine("-print", inFileSpec); + + // Final case: we're not just starting up. How do we handle this? + NS_NOTYETIMPLEMENTED("Write Me"); + return errAEEventNotHandled; +} + + + +//---------------------------------------------------------------------------------------- +nsresult nsMacCommandLine::OpenWindow(const char *chrome, const PRUnichar *url) +//---------------------------------------------------------------------------------------- +{ + nsresult rv; + NS_WITH_SERVICE(nsIAppShellService, appShellService, kAppShellServiceCID, &rv) + if (NS_SUCCEEDED(rv)) + { + nsCOMPtr hiddenWindow; + JSContext *jsContext; + rv = appShellService->GetHiddenWindowAndJSContext( getter_AddRefs( hiddenWindow ), + &jsContext ); + if (NS_SUCCEEDED(rv)) + { + void *stackPtr; + jsval *argv = JS_PushArguments( jsContext, + &stackPtr, + "sssW", + chrome, + "_blank", + "chrome,dialog=no,all", + url ); + if(argv) + { + nsCOMPtr newWindow; + rv = hiddenWindow->OpenDialog( jsContext, + argv, + 4, + getter_AddRefs( newWindow ) ); + JS_PopArguments( jsContext, stackPtr ); + } + } + } + return rv; } //---------------------------------------------------------------------------------------- -void MoreExtractFromAEDesc::MakeErrorReturn( - AppleEvent &event, - ConstStr255Param errorString, - OSErr errorCode) -// Add an error string and error code to an AppleEvent. -// Typically used when constructing the return event when an -// error occured -// In: Apple Event to append to -// Error string -// Error code -// Out: keyErrorNum and keyErrorSting AEDescs are added to the Event. +OSErr nsMacCommandLine::DispatchURLToNewBrowser(const char* url) //---------------------------------------------------------------------------------------- { -#ifdef MOZ_POWERPLANT - StAEDescriptor errorNum(errorCode); - StAEDescriptor errorText((ConstStringPtr)errorString); - // We can ignore the errors. If error occurs, it only means that the reply is not handled - OSErr err = ::AEPutParamDesc(&event, keyErrorNumber, &errorNum.mDesc); - err = ::AEPutParamDesc(&event, keyErrorString, &errorText.mDesc); -#endif + OSErr err; + if (mStartedUp) + { + nsresult rv; + rv = OpenWindow("chrome://navigator/content", nsAutoString(url).GetUnicode()); + if (NS_FAILED(rv)) + return errAEEventNotHandled; + } + else + err = AddToCommandLine(url); + + return err; } //---------------------------------------------------------------------------------------- -Boolean MoreExtractFromAEDesc::DisplayErrorReply(AppleEvent &reply) -// Display an error dialog if the given AppleEvent contains -// a keyErrorNumber. a keyErrorString is optional and will be -// displayed if present -// In: Apple Event -// Out: Error dialog displayed if error data present. +OSErr nsMacCommandLine::Quit(TAskSave askSave) //---------------------------------------------------------------------------------------- { - DescType realType; - Size actualSize; - OSErr errNumber; - Str255 errorString; - // First check for errors - errNumber = AEUtilities::EventHasErrorReply(reply); - if (errNumber == noErr) - return false; - - // server returned an error, so get error string - OSErr err = ::AEGetParamPtr(&reply, keyErrorString, typeChar, - &realType, &errorString[1], sizeof(errorString)-1, - &actualSize); - if (err == noErr) - { - errorString[0] = actualSize > 255 ? 255 : actualSize; - NS_NOTYETIMPLEMENTED("Write Me"); -// ErrorManager::ErrorNotify(errNumber, errorString); - } - else - { - NS_NOTYETIMPLEMENTED("Write Me"); -// ErrorManager::ErrorNotify(errNumber, (unsigned char *)*GetString(AE_ERR_RESID)); - } - return TRUE; + nsresult rv; + NS_WITH_SERVICE(nsIAppShellService, appShellService, kAppShellServiceCID, &rv); + if (NS_FAILED(rv)) + return errAEEventNotHandled; + + (void)appShellService->Quit(); + return noErr; } -//---------------------------------------------------------------------------------------- -ProcessSerialNumber MoreExtractFromAEDesc::ExtractAESender(const AppleEvent &inAppleEvent) -// Return the process serial number of the sending process. -// In: Apple Event send by some app. -// Out: ProcessSerialNumber of the sending app. -//---------------------------------------------------------------------------------------- -{ - Size realSize; - DescType realType; - TargetID target; - ProcessSerialNumber psn; - - OSErr err = AEGetAttributePtr(&inAppleEvent, keyAddressAttr, typeTargetID, &realType, - &target, sizeof(target), &realSize); - // ThrowIfOSErr_(err); - err = ::GetProcessSerialNumberFromPortName(&target.name,&psn); - // ThrowIfOSErr_(err); - return psn; -} - -//---------------------------------------------------------------------------------------- -void MoreExtractFromAEDesc::DispatchURLDirectly(const AppleEvent &inAppleEvent) -//---------------------------------------------------------------------------------------- -{ - char *url = nsnull; - MoreExtractFromAEDesc::GetCString(inAppleEvent, keyDirectObject, url); - // ThrowIfNil_(url); - NS_NOTYETIMPLEMENTED("Write Me"); -#if 0 - URL_Struct * request = NET_CreateURLStruct(url, NET_DONT_RELOAD); - PR_DELETE(url); - ThrowIfNil_(request); - request->internal_url = TRUE; // for attachments in mailto: urls. - CURLDispatcher::DispatchURL(request, nsnull); -#endif -} //======================================================================================== -// Implementation of AEUtilities -// Some more simple Apple Event utility routines. -//======================================================================================== - -#pragma mark - - -//---------------------------------------------------------------------------------------- -OSErr AEUtilities::CreateAppleEvent(OSType suite, OSType id, - AppleEvent &event, ProcessSerialNumber targetPSN) -// CreateAppleEvent -// Create a new Apple Event from scratch. -// In: Apple Event suite -// Apple Event ID -// Ptr to return Apple Event -// ProcessSerialNumber of the target app to send event to. -// Out:A new Apple Event is created. More data may be added to -// the event simply by calling AEPutParamDesc or AEPutParamPtr -//---------------------------------------------------------------------------------------- -{ - AEAddressDesc progressApp; - OSErr err = ::AECreateDesc(typeProcessSerialNumber, &targetPSN, - sizeof(targetPSN), &progressApp); - if (err) - return err; - err = ::AECreateAppleEvent(suite, id, - &progressApp, - kAutoGenerateReturnID, - kAnyTransactionID, - &event); - AEDisposeDesc(&progressApp); - return err; -} - -//---------------------------------------------------------------------------------------- -OSErr AEUtilities::EventHasErrorReply(AppleEvent & reply) -// Check to see if there is an error in the given AEvent. -// We simply return an OSError equiv to the error value -// in the event. If none exists (or an error took place -// during access) we return 0. -// In: Apple Event to test -// Out:Error value returned -//---------------------------------------------------------------------------------------- -{ - if (reply.descriptorType == typeNull) - return noErr; - - SInt32 errNumber; - Size realSize; - DescType realType; - OSErr err = ::AEGetParamPtr(&reply, keyErrorNumber, typeLongInteger, - &realType, &errNumber, sizeof(errNumber), - &realSize); - if (err == noErr) - return errNumber; - else - return noErr; -} - -//======================================================================================== -// InitializeMacCommandLine +// InitializeMacCommandLine // The only external entry point to this file. //======================================================================================== #pragma mark - //---------------------------------------------------------------------------------------- -void InitializeMacCommandLine(int& argc, char**& argv) +nsresult InitializeMacCommandLine(int& argc, char**& argv) //---------------------------------------------------------------------------------------- { - typedef char* charP; - args = new charP[MAX_TOKENS]; - args[0] = nsnull; - argc = 0; - argv = args; - - // Set up AppleEvent handling. - - nsAppleEventHandler* handler = nsAppleEventHandler::Get(); - if (!handler) - return; - - // Snarf all the odoc and pdoc apple-events. - // - // 1. If they are odoc for 'CMDL' documents, read them into the buffer ready for - // parsing (concatenating multiple files). - // - // 2. If they are any other kind of document, convert them into -url command-line - // parameters or -print parameters, with file URLs. - - EventRecord anEvent; - for (int i = 1; i < 5; i++) - ::WaitNextEvent(0, &anEvent, 0, nsnull); - - while (::EventAvail(highLevelEventMask, &anEvent)) - { - ::WaitNextEvent(highLevelEventMask, &anEvent, 0, nsnull); - if (anEvent.what == kHighLevelEvent) - OSErr err = ::AEProcessAppleEvent(&anEvent); - } - // Now we've grabbed all the initial high-level events, and written them into - // the command-line buffer as url commands, parse the buffer. - - handler->SetStartedUp(PR_TRUE); - if (!argBuffer) - return; - - // Release some unneeded memory - char* oldBuffer = argBuffer; - argBuffer = new char[PL_strlen(argBuffer) + 1]; - PL_strcpy(argBuffer, oldBuffer); - delete [] oldBuffer; - - // Parse the buffer. - int rowNumber = 0; - char* strtokFirstParam = argBuffer; - while (argc < MAX_TOKENS) - { - // Get the next token. Initialize strtok by passing the string the - // first time. Subsequently, pass nil. - char* nextToken = strtok(strtokFirstParam, " \t\n\r"); - args[argc] = nextToken; - if (!nextToken) - break; - // Loop - argc++; - strtokFirstParam = nsnull; - } - - // Release the unneeded memory. - if (argc < MAX_TOKENS) - { - charP* oldArgs = args; - int arraySize = 1 + argc; - args = new charP[arraySize]; - memcpy(args, oldArgs, arraySize * sizeof(charP)); - delete [] oldArgs; - argv = args; - } + nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine(); + return cmdLine.Initialize(argc, argv); } // InitializeMac diff --git a/mozilla/xpfe/components/startup/src/nsCommandLineServiceMac.h b/mozilla/xpfe/components/startup/src/nsCommandLineServiceMac.h index 5cbf68f21a5..098852a48d7 100644 --- a/mozilla/xpfe/components/startup/src/nsCommandLineServiceMac.h +++ b/mozilla/xpfe/components/startup/src/nsCommandLineServiceMac.h @@ -22,4 +22,77 @@ // Special stuff for the Macintosh implementation of command-line service. -void InitializeMacCommandLine(int& argc, char**& argv); +#ifndef nsCommandLineServiceMac_h_ +#define nsCommandLineServiceMac_h_ + +#include + +#include "nscore.h" +#include "nsError.h" + +#include "nsAEDefs.h" + +#ifdef __cplusplus + +class nsMacCommandLine +{ +public: + + + enum + { + kMaxBufferSize = 512, + kMaxTokens = 20 + }; + + nsMacCommandLine(); + ~nsMacCommandLine(); + + nsresult Initialize(int& argc, char**& argv); + + PRBool EnsureCommandLine(); + nsresult AddToCommandLine(const char* inArgText); + nsresult AddToCommandLine(const char* inOptionString, const FSSpec& inFileSpec); + nsresult AddToEnvironmentVars(const char* inArgText); + + OSErr HandleOpenOneDoc(const FSSpec& inFileSpec, OSType inFileType); + OSErr HandlePrintOneDoc(const FSSpec& inFileSpec, OSType fileType); + + OSErr DispatchURLToNewBrowser(const char* url); + + OSErr Quit(TAskSave askSave); + +protected: + + nsresult OpenWindow(const char *chrome, const PRUnichar *url); + + char* mArgBuffer; // the command line itself + char** mArgs; // array of pointers into argBuffer + + PRBool mStartedUp; + +public: + + static nsMacCommandLine& GetMacCommandLine() { return sMacCommandLine; } + +private: + + static nsMacCommandLine sMacCommandLine; + +}; + +#endif //__cplusplus + + +#ifdef __cplusplus +extern "C" { +#endif + +nsresult InitializeMacCommandLine(int& argc, char**& argv); + +#ifdef __cplusplus +} +#endif + + +#endif // nsCommandLineServiceMac_h_