LCOV - code coverage report
Current view: top level - libreoffice/vcl/unx/generic/desktopdetect - desktopdetector.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 10 168 6.0 %
Date: 2012-12-27 Functions: 1 9 11.1 %
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             : 
      21             : #include <unx/svunx.h>
      22             : #include <unx/desktops.hxx>
      23             : #include <tools/prex.h>
      24             : #include <X11/Xatom.h>
      25             : #include <tools/postx.h>
      26             : 
      27             : #include "rtl/process.h"
      28             : #include "rtl/ustrbuf.hxx"
      29             : #include "osl/module.h"
      30             : #include "osl/thread.h"
      31             : #include "vcl/svapp.hxx"
      32             : 
      33             : #include "vclpluginapi.h"
      34             : 
      35             : #include <unistd.h>
      36             : #include <string.h>
      37             : 
      38             : using ::rtl::OUString;
      39             : using ::rtl::OString;
      40             : 
      41           0 : static bool is_gnome_desktop( Display* pDisplay )
      42             : {
      43           0 :     bool ret = false;
      44             : 
      45             :     // warning: these checks are coincidental, GNOME does not
      46             :     // explicitly advertise itself
      47             : 
      48           0 :     if ( NULL != getenv( "GNOME_DESKTOP_SESSION_ID" ) )
      49           0 :         ret = true;
      50             : 
      51           0 :     if( ! ret )
      52             :     {
      53           0 :         Atom nAtom1 = XInternAtom( pDisplay, "GNOME_SM_PROXY", True );
      54           0 :         Atom nAtom2 = XInternAtom( pDisplay, "NAUTILUS_DESKTOP_WINDOW_ID", True );
      55           0 :         if( nAtom1 || nAtom2 )
      56             :         {
      57           0 :             int nProperties = 0;
      58           0 :             Atom* pProperties = XListProperties( pDisplay, DefaultRootWindow( pDisplay ), &nProperties );
      59           0 :             if( pProperties && nProperties )
      60             :             {
      61           0 :                 for( int i = 0; i < nProperties; i++ )
      62           0 :                     if( pProperties[ i ] == nAtom1 ||
      63           0 :                         pProperties[ i ] == nAtom2 )
      64             :                 {
      65           0 :                     ret = true;
      66             :                 }
      67           0 :                 XFree( pProperties );
      68             :             }
      69             :         }
      70             :     }
      71             : 
      72           0 :     if( ! ret )
      73             :     {
      74           0 :         Atom nUTFAtom       = XInternAtom( pDisplay, "UTF8_STRING", True );
      75           0 :         Atom nNetWMNameAtom = XInternAtom( pDisplay, "_NET_WM_NAME", True );
      76           0 :         if( nUTFAtom && nNetWMNameAtom )
      77             :         {
      78             :             // another, more expensive check: search for a gnome-panel
      79           0 :             XLIB_Window aRoot, aParent, *pChildren = NULL;
      80           0 :             unsigned int nChildren = 0;
      81           0 :             XQueryTree( pDisplay, DefaultRootWindow( pDisplay ),
      82           0 :                         &aRoot, &aParent, &pChildren, &nChildren );
      83           0 :             if( pChildren && nChildren )
      84             :             {
      85           0 :                 for( unsigned int i = 0; i < nChildren && ! ret; i++ )
      86             :                 {
      87           0 :                     Atom nType = None;
      88           0 :                     int nFormat = 0;
      89           0 :                     unsigned long nItems = 0, nBytes = 0;
      90           0 :                     unsigned char* pProp = NULL;
      91             :                     XGetWindowProperty( pDisplay,
      92           0 :                                         pChildren[i],
      93             :                                         nNetWMNameAtom,
      94             :                                         0, 8,
      95             :                                         False,
      96             :                                         nUTFAtom,
      97             :                                         &nType,
      98             :                                         &nFormat,
      99             :                                         &nItems,
     100             :                                         &nBytes,
     101           0 :                                         &pProp );
     102           0 :                     if( pProp && nType == nUTFAtom )
     103             :                     {
     104           0 :                         OString aWMName( (sal_Char*)pProp );
     105           0 :                         if (
     106           0 :                             (aWMName.equalsIgnoreAsciiCase("gnome-shell")) ||
     107           0 :                             (aWMName.equalsIgnoreAsciiCase("gnome-panel"))
     108             :                            )
     109             :                         {
     110           0 :                             ret = true;
     111           0 :                         }
     112             :                     }
     113           0 :                     if( pProp )
     114           0 :                         XFree( pProp );
     115             :                 }
     116           0 :                 XFree( pChildren );
     117             :             }
     118             :         }
     119             :     }
     120             : 
     121           0 :     return ret;
     122             : }
     123             : 
     124             : static bool bWasXError = false;
     125             : 
     126           0 : static inline bool WasXError()
     127             : {
     128           0 :     bool bRet = bWasXError;
     129           0 :     bWasXError = false;
     130           0 :     return bRet;
     131             : }
     132             : 
     133             : extern "C"
     134             : {
     135           0 :     static int autodect_error_handler( Display*, XErrorEvent* )
     136             :     {
     137           0 :         bWasXError = true;
     138           0 :         return 0;
     139             :     }
     140             : 
     141             :     typedef int(* XErrorHandler)(Display*,XErrorEvent*);
     142             : }
     143             : 
     144           0 : static int TDEVersion( Display* pDisplay )
     145             : {
     146           0 :     int nRet = 0;
     147             : 
     148           0 :     Atom nFullSession = XInternAtom( pDisplay, "TDE_FULL_SESSION", True );
     149           0 :     Atom nTDEVersion  = XInternAtom( pDisplay, "TDE_SESSION_VERSION", True );
     150             : 
     151           0 :     if( nFullSession )
     152             :     {
     153           0 :         if( !nTDEVersion )
     154           0 :             return 14;
     155             : 
     156           0 :         Atom                aRealType   = None;
     157           0 :         int                 nFormat     = 8;
     158           0 :         unsigned long       nItems      = 0;
     159           0 :         unsigned long       nBytesLeft  = 0;
     160           0 :         unsigned char*  pProperty   = NULL;
     161             :         XGetWindowProperty( pDisplay,
     162           0 :                             DefaultRootWindow( pDisplay ),
     163             :                             nTDEVersion,
     164             :                             0, 1,
     165             :                             False,
     166             :                             AnyPropertyType,
     167             :                             &aRealType,
     168             :                             &nFormat,
     169             :                             &nItems,
     170             :                             &nBytesLeft,
     171           0 :                             &pProperty );
     172           0 :         if( !WasXError() && nItems != 0 && pProperty )
     173             :         {
     174           0 :             nRet = *reinterpret_cast< sal_Int32* >( pProperty );
     175             :         }
     176           0 :         if( pProperty )
     177             :         {
     178           0 :             XFree( pProperty );
     179           0 :             pProperty = NULL;
     180             :         }
     181             :     }
     182           0 :     return nRet;
     183             : }
     184             : 
     185           0 : static int KDEVersion( Display* pDisplay )
     186             : {
     187           0 :     int nRet = 0;
     188             : 
     189           0 :     Atom nFullSession = XInternAtom( pDisplay, "KDE_FULL_SESSION", True );
     190           0 :     Atom nKDEVersion  = XInternAtom( pDisplay, "KDE_SESSION_VERSION", True );
     191             : 
     192           0 :     if( nFullSession )
     193             :     {
     194           0 :         if( !nKDEVersion )
     195           0 :             return 3;
     196             : 
     197           0 :         Atom                aRealType   = None;
     198           0 :         int                 nFormat     = 8;
     199           0 :         unsigned long       nItems      = 0;
     200           0 :         unsigned long       nBytesLeft  = 0;
     201           0 :         unsigned char*  pProperty   = NULL;
     202             :         XGetWindowProperty( pDisplay,
     203           0 :                             DefaultRootWindow( pDisplay ),
     204             :                             nKDEVersion,
     205             :                             0, 1,
     206             :                             False,
     207             :                             AnyPropertyType,
     208             :                             &aRealType,
     209             :                             &nFormat,
     210             :                             &nItems,
     211             :                             &nBytesLeft,
     212           0 :                             &pProperty );
     213           0 :         if( !WasXError() && nItems != 0 && pProperty )
     214             :         {
     215           0 :             nRet = *reinterpret_cast< sal_Int32* >( pProperty );
     216             :         }
     217           0 :         if( pProperty )
     218             :         {
     219           0 :             XFree( pProperty );
     220           0 :             pProperty = NULL;
     221             :         }
     222             :     }
     223           0 :     return nRet;
     224             : }
     225             : 
     226           0 : static bool is_tde_desktop( Display* pDisplay )
     227             : {
     228           0 :     if ( NULL != getenv( "TDE_FULL_SESSION" ) )
     229             :     {
     230           0 :         return true; // TDE
     231             :     }
     232             : 
     233           0 :     if ( TDEVersion( pDisplay ) >= 14 )
     234           0 :         return true;
     235             : 
     236           0 :     return false;
     237             : }
     238             : 
     239           0 : static bool is_kde_desktop( Display* pDisplay )
     240             : {
     241           0 :     if ( NULL != getenv( "KDE_FULL_SESSION" ) )
     242             :     {
     243           0 :         const char *pVer = getenv( "KDE_SESSION_VERSION" );
     244           0 :         if ( !pVer || pVer[0] == '0' )
     245             :         {
     246           0 :             return true; // does not exist => KDE3
     247             :         }
     248             : 
     249           0 :         rtl::OUString aVer( RTL_CONSTASCII_USTRINGPARAM( "3" ) );
     250           0 :         if ( aVer.equalsIgnoreAsciiCaseAscii( pVer ) )
     251             :         {
     252           0 :             return true;
     253           0 :         }
     254             :     }
     255             : 
     256           0 :     if ( KDEVersion( pDisplay ) == 3 )
     257           0 :         return true;
     258             : 
     259           0 :     return false;
     260             : }
     261             : 
     262           0 : static bool is_kde4_desktop( Display* pDisplay )
     263             : {
     264           0 :     if ( NULL != getenv( "KDE_FULL_SESSION" ) )
     265             :     {
     266           0 :         rtl::OUString aVer( RTL_CONSTASCII_USTRINGPARAM( "4" ) );
     267             : 
     268           0 :         const char *pVer = getenv( "KDE_SESSION_VERSION" );
     269           0 :         if ( pVer && aVer.equalsIgnoreAsciiCaseAscii( pVer ) )
     270           0 :             return true;
     271             :     }
     272             : 
     273           0 :     if ( KDEVersion( pDisplay ) == 4 )
     274           0 :         return true;
     275             : 
     276           0 :     return false;
     277             : }
     278             : 
     279             : extern "C"
     280             : {
     281             : 
     282          11 : DESKTOP_DETECTOR_PUBLIC DesktopType get_desktop_environment()
     283             : {
     284          11 :     static const char *pOverride = getenv( "OOO_FORCE_DESKTOP" );
     285             : 
     286          11 :     if ( pOverride && *pOverride )
     287             :     {
     288           0 :         OString aOver( pOverride );
     289             : 
     290           0 :         if ( aOver.equalsIgnoreAsciiCase( "tde" ) )
     291           0 :             return DESKTOP_TDE;
     292           0 :         if ( aOver.equalsIgnoreAsciiCase( "kde4" ) )
     293           0 :             return DESKTOP_KDE4;
     294           0 :         if ( aOver.equalsIgnoreAsciiCase( "gnome" ) )
     295           0 :             return DESKTOP_GNOME;
     296           0 :         if ( aOver.equalsIgnoreAsciiCase( "kde" ) )
     297           0 :             return DESKTOP_KDE;
     298           0 :         if ( aOver.equalsIgnoreAsciiCase( "none" ) )
     299           0 :             return DESKTOP_UNKNOWN;
     300             :     }
     301             : 
     302             :     // get display to connect to
     303          11 :     const char* pDisplayStr = getenv( "DISPLAY" );
     304             : 
     305          11 :     const char* pUsePlugin = getenv( "SAL_USE_VCLPLUGIN" );
     306             : 
     307          22 :     if ((pUsePlugin && (strcmp(pUsePlugin, "svp") == 0))
     308          11 :         || Application::IsHeadlessModeRequested())
     309          11 :         pDisplayStr = NULL;
     310             :     else
     311             :     {
     312           0 :         int nParams = rtl_getAppCommandArgCount();
     313           0 :         OUString aParam;
     314           0 :         OString aBParm;
     315           0 :         for( int i = 0; i < nParams; i++ )
     316             :         {
     317           0 :             rtl_getAppCommandArg( i, &aParam.pData );
     318           0 :             if( i < nParams-1 && (aParam == "-display" || aParam == "--display" ) )
     319             :             {
     320           0 :                 osl_getCommandArg( i+1, &aParam.pData );
     321           0 :                 aBParm = OUStringToOString( aParam, osl_getThreadTextEncoding() );
     322           0 :                 pDisplayStr = aBParm.getStr();
     323           0 :                 break;
     324             :             }
     325           0 :         }
     326             :     }
     327             : 
     328             :     // no server at all
     329          11 :     if( ! pDisplayStr || !*pDisplayStr )
     330          11 :         return DESKTOP_NONE;
     331             : 
     332             :     /* #i92121# workaround deadlocks in the X11 implementation
     333             :     */
     334           0 :     static const char* pNoXInitThreads = getenv( "SAL_NO_XINITTHREADS" );
     335             :     /* #i90094#
     336             :        from now on we know that an X connection will be
     337             :        established, so protect X against itself
     338             :     */
     339           0 :     if( ! ( pNoXInitThreads && *pNoXInitThreads ) )
     340           0 :         XInitThreads();
     341             : 
     342           0 :     Display* pDisplay = XOpenDisplay( pDisplayStr );
     343           0 :     if( pDisplay == NULL )
     344           0 :         return DESKTOP_NONE;
     345             : 
     346             :     DesktopType ret;
     347             : 
     348           0 :     XErrorHandler pOldHdl = XSetErrorHandler( autodect_error_handler );
     349             : 
     350           0 :     if ( is_tde_desktop( pDisplay ) )
     351           0 :         ret = DESKTOP_TDE;
     352           0 :     else if ( is_kde4_desktop( pDisplay ) )
     353           0 :         ret = DESKTOP_KDE4;
     354           0 :     else if ( is_gnome_desktop( pDisplay ) )
     355           0 :         ret = DESKTOP_GNOME;
     356           0 :     else if ( is_kde_desktop( pDisplay ) )
     357           0 :         ret = DESKTOP_KDE;
     358             :     else
     359           0 :         ret = DESKTOP_UNKNOWN;
     360             : 
     361             :     // set the default handler again
     362           0 :     XSetErrorHandler( pOldHdl );
     363             : 
     364           0 :     XCloseDisplay( pDisplay );
     365             : 
     366           0 :     return ret;
     367             : }
     368             : 
     369             : }
     370             : 
     371             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10