[TASKMGR] Process page: Allow using "Open File Location" functionality without runnin...
[reactos.git] / dll / win32 / imm32 / keymsg.c
index e2d4114..f1dd211 100644 (file)
  */
 
 #include "precomp.h"
+#include <jpnvkeys.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(imm);
 
-BOOL APIENTRY Imm32ImeNonImeToggle(HIMC hIMC, HKL hKL, HWND hWnd, LANGID LangID)
+/* Win: IMENonIMEToggle */
+BOOL APIENTRY Imm32ImeNonImeToggle(HIMC hIMC, HKL hKL, HWND hWnd, BOOL bNowIME, LANGID LangID)
+{
+    HKL hOldKL, LayoutList[32], hFoundKL = NULL;
+    UINT iLayout, nLayoutCount;
+
+    /* Get the previous layout */
+    hOldKL = (HKL)NtUserGetThreadState(THREADSTATE_OLDKEYBOARDLAYOUT);
+
+    /* Get the layout list */
+    nLayoutCount = GetKeyboardLayoutList(_countof(LayoutList), LayoutList);
+
+    /* Is there hOldKL in the list in the specified language ID? */
+    if (hOldKL && (LangID == 0 || LOWORD(hOldKL) == LangID))
+    {
+        for (iLayout = 0; iLayout < nLayoutCount; ++iLayout)
+        {
+            if (LayoutList[iLayout] == hOldKL)
+            {
+                hFoundKL = hOldKL;
+                break;
+            }
+        }
+    }
+
+    if (hFoundKL == NULL) /* Not found? */
+    {
+        /* Is there the keyboard layout of another kind in LangID? */
+        for (iLayout = 0; iLayout < nLayoutCount; ++iLayout)
+        {
+            if (bNowIME == ImmIsIME(LayoutList[iLayout])) /* Same kind? */
+                continue;
+
+            if (LangID == 0 || LangID == LOWORD(LayoutList[iLayout]))
+            {
+                hFoundKL = LayoutList[iLayout];
+                break;
+            }
+        }
+    }
+
+    if (hFoundKL && hKL != hFoundKL) /* Found and different layout */
+    {
+        PostMessageW(hWnd, WM_INPUTLANGCHANGEREQUEST, 1, (LPARAM)hFoundKL);
+    }
+
+    return ImmIsIME(hFoundKL);
+}
+
+/* Open or close the IME on Chinese or Taiwanese */
+/* Win: CIMENonIMEToggle */
+BOOL APIENTRY Imm32CImeNonImeToggle(HIMC hIMC, HKL hKL, HWND hWnd, LANGID LangID)
 {
     LPINPUTCONTEXT pIC;
     BOOL fOpen;
 
-    if (hWnd != NULL)
+    if (IS_NULL_UNEXPECTEDLY(hWnd))
         return FALSE;
 
-    if (!IS_IME_HKL(hKL) || LOWORD(hKL) != LangID)
+    if (LOWORD(hKL) != LangID || !ImmIsIME(hKL))
     {
-        FIXME("We have to do something here\n");
+        Imm32ImeNonImeToggle(hIMC, hKL, hWnd, FALSE, LangID);
         return TRUE;
     }
 
     pIC = ImmLockIMC(hIMC);
-    if (pIC == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
         return TRUE;
 
     fOpen = pIC->fOpen;
     ImmUnlockIMC(hIMC);
 
-    if (!fOpen)
-    {
+    if (fOpen)
+        Imm32ImeNonImeToggle(hIMC, hKL, hWnd, TRUE, 0);
+    else
         ImmSetOpenStatus(hIMC, TRUE);
-        return TRUE;
-    }
 
-    FIXME("We have to do something here\n");
     return TRUE;
 }
 
+/* Toggle shape mode on Chinese or Taiwanese */
+/* Win: TShapeToggle */
 BOOL APIENTRY Imm32CShapeToggle(HIMC hIMC, HKL hKL, HWND hWnd)
 {
     LPINPUTCONTEXT pIC;
     BOOL fOpen;
     DWORD dwConversion, dwSentence;
 
-    if (hWnd == NULL || !IS_IME_HKL(hKL))
+    if (hWnd == NULL || !ImmIsIME(hKL))
         return FALSE;
 
     pIC = ImmLockIMC(hIMC);
-    if (pIC == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
         return TRUE;
 
     fOpen = pIC->fOpen;
@@ -74,17 +126,18 @@ BOOL APIENTRY Imm32CShapeToggle(HIMC hIMC, HKL hKL, HWND hWnd)
     return TRUE;
 }
 
+/* Win: CSymbolToggle */
 BOOL APIENTRY Imm32CSymbolToggle(HIMC hIMC, HKL hKL, HWND hWnd)
 {
     LPINPUTCONTEXT pIC;
     BOOL fOpen;
     DWORD dwConversion, dwSentence;
 
-    if (hWnd == NULL || !IS_IME_HKL(hKL))
+    if (hWnd == NULL || !ImmIsIME(hKL))
         return FALSE;
 
     pIC = ImmLockIMC(hIMC);
-    if (pIC == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
         return TRUE;
 
     fOpen = pIC->fOpen;
@@ -104,28 +157,41 @@ BOOL APIENTRY Imm32CSymbolToggle(HIMC hIMC, HKL hKL, HWND hWnd)
     return TRUE;
 }
 
+/* Open or close Japanese IME */
 BOOL APIENTRY Imm32JCloseOpen(HIMC hIMC, HKL hKL, HWND hWnd)
 {
     BOOL fOpen;
+    LPINPUTCONTEXTDX pIC;
 
-    if (ImmIsIME(hKL) && LOWORD(hKL) == LANGID_JAPANESE)
+    if (LOWORD(hKL) == LANGID_JAPANESE && ImmIsIME(hKL)) /* Japanese IME is selected */
     {
         fOpen = ImmGetOpenStatus(hIMC);
         ImmSetOpenStatus(hIMC, !fOpen);
         return TRUE;
     }
 
-    FIXME("We have to do something here\n");
+    /* Japanese IME is not selected. Select now */
+    if (Imm32ImeNonImeToggle(hIMC, hKL, hWnd, FALSE, LANGID_JAPANESE))
+    {
+        pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
+        if (pIC)
+        {
+            pIC->dwChange |= INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
+            ImmUnlockIMC(hIMC);
+        }
+    }
+
     return TRUE;
 }
 
+/* Win: KShapeToggle */
 BOOL APIENTRY Imm32KShapeToggle(HIMC hIMC)
 {
     LPINPUTCONTEXT pIC;
     DWORD dwConversion, dwSentence;
 
     pIC = ImmLockIMC(hIMC);
-    if (pIC == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
         return FALSE;
 
     dwConversion = (pIC->fdwConversion ^ IME_CMODE_FULLSHAPE);
@@ -141,13 +207,14 @@ BOOL APIENTRY Imm32KShapeToggle(HIMC hIMC)
     return TRUE;
 }
 
+/* Win: KHanjaConvert */
 BOOL APIENTRY Imm32KHanjaConvert(HIMC hIMC)
 {
     LPINPUTCONTEXT pIC;
     DWORD dwConversion, dwSentence;
 
     pIC = ImmLockIMC(hIMC);
-    if (!pIC)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
         return FALSE;
 
     dwConversion = (pIC->fdwConversion ^ IME_CMODE_HANJACONVERT);
@@ -158,6 +225,7 @@ BOOL APIENTRY Imm32KHanjaConvert(HIMC hIMC)
     return TRUE;
 }
 
+/* Win: KEnglishHangul */
 BOOL APIENTRY Imm32KEnglish(HIMC hIMC)
 {
     LPINPUTCONTEXT pIC;
@@ -165,7 +233,7 @@ BOOL APIENTRY Imm32KEnglish(HIMC hIMC)
     BOOL fOpen;
 
     pIC = ImmLockIMC(hIMC);
-    if (pIC == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
         return FALSE;
 
     dwConversion = (pIC->fdwConversion ^ IME_CMODE_NATIVE);
@@ -185,13 +253,13 @@ BOOL APIENTRY Imm32ProcessHotKey(HWND hWnd, HIMC hIMC, HKL hKL, DWORD dwHotKeyID
     PIMEDPI pImeDpi;
     BOOL ret;
 
-    if (hIMC && Imm32IsCrossThreadAccess(hIMC))
+    if (hIMC && IS_CROSS_THREAD_HIMC(hIMC))
         return FALSE;
 
     switch (dwHotKeyID)
     {
         case IME_CHOTKEY_IME_NONIME_TOGGLE:
-            return Imm32ImeNonImeToggle(hIMC, hKL, hWnd, LANGID_CHINESE_SIMPLIFIED);
+            return Imm32CImeNonImeToggle(hIMC, hKL, hWnd, LANGID_CHINESE_SIMPLIFIED);
 
         case IME_CHOTKEY_SHAPE_TOGGLE:
             return Imm32CShapeToggle(hIMC, hKL, hWnd);
@@ -212,7 +280,7 @@ BOOL APIENTRY Imm32ProcessHotKey(HWND hWnd, HIMC hIMC, HKL hKL, DWORD dwHotKeyID
             return Imm32KEnglish(hIMC);
 
         case IME_THOTKEY_IME_NONIME_TOGGLE:
-            return Imm32ImeNonImeToggle(hIMC, hKL, hWnd, LANGID_CHINESE_TRADITIONAL);
+            return Imm32CImeNonImeToggle(hIMC, hKL, hWnd, LANGID_CHINESE_TRADITIONAL);
 
         case IME_THOTKEY_SHAPE_TOGGLE:
             return Imm32CShapeToggle(hIMC, hKL, hWnd);
@@ -221,6 +289,7 @@ BOOL APIENTRY Imm32ProcessHotKey(HWND hWnd, HIMC hIMC, HKL hKL, DWORD dwHotKeyID
             return Imm32CSymbolToggle(hIMC, hKL, hWnd);
 
         default:
+            WARN("0x%X\n", dwHotKeyID);
             break;
     }
 
@@ -228,7 +297,7 @@ BOOL APIENTRY Imm32ProcessHotKey(HWND hWnd, HIMC hIMC, HKL hKL, DWORD dwHotKeyID
         return FALSE;
 
     pImeDpi = ImmLockImeDpi(hKL);
-    if (pImeDpi == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pImeDpi))
         return FALSE;
 
     ret = (BOOL)pImeDpi->ImeEscape(hIMC, IME_ESC_PRIVATE_HOTKEY, &dwHotKeyID);
@@ -250,7 +319,7 @@ ImmIsUIMessageAW(HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam, BOOL bAns
             return FALSE;
     }
 
-    if (!hWndIME)
+    if (IS_NULL_UNEXPECTEDLY(hWndIME))
         return TRUE;
 
     if (bAnsi)
@@ -261,80 +330,26 @@ ImmIsUIMessageAW(HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam, BOOL bAns
     return TRUE;
 }
 
-typedef struct IMM_DELAY_SET_LANG_BAND
-{
-    HWND hWnd;
-    BOOL fFlag;
-} IMM_DELAY_SET_LANG_BAND, *PIMM_DELAY_SET_LANG_BAND;
-
-/* Win: DelaySetLangBand */
-static DWORD APIENTRY Imm32DelaySetLangBandProc(LPVOID arg)
-{
-    HWND hwndDefIME;
-    UINT uValue;
-    DWORD_PTR lResult;
-    PIMM_DELAY_SET_LANG_BAND pSetBand = arg;
-
-    Sleep(3000); /* Delay 3 seconds! */
-
-    hwndDefIME = ImmGetDefaultIMEWnd(pSetBand->hWnd);
-    if (hwndDefIME)
-    {
-        uValue = (pSetBand->fFlag ? 0x23 : 0x24);
-        SendMessageTimeoutW(hwndDefIME, WM_IME_SYSTEM, uValue, (LPARAM)pSetBand->hWnd,
-                            SMTO_BLOCK | SMTO_ABORTIFHUNG, 5000, &lResult);
-    }
-    ImmLocalFree(pSetBand);
-    return FALSE;
-}
-
-/* Win: CtfImmSetLangBand */
-LRESULT APIENTRY CtfImmSetLangBand(HWND hWnd, BOOL fFlag)
-{
-    HANDLE hThread;
-    PWND pWnd = NULL;
-    PIMM_DELAY_SET_LANG_BAND pSetBand;
-    DWORD_PTR lResult = 0;
-
-    if (hWnd && gpsi)
-        pWnd = ValidateHwndNoErr(hWnd);
-
-    if (!pWnd)
-        return 0;
-
-    if (pWnd->state2 & WNDS2_WMCREATEMSGPROCESSED)
-    {
-        SendMessageTimeoutW(hWnd, 0x505, 0, fFlag, 3, 5000, &lResult);
-        return lResult;
-    }
-
-    pSetBand = ImmLocalAlloc(0, sizeof(IMM_DELAY_SET_LANG_BAND));
-    if (!pSetBand)
-        return 0;
-
-    pSetBand->hWnd = hWnd;
-    pSetBand->fFlag = fFlag;
-
-    hThread = CreateThread(NULL, 0, Imm32DelaySetLangBandProc, pSetBand, 0, NULL);
-    if (hThread)
-        CloseHandle(hThread);
-    return 0;
-}
-
-/* Win: SendNotificationProc */
-static BOOL CALLBACK Imm32SendNotificationProc(HIMC hIMC, LPARAM lParam)
+static BOOL CALLBACK
+Imm32SendNotificationProc(
+    _In_ HIMC hIMC,
+    _In_ LPARAM lParam)
 {
     HWND hWnd;
     LPINPUTCONTEXTDX pIC;
 
+    UNREFERENCED_PARAMETER(lParam);
+
     pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
-    if (!pIC)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
         return TRUE;
 
     hWnd = pIC->hWnd;
     if (!IsWindow(hWnd))
         goto Quit;
 
+    TRACE("dwChange: 0x%08X\n", pIC->dwChange);
+
     if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_OPEN)
         SendMessageW(hWnd, WM_IME_NOTIFY, IMN_SETOPENSTATUS, 0);
     if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_CONVERSION)
@@ -349,23 +364,16 @@ Quit:
     return TRUE;
 }
 
-/* Win: ImmSendNotification */
 BOOL APIENTRY Imm32SendNotification(BOOL bProcess)
 {
     return ImmEnumInputContext((bProcess ? -1 : 0), Imm32SendNotificationProc, 0);
 }
 
-VOID APIENTRY Imm32RequestError(DWORD dwError)
-{
-    FIXME("()\n");
-    SetLastError(dwError);
-}
-
 LRESULT APIENTRY
 Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bAnsiAPI)
 {
     HWND hWnd;
-    DWORD ret = 0, dwCharPos, cchCompStr;
+    DWORD ret = 0, dwCharPos, cchCompStr, dwSize;
     LPVOID pCS, pTempData = pData;
     LPRECONVERTSTRING pRS;
     LPIMECHARPOSITION pICP;
@@ -385,10 +393,17 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA
     };
 
     if (dwCommand == 0 || dwCommand > IMR_DOCUMENTFEED)
+    {
+        ERR("Out of boundary\n");
         return 0; /* Out of range */
+    }
 
-    if (pData && IsBadWritePtr(pData, acbData[bAnsiAPI * 7 + dwCommand - 1]))
+    dwSize = acbData[bAnsiAPI * 7 + dwCommand - 1];
+    if (pData && IsBadWritePtr(pData, dwSize))
+    {
+        ERR("\n");
         return 0; /* Invalid pointer */
+    }
 
     /* Sanity check */
     switch (dwCommand)
@@ -397,7 +412,7 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA
             pRS = pData;
             if (pRS && (pRS->dwVersion != 0 || pRS->dwSize < sizeof(RECONVERTSTRING)))
             {
-                Imm32RequestError(ERROR_INVALID_PARAMETER);
+                ERR("Invalid pRS\n");
                 return 0;
             }
             break;
@@ -406,17 +421,14 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA
             pRS = pData;
             if (!pRS || pRS->dwVersion != 0)
             {
-                Imm32RequestError(ERROR_INVALID_PARAMETER);
+                ERR("Invalid pRS\n");
                 return 0;
             }
             break;
 
         default:
-            if (!pData)
-            {
-                Imm32RequestError(ERROR_INVALID_PARAMETER);
+            if (IS_NULL_UNEXPECTEDLY(pData))
                 return 0;
-            }
             break;
     }
 
@@ -432,18 +444,20 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA
     {
         case IMR_COMPOSITIONFONT:
             if (bAnsiAPI == bAnsiWnd)
-                goto DoIt;
+                goto DoIt; /* No conversion needed */
+
             if (bAnsiWnd)
                 pTempData = ImmLocalAlloc(0, sizeof(LOGFONTA));
             else
                 pTempData = ImmLocalAlloc(0, sizeof(LOGFONTW));
-            if (!pTempData)
+
+            if (IS_NULL_UNEXPECTEDLY(pTempData))
                 return 0;
             break;
 
         case IMR_RECONVERTSTRING: case IMR_CONFIRMRECONVERTSTRING: case IMR_DOCUMENTFEED:
             if (bAnsiAPI == bAnsiWnd || !pData)
-                goto DoIt;
+                goto DoIt; /* No conversion needed */
 
             if (bAnsiWnd)
                 ret = Imm32ReconvertAnsiFromWide(NULL, pData, uCodePage);
@@ -451,7 +465,7 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA
                 ret = Imm32ReconvertWideFromAnsi(NULL, pData, uCodePage);
 
             pTempData = ImmLocalAlloc(0, ret + sizeof(WCHAR));
-            if (!pTempData)
+            if (IS_NULL_UNEXPECTEDLY(pTempData))
                 return 0;
 
             pRS = pTempData;
@@ -469,7 +483,7 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA
 
         case IMR_QUERYCHARPOSITION:
             if (bAnsiAPI == bAnsiWnd)
-                goto DoIt;
+                goto DoIt; /* No conversion needed */
 
             pICP = pData;
             dwCharPos = pICP->dwCharPos;
@@ -477,11 +491,11 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA
             if (bAnsiAPI)
             {
                 cchCompStr = ImmGetCompositionStringA(hIMC, GCS_COMPSTR, NULL, 0);
-                if (!cchCompStr)
+                if (IS_ZERO_UNEXPECTEDLY(cchCompStr))
                     return 0;
 
                 pCS = ImmLocalAlloc(0, (cchCompStr + 1) * sizeof(CHAR));
-                if (!pCS)
+                if (IS_NULL_UNEXPECTEDLY(pCS))
                     return 0;
 
                 ImmGetCompositionStringA(hIMC, GCS_COMPSTR, pCS, cchCompStr);
@@ -490,11 +504,11 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA
             else
             {
                 cchCompStr = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, NULL, 0);
-                if (!cchCompStr)
+                if (IS_ZERO_UNEXPECTEDLY(cchCompStr))
                     return 0;
 
                 pCS = ImmLocalAlloc(0, (cchCompStr + 1) * sizeof(WCHAR));
-                if (!pCS)
+                if (IS_NULL_UNEXPECTEDLY(pCS))
                     return 0;
 
                 ImmGetCompositionStringW(hIMC, GCS_COMPSTR, pCS, cchCompStr);
@@ -505,6 +519,7 @@ Imm32ProcessRequest(HIMC hIMC, PWND pWnd, DWORD dwCommand, LPVOID pData, BOOL bA
             break;
 
         default:
+            WARN("0x%X\n", dwCommand);
             break;
     }
 
@@ -517,7 +532,7 @@ DoIt:
         ret = SendMessageW(hWnd, WM_IME_REQUEST, dwCommand, (LPARAM)pTempData);
 
     if (bAnsiAPI == bAnsiWnd)
-        goto Quit;
+        goto Quit; /* No conversion needed */
 
     /* Get back to caller */
     switch (dwCommand)
@@ -553,6 +568,7 @@ DoIt:
             break;
 
         default:
+            WARN("0x%X\n", dwCommand);
             break;
     }
 
@@ -570,11 +586,11 @@ LRESULT APIENTRY ImmRequestMessageAW(HIMC hIMC, WPARAM wParam, LPARAM lParam, BO
     HWND hWnd;
     PWND pWnd = NULL;
 
-    if (!hIMC || Imm32IsCrossThreadAccess(hIMC))
+    if (IS_NULL_UNEXPECTEDLY(hIMC) || IS_CROSS_THREAD_HIMC(hIMC))
         return FALSE;
 
     pIC = ImmLockIMC(hIMC);
-    if (!pIC)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
         return FALSE;
 
     hWnd = pIC->hWnd;
@@ -662,7 +678,7 @@ UINT WINAPI ImmGetVirtualKey(HWND hWnd)
 
     hIMC = ImmGetContext(hWnd);
     pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
-    if (!pIC)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
         return ret;
 
     if (pIC->bNeedsTrans)
@@ -672,6 +688,25 @@ UINT WINAPI ImmGetVirtualKey(HWND hWnd)
     return ret;
 }
 
+/***********************************************************************
+ *             ImmGetAppCompatFlags (IMM32.@)
+ */
+DWORD WINAPI ImmGetAppCompatFlags(HIMC hIMC)
+{
+    PCLIENTIMC pClientIMC;
+    DWORD dwFlags;
+
+    TRACE("(%p)\n", hIMC);
+
+    pClientIMC = ImmLockClientImc(hIMC);
+    if (IS_NULL_UNEXPECTEDLY(pClientIMC))
+        return 0;
+
+    dwFlags = pClientIMC->dwCompatFlags;
+    ImmUnlockClientImc(pClientIMC);
+    return (dwFlags | g_aimm_compat_flags);
+}
+
 /***********************************************************************
  *             ImmProcessKey(IMM32.@)
  *       ( Undocumented, called from user32.dll )
@@ -684,11 +719,11 @@ ImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, DWORD dwHotKeyID)
     PIMEDPI pImeDpi;
     LPINPUTCONTEXTDX pIC;
     BYTE KeyState[256];
-    UINT vk;
-    BOOL bUseIme = TRUE, bSkipThisKey = FALSE, bLowWordOnly = FALSE;
+    BOOL bLowWordOnly = FALSE, bSkipThisKey = FALSE, bHotKeyDone = TRUE;
 
     TRACE("(%p, %p, 0x%X, %p, 0x%lX)\n", hWnd, hKL, vKey, lParam, dwHotKeyID);
 
+    /* Process the key by the IME */
     hIMC = ImmGetContext(hWnd);
     pImeDpi = ImmLockImeDpi(hKL);
     if (pImeDpi)
@@ -696,7 +731,7 @@ ImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, DWORD dwHotKeyID)
         pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
         if (pIC)
         {
-            if (LOBYTE(vKey) == VK_PACKET &&
+            if ((LOBYTE(vKey) == VK_PACKET) &&
                 !(pImeDpi->ImeInfo.fdwProperty & IME_PROP_ACCEPT_WIDE_VKEY))
             {
                 if (ImeDpi_IsUnicode(pImeDpi))
@@ -705,29 +740,23 @@ ImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, DWORD dwHotKeyID)
                 }
                 else
                 {
-                    bUseIme = FALSE;
                     if (pIC->fOpen)
-                        bSkipThisKey = TRUE;
+                        ret |= IPHK_SKIPTHISKEY;
+
+                    bSkipThisKey = TRUE;
                 }
             }
 
-            if (bUseIme)
+            if (!bSkipThisKey && GetKeyboardState(KeyState))
             {
-                if (GetKeyboardState(KeyState))
+                UINT vk = (bLowWordOnly ? LOWORD(vKey) : vKey);
+                if (pImeDpi->ImeProcessKey(hIMC, vk, lParam, KeyState))
                 {
-                    vk = (bLowWordOnly ? LOWORD(vKey) : vKey);
-                    if (pImeDpi->ImeProcessKey(hIMC, vk, lParam, KeyState))
-                    {
-                        pIC->bNeedsTrans = TRUE;
-                        pIC->nVKey = vKey;
-                        ret |= IPHK_PROCESSBYIME;
-                    }
+                    pIC->bNeedsTrans = TRUE;
+                    pIC->nVKey = vKey;
+                    ret |= IPHK_PROCESSBYIME;
                 }
             }
-            else if (bSkipThisKey)
-            {
-                ret |= IPHK_SKIPTHISKEY;
-            }
 
             ImmUnlockIMC(hIMC);
         }
@@ -735,22 +764,47 @@ ImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, DWORD dwHotKeyID)
         ImmUnlockImeDpi(pImeDpi);
     }
 
-    if (dwHotKeyID != INVALID_HOTKEY_ID)
+    /* Process the hot-key if necessary */
+    if (!CtfImmIsCiceroStartedInThread()) /* Not Cicero? */
+    {
+        /* Process IMM IME hotkey */
+        if ((dwHotKeyID == INVALID_HOTKEY_ID) || !Imm32ProcessHotKey(hWnd, hIMC, hKL, dwHotKeyID))
+            bHotKeyDone = FALSE;
+    }
+    else if (!CtfImeProcessCicHotkey(hIMC, vKey, lParam)) /* CTF IME not processed the hotkey? */
     {
-        if (Imm32ProcessHotKey(hWnd, hIMC, hKL, dwHotKeyID))
+        /* Process IMM IME hotkey */
+        if (!IS_IME_HKL(hKL) ||
+            ((dwHotKeyID == INVALID_HOTKEY_ID) || !Imm32ProcessHotKey(hWnd, hIMC, hKL, dwHotKeyID)))
         {
-            if (vKey != VK_KANJI || dwHotKeyID != IME_JHOTKEY_CLOSE_OPEN)
-                ret |= IPHK_HOTKEY;
+            bHotKeyDone = FALSE;
         }
     }
 
-    if (ret & IPHK_PROCESSBYIME)
+    if (bHotKeyDone && ((vKey != VK_KANJI) || (dwHotKeyID != IME_JHOTKEY_CLOSE_OPEN)))
+        ret |= IPHK_HOTKEY;
+
+    if ((ret & IPHK_PROCESSBYIME) && (ImmGetAppCompatFlags(hIMC) & 0x10000))
     {
-        FIXME("TODO: We have to do something here.\n");
+        /* The key has been processed by IME's ImeProcessKey */
+        LANGID wLangID = LANGIDFROMLCID(GetSystemDefaultLCID());
+        if ((PRIMARYLANGID(wLangID) == LANG_KOREAN) &&
+            ((vKey == VK_PROCESSKEY) || (ret & IPHK_HOTKEY)))
+        {
+            /* Korean don't want VK_PROCESSKEY and IME hot-keys */
+        }
+        else
+        {
+            /* Add WM_KEYDOWN:VK_PROCESSKEY message */
+            ImmTranslateMessage(hWnd, WM_KEYDOWN, VK_PROCESSKEY, lParam);
+
+            ret &= ~IPHK_PROCESSBYIME;
+            ret |= IPHK_SKIPTHISKEY;
+        }
     }
 
     ImmReleaseContext(hWnd, hIMC);
-    return ret;
+    return ret; /* Returns IPHK_... flags */
 }
 
 /***********************************************************************
@@ -762,18 +816,20 @@ LRESULT WINAPI ImmSystemHandler(HIMC hIMC, WPARAM wParam, LPARAM lParam)
 
     switch (wParam)
     {
-        case 0x1f:
+        case IMS_SENDNOTIFICATION:
             Imm32SendNotification((BOOL)lParam);
             return 0;
 
-        case 0x20:
+        case IMS_COMPLETECOMPSTR:
             ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
             return 0;
 
-        case 0x23: case 0x24:
-            return CtfImmSetLangBand((HWND)lParam, (wParam == 0x23));
+        case IMS_SETLANGBAND:
+        case IMS_UNSETLANGBAND:
+            return CtfImmSetLangBand((HWND)lParam, (wParam == IMS_SETLANGBAND));
 
         default:
+            WARN("%p\n", wParam);
             return 0;
     }
 }
@@ -793,18 +849,18 @@ BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
 
     TRACE("(%p)\n", hIMC);
 
-    if (Imm32IsCrossThreadAccess(hIMC))
+    if (IS_CROSS_THREAD_HIMC(hIMC))
         return FALSE;
 
     pClientImc = ImmLockClientImc(hIMC);
-    if (pClientImc == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pClientImc))
         return FALSE;
 
     bAnsi = !(pClientImc->dwFlags & CLIENTIMC_WIDE);
     ImmUnlockClientImc(pClientImc);
 
     pIC = ImmLockIMC(hIMC);
-    if (pIC == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
         return FALSE;
 
     dwCount = pIC->dwNumMsgBuf;
@@ -813,12 +869,12 @@ BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
 
     hMsgBuf = pIC->hMsgBuf;
     pMsgs = ImmLockIMCC(hMsgBuf);
-    if (pMsgs == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pMsgs))
         goto Quit;
 
     cbTrans = dwCount * sizeof(TRANSMSG);
     pTrans = ImmLocalAlloc(0, cbTrans);
-    if (pTrans == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pTrans))
         goto Quit;
 
     RtlCopyMemory(pTrans, pMsgs, cbTrans);
@@ -833,7 +889,7 @@ BOOL WINAPI ImmGenerateMessage(HIMC hIMC)
         if (wLang == LANG_JAPANESE ||
             (wLang == LANG_KOREAN && NtUserGetAppImeLevel(pIC->hWnd) == 3))
         {
-            dwCount = ImmNt3Trans(dwCount, pTrans, hIMC, bAnsi, wLang);
+            dwCount = WINNLSTranslateMessage(dwCount, pTrans, hIMC, bAnsi, wLang);
         }
     }
 #endif
@@ -859,7 +915,7 @@ Quit:
 }
 
 VOID APIENTRY
-Imm32PostMessages(HWND hwnd, HIMC hIMC, DWORD dwCount, LPTRANSMSG lpTransMsg)
+ImmPostMessages(HWND hwnd, HIMC hIMC, DWORD dwCount, LPTRANSMSG lpTransMsg)
 {
     DWORD dwIndex;
     PCLIENTIMC pClientImc;
@@ -867,7 +923,7 @@ Imm32PostMessages(HWND hwnd, HIMC hIMC, DWORD dwCount, LPTRANSMSG lpTransMsg)
     BOOL bAnsi;
 
     pClientImc = ImmLockClientImc(hIMC);
-    if (pClientImc == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pClientImc))
         return;
 
     bAnsi = !(pClientImc->dwFlags & CLIENTIMC_WIDE);
@@ -888,7 +944,7 @@ Imm32PostMessages(HWND hwnd, HIMC hIMC, DWORD dwCount, LPTRANSMSG lpTransMsg)
             if (pNewTransMsg)
             {
                 RtlCopyMemory(pNewTransMsg, lpTransMsg, cbTransMsg);
-                dwCount = ImmNt3Trans(dwCount, pNewTransMsg, hIMC, bAnsi, Lang);
+                dwCount = WINNLSTranslateMessage(dwCount, pNewTransMsg, hIMC, bAnsi, Lang);
             }
             else
             {
@@ -948,7 +1004,7 @@ BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyD
 
     hIMC = ImmGetContext(hwnd);
     pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
-    if (pIC == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pIC))
     {
         ImmReleaseContext(hwnd, hIMC);
         return FALSE;
@@ -964,7 +1020,7 @@ BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyD
         pTransMsg = ImmLockIMCC(pIC->hMsgBuf);
         if (pTransMsg)
         {
-            Imm32PostMessages(hwnd, hIMC, dwCount, pTransMsg);
+            ImmPostMessages(hwnd, hIMC, dwCount, pTransMsg);
             ImmUnlockIMCC(pIC->hMsgBuf);
             ret = TRUE;
         }
@@ -976,11 +1032,14 @@ BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyD
     dwThreadId = GetWindowThreadProcessId(hwnd, NULL);
     hKL = GetKeyboardLayout(dwThreadId);
     pImeDpi = ImmLockImeDpi(hKL);
-    if (pImeDpi == NULL)
+    if (IS_NULL_UNEXPECTEDLY(pImeDpi))
         goto Quit;
 
     if (!GetKeyboardState(abKeyState)) /* get keyboard ON/OFF status */
+    {
+        WARN("\n");
         goto Quit;
+    }
 
     /* convert a virtual key if IME_PROP_KBD_CHAR_FIRST */
     vk = pIC->nVKey;
@@ -998,14 +1057,24 @@ BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyD
             wChar = 0;
             kret = ToAsciiEx(vk, HIWORD(lKeyData), abKeyState, &wChar, 0, hKL);
             if (kret > 0)
-                vk = MAKEWORD(vk, wChar);
+            {
+                if ((BYTE)vk == VK_PACKET)
+                {
+                    vk &= 0xFF;
+                    vk |= (wChar << 8);
+                }
+                else
+                {
+                    vk = MAKEWORD(vk, wChar);
+                }
+            }
         }
     }
 
     /* allocate a list */
     cbList = offsetof(TRANSMSGLIST, TransMsg) + MSG_COUNT * sizeof(TRANSMSG);
     pList = ImmLocalAlloc(0, cbList);
-    if (!pList)
+    if (IS_NULL_UNEXPECTEDLY(pList))
         goto Quit;
 
     /* use IME conversion engine and convert the list */
@@ -1017,15 +1086,15 @@ BOOL WINAPI ImmTranslateMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lKeyD
     /* post them */
     if (kret <= MSG_COUNT)
     {
-        Imm32PostMessages(hwnd, hIMC, kret, pList->TransMsg);
+        ImmPostMessages(hwnd, hIMC, kret, pList->TransMsg);
         ret = TRUE;
     }
     else
     {
         pTransMsg = ImmLockIMCC(pIC->hMsgBuf);
-        if (pTransMsg == NULL)
+        if (IS_NULL_UNEXPECTEDLY(pTransMsg))
             goto Quit;
-        Imm32PostMessages(hwnd, hIMC, kret, pTransMsg);
+        ImmPostMessages(hwnd, hIMC, kret, pTransMsg);
         ImmUnlockIMCC(pIC->hMsgBuf);
     }
 
@@ -1034,6 +1103,7 @@ Quit:
     ImmUnlockImeDpi(pImeDpi);
     ImmUnlockIMC(hIMC);
     ImmReleaseContext(hwnd, hIMC);
+    TRACE("ret: %d\n", ret);
     return ret;
 #undef MSG_COUNT
 }
@@ -1057,19 +1127,92 @@ LRESULT WINAPI ImmRequestMessageW(HIMC hIMC, WPARAM wParam, LPARAM lParam)
 }
 
 /***********************************************************************
- *              ImmSendMessageToActiveDefImeWndW (IMM32.@)
+ *              ImmCallImeConsoleIME (IMM32.@)
  */
-LRESULT WINAPI
-ImmSendMessageToActiveDefImeWndW(UINT uMsg, WPARAM wParam, LPARAM lParam)
+DWORD WINAPI
+ImmCallImeConsoleIME(
+    _In_ HWND hWnd,
+    _In_ UINT uMsg,
+    _In_ WPARAM wParam,
+    _In_ LPARAM lParam,
+    _Out_ LPUINT puVK)
 {
-    HWND hwndIME;
+    DWORD dwThreadId, ret = 0;
+    HKL hKL;
+    PWND pWnd = NULL;
+    HIMC hIMC;
+    PIMEDPI pImeDpi;
+    UINT uVK;
+    PIMC pIMC;
+
+    switch (uMsg)
+    {
+        case WM_KEYDOWN:
+        case WM_KEYUP:
+        case WM_SYSKEYDOWN:
+        case WM_SYSKEYUP:
+            break;
+
+        default:
+            return 0;
+    }
+
+    dwThreadId = GetWindowThreadProcessId(hWnd, NULL);
+    hKL = GetKeyboardLayout(dwThreadId);
+
+    if (hWnd && gpsi)
+        pWnd = ValidateHwndNoErr(hWnd);
+    if (IS_NULL_UNEXPECTEDLY(pWnd))
+        return 0;
 
-    if (uMsg != WM_COPYDATA)
+    hIMC = ImmGetContext(hWnd);
+    if (IS_NULL_UNEXPECTEDLY(hIMC))
         return 0;
 
-    hwndIME = (HWND)NtUserQueryWindow((HWND)wParam, QUERY_WINDOW_DEFAULT_IME);
-    if (!hwndIME)
+    uVK = *puVK = (wParam & 0xFF);
+
+    pIMC = ValidateHandleNoErr(hIMC, TYPE_INPUTCONTEXT);
+    if (IS_NULL_UNEXPECTEDLY(pIMC))
+        return 0;
+
+    pImeDpi = ImmLockImeDpi(hKL);
+    if (IS_NULL_UNEXPECTEDLY(pImeDpi))
         return 0;
 
-    return SendMessageW(hwndIME, uMsg, wParam, lParam);
+    if ((lParam & MAKELPARAM(0, KF_UP)) && (pImeDpi->ImeInfo.fdwProperty & IME_PROP_IGNORE_UPKEYS))
+        goto Quit;
+
+    switch (uVK)
+    {
+        case VK_DBE_ROMAN:
+        case VK_DBE_NOROMAN:
+        case VK_DBE_HIRAGANA:
+        case VK_DBE_KATAKANA:
+        case VK_DBE_CODEINPUT:
+        case VK_DBE_NOCODEINPUT:
+        case VK_DBE_ENTERWORDREGISTERMODE:
+        case VK_DBE_ENTERCONFIGMODE:
+            break;
+
+        default:
+        {
+            if (uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP)
+            {
+                if (uVK != VK_MENU && uVK != VK_F10)
+                    goto Quit;
+            }
+
+            if (!(pImeDpi->ImeInfo.fdwProperty & IME_PROP_NEED_ALTKEY))
+            {
+                if (uVK == VK_MENU || (lParam & MAKELPARAM(0, KF_ALTDOWN)))
+                    goto Quit;
+            }
+        }
+    }
+
+    ret = ImmProcessKey(hWnd, hKL, uVK, lParam, INVALID_HOTKEY_ID);
+
+Quit:
+    ImmUnlockImeDpi(pImeDpi);
+    return ret;
 }