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