Update ooo320-m1
[ooovba.git] / vcl / source / app / svmain.cxx
blob84c584b26f8e328d76388d09b242cd532400687f
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: svmain.cxx,v $
10 * $Revision: 1.73.92.1 $
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_vcl.hxx"
34 #ifdef WNT
35 #include <tools/prewin.h>
36 #include <process.h> // for _beginthreadex
37 #include <ole2.h> // for _beginthreadex
38 #include <tools/postwin.h>
39 #endif
41 // [ed 5/14/02 Add in explicit check for quartz graphics. OS X will define
42 // unx for both quartz and X11 graphics, but we include svunx.h only if we're
43 // building X11 graphics layers.
45 #if defined UNX && ! defined QUARTZ
46 #include "svunx.h"
47 #endif
49 #include "svsys.h"
50 #include "vcl/salinst.hxx"
51 #include "vcl/salwtype.hxx"
52 #include "vos/signal.hxx"
53 #include "tools/tools.h"
54 #include "tools/debug.hxx"
55 #include "tools/unqid.hxx"
56 #include "vcl/svdata.hxx"
57 #include "vcl/dbggui.hxx"
58 #include "vcl/svapp.hxx"
59 #include "vcl/wrkwin.hxx"
60 #include "vcl/cvtgrf.hxx"
61 #include "vcl/image.hxx"
62 #include "tools/resmgr.hxx"
63 #include "vcl/accmgr.hxx"
64 #include "vcl/idlemgr.hxx"
65 #include "vcl/outdev.h"
66 #include "vcl/outfont.hxx"
67 #include "vcl/print.h"
68 #include "vcl/settings.hxx"
69 #include "vcl/unowrap.hxx"
70 #include "vcl/salsys.hxx"
71 #include "vcl/saltimer.hxx"
72 #include "vcl/salimestatus.hxx"
73 #include "vcl/impimagetree.hxx"
74 #include "vcl/xconnection.hxx"
76 #include "vos/process.hxx"
77 #include "osl/file.hxx"
78 #include "comphelper/processfactory.hxx"
79 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
80 #include "com/sun/star/lang/XComponent.hpp"
81 #include "rtl/logfile.hxx"
83 #include "vcl/fontcfg.hxx"
84 #include "vcl/configsettings.hxx"
85 #include "vcl/lazydelete.hxx"
87 #include "cppuhelper/implbase1.hxx"
88 #include "uno/current_context.hxx"
90 #if OSL_DEBUG_LEVEL > 0
91 #include <typeinfo>
92 #include "rtl/strbuf.hxx"
93 #endif
95 using namespace ::rtl;
96 using namespace ::com::sun::star::uno;
97 using namespace ::com::sun::star::lang;
101 // =======================================================================
103 class ImplVCLExceptionHandler : public ::vos::OSignalHandler
105 public:
106 virtual ::vos::OSignalHandler::TSignalAction SAL_CALL signal( ::vos::OSignalHandler::TSignalInfo* pInfo );
109 // -----------------------------------------------------------------------
111 ::vos::OSignalHandler::TSignalAction SAL_CALL ImplVCLExceptionHandler::signal( ::vos::OSignalHandler::TSignalInfo* pInfo )
113 static BOOL bIn = FALSE;
115 // Wenn wir nocheinmal abstuerzen, verabschieden wir uns gleich
116 if ( !bIn )
118 USHORT nVCLException = 0;
120 // UAE
121 if ( (pInfo->Signal == osl_Signal_AccessViolation) ||
122 (pInfo->Signal == osl_Signal_IntegerDivideByZero) ||
123 (pInfo->Signal == osl_Signal_FloatDivideByZero) ||
124 (pInfo->Signal == osl_Signal_DebugBreak) )
125 nVCLException = EXC_SYSTEM;
127 // RC
128 if ((pInfo->Signal == osl_Signal_User) &&
129 (pInfo->UserSignal == OSL_SIGNAL_USER_RESOURCEFAILURE) )
130 nVCLException = EXC_RSCNOTLOADED;
132 // DISPLAY-Unix
133 if ((pInfo->Signal == osl_Signal_User) &&
134 (pInfo->UserSignal == OSL_SIGNAL_USER_X11SUBSYSTEMERROR) )
135 nVCLException = EXC_DISPLAY;
137 // Remote-Client
138 if ((pInfo->Signal == osl_Signal_User) &&
139 (pInfo->UserSignal == OSL_SIGNAL_USER_RVPCONNECTIONERROR) )
140 nVCLException = EXC_REMOTE;
142 if ( nVCLException )
144 bIn = TRUE;
146 ::vos::OGuard aLock(&Application::GetSolarMutex());
148 // Timer nicht mehr anhalten, da ansonsten die UAE-Box
149 // auch nicht mehr gepaintet wird
150 ImplSVData* pSVData = ImplGetSVData();
151 if ( pSVData->mpApp )
153 USHORT nOldMode = Application::GetSystemWindowMode();
154 Application::SetSystemWindowMode( nOldMode & ~SYSTEMWINDOW_MODE_NOAUTOMODE );
155 pSVData->mpApp->Exception( nVCLException );
156 Application::SetSystemWindowMode( nOldMode );
158 bIn = FALSE;
160 return vos::OSignalHandler::TAction_CallNextHandler;
164 return vos::OSignalHandler::TAction_CallNextHandler;
167 // =======================================================================
168 BOOL ImplSVMain()
170 // The 'real' SVMain()
171 RTL_LOGFILE_CONTEXT( aLog, "vcl (ss112471) ::SVMain" );
173 ImplSVData* pSVData = ImplGetSVData();
175 DBG_ASSERT( pSVData->mpApp, "no instance of class Application" );
177 Reference<XMultiServiceFactory> xMS;
180 BOOL bInit = InitVCL( xMS );
182 if( bInit )
184 // Application-Main rufen
185 pSVData->maAppData.mbInAppMain = TRUE;
186 pSVData->mpApp->Main();
187 pSVData->maAppData.mbInAppMain = FALSE;
190 if( pSVData->mxDisplayConnection.is() )
192 vcl::DisplayConnection* pConnection =
193 dynamic_cast<vcl::DisplayConnection*>(pSVData->mxDisplayConnection.get());
195 if( pConnection )
196 pConnection->dispatchDowningEvent();
197 pSVData->mxDisplayConnection.clear();
200 // This is a hack to work around the problem of the asynchronous nature
201 // of bridging accessibility through Java: on shutdown there might still
202 // be some events in the AWT EventQueue, which need the SolarMutex which
203 // - on the other hand - is destroyed in DeInitVCL(). So empty the queue
204 // here ..
205 Reference< XComponent > xComponent(pSVData->mxAccessBridge, UNO_QUERY);
206 if( xComponent.is() )
208 ULONG nCount = Application::ReleaseSolarMutex();
209 xComponent->dispose();
210 Application::AcquireSolarMutex(nCount);
211 pSVData->mxAccessBridge.clear();
214 DeInitVCL();
215 return bInit;
218 BOOL SVMain()
220 // #i47888# allow for alternative initialization as required for e.g. MacOSX
221 extern BOOL ImplSVMainHook( BOOL* );
223 BOOL bInit;
224 if( ImplSVMainHook( &bInit ) )
225 return bInit;
226 else
227 return ImplSVMain();
229 // This variable is set, when no Application object is instantiated
230 // before SVInit is called
231 static Application * pOwnSvApp = NULL;
232 // Exception handler. pExceptionHandler != NULL => VCL already inited
233 ImplVCLExceptionHandler * pExceptionHandler = NULL;
235 class Application_Impl : public Application
237 public:
238 void Main(){};
241 class DesktopEnvironmentContext: public cppu::WeakImplHelper1< com::sun::star::uno::XCurrentContext >
243 public:
244 DesktopEnvironmentContext( const com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > & ctx)
245 : m_xNextContext( ctx ) {}
247 // XCurrentContext
248 virtual com::sun::star::uno::Any SAL_CALL getValueByName( const rtl::OUString& Name )
249 throw (com::sun::star::uno::RuntimeException);
251 private:
252 com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > m_xNextContext;
255 Any SAL_CALL DesktopEnvironmentContext::getValueByName( const rtl::OUString& Name) throw (RuntimeException)
257 Any retVal;
259 if ( 0 == Name.compareToAscii( "system.desktop-environment" ) )
261 retVal = makeAny( Application::GetDesktopEnvironment() );
263 else if( m_xNextContext.is() )
265 // Call next context in chain if found
266 retVal = m_xNextContext->getValueByName( Name );
268 return retVal;
271 BOOL InitVCL( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & rSMgr )
273 RTL_LOGFILE_CONTEXT( aLog, "vcl (ss112471) ::InitVCL" );
275 if( pExceptionHandler != NULL )
276 return FALSE;
278 if( ! ImplGetSVData() )
279 ImplInitSVData();
281 if( !ImplGetSVData()->mpApp )
283 pOwnSvApp = new Application_Impl();
285 InitSalMain();
287 /*AllSettings aAS;
288 Application::SetSettings( aAS );// ???
290 ImplSVData* pSVData = ImplGetSVData();
292 // SV bei den Tools anmelden
293 InitTools();
295 DBG_ASSERT( !pSVData->maAppData.mxMSF.is(), "VCL service factory already set" );
296 pSVData->maAppData.mxMSF = rSMgr;
298 // Main-Thread-Id merken
299 pSVData->mnMainThreadId = ::vos::OThread::getCurrentIdentifier();
301 vos::OStartupInfo aStartInfo;
302 rtl::OUString aExeFileName;
305 // Sal initialisieren
306 RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ ::CreateSalInstance" );
307 pSVData->mpDefInst = CreateSalInstance();
308 if ( !pSVData->mpDefInst )
309 return FALSE;
310 RTL_LOGFILE_CONTEXT_TRACE( aLog, "} ::CreateSalInstance" );
312 // Desktop Environment context (to be able to get value of "system.desktop-environment" as soon as possible)
313 com::sun::star::uno::setCurrentContext(
314 new DesktopEnvironmentContext( com::sun::star::uno::getCurrentContext() ) );
316 // Initialize application instance (should be done after initialization of VCL SAL part)
317 if( pSVData->mpApp )
318 // call init to initialize application class
319 // soffice/sfx implementation creates the global service manager
320 pSVData->mpApp->Init();
322 // Den AppFileName gleich holen und absolut machen, bevor das
323 // WorkingDirectory sich aendert...
324 aStartInfo.getExecutableFile( aExeFileName );
326 // convert path to native file format
327 rtl::OUString aNativeFileName;
328 osl::FileBase::getSystemPathFromFileURL( aExeFileName, aNativeFileName );
329 pSVData->maAppData.mpAppFileName = new String( aNativeFileName );
331 // Initialize global data
332 pSVData->maGDIData.mpScreenFontList = new ImplDevFontList;
333 pSVData->maGDIData.mpScreenFontCache = new ImplFontCache( FALSE );
334 pSVData->maGDIData.mpGrfConverter = new GraphicConverter;
336 // Exception-Handler setzen
337 pExceptionHandler = new ImplVCLExceptionHandler();
339 // Debug-Daten initialisieren
340 DBGGUI_INIT();
342 return TRUE;
345 void DeInitVCL()
347 ImplSVData* pSVData = ImplGetSVData();
348 pSVData->mbDeInit = TRUE;
350 vcl::DeleteOnDeinitBase::ImplDeleteOnDeInit();
352 // give ime status a chance to destroy its own windows
353 delete pSVData->mpImeStatus;
354 pSVData->mpImeStatus = NULL;
356 #if OSL_DEBUG_LEVEL > 0
357 rtl::OStringBuffer aBuf( 256 );
358 aBuf.append( "DeInitVCL: some top Windows are still alive\n" );
359 long nTopWindowCount = Application::GetTopWindowCount();
360 long nBadTopWindows = nTopWindowCount;
361 for( long i = 0; i < nTopWindowCount; i++ )
363 Window* pWin = Application::GetTopWindow( i );
364 // default window will be destroyed further down
365 // but may still be useful during deinit up to that point
366 if( pWin == pSVData->mpDefaultWin )
367 nBadTopWindows--;
368 else
370 aBuf.append( "text = \"" );
371 aBuf.append( rtl::OUStringToOString( pWin->GetText(), osl_getThreadTextEncoding() ) );
372 aBuf.append( "\" type = \"" );
373 aBuf.append( typeid(*pWin).name() );
374 aBuf.append( "\"\n" );
377 DBG_ASSERT( nBadTopWindows==0, aBuf.getStr() );
378 #endif
380 ImplImageTreeSingletonRef()->shutDown();
382 delete pExceptionHandler;
383 pExceptionHandler = NULL;
385 // Debug Daten zuruecksetzen
386 DBGGUI_DEINIT();
388 // free global data
389 delete pSVData->maGDIData.mpGrfConverter;
391 if( pSVData->mpSettingsConfigItem )
392 delete pSVData->mpSettingsConfigItem, pSVData->mpSettingsConfigItem = NULL;
393 if( pSVData->maGDIData.mpDefaultFontConfiguration )
394 delete pSVData->maGDIData.mpDefaultFontConfiguration, pSVData->maGDIData.mpDefaultFontConfiguration = NULL;
395 if( pSVData->maGDIData.mpFontSubstConfiguration )
396 delete pSVData->maGDIData.mpFontSubstConfiguration, pSVData->maGDIData.mpFontSubstConfiguration = NULL;
398 if ( pSVData->maAppData.mpIdleMgr )
399 delete pSVData->maAppData.mpIdleMgr;
400 Timer::ImplDeInitTimer();
402 if ( pSVData->maWinData.mpMsgBoxImgList )
404 delete pSVData->maWinData.mpMsgBoxImgList;
405 pSVData->maWinData.mpMsgBoxImgList = NULL;
407 if ( pSVData->maWinData.mpMsgBoxHCImgList )
409 delete pSVData->maWinData.mpMsgBoxHCImgList;
410 pSVData->maWinData.mpMsgBoxHCImgList = NULL;
412 if ( pSVData->maCtrlData.mpCheckImgList )
414 delete pSVData->maCtrlData.mpCheckImgList;
415 pSVData->maCtrlData.mpCheckImgList = NULL;
417 if ( pSVData->maCtrlData.mpRadioImgList )
419 delete pSVData->maCtrlData.mpRadioImgList;
420 pSVData->maCtrlData.mpRadioImgList = NULL;
422 if ( pSVData->maCtrlData.mpPinImgList )
424 delete pSVData->maCtrlData.mpPinImgList;
425 pSVData->maCtrlData.mpPinImgList = NULL;
427 if ( pSVData->maCtrlData.mpSplitHPinImgList )
429 delete pSVData->maCtrlData.mpSplitHPinImgList;
430 pSVData->maCtrlData.mpSplitHPinImgList = NULL;
432 if ( pSVData->maCtrlData.mpSplitVPinImgList )
434 delete pSVData->maCtrlData.mpSplitVPinImgList;
435 pSVData->maCtrlData.mpSplitVPinImgList = NULL;
437 if ( pSVData->maCtrlData.mpSplitHArwImgList )
439 delete pSVData->maCtrlData.mpSplitHArwImgList;
440 pSVData->maCtrlData.mpSplitHArwImgList = NULL;
442 if ( pSVData->maCtrlData.mpSplitVArwImgList )
444 delete pSVData->maCtrlData.mpSplitVArwImgList;
445 pSVData->maCtrlData.mpSplitVArwImgList = NULL;
447 if ( pSVData->mpDefaultWin )
449 delete pSVData->mpDefaultWin;
450 pSVData->mpDefaultWin = NULL;
453 // #114285# Moved here from ImplDeInitSVData...
454 if ( pSVData->mpUnoWrapper )
456 pSVData->mpUnoWrapper->Destroy();
457 pSVData->mpUnoWrapper = NULL;
460 pSVData->maAppData.mxMSF.clear();
462 if( pSVData->mpApp )
463 // call deinit to deinitialize application class
464 // soffice/sfx implementation disposes the global service manager
465 // Warning: After this call you can't call uno services
466 pSVData->mpApp->DeInit();
468 if ( pSVData->maAppData.mpSettings )
470 delete pSVData->maAppData.mpSettings;
471 pSVData->maAppData.mpSettings = NULL;
473 if ( pSVData->maAppData.mpAccelMgr )
475 delete pSVData->maAppData.mpAccelMgr;
476 pSVData->maAppData.mpAccelMgr = NULL;
478 if ( pSVData->maAppData.mpUniqueIdCont )
480 delete pSVData->maAppData.mpUniqueIdCont;
481 pSVData->maAppData.mpUniqueIdCont = NULL;
483 if ( pSVData->maAppData.mpAppFileName )
485 delete pSVData->maAppData.mpAppFileName;
486 pSVData->maAppData.mpAppFileName = NULL;
488 if ( pSVData->maAppData.mpAppName )
490 delete pSVData->maAppData.mpAppName;
491 pSVData->maAppData.mpAppName = NULL;
493 if ( pSVData->maAppData.mpDisplayName )
495 delete pSVData->maAppData.mpDisplayName;
496 pSVData->maAppData.mpDisplayName = NULL;
498 if ( pSVData->maAppData.mpEventListeners )
500 delete pSVData->maAppData.mpEventListeners;
501 pSVData->maAppData.mpEventListeners = NULL;
503 if ( pSVData->maAppData.mpKeyListeners )
505 delete pSVData->maAppData.mpKeyListeners;
506 pSVData->maAppData.mpKeyListeners = NULL;
509 if ( pSVData->maAppData.mpFirstHotKey )
510 ImplFreeHotKeyData();
511 if ( pSVData->maAppData.mpFirstEventHook )
512 ImplFreeEventHookData();
514 ImplDeletePrnQueueList();
515 delete pSVData->maGDIData.mpScreenFontList;
516 pSVData->maGDIData.mpScreenFontList = NULL;
517 delete pSVData->maGDIData.mpScreenFontCache;
518 pSVData->maGDIData.mpScreenFontCache = NULL;
519 ImplFreeOutDevFontData();
521 if ( pSVData->mpResMgr )
523 delete pSVData->mpResMgr;
524 pSVData->mpResMgr = NULL;
527 ResMgr::DestroyAllResMgr();
529 // destroy all Sal interfaces before destorying the instance
530 // and thereby unloading the plugin
531 delete pSVData->mpSalSystem;
532 pSVData->mpSalSystem = NULL;
533 delete pSVData->mpSalTimer;
534 pSVData->mpSalTimer = NULL;
536 // Sal deinitialisieren
537 DestroySalInstance( pSVData->mpDefInst );
539 DeInitTools();
541 DeInitSalMain();
543 if( pOwnSvApp )
545 delete pOwnSvApp;
546 pOwnSvApp = NULL;
550 // only one call is allowed
551 struct WorkerThreadData
553 oslWorkerFunction pWorker;
554 void * pThreadData;
555 WorkerThreadData( oslWorkerFunction pWorker_, void * pThreadData_ )
556 : pWorker( pWorker_ )
557 , pThreadData( pThreadData_ )
562 #ifdef WNT
563 static HANDLE hThreadID = 0;
564 static unsigned __stdcall _threadmain( void *pArgs )
566 OleInitialize( NULL );
567 ((WorkerThreadData*)pArgs)->pWorker( ((WorkerThreadData*)pArgs)->pThreadData );
568 delete (WorkerThreadData*)pArgs;
569 OleUninitialize();
570 hThreadID = 0;
571 return 0;
573 #else
574 static oslThread hThreadID = 0;
575 extern "C"
577 static void SAL_CALL MainWorkerFunction( void* pArgs )
579 ((WorkerThreadData*)pArgs)->pWorker( ((WorkerThreadData*)pArgs)->pThreadData );
580 delete (WorkerThreadData*)pArgs;
581 hThreadID = 0;
583 } // extern "C"
584 #endif
586 void CreateMainLoopThread( oslWorkerFunction pWorker, void * pThreadData )
588 #ifdef WNT
589 // sal thread alway call CoInitializeEx, so a sysdepen implementation is necessary
591 unsigned uThreadID;
592 hThreadID = (HANDLE)_beginthreadex(
593 NULL, // no security handle
594 0, // stacksize 0 means default
595 _threadmain, // thread worker function
596 new WorkerThreadData( pWorker, pThreadData ), // arguments for worker function
597 0, // 0 means: create immediatly otherwise use CREATE_SUSPENDED
598 &uThreadID ); // thread id to fill
599 #else
600 hThreadID = osl_createThread( MainWorkerFunction, new WorkerThreadData( pWorker, pThreadData ) );
601 #endif
604 void JoinMainLoopThread()
606 if( hThreadID )
608 #ifdef WNT
609 WaitForSingleObject(hThreadID, INFINITE);
610 #else
611 osl_joinWithThread(hThreadID);
612 osl_destroyThread( hThreadID );
613 #endif