< prev index next >

src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp

Print this page

        

*** 27,36 **** --- 27,38 ---- #include "awt.h" #include <signal.h> #include <windowsx.h> #include <process.h> + #include <shellapi.h> + #include <shlwapi.h> #include "awt_DrawingSurface.h" #include "awt_AWTEvent.h" #include "awt_Component.h" #include "awt_Canvas.h"
*** 303,312 **** --- 305,321 ---- m_vmSignalled = FALSE; m_isDynamicLayoutSet = FALSE; m_areExtraMouseButtonsEnabled = TRUE; + m_isWin8OrLater = FALSE; + m_touchKbrdAutoShowIsEnabled = FALSE; + m_touchKbrdExeFilePath = NULL; + m_pRegisterTouchWindow = NULL; + m_pGetTouchInputInfo = NULL; + m_pCloseTouchInputHandle = NULL; + m_verifyComponents = FALSE; m_breakOnError = FALSE; m_breakMessageLoop = FALSE; m_messageLoopResult = 0;
*** 357,366 **** --- 366,518 ---- NULL); /* lpParam */ DASSERT(hwnd != NULL); return hwnd; } + void AwtToolkit::InitTouchKeyboardExeFilePath() { + enum RegistryView { WOW64_32BIT, WOW64_64BIT }; + const TCHAR tabTipCoKeyName[] = _T("SOFTWARE\\Classes\\CLSID\\") + _T("{054AAE20-4BEA-4347-8A35-64A533254A9D}\\LocalServer32"); + HKEY hTabTipCoKey = NULL; + RegistryView regViewWithTabTipCoKey = WOW64_32BIT; + + if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, tabTipCoKeyName, 0, + KEY_READ | KEY_WOW64_32KEY, &hTabTipCoKey) != ERROR_SUCCESS) { + if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, tabTipCoKeyName, 0, + KEY_READ | KEY_WOW64_64KEY, &hTabTipCoKey) != ERROR_SUCCESS) { + return; + } else { + regViewWithTabTipCoKey = WOW64_64BIT; + } + } + + DWORD keyValType = 0; + DWORD bytesCopied = 0; + if ((::RegQueryValueEx(hTabTipCoKey, NULL, NULL, &keyValType, NULL, + &bytesCopied) != ERROR_SUCCESS) || + ((keyValType != REG_EXPAND_SZ) && (keyValType != REG_SZ))) { + if (hTabTipCoKey != NULL) { + ::RegCloseKey(hTabTipCoKey); + } + return; + } + + // Increase the buffer size for 1 additional null-terminating character. + bytesCopied += sizeof(TCHAR); + TCHAR* tabTipFilePath = new TCHAR[bytesCopied / sizeof(TCHAR)]; + ::memset(tabTipFilePath, 0, bytesCopied); + + DWORD oldBytesCopied = bytesCopied; + if (::RegQueryValueEx(hTabTipCoKey, NULL, NULL, NULL, + (LPBYTE)tabTipFilePath, &bytesCopied) == ERROR_SUCCESS) { + const TCHAR searchedStr[] = _T("%CommonProgramFiles%"); + const size_t searchedStrLen = ::_tcslen(searchedStr); + int searchedStrStartIndex = -1; + + TCHAR* commonFilesDirPath = NULL; + DWORD commonFilesDirPathLen = 0; + + // Check, if '%CommonProgramFiles%' string is present in the defined + // path of the touch keyboard executable. + TCHAR* const searchedStrStart = ::_tcsstr(tabTipFilePath, searchedStr); + if (searchedStrStart != NULL) { + searchedStrStartIndex = searchedStrStart - tabTipFilePath; + + // Get value of 'CommonProgramFiles' environment variable, if the + // file path of the touch keyboard executable was found in 32-bit + // registry view, otherwise get value of 'CommonProgramW6432'. + const TCHAR envVar32BitName[] = _T("CommonProgramFiles"); + const TCHAR envVar64BitName[] = _T("CommonProgramW6432"); + const TCHAR* envVarName = (regViewWithTabTipCoKey == WOW64_32BIT ? + envVar32BitName : envVar64BitName); + + DWORD charsStored = ::GetEnvironmentVariable(envVarName, NULL, 0); + if (charsStored > 0) { + commonFilesDirPath = new TCHAR[charsStored]; + ::memset(commonFilesDirPath, 0, charsStored * sizeof(TCHAR)); + + DWORD oldCharsStored = charsStored; + if (((charsStored = ::GetEnvironmentVariable(envVarName, + commonFilesDirPath, charsStored)) > 0) && + (charsStored <= oldCharsStored)) { + commonFilesDirPathLen = charsStored; + } else { + delete[] commonFilesDirPath; + commonFilesDirPath = NULL; + } + } + } + + // Calculate 'm_touchKbrdExeFilePath' length in characters including + // the null-terminating character. + DWORD exeFilePathLen = oldBytesCopied / sizeof(TCHAR); + if (commonFilesDirPathLen > 0) { + exeFilePathLen = exeFilePathLen - searchedStrLen + + commonFilesDirPathLen; + } + + if (m_touchKbrdExeFilePath != NULL) { + delete[] m_touchKbrdExeFilePath; + m_touchKbrdExeFilePath = NULL; + } + m_touchKbrdExeFilePath = new TCHAR[exeFilePathLen]; + ::memset(m_touchKbrdExeFilePath, 0, exeFilePathLen * sizeof(TCHAR)); + + if (commonFilesDirPathLen > 0) { + ::_tcsncpy_s(m_touchKbrdExeFilePath, exeFilePathLen, tabTipFilePath, + searchedStrStartIndex); + DWORD charsCopied = searchedStrStartIndex; + + ::_tcsncpy_s(m_touchKbrdExeFilePath + charsCopied, + exeFilePathLen - charsCopied, commonFilesDirPath, + commonFilesDirPathLen); + charsCopied += commonFilesDirPathLen; + + ::_tcsncpy_s(m_touchKbrdExeFilePath + charsCopied, + exeFilePathLen - charsCopied, searchedStrStart + searchedStrLen, + bytesCopied / sizeof(TCHAR) - + (searchedStrStartIndex + searchedStrLen)); + } else { + ::_tcsncpy_s(m_touchKbrdExeFilePath, exeFilePathLen, tabTipFilePath, + bytesCopied / sizeof(TCHAR)); + } + + // Remove leading and trailing quotation marks. + ::StrTrim(m_touchKbrdExeFilePath, _T("\"")); + + // Verify that a file with the path 'm_touchKbrdExeFilePath' exists. + DWORD fileAttrs = ::GetFileAttributes(m_touchKbrdExeFilePath); + DWORD err = ::GetLastError(); + if ((fileAttrs == INVALID_FILE_ATTRIBUTES) || + (fileAttrs & FILE_ATTRIBUTE_DIRECTORY)) { + delete[] m_touchKbrdExeFilePath; + m_touchKbrdExeFilePath = NULL; + } + + if (commonFilesDirPath != NULL) { + delete[] commonFilesDirPath; + } + } + + if (tabTipFilePath != NULL) { + delete[] tabTipFilePath; + } + if (hTabTipCoKey != NULL) { + ::RegCloseKey(hTabTipCoKey); + } + } + + HWND AwtToolkit::GetTouchKeyboardWindow() { + const TCHAR wndClassName[] = _T("IPTip_Main_Window"); + HWND hwnd = ::FindWindow(wndClassName, NULL); + if ((hwnd != NULL) && ::IsWindow(hwnd) && ::IsWindowEnabled(hwnd) && + ::IsWindowVisible(hwnd)) { + return hwnd; + } + return NULL; + } + struct ToolkitThreadProc_Data { bool result; HANDLE hCompleted;
*** 515,524 **** --- 667,722 ---- (HOOKPROC)GetMessageFilter, 0, tk.m_mainThreadId); awt_dnd_initialize(); + /* + * Initialization of the touch keyboard related variables. + */ + tk.m_isWin8OrLater = IS_WIN8; + + TRY; + + JNIEnv* env = AwtToolkit::GetEnv(); + jclass sunToolkitCls = env->FindClass("sun/awt/SunToolkit"); + DASSERT(sunToolkitCls != 0); + CHECK_NULL_RETURN(sunToolkitCls, FALSE); + + jmethodID isTouchKeyboardAutoShowEnabledMID = env->GetStaticMethodID( + sunToolkitCls, "isTouchKeyboardAutoShowEnabled", "()Z"); + DASSERT(isTouchKeyboardAutoShowEnabledMID != 0); + CHECK_NULL_RETURN(isTouchKeyboardAutoShowEnabledMID, FALSE); + + tk.m_touchKbrdAutoShowIsEnabled = env->CallStaticBooleanMethod( + sunToolkitCls, isTouchKeyboardAutoShowEnabledMID); + + CATCH_BAD_ALLOC_RET(FALSE); + + if (tk.m_isWin8OrLater && tk.m_touchKbrdAutoShowIsEnabled) { + tk.InitTouchKeyboardExeFilePath(); + HMODULE hUser32Dll = ::LoadLibrary(_T("user32.dll")); + if (hUser32Dll != NULL) { + tk.m_pRegisterTouchWindow = (RegisterTouchWindowFunc) + ::GetProcAddress(hUser32Dll, "RegisterTouchWindow"); + tk.m_pGetTouchInputInfo = (GetTouchInputInfoFunc) + ::GetProcAddress(hUser32Dll, "GetTouchInputInfo"); + tk.m_pCloseTouchInputHandle = (CloseTouchInputHandleFunc) + ::GetProcAddress(hUser32Dll, "CloseTouchInputHandle"); + } + + if ((tk.m_pRegisterTouchWindow == NULL) || + (tk.m_pGetTouchInputInfo == NULL) || + (tk.m_pCloseTouchInputHandle == NULL)) { + tk.m_pRegisterTouchWindow = NULL; + tk.m_pGetTouchInputInfo = NULL; + tk.m_pCloseTouchInputHandle = NULL; + } + } + /* + * End of the touch keyboard related initialization code. + */ + return TRUE; } BOOL AwtToolkit::Dispose() { DTRACE_PRINTLN("In AwtToolkit::Dispose()");
*** 539,548 **** --- 737,754 ---- AwtObjectList::Cleanup(); awt_dnd_uninitialize(); awt_clipboard_uninitialize((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)); + if (tk.m_touchKbrdExeFilePath != NULL) { + delete[] tk.m_touchKbrdExeFilePath; + tk.m_touchKbrdExeFilePath = NULL; + } + tk.m_pRegisterTouchWindow = NULL; + tk.m_pGetTouchInputInfo = NULL; + tk.m_pCloseTouchInputHandle = NULL; + if (tk.m_inputMethodHWnd != NULL) { ::SendMessage(tk.m_inputMethodHWnd, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0); } tk.m_inputMethodHWnd = NULL;
*** 2745,2754 **** --- 2951,2986 ---- return JNU_NewStringPlatform(env, szVer); CATCH_BAD_ALLOC_RET(NULL); } + JNIEXPORT void JNICALL + Java_sun_awt_windows_WToolkit_showTouchKeyboard(JNIEnv *env, jobject self, + jboolean causedByTouchEvent) + { + AwtToolkit& tk = AwtToolkit::GetInstance(); + if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) { + return; + } + + if (causedByTouchEvent || + (tk.IsTouchKeyboardAutoShowSystemEnabled() && + !tk.IsAnyKeyboardAttached())) { + tk.ShowTouchKeyboard(); + } + } + + JNIEXPORT void JNICALL + Java_sun_awt_windows_WToolkit_hideTouchKeyboard(JNIEnv *env, jobject self) + { + AwtToolkit& tk = AwtToolkit::GetInstance(); + if (!tk.IsWin8OrLater() || !tk.IsTouchKeyboardAutoShowEnabled()) { + return; + } + tk.HideTouchKeyboard(); + } + JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WToolkit_syncNativeQueue(JNIEnv *env, jobject self, jlong timeout) { AwtToolkit & tk = AwtToolkit::GetInstance(); DWORD eventNumber = tk.eventNumber;
*** 2822,2826 **** --- 3054,3179 ---- } UINT AwtToolkit::GetNumberOfButtons() { return MOUSE_BUTTONS_WINDOWS_SUPPORTED; } + + bool AwtToolkit::IsWin8OrLater() { + return m_isWin8OrLater; + } + + bool AwtToolkit::IsTouchKeyboardAutoShowEnabled() { + return m_touchKbrdAutoShowIsEnabled; + } + + bool AwtToolkit::IsAnyKeyboardAttached() { + UINT numDevs = 0; + UINT numDevsRet = 0; + const UINT devListTypeSize = sizeof(RAWINPUTDEVICELIST); + if ((::GetRawInputDeviceList(NULL, &numDevs, devListTypeSize) != 0) || + (numDevs == 0)) { + return false; + } + + RAWINPUTDEVICELIST* pDevList = new RAWINPUTDEVICELIST[numDevs]; + while (((numDevsRet = ::GetRawInputDeviceList(pDevList, &numDevs, + devListTypeSize)) == (UINT)-1) && + (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { + if (pDevList != NULL) { + delete[] pDevList; + } + pDevList = new RAWINPUTDEVICELIST[numDevs]; + } + + bool keyboardIsAttached = false; + if (numDevsRet != (UINT)-1) { + for (UINT i = 0; i < numDevsRet; i++) { + if (pDevList[i].dwType == RIM_TYPEKEYBOARD) { + keyboardIsAttached = true; + break; + } + } + } + + if (pDevList != NULL) { + delete[] pDevList; + } + return keyboardIsAttached; + } + + bool AwtToolkit::IsTouchKeyboardAutoShowSystemEnabled() { + const TCHAR tabTipKeyName[] = _T("SOFTWARE\\Microsoft\\TabletTip\\1.7"); + HKEY hTabTipKey = NULL; + if (::RegOpenKeyEx(HKEY_CURRENT_USER, tabTipKeyName, 0, KEY_READ, + &hTabTipKey) != ERROR_SUCCESS) { + return false; + } + + const TCHAR enableAutoInvokeValName[] = _T("EnableDesktopModeAutoInvoke"); + DWORD keyValType = 0; + bool autoShowIsEnabled = false; + if (::RegQueryValueEx(hTabTipKey, enableAutoInvokeValName, NULL, + &keyValType, NULL, NULL) == ERROR_SUCCESS) { + if (keyValType == REG_DWORD) { + DWORD enableAutoInvokeVal = 0; + DWORD bytesCopied = sizeof(DWORD); + if (::RegQueryValueEx(hTabTipKey, enableAutoInvokeValName, NULL, + NULL, (LPBYTE)(DWORD*)&enableAutoInvokeVal, + &bytesCopied) == ERROR_SUCCESS) { + autoShowIsEnabled = (enableAutoInvokeVal == 0 ? false : true); + } + } + } + + if (hTabTipKey != NULL) { + ::RegCloseKey(hTabTipKey); + } + return autoShowIsEnabled; + } + + void AwtToolkit::ShowTouchKeyboard() { + if (m_isWin8OrLater && m_touchKbrdAutoShowIsEnabled && + (m_touchKbrdExeFilePath != NULL)) { + HINSTANCE retVal = ::ShellExecute(NULL, _T("open"), + m_touchKbrdExeFilePath, NULL, NULL, SW_SHOW); + if ((int)retVal <= 32) { + // Verify that a file with the path 'm_touchKbrdExeFilePath' exists. + DWORD fileAttrs = ::GetFileAttributes(m_touchKbrdExeFilePath); + if ((fileAttrs == INVALID_FILE_ATTRIBUTES) || + (fileAttrs & FILE_ATTRIBUTE_DIRECTORY)) { + delete[] m_touchKbrdExeFilePath; + m_touchKbrdExeFilePath = NULL; + } + } + } + } + + void AwtToolkit::HideTouchKeyboard() { + if (m_isWin8OrLater && m_touchKbrdAutoShowIsEnabled) { + HWND hwnd = GetTouchKeyboardWindow(); + if (hwnd != NULL) { + ::PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0); + } + } + } + + BOOL AwtToolkit::TIRegisterTouchWindow(HWND hWnd, ULONG ulFlags) { + if (m_pRegisterTouchWindow == NULL) { + return FALSE; + } + return m_pRegisterTouchWindow(hWnd, ulFlags); + } + + BOOL AwtToolkit::TIGetTouchInputInfo(HTOUCHINPUT hTouchInput, + UINT cInputs, PTOUCHINPUT pInputs, int cbSize) { + if (m_pGetTouchInputInfo == NULL) { + return FALSE; + } + return m_pGetTouchInputInfo(hTouchInput, cInputs, pInputs, cbSize); + } + + BOOL AwtToolkit::TICloseTouchInputHandle(HTOUCHINPUT hTouchInput) { + if (m_pCloseTouchInputHandle == NULL) { + return FALSE; + } + return m_pCloseTouchInputHandle(hTouchInput); + }
< prev index next >