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 ( xp_theme_is_active() ) {
1721 return xp_theme_draw( window, XP_THEME_ELEMENT_MENU_ITEM, style,
1722 x, y, width, height, state_type, area );
1725 if( (parent = gtk_widget_get_parent(widget))
1726 && GTK_IS_MENU_BAR(parent) )
1728 bar = GTK_MENU_SHELL(parent);
1730 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1731 if( state_type == GTK_STATE_PRELIGHT ){
1732 draw_3d_border( dc, &rect, bar->active );
1734 release_window_dc( style, window, state_type );
1741 get_dither_brush( void )
1744 HBITMAP pattern_bmp;
1747 if( g_dither_brush )
1748 return g_dither_brush;
1749 for ( i = 0; i < 8; i++ )
1750 pattern[i] = (WORD)(0x5555 << (i & 1));
1751 pattern_bmp = CreateBitmap(8, 8, 1, 1, &pattern);
1753 g_dither_brush = CreatePatternBrush(pattern_bmp);
1754 DeleteObject(pattern_bmp);
1756 return g_dither_brush;
1760 draw_tool_button(GdkWindow* window, GtkWidget* widget, GtkStyle* style,
1761 gint x, gint y, gint width, gint height,
1762 GtkStateType state_type, GdkRectangle* area )
1766 gboolean is_toggled = FALSE;
1768 if ( xp_theme_is_active() ) {
1769 return (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
1770 x, y, width, height, state_type, area) );
1773 if( GTK_IS_TOGGLE_BUTTON(widget) ){
1774 if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ) {
1779 if( state_type != GTK_STATE_PRELIGHT
1780 && state_type != GTK_STATE_ACTIVE && !is_toggled )
1783 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1784 if( state_type == GTK_STATE_PRELIGHT ){
1786 FillRect( dc, &rect, GetSysColorBrush(COLOR_BTNFACE));
1788 draw_3d_border( dc, &rect, is_toggled);
1790 else if ( state_type == GTK_STATE_ACTIVE ){
1791 if( is_toggled && ! is_menu_tool_button_child(widget->parent) ){
1792 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
1793 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
1794 FillRect( dc, &rect, get_dither_brush() );
1796 draw_3d_border( dc, &rect, TRUE );
1798 release_window_dc( style, window, state_type );
1803 draw_push_button( GdkWindow* window, GtkWidget* widget, GtkStyle* style, gint x, gint y,
1804 gint width, gint height,
1805 GtkStateType state_type, gboolean is_default )
1810 dc = get_window_dc( style, window, state_type,
1811 x, y, width, height, &rect );
1812 if( GTK_IS_TOGGLE_BUTTON(widget) ) {
1813 if( state_type == GTK_STATE_PRELIGHT &&
1814 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) )
1816 state_type = GTK_STATE_ACTIVE;
1820 if( state_type == GTK_STATE_ACTIVE ) {
1821 if( GTK_IS_TOGGLE_BUTTON(widget) ) {
1822 DrawEdge( dc, &rect, EDGE_SUNKEN, BF_RECT|BF_ADJUST);
1823 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
1824 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
1825 FillRect( dc, &rect, get_dither_brush() );
1828 FrameRect( dc, &rect, GetSysColorBrush(COLOR_WINDOWFRAME) );
1829 InflateRect( &rect, -1, -1 );
1830 FrameRect( dc, &rect, GetSysColorBrush(COLOR_BTNSHADOW) );
1831 InflateRect( &rect, -1, -1 );
1832 FillRect( dc, &rect, GetSysColorBrush(COLOR_BTNFACE) );
1836 if( is_default || GTK_WIDGET_HAS_FOCUS(widget) ) {
1837 FrameRect( dc, &rect, GetSysColorBrush(COLOR_WINDOWFRAME) );
1838 InflateRect( &rect, -1, -1 );
1840 DrawFrameControl( dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH );
1842 release_window_dc(style, window, state_type);
1846 draw_box (GtkStyle * style,
1848 GtkStateType state_type,
1849 GtkShadowType shadow_type,
1850 GdkRectangle * area,
1852 const gchar * detail, gint x, gint y, gint width, gint height)
1854 if (is_combo_box_child (widget) && detail && !strcmp (detail, "button")) {
1859 dc = get_window_dc (style, window, state_type, x, y, width - cx, height, &rect);
1860 FillRect (dc, &rect, GetSysColorBrush(COLOR_WINDOW));
1861 release_window_dc (style, window, state_type);
1863 cx = 2 * GetSystemMetrics (SM_CXEDGE) + 16; /* TODO evaluate arrow width */
1867 if (xp_theme_is_active () && xp_theme_draw (
1868 window, XP_THEME_ELEMENT_COMBOBUTTON, style,
1869 x, y, width, height, state_type, area))
1874 (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
1876 if (GTK_IS_TREE_VIEW (widget->parent)
1877 || GTK_IS_CLIST (widget->parent))
1880 (window, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
1881 width, height, state_type, area))
1886 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1888 DrawFrameControl( dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH |
1889 (state_type == GTK_STATE_ACTIVE ? (DFCS_PUSHED|DFCS_FLAT) : 0 ) );
1890 release_window_dc( style, window, state_type );
1893 else if (is_toolbar_child (widget->parent)
1894 || (GTK_RELIEF_NONE == gtk_button_get_relief(GTK_BUTTON(widget)) ) )
1896 if( draw_tool_button( window, widget, style, x, y,
1897 width, height, state_type, area ) )
1904 gboolean is_default = GTK_WIDGET_HAS_DEFAULT(widget);
1907 is_default ? XP_THEME_ELEMENT_DEFAULT_BUTTON :
1908 XP_THEME_ELEMENT_BUTTON, style, x, y, width, height,
1913 draw_push_button( window, widget, style,
1914 x, y, width, height, state_type, is_default );
1919 else if (detail && !strcmp (detail, "spinbutton"))
1921 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1926 else if (detail && (!strcmp (detail, "spinbutton_up")
1927 || !strcmp (detail, "spinbutton_down")))
1929 if ( ! xp_theme_draw ( window,
1930 (!strcmp (detail, "spinbutton_up"))
1931 ? XP_THEME_ELEMENT_SPIN_BUTTON_UP
1932 : XP_THEME_ELEMENT_SPIN_BUTTON_DOWN,
1933 style, x, y, width, height, state_type, area))
1938 dc = get_window_dc( style, window, state_type,
1939 x, y, width, height, &rect );
1940 DrawEdge( dc, &rect,
1941 state_type == GTK_STATE_ACTIVE ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT );
1942 release_window_dc( style, window, state_type );
1946 else if (detail && !strcmp (detail, "slider"))
1948 if (GTK_IS_SCROLLBAR (widget))
1950 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1951 gboolean is_v = GTK_IS_VSCROLLBAR (widget);
1953 if (xp_theme_draw (window,
1955 ? XP_THEME_ELEMENT_SCROLLBAR_V
1956 : XP_THEME_ELEMENT_SCROLLBAR_H,
1957 style, x, y, width, height, state_type,
1960 XpThemeElement gripper =
1961 (is_v ? XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V :
1962 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H);
1964 /* Do not display grippers on tiny scroll bars,
1965 the limit imposed is rather arbitrary, perhaps
1966 we can fetch the gripper geometry from
1967 somewhere and use that... */
1969 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H
1972 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V
1978 xp_theme_draw (window, gripper, style, x, y,
1979 width, height, state_type, area);
1984 if (scrollbar->range.adjustment->page_size >=
1985 (scrollbar->range.adjustment->upper -
1986 scrollbar->range.adjustment->lower))
1991 else if (detail && !strcmp (detail, "bar"))
1993 if (widget && GTK_IS_PROGRESS_BAR (widget))
1995 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
1996 XpThemeElement xp_progress_bar =
1997 map_gtk_progress_bar_to_xp (progress_bar, FALSE);
1999 if (xp_theme_draw (window, xp_progress_bar, style, x, y,
2000 width, height, state_type, area))
2005 shadow_type = GTK_SHADOW_NONE;
2008 else if (detail && strcmp (detail, "menuitem") == 0)
2010 shadow_type = GTK_SHADOW_NONE;
2011 if( draw_menu_item(window, widget, style,
2012 x, y, width, height, state_type, area ) )
2017 else if (detail && !strcmp (detail, "trough"))
2019 if (widget && GTK_IS_PROGRESS_BAR (widget))
2021 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2022 XpThemeElement xp_progress_bar =
2023 map_gtk_progress_bar_to_xp (progress_bar, TRUE);
2025 (window, xp_progress_bar, style, x, y, width, height,
2032 /* Blank in classic Windows */
2035 else if (widget && GTK_IS_SCROLLBAR (widget))
2037 gboolean is_vertical = GTK_IS_VSCROLLBAR (widget);
2039 if (xp_theme_draw (window,
2041 ? XP_THEME_ELEMENT_TROUGH_V
2042 : XP_THEME_ELEMENT_TROUGH_H,
2044 x, y, width, height, state_type, area))
2053 sanitize_size (window, &width, &height);
2054 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2055 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
2056 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
2057 FillRect( dc, &rect, get_dither_brush() );
2058 release_window_dc( style, window, state_type );
2063 else if (widget && GTK_IS_SCALE (widget))
2065 gboolean is_vertical = GTK_IS_VSCALE (widget);
2067 if (!xp_theme_is_active ())
2069 parent_class->draw_box (style, window, state_type,
2070 GTK_SHADOW_NONE, area,
2071 widget, detail, x, y,
2078 (window, XP_THEME_ELEMENT_SCALE_TROUGH_V,
2079 style, (2 * x + width) / 2, y, 2, height,
2083 parent_class->draw_box (style, window, state_type,
2084 GTK_SHADOW_ETCHED_IN,
2086 (2 * x + width) / 2, y, 1,
2092 (window, XP_THEME_ELEMENT_SCALE_TROUGH_H,
2093 style, x, (2 * y + height) / 2, width, 2,
2097 parent_class->draw_box (style, window, state_type,
2098 GTK_SHADOW_ETCHED_IN,
2099 area, NULL, NULL, x,
2100 (2 * y + height) / 2,
2106 else if (detail && strcmp (detail, "optionmenu") == 0)
2108 if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
2109 style, x, y, width, height, state_type, area))
2115 && (strcmp (detail, "vscrollbar") == 0
2116 || strcmp (detail, "hscrollbar") == 0))
2121 && (strcmp (detail, "handlebox_bin") == 0
2122 || strcmp (detail, "toolbar") == 0
2123 || strcmp (detail, "menubar") == 0))
2125 sanitize_size( window, &width, &height );
2126 if (xp_theme_draw (window, XP_THEME_ELEMENT_REBAR,
2127 style, x, y, width, height, state_type, area))
2132 else if (detail && (!strcmp (detail, "handlebox"))) /* grip */
2134 if( !xp_theme_is_active() ) {
2140 const gchar *name = gtk_widget_get_name (widget);
2142 if (name && !strcmp (name, "gtk-tooltips"))
2145 (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
2146 height, state_type, area))
2156 hdc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2158 brush = GetSysColorBrush (COLOR_3DDKSHADOW);
2160 FrameRect (hdc, &rect, brush);
2161 InflateRect (&rect, -1, -1);
2162 FillRect (hdc, &rect,
2163 (HBRUSH) (COLOR_INFOBK + 1));
2165 release_window_dc (style, window, state_type);
2173 parent_class->draw_box (style, window, state_type, shadow_type, area,
2174 widget, detail, x, y, width, height);
2176 if (detail && strcmp (detail, "optionmenu") == 0)
2178 GtkRequisition indicator_size;
2179 GtkBorder indicator_spacing;
2182 option_menu_get_props (widget, &indicator_size,
2183 &indicator_spacing);
2185 sanitize_size (window, &width, &height);
2187 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
2189 x + indicator_size.width + indicator_spacing.left +
2190 indicator_spacing.right;
2193 x + width - (indicator_size.width +
2194 indicator_spacing.left +
2195 indicator_spacing.right) - style->xthickness;
2197 parent_class->draw_vline (style, window, state_type, area, widget,
2199 y + style->ythickness + 1,
2200 y + height - style->ythickness - 3,
2206 draw_tab (GtkStyle * style,
2209 GtkShadowType shadow,
2210 GdkRectangle * area,
2212 const gchar * detail, gint x, gint y, gint width, gint height)
2214 GtkRequisition indicator_size;
2215 GtkBorder indicator_spacing;
2219 g_return_if_fail (style != NULL);
2220 g_return_if_fail (window != NULL);
2222 if (detail && !strcmp (detail, "optionmenutab"))
2224 if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
2225 style, x - 5, widget->allocation.y + 1,
2226 width + 10, widget->allocation.height - 2,
2234 gtk_widget_style_get (widget, "indicator_size", &indicator_size,
2237 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2239 x += (width - indicator_size.width) / 2;
2240 arrow_height = (indicator_size.width + 1) / 2;
2242 y += (height - arrow_height) / 2;
2244 draw_varrow (window, style->black_gc, shadow, area, GTK_ARROW_DOWN,
2245 x, y, indicator_size.width, arrow_height);
2248 /* Draw classic Windows tab - thanks Mozilla!
2249 (no system API for this, but DrawEdge can draw all the parts of a tab) */
2250 static void DrawTab(HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
2251 gboolean aDrawLeft, gboolean aDrawRight)
2253 gint32 leftFlag, topFlag, rightFlag, lightFlag, shadeFlag;
2254 RECT topRect, sideRect, bottomRect, lightRect, shadeRect;
2255 gint32 selectedOffset, lOffset, rOffset;
2257 selectedOffset = aSelected ? 1 : 0;
2258 lOffset = aDrawLeft ? 2 : 0;
2259 rOffset = aDrawRight ? 2 : 0;
2261 /* Get info for tab orientation/position (Left, Top, Right, Bottom) */
2262 switch (aPosition) {
2264 leftFlag = BF_TOP; topFlag = BF_LEFT;
2265 rightFlag = BF_BOTTOM;
2266 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2267 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2269 SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
2270 SetRect(&sideRect, R.left+2, R.top, R.right-2+selectedOffset, R.bottom);
2271 SetRect(&bottomRect, R.right-2, R.top, R.right, R.bottom);
2272 SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
2273 SetRect(&shadeRect, R.left+1, R.bottom-2, R.left+2, R.bottom-1);
2276 leftFlag = BF_LEFT; topFlag = BF_TOP;
2277 rightFlag = BF_RIGHT;
2278 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2279 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2281 SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
2282 SetRect(&sideRect, R.left, R.top+2, R.right, R.bottom-1+selectedOffset);
2283 SetRect(&bottomRect, R.left, R.bottom-1, R.right, R.bottom);
2284 SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
2285 SetRect(&shadeRect, R.right-2, R.top+1, R.right-1, R.top+2);
2288 leftFlag = BF_TOP; topFlag = BF_RIGHT;
2289 rightFlag = BF_BOTTOM;
2290 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2291 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2293 SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
2294 SetRect(&sideRect, R.left+2-selectedOffset, R.top, R.right-2, R.bottom);
2295 SetRect(&bottomRect, R.left, R.top, R.left+2, R.bottom);
2296 SetRect(&lightRect, R.right-3, R.top, R.right-1, R.top+2);
2297 SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
2300 leftFlag = BF_LEFT; topFlag = BF_BOTTOM;
2301 rightFlag = BF_RIGHT;
2302 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2303 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2305 SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
2306 SetRect(&sideRect, R.left, R.top+2-selectedOffset, R.right, R.bottom-2);
2307 SetRect(&bottomRect, R.left, R.top, R.right, R.top+2);
2308 SetRect(&lightRect, R.left, R.bottom-3, R.left+2, R.bottom-1);
2309 SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
2312 g_return_if_reached();
2316 FillRect(hdc, &R, (HBRUSH) (COLOR_3DFACE+1) );
2319 DrawEdge(hdc, &topRect, EDGE_RAISED, BF_SOFT | topFlag);
2323 DrawEdge(hdc, &bottomRect, EDGE_RAISED, BF_SOFT | topFlag);
2330 DrawEdge(hdc, &sideRect, EDGE_RAISED, BF_SOFT | leftFlag | rightFlag);
2332 /* Tab Diagonal Corners */
2334 DrawEdge(hdc, &lightRect, EDGE_RAISED, BF_SOFT | lightFlag);
2337 DrawEdge(hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
2341 draw_extension (GtkStyle * style,
2343 GtkStateType state_type,
2344 GtkShadowType shadow_type,
2345 GdkRectangle * area,
2347 const gchar * detail,
2349 gint y, gint width, gint height, GtkPositionType gap_side)
2351 if (widget && GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "tab"))
2353 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2354 GdkPixmap *pixmap = NULL;
2355 GdkDrawable *target = NULL;
2356 gint x2 = 0, y2 = 0, w2 = width, h2 = height;
2357 int tab_part = XP_THEME_ELEMENT_TAB_ITEM;
2358 int real_gap_side = gtk_notebook_get_tab_pos (notebook);
2359 int border_width = gtk_container_get_border_width (GTK_CONTAINER (notebook));
2361 /* why this differs from the above gap_side, i have no idea... */
2362 if (real_gap_side == GTK_POS_LEFT)
2364 /* Create "rotated" pixmap.. swap width and height */
2365 pixmap = gdk_pixmap_new (window, height, width, -1);
2370 h2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2372 /* If we are currently rendering the bottom-most tab, and if that tab is the selected tab... */
2373 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2374 state_type == GTK_STATE_NORMAL)
2379 else if (real_gap_side == GTK_POS_RIGHT)
2381 /* Create "rotated" pixmap.. swap width and height */
2385 h2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2386 pixmap = gdk_pixmap_new (window, w2, h2, -1);
2389 /* If we are currently rendering the bottom-most tab, and if that tab is the selected tab... */
2390 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2391 state_type == GTK_STATE_NORMAL)
2396 else if (real_gap_side == GTK_POS_TOP)
2402 if (state_type == GTK_STATE_NORMAL)
2405 h2 = height - notebook->tab_vborder;
2407 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2408 if (widget->allocation.x + widget->allocation.width - border_width == x + width &&
2409 state_type == GTK_STATE_NORMAL)
2414 else if (real_gap_side == GTK_POS_BOTTOM)
2419 h2 = height - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_vborder * 2);
2420 pixmap = gdk_pixmap_new (window, w2, h2, -1);
2424 if (xp_theme_draw (target, tab_part, style, x2, y2, w2, h2, state_type, NULL /*area*/))
2426 GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
2427 if (real_gap_side == GTK_POS_BOTTOM)
2428 rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
2429 else if (real_gap_side == GTK_POS_LEFT)
2430 rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
2431 else if (real_gap_side == GTK_POS_RIGHT)
2432 rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
2434 if (rotation != GDK_PIXBUF_ROTATE_NONE)
2436 GdkPixbuf * pixbuf, * rotated;
2438 pixbuf = gdk_pixbuf_get_from_drawable (NULL, target, NULL, x2, y2, 0, 0, w2, h2);
2440 rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
2441 g_object_unref (pixbuf);
2444 if (real_gap_side == GTK_POS_RIGHT)
2446 x2 = x + (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2448 w2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2451 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2452 state_type == GTK_STATE_NORMAL)
2457 else if (real_gap_side == GTK_POS_LEFT)
2461 w2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2464 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2465 state_type == GTK_STATE_NORMAL)
2470 else if (real_gap_side == GTK_POS_BOTTOM)
2473 y2 = y + (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_vborder);
2475 h2 = height - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_vborder * 2);
2476 /* If we are currently drawing the right-most tab (any state)... */
2477 if (widget->allocation.x + widget->allocation.width - border_width == x + width)
2484 gdk_draw_pixbuf (window, NULL, pixbuf, 0, 0, x2, y2, w2, h2, GDK_RGB_DITHER_NONE, 0, 0);
2486 g_object_unref (G_OBJECT (pixbuf));
2488 if (real_gap_side == GTK_POS_LEFT || real_gap_side == GTK_POS_RIGHT || real_gap_side == GTK_POS_BOTTOM)
2490 g_object_unref (pixmap);
2494 } else if (real_gap_side == GTK_POS_TOP || real_gap_side == GTK_POS_BOTTOM) {
2495 /* experimental tab-drawing code from mozilla */
2500 dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2502 if (real_gap_side == GTK_POS_TOP)
2504 else if (real_gap_side == GTK_POS_BOTTOM)
2505 aPosition = BF_BOTTOM;
2506 else if (real_gap_side == GTK_POS_LEFT)
2507 aPosition = BF_LEFT;
2509 aPosition = BF_RIGHT;
2511 if( state_type == GTK_STATE_PRELIGHT )
2512 state_type = GTK_STATE_NORMAL;
2514 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2515 DrawTab (dc, rect, aPosition, state_type != GTK_STATE_PRELIGHT, (real_gap_side != GTK_POS_LEFT), (real_gap_side != GTK_POS_RIGHT));
2517 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2519 release_window_dc (style, window, state_type);
2523 parent_class->draw_extension
2524 (style, window, state_type, shadow_type, area, widget, detail,
2525 x, y, width, height, gap_side);
2529 draw_box_gap (GtkStyle * style, GdkWindow * window, GtkStateType state_type,
2530 GtkShadowType shadow_type, GdkRectangle * area,
2531 GtkWidget * widget, const gchar * detail, gint x,
2532 gint y, gint width, gint height, GtkPositionType gap_side,
2533 gint gap_x, gint gap_width)
2535 if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
2537 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2538 int side = gtk_notebook_get_tab_pos (notebook);
2539 int x2 = x, y2 = y, w2 = width, h2 = height;
2541 if (side == GTK_POS_TOP)
2544 y2 = y - notebook->tab_vborder;
2546 h2 = height + notebook->tab_vborder * 2;
2548 else if (side == GTK_POS_BOTTOM)
2553 h2 = height + notebook->tab_vborder * 2;
2555 else if (side == GTK_POS_LEFT)
2557 x2 = x - notebook->tab_hborder;
2559 w2 = width + notebook->tab_hborder;
2562 else if (side == GTK_POS_RIGHT)
2566 w2 = width + notebook->tab_hborder * 2;
2570 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2571 x2, y2, w2, h2, state_type, area))
2577 parent_class->draw_box_gap (style, window, state_type, shadow_type,
2578 area, widget, detail, x, y, width, height,
2579 gap_side, gap_x, gap_width);
2582 static gboolean is_popup_window_child( GtkWidget* widget )
2585 GtkWindowType type = -1;
2587 top = gtk_widget_get_toplevel( widget );
2588 if( top && GTK_IS_WINDOW(top) ) {
2589 g_object_get(top, "type", &type, NULL );
2590 if( type == GTK_WINDOW_POPUP ) { /* Hack for combo boxes */
2598 draw_flat_box (GtkStyle * style, GdkWindow * window,
2599 GtkStateType state_type, GtkShadowType shadow_type,
2600 GdkRectangle * area, GtkWidget * widget,
2601 const gchar * detail, gint x, gint y, gint width, gint height)
2604 if ( !strcmp (detail, "checkbutton") )
2606 if (state_type == GTK_STATE_PRELIGHT)
2613 parent_class->draw_flat_box (style, window, state_type, shadow_type,
2614 area, widget, detail, x, y, width, height);
2618 draw_menu_border ( GdkWindow* win, GtkStyle* style,
2619 gint x, gint y, gint width, gint height )
2624 dc = get_window_dc (style, win, GTK_STATE_NORMAL, x, y, width, height, &rect );
2627 if( xp_theme_is_active() ) {
2628 FrameRect( dc, &rect, GetSysColorBrush(COLOR_3DSHADOW) );
2631 DrawEdge( dc, &rect, EDGE_RAISED, BF_RECT );
2633 release_window_dc( style, win, GTK_STATE_NORMAL );
2638 draw_shadow (GtkStyle * style,
2640 GtkStateType state_type,
2641 GtkShadowType shadow_type,
2642 GdkRectangle * area,
2644 const gchar * detail, gint x, gint y, gint width, gint height)
2646 gboolean is_handlebox;
2647 gboolean is_toolbar;
2649 if( detail && !strcmp( detail, "frame") )
2653 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2654 if( is_popup_window_child(widget) ) {
2655 FrameRect( dc, &rect, GetSysColorBrush( COLOR_WINDOWFRAME ) );
2658 switch( shadow_type ){
2660 draw_3d_border(dc, &rect, TRUE);
2662 case GTK_SHADOW_OUT:
2663 draw_3d_border(dc, &rect, FALSE);
2665 case GTK_SHADOW_ETCHED_IN:
2666 draw_3d_border(dc, &rect, TRUE);
2667 InflateRect( &rect, -1, -1 );
2668 draw_3d_border(dc, &rect, FALSE);
2670 case GTK_SHADOW_ETCHED_OUT:
2671 draw_3d_border(dc, &rect, FALSE);
2672 InflateRect( &rect, -1, -1 );
2673 draw_3d_border(dc, &rect, TRUE);
2675 case GTK_SHADOW_NONE:
2679 release_window_dc( style, window, state_type );
2682 if (detail && (!strcmp (detail, "entry") || !strcmp (detail, "combobox")) )
2684 if( shadow_type != GTK_SHADOW_IN )
2687 if ( !xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2688 x, y, width, height, state_type, area))
2693 dc = get_window_dc (style, window, state_type,
2694 x, y, width, height, &rect);
2695 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
2696 release_window_dc (style, window, state_type);
2702 if (detail && !strcmp (detail, "scrolled_window") &&
2703 xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2704 x, y, width, height, state_type, area))
2707 if (detail && !strcmp (detail, "spinbutton"))
2710 if (detail && !strcmp (detail, "menu"))
2712 if ( draw_menu_border ( window, style, x, y, width, height ) ) {
2717 if (detail && !strcmp (detail, "handlebox"))
2720 is_handlebox = (detail && !strcmp (detail, "handlebox_bin"));
2721 is_toolbar = (detail && (!strcmp (detail, "toolbar") || !strcmp(detail, "menubar")));
2723 if ( is_toolbar || is_handlebox )
2728 HGDIOBJ old_pen = NULL;
2729 GtkPositionType pos;
2731 sanitize_size (window, &width, &height);
2733 if( is_handlebox ) {
2734 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
2736 If the handle box is at left side,
2737 we shouldn't draw its right border.
2738 The same holds true for top, right, and bottom.
2742 pos = GTK_POS_RIGHT; break;
2744 pos = GTK_POS_LEFT; break;
2746 pos = GTK_POS_BOTTOM; break;
2747 case GTK_POS_BOTTOM:
2748 pos = GTK_POS_TOP; break;
2752 GtkWidget* parent = gtk_widget_get_parent(widget);
2753 /* Dirty hack for toolbars contained in handle boxes */
2754 if( GTK_IS_HANDLE_BOX( parent ) ) {
2755 pos = gtk_handle_box_get_handle_position( GTK_HANDLE_BOX( parent ) );
2760 Make pos != all legal enum vaules of GtkPositionType.
2761 So every border will be draw.
2763 pos = (GtkPositionType)-1;
2767 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2768 if( pos != GTK_POS_LEFT ) {
2769 old_pen = SelectObject( dc, get_light_pen() );
2770 MoveToEx( dc, rect.left, rect.top, NULL );
2771 LineTo( dc, rect.left, rect.bottom );
2773 if( pos != GTK_POS_TOP ) {
2774 old_pen = SelectObject( dc, get_light_pen() );
2775 MoveToEx( dc, rect.left, rect.top, NULL );
2776 LineTo( dc, rect.right, rect.top );
2778 if( pos != GTK_POS_RIGHT ) {
2779 old_pen = SelectObject( dc, get_dark_pen() );
2780 MoveToEx( dc, rect.right-1, rect.top, NULL );
2781 LineTo( dc, rect.right-1, rect.bottom );
2783 if( pos != GTK_POS_BOTTOM ) {
2784 old_pen = SelectObject( dc, get_dark_pen() );
2785 MoveToEx( dc, rect.left, rect.bottom-1, NULL );
2786 LineTo( dc, rect.right, rect.bottom-1 );
2789 SelectObject( dc, old_pen );
2790 release_window_dc( style, window, state_type );
2795 if (detail && !strcmp (detail, "statusbar")) {
2799 parent_class->draw_shadow (style, window, state_type, shadow_type, area,
2800 widget, detail, x, y, width, height);
2804 draw_hline (GtkStyle * style,
2806 GtkStateType state_type,
2807 GdkRectangle * area,
2809 const gchar * detail, gint x1, gint x2, gint y)
2811 if (xp_theme_is_active () && detail && !strcmp(detail, "menuitem")) {
2812 if(xp_theme_draw (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, y, x2, 1, state_type, area))
2816 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2818 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2821 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2824 if( style->ythickness == 2 )
2828 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2829 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2831 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2833 gdk_draw_line (window, style->light_gc[state_type], x1, y, x2, y);
2836 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2837 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2842 parent_class->draw_hline (style, window, state_type, area, widget,
2849 draw_vline (GtkStyle * style,
2851 GtkStateType state_type,
2852 GdkRectangle * area,
2854 const gchar * detail, gint y1, gint y2, gint x)
2856 if( style->xthickness == 2 )
2860 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2861 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2863 gdk_draw_line (window, style->dark_gc[state_type], x, y1, x, y2);
2865 gdk_draw_line (window, style->light_gc[state_type], x, y1, x, y2);
2868 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2869 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2874 parent_class->draw_vline (style, window, state_type, area, widget,
2880 draw_slider (GtkStyle * style,
2882 GtkStateType state_type,
2883 GtkShadowType shadow_type,
2884 GdkRectangle * area,
2886 const gchar * detail,
2888 gint y, gint width, gint height, GtkOrientation orientation)
2890 if (GTK_IS_SCALE (widget) &&
2891 xp_theme_draw (window,
2893 GTK_ORIENTATION_VERTICAL) ?
2894 XP_THEME_ELEMENT_SCALE_SLIDER_V :
2895 XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
2896 height, state_type, area))
2901 parent_class->draw_slider (style, window, state_type, shadow_type, area,
2902 widget, detail, x, y, width, height,
2907 draw_resize_grip (GtkStyle * style,
2909 GtkStateType state_type,
2910 GdkRectangle * area,
2912 const gchar * detail,
2913 GdkWindowEdge edge, gint x, gint y, gint width, gint height)
2915 if (detail && !strcmp (detail, "statusbar"))
2918 (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
2919 height, state_type, area))
2923 HDC dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2926 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2927 DrawFrameControl(dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
2928 release_window_dc(style, window, state_type);
2930 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2935 parent_class->draw_resize_grip (style, window, state_type, area,
2936 widget, detail, edge, x, y, width,
2941 draw_handle (GtkStyle * style,
2943 GtkStateType state_type,
2944 GtkShadowType shadow_type,
2945 GdkRectangle * area,
2947 const gchar * detail,
2949 gint y, gint width, gint height, GtkOrientation orientation)
2954 if (is_toolbar_child (widget))
2956 XpThemeElement hndl;
2958 sanitize_size (window, &width, &height);
2960 if( GTK_IS_HANDLE_BOX(widget) ) {
2961 GtkPositionType pos;
2962 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
2963 if( pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM ) {
2964 orientation = GTK_ORIENTATION_HORIZONTAL;
2967 orientation = GTK_ORIENTATION_VERTICAL;
2971 if ( orientation == GTK_ORIENTATION_VERTICAL )
2972 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_V;
2974 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
2976 if (xp_theme_draw (window, hndl, style, x, y, width, height,
2982 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2983 if ( orientation == GTK_ORIENTATION_VERTICAL ) {
2985 rect.right = rect.left + 3;
2991 rect.bottom = rect.top + 3;
2995 draw_3d_border( dc, &rect, FALSE );
2996 release_window_dc( style, window, state_type );
3000 if (!GTK_IS_PANED (widget))
3002 gint xthick, ythick;
3003 GdkGC *light_gc, *dark_gc, *shadow_gc;
3006 sanitize_size (window, &width, &height);
3008 gtk_paint_box (style, window, state_type, shadow_type, area,
3009 widget, detail, x, y, width, height);
3011 light_gc = style->light_gc[state_type];
3012 dark_gc = style->dark_gc[state_type];
3013 shadow_gc = style->mid_gc[state_type];
3015 xthick = style->xthickness;
3016 ythick = style->ythickness;
3018 dest.x = x + xthick;
3019 dest.y = y + ythick;
3020 dest.width = width - (xthick * 2);
3021 dest.height = height - (ythick * 2);
3023 if (dest.width < dest.height)
3028 gdk_gc_set_clip_rectangle (light_gc, &dest);
3029 gdk_gc_set_clip_rectangle (dark_gc, &dest);
3030 gdk_gc_set_clip_rectangle (shadow_gc, &dest);
3032 if (dest.width < dest.height)
3034 gdk_draw_line (window, light_gc, dest.x, dest.y, dest.x,
3036 gdk_draw_line (window, dark_gc, dest.x + (dest.width / 2),
3037 dest.y, dest.x + (dest.width / 2),
3039 gdk_draw_line (window, shadow_gc, dest.x + dest.width,
3040 dest.y, dest.x + dest.width, dest.height);
3044 gdk_draw_line (window, light_gc, dest.x, dest.y,
3045 dest.x + dest.width, dest.y);
3046 gdk_draw_line (window, dark_gc, dest.x,
3047 dest.y + (dest.height / 2),
3048 dest.x + dest.width,
3049 dest.y + (dest.height / 2));
3050 gdk_draw_line (window, shadow_gc, dest.x,
3051 dest.y + dest.height, dest.x + dest.width,
3052 dest.y + dest.height);
3055 gdk_gc_set_clip_rectangle (shadow_gc, NULL);
3056 gdk_gc_set_clip_rectangle (light_gc, NULL);
3057 gdk_gc_set_clip_rectangle (dark_gc, NULL);
3062 draw_focus ( GtkStyle *style,
3064 GtkStateType state_type,
3067 const gchar *detail,
3075 if( !GTK_WIDGET_CAN_FOCUS(widget) ) {
3078 if( detail && 0 == strcmp(detail, "button")
3079 && GTK_RELIEF_NONE == gtk_button_get_relief( GTK_BUTTON(widget) ) )
3083 if ( is_combo_box_child(widget)
3084 && (GTK_IS_ARROW(widget) || GTK_IS_BUTTON(widget)) ) {
3087 if (GTK_IS_TREE_VIEW (widget->parent) /* list view bheader */
3088 || GTK_IS_CLIST (widget->parent)) {
3092 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
3093 DrawFocusRect(dc, &rect);
3094 release_window_dc( style, window, state_type );
3096 parent_class->draw_focus (style, window, state_type,
3097 area, widget, detail, x, y, width, height);
3102 msw_style_init_from_rc (GtkStyle * style, GtkRcStyle * rc_style)
3104 setup_system_font (style);
3105 setup_menu_settings (gtk_settings_get_default ());
3106 setup_system_styles (style);
3107 parent_class->init_from_rc (style, rc_style);
3111 load_bg_image (GdkColormap *colormap,
3113 const gchar *filename)
3115 if (strcmp (filename, "<parent>") == 0)
3116 return (GdkPixmap*) GDK_PARENT_RELATIVE;
3119 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
3126 msw_style_realize (GtkStyle * style)
3128 GdkGCValues gc_values;
3129 GdkGCValuesMask gc_values_mask;
3133 for (i = 0; i < 5; i++)
3135 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
3136 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
3137 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
3139 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
3140 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
3141 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
3144 style->black.red = 0x0000;
3145 style->black.green = 0x0000;
3146 style->black.blue = 0x0000;
3147 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
3149 style->white.red = 0xffff;
3150 style->white.green = 0xffff;
3151 style->white.blue = 0xffff;
3152 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
3154 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
3156 gc_values.foreground = style->black;
3157 gc_values.background = style->white;
3158 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3160 gc_values.foreground = style->white;
3161 gc_values.background = style->black;
3162 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3164 gc_values_mask = GDK_GC_FOREGROUND;
3166 for (i = 0; i < 5; i++)
3168 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
3169 style->bg_pixmap[i] = load_bg_image (style->colormap,
3171 style->rc_style->bg_pixmap_name[i]);
3173 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
3174 g_warning ("unable to allocate color: ( %d %d %d )",
3175 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
3176 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
3177 g_warning ("unable to allocate color: ( %d %d %d )",
3178 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
3179 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
3180 g_warning ("unable to allocate color: ( %d %d %d )",
3181 style->light[i].red, style->light[i].green, style->light[i].blue);
3182 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
3183 g_warning ("unable to allocate color: ( %d %d %d )",
3184 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
3185 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
3186 g_warning ("unable to allocate color: ( %d %d %d )",
3187 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
3188 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
3189 g_warning ("unable to allocate color: ( %d %d %d )",
3190 style->text[i].red, style->text[i].green, style->text[i].blue);
3191 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
3192 g_warning ("unable to allocate color: ( %d %d %d )",
3193 style->base[i].red, style->base[i].green, style->base[i].blue);
3194 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
3195 g_warning ("unable to allocate color: ( %d %d %d )",
3196 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
3198 gc_values.foreground = style->fg[i];
3199 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3201 gc_values.foreground = style->bg[i];
3202 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3204 gc_values.foreground = style->light[i];
3205 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3207 gc_values.foreground = style->dark[i];
3208 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3210 gc_values.foreground = style->mid[i];
3211 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3213 gc_values.foreground = style->text[i];
3214 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3216 gc_values.foreground = style->base[i];
3217 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3219 gc_values.foreground = style->text_aa[i];
3220 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3225 msw_style_unrealize (GtkStyle * style)
3227 parent_class->unrealize (style);
3231 msw_style_class_init (MswStyleClass * klass)
3233 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3235 parent_class = g_type_class_peek_parent (klass);
3237 style_class->init_from_rc = msw_style_init_from_rc;
3238 style_class->draw_arrow = draw_arrow;
3239 style_class->draw_box = draw_box;
3240 style_class->draw_check = draw_check;
3241 style_class->draw_option = draw_option;
3242 style_class->draw_tab = draw_tab;
3243 style_class->draw_flat_box = draw_flat_box;
3244 style_class->draw_expander = draw_expander;
3245 style_class->draw_extension = draw_extension;
3246 style_class->draw_box_gap = draw_box_gap;
3247 style_class->draw_shadow = draw_shadow;
3248 style_class->draw_hline = draw_hline;
3249 style_class->draw_vline = draw_vline;
3250 style_class->draw_handle = draw_handle;
3251 style_class->draw_resize_grip = draw_resize_grip;
3252 style_class->draw_slider = draw_slider;
3253 style_class->draw_focus = draw_focus;
3255 style_class->realize = msw_style_realize;
3256 style_class->unrealize = msw_style_unrealize;
3259 GType msw_type_style = 0;
3262 msw_style_register_type (GTypeModule * module)
3264 static const GTypeInfo object_info = {
3265 sizeof (MswStyleClass),
3266 (GBaseInitFunc) NULL,
3267 (GBaseFinalizeFunc) NULL,
3268 (GClassInitFunc) msw_style_class_init,
3269 NULL, /* class_finalize */
3270 NULL, /* class_data */
3272 0, /* n_preallocs */
3273 (GInstanceInitFunc) NULL,
3276 msw_type_style = g_type_module_register_type (module,
3283 msw_style_init (void)
3286 msw_style_setup_system_settings ();
3287 setup_msw_rc_style ();
3290 DeleteObject( g_light_pen );
3294 DeleteObject( g_dark_pen );
3299 void msw_style_finalize(void)
3301 if( g_dither_brush ){
3302 DeleteObject( g_dither_brush );
3305 DeleteObject( g_light_pen );
3308 DeleteObject( g_dark_pen );