LCOV - code coverage report
Current view: top level - vcl/unx/gtk/gdi - salnativewidgets-gtk.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 2145 0.0 %
Date: 2014-04-14 Functions: 0 100 0.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 <config_version.h>
      21             : 
      22             : #include "vcl/svapp.hxx"
      23             : 
      24             : #include "unx/gtk/gtkframe.hxx"
      25             : #include "unx/gtk/gtkdata.hxx"
      26             : #include "unx/gtk/gtkinst.hxx"
      27             : #include "unx/gtk/gtkgdi.hxx"
      28             : 
      29             : #include "unx/saldata.hxx"
      30             : #include "unx/saldisp.hxx"
      31             : 
      32             : #include <cstdio>
      33             : #include <cmath>
      34             : #include <vector>
      35             : #include <algorithm>
      36             : #include <boost/unordered_map.hpp>
      37             : 
      38             : #include "vcl/vclenum.hxx"
      39             : #include <vcl/settings.hxx>
      40             : #include "fontmanager.hxx"
      41             : #include <vcl/decoview.hxx>
      42             : 
      43             : typedef struct _cairo_font_options cairo_font_options_t;
      44             : const char* const tabPrelitDataName="libreoffice-tab-is-prelit";
      45             : 
      46             : // initialize statics
      47             : bool GtkSalGraphics::bThemeChanged = true;
      48             : bool GtkSalGraphics::bNeedPixmapPaint = false;
      49             : 
      50           0 : GtkSalGraphics::GtkSalGraphics( GtkSalFrame *pFrame, GtkWidget *pWindow )
      51             :     : X11SalGraphics(),
      52             :       m_pWindow( pWindow ),
      53           0 :       m_aClipRegion(true)
      54             : {
      55             :     Init( pFrame, GDK_WINDOW_XID( widget_get_window( pWindow ) ),
      56             :           SalX11Screen( gdk_x11_screen_get_screen_number(
      57           0 :                                 gtk_widget_get_screen( pWindow ) ) ) );
      58           0 : }
      59             : 
      60           0 : GtkSalGraphics::~GtkSalGraphics()
      61             : {
      62           0 : }
      63             : 
      64             : /*************************************
      65             :  * Cached native widget objects
      66             :  *************************************/
      67             : class NWPixmapCacheList;
      68             : class NWPixmapCache;
      69             : struct NWFWidgetData
      70             : {
      71             :     GtkWidget *  gCacheWindow;
      72             :     GtkWidget *  gDumbContainer;
      73             : 
      74             :     GtkWidget *  gBtnWidget;
      75             :     GtkWidget *  gRadioWidget;
      76             :     GtkWidget *  gRadioWidgetSibling;
      77             :     GtkWidget *  gCheckWidget;
      78             :     GtkWidget *  gScrollHorizWidget;
      79             :     GtkWidget *  gScrollVertWidget;
      80             :     GtkWidget *  gArrowWidget;
      81             :     GtkWidget *  gDropdownWidget;
      82             :     GtkWidget *  gEditBoxWidget;
      83             :     GtkWidget *  gSpinButtonWidget;
      84             :     GtkWidget *  gNotebookWidget;
      85             :     GtkWidget *  gOptionMenuWidget;
      86             :     GtkWidget *  gComboWidget;
      87             :     GtkWidget *  gScrolledWindowWidget;
      88             :     GtkWidget *  gToolbarWidget;
      89             :     GtkWidget *  gToolbarButtonWidget;
      90             :     GtkWidget *  gHandleBoxWidget;
      91             :     GtkWidget *  gMenubarWidget;
      92             :     GtkWidget *  gMenuItemMenubarWidget;
      93             :     GtkWidget *  gMenuWidget;
      94             :     GtkWidget *  gMenuItemMenuWidget;
      95             :     GtkWidget *  gMenuItemCheckMenuWidget;
      96             :     GtkWidget *  gMenuItemRadioMenuWidget;
      97             :     GtkWidget *  gMenuItemSeparatorMenuWidget;
      98             :     GtkWidget *  gImageMenuItem;
      99             :     GtkWidget *  gTooltipPopup;
     100             :     GtkWidget *  gProgressBar;
     101             :     GtkWidget *  gTreeView;
     102             :     GtkWidget *  gHScale;
     103             :     GtkWidget *  gVScale;
     104             :     GtkWidget *  gSeparator;
     105             :     GtkWidget *  gDialog;
     106             :     GtkWidget *  gFrame;
     107             : 
     108             :     NWPixmapCacheList* gNWPixmapCacheList;
     109             :     NWPixmapCache* gCacheTabItems;
     110             :     NWPixmapCache* gCacheTabPages;
     111             : 
     112           0 :     NWFWidgetData() :
     113             :         gCacheWindow( NULL ),
     114             :         gDumbContainer( NULL ),
     115             :         gBtnWidget( NULL ),
     116             :         gRadioWidget( NULL ),
     117             :         gRadioWidgetSibling( NULL ),
     118             :         gCheckWidget( NULL ),
     119             :         gScrollHorizWidget( NULL ),
     120             :         gScrollVertWidget( NULL ),
     121             :         gArrowWidget( NULL ),
     122             :         gDropdownWidget( NULL ),
     123             :         gEditBoxWidget( NULL ),
     124             :         gSpinButtonWidget( NULL ),
     125             :         gNotebookWidget( NULL ),
     126             :         gOptionMenuWidget( NULL ),
     127             :         gComboWidget( NULL ),
     128             :         gScrolledWindowWidget( NULL ),
     129             :         gToolbarWidget( NULL ),
     130             :         gToolbarButtonWidget( NULL ),
     131             :         gHandleBoxWidget( NULL ),
     132             :         gMenubarWidget( NULL ),
     133             :         gMenuItemMenubarWidget( NULL ),
     134             :         gMenuWidget( NULL ),
     135             :         gMenuItemMenuWidget( NULL ),
     136             :         gMenuItemCheckMenuWidget( NULL ),
     137             :         gMenuItemRadioMenuWidget( NULL ),
     138             :         gMenuItemSeparatorMenuWidget( NULL ),
     139             :         gImageMenuItem( NULL ),
     140             :         gTooltipPopup( NULL ),
     141             :         gProgressBar( NULL ),
     142             :         gTreeView( NULL ),
     143             :         gHScale( NULL ),
     144             :         gVScale( NULL ),
     145             :         gSeparator( NULL ),
     146             :         gDialog( NULL ),
     147             :         gFrame( NULL ),
     148             :         gNWPixmapCacheList( NULL ),
     149             :         gCacheTabItems( NULL ),
     150           0 :         gCacheTabPages( NULL )
     151           0 :     {}
     152             : };
     153             : 
     154             : // Keep a hash table of Widgets->default flags so that we can
     155             : // easily and quickly reset each to a default state before using
     156             : // them
     157           0 : static boost::unordered_map<long, guint>    gWidgetDefaultFlags;
     158           0 : class WidgetDataVector : public std::vector<NWFWidgetData>
     159             : {
     160             : public:
     161           0 :     WidgetDataVector(size_t nElems = 0) : std::vector<NWFWidgetData>( nElems ) {}
     162           0 :     NWFWidgetData &operator [](size_t i) { return at(i); }
     163           0 :     NWFWidgetData &operator [](const SalX11Screen &s) { return at(s.getXScreen()); }
     164             : };
     165           0 : static WidgetDataVector gWidgetData;
     166             : 
     167             : static const GtkBorder aDefDefBorder        = { 1, 1, 1, 1 };
     168             : 
     169             : // Some GTK defaults
     170             : #define MIN_ARROW_SIZE                    11
     171             : #define BTN_CHILD_SPACING                1
     172             : #define MIN_SPIN_ARROW_WIDTH                6
     173             : 
     174             : static void NWEnsureGTKRadio             ( SalX11Screen nScreen );
     175             : static void NWEnsureGTKButton            ( SalX11Screen nScreen );
     176             : static void NWEnsureGTKCheck             ( SalX11Screen nScreen );
     177             : static void NWEnsureGTKScrollbars        ( SalX11Screen nScreen );
     178             : static void NWEnsureGTKArrow             ( SalX11Screen nScreen );
     179             : static void NWEnsureGTKEditBox           ( SalX11Screen nScreen );
     180             : static void NWEnsureGTKSpinButton        ( SalX11Screen nScreen );
     181             : static void NWEnsureGTKNotebook          ( SalX11Screen nScreen );
     182             : static void NWEnsureGTKOptionMenu        ( SalX11Screen nScreen );
     183             : static void NWEnsureGTKCombo             ( SalX11Screen nScreen );
     184             : static void NWEnsureGTKScrolledWindow    ( SalX11Screen nScreen );
     185             : static void NWEnsureGTKToolbar           ( SalX11Screen nScreen );
     186             : static void NWEnsureGTKMenubar           ( SalX11Screen nScreen );
     187             : static void NWEnsureGTKMenu              ( SalX11Screen nScreen );
     188             : static void NWEnsureGTKTooltip           ( SalX11Screen nScreen );
     189             : static void NWEnsureGTKDialog            ( SalX11Screen nScreen );
     190             : static void NWEnsureGTKFrame             ( SalX11Screen nScreen );
     191             : static void NWEnsureGTKProgressBar       ( SalX11Screen nScreen );
     192             : static void NWEnsureGTKTreeView          ( SalX11Screen nScreen );
     193             : static void NWEnsureGTKSlider            ( SalX11Screen nScreen );
     194             : 
     195             : static void NWConvertVCLStateToGTKState( ControlState nVCLState, GtkStateType* nGTKState, GtkShadowType* nGTKShadow );
     196             : static void NWAddWidgetToCacheWindow( GtkWidget* widget, SalX11Screen nScreen );
     197             : static void NWSetWidgetState( GtkWidget* widget, ControlState nState, GtkStateType nGtkState );
     198             : 
     199             : static void NWCalcArrowRect( const Rectangle& rButton, Rectangle& rArrow );
     200             : 
     201             : /*
     202             :  * Individual helper functions
     203             :  *
     204             :  */
     205             : 
     206             : static Rectangle NWGetButtonArea( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
     207             :                                 const ImplControlValue& aValue, const OUString& rCaption );
     208             : 
     209             : static Rectangle NWGetTabItemRect( SalX11Screen nScreen, Rectangle aAreaRect );
     210             : 
     211             : static Rectangle NWGetEditBoxPixmapRect( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
     212             :                             const ImplControlValue& aValue, const OUString& rCaption );
     213             : 
     214             : static void NWPaintOneEditBox( SalX11Screen nScreen, GdkDrawable * gdkDrawable, GdkRectangle *gdkRect,
     215             :                                ControlType nType, ControlPart nPart, Rectangle aEditBoxRect,
     216             :                                ControlState nState, const ImplControlValue& aValue,
     217             :                                const OUString& rCaption );
     218             : 
     219             : static Rectangle NWGetSpinButtonRect( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
     220             :                             const ImplControlValue& aValue, const OUString& rCaption );
     221             : 
     222             : static void NWPaintOneSpinButton( SalX11Screen nScreen, GdkPixmap * pixmap, ControlType nType, ControlPart nPart, Rectangle aAreaRect,
     223             :                             ControlState nState, const ImplControlValue& aValue,
     224             :                             const OUString& rCaption );
     225             : 
     226             : static Rectangle NWGetComboBoxButtonRect( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
     227             :                             const ImplControlValue& aValue, const OUString& rCaption );
     228             : 
     229             : static Rectangle NWGetListBoxButtonRect( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
     230             :                             const ImplControlValue& aValue, const OUString& rCaption );
     231             : 
     232             : static Rectangle NWGetListBoxIndicatorRect( SalX11Screen nScreen, ControlType nType, ControlPart nPart, Rectangle aAreaRect, ControlState nState,
     233             :                             const ImplControlValue& aValue, const OUString& rCaption );
     234             : 
     235             : static Rectangle NWGetToolbarRect( SalX11Screen nScreen,
     236             :                                    ControlType nType,
     237             :                                    ControlPart nPart,
     238             :                                    Rectangle aAreaRect,
     239             :                                    ControlState nState,
     240             :                                    const ImplControlValue& aValue,
     241             :                                    const OUString& rCaption );
     242             : 
     243             : static int getFrameWidth(GtkWidget* widget);
     244             : 
     245             : static Rectangle NWGetScrollButtonRect(    SalX11Screen nScreen, ControlPart nPart, Rectangle aAreaRect );
     246             : 
     247             : /*********************************************************
     248             :  * PixmapCache
     249             :  *********************************************************/
     250             : 
     251             : // as some native widget drawing operations are pretty slow
     252             : // with certain themes (eg tabpages)
     253             : // this cache can be used to cache the corresponding pixmap
     254             : // see NWPaintGTKTabItem
     255             : 
     256             : class NWPixmapCacheData
     257             : {
     258             : public:
     259             :     ControlType m_nType;
     260             :     ControlState m_nState;
     261             :     Rectangle   m_pixmapRect;
     262             :     GdkPixmap*  m_pixmap;
     263             : 
     264           0 :     NWPixmapCacheData() : m_nType(0), m_nState(0), m_pixmap(0) {}
     265           0 :     ~NWPixmapCacheData()
     266           0 :         { SetPixmap( NULL ); };
     267             :     void SetPixmap( GdkPixmap* pPixmap );
     268             : };
     269             : 
     270             : class NWPixmapCache
     271             : {
     272             :     int m_size;
     273             :     int m_idx;
     274             :     int m_screen;
     275             :     NWPixmapCacheData* pData;
     276             : public:
     277             :     NWPixmapCache( SalX11Screen nScreen );
     278             :     ~NWPixmapCache();
     279             : 
     280           0 :     void SetSize( int n)
     281           0 :         { delete [] pData; m_idx = 0; m_size = n; pData = new NWPixmapCacheData[m_size]; }
     282           0 :     int GetSize() const { return m_size; }
     283             : 
     284             :     bool Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap** pPixmap );
     285             :     void Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap* pPixmap );
     286             : 
     287             :     void ThemeChanged();
     288             : };
     289             : 
     290           0 : class NWPixmapCacheList
     291             : {
     292             : public:
     293             :     ::std::vector< NWPixmapCache* > mCaches;
     294             : 
     295             :     void AddCache( NWPixmapCache *pCache );
     296             :     void RemoveCache( NWPixmapCache *pCache );
     297             :     void ThemeChanged();
     298             : };
     299             : 
     300             : // --- implementation ---
     301             : 
     302           0 : void NWPixmapCacheData::SetPixmap( GdkPixmap* pPixmap )
     303             : {
     304           0 :     if( m_pixmap )
     305           0 :         g_object_unref( m_pixmap );
     306             : 
     307           0 :     m_pixmap = pPixmap;
     308             : 
     309           0 :     if( m_pixmap )
     310           0 :         g_object_ref( m_pixmap );
     311           0 : }
     312             : 
     313           0 : NWPixmapCache::NWPixmapCache( SalX11Screen nScreen )
     314             : {
     315           0 :     m_idx = 0;
     316           0 :     m_size = 0;
     317           0 :     m_screen = nScreen.getXScreen();
     318           0 :     pData = NULL;
     319           0 :     if( gWidgetData[m_screen].gNWPixmapCacheList )
     320           0 :         gWidgetData[m_screen].gNWPixmapCacheList->AddCache(this);
     321           0 : }
     322           0 : NWPixmapCache::~NWPixmapCache()
     323             : {
     324           0 :     if( gWidgetData[m_screen].gNWPixmapCacheList )
     325           0 :         gWidgetData[m_screen].gNWPixmapCacheList->RemoveCache(this);
     326           0 :     delete[] pData;
     327           0 : }
     328           0 : void NWPixmapCache::ThemeChanged()
     329             : {
     330             :     // throw away cached pixmaps
     331             :     int i;
     332           0 :     for(i=0; i<m_size; i++)
     333           0 :         pData[i].SetPixmap( NULL );
     334           0 : }
     335             : 
     336           0 : bool  NWPixmapCache::Find( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap** pPixmap )
     337             : {
     338           0 :     aState &= ~CTRL_CACHING_ALLOWED; // mask clipping flag
     339             :     int i;
     340           0 :     for(i=0; i<m_size; i++)
     341             :     {
     342           0 :         if( pData[i].m_nType == aType &&
     343           0 :             pData[i].m_nState == aState &&
     344           0 :             pData[i].m_pixmapRect.GetWidth() == r_pixmapRect.GetWidth() &&
     345           0 :             pData[i].m_pixmapRect.GetHeight() == r_pixmapRect.GetHeight() &&
     346           0 :             pData[i].m_pixmap != NULL )
     347             :         {
     348           0 :             *pPixmap = pData[i].m_pixmap;
     349           0 :             return true;
     350             :         }
     351             :     }
     352           0 :     return false;
     353             : }
     354             : 
     355           0 : void NWPixmapCache::Fill( ControlType aType, ControlState aState, const Rectangle& r_pixmapRect, GdkPixmap* pPixmap )
     356             : {
     357           0 :     if( !(aState & CTRL_CACHING_ALLOWED) )
     358           0 :         return;
     359             : 
     360           0 :     aState &= ~CTRL_CACHING_ALLOWED; // mask clipping flag
     361           0 :     m_idx = (m_idx+1) % m_size; // just wrap
     362           0 :     pData[m_idx].m_nType = aType;
     363           0 :     pData[m_idx].m_nState = aState;
     364           0 :     pData[m_idx].m_pixmapRect = r_pixmapRect;
     365           0 :     pData[m_idx].SetPixmap( pPixmap );
     366             : }
     367             : 
     368           0 : void NWPixmapCacheList::AddCache( NWPixmapCache* pCache )
     369             : {
     370           0 :     mCaches.push_back( pCache );
     371           0 : }
     372           0 : void NWPixmapCacheList::RemoveCache( NWPixmapCache* pCache )
     373             : {
     374           0 :     ::std::vector< NWPixmapCache* >::iterator p;
     375           0 :     p = ::std::find( mCaches.begin(), mCaches.end(), pCache );
     376           0 :     if( p != mCaches.end() )
     377           0 :         mCaches.erase( p );
     378           0 : }
     379           0 : void NWPixmapCacheList::ThemeChanged( )
     380             : {
     381           0 :     ::std::vector< NWPixmapCache* >::iterator p = mCaches.begin();
     382           0 :     while( p != mCaches.end() )
     383             :     {
     384           0 :         (*p)->ThemeChanged();
     385           0 :         ++p;
     386             :     }
     387           0 : }
     388             : 
     389             : /*********************************************************
     390             :  * Make border manipulation easier
     391             :  *********************************************************/
     392           0 : inline void NW_gtk_border_set_from_border( GtkBorder& aDst, const GtkBorder * pSrc )
     393             : {
     394           0 :     aDst.left        = pSrc->left;
     395           0 :     aDst.top        = pSrc->top;
     396           0 :     aDst.right    = pSrc->right;
     397           0 :     aDst.bottom    = pSrc->bottom;
     398           0 : }
     399             : 
     400             : /*********************************************************
     401             :  * Initialize GTK and local stuff
     402             :  *********************************************************/
     403           0 : void GtkData::initNWF( void )
     404             : {
     405           0 :     ImplSVData* pSVData = ImplGetSVData();
     406             : 
     407             :     // draw no border for popup menus (NWF draws its own)
     408           0 :     pSVData->maNWFData.mbFlatMenu = true;
     409             : 
     410             :     // draw separate buttons for toolbox dropdown items
     411           0 :     pSVData->maNWFData.mbToolboxDropDownSeparate = true;
     412             : 
     413             :     // draw toolbars in separate lines
     414           0 :     pSVData->maNWFData.mbDockingAreaSeparateTB = true;
     415             : 
     416             :     // open first menu on F10
     417           0 :     pSVData->maNWFData.mbOpenMenuOnF10 = true;
     418             : 
     419             :     // omit GetNativeControl while painting (see brdwin.cxx)
     420           0 :     pSVData->maNWFData.mbCanDrawWidgetAnySize = true;
     421             : 
     422           0 :     pSVData->maNWFData.mbDDListBoxNoTextArea = true;
     423             : 
     424           0 :     int nScreens = GetGtkSalData()->GetGtkDisplay()->GetXScreenCount();
     425           0 :     gWidgetData = WidgetDataVector( nScreens );
     426           0 :     for( int i = 0; i < nScreens; i++ )
     427           0 :         gWidgetData[i].gNWPixmapCacheList = new NWPixmapCacheList;
     428             : 
     429             :     // small extra border around menu items
     430           0 :     NWEnsureGTKMenu( SalX11Screen( 0 ) );
     431           0 :     gint horizontal_padding = 1;
     432           0 :     gint vertical_padding = 1;
     433           0 :     gtk_widget_style_get( gWidgetData[0].gMenuWidget,
     434             :             "horizontal-padding", &horizontal_padding,
     435           0 :             (char *)NULL);
     436           0 :     gtk_widget_style_get( gWidgetData[0].gMenuWidget,
     437             :             "vertical-padding", &vertical_padding,
     438           0 :             (char *)NULL);
     439           0 :     gint xthickness = gWidgetData[0].gMenuWidget->style->xthickness;
     440           0 :     gint ythickness = gWidgetData[0].gMenuWidget->style->ythickness;
     441           0 :     pSVData->maNWFData.mnMenuFormatBorderX = xthickness + horizontal_padding;
     442           0 :     pSVData->maNWFData.mnMenuFormatBorderY = ythickness + vertical_padding;
     443             : 
     444           0 :     if( SalGetDesktopEnvironment() == "KDE" )
     445             :     {
     446             :         // #i97196# ensure a widget exists and the style engine was loaded
     447           0 :         NWEnsureGTKButton( SalX11Screen( 0 ) );
     448           0 :         if( g_type_from_name( "QtEngineStyle" ) )
     449             :         {
     450             :             // KDE 3.3 invented a bug in the qt<->gtk theme engine
     451             :             // that makes direct rendering impossible: they totally
     452             :             // ignore the clip rectangle passed to the paint methods
     453           0 :             GtkSalGraphics::bNeedPixmapPaint = true;
     454             :         }
     455             :     }
     456           0 :     static const char* pEnv = getenv( "SAL_GTK_USE_PIXMAPPAINT" );
     457           0 :     if( pEnv && *pEnv )
     458           0 :         GtkSalGraphics::bNeedPixmapPaint = true;
     459             : 
     460             :     #if OSL_DEBUG_LEVEL > 1
     461             :     std::fprintf( stderr, "GtkPlugin: using %s NWF\n",
     462             :              GtkSalGraphics::bNeedPixmapPaint ? "offscreen" : "direct" );
     463             :     #endif
     464           0 : }
     465             : 
     466             : /*********************************************************
     467             :  * Release GTK and local stuff
     468             :  *********************************************************/
     469           0 : void GtkData::deInitNWF( void )
     470             : {
     471           0 :     for( unsigned int i = 0; i < gWidgetData.size(); i++ )
     472             :     {
     473             :         // free up global widgets
     474             :         // gtk_widget_destroy will in turn destroy the child hierarchy
     475             :         // so only destroy disjunct hierachies
     476           0 :         if( gWidgetData[i].gCacheWindow )
     477           0 :             gtk_widget_destroy( gWidgetData[i].gCacheWindow );
     478           0 :         if( gWidgetData[i].gMenuWidget )
     479           0 :             gtk_widget_destroy( gWidgetData[i].gMenuWidget );
     480           0 :         if( gWidgetData[i].gTooltipPopup )
     481           0 :             gtk_widget_destroy( gWidgetData[i].gTooltipPopup );
     482           0 :         if( gWidgetData[i].gDialog )
     483           0 :             gtk_widget_destroy( gWidgetData[i].gDialog );
     484           0 :         delete gWidgetData[i].gCacheTabPages;
     485           0 :         gWidgetData[i].gCacheTabPages = NULL;
     486           0 :         delete gWidgetData[i].gCacheTabItems;
     487           0 :         gWidgetData[i].gCacheTabItems = NULL;
     488           0 :         delete gWidgetData[i].gNWPixmapCacheList;
     489           0 :         gWidgetData[i].gNWPixmapCacheList = NULL;
     490             :     }
     491           0 : }
     492             : 
     493             : /**********************************************************
     494             :  * track clip region
     495             :  **********************************************************/
     496           0 : void GtkSalGraphics::ResetClipRegion()
     497             : {
     498           0 :     m_aClipRegion.SetNull();
     499           0 :     X11SalGraphics::ResetClipRegion();
     500           0 : }
     501             : 
     502           0 : bool GtkSalGraphics::setClipRegion( const Region& i_rClip )
     503             : {
     504           0 :     m_aClipRegion = i_rClip;
     505           0 :     bool bRet = X11SalGraphics::setClipRegion( m_aClipRegion );
     506           0 :     if( m_aClipRegion.IsEmpty() )
     507           0 :         m_aClipRegion.SetNull();
     508           0 :     return bRet;
     509             : }
     510             : 
     511           0 : void GtkSalGraphics::copyBits( const SalTwoRect& rPosAry,
     512             :                                SalGraphics* pSrcGraphics )
     513             : {
     514           0 :     GtkSalFrame* pFrame = GetGtkFrame();
     515           0 :     XLIB_Window aWin = None;
     516           0 :     if( pFrame && m_pWindow )
     517             :     {
     518             :         /* #i64117# some themes set the background pixmap VERY frequently */
     519           0 :         GdkWindow* pWin = GTK_WIDGET(m_pWindow)->window;
     520           0 :         if( pWin )
     521             :         {
     522           0 :             aWin = GDK_WINDOW_XWINDOW(pWin);
     523           0 :             if( aWin != None )
     524           0 :                 XSetWindowBackgroundPixmap( pFrame->getDisplay()->GetDisplay(),
     525             :                                             aWin,
     526           0 :                                             None );
     527             :         }
     528             :     }
     529           0 :     X11SalGraphics::copyBits( rPosAry, pSrcGraphics );
     530           0 :     if( pFrame && pFrame->getBackgroundPixmap() != None )
     531           0 :         XSetWindowBackgroundPixmap( pFrame->getDisplay()->GetDisplay(),
     532             :                                     aWin,
     533           0 :                                     pFrame->getBackgroundPixmap() );
     534           0 : }
     535             : 
     536             : /*
     537             :  * IsNativeControlSupported()
     538             :  *
     539             :  *  Returns true if the platform supports native
     540             :  *  drawing of the control defined by nPart
     541             :  */
     542           0 : bool GtkSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart )
     543             : {
     544           0 :     switch(nType)
     545             :     {
     546             :         case CTRL_PUSHBUTTON:
     547             :         case CTRL_RADIOBUTTON:
     548             :         case CTRL_CHECKBOX:
     549             :         case CTRL_TOOLTIP:
     550             :         case CTRL_PROGRESS:
     551             :         case CTRL_LISTNODE:
     552             :         case CTRL_LISTNET:
     553           0 :             if(nPart==PART_ENTIRE_CONTROL)
     554           0 :                 return true;
     555           0 :             break;
     556             : 
     557             :         case CTRL_SCROLLBAR:
     558           0 :             if(nPart==PART_DRAW_BACKGROUND_HORZ || nPart==PART_DRAW_BACKGROUND_VERT ||
     559           0 :                nPart==PART_ENTIRE_CONTROL       || nPart==HAS_THREE_BUTTONS)
     560           0 :                 return true;
     561           0 :             break;
     562             : 
     563             :         case CTRL_EDITBOX:
     564             :         case CTRL_MULTILINE_EDITBOX:
     565             :         case CTRL_COMBOBOX:
     566           0 :             if(nPart==PART_ENTIRE_CONTROL || nPart==HAS_BACKGROUND_TEXTURE)
     567           0 :                 return true;
     568           0 :             break;
     569             : 
     570             :         case CTRL_SPINBOX:
     571           0 :             if(nPart==PART_ENTIRE_CONTROL || nPart==PART_ALL_BUTTONS || nPart==HAS_BACKGROUND_TEXTURE)
     572           0 :                 return true;
     573           0 :             break;
     574             : 
     575             :         case CTRL_SPINBUTTONS:
     576           0 :             if(nPart==PART_ENTIRE_CONTROL || nPart==PART_ALL_BUTTONS)
     577           0 :                 return true;
     578           0 :             break;
     579             : 
     580             :         case CTRL_FRAME:
     581             :         case CTRL_WINDOW_BACKGROUND:
     582           0 :             return true;
     583             : 
     584             :         case CTRL_TAB_ITEM:
     585             :         case CTRL_TAB_PANE:
     586             :         case CTRL_TAB_BODY:
     587           0 :             if(nPart==PART_ENTIRE_CONTROL || nPart==PART_TABS_DRAW_RTL)
     588           0 :                 return true;
     589           0 :             break;
     590             : 
     591             :         case CTRL_LISTBOX:
     592           0 :             if(nPart==PART_ENTIRE_CONTROL || nPart==PART_WINDOW || nPart==HAS_BACKGROUND_TEXTURE)
     593           0 :                 return true;
     594           0 :             break;
     595             : 
     596             :         case CTRL_TOOLBAR:
     597           0 :             if( nPart==PART_ENTIRE_CONTROL
     598           0 :                 ||  nPart==PART_DRAW_BACKGROUND_HORZ
     599           0 :                 ||  nPart==PART_DRAW_BACKGROUND_VERT
     600           0 :                 ||  nPart==PART_THUMB_HORZ
     601           0 :                 ||  nPart==PART_THUMB_VERT
     602           0 :                 ||  nPart==PART_BUTTON
     603           0 :                 ||  nPart==PART_SEPARATOR_HORZ
     604           0 :                 ||  nPart==PART_SEPARATOR_VERT
     605             :                 )
     606           0 :                 return true;
     607           0 :             break;
     608             : 
     609             :         case CTRL_MENUBAR:
     610           0 :             if(nPart==PART_ENTIRE_CONTROL || nPart==PART_MENU_ITEM)
     611           0 :                 return true;
     612           0 :             break;
     613             : 
     614             :         case CTRL_MENU_POPUP:
     615           0 :             if (nPart==PART_ENTIRE_CONTROL
     616           0 :                 ||  nPart==PART_MENU_ITEM
     617           0 :                 ||  nPart==PART_MENU_ITEM_CHECK_MARK
     618           0 :                 ||  nPart==PART_MENU_ITEM_RADIO_MARK
     619           0 :                 ||  nPart==PART_MENU_SEPARATOR
     620           0 :                 ||  nPart==PART_MENU_SUBMENU_ARROW
     621             :             )
     622           0 :                 return true;
     623           0 :             break;
     624             : 
     625             :         case CTRL_SLIDER:
     626           0 :             if(nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA)
     627           0 :                 return true;
     628           0 :             break;
     629             : 
     630             :         case CTRL_FIXEDLINE:
     631           0 :             if(nPart == PART_SEPARATOR_VERT || nPart == PART_SEPARATOR_HORZ)
     632           0 :                 return true;
     633           0 :             break;
     634             : 
     635             :         case CTRL_LISTHEADER:
     636           0 :             if(nPart == PART_BUTTON || nPart == PART_ARROW)
     637           0 :                 return true;
     638           0 :             break;
     639             :     }
     640             : 
     641           0 :     return false;
     642             : }
     643             : 
     644             : /*
     645             :  * HitTestNativeControl()
     646             :  *
     647             :  *  bIsInside is set to true if aPos is contained within the
     648             :  *  given part of the control, whose bounding region is
     649             :  *  given by rControlRegion (in VCL frame coordinates).
     650             :  *
     651             :  *  returns whether bIsInside was really set.
     652             :  */
     653           0 : bool GtkSalGraphics::hitTestNativeControl( ControlType        nType,
     654             :                                 ControlPart        nPart,
     655             :                                 const Rectangle&        rControlRegion,
     656             :                                 const Point&        aPos,
     657             :                                 bool&            rIsInside )
     658             : {
     659           0 :     if ( ( nType == CTRL_SCROLLBAR ) &&
     660           0 :          ( ( nPart == PART_BUTTON_UP ) ||
     661           0 :            ( nPart == PART_BUTTON_DOWN ) ||
     662           0 :            ( nPart == PART_BUTTON_LEFT ) ||
     663             :            ( nPart == PART_BUTTON_RIGHT ) ) )
     664             :     {
     665           0 :         NWEnsureGTKScrollbars( m_nXScreen );
     666             : 
     667             :         // Grab some button style attributes
     668             :         gboolean has_forward;
     669             :         gboolean has_forward2;
     670             :         gboolean has_backward;
     671             :         gboolean has_backward2;
     672             : 
     673           0 :         gtk_widget_style_get( gWidgetData[m_nXScreen].gScrollHorizWidget,
     674             :                               "has-forward-stepper", &has_forward,
     675             :                               "has-secondary-forward-stepper", &has_forward2,
     676             :                               "has-backward-stepper", &has_backward,
     677             :                               "has-secondary-backward-stepper", &has_backward2,
     678           0 :                               (char *)NULL );
     679           0 :         Rectangle aForward;
     680           0 :         Rectangle aBackward;
     681             : 
     682           0 :         rIsInside = false;
     683             : 
     684           0 :         ControlPart nCounterPart = 0;
     685           0 :         if ( nPart == PART_BUTTON_UP )
     686           0 :             nCounterPart = PART_BUTTON_DOWN;
     687           0 :         else if ( nPart == PART_BUTTON_DOWN )
     688           0 :             nCounterPart = PART_BUTTON_UP;
     689           0 :         else if ( nPart == PART_BUTTON_LEFT )
     690           0 :             nCounterPart = PART_BUTTON_RIGHT;
     691           0 :         else if ( nPart == PART_BUTTON_RIGHT )
     692           0 :             nCounterPart = PART_BUTTON_LEFT;
     693             : 
     694           0 :         aBackward = NWGetScrollButtonRect( m_nXScreen, nPart, rControlRegion );
     695           0 :         aForward = NWGetScrollButtonRect( m_nXScreen, nCounterPart, rControlRegion );
     696             : 
     697           0 :         if ( has_backward && has_forward2 )
     698             :         {
     699           0 :             Size aSize( aBackward.GetSize() );
     700           0 :             if ( ( nPart == PART_BUTTON_UP ) || ( nPart == PART_BUTTON_DOWN ) )
     701           0 :                 aSize.setHeight( aBackward.GetHeight() / 2 );
     702             :             else
     703           0 :                 aSize.setWidth( aBackward.GetWidth() / 2 );
     704           0 :             aBackward.SetSize( aSize );
     705             : 
     706           0 :             if ( nPart == PART_BUTTON_DOWN )
     707           0 :                 aBackward.Move( 0, aBackward.GetHeight() / 2 );
     708           0 :             else if ( nPart == PART_BUTTON_RIGHT )
     709           0 :                 aBackward.Move( aBackward.GetWidth() / 2, 0 );
     710             :         }
     711             : 
     712           0 :         if ( has_backward2 && has_forward )
     713             :         {
     714           0 :             Size aSize( aForward.GetSize() );
     715           0 :             if ( ( nPart == PART_BUTTON_UP ) || ( nPart == PART_BUTTON_DOWN ) )
     716           0 :                 aSize.setHeight( aForward.GetHeight() / 2 );
     717             :             else
     718           0 :                 aSize.setWidth( aForward.GetWidth() / 2 );
     719           0 :             aForward.SetSize( aSize );
     720             : 
     721           0 :             if ( nPart == PART_BUTTON_DOWN )
     722           0 :                 aForward.Move( 0, aForward.GetHeight() / 2 );
     723           0 :             else if ( nPart == PART_BUTTON_RIGHT )
     724           0 :                 aForward.Move( aForward.GetWidth() / 2, 0 );
     725             :         }
     726             : 
     727           0 :         if ( ( nPart == PART_BUTTON_UP ) || ( nPart == PART_BUTTON_LEFT ) )
     728             :         {
     729           0 :             if ( has_backward )
     730           0 :                 rIsInside |= aBackward.IsInside( aPos );
     731           0 :             if ( has_backward2 )
     732           0 :                 rIsInside |= aForward.IsInside( aPos );
     733             :         }
     734             :         else
     735             :         {
     736           0 :             if ( has_forward )
     737           0 :                 rIsInside |= aBackward.IsInside( aPos );
     738           0 :             if ( has_forward2 )
     739           0 :                 rIsInside |= aForward.IsInside( aPos );
     740             :         }
     741           0 :         return true;
     742             :     }
     743             : 
     744           0 :     if( IsNativeControlSupported(nType, nPart) )
     745             :     {
     746           0 :         rIsInside = rControlRegion.IsInside( aPos );
     747           0 :         return true;
     748             :     }
     749             :     else
     750             :     {
     751           0 :         return false;
     752             :     }
     753             : }
     754             : 
     755             : /*
     756             :  * DrawNativeControl()
     757             :  *
     758             :  *  Draws the requested control described by nPart/nState.
     759             :  *
     760             :  *  rControlRegion:    The bounding region of the complete control in VCL frame coordinates.
     761             :  *  aValue:          An optional value (tristate/numerical/string)
     762             :  *  rCaption:      A caption or title string (like button text etc)
     763             :  */
     764           0 : bool GtkSalGraphics::drawNativeControl(    ControlType nType,
     765             :                             ControlPart nPart,
     766             :                             const Rectangle& rControlRegion,
     767             :                             ControlState nState,
     768             :                             const ImplControlValue& aValue,
     769             :                             const OUString& rCaption )
     770             : {
     771             :     // get a GC with current clipping region set
     772           0 :     GetFontGC();
     773             : 
     774             :     // theme changed ?
     775           0 :     if( GtkSalGraphics::bThemeChanged )
     776             :     {
     777             :         // invalidate caches
     778           0 :         for( unsigned int i = 0; i < gWidgetData.size(); i++ )
     779           0 :             if( gWidgetData[i].gNWPixmapCacheList )
     780           0 :                 gWidgetData[i].gNWPixmapCacheList->ThemeChanged();
     781           0 :         GtkSalGraphics::bThemeChanged = false;
     782             :     }
     783             : 
     784           0 :     Rectangle aCtrlRect( rControlRegion );
     785           0 :     Region aClipRegion( m_aClipRegion );
     786           0 :     if( aClipRegion.IsNull() )
     787           0 :         aClipRegion = aCtrlRect;
     788             : 
     789           0 :     clipList aClip;
     790           0 :     GdkDrawable* gdkDrawable = GDK_DRAWABLE( GetGdkWindow() );
     791           0 :     GdkPixmap* pixmap = NULL;
     792           0 :     Rectangle aPixmapRect;
     793           0 :     if( ( bNeedPixmapPaint )
     794           0 :         && nType != CTRL_SCROLLBAR
     795           0 :         && nType != CTRL_SPINBOX
     796           0 :         && nType != CTRL_TAB_ITEM
     797           0 :         && nType != CTRL_TAB_PANE
     798           0 :         && nType != CTRL_PROGRESS
     799           0 :         && ! (nType == CTRL_TOOLBAR && (nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT) )
     800             :         )
     801             :     {
     802             :         // make pixmap a little larger since some themes draw decoration
     803             :         // outside the rectangle, see e.g. checkbox
     804           0 :         aPixmapRect = Rectangle( Point( aCtrlRect.Left()-1, aCtrlRect.Top()-1 ),
     805           0 :                                  Size( aCtrlRect.GetWidth()+2, aCtrlRect.GetHeight()+2) );
     806           0 :         pixmap = NWGetPixmapFromScreen( aPixmapRect );
     807           0 :         if( ! pixmap )
     808           0 :             return false;
     809           0 :         gdkDrawable = GDK_DRAWABLE( pixmap );
     810           0 :         aCtrlRect = Rectangle( Point(1,1), aCtrlRect.GetSize() );
     811           0 :         aClip.push_back( aCtrlRect );
     812             :     }
     813             :     else
     814             :     {
     815           0 :         RectangleVector aRectangles;
     816           0 :         aClipRegion.GetRegionRectangles(aRectangles);
     817             : 
     818           0 :         for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     819             :         {
     820           0 :             Rectangle aPaintRect = aCtrlRect.GetIntersection(*aRectIter);
     821           0 :             if( aPaintRect.IsEmpty() )
     822           0 :                 continue;
     823           0 :             aClip.push_back( aPaintRect );
     824           0 :         }
     825             :     }
     826             : 
     827             :     assert(gdkDrawable); //rhbz#1050162
     828           0 :     if (gdkDrawable == 0)
     829           0 :         return false;
     830             : 
     831           0 :     bool            returnVal = false;
     832           0 :     if ( (nType==CTRL_PUSHBUTTON) && (nPart==PART_ENTIRE_CONTROL) )
     833             :     {
     834           0 :         returnVal = NWPaintGTKButton( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     835             :     }
     836           0 :     else if ( (nType==CTRL_RADIOBUTTON) && (nPart==PART_ENTIRE_CONTROL) )
     837             :     {
     838           0 :         returnVal = NWPaintGTKRadio( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     839             :     }
     840           0 :     else if ( (nType==CTRL_CHECKBOX) && (nPart==PART_ENTIRE_CONTROL) )
     841             :     {
     842           0 :         returnVal = NWPaintGTKCheck( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     843             :     }
     844           0 :     else if ( (nType==CTRL_SCROLLBAR) && ((nPart==PART_DRAW_BACKGROUND_HORZ) || (nPart==PART_DRAW_BACKGROUND_VERT)) )
     845             :     {
     846           0 :         returnVal = NWPaintGTKScrollbar( nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     847             :     }
     848           0 :     else if ( ((nType==CTRL_EDITBOX) && ((nPart==PART_ENTIRE_CONTROL) || (nPart==HAS_BACKGROUND_TEXTURE)) )
     849           0 :         || ((nType==CTRL_SPINBOX) && (nPart==HAS_BACKGROUND_TEXTURE))
     850           0 :     || ((nType==CTRL_COMBOBOX) && (nPart==HAS_BACKGROUND_TEXTURE))
     851           0 :     || ((nType==CTRL_LISTBOX) && (nPart==HAS_BACKGROUND_TEXTURE)) )
     852             :     {
     853           0 :         returnVal = NWPaintGTKEditBox( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     854             :     }
     855           0 :     else if ( ((nType==CTRL_MULTILINE_EDITBOX) && ((nPart==PART_ENTIRE_CONTROL) || (nPart==HAS_BACKGROUND_TEXTURE)) ) )
     856             :     {
     857           0 :         returnVal = NWPaintGTKEditBox( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     858             :     }
     859           0 :     else if ( ((nType==CTRL_SPINBOX) || (nType==CTRL_SPINBUTTONS))
     860           0 :         && ((nPart==PART_ENTIRE_CONTROL) || (nPart==PART_ALL_BUTTONS)) )
     861             :     {
     862           0 :         returnVal = NWPaintGTKSpinBox( nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     863             :     }
     864           0 :     else if ( (nType == CTRL_COMBOBOX) &&
     865             :         ( (nPart==PART_ENTIRE_CONTROL)
     866           0 :         ||(nPart==PART_BUTTON_DOWN)
     867             :         ) )
     868             :     {
     869           0 :         returnVal = NWPaintGTKComboBox( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     870             :     }
     871           0 :     else if ( (nType==CTRL_TAB_ITEM) || (nType==CTRL_TAB_PANE) || (nType==CTRL_TAB_BODY) )
     872             :     {
     873           0 :         if ( nType == CTRL_TAB_BODY )
     874           0 :             returnVal = true;
     875             :         else
     876           0 :             returnVal = NWPaintGTKTabItem( nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption);
     877             :     }
     878           0 :     else if ( (nType==CTRL_LISTBOX) && ((nPart==PART_ENTIRE_CONTROL) || (nPart==PART_WINDOW)) )
     879             :     {
     880           0 :         returnVal = NWPaintGTKListBox( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     881             :     }
     882           0 :     else if ( nType== CTRL_TOOLBAR )
     883             :     {
     884           0 :         returnVal = NWPaintGTKToolbar( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     885             :     }
     886           0 :     else if ( nType== CTRL_MENUBAR )
     887             :     {
     888           0 :         returnVal = NWPaintGTKMenubar( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     889             :     }
     890           0 :     else if(    (nType == CTRL_MENU_POPUP)
     891           0 :         && (  (nPart == PART_ENTIRE_CONTROL)
     892           0 :     || (nPart == PART_MENU_ITEM)
     893           0 :     || (nPart == PART_MENU_ITEM_CHECK_MARK)
     894           0 :     || (nPart == PART_MENU_ITEM_RADIO_MARK)
     895           0 :     || (nPart == PART_MENU_SEPARATOR)
     896           0 :     || (nPart == PART_MENU_SUBMENU_ARROW)
     897             :     )
     898             :     )
     899             :     {
     900           0 :         returnVal = NWPaintGTKPopupMenu( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     901             :     }
     902           0 :     else if( (nType == CTRL_TOOLTIP) && (nPart == PART_ENTIRE_CONTROL) )
     903             :     {
     904           0 :         returnVal = NWPaintGTKTooltip( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     905             :     }
     906           0 :     else if( (nType == CTRL_PROGRESS) && (nPart == PART_ENTIRE_CONTROL) )
     907             :     {
     908           0 :         returnVal = NWPaintGTKProgress( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     909             :     }
     910           0 :     else if( (nType == CTRL_LISTNODE) && (nPart == PART_ENTIRE_CONTROL) )
     911             :     {
     912           0 :         returnVal = NWPaintGTKListNode( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     913             :     }
     914           0 :     else if( (nType == CTRL_LISTNET) && (nPart == PART_ENTIRE_CONTROL) )
     915             :     {
     916             :         // don't actually draw anything; gtk treeviews do not draw lines
     917           0 :         returnVal = TRUE;
     918             :     }
     919           0 :     else if( nType == CTRL_SLIDER )
     920             :     {
     921           0 :         returnVal = NWPaintGTKSlider( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     922             :     }
     923           0 :     else if( nType == CTRL_WINDOW_BACKGROUND )
     924             :     {
     925           0 :         returnVal = NWPaintGTKWindowBackground( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     926             :     }
     927           0 :     else if( nType == CTRL_FIXEDLINE )
     928             :     {
     929           0 :         returnVal = NWPaintGTKFixedLine( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     930             :     }
     931           0 :     else if(nType==CTRL_FRAME)
     932             :     {
     933           0 :         returnVal = NWPaintGTKFrame( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption);
     934             :     }
     935           0 :     else if(nType==CTRL_LISTHEADER)
     936             :     {
     937           0 :         if(nPart == PART_BUTTON)
     938           0 :             returnVal = NWPaintGTKListHeader( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     939           0 :         else if(nPart == PART_ARROW)
     940           0 :             returnVal = NWPaintGTKArrow( gdkDrawable, nType, nPart, aCtrlRect, aClip, nState, aValue, rCaption );
     941             :     }
     942             : 
     943           0 :     if( pixmap )
     944             :     {
     945           0 :         returnVal = NWRenderPixmapToScreen( pixmap, aPixmapRect ) && returnVal;
     946           0 :         g_object_unref( pixmap );
     947             :     }
     948             : 
     949           0 :     return( returnVal );
     950             : }
     951             : 
     952             : /*
     953             :  * GetNativeControlRegion()
     954             :  *
     955             :  *  If the return value is true, rNativeBoundingRegion
     956             :  *  contains the true bounding region covered by the control
     957             :  *  including any adornment, while rNativeContentRegion contains the area
     958             :  *  within the control that can be safely drawn into without drawing over
     959             :  *  the borders of the control.
     960             :  *
     961             :  *  rControlRegion:    The bounding region of the control in VCL frame coordinates.
     962             :  *  aValue:        An optional value (tristate/numerical/string)
     963             :  *  rCaption:        A caption or title string (like button text etc)
     964             :  */
     965           0 : bool GtkSalGraphics::getNativeControlRegion(  ControlType nType,
     966             :                                 ControlPart nPart,
     967             :                                 const Rectangle& rControlRegion,
     968             :                                 ControlState nState,
     969             :                                 const ImplControlValue& aValue,
     970             :                                 const OUString& rCaption,
     971             :                                 Rectangle &rNativeBoundingRegion,
     972             :                                 Rectangle &rNativeContentRegion )
     973             : {
     974           0 :     bool returnVal = false;
     975             : 
     976           0 :     if ( (nType==CTRL_PUSHBUTTON) && (nPart==PART_ENTIRE_CONTROL)
     977           0 :         && (rControlRegion.GetWidth() > 16)
     978           0 :     && (rControlRegion.GetHeight() > 16) )
     979             :     {
     980             :         rNativeBoundingRegion = NWGetButtonArea( m_nXScreen, nType, nPart, rControlRegion,
     981           0 :         nState, aValue, rCaption );
     982           0 :         rNativeContentRegion = rControlRegion;
     983             : 
     984           0 :         returnVal = true;
     985             :     }
     986           0 :     if (nType == CTRL_TAB_ITEM && nPart == PART_ENTIRE_CONTROL)
     987             :     {
     988           0 :         rNativeBoundingRegion = NWGetTabItemRect(m_nXScreen, rControlRegion);
     989           0 :         rNativeContentRegion = rNativeBoundingRegion;
     990           0 :         returnVal = true;
     991             :     }
     992           0 :     if ( (nType==CTRL_COMBOBOX) && ((nPart==PART_BUTTON_DOWN) || (nPart==PART_SUB_EDIT)) )
     993             :     {
     994             :         rNativeBoundingRegion = NWGetComboBoxButtonRect( m_nXScreen, nType, nPart, rControlRegion, nState,
     995           0 :         aValue, rCaption );
     996           0 :         rNativeContentRegion = rNativeBoundingRegion;
     997             : 
     998           0 :         returnVal = true;
     999             :     }
    1000           0 :     if ( (nType==CTRL_SPINBOX) && ((nPart==PART_BUTTON_UP) || (nPart==PART_BUTTON_DOWN) || (nPart==PART_SUB_EDIT)) )
    1001             :     {
    1002             : 
    1003             :         rNativeBoundingRegion = NWGetSpinButtonRect( m_nXScreen, nType, nPart, rControlRegion, nState,
    1004           0 :         aValue, rCaption );
    1005           0 :         rNativeContentRegion = rNativeBoundingRegion;
    1006             : 
    1007           0 :         returnVal = true;
    1008             :     }
    1009           0 :     if ( (nType==CTRL_LISTBOX) && ((nPart==PART_BUTTON_DOWN) || (nPart==PART_SUB_EDIT)) )
    1010             :     {
    1011             :         rNativeBoundingRegion = NWGetListBoxButtonRect( m_nXScreen, nType, nPart, rControlRegion, nState,
    1012           0 :         aValue, rCaption );
    1013           0 :         rNativeContentRegion = rNativeBoundingRegion;
    1014             : 
    1015           0 :         returnVal = true;
    1016             :     }
    1017           0 :     if ( (nType==CTRL_TOOLBAR) &&
    1018           0 :         ((nPart==PART_DRAW_BACKGROUND_HORZ)    ||
    1019           0 :         (nPart==PART_DRAW_BACKGROUND_VERT)    ||
    1020           0 :         (nPart==PART_THUMB_HORZ)            ||
    1021           0 :         (nPart==PART_THUMB_VERT)            ||
    1022             :         (nPart==PART_BUTTON)
    1023             :         ))
    1024             :     {
    1025           0 :         rNativeBoundingRegion = NWGetToolbarRect( m_nXScreen, nType, nPart, rControlRegion, nState, aValue, rCaption );
    1026           0 :         rNativeContentRegion = rNativeBoundingRegion;
    1027           0 :         returnVal = true;
    1028             :     }
    1029           0 :     if ( (nType==CTRL_SCROLLBAR) && ((nPart==PART_BUTTON_LEFT) || (nPart==PART_BUTTON_RIGHT) ||
    1030           0 :         (nPart==PART_BUTTON_UP) || (nPart==PART_BUTTON_DOWN)  ) )
    1031             :     {
    1032           0 :         rNativeBoundingRegion = NWGetScrollButtonRect( m_nXScreen, nPart, rControlRegion );
    1033           0 :         rNativeContentRegion = rNativeBoundingRegion;
    1034             : 
    1035             :         //See fdo#33523, possibly makes sense to do this test for all return values
    1036           0 :         if (!rNativeContentRegion.GetWidth())
    1037           0 :             rNativeContentRegion.Right() = rNativeContentRegion.Left() + 1;
    1038           0 :         if (!rNativeContentRegion.GetHeight())
    1039           0 :             rNativeContentRegion.Bottom() = rNativeContentRegion.Top() + 1;
    1040           0 :         returnVal = true;
    1041             :     }
    1042           0 :     if( (nType == CTRL_MENUBAR) && (nPart == PART_ENTIRE_CONTROL) )
    1043             :     {
    1044           0 :         NWEnsureGTKMenubar( m_nXScreen );
    1045             :         GtkRequisition aReq;
    1046           0 :         gtk_widget_size_request( gWidgetData[m_nXScreen].gMenubarWidget, &aReq );
    1047           0 :         Rectangle aMenuBarRect = rControlRegion;
    1048             :         aMenuBarRect = Rectangle( aMenuBarRect.TopLeft(),
    1049           0 :                                   Size( aMenuBarRect.GetWidth(), aReq.height+1 ) );
    1050           0 :         rNativeBoundingRegion = aMenuBarRect;
    1051           0 :         rNativeContentRegion = rNativeBoundingRegion;
    1052           0 :         returnVal = true;
    1053             :     }
    1054           0 :     if( nType == CTRL_MENU_POPUP )
    1055             :     {
    1056           0 :         if( (nPart == PART_MENU_ITEM_CHECK_MARK) ||
    1057             :             (nPart == PART_MENU_ITEM_RADIO_MARK) )
    1058             :         {
    1059           0 :             NWEnsureGTKMenu( m_nXScreen );
    1060             : 
    1061           0 :             gint indicator_size = 0;
    1062             :             GtkWidget* pWidget = (nPart == PART_MENU_ITEM_CHECK_MARK) ?
    1063           0 :                 gWidgetData[m_nXScreen].gMenuItemCheckMenuWidget : gWidgetData[m_nXScreen].gMenuItemRadioMenuWidget;
    1064             :             gtk_widget_style_get( pWidget,
    1065             :                                   "indicator_size", &indicator_size,
    1066           0 :                                   (char *)NULL );
    1067           0 :             rNativeBoundingRegion = rControlRegion;
    1068             :             Rectangle aIndicatorRect( Point( 0,
    1069           0 :                                              (rControlRegion.GetHeight()-indicator_size)/2),
    1070           0 :                                       Size( indicator_size, indicator_size ) );
    1071           0 :             rNativeContentRegion = aIndicatorRect;
    1072           0 :             returnVal = true;
    1073             :         }
    1074           0 :         else if( nPart == PART_MENU_SUBMENU_ARROW )
    1075             :         {
    1076           0 :             GtkWidget* widget = gWidgetData[m_nXScreen].gMenuItemMenuWidget;
    1077             :             GtkWidget* child;
    1078             :             PangoContext *context;
    1079             :             PangoFontMetrics *metrics;
    1080             :             gint arrow_size;
    1081             :             gint arrow_extent;
    1082             :             guint horizontal_padding;
    1083           0 :             gfloat arrow_scaling = 0.4; // Default for early GTK versions
    1084             : 
    1085             :             gtk_widget_style_get( widget,
    1086             :                                   "horizontal-padding", &horizontal_padding,
    1087           0 :                                   NULL );
    1088             : 
    1089             :             // Use arrow-scaling property if available (2.15+), avoid warning otherwise
    1090           0 :             if ( gtk_widget_class_find_style_property( GTK_WIDGET_GET_CLASS( widget ),
    1091           0 :                                                        "arrow-scaling" ) )
    1092             :             {
    1093             :                 gtk_widget_style_get( widget,
    1094             :                                       "arrow-scaling", &arrow_scaling,
    1095           0 :                                       NULL );
    1096             :             }
    1097             : 
    1098           0 :             child = GTK_BIN( widget )->child;
    1099             : 
    1100           0 :             context = gtk_widget_get_pango_context( child );
    1101             :             metrics = pango_context_get_metrics( context,
    1102             :                                                  child->style->font_desc,
    1103           0 :                                                  pango_context_get_language( context ) );
    1104             : 
    1105           0 :             arrow_size = ( PANGO_PIXELS( pango_font_metrics_get_ascent( metrics ) +
    1106           0 :                                          pango_font_metrics_get_descent( metrics ) ));
    1107             : 
    1108           0 :             pango_font_metrics_unref( metrics );
    1109             : 
    1110           0 :             arrow_extent = static_cast<gint>(arrow_size * arrow_scaling);
    1111             : 
    1112             :             rNativeContentRegion = Rectangle( Point( 0, 0 ),
    1113           0 :                                               Size( arrow_extent, arrow_extent ));
    1114             :             rNativeBoundingRegion = Rectangle( Point( 0, 0 ),
    1115           0 :                                                Size( arrow_extent + horizontal_padding, arrow_extent ));
    1116           0 :             returnVal = true;
    1117             :         }
    1118             :     }
    1119           0 :     if( (nType == CTRL_RADIOBUTTON || nType == CTRL_CHECKBOX) )
    1120             :     {
    1121           0 :         NWEnsureGTKRadio( m_nXScreen );
    1122           0 :         NWEnsureGTKCheck( m_nXScreen );
    1123           0 :         GtkWidget* widget = (nType == CTRL_RADIOBUTTON) ? gWidgetData[m_nXScreen].gRadioWidget : gWidgetData[m_nXScreen].gCheckWidget;
    1124             :         gint indicator_size, indicator_spacing, focusPad, focusWidth;
    1125             :         gtk_widget_style_get( widget,
    1126             :                               "indicator_size", &indicator_size,
    1127             :                               "indicator_spacing", &indicator_spacing,
    1128             :                               "focus-line-width", &focusWidth,
    1129             :                               "focus-padding", &focusPad,
    1130           0 :                               (char *)NULL);
    1131           0 :         indicator_size += 2*indicator_spacing + 2*(focusWidth + focusWidth);
    1132           0 :         rNativeBoundingRegion = rControlRegion;
    1133             :         Rectangle aIndicatorRect( Point( 0,
    1134           0 :                                          (rControlRegion.GetHeight()-indicator_size)/2),
    1135           0 :                                   Size( indicator_size, indicator_size ) );
    1136           0 :         rNativeContentRegion = aIndicatorRect;
    1137           0 :         returnVal = true;
    1138             :     }
    1139           0 :     if( (nType == CTRL_EDITBOX || nType == CTRL_SPINBOX || nType == CTRL_COMBOBOX) && nPart == PART_ENTIRE_CONTROL )
    1140             :     {
    1141           0 :         NWEnsureGTKEditBox( m_nXScreen );
    1142           0 :         GtkWidget* widget = gWidgetData[m_nXScreen].gEditBoxWidget;
    1143             :         GtkRequisition aReq;
    1144           0 :         gtk_widget_size_request( widget, &aReq );
    1145           0 :         Rectangle aEditRect = rControlRegion;
    1146           0 :         long nHeight = (aEditRect.GetHeight() > aReq.height) ? aEditRect.GetHeight() : aReq.height;
    1147             :         aEditRect = Rectangle( aEditRect.TopLeft(),
    1148           0 :                                Size( aEditRect.GetWidth(), nHeight ) );
    1149           0 :         rNativeBoundingRegion = aEditRect;
    1150           0 :         rNativeContentRegion = rNativeBoundingRegion;
    1151           0 :         returnVal = true;
    1152             :     }
    1153           0 :     if( (nType == CTRL_SLIDER) && (nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT) )
    1154             :     {
    1155           0 :         NWEnsureGTKSlider( m_nXScreen );
    1156           0 :         GtkWidget* widget = (nPart == PART_THUMB_HORZ) ? gWidgetData[m_nXScreen].gHScale : gWidgetData[m_nXScreen].gVScale;
    1157           0 :         gint slider_length = 10;
    1158           0 :         gint slider_width = 10;
    1159             :         gtk_widget_style_get( widget,
    1160             :                               "slider-width", &slider_width,
    1161             :                               "slider-length", &slider_length,
    1162           0 :                               (char *)NULL);
    1163           0 :         Rectangle aRect( rControlRegion );
    1164           0 :         if( nPart == PART_THUMB_HORZ )
    1165             :         {
    1166           0 :             aRect.Right() = aRect.Left() + slider_length - 1;
    1167           0 :             aRect.Bottom() = aRect.Top() + slider_width - 1;
    1168             :         }
    1169             :         else
    1170             :         {
    1171           0 :             aRect.Bottom() = aRect.Top() + slider_length - 1;
    1172           0 :             aRect.Right() = aRect.Left() + slider_width - 1;
    1173             :         }
    1174           0 :         rNativeBoundingRegion = rNativeContentRegion = aRect;
    1175           0 :         returnVal = true;
    1176             :     }
    1177           0 :     if( nType == CTRL_FRAME && nPart == PART_BORDER )
    1178             :     {
    1179           0 :         int frameWidth = getFrameWidth(gWidgetData[m_nXScreen].gFrame);
    1180           0 :         rNativeBoundingRegion = rControlRegion;
    1181           0 :         sal_uInt16 nStyle = aValue.getNumericVal();
    1182           0 :         int x1=rControlRegion.Left();
    1183           0 :         int y1=rControlRegion.Top();
    1184           0 :         int x2=rControlRegion.Right();
    1185           0 :         int y2=rControlRegion.Bottom();
    1186             : 
    1187           0 :         if( nStyle & FRAME_DRAW_NODRAW )
    1188             :         {
    1189           0 :             rNativeContentRegion = Rectangle(x1+frameWidth,
    1190           0 :                                              y1+frameWidth,
    1191           0 :                                              x2-frameWidth,
    1192           0 :                                              y2-frameWidth);
    1193             :         }
    1194             :         else
    1195           0 :             rNativeContentRegion = rControlRegion;
    1196           0 :         returnVal=true;
    1197             :     }
    1198             : 
    1199           0 :     return( returnVal );
    1200             : }
    1201             : 
    1202             : /************************************************************************
    1203             :  * Individual control drawing functions
    1204             :  ************************************************************************/
    1205           0 : bool GtkSalGraphics::NWPaintGTKArrow(
    1206             :             GdkDrawable* gdkDrawable,
    1207             :             ControlType, ControlPart,
    1208             :             const Rectangle& rControlRectangle,
    1209             :             const clipList& rClipList,
    1210             :             ControlState nState, const ImplControlValue& aValue,
    1211             :             const OUString& )
    1212             : {
    1213           0 :     GtkArrowType arrowType(aValue.getNumericVal()&1?GTK_ARROW_DOWN:GTK_ARROW_UP);
    1214           0 :     GtkStateType stateType(nState&CTRL_STATE_PRESSED?GTK_STATE_ACTIVE:GTK_STATE_NORMAL);
    1215             : 
    1216             :     GdkRectangle clipRect;
    1217           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    1218             :     {
    1219           0 :         clipRect.x = it->Left();
    1220           0 :         clipRect.y = it->Top();
    1221           0 :         clipRect.width = it->GetWidth();
    1222           0 :         clipRect.height = it->GetHeight();
    1223             : 
    1224             :         gtk_paint_arrow(m_pWindow->style,gdkDrawable,stateType,GTK_SHADOW_NONE,&clipRect,
    1225             :                 m_pWindow,"arrow",arrowType,true,
    1226           0 :                 rControlRectangle.Left(),
    1227           0 :                 rControlRectangle.Top(),
    1228           0 :                 rControlRectangle.GetWidth(),
    1229           0 :                 rControlRectangle.GetHeight());
    1230             :     }
    1231           0 :     return true;
    1232             : }
    1233             : 
    1234           0 : bool GtkSalGraphics::NWPaintGTKListHeader(
    1235             :             GdkDrawable* gdkDrawable,
    1236             :             ControlType, ControlPart,
    1237             :             const Rectangle& rControlRectangle,
    1238             :             const clipList& rClipList,
    1239             :             ControlState nState, const ImplControlValue&,
    1240             :             const OUString& )
    1241             : {
    1242             :     GtkStateType    stateType;
    1243             :     GtkShadowType    shadowType;
    1244           0 :     NWEnsureGTKTreeView( m_nXScreen );
    1245           0 :     GtkWidget* &treeview(gWidgetData[m_nXScreen].gTreeView);
    1246           0 :     GtkTreeViewColumn* column=gtk_tree_view_get_column(GTK_TREE_VIEW(treeview),0);
    1247           0 :     GtkWidget* button=gtk_tree_view_column_get_widget(column);
    1248           0 :     while(button && !GTK_IS_BUTTON(button))
    1249           0 :         button=gtk_widget_get_parent(button);
    1250           0 :     if(!button)
    1251             :         // Shouldn't ever happen
    1252           0 :         return false;
    1253           0 :     gtk_widget_realize(button);
    1254           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    1255           0 :     NWSetWidgetState( button, nState, stateType );
    1256             : 
    1257             :     GdkRectangle clipRect;
    1258           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    1259             :     {
    1260           0 :         clipRect.x = it->Left();
    1261           0 :         clipRect.y = it->Top();
    1262           0 :         clipRect.width = it->GetWidth();
    1263           0 :         clipRect.height = it->GetHeight();
    1264             : 
    1265             :         gtk_paint_box(button->style,gdkDrawable,stateType,shadowType,&clipRect,
    1266             :                 button,"button",
    1267           0 :                 rControlRectangle.Left()-1,
    1268           0 :                 rControlRectangle.Top(),
    1269           0 :                 rControlRectangle.GetWidth()+1,
    1270           0 :                 rControlRectangle.GetHeight());
    1271             :     }
    1272           0 :     return true;
    1273             : }
    1274             : 
    1275           0 : bool GtkSalGraphics::NWPaintGTKFixedLine(
    1276             :             GdkDrawable* gdkDrawable,
    1277             :             ControlType, ControlPart nPart,
    1278             :             const Rectangle& rControlRectangle,
    1279             :             const clipList&,
    1280             :             ControlState, const ImplControlValue&,
    1281             :             const OUString& )
    1282             : {
    1283           0 :     if(nPart == PART_SEPARATOR_HORZ)
    1284           0 :         gtk_paint_hline(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,NULL,m_pWindow,"hseparator",rControlRectangle.Left(),rControlRectangle.Right(),rControlRectangle.Top());
    1285             :     else
    1286           0 :         gtk_paint_vline(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,NULL,m_pWindow,"vseparator",rControlRectangle.Top(),rControlRectangle.Bottom(),rControlRectangle.Left());
    1287             : 
    1288           0 :     return true;
    1289             : }
    1290             : 
    1291           0 : bool GtkSalGraphics::NWPaintGTKFrame(
    1292             :             GdkDrawable* gdkDrawable,
    1293             :             ControlType, ControlPart,
    1294             :             const Rectangle& rControlRectangle,
    1295             :             const clipList& rClipList,
    1296             :             ControlState /* nState */, const ImplControlValue& aValue,
    1297             :             const OUString& )
    1298             : {
    1299             :     GdkRectangle clipRect;
    1300           0 :     int frameWidth=getFrameWidth(gWidgetData[m_nXScreen].gFrame);
    1301           0 :     GtkShadowType shadowType=GTK_SHADOW_IN;
    1302           0 :     sal_uInt16 nStyle = aValue.getNumericVal();
    1303           0 :     if( nStyle & FRAME_DRAW_IN )
    1304           0 :         shadowType=GTK_SHADOW_OUT;
    1305           0 :     if( nStyle & FRAME_DRAW_OUT )
    1306           0 :         shadowType=GTK_SHADOW_IN;
    1307             : 
    1308           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    1309             :     {
    1310           0 :         clipRect.x = it->Left();
    1311           0 :         clipRect.y = it->Top();
    1312           0 :         clipRect.width = it->GetWidth();
    1313           0 :         clipRect.height = it->GetHeight();
    1314             : 
    1315             :         // Draw background first
    1316             : 
    1317             :         // Top
    1318             :         gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_OUT,&clipRect,
    1319             :                          m_pWindow,"base",
    1320           0 :                          rControlRectangle.Left(),
    1321           0 :                          rControlRectangle.Top(),
    1322           0 :                          rControlRectangle.GetWidth(),
    1323           0 :                          frameWidth);
    1324             :         // Bottom
    1325             :         gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_OUT,&clipRect,
    1326             :                          m_pWindow,"base",
    1327           0 :                          rControlRectangle.Left(),
    1328           0 :                          rControlRectangle.Top()+rControlRectangle.GetHeight()-frameWidth,
    1329           0 :                          rControlRectangle.GetWidth(),
    1330           0 :                          frameWidth);
    1331             :         // Left
    1332             :         gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_OUT,&clipRect,
    1333             :                          m_pWindow,"base",
    1334           0 :                          rControlRectangle.Left(),
    1335           0 :                          rControlRectangle.Top(),
    1336             :                          2*frameWidth,
    1337           0 :                          rControlRectangle.GetHeight());
    1338             :         // Right
    1339             :         gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_OUT,&clipRect,
    1340             :                          m_pWindow,"base",
    1341           0 :                          rControlRectangle.Left()+rControlRectangle.GetWidth()-frameWidth,
    1342           0 :                          rControlRectangle.Top(),
    1343             :                          2*frameWidth,
    1344           0 :                          rControlRectangle.GetHeight());
    1345             : 
    1346             :         // Now render the frame
    1347           0 :         gtk_paint_shadow(gWidgetData[m_nXScreen].gFrame->style,gdkDrawable,GTK_STATE_NORMAL,shadowType,&clipRect,
    1348           0 :                          gWidgetData[m_nXScreen].gFrame,"base",
    1349           0 :                          rControlRectangle.Left(),
    1350           0 :                          rControlRectangle.Top(),
    1351           0 :                          rControlRectangle.GetWidth(),
    1352           0 :                          rControlRectangle.GetHeight());
    1353             :     }
    1354             : 
    1355           0 :     return true;
    1356             : }
    1357             : 
    1358           0 : bool GtkSalGraphics::NWPaintGTKWindowBackground(
    1359             :             GdkDrawable* gdkDrawable,
    1360             :             ControlType, ControlPart,
    1361             :             const Rectangle& /* rControlRectangle */,
    1362             :             const clipList& rClipList,
    1363             :             ControlState /* nState */, const ImplControlValue&,
    1364             :             const OUString& )
    1365             : {
    1366             :     int w,h;
    1367           0 :     gtk_window_get_size(GTK_WINDOW(m_pWindow),&w,&h);
    1368             :     GdkRectangle clipRect;
    1369           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    1370             :     {
    1371           0 :         clipRect.x = it->Left();
    1372           0 :         clipRect.y = it->Top();
    1373           0 :         clipRect.width = it->GetWidth();
    1374           0 :         clipRect.height = it->GetHeight();
    1375             : 
    1376           0 :         gtk_paint_flat_box(m_pWindow->style,gdkDrawable,GTK_STATE_NORMAL,GTK_SHADOW_NONE,&clipRect,m_pWindow,"base",0,0,w,h);
    1377             :     }
    1378             : 
    1379           0 :     return true;
    1380             : }
    1381             : 
    1382           0 : bool GtkSalGraphics::NWPaintGTKButtonReal(
    1383             :             GtkWidget* button,
    1384             :             GdkDrawable* gdkDrawable,
    1385             :             ControlType, ControlPart,
    1386             :             const Rectangle& rControlRectangle,
    1387             :             const clipList& rClipList,
    1388             :             ControlState nState, const ImplControlValue&,
    1389             :             const OUString& )
    1390             : {
    1391             :     GtkStateType    stateType;
    1392             :     GtkShadowType    shadowType;
    1393             :     gboolean        interiorFocus;
    1394             :     gint            focusWidth;
    1395             :     gint            focusPad;
    1396           0 :     bool            bDrawFocus = true;
    1397             :     gint            x, y, w, h;
    1398             :     GtkBorder        aDefBorder;
    1399             :     GtkBorder*        pBorder;
    1400             :     GdkRectangle    clipRect;
    1401             : 
    1402           0 :     NWEnsureGTKButton( m_nXScreen );
    1403           0 :     NWEnsureGTKToolbar( m_nXScreen );
    1404             : 
    1405             :     // Flat toolbutton has a bit bigger variety of states than normal buttons, so handle it differently
    1406           0 :     if(GTK_IS_TOGGLE_BUTTON(button))
    1407             :     {
    1408           0 :        if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
    1409           0 :            shadowType=GTK_SHADOW_IN;
    1410             :        else
    1411           0 :            shadowType=GTK_SHADOW_OUT;
    1412             : 
    1413           0 :        if(nState & CTRL_STATE_ROLLOVER)
    1414           0 :            stateType=GTK_STATE_PRELIGHT;
    1415             :        else
    1416           0 :            stateType=GTK_STATE_NORMAL;
    1417             : 
    1418           0 :        if(nState & CTRL_STATE_PRESSED)
    1419             :        {
    1420           0 :            stateType=GTK_STATE_ACTIVE;
    1421           0 :            shadowType=GTK_SHADOW_IN;
    1422             :        }
    1423             :     }
    1424             :     else
    1425             :     {
    1426           0 :         NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    1427           0 :         NWSetWidgetState( gWidgetData[m_nXScreen].gBtnWidget, nState, stateType );
    1428             :     }
    1429             : 
    1430           0 :     x = rControlRectangle.Left();
    1431           0 :     y = rControlRectangle.Top();
    1432           0 :     w = rControlRectangle.GetWidth();
    1433           0 :     h = rControlRectangle.GetHeight();
    1434             : 
    1435           0 :     gint internal_padding = 0;
    1436           0 :     if(GTK_IS_TOOL_ITEM(button))
    1437             :     {
    1438           0 :         gtk_widget_style_get (GTK_WIDGET (gWidgetData[m_nXScreen].gToolbarWidget),
    1439             :                 "internal-padding", &internal_padding,
    1440           0 :                 NULL);
    1441           0 :         x += internal_padding/2;
    1442           0 :         w -= internal_padding;
    1443           0 :         stateType = GTK_STATE_PRELIGHT;
    1444             :     }
    1445             : 
    1446             :     // Grab some button style attributes
    1447           0 :     gtk_widget_style_get( gWidgetData[m_nXScreen].gBtnWidget,    "focus-line-width",    &focusWidth,
    1448             :                                 "focus-padding",     &focusPad,
    1449             :                                  "interior_focus",    &interiorFocus,
    1450           0 :                                 (char *)NULL );
    1451           0 :     gtk_widget_style_get( gWidgetData[m_nXScreen].gBtnWidget,
    1452             :                                 "default_border",    &pBorder,
    1453           0 :                                 (char *)NULL );
    1454             : 
    1455             :     // Make sure the border values exist, otherwise use some defaults
    1456           0 :     if ( pBorder )
    1457             :     {
    1458           0 :         NW_gtk_border_set_from_border( aDefBorder, pBorder );
    1459           0 :         gtk_border_free( pBorder );
    1460             :     }
    1461           0 :     else NW_gtk_border_set_from_border( aDefBorder, &aDefDefBorder );
    1462             : 
    1463             :     // If the button is too small, don't ever draw focus or grab more space
    1464           0 :     if ( (w < 16) || (h < 16) )
    1465           0 :         bDrawFocus = false;
    1466             : 
    1467           0 :     gint xi = x, yi = y, wi = w, hi = h;
    1468           0 :     if ( (nState & CTRL_STATE_DEFAULT) && bDrawFocus )
    1469             :     {
    1470           0 :         xi += aDefBorder.left;
    1471           0 :         yi += aDefBorder.top;
    1472           0 :         wi -= aDefBorder.left + aDefBorder.right;
    1473           0 :         hi -= aDefBorder.top + aDefBorder.bottom;
    1474             :     }
    1475             : 
    1476           0 :     if ( !interiorFocus && bDrawFocus )
    1477             :     {
    1478           0 :         xi += focusWidth + focusPad;
    1479           0 :         yi += focusWidth + focusPad;
    1480           0 :         wi -= 2 * (focusWidth + focusPad);
    1481           0 :         hi -= 2 * (focusWidth + focusPad);
    1482             :     }
    1483           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it)
    1484             :     {
    1485           0 :         clipRect.x = it->Left();
    1486           0 :         clipRect.y = it->Top();
    1487           0 :         clipRect.width = it->GetWidth();
    1488           0 :         clipRect.height = it->GetHeight();
    1489             : 
    1490             :         // Buttons must paint opaque since some themes have alpha-channel enabled buttons
    1491           0 :         if(button == gWidgetData[m_nXScreen].gToolbarButtonWidget)
    1492             :         {
    1493           0 :             gtk_paint_box( gWidgetData[m_nXScreen].gToolbarWidget->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
    1494           0 :                                 &clipRect, gWidgetData[m_nXScreen].gToolbarWidget, "toolbar", x, y, w, h );
    1495             :         }
    1496             :         else
    1497             :         {
    1498             :             gtk_paint_box( m_pWindow->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
    1499           0 :                                 &clipRect, m_pWindow, "base", x, y, w, h );
    1500             :         }
    1501             : 
    1502           0 :         if ( GTK_IS_BUTTON(button) )
    1503             :         {
    1504           0 :             if ( (nState & CTRL_STATE_DEFAULT) )
    1505             :                 gtk_paint_box( button->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
    1506           0 :                                &clipRect, button, "buttondefault", x, y, w, h );
    1507             : 
    1508             :             /* don't draw "button", because it can be a tool_button, and
    1509             :              * it causes some weird things, so, the default button is
    1510             :              * just fine */
    1511             :             gtk_paint_box( button->style, gdkDrawable, stateType, shadowType,
    1512           0 :                            &clipRect, button, "button", xi, yi, wi, hi );
    1513             :         }
    1514             :     }
    1515             : 
    1516           0 :     return true;
    1517             : }
    1518             : 
    1519           0 : bool GtkSalGraphics::NWPaintGTKButton(
    1520             :             GdkDrawable* gdkDrawable,
    1521             :             ControlType type, ControlPart part,
    1522             :             const Rectangle& rControlRectangle,
    1523             :             const clipList& rClipList,
    1524             :             ControlState nState, const ImplControlValue& value,
    1525             :             const OUString& string)
    1526             : {
    1527             :         return NWPaintGTKButtonReal(
    1528           0 :             gWidgetData[m_nXScreen].gBtnWidget,
    1529             :             gdkDrawable,
    1530             :             type, part,
    1531             :             rControlRectangle,
    1532             :             rClipList,
    1533             :             nState, value,
    1534           0 :             string );
    1535             : }
    1536             : 
    1537           0 : static Rectangle NWGetButtonArea( SalX11Screen nScreen,
    1538             :                                   ControlType, ControlPart, Rectangle aAreaRect, ControlState nState,
    1539             :                                   const ImplControlValue&, const OUString& )
    1540             : {
    1541             :     gboolean        interiorFocus;
    1542             :     gint            focusWidth;
    1543             :     gint            focusPad;
    1544             :     GtkBorder        aDefBorder;
    1545             :     GtkBorder *    pBorder;
    1546           0 :     bool            bDrawFocus = true;
    1547           0 :     Rectangle        aRect;
    1548             :     gint            x, y, w, h;
    1549             : 
    1550           0 :     NWEnsureGTKButton( nScreen );
    1551           0 :     gtk_widget_style_get( gWidgetData[nScreen].gBtnWidget,
    1552             :                                 "focus-line-width",    &focusWidth,
    1553             :                                 "focus-padding",     &focusPad,
    1554             :                                  "interior_focus",    &interiorFocus,
    1555             :                                 "default_border",    &pBorder,
    1556           0 :                                 (char *)NULL );
    1557             : 
    1558             :     // Make sure the border values exist, otherwise use some defaults
    1559           0 :     if ( pBorder )
    1560             :     {
    1561           0 :         NW_gtk_border_set_from_border( aDefBorder, pBorder );
    1562           0 :         gtk_border_free( pBorder );
    1563             :     }
    1564           0 :     else NW_gtk_border_set_from_border( aDefBorder, &aDefDefBorder );
    1565             : 
    1566           0 :     x = aAreaRect.Left();
    1567           0 :     y = aAreaRect.Top();
    1568           0 :     w = aAreaRect.GetWidth();
    1569           0 :     h = aAreaRect.GetHeight();
    1570             : 
    1571             :     // If the button is too small, don't ever draw focus or grab more space
    1572           0 :     if ( (w < 16) || (h < 16) )
    1573           0 :         bDrawFocus = false;
    1574             : 
    1575           0 :     if ( (nState & CTRL_STATE_DEFAULT) && bDrawFocus )
    1576             :     {
    1577           0 :         x -= aDefBorder.left;
    1578           0 :         y -= aDefBorder.top;
    1579           0 :         w += aDefBorder.left + aDefBorder.right;
    1580           0 :         h += aDefBorder.top + aDefBorder.bottom;
    1581             :     }
    1582             : 
    1583           0 :     aRect = Rectangle( Point( x, y ), Size( w, h ) );
    1584             : 
    1585           0 :     return( aRect );
    1586             : }
    1587             : 
    1588           0 : static Rectangle NWGetTabItemRect( SalX11Screen nScreen, Rectangle aAreaRect )
    1589             : {
    1590           0 :     NWEnsureGTKNotebook( nScreen );
    1591             : 
    1592             :     gint            x, y, w, h;
    1593             : 
    1594           0 :     x = aAreaRect.Left();
    1595           0 :     y = aAreaRect.Top();
    1596           0 :     w = aAreaRect.GetWidth();
    1597           0 :     h = aAreaRect.GetHeight();
    1598             : 
    1599           0 :     gint xthickness = gWidgetData[nScreen].gNotebookWidget->style->xthickness;
    1600           0 :     gint ythickness = gWidgetData[nScreen].gNotebookWidget->style->ythickness;
    1601             : 
    1602           0 :     x -= xthickness;
    1603           0 :     y -= ythickness;
    1604           0 :     w += xthickness*2;
    1605           0 :     h += ythickness*2;
    1606             : 
    1607           0 :     return Rectangle( Point( x, y ), Size( w, h ) );
    1608             : }
    1609             : 
    1610           0 : bool GtkSalGraphics::NWPaintGTKRadio( GdkDrawable* gdkDrawable,
    1611             :                                       ControlType, ControlPart,
    1612             :                                       const Rectangle& rControlRectangle,
    1613             :                                       const clipList& rClipList,
    1614             :                                       ControlState nState,
    1615             :                                       const ImplControlValue& aValue,
    1616             :                                       const OUString& )
    1617             : {
    1618             :     GtkStateType    stateType;
    1619             :     GtkShadowType    shadowType;
    1620           0 :     bool            isChecked = (aValue.getTristateVal()==BUTTONVALUE_ON);
    1621             :     gint            x, y;
    1622             :     GdkRectangle    clipRect;
    1623             : 
    1624           0 :     NWEnsureGTKButton( m_nXScreen );
    1625           0 :     NWEnsureGTKRadio( m_nXScreen );
    1626           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    1627             : 
    1628             :     gint indicator_size;
    1629           0 :     gtk_widget_style_get( gWidgetData[m_nXScreen].gRadioWidget, "indicator_size", &indicator_size, (char *)NULL);
    1630             : 
    1631           0 :     x = rControlRectangle.Left() + (rControlRectangle.GetWidth()-indicator_size)/2;
    1632           0 :     y = rControlRectangle.Top() + (rControlRectangle.GetHeight()-indicator_size)/2;
    1633             : 
    1634             :     // Set the shadow based on if checked or not so we get a freakin checkmark.
    1635           0 :     shadowType = isChecked ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
    1636           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gRadioWidget, nState, stateType );
    1637           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gRadioWidgetSibling, nState, stateType );
    1638             : 
    1639             :     // GTK enforces radio groups, so that if we don't have 2 buttons in the group,
    1640             :     // the single button will always be active.  So we have to have 2 buttons.
    1641             : 
    1642             :     // #i59666# set the members directly where we should use
    1643             :     // gtk_toggle_button_set_active. reason: there are animated themes
    1644             :     // which are in active state only after a while leading to painting
    1645             :     // intermediate states between active/inactive. Let's hope that
    1646             :     // GtkToggleButtone stays binary compatible.
    1647           0 :     if (!isChecked)
    1648           0 :         GTK_TOGGLE_BUTTON(gWidgetData[m_nXScreen].gRadioWidgetSibling)->active = true;
    1649           0 :     GTK_TOGGLE_BUTTON(gWidgetData[m_nXScreen].gRadioWidget)->active = isChecked;
    1650             : 
    1651           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    1652             :     {
    1653           0 :         clipRect.x = it->Left();
    1654           0 :         clipRect.y = it->Top();
    1655           0 :         clipRect.width = it->GetWidth();
    1656           0 :         clipRect.height = it->GetHeight();
    1657             : 
    1658           0 :         gtk_paint_option( gWidgetData[m_nXScreen].gRadioWidget->style, gdkDrawable, stateType, shadowType,
    1659           0 :                           &clipRect, gWidgetData[m_nXScreen].gRadioWidget, "radiobutton",
    1660           0 :                           x, y, indicator_size, indicator_size );
    1661             :     }
    1662             : 
    1663           0 :     return true;
    1664             : }
    1665             : 
    1666           0 : bool GtkSalGraphics::NWPaintGTKCheck( GdkDrawable* gdkDrawable,
    1667             :                                       ControlType, ControlPart,
    1668             :                                       const Rectangle& rControlRectangle,
    1669             :                                       const clipList& rClipList,
    1670             :                                       ControlState nState,
    1671             :                                       const ImplControlValue& aValue,
    1672             :                                       const OUString& )
    1673             : {
    1674             :     GtkStateType    stateType;
    1675             :     GtkShadowType    shadowType;
    1676           0 :     bool            isChecked = (aValue.getTristateVal() == BUTTONVALUE_ON);
    1677           0 :     bool            isInconsistent = (aValue.getTristateVal() == BUTTONVALUE_MIXED);
    1678             :     GdkRectangle    clipRect;
    1679             :     gint            x,y;
    1680             : 
    1681           0 :     NWEnsureGTKButton( m_nXScreen );
    1682           0 :     NWEnsureGTKCheck( m_nXScreen );
    1683           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    1684             : 
    1685             :     gint indicator_size;
    1686           0 :     gtk_widget_style_get( gWidgetData[m_nXScreen].gCheckWidget, "indicator_size", &indicator_size, (char *)NULL);
    1687             : 
    1688           0 :     x = rControlRectangle.Left() + (rControlRectangle.GetWidth()-indicator_size)/2;
    1689           0 :     y = rControlRectangle.Top() + (rControlRectangle.GetHeight()-indicator_size)/2;
    1690             : 
    1691             :     // Set the shadow based on if checked or not so we get a checkmark.
    1692           0 :     shadowType = isChecked ? GTK_SHADOW_IN : isInconsistent ? GTK_SHADOW_ETCHED_IN : GTK_SHADOW_OUT;
    1693           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gCheckWidget, nState, stateType );
    1694           0 :     GTK_TOGGLE_BUTTON(gWidgetData[m_nXScreen].gCheckWidget)->active = isChecked;
    1695             : 
    1696           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    1697             :     {
    1698           0 :         clipRect.x = it->Left();
    1699           0 :         clipRect.y = it->Top();
    1700           0 :         clipRect.width = it->GetWidth();
    1701           0 :         clipRect.height = it->GetHeight();
    1702             : 
    1703           0 :         gtk_paint_check( gWidgetData[m_nXScreen].gCheckWidget->style, gdkDrawable, stateType, shadowType,
    1704           0 :                          &clipRect, gWidgetData[m_nXScreen].gCheckWidget, "checkbutton",
    1705           0 :                          x, y, indicator_size, indicator_size );
    1706             :     }
    1707             : 
    1708           0 :     return true;
    1709             : }
    1710             : 
    1711           0 : static void NWCalcArrowRect( const Rectangle& rButton, Rectangle& rArrow )
    1712             : {
    1713             :     // Size the arrow appropriately
    1714           0 :     Size aSize( rButton.GetWidth()/2, rButton.GetHeight()/2 );
    1715           0 :     rArrow.SetSize( aSize );
    1716             : 
    1717             :     rArrow.SetPos( Point(
    1718           0 :         rButton.Left() + ( rButton.GetWidth()  - rArrow.GetWidth()  ) / 2,
    1719           0 :         rButton.Top() + ( rButton.GetHeight() - rArrow.GetHeight() ) / 2
    1720           0 :         ) );
    1721           0 : }
    1722             : 
    1723           0 : bool GtkSalGraphics::NWPaintGTKScrollbar( ControlType, ControlPart nPart,
    1724             :                                           const Rectangle& rControlRectangle,
    1725             :                                           const clipList&,
    1726             :                                           ControlState nState,
    1727             :                                           const ImplControlValue& aValue,
    1728             :                                           const OUString& )
    1729             : {
    1730             :     assert(aValue.getType() == CTRL_SCROLLBAR);
    1731           0 :     const ScrollbarValue& rScrollbarVal = static_cast<const ScrollbarValue&>(aValue);
    1732           0 :     GdkPixmap*      pixmap = NULL;
    1733           0 :     Rectangle        pixmapRect, scrollbarRect;
    1734             :     GtkStateType    stateType;
    1735             :     GtkShadowType    shadowType;
    1736             :     GtkScrollbar *    scrollbarWidget;
    1737             :     GtkStyle *    style;
    1738           0 :     GtkAdjustment* scrollbarValues = NULL;
    1739             :     GtkOrientation    scrollbarOrientation;
    1740           0 :     Rectangle        thumbRect = rScrollbarVal.maThumbRect;
    1741           0 :     Rectangle        button11BoundRect = rScrollbarVal.maButton1Rect;   // backward
    1742           0 :     Rectangle        button22BoundRect = rScrollbarVal.maButton2Rect;   // forward
    1743           0 :     Rectangle        button12BoundRect = rScrollbarVal.maButton1Rect;   // secondary forward
    1744           0 :     Rectangle        button21BoundRect = rScrollbarVal.maButton2Rect;   // secondary backward
    1745             :     GtkArrowType    button1Type;                                        // backward
    1746             :     GtkArrowType    button2Type;                                        // forward
    1747           0 :     gchar *        scrollbarTagH = (gchar *) "hscrollbar";
    1748           0 :     gchar *        scrollbarTagV = (gchar *) "vscrollbar";
    1749           0 :     gchar *        scrollbarTag = NULL;
    1750           0 :     Rectangle        arrowRect;
    1751           0 :     gint            slider_width = 0;
    1752           0 :     gint            stepper_size = 0;
    1753           0 :     gint            stepper_spacing = 0;
    1754           0 :     gint            trough_border = 0;
    1755           0 :     gint            min_slider_length = 0;
    1756           0 :     gint            vShim = 0;
    1757           0 :     gint            hShim = 0;
    1758             :     gint            x,y,w,h;
    1759             : 
    1760             :     // make controlvalue rectangles relative to area
    1761           0 :     thumbRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
    1762           0 :     button11BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
    1763           0 :     button22BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
    1764           0 :     button12BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
    1765           0 :     button21BoundRect.Move( -rControlRectangle.Left(), -rControlRectangle.Top() );
    1766             : 
    1767           0 :     NWEnsureGTKButton( m_nXScreen );
    1768           0 :     NWEnsureGTKScrollbars( m_nXScreen );
    1769           0 :     NWEnsureGTKArrow( m_nXScreen );
    1770             : 
    1771             :     // Find the overall bounding rect of the control
    1772           0 :     pixmapRect = rControlRectangle;
    1773           0 :     scrollbarRect = pixmapRect;
    1774             : 
    1775           0 :     if ( (scrollbarRect.GetWidth() <= 1) || (scrollbarRect.GetHeight() <= 1) )
    1776           0 :         return true;
    1777             : 
    1778             :     // Grab some button style attributes
    1779           0 :     gtk_widget_style_get( gWidgetData[m_nXScreen].gScrollHorizWidget,
    1780             :                                       "slider_width", &slider_width,
    1781             :                                       "stepper_size", &stepper_size,
    1782             :                                       "trough_border", &trough_border,
    1783             :                                       "stepper_spacing", &stepper_spacing,
    1784           0 :                                       "min_slider_length", &min_slider_length, (char *)NULL );
    1785             :     gboolean has_forward;
    1786             :     gboolean has_forward2;
    1787             :     gboolean has_backward;
    1788             :     gboolean has_backward2;
    1789             : 
    1790           0 :     gtk_widget_style_get( gWidgetData[m_nXScreen].gScrollHorizWidget, "has-forward-stepper", &has_forward,
    1791             :                                       "has-secondary-forward-stepper", &has_forward2,
    1792             :                                       "has-backward-stepper", &has_backward,
    1793           0 :                                          "has-secondary-backward-stepper", &has_backward2, (char *)NULL );
    1794           0 :     gint magic = trough_border ? 1 : 0;
    1795           0 :     gint nFirst = 0;
    1796             : 
    1797           0 :     if ( has_backward )  nFirst  += 1;
    1798           0 :     if ( has_forward2 )  nFirst  += 1;
    1799             : 
    1800           0 :     if ( nPart == PART_DRAW_BACKGROUND_HORZ )
    1801             :     {
    1802           0 :         unsigned int sliderHeight = slider_width + (trough_border * 2);
    1803           0 :         vShim = (pixmapRect.GetHeight() - sliderHeight) / 2;
    1804           0 :         bool bRTLSwap = button11BoundRect.Left() > button22BoundRect.Left();
    1805             : 
    1806           0 :         scrollbarRect.Move( 0, vShim );
    1807           0 :         scrollbarRect.SetSize( Size( scrollbarRect.GetWidth(), sliderHeight ) );
    1808             : 
    1809           0 :         scrollbarWidget = GTK_SCROLLBAR( gWidgetData[m_nXScreen].gScrollHorizWidget );
    1810           0 :         scrollbarOrientation = GTK_ORIENTATION_HORIZONTAL;
    1811           0 :         scrollbarTag = scrollbarTagH;
    1812           0 :         button1Type = bRTLSwap? GTK_ARROW_RIGHT: GTK_ARROW_LEFT;
    1813           0 :         button2Type = bRTLSwap? GTK_ARROW_LEFT: GTK_ARROW_RIGHT;
    1814             : 
    1815           0 :         if ( has_backward )
    1816             :         {
    1817           0 :             button12BoundRect.Move( stepper_size - trough_border,
    1818           0 :                                     (scrollbarRect.GetHeight() - slider_width) / 2 );
    1819             :         }
    1820             : 
    1821           0 :         button11BoundRect.Move( trough_border, (scrollbarRect.GetHeight() - slider_width) / 2 );
    1822           0 :         button11BoundRect.SetSize( Size( stepper_size, slider_width ) );
    1823           0 :         button12BoundRect.SetSize( Size( stepper_size, slider_width ) );
    1824             : 
    1825           0 :         if ( has_backward2 )
    1826             :         {
    1827           0 :             button22BoundRect.Move( stepper_size+(trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
    1828           0 :             button21BoundRect.Move( (trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
    1829             :         }
    1830             :         else
    1831             :         {
    1832           0 :             button22BoundRect.Move( (trough_border+1)/2, (scrollbarRect.GetHeight() - slider_width) / 2 );
    1833             :         }
    1834             : 
    1835           0 :         button21BoundRect.SetSize( Size( stepper_size, slider_width ) );
    1836           0 :         button22BoundRect.SetSize( Size( stepper_size, slider_width ) );
    1837             : 
    1838           0 :         thumbRect.Bottom() = thumbRect.Top() + slider_width - 1;
    1839             :         // Make sure the thumb is at least the default width (so we don't get tiny thumbs),
    1840             :         // but if the VCL gives us a size smaller than the theme's default thumb size,
    1841             :         // honor the VCL size
    1842           0 :         thumbRect.Right() += magic;
    1843             :         // Center vertically in the track
    1844           0 :         thumbRect.Move( 0, (scrollbarRect.GetHeight() - slider_width) / 2 );
    1845             :     }
    1846             :     else
    1847             :     {
    1848           0 :         unsigned int sliderWidth = slider_width + (trough_border * 2);
    1849           0 :         hShim = (pixmapRect.GetWidth() - sliderWidth) / 2;
    1850             : 
    1851           0 :         scrollbarRect.Move( hShim, 0 );
    1852           0 :         scrollbarRect.SetSize( Size( sliderWidth, scrollbarRect.GetHeight() ) );
    1853             : 
    1854           0 :         scrollbarWidget = GTK_SCROLLBAR( gWidgetData[m_nXScreen].gScrollVertWidget );
    1855           0 :         scrollbarOrientation = GTK_ORIENTATION_VERTICAL;
    1856           0 :         scrollbarTag = scrollbarTagV;
    1857           0 :         button1Type = GTK_ARROW_UP;
    1858           0 :         button2Type = GTK_ARROW_DOWN;
    1859             : 
    1860           0 :         if ( has_backward )
    1861             :         {
    1862           0 :             button12BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2,
    1863           0 :                                     stepper_size + trough_border );
    1864             :         }
    1865           0 :         button11BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, trough_border );
    1866           0 :         button11BoundRect.SetSize( Size( slider_width, stepper_size ) );
    1867           0 :         button12BoundRect.SetSize( Size( slider_width, stepper_size ) );
    1868             : 
    1869           0 :         if ( has_backward2 )
    1870             :         {
    1871           0 :             button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, stepper_size+(trough_border+1)/2 );
    1872           0 :             button21BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, (trough_border+1)/2 );
    1873             :         }
    1874             :         else
    1875             :         {
    1876           0 :             button22BoundRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, (trough_border+1)/2 );
    1877             :         }
    1878             : 
    1879           0 :         button21BoundRect.SetSize( Size( slider_width, stepper_size ) );
    1880           0 :         button22BoundRect.SetSize( Size( slider_width, stepper_size ) );
    1881             : 
    1882           0 :         thumbRect.Right() = thumbRect.Left() + slider_width - 1;
    1883             : 
    1884           0 :         thumbRect.Bottom() += magic;
    1885             :         // Center horizontally in the track
    1886           0 :         thumbRect.Move( (scrollbarRect.GetWidth() - slider_width) / 2, 0 );
    1887             :     }
    1888             : 
    1889           0 :     bool has_slider = ( thumbRect.GetWidth() > 0 && thumbRect.GetHeight() > 0 );
    1890             : 
    1891           0 :     scrollbarValues = gtk_range_get_adjustment( GTK_RANGE(scrollbarWidget) );
    1892           0 :     if ( scrollbarValues == NULL )
    1893           0 :         scrollbarValues = GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 0, 0, 0, 0) );
    1894           0 :     if ( nPart == PART_DRAW_BACKGROUND_HORZ )
    1895             :     {
    1896           0 :         scrollbarValues->lower = rScrollbarVal.mnMin;
    1897           0 :         scrollbarValues->upper = rScrollbarVal.mnMax;
    1898           0 :         scrollbarValues->value = rScrollbarVal.mnCur;
    1899           0 :         scrollbarValues->page_size = scrollbarRect.GetWidth() / 2;
    1900             :     }
    1901             :     else
    1902             :     {
    1903           0 :         scrollbarValues->lower = rScrollbarVal.mnMin;
    1904           0 :         scrollbarValues->upper = rScrollbarVal.mnMax;
    1905           0 :         scrollbarValues->value = rScrollbarVal.mnCur;
    1906           0 :         scrollbarValues->page_size = scrollbarRect.GetHeight() / 2;
    1907             :     }
    1908           0 :     gtk_adjustment_changed( scrollbarValues );
    1909             : 
    1910             :     // as multiple paints are required for the scrollbar
    1911             :     // painting them directly to the window flickers
    1912           0 :     pixmap = NWGetPixmapFromScreen( pixmapRect );
    1913           0 :     if( ! pixmap )
    1914           0 :         return false;
    1915           0 :     x = y = 0;
    1916             : 
    1917           0 :     w = pixmapRect.GetWidth();
    1918           0 :     h = pixmapRect.GetHeight();
    1919             : 
    1920           0 :     GdkDrawable* const &gdkDrawable = GDK_DRAWABLE( pixmap );
    1921           0 :     GdkRectangle* gdkRect = NULL;
    1922             : 
    1923           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    1924           0 :     NWSetWidgetState( GTK_WIDGET(scrollbarWidget), nState, stateType );
    1925           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gBtnWidget, nState, stateType );
    1926           0 :     style = GTK_WIDGET( scrollbarWidget )->style;
    1927             : 
    1928             :     gtk_style_apply_default_background( m_pWindow->style, gdkDrawable, TRUE,
    1929             :                                         GTK_STATE_NORMAL, gdkRect,
    1930           0 :                                         x, y, w, h );
    1931             : 
    1932             :     // ----------------- TROUGH
    1933             :     // Pass coordinates of draw rect: window(0,0) -> widget(bottom-right) (coords relative to widget)
    1934             :     gtk_paint_flat_box(m_pWindow->style, gdkDrawable,
    1935             :                         GTK_STATE_NORMAL, GTK_SHADOW_NONE, gdkRect,
    1936           0 :                         m_pWindow, "base", x-pixmapRect.Left(),y-pixmapRect.Top(),x+pixmapRect.Right(),y+pixmapRect.Bottom());
    1937             : 
    1938             :     gtk_paint_box( style, gdkDrawable, GTK_STATE_ACTIVE, GTK_SHADOW_IN,
    1939           0 :                    gdkRect, GTK_WIDGET(scrollbarWidget), "trough",
    1940             :                    x, y,
    1941           0 :                    scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
    1942             : 
    1943           0 :     if ( nState & CTRL_STATE_FOCUSED )
    1944             :     {
    1945             :         gtk_paint_focus( style, gdkDrawable, GTK_STATE_ACTIVE,
    1946           0 :                          gdkRect, GTK_WIDGET(scrollbarWidget), "trough",
    1947             :                          x, y,
    1948           0 :                          scrollbarRect.GetWidth(), scrollbarRect.GetHeight() );
    1949             :     }
    1950             : 
    1951             :     // ----------------- THUMB
    1952           0 :     if ( has_slider )
    1953             :     {
    1954           0 :         NWConvertVCLStateToGTKState( rScrollbarVal.mnThumbState, &stateType, &shadowType );
    1955             :         gtk_paint_slider( style, gdkDrawable, stateType, GTK_SHADOW_OUT,
    1956           0 :                         gdkRect, GTK_WIDGET(scrollbarWidget), "slider",
    1957           0 :                         x+hShim+thumbRect.Left(), y+vShim+thumbRect.Top(),
    1958           0 :                         thumbRect.GetWidth(), thumbRect.GetHeight(), scrollbarOrientation );
    1959             :     }
    1960             : 
    1961             :     // Some engines require allocation, e.g. Clearlooks uses it to identify
    1962             :     // positions of the buttons, whereupon the first and the last button will
    1963             :     // have rounded corners.
    1964           0 :     GTK_WIDGET(scrollbarWidget)->allocation.x = x;
    1965           0 :     GTK_WIDGET(scrollbarWidget)->allocation.y = y;
    1966           0 :     GTK_WIDGET(scrollbarWidget)->allocation.width = w;
    1967           0 :     GTK_WIDGET(scrollbarWidget)->allocation.height = h;
    1968             : 
    1969             :     bool backwardButtonInsensitive =
    1970           0 :         rScrollbarVal.mnCur == rScrollbarVal.mnMin;
    1971           0 :     bool forwardButtonInsensitive = rScrollbarVal.mnMax == 0 ||
    1972           0 :         rScrollbarVal.mnCur + rScrollbarVal.mnVisibleSize >= rScrollbarVal.mnMax;
    1973             : 
    1974             :     // ----------------- BUTTON 1
    1975           0 :     if ( has_backward )
    1976             :     {
    1977           0 :         NWConvertVCLStateToGTKState( rScrollbarVal.mnButton1State, &stateType, &shadowType );
    1978           0 :         if ( backwardButtonInsensitive )
    1979           0 :             stateType = GTK_STATE_INSENSITIVE;
    1980             :         gtk_paint_box( style, gdkDrawable, stateType, shadowType,
    1981           0 :                        gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag,
    1982           0 :                        x+hShim+button11BoundRect.Left(), y+vShim+button11BoundRect.Top(),
    1983           0 :                        button11BoundRect.GetWidth(), button11BoundRect.GetHeight() );
    1984             :         // ----------------- ARROW 1
    1985           0 :         NWCalcArrowRect( button11BoundRect, arrowRect );
    1986             :         gtk_paint_arrow( style, gdkDrawable, stateType, shadowType,
    1987           0 :                          gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag, button1Type, true,
    1988           0 :                          x+hShim+arrowRect.Left(), y+vShim+arrowRect.Top(),
    1989           0 :                          arrowRect.GetWidth(), arrowRect.GetHeight() );
    1990             :     }
    1991           0 :     if ( has_forward2 )
    1992             :     {
    1993           0 :         NWConvertVCLStateToGTKState( rScrollbarVal.mnButton2State, &stateType, &shadowType );
    1994           0 :         if ( forwardButtonInsensitive )
    1995           0 :             stateType = GTK_STATE_INSENSITIVE;
    1996             :         gtk_paint_box( style, gdkDrawable, stateType, shadowType,
    1997           0 :                        gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag,
    1998           0 :                        x+hShim+button12BoundRect.Left(), y+vShim+button12BoundRect.Top(),
    1999           0 :                        button12BoundRect.GetWidth(), button12BoundRect.GetHeight() );
    2000             :         // ----------------- ARROW 1
    2001           0 :         NWCalcArrowRect( button12BoundRect, arrowRect );
    2002             :         gtk_paint_arrow( style, gdkDrawable, stateType, shadowType,
    2003           0 :                          gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag, button2Type, true,
    2004           0 :                          x+hShim+arrowRect.Left(), y+vShim+arrowRect.Top(),
    2005           0 :                          arrowRect.GetWidth(), arrowRect.GetHeight() );
    2006             :     }
    2007             :     // ----------------- BUTTON 2
    2008           0 :     if ( has_backward2 )
    2009             :     {
    2010           0 :         NWConvertVCLStateToGTKState( rScrollbarVal.mnButton1State, &stateType, &shadowType );
    2011           0 :         if ( backwardButtonInsensitive )
    2012           0 :             stateType = GTK_STATE_INSENSITIVE;
    2013             :         gtk_paint_box( style, gdkDrawable, stateType, shadowType, gdkRect,
    2014           0 :                        GTK_WIDGET(scrollbarWidget), scrollbarTag,
    2015           0 :                        x+hShim+button21BoundRect.Left(), y+vShim+button21BoundRect.Top(),
    2016           0 :                        button21BoundRect.GetWidth(), button21BoundRect.GetHeight() );
    2017             :         // ----------------- ARROW 2
    2018           0 :         NWCalcArrowRect( button21BoundRect, arrowRect );
    2019             :         gtk_paint_arrow( style, gdkDrawable, stateType, shadowType,
    2020           0 :                          gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag, button1Type, true,
    2021           0 :                          x+hShim+arrowRect.Left(), y+vShim+arrowRect.Top(),
    2022           0 :                          arrowRect.GetWidth(), arrowRect.GetHeight() );
    2023             :     }
    2024           0 :     if ( has_forward )
    2025             :     {
    2026           0 :         NWConvertVCLStateToGTKState( rScrollbarVal.mnButton2State, &stateType, &shadowType );
    2027           0 :         if ( forwardButtonInsensitive )
    2028           0 :             stateType = GTK_STATE_INSENSITIVE;
    2029             :         gtk_paint_box( style, gdkDrawable, stateType, shadowType, gdkRect,
    2030           0 :                        GTK_WIDGET(scrollbarWidget), scrollbarTag,
    2031           0 :                        x+hShim+button22BoundRect.Left(), y+vShim+button22BoundRect.Top(),
    2032           0 :                        button22BoundRect.GetWidth(), button22BoundRect.GetHeight() );
    2033             :         // ----------------- ARROW 2
    2034           0 :         NWCalcArrowRect( button22BoundRect, arrowRect );
    2035             :         gtk_paint_arrow( style, gdkDrawable, stateType, shadowType,
    2036           0 :                          gdkRect, GTK_WIDGET(scrollbarWidget), scrollbarTag, button2Type, true,
    2037           0 :                          x+hShim+arrowRect.Left(), y+vShim+arrowRect.Top(),
    2038           0 :                          arrowRect.GetWidth(), arrowRect.GetHeight() );
    2039             :     }
    2040             : 
    2041           0 :     if( !NWRenderPixmapToScreen(pixmap, pixmapRect) )
    2042             :     {
    2043           0 :         g_object_unref( pixmap );
    2044           0 :         return false;
    2045             :     }
    2046           0 :     g_object_unref( pixmap );
    2047             : 
    2048           0 :     return true;
    2049             : }
    2050             : 
    2051           0 : static Rectangle NWGetScrollButtonRect(    SalX11Screen nScreen, ControlPart nPart, Rectangle aAreaRect )
    2052             : {
    2053             :     gint slider_width;
    2054             :     gint stepper_size;
    2055             :     gint stepper_spacing;
    2056             :     gint trough_border;
    2057             : 
    2058           0 :     NWEnsureGTKScrollbars( nScreen );
    2059             : 
    2060             :     // Grab some button style attributes
    2061           0 :     gtk_widget_style_get( gWidgetData[nScreen].gScrollHorizWidget,
    2062             :                                       "slider-width", &slider_width,
    2063             :                                       "stepper-size", &stepper_size,
    2064             :                                       "trough-border", &trough_border,
    2065           0 :                                          "stepper-spacing", &stepper_spacing, (char *)NULL );
    2066             : 
    2067             :     gboolean has_forward;
    2068             :     gboolean has_forward2;
    2069             :     gboolean has_backward;
    2070             :     gboolean has_backward2;
    2071             : 
    2072           0 :     gtk_widget_style_get( gWidgetData[nScreen].gScrollHorizWidget,
    2073             :                                       "has-forward-stepper", &has_forward,
    2074             :                                       "has-secondary-forward-stepper", &has_forward2,
    2075             :                                       "has-backward-stepper", &has_backward,
    2076           0 :                                          "has-secondary-backward-stepper", &has_backward2, (char *)NULL );
    2077             :     gint       buttonWidth;
    2078             :     gint       buttonHeight;
    2079           0 :     Rectangle  buttonRect;
    2080             : 
    2081           0 :     gint nFirst = 0;
    2082           0 :     gint nSecond = 0;
    2083             : 
    2084           0 :     if ( has_forward )   nSecond += 1;
    2085           0 :     if ( has_forward2 )  nFirst  += 1;
    2086           0 :     if ( has_backward )  nFirst  += 1;
    2087           0 :     if ( has_backward2 ) nSecond += 1;
    2088             : 
    2089           0 :     if ( ( nPart == PART_BUTTON_UP ) || ( nPart == PART_BUTTON_DOWN ) )
    2090             :     {
    2091           0 :         buttonWidth = slider_width + 2 * trough_border;
    2092           0 :         buttonHeight = stepper_size + trough_border + stepper_spacing;
    2093             :     }
    2094             :     else
    2095             :     {
    2096           0 :         buttonWidth = stepper_size + trough_border + stepper_spacing;
    2097           0 :         buttonHeight = slider_width + 2 * trough_border;
    2098             :     }
    2099             : 
    2100           0 :     if ( nPart == PART_BUTTON_UP )
    2101             :     {
    2102           0 :         buttonHeight *= nFirst;
    2103           0 :         buttonHeight -= 1;
    2104           0 :         buttonRect.setX( aAreaRect.Left() );
    2105           0 :         buttonRect.setY( aAreaRect.Top() );
    2106             :     }
    2107           0 :     else if ( nPart == PART_BUTTON_LEFT )
    2108             :     {
    2109           0 :         buttonWidth *= nFirst;
    2110           0 :         buttonWidth -= 1;
    2111           0 :         buttonRect.setX( aAreaRect.Left() );
    2112           0 :         buttonRect.setY( aAreaRect.Top() );
    2113             :     }
    2114           0 :     else if ( nPart == PART_BUTTON_DOWN )
    2115             :     {
    2116           0 :         buttonHeight *= nSecond;
    2117           0 :         buttonRect.setX( aAreaRect.Left() );
    2118           0 :         buttonRect.setY( aAreaRect.Top() + aAreaRect.GetHeight() - buttonHeight );
    2119             :     }
    2120           0 :     else if ( nPart == PART_BUTTON_RIGHT )
    2121             :     {
    2122           0 :         buttonWidth *= nSecond;
    2123           0 :         buttonRect.setX( aAreaRect.Left() + aAreaRect.GetWidth() - buttonWidth );
    2124           0 :         buttonRect.setY( aAreaRect.Top() );
    2125             :     }
    2126             : 
    2127           0 :     buttonRect.SetSize( Size( buttonWidth, buttonHeight ) );
    2128             : 
    2129           0 :     return( buttonRect );
    2130             : }
    2131             : 
    2132           0 : bool GtkSalGraphics::NWPaintGTKEditBox( GdkDrawable* gdkDrawable,
    2133             :                                         ControlType nType, ControlPart nPart,
    2134             :                                         const Rectangle& rControlRectangle,
    2135             :                                         const clipList& rClipList,
    2136             :                                         ControlState nState,
    2137             :                                         const ImplControlValue& aValue,
    2138             :                                         const OUString& rCaption )
    2139             : {
    2140           0 :     Rectangle        pixmapRect;
    2141             :     GdkRectangle    clipRect;
    2142             : 
    2143             :     // Find the overall bounding rect of the buttons's drawing area,
    2144             :     // plus its actual draw rect excluding adornment
    2145             :     pixmapRect = NWGetEditBoxPixmapRect( m_nXScreen, nType, nPart, rControlRectangle,
    2146           0 :                                          nState, aValue, rCaption );
    2147           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    2148             :     {
    2149           0 :         clipRect.x = it->Left();
    2150           0 :         clipRect.y = it->Top();
    2151           0 :         clipRect.width = it->GetWidth();
    2152           0 :         clipRect.height = it->GetHeight();
    2153             : 
    2154           0 :         NWPaintOneEditBox( m_nXScreen, gdkDrawable, &clipRect, nType, nPart, pixmapRect, nState, aValue, rCaption );
    2155             :     }
    2156             : 
    2157           0 :     return true;
    2158             : }
    2159             : 
    2160             : /* Take interior/exterior focus into account and return
    2161             :  * the bounding rectangle of the edit box including
    2162             :  * any focus requirements.
    2163             :  */
    2164           0 : static Rectangle NWGetEditBoxPixmapRect(SalX11Screen nScreen,
    2165             :                                         ControlType,
    2166             :                                         ControlPart,
    2167             :                                         Rectangle aAreaRect,
    2168             :                                         ControlState,
    2169             :                                         const ImplControlValue&,
    2170             :                                         const OUString& )
    2171             : {
    2172           0 :     Rectangle        pixmapRect = aAreaRect;
    2173             :     gboolean        interiorFocus;
    2174             :     gint            focusWidth;
    2175             : 
    2176           0 :     NWEnsureGTKEditBox( nScreen );
    2177             : 
    2178             :     // Grab some entry style attributes
    2179           0 :     gtk_widget_style_get( gWidgetData[nScreen].gEditBoxWidget,
    2180             :                                     "focus-line-width",    &focusWidth,
    2181           0 :                                      "interior-focus",    &interiorFocus, (char *)NULL );
    2182             : 
    2183           0 :     if ( !interiorFocus )
    2184             :     {
    2185           0 :         pixmapRect.Move( -(focusWidth), -(focusWidth) );
    2186           0 :         pixmapRect.SetSize( Size( pixmapRect.GetWidth() + (2*(focusWidth)),
    2187           0 :                                   pixmapRect.GetHeight() + (2*(focusWidth)) ) );
    2188             :     }
    2189             : 
    2190           0 :     return( pixmapRect );
    2191             : }
    2192             : 
    2193             : /* Paint a GTK Entry widget into the specified GdkPixmap.
    2194             :  * All coordinates should be local to the Pixmap, NOT
    2195             :  * screen/window coordinates.
    2196             :  */
    2197           0 : static void NWPaintOneEditBox(    SalX11Screen nScreen,
    2198             :                                 GdkDrawable * gdkDrawable,
    2199             :                                 GdkRectangle *    gdkRect,
    2200             :                                 ControlType            nType,
    2201             :                                 ControlPart,
    2202             :                                 Rectangle                aEditBoxRect,
    2203             :                                 ControlState            nState,
    2204             :                                 const ImplControlValue&,
    2205             :                                 const OUString& )
    2206             : {
    2207             :     GtkStateType    stateType;
    2208             :     GtkShadowType    shadowType;
    2209             :     GtkWidget      *widget;
    2210             : 
    2211           0 :     NWEnsureGTKButton( nScreen );
    2212           0 :     NWEnsureGTKEditBox( nScreen );
    2213           0 :     NWEnsureGTKSpinButton( nScreen );
    2214           0 :     NWEnsureGTKCombo( nScreen );
    2215           0 :     NWEnsureGTKScrolledWindow( nScreen );
    2216           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    2217             : 
    2218           0 :     switch ( nType )
    2219             :     {
    2220             :         case CTRL_SPINBOX:
    2221           0 :             widget = gWidgetData[nScreen].gSpinButtonWidget;
    2222           0 :             break;
    2223             : 
    2224             :         case CTRL_MULTILINE_EDITBOX:
    2225           0 :             widget = gWidgetData[nScreen].gScrolledWindowWidget;
    2226           0 :             break;
    2227             :         case CTRL_COMBOBOX:
    2228           0 :             widget = GTK_COMBO(gWidgetData[nScreen].gComboWidget)->entry;
    2229           0 :             break;
    2230             : 
    2231             :         default:
    2232           0 :             widget = gWidgetData[nScreen].gEditBoxWidget;
    2233           0 :             break;
    2234             :     }
    2235             : 
    2236           0 :     if ( stateType == GTK_STATE_PRELIGHT )
    2237           0 :         stateType = GTK_STATE_NORMAL;
    2238             : 
    2239           0 :     NWSetWidgetState( widget, nState, stateType );
    2240             : 
    2241           0 :     gint xborder = widget->style->xthickness;
    2242           0 :     gint yborder = widget->style->ythickness;
    2243             :     gint bInteriorFocus, nFocusLineWidth;
    2244             :     gtk_widget_style_get( widget,
    2245             :         "interior-focus",   &bInteriorFocus,
    2246             :         "focus-line-width", &nFocusLineWidth,
    2247           0 :         (char *)NULL);
    2248           0 :     if ( !bInteriorFocus )
    2249             :     {
    2250           0 :         xborder += nFocusLineWidth;
    2251           0 :         yborder += nFocusLineWidth;
    2252             :     }
    2253             : 
    2254             :     gtk_paint_flat_box( widget->style, gdkDrawable, stateType, GTK_SHADOW_NONE,
    2255             :                         gdkRect, widget, "entry_bg",
    2256           0 :                         aEditBoxRect.Left() + xborder, aEditBoxRect.Top() + yborder,
    2257           0 :                         aEditBoxRect.GetWidth() - 2*xborder, aEditBoxRect.GetHeight() - 2*yborder );
    2258             :     gtk_paint_shadow( widget->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_IN,
    2259             :                       gdkRect, widget, "entry",
    2260           0 :                       aEditBoxRect.Left(), aEditBoxRect.Top(),
    2261           0 :                       aEditBoxRect.GetWidth(), aEditBoxRect.GetHeight() );
    2262             : 
    2263           0 : }
    2264             : 
    2265           0 : bool GtkSalGraphics::NWPaintGTKSpinBox( ControlType nType, ControlPart nPart,
    2266             :                                         const Rectangle& rControlRectangle,
    2267             :                                         const clipList&,
    2268             :                                         ControlState nState,
    2269             :                                         const ImplControlValue& aValue,
    2270             :                                         const OUString& rCaption )
    2271             : {
    2272             :     GdkPixmap    *        pixmap;
    2273           0 :     Rectangle            pixmapRect;
    2274             :     GtkStateType        stateType;
    2275             :     GtkShadowType        shadowType;
    2276           0 :     const SpinbuttonValue *    pSpinVal = (aValue.getType() == CTRL_SPINBUTTONS) ? static_cast<const SpinbuttonValue *>(&aValue) : NULL;
    2277           0 :     Rectangle            upBtnRect;
    2278           0 :     ControlPart        upBtnPart = PART_BUTTON_UP;
    2279           0 :     ControlState        upBtnState = CTRL_STATE_ENABLED;
    2280           0 :     Rectangle            downBtnRect;
    2281           0 :     ControlPart        downBtnPart = PART_BUTTON_DOWN;
    2282           0 :     ControlState        downBtnState = CTRL_STATE_ENABLED;
    2283             : 
    2284           0 :     NWEnsureGTKButton( m_nXScreen );
    2285           0 :     NWEnsureGTKSpinButton( m_nXScreen );
    2286           0 :     NWEnsureGTKArrow( m_nXScreen );
    2287             : 
    2288           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    2289             : 
    2290           0 :     if ( pSpinVal )
    2291             :     {
    2292           0 :         upBtnPart = pSpinVal->mnUpperPart;
    2293           0 :         upBtnState = pSpinVal->mnUpperState;
    2294             : 
    2295           0 :         downBtnPart = pSpinVal->mnLowerPart;
    2296           0 :         downBtnState = pSpinVal->mnLowerState;
    2297             :     }
    2298             : 
    2299             :     // CTRL_SPINBUTTONS pass their area in pSpinVal, not in rControlRectangle
    2300           0 :     if ( nType == CTRL_SPINBUTTONS )
    2301             :     {
    2302           0 :         if ( !pSpinVal )
    2303             :         {
    2304           0 :             std::fprintf( stderr, "Tried to draw CTRL_SPINBUTTONS, but the SpinButtons data structure didn't exist!\n" );
    2305           0 :             return( false );
    2306             :         }
    2307           0 :         pixmapRect = pSpinVal->maUpperRect;
    2308           0 :         pixmapRect.Union( pSpinVal->maLowerRect );
    2309             :     }
    2310             :     else
    2311           0 :         pixmapRect = rControlRectangle;
    2312             : 
    2313           0 :     pixmap = NWGetPixmapFromScreen( pixmapRect );
    2314           0 :     if ( !pixmap )
    2315           0 :         return false;
    2316             : 
    2317             :     // First render background
    2318             :     gtk_paint_flat_box(m_pWindow->style,pixmap,GTK_STATE_NORMAL,GTK_SHADOW_NONE,NULL,m_pWindow,"base",
    2319           0 :             -pixmapRect.Left(),
    2320           0 :             -pixmapRect.Top(),
    2321           0 :             pixmapRect.Right(),
    2322           0 :             pixmapRect.Bottom() );
    2323             : 
    2324           0 :     upBtnRect = NWGetSpinButtonRect( m_nXScreen, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption );
    2325           0 :     downBtnRect = NWGetSpinButtonRect( m_nXScreen, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption );
    2326             : 
    2327           0 :     if ( (nType==CTRL_SPINBOX) && (nPart!=PART_ALL_BUTTONS) )
    2328             :     {
    2329             :         // Draw an edit field for SpinBoxes and ComboBoxes
    2330           0 :         Rectangle aEditBoxRect( pixmapRect );
    2331           0 :         aEditBoxRect.SetSize( Size( pixmapRect.GetWidth() - upBtnRect.GetWidth(), aEditBoxRect.GetHeight() ) );
    2332           0 :         if( Application::GetSettings().GetLayoutRTL() )
    2333           0 :             aEditBoxRect.setX( upBtnRect.GetWidth() );
    2334             :         else
    2335           0 :             aEditBoxRect.setX( 0 );
    2336           0 :         aEditBoxRect.setY( 0 );
    2337             : 
    2338           0 :         NWPaintOneEditBox( m_nXScreen, pixmap, NULL, nType, nPart, aEditBoxRect, nState, aValue, rCaption );
    2339             :     }
    2340             : 
    2341           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gSpinButtonWidget, nState, stateType );
    2342           0 :     gtk_widget_style_get( gWidgetData[m_nXScreen].gSpinButtonWidget, "shadow_type", &shadowType, (char *)NULL );
    2343             : 
    2344           0 :     if ( shadowType != GTK_SHADOW_NONE )
    2345             :     {
    2346           0 :         Rectangle        shadowRect( upBtnRect );
    2347             : 
    2348           0 :         shadowRect.Union( downBtnRect );
    2349           0 :         gtk_paint_box( gWidgetData[m_nXScreen].gSpinButtonWidget->style, pixmap, GTK_STATE_NORMAL, shadowType, NULL,
    2350           0 :             gWidgetData[m_nXScreen].gSpinButtonWidget, "spinbutton",
    2351           0 :             (shadowRect.Left() - pixmapRect.Left()), (shadowRect.Top() - pixmapRect.Top()),
    2352           0 :             shadowRect.GetWidth(), shadowRect.GetHeight() );
    2353             :     }
    2354             : 
    2355           0 :     NWPaintOneSpinButton( m_nXScreen, pixmap, nType, upBtnPart, pixmapRect, upBtnState, aValue, rCaption );
    2356           0 :     NWPaintOneSpinButton( m_nXScreen, pixmap, nType, downBtnPart, pixmapRect, downBtnState, aValue, rCaption );
    2357             : 
    2358           0 :     if( !NWRenderPixmapToScreen(pixmap, pixmapRect) )
    2359             :     {
    2360           0 :         g_object_unref( pixmap );
    2361           0 :         return false;
    2362             :     }
    2363             : 
    2364           0 :     g_object_unref( pixmap );
    2365           0 :     return true;
    2366             : }
    2367             : 
    2368           0 : static Rectangle NWGetSpinButtonRect( SalX11Screen nScreen,
    2369             :                                       ControlType,
    2370             :                                       ControlPart            nPart,
    2371             :                                       Rectangle             aAreaRect,
    2372             :                                       ControlState,
    2373             :                                       const ImplControlValue&,
    2374             :                                       const OUString& )
    2375             : {
    2376             :     gint            buttonSize;
    2377           0 :     Rectangle        buttonRect;
    2378             : 
    2379           0 :     NWEnsureGTKSpinButton( nScreen );
    2380             : 
    2381           0 :     buttonSize = MAX( PANGO_PIXELS( pango_font_description_get_size(GTK_WIDGET(gWidgetData[nScreen].gSpinButtonWidget)->style->font_desc) ),
    2382           0 :                    MIN_SPIN_ARROW_WIDTH );
    2383           0 :     buttonSize -= buttonSize % 2 - 1; /* force odd */
    2384           0 :     buttonRect.SetSize( Size( buttonSize + 2 * gWidgetData[nScreen].gSpinButtonWidget->style->xthickness,
    2385           0 :                               buttonRect.GetHeight() ) );
    2386           0 :     if( Application::GetSettings().GetLayoutRTL() )
    2387           0 :         buttonRect.setX( aAreaRect.Left() );
    2388             :     else
    2389           0 :         buttonRect.setX( aAreaRect.Left() + (aAreaRect.GetWidth() - buttonRect.GetWidth()) );
    2390           0 :     if ( nPart == PART_BUTTON_UP )
    2391             :     {
    2392           0 :         buttonRect.setY( aAreaRect.Top() );
    2393           0 :         buttonRect.Bottom() = buttonRect.Top() + (aAreaRect.GetHeight() / 2);
    2394             :     }
    2395           0 :     else if( nPart == PART_BUTTON_DOWN )
    2396             :     {
    2397           0 :         buttonRect.setY( aAreaRect.Top() + (aAreaRect.GetHeight() / 2) );
    2398           0 :         buttonRect.Bottom() = aAreaRect.Bottom(); // cover area completely
    2399             :     }
    2400             :     else
    2401             :     {
    2402           0 :         if( Application::GetSettings().GetLayoutRTL() ) {
    2403           0 :             buttonRect.Left()   = buttonRect.Right()+1;
    2404           0 :             buttonRect.Right()  = aAreaRect.Right();
    2405             :         } else {
    2406           0 :             buttonRect.Right()  = buttonRect.Left()-1;
    2407           0 :             buttonRect.Left()   = aAreaRect.Left();
    2408             :         }
    2409           0 :         buttonRect.Top()    = aAreaRect.Top();
    2410           0 :         buttonRect.Bottom() = aAreaRect.Bottom();
    2411             :     }
    2412             : 
    2413           0 :     return( buttonRect );
    2414             : }
    2415             : 
    2416           0 : static void NWPaintOneSpinButton( SalX11Screen nScreen,
    2417             :                                   GdkPixmap*            pixmap,
    2418             :                                   ControlType            nType,
    2419             :                                   ControlPart            nPart,
    2420             :                                   Rectangle                aAreaRect,
    2421             :                                   ControlState            nState,
    2422             :                                   const ImplControlValue&    aValue,
    2423             :                                   const OUString&                rCaption )
    2424             : {
    2425           0 :     Rectangle            buttonRect;
    2426             :     GtkStateType        stateType;
    2427             :     GtkShadowType        shadowType;
    2428           0 :     Rectangle            arrowRect;
    2429             :     gint                arrowSize;
    2430             : 
    2431           0 :     NWEnsureGTKSpinButton( nScreen );
    2432           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    2433             : 
    2434           0 :     buttonRect = NWGetSpinButtonRect( nScreen, nType, nPart, aAreaRect, nState, aValue, rCaption );
    2435             : 
    2436           0 :     NWSetWidgetState( gWidgetData[nScreen].gSpinButtonWidget, nState, stateType );
    2437           0 :     gtk_paint_box( gWidgetData[nScreen].gSpinButtonWidget->style, pixmap, stateType, shadowType, NULL, gWidgetData[nScreen].gSpinButtonWidget,
    2438             :             (nPart == PART_BUTTON_UP) ? "spinbutton_up" : "spinbutton_down",
    2439           0 :             (buttonRect.Left() - aAreaRect.Left()), (buttonRect.Top() - aAreaRect.Top()),
    2440           0 :             buttonRect.GetWidth(), buttonRect.GetHeight() );
    2441             : 
    2442           0 :     arrowSize = (buttonRect.GetWidth() - (2 * gWidgetData[nScreen].gSpinButtonWidget->style->xthickness)) - 4;
    2443           0 :     arrowSize -= arrowSize % 2 - 1; /* force odd */
    2444           0 :     arrowRect.SetSize( Size( arrowSize, arrowSize ) );
    2445           0 :     arrowRect.setX( buttonRect.Left() + (buttonRect.GetWidth() - arrowRect.GetWidth()) / 2 );
    2446           0 :     if ( nPart == PART_BUTTON_UP )
    2447           0 :         arrowRect.setY( buttonRect.Top() + (buttonRect.GetHeight() - arrowRect.GetHeight()) / 2 + 1);
    2448             :     else
    2449           0 :         arrowRect.setY( buttonRect.Top() + (buttonRect.GetHeight() - arrowRect.GetHeight()) / 2 - 1);
    2450             : 
    2451           0 :     gtk_paint_arrow( gWidgetData[nScreen].gSpinButtonWidget->style, pixmap, stateType, GTK_SHADOW_OUT, NULL, gWidgetData[nScreen].gSpinButtonWidget,
    2452             :             "spinbutton", (nPart == PART_BUTTON_UP) ? GTK_ARROW_UP : GTK_ARROW_DOWN, true,
    2453           0 :             (arrowRect.Left() - aAreaRect.Left()), (arrowRect.Top() - aAreaRect.Top()),
    2454           0 :             arrowRect.GetWidth(), arrowRect.GetHeight() );
    2455           0 : }
    2456             : 
    2457           0 : bool GtkSalGraphics::NWPaintGTKComboBox( GdkDrawable* gdkDrawable,
    2458             :                                          ControlType nType, ControlPart nPart,
    2459             :                                          const Rectangle& rControlRectangle,
    2460             :                                          const clipList& rClipList,
    2461             :                                          ControlState nState,
    2462             :                                          const ImplControlValue& aValue,
    2463             :                                          const OUString& rCaption )
    2464             : {
    2465           0 :     Rectangle        pixmapRect;
    2466           0 :     Rectangle        buttonRect;
    2467             :     GtkStateType    stateType;
    2468             :     GtkShadowType    shadowType;
    2469           0 :     Rectangle        arrowRect;
    2470             :     gint            x,y;
    2471             :     GdkRectangle    clipRect;
    2472             : 
    2473           0 :     NWEnsureGTKButton( m_nXScreen );
    2474           0 :     NWEnsureGTKArrow( m_nXScreen );
    2475           0 :     NWEnsureGTKCombo( m_nXScreen );
    2476           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    2477             : 
    2478             :     // Find the overall bounding rect of the buttons's drawing area,
    2479             :     // plus its actual draw rect excluding adornment
    2480           0 :     pixmapRect = rControlRectangle;
    2481           0 :     x = rControlRectangle.Left();
    2482           0 :     y = rControlRectangle.Top();
    2483             : 
    2484           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gBtnWidget, nState, stateType );
    2485           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gComboWidget, nState, stateType );
    2486           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gArrowWidget, nState, stateType );
    2487             : 
    2488           0 :     buttonRect = NWGetComboBoxButtonRect( m_nXScreen, nType, PART_BUTTON_DOWN, pixmapRect, nState, aValue, rCaption );
    2489           0 :     if( nPart == PART_BUTTON_DOWN )
    2490           0 :         buttonRect.Left() += 1;
    2491             : 
    2492           0 :     Rectangle        aEditBoxRect( pixmapRect );
    2493           0 :     aEditBoxRect.SetSize( Size( pixmapRect.GetWidth() - buttonRect.GetWidth(), aEditBoxRect.GetHeight() ) );
    2494           0 :     if( Application::GetSettings().GetLayoutRTL() )
    2495           0 :         aEditBoxRect.SetPos( Point( x + buttonRect.GetWidth() , y ) );
    2496             : 
    2497             :     #define ARROW_EXTENT        0.7
    2498             :     arrowRect.SetSize( Size( (gint)(MIN_ARROW_SIZE * ARROW_EXTENT),
    2499           0 :                              (gint)(MIN_ARROW_SIZE * ARROW_EXTENT) ) );
    2500           0 :     arrowRect.SetPos( Point( buttonRect.Left() + (gint)((buttonRect.GetWidth() - arrowRect.GetWidth()) / 2),
    2501           0 :                              buttonRect.Top() + (gint)((buttonRect.GetHeight() - arrowRect.GetHeight()) / 2) ) );
    2502             : 
    2503           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    2504             :     {
    2505           0 :         clipRect.x = it->Left();
    2506           0 :         clipRect.y = it->Top();
    2507           0 :         clipRect.width = it->GetWidth();
    2508           0 :         clipRect.height = it->GetHeight();
    2509             : 
    2510           0 :         if( nPart == PART_ENTIRE_CONTROL )
    2511             :             NWPaintOneEditBox( m_nXScreen, gdkDrawable, &clipRect, nType, nPart, aEditBoxRect,
    2512           0 :                                nState, aValue, rCaption );
    2513             : 
    2514             :         // Buttons must paint opaque since some themes have alpha-channel enabled buttons
    2515             :         gtk_paint_flat_box( m_pWindow->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
    2516             :                             &clipRect, m_pWindow, "base",
    2517           0 :                             x+(buttonRect.Left() - pixmapRect.Left()),
    2518           0 :                             y+(buttonRect.Top() - pixmapRect.Top()),
    2519           0 :                             buttonRect.GetWidth(), buttonRect.GetHeight() );
    2520           0 :         gtk_paint_box( GTK_COMBO(gWidgetData[m_nXScreen].gComboWidget)->button->style, gdkDrawable, stateType, shadowType,
    2521           0 :                        &clipRect, GTK_COMBO(gWidgetData[m_nXScreen].gComboWidget)->button, "button",
    2522           0 :                        x+(buttonRect.Left() - pixmapRect.Left()),
    2523           0 :                        y+(buttonRect.Top() - pixmapRect.Top()),
    2524           0 :                        buttonRect.GetWidth(), buttonRect.GetHeight() );
    2525             : 
    2526           0 :         gtk_paint_arrow( gWidgetData[m_nXScreen].gArrowWidget->style, gdkDrawable, stateType, shadowType,
    2527           0 :                          &clipRect, gWidgetData[m_nXScreen].gArrowWidget, "arrow", GTK_ARROW_DOWN, true,
    2528           0 :                          x+(arrowRect.Left() - pixmapRect.Left()), y+(arrowRect.Top() - pixmapRect.Top()),
    2529           0 :                          arrowRect.GetWidth(), arrowRect.GetHeight() );
    2530             :     }
    2531             : 
    2532           0 :     return true;
    2533             : }
    2534             : 
    2535           0 : static Rectangle NWGetComboBoxButtonRect( SalX11Screen nScreen,
    2536             :                                           ControlType,
    2537             :                                           ControlPart nPart,
    2538             :                                           Rectangle                aAreaRect,
    2539             :                                           ControlState,
    2540             :                                           const ImplControlValue&,
    2541             :                                           const OUString& )
    2542             : {
    2543           0 :     Rectangle    aButtonRect;
    2544             :     gint        nArrowWidth;
    2545             :     gint        nButtonWidth;
    2546             :     gint        nFocusWidth;
    2547             :     gint        nFocusPad;
    2548             : 
    2549           0 :     NWEnsureGTKArrow( nScreen );
    2550             : 
    2551             :     // Grab some button style attributes
    2552           0 :     gtk_widget_style_get( gWidgetData[nScreen].gDropdownWidget,
    2553             :                                       "focus-line-width",    &nFocusWidth,
    2554           0 :                                     "focus-padding",     &nFocusPad, (char *)NULL );
    2555             : 
    2556           0 :     nArrowWidth = MIN_ARROW_SIZE + (GTK_MISC(gWidgetData[nScreen].gArrowWidget)->xpad * 2);
    2557           0 :     nButtonWidth = nArrowWidth +
    2558           0 :                    ((BTN_CHILD_SPACING + gWidgetData[nScreen].gDropdownWidget->style->xthickness) * 2)
    2559           0 :                    + (2 * (nFocusWidth+nFocusPad));
    2560           0 :     if( nPart == PART_BUTTON_DOWN )
    2561             :     {
    2562           0 :         aButtonRect.SetSize( Size( nButtonWidth, aAreaRect.GetHeight() ) );
    2563           0 :         if( Application::GetSettings().GetLayoutRTL() )
    2564           0 :             aButtonRect.SetPos( Point( aAreaRect.Left(), aAreaRect.Top() ) );
    2565             :         else
    2566           0 :             aButtonRect.SetPos( Point( aAreaRect.Left() + aAreaRect.GetWidth() - nButtonWidth,
    2567           0 :                                        aAreaRect.Top() ) );
    2568             :     }
    2569           0 :     else if( nPart == PART_SUB_EDIT )
    2570             :     {
    2571           0 :         NWEnsureGTKCombo( nScreen );
    2572             : 
    2573           0 :         gint adjust_x = GTK_CONTAINER(gWidgetData[nScreen].gComboWidget)->border_width +
    2574           0 :                         nFocusWidth +
    2575           0 :                         nFocusPad;
    2576           0 :         gint adjust_y = adjust_x + gWidgetData[nScreen].gComboWidget->style->ythickness;
    2577           0 :         adjust_x     += gWidgetData[nScreen].gComboWidget->style->xthickness;
    2578           0 :         aButtonRect.SetSize( Size( aAreaRect.GetWidth() - nButtonWidth - 2 * adjust_x,
    2579           0 :                                    aAreaRect.GetHeight() - 2 * adjust_y ) );
    2580           0 :         Point aEditPos = aAreaRect.TopLeft();
    2581           0 :         aEditPos.X() += adjust_x;
    2582           0 :         aEditPos.Y() += adjust_y;
    2583           0 :         if( Application::GetSettings().GetLayoutRTL() )
    2584           0 :             aEditPos.X() += nButtonWidth;
    2585           0 :         aButtonRect.SetPos( aEditPos );
    2586             :     }
    2587             : 
    2588           0 :     return( aButtonRect );
    2589             : }
    2590             : 
    2591           0 : bool GtkSalGraphics::NWPaintGTKTabItem( ControlType nType, ControlPart,
    2592             :                                         const Rectangle& rControlRectangle,
    2593             :                                         const clipList&,
    2594             :                                         ControlState nState,
    2595             :                                         const ImplControlValue& aValue,
    2596             :                                         const OUString& )
    2597             : {
    2598             :     OSL_ASSERT( nType != CTRL_TAB_ITEM || aValue.getType() == CTRL_TAB_ITEM );
    2599             :     GdkPixmap *    pixmap;
    2600           0 :     Rectangle        pixmapRect;
    2601           0 :     Rectangle        tabRect;
    2602             :     GtkStateType    stateType;
    2603             :     GtkShadowType    shadowType;
    2604           0 :     if( ! gWidgetData[ m_nXScreen ].gCacheTabItems )
    2605             :     {
    2606           0 :         gWidgetData[ m_nXScreen ].gCacheTabItems = new NWPixmapCache( m_nXScreen );
    2607           0 :         gWidgetData[ m_nXScreen ].gCacheTabPages = new NWPixmapCache( m_nXScreen );
    2608             :     }
    2609           0 :     NWPixmapCache& aCacheItems = *gWidgetData[ m_nXScreen ].gCacheTabItems;
    2610           0 :     NWPixmapCache& aCachePage = *gWidgetData[ m_nXScreen ].gCacheTabPages;
    2611             : 
    2612           0 :     if( !aCacheItems.GetSize() )
    2613           0 :         aCacheItems.SetSize( 20 );
    2614           0 :     if( !aCachePage.GetSize() )
    2615           0 :         aCachePage.SetSize( 1 );
    2616             : 
    2617           0 :     if ( (nType == CTRL_TAB_ITEM) && (aValue.getType() != CTRL_TAB_ITEM) )
    2618             :     {
    2619           0 :         return( false );
    2620             :     }
    2621             : 
    2622           0 :     NWEnsureGTKButton( m_nXScreen );
    2623           0 :     NWEnsureGTKNotebook( m_nXScreen );
    2624           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    2625             : 
    2626             :     // Find the overall bounding rect of the buttons's drawing area,
    2627             :     // plus its actual draw rect excluding adornment
    2628           0 :     pixmapRect = rControlRectangle;
    2629           0 :     if ( nType == CTRL_TAB_ITEM )
    2630             :     {
    2631           0 :         const TabitemValue *    pTabitemValue = static_cast<const TabitemValue *>(&aValue);
    2632           0 :         if ( !pTabitemValue->isFirst() )
    2633             :         {
    2634             :             // GTK+ tabs overlap on the right edge (the top tab obscures the
    2635             :             // left edge of the tab right "below" it, so adjust the rectangle
    2636             :             // to draw tabs slightly large so the overlap happens
    2637           0 :             pixmapRect.Move( -2, 0 );
    2638           0 :             pixmapRect.SetSize( Size( pixmapRect.GetWidth() + 2, pixmapRect.GetHeight() ) );
    2639             :         }
    2640           0 :         if ( nState & CTRL_STATE_SELECTED )
    2641             :         {
    2642             :             // In GTK+, the selected tab is 2px taller than all other tabs
    2643           0 :             pixmapRect.Move( 0, -2 );
    2644           0 :             pixmapRect.Bottom() += 2;
    2645           0 :             tabRect = pixmapRect;
    2646             :             // Only draw over 1 pixel of the tab pane that this tab is drawn on top of.
    2647           0 :             tabRect.Bottom() -= 1;
    2648             :         }
    2649             :         else
    2650           0 :             tabRect = pixmapRect;
    2651             : 
    2652             :         // Allow the tab to draw a right border if needed
    2653           0 :         tabRect.Right() -= 1;
    2654             : 
    2655             :         // avoid degenerate cases which might lead to crashes
    2656           0 :         if( tabRect.GetWidth() <= 1 || tabRect.GetHeight() <= 1 )
    2657           0 :             return false;
    2658             :     }
    2659             : 
    2660           0 :     if( nType == CTRL_TAB_ITEM )
    2661             :     {
    2662           0 :         if( aCacheItems.Find( nType, nState, pixmapRect, &pixmap ) )
    2663           0 :             return NWRenderPixmapToScreen( pixmap, pixmapRect );
    2664             :     }
    2665             :     else
    2666             :     {
    2667           0 :         if( aCachePage.Find( nType, nState, pixmapRect, &pixmap ) )
    2668           0 :             return NWRenderPixmapToScreen( pixmap, pixmapRect );
    2669             :     }
    2670             : 
    2671           0 :     pixmap = gdk_pixmap_new( NULL, pixmapRect.GetWidth(), pixmapRect.GetHeight(),
    2672           0 :                              GetGenericData()->GetSalDisplay()->GetVisual( m_nXScreen ).GetDepth() );
    2673             :     GdkRectangle paintRect;
    2674           0 :     paintRect.x = paintRect.y = 0;
    2675           0 :     paintRect.width = pixmapRect.GetWidth();
    2676           0 :     paintRect.height = pixmapRect.GetHeight();
    2677             : 
    2678             :     gtk_paint_flat_box( m_pWindow->style, pixmap, GTK_STATE_NORMAL,
    2679             :                         GTK_SHADOW_NONE, &paintRect, m_pWindow, "base",
    2680           0 :                         -rControlRectangle.Left(),
    2681           0 :                         -rControlRectangle.Top(),
    2682           0 :                         pixmapRect.GetWidth()+rControlRectangle.Left(),
    2683           0 :                         pixmapRect.GetHeight()+rControlRectangle.Top());
    2684             : 
    2685           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gNotebookWidget, nState, stateType );
    2686             : 
    2687           0 :     switch( nType )
    2688             :     {
    2689             :         case CTRL_TAB_BODY:
    2690           0 :             break;
    2691             : 
    2692             :         case CTRL_TAB_PANE:
    2693           0 :             gtk_paint_box_gap( gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
    2694           0 :                 (char *)"notebook", 0, 0, pixmapRect.GetWidth(), pixmapRect.GetHeight(), GTK_POS_TOP, 0, 0 );
    2695           0 :             break;
    2696             : 
    2697             :         case CTRL_TAB_ITEM:
    2698             :         {
    2699           0 :             stateType = ( nState & CTRL_STATE_SELECTED ) ? GTK_STATE_NORMAL : GTK_STATE_ACTIVE;
    2700             : 
    2701             :             // First draw the background
    2702           0 :             gtk_paint_flat_box(gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap,
    2703             :                                    GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, m_pWindow, "base",
    2704           0 :                                    -rControlRectangle.Left(),
    2705           0 :                                    -rControlRectangle.Top(),
    2706           0 :                                    pixmapRect.GetWidth()+rControlRectangle.Left(),
    2707           0 :                                    pixmapRect.GetHeight()+rControlRectangle.Top());
    2708             : 
    2709             :             // Now the tab itself
    2710           0 :             if( nState & CTRL_STATE_ROLLOVER )
    2711           0 :                 g_object_set_data(G_OBJECT(pixmap),tabPrelitDataName,(gpointer)TRUE);
    2712             : 
    2713           0 :             gtk_paint_extension( gWidgetData[m_nXScreen].gNotebookWidget->style, pixmap, stateType, GTK_SHADOW_OUT, NULL, gWidgetData[m_nXScreen].gNotebookWidget,
    2714           0 :                 (char *)"tab", (tabRect.Left() - pixmapRect.Left()), (tabRect.Top() - pixmapRect.Top()),
    2715           0 :                 tabRect.GetWidth(), tabRect.GetHeight(), GTK_POS_BOTTOM );
    2716             : 
    2717           0 :             g_object_steal_data(G_OBJECT(pixmap),tabPrelitDataName);
    2718             : 
    2719           0 :             if ( nState & CTRL_STATE_SELECTED )
    2720             :             {
    2721             :                 gtk_paint_flat_box( m_pWindow->style, pixmap, stateType, GTK_SHADOW_NONE, NULL, m_pWindow,
    2722           0 :                     "base", 0, (pixmapRect.GetHeight() - 1), pixmapRect.GetWidth(), 1 );
    2723             :             }
    2724           0 :             break;
    2725             :         }
    2726             : 
    2727             :         default:
    2728           0 :             break;
    2729             :     }
    2730             : 
    2731             :     // cache data
    2732           0 :     if( nType == CTRL_TAB_ITEM )
    2733           0 :         aCacheItems.Fill( nType, nState, pixmapRect, pixmap );
    2734             :     else
    2735           0 :         aCachePage.Fill( nType, nState, pixmapRect, pixmap );
    2736             : 
    2737           0 :     bool bSuccess = NWRenderPixmapToScreen(pixmap, pixmapRect);
    2738           0 :     g_object_unref( pixmap );
    2739           0 :     return bSuccess;
    2740             : }
    2741             : 
    2742           0 : bool GtkSalGraphics::NWPaintGTKListBox( GdkDrawable* gdkDrawable,
    2743             :                                         ControlType nType, ControlPart nPart,
    2744             :                                         const Rectangle& rControlRectangle,
    2745             :                                         const clipList& rClipList,
    2746             :                                         ControlState nState,
    2747             :                                         const ImplControlValue& aValue,
    2748             :                                         const OUString& rCaption )
    2749             : {
    2750           0 :     Rectangle        aIndicatorRect;
    2751             :     GtkStateType    stateType;
    2752             :     GtkShadowType    shadowType;
    2753             :     gint            bInteriorFocus;
    2754             :     gint            nFocusLineWidth;
    2755             :     gint            nFocusPadding;
    2756             :     gint            x,y,w,h;
    2757             :     GdkRectangle    clipRect;
    2758             : 
    2759           0 :     NWEnsureGTKButton( m_nXScreen );
    2760           0 :     NWEnsureGTKOptionMenu( m_nXScreen );
    2761           0 :     NWEnsureGTKScrolledWindow( m_nXScreen );
    2762           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    2763             : 
    2764             :     // set up references to correct drawable and cliprect
    2765           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gBtnWidget, nState, stateType );
    2766           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gOptionMenuWidget, nState, stateType );
    2767           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gScrolledWindowWidget, nState, stateType );
    2768             : 
    2769           0 :     x = rControlRectangle.Left();
    2770           0 :     y = rControlRectangle.Top();
    2771           0 :     w = rControlRectangle.GetWidth();
    2772           0 :     h = rControlRectangle.GetHeight();
    2773             : 
    2774           0 :     if ( nPart != PART_WINDOW )
    2775             :     {
    2776           0 :         gtk_widget_style_get( gWidgetData[m_nXScreen].gOptionMenuWidget,
    2777             :             "interior_focus",    &bInteriorFocus,
    2778             :             "focus_line_width",    &nFocusLineWidth,
    2779             :             "focus_padding",    &nFocusPadding,
    2780           0 :             (char *)NULL);
    2781             :     }
    2782             : 
    2783           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    2784             :     {
    2785           0 :         clipRect.x = it->Left();
    2786           0 :         clipRect.y = it->Top();
    2787           0 :         clipRect.width = it->GetWidth();
    2788           0 :         clipRect.height = it->GetHeight();
    2789             : 
    2790           0 :         if ( nPart != PART_WINDOW )
    2791             :         {
    2792             :             // Listboxes must paint opaque since some themes have alpha-channel enabled bodies
    2793             :             gtk_paint_flat_box( m_pWindow->style, gdkDrawable, GTK_STATE_NORMAL, GTK_SHADOW_NONE,
    2794           0 :                                 &clipRect, m_pWindow, "base", x, y, w, h);
    2795           0 :             gtk_paint_box( gWidgetData[m_nXScreen].gOptionMenuWidget->style, gdkDrawable, stateType, shadowType, &clipRect,
    2796           0 :                            gWidgetData[m_nXScreen].gOptionMenuWidget, "optionmenu",
    2797           0 :                            x, y, w, h);
    2798             :             aIndicatorRect = NWGetListBoxIndicatorRect( m_nXScreen, nType, nPart, rControlRectangle, nState,
    2799           0 :                                                         aValue, rCaption );
    2800           0 :             gtk_paint_tab( gWidgetData[m_nXScreen].gOptionMenuWidget->style, gdkDrawable, stateType, shadowType, &clipRect,
    2801           0 :                            gWidgetData[m_nXScreen].gOptionMenuWidget, "optionmenutab",
    2802           0 :                            aIndicatorRect.Left(), aIndicatorRect.Top(),
    2803           0 :                            aIndicatorRect.GetWidth(), aIndicatorRect.GetHeight() );
    2804             :         }
    2805             :         else
    2806             :         {
    2807           0 :             shadowType = GTK_SHADOW_IN;
    2808             : 
    2809           0 :             gtk_paint_shadow( gWidgetData[m_nXScreen].gScrolledWindowWidget->style, gdkDrawable, GTK_STATE_NORMAL, shadowType,
    2810           0 :                 &clipRect, gWidgetData[m_nXScreen].gScrolledWindowWidget, "scrolled_window",
    2811           0 :                 x, y, w, h );
    2812             :         }
    2813             :     }
    2814             : 
    2815           0 :     return true;
    2816             : }
    2817             : 
    2818           0 : bool GtkSalGraphics::NWPaintGTKToolbar(
    2819             :             GdkDrawable* gdkDrawable,
    2820             :             ControlType, ControlPart nPart,
    2821             :             const Rectangle& rControlRectangle,
    2822             :             const clipList& rClipList,
    2823             :             ControlState nState, const ImplControlValue& aValue,
    2824             :             const OUString& string)
    2825             : {
    2826             :     GtkStateType    stateType;
    2827             :     GtkShadowType    shadowType;
    2828             :     gint            x, y, w, h;
    2829           0 :     gint            g_x=0, g_y=0, g_w=10, g_h=10;
    2830           0 :     GtkWidget*      pButtonWidget = gWidgetData[m_nXScreen].gToolbarButtonWidget;
    2831             :     GdkRectangle    clipRect;
    2832             : 
    2833           0 :     NWEnsureGTKToolbar( m_nXScreen );
    2834           0 :     if( nPart == PART_BUTTON ) // toolbar buttons cannot focus in gtk
    2835           0 :         nState &= ~CTRL_STATE_FOCUSED;
    2836           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    2837             : 
    2838           0 :     x = rControlRectangle.Left();
    2839           0 :     y = rControlRectangle.Top();
    2840           0 :     w = rControlRectangle.GetWidth();
    2841           0 :     h = rControlRectangle.GetHeight();
    2842             : 
    2843             :     // handle toolbar
    2844           0 :     if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT )
    2845             :     {
    2846           0 :         NWSetWidgetState( gWidgetData[m_nXScreen].gToolbarWidget, nState, stateType );
    2847             : 
    2848           0 :         GTK_WIDGET_UNSET_FLAGS( gWidgetData[m_nXScreen].gToolbarWidget, GTK_SENSITIVE );
    2849           0 :         if ( nState & CTRL_STATE_ENABLED )
    2850           0 :             GTK_WIDGET_SET_FLAGS( gWidgetData[m_nXScreen].gToolbarWidget, GTK_SENSITIVE );
    2851             : 
    2852           0 :         if( nPart == PART_DRAW_BACKGROUND_HORZ )
    2853           0 :             gtk_toolbar_set_orientation( GTK_TOOLBAR(gWidgetData[m_nXScreen].gToolbarWidget), GTK_ORIENTATION_HORIZONTAL );
    2854             :         else
    2855           0 :             gtk_toolbar_set_orientation( GTK_TOOLBAR(gWidgetData[m_nXScreen].gToolbarWidget), GTK_ORIENTATION_VERTICAL );
    2856             :     }
    2857             :     // handle grip
    2858           0 :     else if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT )
    2859             :     {
    2860           0 :         NWSetWidgetState( gWidgetData[m_nXScreen].gHandleBoxWidget, nState, stateType );
    2861             : 
    2862           0 :         GTK_WIDGET_UNSET_FLAGS( gWidgetData[m_nXScreen].gHandleBoxWidget, GTK_SENSITIVE );
    2863           0 :         if ( nState & CTRL_STATE_ENABLED )
    2864           0 :             GTK_WIDGET_SET_FLAGS( gWidgetData[m_nXScreen].gHandleBoxWidget, GTK_SENSITIVE );
    2865             : 
    2866           0 :         gtk_handle_box_set_shadow_type( GTK_HANDLE_BOX(gWidgetData[m_nXScreen].gHandleBoxWidget), shadowType );
    2867             : 
    2868             :         // evaluate grip rect
    2869           0 :         if( aValue.getType() == CTRL_TOOLBAR )
    2870             :         {
    2871           0 :             const ToolbarValue* pVal = static_cast<const ToolbarValue*>(&aValue);
    2872           0 :             g_x = pVal->maGripRect.Left();
    2873           0 :             g_y = pVal->maGripRect.Top();
    2874           0 :             g_w = pVal->maGripRect.GetWidth();
    2875           0 :             g_h = pVal->maGripRect.GetHeight();
    2876           0 :         }
    2877             :     }
    2878             :     // handle button
    2879           0 :     else if( nPart == PART_BUTTON )
    2880             :     {
    2881           0 :         bool bPaintButton = (nState & CTRL_STATE_PRESSED)
    2882           0 :             || (nState & CTRL_STATE_ROLLOVER);
    2883           0 :         if( aValue.getTristateVal() == BUTTONVALUE_ON )
    2884             :         {
    2885           0 :             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pButtonWidget),TRUE);
    2886           0 :             bPaintButton = true;
    2887             :         }
    2888             :         else
    2889           0 :             gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pButtonWidget),FALSE);
    2890             : 
    2891           0 :         NWSetWidgetState( pButtonWidget, nState, stateType );
    2892           0 :         gtk_widget_ensure_style( pButtonWidget );
    2893           0 :         if(bPaintButton)
    2894           0 :             NWPaintGTKButtonReal(pButtonWidget, gdkDrawable, 0, 0, rControlRectangle, rClipList, nState, aValue, string);
    2895             :     }
    2896             : 
    2897           0 :     if( nPart != PART_BUTTON )
    2898             :     {
    2899           0 :         for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    2900             :         {
    2901           0 :             clipRect.x = it->Left();
    2902           0 :             clipRect.y = it->Top();
    2903           0 :             clipRect.width = it->GetWidth();
    2904           0 :             clipRect.height = it->GetHeight();
    2905             : 
    2906             :             // draw toolbar
    2907           0 :             if( nPart == PART_DRAW_BACKGROUND_HORZ || nPart == PART_DRAW_BACKGROUND_VERT )
    2908             :             {
    2909           0 :                 gtk_paint_flat_box( gWidgetData[m_nXScreen].gToolbarWidget->style,
    2910             :                                     gdkDrawable,
    2911             :                                     (GtkStateType)GTK_STATE_NORMAL,
    2912             :                                     GTK_SHADOW_NONE,
    2913             :                                     &clipRect,
    2914           0 :                                     gWidgetData[m_nXScreen].gToolbarWidget,
    2915             :                                     "base",
    2916           0 :                                     x, y, w, h );
    2917           0 :                 gtk_paint_box( gWidgetData[m_nXScreen].gToolbarWidget->style,
    2918             :                                gdkDrawable,
    2919             :                                stateType,
    2920             :                                shadowType,
    2921             :                                &clipRect,
    2922           0 :                                gWidgetData[m_nXScreen].gToolbarWidget,
    2923             :                                "toolbar",
    2924           0 :                                x, y, w, h );
    2925             :             }
    2926             :             // draw grip
    2927           0 :             else if( nPart == PART_THUMB_HORZ || nPart == PART_THUMB_VERT )
    2928             :             {
    2929           0 :                 gtk_paint_handle( gWidgetData[m_nXScreen].gHandleBoxWidget->style,
    2930             :                                   gdkDrawable,
    2931             :                                   GTK_STATE_NORMAL,
    2932             :                                   GTK_SHADOW_OUT,
    2933             :                                   &clipRect,
    2934           0 :                                   gWidgetData[m_nXScreen].gHandleBoxWidget,
    2935             :                                   "handlebox",
    2936             :                                   g_x, g_y, g_w, g_h,
    2937             :                                   nPart == PART_THUMB_HORZ ?
    2938             :                                   GTK_ORIENTATION_HORIZONTAL :
    2939             :                                   GTK_ORIENTATION_VERTICAL
    2940           0 :                                   );
    2941             :             }
    2942           0 :             else if( nPart == PART_SEPARATOR_HORZ || nPart == PART_SEPARATOR_VERT )
    2943             :             {
    2944           0 :                 const double shim = 0.2;
    2945             : 
    2946             : #if GTK_CHECK_VERSION(2,10,0)
    2947           0 :                 gint separator_height, separator_width, wide_separators = 0;
    2948             : 
    2949           0 :                 gtk_widget_style_get (gWidgetData[m_nXScreen].gSeparator,
    2950             :                                       "wide-separators",  &wide_separators,
    2951             :                                       "separator-width",  &separator_width,
    2952             :                                       "separator-height", &separator_height,
    2953           0 :                                       NULL);
    2954             : 
    2955           0 :                 if (wide_separators)
    2956             :                 {
    2957           0 :                     if (nPart == PART_SEPARATOR_VERT)
    2958           0 :                         gtk_paint_box (gWidgetData[m_nXScreen].gSeparator->style, gdkDrawable,
    2959             :                                        GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
    2960           0 :                                        &clipRect, gWidgetData[m_nXScreen].gSeparator, "vseparator",
    2961           0 :                                        x + (w - separator_width) / 2, y + h * shim,
    2962           0 :                                        separator_width, h * (1 - 2*shim));
    2963             :                     else
    2964           0 :                         gtk_paint_box (gWidgetData[m_nXScreen].gSeparator->style, gdkDrawable,
    2965             :                                        GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT,
    2966           0 :                                        &clipRect, gWidgetData[m_nXScreen].gSeparator, "hseparator",
    2967           0 :                                        x + w * shim, y + (h - separator_width) / 2,
    2968           0 :                                        w * (1 - 2*shim), separator_width);
    2969             :                 }
    2970             :                 else
    2971             : #endif
    2972             :                 {
    2973           0 :                     if (nPart == PART_SEPARATOR_VERT)
    2974           0 :                         gtk_paint_vline (gWidgetData[m_nXScreen].gSeparator->style, gdkDrawable,
    2975             :                                          GTK_STATE_NORMAL,
    2976           0 :                                          &clipRect, gWidgetData[m_nXScreen].gSeparator, "vseparator",
    2977           0 :                                          y + h * shim, y + h * (1 - shim), x + w/2 - 1);
    2978             :                     else
    2979           0 :                         gtk_paint_hline (gWidgetData[m_nXScreen].gSeparator->style, gdkDrawable,
    2980             :                                          GTK_STATE_NORMAL,
    2981           0 :                                          &clipRect, gWidgetData[m_nXScreen].gSeparator, "hseparator",
    2982           0 :                                          x + w * shim, x + w * (1 - shim), y + h/2 - 1);
    2983             :                 }
    2984             :             }
    2985             :         }
    2986             :     }
    2987             : 
    2988           0 :     return true;
    2989             : }
    2990             : 
    2991           0 : bool GtkSalGraphics::NWPaintGTKMenubar(
    2992             :             GdkDrawable* gdkDrawable,
    2993             :             ControlType, ControlPart nPart,
    2994             :             const Rectangle& rControlRectangle,
    2995             :             const clipList& rClipList,
    2996             :             ControlState nState, const ImplControlValue&,
    2997             :             const OUString& )
    2998             : {
    2999             :     GtkStateType    stateType;
    3000             :     GtkShadowType    shadowType;
    3001           0 :     GtkShadowType   selected_shadow_type = GTK_SHADOW_OUT;
    3002             :     gint            x, y, w, h;
    3003             :     GdkRectangle    clipRect;
    3004             : 
    3005           0 :     NWEnsureGTKMenubar( m_nXScreen );
    3006           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    3007             : 
    3008           0 :     x = rControlRectangle.Left();
    3009           0 :     y = rControlRectangle.Top();
    3010           0 :     w = rControlRectangle.GetWidth();
    3011           0 :     h = rControlRectangle.GetHeight();
    3012             : 
    3013           0 :     if( nPart == PART_MENU_ITEM )
    3014             :     {
    3015           0 :         if( nState & CTRL_STATE_SELECTED )
    3016             :         {
    3017           0 :             gtk_widget_style_get( gWidgetData[m_nXScreen].gMenuItemMenubarWidget,
    3018             :                                   "selected_shadow_type", &selected_shadow_type,
    3019           0 :                                   (char *)NULL);
    3020             :         }
    3021             :     }
    3022             : 
    3023           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    3024             :     {
    3025           0 :         clipRect.x = it->Left();
    3026           0 :         clipRect.y = it->Top();
    3027           0 :         clipRect.width = it->GetWidth();
    3028           0 :         clipRect.height = it->GetHeight();
    3029             : 
    3030             :         // handle Menubar
    3031           0 :         if( nPart == PART_ENTIRE_CONTROL )
    3032             :         {
    3033           0 :             NWSetWidgetState( gWidgetData[m_nXScreen].gMenubarWidget, nState, stateType );
    3034             : 
    3035           0 :             GTK_WIDGET_UNSET_FLAGS( gWidgetData[m_nXScreen].gMenubarWidget, GTK_SENSITIVE );
    3036           0 :             if ( nState & CTRL_STATE_ENABLED )
    3037           0 :                 GTK_WIDGET_SET_FLAGS( gWidgetData[m_nXScreen].gMenubarWidget, GTK_SENSITIVE );
    3038             : 
    3039             :             // for translucent menubar styles paint background first
    3040           0 :             gtk_paint_flat_box( gWidgetData[m_nXScreen].gMenubarWidget->style,
    3041             :                                 gdkDrawable,
    3042             :                                 GTK_STATE_NORMAL,
    3043             :                                 GTK_SHADOW_NONE,
    3044             :                                 &clipRect,
    3045           0 :                                 GTK_WIDGET(m_pWindow),
    3046             :                                 "base",
    3047           0 :                                 x, y, w, h );
    3048           0 :             gtk_paint_box( gWidgetData[m_nXScreen].gMenubarWidget->style,
    3049             :                            gdkDrawable,
    3050             :                            stateType,
    3051             :                            shadowType,
    3052             :                            &clipRect,
    3053           0 :                            gWidgetData[m_nXScreen].gMenubarWidget,
    3054             :                            "menubar",
    3055           0 :                            x, y, w, h );
    3056             :         }
    3057             : 
    3058           0 :         else if( nPart == PART_MENU_ITEM )
    3059             :         {
    3060           0 :             if( nState & CTRL_STATE_SELECTED )
    3061             :             {
    3062           0 :                 gtk_paint_box( gWidgetData[m_nXScreen].gMenuItemMenubarWidget->style,
    3063             :                                gdkDrawable,
    3064             :                                GTK_STATE_PRELIGHT,
    3065             :                                selected_shadow_type,
    3066             :                                &clipRect,
    3067           0 :                                gWidgetData[m_nXScreen].gMenuItemMenubarWidget,
    3068             :                                "menuitem",
    3069           0 :                                x, y, w, h);
    3070             :             }
    3071             :         }
    3072             :     }
    3073             : 
    3074           0 :     return true;
    3075             : }
    3076             : 
    3077           0 : bool GtkSalGraphics::NWPaintGTKPopupMenu(
    3078             :             GdkDrawable* gdkDrawable,
    3079             :             ControlType, ControlPart nPart,
    3080             :             const Rectangle& rControlRectangle,
    3081             :             const clipList& rClipList,
    3082             :             ControlState nState, const ImplControlValue&,
    3083             :             const OUString& )
    3084             : {
    3085             :     // #i50745# gtk does not draw disabled menu entries (and crux theme
    3086             :     // even crashes) in very old (Fedora Core 4 vintage) gtk's
    3087           0 :     if (gtk_major_version <= 2 && gtk_minor_version <= 8 &&
    3088           0 :         nPart == PART_MENU_ITEM && ! (nState & CTRL_STATE_ENABLED) )
    3089           0 :         return true;
    3090             : 
    3091             :     GtkStateType    stateType;
    3092             :     GtkShadowType    shadowType;
    3093           0 :     GtkShadowType   selected_shadow_type = GTK_SHADOW_OUT;
    3094             :     gint            x, y, w, h;
    3095             :     GdkRectangle    clipRect;
    3096             : 
    3097           0 :     NWEnsureGTKMenu( m_nXScreen );
    3098           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    3099             : 
    3100           0 :     x = rControlRectangle.Left();
    3101           0 :     y = rControlRectangle.Top();
    3102           0 :     w = rControlRectangle.GetWidth();
    3103           0 :     h = rControlRectangle.GetHeight();
    3104             : 
    3105           0 :     if( nPart == PART_MENU_ITEM &&
    3106           0 :         ( nState & (CTRL_STATE_SELECTED|CTRL_STATE_ROLLOVER) ) )
    3107             :     {
    3108           0 :         gtk_widget_style_get( gWidgetData[m_nXScreen].gMenuItemMenuWidget,
    3109             :                               "selected_shadow_type", &selected_shadow_type,
    3110           0 :                               (char *)NULL);
    3111             :     }
    3112             : 
    3113           0 :     NWSetWidgetState( gWidgetData[m_nXScreen].gMenuWidget, nState, stateType );
    3114             : 
    3115           0 :     GTK_WIDGET_UNSET_FLAGS( gWidgetData[m_nXScreen].gMenuWidget, GTK_SENSITIVE );
    3116           0 :     if ( nState & CTRL_STATE_ENABLED )
    3117           0 :         GTK_WIDGET_SET_FLAGS( gWidgetData[m_nXScreen].gMenuWidget, GTK_SENSITIVE );
    3118             : 
    3119           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    3120             :     {
    3121           0 :         clipRect.x = it->Left();
    3122           0 :         clipRect.y = it->Top();
    3123           0 :         clipRect.width = it->GetWidth();
    3124           0 :         clipRect.height = it->GetHeight();
    3125             : 
    3126           0 :         if( nPart == PART_ENTIRE_CONTROL )
    3127             :         {
    3128             :             // for translucent menubar styles paint background first
    3129           0 :             gtk_paint_flat_box( gWidgetData[m_nXScreen].gMenuWidget->style,
    3130             :                                 gdkDrawable,
    3131             :                                 GTK_STATE_NORMAL,
    3132             :                                 GTK_SHADOW_NONE,
    3133             :                                 &clipRect,
    3134           0 :                                 GTK_WIDGET(m_pWindow),
    3135             :                                 "base",
    3136           0 :                                 x, y, w, h );
    3137           0 :             gtk_paint_box( gWidgetData[m_nXScreen].gMenuWidget->style,
    3138             :                            gdkDrawable,
    3139             :                            GTK_STATE_NORMAL,
    3140             :                            GTK_SHADOW_OUT,
    3141             :                            &clipRect,
    3142           0 :                            gWidgetData[m_nXScreen].gMenuWidget,
    3143             :                            "menu",
    3144           0 :                            x, y, w, h );
    3145             :         }
    3146           0 :         else if( nPart == PART_MENU_ITEM )
    3147             :         {
    3148           0 :             if( nState & (CTRL_STATE_SELECTED|CTRL_STATE_ROLLOVER) )
    3149             :             {
    3150           0 :                 if( nState & CTRL_STATE_ENABLED )
    3151           0 :                 gtk_paint_box( gWidgetData[m_nXScreen].gMenuItemMenuWidget->style,
    3152             :                                gdkDrawable,
    3153             :                                GTK_STATE_PRELIGHT,
    3154             :                                selected_shadow_type,
    3155             :                                &clipRect,
    3156           0 :                                gWidgetData[m_nXScreen].gMenuItemMenuWidget,
    3157             :                                "menuitem",
    3158           0 :                                x, y, w, h);
    3159             :             }
    3160             :         }
    3161           0 :         else if( nPart == PART_MENU_ITEM_CHECK_MARK || nPart == PART_MENU_ITEM_RADIO_MARK )
    3162             :         {
    3163             :             GtkWidget* pWidget = (nPart == PART_MENU_ITEM_CHECK_MARK) ?
    3164           0 :                                  gWidgetData[m_nXScreen].gMenuItemCheckMenuWidget :
    3165           0 :                                  gWidgetData[m_nXScreen].gMenuItemRadioMenuWidget;
    3166             : 
    3167             :             GtkStateType nStateType;
    3168             :             GtkShadowType nShadowType;
    3169           0 :             NWConvertVCLStateToGTKState( nState, &nStateType, &nShadowType );
    3170             : 
    3171           0 :             if ( (nState & CTRL_STATE_SELECTED) && (nState & CTRL_STATE_ENABLED) )
    3172           0 :                 nStateType = GTK_STATE_PRELIGHT;
    3173             : 
    3174           0 :             NWSetWidgetState( pWidget, nState, nStateType );
    3175             : 
    3176           0 :             if ( nPart == PART_MENU_ITEM_CHECK_MARK )
    3177             :             {
    3178             :                 gtk_paint_check( pWidget->style,
    3179             :                                  gdkDrawable,
    3180             :                                  nStateType,
    3181             :                                  nShadowType,
    3182             :                                  &clipRect,
    3183           0 :                                  gWidgetData[m_nXScreen].gMenuItemMenuWidget,
    3184             :                                  "check",
    3185           0 :                                  x, y, w, h );
    3186             :             }
    3187             :             else
    3188             :             {
    3189             :                 gtk_paint_option( pWidget->style,
    3190             :                                   gdkDrawable,
    3191             :                                   nStateType,
    3192             :                                   nShadowType,
    3193             :                                   &clipRect,
    3194           0 :                                   gWidgetData[m_nXScreen].gMenuItemMenuWidget,
    3195             :                                   "option",
    3196           0 :                                   x, y, w, h );
    3197           0 :             }
    3198             :         }
    3199           0 :         else if( nPart == PART_MENU_SEPARATOR )
    3200             :         {
    3201           0 :             gtk_paint_hline( gWidgetData[m_nXScreen].gMenuItemSeparatorMenuWidget->style,
    3202             :                              gdkDrawable,
    3203             :                              GTK_STATE_NORMAL,
    3204             :                              &clipRect,
    3205           0 :                              gWidgetData[m_nXScreen].gMenuItemSeparatorMenuWidget,
    3206             :                              "menuitem",
    3207           0 :                              x, x + w, y + h / 2);
    3208             :         }
    3209           0 :         else if( nPart == PART_MENU_SUBMENU_ARROW )
    3210             :         {
    3211             :             GtkStateType nStateType;
    3212             :             GtkShadowType nShadowType;
    3213           0 :             NWConvertVCLStateToGTKState( nState, &nStateType, &nShadowType );
    3214             : 
    3215           0 :             if ( (nState & CTRL_STATE_SELECTED) && (nState & CTRL_STATE_ENABLED) )
    3216           0 :                 nStateType = GTK_STATE_PRELIGHT;
    3217             : 
    3218           0 :             NWSetWidgetState( gWidgetData[m_nXScreen].gMenuItemMenuWidget,
    3219           0 :                               nState, nStateType );
    3220             : 
    3221             :             GtkArrowType eArrow;
    3222           0 :             if( Application::GetSettings().GetLayoutRTL() )
    3223           0 :                 eArrow = GTK_ARROW_LEFT;
    3224             :             else
    3225           0 :                 eArrow = GTK_ARROW_RIGHT;
    3226             : 
    3227           0 :             gtk_paint_arrow( gWidgetData[m_nXScreen].gMenuItemMenuWidget->style,
    3228             :                              gdkDrawable,
    3229             :                              nStateType,
    3230             :                              nShadowType,
    3231             :                              &clipRect,
    3232           0 :                              gWidgetData[m_nXScreen].gMenuItemMenuWidget,
    3233             :                              "menuitem",
    3234             :                              eArrow, TRUE,
    3235           0 :                              x, y, w, h);
    3236             :         }
    3237             :     }
    3238             : 
    3239           0 :     return true;
    3240             : }
    3241             : 
    3242           0 : bool GtkSalGraphics::NWPaintGTKTooltip(
    3243             :             GdkDrawable* gdkDrawable,
    3244             :             ControlType, ControlPart,
    3245             :             const Rectangle& rControlRectangle,
    3246             :             const clipList& rClipList,
    3247             :             ControlState, const ImplControlValue&,
    3248             :             const OUString& )
    3249             : {
    3250           0 :     NWEnsureGTKTooltip( m_nXScreen );
    3251             : 
    3252             :     gint            x, y, w, h;
    3253             :     GdkRectangle    clipRect;
    3254             : 
    3255           0 :     x = rControlRectangle.Left();
    3256           0 :     y = rControlRectangle.Top();
    3257           0 :     w = rControlRectangle.GetWidth();
    3258           0 :     h = rControlRectangle.GetHeight();
    3259             : 
    3260           0 :     for( clipList::const_iterator it = rClipList.begin(); it != rClipList.end(); ++it )
    3261             :     {
    3262           0 :         clipRect.x = it->Left();
    3263           0 :         clipRect.y = it->Top();
    3264           0 :         clipRect.width = it->GetWidth();
    3265           0 :         clipRect.height = it->GetHeight();
    3266             : 
    3267           0 :         gtk_paint_flat_box( gWidgetData[m_nXScreen].gTooltipPopup->style,
    3268             :                             gdkDrawable,
    3269             :                             GTK_STATE_NORMAL,
    3270             :                             GTK_SHADOW_OUT,
    3271             :                             &clipRect,
    3272           0 :                             gWidgetData[m_nXScreen].gTooltipPopup,
    3273             :                             "tooltip",
    3274           0 :                             x, y, w, h );
    3275             :     }
    3276             : 
    3277           0 :     return true;
    3278             : }
    3279             : 
    3280           0 : bool GtkSalGraphics::NWPaintGTKListNode(
    3281             :             GdkDrawable*,
    3282             :             ControlType, ControlPart,
    3283             :             const Rectangle& rControlRectangle,
    3284             :             const clipList&,
    3285             :             ControlState nState, const ImplControlValue& rValue,
    3286             :             const OUString& )
    3287             : {
    3288           0 :     NWEnsureGTKTreeView( m_nXScreen );
    3289             : 
    3290           0 :     Rectangle aRect( rControlRectangle );
    3291           0 :     aRect.Left() -= 2;
    3292           0 :     aRect.Right() += 2;
    3293           0 :     aRect.Top() -= 2;
    3294           0 :     aRect.Bottom() += 2;
    3295             :     gint            w, h;
    3296           0 :     w = aRect.GetWidth();
    3297           0 :     h = aRect.GetHeight();
    3298             : 
    3299             :     GtkStateType    stateType;
    3300             :     GtkShadowType    shadowType;
    3301           0 :     NWConvertVCLStateToGTKState( nState, &stateType, &shadowType );
    3302             : 
    3303           0 :     ButtonValue aButtonValue = rValue.getTristateVal();
    3304           0 :     GtkExpanderStyle eStyle = GTK_EXPANDER_EXPANDED;
    3305             : 
    3306           0 :     switch( aButtonValue )
    3307             :     {
    3308           0 :         case BUTTONVALUE_ON: eStyle = GTK_EXPANDER_EXPANDED;break;
    3309           0 :         case BUTTONVALUE_OFF: eStyle = GTK_EXPANDER_COLLAPSED; break;
    3310             :         default:
    3311           0 :             break;
    3312             :     }
    3313             : 
    3314           0 :     GdkPixmap* pixmap = NWGetPixmapFromScreen( aRect );
    3315           0 :     if( ! pixmap )
    3316           0 :         return false;
    3317             : 
    3318           0 :     GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
    3319           0 :     gtk_paint_expander( gWidgetData[m_nXScreen].gTreeView->style,
    3320             :                         pixDrawable,
    3321             :                         stateType,
    3322             :                         NULL,
    3323           0 :                         gWidgetData[m_nXScreen].gTreeView,
    3324             :                         "treeview",
    3325             :                         w/2, h/2,
    3326           0 :                         eStyle );
    3327             : 
    3328           0 :     bool bRet = NWRenderPixmapToScreen( pixmap, aRect );
    3329           0 :     g_object_unref( pixmap );
    3330             : 
    3331           0 :     return bRet;
    3332             : }
    3333             : 
    3334           0 : bool GtkSalGraphics::NWPaintGTKProgress(
    3335             :             GdkDrawable*,
    3336             :             ControlType, ControlPart,
    3337             :             const Rectangle& rControlRectangle,
    3338             :             const clipList&,
    3339             :             ControlState, const ImplControlValue& rValue,
    3340             :             const OUString& )
    3341             : {
    3342           0 :     NWEnsureGTKProgressBar( m_nXScreen );
    3343             : 
    3344             :     gint            w, h;
    3345           0 :     w = rControlRectangle.GetWidth();
    3346           0 :     h = rControlRectangle.GetHeight();
    3347             : 
    3348           0 :     long nProgressWidth = rValue.getNumericVal();
    3349             : 
    3350           0 :     GdkPixmap* pixmap = NWGetPixmapFromScreen( Rectangle( Point( 0, 0 ), Size( w, h ) ) );
    3351           0 :     if( ! pixmap )
    3352           0 :         return false;
    3353             : 
    3354           0 :     GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
    3355             : 
    3356             :     // paint background
    3357           0 :     gtk_paint_flat_box(gWidgetData[m_nXScreen].gProgressBar->style, pixDrawable,
    3358             :                            GTK_STATE_NORMAL, GTK_SHADOW_NONE, NULL, m_pWindow, "base",
    3359           0 :                            -rControlRectangle.Left(),-rControlRectangle.Top(),
    3360           0 :                            rControlRectangle.Left()+w,rControlRectangle.Top()+h);
    3361             : 
    3362           0 :     gtk_paint_flat_box( gWidgetData[m_nXScreen].gProgressBar->style,
    3363             :                         pixDrawable,
    3364             :                         GTK_STATE_NORMAL,
    3365             :                         GTK_SHADOW_NONE,
    3366             :                         NULL,
    3367           0 :                         gWidgetData[m_nXScreen].gProgressBar,
    3368             :                         "trough",
    3369           0 :                         0, 0, w, h );
    3370           0 :     if( nProgressWidth > 0 )
    3371             :     {
    3372             :         // paint progress
    3373           0 :         if( Application::GetSettings().GetLayoutRTL() )
    3374             :         {
    3375           0 :             gtk_paint_box( gWidgetData[m_nXScreen].gProgressBar->style,
    3376             :                            pixDrawable,
    3377             :                            GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
    3378             :                            NULL,
    3379           0 :                            gWidgetData[m_nXScreen].gProgressBar,
    3380             :                            "bar",
    3381           0 :                            w-nProgressWidth, 0, nProgressWidth, h
    3382           0 :                            );
    3383             :         }
    3384             :         else
    3385             :         {
    3386           0 :             gtk_paint_box( gWidgetData[m_nXScreen].gProgressBar->style,
    3387             :                            pixDrawable,
    3388             :                            GTK_STATE_PRELIGHT, GTK_SHADOW_OUT,
    3389             :                            NULL,
    3390           0 :                            gWidgetData[m_nXScreen].gProgressBar,
    3391             :                            "bar",
    3392             :                            0, 0, nProgressWidth, h
    3393           0 :                            );
    3394             :         }
    3395             :     }
    3396             : 
    3397           0 :     bool bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle );
    3398           0 :     g_object_unref( pixmap );
    3399             : 
    3400           0 :     return bRet;
    3401             : }
    3402             : 
    3403           0 : bool GtkSalGraphics::NWPaintGTKSlider(
    3404             :             GdkDrawable*,
    3405             :             ControlType, ControlPart nPart,
    3406             :             const Rectangle& rControlRectangle,
    3407             :             const clipList&,
    3408             :             ControlState nState, const ImplControlValue& rValue,
    3409             :             const OUString& )
    3410             : {
    3411             :     OSL_ASSERT( rValue.getType() == CTRL_SLIDER );
    3412           0 :     NWEnsureGTKSlider( m_nXScreen );
    3413             : 
    3414             :     gint            w, h;
    3415           0 :     w = rControlRectangle.GetWidth();
    3416           0 :     h = rControlRectangle.GetHeight();
    3417             : 
    3418           0 :     const SliderValue* pVal = static_cast<const SliderValue*>(&rValue);
    3419             : 
    3420           0 :     GdkPixmap* pixmap = NWGetPixmapFromScreen( rControlRectangle );
    3421           0 :     if( ! pixmap )
    3422           0 :         return false;
    3423             : 
    3424           0 :     GdkDrawable* const &pixDrawable = GDK_DRAWABLE( pixmap );
    3425             :     GtkWidget* pWidget = (nPart == PART_TRACK_HORZ_AREA)
    3426           0 :                          ? GTK_WIDGET(gWidgetData[m_nXScreen].gHScale)
    3427           0 :                          : GTK_WIDGET(gWidgetData[m_nXScreen].gVScale);
    3428           0 :     const gchar* pDetail = (nPart == PART_TRACK_HORZ_AREA) ? "hscale" : "vscale";
    3429           0 :     GtkOrientation eOri = (nPart == PART_TRACK_HORZ_AREA) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL;
    3430           0 :     gint slider_width = 10;
    3431           0 :     gint slider_length = 10;
    3432           0 :     gint trough_border = 0;
    3433             :     gtk_widget_style_get( pWidget,
    3434             :                           "slider-width", &slider_width,
    3435             :                           "slider-length", &slider_length,
    3436             :                           "trough-border", &trough_border,
    3437           0 :                           NULL);
    3438             : 
    3439           0 :     GtkStateType eState = (nState & CTRL_STATE_ENABLED) ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE;
    3440           0 :     if( nPart == PART_TRACK_HORZ_AREA )
    3441             :     {
    3442             :         gtk_paint_box( pWidget->style,
    3443             :                        pixDrawable,
    3444             :                        eState,
    3445             :                        GTK_SHADOW_IN,
    3446             :                        NULL,
    3447             :                        pWidget,
    3448             :                        "trough",
    3449           0 :                        0, (h-slider_width-2*trough_border)/2, w, slider_width + 2*trough_border);
    3450           0 :         gint x = (w - slider_length + 1) * (pVal->mnCur - pVal->mnMin) / (pVal->mnMax - pVal->mnMin);
    3451             :         gtk_paint_slider( pWidget->style,
    3452             :                           pixDrawable,
    3453             :                           eState,
    3454             :                           GTK_SHADOW_OUT,
    3455             :                           NULL,
    3456             :                           pWidget,
    3457             :                           pDetail,
    3458           0 :                           x, (h-slider_width)/2,
    3459             :                           slider_length, slider_width,
    3460           0 :                           eOri );
    3461             :     }
    3462             :     else
    3463             :     {
    3464             :         gtk_paint_box( pWidget->style,
    3465             :                        pixDrawable,
    3466             :                        eState,
    3467             :                        GTK_SHADOW_IN,
    3468             :                        NULL,
    3469             :                        pWidget,
    3470             :                        "trough",
    3471           0 :                        (w-slider_width-2*trough_border)/2, 0, slider_width + 2*trough_border, h);
    3472           0 :         gint y = (h - slider_length + 1) * (pVal->mnCur - pVal->mnMin) / (pVal->mnMax - pVal->mnMin);
    3473             :         gtk_paint_slider( pWidget->style,
    3474             :                           pixDrawable,
    3475             :                           eState,
    3476             :                           GTK_SHADOW_OUT,
    3477             :                           NULL,
    3478             :                           pWidget,
    3479             :                           pDetail,
    3480           0 :                           (w-slider_width)/2, y,
    3481             :                           slider_width, slider_length,
    3482           0 :                           eOri );
    3483             :     }
    3484             : 
    3485           0 :     bool bRet = NWRenderPixmapToScreen( pixmap, rControlRectangle );
    3486           0 :     g_object_unref( pixmap );
    3487             : 
    3488           0 :     return bRet;
    3489             : }
    3490             : 
    3491           0 : static int getFrameWidth(GtkWidget* widget)
    3492             : {
    3493           0 :     return widget->style->xthickness;
    3494             : }
    3495             : 
    3496           0 : static Rectangle NWGetListBoxButtonRect( SalX11Screen nScreen,
    3497             :                                          ControlType,
    3498             :                                          ControlPart    nPart,
    3499             :                                          Rectangle      aAreaRect,
    3500             :                                          ControlState,
    3501             :                                          const ImplControlValue&,
    3502             :                                          const OUString& )
    3503             : {
    3504           0 :     Rectangle       aPartRect;
    3505           0 :     GtkRequisition *pIndicatorSize = NULL;
    3506           0 :     GtkBorder      *pIndicatorSpacing = NULL;
    3507           0 :     gint            width = 13;    // GTK+ default
    3508           0 :     gint            right = 5;    // GTK+ default
    3509           0 :     gint            nButtonAreaWidth = 0;
    3510           0 :     gint            xthickness = 0;
    3511             : 
    3512           0 :     NWEnsureGTKOptionMenu( nScreen );
    3513             : 
    3514           0 :     gtk_widget_style_get( gWidgetData[nScreen].gOptionMenuWidget,
    3515             :             "indicator_size",    &pIndicatorSize,
    3516           0 :             "indicator_spacing",&pIndicatorSpacing, (char *)NULL);
    3517             : 
    3518           0 :     if ( pIndicatorSize )
    3519           0 :         width = pIndicatorSize->width;
    3520             : 
    3521           0 :     if ( pIndicatorSpacing )
    3522           0 :         right = pIndicatorSpacing->right;
    3523             : 
    3524           0 :     Size aPartSize( 0, aAreaRect.GetHeight() );
    3525           0 :     Point aPartPos ( 0, aAreaRect.Top() );
    3526             : 
    3527           0 :     xthickness = gWidgetData[nScreen].gOptionMenuWidget->style->xthickness;
    3528           0 :     nButtonAreaWidth = width + right + (xthickness * 2);
    3529           0 :     switch( nPart )
    3530             :     {
    3531             :         case PART_BUTTON_DOWN:
    3532           0 :             aPartSize.Width() = nButtonAreaWidth;
    3533           0 :             aPartPos.X() = aAreaRect.Left() + aAreaRect.GetWidth() - aPartSize.Width();
    3534           0 :             break;
    3535             : 
    3536             :         case PART_SUB_EDIT:
    3537           0 :             aPartSize.Width() = aAreaRect.GetWidth() - nButtonAreaWidth - xthickness;
    3538           0 :             if( Application::GetSettings().GetLayoutRTL() )
    3539           0 :                 aPartPos.X() = aAreaRect.Left() + nButtonAreaWidth;
    3540             :             else
    3541           0 :                 aPartPos.X() = aAreaRect.Left() + xthickness;
    3542           0 :             break;
    3543             : 
    3544             :         default:
    3545           0 :             aPartSize.Width() = aAreaRect.GetWidth();
    3546           0 :             aPartPos.X() = aAreaRect.Left();
    3547           0 :             break;
    3548             :     }
    3549           0 :     aPartRect = Rectangle( aPartPos, aPartSize );
    3550             : 
    3551           0 :     if ( pIndicatorSize )
    3552           0 :         gtk_requisition_free( pIndicatorSize );
    3553           0 :     if ( pIndicatorSpacing )
    3554           0 :         gtk_border_free( pIndicatorSpacing );
    3555             : 
    3556           0 :     return( aPartRect );
    3557             : }
    3558             : 
    3559           0 : static Rectangle NWGetListBoxIndicatorRect( SalX11Screen nScreen,
    3560             :                                             ControlType,
    3561             :                                             ControlPart,
    3562             :                                             Rectangle                aAreaRect,
    3563             :                                             ControlState,
    3564             :                                             const ImplControlValue&,
    3565             :                                             const OUString& )
    3566             : {
    3567           0 :     Rectangle       aIndicatorRect;
    3568           0 :     GtkRequisition *pIndicatorSize = NULL;
    3569           0 :     GtkBorder      *pIndicatorSpacing = NULL;
    3570           0 :     gint            width = 13;    // GTK+ default
    3571           0 :     gint            height = 13;    // GTK+ default
    3572           0 :     gint            right = 5;    // GTK+ default
    3573             :     gint            x;
    3574             : 
    3575           0 :     NWEnsureGTKOptionMenu( nScreen );
    3576             : 
    3577           0 :     gtk_widget_style_get( gWidgetData[nScreen].gOptionMenuWidget,
    3578             :             "indicator_size",    &pIndicatorSize,
    3579           0 :             "indicator_spacing",&pIndicatorSpacing, (char *)NULL);
    3580             : 
    3581           0 :     if ( pIndicatorSize )
    3582             :     {
    3583           0 :         width = pIndicatorSize->width;
    3584           0 :         height = pIndicatorSize->height;
    3585             :     }
    3586             : 
    3587           0 :     if ( pIndicatorSpacing )
    3588           0 :         right = pIndicatorSpacing->right;
    3589             : 
    3590           0 :     aIndicatorRect.SetSize( Size( width, height ) );
    3591           0 :     if( Application::GetSettings().GetLayoutRTL() )
    3592           0 :         x = aAreaRect.Left() + right;
    3593             :     else
    3594           0 :         x = aAreaRect.Left() + aAreaRect.GetWidth() - width - right - gWidgetData[nScreen].gOptionMenuWidget->style->xthickness;
    3595           0 :     aIndicatorRect.SetPos( Point( x, aAreaRect.Top() + ((aAreaRect.GetHeight() - height) / 2) ) );
    3596             : 
    3597             :     // If height is odd, move the indicator down 1 pixel
    3598           0 :     if ( aIndicatorRect.GetHeight() % 2 )
    3599           0 :         aIndicatorRect.Move( 0, 1 );
    3600             : 
    3601           0 :     if ( pIndicatorSize )
    3602           0 :         gtk_requisition_free( pIndicatorSize );
    3603           0 :     if ( pIndicatorSpacing )
    3604           0 :         gtk_border_free( pIndicatorSpacing );
    3605             : 
    3606           0 :     return( aIndicatorRect );
    3607             : }
    3608             : 
    3609           0 : static Rectangle NWGetToolbarRect(  SalX11Screen nScreen,
    3610             :                                     ControlType,
    3611             :                                     ControlPart                nPart,
    3612             :                                     Rectangle                aAreaRect,
    3613             :                                     ControlState,
    3614             :                                     const ImplControlValue&,
    3615             :                                     const OUString& )
    3616             : {
    3617           0 :     Rectangle aRet;
    3618             : 
    3619           0 :     if( nPart == PART_DRAW_BACKGROUND_HORZ ||
    3620             :         nPart == PART_DRAW_BACKGROUND_VERT )
    3621           0 :         aRet = aAreaRect;
    3622           0 :     else if( nPart == PART_THUMB_HORZ )
    3623           0 :         aRet = Rectangle( Point( 0, 0 ), Size( aAreaRect.GetWidth(), 10 ) );
    3624           0 :     else if( nPart == PART_THUMB_VERT )
    3625           0 :         aRet = Rectangle( Point( 0, 0 ), Size( 10, aAreaRect.GetHeight() ) );
    3626           0 :     else if( nPart == PART_BUTTON )
    3627             :     {
    3628           0 :         aRet = aAreaRect;
    3629             : 
    3630           0 :         NWEnsureGTKToolbar( nScreen );
    3631             : 
    3632             :         gint nMinWidth =
    3633           0 :             2*gWidgetData[nScreen].gToolbarButtonWidget->style->xthickness
    3634           0 :             + 1 // CHILD_SPACING constant, found in gtk_button.c
    3635           0 :             + 3*gWidgetData[nScreen].gToolbarButtonWidget->style->xthickness; // Murphy factor
    3636             :         gint nMinHeight =
    3637           0 :             2*gWidgetData[nScreen].gToolbarButtonWidget->style->ythickness
    3638           0 :             + 1 // CHILD_SPACING constant, found in gtk_button.c
    3639           0 :             + 3*gWidgetData[nScreen].gToolbarButtonWidget->style->ythickness; // Murphy factor
    3640             : 
    3641           0 :         gtk_widget_ensure_style( gWidgetData[nScreen].gToolbarButtonWidget );
    3642           0 :         if( aAreaRect.GetWidth() < nMinWidth )
    3643           0 :             aRet.Right() = aRet.Left() + nMinWidth;
    3644           0 :         if( aAreaRect.GetHeight() < nMinHeight  )
    3645           0 :             aRet.Bottom() = aRet.Top() + nMinHeight;
    3646             :     }
    3647             : 
    3648           0 :     return aRet;
    3649             : }
    3650             : 
    3651             : /************************************************************************
    3652             :  * helper for GtkSalFrame
    3653             :  ************************************************************************/
    3654           0 : static inline Color getColor( const GdkColor& rCol )
    3655             : {
    3656           0 :     return Color( rCol.red >> 8, rCol.green >> 8, rCol.blue >> 8 );
    3657             : }
    3658             : 
    3659             : #if OSL_DEBUG_LEVEL > 1
    3660             : 
    3661             : void printColor( const char* name, const GdkColor& rCol )
    3662             : {
    3663             :     std::fprintf( stderr, "   %s = 0x%2x 0x%2x 0x%2x\n",
    3664             :              name,
    3665             :              rCol.red >> 8, rCol.green >> 8, rCol.blue >> 8 );
    3666             : }
    3667             : 
    3668             : void printStyleColors( GtkStyle* pStyle )
    3669             : {
    3670             :     static const char* pStates[] = { "NORMAL", "ACTIVE", "PRELIGHT", "SELECTED", "INSENSITIVE" };
    3671             : 
    3672             :     for( int i = 0; i < 5; i++ )
    3673             :     {
    3674             :         std::fprintf( stderr, "state %s colors:\n", pStates[i] );
    3675             :         printColor( "bg     ", pStyle->bg[i] );
    3676             :         printColor( "fg     ", pStyle->fg[i] );
    3677             :         printColor( "light  ", pStyle->light[i] );
    3678             :         printColor( "dark   ", pStyle->dark[i] );
    3679             :         printColor( "mid    ", pStyle->mid[i] );
    3680             :         printColor( "text   ", pStyle->text[i] );
    3681             :         printColor( "base   ", pStyle->base[i] );
    3682             :         printColor( "text_aa", pStyle->text_aa[i] );
    3683             :     }
    3684             : }
    3685             : #endif
    3686             : 
    3687           0 : void GtkSalGraphics::signalSettingsNotify( GObject *pSettings, GParamSpec *pSpec, gpointer )
    3688             : {
    3689           0 :     g_return_if_fail( pSpec != NULL );
    3690             : 
    3691           0 :     if( !strcmp( pSpec->name, "gtk-fontconfig-timestamp" ) )
    3692           0 :         GtkSalGraphics::refreshFontconfig( GTK_SETTINGS( pSettings ) );
    3693             : }
    3694             : 
    3695           0 : void GtkSalGraphics::refreshFontconfig( GtkSettings *pSettings )
    3696             : {
    3697           0 :     guint latest_fontconfig_timestamp = 0;
    3698             :     static guint our_fontconfig_timestamp = 0;
    3699           0 :     g_object_get( pSettings, "gtk-fontconfig-timestamp", &latest_fontconfig_timestamp, (char *)NULL );
    3700           0 :     if (latest_fontconfig_timestamp != our_fontconfig_timestamp)
    3701             :     {
    3702           0 :         bool bFirstTime = our_fontconfig_timestamp == 0;
    3703           0 :         our_fontconfig_timestamp = latest_fontconfig_timestamp;
    3704           0 :         if (!bFirstTime)
    3705             :         {
    3706           0 :             psp::PrintFontManager::get().initialize();
    3707             :         }
    3708             :     }
    3709           0 : }
    3710             : 
    3711           0 : void GtkSalGraphics::updateSettings( AllSettings& rSettings )
    3712             : {
    3713           0 :     GdkScreen* pScreen = gtk_widget_get_screen( m_pWindow );
    3714           0 :     gtk_widget_ensure_style( m_pWindow );
    3715           0 :     GtkStyle* pStyle = gtk_widget_get_style( m_pWindow );
    3716           0 :     GtkSettings* pSettings = gtk_widget_get_settings( m_pWindow );
    3717           0 :     StyleSettings aStyleSet = rSettings.GetStyleSettings();
    3718             : 
    3719             :     // Listen for font changes
    3720           0 :     if( !g_object_get_data( G_OBJECT( pSettings ), "libo:listening" ) )
    3721             :     {
    3722           0 :         g_object_set_data( G_OBJECT( pSettings ), "libo:listening",
    3723           0 :                            GUINT_TO_POINTER( 1 ) );
    3724           0 :         g_signal_connect_data( G_OBJECT( pSettings ), "notify",
    3725             :                                G_CALLBACK( signalSettingsNotify ),
    3726           0 :                                NULL, NULL, G_CONNECT_AFTER );
    3727             :     }
    3728             : 
    3729           0 :     refreshFontconfig( pSettings );
    3730             : 
    3731             :     // get the widgets in place
    3732           0 :     NWEnsureGTKMenu( m_nXScreen );
    3733           0 :     NWEnsureGTKMenubar( m_nXScreen );
    3734           0 :     NWEnsureGTKScrollbars( m_nXScreen );
    3735           0 :     NWEnsureGTKEditBox( m_nXScreen );
    3736           0 :     NWEnsureGTKTooltip( m_nXScreen );
    3737           0 :     NWEnsureGTKDialog( m_nXScreen );
    3738           0 :     NWEnsureGTKFrame( m_nXScreen );
    3739             : 
    3740             : #if OSL_DEBUG_LEVEL > 2
    3741             :     printStyleColors( pStyle );
    3742             : #endif
    3743             : 
    3744             :     // text colors
    3745           0 :     Color aTextColor = getColor( pStyle->text[GTK_STATE_NORMAL] );
    3746           0 :     aStyleSet.SetDialogTextColor( aTextColor );
    3747           0 :     aStyleSet.SetWindowTextColor( aTextColor );
    3748           0 :     aStyleSet.SetFieldTextColor( aTextColor );
    3749           0 :     aTextColor = getColor( pStyle->fg[GTK_STATE_NORMAL] );
    3750           0 :     aStyleSet.SetButtonTextColor( aTextColor );
    3751           0 :     aStyleSet.SetRadioCheckTextColor( aTextColor );
    3752           0 :     aStyleSet.SetGroupTextColor( aTextColor );
    3753           0 :     aStyleSet.SetLabelTextColor( aTextColor );
    3754           0 :     aStyleSet.SetInfoTextColor( aTextColor );
    3755             : 
    3756             :     // Tooltip colors
    3757           0 :     GtkStyle* pTooltipStyle = gtk_widget_get_style( gWidgetData[m_nXScreen].gTooltipPopup );
    3758           0 :     aTextColor = getColor( pTooltipStyle->fg[ GTK_STATE_NORMAL ] );
    3759           0 :     aStyleSet.SetHelpTextColor( aTextColor );
    3760             : 
    3761           0 :     DialogStyle aDialogStyle(aStyleSet.GetDialogStyle());
    3762           0 :     gtk_widget_style_get (gWidgetData[m_nXScreen].gDialog,
    3763             :         "content-area-border", &aDialogStyle.content_area_border,
    3764             :         "content-area-spacing", &aDialogStyle.content_area_spacing,
    3765             :         "button-spacing", &aDialogStyle.button_spacing,
    3766             :         "action-area-border", &aDialogStyle.action_area_border,
    3767           0 :         NULL);
    3768           0 :     aStyleSet.SetDialogStyle(aDialogStyle);
    3769             : 
    3770           0 :     FrameStyle aFrameStyle(aStyleSet.GetFrameStyle());
    3771             :     aFrameStyle.left = aFrameStyle.right =
    3772           0 :         gWidgetData[m_nXScreen].gFrame->style->xthickness;
    3773             :     aFrameStyle.top = aFrameStyle.bottom =
    3774           0 :         gWidgetData[m_nXScreen].gFrame->style->ythickness;
    3775           0 :     aStyleSet.SetFrameStyle(aFrameStyle);
    3776             : 
    3777             :     // mouse over text colors
    3778           0 :     aTextColor = getColor( pStyle->fg[ GTK_STATE_PRELIGHT ] );
    3779           0 :     aStyleSet.SetButtonRolloverTextColor( aTextColor );
    3780           0 :     aStyleSet.SetFieldRolloverTextColor( aTextColor );
    3781             : 
    3782             :     // background colors
    3783           0 :     Color aBackColor = getColor( pStyle->bg[GTK_STATE_NORMAL] );
    3784           0 :     Color aBackFieldColor = getColor( pStyle->base[ GTK_STATE_NORMAL ] );
    3785           0 :     aStyleSet.Set3DColors( aBackColor );
    3786           0 :     aStyleSet.SetFaceColor( aBackColor );
    3787           0 :     aStyleSet.SetDialogColor( aBackColor );
    3788           0 :     aStyleSet.SetWorkspaceColor( aBackColor );
    3789           0 :     aStyleSet.SetFieldColor( aBackFieldColor );
    3790           0 :     aStyleSet.SetWindowColor( aBackFieldColor );
    3791           0 :     aStyleSet.SetCheckedColorSpecialCase( );
    3792             : 
    3793             :     // highlighting colors
    3794           0 :     Color aHighlightColor = getColor( pStyle->base[GTK_STATE_SELECTED] );
    3795           0 :     Color aHighlightTextColor = getColor( pStyle->text[GTK_STATE_SELECTED] );
    3796           0 :     aStyleSet.SetHighlightColor( aHighlightColor );
    3797           0 :     aStyleSet.SetHighlightTextColor( aHighlightTextColor );
    3798             : 
    3799           0 :     if( ! gtk_check_version( 2, 10, 0 ) ) // link colors came in with 2.10, avoid an assertion
    3800             :     {
    3801             :         // hyperlink colors
    3802           0 :         GdkColor *link_color = NULL;
    3803           0 :         gtk_widget_style_get (m_pWindow, "link-color", &link_color, NULL);
    3804           0 :         if (link_color)
    3805             :         {
    3806           0 :             aStyleSet.SetLinkColor(getColor(*link_color));
    3807           0 :             gdk_color_free (link_color);
    3808           0 :             link_color = NULL;
    3809             :         }
    3810           0 :         gtk_widget_style_get (m_pWindow, "visited-link-color", &link_color, NULL);
    3811           0 :         if (link_color)
    3812             :         {
    3813           0 :             aStyleSet.SetVisitedLinkColor(getColor(*link_color));
    3814           0 :             gdk_color_free (link_color);
    3815             :         }
    3816             :     }
    3817             : 
    3818             :     // Tab colors
    3819           0 :     aStyleSet.SetActiveTabColor( aBackFieldColor ); // same as the window color.
    3820           0 :     Color aSelectedBackColor = getColor( pStyle->bg[GTK_STATE_ACTIVE] );
    3821           0 :     aStyleSet.SetInactiveTabColor( aSelectedBackColor );
    3822             : 
    3823             :     // menu disabled entries handling
    3824           0 :     aStyleSet.SetSkipDisabledInMenus( true );
    3825           0 :     aStyleSet.SetAcceleratorsInContextMenus( false );
    3826             :     // menu colors
    3827           0 :     GtkStyle* pMenuStyle = gtk_widget_get_style( gWidgetData[m_nXScreen].gMenuWidget );
    3828           0 :     GtkStyle* pMenuItemStyle = gtk_rc_get_style( gWidgetData[m_nXScreen].gMenuItemMenuWidget );
    3829           0 :     GtkStyle* pMenubarStyle = gtk_rc_get_style( gWidgetData[m_nXScreen].gMenubarWidget );
    3830           0 :     GtkStyle* pMenuTextStyle = gtk_rc_get_style( gtk_bin_get_child( GTK_BIN(gWidgetData[m_nXScreen].gMenuItemMenuWidget) ) );
    3831             : 
    3832           0 :     aBackColor = getColor( pMenubarStyle->bg[GTK_STATE_NORMAL] );
    3833           0 :     aStyleSet.SetMenuBarColor( aBackColor );
    3834           0 :     aStyleSet.SetMenuBarRolloverColor( aBackColor );
    3835           0 :     aBackColor = getColor( pMenuStyle->bg[GTK_STATE_NORMAL] );
    3836           0 :     aTextColor = getColor( pMenuTextStyle->fg[GTK_STATE_NORMAL] );
    3837           0 :     aStyleSet.SetMenuColor( aBackColor );
    3838           0 :     aStyleSet.SetMenuTextColor( aTextColor );
    3839             : 
    3840           0 :     aTextColor = aStyleSet.GetPersonaMenuBarTextColor().get_value_or( getColor( pMenubarStyle->fg[GTK_STATE_NORMAL] ) );
    3841           0 :     aStyleSet.SetMenuBarTextColor( aTextColor );
    3842           0 :     aStyleSet.SetMenuBarRolloverTextColor( aTextColor );
    3843             : 
    3844             : #if OSL_DEBUG_LEVEL > 1
    3845             :     std::fprintf( stderr, "==\n" );
    3846             :     std::fprintf( stderr, "MenuColor = %x (%d)\n", (int)aStyleSet.GetMenuColor().GetColor(), aStyleSet.GetMenuColor().GetLuminance() );
    3847             :     std::fprintf( stderr, "MenuTextColor = %x (%d)\n", (int)aStyleSet.GetMenuTextColor().GetColor(), aStyleSet.GetMenuTextColor().GetLuminance() );
    3848             :     std::fprintf( stderr, "MenuBarColor = %x (%d)\n", (int)aStyleSet.GetMenuBarColor().GetColor(), aStyleSet.GetMenuBarColor().GetLuminance() );
    3849             :     std::fprintf( stderr, "MenuBarRolloverColor = %x (%d)\n", (int)aStyleSet.GetMenuBarRolloverColor().GetColor(), aStyleSet.GetMenuBarRolloverColor().GetLuminance() );
    3850             :     std::fprintf( stderr, "MenuBarTextColor = %x (%d)\n", (int)aStyleSet.GetMenuBarTextColor().GetColor(), aStyleSet.GetMenuBarTextColor().GetLuminance() );
    3851             :     std::fprintf( stderr, "MenuBarRolloverTextColor = %x (%d)\n", (int)aStyleSet.GetMenuBarRolloverTextColor().GetColor(), aStyleSet.GetMenuBarRolloverTextColor().GetLuminance() );
    3852             :     std::fprintf( stderr, "LightColor = %x (%d)\n", (int)aStyleSet.GetLightColor().GetColor(), aStyleSet.GetLightColor().GetLuminance() );
    3853             :     std::fprintf( stderr, "ShadowColor = %x (%d)\n", (int)aStyleSet.GetShadowColor().GetColor(), aStyleSet.GetShadowColor().GetLuminance() );
    3854             :     std::fprintf( stderr, "DarkShadowColor = %x (%d)\n", (int)aStyleSet.GetDarkShadowColor().GetColor(), aStyleSet.GetDarkShadowColor().GetLuminance() );
    3855             : #endif
    3856             : 
    3857             :     // Awful hack for menu separators in the Sonar and similar themes.
    3858             :     // If the menu color is not too dark, and the menu text color is lighter,
    3859             :     // make the "light" color lighter than the menu color and the "shadow"
    3860             :     // color darker than it.
    3861           0 :     if ( aStyleSet.GetMenuColor().GetLuminance() >= 32 &&
    3862           0 :      aStyleSet.GetMenuColor().GetLuminance() <= aStyleSet.GetMenuTextColor().GetLuminance() )
    3863             :     {
    3864           0 :       Color temp = aStyleSet.GetMenuColor();
    3865           0 :       temp.IncreaseLuminance( 8 );
    3866           0 :       aStyleSet.SetLightColor( temp );
    3867           0 :       temp = aStyleSet.GetMenuColor();
    3868           0 :       temp.DecreaseLuminance( 16 );
    3869           0 :       aStyleSet.SetShadowColor( temp );
    3870             :     }
    3871             : 
    3872           0 :     aHighlightColor = getColor( pMenuItemStyle->bg[ GTK_STATE_SELECTED ] );
    3873           0 :     aHighlightTextColor = getColor( pMenuTextStyle->fg[ GTK_STATE_PRELIGHT ] );
    3874           0 :     if( aHighlightColor == aHighlightTextColor )
    3875           0 :         aHighlightTextColor = (aHighlightColor.GetLuminance() < 128) ? Color( COL_WHITE ) : Color( COL_BLACK );
    3876           0 :     aStyleSet.SetMenuHighlightColor( aHighlightColor );
    3877           0 :     aStyleSet.SetMenuHighlightTextColor( aHighlightTextColor );
    3878             : 
    3879             :     // UI font
    3880           0 :     OString    aFamily        = pango_font_description_get_family( pStyle->font_desc );
    3881           0 :     int nPangoHeight    = pango_font_description_get_size( pStyle->font_desc );
    3882           0 :     PangoStyle    eStyle    = pango_font_description_get_style( pStyle->font_desc );
    3883           0 :     PangoWeight    eWeight    = pango_font_description_get_weight( pStyle->font_desc );
    3884           0 :     PangoStretch eStretch = pango_font_description_get_stretch( pStyle->font_desc );
    3885             : 
    3886           0 :     psp::FastPrintFontInfo aInfo;
    3887             :     // set family name
    3888           0 :     aInfo.m_aFamilyName = OStringToOUString( aFamily, RTL_TEXTENCODING_UTF8 );
    3889             :     // set italic
    3890           0 :     switch( eStyle )
    3891             :     {
    3892           0 :         case PANGO_STYLE_NORMAL:    aInfo.m_eItalic = ITALIC_NONE;break;
    3893           0 :         case PANGO_STYLE_ITALIC:    aInfo.m_eItalic = ITALIC_NORMAL;break;
    3894           0 :         case PANGO_STYLE_OBLIQUE:    aInfo.m_eItalic = ITALIC_OBLIQUE;break;
    3895             :     }
    3896             :     // set weight
    3897           0 :     if( eWeight <= PANGO_WEIGHT_ULTRALIGHT )
    3898           0 :         aInfo.m_eWeight = WEIGHT_ULTRALIGHT;
    3899           0 :     else if( eWeight <= PANGO_WEIGHT_LIGHT )
    3900           0 :         aInfo.m_eWeight = WEIGHT_LIGHT;
    3901           0 :     else if( eWeight <= PANGO_WEIGHT_NORMAL )
    3902           0 :         aInfo.m_eWeight = WEIGHT_NORMAL;
    3903           0 :     else if( eWeight <= PANGO_WEIGHT_BOLD )
    3904           0 :         aInfo.m_eWeight = WEIGHT_BOLD;
    3905             :     else
    3906           0 :         aInfo.m_eWeight = WEIGHT_ULTRABOLD;
    3907             :     // set width
    3908           0 :     switch( eStretch )
    3909             :     {
    3910           0 :         case PANGO_STRETCH_ULTRA_CONDENSED:    aInfo.m_eWidth = WIDTH_ULTRA_CONDENSED;break;
    3911           0 :         case PANGO_STRETCH_EXTRA_CONDENSED:    aInfo.m_eWidth = WIDTH_EXTRA_CONDENSED;break;
    3912           0 :         case PANGO_STRETCH_CONDENSED:        aInfo.m_eWidth = WIDTH_CONDENSED;break;
    3913           0 :         case PANGO_STRETCH_SEMI_CONDENSED:    aInfo.m_eWidth = WIDTH_SEMI_CONDENSED;break;
    3914           0 :         case PANGO_STRETCH_NORMAL:            aInfo.m_eWidth = WIDTH_NORMAL;break;
    3915           0 :         case PANGO_STRETCH_SEMI_EXPANDED:    aInfo.m_eWidth = WIDTH_SEMI_EXPANDED;break;
    3916           0 :         case PANGO_STRETCH_EXPANDED:        aInfo.m_eWidth = WIDTH_EXPANDED;break;
    3917           0 :         case PANGO_STRETCH_EXTRA_EXPANDED:    aInfo.m_eWidth = WIDTH_EXTRA_EXPANDED;break;
    3918           0 :         case PANGO_STRETCH_ULTRA_EXPANDED:    aInfo.m_eWidth = WIDTH_ULTRA_EXPANDED;break;
    3919             :     }
    3920             : 
    3921             : #if OSL_DEBUG_LEVEL > 1
    3922             :     std::fprintf( stderr, "font name BEFORE system match: \"%s\"\n", aFamily.getStr() );
    3923             : #endif
    3924             : 
    3925             :     // match font to e.g. resolve "Sans"
    3926           0 :     psp::PrintFontManager::get().matchFont( aInfo, rSettings.GetUILanguageTag().getLocale() );
    3927             : 
    3928             : #if OSL_DEBUG_LEVEL > 1
    3929             :     std::fprintf( stderr, "font match %s, name AFTER: \"%s\"\n",
    3930             :              aInfo.m_nID != 0 ? "succeeded" : "failed",
    3931             :              OUStringToOString( aInfo.m_aFamilyName, RTL_TEXTENCODING_ISO_8859_1 ).getStr() );
    3932             : #endif
    3933             : 
    3934           0 :     sal_Int32 nDispDPIY = GetDisplay()->GetResolution().B();
    3935           0 :     int nPointHeight = 0;
    3936             :     static gboolean(*pAbso)(const PangoFontDescription*) =
    3937           0 :         (gboolean(*)(const PangoFontDescription*))osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "pango_font_description_get_size_is_absolute" );
    3938             : 
    3939           0 :     if( pAbso && pAbso( pStyle->font_desc ) )
    3940           0 :         nPointHeight = (nPangoHeight * 72 + nDispDPIY*PANGO_SCALE/2) / (nDispDPIY * PANGO_SCALE);
    3941             :     else
    3942           0 :         nPointHeight = nPangoHeight/PANGO_SCALE;
    3943             : 
    3944           0 :     Font aFont( aInfo.m_aFamilyName, Size( 0, nPointHeight ) );
    3945           0 :     if( aInfo.m_eWeight != WEIGHT_DONTKNOW )
    3946           0 :         aFont.SetWeight( aInfo.m_eWeight );
    3947           0 :     if( aInfo.m_eWidth != WIDTH_DONTKNOW )
    3948           0 :         aFont.SetWidthType( aInfo.m_eWidth );
    3949           0 :     if( aInfo.m_eItalic != ITALIC_DONTKNOW )
    3950           0 :         aFont.SetItalic( aInfo.m_eItalic );
    3951           0 :     if( aInfo.m_ePitch != PITCH_DONTKNOW )
    3952           0 :         aFont.SetPitch( aInfo.m_ePitch );
    3953             : 
    3954           0 :     aStyleSet.SetAppFont( aFont );
    3955           0 :     aStyleSet.SetHelpFont( aFont );
    3956           0 :     aStyleSet.SetMenuFont( aFont );
    3957           0 :     aStyleSet.SetToolFont( aFont );
    3958           0 :     aStyleSet.SetLabelFont( aFont );
    3959           0 :     aStyleSet.SetInfoFont( aFont );
    3960           0 :     aStyleSet.SetRadioCheckFont( aFont );
    3961           0 :     aStyleSet.SetPushButtonFont( aFont );
    3962           0 :     aStyleSet.SetFieldFont( aFont );
    3963           0 :     aStyleSet.SetIconFont( aFont );
    3964           0 :     aStyleSet.SetGroupFont( aFont );
    3965             : 
    3966           0 :     aFont.SetWeight( WEIGHT_BOLD );
    3967           0 :     aStyleSet.SetTitleFont( aFont );
    3968           0 :     aStyleSet.SetFloatTitleFont( aFont );
    3969             : 
    3970             :     // get cursor blink time
    3971           0 :     gboolean blink = false;
    3972             : 
    3973           0 :     g_object_get( pSettings, "gtk-cursor-blink", &blink, (char *)NULL );
    3974           0 :     if( blink )
    3975             :     {
    3976           0 :         gint blink_time = STYLE_CURSOR_NOBLINKTIME;
    3977           0 :         g_object_get( pSettings, "gtk-cursor-blink-time", &blink_time, (char *)NULL );
    3978             :         // set the blink_time if there is a setting and it is reasonable
    3979             :         // else leave the default value
    3980           0 :         if( blink_time > 100 && blink_time != gint(STYLE_CURSOR_NOBLINKTIME) )
    3981           0 :             aStyleSet.SetCursorBlinkTime( blink_time/2 );
    3982             :     }
    3983             :     else
    3984           0 :         aStyleSet.SetCursorBlinkTime( STYLE_CURSOR_NOBLINKTIME );
    3985             : 
    3986           0 :     MouseSettings aMouseSettings = rSettings.GetMouseSettings();
    3987             :     int iDoubleClickTime, iDoubleClickDistance, iDragThreshold, iMenuPopupDelay;
    3988             :     g_object_get( pSettings,
    3989             :                   "gtk-double-click-time", &iDoubleClickTime,
    3990             :                   "gtk-double-click-distance", &iDoubleClickDistance,
    3991             :                   "gtk-dnd-drag-threshold", &iDragThreshold,
    3992             :                   "gtk-menu-popup-delay", &iMenuPopupDelay,
    3993           0 :                   (char *)NULL );
    3994           0 :     aMouseSettings.SetDoubleClickTime( iDoubleClickTime );
    3995           0 :     aMouseSettings.SetDoubleClickWidth( iDoubleClickDistance );
    3996           0 :     aMouseSettings.SetDoubleClickHeight( iDoubleClickDistance );
    3997           0 :     aMouseSettings.SetStartDragWidth( iDragThreshold );
    3998           0 :     aMouseSettings.SetStartDragHeight( iDragThreshold );
    3999           0 :     aMouseSettings.SetMenuDelay( iMenuPopupDelay );
    4000           0 :     rSettings.SetMouseSettings( aMouseSettings );
    4001             : 
    4002           0 :     gboolean showmenuicons = true, primarybuttonwarps = false;
    4003             :     g_object_get( pSettings,
    4004             :         "gtk-menu-images", &showmenuicons,
    4005           0 :         (char *)NULL );
    4006           0 :     if( g_object_class_find_property(
    4007           0 :             G_OBJECT_GET_CLASS(pSettings), "gtk-primary-button-warps-slider") )
    4008             :     {
    4009             :         g_object_get( pSettings,
    4010             :             "gtk-primary-button-warps-slider", &primarybuttonwarps,
    4011           0 :             (char *)NULL );
    4012             :     }
    4013           0 :     aStyleSet.SetPreferredUseImagesInMenus(showmenuicons);
    4014           0 :     aStyleSet.SetPrimaryButtonWarpsSlider(primarybuttonwarps);
    4015             : 
    4016             :     // set scrollbar settings
    4017           0 :     gint slider_width = 14;
    4018           0 :     gint trough_border = 1;
    4019           0 :     gint min_slider_length = 21;
    4020             : 
    4021             :     // Grab some button style attributes
    4022           0 :     gtk_widget_style_get( gWidgetData[m_nXScreen].gScrollHorizWidget,
    4023             :                           "slider-width", &slider_width,
    4024             :                           "trough-border", &trough_border,
    4025             :                           "min-slider-length", &min_slider_length,
    4026           0 :                           (char *)NULL );
    4027           0 :     gint magic = trough_border ? 1 : 0;
    4028           0 :     aStyleSet.SetScrollBarSize( slider_width + 2*trough_border );
    4029           0 :     aStyleSet.SetMinThumbSize( min_slider_length - magic );
    4030             : 
    4031             :     // preferred icon style
    4032           0 :     gchar* pIconThemeName = NULL;
    4033           0 :     g_object_get( pSettings, "gtk-icon-theme-name", &pIconThemeName, (char *)NULL );
    4034           0 :     aStyleSet.SetPreferredIconTheme( OUString::createFromAscii( pIconThemeName ) );
    4035           0 :     g_free( pIconThemeName );
    4036             : 
    4037           0 :     aStyleSet.SetToolbarIconSize( STYLE_TOOLBAR_ICONSIZE_LARGE );
    4038             : 
    4039             : #if !GTK_CHECK_VERSION(2,9,0)
    4040             :     static cairo_font_options_t* (*gdk_screen_get_font_options)(GdkScreen*) =
    4041             :         (cairo_font_options_t*(*)(GdkScreen*))osl_getAsciiFunctionSymbol( GetSalData()->m_pPlugin, "gdk_screen_get_font_options" );
    4042             :     if( gdk_screen_get_font_options != NULL )
    4043             :     {
    4044             :         const cairo_font_options_t* pNewOptions = gdk_screen_get_font_options( pScreen );
    4045             :         aStyleSet.SetCairoFontOptions( pNewOptions );
    4046             :     }
    4047             : #else
    4048           0 :     const cairo_font_options_t* pNewOptions = gdk_screen_get_font_options( pScreen );
    4049           0 :     aStyleSet.SetCairoFontOptions( pNewOptions );
    4050             : #endif
    4051             : 
    4052             :     // finally update the collected settings
    4053           0 :     rSettings.SetStyleSettings( aStyleSet );
    4054           0 : }
    4055             : 
    4056             : /************************************************************************
    4057             :  * Create a GdkPixmap filled with the contents of an area of an Xlib window
    4058             :  ************************************************************************/
    4059             : 
    4060           0 : GdkPixmap* GtkSalGraphics::NWGetPixmapFromScreen( Rectangle srcRect )
    4061             : {
    4062             :     // Create a new pixmap to hold the composite of the window background and the control
    4063           0 :     GdkPixmap * pPixmap        = gdk_pixmap_new( GDK_DRAWABLE(GetGdkWindow()), srcRect.GetWidth(), srcRect.GetHeight(), -1 );
    4064           0 :     GdkGC *     pPixmapGC      = gdk_gc_new( pPixmap );
    4065             : 
    4066           0 :     if( !pPixmap || !pPixmapGC )
    4067             :     {
    4068           0 :         if ( pPixmap )
    4069           0 :             g_object_unref( pPixmap );
    4070           0 :         if ( pPixmapGC )
    4071           0 :             g_object_unref( pPixmapGC );
    4072           0 :         std::fprintf( stderr, "salnativewidgets-gtk.cxx: could not get valid pixmap from screen\n" );
    4073           0 :         return( NULL );
    4074             :     }
    4075             : 
    4076             :     // Copy the background of the screen into a composite pixmap
    4077             :     CopyScreenArea( GetXDisplay(),
    4078           0 :                     GetDrawable(), GetScreenNumber(), GetVisual().GetDepth(),
    4079             :                     gdk_x11_drawable_get_xid(pPixmap),
    4080           0 :                     SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ) ),
    4081           0 :                     gdk_drawable_get_depth( GDK_DRAWABLE( pPixmap ) ),
    4082             :                     gdk_x11_gc_get_xgc(pPixmapGC),
    4083           0 :                     srcRect.Left(), srcRect.Top(), srcRect.GetWidth(), srcRect.GetHeight(), 0, 0 );
    4084             : 
    4085           0 :     g_object_unref( pPixmapGC );
    4086           0 :     return( pPixmap );
    4087             : }
    4088             : 
    4089             : /************************************************************************
    4090             :  * Copy an alpha pixmap to screen using a gc with clipping
    4091             :  ************************************************************************/
    4092             : 
    4093           0 : bool GtkSalGraphics::NWRenderPixmapToScreen( GdkPixmap* pPixmap, Rectangle dstRect )
    4094             : {
    4095             :     // The GC can't be null, otherwise we'd have no clip region
    4096           0 :     GC aFontGC = GetFontGC();
    4097           0 :     if( aFontGC == NULL )
    4098             :     {
    4099           0 :         std::fprintf(stderr, "salnativewidgets.cxx: no valid GC\n" );
    4100           0 :         return false;
    4101             :     }
    4102             : 
    4103           0 :     if ( !pPixmap )
    4104           0 :         return false;
    4105             : 
    4106             :     // Copy the background of the screen into a composite pixmap
    4107             :     CopyScreenArea( GetXDisplay(),
    4108             :                     GDK_DRAWABLE_XID(pPixmap),
    4109           0 :                     SalX11Screen( gdk_screen_get_number( gdk_drawable_get_screen( GDK_DRAWABLE(pPixmap) ) ) ),
    4110           0 :                     gdk_drawable_get_depth( GDK_DRAWABLE(pPixmap) ),
    4111           0 :                     GetDrawable(), m_nXScreen, GetVisual().GetDepth(),
    4112             :                     aFontGC,
    4113           0 :                     0, 0, dstRect.GetWidth(), dstRect.GetHeight(), dstRect.Left(), dstRect.Top() );
    4114             : 
    4115           0 :     return true;
    4116             : }
    4117             : 
    4118             : /************************************************************************
    4119             :  * State conversion
    4120             :  ************************************************************************/
    4121           0 : static void NWConvertVCLStateToGTKState( ControlState nVCLState,
    4122             :             GtkStateType* nGTKState, GtkShadowType* nGTKShadow )
    4123             : {
    4124           0 :     *nGTKShadow = GTK_SHADOW_OUT;
    4125           0 :     *nGTKState = GTK_STATE_INSENSITIVE;
    4126             : 
    4127           0 :     if ( nVCLState & CTRL_STATE_ENABLED )
    4128             :     {
    4129           0 :         if ( nVCLState & CTRL_STATE_PRESSED )
    4130             :         {
    4131           0 :             *nGTKState = GTK_STATE_ACTIVE;
    4132           0 :             *nGTKShadow = GTK_SHADOW_IN;
    4133             :         }
    4134           0 :         else if ( nVCLState & CTRL_STATE_ROLLOVER )
    4135             :         {
    4136           0 :             *nGTKState = GTK_STATE_PRELIGHT;
    4137           0 :             *nGTKShadow = GTK_SHADOW_OUT;
    4138             :         }
    4139             :         else
    4140             :         {
    4141           0 :             *nGTKState = GTK_STATE_NORMAL;
    4142           0 :             *nGTKShadow = GTK_SHADOW_OUT;
    4143             :         }
    4144             :     }
    4145           0 : }
    4146             : 
    4147             : /************************************************************************
    4148             :  * Set widget flags
    4149             :  ************************************************************************/
    4150           0 : static void NWSetWidgetState( GtkWidget* widget, ControlState nState, GtkStateType nGtkState )
    4151             : {
    4152             :     // Set to default state, then build up from there
    4153           0 :     GTK_WIDGET_UNSET_FLAGS( widget, GTK_HAS_DEFAULT );
    4154           0 :     GTK_WIDGET_UNSET_FLAGS( widget, GTK_HAS_FOCUS );
    4155           0 :     GTK_WIDGET_UNSET_FLAGS( widget, GTK_SENSITIVE );
    4156           0 :     GTK_WIDGET_SET_FLAGS( widget, gWidgetDefaultFlags[(long)widget] );
    4157             : 
    4158           0 :     if ( nState & CTRL_STATE_DEFAULT )
    4159           0 :         GTK_WIDGET_SET_FLAGS( widget, GTK_HAS_DEFAULT );
    4160           0 :     if ( !GTK_IS_TOGGLE_BUTTON(widget) && (nState & CTRL_STATE_FOCUSED) )
    4161           0 :         GTK_WIDGET_SET_FLAGS( widget, GTK_HAS_FOCUS );
    4162           0 :     if ( nState & CTRL_STATE_ENABLED )
    4163           0 :         GTK_WIDGET_SET_FLAGS( widget, GTK_SENSITIVE );
    4164           0 :     gtk_widget_set_state( widget, nGtkState );
    4165           0 : }
    4166             : 
    4167             : /************************************************************************
    4168             :  * Widget ensure functions - make sure cached objects are valid
    4169             :  ************************************************************************/
    4170             : 
    4171           0 : static void NWAddWidgetToCacheWindow( GtkWidget* widget, SalX11Screen nScreen )
    4172             : {
    4173           0 :     NWFWidgetData& rData = gWidgetData[nScreen];
    4174           0 :     if ( !rData.gCacheWindow || !rData.gDumbContainer )
    4175             :     {
    4176           0 :         if ( !rData.gCacheWindow )
    4177             :         {
    4178           0 :             rData.gCacheWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL );
    4179           0 :             g_object_set_data( G_OBJECT( rData.gCacheWindow ), "libo-version",
    4180           0 :                                (gpointer)LIBO_VERSION_DOTTED );
    4181             : 
    4182             :             GdkScreen* pScreen = gdk_display_get_screen( gdk_display_get_default(),
    4183           0 :                                                          nScreen.getXScreen() );
    4184           0 :             if( pScreen )
    4185           0 :                 gtk_window_set_screen( GTK_WINDOW(rData.gCacheWindow), pScreen );
    4186             :         }
    4187           0 :         if ( !rData.gDumbContainer )
    4188           0 :             rData.gDumbContainer = gtk_fixed_new();
    4189           0 :         gtk_container_add( GTK_CONTAINER(rData.gCacheWindow), rData.gDumbContainer );
    4190           0 :         gtk_widget_realize( rData.gDumbContainer );
    4191           0 :         gtk_widget_realize( rData.gCacheWindow );
    4192             :     }
    4193             : 
    4194           0 :     gtk_container_add( GTK_CONTAINER(rData.gDumbContainer), widget );
    4195           0 :     gtk_widget_realize( widget );
    4196           0 :     gtk_widget_ensure_style( widget );
    4197             : 
    4198             :     // Store widget's default flags
    4199           0 :     gWidgetDefaultFlags[ (long)widget ] = GTK_WIDGET_FLAGS( widget );
    4200           0 : }
    4201             : 
    4202           0 : static void NWEnsureGTKButton( SalX11Screen nScreen )
    4203             : {
    4204           0 :     if ( !gWidgetData[nScreen].gBtnWidget )
    4205             :     {
    4206           0 :         gWidgetData[nScreen].gBtnWidget = gtk_button_new_with_label( "" );
    4207           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gBtnWidget, nScreen );
    4208             :     }
    4209           0 : }
    4210             : 
    4211           0 : static void NWEnsureGTKRadio( SalX11Screen nScreen )
    4212             : {
    4213           0 :     if ( !gWidgetData[nScreen].gRadioWidget || !gWidgetData[nScreen].gRadioWidgetSibling )
    4214             :     {
    4215           0 :         gWidgetData[nScreen].gRadioWidget = gtk_radio_button_new( NULL );
    4216           0 :         gWidgetData[nScreen].gRadioWidgetSibling = gtk_radio_button_new_from_widget( GTK_RADIO_BUTTON(gWidgetData[nScreen].gRadioWidget) );
    4217           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gRadioWidget, nScreen );
    4218           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gRadioWidgetSibling, nScreen );
    4219             :     }
    4220           0 : }
    4221             : 
    4222           0 : static void NWEnsureGTKCheck( SalX11Screen nScreen )
    4223             : {
    4224           0 :     if ( !gWidgetData[nScreen].gCheckWidget )
    4225             :     {
    4226           0 :         gWidgetData[nScreen].gCheckWidget = gtk_check_button_new();
    4227           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gCheckWidget, nScreen );
    4228             :     }
    4229           0 : }
    4230             : 
    4231           0 : static void NWEnsureGTKScrollbars( SalX11Screen nScreen )
    4232             : {
    4233           0 :     if ( !gWidgetData[nScreen].gScrollHorizWidget )
    4234             :     {
    4235           0 :         gWidgetData[nScreen].gScrollHorizWidget = gtk_hscrollbar_new( NULL );
    4236           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gScrollHorizWidget, nScreen );
    4237             :     }
    4238             : 
    4239           0 :     if ( !gWidgetData[nScreen].gScrollVertWidget )
    4240             :     {
    4241           0 :         gWidgetData[nScreen].gScrollVertWidget = gtk_vscrollbar_new( NULL );
    4242           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gScrollVertWidget, nScreen );
    4243             :     }
    4244           0 : }
    4245             : 
    4246           0 : static void NWEnsureGTKArrow( SalX11Screen nScreen )
    4247             : {
    4248           0 :     if ( !gWidgetData[nScreen].gArrowWidget || !gWidgetData[nScreen].gDropdownWidget )
    4249             :     {
    4250           0 :         gWidgetData[nScreen].gDropdownWidget = gtk_toggle_button_new();
    4251           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gDropdownWidget, nScreen );
    4252           0 :         gWidgetData[nScreen].gArrowWidget = gtk_arrow_new( GTK_ARROW_DOWN, GTK_SHADOW_OUT );
    4253           0 :         gtk_container_add( GTK_CONTAINER(gWidgetData[nScreen].gDropdownWidget), gWidgetData[nScreen].gArrowWidget );
    4254           0 :         gtk_widget_set_rc_style( gWidgetData[nScreen].gArrowWidget );
    4255           0 :         gtk_widget_realize( gWidgetData[nScreen].gArrowWidget );
    4256             :     }
    4257           0 : }
    4258             : 
    4259           0 : static void NWEnsureGTKEditBox( SalX11Screen nScreen )
    4260             : {
    4261           0 :     if ( !gWidgetData[nScreen].gEditBoxWidget )
    4262             :     {
    4263           0 :         gWidgetData[nScreen].gEditBoxWidget = gtk_entry_new();
    4264           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gEditBoxWidget, nScreen );
    4265             :     }
    4266           0 : }
    4267             : 
    4268           0 : static void NWEnsureGTKSpinButton( SalX11Screen nScreen )
    4269             : {
    4270           0 :     if ( !gWidgetData[nScreen].gSpinButtonWidget )
    4271             :     {
    4272           0 :         GtkAdjustment *adj = GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 1, 1, 1, 0) );
    4273           0 :         gWidgetData[nScreen].gSpinButtonWidget = gtk_spin_button_new( adj, 1, 2 );
    4274             : 
    4275             :         //Setting non-editable means it doesn't blink, so there's no timeouts
    4276             :         //running around to nobble us
    4277           0 :         gtk_editable_set_editable(GTK_EDITABLE(gWidgetData[nScreen].gSpinButtonWidget), false);
    4278             : 
    4279           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gSpinButtonWidget, nScreen );
    4280             :     }
    4281           0 : }
    4282             : 
    4283           0 : static void NWEnsureGTKNotebook( SalX11Screen nScreen )
    4284             : {
    4285           0 :     if ( !gWidgetData[nScreen].gNotebookWidget )
    4286             :     {
    4287           0 :         gWidgetData[nScreen].gNotebookWidget = gtk_notebook_new();
    4288           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gNotebookWidget, nScreen );
    4289             :     }
    4290           0 : }
    4291             : 
    4292           0 : static void NWEnsureGTKOptionMenu( SalX11Screen nScreen )
    4293             : {
    4294           0 :     if ( !gWidgetData[nScreen].gOptionMenuWidget )
    4295             :     {
    4296           0 :         gWidgetData[nScreen].gOptionMenuWidget = gtk_option_menu_new();
    4297           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gOptionMenuWidget, nScreen );
    4298             :     }
    4299           0 : }
    4300             : 
    4301           0 : static void NWEnsureGTKCombo( SalX11Screen nScreen )
    4302             : {
    4303           0 :     if ( !gWidgetData[nScreen].gComboWidget )
    4304             :     {
    4305           0 :         gWidgetData[nScreen].gComboWidget = gtk_combo_new();
    4306             : 
    4307             :         // #i59129# Setting non-editable means it doesn't blink, so
    4308             :         // there are no timeouts running around to nobble us
    4309           0 :         gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(gWidgetData[nScreen].gComboWidget)->entry), false);
    4310             : 
    4311           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gComboWidget, nScreen );
    4312             :         // Must realize the ComboBox's children, since GTK
    4313             :         // does not do this for us in GtkCombo::gtk_widget_realize()
    4314           0 :         gtk_widget_realize( GTK_COMBO(gWidgetData[nScreen].gComboWidget)->button );
    4315           0 :         gtk_widget_realize( GTK_COMBO(gWidgetData[nScreen].gComboWidget)->entry );
    4316             :     }
    4317           0 : }
    4318             : 
    4319           0 : static void NWEnsureGTKScrolledWindow( SalX11Screen nScreen )
    4320             : {
    4321           0 :     if ( !gWidgetData[nScreen].gScrolledWindowWidget )
    4322             :     {
    4323           0 :         GtkAdjustment *hadj = GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 0, 0, 0, 0) );
    4324           0 :         GtkAdjustment *vadj = GTK_ADJUSTMENT( gtk_adjustment_new(0, 0, 0, 0, 0, 0) );
    4325             : 
    4326           0 :         gWidgetData[nScreen].gScrolledWindowWidget = gtk_scrolled_window_new( hadj, vadj );
    4327           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gScrolledWindowWidget, nScreen );
    4328             :     }
    4329           0 : }
    4330             : 
    4331           0 : static void NWEnsureGTKToolbar( SalX11Screen nScreen )
    4332             : {
    4333           0 :     if( !gWidgetData[nScreen].gToolbarWidget )
    4334             :     {
    4335           0 :         gWidgetData[nScreen].gToolbarWidget = gtk_toolbar_new();
    4336           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gToolbarWidget, nScreen );
    4337           0 :         gWidgetData[nScreen].gToolbarButtonWidget = GTK_WIDGET(gtk_toggle_button_new());
    4338           0 :         gWidgetData[nScreen].gSeparator = GTK_WIDGET(gtk_separator_tool_item_new());
    4339           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gSeparator, nScreen );
    4340             : 
    4341           0 :         GtkReliefStyle aRelief = GTK_RELIEF_NORMAL;
    4342           0 :         gtk_widget_ensure_style( gWidgetData[nScreen].gToolbarWidget );
    4343           0 :         gtk_widget_style_get( gWidgetData[nScreen].gToolbarWidget,
    4344             :                               "button_relief", &aRelief,
    4345           0 :                               (char *)NULL);
    4346             : 
    4347           0 :         gtk_button_set_relief( GTK_BUTTON(gWidgetData[nScreen].gToolbarButtonWidget), aRelief );
    4348           0 :         GTK_WIDGET_UNSET_FLAGS( gWidgetData[nScreen].gToolbarButtonWidget, GTK_CAN_FOCUS );
    4349           0 :         GTK_WIDGET_UNSET_FLAGS( gWidgetData[nScreen].gToolbarButtonWidget, GTK_CAN_DEFAULT );
    4350           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gToolbarButtonWidget, nScreen );
    4351             : 
    4352             :     }
    4353           0 :     if( ! gWidgetData[nScreen].gHandleBoxWidget )
    4354             :     {
    4355           0 :         gWidgetData[nScreen].gHandleBoxWidget = gtk_handle_box_new();
    4356           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gHandleBoxWidget, nScreen );
    4357             :     }
    4358           0 : }
    4359             : 
    4360           0 : static void NWEnsureGTKMenubar( SalX11Screen nScreen )
    4361             : {
    4362           0 :     if( !gWidgetData[nScreen].gMenubarWidget )
    4363             :     {
    4364           0 :         gWidgetData[nScreen].gMenubarWidget = gtk_menu_bar_new();
    4365           0 :         gWidgetData[nScreen].gMenuItemMenubarWidget = gtk_menu_item_new_with_label( "b" );
    4366           0 :         gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenubarWidget ), gWidgetData[nScreen].gMenuItemMenubarWidget );
    4367           0 :         gtk_widget_show( gWidgetData[nScreen].gMenuItemMenubarWidget );
    4368           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gMenubarWidget, nScreen );
    4369           0 :         gtk_widget_show( gWidgetData[nScreen].gMenubarWidget );
    4370             : 
    4371             :         // do what NWAddWidgetToCacheWindow does except adding to def container
    4372           0 :         gtk_widget_realize( gWidgetData[nScreen].gMenuItemMenubarWidget );
    4373           0 :         gtk_widget_ensure_style( gWidgetData[nScreen].gMenuItemMenubarWidget );
    4374             : 
    4375           0 :         gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuItemMenubarWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuItemMenubarWidget );
    4376             :     }
    4377           0 : }
    4378             : 
    4379           0 : static void NWEnsureGTKMenu( SalX11Screen nScreen )
    4380             : {
    4381           0 :     if( !gWidgetData[nScreen].gMenuWidget )
    4382             :     {
    4383           0 :         gWidgetData[nScreen].gMenuWidget                  = gtk_menu_new();
    4384           0 :         gWidgetData[nScreen].gMenuItemMenuWidget          = gtk_menu_item_new_with_label( "b" );
    4385           0 :         gWidgetData[nScreen].gMenuItemCheckMenuWidget     = gtk_check_menu_item_new_with_label( "b" );
    4386           0 :         gWidgetData[nScreen].gMenuItemRadioMenuWidget     = gtk_radio_menu_item_new_with_label( NULL, "b" );
    4387           0 :         gWidgetData[nScreen].gMenuItemSeparatorMenuWidget = gtk_menu_item_new();
    4388           0 :         gWidgetData[nScreen].gImageMenuItem               = gtk_image_menu_item_new();
    4389             : 
    4390           0 :         gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenuWidget ), gWidgetData[nScreen].gMenuItemMenuWidget );
    4391           0 :         gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenuWidget ), gWidgetData[nScreen].gMenuItemCheckMenuWidget );
    4392           0 :         gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenuWidget ), gWidgetData[nScreen].gMenuItemRadioMenuWidget );
    4393           0 :         gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenuWidget ), gWidgetData[nScreen].gMenuItemSeparatorMenuWidget );
    4394           0 :         gtk_menu_shell_append( GTK_MENU_SHELL( gWidgetData[nScreen].gMenuWidget ), gWidgetData[nScreen].gImageMenuItem );
    4395             : 
    4396             :         // do what NWAddWidgetToCacheWindow does except adding to def container
    4397           0 :         gtk_widget_realize( gWidgetData[nScreen].gMenuWidget );
    4398           0 :         gtk_widget_ensure_style( gWidgetData[nScreen].gMenuWidget );
    4399             : 
    4400           0 :         gtk_widget_realize( gWidgetData[nScreen].gMenuItemMenuWidget );
    4401           0 :         gtk_widget_ensure_style( gWidgetData[nScreen].gMenuItemMenuWidget );
    4402             : 
    4403           0 :         gtk_widget_realize( gWidgetData[nScreen].gMenuItemCheckMenuWidget );
    4404           0 :         gtk_widget_ensure_style( gWidgetData[nScreen].gMenuItemCheckMenuWidget );
    4405             : 
    4406           0 :         gtk_widget_realize( gWidgetData[nScreen].gMenuItemRadioMenuWidget );
    4407           0 :         gtk_widget_ensure_style( gWidgetData[nScreen].gMenuItemRadioMenuWidget );
    4408             : 
    4409           0 :         gtk_widget_realize( gWidgetData[nScreen].gMenuItemSeparatorMenuWidget );
    4410           0 :         gtk_widget_ensure_style( gWidgetData[nScreen].gMenuItemSeparatorMenuWidget );
    4411             : 
    4412           0 :         gtk_widget_realize( gWidgetData[nScreen].gImageMenuItem );
    4413           0 :         gtk_widget_ensure_style( gWidgetData[nScreen].gImageMenuItem );
    4414             : 
    4415           0 :         gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuWidget );
    4416           0 :         gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuItemMenuWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuItemMenuWidget );
    4417           0 :         gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuItemCheckMenuWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuItemCheckMenuWidget );
    4418           0 :         gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuItemRadioMenuWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuItemRadioMenuWidget );
    4419           0 :         gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gMenuItemSeparatorMenuWidget ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gMenuItemSeparatorMenuWidget );
    4420           0 :         gWidgetDefaultFlags[ (long)gWidgetData[nScreen].gImageMenuItem ] = GTK_WIDGET_FLAGS( gWidgetData[nScreen].gImageMenuItem );
    4421             :     }
    4422           0 : }
    4423             : 
    4424           0 : static void NWEnsureGTKTooltip( SalX11Screen nScreen )
    4425             : {
    4426           0 :     if( !gWidgetData[nScreen].gTooltipPopup )
    4427             :     {
    4428           0 :         gWidgetData[nScreen].gTooltipPopup = gtk_window_new (GTK_WINDOW_POPUP);
    4429             :         GdkScreen* pScreen = gdk_display_get_screen( gdk_display_get_default(),
    4430           0 :                                                      nScreen.getXScreen() );
    4431           0 :         if( pScreen )
    4432           0 :             gtk_window_set_screen( GTK_WINDOW(gWidgetData[nScreen].gTooltipPopup), pScreen );
    4433           0 :         gtk_widget_set_name( gWidgetData[nScreen].gTooltipPopup, "gtk-tooltips");
    4434           0 :         gtk_widget_realize( gWidgetData[nScreen].gTooltipPopup );
    4435           0 :         gtk_widget_ensure_style( gWidgetData[nScreen].gTooltipPopup );
    4436             :     }
    4437           0 : }
    4438             : 
    4439           0 : static void NWEnsureGTKDialog( SalX11Screen nScreen )
    4440             : {
    4441           0 :     if( !gWidgetData[nScreen].gDialog )
    4442             :     {
    4443           0 :         gWidgetData[nScreen].gDialog = gtk_dialog_new();
    4444             :         GdkScreen* pScreen = gdk_display_get_screen( gdk_display_get_default(),
    4445           0 :                                                      nScreen.getXScreen() );
    4446           0 :         if( pScreen )
    4447           0 :             gtk_window_set_screen( GTK_WINDOW(gWidgetData[nScreen].gDialog), pScreen );
    4448           0 :         gtk_widget_realize(gWidgetData[nScreen].gDialog);
    4449           0 :         gtk_widget_ensure_style(gWidgetData[nScreen].gDialog);
    4450             :     }
    4451           0 : }
    4452             : 
    4453           0 : static void NWEnsureGTKFrame( SalX11Screen nScreen )
    4454             : {
    4455           0 :     if( !gWidgetData[nScreen].gFrame )
    4456             :     {
    4457           0 :         gWidgetData[nScreen].gFrame = gtk_frame_new(NULL);
    4458           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gFrame, nScreen );
    4459             :     }
    4460           0 : }
    4461             : 
    4462           0 : static void NWEnsureGTKProgressBar( SalX11Screen nScreen )
    4463             : {
    4464           0 :     if( !gWidgetData[nScreen].gProgressBar )
    4465             :     {
    4466           0 :         gWidgetData[nScreen].gProgressBar = gtk_progress_bar_new ();
    4467           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gProgressBar, nScreen );
    4468             :     }
    4469           0 : }
    4470             : 
    4471           0 : static void NWEnsureGTKTreeView( SalX11Screen nScreen )
    4472             : {
    4473           0 :     if( !gWidgetData[nScreen].gTreeView )
    4474             :     {
    4475           0 :         gWidgetData[nScreen].gTreeView = gtk_tree_view_new ();
    4476             : 
    4477             :         // Columns will be used for tree header rendering
    4478           0 :         GtkCellRenderer* renderer=gtk_cell_renderer_text_new();
    4479           0 :         GtkTreeViewColumn* column=gtk_tree_view_column_new_with_attributes("",renderer,"text",0,NULL);
    4480           0 :         gtk_tree_view_column_set_widget(column,gtk_label_new(""));
    4481           0 :         gtk_tree_view_append_column(GTK_TREE_VIEW(gWidgetData[nScreen].gTreeView), column);
    4482             : 
    4483             :         // Add one more column so that some engines like clearlooks did render separators between columns
    4484           0 :         column=gtk_tree_view_column_new_with_attributes("",renderer,"text",0,NULL);
    4485           0 :         gtk_tree_view_append_column(GTK_TREE_VIEW(gWidgetData[nScreen].gTreeView), column);
    4486             : 
    4487           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gTreeView, nScreen );
    4488             :     }
    4489           0 : }
    4490             : 
    4491           0 : static void NWEnsureGTKSlider( SalX11Screen nScreen )
    4492             : {
    4493           0 :     if( !gWidgetData[nScreen].gHScale )
    4494             :     {
    4495           0 :         gWidgetData[nScreen].gHScale = gtk_hscale_new_with_range(0, 10, 1);
    4496           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gHScale, nScreen );
    4497             :     }
    4498           0 :     if( !gWidgetData[nScreen].gVScale )
    4499             :     {
    4500           0 :         gWidgetData[nScreen].gVScale = gtk_vscale_new_with_range(0, 10, 1);
    4501           0 :         NWAddWidgetToCacheWindow( gWidgetData[nScreen].gVScale, nScreen );
    4502             :     }
    4503           0 : }
    4504             : 
    4505             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10