1 /* MS-Windows Engine (aka GTK-Wimp)
3 * Copyright (C) 2003, 2004 Raymond Penners <raymond@dotsphinx.com>
4 * Copyright (C) 2006 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
5 * Includes code adapted from redmond95 by Owen Taylor, and
6 * gtk-nativewin by Evan Martin
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
27 * http://lxr.mozilla.org/seamonkey/source/widget/src/windows/nsNativeThemeWin.cpp
28 * http://lxr.mozilla.org/seamonkey/source/widget/src/windows/nsLookAndFeel.cpp
29 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/functions/drawthemebackground.asp
30 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_4b3g.asp
33 /* Include first, else we get redefinition warnings about STRICT */
34 #include "pango/pangowin32.h"
36 #include "msw_style.h"
47 #ifdef BUILDING_STANDALONE
48 #include "gdk/gdkwin32.h"
50 #include "gdk/win32/gdkwin32.h"
54 /* Default values, not normally used
56 static const GtkRequisition default_option_indicator_size = { 9, 8 };
57 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
59 static GtkStyleClass *parent_class;
60 static HBRUSH g_dither_brush = NULL;
62 static HPEN g_light_pen = NULL;
63 static HPEN g_dark_pen = NULL;
85 static const unsigned char check_aa_bits[] = {
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00
94 static const unsigned char check_base_bits[] = {
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
97 0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
98 0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
99 0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
100 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00
103 static const unsigned char check_black_bits[] = {
104 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00,
105 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
106 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
107 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
108 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
109 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00
112 static const unsigned char check_dark_bits[] = {
113 0xff, 0x1f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
114 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
115 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
116 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
117 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
118 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
119 0x01, 0x00, 0x00, 0x00
121 static const unsigned char check_light_bits[] = {
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
123 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
124 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
125 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
126 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
127 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
128 0xfe, 0x1f, 0x00, 0x00
130 static const unsigned char check_mid_bits[] = {
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
133 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
134 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
135 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
136 0x00, 0x08, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00
139 static const unsigned char check_text_bits[] = {
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
142 0x00, 0x03, 0x00, 0x00, 0x88, 0x03, 0x00, 0x00,
143 0xd8, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
144 0x70, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00
148 static const unsigned char check_inconsistent_bits[] = {
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00
157 static const unsigned char radio_base_bits[] = {
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0xf0, 0x01, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00,
160 0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
161 0xfc, 0x07, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00,
162 0xfc, 0x07, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00,
163 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x00
166 static const unsigned char radio_black_bits[] = {
167 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00,
168 0x0c, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
169 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
170 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
171 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00
175 static const unsigned char radio_dark_bits[] = {
176 0xf0, 0x01, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00,
177 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
178 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
179 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
180 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
181 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00
184 static const unsigned char radio_light_bits[] = {
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
187 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
188 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
189 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
190 0x00, 0x08, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00,
191 0xf0, 0x01, 0x00, 0x00
193 static const unsigned char radio_mid_bits[] = {
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
196 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
197 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
198 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
199 0x0c, 0x06, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x00
202 static const unsigned char radio_text_bits[] = {
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00,
206 0xf0, 0x01, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00,
207 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00
214 const unsigned char *bits;
215 cairo_surface_t *bmap;
217 { check_aa_bits, NULL },
218 { check_base_bits, NULL },
219 { check_black_bits, NULL },
220 { check_dark_bits, NULL },
221 { check_light_bits, NULL },
222 { check_mid_bits, NULL },
223 { check_text_bits, NULL },
224 { check_inconsistent_bits, NULL },
225 { radio_base_bits, NULL },
226 { radio_black_bits, NULL },
227 { radio_dark_bits, NULL },
228 { radio_light_bits, NULL },
229 { radio_mid_bits, NULL },
230 { radio_text_bits, NULL }
234 _cairo_draw_line (cairo_t *cr,
243 gdk_cairo_set_source_color (cr, color);
244 cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
245 cairo_set_line_width (cr, 1.0);
247 cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
248 cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
255 _cairo_draw_rectangle (cairo_t *cr,
263 gdk_cairo_set_source_color (cr, color);
267 cairo_rectangle (cr, x, y, width, height);
272 cairo_rectangle (cr, x + 0.5, y + 0.5, width, height);
278 get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONTW *out_lf)
280 if (xp_theme_get_system_font (klazz, type, out_lf))
286 /* Use wide char versions here, as the theming functions only support
287 * wide chars versions of the structures. */
288 NONCLIENTMETRICSW ncm;
290 ncm.cbSize = sizeof (NONCLIENTMETRICSW);
292 if (SystemParametersInfoW (SPI_GETNONCLIENTMETRICS,
293 sizeof (NONCLIENTMETRICSW), &ncm, 0))
295 if (type == XP_THEME_FONT_CAPTION)
296 *out_lf = ncm.lfCaptionFont;
297 else if (type == XP_THEME_FONT_MENU)
298 *out_lf = ncm.lfMenuFont;
299 else if (type == XP_THEME_FONT_STATUS)
300 *out_lf = ncm.lfStatusFont;
302 *out_lf = ncm.lfMessageFont;
312 sys_font_to_pango_font (XpThemeClass klazz, XpThemeFont type, char *buf,
317 if (get_system_font (klazz, type, &lf))
319 PangoFontDescription *desc = NULL;
323 desc = pango_win32_font_description_from_logfontw (&lf);
327 font = pango_font_description_to_string (desc);
328 pt_size = pango_font_description_get_size (desc);
330 if (!(font && *font))
332 pango_font_description_free (desc);
341 hwnd = GetDesktopWindow ();
345 pt_size = -MulDiv (lf.lfHeight, 72, GetDeviceCaps (hDC, LOGPIXELSY));
350 ReleaseDC (hwnd, hDC);
352 g_snprintf (buf, bufsiz, "%s %d", font, pt_size);
356 g_snprintf (buf, bufsiz, "%s", font);
360 pango_font_description_free (desc);
368 /* missing from ms's header files */
369 #ifndef SPI_GETMENUSHOWDELAY
370 #define SPI_GETMENUSHOWDELAY 106
373 /* I don't know the proper XP theme class for things like
374 HIGHLIGHTTEXT, so we'll just define it to be "BUTTON"
376 #define XP_THEME_CLASS_TEXT XP_THEME_CLASS_BUTTON
378 #define WIN95_VERSION 0x400
379 #define WIN2K_VERSION 0x500
380 #define WINXP_VERSION 0x501
381 #define WIN2K3_VERSION 0x502
382 #define VISTA_VERSION 0x600
385 get_windows_version ()
387 static gint32 version = 0;
388 static gboolean have_version = FALSE;
392 OSVERSIONINFOEX osvi;
395 ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
396 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
398 GetVersionEx((OSVERSIONINFO*) &osvi);
400 version = (osvi.dwMajorVersion & 0xff) << 8 | (osvi.dwMinorVersion & 0xff);
407 setup_menu_settings (GtkSettings *settings)
410 GObjectClass *klazz = G_OBJECT_GET_CLASS (G_OBJECT (settings));
412 if (get_windows_version () > WIN95_VERSION)
414 if (SystemParametersInfo (SPI_GETMENUSHOWDELAY, 0, &menu_delay, 0))
418 if (g_object_class_find_property
419 (klazz, "gtk-menu-bar-popup-delay"))
421 g_object_set (settings,
422 "gtk-menu-bar-popup-delay", 0, NULL);
424 if (g_object_class_find_property
425 (klazz, "gtk-menu-popup-delay"))
427 g_object_set (settings,
428 "gtk-menu-popup-delay", menu_delay, NULL);
430 if (g_object_class_find_property
431 (klazz, "gtk-menu-popdown-delay"))
433 g_object_set (settings,
434 "gtk-menu-popdown-delay", menu_delay, NULL);
442 msw_style_setup_system_settings (void)
444 GtkSettings *settings;
445 int cursor_blink_time;
447 settings = gtk_settings_get_default ();
451 cursor_blink_time = GetCaretBlinkTime ();
452 g_object_set (settings, "gtk-cursor-blink", cursor_blink_time > 0, NULL);
454 if (cursor_blink_time > 0)
456 g_object_set (settings, "gtk-cursor-blink-time",
457 2 * cursor_blink_time, NULL);
460 g_object_set (settings, "gtk-double-click-distance",
461 GetSystemMetrics (SM_CXDOUBLECLK), NULL);
462 g_object_set (settings, "gtk-double-click-time", GetDoubleClickTime (),
464 g_object_set (settings, "gtk-dnd-drag-threshold",
465 GetSystemMetrics (SM_CXDRAG), NULL);
467 setup_menu_settings (settings);
470 http://developer.gnome.org/doc/API/2.0/gtk/GtkSettings.html
471 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/systemparametersinfo.asp
472 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getsystemmetrics.asp */
476 setup_system_font (GtkStyle *style)
478 char buf[256], *font; /* It's okay, lfFaceName is smaller than 32
481 if ((font = sys_font_to_pango_font (XP_THEME_CLASS_TEXT,
482 XP_THEME_FONT_MESSAGE,
483 buf, sizeof (buf))) != NULL)
485 if (style->font_desc)
487 pango_font_description_free (style->font_desc);
490 style->font_desc = pango_font_description_from_string (font);
495 sys_color_to_gtk_color (XpThemeClass klazz, int id, GdkColor * pcolor)
499 if (!xp_theme_get_system_color (klazz, id, &color))
500 color = GetSysColor (id);
502 pcolor->pixel = color;
503 pcolor->red = (GetRValue (color) << 8) | GetRValue (color);
504 pcolor->green = (GetGValue (color) << 8) | GetGValue (color);
505 pcolor->blue = (GetBValue (color) << 8) | GetBValue (color);
509 get_system_metric (XpThemeClass klazz, int id)
513 if (!xp_theme_get_system_metric (klazz, id, &rval))
514 rval = GetSystemMetrics (id);
520 setup_msw_rc_style (void)
522 char buf[1024], font_buf[256], *font_ptr;
523 char menu_bar_prelight_str[128];
526 GdkColor menu_text_color;
527 GdkColor tooltip_back;
528 GdkColor tooltip_fore;
531 GdkColor progress_back;
533 GdkColor fg_prelight;
534 GdkColor bg_prelight;
535 GdkColor base_prelight;
536 GdkColor text_prelight;
539 sys_color_to_gtk_color (get_windows_version () >= VISTA_VERSION ? XP_THEME_CLASS_MENU : XP_THEME_CLASS_TEXT,
540 get_windows_version () >= VISTA_VERSION ? COLOR_MENUTEXT : COLOR_HIGHLIGHTTEXT,
542 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT, &bg_prelight);
543 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
545 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
548 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENUTEXT,
550 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENU, &menu_color);
553 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOTEXT,
555 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOBK,
558 /* text on push buttons. TODO: button shadows, backgrounds, and
560 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT, &btn_fore);
561 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE, &btn_face);
563 /* progress bar background color */
564 sys_color_to_gtk_color (XP_THEME_CLASS_PROGRESS, COLOR_HIGHLIGHT,
567 /* Enable coloring for menus. */
569 sys_font_to_pango_font (XP_THEME_CLASS_MENU, XP_THEME_FONT_MENU,
570 font_buf, sizeof (font_buf));
571 g_snprintf (buf, sizeof (buf),
572 "style \"msw-menu\" = \"msw-default\"\n" "{\n"
573 "GtkMenuItem::toggle-spacing = 8\n"
574 "fg[PRELIGHT] = { %d, %d, %d }\n"
575 "bg[PRELIGHT] = { %d, %d, %d }\n"
576 "text[PRELIGHT] = { %d, %d, %d }\n"
577 "base[PRELIGHT] = { %d, %d, %d }\n"
578 "fg[NORMAL] = { %d, %d, %d }\n"
579 "bg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
580 "}widget_class \"*MenuItem*\" style \"msw-menu\"\n"
581 "widget_class \"*GtkMenu\" style \"msw-menu\"\n"
582 "widget_class \"*GtkMenuShell*\" style \"msw-menu\"\n",
583 fg_prelight.red, fg_prelight.green, fg_prelight.blue,
584 bg_prelight.red, bg_prelight.green, bg_prelight.blue,
585 text_prelight.red, text_prelight.green, text_prelight.blue,
586 base_prelight.red, base_prelight.green, base_prelight.blue,
587 menu_text_color.red, menu_text_color.green,
588 menu_text_color.blue, menu_color.red, menu_color.green,
589 menu_color.blue, (font_ptr ? "font_name" : "#"),
590 (font_ptr ? font_ptr : " font name should go here"));
591 gtk_rc_parse_string (buf);
593 if (xp_theme_is_active ())
595 *menu_bar_prelight_str = '\0';
599 g_snprintf (menu_bar_prelight_str, sizeof (menu_bar_prelight_str),
600 "fg[PRELIGHT] = { %d, %d, %d }\n",
601 menu_text_color.red, menu_text_color.green,
602 menu_text_color.blue);
605 /* Enable coloring for menu bars. */
606 g_snprintf (buf, sizeof (buf),
607 "style \"msw-menu-bar\" = \"msw-menu\"\n"
609 "bg[NORMAL] = { %d, %d, %d }\n"
610 "%s" "GtkMenuBar::shadow-type = %d\n"
612 FIXME: This should be enabled once gtk+ support
613 GtkMenuBar::prelight-item style property.
615 /* "GtkMenuBar::prelight-item = 1\n" */
616 "}widget_class \"*MenuBar*\" style \"msw-menu-bar\"\n",
617 btn_face.red, btn_face.green, btn_face.blue,
618 menu_bar_prelight_str, xp_theme_is_active ()? 0 : 2);
619 gtk_rc_parse_string (buf);
621 g_snprintf (buf, sizeof (buf),
622 "style \"msw-toolbar\" = \"msw-default\"\n"
624 "GtkHandleBox::shadow-type = %s\n"
625 "GtkToolbar::shadow-type = %s\n"
626 "}widget_class \"*HandleBox*\" style \"msw-toolbar\"\n",
627 "etched-in", "etched-in");
628 gtk_rc_parse_string (buf);
630 /* enable tooltip fonts */
631 font_ptr = sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
632 font_buf, sizeof (font_buf));
633 g_snprintf (buf, sizeof (buf),
634 "style \"msw-tooltips-caption\" = \"msw-default\"\n"
635 "{fg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
636 "}widget \"gtk-tooltips.GtkLabel\" style \"msw-tooltips-caption\"\n"
637 "widget \"gtk-tooltip.GtkLabel\" style \"msw-tooltips-caption\"\n",
638 tooltip_fore.red, tooltip_fore.green, tooltip_fore.blue,
639 (font_ptr ? "font_name" : "#"),
640 (font_ptr ? font_ptr : " font name should go here"));
641 gtk_rc_parse_string (buf);
643 g_snprintf (buf, sizeof (buf),
644 "style \"msw-tooltips\" = \"msw-default\"\n"
645 "{bg[NORMAL] = { %d, %d, %d }\n"
646 "}widget \"gtk-tooltips*\" style \"msw-tooltips\"\n"
647 "widget \"gtk-tooltip*\" style \"msw-tooltips\"\n",
648 tooltip_back.red, tooltip_back.green, tooltip_back.blue);
649 gtk_rc_parse_string (buf);
651 /* enable font theming for status bars */
652 font_ptr = sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
653 font_buf, sizeof (font_buf));
654 g_snprintf (buf, sizeof (buf),
655 "style \"msw-status\" = \"msw-default\"\n" "{%s = \"%s\"\n"
656 "bg[NORMAL] = { %d, %d, %d }\n"
657 "}widget_class \"*Status*\" style \"msw-status\"\n",
658 (font_ptr ? "font_name" : "#"),
659 (font_ptr ? font_ptr : " font name should go here"),
660 btn_face.red, btn_face.green, btn_face.blue);
661 gtk_rc_parse_string (buf);
663 /* enable coloring for text on buttons TODO: use GetThemeMetric for the
664 border and outside border */
665 g_snprintf (buf, sizeof (buf),
666 "style \"msw-button\" = \"msw-default\"\n"
668 "bg[NORMAL] = { %d, %d, %d }\n"
669 "bg[PRELIGHT] = { %d, %d, %d }\n"
670 "bg[INSENSITIVE] = { %d, %d, %d }\n"
671 "fg[PRELIGHT] = { %d, %d, %d }\n"
672 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
673 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
674 "GtkButton::child-displacement-x = 1\n"
675 "GtkButton::child-displacement-y = 1\n"
676 "GtkButton::focus-padding = %d\n"
677 "}widget_class \"*Button*\" style \"msw-button\"\n",
678 btn_face.red, btn_face.green, btn_face.blue,
679 btn_face.red, btn_face.green, btn_face.blue,
680 btn_face.red, btn_face.green, btn_face.blue,
681 btn_fore.red, btn_fore.green, btn_fore.blue,
682 xp_theme_is_active ()? 1 : 2);
683 gtk_rc_parse_string (buf);
685 /* enable coloring for progress bars */
686 g_snprintf (buf, sizeof (buf),
687 "style \"msw-progress\" = \"msw-default\"\n"
688 "{bg[PRELIGHT] = { %d, %d, %d }\n"
689 "bg[NORMAL] = { %d, %d, %d }\n"
690 "}widget_class \"*Progress*\" style \"msw-progress\"\n",
694 btn_face.red, btn_face.green, btn_face.blue);
695 gtk_rc_parse_string (buf);
697 /* scrollbar thumb width and height */
698 g_snprintf (buf, sizeof (buf),
699 "style \"msw-vscrollbar\" = \"msw-default\"\n"
700 "{GtkRange::slider-width = %d\n"
701 "GtkRange::stepper-size = %d\n"
702 "GtkRange::stepper-spacing = 0\n"
703 "GtkRange::trough_border = 0\n"
704 "GtkScale::slider-length = %d\n"
705 "GtkScrollbar::min-slider-length = 8\n"
706 "}widget_class \"*VScrollbar*\" style \"msw-vscrollbar\"\n"
707 "widget_class \"*VScale*\" style \"msw-vscrollbar\"\n",
708 GetSystemMetrics (SM_CYVTHUMB),
709 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CXVSCROLL), 11);
710 gtk_rc_parse_string (buf);
712 g_snprintf (buf, sizeof (buf),
713 "style \"msw-hscrollbar\" = \"msw-default\"\n"
714 "{GtkRange::slider-width = %d\n"
715 "GtkRange::stepper-size = %d\n"
716 "GtkRange::stepper-spacing = 0\n"
717 "GtkRange::trough_border = 0\n"
718 "GtkScale::slider-length = %d\n"
719 "GtkScrollbar::min-slider-length = 8\n"
720 "}widget_class \"*HScrollbar*\" style \"msw-hscrollbar\"\n"
721 "widget_class \"*HScale*\" style \"msw-hscrollbar\"\n",
722 GetSystemMetrics (SM_CXHTHUMB),
723 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CYHSCROLL), 11);
724 gtk_rc_parse_string (buf);
726 gtk_rc_parse_string ("style \"msw-scrolled-window\" = \"msw-default\"\n"
727 "{GtkScrolledWindow::scrollbars-within-bevel = 1}\n"
728 "class \"GtkScrolledWindow\" style \"msw-scrolled-window\"\n");
730 /* radio/check button sizes */
731 g_snprintf (buf, sizeof (buf),
732 "style \"msw-checkbutton\" = \"msw-button\"\n"
733 "{GtkCheckButton::indicator-size = 13\n"
734 "}widget_class \"*CheckButton*\" style \"msw-checkbutton\"\n"
735 "widget_class \"*RadioButton*\" style \"msw-checkbutton\"\n");
736 gtk_rc_parse_string (buf);
738 /* size of combo box toggle button */
739 g_snprintf (buf, sizeof (buf),
740 "style \"msw-combobox-button\" = \"msw-default\"\n"
744 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
745 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
746 "GtkButton::child-displacement-x = 0\n"
747 "GtkButton::child-displacement-y = 0\n"
748 "GtkWidget::focus-padding = 0\n"
749 "GtkWidget::focus-line-width = 0\n"
751 "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combobox-button\"\n");
752 gtk_rc_parse_string (buf);
754 g_snprintf (buf, sizeof (buf),
755 "style \"msw-combobox\" = \"msw-default\"\n"
757 "GtkComboBox::shadow-type = in\n"
761 "class \"GtkComboBox\" style \"msw-combobox\"\n",
762 xp_theme_is_active()? 1 : GetSystemMetrics (SM_CXEDGE),
763 xp_theme_is_active()? 1 : GetSystemMetrics (SM_CYEDGE));
764 gtk_rc_parse_string (buf);
766 /* size of tree view header */
767 g_snprintf (buf, sizeof (buf),
768 "style \"msw-header-button\" = \"msw-default\"\n"
772 "GtkWidget::draw-border = {0, 0, 0, 0}\n"
773 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
774 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
775 "GtkButton::child-displacement-x = 0\n"
776 "GtkButton::child-displacement-y = 0\n"
777 "GtkWidget::focus-padding = 0\n"
778 "GtkWidget::focus-line-width = 0\n"
780 "widget_class \"*TreeView*Button*\" style \"msw-header-button\"\n");
781 gtk_rc_parse_string (buf);
783 /* FIXME: This should be enabled once gtk+ support GtkNotebok::prelight-tab */
784 /* enable prelight tab of GtkNotebook */
786 g_snprintf (buf, sizeof (buf),
787 "style \"msw-notebook\" = \"msw-default\"\n"
788 "{GtkNotebook::prelight-tab=1\n"
789 "}widget_class \"*Notebook*\" style \"msw-notebook\"\n");
790 gtk_rc_parse_string (buf);
793 /* FIXME: This should be enabled once gtk+ support GtkTreeView::full-row-focus */
795 g_snprintf (buf, sizeof (buf),
796 "style \"msw-treeview\" = \"msw-default\"\n"
797 "{GtkTreeView::full-row-focus=0\n"
798 "}widget_class \"*TreeView*\" style \"msw-treeview\"\n");
799 gtk_rc_parse_string (buf);
804 setup_system_styles (GtkStyle *style)
808 /* Default background */
809 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
810 &style->bg[GTK_STATE_NORMAL]);
811 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
812 &style->bg[GTK_STATE_SELECTED]);
813 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
814 &style->bg[GTK_STATE_INSENSITIVE]);
815 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
816 &style->bg[GTK_STATE_ACTIVE]);
817 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
818 &style->bg[GTK_STATE_PRELIGHT]);
821 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
822 &style->base[GTK_STATE_NORMAL]);
823 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
824 &style->base[GTK_STATE_SELECTED]);
825 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
826 &style->base[GTK_STATE_INSENSITIVE]);
827 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
828 &style->base[GTK_STATE_ACTIVE]);
829 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
830 &style->base[GTK_STATE_PRELIGHT]);
833 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
834 &style->text[GTK_STATE_NORMAL]);
835 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
836 &style->text[GTK_STATE_SELECTED]);
837 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_GRAYTEXT,
838 &style->text[GTK_STATE_INSENSITIVE]);
839 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
840 &style->text[GTK_STATE_ACTIVE]);
841 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
842 &style->text[GTK_STATE_PRELIGHT]);
844 /* Default foreground */
845 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
846 &style->fg[GTK_STATE_NORMAL]);
847 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
848 &style->fg[GTK_STATE_SELECTED]);
849 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_GRAYTEXT,
850 &style->fg[GTK_STATE_INSENSITIVE]);
851 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
852 &style->bg[GTK_STATE_ACTIVE]);
853 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
854 &style->fg[GTK_STATE_PRELIGHT]);
856 for (i = 0; i < 5; i++)
858 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DSHADOW,
860 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DHILIGHT,
863 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
864 style->mid[i].green =
865 (style->light[i].green + style->dark[i].green) / 2;
866 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
868 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
869 style->text_aa[i].green =
870 (style->text[i].green + style->base[i].green) / 2;
871 style->text_aa[i].blue =
872 (style->text[i].blue + style->base[i].blue) / 2;
876 static XpThemeElement
877 map_gtk_progress_bar_to_xp (GtkProgressBar *progress_bar, gboolean trough)
881 switch (gtk_orientable_get_orientation (GTK_ORIENTABLE (progress_bar)))
883 case GTK_ORIENTATION_HORIZONTAL:
885 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_H
886 : XP_THEME_ELEMENT_PROGRESS_BAR_H;
891 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_V
892 : XP_THEME_ELEMENT_PROGRESS_BAR_V;
900 is_combo_box_child (GtkWidget *w)
907 for (tmp = gtk_widget_get_parent (w); tmp; tmp = gtk_widget_get_parent (tmp))
909 if (GTK_IS_COMBO_BOX (tmp))
916 /* This function is not needed anymore */
918 combo_box_draw_arrow (GtkStyle *style,
923 if (xp_theme_is_active ())
926 if (widget && GTK_IS_TOGGLE_BUTTON (widget->parent))
933 dc = get_window_dc (style, cr, state, &dc_info, area->x, area->y, area->width,
934 area->height, &rect);
935 border = (GTK_TOGGLE_BUTTON (gtk_widget_get_parent (widget))->
936 active ? DFCS_PUSHED | DFCS_FLAT : 0);
938 InflateRect (&rect, 1, 1);
939 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
941 release_window_dc (&dc_info);
950 draw_part (cairo_t *cr,
951 GdkColor *gc, gint x, gint y, Part part)
953 if (!parts[part].bmap)
955 parts[part].bmap = cairo_image_surface_create_for_data ((unsigned char *)parts[part].bits,
957 PART_SIZE, PART_SIZE, 4);
960 gdk_cairo_set_source_color (cr, gc);
961 cairo_mask_surface (cr, parts[part].bmap, x, y);
965 draw_check (GtkStyle *style,
968 GtkShadowType shadow,
970 const gchar *detail, gint x, gint y, gint width, gint height)
972 x -= (1 + PART_SIZE - width) / 2;
973 y -= (1 + PART_SIZE - height) / 2;
975 if (detail && strcmp (detail, "check") == 0) /* Menu item */
977 if (shadow == GTK_SHADOW_IN)
979 draw_part (cr, &style->black, x, y, CHECK_TEXT);
980 draw_part (cr, &style->dark[state], x, y, CHECK_AA);
985 XpThemeElement theme_elt = XP_THEME_ELEMENT_CHECKBOX;
988 case GTK_SHADOW_ETCHED_IN:
989 theme_elt = XP_THEME_ELEMENT_INCONSISTENT_CHECKBOX;
993 theme_elt = XP_THEME_ELEMENT_PRESSED_CHECKBOX;
1000 if (!xp_theme_draw (cr, theme_elt,
1001 style, x, y, width, height, state))
1003 if (detail && !strcmp (detail, "cellcheck"))
1004 state = GTK_STATE_NORMAL;
1006 draw_part (cr, &style->black, x, y, CHECK_BLACK);
1007 draw_part (cr, &style->dark[state], x, y, CHECK_DARK);
1008 draw_part (cr, &style->mid[state], x, y, CHECK_MID);
1009 draw_part (cr, &style->light[state], x, y, CHECK_LIGHT);
1010 draw_part (cr, &style->base[state], x, y, CHECK_BASE);
1012 if (shadow == GTK_SHADOW_IN)
1014 draw_part (cr, &style->text[state], x, y, CHECK_TEXT);
1015 draw_part (cr, &style->text_aa[state], x, y, CHECK_AA);
1017 else if (shadow == GTK_SHADOW_ETCHED_IN)
1019 draw_part (cr, &style->text[state], x, y, CHECK_INCONSISTENT);
1020 draw_part (cr, &style->text_aa[state], x, y, CHECK_AA);
1027 draw_expander (GtkStyle *style,
1031 const gchar *detail,
1032 gint x, gint y, GtkExpanderStyle expander_style)
1035 gint expander_semi_size;
1036 XpThemeElement xp_expander;
1038 gtk_widget_style_get (widget, "expander_size", &expander_size, NULL);
1040 switch (expander_style)
1042 case GTK_EXPANDER_COLLAPSED:
1043 case GTK_EXPANDER_SEMI_COLLAPSED:
1044 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED;
1048 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED;
1052 if ((expander_size % 2) == 0)
1055 if (expander_size > 2)
1059 gdk_cairo_set_source_color (cr, &style->fg[state]);
1062 expander_semi_size = expander_size / 2;
1063 x -= expander_semi_size;
1064 y -= expander_semi_size;
1066 if (!xp_theme_draw (cr, xp_expander, style,
1067 x, y, expander_size, expander_size, state))
1075 dc = get_window_dc (style, cr, state, &dc_info, x, y, expander_size,
1076 expander_size, &rect);
1077 FrameRect (dc, &rect, GetSysColorBrush (COLOR_GRAYTEXT));
1078 InflateRect (&rect, -1, -1);
1079 FillRect (dc, &rect,
1080 GetSysColorBrush (state ==
1081 GTK_STATE_INSENSITIVE ? COLOR_BTNFACE :
1084 InflateRect (&rect, -1, -1);
1086 pen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_WINDOWTEXT));
1087 old_pen = SelectObject (dc, pen);
1089 MoveToEx (dc, rect.left, rect.top - 2 + expander_semi_size, NULL);
1090 LineTo (dc, rect.right, rect.top - 2 + expander_semi_size);
1092 if (expander_style == GTK_EXPANDER_COLLAPSED ||
1093 expander_style == GTK_EXPANDER_SEMI_COLLAPSED)
1095 MoveToEx (dc, rect.left - 2 + expander_semi_size, rect.top, NULL);
1096 LineTo (dc, rect.left - 2 + expander_semi_size, rect.bottom);
1099 SelectObject (dc, old_pen);
1101 release_window_dc (&dc_info);
1106 draw_option (GtkStyle *style,
1109 GtkShadowType shadow,
1111 const gchar *detail, gint x, gint y, gint width, gint height)
1113 x -= (1 + PART_SIZE - width) / 2;
1114 y -= (1 + PART_SIZE - height) / 2;
1116 if (detail && strcmp (detail, "option") == 0) /* Menu item */
1118 if (shadow == GTK_SHADOW_IN)
1120 draw_part (cr, &style->fg[state], x, y, RADIO_TEXT);
1125 if (xp_theme_draw (cr, shadow == GTK_SHADOW_IN
1126 ? XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON
1127 : XP_THEME_ELEMENT_RADIO_BUTTON,
1128 style, x, y, width, height, state))
1133 if (detail && !strcmp (detail, "cellradio"))
1134 state = GTK_STATE_NORMAL;
1136 draw_part (cr, &style->black, x, y, RADIO_BLACK);
1137 draw_part (cr, &style->dark[state], x, y, RADIO_DARK);
1138 draw_part (cr, &style->mid[state], x, y, RADIO_MID);
1139 draw_part (cr, &style->light[state], x, y, RADIO_LIGHT);
1140 draw_part (cr, &style->base[state], x, y, RADIO_BASE);
1142 if (shadow == GTK_SHADOW_IN)
1143 draw_part (cr, &style->text[state], x, y, RADIO_TEXT);
1149 draw_varrow (cairo_t *cr,
1151 GtkShadowType shadow_type,
1152 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1155 gint y_start, y_increment;
1158 width = width + width % 2 - 1; /* Force odd */
1159 steps = 1 + width / 2;
1160 extra = height - steps;
1162 if (arrow_type == GTK_ARROW_DOWN)
1169 y_start = y + height - 1;
1173 for (i = extra; i < height; i++)
1175 _cairo_draw_line (cr, gc,
1176 x + (i - extra), y_start + i * y_increment,
1177 x + width - (i - extra) - 1, y_start + i * y_increment);
1182 draw_harrow (cairo_t *cr,
1184 GtkShadowType shadow_type,
1185 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1188 gint x_start, x_increment;
1191 height = height + height % 2 - 1; /* Force odd */
1192 steps = 1 + height / 2;
1193 extra = width - steps;
1195 if (arrow_type == GTK_ARROW_RIGHT)
1202 x_start = x + width - 1;
1206 for (i = extra; i < width; i++)
1208 _cairo_draw_line (cr, gc,
1209 x_start + i * x_increment, y + (i - extra),
1210 x_start + i * x_increment, y + height - (i - extra) - 1);
1214 /* This function makes up for some brokeness in gtkrange.c
1215 * where we never get the full arrow of the stepper button
1216 * and the type of button in a single drawing function.
1218 * It doesn't work correctly when the scrollbar is squished
1219 * to the point we don't have room for full-sized steppers.
1222 reverse_engineer_stepper_box (GtkWidget *range,
1223 GtkArrowType arrow_type,
1224 gint *x, gint *y, gint *width, gint *height)
1226 gint slider_width = 14, stepper_size = 14;
1232 gtk_widget_style_get (range,
1233 "slider_width", &slider_width,
1234 "stepper_size", &stepper_size, NULL);
1237 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1239 box_width = slider_width;
1240 box_height = stepper_size;
1244 box_width = stepper_size;
1245 box_height = slider_width;
1248 *x = *x - (box_width - *width) / 2;
1249 *y = *y - (box_height - *height) / 2;
1251 *height = box_height;
1254 static XpThemeElement
1255 to_xp_arrow (GtkArrowType arrow_type)
1257 XpThemeElement xp_arrow;
1262 xp_arrow = XP_THEME_ELEMENT_ARROW_UP;
1265 case GTK_ARROW_DOWN:
1266 xp_arrow = XP_THEME_ELEMENT_ARROW_DOWN;
1269 case GTK_ARROW_LEFT:
1270 xp_arrow = XP_THEME_ELEMENT_ARROW_LEFT;
1274 xp_arrow = XP_THEME_ELEMENT_ARROW_RIGHT;
1282 draw_arrow (GtkStyle *style,
1285 GtkShadowType shadow,
1287 const gchar *detail,
1288 GtkArrowType arrow_type,
1289 gboolean fill, gint x, gint y, gint width, gint height)
1296 name = gtk_widget_get_name (widget);
1298 if (GTK_IS_ARROW (widget) && is_combo_box_child (widget) && xp_theme_is_active ())
1301 if (detail && strcmp (detail, "spinbutton") == 0)
1303 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1310 if (arrow_type == GTK_ARROW_DOWN)
1314 if (state == GTK_STATE_ACTIVE)
1320 draw_varrow (cr, &style->fg[state], shadow,
1321 arrow_type, x, y, width, height);
1325 else if (detail && (!strcmp (detail, "vscrollbar")
1326 || !strcmp (detail, "hscrollbar")))
1328 gboolean is_disabled = FALSE;
1330 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1334 gint box_width = width;
1335 gint box_height = height;
1337 reverse_engineer_stepper_box (widget, arrow_type,
1338 &box_x, &box_y, &box_width, &box_height);
1340 if (gtk_range_get_adjustment(&scrollbar->range)->page_size >=
1341 (gtk_range_get_adjustment(&scrollbar->range)->upper -
1342 gtk_range_get_adjustment(&scrollbar->range)->lower))
1347 if (xp_theme_draw (cr, to_xp_arrow (arrow_type), style, box_x, box_y,
1348 box_width, box_height, state))
1356 btn_type = DFCS_SCROLLUP;
1359 case GTK_ARROW_DOWN:
1360 btn_type = DFCS_SCROLLDOWN;
1363 case GTK_ARROW_LEFT:
1364 btn_type = DFCS_SCROLLLEFT;
1367 case GTK_ARROW_RIGHT:
1368 btn_type = DFCS_SCROLLRIGHT;
1371 case GTK_ARROW_NONE:
1375 if (state == GTK_STATE_INSENSITIVE)
1377 btn_type |= DFCS_INACTIVE;
1382 dc = get_window_dc (style, cr, state, &dc_info,
1383 box_x, box_y, box_width, box_height, &rect);
1384 DrawFrameControl (dc, &rect, DFC_SCROLL,
1385 btn_type | (shadow ==
1386 GTK_SHADOW_IN ? (DFCS_PUSHED |
1388 release_window_dc (&dc_info);
1394 /* draw the toolbar chevrons - waiting for GTK 2.4 */
1395 if (name && !strcmp (name, "gtk-toolbar-arrow"))
1398 (cr, XP_THEME_ELEMENT_REBAR_CHEVRON, style, x, y,
1399 width, height, state))
1404 /* probably a gtk combo box on a toolbar */
1405 else if (0 /* gtk_widget_get_parent (widget) && GTK_IS_BUTTON
1406 (gtk_widget_get_parent (widget)) */ )
1408 GtkAllocation allocation;
1410 gtk_widget_get_allocation (widget, &allocation);
1412 (cr, XP_THEME_ELEMENT_COMBOBUTTON, style, x - 3,
1413 allocation.y + 1, width + 5,
1414 allocation.height - 4, state))
1420 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1422 x += (width - 7) / 2;
1423 y += (height - 5) / 2;
1425 draw_varrow (cr, &style->fg[state], shadow,
1426 arrow_type, x, y, 7, 5);
1430 x += (width - 5) / 2;
1431 y += (height - 7) / 2;
1433 draw_harrow (cr, &style->fg[state], shadow,
1434 arrow_type, x, y, 5, 7);
1440 option_menu_get_props (GtkWidget *widget,
1441 GtkRequisition *indicator_size,
1442 GtkBorder *indicator_spacing)
1444 GtkRequisition *tmp_size = NULL;
1445 GtkBorder *tmp_spacing = NULL;
1448 gtk_widget_style_get (widget,
1449 "indicator_size", &tmp_size,
1450 "indicator_spacing", &tmp_spacing, NULL);
1454 *indicator_size = *tmp_size;
1455 gtk_requisition_free (tmp_size);
1459 *indicator_size = default_option_indicator_size;
1464 *indicator_spacing = *tmp_spacing;
1465 gtk_border_free (tmp_spacing);
1469 *indicator_spacing = default_option_indicator_spacing;
1474 is_toolbar_child (GtkWidget *wid)
1478 if (GTK_IS_TOOLBAR (wid) || GTK_IS_HANDLE_BOX (wid))
1481 wid = gtk_widget_get_parent (wid);
1488 is_menu_tool_button_child (GtkWidget *wid)
1492 if (GTK_IS_MENU_TOOL_BUTTON (wid))
1495 wid = gtk_widget_get_parent (wid);
1505 g_light_pen = CreatePen (PS_SOLID | PS_INSIDEFRAME, 1,
1506 GetSysColor (COLOR_BTNHIGHLIGHT));
1517 g_dark_pen = CreatePen (PS_SOLID | PS_INSIDEFRAME, 1,
1518 GetSysColor (COLOR_BTNSHADOW));
1525 draw_3d_border (HDC hdc, RECT *rc, gboolean sunken)
1532 pen1 = get_dark_pen ();
1533 pen2 = get_light_pen ();
1537 pen1 = get_light_pen ();
1538 pen2 = get_dark_pen ();
1541 MoveToEx (hdc, rc->left, rc->bottom - 1, NULL);
1543 old_pen = SelectObject (hdc, pen1);
1544 LineTo (hdc, rc->left, rc->top);
1545 LineTo (hdc, rc->right - 1, rc->top);
1546 SelectObject (hdc, old_pen);
1548 old_pen = SelectObject (hdc, pen2);
1549 LineTo (hdc, rc->right - 1, rc->bottom - 1);
1550 LineTo (hdc, rc->left, rc->bottom - 1);
1551 SelectObject (hdc, old_pen);
1555 draw_menu_item (cairo_t *cr, GtkWidget *widget, GtkStyle *style,
1556 gint x, gint y, gint width, gint height,
1557 GtkStateType state_type)
1565 if (xp_theme_is_active ())
1567 return (xp_theme_draw (cr, XP_THEME_ELEMENT_MENU_ITEM, style,
1568 x, y, width, height, state_type));
1571 if ((parent = gtk_widget_get_parent (widget))
1572 && GTK_IS_MENU_BAR (parent) && !xp_theme_is_active ())
1574 bar = GTK_MENU_SHELL (parent);
1576 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
1578 if (state_type == GTK_STATE_PRELIGHT)
1580 draw_3d_border (dc, &rect, bar->active);
1583 release_window_dc (&dc_info);
1592 get_dither_brush (void)
1595 HBITMAP pattern_bmp;
1599 return g_dither_brush;
1601 for (i = 0; i < 8; i++)
1603 pattern[i] = (WORD) (0x5555 << (i & 1));
1606 pattern_bmp = CreateBitmap (8, 8, 1, 1, &pattern);
1610 g_dither_brush = CreatePatternBrush (pattern_bmp);
1611 DeleteObject (pattern_bmp);
1614 return g_dither_brush;
1618 draw_tool_button (cairo_t *cr, GtkWidget *widget, GtkStyle *style,
1619 gint x, gint y, gint width, gint height,
1620 GtkStateType state_type)
1625 gboolean is_toggled = FALSE;
1627 if (xp_theme_is_active ())
1629 return (xp_theme_draw (cr, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
1630 x, y, width, height, state_type));
1633 if (GTK_IS_TOGGLE_BUTTON (widget))
1635 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1641 if (state_type != GTK_STATE_PRELIGHT
1642 && state_type != GTK_STATE_ACTIVE && !is_toggled)
1647 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
1648 if (state_type == GTK_STATE_PRELIGHT)
1652 FillRect (dc, &rect, GetSysColorBrush (COLOR_BTNFACE));
1655 draw_3d_border (dc, &rect, is_toggled);
1657 else if (state_type == GTK_STATE_ACTIVE)
1659 if (is_toggled && !is_menu_tool_button_child (gtk_widget_get_parent (widget)))
1661 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
1662 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
1663 FillRect (dc, &rect, get_dither_brush ());
1666 draw_3d_border (dc, &rect, TRUE);
1669 release_window_dc (&dc_info);
1675 draw_push_button (cairo_t *cr, GtkWidget *widget, GtkStyle *style,
1676 gint x, gint y, gint width, gint height,
1677 GtkStateType state_type, gboolean is_default)
1683 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
1685 if (GTK_IS_TOGGLE_BUTTON (widget))
1687 if (state_type == GTK_STATE_PRELIGHT &&
1688 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1690 state_type = GTK_STATE_ACTIVE;
1694 if (state_type == GTK_STATE_ACTIVE)
1696 if (GTK_IS_TOGGLE_BUTTON (widget))
1698 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1699 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
1700 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
1701 FillRect (dc, &rect, get_dither_brush ());
1705 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
1706 InflateRect (&rect, -1, -1);
1707 FrameRect (dc, &rect, GetSysColorBrush (COLOR_BTNSHADOW));
1708 InflateRect (&rect, -1, -1);
1709 FillRect (dc, &rect, GetSysColorBrush (COLOR_BTNFACE));
1714 if (is_default || gtk_widget_has_focus (widget))
1716 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
1717 InflateRect (&rect, -1, -1);
1720 DrawFrameControl (dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH);
1723 release_window_dc (&dc_info);
1727 draw_box (GtkStyle *style,
1729 GtkStateType state_type,
1730 GtkShadowType shadow_type,
1732 const gchar *detail, gint x, gint y, gint width, gint height)
1734 if (is_combo_box_child (widget) && detail && !strcmp (detail, "button"))
1742 border = (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)) ? DFCS_PUSHED | DFCS_FLAT : 0);
1744 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
1745 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
1746 release_window_dc (&dc_info);
1748 if (xp_theme_is_active ()
1749 && xp_theme_draw (cr, XP_THEME_ELEMENT_COMBOBUTTON, style, x, y,
1750 width, height, state_type))
1752 cx = GetSystemMetrics(SM_CXVSCROLL);
1757 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width - cx, height, &rect);
1758 FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
1759 release_window_dc (&dc_info);
1765 (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
1767 if (GTK_IS_TREE_VIEW (gtk_widget_get_parent (widget)))
1770 (cr, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
1771 width, height, state_type))
1780 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
1782 DrawFrameControl (dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH |
1784 GTK_STATE_ACTIVE ? (DFCS_PUSHED | DFCS_FLAT)
1786 release_window_dc (&dc_info);
1789 else if (is_toolbar_child (gtk_widget_get_parent (widget))
1790 || (!GTK_IS_BUTTON (widget) ||
1791 (GTK_RELIEF_NONE == gtk_button_get_relief (GTK_BUTTON (widget)))))
1793 if (draw_tool_button (cr, widget, style, x, y,
1794 width, height, state_type))
1801 gboolean is_default = gtk_widget_has_default (widget);
1804 is_default ? XP_THEME_ELEMENT_DEFAULT_BUTTON :
1805 XP_THEME_ELEMENT_BUTTON, style, x, y, width, height,
1811 draw_push_button (cr, widget, style,
1812 x, y, width, height, state_type, is_default);
1819 else if (detail && !strcmp (detail, "spinbutton"))
1821 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1826 else if (detail && (!strcmp (detail, "spinbutton_up")
1827 || !strcmp (detail, "spinbutton_down")))
1829 if (!xp_theme_draw (cr,
1830 (!strcmp (detail, "spinbutton_up"))
1831 ? XP_THEME_ELEMENT_SPIN_BUTTON_UP
1832 : XP_THEME_ELEMENT_SPIN_BUTTON_DOWN,
1833 style, x, y, width, height, state_type))
1839 dc = get_window_dc (style, cr, state_type, &dc_info,
1840 x, y, width, height, &rect);
1841 DrawEdge (dc, &rect,
1843 GTK_STATE_ACTIVE ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT);
1844 release_window_dc (&dc_info);
1848 else if (detail && !strcmp (detail, "slider"))
1850 if (GTK_IS_SCROLLBAR (widget))
1852 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1853 gboolean is_v = GTK_IS_VSCROLLBAR (widget);
1855 if (xp_theme_draw (cr,
1857 ? XP_THEME_ELEMENT_SCROLLBAR_V
1858 : XP_THEME_ELEMENT_SCROLLBAR_H,
1859 style, x, y, width, height, state_type))
1861 XpThemeElement gripper =
1862 (is_v ? XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V :
1863 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H);
1865 /* Do not display grippers on tiny scroll bars,
1866 the limit imposed is rather arbitrary, perhaps
1867 we can fetch the gripper geometry from
1868 somewhere and use that... */
1870 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H
1873 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V && height < 16))
1878 xp_theme_draw (cr, gripper, style, x, y,
1879 width, height, state_type);
1884 if (gtk_range_get_adjustment(&scrollbar->range)->page_size >=
1885 (gtk_range_get_adjustment(&scrollbar->range)->upper -
1886 gtk_range_get_adjustment(&scrollbar->range)->lower))
1893 else if (detail && !strcmp (detail, "bar"))
1895 if (widget && GTK_IS_PROGRESS_BAR (widget))
1897 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
1898 XpThemeElement xp_progress_bar =
1899 map_gtk_progress_bar_to_xp (progress_bar, FALSE);
1901 if (xp_theme_draw (cr, xp_progress_bar, style, x, y,
1902 width, height, state_type))
1907 shadow_type = GTK_SHADOW_NONE;
1910 else if (detail && strcmp (detail, "menuitem") == 0)
1912 shadow_type = GTK_SHADOW_NONE;
1913 if (draw_menu_item (cr, widget, style,
1914 x, y, width, height, state_type))
1919 else if (detail && !strcmp (detail, "trough"))
1921 if (widget && GTK_IS_PROGRESS_BAR (widget))
1923 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
1924 XpThemeElement xp_progress_bar =
1925 map_gtk_progress_bar_to_xp (progress_bar, TRUE);
1927 (cr, xp_progress_bar, style, x, y, width, height,
1934 /* Blank in classic Windows */
1937 else if (widget && GTK_IS_SCROLLBAR (widget))
1939 gboolean is_vertical = GTK_IS_VSCROLLBAR (widget);
1941 if (xp_theme_draw (cr,
1943 ? XP_THEME_ELEMENT_TROUGH_V
1944 : XP_THEME_ELEMENT_TROUGH_H,
1945 style, x, y, width, height, state_type))
1955 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
1957 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
1958 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
1959 FillRect (dc, &rect, get_dither_brush ());
1961 release_window_dc (&dc_info);
1966 else if (widget && GTK_IS_SCALE (widget))
1968 gboolean is_vertical = GTK_IS_VSCALE (widget);
1970 if (!xp_theme_is_active ())
1972 parent_class->draw_box (style, cr, state_type,
1974 widget, detail, x, y, width, height);
1980 (cr, XP_THEME_ELEMENT_SCALE_TROUGH_V,
1981 style, (2 * x + width) / 2, y, 2, height,
1987 parent_class->draw_box (style, cr, state_type,
1988 GTK_SHADOW_ETCHED_IN,
1990 (2 * x + width) / 2, y, 1, height);
1995 (cr, XP_THEME_ELEMENT_SCALE_TROUGH_H,
1996 style, x, (2 * y + height) / 2, width, 2,
2002 parent_class->draw_box (style, cr, state_type,
2003 GTK_SHADOW_ETCHED_IN,
2005 (2 * y + height) / 2, width, 1);
2011 else if (detail && strcmp (detail, "optionmenu") == 0)
2013 if (xp_theme_draw (cr, XP_THEME_ELEMENT_EDIT_TEXT,
2014 style, x, y, width, height, state_type))
2020 && (strcmp (detail, "vscrollbar") == 0
2021 || strcmp (detail, "hscrollbar") == 0))
2026 && (strcmp (detail, "handlebox_bin") == 0
2027 || strcmp (detail, "toolbar") == 0
2028 || strcmp (detail, "menubar") == 0))
2030 if (xp_theme_draw (cr, XP_THEME_ELEMENT_REBAR,
2031 style, x, y, width, height, state_type))
2036 else if (detail && (!strcmp (detail, "handlebox"))) /* grip */
2038 if (!xp_theme_is_active ())
2043 else if (detail && !strcmp (detail, "notebook") && GTK_IS_NOTEBOOK (widget))
2045 if (xp_theme_draw (cr, XP_THEME_ELEMENT_TAB_PANE, style,
2046 x, y, width, height, state_type))
2054 const gchar *name = gtk_widget_get_name (widget);
2056 if (name && !strcmp (name, "gtk-tooltips"))
2059 (cr, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
2060 height, state_type))
2071 hdc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
2073 brush = GetSysColorBrush (COLOR_3DDKSHADOW);
2077 FrameRect (hdc, &rect, brush);
2080 InflateRect (&rect, -1, -1);
2081 FillRect (hdc, &rect, (HBRUSH) (COLOR_INFOBK + 1));
2083 release_window_dc (&dc_info);
2090 parent_class->draw_box (style, cr, state_type, shadow_type,
2091 widget, detail, x, y, width, height);
2093 if (detail && strcmp (detail, "optionmenu") == 0)
2095 GtkRequisition indicator_size;
2096 GtkBorder indicator_spacing;
2099 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2101 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
2104 x + indicator_size.width + indicator_spacing.left +
2105 indicator_spacing.right;
2109 vline_x = x + width - (indicator_size.width +
2110 indicator_spacing.left +
2111 indicator_spacing.right) - style->xthickness;
2113 parent_class->draw_vline (style, cr, state_type, widget,
2115 y + style->ythickness + 1,
2116 y + height - style->ythickness - 3, vline_x);
2122 draw_tab (GtkStyle *style,
2125 GtkShadowType shadow,
2127 const gchar *detail, gint x, gint y, gint width, gint height)
2129 GtkRequisition indicator_size;
2130 GtkBorder indicator_spacing;
2134 g_return_if_fail (style != NULL);
2135 g_return_if_fail (cr != NULL);
2137 if (detail && !strcmp (detail, "optionmenutab"))
2139 GtkAllocation allocation;
2141 gtk_widget_get_allocation (widget, &allocation);
2142 if (xp_theme_draw (cr, XP_THEME_ELEMENT_COMBOBUTTON,
2143 style, x - 5, allocation.y + 1,
2144 width + 10, allocation.height - 2,
2151 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2153 x += (width - indicator_size.width) / 2;
2154 arrow_height = (indicator_size.width + 1) / 2;
2156 y += (height - arrow_height) / 2;
2158 draw_varrow (cr, &style->black, shadow, GTK_ARROW_DOWN,
2159 x, y, indicator_size.width, arrow_height);
2162 /* Draw classic Windows tab - thanks Mozilla!
2163 (no system API for this, but DrawEdge can draw all the parts of a tab) */
2165 DrawTab (HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
2166 gboolean aDrawLeft, gboolean aDrawRight)
2168 gint32 leftFlag, topFlag, rightFlag, lightFlag, shadeFlag;
2169 RECT topRect, sideRect, bottomRect, lightRect, shadeRect;
2170 gint32 selectedOffset, lOffset, rOffset;
2172 selectedOffset = aSelected ? 1 : 0;
2173 lOffset = aDrawLeft ? 2 : 0;
2174 rOffset = aDrawRight ? 2 : 0;
2176 /* Get info for tab orientation/position (Left, Top, Right, Bottom) */
2182 rightFlag = BF_BOTTOM;
2183 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2184 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2186 SetRect (&topRect, R.left, R.top + lOffset, R.right,
2187 R.bottom - rOffset);
2188 SetRect (&sideRect, R.left + 2, R.top, R.right - 2 + selectedOffset,
2190 SetRect (&bottomRect, R.right - 2, R.top, R.right, R.bottom);
2191 SetRect (&lightRect, R.left, R.top, R.left + 3, R.top + 3);
2192 SetRect (&shadeRect, R.left + 1, R.bottom - 2, R.left + 2,
2199 rightFlag = BF_RIGHT;
2200 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2201 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2203 SetRect (&topRect, R.left + lOffset, R.top, R.right - rOffset,
2205 SetRect (&sideRect, R.left, R.top + 2, R.right,
2206 R.bottom - 1 + selectedOffset);
2207 SetRect (&bottomRect, R.left, R.bottom - 1, R.right, R.bottom);
2208 SetRect (&lightRect, R.left, R.top, R.left + 3, R.top + 3);
2209 SetRect (&shadeRect, R.right - 2, R.top + 1, R.right - 1, R.top + 2);
2215 rightFlag = BF_BOTTOM;
2216 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2217 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2219 SetRect (&topRect, R.left, R.top + lOffset, R.right,
2220 R.bottom - rOffset);
2221 SetRect (&sideRect, R.left + 2 - selectedOffset, R.top, R.right - 2,
2223 SetRect (&bottomRect, R.left, R.top, R.left + 2, R.bottom);
2224 SetRect (&lightRect, R.right - 3, R.top, R.right - 1, R.top + 2);
2225 SetRect (&shadeRect, R.right - 2, R.bottom - 3, R.right, R.bottom - 1);
2230 topFlag = BF_BOTTOM;
2231 rightFlag = BF_RIGHT;
2232 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2233 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2235 SetRect (&topRect, R.left + lOffset, R.top, R.right - rOffset,
2237 SetRect (&sideRect, R.left, R.top + 2 - selectedOffset, R.right,
2239 SetRect (&bottomRect, R.left, R.top, R.right, R.top + 2);
2240 SetRect (&lightRect, R.left, R.bottom - 3, R.left + 2, R.bottom - 1);
2241 SetRect (&shadeRect, R.right - 2, R.bottom - 3, R.right, R.bottom - 1);
2245 g_return_if_reached ();
2249 FillRect (hdc, &R, (HBRUSH) (COLOR_3DFACE + 1));
2252 DrawEdge (hdc, &topRect, EDGE_RAISED, BF_SOFT | topFlag);
2256 DrawEdge (hdc, &bottomRect, EDGE_RAISED, BF_SOFT | topFlag);
2264 DrawEdge (hdc, &sideRect, EDGE_RAISED, BF_SOFT | leftFlag | rightFlag);
2266 /* Tab Diagonal Corners */
2268 DrawEdge (hdc, &lightRect, EDGE_RAISED, BF_SOFT | lightFlag);
2271 DrawEdge (hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
2275 draw_themed_tab_button (GtkStyle *style,
2277 GtkStateType state_type,
2278 GtkNotebook *notebook,
2280 gint width, gint height, gint gap_side)
2283 GdkPixmap *pixmap = NULL;
2286 gtk_container_get_border_width (GTK_CONTAINER (notebook));
2287 GtkWidget *widget = GTK_WIDGET (notebook);
2288 GdkRectangle draw_rect;
2289 GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
2290 GtkAllocation allocation;
2292 gtk_widget_get_allocation (widget, &allocation);
2294 if (gap_side == GTK_POS_TOP)
2298 if (state_type == GTK_STATE_NORMAL)
2302 draw_rect.width = width + 2;
2303 draw_rect.height = height;
2311 draw_rect.x = x + 2;
2313 draw_rect.width = width - 2;
2314 draw_rect.height = height - 2;
2317 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2318 widget_right = allocation.x + allocation.width - border_width - 2;
2320 if (draw_rect.x + draw_rect.width >= widget_right)
2322 draw_rect.width = widget_right - draw_rect.x;
2325 if (gap_side == GTK_POS_BOTTOM)
2329 if (state_type == GTK_STATE_NORMAL)
2333 draw_rect.width = width + 2;
2334 draw_rect.height = height;
2338 draw_rect.x = x + 2;
2339 draw_rect.y = y + 2;
2340 draw_rect.width = width - 2;
2341 draw_rect.height = height - 2;
2344 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2345 widget_right = allocation.x + allocation.width - border_width - 2;
2347 if (draw_rect.x + draw_rect.width >= widget_right)
2349 draw_rect.width = widget_right - draw_rect.x;
2352 rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
2354 else if (gap_side == GTK_POS_LEFT)
2358 if (state_type == GTK_STATE_NORMAL)
2362 draw_rect.width = width;
2363 draw_rect.height = height + 2;
2372 draw_rect.y = y + 2;
2373 draw_rect.width = width - 2;
2374 draw_rect.height = height - 2;
2377 /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
2378 widget_bottom = allocation.x + allocation.height - border_width - 2;
2380 if (draw_rect.y + draw_rect.height >= widget_bottom)
2382 draw_rect.height = widget_bottom - draw_rect.y;
2385 rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
2387 else if (gap_side == GTK_POS_RIGHT)
2391 if (state_type == GTK_STATE_NORMAL)
2393 draw_rect.x = x + 1;
2395 draw_rect.width = width;
2396 draw_rect.height = height + 2;
2404 draw_rect.x = x + 2;
2405 draw_rect.y = y + 2;
2406 draw_rect.width = width - 2;
2407 draw_rect.height = height - 2;
2410 /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
2411 widget_bottom = allocation.x + allocation.height - border_width - 2;
2413 if (draw_rect.y + draw_rect.height >= widget_bottom)
2415 draw_rect.height = widget_bottom - draw_rect.y;
2418 rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
2421 if (gap_side == GTK_POS_TOP)
2423 if (!xp_theme_draw (cr, XP_THEME_ELEMENT_TAB_ITEM, style,
2424 draw_rect.x, draw_rect.y,
2425 draw_rect.width, draw_rect.height,
2438 if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_RIGHT)
2440 pixmap = gdk_pixmap_new (cr, draw_rect.height, draw_rect.width, -1);
2442 if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
2444 draw_rect.y - draw_rect.y, draw_rect.x - draw_rect.x,
2445 draw_rect.height, draw_rect.width, state_type, 0))
2447 g_object_unref (pixmap);
2451 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
2452 draw_rect.height, draw_rect.width);
2453 g_object_unref (pixmap);
2457 pixmap = gdk_pixmap_new (cr, draw_rect.width, draw_rect.height, -1);
2459 if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
2461 draw_rect.x - draw_rect.x, draw_rect.y - draw_rect.y,
2462 draw_rect.width, draw_rect.height, state_type, 0))
2464 g_object_unref (pixmap);
2468 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
2469 draw_rect.width, draw_rect.height);
2470 g_object_unref (pixmap);
2473 rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
2474 g_object_unref (pixbuf);
2477 // XXX - This is really hacky and evil. When we're drawing the left-most tab
2478 // while it is active on a bottom-oriented notebook, there is one white
2479 // pixel at the top. There may be a better solution than this if someone
2480 // has time to discover it.
2481 if (gap_side == GTK_POS_BOTTOM && state_type == GTK_STATE_NORMAL
2482 && x == allocation.x)
2484 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
2485 int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
2488 guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
2489 guchar *p = pixels + rowstride;
2491 for (psub = 0; psub < n_channels; psub++)
2493 pixels[psub] = p[psub];
2497 gdk_cairo_set_source_pixbuf (cr, pixbuf, clip_rect.x, clip_rect.y);
2499 g_object_unref (pixbuf);
2507 draw_tab_button (GtkStyle *style,
2509 GtkStateType state_type,
2510 GtkShadowType shadow_type,
2512 const gchar *detail,
2513 gint x, gint y, gint width, gint height, gint gap_side)
2515 if (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM)
2517 /* experimental tab-drawing code from mozilla */
2523 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
2525 if (gap_side == GTK_POS_TOP)
2527 else if (gap_side == GTK_POS_BOTTOM)
2528 aPosition = BF_BOTTOM;
2529 else if (gap_side == GTK_POS_LEFT)
2530 aPosition = BF_LEFT;
2532 aPosition = BF_RIGHT;
2534 if (state_type == GTK_STATE_PRELIGHT)
2535 state_type = GTK_STATE_NORMAL;
2538 gdk_cairo_set_source_color (cr, &style->dark[state_type]);
2541 DrawTab (dc, rect, aPosition,
2542 state_type != GTK_STATE_PRELIGHT,
2543 (gap_side != GTK_POS_LEFT), (gap_side != GTK_POS_RIGHT));
2545 release_window_dc (&dc_info);
2554 draw_extension (GtkStyle *style,
2556 GtkStateType state_type,
2557 GtkShadowType shadow_type,
2559 const gchar *detail,
2561 gint width, gint height, GtkPositionType gap_side)
2563 if (widget && GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "tab"))
2565 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2567 /* Why this differs from gap_side, I have no idea.. */
2568 int real_gap_side = gtk_notebook_get_tab_pos (notebook);
2570 if (!draw_themed_tab_button (style, cr, state_type,
2571 GTK_NOTEBOOK (widget), x, y,
2572 width, height, real_gap_side))
2574 if (!draw_tab_button (style, cr, state_type,
2575 shadow_type, widget,
2576 detail, x, y, width, height, real_gap_side))
2578 parent_class->draw_extension (style, cr, state_type,
2579 shadow_type, widget, detail,
2580 x, y, width, height,
2588 draw_box_gap (GtkStyle *style, cairo_t *cr, GtkStateType state_type,
2589 GtkShadowType shadow_type,
2590 GtkWidget *widget, const gchar *detail, gint x,
2591 gint y, gint width, gint height, GtkPositionType gap_side,
2592 gint gap_x, gint gap_width)
2594 if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
2596 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2597 int side = gtk_notebook_get_tab_pos (notebook);
2598 int x2 = x, y2 = y, w2 = width, h2 = height;
2600 if (side == GTK_POS_TOP)
2603 y2 = y - gtk_notebook_get_tab_vborder (notebook);
2605 h2 = height + gtk_notebook_get_tab_vborder (notebook) * 2;
2607 else if (side == GTK_POS_BOTTOM)
2612 h2 = height + gtk_notebook_get_tab_vborder (notebook) * 2;
2614 else if (side == GTK_POS_LEFT)
2616 x2 = x - gtk_notebook_get_tab_hborder (notebook);
2618 w2 = width + gtk_notebook_get_tab_hborder (notebook);
2621 else if (side == GTK_POS_RIGHT)
2625 w2 = width + gtk_notebook_get_tab_hborder (notebook) * 2;
2629 if (xp_theme_draw (cr, XP_THEME_ELEMENT_TAB_PANE, style,
2630 x2, y2, w2, h2, state_type))
2636 parent_class->draw_box_gap (style, cr, state_type, shadow_type,
2637 widget, detail, x, y, width, height,
2638 gap_side, gap_x, gap_width);
2642 is_popup_window_child (GtkWidget *widget)
2645 GtkWindowType type = -1;
2647 top = gtk_widget_get_toplevel (widget);
2649 if (top && GTK_IS_WINDOW (top))
2651 g_object_get (top, "type", &type, NULL);
2653 if (type == GTK_WINDOW_POPUP)
2654 { /* Hack for combo boxes */
2663 draw_flat_box (GtkStyle *style, cairo_t *cr,
2664 GtkStateType state_type, GtkShadowType shadow_type,
2666 const gchar *detail, gint x, gint y, gint width, gint height)
2670 if (state_type == GTK_STATE_SELECTED &&
2671 (!strncmp ("cell_even", detail, 9) || !strncmp ("cell_odd", detail, 8)))
2673 GdkColor *gc = gtk_widget_has_focus (widget) ? &style->base[state_type] : &style->base[GTK_STATE_ACTIVE];
2675 _cairo_draw_rectangle (cr, gc, TRUE, x, y, width, height);
2679 else if (!strcmp (detail, "checkbutton"))
2681 if (state_type == GTK_STATE_PRELIGHT)
2688 parent_class->draw_flat_box (style, cr, state_type, shadow_type,
2689 widget, detail, x, y, width, height);
2693 draw_menu_border (cairo_t *cr, GtkStyle *style,
2694 gint x, gint y, gint width, gint height)
2700 dc = get_window_dc (style, cr, GTK_STATE_NORMAL, &dc_info, x, y, width, height, &rect);
2705 if (xp_theme_is_active ())
2707 FrameRect (dc, &rect, GetSysColorBrush (COLOR_3DSHADOW));
2711 DrawEdge (dc, &rect, EDGE_RAISED, BF_RECT);
2714 release_window_dc (&dc_info);
2720 draw_shadow (GtkStyle *style,
2722 GtkStateType state_type,
2723 GtkShadowType shadow_type,
2725 const gchar *detail, gint x, gint y, gint width, gint height)
2727 gboolean is_handlebox;
2728 gboolean is_toolbar;
2730 if (detail && !strcmp (detail, "frame"))
2739 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
2740 if (is_combo_box_child (widget))
2742 FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
2744 else if (is_popup_window_child (widget))
2746 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
2750 switch (shadow_type)
2753 draw_3d_border (dc, &rect, TRUE);
2756 case GTK_SHADOW_OUT:
2757 draw_3d_border (dc, &rect, FALSE);
2760 case GTK_SHADOW_ETCHED_IN:
2761 draw_3d_border (dc, &rect, TRUE);
2762 InflateRect (&rect, -1, -1);
2763 draw_3d_border (dc, &rect, FALSE);
2766 case GTK_SHADOW_ETCHED_OUT:
2767 draw_3d_border (dc, &rect, FALSE);
2768 InflateRect (&rect, -1, -1);
2769 draw_3d_border (dc, &rect, TRUE);
2772 case GTK_SHADOW_NONE:
2777 release_window_dc (&dc_info);
2781 if (detail && (!strcmp (detail, "entry") || !strcmp (detail, "combobox")))
2783 if (shadow_type != GTK_SHADOW_IN)
2786 if (!xp_theme_draw (cr, XP_THEME_ELEMENT_EDIT_TEXT, style,
2787 x, y, width, height, state_type))
2793 dc = get_window_dc (style, cr, state_type, &dc_info,
2794 x, y, width, height, &rect);
2796 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
2797 release_window_dc (&dc_info);
2803 if (detail && !strcmp (detail, "scrolled_window") &&
2804 xp_theme_draw (cr, XP_THEME_ELEMENT_EDIT_TEXT, style,
2805 x, y, width, height, state_type))
2810 if (detail && !strcmp (detail, "spinbutton"))
2813 if (detail && !strcmp (detail, "menu"))
2815 if (draw_menu_border (cr, style, x, y, width, height))
2821 if (detail && !strcmp (detail, "handlebox"))
2824 is_handlebox = (detail && !strcmp (detail, "handlebox_bin"));
2825 is_toolbar = (detail
2826 && (!strcmp (detail, "toolbar")
2827 || !strcmp (detail, "menubar")));
2829 if (is_toolbar || is_handlebox)
2831 if (shadow_type == GTK_SHADOW_NONE)
2841 HGDIOBJ old_pen = NULL;
2842 GtkPositionType pos;
2846 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (widget));
2848 If the handle box is at left side,
2849 we shouldn't draw its right border.
2850 The same holds true for top, right, and bottom.
2855 pos = GTK_POS_RIGHT;
2863 pos = GTK_POS_BOTTOM;
2866 case GTK_POS_BOTTOM:
2873 GtkWidget *parent = gtk_widget_get_parent (widget);
2875 /* Dirty hack for toolbars contained in handle boxes */
2876 if (GTK_IS_HANDLE_BOX (parent))
2878 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (parent));
2884 Make pos != all legal enum vaules of GtkPositionType.
2885 So every border will be draw.
2887 pos = (GtkPositionType) - 1;
2891 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
2893 if (pos != GTK_POS_LEFT)
2895 old_pen = SelectObject (dc, get_light_pen ());
2896 MoveToEx (dc, rect.left, rect.top, NULL);
2897 LineTo (dc, rect.left, rect.bottom);
2899 if (pos != GTK_POS_TOP)
2901 old_pen = SelectObject (dc, get_light_pen ());
2902 MoveToEx (dc, rect.left, rect.top, NULL);
2903 LineTo (dc, rect.right, rect.top);
2905 if (pos != GTK_POS_RIGHT)
2907 old_pen = SelectObject (dc, get_dark_pen ());
2908 MoveToEx (dc, rect.right - 1, rect.top, NULL);
2909 LineTo (dc, rect.right - 1, rect.bottom);
2911 if (pos != GTK_POS_BOTTOM)
2913 old_pen = SelectObject (dc, get_dark_pen ());
2914 MoveToEx (dc, rect.left, rect.bottom - 1, NULL);
2915 LineTo (dc, rect.right, rect.bottom - 1);
2918 SelectObject (dc, old_pen);
2919 release_window_dc (&dc_info);
2925 if (detail && !strcmp (detail, "statusbar"))
2930 parent_class->draw_shadow (style, cr, state_type, shadow_type,
2931 widget, detail, x, y, width, height);
2935 draw_hline (GtkStyle *style,
2937 GtkStateType state_type,
2939 const gchar *detail, gint x1, gint x2, gint y)
2941 if (xp_theme_is_active () && detail && !strcmp (detail, "menuitem"))
2944 gint new_y, new_height;
2947 xp_theme_get_element_dimensions (XP_THEME_ELEMENT_MENU_SEPARATOR,
2951 /* Center the separator */
2952 y_offset = (cy / 2) - 1;
2953 new_y = (y - y_offset) >= 0 ? y - y_offset : y;
2957 (cr, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, new_y, x2, new_height,
2964 _cairo_draw_line (cr, &style->dark[state_type], x1, y, x2, y);
2970 if (style->ythickness == 2)
2972 _cairo_draw_line (cr, &style->dark[state_type], x1, y, x2, y);
2974 _cairo_draw_line (cr, &style->light[state_type], x1, y, x2, y);
2979 parent_class->draw_hline (style, cr, state_type, widget,
2986 draw_vline (GtkStyle *style,
2988 GtkStateType state_type,
2990 const gchar *detail, gint y1, gint y2, gint x)
2992 if (style->xthickness == 2)
2994 _cairo_draw_line (cr, &style->dark[state_type], x, y1, x, y2);
2996 _cairo_draw_line (cr, &style->light[state_type], x, y1, x, y2);
3001 parent_class->draw_vline (style, cr, state_type, widget,
3007 draw_slider (GtkStyle *style,
3009 GtkStateType state_type,
3010 GtkShadowType shadow_type,
3012 const gchar *detail,
3014 gint y, gint width, gint height, GtkOrientation orientation)
3016 if (GTK_IS_SCALE (widget) &&
3017 xp_theme_draw (cr, ((orientation == GTK_ORIENTATION_VERTICAL) ?
3018 XP_THEME_ELEMENT_SCALE_SLIDER_V :
3019 XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
3020 height, state_type))
3025 parent_class->draw_slider (style, cr, state_type, shadow_type,
3026 widget, detail, x, y, width, height,
3031 draw_resize_grip (GtkStyle *style,
3033 GtkStateType state_type,
3035 const gchar *detail,
3036 GdkWindowEdge edge, gint x, gint y, gint width, gint height)
3038 if (detail && !strcmp (detail, "statusbar"))
3041 (cr, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
3042 height, state_type))
3050 HDC dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
3053 gdk_cairo_set_source_color (cr, &style->dark[state_type]);
3056 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
3057 release_window_dc (&dc_info);
3063 parent_class->draw_resize_grip (style, cr, state_type,
3064 widget, detail, edge, x, y, width, height);
3068 draw_handle (GtkStyle *style,
3070 GtkStateType state_type,
3071 GtkShadowType shadow_type,
3073 const gchar *detail,
3075 gint y, gint width, gint height, GtkOrientation orientation)
3081 if (is_toolbar_child (widget))
3083 XpThemeElement hndl;
3085 if (GTK_IS_HANDLE_BOX (widget))
3087 GtkPositionType pos;
3088 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (widget));
3090 if (pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM)
3092 orientation = GTK_ORIENTATION_HORIZONTAL;
3096 orientation = GTK_ORIENTATION_VERTICAL;
3100 if (orientation == GTK_ORIENTATION_VERTICAL)
3101 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_V;
3103 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
3105 if (xp_theme_draw (cr, hndl, style, x, y, width, height,
3111 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
3113 if (orientation == GTK_ORIENTATION_VERTICAL)
3116 rect.right = rect.left + 3;
3123 rect.bottom = rect.top + 3;
3128 draw_3d_border (dc, &rect, FALSE);
3129 release_window_dc (&dc_info);
3133 if (!GTK_IS_PANED (widget))
3135 gint xthick, ythick;
3136 GdkColor *light, *dark, *shadow;
3139 gtk_paint_box (style, cr, state_type, shadow_type,
3140 widget, detail, x, y, width, height);
3142 light = &style->light[state_type];
3143 dark = &style->dark[state_type];
3144 shadow = &style->mid[state_type];
3146 xthick = style->xthickness;
3147 ythick = style->ythickness;
3149 dest.x = x + xthick;
3150 dest.y = y + ythick;
3151 dest.width = width - (xthick * 2);
3152 dest.height = height - (ythick * 2);
3154 if (dest.width < dest.height)
3159 if (dest.width < dest.height)
3161 _cairo_draw_line (cr, light, dest.x, dest.y, dest.x,
3163 _cairo_draw_line (cr, dark, dest.x + (dest.width / 2),
3164 dest.y, dest.x + (dest.width / 2), dest.height);
3165 _cairo_draw_line (cr, shadow, dest.x + dest.width,
3166 dest.y, dest.x + dest.width, dest.height);
3170 _cairo_draw_line (cr, light, dest.x, dest.y,
3171 dest.x + dest.width, dest.y);
3172 _cairo_draw_line (cr, dark, dest.x,
3173 dest.y + (dest.height / 2),
3174 dest.x + dest.width, dest.y + (dest.height / 2));
3175 _cairo_draw_line (cr, shadow, dest.x,
3176 dest.y + dest.height, dest.x + dest.width,
3177 dest.y + dest.height);
3183 draw_focus (GtkStyle *style,
3185 GtkStateType state_type,
3187 const gchar *detail, gint x, gint y, gint width, gint height)
3193 if (!gtk_widget_get_can_focus (widget))
3198 if (is_combo_box_child (widget)
3199 && (GTK_IS_ARROW (widget) || GTK_IS_BUTTON (widget)))
3203 if (GTK_IS_TREE_VIEW (gtk_widget_get_parent (widget)) /* list view bheader */)
3208 dc = get_window_dc (style, cr, state_type, &dc_info, x, y, width, height, &rect);
3209 DrawFocusRect (dc, &rect);
3210 release_window_dc (&dc_info);
3212 parent_class->draw_focus (style, cr, state_type,
3213 widget, detail, x, y, width, height);
3218 draw_layout (GtkStyle *style,
3220 GtkStateType state_type,
3223 const gchar *detail,
3224 gint old_x, gint old_y, PangoLayout *layout)
3226 GtkNotebook *notebook = NULL;
3230 /* In the XP theme, labels don't appear correctly centered inside
3231 * notebook tabs, so we give them a gentle nudge two pixels to the
3232 * right. A little hackish, but what are 'ya gonna do? -- Cody
3234 if (xp_theme_is_active () && detail && !strcmp (detail, "label"))
3236 if (gtk_widget_get_parent (widget) != NULL)
3238 if (GTK_IS_NOTEBOOK (gtk_widget_get_parent (widget)))
3241 notebook = GTK_NOTEBOOK (gtk_widget_get_parent (widget));
3242 side = gtk_notebook_get_tab_pos (notebook);
3244 if (side == GTK_POS_TOP || side == GTK_POS_BOTTOM)
3252 parent_class->draw_layout (style, cr, state_type,
3253 use_text, widget, detail, x, y, layout);
3257 msw_style_init_from_rc (GtkStyle *style, GtkRcStyle *rc_style)
3259 setup_system_font (style);
3260 setup_menu_settings (gtk_settings_get_default ());
3261 setup_system_styles (style);
3262 parent_class->init_from_rc (style, rc_style);
3266 msw_style_class_init (MswStyleClass *klass)
3268 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3270 parent_class = g_type_class_peek_parent (klass);
3272 style_class->init_from_rc = msw_style_init_from_rc;
3273 style_class->draw_arrow = draw_arrow;
3274 style_class->draw_box = draw_box;
3275 style_class->draw_check = draw_check;
3276 style_class->draw_option = draw_option;
3277 style_class->draw_tab = draw_tab;
3278 style_class->draw_flat_box = draw_flat_box;
3279 style_class->draw_expander = draw_expander;
3280 style_class->draw_extension = draw_extension;
3281 style_class->draw_box_gap = draw_box_gap;
3282 style_class->draw_shadow = draw_shadow;
3283 style_class->draw_hline = draw_hline;
3284 style_class->draw_vline = draw_vline;
3285 style_class->draw_handle = draw_handle;
3286 style_class->draw_resize_grip = draw_resize_grip;
3287 style_class->draw_slider = draw_slider;
3288 style_class->draw_focus = draw_focus;
3289 style_class->draw_layout = draw_layout;
3292 GType msw_type_style = 0;
3295 msw_style_register_type (GTypeModule *module)
3297 const GTypeInfo object_info = {
3298 sizeof (MswStyleClass),
3299 (GBaseInitFunc) NULL,
3300 (GBaseFinalizeFunc) NULL,
3301 (GClassInitFunc) msw_style_class_init,
3302 NULL, /* class_finalize */
3303 NULL, /* class_data */
3305 0, /* n_preallocs */
3306 (GInstanceInitFunc) NULL,
3309 msw_type_style = g_type_module_register_type (module,
3311 "MswStyle", &object_info, 0);
3315 msw_style_init (void)
3318 msw_style_setup_system_settings ();
3319 setup_msw_rc_style ();
3323 DeleteObject (g_light_pen);
3329 DeleteObject (g_dark_pen);
3335 msw_style_finalize (void)
3339 DeleteObject (g_dither_brush);
3344 DeleteObject (g_light_pen);
3349 DeleteObject (g_dark_pen);