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;
82 static const guint8 check_aa_bits[] = {
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
87 static const guint8 check_base_bits[] = {
88 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07,
90 0x07, 0xfc, 0x07, 0xfc, 0x07, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00
92 static const guint8 check_black_bits[] = {
93 0x00, 0x00, 0xfe, 0x0f, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
95 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00
97 static const guint8 check_dark_bits[] = {
98 0xff, 0x1f, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
100 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00
102 static const guint8 check_light_bits[] = {
103 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10,
105 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0xfe, 0x1f
107 static const guint8 check_mid_bits[] = {
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08,
110 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xfc, 0x0f, 0x00, 0x00
112 static const guint8 check_text_bits[] = {
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x88, 0x03,
115 0x00, 0x70, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
117 static const char check_inconsistent_bits[] = {
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0xf0,
119 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
121 static const guint8 radio_base_bits[] = {
122 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xf8, 0x03, 0xfc, 0x07, 0xfc, 0x07,
124 0x07, 0xfc, 0x07, 0xf8, 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00
126 static const guint8 radio_black_bits[] = {
127 0x00, 0x00, 0xf0, 0x01, 0x0c, 0x02, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00,
129 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
131 static const guint8 radio_dark_bits[] = {
132 0xf0, 0x01, 0x0c, 0x06, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00,
134 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
136 static const guint8 radio_light_bits[] = {
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x10,
139 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x0c, 0x06, 0xf0, 0x01
141 static const guint8 radio_mid_bits[] = {
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08,
144 0x08, 0x00, 0x08, 0x00, 0x04, 0x0c, 0x06, 0xf0, 0x01, 0x00, 0x00
146 static const guint8 radio_text_bits[] = {
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf0, 0x01,
149 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
158 {check_aa_bits, NULL},
159 {check_base_bits, NULL},
160 {check_black_bits, NULL},
161 {check_dark_bits, NULL},
162 {check_light_bits, NULL},
163 {check_mid_bits, NULL},
164 {check_text_bits, NULL},
165 {check_inconsistent_bits, NULL},
166 {radio_base_bits, NULL},
167 {radio_black_bits, NULL},
168 {radio_dark_bits, NULL},
169 {radio_light_bits, NULL},
170 {radio_mid_bits, NULL},
171 {radio_text_bits, NULL}
175 get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONT * out_lf)
178 /* TODO: this causes crashes later because the font name is in UCS2, and
179 the pango fns don't deal with that gracefully */
180 if (xp_theme_get_system_font (klazz, type, out_lf))
185 NONCLIENTMETRICS ncm;
187 ncm.cbSize = sizeof (NONCLIENTMETRICS);
189 if (SystemParametersInfo (SPI_GETNONCLIENTMETRICS,
190 sizeof (NONCLIENTMETRICS), &ncm, 0))
192 if (type == XP_THEME_FONT_CAPTION)
193 *out_lf = ncm.lfCaptionFont;
194 else if (type == XP_THEME_FONT_MENU)
195 *out_lf = ncm.lfMenuFont;
196 else if (type == XP_THEME_FONT_STATUS)
197 *out_lf = ncm.lfStatusFont;
199 *out_lf = ncm.lfMessageFont;
207 /***************************** BEGIN STOLEN FROM PANGO *****************************/
210 This code is stolen from Pango 1.4. It attempts to address the following problems:
212 http://bugzilla.gnome.org/show_bug.cgi?id=135098
213 http://sourceforge.net/tracker/index.php?func=detail&aid=895762&group_id=76416&atid=547655
215 As Owen suggested in bug 135098, once Pango 1.6 is released, we need to get rid of this code.
218 #define PING(printlist)
220 /* TrueType defines: */
222 #define MAKE_TT_TABLE_NAME(c1, c2, c3, c4) \
223 (((guint32)c4) << 24 | ((guint32)c3) << 16 | ((guint32)c2) << 8 | ((guint32)c1))
225 #define CMAP (MAKE_TT_TABLE_NAME('c','m','a','p'))
226 #define CMAP_HEADER_SIZE 4
228 #define NAME (MAKE_TT_TABLE_NAME('n','a','m','e'))
229 #define NAME_HEADER_SIZE 6
231 #define ENCODING_TABLE_SIZE 8
233 #define APPLE_UNICODE_PLATFORM_ID 0
234 #define MACINTOSH_PLATFORM_ID 1
235 #define ISO_PLATFORM_ID 2
236 #define MICROSOFT_PLATFORM_ID 3
238 #define SYMBOL_ENCODING_ID 0
239 #define UNICODE_ENCODING_ID 1
240 #define UCS4_ENCODING_ID 10
244 guint16 format_selector;
246 guint16 string_storage_offset;
255 guint16 string_length;
256 guint16 string_offset;
260 pango_win32_get_name_header (HDC hdc, struct name_header *header)
262 if (GetFontData (hdc, NAME, 0, header, sizeof (*header)) !=
266 header->num_records = GUINT16_FROM_BE (header->num_records);
267 header->string_storage_offset =
268 GUINT16_FROM_BE (header->string_storage_offset);
274 pango_win32_get_name_record (HDC hdc, gint i, struct name_record *record)
276 if (GetFontData (hdc, NAME, 6 + i * sizeof (*record),
277 record, sizeof (*record)) != sizeof (*record))
280 record->platform_id = GUINT16_FROM_BE (record->platform_id);
281 record->encoding_id = GUINT16_FROM_BE (record->encoding_id);
282 record->language_id = GUINT16_FROM_BE (record->language_id);
283 record->name_id = GUINT16_FROM_BE (record->name_id);
284 record->string_length = GUINT16_FROM_BE (record->string_length);
285 record->string_offset = GUINT16_FROM_BE (record->string_offset);
291 get_family_name (LOGFONT * lfp, HDC pango_win32_hdc)
296 struct name_header header;
297 struct name_record record;
299 gint unicode_ix = -1, mac_ix = -1, microsoft_ix = -1;
303 gchar *string = NULL;
308 /* If lfFaceName is ASCII, assume it is the common (English) name for the
309 font. Is this valid? Do some TrueType fonts have different names in
310 French, German, etc, and does the system return these if the locale is
311 set to use French, German, etc? */
312 l = strlen (lfp->lfFaceName);
313 for (i = 0; i < l; i++)
314 if (lfp->lfFaceName[i] < ' ' || lfp->lfFaceName[i] > '~')
318 return g_strdup (lfp->lfFaceName);
320 if ((hfont = CreateFontIndirect (lfp)) == NULL)
323 if ((oldhfont = (HFONT) SelectObject (pango_win32_hdc, hfont)) == NULL)
326 if (!pango_win32_get_name_header (pango_win32_hdc, &header))
329 PING (("%d name records", header.num_records));
331 for (i = 0; i < header.num_records; i++)
333 if (!pango_win32_get_name_record (pango_win32_hdc, i, &record))
336 if ((record.name_id != 1 && record.name_id != 16)
337 || record.string_length <= 0)
340 PING (("platform:%d encoding:%d language:%04x name_id:%d",
341 record.platform_id, record.encoding_id, record.language_id,
344 if (record.platform_id == APPLE_UNICODE_PLATFORM_ID ||
345 record.platform_id == ISO_PLATFORM_ID)
347 else if (record.platform_id == MACINTOSH_PLATFORM_ID && record.encoding_id == 0 && /* Roman
349 record.language_id == 0) /* English */
351 else if (record.platform_id == MICROSOFT_PLATFORM_ID)
352 if ((microsoft_ix == -1 ||
353 PRIMARYLANGID (record.language_id) == LANG_ENGLISH) &&
354 (record.encoding_id == SYMBOL_ENCODING_ID ||
355 record.encoding_id == UNICODE_ENCODING_ID ||
356 record.encoding_id == UCS4_ENCODING_ID))
360 if (microsoft_ix >= 0)
361 name_ix = microsoft_ix;
362 else if (mac_ix >= 0)
364 else if (unicode_ix >= 0)
365 name_ix = unicode_ix;
369 if (!pango_win32_get_name_record (pango_win32_hdc, name_ix, &record))
372 string = g_malloc (record.string_length + 1);
373 if (GetFontData (pango_win32_hdc, NAME,
374 header.string_storage_offset + record.string_offset,
375 string, record.string_length) != record.string_length)
378 string[record.string_length] = '\0';
380 if (name_ix == microsoft_ix)
381 if (record.encoding_id == SYMBOL_ENCODING_ID ||
382 record.encoding_id == UNICODE_ENCODING_ID)
383 codeset = "UTF-16BE";
386 else if (name_ix == mac_ix)
387 codeset = "MacRoman";
388 else /* name_ix == unicode_ix */
392 g_convert (string, record.string_length, "UTF-8", codeset, NULL,
400 SelectObject (pango_win32_hdc, oldhfont);
401 DeleteObject (hfont);
407 SelectObject (pango_win32_hdc, oldhfont);
410 DeleteObject (hfont);
413 return g_locale_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
416 /***************************** END STOLEN FROM PANGO *****************************/
419 sys_font_to_pango_font (XpThemeClass klazz, XpThemeFont type, char *buf,
430 if (get_system_font (klazz, type, &lf))
436 weight = "Ultra-Light";
448 weight = "Semi-Bold";
452 weight = "Ultra-Bold";
469 hwnd = GetDesktopWindow ();
473 pt_size = -MulDiv (lf.lfHeight, 72,
474 GetDeviceCaps (hDC, LOGPIXELSY));
479 font = get_family_name (&lf, hDC);
482 ReleaseDC (hwnd, hDC);
487 g_snprintf (buf, bufsiz, "%s %s %s %d", font, style, weight, pt_size);
496 /* missing from ms's header files */
497 #ifndef SPI_GETMENUSHOWDELAY
498 #define SPI_GETMENUSHOWDELAY 106
501 /* I don't know the proper XP theme class for things like
502 HIGHLIGHTTEXT, so we'll just define it to be "BUTTON"
504 #define XP_THEME_CLASS_TEXT XP_THEME_CLASS_BUTTON
507 setup_menu_settings (GtkSettings * settings)
510 gboolean win95 = FALSE;
511 OSVERSIONINFOEX osvi;
512 GObjectClass *klazz = G_OBJECT_GET_CLASS (G_OBJECT (settings));
514 ZeroMemory (&osvi, sizeof (OSVERSIONINFOEX));
515 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
517 if (!GetVersionEx ((OSVERSIONINFO *) & osvi))
518 win95 = TRUE; /* assume the worst */
520 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
521 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
526 if (SystemParametersInfo
527 (SPI_GETMENUSHOWDELAY, 0, &menu_delay, 0))
531 if (g_object_class_find_property
532 (klazz, "gtk-menu-bar-popup-delay"))
534 g_object_set (settings,
535 "gtk-menu-bar-popup-delay",
538 if (g_object_class_find_property
539 (klazz, "gtk-menu-popup-delay"))
541 g_object_set (settings,
542 "gtk-menu-popup-delay",
545 if (g_object_class_find_property
546 (klazz, "gtk-menu-popdown-delay"))
548 g_object_set (settings,
549 "gtk-menu-popdown-delay",
558 msw_style_setup_system_settings (void)
560 GtkSettings *settings;
561 int cursor_blink_time;
563 settings = gtk_settings_get_default ();
567 cursor_blink_time = GetCaretBlinkTime ();
568 g_object_set (settings, "gtk-cursor-blink", cursor_blink_time > 0, NULL);
570 if (cursor_blink_time > 0)
571 g_object_set (settings, "gtk-cursor-blink-time",
572 2 * cursor_blink_time, NULL);
574 g_object_set (settings, "gtk-double-click-distance",
575 GetSystemMetrics (SM_CXDOUBLECLK), NULL);
576 g_object_set (settings, "gtk-double-click-time", GetDoubleClickTime (),
578 g_object_set (settings, "gtk-dnd-drag-threshold",
579 GetSystemMetrics (SM_CXDRAG), NULL);
581 setup_menu_settings (settings);
584 http://developer.gnome.org/doc/API/2.0/gtk/GtkSettings.html
585 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/systemparametersinfo.asp
586 http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getsystemmetrics.asp */
590 setup_system_font (GtkStyle * style)
592 char buf[256], *font; /* It's okay, lfFaceName is smaller than 32
595 if ((font = sys_font_to_pango_font (XP_THEME_CLASS_TEXT,
596 XP_THEME_FONT_MESSAGE,
597 buf, sizeof (buf))) != NULL)
599 if (style->font_desc)
600 pango_font_description_free (style->font_desc);
602 style->font_desc = pango_font_description_from_string (font);
607 sys_color_to_gtk_color (XpThemeClass klazz, int id, GdkColor * pcolor)
611 if (!xp_theme_get_system_color (klazz, id, &color))
612 color = GetSysColor (id);
614 pcolor->pixel = color;
615 pcolor->red = (GetRValue (color) << 8) | GetRValue (color);
616 pcolor->green = (GetGValue (color) << 8) | GetGValue (color);
617 pcolor->blue = (GetBValue (color) << 8) | GetBValue (color);
621 get_system_metric (XpThemeClass klazz, int id)
625 if (!xp_theme_get_system_metric (klazz, id, &rval))
626 rval = GetSystemMetrics (id);
632 setup_msw_rc_style (void)
634 char buf[1024], font_buf[256], *font_ptr;
635 char menu_bar_prelight_str[128];
638 GdkColor menu_text_color;
639 GdkColor tooltip_back;
640 GdkColor tooltip_fore;
643 GdkColor progress_back;
645 GdkColor fg_prelight;
646 GdkColor bg_prelight;
647 GdkColor base_prelight;
648 GdkColor text_prelight;
651 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
653 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
655 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
657 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
660 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENUTEXT,
662 sys_color_to_gtk_color (XP_THEME_CLASS_MENU, COLOR_MENU, &menu_color);
665 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOTEXT,
667 sys_color_to_gtk_color (XP_THEME_CLASS_TOOLTIP, COLOR_INFOBK,
670 /* text on push buttons. TODO: button shadows, backgrounds, and
672 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT, &btn_fore);
673 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE, &btn_face);
675 /* progress bar background color */
676 sys_color_to_gtk_color (XP_THEME_CLASS_PROGRESS, COLOR_HIGHLIGHT,
679 /* Enable coloring for menus. */
681 sys_font_to_pango_font (XP_THEME_CLASS_MENU, XP_THEME_FONT_MENU,
682 font_buf, sizeof (font_buf));
683 g_snprintf (buf, sizeof (buf),
684 "style \"msw-menu\" = \"msw-default\"\n" "{\n"
685 "GtkMenuItem::toggle-spacing = 8\n"
686 "fg[PRELIGHT] = { %d, %d, %d }\n"
687 "bg[PRELIGHT] = { %d, %d, %d }\n"
688 "text[PRELIGHT] = { %d, %d, %d }\n"
689 "base[PRELIGHT] = { %d, %d, %d }\n"
690 "fg[NORMAL] = { %d, %d, %d }\n"
691 "bg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
692 "}widget_class \"*MenuItem*\" style \"msw-menu\"\n"
693 "widget_class \"*GtkMenu\" style \"msw-menu\"\n"
694 "widget_class \"*GtkMenuShell*\" style \"msw-menu\"\n",
695 fg_prelight.red, fg_prelight.green, fg_prelight.blue,
696 bg_prelight.red, bg_prelight.green, bg_prelight.blue,
697 text_prelight.red, text_prelight.green, text_prelight.blue,
698 base_prelight.red, base_prelight.green, base_prelight.blue,
699 menu_text_color.red, menu_text_color.green,
700 menu_text_color.blue, menu_color.red, menu_color.green,
701 menu_color.blue, (font_ptr ? "font_name" : "#"),
702 (font_ptr ? font_ptr : " font name should go here"));
703 gtk_rc_parse_string (buf);
705 if( xp_theme_is_active() ) {
706 *menu_bar_prelight_str = '\0';
709 g_snprintf(menu_bar_prelight_str, sizeof(menu_bar_prelight_str),
710 "fg[PRELIGHT] = { %d, %d, %d }\n",
711 menu_text_color.red, menu_text_color.green, menu_text_color.blue);
714 /* Enable coloring for menu bars. */
715 g_snprintf (buf, sizeof (buf),
716 "style \"msw-menu-bar\" = \"msw-menu\"\n"
718 "bg[NORMAL] = { %d, %d, %d }\n"
720 "GtkMenuBar::shadow-type = %d\n"
722 FIXME: This should be enabled once gtk+ support
723 GtkMenuBar::prelight-item style property.
725 /* "GtkMenuBar::prelight-item = 1\n" */
726 "}widget_class \"*MenuBar*\" style \"msw-menu-bar\"\n",
727 btn_face.red, btn_face.green, btn_face.blue,
728 menu_bar_prelight_str,
729 xp_theme_is_active() ? 0 : 2 );
730 gtk_rc_parse_string (buf);
732 g_snprintf (buf, sizeof (buf),
733 "style \"msw-toolbar\" = \"msw-default\"\n"
735 "GtkHandleBox::shadow-type = %s\n"
736 "GtkToolbar::shadow-type = %s\n"
737 "}widget_class \"*HandleBox*\" style \"msw-toolbar\"\n",
738 "etched-in", "etched-in");
739 gtk_rc_parse_string (buf);
741 /* enable tooltip fonts */
743 sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
744 font_buf, sizeof (font_buf));
745 g_snprintf (buf, sizeof (buf),
746 "style \"msw-tooltips-caption\" = \"msw-default\"\n"
747 "{fg[NORMAL] = { %d, %d, %d }\n" "%s = \"%s\"\n"
748 "}widget \"gtk-tooltips.GtkLabel\" style \"msw-tooltips-caption\"\n",
749 tooltip_fore.red, tooltip_fore.green, tooltip_fore.blue,
750 (font_ptr ? "font_name" : "#"),
751 (font_ptr ? font_ptr : " font name should go here"));
752 gtk_rc_parse_string (buf);
754 g_snprintf (buf, sizeof (buf),
755 "style \"msw-tooltips\" = \"msw-default\"\n"
756 "{bg[NORMAL] = { %d, %d, %d }\n"
757 "}widget \"gtk-tooltips*\" style \"msw-tooltips\"\n",
758 tooltip_back.red, tooltip_back.green, tooltip_back.blue);
759 gtk_rc_parse_string (buf);
761 /* enable font theming for status bars */
763 sys_font_to_pango_font (XP_THEME_CLASS_STATUS, XP_THEME_FONT_STATUS,
764 font_buf, sizeof (font_buf));
765 g_snprintf (buf, sizeof (buf),
766 "style \"msw-status\" = \"msw-default\"\n" "{%s = \"%s\"\n"
767 "bg[NORMAL] = { %d, %d, %d }\n"
768 "}widget_class \"*Status*\" style \"msw-status\"\n",
769 (font_ptr ? "font_name" : "#"),
770 (font_ptr ? font_ptr : " font name should go here"),
771 btn_face.red, btn_face.green, btn_face.blue);
772 gtk_rc_parse_string (buf);
774 /* enable coloring for text on buttons TODO: use GetThemeMetric for the
775 border and outside border */
776 g_snprintf (buf, sizeof (buf),
777 "style \"msw-button\" = \"msw-default\"\n"
779 "bg[NORMAL] = { %d, %d, %d }\n"
780 "bg[PRELIGHT] = { %d, %d, %d }\n"
781 "bg[INSENSITIVE] = { %d, %d, %d }\n"
782 "fg[PRELIGHT] = { %d, %d, %d }\n"
783 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
784 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
785 "GtkButton::child-displacement-x = 1\n"
786 "GtkButton::child-displacement-y = 1\n"
787 "GtkButton::focus-padding = %d\n"
788 "}widget_class \"*Button*\" style \"msw-button\"\n",
789 btn_face.red, btn_face.green, btn_face.blue,
790 btn_face.red, btn_face.green, btn_face.blue,
791 btn_face.red, btn_face.green, btn_face.blue,
792 btn_fore.red, btn_fore.green, btn_fore.blue,
793 xp_theme_is_active() ? 1 : 2 );
794 gtk_rc_parse_string (buf);
796 /* enable coloring for progress bars */
797 g_snprintf (buf, sizeof (buf),
798 "style \"msw-progress\" = \"msw-default\"\n"
799 "{bg[PRELIGHT] = { %d, %d, %d }\n"
800 "bg[NORMAL] = { %d, %d, %d }\n"
801 "}widget_class \"*Progress*\" style \"msw-progress\"\n",
805 btn_face.red, btn_face.green, btn_face.blue);
806 gtk_rc_parse_string (buf);
808 /* scrollbar thumb width and height */
809 g_snprintf (buf, sizeof (buf),
810 "style \"msw-vscrollbar\" = \"msw-default\"\n"
811 "{GtkRange::slider-width = %d\n"
812 "GtkRange::stepper-size = %d\n"
813 "GtkRange::stepper-spacing = 0\n"
814 "GtkRange::trough_border = 0\n"
815 "GtkScale::slider-length = %d\n"
816 "GtkScrollbar::min-slider-length = 8\n"
817 "}widget_class \"*VScrollbar*\" style \"msw-vscrollbar\"\n"
818 "widget_class \"*VScale*\" style \"msw-vscrollbar\"\n",
819 GetSystemMetrics (SM_CYVTHUMB),
820 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CXVSCROLL),
822 gtk_rc_parse_string (buf);
824 g_snprintf (buf, sizeof (buf),
825 "style \"msw-hscrollbar\" = \"msw-default\"\n"
826 "{GtkRange::slider-width = %d\n"
827 "GtkRange::stepper-size = %d\n"
828 "GtkRange::stepper-spacing = 0\n"
829 "GtkRange::trough_border = 0\n"
830 "GtkScale::slider-length = %d\n"
831 "GtkScrollbar::min-slider-length = 8\n"
832 "}widget_class \"*HScrollbar*\" style \"msw-hscrollbar\"\n"
833 "widget_class \"*HScale*\" style \"msw-hscrollbar\"\n",
834 GetSystemMetrics (SM_CXHTHUMB),
835 get_system_metric (XP_THEME_CLASS_SCROLLBAR, SM_CYHSCROLL),
837 gtk_rc_parse_string (buf);
839 gtk_rc_parse_string (
840 "style \"msw-scrolled-window\" = \"msw-default\"\n"
841 "{GtkScrolledWindow::scrollbars-within-bevel = 1}\n"
842 "class \"GtkScrolledWindow\" style \"msw-scrolled-window\"\n");
844 /* radio/check button sizes */
845 g_snprintf (buf, sizeof (buf),
846 "style \"msw-checkbutton\" = \"msw-button\"\n"
847 "{GtkCheckButton::indicator-size = 13\n"
848 "}widget_class \"*CheckButton*\" style \"msw-checkbutton\"\n"
849 "widget_class \"*RadioButton*\" style \"msw-checkbutton\"\n");
850 gtk_rc_parse_string (buf);
852 /* size of combo box toggle button */
853 g_snprintf (buf, sizeof(buf),
854 "style \"msw-combobox-button\" = \"msw-default\"\n"
858 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
859 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
860 "GtkButton::child-displacement-x = 0\n"
861 "GtkButton::child-displacement-y = 0\n"
862 "GtkWidget::focus-padding = 0\n"
863 "GtkWidget::focus-line-width = 0\n"
865 "widget_class \"*ComboBox*ToggleButton*\" style \"msw-combobox-button\"\n");
866 gtk_rc_parse_string (buf);
868 g_snprintf (buf, sizeof(buf),
869 "style \"msw-combobox\" = \"msw-default\"\n"
871 "GtkComboBox::shadow-type = in\n"
875 "class \"GtkComboBox\" style \"msw-combobox\"\n",
876 GetSystemMetrics (SM_CXEDGE),
877 GetSystemMetrics (SM_CYEDGE));
878 gtk_rc_parse_string (buf);
880 /* size of tree view header */
881 g_snprintf (buf, sizeof(buf),
882 "style \"msw-header-button\" = \"msw-default\"\n"
886 "GtkButton::default-border = { 0, 0, 0, 0 }\n"
887 "GtkButton::default-outside-border = { 0, 0, 0, 0 }\n"
888 "GtkButton::child-displacement-x = 1\n"
889 "GtkButton::child-displacement-y = 1\n"
890 "GtkWidget::focus-padding = 0\n"
891 "GtkWidget::focus-line-width = 0\n"
893 "widget_class \"*TreeView*Button*\" style \"msw-header-button\"\n",
894 xp_theme_is_active() ? 2 : 0 );
895 gtk_rc_parse_string (buf);
897 /* FIXME: This should be enabled once gtk+ support GtkNotebok::prelight-tab */
898 /* enable prelight tab of GtkNotebook */
900 g_snprintf (buf, sizeof (buf),
901 "style \"msw-notebook\" = \"msw-default\"\n"
902 "{GtkNotebook::prelight-tab=1\n"
903 "}widget_class \"*Notebook*\" style \"msw-notebook\"\n");
904 gtk_rc_parse_string (buf);
907 /* FIXME: This should be enabled once gtk+ support GtkTreeView::full-row-focus */
909 g_snprintf (buf, sizeof (buf),
910 "style \"msw-treeview\" = \"msw-default\"\n"
911 "{GtkTreeView::full-row-focus=0\n"
912 "}widget_class \"*TreeView*\" style \"msw-treeview\"\n");
913 gtk_rc_parse_string (buf);
918 setup_system_styles (GtkStyle * style)
922 /* Default background */
923 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
924 &style->bg[GTK_STATE_NORMAL]);
925 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
926 &style->bg[GTK_STATE_SELECTED]);
927 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
928 &style->bg[GTK_STATE_INSENSITIVE]);
929 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
930 &style->bg[GTK_STATE_ACTIVE]);
931 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
932 &style->bg[GTK_STATE_PRELIGHT]);
935 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
936 &style->base[GTK_STATE_NORMAL]);
937 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHT,
938 &style->base[GTK_STATE_SELECTED]);
939 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
940 &style->base[GTK_STATE_INSENSITIVE]);
941 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNFACE,
942 &style->base[GTK_STATE_ACTIVE]);
943 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOW,
944 &style->base[GTK_STATE_PRELIGHT]);
947 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
948 &style->text[GTK_STATE_NORMAL]);
949 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
950 &style->text[GTK_STATE_SELECTED]);
951 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_GRAYTEXT,
952 &style->text[GTK_STATE_INSENSITIVE]);
953 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
954 &style->text[GTK_STATE_ACTIVE]);
955 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
956 &style->text[GTK_STATE_PRELIGHT]);
958 /* Default foreground */
959 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
960 &style->fg[GTK_STATE_NORMAL]);
961 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_HIGHLIGHTTEXT,
962 &style->fg[GTK_STATE_SELECTED]);
963 sys_color_to_gtk_color (XP_THEME_CLASS_TEXT, COLOR_GRAYTEXT,
964 &style->fg[GTK_STATE_INSENSITIVE]);
965 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_BTNTEXT,
966 &style->fg[GTK_STATE_ACTIVE]);
967 sys_color_to_gtk_color (XP_THEME_CLASS_WINDOW, COLOR_WINDOWTEXT,
968 &style->fg[GTK_STATE_PRELIGHT]);
970 for (i = 0; i < 5; i++)
972 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DSHADOW,
974 sys_color_to_gtk_color (XP_THEME_CLASS_BUTTON, COLOR_3DHILIGHT,
978 (style->light[i].red + style->dark[i].red) / 2;
979 style->mid[i].green =
980 (style->light[i].green + style->dark[i].green) / 2;
982 (style->light[i].blue + style->dark[i].blue) / 2;
984 style->text_aa[i].red =
985 (style->text[i].red + style->base[i].red) / 2;
986 style->text_aa[i].green =
987 (style->text[i].green + style->base[i].green) / 2;
988 style->text_aa[i].blue =
989 (style->text[i].blue + style->base[i].blue) / 2;
994 sanitize_size (GdkWindow * window, gint * width, gint * height)
996 gboolean set_bg = FALSE;
998 if ((*width == -1) && (*height == -1))
1000 set_bg = GDK_IS_WINDOW (window);
1001 gdk_drawable_get_size (window, width, height);
1003 else if (*width == -1)
1004 gdk_drawable_get_size (window, width, NULL);
1005 else if (*height == -1)
1006 gdk_drawable_get_size (window, NULL, height);
1011 static XpThemeElement
1012 map_gtk_progress_bar_to_xp (GtkProgressBar * progress_bar, gboolean trough)
1016 switch (progress_bar->orientation)
1018 case GTK_PROGRESS_LEFT_TO_RIGHT:
1019 case GTK_PROGRESS_RIGHT_TO_LEFT:
1021 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_H
1022 : XP_THEME_ELEMENT_PROGRESS_BAR_H;
1026 ? XP_THEME_ELEMENT_PROGRESS_TROUGH_V
1027 : XP_THEME_ELEMENT_PROGRESS_BAR_V;
1034 is_combo_box_child (GtkWidget* w)
1041 for (tmp = w->parent; tmp; tmp = tmp->parent)
1043 if (GTK_IS_COMBO_BOX(tmp))
1051 combo_box_draw_arrow (GtkStyle * style,
1054 GdkRectangle * area,
1057 if (xp_theme_is_active ())
1060 if (widget && GTK_IS_TOGGLE_BUTTON(widget->parent) )
1066 dc = get_window_dc( style, window, state, area->x, area->y, area->width, area->height, &rect );
1067 border = (GTK_TOGGLE_BUTTON(widget->parent)->active ? DFCS_PUSHED|DFCS_FLAT : 0);
1069 InflateRect( &rect, 1, 1 );
1070 DrawFrameControl (dc, &rect, DFC_SCROLL, DFCS_SCROLLDOWN | border);
1072 release_window_dc( style, window, state );
1080 draw_part (GdkDrawable * drawable,
1081 GdkGC * gc, GdkRectangle * area, gint x, gint y, Part part)
1084 gdk_gc_set_clip_rectangle (gc, area);
1086 if (!parts[part].bmap)
1087 parts[part].bmap = gdk_bitmap_create_from_data (drawable,
1089 PART_SIZE, PART_SIZE);
1091 gdk_gc_set_ts_origin (gc, x, y);
1092 gdk_gc_set_stipple (gc, parts[part].bmap);
1093 gdk_gc_set_fill (gc, GDK_STIPPLED);
1095 gdk_draw_rectangle (drawable, gc, TRUE, x, y, PART_SIZE, PART_SIZE);
1097 gdk_gc_set_fill (gc, GDK_SOLID);
1100 gdk_gc_set_clip_rectangle (gc, NULL);
1104 draw_check (GtkStyle * style,
1107 GtkShadowType shadow,
1108 GdkRectangle * area,
1110 const gchar * detail, gint x, gint y, gint width, gint height)
1112 x -= (1 + PART_SIZE - width) / 2;
1113 y -= (1 + PART_SIZE - height) / 2;
1115 if (detail && strcmp (detail, "check") == 0) /* Menu item */
1117 if (shadow == GTK_SHADOW_IN)
1119 draw_part (window, style->black_gc, area, x, y,
1121 draw_part (window, style->dark_gc[state], area, x, y,
1127 XpThemeElement theme_elt = XP_THEME_ELEMENT_CHECKBOX;
1130 case GTK_SHADOW_ETCHED_IN:
1131 theme_elt = XP_THEME_ELEMENT_INCONSISTENT_CHECKBOX;
1135 theme_elt = XP_THEME_ELEMENT_PRESSED_CHECKBOX;
1142 if (!xp_theme_draw (window, theme_elt,
1143 style, x, y, width, height, state, area))
1145 if( detail && !strcmp(detail, "cellcheck") )
1146 state = GTK_STATE_NORMAL;
1148 draw_part (window, style->black_gc, area, x, y,
1150 draw_part (window, style->dark_gc[state], area, x, y,
1152 draw_part (window, style->mid_gc[state], area, x, y,
1154 draw_part (window, style->light_gc[state], area, x, y,
1156 draw_part (window, style->base_gc[state], area, x, y,
1159 if (shadow == GTK_SHADOW_IN)
1161 draw_part (window, style->text_gc[state], area, x,
1163 draw_part (window, style->text_aa_gc[state], area,
1166 else if (shadow == GTK_SHADOW_ETCHED_IN)
1168 draw_part (window, style->text_gc[state], area, x, y, CHECK_INCONSISTENT);
1169 draw_part (window, style->text_aa_gc[state], area, x, y, CHECK_AA);
1176 draw_expander (GtkStyle * style,
1179 GdkRectangle * area,
1181 const gchar * detail,
1182 gint x, gint y, GtkExpanderStyle expander_style)
1185 gint expander_semi_size;
1186 XpThemeElement xp_expander;
1188 gtk_widget_style_get (widget, "expander_size", &expander_size, NULL);
1190 switch (expander_style)
1192 case GTK_EXPANDER_COLLAPSED:
1193 case GTK_EXPANDER_SEMI_COLLAPSED:
1194 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED;
1197 xp_expander = XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED;
1201 if ((expander_size % 2) == 0)
1204 if (expander_size > 2)
1208 gdk_gc_set_clip_rectangle (style->fg_gc[state], area);
1210 expander_semi_size = expander_size / 2;
1211 x -= expander_semi_size;
1212 y -= expander_semi_size;
1214 if (!xp_theme_draw (window, xp_expander, style,
1215 x, y, expander_size, expander_size, state, area))
1222 dc = get_window_dc( style, window, state, x, y, expander_size, expander_size, &rect );
1223 FrameRect( dc, &rect, GetSysColorBrush(COLOR_GRAYTEXT) );
1224 InflateRect( &rect, -1, -1 );
1225 FillRect( dc, &rect, GetSysColorBrush(state == GTK_STATE_INSENSITIVE ? COLOR_BTNFACE : COLOR_WINDOW) );
1227 InflateRect( &rect, -1, -1 );
1229 pen = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_WINDOWTEXT) );
1230 old_pen = SelectObject( dc, pen );
1232 MoveToEx( dc, rect.left, rect.top - 2 + expander_semi_size, NULL );
1233 LineTo( dc, rect.right, rect.top - 2 + expander_semi_size );
1235 if( expander_style == GTK_EXPANDER_COLLAPSED ||
1236 expander_style == GTK_EXPANDER_SEMI_COLLAPSED )
1238 MoveToEx( dc, rect.left - 2 + expander_semi_size, rect.top, NULL );
1239 LineTo( dc, rect.left - 2 + expander_semi_size, rect.bottom );
1242 SelectObject( dc, old_pen );
1243 DeleteObject( pen );
1244 release_window_dc( style, window, state );
1248 gdk_gc_set_clip_rectangle (style->fg_gc[state], NULL);
1252 draw_option (GtkStyle * style,
1255 GtkShadowType shadow,
1256 GdkRectangle * area,
1258 const gchar * detail, gint x, gint y, gint width, gint height)
1260 x -= (1 + PART_SIZE - width) / 2;
1261 y -= (1 + PART_SIZE - height) / 2;
1263 if (detail && strcmp (detail, "option") == 0) /* Menu item */
1265 if (shadow == GTK_SHADOW_IN)
1266 draw_part (window, style->fg_gc[state], area, x, y,
1271 if (xp_theme_draw (window, shadow == GTK_SHADOW_IN
1272 ? XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON
1273 : XP_THEME_ELEMENT_RADIO_BUTTON,
1274 style, x, y, width, height, state, area))
1279 if( detail && !strcmp(detail, "cellradio") )
1280 state = GTK_STATE_NORMAL;
1282 draw_part (window, style->black_gc, area, x, y,
1284 draw_part (window, style->dark_gc[state], area, x, y,
1286 draw_part (window, style->mid_gc[state], area, x, y,
1288 draw_part (window, style->light_gc[state], area, x, y,
1290 draw_part (window, style->base_gc[state], area, x, y,
1293 if (shadow == GTK_SHADOW_IN)
1294 draw_part (window, style->text_gc[state], area, x, y,
1301 draw_varrow (GdkWindow * window,
1303 GtkShadowType shadow_type,
1304 GdkRectangle * area,
1305 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1308 gint y_start, y_increment;
1312 gdk_gc_set_clip_rectangle (gc, area);
1314 width = width + width % 2 - 1; /* Force odd */
1315 steps = 1 + width / 2;
1316 extra = height - steps;
1318 if (arrow_type == GTK_ARROW_DOWN)
1325 y_start = y + height - 1;
1329 for (i = extra; i < height; i++)
1331 gdk_draw_line (window, gc,
1332 x + (i - extra), y_start + i * y_increment,
1333 x + width - (i - extra) - 1,
1334 y_start + i * y_increment);
1338 gdk_gc_set_clip_rectangle (gc, NULL);
1342 draw_harrow (GdkWindow * window,
1344 GtkShadowType shadow_type,
1345 GdkRectangle * area,
1346 GtkArrowType arrow_type, gint x, gint y, gint width, gint height)
1349 gint x_start, x_increment;
1353 gdk_gc_set_clip_rectangle (gc, area);
1355 height = height + height % 2 - 1; /* Force odd */
1356 steps = 1 + height / 2;
1357 extra = width - steps;
1359 if (arrow_type == GTK_ARROW_RIGHT)
1366 x_start = x + width - 1;
1370 for (i = extra; i < width; i++)
1372 gdk_draw_line (window, gc,
1373 x_start + i * x_increment, y + (i - extra),
1374 x_start + i * x_increment,
1375 y + height - (i - extra) - 1);
1380 gdk_gc_set_clip_rectangle (gc, NULL);
1383 /* This function makes up for some brokeness in gtkrange.c
1384 * where we never get the full arrow of the stepper button
1385 * and the type of button in a single drawing function.
1387 * It doesn't work correctly when the scrollbar is squished
1388 * to the point we don't have room for full-sized steppers.
1391 reverse_engineer_stepper_box (GtkWidget * range,
1392 GtkArrowType arrow_type,
1393 gint * x, gint * y, gint * width, gint * height)
1395 gint slider_width = 14, stepper_size = 14;
1401 gtk_widget_style_get (range,
1402 "slider_width", &slider_width,
1403 "stepper_size", &stepper_size, NULL);
1406 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1408 box_width = slider_width;
1409 box_height = stepper_size;
1413 box_width = stepper_size;
1414 box_height = slider_width;
1417 *x = *x - (box_width - *width) / 2;
1418 *y = *y - (box_height - *height) / 2;
1420 *height = box_height;
1423 static XpThemeElement
1424 to_xp_arrow (GtkArrowType arrow_type)
1426 XpThemeElement xp_arrow;
1431 xp_arrow = XP_THEME_ELEMENT_ARROW_UP;
1433 case GTK_ARROW_DOWN:
1434 xp_arrow = XP_THEME_ELEMENT_ARROW_DOWN;
1436 case GTK_ARROW_LEFT:
1437 xp_arrow = XP_THEME_ELEMENT_ARROW_LEFT;
1440 xp_arrow = XP_THEME_ELEMENT_ARROW_RIGHT;
1448 draw_arrow (GtkStyle * style,
1451 GtkShadowType shadow,
1452 GdkRectangle * area,
1454 const gchar * detail,
1455 GtkArrowType arrow_type,
1456 gboolean fill, gint x, gint y, gint width, gint height)
1462 name = gtk_widget_get_name (widget);
1464 sanitize_size (window, &width, &height);
1466 if (GTK_IS_ARROW(widget) && is_combo_box_child(widget))
1468 if (combo_box_draw_arrow (style, window, state, area, widget))
1474 if (detail && strcmp (detail, "spinbutton") == 0)
1476 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1483 if( arrow_type == GTK_ARROW_DOWN )
1487 if( state == GTK_STATE_ACTIVE ) {
1491 draw_varrow (window, style->fg_gc[state], shadow, area,
1492 arrow_type, x, y, width, height);
1495 else if (detail && (!strcmp (detail, "vscrollbar")
1496 || !strcmp (detail, "hscrollbar")))
1498 gboolean is_disabled = FALSE;
1500 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1504 gint box_width = width;
1505 gint box_height = height;
1507 reverse_engineer_stepper_box (widget, arrow_type,
1508 &box_x, &box_y, &box_width,
1511 if (scrollbar->range.adjustment->page_size >=
1512 (scrollbar->range.adjustment->upper -
1513 scrollbar->range.adjustment->lower))
1517 (window, to_xp_arrow (arrow_type), style, box_x, box_y,
1518 box_width, box_height, state, area))
1526 btn_type = DFCS_SCROLLUP;
1528 case GTK_ARROW_DOWN:
1529 btn_type = DFCS_SCROLLDOWN;
1531 case GTK_ARROW_LEFT:
1532 btn_type = DFCS_SCROLLLEFT;
1534 case GTK_ARROW_RIGHT:
1535 btn_type = DFCS_SCROLLRIGHT;
1537 case GTK_ARROW_NONE:
1540 if( state == GTK_STATE_INSENSITIVE )
1541 btn_type |= DFCS_INACTIVE;
1543 sanitize_size (window, &width, &height);
1545 dc = get_window_dc( style, window, state,
1546 box_x, box_y, box_width, box_height, &rect );
1547 DrawFrameControl( dc, &rect, DFC_SCROLL,
1548 btn_type|(shadow == GTK_SHADOW_IN ? (DFCS_PUSHED|DFCS_FLAT) : 0) );
1549 release_window_dc( style, window, state );
1555 /* draw the toolbar chevrons - waiting for GTK 2.4 */
1556 if (name && !strcmp (name, "gtk-toolbar-arrow"))
1559 (window, XP_THEME_ELEMENT_REBAR_CHEVRON, style, x, y,
1560 width, height, state, area))
1563 /* probably a gtk combo box on a toolbar */
1564 else if (0 /* widget->parent && GTK_IS_BUTTON
1565 (widget->parent) */ )
1568 (window, XP_THEME_ELEMENT_COMBOBUTTON, style, x - 3,
1569 widget->allocation.y + 1, width + 5,
1570 widget->allocation.height - 4, state, area))
1574 if (arrow_type == GTK_ARROW_UP || arrow_type == GTK_ARROW_DOWN)
1576 x += (width - 7) / 2;
1577 y += (height - 5) / 2;
1579 draw_varrow (window, style->fg_gc[state], shadow, area,
1580 arrow_type, x, y, 7, 5);
1584 x += (width - 5) / 2;
1585 y += (height - 7) / 2;
1587 draw_harrow (window, style->fg_gc[state], shadow, area,
1588 arrow_type, x, y, 5, 7);
1594 option_menu_get_props (GtkWidget * widget,
1595 GtkRequisition * indicator_size,
1596 GtkBorder * indicator_spacing)
1598 GtkRequisition *tmp_size = NULL;
1599 GtkBorder *tmp_spacing = NULL;
1602 gtk_widget_style_get (widget,
1603 "indicator_size", &tmp_size,
1604 "indicator_spacing", &tmp_spacing, NULL);
1608 *indicator_size = *tmp_size;
1612 *indicator_size = default_option_indicator_size;
1616 *indicator_spacing = *tmp_spacing;
1617 g_free (tmp_spacing);
1620 *indicator_spacing = default_option_indicator_spacing;
1624 is_toolbar_child (GtkWidget * wid)
1628 if (GTK_IS_TOOLBAR (wid) || GTK_IS_HANDLE_BOX (wid))
1638 is_menu_tool_button_child (GtkWidget * wid)
1642 if (GTK_IS_MENU_TOOL_BUTTON (wid) )
1650 HDC get_window_dc(GtkStyle * style, GdkWindow * window, GtkStateType state_type, gint x, gint y, gint width, gint height, RECT *rect)
1653 GdkDrawable *drawable;
1655 if (!GDK_IS_WINDOW (window))
1663 gdk_window_get_internal_paint_info (window, &drawable, &xoff, &yoff);
1666 rect->left = x - xoff;
1667 rect->top = y - yoff;
1668 rect->right = rect->left + width;
1669 rect->bottom = rect->top + height;
1671 return gdk_win32_hdc_get (drawable, style->dark_gc[state_type], 0);
1674 void release_window_dc(GtkStyle * style, GdkWindow * window, GtkStateType state_type)
1676 GdkDrawable *drawable;
1678 if (!GDK_IS_WINDOW (window))
1684 gdk_window_get_internal_paint_info (window, &drawable, NULL, NULL);
1687 gdk_win32_hdc_release (drawable, style->dark_gc[state_type], 0);
1690 static HPEN get_light_pen()
1692 if( ! g_light_pen ) {
1693 g_light_pen = CreatePen( PS_SOLID|PS_INSIDEFRAME, 1, GetSysColor(COLOR_BTNHIGHLIGHT) );
1698 static HPEN get_dark_pen()
1700 if( ! g_dark_pen ) {
1701 g_dark_pen = CreatePen( PS_SOLID|PS_INSIDEFRAME, 1, GetSysColor(COLOR_BTNSHADOW) );
1707 draw_3d_border( HDC hdc, RECT* rc, gboolean sunken )
1713 pen1 = get_dark_pen();
1714 pen2 = get_light_pen();
1717 pen1 = get_light_pen();
1718 pen2 = get_dark_pen();
1721 MoveToEx( hdc, rc->left, rc->bottom - 1, NULL);
1723 old_pen = SelectObject( hdc, pen1 );
1724 LineTo( hdc, rc->left, rc->top );
1725 LineTo( hdc, rc->right-1, rc->top );
1726 SelectObject( hdc, old_pen );
1728 old_pen = SelectObject( hdc, pen2 );
1729 LineTo( hdc, rc->right-1, rc->bottom-1 );
1730 LineTo( hdc, rc->left, rc->bottom-1 );
1731 SelectObject( hdc, old_pen );
1735 draw_menu_item(GdkWindow* window, GtkWidget* widget, GtkStyle* style,
1736 gint x, gint y, gint width, gint height,
1737 GtkStateType state_type, GdkRectangle* area )
1744 if( (parent = gtk_widget_get_parent(widget))
1745 && GTK_IS_MENU_BAR(parent)
1746 && !xp_theme_is_active() )
1748 bar = GTK_MENU_SHELL(parent);
1750 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1751 if( state_type == GTK_STATE_PRELIGHT ){
1752 draw_3d_border( dc, &rect, bar->active );
1754 release_window_dc( style, window, state_type );
1761 get_dither_brush( void )
1764 HBITMAP pattern_bmp;
1767 if( g_dither_brush )
1768 return g_dither_brush;
1769 for ( i = 0; i < 8; i++ )
1770 pattern[i] = (WORD)(0x5555 << (i & 1));
1771 pattern_bmp = CreateBitmap(8, 8, 1, 1, &pattern);
1773 g_dither_brush = CreatePatternBrush(pattern_bmp);
1774 DeleteObject(pattern_bmp);
1776 return g_dither_brush;
1780 draw_tool_button(GdkWindow* window, GtkWidget* widget, GtkStyle* style,
1781 gint x, gint y, gint width, gint height,
1782 GtkStateType state_type, GdkRectangle* area )
1786 gboolean is_toggled = FALSE;
1788 if ( xp_theme_is_active() ) {
1789 return (xp_theme_draw (window, XP_THEME_ELEMENT_TOOLBAR_BUTTON, style,
1790 x, y, width, height, state_type, area) );
1793 if( GTK_IS_TOGGLE_BUTTON(widget) ){
1794 if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) ) {
1799 if( state_type != GTK_STATE_PRELIGHT
1800 && state_type != GTK_STATE_ACTIVE && !is_toggled )
1803 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1804 if( state_type == GTK_STATE_PRELIGHT ){
1806 FillRect( dc, &rect, GetSysColorBrush(COLOR_BTNFACE));
1808 draw_3d_border( dc, &rect, is_toggled);
1810 else if ( state_type == GTK_STATE_ACTIVE ){
1811 if( is_toggled && ! is_menu_tool_button_child(widget->parent) ){
1812 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
1813 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
1814 FillRect( dc, &rect, get_dither_brush() );
1816 draw_3d_border( dc, &rect, TRUE );
1818 release_window_dc( style, window, state_type );
1823 draw_push_button( GdkWindow* window, GtkWidget* widget, GtkStyle* style, gint x, gint y,
1824 gint width, gint height,
1825 GtkStateType state_type, gboolean is_default )
1830 dc = get_window_dc( style, window, state_type,
1831 x, y, width, height, &rect );
1832 if( GTK_IS_TOGGLE_BUTTON(widget) ) {
1833 if( state_type == GTK_STATE_PRELIGHT &&
1834 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) )
1836 state_type = GTK_STATE_ACTIVE;
1840 if( state_type == GTK_STATE_ACTIVE ) {
1841 if( GTK_IS_TOGGLE_BUTTON(widget) ) {
1842 DrawEdge( dc, &rect, EDGE_SUNKEN, BF_RECT|BF_ADJUST);
1843 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
1844 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
1845 FillRect( dc, &rect, get_dither_brush() );
1848 FrameRect( dc, &rect, GetSysColorBrush(COLOR_WINDOWFRAME) );
1849 InflateRect( &rect, -1, -1 );
1850 FrameRect( dc, &rect, GetSysColorBrush(COLOR_BTNSHADOW) );
1851 InflateRect( &rect, -1, -1 );
1852 FillRect( dc, &rect, GetSysColorBrush(COLOR_BTNFACE) );
1856 if( is_default || GTK_WIDGET_HAS_FOCUS(widget) ) {
1857 FrameRect( dc, &rect, GetSysColorBrush(COLOR_WINDOWFRAME) );
1858 InflateRect( &rect, -1, -1 );
1860 DrawFrameControl( dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH );
1862 release_window_dc(style, window, state_type);
1866 draw_box (GtkStyle * style,
1868 GtkStateType state_type,
1869 GtkShadowType shadow_type,
1870 GdkRectangle * area,
1872 const gchar * detail, gint x, gint y, gint width, gint height)
1874 if (is_combo_box_child (widget) && detail && !strcmp (detail, "button")) {
1879 dc = get_window_dc (style, window, state_type, x, y, width - cx, height, &rect);
1880 FillRect (dc, &rect, GetSysColorBrush(COLOR_WINDOW));
1881 release_window_dc (style, window, state_type);
1883 cx = 2 * GetSystemMetrics (SM_CXEDGE) + 16; /* TODO evaluate arrow width */
1887 if (xp_theme_is_active () && xp_theme_draw (
1888 window, XP_THEME_ELEMENT_COMBOBUTTON, style,
1889 x, y, width, height, state_type, area))
1894 (!strcmp (detail, "button") || !strcmp (detail, "buttondefault")))
1896 if (GTK_IS_TREE_VIEW (widget->parent)
1897 || GTK_IS_CLIST (widget->parent))
1900 (window, XP_THEME_ELEMENT_LIST_HEADER, style, x, y,
1901 width, height, state_type, area))
1906 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
1908 DrawFrameControl( dc, &rect, DFC_BUTTON, DFCS_BUTTONPUSH |
1909 (state_type == GTK_STATE_ACTIVE ? (DFCS_PUSHED|DFCS_FLAT) : 0 ) );
1910 release_window_dc( style, window, state_type );
1913 else if (is_toolbar_child (widget->parent)
1914 || (GTK_RELIEF_NONE == gtk_button_get_relief(GTK_BUTTON(widget)) ) )
1916 if( draw_tool_button( window, widget, style, x, y,
1917 width, height, state_type, area ) )
1924 gboolean is_default = GTK_WIDGET_HAS_DEFAULT(widget);
1927 is_default ? XP_THEME_ELEMENT_DEFAULT_BUTTON :
1928 XP_THEME_ELEMENT_BUTTON, style, x, y, width, height,
1933 draw_push_button( window, widget, style,
1934 x, y, width, height, state_type, is_default );
1939 else if (detail && !strcmp (detail, "spinbutton"))
1941 if (xp_theme_is_drawable (XP_THEME_ELEMENT_SPIN_BUTTON_UP))
1946 else if (detail && (!strcmp (detail, "spinbutton_up")
1947 || !strcmp (detail, "spinbutton_down")))
1949 if ( ! xp_theme_draw ( window,
1950 (!strcmp (detail, "spinbutton_up"))
1951 ? XP_THEME_ELEMENT_SPIN_BUTTON_UP
1952 : XP_THEME_ELEMENT_SPIN_BUTTON_DOWN,
1953 style, x, y, width, height, state_type, area))
1958 dc = get_window_dc( style, window, state_type,
1959 x, y, width, height, &rect );
1960 DrawEdge( dc, &rect,
1961 state_type == GTK_STATE_ACTIVE ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT );
1962 release_window_dc( style, window, state_type );
1966 else if (detail && !strcmp (detail, "slider"))
1968 if (GTK_IS_SCROLLBAR (widget))
1970 GtkScrollbar *scrollbar = GTK_SCROLLBAR (widget);
1971 gboolean is_v = GTK_IS_VSCROLLBAR (widget);
1973 if (xp_theme_draw (window,
1975 ? XP_THEME_ELEMENT_SCROLLBAR_V
1976 : XP_THEME_ELEMENT_SCROLLBAR_H,
1977 style, x, y, width, height, state_type,
1980 XpThemeElement gripper =
1981 (is_v ? XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V :
1982 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H);
1984 /* Do not display grippers on tiny scroll bars,
1985 the limit imposed is rather arbitrary, perhaps
1986 we can fetch the gripper geometry from
1987 somewhere and use that... */
1989 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H
1992 XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V
1998 xp_theme_draw (window, gripper, style, x, y,
1999 width, height, state_type, area);
2004 if (scrollbar->range.adjustment->page_size >=
2005 (scrollbar->range.adjustment->upper -
2006 scrollbar->range.adjustment->lower))
2011 else if (detail && !strcmp (detail, "bar"))
2013 if (widget && GTK_IS_PROGRESS_BAR (widget))
2015 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2016 XpThemeElement xp_progress_bar =
2017 map_gtk_progress_bar_to_xp (progress_bar, FALSE);
2019 if (xp_theme_draw (window, xp_progress_bar, style, x, y,
2020 width, height, state_type, area))
2025 shadow_type = GTK_SHADOW_NONE;
2028 else if (detail && strcmp (detail, "menuitem") == 0)
2030 shadow_type = GTK_SHADOW_NONE;
2031 if( draw_menu_item(window, widget, style,
2032 x, y, width, height, state_type, area ) )
2037 else if (detail && !strcmp (detail, "trough"))
2039 if (widget && GTK_IS_PROGRESS_BAR (widget))
2041 GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (widget);
2042 XpThemeElement xp_progress_bar =
2043 map_gtk_progress_bar_to_xp (progress_bar, TRUE);
2045 (window, xp_progress_bar, style, x, y, width, height,
2052 /* Blank in classic Windows */
2055 else if (widget && GTK_IS_SCROLLBAR (widget))
2057 gboolean is_vertical = GTK_IS_VSCROLLBAR (widget);
2059 if (xp_theme_draw (window,
2061 ? XP_THEME_ELEMENT_TROUGH_V
2062 : XP_THEME_ELEMENT_TROUGH_H,
2064 x, y, width, height, state_type, area))
2073 sanitize_size (window, &width, &height);
2074 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2075 SetTextColor( dc, GetSysColor(COLOR_3DHILIGHT) );
2076 SetBkColor( dc, GetSysColor(COLOR_BTNFACE) );
2077 FillRect( dc, &rect, get_dither_brush() );
2078 release_window_dc( style, window, state_type );
2083 else if (widget && GTK_IS_SCALE (widget))
2085 gboolean is_vertical = GTK_IS_VSCALE (widget);
2087 if (!xp_theme_is_active ())
2089 parent_class->draw_box (style, window, state_type,
2090 GTK_SHADOW_NONE, area,
2091 widget, detail, x, y,
2098 (window, XP_THEME_ELEMENT_SCALE_TROUGH_V,
2099 style, (2 * x + width) / 2, y, 2, height,
2103 parent_class->draw_box (style, window, state_type,
2104 GTK_SHADOW_ETCHED_IN,
2106 (2 * x + width) / 2, y, 1,
2112 (window, XP_THEME_ELEMENT_SCALE_TROUGH_H,
2113 style, x, (2 * y + height) / 2, width, 2,
2117 parent_class->draw_box (style, window, state_type,
2118 GTK_SHADOW_ETCHED_IN,
2119 area, NULL, NULL, x,
2120 (2 * y + height) / 2,
2126 else if (detail && strcmp (detail, "optionmenu") == 0)
2128 if (xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT,
2129 style, x, y, width, height, state_type, area))
2135 && (strcmp (detail, "vscrollbar") == 0
2136 || strcmp (detail, "hscrollbar") == 0))
2141 && (strcmp (detail, "handlebox_bin") == 0
2142 || strcmp (detail, "toolbar") == 0
2143 || strcmp (detail, "menubar") == 0))
2145 sanitize_size( window, &width, &height );
2146 if (xp_theme_draw (window, XP_THEME_ELEMENT_REBAR,
2147 style, x, y, width, height, state_type, area))
2152 else if (detail && (!strcmp (detail, "handlebox"))) /* grip */
2154 if( !xp_theme_is_active() ) {
2160 const gchar *name = gtk_widget_get_name (widget);
2162 if (name && !strcmp (name, "gtk-tooltips"))
2165 (window, XP_THEME_ELEMENT_TOOLTIP, style, x, y, width,
2166 height, state_type, area))
2176 hdc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
2178 brush = GetSysColorBrush (COLOR_3DDKSHADOW);
2180 FrameRect (hdc, &rect, brush);
2181 InflateRect (&rect, -1, -1);
2182 FillRect (hdc, &rect,
2183 (HBRUSH) (COLOR_INFOBK + 1));
2185 release_window_dc (style, window, state_type);
2193 parent_class->draw_box (style, window, state_type, shadow_type, area,
2194 widget, detail, x, y, width, height);
2196 if (detail && strcmp (detail, "optionmenu") == 0)
2198 GtkRequisition indicator_size;
2199 GtkBorder indicator_spacing;
2202 option_menu_get_props (widget, &indicator_size,
2203 &indicator_spacing);
2205 sanitize_size (window, &width, &height);
2207 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
2209 x + indicator_size.width + indicator_spacing.left +
2210 indicator_spacing.right;
2213 x + width - (indicator_size.width +
2214 indicator_spacing.left +
2215 indicator_spacing.right) - style->xthickness;
2217 parent_class->draw_vline (style, window, state_type, area, widget,
2219 y + style->ythickness + 1,
2220 y + height - style->ythickness - 3,
2226 draw_tab (GtkStyle * style,
2229 GtkShadowType shadow,
2230 GdkRectangle * area,
2232 const gchar * detail, gint x, gint y, gint width, gint height)
2234 GtkRequisition indicator_size;
2235 GtkBorder indicator_spacing;
2239 g_return_if_fail (style != NULL);
2240 g_return_if_fail (window != NULL);
2242 if (detail && !strcmp (detail, "optionmenutab"))
2244 if (xp_theme_draw (window, XP_THEME_ELEMENT_COMBOBUTTON,
2245 style, x - 5, widget->allocation.y + 1,
2246 width + 10, widget->allocation.height - 2,
2254 gtk_widget_style_get (widget, "indicator_size", &indicator_size,
2257 option_menu_get_props (widget, &indicator_size, &indicator_spacing);
2259 x += (width - indicator_size.width) / 2;
2260 arrow_height = (indicator_size.width + 1) / 2;
2262 y += (height - arrow_height) / 2;
2264 draw_varrow (window, style->black_gc, shadow, area, GTK_ARROW_DOWN,
2265 x, y, indicator_size.width, arrow_height);
2268 /* Draw classic Windows tab - thanks Mozilla!
2269 (no system API for this, but DrawEdge can draw all the parts of a tab) */
2270 static void DrawTab(HDC hdc, const RECT R, gint32 aPosition, gboolean aSelected,
2271 gboolean aDrawLeft, gboolean aDrawRight)
2273 gint32 leftFlag, topFlag, rightFlag, lightFlag, shadeFlag;
2274 RECT topRect, sideRect, bottomRect, lightRect, shadeRect;
2275 gint32 selectedOffset, lOffset, rOffset;
2277 selectedOffset = aSelected ? 1 : 0;
2278 lOffset = aDrawLeft ? 2 : 0;
2279 rOffset = aDrawRight ? 2 : 0;
2281 /* Get info for tab orientation/position (Left, Top, Right, Bottom) */
2285 leftFlag = BF_TOP; topFlag = BF_LEFT;
2286 rightFlag = BF_BOTTOM;
2287 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2288 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2290 SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
2291 SetRect(&sideRect, R.left+2, R.top, R.right-2+selectedOffset, R.bottom);
2292 SetRect(&bottomRect, R.right-2, R.top, R.right, R.bottom);
2293 SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
2294 SetRect(&shadeRect, R.left+1, R.bottom-2, R.left+2, R.bottom-1);
2298 leftFlag = BF_LEFT; topFlag = BF_TOP;
2299 rightFlag = BF_RIGHT;
2300 lightFlag = BF_DIAGONAL_ENDTOPRIGHT;
2301 shadeFlag = BF_DIAGONAL_ENDBOTTOMRIGHT;
2303 SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
2304 SetRect(&sideRect, R.left, R.top+2, R.right, R.bottom-1+selectedOffset);
2305 SetRect(&bottomRect, R.left, R.bottom-1, R.right, R.bottom);
2306 SetRect(&lightRect, R.left, R.top, R.left+3, R.top+3);
2307 SetRect(&shadeRect, R.right-2, R.top+1, R.right-1, R.top+2);
2310 leftFlag = BF_TOP; topFlag = BF_RIGHT;
2311 rightFlag = BF_BOTTOM;
2312 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2313 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2315 SetRect(&topRect, R.left, R.top+lOffset, R.right, R.bottom-rOffset);
2316 SetRect(&sideRect, R.left+2-selectedOffset, R.top, R.right-2, R.bottom);
2317 SetRect(&bottomRect, R.left, R.top, R.left+2, R.bottom);
2318 SetRect(&lightRect, R.right-3, R.top, R.right-1, R.top+2);
2319 SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
2323 leftFlag = BF_LEFT; topFlag = BF_BOTTOM;
2324 rightFlag = BF_RIGHT;
2325 lightFlag = BF_DIAGONAL_ENDTOPLEFT;
2326 shadeFlag = BF_DIAGONAL_ENDBOTTOMLEFT;
2328 SetRect(&topRect, R.left+lOffset, R.top, R.right-rOffset, R.bottom);
2329 SetRect(&sideRect, R.left, R.top+2-selectedOffset, R.right, R.bottom-2);
2330 SetRect(&bottomRect, R.left, R.top, R.right, R.top+2);
2331 SetRect(&lightRect, R.left, R.bottom-3, R.left+2, R.bottom-1);
2332 SetRect(&shadeRect, R.right-2, R.bottom-3, R.right, R.bottom-1);
2336 g_return_if_reached();
2340 FillRect(hdc, &R, (HBRUSH) (COLOR_3DFACE+1) );
2343 DrawEdge(hdc, &topRect, EDGE_RAISED, BF_SOFT | topFlag);
2347 DrawEdge(hdc, &bottomRect, EDGE_RAISED, BF_SOFT | topFlag);
2354 DrawEdge(hdc, &sideRect, EDGE_RAISED, BF_SOFT | leftFlag | rightFlag);
2356 /* Tab Diagonal Corners */
2358 DrawEdge(hdc, &lightRect, EDGE_RAISED, BF_SOFT | lightFlag);
2361 DrawEdge(hdc, &shadeRect, EDGE_RAISED, BF_SOFT | shadeFlag);
2365 draw_themed_tab_button (GtkStyle *style,
2367 GtkStateType state_type,
2368 GtkNotebook *notebook,
2370 gint width, gint height,
2373 GdkPixmap *pixmap = NULL;
2374 gint border_width = gtk_container_get_border_width (GTK_CONTAINER (notebook));
2375 GtkWidget *widget = GTK_WIDGET (notebook);
2376 GdkRectangle draw_rect, clip_rect;
2377 GdkPixbufRotation rotation = GDK_PIXBUF_ROTATE_NONE;
2379 if (gap_side == GTK_POS_TOP)
2383 if (state_type == GTK_STATE_NORMAL)
2387 draw_rect.width = width + 2;
2388 draw_rect.height = height;
2390 clip_rect = draw_rect;
2395 draw_rect.x = x + 2;
2397 draw_rect.width = width - 2;
2398 draw_rect.height = height - 2;
2399 clip_rect = draw_rect;
2402 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2403 widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
2404 if (draw_rect.x + draw_rect.width >= widget_right)
2406 draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
2409 if (gap_side == GTK_POS_BOTTOM)
2413 if (state_type == GTK_STATE_NORMAL)
2417 draw_rect.width = width + 2;
2418 draw_rect.height = height;
2420 clip_rect = draw_rect;
2424 draw_rect.x = x + 2;
2425 draw_rect.y = y + 2;
2426 draw_rect.width = width - 2;
2427 draw_rect.height = height - 2;
2428 clip_rect = draw_rect;
2431 /* If we are currently drawing the right-most tab, and if that tab is the selected tab... */
2432 widget_right = widget->allocation.x + widget->allocation.width - border_width - 2;
2433 if (draw_rect.x + draw_rect.width >= widget_right)
2435 draw_rect.width = clip_rect.width = widget_right - draw_rect.x;
2438 rotation = GDK_PIXBUF_ROTATE_UPSIDEDOWN;
2440 else if (gap_side == GTK_POS_LEFT)
2444 if (state_type == GTK_STATE_NORMAL)
2448 draw_rect.width = width;
2449 draw_rect.height = height + 2;
2451 clip_rect = draw_rect;
2457 draw_rect.y = y + 2;
2458 draw_rect.width = width - 2;
2459 draw_rect.height = height - 2;
2460 clip_rect = draw_rect;
2463 /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
2464 widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
2465 if (draw_rect.y + draw_rect.height >= widget_bottom)
2467 draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
2470 rotation = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE;
2472 else if (gap_side == GTK_POS_RIGHT)
2476 if (state_type == GTK_STATE_NORMAL)
2478 draw_rect.x = x + 1;
2480 draw_rect.width = width;
2481 draw_rect.height = height + 2;
2483 clip_rect = draw_rect;
2488 draw_rect.x = x + 2;
2489 draw_rect.y = y + 2;
2490 draw_rect.width = width - 2;
2491 draw_rect.height = height - 2;
2492 clip_rect = draw_rect;
2495 /* If we are currently drawing the bottom-most tab, and if that tab is the selected tab... */
2496 widget_bottom = widget->allocation.x + widget->allocation.height - border_width - 2;
2497 if (draw_rect.y + draw_rect.height >= widget_bottom)
2499 draw_rect.height = clip_rect.height = widget_bottom - draw_rect.y;
2502 rotation = GDK_PIXBUF_ROTATE_CLOCKWISE;
2505 if (gap_side == GTK_POS_TOP)
2507 if (!xp_theme_draw (window, XP_THEME_ELEMENT_TAB_ITEM, style,
2508 draw_rect.x, draw_rect.y,
2509 draw_rect.width,draw_rect.height,
2510 state_type, &clip_rect))
2520 if (gap_side == GTK_POS_LEFT || gap_side == GTK_POS_RIGHT)
2522 pixmap = gdk_pixmap_new (window, clip_rect.height, clip_rect.width, -1);
2523 if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
2524 draw_rect.y - clip_rect.y, draw_rect.x - clip_rect.x,
2525 draw_rect.height, draw_rect.width, state_type, 0))
2527 g_object_unref (pixmap);
2531 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
2532 clip_rect.height, clip_rect.width);
2533 g_object_unref (pixmap);
2537 pixmap = gdk_pixmap_new (window, clip_rect.width, clip_rect.height, -1);
2538 if (!xp_theme_draw (pixmap, XP_THEME_ELEMENT_TAB_ITEM, style,
2539 draw_rect.x - clip_rect.x, draw_rect.y - clip_rect.y,
2540 draw_rect.width, draw_rect.height, state_type, 0))
2542 g_object_unref (pixmap);
2546 pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, NULL, 0, 0, 0, 0,
2547 clip_rect.width, clip_rect.height);
2548 g_object_unref (pixmap);
2551 rotated = gdk_pixbuf_rotate_simple (pixbuf, rotation);
2552 g_object_unref (pixbuf);
2555 // XXX - This is really hacky and evil. When we're drawing the left-most tab
2556 // while it is active on a bottom-oriented notebook, there is one white
2557 // pixel at the top. There may be a better solution than this if someone
2558 // has time to discover it.
2559 if (gap_side == GTK_POS_BOTTOM && state_type == GTK_STATE_NORMAL && x == widget->allocation.x)
2561 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
2562 int n_channels = gdk_pixbuf_get_n_channels (pixbuf);
2565 guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
2566 guchar *p = pixels + rowstride;
2568 for (psub = 0; psub < n_channels; psub++)
2570 pixels[psub] = p[psub];
2574 gdk_draw_pixbuf (window, NULL, pixbuf, 0, 0, clip_rect.x, clip_rect.y,
2575 clip_rect.width, clip_rect.height, GDK_RGB_DITHER_NONE, 0, 0);
2576 g_object_unref (pixbuf);
2583 draw_tab_button (GtkStyle *style,
2585 GtkStateType state_type,
2586 GtkShadowType shadow_type,
2589 const gchar *detail,
2591 gint width, gint height,
2594 if (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM)
2596 /* experimental tab-drawing code from mozilla */
2601 dc = get_window_dc (style, window, state_type, x, y, width, height, &rect);
2603 if (gap_side == GTK_POS_TOP)
2605 else if (gap_side == GTK_POS_BOTTOM)
2606 aPosition = BF_BOTTOM;
2607 else if (gap_side == GTK_POS_LEFT)
2608 aPosition = BF_LEFT;
2610 aPosition = BF_RIGHT;
2612 if(state_type == GTK_STATE_PRELIGHT)
2613 state_type = GTK_STATE_NORMAL;
2615 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2617 DrawTab (dc, rect, aPosition,
2618 state_type != GTK_STATE_PRELIGHT,
2619 (gap_side != GTK_POS_LEFT),
2620 (gap_side != GTK_POS_RIGHT));
2622 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2624 release_window_dc (style, window, state_type);
2632 draw_extension (GtkStyle *style,
2634 GtkStateType state_type,
2635 GtkShadowType shadow_type,
2638 const gchar *detail,
2640 gint width, gint height,
2641 GtkPositionType gap_side)
2643 if (widget && GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "tab"))
2645 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2647 /* Why this differs from gap_side, I have no idea.. */
2648 int real_gap_side = gtk_notebook_get_tab_pos (notebook);
2650 if (!draw_themed_tab_button (style, window, state_type,
2651 GTK_NOTEBOOK (widget), x, y,
2652 width, height, real_gap_side))
2654 if (!draw_tab_button (style, window, state_type,
2655 shadow_type, area, widget,
2657 x, y, width, height, real_gap_side))
2659 parent_class->draw_extension (style, window, state_type,
2660 shadow_type, area, widget, detail,
2661 x, y, width, height, real_gap_side);
2668 draw_box_gap (GtkStyle * style, GdkWindow * window, GtkStateType state_type,
2669 GtkShadowType shadow_type, GdkRectangle * area,
2670 GtkWidget * widget, const gchar * detail, gint x,
2671 gint y, gint width, gint height, GtkPositionType gap_side,
2672 gint gap_x, gint gap_width)
2674 if (GTK_IS_NOTEBOOK (widget) && detail && !strcmp (detail, "notebook"))
2676 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
2677 int side = gtk_notebook_get_tab_pos (notebook);
2678 int x2 = x, y2 = y, w2 = width, h2 = height;
2680 if (side == GTK_POS_TOP)
2683 y2 = y - notebook->tab_vborder;
2685 h2 = height + notebook->tab_vborder * 2;
2687 else if (side == GTK_POS_BOTTOM)
2692 h2 = height + notebook->tab_vborder * 2;
2694 else if (side == GTK_POS_LEFT)
2696 x2 = x - notebook->tab_hborder;
2698 w2 = width + notebook->tab_hborder;
2701 else if (side == GTK_POS_RIGHT)
2705 w2 = width + notebook->tab_hborder * 2;
2709 if (xp_theme_draw (window, XP_THEME_ELEMENT_TAB_PANE, style,
2710 x2, y2, w2, h2, state_type, area))
2716 parent_class->draw_box_gap (style, window, state_type, shadow_type,
2717 area, widget, detail, x, y, width, height,
2718 gap_side, gap_x, gap_width);
2721 static gboolean is_popup_window_child( GtkWidget* widget )
2724 GtkWindowType type = -1;
2726 top = gtk_widget_get_toplevel( widget );
2727 if( top && GTK_IS_WINDOW(top) ) {
2728 g_object_get(top, "type", &type, NULL );
2729 if( type == GTK_WINDOW_POPUP ) { /* Hack for combo boxes */
2737 draw_flat_box (GtkStyle * style, GdkWindow * window,
2738 GtkStateType state_type, GtkShadowType shadow_type,
2739 GdkRectangle * area, GtkWidget * widget,
2740 const gchar * detail, gint x, gint y, gint width, gint height)
2743 if ( !strcmp (detail, "checkbutton") )
2745 if (state_type == GTK_STATE_PRELIGHT)
2752 parent_class->draw_flat_box (style, window, state_type, shadow_type,
2753 area, widget, detail, x, y, width, height);
2757 draw_menu_border ( GdkWindow* win, GtkStyle* style,
2758 gint x, gint y, gint width, gint height )
2763 dc = get_window_dc (style, win, GTK_STATE_NORMAL, x, y, width, height, &rect );
2766 if( xp_theme_is_active() ) {
2767 FrameRect( dc, &rect, GetSysColorBrush(COLOR_3DSHADOW) );
2770 DrawEdge( dc, &rect, EDGE_RAISED, BF_RECT );
2772 release_window_dc( style, win, GTK_STATE_NORMAL );
2777 draw_shadow (GtkStyle * style,
2779 GtkStateType state_type,
2780 GtkShadowType shadow_type,
2781 GdkRectangle * area,
2783 const gchar * detail, gint x, gint y, gint width, gint height)
2785 gboolean is_handlebox;
2786 gboolean is_toolbar;
2788 if( detail && !strcmp( detail, "frame") )
2792 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2793 if( is_popup_window_child(widget) ) {
2794 FrameRect( dc, &rect, GetSysColorBrush( COLOR_WINDOWFRAME ) );
2797 switch( shadow_type ){
2799 draw_3d_border(dc, &rect, TRUE);
2801 case GTK_SHADOW_OUT:
2802 draw_3d_border(dc, &rect, FALSE);
2804 case GTK_SHADOW_ETCHED_IN:
2805 draw_3d_border(dc, &rect, TRUE);
2806 InflateRect( &rect, -1, -1 );
2807 draw_3d_border(dc, &rect, FALSE);
2809 case GTK_SHADOW_ETCHED_OUT:
2810 draw_3d_border(dc, &rect, FALSE);
2811 InflateRect( &rect, -1, -1 );
2812 draw_3d_border(dc, &rect, TRUE);
2814 case GTK_SHADOW_NONE:
2818 release_window_dc( style, window, state_type );
2821 if (detail && (!strcmp (detail, "entry") || !strcmp (detail, "combobox")) )
2823 if( shadow_type != GTK_SHADOW_IN )
2826 if ( !xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2827 x, y, width, height, state_type, area))
2832 dc = get_window_dc (style, window, state_type,
2833 x, y, width, height, &rect);
2834 DrawEdge (dc, &rect, EDGE_SUNKEN, BF_RECT);
2835 release_window_dc (style, window, state_type);
2841 if (detail && !strcmp (detail, "scrolled_window") &&
2842 xp_theme_draw (window, XP_THEME_ELEMENT_EDIT_TEXT, style,
2843 x, y, width, height, state_type, area))
2846 if (detail && !strcmp (detail, "spinbutton"))
2849 if (detail && !strcmp (detail, "menu"))
2851 if ( draw_menu_border ( window, style, x, y, width, height ) ) {
2856 if (detail && !strcmp (detail, "handlebox"))
2859 is_handlebox = (detail && !strcmp (detail, "handlebox_bin"));
2860 is_toolbar = (detail && (!strcmp (detail, "toolbar") || !strcmp(detail, "menubar")));
2862 if ( is_toolbar || is_handlebox )
2864 if( shadow_type == GTK_SHADOW_NONE )
2870 HGDIOBJ old_pen = NULL;
2871 GtkPositionType pos;
2873 sanitize_size (window, &width, &height);
2875 if( is_handlebox ) {
2876 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
2878 If the handle box is at left side,
2879 we shouldn't draw its right border.
2880 The same holds true for top, right, and bottom.
2884 pos = GTK_POS_RIGHT; break;
2886 pos = GTK_POS_LEFT; break;
2888 pos = GTK_POS_BOTTOM; break;
2889 case GTK_POS_BOTTOM:
2890 pos = GTK_POS_TOP; break;
2894 GtkWidget* parent = gtk_widget_get_parent(widget);
2895 /* Dirty hack for toolbars contained in handle boxes */
2896 if( GTK_IS_HANDLE_BOX( parent ) ) {
2897 pos = gtk_handle_box_get_handle_position( GTK_HANDLE_BOX( parent ) );
2902 Make pos != all legal enum vaules of GtkPositionType.
2903 So every border will be draw.
2905 pos = (GtkPositionType)-1;
2909 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
2910 if( pos != GTK_POS_LEFT ) {
2911 old_pen = SelectObject( dc, get_light_pen() );
2912 MoveToEx( dc, rect.left, rect.top, NULL );
2913 LineTo( dc, rect.left, rect.bottom );
2915 if( pos != GTK_POS_TOP ) {
2916 old_pen = SelectObject( dc, get_light_pen() );
2917 MoveToEx( dc, rect.left, rect.top, NULL );
2918 LineTo( dc, rect.right, rect.top );
2920 if( pos != GTK_POS_RIGHT ) {
2921 old_pen = SelectObject( dc, get_dark_pen() );
2922 MoveToEx( dc, rect.right-1, rect.top, NULL );
2923 LineTo( dc, rect.right-1, rect.bottom );
2925 if( pos != GTK_POS_BOTTOM ) {
2926 old_pen = SelectObject( dc, get_dark_pen() );
2927 MoveToEx( dc, rect.left, rect.bottom-1, NULL );
2928 LineTo( dc, rect.right, rect.bottom-1 );
2931 SelectObject( dc, old_pen );
2932 release_window_dc( style, window, state_type );
2937 if (detail && !strcmp (detail, "statusbar")) {
2941 parent_class->draw_shadow (style, window, state_type, shadow_type, area,
2942 widget, detail, x, y, width, height);
2946 draw_hline (GtkStyle * style,
2948 GtkStateType state_type,
2949 GdkRectangle * area,
2951 const gchar * detail, gint x1, gint x2, gint y)
2953 if (xp_theme_is_active () && detail && !strcmp(detail, "menuitem")) {
2954 if(xp_theme_draw (window, XP_THEME_ELEMENT_MENU_SEPARATOR, style, x1, y, x2, 1, state_type, area))
2958 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2960 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2963 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2966 if( style->ythickness == 2 )
2970 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
2971 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
2973 gdk_draw_line (window, style->dark_gc[state_type], x1, y, x2, y);
2975 gdk_draw_line (window, style->light_gc[state_type], x1, y, x2, y);
2978 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
2979 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
2984 parent_class->draw_hline (style, window, state_type, area, widget,
2991 draw_vline (GtkStyle * style,
2993 GtkStateType state_type,
2994 GdkRectangle * area,
2996 const gchar * detail, gint y1, gint y2, gint x)
2998 if( style->xthickness == 2 )
3002 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3003 gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
3005 gdk_draw_line (window, style->dark_gc[state_type], x, y1, x, y2);
3007 gdk_draw_line (window, style->light_gc[state_type], x, y1, x, y2);
3010 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3011 gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL);
3016 parent_class->draw_vline (style, window, state_type, area, widget,
3022 draw_slider (GtkStyle * style,
3024 GtkStateType state_type,
3025 GtkShadowType shadow_type,
3026 GdkRectangle * area,
3028 const gchar * detail,
3030 gint y, gint width, gint height, GtkOrientation orientation)
3032 if (GTK_IS_SCALE (widget) &&
3033 xp_theme_draw (window,
3035 GTK_ORIENTATION_VERTICAL) ?
3036 XP_THEME_ELEMENT_SCALE_SLIDER_V :
3037 XP_THEME_ELEMENT_SCALE_SLIDER_H), style, x, y, width,
3038 height, state_type, area))
3043 parent_class->draw_slider (style, window, state_type, shadow_type, area,
3044 widget, detail, x, y, width, height,
3049 draw_resize_grip (GtkStyle * style,
3051 GtkStateType state_type,
3052 GdkRectangle * area,
3054 const gchar * detail,
3055 GdkWindowEdge edge, gint x, gint y, gint width, gint height)
3057 if (detail && !strcmp (detail, "statusbar"))
3060 (window, XP_THEME_ELEMENT_STATUS_GRIPPER, style, x, y, width,
3061 height, state_type, area))
3065 HDC dc = get_window_dc(style, window, state_type, x, y, width, height, &rect);
3068 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area);
3069 DrawFrameControl(dc, &rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
3070 release_window_dc(style, window, state_type);
3072 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
3077 parent_class->draw_resize_grip (style, window, state_type, area,
3078 widget, detail, edge, x, y, width,
3083 draw_handle (GtkStyle * style,
3085 GtkStateType state_type,
3086 GtkShadowType shadow_type,
3087 GdkRectangle * area,
3089 const gchar * detail,
3091 gint y, gint width, gint height, GtkOrientation orientation)
3096 if (is_toolbar_child (widget))
3098 XpThemeElement hndl;
3100 sanitize_size (window, &width, &height);
3102 if( GTK_IS_HANDLE_BOX(widget) ) {
3103 GtkPositionType pos;
3104 pos = gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget));
3105 if( pos == GTK_POS_TOP || pos == GTK_POS_BOTTOM ) {
3106 orientation = GTK_ORIENTATION_HORIZONTAL;
3109 orientation = GTK_ORIENTATION_VERTICAL;
3113 if ( orientation == GTK_ORIENTATION_VERTICAL )
3114 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_V;
3116 hndl = XP_THEME_ELEMENT_REBAR_GRIPPER_H;
3118 if (xp_theme_draw (window, hndl, style, x, y, width, height,
3124 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
3125 if ( orientation == GTK_ORIENTATION_VERTICAL ) {
3127 rect.right = rect.left + 3;
3133 rect.bottom = rect.top + 3;
3137 draw_3d_border( dc, &rect, FALSE );
3138 release_window_dc( style, window, state_type );
3142 if (!GTK_IS_PANED (widget))
3144 gint xthick, ythick;
3145 GdkGC *light_gc, *dark_gc, *shadow_gc;
3148 sanitize_size (window, &width, &height);
3150 gtk_paint_box (style, window, state_type, shadow_type, area,
3151 widget, detail, x, y, width, height);
3153 light_gc = style->light_gc[state_type];
3154 dark_gc = style->dark_gc[state_type];
3155 shadow_gc = style->mid_gc[state_type];
3157 xthick = style->xthickness;
3158 ythick = style->ythickness;
3160 dest.x = x + xthick;
3161 dest.y = y + ythick;
3162 dest.width = width - (xthick * 2);
3163 dest.height = height - (ythick * 2);
3165 if (dest.width < dest.height)
3170 gdk_gc_set_clip_rectangle (light_gc, &dest);
3171 gdk_gc_set_clip_rectangle (dark_gc, &dest);
3172 gdk_gc_set_clip_rectangle (shadow_gc, &dest);
3174 if (dest.width < dest.height)
3176 gdk_draw_line (window, light_gc, dest.x, dest.y, dest.x,
3178 gdk_draw_line (window, dark_gc, dest.x + (dest.width / 2),
3179 dest.y, dest.x + (dest.width / 2),
3181 gdk_draw_line (window, shadow_gc, dest.x + dest.width,
3182 dest.y, dest.x + dest.width, dest.height);
3186 gdk_draw_line (window, light_gc, dest.x, dest.y,
3187 dest.x + dest.width, dest.y);
3188 gdk_draw_line (window, dark_gc, dest.x,
3189 dest.y + (dest.height / 2),
3190 dest.x + dest.width,
3191 dest.y + (dest.height / 2));
3192 gdk_draw_line (window, shadow_gc, dest.x,
3193 dest.y + dest.height, dest.x + dest.width,
3194 dest.y + dest.height);
3197 gdk_gc_set_clip_rectangle (shadow_gc, NULL);
3198 gdk_gc_set_clip_rectangle (light_gc, NULL);
3199 gdk_gc_set_clip_rectangle (dark_gc, NULL);
3204 draw_focus ( GtkStyle *style,
3206 GtkStateType state_type,
3209 const gchar *detail,
3217 if( !GTK_WIDGET_CAN_FOCUS(widget) ) {
3220 if( detail && 0 == strcmp(detail, "button")
3221 && GTK_RELIEF_NONE == gtk_button_get_relief( GTK_BUTTON(widget) ) )
3225 if ( is_combo_box_child(widget)
3226 && (GTK_IS_ARROW(widget) || GTK_IS_BUTTON(widget)) ) {
3229 if (GTK_IS_TREE_VIEW (widget->parent) /* list view bheader */
3230 || GTK_IS_CLIST (widget->parent)) {
3234 dc = get_window_dc( style, window, state_type, x, y, width, height, &rect );
3235 DrawFocusRect(dc, &rect);
3236 release_window_dc( style, window, state_type );
3238 parent_class->draw_focus (style, window, state_type,
3239 area, widget, detail, x, y, width, height);
3244 msw_style_init_from_rc (GtkStyle * style, GtkRcStyle * rc_style)
3246 setup_system_font (style);
3247 setup_menu_settings (gtk_settings_get_default ());
3248 setup_system_styles (style);
3249 parent_class->init_from_rc (style, rc_style);
3253 load_bg_image (GdkColormap *colormap,
3255 const gchar *filename)
3257 if (strcmp (filename, "<parent>") == 0)
3258 return (GdkPixmap*) GDK_PARENT_RELATIVE;
3261 return gdk_pixmap_colormap_create_from_xpm (NULL, colormap, NULL,
3268 msw_style_realize (GtkStyle * style)
3270 GdkGCValues gc_values;
3271 GdkGCValuesMask gc_values_mask;
3275 for (i = 0; i < 5; i++)
3277 style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
3278 style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
3279 style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
3281 style->text_aa[i].red = (style->text[i].red + style->base[i].red) / 2;
3282 style->text_aa[i].green = (style->text[i].green + style->base[i].green) / 2;
3283 style->text_aa[i].blue = (style->text[i].blue + style->base[i].blue) / 2;
3286 style->black.red = 0x0000;
3287 style->black.green = 0x0000;
3288 style->black.blue = 0x0000;
3289 gdk_colormap_alloc_color (style->colormap, &style->black, FALSE, TRUE);
3291 style->white.red = 0xffff;
3292 style->white.green = 0xffff;
3293 style->white.blue = 0xffff;
3294 gdk_colormap_alloc_color (style->colormap, &style->white, FALSE, TRUE);
3296 gc_values_mask = GDK_GC_FOREGROUND | GDK_GC_BACKGROUND;
3298 gc_values.foreground = style->black;
3299 gc_values.background = style->white;
3300 style->black_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3302 gc_values.foreground = style->white;
3303 gc_values.background = style->black;
3304 style->white_gc = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3306 gc_values_mask = GDK_GC_FOREGROUND;
3308 for (i = 0; i < 5; i++)
3310 if (style->rc_style && style->rc_style->bg_pixmap_name[i])
3311 style->bg_pixmap[i] = load_bg_image (style->colormap,
3313 style->rc_style->bg_pixmap_name[i]);
3315 if (!gdk_colormap_alloc_color (style->colormap, &style->fg[i], FALSE, TRUE))
3316 g_warning ("unable to allocate color: ( %d %d %d )",
3317 style->fg[i].red, style->fg[i].green, style->fg[i].blue);
3318 if (!gdk_colormap_alloc_color (style->colormap, &style->bg[i], FALSE, TRUE))
3319 g_warning ("unable to allocate color: ( %d %d %d )",
3320 style->bg[i].red, style->bg[i].green, style->bg[i].blue);
3321 if (!gdk_colormap_alloc_color (style->colormap, &style->light[i], FALSE, TRUE))
3322 g_warning ("unable to allocate color: ( %d %d %d )",
3323 style->light[i].red, style->light[i].green, style->light[i].blue);
3324 if (!gdk_colormap_alloc_color (style->colormap, &style->dark[i], FALSE, TRUE))
3325 g_warning ("unable to allocate color: ( %d %d %d )",
3326 style->dark[i].red, style->dark[i].green, style->dark[i].blue);
3327 if (!gdk_colormap_alloc_color (style->colormap, &style->mid[i], FALSE, TRUE))
3328 g_warning ("unable to allocate color: ( %d %d %d )",
3329 style->mid[i].red, style->mid[i].green, style->mid[i].blue);
3330 if (!gdk_colormap_alloc_color (style->colormap, &style->text[i], FALSE, TRUE))
3331 g_warning ("unable to allocate color: ( %d %d %d )",
3332 style->text[i].red, style->text[i].green, style->text[i].blue);
3333 if (!gdk_colormap_alloc_color (style->colormap, &style->base[i], FALSE, TRUE))
3334 g_warning ("unable to allocate color: ( %d %d %d )",
3335 style->base[i].red, style->base[i].green, style->base[i].blue);
3336 if (!gdk_colormap_alloc_color (style->colormap, &style->text_aa[i], FALSE, TRUE))
3337 g_warning ("unable to allocate color: ( %d %d %d )",
3338 style->text_aa[i].red, style->text_aa[i].green, style->text_aa[i].blue);
3340 gc_values.foreground = style->fg[i];
3341 style->fg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3343 gc_values.foreground = style->bg[i];
3344 style->bg_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3346 gc_values.foreground = style->light[i];
3347 style->light_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3349 gc_values.foreground = style->dark[i];
3350 style->dark_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3352 gc_values.foreground = style->mid[i];
3353 style->mid_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3355 gc_values.foreground = style->text[i];
3356 style->text_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3358 gc_values.foreground = style->base[i];
3359 style->base_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3361 gc_values.foreground = style->text_aa[i];
3362 style->text_aa_gc[i] = gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask);
3367 msw_style_unrealize (GtkStyle * style)
3369 parent_class->unrealize (style);
3373 msw_style_class_init (MswStyleClass * klass)
3375 GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
3377 parent_class = g_type_class_peek_parent (klass);
3379 style_class->init_from_rc = msw_style_init_from_rc;
3380 style_class->draw_arrow = draw_arrow;
3381 style_class->draw_box = draw_box;
3382 style_class->draw_check = draw_check;
3383 style_class->draw_option = draw_option;
3384 style_class->draw_tab = draw_tab;
3385 style_class->draw_flat_box = draw_flat_box;
3386 style_class->draw_expander = draw_expander;
3387 style_class->draw_extension = draw_extension;
3388 style_class->draw_box_gap = draw_box_gap;
3389 style_class->draw_shadow = draw_shadow;
3390 style_class->draw_hline = draw_hline;
3391 style_class->draw_vline = draw_vline;
3392 style_class->draw_handle = draw_handle;
3393 style_class->draw_resize_grip = draw_resize_grip;
3394 style_class->draw_slider = draw_slider;
3395 style_class->draw_focus = draw_focus;
3397 style_class->realize = msw_style_realize;
3398 style_class->unrealize = msw_style_unrealize;
3401 GType msw_type_style = 0;
3404 msw_style_register_type (GTypeModule * module)
3406 static const GTypeInfo object_info = {
3407 sizeof (MswStyleClass),
3408 (GBaseInitFunc) NULL,
3409 (GBaseFinalizeFunc) NULL,
3410 (GClassInitFunc) msw_style_class_init,
3411 NULL, /* class_finalize */
3412 NULL, /* class_data */
3414 0, /* n_preallocs */
3415 (GInstanceInitFunc) NULL,
3418 msw_type_style = g_type_module_register_type (module,
3425 msw_style_init (void)
3428 msw_style_setup_system_settings ();
3429 setup_msw_rc_style ();
3432 DeleteObject( g_light_pen );
3436 DeleteObject( g_dark_pen );
3441 void msw_style_finalize(void)
3443 if( g_dither_brush ){
3444 DeleteObject( g_dither_brush );
3447 DeleteObject( g_light_pen );
3450 DeleteObject( g_dark_pen );