1cdf0e10cSrcweir /************************************************************************* 2cdf0e10cSrcweir * 3cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4cdf0e10cSrcweir * 5cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6cdf0e10cSrcweir * 7cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8cdf0e10cSrcweir * 9cdf0e10cSrcweir * This file is part of OpenOffice.org. 10cdf0e10cSrcweir * 11cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14cdf0e10cSrcweir * 15cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20cdf0e10cSrcweir * 21cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25cdf0e10cSrcweir * 26cdf0e10cSrcweir ************************************************************************/ 27cdf0e10cSrcweir 28cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30cdf0e10cSrcweir 31cdf0e10cSrcweir #include "osl/module.h" 32cdf0e10cSrcweir #include "osl/process.h" 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 35cdf0e10cSrcweir 36cdf0e10cSrcweir #include "salinst.hxx" 37cdf0e10cSrcweir #include "unx/saldata.hxx" 38cdf0e10cSrcweir #include "vcl/printerinfomanager.hxx" 39cdf0e10cSrcweir 40cdf0e10cSrcweir #include <cstdio> 41cdf0e10cSrcweir #include <unistd.h> 42cdf0e10cSrcweir 43cdf0e10cSrcweir using namespace rtl; 44cdf0e10cSrcweir 45cdf0e10cSrcweir extern "C" { 46cdf0e10cSrcweir typedef SalInstance*(*salFactoryProc)( oslModule pModule); 47cdf0e10cSrcweir } 48cdf0e10cSrcweir 49cdf0e10cSrcweir static oslModule pCloseModule = NULL; 50cdf0e10cSrcweir 51cdf0e10cSrcweir enum { 52cdf0e10cSrcweir DESKTOP_NONE = 0, 53cdf0e10cSrcweir DESKTOP_UNKNOWN, 54cdf0e10cSrcweir DESKTOP_GNOME, 55cdf0e10cSrcweir DESKTOP_KDE, 56cdf0e10cSrcweir DESKTOP_KDE4, 57cdf0e10cSrcweir DESKTOP_CDE 58cdf0e10cSrcweir }; 59cdf0e10cSrcweir 60cdf0e10cSrcweir static const char * desktop_strings[] = { "none", "unknown", "GNOME", "KDE", "KDE4", "CDE" }; 61cdf0e10cSrcweir 62cdf0e10cSrcweir static SalInstance* tryInstance( const OUString& rModuleBase ) 63cdf0e10cSrcweir { 64cdf0e10cSrcweir SalInstance* pInst = NULL; 65cdf0e10cSrcweir 66cdf0e10cSrcweir OUStringBuffer aModName( 128 ); 67cdf0e10cSrcweir aModName.appendAscii( SAL_DLLPREFIX"vclplug_" ); 68cdf0e10cSrcweir aModName.append( rModuleBase ); 69cdf0e10cSrcweir aModName.appendAscii( SAL_DLLPOSTFIX ); 70*1385a70cSHerbert Dürr aModName.appendAscii( SAL_DLLEXTENSION ); 71cdf0e10cSrcweir OUString aModule = aModName.makeStringAndClear(); 72cdf0e10cSrcweir 73cdf0e10cSrcweir oslModule aMod = osl_loadModuleRelative( 74cdf0e10cSrcweir reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData, 75cdf0e10cSrcweir SAL_LOADMODULE_DEFAULT ); 76cdf0e10cSrcweir if( aMod ) 77cdf0e10cSrcweir { 78cdf0e10cSrcweir salFactoryProc aProc = (salFactoryProc)osl_getAsciiFunctionSymbol( aMod, "create_SalInstance" ); 79cdf0e10cSrcweir if( aProc ) 80cdf0e10cSrcweir { 81cdf0e10cSrcweir pInst = aProc( aMod ); 82cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 83cdf0e10cSrcweir std::fprintf( stderr, "sal plugin %s produced instance %p\n", 84cdf0e10cSrcweir OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr(), 85cdf0e10cSrcweir pInst ); 86cdf0e10cSrcweir #endif 87cdf0e10cSrcweir if( pInst ) 88cdf0e10cSrcweir { 89cdf0e10cSrcweir pCloseModule = aMod; 90cdf0e10cSrcweir 91cdf0e10cSrcweir /* 92cdf0e10cSrcweir * Recent GTK+ versions load their modules with RTLD_LOCAL, so we can 93cdf0e10cSrcweir * not access the 'gnome_accessibility_module_shutdown' anymore. 94cdf0e10cSrcweir * So make sure libgtk+ & co are still mapped into memory when 95cdf0e10cSrcweir * atk-bridge's atexit handler gets called. 96cdf0e10cSrcweir */ 97cdf0e10cSrcweir if( rModuleBase.equalsAscii("gtk") ) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir pCloseModule = NULL; 100cdf0e10cSrcweir } 101cdf0e10cSrcweir /* 102cdf0e10cSrcweir * #i109007# KDE3 seems to have the same problem; an atexit cleanup 103cdf0e10cSrcweir * handler, which cannot be resolved anymore if the plugin is already unloaded. 104cdf0e10cSrcweir */ 105cdf0e10cSrcweir else if( rModuleBase.equalsAscii("kde") ) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir pCloseModule = NULL; 108cdf0e10cSrcweir } 109cdf0e10cSrcweir 110cdf0e10cSrcweir GetSalData()->m_pPlugin = aMod; 111cdf0e10cSrcweir } 112cdf0e10cSrcweir else 113cdf0e10cSrcweir osl_unloadModule( aMod ); 114cdf0e10cSrcweir } 115cdf0e10cSrcweir else 116cdf0e10cSrcweir { 117cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 118cdf0e10cSrcweir std::fprintf( stderr, "could not load symbol %s from shared object %s\n", 119cdf0e10cSrcweir "create_SalInstance", 120cdf0e10cSrcweir OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() ); 121cdf0e10cSrcweir #endif 122cdf0e10cSrcweir osl_unloadModule( aMod ); 123cdf0e10cSrcweir } 124cdf0e10cSrcweir } 125cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 126cdf0e10cSrcweir else 127cdf0e10cSrcweir std::fprintf( stderr, "could not load shared object %s\n", 128cdf0e10cSrcweir OUStringToOString( aModule, RTL_TEXTENCODING_ASCII_US ).getStr() ); 129cdf0e10cSrcweir #endif 130cdf0e10cSrcweir 131cdf0e10cSrcweir return pInst; 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir static const rtl::OUString& get_desktop_environment() 135cdf0e10cSrcweir { 136cdf0e10cSrcweir static rtl::OUString aRet; 137cdf0e10cSrcweir if( ! aRet.getLength() ) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir OUStringBuffer aModName( 128 ); 140cdf0e10cSrcweir aModName.appendAscii( SAL_DLLPREFIX"desktop_detector" ); 141cdf0e10cSrcweir aModName.appendAscii( SAL_DLLPOSTFIX ); 142cdf0e10cSrcweir aModName.appendAscii( SAL_DLLEXTENSION ); 143cdf0e10cSrcweir OUString aModule = aModName.makeStringAndClear(); 144cdf0e10cSrcweir 145cdf0e10cSrcweir oslModule aMod = osl_loadModuleRelative( 146cdf0e10cSrcweir reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData, 147cdf0e10cSrcweir SAL_LOADMODULE_DEFAULT ); 148cdf0e10cSrcweir if( aMod ) 149cdf0e10cSrcweir { 150cdf0e10cSrcweir rtl::OUString (*pSym)() = (rtl::OUString(*)()) 151cdf0e10cSrcweir osl_getAsciiFunctionSymbol( aMod, "get_desktop_environment" ); 152cdf0e10cSrcweir if( pSym ) 153cdf0e10cSrcweir aRet = pSym(); 154cdf0e10cSrcweir } 155cdf0e10cSrcweir osl_unloadModule( aMod ); 156cdf0e10cSrcweir } 157cdf0e10cSrcweir return aRet; 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir static SalInstance* autodetect_plugin() 161cdf0e10cSrcweir { 162cdf0e10cSrcweir static const char* pKDEFallbackList[] = 163cdf0e10cSrcweir { 164cdf0e10cSrcweir "kde4", "kde", "gtk", "gen", 0 165cdf0e10cSrcweir }; 166cdf0e10cSrcweir 167cdf0e10cSrcweir static const char* pStandardFallbackList[] = 168cdf0e10cSrcweir { 169cdf0e10cSrcweir "gtk", "gen", 0 170cdf0e10cSrcweir }; 171cdf0e10cSrcweir 172cdf0e10cSrcweir static const char* pHeadlessFallbackList[] = 173cdf0e10cSrcweir { 174cdf0e10cSrcweir "svp", 0 175cdf0e10cSrcweir }; 176cdf0e10cSrcweir 177cdf0e10cSrcweir const rtl::OUString& desktop( get_desktop_environment() ); 178cdf0e10cSrcweir const char ** pList = pStandardFallbackList; 179cdf0e10cSrcweir int nListEntry = 0; 180cdf0e10cSrcweir 181cdf0e10cSrcweir // no server at all: dummy plugin 182cdf0e10cSrcweir if ( desktop.equalsAscii( desktop_strings[DESKTOP_NONE] ) ) 183cdf0e10cSrcweir pList = pHeadlessFallbackList; 184cdf0e10cSrcweir else if ( desktop.equalsAscii( desktop_strings[DESKTOP_GNOME] ) ) 185cdf0e10cSrcweir pList = pStandardFallbackList; 186cdf0e10cSrcweir else if( desktop.equalsAscii( desktop_strings[DESKTOP_KDE] ) ) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir pList = pKDEFallbackList; 189cdf0e10cSrcweir nListEntry = 1; 190cdf0e10cSrcweir } 191cdf0e10cSrcweir else if( desktop.equalsAscii( desktop_strings[DESKTOP_KDE4] ) ) 192cdf0e10cSrcweir pList = pKDEFallbackList; 193cdf0e10cSrcweir 194cdf0e10cSrcweir SalInstance* pInst = NULL; 195cdf0e10cSrcweir while( pList[nListEntry] && pInst == NULL ) 196cdf0e10cSrcweir { 197cdf0e10cSrcweir rtl::OUString aTry( rtl::OUString::createFromAscii( pList[nListEntry] ) ); 198cdf0e10cSrcweir pInst = tryInstance( aTry ); 199cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 200cdf0e10cSrcweir if( pInst ) 201cdf0e10cSrcweir std::fprintf( stderr, "plugin autodetection: %s\n", pList[nListEntry] ); 202cdf0e10cSrcweir #endif 203cdf0e10cSrcweir nListEntry++; 204cdf0e10cSrcweir } 205cdf0e10cSrcweir 206cdf0e10cSrcweir return pInst; 207cdf0e10cSrcweir } 208cdf0e10cSrcweir 209cdf0e10cSrcweir static SalInstance* check_headless_plugin() 210cdf0e10cSrcweir { 211cdf0e10cSrcweir int nParams = osl_getCommandArgCount(); 212cdf0e10cSrcweir OUString aParam; 213cdf0e10cSrcweir for( int i = 0; i < nParams; i++ ) 214cdf0e10cSrcweir { 215cdf0e10cSrcweir osl_getCommandArg( i, &aParam.pData ); 216cdf0e10cSrcweir if( aParam.equalsAscii( "-headless" ) ) 217cdf0e10cSrcweir return tryInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "svp" ) ) ); 218cdf0e10cSrcweir } 219cdf0e10cSrcweir return NULL; 220cdf0e10cSrcweir } 221cdf0e10cSrcweir 222cdf0e10cSrcweir SalInstance *CreateSalInstance() 223cdf0e10cSrcweir { 224cdf0e10cSrcweir SalInstance* pInst = NULL; 225cdf0e10cSrcweir 226cdf0e10cSrcweir static const char* pUsePlugin = getenv( "SAL_USE_VCLPLUGIN" ); 227cdf0e10cSrcweir 228cdf0e10cSrcweir if( !(pUsePlugin && *pUsePlugin) ) 229cdf0e10cSrcweir pInst = check_headless_plugin(); 230cdf0e10cSrcweir else 231cdf0e10cSrcweir pInst = tryInstance( OUString::createFromAscii( pUsePlugin ) ); 232cdf0e10cSrcweir 233cdf0e10cSrcweir if( ! pInst ) 234cdf0e10cSrcweir pInst = autodetect_plugin(); 235cdf0e10cSrcweir 236cdf0e10cSrcweir // fallback to gen 237cdf0e10cSrcweir if( ! pInst ) 238cdf0e10cSrcweir pInst = tryInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "gen" ) ) ); 239cdf0e10cSrcweir 240cdf0e10cSrcweir if( ! pInst ) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir std::fprintf( stderr, "no suitable windowing system found, exiting.\n" ); 243cdf0e10cSrcweir _exit( 1 ); 244cdf0e10cSrcweir } 245cdf0e10cSrcweir 246cdf0e10cSrcweir // acquire SolarMutex 247cdf0e10cSrcweir pInst->AcquireYieldMutex( 1 ); 248cdf0e10cSrcweir 249cdf0e10cSrcweir return pInst; 250cdf0e10cSrcweir } 251cdf0e10cSrcweir 252cdf0e10cSrcweir void DestroySalInstance( SalInstance *pInst ) 253cdf0e10cSrcweir { 254cdf0e10cSrcweir // release SolarMutex 255cdf0e10cSrcweir pInst->ReleaseYieldMutex(); 256cdf0e10cSrcweir 257cdf0e10cSrcweir delete pInst; 258cdf0e10cSrcweir if( pCloseModule ) 259cdf0e10cSrcweir osl_unloadModule( pCloseModule ); 260cdf0e10cSrcweir } 261cdf0e10cSrcweir 262cdf0e10cSrcweir void InitSalData() 263cdf0e10cSrcweir { 264cdf0e10cSrcweir } 265cdf0e10cSrcweir 266cdf0e10cSrcweir void DeInitSalData() 267cdf0e10cSrcweir { 268cdf0e10cSrcweir } 269cdf0e10cSrcweir 270cdf0e10cSrcweir void InitSalMain() 271cdf0e10cSrcweir { 272cdf0e10cSrcweir } 273cdf0e10cSrcweir 274cdf0e10cSrcweir void DeInitSalMain() 275cdf0e10cSrcweir { 276cdf0e10cSrcweir } 277cdf0e10cSrcweir 278cdf0e10cSrcweir void SalAbort( const XubString& rErrorText ) 279cdf0e10cSrcweir { 280cdf0e10cSrcweir if( !rErrorText.Len() ) 281cdf0e10cSrcweir std::fprintf( stderr, "Application Error" ); 282cdf0e10cSrcweir else 283cdf0e10cSrcweir std::fprintf( stderr, ByteString( rErrorText, gsl_getSystemTextEncoding() ).GetBuffer() ); 284cdf0e10cSrcweir abort(); 285cdf0e10cSrcweir } 286cdf0e10cSrcweir 287cdf0e10cSrcweir const OUString& SalGetDesktopEnvironment() 288cdf0e10cSrcweir { 289cdf0e10cSrcweir return get_desktop_environment(); 290cdf0e10cSrcweir } 291cdf0e10cSrcweir 292cdf0e10cSrcweir SalData::SalData() : 293cdf0e10cSrcweir m_pInstance(NULL), 294cdf0e10cSrcweir m_pPlugin(NULL), 295cdf0e10cSrcweir m_pPIManager(NULL) 296cdf0e10cSrcweir { 297cdf0e10cSrcweir } 298cdf0e10cSrcweir 299cdf0e10cSrcweir SalData::~SalData() 300cdf0e10cSrcweir { 301cdf0e10cSrcweir psp::PrinterInfoManager::release(); 302cdf0e10cSrcweir } 303