LCOV - code coverage report
Current view: top level - vcl/unx/generic/plugadapt - salplug.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 75 103 72.8 %
Date: 2014-11-03 Functions: 12 15 80.0 %
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 "osl/module.h"
      21             : #include "osl/process.h"
      22             : 
      23             : #include "rtl/bootstrap.hxx"
      24             : 
      25             : #include "salinst.hxx"
      26             : #include "generic/gensys.h"
      27             : #include "generic/gendata.hxx"
      28             : #include "unx/desktops.hxx"
      29             : #include "vcl/printerinfomanager.hxx"
      30             : #include <config_vclplug.h>
      31             : 
      32             : #include <cstdio>
      33             : #include <unistd.h>
      34             : 
      35             : extern "C" {
      36             : typedef SalInstance*(*salFactoryProc)();
      37             : }
      38             : 
      39             : static oslModule pCloseModule = NULL;
      40             : 
      41         373 : static SalInstance* tryInstance( const OUString& rModuleBase, bool bForce = false )
      42             : {
      43         373 :     SalInstance* pInst = NULL;
      44             :     // Disable gtk3 plugin for now unless explicitly requested via
      45             :     // SAL_USE_VCLPLUGIN=gtk3 (would ideally depend on experimental mode, but
      46             :     // reading the experimental mode setting requires the UNO service manager
      47             :     // which has not yet been instantiated):
      48         373 :     if (!bForce && rModuleBase == "gtk3")
      49             :     {
      50           0 :         return NULL;
      51             :     }
      52             :     OUString aModule(
      53             : #ifdef SAL_DLLPREFIX
      54             :             SAL_DLLPREFIX
      55             : #endif
      56         373 :             "vclplug_" + rModuleBase + "lo" SAL_DLLEXTENSION );
      57             :     // vclplug_svp is in libmerged
      58         373 :     if (rModuleBase == "svp")
      59         373 :         aModule = VCLPLUG_SVP_DLL_NAME;
      60             : 
      61             :     oslModule aMod = osl_loadModuleRelative(
      62             :         reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData,
      63         373 :         SAL_LOADMODULE_DEFAULT );
      64         373 :     if( aMod )
      65             :     {
      66         373 :         salFactoryProc aProc = (salFactoryProc)osl_getAsciiFunctionSymbol( aMod, "create_SalInstance" );
      67         373 :         if( aProc )
      68             :         {
      69         373 :             pInst = aProc();
      70             :             SAL_INFO(
      71             :                 "vcl.plugadapt",
      72             :                 "sal plugin " << aModule << " produced instance " << pInst);
      73         373 :             if( pInst )
      74             :             {
      75         373 :                 pCloseModule = aMod;
      76             : 
      77             : #ifndef ANDROID
      78             :                 /*
      79             :                  * Recent GTK+ versions load their modules with RTLD_LOCAL, so we can
      80             :                  * not access the 'gnome_accessibility_module_shutdown' anymore.
      81             :                  * So make sure libgtk+ & co are still mapped into memory when
      82             :                  * atk-bridge's atexit handler gets called.
      83             :                  * #i109007# KDE3 seems to have the same problem.
      84             :                  * And same applies for KDE4.
      85             :                  */
      86         373 :                 if( rModuleBase == "gtk" || rModuleBase == "gtk3" || rModuleBase == "tde" || rModuleBase == "kde" || rModuleBase == "kde4" )
      87             :                 {
      88           0 :                     pCloseModule = NULL;
      89             :                 }
      90             : #endif
      91         373 :                 GetSalData()->m_pPlugin = aMod;
      92             :             }
      93             :             else
      94           0 :                 osl_unloadModule( aMod );
      95             :         }
      96             :         else
      97             :         {
      98             :             SAL_WARN(
      99             :                 "vcl.plugadapt",
     100             :                 "could not load symbol create_SalInstance from shared object "
     101             :                     << aModule);
     102           0 :             osl_unloadModule( aMod );
     103             :         }
     104             :     }
     105           0 :     else if (bForce)
     106             :     {
     107             :         SAL_WARN("vcl.plugadapt", "could not load shared object " << aModule);
     108             :     }
     109             :     else
     110             :     {
     111             :         SAL_INFO("vcl.plugadapt", "could not load shared object " << aModule);
     112             :     }
     113             : 
     114         373 :     return pInst;
     115             : }
     116             : 
     117             : #if !defined(ANDROID)
     118             : 
     119           8 : static DesktopType get_desktop_environment()
     120             : {
     121           8 :     OUString aModule(DESKTOP_DETECTOR_DLL_NAME);
     122             :     oslModule aMod = osl_loadModuleRelative(
     123             :         reinterpret_cast< oslGenericFunction >( &tryInstance ), aModule.pData,
     124           8 :         SAL_LOADMODULE_DEFAULT );
     125           8 :     DesktopType ret = DESKTOP_UNKNOWN;
     126           8 :     if( aMod )
     127             :     {
     128             :         DesktopType (*pSym)() = (DesktopType(*)())
     129           8 :             osl_getAsciiFunctionSymbol( aMod, "get_desktop_environment" );
     130           8 :         if( pSym )
     131           8 :             ret = pSym();
     132             :     }
     133           8 :     osl_unloadModule( aMod );
     134           8 :     return ret;
     135             : }
     136             : 
     137             : #else
     138             : 
     139             : #define get_desktop_environment() DESKTOP_NONE // For now...
     140             : 
     141             : #endif
     142             : 
     143           4 : static SalInstance* autodetect_plugin()
     144             : {
     145             :     static const char* const pTDEFallbackList[] =
     146             :     {
     147             :         "tde",
     148             : #if ENABLE_KDE4
     149             :         "kde4",
     150             : #endif
     151             : #if ENABLE_KDE
     152             :         "kde",
     153             : #endif
     154             :         "gtk3", "gtk", "gen", 0
     155             :     };
     156             : 
     157             :     static const char* const pKDEFallbackList[] =
     158             :     {
     159             : #if ENABLE_KDE4
     160             :         "kde4",
     161             : #endif
     162             : #if ENABLE_KDE
     163             :         "kde",
     164             : #endif
     165             :         "gtk3", "gtk", "gen", 0
     166             :     };
     167             : 
     168             :     static const char* const pStandardFallbackList[] =
     169             :     {
     170             :         "gtk3", "gtk", "gen", 0
     171             :     };
     172             : 
     173             :     static const char* const pHeadlessFallbackList[] =
     174             :     {
     175             :         "svp", 0
     176             :     };
     177             : 
     178           4 :     DesktopType desktop = get_desktop_environment();
     179           4 :     const char * const * pList = pStandardFallbackList;
     180           4 :     int nListEntry = 0;
     181             : 
     182             :     // no server at all: dummy plugin
     183           4 :     if ( desktop == DESKTOP_NONE )
     184           4 :         pList = pHeadlessFallbackList;
     185           0 :     else if ( desktop == DESKTOP_GNOME ||
     186           0 :               desktop == DESKTOP_UNITY ||
     187           0 :               desktop == DESKTOP_XFCE  ||
     188             :               desktop == DESKTOP_MATE )
     189           0 :         pList = pStandardFallbackList;
     190           0 :     else if( desktop == DESKTOP_TDE )
     191           0 :         pList = pTDEFallbackList;
     192           0 :     else if( desktop == DESKTOP_KDE )
     193             :     {
     194           0 :         pList = pKDEFallbackList;
     195           0 :         nListEntry = 1;
     196             :     }
     197           0 :     else if( desktop == DESKTOP_KDE4 )
     198           0 :         pList = pKDEFallbackList;
     199             : 
     200           4 :     SalInstance* pInst = NULL;
     201          12 :     while( pList[nListEntry] && pInst == NULL )
     202             :     {
     203           4 :         OUString aTry( OUString::createFromAscii( pList[nListEntry] ) );
     204           4 :         pInst = tryInstance( aTry );
     205             :         SAL_INFO_IF(
     206             :             pInst, "vcl.plugadapt",
     207             :             "plugin autodetection: " << pList[nListEntry]);
     208           4 :         nListEntry++;
     209           4 :     }
     210             : 
     211           4 :     return pInst;
     212             : }
     213             : 
     214         373 : SalInstance *CreateSalInstance()
     215             : {
     216         373 :     SalInstance *pInst = NULL;
     217             : 
     218         373 :     OUString aUsePlugin;
     219         373 :     if( Application::IsHeadlessModeRequested() )
     220         358 :         aUsePlugin = "svp";
     221             :     else
     222             :     {
     223          15 :         rtl::Bootstrap::get( "SAL_USE_VCLPLUGIN", aUsePlugin );
     224             :     }
     225             : 
     226         373 :     if( !aUsePlugin.isEmpty() )
     227         369 :         pInst = tryInstance( aUsePlugin, true );
     228             : 
     229         373 :     if( ! pInst )
     230           4 :         pInst = autodetect_plugin();
     231             : 
     232             :     // fallback, try everything
     233             :     static const char* const pPlugin[] = {
     234             :         "gtk3", "gtk", "kde4", "kde", "tde", "gen" };
     235             : 
     236         373 :     for ( int i = 0; !pInst && i != SAL_N_ELEMENTS(pPlugin); ++i )
     237           0 :         pInst = tryInstance( OUString::createFromAscii( pPlugin[ i ] ) );
     238             : 
     239         373 :     if( ! pInst )
     240             :     {
     241           0 :         std::fprintf( stderr, "no suitable windowing system found, exiting.\n" );
     242           0 :         _exit( 1 );
     243             :     }
     244             : 
     245             :     // acquire SolarMutex
     246         373 :     pInst->AcquireYieldMutex( 1 );
     247             : 
     248         373 :     return pInst;
     249             : }
     250             : 
     251         367 : void DestroySalInstance( SalInstance *pInst )
     252             : {
     253             :     // release SolarMutex
     254         367 :     pInst->ReleaseYieldMutex();
     255             : 
     256         367 :     delete pInst;
     257         367 :     if( pCloseModule )
     258         367 :         osl_unloadModule( pCloseModule );
     259         367 : }
     260             : 
     261         373 : void InitSalData()
     262             : {
     263         373 : }
     264             : 
     265         367 : void DeInitSalData()
     266             : {
     267         367 : }
     268             : 
     269         373 : void InitSalMain()
     270             : {
     271         373 : }
     272             : 
     273           0 : void SalAbort( const OUString& rErrorText, bool bDumpCore )
     274             : {
     275           0 :     if( rErrorText.isEmpty() )
     276           0 :         std::fprintf( stderr, "Application Error\n" );
     277             :     else
     278           0 :         std::fprintf( stderr, "%s\n", OUStringToOString(rErrorText, osl_getThreadTextEncoding()).getStr() );
     279           0 :     if( bDumpCore )
     280           0 :         abort();
     281             :     else
     282           0 :         _exit(1);
     283             : }
     284             : 
     285          12 : const OUString& SalGetDesktopEnvironment()
     286             : {
     287             :     // Order to match desktops.hxx' DesktopType
     288             :     static const char * const desktop_strings[] = {
     289             :         "none", "unknown", "GNOME", "UNITY",
     290             :         "XFCE", "MATE", "TDE",
     291             :         "KDE", "KDE4" };
     292          12 :     static OUString aRet;
     293          12 :     if( aRet.isEmpty())
     294             :     {
     295          12 :         aRet = OUString::createFromAscii(
     296          12 :             desktop_strings[get_desktop_environment()]);
     297             :     }
     298          12 :     return aRet;
     299             : }
     300             : 
     301         373 : SalData::SalData() :
     302             :     m_pInstance(NULL),
     303             :     m_pPlugin(NULL),
     304         373 :     m_pPIManager(NULL)
     305             : {
     306         373 : }
     307             : 
     308           0 : SalData::~SalData()
     309             : {
     310           0 :     psp::PrinterInfoManager::release();
     311        1233 : }
     312             : 
     313             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10