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>
|
|
|
|
* Copyright 2020 Oleg Dubinskiy <oleg.dubinskij2013@yandex.ua>
|
|
|
|
* Copyright 2020-2021 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"
|
2005-12-12 20:59:55 +00:00
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(imm);
|
|
|
|
|
2021-08-04 00:41:59 +00:00
|
|
|
HMODULE g_hImm32Inst = NULL;
|
2021-07-28 14:25:10 +00:00
|
|
|
PSERVERINFO g_psi = NULL;
|
2021-08-04 00:41:59 +00:00
|
|
|
SHAREDINFO g_SharedInfo = { NULL };
|
|
|
|
BYTE g_bClientRegd = FALSE;
|
2021-08-23 21:50:39 +00:00
|
|
|
|
2021-08-04 00:41:59 +00:00
|
|
|
static BOOL APIENTRY Imm32InitInstance(HMODULE hMod)
|
|
|
|
{
|
|
|
|
NTSTATUS status;
|
|
|
|
|
|
|
|
if (hMod)
|
|
|
|
g_hImm32Inst = hMod;
|
|
|
|
|
|
|
|
if (g_bClientRegd)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
status = RtlInitializeCriticalSection(&g_csImeDpi);
|
|
|
|
if (NT_ERROR(status))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
g_bClientRegd = TRUE;
|
|
|
|
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
|
|
|
{
|
2021-09-10 14:39:15 +00:00
|
|
|
g_SharedInfo = *ptr;
|
|
|
|
g_psi = g_SharedInfo.psi;
|
|
|
|
return Imm32InitInstance(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
|
|
|
{
|
|
|
|
DWORD cbData;
|
|
|
|
HKEY hLayoutKey = NULL, hLayoutsKey = NULL;
|
|
|
|
LONG error;
|
|
|
|
WCHAR szLayout[MAX_PATH];
|
|
|
|
|
2021-08-04 00:49:41 +00:00
|
|
|
TRACE("(%p, %p)\n", hKL, pImeInfoEx);
|
2021-07-28 14:25:10 +00:00
|
|
|
|
2021-09-24 13:06:29 +00:00
|
|
|
if (IS_IME_HKL(hKL) || !Imm32IsCiceroMode() || Imm32Is16BitMode())
|
2021-07-28 14:25:10 +00:00
|
|
|
{
|
2021-10-21 01:28:04 +00:00
|
|
|
Imm32UIntToStr((DWORD)(DWORD_PTR)hKL, 16, szLayout, _countof(szLayout));
|
2021-07-28 14:25:10 +00:00
|
|
|
|
|
|
|
error = RegOpenKeyW(HKEY_LOCAL_MACHINE, REGKEY_KEYBOARD_LAYOUTS, &hLayoutsKey);
|
|
|
|
if (error)
|
2021-10-21 01:28:04 +00:00
|
|
|
{
|
|
|
|
ERR("RegOpenKeyW: 0x%08lX\n", error);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2021-07-28 14:25:10 +00:00
|
|
|
|
|
|
|
error = RegOpenKeyW(hLayoutsKey, szLayout, &hLayoutKey);
|
2021-10-21 01:28:04 +00:00
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
ERR("RegOpenKeyW: 0x%08lX\n", error);
|
|
|
|
RegCloseKey(hLayoutsKey);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2021-07-28 14:25:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error = RegOpenKeyW(HKEY_LOCAL_MACHINE, REGKEY_IMM, &hLayoutKey);
|
|
|
|
if (error)
|
2021-10-21 01:28:04 +00:00
|
|
|
{
|
|
|
|
ERR("RegOpenKeyW: 0x%08lX\n", error);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2021-07-28 14:25:10 +00:00
|
|
|
}
|
|
|
|
|
2021-10-21 01:28:04 +00:00
|
|
|
cbData = sizeof(pImeInfoEx->wszImeFile);
|
|
|
|
error = RegQueryValueExW(hLayoutKey, L"Ime File", 0, 0,
|
|
|
|
(LPBYTE)pImeInfoEx->wszImeFile, &cbData);
|
|
|
|
pImeInfoEx->wszImeFile[_countof(pImeInfoEx->wszImeFile) - 1] = 0;
|
|
|
|
|
2021-07-28 14:25:10 +00:00
|
|
|
RegCloseKey(hLayoutKey);
|
|
|
|
if (hLayoutsKey)
|
|
|
|
RegCloseKey(hLayoutsKey);
|
2021-10-21 01:28:04 +00:00
|
|
|
|
|
|
|
pImeInfoEx->fLoadFlag = 0;
|
|
|
|
|
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
ERR("RegQueryValueExW: 0x%08lX\n", error);
|
|
|
|
pImeInfoEx->hkl = NULL;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pImeInfoEx->hkl = hKL;
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
WCHAR szKBD[9];
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
pList = Imm32HeapAlloc(0, cKLs * sizeof(HKL));
|
|
|
|
if (pList == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
cKLs = GetKeyboardLayoutList(cKLs, pList);
|
|
|
|
for (iKL = 0; iKL < cKLs; ++iKL)
|
|
|
|
{
|
|
|
|
if (!IS_IME_HKL(pList[iKL]))
|
|
|
|
{
|
|
|
|
LangID = LOWORD(pList[iKL]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Imm32HeapFree(pList);
|
|
|
|
}
|
|
|
|
|
|
|
|
StringCchPrintfW(szKBD, _countof(szKBD), L"%08X", LangID);
|
|
|
|
if (!LoadKeyboardLayoutW(szKBD, KLF_ACTIVATE))
|
|
|
|
LoadKeyboardLayoutW(L"00000409", KLF_ACTIVATE | 0x200);
|
|
|
|
}
|
|
|
|
else if (dwUnknown == 2)
|
|
|
|
{
|
|
|
|
RtlEnterCriticalSection(&g_csImeDpi);
|
|
|
|
Retry:
|
|
|
|
for (pImeDpi = g_pImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext)
|
|
|
|
{
|
|
|
|
if (Imm32ReleaseIME(pImeDpi->hKL))
|
|
|
|
goto Retry;
|
|
|
|
}
|
|
|
|
RtlLeaveCriticalSection(&g_csImeDpi);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hNewKL = (HKL)(DWORD_PTR)dwUnknown;
|
|
|
|
if (IS_IME_HKL(hNewKL) && hNewKL != hOldKL)
|
|
|
|
Imm32ReleaseIME(hNewKL);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2021-10-03 22:33:15 +00:00
|
|
|
VOID APIENTRY Imm32SelectLayout(HKL hNewKL, HKL hOldKL, HIMC hIMC)
|
|
|
|
{
|
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
LPINPUTCONTEXTDX pIC;
|
|
|
|
LPGUIDELINE pGL;
|
|
|
|
LPCANDIDATEINFO pCI;
|
|
|
|
LPCOMPOSITIONSTRING pCS;
|
|
|
|
LOGFONTA LogFontA;
|
|
|
|
LOGFONTW LogFontW;
|
|
|
|
BOOL fOpen, bIsNewHKLIme = TRUE, bIsOldHKLIme = TRUE, bClientWide, bNewDpiWide;
|
|
|
|
DWORD cbNewPrivate = 0, cbOldPrivate = 0, dwConversion, dwSentence, dwSize, dwNewSize;
|
|
|
|
PIMEDPI pNewImeDpi = NULL, pOldImeDpi = NULL;
|
|
|
|
HANDLE hPrivate;
|
|
|
|
PIME_STATE pNewState = NULL, pOldState = NULL;
|
|
|
|
|
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
if (!pClientImc)
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2021-10-04 22:57:14 +00:00
|
|
|
if (cbNewPrivate < sizeof(DWORD))
|
|
|
|
cbNewPrivate = sizeof(DWORD);
|
2021-10-03 22:33:15 +00:00
|
|
|
|
|
|
|
if (pOldImeDpi)
|
|
|
|
cbOldPrivate = pOldImeDpi->ImeInfo.dwPrivateDataSize;
|
|
|
|
|
2021-10-04 22:57:14 +00:00
|
|
|
if (cbOldPrivate < sizeof(DWORD))
|
|
|
|
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);
|
|
|
|
else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pOldImeDpi->CtfImeSelectEx)
|
|
|
|
pOldImeDpi->CtfImeSelectEx(hIMC, FALSE, hOldKL);
|
|
|
|
}
|
|
|
|
pClientImc->hKL = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CtfImmIsTextFrameServiceDisabled())
|
|
|
|
{
|
2022-01-26 22:34:29 +00:00
|
|
|
if (IS_IMM_MODE() && !Imm32IsCiceroMode())
|
2021-10-03 22:33:15 +00:00
|
|
|
{
|
|
|
|
bIsNewHKLIme = IS_IME_HKL(hNewKL);
|
|
|
|
bIsOldHKLIme = IS_IME_HKL(hOldKL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pIC = (LPINPUTCONTEXTDX)Imm32LockIMCEx(hIMC, FALSE);
|
|
|
|
if (!pIC)
|
|
|
|
{
|
|
|
|
if (pNewImeDpi)
|
|
|
|
{
|
|
|
|
if (IS_IME_HKL(hNewKL))
|
|
|
|
pNewImeDpi->ImeSelect(hIMC, TRUE);
|
|
|
|
else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pNewImeDpi->CtfImeSelectEx)
|
|
|
|
pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
|
|
|
|
|
|
|
|
pClientImc->hKL = hNewKL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dwConversion = pIC->fdwConversion;
|
|
|
|
dwSentence = pIC->fdwSentence;
|
|
|
|
fOpen = pIC->fOpen;
|
|
|
|
|
|
|
|
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;
|
|
|
|
pOldState->dwConversion = (pIC->fdwConversion & ~IME_CMODE_EUDC);
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
pIC->fdwConversion = (pNewState->dwConversion & ~IME_CMODE_EUDC);
|
|
|
|
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);
|
|
|
|
else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pNewImeDpi->CtfImeSelectEx)
|
|
|
|
pNewImeDpi->CtfImeSelectEx(hIMC, TRUE, hNewKL);
|
|
|
|
|
|
|
|
pClientImc->hKL = hNewKL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pIC->dwChange = 0;
|
|
|
|
if (pIC->fOpen != fOpen)
|
|
|
|
pIC->dwChange |= INPUTCONTEXTDX_CHANGE_OPEN;
|
|
|
|
if (pIC->fdwConversion != dwConversion)
|
|
|
|
pIC->dwChange |= INPUTCONTEXTDX_CHANGE_CONVERSION;
|
|
|
|
if (pIC->fdwSentence != dwSentence)
|
|
|
|
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;
|
|
|
|
|
|
|
|
static BOOL CALLBACK Imm32SelectLayoutProc(HIMC hIMC, LPARAM lParam)
|
|
|
|
{
|
|
|
|
LPSELECT_LAYOUT pSelect = (LPSELECT_LAYOUT)lParam;
|
|
|
|
Imm32SelectLayout(pSelect->hNewKL, pSelect->hOldKL, hIMC);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL CALLBACK Imm32NotifyCompStrProc(HIMC hIMC, LPARAM lParam)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
|
|
|
|
ImmEnumInputContext(0, Imm32NotifyCompStrProc, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
hwndDefIME = ImmGetDefaultIMEWnd(NULL);
|
|
|
|
if (IsWindow(hwndDefIME))
|
|
|
|
SendMessageW(hwndDefIME, WM_IME_SELECT, FALSE, (LPARAM)hOldKL);
|
|
|
|
|
|
|
|
NtUserSetThreadLayoutHandles(hKL, hOldKL);
|
|
|
|
}
|
|
|
|
|
|
|
|
SelectLayout.hNewKL = hKL;
|
|
|
|
SelectLayout.hOldKL = hOldKL;
|
|
|
|
ImmEnumInputContext(0, Imm32SelectLayoutProc, (LPARAM)&SelectLayout);
|
|
|
|
|
|
|
|
if (IsWindow(hwndDefIME))
|
|
|
|
SendMessageW(hwndDefIME, WM_IME_SELECT, TRUE, (LPARAM)hKL);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2021-09-30 18:02:56 +00:00
|
|
|
static VOID APIENTRY Imm32CiceroSetActiveContext(HIMC hIMC, BOOL fActive, HWND hWnd, HKL hKL)
|
|
|
|
{
|
|
|
|
FIXME("We have to do something\n");
|
|
|
|
}
|
|
|
|
|
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())
|
2014-09-28 18:27:58 +00:00
|
|
|
return NULL;
|
|
|
|
|
2021-09-28 13:03:25 +00:00
|
|
|
pWnd = ValidateHwndNoErr(hWnd);
|
|
|
|
if (!pWnd)
|
|
|
|
return NULL;
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2021-09-28 13:03:25 +00:00
|
|
|
if (hIMC && Imm32IsCrossThreadAccess(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);
|
|
|
|
if (dwValue == 0)
|
|
|
|
return hOldIMC;
|
|
|
|
if (dwValue != 1)
|
|
|
|
return NULL;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-09-28 13:03:25 +00:00
|
|
|
hwndFocus = (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_FOCUS);
|
|
|
|
if (hwndFocus == hWnd)
|
2019-01-26 12:10:01 +00:00
|
|
|
{
|
2021-09-28 13:03:25 +00:00
|
|
|
ImmSetActiveContext(hWnd, hOldIMC, FALSE);
|
|
|
|
ImmSetActiveContext(hWnd, hIMC, TRUE);
|
2019-01-26 12:10:01 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2021-09-28 13:03:25 +00:00
|
|
|
return hOldIMC;
|
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())
|
2017-12-08 03:14:21 +00:00
|
|
|
return FALSE;
|
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
|
|
|
|
2021-09-16 10:29:49 +00:00
|
|
|
if (hIMC && !(dwFlags & IACE_DEFAULT) && Imm32IsCrossThreadAccess(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);
|
|
|
|
pFocusWnd = ValidateHwndNoErr(hwndFocus);
|
|
|
|
if (pFocusWnd)
|
|
|
|
hOldIMC = pFocusWnd->hImc;
|
|
|
|
|
|
|
|
dwValue = NtUserAssociateInputContext(hWnd, hIMC, dwFlags);
|
|
|
|
switch (dwValue)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
pFocusWnd = ValidateHwndNoErr(hwndFocus);
|
|
|
|
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())
|
2021-08-04 00:41:59 +00:00
|
|
|
return NULL;
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2021-08-04 00:41:59 +00:00
|
|
|
pClientImc = Imm32HeapAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
|
|
|
|
if (pClientImc == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2022-01-01 11:59:00 +00:00
|
|
|
hIMC = NtUserCreateInputContext((ULONG_PTR)pClientImc);
|
2021-08-04 00:41:59 +00:00
|
|
|
if (hIMC == NULL)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
2021-09-18 16:52:05 +00:00
|
|
|
Imm32HeapFree(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
|
|
|
|
2021-10-03 22:33:15 +00:00
|
|
|
static VOID APIENTRY Imm32FreeImeStates(LPINPUTCONTEXTDX pIC)
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
2021-10-03 22:33:15 +00:00
|
|
|
PIME_STATE pState, pStateNext;
|
|
|
|
PIME_SUBSTATE pSubState, pSubStateNext;
|
|
|
|
|
|
|
|
pState = pIC->pState;
|
|
|
|
pIC->pState = NULL;
|
|
|
|
for (; pState; pState = pStateNext)
|
|
|
|
{
|
|
|
|
pStateNext = pState->pNext;
|
|
|
|
for (pSubState = pState->pSubState; pSubState; pSubState = pSubStateNext)
|
|
|
|
{
|
|
|
|
pSubStateNext = pSubState->pNext;
|
|
|
|
Imm32HeapFree(pSubState);
|
|
|
|
}
|
|
|
|
Imm32HeapFree(pState);
|
|
|
|
}
|
2021-08-04 00:41:59 +00:00
|
|
|
}
|
2014-09-28 18:27:58 +00:00
|
|
|
|
2021-08-04 00:41:59 +00:00
|
|
|
BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
|
|
|
|
{
|
|
|
|
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-01-26 22:34:29 +00:00
|
|
|
if (!IS_IMM_MODE() || hIMC == NULL)
|
2021-08-04 00:41:59 +00:00
|
|
|
return FALSE;
|
|
|
|
|
2021-09-27 00:31:16 +00:00
|
|
|
pIMC = ValidateHandleNoErr(hIMC, TYPE_INPUTCONTEXT);
|
2022-02-13 06:51:53 +00:00
|
|
|
if (!pIMC || pIMC->head.pti != Imm32CurrentPti())
|
|
|
|
{
|
|
|
|
ERR("invalid pIMC: %p\n", pIMC);
|
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;
|
2021-08-04 00:41:59 +00:00
|
|
|
if (!pClientImc)
|
2022-02-13 06:51:53 +00:00
|
|
|
goto Finish;
|
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-02-13 06:51:53 +00:00
|
|
|
ERR("CLIENTIMC_UNKNOWN2\n");
|
|
|
|
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);
|
|
|
|
|
|
|
|
if (!pClientImc->hInputContext)
|
|
|
|
goto Quit;
|
|
|
|
|
2021-10-03 22:33:15 +00:00
|
|
|
pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
|
2022-02-13 06:51:53 +00:00
|
|
|
if (!pIC)
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
2022-02-13 06:51:53 +00:00
|
|
|
ERR("!pIC\n");
|
2021-08-04 00:41:59 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2008-04-04 13:20:27 +00:00
|
|
|
|
2022-02-13 06:51:53 +00:00
|
|
|
pImeDpi = ImmLockImeDpi(hKL);
|
|
|
|
if (pImeDpi)
|
2021-08-04 00:41:59 +00:00
|
|
|
{
|
2022-02-13 06:51:53 +00:00
|
|
|
pImeDpi->ImeSelect(hIMC, FALSE);
|
|
|
|
ImmUnlockImeDpi(pImeDpi);
|
2021-08-04 00:41:59 +00:00
|
|
|
}
|
2005-12-12 20:59:55 +00:00
|
|
|
|
2021-09-27 00:32:24 +00:00
|
|
|
pIC->hPrivate = ImmDestroyIMCC(pIC->hPrivate);
|
|
|
|
pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
|
|
|
|
pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
|
|
|
|
pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
|
|
|
|
pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
|
2021-10-03 22:33:15 +00:00
|
|
|
Imm32FreeImeStates(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
|
|
|
}
|
|
|
|
|
2021-09-27 00:32:24 +00:00
|
|
|
BOOL APIENTRY
|
|
|
|
Imm32InitContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL fSelect)
|
|
|
|
{
|
|
|
|
DWORD dwIndex, cbPrivate;
|
|
|
|
PIMEDPI pImeDpi = NULL;
|
|
|
|
LPCOMPOSITIONSTRING pCS;
|
|
|
|
LPCANDIDATEINFO pCI;
|
|
|
|
LPGUIDELINE pGL;
|
|
|
|
/* NOTE: Windows does recursive call ImmLockIMC here but we don't do so. */
|
|
|
|
|
|
|
|
/* Create IC components */
|
|
|
|
pIC->hCompStr = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
|
|
|
|
pIC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
|
|
|
|
pIC->hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
|
|
|
|
pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
|
|
|
|
if (!pIC->hCompStr || !pIC->hCandInfo || !pIC->hGuideLine || !pIC->hMsgBuf)
|
|
|
|
goto Fail;
|
|
|
|
|
|
|
|
/* Initialize IC components */
|
|
|
|
pCS = ImmLockIMCC(pIC->hCompStr);
|
|
|
|
if (!pCS)
|
|
|
|
goto Fail;
|
|
|
|
pCS->dwSize = sizeof(COMPOSITIONSTRING);
|
|
|
|
ImmUnlockIMCC(pIC->hCompStr);
|
|
|
|
|
|
|
|
pCI = ImmLockIMCC(pIC->hCandInfo);
|
|
|
|
if (!pCI)
|
|
|
|
goto Fail;
|
|
|
|
pCI->dwSize = sizeof(CANDIDATEINFO);
|
|
|
|
ImmUnlockIMCC(pIC->hCandInfo);
|
|
|
|
|
|
|
|
pGL = ImmLockIMCC(pIC->hGuideLine);
|
|
|
|
if (!pGL)
|
|
|
|
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);
|
|
|
|
if (!pIC->hPrivate)
|
|
|
|
goto Fail;
|
|
|
|
|
|
|
|
if (pImeDpi)
|
|
|
|
{
|
|
|
|
/* Select the IME */
|
|
|
|
if (fSelect)
|
|
|
|
{
|
|
|
|
if (IS_IME_HKL(hKL))
|
|
|
|
pImeDpi->ImeSelect(hIMC, TRUE);
|
|
|
|
else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pImeDpi->CtfImeSelectEx)
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
LPINPUTCONTEXT APIENTRY Imm32LockIMCEx(HIMC hIMC, BOOL fSelect)
|
|
|
|
{
|
|
|
|
HANDLE hIC;
|
|
|
|
LPINPUTCONTEXT pIC = NULL;
|
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
WORD Word;
|
|
|
|
DWORD dwThreadId;
|
|
|
|
HKL hKL, hNewKL;
|
|
|
|
PIMEDPI pImeDpi = NULL;
|
|
|
|
BOOL bInited;
|
|
|
|
|
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
if (!pClientImc)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
RtlEnterCriticalSection(&pClientImc->cs);
|
|
|
|
|
|
|
|
if (!pClientImc->hInputContext)
|
|
|
|
{
|
2022-01-01 11:56:50 +00:00
|
|
|
dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
|
2021-09-27 00:32:24 +00:00
|
|
|
|
|
|
|
if (dwThreadId == GetCurrentThreadId() && Imm32IsCiceroMode() && !Imm32Is16BitMode())
|
|
|
|
{
|
|
|
|
hKL = GetKeyboardLayout(0);
|
|
|
|
Word = LOWORD(hKL);
|
|
|
|
hNewKL = (HKL)(DWORD_PTR)MAKELONG(Word, Word);
|
|
|
|
|
|
|
|
pImeDpi = ImmLockOrLoadImeDpi(hNewKL);
|
|
|
|
if (pImeDpi)
|
|
|
|
{
|
|
|
|
FIXME("We have to do something here\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-01 11:56:50 +00:00
|
|
|
if (!NtUserQueryInputContext(hIMC, QIC_DEFAULTWINDOWIME))
|
2021-09-27 00:32:24 +00:00
|
|
|
{
|
|
|
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
|
|
|
goto Quit;
|
|
|
|
}
|
|
|
|
|
|
|
|
hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
|
|
|
|
if (!hIC)
|
|
|
|
{
|
|
|
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
|
|
|
goto Quit;
|
|
|
|
}
|
|
|
|
pClientImc->hInputContext = hIC;
|
|
|
|
|
|
|
|
pIC = LocalLock(pClientImc->hInputContext);
|
|
|
|
if (!pIC)
|
|
|
|
{
|
|
|
|
pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
|
|
|
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
|
|
|
goto Quit;
|
|
|
|
}
|
|
|
|
|
|
|
|
hKL = GetKeyboardLayout(dwThreadId);
|
|
|
|
// bInited = Imm32InitContext(hIMC, hKL, fSelect);
|
|
|
|
bInited = Imm32InitContext(hIMC, pIC, pClientImc, hKL, fSelect);
|
|
|
|
LocalUnlock(pClientImc->hInputContext);
|
|
|
|
|
|
|
|
if (!bInited)
|
|
|
|
{
|
|
|
|
pIC = NULL;
|
|
|
|
pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
|
|
|
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
|
|
|
goto Quit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FIXME("We have to do something here\n");
|
|
|
|
|
|
|
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
|
|
|
pIC = LocalLock(pClientImc->hInputContext);
|
|
|
|
InterlockedIncrement(&pClientImc->cLockObj);
|
|
|
|
|
|
|
|
Quit:
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return pIC;
|
|
|
|
}
|
|
|
|
|
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())
|
2010-03-07 11:27:14 +00:00
|
|
|
return FALSE;
|
2021-08-04 00:41:59 +00:00
|
|
|
|
2021-08-14 01:38:06 +00:00
|
|
|
if (Imm32IsCrossThreadAccess(hIMC))
|
2021-08-04 00:41:59 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
hKL = GetKeyboardLayout(0);
|
|
|
|
return Imm32CleanupContext(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
|
|
|
|
|
|
|
if (hImc == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2021-09-27 00:31:16 +00:00
|
|
|
pIMC = ValidateHandleNoErr(hImc, TYPE_INPUTCONTEXT);
|
|
|
|
if (pIMC == NULL || !Imm32CheckImcProcess(pIMC))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
|
2021-07-11 00:48:15 +00:00
|
|
|
if (!pClientImc)
|
|
|
|
{
|
|
|
|
pClientImc = Imm32HeapAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
|
|
|
|
if (!pClientImc)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
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-07-11 00:48:15 +00:00
|
|
|
|
2022-01-01 11:57:51 +00:00
|
|
|
if (!NtUserUpdateInputContext(hImc, UIC_CLIENTIMCDATA, (DWORD_PTR)pClientImc))
|
2021-07-11 00:48:15 +00:00
|
|
|
{
|
2021-09-18 16:52:05 +00:00
|
|
|
Imm32HeapFree(pClientImc);
|
2021-07-11 00:48:15 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-03-03 07:17:07 +00:00
|
|
|
if (pClientImc->dwFlags & CLIENTIMC_DESTROY)
|
2021-07-11 00:48:15 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2021-09-18 16:52:05 +00:00
|
|
|
Imm32HeapFree(pClientImc);
|
2021-07-11 00:48:15 +00:00
|
|
|
}
|
|
|
|
|
2021-08-23 21:50:39 +00:00
|
|
|
static HIMC APIENTRY Imm32GetContextEx(HWND hWnd, DWORD dwContextFlags)
|
|
|
|
{
|
|
|
|
HIMC hIMC;
|
|
|
|
PCLIENTIMC pClientImc;
|
|
|
|
PWND pWnd;
|
|
|
|
|
2022-01-26 22:34:29 +00:00
|
|
|
if (!IS_IMM_MODE())
|
2021-08-23 21:50:39 +00:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
pWnd = ValidateHwndNoErr(hWnd);
|
|
|
|
if (!pWnd || Imm32IsCrossProcessAccess(hWnd))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
hIMC = pWnd->hImc;
|
|
|
|
if (!hIMC && (dwContextFlags & 1))
|
|
|
|
hIMC = (HIMC)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_ICONTEXT);
|
|
|
|
|
|
|
|
Quit:
|
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
if (pClientImc == NULL)
|
|
|
|
return NULL;
|
|
|
|
if ((dwContextFlags & 2) && (pClientImc->dwFlags & CLIENTIMC_UNKNOWN3))
|
|
|
|
hIMC = NULL;
|
|
|
|
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);
|
|
|
|
if (hWnd == NULL)
|
2011-12-15 00:40:35 +00:00
|
|
|
return NULL;
|
2021-08-23 21:50:39 +00:00
|
|
|
return Imm32GetContextEx(hWnd, 2);
|
2005-12-12 20:59:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
2021-09-10 14:39:15 +00:00
|
|
|
* CtfImmIsCiceroEnabled (IMM32.@)
|
2005-12-12 20:59:55 +00:00
|
|
|
*/
|
2021-09-10 14:39:15 +00:00
|
|
|
BOOL WINAPI CtfImmIsCiceroEnabled(VOID)
|
2005-12-12 20:59:55 +00:00
|
|
|
{
|
2021-09-24 13:06:29 +00:00
|
|
|
return Imm32IsCiceroMode();
|
2021-09-10 14:39:15 +00:00
|
|
|
}
|
2021-08-12 03:32:02 +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);
|
|
|
|
return Imm32LockIMCEx(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);
|
|
|
|
if (pClientImc == NULL)
|
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
|
|
|
}
|
|
|
|
|
2021-09-10 14:39:15 +00:00
|
|
|
/***********************************************************************
|
|
|
|
* ImmCreateSoftKeyboard(IMM32.@)
|
|
|
|
*/
|
|
|
|
HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
|
|
|
|
{
|
|
|
|
FIXME("(%d, %d, %d, %d): stub\n", uType, hOwner, x, y);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmDestroySoftKeyboard(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
|
|
|
|
{
|
|
|
|
TRACE("(%p)\n", hSoftWnd);
|
|
|
|
return DestroyWindow(hSoftWnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmShowSoftKeyboard(IMM32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
|
|
|
|
{
|
|
|
|
TRACE("(%p, %d)\n", hSoftWnd, nCmdShow);
|
|
|
|
if (hSoftWnd)
|
|
|
|
return ShowWindow(hSoftWnd, nCmdShow);
|
|
|
|
return FALSE;
|
2010-03-07 11:27:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* ImmDisableTextFrameService(IMM32.@)
|
|
|
|
*/
|
2021-07-28 23:21:33 +00:00
|
|
|
BOOL WINAPI ImmDisableTextFrameService(DWORD dwThreadId)
|
2010-03-07 11:27:14 +00:00
|
|
|
{
|
|
|
|
FIXME("Stub\n");
|
|
|
|
return FALSE;
|
2005-12-12 20:59:55 +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
|
|
|
|
|
|
|
dwCount = Imm32AllocAndBuildHimcList(dwThreadId, &phList);
|
|
|
|
if (!dwCount)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (dwIndex = 0; dwIndex < dwCount; ++dwIndex)
|
|
|
|
{
|
|
|
|
hIMC = phList[dwIndex];
|
|
|
|
ret = (*lpfn)(hIMC, lParam);
|
|
|
|
if (!ret)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-09-18 16:52:05 +00:00
|
|
|
Imm32HeapFree(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;
|
|
|
|
HKL hKL;
|
|
|
|
BOOL fOpen = FALSE;
|
|
|
|
DWORD dwConversion = 0, iShow = ISC_SHOWUIALL;
|
|
|
|
HWND hwndDefIME;
|
|
|
|
|
|
|
|
TRACE("(%p, %p, %d)\n", hWnd, hIMC, fActive);
|
|
|
|
|
2022-01-26 22:34:29 +00:00
|
|
|
if (!IS_IMM_MODE())
|
2021-09-30 18:02:56 +00:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
pClientImc = ImmLockClientImc(hIMC);
|
|
|
|
|
|
|
|
if (!fActive)
|
|
|
|
{
|
|
|
|
if (pClientImc)
|
|
|
|
pClientImc->dwFlags &= ~CLIENTIMC_UNKNOWN4;
|
|
|
|
}
|
|
|
|
else if (hIMC)
|
|
|
|
{
|
|
|
|
if (!pClientImc)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
|
|
|
|
if (!pIC)
|
|
|
|
{
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pIC->hWnd = hWnd;
|
|
|
|
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN5;
|
|
|
|
|
|
|
|
if (pIC->dwUIFlags & 2)
|
|
|
|
iShow = (ISC_SHOWUIGUIDELINE | ISC_SHOWUIALLCANDIDATEWINDOW);
|
|
|
|
|
|
|
|
fOpen = pIC->fOpen;
|
|
|
|
dwConversion = pIC->fdwConversion;
|
|
|
|
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-10 06:18:44 +00:00
|
|
|
hIMC = Imm32GetContextEx(hWnd, 1);
|
2021-09-30 18:02:56 +00:00
|
|
|
pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
|
|
|
|
if (pIC)
|
|
|
|
{
|
|
|
|
pIC->hWnd = hWnd;
|
|
|
|
ImmUnlockIMC(hIMC);
|
|
|
|
}
|
|
|
|
hIMC = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
hKL = GetKeyboardLayout(0);
|
|
|
|
|
|
|
|
if (Imm32IsCiceroMode() && !Imm32Is16BitMode())
|
|
|
|
{
|
|
|
|
Imm32CiceroSetActiveContext(hIMC, fActive, hWnd, hKL);
|
|
|
|
hKL = GetKeyboardLayout(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
pImeDpi = ImmLockImeDpi(hKL);
|
|
|
|
if (pImeDpi)
|
|
|
|
{
|
|
|
|
if (IS_IME_HKL(hKL))
|
|
|
|
pImeDpi->ImeSetActiveContext(hIMC, fActive);
|
|
|
|
ImmUnlockImeDpi(pImeDpi);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IsWindow(hWnd))
|
|
|
|
{
|
|
|
|
SendMessageW(hWnd, WM_IME_SETCONTEXT, fActive, iShow);
|
|
|
|
if (fActive)
|
|
|
|
NtUserNotifyIMEStatus(hWnd, fOpen, dwConversion);
|
|
|
|
}
|
|
|
|
else if (!fActive)
|
|
|
|
{
|
|
|
|
hwndDefIME = ImmGetDefaultIMEWnd(NULL);
|
|
|
|
if (hwndDefIME)
|
|
|
|
SendMessageW(hwndDefIME, WM_IME_SETCONTEXT, 0, iShow);
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !!Imm32GetContextEx(hWnd, 2);
|
|
|
|
}
|
|
|
|
|
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);
|
2020-08-08 00:46:13 +00:00
|
|
|
if (hIMC)
|
|
|
|
return ImmSetActiveContext(hwnd, hIMC, fFlag);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2020-08-09 13:49:00 +00:00
|
|
|
|
2021-08-04 00:41:59 +00:00
|
|
|
BOOL WINAPI User32InitializeImmEntryTable(DWORD);
|
|
|
|
|
|
|
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
|
|
|
|
{
|
|
|
|
HKL hKL;
|
2021-08-16 06:33:51 +00:00
|
|
|
HIMC hIMC;
|
2021-08-04 00:41:59 +00:00
|
|
|
|
2021-08-04 00:49:41 +00:00
|
|
|
TRACE("(%p, 0x%X, %p)\n", hinstDLL, fdwReason, lpReserved);
|
2021-08-04 00:41:59 +00:00
|
|
|
|
|
|
|
switch (fdwReason)
|
|
|
|
{
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
if (!Imm32InitInstance(hinstDLL))
|
|
|
|
{
|
|
|
|
ERR("Imm32InitInstance failed\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
|
|
|
|
{
|
|
|
|
ERR("User32InitializeImmEntryTable failed\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
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);
|
2021-08-16 06:33:51 +00:00
|
|
|
Imm32CleanupContext(hIMC, hKL, TRUE);
|
2021-08-04 00:41:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
RtlDeleteCriticalSection(&g_csImeDpi);
|
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;
|
|
|
|
}
|