https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3b2fdc56bdd8c13b433de9...
commit 3b2fdc56bdd8c13b433de96b2ca212fe82524c54 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sat Nov 25 22:46:00 2023 +0900 Commit: GitHub noreply@github.com CommitDate: Sat Nov 25 22:46:00 2023 +0900
[IMM32][SDK][NTUSER][IMM32_WINETEST] Add CtfImmGenerateMessage (#6037)
Implementing advanced text service...
- Add CtfImmGenerateMessage function. - Modify imm32.spec. - Move TRANSMSG, TRANSMSGLIST etc. in win32ss/include/ntuser.h to <immdev.h>. - Move win32ss/include/imetable.h to sdk/include/reactos/imetable.h. - Move dll/win32/imm32/CtfImeTable.h to sdk/include/reactos/CtfImeTable.h. - Fix build failure of imm32_winetest due to TRANSMSG redefinition.
CORE-19268 --- dll/win32/imm32/ctf.c | 98 +++++++++++++++++++- dll/win32/imm32/ime.c | 6 +- dll/win32/imm32/imm32.spec | 1 + modules/rostests/winetests/imm32/imm32.c | 2 + sdk/include/ddk/immdev.h | 101 +++++++++++++++++++++ .../imm32 => sdk/include/reactos}/CtfImeTable.h | 0 .../include => sdk/include/reactos}/imetable.h | 0 sdk/include/reactos/imm32_undoc.h | 1 + win32ss/include/ntuser.h | 101 --------------------- 9 files changed, 201 insertions(+), 109 deletions(-)
diff --git a/dll/win32/imm32/ctf.c b/dll/win32/imm32/ctf.c index 78f9b09acb9..1fc124f24b5 100644 --- a/dll/win32/imm32/ctf.c +++ b/dll/win32/imm32/ctf.c @@ -134,7 +134,7 @@ VOID Imm32TF_InvalidAssemblyListCacheIfExist(VOID) * new-style and high-level input method. * * The CTF IME file is a DLL file that the software developer distributes. - * The export functions of the CTF IME file are defined in "CtfImeTable.h" of + * The export functions of the CTF IME file are defined in <CtfImeTable.h> of * this folder. */
@@ -148,13 +148,13 @@ HINSTANCE g_hCtfIme = NULL; #undef DEFINE_CTF_IME_FN #define DEFINE_CTF_IME_FN(func_name, ret_type, params) \ typedef ret_type (WINAPI *FN_##func_name)params; -#include "CtfImeTable.h" +#include <CtfImeTable.h>
/* Define the global variables (g_pfn...) for CTF IME functions */ #undef DEFINE_CTF_IME_FN #define DEFINE_CTF_IME_FN(func_name, ret_type, params) \ FN_##func_name g_pfn##func_name = NULL; -#include "CtfImeTable.h" +#include <CtfImeTable.h>
/* The macro that gets the variable name from the CTF IME function name */ #define CTF_IME_FN(func_name) g_pfn##func_name @@ -256,7 +256,7 @@ Imm32LoadCtfIme(VOID) bSuccess = FALSE; /* Failed */ \ break; \ } -#include "CtfImeTable.h" +#include <CtfImeTable.h> } while (0);
/* Unload the CTF IME if failed */ @@ -265,7 +265,7 @@ Imm32LoadCtfIme(VOID) /* Set NULL to the function pointers */ #undef DEFINE_CTF_IME_FN #define DEFINE_CTF_IME_FN(func_name, ret_type, params) CTF_IME_FN(func_name) = NULL; -#include "CtfImeTable.h" +#include <CtfImeTable.h>
if (g_hCtfIme) { @@ -493,6 +493,94 @@ CtfImmTIMActivate(_In_ HKL hKL) return E_NOTIMPL; }
+/*********************************************************************** + * CtfImmGenerateMessage(IMM32.@) + */ +BOOL WINAPI +CtfImmGenerateMessage( + _In_ HIMC hIMC, + _In_ BOOL bSend) +{ + DWORD_PTR dwImeThreadId, dwCurrentThreadId; + PCLIENTIMC pClientImc; + BOOL bUnicode; + LPINPUTCONTEXT pIC; + DWORD iMsg, dwNumMsgBuf; + LPTRANSMSG pOldTransMsg, pNewTransMsg; + SIZE_T cbTransMsg; + + TRACE("(%p, %d)\n", hIMC, bSend); + + dwImeThreadId = NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID); + dwCurrentThreadId = GetCurrentThreadId(); + if (dwImeThreadId != dwCurrentThreadId) + { + ERR("%p vs %p\n", dwImeThreadId, dwCurrentThreadId); + return FALSE; + } + + pClientImc = ImmLockClientImc(hIMC); + if (IS_NULL_UNEXPECTEDLY(pClientImc)) + return FALSE; + + bUnicode = !!(pClientImc->dwFlags & CLIENTIMC_WIDE); + ImmUnlockClientImc(pClientImc); + + pIC = (LPINPUTCONTEXT)ImmLockIMC(hIMC); + if (IS_NULL_UNEXPECTEDLY(pIC)) + return FALSE; + + dwNumMsgBuf = pIC->dwNumMsgBuf; + pOldTransMsg = (LPTRANSMSG)ImmLockIMCC(pIC->hMsgBuf); + if (IS_NULL_UNEXPECTEDLY(pOldTransMsg)) + { + pIC->dwNumMsgBuf = 0; + ImmUnlockIMC(hIMC); + return TRUE; + } + + cbTransMsg = sizeof(TRANSMSG) * dwNumMsgBuf; + pNewTransMsg = (PTRANSMSG)ImmLocalAlloc(0, cbTransMsg); + if (IS_NULL_UNEXPECTEDLY(pNewTransMsg)) + { + ImmUnlockIMCC(pIC->hMsgBuf); + pIC->dwNumMsgBuf = 0; + ImmUnlockIMC(hIMC); + return TRUE; + } + + RtlCopyMemory(pNewTransMsg, pOldTransMsg, cbTransMsg); + + for (iMsg = 0; iMsg < dwNumMsgBuf; ++iMsg) + { + HWND hWnd = pIC->hWnd; + UINT uMsg = pNewTransMsg[iMsg].message; + WPARAM wParam = pNewTransMsg[iMsg].wParam; + LPARAM lParam = pNewTransMsg[iMsg].lParam; + if (bSend) + { + if (bUnicode) + SendMessageW(hWnd, uMsg, wParam, lParam); + else + SendMessageA(hWnd, uMsg, wParam, lParam); + } + else + { + if (bUnicode) + PostMessageW(hWnd, uMsg, wParam, lParam); + else + PostMessageA(hWnd, uMsg, wParam, lParam); + } + } + + ImmLocalFree(pNewTransMsg); + ImmUnlockIMCC(pIC->hMsgBuf); + pIC->dwNumMsgBuf = 0; /* Processed */ + ImmUnlockIMC(hIMC); + + return TRUE; +} + /*********************************************************************** * CtfImmHideToolbarWnd(IMM32.@) * diff --git a/dll/win32/imm32/ime.c b/dll/win32/imm32/ime.c index d898c924570..9268b66a0a7 100644 --- a/dll/win32/imm32/ime.c +++ b/dll/win32/imm32/ime.c @@ -191,7 +191,7 @@ BOOL APIENTRY Imm32InquireIme(PIMEDPI pImeDpi) FIXME("%s: Why stub called?\n", #name); \ return (type)0; \ } -#include "imetable.h" +#include <imetable.h> #undef DEFINE_IME_ENTRY
// Win: LoadIME @@ -214,7 +214,7 @@ BOOL APIENTRY Imm32LoadIME(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi)
/* Populate the table by stub IME functions */ #define DEFINE_IME_ENTRY(type, name, params, optional) pImeDpi->name = Stub##name; -#include "imetable.h" +#include <imetable.h> #undef DEFINE_IME_ENTRY
/* Populate the table by real IME functions */ @@ -227,7 +227,7 @@ BOOL APIENTRY Imm32LoadIME(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi) goto Failed; \ } \ } while (0); -#include "imetable.h" +#include <imetable.h> #undef DEFINE_IME_ENTRY
if (Imm32InquireIme(pImeDpi)) diff --git a/dll/win32/imm32/imm32.spec b/dll/win32/imm32/imm32.spec index 8173e1e975c..bf0d216f723 100644 --- a/dll/win32/imm32/imm32.spec +++ b/dll/win32/imm32/imm32.spec @@ -2,6 +2,7 @@ @ stdcall CtfAImmDeactivate(long) @ stdcall CtfAImmIsIME(ptr) @ stdcall CtfImmDispatchDefImeMessage(ptr long ptr ptr) +@ stdcall CtfImmGenerateMessage(ptr long) @ stdcall CtfImmGetGuidAtom(ptr long ptr) @ stdcall CtfImmHideToolbarWnd() @ stdcall CtfImmIsCiceroEnabled() diff --git a/modules/rostests/winetests/imm32/imm32.c b/modules/rostests/winetests/imm32/imm32.c index 39222884f2b..e7d9c67c332 100644 --- a/modules/rostests/winetests/imm32/imm32.c +++ b/modules/rostests/winetests/imm32/imm32.c @@ -61,11 +61,13 @@ typedef struct } u; } TEST_INPUT;
+#ifndef __REACTOS__ typedef struct _tagTRANSMSG { UINT message; WPARAM wParam; LPARAM lParam; } TRANSMSG, *LPTRANSMSG; +#endif
static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t);
diff --git a/sdk/include/ddk/immdev.h b/sdk/include/ddk/immdev.h index 8a8586b774d..b553838888f 100644 --- a/sdk/include/ddk/immdev.h +++ b/sdk/include/ddk/immdev.h @@ -238,6 +238,107 @@ typedef struct IME_STATE C_ASSERT(sizeof(IME_STATE) == 0x18); #endif
+typedef struct _tagTRANSMSG +{ + UINT message; + WPARAM wParam; + LPARAM lParam; +} TRANSMSG, *PTRANSMSG, *LPTRANSMSG; + +typedef struct _tagTRANSMSGLIST +{ + UINT uMsgCount; + TRANSMSG TransMsg[ANYSIZE_ARRAY]; +} TRANSMSGLIST, *PTRANSMSGLIST, *LPTRANSMSGLIST; + +#define DEFINE_IME_ENTRY(type, name, params, extended) typedef type (WINAPI *FN_##name) params; +#include <imetable.h> +#undef DEFINE_IME_ENTRY + +typedef struct IMEDPI +{ + struct IMEDPI *pNext; + HINSTANCE hInst; + HKL hKL; + IMEINFO ImeInfo; + UINT uCodePage; + WCHAR szUIClass[16]; + DWORD cLockObj; + DWORD dwFlags; +#define DEFINE_IME_ENTRY(type, name, params, extended) FN_##name name; +#include <imetable.h> +#undef DEFINE_IME_ENTRY +} IMEDPI, *PIMEDPI; + +#ifndef _WIN64 +C_ASSERT(offsetof(IMEDPI, pNext) == 0x0); +C_ASSERT(offsetof(IMEDPI, hInst) == 0x4); +C_ASSERT(offsetof(IMEDPI, hKL) == 0x8); +C_ASSERT(offsetof(IMEDPI, ImeInfo) == 0xc); +C_ASSERT(offsetof(IMEDPI, uCodePage) == 0x28); +C_ASSERT(offsetof(IMEDPI, szUIClass) == 0x2c); +C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c); +C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50); +C_ASSERT(offsetof(IMEDPI, ImeInquire) == 0x54); +C_ASSERT(offsetof(IMEDPI, ImeConversionList) == 0x58); +C_ASSERT(offsetof(IMEDPI, ImeRegisterWord) == 0x5c); +C_ASSERT(offsetof(IMEDPI, ImeUnregisterWord) == 0x60); +C_ASSERT(offsetof(IMEDPI, ImeGetRegisterWordStyle) == 0x64); +C_ASSERT(offsetof(IMEDPI, ImeEnumRegisterWord) == 0x68); +C_ASSERT(offsetof(IMEDPI, ImeConfigure) == 0x6c); +C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70); +C_ASSERT(offsetof(IMEDPI, ImeEscape) == 0x74); +C_ASSERT(offsetof(IMEDPI, ImeProcessKey) == 0x78); +C_ASSERT(offsetof(IMEDPI, ImeSelect) == 0x7c); +C_ASSERT(offsetof(IMEDPI, ImeSetActiveContext) == 0x80); +C_ASSERT(offsetof(IMEDPI, ImeToAsciiEx) == 0x84); +C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88); +C_ASSERT(offsetof(IMEDPI, ImeSetCompositionString) == 0x8c); +C_ASSERT(offsetof(IMEDPI, ImeGetImeMenuItems) == 0x90); +C_ASSERT(offsetof(IMEDPI, CtfImeInquireExW) == 0x94); +C_ASSERT(offsetof(IMEDPI, CtfImeSelectEx) == 0x98); +C_ASSERT(offsetof(IMEDPI, CtfImeEscapeEx) == 0x9c); +C_ASSERT(offsetof(IMEDPI, CtfImeGetGuidAtom) == 0xa0); +C_ASSERT(offsetof(IMEDPI, CtfImeIsGuidMapEnable) == 0xa4); +C_ASSERT(sizeof(IMEDPI) == 0xa8); +#endif + +/* flags for IMEDPI.dwFlags */ +#define IMEDPI_FLAG_UNLOADED 0x1 +#define IMEDPI_FLAG_LOCKED 0x2 + +/* unconfirmed */ +typedef struct tagCLIENTIMC +{ + HANDLE hInputContext; /* LocalAlloc'ed LHND */ + LONG cLockObj; + DWORD dwFlags; + DWORD dwCompatFlags; + RTL_CRITICAL_SECTION cs; + UINT uCodePage; + HKL hKL; + BOOL bUnknown4; +} CLIENTIMC, *PCLIENTIMC; + +#ifndef _WIN64 +C_ASSERT(offsetof(CLIENTIMC, hInputContext) == 0x0); +C_ASSERT(offsetof(CLIENTIMC, cLockObj) == 0x4); +C_ASSERT(offsetof(CLIENTIMC, dwFlags) == 0x8); +C_ASSERT(offsetof(CLIENTIMC, dwCompatFlags) == 0xc); +C_ASSERT(offsetof(CLIENTIMC, cs) == 0x10); +C_ASSERT(offsetof(CLIENTIMC, uCodePage) == 0x28); +C_ASSERT(offsetof(CLIENTIMC, hKL) == 0x2c); +C_ASSERT(sizeof(CLIENTIMC) == 0x34); +#endif + +/* flags for CLIENTIMC */ +#define CLIENTIMC_WIDE 0x1 +#define CLIENTIMC_ACTIVE 0x2 +#define CLIENTIMC_UNKNOWN4 0x20 +#define CLIENTIMC_DESTROY 0x40 +#define CLIENTIMC_DISABLEIME 0x80 +#define CLIENTIMC_UNKNOWN2 0x100 + #ifdef __cplusplus } // extern "C" #endif diff --git a/dll/win32/imm32/CtfImeTable.h b/sdk/include/reactos/CtfImeTable.h similarity index 100% rename from dll/win32/imm32/CtfImeTable.h rename to sdk/include/reactos/CtfImeTable.h diff --git a/win32ss/include/imetable.h b/sdk/include/reactos/imetable.h similarity index 100% rename from win32ss/include/imetable.h rename to sdk/include/reactos/imetable.h diff --git a/sdk/include/reactos/imm32_undoc.h b/sdk/include/reactos/imm32_undoc.h index 61904db0b13..84d962e77c4 100644 --- a/sdk/include/reactos/imm32_undoc.h +++ b/sdk/include/reactos/imm32_undoc.h @@ -29,6 +29,7 @@ BOOL WINAPI CtfImmIsCiceroStartedInThread(VOID); VOID WINAPI CtfImmSetAppCompatFlags(_In_ DWORD dwFlags); DWORD WINAPI CtfImmHideToolbarWnd(VOID); VOID WINAPI CtfImmRestoreToolbarWnd(_In_ LPVOID pUnused, _In_ DWORD dwShowFlags); +BOOL WINAPI CtfImmGenerateMessage(_In_ HIMC hIMC, _In_ BOOL bSend);
LRESULT WINAPI CtfImmDispatchDefImeMessage( diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h index 1cb0fb2db4c..f501babb00a 100644 --- a/win32ss/include/ntuser.h +++ b/win32ss/include/ntuser.h @@ -1261,107 +1261,6 @@ typedef struct _IMEWND PIMEUI pimeui; } IMEWND, *PIMEWND;
-typedef struct tagTRANSMSG -{ - UINT message; - WPARAM wParam; - LPARAM lParam; -} TRANSMSG, *PTRANSMSG, *LPTRANSMSG; - -typedef struct tagTRANSMSGLIST -{ - UINT uMsgCount; - TRANSMSG TransMsg[ANYSIZE_ARRAY]; -} TRANSMSGLIST, *PTRANSMSGLIST, *LPTRANSMSGLIST; - -#define DEFINE_IME_ENTRY(type, name, params, extended) typedef type (WINAPI *FN_##name) params; -#include "imetable.h" -#undef DEFINE_IME_ENTRY - -typedef struct IMEDPI -{ - struct IMEDPI *pNext; - HINSTANCE hInst; - HKL hKL; - IMEINFO ImeInfo; - UINT uCodePage; - WCHAR szUIClass[16]; - DWORD cLockObj; - DWORD dwFlags; -#define DEFINE_IME_ENTRY(type, name, params, extended) FN_##name name; -#include "imetable.h" -#undef DEFINE_IME_ENTRY -} IMEDPI, *PIMEDPI; - -#ifndef _WIN64 -C_ASSERT(offsetof(IMEDPI, pNext) == 0x0); -C_ASSERT(offsetof(IMEDPI, hInst) == 0x4); -C_ASSERT(offsetof(IMEDPI, hKL) == 0x8); -C_ASSERT(offsetof(IMEDPI, ImeInfo) == 0xc); -C_ASSERT(offsetof(IMEDPI, uCodePage) == 0x28); -C_ASSERT(offsetof(IMEDPI, szUIClass) == 0x2c); -C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c); -C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50); -C_ASSERT(offsetof(IMEDPI, ImeInquire) == 0x54); -C_ASSERT(offsetof(IMEDPI, ImeConversionList) == 0x58); -C_ASSERT(offsetof(IMEDPI, ImeRegisterWord) == 0x5c); -C_ASSERT(offsetof(IMEDPI, ImeUnregisterWord) == 0x60); -C_ASSERT(offsetof(IMEDPI, ImeGetRegisterWordStyle) == 0x64); -C_ASSERT(offsetof(IMEDPI, ImeEnumRegisterWord) == 0x68); -C_ASSERT(offsetof(IMEDPI, ImeConfigure) == 0x6c); -C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70); -C_ASSERT(offsetof(IMEDPI, ImeEscape) == 0x74); -C_ASSERT(offsetof(IMEDPI, ImeProcessKey) == 0x78); -C_ASSERT(offsetof(IMEDPI, ImeSelect) == 0x7c); -C_ASSERT(offsetof(IMEDPI, ImeSetActiveContext) == 0x80); -C_ASSERT(offsetof(IMEDPI, ImeToAsciiEx) == 0x84); -C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88); -C_ASSERT(offsetof(IMEDPI, ImeSetCompositionString) == 0x8c); -C_ASSERT(offsetof(IMEDPI, ImeGetImeMenuItems) == 0x90); -C_ASSERT(offsetof(IMEDPI, CtfImeInquireExW) == 0x94); -C_ASSERT(offsetof(IMEDPI, CtfImeSelectEx) == 0x98); -C_ASSERT(offsetof(IMEDPI, CtfImeEscapeEx) == 0x9c); -C_ASSERT(offsetof(IMEDPI, CtfImeGetGuidAtom) == 0xa0); -C_ASSERT(offsetof(IMEDPI, CtfImeIsGuidMapEnable) == 0xa4); -C_ASSERT(sizeof(IMEDPI) == 0xa8); -#endif - -/* flags for IMEDPI.dwFlags */ -#define IMEDPI_FLAG_UNLOADED 0x1 -#define IMEDPI_FLAG_LOCKED 0x2 - -/* unconfirmed */ -typedef struct tagCLIENTIMC -{ - HANDLE hInputContext; /* LocalAlloc'ed LHND */ - LONG cLockObj; - DWORD dwFlags; - DWORD dwCompatFlags; - RTL_CRITICAL_SECTION cs; - UINT uCodePage; - HKL hKL; - BOOL bUnknown4; -} CLIENTIMC, *PCLIENTIMC; - -#ifndef _WIN64 -C_ASSERT(offsetof(CLIENTIMC, hInputContext) == 0x0); -C_ASSERT(offsetof(CLIENTIMC, cLockObj) == 0x4); -C_ASSERT(offsetof(CLIENTIMC, dwFlags) == 0x8); -C_ASSERT(offsetof(CLIENTIMC, dwCompatFlags) == 0xc); -C_ASSERT(offsetof(CLIENTIMC, cs) == 0x10); -C_ASSERT(offsetof(CLIENTIMC, uCodePage) == 0x28); -C_ASSERT(offsetof(CLIENTIMC, hKL) == 0x2c); -C_ASSERT(sizeof(CLIENTIMC) == 0x34); -#endif - -/* flags for CLIENTIMC */ -#define CLIENTIMC_WIDE 0x1 -#define CLIENTIMC_ACTIVE 0x2 -#define CLIENTIMC_UNKNOWN4 0x20 -#define CLIENTIMC_DESTROY 0x40 -#define CLIENTIMC_DISABLEIME 0x80 -#define CLIENTIMC_UNKNOWN2 0x100 - DWORD NTAPI NtUserAssociateInputContext(HWND hWnd, HIMC hIMC, DWORD dwFlags);