LCOV - code coverage report
Current view: top level - vcl/source/app - svmain.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 157 218 72.0 %
Date: 2015-06-13 12:38:46 Functions: 18 19 94.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <sal/config.h>
      21             : 
      22             : #include <cassert>
      23             : 
      24             : #include <osl/file.hxx>
      25             : #include <osl/signal.h>
      26             : 
      27             : #include "tools/debug.hxx"
      28             : #include "tools/resmgr.hxx"
      29             : 
      30             : #include "comphelper/processfactory.hxx"
      31             : 
      32             : #include "unotools/syslocaleoptions.hxx"
      33             : #include "vcl/svapp.hxx"
      34             : #include "vcl/wrkwin.hxx"
      35             : #include "vcl/cvtgrf.hxx"
      36             : #include "vcl/scheduler.hxx"
      37             : #include "vcl/image.hxx"
      38             : #include "vcl/settings.hxx"
      39             : #include "vcl/unowrap.hxx"
      40             : #include "vcl/configsettings.hxx"
      41             : #include "vcl/lazydelete.hxx"
      42             : #include "vcl/embeddedfontshelper.hxx"
      43             : #include "vcl/debugevent.hxx"
      44             : 
      45             : #ifdef WNT
      46             : #include <svsys.h>
      47             : #include <process.h>
      48             : #include <ole2.h>
      49             : #endif
      50             : 
      51             : #ifdef ANDROID
      52             : #include <cppuhelper/bootstrap.hxx>
      53             : #include <jni.h>
      54             : #endif
      55             : 
      56             : #include "salinst.hxx"
      57             : #include "salwtype.hxx"
      58             : #include "svdata.hxx"
      59             : #include "vcl/svmain.hxx"
      60             : #include "dbggui.hxx"
      61             : #include "accmgr.hxx"
      62             : #include "idlemgr.hxx"
      63             : #include "outdev.h"
      64             : #include "outfont.hxx"
      65             : #include "PhysicalFontCollection.hxx"
      66             : #include "print.h"
      67             : #include "salgdi.hxx"
      68             : #include "salsys.hxx"
      69             : #include "saltimer.hxx"
      70             : #include "salimestatus.hxx"
      71             : #include "impimagetree.hxx"
      72             : #include "xconnection.hxx"
      73             : 
      74             : #include "vcl/opengl/OpenGLContext.hxx"
      75             : 
      76             : #include "osl/process.h"
      77             : #include "com/sun/star/lang/XMultiServiceFactory.hpp"
      78             : #include "com/sun/star/lang/XComponent.hpp"
      79             : #include "com/sun/star/frame/Desktop.hpp"
      80             : 
      81             : #include "cppuhelper/implbase1.hxx"
      82             : #include "uno/current_context.hxx"
      83             : 
      84             : #if OSL_DEBUG_LEVEL > 0
      85             : #include <typeinfo>
      86             : #include "rtl/strbuf.hxx"
      87             : #endif
      88             : 
      89             : using namespace ::com::sun::star;
      90             : 
      91           0 : oslSignalAction SAL_CALL VCLExceptionSignal_impl( void* /*pData*/, oslSignalInfo* pInfo)
      92             : {
      93             :     static bool bIn = false;
      94             : 
      95             :     // if we crash again, bail out immediately
      96           0 :     if ( !bIn )
      97             :     {
      98           0 :         sal_uInt16 nVCLException = 0;
      99             : 
     100             :         // UAE
     101           0 :         if ( (pInfo->Signal == osl_Signal_AccessViolation)     ||
     102           0 :              (pInfo->Signal == osl_Signal_IntegerDivideByZero) ||
     103           0 :              (pInfo->Signal == osl_Signal_FloatDivideByZero)   ||
     104           0 :              (pInfo->Signal == osl_Signal_DebugBreak) )
     105           0 :             nVCLException = EXC_SYSTEM;
     106             : 
     107             :         // RC
     108           0 :         if ((pInfo->Signal == osl_Signal_User) &&
     109           0 :             (pInfo->UserSignal == OSL_SIGNAL_USER_RESOURCEFAILURE) )
     110           0 :             nVCLException = EXC_RSCNOTLOADED;
     111             : 
     112             :         // DISPLAY-Unix
     113           0 :         if ((pInfo->Signal == osl_Signal_User) &&
     114           0 :             (pInfo->UserSignal == OSL_SIGNAL_USER_X11SUBSYSTEMERROR) )
     115           0 :             nVCLException = EXC_DISPLAY;
     116             : 
     117             :         // Remote-Client
     118           0 :         if ((pInfo->Signal == osl_Signal_User) &&
     119           0 :             (pInfo->UserSignal == OSL_SIGNAL_USER_RVPCONNECTIONERROR) )
     120           0 :             nVCLException = EXC_REMOTE;
     121             : 
     122           0 :         if ( nVCLException )
     123             :         {
     124           0 :             bIn = true;
     125             : 
     126           0 :             SolarMutexGuard aLock;
     127             : 
     128             :             // do not stop timer because otherwise the UAE-Box will not be painted as well
     129           0 :             ImplSVData* pSVData = ImplGetSVData();
     130           0 :             if ( pSVData->mpApp )
     131             :             {
     132           0 :                 SystemWindowFlags nOldMode = Application::GetSystemWindowMode();
     133           0 :                 Application::SetSystemWindowMode( nOldMode & ~SystemWindowFlags::NOAUTOMODE );
     134           0 :                 pSVData->mpApp->Exception( nVCLException );
     135           0 :                 Application::SetSystemWindowMode( nOldMode );
     136             :             }
     137           0 :             bIn = false;
     138             : 
     139           0 :             return osl_Signal_ActCallNextHdl;
     140             :         }
     141             :     }
     142             : 
     143           0 :     return osl_Signal_ActCallNextHdl;
     144             : 
     145             : }
     146             : 
     147         127 : int ImplSVMain()
     148             : {
     149             :     // The 'real' SVMain()
     150         127 :     ImplSVData* pSVData = ImplGetSVData();
     151             : 
     152             :     DBG_ASSERT( pSVData->mpApp, "no instance of class Application" );
     153             : 
     154         127 :     int nReturn = EXIT_FAILURE;
     155             : 
     156         127 :     bool bInit = InitVCL();
     157             : 
     158         127 :     if( bInit )
     159             :     {
     160             :         // call application main
     161         127 :         pSVData->maAppData.mbInAppMain = true;
     162         127 :         nReturn = pSVData->mpApp->Main();
     163         127 :         pSVData->maAppData.mbInAppMain = false;
     164             :     }
     165             : 
     166         127 :     if( pSVData->mxDisplayConnection.is() )
     167             :     {
     168          44 :         pSVData->mxDisplayConnection->terminate();
     169          44 :         pSVData->mxDisplayConnection.clear();
     170             :     }
     171             : 
     172             :     // This is a hack to work around the problem of the asynchronous nature
     173             :     // of bridging accessibility through Java: on shutdown there might still
     174             :     // be some events in the AWT EventQueue, which need the SolarMutex which
     175             :     // - on the other hand - is destroyed in DeInitVCL(). So empty the queue
     176             :     // here ..
     177         127 :     if( pSVData->mxAccessBridge.is() )
     178             :     {
     179             :         {
     180           0 :             SolarMutexReleaser aReleaser;
     181           0 :             pSVData->mxAccessBridge->dispose();
     182             :         }
     183           0 :       pSVData->mxAccessBridge.clear();
     184             :     }
     185             : 
     186         127 :     DeInitVCL();
     187         127 :     return nReturn;
     188             : }
     189             : 
     190         127 : int SVMain()
     191             : {
     192             :     int nRet;
     193         127 :     if( !Application::IsConsoleOnly() && ImplSVMainHook( &nRet ) )
     194           0 :         return nRet;
     195             :     else
     196         127 :         return ImplSVMain();
     197             : }
     198             : 
     199             : // This variable is set when no Application object has been instantiated
     200             : // before InitVCL is called
     201             : static Application *        pOwnSvApp = NULL;
     202             : 
     203             : // Exception handler. pExceptionHandler != NULL => VCL already inited
     204             : static oslSignalHandler pExceptionHandler = NULL;
     205             : 
     206           2 : class DesktopEnvironmentContext: public cppu::WeakImplHelper1< com::sun::star::uno::XCurrentContext >
     207             : {
     208             : public:
     209         245 :     explicit DesktopEnvironmentContext( const com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > & ctx)
     210         245 :         : m_xNextContext( ctx ) {}
     211             : 
     212             :     // XCurrentContext
     213             :     virtual com::sun::star::uno::Any SAL_CALL getValueByName( const OUString& Name )
     214             :             throw (com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     215             : 
     216             : private:
     217             :     com::sun::star::uno::Reference< com::sun::star::uno::XCurrentContext > m_xNextContext;
     218             : };
     219             : 
     220         133 : uno::Any SAL_CALL DesktopEnvironmentContext::getValueByName( const OUString& Name) throw (uno::RuntimeException, std::exception)
     221             : {
     222         133 :     uno::Any retVal;
     223             : 
     224         133 :     if ( Name == "system.desktop-environment" )
     225             :     {
     226         133 :         retVal = uno::makeAny( Application::GetDesktopEnvironment() );
     227             :     }
     228           0 :     else if( m_xNextContext.is() )
     229             :     {
     230             :         // Call next context in chain if found
     231           0 :         retVal = m_xNextContext->getValueByName( Name );
     232             :     }
     233         133 :     return retVal;
     234             : }
     235             : 
     236         413 : bool InitVCL()
     237             : {
     238         413 :     if( pExceptionHandler != NULL )
     239         168 :         return false;
     240             : 
     241         245 :     EmbeddedFontsHelper::clearTemporaryFontFiles();
     242             : 
     243         245 :     if( !ImplGetSVData()->mpApp )
     244             :     {
     245         118 :         pOwnSvApp = new Application();
     246             :     }
     247         245 :     InitSalMain();
     248             : 
     249         245 :     ImplSVData* pSVData = ImplGetSVData();
     250             : 
     251             :     // remember Main-Thread-Id
     252         245 :     pSVData->mnMainThreadId = ::osl::Thread::getCurrentIdentifier();
     253             : 
     254             :     // Initialize Sal
     255         245 :     pSVData->mpDefInst = CreateSalInstance();
     256         245 :     if ( !pSVData->mpDefInst )
     257           0 :         return false;
     258             : 
     259             :     // Desktop Environment context (to be able to get value of "system.desktop-environment" as soon as possible)
     260             :     com::sun::star::uno::setCurrentContext(
     261         245 :         new DesktopEnvironmentContext( com::sun::star::uno::getCurrentContext() ) );
     262             : 
     263             :     // Initialize application instance (should be done after initialization of VCL SAL part)
     264         245 :     if( pSVData->mpApp )
     265             :         // call init to initialize application class
     266             :         // soffice/sfx implementation creates the global service manager
     267         245 :         pSVData->mpApp->Init();
     268             : 
     269         245 :     pSVData->mpDefInst->AfterAppInit();
     270             : 
     271             :     // Fetch AppFileName and make it absolute before the workdir changes...
     272         245 :     OUString aExeFileName;
     273         245 :     osl_getExecutableFile( &aExeFileName.pData );
     274             : 
     275             :     // convert path to native file format
     276         490 :     OUString aNativeFileName;
     277         245 :     osl::FileBase::getSystemPathFromFileURL( aExeFileName, aNativeFileName );
     278         245 :     pSVData->maAppData.mpAppFileName = new OUString( aNativeFileName );
     279             : 
     280             :     // Initialize global data
     281         245 :     pSVData->maGDIData.mpScreenFontList     = new PhysicalFontCollection;
     282         245 :     pSVData->maGDIData.mpScreenFontCache    = new ImplFontCache;
     283         245 :     pSVData->maGDIData.mpGrfConverter       = new GraphicConverter;
     284             : 
     285             :     // Set exception handler
     286         245 :     pExceptionHandler = osl_addSignalHandler(VCLExceptionSignal_impl, NULL);
     287             : 
     288             :     DBGGUI_INIT_SOLARMUTEXCHECK();
     289             : 
     290             : #if OSL_DEBUG_LEVEL > 0
     291             :     DebugEventInjector::getCreate();
     292             : #endif
     293             : 
     294         490 :     return true;
     295             : }
     296             : 
     297             : namespace
     298             : {
     299             : 
     300             : /** Serves for destroying the VCL UNO wrapper as late as possible. This avoids
     301             :   crash at exit in some special cases when a11y is enabled (e.g., when
     302             :   a bundled extension is registered/deregistered during startup, forcing exit
     303             :   while the app is still in splash screen.)
     304             :  */
     305         351 : class VCLUnoWrapperDeleter : public cppu::WeakImplHelper1<com::sun::star::lang::XEventListener>
     306             : {
     307             :     virtual void SAL_CALL disposing(lang::EventObject const& rSource) throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
     308             : };
     309             : 
     310             : void
     311         117 : VCLUnoWrapperDeleter::disposing(lang::EventObject const& /* rSource */)
     312             :     throw(uno::RuntimeException, std::exception)
     313             : {
     314         117 :     ImplSVData* const pSVData = ImplGetSVData();
     315         117 :     if (pSVData && pSVData->mpUnoWrapper)
     316             :     {
     317         117 :         pSVData->mpUnoWrapper->Destroy();
     318         117 :         pSVData->mpUnoWrapper = NULL;
     319             :     }
     320         117 : }
     321             : 
     322             : }
     323             : 
     324         242 : void DeInitVCL()
     325             : {
     326         242 :     ImplSVData* pSVData = ImplGetSVData();
     327         242 :     pSVData->mbDeInit = true;
     328             : 
     329         242 :     vcl::DeleteOnDeinitBase::ImplDeleteOnDeInit();
     330             : 
     331             :     // give ime status a chance to destroy its own windows
     332         242 :     delete pSVData->mpImeStatus;
     333         242 :     pSVData->mpImeStatus = NULL;
     334             : 
     335             : #if OSL_DEBUG_LEVEL > 0
     336             :     OStringBuffer aBuf( 256 );
     337             :     aBuf.append( "DeInitVCL: some top Windows are still alive\n" );
     338             :     long nTopWindowCount = Application::GetTopWindowCount();
     339             :     long nBadTopWindows = nTopWindowCount;
     340             :     for( long i = 0; i < nTopWindowCount; i++ )
     341             :     {
     342             :         vcl::Window* pWin = Application::GetTopWindow( i );
     343             :         // default window will be destroyed further down
     344             :         // but may still be useful during deinit up to that point
     345             :         if( pWin == pSVData->mpDefaultWin )
     346             :             nBadTopWindows--;
     347             :         else
     348             :         {
     349             :             aBuf.append( "text = \"" );
     350             :             aBuf.append( OUStringToOString( pWin->GetText(), osl_getThreadTextEncoding() ) );
     351             :             aBuf.append( "\" type = \"" );
     352             :             aBuf.append( typeid(*pWin).name() );
     353             :             aBuf.append( "\", ptr = 0x" );
     354             :             aBuf.append( sal_Int64( pWin ), 16 );
     355             :             aBuf.append( "\n" );
     356             :         }
     357             :     }
     358             :     DBG_ASSERT( nBadTopWindows==0, aBuf.getStr() );
     359             : #endif
     360             : 
     361         242 :     ImplImageTreeSingletonRef()->shutDown();
     362             : 
     363         242 :     osl_removeSignalHandler( pExceptionHandler);
     364         242 :     pExceptionHandler = NULL;
     365             : 
     366             :     // free global data
     367         242 :     delete pSVData->maGDIData.mpGrfConverter;
     368             : 
     369         242 :     if( pSVData->mpSettingsConfigItem )
     370         178 :         delete pSVData->mpSettingsConfigItem, pSVData->mpSettingsConfigItem = NULL;
     371             : 
     372         242 :     if ( pSVData->maAppData.mpIdleMgr )
     373          89 :         delete pSVData->maAppData.mpIdleMgr;
     374         242 :     Scheduler::ImplDeInitScheduler();
     375             : 
     376         242 :     if ( pSVData->maWinData.mpMsgBoxImgList )
     377             :     {
     378           0 :         delete pSVData->maWinData.mpMsgBoxImgList;
     379           0 :         pSVData->maWinData.mpMsgBoxImgList = NULL;
     380             :     }
     381         242 :     if ( pSVData->maCtrlData.mpCheckImgList )
     382             :     {
     383          19 :         delete pSVData->maCtrlData.mpCheckImgList;
     384          19 :         pSVData->maCtrlData.mpCheckImgList = NULL;
     385             :     }
     386         242 :     if ( pSVData->maCtrlData.mpRadioImgList )
     387             :     {
     388           4 :         delete pSVData->maCtrlData.mpRadioImgList;
     389           4 :         pSVData->maCtrlData.mpRadioImgList = NULL;
     390             :     }
     391         242 :     if ( pSVData->maCtrlData.mpPinImgList )
     392             :     {
     393           0 :         delete pSVData->maCtrlData.mpPinImgList;
     394           0 :         pSVData->maCtrlData.mpPinImgList = NULL;
     395             :     }
     396         242 :     if ( pSVData->maCtrlData.mpSplitHPinImgList )
     397             :     {
     398           0 :         delete pSVData->maCtrlData.mpSplitHPinImgList;
     399           0 :         pSVData->maCtrlData.mpSplitHPinImgList = NULL;
     400             :     }
     401         242 :     if ( pSVData->maCtrlData.mpSplitVPinImgList )
     402             :     {
     403           0 :         delete pSVData->maCtrlData.mpSplitVPinImgList;
     404           0 :         pSVData->maCtrlData.mpSplitVPinImgList = NULL;
     405             :     }
     406         242 :     if ( pSVData->maCtrlData.mpSplitHArwImgList )
     407             :     {
     408           0 :         delete pSVData->maCtrlData.mpSplitHArwImgList;
     409           0 :         pSVData->maCtrlData.mpSplitHArwImgList = NULL;
     410             :     }
     411         242 :     if ( pSVData->maCtrlData.mpSplitVArwImgList )
     412             :     {
     413           0 :         delete pSVData->maCtrlData.mpSplitVArwImgList;
     414           0 :         pSVData->maCtrlData.mpSplitVArwImgList = NULL;
     415             :     }
     416         242 :     if ( pSVData->maCtrlData.mpDisclosurePlus )
     417             :     {
     418           0 :         delete pSVData->maCtrlData.mpDisclosurePlus;
     419           0 :         pSVData->maCtrlData.mpDisclosurePlus = NULL;
     420             :     }
     421         242 :     if ( pSVData->maCtrlData.mpDisclosureMinus )
     422             :     {
     423           0 :         delete pSVData->maCtrlData.mpDisclosureMinus;
     424           0 :         pSVData->maCtrlData.mpDisclosureMinus = NULL;
     425             :     }
     426         242 :     pSVData->mpDefaultWin.disposeAndClear();
     427             : 
     428             :     DBGGUI_DEINIT_SOLARMUTEXCHECK();
     429             : 
     430         242 :     if ( pSVData->mpUnoWrapper )
     431             :     {
     432             :         try
     433             :         {
     434             :             uno::Reference<frame::XDesktop2> const xDesktop = frame::Desktop::create(
     435         121 :                     comphelper::getProcessComponentContext() );
     436         117 :             xDesktop->addEventListener(new VCLUnoWrapperDeleter());
     437             :         }
     438           2 :         catch (uno::Exception const&)
     439             :         {
     440             :             // ignore
     441             :         }
     442             :     }
     443             : 
     444         242 :     if( pSVData->mpApp || pSVData->maDeInitHook.IsSet() )
     445             :     {
     446         242 :         SolarMutexReleaser aReleaser;
     447             :         // call deinit to deinitialize application class
     448             :         // soffice/sfx implementation disposes the global service manager
     449             :         // Warning: After this call you can't call uno services
     450         242 :         if( pSVData->mpApp )
     451             :         {
     452         242 :             pSVData->mpApp->DeInit();
     453             :         }
     454         242 :         if( pSVData->maDeInitHook.IsSet() )
     455             :         {
     456         115 :             pSVData->maDeInitHook.Call(0);
     457         242 :         }
     458             :     }
     459             : 
     460         242 :     if ( pSVData->maAppData.mpSettings )
     461             :     {
     462         223 :         if ( pSVData->maAppData.mpCfgListener )
     463             :         {
     464         223 :             pSVData->maAppData.mpSettings->GetSysLocale().GetOptions().RemoveListener( pSVData->maAppData.mpCfgListener );
     465         223 :             delete pSVData->maAppData.mpCfgListener;
     466             :         }
     467             : 
     468         223 :         delete pSVData->maAppData.mpSettings;
     469         223 :         pSVData->maAppData.mpSettings = NULL;
     470             :     }
     471         242 :     if ( pSVData->maAppData.mpAccelMgr )
     472             :     {
     473           0 :         delete pSVData->maAppData.mpAccelMgr;
     474           0 :         pSVData->maAppData.mpAccelMgr = NULL;
     475             :     }
     476         242 :     if ( pSVData->maAppData.mpAppFileName )
     477             :     {
     478         242 :         delete pSVData->maAppData.mpAppFileName;
     479         242 :         pSVData->maAppData.mpAppFileName = NULL;
     480             :     }
     481         242 :     if ( pSVData->maAppData.mpAppName )
     482             :     {
     483         116 :         delete pSVData->maAppData.mpAppName;
     484         116 :         pSVData->maAppData.mpAppName = NULL;
     485             :     }
     486         242 :     if ( pSVData->maAppData.mpDisplayName )
     487             :     {
     488         116 :         delete pSVData->maAppData.mpDisplayName;
     489         116 :         pSVData->maAppData.mpDisplayName = NULL;
     490             :     }
     491         242 :     if ( pSVData->maAppData.mpEventListeners )
     492             :     {
     493         120 :         delete pSVData->maAppData.mpEventListeners;
     494         120 :         pSVData->maAppData.mpEventListeners = NULL;
     495             :     }
     496         242 :     if ( pSVData->maAppData.mpKeyListeners )
     497             :     {
     498           0 :         delete pSVData->maAppData.mpKeyListeners;
     499           0 :         pSVData->maAppData.mpKeyListeners = NULL;
     500             :     }
     501         242 :     if ( pSVData->maAppData.mpPostYieldListeners )
     502             :     {
     503           0 :         delete pSVData->maAppData.mpPostYieldListeners;
     504           0 :         pSVData->maAppData.mpPostYieldListeners = NULL;
     505             :     }
     506             : 
     507         242 :     if ( pSVData->maAppData.mpFirstHotKey )
     508           0 :         ImplFreeHotKeyData();
     509         242 :     if ( pSVData->maAppData.mpFirstEventHook )
     510           0 :         ImplFreeEventHookData();
     511             : 
     512         242 :     if (pSVData->mpBlendFrameCache)
     513           0 :         delete pSVData->mpBlendFrameCache, pSVData->mpBlendFrameCache = NULL;
     514             : 
     515         242 :     ImplDeletePrnQueueList();
     516         242 :     delete pSVData->maGDIData.mpScreenFontList;
     517         242 :     pSVData->maGDIData.mpScreenFontList = NULL;
     518         242 :     delete pSVData->maGDIData.mpScreenFontCache;
     519         242 :     pSVData->maGDIData.mpScreenFontCache = NULL;
     520             : 
     521         242 :     if ( pSVData->mpResMgr )
     522             :     {
     523         105 :         delete pSVData->mpResMgr;
     524         105 :         pSVData->mpResMgr = NULL;
     525             :     }
     526             : 
     527         242 :     ResMgr::DestroyAllResMgr();
     528             : 
     529             :     // destroy all Sal interfaces before destorying the instance
     530             :     // and thereby unloading the plugin
     531         242 :     delete pSVData->mpSalSystem;
     532         242 :     pSVData->mpSalSystem = NULL;
     533         242 :     delete pSVData->mpSalTimer;
     534         242 :     pSVData->mpSalTimer = NULL;
     535             : 
     536             :     // Deinit Sal
     537         242 :     DestroySalInstance( pSVData->mpDefInst );
     538             : 
     539         242 :     if( pOwnSvApp )
     540             :     {
     541         115 :         delete pOwnSvApp;
     542         115 :         pOwnSvApp = NULL;
     543             :     }
     544             : 
     545         242 :     EmbeddedFontsHelper::clearTemporaryFontFiles();
     546         242 : }
     547             : 
     548             : // only one call is allowed
     549             : struct WorkerThreadData
     550             : {
     551             :     oslWorkerFunction   pWorker;
     552             :     void *              pThreadData;
     553         162 :     WorkerThreadData( oslWorkerFunction pWorker_, void * pThreadData_ )
     554             :         : pWorker( pWorker_ )
     555         162 :         , pThreadData( pThreadData_ )
     556             :     {
     557         162 :     }
     558             : };
     559             : 
     560             : #ifdef WNT
     561             : static HANDLE hThreadID = 0;
     562             : static unsigned __stdcall _threadmain( void *pArgs )
     563             : {
     564             :     OleInitialize( NULL );
     565             :     ((WorkerThreadData*)pArgs)->pWorker( ((WorkerThreadData*)pArgs)->pThreadData );
     566             :     delete (WorkerThreadData*)pArgs;
     567             :     OleUninitialize();
     568             :     hThreadID = 0;
     569             :     return 0;
     570             : }
     571             : #else
     572             : static oslThread hThreadID = 0;
     573             : extern "C"
     574             : {
     575         162 : static void SAL_CALL MainWorkerFunction( void* pArgs )
     576             : {
     577         162 :     static_cast<WorkerThreadData*>(pArgs)->pWorker( static_cast<WorkerThreadData*>(pArgs)->pThreadData );
     578         162 :     delete static_cast<WorkerThreadData*>(pArgs);
     579         162 :     hThreadID = 0;
     580         162 : }
     581             : } // extern "C"
     582             : #endif
     583             : 
     584         162 : void CreateMainLoopThread( oslWorkerFunction pWorker, void * pThreadData )
     585             : {
     586             : #ifdef WNT
     587             :     // sal thread always call CoInitializeEx, so a sysdepen implementation is necessary
     588             : 
     589             :     unsigned uThreadID;
     590             :     hThreadID = (HANDLE)_beginthreadex(
     591             :         NULL,       // no security handle
     592             :         0,          // stacksize 0 means default
     593             :         _threadmain,    // thread worker function
     594             :         new WorkerThreadData( pWorker, pThreadData ),       // arguments for worker function
     595             :         0,          // 0 means: create immediately otherwise use CREATE_SUSPENDED
     596             :         &uThreadID );   // thread id to fill
     597             : #else
     598         162 :     hThreadID = osl_createThread( MainWorkerFunction, new WorkerThreadData( pWorker, pThreadData ) );
     599             : #endif
     600         162 : }
     601             : 
     602         162 : void JoinMainLoopThread()
     603             : {
     604         162 :     if( hThreadID )
     605             :     {
     606             : #ifdef WNT
     607             :         WaitForSingleObject(hThreadID, INFINITE);
     608             : #else
     609         128 :         osl_joinWithThread(hThreadID);
     610         128 :         osl_destroyThread( hThreadID );
     611             : #endif
     612             :     }
     613         963 : }
     614             : 
     615             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11