1 /*
   2  * Copyright (c) 1999, 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 "awt.h"
  27 #include "mmsystem.h"
  28 #include "jlong.h"
  29 #include "awt_DesktopProperties.h"
  30 #include "awt_Toolkit.h"
  31 #include "sun_awt_windows_WDesktopProperties.h"
  32 #include "java_awt_Font.h"
  33 #include "awtmsg.h"
  34 #include "zmouse.h"
  35 #include <shellapi.h>
  36 #include <shlobj.h>
  37 
  38 #include "math.h"
  39 
  40 // WDesktopProperties fields
  41 jfieldID AwtDesktopProperties::pDataID = 0;
  42 jmethodID AwtDesktopProperties::setBooleanPropertyID = 0;
  43 jmethodID AwtDesktopProperties::setIntegerPropertyID = 0;
  44 jmethodID AwtDesktopProperties::setStringPropertyID = 0;
  45 jmethodID AwtDesktopProperties::setColorPropertyID = 0;
  46 jmethodID AwtDesktopProperties::setFontPropertyID = 0;
  47 jmethodID AwtDesktopProperties::setSoundPropertyID = 0;
  48 
  49 AwtDesktopProperties::AwtDesktopProperties(jobject self) {
  50     this->self = GetEnv()->NewGlobalRef(self);
  51     GetEnv()->SetLongField( self, AwtDesktopProperties::pDataID,
  52                             ptr_to_jlong(this) );
  53 }
  54 
  55 AwtDesktopProperties::~AwtDesktopProperties() {
  56     GetEnv()->DeleteGlobalRef(self);
  57 }
  58 
  59 //
  60 // Reads Windows parameters and sets the corresponding values
  61 // in WDesktopProperties
  62 //
  63 void AwtDesktopProperties::GetWindowsParameters() {
  64     if (GetEnv()->EnsureLocalCapacity(MAX_PROPERTIES) < 0) {
  65         DASSERT(0);
  66         return;
  67     }
  68     // this number defines the set of properties available, it is incremented
  69     // whenever more properties are added (in a public release of course)
  70     // for example, version 1 defines the properties available in Java SDK version 1.3.
  71     SetIntegerProperty( TEXT("win.properties.version"), AWT_DESKTOP_PROPERTIES_VERSION);
  72     GetNonClientParameters();
  73     GetIconParameters();
  74     GetColorParameters();
  75     GetCaretParameters();
  76     GetOtherParameters();
  77     GetSoundEvents();
  78     GetSystemProperties();
  79     if (IS_WINXP) {
  80         GetXPStyleProperties();
  81     }
  82 }
  83 
  84 float getInvScale() {
  85     HWND hWnd = ::GetDesktopWindow();
  86     HDC hDC = ::GetDC(hWnd);
  87     int dpi = ::GetDeviceCaps(hDC, LOGPIXELSY);
  88     ::ReleaseDC(hWnd, hDC);
  89     return dpi == 0.0f ? 1.0f : 96.0f / dpi;
  90 }
  91 
  92 int rescale(int x, float invScale){
  93     return invScale == 1.0f ? x : (int)round(x * invScale);
  94 }
  95 
  96 void AwtDesktopProperties::GetSystemProperties() {
  97     HDC dc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
  98 
  99     if (dc != NULL) {
 100         try {
 101             SetFontProperty(dc, ANSI_FIXED_FONT, TEXT("win.ansiFixed.font"));
 102             SetFontProperty(dc, ANSI_VAR_FONT, TEXT("win.ansiVar.font"));
 103             SetFontProperty(dc, DEVICE_DEFAULT_FONT, TEXT("win.deviceDefault.font"));
 104             SetFontProperty(dc, DEFAULT_GUI_FONT, TEXT("win.defaultGUI.font"), getInvScale());
 105             SetFontProperty(dc, OEM_FIXED_FONT, TEXT("win.oemFixed.font"));
 106             SetFontProperty(dc, SYSTEM_FONT, TEXT("win.system.font"));
 107             SetFontProperty(dc, SYSTEM_FIXED_FONT, TEXT("win.systemFixed.font"));
 108         }
 109         catch (std::bad_alloc&) {
 110             DeleteDC(dc);
 111             throw;
 112         }
 113         DeleteDC(dc);
 114     }
 115 }
 116 
 117 
 118 // Does the actual lookup for shell dialog font (MS Shell Dlg).  fontName
 119 // contains the name to lookup (either MS Shell Dlg or MS Shell Dlg 2) and
 120 // handle contains a reference toe the registry entry to look in.
 121 // This will return NULL or a pointer to the resolved name.
 122 // Note that it uses malloc() and returns the pointer to allocated
 123 // memory, so remember to use free() when you are done with its
 124 // result.
 125 static LPTSTR resolveShellDialogFont(LPTSTR fontName, HKEY handle) {
 126     DWORD valueType, valueSize;
 127     if (RegQueryValueEx((HKEY)handle, fontName, NULL,
 128                         &valueType, NULL, &valueSize) != 0) {
 129         // Couldn't find it
 130         return NULL;
 131     }
 132     if (valueType != REG_SZ) {
 133         // Not the expected type
 134         return NULL;
 135     }
 136     LPTSTR buffer = (LPTSTR)safe_Malloc(valueSize);
 137     if (RegQueryValueEx((HKEY)handle, fontName, NULL,
 138                         &valueType, (unsigned char *)buffer, &valueSize) != 0) {
 139         // Error fetching
 140         free(buffer);
 141         return NULL;
 142     }
 143     return buffer;
 144 }
 145 
 146 // Determines what the font MS Shell Dlg maps to.
 147 // Note that it uses malloc() and returns the pointer to allocated
 148 // memory, so remember to use free() when you are done with its
 149 // result.
 150 static LPTSTR resolveShellDialogFont() {
 151     LPTSTR subKey = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes");
 152 
 153     HKEY handle;
 154     if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &handle) != 0) {
 155         return NULL;
 156     }
 157     // Prefer MS Shell Dlg 2.
 158     LPTSTR font = resolveShellDialogFont(TEXT("MS Shell Dlg 2"), handle);
 159     if (font == NULL) {
 160         font = resolveShellDialogFont(TEXT("MS Shell Dlg"), handle);
 161     }
 162     RegCloseKey(handle);
 163     return font;
 164 }
 165 
 166 // Local function for getting values from the Windows registry
 167 // Note that it uses malloc() and returns the pointer to allocated
 168 // memory, so remember to use free() when you are done with its
 169 // result.
 170 static LPTSTR getWindowsPropFromReg(LPTSTR subKey, LPTSTR valueName, DWORD *valueType) {
 171     HKEY handle;
 172     if (RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_READ, &handle) != 0) {
 173         return NULL;
 174     }
 175     // valueSize is in bytes, while valueChar is in characters.
 176     DWORD valueSize, valueChar;
 177     if (RegQueryValueEx((HKEY)handle, valueName, NULL,
 178                         valueType, NULL, &valueSize) != 0) {
 179         RegCloseKey(handle);
 180         return NULL;
 181     }
 182     LPTSTR buffer = (LPTSTR)safe_Malloc(valueSize);
 183     if (RegQueryValueEx((HKEY)handle, valueName, NULL,
 184                         valueType, (unsigned char *)buffer, &valueSize) != 0) {
 185         free(buffer);
 186         RegCloseKey(handle);
 187         return NULL;
 188     }
 189     RegCloseKey(handle);
 190 
 191     if (*valueType == REG_EXPAND_SZ) {
 192         // Pending: buffer must be null-terminated at this point
 193         valueChar = ExpandEnvironmentStrings(buffer, NULL, 0);
 194         LPTSTR buffer2 = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, valueChar, sizeof(TCHAR));
 195         ExpandEnvironmentStrings(buffer, buffer2, valueChar);
 196         free(buffer);
 197         return buffer2;
 198     } else if (*valueType == REG_SZ) {
 199         return buffer;
 200     } else if (*valueType == REG_DWORD) {
 201         return buffer;
 202     } else {
 203         free(buffer);
 204         return NULL;
 205     }
 206 }
 207 
 208 static LPTSTR getXPStylePropFromReg(LPTSTR valueName) {
 209     DWORD valueType;
 210     return getWindowsPropFromReg(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager"),
 211                                  valueName, &valueType);
 212 }
 213 
 214 
 215 // Used in AwtMenuItem to determine the color of top menus,
 216 // since they depend on XP style. ThemeActive property is
 217 // '1' for XP Style, '0' for Windows classic style.
 218 BOOL AwtDesktopProperties::IsXPStyle() {
 219     LPTSTR style = getXPStylePropFromReg(TEXT("ThemeActive"));
 220     BOOL result = (style != NULL && *style == _T('1'));
 221     free(style);
 222     return result;
 223 }
 224 
 225 void AwtDesktopProperties::GetXPStyleProperties() {
 226     LPTSTR value;
 227 
 228     value = getXPStylePropFromReg(TEXT("ThemeActive"));
 229     try {
 230         SetBooleanProperty(TEXT("win.xpstyle.themeActive"), (value != NULL && *value == _T('1')));
 231         if (value != NULL) {
 232             free(value);
 233             value = NULL;
 234         }
 235         value = getXPStylePropFromReg(TEXT("DllName"));
 236         if (value != NULL) {
 237             SetStringProperty(TEXT("win.xpstyle.dllName"), value);
 238             free(value);
 239             value = NULL;
 240         }
 241         value = getXPStylePropFromReg(TEXT("SizeName"));
 242         if (value != NULL) {
 243             SetStringProperty(TEXT("win.xpstyle.sizeName"), value);
 244             free(value);
 245             value = NULL;
 246         }
 247         value = getXPStylePropFromReg(TEXT("ColorName"));
 248         if (value != NULL) {
 249             SetStringProperty(TEXT("win.xpstyle.colorName"), value);
 250             free(value);
 251         }
 252     }
 253     catch (std::bad_alloc&) {
 254         if (value != NULL) {
 255             free(value);
 256         }
 257         throw;
 258     }
 259 }
 260 
 261 
 262 void AwtDesktopProperties::GetNonClientParameters() {
 263     //
 264     // general window properties
 265     //
 266     NONCLIENTMETRICS    ncmetrics;
 267 
 268     // Fix for 6944516: specify correct size for ncmetrics on WIN2K/XP
 269     // Microsoft recommend to subtract the size of  'iPaddedBorderWidth' field
 270     // when running on XP. However this can't be referenced at compile time
 271     // with the older SDK, so there use 'lfMessageFont' plus its size.
 272     if (!IS_WINVISTA) {
 273 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
 274         ncmetrics.cbSize = offsetof(NONCLIENTMETRICS, iPaddedBorderWidth);
 275 #else
 276         ncmetrics.cbSize = offsetof(NONCLIENTMETRICS,lfMessageFont) + sizeof(LOGFONT);
 277 #endif
 278     } else {
 279         ncmetrics.cbSize = sizeof(ncmetrics);
 280     }
 281     VERIFY( SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncmetrics.cbSize, &ncmetrics, FALSE) );
 282 
 283     float invScale = getInvScale();
 284 
 285     SetFontProperty(TEXT("win.frame.captionFont"), ncmetrics.lfCaptionFont, invScale);
 286     SetIntegerProperty(TEXT("win.frame.captionHeight"), rescale(ncmetrics.iCaptionHeight, invScale));
 287     SetIntegerProperty(TEXT("win.frame.captionButtonWidth"), rescale(ncmetrics.iCaptionWidth, invScale));
 288     SetIntegerProperty(TEXT("win.frame.captionButtonHeight"), rescale(ncmetrics.iCaptionHeight, invScale));
 289     SetFontProperty(TEXT("win.frame.smallCaptionFont"), ncmetrics.lfSmCaptionFont, invScale);
 290     SetIntegerProperty(TEXT("win.frame.smallCaptionHeight"), rescale(ncmetrics.iSmCaptionHeight, invScale));
 291     SetIntegerProperty(TEXT("win.frame.smallCaptionButtonWidth"), rescale(ncmetrics.iSmCaptionWidth, invScale));
 292     SetIntegerProperty(TEXT("win.frame.smallCaptionButtonHeight"), rescale(ncmetrics.iSmCaptionHeight, invScale));
 293     SetIntegerProperty(TEXT("win.frame.sizingBorderWidth"), rescale(ncmetrics.iBorderWidth, 1.0f / invScale));
 294 
 295     // menu properties
 296     SetFontProperty(TEXT("win.menu.font"), ncmetrics.lfMenuFont, invScale);
 297     SetIntegerProperty(TEXT("win.menu.height"), rescale(ncmetrics.iMenuHeight, invScale));
 298     SetIntegerProperty(TEXT("win.menu.buttonWidth"), rescale(ncmetrics.iMenuWidth, invScale));
 299 
 300     // scrollbar properties
 301     SetIntegerProperty(TEXT("win.scrollbar.width"), rescale(ncmetrics.iScrollWidth, invScale));
 302     SetIntegerProperty(TEXT("win.scrollbar.height"), rescale(ncmetrics.iScrollHeight, invScale));
 303 
 304     // status bar and tooltip properties
 305     SetFontProperty(TEXT("win.status.font"), ncmetrics.lfStatusFont, invScale);
 306     SetFontProperty(TEXT("win.tooltip.font"), ncmetrics.lfStatusFont, invScale);
 307 
 308     // message box properties
 309     SetFontProperty(TEXT("win.messagebox.font"), ncmetrics.lfMessageFont, invScale);
 310 }
 311 
 312 void AwtDesktopProperties::GetIconParameters() {
 313     //
 314     // icon properties
 315     //
 316     ICONMETRICS iconmetrics;
 317 
 318     iconmetrics.cbSize = sizeof(iconmetrics);
 319     VERIFY( SystemParametersInfo(SPI_GETICONMETRICS, iconmetrics.cbSize, &iconmetrics, FALSE) );
 320 
 321     float invScale = getInvScale();
 322     SetIntegerProperty(TEXT("win.icon.hspacing"), rescale(iconmetrics.iHorzSpacing, invScale));
 323     SetIntegerProperty(TEXT("win.icon.vspacing"), rescale(iconmetrics.iVertSpacing, invScale));
 324     SetBooleanProperty(TEXT("win.icon.titleWrappingOn"), iconmetrics.iTitleWrap != 0);
 325     SetFontProperty(TEXT("win.icon.font"), iconmetrics.lfFont, invScale);
 326 }
 327 /*
 328  Windows settings for these are also in the registry
 329  They exist as system wide HKLM: HKEY_LOCAL_MACHINE and
 330  HKCU: HKEY_CURRENT_USER.
 331  HKCU\Control Panel\Desktop\FontSmoothing :  "0=OFF",  "2=ON"
 332  HKCU\Control Panel\Desktop\FontSmoothingType: 1=Standard, 2=LCD
 333  HKCU\Control Panel\Desktop\FontSmoothingGamma: 1000->2200
 334  HKCU\Control Panel\Desktop\FontSmoothingOrientation: 0=BGR, 1=RGB
 335 
 336  SystemParametersInfo supplies the first three of these but does not
 337  however expose the Orientation. That has to come from the registry.
 338 
 339  We go to some small lengths in here to not make queries we don't need.
 340  Eg if we previously were using standard font smoothing and we still are
 341  then its unlikely that any change in gamma will have occurred except
 342  by a program which changed it, and even if it did, we don't need to pick
 343  it up until someone turns on the LCD option.
 344  To do: this loop is called once per top-level window so an app with
 345  N windows will get notified N times. It would save us a small amount of
 346  redundant work if I could identify the message as being one already processed
 347  for another window.
 348  Also presumably a repaint that specifies only a partially damaged window
 349  isn't one that needs this checking.
 350 */
 351 
 352 #define FONTSMOOTHING_OFF 0
 353 #define FONTSMOOTHING_ON  1
 354 #define FONTSMOOTHING_STANDARD 1
 355 #define FONTSMOOTHING_LCD 2
 356 #define LCD_RGB_ORDER 1
 357 #define LCD_BGR_ORDER 0
 358 
 359 
 360 int GetLCDSubPixelOrder() {
 361     LONG order=99;
 362     LONG bufferSize = 4;
 363     HKEY hkeyDesktop;
 364     static LPCTSTR DESKTOPKEY = TEXT("Control Panel\\Desktop");
 365     LONG ret = RegOpenKeyEx(HKEY_CURRENT_USER,
 366                             DESKTOPKEY, 0L, KEY_READ, &hkeyDesktop);
 367     if (ret != ERROR_SUCCESS) {
 368         return LCD_RGB_ORDER;
 369     }
 370     ret = RegQueryValueEx(hkeyDesktop, TEXT("FontSmoothingOrientation"),
 371                           NULL, NULL, (LPBYTE)&order, (LPDWORD)&bufferSize);
 372     RegCloseKey(hkeyDesktop);
 373     if (ret != ERROR_SUCCESS) {
 374         return LCD_RGB_ORDER;
 375     } else {
 376         return (int)order;
 377     }
 378 }
 379 
 380 void CheckFontSmoothingSettings(HWND hWnd) {
 381     static BOOL firstTime = TRUE;
 382     static BOOL lastFontSmoothing = FALSE;
 383     static UINT lastFontSmoothingType = FONTSMOOTHING_ON;
 384     static UINT lastFontSmoothingContrast = 1400;
 385     static UINT lastSubpixelOrder = LCD_RGB_ORDER;
 386 
 387     /* If we are called with a window handle it is because there is a
 388      * message to repaint at least some part of the window which typically
 389      * is not because of the desktop font settings change. Much more likely
 390      * its a normal repaint event. If it is because of the rare settings
 391      * change in that case the update region will be the entire window.
 392      * Try to as cheaply as possible determine if this is not a call
 393      * to repaint the whole window by assuming that all such calls will
 394      * have an update region whose origin is 0,0. Only in that case will
 395      * we take the hit of checking the settings.
 396      * Thus we avoid taking the hit of the other calls for most partial
 397      * expose events, which will never be the result of changes to desktop
 398      * font settings.
 399      */
 400     if (hWnd != NULL) {
 401         RECT r;
 402         if (!::GetUpdateRect(hWnd, &r, FALSE) || r.top != 0 || r.left != 0) {
 403             return;
 404         }
 405     }
 406 
 407     BOOL fontSmoothing = FALSE, settingsChanged;
 408     UINT fontSmoothingType=0, fontSmoothingContrast=0, subPixelOrder;
 409 
 410     if (firstTime) {
 411         SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothing, 0);
 412         if (IS_WINXP) {
 413             SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0,
 414                                  &fontSmoothingType, 0);
 415             SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0,
 416                                  &fontSmoothingContrast, 0);
 417         }
 418         lastFontSmoothing = fontSmoothing;
 419         lastFontSmoothingType = fontSmoothingType;
 420         lastFontSmoothingContrast = fontSmoothingContrast;
 421         firstTime = FALSE;
 422         return;
 423     } else {
 424         SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothing, 0);
 425         settingsChanged = fontSmoothing != lastFontSmoothing;
 426         if (!settingsChanged && fontSmoothing == FONTSMOOTHING_OFF) {
 427             /* no need to check the other settings in this case. */
 428             return;
 429         }
 430         if (IS_WINXP) {
 431             SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0,
 432                                  &fontSmoothingType, 0);
 433             settingsChanged |= fontSmoothingType != lastFontSmoothingType;
 434             if (!settingsChanged &&
 435                 fontSmoothingType == FONTSMOOTHING_STANDARD) {
 436                 /* No need to check any LCD specific settings */
 437                 return;
 438             } else {
 439                 SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0,
 440                                      &fontSmoothingContrast, 0);
 441                 settingsChanged |=
 442                     fontSmoothingContrast != lastFontSmoothingContrast;
 443                 if (fontSmoothingType == FONTSMOOTHING_LCD) {
 444                     // Order is a registry entry so more expensive to check.x
 445                     subPixelOrder = GetLCDSubPixelOrder();
 446                     settingsChanged |= subPixelOrder != lastSubpixelOrder;
 447                 }
 448             }
 449         } else {
 450             if (settingsChanged && fontSmoothing == FONTSMOOTHING_ON) {
 451                 fontSmoothingType = FONTSMOOTHING_STANDARD;
 452             }
 453         }
 454     }
 455     if (settingsChanged) {
 456         /* Some of these values may not have been queried, but it shouldn't
 457          * matter as what's important is to track changes in values we are
 458          * actually using. The up-call we make here will cause the actual
 459          * values for everything to get queried and set into the desktop
 460          * properties.
 461          */
 462         lastFontSmoothing = fontSmoothing;
 463         lastFontSmoothingType = fontSmoothingType;
 464         lastFontSmoothingContrast = fontSmoothingContrast;
 465         lastSubpixelOrder = subPixelOrder;
 466 
 467         jobject peer = AwtToolkit::GetInstance().GetPeer();
 468         if (peer != NULL) {
 469             AwtToolkit::GetEnv()->CallVoidMethod(peer,
 470                                      AwtToolkit::windowsSettingChangeMID);
 471         }
 472     }
 473 }
 474 
 475 void AwtDesktopProperties::GetColorParameters() {
 476 
 477     SetColorProperty(TEXT("win.frame.activeCaptionGradientColor"),
 478                      GetSysColor(COLOR_GRADIENTACTIVECAPTION));
 479     SetColorProperty(TEXT("win.frame.inactiveCaptionGradientColor"),
 480                      GetSysColor(COLOR_GRADIENTINACTIVECAPTION));
 481     SetColorProperty(TEXT("win.item.hotTrackedColor"),
 482                      GetSysColor(COLOR_HOTLIGHT));
 483     SetColorProperty(TEXT("win.3d.darkShadowColor"), GetSysColor(COLOR_3DDKSHADOW));
 484     SetColorProperty(TEXT("win.3d.backgroundColor"), GetSysColor(COLOR_3DFACE));
 485     SetColorProperty(TEXT("win.3d.highlightColor"), GetSysColor(COLOR_3DHIGHLIGHT));
 486     SetColorProperty(TEXT("win.3d.lightColor"), GetSysColor(COLOR_3DLIGHT));
 487     SetColorProperty(TEXT("win.3d.shadowColor"), GetSysColor(COLOR_3DSHADOW));
 488     SetColorProperty(TEXT("win.button.textColor"), GetSysColor(COLOR_BTNTEXT));
 489     SetColorProperty(TEXT("win.desktop.backgroundColor"), GetSysColor(COLOR_DESKTOP));
 490     SetColorProperty(TEXT("win.frame.activeCaptionColor"), GetSysColor(COLOR_ACTIVECAPTION));
 491     SetColorProperty(TEXT("win.frame.activeBorderColor"), GetSysColor(COLOR_ACTIVEBORDER));
 492 
 493     // ?? ?? ??
 494     SetColorProperty(TEXT("win.frame.color"), GetSysColor(COLOR_WINDOWFRAME)); // ?? WHAT THE HECK DOES THIS MEAN ??
 495     // ?? ?? ??
 496 
 497     SetColorProperty(TEXT("win.frame.backgroundColor"), GetSysColor(COLOR_WINDOW));
 498     SetColorProperty(TEXT("win.frame.captionTextColor"), GetSysColor(COLOR_CAPTIONTEXT));
 499     SetColorProperty(TEXT("win.frame.inactiveBorderColor"), GetSysColor(COLOR_INACTIVEBORDER));
 500     SetColorProperty(TEXT("win.frame.inactiveCaptionColor"), GetSysColor(COLOR_INACTIVECAPTION));
 501     SetColorProperty(TEXT("win.frame.inactiveCaptionTextColor"), GetSysColor(COLOR_INACTIVECAPTIONTEXT));
 502     SetColorProperty(TEXT("win.frame.textColor"), GetSysColor(COLOR_WINDOWTEXT));
 503     SetColorProperty(TEXT("win.item.highlightColor"), GetSysColor(COLOR_HIGHLIGHT));
 504     SetColorProperty(TEXT("win.item.highlightTextColor"), GetSysColor(COLOR_HIGHLIGHTTEXT));
 505     SetColorProperty(TEXT("win.mdi.backgroundColor"), GetSysColor(COLOR_APPWORKSPACE));
 506     SetColorProperty(TEXT("win.menu.backgroundColor"), GetSysColor(COLOR_MENU));
 507     SetColorProperty(TEXT("win.menu.textColor"), GetSysColor(COLOR_MENUTEXT));
 508     // COLOR_MENUBAR is only defined on WindowsXP. Our binaries are
 509     // built on NT, hence the below ifdef.
 510 #ifndef COLOR_MENUBAR
 511 #define COLOR_MENUBAR 30
 512 #endif
 513     SetColorProperty(TEXT("win.menubar.backgroundColor"),
 514                                 GetSysColor(IS_WINXP ? COLOR_MENUBAR : COLOR_MENU));
 515     SetColorProperty(TEXT("win.scrollbar.backgroundColor"), GetSysColor(COLOR_SCROLLBAR));
 516     SetColorProperty(TEXT("win.text.grayedTextColor"), GetSysColor(COLOR_GRAYTEXT));
 517     SetColorProperty(TEXT("win.tooltip.backgroundColor"), GetSysColor(COLOR_INFOBK));
 518     SetColorProperty(TEXT("win.tooltip.textColor"), GetSysColor(COLOR_INFOTEXT));
 519 }
 520 
 521 void AwtDesktopProperties::GetOtherParameters() {
 522     // TODO BEGIN: On NT4, some setttings don't trigger WM_SETTINGCHANGE --
 523     // check whether this has been fixed on Windows 2000 and Windows 98
 524     // ECH 10/6/2000 seems to be fixed on NT4 SP5, but not on 98
 525     SetBooleanProperty(TEXT("win.frame.fullWindowDragsOn"), GetBooleanParameter(SPI_GETDRAGFULLWINDOWS));
 526     SetBooleanProperty(TEXT("win.text.fontSmoothingOn"), GetBooleanParameter(SPI_GETFONTSMOOTHING));
 527     // TODO END
 528 
 529     if (IS_WINXP) {
 530         SetIntegerProperty(TEXT("win.text.fontSmoothingType"),
 531                            GetIntegerParameter(SPI_GETFONTSMOOTHINGTYPE));
 532         SetIntegerProperty(TEXT("win.text.fontSmoothingContrast"),
 533                            GetIntegerParameter(SPI_GETFONTSMOOTHINGCONTRAST));
 534         SetIntegerProperty(TEXT("win.text.fontSmoothingOrientation"),
 535                            GetLCDSubPixelOrder());
 536     }
 537 
 538     int cxdrag = GetSystemMetrics(SM_CXDRAG);
 539     int cydrag = GetSystemMetrics(SM_CYDRAG);
 540     SetIntegerProperty(TEXT("win.drag.width"), cxdrag);
 541     SetIntegerProperty(TEXT("win.drag.height"), cydrag);
 542     SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2);
 543     SetIntegerProperty(TEXT("awt.mouse.numButtons"), AwtToolkit::GetNumberOfButtons());
 544 
 545     SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime());
 546 
 547     // BEGIN cross-platform properties
 548     // Note that these are cross-platform properties, but are being stuck into
 549     // WDesktopProperties.  WToolkit.lazilyLoadDesktopProperty() can find them,
 550     // but if a Toolkit subclass uses the desktopProperties
 551     // member, these properties won't be there. -bchristi, echawkes
 552     // This property is called "win.frame.fullWindowDragsOn" above
 553     // This is one of the properties that don't trigger WM_SETTINGCHANGE
 554     SetBooleanProperty(TEXT("awt.dynamicLayoutSupported"), GetBooleanParameter(SPI_GETDRAGFULLWINDOWS));
 555     SetBooleanProperty(TEXT("awt.wheelMousePresent"),
 556                        ::GetSystemMetrics(SM_MOUSEWHEELPRESENT));
 557 
 558     // END cross-platform properties
 559 
 560     //DWORD   menuShowDelay;
 561     //SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &menuShowDelay, 0);
 562     // SetIntegerProperty(TEXT("win.menu.showDelay"), menuShowDelay);
 563     SetBooleanProperty(TEXT("win.frame.captionGradientsOn"), GetBooleanParameter(SPI_GETGRADIENTCAPTIONS));
 564     SetBooleanProperty(TEXT("win.item.hotTrackingOn"), GetBooleanParameter(SPI_GETHOTTRACKING));
 565 
 566     SetBooleanProperty(TEXT("win.menu.keyboardCuesOn"), GetBooleanParameter(SPI_GETKEYBOARDCUES));
 567 
 568     // High contrast accessibility property
 569     HIGHCONTRAST contrast;
 570     contrast.cbSize = sizeof(HIGHCONTRAST);
 571     if (SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(HIGHCONTRAST),
 572                              &contrast, 0) != 0 &&
 573               (contrast.dwFlags & HCF_HIGHCONTRASTON) == HCF_HIGHCONTRASTON) {
 574       SetBooleanProperty(TEXT("win.highContrast.on"), TRUE);
 575     }
 576     else {
 577       SetBooleanProperty(TEXT("win.highContrast.on"), FALSE);
 578     }
 579 
 580     SHELLFLAGSTATE sfs;
 581     ::SHGetSettings(&sfs, SSF_SHOWALLOBJECTS | SSF_SHOWATTRIBCOL);
 582     if (sfs.fShowAllObjects) {
 583         SetBooleanProperty(TEXT("awt.file.showHiddenFiles"), TRUE);
 584     }
 585     else {
 586         SetBooleanProperty(TEXT("awt.file.showHiddenFiles"), FALSE);
 587     }
 588     if (sfs.fShowAttribCol) {
 589         SetBooleanProperty(TEXT("awt.file.showAttribCol"), TRUE);
 590     }
 591     else {
 592         SetBooleanProperty(TEXT("awt.file.showAttribCol"), FALSE);
 593     }
 594 
 595     LPTSTR value;
 596     DWORD valueType;
 597 
 598     // Shell Icon BPP - only honored on platforms before XP
 599     value = getWindowsPropFromReg(TEXT("Control Panel\\Desktop\\WindowMetrics"),
 600                                   TEXT("Shell Icon BPP"), &valueType);
 601 
 602     try {
 603         if (value != NULL) {
 604             if (valueType == REG_SZ) {
 605                 SetStringProperty(TEXT("win.icon.shellIconBPP"), value);
 606             }
 607             free(value);
 608             value = NULL;
 609         }
 610 
 611 
 612         // The following registry settings control the file chooser places bar
 613         // under the Windows L&F. These settings are not present by default, but
 614         // can be enabled using the TweakUI tool from Microsoft. For more info,
 615         // see http://msdn.microsoft.com/msdnmag/issues/1100/Registry/
 616 
 617         // NoPlacesBar is a REG_DWORD, with values 0 or 1
 618         value = getWindowsPropFromReg(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\comdlg32"),
 619                                       TEXT("NoPlacesBar"), &valueType);
 620         if (value != NULL) {
 621             if (valueType == REG_DWORD) {
 622                 SetBooleanProperty(TEXT("win.comdlg.noPlacesBar"), (BOOL)((int)*value != 0));
 623             }
 624             free(value);
 625         }
 626     }
 627     catch (std::bad_alloc&) {
 628         if (value != NULL) {
 629             free(value);
 630         }
 631         throw;
 632     }
 633 
 634     LPTSTR valueName = TEXT("PlaceN");
 635     LPTSTR valueNameBuf = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (lstrlen(valueName) + 1), sizeof(TCHAR));
 636     lstrcpy(valueNameBuf, valueName);
 637 
 638     LPTSTR propKey = TEXT("win.comdlg.placesBarPlaceN");
 639 
 640     LPTSTR propKeyBuf;
 641     try {
 642         propKeyBuf = (LPTSTR)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, (lstrlen(propKey) + 1), sizeof(TCHAR));
 643     }
 644     catch (std::bad_alloc&) {
 645         free(valueNameBuf);
 646         throw;
 647     }
 648     lstrcpy(propKeyBuf, propKey);
 649 
 650     int i = 0;
 651     do {
 652         valueNameBuf[5] = _T('0' + i++);
 653         propKeyBuf[25] = valueNameBuf[5];
 654 
 655         LPTSTR key = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\comdlg32\\PlacesBar");
 656         try {
 657             value = NULL;
 658             if ((value = getWindowsPropFromReg(key, valueNameBuf, &valueType)) != NULL) {
 659                 if (valueType == REG_DWORD) {
 660                     // Value is a CSIDL
 661                     SetIntegerProperty(propKeyBuf, (int)*value);
 662                 } else {
 663                     // Value is a path
 664                     SetStringProperty(propKeyBuf, value);
 665                 }
 666                 free(value);
 667             }
 668         }
 669         catch (std::bad_alloc&) {
 670             if (value != NULL) {
 671                 free(value);
 672             }
 673             free(propKeyBuf);
 674             free(valueNameBuf);
 675             throw;
 676         }
 677     } while (value != NULL);
 678 
 679     free(propKeyBuf);
 680     free(valueNameBuf);
 681 }
 682 
 683 void AwtDesktopProperties::GetSoundEvents() {
 684     /////
 685     SetSoundProperty(TEXT("win.sound.default"), TEXT(".Default"));
 686     SetSoundProperty(TEXT("win.sound.close"), TEXT("Close"));
 687     SetSoundProperty(TEXT("win.sound.maximize"), TEXT("Maximize"));
 688     SetSoundProperty(TEXT("win.sound.minimize"), TEXT("Minimize"));
 689     SetSoundProperty(TEXT("win.sound.menuCommand"), TEXT("MenuCommand"));
 690     SetSoundProperty(TEXT("win.sound.menuPopup"), TEXT("MenuPopup"));
 691     SetSoundProperty(TEXT("win.sound.open"), TEXT("Open"));
 692     SetSoundProperty(TEXT("win.sound.restoreDown"), TEXT("RestoreDown"));
 693     SetSoundProperty(TEXT("win.sound.restoreUp"), TEXT("RestoreUp"));
 694     /////
 695     SetSoundProperty(TEXT("win.sound.asterisk"), TEXT("SystemAsterisk"));
 696     SetSoundProperty(TEXT("win.sound.exclamation"), TEXT("SystemExclamation"));
 697     SetSoundProperty(TEXT("win.sound.exit"), TEXT("SystemExit"));
 698     SetSoundProperty(TEXT("win.sound.hand"), TEXT("SystemHand"));
 699     SetSoundProperty(TEXT("win.sound.question"), TEXT("SystemQuestion"));
 700     SetSoundProperty(TEXT("win.sound.start"), TEXT("SystemStart"));
 701 }
 702 
 703 void AwtDesktopProperties::GetCaretParameters() {
 704     SetIntegerProperty(TEXT("win.caret.width"), GetIntegerParameter(SPI_GETCARETWIDTH));
 705 }
 706 
 707 BOOL AwtDesktopProperties::GetBooleanParameter(UINT spi) {
 708     BOOL        flag;
 709     SystemParametersInfo(spi, 0, &flag, 0);
 710     DASSERT(flag == TRUE || flag == FALSE); // should be simple boolean value
 711     return flag;
 712 }
 713 
 714 UINT AwtDesktopProperties::GetIntegerParameter(UINT spi) {
 715     UINT retValue;
 716     SystemParametersInfo(spi, 0, &retValue, 0);
 717     return retValue;
 718 }
 719 
 720 void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) {
 721     jstring key = JNU_NewStringPlatform(GetEnv(), propName);
 722     if (key == NULL) {
 723         throw std::bad_alloc();
 724     }
 725     jstring jValue = JNU_NewStringPlatform(GetEnv(), value);
 726     if (jValue == NULL) {
 727         GetEnv()->DeleteLocalRef(key);
 728         throw std::bad_alloc();
 729     }
 730     GetEnv()->CallVoidMethod(self,
 731                              AwtDesktopProperties::setStringPropertyID,
 732                              key, jValue);
 733     GetEnv()->DeleteLocalRef(jValue);
 734     GetEnv()->DeleteLocalRef(key);
 735 }
 736 
 737 void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) {
 738 
 739     jstring key = JNU_NewStringPlatform(GetEnv(), propName);
 740     if (key == NULL) {
 741         throw std::bad_alloc();
 742     }
 743     GetEnv()->CallVoidMethod(self,
 744                              AwtDesktopProperties::setIntegerPropertyID,
 745                              key, (jint)value);
 746     GetEnv()->DeleteLocalRef(key);
 747 }
 748 
 749 void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) {
 750     jstring key = JNU_NewStringPlatform(GetEnv(), propName);
 751     if (key == NULL) {
 752         throw std::bad_alloc();
 753     }
 754     GetEnv()->CallVoidMethod(self,
 755                              AwtDesktopProperties::setBooleanPropertyID,
 756                              key, value ? JNI_TRUE : JNI_FALSE);
 757     GetEnv()->DeleteLocalRef(key);
 758 }
 759 
 760 void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) {
 761     jstring key = JNU_NewStringPlatform(GetEnv(), propName);
 762     if (key == NULL) {
 763         throw std::bad_alloc();
 764     }
 765     GetEnv()->CallVoidMethod(self,
 766                              AwtDesktopProperties::setColorPropertyID,
 767                              key, GetRValue(value), GetGValue(value),
 768                              GetBValue(value));
 769     GetEnv()->DeleteLocalRef(key);
 770 }
 771 
 772 void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID,
 773     LPCTSTR propName) {
 774     AwtDesktopProperties::SetFontProperty(dc, fontID, propName, 1.0f);
 775 }
 776 
 777 void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID,
 778     LPCTSTR propName, float invScale) {
 779         HGDIOBJ font = GetStockObject(fontID);
 780     if (font != NULL && SelectObject(dc, font) != NULL) {
 781         int length = GetTextFace(dc, 0, NULL);
 782 
 783         if (length > 0) {
 784             LPTSTR face = new TCHAR[length];
 785 
 786             if (GetTextFace(dc, length, face) > 0) {
 787                 TEXTMETRIC metrics;
 788 
 789                 if (GetTextMetrics(dc, &metrics) > 0) {
 790                     jstring fontName = NULL;
 791                     if (!wcscmp(face, L"MS Shell Dlg")) {
 792                         // MS Shell Dlg is an indirect font name, find the
 793                         // real face name from the registry.
 794                         LPTSTR shellDialogFace = resolveShellDialogFont();
 795                         if (shellDialogFace != NULL) {
 796                             fontName = JNU_NewStringPlatform(GetEnv(),
 797                                                              shellDialogFace);
 798                             free(shellDialogFace);
 799                         }
 800                         else {
 801                             // Couldn't determine mapping for MS Shell Dlg,
 802                             // fall back to Microsoft Sans Serif
 803                             fontName = JNU_NewStringPlatform(GetEnv(),
 804                                                     L"Microsoft Sans Serif");
 805                         }
 806                     }
 807                     else {
 808                         fontName = JNU_NewStringPlatform(GetEnv(), face);
 809                     }
 810                     if (fontName == NULL) {
 811                         delete[] face;
 812                         throw std::bad_alloc();
 813                     }
 814 
 815                     jint pointSize = rescale(metrics.tmHeight -
 816                                      metrics.tmInternalLeading, invScale);
 817                     jint style = java_awt_Font_PLAIN;
 818 
 819                     if (metrics.tmWeight >= FW_BOLD) {
 820                         style =  java_awt_Font_BOLD;
 821                     }
 822                     if (metrics.tmItalic ) {
 823                         style |= java_awt_Font_ITALIC;
 824                     }
 825 
 826                     jstring key = JNU_NewStringPlatform(GetEnv(), propName);
 827                     if (key == NULL) {
 828                         GetEnv()->DeleteLocalRef(fontName);
 829                         delete[] face;
 830                         throw std::bad_alloc();
 831                     }
 832                     GetEnv()->CallVoidMethod(self,
 833                               AwtDesktopProperties::setFontPropertyID,
 834                               key, fontName, style, pointSize);
 835                     GetEnv()->DeleteLocalRef(key);
 836                     GetEnv()->DeleteLocalRef(fontName);
 837                 }
 838             }
 839             delete[] face;
 840         }
 841     }
 842 }
 843 
 844 void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & font) {
 845     AwtDesktopProperties::SetFontProperty(propName, font, 1.0f);
 846 }
 847 
 848 void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & font,
 849     float invScale) {
 850     jstring fontName;
 851     jint pointSize;
 852     jint style;
 853 
 854     fontName = JNU_NewStringPlatform(GetEnv(), font.lfFaceName);
 855     if (fontName == NULL) {
 856         throw std::bad_alloc();
 857     }
 858 #if 0
 859     HDC         hdc;
 860     int         pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY);
 861     // convert font size specified in pixels to font size in points
 862     hdc = GetDC(NULL);
 863     pointSize = (-font.lfHeight)*72/pixelsPerInch;
 864     ReleaseDC(NULL, hdc);
 865 #endif
 866     // Java uses point sizes, but assumes 1 pixel = 1 point
 867     pointSize = rescale(-font.lfHeight, invScale);
 868 
 869     // convert Windows font style to Java style
 870     style = java_awt_Font_PLAIN;
 871     DTRACE_PRINTLN1("weight=%d", font.lfWeight);
 872     if ( font.lfWeight >= FW_BOLD ) {
 873         style =  java_awt_Font_BOLD;
 874     }
 875     if ( font.lfItalic ) {
 876         style |= java_awt_Font_ITALIC;
 877     }
 878 
 879     jstring key = JNU_NewStringPlatform(GetEnv(), propName);
 880     if (key == NULL) {
 881         GetEnv()->DeleteLocalRef(fontName);
 882         throw std::bad_alloc();
 883     }
 884     GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setFontPropertyID,
 885                              key, fontName, style, pointSize);
 886     GetEnv()->DeleteLocalRef(key);
 887     GetEnv()->DeleteLocalRef(fontName);
 888 }
 889 
 890 void AwtDesktopProperties::SetSoundProperty(LPCTSTR propName, LPCTSTR winEventName) {
 891     jstring key = JNU_NewStringPlatform(GetEnv(), propName);
 892     if (key == NULL) {
 893         throw std::bad_alloc();
 894     }
 895     jstring event = JNU_NewStringPlatform(GetEnv(), winEventName);
 896     if (event == NULL) {
 897         GetEnv()->DeleteLocalRef(key);
 898         throw std::bad_alloc();
 899     }
 900     GetEnv()->CallVoidMethod(self,
 901                              AwtDesktopProperties::setSoundPropertyID,
 902                              key, event);
 903     GetEnv()->DeleteLocalRef(event);
 904     GetEnv()->DeleteLocalRef(key);
 905 }
 906 
 907 void AwtDesktopProperties::PlayWindowsSound(LPCTSTR event) {
 908     // stop any currently playing sounds
 909     ::PlaySound(NULL, NULL, SND_PURGE);
 910     // play the sound for the given event name
 911     ::PlaySound(event, NULL, SND_ASYNC|SND_ALIAS|SND_NODEFAULT);
 912 }
 913 
 914 ///////////////////////////////////////////////////////////////////////////////////////////////////
 915 
 916 static AwtDesktopProperties * GetCppThis(JNIEnv *env, jobject self) {
 917     jlong longProps = env->GetLongField(self, AwtDesktopProperties::pDataID);
 918     AwtDesktopProperties * props =
 919         (AwtDesktopProperties *)jlong_to_ptr(longProps);
 920     DASSERT( !IsBadReadPtr(props, sizeof(*props)) );
 921     return props;
 922 }
 923 
 924 JNIEXPORT void JNICALL
 925 Java_sun_awt_windows_WDesktopProperties_initIDs(JNIEnv *env, jclass cls) {
 926     TRY;
 927 
 928     AwtDesktopProperties::pDataID = env->GetFieldID(cls, "pData", "J");
 929     DASSERT(AwtDesktopProperties::pDataID != 0);
 930     CHECK_NULL(AwtDesktopProperties::pDataID);
 931 
 932     AwtDesktopProperties::setBooleanPropertyID =
 933         env->GetMethodID(cls, "setBooleanProperty", "(Ljava/lang/String;Z)V");
 934     DASSERT(AwtDesktopProperties::setBooleanPropertyID != 0);
 935     CHECK_NULL(AwtDesktopProperties::setBooleanPropertyID);
 936 
 937     AwtDesktopProperties::setIntegerPropertyID =
 938         env->GetMethodID(cls, "setIntegerProperty", "(Ljava/lang/String;I)V");
 939     DASSERT(AwtDesktopProperties::setIntegerPropertyID != 0);
 940     CHECK_NULL(AwtDesktopProperties::setIntegerPropertyID);
 941 
 942     AwtDesktopProperties::setStringPropertyID =
 943         env->GetMethodID(cls, "setStringProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
 944     DASSERT(AwtDesktopProperties::setStringPropertyID != 0);
 945     CHECK_NULL(AwtDesktopProperties::setStringPropertyID);
 946 
 947     AwtDesktopProperties::setColorPropertyID =
 948         env->GetMethodID(cls, "setColorProperty", "(Ljava/lang/String;III)V");
 949     DASSERT(AwtDesktopProperties::setColorPropertyID != 0);
 950     CHECK_NULL(AwtDesktopProperties::setColorPropertyID);
 951 
 952     AwtDesktopProperties::setFontPropertyID =
 953         env->GetMethodID(cls, "setFontProperty", "(Ljava/lang/String;Ljava/lang/String;II)V");
 954     DASSERT(AwtDesktopProperties::setFontPropertyID != 0);
 955     CHECK_NULL(AwtDesktopProperties::setFontPropertyID);
 956 
 957     AwtDesktopProperties::setSoundPropertyID =
 958         env->GetMethodID(cls, "setSoundProperty", "(Ljava/lang/String;Ljava/lang/String;)V");
 959     DASSERT(AwtDesktopProperties::setSoundPropertyID != 0);
 960     CHECK_NULL(AwtDesktopProperties::setSoundPropertyID);
 961 
 962     CATCH_BAD_ALLOC;
 963 }
 964 
 965 JNIEXPORT void JNICALL
 966 Java_sun_awt_windows_WDesktopProperties_init(JNIEnv *env, jobject self) {
 967     TRY;
 968 
 969     new AwtDesktopProperties(self);
 970 
 971     CATCH_BAD_ALLOC;
 972 }
 973 
 974 JNIEXPORT void JNICALL
 975 Java_sun_awt_windows_WDesktopProperties_getWindowsParameters(JNIEnv *env, jobject self) {
 976     TRY;
 977 
 978     GetCppThis(env, self)->GetWindowsParameters();
 979 
 980     CATCH_BAD_ALLOC;
 981 }
 982 
 983 JNIEXPORT void JNICALL
 984 Java_sun_awt_windows_WDesktopProperties_playWindowsSound(JNIEnv *env, jobject self, jstring event) {
 985     TRY;
 986 
 987     LPCTSTR winEventName;
 988     winEventName = JNU_GetStringPlatformChars(env, event, NULL);
 989     if ( winEventName == NULL ) {
 990         return;
 991     }
 992     GetCppThis(env, self)->PlayWindowsSound(winEventName);
 993     JNU_ReleaseStringPlatformChars(env, event, winEventName);
 994 
 995     CATCH_BAD_ALLOC;
 996 }