LCOV - code coverage report
Current view: top level - vcl/unx/generic/plugadapt - salplug.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 72 101 71.3 %
Date: 2014-04-11 Functions: 10 13 76.9 %
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 <config_libraries.h>
      21             : 
      22             : #include "osl/module.h"
      23             : #include "osl/process.h"
      24             : 
      25             : #include "rtl/bootstrap.hxx"
      26             : 
      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>
      33             : 
      34             : #include <cstdio>
      35             : #include <unistd.h>
      36             : 
      37             : extern "C" {
      38             : typedef SalInstance*(*salFactoryProc)( oslModule pModule);
      39             : }
      40             : 
      41             : static oslModule pCloseModule = NULL;
      42             : 
      43         165 : static SalInstance* tryInstance( const OUString& rModuleBase, bool bForce = false )
      44             : {
      45         165 :     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         165 :     if (!bForce && rModuleBase == "gtk3")
      51             :     {
      52           0 :         return NULL;
      53             :     }
      54             :     OUString aModule(
      55             : #ifdef SAL_DLLPREFIX
      56             :             SAL_DLLPREFIX
      57             : #endif
      58         165 :             "vclplug_" + rModuleBase + "lo" SAL_DLLEXTENSION );
      59             : 
      60             :     oslModule aMod = osl_loadModuleRelative(
      61             :         reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData,
      62         165 :         SAL_LOADMODULE_DEFAULT );
      63         165 :     if( aMod )
      64             :     {
      65         165 :         salFactoryProc aProc = (salFactoryProc)osl_getAsciiFunctionSymbol( aMod, "create_SalInstance" );
      66         165 :         if( aProc )
      67             :         {
      68         165 :             pInst = aProc( aMod );
      69             :             SAL_INFO(
      70             :                 "vcl.plugadapt",
      71             :                 "sal plugin " << aModule << " produced instance " << pInst);
      72         165 :             if( pInst )
      73             :             {
      74         165 :                 pCloseModule = aMod;
      75             : 
      76             : #ifndef ANDROID
      77             :                 /*
      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.
      84             :                  */
      85         165 :                 if( rModuleBase == "gtk" || rModuleBase == "gtk3" || rModuleBase == "tde" || rModuleBase == "kde" || rModuleBase == "kde4" )
      86             :                 {
      87           0 :                     pCloseModule = NULL;
      88             :                 }
      89             : #endif
      90         165 :                 GetSalData()->m_pPlugin = aMod;
      91             :             }
      92             :             else
      93           0 :                 osl_unloadModule( aMod );
      94             :         }
      95             :         else
      96             :         {
      97             :             SAL_WARN(
      98             :                 "vcl.plugadapt",
      99             :                 "could not load symbol create_SalInstance from shared object "
     100             :                     << aModule);
     101           0 :             osl_unloadModule( aMod );
     102             :         }
     103             :     }
     104           0 :     else if (bForce)
     105             :     {
     106             :         SAL_WARN("vcl.plugadapt", "could not load shared object " << aModule);
     107             :     }
     108             :     else
     109             :     {
     110             :         SAL_INFO("vcl.plugadapt", "could not load shared object " << aModule);
     111             :     }
     112             : 
     113         165 :     return pInst;
     114             : }
     115             : 
     116             : #if !defined(ANDROID)
     117             : 
     118         126 : static DesktopType get_desktop_environment()
     119             : {
     120         126 :     OUString aModule(LIBO_LIBRARY(desktop_detector));
     121             :     oslModule aMod = osl_loadModuleRelative(
     122             :         reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData,
     123         126 :         SAL_LOADMODULE_DEFAULT );
     124         126 :     DesktopType ret = DESKTOP_UNKNOWN;
     125         126 :     if( aMod )
     126             :     {
     127             :         DesktopType (*pSym)() = (DesktopType(*)())
     128         126 :             osl_getAsciiFunctionSymbol( aMod, "get_desktop_environment" );
     129         126 :         if( pSym )
     130         126 :             ret = pSym();
     131             :     }
     132         126 :     osl_unloadModule( aMod );
     133         126 :     return ret;
     134             : }
     135             : 
     136             : #else
     137             : 
     138             : #define get_desktop_environment() DESKTOP_NONE // For now...
     139             : 
     140             : #endif
     141             : 
     142           2 : static SalInstance* autodetect_plugin()
     143             : {
     144             :     static const char* const pTDEFallbackList[] =
     145             :     {
     146             :         "tde",
     147             : #if ENABLE_KDE4
     148             :         "kde4",
     149             : #endif
     150             : #if ENABLE_KDE
     151             :         "kde",
     152             : #endif
     153             :         "gtk3", "gtk", "gen", 0
     154             :     };
     155             : 
     156             :     static const char* const pKDEFallbackList[] =
     157             :     {
     158             : #if ENABLE_KDE4
     159             :         "kde4",
     160             : #endif
     161             : #if ENABLE_KDE
     162             :         "kde",
     163             : #endif
     164             :         "gtk3", "gtk", "gen", 0
     165             :     };
     166             : 
     167             :     static const char* const pStandardFallbackList[] =
     168             :     {
     169             :         "gtk3", "gtk", "gen", 0
     170             :     };
     171             : 
     172             :     static const char* const pHeadlessFallbackList[] =
     173             :     {
     174             :         "svp", 0
     175             :     };
     176             : 
     177           2 :     DesktopType desktop = get_desktop_environment();
     178           2 :     const char * const * pList = pStandardFallbackList;
     179           2 :     int nListEntry = 0;
     180             : 
     181             :     // no server at all: dummy plugin
     182           2 :     if ( desktop == DESKTOP_NONE )
     183           2 :         pList = pHeadlessFallbackList;
     184           0 :     else if ( desktop == DESKTOP_GNOME ||
     185           0 :               desktop == DESKTOP_UNITY ||
     186           0 :               desktop == DESKTOP_XFCE  ||
     187             :               desktop == DESKTOP_MATE )
     188           0 :         pList = pStandardFallbackList;
     189           0 :     else if( desktop == DESKTOP_TDE )
     190           0 :         pList = pTDEFallbackList;
     191           0 :     else if( desktop == DESKTOP_KDE )
     192             :     {
     193           0 :         pList = pKDEFallbackList;
     194           0 :         nListEntry = 1;
     195             :     }
     196           0 :     else if( desktop == DESKTOP_KDE4 )
     197           0 :         pList = pKDEFallbackList;
     198             : 
     199           2 :     SalInstance* pInst = NULL;
     200           6 :     while( pList[nListEntry] && pInst == NULL )
     201             :     {
     202           2 :         OUString aTry( OUString::createFromAscii( pList[nListEntry] ) );
     203           2 :         pInst = tryInstance( aTry );
     204             :         SAL_INFO_IF(
     205             :             pInst, "vcl.plugadapt",
     206             :             "plugin autodetection: " << pList[nListEntry]);
     207           2 :         nListEntry++;
     208           2 :     }
     209             : 
     210           2 :     return pInst;
     211             : }
     212             : 
     213         165 : SalInstance *CreateSalInstance()
     214             : {
     215         165 :     SalInstance *pInst = NULL;
     216             : 
     217         165 :     OUString aUsePlugin;
     218         165 :     if( Application::IsHeadlessModeRequested() )
     219         152 :         aUsePlugin = "svp";
     220             :     else
     221             :     {
     222          13 :         rtl::Bootstrap::get( "SAL_USE_VCLPLUGIN", aUsePlugin );
     223             :     }
     224             : 
     225         165 :     if( !aUsePlugin.isEmpty() )
     226         163 :         pInst = tryInstance( aUsePlugin, true );
     227             : 
     228         165 :     if( ! pInst )
     229           2 :         pInst = autodetect_plugin();
     230             : 
     231             :     // fallback, try everything
     232             :     static const char* const pPlugin[] = {
     233             :         "gtk3", "gtk", "kde4", "kde", "tde", "gen" };
     234             : 
     235         165 :     for ( int i = 0; !pInst && i != SAL_N_ELEMENTS(pPlugin); ++i )
     236           0 :         pInst = tryInstance( OUString::createFromAscii( pPlugin[ i ] ) );
     237             : 
     238         165 :     if( ! pInst )
     239             :     {
     240           0 :         std::fprintf( stderr, "no suitable windowing system found, exiting.\n" );
     241           0 :         _exit( 1 );
     242             :     }
     243             : 
     244             :     // acquire SolarMutex
     245         165 :     pInst->AcquireYieldMutex( 1 );
     246             : 
     247         165 :     return pInst;
     248             : }
     249             : 
     250          91 : void DestroySalInstance( SalInstance *pInst )
     251             : {
     252             :     // release SolarMutex
     253          91 :     pInst->ReleaseYieldMutex();
     254             : 
     255          91 :     delete pInst;
     256          91 :     if( pCloseModule )
     257          91 :         osl_unloadModule( pCloseModule );
     258          91 : }
     259             : 
     260         165 : void InitSalData()
     261             : {
     262         165 : }
     263             : 
     264          91 : void DeInitSalData()
     265             : {
     266          91 : }
     267             : 
     268         165 : void InitSalMain()
     269             : {
     270         165 : }
     271             : 
     272           0 : void SalAbort( const OUString& rErrorText, bool bDumpCore )
     273             : {
     274           0 :     if( rErrorText.isEmpty() )
     275           0 :         std::fprintf( stderr, "Application Error\n" );
     276             :     else
     277           0 :         std::fprintf( stderr, "%s\n", OUStringToOString(rErrorText, osl_getThreadTextEncoding()).getStr() );
     278           0 :     if( bDumpCore )
     279           0 :         abort();
     280             :     else
     281           0 :         _exit(1);
     282             : }
     283             : 
     284         337 : const OUString& SalGetDesktopEnvironment()
     285             : {
     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         337 :     static OUString aRet;
     292         337 :     if( aRet.isEmpty())
     293             :     {
     294         372 :         aRet = OUString::createFromAscii(
     295         372 :             desktop_strings[get_desktop_environment()]);
     296             :     }
     297         337 :     return aRet;
     298             : }
     299             : 
     300         165 : SalData::SalData() :
     301             :     m_pInstance(NULL),
     302             :     m_pPlugin(NULL),
     303         165 :     m_pPIManager(NULL)
     304             : {
     305         165 : }
     306             : 
     307           0 : SalData::~SalData()
     308             : {
     309           0 :     psp::PrinterInfoManager::release();
     310           0 : }
     311             : 
     312             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10