https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3b2fdc56bdd8c13b433de96b2ca212fe82524c54

commit 3b2fdc56bdd8c13b433de96b2ca212fe82524c54
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sat Nov 25 22:46:00 2023 +0900
Commit:     GitHub <[email protected]>
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);

Reply via email to