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