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 /* radio/check button sizes */
834 g_snprintf (buf, sizeof (buf),
835 "style \"msw-checkbutton\" = \"msw-button\"\n"
836 "{GtkCheckButton::indicator-size = 13\n"
837 "}widget_class \"*CheckButton*\" style \"msw-checkbutton\"\n"
838 "widget_class \"*RadioButton*\" style \"msw-checkbutton\"\n");
839 gtk_rc_parse_string (buf);
841 /* size of combo box toggle button */
842 g_snprintf (buf, sizeof(buf),
843 "style \"msw-combo-button\" = \"msw-default\"\n"
847 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
848 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
849 "GtkButton::child-displacement-x = 0\n"
850 "GtkButton::child-displacement-y = 0\n"
851 "GtkWidget::focus-padding = 0\n"
852 "GtkWidget::focus-line-width = 0\n"
854 "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combo-button\"\n");
855 gtk_rc_parse_string (buf);
857 /* size of tree view header */
858 g_snprintf (buf, sizeof(buf),
859 "style \"msw-header-button\" = \"msw-default\"\n"
863 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
864 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
865 "GtkButton::child-displacement-x = 1\n"
866 "GtkButton::child-displacement-y = 1\n"
867 "GtkWidget::focus-padding = 0\n"
868 "GtkWidget::focus-line-width = 0\n"
870 "widget_class \"*TreeView*Button*\" style \"msw-header-button\"\n",
871 xp_theme_is_active() ? 2 : 0 );
872 gtk_rc_parse_string (buf);
874 /* FIXME: This should be enabled once gtk+ support GtkNotebok::prelight-tab */
875 /* enable prelight tab of GtkNotebook */
877 g_snprintf (buf, sizeof (buf),
878 "style \"msw-notebook\" = \"msw-default\"\n"
879 "{GtkNotebook::prelight-tab=1\n"
880 "}widget_class \"*Notebook*\" style \"msw-notebook\"\n");
881 gtk_rc_parse_string (buf);
884 /* FIXME: This should be enabled once gtk+ support GtkTreeView::full-row-focus */
886 g_snprintf (buf, sizeof (buf),
887 "style \"msw-treeview\" = \"msw-default\"\n"
888 "{GtkTreeView::full-row-focus=0\n"
889 "}widget_class \"*TreeView*\" style \"msw-treeview\"\n");
890 gtk_rc_parse_string (buf);
895 setup_system_styles (GtkStyle * style)
899 /* Default background */
900 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
901 &style->bg[GTK_STATE_NORMAL]);
902 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
903 &style->bg[GTK_STATE_SELECTED]);
904 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
905 &style->bg[GTK_STATE_INSENSITIVE]);
906 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
907 &style->bg[GTK_STATE_ACTIVE]);
908 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
909 &style->bg[GTK_STATE_PRELIGHT]);
912 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
913 &style->base[GTK_STATE_NORMAL]);
914 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
915 &style->base[GTK_STATE_SELECTED]);
916 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
917 &style->base[GTK_STATE_INSENSITIVE]);
918 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
919 &style->base[GTK_STATE_ACTIVE]);
920 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
921 &style->base[GTK_STATE_PRELIGHT]);
924 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
925 &style->text[GTK_STATE_NORMAL]);
926 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
927 &style->text[GTK_STATE_SELECTED]);
928 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_GRAYTEXT,
929 &style->text[GTK_STATE_INSENSITIVE]);
930 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
931 &style->text[GTK_STATE_ACTIVE]);
932 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
933 &style->text[GTK_STATE_PRELIGHT]);
935 /* Default foreground */
936 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
937 &style->fg[GTK_STATE_NORMAL]);
938 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
939 &style->fg[GTK_STATE_SELECTED]);
940 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_GRAYTEXT,
941 &style->fg[GTK_STATE_INSENSITIVE]);
942 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
943 &style->fg[GTK_STATE_ACTIVE]);
944 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
945 &style->fg[GTK_STATE_PRELIGHT]);
947 for (i = 0; i < 5; i++)
949 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DSHADOW,
951 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DHILIGHT,
955 (style->light[i].red + style->dark[i].red) / 2;
956 style->mid[i].green =
957 (style->light[i].green + style->dark[i].green) / 2;
959 (style->light[i].blue + style->dark[i].blue) / 2;
961 style->text_aa[i].red =
962 (style->text[i].red + style->base[i].red) / 2;
963 style->text_aa[i].green =
964 (style->text[i].green + style->base[i].green) / 2;
965 style->text_aa[i].blue =
966 (style->text[i].blue + style->base[i].blue) / 2;
971 sanitize_size (GdkWindow * window, gint * width, gint * height)
973 gboolean set_bg = FALSE;
975 if ((*width == -1) && (*height == -1))
977 set_bg = GDK_IS_WINDOW (window);
978 gdk_drawable_get_size (window, width, height);
980 else if (*width == -1)
981 gdk_drawable_get_size (window, width, NULL);
982 else if (*height == -1)
983 gdk_drawable_get_size (window, NULL, height);
988 static XpThemeElement
989 map_gtk_progress_bar_to_xp (GtkProgressBar * progress_bar, gboolean trough)
993 switch (progress_bar->orientation)
995 case GTK_PROGRESS_LEFT_TO_RIGHT:
996 case GTK_PROGRESS_RIGHT_TO_LEFT:
998 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_H
999 : XP_THEME_ELEMENT_PROGRESS_BAR_H;
1003 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_V
1004 : XP_THEME_ELEMENT_PROGRESS_BAR_V;
1011 is_combo_box_child (GtkWidget* w)
1018 for (tmp = w->parent; tmp; tmp = tmp->parent)
1020 if (GTK_IS_COMBO_BOX(tmp))
1028 combo_box_draw_arrow (GtkStyle * style,
1031 GdkRectangle * area,
1037 if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
1038 style, widget->allocation.x, widget->allocation.y,
1039 widget->allocation.width, widget->allocation.height,
1044 else if ( !xp_theme_is_active () && widget && GTK_IS_TOGGLE_BUTTON(widget->parent) )
1046 dc = get_window_dc( style, window, state, area->x, area->y, area->width, area->height, &rect );
1047 InflateRect( &rect, 1, 1 );
1048 DrawFrameControl( dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN |
1049 (GTK_TOGGLE_BUTTON(widget->parent)->active ? DFCS_PUSHED|DFCS_FLAT : 0) );
1050 release_window_dc( style, window, state );
1056 /* This is ugly because no box drawing function is invoked for the combo
1057 box as a whole, so we draw part of the entire box in every subwidget.
1058 We do this by finding the allocation of the combo box in the given
1059 window's coordinates and drawing. The xp drawing routines take care
1062 combo_box_draw_box (GtkStyle * style,
1064 GtkStateType state_type,
1065 GtkShadowType shadow_type,
1066 GdkRectangle * area,
1068 const gchar * detail, gint x, gint y, gint width, gint height)
1070 GtkWidget* combo_box;
1071 GdkRectangle combo_alloc;
1077 for (combo_box = widget->parent; combo_box; combo_box = combo_box->parent)
1079 if (GTK_IS_COMBO_BOX(combo_box))
1085 combo_alloc = combo_box->allocation;
1086 if (window != combo_box->window)
1089 for (tmp = widget; tmp && tmp != combo_box; tmp = widget->parent)
1091 if (tmp->parent && tmp->window != tmp->parent->window)
1093 combo_alloc.x -= tmp->allocation.x;
1094 combo_alloc.y -= tmp->allocation.y;
1099 if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
1100 style, combo_alloc.x, combo_alloc.y,
1101 combo_alloc.width, combo_alloc.height,
1107 gboolean rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
1109 if( !strcmp(detail, "button") )
1110 edges = BF_BOTTOM|BF_TOP|(rtl ? BF_LEFT : BF_RIGHT);
1111 else if( !strcmp( detail, "frame") || !strcmp( detail, "entry" ) )
1112 edges = BF_BOTTOM|BF_TOP|(rtl ? BF_RIGHT : BF_LEFT);
1115 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1116 DrawEdge( dc, &rect, EDGE_SUNKEN, edges );
1118 /* Fill blank area between frame/entry and button */
1119 if( !strcmp(detail, "button") ) { /* button */
1121 rect.left = rect.right;
1125 rect.right = rect.left + 2;
1127 else{ /* frame or entry */
1129 rect.right = rect.left;
1133 rect.left = rect.right - 2;
1137 FillRect( dc, &rect, GetSysColorBrush(COLOR_WINDOW) );
1138 release_window_dc( style, window, state_type );
1146 draw_part (GdkDrawable * drawable,
1147 GdkGC * gc, GdkRectangle * area, gint x, gint y, Part part)
1150 gdk_gc_set_clip_rectangle (gc, area);
1152 if (!parts[part].bmap)
1153 parts[part].bmap = gdk_bitmap_create_from_data (drawable,
1155 PART_SIZE, PART_SIZE);
1157 gdk_gc_set_ts_origin (gc, x, y);
1158 gdk_gc_set_stipple (gc, parts[part].bmap);
1159 gdk_gc_set_fill (gc, GDK_STIPPLED);
1161 gdk_draw_rectangle (drawable, gc, TRUE, x, y, PART_SIZE, PART_SIZE);
1163 gdk_gc_set_fill (gc, GDK_SOLID);
1166 gdk_gc_set_clip_rectangle (gc, NULL);
1170 draw_check (GtkStyle * style,
1173 GtkShadowType shadow,
1174 GdkRectangle * area,
1176 const gchar * detail, gint x, gint y, gint width, gint height)
1178 x -= (1 + PART_SIZE - width) / 2;
1179 y -= (1 + PART_SIZE - height) / 2;
1181 if (detail && strcmp (detail, "check") == 0) /* Menu item */
1183 if (shadow == GTK_SHADOW_IN)
1185 draw_part (window, style->black_gc, area, x, y,
1187 draw_part (window, style->dark_gc[state], area, x, y,
1193 if (!xp_theme_draw (window, shadow == GTK_SHADOW_IN
1194 ? XP_THEME_ELEMENT_PRESSED_CHECKBOX
1195 : XP_THEME_ELEMENT_CHECKBOX,
1196 style, x, y, width, height, state, area))
1198 if( detail && !strcmp(detail, "cellcheck") )
1199 state = GTK_STATE_NORMAL;
1201 draw_part (window, style->black_gc, area, x, y,
1203 draw_part (window, style->dark_gc[state], area, x, y,
1205 draw_part (window, style->mid_gc[state], area, x, y,
1207 draw_part (window, style->light_gc[state], area, x, y,
1209 draw_part (window, style->base_gc[state], area, x, y,
1212 if (shadow == GTK_SHADOW_IN)
1214 draw_part (window, style->text_gc[state], area, x,
1216 draw_part (window, style->text_aa_gc[state], area,
1224 draw_expander (GtkStyle * style,
1227 GdkRectangle * area,
1229 const gchar * detail,
1230 gint x, gint y, GtkExpanderStyle expander_style)
1233 gint expander_semi_size;
1234 XpThemeElement xp_expander;
1236 gtk_widget_style_get (widget, "expander_size", &expander_size, NULL);
1238 switch (expander_style)
1240 case GTK_EXPANDER_COLLAPSED:
1241 case GTK_EXPANDER_SEMI_COLLAPSED:
1242 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED;
1245 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED;
1249 if ((expander_size % 2) == 0)
1252 if (expander_size > 2)
1256 gdk_gc_set_clip_rectangle (style->fg_gc[state], area);
1258 expander_semi_size = expander_size / 2;
1259 x -= expander_semi_size;
1260 y -= expander_semi_size;
1262 if (!xp_theme_draw (window, xp_expander, style,
1263 x, y, expander_size, expander_size, state, area))
1270 dc = get_window_dc( style, window, state, x, y, expander_size, expander_size, &rect );
1271 FrameRect( dc, &rect, GetSysColorBrush(COLOR_GRAYTEXT) );
1272 InflateRect( &rect, -1, -1 );
1273 FillRect( dc, &rect, GetSysColorBrush(state == GTK_STATE_INSENSITIVE ? COLOR_BTNFACE : COLOR_WINDOW) );
1275 InflateRect( &rect, -1, -1 );
1277 pen = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_WINDOWTEXT) );
1278 old_pen = SelectObject( dc, pen );
1280 MoveToEx( dc, rect.left, rect.top - 2 + expander_semi_size, NULL );
1281 LineTo( dc, rect.right, rect.top - 2 + expander_semi_size );
1283 if( expander_style == GTK_EXPANDER_COLLAPSED ||
1284 expander_style == GTK_EXPANDER_SEMI_COLLAPSED )
1286 MoveToEx( dc, rect.left - 2 + expander_semi_size, rect.top, NULL );
1287 LineTo( dc, rect.left - 2 + expander_semi_size, rect.bottom );
1290 SelectObject( dc, old_pen );
1291 DeleteObject( pen );
1292 release_window_dc( style, window, state );
1296 gdk_gc_set_clip_rectangle (style->fg_gc[state], NULL);
1300 draw_option (GtkStyle * style,
1303 GtkShadowType shadow,
1304 GdkRectangle * area,
1306 const gchar * detail, gint x, gint y, gint width, gint height)
1308 x -= (1 + PART_SIZE - width) / 2;
1309 y -= (1 + PART_SIZE - height) / 2;
1311 if (detail && strcmp (detail, "option") == 0) /* Menu item */
1313 if (shadow == GTK_SHADOW_IN)
1314 draw_part (window, style->fg_gc[state], area, x, y,
1319 if (xp_theme_draw (window, shadow == GTK_SHADOW_IN
1320 ? XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON
1321 : XP_THEME_ELEMENT_RADIO_BUTTON,
1322 style, x, y, width, height, state, area))
1327 if( detail && !strcmp(detail, "cellradio") )
1328 state = GTK_STATE_NORMAL;
1330 draw_part (window, style->black_gc, area, x, y,
1332 draw_part (window, style->dark_gc[state], area, x, y,
1334 draw_part (window, style->mid_gc[state], area, x, y,
1336 draw_part (window, style->light_gc[state], area, x, y,
1338 draw_part (window, style->base_gc[state], area, x, y,
1341 if (shadow == GTK_SHADOW_IN)
1342 draw_part (window, style->text_gc[state], area, x, y,
1349 draw_varrow (GdkWindow * window,
1351 GtkShadowType shadow_type,
1352 GdkRectangle * area,
1353 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1356 gint y_start, y_increment;
1360 gdk_gc_set_clip_rectangle (gc, area);
1362 width = width + width % 2 - 1; /* Force odd */
1363 steps = 1 + width / 2;
1364 extra = height - steps;
1366 if (arrow_type == GTK_ARROW_DOWN)
1373 y_start = y + height - 1;
1377 for (i = extra; i < height; i++)
1379 gdk_draw_line (window, gc,
1380 x + (i - extra), y_start + i * y_increment,
1381 x + width - (i - extra) - 1,
1382 y_start + i * y_increment);
1386 gdk_gc_set_clip_rectangle (gc, NULL);
1390 draw_harrow (GdkWindow * window,
1392 GtkShadowType shadow_type,
1393 GdkRectangle * area,
1394 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1397 gint x_start, x_increment;
1401 gdk_gc_set_clip_rectangle (gc, area);
1403 height = height + height % 2 - 1; /* Force odd */
1404 steps = 1 + height / 2;
1405 extra = width - steps;
1407 if (arrow_type == GTK_ARROW_RIGHT)
1414 x_start = x + width - 1;
1418 for (i = extra; i < width; i++)
1420 gdk_draw_line (window, gc,
1421 x_start + i * x_increment, y + (i - extra),
1422 x_start + i * x_increment,
1423 y + height - (i - extra) - 1);
1428 gdk_gc_set_clip_rectangle (gc, NULL);
1431 /* This function makes up for some brokeness in gtkrange.c
1432 * where we never get the full arrow of the stepper button
1433 * and the type of button in a single drawing function.
1435 * It doesn't work correctly when the scrollbar is squished
1436 * to the point we don't have room for full-sized steppers.
1439 reverse_engineer_stepper_box (GtkWidget * range,
1440 GtkArrowType arrow_type,
1441 gint * x, gint * y, gint * width, gint * height)
1443 gint slider_width = 14, stepper_size = 14;
1449 gtk_widget_style_get (range,
1450 "slider_width", &slider_width,
1451 "stepper_size", &stepper_size, NULL);
1454 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1456 box_width = slider_width;
1457 box_height = stepper_size;
1461 box_width = stepper_size;
1462 box_height = slider_width;
1465 *x = *x - (box_width - *width) / 2;
1466 *y = *y - (box_height - *height) / 2;
1468 *height = box_height;
1471 static XpThemeElement
1472 to_xp_arrow (GtkArrowType arrow_type)
1474 XpThemeElement xp_arrow;
1479 xp_arrow = XP_THEME_ELEMENT_ARROW_UP;
1481 case GTK_ARROW_DOWN:
1482 xp_arrow = XP_THEME_ELEMENT_ARROW_DOWN;
1484 case GTK_ARROW_LEFT:
1485 xp_arrow = XP_THEME_ELEMENT_ARROW_LEFT;
1488 xp_arrow = XP_THEME_ELEMENT_ARROW_RIGHT;
1496 draw_arrow (GtkStyle * style,
1499 GtkShadowType shadow,
1500 GdkRectangle * area,
1502 const gchar * detail,
1503 GtkArrowType arrow_type,
1504 gboolean fill, gint x, gint y, gint width, gint height)
1510 name = gtk_widget_get_name (widget);
1512 sanitize_size (window, &width, &height);
1514 if (GTK_IS_ARROW(widget) && is_combo_box_child(widget))
1516 if (combo_box_draw_arrow (style, window, state, area, widget))
1522 if (detail && strcmp (detail, "spinbutton") == 0)
1524 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1531 if( arrow_type == GTK_ARROW_DOWN )
1535 if( state == GTK_STATE_ACTIVE ) {
1539 draw_varrow (window, style->fg_gc[state], shadow, area,
1540 arrow_type, x, y, width, height);
1543 else if (detail && (!strcmp (detail, "vscrollbar")
1544 || !strcmp (detail, "hscrollbar")))
1546 gboolean is_disabled = FALSE;
1548 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1552 gint box_width = width;
1553 gint box_height = height;
1555 reverse_engineer_stepper_box (widget, arrow_type,
1556 &box_x, &box_y, &box_width,
1559 if (scrollbar->range.adjustment->page_size >=
1560 (scrollbar->range.adjustment->upper -
1561 scrollbar->range.adjustment->lower))
1565 (window, to_xp_arrow (arrow_type), style, box_x, box_y,
1566 box_width, box_height, state, area))
1574 btn_type = DFCS_SCROLLUP;
1576 case GTK_ARROW_DOWN:
1577 btn_type = DFCS_SCROLLDOWN;
1579 case GTK_ARROW_LEFT:
1580 btn_type = DFCS_SCROLLLEFT;
1582 case GTK_ARROW_RIGHT:
1583 btn_type = DFCS_SCROLLRIGHT;
1586 if( state == GTK_STATE_INSENSITIVE )
1587 btn_type |= DFCS_INACTIVE;
1589 sanitize_size (window, &width, &height);
1591 dc = get_window_dc( style, window, state,
1592 box_x, box_y, box_width, box_height, &rect );
1593 DrawFrameControl( dc, &rect, DFC_SCROLL,
1594 btn_type|(shadow == GTK_SHADOW_IN ? (DFCS_PUSHED|DFCS_FLAT) : 0) );
1595 release_window_dc( style, window, state );
1601 /* draw the toolbar chevrons - waiting for GTK 2.4 */
1602 if (name && !strcmp (name, "gtk-toolbar-arrow"))
1605 (window, XP_THEME_ELEMENT_REBAR_CHEVRON, style, x, y,
1606 width, height, state, area))
1609 /* probably a gtk combo box on a toolbar */
1610 else if (0 /* widget->parent && GTK_IS_BUTTON
1611 (widget->parent) */ )
1614 (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x - 3,
1615 widget->allocation.y + 1, width + 5,
1616 widget->allocation.height - 4, state, area))
1620 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1622 x += (width - 7) / 2;
1623 y += (height - 5) / 2;
1625 draw_varrow (window, style->fg_gc[state], shadow, area,
1626 arrow_type, x, y, 7, 5);
1630 x += (width - 5) / 2;
1631 y += (height - 7) / 2;
1633 draw_harrow (window, style->fg_gc[state], shadow, area,
1634 arrow_type, x, y, 5, 7);
1640 option_menu_get_props (GtkWidget * widget,
1641 GtkRequisition * indicator_size,
1642 GtkBorder * indicator_spacing)
1644 GtkRequisition *tmp_size = NULL;
1645 GtkBorder *tmp_spacing = NULL;
1648 gtk_widget_style_get (widget,
1649 "indicator_size", &tmp_size,
1650 "indicator_spacing", &tmp_spacing, NULL);
1654 *indicator_size = *tmp_size;
1658 *indicator_size = default_option_indicator_size;
1662 *indicator_spacing = *tmp_spacing;
1663 g_free (tmp_spacing);
1666 *indicator_spacing = default_option_indicator_spacing;
1670 is_toolbar_child (GtkWidget * wid)
1674 if (GTK_IS_TOOLBAR (wid) || GTK_IS_HANDLE_BOX (wid))
1684 is_menu_tool_button_child (GtkWidget * wid)
1688 if (GTK_IS_MENU_TOOL_BUTTON (wid) )
1696 HDC get_window_dc(GtkStyle * style, GdkWindow * window, GtkStateType state_type, gint x, gint y, gint width, gint height, RECT *rect)
1699 GdkDrawable *drawable;
1701 if (!GDK_IS_WINDOW (window))
1709 gdk_window_get_internal_paint_info (window, &drawable, &xoff, &yoff);
1712 rect->left = x - xoff;
1713 rect->top = y - yoff;
1714 rect->right = rect->left + width;
1715 rect->bottom = rect->top + height;
1717 return gdk_win32_hdc_get (drawable, style->dark_gc[state_type], 0);
1720 void release_window_dc(GtkStyle * style, GdkWindow * window, GtkStateType state_type)
1722 GdkDrawable *drawable;
1724 if (!GDK_IS_WINDOW (window))
1730 gdk_window_get_internal_paint_info (window, &drawable, NULL, NULL);
1733 gdk_win32_hdc_release (drawable, style->dark_gc[state_type], 0);
1736 static HPEN get_light_pen()
1738 if( ! g_light_pen ) {
1739 g_light_pen = CreatePen( PS_SOLID|PS_INSIDEFRAME, 1, GetSysColor(COLOR_BTNHIGHLIGHT) );
1744 static HPEN get_dark_pen()
1746 if( ! g_dark_pen ) {
1747 g_dark_pen = CreatePen( PS_SOLID|PS_INSIDEFRAME, 1, GetSysColor(COLOR_BTNSHADOW) );
1753 draw_3d_border( HDC hdc, RECT* rc, gboolean sunken )
1759 pen1 = get_dark_pen();
1760 pen2 = get_light_pen();
1763 pen1 = get_light_pen();
1764 pen2 = get_dark_pen();
1767 MoveToEx( hdc, rc->left, rc->bottom - 1, NULL);
1769 old_pen = SelectObject( hdc, pen1 );
1770 LineTo( hdc, rc->left, rc->top );
1771 LineTo( hdc, rc->right-1, rc->top );
1772 SelectObject( hdc, old_pen );
1774 old_pen = SelectObject( hdc, pen2 );
1775 LineTo( hdc, rc->right-1, rc->bottom-1 );
1776 LineTo( hdc, rc->left, rc->bottom-1 );
1777 SelectObject( hdc, old_pen );
1781 draw_menu_item(GdkWindow* window, GtkWidget* widget, GtkStyle* style,
1782 gint x, gint y, gint width, gint height,
1783 GtkStateType state_type, GdkRectangle* area )
1790 if ( xp_theme_is_active() ) {
1791 return xp_theme_draw( window, XP_THEME_ELEMENT_MENU_ITEM, style,
1792 x, y, width, height, state_type, area );
1795 if( (parent = gtk_widget_get_parent(widget))
1796 && GTK_IS_MENU_BAR(parent) )
1798 bar = GTK_MENU_SHELL(parent);
1800 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1801 if( state_type == GTK_STATE_PRELIGHT ){
1802 draw_3d_border( dc, &rect, bar->active );
1804 release_window_dc( style, window, state_type );
1811 get_dither_brush( void )
1814 HBITMAP pattern_bmp;
1817 if( g_dither_brush )
1818 return g_dither_brush;
1819 for ( i = 0; i < 8; i++ )
1820 pattern[i] = (WORD)(0x5555 << (i & 1));
1821 pattern_bmp = CreateBitmap(8, 8, 1, 1, &pattern);
1823 g_dither_brush = CreatePatternBrush(pattern_bmp);
1824 DeleteObject(pattern_bmp);
1826 return g_dither_brush;
1830 draw_tool_button(GdkWindow* window, GtkWidget* widget, GtkStyle* style,
1831 gint x, gint y, gint width, gint height,
1832 GtkStateType state_type, GdkRectangle* area )
1836 gboolean is_toggled = FALSE;
1838 if ( xp_theme_is_active() ) {
1839 return (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
1840 x, y, width, height, state_type, area) );
1843 if( GTK_IS_TOGGLE_BUTTON(widget) ){
1844 if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ) {
1849 if( state_type != GTK_STATE_PRELIGHT
1850 && state_type != GTK_STATE_ACTIVE && !is_toggled )
1853 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1854 if( state_type == GTK_STATE_PRELIGHT ){
1856 FillRect( dc, &rect, GetSysColorBrush(COLOR_BTNFACE));
1858 draw_3d_border( dc, &rect, is_toggled);
1860 else if ( state_type == GTK_STATE_ACTIVE ){
1861 if( is_toggled && ! is_menu_tool_button_child(widget->parent) ){
1862 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
1863 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
1864 FillRect( dc, &rect, get_dither_brush() );
1866 draw_3d_border( dc, &rect, TRUE );
1868 release_window_dc( style, window, state_type );
1873 draw_push_button( GdkWindow* window, GtkWidget* widget, GtkStyle* style, gint x, gint y,
1874 gint width, gint height,
1875 GtkStateType state_type, gboolean is_default )
1880 dc = get_window_dc( style, window, state_type,
1881 x, y, width, height, &rect );
1882 if( GTK_IS_TOGGLE_BUTTON(widget) ) {
1883 if( state_type == GTK_STATE_PRELIGHT &&
1884 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) )
1886 state_type = GTK_STATE_ACTIVE;
1890 if( state_type == GTK_STATE_ACTIVE ) {
1891 if( GTK_IS_TOGGLE_BUTTON(widget) ) {
1892 DrawEdge( dc, &rect, EDGE_SUNKEN, BF_RECT|BF_ADJUST);
1893 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
1894 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
1895 FillRect( dc, &rect, get_dither_brush() );
1898 FrameRect( dc, &rect, GetSysColorBrush(COLOR_WINDOWFRAME) );
1899 InflateRect( &rect, -1, -1 );
1900 FrameRect( dc, &rect, GetSysColorBrush(COLOR_BTNSHADOW) );
1901 InflateRect( &rect, -1, -1 );
1902 FillRect( dc, &rect, GetSysColorBrush(COLOR_BTNFACE) );
1906 if( is_default || GTK_WIDGET_HAS_FOCUS(widget) ) {
1907 FrameRect( dc, &rect, GetSysColorBrush(COLOR_WINDOWFRAME) );
1908 InflateRect( &rect, -1, -1 );
1910 DrawFrameControl( dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH );
1912 release_window_dc(style, window, state_type);
1916 draw_box (GtkStyle * style,
1918 GtkStateType state_type,
1919 GtkShadowType shadow_type,
1920 GdkRectangle * area,
1922 const gchar * detail, gint x, gint y, gint width, gint height)
1924 if (is_combo_box_child (widget)
1925 && combo_box_draw_box (style, window, state_type, shadow_type,
1926 area, widget, detail, x, y, width, height))
1931 (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
1933 if (GTK_IS_TREE_VIEW (widget->parent)
1934 || GTK_IS_CLIST (widget->parent))
1937 (window, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
1938 width, height, state_type, area))
1943 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1945 DrawFrameControl( dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH |
1946 (state_type == GTK_STATE_ACTIVE ? (DFCS_PUSHED|DFCS_FLAT) : 0 ) );
1947 release_window_dc( style, window, state_type );
1950 else if (is_toolbar_child (widget->parent)
1951 || (GTK_RELIEF_NONE == gtk_button_get_relief(GTK_BUTTON(widget)) ) )
1953 if( draw_tool_button( window, widget, style, x, y,
1954 width, height, state_type, area ) )
1961 gboolean is_default = GTK_WIDGET_HAS_DEFAULT(widget);
1964 is_default ? XP_THEME_ELEMENT_DEFAULT_BUTTON :
1965 XP_THEME_ELEMENT_BUTTON, style, x, y, width, height,
1970 draw_push_button( window, widget, style,
1971 x, y, width, height, state_type, is_default );
1976 else if (detail && !strcmp (detail, "spinbutton"))
1978 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1983 else if (detail && (!strcmp (detail, "spinbutton_up")
1984 || !strcmp (detail, "spinbutton_down")))
1986 if ( ! xp_theme_draw ( window,
1987 (!strcmp (detail, "spinbutton_up"))
1988 ? XP_THEME_ELEMENT_SPIN_BUTTON_UP
1989 : XP_THEME_ELEMENT_SPIN_BUTTON_DOWN,
1990 style, x, y, width, height, state_type, area))
1995 dc = get_window_dc( style, window, state_type,
1996 x, y, width, height, &rect );
1997 DrawEdge( dc, &rect,
1998 state_type == GTK_STATE_ACTIVE ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT );
1999 release_window_dc( style, window, state_type );
2003 else if (detail && !strcmp (detail, "slider"))
2005 if (GTK_IS_SCROLLBAR (widget))
2007 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
2008 gboolean is_v = GTK_IS_VSCROLLBAR (widget);
2010 if (xp_theme_draw (window,
2012 ? XP_THEME_ELEMENT_SCROLLBAR_V
2013 : XP_THEME_ELEMENT_SCROLLBAR_H,
2014 style, x, y, width, height, state_type,
2017 XpThemeElement gripper =
2018 (is_v ? XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V :
2019 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H);
2021 /* Do not display grippers on tiny scroll bars,
2022 the limit imposed is rather arbitrary, perhaps
2023 we can fetch the gripper geometry from
2024 somewhere and use that... */
2026 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H
2029 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V
2035 xp_theme_draw (window, gripper, style, x, y,
2036 width, height, state_type, area);
2041 if (scrollbar->range.adjustment->page_size >=
2042 (scrollbar->range.adjustment->upper -
2043 scrollbar->range.adjustment->lower))
2048 else if (detail && !strcmp (detail, "bar"))
2050 if (widget && GTK_IS_PROGRESS_BAR (widget))
2052 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2053 XpThemeElement xp_progress_bar =
2054 map_gtk_progress_bar_to_xp (progress_bar, FALSE);
2056 (window, xp_progress_bar, style, x, y, width, height,
2063 else if (detail && strcmp (detail, "menuitem") == 0)
2065 shadow_type = GTK_SHADOW_NONE;
2066 if( draw_menu_item(window, widget, style,
2067 x, y, width, height, state_type, area ) )
2072 else if (detail && !strcmp (detail, "trough"))
2074 if (widget && GTK_IS_PROGRESS_BAR (widget))
2076 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2077 XpThemeElement xp_progress_bar =
2078 map_gtk_progress_bar_to_xp (progress_bar, TRUE);
2080 (window, xp_progress_bar, style, x, y, width, height,
2087 /* Blank in classic Windows */
2090 else if (widget && GTK_IS_SCROLLBAR (widget))
2092 gboolean is_vertical = GTK_IS_VSCROLLBAR (widget);
2094 if (xp_theme_draw (window,
2096 ? XP_THEME_ELEMENT_TROUGH_V
2097 : XP_THEME_ELEMENT_TROUGH_H,
2099 x, y, width, height, state_type, area))
2108 sanitize_size (window, &width, &height);
2109 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2110 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
2111 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
2112 FillRect( dc, &rect, get_dither_brush() );
2113 release_window_dc( style, window, state_type );
2118 else if (widget && GTK_IS_SCALE (widget))
2120 gboolean is_vertical = GTK_IS_VSCALE (widget);
2122 if (!xp_theme_is_active ())
2124 parent_class->draw_box (style, window, state_type,
2125 GTK_SHADOW_NONE, area,
2126 widget, detail, x, y,
2133 (window, XP_THEME_ELEMENT_SCALE_TROUGH_V,
2134 style, (2 * x + width) / 2, y, 2, height,
2138 parent_class->draw_box (style, window, state_type,
2139 GTK_SHADOW_ETCHED_IN,
2141 (2 * x + width) / 2, y, 1,
2147 (window, XP_THEME_ELEMENT_SCALE_TROUGH_H,
2148 style, x, (2 * y + height) / 2, width, 2,
2152 parent_class->draw_box (style, window, state_type,
2153 GTK_SHADOW_ETCHED_IN,
2154 area, NULL, NULL, x,
2155 (2 * y + height) / 2,
2161 else if (detail && strcmp (detail, "optionmenu") == 0)
2163 if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
2164 style, x, y, width, height, state_type, area))
2170 && (strcmp (detail, "vscrollbar") == 0
2171 || strcmp (detail, "hscrollbar") == 0))
2176 && (strcmp (detail, "handlebox_bin") == 0
2177 || strcmp (detail, "toolbar") == 0
2178 || strcmp (detail, "menubar") == 0))
2180 sanitize_size( window, &width, &height );
2181 if (xp_theme_draw (window, XP_THEME_ELEMENT_REBAR,
2182 style, x, y, width, height, state_type, area))
2187 else if (detail && (!strcmp (detail, "handlebox"))) /* grip */
2189 if( !xp_theme_is_active() ) {
2195 const gchar *name = gtk_widget_get_name (widget);
2197 if (name && !strcmp (name, "gtk-tooltips"))
2200 (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
2201 height, state_type, area))
2211 hdc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2213 brush = GetSysColorBrush (COLOR_3DDKSHADOW);
2215 FrameRect (hdc, &rect, brush);
2216 InflateRect (&rect, -1, -1);
2217 FillRect (hdc, &rect,
2218 (HBRUSH) (COLOR_INFOBK + 1));
2220 release_window_dc (style, window, state_type);
2228 parent_class->draw_box (style, window, state_type, shadow_type, area,
2229 widget, detail, x, y, width, height);
2231 if (detail && strcmp (detail, "optionmenu") == 0)
2233 GtkRequisition indicator_size;
2234 GtkBorder indicator_spacing;
2237 option_menu_get_props (widget, &indicator_size,
2238 &indicator_spacing);
2240 sanitize_size (window, &width, &height);
2242 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
2244 x + indicator_size.width + indicator_spacing.left +
2245 indicator_spacing.right;
2248 x + width - (indicator_size.width +
2249 indicator_spacing.left +
2250 indicator_spacing.right) - style->xthickness;
2252 parent_class->draw_vline (style, window, state_type, area, widget,
2254 y + style->ythickness + 1,
2255 y + height - style->ythickness - 3,
2261 draw_tab (GtkStyle * style,
2264 GtkShadowType shadow,
2265 GdkRectangle * area,
2267 const gchar * detail, gint x, gint y, gint width, gint height)
2269 GtkRequisition indicator_size;
2270 GtkBorder indicator_spacing;
2274 g_return_if_fail (style != NULL);
2275 g_return_if_fail (window != NULL);
2277 if (detail && !strcmp (detail, "optionmenutab"))
2279 if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
2280 style, x - 5, widget->allocation.y + 1,
2281 width + 10, widget->allocation.height - 2,
2289 gtk_widget_style_get (widget, "indicator_size", &indicator_size,
2292 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2294 x += (width - indicator_size.width) / 2;
2295 arrow_height = (indicator_size.width + 1) / 2;
2297 y += (height - arrow_height) / 2;
2299 draw_varrow (window, style->black_gc, shadow, area, GTK_ARROW_DOWN,
2300 x, y, indicator_size.width, arrow_height);
2303 /* Draw classic Windows tab - thanks Mozilla!
2304 (no system API for this, but DrawEdge can draw all the parts of a tab) */
2305 static void DrawTab(HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
2306 gboolean aDrawLeft, gboolean aDrawRight)
2308 gint32 leftFlag, topFlag, rightFlag, lightFlag, shadeFlag;
2309 RECT topRect, sideRect, bottomRect, lightRect, shadeRect;
2310 gint32 selectedOffset, lOffset, rOffset;
2312 selectedOffset = aSelected ? 1 : 0;
2313 lOffset = aDrawLeft ? 2 : 0;
2314 rOffset = aDrawRight ? 2 : 0;
2316 /* Get info for tab orientation/position (Left, Top, Right, Bottom) */
2317 switch (aPosition) {
2319 leftFlag = BF_TOP; topFlag = BF_LEFT;
2320 rightFlag = BF_BOTTOM;
2321 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2322 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2324 SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
2325 SetRect(&sideRect, R.left+2, R.top, R.right-2+selectedOffset, R.bottom);
2326 SetRect(&bottomRect, R.right-2, R.top, R.right, R.bottom);
2327 SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
2328 SetRect(&shadeRect, R.left+1, R.bottom-2, R.left+2, R.bottom-1);
2331 leftFlag = BF_LEFT; topFlag = BF_TOP;
2332 rightFlag = BF_RIGHT;
2333 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2334 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2336 SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
2337 SetRect(&sideRect, R.left, R.top+2, R.right, R.bottom-1+selectedOffset);
2338 SetRect(&bottomRect, R.left, R.bottom-1, R.right, R.bottom);
2339 SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
2340 SetRect(&shadeRect, R.right-2, R.top+1, R.right-1, R.top+2);
2343 leftFlag = BF_TOP; topFlag = BF_RIGHT;
2344 rightFlag = BF_BOTTOM;
2345 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2346 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2348 SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
2349 SetRect(&sideRect, R.left+2-selectedOffset, R.top, R.right-2, R.bottom);
2350 SetRect(&bottomRect, R.left, R.top, R.left+2, R.bottom);
2351 SetRect(&lightRect, R.right-3, R.top, R.right-1, R.top+2);
2352 SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
2355 leftFlag = BF_LEFT; topFlag = BF_BOTTOM;
2356 rightFlag = BF_RIGHT;
2357 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2358 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2360 SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
2361 SetRect(&sideRect, R.left, R.top+2-selectedOffset, R.right, R.bottom-2);
2362 SetRect(&bottomRect, R.left, R.top, R.right, R.top+2);
2363 SetRect(&lightRect, R.left, R.bottom-3, R.left+2, R.bottom-1);
2364 SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
2369 FillRect(hdc, &R, (HBRUSH) (COLOR_3DFACE+1) );
2372 DrawEdge(hdc, &topRect, EDGE_RAISED, BF_SOFT | topFlag);
2376 DrawEdge(hdc, &bottomRect, EDGE_RAISED, BF_SOFT | topFlag);
2383 DrawEdge(hdc, &sideRect, EDGE_RAISED, BF_SOFT | leftFlag | rightFlag);
2385 /* Tab Diagonal Corners */
2387 DrawEdge(hdc, &lightRect, EDGE_RAISED, BF_SOFT | lightFlag);
2390 DrawEdge(hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
2394 draw_extension (GtkStyle * style,
2396 GtkStateType state_type,
2397 GtkShadowType shadow_type,
2398 GdkRectangle * area,
2400 const gchar * detail,
2402 gint y, gint width, gint height, GtkPositionType gap_side)
2404 if (widget && GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "tab"))
2406 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2407 GdkPixmap *pixmap = NULL;
2408 GdkDrawable *target = NULL;
2409 gint x2 = 0, y2 = 0, w2 = width, h2 = height;
2410 int tab_part = XP_THEME_ELEMENT_TAB_ITEM;
2411 int real_gap_side = gtk_notebook_get_tab_pos (notebook);
2412 int border_width = gtk_container_get_border_width (GTK_CONTAINER (notebook));
2414 /* why this differs from the above gap_side, i have no idea... */
2415 if (real_gap_side == GTK_POS_LEFT)
2417 /* Create "rotated" pixmap.. swap width and height */
2418 pixmap = gdk_pixmap_new (window, height, width, -1);
2423 h2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2425 /* If we are currently rendering the bottom-most tab, and if that tab is the selected tab... */
2426 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2427 state_type == GTK_STATE_NORMAL)
2432 else if (real_gap_side == GTK_POS_RIGHT)
2434 /* Create "rotated" pixmap.. swap width and height */
2438 h2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2439 pixmap = gdk_pixmap_new (window, w2, h2, -1);
2442 /* If we are currently rendering the bottom-most tab, and if that tab is the selected tab... */
2443 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2444 state_type == GTK_STATE_NORMAL)
2449 else if (real_gap_side == GTK_POS_TOP)
2455 if (state_type == GTK_STATE_NORMAL)
2458 h2 = height - notebook->tab_vborder;
2460 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2461 if (widget->allocation.x + widget->allocation.width - border_width == x + width &&
2462 state_type == GTK_STATE_NORMAL)
2467 else if (real_gap_side == GTK_POS_BOTTOM)
2470 y2 = y + (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_vborder);
2472 h2 = height - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_vborder * 2);
2475 /* If we are currently drawing the right-most tab (any state)... */
2476 if (widget->allocation.x + widget->allocation.width - border_width == x + width)
2483 if (xp_theme_draw (target, tab_part, style, x2, y2, w2, h2, state_type, NULL /*area*/))
2485 GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
2486 if (real_gap_side == GTK_POS_BOTTOM)
2487 rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
2488 else if (real_gap_side == GTK_POS_LEFT)
2489 rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
2490 else if (real_gap_side == GTK_POS_RIGHT)
2491 rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
2493 if (rotation != GDK_PIXBUF_ROTATE_NONE)
2495 GdkPixbuf * pixbuf, * rotated;
2497 pixbuf = gdk_pixbuf_get_from_drawable (NULL, target, NULL, x2, y2, 0, 0, w2, h2);
2499 rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
2500 g_object_unref (pixbuf);
2503 if (real_gap_side == GTK_POS_RIGHT)
2505 x2 = x + (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2507 w2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2510 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2511 state_type == GTK_STATE_NORMAL)
2516 else if (real_gap_side == GTK_POS_LEFT)
2520 w2 = width - (state_type == GTK_STATE_NORMAL ? 0 : notebook->tab_hborder);
2523 if (widget->allocation.y + widget->allocation.height - border_width == y + height &&
2524 state_type == GTK_STATE_NORMAL)
2530 gdk_draw_pixbuf (window, NULL, pixbuf, 0, 0, x2, y2, w2, h2, GDK_RGB_DITHER_NONE, 0, 0);
2532 g_object_unref (G_OBJECT (pixbuf));
2534 if (real_gap_side == GTK_POS_LEFT || real_gap_side == GTK_POS_RIGHT)
2536 g_object_unref (pixmap);
2540 } else if (real_gap_side == GTK_POS_TOP || real_gap_side == GTK_POS_BOTTOM) {
2541 /* experimental tab-drawing code from mozilla */
2546 dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2548 if (real_gap_side == GTK_POS_TOP)
2550 else if (real_gap_side == GTK_POS_BOTTOM)
2551 aPosition = BF_BOTTOM;
2552 else if (real_gap_side == GTK_POS_LEFT)
2553 aPosition = BF_LEFT;
2555 aPosition = BF_RIGHT;
2557 if( state_type == GTK_STATE_PRELIGHT )
2558 state_type = GTK_STATE_NORMAL;
2560 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2561 DrawTab (dc, rect, aPosition, state_type != GTK_STATE_PRELIGHT, (real_gap_side != GTK_POS_LEFT), (real_gap_side != GTK_POS_RIGHT));
2563 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2565 release_window_dc (style, window, state_type);
2569 parent_class->draw_extension
2570 (style, window, state_type, shadow_type, area, widget, detail,
2571 x, y, width, height, gap_side);
2575 draw_box_gap (GtkStyle * style, GdkWindow * window, GtkStateType state_type,
2576 GtkShadowType shadow_type, GdkRectangle * area,
2577 GtkWidget * widget, const gchar * detail, gint x,
2578 gint y, gint width, gint height, GtkPositionType gap_side,
2579 gint gap_x, gint gap_width)
2581 if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
2583 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2584 int side = gtk_notebook_get_tab_pos (notebook);
2585 int x2 = x, y2 = y, w2 = width, h2 = height;
2587 if (side == GTK_POS_TOP)
2590 y2 = y - notebook->tab_vborder;
2592 h2 = height + notebook->tab_vborder * 2;
2594 else if (side == GTK_POS_BOTTOM)
2599 h2 = height + notebook->tab_vborder * 2;
2601 else if (side == GTK_POS_LEFT)
2603 x2 = x - notebook->tab_hborder;
2605 w2 = width + notebook->tab_hborder;
2608 else if (side == GTK_POS_RIGHT)
2612 w2 = width + notebook->tab_hborder * 2;
2616 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2617 x2, y2, w2, h2, state_type, area))
2623 parent_class->draw_box_gap (style, window, state_type, shadow_type,
2624 area, widget, detail, x, y, width, height,
2625 gap_side, gap_x, gap_width);
2628 static gboolean is_popup_window_child( GtkWidget* widget )
2631 GtkWindowType type = -1;
2633 top = gtk_widget_get_toplevel( widget );
2634 if( top && GTK_IS_WINDOW(top) ) {
2635 g_object_get(top, "type", &type, NULL );
2636 if( type == GTK_WINDOW_POPUP ) { /* Hack for combo boxes */
2644 draw_flat_box (GtkStyle * style, GdkWindow * window,
2645 GtkStateType state_type, GtkShadowType shadow_type,
2646 GdkRectangle * area, GtkWidget * widget,
2647 const gchar * detail, gint x, gint y, gint width, gint height)
2650 if ( !strcmp (detail, "checkbutton") )
2652 if (state_type == GTK_STATE_PRELIGHT)
2659 parent_class->draw_flat_box (style, window, state_type, shadow_type,
2660 area, widget, detail, x, y, width, height);
2664 draw_menu_border ( GdkWindow* win, GtkStyle* style,
2665 gint x, gint y, gint width, gint height )
2670 dc = get_window_dc (style, win, GTK_STATE_NORMAL, x, y, width, height, &rect );
2673 if( xp_theme_is_active() ) {
2674 FrameRect( dc, &rect, GetSysColorBrush(COLOR_3DSHADOW) );
2677 DrawEdge( dc, &rect, EDGE_RAISED, BF_RECT );
2679 release_window_dc( style, win, GTK_STATE_NORMAL );
2684 draw_shadow (GtkStyle * style,
2686 GtkStateType state_type,
2687 GtkShadowType shadow_type,
2688 GdkRectangle * area,
2690 const gchar * detail, gint x, gint y, gint width, gint height)
2692 gboolean is_handlebox;
2693 gboolean is_toolbar;
2695 if (is_combo_box_child (widget)
2696 && combo_box_draw_box (style, window, state_type, shadow_type,
2697 area, widget, detail, x, y, width, height))
2701 if( detail && !strcmp( detail, "frame") )
2705 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2706 if( is_popup_window_child(widget) ) {
2707 FrameRect( dc, &rect, GetSysColorBrush( COLOR_WINDOWFRAME ) );
2710 switch( shadow_type ){
2712 draw_3d_border(dc, &rect, TRUE);
2714 case GTK_SHADOW_OUT:
2715 draw_3d_border(dc, &rect, FALSE);
2717 case GTK_SHADOW_ETCHED_IN:
2718 draw_3d_border(dc, &rect, TRUE);
2719 InflateRect( &rect, -1, -1 );
2720 draw_3d_border(dc, &rect, FALSE);
2722 case GTK_SHADOW_ETCHED_OUT:
2723 draw_3d_border(dc, &rect, FALSE);
2724 InflateRect( &rect, -1, -1 );
2725 draw_3d_border(dc, &rect, TRUE);
2729 release_window_dc( style, window, state_type );
2732 if (detail && !strcmp (detail, "entry") )
2734 if ( xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2735 x, y, width, height, state_type, area))
2739 if( shadow_type == GTK_SHADOW_IN ) {
2742 dc = get_window_dc( style, window, state_type,
2743 x, y, width, height, &rect );
2744 DrawEdge( dc, &rect, EDGE_SUNKEN, BF_RECT );
2745 release_window_dc( style, window, state_type );
2750 if( detail && !strcmp( detail, "spinbutton" ) )
2755 if (detail && !strcmp (detail, "menu"))
2757 if ( draw_menu_border ( window, style, x, y, width, height ) ) {
2762 if (detail && !strcmp (detail, "handlebox"))
2765 is_handlebox = (detail && !strcmp (detail, "handlebox_bin"));
2766 is_toolbar = (detail && (!strcmp (detail, "toolbar") || !strcmp(detail, "menubar")));
2768 if ( is_toolbar || is_handlebox )
2774 GtkPositionType pos;
2776 sanitize_size (window, &width, &height);
2778 if( is_handlebox ) {
2779 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
2781 If the handle box is at left side,
2782 we shouldn't draw its right border.
2783 The same holds true for top, right, and bottom.
2787 pos = GTK_POS_RIGHT; break;
2789 pos = GTK_POS_LEFT; break;
2791 pos = GTK_POS_BOTTOM; break;
2792 case GTK_POS_BOTTOM:
2793 pos = GTK_POS_TOP; break;
2797 GtkWidget* parent = gtk_widget_get_parent(widget);
2798 /* Dirty hack for toolbars contained in handle boxes */
2799 if( GTK_IS_HANDLE_BOX( parent ) ) {
2800 pos = gtk_handle_box_get_handle_position( GTK_HANDLE_BOX( parent ) );
2805 Make pos != all legal enum vaules of GtkPositionType.
2806 So every border will be draw.
2808 pos = (GtkPositionType)-1;
2812 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2813 if( pos != GTK_POS_LEFT ) {
2814 old_pen = SelectObject( dc, get_light_pen() );
2815 MoveToEx( dc, rect.left, rect.top, NULL );
2816 LineTo( dc, rect.left, rect.bottom );
2818 if( pos != GTK_POS_TOP ) {
2819 old_pen = SelectObject( dc, get_light_pen() );
2820 MoveToEx( dc, rect.left, rect.top, NULL );
2821 LineTo( dc, rect.right, rect.top );
2823 if( pos != GTK_POS_RIGHT ) {
2824 old_pen = SelectObject( dc, get_dark_pen() );
2825 MoveToEx( dc, rect.right-1, rect.top, NULL );
2826 LineTo( dc, rect.right-1, rect.bottom );
2828 if( pos != GTK_POS_BOTTOM ) {
2829 old_pen = SelectObject( dc, get_dark_pen() );
2830 MoveToEx( dc, rect.left, rect.bottom-1, NULL );
2831 LineTo( dc, rect.right, rect.bottom-1 );
2833 SelectObject( dc, old_pen );
2834 release_window_dc( style, window, state_type );
2839 if (detail && !strcmp (detail, "statusbar")) {
2843 parent_class->draw_shadow (style, window, state_type, shadow_type, area,
2844 widget, detail, x, y, width, height);
2848 draw_hline (GtkStyle * style,
2850 GtkStateType state_type,
2851 GdkRectangle * area,
2853 const gchar * detail, gint x1, gint x2, gint y)
2855 if (xp_theme_is_active () && detail && !strcmp(detail, "menuitem")) {
2856 if(xp_theme_draw (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, y, x2, 1, state_type, area))
2860 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2862 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2865 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2868 if( style->ythickness == 2 )
2872 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2873 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2875 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2877 gdk_draw_line (window, style->light_gc[state_type], x1, y, x2, y);
2880 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2881 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2886 parent_class->draw_hline (style, window, state_type, area, widget,
2893 draw_vline (GtkStyle * style,
2895 GtkStateType state_type,
2896 GdkRectangle * area,
2898 const gchar * detail, gint y1, gint y2, gint x)
2900 if( style->xthickness == 2 )
2904 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2905 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2907 gdk_draw_line (window, style->dark_gc[state_type], x, y1, x, y2);
2909 gdk_draw_line (window, style->light_gc[state_type], x, y1, x, y2);
2912 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2913 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2918 parent_class->draw_vline (style, window, state_type, area, widget,
2924 draw_slider (GtkStyle * style,
2926 GtkStateType state_type,
2927 GtkShadowType shadow_type,
2928 GdkRectangle * area,
2930 const gchar * detail,
2932 gint y, gint width, gint height, GtkOrientation orientation)
2934 if (GTK_IS_SCALE (widget) &&
2935 xp_theme_draw (window,
2937 GTK_ORIENTATION_VERTICAL) ?
2938 XP_THEME_ELEMENT_SCALE_SLIDER_V :
2939 XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
2940 height, state_type, area))
2945 parent_class->draw_slider (style, window, state_type, shadow_type, area,
2946 widget, detail, x, y, width, height,
2951 draw_resize_grip (GtkStyle * style,
2953 GtkStateType state_type,
2954 GdkRectangle * area,
2956 const gchar * detail,
2957 GdkWindowEdge edge, gint x, gint y, gint width, gint height)
2959 if (detail && !strcmp (detail, "statusbar"))
2962 (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
2963 height, state_type, area))
2967 HDC dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2970 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2971 DrawFrameControl(dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
2972 release_window_dc(style, window, state_type);
2974 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2979 parent_class->draw_resize_grip (style, window, state_type, area,
2980 widget, detail, edge, x, y, width,
2985 draw_handle (GtkStyle * style,
2987 GtkStateType state_type,
2988 GtkShadowType shadow_type,
2989 GdkRectangle * area,
2991 const gchar * detail,
2993 gint y, gint width, gint height, GtkOrientation orientation)
2998 if (is_toolbar_child (widget))
3000 XpThemeElement hndl;
3002 sanitize_size (window, &width, &height);
3004 if( GTK_IS_HANDLE_BOX(widget) ) {
3005 GtkPositionType pos;
3006 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
3007 if( pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM ) {
3008 orientation = GTK_ORIENTATION_HORIZONTAL;
3011 orientation = GTK_ORIENTATION_VERTICAL;
3015 if ( orientation == GTK_ORIENTATION_VERTICAL )
3016 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_V;
3018 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
3020 if (xp_theme_draw (window, hndl, style, x, y, width, height,
3026 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
3027 if ( orientation == GTK_ORIENTATION_VERTICAL ) {
3029 rect.right = rect.left + 3;
3035 rect.bottom = rect.top + 3;
3039 draw_3d_border( dc, &rect, FALSE );
3040 release_window_dc( style, window, state_type );
3044 if (!GTK_IS_PANED (widget))
3046 gint xthick, ythick;
3047 GdkGC *light_gc, *dark_gc, *shadow_gc;
3050 sanitize_size (window, &width, &height);
3052 gtk_paint_box (style, window, state_type, shadow_type, area,
3053 widget, detail, x, y, width, height);
3055 light_gc = style->light_gc[state_type];
3056 dark_gc = style->dark_gc[state_type];
3057 shadow_gc = style->mid_gc[state_type];
3059 xthick = style->xthickness;
3060 ythick = style->ythickness;
3062 dest.x = x + xthick;
3063 dest.y = y + ythick;
3064 dest.width = width - (xthick * 2);
3065 dest.height = height - (ythick * 2);
3067 if (dest.width < dest.height)
3072 gdk_gc_set_clip_rectangle (light_gc, &dest);
3073 gdk_gc_set_clip_rectangle (dark_gc, &dest);
3074 gdk_gc_set_clip_rectangle (shadow_gc, &dest);
3076 if (dest.width < dest.height)
3078 gdk_draw_line (window, light_gc, dest.x, dest.y, dest.x,
3080 gdk_draw_line (window, dark_gc, dest.x + (dest.width / 2),
3081 dest.y, dest.x + (dest.width / 2),
3083 gdk_draw_line (window, shadow_gc, dest.x + dest.width,
3084 dest.y, dest.x + dest.width, dest.height);
3088 gdk_draw_line (window, light_gc, dest.x, dest.y,
3089 dest.x + dest.width, dest.y);
3090 gdk_draw_line (window, dark_gc, dest.x,
3091 dest.y + (dest.height / 2),
3092 dest.x + dest.width,
3093 dest.y + (dest.height / 2));
3094 gdk_draw_line (window, shadow_gc, dest.x,
3095 dest.y + dest.height, dest.x + dest.width,
3096 dest.y + dest.height);
3099 gdk_gc_set_clip_rectangle (shadow_gc, NULL);
3100 gdk_gc_set_clip_rectangle (light_gc, NULL);
3101 gdk_gc_set_clip_rectangle (dark_gc, NULL);
3106 draw_focus ( GtkStyle *style,
3108 GtkStateType state_type,
3111 const gchar *detail,
3119 if( !GTK_WIDGET_CAN_FOCUS(widget) ) {
3122 if( detail && 0 == strcmp(detail, "button")
3123 && GTK_RELIEF_NONE == gtk_button_get_relief( GTK_BUTTON(widget) ) )
3127 if ( is_combo_box_child(widget)
3128 && (GTK_IS_ARROW(widget) || GTK_IS_BUTTON(widget)) ) {
3131 if (GTK_IS_TREE_VIEW (widget->parent) /* list view bheader */
3132 || GTK_IS_CLIST (widget->parent)) {
3136 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
3137 DrawFocusRect(dc, &rect);
3138 release_window_dc( style, window, state_type );
3140 parent_class->draw_focus (style, window, state_type,
3141 area, widget, detail, x, y, width, height);
3146 msw_style_init_from_rc (GtkStyle * style, GtkRcStyle * rc_style)
3148 setup_system_font (style);
3149 setup_menu_settings (gtk_settings_get_default ());
3150 setup_system_styles (style);
3151 parent_class->init_from_rc (style, rc_style);
3155 load_bg_image (GdkColormap *colormap,
3157 const gchar *filename)
3159 if (strcmp (filename, "<parent>") == 0)
3160 return (GdkPixmap*) GDK_PARENT_RELATIVE;
3163 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
3170 msw_style_realize (GtkStyle * style)
3172 GdkGCValues gc_values;
3173 GdkGCValuesMask gc_values_mask;
3177 for (i = 0; i < 5; i++)
3179 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
3180 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
3181 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
3183 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
3184 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
3185 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
3188 style->black.red = 0x0000;
3189 style->black.green = 0x0000;
3190 style->black.blue = 0x0000;
3191 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
3193 style->white.red = 0xffff;
3194 style->white.green = 0xffff;
3195 style->white.blue = 0xffff;
3196 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
3198 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
3200 gc_values.foreground = style->black;
3201 gc_values.background = style->white;
3202 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3204 gc_values.foreground = style->white;
3205 gc_values.background = style->black;
3206 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3208 gc_values_mask = GDK_GC_FOREGROUND;
3210 for (i = 0; i < 5; i++)
3212 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
3213 style->bg_pixmap[i] = load_bg_image (style->colormap,
3215 style->rc_style->bg_pixmap_name[i]);
3217 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
3218 g_warning ("unable to allocate color: ( %d %d %d )",
3219 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
3220 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
3221 g_warning ("unable to allocate color: ( %d %d %d )",
3222 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
3223 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
3224 g_warning ("unable to allocate color: ( %d %d %d )",
3225 style->light[i].red, style->light[i].green, style->light[i].blue);
3226 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
3227 g_warning ("unable to allocate color: ( %d %d %d )",
3228 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
3229 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
3230 g_warning ("unable to allocate color: ( %d %d %d )",
3231 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
3232 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
3233 g_warning ("unable to allocate color: ( %d %d %d )",
3234 style->text[i].red, style->text[i].green, style->text[i].blue);
3235 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
3236 g_warning ("unable to allocate color: ( %d %d %d )",
3237 style->base[i].red, style->base[i].green, style->base[i].blue);
3238 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
3239 g_warning ("unable to allocate color: ( %d %d %d )",
3240 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
3242 gc_values.foreground = style->fg[i];
3243 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3245 gc_values.foreground = style->bg[i];
3246 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3248 gc_values.foreground = style->light[i];
3249 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3251 gc_values.foreground = style->dark[i];
3252 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3254 gc_values.foreground = style->mid[i];
3255 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3257 gc_values.foreground = style->text[i];
3258 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3260 gc_values.foreground = style->base[i];
3261 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3263 gc_values.foreground = style->text_aa[i];
3264 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3269 msw_style_unrealize (GtkStyle * style)
3271 parent_class->unrealize (style);
3275 msw_style_class_init (MswStyleClass * klass)
3277 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3279 parent_class = g_type_class_peek_parent (klass);
3281 style_class->init_from_rc = msw_style_init_from_rc;
3282 style_class->draw_arrow = draw_arrow;
3283 style_class->draw_box = draw_box;
3284 style_class->draw_check = draw_check;
3285 style_class->draw_option = draw_option;
3286 style_class->draw_tab = draw_tab;
3287 style_class->draw_flat_box = draw_flat_box;
3288 style_class->draw_expander = draw_expander;
3289 style_class->draw_extension = draw_extension;
3290 style_class->draw_box_gap = draw_box_gap;
3291 style_class->draw_shadow = draw_shadow;
3292 style_class->draw_hline = draw_hline;
3293 style_class->draw_vline = draw_vline;
3294 style_class->draw_handle = draw_handle;
3295 style_class->draw_resize_grip = draw_resize_grip;
3296 style_class->draw_slider = draw_slider;
3297 style_class->draw_focus = draw_focus;
3299 style_class->realize = msw_style_realize;
3300 style_class->unrealize = msw_style_unrealize;
3303 GType msw_type_style = 0;
3306 msw_style_register_type (GTypeModule * module)
3308 static const GTypeInfo object_info = {
3309 sizeof (MswStyleClass),
3310 (GBaseInitFunc) NULL,
3311 (GBaseFinalizeFunc) NULL,
3312 (GClassInitFunc) msw_style_class_init,
3313 NULL, /* class_finalize */
3314 NULL, /* class_data */
3316 0, /* n_preallocs */
3317 (GInstanceInitFunc) NULL,
3320 msw_type_style = g_type_module_register_type (module,
3327 msw_style_init (void)
3330 msw_style_setup_system_settings ();
3331 setup_msw_rc_style ();
3334 DeleteObject( g_light_pen );
3338 DeleteObject( g_dark_pen );
3343 void msw_style_finalize(void)
3345 if( g_dither_brush ){
3346 DeleteObject( g_dither_brush );
3349 DeleteObject( g_light_pen );
3352 DeleteObject( g_dark_pen );