https://git.reactos.org/?p=reactos.git;a=commitdiff;h=33affbfecbc8a3a4c5c20…
commit 33affbfecbc8a3a4c5c20a8776e46f34da898f40
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Fri Oct 1 03:04:00 2021 +0900
Commit: GitHub <noreply(a)github.com>
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)