< prev index next >
src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
Print this page
*** 341,350 ****
--- 341,351 ----
// initialize kb state array
::GetKeyboardState(m_lastKeyboardState);
m_waitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+ m_inputMethodWaitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
isInDoDragDropLoop = FALSE;
eventNumber = 0;
}
AwtToolkit::~AwtToolkit() {
*** 775,784 ****
--- 776,786 ----
tk.m_mainThreadId = 0;
delete tk.m_cmdIDs;
::CloseHandle(m_waitEvent);
+ ::CloseHandle(m_inputMethodWaitEvent);
tk.m_isDisposed = TRUE;
return TRUE;
}
*** 1085,1099 ****
// ImmXXXX() API must be used in the main thread.
// In other thread these APIs does not work correctly even if
// it returs with no error. (This restriction is not documented)
// So we must use thse messages to call these APIs in main thread.
case WM_AWT_CREATECONTEXT: {
! return reinterpret_cast<LRESULT>(
reinterpret_cast<void*>(ImmCreateContext()));
}
case WM_AWT_DESTROYCONTEXT: {
ImmDestroyContext((HIMC)wParam);
return 0;
}
case WM_AWT_ASSOCIATECONTEXT: {
EnableNativeIMEStruct *data = (EnableNativeIMEStruct*)wParam;
--- 1087,1107 ----
// ImmXXXX() API must be used in the main thread.
// In other thread these APIs does not work correctly even if
// it returs with no error. (This restriction is not documented)
// So we must use thse messages to call these APIs in main thread.
case WM_AWT_CREATECONTEXT: {
! AwtToolkit& tk = AwtToolkit::GetInstance();
! tk.m_inputMethodData = reinterpret_cast<LRESULT>(
reinterpret_cast<void*>(ImmCreateContext()));
+ ::SetEvent(tk.m_inputMethodWaitEvent);
+ return tk.m_inputMethodData;
}
case WM_AWT_DESTROYCONTEXT: {
ImmDestroyContext((HIMC)wParam);
+ AwtToolkit& tk = AwtToolkit::GetInstance();
+ tk.m_inputMethodData = 0;
+ ::SetEvent(tk.m_inputMethodWaitEvent);
return 0;
}
case WM_AWT_ASSOCIATECONTEXT: {
EnableNativeIMEStruct *data = (EnableNativeIMEStruct*)wParam;
*** 1115,1142 ****
if (self != NULL) {
env->DeleteGlobalRef(self);
}
delete data;
return 0;
}
case WM_AWT_GET_DEFAULT_IME_HANDLER: {
LRESULT ret = (LRESULT)FALSE;
jobject peer = (jobject)wParam;
AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
if (comp != NULL) {
HWND defaultIMEHandler = ImmGetDefaultIMEWnd(comp->GetHWnd());
if (defaultIMEHandler != NULL) {
! AwtToolkit::GetInstance().SetInputMethodWindow(defaultIMEHandler);
ret = (LRESULT)TRUE;
}
}
if (peer != NULL) {
env->DeleteGlobalRef(peer);
}
return ret;
}
case WM_AWT_HANDLE_NATIVE_IME_EVENT: {
jobject peer = (jobject)wParam;
AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
--- 1123,1156 ----
if (self != NULL) {
env->DeleteGlobalRef(self);
}
delete data;
+ AwtToolkit& tk = AwtToolkit::GetInstance();
+ tk.m_inputMethodData = 0;
+ ::SetEvent(tk.m_inputMethodWaitEvent);
return 0;
}
case WM_AWT_GET_DEFAULT_IME_HANDLER: {
LRESULT ret = (LRESULT)FALSE;
jobject peer = (jobject)wParam;
+ AwtToolkit& tk = AwtToolkit::GetInstance();
AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
if (comp != NULL) {
HWND defaultIMEHandler = ImmGetDefaultIMEWnd(comp->GetHWnd());
if (defaultIMEHandler != NULL) {
! tk.SetInputMethodWindow(defaultIMEHandler);
ret = (LRESULT)TRUE;
}
}
if (peer != NULL) {
env->DeleteGlobalRef(peer);
}
+ tk.m_inputMethodData = ret;
+ ::SetEvent(tk.m_inputMethodWaitEvent);
return ret;
}
case WM_AWT_HANDLE_NATIVE_IME_EVENT: {
jobject peer = (jobject)wParam;
AwtComponent* comp = (AwtComponent*)JNI_GET_PDATA(peer);
*** 1168,1190 ****
--- 1182,1213 ----
/*right now we just cancel the composition string
may need to commit it in the furture
Changed to commit it according to the flag 10/29/98*/
ImmNotifyIME((HIMC)wParam, NI_COMPOSITIONSTR,
(lParam ? CPS_COMPLETE : CPS_CANCEL), 0);
+ AwtToolkit& tk = AwtToolkit::GetInstance();
+ tk.m_inputMethodData = 0;
+ ::SetEvent(tk.m_inputMethodWaitEvent);
return 0;
}
case WM_AWT_SETCONVERSIONSTATUS: {
DWORD cmode;
DWORD smode;
ImmGetConversionStatus((HIMC)wParam, (LPDWORD)&cmode, (LPDWORD)&smode);
ImmSetConversionStatus((HIMC)wParam, (DWORD)LOWORD(lParam), smode);
+ AwtToolkit& tk = AwtToolkit::GetInstance();
+ tk.m_inputMethodData = 0;
+ ::SetEvent(tk.m_inputMethodWaitEvent);
return 0;
}
case WM_AWT_GETCONVERSIONSTATUS: {
DWORD cmode;
DWORD smode;
ImmGetConversionStatus((HIMC)wParam, (LPDWORD)&cmode, (LPDWORD)&smode);
+ AwtToolkit& tk = AwtToolkit::GetInstance();
+ tk.m_inputMethodData = cmode;
+ ::SetEvent(tk.m_inputMethodWaitEvent);
return cmode;
}
case WM_AWT_ACTIVATEKEYBOARDLAYOUT: {
if (wParam && g_bUserHasChangedInputLang) {
// Input language has been changed since the last WInputMethod.getNativeLocale()
*** 1215,1224 ****
--- 1238,1250 ----
DASSERT( !IsBadReadPtr(p, sizeof(AwtObject)));
// fix for 4805862: use GET_X_LPARAM and GET_Y_LPARAM macros
// instead of LOWORD and HIWORD
p->OpenCandidateWindow(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
env->DeleteGlobalRef(peerObject);
+ AwtToolkit& tk = AwtToolkit::GetInstance();
+ tk.m_inputMethodData = 0;
+ ::SetEvent(tk.m_inputMethodWaitEvent);
return 0;
}
/*
* send this message via ::SendMessage() and the MPT will acquire the
*** 1236,1249 ****
return (LRESULT)(*(void*(*)(void))wParam)();
}
case WM_AWT_SETOPENSTATUS: {
ImmSetOpenStatus((HIMC)wParam, (BOOL)lParam);
return 0;
}
case WM_AWT_GETOPENSTATUS: {
! return (DWORD)ImmGetOpenStatus((HIMC)wParam);
}
case WM_DISPLAYCHANGE: {
// Reinitialize screens
initScreens(env);
--- 1262,1281 ----
return (LRESULT)(*(void*(*)(void))wParam)();
}
case WM_AWT_SETOPENSTATUS: {
ImmSetOpenStatus((HIMC)wParam, (BOOL)lParam);
+ AwtToolkit& tk = AwtToolkit::GetInstance();
+ tk.m_inputMethodData = 0;
+ ::SetEvent(tk.m_inputMethodWaitEvent);
return 0;
}
case WM_AWT_GETOPENSTATUS: {
! AwtToolkit& tk = AwtToolkit::GetInstance();
! tk.m_inputMethodData = (DWORD)ImmGetOpenStatus((HIMC)wParam);
! ::SetEvent(tk.m_inputMethodWaitEvent);
! return tk.m_inputMethodData;
}
case WM_DISPLAYCHANGE: {
// Reinitialize screens
initScreens(env);
*** 3164,3168 ****
--- 3196,3220 ----
if (m_pCloseTouchInputHandle == NULL) {
return FALSE;
}
return m_pCloseTouchInputHandle(hTouchInput);
}
+
+ /*
+ * The fuction intended for access to an IME API. It posts IME message to the queue and
+ * waits untill the message processing is completed.
+ *
+ * On Windows 10 the IME may process the messages send via SenMessage() from other threads
+ * when the IME is called by TranslateMessage(). This may cause an reentrancy issue when
+ * the windows procedure processing the sent message call an IME function and leaves
+ * the IME functionality in an unexpected state.
+ * This function avoids reentrancy issue and must be used for sending of all IME messages
+ * instead of SendMessage().
+ */
+ LRESULT AwtToolkit::InvokeInputMethodFunction(UINT msg, WPARAM wParam, LPARAM lParam) {
+ CriticalSection::Lock lock(m_inputMethodLock);
+ if (PostMessage(msg, wParam, lParam)) {
+ ::WaitForSingleObject(m_inputMethodWaitEvent, INFINITE);
+ return m_inputMethodData;
+ }
+ return 0;
+ }
< prev index next >