Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / vcl / unx / generic / plugadapt / salplug.cxx
blob0fd81dc9ac181979ee314ecaf70ba04843faa9ec
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
34 #include <cstdio>
35 #include <unistd.h>
37 extern "C" {
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")
52 return NULL;
54 OUString aModule(
55 #ifdef SAL_DLLPREFIX
56 SAL_DLLPREFIX
57 #endif
58 "vclplug_" + rModuleBase + "lo" SAL_DLLEXTENSION );
60 oslModule aMod = osl_loadModuleRelative(
61 reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData,
62 SAL_LOADMODULE_DEFAULT );
63 if( aMod )
65 salFactoryProc aProc = (salFactoryProc)osl_getAsciiFunctionSymbol( aMod, "create_SalInstance" );
66 if( aProc )
68 pInst = aProc( aMod );
69 SAL_INFO(
70 "vcl.plugadapt",
71 "sal plugin " << aModule << " produced instance " << pInst);
72 if( pInst )
74 pCloseModule = aMod;
76 #ifndef ANDROID
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" )
87 pCloseModule = NULL;
89 #endif
90 GetSalData()->m_pPlugin = aMod;
92 else
93 osl_unloadModule( aMod );
95 else
97 SAL_WARN(
98 "vcl.plugadapt",
99 "could not load symbol create_SalInstance from shared object "
100 << aModule);
101 osl_unloadModule( aMod );
104 else if (bForce)
106 SAL_WARN("vcl.plugadapt", "could not load shared object " << aModule);
108 else
110 SAL_INFO("vcl.plugadapt", "could not load shared object " << aModule);
113 return pInst;
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;
125 if( aMod )
127 DesktopType (*pSym)() = (DesktopType(*)())
128 osl_getAsciiFunctionSymbol( aMod, "get_desktop_environment" );
129 if( pSym )
130 ret = pSym();
132 osl_unloadModule( aMod );
133 return ret;
136 #else
138 #define get_desktop_environment() DESKTOP_NONE // For now...
140 #endif
142 static SalInstance* autodetect_plugin()
144 static const char* const pTDEFallbackList[] =
146 "tde",
147 #if ENABLE_KDE4
148 "kde4",
149 #endif
150 #if ENABLE_KDE
151 "kde",
152 #endif
153 "gtk3", "gtk", "gen", 0
156 static const char* const pKDEFallbackList[] =
158 #if ENABLE_KDE4
159 "kde4",
160 #endif
161 #if ENABLE_KDE
162 "kde",
163 #endif
164 "gtk3", "gtk", "gen", 0
167 static const char* const pStandardFallbackList[] =
169 "gtk3", "gtk", "gen", 0
172 static const char* const pHeadlessFallbackList[] =
174 "svp", 0
177 DesktopType desktop = get_desktop_environment();
178 const char * const * pList = pStandardFallbackList;
179 int nListEntry = 0;
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;
194 nListEntry = 1;
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 );
204 SAL_INFO_IF(
205 pInst, "vcl.plugadapt",
206 "plugin autodetection: " << pList[nListEntry]);
207 nListEntry++;
210 return pInst;
213 SalInstance *CreateSalInstance()
215 SalInstance *pInst = NULL;
217 OUString aUsePlugin;
218 if( Application::IsHeadlessModeRequested() )
219 aUsePlugin = "svp";
220 else
222 rtl::Bootstrap::get( "SAL_USE_VCLPLUGIN", aUsePlugin );
225 if( !aUsePlugin.isEmpty() )
226 pInst = tryInstance( aUsePlugin, true );
228 if( ! pInst )
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 ] ) );
238 if( ! pInst )
240 std::fprintf( stderr, "no suitable windowing system found, exiting.\n" );
241 _exit( 1 );
244 // acquire SolarMutex
245 pInst->AcquireYieldMutex( 1 );
247 return pInst;
250 void DestroySalInstance( SalInstance *pInst )
252 // release SolarMutex
253 pInst->ReleaseYieldMutex();
255 delete pInst;
256 if( pCloseModule )
257 osl_unloadModule( pCloseModule );
260 void InitSalData()
264 void DeInitSalData()
268 void InitSalMain()
272 void SalAbort( const OUString& rErrorText, bool bDumpCore )
274 if( rErrorText.isEmpty() )
275 std::fprintf( stderr, "Application Error\n" );
276 else
277 std::fprintf( stderr, "%s\n", OUStringToOString(rErrorText, osl_getThreadTextEncoding()).getStr() );
278 if( bDumpCore )
279 abort();
280 else
281 _exit(1);
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",
290 "KDE", "KDE4" };
291 static OUString aRet;
292 if( aRet.isEmpty())
294 aRet = OUString::createFromAscii(
295 desktop_strings[get_desktop_environment()]);
297 return aRet;
300 SalData::SalData() :
301 m_pInstance(NULL),
302 m_pPlugin(NULL),
303 m_pPIManager(NULL)
307 SalData::~SalData()
309 psp::PrinterInfoManager::release();
312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */