1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
---|
2 | /* ***** BEGIN LICENSE BLOCK ***** |
---|
3 | * Version: NPL 1.1/GPL 2.0/LGPL 2.1 |
---|
4 | * |
---|
5 | * The contents of this file are subject to the Netscape Public License |
---|
6 | * Version 1.1 (the "License"); you may not use this file except in |
---|
7 | * compliance with the License. You may obtain a copy of the License at |
---|
8 | * http://www.mozilla.org/NPL/ |
---|
9 | * |
---|
10 | * Software distributed under the License is distributed on an "AS IS" basis, |
---|
11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
---|
12 | * for the specific language governing rights and limitations under the |
---|
13 | * License. |
---|
14 | * |
---|
15 | * The Original Code is Mozilla Communicator client code. |
---|
16 | * |
---|
17 | * The Initial Developer of the Original Code is |
---|
18 | * Netscape Communications Corporation. |
---|
19 | * Portions created by the Initial Developer are Copyright (C) 1998 |
---|
20 | * the Initial Developer. All Rights Reserved. |
---|
21 | * |
---|
22 | * Contributor(s): |
---|
23 | * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> |
---|
24 | * |
---|
25 | * Alternatively, the contents of this file may be used under the terms of |
---|
26 | * either the GNU General Public License Version 2 or later (the "GPL"), or |
---|
27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
---|
28 | * in which case the provisions of the GPL or the LGPL are applicable instead |
---|
29 | * of those above. If you wish to allow use of your version of this file only |
---|
30 | * under the terms of either the GPL or the LGPL, and not to allow others to |
---|
31 | * use your version of this file under the terms of the NPL, indicate your |
---|
32 | * decision by deleting the provisions above and replace them with the notice |
---|
33 | * and other provisions required by the GPL or the LGPL. If you do not delete |
---|
34 | * the provisions above, a recipient may use your version of this file under |
---|
35 | * the terms of any one of the NPL, the GPL or the LGPL. |
---|
36 | * |
---|
37 | * ***** END LICENSE BLOCK ***** */ |
---|
38 | |
---|
39 | |
---|
40 | #ifdef XPCOM_GLUE |
---|
41 | #include "nsXPCOMGlue.h" |
---|
42 | #endif |
---|
43 | |
---|
44 | #include "nsIServiceManager.h" |
---|
45 | #include "nsIComponentManager.h" |
---|
46 | #include "nsIGenericFactory.h" |
---|
47 | #include "nsIComponentRegistrar.h" |
---|
48 | |
---|
49 | #include "nsIPref.h" |
---|
50 | #include "nsILocaleService.h" |
---|
51 | #include "plevent.h" |
---|
52 | #include "prmem.h" |
---|
53 | #include "prnetdb.h" |
---|
54 | |
---|
55 | #include "nsCOMPtr.h" |
---|
56 | #include "nsIAppShell.h" |
---|
57 | #include "nsICmdLineService.h" |
---|
58 | #include "nsIAppShellService.h" |
---|
59 | #include "nsIAppStartupNotifier.h" |
---|
60 | #include "nsIObserverService.h" |
---|
61 | #include "nsAppShellCIDs.h" |
---|
62 | #include "prprf.h" |
---|
63 | #include "nsCRT.h" |
---|
64 | #include "nsIDirectoryService.h" |
---|
65 | #include "nsAppDirectoryServiceDefs.h" |
---|
66 | #include "nsIWindowMediator.h" |
---|
67 | #include "nsIDOMWindowInternal.h" |
---|
68 | #include "nsIClipboard.h" |
---|
69 | #include "nsXPCOM.h" |
---|
70 | #include "nsISupportsPrimitives.h" |
---|
71 | #include "nsICmdLineHandler.h" |
---|
72 | #include "nsICategoryManager.h" |
---|
73 | #include "nsXPIDLString.h" |
---|
74 | #include "nsIXULWindow.h" |
---|
75 | #include "nsIChromeRegistry.h" |
---|
76 | #include "nsIContentHandler.h" |
---|
77 | #include "nsIEventQueueService.h" |
---|
78 | #include "nsDirectoryServiceDefs.h" |
---|
79 | #include "nsBuildID.h" |
---|
80 | #include "nsWindowCreator.h" |
---|
81 | #include "nsIWindowWatcher.h" |
---|
82 | #include "nsProcess.h" |
---|
83 | #include "nsILocalFile.h" |
---|
84 | |
---|
85 | #ifdef MOZ_XPINSTALL |
---|
86 | #include "InstallCleanupDefines.h" |
---|
87 | #include "nsISoftwareUpdate.h" |
---|
88 | #endif |
---|
89 | |
---|
90 | // Interfaces Needed |
---|
91 | #include "nsIXULWindow.h" |
---|
92 | #include "nsIWebBrowserChrome.h" |
---|
93 | #include "nsIDocShell.h" |
---|
94 | |
---|
95 | // for X remote support |
---|
96 | #ifdef MOZ_ENABLE_XREMOTE |
---|
97 | #include "nsXRemoteClientCID.h" |
---|
98 | #include "nsIXRemoteClient.h" |
---|
99 | #include "nsIXRemoteService.h" |
---|
100 | #endif |
---|
101 | |
---|
102 | // see DoOnShutdown() |
---|
103 | #include "nsIProfile.h" |
---|
104 | |
---|
105 | #ifdef NS_TRACE_MALLOC |
---|
106 | #include "nsTraceMalloc.h" |
---|
107 | #endif |
---|
108 | |
---|
109 | #if defined(DEBUG) && defined(XP_WIN32) |
---|
110 | #include <malloc.h> |
---|
111 | #endif |
---|
112 | |
---|
113 | #if defined (XP_MACOSX) |
---|
114 | #include <Processes.h> |
---|
115 | #endif |
---|
116 | |
---|
117 | #include "nsITimelineService.h" |
---|
118 | |
---|
119 | #if defined(DEBUG_pra) |
---|
120 | #define DEBUG_CMD_LINE |
---|
121 | #endif |
---|
122 | |
---|
123 | static NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); |
---|
124 | static NS_DEFINE_CID(kIProcessCID, NS_PROCESS_CID); |
---|
125 | |
---|
126 | #define UILOCALE_CMD_LINE_ARG "-UILocale" |
---|
127 | #define CONTENTLOCALE_CMD_LINE_ARG "-contentLocale" |
---|
128 | |
---|
129 | extern "C" void ShowOSAlert(const char* aMessage); |
---|
130 | |
---|
131 | #define HELP_SPACER_1 "\t" |
---|
132 | #define HELP_SPACER_2 "\t\t" |
---|
133 | #define HELP_SPACER_4 "\t\t\t\t" |
---|
134 | |
---|
135 | #ifdef DEBUG |
---|
136 | #include "prlog.h" |
---|
137 | #endif |
---|
138 | |
---|
139 | #ifdef MOZ_JPROF |
---|
140 | #include "jprof.h" |
---|
141 | #endif |
---|
142 | |
---|
143 | // on x86 linux, the current builds of some popular plugins (notably |
---|
144 | // flashplayer and real) expect a few builtin symbols from libgcc |
---|
145 | // which were available in some older versions of gcc. However, |
---|
146 | // they're _NOT_ available in newer versions of gcc (eg 3.1), so if |
---|
147 | // we want those plugin to work with a gcc-3.1 built binary, we need |
---|
148 | // to provide these symbols. MOZ_ENABLE_OLD_ABI_COMPAT_WRAPPERS defaults |
---|
149 | // to true on x86 linux, and false everywhere else. |
---|
150 | // |
---|
151 | // The fact that the new and free operators are mismatched |
---|
152 | // mirrors the way the original functions in egcs 1.1.2 worked. |
---|
153 | |
---|
154 | #ifdef MOZ_ENABLE_OLD_ABI_COMPAT_WRAPPERS |
---|
155 | |
---|
156 | extern "C" { |
---|
157 | |
---|
158 | # ifndef HAVE___BUILTIN_VEC_NEW |
---|
159 | void *__builtin_vec_new(size_t aSize, const std::nothrow_t &aNoThrow) throw() |
---|
160 | { |
---|
161 | return ::operator new(aSize, aNoThrow); |
---|
162 | } |
---|
163 | # endif |
---|
164 | |
---|
165 | # ifndef HAVE___BUILTIN_VEC_DELETE |
---|
166 | void __builtin_vec_delete(void *aPtr, const std::nothrow_t &) throw () |
---|
167 | { |
---|
168 | if (aPtr) { |
---|
169 | free(aPtr); |
---|
170 | } |
---|
171 | } |
---|
172 | # endif |
---|
173 | |
---|
174 | # ifndef HAVE___BUILTIN_NEW |
---|
175 | void *__builtin_new(int aSize) |
---|
176 | { |
---|
177 | return malloc(aSize); |
---|
178 | } |
---|
179 | # endif |
---|
180 | |
---|
181 | # ifndef HAVE___BUILTIN_DELETE |
---|
182 | void __builtin_delete(void *aPtr) |
---|
183 | { |
---|
184 | free(aPtr); |
---|
185 | } |
---|
186 | # endif |
---|
187 | |
---|
188 | # ifndef HAVE___PURE_VIRTUAL |
---|
189 | void __pure_virtual(void) { |
---|
190 | extern void __cxa_pure_virtual(void); |
---|
191 | |
---|
192 | __cxa_pure_virtual(); |
---|
193 | } |
---|
194 | # endif |
---|
195 | } |
---|
196 | #endif |
---|
197 | |
---|
198 | #ifdef _BUILD_STATIC_BIN |
---|
199 | #include "nsStaticComponent.h" |
---|
200 | nsresult PR_CALLBACK |
---|
201 | app_getModuleInfo(nsStaticModuleInfo **info, PRUint32 *count); |
---|
202 | #endif |
---|
203 | |
---|
204 | #if defined(XP_UNIX) || defined(XP_BEOS) |
---|
205 | extern void InstallUnixSignalHandlers(const char *ProgramName); |
---|
206 | #endif |
---|
207 | |
---|
208 | #if defined(XP_OS2) |
---|
209 | /* Adding globals that OS/2 doesn't have so we can port the DDE code */ |
---|
210 | char **__argv; |
---|
211 | int __argc; |
---|
212 | #endif /* XP_OS2 */ |
---|
213 | |
---|
214 | #if defined(XP_BEOS) |
---|
215 | |
---|
216 | #include <AppKit.h> |
---|
217 | #include <AppFileInfo.h> |
---|
218 | |
---|
219 | class nsBeOSApp : public BApplication |
---|
220 | { |
---|
221 | public: |
---|
222 | nsBeOSApp(sem_id sem) |
---|
223 | : BApplication(GetAppSig()), init(sem) |
---|
224 | { |
---|
225 | } |
---|
226 | |
---|
227 | void ReadyToRun(void) |
---|
228 | { |
---|
229 | release_sem(init); |
---|
230 | } |
---|
231 | |
---|
232 | static int32 Main(void *args) |
---|
233 | { |
---|
234 | nsBeOSApp *app = new nsBeOSApp((sem_id)args); |
---|
235 | if (nsnull == app) |
---|
236 | return B_ERROR; |
---|
237 | return app->Run(); |
---|
238 | } |
---|
239 | |
---|
240 | private: |
---|
241 | char *GetAppSig(void) |
---|
242 | { |
---|
243 | app_info appInfo; |
---|
244 | BFile file; |
---|
245 | BAppFileInfo appFileInfo; |
---|
246 | image_info info; |
---|
247 | int32 cookie = 0; |
---|
248 | static char sig[B_MIME_TYPE_LENGTH]; |
---|
249 | |
---|
250 | sig[0] = 0; |
---|
251 | if (get_next_image_info(0, &cookie, &info) != B_OK || |
---|
252 | file.SetTo(info.name, B_READ_ONLY) != B_OK || |
---|
253 | appFileInfo.SetTo(&file) != B_OK || |
---|
254 | appFileInfo.GetSignature(sig) != B_OK) |
---|
255 | { |
---|
256 | return "application/x-vnd.Mozilla"; |
---|
257 | } |
---|
258 | return sig; |
---|
259 | } |
---|
260 | |
---|
261 | sem_id init; |
---|
262 | }; |
---|
263 | |
---|
264 | static nsresult InitializeBeOSApp(void) |
---|
265 | { |
---|
266 | nsresult rv = NS_OK; |
---|
267 | |
---|
268 | sem_id initsem = create_sem(0, "beapp init"); |
---|
269 | if (initsem < B_OK) |
---|
270 | return NS_ERROR_FAILURE; |
---|
271 | |
---|
272 | thread_id tid = spawn_thread(nsBeOSApp::Main, "BApplication", B_NORMAL_PRIORITY, (void *)initsem); |
---|
273 | if (tid < B_OK || B_OK != resume_thread(tid)) |
---|
274 | rv = NS_ERROR_FAILURE; |
---|
275 | |
---|
276 | if (B_OK != acquire_sem(initsem)) |
---|
277 | rv = NS_ERROR_FAILURE; |
---|
278 | if (B_OK != delete_sem(initsem)) |
---|
279 | rv = NS_ERROR_FAILURE; |
---|
280 | |
---|
281 | return rv; |
---|
282 | } |
---|
283 | |
---|
284 | #endif // XP_BEOS |
---|
285 | |
---|
286 | #if defined(XP_MAC) |
---|
287 | |
---|
288 | #include "macstdlibextras.h" |
---|
289 | #include <TextServices.h> |
---|
290 | |
---|
291 | // Set up the toolbox and (if DEBUG) the console. Do this in a static initializer, |
---|
292 | // to make it as unlikely as possible that somebody calls printf() before we get initialized. |
---|
293 | static struct MacInitializer { MacInitializer() { InitializeMacToolbox(); } } gInitializer; |
---|
294 | |
---|
295 | // Initialize profile services for both standalone and regular profiles |
---|
296 | static nsresult InitializeProfileService(nsICmdLineService *cmdLineArgs); |
---|
297 | |
---|
298 | // Install global locale if possible |
---|
299 | static nsresult InstallGlobalLocale(nsICmdLineService *cmdLineArgs); |
---|
300 | static nsresult getUILangCountry(nsAString& aUILang, nsAString& aCountry); |
---|
301 | |
---|
302 | class stTSMCloser |
---|
303 | { |
---|
304 | public: |
---|
305 | stTSMCloser() |
---|
306 | { |
---|
307 | // TSM is initialized in InitializeMacToolbox |
---|
308 | }; |
---|
309 | |
---|
310 | ~stTSMCloser() |
---|
311 | { |
---|
312 | #if !TARGET_CARBON |
---|
313 | (void)CloseTSMAwareApplication(); |
---|
314 | #endif |
---|
315 | } |
---|
316 | }; |
---|
317 | #endif // XP_MAC |
---|
318 | |
---|
319 | #if defined(XP_MACOSX) |
---|
320 | |
---|
321 | static void InitializeMacOSXApp(int argc, char* argv[]) |
---|
322 | { |
---|
323 | // use the location of the executable to learn where everything is, this |
---|
324 | // is because the current working directory is ill-defined when the |
---|
325 | // application is double-clicked from the Finder. |
---|
326 | char* path = strdup(argv[0]); |
---|
327 | char* lastSlash = strrchr(path, '/'); |
---|
328 | if (lastSlash) { |
---|
329 | *lastSlash = '\0'; |
---|
330 | setenv("MOZILLA_FIVE_HOME", path, 1); |
---|
331 | } |
---|
332 | free(path); |
---|
333 | } |
---|
334 | |
---|
335 | #endif /* XP_MACOSX */ |
---|
336 | |
---|
337 | #if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GTK2) |
---|
338 | #include <gtk/gtk.h> |
---|
339 | #endif //MOZ_WIDGET_GTK || MOZ_WIDGET_GTK2 |
---|
340 | |
---|
341 | /* Define Class IDs */ |
---|
342 | static NS_DEFINE_CID(kAppShellServiceCID, NS_APPSHELL_SERVICE_CID); |
---|
343 | static NS_DEFINE_CID(kCmdLineServiceCID, NS_COMMANDLINE_SERVICE_CID); |
---|
344 | |
---|
345 | #include "nsNativeAppSupport.h" |
---|
346 | |
---|
347 | /*********************************************/ |
---|
348 | // Default implemenations for nativeAppSupport |
---|
349 | // If your platform implements these functions if def out this code. |
---|
350 | #if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_PHOTON) && !defined( XP_WIN) && !defined(XP_OS2) && !defined( XP_BEOS ) && !defined(MOZ_WIDGET_GTK) && !defined(MOZ_WIDGET_GTK2) |
---|
351 | |
---|
352 | nsresult NS_CreateSplashScreen(nsISplashScreen **aResult) |
---|
353 | { |
---|
354 | nsresult rv = NS_OK; |
---|
355 | if (aResult) { |
---|
356 | *aResult = 0; |
---|
357 | } else { |
---|
358 | rv = NS_ERROR_NULL_POINTER; |
---|
359 | } |
---|
360 | return rv; |
---|
361 | } |
---|
362 | |
---|
363 | PRBool NS_CanRun() |
---|
364 | { |
---|
365 | return PR_TRUE; |
---|
366 | } |
---|
367 | #endif |
---|
368 | |
---|
369 | /*********************************************/ |
---|
370 | // Default implementation for new and improved |
---|
371 | // native app support. If your platform |
---|
372 | // implements nsINativeAppSupport then implement |
---|
373 | // this function and if def out this code. |
---|
374 | // |
---|
375 | // Note: For now, the default imiplementation returns 0 and |
---|
376 | // the code that calls this will defalt to use the old |
---|
377 | // nsISplashScreen interface directly. At some point |
---|
378 | // this function will return an instance of |
---|
379 | // nsNativeAppSupportBase which will use the older |
---|
380 | // "splash screen" interface. The code below will |
---|
381 | // then rely on nsINativeAppSupport and its use of |
---|
382 | // nsISplashScreen will be removed. |
---|
383 | // |
---|
384 | |
---|
385 | #if !defined(XP_WIN) && !defined(XP_OS2) && !defined(MOZ_WIDGET_GTK) && !defined(MOZ_WIDGET_GTK2) && !defined(XP_MAC) && (!defined(XP_MACOSX) || defined(MOZ_WIDGET_COCOA)) |
---|
386 | |
---|
387 | nsresult NS_CreateNativeAppSupport(nsINativeAppSupport **aResult) |
---|
388 | { |
---|
389 | nsresult rv = NS_OK; |
---|
390 | if (aResult) { |
---|
391 | *aResult = 0; |
---|
392 | } else { |
---|
393 | rv = NS_ERROR_NULL_POINTER; |
---|
394 | } |
---|
395 | return rv; |
---|
396 | } |
---|
397 | |
---|
398 | #endif |
---|
399 | |
---|
400 | static nsresult GetNativeAppSupport(nsINativeAppSupport** aNativeApp) |
---|
401 | { |
---|
402 | NS_ENSURE_ARG_POINTER(aNativeApp); |
---|
403 | *aNativeApp = nsnull; |
---|
404 | |
---|
405 | nsCOMPtr<nsIAppShellService> appShellService(do_GetService(kAppShellServiceCID)); |
---|
406 | if (appShellService) |
---|
407 | appShellService->GetNativeAppSupport(aNativeApp); |
---|
408 | |
---|
409 | return *aNativeApp ? NS_OK : NS_ERROR_FAILURE; |
---|
410 | } |
---|
411 | |
---|
412 | /* |
---|
413 | * This routine translates the nsresult into a platform specific return |
---|
414 | * code for the application... |
---|
415 | */ |
---|
416 | static int TranslateReturnValue(nsresult aResult) |
---|
417 | { |
---|
418 | if (NS_SUCCEEDED(aResult)) { |
---|
419 | return 0; |
---|
420 | } |
---|
421 | return 1; |
---|
422 | } |
---|
423 | |
---|
424 | #ifdef XP_MAC |
---|
425 | #include "nsCommandLineServiceMac.h" |
---|
426 | #endif |
---|
427 | |
---|
428 | static void |
---|
429 | PrintUsage(void) |
---|
430 | { |
---|
431 | fprintf(stderr, "Usage: apprunner <url>\n"); |
---|
432 | fprintf(stderr, "\t<url>: a fully defined url string like http:// etc..\n"); |
---|
433 | } |
---|
434 | |
---|
435 | static nsresult OpenWindow(const nsAFlatCString& aChromeURL, |
---|
436 | const nsAFlatString& aAppArgs, |
---|
437 | PRInt32 aWidth, PRInt32 aHeight); |
---|
438 | |
---|
439 | static nsresult OpenWindow(const nsAFlatCString& aChromeURL, |
---|
440 | const nsAFlatString& aAppArgs) |
---|
441 | { |
---|
442 | return OpenWindow(aChromeURL, aAppArgs, |
---|
443 | nsIAppShellService::SIZE_TO_CONTENT, |
---|
444 | nsIAppShellService::SIZE_TO_CONTENT); |
---|
445 | } |
---|
446 | |
---|
447 | static nsresult OpenWindow(const nsAFlatCString& aChromeURL, |
---|
448 | PRInt32 aWidth, PRInt32 aHeight) |
---|
449 | { |
---|
450 | return OpenWindow(aChromeURL, NS_LITERAL_STRING(""), aWidth, aHeight); |
---|
451 | } |
---|
452 | |
---|
453 | static nsresult OpenWindow(const nsAFlatCString& aChromeURL, |
---|
454 | const nsAFlatString& aAppArgs, |
---|
455 | PRInt32 aWidth, PRInt32 aHeight) |
---|
456 | { |
---|
457 | |
---|
458 | #ifdef DEBUG_CMD_LINE |
---|
459 | printf("OpenWindow(%s, %s, %d, %d)\n", aChromeURL.get(), |
---|
460 | NS_ConvertUCS2toUTF8(aAppArgs).get(), |
---|
461 | aWidth, aHeight); |
---|
462 | #endif /* DEBUG_CMD_LINE */ |
---|
463 | |
---|
464 | nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); |
---|
465 | nsCOMPtr<nsISupportsString> sarg(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID)); |
---|
466 | if (!wwatch || !sarg) |
---|
467 | return NS_ERROR_FAILURE; |
---|
468 | |
---|
469 | // Make sure a profile is selected. |
---|
470 | |
---|
471 | // We need the native app support object, which we get from |
---|
472 | // the app shell service. If this fails, we still proceed. |
---|
473 | // That's because some platforms don't have a native app |
---|
474 | // support implementation. On those platforms, "ensuring a |
---|
475 | // profile" is moot (because they don't support "-turbo", |
---|
476 | // basically). Specifically, because they don't do turbo, they will |
---|
477 | // *always* have a profile selected. |
---|
478 | nsCOMPtr<nsIAppShellService> appShell(do_GetService("@mozilla.org/appshell/appShellService;1")); |
---|
479 | nsCOMPtr <nsICmdLineService> cmdLine(do_GetService("@mozilla.org/appshell/commandLineService;1")); |
---|
480 | if (appShell && cmdLine) |
---|
481 | { |
---|
482 | nsCOMPtr<nsINativeAppSupport> nativeApp; |
---|
483 | if (NS_SUCCEEDED(appShell->GetNativeAppSupport(getter_AddRefs(nativeApp)))) |
---|
484 | { |
---|
485 | // Make sure profile has been selected. |
---|
486 | // At this point, we have to look for failure. That |
---|
487 | // handles the case where the user chooses "Exit" on |
---|
488 | // the profile manager window. |
---|
489 | if (NS_FAILED(nativeApp->EnsureProfile(cmdLine))) |
---|
490 | return NS_ERROR_NOT_INITIALIZED; |
---|
491 | } |
---|
492 | } |
---|
493 | |
---|
494 | sarg->SetData(aAppArgs); |
---|
495 | |
---|
496 | nsCAutoString features("chrome,dialog=no,all"); |
---|
497 | if (aHeight != nsIAppShellService::SIZE_TO_CONTENT) { |
---|
498 | features.Append(",height="); |
---|
499 | features.AppendInt(aHeight); |
---|
500 | } |
---|
501 | if (aWidth != nsIAppShellService::SIZE_TO_CONTENT) { |
---|
502 | features.Append(",width="); |
---|
503 | features.AppendInt(aWidth); |
---|
504 | } |
---|
505 | |
---|
506 | #ifdef DEBUG_CMD_LINE |
---|
507 | printf("features: %s...\n", features.get()); |
---|
508 | #endif /* DEBUG_CMD_LINE */ |
---|
509 | |
---|
510 | nsCOMPtr<nsIDOMWindow> newWindow; |
---|
511 | return wwatch->OpenWindow(0, aChromeURL.get(), "_blank", |
---|
512 | features.get(), sarg, |
---|
513 | getter_AddRefs(newWindow)); |
---|
514 | } |
---|
515 | |
---|
516 | static void DumpArbitraryHelp() |
---|
517 | { |
---|
518 | nsresult rv; |
---|
519 | nsCOMPtr<nsICategoryManager> catman(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv)); |
---|
520 | if(NS_SUCCEEDED(rv) && catman) { |
---|
521 | nsCOMPtr<nsISimpleEnumerator> e; |
---|
522 | rv = catman->EnumerateCategory(COMMAND_LINE_ARGUMENT_HANDLERS, getter_AddRefs(e)); |
---|
523 | if(NS_SUCCEEDED(rv) && e) { |
---|
524 | while (PR_TRUE) { |
---|
525 | nsCOMPtr<nsISupportsCString> catEntry; |
---|
526 | rv = e->GetNext(getter_AddRefs(catEntry)); |
---|
527 | if (NS_FAILED(rv) || !catEntry) break; |
---|
528 | |
---|
529 | nsCAutoString entryString; |
---|
530 | rv = catEntry->GetData(entryString); |
---|
531 | if (NS_FAILED(rv) || entryString.IsEmpty()) break; |
---|
532 | |
---|
533 | nsXPIDLCString contractidString; |
---|
534 | rv = catman->GetCategoryEntry(COMMAND_LINE_ARGUMENT_HANDLERS, |
---|
535 | entryString.get(), |
---|
536 | getter_Copies(contractidString)); |
---|
537 | if (NS_FAILED(rv) || !((const char *)contractidString)) break; |
---|
538 | |
---|
539 | #ifdef DEBUG_CMD_LINE |
---|
540 | printf("cmd line handler contractid = %s\n", (const char *)contractidString); |
---|
541 | #endif /* DEBUG_CMD_LINE */ |
---|
542 | |
---|
543 | nsCOMPtr <nsICmdLineHandler> handler(do_GetService((const char *)contractidString, &rv)); |
---|
544 | |
---|
545 | if (handler) { |
---|
546 | nsXPIDLCString commandLineArg; |
---|
547 | rv = handler->GetCommandLineArgument(getter_Copies(commandLineArg)); |
---|
548 | if (NS_FAILED(rv)) continue; |
---|
549 | |
---|
550 | nsXPIDLCString helpText; |
---|
551 | rv = handler->GetHelpText(getter_Copies(helpText)); |
---|
552 | if (NS_FAILED(rv)) continue; |
---|
553 | |
---|
554 | if ((const char *)commandLineArg) { |
---|
555 | printf("%s%s", HELP_SPACER_1,(const char *)commandLineArg); |
---|
556 | |
---|
557 | PRBool handlesArgs = PR_FALSE; |
---|
558 | rv = handler->GetHandlesArgs(&handlesArgs); |
---|
559 | if (NS_SUCCEEDED(rv) && handlesArgs) { |
---|
560 | printf(" <url>"); |
---|
561 | } |
---|
562 | if ((const char *)helpText) { |
---|
563 | printf("%s%s\n",HELP_SPACER_2,(const char *)helpText); |
---|
564 | } |
---|
565 | } |
---|
566 | } |
---|
567 | |
---|
568 | } |
---|
569 | } |
---|
570 | } |
---|
571 | return; |
---|
572 | } |
---|
573 | |
---|
574 | static nsresult |
---|
575 | LaunchApplicationWithArgs(const char *commandLineArg, |
---|
576 | nsICmdLineService *cmdLineArgs, |
---|
577 | const char *aParam, |
---|
578 | PRInt32 height, PRInt32 width, PRBool *windowOpened) |
---|
579 | { |
---|
580 | NS_ENSURE_ARG(commandLineArg); |
---|
581 | NS_ENSURE_ARG(cmdLineArgs); |
---|
582 | NS_ENSURE_ARG(aParam); |
---|
583 | NS_ENSURE_ARG(windowOpened); |
---|
584 | |
---|
585 | nsresult rv; |
---|
586 | |
---|
587 | nsCOMPtr<nsICmdLineService> cmdLine = |
---|
588 | do_GetService("@mozilla.org/appshell/commandLineService;1",&rv); |
---|
589 | if (NS_FAILED(rv)) return rv; |
---|
590 | |
---|
591 | nsCOMPtr <nsICmdLineHandler> handler; |
---|
592 | rv = cmdLine->GetHandlerForParam(aParam, getter_AddRefs(handler)); |
---|
593 | if (NS_FAILED(rv)) return rv; |
---|
594 | |
---|
595 | if (!handler) return NS_ERROR_FAILURE; |
---|
596 | |
---|
597 | nsXPIDLCString chromeUrlForTask; |
---|
598 | rv = handler->GetChromeUrlForTask(getter_Copies(chromeUrlForTask)); |
---|
599 | if (NS_FAILED(rv)) return rv; |
---|
600 | |
---|
601 | #ifdef DEBUG_CMD_LINE |
---|
602 | printf("XXX got this one:\t%s\n\t%s\n\n",commandLineArg,(const char *)chromeUrlForTask); |
---|
603 | #endif /* DEBUG_CMD_LINE */ |
---|
604 | |
---|
605 | nsXPIDLCString cmdResult; |
---|
606 | rv = cmdLineArgs->GetCmdLineValue(commandLineArg, getter_Copies(cmdResult)); |
---|
607 | if (NS_FAILED(rv)) return rv; |
---|
608 | #ifdef DEBUG_CMD_LINE |
---|
609 | printf("%s, cmdResult = %s\n",commandLineArg,(const char *)cmdResult); |
---|
610 | #endif /* DEBUG_CMD_LINE */ |
---|
611 | |
---|
612 | PRBool handlesArgs = PR_FALSE; |
---|
613 | rv = handler->GetHandlesArgs(&handlesArgs); |
---|
614 | if (handlesArgs) { |
---|
615 | if ((const char *)cmdResult) { |
---|
616 | if (PL_strcmp("1",(const char *)cmdResult)) { |
---|
617 | PRBool openWindowWithArgs = PR_TRUE; |
---|
618 | rv = handler->GetOpenWindowWithArgs(&openWindowWithArgs); |
---|
619 | if (NS_FAILED(rv)) return rv; |
---|
620 | |
---|
621 | if (openWindowWithArgs) { |
---|
622 | nsAutoString cmdArgs; cmdArgs.AssignWithConversion(cmdResult); |
---|
623 | #ifdef DEBUG_CMD_LINE |
---|
624 | printf("opening %s with %s\n", chromeUrlForTask.get(), "OpenWindow"); |
---|
625 | #endif /* DEBUG_CMD_LINE */ |
---|
626 | rv = OpenWindow(chromeUrlForTask, cmdArgs); |
---|
627 | } |
---|
628 | else { |
---|
629 | #ifdef DEBUG_CMD_LINE |
---|
630 | printf("opening %s with %s\n", cmdResult.get(), "OpenWindow"); |
---|
631 | #endif /* DEBUG_CMD_LINE */ |
---|
632 | rv = OpenWindow(cmdResult, width, height); |
---|
633 | if (NS_FAILED(rv)) return rv; |
---|
634 | } |
---|
635 | // If we get here without an error, then a window was opened OK. |
---|
636 | if (NS_SUCCEEDED(rv)) { |
---|
637 | *windowOpened = PR_TRUE; |
---|
638 | } |
---|
639 | } |
---|
640 | else { |
---|
641 | nsXPIDLString defaultArgs; |
---|
642 | rv = handler->GetDefaultArgs(getter_Copies(defaultArgs)); |
---|
643 | if (NS_FAILED(rv)) return rv; |
---|
644 | |
---|
645 | rv = OpenWindow(chromeUrlForTask, defaultArgs); |
---|
646 | if (NS_FAILED(rv)) return rv; |
---|
647 | // Window was opened OK. |
---|
648 | *windowOpened = PR_TRUE; |
---|
649 | } |
---|
650 | } |
---|
651 | } |
---|
652 | else { |
---|
653 | if (NS_SUCCEEDED(rv) && (const char*)cmdResult) { |
---|
654 | if (PL_strcmp("1",cmdResult) == 0) { |
---|
655 | rv = OpenWindow(chromeUrlForTask, width, height); |
---|
656 | if (NS_FAILED(rv)) return rv; |
---|
657 | } |
---|
658 | else { |
---|
659 | rv = OpenWindow(cmdResult, width, height); |
---|
660 | if (NS_FAILED(rv)) return rv; |
---|
661 | } |
---|
662 | // If we get here without an error, then a window was opened OK. |
---|
663 | if (NS_SUCCEEDED(rv)) { |
---|
664 | *windowOpened = PR_TRUE; |
---|
665 | } |
---|
666 | } |
---|
667 | } |
---|
668 | |
---|
669 | return NS_OK; |
---|
670 | } |
---|
671 | |
---|
672 | static PRBool IsStartupCommand(const char *arg) |
---|
673 | { |
---|
674 | if (!arg) return PR_FALSE; |
---|
675 | |
---|
676 | if (PL_strlen(arg) <= 1) return PR_FALSE; |
---|
677 | |
---|
678 | // windows allows /mail or -mail |
---|
679 | if ((arg[0] == '-') |
---|
680 | #if defined(XP_WIN) || defined(XP_OS2) |
---|
681 | || (arg[0] == '/') |
---|
682 | #endif /* XP_WIN || XP_OS2 */ |
---|
683 | ) { |
---|
684 | return PR_TRUE; |
---|
685 | } |
---|
686 | |
---|
687 | return PR_FALSE; |
---|
688 | } |
---|
689 | |
---|
690 | |
---|
691 | // This should be done by app shell enumeration someday |
---|
692 | nsresult DoCommandLines(nsICmdLineService* cmdLineArgs, PRBool heedGeneralStartupPrefs, PRBool *windowOpened) |
---|
693 | { |
---|
694 | NS_ENSURE_ARG(windowOpened); |
---|
695 | *windowOpened = PR_FALSE; |
---|
696 | |
---|
697 | nsresult rv; |
---|
698 | |
---|
699 | PRInt32 height = nsIAppShellService::SIZE_TO_CONTENT; |
---|
700 | PRInt32 width = nsIAppShellService::SIZE_TO_CONTENT; |
---|
701 | nsXPIDLCString tempString; |
---|
702 | |
---|
703 | // Get the value of -width option |
---|
704 | rv = cmdLineArgs->GetCmdLineValue("-width", getter_Copies(tempString)); |
---|
705 | if (NS_SUCCEEDED(rv) && !tempString.IsEmpty()) |
---|
706 | PR_sscanf(tempString.get(), "%d", &width); |
---|
707 | |
---|
708 | // Get the value of -height option |
---|
709 | rv = cmdLineArgs->GetCmdLineValue("-height", getter_Copies(tempString)); |
---|
710 | if (NS_SUCCEEDED(rv) && !tempString.IsEmpty()) |
---|
711 | PR_sscanf(tempString.get(), "%d", &height); |
---|
712 | |
---|
713 | if (heedGeneralStartupPrefs) { |
---|
714 | nsCOMPtr<nsIAppShellService> appShell(do_GetService("@mozilla.org/appshell/appShellService;1", &rv)); |
---|
715 | if (NS_FAILED(rv)) return rv; |
---|
716 | rv = appShell->CreateStartupState(width, height, windowOpened); |
---|
717 | if (NS_FAILED(rv)) return rv; |
---|
718 | } |
---|
719 | else { |
---|
720 | PRInt32 argc = 0; |
---|
721 | rv = cmdLineArgs->GetArgc(&argc); |
---|
722 | if (NS_FAILED(rv)) return rv; |
---|
723 | |
---|
724 | char **argv = nsnull; |
---|
725 | rv = cmdLineArgs->GetArgv(&argv); |
---|
726 | if (NS_FAILED(rv)) return rv; |
---|
727 | |
---|
728 | PRInt32 i = 0; |
---|
729 | for (i=1;i<argc;i++) { |
---|
730 | #ifdef DEBUG_CMD_LINE |
---|
731 | printf("XXX argv[%d] = %s\n",i,argv[i]); |
---|
732 | #endif /* DEBUG_CMD_LINE */ |
---|
733 | if (IsStartupCommand(argv[i])) { |
---|
734 | |
---|
735 | // skip over the - (or / on windows) |
---|
736 | char *command = argv[i] + 1; |
---|
737 | #ifdef XP_UNIX |
---|
738 | // unix allows -mail and --mail |
---|
739 | if ((argv[i][0] == '-') && (argv[i][1] == '-')) { |
---|
740 | command = argv[i] + 2; |
---|
741 | } |
---|
742 | #endif /* XP_UNIX */ |
---|
743 | |
---|
744 | // this can fail, as someone could do -foo, where -foo is not handled |
---|
745 | rv = LaunchApplicationWithArgs((const char *)(argv[i]), |
---|
746 | cmdLineArgs, command, |
---|
747 | height, width, windowOpened); |
---|
748 | if (rv == NS_ERROR_NOT_AVAILABLE || rv == NS_ERROR_ABORT) |
---|
749 | return rv; |
---|
750 | } |
---|
751 | } |
---|
752 | } |
---|
753 | return NS_OK; |
---|
754 | } |
---|
755 | |
---|
756 | static nsresult DoOnShutdown() |
---|
757 | { |
---|
758 | nsresult rv; |
---|
759 | |
---|
760 | // save the prefs, in case they weren't saved |
---|
761 | { |
---|
762 | // scoping this in a block to force release |
---|
763 | nsCOMPtr<nsIPref> prefs(do_GetService(NS_PREF_CONTRACTID, &rv)); |
---|
764 | NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get prefs, so unable to save them"); |
---|
765 | if (NS_SUCCEEDED(rv)) |
---|
766 | prefs->SavePrefFile(nsnull); |
---|
767 | } |
---|
768 | |
---|
769 | // call ShutDownCurrentProfile() so we update the last modified time of the profile |
---|
770 | { |
---|
771 | // scoping this in a block to force release |
---|
772 | nsCOMPtr<nsIProfile> profileMgr(do_GetService(NS_PROFILE_CONTRACTID, &rv)); |
---|
773 | NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get profile manager, so unable to update last modified time"); |
---|
774 | if (NS_SUCCEEDED(rv)) { |
---|
775 | profileMgr->ShutDownCurrentProfile(nsIProfile::SHUTDOWN_PERSIST); |
---|
776 | } |
---|
777 | } |
---|
778 | |
---|
779 | // at this point, all that is on the clipboard is a proxy object, but that object |
---|
780 | // won't be valid once the app goes away. As a result, we need to force the data |
---|
781 | // out of that proxy and properly onto the clipboard. This can't be done in the |
---|
782 | // clipboard service's shutdown routine because it requires the parser/etc which |
---|
783 | // has already been shutdown by the time the clipboard is shut down. |
---|
784 | { |
---|
785 | // scoping this in a block to force release |
---|
786 | nsCOMPtr<nsIClipboard> clipService(do_GetService("@mozilla.org/widget/clipboard;1", &rv)); |
---|
787 | if (NS_SUCCEEDED(rv)) |
---|
788 | clipService->ForceDataToClipboard(nsIClipboard::kGlobalClipboard); |
---|
789 | } |
---|
790 | |
---|
791 | return rv; |
---|
792 | } |
---|
793 | |
---|
794 | // match OS locale |
---|
795 | static char kMatchOSLocalePref[] = "intl.locale.matchOS"; |
---|
796 | |
---|
797 | nsresult |
---|
798 | getCountry(const nsAString& lc_name, nsAString& aCountry) |
---|
799 | { |
---|
800 | |
---|
801 | nsresult result = NS_OK; |
---|
802 | |
---|
803 | PRInt32 dash = lc_name.FindChar('-'); |
---|
804 | if (dash > 0) |
---|
805 | aCountry = Substring(lc_name, dash+1, lc_name.Length()-dash); |
---|
806 | else |
---|
807 | result = NS_ERROR_FAILURE; |
---|
808 | |
---|
809 | return result; |
---|
810 | } |
---|
811 | |
---|
812 | static nsresult |
---|
813 | getUILangCountry(nsAString& aUILang, nsAString& aCountry) |
---|
814 | { |
---|
815 | nsresult result; |
---|
816 | // get a locale service |
---|
817 | nsCOMPtr<nsILocaleService> localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &result); |
---|
818 | NS_ASSERTION(NS_SUCCEEDED(result),"getUILangCountry: get locale service failed"); |
---|
819 | |
---|
820 | nsXPIDLString uiLang; |
---|
821 | result = localeService->GetLocaleComponentForUserAgent(getter_Copies(uiLang)); |
---|
822 | aUILang = uiLang; |
---|
823 | result = getCountry(aUILang, aCountry); |
---|
824 | return result; |
---|
825 | } |
---|
826 | |
---|
827 | // update global locale if possible (in case when user-*.rdf can be updated) |
---|
828 | // so that any apps after this can be invoked in the UILocale and contentLocale |
---|
829 | static nsresult InstallGlobalLocale(nsICmdLineService *cmdLineArgs) |
---|
830 | { |
---|
831 | nsresult rv = NS_OK; |
---|
832 | |
---|
833 | // check the pref first |
---|
834 | nsCOMPtr<nsIPref> prefService(do_GetService(NS_PREF_CONTRACTID)); |
---|
835 | PRBool matchOS = PR_FALSE; |
---|
836 | if (prefService) |
---|
837 | prefService->GetBoolPref(kMatchOSLocalePref, &matchOS); |
---|
838 | |
---|
839 | // match os locale |
---|
840 | nsAutoString uiLang; |
---|
841 | nsAutoString country; |
---|
842 | if (matchOS) { |
---|
843 | // compute lang and region code only when needed! |
---|
844 | rv = getUILangCountry(uiLang, country); |
---|
845 | } |
---|
846 | |
---|
847 | nsXPIDLCString cmdUI; |
---|
848 | rv = cmdLineArgs->GetCmdLineValue(UILOCALE_CMD_LINE_ARG, getter_Copies(cmdUI)); |
---|
849 | if (NS_SUCCEEDED(rv)){ |
---|
850 | if (cmdUI) { |
---|
851 | nsCAutoString UILocaleName(cmdUI); |
---|
852 | nsCOMPtr<nsIXULChromeRegistry> chromeRegistry = do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv); |
---|
853 | if (chromeRegistry) |
---|
854 | rv = chromeRegistry->SelectLocale(UILocaleName, PR_FALSE); |
---|
855 | } |
---|
856 | } |
---|
857 | // match OS when no cmdline override |
---|
858 | if (!cmdUI && matchOS) { |
---|
859 | nsCOMPtr<nsIXULChromeRegistry> chromeRegistry = do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv); |
---|
860 | if (chromeRegistry) { |
---|
861 | chromeRegistry->SetRuntimeProvider(PR_TRUE); |
---|
862 | rv = chromeRegistry->SelectLocale(NS_ConvertUCS2toUTF8(uiLang), PR_FALSE); |
---|
863 | } |
---|
864 | } |
---|
865 | |
---|
866 | nsXPIDLCString cmdContent; |
---|
867 | rv = cmdLineArgs->GetCmdLineValue(CONTENTLOCALE_CMD_LINE_ARG, getter_Copies(cmdContent)); |
---|
868 | if (NS_SUCCEEDED(rv)){ |
---|
869 | if (cmdContent) { |
---|
870 | nsCAutoString contentLocaleName(cmdContent); |
---|
871 | nsCOMPtr<nsIXULChromeRegistry> chromeRegistry = do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv); |
---|
872 | if(chromeRegistry) |
---|
873 | rv = chromeRegistry->SelectLocale(contentLocaleName, PR_FALSE); |
---|
874 | } |
---|
875 | } |
---|
876 | // match OS when no cmdline override |
---|
877 | if (!cmdContent && matchOS) { |
---|
878 | nsCOMPtr<nsIXULChromeRegistry> chromeRegistry = do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv); |
---|
879 | if (chromeRegistry) { |
---|
880 | chromeRegistry->SetRuntimeProvider(PR_TRUE); |
---|
881 | rv = chromeRegistry->SelectLocale(NS_ConvertUCS2toUTF8(country), PR_FALSE); |
---|
882 | } |
---|
883 | } |
---|
884 | |
---|
885 | return NS_OK; |
---|
886 | } |
---|
887 | |
---|
888 | static nsresult InitializeProfileService(nsICmdLineService *cmdLineArgs) |
---|
889 | { |
---|
890 | // If we are being launched in -turbo mode, we cannot show UI |
---|
891 | PRBool shouldShowUI = PR_TRUE; |
---|
892 | nsCOMPtr<nsINativeAppSupport> nativeApp; |
---|
893 | if (NS_SUCCEEDED(GetNativeAppSupport(getter_AddRefs(nativeApp)))) |
---|
894 | nativeApp->GetShouldShowUI(&shouldShowUI); |
---|
895 | // If we were launched with -silent, we cannot show UI, either. |
---|
896 | if (shouldShowUI) { |
---|
897 | nsXPIDLCString arg; |
---|
898 | if (NS_SUCCEEDED(cmdLineArgs->GetCmdLineValue("-silent", getter_Copies(arg))) && (const char*)arg) { |
---|
899 | shouldShowUI = PR_FALSE; |
---|
900 | } |
---|
901 | } |
---|
902 | nsresult rv; |
---|
903 | nsCOMPtr<nsIAppShellService> appShellService(do_GetService(kAppShellServiceCID, &rv)); |
---|
904 | if (NS_FAILED(rv)) return rv; |
---|
905 | rv = appShellService->DoProfileStartup(cmdLineArgs, shouldShowUI); |
---|
906 | |
---|
907 | return rv; |
---|
908 | } |
---|
909 | |
---|
910 | static nsresult InitializeWindowCreator() |
---|
911 | { |
---|
912 | // create an nsWindowCreator and give it to the WindowWatcher service |
---|
913 | nsWindowCreator *creatorCallback = new nsWindowCreator(); |
---|
914 | if (!creatorCallback) |
---|
915 | return NS_ERROR_OUT_OF_MEMORY; |
---|
916 | |
---|
917 | nsCOMPtr<nsIWindowCreator> windowCreator(NS_STATIC_CAST(nsIWindowCreator *, creatorCallback)); |
---|
918 | if (windowCreator) { |
---|
919 | nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID)); |
---|
920 | if (wwatch) { |
---|
921 | wwatch->SetWindowCreator(windowCreator); |
---|
922 | return NS_OK; |
---|
923 | } |
---|
924 | } |
---|
925 | return NS_ERROR_FAILURE; |
---|
926 | } |
---|
927 | |
---|
928 | // Maximum allowed / used length of alert message is 255 chars, due to restrictions on Mac. |
---|
929 | // Please make sure that file contents and fallback_alert_text are at most 255 chars. |
---|
930 | // Fallback_alert_text must be non-const, because of inplace conversion on Mac. |
---|
931 | static void ShowOSAlertFromFile(int argc, char **argv, const char *alert_filename, const char* fallback_alert_text) |
---|
932 | { |
---|
933 | char message[256] = { 0 }; |
---|
934 | PRInt32 numRead = 0; |
---|
935 | const char *messageToShow = fallback_alert_text; |
---|
936 | nsresult rv; |
---|
937 | nsCOMPtr<nsILocalFile> fileName; |
---|
938 | nsCOMPtr<nsIProperties> directoryService; |
---|
939 | |
---|
940 | directoryService = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); |
---|
941 | if (NS_SUCCEEDED(rv)) { |
---|
942 | rv = directoryService->Get(NS_APP_RES_DIR, |
---|
943 | NS_GET_IID(nsIFile), |
---|
944 | getter_AddRefs(fileName)); |
---|
945 | if (NS_SUCCEEDED(rv) && fileName) { |
---|
946 | fileName->AppendNative(nsDependentCString(alert_filename)); |
---|
947 | PRFileDesc* fd = 0; |
---|
948 | fileName->OpenNSPRFileDesc(PR_RDONLY, 0664, &fd); |
---|
949 | if (fd) { |
---|
950 | numRead = PR_Read(fd, message, sizeof(message)-1); |
---|
951 | if (numRead > 0) { |
---|
952 | message[numRead] = 0; |
---|
953 | messageToShow = message; |
---|
954 | } |
---|
955 | } |
---|
956 | } |
---|
957 | } |
---|
958 | |
---|
959 | ShowOSAlert(messageToShow); |
---|
960 | } |
---|
961 | |
---|
962 | static nsresult VerifyInstallation(int argc, char **argv) |
---|
963 | { |
---|
964 | #ifdef MOZ_XPINSTALL |
---|
965 | nsresult rv; |
---|
966 | nsCOMPtr<nsILocalFile> registryFile; |
---|
967 | |
---|
968 | nsCOMPtr<nsIProperties> directoryService = |
---|
969 | do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); |
---|
970 | if (NS_FAILED(rv)) |
---|
971 | return NS_OK; |
---|
972 | rv = directoryService->Get(NS_APP_INSTALL_CLEANUP_DIR, |
---|
973 | NS_GET_IID(nsIFile), |
---|
974 | getter_AddRefs(registryFile)); |
---|
975 | if (NS_FAILED(rv) || !registryFile) |
---|
976 | return NS_ERROR_FAILURE; |
---|
977 | |
---|
978 | registryFile->AppendNative(CLEANUP_REGISTRY); |
---|
979 | |
---|
980 | PRBool exists; |
---|
981 | registryFile->Exists(&exists); |
---|
982 | if (exists) |
---|
983 | { |
---|
984 | nsCOMPtr<nsIFile> binPath; |
---|
985 | const char lastResortMessage[] = "A previous install did not complete correctly. Finishing install."; |
---|
986 | |
---|
987 | ShowOSAlertFromFile(argc, argv, CLEANUP_MESSAGE_FILENAME.get(), lastResortMessage); |
---|
988 | |
---|
989 | nsCOMPtr<nsIFile> cleanupUtility; |
---|
990 | registryFile->Clone(getter_AddRefs(cleanupUtility)); |
---|
991 | cleanupUtility->SetNativeLeafName(CLEANUP_UTIL); |
---|
992 | |
---|
993 | //Create the process framework to run the cleanup utility |
---|
994 | nsCOMPtr<nsIProcess> cleanupProcess = do_CreateInstance(kIProcessCID); |
---|
995 | rv = cleanupProcess->Init(cleanupUtility); |
---|
996 | if (NS_SUCCEEDED(rv)) |
---|
997 | rv = cleanupProcess->Run(PR_FALSE,nsnull, 0, nsnull); |
---|
998 | |
---|
999 | //We must exit because all open files must be released by the system |
---|
1000 | return NS_ERROR_FAILURE; |
---|
1001 | } |
---|
1002 | #endif |
---|
1003 | return NS_OK; |
---|
1004 | } |
---|
1005 | |
---|
1006 | #ifdef DEBUG_warren |
---|
1007 | #ifdef XP_WIN |
---|
1008 | #define _CRTDBG_MAP_ALLOC |
---|
1009 | #include <crtdbg.h> |
---|
1010 | #endif |
---|
1011 | #endif |
---|
1012 | |
---|
1013 | #if defined(FREEBSD) |
---|
1014 | // pick up fpsetmask prototype. |
---|
1015 | #include <ieeefp.h> |
---|
1016 | #endif |
---|
1017 | |
---|
1018 | // Note: nativeApp is an owning reference that this function has responsibility |
---|
1019 | // to release. This responsibility is delegated to the app shell service |
---|
1020 | // (see nsAppShellService::Initialize call, below). |
---|
1021 | static nsresult main1(int argc, char* argv[], nsISupports *nativeApp ) |
---|
1022 | { |
---|
1023 | nsresult rv; |
---|
1024 | NS_TIMELINE_ENTER("main1"); |
---|
1025 | nsCOMPtr<nsISupports> nativeAppOwner(dont_AddRef(nativeApp)); |
---|
1026 | |
---|
1027 | //---------------------------------------------------------------- |
---|
1028 | // First we need to check if a previous installation occured and |
---|
1029 | // if so, make sure it finished and cleaned up correctly. |
---|
1030 | // |
---|
1031 | // If there is an xpicleanup.dat file left around, that means the |
---|
1032 | // previous installation did not finish correctly. We must cleanup |
---|
1033 | // before a valid mozilla can run. |
---|
1034 | // |
---|
1035 | // Show the user a platform-specific Alert message, then spawn the |
---|
1036 | // xpicleanup utility, then exit. |
---|
1037 | //---------------------------------------------------------------- |
---|
1038 | rv = VerifyInstallation(argc, argv); |
---|
1039 | if (NS_FAILED(rv)) |
---|
1040 | return NS_ERROR_FAILURE; |
---|
1041 | |
---|
1042 | #ifdef DEBUG_warren |
---|
1043 | // _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_CHECK_ALWAYS_DF); |
---|
1044 | #endif |
---|
1045 | |
---|
1046 | #ifndef XP_MAC |
---|
1047 | // Unbuffer debug output (necessary for automated QA performance scripts). |
---|
1048 | setbuf(stdout, 0); |
---|
1049 | #endif |
---|
1050 | |
---|
1051 | #if defined(FREEBSD) |
---|
1052 | // Disable all SIGFPE's on FreeBSD, as it has non-IEEE-conformant fp |
---|
1053 | // trap behavior that trips up on floating-point tests performed by |
---|
1054 | // the JS engine. See bugzilla bug 9967 details. |
---|
1055 | fpsetmask(0); |
---|
1056 | #endif |
---|
1057 | |
---|
1058 | NS_TIMELINE_ENTER("init event service"); |
---|
1059 | nsCOMPtr<nsIEventQueueService> eventQService(do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv)); |
---|
1060 | if (NS_SUCCEEDED(rv)) { |
---|
1061 | // XXX: What if this fails? |
---|
1062 | rv = eventQService->CreateThreadEventQueue(); |
---|
1063 | } |
---|
1064 | NS_TIMELINE_LEAVE("init event service"); |
---|
1065 | |
---|
1066 | // Setup an autoreg obserer, so that we can update a progress |
---|
1067 | // string in the splash screen |
---|
1068 | nsCOMPtr<nsIObserverService> obsService(do_GetService("@mozilla.org/observer-service;1")); |
---|
1069 | if (obsService) |
---|
1070 | { |
---|
1071 | nsCOMPtr<nsIObserver> splashScreenObserver(do_QueryInterface(nativeAppOwner)); |
---|
1072 | if (splashScreenObserver) |
---|
1073 | { |
---|
1074 | obsService->AddObserver(splashScreenObserver, NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID, PR_FALSE); |
---|
1075 | obsService->AddObserver(splashScreenObserver, "startup_user_notifcations", PR_FALSE); |
---|
1076 | } |
---|
1077 | } |
---|
1078 | |
---|
1079 | #if XP_MAC |
---|
1080 | stTSMCloser tsmCloser; |
---|
1081 | |
---|
1082 | rv = InitializeMacCommandLine(argc, argv); |
---|
1083 | NS_ASSERTION(NS_SUCCEEDED(rv), "Initializing AppleEvents failed"); |
---|
1084 | #endif |
---|
1085 | |
---|
1086 | #ifdef DEBUG |
---|
1087 | // _Always_ autoreg if we're in a debug build, under the assumption |
---|
1088 | // that people are busily modifying components and will be angry if |
---|
1089 | // their changes aren't noticed. |
---|
1090 | nsCOMPtr<nsIComponentRegistrar> registrar; |
---|
1091 | NS_GetComponentRegistrar(getter_AddRefs(registrar)); |
---|
1092 | registrar->AutoRegister(nsnull); |
---|
1093 | registrar = nsnull; |
---|
1094 | #endif |
---|
1095 | |
---|
1096 | NS_TIMELINE_ENTER("startupNotifier"); |
---|
1097 | |
---|
1098 | // Start up the core services: |
---|
1099 | |
---|
1100 | // Please do not add new things to main1() - please hook into the |
---|
1101 | // nsIAppStartupNotifier service. |
---|
1102 | nsCOMPtr<nsIObserver> startupNotifier = do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID, &rv); |
---|
1103 | if(NS_FAILED(rv)) |
---|
1104 | return rv; |
---|
1105 | startupNotifier->Observe(nsnull, APPSTARTUP_TOPIC, nsnull); |
---|
1106 | NS_TIMELINE_LEAVE("startupNotifier"); |
---|
1107 | |
---|
1108 | NS_TIMELINE_ENTER("cmdLineArgs"); |
---|
1109 | |
---|
1110 | // Initialize the cmd line service |
---|
1111 | nsCOMPtr<nsICmdLineService> cmdLineArgs(do_GetService(kCmdLineServiceCID, &rv)); |
---|
1112 | NS_ASSERTION(NS_SUCCEEDED(rv), "Could not obtain CmdLine processing service\n"); |
---|
1113 | if (NS_FAILED(rv)) |
---|
1114 | return rv; |
---|
1115 | |
---|
1116 | rv = cmdLineArgs->Initialize(argc, argv); |
---|
1117 | NS_ASSERTION(NS_SUCCEEDED(rv), "failed to initialize command line args"); |
---|
1118 | if (rv == NS_ERROR_INVALID_ARG) { |
---|
1119 | PrintUsage(); |
---|
1120 | return rv; |
---|
1121 | } |
---|
1122 | |
---|
1123 | NS_TIMELINE_LEAVE("cmdLineArgs"); |
---|
1124 | |
---|
1125 | NS_TIMELINE_ENTER("InstallGlobalLocale"); |
---|
1126 | rv = InstallGlobalLocale(cmdLineArgs); |
---|
1127 | if(NS_FAILED(rv)) |
---|
1128 | return rv; |
---|
1129 | NS_TIMELINE_LEAVE("InstallGlobalLocale"); |
---|
1130 | |
---|
1131 | NS_TIMELINE_ENTER("appShell"); |
---|
1132 | |
---|
1133 | nsCOMPtr<nsIAppShellService> appShell(do_GetService(kAppShellServiceCID, &rv)); |
---|
1134 | NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get the appshell service"); |
---|
1135 | |
---|
1136 | /* if we couldn't get the nsIAppShellService service, then we should hide the |
---|
1137 | splash screen and return */ |
---|
1138 | if (NS_FAILED(rv)) |
---|
1139 | { |
---|
1140 | // See if platform supports nsINativeAppSupport. |
---|
1141 | nsCOMPtr<nsINativeAppSupport> nativeAppSupport(do_QueryInterface(nativeAppOwner)); |
---|
1142 | if (nativeAppSupport) |
---|
1143 | { |
---|
1144 | // Use that interface to remove splash screen. |
---|
1145 | nativeAppSupport->HideSplashScreen(); |
---|
1146 | } |
---|
1147 | else |
---|
1148 | { |
---|
1149 | // See if platform supports nsISplashScreen, instead. |
---|
1150 | nsCOMPtr<nsISplashScreen> splashScreen(do_QueryInterface(nativeAppOwner)); |
---|
1151 | if (splashScreen) |
---|
1152 | { |
---|
1153 | splashScreen->Hide(); |
---|
1154 | } |
---|
1155 | } |
---|
1156 | return rv; |
---|
1157 | } |
---|
1158 | |
---|
1159 | NS_TIMELINE_LEAVE("appShell"); |
---|
1160 | |
---|
1161 | NS_TIMELINE_ENTER("appShell->Initialize"); |
---|
1162 | |
---|
1163 | // Create the Application Shell instance... |
---|
1164 | rv = appShell->Initialize(cmdLineArgs, nativeAppOwner); |
---|
1165 | |
---|
1166 | NS_TIMELINE_LEAVE("appShell->Initialize"); |
---|
1167 | |
---|
1168 | NS_ASSERTION(NS_SUCCEEDED(rv), "failed to initialize appshell"); |
---|
1169 | if (NS_FAILED(rv)) return rv; |
---|
1170 | |
---|
1171 | rv = InitializeWindowCreator(); |
---|
1172 | NS_ASSERTION(NS_SUCCEEDED(rv), "failed to initialize window creator"); |
---|
1173 | if (NS_FAILED(rv)) return rv; |
---|
1174 | |
---|
1175 | // So we can open and close windows during startup |
---|
1176 | appShell->EnterLastWindowClosingSurvivalArea(); |
---|
1177 | |
---|
1178 | // Initialize Profile Service here. |
---|
1179 | NS_TIMELINE_ENTER("InitializeProfileService"); |
---|
1180 | rv = InitializeProfileService(cmdLineArgs); |
---|
1181 | NS_TIMELINE_LEAVE("InitializeProfileService"); |
---|
1182 | if (NS_FAILED(rv)) return rv; |
---|
1183 | |
---|
1184 | NS_TIMELINE_ENTER("appShell->CreateHiddenWindow"); |
---|
1185 | appShell->CreateHiddenWindow(); |
---|
1186 | NS_TIMELINE_LEAVE("appShell->CreateHiddenWindow"); |
---|
1187 | |
---|
1188 | // This will go away once Components are handling there own commandlines |
---|
1189 | // if we have no command line arguments, we need to heed the |
---|
1190 | // "general.startup.*" prefs |
---|
1191 | // if we had no command line arguments, argc == 1. |
---|
1192 | |
---|
1193 | PRBool windowOpened = PR_FALSE; |
---|
1194 | PRBool defaultStartup; |
---|
1195 | #if defined(XP_MAC) || defined(XP_MACOSX) |
---|
1196 | // On Mac, nsCommandLineServiceMac may have added synthetic |
---|
1197 | // args. Check this adjusted value instead of the raw value. |
---|
1198 | PRInt32 processedArgc; |
---|
1199 | cmdLineArgs->GetArgc(&processedArgc); |
---|
1200 | defaultStartup = (processedArgc == 1); |
---|
1201 | #if defined(XP_MACOSX) |
---|
1202 | // On OSX, we get passed two args if double-clicked from the Finder. |
---|
1203 | // The second is our PSN. Check for this and consider it to be default. |
---|
1204 | if (argc == 2 && processedArgc == 2) { |
---|
1205 | ProcessSerialNumber ourPSN; |
---|
1206 | if (::MacGetCurrentProcess(&ourPSN) == noErr) { |
---|
1207 | char argBuf[64]; |
---|
1208 | sprintf(argBuf, "-psn_%ld_%ld", ourPSN.highLongOfPSN, ourPSN.lowLongOfPSN); |
---|
1209 | if (!strcmp(argBuf, argv[1])) |
---|
1210 | defaultStartup = PR_TRUE; |
---|
1211 | } |
---|
1212 | } |
---|
1213 | #endif /* XP_MACOSX */ |
---|
1214 | #else |
---|
1215 | defaultStartup = (argc == 1); |
---|
1216 | #endif |
---|
1217 | rv = DoCommandLines(cmdLineArgs, defaultStartup, &windowOpened); |
---|
1218 | if (NS_FAILED(rv)) |
---|
1219 | { |
---|
1220 | NS_WARNING("failed to process command line"); |
---|
1221 | return rv; |
---|
1222 | } |
---|
1223 | |
---|
1224 | if (obsService) |
---|
1225 | { |
---|
1226 | nsAutoString userMessage; userMessage.AssignWithConversion("Creating first window..."); |
---|
1227 | obsService->NotifyObservers(nsnull, "startup_user_notifcations", userMessage.get()); |
---|
1228 | } |
---|
1229 | |
---|
1230 | |
---|
1231 | // Make sure there exists at least 1 window. |
---|
1232 | NS_TIMELINE_ENTER("Ensure1Window"); |
---|
1233 | rv = appShell->Ensure1Window(cmdLineArgs); |
---|
1234 | NS_TIMELINE_LEAVE("Ensure1Window"); |
---|
1235 | NS_ASSERTION(NS_SUCCEEDED(rv), "failed to Ensure1Window"); |
---|
1236 | if (NS_FAILED(rv)) return rv; |
---|
1237 | |
---|
1238 | #if !defined(XP_MAC) && !defined(XP_MACOSX) |
---|
1239 | appShell->ExitLastWindowClosingSurvivalArea(); |
---|
1240 | #endif |
---|
1241 | |
---|
1242 | #ifdef MOZ_ENABLE_XREMOTE |
---|
1243 | // if we have X remote support and we have our one window up and |
---|
1244 | // running start listening for requests on the proxy window. |
---|
1245 | nsCOMPtr<nsIXRemoteService> remoteService; |
---|
1246 | remoteService = do_GetService(NS_IXREMOTESERVICE_CONTRACTID); |
---|
1247 | if (remoteService) |
---|
1248 | remoteService->Startup(); |
---|
1249 | #endif /* MOZ_ENABLE_XREMOTE */ |
---|
1250 | |
---|
1251 | // remove the nativeApp as an XPCOM autoreg observer |
---|
1252 | if (obsService) |
---|
1253 | { |
---|
1254 | nsCOMPtr<nsIObserver> splashScreenObserver(do_QueryInterface(nativeAppOwner)); |
---|
1255 | if (splashScreenObserver) |
---|
1256 | { |
---|
1257 | obsService->RemoveObserver(splashScreenObserver, NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID); |
---|
1258 | obsService->RemoveObserver(splashScreenObserver, "startup_user_notifcations"); |
---|
1259 | } |
---|
1260 | } |
---|
1261 | |
---|
1262 | // We are done with the native app (or splash screen) object here; |
---|
1263 | // the app shell owns it now. |
---|
1264 | nativeAppOwner = nsnull; |
---|
1265 | |
---|
1266 | // Start main event loop |
---|
1267 | NS_TIMELINE_ENTER("appShell->Run"); |
---|
1268 | rv = appShell->Run(); |
---|
1269 | NS_TIMELINE_LEAVE("appShell->Run"); |
---|
1270 | NS_ASSERTION(NS_SUCCEEDED(rv), "failed to run appshell"); |
---|
1271 | |
---|
1272 | #ifdef MOZ_ENABLE_XREMOTE |
---|
1273 | // shut down the x remote proxy window |
---|
1274 | if (remoteService) |
---|
1275 | remoteService->Shutdown(); |
---|
1276 | #endif /* MOZ_ENABLE_XREMOTE */ |
---|
1277 | |
---|
1278 | #ifdef MOZ_TIMELINE |
---|
1279 | // Make sure we print this out even if timeline is runtime disabled |
---|
1280 | if (NS_FAILED(NS_TIMELINE_LEAVE("main1"))) |
---|
1281 | NS_TimelineForceMark("...main1"); |
---|
1282 | #endif |
---|
1283 | |
---|
1284 | return rv; |
---|
1285 | } |
---|
1286 | |
---|
1287 | // English text needs to go into a dtd file. |
---|
1288 | // But when this is called we have no components etc. These strings must either be |
---|
1289 | // here, or in a native resource file. |
---|
1290 | static void DumpHelp(char *appname) |
---|
1291 | { |
---|
1292 | printf("Usage: %s [ options ... ] [URL]\n", appname); |
---|
1293 | printf(" where options include:\n"); |
---|
1294 | printf("\n"); |
---|
1295 | |
---|
1296 | #ifdef MOZ_WIDGET_GTK |
---|
1297 | /* insert gtk options above moz options, like any other gtk app |
---|
1298 | * |
---|
1299 | * note: this isn't a very cool way to do things -- i'd rather get |
---|
1300 | * these straight from a user's gtk version -- but it seems to be |
---|
1301 | * what most gtk apps do. -dr |
---|
1302 | */ |
---|
1303 | |
---|
1304 | printf("GTK options\n"); |
---|
1305 | printf("%s--gdk-debug=FLAGS%sGdk debugging flags to set\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1306 | printf("%s--gdk-no-debug=FLAGS%sGdk debugging flags to unset\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1307 | printf("%s--gtk-debug=FLAGS%sGtk+ debugging flags to set\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1308 | printf("%s--gtk-no-debug=FLAGS%sGtk+ debugging flags to unset\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1309 | printf("%s--gtk-module=MODULE%sLoad an additional Gtk module\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1310 | printf("%s-install%sInstall a private colormap\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1311 | |
---|
1312 | /* end gtk toolkit options */ |
---|
1313 | #endif /* MOZ_WIDGET_GTK */ |
---|
1314 | #if MOZ_WIDGET_XLIB |
---|
1315 | printf("Xlib options\n"); |
---|
1316 | printf("%s-display=DISPLAY%sX display to use\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1317 | printf("%s-visual=VISUALID%sX visual to use\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1318 | printf("%s-install_colormap%sInstall own colormap\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1319 | printf("%s-sync%sMake X calls synchronous\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1320 | printf("%s-no-xshm%sDon't use X shared memory extension\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1321 | |
---|
1322 | /* end xlib toolkit options */ |
---|
1323 | #endif /* MOZ_WIDGET_XLIB */ |
---|
1324 | #ifdef MOZ_X11 |
---|
1325 | printf("X11 options\n"); |
---|
1326 | printf("%s--display=DISPLAY%sX display to use\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1327 | printf("%s--sync%sMake X calls synchronous\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1328 | printf("%s--no-xshm%sDon't use X shared memory extension\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1329 | printf("%s--xim-preedit=STYLE\n", HELP_SPACER_1); |
---|
1330 | printf("%s--xim-status=STYLE\n", HELP_SPACER_1); |
---|
1331 | #endif |
---|
1332 | #ifdef XP_UNIX |
---|
1333 | printf("%s--g-fatal-warnings%sMake all warnings fatal\n", HELP_SPACER_1, HELP_SPACER_2); |
---|
1334 | |
---|
1335 | printf("\nMozilla options\n"); |
---|
1336 | #endif |
---|
1337 | |
---|
1338 | printf("%s-height <value>%sSet height of startup window to <value>.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1339 | printf("%s-h or -help%sPrint this message.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1340 | printf("%s-installer%sStart with 4.x migration window.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1341 | printf("%s-width <value>%sSet width of startup window to <value>.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1342 | printf("%s-v or -version%sPrint %s version.\n",HELP_SPACER_1,HELP_SPACER_2, appname); |
---|
1343 | printf("%s-CreateProfile <profile>%sCreate <profile>.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1344 | printf("%s-P <profile>%sStart with <profile>.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1345 | printf("%s-ProfileWizard%sStart with profile wizard.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1346 | printf("%s-ProfileManager%sStart with profile manager.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1347 | printf("%s-SelectProfile%sStart with profile selection dialog.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1348 | printf("%s-UILocale <locale>%sStart with <locale> resources as UI Locale.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1349 | printf("%s-contentLocale <locale>%sStart with <locale> resources as content Locale.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1350 | #ifdef XP_WIN32 |
---|
1351 | printf("%s-console%sStart Mozilla with a debugging console.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1352 | #endif |
---|
1353 | #ifdef MOZ_ENABLE_XREMOTE |
---|
1354 | printf("%s-remote <command>%sExecute <command> in an already running\n" |
---|
1355 | "%sMozilla process. For more info, see:\n" |
---|
1356 | "\n%shttp://www.mozilla.org/unix/remote.html\n\n", |
---|
1357 | HELP_SPACER_1,HELP_SPACER_1,HELP_SPACER_4,HELP_SPACER_2); |
---|
1358 | printf("%s-splash%sEnable splash screen.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1359 | #else |
---|
1360 | printf("%s-nosplash%sDisable splash screen.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1361 | #if defined(XP_WIN) || defined(XP_OS2) |
---|
1362 | printf("%s-quiet%sDisable splash screen.\n",HELP_SPACER_1,HELP_SPACER_2); |
---|
1363 | #endif |
---|
1364 | #endif |
---|
1365 | |
---|
1366 | // this works, but only after the components have registered. so if you drop in a new command line handler, -help |
---|
1367 | // won't not until the second run. |
---|
1368 | // out of the bug, because we ship a component.reg file, it works correctly. |
---|
1369 | DumpArbitraryHelp(); |
---|
1370 | } |
---|
1371 | |
---|
1372 | |
---|
1373 | static nsresult DumpVersion(char *appname) |
---|
1374 | { |
---|
1375 | nsresult rv = NS_OK; |
---|
1376 | long buildID = NS_BUILD_ID; // 10-digit number |
---|
1377 | |
---|
1378 | printf("Mozilla %s, Copyright (c) 2003 mozilla.org", MOZILLA_VERSION); |
---|
1379 | |
---|
1380 | if(buildID) { |
---|
1381 | printf(", build %u\n", (unsigned int)buildID); |
---|
1382 | } else { |
---|
1383 | printf(" <developer build>\n"); |
---|
1384 | } |
---|
1385 | |
---|
1386 | return rv; |
---|
1387 | } |
---|
1388 | |
---|
1389 | #ifdef MOZ_ENABLE_XREMOTE |
---|
1390 | // use int here instead of a PR type since it will be returned |
---|
1391 | // from main - just to keep types consistent |
---|
1392 | static int HandleRemoteArguments(int argc, char* argv[], PRBool *aArgUsed) |
---|
1393 | { |
---|
1394 | int i = 0; |
---|
1395 | for (i=1; i < argc; i++) { |
---|
1396 | if (PL_strcasecmp(argv[i], "-remote") == 0) { |
---|
1397 | // someone used a -remote flag |
---|
1398 | *aArgUsed = PR_TRUE; |
---|
1399 | // check to make sure there's another arg |
---|
1400 | if (argc-1 == i) { |
---|
1401 | PR_fprintf(PR_STDERR, "-remote requires an argument\n"); |
---|
1402 | return 1; |
---|
1403 | } |
---|
1404 | // try to get the X remote client |
---|
1405 | nsCOMPtr<nsIXRemoteClient> client (do_CreateInstance(NS_XREMOTECLIENT_CONTRACTID)); |
---|
1406 | if (!client) |
---|
1407 | return 1; |
---|
1408 | nsresult rv; |
---|
1409 | // try to init - connects to the X server and stuff |
---|
1410 | rv = client->Init(); |
---|
1411 | if (NS_FAILED(rv)) { |
---|
1412 | PR_fprintf(PR_STDERR, "Failed to connect to X server.\n"); |
---|
1413 | return 1; |
---|
1414 | } |
---|
1415 | PRBool success = PR_FALSE; |
---|
1416 | rv = client->SendCommand(argv[i+1], &success); |
---|
1417 | // did the command fail? |
---|
1418 | if (NS_FAILED(rv)) { |
---|
1419 | PR_fprintf(PR_STDERR, "Failed to send command.\n"); |
---|
1420 | return 1; |
---|
1421 | } |
---|
1422 | // was there a window not running? |
---|
1423 | if (!success) { |
---|
1424 | PR_fprintf(PR_STDERR, "No running window found.\n"); |
---|
1425 | return 2; |
---|
1426 | } |
---|
1427 | client->Shutdown(); |
---|
1428 | // success |
---|
1429 | return 0; |
---|
1430 | } |
---|
1431 | } |
---|
1432 | return 0; |
---|
1433 | } |
---|
1434 | #endif /* XP_UNIX */ |
---|
1435 | |
---|
1436 | static PRBool HandleDumpArguments(int argc, char* argv[]) |
---|
1437 | { |
---|
1438 | for (int i=1; i<argc; i++) { |
---|
1439 | if ((PL_strcasecmp(argv[i], "-h") == 0) |
---|
1440 | || (PL_strcasecmp(argv[i], "-help") == 0) |
---|
1441 | #if defined(XP_UNIX) || defined(XP_BEOS) |
---|
1442 | || (PL_strcasecmp(argv[i], "--help") == 0) |
---|
1443 | #endif /* XP_UNIX || XP_BEOS*/ |
---|
1444 | #if defined(XP_WIN) || defined(XP_OS2) |
---|
1445 | || (PL_strcasecmp(argv[i], "/h") == 0) |
---|
1446 | || (PL_strcasecmp(argv[i], "/help") == 0) |
---|
1447 | || (PL_strcasecmp(argv[i], "/?") == 0) |
---|
1448 | #endif /* XP_WIN || XP_OS2 */ |
---|
1449 | ) { |
---|
1450 | DumpHelp(argv[0]); |
---|
1451 | return PR_TRUE; |
---|
1452 | } |
---|
1453 | if ((PL_strcasecmp(argv[i], "-v") == 0) |
---|
1454 | || (PL_strcasecmp(argv[i], "-version") == 0) |
---|
1455 | #if defined(XP_UNIX) || defined(XP_BEOS) |
---|
1456 | || (PL_strcasecmp(argv[i], "--version") == 0) |
---|
1457 | #endif /* XP_UNIX || XP_BEOS */ |
---|
1458 | #if defined(XP_WIN) || defined(XP_OS2) |
---|
1459 | || (PL_strcasecmp(argv[i], "/v") == 0) |
---|
1460 | || (PL_strcasecmp(argv[i], "/version") == 0) |
---|
1461 | #endif /* XP_WIN || XP_OS2 */ |
---|
1462 | ) { |
---|
1463 | DumpVersion(argv[0]); |
---|
1464 | return PR_TRUE; |
---|
1465 | } |
---|
1466 | } |
---|
1467 | |
---|
1468 | return PR_FALSE; |
---|
1469 | } |
---|
1470 | |
---|
1471 | |
---|
1472 | static PRBool GetWantSplashScreen(int argc, char* argv[]) |
---|
1473 | { |
---|
1474 | int i; |
---|
1475 | PRBool dosplash; |
---|
1476 | // We can't use the command line service here because it isn't running yet |
---|
1477 | #if defined(XP_UNIX) && !defined(MOZ_WIDGET_PHOTON) |
---|
1478 | dosplash = PR_FALSE; |
---|
1479 | for (i=1; i<argc; i++) |
---|
1480 | if ((PL_strcasecmp(argv[i], "-splash") == 0) |
---|
1481 | || (PL_strcasecmp(argv[i], "--splash") == 0)) |
---|
1482 | dosplash = PR_TRUE; |
---|
1483 | #else |
---|
1484 | dosplash = PR_TRUE; |
---|
1485 | for (i=1; i<argc; i++) |
---|
1486 | if ((PL_strcasecmp(argv[i], "-nosplash") == 0) |
---|
1487 | #ifdef XP_BEOS |
---|
1488 | || (PL_strcasecmp(argv[i], "--nosplash") == 0) |
---|
1489 | #endif /* XP_BEOS */ |
---|
1490 | #if defined(XP_WIN) || defined(XP_OS2) |
---|
1491 | || (PL_strcasecmp(argv[i], "/nosplash") == 0) |
---|
1492 | #endif /* XP_WIN || XP_OS2 */ |
---|
1493 | ) { |
---|
1494 | dosplash = PR_FALSE; |
---|
1495 | } |
---|
1496 | #endif |
---|
1497 | |
---|
1498 | return dosplash; |
---|
1499 | } |
---|
1500 | |
---|
1501 | int main(int argc, char* argv[]) |
---|
1502 | { |
---|
1503 | NS_TIMELINE_MARK("enter main"); |
---|
1504 | |
---|
1505 | #if defined(DEBUG) && defined(XP_WIN32) |
---|
1506 | // Disable small heap allocator to get heapwalk() giving us |
---|
1507 | // accurate heap numbers. Win2k non-debug does not use small heap allocator. |
---|
1508 | // Win2k debug seems to be still using it. |
---|
1509 | // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__set_sbh_threshold.asp |
---|
1510 | _set_sbh_threshold(0); |
---|
1511 | #endif |
---|
1512 | |
---|
1513 | #if defined(XP_UNIX) || defined(XP_BEOS) |
---|
1514 | InstallUnixSignalHandlers(argv[0]); |
---|
1515 | #endif |
---|
1516 | |
---|
1517 | #if defined(XP_OS2) |
---|
1518 | __argc = argc; |
---|
1519 | __argv = argv; |
---|
1520 | |
---|
1521 | ULONG ulMaxFH = 0; |
---|
1522 | LONG ulReqCount = 0; |
---|
1523 | APIRET rc = NO_ERROR; |
---|
1524 | |
---|
1525 | DosSetRelMaxFH(&ulReqCount, |
---|
1526 | &ulMaxFH); |
---|
1527 | |
---|
1528 | if (ulMaxFH < 256) { |
---|
1529 | DosSetMaxFH(256); |
---|
1530 | } |
---|
1531 | #endif /* XP_OS2 */ |
---|
1532 | |
---|
1533 | #if defined(XP_BEOS) |
---|
1534 | if (NS_OK != InitializeBeOSApp()) |
---|
1535 | return 1; |
---|
1536 | #endif |
---|
1537 | |
---|
1538 | #if defined(XP_MACOSX) |
---|
1539 | InitializeMacOSXApp(argc, argv); |
---|
1540 | #endif |
---|
1541 | |
---|
1542 | #ifdef _BUILD_STATIC_BIN |
---|
1543 | // Initialize XPCOM's module info table |
---|
1544 | NSGetStaticModuleInfo = app_getModuleInfo; |
---|
1545 | #endif |
---|
1546 | |
---|
1547 | // Handle -help and -version command line arguments. |
---|
1548 | // They should% return quick, so we deal with them here. |
---|
1549 | if (HandleDumpArguments(argc, argv)) |
---|
1550 | return 0; |
---|
1551 | |
---|
1552 | #ifdef NS_TRACE_MALLOC |
---|
1553 | argc = NS_TraceMallocStartupArgs(argc, argv); |
---|
1554 | #endif |
---|
1555 | |
---|
1556 | #if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_GTK2) |
---|
1557 | // Initialize GTK+1/2 here for splash |
---|
1558 | #if defined(MOZ_WIDGET_GTK) |
---|
1559 | gtk_set_locale(); |
---|
1560 | #endif |
---|
1561 | gtk_init(&argc, &argv); |
---|
1562 | #endif /* MOZ_WIDGET_GTK || MOZ_WIDGET_GTK2 */ |
---|
1563 | |
---|
1564 | // Call the code to install our handler |
---|
1565 | #ifdef MOZ_JPROF |
---|
1566 | setupProfilingStuff(); |
---|
1567 | #endif |
---|
1568 | |
---|
1569 | |
---|
1570 | #ifdef XPCOM_GLUE |
---|
1571 | NS_TIMELINE_MARK("GRE_Startup..."); |
---|
1572 | nsresult rv = GRE_Startup(); |
---|
1573 | NS_TIMELINE_MARK("...GRE_Startup done"); |
---|
1574 | if (NS_FAILED(rv)) { |
---|
1575 | // We should be displaying a dialog here with the reason why we failed. |
---|
1576 | NS_WARNING("GRE_Startup failed"); |
---|
1577 | return 1; |
---|
1578 | } |
---|
1579 | #else |
---|
1580 | NS_TIMELINE_MARK("NS_InitXPCOM2..."); |
---|
1581 | nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); |
---|
1582 | NS_TIMELINE_MARK("...NS_InitXPCOM2 done"); |
---|
1583 | if (NS_FAILED(rv)) { |
---|
1584 | // We should be displaying a dialog here with the reason why we failed. |
---|
1585 | NS_WARNING("NS_InitXPCOM2 failed"); |
---|
1586 | return 1; |
---|
1587 | } |
---|
1588 | #endif |
---|
1589 | |
---|
1590 | |
---|
1591 | // Try to allocate "native app support." |
---|
1592 | // Note: this object is not released here. It is passed to main1 which |
---|
1593 | // has responsibility to release it. |
---|
1594 | nsINativeAppSupport *nativeApp = 0; |
---|
1595 | rv = NS_CreateNativeAppSupport(&nativeApp); |
---|
1596 | |
---|
1597 | // See if we can run. |
---|
1598 | if (nativeApp) |
---|
1599 | { |
---|
1600 | PRBool canRun = PR_FALSE; |
---|
1601 | rv = nativeApp->Start(&canRun); |
---|
1602 | if (!canRun) { |
---|
1603 | return 1; |
---|
1604 | } |
---|
1605 | } else { |
---|
1606 | // If platform doesn't implement nsINativeAppSupport, fall |
---|
1607 | // back to old method. |
---|
1608 | if (!NS_CanRun()) |
---|
1609 | return 1; |
---|
1610 | } |
---|
1611 | // Note: this object is not released here. It is passed to main1 which |
---|
1612 | // has responsibility to release it. |
---|
1613 | nsISplashScreen *splash = 0; |
---|
1614 | PRBool dosplash = GetWantSplashScreen(argc, argv); |
---|
1615 | |
---|
1616 | if (dosplash && !nativeApp) { |
---|
1617 | // If showing splash screen and platform doesn't implement |
---|
1618 | // nsINativeAppSupport, then use older nsISplashScreen interface. |
---|
1619 | rv = NS_CreateSplashScreen(&splash); |
---|
1620 | NS_ASSERTION(NS_SUCCEEDED(rv), "NS_CreateSplashScreen failed"); |
---|
1621 | } |
---|
1622 | // If the platform has a splash screen, show it ASAP. |
---|
1623 | if (dosplash && nativeApp) { |
---|
1624 | nativeApp->ShowSplashScreen(); |
---|
1625 | } else if (splash) { |
---|
1626 | splash->Show(); |
---|
1627 | } |
---|
1628 | |
---|
1629 | #ifdef MOZ_ENABLE_XREMOTE |
---|
1630 | // handle -remote now that xpcom is fired up |
---|
1631 | int remoterv; |
---|
1632 | PRBool argused = PR_FALSE; |
---|
1633 | // argused will be true if someone tried to use a -remote flag. We |
---|
1634 | // always exit in that case. |
---|
1635 | remoterv = HandleRemoteArguments(argc, argv, &argused); |
---|
1636 | |
---|
1637 | if (argused) { |
---|
1638 | #ifdef XPCOM_GLUE |
---|
1639 | GRE_Shutdown(); |
---|
1640 | #else |
---|
1641 | NS_ShutdownXPCOM(nsnull); |
---|
1642 | #endif |
---|
1643 | return remoterv; |
---|
1644 | } |
---|
1645 | #endif |
---|
1646 | |
---|
1647 | nsresult mainResult = main1(argc, argv, nativeApp ? (nsISupports*)nativeApp : (nsISupports*)splash); |
---|
1648 | |
---|
1649 | /* if main1() didn't succeed, then don't bother trying to shut down clipboard, etc */ |
---|
1650 | if (NS_SUCCEEDED(mainResult)) { |
---|
1651 | rv = DoOnShutdown(); |
---|
1652 | NS_ASSERTION(NS_SUCCEEDED(rv), "DoOnShutdown failed"); |
---|
1653 | } |
---|
1654 | #ifdef XPCOM_GLUE |
---|
1655 | rv = GRE_Shutdown(); |
---|
1656 | NS_ASSERTION(NS_SUCCEEDED(rv), "GRE_Shutdown failed"); |
---|
1657 | #else |
---|
1658 | rv = NS_ShutdownXPCOM(nsnull); |
---|
1659 | NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); |
---|
1660 | #endif |
---|
1661 | |
---|
1662 | return TranslateReturnValue(mainResult); |
---|
1663 | } |
---|
1664 | |
---|
1665 | #if defined( XP_WIN ) && defined( WIN32 ) |
---|
1666 | // We need WinMain in order to not be a console app. This function is |
---|
1667 | // unused if we are a console application. |
---|
1668 | int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR args, int) |
---|
1669 | { |
---|
1670 | // Do the real work. |
---|
1671 | return main(__argc, __argv); |
---|
1672 | } |
---|
1673 | #endif // XP_WIN && WIN32 |
---|