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, GtkStateType state_type, gint x, gint y, gint width, gint height, RECT *rect);
48 static void release_window_dc(GtkStyle * style, GdkWindow * window, GtkStateType state_type);
51 /* Default values, not normally used
53 static const GtkRequisition default_option_indicator_size = { 9, 8 };
54 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
56 static GtkStyleClass *parent_class;
57 static HBRUSH g_dither_brush = NULL;
59 static HPEN g_light_pen = NULL;
60 static HPEN g_dark_pen = NULL;
81 static const guint8 check_aa_bits[] = {
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
86 static const guint8 check_base_bits[] = {
87 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07,
89 0x07, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00
91 static const guint8 check_black_bits[] = {
92 0x00, 0x00, 0xfe, 0x0f, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
94 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00
96 static const guint8 check_dark_bits[] = {
97 0xff, 0x1f, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
99 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00
101 static const guint8 check_light_bits[] = {
102 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
104 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0xfe, 0x1f
106 static const guint8 check_mid_bits[] = {
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08,
109 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xfc, 0x0f, 0x00, 0x00
111 static const guint8 check_text_bits[] = {
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x88, 0x03,
114 0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
116 static const guint8 radio_base_bits[] = {
117 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xf8, 0x03, 0xfc, 0x07, 0xfc, 0x07,
119 0x07, 0xfc, 0x07, 0xf8, 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00
121 static const guint8 radio_black_bits[] = {
122 0x00, 0x00, 0xf0, 0x01, 0x0c, 0x02, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00,
124 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
126 static const guint8 radio_dark_bits[] = {
127 0xf0, 0x01, 0x0c, 0x06, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00,
129 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
131 static const guint8 radio_light_bits[] = {
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10,
134 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x0c, 0x06, 0xf0, 0x01
136 static const guint8 radio_mid_bits[] = {
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08,
139 0x08, 0x00, 0x08, 0x00, 0x04, 0x0c, 0x06, 0xf0, 0x01, 0x00, 0x00
141 static const guint8 radio_text_bits[] = {
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf0, 0x01,
144 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
153 {check_aa_bits, NULL},
154 {check_base_bits, NULL},
155 {check_black_bits, NULL},
156 {check_dark_bits, NULL},
157 {check_light_bits, NULL},
158 {check_mid_bits, NULL},
159 {check_text_bits, NULL},
160 {radio_base_bits, NULL},
161 {radio_black_bits, NULL},
162 {radio_dark_bits, NULL},
163 {radio_light_bits, NULL},
164 {radio_mid_bits, NULL},
165 {radio_text_bits, NULL}
169 get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONT * out_lf)
172 /* TODO: this causes crashes later because the font name is in UCS2, and
173 the pango fns don't deal with that gracefully */
174 if (xp_theme_get_system_font (klazz, type, out_lf))
179 NONCLIENTMETRICS ncm;
181 ncm.cbSize = sizeof (NONCLIENTMETRICS);
183 if (SystemParametersInfo (SPI_GETNONCLIENTMETRICS,
184 sizeof (NONCLIENTMETRICS), &ncm, 0))
186 if (type == XP_THEME_FONT_CAPTION)
187 *out_lf = ncm.lfCaptionFont;
188 else if (type == XP_THEME_FONT_MENU)
189 *out_lf = ncm.lfMenuFont;
190 else if (type == XP_THEME_FONT_STATUS)
191 *out_lf = ncm.lfStatusFont;
193 *out_lf = ncm.lfMessageFont;
201 /***************************** BEGIN STOLEN FROM PANGO *****************************/
204 This code is stolen from Pango 1.4. It attempts to address the following problems:
206 http://bugzilla.gnome.org/show_bug.cgi?id=135098
207 http://sourceforge.net/tracker/index.php?func=detail&aid=895762&group_id=76416&atid=547655
209 As Owen suggested in bug 135098, once Pango 1.6 is released, we need to get rid of this code.
212 #define PING(printlist)
214 /* TrueType defines: */
216 #define MAKE_TT_TABLE_NAME(c1, c2, c3, c4) \
217 (((guint32)c4) << 24 | ((guint32)c3) << 16 | ((guint32)c2) << 8 | ((guint32)c1))
219 #define CMAP (MAKE_TT_TABLE_NAME('c','m','a','p'))
220 #define CMAP_HEADER_SIZE 4
222 #define NAME (MAKE_TT_TABLE_NAME('n','a','m','e'))
223 #define NAME_HEADER_SIZE 6
225 #define ENCODING_TABLE_SIZE 8
227 #define APPLE_UNICODE_PLATFORM_ID 0
228 #define MACINTOSH_PLATFORM_ID 1
229 #define ISO_PLATFORM_ID 2
230 #define MICROSOFT_PLATFORM_ID 3
232 #define SYMBOL_ENCODING_ID 0
233 #define UNICODE_ENCODING_ID 1
234 #define UCS4_ENCODING_ID 10
238 guint16 format_selector;
240 guint16 string_storage_offset;
249 guint16 string_length;
250 guint16 string_offset;
254 pango_win32_get_name_header (HDC hdc, struct name_header *header)
256 if (GetFontData (hdc, NAME, 0, header, sizeof (*header)) !=
260 header->num_records = GUINT16_FROM_BE (header->num_records);
261 header->string_storage_offset =
262 GUINT16_FROM_BE (header->string_storage_offset);
268 pango_win32_get_name_record (HDC hdc, gint i, struct name_record *record)
270 if (GetFontData (hdc, NAME, 6 + i * sizeof (*record),
271 record, sizeof (*record)) != sizeof (*record))
274 record->platform_id = GUINT16_FROM_BE (record->platform_id);
275 record->encoding_id = GUINT16_FROM_BE (record->encoding_id);
276 record->language_id = GUINT16_FROM_BE (record->language_id);
277 record->name_id = GUINT16_FROM_BE (record->name_id);
278 record->string_length = GUINT16_FROM_BE (record->string_length);
279 record->string_offset = GUINT16_FROM_BE (record->string_offset);
285 get_family_name (LOGFONT * lfp, HDC pango_win32_hdc)
290 struct name_header header;
291 struct name_record record;
293 gint unicode_ix = -1, mac_ix = -1, microsoft_ix = -1;
297 gchar *string = NULL;
302 /* If lfFaceName is ASCII, assume it is the common (English) name for the
303 font. Is this valid? Do some TrueType fonts have different names in
304 French, German, etc, and does the system return these if the locale is
305 set to use French, German, etc? */
306 l = strlen (lfp->lfFaceName);
307 for (i = 0; i < l; i++)
308 if (lfp->lfFaceName[i] < ' ' || lfp->lfFaceName[i] > '~')
312 return g_strdup (lfp->lfFaceName);
314 if ((hfont = CreateFontIndirect (lfp)) == NULL)
317 if ((oldhfont = (HFONT) SelectObject (pango_win32_hdc, hfont)) == NULL)
320 if (!pango_win32_get_name_header (pango_win32_hdc, &header))
323 PING (("%d name records", header.num_records));
325 for (i = 0; i < header.num_records; i++)
327 if (!pango_win32_get_name_record (pango_win32_hdc, i, &record))
330 if ((record.name_id != 1 && record.name_id != 16)
331 || record.string_length <= 0)
334 PING (("platform:%d encoding:%d language:%04x name_id:%d",
335 record.platform_id, record.encoding_id, record.language_id,
338 if (record.platform_id == APPLE_UNICODE_PLATFORM_ID ||
339 record.platform_id == ISO_PLATFORM_ID)
341 else if (record.platform_id == MACINTOSH_PLATFORM_ID && record.encoding_id == 0 && /* Roman
343 record.language_id == 0) /* English */
345 else if (record.platform_id == MICROSOFT_PLATFORM_ID)
346 if ((microsoft_ix == -1 ||
347 PRIMARYLANGID (record.language_id) == LANG_ENGLISH) &&
348 (record.encoding_id == SYMBOL_ENCODING_ID ||
349 record.encoding_id == UNICODE_ENCODING_ID ||
350 record.encoding_id == UCS4_ENCODING_ID))
354 if (microsoft_ix >= 0)
355 name_ix = microsoft_ix;
356 else if (mac_ix >= 0)
358 else if (unicode_ix >= 0)
359 name_ix = unicode_ix;
363 if (!pango_win32_get_name_record (pango_win32_hdc, name_ix, &record))
366 string = g_malloc (record.string_length + 1);
367 if (GetFontData (pango_win32_hdc, NAME,
368 header.string_storage_offset + record.string_offset,
369 string, record.string_length) != record.string_length)
372 string[record.string_length] = '\0';
374 if (name_ix == microsoft_ix)
375 if (record.encoding_id == SYMBOL_ENCODING_ID ||
376 record.encoding_id == UNICODE_ENCODING_ID)
377 codeset = "UTF-16BE";
380 else if (name_ix == mac_ix)
381 codeset = "MacRoman";
382 else /* name_ix == unicode_ix */
386 g_convert (string, record.string_length, "UTF-8", codeset, NULL,
394 SelectObject (pango_win32_hdc, oldhfont);
395 DeleteObject (hfont);
401 SelectObject (pango_win32_hdc, oldhfont);
404 DeleteObject (hfont);
407 return g_locale_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
410 /***************************** END STOLEN FROM PANGO *****************************/
413 sys_font_to_pango_font (XpThemeClass klazz, XpThemeFont type, char *buf,
424 if (get_system_font (klazz, type, &lf))
430 weight = "Ultra-Light";
442 weight = "Semi-Bold";
446 weight = "Ultra-Bold";
463 hwnd = GetDesktopWindow ();
467 pt_size = -MulDiv (lf.lfHeight, 72,
468 GetDeviceCaps (hDC, LOGPIXELSY));
473 font = get_family_name (&lf, hDC);
476 ReleaseDC (hwnd, hDC);
481 g_snprintf (buf, bufsiz, "%s %s %s %d", font, style, weight, pt_size);
490 /* missing from ms's header files */
491 #ifndef SPI_GETMENUSHOWDELAY
492 #define SPI_GETMENUSHOWDELAY 106
495 /* I don't know the proper XP theme class for things like
496 HIGHLIGHTTEXT, so we'll just define it to be "BUTTON"
498 #define XP_THEME_CLASS_TEXT XP_THEME_CLASS_BUTTON
501 setup_menu_settings (GtkSettings * settings)
504 gboolean win95 = FALSE;
505 OSVERSIONINFOEX osvi;
506 GObjectClass *klazz = G_OBJECT_GET_CLASS (G_OBJECT (settings));
508 ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
509 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
511 if (!GetVersionEx ((OSVERSIONINFO *) & osvi))
512 win95 = TRUE; /* assume the worst */
514 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
515 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
520 if (SystemParametersInfo
521 (SPI_GETMENUSHOWDELAY, 0, &menu_delay, 0))
525 if (g_object_class_find_property
526 (klazz, "gtk-menu-bar-popup-delay"))
528 g_object_set (settings,
529 "gtk-menu-bar-popup-delay",
532 if (g_object_class_find_property
533 (klazz, "gtk-menu-popup-delay"))
535 g_object_set (settings,
536 "gtk-menu-popup-delay",
539 if (g_object_class_find_property
540 (klazz, "gtk-menu-popdown-delay"))
542 g_object_set (settings,
543 "gtk-menu-popdown-delay",
552 msw_style_setup_system_settings (void)
554 GtkSettings *settings;
555 int cursor_blink_time;
557 settings = gtk_settings_get_default ();
561 cursor_blink_time = GetCaretBlinkTime ();
562 g_object_set (settings, "gtk-cursor-blink", cursor_blink_time > 0, NULL);
564 if (cursor_blink_time > 0)
565 g_object_set (settings, "gtk-cursor-blink-time",
566 2 * cursor_blink_time, NULL);
568 g_object_set (settings, "gtk-double-click-distance",
569 GetSystemMetrics (SM_CXDOUBLECLK), NULL);
570 g_object_set (settings, "gtk-double-click-time", GetDoubleClickTime (),
572 g_object_set (settings, "gtk-dnd-drag-threshold",
573 GetSystemMetrics (SM_CXDRAG), NULL);
575 setup_menu_settings (settings);
578 http://developer.gnome.org/doc/API/2.0/gtk/GtkSettings.html
579 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/systemparametersinfo.asp
580 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getsystemmetrics.asp */
584 setup_system_font (GtkStyle * style)
586 char buf[256], *font; /* It's okay, lfFaceName is smaller than 32
589 if ((font = sys_font_to_pango_font (XP_THEME_CLASS_TEXT,
590 XP_THEME_FONT_MESSAGE,
591 buf, sizeof (buf))) != NULL)
593 if (style->font_desc)
594 pango_font_description_free (style->font_desc);
596 style->font_desc = pango_font_description_from_string (font);
601 sys_color_to_gtk_color (XpThemeClass klazz, int id, GdkColor * pcolor)
605 if (!xp_theme_get_system_color (klazz, id, &color))
606 color = GetSysColor (id);
608 pcolor->pixel = color;
609 pcolor->red = (GetRValue (color) << 8) | GetRValue (color);
610 pcolor->green = (GetGValue (color) << 8) | GetGValue (color);
611 pcolor->blue = (GetBValue (color) << 8) | GetBValue (color);
615 get_system_metric (XpThemeClass klazz, int id)
619 if (!xp_theme_get_system_metric (klazz, id, &rval))
620 rval = GetSystemMetrics (id);
626 setup_msw_rc_style (void)
628 char buf[1024], font_buf[256], *font_ptr;
629 char menu_bar_prelight_str[128];
632 GdkColor menu_text_color;
633 GdkColor tooltip_back;
634 GdkColor tooltip_fore;
637 GdkColor progress_back;
639 GdkColor fg_prelight;
640 GdkColor bg_prelight;
641 GdkColor base_prelight;
642 GdkColor text_prelight;
645 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
647 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
649 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
651 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
654 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENUTEXT,
656 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENU, &menu_color);
659 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOTEXT,
661 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOBK,
664 /* text on push buttons. TODO: button shadows, backgrounds, and
666 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT, &btn_fore);
667 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE, &btn_face);
669 /* progress bar background color */
670 sys_color_to_gtk_color (XP_THEME_CLASS_PROGRESS, COLOR_HIGHLIGHT,
673 /* Enable coloring for menus. */
675 sys_font_to_pango_font (XP_THEME_CLASS_MENU, XP_THEME_FONT_MENU,
676 font_buf, sizeof (font_buf));
677 g_snprintf (buf, sizeof (buf),
678 "style \"msw-menu\" = \"msw-default\"\n" "{\n"
679 "GtkMenuItem::toggle-spacing = 8\n"
680 "fg[PRELIGHT] = { %d, %d, %d }\n"
681 "bg[PRELIGHT] = { %d, %d, %d }\n"
682 "text[PRELIGHT] = { %d, %d, %d }\n"
683 "base[PRELIGHT] = { %d, %d, %d }\n"
684 "fg[NORMAL] = { %d, %d, %d }\n"
685 "bg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
686 "}widget_class \"*MenuItem*\" style \"msw-menu\"\n"
687 "widget_class \"*GtkMenu\" style \"msw-menu\"\n"
688 "widget_class \"*GtkMenuShell*\" style \"msw-menu\"\n",
689 fg_prelight.red, fg_prelight.green, fg_prelight.blue,
690 bg_prelight.red, bg_prelight.green, bg_prelight.blue,
691 text_prelight.red, text_prelight.green, text_prelight.blue,
692 base_prelight.red, base_prelight.green, base_prelight.blue,
693 menu_text_color.red, menu_text_color.green,
694 menu_text_color.blue, menu_color.red, menu_color.green,
695 menu_color.blue, (font_ptr ? "font_name" : "#"),
696 (font_ptr ? font_ptr : " font name should go here"));
697 gtk_rc_parse_string (buf);
699 if( xp_theme_is_active() ) {
700 *menu_bar_prelight_str = '\0';
703 g_snprintf(menu_bar_prelight_str, sizeof(menu_bar_prelight_str),
704 "fg[PRELIGHT] = { %d, %d, %d }\n",
705 menu_text_color.red, menu_text_color.green, menu_text_color.blue);
708 /* Enable coloring for menu bars. */
709 g_snprintf (buf, sizeof (buf),
710 "style \"msw-menu-bar\" = \"msw-menu\"\n"
712 "bg[NORMAL] = { %d, %d, %d }\n"
714 "GtkMenuBar::shadow-type = %d\n"
716 FIXME: This should be enabled once gtk+ support
717 GtkMenuBar::prelight-item style property.
719 /* "GtkMenuBar::prelight-item = 1\n" */
720 "}widget_class \"*MenuBar*\" style \"msw-menu-bar\"\n",
721 btn_face.red, btn_face.green, btn_face.blue,
722 menu_bar_prelight_str,
723 xp_theme_is_active() ? 0 : 2 );
724 gtk_rc_parse_string (buf);
726 g_snprintf (buf, sizeof (buf),
727 "style \"msw-toolbar\" = \"msw-default\"\n"
729 "GtkHandleBox::shadow-type = %s\n"
730 "GtkToolbar::shadow-type = %s\n"
731 "}widget_class \"*HandleBox*\" style \"msw-toolbar\"\n",
732 "etched-in", "etched-in");
733 gtk_rc_parse_string (buf);
735 /* enable tooltip fonts */
737 sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
738 font_buf, sizeof (font_buf));
739 g_snprintf (buf, sizeof (buf),
740 "style \"msw-tooltips-caption\" = \"msw-default\"\n"
741 "{fg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
742 "}widget \"gtk-tooltips.GtkLabel\" style \"msw-tooltips-caption\"\n",
743 tooltip_fore.red, tooltip_fore.green, tooltip_fore.blue,
744 (font_ptr ? "font_name" : "#"),
745 (font_ptr ? font_ptr : " font name should go here"));
746 gtk_rc_parse_string (buf);
748 g_snprintf (buf, sizeof (buf),
749 "style \"msw-tooltips\" = \"msw-default\"\n"
750 "{bg[NORMAL] = { %d, %d, %d }\n"
751 "}widget \"gtk-tooltips*\" style \"msw-tooltips\"\n",
752 tooltip_back.red, tooltip_back.green, tooltip_back.blue);
753 gtk_rc_parse_string (buf);
755 /* enable font theming for status bars */
757 sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
758 font_buf, sizeof (font_buf));
759 g_snprintf (buf, sizeof (buf),
760 "style \"msw-status\" = \"msw-default\"\n" "{%s = \"%s\"\n"
761 "bg[NORMAL] = { %d, %d, %d }\n"
762 "}widget_class \"*Status*\" style \"msw-status\"\n",
763 (font_ptr ? "font_name" : "#"),
764 (font_ptr ? font_ptr : " font name should go here"),
765 btn_face.red, btn_face.green, btn_face.blue);
766 gtk_rc_parse_string (buf);
768 /* enable coloring for text on buttons TODO: use GetThemeMetric for the
769 border and outside border */
770 g_snprintf (buf, sizeof (buf),
771 "style \"msw-button\" = \"msw-default\"\n"
773 "bg[NORMAL] = { %d, %d, %d }\n"
774 "bg[PRELIGHT] = { %d, %d, %d }\n"
775 "bg[INSENSITIVE] = { %d, %d, %d }\n"
776 "fg[PRELIGHT] = { %d, %d, %d }\n"
777 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
778 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
779 "GtkButton::child-displacement-x = 1\n"
780 "GtkButton::child-displacement-y = 1\n"
781 "GtkButton::focus-padding = %d\n"
782 "}widget_class \"*Button*\" style \"msw-button\"\n",
783 btn_face.red, btn_face.green, btn_face.blue,
784 btn_face.red, btn_face.green, btn_face.blue,
785 btn_face.red, btn_face.green, btn_face.blue,
786 btn_fore.red, btn_fore.green, btn_fore.blue,
787 xp_theme_is_active() ? 1 : 2 );
788 gtk_rc_parse_string (buf);
790 /* enable coloring for progress bars */
791 g_snprintf (buf, sizeof (buf),
792 "style \"msw-progress\" = \"msw-default\"\n"
793 "{bg[PRELIGHT] = { %d, %d, %d }\n"
794 "bg[NORMAL] = { %d, %d, %d }\n"
795 "}widget_class \"*Progress*\" style \"msw-progress\"\n",
799 btn_face.red, btn_face.green, btn_face.blue);
800 gtk_rc_parse_string (buf);
802 /* scrollbar thumb width and height */
803 g_snprintf (buf, sizeof (buf),
804 "style \"msw-vscrollbar\" = \"msw-default\"\n"
805 "{GtkRange::slider-width = %d\n"
806 "GtkRange::stepper-size = %d\n"
807 "GtkRange::stepper-spacing = 0\n"
808 "GtkRange::trough_border = 0\n"
809 "GtkScale::slider-length = %d\n"
810 "GtkScrollbar::min-slider-length = 8\n"
811 "}widget_class \"*VScrollbar*\" style \"msw-vscrollbar\"\n"
812 "widget_class \"*VScale*\" style \"msw-vscrollbar\"\n",
813 GetSystemMetrics (SM_CYVTHUMB),
814 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CXVSCROLL),
816 gtk_rc_parse_string (buf);
818 g_snprintf (buf, sizeof (buf),
819 "style \"msw-hscrollbar\" = \"msw-default\"\n"
820 "{GtkRange::slider-width = %d\n"
821 "GtkRange::stepper-size = %d\n"
822 "GtkRange::stepper-spacing = 0\n"
823 "GtkRange::trough_border = 0\n"
824 "GtkScale::slider-length = %d\n"
825 "GtkScrollbar::min-slider-length = 8\n"
826 "}widget_class \"*HScrollbar*\" style \"msw-hscrollbar\"\n"
827 "widget_class \"*HScale*\" style \"msw-hscrollbar\"\n",
828 GetSystemMetrics (SM_CXHTHUMB),
829 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CYHSCROLL),
831 gtk_rc_parse_string (buf);
833 gtk_rc_parse_string (
834 "style \"msw-scrolled-window\" = \"msw-default\"\n"
835 "{GtkScrolledWindow::scrollbars-within-bevel = 1}\n"
836 "class \"GtkScrolledWindow\" style \"msw-scrolled-window\"\n");
838 /* radio/check button sizes */
839 g_snprintf (buf, sizeof (buf),
840 "style \"msw-checkbutton\" = \"msw-button\"\n"
841 "{GtkCheckButton::indicator-size = 13\n"
842 "}widget_class \"*CheckButton*\" style \"msw-checkbutton\"\n"
843 "widget_class \"*RadioButton*\" style \"msw-checkbutton\"\n");
844 gtk_rc_parse_string (buf);
846 /* size of combo box toggle button */
847 g_snprintf (buf, sizeof(buf),
848 "style \"msw-combobox-button\" = \"msw-default\"\n"
852 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
853 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
854 "GtkButton::child-displacement-x = 0\n"
855 "GtkButton::child-displacement-y = 0\n"
856 "GtkWidget::focus-padding = 0\n"
857 "GtkWidget::focus-line-width = 0\n"
859 "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combobox-button\"\n");
860 gtk_rc_parse_string (buf);
862 g_snprintf (buf, sizeof(buf),
863 "style \"msw-combobox\" = \"msw-default\"\n"
865 "GtkComboBox::shadow-type = in\n"
869 "class \"GtkComboBox\" style \"msw-combobox\"\n",
870 GetSystemMetrics (SM_CXEDGE),
871 GetSystemMetrics (SM_CYEDGE));
872 gtk_rc_parse_string (buf);
874 /* size of tree view header */
875 g_snprintf (buf, sizeof(buf),
876 "style \"msw-header-button\" = \"msw-default\"\n"
880 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
881 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
882 "GtkButton::child-displacement-x = 1\n"
883 "GtkButton::child-displacement-y = 1\n"
884 "GtkWidget::focus-padding = 0\n"
885 "GtkWidget::focus-line-width = 0\n"
887 "widget_class \"*TreeView*Button*\" style \"msw-header-button\"\n",
888 xp_theme_is_active() ? 2 : 0 );
889 gtk_rc_parse_string (buf);
891 /* FIXME: This should be enabled once gtk+ support GtkNotebok::prelight-tab */
892 /* enable prelight tab of GtkNotebook */
894 g_snprintf (buf, sizeof (buf),
895 "style \"msw-notebook\" = \"msw-default\"\n"
896 "{GtkNotebook::prelight-tab=1\n"
897 "}widget_class \"*Notebook*\" style \"msw-notebook\"\n");
898 gtk_rc_parse_string (buf);
901 /* FIXME: This should be enabled once gtk+ support GtkTreeView::full-row-focus */
903 g_snprintf (buf, sizeof (buf),
904 "style \"msw-treeview\" = \"msw-default\"\n"
905 "{GtkTreeView::full-row-focus=0\n"
906 "}widget_class \"*TreeView*\" style \"msw-treeview\"\n");
907 gtk_rc_parse_string (buf);
912 setup_system_styles (GtkStyle * style)
916 /* Default background */
917 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
918 &style->bg[GTK_STATE_NORMAL]);
919 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
920 &style->bg[GTK_STATE_SELECTED]);
921 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
922 &style->bg[GTK_STATE_INSENSITIVE]);
923 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
924 &style->bg[GTK_STATE_ACTIVE]);
925 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
926 &style->bg[GTK_STATE_PRELIGHT]);
929 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
930 &style->base[GTK_STATE_NORMAL]);
931 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
932 &style->base[GTK_STATE_SELECTED]);
933 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
934 &style->base[GTK_STATE_INSENSITIVE]);
935 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
936 &style->base[GTK_STATE_ACTIVE]);
937 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
938 &style->base[GTK_STATE_PRELIGHT]);
941 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
942 &style->text[GTK_STATE_NORMAL]);
943 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
944 &style->text[GTK_STATE_SELECTED]);
945 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_GRAYTEXT,
946 &style->text[GTK_STATE_INSENSITIVE]);
947 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
948 &style->text[GTK_STATE_ACTIVE]);
949 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
950 &style->text[GTK_STATE_PRELIGHT]);
952 /* Default foreground */
953 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
954 &style->fg[GTK_STATE_NORMAL]);
955 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
956 &style->fg[GTK_STATE_SELECTED]);
957 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_GRAYTEXT,
958 &style->fg[GTK_STATE_INSENSITIVE]);
959 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
960 &style->fg[GTK_STATE_ACTIVE]);
961 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
962 &style->fg[GTK_STATE_PRELIGHT]);
964 for (i = 0; i < 5; i++)
966 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DSHADOW,
968 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DHILIGHT,
972 (style->light[i].red + style->dark[i].red) / 2;
973 style->mid[i].green =
974 (style->light[i].green + style->dark[i].green) / 2;
976 (style->light[i].blue + style->dark[i].blue) / 2;
978 style->text_aa[i].red =
979 (style->text[i].red + style->base[i].red) / 2;
980 style->text_aa[i].green =
981 (style->text[i].green + style->base[i].green) / 2;
982 style->text_aa[i].blue =
983 (style->text[i].blue + style->base[i].blue) / 2;
988 sanitize_size (GdkWindow * window, gint * width, gint * height)
990 gboolean set_bg = FALSE;
992 if ((*width == -1) && (*height == -1))
994 set_bg = GDK_IS_WINDOW (window);
995 gdk_drawable_get_size (window, width, height);
997 else if (*width == -1)
998 gdk_drawable_get_size (window, width, NULL);
999 else if (*height == -1)
1000 gdk_drawable_get_size (window, NULL, height);
1005 static XpThemeElement
1006 map_gtk_progress_bar_to_xp (GtkProgressBar * progress_bar, gboolean trough)
1010 switch (progress_bar->orientation)
1012 case GTK_PROGRESS_LEFT_TO_RIGHT:
1013 case GTK_PROGRESS_RIGHT_TO_LEFT:
1015 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_H
1016 : XP_THEME_ELEMENT_PROGRESS_BAR_H;
1020 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_V
1021 : XP_THEME_ELEMENT_PROGRESS_BAR_V;
1028 is_combo_box_child (GtkWidget* w)
1035 for (tmp = w->parent; tmp; tmp = tmp->parent)
1037 if (GTK_IS_COMBO_BOX(tmp))
1045 combo_box_draw_arrow (GtkStyle * style,
1048 GdkRectangle * area,
1051 if (xp_theme_is_active ())
1054 if (widget && GTK_IS_TOGGLE_BUTTON(widget->parent) )
1060 dc = get_window_dc( style, window, state, area->x, area->y, area->width, area->height, &rect );
1061 border = (GTK_TOGGLE_BUTTON(widget->parent)->active ? DFCS_PUSHED|DFCS_FLAT : 0);
1063 InflateRect( &rect, 1, 1 );
1064 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
1066 release_window_dc( style, window, state );
1074 draw_part (GdkDrawable * drawable,
1075 GdkGC * gc, GdkRectangle * area, gint x, gint y, Part part)
1078 gdk_gc_set_clip_rectangle (gc, area);
1080 if (!parts[part].bmap)
1081 parts[part].bmap = gdk_bitmap_create_from_data (drawable,
1083 PART_SIZE, PART_SIZE);
1085 gdk_gc_set_ts_origin (gc, x, y);
1086 gdk_gc_set_stipple (gc, parts[part].bmap);
1087 gdk_gc_set_fill (gc, GDK_STIPPLED);
1089 gdk_draw_rectangle (drawable, gc, TRUE, x, y, PART_SIZE, PART_SIZE);
1091 gdk_gc_set_fill (gc, GDK_SOLID);
1094 gdk_gc_set_clip_rectangle (gc, NULL);
1098 draw_check (GtkStyle * style,
1101 GtkShadowType shadow,
1102 GdkRectangle * area,
1104 const gchar * detail, gint x, gint y, gint width, gint height)
1106 x -= (1 + PART_SIZE - width) / 2;
1107 y -= (1 + PART_SIZE - height) / 2;
1109 if (detail && strcmp (detail, "check") == 0) /* Menu item */
1111 if (shadow == GTK_SHADOW_IN)
1113 draw_part (window, style->black_gc, area, x, y,
1115 draw_part (window, style->dark_gc[state], area, x, y,
1121 if (!xp_theme_draw (window, shadow == GTK_SHADOW_IN
1122 ? XP_THEME_ELEMENT_PRESSED_CHECKBOX
1123 : XP_THEME_ELEMENT_CHECKBOX,
1124 style, x, y, width, height, state, area))
1126 if( detail && !strcmp(detail, "cellcheck") )
1127 state = GTK_STATE_NORMAL;
1129 draw_part (window, style->black_gc, area, x, y,
1131 draw_part (window, style->dark_gc[state], area, x, y,
1133 draw_part (window, style->mid_gc[state], area, x, y,
1135 draw_part (window, style->light_gc[state], area, x, y,
1137 draw_part (window, style->base_gc[state], area, x, y,
1140 if (shadow == GTK_SHADOW_IN)
1142 draw_part (window, style->text_gc[state], area, x,
1144 draw_part (window, style->text_aa_gc[state], area,
1152 draw_expander (GtkStyle * style,
1155 GdkRectangle * area,
1157 const gchar * detail,
1158 gint x, gint y, GtkExpanderStyle expander_style)
1161 gint expander_semi_size;
1162 XpThemeElement xp_expander;
1164 gtk_widget_style_get (widget, "expander_size", &expander_size, NULL);
1166 switch (expander_style)
1168 case GTK_EXPANDER_COLLAPSED:
1169 case GTK_EXPANDER_SEMI_COLLAPSED:
1170 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED;
1173 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED;
1177 if ((expander_size % 2) == 0)
1180 if (expander_size > 2)
1184 gdk_gc_set_clip_rectangle (style->fg_gc[state], area);
1186 expander_semi_size = expander_size / 2;
1187 x -= expander_semi_size;
1188 y -= expander_semi_size;
1190 if (!xp_theme_draw (window, xp_expander, style,
1191 x, y, expander_size, expander_size, state, area))
1198 dc = get_window_dc( style, window, state, x, y, expander_size, expander_size, &rect );
1199 FrameRect( dc, &rect, GetSysColorBrush(COLOR_GRAYTEXT) );
1200 InflateRect( &rect, -1, -1 );
1201 FillRect( dc, &rect, GetSysColorBrush(state == GTK_STATE_INSENSITIVE ? COLOR_BTNFACE : COLOR_WINDOW) );
1203 InflateRect( &rect, -1, -1 );
1205 pen = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_WINDOWTEXT) );
1206 old_pen = SelectObject( dc, pen );
1208 MoveToEx( dc, rect.left, rect.top - 2 + expander_semi_size, NULL );
1209 LineTo( dc, rect.right, rect.top - 2 + expander_semi_size );
1211 if( expander_style == GTK_EXPANDER_COLLAPSED ||
1212 expander_style == GTK_EXPANDER_SEMI_COLLAPSED )
1214 MoveToEx( dc, rect.left - 2 + expander_semi_size, rect.top, NULL );
1215 LineTo( dc, rect.left - 2 + expander_semi_size, rect.bottom );
1218 SelectObject( dc, old_pen );
1219 DeleteObject( pen );
1220 release_window_dc( style, window, state );
1224 gdk_gc_set_clip_rectangle (style->fg_gc[state], NULL);
1228 draw_option (GtkStyle * style,
1231 GtkShadowType shadow,
1232 GdkRectangle * area,
1234 const gchar * detail, gint x, gint y, gint width, gint height)
1236 x -= (1 + PART_SIZE - width) / 2;
1237 y -= (1 + PART_SIZE - height) / 2;
1239 if (detail && strcmp (detail, "option") == 0) /* Menu item */
1241 if (shadow == GTK_SHADOW_IN)
1242 draw_part (window, style->fg_gc[state], area, x, y,
1247 if (xp_theme_draw (window, shadow == GTK_SHADOW_IN
1248 ? XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON
1249 : XP_THEME_ELEMENT_RADIO_BUTTON,
1250 style, x, y, width, height, state, area))
1255 if( detail && !strcmp(detail, "cellradio") )
1256 state = GTK_STATE_NORMAL;
1258 draw_part (window, style->black_gc, area, x, y,
1260 draw_part (window, style->dark_gc[state], area, x, y,
1262 draw_part (window, style->mid_gc[state], area, x, y,
1264 draw_part (window, style->light_gc[state], area, x, y,
1266 draw_part (window, style->base_gc[state], area, x, y,
1269 if (shadow == GTK_SHADOW_IN)
1270 draw_part (window, style->text_gc[state], area, x, y,
1277 draw_varrow (GdkWindow * window,
1279 GtkShadowType shadow_type,
1280 GdkRectangle * area,
1281 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1284 gint y_start, y_increment;
1288 gdk_gc_set_clip_rectangle (gc, area);
1290 width = width + width % 2 - 1; /* Force odd */
1291 steps = 1 + width / 2;
1292 extra = height - steps;
1294 if (arrow_type == GTK_ARROW_DOWN)
1301 y_start = y + height - 1;
1305 for (i = extra; i < height; i++)
1307 gdk_draw_line (window, gc,
1308 x + (i - extra), y_start + i * y_increment,
1309 x + width - (i - extra) - 1,
1310 y_start + i * y_increment);
1314 gdk_gc_set_clip_rectangle (gc, NULL);
1318 draw_harrow (GdkWindow * window,
1320 GtkShadowType shadow_type,
1321 GdkRectangle * area,
1322 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1325 gint x_start, x_increment;
1329 gdk_gc_set_clip_rectangle (gc, area);
1331 height = height + height % 2 - 1; /* Force odd */
1332 steps = 1 + height / 2;
1333 extra = width - steps;
1335 if (arrow_type == GTK_ARROW_RIGHT)
1342 x_start = x + width - 1;
1346 for (i = extra; i < width; i++)
1348 gdk_draw_line (window, gc,
1349 x_start + i * x_increment, y + (i - extra),
1350 x_start + i * x_increment,
1351 y + height - (i - extra) - 1);
1356 gdk_gc_set_clip_rectangle (gc, NULL);
1359 /* This function makes up for some brokeness in gtkrange.c
1360 * where we never get the full arrow of the stepper button
1361 * and the type of button in a single drawing function.
1363 * It doesn't work correctly when the scrollbar is squished
1364 * to the point we don't have room for full-sized steppers.
1367 reverse_engineer_stepper_box (GtkWidget * range,
1368 GtkArrowType arrow_type,
1369 gint * x, gint * y, gint * width, gint * height)
1371 gint slider_width = 14, stepper_size = 14;
1377 gtk_widget_style_get (range,
1378 "slider_width", &slider_width,
1379 "stepper_size", &stepper_size, NULL);
1382 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1384 box_width = slider_width;
1385 box_height = stepper_size;
1389 box_width = stepper_size;
1390 box_height = slider_width;
1393 *x = *x - (box_width - *width) / 2;
1394 *y = *y - (box_height - *height) / 2;
1396 *height = box_height;
1399 static XpThemeElement
1400 to_xp_arrow (GtkArrowType arrow_type)
1402 XpThemeElement xp_arrow;
1407 xp_arrow = XP_THEME_ELEMENT_ARROW_UP;
1409 case GTK_ARROW_DOWN:
1410 xp_arrow = XP_THEME_ELEMENT_ARROW_DOWN;
1412 case GTK_ARROW_LEFT:
1413 xp_arrow = XP_THEME_ELEMENT_ARROW_LEFT;
1416 xp_arrow = XP_THEME_ELEMENT_ARROW_RIGHT;
1424 draw_arrow (GtkStyle * style,
1427 GtkShadowType shadow,
1428 GdkRectangle * area,
1430 const gchar * detail,
1431 GtkArrowType arrow_type,
1432 gboolean fill, gint x, gint y, gint width, gint height)
1438 name = gtk_widget_get_name (widget);
1440 sanitize_size (window, &width, &height);
1442 if (GTK_IS_ARROW(widget) && is_combo_box_child(widget))
1444 if (combo_box_draw_arrow (style, window, state, area, widget))
1450 if (detail && strcmp (detail, "spinbutton") == 0)
1452 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1459 if( arrow_type == GTK_ARROW_DOWN )
1463 if( state == GTK_STATE_ACTIVE ) {
1467 draw_varrow (window, style->fg_gc[state], shadow, area,
1468 arrow_type, x, y, width, height);
1471 else if (detail && (!strcmp (detail, "vscrollbar")
1472 || !strcmp (detail, "hscrollbar")))
1474 gboolean is_disabled = FALSE;
1476 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1480 gint box_width = width;
1481 gint box_height = height;
1483 reverse_engineer_stepper_box (widget, arrow_type,
1484 &box_x, &box_y, &box_width,
1487 if (scrollbar->range.adjustment->page_size >=
1488 (scrollbar->range.adjustment->upper -
1489 scrollbar->range.adjustment->lower))
1493 (window, to_xp_arrow (arrow_type), style, box_x, box_y,
1494 box_width, box_height, state, area))
1502 btn_type = DFCS_SCROLLUP;
1504 case GTK_ARROW_DOWN:
1505 btn_type = DFCS_SCROLLDOWN;
1507 case GTK_ARROW_LEFT:
1508 btn_type = DFCS_SCROLLLEFT;
1510 case GTK_ARROW_RIGHT:
1511 btn_type = DFCS_SCROLLRIGHT;
1513 case GTK_ARROW_NONE:
1516 if( state == GTK_STATE_INSENSITIVE )
1517 btn_type |= DFCS_INACTIVE;
1519 sanitize_size (window, &width, &height);
1521 dc = get_window_dc( style, window, state,
1522 box_x, box_y, box_width, box_height, &rect );
1523 DrawFrameControl( dc, &rect, DFC_SCROLL,
1524 btn_type|(shadow == GTK_SHADOW_IN ? (DFCS_PUSHED|DFCS_FLAT) : 0) );
1525 release_window_dc( style, window, state );
1531 /* draw the toolbar chevrons - waiting for GTK 2.4 */
1532 if (name && !strcmp (name, "gtk-toolbar-arrow"))
1535 (window, XP_THEME_ELEMENT_REBAR_CHEVRON, style, x, y,
1536 width, height, state, area))
1539 /* probably a gtk combo box on a toolbar */
1540 else if (0 /* widget->parent && GTK_IS_BUTTON
1541 (widget->parent) */ )
1544 (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x - 3,
1545 widget->allocation.y + 1, width + 5,
1546 widget->allocation.height - 4, state, area))
1550 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1552 x += (width - 7) / 2;
1553 y += (height - 5) / 2;
1555 draw_varrow (window, style->fg_gc[state], shadow, area,
1556 arrow_type, x, y, 7, 5);
1560 x += (width - 5) / 2;
1561 y += (height - 7) / 2;
1563 draw_harrow (window, style->fg_gc[state], shadow, area,
1564 arrow_type, x, y, 5, 7);
1570 option_menu_get_props (GtkWidget * widget,
1571 GtkRequisition * indicator_size,
1572 GtkBorder * indicator_spacing)
1574 GtkRequisition *tmp_size = NULL;
1575 GtkBorder *tmp_spacing = NULL;
1578 gtk_widget_style_get (widget,
1579 "indicator_size", &tmp_size,
1580 "indicator_spacing", &tmp_spacing, NULL);
1584 *indicator_size = *tmp_size;
1588 *indicator_size = default_option_indicator_size;
1592 *indicator_spacing = *tmp_spacing;
1593 g_free (tmp_spacing);
1596 *indicator_spacing = default_option_indicator_spacing;
1600 is_toolbar_child (GtkWidget * wid)
1604 if (GTK_IS_TOOLBAR (wid) || GTK_IS_HANDLE_BOX (wid))
1614 is_menu_tool_button_child (GtkWidget * wid)
1618 if (GTK_IS_MENU_TOOL_BUTTON (wid) )
1626 HDC get_window_dc(GtkStyle * style, GdkWindow * window, GtkStateType state_type, gint x, gint y, gint width, gint height, RECT *rect)
1629 GdkDrawable *drawable;
1631 if (!GDK_IS_WINDOW (window))
1639 gdk_window_get_internal_paint_info (window, &drawable, &xoff, &yoff);
1642 rect->left = x - xoff;
1643 rect->top = y - yoff;
1644 rect->right = rect->left + width;
1645 rect->bottom = rect->top + height;
1647 return gdk_win32_hdc_get (drawable, style->dark_gc[state_type], 0);
1650 void release_window_dc(GtkStyle * style, GdkWindow * window, GtkStateType state_type)
1652 GdkDrawable *drawable;
1654 if (!GDK_IS_WINDOW (window))
1660 gdk_window_get_internal_paint_info (window, &drawable, NULL, NULL);
1663 gdk_win32_hdc_release (drawable, style->dark_gc[state_type], 0);
1666 static HPEN get_light_pen()
1668 if( ! g_light_pen ) {
1669 g_light_pen = CreatePen( PS_SOLID|PS_INSIDEFRAME, 1, GetSysColor(COLOR_BTNHIGHLIGHT) );
1674 static HPEN get_dark_pen()
1676 if( ! g_dark_pen ) {
1677 g_dark_pen = CreatePen( PS_SOLID|PS_INSIDEFRAME, 1, GetSysColor(COLOR_BTNSHADOW) );
1683 draw_3d_border( HDC hdc, RECT* rc, gboolean sunken )
1689 pen1 = get_dark_pen();
1690 pen2 = get_light_pen();
1693 pen1 = get_light_pen();
1694 pen2 = get_dark_pen();
1697 MoveToEx( hdc, rc->left, rc->bottom - 1, NULL);
1699 old_pen = SelectObject( hdc, pen1 );
1700 LineTo( hdc, rc->left, rc->top );
1701 LineTo( hdc, rc->right-1, rc->top );
1702 SelectObject( hdc, old_pen );
1704 old_pen = SelectObject( hdc, pen2 );
1705 LineTo( hdc, rc->right-1, rc->bottom-1 );
1706 LineTo( hdc, rc->left, rc->bottom-1 );
1707 SelectObject( hdc, old_pen );
1711 draw_menu_item(GdkWindow* window, GtkWidget* widget, GtkStyle* style,
1712 gint x, gint y, gint width, gint height,
1713 GtkStateType state_type, GdkRectangle* area )
1720 if( (parent = gtk_widget_get_parent(widget))
1721 && GTK_IS_MENU_BAR(parent)
1722 && !xp_theme_is_active() )
1724 bar = GTK_MENU_SHELL(parent);
1726 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1727 if( state_type == GTK_STATE_PRELIGHT ){
1728 draw_3d_border( dc, &rect, bar->active );
1730 release_window_dc( style, window, state_type );
1737 get_dither_brush( void )
1740 HBITMAP pattern_bmp;
1743 if( g_dither_brush )
1744 return g_dither_brush;
1745 for ( i = 0; i < 8; i++ )
1746 pattern[i] = (WORD)(0x5555 << (i & 1));
1747 pattern_bmp = CreateBitmap(8, 8, 1, 1, &pattern);
1749 g_dither_brush = CreatePatternBrush(pattern_bmp);
1750 DeleteObject(pattern_bmp);
1752 return g_dither_brush;
1756 draw_tool_button(GdkWindow* window, GtkWidget* widget, GtkStyle* style,
1757 gint x, gint y, gint width, gint height,
1758 GtkStateType state_type, GdkRectangle* area )
1762 gboolean is_toggled = FALSE;
1764 if ( xp_theme_is_active() ) {
1765 return (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
1766 x, y, width, height, state_type, area) );
1769 if( GTK_IS_TOGGLE_BUTTON(widget) ){
1770 if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ) {
1775 if( state_type != GTK_STATE_PRELIGHT
1776 && state_type != GTK_STATE_ACTIVE && !is_toggled )
1779 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1780 if( state_type == GTK_STATE_PRELIGHT ){
1782 FillRect( dc, &rect, GetSysColorBrush(COLOR_BTNFACE));
1784 draw_3d_border( dc, &rect, is_toggled);
1786 else if ( state_type == GTK_STATE_ACTIVE ){
1787 if( is_toggled && ! is_menu_tool_button_child(widget->parent) ){
1788 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
1789 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
1790 FillRect( dc, &rect, get_dither_brush() );
1792 draw_3d_border( dc, &rect, TRUE );
1794 release_window_dc( style, window, state_type );
1799 draw_push_button( GdkWindow* window, GtkWidget* widget, GtkStyle* style, gint x, gint y,
1800 gint width, gint height,
1801 GtkStateType state_type, gboolean is_default )
1806 dc = get_window_dc( style, window, state_type,
1807 x, y, width, height, &rect );
1808 if( GTK_IS_TOGGLE_BUTTON(widget) ) {
1809 if( state_type == GTK_STATE_PRELIGHT &&
1810 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) )
1812 state_type = GTK_STATE_ACTIVE;
1816 if( state_type == GTK_STATE_ACTIVE ) {
1817 if( GTK_IS_TOGGLE_BUTTON(widget) ) {
1818 DrawEdge( dc, &rect, EDGE_SUNKEN, BF_RECT|BF_ADJUST);
1819 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
1820 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
1821 FillRect( dc, &rect, get_dither_brush() );
1824 FrameRect( dc, &rect, GetSysColorBrush(COLOR_WINDOWFRAME) );
1825 InflateRect( &rect, -1, -1 );
1826 FrameRect( dc, &rect, GetSysColorBrush(COLOR_BTNSHADOW) );
1827 InflateRect( &rect, -1, -1 );
1828 FillRect( dc, &rect, GetSysColorBrush(COLOR_BTNFACE) );
1832 if( is_default || GTK_WIDGET_HAS_FOCUS(widget) ) {
1833 FrameRect( dc, &rect, GetSysColorBrush(COLOR_WINDOWFRAME) );
1834 InflateRect( &rect, -1, -1 );
1836 DrawFrameControl( dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH );
1838 release_window_dc(style, window, state_type);
1842 draw_box (GtkStyle * style,
1844 GtkStateType state_type,
1845 GtkShadowType shadow_type,
1846 GdkRectangle * area,
1848 const gchar * detail, gint x, gint y, gint width, gint height)
1850 if (is_combo_box_child (widget) && detail && !strcmp (detail, "button")) {
1855 dc = get_window_dc (style, window, state_type, x, y, width - cx, height, &rect);
1856 FillRect (dc, &rect, GetSysColorBrush(COLOR_WINDOW));
1857 release_window_dc (style, window, state_type);
1859 cx = 2 * GetSystemMetrics (SM_CXEDGE) + 16; /* TODO evaluate arrow width */
1863 if (xp_theme_is_active () && xp_theme_draw (
1864 window, XP_THEME_ELEMENT_COMBOBUTTON, style,
1865 x, y, width, height, state_type, area))
1870 (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
1872 if (GTK_IS_TREE_VIEW (widget->parent)
1873 || GTK_IS_CLIST (widget->parent))
1876 (window, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
1877 width, height, state_type, area))
1882 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1884 DrawFrameControl( dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH |
1885 (state_type == GTK_STATE_ACTIVE ? (DFCS_PUSHED|DFCS_FLAT) : 0 ) );
1886 release_window_dc( style, window, state_type );
1889 else if (is_toolbar_child (widget->parent)
1890 || (GTK_RELIEF_NONE == gtk_button_get_relief(GTK_BUTTON(widget)) ) )
1892 if( draw_tool_button( window, widget, style, x, y,
1893 width, height, state_type, area ) )
1900 gboolean is_default = GTK_WIDGET_HAS_DEFAULT(widget);
1903 is_default ? XP_THEME_ELEMENT_DEFAULT_BUTTON :
1904 XP_THEME_ELEMENT_BUTTON, style, x, y, width, height,
1909 draw_push_button( window, widget, style,
1910 x, y, width, height, state_type, is_default );
1915 else if (detail && !strcmp (detail, "spinbutton"))
1917 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1922 else if (detail && (!strcmp (detail, "spinbutton_up")
1923 || !strcmp (detail, "spinbutton_down")))
1925 if ( ! xp_theme_draw ( window,
1926 (!strcmp (detail, "spinbutton_up"))
1927 ? XP_THEME_ELEMENT_SPIN_BUTTON_UP
1928 : XP_THEME_ELEMENT_SPIN_BUTTON_DOWN,
1929 style, x, y, width, height, state_type, area))
1934 dc = get_window_dc( style, window, state_type,
1935 x, y, width, height, &rect );
1936 DrawEdge( dc, &rect,
1937 state_type == GTK_STATE_ACTIVE ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT );
1938 release_window_dc( style, window, state_type );
1942 else if (detail && !strcmp (detail, "slider"))
1944 if (GTK_IS_SCROLLBAR (widget))
1946 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1947 gboolean is_v = GTK_IS_VSCROLLBAR (widget);
1949 if (xp_theme_draw (window,
1951 ? XP_THEME_ELEMENT_SCROLLBAR_V
1952 : XP_THEME_ELEMENT_SCROLLBAR_H,
1953 style, x, y, width, height, state_type,
1956 XpThemeElement gripper =
1957 (is_v ? XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V :
1958 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H);
1960 /* Do not display grippers on tiny scroll bars,
1961 the limit imposed is rather arbitrary, perhaps
1962 we can fetch the gripper geometry from
1963 somewhere and use that... */
1965 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H
1968 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V
1974 xp_theme_draw (window, gripper, style, x, y,
1975 width, height, state_type, area);
1980 if (scrollbar->range.adjustment->page_size >=
1981 (scrollbar->range.adjustment->upper -
1982 scrollbar->range.adjustment->lower))
1987 else if (detail && !strcmp (detail, "bar"))
1989 if (widget && GTK_IS_PROGRESS_BAR (widget))
1991 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
1992 XpThemeElement xp_progress_bar =
1993 map_gtk_progress_bar_to_xp (progress_bar, FALSE);
1995 if (xp_theme_draw (window, xp_progress_bar, style, x, y,
1996 width, height, state_type, area))
2001 shadow_type = GTK_SHADOW_NONE;
2004 else if (detail && strcmp (detail, "menuitem") == 0)
2006 shadow_type = GTK_SHADOW_NONE;
2007 if( draw_menu_item(window, widget, style,
2008 x, y, width, height, state_type, area ) )
2013 else if (detail && !strcmp (detail, "trough"))
2015 if (widget && GTK_IS_PROGRESS_BAR (widget))
2017 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2018 XpThemeElement xp_progress_bar =
2019 map_gtk_progress_bar_to_xp (progress_bar, TRUE);
2021 (window, xp_progress_bar, style, x, y, width, height,
2028 /* Blank in classic Windows */
2031 else if (widget && GTK_IS_SCROLLBAR (widget))
2033 gboolean is_vertical = GTK_IS_VSCROLLBAR (widget);
2035 if (xp_theme_draw (window,
2037 ? XP_THEME_ELEMENT_TROUGH_V
2038 : XP_THEME_ELEMENT_TROUGH_H,
2040 x, y, width, height, state_type, area))
2049 sanitize_size (window, &width, &height);
2050 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2051 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
2052 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
2053 FillRect( dc, &rect, get_dither_brush() );
2054 release_window_dc( style, window, state_type );
2059 else if (widget && GTK_IS_SCALE (widget))
2061 gboolean is_vertical = GTK_IS_VSCALE (widget);
2063 if (!xp_theme_is_active ())
2065 parent_class->draw_box (style, window, state_type,
2066 GTK_SHADOW_NONE, area,
2067 widget, detail, x, y,
2074 (window, XP_THEME_ELEMENT_SCALE_TROUGH_V,
2075 style, (2 * x + width) / 2, y, 2, height,
2079 parent_class->draw_box (style, window, state_type,
2080 GTK_SHADOW_ETCHED_IN,
2082 (2 * x + width) / 2, y, 1,
2088 (window, XP_THEME_ELEMENT_SCALE_TROUGH_H,
2089 style, x, (2 * y + height) / 2, width, 2,
2093 parent_class->draw_box (style, window, state_type,
2094 GTK_SHADOW_ETCHED_IN,
2095 area, NULL, NULL, x,
2096 (2 * y + height) / 2,
2102 else if (detail && strcmp (detail, "optionmenu") == 0)
2104 if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
2105 style, x, y, width, height, state_type, area))
2111 && (strcmp (detail, "vscrollbar") == 0
2112 || strcmp (detail, "hscrollbar") == 0))
2117 && (strcmp (detail, "handlebox_bin") == 0
2118 || strcmp (detail, "toolbar") == 0
2119 || strcmp (detail, "menubar") == 0))
2121 sanitize_size( window, &width, &height );
2122 if (xp_theme_draw (window, XP_THEME_ELEMENT_REBAR,
2123 style, x, y, width, height, state_type, area))
2128 else if (detail && (!strcmp (detail, "handlebox"))) /* grip */
2130 if( !xp_theme_is_active() ) {
2136 const gchar *name = gtk_widget_get_name (widget);
2138 if (name && !strcmp (name, "gtk-tooltips"))
2141 (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
2142 height, state_type, area))
2152 hdc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2154 brush = GetSysColorBrush (COLOR_3DDKSHADOW);
2156 FrameRect (hdc, &rect, brush);
2157 InflateRect (&rect, -1, -1);
2158 FillRect (hdc, &rect,
2159 (HBRUSH) (COLOR_INFOBK + 1));
2161 release_window_dc (style, window, state_type);
2169 parent_class->draw_box (style, window, state_type, shadow_type, area,
2170 widget, detail, x, y, width, height);
2172 if (detail && strcmp (detail, "optionmenu") == 0)
2174 GtkRequisition indicator_size;
2175 GtkBorder indicator_spacing;
2178 option_menu_get_props (widget, &indicator_size,
2179 &indicator_spacing);
2181 sanitize_size (window, &width, &height);
2183 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
2185 x + indicator_size.width + indicator_spacing.left +
2186 indicator_spacing.right;
2189 x + width - (indicator_size.width +
2190 indicator_spacing.left +
2191 indicator_spacing.right) - style->xthickness;
2193 parent_class->draw_vline (style, window, state_type, area, widget,
2195 y + style->ythickness + 1,
2196 y + height - style->ythickness - 3,
2202 draw_tab (GtkStyle * style,
2205 GtkShadowType shadow,
2206 GdkRectangle * area,
2208 const gchar * detail, gint x, gint y, gint width, gint height)
2210 GtkRequisition indicator_size;
2211 GtkBorder indicator_spacing;
2215 g_return_if_fail (style != NULL);
2216 g_return_if_fail (window != NULL);
2218 if (detail && !strcmp (detail, "optionmenutab"))
2220 if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
2221 style, x - 5, widget->allocation.y + 1,
2222 width + 10, widget->allocation.height - 2,
2230 gtk_widget_style_get (widget, "indicator_size", &indicator_size,
2233 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2235 x += (width - indicator_size.width) / 2;
2236 arrow_height = (indicator_size.width + 1) / 2;
2238 y += (height - arrow_height) / 2;
2240 draw_varrow (window, style->black_gc, shadow, area, GTK_ARROW_DOWN,
2241 x, y, indicator_size.width, arrow_height);
2244 /* Draw classic Windows tab - thanks Mozilla!
2245 (no system API for this, but DrawEdge can draw all the parts of a tab) */
2246 static void DrawTab(HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
2247 gboolean aDrawLeft, gboolean aDrawRight)
2249 gint32 leftFlag, topFlag, rightFlag, lightFlag, shadeFlag;
2250 RECT topRect, sideRect, bottomRect, lightRect, shadeRect;
2251 gint32 selectedOffset, lOffset, rOffset;
2253 selectedOffset = aSelected ? 1 : 0;
2254 lOffset = aDrawLeft ? 2 : 0;
2255 rOffset = aDrawRight ? 2 : 0;
2257 /* Get info for tab orientation/position (Left, Top, Right, Bottom) */
2258 switch (aPosition) {
2260 leftFlag = BF_TOP; topFlag = BF_LEFT;
2261 rightFlag = BF_BOTTOM;
2262 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2263 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2265 SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
2266 SetRect(&sideRect, R.left+2, R.top, R.right-2+selectedOffset, R.bottom);
2267 SetRect(&bottomRect, R.right-2, R.top, R.right, R.bottom);
2268 SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
2269 SetRect(&shadeRect, R.left+1, R.bottom-2, R.left+2, R.bottom-1);
2272 leftFlag = BF_LEFT; topFlag = BF_TOP;
2273 rightFlag = BF_RIGHT;
2274 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2275 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2277 SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
2278 SetRect(&sideRect, R.left, R.top+2, R.right, R.bottom-1+selectedOffset);
2279 SetRect(&bottomRect, R.left, R.bottom-1, R.right, R.bottom);
2280 SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
2281 SetRect(&shadeRect, R.right-2, R.top+1, R.right-1, R.top+2);
2284 leftFlag = BF_TOP; topFlag = BF_RIGHT;
2285 rightFlag = BF_BOTTOM;
2286 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2287 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2289 SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
2290 SetRect(&sideRect, R.left+2-selectedOffset, R.top, R.right-2, R.bottom);
2291 SetRect(&bottomRect, R.left, R.top, R.left+2, R.bottom);
2292 SetRect(&lightRect, R.right-3, R.top, R.right-1, R.top+2);
2293 SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
2296 leftFlag = BF_LEFT; topFlag = BF_BOTTOM;
2297 rightFlag = BF_RIGHT;
2298 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2299 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2301 SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
2302 SetRect(&sideRect, R.left, R.top+2-selectedOffset, R.right, R.bottom-2);
2303 SetRect(&bottomRect, R.left, R.top, R.right, R.top+2);
2304 SetRect(&lightRect, R.left, R.bottom-3, R.left+2, R.bottom-1);
2305 SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
2308 g_return_if_reached();
2312 FillRect(hdc, &R, (HBRUSH) (COLOR_3DFACE+1) );
2315 DrawEdge(hdc, &topRect, EDGE_RAISED, BF_SOFT | topFlag);
2319 DrawEdge(hdc, &bottomRect, EDGE_RAISED, BF_SOFT | topFlag);
2326 DrawEdge(hdc, &sideRect, EDGE_RAISED, BF_SOFT | leftFlag | rightFlag);
2328 /* Tab Diagonal Corners */
2330 DrawEdge(hdc, &lightRect, EDGE_RAISED, BF_SOFT | lightFlag);
2333 DrawEdge(hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
2337 draw_extension (GtkStyle * style,
2339 GtkStateType state_type,
2340 GtkShadowType shadow_type,
2341 GdkRectangle * area,
2343 const gchar * detail,
2345 gint y, gint width, gint height, GtkPositionType gap_side)
2347 if (widget && GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "tab"))
2349 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2350 GdkPixmap *pixmap = NULL;
2351 GdkDrawable *target = NULL;
2352 gint x2 = 0, y2 = 0, w2 = width, h2 = height;
2353 int tab_part = XP_THEME_ELEMENT_TAB_ITEM;
2354 int real_gap_side = gtk_notebook_get_tab_pos (notebook);
2355 int border_width = gtk_container_get_border_width (GTK_CONTAINER (notebook));
2357 /* why this differs from the above gap_side, i have no idea... */
2358 if (real_gap_side == GTK_POS_LEFT)
2360 /* Create "rotated" pixmap.. swap width and height */
2361 pixmap = gdk_pixmap_new (window, height, width, -1);
2366 h2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2368 /* If we are currently rendering the bottom-most tab, and if that tab is the selected tab... */
2369 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2370 state_type == GTK_STATE_NORMAL)
2375 else if (real_gap_side == GTK_POS_RIGHT)
2377 /* Create "rotated" pixmap.. swap width and height */
2381 h2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2382 pixmap = gdk_pixmap_new (window, w2, h2, -1);
2385 /* If we are currently rendering the bottom-most tab, and if that tab is the selected tab... */
2386 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2387 state_type == GTK_STATE_NORMAL)
2392 else if (real_gap_side == GTK_POS_TOP)
2398 if (state_type == GTK_STATE_NORMAL)
2401 h2 = height - notebook->tab_vborder;
2403 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2404 if (widget->allocation.x + widget->allocation.width - border_width == x + width &&
2405 state_type == GTK_STATE_NORMAL)
2410 else if (real_gap_side == GTK_POS_BOTTOM)
2415 h2 = height - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_vborder * 2);
2416 pixmap = gdk_pixmap_new (window, w2, h2, -1);
2420 if (xp_theme_draw (target, tab_part, style, x2, y2, w2, h2, state_type, NULL /*area*/))
2422 GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
2423 if (real_gap_side == GTK_POS_BOTTOM)
2424 rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
2425 else if (real_gap_side == GTK_POS_LEFT)
2426 rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
2427 else if (real_gap_side == GTK_POS_RIGHT)
2428 rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
2430 if (rotation != GDK_PIXBUF_ROTATE_NONE)
2432 GdkPixbuf * pixbuf, * rotated;
2434 pixbuf = gdk_pixbuf_get_from_drawable (NULL, target, NULL, x2, y2, 0, 0, w2, h2);
2436 rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
2437 g_object_unref (pixbuf);
2440 if (real_gap_side == GTK_POS_RIGHT)
2442 x2 = x + (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2444 w2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2447 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2448 state_type == GTK_STATE_NORMAL)
2453 else if (real_gap_side == GTK_POS_LEFT)
2457 w2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2460 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2461 state_type == GTK_STATE_NORMAL)
2466 else if (real_gap_side == GTK_POS_BOTTOM)
2469 y2 = y + (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_vborder);
2471 h2 = height - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_vborder * 2);
2472 /* If we are currently drawing the right-most tab (any state)... */
2473 if (widget->allocation.x + widget->allocation.width - border_width == x + width)
2480 gdk_draw_pixbuf (window, NULL, pixbuf, 0, 0, x2, y2, w2, h2, GDK_RGB_DITHER_NONE, 0, 0);
2482 g_object_unref (G_OBJECT (pixbuf));
2484 if (real_gap_side == GTK_POS_LEFT || real_gap_side == GTK_POS_RIGHT || real_gap_side == GTK_POS_BOTTOM)
2486 g_object_unref (pixmap);
2490 } else if (real_gap_side == GTK_POS_TOP || real_gap_side == GTK_POS_BOTTOM) {
2491 /* experimental tab-drawing code from mozilla */
2496 if (real_gap_side == GTK_POS_BOTTOM)
2497 g_object_unref (pixmap);
2499 dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2501 if (real_gap_side == GTK_POS_TOP)
2503 else if (real_gap_side == GTK_POS_BOTTOM)
2504 aPosition = BF_BOTTOM;
2505 else if (real_gap_side == GTK_POS_LEFT)
2506 aPosition = BF_LEFT;
2508 aPosition = BF_RIGHT;
2510 if( state_type == GTK_STATE_PRELIGHT )
2511 state_type = GTK_STATE_NORMAL;
2513 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2514 DrawTab (dc, rect, aPosition, state_type != GTK_STATE_PRELIGHT, (real_gap_side != GTK_POS_LEFT), (real_gap_side != GTK_POS_RIGHT));
2516 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2518 release_window_dc (style, window, state_type);
2522 if (real_gap_side == GTK_POS_LEFT || real_gap_side == GTK_POS_RIGHT)
2523 g_object_unref (pixmap);
2525 parent_class->draw_extension
2526 (style, window, state_type, shadow_type, area, widget, detail,
2527 x, y, width, height, gap_side);
2531 draw_box_gap (GtkStyle * style, GdkWindow * window, GtkStateType state_type,
2532 GtkShadowType shadow_type, GdkRectangle * area,
2533 GtkWidget * widget, const gchar * detail, gint x,
2534 gint y, gint width, gint height, GtkPositionType gap_side,
2535 gint gap_x, gint gap_width)
2537 if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
2539 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2540 int side = gtk_notebook_get_tab_pos (notebook);
2541 int x2 = x, y2 = y, w2 = width, h2 = height;
2543 if (side == GTK_POS_TOP)
2546 y2 = y - notebook->tab_vborder;
2548 h2 = height + notebook->tab_vborder * 2;
2550 else if (side == GTK_POS_BOTTOM)
2555 h2 = height + notebook->tab_vborder * 2;
2557 else if (side == GTK_POS_LEFT)
2559 x2 = x - notebook->tab_hborder;
2561 w2 = width + notebook->tab_hborder;
2564 else if (side == GTK_POS_RIGHT)
2568 w2 = width + notebook->tab_hborder * 2;
2572 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2573 x2, y2, w2, h2, state_type, area))
2579 parent_class->draw_box_gap (style, window, state_type, shadow_type,
2580 area, widget, detail, x, y, width, height,
2581 gap_side, gap_x, gap_width);
2584 static gboolean is_popup_window_child( GtkWidget* widget )
2587 GtkWindowType type = -1;
2589 top = gtk_widget_get_toplevel( widget );
2590 if( top && GTK_IS_WINDOW(top) ) {
2591 g_object_get(top, "type", &type, NULL );
2592 if( type == GTK_WINDOW_POPUP ) { /* Hack for combo boxes */
2600 draw_flat_box (GtkStyle * style, GdkWindow * window,
2601 GtkStateType state_type, GtkShadowType shadow_type,
2602 GdkRectangle * area, GtkWidget * widget,
2603 const gchar * detail, gint x, gint y, gint width, gint height)
2606 if ( !strcmp (detail, "checkbutton") )
2608 if (state_type == GTK_STATE_PRELIGHT)
2615 parent_class->draw_flat_box (style, window, state_type, shadow_type,
2616 area, widget, detail, x, y, width, height);
2620 draw_menu_border ( GdkWindow* win, GtkStyle* style,
2621 gint x, gint y, gint width, gint height )
2626 dc = get_window_dc (style, win, GTK_STATE_NORMAL, x, y, width, height, &rect );
2629 if( xp_theme_is_active() ) {
2630 FrameRect( dc, &rect, GetSysColorBrush(COLOR_3DSHADOW) );
2633 DrawEdge( dc, &rect, EDGE_RAISED, BF_RECT );
2635 release_window_dc( style, win, GTK_STATE_NORMAL );
2640 draw_shadow (GtkStyle * style,
2642 GtkStateType state_type,
2643 GtkShadowType shadow_type,
2644 GdkRectangle * area,
2646 const gchar * detail, gint x, gint y, gint width, gint height)
2648 gboolean is_handlebox;
2649 gboolean is_toolbar;
2651 if( detail && !strcmp( detail, "frame") )
2655 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2656 if( is_popup_window_child(widget) ) {
2657 FrameRect( dc, &rect, GetSysColorBrush( COLOR_WINDOWFRAME ) );
2660 switch( shadow_type ){
2662 draw_3d_border(dc, &rect, TRUE);
2664 case GTK_SHADOW_OUT:
2665 draw_3d_border(dc, &rect, FALSE);
2667 case GTK_SHADOW_ETCHED_IN:
2668 draw_3d_border(dc, &rect, TRUE);
2669 InflateRect( &rect, -1, -1 );
2670 draw_3d_border(dc, &rect, FALSE);
2672 case GTK_SHADOW_ETCHED_OUT:
2673 draw_3d_border(dc, &rect, FALSE);
2674 InflateRect( &rect, -1, -1 );
2675 draw_3d_border(dc, &rect, TRUE);
2677 case GTK_SHADOW_NONE:
2681 release_window_dc( style, window, state_type );
2684 if (detail && (!strcmp (detail, "entry") || !strcmp (detail, "combobox")) )
2686 if( shadow_type != GTK_SHADOW_IN )
2689 if ( !xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2690 x, y, width, height, state_type, area))
2695 dc = get_window_dc (style, window, state_type,
2696 x, y, width, height, &rect);
2697 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
2698 release_window_dc (style, window, state_type);
2704 if (detail && !strcmp (detail, "scrolled_window") &&
2705 xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2706 x, y, width, height, state_type, area))
2709 if (detail && !strcmp (detail, "spinbutton"))
2712 if (detail && !strcmp (detail, "menu"))
2714 if ( draw_menu_border ( window, style, x, y, width, height ) ) {
2719 if (detail && !strcmp (detail, "handlebox"))
2722 is_handlebox = (detail && !strcmp (detail, "handlebox_bin"));
2723 is_toolbar = (detail && (!strcmp (detail, "toolbar") || !strcmp(detail, "menubar")));
2725 if ( is_toolbar || is_handlebox )
2730 HGDIOBJ old_pen = NULL;
2731 GtkPositionType pos;
2733 sanitize_size (window, &width, &height);
2735 if( is_handlebox ) {
2736 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
2738 If the handle box is at left side,
2739 we shouldn't draw its right border.
2740 The same holds true for top, right, and bottom.
2744 pos = GTK_POS_RIGHT; break;
2746 pos = GTK_POS_LEFT; break;
2748 pos = GTK_POS_BOTTOM; break;
2749 case GTK_POS_BOTTOM:
2750 pos = GTK_POS_TOP; break;
2754 GtkWidget* parent = gtk_widget_get_parent(widget);
2755 /* Dirty hack for toolbars contained in handle boxes */
2756 if( GTK_IS_HANDLE_BOX( parent ) ) {
2757 pos = gtk_handle_box_get_handle_position( GTK_HANDLE_BOX( parent ) );
2762 Make pos != all legal enum vaules of GtkPositionType.
2763 So every border will be draw.
2765 pos = (GtkPositionType)-1;
2769 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2770 if( pos != GTK_POS_LEFT ) {
2771 old_pen = SelectObject( dc, get_light_pen() );
2772 MoveToEx( dc, rect.left, rect.top, NULL );
2773 LineTo( dc, rect.left, rect.bottom );
2775 if( pos != GTK_POS_TOP ) {
2776 old_pen = SelectObject( dc, get_light_pen() );
2777 MoveToEx( dc, rect.left, rect.top, NULL );
2778 LineTo( dc, rect.right, rect.top );
2780 if( pos != GTK_POS_RIGHT ) {
2781 old_pen = SelectObject( dc, get_dark_pen() );
2782 MoveToEx( dc, rect.right-1, rect.top, NULL );
2783 LineTo( dc, rect.right-1, rect.bottom );
2785 if( pos != GTK_POS_BOTTOM ) {
2786 old_pen = SelectObject( dc, get_dark_pen() );
2787 MoveToEx( dc, rect.left, rect.bottom-1, NULL );
2788 LineTo( dc, rect.right, rect.bottom-1 );
2791 SelectObject( dc, old_pen );
2792 release_window_dc( style, window, state_type );
2797 if (detail && !strcmp (detail, "statusbar")) {
2801 parent_class->draw_shadow (style, window, state_type, shadow_type, area,
2802 widget, detail, x, y, width, height);
2806 draw_hline (GtkStyle * style,
2808 GtkStateType state_type,
2809 GdkRectangle * area,
2811 const gchar * detail, gint x1, gint x2, gint y)
2813 if (xp_theme_is_active () && detail && !strcmp(detail, "menuitem")) {
2814 if(xp_theme_draw (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, y, x2, 1, state_type, area))
2818 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2820 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2823 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2826 if( style->ythickness == 2 )
2830 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2831 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2833 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2835 gdk_draw_line (window, style->light_gc[state_type], x1, y, x2, y);
2838 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2839 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2844 parent_class->draw_hline (style, window, state_type, area, widget,
2851 draw_vline (GtkStyle * style,
2853 GtkStateType state_type,
2854 GdkRectangle * area,
2856 const gchar * detail, gint y1, gint y2, gint x)
2858 if( style->xthickness == 2 )
2862 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2863 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2865 gdk_draw_line (window, style->dark_gc[state_type], x, y1, x, y2);
2867 gdk_draw_line (window, style->light_gc[state_type], x, y1, x, y2);
2870 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2871 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2876 parent_class->draw_vline (style, window, state_type, area, widget,
2882 draw_slider (GtkStyle * style,
2884 GtkStateType state_type,
2885 GtkShadowType shadow_type,
2886 GdkRectangle * area,
2888 const gchar * detail,
2890 gint y, gint width, gint height, GtkOrientation orientation)
2892 if (GTK_IS_SCALE (widget) &&
2893 xp_theme_draw (window,
2895 GTK_ORIENTATION_VERTICAL) ?
2896 XP_THEME_ELEMENT_SCALE_SLIDER_V :
2897 XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
2898 height, state_type, area))
2903 parent_class->draw_slider (style, window, state_type, shadow_type, area,
2904 widget, detail, x, y, width, height,
2909 draw_resize_grip (GtkStyle * style,
2911 GtkStateType state_type,
2912 GdkRectangle * area,
2914 const gchar * detail,
2915 GdkWindowEdge edge, gint x, gint y, gint width, gint height)
2917 if (detail && !strcmp (detail, "statusbar"))
2920 (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
2921 height, state_type, area))
2925 HDC dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2928 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2929 DrawFrameControl(dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
2930 release_window_dc(style, window, state_type);
2932 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2937 parent_class->draw_resize_grip (style, window, state_type, area,
2938 widget, detail, edge, x, y, width,
2943 draw_handle (GtkStyle * style,
2945 GtkStateType state_type,
2946 GtkShadowType shadow_type,
2947 GdkRectangle * area,
2949 const gchar * detail,
2951 gint y, gint width, gint height, GtkOrientation orientation)
2956 if (is_toolbar_child (widget))
2958 XpThemeElement hndl;
2960 sanitize_size (window, &width, &height);
2962 if( GTK_IS_HANDLE_BOX(widget) ) {
2963 GtkPositionType pos;
2964 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
2965 if( pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM ) {
2966 orientation = GTK_ORIENTATION_HORIZONTAL;
2969 orientation = GTK_ORIENTATION_VERTICAL;
2973 if ( orientation == GTK_ORIENTATION_VERTICAL )
2974 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_V;
2976 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
2978 if (xp_theme_draw (window, hndl, style, x, y, width, height,
2984 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2985 if ( orientation == GTK_ORIENTATION_VERTICAL ) {
2987 rect.right = rect.left + 3;
2993 rect.bottom = rect.top + 3;
2997 draw_3d_border( dc, &rect, FALSE );
2998 release_window_dc( style, window, state_type );
3002 if (!GTK_IS_PANED (widget))
3004 gint xthick, ythick;
3005 GdkGC *light_gc, *dark_gc, *shadow_gc;
3008 sanitize_size (window, &width, &height);
3010 gtk_paint_box (style, window, state_type, shadow_type, area,
3011 widget, detail, x, y, width, height);
3013 light_gc = style->light_gc[state_type];
3014 dark_gc = style->dark_gc[state_type];
3015 shadow_gc = style->mid_gc[state_type];
3017 xthick = style->xthickness;
3018 ythick = style->ythickness;
3020 dest.x = x + xthick;
3021 dest.y = y + ythick;
3022 dest.width = width - (xthick * 2);
3023 dest.height = height - (ythick * 2);
3025 if (dest.width < dest.height)
3030 gdk_gc_set_clip_rectangle (light_gc, &dest);
3031 gdk_gc_set_clip_rectangle (dark_gc, &dest);
3032 gdk_gc_set_clip_rectangle (shadow_gc, &dest);
3034 if (dest.width < dest.height)
3036 gdk_draw_line (window, light_gc, dest.x, dest.y, dest.x,
3038 gdk_draw_line (window, dark_gc, dest.x + (dest.width / 2),
3039 dest.y, dest.x + (dest.width / 2),
3041 gdk_draw_line (window, shadow_gc, dest.x + dest.width,
3042 dest.y, dest.x + dest.width, dest.height);
3046 gdk_draw_line (window, light_gc, dest.x, dest.y,
3047 dest.x + dest.width, dest.y);
3048 gdk_draw_line (window, dark_gc, dest.x,
3049 dest.y + (dest.height / 2),
3050 dest.x + dest.width,
3051 dest.y + (dest.height / 2));
3052 gdk_draw_line (window, shadow_gc, dest.x,
3053 dest.y + dest.height, dest.x + dest.width,
3054 dest.y + dest.height);
3057 gdk_gc_set_clip_rectangle (shadow_gc, NULL);
3058 gdk_gc_set_clip_rectangle (light_gc, NULL);
3059 gdk_gc_set_clip_rectangle (dark_gc, NULL);
3064 draw_focus ( GtkStyle *style,
3066 GtkStateType state_type,
3069 const gchar *detail,
3077 if( !GTK_WIDGET_CAN_FOCUS(widget) ) {
3080 if( detail && 0 == strcmp(detail, "button")
3081 && GTK_RELIEF_NONE == gtk_button_get_relief( GTK_BUTTON(widget) ) )
3085 if ( is_combo_box_child(widget)
3086 && (GTK_IS_ARROW(widget) || GTK_IS_BUTTON(widget)) ) {
3089 if (GTK_IS_TREE_VIEW (widget->parent) /* list view bheader */
3090 || GTK_IS_CLIST (widget->parent)) {
3094 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
3095 DrawFocusRect(dc, &rect);
3096 release_window_dc( style, window, state_type );
3098 parent_class->draw_focus (style, window, state_type,
3099 area, widget, detail, x, y, width, height);
3104 msw_style_init_from_rc (GtkStyle * style, GtkRcStyle * rc_style)
3106 setup_system_font (style);
3107 setup_menu_settings (gtk_settings_get_default ());
3108 setup_system_styles (style);
3109 parent_class->init_from_rc (style, rc_style);
3113 load_bg_image (GdkColormap *colormap,
3115 const gchar *filename)
3117 if (strcmp (filename, "<parent>") == 0)
3118 return (GdkPixmap*) GDK_PARENT_RELATIVE;
3121 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
3128 msw_style_realize (GtkStyle * style)
3130 GdkGCValues gc_values;
3131 GdkGCValuesMask gc_values_mask;
3135 for (i = 0; i < 5; i++)
3137 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
3138 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
3139 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
3141 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
3142 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
3143 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
3146 style->black.red = 0x0000;
3147 style->black.green = 0x0000;
3148 style->black.blue = 0x0000;
3149 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
3151 style->white.red = 0xffff;
3152 style->white.green = 0xffff;
3153 style->white.blue = 0xffff;
3154 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
3156 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
3158 gc_values.foreground = style->black;
3159 gc_values.background = style->white;
3160 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3162 gc_values.foreground = style->white;
3163 gc_values.background = style->black;
3164 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3166 gc_values_mask = GDK_GC_FOREGROUND;
3168 for (i = 0; i < 5; i++)
3170 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
3171 style->bg_pixmap[i] = load_bg_image (style->colormap,
3173 style->rc_style->bg_pixmap_name[i]);
3175 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
3176 g_warning ("unable to allocate color: ( %d %d %d )",
3177 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
3178 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
3179 g_warning ("unable to allocate color: ( %d %d %d )",
3180 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
3181 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
3182 g_warning ("unable to allocate color: ( %d %d %d )",
3183 style->light[i].red, style->light[i].green, style->light[i].blue);
3184 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
3185 g_warning ("unable to allocate color: ( %d %d %d )",
3186 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
3187 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
3188 g_warning ("unable to allocate color: ( %d %d %d )",
3189 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
3190 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
3191 g_warning ("unable to allocate color: ( %d %d %d )",
3192 style->text[i].red, style->text[i].green, style->text[i].blue);
3193 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
3194 g_warning ("unable to allocate color: ( %d %d %d )",
3195 style->base[i].red, style->base[i].green, style->base[i].blue);
3196 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
3197 g_warning ("unable to allocate color: ( %d %d %d )",
3198 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
3200 gc_values.foreground = style->fg[i];
3201 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3203 gc_values.foreground = style->bg[i];
3204 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3206 gc_values.foreground = style->light[i];
3207 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3209 gc_values.foreground = style->dark[i];
3210 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3212 gc_values.foreground = style->mid[i];
3213 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3215 gc_values.foreground = style->text[i];
3216 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3218 gc_values.foreground = style->base[i];
3219 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3221 gc_values.foreground = style->text_aa[i];
3222 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3227 msw_style_unrealize (GtkStyle * style)
3229 parent_class->unrealize (style);
3233 msw_style_class_init (MswStyleClass * klass)
3235 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3237 parent_class = g_type_class_peek_parent (klass);
3239 style_class->init_from_rc = msw_style_init_from_rc;
3240 style_class->draw_arrow = draw_arrow;
3241 style_class->draw_box = draw_box;
3242 style_class->draw_check = draw_check;
3243 style_class->draw_option = draw_option;
3244 style_class->draw_tab = draw_tab;
3245 style_class->draw_flat_box = draw_flat_box;
3246 style_class->draw_expander = draw_expander;
3247 style_class->draw_extension = draw_extension;
3248 style_class->draw_box_gap = draw_box_gap;
3249 style_class->draw_shadow = draw_shadow;
3250 style_class->draw_hline = draw_hline;
3251 style_class->draw_vline = draw_vline;
3252 style_class->draw_handle = draw_handle;
3253 style_class->draw_resize_grip = draw_resize_grip;
3254 style_class->draw_slider = draw_slider;
3255 style_class->draw_focus = draw_focus;
3257 style_class->realize = msw_style_realize;
3258 style_class->unrealize = msw_style_unrealize;
3261 GType msw_type_style = 0;
3264 msw_style_register_type (GTypeModule * module)
3266 static const GTypeInfo object_info = {
3267 sizeof (MswStyleClass),
3268 (GBaseInitFunc) NULL,
3269 (GBaseFinalizeFunc) NULL,
3270 (GClassInitFunc) msw_style_class_init,
3271 NULL, /* class_finalize */
3272 NULL, /* class_data */
3274 0, /* n_preallocs */
3275 (GInstanceInitFunc) NULL,
3278 msw_type_style = g_type_module_register_type (module,
3285 msw_style_init (void)
3288 msw_style_setup_system_settings ();
3289 setup_msw_rc_style ();
3292 DeleteObject( g_light_pen );
3296 DeleteObject( g_dark_pen );
3301 void msw_style_finalize(void)
3303 if( g_dither_brush ){
3304 DeleteObject( g_dither_brush );
3307 DeleteObject( g_light_pen );
3310 DeleteObject( g_dark_pen );