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