1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_libraries.h>
22 #include "osl/module.h"
23 #include "osl/process.h"
25 #include "rtl/bootstrap.hxx"
27 #include "salinst.hxx"
28 #include "generic/gensys.h"
29 #include "generic/gendata.hxx"
30 #include "unx/desktops.hxx"
31 #include "vcl/printerinfomanager.hxx"
32 #include <config_vclplug.h>
38 typedef SalInstance
*(*salFactoryProc
)( oslModule pModule
);
41 static oslModule pCloseModule
= NULL
;
43 static SalInstance
* tryInstance( const OUString
& rModuleBase
, bool bForce
= false )
45 SalInstance
* pInst
= NULL
;
46 // Disable gtk3 plugin for now unless explicitly requested via
47 // SAL_USE_VCLPLUGIN=gtk3 (would ideally depend on experimental mode, but
48 // reading the experimental mode setting requires the UNO service manager
49 // which has not yet been instantiated):
50 if (!bForce
&& rModuleBase
== "gtk3")
58 "vclplug_" + rModuleBase
+ "lo" SAL_DLLEXTENSION
);
60 oslModule aMod
= osl_loadModuleRelative(
61 reinterpret_cast< oslGenericFunction
>( &tryInstance
), aModule
.pData
,
62 SAL_LOADMODULE_DEFAULT
);
65 salFactoryProc aProc
= (salFactoryProc
)osl_getAsciiFunctionSymbol( aMod
, "create_SalInstance" );
68 pInst
= aProc( aMod
);
71 "sal plugin " << aModule
<< " produced instance " << pInst
);
78 * Recent GTK+ versions load their modules with RTLD_LOCAL, so we can
79 * not access the 'gnome_accessibility_module_shutdown' anymore.
80 * So make sure libgtk+ & co are still mapped into memory when
81 * atk-bridge's atexit handler gets called.
82 * #i109007# KDE3 seems to have the same problem.
83 * And same applies for KDE4.
85 if( rModuleBase
== "gtk" || rModuleBase
== "gtk3" || rModuleBase
== "tde" || rModuleBase
== "kde" || rModuleBase
== "kde4" )
90 GetSalData()->m_pPlugin
= aMod
;
93 osl_unloadModule( aMod
);
99 "could not load symbol create_SalInstance from shared object "
101 osl_unloadModule( aMod
);
106 SAL_WARN("vcl.plugadapt", "could not load shared object " << aModule
);
110 SAL_INFO("vcl.plugadapt", "could not load shared object " << aModule
);
116 #if !defined(ANDROID)
118 static DesktopType
get_desktop_environment()
120 OUString
aModule(LIBO_LIBRARY(desktop_detector
));
121 oslModule aMod
= osl_loadModuleRelative(
122 reinterpret_cast< oslGenericFunction
>( &tryInstance
), aModule
.pData
,
123 SAL_LOADMODULE_DEFAULT
);
124 DesktopType ret
= DESKTOP_UNKNOWN
;
127 DesktopType (*pSym
)() = (DesktopType(*)())
128 osl_getAsciiFunctionSymbol( aMod
, "get_desktop_environment" );
132 osl_unloadModule( aMod
);
138 #define get_desktop_environment() DESKTOP_NONE // For now...
142 static SalInstance
* autodetect_plugin()
144 static const char* const pTDEFallbackList
[] =
153 "gtk3", "gtk", "gen", 0
156 static const char* const pKDEFallbackList
[] =
164 "gtk3", "gtk", "gen", 0
167 static const char* const pStandardFallbackList
[] =
169 "gtk3", "gtk", "gen", 0
172 static const char* const pHeadlessFallbackList
[] =
177 DesktopType desktop
= get_desktop_environment();
178 const char * const * pList
= pStandardFallbackList
;
181 // no server at all: dummy plugin
182 if ( desktop
== DESKTOP_NONE
)
183 pList
= pHeadlessFallbackList
;
184 else if ( desktop
== DESKTOP_GNOME
||
185 desktop
== DESKTOP_UNITY
||
186 desktop
== DESKTOP_XFCE
||
187 desktop
== DESKTOP_MATE
)
188 pList
= pStandardFallbackList
;
189 else if( desktop
== DESKTOP_TDE
)
190 pList
= pTDEFallbackList
;
191 else if( desktop
== DESKTOP_KDE
)
193 pList
= pKDEFallbackList
;
196 else if( desktop
== DESKTOP_KDE4
)
197 pList
= pKDEFallbackList
;
199 SalInstance
* pInst
= NULL
;
200 while( pList
[nListEntry
] && pInst
== NULL
)
202 OUString
aTry( OUString::createFromAscii( pList
[nListEntry
] ) );
203 pInst
= tryInstance( aTry
);
205 pInst
, "vcl.plugadapt",
206 "plugin autodetection: " << pList
[nListEntry
]);
213 SalInstance
*CreateSalInstance()
215 SalInstance
*pInst
= NULL
;
218 if( Application::IsHeadlessModeRequested() )
222 rtl::Bootstrap::get( "SAL_USE_VCLPLUGIN", aUsePlugin
);
225 if( !aUsePlugin
.isEmpty() )
226 pInst
= tryInstance( aUsePlugin
, true );
229 pInst
= autodetect_plugin();
231 // fallback, try everything
232 static const char* const pPlugin
[] = {
233 "gtk3", "gtk", "kde4", "kde", "tde", "gen" };
235 for ( int i
= 0; !pInst
&& i
!= SAL_N_ELEMENTS(pPlugin
); ++i
)
236 pInst
= tryInstance( OUString::createFromAscii( pPlugin
[ i
] ) );
240 std::fprintf( stderr
, "no suitable windowing system found, exiting.\n" );
244 // acquire SolarMutex
245 pInst
->AcquireYieldMutex( 1 );
250 void DestroySalInstance( SalInstance
*pInst
)
252 // release SolarMutex
253 pInst
->ReleaseYieldMutex();
257 osl_unloadModule( pCloseModule
);
272 void SalAbort( const OUString
& rErrorText
, bool bDumpCore
)
274 if( rErrorText
.isEmpty() )
275 std::fprintf( stderr
, "Application Error\n" );
277 std::fprintf( stderr
, "%s\n", OUStringToOString(rErrorText
, osl_getThreadTextEncoding()).getStr() );
284 const OUString
& SalGetDesktopEnvironment()
286 // Order to match desktops.hxx' DesktopType
287 static const char * const desktop_strings
[] = {
288 "none", "unknown", "GNOME", "UNITY",
289 "XFCE", "MATE", "TDE",
291 static OUString aRet
;
294 aRet
= OUString::createFromAscii(
295 desktop_strings
[get_desktop_environment()]);
309 psp::PrinterInfoManager::release();
312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */