diff options
-rw-r--r-- | intern/ghost/intern/GHOST_ImeWin32.cpp | 59 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ImeWin32.h | 18 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 16 |
3 files changed, 91 insertions, 2 deletions
diff --git a/intern/ghost/intern/GHOST_ImeWin32.cpp b/intern/ghost/intern/GHOST_ImeWin32.cpp index 112a266ae28..412f7e4276c 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.cpp +++ b/intern/ghost/intern/GHOST_ImeWin32.cpp @@ -34,6 +34,8 @@ GHOST_ImeWin32::GHOST_ImeWin32() : is_composing_(false), ime_status_(false), input_language_id_(LANG_USER_DEFAULT), + conversion_modes_(IME_CMODE_ALPHANUMERIC), + sentence_mode_(IME_SMODE_NONE), system_caret_(false), caret_rect_(-1, -1, 0, 0), is_first(true), @@ -59,6 +61,63 @@ bool GHOST_ImeWin32::SetInputLanguage() return ime_status_; } +WORD GHOST_ImeWin32::GetInputLanguage() +{ + return input_language_id_; +} + +void GHOST_ImeWin32::UpdateConversionStatus(HWND window_handle) +{ + HIMC imm_context = ::ImmGetContext(window_handle); + if (imm_context) { + if (::ImmGetOpenStatus(imm_context)) { + ::ImmGetConversionStatus(imm_context, &conversion_modes_, &sentence_mode_); + } + else { + conversion_modes_ = IME_CMODE_ALPHANUMERIC; + sentence_mode_ = IME_SMODE_NONE; + } + ::ImmReleaseContext(window_handle, imm_context); + } + else { + conversion_modes_ = IME_CMODE_ALPHANUMERIC; + sentence_mode_ = IME_SMODE_NONE; + } +} + +bool GHOST_ImeWin32::IsEnglishMode() +{ + return (conversion_modes_ & IME_CMODE_NOCONVERSION) || + !(conversion_modes_ & (IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE)); +} + +bool GHOST_ImeWin32::IsImeKeyEvent(char ascii) +{ + if (!(IsEnglishMode())) { + /* In Chinese, Japanese, Korena, all alpha keys are processed by IME. */ + if ((ascii >= 'A' && ascii <= 'Z') || (ascii >= 'a' && ascii <= 'z')) { + return true; + } + switch (PRIMARYLANGID(GetInputLanguage())) { + /* In Japanese, all symbolic characters are also processed by IME. */ + case LANG_JAPANESE: { + if (ascii >= ' ' && ascii <= '~') { + return true; + } + break; + } + /* In Chinese, some symbolic characters are also processed by IME. */ + case LANG_CHINESE: { + if (ascii && strchr("!\"$'(),.:;<>?[\\]^_`", ascii)) { + return true; + } + break; + } + } + } + return false; +} + void GHOST_ImeWin32::CreateImeWindow(HWND window_handle) { /** diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h index 4af988aef6e..bcc4b6eef7c 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.h +++ b/intern/ghost/intern/GHOST_ImeWin32.h @@ -156,6 +156,18 @@ class GHOST_ImeWin32 { */ bool SetInputLanguage(); + /* Returns the current input language id. */ + WORD GetInputLanguage(); + + /* Saves the current conversion status. */ + void UpdateConversionStatus(HWND window_handle); + + /* Is the IME currently in conversion mode? */ + bool IsEnglishMode(); + + /* Checks a key whether IME has to do handling. */ + bool IsImeKeyEvent(char ascii); + /** * Create the IME windows, and allocate required resources for them. * Parameters @@ -371,6 +383,12 @@ class GHOST_ImeWin32 { */ LANGID input_language_id_; + /* Current Conversion Mode Values. Retrieved with ImmGetConversionStatus. */ + DWORD conversion_modes_; + + /* Current Sentence Mode. Retrieved with ImmGetConversionStatus. */ + DWORD sentence_mode_; + /** * Represents whether or not the current input context has created a system * caret to set the position of its IME candidate window. diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 694efaaaf03..60fd175dbf7 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1219,6 +1219,12 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA ascii = utf8_char[0] & 0x80 ? '?' : utf8_char[0]; } +#ifdef WITH_INPUT_IME + if (window->getImeInput()->IsImeKeyEvent(ascii)) { + return NULL; + } +#endif /* WITH_INPUT_IME */ + event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, @@ -1419,6 +1425,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, system->handleKeyboardChange(); #ifdef WITH_INPUT_IME window->getImeInput()->SetInputLanguage(); + window->getImeInput()->UpdateConversionStatus(hwnd); #endif break; } @@ -1455,6 +1462,13 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, //////////////////////////////////////////////////////////////////////// // IME events, processed, read more in GHOST_IME.h //////////////////////////////////////////////////////////////////////// + case WM_IME_NOTIFY: { + /* Update conversion status when IME is changed or input mode is changed. */ + if (wParam == IMN_SETOPENSTATUS || wParam == IMN_SETCONVERSIONMODE) { + window->getImeInput()->UpdateConversionStatus(hwnd); + } + break; + } case WM_IME_SETCONTEXT: { GHOST_ImeWin32 *ime = window->getImeInput(); ime->SetInputLanguage(); @@ -1466,8 +1480,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, case WM_IME_STARTCOMPOSITION: { GHOST_ImeWin32 *ime = window->getImeInput(); eventHandled = true; - /* remove input event before start comp event, avoid redundant input */ - eventManager->removeTypeEvents(GHOST_kEventKeyDown, window); ime->CreateImeWindow(hwnd); ime->ResetComposition(hwnd); event = processImeEvent(GHOST_kEventImeCompositionStart, window, &ime->eventImeData); |