2005-12-12 20:59:55 +00:00
|
|
|
/*
|
2021-08-17 23:42:12 +00:00
|
|
|
* PROJECT: ReactOS IMM32
|
|
|
|
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
|
|
|
* PURPOSE: Implementing Far-Eastern languages input
|
|
|
|
* COPYRIGHT: Copyright 1998 Patrik Stridvall
|
|
|
|
* Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart
|
|
|
|
* Copyright 2017 James Tabor <james.tabor@reactos.org>
|
|
|
|
* Copyright 2018 Amine Khaldi <amine.khaldi@reactos.org>
|
2022-04-06 06:44:27 +00:00
|
|
|
* Copyright 2020-2022 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
2005-12-12 20:59:55 +00:00
|
|
|
*/
|
|
|
|
|
2021-09-10 14:39:15 +00:00
|
|
|
#include "precomp.h"
|
2022-11-13 11:04:34 +00:00
|
|
|
#include <ndk/exfuncs.h>
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(imm);
|
|
|
|
|
2023-12-02 22:46:35 +00:00
|
|
|
HMODULE ghImm32Inst = NULL; /* The IMM32 instance */
|
|
|
|
PSERVERINFO gpsi = NULL;
|
|
|
|
SHAREDINFO gSharedInfo = { NULL };
|
|
|
|
BYTE gfImmInitialized = FALSE; /* Is IMM32 initialized? */
|
2022-11-13 11:04:34 +00:00
|
|
|
ULONG_PTR gHighestUserAddress = 0;
|
2021-08-23 21:50:39 +00:00
|
|
|
|
2022-04-06 06:44:27 +00:00
|
|
|
static BOOL APIENTRY ImmInitializeGlobals(HMODULE hMod)
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
|
|
|
NTSTATUS status;
|
2022-11-13 11:04:34 +00:00
|
|
|
SYSTEM_BASIC_INFORMATION SysInfo;
|
2021-08-04 00:41:59 +00:00
|
|
|
|
|
|
|
if (hMod)
|
2022-04-09 01:41:39 +00:00
|
|
|
ghImm32Inst = hMod;
|
2021-08-04 00:41:59 +00:00
|
|
|
|
2022-04-09 01:41:39 +00:00
|
|
|
if (gfImmInitialized)
|
2021-08-04 00:41:59 +00:00
|
|
|
return TRUE;
|
|
|
|
|
2022-04-08 09:21:54 +00:00
|
|
|
status = RtlInitializeCriticalSection(&gcsImeDpi);
|
2021-08-04 00:41:59 +00:00
|
|
|
if (NT_ERROR(status))
|
2022-10-23 00:51:24 +00:00
|
|
|
{
|
|
|
|
ERR("\n");
|
2021-08-04 00:41:59 +00:00
|
|
|
return FALSE;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2021-08-04 00:41:59 +00:00
|
|
|
|
2022-11-13 11:04:34 +00:00
|
|
|
status = NtQuerySystemInformation(SystemBasicInformation, &SysInfo, sizeof(SysInfo), NULL);
|
|
|
|
if (NT_ERROR(status))
|
|
|
|
{
|
|
|
|
ERR("\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
gHighestUserAddress = SysInfo.MaximumUserModeAddress;
|
|
|
|
|
2022-04-09 01:41:39 +00:00
|
|
|
gfImmInitialized = TRUE;
|
2021-08-04 00:41:59 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2021-08-14 01:38:06 +00:00
|
|
|
/***********************************************************************
|
2021-09-10 14:39:15 +00:00
|
|
|
* ImmRegisterClient(IMM32.@)
|
|
|
|
* ( Undocumented, called from user32.dll )
|
2021-08-14 01:38:06 +00:00
|
|
|
*/
|
2021-09-10 14:39:15 +00:00
|
|
|
BOOL WINAPI ImmRegisterClient(PSHAREDINFO ptr, HINSTANCE hMod)
|
2021-08-09 23:08:23 +00:00
|
|
|
{
|
2022-03-31 01:00:06 +00:00
|
|
|
gSharedInfo = *ptr;
|
|
|
|
gpsi = gSharedInfo.psi;
|
2022-04-06 06:44:27 +00:00
|
|
|
return ImmInitializeGlobals(hMod);
|
2021-08-09 23:08:23 +00:00
|
|
|
}
|
|
|
|
|
2021-08-14 01:38:06 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmLoadLayout (IMM32.@)
|
|
|
|
*/
|
2021-10-21 01:28:04 +00:00
|
|
|
BOOL WINAPI ImmLoadLayout(HKL hKL, PIMEINFOEX pImeInfoEx)
|
2021-07-28 14:25:10 +00:00
|
|
|
{
|
2022-09-04 23:34:00 +00:00
|
|
|
DWORD cbData, dwType;
|
2023-12-09 00:49:57 +00:00
|
|
|
HKEY hKey;
|
|
|
|
LSTATUS error;
|
2021-07-28 14:25:10 +00:00
|
|
|
WCHAR szLayout[MAX_PATH];
|
2023-12-09 00:49:57 +00:00
|
|
|
LPCWSTR pszSubKey;
|
2021-07-28 14:25:10 +00:00
|
|
|
|
2021-08-04 00:49:41 +00:00
|
|
|
TRACE("(%p, %p)\n", hKL, pImeInfoEx);
|
2021-07-28 14:25:10 +00:00
|
|
|
|
2023-12-09 00:49:57 +00:00
|
|
|
/* Choose a key */
|
|
|
|
if (IS_IME_HKL(hKL) || !IS_CICERO_MODE() || IS_16BIT_MODE()) /* Non-Cicero? */
|
2021-07-28 14:25:10 +00:00
|
|
|
{
|
2022-09-04 23:34:00 +00:00
|
|
|
StringCchPrintfW(szLayout, _countof(szLayout), L"%s\\%08lX",
|
|
|
|
REGKEY_KEYBOARD_LAYOUTS, HandleToUlong(hKL));
|
2023-12-09 00:49:57 +00:00
|
|
|
pszSubKey = szLayout;
|
2021-07-28 14:25:10 +00:00
|
|
|
}
|
2023-12-09 00:49:57 +00:00
|
|
|
else /* Cicero */
|
2021-07-28 14:25:10 +00:00
|
|
|
{
|
2023-12-09 00:49:57 +00:00
|
|
|
pszSubKey = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\IMM";
|
2021-07-28 14:25:10 +00:00
|
|
|
}
|
|
|
|
|
2023-12-09 00:49:57 +00:00
|
|
|
/* Open the key */
|
|
|
|
error = RegOpenKeyExW(HKEY_LOCAL_MACHINE, pszSubKey, 0, KEY_READ, &hKey);
|
|
|
|
if (IS_ERROR_UNEXPECTEDLY(error))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Load "IME File" value */
|
2021-10-21 01:28:04 +00:00
|
|
|
cbData = sizeof(pImeInfoEx->wszImeFile);
|
2023-12-09 00:49:57 +00:00
|
|
|
error = RegQueryValueExW(hKey, L"IME File", NULL, &dwType,
|
2021-10-21 01:28:04 +00:00
|
|
|
(LPBYTE)pImeInfoEx->wszImeFile, &cbData);
|
|
|
|
|
2023-12-09 00:49:57 +00:00
|
|
|
/* Avoid buffer overrun */
|
|
|
|
pImeInfoEx->wszImeFile[_countof(pImeInfoEx->wszImeFile) - 1] = UNICODE_NULL;
|
2021-10-21 01:28:04 +00:00
|
|
|
|
2023-12-09 00:49:57 +00:00
|
|
|
RegCloseKey(hKey);
|
2022-10-26 03:01:33 +00:00
|
|
|
|
2023-12-09 00:49:57 +00:00
|
|
|
if (error != ERROR_SUCCESS || dwType != REG_SZ)
|
|
|
|
return FALSE; /* Failed */
|
2021-10-21 01:28:04 +00:00
|
|
|
|
|
|
|
pImeInfoEx->hkl = hKL;
|
2023-12-09 00:49:57 +00:00
|
|
|
pImeInfoEx->fLoadFlag = 0;
|
2021-10-21 01:28:04 +00:00
|
|
|
return Imm32LoadImeVerInfo(pImeInfoEx);
|
2021-07-28 14:25:10 +00:00
|
|
|
}
|
|
|
|
|
2021-09-30 18:10:26 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmFreeLayout (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmFreeLayout(DWORD dwUnknown)
|
|
|
|
{
|
2022-09-04 23:34:00 +00:00
|
|
|
WCHAR szKBD[KL_NAMELENGTH];
|
2021-09-30 18:10:26 +00:00
|
|
|
UINT iKL, cKLs;
|
|
|
|
HKL hOldKL, hNewKL, *pList;
|
|
|
|
PIMEDPI pImeDpi;
|
|
|
|
LANGID LangID;
|
|
|
|
|
|
|
|
TRACE("(0x%lX)\n", dwUnknown);
|
|
|
|
|
|
|
|
hOldKL = GetKeyboardLayout(0);
|
|
|
|
|
|
|
|
if (dwUnknown == 1)
|
|
|
|
{
|
|
|
|
if (!IS_IME_HKL(hOldKL))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
LangID = LANGIDFROMLCID(GetSystemDefaultLCID());
|
|
|
|
|
|
|
|
cKLs = GetKeyboardLayoutList(0, NULL);
|
|
|
|
if (cKLs)
|
|
|
|
{
|
2022-03-29 09:02:25 +00:00
|
|
|
pList = ImmLocalAlloc(0, cKLs * sizeof(HKL));
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pList))
|
2021-09-30 18:10:26 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
cKLs = GetKeyboardLayoutList(cKLs, pList);
|
|
|
|
for (iKL = 0; iKL < cKLs; ++iKL)
|
|
|
|
{
|
|
|
|
if (!IS_IME_HKL(pList[iKL]))
|
|
|
|
{
|
|
|
|
LangID = LOWORD(pList[iKL]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-29 09:02:25 +00:00
|
|
|
ImmLocalFree(pList);
|
2021-09-30 18:10:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
StringCchPrintfW(szKBD, _countof(szKBD), L"%08X", LangID);
|
|
|
|
if (!LoadKeyboardLayoutW(szKBD, KLF_ACTIVATE))
|
2022-10-23 00:51:24 +00:00
|
|
|
{
|
2022-10-26 03:01:33 +00:00
|
|
|
WARN("Default to English US\n");
|
2021-09-30 18:10:26 +00:00
|
|
|
LoadKeyboardLayoutW(L"00000409", KLF_ACTIVATE | 0x200);
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2021-09-30 18:10:26 +00:00
|
|
|
}
|
|
|
|
else if (dwUnknown == 2)
|
|
|
|
{
|
2022-04-08 09:21:54 +00:00
|
|
|
RtlEnterCriticalSection(&gcsImeDpi);
|
2021-09-30 18:10:26 +00:00
|
|
|
Retry:
|
2022-04-08 10:02:08 +00:00
|
|
|
for (pImeDpi = gpImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext)
|
2021-09-30 18:10:26 +00:00
|
|
|
{
|
|
|
|
if (Imm32ReleaseIME(pImeDpi->hKL))
|
|
|
|
goto Retry;
|
|
|
|
}
|
2022-04-08 09:21:54 +00:00
|
|
|
RtlLeaveCriticalSection(&gcsImeDpi);
|
2021-09-30 18:10:26 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hNewKL = (HKL)(DWORD_PTR)dwUnknown;
|
|
|
|
if (IS_IME_HKL(hNewKL) && hNewKL != hOldKL)
|
|
|
|
Imm32ReleaseIME(hNewKL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2022-04-09 01:41:39 +00:00
|
|
|
VOID APIENTRY Imm32SelectInputContext(HKL hNewKL, HKL hOldKL, HIMC hIMC)
|
2021-10-03 22:33:15 +00:00
|
|
|
{
|
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
LPINPUTCONTEXTDX pIC;
|
|
|
|
LPGUIDELINE pGL;
|
|
|
|
LPCANDIDATEINFO pCI;
|
|
|
|
LPCOMPOSITIONSTRING pCS;
|
|
|
|
LOGFONTA LogFontA;
|
|
|
|
LOGFONTW LogFontW;
|
2022-10-21 02:22:00 +00:00
|
|
|
BOOL fOldOpen, bIsNewHKLIme = TRUE, bIsOldHKLIme = TRUE, bClientWide, bNewDpiWide;
|
|
|
|
DWORD cbNewPrivate = 0, cbOldPrivate = 0, dwOldConversion, dwOldSentence, dwSize, dwNewSize;
|
2021-10-03 22:33:15 +00:00
|
|
|
PIMEDPI pNewImeDpi = NULL, pOldImeDpi = NULL;
|
|
|
|
HANDLE hPrivate;
|
|
|
|
PIME_STATE pNewState = NULL, pOldState = NULL;
|
|
|
|
|
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pClientImc))
|
2021-10-03 22:33:15 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
pNewImeDpi = ImmLockImeDpi(hNewKL);
|
|
|
|
|
|
|
|
if (hNewKL != hOldKL)
|
|
|
|
pOldImeDpi = ImmLockImeDpi(hOldKL);
|
|
|
|
|
|
|
|
if (pNewImeDpi)
|
|
|
|
{
|
|
|
|
cbNewPrivate = pNewImeDpi->ImeInfo.dwPrivateDataSize;
|
|
|
|
pClientImc->uCodePage = pNewImeDpi->uCodePage;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pClientImc->uCodePage = CP_ACP;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pOldImeDpi)
|
|
|
|
cbOldPrivate = pOldImeDpi->ImeInfo.dwPrivateDataSize;
|
|
|
|
|
2022-10-21 02:22:00 +00:00
|
|
|
cbNewPrivate = max(cbNewPrivate, sizeof(DWORD));
|
|
|
|
cbOldPrivate = max(cbOldPrivate, sizeof(DWORD));
|
2021-10-03 22:33:15 +00:00
|
|
|
|
|
|
|
if (pClientImc->hKL == hOldKL)
|
|
|
|
{
|
|
|
|
if (pOldImeDpi)
|
|
|
|
{
|
|
|
|
if (IS_IME_HKL(hOldKL))
|
|
|
|
pOldImeDpi->ImeSelect(hIMC, FALSE);
|
2022-09-08 00:57:17 +00:00
|
|
|
else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
|
2021-10-03 22:33:15 +00:00
|
|
|
pOldImeDpi->CtfImeSelectEx(hIMC, FALSE, hOldKL);
|
|
|
|
}
|
|
|
|
pClientImc->hKL = NULL;
|
|
|
|
}
|
|
|
|
|
2022-10-21 02:22:00 +00:00
|
|
|
if (CtfImmIsTextFrameServiceDisabled() && IS_CICERO_MODE() && !IS_16BIT_MODE())
|
2021-10-03 22:33:15 +00:00
|
|
|
{
|
2022-10-21 02:22:00 +00:00
|
|
|
bIsNewHKLIme = IS_IME_HKL(hNewKL);
|
|
|
|
bIsOldHKLIme = IS_IME_HKL(hOldKL);
|
2021-10-03 22:33:15 +00:00
|
|
|
}
|
|
|
|
|
2022-04-08 13:23:30 +00:00
|
|
|
pIC = (LPINPUTCONTEXTDX)Imm32InternalLockIMC(hIMC, FALSE);
|
2021-10-03 22:33:15 +00:00
|
|
|
if (!pIC)
|
|
|
|
{
|
|
|
|
if (pNewImeDpi)
|
|
|
|
{
|
|
|
|
if (IS_IME_HKL(hNewKL))
|
|
|
|
pNewImeDpi->ImeSelect(hIMC, TRUE);
|
2022-09-08 00:57:17 +00:00
|
|
|
else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
|
2021-10-03 22:33:15 +00:00
|
|
|
pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
|
|
|
|
|
|
|
|
pClientImc->hKL = hNewKL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-10-21 02:22:00 +00:00
|
|
|
dwOldConversion = pIC->fdwConversion;
|
|
|
|
dwOldSentence = pIC->fdwSentence;
|
|
|
|
fOldOpen = pIC->fOpen;
|
2021-10-03 22:33:15 +00:00
|
|
|
|
|
|
|
if (pNewImeDpi)
|
|
|
|
{
|
|
|
|
bClientWide = (pClientImc->dwFlags & CLIENTIMC_WIDE);
|
|
|
|
bNewDpiWide = ImeDpi_IsUnicode(pNewImeDpi);
|
|
|
|
if (bClientWide && !bNewDpiWide)
|
|
|
|
{
|
|
|
|
if (pIC->fdwInit & INIT_LOGFONT)
|
|
|
|
{
|
|
|
|
LogFontWideToAnsi(&pIC->lfFont.W, &LogFontA);
|
|
|
|
pIC->lfFont.A = LogFontA;
|
|
|
|
}
|
|
|
|
pClientImc->dwFlags &= ~CLIENTIMC_WIDE;
|
|
|
|
}
|
|
|
|
else if (!bClientWide && bNewDpiWide)
|
|
|
|
{
|
|
|
|
if (pIC->fdwInit & INIT_LOGFONT)
|
|
|
|
{
|
|
|
|
LogFontAnsiToWide(&pIC->lfFont.A, &LogFontW);
|
|
|
|
pIC->lfFont.W = LogFontW;
|
|
|
|
}
|
|
|
|
pClientImc->dwFlags |= CLIENTIMC_WIDE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cbOldPrivate != cbNewPrivate)
|
|
|
|
{
|
|
|
|
hPrivate = ImmReSizeIMCC(pIC->hPrivate, cbNewPrivate);
|
|
|
|
if (!hPrivate)
|
|
|
|
{
|
|
|
|
ImmDestroyIMCC(pIC->hPrivate);
|
|
|
|
hPrivate = ImmCreateIMCC(cbNewPrivate);
|
|
|
|
}
|
|
|
|
pIC->hPrivate = hPrivate;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MAX_IMCC_SIZE 0x1000
|
|
|
|
dwSize = ImmGetIMCCSize(pIC->hMsgBuf);
|
|
|
|
if (ImmGetIMCCLockCount(pIC->hMsgBuf) || dwSize > MAX_IMCC_SIZE)
|
|
|
|
{
|
|
|
|
ImmDestroyIMCC(pIC->hMsgBuf);
|
|
|
|
pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
|
|
|
|
pIC->dwNumMsgBuf = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
dwSize = ImmGetIMCCSize(pIC->hGuideLine);
|
|
|
|
dwNewSize = sizeof(GUIDELINE);
|
|
|
|
if (ImmGetIMCCLockCount(pIC->hGuideLine) ||
|
|
|
|
dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
|
|
|
|
{
|
|
|
|
ImmDestroyIMCC(pIC->hGuideLine);
|
|
|
|
pIC->hGuideLine = ImmCreateIMCC(dwNewSize);
|
|
|
|
pGL = ImmLockIMCC(pIC->hGuideLine);
|
|
|
|
if (pGL)
|
|
|
|
{
|
|
|
|
pGL->dwSize = dwNewSize;
|
|
|
|
ImmUnlockIMCC(pIC->hGuideLine);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dwSize = ImmGetIMCCSize(pIC->hCandInfo);
|
|
|
|
dwNewSize = sizeof(CANDIDATEINFO);
|
|
|
|
if (ImmGetIMCCLockCount(pIC->hCandInfo) ||
|
|
|
|
dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
|
|
|
|
{
|
|
|
|
ImmDestroyIMCC(pIC->hCandInfo);
|
|
|
|
pIC->hCandInfo = ImmCreateIMCC(dwNewSize);
|
|
|
|
pCI = ImmLockIMCC(pIC->hCandInfo);
|
|
|
|
if (pCI)
|
|
|
|
{
|
|
|
|
pCI->dwSize = dwNewSize;
|
|
|
|
ImmUnlockIMCC(pIC->hCandInfo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dwSize = ImmGetIMCCSize(pIC->hCompStr);
|
|
|
|
dwNewSize = sizeof(COMPOSITIONSTRING);
|
|
|
|
if (ImmGetIMCCLockCount(pIC->hCompStr) ||
|
|
|
|
dwSize < dwNewSize || dwSize > MAX_IMCC_SIZE)
|
|
|
|
{
|
|
|
|
ImmDestroyIMCC(pIC->hCompStr);
|
|
|
|
pIC->hCompStr = ImmCreateIMCC(dwNewSize);
|
|
|
|
pCS = ImmLockIMCC(pIC->hCompStr);
|
|
|
|
if (pCS)
|
|
|
|
{
|
|
|
|
pCS->dwSize = dwNewSize;
|
|
|
|
ImmUnlockIMCC(pIC->hCompStr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#undef MAX_IMCC_SIZE
|
|
|
|
|
|
|
|
if (pOldImeDpi && bIsOldHKLIme)
|
|
|
|
{
|
|
|
|
pOldState = Imm32FetchImeState(pIC, hOldKL);
|
|
|
|
if (pOldState)
|
|
|
|
Imm32SaveImeStateSentence(pIC, pOldState, hOldKL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pNewImeDpi && bIsNewHKLIme)
|
|
|
|
pNewState = Imm32FetchImeState(pIC, hNewKL);
|
|
|
|
|
|
|
|
if (pOldState != pNewState)
|
|
|
|
{
|
|
|
|
if (pOldState)
|
|
|
|
{
|
|
|
|
pOldState->fOpen = !!pIC->fOpen;
|
2022-10-21 02:22:00 +00:00
|
|
|
pOldState->dwConversion = pIC->fdwConversion;
|
|
|
|
pOldState->dwConversion &= ~IME_CMODE_EUDC;
|
2021-10-03 22:33:15 +00:00
|
|
|
pOldState->dwSentence = pIC->fdwSentence;
|
|
|
|
pOldState->dwInit = pIC->fdwInit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pNewState)
|
|
|
|
{
|
|
|
|
if (pIC->dwChange & INPUTCONTEXTDX_CHANGE_FORCE_OPEN)
|
|
|
|
{
|
|
|
|
pIC->dwChange &= ~INPUTCONTEXTDX_CHANGE_FORCE_OPEN;
|
|
|
|
pIC->fOpen = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pIC->fOpen = pNewState->fOpen;
|
|
|
|
}
|
|
|
|
|
2022-10-21 02:22:00 +00:00
|
|
|
pIC->fdwConversion = pNewState->dwConversion;
|
|
|
|
pIC->fdwConversion &= ~IME_CMODE_EUDC;
|
2021-10-03 22:33:15 +00:00
|
|
|
pIC->fdwSentence = pNewState->dwSentence;
|
|
|
|
pIC->fdwInit = pNewState->dwInit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pNewState)
|
|
|
|
Imm32LoadImeStateSentence(pIC, pNewState, hNewKL);
|
|
|
|
|
|
|
|
if (pNewImeDpi)
|
|
|
|
{
|
|
|
|
if (IS_IME_HKL(hNewKL))
|
|
|
|
pNewImeDpi->ImeSelect(hIMC, TRUE);
|
2022-09-08 00:57:17 +00:00
|
|
|
else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
|
2021-10-03 22:33:15 +00:00
|
|
|
pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
|
|
|
|
|
|
|
|
pClientImc->hKL = hNewKL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pIC->dwChange = 0;
|
2022-10-21 02:22:00 +00:00
|
|
|
if (pIC->fOpen != fOldOpen)
|
2021-10-03 22:33:15 +00:00
|
|
|
pIC->dwChange |= INPUTCONTEXTDX_CHANGE_OPEN;
|
2022-10-21 02:22:00 +00:00
|
|
|
if (pIC->fdwConversion != dwOldConversion)
|
2021-10-03 22:33:15 +00:00
|
|
|
pIC->dwChange |= INPUTCONTEXTDX_CHANGE_CONVERSION;
|
2022-10-21 02:22:00 +00:00
|
|
|
if (pIC->fdwSentence != dwOldSentence)
|
2021-10-03 22:33:15 +00:00
|
|
|
pIC->dwChange |= INPUTCONTEXTDX_CHANGE_SENTENCE;
|
|
|
|
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImmUnlockImeDpi(pOldImeDpi);
|
|
|
|
ImmUnlockImeDpi(pNewImeDpi);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef struct SELECT_LAYOUT
|
|
|
|
{
|
|
|
|
HKL hNewKL;
|
|
|
|
HKL hOldKL;
|
|
|
|
} SELECT_LAYOUT, *LPSELECT_LAYOUT;
|
|
|
|
|
2022-04-09 01:41:39 +00:00
|
|
|
// Win: SelectContextProc
|
|
|
|
static BOOL CALLBACK Imm32SelectContextProc(HIMC hIMC, LPARAM lParam)
|
2021-10-03 22:33:15 +00:00
|
|
|
{
|
|
|
|
LPSELECT_LAYOUT pSelect = (LPSELECT_LAYOUT)lParam;
|
2022-04-09 01:41:39 +00:00
|
|
|
Imm32SelectInputContext(pSelect->hNewKL, pSelect->hOldKL, hIMC);
|
2021-10-03 22:33:15 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2022-04-09 01:41:39 +00:00
|
|
|
// Win: NotifyIMEProc
|
|
|
|
static BOOL CALLBACK Imm32NotifyIMEProc(HIMC hIMC, LPARAM lParam)
|
2021-10-03 22:33:15 +00:00
|
|
|
{
|
|
|
|
ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, (DWORD)lParam, 0);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmActivateLayout (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmActivateLayout(HKL hKL)
|
|
|
|
{
|
|
|
|
PIMEDPI pImeDpi;
|
|
|
|
HKL hOldKL;
|
|
|
|
LPARAM lParam;
|
|
|
|
HWND hwndDefIME = NULL;
|
|
|
|
SELECT_LAYOUT SelectLayout;
|
|
|
|
|
|
|
|
hOldKL = GetKeyboardLayout(0);
|
|
|
|
|
|
|
|
if (hOldKL == hKL && !(GetWin32ClientInfo()->CI_flags & CI_IMMACTIVATE))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
ImmLoadIME(hKL);
|
|
|
|
|
|
|
|
if (hOldKL != hKL)
|
|
|
|
{
|
|
|
|
pImeDpi = ImmLockImeDpi(hOldKL);
|
|
|
|
if (pImeDpi)
|
|
|
|
{
|
|
|
|
if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_COMPLETE_ON_UNSELECT)
|
|
|
|
lParam = CPS_COMPLETE;
|
|
|
|
else
|
|
|
|
lParam = CPS_CANCEL;
|
|
|
|
ImmUnlockImeDpi(pImeDpi);
|
|
|
|
|
2022-04-09 01:41:39 +00:00
|
|
|
ImmEnumInputContext(0, Imm32NotifyIMEProc, lParam);
|
2021-10-03 22:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
hwndDefIME = ImmGetDefaultIMEWnd(NULL);
|
|
|
|
if (IsWindow(hwndDefIME))
|
|
|
|
SendMessageW(hwndDefIME, WM_IME_SELECT, FALSE, (LPARAM)hOldKL);
|
|
|
|
|
|
|
|
NtUserSetThreadLayoutHandles(hKL, hOldKL);
|
|
|
|
}
|
|
|
|
|
|
|
|
SelectLayout.hNewKL = hKL;
|
|
|
|
SelectLayout.hOldKL = hOldKL;
|
2022-04-09 01:41:39 +00:00
|
|
|
ImmEnumInputContext(0, Imm32SelectContextProc, (LPARAM)&SelectLayout);
|
2021-10-03 22:33:15 +00:00
|
|
|
|
|
|
|
if (IsWindow(hwndDefIME))
|
|
|
|
SendMessageW(hwndDefIME, WM_IME_SELECT, TRUE, (LPARAM)hKL);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmAssociateContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC)
|
|
|
|
{
|
2021-09-28 13:03:25 +00:00
|
|
|
PWND pWnd;
|
|
|
|
HWND hwndFocus;
|
|
|
|
DWORD dwValue;
|
|
|
|
HIMC hOldIMC;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2021-09-28 13:03:25 +00:00
|
|
|
TRACE("(%p, %p)\n", hWnd, hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2022-01-26 22:34:29 +00:00
|
|
|
if (!IS_IMM_MODE())
|
2022-10-23 00:51:24 +00:00
|
|
|
{
|
2022-10-26 03:01:33 +00:00
|
|
|
TRACE("\n");
|
2014-09-28 18:27:58 +00:00
|
|
|
return NULL;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2014-09-28 18:27:58 +00:00
|
|
|
|
2022-04-22 23:16:53 +00:00
|
|
|
pWnd = ValidateHwnd(hWnd);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pWnd))
|
2021-09-28 13:03:25 +00:00
|
|
|
return NULL;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2022-10-23 00:51:24 +00:00
|
|
|
if (hIMC && IS_CROSS_THREAD_HIMC(hIMC))
|
2017-12-08 03:14:21 +00:00
|
|
|
return NULL;
|
|
|
|
|
2021-09-28 13:03:25 +00:00
|
|
|
hOldIMC = pWnd->hImc;
|
|
|
|
if (hOldIMC == hIMC)
|
|
|
|
return hIMC;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-09-28 13:03:25 +00:00
|
|
|
dwValue = NtUserAssociateInputContext(hWnd, hIMC, 0);
|
2022-10-20 03:32:45 +00:00
|
|
|
switch (dwValue)
|
2019-01-26 12:10:01 +00:00
|
|
|
{
|
2022-10-20 03:32:45 +00:00
|
|
|
case 0:
|
|
|
|
return hOldIMC;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2022-10-20 03:32:45 +00:00
|
|
|
case 1:
|
|
|
|
hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
|
|
|
|
if (hwndFocus == hWnd)
|
|
|
|
{
|
|
|
|
ImmSetActiveContext(hWnd, hOldIMC, FALSE);
|
|
|
|
ImmSetActiveContext(hWnd, hIMC, TRUE);
|
|
|
|
}
|
|
|
|
return hOldIMC;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmAssociateContextEx (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags)
|
|
|
|
{
|
2021-09-16 10:29:49 +00:00
|
|
|
HWND hwndFocus;
|
|
|
|
PWND pFocusWnd;
|
|
|
|
HIMC hOldIMC = NULL;
|
|
|
|
DWORD dwValue;
|
|
|
|
|
|
|
|
TRACE("(%p, %p, 0x%lX)\n", hWnd, hIMC, dwFlags);
|
2010-03-07 11:27:14 +00:00
|
|
|
|
2022-01-26 22:34:29 +00:00
|
|
|
if (!IS_IMM_MODE())
|
2022-10-23 00:51:24 +00:00
|
|
|
{
|
2022-10-26 03:01:33 +00:00
|
|
|
TRACE("\n");
|
2017-12-08 03:14:21 +00:00
|
|
|
return FALSE;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
Sync avifil, credui, crypt32, cryptdlg, cryptui, dnsapi, gdiplus, hhctrl, hnetcfg, iccvid, imaadp32, imm32, jscript, localspl, localui, mapi32, mciavi32, mcicda, mciqtz32, mciseq, mciwave, mshtml, msrle32, msvfw32, msvidc32, msxml3, oleacc, oleaut32 to Wine 1.2rc5 (Samuel Serapion, small changes by me)
Remove Esperanto and Walon languages from comctl32, comdlg32, mpr, msi, shlwapi, wininet
svn path=/trunk/; revision=47920
2010-07-01 11:09:47 +00:00
|
|
|
|
2022-10-23 00:51:24 +00:00
|
|
|
if (hIMC && !(dwFlags & IACE_DEFAULT) && IS_CROSS_THREAD_HIMC(hIMC))
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
2021-09-16 10:29:49 +00:00
|
|
|
|
|
|
|
hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
|
2022-04-22 23:16:53 +00:00
|
|
|
pFocusWnd = ValidateHwnd(hwndFocus);
|
2021-09-16 10:29:49 +00:00
|
|
|
if (pFocusWnd)
|
|
|
|
hOldIMC = pFocusWnd->hImc;
|
|
|
|
|
|
|
|
dwValue = NtUserAssociateInputContext(hWnd, hIMC, dwFlags);
|
|
|
|
switch (dwValue)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
case 1:
|
2022-04-22 23:16:53 +00:00
|
|
|
pFocusWnd = ValidateHwnd(hwndFocus);
|
2021-09-16 10:29:49 +00:00
|
|
|
if (pFocusWnd)
|
|
|
|
{
|
|
|
|
hIMC = pFocusWnd->hImc;
|
|
|
|
if (hIMC != hOldIMC)
|
|
|
|
{
|
|
|
|
ImmSetActiveContext(hwndFocus, hOldIMC, FALSE);
|
|
|
|
ImmSetActiveContext(hwndFocus, hIMC, TRUE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return FALSE;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmCreateContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMC WINAPI ImmCreateContext(void)
|
|
|
|
{
|
2021-08-04 00:41:59 +00:00
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
HIMC hIMC;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2021-08-04 00:49:41 +00:00
|
|
|
TRACE("()\n");
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2022-01-26 22:34:29 +00:00
|
|
|
if (!IS_IMM_MODE())
|
2022-10-23 00:51:24 +00:00
|
|
|
{
|
2022-10-26 03:01:33 +00:00
|
|
|
TRACE("\n");
|
2021-08-04 00:41:59 +00:00
|
|
|
return NULL;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2022-03-29 09:02:25 +00:00
|
|
|
pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pClientImc))
|
2021-08-04 00:41:59 +00:00
|
|
|
return NULL;
|
|
|
|
|
2022-01-01 11:59:00 +00:00
|
|
|
hIMC = NtUserCreateInputContext((ULONG_PTR)pClientImc);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(hIMC))
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2022-03-29 09:02:25 +00:00
|
|
|
ImmLocalFree(pClientImc);
|
2021-08-04 00:41:59 +00:00
|
|
|
return NULL;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-08-04 00:41:59 +00:00
|
|
|
RtlInitializeCriticalSection(&pClientImc->cs);
|
2021-08-17 23:42:12 +00:00
|
|
|
|
2022-01-20 02:49:27 +00:00
|
|
|
pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
|
2021-08-17 23:42:12 +00:00
|
|
|
|
2021-08-04 00:41:59 +00:00
|
|
|
return hIMC;
|
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2022-04-07 13:55:33 +00:00
|
|
|
// Win: DestroyImeModeSaver
|
|
|
|
static VOID APIENTRY Imm32DestroyImeModeSaver(LPINPUTCONTEXTDX pIC)
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
2022-04-07 13:55:33 +00:00
|
|
|
PIME_STATE pState, pNext;
|
|
|
|
PIME_SUBSTATE pSubState, pSubNext;
|
2021-10-03 22:33:15 +00:00
|
|
|
|
2022-04-07 13:55:33 +00:00
|
|
|
for (pState = pIC->pState; pState; pState = pNext)
|
2021-10-03 22:33:15 +00:00
|
|
|
{
|
2022-04-07 13:55:33 +00:00
|
|
|
pNext = pState->pNext;
|
|
|
|
|
|
|
|
for (pSubState = pState->pSubState; pSubState; pSubState = pSubNext)
|
2021-10-03 22:33:15 +00:00
|
|
|
{
|
2022-04-07 13:55:33 +00:00
|
|
|
pSubNext = pSubState->pNext;
|
2022-03-29 09:02:25 +00:00
|
|
|
ImmLocalFree(pSubState);
|
2021-10-03 22:33:15 +00:00
|
|
|
}
|
2022-04-07 13:55:33 +00:00
|
|
|
|
2022-03-29 09:02:25 +00:00
|
|
|
ImmLocalFree(pState);
|
2021-10-03 22:33:15 +00:00
|
|
|
}
|
2022-04-07 13:55:33 +00:00
|
|
|
|
|
|
|
pIC->pState = NULL;
|
2021-08-04 00:41:59 +00:00
|
|
|
}
|
2014-09-28 18:27:58 +00:00
|
|
|
|
2022-04-06 06:44:27 +00:00
|
|
|
// Win: DestroyInputContext
|
2022-03-29 10:02:56 +00:00
|
|
|
BOOL APIENTRY Imm32DestroyInputContext(HIMC hIMC, HKL hKL, BOOL bKeep)
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
|
|
|
PIMEDPI pImeDpi;
|
2021-10-03 22:33:15 +00:00
|
|
|
LPINPUTCONTEXTDX pIC;
|
2021-08-04 00:41:59 +00:00
|
|
|
PCLIENTIMC pClientImc;
|
2021-09-27 00:31:16 +00:00
|
|
|
PIMC pIMC;
|
2014-09-28 18:27:58 +00:00
|
|
|
|
2022-10-23 00:51:24 +00:00
|
|
|
if (hIMC == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (!IS_IMM_MODE())
|
|
|
|
{
|
2022-10-26 03:01:33 +00:00
|
|
|
TRACE("\n");
|
2021-08-04 00:41:59 +00:00
|
|
|
return FALSE;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2021-08-04 00:41:59 +00:00
|
|
|
|
2022-04-22 23:16:53 +00:00
|
|
|
pIMC = ValidateHandle(hIMC, TYPE_INPUTCONTEXT);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pIMC))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (pIMC->head.pti != Imm32CurrentPti())
|
2022-02-13 06:51:53 +00:00
|
|
|
{
|
2022-10-26 03:01:33 +00:00
|
|
|
ERR("Thread mismatch\n");
|
2021-09-27 00:31:16 +00:00
|
|
|
return FALSE;
|
2022-02-13 06:51:53 +00:00
|
|
|
}
|
2021-09-27 00:31:16 +00:00
|
|
|
|
|
|
|
pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
|
2022-10-23 00:51:24 +00:00
|
|
|
if (pClientImc == NULL)
|
|
|
|
{
|
|
|
|
TRACE("pClientImc == NULL\n");
|
2022-02-13 06:51:53 +00:00
|
|
|
goto Finish;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2021-08-04 00:41:59 +00:00
|
|
|
|
2022-02-13 06:51:53 +00:00
|
|
|
if ((pClientImc->dwFlags & CLIENTIMC_UNKNOWN2) && !bKeep)
|
2008-04-04 13:20:27 +00:00
|
|
|
{
|
2022-10-26 03:01:33 +00:00
|
|
|
ERR("Can't destroy for CLIENTIMC_UNKNOWN2\n");
|
2022-02-13 06:51:53 +00:00
|
|
|
return FALSE;
|
2008-04-04 13:20:27 +00:00
|
|
|
}
|
|
|
|
|
2022-03-03 07:17:07 +00:00
|
|
|
if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
|
2022-02-13 06:51:53 +00:00
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
InterlockedIncrement(&pClientImc->cLockObj);
|
|
|
|
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pClientImc->hInputContext))
|
2022-02-13 06:51:53 +00:00
|
|
|
goto Quit;
|
|
|
|
|
2021-10-03 22:33:15 +00:00
|
|
|
pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pIC))
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2022-04-07 13:55:33 +00:00
|
|
|
CtfImmTIMDestroyInputContext(hIMC);
|
|
|
|
|
|
|
|
if (pClientImc->hKL == hKL)
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
2022-04-07 13:55:33 +00:00
|
|
|
pImeDpi = ImmLockImeDpi(hKL);
|
|
|
|
if (pImeDpi)
|
|
|
|
{
|
|
|
|
if (IS_IME_HKL(hKL))
|
|
|
|
pImeDpi->ImeSelect(hIMC, FALSE);
|
2022-09-08 00:43:43 +00:00
|
|
|
else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
|
2022-04-07 13:55:33 +00:00
|
|
|
pImeDpi->CtfImeSelectEx(hIMC, FALSE, hKL);
|
|
|
|
|
|
|
|
ImmUnlockImeDpi(pImeDpi);
|
|
|
|
}
|
|
|
|
|
|
|
|
pClientImc->hKL = NULL;
|
2021-08-04 00:41:59 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2022-04-07 13:55:33 +00:00
|
|
|
ImmDestroyIMCC(pIC->hPrivate);
|
|
|
|
ImmDestroyIMCC(pIC->hMsgBuf);
|
|
|
|
ImmDestroyIMCC(pIC->hGuideLine);
|
|
|
|
ImmDestroyIMCC(pIC->hCandInfo);
|
|
|
|
ImmDestroyIMCC(pIC->hCompStr);
|
|
|
|
Imm32DestroyImeModeSaver(pIC);
|
2021-08-04 00:41:59 +00:00
|
|
|
ImmUnlockIMC(hIMC);
|
2014-09-28 18:27:58 +00:00
|
|
|
|
2022-02-13 06:51:53 +00:00
|
|
|
Quit:
|
2022-03-03 07:17:07 +00:00
|
|
|
pClientImc->dwFlags |= CLIENTIMC_DESTROY;
|
2021-08-04 00:41:59 +00:00
|
|
|
ImmUnlockClientImc(pClientImc);
|
2014-09-28 18:27:58 +00:00
|
|
|
|
2022-02-13 06:51:53 +00:00
|
|
|
Finish:
|
|
|
|
if (bKeep)
|
|
|
|
return TRUE;
|
|
|
|
return NtUserDestroyInputContext(hIMC);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2022-04-08 13:23:30 +00:00
|
|
|
// NOTE: Windows does recursive call ImmLockIMC here but we don't do so.
|
|
|
|
// Win: BOOL CreateInputContext(HIMC hIMC, HKL hKL, BOOL fSelect)
|
2021-09-27 00:32:24 +00:00
|
|
|
BOOL APIENTRY
|
2022-04-08 13:23:30 +00:00
|
|
|
Imm32CreateInputContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL fSelect)
|
2021-09-27 00:32:24 +00:00
|
|
|
{
|
|
|
|
DWORD dwIndex, cbPrivate;
|
|
|
|
PIMEDPI pImeDpi = NULL;
|
|
|
|
LPCOMPOSITIONSTRING pCS;
|
|
|
|
LPCANDIDATEINFO pCI;
|
|
|
|
LPGUIDELINE pGL;
|
|
|
|
|
|
|
|
/* Create IC components */
|
|
|
|
pIC->hCompStr = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
|
|
|
|
pIC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
|
|
|
|
pIC->hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
|
|
|
|
pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pIC->hCompStr) ||
|
|
|
|
IS_NULL_UNEXPECTEDLY(pIC->hCandInfo) ||
|
|
|
|
IS_NULL_UNEXPECTEDLY(pIC->hGuideLine) ||
|
|
|
|
IS_NULL_UNEXPECTEDLY(pIC->hMsgBuf))
|
|
|
|
{
|
2021-09-27 00:32:24 +00:00
|
|
|
goto Fail;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2021-09-27 00:32:24 +00:00
|
|
|
|
|
|
|
/* Initialize IC components */
|
|
|
|
pCS = ImmLockIMCC(pIC->hCompStr);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pCS))
|
2021-09-27 00:32:24 +00:00
|
|
|
goto Fail;
|
|
|
|
pCS->dwSize = sizeof(COMPOSITIONSTRING);
|
|
|
|
ImmUnlockIMCC(pIC->hCompStr);
|
|
|
|
|
|
|
|
pCI = ImmLockIMCC(pIC->hCandInfo);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pCI))
|
2021-09-27 00:32:24 +00:00
|
|
|
goto Fail;
|
|
|
|
pCI->dwSize = sizeof(CANDIDATEINFO);
|
|
|
|
ImmUnlockIMCC(pIC->hCandInfo);
|
|
|
|
|
|
|
|
pGL = ImmLockIMCC(pIC->hGuideLine);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pGL))
|
2021-09-27 00:32:24 +00:00
|
|
|
goto Fail;
|
|
|
|
pGL->dwSize = sizeof(GUIDELINE);
|
|
|
|
ImmUnlockIMCC(pIC->hGuideLine);
|
|
|
|
|
|
|
|
pIC->dwNumMsgBuf = 0;
|
|
|
|
pIC->fOpen = FALSE;
|
|
|
|
pIC->fdwConversion = pIC->fdwSentence = 0;
|
|
|
|
|
|
|
|
for (dwIndex = 0; dwIndex < MAX_CANDIDATEFORM; ++dwIndex)
|
|
|
|
pIC->cfCandForm[dwIndex].dwIndex = IMM_INVALID_CANDFORM;
|
|
|
|
|
|
|
|
/* Get private data size */
|
|
|
|
pImeDpi = ImmLockImeDpi(hKL);
|
|
|
|
if (!pImeDpi)
|
|
|
|
{
|
|
|
|
cbPrivate = sizeof(DWORD);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Update CLIENTIMC */
|
|
|
|
pClientImc->uCodePage = pImeDpi->uCodePage;
|
|
|
|
if (ImeDpi_IsUnicode(pImeDpi))
|
|
|
|
pClientImc->dwFlags |= CLIENTIMC_WIDE;
|
|
|
|
|
|
|
|
cbPrivate = pImeDpi->ImeInfo.dwPrivateDataSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create private data */
|
|
|
|
pIC->hPrivate = ImmCreateIMCC(cbPrivate);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pIC->hPrivate))
|
2021-09-27 00:32:24 +00:00
|
|
|
goto Fail;
|
|
|
|
|
2022-10-21 01:52:43 +00:00
|
|
|
CtfImmTIMCreateInputContext(hIMC);
|
|
|
|
|
2021-09-27 00:32:24 +00:00
|
|
|
if (pImeDpi)
|
|
|
|
{
|
|
|
|
/* Select the IME */
|
|
|
|
if (fSelect)
|
|
|
|
{
|
|
|
|
if (IS_IME_HKL(hKL))
|
|
|
|
pImeDpi->ImeSelect(hIMC, TRUE);
|
2022-09-08 00:57:17 +00:00
|
|
|
else if (IS_CICERO_MODE() && !IS_16BIT_MODE())
|
2021-09-27 00:32:24 +00:00
|
|
|
pImeDpi->CtfImeSelectEx(hIMC, TRUE, hKL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set HKL */
|
|
|
|
pClientImc->hKL = hKL;
|
|
|
|
|
|
|
|
ImmUnlockImeDpi(pImeDpi);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
Fail:
|
|
|
|
if (pImeDpi)
|
|
|
|
ImmUnlockImeDpi(pImeDpi);
|
|
|
|
|
|
|
|
pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
|
|
|
|
pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
|
|
|
|
pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
|
|
|
|
pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2022-04-08 13:23:30 +00:00
|
|
|
LPINPUTCONTEXT APIENTRY Imm32InternalLockIMC(HIMC hIMC, BOOL fSelect)
|
2021-09-27 00:32:24 +00:00
|
|
|
{
|
|
|
|
HANDLE hIC;
|
|
|
|
LPINPUTCONTEXT pIC = NULL;
|
|
|
|
PCLIENTIMC pClientImc;
|
2022-04-08 13:23:30 +00:00
|
|
|
WORD LangID;
|
2021-09-27 00:32:24 +00:00
|
|
|
DWORD dwThreadId;
|
2022-04-08 13:23:30 +00:00
|
|
|
HKL hOldKL, hNewKL;
|
2021-09-27 00:32:24 +00:00
|
|
|
PIMEDPI pImeDpi = NULL;
|
|
|
|
|
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
2023-12-29 11:57:27 +00:00
|
|
|
if (!pClientImc)
|
2021-09-27 00:32:24 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
RtlEnterCriticalSection(&pClientImc->cs);
|
|
|
|
|
2022-04-08 13:23:30 +00:00
|
|
|
if (pClientImc->hInputContext)
|
2022-04-22 22:11:48 +00:00
|
|
|
{
|
|
|
|
pIC = LocalLock(pClientImc->hInputContext);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pIC))
|
2022-04-22 22:11:48 +00:00
|
|
|
goto Failure;
|
2022-10-23 00:51:24 +00:00
|
|
|
|
|
|
|
CtfImmTIMCreateInputContext(hIMC);
|
|
|
|
goto Success;
|
2022-04-22 22:11:48 +00:00
|
|
|
}
|
2021-09-27 00:32:24 +00:00
|
|
|
|
2022-04-08 13:23:30 +00:00
|
|
|
dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
|
2022-09-08 00:43:43 +00:00
|
|
|
if (dwThreadId == GetCurrentThreadId() && IS_CICERO_MODE() && !IS_16BIT_MODE())
|
2022-04-08 13:23:30 +00:00
|
|
|
{
|
|
|
|
hOldKL = GetKeyboardLayout(0);
|
|
|
|
LangID = LOWORD(hOldKL);
|
|
|
|
hNewKL = (HKL)(DWORD_PTR)MAKELONG(LangID, LangID);
|
2021-09-27 00:32:24 +00:00
|
|
|
|
2022-04-08 13:23:30 +00:00
|
|
|
pImeDpi = Imm32FindOrLoadImeDpi(hNewKL);
|
|
|
|
if (pImeDpi)
|
2021-09-27 00:32:24 +00:00
|
|
|
{
|
2022-04-08 13:23:30 +00:00
|
|
|
CtfImmTIMActivate(hNewKL);
|
2021-09-27 00:32:24 +00:00
|
|
|
}
|
2022-04-08 13:23:30 +00:00
|
|
|
}
|
2021-09-27 00:32:24 +00:00
|
|
|
|
2022-04-08 13:23:30 +00:00
|
|
|
if (!NtUserQueryInputContext(hIMC, QIC_DEFAULTWINDOWIME))
|
2022-10-23 00:51:24 +00:00
|
|
|
{
|
2022-10-26 03:01:33 +00:00
|
|
|
ERR("No default IME window\n");
|
2022-04-22 22:11:48 +00:00
|
|
|
goto Failure;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2021-09-27 00:32:24 +00:00
|
|
|
|
2022-04-08 13:23:30 +00:00
|
|
|
hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
|
|
|
|
pIC = LocalLock(hIC);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pIC))
|
2022-04-08 13:23:30 +00:00
|
|
|
{
|
|
|
|
LocalFree(hIC);
|
2022-04-22 22:11:48 +00:00
|
|
|
goto Failure;
|
2021-09-27 00:32:24 +00:00
|
|
|
}
|
2022-04-08 13:23:30 +00:00
|
|
|
pClientImc->hInputContext = hIC;
|
2021-09-27 00:32:24 +00:00
|
|
|
|
2022-04-08 13:23:30 +00:00
|
|
|
hNewKL = GetKeyboardLayout(dwThreadId);
|
|
|
|
if (!Imm32CreateInputContext(hIMC, pIC, pClientImc, hNewKL, fSelect))
|
|
|
|
{
|
2022-10-21 07:40:25 +00:00
|
|
|
LocalUnlock(hIC);
|
|
|
|
pClientImc->hInputContext = LocalFree(hIC);
|
2022-04-22 22:11:48 +00:00
|
|
|
goto Failure;
|
2022-04-08 13:23:30 +00:00
|
|
|
}
|
2021-09-27 00:32:24 +00:00
|
|
|
|
2022-04-22 22:11:48 +00:00
|
|
|
Success:
|
2021-09-27 00:32:24 +00:00
|
|
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
|
|
|
InterlockedIncrement(&pClientImc->cLockObj);
|
2022-04-08 13:23:30 +00:00
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return pIC;
|
2021-09-27 00:32:24 +00:00
|
|
|
|
2022-04-22 22:11:48 +00:00
|
|
|
Failure:
|
2022-04-08 13:23:30 +00:00
|
|
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
2021-09-27 00:32:24 +00:00
|
|
|
ImmUnlockClientImc(pClientImc);
|
2022-04-08 13:23:30 +00:00
|
|
|
return NULL;
|
2021-09-27 00:32:24 +00:00
|
|
|
}
|
|
|
|
|
2010-03-07 11:27:14 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmDestroyContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmDestroyContext(HIMC hIMC)
|
|
|
|
{
|
2021-08-04 00:41:59 +00:00
|
|
|
HKL hKL;
|
|
|
|
|
2021-08-04 00:49:41 +00:00
|
|
|
TRACE("(%p)\n", hIMC);
|
2021-08-04 00:41:59 +00:00
|
|
|
|
2022-01-26 22:34:29 +00:00
|
|
|
if (!IS_IMM_MODE())
|
2022-10-23 00:51:24 +00:00
|
|
|
{
|
2022-10-26 03:01:33 +00:00
|
|
|
TRACE("\n");
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2021-08-04 00:41:59 +00:00
|
|
|
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_CROSS_THREAD_HIMC(hIMC))
|
2021-08-04 00:41:59 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
hKL = GetKeyboardLayout(0);
|
2022-03-29 10:02:56 +00:00
|
|
|
return Imm32DestroyInputContext(hIMC, hKL, FALSE);
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
|
|
|
|
2021-08-14 01:38:06 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmLockClientImc (IMM32.@)
|
|
|
|
*/
|
2021-07-11 00:48:15 +00:00
|
|
|
PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
|
|
|
|
{
|
2021-09-27 00:31:16 +00:00
|
|
|
PIMC pIMC;
|
2021-07-11 00:48:15 +00:00
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
|
2021-08-04 00:49:41 +00:00
|
|
|
TRACE("(%p)\n", hImc);
|
2021-07-11 00:48:15 +00:00
|
|
|
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(hImc))
|
2021-07-11 00:48:15 +00:00
|
|
|
return NULL;
|
|
|
|
|
2022-04-22 23:16:53 +00:00
|
|
|
pIMC = ValidateHandle(hImc, TYPE_INPUTCONTEXT);
|
2023-12-29 11:57:27 +00:00
|
|
|
if (!pIMC || !Imm32CheckImcProcess(pIMC))
|
2021-09-27 00:31:16 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
|
2022-04-14 05:10:19 +00:00
|
|
|
if (pClientImc)
|
2021-07-11 00:48:15 +00:00
|
|
|
{
|
2022-04-14 05:10:19 +00:00
|
|
|
if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
|
2021-07-11 00:48:15 +00:00
|
|
|
return NULL;
|
2022-04-14 05:10:19 +00:00
|
|
|
goto Finish;
|
|
|
|
}
|
2021-07-11 00:48:15 +00:00
|
|
|
|
2022-04-14 05:10:19 +00:00
|
|
|
pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pClientImc))
|
2022-04-14 05:10:19 +00:00
|
|
|
return NULL;
|
2021-07-11 00:48:15 +00:00
|
|
|
|
2022-04-14 05:10:19 +00:00
|
|
|
RtlInitializeCriticalSection(&pClientImc->cs);
|
|
|
|
pClientImc->dwCompatFlags = (DWORD)NtUserGetThreadState(THREADSTATE_IMECOMPATFLAGS);
|
2021-07-11 00:48:15 +00:00
|
|
|
|
2022-04-14 05:10:19 +00:00
|
|
|
if (!NtUserUpdateInputContext(hImc, UIC_CLIENTIMCDATA, (DWORD_PTR)pClientImc))
|
2021-07-11 00:48:15 +00:00
|
|
|
{
|
2022-10-23 00:51:24 +00:00
|
|
|
ERR("\n");
|
2022-04-14 05:10:19 +00:00
|
|
|
ImmLocalFree(pClientImc);
|
|
|
|
return NULL;
|
2021-07-11 00:48:15 +00:00
|
|
|
}
|
|
|
|
|
2022-04-14 05:10:19 +00:00
|
|
|
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
|
|
|
|
|
|
|
|
Finish:
|
2021-07-11 00:48:15 +00:00
|
|
|
InterlockedIncrement(&pClientImc->cLockObj);
|
|
|
|
return pClientImc;
|
|
|
|
}
|
|
|
|
|
2021-08-14 01:38:06 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmUnlockClientImc (IMM32.@)
|
|
|
|
*/
|
2021-07-11 00:48:15 +00:00
|
|
|
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
|
|
|
|
{
|
|
|
|
LONG cLocks;
|
2021-09-27 00:32:24 +00:00
|
|
|
HANDLE hInputContext;
|
2021-07-11 00:48:15 +00:00
|
|
|
|
2021-08-04 00:49:41 +00:00
|
|
|
TRACE("(%p)\n", pClientImc);
|
2021-07-11 00:48:15 +00:00
|
|
|
|
|
|
|
cLocks = InterlockedDecrement(&pClientImc->cLockObj);
|
2022-03-03 07:17:07 +00:00
|
|
|
if (cLocks != 0 || !(pClientImc->dwFlags & CLIENTIMC_DESTROY))
|
2021-07-11 00:48:15 +00:00
|
|
|
return;
|
|
|
|
|
2021-09-27 00:32:24 +00:00
|
|
|
hInputContext = pClientImc->hInputContext;
|
|
|
|
if (hInputContext)
|
|
|
|
LocalFree(hInputContext);
|
2021-07-11 00:48:15 +00:00
|
|
|
|
|
|
|
RtlDeleteCriticalSection(&pClientImc->cs);
|
2022-03-29 09:02:25 +00:00
|
|
|
ImmLocalFree(pClientImc);
|
2021-07-11 00:48:15 +00:00
|
|
|
}
|
|
|
|
|
2022-04-06 06:44:27 +00:00
|
|
|
// Win: ImmGetSaveContext
|
2022-03-29 09:05:09 +00:00
|
|
|
static HIMC APIENTRY ImmGetSaveContext(HWND hWnd, DWORD dwContextFlags)
|
2021-08-23 21:50:39 +00:00
|
|
|
{
|
|
|
|
HIMC hIMC;
|
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
PWND pWnd;
|
|
|
|
|
2022-01-26 22:34:29 +00:00
|
|
|
if (!IS_IMM_MODE())
|
2022-10-23 00:51:24 +00:00
|
|
|
{
|
|
|
|
TRACE("Not IMM mode.\n");
|
2021-08-23 21:50:39 +00:00
|
|
|
return NULL;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2021-08-23 21:50:39 +00:00
|
|
|
|
|
|
|
if (!hWnd)
|
|
|
|
{
|
2022-01-20 02:49:27 +00:00
|
|
|
hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
|
2021-08-23 21:50:39 +00:00
|
|
|
goto Quit;
|
|
|
|
}
|
|
|
|
|
2022-04-22 23:16:53 +00:00
|
|
|
pWnd = ValidateHwnd(hWnd);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pWnd) || IS_CROSS_PROCESS_HWND(hWnd))
|
2021-08-23 21:50:39 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
hIMC = pWnd->hImc;
|
|
|
|
if (!hIMC && (dwContextFlags & 1))
|
|
|
|
hIMC = (HIMC)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_ICONTEXT);
|
|
|
|
|
|
|
|
Quit:
|
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pClientImc))
|
2021-08-23 21:50:39 +00:00
|
|
|
return NULL;
|
2022-10-23 00:51:24 +00:00
|
|
|
|
2022-08-09 11:09:23 +00:00
|
|
|
if ((dwContextFlags & 2) && (pClientImc->dwFlags & CLIENTIMC_DISABLEIME))
|
2021-08-23 21:50:39 +00:00
|
|
|
hIMC = NULL;
|
2022-10-23 00:51:24 +00:00
|
|
|
|
2021-08-23 21:50:39 +00:00
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return hIMC;
|
|
|
|
}
|
|
|
|
|
2005-12-12 20:59:55 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmGetContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
HIMC WINAPI ImmGetContext(HWND hWnd)
|
|
|
|
{
|
2021-08-23 21:50:39 +00:00
|
|
|
TRACE("(%p)\n", hWnd);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(hWnd))
|
2011-12-15 00:40:35 +00:00
|
|
|
return NULL;
|
2022-03-29 09:05:09 +00:00
|
|
|
return ImmGetSaveContext(hWnd, 2);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
2007-09-14 08:03:04 +00:00
|
|
|
/***********************************************************************
|
2021-09-27 00:32:24 +00:00
|
|
|
* ImmLockIMC(IMM32.@)
|
|
|
|
*
|
|
|
|
* NOTE: This is not ImmLockIMCC. Don't confuse.
|
|
|
|
*/
|
2007-09-14 08:03:04 +00:00
|
|
|
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
|
|
|
|
{
|
2021-09-27 00:32:24 +00:00
|
|
|
TRACE("(%p)\n", hIMC);
|
2022-04-08 13:23:30 +00:00
|
|
|
return Imm32InternalLockIMC(hIMC, TRUE);
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmUnlockIMC(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
|
|
|
|
{
|
2021-07-13 11:17:17 +00:00
|
|
|
PCLIENTIMC pClientImc;
|
2014-09-28 18:27:58 +00:00
|
|
|
|
2021-07-13 11:17:17 +00:00
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pClientImc))
|
2014-09-28 18:27:58 +00:00
|
|
|
return FALSE;
|
2021-07-11 00:48:15 +00:00
|
|
|
|
2021-09-27 00:32:24 +00:00
|
|
|
if (pClientImc->hInputContext)
|
|
|
|
LocalUnlock(pClientImc->hInputContext);
|
2021-07-11 00:48:15 +00:00
|
|
|
|
2021-07-13 11:17:17 +00:00
|
|
|
InterlockedDecrement(&pClientImc->cLockObj);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
2013-12-01 15:57:34 +00:00
|
|
|
return TRUE;
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
2021-09-10 14:39:15 +00:00
|
|
|
* ImmReleaseContext (IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
|
2007-09-14 08:03:04 +00:00
|
|
|
{
|
2021-09-10 14:39:15 +00:00
|
|
|
TRACE("(%p, %p)\n", hWnd, hIMC);
|
|
|
|
UNREFERENCED_PARAMETER(hWnd);
|
|
|
|
UNREFERENCED_PARAMETER(hIMC);
|
|
|
|
return TRUE; // Do nothing. This is correct.
|
2007-09-14 08:03:04 +00:00
|
|
|
}
|
|
|
|
|
2011-12-15 00:40:35 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmEnumInputContext(IMM32.@)
|
|
|
|
*/
|
2021-07-28 23:21:33 +00:00
|
|
|
BOOL WINAPI ImmEnumInputContext(DWORD dwThreadId, IMCENUMPROC lpfn, LPARAM lParam)
|
2011-12-15 00:40:35 +00:00
|
|
|
{
|
2021-07-31 06:45:07 +00:00
|
|
|
HIMC *phList;
|
|
|
|
DWORD dwIndex, dwCount;
|
|
|
|
BOOL ret = TRUE;
|
|
|
|
HIMC hIMC;
|
|
|
|
|
2021-08-04 00:49:41 +00:00
|
|
|
TRACE("(%lu, %p, %p)\n", dwThreadId, lpfn, lParam);
|
2021-07-31 06:45:07 +00:00
|
|
|
|
2022-04-09 01:41:39 +00:00
|
|
|
dwCount = Imm32BuildHimcList(dwThreadId, &phList);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_ZERO_UNEXPECTEDLY(dwCount))
|
2021-07-31 06:45:07 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (dwIndex = 0; dwIndex < dwCount; ++dwIndex)
|
|
|
|
{
|
|
|
|
hIMC = phList[dwIndex];
|
|
|
|
ret = (*lpfn)(hIMC, lParam);
|
|
|
|
if (!ret)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-03-29 09:02:25 +00:00
|
|
|
ImmLocalFree(phList);
|
2021-07-31 06:45:07 +00:00
|
|
|
return ret;
|
2011-12-15 00:40:35 +00:00
|
|
|
}
|
2012-03-15 21:42:01 +00:00
|
|
|
|
2020-08-08 00:46:13 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetActiveContext(IMM32.@)
|
|
|
|
*/
|
2021-09-30 18:02:56 +00:00
|
|
|
BOOL WINAPI ImmSetActiveContext(HWND hWnd, HIMC hIMC, BOOL fActive)
|
2020-08-08 00:46:13 +00:00
|
|
|
{
|
2021-09-30 18:02:56 +00:00
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
LPINPUTCONTEXTDX pIC;
|
|
|
|
PIMEDPI pImeDpi;
|
2022-10-21 04:07:11 +00:00
|
|
|
HIMC hOldIMC;
|
2021-09-30 18:02:56 +00:00
|
|
|
HKL hKL;
|
|
|
|
BOOL fOpen = FALSE;
|
2022-10-21 04:07:11 +00:00
|
|
|
DWORD dwConversion = 0, dwShowFlags = ISC_SHOWUIALL;
|
2021-09-30 18:02:56 +00:00
|
|
|
HWND hwndDefIME;
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %d)\n", hWnd, hIMC, fActive);
|
|
|
|
|
2022-01-26 22:34:29 +00:00
|
|
|
if (!IS_IMM_MODE())
|
2022-10-23 00:51:24 +00:00
|
|
|
{
|
2022-10-26 03:01:33 +00:00
|
|
|
TRACE("\n");
|
2021-09-30 18:02:56 +00:00
|
|
|
return FALSE;
|
2022-10-23 00:51:24 +00:00
|
|
|
}
|
2021-09-30 18:02:56 +00:00
|
|
|
|
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
|
|
|
|
if (!fActive)
|
|
|
|
{
|
|
|
|
if (pClientImc)
|
2022-10-21 04:21:02 +00:00
|
|
|
pClientImc->dwFlags &= ~CLIENTIMC_ACTIVE;
|
2021-09-30 18:02:56 +00:00
|
|
|
}
|
|
|
|
else if (hIMC)
|
|
|
|
{
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pClientImc))
|
2021-09-30 18:02:56 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(pIC))
|
2021-09-30 18:02:56 +00:00
|
|
|
{
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pIC->hWnd = hWnd;
|
2022-10-21 04:21:02 +00:00
|
|
|
pClientImc->dwFlags |= CLIENTIMC_ACTIVE;
|
2021-09-30 18:02:56 +00:00
|
|
|
|
|
|
|
if (pIC->dwUIFlags & 2)
|
2022-10-21 04:07:11 +00:00
|
|
|
dwShowFlags = (ISC_SHOWUIGUIDELINE | ISC_SHOWUIALLCANDIDATEWINDOW);
|
2021-09-30 18:02:56 +00:00
|
|
|
|
|
|
|
fOpen = pIC->fOpen;
|
|
|
|
dwConversion = pIC->fdwConversion;
|
|
|
|
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-10-21 04:07:11 +00:00
|
|
|
hOldIMC = ImmGetSaveContext(hWnd, 1);
|
|
|
|
pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hOldIMC);
|
2021-09-30 18:02:56 +00:00
|
|
|
if (pIC)
|
|
|
|
{
|
|
|
|
pIC->hWnd = hWnd;
|
2022-10-21 04:07:11 +00:00
|
|
|
ImmUnlockIMC(hOldIMC);
|
2021-09-30 18:02:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
hKL = GetKeyboardLayout(0);
|
2022-09-08 00:43:43 +00:00
|
|
|
if (IS_CICERO_MODE() && !IS_16BIT_MODE())
|
2021-09-30 18:02:56 +00:00
|
|
|
{
|
2023-12-03 08:33:22 +00:00
|
|
|
CtfImeSetActiveContextAlways(hIMC, fActive, hWnd, hKL);
|
2021-09-30 18:02:56 +00:00
|
|
|
hKL = GetKeyboardLayout(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
pImeDpi = ImmLockImeDpi(hKL);
|
|
|
|
if (pImeDpi)
|
|
|
|
{
|
|
|
|
if (IS_IME_HKL(hKL))
|
|
|
|
pImeDpi->ImeSetActiveContext(hIMC, fActive);
|
|
|
|
ImmUnlockImeDpi(pImeDpi);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsWindow(hWnd))
|
|
|
|
{
|
2022-10-21 04:07:11 +00:00
|
|
|
SendMessageW(hWnd, WM_IME_SETCONTEXT, fActive, dwShowFlags);
|
2021-09-30 18:02:56 +00:00
|
|
|
if (fActive)
|
|
|
|
NtUserNotifyIMEStatus(hWnd, fOpen, dwConversion);
|
|
|
|
}
|
|
|
|
else if (!fActive)
|
|
|
|
{
|
|
|
|
hwndDefIME = ImmGetDefaultIMEWnd(NULL);
|
|
|
|
if (hwndDefIME)
|
2022-10-21 04:07:11 +00:00
|
|
|
SendMessageW(hwndDefIME, WM_IME_SETCONTEXT, 0, dwShowFlags);
|
2021-09-30 18:02:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pClientImc)
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
|
|
|
|
return TRUE;
|
2020-08-08 00:46:13 +00:00
|
|
|
}
|
|
|
|
|
2022-02-10 06:18:44 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmWINNLSGetEnableStatus (IMM32.@)
|
|
|
|
*/
|
|
|
|
|
|
|
|
BOOL WINAPI ImmWINNLSGetEnableStatus(HWND hWnd)
|
|
|
|
{
|
|
|
|
if (!Imm32IsSystemJapaneseOrKorean())
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2022-03-29 09:05:09 +00:00
|
|
|
return !!ImmGetSaveContext(hWnd, 2);
|
2022-02-10 06:18:44 +00:00
|
|
|
}
|
|
|
|
|
2020-08-08 00:46:13 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmSetActiveContextConsoleIME(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmSetActiveContextConsoleIME(HWND hwnd, BOOL fFlag)
|
|
|
|
{
|
2020-08-09 13:42:17 +00:00
|
|
|
HIMC hIMC;
|
|
|
|
TRACE("(%p, %d)\n", hwnd, fFlag);
|
|
|
|
|
|
|
|
hIMC = ImmGetContext(hwnd);
|
2022-10-23 00:51:24 +00:00
|
|
|
if (IS_NULL_UNEXPECTEDLY(hIMC))
|
|
|
|
return FALSE;
|
|
|
|
return ImmSetActiveContext(hwnd, hIMC, fFlag);
|
|
|
|
}
|
|
|
|
|
2023-12-02 22:46:35 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* GetKeyboardLayoutCP (IMM32.@)
|
|
|
|
*/
|
|
|
|
UINT WINAPI GetKeyboardLayoutCP(_In_ LANGID wLangId)
|
|
|
|
{
|
|
|
|
WCHAR szText[8];
|
|
|
|
static LANGID s_wKeyboardLangIdCache = 0;
|
|
|
|
static UINT s_uKeyboardLayoutCPCache = 0;
|
|
|
|
|
|
|
|
TRACE("(%u)\n", wLangId);
|
|
|
|
|
|
|
|
if (wLangId == s_wKeyboardLangIdCache)
|
|
|
|
return s_uKeyboardLayoutCPCache;
|
|
|
|
|
|
|
|
if (!GetLocaleInfoW(wLangId, LOCALE_IDEFAULTANSICODEPAGE, szText, _countof(szText)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
s_wKeyboardLangIdCache = wLangId;
|
|
|
|
szText[_countof(szText) - 1] = UNICODE_NULL; /* Avoid buffer overrun */
|
|
|
|
s_uKeyboardLayoutCPCache = wcstol(szText, NULL, 10);
|
|
|
|
return s_uKeyboardLayoutCPCache;
|
|
|
|
}
|
|
|
|
|
2022-10-23 00:51:24 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
VOID APIENTRY Imm32UnitTest(VOID)
|
|
|
|
{
|
|
|
|
if (0)
|
|
|
|
{
|
|
|
|
DWORD dwValue;
|
|
|
|
WCHAR szText[64];
|
|
|
|
|
|
|
|
Imm32StrToUInt(L"123", &dwValue, 10);
|
|
|
|
ASSERT(dwValue == 123);
|
|
|
|
Imm32StrToUInt(L"100", &dwValue, 16);
|
|
|
|
ASSERT(dwValue == 0x100);
|
|
|
|
|
|
|
|
Imm32UIntToStr(123, 10, szText, _countof(szText));
|
|
|
|
ASSERT(lstrcmpW(szText, L"123") == 0);
|
|
|
|
Imm32UIntToStr(0x100, 16, szText, _countof(szText));
|
|
|
|
ASSERT(lstrcmpW(szText, L"100") == 0);
|
|
|
|
}
|
2020-08-08 00:46:13 +00:00
|
|
|
}
|
2022-10-23 00:51:24 +00:00
|
|
|
#endif
|
2020-08-09 13:49:00 +00:00
|
|
|
|
2021-08-04 00:41:59 +00:00
|
|
|
BOOL WINAPI User32InitializeImmEntryTable(DWORD);
|
|
|
|
|
2022-10-05 21:19:48 +00:00
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
ImmDllInitialize(
|
2022-11-12 11:25:29 +00:00
|
|
|
_In_ HINSTANCE hDll,
|
2022-10-05 21:19:48 +00:00
|
|
|
_In_ ULONG dwReason,
|
|
|
|
_In_opt_ PVOID pReserved)
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
|
|
|
HKL hKL;
|
2021-08-16 06:33:51 +00:00
|
|
|
HIMC hIMC;
|
2021-08-04 00:41:59 +00:00
|
|
|
|
2022-10-05 21:19:48 +00:00
|
|
|
TRACE("(%p, 0x%X, %p)\n", hDll, dwReason, pReserved);
|
2021-08-04 00:41:59 +00:00
|
|
|
|
2022-10-05 21:19:48 +00:00
|
|
|
switch (dwReason)
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
|
|
|
case DLL_PROCESS_ATTACH:
|
2022-10-05 21:19:48 +00:00
|
|
|
if (!ImmInitializeGlobals(hDll))
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
2022-04-06 06:44:27 +00:00
|
|
|
ERR("ImmInitializeGlobals failed\n");
|
2021-08-04 00:41:59 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
|
|
|
|
{
|
|
|
|
ERR("User32InitializeImmEntryTable failed\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2022-10-23 00:51:24 +00:00
|
|
|
#ifndef NDEBUG
|
|
|
|
Imm32UnitTest();
|
|
|
|
#endif
|
2021-08-04 00:41:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DLL_THREAD_DETACH:
|
2022-02-13 06:51:53 +00:00
|
|
|
if (!IS_IMM_MODE() || NtCurrentTeb()->Win32ThreadInfo == NULL)
|
2021-08-04 00:41:59 +00:00
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
hKL = GetKeyboardLayout(0);
|
2022-01-20 02:49:27 +00:00
|
|
|
hIMC = (HIMC)NtUserGetThreadState(THREADSTATE_DEFAULTINPUTCONTEXT);
|
2022-03-29 10:02:56 +00:00
|
|
|
Imm32DestroyInputContext(hIMC, hKL, TRUE);
|
2021-08-04 00:41:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DLL_PROCESS_DETACH:
|
2022-04-08 09:21:54 +00:00
|
|
|
RtlDeleteCriticalSection(&gcsImeDpi);
|
2021-08-23 07:25:21 +00:00
|
|
|
TRACE("imm32.dll is unloaded\n");
|
2021-08-04 00:41:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|