1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        gtk/settings.cpp 
   4 // Author:      Robert Roebling 
   5 // Modified by: Mart Raudsepp (GetMetric) 
   7 // Copyright:   (c) 1998 Robert Roebling 
   8 // Licence:     wxWindows licence 
   9 ///////////////////////////////////////////////////////////////////////////// 
  11 // For compilers that support precompilation, includes "wx.h". 
  12 #include "wx/wxprec.h" 
  14 #include "wx/settings.h" 
  16 #include "wx/cmndata.h" 
  17 #include "wx/fontutil.h" 
  18 #include "wx/toplevel.h" 
  22 #include <gdk/gdkprivate.h> 
  25 #include <X11/Xatom.h> 
  27 #define SHIFT (8*(sizeof(short int)-sizeof(char))) 
  29 // ---------------------------------------------------------------------------- 
  31 // ---------------------------------------------------------------------------- 
  33 struct wxSystemObjects
 
  35     wxColour m_colBtnFace
, 
  42              m_colMenuItemHighlight
, 
  49 static wxSystemObjects gs_objects
; 
  51 // ---------------------------------------------------------------------------- 
  52 // wxSystemSettings implementation 
  53 // ---------------------------------------------------------------------------- 
  55 // kind of widget to use in GetColourFromGTKWidget 
  71 // wxSystemSettings::GetColour() helper: get the colours from a GTK+ 
  72 // widget style, return true if we did get them, false to use defaults 
  73 static bool GetColourFromGTKWidget(int& red
, int& green
, int& blue
, 
  74                                    wxGtkWidgetType type 
= wxGTK_BUTTON
, 
  75                                    GtkStateType state 
= GTK_STATE_NORMAL
, 
  76                                    wxGtkColourType colour 
= wxGTK_BG
) 
  82             wxFAIL_MSG( _T("unexpected GTK widget type") ); 
  86             widget 
= gtk_button_new(); 
  90             widget 
= gtk_list_new(); 
  94             widget 
= gtk_menu_item_new(); 
  97     GtkStyle 
*def 
= gtk_rc_get_style( widget 
); 
  99         def 
= gtk_widget_get_default_style(); 
 108                 wxFAIL_MSG( _T("unexpected GTK colour type") ); 
 124         red 
= col
[state
].red
; 
 125         green 
= col
[state
].green
; 
 126         blue 
= col
[state
].blue
; 
 135     gtk_widget_destroy( widget 
); 
 140 static void GetTooltipColors() 
 142     GtkTooltips
* tooltips 
= gtk_tooltips_new(); 
 143     gtk_tooltips_force_window(tooltips
); 
 144     gtk_widget_ensure_style(tooltips
->tip_window
); 
 145     GdkColor c 
= tooltips
->tip_window
->style
->bg
[GTK_STATE_NORMAL
]; 
 146     gs_objects
.m_colTooltip 
= wxColor(c
.red 
>> SHIFT
, c
.green 
>> SHIFT
, c
.blue 
>> SHIFT
); 
 147     c 
= tooltips
->tip_window
->style
->fg
[GTK_STATE_NORMAL
]; 
 148     gs_objects
.m_colTooltipText 
= wxColor(c
.red 
>> SHIFT
, c
.green 
>> SHIFT
, c
.blue 
>> SHIFT
); 
 149     gtk_object_sink(wx_reinterpret_cast(GtkObject
*, tooltips
)); 
 152 wxColour 
wxSystemSettingsNative::GetColour( wxSystemColour index 
) 
 156         case wxSYS_COLOUR_SCROLLBAR
: 
 157         case wxSYS_COLOUR_BACKGROUND
: 
 158         case wxSYS_COLOUR_INACTIVECAPTION
: 
 159         case wxSYS_COLOUR_MENU
: 
 160         case wxSYS_COLOUR_WINDOWFRAME
: 
 161         case wxSYS_COLOUR_ACTIVEBORDER
: 
 162         case wxSYS_COLOUR_INACTIVEBORDER
: 
 163         case wxSYS_COLOUR_BTNFACE
: 
 164         case wxSYS_COLOUR_MENUBAR
: 
 165         case wxSYS_COLOUR_3DLIGHT
: 
 166             if (!gs_objects
.m_colBtnFace
.Ok()) 
 168                 int red
, green
, blue
; 
 169                 if ( !GetColourFromGTKWidget(red
, green
, blue
) ) 
 176                 gs_objects
.m_colBtnFace 
= wxColour( red   
>> SHIFT
, 
 180             return gs_objects
.m_colBtnFace
; 
 182         case wxSYS_COLOUR_WINDOW
: 
 185         case wxSYS_COLOUR_3DDKSHADOW
: 
 188         case wxSYS_COLOUR_GRAYTEXT
: 
 189         case wxSYS_COLOUR_BTNSHADOW
: 
 190         //case wxSYS_COLOUR_3DSHADOW: 
 191             if (!gs_objects
.m_colBtnShadow
.Ok()) 
 193                 wxColour 
faceColour(GetColour(wxSYS_COLOUR_3DFACE
)); 
 194                 gs_objects
.m_colBtnShadow 
= 
 195                    wxColour((unsigned char) (faceColour
.Red() * 0.666), 
 196                             (unsigned char) (faceColour
.Green() * 0.666), 
 197                             (unsigned char) (faceColour
.Blue() * 0.666)); 
 200             return gs_objects
.m_colBtnShadow
; 
 202         case wxSYS_COLOUR_3DHIGHLIGHT
: 
 203         //case wxSYS_COLOUR_BTNHIGHLIGHT: 
 206         case wxSYS_COLOUR_HIGHLIGHT
: 
 207             if (!gs_objects
.m_colHighlight
.Ok()) 
 209                 int red
, green
, blue
; 
 210                 if ( !GetColourFromGTKWidget(red
, green
, blue
, 
 212                                              GTK_STATE_SELECTED
) ) 
 219                 gs_objects
.m_colHighlight 
= wxColour( red   
>> SHIFT
, 
 223             return gs_objects
.m_colHighlight
; 
 225         case wxSYS_COLOUR_LISTBOX
: 
 226             if (!gs_objects
.m_colListBox
.Ok()) 
 228                 int red
, green
, blue
; 
 229                 if ( GetColourFromGTKWidget(red
, green
, blue
, 
 234                     gs_objects
.m_colListBox 
= wxColour( red   
>> SHIFT
, 
 240                     gs_objects
.m_colListBox 
= wxColour(*wxWHITE
); 
 243             return gs_objects
.m_colListBox
; 
 245         case wxSYS_COLOUR_MENUTEXT
: 
 246         case wxSYS_COLOUR_WINDOWTEXT
: 
 247         case wxSYS_COLOUR_CAPTIONTEXT
: 
 248         case wxSYS_COLOUR_INACTIVECAPTIONTEXT
: 
 249         case wxSYS_COLOUR_BTNTEXT
: 
 250             if (!gs_objects
.m_colBtnText
.Ok()) 
 252                 int red
, green
, blue
; 
 253                 if ( !GetColourFromGTKWidget(red
, green
, blue
, 
 263                 gs_objects
.m_colBtnText 
= wxColour( red   
>> SHIFT
, 
 267             return gs_objects
.m_colBtnText
; 
 269         case wxSYS_COLOUR_INFOBK
: 
 270             if (!gs_objects
.m_colTooltip
.Ok()) { 
 273             return gs_objects
.m_colTooltip
; 
 275         case wxSYS_COLOUR_INFOTEXT
: 
 276             if (!gs_objects
.m_colTooltipText
.Ok()) { 
 279             return gs_objects
.m_colTooltipText
; 
 281         case wxSYS_COLOUR_HIGHLIGHTTEXT
: 
 282             if (!gs_objects
.m_colHighlightText
.Ok()) 
 284                 wxColour hclr 
= GetColour(wxSYS_COLOUR_HIGHLIGHT
); 
 285                 if (hclr
.Red() > 200 && hclr
.Green() > 200 && hclr
.Blue() > 200) 
 286                     gs_objects
.m_colHighlightText 
= wxColour(*wxBLACK
); 
 288                     gs_objects
.m_colHighlightText 
= wxColour(*wxWHITE
); 
 290             return gs_objects
.m_colHighlightText
; 
 292         case wxSYS_COLOUR_APPWORKSPACE
: 
 293             return *wxWHITE
;    // ? 
 295         case wxSYS_COLOUR_ACTIVECAPTION
: 
 296         case wxSYS_COLOUR_MENUHILIGHT
: 
 297             if (!gs_objects
.m_colMenuItemHighlight
.Ok()) 
 299                 int red
, green
, blue
; 
 300                 if ( !GetColourFromGTKWidget(red
, green
, blue
, 
 310                 gs_objects
.m_colMenuItemHighlight 
= wxColour( red  
>> SHIFT
, 
 314             return gs_objects
.m_colMenuItemHighlight
; 
 316         case wxSYS_COLOUR_HOTLIGHT
: 
 317         case wxSYS_COLOUR_GRADIENTACTIVECAPTION
: 
 318         case wxSYS_COLOUR_GRADIENTINACTIVECAPTION
: 
 322         case wxSYS_COLOUR_MAX
: 
 324             wxFAIL_MSG( _T("unknown system colour index") ); 
 330 wxFont 
wxSystemSettingsNative::GetFont( wxSystemFont index 
) 
 334         case wxSYS_OEM_FIXED_FONT
: 
 335         case wxSYS_ANSI_FIXED_FONT
: 
 336         case wxSYS_SYSTEM_FIXED_FONT
: 
 338             return *wxNORMAL_FONT
; 
 340         case wxSYS_ANSI_VAR_FONT
: 
 341         case wxSYS_SYSTEM_FONT
: 
 342         case wxSYS_DEVICE_DEFAULT_FONT
: 
 343         case wxSYS_DEFAULT_GUI_FONT
: 
 345             if (!gs_objects
.m_fontSystem
.Ok()) 
 347                 gs_objects
.m_fontSystem 
= wxFont( 12, wxSWISS
, wxNORMAL
, wxNORMAL 
); 
 349             return gs_objects
.m_fontSystem
; 
 357 int wxSystemSettingsNative::GetMetric( wxSystemMetric index
, wxWindow
* win 
) 
 365         // MBN: ditto for icons 
 366         case wxSYS_ICON_X
:     return 32; 
 367         case wxSYS_ICON_Y
:     return 32; 
 370             return gdk_screen_width(); 
 373             return gdk_screen_height(); 
 375         case wxSYS_HSCROLL_Y
:  return 15; 
 376         case wxSYS_VSCROLL_X
:  return 15; 
 378 // a gtk1 implementation should be possible too if gtk2 efficiency/convenience functions aren't used 
 380         case wxSYS_CAPTION_Y
: 
 382                 // No realized window specified, and no implementation for that case yet. 
 385             // Check if wm supports frame extents - we can't know the caption height if it does not. 
 386 #if GTK_CHECK_VERSION(2,2,0) 
 387             if (!gtk_check_version(2,2,0)) 
 389                 if (!gdk_x11_screen_supports_net_wm_hint( 
 390                         gdk_drawable_get_screen(window
), 
 391                         gdk_atom_intern("_NET_FRAME_EXTENTS", false) ) ) 
 397                 if (!gdk_net_wm_supports(gdk_atom_intern("_NET_FRAME_EXTENTS", false))) 
 401             wxASSERT_MSG( wxDynamicCast(win
, wxTopLevelWindow
), 
 402                           wxT("Asking for caption height of a non toplevel window") ); 
 404             // Get the height of the top windowmanager border. 
 405             // This is the titlebar in most cases. The titlebar might be elsewhere, and 
 406             // we could check which is the thickest wm border to decide on which side the 
 407             // titlebar is, but this might lead to interesting behaviours in used code. 
 408             // Reconsider when we have a way to report to the user on which side it is. 
 414 #if GTK_CHECK_VERSION(2,2,0) 
 415             if (!gtk_check_version(2,2,0)) 
 418                 success 
= (XGetWindowProperty (GDK_DISPLAY_XDISPLAY(gdk_drawable_get_display(window
)), 
 419                                     GDK_WINDOW_XWINDOW(window
), 
 420                                     gdk_x11_get_xatom_by_name_for_display ( 
 421                                             gdk_drawable_get_display(window
), 
 422                                             "_NET_FRAME_EXTENTS" ), 
 423                                     0, // left, right, top, bottom, CARDINAL[4]/32 
 424                                     G_MAXLONG
, // size of long 
 425                                     false, // do not delete property 
 426                                     XA_CARDINAL
, // 32 bit 
 427                                     &type
, &format
, &nitems
, &bytes_after
, &data
 
 433                 int caption_height 
= -1; 
 435                 if ((type 
== XA_CARDINAL
) && (format 
== 32) && (nitems 
>= 3) && (data
)) 
 438                     borders 
= (long*)data
; 
 439                     caption_height 
= borders
[2]; // top frame extent 
 445                 return caption_height
; 
 448             // Try a default approach without a window pointer, if possible 
 454         case wxSYS_PENWINDOWS_PRESENT
: 
 455             // No MS Windows for Pen computing extension available in X11 based gtk+. 
 459             return -1;   // metric is unknown 
 463 bool wxSystemSettingsNative::HasFeature(wxSystemFeature index
) 
 467         case wxSYS_CAN_ICONIZE_FRAME
: 
 470         case wxSYS_CAN_DRAW_FRAME_DECORATIONS
: