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