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