https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9db4437185c5891cbb690487b95d922d3ad4049e

commit 9db4437185c5891cbb690487b95d922d3ad4049e
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Tue Feb 8 12:22:08 2022 +0900
Commit:     GitHub <[email protected]>
CommitDate: Tue Feb 8 12:22:08 2022 +0900

    [NTUSER] Implement NtUserNotifyIMEStatus (#4345)
    
    - Define "the special virtual keys for Japanese".
    - Add UserSetImeConversionKeyState helper function.
    - Implement NtUserNotifyIMEStatus function.
    CORE-11700
---
 win32ss/user/ntuser/ime.c | 115 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 114 insertions(+), 1 deletion(-)

diff --git a/win32ss/user/ntuser/ime.c b/win32ss/user/ntuser/ime.c
index 98007549568..5c67c673afe 100644
--- a/win32ss/user/ntuser/ime.c
+++ b/win32ss/user/ntuser/ime.c
@@ -16,6 +16,27 @@ DBG_DEFAULT_CHANNEL(UserMisc);
     (((pwnd)->pcls->style & CS_IME) || \
      ((pwnd)->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME]))
 
+// The special virtual keys for Japanese: Used for key states.
+// https://www.kthree.co.jp/kihelp/index.html?page=app/vkey&type=html
+#define VK_DBE_ALPHANUMERIC 0xF0
+#define VK_DBE_KATAKANA 0xF1
+#define VK_DBE_HIRAGANA 0xF2
+#define VK_DBE_SBCSCHAR 0xF3
+#define VK_DBE_DBCSCHAR 0xF4
+#define VK_DBE_ROMAN 0xF5
+#define VK_DBE_NOROMAN 0xF6
+#define VK_DBE_ENTERWORDREGISTERMODE 0xF7
+#define VK_DBE_ENTERCONFIGMODE 0xF8
+#define VK_DBE_FLUSHSTRING 0xF9
+#define VK_DBE_CODEINPUT 0xFA
+#define VK_DBE_NOCODEINPUT 0xFB
+#define VK_DBE_DETERINESTRING 0xFC
+#define VK_DBE_ENTERDLGCONVERSIONMODE 0xFD
+
+HIMC ghIMC = NULL;
+BOOL gfImeOpen = (BOOL)-1;
+DWORD gdwImeConversion = (DWORD)-1;
+
 PWND FASTCALL IntGetTopLevelWindow(PWND pwnd)
 {
     if (!pwnd)
@@ -184,11 +205,103 @@ NtUserGetImeHotKey(IN DWORD dwHotKey,
    return FALSE;
 }
 
+static VOID FASTCALL UserSetImeConversionKeyState(PTHREADINFO pti, DWORD 
dwConversion)
+{
+    HKL hKL;
+    LANGID LangID;
+    LPBYTE KeyState;
+    BOOL bAlphaNumeric, bKatakana, bHiragana, bFullShape, bRoman, bCharCode;
+
+    if (!pti->KeyboardLayout)
+        return;
+
+    hKL = pti->KeyboardLayout->hkl;
+    LangID = LOWORD(hKL);
+    KeyState = pti->MessageQueue->afKeyState;
+
+    switch (PRIMARYLANGID(LangID))
+    {
+        case LANG_JAPANESE:
+            bAlphaNumeric = !(dwConversion & IME_CMODE_NATIVE);
+            bKatakana = !bAlphaNumeric && (dwConversion & IME_CMODE_KATAKANA);
+            bHiragana = !bAlphaNumeric && !(dwConversion & IME_CMODE_KATAKANA);
+            SET_KEY_DOWN(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
+            SET_KEY_LOCKED(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
+            SET_KEY_DOWN(KeyState, VK_DBE_HIRAGANA, bHiragana);
+            SET_KEY_LOCKED(KeyState, VK_DBE_HIRAGANA, bHiragana);
+            SET_KEY_DOWN(KeyState, VK_DBE_KATAKANA, bKatakana);
+            SET_KEY_LOCKED(KeyState, VK_DBE_KATAKANA, bKatakana);
+
+            bFullShape = (dwConversion & IME_CMODE_FULLSHAPE);
+            SET_KEY_DOWN(KeyState, VK_DBE_DBCSCHAR, bFullShape);
+            SET_KEY_LOCKED(KeyState, VK_DBE_DBCSCHAR, bFullShape);
+            SET_KEY_DOWN(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
+            SET_KEY_LOCKED(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
+
+            bRoman = (dwConversion & IME_CMODE_ROMAN);
+            SET_KEY_DOWN(KeyState, VK_DBE_ROMAN, bRoman);
+            SET_KEY_LOCKED(KeyState, VK_DBE_ROMAN, bRoman);
+            SET_KEY_DOWN(KeyState, VK_DBE_NOROMAN, !bRoman);
+            SET_KEY_LOCKED(KeyState, VK_DBE_NOROMAN, !bRoman);
+
+            bCharCode = (dwConversion & IME_CMODE_CHARCODE);
+            SET_KEY_DOWN(KeyState, VK_DBE_CODEINPUT, bCharCode);
+            SET_KEY_LOCKED(KeyState, VK_DBE_CODEINPUT, bCharCode);
+            SET_KEY_DOWN(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
+            SET_KEY_LOCKED(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
+            break;
+
+        case LANG_KOREAN:
+            SET_KEY_LOCKED(KeyState, VK_HANGUL, (dwConversion & 
IME_CMODE_NATIVE));
+            SET_KEY_LOCKED(KeyState, VK_JUNJA, (dwConversion & 
IME_CMODE_FULLSHAPE));
+            SET_KEY_LOCKED(KeyState, VK_HANJA, (dwConversion & 
IME_CMODE_HANJACONVERT));
+            break;
+
+        default:
+            break;
+    }
+}
+
 DWORD
 APIENTRY
 NtUserNotifyIMEStatus(HWND hwnd, BOOL fOpen, DWORD dwConversion)
 {
-    TRACE("NtUserNotifyIMEStatus(%p, %d, 0x%lX)\n", hwnd, fOpen, dwConversion);
+    PWND pwnd;
+    PTHREADINFO pti;
+    HKL hKL;
+
+    UserEnterExclusive();
+
+    pwnd = ValidateHwndNoErr(hwnd);
+    if (!pwnd || !IS_IMM_MODE())
+        goto Quit;
+
+    pti = pwnd->head.pti;
+    if (!pti || !gptiForeground)
+        goto Quit;
+    if (pti != gptiForeground && pti->MessageQueue != 
gptiForeground->MessageQueue)
+        goto Quit;
+    if (ghIMC == pwnd->hImc && gfImeOpen == !!fOpen && gdwImeConversion == 
dwConversion)
+        goto Quit;
+
+    ghIMC = pwnd->hImc;
+    if (ghIMC)
+    {
+        gfImeOpen = !!fOpen;
+        gdwImeConversion = dwConversion;
+        UserSetImeConversionKeyState(pti, (fOpen ? dwConversion : 
IME_CMODE_ALPHANUMERIC));
+    }
+
+    if (ISITHOOKED(WH_SHELL))
+    {
+        hKL = (pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL);
+        co_HOOK_CallHooks(WH_SHELL, HSHELL_LANGUAGE, (WPARAM)hwnd, 
(LPARAM)hKL);
+    }
+
+    // TODO:
+
+Quit:
+    UserLeave();
     return 0;
 }
 

Reply via email to