[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
This commit is contained in:
Katayama Hirofumi MZ 2023-11-25 22:46:00 +09:00 committed by GitHub
parent 6783061894
commit 3b2fdc56bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 201 additions and 109 deletions

View file

@ -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.@)
*

View file

@ -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))

View file

@ -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()

View file

@ -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);

View file

@ -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

View file

@ -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(

View file

@ -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);