1
/* MS-Windows Engine (aka GTK-Wimp)
3
* Copyright (C) 2003, 2004 Raymond Penners <raymond@dotsphinx.com>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Library General Public
7
* License as published by the Free Software Foundation; either
8
* version 2 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Library General Public License for more details.
15
* You should have received a copy of the GNU Library General Public
16
* License along with this library; if not, write to the
17
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
* Boston, MA 02111-1307, USA.
21
#define _WIN32_WINNT 0x0501
34
/* #include "gdk/gdkwin32.h" */
35
#include "gdk/win32/gdkwin32.h"
37
#include "xp_theme_defs.h"
39
#ifndef TMT_CAPTIONFONT
41
/* These aren't in mingw's "w32api" headers, nor in the Platform SDK
44
#define TMT_CAPTIONFONT 801
45
#define TMT_MENUFONT 803
46
#define TMT_STATUSFONT 804
47
#define TMT_MSGBOXFONT 805
52
#define TP_SEPARATOR 5
53
#define TP_SEPARATORVERT 6
55
/* GLOBALS LINEHORZ states */
60
/* GLOBAL LINEVERT states */
67
#define TKP_TRACKVERT 2
69
#define TKP_THUMBBOTTOM 4
70
#define TKP_THUMBTOP 5
71
#define TKP_THUMBVERT 6
72
#define TKP_THUMBLEFT 7
73
#define TKP_THUMBRIGHT 8
75
#define TKP_TICSVERT 10
79
static const LPCWSTR class_descriptors[] = {
80
L"Scrollbar", /* XP_THEME_CLASS_SCROLLBAR */
81
L"Button", /* XP_THEME_CLASS_BUTTON */
82
L"Header", /* XP_THEME_CLASS_HEADER */
83
L"ComboBox", /* XP_THEME_CLASS_COMBOBOX */
84
L"Tab", /* XP_THEME_CLASS_TAB */
85
L"Edit", /* XP_THEME_CLASS_EDIT */
86
L"TreeView", /* XP_THEME_CLASS_TREEVIEW */
87
L"Spin", /* XP_THEME_CLASS_SPIN */
88
L"Progress", /* XP_THEME_CLASS_PROGRESS */
89
L"Tooltip", /* XP_THEME_CLASS_TOOLTIP */
90
L"Rebar", /* XP_THEME_CLASS_REBAR */
91
L"Toolbar", /* XP_THEME_CLASS_TOOLBAR */
92
L"Globals", /* XP_THEME_CLASS_GLOBALS */
93
L"Menu", /* XP_THEME_CLASS_MENU */
94
L"Window", /* XP_THEME_CLASS_WINDOW */
95
L"Status", /* XP_THEME_CLASS_STATUS */
96
L"Trackbar" /* XP_THEME_CLASS_TRACKBAR */
99
static const short element_part_map[] = {
107
TABP_TABITEMLEFTEDGE,
108
TABP_TABITEMRIGHTEDGE,
154
static HINSTANCE uxtheme_dll = NULL;
155
static HTHEME open_themes[XP_THEME_CLASS__SIZEOF];
156
static gboolean use_xp_theme = FALSE;
158
typedef HRESULT (FAR PASCAL * GetThemeSysFontFunc)
159
(HTHEME hTheme, int iFontID, OUT LOGFONT * plf);
160
typedef int (FAR PASCAL * GetThemeSysSizeFunc) (HTHEME hTheme, int iSizeId);
161
typedef COLORREF (FAR PASCAL * GetThemeSysColorFunc) (HTHEME hTheme,
163
typedef HTHEME (FAR PASCAL * OpenThemeDataFunc) (HWND hwnd,
164
LPCWSTR pszClassList);
165
typedef HRESULT (FAR PASCAL * CloseThemeDataFunc) (HTHEME theme);
166
typedef HRESULT (FAR PASCAL * DrawThemeBackgroundFunc)
167
(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
168
const RECT * pRect, const RECT * pClipRect);
169
typedef HRESULT (FAR PASCAL * EnableThemeDialogTextureFunc) (HWND hwnd,
171
typedef BOOL (FAR PASCAL * IsThemeActiveFunc) (VOID);
172
typedef BOOL (FAR PASCAL * IsAppThemedFunc) (VOID);
173
typedef BOOL (FAR PASCAL *
174
IsThemeBackgroundPartiallyTransparentFunc) (HTHEME hTheme,
177
typedef HRESULT (FAR PASCAL * DrawThemeParentBackgroundFunc) (HWND hwnd,
181
static GetThemeSysFontFunc get_theme_sys_font_func = NULL;
182
static GetThemeSysColorFunc get_theme_sys_color_func = NULL;
183
static GetThemeSysSizeFunc get_theme_sys_metric_func = NULL;
184
static OpenThemeDataFunc open_theme_data_func = NULL;
185
static CloseThemeDataFunc close_theme_data_func = NULL;
186
static DrawThemeBackgroundFunc draw_theme_background_func = NULL;
187
static EnableThemeDialogTextureFunc enable_theme_dialog_texture_func = NULL;
188
static IsThemeActiveFunc is_theme_active_func = NULL;
189
static IsAppThemedFunc is_app_themed_func = NULL;
190
static IsThemeBackgroundPartiallyTransparentFunc
191
is_theme_partially_transparent_func = NULL;
192
static DrawThemeParentBackgroundFunc draw_theme_parent_background_func = NULL;
195
xp_theme_close_open_handles (void)
199
for (i = 0; i < XP_THEME_CLASS__SIZEOF; i++)
203
close_theme_data_func (open_themes[i]);
204
open_themes[i] = NULL;
215
memset (open_themes, 0, sizeof (open_themes));
217
uxtheme_dll = LoadLibrary ("uxtheme.dll");
222
(IsAppThemedFunc) GetProcAddress (uxtheme_dll, "IsAppThemed");
224
if (is_app_themed_func)
226
is_theme_active_func =
227
(IsThemeActiveFunc) GetProcAddress (uxtheme_dll,
229
open_theme_data_func =
230
(OpenThemeDataFunc) GetProcAddress (uxtheme_dll,
232
close_theme_data_func =
233
(CloseThemeDataFunc) GetProcAddress (uxtheme_dll,
235
draw_theme_background_func =
236
(DrawThemeBackgroundFunc) GetProcAddress (uxtheme_dll,
237
"DrawThemeBackground");
238
enable_theme_dialog_texture_func =
239
(EnableThemeDialogTextureFunc) GetProcAddress (uxtheme_dll,
240
"EnableThemeDialogTexture");
241
get_theme_sys_font_func =
242
(GetThemeSysFontFunc) GetProcAddress (uxtheme_dll,
244
get_theme_sys_color_func =
245
(GetThemeSysColorFunc) GetProcAddress (uxtheme_dll,
247
get_theme_sys_metric_func =
248
(GetThemeSysSizeFunc) GetProcAddress (uxtheme_dll,
250
is_theme_partially_transparent_func =
251
(IsThemeBackgroundPartiallyTransparentFunc)
252
GetProcAddress (uxtheme_dll,
253
"IsThemeBackgroundPartiallyTransparent");
254
draw_theme_parent_background_func =
255
(DrawThemeParentBackgroundFunc) GetProcAddress (uxtheme_dll,
256
"DrawThemeParentBackground");
259
if (is_app_themed_func && is_theme_active_func) {
260
use_xp_theme = (is_app_themed_func () && is_theme_active_func ());
263
use_xp_theme = FALSE;
268
xp_theme_reset (void)
270
xp_theme_close_open_handles ();
272
if (is_app_themed_func && is_theme_active_func) {
273
use_xp_theme = (is_app_themed_func () && is_theme_active_func ());
276
use_xp_theme = FALSE;
286
xp_theme_close_open_handles ();
288
FreeLibrary (uxtheme_dll);
290
use_xp_theme = FALSE;
292
is_app_themed_func = NULL;
293
is_theme_active_func = NULL;
294
open_theme_data_func = NULL;
295
close_theme_data_func = NULL;
296
draw_theme_background_func = NULL;
297
enable_theme_dialog_texture_func = NULL;
298
get_theme_sys_font_func = NULL;
299
get_theme_sys_color_func = NULL;
300
get_theme_sys_metric_func = NULL;
301
is_theme_partially_transparent_func = NULL;
302
draw_theme_parent_background_func = NULL;
306
xp_theme_get_handle_by_class (XpThemeClass klazz)
308
if (!open_themes[klazz] && open_theme_data_func)
311
open_theme_data_func (NULL, class_descriptors[klazz]);
313
return open_themes[klazz];
317
xp_theme_get_handle_by_element (XpThemeElement element)
320
XpThemeClass klazz = XP_THEME_CLASS__SIZEOF;
324
case XP_THEME_ELEMENT_TOOLTIP:
325
klazz = XP_THEME_CLASS_TOOLTIP;
328
case XP_THEME_ELEMENT_REBAR:
329
case XP_THEME_ELEMENT_REBAR_GRIPPER_H:
330
case XP_THEME_ELEMENT_REBAR_GRIPPER_V:
331
case XP_THEME_ELEMENT_REBAR_CHEVRON:
332
klazz = XP_THEME_CLASS_REBAR;
335
case XP_THEME_ELEMENT_SCALE_TROUGH_H:
336
case XP_THEME_ELEMENT_SCALE_TROUGH_V:
337
case XP_THEME_ELEMENT_SCALE_SLIDER_H:
338
case XP_THEME_ELEMENT_SCALE_SLIDER_V:
339
case XP_THEME_ELEMENT_SCALE_TICS_H:
340
case XP_THEME_ELEMENT_SCALE_TICS_V:
341
klazz = XP_THEME_CLASS_TRACKBAR;
344
case XP_THEME_ELEMENT_STATUS_GRIPPER:
345
case XP_THEME_ELEMENT_STATUS_PANE:
346
klazz = XP_THEME_CLASS_STATUS;
349
case XP_THEME_ELEMENT_TOOLBAR_BUTTON:
350
case XP_THEME_ELEMENT_TOOLBAR_SEPARATOR_H:
351
case XP_THEME_ELEMENT_TOOLBAR_SEPARATOR_V:
352
klazz = XP_THEME_CLASS_TOOLBAR;
355
case XP_THEME_ELEMENT_MENU_ITEM:
356
case XP_THEME_ELEMENT_MENU_SEPARATOR:
357
klazz = XP_THEME_CLASS_MENU;
360
case XP_THEME_ELEMENT_PRESSED_CHECKBOX:
361
case XP_THEME_ELEMENT_CHECKBOX:
362
case XP_THEME_ELEMENT_BUTTON:
363
case XP_THEME_ELEMENT_DEFAULT_BUTTON:
364
case XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON:
365
case XP_THEME_ELEMENT_RADIO_BUTTON:
366
klazz = XP_THEME_CLASS_BUTTON;
369
case XP_THEME_ELEMENT_LIST_HEADER:
370
klazz = XP_THEME_CLASS_HEADER;
373
case XP_THEME_ELEMENT_COMBOBUTTON:
374
klazz = XP_THEME_CLASS_COMBOBOX;
377
case XP_THEME_ELEMENT_BODY:
378
case XP_THEME_ELEMENT_TAB_ITEM:
379
case XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE:
380
case XP_THEME_ELEMENT_TAB_ITEM_RIGHT_EDGE:
381
case XP_THEME_ELEMENT_TAB_PANE:
382
klazz = XP_THEME_CLASS_TAB;
385
case XP_THEME_ELEMENT_SCROLLBAR_V:
386
case XP_THEME_ELEMENT_SCROLLBAR_H:
387
case XP_THEME_ELEMENT_ARROW_UP:
388
case XP_THEME_ELEMENT_ARROW_DOWN:
389
case XP_THEME_ELEMENT_ARROW_LEFT:
390
case XP_THEME_ELEMENT_ARROW_RIGHT:
391
case XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V:
392
case XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H:
393
case XP_THEME_ELEMENT_TROUGH_V:
394
case XP_THEME_ELEMENT_TROUGH_H:
395
klazz = XP_THEME_CLASS_SCROLLBAR;
398
case XP_THEME_ELEMENT_EDIT_TEXT:
399
klazz = XP_THEME_CLASS_EDIT;
402
case XP_THEME_ELEMENT_SPIN_BUTTON_UP:
403
case XP_THEME_ELEMENT_SPIN_BUTTON_DOWN:
404
klazz = XP_THEME_CLASS_SPIN;
407
case XP_THEME_ELEMENT_PROGRESS_BAR_H:
408
case XP_THEME_ELEMENT_PROGRESS_BAR_V:
409
case XP_THEME_ELEMENT_PROGRESS_TROUGH_H:
410
case XP_THEME_ELEMENT_PROGRESS_TROUGH_V:
411
klazz = XP_THEME_CLASS_PROGRESS;
414
case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED:
415
case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED:
416
klazz = XP_THEME_CLASS_TREEVIEW;
419
case XP_THEME_ELEMENT_LINE_H:
420
case XP_THEME_ELEMENT_LINE_V:
421
klazz = XP_THEME_CLASS_GLOBALS;
428
if (klazz != XP_THEME_CLASS__SIZEOF)
430
ret = xp_theme_get_handle_by_class (klazz);
436
xp_theme_map_gtk_state (XpThemeElement element, GtkStateType state)
442
case XP_THEME_ELEMENT_TOOLTIP:
446
case XP_THEME_ELEMENT_REBAR:
450
case XP_THEME_ELEMENT_REBAR_GRIPPER_H:
451
case XP_THEME_ELEMENT_REBAR_GRIPPER_V:
455
case XP_THEME_ELEMENT_STATUS_GRIPPER:
456
case XP_THEME_ELEMENT_STATUS_PANE:
460
case XP_THEME_ELEMENT_REBAR_CHEVRON:
463
case GTK_STATE_PRELIGHT:
466
case GTK_STATE_SELECTED:
467
case GTK_STATE_ACTIVE:
475
case XP_THEME_ELEMENT_TOOLBAR_SEPARATOR_H:
476
case XP_THEME_ELEMENT_TOOLBAR_SEPARATOR_V:
480
case XP_THEME_ELEMENT_TOOLBAR_BUTTON:
483
case GTK_STATE_ACTIVE:
486
case GTK_STATE_PRELIGHT:
489
case GTK_STATE_INSENSITIVE:
497
case XP_THEME_ELEMENT_TAB_PANE:
501
case XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE:
502
case XP_THEME_ELEMENT_TAB_ITEM_RIGHT_EDGE:
503
case XP_THEME_ELEMENT_TAB_ITEM:
506
case GTK_STATE_PRELIGHT:
509
case GTK_STATE_INSENSITIVE:
512
case GTK_STATE_SELECTED:
513
case GTK_STATE_ACTIVE:
521
case XP_THEME_ELEMENT_EDIT_TEXT:
524
case GTK_STATE_PRELIGHT:
527
case GTK_STATE_INSENSITIVE:
530
case GTK_STATE_SELECTED:
531
case GTK_STATE_ACTIVE:
537
case XP_THEME_ELEMENT_TROUGH_H:
538
case XP_THEME_ELEMENT_TROUGH_V:
542
case XP_THEME_ELEMENT_SCROLLBAR_H:
543
case XP_THEME_ELEMENT_SCROLLBAR_V:
546
case GTK_STATE_SELECTED:
547
case GTK_STATE_ACTIVE:
550
case GTK_STATE_PRELIGHT:
553
case GTK_STATE_INSENSITIVE:
554
ret = SCRBS_DISABLED;
561
case XP_THEME_ELEMENT_ARROW_DOWN:
564
case GTK_STATE_ACTIVE:
565
ret = ABS_DOWNPRESSED;
567
case GTK_STATE_PRELIGHT:
570
case GTK_STATE_INSENSITIVE:
571
ret = ABS_DOWNDISABLED;
574
ret = ABS_DOWNNORMAL;
578
case XP_THEME_ELEMENT_ARROW_UP:
581
case GTK_STATE_ACTIVE:
584
case GTK_STATE_PRELIGHT:
587
case GTK_STATE_INSENSITIVE:
588
ret = ABS_UPDISABLED;
595
case XP_THEME_ELEMENT_ARROW_LEFT:
598
case GTK_STATE_ACTIVE:
599
ret = ABS_LEFTPRESSED;
601
case GTK_STATE_PRELIGHT:
604
case GTK_STATE_INSENSITIVE:
605
ret = ABS_LEFTDISABLED;
608
ret = ABS_LEFTNORMAL;
612
case XP_THEME_ELEMENT_ARROW_RIGHT:
615
case GTK_STATE_ACTIVE:
616
ret = ABS_RIGHTPRESSED;
618
case GTK_STATE_PRELIGHT:
621
case GTK_STATE_INSENSITIVE:
622
ret = ABS_RIGHTDISABLED;
625
ret = ABS_RIGHTNORMAL;
629
case XP_THEME_ELEMENT_CHECKBOX:
630
case XP_THEME_ELEMENT_RADIO_BUTTON:
633
case GTK_STATE_SELECTED:
634
ret = CBS_UNCHECKEDPRESSED;
636
case GTK_STATE_PRELIGHT:
637
ret = CBS_UNCHECKEDHOT;
639
case GTK_STATE_INSENSITIVE:
640
ret = CBS_UNCHECKEDDISABLED;
643
ret = CBS_UNCHECKEDNORMAL;
647
case XP_THEME_ELEMENT_PRESSED_CHECKBOX:
648
case XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON:
651
case GTK_STATE_SELECTED:
652
ret = CBS_CHECKEDPRESSED;
654
case GTK_STATE_PRELIGHT:
655
ret = CBS_CHECKEDHOT;
657
case GTK_STATE_INSENSITIVE:
658
ret = CBS_CHECKEDDISABLED;
661
ret = CBS_CHECKEDNORMAL;
665
case XP_THEME_ELEMENT_DEFAULT_BUTTON:
668
case GTK_STATE_ACTIVE:
671
case GTK_STATE_PRELIGHT:
674
case GTK_STATE_INSENSITIVE:
682
case XP_THEME_ELEMENT_SPIN_BUTTON_DOWN:
685
case GTK_STATE_ACTIVE:
688
case GTK_STATE_PRELIGHT:
691
case GTK_STATE_INSENSITIVE:
699
case XP_THEME_ELEMENT_SPIN_BUTTON_UP:
702
case GTK_STATE_ACTIVE:
705
case GTK_STATE_PRELIGHT:
708
case GTK_STATE_INSENSITIVE:
716
case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED:
720
case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED:
724
case XP_THEME_ELEMENT_PROGRESS_BAR_H:
725
case XP_THEME_ELEMENT_PROGRESS_BAR_V:
726
case XP_THEME_ELEMENT_PROGRESS_TROUGH_H:
727
case XP_THEME_ELEMENT_PROGRESS_TROUGH_V:
731
case XP_THEME_ELEMENT_MENU_ITEM:
732
case XP_THEME_ELEMENT_MENU_SEPARATOR:
735
case GTK_STATE_SELECTED:
738
case GTK_STATE_INSENSITIVE:
746
case XP_THEME_ELEMENT_LINE_H:
749
/* LHS_FLAT, LHS_RAISED, LHS_SUNKEN */
755
case XP_THEME_ELEMENT_LINE_V:
758
/* LVS_FLAT, LVS_RAISED, LVS_SUNKEN */
764
case XP_THEME_ELEMENT_SCALE_TROUGH_H:
765
case XP_THEME_ELEMENT_SCALE_TROUGH_V:
772
case GTK_STATE_ACTIVE:
775
case GTK_STATE_PRELIGHT:
778
case GTK_STATE_INSENSITIVE:
789
xp_theme_draw (GdkWindow * win, XpThemeElement element, GtkStyle * style,
790
int x, int y, int width, int height,
791
GtkStateType state_type, GdkRectangle * area)
794
RECT rect, clip, *pClip;
797
GdkDrawable *drawable;
800
if (!xp_theme_is_drawable (element))
803
theme = xp_theme_get_handle_by_element (element);
807
/* FIXME: Recheck its function */
808
enable_theme_dialog_texture_func (GDK_WINDOW_HWND (win), ETDT_ENABLETAB);
810
if (!GDK_IS_WINDOW (win))
818
gdk_window_get_internal_paint_info (win, &drawable, &xoff, &yoff);
821
rect.left = x - xoff;
823
rect.right = rect.left + width;
824
rect.bottom = rect.top + height;
828
clip.left = area->x - xoff;
829
clip.top = area->y - yoff;
830
clip.right = clip.left + area->width;
831
clip.bottom = clip.top + area->height;
840
gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
841
dc = gdk_win32_hdc_get (drawable, style->dark_gc[state_type], 0);
845
part_state = xp_theme_map_gtk_state (element, state_type);
847
draw_theme_background_func (theme, dc, element_part_map[element],
848
part_state, &rect, pClip);
849
gdk_win32_hdc_release (drawable, style->dark_gc[state_type], 0);
855
xp_theme_is_active (void)
861
xp_theme_is_drawable (XpThemeElement element)
863
if (xp_theme_is_active ())
864
return (xp_theme_get_handle_by_element (element) != NULL);
870
xp_theme_get_system_font (XpThemeClass klazz, XpThemeFont fontId,
873
if (xp_theme_is_active () && get_theme_sys_font_func != NULL)
875
HTHEME theme = xp_theme_get_handle_by_class (klazz);
883
case XP_THEME_FONT_CAPTION:
884
themeFont = TMT_CAPTIONFONT;
886
case XP_THEME_FONT_MENU:
887
themeFont = TMT_MENUFONT;
889
case XP_THEME_FONT_STATUS:
890
themeFont = TMT_STATUSFONT;
892
case XP_THEME_FONT_MESSAGE:
894
themeFont = TMT_MSGBOXFONT;
897
/* if theme is NULL, it will just return the GetSystemFont()
899
return ((*get_theme_sys_font_func) (theme, themeFont, lf) ==
907
xp_theme_get_system_color (XpThemeClass klazz, int colorId,
910
if (xp_theme_is_active () && get_theme_sys_color_func != NULL)
912
HTHEME theme = xp_theme_get_handle_by_class (klazz);
914
/* if theme is NULL, it will just return the GetSystemColor()
916
*pColor = (*get_theme_sys_color_func) (theme, colorId);
924
xp_theme_get_system_metric (XpThemeClass klazz, int metricId, OUT int *pVal)
926
if (xp_theme_is_active () && get_theme_sys_metric_func != NULL)
928
HTHEME theme = xp_theme_get_handle_by_class (klazz);
930
/* if theme is NULL, it will just return the GetSystemMetrics()
932
*pVal = (*get_theme_sys_metric_func) (theme, metricId);