diff options
author | Vladimir Glazounov <vg@openoffice.org> | 2005-02-21 11:26:42 +0000 |
---|---|---|
committer | Vladimir Glazounov <vg@openoffice.org> | 2005-02-21 11:26:42 +0000 |
commit | 36af8356f8c8f1d3ed382ecba10f0435e5a5e6f8 (patch) | |
tree | 8daf76070002e9d1346aa7710e2d39f8b6c5e7c8 /connectivity | |
parent | 5e1c5ca90d39e6c4e38ac9161808e4bb0a90e308 (diff) |
INTEGRATION: CWS mozab05 (1.1.2); FILE ADDED
2005/01/27 11:30:10 windly 1.1.2.4: #i41444# mozab crash on solaris sparc
2005/01/25 09:24:27 windly 1.1.2.3: #i20088# now work on linux/solaris too
2005/01/24 07:49:04 windly 1.1.2.2: #i20088# add thunderbird support
2005/01/17 05:30:47 windly 1.1.2.1: #i20088# Detect Mozilla Thunderbird Address Book: patchs for connectivity
Diffstat (limited to 'connectivity')
-rw-r--r-- | connectivity/source/drivers/mozab/bootstrap/MNSInit.cxx | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/connectivity/source/drivers/mozab/bootstrap/MNSInit.cxx b/connectivity/source/drivers/mozab/bootstrap/MNSInit.cxx new file mode 100644 index 000000000000..0d075fca2180 --- /dev/null +++ b/connectivity/source/drivers/mozab/bootstrap/MNSInit.cxx @@ -0,0 +1,394 @@ +/************************************************************************* + * + * $RCSfile: MNSInit.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: vg $ $Date: 2005-02-21 12:26:42 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): Darren Kenny + * + * + ************************************************************************/ + +#ifndef _CONNECTIVITY_MAB_NS_INCLUDE_HXX_ +#include <MNSInclude.hxx> +#endif +#include "nsIServiceManager.h" +#include "nsIEventQueueService.h" +#include "nsIChromeRegistry.h" + +#include "nsIStringBundle.h" + +#include "nsIDirectoryService.h" +#include "nsIProfile.h" +#include "nsIProfileInternal.h" +#include "nsIPref.h" +#include "nsXPIDLString.h" + +#include "nsString.h" +#include "nsEmbedAPI.h" +#include <sal/types.h> +#include <osl/diagnose.h> +#ifndef _OSL_CONDITN_HXX_ +#include <osl/conditn.hxx> +#endif + +#ifndef _CONNECTIVITY_MAB_NS_INIT_HXX_ +#include <MNSInit.hxx> +#endif + +#ifndef CONNECTIVITY_MOZAB_MCONFIGACCESS_HXX +#include "MConfigAccess.hxx" +#endif + +#ifndef _CONNECTIVITY_MAB_NS_DECLARES_HXX_ +#include "MNSDeclares.hxx" +#endif + +#ifndef _THREAD_HXX_ +#include <osl/thread.hxx> +#endif + +#ifndef _MNSTERMINATELISTENER_HXX +#include <MNSTerminateListener.hxx> +#endif + +#include "nsDirectoryService.h" + +static nsIServiceManager* sServiceManager = nsnull; +static sal_Int32 sInitCounter = 0; +static sal_Bool s_bProfilePresentAfterInitialized = sal_False; + +static NS_DEFINE_CID(kProfileCID, NS_PROFILE_CID); +static NS_DEFINE_CID(kPrefCID, NS_PREF_CID); + +static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); +static oslThread m_Mozilla_UI_Thread; +static PRBool aLive=1; +static ::osl::Condition m_aUI_Thread_Condition; + +#define HACK_AROUND_THREADING_ISSUES +#define HACK_AROUND_NONREENTRANT_INITXPCOM + +#ifdef HACK_AROUND_NONREENTRANT_INITXPCOM +// XXX hack class to clean up XPCOM when this module is unloaded +static PRBool sXPCOMInitializedFlag = PR_FALSE; +#endif + + +extern "C" void NS_SetupRegistry(); + + const PRUnichar* determineProfile( PRUnichar const* const* _pValidProfiles, const PRUint32 _nValidProfiles ) +{ + // the fallback for the to-be-used user profile: the first profile + const PRUnichar* pUsedProfile = *_pValidProfiles; + + // have a look what the configuration suggests as preferred profile + const PRUnichar* pPreferredProfile = static_cast< const PRUnichar* >( getUserProfile( ) ); + if ( pPreferredProfile && *pPreferredProfile ) + { + PRUnichar const* const* pLoop = _pValidProfiles; + PRUnichar const* const* pLoopEnd = pLoop + _nValidProfiles; + for ( ; pLoop != pLoopEnd; ++pLoop ) + { + // compare the current and the preferred profile + // (by looping through the characters) + const PRUnichar* pCurrent = *pLoop; + const PRUnichar* pPref = pPreferredProfile; + while ( *pCurrent && ( *pCurrent == *pPref ) ) // testing one of them against 0 is enough because of the second clause + { + ++pCurrent; + ++pPref; + } + if ( *pCurrent == *pPref ) + // the are equal + break; + } + + if ( pLoop != pLoopEnd ) + pUsedProfile = *pLoop; + return pUsedProfile; + } + else + return NULL; +} + + +sal_Bool MNS_InitXPCOM(sal_Bool* aProfileExists,sal_Int32 nProduct) +{ + nsresult rv; + OSL_TRACE( "IN : MNS_InitXPCOM() \n" ); + // Reentrant calls to this method do nothing except increment a counter + +#ifdef HACK_AROUND_NONREENTRANT_INITXPCOM + // The first time, add another increment so that it'll be left until exit + // for the final cleanup to happen + sInitCounter++; +#endif // HACK_AROUND_NONREENTRANT_INITXPCOM + + // Initialise XPCOM +#ifdef HACK_AROUND_NONREENTRANT_INITXPCOM + // Can't call NS_InitXPCom more than once or things go boom! + if (!sXPCOMInitializedFlag) +#endif + { + nsCOMPtr<nsILocalFile> binDir; + // Note: if getenv() returns NULL, mozilla will default to using MOZILLA_FIVE_HOME in the NS_InitXPCOM2() + // The NS_NewNativeLocalFile() will accept NULL as its first parameter. + char * env = getenv("OPENOFFICE_MOZILLA_FIVE_HOME"); + if (env) + { + nsDependentCString sPath(env); + rv = NS_NewNativeLocalFile(sPath, PR_TRUE, getter_AddRefs(binDir)); + if (NS_FAILED(rv)) + return sal_False; + } + + + + // Initialise XPCOM + NS_InitXPCOM2(&sServiceManager, binDir, NULL); + +// if (!sServiceManager) +// return sal_False; + +#ifdef HACK_AROUND_NONREENTRANT_INITXPCOM + sXPCOMInitializedFlag = PR_TRUE; +#endif + } + + + // Create the Event Queue for the UI thread... + // + // If an event queue already exists for the thread, then + // CreateThreadEventQueue(...) will fail... + // CreateThread0ueue(...) will fail... + nsCOMPtr<nsIEventQueueService> eventQService( + do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) + return rv; + + eventQService->CreateThreadEventQueue(); + +// nsCOMPtr<nsIObserver> mStartupNotifier = do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID, &rv); +// if(NS_FAILED(rv)) +// return rv; +// mStartupNotifier->Observe(nsnull, APPSTARTUP_TOPIC, nsnull); + +#ifdef HACK_AROUND_THREADING_ISSUES + // XXX force certain objects to be created on the main thread + nsCOMPtr<nsIStringBundleService> sBundleService; + sBundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) + { + nsCOMPtr<nsIStringBundle> stringBundle; + char* propertyURL = "chrome://necko/locale/necko.properties"; + rv = sBundleService->CreateBundle(propertyURL, + getter_AddRefs(stringBundle)); + } +#endif + + // Need to create a Pref Service + nsCOMPtr< nsIPref > thePref = do_GetService( kPrefCID, &rv ); + if (NS_SUCCEEDED(rv) ) + { + OSL_TRACE("Created an nsIPref i/f\n"); + thePref->ReadUserPrefs( nsnull ); + *aProfileExists = sal_True ; + s_bProfilePresentAfterInitialized = sal_True; + } + OSL_TRACE( "OUT : MNS_InitXPCOM() - XPCOM Init\n" ); + + return sal_True; +} + +void MNS_XPCOM_EventLoop() +{ + OSL_TRACE( "IN : MNS_XPCOM_EventLoop() \n" ); + nsresult rv; + nsCOMPtr<nsIEventQueue> eventQ; + nsCOMPtr<nsIEventQueueService> eventQService; + rv=nsServiceManager::GetService(kEventQueueServiceCID, + NS_GET_IID(nsIEventQueueService), + getter_AddRefs(eventQService)); + + if (NS_SUCCEEDED(rv)) + { + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD , getter_AddRefs(eventQ)); + if (NS_FAILED(rv)) + { + rv = eventQService->CreateThreadEventQueue(); + if (NS_FAILED(rv)) + return ; + else + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQ)); + } + } + + if (NS_FAILED(rv)) return ; + + PLEvent* event = nsnull; + m_aUI_Thread_Condition.set(); //we are ready to recive event + do + { + rv = eventQ->GetEvent(&event); + if (NS_FAILED(rv)) + return ; + if (event) + eventQ->HandleEvent(event); + }while ( PR_SUCCESS == PR_Sleep( PR_MillisecondsToInterval(1)) && aLive ); + + eventQ->ProcessPendingEvents(); + OSL_TRACE( "OUT : MNS_XPCOM_EventLoop() \n" ); +} + +static void MNS_Mozilla_UI_Thread( void *arg ) +{ + aLive=1; + OSL_TRACE( "IN : MNS_Mozilla_UI_Thread() \n" ); + UI_Thread_ARGS * args = (UI_Thread_ARGS*) arg; + sal_Bool* aProfileExists=args->bProfileExists; + sal_Int32 nProduct = args->nProduct; + delete args; + args=NULL; + + //Init xpcom + if (!MNS_InitXPCOM(aProfileExists,nProduct)) + { + m_aUI_Thread_Condition.set(); // error happened + return; + } + + //do the mozilla event loop + MNS_XPCOM_EventLoop(); + //we are interupted + + if (sServiceManager) + { + NS_RELEASE(sServiceManager); + + // Terminate XPCOM & cleanup +#ifndef HACK_AROUND_NONREENTRANT_INITXPCOM + NS_ShutdownXPCOM(sServiceManager); +#endif + } + + m_aUI_Thread_Condition.set(); //release all blocks + + OSL_TRACE( "OUT : MNS_Mozilla_UI_Thread() \n" ); + +} + + +sal_Bool MNS_Init(sal_Bool& aProfileExists,sal_Int32 nProduct) +{ + aProfileExists = sal_False ; + + OSL_TRACE( "IN : MNS_Init() \n" ); + // Reentrant calls to this method do nothing except increment a counter + sInitCounter++; + if (sInitCounter > 1) { + OSL_TRACE( "IN : MNS_Init() wait for xpcom to be initted \n" ); + //wait for xpcom to be initted + m_aUI_Thread_Condition.wait(); + + OSL_TRACE( "OUT : MNS_Init() : counter = %d\n", sInitCounter ); + aProfileExists = s_bProfilePresentAfterInitialized; + return sal_True; + } + + UI_Thread_ARGS * args = new UI_Thread_ARGS; + args->bProfileExists = &aProfileExists; + args->nProduct = nProduct; + + m_aUI_Thread_Condition.reset(); + m_Mozilla_UI_Thread=osl_createThread(MNS_Mozilla_UI_Thread, + (void*)args); + if (!m_Mozilla_UI_Thread) + { + return sal_False; + } + + //wait for xpcom to be initted + m_aUI_Thread_Condition.wait(); + + //Add Terminate Listener to XDesktop to get application exit event + MNSTerminateListener::addTerminateListener(); + + OSL_TRACE( "OUT : MNS_Init() - First Init\n" ); + + return sal_True; +} + +sal_Bool MNS_Term(sal_Bool aForce) +{ + // Reentrant calls to this method do nothing except decrement a counter + OSL_TRACE( "IN : MNS_Term() \n" ); + if (!aForce && sInitCounter > 1) + { + --sInitCounter; + OSL_TRACE( "OUT : MNS_Term() : counter = %d\n", sInitCounter ); + return sal_True; + } + sInitCounter = 0; + + aLive=0; + + //wait for xpcom to be finished + TimeValue timeValue = { 1, 0 }; + m_aUI_Thread_Condition.wait(&timeValue); + + + OSL_TRACE( "OUT : MNS_Term() - Final Term\n" ); + return sal_True; +} + |