https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7342ed1861d4cae5fc21656e0c249a81f423f49c

commit 7342ed1861d4cae5fc21656e0c249a81f423f49c
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sun Aug 8 17:35:34 2021 +0900
Commit:     GitHub <[email protected]>
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_ */

Reply via email to