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 DWORD fret= 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 if (fret != 0) {
265 DTRACE_PRINTLN3("Error: hres=0x%x lastError=0x%x %s\n", hres,
266 lastError, msgBuffer);
267 LocalFree(msgBuffer);
268 } else {
269 DTRACE_PRINTLN2("Error: hres=0x%x lastError=0x%x \n", hres,
270 lastError);
271 }
272 }
273 }
274 #endif
275 }
276
277
278 /*
279 * Class: sun_awt_windows_ThemeReader
280 * Method: openTheme
281 * Signature: (Ljava/lang/String;)J
282 */
Java_sun_awt_windows_ThemeReader_openTheme(JNIEnv * env,jclass klass,jstring widget)283 JNIEXPORT jlong JNICALL Java_sun_awt_windows_ThemeReader_openTheme
284 (JNIEnv *env, jclass klass, jstring widget) {
285
286 LPCTSTR str = (LPCTSTR) JNU_GetStringPlatformChars(env, widget, NULL);
287 if (str == NULL) {
288 JNU_ThrowOutOfMemoryError(env, 0);
289 return 0;
290 }
291 // We need to open the Theme on a Window that will stick around.
292 // The best one for that purpose is the Toolkit window.
293 HTHEME htheme = OpenThemeData(AwtToolkit::GetInstance().GetHWnd(), str);
294 JNU_ReleaseStringPlatformChars(env, widget, str);
295 return (jlong) htheme;
296 }
297
298 /*
299 * Class: sun_awt_windows_ThemeReader
300 * Method: setWindowTheme
301 * Signature: (Ljava/lang/String;)V
302 */
Java_sun_awt_windows_ThemeReader_setWindowTheme(JNIEnv * env,jclass klass,jstring subAppName)303 JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_setWindowTheme
304 (JNIEnv *env, jclass klass, jstring subAppName) {
305
306 LPCTSTR str = NULL;
307 if (subAppName != NULL) {
308 str = (LPCTSTR) JNU_GetStringPlatformChars(env, subAppName, NULL);
309 }
310 // We need to set the Window theme on the same theme that we opened it with.
311 HRESULT hres = SetWindowTheme(AwtToolkit::GetInstance().GetHWnd(), str, NULL);
312 assert_result(hres, env);
313 if (subAppName != NULL) {
314 JNU_ReleaseStringPlatformChars(env, subAppName, str);
315 }
316 }
317
318 /*
319 * Class: sun_awt_windows_ThemeReader
320 * Method: closeTheme
321 * Signature: (J)V
322 */
Java_sun_awt_windows_ThemeReader_closeTheme(JNIEnv * env,jclass klass,jlong theme)323 JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_closeTheme
324 (JNIEnv *env, jclass klass, jlong theme) {
325
326 HRESULT hres = CloseThemeData((HTHEME)theme);
327 assert_result(hres, env);
328 }
329
copyDIBToBufferedImage(int * pDstBits,int * pSrcBits,BOOL transparent,int w,int h,int stride)330 static void copyDIBToBufferedImage(int *pDstBits, int *pSrcBits,
331 BOOL transparent, int w, int h, int stride) {
332
333 int offsetToNextLine = stride - w;
334 int *dst = pDstBits;
335 int *src = pSrcBits;
336 double alphaScale;
337 int r,g,b,a;
338 int pixel;
339
340 BOOL translucent = FALSE;
341
342 for (int i=0;i<h;i++) {
343 for (int j=0;j<w;j++) {
344 pixel = *src++;
345 a = (pixel & ALPHA_MASK) >> ALPHA_SHIFT;
346 if ((a != 0) && (a != 255)) {
347 translucent = TRUE;
348 break;
349 }
350 }
351 if (translucent) break;
352 }
353 src = pSrcBits;
354
355 if (translucent) {
356 for (int i=0;i<h;i++) {
357 for (int j=0;j<w;j++) {
358 pixel = *src++;
359 if (pixel != 0) {
360 // The UxTheme API seems to do the blending and
361 // premultiply the resulting values.
362 // so we have to divide by the alpha to get the
363 // original component values.
364 a = (pixel & ALPHA_MASK) >> ALPHA_SHIFT;
365 if ((a != 255) && (a != 0)) {
366 r = (pixel & RED_MASK) >> RED_SHIFT;
367 g = (pixel & GREEN_MASK) >> GREEN_SHIFT;
368 b = (pixel & BLUE_MASK);
369 alphaScale = 255.0 / a;
370 r = (int) ((double) r * alphaScale);
371 if (r > 255) r = 255;
372 g = (int) ((double) g * alphaScale);
373 if (g > 255) g = 255;
374 b = (int) ((double) b * alphaScale);
375 if (b > 255) b = 255;
376 pixel = (a << ALPHA_SHIFT) | (r << RED_SHIFT) |
377 (g << GREEN_SHIFT) | b ;
378 }
379 else {
380 // Frame maximize and minimize buttons
381 // have transparent pixels with alpha
382 // set to FF and nontransparent pixels have zero alpha.
383 pixel |= 0xFF000000;
384 }
385 }
386 *dst++ = pixel;
387 }
388 dst += offsetToNextLine;
389 }
390 }
391 else if (transparent) {
392 for (int i=0;i<h;i++) {
393 for (int j=0;j<w;j++) {
394 pixel = *src++;
395 if (pixel == 0) {
396 *dst++ = 0;
397 }
398 else {
399 *dst++ = 0xFF000000 | pixel;
400 }
401 }
402 dst += offsetToNextLine;
403 }
404 }
405 else {
406 for (int i=0;i<h;i++) {
407 for (int j=0;j<w;j++) {
408 pixel = *src++;
409 *dst++ = 0xFF000000 | pixel;
410 }
411 dst += offsetToNextLine;
412 }
413 }
414
415 }
416
417
418
419 /*
420 * Class: sun_awt_windows_ThemeReader
421 * Method: paintBackground
422 * Signature: ([IJIIIIIII)V
423 */
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)424 JNIEXPORT void JNICALL Java_sun_awt_windows_ThemeReader_paintBackground
425 (JNIEnv *env, jclass klass, jintArray array, jlong theme, jint part, jint state,
426 jint x, jint y, jint w, jint h, jint stride) {
427
428 int *pDstBits=NULL;
429 int *pSrcBits=NULL;
430 HDC memDC,defaultDC;
431 HBITMAP hDibSection = NULL;
432 RECT rect;
433 BITMAPINFO bmi;
434 HTHEME hTheme = (HTHEME) theme;
435
436 DTRACE_PRINTLN3("Java_sun_awt_windows_ThemeReader_paintButtonBackground w=%d h=%d\n stride=%d\n",w,h,stride);
437
438 if (hTheme == NULL) {
439 JNU_ThrowInternalError(env, "HTHEME is null");
440 return;
441 }
442
443 defaultDC = GetDC(NULL);
444
445 memDC = CreateCompatibleDC(defaultDC);
446
447 static const int BITS_PER_PIXEL = 32;
448
449 ZeroMemory(&bmi,sizeof(BITMAPINFO));
450 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
451 bmi.bmiHeader.biWidth = w;
452 bmi.bmiHeader.biHeight = -h;
453 bmi.bmiHeader.biPlanes = 1;
454 bmi.bmiHeader.biBitCount = BITS_PER_PIXEL;
455 bmi.bmiHeader.biCompression = BI_RGB;
456 bmi.bmiHeader.biSizeImage = w * h * (BITS_PER_PIXEL>>3);
457
458
459 hDibSection = ::CreateDIBSection(memDC, (BITMAPINFO*) &bmi,
460 DIB_RGB_COLORS, (void **) &pSrcBits,
461 NULL, 0);
462 if (hDibSection == NULL) {
463 DTRACE_PRINTLN("Error creating DIB section");
464 ReleaseDC(NULL,defaultDC);
465 return;
466 }
467
468 SelectObject(memDC,hDibSection);
469
470 rect.left = 0;
471 rect.top = 0;
472 rect.bottom = h;
473 rect.right = w;
474
475 ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h);
476
477 HRESULT hres = DrawThemeBackground(hTheme, memDC, part, state, &rect, NULL);
478 assert_result(hres, env);
479 if (SUCCEEDED(hres)) {
480 // Make sure GDI is done.
481 GdiFlush();
482 // Copy the resulting pixels to our Java BufferedImage.
483 pDstBits = (int *)env->GetPrimitiveArrayCritical(array, 0);
484 BOOL transparent = FALSE;
485 transparent = IsThemeBackgroundPartiallyTransparent(hTheme,part,state);
486 copyDIBToBufferedImage(pDstBits, pSrcBits, transparent, w, h, stride);
487 env->ReleasePrimitiveArrayCritical(array, pDstBits, 0);
488 }
489
490 // Delete resources.
491 DeleteObject(hDibSection);
492 DeleteDC(memDC);
493 ReleaseDC(NULL,defaultDC);
494 }
495
newInsets(JNIEnv * env,jint top,jint left,jint bottom,jint right)496 jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) {
497 if (env->EnsureLocalCapacity(2) < 0) {
498 return NULL;
499 }
500
501 static jclass insetsClassID = NULL;
502
503 if (insetsClassID == NULL) {
504 jclass insetsClassIDLocal = env->FindClass("java/awt/Insets");
505 CHECK_NULL_RETURN(insetsClassIDLocal, NULL);
506 insetsClassID = (jclass)env->NewGlobalRef(insetsClassIDLocal);
507 env->DeleteLocalRef(insetsClassIDLocal);
508 }
509
510 jobject insets = env->NewObject(insetsClassID,
511 AwtToolkit::insetsMID,
512 top, left, bottom, right);
513
514 if (safe_ExceptionOccurred(env)) {
515 env->ExceptionDescribe();
516 env->ExceptionClear();
517 }
518
519 return insets;
520 }
521
522 /*
523 * Class: sun_awt_windows_ThemeReader
524 * Method: getThemeMargins
525 * Signature: (JIII)Ljava/awt/Insets;
526 */
Java_sun_awt_windows_ThemeReader_getThemeMargins(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint property)527 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getThemeMargins
528 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint property) {
529 MARGINS margins;
530 HTHEME hTheme = (HTHEME) theme;
531
532 if (hTheme != NULL) {
533 HRESULT hres = GetThemeMargins(hTheme, NULL, part, state, property, NULL, &margins);
534 assert_result(hres, env);
535 if (FAILED(hres)) {
536 return NULL;
537 }
538
539 return newInsets(env,
540 margins.cyTopHeight,
541 margins.cxLeftWidth, margins.cyBottomHeight, margins.cxRightWidth);
542 }
543 return NULL;
544 }
545
546 /*
547 * Class: sun_awt_windows_ThemeReader
548 * Method: isThemePartDefined
549 * Signature: (JII)Z
550 */
Java_sun_awt_windows_ThemeReader_isThemePartDefined(JNIEnv * env,jclass klass,jlong theme,jint part,jint state)551 JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_isThemePartDefined
552 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state) {
553 HTHEME hTheme = (HTHEME) theme;
554 return JNI_IS_TRUE(IsThemePartDefined(hTheme, part, state));
555 }
556
557 /*
558 * Class: sun_awt_windows_ThemeReader
559 * Method: getColor
560 * Signature: (JIII)Ljava/awt/Color;
561 */
Java_sun_awt_windows_ThemeReader_getColor(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint type)562 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getColor
563 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint type) {
564
565 HTHEME hTheme = (HTHEME) theme;
566
567 if (hTheme != NULL) {
568 COLORREF color=0;
569
570 if (GetThemeColor(hTheme, part, state, type, &color) != S_OK) {
571 return NULL;
572 }
573
574 if (env->EnsureLocalCapacity(1) < 0) {
575 return NULL;
576 }
577
578 static jmethodID colorMID = NULL;
579 static jclass colorClassID = NULL;
580
581 if (colorClassID == NULL) {
582 jclass colorClassIDLocal = env->FindClass("java/awt/Color");
583 CHECK_NULL_RETURN(colorClassIDLocal, NULL);
584 colorClassID = (jclass)env->NewGlobalRef(colorClassIDLocal);
585 env->DeleteLocalRef(colorClassIDLocal);
586 }
587
588 if (colorMID == NULL) {
589 colorMID = env->GetMethodID(colorClassID, "<init>", "(III)V");
590 CHECK_NULL_RETURN(colorMID, NULL);
591 }
592 jobject colorObj = env->NewObject(colorClassID,
593 colorMID, GetRValue(color), GetGValue(color),GetBValue(color));
594
595 if (safe_ExceptionOccurred(env)) {
596 env->ExceptionDescribe();
597 env->ExceptionClear();
598 }
599
600 return colorObj;
601 }
602 return NULL;
603 }
604
605 /*
606 * Class: sun_awt_windows_ThemeReader
607 * Method: getInt
608 * Signature: (JIII)I
609 */
Java_sun_awt_windows_ThemeReader_getInt(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint prop)610 JNIEXPORT jint JNICALL Java_sun_awt_windows_ThemeReader_getInt
611 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint prop) {
612
613 HTHEME hTheme = (HTHEME) theme;
614 int retVal = -1;
615 if (hTheme != NULL) {
616 HRESULT hres = GetThemeInt(hTheme, part, state, prop, &retVal);
617 assert_result(hres, env);
618 }
619 return retVal;
620 }
621
622 /*
623 * Class: sun_awt_windows_ThemeReader
624 * Method: getEnum
625 * Signature: (JIII)I
626 */
Java_sun_awt_windows_ThemeReader_getEnum(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint prop)627 JNIEXPORT jint JNICALL Java_sun_awt_windows_ThemeReader_getEnum
628 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint prop) {
629 HTHEME hTheme = (HTHEME) theme;
630 int retVal = -1;
631 if (hTheme != NULL) {
632 HRESULT hres = GetThemeEnumValue(hTheme, part, state, prop, &retVal);
633 assert_result(hres, env);
634 }
635 return retVal;
636 }
637
638 /*
639 * Class: sun_awt_windows_ThemeReader
640 * Method: getBoolean
641 * Signature: (JIII)Z
642 */
Java_sun_awt_windows_ThemeReader_getBoolean(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint prop)643 JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_getBoolean
644 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint prop) {
645 HTHEME hTheme = (HTHEME) theme;
646 BOOL retVal = FALSE;
647 if (hTheme != NULL) {
648 HRESULT hres = GetThemeBool(hTheme, part, state, prop, &retVal);
649 assert_result(hres, env);
650 }
651 return JNI_IS_TRUE(retVal);
652 }
653
654 /*
655 * Class: sun_awt_windows_ThemeReader
656 * Method: getSysBoolean
657 * Signature: (JI)Z
658 */
Java_sun_awt_windows_ThemeReader_getSysBoolean(JNIEnv * env,jclass klass,jlong theme,jint prop)659 JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_getSysBoolean
660 (JNIEnv *env, jclass klass, jlong theme, jint prop) {
661 HTHEME hTheme = (HTHEME)theme;
662 if (hTheme != NULL) {
663 return JNI_IS_TRUE(GetThemeSysBool(hTheme, prop));
664 }
665 return JNI_FALSE;
666 }
667
668 /*
669 * Class: sun_awt_windows_ThemeReader
670 * Method: getPoint
671 * Signature: (JIII)Ljava/awt/Point;
672 */
Java_sun_awt_windows_ThemeReader_getPoint(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint prop)673 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPoint
674 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint prop) {
675 HTHEME hTheme = (HTHEME) theme;
676 POINT point;
677
678 if (hTheme != NULL) {
679 if (GetThemePosition(hTheme, part, state, prop, &point) != S_OK) {
680 return NULL;
681 }
682
683 if (env->EnsureLocalCapacity(2) < 0) {
684 return NULL;
685 }
686
687 static jmethodID pointMID = NULL;
688 static jclass pointClassID = NULL;
689
690 if (pointClassID == NULL) {
691 jclass pointClassIDLocal = env->FindClass("java/awt/Point");
692 CHECK_NULL_RETURN(pointClassIDLocal, NULL);
693 pointClassID = (jclass)env->NewGlobalRef(pointClassIDLocal);
694 env->DeleteLocalRef(pointClassIDLocal);
695 }
696
697 if (pointMID == NULL) {
698 pointMID = env->GetMethodID(pointClassID, "<init>", "(II)V");
699 CHECK_NULL_RETURN(pointMID, NULL);
700 }
701 jobject pointObj = env->NewObject(pointClassID, pointMID, point.x, point.y);
702
703 if (safe_ExceptionOccurred(env)) {
704 env->ExceptionDescribe();
705 env->ExceptionClear();
706 }
707
708 return pointObj;
709 }
710 return NULL;
711 }
712
713 /*
714 * Class: sun_awt_windows_ThemeReader
715 * Method: getPosition
716 * Signature: (JIII)Ljava/awt/Dimension;
717 */
Java_sun_awt_windows_ThemeReader_getPosition(JNIEnv * env,jclass klass,jlong theme,jint part,jint state,jint prop)718 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPosition
719 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state, jint prop) {
720
721 HTHEME hTheme = (HTHEME) theme;
722 if (hTheme != NULL) {
723
724 POINT point;
725
726 HRESULT hres = GetThemePosition(hTheme, part, state, prop, &point);
727 assert_result(hres, env);
728 if (FAILED(hres)) {
729 return NULL;
730 }
731
732
733 if (env->EnsureLocalCapacity(2) < 0) {
734 return NULL;
735 }
736
737 static jmethodID dimMID = NULL;
738 static jclass dimClassID = NULL;
739 if (dimClassID == NULL) {
740 jclass dimClassIDLocal = env->FindClass("java/awt/Dimension");
741 CHECK_NULL_RETURN(dimClassIDLocal, NULL);
742 dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal);
743 env->DeleteLocalRef(dimClassIDLocal);
744 }
745 if (dimMID == NULL) {
746 dimMID = env->GetMethodID(dimClassID, "<init>", "(II)V");
747 CHECK_NULL_RETURN(dimMID, NULL);
748 }
749 jobject dimObj = env->NewObject(dimClassID, dimMID, point.x, point.y);
750
751 if (safe_ExceptionOccurred(env)) {
752 env->ExceptionDescribe();
753 env->ExceptionClear();
754 }
755
756 return dimObj;
757 }
758 return NULL;
759 }
760
rescale(SIZE * size)761 void rescale(SIZE *size) {
762 static int dpiX = -1;
763 static int dpiY = -1;
764 if (dpiX == -1 || dpiY == -1) {
765 HWND hWnd = ::GetDesktopWindow();
766 HDC hDC = ::GetDC(hWnd);
767 dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
768 dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
769 ::ReleaseDC(hWnd, hDC);
770 }
771
772 if (dpiX !=0 && dpiX != 96) {
773 float invScaleX = 96.0f / dpiX;
774 size->cx = ROUND_TO_INT(size->cx * invScaleX);
775 }
776 if (dpiY != 0 && dpiY != 96) {
777 float invScaleY = 96.0f / dpiY;
778 size->cy = ROUND_TO_INT(size->cy * invScaleY);
779 }
780 }
781
782 /*
783 * Class: sun_awt_windows_ThemeReader
784 * Method: getPartSize
785 * Signature: (JII)Ljava/awt/Dimension;
786 */
Java_sun_awt_windows_ThemeReader_getPartSize(JNIEnv * env,jclass klass,jlong theme,jint part,jint state)787 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getPartSize
788 (JNIEnv *env, jclass klass, jlong theme, jint part, jint state) {
789 if (theme != NULL) {
790 SIZE size;
791
792 if (SUCCEEDED(GetThemePartSize((HTHEME)theme, NULL, part, state,
793 NULL, TS_TRUE, &size)) && (env->EnsureLocalCapacity(2) >= 0)) {
794
795 static jmethodID dimMID = NULL;
796 static jclass dimClassID = NULL;
797 if (dimClassID == NULL) {
798 jclass dimClassIDLocal = env->FindClass("java/awt/Dimension");
799 CHECK_NULL_RETURN(dimClassIDLocal, NULL);
800 dimClassID = (jclass)env->NewGlobalRef(dimClassIDLocal);
801 env->DeleteLocalRef(dimClassIDLocal);
802 }
803 if (dimMID == NULL) {
804 dimMID = env->GetMethodID(dimClassID, "<init>", "(II)V");
805 CHECK_NULL_RETURN(dimMID, NULL);
806 }
807
808 rescale(&size);
809 jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
810 if (safe_ExceptionOccurred(env)) {
811 env->ExceptionDescribe();
812 env->ExceptionClear();
813 }
814
815 return dimObj;
816 }
817 }
818 return NULL;
819 }
820
821 /*
822 * Class: sun_awt_windows_ThemeReader
823 * Method: getThemeBackgroundContentMargins
824 * Signature: (JIIII)Ljava/awt/Insets;
825 */
Java_sun_awt_windows_ThemeReader_getThemeBackgroundContentMargins(JNIEnv * env,jclass klass,jlong hTheme,jint part,jint state,jint boundingWidth,jint boundingHeight)826 JNIEXPORT jobject JNICALL Java_sun_awt_windows_ThemeReader_getThemeBackgroundContentMargins
827 (JNIEnv *env, jclass klass, jlong hTheme, jint part, jint state,
828 jint boundingWidth, jint boundingHeight) {
829 if (hTheme != NULL) {
830 RECT boundingRect;
831 boundingRect.left = 0;
832 boundingRect.top = 0;
833 boundingRect.right = boundingWidth;
834 boundingRect.bottom = boundingHeight;
835 RECT contentRect;
836 if (SUCCEEDED(GetThemeBackgroundContentRect((HTHEME) hTheme, NULL, part,
837 state, &boundingRect,
838 &contentRect))) {
839 return newInsets(env,
840 contentRect.top, contentRect.left,
841 boundingHeight - contentRect.bottom,
842 boundingWidth - contentRect.right);
843 }
844 }
845 return NULL;
846 }
847
848 /*
849 * Class: sun_awt_windows_ThemeReader
850 * Method: getThemeTransitionDuration
851 * Signature: (JIIII)J
852 */
853 JNIEXPORT jlong JNICALL
Java_sun_awt_windows_ThemeReader_getThemeTransitionDuration(JNIEnv * env,jclass klass,jlong theme,jint part,jint stateFrom,jint stateTo,jint propId)854 Java_sun_awt_windows_ThemeReader_getThemeTransitionDuration
855 (JNIEnv *env, jclass klass, jlong theme, jint part, jint stateFrom,
856 jint stateTo, jint propId) {
857 jlong rv = -1;
858 if (GetThemeTransitionDuration != NULL) {
859 DWORD duration = 0;
860 if (SUCCEEDED(GetThemeTransitionDuration((HTHEME) theme, part,
861 stateFrom, stateTo, propId, &duration))) {
862 rv = duration;
863 }
864 }
865 return rv;
866 }
867
868 /*
869 * Class: sun_awt_windows_ThemeReader
870 * Method: isGetThemeTransitionDurationDefined
871 * Signature: ()Z
872 */
873 JNIEXPORT jboolean JNICALL
Java_sun_awt_windows_ThemeReader_isGetThemeTransitionDurationDefined(JNIEnv * env,jclass klass)874 Java_sun_awt_windows_ThemeReader_isGetThemeTransitionDurationDefined
875 (JNIEnv *env, jclass klass) {
876 return (GetThemeTransitionDuration != NULL) ? JNI_TRUE : JNI_FALSE;
877 }
878