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