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"
44 #ifdef BUILDING_STANDALONE
45 #include "gdk/gdkwin32.h"
47 #include "gdk/win32/gdkwin32.h"
50 static HDC get_window_dc (GtkStyle *style, GdkWindow *window,
51 GtkStateType state_type, gint x, gint y, gint width,
52 gint height, RECT *rect);
53 static void release_window_dc (GtkStyle *style, GdkWindow *window,
54 GtkStateType state_type);
57 /* Default values, not normally used
59 static const GtkRequisition default_option_indicator_size = { 9, 8 };
60 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
62 static GtkStyleClass *parent_class;
63 static HBRUSH g_dither_brush = NULL;
65 static HPEN g_light_pen = NULL;
66 static HPEN g_dark_pen = NULL;
88 static const guint8 check_aa_bits[] = {
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
93 static const guint8 check_base_bits[] = {
94 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07,
96 0x07, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00
98 static const guint8 check_black_bits[] = {
99 0x00, 0x00, 0xfe, 0x0f, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
101 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00
103 static const guint8 check_dark_bits[] = {
104 0xff, 0x1f, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
106 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00
108 static const guint8 check_light_bits[] = {
109 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
111 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0xfe, 0x1f
113 static const guint8 check_mid_bits[] = {
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08,
116 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xfc, 0x0f, 0x00, 0x00
118 static const guint8 check_text_bits[] = {
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x88, 0x03,
121 0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
123 static const char check_inconsistent_bits[] = {
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
128 static const guint8 radio_base_bits[] = {
129 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xf8, 0x03, 0xfc, 0x07, 0xfc, 0x07,
131 0x07, 0xfc, 0x07, 0xf8, 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00
133 static const guint8 radio_black_bits[] = {
134 0x00, 0x00, 0xf0, 0x01, 0x0c, 0x02, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00,
136 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
138 static const guint8 radio_dark_bits[] = {
139 0xf0, 0x01, 0x0c, 0x06, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00,
141 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
143 static const guint8 radio_light_bits[] = {
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10,
146 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x0c, 0x06, 0xf0, 0x01
148 static const guint8 radio_mid_bits[] = {
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08,
151 0x08, 0x00, 0x08, 0x00, 0x04, 0x0c, 0x06, 0xf0, 0x01, 0x00, 0x00
153 static const guint8 radio_text_bits[] = {
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf0, 0x01,
156 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
164 { check_aa_bits, NULL },
165 { check_base_bits, NULL },
166 { check_black_bits, NULL },
167 { check_dark_bits, NULL },
168 { check_light_bits, NULL },
169 { check_mid_bits, NULL },
170 { check_text_bits, NULL },
171 { check_inconsistent_bits, NULL },
172 { radio_base_bits, NULL },
173 { radio_black_bits, NULL },
174 { radio_dark_bits, NULL },
175 { radio_light_bits, NULL },
176 { radio_mid_bits, NULL },
177 { radio_text_bits, NULL }
181 get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONT *out_lf)
184 /* TODO: this causes crashes later because the font name is in UCS2, and
185 the pango fns don't deal with that gracefully */
186 if (xp_theme_get_system_font (klazz, type, out_lf))
193 NONCLIENTMETRICS ncm;
195 ncm.cbSize = sizeof (NONCLIENTMETRICS);
197 if (SystemParametersInfo (SPI_GETNONCLIENTMETRICS,
198 sizeof (NONCLIENTMETRICS), &ncm, 0))
200 if (type == XP_THEME_FONT_CAPTION)
201 *out_lf = ncm.lfCaptionFont;
202 else if (type == XP_THEME_FONT_MENU)
203 *out_lf = ncm.lfMenuFont;
204 else if (type == XP_THEME_FONT_STATUS)
205 *out_lf = ncm.lfStatusFont;
207 *out_lf = ncm.lfMessageFont;
216 /***************************** BEGIN STOLEN FROM PANGO *****************************/
219 This code is stolen from Pango 1.4. It attempts to address the following problems:
221 http://bugzilla.gnome.org/show_bug.cgi?id=135098
222 http://sourceforge.net/tracker/index.php?func=detail&aid=895762&group_id=76416&atid=547655
224 As Owen suggested in bug 135098, once Pango 1.6 is released, we need to get rid of this code.
227 #define PING(printlist)
229 /* TrueType defines: */
231 #define MAKE_TT_TABLE_NAME(c1, c2, c3, c4) \
232 (((guint32)c4) << 24 | ((guint32)c3) << 16 | ((guint32)c2) << 8 | ((guint32)c1))
234 #define CMAP (MAKE_TT_TABLE_NAME('c','m','a','p'))
235 #define CMAP_HEADER_SIZE 4
237 #define NAME (MAKE_TT_TABLE_NAME('n','a','m','e'))
238 #define NAME_HEADER_SIZE 6
240 #define ENCODING_TABLE_SIZE 8
242 #define APPLE_UNICODE_PLATFORM_ID 0
243 #define MACINTOSH_PLATFORM_ID 1
244 #define ISO_PLATFORM_ID 2
245 #define MICROSOFT_PLATFORM_ID 3
247 #define SYMBOL_ENCODING_ID 0
248 #define UNICODE_ENCODING_ID 1
249 #define UCS4_ENCODING_ID 10
253 guint16 format_selector;
255 guint16 string_storage_offset;
264 guint16 string_length;
265 guint16 string_offset;
269 pango_win32_get_name_header (HDC hdc, struct name_header *header)
271 if (GetFontData (hdc, NAME, 0, header, sizeof (*header)) != sizeof (*header))
274 header->num_records = GUINT16_FROM_BE (header->num_records);
275 header->string_storage_offset = GUINT16_FROM_BE (header->string_storage_offset);
281 pango_win32_get_name_record (HDC hdc, gint i, struct name_record *record)
283 if (GetFontData (hdc, NAME, 6 + i * sizeof (*record),
284 record, sizeof (*record)) != sizeof (*record))
289 record->platform_id = GUINT16_FROM_BE (record->platform_id);
290 record->encoding_id = GUINT16_FROM_BE (record->encoding_id);
291 record->language_id = GUINT16_FROM_BE (record->language_id);
292 record->name_id = GUINT16_FROM_BE (record->name_id);
293 record->string_length = GUINT16_FROM_BE (record->string_length);
294 record->string_offset = GUINT16_FROM_BE (record->string_offset);
300 get_family_name (LOGFONT *lfp, HDC pango_win32_hdc)
305 struct name_header header;
306 struct name_record record;
308 gint unicode_ix = -1, mac_ix = -1, microsoft_ix = -1;
312 gchar *string = NULL;
317 /* If lfFaceName is ASCII, assume it is the common (English) name for the
318 font. Is this valid? Do some TrueType fonts have different names in
319 French, German, etc, and does the system return these if the locale is
320 set to use French, German, etc? */
321 l = strlen (lfp->lfFaceName);
322 for (i = 0; i < l; i++)
324 if (lfp->lfFaceName[i] < ' ' || lfp->lfFaceName[i] > '~')
331 return g_strdup (lfp->lfFaceName);
333 if ((hfont = CreateFontIndirect (lfp)) == NULL)
336 if ((oldhfont = (HFONT) SelectObject (pango_win32_hdc, hfont)) == NULL)
339 if (!pango_win32_get_name_header (pango_win32_hdc, &header))
342 PING (("%d name records", header.num_records));
344 for (i = 0; i < header.num_records; i++)
346 if (!pango_win32_get_name_record (pango_win32_hdc, i, &record))
349 if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0)
352 PING (("platform:%d encoding:%d language:%04x name_id:%d",
353 record.platform_id, record.encoding_id, record.language_id,
356 if (record.platform_id == APPLE_UNICODE_PLATFORM_ID ||
357 record.platform_id == ISO_PLATFORM_ID)
361 else if (record.platform_id == MACINTOSH_PLATFORM_ID && record.encoding_id == 0 && /* Roman
363 record.language_id == 0) /* English */
367 else if (record.platform_id == MICROSOFT_PLATFORM_ID)
369 if ((microsoft_ix == -1 ||
370 PRIMARYLANGID (record.language_id) == LANG_ENGLISH) &&
371 (record.encoding_id == SYMBOL_ENCODING_ID ||
372 record.encoding_id == UNICODE_ENCODING_ID ||
373 record.encoding_id == UCS4_ENCODING_ID))
380 if (microsoft_ix >= 0)
381 name_ix = microsoft_ix;
382 else if (mac_ix >= 0)
384 else if (unicode_ix >= 0)
385 name_ix = unicode_ix;
389 if (!pango_win32_get_name_record (pango_win32_hdc, name_ix, &record))
392 string = g_malloc (record.string_length + 1);
393 if (GetFontData (pango_win32_hdc, NAME,
394 header.string_storage_offset + record.string_offset,
395 string, record.string_length) != record.string_length)
398 string[record.string_length] = '\0';
400 if (name_ix == microsoft_ix)
402 if (record.encoding_id == SYMBOL_ENCODING_ID ||
403 record.encoding_id == UNICODE_ENCODING_ID)
405 codeset = "UTF-16BE";
412 else if (name_ix == mac_ix)
414 codeset = "MacRoman";
416 else /* name_ix == unicode_ix */
422 name = g_convert (string, record.string_length, "UTF-8", codeset, NULL,
431 SelectObject (pango_win32_hdc, oldhfont);
432 DeleteObject (hfont);
438 SelectObject (pango_win32_hdc, oldhfont);
441 DeleteObject (hfont);
444 return g_locale_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
447 /***************************** END STOLEN FROM PANGO *****************************/
450 sys_font_to_pango_font (XpThemeClass klazz, XpThemeFont type, char *buf,
461 if (get_system_font (klazz, type, &lf))
467 weight = "Ultra-Light";
479 weight = "Semi-Bold";
483 weight = "Ultra-Bold";
500 hwnd = GetDesktopWindow ();
504 pt_size = -MulDiv (lf.lfHeight, 72,
505 GetDeviceCaps (hDC, LOGPIXELSY));
512 font = get_family_name (&lf, hDC);
515 ReleaseDC (hwnd, hDC);
517 if (!(font && *font))
520 g_snprintf (buf, bufsiz, "%s %s %s %d", font, style, weight, pt_size);
529 /* missing from ms's header files */
530 #ifndef SPI_GETMENUSHOWDELAY
531 #define SPI_GETMENUSHOWDELAY 106
534 /* I don't know the proper XP theme class for things like
535 HIGHLIGHTTEXT, so we'll just define it to be "BUTTON"
537 #define XP_THEME_CLASS_TEXT XP_THEME_CLASS_BUTTON
540 setup_menu_settings (GtkSettings *settings)
543 gboolean win95 = FALSE;
544 OSVERSIONINFOEX osvi;
545 GObjectClass *klazz = G_OBJECT_GET_CLASS (G_OBJECT (settings));
547 ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
548 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
550 if (!GetVersionEx ((OSVERSIONINFO *) & osvi))
551 win95 = TRUE; /* assume the worst */
553 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
555 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
563 if (SystemParametersInfo (SPI_GETMENUSHOWDELAY, 0, &menu_delay, 0))
567 if (g_object_class_find_property
568 (klazz, "gtk-menu-bar-popup-delay"))
570 g_object_set (settings,
571 "gtk-menu-bar-popup-delay", 0, NULL);
573 if (g_object_class_find_property
574 (klazz, "gtk-menu-popup-delay"))
576 g_object_set (settings,
577 "gtk-menu-popup-delay", menu_delay, NULL);
579 if (g_object_class_find_property
580 (klazz, "gtk-menu-popdown-delay"))
582 g_object_set (settings,
583 "gtk-menu-popdown-delay", menu_delay, NULL);
591 msw_style_setup_system_settings (void)
593 GtkSettings *settings;
594 int cursor_blink_time;
596 settings = gtk_settings_get_default ();
600 cursor_blink_time = GetCaretBlinkTime ();
601 g_object_set (settings, "gtk-cursor-blink", cursor_blink_time > 0, NULL);
603 if (cursor_blink_time > 0)
605 g_object_set (settings, "gtk-cursor-blink-time",
606 2 * cursor_blink_time, NULL);
609 g_object_set (settings, "gtk-double-click-distance",
610 GetSystemMetrics (SM_CXDOUBLECLK), NULL);
611 g_object_set (settings, "gtk-double-click-time", GetDoubleClickTime (),
613 g_object_set (settings, "gtk-dnd-drag-threshold",
614 GetSystemMetrics (SM_CXDRAG), NULL);
616 setup_menu_settings (settings);
619 http://developer.gnome.org/doc/API/2.0/gtk/GtkSettings.html
620 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/systemparametersinfo.asp
621 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getsystemmetrics.asp */
625 setup_system_font (GtkStyle *style)
627 char buf[256], *font; /* It's okay, lfFaceName is smaller than 32
630 if ((font = sys_font_to_pango_font (XP_THEME_CLASS_TEXT,
631 XP_THEME_FONT_MESSAGE,
632 buf, sizeof (buf))) != NULL)
634 if (style->font_desc)
636 pango_font_description_free (style->font_desc);
639 style->font_desc = pango_font_description_from_string (font);
644 sys_color_to_gtk_color (XpThemeClass klazz, int id, GdkColor * pcolor)
648 if (!xp_theme_get_system_color (klazz, id, &color))
649 color = GetSysColor (id);
651 pcolor->pixel = color;
652 pcolor->red = (GetRValue (color) << 8) | GetRValue (color);
653 pcolor->green = (GetGValue (color) << 8) | GetGValue (color);
654 pcolor->blue = (GetBValue (color) << 8) | GetBValue (color);
658 get_system_metric (XpThemeClass klazz, int id)
662 if (!xp_theme_get_system_metric (klazz, id, &rval))
663 rval = GetSystemMetrics (id);
669 setup_msw_rc_style (void)
671 char buf[1024], font_buf[256], *font_ptr;
672 char menu_bar_prelight_str[128];
675 GdkColor menu_text_color;
676 GdkColor tooltip_back;
677 GdkColor tooltip_fore;
680 GdkColor progress_back;
682 GdkColor fg_prelight;
683 GdkColor bg_prelight;
684 GdkColor base_prelight;
685 GdkColor text_prelight;
688 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
690 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT, &bg_prelight);
691 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
693 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
696 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENUTEXT,
698 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENU, &menu_color);
701 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOTEXT,
703 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOBK,
706 /* text on push buttons. TODO: button shadows, backgrounds, and
708 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT, &btn_fore);
709 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE, &btn_face);
711 /* progress bar background color */
712 sys_color_to_gtk_color (XP_THEME_CLASS_PROGRESS, COLOR_HIGHLIGHT,
715 /* Enable coloring for menus. */
717 sys_font_to_pango_font (XP_THEME_CLASS_MENU, XP_THEME_FONT_MENU,
718 font_buf, sizeof (font_buf));
719 g_snprintf (buf, sizeof (buf),
720 "style \"msw-menu\" = \"msw-default\"\n" "{\n"
721 "GtkMenuItem::toggle-spacing = 8\n"
722 "fg[PRELIGHT] = { %d, %d, %d }\n"
723 "bg[PRELIGHT] = { %d, %d, %d }\n"
724 "text[PRELIGHT] = { %d, %d, %d }\n"
725 "base[PRELIGHT] = { %d, %d, %d }\n"
726 "fg[NORMAL] = { %d, %d, %d }\n"
727 "bg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
728 "}widget_class \"*MenuItem*\" style \"msw-menu\"\n"
729 "widget_class \"*GtkMenu\" style \"msw-menu\"\n"
730 "widget_class \"*GtkMenuShell*\" style \"msw-menu\"\n",
731 fg_prelight.red, fg_prelight.green, fg_prelight.blue,
732 bg_prelight.red, bg_prelight.green, bg_prelight.blue,
733 text_prelight.red, text_prelight.green, text_prelight.blue,
734 base_prelight.red, base_prelight.green, base_prelight.blue,
735 menu_text_color.red, menu_text_color.green,
736 menu_text_color.blue, menu_color.red, menu_color.green,
737 menu_color.blue, (font_ptr ? "font_name" : "#"),
738 (font_ptr ? font_ptr : " font name should go here"));
739 gtk_rc_parse_string (buf);
741 if (xp_theme_is_active ())
743 *menu_bar_prelight_str = '\0';
747 g_snprintf (menu_bar_prelight_str, sizeof (menu_bar_prelight_str),
748 "fg[PRELIGHT] = { %d, %d, %d }\n",
749 menu_text_color.red, menu_text_color.green,
750 menu_text_color.blue);
753 /* Enable coloring for menu bars. */
754 g_snprintf (buf, sizeof (buf),
755 "style \"msw-menu-bar\" = \"msw-menu\"\n"
757 "bg[NORMAL] = { %d, %d, %d }\n"
758 "%s" "GtkMenuBar::shadow-type = %d\n"
760 FIXME: This should be enabled once gtk+ support
761 GtkMenuBar::prelight-item style property.
763 /* "GtkMenuBar::prelight-item = 1\n" */
764 "}widget_class \"*MenuBar*\" style \"msw-menu-bar\"\n",
765 btn_face.red, btn_face.green, btn_face.blue,
766 menu_bar_prelight_str, xp_theme_is_active ()? 0 : 2);
767 gtk_rc_parse_string (buf);
769 g_snprintf (buf, sizeof (buf),
770 "style \"msw-toolbar\" = \"msw-default\"\n"
772 "GtkHandleBox::shadow-type = %s\n"
773 "GtkToolbar::shadow-type = %s\n"
774 "}widget_class \"*HandleBox*\" style \"msw-toolbar\"\n",
775 "etched-in", "etched-in");
776 gtk_rc_parse_string (buf);
778 /* enable tooltip fonts */
779 font_ptr = sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
780 font_buf, sizeof (font_buf));
781 g_snprintf (buf, sizeof (buf),
782 "style \"msw-tooltips-caption\" = \"msw-default\"\n"
783 "{fg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
784 "}widget \"gtk-tooltips.GtkLabel\" style \"msw-tooltips-caption\"\n"
785 "widget \"gtk-tooltip.GtkLabel\" style \"msw-tooltips-caption\"\n",
786 tooltip_fore.red, tooltip_fore.green, tooltip_fore.blue,
787 (font_ptr ? "font_name" : "#"),
788 (font_ptr ? font_ptr : " font name should go here"));
789 gtk_rc_parse_string (buf);
791 g_snprintf (buf, sizeof (buf),
792 "style \"msw-tooltips\" = \"msw-default\"\n"
793 "{bg[NORMAL] = { %d, %d, %d }\n"
794 "}widget \"gtk-tooltips*\" style \"msw-tooltips\"\n"
795 "widget \"gtk-tooltip*\" style \"msw-tooltips\"\n",
796 tooltip_back.red, tooltip_back.green, tooltip_back.blue);
797 gtk_rc_parse_string (buf);
799 /* enable font theming for status bars */
800 font_ptr = sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
801 font_buf, sizeof (font_buf));
802 g_snprintf (buf, sizeof (buf),
803 "style \"msw-status\" = \"msw-default\"\n" "{%s = \"%s\"\n"
804 "bg[NORMAL] = { %d, %d, %d }\n"
805 "}widget_class \"*Status*\" style \"msw-status\"\n",
806 (font_ptr ? "font_name" : "#"),
807 (font_ptr ? font_ptr : " font name should go here"),
808 btn_face.red, btn_face.green, btn_face.blue);
809 gtk_rc_parse_string (buf);
811 /* enable coloring for text on buttons TODO: use GetThemeMetric for the
812 border and outside border */
813 g_snprintf (buf, sizeof (buf),
814 "style \"msw-button\" = \"msw-default\"\n"
816 "bg[NORMAL] = { %d, %d, %d }\n"
817 "bg[PRELIGHT] = { %d, %d, %d }\n"
818 "bg[INSENSITIVE] = { %d, %d, %d }\n"
819 "fg[PRELIGHT] = { %d, %d, %d }\n"
820 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
821 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
822 "GtkButton::child-displacement-x = 1\n"
823 "GtkButton::child-displacement-y = 1\n"
824 "GtkButton::focus-padding = %d\n"
825 "}widget_class \"*Button*\" style \"msw-button\"\n",
826 btn_face.red, btn_face.green, btn_face.blue,
827 btn_face.red, btn_face.green, btn_face.blue,
828 btn_face.red, btn_face.green, btn_face.blue,
829 btn_fore.red, btn_fore.green, btn_fore.blue,
830 xp_theme_is_active ()? 1 : 2);
831 gtk_rc_parse_string (buf);
833 /* enable coloring for progress bars */
834 g_snprintf (buf, sizeof (buf),
835 "style \"msw-progress\" = \"msw-default\"\n"
836 "{bg[PRELIGHT] = { %d, %d, %d }\n"
837 "bg[NORMAL] = { %d, %d, %d }\n"
838 "}widget_class \"*Progress*\" style \"msw-progress\"\n",
842 btn_face.red, btn_face.green, btn_face.blue);
843 gtk_rc_parse_string (buf);
845 /* scrollbar thumb width and height */
846 g_snprintf (buf, sizeof (buf),
847 "style \"msw-vscrollbar\" = \"msw-default\"\n"
848 "{GtkRange::slider-width = %d\n"
849 "GtkRange::stepper-size = %d\n"
850 "GtkRange::stepper-spacing = 0\n"
851 "GtkRange::trough_border = 0\n"
852 "GtkScale::slider-length = %d\n"
853 "GtkScrollbar::min-slider-length = 8\n"
854 "}widget_class \"*VScrollbar*\" style \"msw-vscrollbar\"\n"
855 "widget_class \"*VScale*\" style \"msw-vscrollbar\"\n",
856 GetSystemMetrics (SM_CYVTHUMB),
857 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CXVSCROLL), 11);
858 gtk_rc_parse_string (buf);
860 g_snprintf (buf, sizeof (buf),
861 "style \"msw-hscrollbar\" = \"msw-default\"\n"
862 "{GtkRange::slider-width = %d\n"
863 "GtkRange::stepper-size = %d\n"
864 "GtkRange::stepper-spacing = 0\n"
865 "GtkRange::trough_border = 0\n"
866 "GtkScale::slider-length = %d\n"
867 "GtkScrollbar::min-slider-length = 8\n"
868 "}widget_class \"*HScrollbar*\" style \"msw-hscrollbar\"\n"
869 "widget_class \"*HScale*\" style \"msw-hscrollbar\"\n",
870 GetSystemMetrics (SM_CXHTHUMB),
871 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CYHSCROLL), 11);
872 gtk_rc_parse_string (buf);
874 gtk_rc_parse_string ("style \"msw-scrolled-window\" = \"msw-default\"\n"
875 "{GtkScrolledWindow::scrollbars-within-bevel = 1}\n"
876 "class \"GtkScrolledWindow\" style \"msw-scrolled-window\"\n");
878 /* radio/check button sizes */
879 g_snprintf (buf, sizeof (buf),
880 "style \"msw-checkbutton\" = \"msw-button\"\n"
881 "{GtkCheckButton::indicator-size = 13\n"
882 "}widget_class \"*CheckButton*\" style \"msw-checkbutton\"\n"
883 "widget_class \"*RadioButton*\" style \"msw-checkbutton\"\n");
884 gtk_rc_parse_string (buf);
886 /* size of combo box toggle button */
887 g_snprintf (buf, sizeof (buf),
888 "style \"msw-combobox-button\" = \"msw-default\"\n"
892 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
893 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
894 "GtkButton::child-displacement-x = 0\n"
895 "GtkButton::child-displacement-y = 0\n"
896 "GtkWidget::focus-padding = 0\n"
897 "GtkWidget::focus-line-width = 0\n"
899 "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combobox-button\"\n");
900 gtk_rc_parse_string (buf);
902 g_snprintf (buf, sizeof (buf),
903 "style \"msw-combobox\" = \"msw-default\"\n"
905 "GtkComboBox::shadow-type = in\n"
909 "class \"GtkComboBox\" style \"msw-combobox\"\n",
910 xp_theme_is_active()? 1 : GetSystemMetrics (SM_CXEDGE),
911 xp_theme_is_active()? 1 : GetSystemMetrics (SM_CYEDGE));
912 gtk_rc_parse_string (buf);
914 /* size of tree view header */
915 g_snprintf (buf, sizeof (buf),
916 "style \"msw-header-button\" = \"msw-default\"\n"
920 "GtkWidget::draw-border = {0, 0, 0, 0}\n"
921 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
922 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
923 "GtkButton::child-displacement-x = 0\n"
924 "GtkButton::child-displacement-y = 0\n"
925 "GtkWidget::focus-padding = 0\n"
926 "GtkWidget::focus-line-width = 0\n"
928 "widget_class \"*TreeView*Button*\" style \"msw-header-button\"\n");
929 gtk_rc_parse_string (buf);
931 /* FIXME: This should be enabled once gtk+ support GtkNotebok::prelight-tab */
932 /* enable prelight tab of GtkNotebook */
934 g_snprintf (buf, sizeof (buf),
935 "style \"msw-notebook\" = \"msw-default\"\n"
936 "{GtkNotebook::prelight-tab=1\n"
937 "}widget_class \"*Notebook*\" style \"msw-notebook\"\n");
938 gtk_rc_parse_string (buf);
941 /* FIXME: This should be enabled once gtk+ support GtkTreeView::full-row-focus */
943 g_snprintf (buf, sizeof (buf),
944 "style \"msw-treeview\" = \"msw-default\"\n"
945 "{GtkTreeView::full-row-focus=0\n"
946 "}widget_class \"*TreeView*\" style \"msw-treeview\"\n");
947 gtk_rc_parse_string (buf);
952 setup_system_styles (GtkStyle *style)
956 /* Default background */
957 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
958 &style->bg[GTK_STATE_NORMAL]);
959 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
960 &style->bg[GTK_STATE_SELECTED]);
961 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
962 &style->bg[GTK_STATE_INSENSITIVE]);
963 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
964 &style->bg[GTK_STATE_ACTIVE]);
965 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
966 &style->bg[GTK_STATE_PRELIGHT]);
969 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
970 &style->base[GTK_STATE_NORMAL]);
971 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
972 &style->base[GTK_STATE_SELECTED]);
973 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
974 &style->base[GTK_STATE_INSENSITIVE]);
975 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
976 &style->base[GTK_STATE_ACTIVE]);
977 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
978 &style->base[GTK_STATE_PRELIGHT]);
981 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
982 &style->text[GTK_STATE_NORMAL]);
983 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
984 &style->text[GTK_STATE_SELECTED]);
985 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_GRAYTEXT,
986 &style->text[GTK_STATE_INSENSITIVE]);
987 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
988 &style->text[GTK_STATE_ACTIVE]);
989 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
990 &style->text[GTK_STATE_PRELIGHT]);
992 /* Default foreground */
993 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
994 &style->fg[GTK_STATE_NORMAL]);
995 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
996 &style->fg[GTK_STATE_SELECTED]);
997 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_GRAYTEXT,
998 &style->fg[GTK_STATE_INSENSITIVE]);
999 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
1000 &style->fg[GTK_STATE_ACTIVE]);
1001 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
1002 &style->fg[GTK_STATE_PRELIGHT]);
1004 for (i = 0; i < 5; i++)
1006 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DSHADOW,
1008 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DHILIGHT,
1011 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
1012 style->mid[i].green =
1013 (style->light[i].green + style->dark[i].green) / 2;
1014 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
1016 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
1017 style->text_aa[i].green =
1018 (style->text[i].green + style->base[i].green) / 2;
1019 style->text_aa[i].blue =
1020 (style->text[i].blue + style->base[i].blue) / 2;
1025 sanitize_size (GdkWindow *window, gint *width, gint *height)
1027 gboolean set_bg = FALSE;
1029 if ((*width == -1) && (*height == -1))
1031 set_bg = GDK_IS_WINDOW (window);
1032 gdk_drawable_get_size (window, width, height);
1034 else if (*width == -1)
1036 gdk_drawable_get_size (window, width, NULL);
1038 else if (*height == -1)
1040 gdk_drawable_get_size (window, NULL, height);
1046 static XpThemeElement
1047 map_gtk_progress_bar_to_xp (GtkProgressBar *progress_bar, gboolean trough)
1051 switch (progress_bar->orientation)
1053 case GTK_PROGRESS_LEFT_TO_RIGHT:
1054 case GTK_PROGRESS_RIGHT_TO_LEFT:
1056 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_H
1057 : XP_THEME_ELEMENT_PROGRESS_BAR_H;
1062 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_V
1063 : XP_THEME_ELEMENT_PROGRESS_BAR_V;
1071 is_combo_box_child (GtkWidget *w)
1078 for (tmp = w->parent; tmp; tmp = tmp->parent)
1080 if (GTK_IS_COMBO_BOX (tmp))
1087 /* This function is not needed anymore */
1089 combo_box_draw_arrow (GtkStyle *style,
1092 GdkRectangle *area, GtkWidget *widget)
1094 if (xp_theme_is_active ())
1097 if (widget && GTK_IS_TOGGLE_BUTTON (widget->parent))
1103 dc = get_window_dc (style, window, state, area->x, area->y, area->width,
1104 area->height, &rect);
1105 border = (GTK_TOGGLE_BUTTON (widget->parent)->
1106 active ? DFCS_PUSHED | DFCS_FLAT : 0);
1108 InflateRect (&rect, 1, 1);
1109 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
1111 release_window_dc (style, window, state);
1120 draw_part (GdkDrawable *drawable,
1121 GdkGC *gc, GdkRectangle *area, gint x, gint y, Part part)
1124 gdk_gc_set_clip_rectangle (gc, area);
1126 if (!parts[part].bmap)
1128 parts[part].bmap = gdk_bitmap_create_from_data (drawable,
1130 PART_SIZE, PART_SIZE);
1133 gdk_gc_set_ts_origin (gc, x, y);
1134 gdk_gc_set_stipple (gc, parts[part].bmap);
1135 gdk_gc_set_fill (gc, GDK_STIPPLED);
1137 gdk_draw_rectangle (drawable, gc, TRUE, x, y, PART_SIZE, PART_SIZE);
1139 gdk_gc_set_fill (gc, GDK_SOLID);
1142 gdk_gc_set_clip_rectangle (gc, NULL);
1146 draw_check (GtkStyle *style,
1149 GtkShadowType shadow,
1152 const gchar *detail, gint x, gint y, gint width, gint height)
1154 x -= (1 + PART_SIZE - width) / 2;
1155 y -= (1 + PART_SIZE - height) / 2;
1157 if (detail && strcmp (detail, "check") == 0) /* Menu item */
1159 if (shadow == GTK_SHADOW_IN)
1161 draw_part (window, style->black_gc, area, x, y, CHECK_TEXT);
1162 draw_part (window, style->dark_gc[state], area, x, y, CHECK_AA);
1167 XpThemeElement theme_elt = XP_THEME_ELEMENT_CHECKBOX;
1170 case GTK_SHADOW_ETCHED_IN:
1171 theme_elt = XP_THEME_ELEMENT_INCONSISTENT_CHECKBOX;
1175 theme_elt = XP_THEME_ELEMENT_PRESSED_CHECKBOX;
1182 if (!xp_theme_draw (window, theme_elt,
1183 style, x, y, width, height, state, area))
1185 if (detail && !strcmp (detail, "cellcheck"))
1186 state = GTK_STATE_NORMAL;
1188 draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
1189 draw_part (window, style->dark_gc[state], area, x, y, CHECK_DARK);
1190 draw_part (window, style->mid_gc[state], area, x, y, CHECK_MID);
1191 draw_part (window, style->light_gc[state], area, x, y, CHECK_LIGHT);
1192 draw_part (window, style->base_gc[state], area, x, y, CHECK_BASE);
1194 if (shadow == GTK_SHADOW_IN)
1196 draw_part (window, style->text_gc[state], area, x,
1198 draw_part (window, style->text_aa_gc[state], area,
1201 else if (shadow == GTK_SHADOW_ETCHED_IN)
1203 draw_part (window, style->text_gc[state], area, x, y,
1204 CHECK_INCONSISTENT);
1205 draw_part (window, style->text_aa_gc[state], area, x, y,
1213 draw_expander (GtkStyle *style,
1218 const gchar *detail,
1219 gint x, gint y, GtkExpanderStyle expander_style)
1222 gint expander_semi_size;
1223 XpThemeElement xp_expander;
1225 gtk_widget_style_get (widget, "expander_size", &expander_size, NULL);
1227 switch (expander_style)
1229 case GTK_EXPANDER_COLLAPSED:
1230 case GTK_EXPANDER_SEMI_COLLAPSED:
1231 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED;
1235 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED;
1239 if ((expander_size % 2) == 0)
1242 if (expander_size > 2)
1246 gdk_gc_set_clip_rectangle (style->fg_gc[state], area);
1248 expander_semi_size = expander_size / 2;
1249 x -= expander_semi_size;
1250 y -= expander_semi_size;
1252 if (!xp_theme_draw (window, xp_expander, style,
1253 x, y, expander_size, expander_size, state, area))
1260 dc = get_window_dc (style, window, state, x, y, expander_size,
1261 expander_size, &rect);
1262 FrameRect (dc, &rect, GetSysColorBrush (COLOR_GRAYTEXT));
1263 InflateRect (&rect, -1, -1);
1264 FillRect (dc, &rect,
1265 GetSysColorBrush (state ==
1266 GTK_STATE_INSENSITIVE ? COLOR_BTNFACE :
1269 InflateRect (&rect, -1, -1);
1271 pen = CreatePen (PS_SOLID, 1, GetSysColor (COLOR_WINDOWTEXT));
1272 old_pen = SelectObject (dc, pen);
1274 MoveToEx (dc, rect.left, rect.top - 2 + expander_semi_size, NULL);
1275 LineTo (dc, rect.right, rect.top - 2 + expander_semi_size);
1277 if (expander_style == GTK_EXPANDER_COLLAPSED ||
1278 expander_style == GTK_EXPANDER_SEMI_COLLAPSED)
1280 MoveToEx (dc, rect.left - 2 + expander_semi_size, rect.top, NULL);
1281 LineTo (dc, rect.left - 2 + expander_semi_size, rect.bottom);
1284 SelectObject (dc, old_pen);
1286 release_window_dc (style, window, state);
1290 gdk_gc_set_clip_rectangle (style->fg_gc[state], NULL);
1294 draw_option (GtkStyle *style,
1297 GtkShadowType shadow,
1300 const gchar *detail, gint x, gint y, gint width, gint height)
1302 x -= (1 + PART_SIZE - width) / 2;
1303 y -= (1 + PART_SIZE - height) / 2;
1305 if (detail && strcmp (detail, "option") == 0) /* Menu item */
1307 if (shadow == GTK_SHADOW_IN)
1309 draw_part (window, style->fg_gc[state], area, x, y, RADIO_TEXT);
1314 if (xp_theme_draw (window, shadow == GTK_SHADOW_IN
1315 ? XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON
1316 : XP_THEME_ELEMENT_RADIO_BUTTON,
1317 style, x, y, width, height, state, area))
1322 if (detail && !strcmp (detail, "cellradio"))
1323 state = GTK_STATE_NORMAL;
1325 draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
1326 draw_part (window, style->dark_gc[state], area, x, y, RADIO_DARK);
1327 draw_part (window, style->mid_gc[state], area, x, y, RADIO_MID);
1328 draw_part (window, style->light_gc[state], area, x, y, RADIO_LIGHT);
1329 draw_part (window, style->base_gc[state], area, x, y, RADIO_BASE);
1331 if (shadow == GTK_SHADOW_IN)
1332 draw_part (window, style->text_gc[state], area, x, y, RADIO_TEXT);
1338 draw_varrow (GdkWindow *window,
1340 GtkShadowType shadow_type,
1342 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1345 gint y_start, y_increment;
1349 gdk_gc_set_clip_rectangle (gc, area);
1351 width = width + width % 2 - 1; /* Force odd */
1352 steps = 1 + width / 2;
1353 extra = height - steps;
1355 if (arrow_type == GTK_ARROW_DOWN)
1362 y_start = y + height - 1;
1366 for (i = extra; i < height; i++)
1368 gdk_draw_line (window, gc,
1369 x + (i - extra), y_start + i * y_increment,
1370 x + width - (i - extra) - 1, y_start + i * y_increment);
1374 gdk_gc_set_clip_rectangle (gc, NULL);
1378 draw_harrow (GdkWindow *window,
1380 GtkShadowType shadow_type,
1382 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1385 gint x_start, x_increment;
1389 gdk_gc_set_clip_rectangle (gc, area);
1391 height = height + height % 2 - 1; /* Force odd */
1392 steps = 1 + height / 2;
1393 extra = width - steps;
1395 if (arrow_type == GTK_ARROW_RIGHT)
1402 x_start = x + width - 1;
1406 for (i = extra; i < width; i++)
1408 gdk_draw_line (window, gc,
1409 x_start + i * x_increment, y + (i - extra),
1410 x_start + i * x_increment, y + height - (i - extra) - 1);
1415 gdk_gc_set_clip_rectangle (gc, NULL);
1418 /* This function makes up for some brokeness in gtkrange.c
1419 * where we never get the full arrow of the stepper button
1420 * and the type of button in a single drawing function.
1422 * It doesn't work correctly when the scrollbar is squished
1423 * to the point we don't have room for full-sized steppers.
1426 reverse_engineer_stepper_box (GtkWidget *range,
1427 GtkArrowType arrow_type,
1428 gint *x, gint *y, gint *width, gint *height)
1430 gint slider_width = 14, stepper_size = 14;
1436 gtk_widget_style_get (range,
1437 "slider_width", &slider_width,
1438 "stepper_size", &stepper_size, NULL);
1441 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1443 box_width = slider_width;
1444 box_height = stepper_size;
1448 box_width = stepper_size;
1449 box_height = slider_width;
1452 *x = *x - (box_width - *width) / 2;
1453 *y = *y - (box_height - *height) / 2;
1455 *height = box_height;
1458 static XpThemeElement
1459 to_xp_arrow (GtkArrowType arrow_type)
1461 XpThemeElement xp_arrow;
1466 xp_arrow = XP_THEME_ELEMENT_ARROW_UP;
1469 case GTK_ARROW_DOWN:
1470 xp_arrow = XP_THEME_ELEMENT_ARROW_DOWN;
1473 case GTK_ARROW_LEFT:
1474 xp_arrow = XP_THEME_ELEMENT_ARROW_LEFT;
1478 xp_arrow = XP_THEME_ELEMENT_ARROW_RIGHT;
1486 draw_arrow (GtkStyle *style,
1489 GtkShadowType shadow,
1492 const gchar *detail,
1493 GtkArrowType arrow_type,
1494 gboolean fill, gint x, gint y, gint width, gint height)
1500 name = gtk_widget_get_name (widget);
1502 sanitize_size (window, &width, &height);
1504 if (GTK_IS_ARROW (widget) && is_combo_box_child (widget) && xp_theme_is_active ())
1507 if (detail && strcmp (detail, "spinbutton") == 0)
1509 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1516 if (arrow_type == GTK_ARROW_DOWN)
1520 if (state == GTK_STATE_ACTIVE)
1526 draw_varrow (window, style->fg_gc[state], shadow, area,
1527 arrow_type, x, y, width, height);
1531 else if (detail && (!strcmp (detail, "vscrollbar")
1532 || !strcmp (detail, "hscrollbar")))
1534 gboolean is_disabled = FALSE;
1536 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1540 gint box_width = width;
1541 gint box_height = height;
1543 reverse_engineer_stepper_box (widget, arrow_type,
1544 &box_x, &box_y, &box_width, &box_height);
1546 if (scrollbar->range.adjustment->page_size >=
1547 (scrollbar->range.adjustment->upper -
1548 scrollbar->range.adjustment->lower))
1553 if (xp_theme_draw (window, to_xp_arrow (arrow_type), style, box_x, box_y,
1554 box_width, box_height, state, area))
1562 btn_type = DFCS_SCROLLUP;
1565 case GTK_ARROW_DOWN:
1566 btn_type = DFCS_SCROLLDOWN;
1569 case GTK_ARROW_LEFT:
1570 btn_type = DFCS_SCROLLLEFT;
1573 case GTK_ARROW_RIGHT:
1574 btn_type = DFCS_SCROLLRIGHT;
1577 case GTK_ARROW_NONE:
1581 if (state == GTK_STATE_INSENSITIVE)
1583 btn_type |= DFCS_INACTIVE;
1588 sanitize_size (window, &width, &height);
1590 dc = get_window_dc (style, window, state,
1591 box_x, box_y, box_width, box_height, &rect);
1592 DrawFrameControl (dc, &rect, DFC_SCROLL,
1593 btn_type | (shadow ==
1594 GTK_SHADOW_IN ? (DFCS_PUSHED |
1596 release_window_dc (style, window, state);
1602 /* draw the toolbar chevrons - waiting for GTK 2.4 */
1603 if (name && !strcmp (name, "gtk-toolbar-arrow"))
1606 (window, XP_THEME_ELEMENT_REBAR_CHEVRON, style, x, y,
1607 width, height, state, area))
1612 /* probably a gtk combo box on a toolbar */
1613 else if (0 /* widget->parent && GTK_IS_BUTTON
1614 (widget->parent) */ )
1617 (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x - 3,
1618 widget->allocation.y + 1, width + 5,
1619 widget->allocation.height - 4, state, area))
1625 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1627 x += (width - 7) / 2;
1628 y += (height - 5) / 2;
1630 draw_varrow (window, style->fg_gc[state], shadow, area,
1631 arrow_type, x, y, 7, 5);
1635 x += (width - 5) / 2;
1636 y += (height - 7) / 2;
1638 draw_harrow (window, style->fg_gc[state], shadow, area,
1639 arrow_type, x, y, 5, 7);
1645 option_menu_get_props (GtkWidget *widget,
1646 GtkRequisition *indicator_size,
1647 GtkBorder *indicator_spacing)
1649 GtkRequisition *tmp_size = NULL;
1650 GtkBorder *tmp_spacing = NULL;
1653 gtk_widget_style_get (widget,
1654 "indicator_size", &tmp_size,
1655 "indicator_spacing", &tmp_spacing, NULL);
1659 *indicator_size = *tmp_size;
1660 gtk_requisition_free (tmp_size);
1664 *indicator_size = default_option_indicator_size;
1669 *indicator_spacing = *tmp_spacing;
1670 gtk_border_free (tmp_spacing);
1674 *indicator_spacing = default_option_indicator_spacing;
1679 is_toolbar_child (GtkWidget *wid)
1683 if (GTK_IS_TOOLBAR (wid) || GTK_IS_HANDLE_BOX (wid))
1693 is_menu_tool_button_child (GtkWidget *wid)
1697 if (GTK_IS_MENU_TOOL_BUTTON (wid))
1706 get_window_dc (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
1707 gint x, gint y, gint width, gint height, RECT *rect)
1710 GdkDrawable *drawable;
1712 if (!GDK_IS_WINDOW (window))
1720 gdk_window_get_internal_paint_info (window, &drawable, &xoff, &yoff);
1723 rect->left = x - xoff;
1724 rect->top = y - yoff;
1725 rect->right = rect->left + width;
1726 rect->bottom = rect->top + height;
1728 return gdk_win32_hdc_get (drawable, style->dark_gc[state_type], 0);
1732 release_window_dc (GtkStyle *style, GdkWindow *window,
1733 GtkStateType state_type)
1735 GdkDrawable *drawable;
1737 if (!GDK_IS_WINDOW (window))
1743 gdk_window_get_internal_paint_info (window, &drawable, NULL, NULL);
1746 gdk_win32_hdc_release (drawable, style->dark_gc[state_type], 0);
1754 g_light_pen = CreatePen (PS_SOLID | PS_INSIDEFRAME, 1,
1755 GetSysColor (COLOR_BTNHIGHLIGHT));
1766 g_dark_pen = CreatePen (PS_SOLID | PS_INSIDEFRAME, 1,
1767 GetSysColor (COLOR_BTNSHADOW));
1774 draw_3d_border (HDC hdc, RECT *rc, gboolean sunken)
1781 pen1 = get_dark_pen ();
1782 pen2 = get_light_pen ();
1786 pen1 = get_light_pen ();
1787 pen2 = get_dark_pen ();
1790 MoveToEx (hdc, rc->left, rc->bottom - 1, NULL);
1792 old_pen = SelectObject (hdc, pen1);
1793 LineTo (hdc, rc->left, rc->top);
1794 LineTo (hdc, rc->right - 1, rc->top);
1795 SelectObject (hdc, old_pen);
1797 old_pen = SelectObject (hdc, pen2);
1798 LineTo (hdc, rc->right - 1, rc->bottom - 1);
1799 LineTo (hdc, rc->left, rc->bottom - 1);
1800 SelectObject (hdc, old_pen);
1804 draw_menu_item (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
1805 gint x, gint y, gint width, gint height,
1806 GtkStateType state_type, GdkRectangle *area)
1813 if ((parent = gtk_widget_get_parent (widget))
1814 && GTK_IS_MENU_BAR (parent) && !xp_theme_is_active ())
1816 bar = GTK_MENU_SHELL (parent);
1818 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
1820 if (state_type == GTK_STATE_PRELIGHT)
1822 draw_3d_border (dc, &rect, bar->active);
1825 release_window_dc (style, window, state_type);
1834 get_dither_brush (void)
1837 HBITMAP pattern_bmp;
1841 return g_dither_brush;
1843 for (i = 0; i < 8; i++)
1845 pattern[i] = (WORD) (0x5555 << (i & 1));
1848 pattern_bmp = CreateBitmap (8, 8, 1, 1, &pattern);
1852 g_dither_brush = CreatePatternBrush (pattern_bmp);
1853 DeleteObject (pattern_bmp);
1856 return g_dither_brush;
1860 draw_tool_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
1861 gint x, gint y, gint width, gint height,
1862 GtkStateType state_type, GdkRectangle *area)
1866 gboolean is_toggled = FALSE;
1868 if (xp_theme_is_active ())
1870 return (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
1871 x, y, width, height, state_type, area));
1874 if (GTK_IS_TOGGLE_BUTTON (widget))
1876 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1882 if (state_type != GTK_STATE_PRELIGHT
1883 && state_type != GTK_STATE_ACTIVE && !is_toggled)
1888 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
1889 if (state_type == GTK_STATE_PRELIGHT)
1893 FillRect (dc, &rect, GetSysColorBrush (COLOR_BTNFACE));
1896 draw_3d_border (dc, &rect, is_toggled);
1898 else if (state_type == GTK_STATE_ACTIVE)
1900 if (is_toggled && !is_menu_tool_button_child (widget->parent))
1902 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
1903 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
1904 FillRect (dc, &rect, get_dither_brush ());
1907 draw_3d_border (dc, &rect, TRUE);
1910 release_window_dc (style, window, state_type);
1916 draw_push_button (GdkWindow *window, GtkWidget *widget, GtkStyle *style,
1917 gint x, gint y, gint width, gint height,
1918 GtkStateType state_type, gboolean is_default)
1923 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
1925 if (GTK_IS_TOGGLE_BUTTON (widget))
1927 if (state_type == GTK_STATE_PRELIGHT &&
1928 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
1930 state_type = GTK_STATE_ACTIVE;
1934 if (state_type == GTK_STATE_ACTIVE)
1936 if (GTK_IS_TOGGLE_BUTTON (widget))
1938 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1939 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
1940 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
1941 FillRect (dc, &rect, get_dither_brush ());
1945 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
1946 InflateRect (&rect, -1, -1);
1947 FrameRect (dc, &rect, GetSysColorBrush (COLOR_BTNSHADOW));
1948 InflateRect (&rect, -1, -1);
1949 FillRect (dc, &rect, GetSysColorBrush (COLOR_BTNFACE));
1954 if (is_default || GTK_WIDGET_HAS_FOCUS (widget))
1956 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
1957 InflateRect (&rect, -1, -1);
1960 DrawFrameControl (dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH);
1963 release_window_dc (style, window, state_type);
1967 draw_box (GtkStyle *style,
1969 GtkStateType state_type,
1970 GtkShadowType shadow_type,
1973 const gchar *detail, gint x, gint y, gint width, gint height)
1975 if (is_combo_box_child (widget) && detail && !strcmp (detail, "button"))
1982 border = (GTK_TOGGLE_BUTTON (widget)->active ? DFCS_PUSHED | DFCS_FLAT : 0);
1984 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
1985 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
1986 release_window_dc (style, window, state_type);
1988 if (xp_theme_is_active ()
1989 && xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x, y,
1990 width, height, state_type, area))
1992 cx = GetSystemMetrics(SM_CXVSCROLL);
1997 dc = get_window_dc (style, window, state_type, x, y, width - cx, height, &rect);
1998 FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
1999 release_window_dc (style, window, state_type);
2005 (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
2007 if (GTK_IS_TREE_VIEW (widget->parent) || GTK_IS_CLIST (widget->parent))
2010 (window, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
2011 width, height, state_type, area))
2019 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2021 DrawFrameControl (dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH |
2023 GTK_STATE_ACTIVE ? (DFCS_PUSHED | DFCS_FLAT)
2025 release_window_dc (style, window, state_type);
2028 else if (is_toolbar_child (widget->parent)
2029 || (!GTK_IS_BUTTON (widget) ||
2030 (GTK_RELIEF_NONE == gtk_button_get_relief (GTK_BUTTON (widget)))))
2032 if (draw_tool_button (window, widget, style, x, y,
2033 width, height, state_type, area))
2040 gboolean is_default = GTK_WIDGET_HAS_DEFAULT (widget);
2043 is_default ? XP_THEME_ELEMENT_DEFAULT_BUTTON :
2044 XP_THEME_ELEMENT_BUTTON, style, x, y, width, height,
2050 draw_push_button (window, widget, style,
2051 x, y, width, height, state_type, is_default);
2058 else if (detail && !strcmp (detail, "spinbutton"))
2060 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
2065 else if (detail && (!strcmp (detail, "spinbutton_up")
2066 || !strcmp (detail, "spinbutton_down")))
2068 if (!xp_theme_draw (window,
2069 (!strcmp (detail, "spinbutton_up"))
2070 ? XP_THEME_ELEMENT_SPIN_BUTTON_UP
2071 : XP_THEME_ELEMENT_SPIN_BUTTON_DOWN,
2072 style, x, y, width, height, state_type, area))
2077 dc = get_window_dc (style, window, state_type,
2078 x, y, width, height, &rect);
2079 DrawEdge (dc, &rect,
2081 GTK_STATE_ACTIVE ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT);
2082 release_window_dc (style, window, state_type);
2086 else if (detail && !strcmp (detail, "slider"))
2088 if (GTK_IS_SCROLLBAR (widget))
2090 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
2091 gboolean is_v = GTK_IS_VSCROLLBAR (widget);
2093 if (xp_theme_draw (window,
2095 ? XP_THEME_ELEMENT_SCROLLBAR_V
2096 : XP_THEME_ELEMENT_SCROLLBAR_H,
2097 style, x, y, width, height, state_type, area))
2099 XpThemeElement gripper =
2100 (is_v ? XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V :
2101 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H);
2103 /* Do not display grippers on tiny scroll bars,
2104 the limit imposed is rather arbitrary, perhaps
2105 we can fetch the gripper geometry from
2106 somewhere and use that... */
2108 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H
2111 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V && height < 16))
2116 xp_theme_draw (window, gripper, style, x, y,
2117 width, height, state_type, area);
2122 if (scrollbar->range.adjustment->page_size >=
2123 (scrollbar->range.adjustment->upper -
2124 scrollbar->range.adjustment->lower))
2131 else if (detail && !strcmp (detail, "bar"))
2133 if (widget && GTK_IS_PROGRESS_BAR (widget))
2135 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2136 XpThemeElement xp_progress_bar =
2137 map_gtk_progress_bar_to_xp (progress_bar, FALSE);
2139 if (xp_theme_draw (window, xp_progress_bar, style, x, y,
2140 width, height, state_type, area))
2145 shadow_type = GTK_SHADOW_NONE;
2148 else if (detail && strcmp (detail, "menuitem") == 0)
2150 shadow_type = GTK_SHADOW_NONE;
2151 if (draw_menu_item (window, widget, style,
2152 x, y, width, height, state_type, area))
2157 else if (detail && !strcmp (detail, "trough"))
2159 if (widget && GTK_IS_PROGRESS_BAR (widget))
2161 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2162 XpThemeElement xp_progress_bar =
2163 map_gtk_progress_bar_to_xp (progress_bar, TRUE);
2165 (window, xp_progress_bar, style, x, y, width, height,
2172 /* Blank in classic Windows */
2175 else if (widget && GTK_IS_SCROLLBAR (widget))
2177 gboolean is_vertical = GTK_IS_VSCROLLBAR (widget);
2179 if (xp_theme_draw (window,
2181 ? XP_THEME_ELEMENT_TROUGH_V
2182 : XP_THEME_ELEMENT_TROUGH_H,
2183 style, x, y, width, height, state_type, area))
2192 sanitize_size (window, &width, &height);
2193 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2195 SetTextColor (dc, GetSysColor (COLOR_3DHILIGHT));
2196 SetBkColor (dc, GetSysColor (COLOR_BTNFACE));
2197 FillRect (dc, &rect, get_dither_brush ());
2199 release_window_dc (style, window, state_type);
2204 else if (widget && GTK_IS_SCALE (widget))
2206 gboolean is_vertical = GTK_IS_VSCALE (widget);
2208 if (!xp_theme_is_active ())
2210 parent_class->draw_box (style, window, state_type,
2211 GTK_SHADOW_NONE, area,
2212 widget, detail, x, y, width, height);
2218 (window, XP_THEME_ELEMENT_SCALE_TROUGH_V,
2219 style, (2 * x + width) / 2, y, 2, height,
2225 parent_class->draw_box (style, window, state_type,
2226 GTK_SHADOW_ETCHED_IN,
2228 (2 * x + width) / 2, y, 1, height);
2233 (window, XP_THEME_ELEMENT_SCALE_TROUGH_H,
2234 style, x, (2 * y + height) / 2, width, 2,
2240 parent_class->draw_box (style, window, state_type,
2241 GTK_SHADOW_ETCHED_IN,
2242 area, NULL, NULL, x,
2243 (2 * y + height) / 2, width, 1);
2249 else if (detail && strcmp (detail, "optionmenu") == 0)
2251 if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
2252 style, x, y, width, height, state_type, area))
2258 && (strcmp (detail, "vscrollbar") == 0
2259 || strcmp (detail, "hscrollbar") == 0))
2264 && (strcmp (detail, "handlebox_bin") == 0
2265 || strcmp (detail, "toolbar") == 0
2266 || strcmp (detail, "menubar") == 0))
2268 sanitize_size (window, &width, &height);
2269 if (xp_theme_draw (window, XP_THEME_ELEMENT_REBAR,
2270 style, x, y, width, height, state_type, area))
2275 else if (detail && (!strcmp (detail, "handlebox"))) /* grip */
2277 if (!xp_theme_is_active ())
2282 else if (detail && !strcmp (detail, "notebook") && GTK_IS_NOTEBOOK (widget))
2284 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2286 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2287 x, y, width, height, state_type, area))
2295 const gchar *name = gtk_widget_get_name (widget);
2297 if (name && !strcmp (name, "gtk-tooltips"))
2300 (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
2301 height, state_type, area))
2311 hdc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2313 brush = GetSysColorBrush (COLOR_3DDKSHADOW);
2317 FrameRect (hdc, &rect, brush);
2320 InflateRect (&rect, -1, -1);
2321 FillRect (hdc, &rect, (HBRUSH) (COLOR_INFOBK + 1));
2323 release_window_dc (style, window, state_type);
2330 parent_class->draw_box (style, window, state_type, shadow_type, area,
2331 widget, detail, x, y, width, height);
2333 if (detail && strcmp (detail, "optionmenu") == 0)
2335 GtkRequisition indicator_size;
2336 GtkBorder indicator_spacing;
2339 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2341 sanitize_size (window, &width, &height);
2343 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
2346 x + indicator_size.width + indicator_spacing.left +
2347 indicator_spacing.right;
2351 vline_x = x + width - (indicator_size.width +
2352 indicator_spacing.left +
2353 indicator_spacing.right) - style->xthickness;
2355 parent_class->draw_vline (style, window, state_type, area, widget,
2357 y + style->ythickness + 1,
2358 y + height - style->ythickness - 3, vline_x);
2364 draw_tab (GtkStyle *style,
2367 GtkShadowType shadow,
2370 const gchar *detail, gint x, gint y, gint width, gint height)
2372 GtkRequisition indicator_size;
2373 GtkBorder indicator_spacing;
2377 g_return_if_fail (style != NULL);
2378 g_return_if_fail (window != NULL);
2380 if (detail && !strcmp (detail, "optionmenutab"))
2382 if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
2383 style, x - 5, widget->allocation.y + 1,
2384 width + 10, widget->allocation.height - 2,
2391 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2393 x += (width - indicator_size.width) / 2;
2394 arrow_height = (indicator_size.width + 1) / 2;
2396 y += (height - arrow_height) / 2;
2398 draw_varrow (window, style->black_gc, shadow, area, GTK_ARROW_DOWN,
2399 x, y, indicator_size.width, arrow_height);
2402 /* Draw classic Windows tab - thanks Mozilla!
2403 (no system API for this, but DrawEdge can draw all the parts of a tab) */
2405 DrawTab (HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
2406 gboolean aDrawLeft, gboolean aDrawRight)
2408 gint32 leftFlag, topFlag, rightFlag, lightFlag, shadeFlag;
2409 RECT topRect, sideRect, bottomRect, lightRect, shadeRect;
2410 gint32 selectedOffset, lOffset, rOffset;
2412 selectedOffset = aSelected ? 1 : 0;
2413 lOffset = aDrawLeft ? 2 : 0;
2414 rOffset = aDrawRight ? 2 : 0;
2416 /* Get info for tab orientation/position (Left, Top, Right, Bottom) */
2422 rightFlag = BF_BOTTOM;
2423 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2424 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2426 SetRect (&topRect, R.left, R.top + lOffset, R.right,
2427 R.bottom - rOffset);
2428 SetRect (&sideRect, R.left + 2, R.top, R.right - 2 + selectedOffset,
2430 SetRect (&bottomRect, R.right - 2, R.top, R.right, R.bottom);
2431 SetRect (&lightRect, R.left, R.top, R.left + 3, R.top + 3);
2432 SetRect (&shadeRect, R.left + 1, R.bottom - 2, R.left + 2,
2439 rightFlag = BF_RIGHT;
2440 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2441 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2443 SetRect (&topRect, R.left + lOffset, R.top, R.right - rOffset,
2445 SetRect (&sideRect, R.left, R.top + 2, R.right,
2446 R.bottom - 1 + selectedOffset);
2447 SetRect (&bottomRect, R.left, R.bottom - 1, R.right, R.bottom);
2448 SetRect (&lightRect, R.left, R.top, R.left + 3, R.top + 3);
2449 SetRect (&shadeRect, R.right - 2, R.top + 1, R.right - 1, R.top + 2);
2455 rightFlag = BF_BOTTOM;
2456 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2457 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2459 SetRect (&topRect, R.left, R.top + lOffset, R.right,
2460 R.bottom - rOffset);
2461 SetRect (&sideRect, R.left + 2 - selectedOffset, R.top, R.right - 2,
2463 SetRect (&bottomRect, R.left, R.top, R.left + 2, R.bottom);
2464 SetRect (&lightRect, R.right - 3, R.top, R.right - 1, R.top + 2);
2465 SetRect (&shadeRect, R.right - 2, R.bottom - 3, R.right, R.bottom - 1);
2470 topFlag = BF_BOTTOM;
2471 rightFlag = BF_RIGHT;
2472 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2473 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2475 SetRect (&topRect, R.left + lOffset, R.top, R.right - rOffset,
2477 SetRect (&sideRect, R.left, R.top + 2 - selectedOffset, R.right,
2479 SetRect (&bottomRect, R.left, R.top, R.right, R.top + 2);
2480 SetRect (&lightRect, R.left, R.bottom - 3, R.left + 2, R.bottom - 1);
2481 SetRect (&shadeRect, R.right - 2, R.bottom - 3, R.right, R.bottom - 1);
2485 g_return_if_reached ();
2489 FillRect (hdc, &R, (HBRUSH) (COLOR_3DFACE + 1));
2492 DrawEdge (hdc, &topRect, EDGE_RAISED, BF_SOFT | topFlag);
2496 DrawEdge (hdc, &bottomRect, EDGE_RAISED, BF_SOFT | topFlag);
2504 DrawEdge (hdc, &sideRect, EDGE_RAISED, BF_SOFT | leftFlag | rightFlag);
2506 /* Tab Diagonal Corners */
2508 DrawEdge (hdc, &lightRect, EDGE_RAISED, BF_SOFT | lightFlag);
2511 DrawEdge (hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
2515 draw_themed_tab_button (GtkStyle *style,
2517 GtkStateType state_type,
2518 GtkNotebook *notebook,
2520 gint width, gint height, gint gap_side)
2522 GdkPixmap *pixmap = NULL;
2524 gtk_container_get_border_width (GTK_CONTAINER (notebook));
2525 GtkWidget *widget = GTK_WIDGET (notebook);
2526 GdkRectangle draw_rect, clip_rect;
2527 GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
2529 if (gap_side == GTK_POS_TOP)
2533 if (state_type == GTK_STATE_NORMAL)
2537 draw_rect.width = width + 2;
2538 draw_rect.height = height;
2540 clip_rect = draw_rect;
2545 draw_rect.x = x + 2;
2547 draw_rect.width = width - 2;
2548 draw_rect.height = height - 2;
2549 clip_rect = draw_rect;
2552 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2553 widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
2555 if (draw_rect.x + draw_rect.width >= widget_right)
2557 draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
2560 if (gap_side == GTK_POS_BOTTOM)
2564 if (state_type == GTK_STATE_NORMAL)
2568 draw_rect.width = width + 2;
2569 draw_rect.height = height;
2571 clip_rect = draw_rect;
2575 draw_rect.x = x + 2;
2576 draw_rect.y = y + 2;
2577 draw_rect.width = width - 2;
2578 draw_rect.height = height - 2;
2579 clip_rect = draw_rect;
2582 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2583 widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
2585 if (draw_rect.x + draw_rect.width >= widget_right)
2587 draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
2590 rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
2592 else if (gap_side == GTK_POS_LEFT)
2596 if (state_type == GTK_STATE_NORMAL)
2600 draw_rect.width = width;
2601 draw_rect.height = height + 2;
2603 clip_rect = draw_rect;
2609 draw_rect.y = y + 2;
2610 draw_rect.width = width - 2;
2611 draw_rect.height = height - 2;
2612 clip_rect = draw_rect;
2615 /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
2616 widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
2618 if (draw_rect.y + draw_rect.height >= widget_bottom)
2620 draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
2623 rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
2625 else if (gap_side == GTK_POS_RIGHT)
2629 if (state_type == GTK_STATE_NORMAL)
2631 draw_rect.x = x + 1;
2633 draw_rect.width = width;
2634 draw_rect.height = height + 2;
2636 clip_rect = draw_rect;
2641 draw_rect.x = x + 2;
2642 draw_rect.y = y + 2;
2643 draw_rect.width = width - 2;
2644 draw_rect.height = height - 2;
2645 clip_rect = draw_rect;
2648 /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
2649 widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
2651 if (draw_rect.y + draw_rect.height >= widget_bottom)
2653 draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
2656 rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
2659 if (gap_side == GTK_POS_TOP)
2661 if (!xp_theme_draw (window, XP_THEME_ELEMENT_TAB_ITEM, style,
2662 draw_rect.x, draw_rect.y,
2663 draw_rect.width, draw_rect.height,
2664 state_type, &clip_rect))
2674 if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_RIGHT)
2676 pixmap = gdk_pixmap_new (window, clip_rect.height, clip_rect.width, -1);
2678 if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
2679 draw_rect.y - clip_rect.y, draw_rect.x - clip_rect.x,
2680 draw_rect.height, draw_rect.width, state_type, 0))
2682 g_object_unref (pixmap);
2686 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
2687 clip_rect.height, clip_rect.width);
2688 g_object_unref (pixmap);
2692 pixmap = gdk_pixmap_new (window, clip_rect.width, clip_rect.height, -1);
2694 if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
2695 draw_rect.x - clip_rect.x, draw_rect.y - clip_rect.y,
2696 draw_rect.width, draw_rect.height, state_type, 0))
2698 g_object_unref (pixmap);
2702 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
2703 clip_rect.width, clip_rect.height);
2704 g_object_unref (pixmap);
2707 rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
2708 g_object_unref (pixbuf);
2711 // XXX - This is really hacky and evil. When we're drawing the left-most tab
2712 // while it is active on a bottom-oriented notebook, there is one white
2713 // pixel at the top. There may be a better solution than this if someone
2714 // has time to discover it.
2715 if (gap_side == GTK_POS_BOTTOM && state_type == GTK_STATE_NORMAL
2716 && x == widget->allocation.x)
2718 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
2719 int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
2722 guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
2723 guchar *p = pixels + rowstride;
2725 for (psub = 0; psub < n_channels; psub++)
2727 pixels[psub] = p[psub];
2731 gdk_draw_pixbuf (window, NULL, pixbuf, 0, 0, clip_rect.x, clip_rect.y,
2732 clip_rect.width, clip_rect.height, GDK_RGB_DITHER_NONE,
2734 g_object_unref (pixbuf);
2741 draw_tab_button (GtkStyle *style,
2743 GtkStateType state_type,
2744 GtkShadowType shadow_type,
2747 const gchar *detail,
2748 gint x, gint y, gint width, gint height, gint gap_side)
2750 if (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM)
2752 /* experimental tab-drawing code from mozilla */
2757 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2759 if (gap_side == GTK_POS_TOP)
2761 else if (gap_side == GTK_POS_BOTTOM)
2762 aPosition = BF_BOTTOM;
2763 else if (gap_side == GTK_POS_LEFT)
2764 aPosition = BF_LEFT;
2766 aPosition = BF_RIGHT;
2768 if (state_type == GTK_STATE_PRELIGHT)
2769 state_type = GTK_STATE_NORMAL;
2771 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2773 DrawTab (dc, rect, aPosition,
2774 state_type != GTK_STATE_PRELIGHT,
2775 (gap_side != GTK_POS_LEFT), (gap_side != GTK_POS_RIGHT));
2778 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2780 release_window_dc (style, window, state_type);
2788 draw_extension (GtkStyle *style,
2790 GtkStateType state_type,
2791 GtkShadowType shadow_type,
2794 const gchar *detail,
2796 gint width, gint height, GtkPositionType gap_side)
2798 if (widget && GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "tab"))
2800 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2802 /* Why this differs from gap_side, I have no idea.. */
2803 int real_gap_side = gtk_notebook_get_tab_pos (notebook);
2805 if (!draw_themed_tab_button (style, window, state_type,
2806 GTK_NOTEBOOK (widget), x, y,
2807 width, height, real_gap_side))
2809 if (!draw_tab_button (style, window, state_type,
2810 shadow_type, area, widget,
2811 detail, x, y, width, height, real_gap_side))
2813 parent_class->draw_extension (style, window, state_type,
2814 shadow_type, area, widget, detail,
2815 x, y, width, height,
2823 draw_box_gap (GtkStyle *style, GdkWindow *window, GtkStateType state_type,
2824 GtkShadowType shadow_type, GdkRectangle *area,
2825 GtkWidget *widget, const gchar *detail, gint x,
2826 gint y, gint width, gint height, GtkPositionType gap_side,
2827 gint gap_x, gint gap_width)
2829 if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
2831 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2832 int side = gtk_notebook_get_tab_pos (notebook);
2833 int x2 = x, y2 = y, w2 = width, h2 = height;
2835 if (side == GTK_POS_TOP)
2838 y2 = y - notebook->tab_vborder;
2840 h2 = height + notebook->tab_vborder * 2;
2842 else if (side == GTK_POS_BOTTOM)
2847 h2 = height + notebook->tab_vborder * 2;
2849 else if (side == GTK_POS_LEFT)
2851 x2 = x - notebook->tab_hborder;
2853 w2 = width + notebook->tab_hborder;
2856 else if (side == GTK_POS_RIGHT)
2860 w2 = width + notebook->tab_hborder * 2;
2864 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2865 x2, y2, w2, h2, state_type, area))
2871 parent_class->draw_box_gap (style, window, state_type, shadow_type,
2872 area, widget, detail, x, y, width, height,
2873 gap_side, gap_x, gap_width);
2877 is_popup_window_child (GtkWidget *widget)
2880 GtkWindowType type = -1;
2882 top = gtk_widget_get_toplevel (widget);
2884 if (top && GTK_IS_WINDOW (top))
2886 g_object_get (top, "type", &type, NULL);
2888 if (type == GTK_WINDOW_POPUP)
2889 { /* Hack for combo boxes */
2898 draw_flat_box (GtkStyle *style, GdkWindow *window,
2899 GtkStateType state_type, GtkShadowType shadow_type,
2900 GdkRectangle *area, GtkWidget *widget,
2901 const gchar *detail, gint x, gint y, gint width, gint height)
2905 if (!strcmp (detail, "checkbutton"))
2907 if (state_type == GTK_STATE_PRELIGHT)
2914 parent_class->draw_flat_box (style, window, state_type, shadow_type,
2915 area, widget, detail, x, y, width, height);
2919 draw_menu_border (GdkWindow *win, GtkStyle *style,
2920 gint x, gint y, gint width, gint height)
2925 dc = get_window_dc (style, win, GTK_STATE_NORMAL, x, y, width, height, &rect);
2930 if (xp_theme_is_active ())
2932 FrameRect (dc, &rect, GetSysColorBrush (COLOR_3DSHADOW));
2936 DrawEdge (dc, &rect, EDGE_RAISED, BF_RECT);
2939 release_window_dc (style, win, GTK_STATE_NORMAL);
2945 draw_shadow (GtkStyle *style,
2947 GtkStateType state_type,
2948 GtkShadowType shadow_type,
2951 const gchar *detail, gint x, gint y, gint width, gint height)
2953 gboolean is_handlebox;
2954 gboolean is_toolbar;
2956 if (detail && !strcmp (detail, "frame"))
2964 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2965 if (is_combo_box_child (widget))
2967 FillRect (dc, &rect, GetSysColorBrush (COLOR_WINDOW));
2969 else if (is_popup_window_child (widget))
2971 FrameRect (dc, &rect, GetSysColorBrush (COLOR_WINDOWFRAME));
2975 switch (shadow_type)
2978 draw_3d_border (dc, &rect, TRUE);
2981 case GTK_SHADOW_OUT:
2982 draw_3d_border (dc, &rect, FALSE);
2985 case GTK_SHADOW_ETCHED_IN:
2986 draw_3d_border (dc, &rect, TRUE);
2987 InflateRect (&rect, -1, -1);
2988 draw_3d_border (dc, &rect, FALSE);
2991 case GTK_SHADOW_ETCHED_OUT:
2992 draw_3d_border (dc, &rect, FALSE);
2993 InflateRect (&rect, -1, -1);
2994 draw_3d_border (dc, &rect, TRUE);
2997 case GTK_SHADOW_NONE:
3002 release_window_dc (style, window, state_type);
3006 if (detail && (!strcmp (detail, "entry") || !strcmp (detail, "combobox")))
3008 if (shadow_type != GTK_SHADOW_IN)
3011 if (!xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
3012 x, y, width, height, state_type, area))
3017 dc = get_window_dc (style, window, state_type,
3018 x, y, width, height, &rect);
3020 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
3021 release_window_dc (style, window, state_type);
3027 if (detail && !strcmp (detail, "scrolled_window") &&
3028 xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
3029 x, y, width, height, state_type, area))
3034 if (detail && !strcmp (detail, "spinbutton"))
3037 if (detail && !strcmp (detail, "menu"))
3039 if (draw_menu_border (window, style, x, y, width, height))
3045 if (detail && !strcmp (detail, "handlebox"))
3048 is_handlebox = (detail && !strcmp (detail, "handlebox_bin"));
3049 is_toolbar = (detail
3050 && (!strcmp (detail, "toolbar")
3051 || !strcmp (detail, "menubar")));
3053 if (is_toolbar || is_handlebox)
3055 if (shadow_type == GTK_SHADOW_NONE)
3064 HGDIOBJ old_pen = NULL;
3065 GtkPositionType pos;
3067 sanitize_size (window, &width, &height);
3071 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (widget));
3073 If the handle box is at left side,
3074 we shouldn't draw its right border.
3075 The same holds true for top, right, and bottom.
3080 pos = GTK_POS_RIGHT;
3088 pos = GTK_POS_BOTTOM;
3091 case GTK_POS_BOTTOM:
3098 GtkWidget *parent = gtk_widget_get_parent (widget);
3100 /* Dirty hack for toolbars contained in handle boxes */
3101 if (GTK_IS_HANDLE_BOX (parent))
3103 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (parent));
3109 Make pos != all legal enum vaules of GtkPositionType.
3110 So every border will be draw.
3112 pos = (GtkPositionType) - 1;
3116 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
3118 if (pos != GTK_POS_LEFT)
3120 old_pen = SelectObject (dc, get_light_pen ());
3121 MoveToEx (dc, rect.left, rect.top, NULL);
3122 LineTo (dc, rect.left, rect.bottom);
3124 if (pos != GTK_POS_TOP)
3126 old_pen = SelectObject (dc, get_light_pen ());
3127 MoveToEx (dc, rect.left, rect.top, NULL);
3128 LineTo (dc, rect.right, rect.top);
3130 if (pos != GTK_POS_RIGHT)
3132 old_pen = SelectObject (dc, get_dark_pen ());
3133 MoveToEx (dc, rect.right - 1, rect.top, NULL);
3134 LineTo (dc, rect.right - 1, rect.bottom);
3136 if (pos != GTK_POS_BOTTOM)
3138 old_pen = SelectObject (dc, get_dark_pen ());
3139 MoveToEx (dc, rect.left, rect.bottom - 1, NULL);
3140 LineTo (dc, rect.right, rect.bottom - 1);
3143 SelectObject (dc, old_pen);
3144 release_window_dc (style, window, state_type);
3150 if (detail && !strcmp (detail, "statusbar"))
3155 parent_class->draw_shadow (style, window, state_type, shadow_type, area,
3156 widget, detail, x, y, width, height);
3160 draw_hline (GtkStyle *style,
3162 GtkStateType state_type,
3165 const gchar *detail, gint x1, gint x2, gint y)
3167 if (xp_theme_is_active () && detail && !strcmp (detail, "menuitem"))
3170 (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, y, x2, 1,
3179 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3182 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
3186 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3192 if (style->ythickness == 2)
3196 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3197 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3200 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
3202 gdk_draw_line (window, style->light_gc[state_type], x1, y, x2, y);
3206 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3207 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3212 parent_class->draw_hline (style, window, state_type, area, widget,
3219 draw_vline (GtkStyle *style,
3221 GtkStateType state_type,
3224 const gchar *detail, gint y1, gint y2, gint x)
3226 if (style->xthickness == 2)
3230 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3231 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3234 gdk_draw_line (window, style->dark_gc[state_type], x, y1, x, y2);
3236 gdk_draw_line (window, style->light_gc[state_type], x, y1, x, y2);
3240 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3241 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3246 parent_class->draw_vline (style, window, state_type, area, widget,
3252 draw_slider (GtkStyle *style,
3254 GtkStateType state_type,
3255 GtkShadowType shadow_type,
3258 const gchar *detail,
3260 gint y, gint width, gint height, GtkOrientation orientation)
3262 if (GTK_IS_SCALE (widget) &&
3263 xp_theme_draw (window, ((orientation == GTK_ORIENTATION_VERTICAL) ?
3264 XP_THEME_ELEMENT_SCALE_SLIDER_V :
3265 XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
3266 height, state_type, area))
3271 parent_class->draw_slider (style, window, state_type, shadow_type, area,
3272 widget, detail, x, y, width, height,
3277 draw_resize_grip (GtkStyle *style,
3279 GtkStateType state_type,
3282 const gchar *detail,
3283 GdkWindowEdge edge, gint x, gint y, gint width, gint height)
3285 if (detail && !strcmp (detail, "statusbar"))
3288 (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
3289 height, state_type, area))
3296 HDC dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
3299 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3301 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
3302 release_window_dc (style, window, state_type);
3305 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3311 parent_class->draw_resize_grip (style, window, state_type, area,
3312 widget, detail, edge, x, y, width, height);
3316 draw_handle (GtkStyle *style,
3318 GtkStateType state_type,
3319 GtkShadowType shadow_type,
3322 const gchar *detail,
3324 gint y, gint width, gint height, GtkOrientation orientation)
3329 if (is_toolbar_child (widget))
3331 XpThemeElement hndl;
3333 sanitize_size (window, &width, &height);
3335 if (GTK_IS_HANDLE_BOX (widget))
3337 GtkPositionType pos;
3338 pos = gtk_handle_box_get_handle_position (GTK_HANDLE_BOX (widget));
3340 if (pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM)
3342 orientation = GTK_ORIENTATION_HORIZONTAL;
3346 orientation = GTK_ORIENTATION_VERTICAL;
3350 if (orientation == GTK_ORIENTATION_VERTICAL)
3351 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_V;
3353 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
3355 if (xp_theme_draw (window, hndl, style, x, y, width, height,
3361 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
3363 if (orientation == GTK_ORIENTATION_VERTICAL)
3366 rect.right = rect.left + 3;
3373 rect.bottom = rect.top + 3;
3378 draw_3d_border (dc, &rect, FALSE);
3379 release_window_dc (style, window, state_type);
3383 if (!GTK_IS_PANED (widget))
3385 gint xthick, ythick;
3386 GdkGC *light_gc, *dark_gc, *shadow_gc;
3389 sanitize_size (window, &width, &height);
3391 gtk_paint_box (style, window, state_type, shadow_type, area,
3392 widget, detail, x, y, width, height);
3394 light_gc = style->light_gc[state_type];
3395 dark_gc = style->dark_gc[state_type];
3396 shadow_gc = style->mid_gc[state_type];
3398 xthick = style->xthickness;
3399 ythick = style->ythickness;
3401 dest.x = x + xthick;
3402 dest.y = y + ythick;
3403 dest.width = width - (xthick * 2);
3404 dest.height = height - (ythick * 2);
3406 if (dest.width < dest.height)
3411 gdk_gc_set_clip_rectangle (light_gc, &dest);
3412 gdk_gc_set_clip_rectangle (dark_gc, &dest);
3413 gdk_gc_set_clip_rectangle (shadow_gc, &dest);
3415 if (dest.width < dest.height)
3417 gdk_draw_line (window, light_gc, dest.x, dest.y, dest.x,
3419 gdk_draw_line (window, dark_gc, dest.x + (dest.width / 2),
3420 dest.y, dest.x + (dest.width / 2), dest.height);
3421 gdk_draw_line (window, shadow_gc, dest.x + dest.width,
3422 dest.y, dest.x + dest.width, dest.height);
3426 gdk_draw_line (window, light_gc, dest.x, dest.y,
3427 dest.x + dest.width, dest.y);
3428 gdk_draw_line (window, dark_gc, dest.x,
3429 dest.y + (dest.height / 2),
3430 dest.x + dest.width, dest.y + (dest.height / 2));
3431 gdk_draw_line (window, shadow_gc, dest.x,
3432 dest.y + dest.height, dest.x + dest.width,
3433 dest.y + dest.height);
3436 gdk_gc_set_clip_rectangle (shadow_gc, NULL);
3437 gdk_gc_set_clip_rectangle (light_gc, NULL);
3438 gdk_gc_set_clip_rectangle (dark_gc, NULL);
3443 draw_focus (GtkStyle *style,
3445 GtkStateType state_type,
3448 const gchar *detail, gint x, gint y, gint width, gint height)
3453 if (!GTK_WIDGET_CAN_FOCUS (widget))
3458 if (is_combo_box_child (widget)
3459 && (GTK_IS_ARROW (widget) || GTK_IS_BUTTON (widget)))
3463 if (GTK_IS_TREE_VIEW (widget->parent) /* list view bheader */
3464 || GTK_IS_CLIST (widget->parent))
3469 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
3470 DrawFocusRect (dc, &rect);
3471 release_window_dc (style, window, state_type);
3473 parent_class->draw_focus (style, window, state_type,
3474 area, widget, detail, x, y, width, height);
3479 draw_layout (GtkStyle *style,
3481 GtkStateType state_type,
3485 const gchar *detail,
3486 gint old_x, gint old_y, PangoLayout *layout)
3488 GtkNotebook *notebook = NULL;
3492 /* In the XP theme, labels don't appear correctly centered inside
3493 * notebook tabs, so we give them a gentle nudge two pixels to the
3494 * right. A little hackish, but what are 'ya gonna do? -- Cody
3496 if (xp_theme_is_active () && detail && !strcmp (detail, "label"))
3498 if (widget->parent != NULL)
3500 if (GTK_IS_NOTEBOOK (widget->parent))
3503 notebook = GTK_NOTEBOOK (widget->parent);
3504 side = gtk_notebook_get_tab_pos (notebook);
3506 if (side == GTK_POS_TOP || side == GTK_POS_BOTTOM)
3514 parent_class->draw_layout (style, window, state_type,
3515 use_text, area, widget, detail, x, y, layout);
3519 msw_style_init_from_rc (GtkStyle *style, GtkRcStyle *rc_style)
3521 setup_system_font (style);
3522 setup_menu_settings (gtk_settings_get_default ());
3523 setup_system_styles (style);
3524 parent_class->init_from_rc (style, rc_style);
3528 load_bg_image (GdkColormap *colormap,
3529 GdkColor *bg_color, const gchar *filename)
3531 if (strcmp (filename, "<parent>") == 0)
3533 return (GdkPixmap *) GDK_PARENT_RELATIVE;
3537 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
3538 bg_color, filename);
3543 msw_style_realize (GtkStyle *style)
3545 GdkGCValues gc_values;
3546 GdkGCValuesMask gc_values_mask;
3550 for (i = 0; i < 5; i++)
3552 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
3553 style->mid[i].green =
3554 (style->light[i].green + style->dark[i].green) / 2;
3555 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
3557 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
3558 style->text_aa[i].green =
3559 (style->text[i].green + style->base[i].green) / 2;
3560 style->text_aa[i].blue =
3561 (style->text[i].blue + style->base[i].blue) / 2;
3564 style->black.red = 0x0000;
3565 style->black.green = 0x0000;
3566 style->black.blue = 0x0000;
3567 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
3569 style->white.red = 0xffff;
3570 style->white.green = 0xffff;
3571 style->white.blue = 0xffff;
3572 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
3574 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
3576 gc_values.foreground = style->black;
3577 gc_values.background = style->white;
3579 gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3581 gc_values.foreground = style->white;
3582 gc_values.background = style->black;
3584 gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3586 gc_values_mask = GDK_GC_FOREGROUND;
3588 for (i = 0; i < 5; i++)
3590 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
3592 style->bg_pixmap[i] = load_bg_image (style->colormap,
3598 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
3600 g_warning ("unable to allocate color: ( %d %d %d )", style->fg[i].red,
3601 style->fg[i].green, style->fg[i].blue);
3604 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
3606 g_warning ("unable to allocate color: ( %d %d %d )", style->bg[i].red,
3607 style->bg[i].green, style->bg[i].blue);
3610 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
3612 g_warning ("unable to allocate color: ( %d %d %d )",
3613 style->light[i].red, style->light[i].green,
3614 style->light[i].blue);
3617 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
3619 g_warning ("unable to allocate color: ( %d %d %d )",
3620 style->dark[i].red, style->dark[i].green,
3621 style->dark[i].blue);
3624 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
3626 g_warning ("unable to allocate color: ( %d %d %d )",
3627 style->mid[i].red, style->mid[i].green,
3628 style->mid[i].blue);
3631 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
3633 g_warning ("unable to allocate color: ( %d %d %d )",
3634 style->text[i].red, style->text[i].green,
3635 style->text[i].blue);
3638 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
3640 g_warning ("unable to allocate color: ( %d %d %d )",
3641 style->base[i].red, style->base[i].green,
3642 style->base[i].blue);
3645 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
3647 g_warning ("unable to allocate color: ( %d %d %d )",
3648 style->text_aa[i].red, style->text_aa[i].green,
3649 style->text_aa[i].blue);
3652 gc_values.foreground = style->fg[i];
3653 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3655 gc_values.foreground = style->bg[i];
3656 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3658 gc_values.foreground = style->light[i];
3659 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3661 gc_values.foreground = style->dark[i];
3662 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3664 gc_values.foreground = style->mid[i];
3665 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3667 gc_values.foreground = style->text[i];
3668 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3670 gc_values.foreground = style->base[i];
3671 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3673 gc_values.foreground = style->text_aa[i];
3674 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3679 msw_style_unrealize (GtkStyle *style)
3681 parent_class->unrealize (style);
3685 msw_style_class_init (MswStyleClass *klass)
3687 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3689 parent_class = g_type_class_peek_parent (klass);
3691 style_class->init_from_rc = msw_style_init_from_rc;
3692 style_class->draw_arrow = draw_arrow;
3693 style_class->draw_box = draw_box;
3694 style_class->draw_check = draw_check;
3695 style_class->draw_option = draw_option;
3696 style_class->draw_tab = draw_tab;
3697 style_class->draw_flat_box = draw_flat_box;
3698 style_class->draw_expander = draw_expander;
3699 style_class->draw_extension = draw_extension;
3700 style_class->draw_box_gap = draw_box_gap;
3701 style_class->draw_shadow = draw_shadow;
3702 style_class->draw_hline = draw_hline;
3703 style_class->draw_vline = draw_vline;
3704 style_class->draw_handle = draw_handle;
3705 style_class->draw_resize_grip = draw_resize_grip;
3706 style_class->draw_slider = draw_slider;
3707 style_class->draw_focus = draw_focus;
3708 style_class->draw_layout = draw_layout;
3710 style_class->realize = msw_style_realize;
3711 style_class->unrealize = msw_style_unrealize;
3714 GType msw_type_style = 0;
3717 msw_style_register_type (GTypeModule *module)
3719 static const GTypeInfo object_info = {
3720 sizeof (MswStyleClass),
3721 (GBaseInitFunc) NULL,
3722 (GBaseFinalizeFunc) NULL,
3723 (GClassInitFunc) msw_style_class_init,
3724 NULL, /* class_finalize */
3725 NULL, /* class_data */
3727 0, /* n_preallocs */
3728 (GInstanceInitFunc) NULL,
3731 msw_type_style = g_type_module_register_type (module,
3733 "MswStyle", &object_info, 0);
3737 msw_style_init (void)
3740 msw_style_setup_system_settings ();
3741 setup_msw_rc_style ();
3745 DeleteObject (g_light_pen);
3751 DeleteObject (g_dark_pen);
3757 msw_style_finalize (void)
3761 DeleteObject (g_dither_brush);
3766 DeleteObject (g_light_pen);
3771 DeleteObject (g_dark_pen);