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