https://git.reactos.org/?p=reactos.git;a=commitdiff;h=33affbfecbc8a3a4c5c20a8776e46f34da898f40

commit 33affbfecbc8a3a4c5c20a8776e46f34da898f40
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Fri Oct 1 03:04:00 2021 +0900
Commit:     GitHub <[email protected]>
CommitDate: Fri Oct 1 03:04:00 2021 +0900

    [IMM32] Rewrite ImmGetImeMenuItemsA/W (#3983)
    
    - Rewrite ImmGetImeMenuItemsA and ImmGetImeMenuItemsW functions.
    - Add Imm32GetImeMenuItemsAW, Imm32IsImcAnsi, Imm32ImeMenuAnsiToWide and 
Imm32ImeMenuWideToAnsi helper functions.
    - Make IME module's ImeGetImeMenuItems function optional.
    CORE-11700
---
 dll/win32/imm32/ime.c      | 177 ++++++++++++++++++++++++++++++++++++++++++++-
 dll/win32/imm32/imm.c      | 142 ------------------------------------
 dll/win32/imm32/precomp.h  |   9 +++
 dll/win32/imm32/utils.c    |  60 +++++++++++++++
 win32ss/include/imetable.h |   4 +-
 5 files changed, 246 insertions(+), 146 deletions(-)

diff --git a/dll/win32/imm32/ime.c b/dll/win32/imm32/ime.c
index b1b31ce9eeb..7ae3325f323 100644
--- a/dll/win32/imm32/ime.c
+++ b/dll/win32/imm32/ime.c
@@ -168,11 +168,11 @@ BOOL APIENTRY Imm32LoadImeInfo(PIMEINFOEX pImeInfoEx, 
PIMEDPI pImeDpi)
     }
     pImeDpi->hInst = hIME;
 
-#define DEFINE_IME_ENTRY(type, name, params, extended) \
+#define DEFINE_IME_ENTRY(type, name, params, optional) \
     do { \
         fn = GetProcAddress(hIME, #name); \
         if (fn) pImeDpi->name = (FN_##name)fn; \
-        else if (!(extended)) goto Failed; \
+        else if (!(optional)) goto Failed; \
     } while (0);
 #include "imetable.h"
 #undef DEFINE_IME_ENTRY
@@ -330,6 +330,151 @@ Quit:
     return ret;
 }
 
+DWORD APIENTRY
+Imm32GetImeMenuItemWCrossProcess(HIMC hIMC, DWORD dwFlags, DWORD dwType, 
LPVOID lpImeParentMenu,
+                                 LPVOID lpImeMenu, DWORD dwSize)
+{
+    FIXME("We have to do something\n");
+    return 0;
+}
+
+DWORD APIENTRY
+Imm32GetImeMenuItemsAW(HIMC hIMC, DWORD dwFlags, DWORD dwType, LPVOID 
lpImeParentMenu,
+                       LPVOID lpImeMenu, DWORD dwSize, BOOL bTargetIsAnsi)
+{
+    DWORD ret = 0, cbTotal, dwProcessId, dwThreadId, iItem;
+    LPINPUTCONTEXT pIC;
+    PIMEDPI pImeDpi = NULL;
+    IMEMENUITEMINFOA ParentA;
+    IMEMENUITEMINFOW ParentW;
+    LPIMEMENUITEMINFOA pItemA;
+    LPIMEMENUITEMINFOW pItemW;
+    LPVOID pNewItems = NULL, pNewParent = NULL;
+    BOOL bImcIsAnsi;
+    HKL hKL;
+
+    if (!hIMC)
+        return 0;
+
+    dwProcessId = NtUserQueryInputContext(hIMC, 0);
+    if (dwProcessId == 0)
+        return 0;
+
+    if (dwProcessId != GetCurrentProcessId())
+    {
+        if (bTargetIsAnsi)
+            return 0;
+        return Imm32GetImeMenuItemWCrossProcess(hIMC, dwFlags, dwType, 
lpImeParentMenu,
+                                                lpImeMenu, dwSize);
+    }
+
+    pIC = ImmLockIMC(hIMC);
+    if (pIC == NULL)
+        return 0;
+
+    dwThreadId = NtUserQueryInputContext(hIMC, 1);
+    if (dwThreadId == 0)
+    {
+        ImmUnlockIMC(hIMC);
+        return 0;
+    }
+
+    hKL = GetKeyboardLayout(dwThreadId);
+    pImeDpi = ImmLockImeDpi(hKL);
+    if (!pImeDpi)
+    {
+        ImmUnlockIMC(hIMC);
+        return 0;
+    }
+
+    if (pImeDpi->ImeGetImeMenuItems == NULL)
+        goto Quit;
+
+    bImcIsAnsi = Imm32IsImcAnsi(hIMC);
+
+    if (bImcIsAnsi != bTargetIsAnsi)
+    {
+        if (bTargetIsAnsi)
+        {
+            if (lpImeParentMenu)
+                pNewParent = &ParentW;
+
+            if (lpImeMenu)
+            {
+                cbTotal = ((dwSize / sizeof(IMEMENUITEMINFOA)) * 
sizeof(IMEMENUITEMINFOW));
+                pNewItems = Imm32HeapAlloc(0, cbTotal);
+                if (!pNewItems)
+                    goto Quit;
+            }
+        }
+        else
+        {
+            if (lpImeParentMenu)
+                pNewParent = &ParentA;
+
+            if (lpImeMenu)
+            {
+                cbTotal = ((dwSize / sizeof(IMEMENUITEMINFOW)) * 
sizeof(IMEMENUITEMINFOA));
+                pNewItems = Imm32HeapAlloc(0, cbTotal);
+                if (!pNewItems)
+                    goto Quit;
+            }
+        }
+    }
+    else
+    {
+        pNewItems = lpImeMenu;
+        pNewParent = lpImeParentMenu;
+    }
+
+    ret = pImeDpi->ImeGetImeMenuItems(hIMC, dwFlags, dwType, pNewParent, 
pNewItems, dwSize);
+    if (!ret || !lpImeMenu)
+        goto Quit;
+
+    if (bImcIsAnsi != bTargetIsAnsi)
+    {
+        if (bTargetIsAnsi)
+        {
+            if (pNewParent)
+                Imm32ImeMenuWideToAnsi(pNewParent, lpImeParentMenu, CP_ACP);
+
+            pItemW = pNewItems;
+            pItemA = lpImeMenu;
+            for (iItem = 0; iItem < ret; ++iItem, ++pItemW, ++pItemA)
+            {
+                if (!Imm32ImeMenuWideToAnsi(pItemW, pItemA, CP_ACP))
+                {
+                    ret = 0;
+                    break;
+                }
+            }
+        }
+        else
+        {
+            if (pNewParent)
+                Imm32ImeMenuAnsiToWide(pNewParent, lpImeParentMenu, 
pImeDpi->uCodePage, TRUE);
+
+            pItemA = pNewItems;
+            pItemW = lpImeMenu;
+            for (iItem = 0; iItem < dwSize; ++iItem, ++pItemA, ++pItemW)
+            {
+                if (!Imm32ImeMenuAnsiToWide(pItemA, pItemW, 
pImeDpi->uCodePage, TRUE))
+                {
+                    ret = 0;
+                    break;
+                }
+            }
+        }
+    }
+
+Quit:
+    if (pNewItems != lpImeMenu)
+        Imm32HeapFree(pNewItems);
+    ImmUnlockImeDpi(pImeDpi);
+    ImmUnlockIMC(hIMC);
+    return ret;
+}
+
 /***********************************************************************
  *             ImmIsIME (IMM32.@)
  */
@@ -1505,6 +1650,34 @@ Quit:
     return ret;
 }
 
+/***********************************************************************
+ *             ImmGetImeMenuItemsA (IMM32.@)
+ */
+DWORD WINAPI
+ImmGetImeMenuItemsA(HIMC hIMC, DWORD dwFlags, DWORD dwType,
+                    LPIMEMENUITEMINFOA lpImeParentMenu,
+                    LPIMEMENUITEMINFOA lpImeMenu, DWORD dwSize)
+{
+    TRACE("(%p, 0x%lX, 0x%lX, %p, %p, 0x%lX)\n",
+          hIMC, dwFlags, dwType, lpImeParentMenu, lpImeMenu, dwSize);
+    return Imm32GetImeMenuItemsAW(hIMC, dwFlags, dwType, lpImeParentMenu, 
lpImeMenu,
+                                  dwSize, TRUE);
+}
+
+/***********************************************************************
+ *             ImmGetImeMenuItemsW (IMM32.@)
+ */
+DWORD WINAPI
+ImmGetImeMenuItemsW(HIMC hIMC, DWORD dwFlags, DWORD dwType,
+                    LPIMEMENUITEMINFOW lpImeParentMenu,
+                    LPIMEMENUITEMINFOW lpImeMenu, DWORD dwSize)
+{
+    TRACE("(%p, 0x%lX, 0x%lX, %p, %p, 0x%lX)\n",
+          hIMC, dwFlags, dwType, lpImeParentMenu, lpImeMenu, dwSize);
+    return Imm32GetImeMenuItemsAW(hIMC, dwFlags, dwType, lpImeParentMenu, 
lpImeMenu,
+                                  dwSize, FALSE);
+}
+
 /***********************************************************************
  *             ImmFreeLayout (IMM32.@)
  */
diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index 07eb129bffc..5cb72db884c 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -1425,148 +1425,6 @@ BOOL WINAPI ImmSetActiveContextConsoleIME(HWND hwnd, 
BOOL fFlag)
     return FALSE;
 }
 
-/***********************************************************************
- *             ImmGetImeMenuItemsA (IMM32.@)
- */
-DWORD WINAPI
-ImmGetImeMenuItemsA(HIMC hIMC, DWORD dwFlags, DWORD dwType,
-                    LPIMEMENUITEMINFOA lpImeParentMenu,
-                    LPIMEMENUITEMINFOA lpImeMenu, DWORD dwSize)
-{
-    InputContextData *data = get_imc_data(hIMC);
-    TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
-        lpImeParentMenu, lpImeMenu, dwSize);
-
-    if (!data)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return 0;
-    }
-
-    if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
-    {
-        if (!is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
-            return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
-                                (IMEMENUITEMINFOW*)lpImeParentMenu,
-                                (IMEMENUITEMINFOW*)lpImeMenu, dwSize);
-        else
-        {
-            IMEMENUITEMINFOW lpImeParentMenuW;
-            IMEMENUITEMINFOW *lpImeMenuW, *parent = NULL;
-            DWORD rc;
-
-            if (lpImeParentMenu)
-                parent = &lpImeParentMenuW;
-            if (lpImeMenu)
-            {
-                int count = dwSize / sizeof(LPIMEMENUITEMINFOA);
-                dwSize = count * sizeof(IMEMENUITEMINFOW);
-                lpImeMenuW = HeapAlloc(GetProcessHeap(), 0, dwSize);
-            }
-            else
-                lpImeMenuW = NULL;
-
-            rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
-                                parent, lpImeMenuW, dwSize);
-
-            if (lpImeParentMenu)
-            {
-                
memcpy(lpImeParentMenu,&lpImeParentMenuW,sizeof(IMEMENUITEMINFOA));
-                lpImeParentMenu->hbmpItem = lpImeParentMenuW.hbmpItem;
-                WideCharToMultiByte(CP_ACP, 0, lpImeParentMenuW.szString,
-                    -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE,
-                    NULL, NULL);
-            }
-            if (lpImeMenu && rc)
-            {
-                unsigned int i;
-                for (i = 0; i < rc; i++)
-                {
-                    
memcpy(&lpImeMenu[i],&lpImeMenuW[1],sizeof(IMEMENUITEMINFOA));
-                    lpImeMenu[i].hbmpItem = lpImeMenuW[i].hbmpItem;
-                    WideCharToMultiByte(CP_ACP, 0, lpImeMenuW[i].szString,
-                        -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE,
-                        NULL, NULL);
-                }
-            }
-            HeapFree(GetProcessHeap(),0,lpImeMenuW);
-            return rc;
-        }
-    }
-    else
-        return 0;
-}
-
-/***********************************************************************
- *             ImmGetImeMenuItemsW (IMM32.@)
- */
-DWORD WINAPI
-ImmGetImeMenuItemsW(HIMC hIMC, DWORD dwFlags, DWORD dwType,
-                    LPIMEMENUITEMINFOW lpImeParentMenu,
-                    LPIMEMENUITEMINFOW lpImeMenu, DWORD dwSize)
-{
-    InputContextData *data = get_imc_data(hIMC);
-    TRACE("(%p, %i, %i, %p, %p, %i):\n", hIMC, dwFlags, dwType,
-        lpImeParentMenu, lpImeMenu, dwSize);
-
-    if (!data)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return 0;
-    }
-
-    if (data->immKbd->hIME && data->immKbd->pImeGetImeMenuItems)
-    {
-        if (is_himc_ime_unicode(data) || (!lpImeParentMenu && !lpImeMenu))
-            return data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
-                                lpImeParentMenu, lpImeMenu, dwSize);
-        else
-        {
-            IMEMENUITEMINFOA lpImeParentMenuA;
-            IMEMENUITEMINFOA *lpImeMenuA, *parent = NULL;
-            DWORD rc;
-
-            if (lpImeParentMenu)
-                parent = &lpImeParentMenuA;
-            if (lpImeMenu)
-            {
-                int count = dwSize / sizeof(LPIMEMENUITEMINFOW);
-                dwSize = count * sizeof(IMEMENUITEMINFOA);
-                lpImeMenuA = HeapAlloc(GetProcessHeap(), 0, dwSize);
-            }
-            else
-                lpImeMenuA = NULL;
-
-            rc = data->immKbd->pImeGetImeMenuItems(hIMC, dwFlags, dwType,
-                                (IMEMENUITEMINFOW*)parent,
-                                (IMEMENUITEMINFOW*)lpImeMenuA, dwSize);
-
-            if (lpImeParentMenu)
-            {
-                
memcpy(lpImeParentMenu,&lpImeParentMenuA,sizeof(IMEMENUITEMINFOA));
-                lpImeParentMenu->hbmpItem = lpImeParentMenuA.hbmpItem;
-                MultiByteToWideChar(CP_ACP, 0, lpImeParentMenuA.szString,
-                    -1, lpImeParentMenu->szString, IMEMENUITEM_STRING_SIZE);
-            }
-            if (lpImeMenu && rc)
-            {
-                unsigned int i;
-                for (i = 0; i < rc; i++)
-                {
-                    
memcpy(&lpImeMenu[i],&lpImeMenuA[1],sizeof(IMEMENUITEMINFOA));
-                    lpImeMenu[i].hbmpItem = lpImeMenuA[i].hbmpItem;
-                    MultiByteToWideChar(CP_ACP, 0, lpImeMenuA[i].szString,
-                        -1, lpImeMenu[i].szString, IMEMENUITEM_STRING_SIZE);
-                }
-            }
-            HeapFree(GetProcessHeap(),0,lpImeMenuA);
-            return rc;
-        }
-    }
-    else
-        return 0;
-}
-
 BOOL WINAPI User32InitializeImmEntryTable(DWORD);
 
 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
diff --git a/dll/win32/imm32/precomp.h b/dll/win32/imm32/precomp.h
index 7bab3b95031..1bcc18bbb30 100644
--- a/dll/win32/imm32/precomp.h
+++ b/dll/win32/imm32/precomp.h
@@ -95,6 +95,8 @@ static inline BOOL Imm32IsCrossProcessAccess(HWND hWnd)
             (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess);
 }
 
+BOOL WINAPI Imm32IsImcAnsi(HIMC hIMC);
+
 #define ImeDpi_IsUnicode(pImeDpi)   ((pImeDpi)->ImeInfo.fdwProperty & 
IME_PROP_UNICODE)
 #define Imm32IsImmMode()            (g_psi && (g_psi->dwSRVIFlags & 
SRVINFO_IMM32))
 #define Imm32IsCiceroMode()         (g_psi && (g_psi->dwSRVIFlags & 
SRVINFO_CICERO_ENABLED))
@@ -112,3 +114,10 @@ Imm32NotifyAction(HIMC hIMC, HWND hwnd, DWORD dwAction, 
DWORD_PTR dwIndex, DWORD
                   DWORD_PTR dwCommand, DWORD_PTR dwData);
 
 DWORD APIENTRY Imm32AllocAndBuildHimcList(DWORD dwThreadId, HIMC **pphList);
+
+INT APIENTRY
+Imm32ImeMenuAnsiToWide(const IMEMENUITEMINFOA *pItemA, LPIMEMENUITEMINFOW 
pItemW,
+                       UINT uCodePage, BOOL bBitmap);
+INT APIENTRY
+Imm32ImeMenuWideToAnsi(const IMEMENUITEMINFOW *pItemW, LPIMEMENUITEMINFOA 
pItemA,
+                       UINT uCodePage);
diff --git a/dll/win32/imm32/utils.c b/dll/win32/imm32/utils.c
index 64bd3d158be..cda20efc884 100644
--- a/dll/win32/imm32/utils.c
+++ b/dll/win32/imm32/utils.c
@@ -16,6 +16,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm);
 
 HANDLE g_hImm32Heap = NULL;
 
+BOOL WINAPI Imm32IsImcAnsi(HIMC hIMC)
+{
+    BOOL ret;
+    PCLIENTIMC pClientImc = ImmLockClientImc(hIMC);
+    if (!pClientImc)
+        return -1;
+    ret = !(pClientImc->dwFlags & CLIENTIMC_WIDE);
+    ImmUnlockClientImc(pClientImc);
+    return ret;
+}
+
 LPWSTR APIENTRY Imm32WideFromAnsi(LPCSTR pszA)
 {
     INT cch = lstrlenA(pszA);
@@ -202,6 +213,55 @@ DWORD APIENTRY Imm32AllocAndBuildHimcList(DWORD 
dwThreadId, HIMC **pphList)
 #undef MAX_RETRY
 }
 
+INT APIENTRY
+Imm32ImeMenuAnsiToWide(const IMEMENUITEMINFOA *pItemA, LPIMEMENUITEMINFOW 
pItemW,
+                       UINT uCodePage, BOOL bBitmap)
+{
+    INT ret;
+    pItemW->cbSize = pItemA->cbSize;
+    pItemW->fType = pItemA->fType;
+    pItemW->fState = pItemA->fState;
+    pItemW->wID = pItemA->wID;
+    if (bBitmap)
+    {
+        pItemW->hbmpChecked = pItemA->hbmpChecked;
+        pItemW->hbmpUnchecked = pItemA->hbmpUnchecked;
+        pItemW->hbmpItem = pItemA->hbmpItem;
+    }
+    pItemW->dwItemData = pItemA->dwItemData;
+    ret = MultiByteToWideChar(uCodePage, 0, pItemA->szString, -1,
+                              pItemW->szString, _countof(pItemW->szString));
+    if (ret >= _countof(pItemW->szString))
+    {
+        ret = 0;
+        pItemW->szString[0] = 0;
+    }
+    return ret;
+}
+
+INT APIENTRY
+Imm32ImeMenuWideToAnsi(const IMEMENUITEMINFOW *pItemW, LPIMEMENUITEMINFOA 
pItemA,
+                       UINT uCodePage)
+{
+    INT ret;
+    pItemA->cbSize = pItemW->cbSize;
+    pItemA->fType = pItemW->fType;
+    pItemA->fState = pItemW->fState;
+    pItemA->wID = pItemW->wID;
+    pItemA->hbmpChecked = pItemW->hbmpChecked;
+    pItemA->hbmpUnchecked = pItemW->hbmpUnchecked;
+    pItemA->dwItemData = pItemW->dwItemData;
+    pItemA->hbmpItem = pItemW->hbmpItem;
+    ret = WideCharToMultiByte(uCodePage, 0, pItemW->szString, -1,
+                              pItemA->szString, _countof(pItemA->szString), 
NULL, NULL);
+    if (ret >= _countof(pItemA->szString))
+    {
+        ret = 0;
+        pItemA->szString[0] = 0;
+    }
+    return ret;
+}
+
 /***********************************************************************
  *             ImmCreateIMCC(IMM32.@)
  */
diff --git a/win32ss/include/imetable.h b/win32ss/include/imetable.h
index 09580a4ac95..70bc982a6dc 100644
--- a/win32ss/include/imetable.h
+++ b/win32ss/include/imetable.h
@@ -1,4 +1,4 @@
-/* DEFINE_IME_ENTRY(type, name, params, extended) */
+/* DEFINE_IME_ENTRY(type, name, params, optional) */
 DEFINE_IME_ENTRY(BOOL, ImeInquire, (LPIMEINFO lpIMEInfo, LPVOID lpszWndClass, 
DWORD dwSystemInfoFlags), FALSE)
 DEFINE_IME_ENTRY(DWORD, ImeConversionList, (HIMC hIMC, LPCVOID lpSrc, 
LPCANDIDATELIST lpDst, DWORD dwBufLen, UINT uFlag), FALSE)
 DEFINE_IME_ENTRY(BOOL, ImeRegisterWord, (LPCVOID lpszReading, DWORD dwStyle, 
LPCVOID lpszString), FALSE)
@@ -14,7 +14,7 @@ DEFINE_IME_ENTRY(BOOL, ImeSetActiveContext, (HIMC hIMC, BOOL 
fFlag), FALSE)
 DEFINE_IME_ENTRY(UINT, ImeToAsciiEx, (UINT uVirKey, UINT uScanCode, CONST 
LPBYTE lpbKeyState, LPTRANSMSGLIST lpTransMsgList, UINT fuState, HIMC hIMC), 
FALSE)
 DEFINE_IME_ENTRY(BOOL, NotifyIME, (HIMC hIMC, DWORD dwAction, DWORD dwIndex, 
DWORD dwValue), FALSE)
 DEFINE_IME_ENTRY(BOOL, ImeSetCompositionString, (HIMC hIMC, DWORD dwIndex, 
LPCVOID lpComp, DWORD dwCompLen, LPCVOID lpRead, DWORD dwReadLen), FALSE)
-DEFINE_IME_ENTRY(DWORD, ImeGetImeMenuItems, (HIMC hIMC, DWORD dwFlags, DWORD 
dwType, LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu, DWORD 
dwSize), FALSE)
+DEFINE_IME_ENTRY(DWORD, ImeGetImeMenuItems, (HIMC hIMC, DWORD dwFlags, DWORD 
dwType, LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu, DWORD 
dwSize), TRUE)
 DEFINE_IME_ENTRY(BOOL, CtfImeInquireExW, (LPIMEINFO lpIMEInfo, LPVOID 
lpszWndClass, DWORD dwSystemInfoFlags, HKL hKL), TRUE)
 DEFINE_IME_ENTRY(BOOL, CtfImeSelectEx, (HIMC hIMC, BOOL fSelect, HKL hKL), 
TRUE)
 DEFINE_IME_ENTRY(LRESULT, CtfImeEscapeEx, (HIMC hIMC, UINT uSubFunc, LPVOID 
lpData, HKL hKL), TRUE)

Reply via email to