1 /* Wimp "Windows Impersonator" Engine
3 * Copyright (C) 2003 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.
28 #include <gdk/gdkwin32.h>
32 /* MS defines this when it includes its schema definitions */
34 #include "xp_theme_dfns.h"
37 static const LPCWSTR class_descriptors[] =
54 static const short element_part_map[]=
100 static HINSTANCE uxtheme_dll = NULL;
101 static HTHEME open_themes[XP_THEME_CLASS__SIZEOF];
103 typedef HRESULT (FAR PASCAL *GetThemeSysFontFunc)
104 (HTHEME hTheme, int iFontID, FAR LOGFONT *plf);
105 typedef HTHEME (FAR PASCAL *OpenThemeDataFunc)
106 (HWND hwnd, LPCWSTR pszClassList);
107 typedef HRESULT (FAR PASCAL *CloseThemeDataFunc)(HTHEME theme);
108 typedef HRESULT (FAR PASCAL *DrawThemeBackgroundFunc)
109 (HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
110 const RECT *pRect, const RECT *pClipRect);
111 typedef HRESULT (FAR PASCAL *EnableThemeDialogTextureFunc)(HWND hwnd, DWORD dwFlags);
113 static GetThemeSysFontFunc get_theme_sys_font_func = NULL;
114 static OpenThemeDataFunc open_theme_data_func = NULL;
115 static CloseThemeDataFunc close_theme_data_func = NULL;
116 static DrawThemeBackgroundFunc draw_theme_background_func = NULL;
117 static EnableThemeDialogTextureFunc enable_theme_dialog_texture_func = NULL;
125 uxtheme_dll = LoadLibrary("uxtheme.dll");
126 memset(open_themes, 0, sizeof(open_themes));
128 open_theme_data_func = (OpenThemeDataFunc) GetProcAddress(uxtheme_dll, "OpenThemeData");
129 close_theme_data_func = (CloseThemeDataFunc) GetProcAddress(uxtheme_dll, "CloseThemeData");
130 draw_theme_background_func = (DrawThemeBackgroundFunc) GetProcAddress(uxtheme_dll, "DrawThemeBackground");
131 enable_theme_dialog_texture_func = (EnableThemeDialogTextureFunc) GetProcAddress(uxtheme_dll, "EnableThemeDialogTexture");
132 get_theme_sys_font_func = (GetThemeSysFontFunc) GetProcAddress(uxtheme_dll, "GetThemeSysFont");
143 for (i=0; i < XP_THEME_CLASS__SIZEOF; i++)
147 close_theme_data_func(open_themes[i]);
148 open_themes[i] = NULL;
152 FreeLibrary(uxtheme_dll);
155 open_theme_data_func = NULL;
156 close_theme_data_func = NULL;
157 draw_theme_background_func = NULL;
158 enable_theme_dialog_texture_func = NULL;
159 get_theme_sys_font_func = NULL;
163 xp_theme_get_handle_by_class(XpThemeClass klazz)
165 if (!open_themes[klazz] && open_theme_data_func)
167 open_themes[klazz] = open_theme_data_func(NULL, class_descriptors[klazz]);
169 return open_themes[klazz];
173 xp_theme_get_handle_by_element(XpThemeElement element)
176 XpThemeClass klazz = XP_THEME_CLASS__SIZEOF;
180 case XP_THEME_ELEMENT_TOOLTIP:
181 klazz = XP_THEME_CLASS_TOOLTIP;
184 case XP_THEME_ELEMENT_REBAR:
185 case XP_THEME_ELEMENT_GRIPPER_H:
186 case XP_THEME_ELEMENT_GRIPPER_V:
187 case XP_THEME_ELEMENT_CHEVRON:
188 klazz = XP_THEME_CLASS_REBAR;
191 case XP_THEME_ELEMENT_TOOLBAR:
192 klazz = XP_THEME_CLASS_TOOLBAR;
195 case XP_THEME_ELEMENT_HLINE:
196 case XP_THEME_ELEMENT_VLINE:
197 klazz = XP_THEME_CLASS_GLOBALS;
200 case XP_THEME_ELEMENT_PRESSED_CHECKBOX:
201 case XP_THEME_ELEMENT_CHECKBOX:
202 case XP_THEME_ELEMENT_BUTTON:
203 case XP_THEME_ELEMENT_DEFAULT_BUTTON:
204 case XP_THEME_ELEMENT_RADIO_BUTTON:
205 klazz = XP_THEME_CLASS_BUTTON;
208 case XP_THEME_ELEMENT_LIST_HEADER:
209 klazz = XP_THEME_CLASS_HEADER;
212 case XP_THEME_ELEMENT_COMBOBUTTON:
213 klazz = XP_THEME_CLASS_COMBOBOX;
216 case XP_THEME_ELEMENT_BODY:
217 case XP_THEME_ELEMENT_TAB_ITEM:
218 case XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE:
219 case XP_THEME_ELEMENT_TAB_PANE:
220 klazz = XP_THEME_CLASS_TAB;
223 case XP_THEME_ELEMENT_SCROLLBAR_V:
224 case XP_THEME_ELEMENT_SCROLLBAR_H:
225 case XP_THEME_ELEMENT_ARROW_UP:
226 case XP_THEME_ELEMENT_ARROW_DOWN:
227 case XP_THEME_ELEMENT_ARROW_LEFT:
228 case XP_THEME_ELEMENT_ARROW_RIGHT:
229 case XP_THEME_ELEMENT_GRIP_V:
230 case XP_THEME_ELEMENT_GRIP_H:
231 case XP_THEME_ELEMENT_TROUGH_V:
232 case XP_THEME_ELEMENT_TROUGH_H:
233 klazz = XP_THEME_CLASS_SCROLLBAR;
236 case XP_THEME_ELEMENT_EDIT_TEXT:
237 klazz = XP_THEME_CLASS_EDIT;
240 case XP_THEME_ELEMENT_SPIN_BUTTON_UP:
241 case XP_THEME_ELEMENT_SPIN_BUTTON_DOWN:
242 klazz = XP_THEME_CLASS_SPIN;
245 case XP_THEME_ELEMENT_PROGRESS_BAR_H:
246 case XP_THEME_ELEMENT_PROGRESS_BAR_V:
247 case XP_THEME_ELEMENT_PROGRESS_TROUGH_H:
248 case XP_THEME_ELEMENT_PROGRESS_TROUGH_V:
249 klazz = XP_THEME_CLASS_PROGRESS;
252 case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED:
253 case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED:
254 klazz = XP_THEME_CLASS_TREEVIEW;
258 if (klazz != XP_THEME_CLASS__SIZEOF)
260 ret = xp_theme_get_handle_by_class (klazz);
266 xp_theme_map_gtk_state(XpThemeElement element, GtkStateType state)
272 case XP_THEME_ELEMENT_TOOLTIP:
276 case XP_THEME_ELEMENT_REBAR:
277 case XP_THEME_ELEMENT_GRIPPER_H:
278 case XP_THEME_ELEMENT_GRIPPER_V:
282 case XP_THEME_ELEMENT_CHEVRON:
285 case GTK_STATE_PRELIGHT:
288 case GTK_STATE_SELECTED:
289 case GTK_STATE_ACTIVE:
297 case XP_THEME_ELEMENT_TOOLBAR:
301 case XP_THEME_ELEMENT_TAB_PANE:
305 case XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE:
306 case XP_THEME_ELEMENT_TAB_ITEM:
309 case GTK_STATE_PRELIGHT:
312 case GTK_STATE_INSENSITIVE:
315 case GTK_STATE_SELECTED:
316 case GTK_STATE_ACTIVE:
324 case XP_THEME_ELEMENT_EDIT_TEXT:
327 case GTK_STATE_PRELIGHT:
330 case GTK_STATE_INSENSITIVE:
333 case GTK_STATE_SELECTED:
334 case GTK_STATE_ACTIVE:
340 case XP_THEME_ELEMENT_SCROLLBAR_H:
341 case XP_THEME_ELEMENT_SCROLLBAR_V:
342 case XP_THEME_ELEMENT_TROUGH_H:
343 case XP_THEME_ELEMENT_TROUGH_V:
346 case GTK_STATE_SELECTED:
347 case GTK_STATE_ACTIVE:
350 case GTK_STATE_PRELIGHT:
353 case GTK_STATE_INSENSITIVE:
354 ret = SCRBS_DISABLED;
361 case XP_THEME_ELEMENT_ARROW_DOWN:
364 case GTK_STATE_ACTIVE:
365 ret = ABS_DOWNPRESSED;
367 case GTK_STATE_PRELIGHT:
370 case GTK_STATE_INSENSITIVE:
371 ret = ABS_DOWNDISABLED;
374 ret = ABS_DOWNNORMAL;
378 case XP_THEME_ELEMENT_ARROW_UP:
381 case GTK_STATE_ACTIVE:
384 case GTK_STATE_PRELIGHT:
387 case GTK_STATE_INSENSITIVE:
388 ret = ABS_UPDISABLED;
395 case XP_THEME_ELEMENT_ARROW_LEFT:
398 case GTK_STATE_ACTIVE:
399 ret = ABS_LEFTPRESSED;
401 case GTK_STATE_PRELIGHT:
404 case GTK_STATE_INSENSITIVE:
405 ret = ABS_LEFTDISABLED;
408 ret = ABS_LEFTNORMAL;
412 case XP_THEME_ELEMENT_ARROW_RIGHT:
415 case GTK_STATE_ACTIVE:
416 ret = ABS_RIGHTPRESSED;
418 case GTK_STATE_PRELIGHT:
421 case GTK_STATE_INSENSITIVE:
422 ret = ABS_RIGHTDISABLED;
425 ret = ABS_RIGHTNORMAL;
429 case XP_THEME_ELEMENT_CHECKBOX:
430 case XP_THEME_ELEMENT_RADIO_BUTTON:
433 case GTK_STATE_SELECTED:
434 ret = CBS_UNCHECKEDPRESSED;
436 case GTK_STATE_PRELIGHT:
437 ret = CBS_UNCHECKEDHOT;
439 case GTK_STATE_INSENSITIVE:
440 ret = CBS_UNCHECKEDDISABLED;
443 ret = CBS_UNCHECKEDNORMAL;
447 case XP_THEME_ELEMENT_PRESSED_CHECKBOX:
450 case GTK_STATE_SELECTED:
451 ret = CBS_CHECKEDPRESSED;
453 case GTK_STATE_PRELIGHT:
454 ret = CBS_CHECKEDHOT;
456 case GTK_STATE_INSENSITIVE:
457 ret = CBS_CHECKEDDISABLED;
460 ret = CBS_CHECKEDNORMAL;
464 XP_THEME_ELEMENT_DEFAULT_BUTTON:
467 case GTK_STATE_ACTIVE:
470 case GTK_STATE_PRELIGHT:
473 case GTK_STATE_INSENSITIVE:
481 case XP_THEME_ELEMENT_SPIN_BUTTON_DOWN:
484 case GTK_STATE_ACTIVE:
487 case GTK_STATE_PRELIGHT:
490 case GTK_STATE_INSENSITIVE:
498 case XP_THEME_ELEMENT_SPIN_BUTTON_UP:
501 case GTK_STATE_ACTIVE:
504 case GTK_STATE_PRELIGHT:
507 case GTK_STATE_INSENSITIVE:
515 case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED:
519 case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED:
523 case XP_THEME_ELEMENT_PROGRESS_BAR_H:
524 case XP_THEME_ELEMENT_PROGRESS_BAR_V:
525 case XP_THEME_ELEMENT_PROGRESS_TROUGH_H:
526 case XP_THEME_ELEMENT_PROGRESS_TROUGH_V:
530 #if UXTHEME_HAS_LINES
532 case XP_THEME_ELEMENT_HLINE:
534 case GTK_STATE_ACTIVE:
537 case GTK_STATE_INSENSITIVE:
545 case XP_THEME_ELEMENT_VLINE:
547 case GTK_STATE_ACTIVE:
550 case GTK_STATE_INSENSITIVE:
563 case GTK_STATE_ACTIVE:
566 case GTK_STATE_PRELIGHT:
569 case GTK_STATE_INSENSITIVE:
580 xp_theme_draw(GdkWindow *win, XpThemeElement element, GtkStyle *style,
581 int x, int y, int width, int height, GtkStateType state_type,
585 RECT rect, clip, *pClip;
586 int xoff, yoff, state;
588 GdkDrawable *drawable;
594 theme = xp_theme_get_handle_by_element(element);
598 /* FIXME: Recheck its function */
599 enable_theme_dialog_texture_func(GDK_WINDOW_HWND(win), ETDT_ENABLETAB);
601 if (!GDK_IS_WINDOW(win))
609 gdk_window_get_internal_paint_info(win, &drawable, &xoff, &yoff);
611 rect.left = x - xoff;
613 rect.right = rect.left + width;
614 rect.bottom = rect.top + height;
618 clip.left = area->x - xoff;
619 clip.top = area->y - yoff;
620 clip.right = clip.left + area->width;
621 clip.bottom = clip.top + area->height;
630 gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
631 dc = gdk_win32_hdc_get(drawable, style->dark_gc[state_type], 0);
635 part_state = xp_theme_map_gtk_state(element, state_type);
636 draw_theme_background_func(theme, dc, element_part_map[element], part_state, &rect, pClip);
637 gdk_win32_hdc_release(drawable, style->dark_gc[state_type], 0);
643 xp_theme_is_drawable(XpThemeElement element)
647 return (xp_theme_get_handle_by_element(element) != NULL);
653 xp_theme_get_system_font(int fontId, LOGFONT *lf)
655 if (get_theme_sys_font_func != NULL)
657 return ((*get_theme_sys_font_func)(NULL, fontId, lf) == S_OK);