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;
877 sanitize_size (GdkWindow *window, gint *width, gint *height)
879 gboolean set_bg = FALSE;
881 if ((*width == -1) && (*height == -1))
883 set_bg = GDK_IS_WINDOW (window);
884 gdk_drawable_get_size (window, width, height);
886 else if (*width == -1)
888 gdk_drawable_get_size (window, width, NULL);
890 else if (*height == -1)
892 gdk_drawable_get_size (window, NULL, height);
898 static XpThemeElement
899 map_gtk_progress_bar_to_xp (GtkProgressBar *progress_bar, gboolean trough)
903 switch (gtk_progress_bar_get_orientation (progress_bar))
905 case GTK_PROGRESS_LEFT_TO_RIGHT:
906 case GTK_PROGRESS_RIGHT_TO_LEFT:
908 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_H
909 : XP_THEME_ELEMENT_PROGRESS_BAR_H;
914 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_V
915 : XP_THEME_ELEMENT_PROGRESS_BAR_V;
923 is_combo_box_child (GtkWidget *w)
930 for (tmp = w->parent; tmp; tmp = tmp->parent)
932 if (GTK_IS_COMBO_BOX (tmp))
939 /* This function is not needed anymore */
941 combo_box_draw_arrow (GtkStyle *style,
944 GdkRectangle *area, GtkWidget *widget)
946 if (xp_theme_is_active ())
949 if (widget && GTK_IS_TOGGLE_BUTTON (widget->parent))
956 dc = get_window_dc (style, window, state, &dc_info, area->x, area->y, area->width,
957 area->height, &rect);
958 border = (GTK_TOGGLE_BUTTON (widget->parent)->
959 active ? DFCS_PUSHED | DFCS_FLAT : 0);
961 InflateRect (&rect, 1, 1);
962 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
964 release_window_dc (&dc_info);
973 draw_part (GdkDrawable *drawable,
974 GdkColor *gc, GdkRectangle *area, gint x, gint y, Part part)
976 cairo_t *cr = gdk_cairo_create (drawable);
980 gdk_cairo_rectangle (cr, area);
984 if (!parts[part].bmap)
986 parts[part].bmap = cairo_image_surface_create_for_data ((unsigned char *)parts[part].bits,
988 PART_SIZE, PART_SIZE, 4);
991 gdk_cairo_set_source_color (cr, gc);
992 cairo_mask_surface (cr, parts[part].bmap, x, y);
998 draw_check (GtkStyle *style,
1001 GtkShadowType shadow,
1004 const gchar *detail, gint x, gint y, gint width, gint height)
1006 x -= (1 + PART_SIZE - width) / 2;
1007 y -= (1 + PART_SIZE - height) / 2;
1009 if (detail && strcmp (detail, "check") == 0) /* Menu item */
1011 if (shadow == GTK_SHADOW_IN)
1013 draw_part (window, &style->black, area, x, y, CHECK_TEXT);
1014 draw_part (window, &style->dark[state], area, x, y, CHECK_AA);
1019 XpThemeElement theme_elt = XP_THEME_ELEMENT_CHECKBOX;
1022 case GTK_SHADOW_ETCHED_IN:
1023 theme_elt = XP_THEME_ELEMENT_INCONSISTENT_CHECKBOX;
1027 theme_elt = XP_THEME_ELEMENT_PRESSED_CHECKBOX;
1034 if (!xp_theme_draw (window, theme_elt,
1035 style, x, y, width, height, state, area))
1037 if (detail && !strcmp (detail, "cellcheck"))
1038 state = GTK_STATE_NORMAL;
1040 draw_part (window, &style->black, area, x, y, CHECK_BLACK);
1041 draw_part (window, &style->dark[state], area, x, y, CHECK_DARK);
1042 draw_part (window, &style->mid[state], area, x, y, CHECK_MID);
1043 draw_part (window, &style->light[state], area, x, y, CHECK_LIGHT);
1044 draw_part (window, &style->base[state], area, x, y, CHECK_BASE);
1046 if (shadow == GTK_SHADOW_IN)
1048 draw_part (window, &style->text[state], area, x,
1050 draw_part (window, &style->text_aa[state], area,
1053 else if (shadow == GTK_SHADOW_ETCHED_IN)
1055 draw_part (window, &style->text[state], area, x, y,
1056 CHECK_INCONSISTENT);
1057 draw_part (window, &style->text_aa[state], area, x, y,
1065 draw_expander (GtkStyle *style,
1070 const gchar *detail,
1071 gint x, gint y, GtkExpanderStyle expander_style)
1073 cairo_t *cr = gdk_cairo_create (window);
1076 gint expander_semi_size;
1077 XpThemeElement xp_expander;
1079 gtk_widget_style_get (widget, "expander_size", &expander_size, NULL);
1081 switch (expander_style)
1083 case GTK_EXPANDER_COLLAPSED:
1084 case GTK_EXPANDER_SEMI_COLLAPSED:
1085 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED;
1089 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED;
1093 if ((expander_size % 2) == 0)
1096 if (expander_size > 2)
1101 gdk_cairo_rectangle (cr, area);
1103 gdk_cairo_set_source_color (cr, &style->fg[state]);
1106 expander_semi_size = expander_size / 2;
1107 x -= expander_semi_size;
1108 y -= expander_semi_size;
1110 if (!xp_theme_draw (window, xp_expander, style,
1111 x, y, expander_size, expander_size, state, area))
1119 dc = get_window_dc (style, window, state, &dc_info, x, y, expander_size,
1120 expander_size, &rect);
1121 FrameRect (dc, &rect, GetSysColorBrush (COLOR_GRAYTEXT));
1122 InflateRect (&rect, -1, -1);
1123 FillRect (dc, &rect,
1124 GetSysColorBrush (state ==
1125 GTK_STATE_INSENSITIVE ? COLOR_BTNFACE :
1128 InflateRect (&rect, -1, -1);
1130 pen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_WINDOWTEXT));
1131 old_pen = SelectObject (dc, pen);
1133 MoveToEx (dc, rect.left, rect.top - 2 + expander_semi_size, NULL);
1134 LineTo (dc, rect.right, rect.top - 2 + expander_semi_size);
1136 if (expander_style == GTK_EXPANDER_COLLAPSED ||
1137 expander_style == GTK_EXPANDER_SEMI_COLLAPSED)
1139 MoveToEx (dc, rect.left - 2 + expander_semi_size, rect.top, NULL);
1140 LineTo (dc, rect.left - 2 + expander_semi_size, rect.bottom);
1143 SelectObject (dc, old_pen);
1145 release_window_dc (&dc_info);
1152 draw_option (GtkStyle *style,
1155 GtkShadowType shadow,
1158 const gchar *detail, gint x, gint y, gint width, gint height)
1160 x -= (1 + PART_SIZE - width) / 2;
1161 y -= (1 + PART_SIZE - height) / 2;
1163 if (detail && strcmp (detail, "option") == 0) /* Menu item */
1165 if (shadow == GTK_SHADOW_IN)
1167 draw_part (window, &style->fg[state], area, x, y, RADIO_TEXT);
1172 if (xp_theme_draw (window, shadow == GTK_SHADOW_IN
1173 ? XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON
1174 : XP_THEME_ELEMENT_RADIO_BUTTON,
1175 style, x, y, width, height, state, area))
1180 if (detail && !strcmp (detail, "cellradio"))
1181 state = GTK_STATE_NORMAL;
1183 draw_part (window, &style->black, area, x, y, RADIO_BLACK);
1184 draw_part (window, &style->dark[state], area, x, y, RADIO_DARK);
1185 draw_part (window, &style->mid[state], area, x, y, RADIO_MID);
1186 draw_part (window, &style->light[state], area, x, y, RADIO_LIGHT);
1187 draw_part (window, &style->base[state], area, x, y, RADIO_BASE);
1189 if (shadow == GTK_SHADOW_IN)
1190 draw_part (window, &style->text[state], area, x, y, RADIO_TEXT);
1196 draw_varrow (GdkWindow *window,
1198 GtkShadowType shadow_type,
1200 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1203 gint y_start, y_increment;
1207 cr = gdk_cairo_create (window);
1211 gdk_cairo_rectangle (cr, area);
1215 width = width + width % 2 - 1; /* Force odd */
1216 steps = 1 + width / 2;
1217 extra = height - steps;
1219 if (arrow_type == GTK_ARROW_DOWN)
1226 y_start = y + height - 1;
1230 for (i = extra; i < height; i++)
1232 _cairo_draw_line (cr, gc,
1233 x + (i - extra), y_start + i * y_increment,
1234 x + width - (i - extra) - 1, y_start + i * y_increment);
1241 draw_harrow (GdkWindow *window,
1243 GtkShadowType shadow_type,
1245 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1248 gint x_start, x_increment;
1252 cr = gdk_cairo_create (window);
1256 gdk_cairo_rectangle (cr, area);
1260 height = height + height % 2 - 1; /* Force odd */
1261 steps = 1 + height / 2;
1262 extra = width - steps;
1264 if (arrow_type == GTK_ARROW_RIGHT)
1271 x_start = x + width - 1;
1275 for (i = extra; i < width; i++)
1277 _cairo_draw_line (cr, gc,
1278 x_start + i * x_increment, y + (i - extra),
1279 x_start + i * x_increment, y + height - (i - extra) - 1);
1285 /* This function makes up for some brokeness in gtkrange.c
1286 * where we never get the full arrow of the stepper button
1287 * and the type of button in a single drawing function.
1289 * It doesn't work correctly when the scrollbar is squished
1290 * to the point we don't have room for full-sized steppers.
1293 reverse_engineer_stepper_box (GtkWidget *range,
1294 GtkArrowType arrow_type,
1295 gint *x, gint *y, gint *width, gint *height)
1297 gint slider_width = 14, stepper_size = 14;
1303 gtk_widget_style_get (range,
1304 "slider_width", &slider_width,
1305 "stepper_size", &stepper_size, NULL);
1308 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1310 box_width = slider_width;
1311 box_height = stepper_size;
1315 box_width = stepper_size;
1316 box_height = slider_width;
1319 *x = *x - (box_width - *width) / 2;
1320 *y = *y - (box_height - *height) / 2;
1322 *height = box_height;
1325 static XpThemeElement
1326 to_xp_arrow (GtkArrowType arrow_type)
1328 XpThemeElement xp_arrow;
1333 xp_arrow = XP_THEME_ELEMENT_ARROW_UP;
1336 case GTK_ARROW_DOWN:
1337 xp_arrow = XP_THEME_ELEMENT_ARROW_DOWN;
1340 case GTK_ARROW_LEFT:
1341 xp_arrow = XP_THEME_ELEMENT_ARROW_LEFT;
1345 xp_arrow = XP_THEME_ELEMENT_ARROW_RIGHT;
1353 draw_arrow (GtkStyle *style,
1356 GtkShadowType shadow,
1359 const gchar *detail,
1360 GtkArrowType arrow_type,
1361 gboolean fill, gint x, gint y, gint width, gint height)
1368 name = gtk_widget_get_name (widget);
1370 sanitize_size (window, &width, &height);
1372 if (GTK_IS_ARROW (widget) && is_combo_box_child (widget) && xp_theme_is_active ())
1375 if (detail && strcmp (detail, "spinbutton") == 0)
1377 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1384 if (arrow_type == GTK_ARROW_DOWN)
1388 if (state == GTK_STATE_ACTIVE)
1394 draw_varrow (window, &style->fg[state], shadow, area,
1395 arrow_type, x, y, width, height);
1399 else if (detail && (!strcmp (detail, "vscrollbar")
1400 || !strcmp (detail, "hscrollbar")))
1402 gboolean is_disabled = FALSE;
1404 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1408 gint box_width = width;
1409 gint box_height = height;
1411 reverse_engineer_stepper_box (widget, arrow_type,
1412 &box_x, &box_y, &box_width, &box_height);
1414 if (gtk_range_get_adjustment(&scrollbar->range)->page_size >=
1415 (gtk_range_get_adjustment(&scrollbar->range)->upper -
1416 gtk_range_get_adjustment(&scrollbar->range)->lower))
1421 if (xp_theme_draw (window, to_xp_arrow (arrow_type), style, box_x, box_y,
1422 box_width, box_height, state, area))
1430 btn_type = DFCS_SCROLLUP;
1433 case GTK_ARROW_DOWN:
1434 btn_type = DFCS_SCROLLDOWN;
1437 case GTK_ARROW_LEFT:
1438 btn_type = DFCS_SCROLLLEFT;
1441 case GTK_ARROW_RIGHT:
1442 btn_type = DFCS_SCROLLRIGHT;
1445 case GTK_ARROW_NONE:
1449 if (state == GTK_STATE_INSENSITIVE)
1451 btn_type |= DFCS_INACTIVE;
1456 sanitize_size (window, &width, &height);
1458 dc = get_window_dc (style, window, state, &dc_info,
1459 box_x, box_y, box_width, box_height, &rect);
1460 DrawFrameControl (dc, &rect, DFC_SCROLL,
1461 btn_type | (shadow ==
1462 GTK_SHADOW_IN ? (DFCS_PUSHED |
1464 release_window_dc (&dc_info);
1470 /* draw the toolbar chevrons - waiting for GTK 2.4 */
1471 if (name && !strcmp (name, "gtk-toolbar-arrow"))
1474 (window, XP_THEME_ELEMENT_REBAR_CHEVRON, style, x, y,
1475 width, height, state, area))
1480 /* probably a gtk combo box on a toolbar */
1481 else if (0 /* widget->parent && GTK_IS_BUTTON
1482 (widget->parent) */ )
1485 (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x - 3,
1486 widget->allocation.y + 1, width + 5,
1487 widget->allocation.height - 4, state, area))
1493 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1495 x += (width - 7) / 2;
1496 y += (height - 5) / 2;
1498 draw_varrow (window, &style->fg[state], shadow, area,
1499 arrow_type, x, y, 7, 5);
1503 x += (width - 5) / 2;
1504 y += (height - 7) / 2;
1506 draw_harrow (window, &style->fg[state], shadow, area,
1507 arrow_type, x, y, 5, 7);
1513 option_menu_get_props (GtkWidget *widget,
1514 GtkRequisition *indicator_size,
1515 GtkBorder *indicator_spacing)
1517 GtkRequisition *tmp_size = NULL;
1518 GtkBorder *tmp_spacing = NULL;
1521 gtk_widget_style_get (widget,
1522 "indicator_size", &tmp_size,
1523 "indicator_spacing", &tmp_spacing, NULL);
1527 *indicator_size = *tmp_size;
1528 gtk_requisition_free (tmp_size);
1532 *indicator_size = default_option_indicator_size;
1537 *indicator_spacing = *tmp_spacing;
1538 gtk_border_free (tmp_spacing);
1542 *indicator_spacing = default_option_indicator_spacing;
1547 is_toolbar_child (GtkWidget *wid)
1551 if (GTK_IS_TOOLBAR (wid) || GTK_IS_HANDLE_BOX (wid))
1561 is_menu_tool_button_child (GtkWidget *wid)
1565 if (GTK_IS_MENU_TOOL_BUTTON (wid))
1578 g_light_pen = CreatePen (PS_SOLID | PS_INSIDEFRAME, 1,
1579 GetSysColor (COLOR_BTNHIGHLIGHT));
1590 g_dark_pen = CreatePen (PS_SOLID | PS_INSIDEFRAME, 1,
1591 GetSysColor (COLOR_BTNSHADOW));
1598 draw_3d_border (HDC hdc, RECT *rc, gboolean sunken)
1605 pen1 = get_dark_pen ();
1606 pen2 = get_light_pen ();
1610 pen1 = get_light_pen ();
1611 pen2 = get_dark_pen ();
1614 MoveToEx (hdc, rc->left, rc->bottom - 1, NULL);
1616 old_pen = SelectObject (hdc, pen1);
1617 LineTo (hdc, rc->left, rc->top);
1618 LineTo (hdc, rc->right - 1, rc->top);
1619 SelectObject (hdc, old_pen);
1621 old_pen = SelectObject (hdc, pen2);
1622 LineTo (hdc, rc->right - 1, rc->bottom - 1);
1623 LineTo (hdc, rc->left, rc->bottom - 1);
1624 SelectObject (hdc, old_pen);
1628 draw_menu_item (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
1629 gint x, gint y, gint width, gint height,
1630 GtkStateType state_type, GdkRectangle *area)
1638 if (xp_theme_is_active ())
1640 return (xp_theme_draw (window, XP_THEME_ELEMENT_MENU_ITEM, style,
1641 x, y, width, height, state_type, area));
1644 if ((parent = gtk_widget_get_parent (widget))
1645 && GTK_IS_MENU_BAR (parent) && !xp_theme_is_active ())
1647 bar = GTK_MENU_SHELL (parent);
1649 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
1651 if (state_type == GTK_STATE_PRELIGHT)
1653 draw_3d_border (dc, &rect, bar->active);
1656 release_window_dc (&dc_info);
1665 get_dither_brush (void)
1668 HBITMAP pattern_bmp;
1672 return g_dither_brush;
1674 for (i = 0; i < 8; i++)
1676 pattern[i] = (WORD) (0x5555 << (i & 1));
1679 pattern_bmp = CreateBitmap (8, 8, 1, 1, &pattern);
1683 g_dither_brush = CreatePatternBrush (pattern_bmp);
1684 DeleteObject (pattern_bmp);
1687 return g_dither_brush;
1691 draw_tool_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
1692 gint x, gint y, gint width, gint height,
1693 GtkStateType state_type, GdkRectangle *area)
1698 gboolean is_toggled = FALSE;
1700 if (xp_theme_is_active ())
1702 return (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
1703 x, y, width, height, state_type, area));
1706 if (GTK_IS_TOGGLE_BUTTON (widget))
1708 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1714 if (state_type != GTK_STATE_PRELIGHT
1715 && state_type != GTK_STATE_ACTIVE && !is_toggled)
1720 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
1721 if (state_type == GTK_STATE_PRELIGHT)
1725 FillRect (dc, &rect, GetSysColorBrush (COLOR_BTNFACE));
1728 draw_3d_border (dc, &rect, is_toggled);
1730 else if (state_type == GTK_STATE_ACTIVE)
1732 if (is_toggled && !is_menu_tool_button_child (widget->parent))
1734 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
1735 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
1736 FillRect (dc, &rect, get_dither_brush ());
1739 draw_3d_border (dc, &rect, TRUE);
1742 release_window_dc (&dc_info);
1748 draw_push_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
1749 gint x, gint y, gint width, gint height,
1750 GtkStateType state_type, gboolean is_default)
1756 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
1758 if (GTK_IS_TOGGLE_BUTTON (widget))
1760 if (state_type == GTK_STATE_PRELIGHT &&
1761 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1763 state_type = GTK_STATE_ACTIVE;
1767 if (state_type == GTK_STATE_ACTIVE)
1769 if (GTK_IS_TOGGLE_BUTTON (widget))
1771 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1772 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
1773 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
1774 FillRect (dc, &rect, get_dither_brush ());
1778 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
1779 InflateRect (&rect, -1, -1);
1780 FrameRect (dc, &rect, GetSysColorBrush (COLOR_BTNSHADOW));
1781 InflateRect (&rect, -1, -1);
1782 FillRect (dc, &rect, GetSysColorBrush (COLOR_BTNFACE));
1787 if (is_default || gtk_widget_has_focus (widget))
1789 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
1790 InflateRect (&rect, -1, -1);
1793 DrawFrameControl (dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH);
1796 release_window_dc (&dc_info);
1800 draw_box (GtkStyle *style,
1802 GtkStateType state_type,
1803 GtkShadowType shadow_type,
1806 const gchar *detail, gint x, gint y, gint width, gint height)
1808 if (is_combo_box_child (widget) && detail && !strcmp (detail, "button"))
1816 border = (GTK_TOGGLE_BUTTON (widget)->active ? DFCS_PUSHED | DFCS_FLAT : 0);
1818 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
1819 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
1820 release_window_dc (&dc_info);
1822 if (xp_theme_is_active ()
1823 && xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x, y,
1824 width, height, state_type, area))
1826 cx = GetSystemMetrics(SM_CXVSCROLL);
1831 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width - cx, height, &rect);
1832 FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
1833 release_window_dc (&dc_info);
1839 (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
1841 if (GTK_IS_TREE_VIEW (widget->parent))
1844 (window, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
1845 width, height, state_type, area))
1854 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
1856 DrawFrameControl (dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH |
1858 GTK_STATE_ACTIVE ? (DFCS_PUSHED | DFCS_FLAT)
1860 release_window_dc (&dc_info);
1863 else if (is_toolbar_child (widget->parent)
1864 || (!GTK_IS_BUTTON (widget) ||
1865 (GTK_RELIEF_NONE == gtk_button_get_relief (GTK_BUTTON (widget)))))
1867 if (draw_tool_button (window, widget, style, x, y,
1868 width, height, state_type, area))
1875 gboolean is_default = gtk_widget_has_default (widget);
1878 is_default ? XP_THEME_ELEMENT_DEFAULT_BUTTON :
1879 XP_THEME_ELEMENT_BUTTON, style, x, y, width, height,
1885 draw_push_button (window, widget, style,
1886 x, y, width, height, state_type, is_default);
1893 else if (detail && !strcmp (detail, "spinbutton"))
1895 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1900 else if (detail && (!strcmp (detail, "spinbutton_up")
1901 || !strcmp (detail, "spinbutton_down")))
1903 if (!xp_theme_draw (window,
1904 (!strcmp (detail, "spinbutton_up"))
1905 ? XP_THEME_ELEMENT_SPIN_BUTTON_UP
1906 : XP_THEME_ELEMENT_SPIN_BUTTON_DOWN,
1907 style, x, y, width, height, state_type, area))
1913 dc = get_window_dc (style, window, state_type, &dc_info,
1914 x, y, width, height, &rect);
1915 DrawEdge (dc, &rect,
1917 GTK_STATE_ACTIVE ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT);
1918 release_window_dc (&dc_info);
1922 else if (detail && !strcmp (detail, "slider"))
1924 if (GTK_IS_SCROLLBAR (widget))
1926 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1927 gboolean is_v = GTK_IS_VSCROLLBAR (widget);
1929 if (xp_theme_draw (window,
1931 ? XP_THEME_ELEMENT_SCROLLBAR_V
1932 : XP_THEME_ELEMENT_SCROLLBAR_H,
1933 style, x, y, width, height, state_type, area))
1935 XpThemeElement gripper =
1936 (is_v ? XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V :
1937 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H);
1939 /* Do not display grippers on tiny scroll bars,
1940 the limit imposed is rather arbitrary, perhaps
1941 we can fetch the gripper geometry from
1942 somewhere and use that... */
1944 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H
1947 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V && height < 16))
1952 xp_theme_draw (window, gripper, style, x, y,
1953 width, height, state_type, area);
1958 if (gtk_range_get_adjustment(&scrollbar->range)->page_size >=
1959 (gtk_range_get_adjustment(&scrollbar->range)->upper -
1960 gtk_range_get_adjustment(&scrollbar->range)->lower))
1967 else if (detail && !strcmp (detail, "bar"))
1969 if (widget && GTK_IS_PROGRESS_BAR (widget))
1971 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
1972 XpThemeElement xp_progress_bar =
1973 map_gtk_progress_bar_to_xp (progress_bar, FALSE);
1975 if (xp_theme_draw (window, xp_progress_bar, style, x, y,
1976 width, height, state_type, area))
1981 shadow_type = GTK_SHADOW_NONE;
1984 else if (detail && strcmp (detail, "menuitem") == 0)
1986 shadow_type = GTK_SHADOW_NONE;
1987 if (draw_menu_item (window, widget, style,
1988 x, y, width, height, state_type, area))
1993 else if (detail && !strcmp (detail, "trough"))
1995 if (widget && GTK_IS_PROGRESS_BAR (widget))
1997 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
1998 XpThemeElement xp_progress_bar =
1999 map_gtk_progress_bar_to_xp (progress_bar, TRUE);
2001 (window, xp_progress_bar, style, x, y, width, height,
2008 /* Blank in classic Windows */
2011 else if (widget && GTK_IS_SCROLLBAR (widget))
2013 gboolean is_vertical = GTK_IS_VSCROLLBAR (widget);
2015 if (xp_theme_draw (window,
2017 ? XP_THEME_ELEMENT_TROUGH_V
2018 : XP_THEME_ELEMENT_TROUGH_H,
2019 style, x, y, width, height, state_type, area))
2029 sanitize_size (window, &width, &height);
2030 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
2032 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
2033 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
2034 FillRect (dc, &rect, get_dither_brush ());
2036 release_window_dc (&dc_info);
2041 else if (widget && GTK_IS_SCALE (widget))
2043 gboolean is_vertical = GTK_IS_VSCALE (widget);
2045 if (!xp_theme_is_active ())
2047 parent_class->draw_box (style, window, state_type,
2048 GTK_SHADOW_NONE, area,
2049 widget, detail, x, y, width, height);
2055 (window, XP_THEME_ELEMENT_SCALE_TROUGH_V,
2056 style, (2 * x + width) / 2, y, 2, height,
2062 parent_class->draw_box (style, window, state_type,
2063 GTK_SHADOW_ETCHED_IN,
2065 (2 * x + width) / 2, y, 1, height);
2070 (window, XP_THEME_ELEMENT_SCALE_TROUGH_H,
2071 style, x, (2 * y + height) / 2, width, 2,
2077 parent_class->draw_box (style, window, state_type,
2078 GTK_SHADOW_ETCHED_IN,
2079 area, NULL, NULL, x,
2080 (2 * y + height) / 2, width, 1);
2086 else if (detail && strcmp (detail, "optionmenu") == 0)
2088 if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
2089 style, x, y, width, height, state_type, area))
2095 && (strcmp (detail, "vscrollbar") == 0
2096 || strcmp (detail, "hscrollbar") == 0))
2101 && (strcmp (detail, "handlebox_bin") == 0
2102 || strcmp (detail, "toolbar") == 0
2103 || strcmp (detail, "menubar") == 0))
2105 sanitize_size (window, &width, &height);
2106 if (xp_theme_draw (window, XP_THEME_ELEMENT_REBAR,
2107 style, x, y, width, height, state_type, area))
2112 else if (detail && (!strcmp (detail, "handlebox"))) /* grip */
2114 if (!xp_theme_is_active ())
2119 else if (detail && !strcmp (detail, "notebook") && GTK_IS_NOTEBOOK (widget))
2121 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2122 x, y, width, height, state_type, area))
2130 const gchar *name = gtk_widget_get_name (widget);
2132 if (name && !strcmp (name, "gtk-tooltips"))
2135 (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
2136 height, state_type, area))
2147 hdc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
2149 brush = GetSysColorBrush (COLOR_3DDKSHADOW);
2153 FrameRect (hdc, &rect, brush);
2156 InflateRect (&rect, -1, -1);
2157 FillRect (hdc, &rect, (HBRUSH) (COLOR_INFOBK + 1));
2159 release_window_dc (&dc_info);
2166 parent_class->draw_box (style, window, state_type, shadow_type, area,
2167 widget, detail, x, y, width, height);
2169 if (detail && strcmp (detail, "optionmenu") == 0)
2171 GtkRequisition indicator_size;
2172 GtkBorder indicator_spacing;
2175 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2177 sanitize_size (window, &width, &height);
2179 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
2182 x + indicator_size.width + indicator_spacing.left +
2183 indicator_spacing.right;
2187 vline_x = x + width - (indicator_size.width +
2188 indicator_spacing.left +
2189 indicator_spacing.right) - style->xthickness;
2191 parent_class->draw_vline (style, window, state_type, area, widget,
2193 y + style->ythickness + 1,
2194 y + height - style->ythickness - 3, vline_x);
2200 draw_tab (GtkStyle *style,
2203 GtkShadowType shadow,
2206 const gchar *detail, gint x, gint y, gint width, gint height)
2208 GtkRequisition indicator_size;
2209 GtkBorder indicator_spacing;
2213 g_return_if_fail (style != NULL);
2214 g_return_if_fail (window != NULL);
2216 if (detail && !strcmp (detail, "optionmenutab"))
2218 if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
2219 style, x - 5, widget->allocation.y + 1,
2220 width + 10, widget->allocation.height - 2,
2227 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2229 x += (width - indicator_size.width) / 2;
2230 arrow_height = (indicator_size.width + 1) / 2;
2232 y += (height - arrow_height) / 2;
2234 draw_varrow (window, &style->black, shadow, area, GTK_ARROW_DOWN,
2235 x, y, indicator_size.width, arrow_height);
2238 /* Draw classic Windows tab - thanks Mozilla!
2239 (no system API for this, but DrawEdge can draw all the parts of a tab) */
2241 DrawTab (HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
2242 gboolean aDrawLeft, gboolean aDrawRight)
2244 gint32 leftFlag, topFlag, rightFlag, lightFlag, shadeFlag;
2245 RECT topRect, sideRect, bottomRect, lightRect, shadeRect;
2246 gint32 selectedOffset, lOffset, rOffset;
2248 selectedOffset = aSelected ? 1 : 0;
2249 lOffset = aDrawLeft ? 2 : 0;
2250 rOffset = aDrawRight ? 2 : 0;
2252 /* Get info for tab orientation/position (Left, Top, Right, Bottom) */
2258 rightFlag = BF_BOTTOM;
2259 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2260 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2262 SetRect (&topRect, R.left, R.top + lOffset, R.right,
2263 R.bottom - rOffset);
2264 SetRect (&sideRect, R.left + 2, R.top, R.right - 2 + selectedOffset,
2266 SetRect (&bottomRect, R.right - 2, R.top, R.right, R.bottom);
2267 SetRect (&lightRect, R.left, R.top, R.left + 3, R.top + 3);
2268 SetRect (&shadeRect, R.left + 1, R.bottom - 2, R.left + 2,
2275 rightFlag = BF_RIGHT;
2276 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2277 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2279 SetRect (&topRect, R.left + lOffset, R.top, R.right - rOffset,
2281 SetRect (&sideRect, R.left, R.top + 2, R.right,
2282 R.bottom - 1 + selectedOffset);
2283 SetRect (&bottomRect, R.left, R.bottom - 1, R.right, R.bottom);
2284 SetRect (&lightRect, R.left, R.top, R.left + 3, R.top + 3);
2285 SetRect (&shadeRect, R.right - 2, R.top + 1, R.right - 1, R.top + 2);
2291 rightFlag = BF_BOTTOM;
2292 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2293 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2295 SetRect (&topRect, R.left, R.top + lOffset, R.right,
2296 R.bottom - rOffset);
2297 SetRect (&sideRect, R.left + 2 - selectedOffset, R.top, R.right - 2,
2299 SetRect (&bottomRect, R.left, R.top, R.left + 2, R.bottom);
2300 SetRect (&lightRect, R.right - 3, R.top, R.right - 1, R.top + 2);
2301 SetRect (&shadeRect, R.right - 2, R.bottom - 3, R.right, R.bottom - 1);
2306 topFlag = BF_BOTTOM;
2307 rightFlag = BF_RIGHT;
2308 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2309 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2311 SetRect (&topRect, R.left + lOffset, R.top, R.right - rOffset,
2313 SetRect (&sideRect, R.left, R.top + 2 - selectedOffset, R.right,
2315 SetRect (&bottomRect, R.left, R.top, R.right, R.top + 2);
2316 SetRect (&lightRect, R.left, R.bottom - 3, R.left + 2, R.bottom - 1);
2317 SetRect (&shadeRect, R.right - 2, R.bottom - 3, R.right, R.bottom - 1);
2321 g_return_if_reached ();
2325 FillRect (hdc, &R, (HBRUSH) (COLOR_3DFACE + 1));
2328 DrawEdge (hdc, &topRect, EDGE_RAISED, BF_SOFT | topFlag);
2332 DrawEdge (hdc, &bottomRect, EDGE_RAISED, BF_SOFT | topFlag);
2340 DrawEdge (hdc, &sideRect, EDGE_RAISED, BF_SOFT | leftFlag | rightFlag);
2342 /* Tab Diagonal Corners */
2344 DrawEdge (hdc, &lightRect, EDGE_RAISED, BF_SOFT | lightFlag);
2347 DrawEdge (hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
2351 draw_themed_tab_button (GtkStyle *style,
2353 GtkStateType state_type,
2354 GtkNotebook *notebook,
2356 gint width, gint height, gint gap_side)
2358 GdkPixmap *pixmap = NULL;
2360 gtk_container_get_border_width (GTK_CONTAINER (notebook));
2361 GtkWidget *widget = GTK_WIDGET (notebook);
2362 GdkRectangle draw_rect, clip_rect;
2363 GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
2366 if (gap_side == GTK_POS_TOP)
2370 if (state_type == GTK_STATE_NORMAL)
2374 draw_rect.width = width + 2;
2375 draw_rect.height = height;
2377 clip_rect = draw_rect;
2382 draw_rect.x = x + 2;
2384 draw_rect.width = width - 2;
2385 draw_rect.height = height - 2;
2386 clip_rect = draw_rect;
2389 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2390 widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
2392 if (draw_rect.x + draw_rect.width >= widget_right)
2394 draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
2397 if (gap_side == GTK_POS_BOTTOM)
2401 if (state_type == GTK_STATE_NORMAL)
2405 draw_rect.width = width + 2;
2406 draw_rect.height = height;
2408 clip_rect = draw_rect;
2412 draw_rect.x = x + 2;
2413 draw_rect.y = y + 2;
2414 draw_rect.width = width - 2;
2415 draw_rect.height = height - 2;
2416 clip_rect = draw_rect;
2419 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2420 widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
2422 if (draw_rect.x + draw_rect.width >= widget_right)
2424 draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
2427 rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
2429 else if (gap_side == GTK_POS_LEFT)
2433 if (state_type == GTK_STATE_NORMAL)
2437 draw_rect.width = width;
2438 draw_rect.height = height + 2;
2440 clip_rect = draw_rect;
2446 draw_rect.y = y + 2;
2447 draw_rect.width = width - 2;
2448 draw_rect.height = height - 2;
2449 clip_rect = draw_rect;
2452 /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
2453 widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
2455 if (draw_rect.y + draw_rect.height >= widget_bottom)
2457 draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
2460 rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
2462 else if (gap_side == GTK_POS_RIGHT)
2466 if (state_type == GTK_STATE_NORMAL)
2468 draw_rect.x = x + 1;
2470 draw_rect.width = width;
2471 draw_rect.height = height + 2;
2473 clip_rect = draw_rect;
2478 draw_rect.x = x + 2;
2479 draw_rect.y = y + 2;
2480 draw_rect.width = width - 2;
2481 draw_rect.height = height - 2;
2482 clip_rect = draw_rect;
2485 /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
2486 widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
2488 if (draw_rect.y + draw_rect.height >= widget_bottom)
2490 draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
2493 rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
2496 if (gap_side == GTK_POS_TOP)
2498 if (!xp_theme_draw (window, XP_THEME_ELEMENT_TAB_ITEM, style,
2499 draw_rect.x, draw_rect.y,
2500 draw_rect.width, draw_rect.height,
2501 state_type, &clip_rect))
2511 if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_RIGHT)
2513 pixmap = gdk_pixmap_new (window, clip_rect.height, clip_rect.width, -1);
2515 if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
2516 draw_rect.y - clip_rect.y, draw_rect.x - clip_rect.x,
2517 draw_rect.height, draw_rect.width, state_type, 0))
2519 g_object_unref (pixmap);
2523 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
2524 clip_rect.height, clip_rect.width);
2525 g_object_unref (pixmap);
2529 pixmap = gdk_pixmap_new (window, clip_rect.width, clip_rect.height, -1);
2531 if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
2532 draw_rect.x - clip_rect.x, draw_rect.y - clip_rect.y,
2533 draw_rect.width, draw_rect.height, state_type, 0))
2535 g_object_unref (pixmap);
2539 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
2540 clip_rect.width, clip_rect.height);
2541 g_object_unref (pixmap);
2544 rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
2545 g_object_unref (pixbuf);
2548 // XXX - This is really hacky and evil. When we're drawing the left-most tab
2549 // while it is active on a bottom-oriented notebook, there is one white
2550 // pixel at the top. There may be a better solution than this if someone
2551 // has time to discover it.
2552 if (gap_side == GTK_POS_BOTTOM && state_type == GTK_STATE_NORMAL
2553 && x == widget->allocation.x)
2555 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
2556 int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
2559 guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
2560 guchar *p = pixels + rowstride;
2562 for (psub = 0; psub < n_channels; psub++)
2564 pixels[psub] = p[psub];
2568 cr = gdk_cairo_create (window);
2569 gdk_cairo_set_source_pixbuf (cr, pixbuf, clip_rect.x, clip_rect.y);
2572 g_object_unref (pixbuf);
2579 draw_tab_button (GtkStyle *style,
2581 GtkStateType state_type,
2582 GtkShadowType shadow_type,
2585 const gchar *detail,
2586 gint x, gint y, gint width, gint height, gint gap_side)
2588 if (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM)
2590 /* experimental tab-drawing code from mozilla */
2597 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
2598 cr = gdk_cairo_create (window);
2600 if (gap_side == GTK_POS_TOP)
2602 else if (gap_side == GTK_POS_BOTTOM)
2603 aPosition = BF_BOTTOM;
2604 else if (gap_side == GTK_POS_LEFT)
2605 aPosition = BF_LEFT;
2607 aPosition = BF_RIGHT;
2609 if (state_type == GTK_STATE_PRELIGHT)
2610 state_type = GTK_STATE_NORMAL;
2613 gdk_cairo_rectangle (cr, area);
2615 gdk_cairo_set_source_color (cr, &style->dark[state_type]);
2618 DrawTab (dc, rect, aPosition,
2619 state_type != GTK_STATE_PRELIGHT,
2620 (gap_side != GTK_POS_LEFT), (gap_side != GTK_POS_RIGHT));
2624 release_window_dc (&dc_info);
2632 draw_extension (GtkStyle *style,
2634 GtkStateType state_type,
2635 GtkShadowType shadow_type,
2638 const gchar *detail,
2640 gint width, gint height, GtkPositionType gap_side)
2642 if (widget && GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "tab"))
2644 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2646 /* Why this differs from gap_side, I have no idea.. */
2647 int real_gap_side = gtk_notebook_get_tab_pos (notebook);
2649 if (!draw_themed_tab_button (style, window, state_type,
2650 GTK_NOTEBOOK (widget), x, y,
2651 width, height, real_gap_side))
2653 if (!draw_tab_button (style, window, state_type,
2654 shadow_type, area, widget,
2655 detail, x, y, width, height, real_gap_side))
2657 parent_class->draw_extension (style, window, state_type,
2658 shadow_type, area, widget, detail,
2659 x, y, width, height,
2667 draw_box_gap (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
2668 GtkShadowType shadow_type, GdkRectangle *area,
2669 GtkWidget *widget, const gchar *detail, gint x,
2670 gint y, gint width, gint height, GtkPositionType gap_side,
2671 gint gap_x, gint gap_width)
2673 if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
2675 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2676 int side = gtk_notebook_get_tab_pos (notebook);
2677 int x2 = x, y2 = y, w2 = width, h2 = height;
2679 if (side == GTK_POS_TOP)
2682 y2 = y - gtk_notebook_get_tab_vborder (notebook);
2684 h2 = height + gtk_notebook_get_tab_vborder (notebook) * 2;
2686 else if (side == GTK_POS_BOTTOM)
2691 h2 = height + gtk_notebook_get_tab_vborder (notebook) * 2;
2693 else if (side == GTK_POS_LEFT)
2695 x2 = x - gtk_notebook_get_tab_hborder (notebook);
2697 w2 = width + gtk_notebook_get_tab_hborder (notebook);
2700 else if (side == GTK_POS_RIGHT)
2704 w2 = width + gtk_notebook_get_tab_hborder (notebook) * 2;
2708 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2709 x2, y2, w2, h2, state_type, area))
2715 parent_class->draw_box_gap (style, window, state_type, shadow_type,
2716 area, widget, detail, x, y, width, height,
2717 gap_side, gap_x, gap_width);
2721 is_popup_window_child (GtkWidget *widget)
2724 GtkWindowType type = -1;
2726 top = gtk_widget_get_toplevel (widget);
2728 if (top && GTK_IS_WINDOW (top))
2730 g_object_get (top, "type", &type, NULL);
2732 if (type == GTK_WINDOW_POPUP)
2733 { /* Hack for combo boxes */
2742 draw_flat_box (GtkStyle *style, GdkWindow *window,
2743 GtkStateType state_type, GtkShadowType shadow_type,
2744 GdkRectangle *area, GtkWidget *widget,
2745 const gchar *detail, gint x, gint y, gint width, gint height)
2749 if (state_type == GTK_STATE_SELECTED &&
2750 (!strncmp ("cell_even", detail, 9) || !strncmp ("cell_odd", detail, 8)))
2752 GdkColor *gc = gtk_widget_has_focus (widget) ? &style->base[state_type] : &style->base[GTK_STATE_ACTIVE];
2753 cairo_t *cr = gdk_cairo_create (window);
2755 _cairo_draw_rectangle (cr, gc, TRUE, x, y, width, height);
2761 else if (!strcmp (detail, "checkbutton"))
2763 if (state_type == GTK_STATE_PRELIGHT)
2770 parent_class->draw_flat_box (style, window, state_type, shadow_type,
2771 area, widget, detail, x, y, width, height);
2775 draw_menu_border (GdkWindow *win, GtkStyle *style,
2776 gint x, gint y, gint width, gint height)
2782 dc = get_window_dc (style, win, GTK_STATE_NORMAL, &dc_info, x, y, width, height, &rect);
2787 if (xp_theme_is_active ())
2789 FrameRect (dc, &rect, GetSysColorBrush (COLOR_3DSHADOW));
2793 DrawEdge (dc, &rect, EDGE_RAISED, BF_RECT);
2796 release_window_dc (&dc_info);
2802 draw_shadow (GtkStyle *style,
2804 GtkStateType state_type,
2805 GtkShadowType shadow_type,
2808 const gchar *detail, gint x, gint y, gint width, gint height)
2810 gboolean is_handlebox;
2811 gboolean is_toolbar;
2813 if (detail && !strcmp (detail, "frame"))
2822 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
2823 if (is_combo_box_child (widget))
2825 FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
2827 else if (is_popup_window_child (widget))
2829 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
2833 switch (shadow_type)
2836 draw_3d_border (dc, &rect, TRUE);
2839 case GTK_SHADOW_OUT:
2840 draw_3d_border (dc, &rect, FALSE);
2843 case GTK_SHADOW_ETCHED_IN:
2844 draw_3d_border (dc, &rect, TRUE);
2845 InflateRect (&rect, -1, -1);
2846 draw_3d_border (dc, &rect, FALSE);
2849 case GTK_SHADOW_ETCHED_OUT:
2850 draw_3d_border (dc, &rect, FALSE);
2851 InflateRect (&rect, -1, -1);
2852 draw_3d_border (dc, &rect, TRUE);
2855 case GTK_SHADOW_NONE:
2860 release_window_dc (&dc_info);
2864 if (detail && (!strcmp (detail, "entry") || !strcmp (detail, "combobox")))
2866 if (shadow_type != GTK_SHADOW_IN)
2869 if (!xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2870 x, y, width, height, state_type, area))
2876 dc = get_window_dc (style, window, state_type, &dc_info,
2877 x, y, width, height, &rect);
2879 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
2880 release_window_dc (&dc_info);
2886 if (detail && !strcmp (detail, "scrolled_window") &&
2887 xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2888 x, y, width, height, state_type, area))
2893 if (detail && !strcmp (detail, "spinbutton"))
2896 if (detail && !strcmp (detail, "menu"))
2898 if (draw_menu_border (window, style, x, y, width, height))
2904 if (detail && !strcmp (detail, "handlebox"))
2907 is_handlebox = (detail && !strcmp (detail, "handlebox_bin"));
2908 is_toolbar = (detail
2909 && (!strcmp (detail, "toolbar")
2910 || !strcmp (detail, "menubar")));
2912 if (is_toolbar || is_handlebox)
2914 if (shadow_type == GTK_SHADOW_NONE)
2924 HGDIOBJ old_pen = NULL;
2925 GtkPositionType pos;
2927 sanitize_size (window, &width, &height);
2931 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (widget));
2933 If the handle box is at left side,
2934 we shouldn't draw its right border.
2935 The same holds true for top, right, and bottom.
2940 pos = GTK_POS_RIGHT;
2948 pos = GTK_POS_BOTTOM;
2951 case GTK_POS_BOTTOM:
2958 GtkWidget *parent = gtk_widget_get_parent (widget);
2960 /* Dirty hack for toolbars contained in handle boxes */
2961 if (GTK_IS_HANDLE_BOX (parent))
2963 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (parent));
2969 Make pos != all legal enum vaules of GtkPositionType.
2970 So every border will be draw.
2972 pos = (GtkPositionType) - 1;
2976 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
2978 if (pos != GTK_POS_LEFT)
2980 old_pen = SelectObject (dc, get_light_pen ());
2981 MoveToEx (dc, rect.left, rect.top, NULL);
2982 LineTo (dc, rect.left, rect.bottom);
2984 if (pos != GTK_POS_TOP)
2986 old_pen = SelectObject (dc, get_light_pen ());
2987 MoveToEx (dc, rect.left, rect.top, NULL);
2988 LineTo (dc, rect.right, rect.top);
2990 if (pos != GTK_POS_RIGHT)
2992 old_pen = SelectObject (dc, get_dark_pen ());
2993 MoveToEx (dc, rect.right - 1, rect.top, NULL);
2994 LineTo (dc, rect.right - 1, rect.bottom);
2996 if (pos != GTK_POS_BOTTOM)
2998 old_pen = SelectObject (dc, get_dark_pen ());
2999 MoveToEx (dc, rect.left, rect.bottom - 1, NULL);
3000 LineTo (dc, rect.right, rect.bottom - 1);
3003 SelectObject (dc, old_pen);
3004 release_window_dc (&dc_info);
3010 if (detail && !strcmp (detail, "statusbar"))
3015 parent_class->draw_shadow (style, window, state_type, shadow_type, area,
3016 widget, detail, x, y, width, height);
3020 draw_hline (GtkStyle *style,
3022 GtkStateType state_type,
3025 const gchar *detail, gint x1, gint x2, gint y)
3029 cr = gdk_cairo_create (window);
3031 if (xp_theme_is_active () && detail && !strcmp (detail, "menuitem"))
3034 gint new_y, new_height;
3037 xp_theme_get_element_dimensions (XP_THEME_ELEMENT_MENU_SEPARATOR,
3041 /* Center the separator */
3042 y_offset = (area->height / 2) - (cy / 2);
3043 new_y = y_offset >= 0 ? area->y + y_offset : area->y;
3047 (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, new_y, x2, new_height,
3056 gdk_cairo_rectangle (cr, area);
3060 _cairo_draw_line (cr, &style->dark[state_type], x1, y, x2, y);
3066 if (style->ythickness == 2)
3070 gdk_cairo_rectangle (cr, area);
3074 _cairo_draw_line (cr, &style->dark[state_type], x1, y, x2, y);
3076 _cairo_draw_line (cr, &style->light[state_type], x1, y, x2, y);
3081 parent_class->draw_hline (style, window, state_type, area, widget,
3089 draw_vline (GtkStyle *style,
3091 GtkStateType state_type,
3094 const gchar *detail, gint y1, gint y2, gint x)
3098 cr = gdk_cairo_create (window);
3100 if (style->xthickness == 2)
3104 gdk_cairo_rectangle (cr, area);
3108 _cairo_draw_line (cr, &style->dark[state_type], x, y1, x, y2);
3110 _cairo_draw_line (cr, &style->light[state_type], x, y1, x, y2);
3115 parent_class->draw_vline (style, window, state_type, area, widget,
3123 draw_slider (GtkStyle *style,
3125 GtkStateType state_type,
3126 GtkShadowType shadow_type,
3129 const gchar *detail,
3131 gint y, gint width, gint height, GtkOrientation orientation)
3133 if (GTK_IS_SCALE (widget) &&
3134 xp_theme_draw (window, ((orientation == GTK_ORIENTATION_VERTICAL) ?
3135 XP_THEME_ELEMENT_SCALE_SLIDER_V :
3136 XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
3137 height, state_type, area))
3142 parent_class->draw_slider (style, window, state_type, shadow_type, area,
3143 widget, detail, x, y, width, height,
3148 draw_resize_grip (GtkStyle *style,
3150 GtkStateType state_type,
3153 const gchar *detail,
3154 GdkWindowEdge edge, gint x, gint y, gint width, gint height)
3158 cr = gdk_cairo_create (window);
3160 if (detail && !strcmp (detail, "statusbar"))
3163 (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
3164 height, state_type, area))
3173 HDC dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
3177 gdk_cairo_rectangle (cr, area);
3179 gdk_cairo_set_source_color (cr, &style->dark[state_type]);
3182 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
3183 release_window_dc (&dc_info);
3190 parent_class->draw_resize_grip (style, window, state_type, area,
3191 widget, detail, edge, x, y, width, height);
3195 draw_handle (GtkStyle *style,
3197 GtkStateType state_type,
3198 GtkShadowType shadow_type,
3201 const gchar *detail,
3203 gint y, gint width, gint height, GtkOrientation orientation)
3210 cr = gdk_cairo_create (window);
3212 if (is_toolbar_child (widget))
3214 XpThemeElement hndl;
3216 sanitize_size (window, &width, &height);
3218 if (GTK_IS_HANDLE_BOX (widget))
3220 GtkPositionType pos;
3221 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (widget));
3223 if (pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM)
3225 orientation = GTK_ORIENTATION_HORIZONTAL;
3229 orientation = GTK_ORIENTATION_VERTICAL;
3233 if (orientation == GTK_ORIENTATION_VERTICAL)
3234 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_V;
3236 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
3238 if (xp_theme_draw (window, hndl, style, x, y, width, height,
3244 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
3246 if (orientation == GTK_ORIENTATION_VERTICAL)
3249 rect.right = rect.left + 3;
3256 rect.bottom = rect.top + 3;
3261 draw_3d_border (dc, &rect, FALSE);
3262 release_window_dc (&dc_info);
3266 if (!GTK_IS_PANED (widget))
3268 gint xthick, ythick;
3269 GdkColor *light, *dark, *shadow;
3272 sanitize_size (window, &width, &height);
3274 gtk_paint_box (style, window, state_type, shadow_type, area,
3275 widget, detail, x, y, width, height);
3277 light = &style->light[state_type];
3278 dark = &style->dark[state_type];
3279 shadow = &style->mid[state_type];
3281 xthick = style->xthickness;
3282 ythick = style->ythickness;
3284 dest.x = x + xthick;
3285 dest.y = y + ythick;
3286 dest.width = width - (xthick * 2);
3287 dest.height = height - (ythick * 2);
3289 if (dest.width < dest.height)
3294 gdk_cairo_rectangle (cr, &dest);
3297 if (dest.width < dest.height)
3299 _cairo_draw_line (cr, light, dest.x, dest.y, dest.x,
3301 _cairo_draw_line (cr, dark, dest.x + (dest.width / 2),
3302 dest.y, dest.x + (dest.width / 2), dest.height);
3303 _cairo_draw_line (cr, shadow, dest.x + dest.width,
3304 dest.y, dest.x + dest.width, dest.height);
3308 _cairo_draw_line (cr, light, dest.x, dest.y,
3309 dest.x + dest.width, dest.y);
3310 _cairo_draw_line (cr, dark, dest.x,
3311 dest.y + (dest.height / 2),
3312 dest.x + dest.width, dest.y + (dest.height / 2));
3313 _cairo_draw_line (cr, shadow, dest.x,
3314 dest.y + dest.height, dest.x + dest.width,
3315 dest.y + dest.height);
3323 draw_focus (GtkStyle *style,
3325 GtkStateType state_type,
3328 const gchar *detail, gint x, gint y, gint width, gint height)
3334 if (!gtk_widget_get_can_focus (widget))
3339 if (is_combo_box_child (widget)
3340 && (GTK_IS_ARROW (widget) || GTK_IS_BUTTON (widget)))
3344 if (GTK_IS_TREE_VIEW (widget->parent) /* list view bheader */)
3349 dc = get_window_dc (style, window, state_type, &dc_info, x, y, width, height, &rect);
3350 DrawFocusRect (dc, &rect);
3351 release_window_dc (&dc_info);
3353 parent_class->draw_focus (style, window, state_type,
3354 area, widget, detail, x, y, width, height);
3359 draw_layout (GtkStyle *style,
3361 GtkStateType state_type,
3365 const gchar *detail,
3366 gint old_x, gint old_y, PangoLayout *layout)
3368 GtkNotebook *notebook = NULL;
3372 /* In the XP theme, labels don't appear correctly centered inside
3373 * notebook tabs, so we give them a gentle nudge two pixels to the
3374 * right. A little hackish, but what are 'ya gonna do? -- Cody
3376 if (xp_theme_is_active () && detail && !strcmp (detail, "label"))
3378 if (widget->parent != NULL)
3380 if (GTK_IS_NOTEBOOK (widget->parent))
3383 notebook = GTK_NOTEBOOK (widget->parent);
3384 side = gtk_notebook_get_tab_pos (notebook);
3386 if (side == GTK_POS_TOP || side == GTK_POS_BOTTOM)
3394 parent_class->draw_layout (style, window, state_type,
3395 use_text, area, widget, detail, x, y, layout);
3399 msw_style_init_from_rc (GtkStyle *style, GtkRcStyle *rc_style)
3401 setup_system_font (style);
3402 setup_menu_settings (gtk_settings_get_default ());
3403 setup_system_styles (style);
3404 parent_class->init_from_rc (style, rc_style);
3408 msw_style_class_init (MswStyleClass *klass)
3410 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3412 parent_class = g_type_class_peek_parent (klass);
3414 style_class->init_from_rc = msw_style_init_from_rc;
3415 style_class->draw_arrow = draw_arrow;
3416 style_class->draw_box = draw_box;
3417 style_class->draw_check = draw_check;
3418 style_class->draw_option = draw_option;
3419 style_class->draw_tab = draw_tab;
3420 style_class->draw_flat_box = draw_flat_box;
3421 style_class->draw_expander = draw_expander;
3422 style_class->draw_extension = draw_extension;
3423 style_class->draw_box_gap = draw_box_gap;
3424 style_class->draw_shadow = draw_shadow;
3425 style_class->draw_hline = draw_hline;
3426 style_class->draw_vline = draw_vline;
3427 style_class->draw_handle = draw_handle;
3428 style_class->draw_resize_grip = draw_resize_grip;
3429 style_class->draw_slider = draw_slider;
3430 style_class->draw_focus = draw_focus;
3431 style_class->draw_layout = draw_layout;
3434 GType msw_type_style = 0;
3437 msw_style_register_type (GTypeModule *module)
3439 const GTypeInfo object_info = {
3440 sizeof (MswStyleClass),
3441 (GBaseInitFunc) NULL,
3442 (GBaseFinalizeFunc) NULL,
3443 (GClassInitFunc) msw_style_class_init,
3444 NULL, /* class_finalize */
3445 NULL, /* class_data */
3447 0, /* n_preallocs */
3448 (GInstanceInitFunc) NULL,
3451 msw_type_style = g_type_module_register_type (module,
3453 "MswStyle", &object_info, 0);
3457 msw_style_init (void)
3460 msw_style_setup_system_settings ();
3461 setup_msw_rc_style ();
3465 DeleteObject (g_light_pen);
3471 DeleteObject (g_dark_pen);
3477 msw_style_finalize (void)
3481 DeleteObject (g_dither_brush);
3486 DeleteObject (g_light_pen);
3491 DeleteObject (g_dark_pen);