[IMM32] Rewrite ImmSetCompositionFontA/W (#3886)

- Rewrite ImmSetCompositionFontA and ImmSetCompositionFontW functions.
- Add INPUTCONTEXTDX structure as an extension of INPUTCONTEXT.
CORE-11700
This commit is contained in:
Katayama Hirofumi MZ 2021-08-08 17:35:34 +09:00 committed by GitHub
parent 3927ad9d47
commit 7342ed1861
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 151 additions and 18 deletions

View file

@ -3482,29 +3482,88 @@ BOOL WINAPI ImmSetCandidateWindow(
#undef MAX_CANDIDATEFORM
}
static VOID APIENTRY WideToAnsiLogFont(const LOGFONTW *plfW, LPLOGFONTA plfA)
{
BOOL bUsedDef;
size_t cchW, cchA = _countof(plfA->lfFaceName);
RtlCopyMemory(plfA, plfW, offsetof(LOGFONTA, lfFaceName));
StringCchLengthW(plfW->lfFaceName, _countof(plfW->lfFaceName), &cchW);
cchA = WideCharToMultiByte(CP_ACP, 0, plfW->lfFaceName, (INT)cchW,
plfA->lfFaceName, (INT)cchA, NULL, &bUsedDef);
if (cchA > _countof(plfA->lfFaceName) - 1)
cchA = _countof(plfA->lfFaceName) - 1;
plfA->lfFaceName[cchA] = 0;
}
static VOID APIENTRY AnsiToWideLogFont(const LOGFONTA *plfA, LPLOGFONTW plfW)
{
size_t cchA, cchW = _countof(plfW->lfFaceName);
RtlCopyMemory(plfW, plfA, offsetof(LOGFONTW, lfFaceName));
StringCchLengthA(plfA->lfFaceName, _countof(plfA->lfFaceName), &cchA);
cchW = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, plfA->lfFaceName, (INT)cchA,
plfW->lfFaceName, cchW);
if (cchW > _countof(plfW->lfFaceName) - 1)
cchW = _countof(plfW->lfFaceName) - 1;
plfW->lfFaceName[cchW] = 0;
}
/***********************************************************************
* ImmSetCompositionFontA (IMM32.@)
*/
BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
{
InputContextData *data = get_imc_data(hIMC);
LOGFONTW lfW;
DWORD dwImeThreadId, dwThreadId;
PCLIENTIMC pClientImc;
BOOL bWide;
LPINPUTCONTEXTDX pIC;
LCID lcid;
HWND hWnd;
PTEB pTeb;
TRACE("(%p, %p)\n", hIMC, lplf);
if (!data || !lplf)
{
SetLastError(ERROR_INVALID_HANDLE);
dwImeThreadId = Imm32QueryInputContext(hIMC, 1);
dwThreadId = GetCurrentThreadId();
if (dwImeThreadId != dwThreadId)
return FALSE;
pClientImc = ImmLockClientImc(hIMC);
if (pClientImc == NULL)
return FALSE;
bWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
ImmUnlockClientImc(pClientImc);
if (bWide)
{
AnsiToWideLogFont(lplf, &lfW);
return ImmSetCompositionFontW(hIMC, &lfW);
}
if (IMM_IsCrossThreadAccess(NULL, hIMC))
pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
if (pIC == NULL)
return FALSE;
memcpy(&data->IMC.lfFont.W,lplf,sizeof(LOGFONTA));
MultiByteToWideChar(CP_ACP, 0, lplf->lfFaceName, -1, data->IMC.lfFont.W.lfFaceName,
LF_FACESIZE);
ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
pTeb = NtCurrentTeb();
if (pTeb->Win32ClientInfo[2] < 0x400)
{
lcid = GetSystemDefaultLCID();
if (PRIMARYLANGID(lcid) == LANG_JAPANESE && !(pIC->dwUIFlags & 2) &&
pIC->cfCompForm.dwStyle != CFS_DEFAULT)
{
PostMessageA(pIC->hWnd, WM_IME_REPORT, IR_CHANGECONVERT, 0);
}
}
pIC->lfFont.A = *lplf;
pIC->fdwInit |= INIT_LOGFONT;
hWnd = pIC->hWnd;
ImmUnlockIMC(hIMC);
Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT,
IMN_SETCOMPOSITIONFONT, 0);
return TRUE;
}
@ -3513,22 +3572,59 @@ BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf)
*/
BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
{
InputContextData *data = get_imc_data(hIMC);
LOGFONTA lfA;
DWORD dwImeThreadId, dwThreadId;
PCLIENTIMC pClientImc;
BOOL bWide;
HWND hWnd;
LPINPUTCONTEXTDX pIC;
PTEB pTeb;
LCID lcid;
TRACE("(%p, %p)\n", hIMC, lplf);
if (!data || !lplf)
{
SetLastError(ERROR_INVALID_HANDLE);
dwImeThreadId = Imm32QueryInputContext(hIMC, 1);
dwThreadId = GetCurrentThreadId();
if (dwImeThreadId != dwThreadId)
return FALSE;
pClientImc = ImmLockClientImc(hIMC);
if (pClientImc == NULL)
return FALSE;
bWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
ImmUnlockClientImc(pClientImc);
if (!bWide)
{
WideToAnsiLogFont(lplf, &lfA);
return ImmSetCompositionFontA(hIMC, &lfA);
}
if (IMM_IsCrossThreadAccess(NULL, hIMC))
pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
if (pIC == NULL)
return FALSE;
data->IMC.lfFont.W = *lplf;
ImmNotifyIME(hIMC, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT);
ImmInternalSendIMENotify(data, IMN_SETCOMPOSITIONFONT, 0);
pTeb = NtCurrentTeb();
if (pTeb->Win32ClientInfo[2] < 0x400)
{
lcid = GetSystemDefaultLCID();
if (PRIMARYLANGID(lcid) == LANG_JAPANESE &&
!(pIC->dwUIFlags & 2) &&
pIC->cfCompForm.dwStyle != CFS_DEFAULT)
{
PostMessageW(pIC->hWnd, WM_IME_REPORT, IR_CHANGECONVERT, 0);
}
}
pIC->lfFont.W = *lplf;
pIC->fdwInit |= INIT_LOGFONT;
hWnd = pIC->hWnd;
ImmUnlockIMC(hIMC);
Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT,
IMN_SETCOMPOSITIONFONT, 0);
return TRUE;
}

View file

@ -87,6 +87,24 @@ C_ASSERT(offsetof(INPUTCONTEXT, dwReserve) == 0x134);
C_ASSERT(sizeof(INPUTCONTEXT) == 0x140);
#endif
typedef struct INPUTCONTEXTDX /* unconfirmed */
{
INPUTCONTEXT;
UINT nVKey;
BOOL bHasVKey;
DWORD dwUnknown148;
DWORD dwUIFlags;
DWORD dwUnknown150;
void *pUnknown154;
/* ... */
} INPUTCONTEXTDX, *LPINPUTCONTEXTDX;
#ifndef _WIN64
C_ASSERT(offsetof(INPUTCONTEXTDX, nVKey) == 0x140);
C_ASSERT(offsetof(INPUTCONTEXTDX, bHasVKey) == 0x144);
C_ASSERT(offsetof(INPUTCONTEXTDX, dwUIFlags) == 0x14c);
#endif
// bits of fdwInit of INPUTCONTEXT
#define INIT_STATUSWNDPOS 0x00000001
#define INIT_CONVERSION 0x00000002
@ -95,6 +113,25 @@ C_ASSERT(sizeof(INPUTCONTEXT) == 0x140);
#define INIT_COMPFORM 0x00000010
#define INIT_SOFTKBDPOS 0x00000020
#ifndef WM_IME_REPORT
#define WM_IME_REPORT 0x280
#endif
// WM_IME_REPORT wParam
#define IR_STRINGSTART 0x100
#define IR_STRINGEND 0x101
#define IR_OPENCONVERT 0x120
#define IR_CHANGECONVERT 0x121
#define IR_CLOSECONVERT 0x122
#define IR_FULLCONVERT 0x123
#define IR_IMESELECT 0x130
#define IR_STRING 0x140
#define IR_DBCSCHAR 0x160
#define IR_UNDETERMINE 0x170
#define IR_STRINGEX 0x180
#define IR_MODEINFO 0x190
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC);
#endif /* _WINE_IMM_H_ */