https://git.reactos.org/?p=reactos.git;a=commitdiff;h=afb6c8a12957f4b3f138a…
commit afb6c8a12957f4b3f138ae434a741dcb20bb0fcb
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Thu Sep 16 19:27:43 2021 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu Sep 16 19:27:43 2021 +0900
[IMM32] Rewrite ImmEscapeA/W (#3959)
- Rewrite ImmEscapeA and ImmEscapeW functions.
- Delete useless legacy code.
CORE-11700
---
dll/win32/imm32/ime.c | 178 ++++++++++++++++++++++++++++++++++++++++
dll/win32/imm32/imm.c | 199 ---------------------------------------------
dll/win32/imm32/precomp.h | 1 +
win32ss/include/imetable.h | 2 +-
4 files changed, 180 insertions(+), 200 deletions(-)
diff --git a/dll/win32/imm32/ime.c b/dll/win32/imm32/ime.c
index 3edb95b08ef..80a2c50f33c 100644
--- a/dll/win32/imm32/ime.c
+++ b/dll/win32/imm32/ime.c
@@ -276,6 +276,20 @@ PIMEDPI APIENTRY ImmLockOrLoadImeDpi(HKL hKL)
return pImeDpi;
}
+static LRESULT APIENTRY
+ImeDpi_Escape(PIMEDPI pImeDpi, HIMC hIMC, UINT uSubFunc, LPVOID lpData, HKL hKL)
+{
+ if (IS_IME_HKL(hKL))
+ return pImeDpi->ImeEscape(hIMC, uSubFunc, lpData);
+
+ if (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED))
+ {
+ if (pImeDpi->CtfImeEscapeEx)
+ return pImeDpi->CtfImeEscapeEx(hIMC, uSubFunc, lpData, hKL);
+ }
+ return 0;
+}
+
/***********************************************************************
* ImmIsIME (IMM32.@)
*/
@@ -650,6 +664,170 @@ DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex)
return dwValue;
}
+/***********************************************************************
+ * ImmEscapeA (IMM32.@)
+ */
+LRESULT WINAPI ImmEscapeA(HKL hKL, HIMC hIMC, UINT uSubFunc, LPVOID lpData)
+{
+ LRESULT ret;
+ PIMEDPI pImeDpi;
+ INT cch;
+ CHAR szA[MAX_IMM_FILENAME];
+ WCHAR szW[MAX_IMM_FILENAME];
+
+ TRACE("(%p, %p, %u, %p)\n", hKL, hIMC, uSubFunc, lpData);
+
+ pImeDpi = ImmLockOrLoadImeDpi(hKL);
+ if (!pImeDpi)
+ return 0;
+
+ if (!(pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) || !lpData)
+ {
+ ret = ImeDpi_Escape(pImeDpi, hIMC, uSubFunc, lpData, hKL);
+ ImmUnlockImeDpi(pImeDpi);
+ return ret;
+ }
+
+ switch (uSubFunc)
+ {
+ case IME_ESC_SEQUENCE_TO_INTERNAL:
+ ret = ImeDpi_Escape(pImeDpi, hIMC, uSubFunc, lpData, hKL);
+
+ cch = 0;
+ if (HIWORD(ret))
+ szW[cch++] = HIWORD(ret);
+ if (LOWORD(ret))
+ szW[cch++] = LOWORD(ret);
+
+ cch = WideCharToMultiByte(pImeDpi->uCodePage, 0, szW, cch, szA,
_countof(szA),
+ NULL, NULL);
+ switch (cch)
+ {
+ case 1:
+ ret = MAKEWORD(szA[0], 0);
+ break;
+ case 2:
+ ret = MAKEWORD(szA[1], szA[0]);
+ break;
+ case 3:
+ ret = MAKELONG(MAKEWORD(szA[2], szA[1]), MAKEWORD(szA[0], 0));
+ break;
+ case 4:
+ ret = MAKELONG(MAKEWORD(szA[3], szA[2]), MAKEWORD(szA[1], szA[0]));
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ break;
+
+ case IME_ESC_GET_EUDC_DICTIONARY:
+ case IME_ESC_IME_NAME:
+ case IME_ESC_GETHELPFILENAME:
+ ret = ImeDpi_Escape(pImeDpi, hIMC, uSubFunc, szW, hKL);
+ if (ret)
+ {
+ szW[_countof(szW) - 1] = 0;
+ WideCharToMultiByte(pImeDpi->uCodePage, 0, szW, -1,
+ lpData, MAX_IMM_FILENAME, NULL, NULL);
+ ((LPSTR)lpData)[MAX_IMM_FILENAME - 1] = 0;
+ }
+ break;
+
+ case IME_ESC_SET_EUDC_DICTIONARY:
+ case IME_ESC_HANJA_MODE:
+ MultiByteToWideChar(pImeDpi->uCodePage, MB_PRECOMPOSED,
+ lpData, -1, szW, _countof(szW));
+ szW[_countof(szW) - 1] = 0;
+ ret = ImeDpi_Escape(pImeDpi, hIMC, uSubFunc, szW, hKL);
+ break;
+
+ default:
+ ret = ImeDpi_Escape(pImeDpi, hIMC, uSubFunc, lpData, hKL);
+ break;
+ }
+
+ ImmUnlockImeDpi(pImeDpi);
+ return ret;
+}
+
+/***********************************************************************
+ * ImmEscapeW (IMM32.@)
+ */
+LRESULT WINAPI ImmEscapeW(HKL hKL, HIMC hIMC, UINT uSubFunc, LPVOID lpData)
+{
+ LRESULT ret;
+ PIMEDPI pImeDpi;
+ INT cch;
+ CHAR szA[MAX_IMM_FILENAME];
+ WCHAR szW[MAX_IMM_FILENAME];
+ WORD word;
+
+ TRACE("(%p, %p, %u, %p)\n", hKL, hIMC, uSubFunc, lpData);
+
+ pImeDpi = ImmLockOrLoadImeDpi(hKL);
+ if (!pImeDpi)
+ return 0;
+
+ if ((pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) || !lpData)
+ {
+ ret = ImeDpi_Escape(pImeDpi, hIMC, uSubFunc, lpData, hKL);
+ ImmUnlockImeDpi(pImeDpi);
+ return ret;
+ }
+
+ switch (uSubFunc)
+ {
+ case IME_ESC_SEQUENCE_TO_INTERNAL:
+ ret = ImeDpi_Escape(pImeDpi, hIMC, uSubFunc, lpData, hKL);
+
+ word = LOWORD(ret);
+ cch = 0;
+ if (HIBYTE(word))
+ szA[cch++] = HIBYTE(word);
+ if (LOBYTE(word))
+ szA[cch++] = LOBYTE(word);
+
+ cch = MultiByteToWideChar(pImeDpi->uCodePage, MB_PRECOMPOSED,
+ szA, cch, szW, _countof(szW));
+ switch (cch)
+ {
+ case 1: ret = szW[0]; break;
+ case 2: ret = MAKELONG(szW[1], szW[0]); break;
+ default: ret = 0; break;
+ }
+ break;
+
+ case IME_ESC_GET_EUDC_DICTIONARY:
+ case IME_ESC_IME_NAME:
+ case IME_ESC_GETHELPFILENAME:
+ ret = ImeDpi_Escape(pImeDpi, hIMC, uSubFunc, szA, hKL);
+ if (ret)
+ {
+ szA[_countof(szA) - 1] = 0;
+ MultiByteToWideChar(pImeDpi->uCodePage, MB_PRECOMPOSED,
+ szA, -1, lpData, MAX_IMM_FILENAME);
+ ((LPWSTR)lpData)[MAX_IMM_FILENAME - 1] = 0;
+ }
+ break;
+
+ case IME_ESC_SET_EUDC_DICTIONARY:
+ case IME_ESC_HANJA_MODE:
+ WideCharToMultiByte(pImeDpi->uCodePage, 0,
+ lpData, -1, szA, _countof(szA), NULL, NULL);
+ szA[_countof(szA) - 1] = 0;
+ ret = ImeDpi_Escape(pImeDpi, hIMC, uSubFunc, szA, hKL);
+ break;
+
+ default:
+ ret = ImeDpi_Escape(pImeDpi, hIMC, uSubFunc, lpData, hKL);
+ break;
+ }
+
+ ImmUnlockImeDpi(pImeDpi);
+ return ret;
+}
+
/***********************************************************************
* ImmGetOpenStatus (IMM32.@)
*/
diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index a07a6c6965a..21832a5a3bc 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -146,21 +146,7 @@ typedef struct tagInputContextData
#define WINE_IMC_VALID_MAGIC 0x56434D49
-typedef struct _tagIMMThreadData
-{
- struct list entry;
- DWORD threadID;
- HIMC defaultContext;
- HWND hwndDefault;
- BOOL disableIME;
- DWORD windowRefs;
-} IMMThreadData;
-
-static struct list ImmHklList = LIST_INIT(ImmHklList);
-static struct list ImmThreadDataList = LIST_INIT(ImmThreadDataList);
-
static const WCHAR szwWineIMCProperty[] =
{'W','i','n','e','I','m','m','H','I','M','C','P','r','o','p','e','r','t','y',0};
-
static const WCHAR szImeFileW[] = {'I','m','e','
','F','i','l','e',0};
static const WCHAR szLayoutTextW[] =
{'L','a','y','o','u','t','
','T','e','x','t',0};
static const WCHAR szImeRegFmt[] =
{'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','K','e','y','b','o','a','r','d','
','L','a','y','o','u','t','s','\\','%','0','8','l','x',0};
@@ -170,115 +156,6 @@ static inline BOOL is_himc_ime_unicode(const InputContextData
*data)
return !!(data->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE);
}
-static inline BOOL is_kbd_ime_unicode(const ImmHkl *hkl)
-{
- return !!(hkl->imeInfo.fdwProperty & IME_PROP_UNICODE);
-}
-
-static InputContextData* get_imc_data(HIMC hIMC);
-
-static HMODULE load_graphics_driver(void)
-{
- static const WCHAR display_device_guid_propW[] = {
-
'_','_','w','i','n','e','_','d','i','s','p','l','a','y','_',
-
'd','e','v','i','c','e','_','g','u','i','d',0
};
- static const WCHAR key_pathW[] = {
-
'S','y','s','t','e','m','\\',
-
'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
-
'C','o','n','t','r','o','l','\\',
-
'V','i','d','e','o','\\','{',0};
- static const WCHAR displayW[] =
{'}','\\','0','0','0','0',0};
- static const WCHAR driverW[] =
{'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
-
- HMODULE ret = 0;
- HKEY hkey;
- DWORD size;
- WCHAR path[MAX_PATH];
- WCHAR key[ARRAY_SIZE( key_pathW ) + ARRAY_SIZE( displayW ) + 40];
- UINT guid_atom = HandleToULong( GetPropW( GetDesktopWindow(),
display_device_guid_propW ));
-
- if (!guid_atom) return 0;
- memcpy( key, key_pathW, sizeof(key_pathW) );
- if (!GlobalGetAtomNameW( guid_atom, key + lstrlenW(key), 40 )) return 0;
- lstrcatW( key, displayW );
- if (RegOpenKeyW( HKEY_LOCAL_MACHINE, key, &hkey )) return 0;
- size = sizeof(path);
- if (!RegQueryValueExW( hkey, driverW, NULL, NULL, (BYTE *)path, &size )) ret =
LoadLibraryW( path );
- RegCloseKey( hkey );
- TRACE( "%s %p\n", debugstr_w(path), ret );
- return ret;
-}
-
-/* ImmHkl loading and freeing */
-#define LOAD_FUNCPTR(f) if((ptr->p##f = (LPVOID)GetProcAddress(ptr->hIME, #f)) ==
NULL){WARN("Can't find function %s in ime\n", #f);}
-static ImmHkl *IMM_GetImmHkl(HKL hkl)
-{
- ImmHkl *ptr;
- WCHAR filename[MAX_PATH];
-
- TRACE("Seeking ime for keyboard %p\n",hkl);
-
- LIST_FOR_EACH_ENTRY(ptr, &ImmHklList, ImmHkl, entry)
- {
- if (ptr->hkl == hkl)
- return ptr;
- }
- /* not found... create it */
-
- ptr = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ImmHkl));
-
- ptr->hkl = hkl;
- if (ImmGetIMEFileNameW(hkl, filename, MAX_PATH)) ptr->hIME =
LoadLibraryW(filename);
- if (!ptr->hIME) ptr->hIME = load_graphics_driver();
- if (ptr->hIME)
- {
- LOAD_FUNCPTR(ImeInquire);
- if (!ptr->pImeInquire || !ptr->pImeInquire(&ptr->imeInfo,
ptr->imeClassName, NULL))
- {
- FreeLibrary(ptr->hIME);
- ptr->hIME = NULL;
- }
- else
- {
- LOAD_FUNCPTR(ImeDestroy);
- LOAD_FUNCPTR(ImeSelect);
- if (!ptr->pImeSelect || !ptr->pImeDestroy)
- {
- FreeLibrary(ptr->hIME);
- ptr->hIME = NULL;
- }
- else
- {
- LOAD_FUNCPTR(ImeConfigure);
- LOAD_FUNCPTR(ImeEscape);
- LOAD_FUNCPTR(ImeSetActiveContext);
- LOAD_FUNCPTR(ImeToAsciiEx);
- LOAD_FUNCPTR(NotifyIME);
- LOAD_FUNCPTR(ImeRegisterWord);
- LOAD_FUNCPTR(ImeUnregisterWord);
- LOAD_FUNCPTR(ImeEnumRegisterWord);
- LOAD_FUNCPTR(ImeSetCompositionString);
- LOAD_FUNCPTR(ImeConversionList);
- LOAD_FUNCPTR(ImeProcessKey);
- LOAD_FUNCPTR(ImeGetRegisterWordStyle);
- LOAD_FUNCPTR(ImeGetImeMenuItems);
- /* make sure our classname is WCHAR */
- if (!is_kbd_ime_unicode(ptr))
- {
- WCHAR bufW[17];
- MultiByteToWideChar(CP_ACP, 0, (LPSTR)ptr->imeClassName,
- -1, bufW, 17);
- lstrcpyW(ptr->imeClassName, bufW);
- }
- }
- }
- }
- list_add_head(&ImmHklList,&ptr->entry);
-
- return ptr;
-}
-#undef LOAD_FUNCPTR
-
static InputContextData* get_imc_data(HIMC hIMC)
{
InputContextData *data = (InputContextData *)hIMC;
@@ -553,82 +430,6 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
return Imm32CleanupContext(hIMC, hKL, FALSE);
}
-static inline BOOL EscapeRequiresWA(UINT uEscape)
-{
- if (uEscape == IME_ESC_GET_EUDC_DICTIONARY ||
- uEscape == IME_ESC_SET_EUDC_DICTIONARY ||
- uEscape == IME_ESC_IME_NAME ||
- uEscape == IME_ESC_GETHELPFILENAME)
- return TRUE;
- return FALSE;
-}
-
-/***********************************************************************
- * ImmEscapeA (IMM32.@)
- */
-LRESULT WINAPI ImmEscapeA(HKL hKL, HIMC hIMC, UINT uEscape, LPVOID lpData)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
-
- if (immHkl->hIME && immHkl->pImeEscape)
- {
- if (!EscapeRequiresWA(uEscape) || !is_kbd_ime_unicode(immHkl))
- return immHkl->pImeEscape(hIMC,uEscape,lpData);
- else
- {
- WCHAR buffer[81]; /* largest required buffer should be 80 */
- LRESULT rc;
- if (uEscape == IME_ESC_SET_EUDC_DICTIONARY)
- {
- MultiByteToWideChar(CP_ACP,0,lpData,-1,buffer,81);
- rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
- }
- else
- {
- rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
- WideCharToMultiByte(CP_ACP,0,buffer,-1,lpData,80, NULL, NULL);
- }
- return rc;
- }
- }
- else
- return 0;
-}
-
-/***********************************************************************
- * ImmEscapeW (IMM32.@)
- */
-LRESULT WINAPI ImmEscapeW(HKL hKL, HIMC hIMC, UINT uEscape, LPVOID lpData)
-{
- ImmHkl *immHkl = IMM_GetImmHkl(hKL);
- TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
-
- if (immHkl->hIME && immHkl->pImeEscape)
- {
- if (!EscapeRequiresWA(uEscape) || is_kbd_ime_unicode(immHkl))
- return immHkl->pImeEscape(hIMC,uEscape,lpData);
- else
- {
- CHAR buffer[81]; /* largest required buffer should be 80 */
- LRESULT rc;
- if (uEscape == IME_ESC_SET_EUDC_DICTIONARY)
- {
- WideCharToMultiByte(CP_ACP,0,lpData,-1,buffer,81, NULL, NULL);
- rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
- }
- else
- {
- rc = immHkl->pImeEscape(hIMC,uEscape,buffer);
- MultiByteToWideChar(CP_ACP,0,buffer,-1,lpData,80);
- }
- return rc;
- }
- }
- else
- return 0;
-}
-
static PCLIENTIMC APIENTRY Imm32GetClientImcCache(void)
{
// FIXME: Do something properly here
diff --git a/dll/win32/imm32/precomp.h b/dll/win32/imm32/precomp.h
index 6efcbf70fe1..b96a9afa695 100644
--- a/dll/win32/imm32/precomp.h
+++ b/dll/win32/imm32/precomp.h
@@ -49,6 +49,7 @@
#define IMM_INVALID_CANDFORM ULONG_MAX
#define INVALID_HOTKEY_ID 0xFFFFFFFF
#define MAX_CANDIDATEFORM 4
+#define MAX_IMM_FILENAME 80
#define LANGID_CHINESE_SIMPLIFIED MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
#define LANGID_CHINESE_TRADITIONAL MAKELANGID(LANG_CHINESE,
SUBLANG_CHINESE_TRADITIONAL)
diff --git a/win32ss/include/imetable.h b/win32ss/include/imetable.h
index 96d18de18b4..d9d0929757d 100644
--- a/win32ss/include/imetable.h
+++ b/win32ss/include/imetable.h
@@ -17,6 +17,6 @@ DEFINE_IME_ENTRY(BOOL, ImeSetCompositionString, (HIMC hIMC, DWORD
dwIndex, LPCVO
DEFINE_IME_ENTRY(DWORD, ImeGetImeMenuItems, (HIMC hIMC, DWORD dwFlags, DWORD dwType,
LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu, DWORD dwSize), FALSE)
DEFINE_IME_ENTRY(DWORD, CtfImeInquireExW, (VOID /* FIXME: unknown */), TRUE)
DEFINE_IME_ENTRY(DWORD, CtfImeSelectEx, (VOID /* FIXME: unknown */), TRUE)
-DEFINE_IME_ENTRY(DWORD, CtfImeEscapeEx, (VOID /* FIXME: unknown */), TRUE)
+DEFINE_IME_ENTRY(LRESULT, CtfImeEscapeEx, (HIMC hIMC, UINT uSubFunc, LPVOID lpData, HKL
hKL), TRUE)
DEFINE_IME_ENTRY(DWORD, CtfImeGetGuidAtom, (VOID /* FIXME: unknown */), TRUE)
DEFINE_IME_ENTRY(DWORD, CtfImeIsGuidMapEnable, (VOID /* FIXME: unknown */), TRUE)