< 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 >