/* * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #include "awt.h" #include "mmsystem.h" #include "jlong.h" #include "awt_DesktopProperties.h" #include "awt_Toolkit.h" #include "sun_awt_windows_WDesktopProperties.h" #include "java_awt_Font.h" #include "awtmsg.h" #include "zmouse.h" #include #include // WDesktopProperties fields jfieldID AwtDesktopProperties::pDataID = 0; jmethodID AwtDesktopProperties::setBooleanPropertyID = 0; jmethodID AwtDesktopProperties::setIntegerPropertyID = 0; jmethodID AwtDesktopProperties::setStringPropertyID = 0; jmethodID AwtDesktopProperties::setColorPropertyID = 0; jmethodID AwtDesktopProperties::setFontPropertyID = 0; jmethodID AwtDesktopProperties::setSoundPropertyID = 0; AwtDesktopProperties::AwtDesktopProperties(jobject self) { this->self = GetEnv()->NewGlobalRef(self); GetEnv()->SetLongField( self, AwtDesktopProperties::pDataID, ptr_to_jlong(this) ); } AwtDesktopProperties::~AwtDesktopProperties() { GetEnv()->DeleteGlobalRef(self); } // // Reads Windows parameters and sets the corresponding values // in WDesktopProperties // void AwtDesktopProperties::GetWindowsParameters() { if (GetEnv()->EnsureLocalCapacity(MAX_PROPERTIES) < 0) { DASSERT(0); return; } // this number defines the set of properties available, it is incremented // whenever more properties are added (in a public release of course) // for example, version 1 defines the properties available in Java SDK version 1.3. SetIntegerProperty( TEXT("win.properties.version"), AWT_DESKTOP_PROPERTIES_VERSION); GetNonClientParameters(); GetIconParameters(); GetColorParameters(); GetCaretParameters(); GetOtherParameters(); GetSoundEvents(); GetSystemProperties(); if (IS_WINXP) { GetXPStyleProperties(); } } void AwtDesktopProperties::GetSystemProperties() { HDC dc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); if (dc != NULL) { SetFontProperty(dc, ANSI_FIXED_FONT, TEXT("win.ansiFixed.font")); SetFontProperty(dc, ANSI_VAR_FONT, TEXT("win.ansiVar.font")); SetFontProperty(dc, DEVICE_DEFAULT_FONT, TEXT("win.deviceDefault.font")); SetFontProperty(dc, DEFAULT_GUI_FONT, TEXT("win.defaultGUI.font")); SetFontProperty(dc, OEM_FIXED_FONT, TEXT("win.oemFixed.font")); SetFontProperty(dc, SYSTEM_FONT, TEXT("win.system.font")); SetFontProperty(dc, SYSTEM_FIXED_FONT, TEXT("win.systemFixed.font")); DeleteDC(dc); } } // Does the actual lookup for shell dialog font (MS Shell Dlg). fontName // contains the name to lookup (either MS Shell Dlg or MS Shell Dlg 2) and // handle contains a reference toe the registry entry to look in. // This will return NULL or a pointer to the resolved name. // Note that it uses malloc() and returns the pointer to allocated // memory, so remember to use free() when you are done with its // result. static LPTSTR resolveShellDialogFont(LPTSTR fontName, HKEY handle) { DWORD valueType, valueSize; if (RegQueryValueEx((HKEY)handle, fontName, NULL, &valueType, NULL, &valueSize) != 0) { // Couldn't find it return NULL; } if (valueType != REG_SZ) { // Not the expected type return NULL; } LPTSTR buffer = (LPTSTR)safe_Malloc(valueSize); if (RegQueryValueEx((HKEY)handle, fontName, NULL, &valueType, (unsigned char *)buffer, &valueSize) != 0) { // Error fetching free(buffer); return NULL; } return buffer; } // Determines what the font MS Shell Dlg maps to. // Note that it uses malloc() and returns the pointer to allocated // memory, so remember to use free() when you are done with its // result. static LPTSTR resolveShellDialogFont() { LPTSTR subKey = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\FontSubstitutes"); HKEY handle; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, subKey, 0, KEY_READ, &handle) != 0) { return NULL; } // Prefer MS Shell Dlg 2. LPTSTR font = resolveShellDialogFont(TEXT("MS Shell Dlg 2"), handle); if (font == NULL) { font = resolveShellDialogFont(TEXT("MS Shell Dlg"), handle); } RegCloseKey(handle); return font; } // Local function for getting values from the Windows registry // Note that it uses malloc() and returns the pointer to allocated // memory, so remember to use free() when you are done with its // result. static LPTSTR getWindowsPropFromReg(LPTSTR subKey, LPTSTR valueName, DWORD *valueType) { HKEY handle; if (RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_READ, &handle) != 0) { return NULL; } // valueSize is in bytes, while valueChar is in characters. DWORD valueSize, valueChar; if (RegQueryValueEx((HKEY)handle, valueName, NULL, valueType, NULL, &valueSize) != 0) { RegCloseKey(handle); return NULL; } LPTSTR buffer = (LPTSTR)safe_Malloc(valueSize); if (RegQueryValueEx((HKEY)handle, valueName, NULL, valueType, (unsigned char *)buffer, &valueSize) != 0) { free(buffer); RegCloseKey(handle); return NULL; } RegCloseKey(handle); if (*valueType == REG_EXPAND_SZ) { // Pending: buffer must be null-terminated at this point valueChar = ExpandEnvironmentStrings(buffer, NULL, 0); LPTSTR buffer2 = (LPTSTR)safe_Malloc(valueChar*sizeof(TCHAR)); ExpandEnvironmentStrings(buffer, buffer2, valueChar); free(buffer); return buffer2; } else if (*valueType == REG_SZ) { return buffer; } else if (*valueType == REG_DWORD) { return buffer; } else { free(buffer); return NULL; } } static LPTSTR getXPStylePropFromReg(LPTSTR valueName) { DWORD valueType; return getWindowsPropFromReg(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager"), valueName, &valueType); } // Used in AwtMenuItem to determine the color of top menus, // since they depend on XP style. ThemeActive property is // '1' for XP Style, '0' for Windows classic style. BOOL AwtDesktopProperties::IsXPStyle() { LPTSTR style = getXPStylePropFromReg(TEXT("ThemeActive")); BOOL result = (style != NULL && *style == _T('1')); free(style); return result; } void AwtDesktopProperties::GetXPStyleProperties() { LPTSTR value; value = getXPStylePropFromReg(TEXT("ThemeActive")); SetBooleanProperty(TEXT("win.xpstyle.themeActive"), (value != NULL && *value == _T('1'))); if (value != NULL) { free(value); } value = getXPStylePropFromReg(TEXT("DllName")); if (value != NULL) { SetStringProperty(TEXT("win.xpstyle.dllName"), value); free(value); } value = getXPStylePropFromReg(TEXT("SizeName")); if (value != NULL) { SetStringProperty(TEXT("win.xpstyle.sizeName"), value); free(value); } value = getXPStylePropFromReg(TEXT("ColorName")); if (value != NULL) { SetStringProperty(TEXT("win.xpstyle.colorName"), value); free(value); } } void AwtDesktopProperties::GetNonClientParameters() { // // general window properties // NONCLIENTMETRICS ncmetrics; // Fix for 6944516: specify correct size for ncmetrics on WIN2K/XP // Microsoft recommend to subtract the size of 'iPaddedBorderWidth' field // when running on XP. However this can't be referenced at compile time // with the older SDK, so there use 'lfMessageFont' plus its size. if (!IS_WINVISTA) { #if defined(_MSC_VER) && (_MSC_VER >= 1600) ncmetrics.cbSize = offsetof(NONCLIENTMETRICS, iPaddedBorderWidth); #else ncmetrics.cbSize = offsetof(NONCLIENTMETRICS,lfMessageFont) + sizeof(LOGFONT); #endif } else { ncmetrics.cbSize = sizeof(ncmetrics); } VERIFY( SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncmetrics.cbSize, &ncmetrics, FALSE) ); SetFontProperty( TEXT("win.frame.captionFont"), ncmetrics.lfCaptionFont ); SetIntegerProperty( TEXT("win.frame.captionHeight"), ncmetrics.iCaptionHeight ); SetIntegerProperty( TEXT("win.frame.captionButtonWidth"), ncmetrics.iCaptionWidth ); SetIntegerProperty( TEXT("win.frame.captionButtonHeight"), ncmetrics.iCaptionHeight ); SetFontProperty( TEXT("win.frame.smallCaptionFont"), ncmetrics.lfSmCaptionFont ); SetIntegerProperty( TEXT("win.frame.smallCaptionHeight"), ncmetrics.iSmCaptionHeight ); SetIntegerProperty( TEXT("win.frame.smallCaptionButtonWidth"), ncmetrics.iSmCaptionWidth ); SetIntegerProperty( TEXT("win.frame.smallCaptionButtonHeight"), ncmetrics.iSmCaptionHeight ); SetIntegerProperty( TEXT("win.frame.sizingBorderWidth"), ncmetrics.iBorderWidth ); // menu properties SetFontProperty( TEXT("win.menu.font"), ncmetrics.lfMenuFont ); SetIntegerProperty( TEXT("win.menu.height"), ncmetrics.iMenuHeight ); SetIntegerProperty( TEXT("win.menu.buttonWidth"), ncmetrics.iMenuWidth ); // scrollbar properties SetIntegerProperty( TEXT("win.scrollbar.width"), ncmetrics.iScrollWidth ); SetIntegerProperty( TEXT("win.scrollbar.height"), ncmetrics.iScrollHeight ); // status bar and tooltip properties SetFontProperty( TEXT("win.status.font"), ncmetrics.lfStatusFont ); SetFontProperty( TEXT("win.tooltip.font"), ncmetrics.lfStatusFont ); // message box properties SetFontProperty( TEXT("win.messagebox.font"), ncmetrics.lfMessageFont ); } void AwtDesktopProperties::GetIconParameters() { // // icon properties // ICONMETRICS iconmetrics; iconmetrics.cbSize = sizeof(iconmetrics); VERIFY( SystemParametersInfo(SPI_GETICONMETRICS, iconmetrics.cbSize, &iconmetrics, FALSE) ); SetIntegerProperty(TEXT("win.icon.hspacing"), iconmetrics.iHorzSpacing); SetIntegerProperty(TEXT("win.icon.vspacing"), iconmetrics.iVertSpacing); SetBooleanProperty(TEXT("win.icon.titleWrappingOn"), iconmetrics.iTitleWrap != 0); SetFontProperty(TEXT("win.icon.font"), iconmetrics.lfFont); } /* Windows settings for these are also in the registry They exist as system wide HKLM: HKEY_LOCAL_MACHINE and HKCU: HKEY_CURRENT_USER. HKCU\Control Panel\Desktop\FontSmoothing : "0=OFF", "2=ON" HKCU\Control Panel\Desktop\FontSmoothingType: 1=Standard, 2=LCD HKCU\Control Panel\Desktop\FontSmoothingGamma: 1000->2200 HKCU\Control Panel\Desktop\FontSmoothingOrientation: 0=BGR, 1=RGB SystemParametersInfo supplies the first three of these but does not however expose the Orientation. That has to come from the registry. We go to some small lengths in here to not make queries we don't need. Eg if we previously were using standard font smoothing and we still are then its unlikely that any change in gamma will have occurred except by a program which changed it, and even if it did, we don't need to pick it up until someone turns on the LCD option. To do: this loop is called once per top-level window so an app with N windows will get notified N times. It would save us a small amount of redundant work if I could identify the message as being one already processed for another window. Also presumably a repaint that specifies only a partially damaged window isn't one that needs this checking. */ #define FONTSMOOTHING_OFF 0 #define FONTSMOOTHING_ON 1 #define FONTSMOOTHING_STANDARD 1 #define FONTSMOOTHING_LCD 2 #define LCD_RGB_ORDER 1 #define LCD_BGR_ORDER 0 int GetLCDSubPixelOrder() { LONG order=99; LONG bufferSize = 4; HKEY hkeyDesktop; static LPCTSTR DESKTOPKEY = TEXT("Control Panel\\Desktop"); LONG ret = RegOpenKeyEx(HKEY_CURRENT_USER, DESKTOPKEY, 0L, KEY_READ, &hkeyDesktop); if (ret != ERROR_SUCCESS) { return LCD_RGB_ORDER; } ret = RegQueryValueEx(hkeyDesktop, TEXT("FontSmoothingOrientation"), NULL, NULL, (LPBYTE)&order, (LPDWORD)&bufferSize); RegCloseKey(hkeyDesktop); if (ret != ERROR_SUCCESS) { return LCD_RGB_ORDER; } else { return (int)order; } } void CheckFontSmoothingSettings(HWND hWnd) { static BOOL firstTime = TRUE; static BOOL lastFontSmoothing = FALSE; static UINT lastFontSmoothingType = FONTSMOOTHING_ON; static UINT lastFontSmoothingContrast = 1400; static UINT lastSubpixelOrder = LCD_RGB_ORDER; /* If we are called with a window handle it is because there is a * message to repaint at least some part of the window which typically * is not because of the desktop font settings change. Much more likely * its a normal repaint event. If it is because of the rare settings * change in that case the update region will be the entire window. * Try to as cheaply as possible determine if this is not a call * to repaint the whole window by assuming that all such calls will * have an update region whose origin is 0,0. Only in that case will * we take the hit of checking the settings. * Thus we avoid taking the hit of the other calls for most partial * expose events, which will never be the result of changes to desktop * font settings. */ if (hWnd != NULL) { RECT r; if (!::GetUpdateRect(hWnd, &r, FALSE) || r.top != 0 || r.left != 0) { return; } } BOOL fontSmoothing = FALSE, settingsChanged; UINT fontSmoothingType=0, fontSmoothingContrast=0, subPixelOrder; if (firstTime) { SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothing, 0); if (IS_WINXP) { SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &fontSmoothingType, 0); SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &fontSmoothingContrast, 0); } lastFontSmoothing = fontSmoothing; lastFontSmoothingType = fontSmoothingType; lastFontSmoothingContrast = fontSmoothingContrast; firstTime = FALSE; return; } else { SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothing, 0); settingsChanged = fontSmoothing != lastFontSmoothing; if (!settingsChanged && fontSmoothing == FONTSMOOTHING_OFF) { /* no need to check the other settings in this case. */ return; } if (IS_WINXP) { SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &fontSmoothingType, 0); settingsChanged |= fontSmoothingType != lastFontSmoothingType; if (!settingsChanged && fontSmoothingType == FONTSMOOTHING_STANDARD) { /* No need to check any LCD specific settings */ return; } else { SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &fontSmoothingContrast, 0); settingsChanged |= fontSmoothingContrast != lastFontSmoothingContrast; if (fontSmoothingType == FONTSMOOTHING_LCD) { // Order is a registry entry so more expensive to check.x subPixelOrder = GetLCDSubPixelOrder(); settingsChanged |= subPixelOrder != lastSubpixelOrder; } } } else { if (settingsChanged && fontSmoothing == FONTSMOOTHING_ON) { fontSmoothingType = FONTSMOOTHING_STANDARD; } } } if (settingsChanged) { /* Some of these values may not have been queried, but it shouldn't * matter as what's important is to track changes in values we are * actually using. The up-call we make here will cause the actual * values for everything to get queried and set into the desktop * properties. */ lastFontSmoothing = fontSmoothing; lastFontSmoothingType = fontSmoothingType; lastFontSmoothingContrast = fontSmoothingContrast; lastSubpixelOrder = subPixelOrder; jobject peer = AwtToolkit::GetInstance().GetPeer(); if (peer != NULL) { AwtToolkit::GetEnv()->CallVoidMethod(peer, AwtToolkit::windowsSettingChangeMID); } } } void AwtDesktopProperties::GetColorParameters() { SetColorProperty(TEXT("win.frame.activeCaptionGradientColor"), GetSysColor(COLOR_GRADIENTACTIVECAPTION)); SetColorProperty(TEXT("win.frame.inactiveCaptionGradientColor"), GetSysColor(COLOR_GRADIENTINACTIVECAPTION)); SetColorProperty(TEXT("win.item.hotTrackedColor"), GetSysColor(COLOR_HOTLIGHT)); SetColorProperty(TEXT("win.3d.darkShadowColor"), GetSysColor(COLOR_3DDKSHADOW)); SetColorProperty(TEXT("win.3d.backgroundColor"), GetSysColor(COLOR_3DFACE)); SetColorProperty(TEXT("win.3d.highlightColor"), GetSysColor(COLOR_3DHIGHLIGHT)); SetColorProperty(TEXT("win.3d.lightColor"), GetSysColor(COLOR_3DLIGHT)); SetColorProperty(TEXT("win.3d.shadowColor"), GetSysColor(COLOR_3DSHADOW)); SetColorProperty(TEXT("win.button.textColor"), GetSysColor(COLOR_BTNTEXT)); SetColorProperty(TEXT("win.desktop.backgroundColor"), GetSysColor(COLOR_DESKTOP)); SetColorProperty(TEXT("win.frame.activeCaptionColor"), GetSysColor(COLOR_ACTIVECAPTION)); SetColorProperty(TEXT("win.frame.activeBorderColor"), GetSysColor(COLOR_ACTIVEBORDER)); // ?? ?? ?? SetColorProperty(TEXT("win.frame.color"), GetSysColor(COLOR_WINDOWFRAME)); // ?? WHAT THE HECK DOES THIS MEAN ?? // ?? ?? ?? SetColorProperty(TEXT("win.frame.backgroundColor"), GetSysColor(COLOR_WINDOW)); SetColorProperty(TEXT("win.frame.captionTextColor"), GetSysColor(COLOR_CAPTIONTEXT)); SetColorProperty(TEXT("win.frame.inactiveBorderColor"), GetSysColor(COLOR_INACTIVEBORDER)); SetColorProperty(TEXT("win.frame.inactiveCaptionColor"), GetSysColor(COLOR_INACTIVECAPTION)); SetColorProperty(TEXT("win.frame.inactiveCaptionTextColor"), GetSysColor(COLOR_INACTIVECAPTIONTEXT)); SetColorProperty(TEXT("win.frame.textColor"), GetSysColor(COLOR_WINDOWTEXT)); SetColorProperty(TEXT("win.item.highlightColor"), GetSysColor(COLOR_HIGHLIGHT)); SetColorProperty(TEXT("win.item.highlightTextColor"), GetSysColor(COLOR_HIGHLIGHTTEXT)); SetColorProperty(TEXT("win.mdi.backgroundColor"), GetSysColor(COLOR_APPWORKSPACE)); SetColorProperty(TEXT("win.menu.backgroundColor"), GetSysColor(COLOR_MENU)); SetColorProperty(TEXT("win.menu.textColor"), GetSysColor(COLOR_MENUTEXT)); // COLOR_MENUBAR is only defined on WindowsXP. Our binaries are // built on NT, hence the below ifdef. #ifndef COLOR_MENUBAR #define COLOR_MENUBAR 30 #endif SetColorProperty(TEXT("win.menubar.backgroundColor"), GetSysColor(IS_WINXP ? COLOR_MENUBAR : COLOR_MENU)); SetColorProperty(TEXT("win.scrollbar.backgroundColor"), GetSysColor(COLOR_SCROLLBAR)); SetColorProperty(TEXT("win.text.grayedTextColor"), GetSysColor(COLOR_GRAYTEXT)); SetColorProperty(TEXT("win.tooltip.backgroundColor"), GetSysColor(COLOR_INFOBK)); SetColorProperty(TEXT("win.tooltip.textColor"), GetSysColor(COLOR_INFOTEXT)); } void AwtDesktopProperties::GetOtherParameters() { // TODO BEGIN: On NT4, some setttings don't trigger WM_SETTINGCHANGE -- // check whether this has been fixed on Windows 2000 and Windows 98 // ECH 10/6/2000 seems to be fixed on NT4 SP5, but not on 98 SetBooleanProperty(TEXT("win.frame.fullWindowDragsOn"), GetBooleanParameter(SPI_GETDRAGFULLWINDOWS)); SetBooleanProperty(TEXT("win.text.fontSmoothingOn"), GetBooleanParameter(SPI_GETFONTSMOOTHING)); // TODO END if (IS_WINXP) { SetIntegerProperty(TEXT("win.text.fontSmoothingType"), GetIntegerParameter(SPI_GETFONTSMOOTHINGTYPE)); SetIntegerProperty(TEXT("win.text.fontSmoothingContrast"), GetIntegerParameter(SPI_GETFONTSMOOTHINGCONTRAST)); SetIntegerProperty(TEXT("win.text.fontSmoothingOrientation"), GetLCDSubPixelOrder()); } int cxdrag = GetSystemMetrics(SM_CXDRAG); int cydrag = GetSystemMetrics(SM_CYDRAG); SetIntegerProperty(TEXT("win.drag.width"), cxdrag); SetIntegerProperty(TEXT("win.drag.height"), cydrag); SetIntegerProperty(TEXT("DnD.gestureMotionThreshold"), max(cxdrag, cydrag)/2); SetIntegerProperty(TEXT("awt.mouse.numButtons"), AwtToolkit::GetNumberOfButtons()); SetIntegerProperty(TEXT("awt.multiClickInterval"), GetDoubleClickTime()); // BEGIN cross-platform properties // Note that these are cross-platform properties, but are being stuck into // WDesktopProperties. WToolkit.lazilyLoadDesktopProperty() can find them, // but if a Toolkit subclass uses the desktopProperties // member, these properties won't be there. -bchristi, echawkes // This property is called "win.frame.fullWindowDragsOn" above // This is one of the properties that don't trigger WM_SETTINGCHANGE SetBooleanProperty(TEXT("awt.dynamicLayoutSupported"), GetBooleanParameter(SPI_GETDRAGFULLWINDOWS)); SetBooleanProperty(TEXT("awt.wheelMousePresent"), ::GetSystemMetrics(SM_MOUSEWHEELPRESENT)); // END cross-platform properties //DWORD menuShowDelay; //SystemParametersInfo(SPI_GETMENUSHOWDELAY, 0, &menuShowDelay, 0); // SetIntegerProperty(TEXT("win.menu.showDelay"), menuShowDelay); SetBooleanProperty(TEXT("win.frame.captionGradientsOn"), GetBooleanParameter(SPI_GETGRADIENTCAPTIONS)); SetBooleanProperty(TEXT("win.item.hotTrackingOn"), GetBooleanParameter(SPI_GETHOTTRACKING)); SetBooleanProperty(TEXT("win.menu.keyboardCuesOn"), GetBooleanParameter(SPI_GETKEYBOARDCUES)); // High contrast accessibility property HIGHCONTRAST contrast; contrast.cbSize = sizeof(HIGHCONTRAST); if (SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(HIGHCONTRAST), &contrast, 0) != 0 && (contrast.dwFlags & HCF_HIGHCONTRASTON) == HCF_HIGHCONTRASTON) { SetBooleanProperty(TEXT("win.highContrast.on"), TRUE); } else { SetBooleanProperty(TEXT("win.highContrast.on"), FALSE); } SHELLFLAGSTATE sfs; ::SHGetSettings(&sfs, SSF_SHOWALLOBJECTS | SSF_SHOWATTRIBCOL); if (sfs.fShowAllObjects) { SetBooleanProperty(TEXT("awt.file.showHiddenFiles"), TRUE); } else { SetBooleanProperty(TEXT("awt.file.showHiddenFiles"), FALSE); } if (sfs.fShowAttribCol) { SetBooleanProperty(TEXT("awt.file.showAttribCol"), TRUE); } else { SetBooleanProperty(TEXT("awt.file.showAttribCol"), FALSE); } LPTSTR value; DWORD valueType; // Shell Icon BPP - only honored on platforms before XP value = getWindowsPropFromReg(TEXT("Control Panel\\Desktop\\WindowMetrics"), TEXT("Shell Icon BPP"), &valueType); if (value != NULL) { if (valueType == REG_SZ) { SetStringProperty(TEXT("win.icon.shellIconBPP"), value); } free(value); } // The following registry settings control the file chooser places bar // under the Windows L&F. These settings are not present by default, but // can be enabled using the TweakUI tool from Microsoft. For more info, // see http://msdn.microsoft.com/msdnmag/issues/1100/Registry/ // NoPlacesBar is a REG_DWORD, with values 0 or 1 value = getWindowsPropFromReg(TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\comdlg32"), TEXT("NoPlacesBar"), &valueType); if (value != NULL) { if (valueType == REG_DWORD) { SetBooleanProperty(TEXT("win.comdlg.noPlacesBar"), (BOOL)((int)*value != 0)); } free(value); } LPTSTR valueName = TEXT("PlaceN"); LPTSTR valueNameBuf = (LPTSTR)safe_Malloc((lstrlen(valueName) + 1) * sizeof(TCHAR)); lstrcpy(valueNameBuf, valueName); LPTSTR propKey = TEXT("win.comdlg.placesBarPlaceN"); LPTSTR propKeyBuf = (LPTSTR)safe_Malloc((lstrlen(propKey) + 1) * sizeof(TCHAR)); lstrcpy(propKeyBuf, propKey); int i = 0; do { valueNameBuf[5] = _T('0' + i++); propKeyBuf[25] = valueNameBuf[5]; LPTSTR key = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\comdlg32\\PlacesBar"); if ((value = getWindowsPropFromReg(key, valueNameBuf, &valueType)) != NULL) { if (valueType == REG_DWORD) { // Value is a CSIDL SetIntegerProperty(propKeyBuf, (int)*value); } else { // Value is a path SetStringProperty(propKeyBuf, value); } free(value); } } while (value != NULL); free(valueNameBuf); free(propKeyBuf); } void AwtDesktopProperties::GetSoundEvents() { ///// SetSoundProperty(TEXT("win.sound.default"), TEXT(".Default")); SetSoundProperty(TEXT("win.sound.close"), TEXT("Close")); SetSoundProperty(TEXT("win.sound.maximize"), TEXT("Maximize")); SetSoundProperty(TEXT("win.sound.minimize"), TEXT("Minimize")); SetSoundProperty(TEXT("win.sound.menuCommand"), TEXT("MenuCommand")); SetSoundProperty(TEXT("win.sound.menuPopup"), TEXT("MenuPopup")); SetSoundProperty(TEXT("win.sound.open"), TEXT("Open")); SetSoundProperty(TEXT("win.sound.restoreDown"), TEXT("RestoreDown")); SetSoundProperty(TEXT("win.sound.restoreUp"), TEXT("RestoreUp")); ///// SetSoundProperty(TEXT("win.sound.asterisk"), TEXT("SystemAsterisk")); SetSoundProperty(TEXT("win.sound.exclamation"), TEXT("SystemExclamation")); SetSoundProperty(TEXT("win.sound.exit"), TEXT("SystemExit")); SetSoundProperty(TEXT("win.sound.hand"), TEXT("SystemHand")); SetSoundProperty(TEXT("win.sound.question"), TEXT("SystemQuestion")); SetSoundProperty(TEXT("win.sound.start"), TEXT("SystemStart")); } void AwtDesktopProperties::GetCaretParameters() { SetIntegerProperty(TEXT("win.caret.width"), GetIntegerParameter(SPI_GETCARETWIDTH)); } BOOL AwtDesktopProperties::GetBooleanParameter(UINT spi) { BOOL flag; SystemParametersInfo(spi, 0, &flag, 0); DASSERT(flag == TRUE || flag == FALSE); // should be simple boolean value return flag; } UINT AwtDesktopProperties::GetIntegerParameter(UINT spi) { UINT retValue; SystemParametersInfo(spi, 0, &retValue, 0); return retValue; } void AwtDesktopProperties::SetStringProperty(LPCTSTR propName, LPTSTR value) { jstring key = JNU_NewStringPlatform(GetEnv(), propName); GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setStringPropertyID, key, JNU_NewStringPlatform(GetEnv(), value)); GetEnv()->DeleteLocalRef(key); } void AwtDesktopProperties::SetIntegerProperty(LPCTSTR propName, int value) { jstring key = JNU_NewStringPlatform(GetEnv(), propName); GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setIntegerPropertyID, key, (jint)value); GetEnv()->DeleteLocalRef(key); } void AwtDesktopProperties::SetBooleanProperty(LPCTSTR propName, BOOL value) { jstring key = JNU_NewStringPlatform(GetEnv(), propName); GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setBooleanPropertyID, key, value ? JNI_TRUE : JNI_FALSE); GetEnv()->DeleteLocalRef(key); } void AwtDesktopProperties::SetColorProperty(LPCTSTR propName, DWORD value) { jstring key = JNU_NewStringPlatform(GetEnv(), propName); GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setColorPropertyID, key, GetRValue(value), GetGValue(value), GetBValue(value)); GetEnv()->DeleteLocalRef(key); } void AwtDesktopProperties::SetFontProperty(HDC dc, int fontID, LPCTSTR propName) { HGDIOBJ font = GetStockObject(fontID); if (font != NULL && SelectObject(dc, font) != NULL) { int length = GetTextFace(dc, 0, NULL); if (length > 0) { LPTSTR face = new TCHAR[length]; if (GetTextFace(dc, length, face) > 0) { TEXTMETRIC metrics; if (GetTextMetrics(dc, &metrics) > 0) { jstring fontName = NULL; if (!wcscmp(face, L"MS Shell Dlg")) { // MS Shell Dlg is an indirect font name, find the // real face name from the registry. LPTSTR shellDialogFace = resolveShellDialogFont(); if (shellDialogFace != NULL) { fontName = JNU_NewStringPlatform(GetEnv(), shellDialogFace); free(shellDialogFace); } else { // Couldn't determine mapping for MS Shell Dlg, // fall back to Microsoft Sans Serif fontName = JNU_NewStringPlatform(GetEnv(), L"Microsoft Sans Serif"); } } else { fontName = JNU_NewStringPlatform(GetEnv(), face); } jint pointSize = metrics.tmHeight - metrics.tmInternalLeading; jint style = java_awt_Font_PLAIN; if (metrics.tmWeight >= FW_BOLD) { style = java_awt_Font_BOLD; } if (metrics.tmItalic ) { style |= java_awt_Font_ITALIC; } jstring key = JNU_NewStringPlatform(GetEnv(), propName); GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setFontPropertyID, key, fontName, style, pointSize); GetEnv()->DeleteLocalRef(fontName); GetEnv()->DeleteLocalRef(key); } } delete[] face; } } } void AwtDesktopProperties::SetFontProperty(LPCTSTR propName, const LOGFONT & font) { jstring fontName; jint pointSize; jint style; fontName = JNU_NewStringPlatform(GetEnv(), font.lfFaceName); #if 0 HDC hdc; int pixelsPerInch = GetDeviceCaps(hdc, LOGPIXELSY); // convert font size specified in pixels to font size in points hdc = GetDC(NULL); pointSize = (-font.lfHeight)*72/pixelsPerInch; ReleaseDC(NULL, hdc); #endif // Java uses point sizes, but assumes 1 pixel = 1 point pointSize = -font.lfHeight; // convert Windows font style to Java style style = java_awt_Font_PLAIN; DTRACE_PRINTLN1("weight=%d", font.lfWeight); if ( font.lfWeight >= FW_BOLD ) { style = java_awt_Font_BOLD; } if ( font.lfItalic ) { style |= java_awt_Font_ITALIC; } jstring key = JNU_NewStringPlatform(GetEnv(), propName); GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setFontPropertyID, key, fontName, style, pointSize); GetEnv()->DeleteLocalRef(fontName); GetEnv()->DeleteLocalRef(key); } void AwtDesktopProperties::SetSoundProperty(LPCTSTR propName, LPCTSTR winEventName) { jstring key = JNU_NewStringPlatform(GetEnv(), propName); jstring event = JNU_NewStringPlatform(GetEnv(), winEventName); GetEnv()->CallVoidMethod(self, AwtDesktopProperties::setSoundPropertyID, key, event); GetEnv()->DeleteLocalRef(key); GetEnv()->DeleteLocalRef(event); } void AwtDesktopProperties::PlayWindowsSound(LPCTSTR event) { // stop any currently playing sounds ::PlaySound(NULL, NULL, SND_PURGE); // play the sound for the given event name ::PlaySound(event, NULL, SND_ASYNC|SND_ALIAS|SND_NODEFAULT); } /////////////////////////////////////////////////////////////////////////////////////////////////// static AwtDesktopProperties * GetCppThis(JNIEnv *env, jobject self) { jlong longProps = env->GetLongField(self, AwtDesktopProperties::pDataID); AwtDesktopProperties * props = (AwtDesktopProperties *)jlong_to_ptr(longProps); DASSERT( !IsBadReadPtr(props, sizeof(*props)) ); return props; } JNIEXPORT void JNICALL Java_sun_awt_windows_WDesktopProperties_initIDs(JNIEnv *env, jclass cls) { TRY; AwtDesktopProperties::pDataID = env->GetFieldID(cls, "pData", "J"); DASSERT(AwtDesktopProperties::pDataID != 0); AwtDesktopProperties::setBooleanPropertyID = env->GetMethodID(cls, "setBooleanProperty", "(Ljava/lang/String;Z)V"); DASSERT(AwtDesktopProperties::setBooleanPropertyID != 0); AwtDesktopProperties::setIntegerPropertyID = env->GetMethodID(cls, "setIntegerProperty", "(Ljava/lang/String;I)V"); DASSERT(AwtDesktopProperties::setIntegerPropertyID != 0); AwtDesktopProperties::setStringPropertyID = env->GetMethodID(cls, "setStringProperty", "(Ljava/lang/String;Ljava/lang/String;)V"); DASSERT(AwtDesktopProperties::setStringPropertyID != 0); AwtDesktopProperties::setColorPropertyID = env->GetMethodID(cls, "setColorProperty", "(Ljava/lang/String;III)V"); DASSERT(AwtDesktopProperties::setColorPropertyID != 0); AwtDesktopProperties::setFontPropertyID = env->GetMethodID(cls, "setFontProperty", "(Ljava/lang/String;Ljava/lang/String;II)V"); DASSERT(AwtDesktopProperties::setFontPropertyID != 0); AwtDesktopProperties::setSoundPropertyID = env->GetMethodID(cls, "setSoundProperty", "(Ljava/lang/String;Ljava/lang/String;)V"); DASSERT(AwtDesktopProperties::setSoundPropertyID != 0); CATCH_BAD_ALLOC; } JNIEXPORT void JNICALL Java_sun_awt_windows_WDesktopProperties_init(JNIEnv *env, jobject self) { TRY; new AwtDesktopProperties(self); CATCH_BAD_ALLOC; } JNIEXPORT void JNICALL Java_sun_awt_windows_WDesktopProperties_getWindowsParameters(JNIEnv *env, jobject self) { TRY; GetCppThis(env, self)->GetWindowsParameters(); CATCH_BAD_ALLOC; } JNIEXPORT void JNICALL Java_sun_awt_windows_WDesktopProperties_playWindowsSound(JNIEnv *env, jobject self, jstring event) { TRY; LPCTSTR winEventName; winEventName = JNU_GetStringPlatformChars(env, event, NULL); if ( winEventName == NULL ) { return; } GetCppThis(env, self)->PlayWindowsSound(winEventName); JNU_ReleaseStringPlatformChars(env, event, winEventName); CATCH_BAD_ALLOC; }