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));
469 ReleaseDC (hwnd, hDC);
474 font = get_family_name (&lf, hDC);
478 g_snprintf (buf, bufsiz, "%s %s %s %d", font, style, weight, pt_size);
487 /* missing from ms's header files */
488 #ifndef SPI_GETMENUSHOWDELAY
489 #define SPI_GETMENUSHOWDELAY 106
492 /* I don't know the proper XP theme class for things like
493 HIGHLIGHTTEXT, so we'll just define it to be "BUTTON"
495 #define XP_THEME_CLASS_TEXT XP_THEME_CLASS_BUTTON
498 setup_menu_settings (GtkSettings * settings)
501 gboolean win95 = FALSE;
502 OSVERSIONINFOEX osvi;
503 GObjectClass *klazz = G_OBJECT_GET_CLASS (G_OBJECT (settings));
505 ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
506 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
508 if (!GetVersionEx ((OSVERSIONINFO *) & osvi))
509 win95 = TRUE; /* assume the worst */
511 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
512 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
517 if (SystemParametersInfo
518 (SPI_GETMENUSHOWDELAY, 0, &menu_delay, 0))
522 if (g_object_class_find_property
523 (klazz, "gtk-menu-bar-popup-delay"))
525 g_object_set (settings,
526 "gtk-menu-bar-popup-delay",
529 if (g_object_class_find_property
530 (klazz, "gtk-menu-popup-delay"))
532 g_object_set (settings,
533 "gtk-menu-popup-delay",
536 if (g_object_class_find_property
537 (klazz, "gtk-menu-popdown-delay"))
539 g_object_set (settings,
540 "gtk-menu-popdown-delay",
549 msw_style_setup_system_settings (void)
551 GtkSettings *settings;
552 int cursor_blink_time;
554 settings = gtk_settings_get_default ();
558 cursor_blink_time = GetCaretBlinkTime ();
559 g_object_set (settings, "gtk-cursor-blink", cursor_blink_time > 0, NULL);
561 if (cursor_blink_time > 0)
562 g_object_set (settings, "gtk-cursor-blink-time",
563 2 * cursor_blink_time, NULL);
565 g_object_set (settings, "gtk-double-click-distance",
566 GetSystemMetrics (SM_CXDOUBLECLK), NULL);
567 g_object_set (settings, "gtk-double-click-time", GetDoubleClickTime (),
569 g_object_set (settings, "gtk-dnd-drag-threshold",
570 GetSystemMetrics (SM_CXDRAG), NULL);
572 setup_menu_settings (settings);
575 http://developer.gnome.org/doc/API/2.0/gtk/GtkSettings.html
576 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/systemparametersinfo.asp
577 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getsystemmetrics.asp */
581 setup_system_font (GtkStyle * style)
583 char buf[256], *font; /* It's okay, lfFaceName is smaller than 32
586 if ((font = sys_font_to_pango_font (XP_THEME_CLASS_TEXT,
587 XP_THEME_FONT_MESSAGE,
588 buf, sizeof (buf))) != NULL)
590 if (style->font_desc)
591 pango_font_description_free (style->font_desc);
593 style->font_desc = pango_font_description_from_string (font);
598 sys_color_to_gtk_color (XpThemeClass klazz, int id, GdkColor * pcolor)
602 if (!xp_theme_get_system_color (klazz, id, &color))
603 color = GetSysColor (id);
605 pcolor->pixel = color;
606 pcolor->red = (GetRValue (color) << 8) | GetRValue (color);
607 pcolor->green = (GetGValue (color) << 8) | GetGValue (color);
608 pcolor->blue = (GetBValue (color) << 8) | GetBValue (color);
612 get_system_metric (XpThemeClass klazz, int id)
616 if (!xp_theme_get_system_metric (klazz, id, &rval))
617 rval = GetSystemMetrics (id);
623 setup_msw_rc_style (void)
625 char buf[1024], font_buf[256], *font_ptr;
626 char menu_bar_prelight_str[128];
629 GdkColor menu_text_color;
630 GdkColor tooltip_back;
631 GdkColor tooltip_fore;
634 GdkColor progress_back;
636 GdkColor fg_prelight;
637 GdkColor bg_prelight;
638 GdkColor base_prelight;
639 GdkColor text_prelight;
642 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
644 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
646 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
648 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
651 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENUTEXT,
653 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENU, &menu_color);
656 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOTEXT,
658 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOBK,
661 /* text on push buttons. TODO: button shadows, backgrounds, and
663 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT, &btn_fore);
664 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE, &btn_face);
666 /* progress bar background color */
667 sys_color_to_gtk_color (XP_THEME_CLASS_PROGRESS, COLOR_HIGHLIGHT,
670 /* Enable coloring for menus. */
672 sys_font_to_pango_font (XP_THEME_CLASS_MENU, XP_THEME_FONT_MENU,
673 font_buf, sizeof (font_buf));
674 g_snprintf (buf, sizeof (buf),
675 "style \"msw-menu\" = \"msw-default\"\n" "{\n"
676 "GtkMenuItem::toggle-spacing = 8\n"
677 "fg[PRELIGHT] = { %d, %d, %d }\n"
678 "bg[PRELIGHT] = { %d, %d, %d }\n"
679 "text[PRELIGHT] = { %d, %d, %d }\n"
680 "base[PRELIGHT] = { %d, %d, %d }\n"
681 "fg[NORMAL] = { %d, %d, %d }\n"
682 "bg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
683 "}widget_class \"*MenuItem*\" style \"msw-menu\"\n"
684 "widget_class \"*GtkMenu\" style \"msw-menu\"\n"
685 "widget_class \"*GtkMenuShell*\" style \"msw-menu\"\n",
686 fg_prelight.red, fg_prelight.green, fg_prelight.blue,
687 bg_prelight.red, bg_prelight.green, bg_prelight.blue,
688 text_prelight.red, text_prelight.green, text_prelight.blue,
689 base_prelight.red, base_prelight.green, base_prelight.blue,
690 menu_text_color.red, menu_text_color.green,
691 menu_text_color.blue, menu_color.red, menu_color.green,
692 menu_color.blue, (font_ptr ? "font_name" : "#"),
693 (font_ptr ? font_ptr : " font name should go here"));
694 gtk_rc_parse_string (buf);
696 if( xp_theme_is_active() ) {
697 *menu_bar_prelight_str = '\0';
700 g_snprintf(menu_bar_prelight_str, sizeof(menu_bar_prelight_str),
701 "fg[PRELIGHT] = { %d, %d, %d }\n",
702 menu_text_color.red, menu_text_color.green, menu_text_color.blue);
705 /* Enable coloring for menu bars. */
706 g_snprintf (buf, sizeof (buf),
707 "style \"msw-menu-bar\" = \"msw-menu\"\n"
709 "bg[NORMAL] = { %d, %d, %d }\n"
711 "GtkMenuBar::shadow-type = %d\n"
713 FIXME: This should be enabled once gtk+ support
714 GtkMenuBar::prelight-item style property.
716 /* "GtkMenuBar::prelight-item = 1\n" */
717 "}widget_class \"*MenuBar*\" style \"msw-menu-bar\"\n",
718 btn_face.red, btn_face.green, btn_face.blue,
719 menu_bar_prelight_str,
720 xp_theme_is_active() ? 0 : 2 );
721 gtk_rc_parse_string (buf);
723 g_snprintf (buf, sizeof (buf),
724 "style \"msw-toolbar\" = \"msw-default\"\n"
726 "GtkHandleBox::shadow-type = %s\n"
727 "GtkToolbar::shadow-type = %s\n"
728 "}widget_class \"*HandleBox*\" style \"msw-toolbar\"\n",
729 "etched-in", "etched-in");
730 gtk_rc_parse_string (buf);
732 /* enable tooltip fonts */
734 sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
735 font_buf, sizeof (font_buf));
736 g_snprintf (buf, sizeof (buf),
737 "style \"msw-tooltips-caption\" = \"msw-default\"\n"
738 "{fg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
739 "}widget \"gtk-tooltips.GtkLabel\" style \"msw-tooltips-caption\"\n",
740 tooltip_fore.red, tooltip_fore.green, tooltip_fore.blue,
741 (font_ptr ? "font_name" : "#"),
742 (font_ptr ? font_ptr : " font name should go here"));
743 gtk_rc_parse_string (buf);
745 g_snprintf (buf, sizeof (buf),
746 "style \"msw-tooltips\" = \"msw-default\"\n"
747 "{bg[NORMAL] = { %d, %d, %d }\n"
748 "}widget \"gtk-tooltips*\" style \"msw-tooltips\"\n",
749 tooltip_back.red, tooltip_back.green, tooltip_back.blue);
750 gtk_rc_parse_string (buf);
752 /* enable font theming for status bars */
754 sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
755 font_buf, sizeof (font_buf));
756 g_snprintf (buf, sizeof (buf),
757 "style \"msw-status\" = \"msw-default\"\n" "{%s = \"%s\"\n"
758 "bg[NORMAL] = { %d, %d, %d }\n"
759 "}widget_class \"*Status*\" style \"msw-status\"\n",
760 (font_ptr ? "font_name" : "#"),
761 (font_ptr ? font_ptr : " font name should go here"),
762 btn_face.red, btn_face.green, btn_face.blue);
763 gtk_rc_parse_string (buf);
765 /* enable coloring for text on buttons TODO: use GetThemeMetric for the
766 border and outside border */
767 g_snprintf (buf, sizeof (buf),
768 "style \"msw-button\" = \"msw-default\"\n"
770 "bg[NORMAL] = { %d, %d, %d }\n"
771 "bg[PRELIGHT] = { %d, %d, %d }\n"
772 "bg[INSENSITIVE] = { %d, %d, %d }\n"
773 "fg[PRELIGHT] = { %d, %d, %d }\n"
774 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
775 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
776 "GtkButton::child-displacement-x = 1\n"
777 "GtkButton::child-displacement-y = 1\n"
778 "GtkButton::focus-padding = %d\n"
779 "}widget_class \"*Button*\" style \"msw-button\"\n",
780 btn_face.red, btn_face.green, btn_face.blue,
781 btn_face.red, btn_face.green, btn_face.blue,
782 btn_face.red, btn_face.green, btn_face.blue,
783 btn_fore.red, btn_fore.green, btn_fore.blue,
784 xp_theme_is_active() ? 1 : 2 );
785 gtk_rc_parse_string (buf);
787 /* enable coloring for progress bars */
788 g_snprintf (buf, sizeof (buf),
789 "style \"msw-progress\" = \"msw-default\"\n"
790 "{bg[PRELIGHT] = { %d, %d, %d }\n"
791 "bg[NORMAL] = { %d, %d, %d }\n"
792 "}widget_class \"*Progress*\" style \"msw-progress\"\n",
796 btn_face.red, btn_face.green, btn_face.blue);
797 gtk_rc_parse_string (buf);
799 /* scrollbar thumb width and height */
800 g_snprintf (buf, sizeof (buf),
801 "style \"msw-vscrollbar\" = \"msw-default\"\n"
802 "{GtkRange::slider-width = %d\n"
803 "GtkRange::stepper-size = %d\n"
804 "GtkRange::stepper-spacing = 0\n"
805 "GtkRange::trough_border = 0\n"
806 "GtkScale::slider-length = %d\n"
807 "GtkScrollbar::min-slider-length = 8\n"
808 "}widget_class \"*VScrollbar*\" style \"msw-vscrollbar\"\n"
809 "widget_class \"*VScale*\" style \"msw-vscrollbar\"\n",
810 GetSystemMetrics (SM_CYVTHUMB),
811 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CXVSCROLL),
813 gtk_rc_parse_string (buf);
815 g_snprintf (buf, sizeof (buf),
816 "style \"msw-hscrollbar\" = \"msw-default\"\n"
817 "{GtkRange::slider-width = %d\n"
818 "GtkRange::stepper-size = %d\n"
819 "GtkRange::stepper-spacing = 0\n"
820 "GtkRange::trough_border = 0\n"
821 "GtkScale::slider-length = %d\n"
822 "GtkScrollbar::min-slider-length = 8\n"
823 "}widget_class \"*HScrollbar*\" style \"msw-hscrollbar\"\n"
824 "widget_class \"*HScale*\" style \"msw-hscrollbar\"\n",
825 GetSystemMetrics (SM_CXHTHUMB),
826 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CYHSCROLL),
828 gtk_rc_parse_string (buf);
830 /* radio/check button sizes */
831 g_snprintf (buf, sizeof (buf),
832 "style \"msw-checkbutton\" = \"msw-button\"\n"
833 "{GtkCheckButton::indicator-size = 13\n"
834 "}widget_class \"*CheckButton*\" style \"msw-checkbutton\"\n"
835 "widget_class \"*RadioButton*\" style \"msw-checkbutton\"\n");
836 gtk_rc_parse_string (buf);
838 /* size of combo box toggle button */
839 g_snprintf (buf, sizeof(buf),
840 "style \"msw-combo-button\" = \"msw-default\"\n"
844 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
845 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
846 "GtkButton::child-displacement-x = 0\n"
847 "GtkButton::child-displacement-y = 0\n"
848 "GtkWidget::focus-padding = 0\n"
849 "GtkWidget::focus-line-width = 0\n"
851 "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combo-button\"\n");
852 gtk_rc_parse_string (buf);
854 /* size of tree view header */
855 g_snprintf (buf, sizeof(buf),
856 "style \"msw-header-button\" = \"msw-default\"\n"
860 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
861 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
862 "GtkButton::child-displacement-x = 1\n"
863 "GtkButton::child-displacement-y = 1\n"
864 "GtkWidget::focus-padding = 0\n"
865 "GtkWidget::focus-line-width = 0\n"
867 "widget_class \"*TreeView*Button*\" style \"msw-header-button\"\n",
868 xp_theme_is_active() ? 2 : 0 );
869 gtk_rc_parse_string (buf);
871 /* FIXME: This should be enabled once gtk+ support GtkNotebok::prelight-tab */
872 /* enable prelight tab of GtkNotebook */
874 g_snprintf (buf, sizeof (buf),
875 "style \"msw-notebook\" = \"msw-default\"\n"
876 "{GtkNotebook::prelight-tab=1\n"
877 "}widget_class \"*Notebook*\" style \"msw-notebook\"\n");
878 gtk_rc_parse_string (buf);
881 /* FIXME: This should be enabled once gtk+ support GtkTreeView::full-row-focus */
883 g_snprintf (buf, sizeof (buf),
884 "style \"msw-treeview\" = \"msw-default\"\n"
885 "{GtkTreeView::full-row-focus=0\n"
886 "}widget_class \"*TreeView*\" style \"msw-treeview\"\n");
887 gtk_rc_parse_string (buf);
892 setup_system_styles (GtkStyle * style)
896 /* Default background */
897 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
898 &style->bg[GTK_STATE_NORMAL]);
899 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
900 &style->bg[GTK_STATE_SELECTED]);
901 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
902 &style->bg[GTK_STATE_INSENSITIVE]);
903 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
904 &style->bg[GTK_STATE_ACTIVE]);
905 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
906 &style->bg[GTK_STATE_PRELIGHT]);
909 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
910 &style->base[GTK_STATE_NORMAL]);
911 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
912 &style->base[GTK_STATE_SELECTED]);
913 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
914 &style->base[GTK_STATE_INSENSITIVE]);
915 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
916 &style->base[GTK_STATE_ACTIVE]);
917 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
918 &style->base[GTK_STATE_PRELIGHT]);
921 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
922 &style->text[GTK_STATE_NORMAL]);
923 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
924 &style->text[GTK_STATE_SELECTED]);
925 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_GRAYTEXT,
926 &style->text[GTK_STATE_INSENSITIVE]);
927 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
928 &style->text[GTK_STATE_ACTIVE]);
929 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
930 &style->text[GTK_STATE_PRELIGHT]);
932 /* Default foreground */
933 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
934 &style->fg[GTK_STATE_NORMAL]);
935 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
936 &style->fg[GTK_STATE_SELECTED]);
937 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_GRAYTEXT,
938 &style->fg[GTK_STATE_INSENSITIVE]);
939 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
940 &style->fg[GTK_STATE_ACTIVE]);
941 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
942 &style->fg[GTK_STATE_PRELIGHT]);
944 for (i = 0; i < 5; i++)
946 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DSHADOW,
948 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DHILIGHT,
952 (style->light[i].red + style->dark[i].red) / 2;
953 style->mid[i].green =
954 (style->light[i].green + style->dark[i].green) / 2;
956 (style->light[i].blue + style->dark[i].blue) / 2;
958 style->text_aa[i].red =
959 (style->text[i].red + style->base[i].red) / 2;
960 style->text_aa[i].green =
961 (style->text[i].green + style->base[i].green) / 2;
962 style->text_aa[i].blue =
963 (style->text[i].blue + style->base[i].blue) / 2;
968 sanitize_size (GdkWindow * window, gint * width, gint * height)
970 gboolean set_bg = FALSE;
972 if ((*width == -1) && (*height == -1))
974 set_bg = GDK_IS_WINDOW (window);
975 gdk_drawable_get_size (window, width, height);
977 else if (*width == -1)
978 gdk_drawable_get_size (window, width, NULL);
979 else if (*height == -1)
980 gdk_drawable_get_size (window, NULL, height);
985 static XpThemeElement
986 map_gtk_progress_bar_to_xp (GtkProgressBar * progress_bar, gboolean trough)
990 switch (progress_bar->orientation)
992 case GTK_PROGRESS_LEFT_TO_RIGHT:
993 case GTK_PROGRESS_RIGHT_TO_LEFT:
995 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_H
996 : XP_THEME_ELEMENT_PROGRESS_BAR_H;
1000 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_V
1001 : XP_THEME_ELEMENT_PROGRESS_BAR_V;
1008 is_combo_box_child (GtkWidget* w)
1015 for (tmp = w->parent; tmp; tmp = tmp->parent)
1017 if (GTK_IS_COMBO_BOX(tmp))
1025 combo_box_draw_arrow (GtkStyle * style,
1028 GdkRectangle * area,
1034 if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
1035 style, widget->allocation.x, widget->allocation.y,
1036 widget->allocation.width, widget->allocation.height,
1041 else if ( !xp_theme_is_active () && widget && GTK_IS_TOGGLE_BUTTON(widget->parent) )
1043 dc = get_window_dc( style, window, state, area->x, area->y, area->width, area->height, &rect );
1044 InflateRect( &rect, 1, 1 );
1045 DrawFrameControl( dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN |
1046 (GTK_TOGGLE_BUTTON(widget->parent)->active ? DFCS_PUSHED|DFCS_FLAT : 0) );
1047 release_window_dc( style, window, state );
1053 /* This is ugly because no box drawing function is invoked for the combo
1054 box as a whole, so we draw part of the entire box in every subwidget.
1055 We do this by finding the allocation of the combo box in the given
1056 window's coordinates and drawing. The xp drawing routines take care
1059 combo_box_draw_box (GtkStyle * style,
1061 GtkStateType state_type,
1062 GtkShadowType shadow_type,
1063 GdkRectangle * area,
1065 const gchar * detail, gint x, gint y, gint width, gint height)
1067 GtkWidget* combo_box;
1068 GdkRectangle combo_alloc;
1074 for (combo_box = widget->parent; combo_box; combo_box = combo_box->parent)
1076 if (GTK_IS_COMBO_BOX(combo_box))
1082 combo_alloc = combo_box->allocation;
1083 if (window != combo_box->window)
1086 for (tmp = widget; tmp && tmp != combo_box; tmp = widget->parent)
1088 if (tmp->parent && tmp->window != tmp->parent->window)
1090 combo_alloc.x -= tmp->allocation.x;
1091 combo_alloc.y -= tmp->allocation.y;
1096 if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
1097 style, combo_alloc.x, combo_alloc.y,
1098 combo_alloc.width, combo_alloc.height,
1104 gboolean rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
1106 if( !strcmp(detail, "button") )
1107 edges = BF_BOTTOM|BF_TOP|(rtl ? BF_LEFT : BF_RIGHT);
1108 else if( !strcmp( detail, "frame") || !strcmp( detail, "entry" ) )
1109 edges = BF_BOTTOM|BF_TOP|(rtl ? BF_RIGHT : BF_LEFT);
1112 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1113 DrawEdge( dc, &rect, EDGE_SUNKEN, edges );
1115 /* Fill blank area between frame/entry and button */
1116 if( !strcmp(detail, "button") ) { /* button */
1118 rect.left = rect.right;
1122 rect.right = rect.left + 2;
1124 else{ /* frame or entry */
1126 rect.right = rect.left;
1130 rect.left = rect.right - 2;
1134 FillRect( dc, &rect, GetSysColorBrush(COLOR_WINDOW) );
1135 release_window_dc( style, window, state_type );
1143 draw_part (GdkDrawable * drawable,
1144 GdkGC * gc, GdkRectangle * area, gint x, gint y, Part part)
1147 gdk_gc_set_clip_rectangle (gc, area);
1149 if (!parts[part].bmap)
1150 parts[part].bmap = gdk_bitmap_create_from_data (drawable,
1152 PART_SIZE, PART_SIZE);
1154 gdk_gc_set_ts_origin (gc, x, y);
1155 gdk_gc_set_stipple (gc, parts[part].bmap);
1156 gdk_gc_set_fill (gc, GDK_STIPPLED);
1158 gdk_draw_rectangle (drawable, gc, TRUE, x, y, PART_SIZE, PART_SIZE);
1160 gdk_gc_set_fill (gc, GDK_SOLID);
1163 gdk_gc_set_clip_rectangle (gc, NULL);
1167 draw_check (GtkStyle * style,
1170 GtkShadowType shadow,
1171 GdkRectangle * area,
1173 const gchar * detail, gint x, gint y, gint width, gint height)
1175 x -= (1 + PART_SIZE - width) / 2;
1176 y -= (1 + PART_SIZE - height) / 2;
1178 if (detail && strcmp (detail, "check") == 0) /* Menu item */
1180 if (shadow == GTK_SHADOW_IN)
1182 draw_part (window, style->black_gc, area, x, y,
1184 draw_part (window, style->dark_gc[state], area, x, y,
1190 if (!xp_theme_draw (window, shadow == GTK_SHADOW_IN
1191 ? XP_THEME_ELEMENT_PRESSED_CHECKBOX
1192 : XP_THEME_ELEMENT_CHECKBOX,
1193 style, x, y, width, height, state, area))
1195 if( detail && !strcmp(detail, "cellcheck") )
1196 state = GTK_STATE_NORMAL;
1198 draw_part (window, style->black_gc, area, x, y,
1200 draw_part (window, style->dark_gc[state], area, x, y,
1202 draw_part (window, style->mid_gc[state], area, x, y,
1204 draw_part (window, style->light_gc[state], area, x, y,
1206 draw_part (window, style->base_gc[state], area, x, y,
1209 if (shadow == GTK_SHADOW_IN)
1211 draw_part (window, style->text_gc[state], area, x,
1213 draw_part (window, style->text_aa_gc[state], area,
1221 draw_expander (GtkStyle * style,
1224 GdkRectangle * area,
1226 const gchar * detail,
1227 gint x, gint y, GtkExpanderStyle expander_style)
1230 gint expander_semi_size;
1231 XpThemeElement xp_expander;
1233 gtk_widget_style_get (widget, "expander_size", &expander_size, NULL);
1235 switch (expander_style)
1237 case GTK_EXPANDER_COLLAPSED:
1238 case GTK_EXPANDER_SEMI_COLLAPSED:
1239 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED;
1242 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED;
1246 if ((expander_size % 2) == 0)
1249 if (expander_size > 2)
1253 gdk_gc_set_clip_rectangle (style->fg_gc[state], area);
1255 expander_semi_size = expander_size / 2;
1256 x -= expander_semi_size;
1257 y -= expander_semi_size;
1259 if (!xp_theme_draw (window, xp_expander, style,
1260 x, y, expander_size, expander_size, state, area))
1267 dc = get_window_dc( style, window, state, x, y, expander_size, expander_size, &rect );
1268 FrameRect( dc, &rect, GetSysColorBrush(COLOR_GRAYTEXT) );
1269 InflateRect( &rect, -1, -1 );
1270 FillRect( dc, &rect, GetSysColorBrush(state == GTK_STATE_INSENSITIVE ? COLOR_BTNFACE : COLOR_WINDOW) );
1272 InflateRect( &rect, -1, -1 );
1274 pen = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_WINDOWTEXT) );
1275 old_pen = SelectObject( dc, pen );
1277 MoveToEx( dc, rect.left, rect.top - 2 + expander_semi_size, NULL );
1278 LineTo( dc, rect.right, rect.top - 2 + expander_semi_size );
1280 if( expander_style == GTK_EXPANDER_COLLAPSED ||
1281 expander_style == GTK_EXPANDER_SEMI_COLLAPSED )
1283 MoveToEx( dc, rect.left - 2 + expander_semi_size, rect.top, NULL );
1284 LineTo( dc, rect.left - 2 + expander_semi_size, rect.bottom );
1287 SelectObject( dc, old_pen );
1288 DeleteObject( pen );
1289 release_window_dc( style, window, state );
1293 gdk_gc_set_clip_rectangle (style->fg_gc[state], NULL);
1297 draw_option (GtkStyle * style,
1300 GtkShadowType shadow,
1301 GdkRectangle * area,
1303 const gchar * detail, gint x, gint y, gint width, gint height)
1305 x -= (1 + PART_SIZE - width) / 2;
1306 y -= (1 + PART_SIZE - height) / 2;
1308 if (detail && strcmp (detail, "option") == 0) /* Menu item */
1310 if (shadow == GTK_SHADOW_IN)
1311 draw_part (window, style->fg_gc[state], area, x, y,
1316 if (xp_theme_draw (window, shadow == GTK_SHADOW_IN
1317 ? XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON
1318 : XP_THEME_ELEMENT_RADIO_BUTTON,
1319 style, x, y, width, height, state, area))
1324 if( detail && !strcmp(detail, "cellradio") )
1325 state = GTK_STATE_NORMAL;
1327 draw_part (window, style->black_gc, area, x, y,
1329 draw_part (window, style->dark_gc[state], area, x, y,
1331 draw_part (window, style->mid_gc[state], area, x, y,
1333 draw_part (window, style->light_gc[state], area, x, y,
1335 draw_part (window, style->base_gc[state], area, x, y,
1338 if (shadow == GTK_SHADOW_IN)
1339 draw_part (window, style->text_gc[state], area, x, y,
1346 draw_varrow (GdkWindow * window,
1348 GtkShadowType shadow_type,
1349 GdkRectangle * area,
1350 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1353 gint y_start, y_increment;
1357 gdk_gc_set_clip_rectangle (gc, area);
1359 width = width + width % 2 - 1; /* Force odd */
1360 steps = 1 + width / 2;
1361 extra = height - steps;
1363 if (arrow_type == GTK_ARROW_DOWN)
1370 y_start = y + height - 1;
1374 for (i = extra; i < height; i++)
1376 gdk_draw_line (window, gc,
1377 x + (i - extra), y_start + i * y_increment,
1378 x + width - (i - extra) - 1,
1379 y_start + i * y_increment);
1383 gdk_gc_set_clip_rectangle (gc, NULL);
1387 draw_harrow (GdkWindow * window,
1389 GtkShadowType shadow_type,
1390 GdkRectangle * area,
1391 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1394 gint x_start, x_increment;
1398 gdk_gc_set_clip_rectangle (gc, area);
1400 height = height + height % 2 - 1; /* Force odd */
1401 steps = 1 + height / 2;
1402 extra = width - steps;
1404 if (arrow_type == GTK_ARROW_RIGHT)
1411 x_start = x + width - 1;
1415 for (i = extra; i < width; i++)
1417 gdk_draw_line (window, gc,
1418 x_start + i * x_increment, y + (i - extra),
1419 x_start + i * x_increment,
1420 y + height - (i - extra) - 1);
1425 gdk_gc_set_clip_rectangle (gc, NULL);
1428 /* This function makes up for some brokeness in gtkrange.c
1429 * where we never get the full arrow of the stepper button
1430 * and the type of button in a single drawing function.
1432 * It doesn't work correctly when the scrollbar is squished
1433 * to the point we don't have room for full-sized steppers.
1436 reverse_engineer_stepper_box (GtkWidget * range,
1437 GtkArrowType arrow_type,
1438 gint * x, gint * y, gint * width, gint * height)
1440 gint slider_width = 14, stepper_size = 14;
1446 gtk_widget_style_get (range,
1447 "slider_width", &slider_width,
1448 "stepper_size", &stepper_size, NULL);
1451 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1453 box_width = slider_width;
1454 box_height = stepper_size;
1458 box_width = stepper_size;
1459 box_height = slider_width;
1462 *x = *x - (box_width - *width) / 2;
1463 *y = *y - (box_height - *height) / 2;
1465 *height = box_height;
1468 static XpThemeElement
1469 to_xp_arrow (GtkArrowType arrow_type)
1471 XpThemeElement xp_arrow;
1476 xp_arrow = XP_THEME_ELEMENT_ARROW_UP;
1478 case GTK_ARROW_DOWN:
1479 xp_arrow = XP_THEME_ELEMENT_ARROW_DOWN;
1481 case GTK_ARROW_LEFT:
1482 xp_arrow = XP_THEME_ELEMENT_ARROW_LEFT;
1485 xp_arrow = XP_THEME_ELEMENT_ARROW_RIGHT;
1493 draw_arrow (GtkStyle * style,
1496 GtkShadowType shadow,
1497 GdkRectangle * area,
1499 const gchar * detail,
1500 GtkArrowType arrow_type,
1501 gboolean fill, gint x, gint y, gint width, gint height)
1507 name = gtk_widget_get_name (widget);
1509 sanitize_size (window, &width, &height);
1511 if (GTK_IS_ARROW(widget) && is_combo_box_child(widget))
1513 if (combo_box_draw_arrow (style, window, state, area, widget))
1519 if (detail && strcmp (detail, "spinbutton") == 0)
1521 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1528 if( arrow_type == GTK_ARROW_DOWN )
1532 if( state == GTK_STATE_ACTIVE ) {
1536 draw_varrow (window, style->fg_gc[state], shadow, area,
1537 arrow_type, x, y, width, height);
1540 else if (detail && (!strcmp (detail, "vscrollbar")
1541 || !strcmp (detail, "hscrollbar")))
1543 gboolean is_disabled = FALSE;
1545 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1549 gint box_width = width;
1550 gint box_height = height;
1552 reverse_engineer_stepper_box (widget, arrow_type,
1553 &box_x, &box_y, &box_width,
1556 if (scrollbar->range.adjustment->page_size >=
1557 (scrollbar->range.adjustment->upper -
1558 scrollbar->range.adjustment->lower))
1562 (window, to_xp_arrow (arrow_type), style, box_x, box_y,
1563 box_width, box_height, state, area))
1571 btn_type = DFCS_SCROLLUP;
1573 case GTK_ARROW_DOWN:
1574 btn_type = DFCS_SCROLLDOWN;
1576 case GTK_ARROW_LEFT:
1577 btn_type = DFCS_SCROLLLEFT;
1579 case GTK_ARROW_RIGHT:
1580 btn_type = DFCS_SCROLLRIGHT;
1583 if( state == GTK_STATE_INSENSITIVE )
1584 btn_type |= DFCS_INACTIVE;
1586 sanitize_size (window, &width, &height);
1588 dc = get_window_dc( style, window, state,
1589 box_x, box_y, box_width, box_height, &rect );
1590 DrawFrameControl( dc, &rect, DFC_SCROLL,
1591 btn_type|(shadow == GTK_SHADOW_IN ? (DFCS_PUSHED|DFCS_FLAT) : 0) );
1592 release_window_dc( style, window, state );
1598 /* draw the toolbar chevrons - waiting for GTK 2.4 */
1599 if (name && !strcmp (name, "gtk-toolbar-arrow"))
1602 (window, XP_THEME_ELEMENT_REBAR_CHEVRON, style, x, y,
1603 width, height, state, area))
1606 /* probably a gtk combo box on a toolbar */
1607 else if (0 /* widget->parent && GTK_IS_BUTTON
1608 (widget->parent) */ )
1611 (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x - 3,
1612 widget->allocation.y + 1, width + 5,
1613 widget->allocation.height - 4, state, area))
1617 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1619 x += (width - 7) / 2;
1620 y += (height - 5) / 2;
1622 draw_varrow (window, style->fg_gc[state], shadow, area,
1623 arrow_type, x, y, 7, 5);
1627 x += (width - 5) / 2;
1628 y += (height - 7) / 2;
1630 draw_harrow (window, style->fg_gc[state], shadow, area,
1631 arrow_type, x, y, 5, 7);
1637 option_menu_get_props (GtkWidget * widget,
1638 GtkRequisition * indicator_size,
1639 GtkBorder * indicator_spacing)
1641 GtkRequisition *tmp_size = NULL;
1642 GtkBorder *tmp_spacing = NULL;
1645 gtk_widget_style_get (widget,
1646 "indicator_size", &tmp_size,
1647 "indicator_spacing", &tmp_spacing, NULL);
1651 *indicator_size = *tmp_size;
1655 *indicator_size = default_option_indicator_size;
1659 *indicator_spacing = *tmp_spacing;
1660 g_free (tmp_spacing);
1663 *indicator_spacing = default_option_indicator_spacing;
1667 is_toolbar_child (GtkWidget * wid)
1671 if (GTK_IS_TOOLBAR (wid) || GTK_IS_HANDLE_BOX (wid))
1681 is_menu_tool_button_child (GtkWidget * wid)
1685 if (GTK_IS_MENU_TOOL_BUTTON (wid) )
1693 HDC get_window_dc(GtkStyle * style, GdkWindow * window, GtkStateType state_type, gint x, gint y, gint width, gint height, RECT *rect)
1696 GdkDrawable *drawable;
1698 if (!GDK_IS_WINDOW (window))
1706 gdk_window_get_internal_paint_info (window, &drawable, &xoff, &yoff);
1709 rect->left = x - xoff;
1710 rect->top = y - yoff;
1711 rect->right = rect->left + width;
1712 rect->bottom = rect->top + height;
1714 return gdk_win32_hdc_get (drawable, style->dark_gc[state_type], 0);
1717 void release_window_dc(GtkStyle * style, GdkWindow * window, GtkStateType state_type)
1719 GdkDrawable *drawable;
1721 if (!GDK_IS_WINDOW (window))
1727 gdk_window_get_internal_paint_info (window, &drawable, NULL, NULL);
1730 gdk_win32_hdc_release (drawable, style->dark_gc[state_type], 0);
1733 static HPEN get_light_pen()
1735 if( ! g_light_pen ) {
1736 g_light_pen = CreatePen( PS_SOLID|PS_INSIDEFRAME, 1, GetSysColor(COLOR_BTNHIGHLIGHT) );
1741 static HPEN get_dark_pen()
1743 if( ! g_dark_pen ) {
1744 g_dark_pen = CreatePen( PS_SOLID|PS_INSIDEFRAME, 1, GetSysColor(COLOR_BTNSHADOW) );
1750 draw_3d_border( HDC hdc, RECT* rc, gboolean sunken )
1756 pen1 = get_dark_pen();
1757 pen2 = get_light_pen();
1760 pen1 = get_light_pen();
1761 pen2 = get_dark_pen();
1764 MoveToEx( hdc, rc->left, rc->bottom - 1, NULL);
1766 old_pen = SelectObject( hdc, pen1 );
1767 LineTo( hdc, rc->left, rc->top );
1768 LineTo( hdc, rc->right-1, rc->top );
1769 SelectObject( hdc, old_pen );
1771 old_pen = SelectObject( hdc, pen2 );
1772 LineTo( hdc, rc->right-1, rc->bottom-1 );
1773 LineTo( hdc, rc->left, rc->bottom-1 );
1774 SelectObject( hdc, old_pen );
1778 draw_menu_item(GdkWindow* window, GtkWidget* widget, GtkStyle* style,
1779 gint x, gint y, gint width, gint height,
1780 GtkStateType state_type, GdkRectangle* area )
1787 if ( xp_theme_is_active() ) {
1788 return xp_theme_draw( window, XP_THEME_ELEMENT_MENU_ITEM, style,
1789 x, y, width, height, state_type, area );
1792 if( (parent = gtk_widget_get_parent(widget))
1793 && GTK_IS_MENU_BAR(parent) )
1795 bar = GTK_MENU_SHELL(parent);
1797 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1798 if( state_type == GTK_STATE_PRELIGHT ){
1799 draw_3d_border( dc, &rect, bar->active );
1801 release_window_dc( style, window, state_type );
1808 get_dither_brush( void )
1811 HBITMAP pattern_bmp;
1814 if( g_dither_brush )
1815 return g_dither_brush;
1816 for ( i = 0; i < 8; i++ )
1817 pattern[i] = (WORD)(0x5555 << (i & 1));
1818 pattern_bmp = CreateBitmap(8, 8, 1, 1, &pattern);
1820 g_dither_brush = CreatePatternBrush(pattern_bmp);
1821 DeleteObject(pattern_bmp);
1823 return g_dither_brush;
1827 draw_tool_button(GdkWindow* window, GtkWidget* widget, GtkStyle* style,
1828 gint x, gint y, gint width, gint height,
1829 GtkStateType state_type, GdkRectangle* area )
1833 gboolean is_toggled = FALSE;
1835 if ( xp_theme_is_active() ) {
1836 return (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
1837 x, y, width, height, state_type, area) );
1840 if( GTK_IS_TOGGLE_BUTTON(widget) ){
1841 if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ) {
1846 if( state_type != GTK_STATE_PRELIGHT
1847 && state_type != GTK_STATE_ACTIVE && !is_toggled )
1850 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1851 if( state_type == GTK_STATE_PRELIGHT ){
1853 FillRect( dc, &rect, GetSysColorBrush(COLOR_BTNFACE));
1855 draw_3d_border( dc, &rect, is_toggled);
1857 else if ( state_type == GTK_STATE_ACTIVE ){
1858 if( is_toggled && ! is_menu_tool_button_child(widget->parent) ){
1859 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
1860 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
1861 FillRect( dc, &rect, get_dither_brush() );
1863 draw_3d_border( dc, &rect, TRUE );
1865 release_window_dc( style, window, state_type );
1870 draw_push_button( GdkWindow* window, GtkWidget* widget, GtkStyle* style, gint x, gint y,
1871 gint width, gint height,
1872 GtkStateType state_type, gboolean is_default )
1877 dc = get_window_dc( style, window, state_type,
1878 x, y, width, height, &rect );
1879 if( GTK_IS_TOGGLE_BUTTON(widget) ) {
1880 if( state_type == GTK_STATE_PRELIGHT &&
1881 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) )
1883 state_type = GTK_STATE_ACTIVE;
1887 if( state_type == GTK_STATE_ACTIVE ) {
1888 if( GTK_IS_TOGGLE_BUTTON(widget) ) {
1889 DrawEdge( dc, &rect, EDGE_SUNKEN, BF_RECT|BF_ADJUST);
1890 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
1891 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
1892 FillRect( dc, &rect, get_dither_brush() );
1895 FrameRect( dc, &rect, GetSysColorBrush(COLOR_WINDOWFRAME) );
1896 InflateRect( &rect, -1, -1 );
1897 FrameRect( dc, &rect, GetSysColorBrush(COLOR_BTNSHADOW) );
1898 InflateRect( &rect, -1, -1 );
1899 FillRect( dc, &rect, GetSysColorBrush(COLOR_BTNFACE) );
1903 if( is_default || GTK_WIDGET_HAS_FOCUS(widget) ) {
1904 FrameRect( dc, &rect, GetSysColorBrush(COLOR_WINDOWFRAME) );
1905 InflateRect( &rect, -1, -1 );
1907 DrawFrameControl( dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH );
1909 release_window_dc(style, window, state_type);
1913 draw_box (GtkStyle * style,
1915 GtkStateType state_type,
1916 GtkShadowType shadow_type,
1917 GdkRectangle * area,
1919 const gchar * detail, gint x, gint y, gint width, gint height)
1921 if (is_combo_box_child (widget)
1922 && combo_box_draw_box (style, window, state_type, shadow_type,
1923 area, widget, detail, x, y, width, height))
1928 (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
1930 if (GTK_IS_TREE_VIEW (widget->parent)
1931 || GTK_IS_CLIST (widget->parent))
1934 (window, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
1935 width, height, state_type, area))
1940 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1942 DrawFrameControl( dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH |
1943 (state_type == GTK_STATE_ACTIVE ? (DFCS_PUSHED|DFCS_FLAT) : 0 ) );
1944 release_window_dc( style, window, state_type );
1947 else if (is_toolbar_child (widget->parent)
1948 || (GTK_RELIEF_NONE == gtk_button_get_relief(GTK_BUTTON(widget)) ) )
1950 if( draw_tool_button( window, widget, style, x, y,
1951 width, height, state_type, area ) )
1958 gboolean is_default = GTK_WIDGET_HAS_DEFAULT(widget);
1961 is_default ? XP_THEME_ELEMENT_DEFAULT_BUTTON :
1962 XP_THEME_ELEMENT_BUTTON, style, x, y, width, height,
1967 draw_push_button( window, widget, style,
1968 x, y, width, height, state_type, is_default );
1973 else if (detail && !strcmp (detail, "spinbutton"))
1975 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1980 else if (detail && (!strcmp (detail, "spinbutton_up")
1981 || !strcmp (detail, "spinbutton_down")))
1983 if ( ! xp_theme_draw ( window,
1984 (!strcmp (detail, "spinbutton_up"))
1985 ? XP_THEME_ELEMENT_SPIN_BUTTON_UP
1986 : XP_THEME_ELEMENT_SPIN_BUTTON_DOWN,
1987 style, x, y, width, height, state_type, area))
1991 gboolean rtl = (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL);
1992 gboolean up = !strcmp (detail, "spinbutton_up");
1994 dc = get_window_dc( style, window, state_type,
1995 x, y, width, height, &rect );
1996 DrawEdge( dc, &rect,
1997 state_type == GTK_STATE_ACTIVE ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT );
1998 release_window_dc( style, window, state_type );
2002 else if (detail && !strcmp (detail, "slider"))
2004 if (GTK_IS_SCROLLBAR (widget))
2006 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
2007 gboolean is_v = GTK_IS_VSCROLLBAR (widget);
2009 if (xp_theme_draw (window,
2011 ? XP_THEME_ELEMENT_SCROLLBAR_V
2012 : XP_THEME_ELEMENT_SCROLLBAR_H,
2013 style, x, y, width, height, state_type,
2016 XpThemeElement gripper =
2017 (is_v ? XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V :
2018 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H);
2020 /* Do not display grippers on tiny scroll bars,
2021 the limit imposed is rather arbitrary, perhaps
2022 we can fetch the gripper geometry from
2023 somewhere and use that... */
2025 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H
2028 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V
2034 xp_theme_draw (window, gripper, style, x, y,
2035 width, height, state_type, area);
2040 if (scrollbar->range.adjustment->page_size >=
2041 (scrollbar->range.adjustment->upper -
2042 scrollbar->range.adjustment->lower))
2047 else if (detail && !strcmp (detail, "bar"))
2049 if (widget && GTK_IS_PROGRESS_BAR (widget))
2051 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2052 XpThemeElement xp_progress_bar =
2053 map_gtk_progress_bar_to_xp (progress_bar, FALSE);
2055 (window, xp_progress_bar, style, x, y, width, height,
2062 else if (detail && strcmp (detail, "menuitem") == 0)
2064 shadow_type = GTK_SHADOW_NONE;
2065 if( draw_menu_item(window, widget, style,
2066 x, y, width, height, state_type, area ) )
2071 else if (detail && !strcmp (detail, "trough"))
2073 if (widget && GTK_IS_PROGRESS_BAR (widget))
2075 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2076 XpThemeElement xp_progress_bar =
2077 map_gtk_progress_bar_to_xp (progress_bar, TRUE);
2079 (window, xp_progress_bar, style, x, y, width, height,
2086 /* Blank in classic Windows */
2089 else if (widget && GTK_IS_SCROLLBAR (widget))
2091 gboolean is_vertical = GTK_IS_VSCROLLBAR (widget);
2093 if (xp_theme_draw (window,
2095 ? XP_THEME_ELEMENT_TROUGH_V
2096 : XP_THEME_ELEMENT_TROUGH_H,
2098 x, y, width, height, state_type, area))
2107 sanitize_size (window, &width, &height);
2108 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2109 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
2110 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
2111 FillRect( dc, &rect, get_dither_brush() );
2112 release_window_dc( style, window, state_type );
2117 else if (widget && GTK_IS_SCALE (widget))
2119 gboolean is_vertical = GTK_IS_VSCALE (widget);
2121 if (!xp_theme_is_active ())
2123 parent_class->draw_box (style, window, state_type,
2124 GTK_SHADOW_NONE, area,
2125 widget, detail, x, y,
2132 (window, XP_THEME_ELEMENT_SCALE_TROUGH_V,
2133 style, (2 * x + width) / 2, y, 2, height,
2137 parent_class->draw_box (style, window, state_type,
2138 GTK_SHADOW_ETCHED_IN,
2140 (2 * x + width) / 2, y, 1,
2146 (window, XP_THEME_ELEMENT_SCALE_TROUGH_H,
2147 style, x, (2 * y + height) / 2, width, 2,
2151 parent_class->draw_box (style, window, state_type,
2152 GTK_SHADOW_ETCHED_IN,
2153 area, NULL, NULL, x,
2154 (2 * y + height) / 2,
2160 else if (detail && strcmp (detail, "optionmenu") == 0)
2162 if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
2163 style, x, y, width, height, state_type, area))
2169 && (strcmp (detail, "vscrollbar") == 0
2170 || strcmp (detail, "hscrollbar") == 0))
2175 && (strcmp (detail, "handlebox_bin") == 0
2176 || strcmp (detail, "toolbar") == 0
2177 || strcmp (detail, "menubar") == 0))
2179 sanitize_size( window, &width, &height );
2180 if (xp_theme_draw (window, XP_THEME_ELEMENT_REBAR,
2181 style, x, y, width, height, state_type, area))
2186 else if (detail && (!strcmp (detail, "handlebox"))) /* grip */
2188 if( !xp_theme_is_active() ) {
2194 const gchar *name = gtk_widget_get_name (widget);
2196 if (name && !strcmp (name, "gtk-tooltips"))
2199 (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
2200 height, state_type, area))
2210 hdc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2212 brush = GetSysColorBrush (COLOR_3DDKSHADOW);
2214 FrameRect (hdc, &rect, brush);
2215 InflateRect (&rect, -1, -1);
2216 FillRect (hdc, &rect,
2217 (HBRUSH) (COLOR_INFOBK + 1));
2219 release_window_dc (style, window, state_type);
2227 parent_class->draw_box (style, window, state_type, shadow_type, area,
2228 widget, detail, x, y, width, height);
2230 if (detail && strcmp (detail, "optionmenu") == 0)
2232 GtkRequisition indicator_size;
2233 GtkBorder indicator_spacing;
2236 option_menu_get_props (widget, &indicator_size,
2237 &indicator_spacing);
2239 sanitize_size (window, &width, &height);
2241 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
2243 x + indicator_size.width + indicator_spacing.left +
2244 indicator_spacing.right;
2247 x + width - (indicator_size.width +
2248 indicator_spacing.left +
2249 indicator_spacing.right) - style->xthickness;
2251 parent_class->draw_vline (style, window, state_type, area, widget,
2253 y + style->ythickness + 1,
2254 y + height - style->ythickness - 3,
2260 draw_tab (GtkStyle * style,
2263 GtkShadowType shadow,
2264 GdkRectangle * area,
2266 const gchar * detail, gint x, gint y, gint width, gint height)
2268 GtkRequisition indicator_size;
2269 GtkBorder indicator_spacing;
2273 g_return_if_fail (style != NULL);
2274 g_return_if_fail (window != NULL);
2276 if (detail && !strcmp (detail, "optionmenutab"))
2278 if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
2279 style, x - 5, widget->allocation.y + 1,
2280 width + 10, widget->allocation.height - 2,
2288 gtk_widget_style_get (widget, "indicator_size", &indicator_size,
2291 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2293 x += (width - indicator_size.width) / 2;
2294 arrow_height = (indicator_size.width + 1) / 2;
2296 y += (height - arrow_height) / 2;
2298 draw_varrow (window, style->black_gc, shadow, area, GTK_ARROW_DOWN,
2299 x, y, indicator_size.width, arrow_height);
2302 /* Draw classic Windows tab - thanks Mozilla!
2303 (no system API for this, but DrawEdge can draw all the parts of a tab) */
2304 static void DrawTab(HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
2305 gboolean aDrawLeft, gboolean aDrawRight)
2307 gint32 leftFlag, topFlag, rightFlag, lightFlag, shadeFlag;
2308 RECT topRect, sideRect, bottomRect, lightRect, shadeRect;
2309 gint32 selectedOffset, lOffset, rOffset;
2311 selectedOffset = aSelected ? 1 : 0;
2312 lOffset = aDrawLeft ? 2 : 0;
2313 rOffset = aDrawRight ? 2 : 0;
2315 /* Get info for tab orientation/position (Left, Top, Right, Bottom) */
2316 switch (aPosition) {
2318 leftFlag = BF_TOP; topFlag = BF_LEFT;
2319 rightFlag = BF_BOTTOM;
2320 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2321 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2323 SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
2324 SetRect(&sideRect, R.left+2, R.top, R.right-2+selectedOffset, R.bottom);
2325 SetRect(&bottomRect, R.right-2, R.top, R.right, R.bottom);
2326 SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
2327 SetRect(&shadeRect, R.left+1, R.bottom-2, R.left+2, R.bottom-1);
2330 leftFlag = BF_LEFT; topFlag = BF_TOP;
2331 rightFlag = BF_RIGHT;
2332 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2333 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2335 SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
2336 SetRect(&sideRect, R.left, R.top+2, R.right, R.bottom-1+selectedOffset);
2337 SetRect(&bottomRect, R.left, R.bottom-1, R.right, R.bottom);
2338 SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
2339 SetRect(&shadeRect, R.right-2, R.top+1, R.right-1, R.top+2);
2342 leftFlag = BF_TOP; topFlag = BF_RIGHT;
2343 rightFlag = BF_BOTTOM;
2344 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2345 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2347 SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
2348 SetRect(&sideRect, R.left+2-selectedOffset, R.top, R.right-2, R.bottom);
2349 SetRect(&bottomRect, R.left, R.top, R.left+2, R.bottom);
2350 SetRect(&lightRect, R.right-3, R.top, R.right-1, R.top+2);
2351 SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
2354 leftFlag = BF_LEFT; topFlag = BF_BOTTOM;
2355 rightFlag = BF_RIGHT;
2356 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2357 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2359 SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
2360 SetRect(&sideRect, R.left, R.top+2-selectedOffset, R.right, R.bottom-2);
2361 SetRect(&bottomRect, R.left, R.top, R.right, R.top+2);
2362 SetRect(&lightRect, R.left, R.bottom-3, R.left+2, R.bottom-1);
2363 SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
2368 FillRect(hdc, &R, (HBRUSH) (COLOR_3DFACE+1) );
2371 DrawEdge(hdc, &topRect, EDGE_RAISED, BF_SOFT | topFlag);
2375 DrawEdge(hdc, &bottomRect, EDGE_RAISED, BF_SOFT | topFlag);
2382 DrawEdge(hdc, &sideRect, EDGE_RAISED, BF_SOFT | leftFlag | rightFlag);
2384 /* Tab Diagonal Corners */
2386 DrawEdge(hdc, &lightRect, EDGE_RAISED, BF_SOFT | lightFlag);
2389 DrawEdge(hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
2393 draw_extension (GtkStyle * style,
2395 GtkStateType state_type,
2396 GtkShadowType shadow_type,
2397 GdkRectangle * area,
2399 const gchar * detail,
2401 gint y, gint width, gint height, GtkPositionType gap_side)
2403 if (widget && GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "tab"))
2405 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2406 GdkPixmap *pixmap = NULL;
2407 GdkDrawable *target = NULL;
2408 gint x2, y2, w2, h2;
2409 int tab_part = XP_THEME_ELEMENT_TAB_ITEM;
2410 int real_gap_side = gtk_notebook_get_tab_pos (notebook);
2412 /* why this differs from the above gap_side, i have no idea... */
2413 if (real_gap_side == GTK_POS_LEFT || real_gap_side == GTK_POS_RIGHT)
2415 /* Create "rotated" pixmap.. swap width and height */
2416 pixmap = gdk_pixmap_new (window, height, width, -1);
2432 if (xp_theme_draw (target, tab_part, style, x2, y2, w2, h2, state_type, NULL /*area*/))
2434 GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
2435 if (real_gap_side == GTK_POS_BOTTOM)
2436 rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
2437 else if (real_gap_side == GTK_POS_LEFT)
2438 rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
2439 else if (real_gap_side == GTK_POS_RIGHT)
2440 rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
2442 if (rotation != GDK_PIXBUF_ROTATE_NONE)
2444 GdkPixbuf * pixbuf, * rotated;
2446 pixbuf = gdk_pixbuf_get_from_drawable (NULL, target, NULL, x2, y2, 0, 0, w2, h2);
2448 rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
2449 g_object_unref (pixbuf);
2452 if (real_gap_side == GTK_POS_RIGHT || real_gap_side == GTK_POS_LEFT)
2460 gdk_draw_pixbuf (window, NULL, pixbuf, 0, 0, x2, y2, w2, h2, GDK_RGB_DITHER_NONE, 0, 0);
2462 if (real_gap_side == GTK_POS_LEFT || real_gap_side == GTK_POS_RIGHT)
2464 g_object_unref (pixmap);
2468 } else if (real_gap_side == GTK_POS_TOP || real_gap_side == GTK_POS_BOTTOM) {
2469 /* experimental tab-drawing code from mozilla */
2474 dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2476 if (real_gap_side == GTK_POS_TOP)
2478 else if (real_gap_side == GTK_POS_BOTTOM)
2479 aPosition = BF_BOTTOM;
2480 else if (real_gap_side == GTK_POS_LEFT)
2481 aPosition = BF_LEFT;
2483 aPosition = BF_RIGHT;
2485 if( state_type == GTK_STATE_PRELIGHT )
2486 state_type = GTK_STATE_NORMAL;
2488 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2489 DrawTab (dc, rect, aPosition, state_type != GTK_STATE_PRELIGHT, (real_gap_side != GTK_POS_LEFT), (real_gap_side != GTK_POS_RIGHT));
2491 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2493 release_window_dc (style, window, state_type);
2497 parent_class->draw_extension
2498 (style, window, state_type, shadow_type, area, widget, detail,
2499 x, y, width, height, gap_side);
2503 draw_box_gap (GtkStyle * style, GdkWindow * window, GtkStateType state_type,
2504 GtkShadowType shadow_type, GdkRectangle * area,
2505 GtkWidget * widget, const gchar * detail, gint x,
2506 gint y, gint width, gint height, GtkPositionType gap_side,
2507 gint gap_x, gint gap_width)
2509 if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
2511 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style, x,
2512 y, width, height, state_type, area))
2517 parent_class->draw_box_gap (style, window, state_type, shadow_type,
2518 area, widget, detail, x, y, width, height,
2519 gap_side, gap_x, gap_width);
2522 static gboolean is_popup_window_child( GtkWidget* widget )
2525 GtkWindowType type = -1;
2527 top = gtk_widget_get_toplevel( widget );
2528 if( top && GTK_IS_WINDOW(top) ) {
2529 g_object_get(top, "type", &type, NULL );
2530 if( type == GTK_WINDOW_POPUP ) { /* Hack for combo boxes */
2538 draw_flat_box (GtkStyle * style, GdkWindow * window,
2539 GtkStateType state_type, GtkShadowType shadow_type,
2540 GdkRectangle * area, GtkWidget * widget,
2541 const gchar * detail, gint x, gint y, gint width, gint height)
2544 if ( !strcmp (detail, "checkbutton") )
2546 if (state_type == GTK_STATE_PRELIGHT)
2553 parent_class->draw_flat_box (style, window, state_type, shadow_type,
2554 area, widget, detail, x, y, width, height);
2558 draw_menu_border ( GdkWindow* win, GtkStyle* style,
2559 gint x, gint y, gint width, gint height )
2564 dc = get_window_dc (style, win, GTK_STATE_NORMAL, x, y, width, height, &rect );
2567 if( xp_theme_is_active() ) {
2568 FrameRect( dc, &rect, GetSysColorBrush(COLOR_3DSHADOW) );
2571 DrawEdge( dc, &rect, EDGE_RAISED, BF_RECT );
2573 release_window_dc( style, win, GTK_STATE_NORMAL );
2578 draw_shadow (GtkStyle * style,
2580 GtkStateType state_type,
2581 GtkShadowType shadow_type,
2582 GdkRectangle * area,
2584 const gchar * detail, gint x, gint y, gint width, gint height)
2586 gboolean is_handlebox;
2587 gboolean is_toolbar;
2589 if (is_combo_box_child (widget)
2590 && combo_box_draw_box (style, window, state_type, shadow_type,
2591 area, widget, detail, x, y, width, height))
2595 if( detail && !strcmp( detail, "frame") )
2599 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2600 if( is_popup_window_child(widget) ) {
2601 FrameRect( dc, &rect, GetSysColorBrush( COLOR_WINDOWFRAME ) );
2604 switch( shadow_type ){
2606 draw_3d_border(dc, &rect, TRUE);
2608 case GTK_SHADOW_OUT:
2609 draw_3d_border(dc, &rect, FALSE);
2611 case GTK_SHADOW_ETCHED_IN:
2612 draw_3d_border(dc, &rect, TRUE);
2613 InflateRect( &rect, -1, -1 );
2614 draw_3d_border(dc, &rect, FALSE);
2616 case GTK_SHADOW_ETCHED_OUT:
2617 draw_3d_border(dc, &rect, FALSE);
2618 InflateRect( &rect, -1, -1 );
2619 draw_3d_border(dc, &rect, TRUE);
2623 release_window_dc( style, window, state_type );
2626 if (detail && !strcmp (detail, "entry") )
2628 if ( xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2629 x, y, width, height, state_type, area))
2633 if( shadow_type == GTK_SHADOW_IN ) {
2636 dc = get_window_dc( style, window, state_type,
2637 x, y, width, height, &rect );
2638 DrawEdge( dc, &rect, EDGE_SUNKEN, BF_RECT );
2639 release_window_dc( style, window, state_type );
2644 if( detail && !strcmp( detail, "spinbutton" ) )
2649 if (detail && !strcmp (detail, "menu"))
2651 if ( draw_menu_border ( window, style, x, y, width, height ) ) {
2656 if (detail && !strcmp (detail, "handlebox"))
2659 is_handlebox = (detail && !strcmp (detail, "handlebox_bin"));
2660 is_toolbar = (detail && (!strcmp (detail, "toolbar") || !strcmp(detail, "menubar")));
2662 if ( is_toolbar || is_handlebox )
2668 GtkPositionType pos;
2670 sanitize_size (window, &width, &height);
2672 if( is_handlebox ) {
2673 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
2675 If the handle box is at left side,
2676 we shouldn't draw its right border.
2677 The same holds true for top, right, and bottom.
2681 pos = GTK_POS_RIGHT; break;
2683 pos = GTK_POS_LEFT; break;
2685 pos = GTK_POS_BOTTOM; break;
2686 case GTK_POS_BOTTOM:
2687 pos = GTK_POS_TOP; break;
2691 GtkWidget* parent = gtk_widget_get_parent(widget);
2692 /* Dirty hack for toolbars contained in handle boxes */
2693 if( GTK_IS_HANDLE_BOX( parent ) ) {
2694 pos = gtk_handle_box_get_handle_position( GTK_HANDLE_BOX( parent ) );
2699 Make pos != all legal enum vaules of GtkPositionType.
2700 So every border will be draw.
2702 pos = (GtkPositionType)-1;
2706 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2707 if( pos != GTK_POS_LEFT ) {
2708 old_pen = SelectObject( dc, get_light_pen() );
2709 MoveToEx( dc, rect.left, rect.top, NULL );
2710 LineTo( dc, rect.left, rect.bottom );
2712 if( pos != GTK_POS_TOP ) {
2713 old_pen = SelectObject( dc, get_light_pen() );
2714 MoveToEx( dc, rect.left, rect.top, NULL );
2715 LineTo( dc, rect.right, rect.top );
2717 if( pos != GTK_POS_RIGHT ) {
2718 old_pen = SelectObject( dc, get_dark_pen() );
2719 MoveToEx( dc, rect.right-1, rect.top, NULL );
2720 LineTo( dc, rect.right-1, rect.bottom );
2722 if( pos != GTK_POS_BOTTOM ) {
2723 old_pen = SelectObject( dc, get_dark_pen() );
2724 MoveToEx( dc, rect.left, rect.bottom-1, NULL );
2725 LineTo( dc, rect.right, rect.bottom-1 );
2727 SelectObject( dc, old_pen );
2728 release_window_dc( style, window, state_type );
2733 if (detail && !strcmp (detail, "statusbar")) {
2737 parent_class->draw_shadow (style, window, state_type, shadow_type, area,
2738 widget, detail, x, y, width, height);
2742 draw_hline (GtkStyle * style,
2744 GtkStateType state_type,
2745 GdkRectangle * area,
2747 const gchar * detail, gint x1, gint x2, gint y)
2749 if (xp_theme_is_active () && detail && !strcmp(detail, "menuitem")) {
2750 if(xp_theme_draw (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, y, x2, 1, state_type, area))
2754 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2756 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2759 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2762 if( style->ythickness == 2 )
2766 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2767 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2769 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2771 gdk_draw_line (window, style->light_gc[state_type], x1, y, x2, y);
2774 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2775 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2780 parent_class->draw_hline (style, window, state_type, area, widget,
2787 draw_vline (GtkStyle * style,
2789 GtkStateType state_type,
2790 GdkRectangle * area,
2792 const gchar * detail, gint y1, gint y2, gint x)
2794 if( style->xthickness == 2 )
2798 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2799 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2801 gdk_draw_line (window, style->dark_gc[state_type], x, y1, x, y2);
2803 gdk_draw_line (window, style->light_gc[state_type], x, y1, x, y2);
2806 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2807 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2812 parent_class->draw_vline (style, window, state_type, area, widget,
2818 draw_slider (GtkStyle * style,
2820 GtkStateType state_type,
2821 GtkShadowType shadow_type,
2822 GdkRectangle * area,
2824 const gchar * detail,
2826 gint y, gint width, gint height, GtkOrientation orientation)
2828 if (GTK_IS_SCALE (widget) &&
2829 xp_theme_draw (window,
2831 GTK_ORIENTATION_VERTICAL) ?
2832 XP_THEME_ELEMENT_SCALE_SLIDER_V :
2833 XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
2834 height, state_type, area))
2839 parent_class->draw_slider (style, window, state_type, shadow_type, area,
2840 widget, detail, x, y, width, height,
2845 draw_resize_grip (GtkStyle * style,
2847 GtkStateType state_type,
2848 GdkRectangle * area,
2850 const gchar * detail,
2851 GdkWindowEdge edge, gint x, gint y, gint width, gint height)
2853 if (detail && !strcmp (detail, "statusbar"))
2856 (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
2857 height, state_type, area))
2861 HDC dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2864 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2865 DrawFrameControl(dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
2866 release_window_dc(style, window, state_type);
2868 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2873 parent_class->draw_resize_grip (style, window, state_type, area,
2874 widget, detail, edge, x, y, width,
2879 draw_handle (GtkStyle * style,
2881 GtkStateType state_type,
2882 GtkShadowType shadow_type,
2883 GdkRectangle * area,
2885 const gchar * detail,
2887 gint y, gint width, gint height, GtkOrientation orientation)
2892 if (is_toolbar_child (widget))
2894 XpThemeElement hndl;
2896 sanitize_size (window, &width, &height);
2898 if( GTK_IS_HANDLE_BOX(widget) ) {
2899 GtkPositionType pos;
2900 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
2901 if( pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM ) {
2902 orientation = GTK_ORIENTATION_HORIZONTAL;
2905 orientation = GTK_ORIENTATION_VERTICAL;
2909 if ( orientation == GTK_ORIENTATION_VERTICAL )
2910 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_V;
2912 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
2914 if (xp_theme_draw (window, hndl, style, x, y, width, height,
2920 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2921 if ( orientation == GTK_ORIENTATION_VERTICAL ) {
2923 rect.right = rect.left + 3;
2929 rect.bottom = rect.top + 3;
2933 draw_3d_border( dc, &rect, FALSE );
2934 release_window_dc( style, window, state_type );
2938 if (!GTK_IS_PANED (widget))
2940 gint xthick, ythick;
2941 GdkGC *light_gc, *dark_gc, *shadow_gc;
2944 sanitize_size (window, &width, &height);
2946 gtk_paint_box (style, window, state_type, shadow_type, area,
2947 widget, detail, x, y, width, height);
2949 light_gc = style->light_gc[state_type];
2950 dark_gc = style->dark_gc[state_type];
2951 shadow_gc = style->mid_gc[state_type];
2953 xthick = style->xthickness;
2954 ythick = style->ythickness;
2956 dest.x = x + xthick;
2957 dest.y = y + ythick;
2958 dest.width = width - (xthick * 2);
2959 dest.height = height - (ythick * 2);
2961 if (dest.width < dest.height)
2966 gdk_gc_set_clip_rectangle (light_gc, &dest);
2967 gdk_gc_set_clip_rectangle (dark_gc, &dest);
2968 gdk_gc_set_clip_rectangle (shadow_gc, &dest);
2970 if (dest.width < dest.height)
2972 gdk_draw_line (window, light_gc, dest.x, dest.y, dest.x,
2974 gdk_draw_line (window, dark_gc, dest.x + (dest.width / 2),
2975 dest.y, dest.x + (dest.width / 2),
2977 gdk_draw_line (window, shadow_gc, dest.x + dest.width,
2978 dest.y, dest.x + dest.width, dest.height);
2982 gdk_draw_line (window, light_gc, dest.x, dest.y,
2983 dest.x + dest.width, dest.y);
2984 gdk_draw_line (window, dark_gc, dest.x,
2985 dest.y + (dest.height / 2),
2986 dest.x + dest.width,
2987 dest.y + (dest.height / 2));
2988 gdk_draw_line (window, shadow_gc, dest.x,
2989 dest.y + dest.height, dest.x + dest.width,
2990 dest.y + dest.height);
2993 gdk_gc_set_clip_rectangle (shadow_gc, NULL);
2994 gdk_gc_set_clip_rectangle (light_gc, NULL);
2995 gdk_gc_set_clip_rectangle (dark_gc, NULL);
3000 draw_focus ( GtkStyle *style,
3002 GtkStateType state_type,
3005 const gchar *detail,
3013 if( !GTK_WIDGET_CAN_FOCUS(widget) ) {
3016 if( detail && 0 == strcmp(detail, "button")
3017 && GTK_RELIEF_NONE == gtk_button_get_relief( GTK_BUTTON(widget) ) )
3021 if ( is_combo_box_child(widget)
3022 && (GTK_IS_ARROW(widget) || GTK_IS_BUTTON(widget)) ) {
3025 if (GTK_IS_TREE_VIEW (widget->parent) /* list view bheader */
3026 || GTK_IS_CLIST (widget->parent)) {
3030 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
3031 DrawFocusRect(dc, &rect);
3032 release_window_dc( style, window, state_type );
3034 parent_class->draw_focus (style, window, state_type,
3035 area, widget, detail, x, y, width, height);
3040 msw_style_init_from_rc (GtkStyle * style, GtkRcStyle * rc_style)
3042 setup_system_font (style);
3043 setup_menu_settings (gtk_settings_get_default ());
3044 setup_system_styles (style);
3045 parent_class->init_from_rc (style, rc_style);
3049 load_bg_image (GdkColormap *colormap,
3051 const gchar *filename)
3053 if (strcmp (filename, "<parent>") == 0)
3054 return (GdkPixmap*) GDK_PARENT_RELATIVE;
3057 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
3064 msw_style_realize (GtkStyle * style)
3066 GdkGCValues gc_values;
3067 GdkGCValuesMask gc_values_mask;
3071 for (i = 0; i < 5; i++)
3073 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
3074 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
3075 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
3077 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
3078 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
3079 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
3082 style->black.red = 0x0000;
3083 style->black.green = 0x0000;
3084 style->black.blue = 0x0000;
3085 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
3087 style->white.red = 0xffff;
3088 style->white.green = 0xffff;
3089 style->white.blue = 0xffff;
3090 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
3092 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
3094 gc_values.foreground = style->black;
3095 gc_values.background = style->white;
3096 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3098 gc_values.foreground = style->white;
3099 gc_values.background = style->black;
3100 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3102 gc_values_mask = GDK_GC_FOREGROUND;
3104 for (i = 0; i < 5; i++)
3106 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
3107 style->bg_pixmap[i] = load_bg_image (style->colormap,
3109 style->rc_style->bg_pixmap_name[i]);
3111 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
3112 g_warning ("unable to allocate color: ( %d %d %d )",
3113 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
3114 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
3115 g_warning ("unable to allocate color: ( %d %d %d )",
3116 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
3117 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
3118 g_warning ("unable to allocate color: ( %d %d %d )",
3119 style->light[i].red, style->light[i].green, style->light[i].blue);
3120 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
3121 g_warning ("unable to allocate color: ( %d %d %d )",
3122 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
3123 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
3124 g_warning ("unable to allocate color: ( %d %d %d )",
3125 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
3126 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
3127 g_warning ("unable to allocate color: ( %d %d %d )",
3128 style->text[i].red, style->text[i].green, style->text[i].blue);
3129 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
3130 g_warning ("unable to allocate color: ( %d %d %d )",
3131 style->base[i].red, style->base[i].green, style->base[i].blue);
3132 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
3133 g_warning ("unable to allocate color: ( %d %d %d )",
3134 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
3136 gc_values.foreground = style->fg[i];
3137 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3139 gc_values.foreground = style->bg[i];
3140 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3142 gc_values.foreground = style->light[i];
3143 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3145 gc_values.foreground = style->dark[i];
3146 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3148 gc_values.foreground = style->mid[i];
3149 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3151 gc_values.foreground = style->text[i];
3152 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3154 gc_values.foreground = style->base[i];
3155 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3157 gc_values.foreground = style->text_aa[i];
3158 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3163 msw_style_unrealize (GtkStyle * style)
3165 parent_class->unrealize (style);
3169 msw_style_class_init (MswStyleClass * klass)
3171 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3173 parent_class = g_type_class_peek_parent (klass);
3175 style_class->init_from_rc = msw_style_init_from_rc;
3176 style_class->draw_arrow = draw_arrow;
3177 style_class->draw_box = draw_box;
3178 style_class->draw_check = draw_check;
3179 style_class->draw_option = draw_option;
3180 style_class->draw_tab = draw_tab;
3181 style_class->draw_flat_box = draw_flat_box;
3182 style_class->draw_expander = draw_expander;
3183 style_class->draw_extension = draw_extension;
3184 style_class->draw_box_gap = draw_box_gap;
3185 style_class->draw_shadow = draw_shadow;
3186 style_class->draw_hline = draw_hline;
3187 style_class->draw_vline = draw_vline;
3188 style_class->draw_handle = draw_handle;
3189 style_class->draw_resize_grip = draw_resize_grip;
3190 style_class->draw_slider = draw_slider;
3191 style_class->draw_focus = draw_focus;
3193 style_class->realize = msw_style_realize;
3194 style_class->unrealize = msw_style_unrealize;
3197 GType msw_type_style = 0;
3200 msw_style_register_type (GTypeModule * module)
3202 static const GTypeInfo object_info = {
3203 sizeof (MswStyleClass),
3204 (GBaseInitFunc) NULL,
3205 (GBaseFinalizeFunc) NULL,
3206 (GClassInitFunc) msw_style_class_init,
3207 NULL, /* class_finalize */
3208 NULL, /* class_data */
3210 0, /* n_preallocs */
3211 (GInstanceInitFunc) NULL,
3214 msw_type_style = g_type_module_register_type (module,
3221 msw_style_init (void)
3224 msw_style_setup_system_settings ();
3225 setup_msw_rc_style ();
3228 DeleteObject( g_light_pen );
3232 DeleteObject( g_dark_pen );
3237 void msw_style_finalize(void)
3239 if( g_dither_brush ){
3240 DeleteObject( g_dither_brush );
3243 DeleteObject( g_light_pen );
3246 DeleteObject( g_dark_pen );