Update ooo320-m1
[ooovba.git] / connectivity / source / drivers / mozab / bootstrap / MNSInit.cxx
blobf929108dd134a39f3e9bd075a521d7c3c5e49b58
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MNSInit.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include <MNSInclude.hxx>
35 #include "mozilla_nsinit.h"
37 #include <MNSInit.hxx>
39 #include <sal/types.h>
40 #include <osl/diagnose.h>
41 #include <osl/conditn.hxx>
42 #include <osl/file.hxx>
43 #include <rtl/bootstrap.hxx>
45 #ifndef CONNECTIVITY_MOZAB_MCONFIGACCESS_HXX
46 #include "MConfigAccess.hxx"
47 #endif
48 #include "MNSDeclares.hxx"
49 #include <osl/thread.hxx>
50 #include <MNSTerminateListener.hxx>
52 static nsIServiceManager* sServiceManager = nsnull;
53 static sal_Int32 sInitCounter = 0;
54 static sal_Bool s_bProfilePresentAfterInitialized = sal_False;
56 static NS_DEFINE_CID(kProfileCID, NS_PROFILE_CID);
57 static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
59 static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
60 static oslThread m_Mozilla_UI_Thread;
61 static PRBool aLive=1;
62 static ::osl::Condition m_aUI_Thread_Condition;
64 #define HACK_AROUND_THREADING_ISSUES
65 #define HACK_AROUND_NONREENTRANT_INITXPCOM
67 #ifdef HACK_AROUND_NONREENTRANT_INITXPCOM
68 // XXX hack class to clean up XPCOM when this module is unloaded
69 static PRBool sXPCOMInitializedFlag = PR_FALSE;
70 #endif
73 extern "C" void NS_SetupRegistry();
75 const PRUnichar* determineProfile( PRUnichar const* const* _pValidProfiles, const PRUint32 _nValidProfiles )
77 // the fallback for the to-be-used user profile: the first profile
78 const PRUnichar* pUsedProfile = *_pValidProfiles;
80 // have a look what the configuration suggests as preferred profile
81 // PRUnichar != sal_Unicode in mingw
82 const PRUnichar* pPreferredProfile = reinterpret_cast_mingw_only< const PRUnichar* >( getUserProfile( ) );
83 if ( pPreferredProfile && *pPreferredProfile )
85 PRUnichar const* const* pLoop = _pValidProfiles;
86 PRUnichar const* const* pLoopEnd = pLoop + _nValidProfiles;
87 for ( ; pLoop != pLoopEnd; ++pLoop )
89 // compare the current and the preferred profile
90 // (by looping through the characters)
91 const PRUnichar* pCurrent = *pLoop;
92 const PRUnichar* pPref = pPreferredProfile;
93 while ( *pCurrent && ( *pCurrent == *pPref ) ) // testing one of them against 0 is enough because of the second clause
95 ++pCurrent;
96 ++pPref;
98 if ( *pCurrent == *pPref )
99 // the are equal
100 break;
103 if ( pLoop != pLoopEnd )
104 pUsedProfile = *pLoop;
105 return pUsedProfile;
107 else
108 return NULL;
112 sal_Bool MNS_InitXPCOM(sal_Bool* aProfileExists)
114 nsresult rv;
115 OSL_TRACE( "IN : MNS_InitXPCOM() \n" );
116 // Reentrant calls to this method do nothing except increment a counter
118 #ifdef HACK_AROUND_NONREENTRANT_INITXPCOM
119 // The first time, add another increment so that it'll be left until exit
120 // for the final cleanup to happen
121 sInitCounter++;
122 #endif // HACK_AROUND_NONREENTRANT_INITXPCOM
124 // Initialise XPCOM
125 #ifdef HACK_AROUND_NONREENTRANT_INITXPCOM
126 // Can't call NS_InitXPCom more than once or things go boom!
127 if (!sXPCOMInitializedFlag)
128 #endif
130 nsCOMPtr<nsILocalFile> binDir;
131 // Note: if path3 construction fails, mozilla will default to using MOZILLA_FIVE_HOME in the NS_InitXPCOM2()
132 rtl::OUString path1(
133 #if defined WNT
134 RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program")
135 #else
136 RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program")
137 #endif
139 rtl::Bootstrap::expandMacros(path1);
140 rtl::OString path2;
141 if ((osl::FileBase::getSystemPathFromFileURL(path1, path1) ==
142 osl::FileBase::E_None) &&
143 path1.convertToString(
144 &path2, osl_getThreadTextEncoding(),
145 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
146 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
148 nsDependentCString sPath(path2.getStr());
149 rv = NS_NewNativeLocalFile(sPath, PR_TRUE, getter_AddRefs(binDir));
150 if (NS_FAILED(rv))
151 return sal_False;
156 // Initialise XPCOM
157 NS_InitXPCOM2(&sServiceManager, binDir, NULL);
159 // if (!sServiceManager)
160 // return sal_False;
162 #ifdef HACK_AROUND_NONREENTRANT_INITXPCOM
163 sXPCOMInitializedFlag = PR_TRUE;
164 #endif
168 // Create the Event Queue for the UI thread...
170 // If an event queue already exists for the thread, then
171 // CreateThreadEventQueue(...) will fail...
172 // CreateThread0ueue(...) will fail...
173 nsCOMPtr<nsIEventQueueService> eventQService(
174 do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv));
175 if (NS_FAILED(rv))
176 return NS_SUCCEEDED( rv ) ? sal_True : sal_False;
178 eventQService->CreateThreadEventQueue();
180 // nsCOMPtr<nsIObserver> mStartupNotifier = do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID, &rv);
181 // if(NS_FAILED(rv))
182 // return rv;
183 // mStartupNotifier->Observe(nsnull, APPSTARTUP_TOPIC, nsnull);
185 #ifdef HACK_AROUND_THREADING_ISSUES
186 // XXX force certain objects to be created on the main thread
187 nsCOMPtr<nsIStringBundleService> sBundleService;
188 sBundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
189 if (NS_SUCCEEDED(rv))
191 nsCOMPtr<nsIStringBundle> stringBundle;
192 const char* propertyURL = "chrome://necko/locale/necko.properties";
193 rv = sBundleService->CreateBundle(propertyURL,
194 getter_AddRefs(stringBundle));
196 #endif
198 // Need to create a Pref Service
199 nsCOMPtr< nsIPref > thePref = do_GetService( kPrefCID, &rv );
200 if (NS_SUCCEEDED(rv) )
202 OSL_TRACE("Created an nsIPref i/f\n");
203 thePref->ReadUserPrefs( nsnull );
204 *aProfileExists = sal_True ;
205 s_bProfilePresentAfterInitialized = sal_True;
207 OSL_TRACE( "OUT : MNS_InitXPCOM() - XPCOM Init\n" );
209 return sal_True;
212 void MNS_XPCOM_EventLoop()
214 OSL_TRACE( "IN : MNS_XPCOM_EventLoop() \n" );
215 nsresult rv;
216 nsCOMPtr<nsIEventQueue> eventQ;
217 nsCOMPtr<nsIEventQueueService> eventQService;
218 rv=nsServiceManager::GetService(kEventQueueServiceCID,
219 NS_GET_IID(nsIEventQueueService),
220 getter_AddRefs(eventQService));
222 if (NS_SUCCEEDED(rv))
224 rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD , getter_AddRefs(eventQ));
225 if (NS_FAILED(rv))
227 rv = eventQService->CreateThreadEventQueue();
228 if (NS_FAILED(rv))
229 return ;
230 else
231 rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQ));
235 if (NS_FAILED(rv)) return ;
237 PLEvent* event = nsnull;
238 m_aUI_Thread_Condition.set(); //we are ready to recive event
241 rv = eventQ->GetEvent(&event);
242 if (NS_FAILED(rv))
243 return ;
244 if (event)
245 eventQ->HandleEvent(event);
246 }while ( PR_SUCCESS == PR_Sleep( PR_MillisecondsToInterval(1)) && aLive );
248 eventQ->ProcessPendingEvents();
249 OSL_TRACE( "OUT : MNS_XPCOM_EventLoop() \n" );
252 extern "C" void MNS_Mozilla_UI_Thread( void *arg )
254 aLive=1;
255 OSL_TRACE( "IN : MNS_Mozilla_UI_Thread() \n" );
256 UI_Thread_ARGS * args = (UI_Thread_ARGS*) arg;
257 sal_Bool* aProfileExists=args->bProfileExists;
258 delete args;
259 args=NULL;
261 //Init xpcom
262 if (!MNS_InitXPCOM(aProfileExists))
264 m_aUI_Thread_Condition.set(); // error happened
265 return;
268 //do the mozilla event loop
269 MNS_XPCOM_EventLoop();
270 //we are interupted
272 if (sServiceManager)
274 NS_RELEASE(sServiceManager);
276 // Terminate XPCOM & cleanup
277 #ifndef HACK_AROUND_NONREENTRANT_INITXPCOM
278 NS_ShutdownXPCOM(sServiceManager);
279 #endif
282 m_aUI_Thread_Condition.set(); //release all blocks
284 OSL_TRACE( "OUT : MNS_Mozilla_UI_Thread() \n" );
289 sal_Bool MNS_Init(sal_Bool& aProfileExists)
291 aProfileExists = sal_False ;
293 OSL_TRACE( "IN : MNS_Init() \n" );
294 // Reentrant calls to this method do nothing except increment a counter
295 sInitCounter++;
296 if (sInitCounter > 1) {
297 OSL_TRACE( "IN : MNS_Init() wait for xpcom to be initted \n" );
298 //wait for xpcom to be initted
299 m_aUI_Thread_Condition.wait();
301 OSL_TRACE( "OUT : MNS_Init() : counter = %d\n", sInitCounter );
302 aProfileExists = s_bProfilePresentAfterInitialized;
303 return sal_True;
306 UI_Thread_ARGS * args = new UI_Thread_ARGS;
307 args->bProfileExists = &aProfileExists;
309 m_aUI_Thread_Condition.reset();
310 m_Mozilla_UI_Thread=osl_createThread(MNS_Mozilla_UI_Thread,
311 (void*)args);
312 if (!m_Mozilla_UI_Thread)
314 return sal_False;
317 //wait for xpcom to be initted
318 m_aUI_Thread_Condition.wait();
320 //Add Terminate Listener to XDesktop to get application exit event
321 MNSTerminateListener::addTerminateListener();
323 OSL_TRACE( "OUT : MNS_Init() - First Init\n" );
325 return sal_True;
328 sal_Bool MNS_Term(sal_Bool aForce)
330 // Reentrant calls to this method do nothing except decrement a counter
331 OSL_TRACE( "IN : MNS_Term() \n" );
332 if (!aForce && sInitCounter > 1)
334 --sInitCounter;
335 OSL_TRACE( "OUT : MNS_Term() : counter = %d\n", sInitCounter );
336 return sal_True;
338 sInitCounter = 0;
340 aLive=0;
342 //wait for xpcom to be finished
343 TimeValue timeValue = { 1, 0 };
344 m_aUI_Thread_Condition.wait(&timeValue);
347 OSL_TRACE( "OUT : MNS_Term() - Final Term\n" );
348 return sal_True;