https://git.reactos.org/?p=reactos.git;a=commitdiff;h=75cf6920bc62f70dc481be5f5d0e63e18cfafd81

commit 75cf6920bc62f70dc481be5f5d0e63e18cfafd81
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Sun Dec 3 17:33:22 2023 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Sun Dec 3 17:33:22 2023 +0900

    [IMM32][SDK][NTUSER] Implement ImmProcessKey for Cicero (#6106)
    
    Complete CTF IMM.
    - Add CtfImeProcessCicHotkey and CtfImeSetActiveContextAlways
      to access CTF IMEs.
    - Check whether Cicero is started in the current thread in ImmProcessKey.
    - Call CtfImeProcessCicHotkey if necessary in ImmProcessKey.
    - Modify <CtfImeTable.h>.
    - Add CI_CICERO_STARTED flag to "ntuser.h".
    - Fix Imm32JCloseOpen.
    CORE-19268
---
 dll/win32/imm32/ctf.c             | 106 +++++++++++++++++++++++++++++-
 dll/win32/imm32/imm.c             |   9 +--
 dll/win32/imm32/keymsg.c          | 134 +++++++++++---------------------------
 dll/win32/imm32/precomp.h         |  18 +++++
 sdk/include/reactos/CtfImeTable.h |   4 +-
 win32ss/include/ntuser.h          |   1 +
 6 files changed, 163 insertions(+), 109 deletions(-)

diff --git a/dll/win32/imm32/ctf.c b/dll/win32/imm32/ctf.c
index 23e4b41c3ed..f4463cc67f1 100644
--- a/dll/win32/imm32/ctf.c
+++ b/dll/win32/imm32/ctf.c
@@ -738,6 +738,20 @@ CtfImeCreateThreadMgr(VOID)
     return CTF_IME_FN(CtfImeCreateThreadMgr)();
 }
 
+/***********************************************************************
+ * This function calls the same name function of the CTF IME side.
+ */
+BOOL
+CtfImeProcessCicHotkey(_In_ HIMC hIMC, _In_ UINT vKey, _In_ LPARAM lParam)
+{
+    TRACE("(%p, %u, %p)\n", hIMC, vKey, lParam);
+
+    if (!Imm32LoadCtfIme())
+        return FALSE;
+
+    return CTF_IME_FN(CtfImeProcessCicHotkey)(hIMC, vKey, lParam);
+}
+
 /***********************************************************************
  * This function calls the same name function of the CTF IME side.
  */
@@ -775,7 +789,7 @@ BOOL WINAPI
 CtfImmIsCiceroStartedInThread(VOID)
 {
     TRACE("()\n");
-    return !!(GetWin32ClientInfo()->CI_flags & 0x200);
+    return !!(GetWin32ClientInfo()->CI_flags & CI_CICERO_STARTED);
 }
 
 /***********************************************************************
@@ -785,9 +799,9 @@ VOID WINAPI CtfImmSetCiceroStartInThread(_In_ BOOL bStarted)
 {
     TRACE("(%d)\n", bStarted);
     if (bStarted)
-        GetWin32ClientInfo()->CI_flags |= 0x200;
+        GetWin32ClientInfo()->CI_flags |= CI_CICERO_STARTED;
     else
-        GetWin32ClientInfo()->CI_flags &= ~0x200;
+        GetWin32ClientInfo()->CI_flags &= ~CI_CICERO_STARTED;
 }
 
 /***********************************************************************
@@ -832,6 +846,24 @@ CtfImeDestroyInputContext(_In_ HIMC hIMC)
     return CTF_IME_FN(CtfImeDestroyInputContext)(hIMC);
 }
 
+/***********************************************************************
+ * This function calls the same name function of the CTF IME side.
+ */
+HRESULT
+CtfImeSetActiveContextAlways(
+    _In_ HIMC hIMC,
+    _In_ BOOL fActive,
+    _In_ HWND hWnd,
+    _In_ HKL hKL)
+{
+    TRACE("(%p, %d, %p, %p)\n", hIMC, fActive, hWnd, hKL);
+
+    if (!Imm32LoadCtfIme())
+        return E_FAIL;
+
+    return CTF_IME_FN(CtfImeSetActiveContextAlways)(hIMC, fActive, hWnd, hKL);
+}
+
 /***********************************************************************
  * The callback function to activate CTF IMEs. Used in CtfAImmActivate.
  */
@@ -1173,6 +1205,74 @@ CtfImmTIMActivate(_In_ HKL hKL)
     return hr;
 }
 
+/***********************************************************************
+ * Setting language band
+ */
+
+typedef struct IMM_DELAY_SET_LANG_BAND
+{
+    HWND hWnd;
+    BOOL fSet;
+} IMM_DELAY_SET_LANG_BAND, *PIMM_DELAY_SET_LANG_BAND;
+
+/* Sends a message to set the language band with delay. */
+static DWORD APIENTRY Imm32DelaySetLangBandProc(LPVOID arg)
+{
+    HWND hwndDefIME;
+    WPARAM wParam;
+    DWORD_PTR lResult;
+    PIMM_DELAY_SET_LANG_BAND pSetBand = arg;
+
+    Sleep(3000); /* Delay 3 seconds! */
+
+    hwndDefIME = ImmGetDefaultIMEWnd(pSetBand->hWnd);
+    if (hwndDefIME)
+    {
+        wParam = (pSetBand->fSet ? IMS_SETLANGBAND : IMS_UNSETLANGBAND);
+        SendMessageTimeoutW(hwndDefIME, WM_IME_SYSTEM, wParam, 
(LPARAM)pSetBand->hWnd,
+                            SMTO_BLOCK | SMTO_ABORTIFHUNG, 5000, &lResult);
+    }
+    ImmLocalFree(pSetBand);
+    return FALSE;
+}
+
+/* Updates the language band. */
+LRESULT
+CtfImmSetLangBand(
+    _In_ HWND hWnd,
+    _In_ BOOL fSet)
+{
+    HANDLE hThread;
+    PWND pWnd = NULL;
+    PIMM_DELAY_SET_LANG_BAND pSetBand;
+    DWORD_PTR lResult = 0;
+
+    if (hWnd && gpsi)
+        pWnd = ValidateHwndNoErr(hWnd);
+
+    if (IS_NULL_UNEXPECTEDLY(pWnd))
+        return 0;
+
+    if (pWnd->state2 & WNDS2_WMCREATEMSGPROCESSED)
+    {
+        SendMessageTimeoutW(hWnd, WM_USER + 0x105, 0, fSet, SMTO_BLOCK | 
SMTO_ABORTIFHUNG,
+                            5000, &lResult);
+        return lResult;
+    }
+
+    pSetBand = ImmLocalAlloc(0, sizeof(IMM_DELAY_SET_LANG_BAND));
+    if (IS_NULL_UNEXPECTEDLY(pSetBand))
+        return 0;
+
+    pSetBand->hWnd = hWnd;
+    pSetBand->fSet = fSet;
+
+    hThread = CreateThread(NULL, 0, Imm32DelaySetLangBandProc, pSetBand, 0, 
NULL);
+    if (hThread)
+        CloseHandle(hThread);
+    return 0;
+}
+
 /***********************************************************************
  *             CtfImmGenerateMessage (IMM32.@)
  */
diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index 3ea5bae50ea..aa81c0935bd 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -183,7 +183,6 @@ Retry:
     return TRUE;
 }
 
-// Win: SelectInputContext
 VOID APIENTRY Imm32SelectInputContext(HKL hNewKL, HKL hOldKL, HIMC hIMC)
 {
     PCLIENTIMC pClientImc;
@@ -490,12 +489,6 @@ BOOL WINAPI ImmActivateLayout(HKL hKL)
     return TRUE;
 }
 
-/* Win: Internal_CtfImeSetActiveContextAlways */
-static VOID APIENTRY Imm32CiceroSetActiveContext(HIMC hIMC, BOOL fActive, HWND 
hWnd, HKL hKL)
-{
-    TRACE("We have to do something\n");
-}
-
 /***********************************************************************
  *             ImmAssociateContext (IMM32.@)
  */
@@ -1196,7 +1189,7 @@ BOOL WINAPI ImmSetActiveContext(HWND hWnd, HIMC hIMC, 
BOOL fActive)
     hKL = GetKeyboardLayout(0);
     if (IS_CICERO_MODE() && !IS_16BIT_MODE())
     {
-        Imm32CiceroSetActiveContext(hIMC, fActive, hWnd, hKL);
+        CtfImeSetActiveContextAlways(hIMC, fActive, hWnd, hKL);
         hKL = GetKeyboardLayout(0);
     }
 
diff --git a/dll/win32/imm32/keymsg.c b/dll/win32/imm32/keymsg.c
index 4131b751071..f1dd211b607 100644
--- a/dll/win32/imm32/keymsg.c
+++ b/dll/win32/imm32/keymsg.c
@@ -158,7 +158,6 @@ BOOL APIENTRY Imm32CSymbolToggle(HIMC hIMC, HKL hKL, HWND 
hWnd)
 }
 
 /* Open or close Japanese IME */
-/* Win: JCloseOpen */
 BOOL APIENTRY Imm32JCloseOpen(HIMC hIMC, HKL hKL, HWND hWnd)
 {
     BOOL fOpen;
@@ -177,7 +176,7 @@ BOOL APIENTRY Imm32JCloseOpen(HIMC hIMC, HKL hKL, HWND hWnd)
         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
         if (pIC)
         {
-            pIC->dwChange |= INPUTCONTEXTDX_CHANGE_OPEN; /* Notify open change 
*/
+            pIC->dwChange |= INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
             ImmUnlockIMC(hIMC);
         }
     }
@@ -331,85 +330,23 @@ ImmIsUIMessageAW(HWND hWndIME, UINT msg, WPARAM wParam, 
LPARAM lParam, BOOL bAns
     return TRUE;
 }
 
-typedef struct IMM_DELAY_SET_LANG_BAND
-{
-    HWND hWnd;
-    BOOL fSet;
-} IMM_DELAY_SET_LANG_BAND, *PIMM_DELAY_SET_LANG_BAND;
-
-/* Sends a message to set the language band with delay. */
-/* Win: DelaySetLangBand */
-static DWORD APIENTRY Imm32DelaySetLangBandProc(LPVOID arg)
-{
-    HWND hwndDefIME;
-    WPARAM wParam;
-    DWORD_PTR lResult;
-    PIMM_DELAY_SET_LANG_BAND pSetBand = arg;
-
-    Sleep(3000); /* Delay 3 seconds! */
-
-    hwndDefIME = ImmGetDefaultIMEWnd(pSetBand->hWnd);
-    if (hwndDefIME)
-    {
-        wParam = (pSetBand->fSet ? IMS_SETLANGBAND : IMS_UNSETLANGBAND);
-        SendMessageTimeoutW(hwndDefIME, WM_IME_SYSTEM, wParam, 
(LPARAM)pSetBand->hWnd,
-                            SMTO_BLOCK | SMTO_ABORTIFHUNG, 5000, &lResult);
-    }
-    ImmLocalFree(pSetBand);
-    return FALSE;
-}
-
-/* Updates the language band. */
-/* Win: CtfImmSetLangBand */
-LRESULT APIENTRY CtfImmSetLangBand(HWND hWnd, BOOL fSet)
-{
-    HANDLE hThread;
-    PWND pWnd = NULL;
-    PIMM_DELAY_SET_LANG_BAND pSetBand;
-    DWORD_PTR lResult = 0;
-
-    if (hWnd && gpsi)
-        pWnd = ValidateHwndNoErr(hWnd);
-
-    if (IS_NULL_UNEXPECTEDLY(pWnd))
-        return 0;
-
-    if (pWnd->state2 & WNDS2_WMCREATEMSGPROCESSED)
-    {
-        SendMessageTimeoutW(hWnd, WM_USER + 0x105, 0, fSet, SMTO_BLOCK | 
SMTO_ABORTIFHUNG,
-                            5000, &lResult);
-        return lResult;
-    }
-
-    pSetBand = ImmLocalAlloc(0, sizeof(IMM_DELAY_SET_LANG_BAND));
-    if (IS_NULL_UNEXPECTEDLY(pSetBand))
-        return 0;
-
-    pSetBand->hWnd = hWnd;
-    pSetBand->fSet = fSet;
-
-    hThread = CreateThread(NULL, 0, Imm32DelaySetLangBandProc, pSetBand, 0, 
NULL);
-    if (hThread)
-        CloseHandle(hThread);
-    return 0;
-}
-
-/* Win: SendNotificationProc */
-static BOOL CALLBACK Imm32SendNotificationProc(HIMC hIMC, LPARAM lParam)
+static BOOL CALLBACK
+Imm32SendNotificationProc(
+    _In_ HIMC hIMC,
+    _In_ LPARAM lParam)
 {
     HWND hWnd;
     LPINPUTCONTEXTDX pIC;
 
+    UNREFERENCED_PARAMETER(lParam);
+
     pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
     if (IS_NULL_UNEXPECTEDLY(pIC))
         return TRUE;
 
     hWnd = pIC->hWnd;
-    if (hWnd == NULL || !IsWindow(hWnd))
-    {
-        ERR("\n");
+    if (!IsWindow(hWnd))
         goto Quit;
-    }
 
     TRACE("dwChange: 0x%08X\n", pIC->dwChange);
 
@@ -427,7 +364,6 @@ Quit:
     return TRUE;
 }
 
-/* Win: ImmSendNotification */
 BOOL APIENTRY Imm32SendNotification(BOOL bProcess)
 {
     return ImmEnumInputContext((bProcess ? -1 : 0), Imm32SendNotificationProc, 
0);
@@ -783,11 +719,11 @@ ImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM 
lParam, DWORD dwHotKeyID)
     PIMEDPI pImeDpi;
     LPINPUTCONTEXTDX pIC;
     BYTE KeyState[256];
-    UINT vk;
-    BOOL bUseIme = TRUE, bSkipThisKey = FALSE, bLowWordOnly = FALSE;
+    BOOL bLowWordOnly = FALSE, bSkipThisKey = FALSE, bHotKeyDone = TRUE;
 
     TRACE("(%p, %p, 0x%X, %p, 0x%lX)\n", hWnd, hKL, vKey, lParam, dwHotKeyID);
 
+    /* Process the key by the IME */
     hIMC = ImmGetContext(hWnd);
     pImeDpi = ImmLockImeDpi(hKL);
     if (pImeDpi)
@@ -795,7 +731,7 @@ ImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, 
DWORD dwHotKeyID)
         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
         if (pIC)
         {
-            if (LOBYTE(vKey) == VK_PACKET &&
+            if ((LOBYTE(vKey) == VK_PACKET) &&
                 !(pImeDpi->ImeInfo.fdwProperty & IME_PROP_ACCEPT_WIDE_VKEY))
             {
                 if (ImeDpi_IsUnicode(pImeDpi))
@@ -804,29 +740,23 @@ ImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM 
lParam, DWORD dwHotKeyID)
                 }
                 else
                 {
-                    bUseIme = FALSE;
                     if (pIC->fOpen)
-                        bSkipThisKey = TRUE;
+                        ret |= IPHK_SKIPTHISKEY;
+
+                    bSkipThisKey = TRUE;
                 }
             }
 
-            if (bUseIme)
+            if (!bSkipThisKey && GetKeyboardState(KeyState))
             {
-                if (GetKeyboardState(KeyState))
+                UINT vk = (bLowWordOnly ? LOWORD(vKey) : vKey);
+                if (pImeDpi->ImeProcessKey(hIMC, vk, lParam, KeyState))
                 {
-                    vk = (bLowWordOnly ? LOWORD(vKey) : vKey);
-                    if (pImeDpi->ImeProcessKey(hIMC, vk, lParam, KeyState))
-                    {
-                        pIC->bNeedsTrans = TRUE;
-                        pIC->nVKey = vKey;
-                        ret |= IPHK_PROCESSBYIME;
-                    }
+                    pIC->bNeedsTrans = TRUE;
+                    pIC->nVKey = vKey;
+                    ret |= IPHK_PROCESSBYIME;
                 }
             }
-            else if (bSkipThisKey)
-            {
-                ret |= IPHK_SKIPTHISKEY;
-            }
 
             ImmUnlockIMC(hIMC);
         }
@@ -834,21 +764,32 @@ ImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM 
lParam, DWORD dwHotKeyID)
         ImmUnlockImeDpi(pImeDpi);
     }
 
-    if (dwHotKeyID != INVALID_HOTKEY_ID) /* Valid Hot-key */
+    /* Process the hot-key if necessary */
+    if (!CtfImmIsCiceroStartedInThread()) /* Not Cicero? */
+    {
+        /* Process IMM IME hotkey */
+        if ((dwHotKeyID == INVALID_HOTKEY_ID) || !Imm32ProcessHotKey(hWnd, 
hIMC, hKL, dwHotKeyID))
+            bHotKeyDone = FALSE;
+    }
+    else if (!CtfImeProcessCicHotkey(hIMC, vKey, lParam)) /* CTF IME not 
processed the hotkey? */
     {
-        if (Imm32ProcessHotKey(hWnd, hIMC, hKL, dwHotKeyID))
+        /* Process IMM IME hotkey */
+        if (!IS_IME_HKL(hKL) ||
+            ((dwHotKeyID == INVALID_HOTKEY_ID) || !Imm32ProcessHotKey(hWnd, 
hIMC, hKL, dwHotKeyID)))
         {
-            if (vKey != VK_KANJI || dwHotKeyID != IME_JHOTKEY_CLOSE_OPEN)
-                ret |= IPHK_HOTKEY;
+            bHotKeyDone = FALSE;
         }
     }
 
+    if (bHotKeyDone && ((vKey != VK_KANJI) || (dwHotKeyID != 
IME_JHOTKEY_CLOSE_OPEN)))
+        ret |= IPHK_HOTKEY;
+
     if ((ret & IPHK_PROCESSBYIME) && (ImmGetAppCompatFlags(hIMC) & 0x10000))
     {
         /* The key has been processed by IME's ImeProcessKey */
         LANGID wLangID = LANGIDFROMLCID(GetSystemDefaultLCID());
-        if (PRIMARYLANGID(wLangID) == LANG_KOREAN &&
-            (vKey == VK_PROCESSKEY || (ret & IPHK_HOTKEY)))
+        if ((PRIMARYLANGID(wLangID) == LANG_KOREAN) &&
+            ((vKey == VK_PROCESSKEY) || (ret & IPHK_HOTKEY)))
         {
             /* Korean don't want VK_PROCESSKEY and IME hot-keys */
         }
@@ -856,6 +797,7 @@ ImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, 
DWORD dwHotKeyID)
         {
             /* Add WM_KEYDOWN:VK_PROCESSKEY message */
             ImmTranslateMessage(hWnd, WM_KEYDOWN, VK_PROCESSKEY, lParam);
+
             ret &= ~IPHK_PROCESSBYIME;
             ret |= IPHK_SKIPTHISKEY;
         }
diff --git a/dll/win32/imm32/precomp.h b/dll/win32/imm32/precomp.h
index 3f667d1d6f5..cb87f48890c 100644
--- a/dll/win32/imm32/precomp.h
+++ b/dll/win32/imm32/precomp.h
@@ -201,3 +201,21 @@ HRESULT CtfImmCoInitialize(VOID);
 HRESULT CtfImeCreateThreadMgr(VOID);
 HRESULT CtfImeDestroyThreadMgr(VOID);
 HRESULT Imm32ActivateOrDeactivateTIM(_In_ BOOL bCreate);
+
+HRESULT
+CtfImeSetActiveContextAlways(
+    _In_ HIMC hIMC,
+    _In_ BOOL fActive,
+    _In_ HWND hWnd,
+    _In_ HKL hKL);
+
+BOOL
+CtfImeProcessCicHotkey(
+    _In_ HIMC hIMC,
+    _In_ UINT vKey,
+    _In_ LPARAM lParam);
+
+LRESULT
+CtfImmSetLangBand(
+    _In_ HWND hWnd,
+    _In_ BOOL fSet);
diff --git a/sdk/include/reactos/CtfImeTable.h 
b/sdk/include/reactos/CtfImeTable.h
index 14f701b6c46..99a208e6f42 100644
--- a/sdk/include/reactos/CtfImeTable.h
+++ b/sdk/include/reactos/CtfImeTable.h
@@ -12,7 +12,7 @@ DEFINE_CTF_IME_FN(CtfImeCreateThreadMgr, HRESULT, (VOID))
 DEFINE_CTF_IME_FN(CtfImeDestroyThreadMgr, HRESULT, (VOID))
 DEFINE_CTF_IME_FN(CtfImeCreateInputContext, HRESULT, (HIMC hIMC))
 DEFINE_CTF_IME_FN(CtfImeDestroyInputContext, HRESULT, (HIMC hIMC))
-DEFINE_CTF_IME_FN(CtfImeSetActiveContextAlways, HRESULT, (DWORD dwFIXME1, 
DWORD dwFIXME2, DWORD dwFIXME3, DWORD dwFIXME4))
-DEFINE_CTF_IME_FN(CtfImeProcessCicHotkey, HRESULT, (DWORD dwFIXME1, DWORD 
dwFIXME2, DWORD dwFIXME3))
+DEFINE_CTF_IME_FN(CtfImeSetActiveContextAlways, HRESULT, (HIMC hIMC, BOOL 
fActive, HWND hWnd, HKL hKL))
+DEFINE_CTF_IME_FN(CtfImeProcessCicHotkey, HRESULT, (HIMC hIMC, UINT vKey, 
LPARAM lParam))
 DEFINE_CTF_IME_FN(CtfImeDispatchDefImeMessage, LRESULT, (HWND hWnd, UINT uMsg, 
WPARAM wParam, LPARAM lParam))
 DEFINE_CTF_IME_FN(CtfImeIsIME, BOOL, (HKL hKL))
diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h
index 2763b4b24cc..c5e08f83ac2 100644
--- a/win32ss/include/ntuser.h
+++ b/win32ss/include/ntuser.h
@@ -305,6 +305,7 @@ typedef struct _CALLBACKWND
 #define CI_IMMACTIVATE       0x00000040 /* IMM/IME (Asian input) */
 #define CI_CTFCOINIT         0x00000080 /* Did CTF CoInitialize? */
 #define CI_CTFTIM            0x00000100 /* CTF Thread Input Manager (TIM) */
+#define CI_CICERO_STARTED    0x00000200 /* Is Cicero started in the thread? */
 #define CI_TSFDISABLED       0x00000400 /* TSF (Text Services Framework a.k.a. 
Cicero) */
 #define CI_AIMMACTIVATED     0x00000800 /* Active IMM (AIMM) */
 

Reply via email to