< prev index next >
src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
Print this page
@@ -27,10 +27,12 @@
#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,10 +305,17 @@
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,10 +366,153 @@
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,10 +667,56 @@
(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,10 +737,18 @@
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,10 +2951,36 @@
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,5 +3054,126 @@
}
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 >