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 <sun_awt_Win32GraphicsEnvironment.h> 28 #include <sun_awt_Win32FontManager.h> 29 #include "awt_Canvas.h" 30 #include "awt_Win32GraphicsDevice.h" 31 #include "Devices.h" 32 #include "WindowsFlags.h" 33 #include "DllUtil.h" 34 35 BOOL DWMIsCompositionEnabled(); 36 37 void initScreens(JNIEnv *env) { 38 39 if (!Devices::UpdateInstance(env)) { 40 JNU_ThrowInternalError(env, "Could not update the devices array."); 41 return; 42 } 43 } 44 45 /** 46 * This function attempts to make a Win32 API call to 47 * BOOL SetProcessDPIAware(VOID); 48 * which is only present on Windows Vista, and which instructs the 49 * Vista Windows Display Manager that this application is High DPI Aware 50 * and does not need to be scaled by the WDM and lied about the 51 * actual system dpi. 52 */ 53 static void 54 SetProcessDPIAwareProperty() 55 { 56 typedef BOOL (WINAPI SetProcessDPIAwareFunc)(void); 57 static BOOL bAlreadySet = FALSE; 58 59 // setHighDPIAware is set in WindowsFlags.cpp 60 if (!setHighDPIAware || bAlreadySet) { 61 return; 62 } 63 64 bAlreadySet = TRUE; 65 66 HMODULE hLibUser32Dll = ::LoadLibrary(TEXT("user32.dll")); 67 68 if (hLibUser32Dll != NULL) { 69 SetProcessDPIAwareFunc *lpSetProcessDPIAware = 70 (SetProcessDPIAwareFunc*)GetProcAddress(hLibUser32Dll, 71 "SetProcessDPIAware"); 72 if (lpSetProcessDPIAware != NULL) { 73 lpSetProcessDPIAware(); 74 } 75 ::FreeLibrary(hLibUser32Dll); 76 } 77 } 78 79 #define DWM_COMP_UNDEFINED (~(TRUE|FALSE)) 80 static int dwmIsCompositionEnabled = DWM_COMP_UNDEFINED; 81 82 /** 83 * This function is called from toolkit event handling code when 84 * WM_DWMCOMPOSITIONCHANGED event is received 85 */ 86 void DWMResetCompositionEnabled() { 87 dwmIsCompositionEnabled = DWM_COMP_UNDEFINED; 88 (void)DWMIsCompositionEnabled(); 89 } 90 91 /** 92 * Returns true if dwm composition is enabled, false if it is not applicable 93 * (if the OS is not Vista) or dwm composition is disabled. 94 */ 95 BOOL DWMIsCompositionEnabled() { 96 // cheaper to check than whether it's vista or not 97 if (dwmIsCompositionEnabled != DWM_COMP_UNDEFINED) { 98 return (BOOL)dwmIsCompositionEnabled; 99 } 100 101 if (!IS_WINVISTA) { 102 dwmIsCompositionEnabled = FALSE; 103 return FALSE; 104 } 105 106 BOOL bRes = FALSE; 107 108 try { 109 BOOL bEnabled; 110 HRESULT res = DwmAPI::DwmIsCompositionEnabled(&bEnabled); 111 if (SUCCEEDED(res)) { 112 bRes = bEnabled; 113 J2dTraceLn1(J2D_TRACE_VERBOSE, " composition enabled: %d",bRes); 114 } else { 115 J2dTraceLn1(J2D_TRACE_ERROR, 116 "IsDWMCompositionEnabled: error %x when detecting"\ 117 "if composition is enabled", res); 118 } 119 } catch (const DllUtil::Exception &) { 120 J2dTraceLn(J2D_TRACE_ERROR, 121 "IsDWMCompositionEnabled: no DwmIsCompositionEnabled() "\ 122 "in dwmapi.dll or dwmapi.dll cannot be loaded"); 123 } 124 125 dwmIsCompositionEnabled = bRes; 126 127 JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); 128 JNU_CallStaticMethodByName(env, NULL, 129 "sun/awt/Win32GraphicsEnvironment", 130 "dwmCompositionChanged", "(Z)V", (jboolean)bRes); 131 return bRes; 132 } 133 134 /* 135 * Class: sun_awt_Win32GraphicsEnvironment 136 * Method: initDisplay 137 * Signature: ()V 138 */ 139 JNIEXPORT void JNICALL 140 Java_sun_awt_Win32GraphicsEnvironment_initDisplay(JNIEnv *env, 141 jclass thisClass) 142 { 143 // This method needs to be called prior to any display-related activity 144 SetProcessDPIAwareProperty(); 145 146 DWMIsCompositionEnabled(); 147 148 initScreens(env); 149 } 150 151 /* 152 * Class: sun_awt_Win32GraphicsEnvironment 153 * Method: getNumScreens 154 * Signature: ()I 155 */ 156 JNIEXPORT jint JNICALL 157 Java_sun_awt_Win32GraphicsEnvironment_getNumScreens(JNIEnv *env, 158 jobject thisobj) 159 { 160 Devices::InstanceAccess devices; 161 return devices->GetNumDevices(); 162 } 163 164 /* 165 * Class: sun_awt_Win32GraphicsEnvironment 166 * Method: getDefaultScreen 167 * Signature: ()I 168 */ 169 JNIEXPORT jint JNICALL 170 Java_sun_awt_Win32GraphicsEnvironment_getDefaultScreen(JNIEnv *env, 171 jobject thisobj) 172 { 173 return AwtWin32GraphicsDevice::GetDefaultDeviceIndex(); 174 } 175 176 /* 177 * Class: sun_awt_Win32FontManager 178 * Method: registerFontWithPlatform 179 * Signature: (Ljava/lang/String;)V 180 */ 181 JNIEXPORT void JNICALL 182 Java_sun_awt_Win32FontManager_registerFontWithPlatform(JNIEnv *env, 183 jclass cl, 184 jstring fontName) 185 { 186 LPTSTR file = (LPTSTR)JNU_GetStringPlatformChars(env, fontName, JNI_FALSE); 187 if (file) { 188 ::AddFontResourceEx(file, FR_PRIVATE, NULL); 189 JNU_ReleaseStringPlatformChars(env, fontName, file); 190 } 191 } 192 193 194 /* 195 * Class: sun_awt_Win32FontManagerEnvironment 196 * Method: deRegisterFontWithPlatform 197 * Signature: (Ljava/lang/String;)V 198 * 199 * This method intended for future use. 200 */ 201 JNIEXPORT void JNICALL 202 Java_sun_awt_Win32FontManager_deRegisterFontWithPlatform(JNIEnv *env, 203 jclass cl, 204 jstring fontName) 205 { 206 LPTSTR file = (LPTSTR)JNU_GetStringPlatformChars(env, fontName, JNI_FALSE); 207 if (file) { 208 ::RemoveFontResourceEx(file, FR_PRIVATE, NULL); 209 JNU_ReleaseStringPlatformChars(env, fontName, file); 210 } 211 } 212 213 #define EUDCKEY_JA_JP L"EUDC\\932" 214 #define EUDCKEY_ZH_CN L"EUDC\\936" 215 #define EUDCKEY_ZH_TW L"EUDC\\950" 216 #define EUDCKEY_KO_KR L"EUDC\\949" 217 #define LANGID_JA_JP 0x411 218 #define LANGID_ZH_CN 0x0804 219 #define LANGID_ZH_SG 0x1004 220 #define LANGID_ZH_TW 0x0404 221 #define LANGID_ZH_HK 0x0c04 222 #define LANGID_ZH_MO 0x1404 223 #define LANGID_KO_KR 0x0412 224 225 226 JNIEXPORT jstring JNICALL 227 Java_sun_awt_Win32FontManager_getEUDCFontFile(JNIEnv *env, jclass cl) { 228 int rc; 229 HKEY key; 230 DWORD type; 231 WCHAR fontPathBuf[MAX_PATH + 1]; 232 unsigned long fontPathLen = MAX_PATH + 1; 233 WCHAR tmpPath[MAX_PATH + 1]; 234 LPWSTR fontPath = fontPathBuf; 235 LPWSTR eudcKey = NULL; 236 237 LANGID langID = GetSystemDefaultLangID(); 238 //lookup for encoding ID, EUDC only supported in 239 //codepage 932, 936, 949, 950 (and unicode) 240 if (langID == LANGID_JA_JP) { 241 eudcKey = EUDCKEY_JA_JP; 242 } else if (langID == LANGID_ZH_CN || langID == LANGID_ZH_SG) { 243 eudcKey = EUDCKEY_ZH_CN; 244 } else if (langID == LANGID_ZH_HK || langID == LANGID_ZH_TW || 245 langID == LANGID_ZH_MO) { 246 eudcKey = EUDCKEY_ZH_TW; 247 } else if (langID == LANGID_KO_KR) { 248 eudcKey = EUDCKEY_KO_KR; 249 } else { 250 return NULL; 251 } 252 253 rc = RegOpenKeyEx(HKEY_CURRENT_USER, eudcKey, 0, KEY_READ, &key); 254 if (rc != ERROR_SUCCESS) { 255 return NULL; 256 } 257 rc = RegQueryValueEx(key, 258 L"SystemDefaultEUDCFont", 259 0, 260 &type, 261 (LPBYTE)fontPath, 262 &fontPathLen); 263 RegCloseKey(key); 264 if (rc != ERROR_SUCCESS || type != REG_SZ) { 265 return NULL; 266 } 267 fontPath[fontPathLen] = L'\0'; 268 if (wcsstr(fontPath, L"%SystemRoot%")) { 269 //if the fontPath includes %SystemRoot% 270 LPWSTR systemRoot = _wgetenv(L"SystemRoot"); 271 if (systemRoot != NULL 272 && swprintf(tmpPath, MAX_PATH, L"%s%s", systemRoot, fontPath + 12) != -1) { 273 fontPath = tmpPath; 274 } 275 else { 276 return NULL; 277 } 278 } else if (wcscmp(fontPath, L"EUDC.TTE") == 0) { 279 //else to see if it only inludes "EUDC.TTE" 280 WCHAR systemRoot[MAX_PATH + 1]; 281 if (GetWindowsDirectory(systemRoot, MAX_PATH + 1) != 0) { 282 swprintf(tmpPath, MAX_PATH, L"%s\\FONTS\\EUDC.TTE", systemRoot); 283 fontPath = tmpPath; 284 } 285 else { 286 return NULL; 287 } 288 } 289 return JNU_NewStringPlatform(env, fontPath); 290 } 291 292 /* 293 * Class: sun_awt_Win32GraphicsEnvironment 294 * Method: getXResolution 295 * Signature: ()I 296 */ 297 JNIEXPORT jint JNICALL 298 Java_sun_awt_Win32GraphicsEnvironment_getXResolution(JNIEnv *env, jobject wge) 299 { 300 TRY; 301 302 HWND hWnd = ::GetDesktopWindow(); 303 HDC hDC = ::GetDC(hWnd); 304 jint result = ::GetDeviceCaps(hDC, LOGPIXELSX); 305 ::ReleaseDC(hWnd, hDC); 306 return result; 307 308 CATCH_BAD_ALLOC_RET(0); 309 } 310 311 /* 312 * Class: sun_awt_Win32GraphicsEnvironment 313 * Method: getYResolution 314 * Signature: ()I 315 */ 316 JNIEXPORT jint JNICALL 317 Java_sun_awt_Win32GraphicsEnvironment_getYResolution(JNIEnv *env, jobject wge) 318 { 319 TRY; 320 321 HWND hWnd = ::GetDesktopWindow(); 322 HDC hDC = ::GetDC(hWnd); 323 jint result = ::GetDeviceCaps(hDC, LOGPIXELSY); 324 ::ReleaseDC(hWnd, hDC); 325 return result; 326 327 CATCH_BAD_ALLOC_RET(0); 328 } 329 330 /* 331 * Class: sun_awt_Win32GraphicsEnvironment 332 * Method: isVistaOS 333 * Signature: ()Z 334 */ 335 JNIEXPORT jboolean JNICALL Java_sun_awt_Win32GraphicsEnvironment_isVistaOS 336 (JNIEnv *env, jclass wgeclass) 337 { 338 return IS_WINVISTA; 339 }