https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7342ed1861d4cae5fc2165...
commit 7342ed1861d4cae5fc21656e0c249a81f423f49c Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Sun Aug 8 17:35:34 2021 +0900 Commit: GitHub noreply@github.com CommitDate: Sun Aug 8 17:35:34 2021 +0900
[IMM32] Rewrite ImmSetCompositionFontA/W (#3886)
- Rewrite ImmSetCompositionFontA and ImmSetCompositionFontW functions. - Add INPUTCONTEXTDX structure as an extension of INPUTCONTEXT. CORE-11700 --- dll/win32/imm32/imm.c | 132 ++++++++++++++++++++++++++++++++----- sdk/include/reactos/wine/ddk/imm.h | 37 +++++++++++ 2 files changed, 151 insertions(+), 18 deletions(-)
diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c index f33211203e4..3f2ed30b2f7 100644 --- a/dll/win32/imm32/imm.c +++ b/dll/win32/imm32/imm.c @@ -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; }
diff --git a/sdk/include/reactos/wine/ddk/imm.h b/sdk/include/reactos/wine/ddk/imm.h index 106d9603119..7242bd3c46a 100644 --- a/sdk/include/reactos/wine/ddk/imm.h +++ b/sdk/include/reactos/wine/ddk/imm.h @@ -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_ */