Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/ghost')
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.cpp59
-rw-r--r--intern/ghost/intern/GHOST_ImeWin32.h18
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp16
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);