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 // 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 
 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 
 228 JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_isThemed
 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 
 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  */
 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  */
 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  */
 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 
 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  */
 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 
 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  */
 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  */
 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  */
 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  */
 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  */
 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  */
 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  */
 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  */
 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  */
 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  */
 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  */
 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
 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
 838 Java_sun_awt_windows_ThemeReader_isGetThemeTransitionDurationDefined
 839 (JNIEnv *env, jclass klass) {
 840     return (GetThemeTransitionDuration != NULL) ? JNI_TRUE : JNI_FALSE;
 841 }