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 "msw_style.h"
43 /* #include <gdk/gdkwin32.h> */
45 #include "gdk/win32/gdkwin32.h"
47 static HDC get_window_dc (GtkStyle *style, GdkWindow *window,
48 GtkStateType state_type, gint x, gint y, gint width,
49 gint height, RECT *rect);
50 static void release_window_dc (GtkStyle *style, GdkWindow *window,
51 GtkStateType state_type);
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 guint8 check_aa_bits[] = {
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
90 static const guint8 check_base_bits[] = {
91 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07,
93 0x07, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00
95 static const guint8 check_black_bits[] = {
96 0x00, 0x00, 0xfe, 0x0f, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
98 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00
100 static const guint8 check_dark_bits[] = {
101 0xff, 0x1f, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
103 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00
105 static const guint8 check_light_bits[] = {
106 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
108 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0xfe, 0x1f
110 static const guint8 check_mid_bits[] = {
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08,
113 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xfc, 0x0f, 0x00, 0x00
115 static const guint8 check_text_bits[] = {
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x88, 0x03,
118 0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
120 static const char check_inconsistent_bits[] = {
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
125 static const guint8 radio_base_bits[] = {
126 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xf8, 0x03, 0xfc, 0x07, 0xfc, 0x07,
128 0x07, 0xfc, 0x07, 0xf8, 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00
130 static const guint8 radio_black_bits[] = {
131 0x00, 0x00, 0xf0, 0x01, 0x0c, 0x02, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00,
133 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
135 static const guint8 radio_dark_bits[] = {
136 0xf0, 0x01, 0x0c, 0x06, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00,
138 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
140 static const guint8 radio_light_bits[] = {
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10,
143 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x0c, 0x06, 0xf0, 0x01
145 static const guint8 radio_mid_bits[] = {
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08,
148 0x08, 0x00, 0x08, 0x00, 0x04, 0x0c, 0x06, 0xf0, 0x01, 0x00, 0x00
150 static const guint8 radio_text_bits[] = {
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf0, 0x01,
153 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
161 { check_aa_bits, NULL },
162 { check_base_bits, NULL },
163 { check_black_bits, NULL },
164 { check_dark_bits, NULL },
165 { check_light_bits, NULL },
166 { check_mid_bits, NULL },
167 { check_text_bits, NULL },
168 { check_inconsistent_bits, NULL },
169 { radio_base_bits, NULL },
170 { radio_black_bits, NULL },
171 { radio_dark_bits, NULL },
172 { radio_light_bits, NULL },
173 { radio_mid_bits, NULL },
174 { radio_text_bits, NULL }
178 get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONT *out_lf)
181 /* TODO: this causes crashes later because the font name is in UCS2, and
182 the pango fns don't deal with that gracefully */
183 if (xp_theme_get_system_font (klazz, type, out_lf))
190 NONCLIENTMETRICS ncm;
192 ncm.cbSize = sizeof (NONCLIENTMETRICS);
194 if (SystemParametersInfo (SPI_GETNONCLIENTMETRICS,
195 sizeof (NONCLIENTMETRICS), &ncm, 0))
197 if (type == XP_THEME_FONT_CAPTION)
198 *out_lf = ncm.lfCaptionFont;
199 else if (type == XP_THEME_FONT_MENU)
200 *out_lf = ncm.lfMenuFont;
201 else if (type == XP_THEME_FONT_STATUS)
202 *out_lf = ncm.lfStatusFont;
204 *out_lf = ncm.lfMessageFont;
213 /***************************** BEGIN STOLEN FROM PANGO *****************************/
216 This code is stolen from Pango 1.4. It attempts to address the following problems:
218 http://bugzilla.gnome.org/show_bug.cgi?id=135098
219 http://sourceforge.net/tracker/index.php?func=detail&aid=895762&group_id=76416&atid=547655
221 As Owen suggested in bug 135098, once Pango 1.6 is released, we need to get rid of this code.
224 #define PING(printlist)
226 /* TrueType defines: */
228 #define MAKE_TT_TABLE_NAME(c1, c2, c3, c4) \
229 (((guint32)c4) << 24 | ((guint32)c3) << 16 | ((guint32)c2) << 8 | ((guint32)c1))
231 #define CMAP (MAKE_TT_TABLE_NAME('c','m','a','p'))
232 #define CMAP_HEADER_SIZE 4
234 #define NAME (MAKE_TT_TABLE_NAME('n','a','m','e'))
235 #define NAME_HEADER_SIZE 6
237 #define ENCODING_TABLE_SIZE 8
239 #define APPLE_UNICODE_PLATFORM_ID 0
240 #define MACINTOSH_PLATFORM_ID 1
241 #define ISO_PLATFORM_ID 2
242 #define MICROSOFT_PLATFORM_ID 3
244 #define SYMBOL_ENCODING_ID 0
245 #define UNICODE_ENCODING_ID 1
246 #define UCS4_ENCODING_ID 10
250 guint16 format_selector;
252 guint16 string_storage_offset;
261 guint16 string_length;
262 guint16 string_offset;
266 pango_win32_get_name_header (HDC hdc, struct name_header *header)
268 if (GetFontData (hdc, NAME, 0, header, sizeof (*header)) != sizeof (*header))
271 header->num_records = GUINT16_FROM_BE (header->num_records);
272 header->string_storage_offset = GUINT16_FROM_BE (header->string_storage_offset);
278 pango_win32_get_name_record (HDC hdc, gint i, struct name_record *record)
280 if (GetFontData (hdc, NAME, 6 + i * sizeof (*record),
281 record, sizeof (*record)) != sizeof (*record))
286 record->platform_id = GUINT16_FROM_BE (record->platform_id);
287 record->encoding_id = GUINT16_FROM_BE (record->encoding_id);
288 record->language_id = GUINT16_FROM_BE (record->language_id);
289 record->name_id = GUINT16_FROM_BE (record->name_id);
290 record->string_length = GUINT16_FROM_BE (record->string_length);
291 record->string_offset = GUINT16_FROM_BE (record->string_offset);
297 get_family_name (LOGFONT *lfp, HDC pango_win32_hdc)
302 struct name_header header;
303 struct name_record record;
305 gint unicode_ix = -1, mac_ix = -1, microsoft_ix = -1;
309 gchar *string = NULL;
314 /* If lfFaceName is ASCII, assume it is the common (English) name for the
315 font. Is this valid? Do some TrueType fonts have different names in
316 French, German, etc, and does the system return these if the locale is
317 set to use French, German, etc? */
318 l = strlen (lfp->lfFaceName);
319 for (i = 0; i < l; i++)
321 if (lfp->lfFaceName[i] < ' ' || lfp->lfFaceName[i] > '~')
328 return g_strdup (lfp->lfFaceName);
330 if ((hfont = CreateFontIndirect (lfp)) == NULL)
333 if ((oldhfont = (HFONT) SelectObject (pango_win32_hdc, hfont)) == NULL)
336 if (!pango_win32_get_name_header (pango_win32_hdc, &header))
339 PING (("%d name records", header.num_records));
341 for (i = 0; i < header.num_records; i++)
343 if (!pango_win32_get_name_record (pango_win32_hdc, i, &record))
346 if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0)
349 PING (("platform:%d encoding:%d language:%04x name_id:%d",
350 record.platform_id, record.encoding_id, record.language_id,
353 if (record.platform_id == APPLE_UNICODE_PLATFORM_ID ||
354 record.platform_id == ISO_PLATFORM_ID)
358 else if (record.platform_id == MACINTOSH_PLATFORM_ID && record.encoding_id == 0 && /* Roman
360 record.language_id == 0) /* English */
364 else if (record.platform_id == MICROSOFT_PLATFORM_ID)
366 if ((microsoft_ix == -1 ||
367 PRIMARYLANGID (record.language_id) == LANG_ENGLISH) &&
368 (record.encoding_id == SYMBOL_ENCODING_ID ||
369 record.encoding_id == UNICODE_ENCODING_ID ||
370 record.encoding_id == UCS4_ENCODING_ID))
377 if (microsoft_ix >= 0)
378 name_ix = microsoft_ix;
379 else if (mac_ix >= 0)
381 else if (unicode_ix >= 0)
382 name_ix = unicode_ix;
386 if (!pango_win32_get_name_record (pango_win32_hdc, name_ix, &record))
389 string = g_malloc (record.string_length + 1);
390 if (GetFontData (pango_win32_hdc, NAME,
391 header.string_storage_offset + record.string_offset,
392 string, record.string_length) != record.string_length)
395 string[record.string_length] = '\0';
397 if (name_ix == microsoft_ix)
399 if (record.encoding_id == SYMBOL_ENCODING_ID ||
400 record.encoding_id == UNICODE_ENCODING_ID)
402 codeset = "UTF-16BE";
409 else if (name_ix == mac_ix)
411 codeset = "MacRoman";
413 else /* name_ix == unicode_ix */
419 name = g_convert (string, record.string_length, "UTF-8", codeset, NULL,
428 SelectObject (pango_win32_hdc, oldhfont);
429 DeleteObject (hfont);
435 SelectObject (pango_win32_hdc, oldhfont);
438 DeleteObject (hfont);
441 return g_locale_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
444 /***************************** END STOLEN FROM PANGO *****************************/
447 sys_font_to_pango_font (XpThemeClass klazz, XpThemeFont type, char *buf,
458 if (get_system_font (klazz, type, &lf))
464 weight = "Ultra-Light";
476 weight = "Semi-Bold";
480 weight = "Ultra-Bold";
497 hwnd = GetDesktopWindow ();
501 pt_size = -MulDiv (lf.lfHeight, 72,
502 GetDeviceCaps (hDC, LOGPIXELSY));
509 font = get_family_name (&lf, hDC);
512 ReleaseDC (hwnd, hDC);
514 if (!(font && *font))
517 g_snprintf (buf, bufsiz, "%s %s %s %d", font, style, weight, pt_size);
526 /* missing from ms's header files */
527 #ifndef SPI_GETMENUSHOWDELAY
528 #define SPI_GETMENUSHOWDELAY 106
531 /* I don't know the proper XP theme class for things like
532 HIGHLIGHTTEXT, so we'll just define it to be "BUTTON"
534 #define XP_THEME_CLASS_TEXT XP_THEME_CLASS_BUTTON
537 setup_menu_settings (GtkSettings *settings)
540 gboolean win95 = FALSE;
541 OSVERSIONINFOEX osvi;
542 GObjectClass *klazz = G_OBJECT_GET_CLASS (G_OBJECT (settings));
544 ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
545 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
547 if (!GetVersionEx ((OSVERSIONINFO *) & osvi))
548 win95 = TRUE; /* assume the worst */
550 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
552 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
560 if (SystemParametersInfo (SPI_GETMENUSHOWDELAY, 0, &menu_delay, 0))
564 if (g_object_class_find_property
565 (klazz, "gtk-menu-bar-popup-delay"))
567 g_object_set (settings,
568 "gtk-menu-bar-popup-delay", 0, NULL);
570 if (g_object_class_find_property
571 (klazz, "gtk-menu-popup-delay"))
573 g_object_set (settings,
574 "gtk-menu-popup-delay", menu_delay, NULL);
576 if (g_object_class_find_property
577 (klazz, "gtk-menu-popdown-delay"))
579 g_object_set (settings,
580 "gtk-menu-popdown-delay", menu_delay, NULL);
588 msw_style_setup_system_settings (void)
590 GtkSettings *settings;
591 int cursor_blink_time;
593 settings = gtk_settings_get_default ();
597 cursor_blink_time = GetCaretBlinkTime ();
598 g_object_set (settings, "gtk-cursor-blink", cursor_blink_time > 0, NULL);
600 if (cursor_blink_time > 0)
602 g_object_set (settings, "gtk-cursor-blink-time",
603 2 * cursor_blink_time, NULL);
606 g_object_set (settings, "gtk-double-click-distance",
607 GetSystemMetrics (SM_CXDOUBLECLK), NULL);
608 g_object_set (settings, "gtk-double-click-time", GetDoubleClickTime (),
610 g_object_set (settings, "gtk-dnd-drag-threshold",
611 GetSystemMetrics (SM_CXDRAG), NULL);
613 setup_menu_settings (settings);
616 http://developer.gnome.org/doc/API/2.0/gtk/GtkSettings.html
617 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/systemparametersinfo.asp
618 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getsystemmetrics.asp */
622 setup_system_font (GtkStyle *style)
624 char buf[256], *font; /* It's okay, lfFaceName is smaller than 32
627 if ((font = sys_font_to_pango_font (XP_THEME_CLASS_TEXT,
628 XP_THEME_FONT_MESSAGE,
629 buf, sizeof (buf))) != NULL)
631 if (style->font_desc)
633 pango_font_description_free (style->font_desc);
636 style->font_desc = pango_font_description_from_string (font);
641 sys_color_to_gtk_color (XpThemeClass klazz, int id, GdkColor * pcolor)
645 if (!xp_theme_get_system_color (klazz, id, &color))
646 color = GetSysColor (id);
648 pcolor->pixel = color;
649 pcolor->red = (GetRValue (color) << 8) | GetRValue (color);
650 pcolor->green = (GetGValue (color) << 8) | GetGValue (color);
651 pcolor->blue = (GetBValue (color) << 8) | GetBValue (color);
655 get_system_metric (XpThemeClass klazz, int id)
659 if (!xp_theme_get_system_metric (klazz, id, &rval))
660 rval = GetSystemMetrics (id);
666 setup_msw_rc_style (void)
668 char buf[1024], font_buf[256], *font_ptr;
669 char menu_bar_prelight_str[128];
672 GdkColor menu_text_color;
673 GdkColor tooltip_back;
674 GdkColor tooltip_fore;
677 GdkColor progress_back;
679 GdkColor fg_prelight;
680 GdkColor bg_prelight;
681 GdkColor base_prelight;
682 GdkColor text_prelight;
685 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
687 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT, &bg_prelight);
688 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
690 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
693 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENUTEXT,
695 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENU, &menu_color);
698 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOTEXT,
700 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOBK,
703 /* text on push buttons. TODO: button shadows, backgrounds, and
705 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT, &btn_fore);
706 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE, &btn_face);
708 /* progress bar background color */
709 sys_color_to_gtk_color (XP_THEME_CLASS_PROGRESS, COLOR_HIGHLIGHT,
712 /* Enable coloring for menus. */
714 sys_font_to_pango_font (XP_THEME_CLASS_MENU, XP_THEME_FONT_MENU,
715 font_buf, sizeof (font_buf));
716 g_snprintf (buf, sizeof (buf),
717 "style \"msw-menu\" = \"msw-default\"\n" "{\n"
718 "GtkMenuItem::toggle-spacing = 8\n"
719 "fg[PRELIGHT] = { %d, %d, %d }\n"
720 "bg[PRELIGHT] = { %d, %d, %d }\n"
721 "text[PRELIGHT] = { %d, %d, %d }\n"
722 "base[PRELIGHT] = { %d, %d, %d }\n"
723 "fg[NORMAL] = { %d, %d, %d }\n"
724 "bg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
725 "}widget_class \"*MenuItem*\" style \"msw-menu\"\n"
726 "widget_class \"*GtkMenu\" style \"msw-menu\"\n"
727 "widget_class \"*GtkMenuShell*\" style \"msw-menu\"\n",
728 fg_prelight.red, fg_prelight.green, fg_prelight.blue,
729 bg_prelight.red, bg_prelight.green, bg_prelight.blue,
730 text_prelight.red, text_prelight.green, text_prelight.blue,
731 base_prelight.red, base_prelight.green, base_prelight.blue,
732 menu_text_color.red, menu_text_color.green,
733 menu_text_color.blue, menu_color.red, menu_color.green,
734 menu_color.blue, (font_ptr ? "font_name" : "#"),
735 (font_ptr ? font_ptr : " font name should go here"));
736 gtk_rc_parse_string (buf);
738 if (xp_theme_is_active ())
740 *menu_bar_prelight_str = '\0';
744 g_snprintf (menu_bar_prelight_str, sizeof (menu_bar_prelight_str),
745 "fg[PRELIGHT] = { %d, %d, %d }\n",
746 menu_text_color.red, menu_text_color.green,
747 menu_text_color.blue);
750 /* Enable coloring for menu bars. */
751 g_snprintf (buf, sizeof (buf),
752 "style \"msw-menu-bar\" = \"msw-menu\"\n"
754 "bg[NORMAL] = { %d, %d, %d }\n"
755 "%s" "GtkMenuBar::shadow-type = %d\n"
757 FIXME: This should be enabled once gtk+ support
758 GtkMenuBar::prelight-item style property.
760 /* "GtkMenuBar::prelight-item = 1\n" */
761 "}widget_class \"*MenuBar*\" style \"msw-menu-bar\"\n",
762 btn_face.red, btn_face.green, btn_face.blue,
763 menu_bar_prelight_str, xp_theme_is_active ()? 0 : 2);
764 gtk_rc_parse_string (buf);
766 g_snprintf (buf, sizeof (buf),
767 "style \"msw-toolbar\" = \"msw-default\"\n"
769 "GtkHandleBox::shadow-type = %s\n"
770 "GtkToolbar::shadow-type = %s\n"
771 "}widget_class \"*HandleBox*\" style \"msw-toolbar\"\n",
772 "etched-in", "etched-in");
773 gtk_rc_parse_string (buf);
775 /* enable tooltip fonts */
776 font_ptr = sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
777 font_buf, sizeof (font_buf));
778 g_snprintf (buf, sizeof (buf),
779 "style \"msw-tooltips-caption\" = \"msw-default\"\n"
780 "{fg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
781 "}widget \"gtk-tooltips.GtkLabel\" style \"msw-tooltips-caption\"\n",
782 tooltip_fore.red, tooltip_fore.green, tooltip_fore.blue,
783 (font_ptr ? "font_name" : "#"),
784 (font_ptr ? font_ptr : " font name should go here"));
785 gtk_rc_parse_string (buf);
787 g_snprintf (buf, sizeof (buf),
788 "style \"msw-tooltips\" = \"msw-default\"\n"
789 "{bg[NORMAL] = { %d, %d, %d }\n"
790 "}widget \"gtk-tooltips*\" style \"msw-tooltips\"\n",
791 tooltip_back.red, tooltip_back.green, tooltip_back.blue);
792 gtk_rc_parse_string (buf);
794 /* enable font theming for status bars */
795 font_ptr = sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
796 font_buf, sizeof (font_buf));
797 g_snprintf (buf, sizeof (buf),
798 "style \"msw-status\" = \"msw-default\"\n" "{%s = \"%s\"\n"
799 "bg[NORMAL] = { %d, %d, %d }\n"
800 "}widget_class \"*Status*\" style \"msw-status\"\n",
801 (font_ptr ? "font_name" : "#"),
802 (font_ptr ? font_ptr : " font name should go here"),
803 btn_face.red, btn_face.green, btn_face.blue);
804 gtk_rc_parse_string (buf);
806 /* enable coloring for text on buttons TODO: use GetThemeMetric for the
807 border and outside border */
808 g_snprintf (buf, sizeof (buf),
809 "style \"msw-button\" = \"msw-default\"\n"
811 "bg[NORMAL] = { %d, %d, %d }\n"
812 "bg[PRELIGHT] = { %d, %d, %d }\n"
813 "bg[INSENSITIVE] = { %d, %d, %d }\n"
814 "fg[PRELIGHT] = { %d, %d, %d }\n"
815 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
816 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
817 "GtkButton::child-displacement-x = 1\n"
818 "GtkButton::child-displacement-y = 1\n"
819 "GtkButton::focus-padding = %d\n"
820 "}widget_class \"*Button*\" style \"msw-button\"\n",
821 btn_face.red, btn_face.green, btn_face.blue,
822 btn_face.red, btn_face.green, btn_face.blue,
823 btn_face.red, btn_face.green, btn_face.blue,
824 btn_fore.red, btn_fore.green, btn_fore.blue,
825 xp_theme_is_active ()? 1 : 2);
826 gtk_rc_parse_string (buf);
828 /* enable coloring for progress bars */
829 g_snprintf (buf, sizeof (buf),
830 "style \"msw-progress\" = \"msw-default\"\n"
831 "{bg[PRELIGHT] = { %d, %d, %d }\n"
832 "bg[NORMAL] = { %d, %d, %d }\n"
833 "}widget_class \"*Progress*\" style \"msw-progress\"\n",
837 btn_face.red, btn_face.green, btn_face.blue);
838 gtk_rc_parse_string (buf);
840 /* scrollbar thumb width and height */
841 g_snprintf (buf, sizeof (buf),
842 "style \"msw-vscrollbar\" = \"msw-default\"\n"
843 "{GtkRange::slider-width = %d\n"
844 "GtkRange::stepper-size = %d\n"
845 "GtkRange::stepper-spacing = 0\n"
846 "GtkRange::trough_border = 0\n"
847 "GtkScale::slider-length = %d\n"
848 "GtkScrollbar::min-slider-length = 8\n"
849 "}widget_class \"*VScrollbar*\" style \"msw-vscrollbar\"\n"
850 "widget_class \"*VScale*\" style \"msw-vscrollbar\"\n",
851 GetSystemMetrics (SM_CYVTHUMB),
852 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CXVSCROLL), 11);
853 gtk_rc_parse_string (buf);
855 g_snprintf (buf, sizeof (buf),
856 "style \"msw-hscrollbar\" = \"msw-default\"\n"
857 "{GtkRange::slider-width = %d\n"
858 "GtkRange::stepper-size = %d\n"
859 "GtkRange::stepper-spacing = 0\n"
860 "GtkRange::trough_border = 0\n"
861 "GtkScale::slider-length = %d\n"
862 "GtkScrollbar::min-slider-length = 8\n"
863 "}widget_class \"*HScrollbar*\" style \"msw-hscrollbar\"\n"
864 "widget_class \"*HScale*\" style \"msw-hscrollbar\"\n",
865 GetSystemMetrics (SM_CXHTHUMB),
866 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CYHSCROLL), 11);
867 gtk_rc_parse_string (buf);
869 gtk_rc_parse_string ("style \"msw-scrolled-window\" = \"msw-default\"\n"
870 "{GtkScrolledWindow::scrollbars-within-bevel = 1}\n"
871 "class \"GtkScrolledWindow\" style \"msw-scrolled-window\"\n");
873 /* radio/check button sizes */
874 g_snprintf (buf, sizeof (buf),
875 "style \"msw-checkbutton\" = \"msw-button\"\n"
876 "{GtkCheckButton::indicator-size = 13\n"
877 "}widget_class \"*CheckButton*\" style \"msw-checkbutton\"\n"
878 "widget_class \"*RadioButton*\" style \"msw-checkbutton\"\n");
879 gtk_rc_parse_string (buf);
881 /* size of combo box toggle button */
882 g_snprintf (buf, sizeof (buf),
883 "style \"msw-combobox-button\" = \"msw-default\"\n"
887 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
888 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
889 "GtkButton::child-displacement-x = 0\n"
890 "GtkButton::child-displacement-y = 0\n"
891 "GtkWidget::focus-padding = 0\n"
892 "GtkWidget::focus-line-width = 0\n"
894 "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combobox-button\"\n");
895 gtk_rc_parse_string (buf);
897 g_snprintf (buf, sizeof (buf),
898 "style \"msw-combobox\" = \"msw-default\"\n"
900 "GtkComboBox::shadow-type = in\n"
904 "class \"GtkComboBox\" style \"msw-combobox\"\n",
905 xp_theme_is_active()? 1 : GetSystemMetrics (SM_CXEDGE),
906 xp_theme_is_active()? 1 : GetSystemMetrics (SM_CYEDGE));
907 gtk_rc_parse_string (buf);
909 /* size of tree view header */
910 g_snprintf (buf, sizeof (buf),
911 "style \"msw-header-button\" = \"msw-default\"\n"
915 "GtkWidget::draw-border = {0, 0, 0, 0}\n"
916 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
917 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
918 "GtkButton::child-displacement-x = 0\n"
919 "GtkButton::child-displacement-y = 0\n"
920 "GtkWidget::focus-padding = 0\n"
921 "GtkWidget::focus-line-width = 0\n"
923 "widget_class \"*TreeView*Button*\" style \"msw-header-button\"\n");
924 gtk_rc_parse_string (buf);
926 /* FIXME: This should be enabled once gtk+ support GtkNotebok::prelight-tab */
927 /* enable prelight tab of GtkNotebook */
929 g_snprintf (buf, sizeof (buf),
930 "style \"msw-notebook\" = \"msw-default\"\n"
931 "{GtkNotebook::prelight-tab=1\n"
932 "}widget_class \"*Notebook*\" style \"msw-notebook\"\n");
933 gtk_rc_parse_string (buf);
936 /* FIXME: This should be enabled once gtk+ support GtkTreeView::full-row-focus */
938 g_snprintf (buf, sizeof (buf),
939 "style \"msw-treeview\" = \"msw-default\"\n"
940 "{GtkTreeView::full-row-focus=0\n"
941 "}widget_class \"*TreeView*\" style \"msw-treeview\"\n");
942 gtk_rc_parse_string (buf);
947 setup_system_styles (GtkStyle *style)
951 /* Default background */
952 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
953 &style->bg[GTK_STATE_NORMAL]);
954 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
955 &style->bg[GTK_STATE_SELECTED]);
956 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
957 &style->bg[GTK_STATE_INSENSITIVE]);
958 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
959 &style->bg[GTK_STATE_ACTIVE]);
960 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
961 &style->bg[GTK_STATE_PRELIGHT]);
964 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
965 &style->base[GTK_STATE_NORMAL]);
966 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
967 &style->base[GTK_STATE_SELECTED]);
968 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
969 &style->base[GTK_STATE_INSENSITIVE]);
970 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
971 &style->base[GTK_STATE_ACTIVE]);
972 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
973 &style->base[GTK_STATE_PRELIGHT]);
976 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
977 &style->text[GTK_STATE_NORMAL]);
978 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
979 &style->text[GTK_STATE_SELECTED]);
980 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_GRAYTEXT,
981 &style->text[GTK_STATE_INSENSITIVE]);
982 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
983 &style->text[GTK_STATE_ACTIVE]);
984 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
985 &style->text[GTK_STATE_PRELIGHT]);
987 /* Default foreground */
988 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
989 &style->fg[GTK_STATE_NORMAL]);
990 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
991 &style->fg[GTK_STATE_SELECTED]);
992 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_GRAYTEXT,
993 &style->fg[GTK_STATE_INSENSITIVE]);
994 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
995 &style->fg[GTK_STATE_ACTIVE]);
996 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
997 &style->fg[GTK_STATE_PRELIGHT]);
999 for (i = 0; i < 5; i++)
1001 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DSHADOW,
1003 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DHILIGHT,
1006 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1007 style->mid[i].green =
1008 (style->light[i].green + style->dark[i].green) / 2;
1009 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1011 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1012 style->text_aa[i].green =
1013 (style->text[i].green + style->base[i].green) / 2;
1014 style->text_aa[i].blue =
1015 (style->text[i].blue + style->base[i].blue) / 2;
1020 sanitize_size (GdkWindow *window, gint *width, gint *height)
1022 gboolean set_bg = FALSE;
1024 if ((*width == -1) && (*height == -1))
1026 set_bg = GDK_IS_WINDOW (window);
1027 gdk_drawable_get_size (window, width, height);
1029 else if (*width == -1)
1031 gdk_drawable_get_size (window, width, NULL);
1033 else if (*height == -1)
1035 gdk_drawable_get_size (window, NULL, height);
1041 static XpThemeElement
1042 map_gtk_progress_bar_to_xp (GtkProgressBar *progress_bar, gboolean trough)
1046 switch (progress_bar->orientation)
1048 case GTK_PROGRESS_LEFT_TO_RIGHT:
1049 case GTK_PROGRESS_RIGHT_TO_LEFT:
1051 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_H
1052 : XP_THEME_ELEMENT_PROGRESS_BAR_H;
1057 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_V
1058 : XP_THEME_ELEMENT_PROGRESS_BAR_V;
1066 is_combo_box_child (GtkWidget *w)
1073 for (tmp = w->parent; tmp; tmp = tmp->parent)
1075 if (GTK_IS_COMBO_BOX (tmp))
1082 /* This function is not needed anymore */
1084 combo_box_draw_arrow (GtkStyle *style,
1087 GdkRectangle *area, GtkWidget *widget)
1089 if (xp_theme_is_active ())
1092 if (widget && GTK_IS_TOGGLE_BUTTON (widget->parent))
1098 dc = get_window_dc (style, window, state, area->x, area->y, area->width,
1099 area->height, &rect);
1100 border = (GTK_TOGGLE_BUTTON (widget->parent)->
1101 active ? DFCS_PUSHED | DFCS_FLAT : 0);
1103 InflateRect (&rect, 1, 1);
1104 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
1106 release_window_dc (style, window, state);
1115 draw_part (GdkDrawable *drawable,
1116 GdkGC *gc, GdkRectangle *area, gint x, gint y, Part part)
1119 gdk_gc_set_clip_rectangle (gc, area);
1121 if (!parts[part].bmap)
1123 parts[part].bmap = gdk_bitmap_create_from_data (drawable,
1125 PART_SIZE, PART_SIZE);
1128 gdk_gc_set_ts_origin (gc, x, y);
1129 gdk_gc_set_stipple (gc, parts[part].bmap);
1130 gdk_gc_set_fill (gc, GDK_STIPPLED);
1132 gdk_draw_rectangle (drawable, gc, TRUE, x, y, PART_SIZE, PART_SIZE);
1134 gdk_gc_set_fill (gc, GDK_SOLID);
1137 gdk_gc_set_clip_rectangle (gc, NULL);
1141 draw_check (GtkStyle *style,
1144 GtkShadowType shadow,
1147 const gchar *detail, gint x, gint y, gint width, gint height)
1149 x -= (1 + PART_SIZE - width) / 2;
1150 y -= (1 + PART_SIZE - height) / 2;
1152 if (detail && strcmp (detail, "check") == 0) /* Menu item */
1154 if (shadow == GTK_SHADOW_IN)
1156 draw_part (window, style->black_gc, area, x, y, CHECK_TEXT);
1157 draw_part (window, style->dark_gc[state], area, x, y, CHECK_AA);
1162 XpThemeElement theme_elt = XP_THEME_ELEMENT_CHECKBOX;
1165 case GTK_SHADOW_ETCHED_IN:
1166 theme_elt = XP_THEME_ELEMENT_INCONSISTENT_CHECKBOX;
1170 theme_elt = XP_THEME_ELEMENT_PRESSED_CHECKBOX;
1177 if (!xp_theme_draw (window, theme_elt,
1178 style, x, y, width, height, state, area))
1180 if (detail && !strcmp (detail, "cellcheck"))
1181 state = GTK_STATE_NORMAL;
1183 draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
1184 draw_part (window, style->dark_gc[state], area, x, y, CHECK_DARK);
1185 draw_part (window, style->mid_gc[state], area, x, y, CHECK_MID);
1186 draw_part (window, style->light_gc[state], area, x, y, CHECK_LIGHT);
1187 draw_part (window, style->base_gc[state], area, x, y, CHECK_BASE);
1189 if (shadow == GTK_SHADOW_IN)
1191 draw_part (window, style->text_gc[state], area, x,
1193 draw_part (window, style->text_aa_gc[state], area,
1196 else if (shadow == GTK_SHADOW_ETCHED_IN)
1198 draw_part (window, style->text_gc[state], area, x, y,
1199 CHECK_INCONSISTENT);
1200 draw_part (window, style->text_aa_gc[state], area, x, y,
1208 draw_expander (GtkStyle *style,
1213 const gchar *detail,
1214 gint x, gint y, GtkExpanderStyle expander_style)
1217 gint expander_semi_size;
1218 XpThemeElement xp_expander;
1220 gtk_widget_style_get (widget, "expander_size", &expander_size, NULL);
1222 switch (expander_style)
1224 case GTK_EXPANDER_COLLAPSED:
1225 case GTK_EXPANDER_SEMI_COLLAPSED:
1226 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED;
1230 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED;
1234 if ((expander_size % 2) == 0)
1237 if (expander_size > 2)
1241 gdk_gc_set_clip_rectangle (style->fg_gc[state], area);
1243 expander_semi_size = expander_size / 2;
1244 x -= expander_semi_size;
1245 y -= expander_semi_size;
1247 if (!xp_theme_draw (window, xp_expander, style,
1248 x, y, expander_size, expander_size, state, area))
1255 dc = get_window_dc (style, window, state, x, y, expander_size,
1256 expander_size, &rect);
1257 FrameRect (dc, &rect, GetSysColorBrush (COLOR_GRAYTEXT));
1258 InflateRect (&rect, -1, -1);
1259 FillRect (dc, &rect,
1260 GetSysColorBrush (state ==
1261 GTK_STATE_INSENSITIVE ? COLOR_BTNFACE :
1264 InflateRect (&rect, -1, -1);
1266 pen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_WINDOWTEXT));
1267 old_pen = SelectObject (dc, pen);
1269 MoveToEx (dc, rect.left, rect.top - 2 + expander_semi_size, NULL);
1270 LineTo (dc, rect.right, rect.top - 2 + expander_semi_size);
1272 if (expander_style == GTK_EXPANDER_COLLAPSED ||
1273 expander_style == GTK_EXPANDER_SEMI_COLLAPSED)
1275 MoveToEx (dc, rect.left - 2 + expander_semi_size, rect.top, NULL);
1276 LineTo (dc, rect.left - 2 + expander_semi_size, rect.bottom);
1279 SelectObject (dc, old_pen);
1281 release_window_dc (style, window, state);
1285 gdk_gc_set_clip_rectangle (style->fg_gc[state], NULL);
1289 draw_option (GtkStyle *style,
1292 GtkShadowType shadow,
1295 const gchar *detail, gint x, gint y, gint width, gint height)
1297 x -= (1 + PART_SIZE - width) / 2;
1298 y -= (1 + PART_SIZE - height) / 2;
1300 if (detail && strcmp (detail, "option") == 0) /* Menu item */
1302 if (shadow == GTK_SHADOW_IN)
1304 draw_part (window, style->fg_gc[state], area, x, y, RADIO_TEXT);
1309 if (xp_theme_draw (window, shadow == GTK_SHADOW_IN
1310 ? XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON
1311 : XP_THEME_ELEMENT_RADIO_BUTTON,
1312 style, x, y, width, height, state, area))
1317 if (detail && !strcmp (detail, "cellradio"))
1318 state = GTK_STATE_NORMAL;
1320 draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
1321 draw_part (window, style->dark_gc[state], area, x, y, RADIO_DARK);
1322 draw_part (window, style->mid_gc[state], area, x, y, RADIO_MID);
1323 draw_part (window, style->light_gc[state], area, x, y, RADIO_LIGHT);
1324 draw_part (window, style->base_gc[state], area, x, y, RADIO_BASE);
1326 if (shadow == GTK_SHADOW_IN)
1327 draw_part (window, style->text_gc[state], area, x, y, RADIO_TEXT);
1333 draw_varrow (GdkWindow *window,
1335 GtkShadowType shadow_type,
1337 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1340 gint y_start, y_increment;
1344 gdk_gc_set_clip_rectangle (gc, area);
1346 width = width + width % 2 - 1; /* Force odd */
1347 steps = 1 + width / 2;
1348 extra = height - steps;
1350 if (arrow_type == GTK_ARROW_DOWN)
1357 y_start = y + height - 1;
1361 for (i = extra; i < height; i++)
1363 gdk_draw_line (window, gc,
1364 x + (i - extra), y_start + i * y_increment,
1365 x + width - (i - extra) - 1, y_start + i * y_increment);
1369 gdk_gc_set_clip_rectangle (gc, NULL);
1373 draw_harrow (GdkWindow *window,
1375 GtkShadowType shadow_type,
1377 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1380 gint x_start, x_increment;
1384 gdk_gc_set_clip_rectangle (gc, area);
1386 height = height + height % 2 - 1; /* Force odd */
1387 steps = 1 + height / 2;
1388 extra = width - steps;
1390 if (arrow_type == GTK_ARROW_RIGHT)
1397 x_start = x + width - 1;
1401 for (i = extra; i < width; i++)
1403 gdk_draw_line (window, gc,
1404 x_start + i * x_increment, y + (i - extra),
1405 x_start + i * x_increment, y + height - (i - extra) - 1);
1410 gdk_gc_set_clip_rectangle (gc, NULL);
1413 /* This function makes up for some brokeness in gtkrange.c
1414 * where we never get the full arrow of the stepper button
1415 * and the type of button in a single drawing function.
1417 * It doesn't work correctly when the scrollbar is squished
1418 * to the point we don't have room for full-sized steppers.
1421 reverse_engineer_stepper_box (GtkWidget *range,
1422 GtkArrowType arrow_type,
1423 gint *x, gint *y, gint *width, gint *height)
1425 gint slider_width = 14, stepper_size = 14;
1431 gtk_widget_style_get (range,
1432 "slider_width", &slider_width,
1433 "stepper_size", &stepper_size, NULL);
1436 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1438 box_width = slider_width;
1439 box_height = stepper_size;
1443 box_width = stepper_size;
1444 box_height = slider_width;
1447 *x = *x - (box_width - *width) / 2;
1448 *y = *y - (box_height - *height) / 2;
1450 *height = box_height;
1453 static XpThemeElement
1454 to_xp_arrow (GtkArrowType arrow_type)
1456 XpThemeElement xp_arrow;
1461 xp_arrow = XP_THEME_ELEMENT_ARROW_UP;
1464 case GTK_ARROW_DOWN:
1465 xp_arrow = XP_THEME_ELEMENT_ARROW_DOWN;
1468 case GTK_ARROW_LEFT:
1469 xp_arrow = XP_THEME_ELEMENT_ARROW_LEFT;
1473 xp_arrow = XP_THEME_ELEMENT_ARROW_RIGHT;
1481 draw_arrow (GtkStyle *style,
1484 GtkShadowType shadow,
1487 const gchar *detail,
1488 GtkArrowType arrow_type,
1489 gboolean fill, gint x, gint y, gint width, gint height)
1495 name = gtk_widget_get_name (widget);
1497 sanitize_size (window, &width, &height);
1499 if (GTK_IS_ARROW (widget) && is_combo_box_child (widget) && xp_theme_is_active ())
1502 if (detail && strcmp (detail, "spinbutton") == 0)
1504 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1511 if (arrow_type == GTK_ARROW_DOWN)
1515 if (state == GTK_STATE_ACTIVE)
1521 draw_varrow (window, style->fg_gc[state], shadow, area,
1522 arrow_type, x, y, width, height);
1526 else if (detail && (!strcmp (detail, "vscrollbar")
1527 || !strcmp (detail, "hscrollbar")))
1529 gboolean is_disabled = FALSE;
1531 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1535 gint box_width = width;
1536 gint box_height = height;
1538 reverse_engineer_stepper_box (widget, arrow_type,
1539 &box_x, &box_y, &box_width, &box_height);
1541 if (scrollbar->range.adjustment->page_size >=
1542 (scrollbar->range.adjustment->upper -
1543 scrollbar->range.adjustment->lower))
1548 if (xp_theme_draw (window, to_xp_arrow (arrow_type), style, box_x, box_y,
1549 box_width, box_height, state, area))
1557 btn_type = DFCS_SCROLLUP;
1560 case GTK_ARROW_DOWN:
1561 btn_type = DFCS_SCROLLDOWN;
1564 case GTK_ARROW_LEFT:
1565 btn_type = DFCS_SCROLLLEFT;
1568 case GTK_ARROW_RIGHT:
1569 btn_type = DFCS_SCROLLRIGHT;
1572 case GTK_ARROW_NONE:
1576 if (state == GTK_STATE_INSENSITIVE)
1578 btn_type |= DFCS_INACTIVE;
1583 sanitize_size (window, &width, &height);
1585 dc = get_window_dc (style, window, state,
1586 box_x, box_y, box_width, box_height, &rect);
1587 DrawFrameControl (dc, &rect, DFC_SCROLL,
1588 btn_type | (shadow ==
1589 GTK_SHADOW_IN ? (DFCS_PUSHED |
1591 release_window_dc (style, window, state);
1597 /* draw the toolbar chevrons - waiting for GTK 2.4 */
1598 if (name && !strcmp (name, "gtk-toolbar-arrow"))
1601 (window, XP_THEME_ELEMENT_REBAR_CHEVRON, style, x, y,
1602 width, height, state, area))
1607 /* probably a gtk combo box on a toolbar */
1608 else if (0 /* widget->parent && GTK_IS_BUTTON
1609 (widget->parent) */ )
1612 (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x - 3,
1613 widget->allocation.y + 1, width + 5,
1614 widget->allocation.height - 4, state, area))
1620 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1622 x += (width - 7) / 2;
1623 y += (height - 5) / 2;
1625 draw_varrow (window, style->fg_gc[state], shadow, area,
1626 arrow_type, x, y, 7, 5);
1630 x += (width - 5) / 2;
1631 y += (height - 7) / 2;
1633 draw_harrow (window, style->fg_gc[state], shadow, area,
1634 arrow_type, x, y, 5, 7);
1640 option_menu_get_props (GtkWidget *widget,
1641 GtkRequisition *indicator_size,
1642 GtkBorder *indicator_spacing)
1644 GtkRequisition *tmp_size = NULL;
1645 GtkBorder *tmp_spacing = NULL;
1648 gtk_widget_style_get (widget,
1649 "indicator_size", &tmp_size,
1650 "indicator_spacing", &tmp_spacing, NULL);
1654 *indicator_size = *tmp_size;
1655 gtk_requisition_free (tmp_size);
1659 *indicator_size = default_option_indicator_size;
1664 *indicator_spacing = *tmp_spacing;
1665 gtk_border_free (tmp_spacing);
1669 *indicator_spacing = default_option_indicator_spacing;
1674 is_toolbar_child (GtkWidget *wid)
1678 if (GTK_IS_TOOLBAR (wid) || GTK_IS_HANDLE_BOX (wid))
1688 is_menu_tool_button_child (GtkWidget *wid)
1692 if (GTK_IS_MENU_TOOL_BUTTON (wid))
1701 get_window_dc (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
1702 gint x, gint y, gint width, gint height, RECT *rect)
1705 GdkDrawable *drawable;
1707 if (!GDK_IS_WINDOW (window))
1715 gdk_window_get_internal_paint_info (window, &drawable, &xoff, &yoff);
1718 rect->left = x - xoff;
1719 rect->top = y - yoff;
1720 rect->right = rect->left + width;
1721 rect->bottom = rect->top + height;
1723 return gdk_win32_hdc_get (drawable, style->dark_gc[state_type], 0);
1727 release_window_dc (GtkStyle *style, GdkWindow *window,
1728 GtkStateType state_type)
1730 GdkDrawable *drawable;
1732 if (!GDK_IS_WINDOW (window))
1738 gdk_window_get_internal_paint_info (window, &drawable, NULL, NULL);
1741 gdk_win32_hdc_release (drawable, style->dark_gc[state_type], 0);
1749 g_light_pen = CreatePen (PS_SOLID | PS_INSIDEFRAME, 1,
1750 GetSysColor (COLOR_BTNHIGHLIGHT));
1761 g_dark_pen = CreatePen (PS_SOLID | PS_INSIDEFRAME, 1,
1762 GetSysColor (COLOR_BTNSHADOW));
1769 draw_3d_border (HDC hdc, RECT *rc, gboolean sunken)
1776 pen1 = get_dark_pen ();
1777 pen2 = get_light_pen ();
1781 pen1 = get_light_pen ();
1782 pen2 = get_dark_pen ();
1785 MoveToEx (hdc, rc->left, rc->bottom - 1, NULL);
1787 old_pen = SelectObject (hdc, pen1);
1788 LineTo (hdc, rc->left, rc->top);
1789 LineTo (hdc, rc->right - 1, rc->top);
1790 SelectObject (hdc, old_pen);
1792 old_pen = SelectObject (hdc, pen2);
1793 LineTo (hdc, rc->right - 1, rc->bottom - 1);
1794 LineTo (hdc, rc->left, rc->bottom - 1);
1795 SelectObject (hdc, old_pen);
1799 draw_menu_item (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
1800 gint x, gint y, gint width, gint height,
1801 GtkStateType state_type, GdkRectangle *area)
1808 if ((parent = gtk_widget_get_parent (widget))
1809 && GTK_IS_MENU_BAR (parent) && !xp_theme_is_active ())
1811 bar = GTK_MENU_SHELL (parent);
1813 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
1815 if (state_type == GTK_STATE_PRELIGHT)
1817 draw_3d_border (dc, &rect, bar->active);
1820 release_window_dc (style, window, state_type);
1829 get_dither_brush (void)
1832 HBITMAP pattern_bmp;
1836 return g_dither_brush;
1838 for (i = 0; i < 8; i++)
1840 pattern[i] = (WORD) (0x5555 << (i & 1));
1843 pattern_bmp = CreateBitmap (8, 8, 1, 1, &pattern);
1847 g_dither_brush = CreatePatternBrush (pattern_bmp);
1848 DeleteObject (pattern_bmp);
1851 return g_dither_brush;
1855 draw_tool_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
1856 gint x, gint y, gint width, gint height,
1857 GtkStateType state_type, GdkRectangle *area)
1861 gboolean is_toggled = FALSE;
1863 if (xp_theme_is_active ())
1865 return (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
1866 x, y, width, height, state_type, area));
1869 if (GTK_IS_TOGGLE_BUTTON (widget))
1871 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1877 if (state_type != GTK_STATE_PRELIGHT
1878 && state_type != GTK_STATE_ACTIVE && !is_toggled)
1883 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
1884 if (state_type == GTK_STATE_PRELIGHT)
1888 FillRect (dc, &rect, GetSysColorBrush (COLOR_BTNFACE));
1891 draw_3d_border (dc, &rect, is_toggled);
1893 else if (state_type == GTK_STATE_ACTIVE)
1895 if (is_toggled && !is_menu_tool_button_child (widget->parent))
1897 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
1898 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
1899 FillRect (dc, &rect, get_dither_brush ());
1902 draw_3d_border (dc, &rect, TRUE);
1905 release_window_dc (style, window, state_type);
1911 draw_push_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
1912 gint x, gint y, gint width, gint height,
1913 GtkStateType state_type, gboolean is_default)
1918 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
1920 if (GTK_IS_TOGGLE_BUTTON (widget))
1922 if (state_type == GTK_STATE_PRELIGHT &&
1923 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1925 state_type = GTK_STATE_ACTIVE;
1929 if (state_type == GTK_STATE_ACTIVE)
1931 if (GTK_IS_TOGGLE_BUTTON (widget))
1933 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1934 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
1935 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
1936 FillRect (dc, &rect, get_dither_brush ());
1940 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
1941 InflateRect (&rect, -1, -1);
1942 FrameRect (dc, &rect, GetSysColorBrush (COLOR_BTNSHADOW));
1943 InflateRect (&rect, -1, -1);
1944 FillRect (dc, &rect, GetSysColorBrush (COLOR_BTNFACE));
1949 if (is_default || GTK_WIDGET_HAS_FOCUS (widget))
1951 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
1952 InflateRect (&rect, -1, -1);
1955 DrawFrameControl (dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH);
1958 release_window_dc (style, window, state_type);
1962 draw_box (GtkStyle *style,
1964 GtkStateType state_type,
1965 GtkShadowType shadow_type,
1968 const gchar *detail, gint x, gint y, gint width, gint height)
1970 if (is_combo_box_child (widget) && detail && !strcmp (detail, "button"))
1977 border = (GTK_TOGGLE_BUTTON (widget)->active ? DFCS_PUSHED | DFCS_FLAT : 0);
1979 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
1980 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
1981 release_window_dc (style, window, state_type);
1983 if (xp_theme_is_active ()
1984 && xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x, y,
1985 width, height, state_type, area))
1987 cx = GetSystemMetrics(SM_CXVSCROLL);
1992 dc = get_window_dc (style, window, state_type, x, y, width - cx, height, &rect);
1993 FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
1994 release_window_dc (style, window, state_type);
2000 (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
2002 if (GTK_IS_TREE_VIEW (widget->parent) || GTK_IS_CLIST (widget->parent))
2005 (window, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
2006 width, height, state_type, area))
2014 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2016 DrawFrameControl (dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH |
2018 GTK_STATE_ACTIVE ? (DFCS_PUSHED | DFCS_FLAT)
2020 release_window_dc (style, window, state_type);
2023 else if (is_toolbar_child (widget->parent)
2024 || (!GTK_IS_BUTTON (widget) ||
2025 (GTK_RELIEF_NONE == gtk_button_get_relief (GTK_BUTTON (widget)))))
2027 if (draw_tool_button (window, widget, style, x, y,
2028 width, height, state_type, area))
2035 gboolean is_default = GTK_WIDGET_HAS_DEFAULT (widget);
2038 is_default ? XP_THEME_ELEMENT_DEFAULT_BUTTON :
2039 XP_THEME_ELEMENT_BUTTON, style, x, y, width, height,
2045 draw_push_button (window, widget, style,
2046 x, y, width, height, state_type, is_default);
2053 else if (detail && !strcmp (detail, "spinbutton"))
2055 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
2060 else if (detail && (!strcmp (detail, "spinbutton_up")
2061 || !strcmp (detail, "spinbutton_down")))
2063 if (!xp_theme_draw (window,
2064 (!strcmp (detail, "spinbutton_up"))
2065 ? XP_THEME_ELEMENT_SPIN_BUTTON_UP
2066 : XP_THEME_ELEMENT_SPIN_BUTTON_DOWN,
2067 style, x, y, width, height, state_type, area))
2072 dc = get_window_dc (style, window, state_type,
2073 x, y, width, height, &rect);
2074 DrawEdge (dc, &rect,
2076 GTK_STATE_ACTIVE ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT);
2077 release_window_dc (style, window, state_type);
2081 else if (detail && !strcmp (detail, "slider"))
2083 if (GTK_IS_SCROLLBAR (widget))
2085 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
2086 gboolean is_v = GTK_IS_VSCROLLBAR (widget);
2088 if (xp_theme_draw (window,
2090 ? XP_THEME_ELEMENT_SCROLLBAR_V
2091 : XP_THEME_ELEMENT_SCROLLBAR_H,
2092 style, x, y, width, height, state_type, area))
2094 XpThemeElement gripper =
2095 (is_v ? XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V :
2096 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H);
2098 /* Do not display grippers on tiny scroll bars,
2099 the limit imposed is rather arbitrary, perhaps
2100 we can fetch the gripper geometry from
2101 somewhere and use that... */
2103 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H
2106 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V && height < 16))
2111 xp_theme_draw (window, gripper, style, x, y,
2112 width, height, state_type, area);
2117 if (scrollbar->range.adjustment->page_size >=
2118 (scrollbar->range.adjustment->upper -
2119 scrollbar->range.adjustment->lower))
2126 else if (detail && !strcmp (detail, "bar"))
2128 if (widget && GTK_IS_PROGRESS_BAR (widget))
2130 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2131 XpThemeElement xp_progress_bar =
2132 map_gtk_progress_bar_to_xp (progress_bar, FALSE);
2134 if (xp_theme_draw (window, xp_progress_bar, style, x, y,
2135 width, height, state_type, area))
2140 shadow_type = GTK_SHADOW_NONE;
2143 else if (detail && strcmp (detail, "menuitem") == 0)
2145 shadow_type = GTK_SHADOW_NONE;
2146 if (draw_menu_item (window, widget, style,
2147 x, y, width, height, state_type, area))
2152 else if (detail && !strcmp (detail, "trough"))
2154 if (widget && GTK_IS_PROGRESS_BAR (widget))
2156 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2157 XpThemeElement xp_progress_bar =
2158 map_gtk_progress_bar_to_xp (progress_bar, TRUE);
2160 (window, xp_progress_bar, style, x, y, width, height,
2167 /* Blank in classic Windows */
2170 else if (widget && GTK_IS_SCROLLBAR (widget))
2172 gboolean is_vertical = GTK_IS_VSCROLLBAR (widget);
2174 if (xp_theme_draw (window,
2176 ? XP_THEME_ELEMENT_TROUGH_V
2177 : XP_THEME_ELEMENT_TROUGH_H,
2178 style, x, y, width, height, state_type, area))
2187 sanitize_size (window, &width, &height);
2188 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2190 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
2191 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
2192 FillRect (dc, &rect, get_dither_brush ());
2194 release_window_dc (style, window, state_type);
2199 else if (widget && GTK_IS_SCALE (widget))
2201 gboolean is_vertical = GTK_IS_VSCALE (widget);
2203 if (!xp_theme_is_active ())
2205 parent_class->draw_box (style, window, state_type,
2206 GTK_SHADOW_NONE, area,
2207 widget, detail, x, y, width, height);
2213 (window, XP_THEME_ELEMENT_SCALE_TROUGH_V,
2214 style, (2 * x + width) / 2, y, 2, height,
2220 parent_class->draw_box (style, window, state_type,
2221 GTK_SHADOW_ETCHED_IN,
2223 (2 * x + width) / 2, y, 1, height);
2228 (window, XP_THEME_ELEMENT_SCALE_TROUGH_H,
2229 style, x, (2 * y + height) / 2, width, 2,
2235 parent_class->draw_box (style, window, state_type,
2236 GTK_SHADOW_ETCHED_IN,
2237 area, NULL, NULL, x,
2238 (2 * y + height) / 2, width, 1);
2244 else if (detail && strcmp (detail, "optionmenu") == 0)
2246 if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
2247 style, x, y, width, height, state_type, area))
2253 && (strcmp (detail, "vscrollbar") == 0
2254 || strcmp (detail, "hscrollbar") == 0))
2259 && (strcmp (detail, "handlebox_bin") == 0
2260 || strcmp (detail, "toolbar") == 0
2261 || strcmp (detail, "menubar") == 0))
2263 sanitize_size (window, &width, &height);
2264 if (xp_theme_draw (window, XP_THEME_ELEMENT_REBAR,
2265 style, x, y, width, height, state_type, area))
2270 else if (detail && (!strcmp (detail, "handlebox"))) /* grip */
2272 if (!xp_theme_is_active ())
2277 else if (detail && !strcmp (detail, "notebook") && GTK_IS_NOTEBOOK (widget))
2279 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2281 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2282 x, y, width, height, state_type, area))
2290 const gchar *name = gtk_widget_get_name (widget);
2292 if (name && !strcmp (name, "gtk-tooltips"))
2295 (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
2296 height, state_type, area))
2306 hdc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2308 brush = GetSysColorBrush (COLOR_3DDKSHADOW);
2312 FrameRect (hdc, &rect, brush);
2315 InflateRect (&rect, -1, -1);
2316 FillRect (hdc, &rect, (HBRUSH) (COLOR_INFOBK + 1));
2318 release_window_dc (style, window, state_type);
2325 parent_class->draw_box (style, window, state_type, shadow_type, area,
2326 widget, detail, x, y, width, height);
2328 if (detail && strcmp (detail, "optionmenu") == 0)
2330 GtkRequisition indicator_size;
2331 GtkBorder indicator_spacing;
2334 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2336 sanitize_size (window, &width, &height);
2338 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
2341 x + indicator_size.width + indicator_spacing.left +
2342 indicator_spacing.right;
2346 vline_x = x + width - (indicator_size.width +
2347 indicator_spacing.left +
2348 indicator_spacing.right) - style->xthickness;
2350 parent_class->draw_vline (style, window, state_type, area, widget,
2352 y + style->ythickness + 1,
2353 y + height - style->ythickness - 3, vline_x);
2359 draw_tab (GtkStyle *style,
2362 GtkShadowType shadow,
2365 const gchar *detail, gint x, gint y, gint width, gint height)
2367 GtkRequisition indicator_size;
2368 GtkBorder indicator_spacing;
2372 g_return_if_fail (style != NULL);
2373 g_return_if_fail (window != NULL);
2375 if (detail && !strcmp (detail, "optionmenutab"))
2377 if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
2378 style, x - 5, widget->allocation.y + 1,
2379 width + 10, widget->allocation.height - 2,
2386 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2388 x += (width - indicator_size.width) / 2;
2389 arrow_height = (indicator_size.width + 1) / 2;
2391 y += (height - arrow_height) / 2;
2393 draw_varrow (window, style->black_gc, shadow, area, GTK_ARROW_DOWN,
2394 x, y, indicator_size.width, arrow_height);
2397 /* Draw classic Windows tab - thanks Mozilla!
2398 (no system API for this, but DrawEdge can draw all the parts of a tab) */
2400 DrawTab (HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
2401 gboolean aDrawLeft, gboolean aDrawRight)
2403 gint32 leftFlag, topFlag, rightFlag, lightFlag, shadeFlag;
2404 RECT topRect, sideRect, bottomRect, lightRect, shadeRect;
2405 gint32 selectedOffset, lOffset, rOffset;
2407 selectedOffset = aSelected ? 1 : 0;
2408 lOffset = aDrawLeft ? 2 : 0;
2409 rOffset = aDrawRight ? 2 : 0;
2411 /* Get info for tab orientation/position (Left, Top, Right, Bottom) */
2417 rightFlag = BF_BOTTOM;
2418 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2419 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2421 SetRect (&topRect, R.left, R.top + lOffset, R.right,
2422 R.bottom - rOffset);
2423 SetRect (&sideRect, R.left + 2, R.top, R.right - 2 + selectedOffset,
2425 SetRect (&bottomRect, R.right - 2, R.top, R.right, R.bottom);
2426 SetRect (&lightRect, R.left, R.top, R.left + 3, R.top + 3);
2427 SetRect (&shadeRect, R.left + 1, R.bottom - 2, R.left + 2,
2434 rightFlag = BF_RIGHT;
2435 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2436 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2438 SetRect (&topRect, R.left + lOffset, R.top, R.right - rOffset,
2440 SetRect (&sideRect, R.left, R.top + 2, R.right,
2441 R.bottom - 1 + selectedOffset);
2442 SetRect (&bottomRect, R.left, R.bottom - 1, R.right, R.bottom);
2443 SetRect (&lightRect, R.left, R.top, R.left + 3, R.top + 3);
2444 SetRect (&shadeRect, R.right - 2, R.top + 1, R.right - 1, R.top + 2);
2450 rightFlag = BF_BOTTOM;
2451 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2452 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2454 SetRect (&topRect, R.left, R.top + lOffset, R.right,
2455 R.bottom - rOffset);
2456 SetRect (&sideRect, R.left + 2 - selectedOffset, R.top, R.right - 2,
2458 SetRect (&bottomRect, R.left, R.top, R.left + 2, R.bottom);
2459 SetRect (&lightRect, R.right - 3, R.top, R.right - 1, R.top + 2);
2460 SetRect (&shadeRect, R.right - 2, R.bottom - 3, R.right, R.bottom - 1);
2465 topFlag = BF_BOTTOM;
2466 rightFlag = BF_RIGHT;
2467 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2468 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2470 SetRect (&topRect, R.left + lOffset, R.top, R.right - rOffset,
2472 SetRect (&sideRect, R.left, R.top + 2 - selectedOffset, R.right,
2474 SetRect (&bottomRect, R.left, R.top, R.right, R.top + 2);
2475 SetRect (&lightRect, R.left, R.bottom - 3, R.left + 2, R.bottom - 1);
2476 SetRect (&shadeRect, R.right - 2, R.bottom - 3, R.right, R.bottom - 1);
2480 g_return_if_reached ();
2484 FillRect (hdc, &R, (HBRUSH) (COLOR_3DFACE + 1));
2487 DrawEdge (hdc, &topRect, EDGE_RAISED, BF_SOFT | topFlag);
2491 DrawEdge (hdc, &bottomRect, EDGE_RAISED, BF_SOFT | topFlag);
2499 DrawEdge (hdc, &sideRect, EDGE_RAISED, BF_SOFT | leftFlag | rightFlag);
2501 /* Tab Diagonal Corners */
2503 DrawEdge (hdc, &lightRect, EDGE_RAISED, BF_SOFT | lightFlag);
2506 DrawEdge (hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
2510 draw_themed_tab_button (GtkStyle *style,
2512 GtkStateType state_type,
2513 GtkNotebook *notebook,
2515 gint width, gint height, gint gap_side)
2517 GdkPixmap *pixmap = NULL;
2519 gtk_container_get_border_width (GTK_CONTAINER (notebook));
2520 GtkWidget *widget = GTK_WIDGET (notebook);
2521 GdkRectangle draw_rect, clip_rect;
2522 GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
2524 if (gap_side == GTK_POS_TOP)
2528 if (state_type == GTK_STATE_NORMAL)
2532 draw_rect.width = width + 2;
2533 draw_rect.height = height;
2535 clip_rect = draw_rect;
2540 draw_rect.x = x + 2;
2542 draw_rect.width = width - 2;
2543 draw_rect.height = height - 2;
2544 clip_rect = draw_rect;
2547 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2548 widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
2550 if (draw_rect.x + draw_rect.width >= widget_right)
2552 draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
2555 if (gap_side == GTK_POS_BOTTOM)
2559 if (state_type == GTK_STATE_NORMAL)
2563 draw_rect.width = width + 2;
2564 draw_rect.height = height;
2566 clip_rect = draw_rect;
2570 draw_rect.x = x + 2;
2571 draw_rect.y = y + 2;
2572 draw_rect.width = width - 2;
2573 draw_rect.height = height - 2;
2574 clip_rect = draw_rect;
2577 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2578 widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
2580 if (draw_rect.x + draw_rect.width >= widget_right)
2582 draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
2585 rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
2587 else if (gap_side == GTK_POS_LEFT)
2591 if (state_type == GTK_STATE_NORMAL)
2595 draw_rect.width = width;
2596 draw_rect.height = height + 2;
2598 clip_rect = draw_rect;
2604 draw_rect.y = y + 2;
2605 draw_rect.width = width - 2;
2606 draw_rect.height = height - 2;
2607 clip_rect = draw_rect;
2610 /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
2611 widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
2613 if (draw_rect.y + draw_rect.height >= widget_bottom)
2615 draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
2618 rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
2620 else if (gap_side == GTK_POS_RIGHT)
2624 if (state_type == GTK_STATE_NORMAL)
2626 draw_rect.x = x + 1;
2628 draw_rect.width = width;
2629 draw_rect.height = height + 2;
2631 clip_rect = draw_rect;
2636 draw_rect.x = x + 2;
2637 draw_rect.y = y + 2;
2638 draw_rect.width = width - 2;
2639 draw_rect.height = height - 2;
2640 clip_rect = draw_rect;
2643 /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
2644 widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
2646 if (draw_rect.y + draw_rect.height >= widget_bottom)
2648 draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
2651 rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
2654 if (gap_side == GTK_POS_TOP)
2656 if (!xp_theme_draw (window, XP_THEME_ELEMENT_TAB_ITEM, style,
2657 draw_rect.x, draw_rect.y,
2658 draw_rect.width, draw_rect.height,
2659 state_type, &clip_rect))
2669 if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_RIGHT)
2671 pixmap = gdk_pixmap_new (window, clip_rect.height, clip_rect.width, -1);
2673 if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
2674 draw_rect.y - clip_rect.y, draw_rect.x - clip_rect.x,
2675 draw_rect.height, draw_rect.width, state_type, 0))
2677 g_object_unref (pixmap);
2681 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
2682 clip_rect.height, clip_rect.width);
2683 g_object_unref (pixmap);
2687 pixmap = gdk_pixmap_new (window, clip_rect.width, clip_rect.height, -1);
2689 if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
2690 draw_rect.x - clip_rect.x, draw_rect.y - clip_rect.y,
2691 draw_rect.width, draw_rect.height, state_type, 0))
2693 g_object_unref (pixmap);
2697 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
2698 clip_rect.width, clip_rect.height);
2699 g_object_unref (pixmap);
2702 rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
2703 g_object_unref (pixbuf);
2706 // XXX - This is really hacky and evil. When we're drawing the left-most tab
2707 // while it is active on a bottom-oriented notebook, there is one white
2708 // pixel at the top. There may be a better solution than this if someone
2709 // has time to discover it.
2710 if (gap_side == GTK_POS_BOTTOM && state_type == GTK_STATE_NORMAL
2711 && x == widget->allocation.x)
2713 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
2714 int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
2717 guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
2718 guchar *p = pixels + rowstride;
2720 for (psub = 0; psub < n_channels; psub++)
2722 pixels[psub] = p[psub];
2726 gdk_draw_pixbuf (window, NULL, pixbuf, 0, 0, clip_rect.x, clip_rect.y,
2727 clip_rect.width, clip_rect.height, GDK_RGB_DITHER_NONE,
2729 g_object_unref (pixbuf);
2736 draw_tab_button (GtkStyle *style,
2738 GtkStateType state_type,
2739 GtkShadowType shadow_type,
2742 const gchar *detail,
2743 gint x, gint y, gint width, gint height, gint gap_side)
2745 if (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM)
2747 /* experimental tab-drawing code from mozilla */
2752 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2754 if (gap_side == GTK_POS_TOP)
2756 else if (gap_side == GTK_POS_BOTTOM)
2757 aPosition = BF_BOTTOM;
2758 else if (gap_side == GTK_POS_LEFT)
2759 aPosition = BF_LEFT;
2761 aPosition = BF_RIGHT;
2763 if (state_type == GTK_STATE_PRELIGHT)
2764 state_type = GTK_STATE_NORMAL;
2766 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2768 DrawTab (dc, rect, aPosition,
2769 state_type != GTK_STATE_PRELIGHT,
2770 (gap_side != GTK_POS_LEFT), (gap_side != GTK_POS_RIGHT));
2773 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2775 release_window_dc (style, window, state_type);
2783 draw_extension (GtkStyle *style,
2785 GtkStateType state_type,
2786 GtkShadowType shadow_type,
2789 const gchar *detail,
2791 gint width, gint height, GtkPositionType gap_side)
2793 if (widget && GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "tab"))
2795 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2797 /* Why this differs from gap_side, I have no idea.. */
2798 int real_gap_side = gtk_notebook_get_tab_pos (notebook);
2800 if (!draw_themed_tab_button (style, window, state_type,
2801 GTK_NOTEBOOK (widget), x, y,
2802 width, height, real_gap_side))
2804 if (!draw_tab_button (style, window, state_type,
2805 shadow_type, area, widget,
2806 detail, x, y, width, height, real_gap_side))
2808 parent_class->draw_extension (style, window, state_type,
2809 shadow_type, area, widget, detail,
2810 x, y, width, height,
2818 draw_box_gap (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
2819 GtkShadowType shadow_type, GdkRectangle *area,
2820 GtkWidget *widget, const gchar *detail, gint x,
2821 gint y, gint width, gint height, GtkPositionType gap_side,
2822 gint gap_x, gint gap_width)
2824 if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
2826 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2827 int side = gtk_notebook_get_tab_pos (notebook);
2828 int x2 = x, y2 = y, w2 = width, h2 = height;
2830 if (side == GTK_POS_TOP)
2833 y2 = y - notebook->tab_vborder;
2835 h2 = height + notebook->tab_vborder * 2;
2837 else if (side == GTK_POS_BOTTOM)
2842 h2 = height + notebook->tab_vborder * 2;
2844 else if (side == GTK_POS_LEFT)
2846 x2 = x - notebook->tab_hborder;
2848 w2 = width + notebook->tab_hborder;
2851 else if (side == GTK_POS_RIGHT)
2855 w2 = width + notebook->tab_hborder * 2;
2859 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2860 x2, y2, w2, h2, state_type, area))
2866 parent_class->draw_box_gap (style, window, state_type, shadow_type,
2867 area, widget, detail, x, y, width, height,
2868 gap_side, gap_x, gap_width);
2872 is_popup_window_child (GtkWidget *widget)
2875 GtkWindowType type = -1;
2877 top = gtk_widget_get_toplevel (widget);
2879 if (top && GTK_IS_WINDOW (top))
2881 g_object_get (top, "type", &type, NULL);
2883 if (type == GTK_WINDOW_POPUP)
2884 { /* Hack for combo boxes */
2893 draw_flat_box (GtkStyle *style, GdkWindow *window,
2894 GtkStateType state_type, GtkShadowType shadow_type,
2895 GdkRectangle *area, GtkWidget *widget,
2896 const gchar *detail, gint x, gint y, gint width, gint height)
2900 if (!strcmp (detail, "checkbutton"))
2902 if (state_type == GTK_STATE_PRELIGHT)
2909 parent_class->draw_flat_box (style, window, state_type, shadow_type,
2910 area, widget, detail, x, y, width, height);
2914 draw_menu_border (GdkWindow *win, GtkStyle *style,
2915 gint x, gint y, gint width, gint height)
2920 dc = get_window_dc (style, win, GTK_STATE_NORMAL, x, y, width, height, &rect);
2925 if (xp_theme_is_active ())
2927 FrameRect (dc, &rect, GetSysColorBrush (COLOR_3DSHADOW));
2931 DrawEdge (dc, &rect, EDGE_RAISED, BF_RECT);
2934 release_window_dc (style, win, GTK_STATE_NORMAL);
2940 draw_shadow (GtkStyle *style,
2942 GtkStateType state_type,
2943 GtkShadowType shadow_type,
2946 const gchar *detail, gint x, gint y, gint width, gint height)
2948 gboolean is_handlebox;
2949 gboolean is_toolbar;
2951 if (detail && !strcmp (detail, "frame"))
2959 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2960 if (is_combo_box_child (widget))
2962 FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
2964 else if (is_popup_window_child (widget))
2966 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
2970 switch (shadow_type)
2973 draw_3d_border (dc, &rect, TRUE);
2976 case GTK_SHADOW_OUT:
2977 draw_3d_border (dc, &rect, FALSE);
2980 case GTK_SHADOW_ETCHED_IN:
2981 draw_3d_border (dc, &rect, TRUE);
2982 InflateRect (&rect, -1, -1);
2983 draw_3d_border (dc, &rect, FALSE);
2986 case GTK_SHADOW_ETCHED_OUT:
2987 draw_3d_border (dc, &rect, FALSE);
2988 InflateRect (&rect, -1, -1);
2989 draw_3d_border (dc, &rect, TRUE);
2992 case GTK_SHADOW_NONE:
2997 release_window_dc (style, window, state_type);
3001 if (detail && (!strcmp (detail, "entry") || !strcmp (detail, "combobox")))
3003 if (shadow_type != GTK_SHADOW_IN)
3006 if (!xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
3007 x, y, width, height, state_type, area))
3012 dc = get_window_dc (style, window, state_type,
3013 x, y, width, height, &rect);
3015 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
3016 release_window_dc (style, window, state_type);
3022 if (detail && !strcmp (detail, "scrolled_window") &&
3023 xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
3024 x, y, width, height, state_type, area))
3029 if (detail && !strcmp (detail, "spinbutton"))
3032 if (detail && !strcmp (detail, "menu"))
3034 if (draw_menu_border (window, style, x, y, width, height))
3040 if (detail && !strcmp (detail, "handlebox"))
3043 is_handlebox = (detail && !strcmp (detail, "handlebox_bin"));
3044 is_toolbar = (detail
3045 && (!strcmp (detail, "toolbar")
3046 || !strcmp (detail, "menubar")));
3048 if (is_toolbar || is_handlebox)
3050 if (shadow_type == GTK_SHADOW_NONE)
3059 HGDIOBJ old_pen = NULL;
3060 GtkPositionType pos;
3062 sanitize_size (window, &width, &height);
3066 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (widget));
3068 If the handle box is at left side,
3069 we shouldn't draw its right border.
3070 The same holds true for top, right, and bottom.
3075 pos = GTK_POS_RIGHT;
3083 pos = GTK_POS_BOTTOM;
3086 case GTK_POS_BOTTOM:
3093 GtkWidget *parent = gtk_widget_get_parent (widget);
3095 /* Dirty hack for toolbars contained in handle boxes */
3096 if (GTK_IS_HANDLE_BOX (parent))
3098 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (parent));
3104 Make pos != all legal enum vaules of GtkPositionType.
3105 So every border will be draw.
3107 pos = (GtkPositionType) - 1;
3111 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
3113 if (pos != GTK_POS_LEFT)
3115 old_pen = SelectObject (dc, get_light_pen ());
3116 MoveToEx (dc, rect.left, rect.top, NULL);
3117 LineTo (dc, rect.left, rect.bottom);
3119 if (pos != GTK_POS_TOP)
3121 old_pen = SelectObject (dc, get_light_pen ());
3122 MoveToEx (dc, rect.left, rect.top, NULL);
3123 LineTo (dc, rect.right, rect.top);
3125 if (pos != GTK_POS_RIGHT)
3127 old_pen = SelectObject (dc, get_dark_pen ());
3128 MoveToEx (dc, rect.right - 1, rect.top, NULL);
3129 LineTo (dc, rect.right - 1, rect.bottom);
3131 if (pos != GTK_POS_BOTTOM)
3133 old_pen = SelectObject (dc, get_dark_pen ());
3134 MoveToEx (dc, rect.left, rect.bottom - 1, NULL);
3135 LineTo (dc, rect.right, rect.bottom - 1);
3138 SelectObject (dc, old_pen);
3139 release_window_dc (style, window, state_type);
3145 if (detail && !strcmp (detail, "statusbar"))
3150 parent_class->draw_shadow (style, window, state_type, shadow_type, area,
3151 widget, detail, x, y, width, height);
3155 draw_hline (GtkStyle *style,
3157 GtkStateType state_type,
3160 const gchar *detail, gint x1, gint x2, gint y)
3162 if (xp_theme_is_active () && detail && !strcmp (detail, "menuitem"))
3165 (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, y, x2, 1,
3174 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3177 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
3181 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3187 if (style->ythickness == 2)
3191 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3192 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3195 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
3197 gdk_draw_line (window, style->light_gc[state_type], x1, y, x2, y);
3201 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3202 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3207 parent_class->draw_hline (style, window, state_type, area, widget,
3214 draw_vline (GtkStyle *style,
3216 GtkStateType state_type,
3219 const gchar *detail, gint y1, gint y2, gint x)
3221 if (style->xthickness == 2)
3225 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3226 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3229 gdk_draw_line (window, style->dark_gc[state_type], x, y1, x, y2);
3231 gdk_draw_line (window, style->light_gc[state_type], x, y1, x, y2);
3235 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3236 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3241 parent_class->draw_vline (style, window, state_type, area, widget,
3247 draw_slider (GtkStyle *style,
3249 GtkStateType state_type,
3250 GtkShadowType shadow_type,
3253 const gchar *detail,
3255 gint y, gint width, gint height, GtkOrientation orientation)
3257 if (GTK_IS_SCALE (widget) &&
3258 xp_theme_draw (window, ((orientation == GTK_ORIENTATION_VERTICAL) ?
3259 XP_THEME_ELEMENT_SCALE_SLIDER_V :
3260 XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
3261 height, state_type, area))
3266 parent_class->draw_slider (style, window, state_type, shadow_type, area,
3267 widget, detail, x, y, width, height,
3272 draw_resize_grip (GtkStyle *style,
3274 GtkStateType state_type,
3277 const gchar *detail,
3278 GdkWindowEdge edge, gint x, gint y, gint width, gint height)
3280 if (detail && !strcmp (detail, "statusbar"))
3283 (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
3284 height, state_type, area))
3291 HDC dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
3294 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3296 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
3297 release_window_dc (style, window, state_type);
3300 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3306 parent_class->draw_resize_grip (style, window, state_type, area,
3307 widget, detail, edge, x, y, width, height);
3311 draw_handle (GtkStyle *style,
3313 GtkStateType state_type,
3314 GtkShadowType shadow_type,
3317 const gchar *detail,
3319 gint y, gint width, gint height, GtkOrientation orientation)
3324 if (is_toolbar_child (widget))
3326 XpThemeElement hndl;
3328 sanitize_size (window, &width, &height);
3330 if (GTK_IS_HANDLE_BOX (widget))
3332 GtkPositionType pos;
3333 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (widget));
3335 if (pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM)
3337 orientation = GTK_ORIENTATION_HORIZONTAL;
3341 orientation = GTK_ORIENTATION_VERTICAL;
3345 if (orientation == GTK_ORIENTATION_VERTICAL)
3346 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_V;
3348 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
3350 if (xp_theme_draw (window, hndl, style, x, y, width, height,
3356 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
3358 if (orientation == GTK_ORIENTATION_VERTICAL)
3361 rect.right = rect.left + 3;
3368 rect.bottom = rect.top + 3;
3373 draw_3d_border (dc, &rect, FALSE);
3374 release_window_dc (style, window, state_type);
3378 if (!GTK_IS_PANED (widget))
3380 gint xthick, ythick;
3381 GdkGC *light_gc, *dark_gc, *shadow_gc;
3384 sanitize_size (window, &width, &height);
3386 gtk_paint_box (style, window, state_type, shadow_type, area,
3387 widget, detail, x, y, width, height);
3389 light_gc = style->light_gc[state_type];
3390 dark_gc = style->dark_gc[state_type];
3391 shadow_gc = style->mid_gc[state_type];
3393 xthick = style->xthickness;
3394 ythick = style->ythickness;
3396 dest.x = x + xthick;
3397 dest.y = y + ythick;
3398 dest.width = width - (xthick * 2);
3399 dest.height = height - (ythick * 2);
3401 if (dest.width < dest.height)
3406 gdk_gc_set_clip_rectangle (light_gc, &dest);
3407 gdk_gc_set_clip_rectangle (dark_gc, &dest);
3408 gdk_gc_set_clip_rectangle (shadow_gc, &dest);
3410 if (dest.width < dest.height)
3412 gdk_draw_line (window, light_gc, dest.x, dest.y, dest.x,
3414 gdk_draw_line (window, dark_gc, dest.x + (dest.width / 2),
3415 dest.y, dest.x + (dest.width / 2), dest.height);
3416 gdk_draw_line (window, shadow_gc, dest.x + dest.width,
3417 dest.y, dest.x + dest.width, dest.height);
3421 gdk_draw_line (window, light_gc, dest.x, dest.y,
3422 dest.x + dest.width, dest.y);
3423 gdk_draw_line (window, dark_gc, dest.x,
3424 dest.y + (dest.height / 2),
3425 dest.x + dest.width, dest.y + (dest.height / 2));
3426 gdk_draw_line (window, shadow_gc, dest.x,
3427 dest.y + dest.height, dest.x + dest.width,
3428 dest.y + dest.height);
3431 gdk_gc_set_clip_rectangle (shadow_gc, NULL);
3432 gdk_gc_set_clip_rectangle (light_gc, NULL);
3433 gdk_gc_set_clip_rectangle (dark_gc, NULL);
3438 draw_focus (GtkStyle *style,
3440 GtkStateType state_type,
3443 const gchar *detail, gint x, gint y, gint width, gint height)
3448 if (!GTK_WIDGET_CAN_FOCUS (widget))
3453 if (is_combo_box_child (widget)
3454 && (GTK_IS_ARROW (widget) || GTK_IS_BUTTON (widget)))
3458 if (GTK_IS_TREE_VIEW (widget->parent) /* list view bheader */
3459 || GTK_IS_CLIST (widget->parent))
3464 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
3465 DrawFocusRect (dc, &rect);
3466 release_window_dc (style, window, state_type);
3468 parent_class->draw_focus (style, window, state_type,
3469 area, widget, detail, x, y, width, height);
3474 draw_layout (GtkStyle *style,
3476 GtkStateType state_type,
3480 const gchar *detail,
3481 gint old_x, gint old_y, PangoLayout *layout)
3483 GtkNotebook *notebook = NULL;
3487 /* In the XP theme, labels don't appear correctly centered inside
3488 * notebook tabs, so we give them a gentle nudge two pixels to the
3489 * right. A little hackish, but what are 'ya gonna do? -- Cody
3491 if (xp_theme_is_active () && detail && !strcmp (detail, "label"))
3493 if (widget->parent != NULL)
3495 if (GTK_IS_NOTEBOOK (widget->parent))
3497 notebook = GTK_NOTEBOOK (widget->parent);
3498 int side = gtk_notebook_get_tab_pos (notebook);
3500 if (side == GTK_POS_TOP || side == GTK_POS_BOTTOM)
3508 parent_class->draw_layout (style, window, state_type,
3509 use_text, area, widget, detail, x, y, layout);
3513 msw_style_init_from_rc (GtkStyle *style, GtkRcStyle *rc_style)
3515 setup_system_font (style);
3516 setup_menu_settings (gtk_settings_get_default ());
3517 setup_system_styles (style);
3518 parent_class->init_from_rc (style, rc_style);
3522 load_bg_image (GdkColormap *colormap,
3523 GdkColor *bg_color, const gchar *filename)
3525 if (strcmp (filename, "<parent>") == 0)
3527 return (GdkPixmap *) GDK_PARENT_RELATIVE;
3531 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
3532 bg_color, filename);
3537 msw_style_realize (GtkStyle *style)
3539 GdkGCValues gc_values;
3540 GdkGCValuesMask gc_values_mask;
3544 for (i = 0; i < 5; i++)
3546 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
3547 style->mid[i].green =
3548 (style->light[i].green + style->dark[i].green) / 2;
3549 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
3551 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
3552 style->text_aa[i].green =
3553 (style->text[i].green + style->base[i].green) / 2;
3554 style->text_aa[i].blue =
3555 (style->text[i].blue + style->base[i].blue) / 2;
3558 style->black.red = 0x0000;
3559 style->black.green = 0x0000;
3560 style->black.blue = 0x0000;
3561 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
3563 style->white.red = 0xffff;
3564 style->white.green = 0xffff;
3565 style->white.blue = 0xffff;
3566 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
3568 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
3570 gc_values.foreground = style->black;
3571 gc_values.background = style->white;
3573 gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3575 gc_values.foreground = style->white;
3576 gc_values.background = style->black;
3578 gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3580 gc_values_mask = GDK_GC_FOREGROUND;
3582 for (i = 0; i < 5; i++)
3584 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
3586 style->bg_pixmap[i] = load_bg_image (style->colormap,
3592 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
3594 g_warning ("unable to allocate color: ( %d %d %d )", style->fg[i].red,
3595 style->fg[i].green, style->fg[i].blue);
3598 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
3600 g_warning ("unable to allocate color: ( %d %d %d )", style->bg[i].red,
3601 style->bg[i].green, style->bg[i].blue);
3604 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
3606 g_warning ("unable to allocate color: ( %d %d %d )",
3607 style->light[i].red, style->light[i].green,
3608 style->light[i].blue);
3611 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
3613 g_warning ("unable to allocate color: ( %d %d %d )",
3614 style->dark[i].red, style->dark[i].green,
3615 style->dark[i].blue);
3618 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
3620 g_warning ("unable to allocate color: ( %d %d %d )",
3621 style->mid[i].red, style->mid[i].green,
3622 style->mid[i].blue);
3625 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
3627 g_warning ("unable to allocate color: ( %d %d %d )",
3628 style->text[i].red, style->text[i].green,
3629 style->text[i].blue);
3632 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
3634 g_warning ("unable to allocate color: ( %d %d %d )",
3635 style->base[i].red, style->base[i].green,
3636 style->base[i].blue);
3639 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
3641 g_warning ("unable to allocate color: ( %d %d %d )",
3642 style->text_aa[i].red, style->text_aa[i].green,
3643 style->text_aa[i].blue);
3646 gc_values.foreground = style->fg[i];
3647 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3649 gc_values.foreground = style->bg[i];
3650 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3652 gc_values.foreground = style->light[i];
3653 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3655 gc_values.foreground = style->dark[i];
3656 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3658 gc_values.foreground = style->mid[i];
3659 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3661 gc_values.foreground = style->text[i];
3662 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3664 gc_values.foreground = style->base[i];
3665 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3667 gc_values.foreground = style->text_aa[i];
3668 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3673 msw_style_unrealize (GtkStyle *style)
3675 parent_class->unrealize (style);
3679 msw_style_class_init (MswStyleClass *klass)
3681 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3683 parent_class = g_type_class_peek_parent (klass);
3685 style_class->init_from_rc = msw_style_init_from_rc;
3686 style_class->draw_arrow = draw_arrow;
3687 style_class->draw_box = draw_box;
3688 style_class->draw_check = draw_check;
3689 style_class->draw_option = draw_option;
3690 style_class->draw_tab = draw_tab;
3691 style_class->draw_flat_box = draw_flat_box;
3692 style_class->draw_expander = draw_expander;
3693 style_class->draw_extension = draw_extension;
3694 style_class->draw_box_gap = draw_box_gap;
3695 style_class->draw_shadow = draw_shadow;
3696 style_class->draw_hline = draw_hline;
3697 style_class->draw_vline = draw_vline;
3698 style_class->draw_handle = draw_handle;
3699 style_class->draw_resize_grip = draw_resize_grip;
3700 style_class->draw_slider = draw_slider;
3701 style_class->draw_focus = draw_focus;
3702 style_class->draw_layout = draw_layout;
3704 style_class->realize = msw_style_realize;
3705 style_class->unrealize = msw_style_unrealize;
3708 GType msw_type_style = 0;
3711 msw_style_register_type (GTypeModule *module)
3713 static const GTypeInfo object_info = {
3714 sizeof (MswStyleClass),
3715 (GBaseInitFunc) NULL,
3716 (GBaseFinalizeFunc) NULL,
3717 (GClassInitFunc) msw_style_class_init,
3718 NULL, /* class_finalize */
3719 NULL, /* class_data */
3721 0, /* n_preallocs */
3722 (GInstanceInitFunc) NULL,
3725 msw_type_style = g_type_module_register_type (module,
3727 "MswStyle", &object_info, 0);
3731 msw_style_init (void)
3734 msw_style_setup_system_settings ();
3735 setup_msw_rc_style ();
3739 DeleteObject (g_light_pen);
3745 DeleteObject (g_dark_pen);
3751 msw_style_finalize (void)
3755 DeleteObject (g_dither_brush);
3760 DeleteObject (g_light_pen);
3765 DeleteObject (g_dark_pen);