1 /*
2  * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 #include "sun_awt_windows_ThemeReader.h"
27 #include <string.h>
28 
29 #include "awt.h"
30 #include "awt_Toolkit.h"
31 #include "awt_Object.h"
32 #include "awt_Component.h"
33 
34 // Important note about VC6 and VC7 (or XP Platform SDK)   !
35 //
36 // These type definitions have been imported from UxTheme.h
37 // They have been imported instead of including them, because
38 // currently we don't require Platform SDK for building J2SE and
39 // VC6 includes do not have UxTheme.h. When we move to VC7
40 // we should remove these imports and just include
41 //
42 //  Uncomment these when we start using VC 7 (or XP Platform SDK)
43 //
44 //  #include <uxtheme.h>
45 //  #incldue <tmschema.h>
46 
47 
48 // Remove everyting inside this ifdef when we start using VC 7 (or XP Platform SDK)
49 #ifndef  _UXTHEME_H_
50 typedef HANDLE HTHEME;          // handle to a section of theme data for class
51 
52 typedef enum {
53     TS_MIN,
54     TS_TRUE,
55     TS_DRAW
56 } THEME_SIZE;
57 
58 
59 // Remove these when we start using VC 7 (or XP Platform SDK)
60 typedef struct _MARGINS
61 {
62     int cxLeftWidth;      // width of left border that retains its size
63     int cxRightWidth;     // width of right border that retains its size
64     int cyTopHeight;      // height of top border that retains its size
65     int cyBottomHeight;   // height of bottom border that retains its size
66 } MARGINS, *PMARGINS;
67 
68 #define TMT_TRANSPARENT 2201
69 #endif // _UXTHEME_H_
70 
71 
72 #define ALPHA_MASK 0xff000000
73 #define RED_MASK 0xff0000
74 #define GREEN_MASK 0xff00
75 #define BLUE_MASK 0xff
76 #define ALPHA_SHIFT 24
77 #define RED_SHIFT 16
78 #define GREEN_SHIFT 8
79 
80 
81 typedef HRESULT(__stdcall *PFNCLOSETHEMEDATA)(HTHEME hTheme);
82 
83 typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc,
84         int iPartId, int iStateId, const RECT *pRect,  const RECT *pClipRect);
85 
86 typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
87 
88 typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc,
89           int iPartId, int iStateId, LPCWSTR pszText, int iCharCount,
90           DWORD dwTextFlags, DWORD dwTextFlags2, const RECT *pRect);
91 
92 typedef HRESULT (__stdcall *PFNGETTHEMEBACKGROUNDCONTENTRECT)(HTHEME hTheme,
93         HDC hdc, int iPartId, int iStateId,  const RECT *pBoundingRect,
94         RECT *pContentRect);
95 
96 typedef HRESULT (__stdcall *PFNGETTHEMEMARGINS)(HTHEME hTheme,
97         OPTIONAL HDC hdc, int iPartId, int iStateId, int iPropId,
98         OPTIONAL RECT *prc, OUT MARGINS *pMargins);
99 
100 typedef BOOL (__stdcall *PFNISTHEMEPARTDEFINED)(HTHEME hTheme, int iPartId, int iStateId);
101 
102 typedef HRESULT (__stdcall *PFNGETTHEMEBOOL)(HTHEME hTheme, int iPartId,
103         int iStateId, int iPropId, BOOL *pfVal);
104 
105 typedef BOOL (__stdcall *PFNGETTHEMESYSBOOL)(HTHEME hTheme, int iPropId);
106 
107 typedef HRESULT (__stdcall *PFNGETTHEMECOLOR)(HTHEME hTheme, int iPartId,
108         int iStateId, int iPropId, COLORREF *pColor);
109 
110 typedef HRESULT (__stdcall *PFNGETTHEMEENUMVALUE)(HTHEME hTheme, int iPartId,
111         int iStateId, int iPropId, int *val);
112 typedef HRESULT (__stdcall *PFNGETTHEMEINT)(HTHEME hTheme, int iPartId,
113         int iStateId, int iPropId, int *val);
114 typedef HRESULT (__stdcall *PFNGETTHEMEPARTSIZE)(HTHEME hTheme, HDC hdc,
115         int iPartId, int iStateId, RECT *prc, THEME_SIZE eSize, SIZE *size);
116 
117 typedef HRESULT (__stdcall *PFNGETTHEMEPOSITION)(HTHEME hTheme, int iPartId,
118         int iStateId, int propID, POINT *point);
119 
120 typedef HRESULT(__stdcall *PFNSETWINDOWTHEME)(HWND hwnd, LPCWSTR pszSubAppName,
121             LPCWSTR pszSubIdList);
122 
123 typedef HRESULT (__stdcall *PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT)
124                 (HTHEME hTheme, int iPartId, int iStateId);
125 
126 typedef HRESULT (__stdcall *PFNGETTHEMETRANSITIONDURATION)
127                 (HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo,
128                  int iPropId, DWORD *pdwDuration);
129 
130 static PFNOPENTHEMEDATA OpenThemeData = NULL;
131 static PFNDRAWTHEMEBACKGROUND DrawThemeBackground = NULL;
132 static PFNCLOSETHEMEDATA CloseThemeData = NULL;
133 static PFNDRAWTHEMETEXT DrawThemeText = NULL;
134 static PFNGETTHEMEBACKGROUNDCONTENTRECT GetThemeBackgroundContentRect = NULL;
135 static PFNGETTHEMEMARGINS GetThemeMargins = NULL;
136 static PFNISTHEMEPARTDEFINED IsThemePartDefined = NULL;
137 static PFNGETTHEMEBOOL GetThemeBool=NULL;
138 static PFNGETTHEMESYSBOOL GetThemeSysBool=NULL;
139 static PFNGETTHEMECOLOR GetThemeColor=NULL;
140 static PFNGETTHEMEENUMVALUE GetThemeEnumValue = NULL;
141 static PFNGETTHEMEINT GetThemeInt = NULL;
142 static PFNGETTHEMEPARTSIZE GetThemePartSize = NULL;
143 static PFNGETTHEMEPOSITION GetThemePosition = NULL;
144 static PFNSETWINDOWTHEME SetWindowTheme = NULL;
145 static PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT
146                                    IsThemeBackgroundPartiallyTransparent = NULL;
147 //this function might not exist on Windows XP
148 static PFNGETTHEMETRANSITIONDURATION GetThemeTransitionDuration = NULL;
149 
150 
InitThemes()151 BOOL InitThemes() {
152     static HMODULE hModThemes = NULL;
153     hModThemes = JDK_LoadSystemLibrary("UXTHEME.DLL");
154     DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes);
155     if(hModThemes) {
156         DTRACE_PRINTLN("Loaded UxTheme.dll\n");
157         OpenThemeData = (PFNOPENTHEMEDATA)GetProcAddress(hModThemes,
158                                                         "OpenThemeData");
159         DrawThemeBackground = (PFNDRAWTHEMEBACKGROUND)GetProcAddress(
160                                         hModThemes, "DrawThemeBackground");
161         CloseThemeData = (PFNCLOSETHEMEDATA)GetProcAddress(
162                                                 hModThemes, "CloseThemeData");
163         DrawThemeText = (PFNDRAWTHEMETEXT)GetProcAddress(
164                                         hModThemes, "DrawThemeText");
165         GetThemeBackgroundContentRect = (PFNGETTHEMEBACKGROUNDCONTENTRECT)
166                 GetProcAddress(hModThemes, "GetThemeBackgroundContentRect");
167         GetThemeMargins = (PFNGETTHEMEMARGINS)GetProcAddress(
168                                         hModThemes, "GetThemeMargins");
169         IsThemePartDefined = (PFNISTHEMEPARTDEFINED)GetProcAddress(
170                                         hModThemes, "IsThemePartDefined");
171         GetThemeBool = (PFNGETTHEMEBOOL)GetProcAddress(
172                                         hModThemes, "GetThemeBool");
173         GetThemeSysBool = (PFNGETTHEMESYSBOOL)GetProcAddress(hModThemes,
174                                                         "GetThemeSysBool");
175         GetThemeColor = (PFNGETTHEMECOLOR)GetProcAddress(hModThemes,
176                                                         "GetThemeColor");
177         GetThemeEnumValue = (PFNGETTHEMEENUMVALUE)GetProcAddress(hModThemes,
178                                                 "GetThemeEnumValue");
179         GetThemeInt = (PFNGETTHEMEINT)GetProcAddress(hModThemes, "GetThemeInt");
180         GetThemePosition = (PFNGETTHEMEPOSITION)GetProcAddress(hModThemes,
181                                                         "GetThemePosition");
182         GetThemePartSize = (PFNGETTHEMEPARTSIZE)GetProcAddress(hModThemes,
183                                                          "GetThemePartSize");
184         SetWindowTheme = (PFNSETWINDOWTHEME)GetProcAddress(hModThemes,
185                                                         "SetWindowTheme");
186         IsThemeBackgroundPartiallyTransparent =
187             (PFNISTHEMEBACKGROUNDPARTIALLYTRANSPARENT)GetProcAddress(hModThemes,
188                                        "IsThemeBackgroundPartiallyTransparent");
189         //this function might not exist
190         GetThemeTransitionDuration =
191             (PFNGETTHEMETRANSITIONDURATION)GetProcAddress(hModThemes,
192                                         "GetThemeTransitionDuration");
193 
194         if(OpenThemeData
195            && DrawThemeBackground
196            && CloseThemeData
197            && DrawThemeText
198            && GetThemeBackgroundContentRect
199            && GetThemeMargins
200            && IsThemePartDefined
201            && GetThemeBool
202            && GetThemeSysBool
203            && GetThemeColor
204            && GetThemeEnumValue
205            && GetThemeInt
206            && GetThemePartSize
207            && GetThemePosition
208            && SetWindowTheme
209            && IsThemeBackgroundPartiallyTransparent
210           ) {
211               DTRACE_PRINTLN("Loaded function pointers.\n");
212               // We need to make sure we can load the Theme. This may not be
213               // the case on a WinXP machine with classic mode enabled.
214               HTHEME hTheme = OpenThemeData(AwtToolkit::GetInstance().GetHWnd(), L"Button");
215               if(hTheme) {
216                   DTRACE_PRINTLN("Loaded Theme data.\n");
217                   CloseThemeData(hTheme);
218                   return TRUE;
219               }
220             } else {
221                FreeLibrary(hModThemes);
222                hModThemes = NULL;
223             }
224     }
225     return FALSE;
226 }
227 
Java_sun_awt_windows_ThemeReader_initThemes(JNIEnv * env,jclass klass)228 JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_initThemes
229 (JNIEnv *env, jclass klass) {
230     static BOOL TryLoadingThemeLib = FALSE;
231     static BOOL Themed = FALSE;
232     if (!TryLoadingThemeLib) {
233         Themed = InitThemes();
234         TryLoadingThemeLib = TRUE;
235     }
236     return JNI_IS_TRUE(Themed);
237 }
238 
239 
240 
assert_result(HRESULT hres,JNIEnv * env)241 static void assert_result(HRESULT hres, JNIEnv *env) {
242 #ifdef _DEBUG
243     if (hres != 0) {
244         DWORD lastError = GetLastError();
245         if (lastError != 0) {
246             LPSTR msgBuffer = NULL;
247             FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
248                     FORMAT_MESSAGE_FROM_SYSTEM |
249                     FORMAT_MESSAGE_IGNORE_INSERTS,
250                     NULL,
251                     lastError,
252                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
253                     (LPSTR)&msgBuffer,
254                     // it's an output parameter when allocate buffer is used
255                     0,
256                     NULL);
257             DTRACE_PRINTLN3("Error: hres=0x%x lastError=0x%x %s\n", hres,
258                                                 lastError, msgBuffer);
259         }
260     }
261 #endif
262 }
263 
264 
265 /*
266  * Class:     sun_awt_windows_ThemeReader
267  * Method:    openTheme
268  * Signature: (Ljava/lang/String;)J
269  */
Java_sun_awt_windows_ThemeReader_openTheme(JNIEnv * env,jclass klass,jstring widget)270 JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme
271 (JNIEnv *env, jclass klass, jstring widget) {
272 
273     LPCTSTR str = (LPCTSTR) JNU_GetStringPlatformChars(env, widget, NULL);
274     if (str == NULL) {
275         JNU_ThrowOutOfMemoryError(env, 0);
276         return 0;
277     }
278     // We need to open the Theme on a Window that will stick around.
279     // The best one for that purpose is the Toolkit window.
280     HTHEME htheme = OpenThemeData(AwtToolkit::GetInstance().GetHWnd(), str);
281     JNU_ReleaseStringPlatformChars(env, widget, str);
282     return (jlong) htheme;
283 }
284 
285 /*
286  * Class:     sun_awt_windows_ThemeReader
287  * Method:    setWindowTheme
288  * Signature: (Ljava/lang/String;)V
289  */
Java_sun_awt_windows_ThemeReader_setWindowTheme(JNIEnv * env,jclass klass,jstring subAppName)290 JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_setWindowTheme
291 (JNIEnv *env, jclass klass, jstring subAppName) {
292 
293     LPCTSTR str = NULL;
294     if (subAppName != NULL) {
295         str = (LPCTSTR) JNU_GetStringPlatformChars(env, subAppName, NULL);
296     }
297     // We need to set the Window theme on the same theme that we opened it with.
298     HRESULT hres = SetWindowTheme(AwtToolkit::GetInstance().GetHWnd(), str, NULL);
299     assert_result(hres, env);
300     if (subAppName != NULL) {
301         JNU_ReleaseStringPlatformChars(env, subAppName, str);
302     }
303 }
304 
305 /*
306  * Class:     sun_awt_windows_ThemeReader
307  * Method:    closeTheme
308  * Signature: (J)V
309  */
Java_sun_awt_windows_ThemeReader_closeTheme(JNIEnv * env,jclass klass,jlong theme)310 JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_closeTheme
311 (JNIEnv *env, jclass klass, jlong theme) {
312 
313     HRESULT hres = CloseThemeData((HTHEME)theme);
314     assert_result(hres, env);
315 }
316 
copyDIBToBufferedImage(int * pDstBits,int * pSrcBits,BOOL transparent,int w,int h,int stride)317 static void copyDIBToBufferedImage(int *pDstBits, int *pSrcBits,
318                 BOOL transparent, int w, int h, int stride) {
319 
320     int offsetToNextLine = stride - w;
321     int *dst = pDstBits;
322     int *src = pSrcBits;
323     double alphaScale;
324     int r,g,b,a;
325     int pixel;
326 
327     BOOL translucent = FALSE;
328 
329     for (int i=0;i<h;i++) {
330         for (int j=0;j<w;j++) {
331             pixel = *src++;
332             a = (pixel & ALPHA_MASK)  >> ALPHA_SHIFT;
333             if ((a != 0) && (a != 255)) {
334                 translucent = TRUE;
335                 break;
336             }
337         }
338         if (translucent) break;
339     }
340     src = pSrcBits;
341 
342     if (translucent) {
343         for (int i=0;i<h;i++) {
344             for (int j=0;j<w;j++) {
345                 pixel = *src++;
346                 if (pixel != 0) {
347                     // The UxTheme API seems to do the blending and
348                     // premultiply the resulting values.
349                     // so we have to divide by the alpha to get the
350                     // original component values.
351                     a = (pixel & ALPHA_MASK)  >> ALPHA_SHIFT;
352                     if ((a != 255) && (a != 0)) {
353                         r = (pixel & RED_MASK)  >> RED_SHIFT;
354                         g = (pixel & GREEN_MASK)  >> GREEN_SHIFT;
355                         b = (pixel & BLUE_MASK);
356                         alphaScale = 255.0 / a;
357                         r = (int) ((double) r * alphaScale);
358                         if (r > 255) r = 255;
359                         g = (int) ((double) g * alphaScale);
360                         if (g > 255) g = 255;
361                         b = (int) ((double) b * alphaScale);
362                         if (b > 255) b = 255;
363                         pixel = (a << ALPHA_SHIFT) | (r << RED_SHIFT) |
364                                                    (g << GREEN_SHIFT) | b ;
365                     }
366                     else {
367                         // Frame maximize and minimize buttons
368                         // have transparent pixels with alpha
369                         // set to FF and nontransparent pixels have zero alpha.
370                         pixel |= 0xFF000000;
371                     }
372                 }
373                 *dst++ = pixel;
374             }
375             dst += offsetToNextLine;
376         }
377     }
378     else if (transparent) {
379          for (int i=0;i<h;i++) {
380              for (int j=0;j<w;j++) {
381                  pixel = *src++;
382                  if (pixel == 0) {
383                      *dst++ = 0;
384                  }
385                  else {
386                      *dst++ = 0xFF000000 | pixel;
387                  }
388              }
389              dst += offsetToNextLine;
390          }
391      }
392      else {
393          for (int i=0;i<h;i++) {
394              for (int j=0;j<w;j++) {
395                  pixel = *src++;
396                  *dst++ = 0xFF000000 | pixel;
397              }
398              dst += offsetToNextLine;
399          }
400      }
401 
402 }
403 
404 
405 
406 /*
407  * Class:     sun_awt_windows_ThemeReader
408  * Method:    paintBackground
409  * Signature: ([IJIIIIIII)V
410  */
Java_sun_awt_windows_ThemeReader_paintBackground(JNIEnv * env,jclass klass,jintArray array,jlong theme,jint part,jint state,jint x,jint y,jint w,jint h,jint stride)411 JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
412   (JNIEnv *env, jclass klass, jintArray array, jlong theme, jint part, jint state,
413     jint x, jint y, jint w, jint h, jint stride) {
414 
415     int *pDstBits=NULL;
416     int *pSrcBits=NULL;
417     HDC memDC,defaultDC;
418     HBITMAP hDibSection = NULL;
419     RECT rect;
420     BITMAPINFO bmi;
421     HTHEME hTheme = (HTHEME) theme;
422 
423     DTRACE_PRINTLN3("Java_sun_awt_windows_ThemeReader_paintButtonBackground w=%d h=%d\n stride=%d\n",w,h,stride);
424 
425     if (hTheme == NULL) {
426         JNU_ThrowInternalError(env, "HTHEME is null");
427         return;
428     }
429 
430     defaultDC = GetDC(NULL);
431 
432     memDC = CreateCompatibleDC(defaultDC);
433 
434     static const int BITS_PER_PIXEL = 32;
435 
436     ZeroMemory(&bmi,sizeof(BITMAPINFO));
437     bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
438     bmi.bmiHeader.biWidth = w;
439     bmi.bmiHeader.biHeight = -h;
440     bmi.bmiHeader.biPlanes = 1;
441     bmi.bmiHeader.biBitCount = BITS_PER_PIXEL;
442     bmi.bmiHeader.biCompression = BI_RGB;
443     bmi.bmiHeader.biSizeImage = w * h * (BITS_PER_PIXEL>>3);
444 
445 
446     hDibSection = ::CreateDIBSection(memDC, (BITMAPINFO*) &bmi,
447             DIB_RGB_COLORS, (void **) &pSrcBits,
448             NULL, 0);
449     if (hDibSection == NULL) {
450         DTRACE_PRINTLN("Error creating DIB section");
451         ReleaseDC(NULL,defaultDC);
452         return;
453     }
454 
455     SelectObject(memDC,hDibSection);
456 
457     rect.left = 0;
458     rect.top = 0;
459     rect.bottom = h;
460     rect.right = w;
461 
462     ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h);
463 
464     HRESULT hres = DrawThemeBackground(hTheme, memDC, part, state, &rect, NULL);
465     assert_result(hres, env);
466     if (SUCCEEDED(hres)) {
467         // Make sure GDI is done.
468         GdiFlush();
469         // Copy the resulting pixels to our Java BufferedImage.
470         pDstBits = (int *)env->GetPrimitiveArrayCritical(array, 0);
471         BOOL transparent = FALSE;
472         transparent = IsThemeBackgroundPartiallyTransparent(hTheme,part,state);
473         copyDIBToBufferedImage(pDstBits, pSrcBits, transparent, w, h, stride);
474         env->ReleasePrimitiveArrayCritical(array, pDstBits, 0);
475     }
476 
477     // Delete resources.
478     DeleteObject(hDibSection);
479     DeleteDC(memDC);
480     ReleaseDC(NULL,defaultDC);
481 }
482 
newInsets(JNIEnv * env,jint top,jint left,jint bottom,jint right)483 jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) {
484     if (env->EnsureLocalCapacity(2) < 0) {
485         return NULL;
486     }
487 
488     static jclass insetsClassID = NULL;
489 
490     if (insetsClassID == NULL) {
491         jclass insetsClassIDLocal = env->FindClass("java/awt/Insets");
492         CHECK_NULL_RETURN(insetsClassIDLocal, NULL);
493         insetsClassID = (jclass)env->NewGlobalRef(insetsClassIDLocal);
494         env->DeleteLocalRef(insetsClassIDLocal);
495     }
496 
497     jobject insets = env->NewObject(insetsClassID,
498         AwtToolkit::insetsMID,
499         top, left, bottom, right);
500 
501     if (safe_ExceptionOccurred(env)) {
502         env->ExceptionDescribe();
503         env->ExceptionClear();
504     }
505 
506     return insets;
507 }
508 
509 /*
510  * Class:     sun_awt_windows_ThemeReader
511  * Method:    getThemeMargins
512  * Signature: (JIII)Ljava/awt/Insets;
513  */
Java_sun_awt_windows_ThemeReader_getThemeMargins(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint property)514 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getThemeMargins
515 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint property) {
516     MARGINS margins;
517     HTHEME hTheme = (HTHEME) theme;
518 
519     if (hTheme != NULL) {
520         HRESULT hres = GetThemeMargins(hTheme, NULL, part, state, property, NULL, &margins);
521         assert_result(hres, env);
522         if (FAILED(hres)) {
523             return NULL;
524         }
525 
526         return newInsets(env,
527                 margins.cyTopHeight,
528                 margins.cxLeftWidth, margins.cyBottomHeight, margins.cxRightWidth);
529     }
530     return NULL;
531 }
532 
533 /*
534  * Class: sun_awt_windows_ThemeReader
535  * Method: isThemePartDefined
536  * Signature: (JII)Z
537  */
Java_sun_awt_windows_ThemeReader_isThemePartDefined(JNIEnv * env,jclass klass,jlong theme,jint part,jint state)538 JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_isThemePartDefined
539 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state) {
540     HTHEME hTheme = (HTHEME) theme;
541     return JNI_IS_TRUE(IsThemePartDefined(hTheme, part, state));
542 }
543 
544 /*
545  * Class:     sun_awt_windows_ThemeReader
546  * Method:    getColor
547  * Signature: (JIII)Ljava/awt/Color;
548  */
Java_sun_awt_windows_ThemeReader_getColor(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint type)549 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getColor
550 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint type) {
551 
552     HTHEME hTheme = (HTHEME) theme;
553 
554     if (hTheme != NULL) {
555         COLORREF color=0;
556 
557         if (GetThemeColor(hTheme, part, state, type, &color) != S_OK) {
558             return NULL;
559         }
560 
561         if (env->EnsureLocalCapacity(1) < 0) {
562             return NULL;
563         }
564 
565         static jmethodID colorMID = NULL;
566         static jclass colorClassID = NULL;
567 
568         if (colorClassID == NULL) {
569             jclass colorClassIDLocal = env->FindClass("java/awt/Color");
570             CHECK_NULL_RETURN(colorClassIDLocal, NULL);
571             colorClassID = (jclass)env->NewGlobalRef(colorClassIDLocal);
572             env->DeleteLocalRef(colorClassIDLocal);
573         }
574 
575         if (colorMID == NULL) {
576             colorMID = env->GetMethodID(colorClassID, "<init>", "(III)V");
577             CHECK_NULL_RETURN(colorMID, NULL);
578         }
579         jobject colorObj = env->NewObject(colorClassID,
580                 colorMID, GetRValue(color), GetGValue(color),GetBValue(color));
581 
582         if (safe_ExceptionOccurred(env)) {
583             env->ExceptionDescribe();
584             env->ExceptionClear();
585         }
586 
587         return colorObj;
588     }
589     return NULL;
590 }
591 
592 /*
593  * Class:     sun_awt_windows_ThemeReader
594  * Method:    getInt
595  * Signature: (JIII)I
596  */
Java_sun_awt_windows_ThemeReader_getInt(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint prop)597 JNIEXPORT jint JNICALL Java_sun_awt_windows_ThemeReader_getInt
598 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint prop) {
599 
600     HTHEME hTheme = (HTHEME) theme;
601     int retVal = -1;
602     if (hTheme != NULL) {
603         HRESULT hres = GetThemeInt(hTheme, part, state, prop, &retVal);
604         assert_result(hres, env);
605     }
606     return retVal;
607 }
608 
609 /*
610  * Class:     sun_awt_windows_ThemeReader
611  * Method:    getEnum
612  * Signature: (JIII)I
613  */
Java_sun_awt_windows_ThemeReader_getEnum(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint prop)614 JNIEXPORT jint JNICALL Java_sun_awt_windows_ThemeReader_getEnum
615 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint prop) {
616     HTHEME hTheme = (HTHEME) theme;
617     int retVal = -1;
618     if (hTheme != NULL) {
619         HRESULT hres = GetThemeEnumValue(hTheme, part, state, prop, &retVal);
620         assert_result(hres, env);
621     }
622     return retVal;
623 }
624 
625 /*
626  * Class:     sun_awt_windows_ThemeReader
627  * Method:    getBoolean
628  * Signature: (JIII)Z
629  */
Java_sun_awt_windows_ThemeReader_getBoolean(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint prop)630 JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_getBoolean
631 (JNIEnv *env, jclass klass, jlong  theme, jint part, jint state, jint prop) {
632     HTHEME hTheme = (HTHEME) theme;
633     BOOL retVal = FALSE;
634     if (hTheme != NULL) {
635         HRESULT hres = GetThemeBool(hTheme, part, state, prop, &retVal);
636         assert_result(hres, env);
637     }
638     return JNI_IS_TRUE(retVal);
639 }
640 
641 /*
642  * Class:     sun_awt_windows_ThemeReader
643  * Method:    getSysBoolean
644  * Signature: (JI)Z
645  */
Java_sun_awt_windows_ThemeReader_getSysBoolean(JNIEnv * env,jclass klass,jlong theme,jint prop)646 JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_getSysBoolean
647 (JNIEnv *env, jclass klass, jlong  theme, jint prop) {
648     HTHEME hTheme = (HTHEME)theme;
649     if (hTheme != NULL) {
650         return JNI_IS_TRUE(GetThemeSysBool(hTheme, prop));
651     }
652     return JNI_FALSE;
653 }
654 
655 /*
656  * Class:     sun_awt_windows_ThemeReader
657  * Method:    getPoint
658  * Signature: (JIII)Ljava/awt/Point;
659  */
Java_sun_awt_windows_ThemeReader_getPoint(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint prop)660 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPoint
661 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint prop) {
662     HTHEME hTheme = (HTHEME) theme;
663     POINT point;
664 
665     if (hTheme != NULL) {
666         if (GetThemePosition(hTheme, part, state, prop, &point) != S_OK) {
667             return NULL;
668         }
669 
670         if (env->EnsureLocalCapacity(2) < 0) {
671             return NULL;
672         }
673 
674         static jmethodID pointMID = NULL;
675         static jclass pointClassID = NULL;
676 
677         if (pointClassID == NULL) {
678             jclass pointClassIDLocal = env->FindClass("java/awt/Point");
679             CHECK_NULL_RETURN(pointClassIDLocal, NULL);
680             pointClassID = (jclass)env->NewGlobalRef(pointClassIDLocal);
681             env->DeleteLocalRef(pointClassIDLocal);
682         }
683 
684         if (pointMID == NULL) {
685             pointMID = env->GetMethodID(pointClassID, "<init>", "(II)V");
686             CHECK_NULL_RETURN(pointMID, NULL);
687         }
688         jobject pointObj = env->NewObject(pointClassID, pointMID, point.x, point.y);
689 
690         if (safe_ExceptionOccurred(env)) {
691             env->ExceptionDescribe();
692             env->ExceptionClear();
693         }
694 
695         return pointObj;
696     }
697     return NULL;
698 }
699 
700 /*
701  * Class:     sun_awt_windows_ThemeReader
702  * Method:    getPosition
703  * Signature: (JIII)Ljava/awt/Dimension;
704  */
Java_sun_awt_windows_ThemeReader_getPosition(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint prop)705 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPosition
706 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint prop) {
707 
708     HTHEME hTheme = (HTHEME) theme;
709     if (hTheme != NULL) {
710 
711         POINT point;
712 
713         HRESULT hres = GetThemePosition(hTheme, part, state, prop, &point);
714         assert_result(hres, env);
715         if (FAILED(hres)) {
716             return NULL;
717         }
718 
719 
720         if (env->EnsureLocalCapacity(2) < 0) {
721             return NULL;
722         }
723 
724         static jmethodID dimMID = NULL;
725         static jclass dimClassID = NULL;
726         if (dimClassID == NULL) {
727             jclass dimClassIDLocal = env->FindClass("java/awt/Dimension");
728             CHECK_NULL_RETURN(dimClassIDLocal, NULL);
729             dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal);
730             env->DeleteLocalRef(dimClassIDLocal);
731         }
732         if (dimMID == NULL) {
733             dimMID = env->GetMethodID(dimClassID, "<init>", "(II)V");
734             CHECK_NULL_RETURN(dimMID, NULL);
735         }
736         jobject dimObj = env->NewObject(dimClassID, dimMID, point.x, point.y);
737 
738         if (safe_ExceptionOccurred(env)) {
739             env->ExceptionDescribe();
740             env->ExceptionClear();
741         }
742 
743         return dimObj;
744     }
745     return NULL;
746 }
747 
748 /*
749  * Class:     sun_awt_windows_ThemeReader
750  * Method:    getPartSize
751  * Signature: (JII)Ljava/awt/Dimension;
752  */
Java_sun_awt_windows_ThemeReader_getPartSize(JNIEnv * env,jclass klass,jlong theme,jint part,jint state)753 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize
754 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state) {
755     if (theme != NULL) {
756         SIZE size;
757 
758         if (SUCCEEDED(GetThemePartSize((HTHEME)theme, NULL, part, state,
759            NULL, TS_TRUE, &size)) && (env->EnsureLocalCapacity(2) >= 0)) {
760 
761             static jmethodID dimMID = NULL;
762             static jclass dimClassID = NULL;
763             if (dimClassID == NULL) {
764                 jclass dimClassIDLocal = env->FindClass("java/awt/Dimension");
765                 CHECK_NULL_RETURN(dimClassIDLocal, NULL);
766                 dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal);
767                 env->DeleteLocalRef(dimClassIDLocal);
768             }
769             if (dimMID == NULL) {
770                 dimMID = env->GetMethodID(dimClassID, "<init>", "(II)V");
771                 CHECK_NULL_RETURN(dimMID, NULL);
772             }
773             jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
774             if (safe_ExceptionOccurred(env)) {
775                 env->ExceptionDescribe();
776                 env->ExceptionClear();
777             }
778 
779             return dimObj;
780         }
781     }
782     return NULL;
783 }
784 
785 /*
786  * Class:     sun_awt_windows_ThemeReader
787  * Method:    getThemeBackgroundContentMargins
788  * Signature: (JIIII)Ljava/awt/Insets;
789  */
Java_sun_awt_windows_ThemeReader_getThemeBackgroundContentMargins(JNIEnv * env,jclass klass,jlong hTheme,jint part,jint state,jint boundingWidth,jint boundingHeight)790 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getThemeBackgroundContentMargins
791 (JNIEnv *env, jclass klass, jlong hTheme, jint part, jint state,
792 jint boundingWidth, jint boundingHeight) {
793     if (hTheme != NULL) {
794         RECT boundingRect;
795         boundingRect.left = 0;
796         boundingRect.top = 0;
797         boundingRect.right = boundingWidth;
798         boundingRect.bottom = boundingHeight;
799         RECT contentRect;
800         if (SUCCEEDED(GetThemeBackgroundContentRect((HTHEME) hTheme, NULL, part,
801                                                     state, &boundingRect,
802                                                     &contentRect))) {
803             return newInsets(env,
804                              contentRect.top, contentRect.left,
805                              boundingHeight - contentRect.bottom,
806                              boundingWidth - contentRect.right);
807         }
808     }
809     return NULL;
810 }
811 
812 /*
813  * Class:     sun_awt_windows_ThemeReader
814  * Method:    getThemeTransitionDuration
815  * Signature: (JIIII)J
816  */
817 JNIEXPORT jlong JNICALL
Java_sun_awt_windows_ThemeReader_getThemeTransitionDuration(JNIEnv * env,jclass klass,jlong theme,jint part,jint stateFrom,jint stateTo,jint propId)818 Java_sun_awt_windows_ThemeReader_getThemeTransitionDuration
819 (JNIEnv *env, jclass klass, jlong theme, jint part, jint stateFrom,
820  jint stateTo, jint propId) {
821     jlong rv = -1;
822     if (GetThemeTransitionDuration != NULL) {
823         DWORD duration = 0;
824         if (SUCCEEDED(GetThemeTransitionDuration((HTHEME) theme, part,
825                                       stateFrom, stateTo, propId, &duration))) {
826             rv = duration;
827         }
828     }
829     return rv;
830 }
831 
832 /*
833  * Class:     sun_awt_windows_ThemeReader
834  * Method:    isGetThemeTransitionDurationDefined
835  * Signature: ()Z
836  */
837 JNIEXPORT jboolean JNICALL
Java_sun_awt_windows_ThemeReader_isGetThemeTransitionDurationDefined(JNIEnv * env,jclass klass)838 Java_sun_awt_windows_ThemeReader_isGetThemeTransitionDurationDefined
839 (JNIEnv *env, jclass klass) {
840     return (GetThemeTransitionDuration != NULL) ? JNI_TRUE : JNI_FALSE;
841 }
842