[IMM32] Rewrite ImmEscapeA/W (#3959)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Thu, 16 Sep 2021 10:27:43 +0000 (19:27 +0900)
committerGitHub <noreply@github.com>
Thu, 16 Sep 2021 10:27:43 +0000 (19:27 +0900)
- Rewrite ImmEscapeA and ImmEscapeW functions.
- Delete useless legacy code.
CORE-11700

dll/win32/imm32/ime.c
dll/win32/imm32/imm.c
dll/win32/imm32/precomp.h
win32ss/include/imetable.h

index 3edb95b..80a2c50 100644 (file)
@@ -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.@)
  */
index a07a6c6..21832a5 100644 (file)
@@ -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
index 6efcbf7..b96a9af 100644 (file)
@@ -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)
index 96d18de..d9d0929 100644 (file)
@@ -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)