https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3b2fdc56bdd8c13b433de…
commit 3b2fdc56bdd8c13b433de96b2ca212fe82524c54
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Nov 25 22:46:00 2023 +0900
Commit: GitHub <noreply(a)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);