Back to index

lightning-sunbird  0.9+nobinonly
nsEmbedFunctions.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla libXUL embedding.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Benjamin Smedberg <benjamin@smedbergs.us>
00018  *
00019  * Portions created by the Initial Developer are Copyright (C) 2005
00020  * the Mozilla Foundation. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsXULAppAPI.h"
00039 
00040 #include <stdlib.h>
00041 
00042 #include "nsIAppStartupNotifier.h"
00043 #include "nsIDirectoryService.h"
00044 #include "nsIEventQueueService.h"
00045 #include "nsILocalFile.h"
00046 #include "nsIToolkitChromeRegistry.h"
00047 
00048 #include "nsAppDirectoryServiceDefs.h"
00049 #include "nsArrayEnumerator.h"
00050 #include "nsCOMArray.h"
00051 #include "nsDirectoryServiceDefs.h"
00052 #include "nsEnumeratorUtils.h"
00053 #include "nsStaticComponents.h"
00054 #include "nsString.h"
00055 
00056 class nsEmbeddingDirProvider : public nsIDirectoryServiceProvider2
00057 {
00058 public:
00059   NS_DECL_ISUPPORTS
00060   NS_DECL_NSIDIRECTORYSERVICEPROVIDER
00061   NS_DECL_NSIDIRECTORYSERVICEPROVIDER2
00062 
00063   nsEmbeddingDirProvider(nsILocalFile* aGREDir,
00064                          nsILocalFile* aAppDir,
00065                          nsIDirectoryServiceProvider* aAppProvider) :
00066     mGREDir(aGREDir),
00067     mAppDir(aAppDir),
00068     mAppProvider(aAppProvider) { }
00069 
00070 private:
00071   nsCOMPtr<nsILocalFile> mGREDir;
00072   nsCOMPtr<nsILocalFile> mAppDir;
00073   nsCOMPtr<nsIDirectoryServiceProvider> mAppProvider;
00074 };
00075 
00076 NS_IMPL_ISUPPORTS2(nsEmbeddingDirProvider,
00077                    nsIDirectoryServiceProvider,
00078                    nsIDirectoryServiceProvider2)
00079 
00080 NS_IMETHODIMP
00081 nsEmbeddingDirProvider::GetFile(const char *aProperty, PRBool *aPersistent,
00082                                 nsIFile* *aFile)
00083 {
00084   nsresult rv;
00085 
00086   if (mAppProvider) {
00087     rv = mAppProvider->GetFile(aProperty, aPersistent, aFile);
00088     if (NS_SUCCEEDED(rv) && *aFile)
00089       return rv;
00090   }
00091 
00092   if (!strcmp(aProperty, NS_OS_CURRENT_PROCESS_DIR) ||
00093       !strcmp(aProperty, NS_APP_INSTALL_CLEANUP_DIR)) {
00094     // NOTE: this is *different* than NS_XPCOM_CURRENT_PROCESS_DIR. This points
00095     // to the application dir. NS_XPCOM_CURRENT_PROCESS_DIR points to the toolkit.
00096     return mAppDir->Clone(aFile);
00097   }
00098 
00099   if (!strcmp(aProperty, NS_GRE_DIR)) {
00100     return mGREDir->Clone(aFile);
00101   }
00102 
00103   if (!strcmp(aProperty, NS_APP_PREF_DEFAULTS_50_DIR))
00104   {
00105     nsCOMPtr<nsIFile> file;
00106     rv = mAppDir->Clone(getter_AddRefs(file));
00107     NS_ENSURE_SUCCESS(rv, rv);
00108 
00109     rv = file->AppendNative(NS_LITERAL_CSTRING("defaults"));
00110     NS_ENSURE_SUCCESS(rv, rv);
00111 
00112     rv = file->AppendNative(NS_LITERAL_CSTRING("pref"));
00113     NS_ENSURE_SUCCESS(rv, rv);
00114 
00115     NS_ADDREF(*aFile = file);
00116     return NS_OK;
00117   }
00118 
00119   return NS_ERROR_FAILURE;
00120 }
00121 
00122 NS_IMETHODIMP
00123 nsEmbeddingDirProvider::GetFiles(const char* aProperty,
00124                                  nsISimpleEnumerator** aResult)
00125 {
00126   nsresult rv;
00127 
00128   nsCOMPtr<nsISimpleEnumerator> appEnum;
00129   nsCOMPtr<nsIDirectoryServiceProvider2> appP2
00130     (do_QueryInterface(mAppProvider));
00131   if (appP2) {
00132     rv = appP2->GetFiles(aProperty, getter_AddRefs(appEnum));
00133     if (NS_SUCCEEDED(rv) && rv != NS_SUCCESS_AGGREGATE_RESULT) {
00134       NS_ADDREF(*aResult = appEnum);
00135       return NS_OK;
00136     }
00137   }
00138 
00139   nsCOMArray<nsIFile> dirs;
00140 
00141   if (!strcmp(aProperty, NS_CHROME_MANIFESTS_FILE_LIST) ||
00142       !strcmp(aProperty, NS_APP_CHROME_DIR_LIST)) {
00143     nsCOMPtr<nsIFile> manifest;
00144     mGREDir->Clone(getter_AddRefs(manifest));
00145     manifest->AppendNative(NS_LITERAL_CSTRING("chrome"));
00146     dirs.AppendObject(manifest);
00147 
00148     mAppDir->Clone(getter_AddRefs(manifest));
00149     manifest->AppendNative(NS_LITERAL_CSTRING("chrome"));
00150     dirs.AppendObject(manifest);
00151   }
00152 
00153   if (dirs.Count()) {
00154     nsCOMPtr<nsISimpleEnumerator> thisEnum;
00155     rv = NS_NewArrayEnumerator(getter_AddRefs(thisEnum), dirs);
00156     NS_ENSURE_SUCCESS(rv, rv);
00157 
00158     if (appEnum) {
00159       return NS_NewUnionEnumerator(aResult, appEnum, thisEnum);
00160     }
00161 
00162     NS_ADDREF(*aResult = thisEnum);
00163     return NS_OK;
00164   }
00165 
00166   if (appEnum) {
00167     NS_ADDREF(*aResult = appEnum);
00168     return NS_OK;
00169   }
00170 
00171   return NS_ERROR_FAILURE;
00172 }
00173 
00174 void
00175 XRE_GetStaticComponents(nsStaticModuleInfo const **aStaticComponents,
00176                         PRUint32 *aComponentCount)
00177 {
00178   *aStaticComponents = kPStaticModules;
00179   *aComponentCount = kStaticModuleCount;
00180 }
00181 
00182 static nsStaticModuleInfo *sCombined;
00183 static PRInt32 sInitCounter;
00184 
00185 nsresult
00186 XRE_InitEmbedding(nsILocalFile *aLibXULDirectory,
00187                   nsILocalFile *aAppDirectory,
00188                   nsIDirectoryServiceProvider *aAppDirProvider,
00189                   nsStaticModuleInfo const *aStaticComponents,
00190                   PRUint32 aStaticComponentCount)
00191 {
00192   if (++sInitCounter > 1)
00193     return NS_OK;
00194 
00195   NS_ENSURE_ARG(aLibXULDirectory);
00196   NS_ENSURE_ARG(aAppDirectory);
00197 
00198   nsresult rv;
00199 
00200   nsCOMPtr<nsIDirectoryServiceProvider> dirSvc
00201     (new nsEmbeddingDirProvider(aLibXULDirectory,
00202                                 aAppDirectory,
00203                                 aAppDirProvider));
00204   if (!dirSvc)
00205     return NS_ERROR_OUT_OF_MEMORY;
00206 
00207   // Combine the toolkit static components and the app components.
00208   PRUint32 combinedCount = kStaticModuleCount + aStaticComponentCount;
00209 
00210   sCombined = new nsStaticModuleInfo[combinedCount];
00211   if (!sCombined)
00212     return NS_ERROR_OUT_OF_MEMORY;
00213 
00214   memcpy(sCombined, kPStaticModules,
00215          sizeof(nsStaticModuleInfo) * kStaticModuleCount);
00216   memcpy(sCombined + kStaticModuleCount, aStaticComponents,
00217          sizeof(nsStaticModuleInfo) * aStaticComponentCount);
00218 
00219   rv = NS_InitXPCOM3(nsnull, aAppDirectory, dirSvc,
00220                      sCombined, combinedCount);
00221   if (NS_FAILED(rv))
00222     return rv;
00223 
00224   // We do not need to autoregister components here. The CheckUpdateFile()
00225   // bits in NS_InitXPCOM3 check for an .autoreg file. If the app wants
00226   // to autoregister every time (for instance, if it's debug), it can do
00227   // so after we return from this function.
00228 
00229   nsCOMPtr<nsIEventQueueService> eventQService
00230     (do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv));
00231   if (NS_FAILED(rv))
00232     return rv;
00233 
00234   rv = eventQService->CreateThreadEventQueue();
00235   if (NS_FAILED(rv))
00236     return rv;
00237 
00238   nsCOMPtr<nsIObserver> startupNotifier
00239     (do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID));
00240   if (!startupNotifier)
00241     return NS_ERROR_FAILURE;
00242 
00243   startupNotifier->Observe(nsnull, APPSTARTUP_TOPIC, nsnull);
00244 
00245   return NS_OK;
00246 }
00247 
00248 void
00249 XRE_TermEmbedding()
00250 {
00251   if (--sInitCounter != 0)
00252     return;
00253 
00254   NS_ShutdownXPCOM(nsnull);
00255   delete [] sCombined;
00256 }