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)
2417 y2 = y + (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_vborder);
2419 h2 = height - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_vborder * 2);
2422 /* If we are currently drawing the right-most tab (any state)... */
2423 if (widget->allocation.x + widget->allocation.width - border_width == x + width)
2430 if (xp_theme_draw (target, tab_part, style, x2, y2, w2, h2, state_type, NULL /*area*/))
2432 GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
2433 if (real_gap_side == GTK_POS_BOTTOM)
2434 rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
2435 else if (real_gap_side == GTK_POS_LEFT)
2436 rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
2437 else if (real_gap_side == GTK_POS_RIGHT)
2438 rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
2440 if (rotation != GDK_PIXBUF_ROTATE_NONE)
2442 GdkPixbuf * pixbuf, * rotated;
2444 pixbuf = gdk_pixbuf_get_from_drawable (NULL, target, NULL, x2, y2, 0, 0, w2, h2);
2446 rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
2447 g_object_unref (pixbuf);
2450 if (real_gap_side == GTK_POS_RIGHT)
2452 x2 = x + (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2454 w2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2457 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2458 state_type == GTK_STATE_NORMAL)
2463 else if (real_gap_side == GTK_POS_LEFT)
2467 w2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2470 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2471 state_type == GTK_STATE_NORMAL)
2477 gdk_draw_pixbuf (window, NULL, pixbuf, 0, 0, x2, y2, w2, h2, GDK_RGB_DITHER_NONE, 0, 0);
2479 g_object_unref (G_OBJECT (pixbuf));
2481 if (real_gap_side == GTK_POS_LEFT || real_gap_side == GTK_POS_RIGHT)
2483 g_object_unref (pixmap);
2487 } else if (real_gap_side == GTK_POS_TOP || real_gap_side == GTK_POS_BOTTOM) {
2488 /* experimental tab-drawing code from mozilla */
2493 dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2495 if (real_gap_side == GTK_POS_TOP)
2497 else if (real_gap_side == GTK_POS_BOTTOM)
2498 aPosition = BF_BOTTOM;
2499 else if (real_gap_side == GTK_POS_LEFT)
2500 aPosition = BF_LEFT;
2502 aPosition = BF_RIGHT;
2504 if( state_type == GTK_STATE_PRELIGHT )
2505 state_type = GTK_STATE_NORMAL;
2507 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2508 DrawTab (dc, rect, aPosition, state_type != GTK_STATE_PRELIGHT, (real_gap_side != GTK_POS_LEFT), (real_gap_side != GTK_POS_RIGHT));
2510 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2512 release_window_dc (style, window, state_type);
2516 parent_class->draw_extension
2517 (style, window, state_type, shadow_type, area, widget, detail,
2518 x, y, width, height, gap_side);
2522 draw_box_gap (GtkStyle * style, GdkWindow * window, GtkStateType state_type,
2523 GtkShadowType shadow_type, GdkRectangle * area,
2524 GtkWidget * widget, const gchar * detail, gint x,
2525 gint y, gint width, gint height, GtkPositionType gap_side,
2526 gint gap_x, gint gap_width)
2528 if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
2530 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2531 int side = gtk_notebook_get_tab_pos (notebook);
2532 int x2 = x, y2 = y, w2 = width, h2 = height;
2534 if (side == GTK_POS_TOP)
2537 y2 = y - notebook->tab_vborder;
2539 h2 = height + notebook->tab_vborder * 2;
2541 else if (side == GTK_POS_BOTTOM)
2546 h2 = height + notebook->tab_vborder * 2;
2548 else if (side == GTK_POS_LEFT)
2550 x2 = x - notebook->tab_hborder;
2552 w2 = width + notebook->tab_hborder;
2555 else if (side == GTK_POS_RIGHT)
2559 w2 = width + notebook->tab_hborder * 2;
2563 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2564 x2, y2, w2, h2, state_type, area))
2570 parent_class->draw_box_gap (style, window, state_type, shadow_type,
2571 area, widget, detail, x, y, width, height,
2572 gap_side, gap_x, gap_width);
2575 static gboolean is_popup_window_child( GtkWidget* widget )
2578 GtkWindowType type = -1;
2580 top = gtk_widget_get_toplevel( widget );
2581 if( top && GTK_IS_WINDOW(top) ) {
2582 g_object_get(top, "type", &type, NULL );
2583 if( type == GTK_WINDOW_POPUP ) { /* Hack for combo boxes */
2591 draw_flat_box (GtkStyle * style, GdkWindow * window,
2592 GtkStateType state_type, GtkShadowType shadow_type,
2593 GdkRectangle * area, GtkWidget * widget,
2594 const gchar * detail, gint x, gint y, gint width, gint height)
2597 if ( !strcmp (detail, "checkbutton") )
2599 if (state_type == GTK_STATE_PRELIGHT)
2606 parent_class->draw_flat_box (style, window, state_type, shadow_type,
2607 area, widget, detail, x, y, width, height);
2611 draw_menu_border ( GdkWindow* win, GtkStyle* style,
2612 gint x, gint y, gint width, gint height )
2617 dc = get_window_dc (style, win, GTK_STATE_NORMAL, x, y, width, height, &rect );
2620 if( xp_theme_is_active() ) {
2621 FrameRect( dc, &rect, GetSysColorBrush(COLOR_3DSHADOW) );
2624 DrawEdge( dc, &rect, EDGE_RAISED, BF_RECT );
2626 release_window_dc( style, win, GTK_STATE_NORMAL );
2631 draw_shadow (GtkStyle * style,
2633 GtkStateType state_type,
2634 GtkShadowType shadow_type,
2635 GdkRectangle * area,
2637 const gchar * detail, gint x, gint y, gint width, gint height)
2639 gboolean is_handlebox;
2640 gboolean is_toolbar;
2642 if( detail && !strcmp( detail, "frame") )
2646 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2647 if( is_popup_window_child(widget) ) {
2648 FrameRect( dc, &rect, GetSysColorBrush( COLOR_WINDOWFRAME ) );
2651 switch( shadow_type ){
2653 draw_3d_border(dc, &rect, TRUE);
2655 case GTK_SHADOW_OUT:
2656 draw_3d_border(dc, &rect, FALSE);
2658 case GTK_SHADOW_ETCHED_IN:
2659 draw_3d_border(dc, &rect, TRUE);
2660 InflateRect( &rect, -1, -1 );
2661 draw_3d_border(dc, &rect, FALSE);
2663 case GTK_SHADOW_ETCHED_OUT:
2664 draw_3d_border(dc, &rect, FALSE);
2665 InflateRect( &rect, -1, -1 );
2666 draw_3d_border(dc, &rect, TRUE);
2668 case GTK_SHADOW_NONE:
2672 release_window_dc( style, window, state_type );
2675 if (detail && (!strcmp (detail, "entry") || !strcmp (detail, "combobox")) )
2677 if( shadow_type != GTK_SHADOW_IN )
2680 if ( !xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2681 x, y, width, height, state_type, area))
2686 dc = get_window_dc (style, window, state_type,
2687 x, y, width, height, &rect);
2688 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
2689 release_window_dc (style, window, state_type);
2695 if( detail && !strcmp( detail, "spinbutton" ) )
2700 if (detail && !strcmp (detail, "menu"))
2702 if ( draw_menu_border ( window, style, x, y, width, height ) ) {
2707 if (detail && !strcmp (detail, "handlebox"))
2710 is_handlebox = (detail && !strcmp (detail, "handlebox_bin"));
2711 is_toolbar = (detail && (!strcmp (detail, "toolbar") || !strcmp(detail, "menubar")));
2713 if ( is_toolbar || is_handlebox )
2718 HGDIOBJ old_pen = NULL;
2719 GtkPositionType pos;
2721 sanitize_size (window, &width, &height);
2723 if( is_handlebox ) {
2724 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
2726 If the handle box is at left side,
2727 we shouldn't draw its right border.
2728 The same holds true for top, right, and bottom.
2732 pos = GTK_POS_RIGHT; break;
2734 pos = GTK_POS_LEFT; break;
2736 pos = GTK_POS_BOTTOM; break;
2737 case GTK_POS_BOTTOM:
2738 pos = GTK_POS_TOP; break;
2742 GtkWidget* parent = gtk_widget_get_parent(widget);
2743 /* Dirty hack for toolbars contained in handle boxes */
2744 if( GTK_IS_HANDLE_BOX( parent ) ) {
2745 pos = gtk_handle_box_get_handle_position( GTK_HANDLE_BOX( parent ) );
2750 Make pos != all legal enum vaules of GtkPositionType.
2751 So every border will be draw.
2753 pos = (GtkPositionType)-1;
2757 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2758 if( pos != GTK_POS_LEFT ) {
2759 old_pen = SelectObject( dc, get_light_pen() );
2760 MoveToEx( dc, rect.left, rect.top, NULL );
2761 LineTo( dc, rect.left, rect.bottom );
2763 if( pos != GTK_POS_TOP ) {
2764 old_pen = SelectObject( dc, get_light_pen() );
2765 MoveToEx( dc, rect.left, rect.top, NULL );
2766 LineTo( dc, rect.right, rect.top );
2768 if( pos != GTK_POS_RIGHT ) {
2769 old_pen = SelectObject( dc, get_dark_pen() );
2770 MoveToEx( dc, rect.right-1, rect.top, NULL );
2771 LineTo( dc, rect.right-1, rect.bottom );
2773 if( pos != GTK_POS_BOTTOM ) {
2774 old_pen = SelectObject( dc, get_dark_pen() );
2775 MoveToEx( dc, rect.left, rect.bottom-1, NULL );
2776 LineTo( dc, rect.right, rect.bottom-1 );
2779 SelectObject( dc, old_pen );
2780 release_window_dc( style, window, state_type );
2785 if (detail && !strcmp (detail, "statusbar")) {
2789 parent_class->draw_shadow (style, window, state_type, shadow_type, area,
2790 widget, detail, x, y, width, height);
2794 draw_hline (GtkStyle * style,
2796 GtkStateType state_type,
2797 GdkRectangle * area,
2799 const gchar * detail, gint x1, gint x2, gint y)
2801 if (xp_theme_is_active () && detail && !strcmp(detail, "menuitem")) {
2802 if(xp_theme_draw (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, y, x2, 1, state_type, area))
2806 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2808 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2811 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2814 if( style->ythickness == 2 )
2818 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2819 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2821 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2823 gdk_draw_line (window, style->light_gc[state_type], x1, y, x2, y);
2826 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2827 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2832 parent_class->draw_hline (style, window, state_type, area, widget,
2839 draw_vline (GtkStyle * style,
2841 GtkStateType state_type,
2842 GdkRectangle * area,
2844 const gchar * detail, gint y1, gint y2, gint x)
2846 if( style->xthickness == 2 )
2850 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2851 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2853 gdk_draw_line (window, style->dark_gc[state_type], x, y1, x, y2);
2855 gdk_draw_line (window, style->light_gc[state_type], x, y1, x, y2);
2858 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2859 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2864 parent_class->draw_vline (style, window, state_type, area, widget,
2870 draw_slider (GtkStyle * style,
2872 GtkStateType state_type,
2873 GtkShadowType shadow_type,
2874 GdkRectangle * area,
2876 const gchar * detail,
2878 gint y, gint width, gint height, GtkOrientation orientation)
2880 if (GTK_IS_SCALE (widget) &&
2881 xp_theme_draw (window,
2883 GTK_ORIENTATION_VERTICAL) ?
2884 XP_THEME_ELEMENT_SCALE_SLIDER_V :
2885 XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
2886 height, state_type, area))
2891 parent_class->draw_slider (style, window, state_type, shadow_type, area,
2892 widget, detail, x, y, width, height,
2897 draw_resize_grip (GtkStyle * style,
2899 GtkStateType state_type,
2900 GdkRectangle * area,
2902 const gchar * detail,
2903 GdkWindowEdge edge, gint x, gint y, gint width, gint height)
2905 if (detail && !strcmp (detail, "statusbar"))
2908 (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
2909 height, state_type, area))
2913 HDC dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2916 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2917 DrawFrameControl(dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
2918 release_window_dc(style, window, state_type);
2920 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2925 parent_class->draw_resize_grip (style, window, state_type, area,
2926 widget, detail, edge, x, y, width,
2931 draw_handle (GtkStyle * style,
2933 GtkStateType state_type,
2934 GtkShadowType shadow_type,
2935 GdkRectangle * area,
2937 const gchar * detail,
2939 gint y, gint width, gint height, GtkOrientation orientation)
2944 if (is_toolbar_child (widget))
2946 XpThemeElement hndl;
2948 sanitize_size (window, &width, &height);
2950 if( GTK_IS_HANDLE_BOX(widget) ) {
2951 GtkPositionType pos;
2952 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
2953 if( pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM ) {
2954 orientation = GTK_ORIENTATION_HORIZONTAL;
2957 orientation = GTK_ORIENTATION_VERTICAL;
2961 if ( orientation == GTK_ORIENTATION_VERTICAL )
2962 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_V;
2964 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
2966 if (xp_theme_draw (window, hndl, style, x, y, width, height,
2972 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2973 if ( orientation == GTK_ORIENTATION_VERTICAL ) {
2975 rect.right = rect.left + 3;
2981 rect.bottom = rect.top + 3;
2985 draw_3d_border( dc, &rect, FALSE );
2986 release_window_dc( style, window, state_type );
2990 if (!GTK_IS_PANED (widget))
2992 gint xthick, ythick;
2993 GdkGC *light_gc, *dark_gc, *shadow_gc;
2996 sanitize_size (window, &width, &height);
2998 gtk_paint_box (style, window, state_type, shadow_type, area,
2999 widget, detail, x, y, width, height);
3001 light_gc = style->light_gc[state_type];
3002 dark_gc = style->dark_gc[state_type];
3003 shadow_gc = style->mid_gc[state_type];
3005 xthick = style->xthickness;
3006 ythick = style->ythickness;
3008 dest.x = x + xthick;
3009 dest.y = y + ythick;
3010 dest.width = width - (xthick * 2);
3011 dest.height = height - (ythick * 2);
3013 if (dest.width < dest.height)
3018 gdk_gc_set_clip_rectangle (light_gc, &dest);
3019 gdk_gc_set_clip_rectangle (dark_gc, &dest);
3020 gdk_gc_set_clip_rectangle (shadow_gc, &dest);
3022 if (dest.width < dest.height)
3024 gdk_draw_line (window, light_gc, dest.x, dest.y, dest.x,
3026 gdk_draw_line (window, dark_gc, dest.x + (dest.width / 2),
3027 dest.y, dest.x + (dest.width / 2),
3029 gdk_draw_line (window, shadow_gc, dest.x + dest.width,
3030 dest.y, dest.x + dest.width, dest.height);
3034 gdk_draw_line (window, light_gc, dest.x, dest.y,
3035 dest.x + dest.width, dest.y);
3036 gdk_draw_line (window, dark_gc, dest.x,
3037 dest.y + (dest.height / 2),
3038 dest.x + dest.width,
3039 dest.y + (dest.height / 2));
3040 gdk_draw_line (window, shadow_gc, dest.x,
3041 dest.y + dest.height, dest.x + dest.width,
3042 dest.y + dest.height);
3045 gdk_gc_set_clip_rectangle (shadow_gc, NULL);
3046 gdk_gc_set_clip_rectangle (light_gc, NULL);
3047 gdk_gc_set_clip_rectangle (dark_gc, NULL);
3052 draw_focus ( GtkStyle *style,
3054 GtkStateType state_type,
3057 const gchar *detail,
3065 if( !GTK_WIDGET_CAN_FOCUS(widget) ) {
3068 if( detail && 0 == strcmp(detail, "button")
3069 && GTK_RELIEF_NONE == gtk_button_get_relief( GTK_BUTTON(widget) ) )
3073 if ( is_combo_box_child(widget)
3074 && (GTK_IS_ARROW(widget) || GTK_IS_BUTTON(widget)) ) {
3077 if (GTK_IS_TREE_VIEW (widget->parent) /* list view bheader */
3078 || GTK_IS_CLIST (widget->parent)) {
3082 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
3083 DrawFocusRect(dc, &rect);
3084 release_window_dc( style, window, state_type );
3086 parent_class->draw_focus (style, window, state_type,
3087 area, widget, detail, x, y, width, height);
3092 msw_style_init_from_rc (GtkStyle * style, GtkRcStyle * rc_style)
3094 setup_system_font (style);
3095 setup_menu_settings (gtk_settings_get_default ());
3096 setup_system_styles (style);
3097 parent_class->init_from_rc (style, rc_style);
3101 load_bg_image (GdkColormap *colormap,
3103 const gchar *filename)
3105 if (strcmp (filename, "<parent>") == 0)
3106 return (GdkPixmap*) GDK_PARENT_RELATIVE;
3109 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
3116 msw_style_realize (GtkStyle * style)
3118 GdkGCValues gc_values;
3119 GdkGCValuesMask gc_values_mask;
3123 for (i = 0; i < 5; i++)
3125 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
3126 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
3127 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
3129 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
3130 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
3131 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
3134 style->black.red = 0x0000;
3135 style->black.green = 0x0000;
3136 style->black.blue = 0x0000;
3137 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
3139 style->white.red = 0xffff;
3140 style->white.green = 0xffff;
3141 style->white.blue = 0xffff;
3142 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
3144 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
3146 gc_values.foreground = style->black;
3147 gc_values.background = style->white;
3148 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3150 gc_values.foreground = style->white;
3151 gc_values.background = style->black;
3152 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3154 gc_values_mask = GDK_GC_FOREGROUND;
3156 for (i = 0; i < 5; i++)
3158 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
3159 style->bg_pixmap[i] = load_bg_image (style->colormap,
3161 style->rc_style->bg_pixmap_name[i]);
3163 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
3164 g_warning ("unable to allocate color: ( %d %d %d )",
3165 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
3166 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
3167 g_warning ("unable to allocate color: ( %d %d %d )",
3168 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
3169 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
3170 g_warning ("unable to allocate color: ( %d %d %d )",
3171 style->light[i].red, style->light[i].green, style->light[i].blue);
3172 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
3173 g_warning ("unable to allocate color: ( %d %d %d )",
3174 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
3175 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
3176 g_warning ("unable to allocate color: ( %d %d %d )",
3177 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
3178 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
3179 g_warning ("unable to allocate color: ( %d %d %d )",
3180 style->text[i].red, style->text[i].green, style->text[i].blue);
3181 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
3182 g_warning ("unable to allocate color: ( %d %d %d )",
3183 style->base[i].red, style->base[i].green, style->base[i].blue);
3184 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
3185 g_warning ("unable to allocate color: ( %d %d %d )",
3186 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
3188 gc_values.foreground = style->fg[i];
3189 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3191 gc_values.foreground = style->bg[i];
3192 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3194 gc_values.foreground = style->light[i];
3195 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3197 gc_values.foreground = style->dark[i];
3198 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3200 gc_values.foreground = style->mid[i];
3201 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3203 gc_values.foreground = style->text[i];
3204 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3206 gc_values.foreground = style->base[i];
3207 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3209 gc_values.foreground = style->text_aa[i];
3210 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3215 msw_style_unrealize (GtkStyle * style)
3217 parent_class->unrealize (style);
3221 msw_style_class_init (MswStyleClass * klass)
3223 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3225 parent_class = g_type_class_peek_parent (klass);
3227 style_class->init_from_rc = msw_style_init_from_rc;
3228 style_class->draw_arrow = draw_arrow;
3229 style_class->draw_box = draw_box;
3230 style_class->draw_check = draw_check;
3231 style_class->draw_option = draw_option;
3232 style_class->draw_tab = draw_tab;
3233 style_class->draw_flat_box = draw_flat_box;
3234 style_class->draw_expander = draw_expander;
3235 style_class->draw_extension = draw_extension;
3236 style_class->draw_box_gap = draw_box_gap;
3237 style_class->draw_shadow = draw_shadow;
3238 style_class->draw_hline = draw_hline;
3239 style_class->draw_vline = draw_vline;
3240 style_class->draw_handle = draw_handle;
3241 style_class->draw_resize_grip = draw_resize_grip;
3242 style_class->draw_slider = draw_slider;
3243 style_class->draw_focus = draw_focus;
3245 style_class->realize = msw_style_realize;
3246 style_class->unrealize = msw_style_unrealize;
3249 GType msw_type_style = 0;
3252 msw_style_register_type (GTypeModule * module)
3254 static const GTypeInfo object_info = {
3255 sizeof (MswStyleClass),
3256 (GBaseInitFunc) NULL,
3257 (GBaseFinalizeFunc) NULL,
3258 (GClassInitFunc) msw_style_class_init,
3259 NULL, /* class_finalize */
3260 NULL, /* class_data */
3262 0, /* n_preallocs */
3263 (GInstanceInitFunc) NULL,
3266 msw_type_style = g_type_module_register_type (module,
3273 msw_style_init (void)
3276 msw_style_setup_system_settings ();
3277 setup_msw_rc_style ();
3280 DeleteObject( g_light_pen );
3284 DeleteObject( g_dark_pen );
3289 void msw_style_finalize(void)
3291 if( g_dither_brush ){
3292 DeleteObject( g_dither_brush );
3295 DeleteObject( g_light_pen );
3298 DeleteObject( g_dark_pen );