https://git.reactos.org/?p=reactos.git;a=commitdiff;h=75cf6920bc62f70dc481b…
commit 75cf6920bc62f70dc481be5f5d0e63e18cfafd81
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Dec 3 17:33:22 2023 +0900
Commit: GitHub <noreply(a)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) */