https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7342ed1861d4cae5fc216…
commit 7342ed1861d4cae5fc21656e0c249a81f423f49c
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Aug 8 17:35:34 2021 +0900
Commit: GitHub <noreply(a)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_ */