https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b5c9d532e83c7a2d0d1086...
commit b5c9d532e83c7a2d0d10863b26e2592c6f74bcce Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sat Feb 12 08:32:13 2022 +0900 Commit: GitHub noreply@github.com CommitDate: Sat Feb 12 08:32:13 2022 +0900
[NTUSER][USER32] Implement IntImmProcessKey (#4353)
- Establish the trampoline callback USER32_CALLBACK_IMMPROCESSKEY for imm32!ImmProcessKey function, between NTUSER and IMM32. - Add IntGetImeCompatFlags helper function. - Implement co_IntImmProcessKey and IntImmProcessKey functions. CORE-11700 --- win32ss/include/callback.h | 14 ++- win32ss/user/ntuser/callback.c | 24 +++++ win32ss/user/ntuser/callback.h | 4 + win32ss/user/ntuser/ime.c | 197 ++++++++++++++++++++++++++++++++----- win32ss/user/user32/misc/dllmain.c | 15 ++- 5 files changed, 226 insertions(+), 28 deletions(-)
diff --git a/win32ss/include/callback.h b/win32ss/include/callback.h index 7eef1d6c278..a75a6de3803 100644 --- a/win32ss/include/callback.h +++ b/win32ss/include/callback.h @@ -19,7 +19,8 @@ #define USER32_CALLBACK_SETOBM (15) #define USER32_CALLBACK_LPK (16) #define USER32_CALLBACK_UMPD (17) -#define USER32_CALLBACK_MAXIMUM (17) +#define USER32_CALLBACK_IMMPROCESSKEY (18) +#define USER32_CALLBACK_MAXIMUM (18)
typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS { @@ -168,6 +169,15 @@ typedef struct _LPK_CALLBACK_ARGUMENTS BOOL bRect; } LPK_CALLBACK_ARGUMENTS, *PLPK_CALLBACK_ARGUMENTS;
+typedef struct _IMMPROCESSKEY_CALLBACK_ARGUMENTS +{ + HWND hWnd; + HKL hKL; + UINT vKey; + LPARAM lParam; + DWORD dwHotKeyID; +} IMMPROCESSKEY_CALLBACK_ARGUMENTS, *PIMMPROCESSKEY_CALLBACK_ARGUMENTS; + NTSTATUS WINAPI User32CallCopyImageFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI @@ -204,4 +214,6 @@ NTSTATUS WINAPI User32CallLPKFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI User32CallUMPDFromKernel(PVOID Arguments, ULONG ArgumentLength); +NTSTATUS WINAPI +User32CallImmProcessKeyFromKernel(PVOID Arguments, ULONG ArgumentLength); #endif /* __INCLUDE_USER32_CALLBACK_H */ diff --git a/win32ss/user/ntuser/callback.c b/win32ss/user/ntuser/callback.c index 25e6eee5dd7..9b5ac56965a 100644 --- a/win32ss/user/ntuser/callback.c +++ b/win32ss/user/ntuser/callback.c @@ -1247,4 +1247,28 @@ co_UserCBClientPrinterThunk( PVOID pkt, INT InSize, PVOID pvOutData, INT OutSize return 0; }
+DWORD +APIENTRY +co_IntImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, DWORD dwHotKeyID) +{ + DWORD ret = 0; + NTSTATUS Status; + ULONG ResultLength = sizeof(DWORD); + PVOID ResultPointer = NULL; + IMMPROCESSKEY_CALLBACK_ARGUMENTS Common = { hWnd, hKL, vKey, lParam, dwHotKeyID }; + + UserLeaveCo(); + Status = KeUserModeCallback(USER32_CALLBACK_IMMPROCESSKEY, + &Common, + sizeof(Common), + &ResultPointer, + &ResultLength); + UserEnterCo(); + + if (NT_SUCCESS(Status)) + ret = *(LPDWORD)ResultPointer; + + return ret; +} + /* EOF */ diff --git a/win32ss/user/ntuser/callback.h b/win32ss/user/ntuser/callback.h index c83be89a976..79217f86425 100644 --- a/win32ss/user/ntuser/callback.h +++ b/win32ss/user/ntuser/callback.h @@ -76,3 +76,7 @@ BOOL FASTCALL co_IntSetWndIcons(VOID); VOID FASTCALL co_IntDeliverUserAPC(VOID); VOID FASTCALL co_IntSetupOBM(VOID); BOOL FASTCALL IntMsgCreateStructW(PWND,CREATESTRUCTW*,CREATESTRUCTW*,PVOID*,PVOID*); + +DWORD +APIENTRY +co_IntImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, DWORD dwHotKeyID); diff --git a/win32ss/user/ntuser/ime.c b/win32ss/user/ntuser/ime.c index 1ea65ef512b..f7c67164c4e 100644 --- a/win32ss/user/ntuser/ime.c +++ b/win32ss/user/ntuser/ime.c @@ -58,6 +58,14 @@ typedef struct tagIMEHOTKEY PIMEHOTKEY gpImeHotKeyList = NULL; LCID glcid = 0;
+DWORD FASTCALL IntGetImeCompatFlags(PTHREADINFO pti) +{ + if (!pti) + pti = PsGetCurrentThreadWin32Thread(); + + return pti->ppi->dwImeCompatFlags; +} + UINT FASTCALL IntGetImeHotKeyLanguageScore(HKL hKL, LANGID HotKeyLangId) { LCID lcid; @@ -343,7 +351,10 @@ IntSetImeHotKey(DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DW case SETIMEHOTKEY_DELETE: pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); if (!pNode) + { + ERR("dwHotKeyId: 0x%lX\n", dwHotKeyId); return FALSE; + }
IntDeleteImeHotKey(&gpImeHotKeyList, pNode); return TRUE; @@ -550,29 +561,122 @@ DWORD FASTCALL UserBuildHimcList(PTHREADINFO pti, DWORD dwCount, HIMC *phList) }
UINT FASTCALL -IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +IntImmProcessKey(PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT uMsg, + WPARAM wParam, LPARAM lParam) { - PKL pKbdLayout; + UINT uVirtualKey, ret = 0; + DWORD dwHotKeyId; + PKL pKL; + PIMC pIMC = NULL; + PIMEHOTKEY pImeHotKey; + HKL hKL; + HWND hWnd;
ASSERT_REFS_CO(pWnd);
- if ( Msg == WM_KEYDOWN || - Msg == WM_SYSKEYDOWN || - Msg == WM_KEYUP || - Msg == WM_SYSKEYUP ) - { - //Vk = wParam & 0xff; - pKbdLayout = pWnd->head.pti->KeyboardLayout; - if (pKbdLayout == NULL) return 0; - // - if (!(gpsi->dwSRVIFlags & SRVINFO_IMM32)) return 0; - // need ime.h! - } - // Call User32: - // Anything but BOOL! - //ImmRet = co_IntImmProcessKey(UserHMGetHandle(pWnd), pKbdLayout->hkl, Vk, lParam, HotKey); - FIXME(" is UNIMPLEMENTED.\n"); - return 0; + switch (uMsg) + { + case WM_KEYDOWN: + case WM_KEYUP: + case WM_SYSKEYDOWN: + case WM_SYSKEYUP: + break; + + default: + return 0; + } + + hWnd = UserHMGetHandle(pWnd); + pKL = pWnd->head.pti->KeyboardLayout; + if (!pKL) + return 0; + + uVirtualKey = LOBYTE(wParam); + pImeHotKey = IntCheckImeHotKey(MessageQueue, uVirtualKey, lParam); + if (pImeHotKey) + { + dwHotKeyId = pImeHotKey->dwHotKeyId; + hKL = pImeHotKey->hKL; + } + else + { + dwHotKeyId = INVALID_HOTKEY; + hKL = NULL; + } + + if (IME_HOTKEY_DSWITCH_FIRST <= dwHotKeyId && dwHotKeyId <= IME_HOTKEY_DSWITCH_LAST) + { + if (pKL->hkl != hKL) + { + UserPostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, + ((pKL->dwFontSigs & gSystemFS) ? INPUTLANGCHANGE_SYSCHARSET : 0), + (LPARAM)hKL); + } + + if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000) + return 0; + + return IPHK_HOTKEY; + } + + if (!IS_IMM_MODE()) + return 0; + + if (dwHotKeyId == INVALID_HOTKEY) + { + if (!pKL->piiex) + return 0; + + if (pWnd->hImc) + pIMC = UserGetObject(gHandleTable, pWnd->hImc, TYPE_INPUTCONTEXT); + if (!pIMC) + return 0; + + if ((lParam & 0x80000000) && + (pKL->piiex->ImeInfo.fdwProperty & IME_PROP_IGNORE_UPKEYS)) + { + return 0; + } + + switch (uVirtualKey) + { + case VK_DBE_CODEINPUT: + case VK_DBE_ENTERCONFIGMODE: + case VK_DBE_ENTERWORDREGISTERMODE: + case VK_DBE_HIRAGANA: + case VK_DBE_KATAKANA: + case VK_DBE_NOCODEINPUT: + case VK_DBE_NOROMAN: + case VK_DBE_ROMAN: + break; + + default: + { + if (uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP) + { + if (uVirtualKey != VK_MENU && uVirtualKey != VK_F10) + return 0; + } + + if (!(pKL->piiex->ImeInfo.fdwProperty & IME_PROP_NEED_ALTKEY)) + { + if (uVirtualKey == VK_MENU || (lParam & 0x20000000)) + return 0; + } + break; + } + } + } + + if (LOBYTE(uVirtualKey) == VK_PACKET) + uVirtualKey = MAKELONG(wParam, GetW32ThreadInfo()->wchInjected); + + ret = co_IntImmProcessKey(hWnd, pKL->hkl, uVirtualKey, lParam, dwHotKeyId); + + if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000) + ret &= ~IPHK_HOTKEY; + + return ret; }
NTSTATUS @@ -587,6 +691,7 @@ NtUserBuildHimcList(DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD pdwCo
if (!IS_IMM_MODE()) { + ERR("!IS_IMM_MODE()\n"); EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); goto Quit; } @@ -695,8 +800,14 @@ NtUserNotifyIMEStatus(HWND hwnd, BOOL fOpen, DWORD dwConversion)
UserEnterExclusive();
+ if (!IS_IMM_MODE()) + { + ERR("!IS_IMM_MODE()\n"); + goto Quit; + } + pwnd = ValidateHwndNoErr(hwnd); - if (!pwnd || !IS_IMM_MODE()) + if (!pwnd) goto Quit;
pti = pwnd->head.pti; @@ -741,6 +852,7 @@ NtUserDisableThreadIme(
if (!IS_IMM_MODE()) { + ERR("!IS_IMM_MODE()\n"); EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); goto Quit; } @@ -812,6 +924,7 @@ NtUserGetAppImeLevel(HWND hWnd)
if (!IS_IMM_MODE()) { + ERR("!IS_IMM_MODE()\n"); EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); goto Quit; } @@ -886,7 +999,10 @@ NtUserGetImeInfoEx( UserEnterShared();
if (!IS_IMM_MODE()) + { + ERR("!IS_IMM_MODE()\n"); goto Quit; + }
_SEH2_TRY { @@ -928,16 +1044,17 @@ NtUserSetAppImeLevel(HWND hWnd, DWORD dwLevel)
UserEnterExclusive();
- pWnd = ValidateHwndNoErr(hWnd); - if (!pWnd) - goto Quit; - if (!IS_IMM_MODE()) { + ERR("!IS_IMM_MODE()\n"); EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); goto Quit; }
+ pWnd = ValidateHwndNoErr(hWnd); + if (!pWnd) + goto Quit; + pti = PsGetCurrentThreadWin32Thread(); if (pWnd->head.pti->ppi == pti->ppi) ret = UserSetProp(pWnd, AtomImeLevel, (HANDLE)(ULONG_PTR)dwLevel, TRUE); @@ -983,7 +1100,10 @@ NtUserSetImeInfoEx(PIMEINFOEX pImeInfoEx) UserEnterExclusive();
if (!IS_IMM_MODE()) + { + ERR("!IS_IMM_MODE()\n"); goto Quit; + }
_SEH2_TRY { @@ -1012,8 +1132,14 @@ NtUserSetImeOwnerWindow(HWND hImeWnd, HWND hwndFocus)
UserEnterExclusive();
+ if (!IS_IMM_MODE()) + { + ERR("!IS_IMM_MODE()\n"); + goto Quit; + } + pImeWnd = ValidateHwndNoErr(hImeWnd); - if (!IS_IMM_MODE() || !pImeWnd || pImeWnd->fnid != FNID_IME) + if (!pImeWnd || pImeWnd->fnid != FNID_IME) goto Quit;
pwndFocus = ValidateHwndNoErr(hwndFocus); @@ -1140,6 +1266,7 @@ BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC)
if (!IS_IMM_MODE()) { + ERR("!IS_IMM_MODE()\n"); EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); goto Quit; } @@ -1185,7 +1312,10 @@ PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData) PDESKTOP pdesk = pti->rpdesk;
if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled? + { + ERR("IME is disabled\n"); return NULL; + }
if (!pdesk) // No desktop? return NULL; @@ -1232,7 +1362,10 @@ NtUserCreateInputContext(ULONG_PTR dwClientImcData) UserEnterExclusive();
if (!IS_IMM_MODE()) + { + ERR("!IS_IMM_MODE()\n"); goto Quit; + }
pIMC = UserCreateInputContext(dwClientImcData); if (pIMC) @@ -1317,8 +1450,14 @@ NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags)
UserEnterExclusive();
+ if (!IS_IMM_MODE()) + { + ERR("!IS_IMM_MODE()\n"); + goto Quit; + } + pWnd = ValidateHwndNoErr(hWnd); - if (!pWnd || !IS_IMM_MODE()) + if (!pWnd) goto Quit;
pIMC = (hIMC ? UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT) : NULL); @@ -1373,7 +1512,10 @@ NtUserUpdateInputContext( UserEnterExclusive();
if (!IS_IMM_MODE()) + { + ERR("!IS_IMM_MODE()\n"); goto Quit; + }
pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT); if (!pIMC) @@ -1397,7 +1539,10 @@ NtUserQueryInputContext(HIMC hIMC, DWORD dwType) UserEnterExclusive();
if (!IS_IMM_MODE()) + { + ERR("!IS_IMM_MODE()\n"); goto Quit; + }
pIMC = UserGetObject(gHandleTable, hIMC, TYPE_INPUTCONTEXT); if (!pIMC) diff --git a/win32ss/user/user32/misc/dllmain.c b/win32ss/user/user32/misc/dllmain.c index 72f82aa1b43..ab5e6fcf825 100644 --- a/win32ss/user/user32/misc/dllmain.c +++ b/win32ss/user/user32/misc/dllmain.c @@ -223,10 +223,10 @@ PVOID apfnDispatch[USER32_CALLBACK_MAXIMUM + 1] = User32CallOBMFromKernel, User32CallLPKFromKernel, User32CallUMPDFromKernel, + User32CallImmProcessKeyFromKernel, };
- VOID WINAPI GdiProcessSetup(VOID); @@ -712,3 +712,16 @@ NTSTATUS WINAPI User32CallUMPDFromKernel(PVOID Arguments, ULONG ArgumentLength) } return ZwCallbackReturn( pktOut, cbSize, Status ); } + +NTSTATUS WINAPI +User32CallImmProcessKeyFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + PIMMPROCESSKEY_CALLBACK_ARGUMENTS Common = Arguments; + DWORD Result = IMM_FN(ImmProcessKey)(Common->hWnd, + Common->hKL, + Common->vKey, + Common->lParam, + Common->dwHotKeyID); + + return ZwCallbackReturn(&Result, sizeof(DWORD), STATUS_SUCCESS); +}