]> Pileus Git - ~andy/gtk/blob - modules/engines/ms-windows/xp_theme.c
Make the ms-windows theme engine build with mingw.
[~andy/gtk] / modules / engines / ms-windows / xp_theme.c
1 /* MS-Windows Engine (aka GTK-Wimp)
2  *
3  * Copyright (C) 2003, 2004 Raymond Penners <raymond@dotsphinx.com>
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 #define _WIN32_WINNT 0x0501
22
23 #include "xp_theme.h"
24
25 #include <windows.h>
26 #include <math.h>
27 #include <string.h>
28 #include <stdio.h>
29
30 #include "gdk/win32/gdkwin32.h"
31
32
33 #ifdef DONT_HAVE_UXTHEME_H
34 #include "xp_theme_defs.h"
35 #else
36 #include <uxtheme.h>
37 #include <tmschema.h>
38 #endif
39
40 #ifndef TMT_CAPTIONFONT
41 /* These aren't in mingw's "w32api" headers, nor in the Platform SDK
42  * headers.
43  */
44 #define TMT_CAPTIONFONT 801
45 #define TMT_MENUFONT 803
46 #define TMT_STATUSFONT 804
47 #define TMT_MSGBOXFONT 805
48 #endif
49
50 static const LPCWSTR class_descriptors[] =
51 {
52   L"Scrollbar", /* XP_THEME_CLASS_SCROLLBAR */
53   L"Button",    /* XP_THEME_CLASS_BUTTON */
54   L"Header",    /* XP_THEME_CLASS_HEADER */
55   L"ComboBox",  /* XP_THEME_CLASS_COMBOBOX */
56   L"Tab",       /* XP_THEME_CLASS_TAB */
57   L"Edit",      /* XP_THEME_CLASS_EDIT */
58   L"TreeView",  /* XP_THEME_CLASS_TREEVIEW */
59   L"Spin",      /* XP_THEME_CLASS_SPIN */
60   L"Progress",  /* XP_THEME_CLASS_PROGRESS */
61   L"Tooltip",   /* XP_THEME_CLASS_TOOLTIP */
62   L"Rebar",     /* XP_THEME_CLASS_REBAR */
63   L"Toolbar",   /* XP_THEME_CLASS_TOOLBAR */
64   L"Globals",   /* XP_THEME_CLASS_GLOBALS */
65   L"Menu",      /* XP_THEME_CLASS_MENU */
66   L"Window",    /* XP_THEME_CLASS_WINDOW */
67   L"Status"     /* XP_THEME_CLASS_STATUS */
68 };
69
70 static const short element_part_map[]=
71 {
72   BP_CHECKBOX,
73   BP_CHECKBOX,
74   BP_PUSHBUTTON,
75   HP_HEADERITEM,
76   CP_DROPDOWNBUTTON,
77   TABP_BODY,
78   TABP_TABITEM,
79   TABP_TABITEMLEFTEDGE,
80   TABP_PANE,
81   SBP_THUMBBTNHORZ,
82   SBP_THUMBBTNVERT,
83   SBP_ARROWBTN,
84   SBP_ARROWBTN,
85   SBP_ARROWBTN,
86   SBP_ARROWBTN,
87   SBP_GRIPPERHORZ,
88   SBP_GRIPPERVERT,
89   SBP_LOWERTRACKHORZ,
90   SBP_LOWERTRACKVERT,
91   EP_EDITTEXT,
92   BP_PUSHBUTTON,
93   SPNP_UP,
94   SPNP_DOWN,
95   BP_RADIOBUTTON,
96   BP_RADIOBUTTON,
97   TVP_GLYPH,
98   TVP_GLYPH,
99   PP_CHUNK,
100   PP_CHUNKVERT,
101   PP_BAR,
102   PP_BARVERT,
103   TTP_STANDARD,
104   RP_BAND,
105   RP_GRIPPER,
106   RP_GRIPPERVERT,
107   RP_CHEVRON,
108   TP_BUTTON,
109   MP_MENUITEM,
110   MP_SEPARATOR,
111   SP_GRIPPER,
112   SP_PANE
113 };
114
115 static HINSTANCE uxtheme_dll = NULL;
116 static HTHEME open_themes[XP_THEME_CLASS__SIZEOF];
117
118 typedef HRESULT (FAR PASCAL *GetThemeSysFontFunc)
119      (HTHEME hTheme, int iFontID, OUT LOGFONT *plf);
120 typedef int (FAR PASCAL *GetThemeSysSizeFunc)
121         (HTHEME hTheme, int iSizeId);
122 typedef COLORREF (FAR PASCAL *GetThemeSysColorFunc)(HTHEME hTheme, int iColorID);
123 typedef HTHEME (FAR PASCAL *OpenThemeDataFunc)
124      (HWND hwnd, LPCWSTR pszClassList);
125 typedef HRESULT (FAR PASCAL *CloseThemeDataFunc)(HTHEME theme);
126 typedef HRESULT (FAR PASCAL *DrawThemeBackgroundFunc)
127      (HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
128       const RECT *pRect, const RECT *pClipRect);
129 typedef HRESULT (FAR PASCAL *EnableThemeDialogTextureFunc)(HWND hwnd, DWORD dwFlags);
130 typedef BOOL (FAR PASCAL *IsThemeActiveFunc)(VOID);
131 typedef BOOL (FAR PASCAL *IsAppThemedFunc)(VOID);
132
133 static GetThemeSysFontFunc get_theme_sys_font_func = NULL;
134 static GetThemeSysColorFunc get_theme_sys_color_func = NULL;
135 static GetThemeSysSizeFunc get_theme_sys_metric_func = NULL;
136 static OpenThemeDataFunc open_theme_data_func = NULL;
137 static CloseThemeDataFunc close_theme_data_func = NULL;
138 static DrawThemeBackgroundFunc draw_theme_background_func = NULL;
139 static EnableThemeDialogTextureFunc enable_theme_dialog_texture_func = NULL;
140 static IsThemeActiveFunc is_theme_active_func = NULL;
141 static IsAppThemedFunc is_app_themed_func = NULL;
142
143 static void
144 xp_theme_close_open_handles (void)
145 {
146   int i;
147
148   for (i=0; i < XP_THEME_CLASS__SIZEOF; i++)
149     {
150       if (open_themes[i])
151         {
152           close_theme_data_func (open_themes[i]);
153           open_themes[i] = NULL;
154         }
155     }
156 }
157
158 void
159 xp_theme_init (void)
160 {
161   if (uxtheme_dll)
162     return;
163
164   memset(open_themes, 0, sizeof(open_themes));
165
166   uxtheme_dll = LoadLibrary("uxtheme.dll");
167   if (!uxtheme_dll) {
168           return;
169   }
170
171   is_app_themed_func = (IsAppThemedFunc) GetProcAddress(uxtheme_dll, "IsAppThemed");
172
173   if(is_app_themed_func) {
174           is_theme_active_func = (IsThemeActiveFunc) GetProcAddress(uxtheme_dll, "IsThemeActive");
175           open_theme_data_func = (OpenThemeDataFunc) GetProcAddress(uxtheme_dll, "OpenThemeData");
176           close_theme_data_func = (CloseThemeDataFunc) GetProcAddress(uxtheme_dll, "CloseThemeData");
177           draw_theme_background_func = (DrawThemeBackgroundFunc) GetProcAddress(uxtheme_dll, "DrawThemeBackground");
178           enable_theme_dialog_texture_func = (EnableThemeDialogTextureFunc) GetProcAddress(uxtheme_dll, "EnableThemeDialogTexture");
179           get_theme_sys_font_func = (GetThemeSysFontFunc) GetProcAddress(uxtheme_dll, "GetThemeSysFont");
180           get_theme_sys_color_func = (GetThemeSysColorFunc) GetProcAddress(uxtheme_dll, "GetThemeSysColor");
181           get_theme_sys_metric_func = (GetThemeSysSizeFunc) GetProcAddress(uxtheme_dll, "GetThemeSysSize");
182   }
183 }
184
185 void
186 xp_theme_reset (void)
187 {
188   xp_theme_close_open_handles ();
189 }
190
191 void
192 xp_theme_exit (void)
193 {
194   if (! uxtheme_dll)
195     return;
196
197   xp_theme_close_open_handles ();
198
199   FreeLibrary (uxtheme_dll);
200   uxtheme_dll = NULL;
201
202   is_app_themed_func = NULL;
203   is_theme_active_func = NULL;
204   open_theme_data_func = NULL;
205   close_theme_data_func = NULL;
206   draw_theme_background_func = NULL;
207   enable_theme_dialog_texture_func = NULL;
208   get_theme_sys_font_func = NULL;
209   get_theme_sys_color_func = NULL;
210   get_theme_sys_metric_func = NULL;
211 }
212
213 static HTHEME
214 xp_theme_get_handle_by_class (XpThemeClass klazz)
215 {
216   if (!open_themes[klazz] && open_theme_data_func)
217     {
218       open_themes[klazz] = open_theme_data_func(NULL, class_descriptors[klazz]);
219     }
220   return open_themes[klazz];
221 }
222
223 static HTHEME
224 xp_theme_get_handle_by_element (XpThemeElement element)
225 {
226   HTHEME ret = NULL;
227   XpThemeClass klazz = XP_THEME_CLASS__SIZEOF;
228
229   switch(element)
230     {
231     case XP_THEME_ELEMENT_TOOLTIP:
232       klazz = XP_THEME_CLASS_TOOLTIP;
233       break;
234
235     case XP_THEME_ELEMENT_REBAR:
236     case XP_THEME_ELEMENT_REBAR_GRIPPER_H:
237     case XP_THEME_ELEMENT_REBAR_GRIPPER_V:
238     case XP_THEME_ELEMENT_REBAR_CHEVRON:
239       klazz = XP_THEME_CLASS_REBAR;
240       break;
241
242     case XP_THEME_ELEMENT_STATUS_GRIPPER:
243     case XP_THEME_ELEMENT_STATUS_PANE:
244       klazz = XP_THEME_CLASS_STATUS;
245       break;
246
247         case XP_THEME_ELEMENT_TOOLBAR_BUTTON:
248       klazz = XP_THEME_CLASS_TOOLBAR;
249       break;
250
251     case XP_THEME_ELEMENT_MENU_ITEM:
252     case XP_THEME_ELEMENT_MENU_SEPARATOR:
253       klazz = XP_THEME_CLASS_MENU;
254       break;
255
256     case XP_THEME_ELEMENT_PRESSED_CHECKBOX:
257     case XP_THEME_ELEMENT_CHECKBOX:
258     case XP_THEME_ELEMENT_BUTTON:
259     case XP_THEME_ELEMENT_DEFAULT_BUTTON:
260     case XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON:
261     case XP_THEME_ELEMENT_RADIO_BUTTON:
262       klazz = XP_THEME_CLASS_BUTTON;
263       break;
264
265     case XP_THEME_ELEMENT_LIST_HEADER:
266       klazz = XP_THEME_CLASS_HEADER;
267       break;
268
269     case XP_THEME_ELEMENT_COMBOBUTTON:
270       klazz = XP_THEME_CLASS_COMBOBOX;
271       break;
272
273     case XP_THEME_ELEMENT_BODY:
274     case XP_THEME_ELEMENT_TAB_ITEM:
275     case XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE:
276     case XP_THEME_ELEMENT_TAB_PANE:
277       klazz = XP_THEME_CLASS_TAB;
278       break;
279
280     case XP_THEME_ELEMENT_SCROLLBAR_V:
281     case XP_THEME_ELEMENT_SCROLLBAR_H:
282     case XP_THEME_ELEMENT_ARROW_UP:
283     case XP_THEME_ELEMENT_ARROW_DOWN:
284     case XP_THEME_ELEMENT_ARROW_LEFT:
285     case XP_THEME_ELEMENT_ARROW_RIGHT:
286     case XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_V:
287     case XP_THEME_ELEMENT_SCROLLBAR_GRIPPER_H:
288     case XP_THEME_ELEMENT_TROUGH_V:
289     case XP_THEME_ELEMENT_TROUGH_H:
290       klazz = XP_THEME_CLASS_SCROLLBAR;
291       break;
292
293     case XP_THEME_ELEMENT_EDIT_TEXT:
294       klazz = XP_THEME_CLASS_EDIT;
295       break;
296
297     case XP_THEME_ELEMENT_SPIN_BUTTON_UP:
298     case XP_THEME_ELEMENT_SPIN_BUTTON_DOWN:
299       klazz = XP_THEME_CLASS_SPIN;
300       break;
301
302     case XP_THEME_ELEMENT_PROGRESS_BAR_H:
303     case XP_THEME_ELEMENT_PROGRESS_BAR_V:
304     case XP_THEME_ELEMENT_PROGRESS_TROUGH_H:
305     case XP_THEME_ELEMENT_PROGRESS_TROUGH_V:
306       klazz = XP_THEME_CLASS_PROGRESS;
307       break;
308
309     case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED:
310     case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED:
311       klazz = XP_THEME_CLASS_TREEVIEW;
312       break;
313     }
314
315   if (klazz != XP_THEME_CLASS__SIZEOF)
316     {
317       ret = xp_theme_get_handle_by_class (klazz);
318     }
319   return ret;
320 }
321
322 static int
323 xp_theme_map_gtk_state (XpThemeElement element, GtkStateType state)
324 {
325   int ret;
326
327   switch(element)
328     {
329     case XP_THEME_ELEMENT_TOOLTIP:
330       ret = TTSS_NORMAL;
331       break;
332
333     case XP_THEME_ELEMENT_REBAR:
334     case XP_THEME_ELEMENT_REBAR_GRIPPER_H:
335     case XP_THEME_ELEMENT_REBAR_GRIPPER_V:
336       ret = CHEVS_NORMAL;
337       break;
338
339         case XP_THEME_ELEMENT_STATUS_GRIPPER:
340         case XP_THEME_ELEMENT_STATUS_PANE:
341                 ret = 1;
342                 break;
343
344     case XP_THEME_ELEMENT_REBAR_CHEVRON:
345       switch (state)
346         {
347         case GTK_STATE_PRELIGHT:
348           ret =  CHEVS_HOT;
349           break;
350         case GTK_STATE_SELECTED:
351         case GTK_STATE_ACTIVE:
352           ret =  CHEVS_PRESSED;
353           break;
354         default:
355           ret =  CHEVS_NORMAL;
356         }
357       break;
358
359         case XP_THEME_ELEMENT_TOOLBAR_BUTTON:
360                 switch (state)
361                 {
362         case GTK_STATE_ACTIVE:
363           ret =  TS_PRESSED;
364           break;
365         case GTK_STATE_PRELIGHT:
366           ret =  TS_HOT;
367           break;
368         case GTK_STATE_INSENSITIVE:
369           ret =  TS_DISABLED;
370           break;
371         default:
372           ret =  TS_NORMAL;
373                 }
374                 break;
375
376     case XP_THEME_ELEMENT_TAB_PANE:
377       ret = 1;
378       break;
379
380     case XP_THEME_ELEMENT_TAB_ITEM_LEFT_EDGE:
381     case XP_THEME_ELEMENT_TAB_ITEM:
382       switch(state)
383         {
384         case GTK_STATE_PRELIGHT:
385           ret =  TIS_HOT;
386           break;
387         case GTK_STATE_INSENSITIVE:
388           ret =  TIS_DISABLED;
389           break;
390         case GTK_STATE_SELECTED:
391         case GTK_STATE_ACTIVE:
392           ret =  TIS_NORMAL;
393           break;
394         default:
395           ret =  TIS_SELECTED;
396         }
397       break;
398
399     case XP_THEME_ELEMENT_EDIT_TEXT:
400       switch(state)
401         {
402         case GTK_STATE_PRELIGHT:
403           ret =  ETS_FOCUSED;
404           break;
405         case GTK_STATE_INSENSITIVE:
406           ret =  ETS_READONLY;
407           break;
408         case GTK_STATE_SELECTED:
409         case GTK_STATE_ACTIVE:
410         default:
411           ret =  ETS_NORMAL;
412         }
413       break;
414
415     case XP_THEME_ELEMENT_SCROLLBAR_H:
416     case XP_THEME_ELEMENT_SCROLLBAR_V:
417     case XP_THEME_ELEMENT_TROUGH_H:
418     case XP_THEME_ELEMENT_TROUGH_V:
419       switch(state)
420         {
421         case GTK_STATE_SELECTED:
422         case GTK_STATE_ACTIVE:
423           ret =  SCRBS_PRESSED;
424           break;
425         case GTK_STATE_PRELIGHT:
426           ret =  SCRBS_HOT;
427           break;
428         case GTK_STATE_INSENSITIVE:
429           ret =  SCRBS_DISABLED;
430           break;
431         default:
432           ret =  SCRBS_NORMAL;
433         }
434       break;
435
436     case XP_THEME_ELEMENT_ARROW_DOWN:
437       switch(state)
438         {
439         case GTK_STATE_ACTIVE:
440           ret =  ABS_DOWNPRESSED;
441           break;
442         case GTK_STATE_PRELIGHT:
443           ret =  ABS_DOWNHOT;
444           break;
445         case GTK_STATE_INSENSITIVE:
446           ret =  ABS_DOWNDISABLED;
447           break;
448         default:
449           ret =  ABS_DOWNNORMAL;
450         }
451       break;
452
453     case XP_THEME_ELEMENT_ARROW_UP:
454       switch(state)
455         {
456         case GTK_STATE_ACTIVE:
457           ret =  ABS_UPPRESSED;
458           break;
459         case GTK_STATE_PRELIGHT:
460           ret =  ABS_UPHOT;
461           break;
462         case GTK_STATE_INSENSITIVE:
463           ret =  ABS_UPDISABLED;
464           break;
465         default:
466           ret =  ABS_UPNORMAL;
467         }
468       break;
469
470     case XP_THEME_ELEMENT_ARROW_LEFT:
471       switch(state)
472         {
473         case GTK_STATE_ACTIVE:
474           ret =  ABS_LEFTPRESSED;
475           break;
476         case GTK_STATE_PRELIGHT:
477           ret =  ABS_LEFTHOT;
478           break;
479         case GTK_STATE_INSENSITIVE:
480           ret =  ABS_LEFTDISABLED;
481           break;
482         default:
483           ret =  ABS_LEFTNORMAL;
484         }
485       break;
486
487     case XP_THEME_ELEMENT_ARROW_RIGHT:
488       switch(state)
489         {
490         case GTK_STATE_ACTIVE:
491           ret =  ABS_RIGHTPRESSED;
492           break;
493         case GTK_STATE_PRELIGHT:
494           ret =  ABS_RIGHTHOT;
495           break;
496         case GTK_STATE_INSENSITIVE:
497           ret =  ABS_RIGHTDISABLED;
498           break;
499         default:
500           ret =  ABS_RIGHTNORMAL;
501         }
502       break;
503
504     case XP_THEME_ELEMENT_CHECKBOX:
505     case XP_THEME_ELEMENT_RADIO_BUTTON:
506       switch(state)
507         {
508         case GTK_STATE_SELECTED:
509           ret =  CBS_UNCHECKEDPRESSED;
510           break;
511         case GTK_STATE_PRELIGHT:
512           ret =  CBS_UNCHECKEDHOT;
513           break;
514         case GTK_STATE_INSENSITIVE:
515           ret =  CBS_UNCHECKEDDISABLED;
516           break;
517         default:
518           ret =  CBS_UNCHECKEDNORMAL;
519         }
520       break;
521
522     case XP_THEME_ELEMENT_PRESSED_CHECKBOX:
523     case XP_THEME_ELEMENT_PRESSED_RADIO_BUTTON:
524       switch(state)
525         {
526         case GTK_STATE_SELECTED:
527           ret =  CBS_CHECKEDPRESSED;
528           break;
529         case GTK_STATE_PRELIGHT:
530           ret =  CBS_CHECKEDHOT;
531           break;
532         case GTK_STATE_INSENSITIVE:
533           ret =  CBS_CHECKEDDISABLED;
534           break;
535         default:
536           ret =  CBS_CHECKEDNORMAL;
537         }
538       break;
539
540     XP_THEME_ELEMENT_DEFAULT_BUTTON:
541       switch(state)
542         {
543         case GTK_STATE_ACTIVE:
544           ret =  PBS_PRESSED;
545           break;
546         case GTK_STATE_PRELIGHT:
547           ret =  PBS_HOT;
548           break;
549         case GTK_STATE_INSENSITIVE:
550           ret =  PBS_DISABLED;
551           break;
552         default:
553           ret =  PBS_DEFAULTED;
554         }
555       break;
556
557     case XP_THEME_ELEMENT_SPIN_BUTTON_DOWN:
558       switch(state)
559         {
560         case GTK_STATE_ACTIVE:
561           ret =  DNS_PRESSED;
562           break;
563         case GTK_STATE_PRELIGHT:
564           ret =  DNS_HOT;
565           break;
566         case GTK_STATE_INSENSITIVE:
567           ret =  DNS_DISABLED;
568           break;
569         default:
570           ret =  DNS_NORMAL;
571         }
572       break;
573
574     case XP_THEME_ELEMENT_SPIN_BUTTON_UP:
575       switch(state)
576         {
577         case GTK_STATE_ACTIVE:
578           ret =  UPS_PRESSED;
579           break;
580         case GTK_STATE_PRELIGHT:
581           ret =  UPS_HOT;
582           break;
583         case GTK_STATE_INSENSITIVE:
584           ret =  UPS_DISABLED;
585           break;
586         default:
587           ret =  UPS_NORMAL;
588         }
589       break;
590
591     case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_OPENED:
592       ret = GLPS_OPENED;
593       break;
594
595     case XP_THEME_ELEMENT_TREEVIEW_EXPANDER_CLOSED:
596       ret = GLPS_CLOSED;
597       break;
598
599     case XP_THEME_ELEMENT_PROGRESS_BAR_H:
600     case XP_THEME_ELEMENT_PROGRESS_BAR_V:
601     case XP_THEME_ELEMENT_PROGRESS_TROUGH_H:
602     case XP_THEME_ELEMENT_PROGRESS_TROUGH_V:
603       ret = 1;
604       break;
605
606         case XP_THEME_ELEMENT_MENU_ITEM:
607         case XP_THEME_ELEMENT_MENU_SEPARATOR:
608                 switch(state) {
609                         case GTK_STATE_SELECTED:
610                                 ret = MS_SELECTED;
611                                 break;
612                         case GTK_STATE_INSENSITIVE:
613                                 ret = MS_DEMOTED;
614                                 break;
615                         default:
616                                 ret = MS_NORMAL;
617                 }
618                 break;
619
620     default:
621       switch(state)
622         {
623         case GTK_STATE_ACTIVE:
624           ret =  PBS_PRESSED;
625           break;
626         case GTK_STATE_PRELIGHT:
627           ret =  PBS_HOT;
628           break;
629         case GTK_STATE_INSENSITIVE:
630           ret =  PBS_DISABLED;
631           break;
632         default:
633           ret =  PBS_NORMAL;
634         }
635     }
636   return ret;
637 }
638
639 gboolean
640 xp_theme_draw (GdkWindow *win, XpThemeElement element, GtkStyle *style,
641                int x, int y, int width, int height,
642                GtkStateType state_type, GdkRectangle *area)
643 {
644   HTHEME theme;
645   RECT rect, clip, *pClip;
646   int xoff, yoff, state;
647   HDC dc;
648   GdkDrawable *drawable;
649   int part_state;
650
651   if (! xp_theme_is_drawable (element))
652     return FALSE;
653
654   theme = xp_theme_get_handle_by_element(element);
655   if (!theme)
656     return FALSE;
657
658   /* FIXME: Recheck its function */
659   enable_theme_dialog_texture_func(GDK_WINDOW_HWND(win), ETDT_ENABLETAB);
660
661   if (!GDK_IS_WINDOW(win))
662     {
663       xoff = 0;
664       yoff = 0;
665       drawable = win;
666     }
667   else
668     {
669       gdk_window_get_internal_paint_info(win, &drawable, &xoff, &yoff);
670     }
671   rect.left = x - xoff;
672   rect.top = y - yoff;
673   rect.right = rect.left + width;
674   rect.bottom = rect.top + height;
675
676   if (area)
677     {
678       clip.left = area->x - xoff;
679       clip.top = area->y - yoff;
680       clip.right = clip.left + area->width;
681       clip.bottom = clip.top + area->height;
682
683       pClip = &clip;
684     }
685   else
686     {
687       pClip = NULL;
688     }
689
690   gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL);
691   dc = gdk_win32_hdc_get(drawable, style->dark_gc[state_type], 0);
692   if (!dc)
693     return FALSE;
694
695   part_state = xp_theme_map_gtk_state(element, state_type);
696
697 #ifdef GNATS_HACK
698   if (element == XP_THEME_ELEMENT_REBAR_GRIPPER_V
699       || element == XP_THEME_ELEMENT_REBAR_GRIPPER_H)
700     {
701       /* Hack alert: when XP draws a gripper, it does not seem to fill
702          up the whole rectangle. It only fills the gripper line
703          itself. Therefore we manually fill up the background here
704          ourselves. I still have to look into this a bit further, as
705          tests with GNAT Programming System show some awkward
706          interference between this FillRect and the subsequent
707          DrawThemeBackground(). */
708       FillRect (dc, &rect, (HBRUSH) (COLOR_3DFACE+1));
709     }
710 #endif
711
712   draw_theme_background_func(theme, dc, element_part_map[element], part_state, &rect, pClip);
713   gdk_win32_hdc_release(drawable, style->dark_gc[state_type], 0);
714
715   return TRUE;
716 }
717
718 static gboolean
719 xp_theme_is_active (void)
720 {
721   gboolean active = FALSE;
722
723   if (is_app_themed_func)
724   {
725           active = (*is_app_themed_func) ();
726
727           if (active && is_theme_active_func)
728             {
729               active = (*is_theme_active_func) ();
730                 }
731   }
732
733   return active;
734 }
735
736 gboolean
737 xp_theme_is_drawable (XpThemeElement element)
738 {
739  if (xp_theme_is_active ())
740   return (xp_theme_get_handle_by_element (element) != NULL);
741
742   return FALSE;
743 }
744
745 gboolean
746 xp_theme_get_system_font (XpThemeClass klazz, XpThemeFont fontId, LOGFONT *lf)
747 {
748   int themeFont;
749
750   if (get_theme_sys_font_func != NULL)
751     {
752       HTHEME theme = xp_theme_get_handle_by_class(klazz);
753       if (!theme)
754         return FALSE;
755
756       switch (fontId)
757         {
758         case XP_THEME_FONT_CAPTION:
759           themeFont = TMT_CAPTIONFONT; break;
760         case XP_THEME_FONT_MENU:
761           themeFont = TMT_MENUFONT; break;
762         case XP_THEME_FONT_STATUS:
763           themeFont = TMT_STATUSFONT; break;
764         case XP_THEME_FONT_MESSAGE:
765         default:
766           themeFont = TMT_MSGBOXFONT; break;
767         }
768       /* if theme is NULL, it will just return the GetSystemFont() value */
769       return ((*get_theme_sys_font_func)(theme, themeFont, lf) == S_OK);
770     }
771   return FALSE;
772 }
773
774 gboolean
775 xp_theme_get_system_color (XpThemeClass klazz, int colorId, DWORD * pColor)
776 {
777   if (get_theme_sys_color_func != NULL)
778     {
779       HTHEME theme = xp_theme_get_handle_by_class(klazz);
780
781       /* if theme is NULL, it will just return the GetSystemColor() value */
782       *pColor = (*get_theme_sys_color_func)(theme, colorId);
783       return TRUE;
784     }
785   return FALSE;
786 }
787
788 gboolean
789 xp_theme_get_system_metric (XpThemeClass klazz, int metricId, int * pVal)
790 {
791   if (get_theme_sys_metric_func != NULL)
792     {
793       HTHEME theme = xp_theme_get_handle_by_class(klazz);
794
795       /* if theme is NULL, it will just return the GetSystemMetrics() value */
796       *pVal = (*get_theme_sys_metric_func)(theme, metricId);
797       return TRUE;
798     }
799   return FALSE;
800 }