https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b4557a60a98b4d188c0583...
commit b4557a60a98b4d188c058388395177b36994572e Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Fri Sep 10 23:39:15 2021 +0900 Commit: GitHub noreply@github.com CommitDate: Fri Sep 10 23:39:15 2021 +0900
[IMM32] Restructure! (Retry) (#3952)
The imm.c file became big and bloated, so we split the source file. CORE-11700 - Split the IMM32 code and do formatting. --- dll/win32/imm32/CMakeLists.txt | 15 +- dll/win32/imm32/candidate.c | 406 ++++ dll/win32/imm32/guideline.c | 198 ++ dll/win32/imm32/ime.c | 1201 +++++++++++ dll/win32/imm32/imm.c | 4507 +++++----------------------------------- dll/win32/imm32/keymsg.c | 688 ++++++ dll/win32/imm32/nt3.c | 205 ++ dll/win32/imm32/precomp.h | 103 + dll/win32/imm32/regword.c | 520 +++++ dll/win32/imm32/utils.c | 276 +++ 10 files changed, 4103 insertions(+), 4016 deletions(-)
diff --git a/dll/win32/imm32/CMakeLists.txt b/dll/win32/imm32/CMakeLists.txt index 9ccdcd26f20..bb50a71ab63 100644 --- a/dll/win32/imm32/CMakeLists.txt +++ b/dll/win32/imm32/CMakeLists.txt @@ -1,14 +1,21 @@
-include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_definitions(-D__WINESRC__) +include_directories( + ${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine + ${REACTOS_SOURCE_DIR}/win32ss/include)
-remove_definitions(-D_WIN32_WINNT=0x502) -add_definitions(-D_WIN32_WINNT=0x600) +add_definitions(-D__WINESRC__)
spec2def(imm32.dll imm32.spec ADD_IMPORTLIB)
list(APPEND SOURCE + candidate.c + guideline.c + ime.c imm.c + keymsg.c + nt3.c + regword.c + utils.c ${CMAKE_CURRENT_BINARY_DIR}/imm32_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/imm32.def)
diff --git a/dll/win32/imm32/candidate.c b/dll/win32/imm32/candidate.c new file mode 100644 index 00000000000..43f4e8d03c1 --- /dev/null +++ b/dll/win32/imm32/candidate.c @@ -0,0 +1,406 @@ +/* + * PROJECT: ReactOS IMM32 + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Implementing IMM32 candidate lists + * COPYRIGHT: Copyright 2020-2021 Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com + */ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(imm); + +DWORD APIENTRY +CandidateListWideToAnsi(const CANDIDATELIST *pWideCL, LPCANDIDATELIST pAnsiCL, DWORD dwBufLen, + UINT uCodePage) +{ + BOOL bUsedDefault; + DWORD dwSize, dwIndex, cbGot, cbLeft; + const BYTE *pbWide; + LPBYTE pbAnsi; + LPDWORD pibOffsets; + + /* calculate total ansi size */ + if (pWideCL->dwCount > 0) + { + dwSize = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * sizeof(DWORD)); + for (dwIndex = 0; dwIndex < pWideCL->dwCount; ++dwIndex) + { + pbWide = (const BYTE *)pWideCL + pWideCL->dwOffset[dwIndex]; + cbGot = WideCharToMultiByte(uCodePage, 0, (LPCWSTR)pbWide, -1, NULL, 0, + NULL, &bUsedDefault); + dwSize += cbGot; + } + } + else + { + dwSize = sizeof(CANDIDATELIST); + } + + dwSize = ROUNDUP4(dwSize); + if (dwBufLen == 0) + return dwSize; + if (dwBufLen < dwSize) + return 0; + + /* store to ansi */ + pAnsiCL->dwSize = dwBufLen; + pAnsiCL->dwStyle = pWideCL->dwStyle; + pAnsiCL->dwCount = pWideCL->dwCount; + pAnsiCL->dwSelection = pWideCL->dwSelection; + pAnsiCL->dwPageStart = pWideCL->dwPageStart; + pAnsiCL->dwPageSize = pWideCL->dwPageSize; + + pibOffsets = pAnsiCL->dwOffset; + if (pWideCL->dwCount > 0) + { + pibOffsets[0] = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * sizeof(DWORD)); + cbLeft = dwBufLen - pibOffsets[0]; + + for (dwIndex = 0; dwIndex < pWideCL->dwCount; ++dwIndex) + { + pbWide = (const BYTE *)pWideCL + pWideCL->dwOffset[dwIndex]; + pbAnsi = (LPBYTE)pAnsiCL + pibOffsets[dwIndex]; + + /* convert to ansi */ + cbGot = WideCharToMultiByte(uCodePage, 0, (LPCWSTR)pbWide, -1, + (LPSTR)pbAnsi, cbLeft, NULL, &bUsedDefault); + cbLeft -= cbGot; + + if (dwIndex < pWideCL->dwCount - 1) + pibOffsets[dwIndex + 1] = pibOffsets[dwIndex] + cbGot; + } + } + else + { + pibOffsets[0] = sizeof(CANDIDATELIST); + } + + return dwBufLen; +} + +DWORD APIENTRY +CandidateListAnsiToWide(const CANDIDATELIST *pAnsiCL, LPCANDIDATELIST pWideCL, DWORD dwBufLen, + UINT uCodePage) +{ + DWORD dwSize, dwIndex, cchGot, cbGot, cbLeft; + const BYTE *pbAnsi; + LPBYTE pbWide; + LPDWORD pibOffsets; + + /* calculate total wide size */ + if (pAnsiCL->dwCount > 0) + { + dwSize = sizeof(CANDIDATELIST) + ((pAnsiCL->dwCount - 1) * sizeof(DWORD)); + for (dwIndex = 0; dwIndex < pAnsiCL->dwCount; ++dwIndex) + { + pbAnsi = (const BYTE *)pAnsiCL + pAnsiCL->dwOffset[dwIndex]; + cchGot = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, (LPCSTR)pbAnsi, -1, NULL, 0); + dwSize += cchGot * sizeof(WCHAR); + } + } + else + { + dwSize = sizeof(CANDIDATELIST); + } + + dwSize = ROUNDUP4(dwSize); + if (dwBufLen == 0) + return dwSize; + if (dwBufLen < dwSize) + return 0; + + /* store to wide */ + pWideCL->dwSize = dwBufLen; + pWideCL->dwStyle = pAnsiCL->dwStyle; + pWideCL->dwCount = pAnsiCL->dwCount; + pWideCL->dwSelection = pAnsiCL->dwSelection; + pWideCL->dwPageStart = pAnsiCL->dwPageStart; + pWideCL->dwPageSize = pAnsiCL->dwPageSize; + + pibOffsets = pWideCL->dwOffset; + if (pAnsiCL->dwCount > 0) + { + pibOffsets[0] = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * sizeof(DWORD)); + cbLeft = dwBufLen - pibOffsets[0]; + + for (dwIndex = 0; dwIndex < pAnsiCL->dwCount; ++dwIndex) + { + pbAnsi = (const BYTE *)pAnsiCL + pAnsiCL->dwOffset[dwIndex]; + pbWide = (LPBYTE)pWideCL + pibOffsets[dwIndex]; + + /* convert to wide */ + cchGot = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, (LPCSTR)pbAnsi, -1, + (LPWSTR)pbWide, cbLeft / sizeof(WCHAR)); + cbGot = cchGot * sizeof(WCHAR); + cbLeft -= cbGot; + + if (dwIndex + 1 < pAnsiCL->dwCount) + pibOffsets[dwIndex + 1] = pibOffsets[dwIndex] + cbGot; + } + } + else + { + pibOffsets[0] = sizeof(CANDIDATELIST); + } + + return dwBufLen; +} + +static DWORD APIENTRY +ImmGetCandidateListAW(HIMC hIMC, DWORD dwIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen, + BOOL bAnsi) +{ + DWORD ret = 0; + LPINPUTCONTEXT pIC; + PCLIENTIMC pClientImc; + LPCANDIDATEINFO pCI; + LPCANDIDATELIST pCL; + DWORD dwSize; + + pClientImc = ImmLockClientImc(hIMC); + if (!pClientImc) + return 0; + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + { + ImmUnlockClientImc(pClientImc); + return 0; + } + + pCI = ImmLockIMCC(pIC->hCandInfo); + if (pCI == NULL) + { + ImmUnlockIMC(hIMC); + ImmUnlockClientImc(pClientImc); + return 0; + } + + if (pCI->dwSize < sizeof(CANDIDATEINFO) || pCI->dwCount <= dwIndex) + goto Quit; + + /* get required size */ + pCL = (LPCANDIDATELIST)((LPBYTE)pCI + pCI->dwOffset[dwIndex]); + if (bAnsi) + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + dwSize = CandidateListAnsiToWide(pCL, NULL, 0, CP_ACP); + else + dwSize = pCL->dwSize; + } + else + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + dwSize = pCL->dwSize; + else + dwSize = CandidateListWideToAnsi(pCL, NULL, 0, CP_ACP); + } + + if (dwBufLen != 0 && dwSize != 0) + { + if (lpCandList == NULL || dwBufLen < dwSize) + goto Quit; + + /* store */ + if (bAnsi) + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + CandidateListAnsiToWide(pCL, lpCandList, dwSize, CP_ACP); + else + RtlCopyMemory(lpCandList, pCL, dwSize); + } + else + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + RtlCopyMemory(lpCandList, pCL, dwSize); + else + CandidateListWideToAnsi(pCL, lpCandList, dwSize, CP_ACP); + } + } + + ret = dwSize; + +Quit: + ImmUnlockIMCC(pIC->hCandInfo); + ImmUnlockIMC(hIMC); + ImmUnlockClientImc(pClientImc); + return ret; +} + +DWORD APIENTRY +ImmGetCandidateListCountAW(HIMC hIMC, LPDWORD lpdwListCount, BOOL bAnsi) +{ + DWORD ret = 0, cbGot, dwIndex; + PCLIENTIMC pClientImc; + LPINPUTCONTEXT pIC; + const CANDIDATEINFO *pCI; + const BYTE *pb; + const CANDIDATELIST *pCL; + const DWORD *pdwOffsets; + + if (lpdwListCount == NULL) + return 0; + + *lpdwListCount = 0; + + pClientImc = ImmLockClientImc(hIMC); + if (pClientImc == NULL) + return 0; + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + { + ImmUnlockClientImc(pClientImc); + return 0; + } + + pCI = ImmLockIMCC(pIC->hCandInfo); + if (pCI == NULL) + { + ImmUnlockIMC(hIMC); + ImmUnlockClientImc(pClientImc); + return 0; + } + + if (pCI->dwSize < sizeof(CANDIDATEINFO)) + goto Quit; + + *lpdwListCount = pCI->dwCount; /* the number of candidate lists */ + + /* calculate total size of candidate lists */ + if (bAnsi) + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + { + ret = ROUNDUP4(pCI->dwPrivateSize); + pdwOffsets = pCI->dwOffset; + for (dwIndex = 0; dwIndex < pCI->dwCount; ++dwIndex) + { + pb = (const BYTE *)pCI + pdwOffsets[dwIndex]; + pCL = (const CANDIDATELIST *)pb; + cbGot = CandidateListWideToAnsi(pCL, NULL, 0, CP_ACP); + ret += cbGot; + } + } + else + { + ret = pCI->dwSize; + } + } + else + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + { + ret = pCI->dwSize; + } + else + { + ret = ROUNDUP4(pCI->dwPrivateSize); + pdwOffsets = pCI->dwOffset; + for (dwIndex = 0; dwIndex < pCI->dwCount; ++dwIndex) + { + pb = (const BYTE *)pCI + pdwOffsets[dwIndex]; + pCL = (const CANDIDATELIST *)pb; + cbGot = CandidateListAnsiToWide(pCL, NULL, 0, CP_ACP); + ret += cbGot; + } + } + } + +Quit: + ImmUnlockIMCC(pIC->hCandInfo); + ImmUnlockIMC(hIMC); + ImmUnlockClientImc(pClientImc); + return ret; +} + +/*********************************************************************** + * ImmGetCandidateListA (IMM32.@) + */ +DWORD WINAPI +ImmGetCandidateListA(HIMC hIMC, DWORD dwIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen) +{ + return ImmGetCandidateListAW(hIMC, dwIndex, lpCandList, dwBufLen, TRUE); +} + +/*********************************************************************** + * ImmGetCandidateListCountA (IMM32.@) + */ +DWORD WINAPI ImmGetCandidateListCountA(HIMC hIMC, LPDWORD lpdwListCount) +{ + return ImmGetCandidateListCountAW(hIMC, lpdwListCount, TRUE); +} + +/*********************************************************************** + * ImmGetCandidateListCountW (IMM32.@) + */ +DWORD WINAPI ImmGetCandidateListCountW(HIMC hIMC, LPDWORD lpdwListCount) +{ + return ImmGetCandidateListCountAW(hIMC, lpdwListCount, FALSE); +} + +/*********************************************************************** + * ImmGetCandidateListW (IMM32.@) + */ +DWORD WINAPI +ImmGetCandidateListW(HIMC hIMC, DWORD dwIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen) +{ + return ImmGetCandidateListAW(hIMC, dwIndex, lpCandList, dwBufLen, FALSE); +} + +/*********************************************************************** + * ImmGetCandidateWindow (IMM32.@) + */ +BOOL WINAPI +ImmGetCandidateWindow(HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate) +{ + BOOL ret = FALSE; + LPINPUTCONTEXT pIC; + LPCANDIDATEFORM pCF; + + TRACE("(%p, %lu, %p)\n", hIMC, dwIndex, lpCandidate); + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + pCF = &pIC->cfCandForm[dwIndex]; + if (pCF->dwIndex != IMM_INVALID_CANDFORM) + { + *lpCandidate = *pCF; + ret = TRUE; + } + + ImmUnlockIMC(hIMC); + return ret; +} + +/*********************************************************************** + * ImmSetCandidateWindow (IMM32.@) + */ +BOOL WINAPI ImmSetCandidateWindow(HIMC hIMC, LPCANDIDATEFORM lpCandidate) +{ + HWND hWnd; + LPINPUTCONTEXT pIC; + + TRACE("(%p, %p)\n", hIMC, lpCandidate); + + if (lpCandidate->dwIndex >= MAX_CANDIDATEFORM) + return FALSE; + + if (Imm32IsCrossThreadAccess(hIMC)) + return FALSE; + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + hWnd = pIC->hWnd; + pIC->cfCandForm[lpCandidate->dwIndex] = *lpCandidate; + + ImmUnlockIMC(hIMC); + + Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS, + IMN_SETCANDIDATEPOS, (1 << (BYTE)lpCandidate->dwIndex)); + return TRUE; +} diff --git a/dll/win32/imm32/guideline.c b/dll/win32/imm32/guideline.c new file mode 100644 index 00000000000..3a9a3c6bae1 --- /dev/null +++ b/dll/win32/imm32/guideline.c @@ -0,0 +1,198 @@ +/* + * PROJECT: ReactOS IMM32 + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Implementing IMM32 guidelines + * COPYRIGHT: Copyright 2020-2021 Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com + */ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(imm); + +DWORD APIENTRY +ImmGetGuideLineAW(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsi) +{ + PCLIENTIMC pClientImc; + LPINPUTCONTEXT pIC; + LPGUIDELINE pGuideLine; + DWORD cb, ret = 0; + LPVOID pvStr, pvPrivate; + BOOL bUsedDefault; + + pClientImc = ImmLockClientImc(hIMC); + if (!pClientImc) + return 0; + + pIC = ImmLockIMC(hIMC); + if (!pIC) + { + ImmUnlockClientImc(pClientImc); + return 0; + } + + pGuideLine = ImmLockIMCC(pIC->hGuideLine); + if (!pGuideLine) + { + ImmUnlockIMC(hIMC); + ImmUnlockClientImc(pClientImc); + return 0; + } + + if (dwIndex == GGL_LEVEL) + { + ret = pGuideLine->dwLevel; + goto Quit; + } + + if (dwIndex == GGL_INDEX) + { + ret = pGuideLine->dwIndex; + goto Quit; + } + + if (dwIndex == GGL_STRING) + { + pvStr = (LPBYTE)pGuideLine + pGuideLine->dwStrOffset; + + /* get size */ + if (bAnsi) + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + { + cb = WideCharToMultiByte(CP_ACP, 0, pvStr, pGuideLine->dwStrLen, + NULL, 0, NULL, &bUsedDefault); + } + else + { + cb = pGuideLine->dwStrLen * sizeof(CHAR); + } + } + else + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + { + cb = pGuideLine->dwStrLen * sizeof(WCHAR); + } + else + { + cb = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pvStr, pGuideLine->dwStrLen, + NULL, 0) * sizeof(WCHAR); + } + } + + if (dwBufLen == 0 || cb == 0 || lpBuf == NULL || dwBufLen < cb) + { + ret = cb; + goto Quit; + } + + /* store to buffer */ + if (bAnsi) + { + if (pClientImc->dwFlags & CLIENTIMC_WIDE) + { + ret = WideCharToMultiByte(CP_ACP, 0, pvStr, pGuideLine->dwStrLen, + lpBuf, dwBufLen, NULL, &bUsedDefault); + goto Quit; + } + } + else + { + if (!(pClientImc->dwFlags & CLIENTIMC_WIDE)) + { + ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pvStr, pGuideLine->dwStrLen, + lpBuf, dwBufLen) * sizeof(WCHAR); + goto Quit; + } + } + + RtlCopyMemory(lpBuf, pvStr, cb); + ret = cb; + goto Quit; + } + + if (dwIndex == GGL_PRIVATE) + { + pvPrivate = (LPBYTE)pGuideLine + pGuideLine->dwPrivateOffset; + + /* get size */ + if (bAnsi) + { + if ((pClientImc->dwFlags & CLIENTIMC_WIDE) && + pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) + { + cb = CandidateListWideToAnsi(pvPrivate, NULL, 0, CP_ACP); + } + else + { + cb = pGuideLine->dwPrivateSize; + } + } + else + { + if (!(pClientImc->dwFlags & CLIENTIMC_WIDE) && + pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) + { + cb = CandidateListAnsiToWide(pvPrivate, NULL, 0, CP_ACP); + } + else + { + cb = pGuideLine->dwPrivateSize; + } + } + + if (dwBufLen == 0 || cb == 0 || lpBuf == NULL || dwBufLen < cb) + { + ret = cb; + goto Quit; + } + + /* store to buffer */ + if (bAnsi) + { + if ((pClientImc->dwFlags & CLIENTIMC_WIDE) && + pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) + { + ret = CandidateListWideToAnsi(pvPrivate, lpBuf, cb, CP_ACP); + goto Quit; + } + } + else + { + if (!(pClientImc->dwFlags & CLIENTIMC_WIDE) && + pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) + { + ret = CandidateListAnsiToWide(pvPrivate, lpBuf, cb, CP_ACP); + goto Quit; + } + } + + RtlCopyMemory(lpBuf, pvPrivate, cb); + ret = cb; + goto Quit; + } + +Quit: + ImmUnlockIMCC(pIC->hGuideLine); + ImmUnlockIMC(hIMC); + ImmUnlockClientImc(pClientImc); + return ret; +} + +/*********************************************************************** + * ImmGetGuideLineA (IMM32.@) + */ +DWORD WINAPI ImmGetGuideLineA(HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen) +{ + TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen); + return ImmGetGuideLineAW(hIMC, dwIndex, lpBuf, dwBufLen, TRUE); +} + +/*********************************************************************** + * ImmGetGuideLineW (IMM32.@) + */ +DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen) +{ + TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen); + return ImmGetGuideLineAW(hIMC, dwIndex, lpBuf, dwBufLen, FALSE); +} diff --git a/dll/win32/imm32/ime.c b/dll/win32/imm32/ime.c new file mode 100644 index 00000000000..ba68a9ab3d1 --- /dev/null +++ b/dll/win32/imm32/ime.c @@ -0,0 +1,1201 @@ +/* + * PROJECT: ReactOS IMM32 + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Implementing IME manipulation of IMM32 + * 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 + */ + +#include "precomp.h" + +WINE_DEFAULT_DEBUG_CHANNEL(imm); + +RTL_CRITICAL_SECTION g_csImeDpi; +PIMEDPI g_pImeDpiList = NULL; + +PIMEDPI APIENTRY Imm32FindImeDpi(HKL hKL) +{ + PIMEDPI pImeDpi; + + RtlEnterCriticalSection(&g_csImeDpi); + for (pImeDpi = g_pImeDpiList; pImeDpi != NULL; pImeDpi = pImeDpi->pNext) + { + if (pImeDpi->hKL == hKL) + break; + } + RtlLeaveCriticalSection(&g_csImeDpi); + + return pImeDpi; +} + +VOID APIENTRY Imm32FreeImeDpi(PIMEDPI pImeDpi, BOOL bDestroy) +{ + if (pImeDpi->hInst == NULL) + return; + if (bDestroy) + pImeDpi->ImeDestroy(0); + FreeLibrary(pImeDpi->hInst); + pImeDpi->hInst = NULL; +} + +BOOL APIENTRY Imm32InquireIme(PIMEDPI pImeDpi) +{ + WCHAR szUIClass[64]; + WNDCLASSW wcW; + DWORD dwSysInfoFlags = 0; // TODO: ??? + LPIMEINFO pImeInfo = &pImeDpi->ImeInfo; + + // TODO: NtUserGetThreadState(16); + + if (!IS_IME_HKL(pImeDpi->hKL)) + { + if (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED) && + pImeDpi->CtfImeInquireExW) + { + // TODO: + return FALSE; + } + } + + if (!pImeDpi->ImeInquire(pImeInfo, szUIClass, dwSysInfoFlags)) + return FALSE; + + szUIClass[_countof(szUIClass) - 1] = 0; + + if (pImeInfo->dwPrivateDataSize == 0) + pImeInfo->dwPrivateDataSize = 4; + +#define VALID_IME_PROP (IME_PROP_AT_CARET | \ + IME_PROP_SPECIAL_UI | \ + IME_PROP_CANDLIST_START_FROM_1 | \ + IME_PROP_UNICODE | \ + IME_PROP_COMPLETE_ON_UNSELECT | \ + IME_PROP_END_UNLOAD | \ + IME_PROP_KBD_CHAR_FIRST | \ + IME_PROP_IGNORE_UPKEYS | \ + IME_PROP_NEED_ALTKEY | \ + IME_PROP_NO_KEYS_ON_CLOSE | \ + IME_PROP_ACCEPT_WIDE_VKEY) +#define VALID_CMODE_CAPS (IME_CMODE_ALPHANUMERIC | \ + IME_CMODE_NATIVE | \ + IME_CMODE_KATAKANA | \ + IME_CMODE_LANGUAGE | \ + IME_CMODE_FULLSHAPE | \ + IME_CMODE_ROMAN | \ + IME_CMODE_CHARCODE | \ + IME_CMODE_HANJACONVERT | \ + IME_CMODE_SOFTKBD | \ + IME_CMODE_NOCONVERSION | \ + IME_CMODE_EUDC | \ + IME_CMODE_SYMBOL | \ + IME_CMODE_FIXED) +#define VALID_SMODE_CAPS (IME_SMODE_NONE | \ + IME_SMODE_PLAURALCLAUSE | \ + IME_SMODE_SINGLECONVERT | \ + IME_SMODE_AUTOMATIC | \ + IME_SMODE_PHRASEPREDICT | \ + IME_SMODE_CONVERSATION) +#define VALID_UI_CAPS (UI_CAP_2700 | \ + UI_CAP_ROT90 | \ + UI_CAP_ROTANY | \ + UI_CAP_SOFTKBD) +#define VALID_SCS_CAPS (SCS_CAP_COMPSTR | \ + SCS_CAP_MAKEREAD | \ + SCS_CAP_SETRECONVERTSTRING) +#define VALID_SELECT_CAPS (SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE) + + if (pImeInfo->fdwProperty & ~VALID_IME_PROP) + return FALSE; + if (pImeInfo->fdwConversionCaps & ~VALID_CMODE_CAPS) + return FALSE; + if (pImeInfo->fdwSentenceCaps & ~VALID_SMODE_CAPS) + return FALSE; + if (pImeInfo->fdwUICaps & ~VALID_UI_CAPS) + return FALSE; + if (pImeInfo->fdwSCSCaps & ~VALID_SCS_CAPS) + return FALSE; + if (pImeInfo->fdwSelectCaps & ~VALID_SELECT_CAPS) + return FALSE; + +#undef VALID_IME_PROP +#undef VALID_CMODE_CAPS +#undef VALID_SMODE_CAPS +#undef VALID_UI_CAPS +#undef VALID_SCS_CAPS +#undef VALID_SELECT_CAPS + + if (pImeInfo->fdwProperty & IME_PROP_UNICODE) + { + StringCchCopyW(pImeDpi->szUIClass, _countof(pImeDpi->szUIClass), szUIClass); + } + else + { + if (pImeDpi->uCodePage != GetACP() && pImeDpi->uCodePage) + return FALSE; + + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPSTR)szUIClass, -1, + pImeDpi->szUIClass, _countof(pImeDpi->szUIClass)); + } + + return GetClassInfoW(pImeDpi->hInst, pImeDpi->szUIClass, &wcW); +} + +BOOL APIENTRY Imm32LoadImeInfo(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi) +{ + WCHAR szPath[MAX_PATH]; + HINSTANCE hIME; + FARPROC fn; + + if (!Imm32GetSystemLibraryPath(szPath, _countof(szPath), pImeInfoEx->wszImeFile)) + return FALSE; + + hIME = GetModuleHandleW(szPath); + if (hIME == NULL) + { + hIME = LoadLibraryW(szPath); + if (hIME == NULL) + { + ERR("Imm32LoadImeInfo: LoadLibraryW(%S) failed\n", szPath); + return FALSE; + } + } + pImeDpi->hInst = hIME; + +#define DEFINE_IME_ENTRY(type, name, params, extended) \ + do { \ + fn = GetProcAddress(hIME, #name); \ + if (fn) pImeDpi->name = (FN_##name)fn; \ + else if (!extended) goto Failed; \ + } while (0); +#include "../../../win32ss/include/imetable.h" +#undef DEFINE_IME_ENTRY + + if (!Imm32InquireIme(pImeDpi)) + { + ERR("Imm32LoadImeInfo: Imm32InquireIme failed\n"); + goto Failed; + } + + if (pImeInfoEx->fLoadFlag) + return TRUE; + + NtUserSetImeOwnerWindow(pImeInfoEx, TRUE); + return TRUE; + +Failed: + FreeLibrary(pImeDpi->hInst); + pImeDpi->hInst = NULL; + return FALSE; +} + +PIMEDPI APIENTRY Ime32LoadImeDpi(HKL hKL, BOOL bLock) +{ + IMEINFOEX ImeInfoEx; + CHARSETINFO ci; + PIMEDPI pImeDpiNew, pImeDpiFound; + UINT uCodePage; + LCID lcid; + + if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL) || + ImeInfoEx.fLoadFlag == 1) + { + return NULL; + } + + pImeDpiNew = Imm32HeapAlloc(HEAP_ZERO_MEMORY, sizeof(IMEDPI)); + if (pImeDpiNew == NULL) + return NULL; + + pImeDpiNew->hKL = hKL; + + lcid = LOWORD(hKL); + if (TranslateCharsetInfo((LPDWORD)(DWORD_PTR)lcid, &ci, TCI_SRCLOCALE)) + uCodePage = ci.ciACP; + else + uCodePage = CP_ACP; + pImeDpiNew->uCodePage = uCodePage; + + if (!Imm32LoadImeInfo(&ImeInfoEx, pImeDpiNew)) + { + HeapFree(g_hImm32Heap, 0, pImeDpiNew); + return FALSE; + } + + RtlEnterCriticalSection(&g_csImeDpi); + + pImeDpiFound = Imm32FindImeDpi(hKL); + if (pImeDpiFound) + { + if (!bLock) + pImeDpiFound->dwFlags &= ~IMEDPI_FLAG_LOCKED; + + RtlLeaveCriticalSection(&g_csImeDpi); + + Imm32FreeImeDpi(pImeDpiNew, FALSE); + HeapFree(g_hImm32Heap, 0, pImeDpiNew); + return pImeDpiFound; + } + else + { + if (bLock) + { + pImeDpiNew->dwFlags |= IMEDPI_FLAG_LOCKED; + pImeDpiNew->cLockObj = 1; + } + + pImeDpiNew->pNext = g_pImeDpiList; + g_pImeDpiList = pImeDpiNew; + + RtlLeaveCriticalSection(&g_csImeDpi); + return pImeDpiNew; + } +} + +PIMEDPI APIENTRY ImmLockOrLoadImeDpi(HKL hKL) +{ + PW32CLIENTINFO pInfo; + PIMEDPI pImeDpi; + + if (!IS_IME_HKL(hKL)) + { + if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)) + return NULL; + + pInfo = (PW32CLIENTINFO)(NtCurrentTeb()->Win32ClientInfo); + if ((pInfo->W32ClientInfo[0] & 2)) + return NULL; + } + + pImeDpi = ImmLockImeDpi(hKL); + if (pImeDpi == NULL) + pImeDpi = Ime32LoadImeDpi(hKL, TRUE); + return pImeDpi; +} + +/*********************************************************************** + * ImmIsIME (IMM32.@) + */ +BOOL WINAPI ImmIsIME(HKL hKL) +{ + IMEINFOEX info; + TRACE("(%p)\n", hKL); + return !!ImmGetImeInfoEx(&info, ImeInfoExImeWindow, &hKL); +} + +/*********************************************************************** + * ImmGetDefaultIMEWnd (IMM32.@) + */ +HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd) +{ + if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_IMM32)) + return NULL; + + // FIXME: NtUserGetThreadState and enum ThreadStateRoutines are broken. + if (hWnd == NULL) + return (HWND)NtUserGetThreadState(3); + + return (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_IME); +} + +/*********************************************************************** + * ImmNotifyIME (IMM32.@) + */ +BOOL WINAPI ImmNotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue) +{ + HKL hKL; + PIMEDPI pImeDpi; + BOOL ret; + + TRACE("(%p, %lu, %lu, %lu)\n", hIMC, dwAction, dwIndex, dwValue); + + if (hIMC && Imm32IsCrossThreadAccess(hIMC)) + return FALSE; + + hKL = GetKeyboardLayout(0); + pImeDpi = ImmLockImeDpi(hKL); + if (pImeDpi == NULL) + return FALSE; + + ret = pImeDpi->NotifyIME(hIMC, dwAction, dwIndex, dwValue); + ImmUnlockImeDpi(pImeDpi); + return ret; +} + +/*********************************************************************** + * ImmDisableLegacyIME(IMM32.@) + */ +BOOL WINAPI ImmDisableLegacyIME(void) +{ + FIXME("stub\n"); + return TRUE; +} + +/*********************************************************************** + * CtfImmIsTextFrameServiceDisabled(IMM32.@) + */ +BOOL WINAPI CtfImmIsTextFrameServiceDisabled(VOID) +{ + PTEB pTeb = NtCurrentTeb(); + if (((PW32CLIENTINFO)pTeb->Win32ClientInfo)->CI_flags & CI_TFSDISABLED) + return TRUE; + return FALSE; +} + +/*********************************************************************** + * ImmGetImeInfoEx (IMM32.@) + */ +BOOL WINAPI +ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx, IMEINFOEXCLASS SearchType, PVOID pvSearchKey) +{ + BOOL bDisabled = FALSE; + HKL hKL; + PTEB pTeb; + + switch (SearchType) + { + case ImeInfoExKeyboardLayout: + break; + + case ImeInfoExImeWindow: + bDisabled = CtfImmIsTextFrameServiceDisabled(); + SearchType = ImeInfoExKeyboardLayout; + break; + + case ImeInfoExImeFileName: + StringCchCopyW(pImeInfoEx->wszImeFile, _countof(pImeInfoEx->wszImeFile), + pvSearchKey); + goto Quit; + } + + hKL = *(HKL*)pvSearchKey; + pImeInfoEx->hkl = hKL; + + if (!IS_IME_HKL(hKL)) + { + if (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)) + { + pTeb = NtCurrentTeb(); + if (((PW32CLIENTINFO)pTeb->Win32ClientInfo)->W32ClientInfo[0] & 2) + return FALSE; + if (!bDisabled) + goto Quit; + } + return FALSE; + } + +Quit: + return NtUserGetImeInfoEx(pImeInfoEx, SearchType); +} + +/*********************************************************************** + * ImmLockImeDpi (IMM32.@) + */ +PIMEDPI WINAPI ImmLockImeDpi(HKL hKL) +{ + PIMEDPI pImeDpi = NULL; + + TRACE("(%p)\n", hKL); + + RtlEnterCriticalSection(&g_csImeDpi); + + /* Find by hKL */ + for (pImeDpi = g_pImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext) + { + if (pImeDpi->hKL == hKL) /* found */ + { + /* lock if possible */ + if (pImeDpi->dwFlags & IMEDPI_FLAG_UNKNOWN) + pImeDpi = NULL; + else + ++(pImeDpi->cLockObj); + break; + } + } + + RtlLeaveCriticalSection(&g_csImeDpi); + return pImeDpi; +} + +/*********************************************************************** + * ImmUnlockImeDpi (IMM32.@) + */ +VOID WINAPI ImmUnlockImeDpi(PIMEDPI pImeDpi) +{ + PIMEDPI *ppEntry; + + TRACE("(%p)\n", pImeDpi); + + if (pImeDpi == NULL) + return; + + RtlEnterCriticalSection(&g_csImeDpi); + + /* unlock */ + --(pImeDpi->cLockObj); + if (pImeDpi->cLockObj != 0) + { + RtlLeaveCriticalSection(&g_csImeDpi); + return; + } + + if ((pImeDpi->dwFlags & IMEDPI_FLAG_UNKNOWN) == 0) + { + if ((pImeDpi->dwFlags & IMEDPI_FLAG_LOCKED) == 0 || + (pImeDpi->ImeInfo.fdwProperty & IME_PROP_END_UNLOAD) == 0) + { + RtlLeaveCriticalSection(&g_csImeDpi); + return; + } + } + + /* Remove from list */ + for (ppEntry = &g_pImeDpiList; *ppEntry; ppEntry = &((*ppEntry)->pNext)) + { + if (*ppEntry == pImeDpi) /* found */ + { + *ppEntry = pImeDpi->pNext; + break; + } + } + + Imm32FreeImeDpi(pImeDpi, TRUE); + HeapFree(g_hImm32Heap, 0, pImeDpi); + + RtlLeaveCriticalSection(&g_csImeDpi); +} + +/*********************************************************************** + * ImmLoadIME (IMM32.@) + */ +BOOL WINAPI ImmLoadIME(HKL hKL) +{ + PW32CLIENTINFO pInfo; + PIMEDPI pImeDpi; + + if (!IS_IME_HKL(hKL)) + { + if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)) + return FALSE; + + pInfo = (PW32CLIENTINFO)(NtCurrentTeb()->Win32ClientInfo); + if ((pInfo->W32ClientInfo[0] & 2)) + return FALSE; + } + + pImeDpi = Imm32FindImeDpi(hKL); + if (pImeDpi == NULL) + pImeDpi = Ime32LoadImeDpi(hKL, FALSE); + return (pImeDpi != NULL); +} + +/*********************************************************************** + * ImmDisableIME (IMM32.@) + */ +BOOL WINAPI ImmDisableIME(DWORD dwThreadId) +{ + return NtUserDisableThreadIme(dwThreadId); +} + +/*********************************************************************** + * ImmGetDescriptionA (IMM32.@) + */ +UINT WINAPI ImmGetDescriptionA(HKL hKL, LPSTR lpszDescription, UINT uBufLen) +{ + IMEINFOEX info; + size_t cch; + + TRACE("(%p,%p,%d)\n", hKL, lpszDescription, uBufLen); + + if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL)) + return 0; + + StringCchLengthW(info.wszImeDescription, _countof(info.wszImeDescription), &cch); + cch = WideCharToMultiByte(CP_ACP, 0, info.wszImeDescription, (INT)cch, + lpszDescription, uBufLen, NULL, NULL); + if (uBufLen) + lpszDescription[cch] = 0; + return (UINT)cch; +} + +/*********************************************************************** + * ImmGetDescriptionW (IMM32.@) + */ +UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen) +{ + IMEINFOEX info; + size_t cch; + + TRACE("(%p, %p, %d)\n", hKL, lpszDescription, uBufLen); + + if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL)) + return 0; + + if (uBufLen != 0) + StringCchCopyW(lpszDescription, uBufLen, info.wszImeDescription); + + StringCchLengthW(info.wszImeDescription, _countof(info.wszImeDescription), &cch); + return (UINT)cch; +} + +/*********************************************************************** + * ImmGetIMEFileNameA (IMM32.@) + */ +UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen) +{ + BOOL bDefUsed; + IMEINFOEX info; + size_t cch; + + TRACE("(%p, %p, %u)\n", hKL, lpszFileName, uBufLen); + + if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL)) + { + if (uBufLen > 0) + lpszFileName[0] = 0; + return 0; + } + + StringCchLengthW(info.wszImeFile, _countof(info.wszImeFile), &cch); + + cch = WideCharToMultiByte(CP_ACP, 0, info.wszImeFile, (INT)cch, + lpszFileName, uBufLen, NULL, &bDefUsed); + if (uBufLen == 0) + return (UINT)cch; + + if (cch > uBufLen - 1) + cch = uBufLen - 1; + + lpszFileName[cch] = 0; + return (UINT)cch; +} + +/*********************************************************************** + * ImmGetIMEFileNameW (IMM32.@) + */ +UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen) +{ + IMEINFOEX info; + size_t cch; + + TRACE("(%p, %p, %u)\n", hKL, lpszFileName, uBufLen); + + if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL)) + { + if (uBufLen > 0) + lpszFileName[0] = 0; + return 0; + } + + StringCchLengthW(info.wszImeFile, _countof(info.wszImeFile), &cch); + if (uBufLen == 0) + return (UINT)cch; + + StringCchCopyNW(lpszFileName, uBufLen, info.wszImeFile, cch); + + if (cch > uBufLen - 1) + cch = uBufLen - 1; + + lpszFileName[cch] = 0; + return (UINT)cch; +} + +/*********************************************************************** + * ImmGetProperty (IMM32.@) + */ +DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex) +{ + IMEINFOEX ImeInfoEx; + LPIMEINFO pImeInfo; + DWORD dwValue; + PIMEDPI pImeDpi = NULL; + + TRACE("(%p, %lu)\n", hKL, fdwIndex); + + if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL)) + return FALSE; + + if (fdwIndex == IGP_GETIMEVERSION) + return ImeInfoEx.dwImeWinVersion; + + if (ImeInfoEx.fLoadFlag != 2) + { + pImeDpi = ImmLockOrLoadImeDpi(hKL); + if (pImeDpi == NULL) + return FALSE; + + pImeInfo = &pImeDpi->ImeInfo; + } + else + { + pImeInfo = &ImeInfoEx.ImeInfo; + } + + switch (fdwIndex) + { + case IGP_PROPERTY: dwValue = pImeInfo->fdwProperty; break; + case IGP_CONVERSION: dwValue = pImeInfo->fdwConversionCaps; break; + case IGP_SENTENCE: dwValue = pImeInfo->fdwSentenceCaps; break; + case IGP_UI: dwValue = pImeInfo->fdwUICaps; break; + case IGP_SETCOMPSTR: dwValue = pImeInfo->fdwSCSCaps; break; + case IGP_SELECT: dwValue = pImeInfo->fdwSelectCaps; break; + default: dwValue = 0; break; + } + + if (pImeDpi) + ImmUnlockImeDpi(pImeDpi); + return dwValue; +} + +/*********************************************************************** + * ImmGetOpenStatus (IMM32.@) + */ +BOOL WINAPI ImmGetOpenStatus(HIMC hIMC) +{ + BOOL ret; + LPINPUTCONTEXT pIC; + + TRACE("(%p)\n", hIMC); + + if (!hIMC) + return FALSE; + + pIC = ImmLockIMC(hIMC); + if (!pIC) + return FALSE; + + ret = pIC->fOpen; + + ImmUnlockIMC(hIMC); + return ret; +} + +/*********************************************************************** + * ImmSetOpenStatus (IMM32.@) + */ +BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen) +{ + DWORD dwConversion; + LPINPUTCONTEXT pIC; + HWND hWnd; + BOOL bHasChange = FALSE; + + TRACE("(%p, %d)\n", hIMC, fOpen); + + if (Imm32IsCrossThreadAccess(hIMC)) + return FALSE; + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + if (pIC->fOpen != fOpen) + { + pIC->fOpen = fOpen; + hWnd = pIC->hWnd; + dwConversion = pIC->fdwConversion; + bHasChange = TRUE; + } + + ImmUnlockIMC(hIMC); + + if (bHasChange) + { + Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, + IMC_SETOPENSTATUS, IMN_SETOPENSTATUS, 0); + NtUserNotifyIMEStatus(hWnd, hIMC, dwConversion); + } + + return TRUE; +} + +/*********************************************************************** + * ImmGetStatusWindowPos (IMM32.@) + */ +BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos) +{ + LPINPUTCONTEXT pIC; + BOOL ret; + + TRACE("(%p, %p)\n", hIMC, lpptPos); + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + ret = !!(pIC->fdwInit & INIT_STATUSWNDPOS); + if (ret) + *lpptPos = pIC->ptStatusWndPos; + + ImmUnlockIMC(hIMC); + return ret; +} + +/*********************************************************************** + * ImmSetStatusWindowPos (IMM32.@) + */ +BOOL WINAPI ImmSetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos) +{ + LPINPUTCONTEXT pIC; + HWND hWnd; + + TRACE("(%p, {%ld, %ld})\n", hIMC, lpptPos->x, lpptPos->y); + + if (Imm32IsCrossThreadAccess(hIMC)) + return FALSE; + + pIC = ImmLockIMC(hIMC); + if (!pIC) + return FALSE; + + hWnd = pIC->hWnd; + pIC->ptStatusWndPos = *lpptPos; + pIC->fdwInit |= INIT_STATUSWNDPOS; + + ImmUnlockIMC(hIMC); + + Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, + IMC_SETSTATUSWINDOWPOS, IMN_SETSTATUSWINDOWPOS, 0); + return TRUE; +} + +/*********************************************************************** + * ImmGetCompositionWindow (IMM32.@) + */ +BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm) +{ + LPINPUTCONTEXT pIC; + BOOL ret = FALSE; + + TRACE("(%p, %p)\n", hIMC, lpCompForm); + + pIC = ImmLockIMC(hIMC); + if (!pIC) + return FALSE; + + if (pIC->fdwInit & INIT_COMPFORM) + { + *lpCompForm = pIC->cfCompForm; + ret = TRUE; + } + + ImmUnlockIMC(hIMC); + return ret; +} + +/*********************************************************************** + * ImmSetCompositionWindow (IMM32.@) + */ +BOOL WINAPI ImmSetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm) +{ + LPINPUTCONTEXT pIC; + HWND hWnd; + + if (Imm32IsCrossThreadAccess(hIMC)) + return FALSE; + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + pIC->cfCompForm = *lpCompForm; + pIC->fdwInit |= INIT_COMPFORM; + + hWnd = pIC->hWnd; + + ImmUnlockIMC(hIMC); + + Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, + IMC_SETCOMPOSITIONWINDOW, IMN_SETCOMPOSITIONWINDOW, 0); + return TRUE; +} + +/*********************************************************************** + * ImmGetCompositionFontA (IMM32.@) + */ +BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf) +{ + PCLIENTIMC pClientImc; + BOOL ret = FALSE, bWide; + LPINPUTCONTEXT pIC; + + TRACE("(%p, %p)\n", hIMC, lplf); + + pClientImc = ImmLockClientImc(hIMC); + if (pClientImc == NULL) + return FALSE; + + bWide = (pClientImc->dwFlags & CLIENTIMC_WIDE); + ImmUnlockClientImc(pClientImc); + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + if (pIC->fdwInit & INIT_LOGFONT) + { + if (bWide) + LogFontWideToAnsi(&pIC->lfFont.W, lplf); + else + *lplf = pIC->lfFont.A; + + ret = TRUE; + } + + ImmUnlockIMC(hIMC); + return ret; +} + +/*********************************************************************** + * ImmGetCompositionFontW (IMM32.@) + */ +BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf) +{ + PCLIENTIMC pClientImc; + BOOL bWide; + LPINPUTCONTEXT pIC; + BOOL ret = FALSE; + + TRACE("(%p, %p)\n", hIMC, lplf); + + pClientImc = ImmLockClientImc(hIMC); + if (pClientImc == NULL) + return FALSE; + + bWide = (pClientImc->dwFlags & CLIENTIMC_WIDE); + ImmUnlockClientImc(pClientImc); + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + if (pIC->fdwInit & INIT_LOGFONT) + { + if (bWide) + *lplf = pIC->lfFont.W; + else + LogFontAnsiToWide(&pIC->lfFont.A, lplf); + + ret = TRUE; + } + + ImmUnlockIMC(hIMC); + return ret; +} + +/*********************************************************************** + * ImmSetCompositionFontA (IMM32.@) + */ +BOOL WINAPI ImmSetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf) +{ + LOGFONTW lfW; + PCLIENTIMC pClientImc; + BOOL bWide; + LPINPUTCONTEXTDX pIC; + LCID lcid; + HWND hWnd; + PTEB pTeb; + + TRACE("(%p, %p)\n", hIMC, lplf); + + if (Imm32IsCrossThreadAccess(hIMC)) + return FALSE; + + pClientImc = ImmLockClientImc(hIMC); + if (pClientImc == NULL) + return FALSE; + + bWide = (pClientImc->dwFlags & CLIENTIMC_WIDE); + ImmUnlockClientImc(pClientImc); + + if (bWide) + { + LogFontAnsiToWide(lplf, &lfW); + return ImmSetCompositionFontW(hIMC, &lfW); + } + + pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + pTeb = NtCurrentTeb(); + if (pTeb->Win32ClientInfo[2] < 0x400) + { + lcid = GetSystemDefaultLCID(); + if (PRIMARYLANGID(lcid) == LANG_JAPANESE && !(pIC->dwUIFlags & 2) && + pIC->cfCompForm.dwStyle != CFS_DEFAULT) + { + PostMessageA(pIC->hWnd, WM_IME_REPORT, IR_CHANGECONVERT, 0); + } + } + + pIC->lfFont.A = *lplf; + pIC->fdwInit |= INIT_LOGFONT; + hWnd = pIC->hWnd; + + ImmUnlockIMC(hIMC); + + Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT, + IMN_SETCOMPOSITIONFONT, 0); + return TRUE; +} + +/*********************************************************************** + * ImmSetCompositionFontW (IMM32.@) + */ +BOOL WINAPI ImmSetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf) +{ + LOGFONTA lfA; + PCLIENTIMC pClientImc; + BOOL bWide; + HWND hWnd; + LPINPUTCONTEXTDX pIC; + PTEB pTeb; + LCID lcid; + + TRACE("(%p, %p)\n", hIMC, lplf); + + if (Imm32IsCrossThreadAccess(hIMC)) + return FALSE; + + pClientImc = ImmLockClientImc(hIMC); + if (pClientImc == NULL) + return FALSE; + + bWide = (pClientImc->dwFlags & CLIENTIMC_WIDE); + ImmUnlockClientImc(pClientImc); + + if (!bWide) + { + LogFontWideToAnsi(lplf, &lfA); + return ImmSetCompositionFontA(hIMC, &lfA); + } + + pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + pTeb = NtCurrentTeb(); + if (pTeb->Win32ClientInfo[2] < 0x400) + { + lcid = GetSystemDefaultLCID(); + if (PRIMARYLANGID(lcid) == LANG_JAPANESE && + !(pIC->dwUIFlags & 2) && + pIC->cfCompForm.dwStyle != CFS_DEFAULT) + { + PostMessageW(pIC->hWnd, WM_IME_REPORT, IR_CHANGECONVERT, 0); + } + } + + pIC->lfFont.W = *lplf; + pIC->fdwInit |= INIT_LOGFONT; + hWnd = pIC->hWnd; + + ImmUnlockIMC(hIMC); + + Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, IMC_SETCOMPOSITIONFONT, + IMN_SETCOMPOSITIONFONT, 0); + return TRUE; +} + +/*********************************************************************** + * ImmGetConversionListA (IMM32.@) + */ +DWORD WINAPI +ImmGetConversionListA(HKL hKL, HIMC hIMC, LPCSTR pSrc, LPCANDIDATELIST lpDst, + DWORD dwBufLen, UINT uFlag) +{ + DWORD ret = 0; + UINT cb; + LPWSTR pszSrcW = NULL; + LPCANDIDATELIST pCL = NULL; + PIMEDPI pImeDpi; + + TRACE("(%p, %p, %s, %p, %lu, 0x%lX)\n", hKL, hIMC, debugstr_a(pSrc), + lpDst, dwBufLen, uFlag); + + pImeDpi = ImmLockOrLoadImeDpi(hKL); + if (pImeDpi == NULL) + return 0; + + if (!(pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE)) + { + ret = pImeDpi->ImeConversionList(hIMC, pSrc, lpDst, dwBufLen, uFlag); + ImmUnlockImeDpi(pImeDpi); + return ret; + } + + if (pSrc) + { + pszSrcW = Imm32WideFromAnsi(pSrc); + if (pszSrcW == NULL) + goto Quit; + } + + cb = pImeDpi->ImeConversionList(hIMC, pszSrcW, NULL, 0, uFlag); + if (cb == 0) + goto Quit; + + pCL = Imm32HeapAlloc(0, cb); + if (pCL == NULL) + goto Quit; + + cb = pImeDpi->ImeConversionList(hIMC, pszSrcW, pCL, cb, uFlag); + if (cb == 0) + goto Quit; + + ret = CandidateListWideToAnsi(pCL, lpDst, dwBufLen, CP_ACP); + +Quit: + if (pszSrcW) + HeapFree(g_hImm32Heap, 0, pszSrcW); + if (pCL) + HeapFree(g_hImm32Heap, 0, pCL); + ImmUnlockImeDpi(pImeDpi); + return ret; +} + +/*********************************************************************** + * ImmGetConversionListW (IMM32.@) + */ +DWORD WINAPI +ImmGetConversionListW(HKL hKL, HIMC hIMC, LPCWSTR pSrc, LPCANDIDATELIST lpDst, + DWORD dwBufLen, UINT uFlag) +{ + DWORD ret = 0; + INT cb; + PIMEDPI pImeDpi; + LPCANDIDATELIST pCL = NULL; + LPSTR pszSrcA = NULL; + + TRACE("(%p, %p, %s, %p, %lu, 0x%lX)\n", hKL, hIMC, debugstr_w(pSrc), + lpDst, dwBufLen, uFlag); + + pImeDpi = ImmLockOrLoadImeDpi(hKL); + if (!pImeDpi) + return 0; + + if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) + { + ret = pImeDpi->ImeConversionList(hIMC, pSrc, lpDst, dwBufLen, uFlag); + ImmUnlockImeDpi(pImeDpi); + return ret; + } + + if (pSrc) + { + pszSrcA = Imm32AnsiFromWide(pSrc); + if (pszSrcA == NULL) + goto Quit; + } + + cb = pImeDpi->ImeConversionList(hIMC, pszSrcA, NULL, 0, uFlag); + if (cb == 0) + goto Quit; + + pCL = Imm32HeapAlloc(0, cb); + if (!pCL) + goto Quit; + + cb = pImeDpi->ImeConversionList(hIMC, pszSrcA, pCL, cb, uFlag); + if (!cb) + goto Quit; + + ret = CandidateListAnsiToWide(pCL, lpDst, dwBufLen, CP_ACP); + +Quit: + if (pszSrcA) + HeapFree(g_hImm32Heap, 0, pszSrcA); + if (pCL) + HeapFree(g_hImm32Heap, 0, pCL); + ImmUnlockImeDpi(pImeDpi); + return ret; +} + +/*********************************************************************** + * ImmGetConversionStatus (IMM32.@) + */ +BOOL WINAPI ImmGetConversionStatus(HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence) +{ + LPINPUTCONTEXT pIC; + + TRACE("(%p %p %p)\n", hIMC, lpfdwConversion, lpfdwSentence); + + pIC = ImmLockIMC(hIMC); + if (!pIC) + return FALSE; + + if (lpfdwConversion) + *lpfdwConversion = pIC->fdwConversion; + if (lpfdwSentence) + *lpfdwSentence = pIC->fdwSentence; + + ImmUnlockIMC(hIMC); + return TRUE; +} + +/*********************************************************************** + * ImmSetConversionStatus (IMM32.@) + */ +BOOL WINAPI ImmSetConversionStatus(HIMC hIMC, DWORD fdwConversion, DWORD fdwSentence) +{ + HKL hKL; + LPINPUTCONTEXT pIC; + DWORD dwOldConversion, dwOldSentence; + BOOL fConversionChange = FALSE, fSentenceChange = FALSE; + HWND hWnd; + + TRACE("(%p, 0x%lX, 0x%lX)\n", hIMC, fdwConversion, fdwSentence); + + hKL = GetKeyboardLayout(0); + if (!IS_IME_HKL(hKL)) + { + if (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)) + { + FIXME("Cicero\n"); + return FALSE; + } + } + + if (Imm32IsCrossThreadAccess(hIMC)) + return FALSE; + + pIC = ImmLockIMC(hIMC); + if (pIC == NULL) + return FALSE; + + if (pIC->fdwConversion != fdwConversion) + { + dwOldConversion = pIC->fdwConversion; + pIC->fdwConversion = fdwConversion; + fConversionChange = TRUE; + } + + if (pIC->fdwSentence != fdwSentence) + { + dwOldSentence = pIC->fdwSentence; + pIC->fdwSentence = fdwSentence; + fSentenceChange = TRUE; + } + + hWnd = pIC->hWnd; + ImmUnlockIMC(hIMC); + + if (fConversionChange) + { + Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, dwOldConversion, + IMC_SETCONVERSIONMODE, IMN_SETCONVERSIONMODE, 0); + NtUserNotifyIMEStatus(hWnd, hIMC, fdwConversion); + } + + if (fSentenceChange) + { + Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, dwOldSentence, + IMC_SETSENTENCEMODE, IMN_SETSENTENCEMODE, 0); + } + + return TRUE; +} diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c index 1dc41f8e362..38dd4b55b57 100644 --- a/dll/win32/imm32/imm.c +++ b/dll/win32/imm32/imm.c @@ -10,88 +10,14 @@ * Copyright 2020-2021 Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com */
-#include <stdarg.h> -#include <stdio.h> - -#define WIN32_NO_STATUS -#include <windef.h> -#include <winbase.h> -#include <wingdi.h> -#include <winuser.h> -#include <winerror.h> -#include <wine/debug.h> -#include <imm.h> -#include <ddk/imm.h> -#include <winnls.h> -#include <winreg.h> -#include <wine/list.h> -#include <stdlib.h> -#include <ndk/umtypes.h> -#include <ndk/pstypes.h> -#include <ndk/rtlfuncs.h> -#include "../../../win32ss/include/ntuser.h" -#include "../../../win32ss/include/ntwin32.h" -#include <undocuser.h> -#include <imm32_undoc.h> -#include <strsafe.h> +#include "precomp.h"
WINE_DEFAULT_DEBUG_CHANNEL(imm);
-#define IMM_INIT_MAGIC 0x19650412 -#define IMM_INVALID_CANDFORM ULONG_MAX -#define INVALID_HOTKEY_ID 0xFFFFFFFF -#define MAX_CANDIDATEFORM 4 - -#define LANGID_CHINESE_SIMPLIFIED MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) -#define LANGID_CHINESE_TRADITIONAL MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) -#define LANGID_JAPANESE MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT) - -#define REGKEY_KEYBOARD_LAYOUTS \ - L"System\CurrentControlSet\Control\Keyboard Layouts" -#define REGKEY_IMM \ - L"Software\Microsoft\Windows NT\CurrentVersion\IMM" - -#define ROUNDUP4(n) (((n) + 3) & ~3) /* DWORD alignment */ - HMODULE g_hImm32Inst = NULL; -RTL_CRITICAL_SECTION g_csImeDpi; -PIMEDPI g_pImeDpiList = NULL; PSERVERINFO g_psi = NULL; SHAREDINFO g_SharedInfo = { NULL }; BYTE g_bClientRegd = FALSE; -HANDLE g_hImm32Heap = NULL; - -static PWND FASTCALL ValidateHwndNoErr(HWND hwnd) -{ - PCLIENTINFO ClientInfo = GetWin32ClientInfo(); - INT index; - PUSER_HANDLE_TABLE ht; - PUSER_HANDLE_ENTRY he; - WORD generation; - - /* See if the window is cached */ - if (hwnd == ClientInfo->CallbackWnd.hWnd) - return ClientInfo->CallbackWnd.pWnd; - - if (!NtUserValidateHandleSecure(hwnd)) - return NULL; - - ht = g_SharedInfo.aheList; /* handle table */ - ASSERT(ht); - /* ReactOS-Specific! */ - ASSERT(g_SharedInfo.ulSharedDelta != 0); - he = (PUSER_HANDLE_ENTRY)((ULONG_PTR)ht->handles - g_SharedInfo.ulSharedDelta); - - index = (LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1; - if (index < 0 || index >= ht->nb_handles || he[index].type != TYPE_WINDOW) - return NULL; - - generation = HIWORD(hwnd); - if (generation != he[index].generation && generation && generation != 0xFFFF) - return NULL; - - return (PWND)&he[index]; -}
static BOOL APIENTRY Imm32InitInstance(HMODULE hMod) { @@ -111,568 +37,15 @@ static BOOL APIENTRY Imm32InitInstance(HMODULE hMod) return TRUE; }
-LPVOID APIENTRY Imm32HeapAlloc(DWORD dwFlags, DWORD dwBytes) -{ - if (!g_hImm32Heap) - { - g_hImm32Heap = RtlGetProcessHeap(); - if (g_hImm32Heap == NULL) - return NULL; - } - return HeapAlloc(g_hImm32Heap, dwFlags, dwBytes); -} - -static LPWSTR APIENTRY Imm32WideFromAnsi(LPCSTR pszA) -{ - INT cch = lstrlenA(pszA); - LPWSTR pszW = Imm32HeapAlloc(0, (cch + 1) * sizeof(WCHAR)); - if (pszW == NULL) - return NULL; - cch = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszA, cch, pszW, cch + 1); - pszW[cch] = 0; - return pszW; -} - -static LPSTR APIENTRY Imm32AnsiFromWide(LPCWSTR pszW) -{ - INT cchW = lstrlenW(pszW); - INT cchA = (cchW + 1) * sizeof(WCHAR); - LPSTR pszA = Imm32HeapAlloc(0, cchA); - if (!pszA) - return NULL; - cchA = WideCharToMultiByte(CP_ACP, 0, pszW, cchW, pszA, cchA, NULL, NULL); - pszA[cchA] = 0; - return pszA; -} - -static inline BOOL Imm32IsCrossThreadAccess(HIMC hIMC) -{ - DWORD dwImeThreadId = NtUserQueryInputContext(hIMC, 1); - DWORD dwThreadId = GetCurrentThreadId(); - return (dwImeThreadId != dwThreadId); -} - -static BOOL Imm32IsCrossProcessAccess(HWND hWnd) -{ - return (NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID) != - (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess); -} - -static VOID APIENTRY Imm32FreeImeDpi(PIMEDPI pImeDpi, BOOL bDestroy) -{ - if (pImeDpi->hInst == NULL) - return; - if (bDestroy) - pImeDpi->ImeDestroy(0); - FreeLibrary(pImeDpi->hInst); - pImeDpi->hInst = NULL; -} - -static BOOL APIENTRY -Imm32NotifyAction(HIMC hIMC, HWND hwnd, DWORD dwAction, DWORD_PTR dwIndex, DWORD_PTR dwValue, - DWORD_PTR dwCommand, DWORD_PTR dwData) -{ - DWORD dwLayout; - HKL hKL; - PIMEDPI pImeDpi; - - if (dwAction) - { - dwLayout = NtUserQueryInputContext(hIMC, 1); - if (dwLayout) - { - /* find keyboard layout and lock it */ - hKL = GetKeyboardLayout(dwLayout); - pImeDpi = ImmLockImeDpi(hKL); - if (pImeDpi) - { - /* do notify */ - pImeDpi->NotifyIME(hIMC, dwAction, dwIndex, dwValue); - - ImmUnlockImeDpi(pImeDpi); /* unlock */ - } - } - } - - if (hwnd && dwCommand) - SendMessageW(hwnd, WM_IME_NOTIFY, dwCommand, dwData); - - return TRUE; -} - -static PIMEDPI APIENTRY Imm32FindImeDpi(HKL hKL) -{ - PIMEDPI pImeDpi; - - RtlEnterCriticalSection(&g_csImeDpi); - for (pImeDpi = g_pImeDpiList; pImeDpi != NULL; pImeDpi = pImeDpi->pNext) - { - if (pImeDpi->hKL == hKL) - break; - } - RtlLeaveCriticalSection(&g_csImeDpi); - - return pImeDpi; -} - -static BOOL Imm32GetSystemLibraryPath(LPWSTR pszPath, DWORD cchPath, LPCWSTR pszFileName) -{ - if (!pszFileName[0] || !GetSystemDirectoryW(pszPath, cchPath)) - return FALSE; - StringCchCatW(pszPath, cchPath, L"\"); - StringCchCatW(pszPath, cchPath, pszFileName); - return TRUE; -} - -static BOOL APIENTRY Imm32InquireIme(PIMEDPI pImeDpi) -{ - WCHAR szUIClass[64]; - WNDCLASSW wcW; - DWORD dwSysInfoFlags = 0; // TODO: ??? - LPIMEINFO pImeInfo = &pImeDpi->ImeInfo; - - // TODO: NtUserGetThreadState(16); - - if (!IS_IME_HKL(pImeDpi->hKL)) - { - if (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED) && - pImeDpi->CtfImeInquireExW) - { - // TODO: - return FALSE; - } - } - - if (!pImeDpi->ImeInquire(pImeInfo, szUIClass, dwSysInfoFlags)) - return FALSE; - - szUIClass[_countof(szUIClass) - 1] = 0; - - if (pImeInfo->dwPrivateDataSize == 0) - pImeInfo->dwPrivateDataSize = 4; - -#define VALID_IME_PROP (IME_PROP_AT_CARET | \ - IME_PROP_SPECIAL_UI | \ - IME_PROP_CANDLIST_START_FROM_1 | \ - IME_PROP_UNICODE | \ - IME_PROP_COMPLETE_ON_UNSELECT | \ - IME_PROP_END_UNLOAD | \ - IME_PROP_KBD_CHAR_FIRST | \ - IME_PROP_IGNORE_UPKEYS | \ - IME_PROP_NEED_ALTKEY | \ - IME_PROP_NO_KEYS_ON_CLOSE | \ - IME_PROP_ACCEPT_WIDE_VKEY) -#define VALID_CMODE_CAPS (IME_CMODE_ALPHANUMERIC | \ - IME_CMODE_NATIVE | \ - IME_CMODE_KATAKANA | \ - IME_CMODE_LANGUAGE | \ - IME_CMODE_FULLSHAPE | \ - IME_CMODE_ROMAN | \ - IME_CMODE_CHARCODE | \ - IME_CMODE_HANJACONVERT | \ - IME_CMODE_SOFTKBD | \ - IME_CMODE_NOCONVERSION | \ - IME_CMODE_EUDC | \ - IME_CMODE_SYMBOL | \ - IME_CMODE_FIXED) -#define VALID_SMODE_CAPS (IME_SMODE_NONE | \ - IME_SMODE_PLAURALCLAUSE | \ - IME_SMODE_SINGLECONVERT | \ - IME_SMODE_AUTOMATIC | \ - IME_SMODE_PHRASEPREDICT | \ - IME_SMODE_CONVERSATION) -#define VALID_UI_CAPS (UI_CAP_2700 | \ - UI_CAP_ROT90 | \ - UI_CAP_ROTANY | \ - UI_CAP_SOFTKBD) -#define VALID_SCS_CAPS (SCS_CAP_COMPSTR | \ - SCS_CAP_MAKEREAD | \ - SCS_CAP_SETRECONVERTSTRING) -#define VALID_SELECT_CAPS (SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE) - - if (pImeInfo->fdwProperty & ~VALID_IME_PROP) - return FALSE; - if (pImeInfo->fdwConversionCaps & ~VALID_CMODE_CAPS) - return FALSE; - if (pImeInfo->fdwSentenceCaps & ~VALID_SMODE_CAPS) - return FALSE; - if (pImeInfo->fdwUICaps & ~VALID_UI_CAPS) - return FALSE; - if (pImeInfo->fdwSCSCaps & ~VALID_SCS_CAPS) - return FALSE; - if (pImeInfo->fdwSelectCaps & ~VALID_SELECT_CAPS) - return FALSE; - -#undef VALID_IME_PROP -#undef VALID_CMODE_CAPS -#undef VALID_SMODE_CAPS -#undef VALID_UI_CAPS -#undef VALID_SCS_CAPS -#undef VALID_SELECT_CAPS - - if (pImeInfo->fdwProperty & IME_PROP_UNICODE) - { - StringCchCopyW(pImeDpi->szUIClass, _countof(pImeDpi->szUIClass), szUIClass); - } - else - { - if (pImeDpi->uCodePage != GetACP() && pImeDpi->uCodePage) - return FALSE; - - MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPSTR)szUIClass, -1, - pImeDpi->szUIClass, _countof(pImeDpi->szUIClass)); - } - - return GetClassInfoW(pImeDpi->hInst, pImeDpi->szUIClass, &wcW); -} - -static BOOL APIENTRY Imm32LoadImeInfo(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi) -{ - WCHAR szPath[MAX_PATH]; - HINSTANCE hIME; - FARPROC fn; - - if (!Imm32GetSystemLibraryPath(szPath, _countof(szPath), pImeInfoEx->wszImeFile)) - return FALSE; - - hIME = GetModuleHandleW(szPath); - if (hIME == NULL) - { - hIME = LoadLibraryW(szPath); - if (hIME == NULL) - { - ERR("Imm32LoadImeInfo: LoadLibraryW(%S) failed\n", szPath); - return FALSE; - } - } - pImeDpi->hInst = hIME; - -#define DEFINE_IME_ENTRY(type, name, params, extended) \ - do { \ - fn = GetProcAddress(hIME, #name); \ - if (fn) pImeDpi->name = (FN_##name)fn; \ - else if (!extended) goto Failed; \ - } while (0); -#include "../../../win32ss/include/imetable.h" -#undef DEFINE_IME_ENTRY - - if (!Imm32InquireIme(pImeDpi)) - { - ERR("Imm32LoadImeInfo: Imm32InquireIme failed\n"); - goto Failed; - } - - if (pImeInfoEx->fLoadFlag) - return TRUE; - - NtUserSetImeOwnerWindow(pImeInfoEx, TRUE); - return TRUE; - -Failed: - FreeLibrary(pImeDpi->hInst); - pImeDpi->hInst = NULL; - return FALSE; -} - -#ifdef IMP_SUPPORT /* 3.x support */ -static DWORD APIENTRY -ImpJTransCompA(LPINPUTCONTEXTDX pIC, LPCOMPOSITIONSTRING pCS, - const TRANSMSG *pSrc, LPTRANSMSG pDest) -{ - // FIXME - *pDest = *pSrc; - return 1; -} - -static DWORD APIENTRY -ImpJTransCompW(LPINPUTCONTEXTDX pIC, LPCOMPOSITIONSTRING pCS, - const TRANSMSG *pSrc, LPTRANSMSG pDest) -{ - // FIXME - *pDest = *pSrc; - return 1; -} - -typedef LRESULT (WINAPI *FN_SendMessage)(HWND, UINT, WPARAM, LPARAM); - -static DWORD APIENTRY -ImpJTrans(DWORD dwCount, LPTRANSMSG pTrans, LPINPUTCONTEXTDX pIC, - LPCOMPOSITIONSTRING pCS, BOOL bAnsi) -{ - DWORD ret = 0; - HWND hWnd, hwndDefIME; - LPTRANSMSG pTempList, pEntry, pNext; - DWORD dwIndex, iCandForm, dwNumber, cbTempList; - HGLOBAL hGlobal; - CANDIDATEFORM CandForm; - FN_SendMessage pSendMessage; - - hWnd = pIC->hWnd; - hwndDefIME = ImmGetDefaultIMEWnd(hWnd); - pSendMessage = (IsWindowUnicode(hWnd) ? SendMessageW : SendMessageA); - - // clone the message list - cbTempList = (dwCount + 1) * sizeof(TRANSMSG); - pTempList = Imm32HeapAlloc(HEAP_ZERO_MEMORY, cbTempList); - if (pTempList == NULL) - return 0; - RtlCopyMemory(pTempList, pTrans, dwCount * sizeof(TRANSMSG)); - - if (pIC->dwUIFlags & 0x2) - { - // find WM_IME_ENDCOMPOSITION - pEntry = pTempList; - for (dwIndex = 0; dwIndex < dwCount; ++dwIndex, ++pEntry) - { - if (pEntry->message == WM_IME_ENDCOMPOSITION) - break; - } - - if (pEntry->message == WM_IME_ENDCOMPOSITION) // if found - { - // move WM_IME_ENDCOMPOSITION to the end of the list - for (pNext = pEntry + 1; pNext->message != 0; ++pEntry, ++pNext) - *pEntry = *pNext; - - pEntry->message = WM_IME_ENDCOMPOSITION; - pEntry->wParam = 0; - pEntry->lParam = 0; - } - } - - for (pEntry = pTempList; pEntry->message != 0; ++pEntry) - { - switch (pEntry->message) - { - case WM_IME_STARTCOMPOSITION: - if (!(pIC->dwUIFlags & 0x2)) - { - // send IR_OPENCONVERT - if (pIC->cfCompForm.dwStyle != CFS_DEFAULT) - pSendMessage(hWnd, WM_IME_REPORT, IR_OPENCONVERT, 0); - - goto DoDefault; - } - break; - - case WM_IME_ENDCOMPOSITION: - if (pIC->dwUIFlags & 0x2) - { - // send IR_UNDETERMINE - hGlobal = GlobalAlloc(GHND | GMEM_SHARE, sizeof(UNDETERMINESTRUCT)); - if (hGlobal) - { - pSendMessage(hWnd, WM_IME_REPORT, IR_UNDETERMINE, (LPARAM)hGlobal); - GlobalFree(hGlobal); - } - } - else - { - // send IR_CLOSECONVERT - if (pIC->cfCompForm.dwStyle != CFS_DEFAULT) - pSendMessage(hWnd, WM_IME_REPORT, IR_CLOSECONVERT, 0); - - goto DoDefault; - } - break; - - case WM_IME_COMPOSITION: - if (bAnsi) - dwNumber = ImpJTransCompA(pIC, pCS, pEntry, pTrans); - else - dwNumber = ImpJTransCompW(pIC, pCS, pEntry, pTrans); - - ret += dwNumber; - pTrans += dwNumber; - - // send IR_CHANGECONVERT - if (!(pIC->dwUIFlags & 0x2)) - { - if (pIC->cfCompForm.dwStyle != CFS_DEFAULT) - pSendMessage(hWnd, WM_IME_REPORT, IR_CHANGECONVERT, 0); - } - break; - - case WM_IME_NOTIFY: - if (pEntry->wParam == IMN_OPENCANDIDATE) - { - if (IsWindow(hWnd) && (pIC->dwUIFlags & 0x2)) - { - // send IMC_SETCANDIDATEPOS - for (iCandForm = 0; iCandForm < MAX_CANDIDATEFORM; ++iCandForm) - { - if (!(pEntry->lParam & (1 << iCandForm))) - continue; - - CandForm.dwIndex = iCandForm; - CandForm.dwStyle = CFS_EXCLUDE; - CandForm.ptCurrentPos = pIC->cfCompForm.ptCurrentPos; - CandForm.rcArea = pIC->cfCompForm.rcArea; - pSendMessage(hwndDefIME, WM_IME_CONTROL, IMC_SETCANDIDATEPOS, - (LPARAM)&CandForm); - } - } - } - - if (!(pIC->dwUIFlags & 0x2)) - goto DoDefault; - - // send a WM_IME_NOTIFY notification to the default ime window - pSendMessage(hwndDefIME, pEntry->message, pEntry->wParam, pEntry->lParam); - break; - -DoDefault: - default: - // default processing - *pTrans++ = *pEntry; - ++ret; - break; - } - } - - HeapFree(g_hImm32Heap, 0, pTempList); - return ret; -} - -static DWORD APIENTRY -ImpKTrans(DWORD dwCount, LPTRANSMSG pEntries, LPINPUTCONTEXTDX pIC, - LPCOMPOSITIONSTRING pCS, BOOL bAnsi) -{ - return dwCount; // FIXME -} - -static DWORD APIENTRY -ImpTrans(DWORD dwCount, LPTRANSMSG pEntries, HIMC hIMC, BOOL bAnsi, WORD wLang) -{ - BOOL ret = FALSE; - LPINPUTCONTEXTDX pIC; - LPCOMPOSITIONSTRING pCS; - - pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC); - if (pIC == NULL) - return 0; - - pCS = ImmLockIMCC(pIC->hCompStr); - if (pCS) - { - if (wLang == LANG_JAPANESE) - ret = ImpJTrans(dwCount, pEntries, pIC, pCS, bAnsi); - else if (wLang == LANG_KOREAN) - ret = ImpKTrans(dwCount, pEntries, pIC, pCS, bAnsi); - ImmUnlockIMCC(pIC->hCompStr); - } - - ImmUnlockIMC(hIMC); - return ret; -} -#endif /* def IMP_SUPPORT */ - -static PIMEDPI APIENTRY Ime32LoadImeDpi(HKL hKL, BOOL bLock) -{ - IMEINFOEX ImeInfoEx; - CHARSETINFO ci; - PIMEDPI pImeDpiNew, pImeDpiFound; - UINT uCodePage; - LCID lcid; - - if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL) || - ImeInfoEx.fLoadFlag == 1) - { - return NULL; - } - - pImeDpiNew = Imm32HeapAlloc(HEAP_ZERO_MEMORY, sizeof(IMEDPI)); - if (pImeDpiNew == NULL) - return NULL; - - pImeDpiNew->hKL = hKL; - - lcid = LOWORD(hKL); - if (TranslateCharsetInfo((LPDWORD)(DWORD_PTR)lcid, &ci, TCI_SRCLOCALE)) - uCodePage = ci.ciACP; - else - uCodePage = CP_ACP; - pImeDpiNew->uCodePage = uCodePage; - - if (!Imm32LoadImeInfo(&ImeInfoEx, pImeDpiNew)) - { - HeapFree(g_hImm32Heap, 0, pImeDpiNew); - return FALSE; - } - - RtlEnterCriticalSection(&g_csImeDpi); - - pImeDpiFound = Imm32FindImeDpi(hKL); - if (pImeDpiFound) - { - if (!bLock) - pImeDpiFound->dwFlags &= ~IMEDPI_FLAG_LOCKED; - - RtlLeaveCriticalSection(&g_csImeDpi); - - Imm32FreeImeDpi(pImeDpiNew, FALSE); - HeapFree(g_hImm32Heap, 0, pImeDpiNew); - return pImeDpiFound; - } - else - { - if (bLock) - { - pImeDpiNew->dwFlags |= IMEDPI_FLAG_LOCKED; - pImeDpiNew->cLockObj = 1; - } - - pImeDpiNew->pNext = g_pImeDpiList; - g_pImeDpiList = pImeDpiNew; - - RtlLeaveCriticalSection(&g_csImeDpi); - return pImeDpiNew; - } -} - /*********************************************************************** - * ImmLoadIME (IMM32.@) + * ImmRegisterClient(IMM32.@) + * ( Undocumented, called from user32.dll ) */ -BOOL WINAPI ImmLoadIME(HKL hKL) -{ - PW32CLIENTINFO pInfo; - PIMEDPI pImeDpi; - - if (!IS_IME_HKL(hKL)) - { - if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)) - return FALSE; - - pInfo = (PW32CLIENTINFO)(NtCurrentTeb()->Win32ClientInfo); - if ((pInfo->W32ClientInfo[0] & 2)) - return FALSE; - } - - pImeDpi = Imm32FindImeDpi(hKL); - if (pImeDpi == NULL) - pImeDpi = Ime32LoadImeDpi(hKL, FALSE); - return (pImeDpi != NULL); -} - -PIMEDPI APIENTRY ImmLockOrLoadImeDpi(HKL hKL) +BOOL WINAPI ImmRegisterClient(PSHAREDINFO ptr, HINSTANCE hMod) { - PW32CLIENTINFO pInfo; - PIMEDPI pImeDpi; - - if (!IS_IME_HKL(hKL)) - { - if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)) - return NULL; - - pInfo = (PW32CLIENTINFO)(NtCurrentTeb()->Win32ClientInfo); - if ((pInfo->W32ClientInfo[0] & 2)) - return NULL; - } - - pImeDpi = ImmLockImeDpi(hKL); - if (pImeDpi == NULL) - pImeDpi = Ime32LoadImeDpi(hKL, TRUE); - return pImeDpi; + g_SharedInfo = *ptr; + g_psi = g_SharedInfo.psi; + return Imm32InitInstance(hMod); }
/*********************************************************************** @@ -730,7 +103,8 @@ HKL WINAPI ImmLoadLayout(HKL hKL, PIMEINFOEX pImeInfoEx) return hKL; }
-typedef struct _tagImmHkl{ +typedef struct _tagImmHkl +{ struct list entry; HKL hkl; HMODULE hIME; @@ -760,19 +134,20 @@ typedef struct _tagImmHkl{
typedef struct tagInputContextData { - DWORD dwLock; - INPUTCONTEXT IMC; - DWORD threadID; - - ImmHkl *immKbd; - UINT lastVK; - BOOL threadDefault; - DWORD magic; + DWORD dwLock; + INPUTCONTEXT IMC; + DWORD threadID; + + ImmHkl *immKbd; + UINT lastVK; + BOOL threadDefault; + DWORD magic; } InputContextData;
#define WINE_IMC_VALID_MAGIC 0x56434D49
-typedef struct _tagIMMThreadData { +typedef struct _tagIMMThreadData +{ struct list entry; DWORD threadID; HIMC defaultContext; @@ -790,18 +165,6 @@ static const WCHAR szImeFileW[] = {'I','m','e',' ','F','i','l','e',0}; static const WCHAR szLayoutTextW[] = {'L','a','y','o','u','t',' ','T','e','x','t',0}; static const WCHAR szImeRegFmt[] = {'S','y','s','t','e','m','\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\','C','o','n','t','r','o','l','\','K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','s','\','%','0','8','l','x',0};
-static const WCHAR szwIME[] = {'I','M','E',0}; -static const WCHAR szwDefaultIME[] = {'D','e','f','a','u','l','t',' ','I','M','E',0}; - -static CRITICAL_SECTION threaddata_cs; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &threaddata_cs, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": threaddata_cs") } -}; -static CRITICAL_SECTION threaddata_cs = { &critsect_debug, -1, 0, 0, 0, 0 }; - static inline BOOL is_himc_ime_unicode(const InputContextData *data) { return !!(data->immKbd->imeInfo.fdwProperty & IME_PROP_UNICODE); @@ -1038,7 +401,6 @@ HIMC WINAPI ImmAssociateContext(HWND hWnd, HIMC hIMC) return old; }
- /* * Helper function for ImmAssociateContextEx */ @@ -1087,8 +449,7 @@ BOOL WINAPI ImmAssociateContextEx(HWND hWnd, HIMC hIMC, DWORD dwFlags) /*********************************************************************** * ImmConfigureIMEA (IMM32.@) */ -BOOL WINAPI ImmConfigureIMEA( - HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData) +BOOL WINAPI ImmConfigureIMEA(HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData) { ImmHkl *immHkl = IMM_GetImmHkl(hKL);
@@ -1122,8 +483,7 @@ BOOL WINAPI ImmConfigureIMEA( /*********************************************************************** * ImmConfigureIMEW (IMM32.@) */ -BOOL WINAPI ImmConfigureIMEW( - HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData) +BOOL WINAPI ImmConfigureIMEW(HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData) { ImmHkl *immHkl = IMM_GetImmHkl(hKL);
@@ -1285,232 +645,25 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC) return Imm32CleanupContext(hIMC, hKL, FALSE); }
-/*********************************************************************** - * ImmDisableIME (IMM32.@) - */ -BOOL WINAPI ImmDisableIME(DWORD dwThreadId) +static inline BOOL EscapeRequiresWA(UINT uEscape) { - return NtUserDisableThreadIme(dwThreadId); + if (uEscape == IME_ESC_GET_EUDC_DICTIONARY || + uEscape == IME_ESC_SET_EUDC_DICTIONARY || + uEscape == IME_ESC_IME_NAME || + uEscape == IME_ESC_GETHELPFILENAME) + return TRUE; + return FALSE; }
-/* - * These functions absorb the difference between Ansi and Wide. +/*********************************************************************** + * ImmEscapeA (IMM32.@) */ -typedef struct ENUM_WORD_A2W -{ - REGISTERWORDENUMPROCW lpfnEnumProc; - LPVOID lpData; - UINT ret; -} ENUM_WORD_A2W, *LPENUM_WORD_A2W; - -typedef struct ENUM_WORD_W2A -{ - REGISTERWORDENUMPROCA lpfnEnumProc; - LPVOID lpData; - UINT ret; -} ENUM_WORD_W2A, *LPENUM_WORD_W2A; - -static INT CALLBACK -Imm32EnumWordProcA2W(LPCSTR pszReadingA, DWORD dwStyle, LPCSTR pszRegisterA, LPVOID lpData) +LRESULT WINAPI ImmEscapeA(HKL hKL, HIMC hIMC, UINT uEscape, LPVOID lpData) { - INT ret = 0; - LPENUM_WORD_A2W lpEnumData = lpData; - LPWSTR pszReadingW = NULL, pszRegisterW = NULL; - - if (pszReadingA) - { - pszReadingW = Imm32WideFromAnsi(pszReadingA); - if (pszReadingW == NULL) - goto Quit; - } + ImmHkl *immHkl = IMM_GetImmHkl(hKL); + TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData);
- if (pszRegisterA) - { - pszRegisterW = Imm32WideFromAnsi(pszRegisterA); - if (pszRegisterW == NULL) - goto Quit; - } - - ret = lpEnumData->lpfnEnumProc(pszReadingW, dwStyle, pszRegisterW, lpEnumData->lpData); - lpEnumData->ret = ret; - -Quit: - if (pszReadingW) - HeapFree(g_hImm32Heap, 0, pszReadingW); - if (pszRegisterW) - HeapFree(g_hImm32Heap, 0, pszRegisterW); - return ret; -} - -static INT CALLBACK -Imm32EnumWordProcW2A(LPCWSTR pszReadingW, DWORD dwStyle, LPCWSTR pszRegisterW, LPVOID lpData) -{ - INT ret = 0; - LPENUM_WORD_W2A lpEnumData = lpData; - LPSTR pszReadingA = NULL, pszRegisterA = NULL; - - if (pszReadingW) - { - pszReadingA = Imm32AnsiFromWide(pszReadingW); - if (pszReadingW == NULL) - goto Quit; - } - - if (pszRegisterW) - { - pszRegisterA = Imm32AnsiFromWide(pszRegisterW); - if (pszRegisterA == NULL) - goto Quit; - } - - ret = lpEnumData->lpfnEnumProc(pszReadingA, dwStyle, pszRegisterA, lpEnumData->lpData); - lpEnumData->ret = ret; - -Quit: - if (pszReadingA) - HeapFree(g_hImm32Heap, 0, pszReadingA); - if (pszRegisterA) - HeapFree(g_hImm32Heap, 0, pszRegisterA); - return ret; -} - -/*********************************************************************** - * ImmEnumRegisterWordA (IMM32.@) - */ -UINT WINAPI ImmEnumRegisterWordA( - HKL hKL, REGISTERWORDENUMPROCA lpfnEnumProc, - LPCSTR lpszReading, DWORD dwStyle, - LPCSTR lpszRegister, LPVOID lpData) -{ - UINT ret = 0; - LPWSTR pszReadingW = NULL, pszRegisterW = NULL; - ENUM_WORD_W2A EnumDataW2A; - PIMEDPI pImeDpi; - - TRACE("(%p, %p, %s, 0x%lX, %s, %p)", hKL, lpfnEnumProc, debugstr_a(lpszReading), - dwStyle, debugstr_a(lpszRegister), lpData); - - pImeDpi = ImmLockOrLoadImeDpi(hKL); - if (!pImeDpi) - return 0; - - if (!(pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE)) - { - ret = pImeDpi->ImeEnumRegisterWord(lpfnEnumProc, lpszReading, dwStyle, - lpszRegister, lpData); - ImmUnlockImeDpi(pImeDpi); - return ret; - } - - if (lpszReading) - { - pszReadingW = Imm32WideFromAnsi(lpszReading); - if (pszReadingW == NULL) - goto Quit; - } - - if (lpszRegister) - { - pszRegisterW = Imm32WideFromAnsi(lpszRegister); - if (pszRegisterW == NULL) - goto Quit; - } - - EnumDataW2A.lpfnEnumProc = lpfnEnumProc; - EnumDataW2A.lpData = lpData; - EnumDataW2A.ret = 0; - pImeDpi->ImeEnumRegisterWord(Imm32EnumWordProcW2A, pszReadingW, dwStyle, - pszRegisterW, &EnumDataW2A); - ret = EnumDataW2A.ret; - -Quit: - if (pszReadingW) - HeapFree(g_hImm32Heap, 0, pszReadingW); - if (pszRegisterW) - HeapFree(g_hImm32Heap, 0, pszRegisterW); - ImmUnlockImeDpi(pImeDpi); - return ret; -} - -/*********************************************************************** - * ImmEnumRegisterWordW (IMM32.@) - */ -UINT WINAPI ImmEnumRegisterWordW( - HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc, - LPCWSTR lpszReading, DWORD dwStyle, - LPCWSTR lpszRegister, LPVOID lpData) -{ - UINT ret = 0; - LPSTR pszReadingA = NULL, pszRegisterA = NULL; - ENUM_WORD_A2W EnumDataA2W; - PIMEDPI pImeDpi; - - TRACE("(%p, %p, %s, 0x%lX, %s, %p)", hKL, lpfnEnumProc, debugstr_w(lpszReading), - dwStyle, debugstr_w(lpszRegister), lpData); - - pImeDpi = ImmLockOrLoadImeDpi(hKL); - if (!pImeDpi) - return 0; - - if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) - { - ret = pImeDpi->ImeEnumRegisterWord(lpfnEnumProc, lpszReading, dwStyle, - lpszRegister, lpData); - ImmUnlockImeDpi(pImeDpi); - return ret; - } - - if (lpszReading) - { - pszReadingA = Imm32AnsiFromWide(lpszReading); - if (pszReadingA == NULL) - goto Quit; - } - - if (lpszRegister) - { - pszRegisterA = Imm32AnsiFromWide(lpszRegister); - if (pszRegisterA == NULL) - goto Quit; - } - - EnumDataA2W.lpfnEnumProc = lpfnEnumProc; - EnumDataA2W.lpData = lpData; - EnumDataA2W.ret = 0; - pImeDpi->ImeEnumRegisterWord(Imm32EnumWordProcA2W, pszReadingA, dwStyle, - pszRegisterA, &EnumDataA2W); - ret = EnumDataA2W.ret; - -Quit: - if (pszReadingA) - HeapFree(g_hImm32Heap, 0, pszReadingA); - if (pszRegisterA) - HeapFree(g_hImm32Heap, 0, pszRegisterA); - ImmUnlockImeDpi(pImeDpi); - return ret; -} - -static inline BOOL EscapeRequiresWA(UINT uEscape) -{ - if (uEscape == IME_ESC_GET_EUDC_DICTIONARY || - uEscape == IME_ESC_SET_EUDC_DICTIONARY || - uEscape == IME_ESC_IME_NAME || - uEscape == IME_ESC_GETHELPFILENAME) - return TRUE; - return FALSE; -} - -/*********************************************************************** - * ImmEscapeA (IMM32.@) - */ -LRESULT WINAPI ImmEscapeA( - HKL hKL, HIMC hIMC, - UINT uEscape, LPVOID lpData) -{ - ImmHkl *immHkl = IMM_GetImmHkl(hKL); - TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData); - - if (immHkl->hIME && immHkl->pImeEscape) + if (immHkl->hIME && immHkl->pImeEscape) { if (!EscapeRequiresWA(uEscape) || !is_kbd_ime_unicode(immHkl)) return immHkl->pImeEscape(hIMC,uEscape,lpData); @@ -1538,9 +691,7 @@ LRESULT WINAPI ImmEscapeA( /*********************************************************************** * ImmEscapeW (IMM32.@) */ -LRESULT WINAPI ImmEscapeW( - HKL hKL, HIMC hIMC, - UINT uEscape, LPVOID lpData) +LRESULT WINAPI ImmEscapeW(HKL hKL, HIMC hIMC, UINT uEscape, LPVOID lpData) { ImmHkl *immHkl = IMM_GetImmHkl(hKL); TRACE("(%p, %p, %d, %p):\n", hKL, hIMC, uEscape, lpData); @@ -1576,266 +727,6 @@ static PCLIENTIMC APIENTRY Imm32GetClientImcCache(void) return NULL; }
-static DWORD APIENTRY Imm32AllocAndBuildHimcList(DWORD dwThreadId, HIMC **pphList) -{ -#define INITIAL_COUNT 0x40 -#define MAX_RETRY 10 - NTSTATUS Status; - DWORD dwCount = INITIAL_COUNT, cRetry = 0; - HIMC *phNewList; - - phNewList = Imm32HeapAlloc(0, dwCount * sizeof(HIMC)); - if (phNewList == NULL) - return 0; - - Status = NtUserBuildHimcList(dwThreadId, dwCount, phNewList, &dwCount); - while (Status == STATUS_BUFFER_TOO_SMALL) - { - HeapFree(g_hImm32Heap, 0, phNewList); - if (cRetry++ >= MAX_RETRY) - return 0; - - phNewList = Imm32HeapAlloc(0, dwCount * sizeof(HIMC)); - if (phNewList == NULL) - return 0; - - Status = NtUserBuildHimcList(dwThreadId, dwCount, phNewList, &dwCount); - } - - if (NT_ERROR(Status) || !dwCount) - { - HeapFree(g_hImm32Heap, 0, phNewList); - return 0; - } - - *pphList = phNewList; - return dwCount; -#undef INITIAL_COUNT -#undef MAX_RETRY -} - -static BOOL APIENTRY Imm32ImeNonImeToggle(HIMC hIMC, HKL hKL, HWND hWnd, LANGID LangID) -{ - LPINPUTCONTEXT pIC; - BOOL fOpen; - - if (hWnd != NULL) - return FALSE; - - if (!IS_IME_HKL(hKL) || LOWORD(hKL) != LangID) - { - FIXME("We have to do something here\n"); - return TRUE; - } - - pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - return TRUE; - - fOpen = pIC->fOpen; - ImmUnlockIMC(hIMC); - - if (!fOpen) - { - ImmSetOpenStatus(hIMC, TRUE); - return TRUE; - } - - FIXME("We have to do something here\n"); - return TRUE; -} - -static BOOL APIENTRY Imm32CShapeToggle(HIMC hIMC, HKL hKL, HWND hWnd) -{ - LPINPUTCONTEXT pIC; - BOOL fOpen; - DWORD dwConversion, dwSentence; - - if (hWnd == NULL || !IS_IME_HKL(hKL)) - return FALSE; - - pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - return TRUE; - - fOpen = pIC->fOpen; - if (fOpen) - { - dwConversion = (pIC->fdwConversion ^ IME_CMODE_FULLSHAPE); - dwSentence = pIC->fdwSentence; - } - - ImmUnlockIMC(hIMC); - - if (fOpen) - ImmSetConversionStatus(hIMC, dwConversion, dwSentence); - else - ImmSetOpenStatus(hIMC, TRUE); - - return TRUE; -} - -static BOOL APIENTRY Imm32CSymbolToggle(HIMC hIMC, HKL hKL, HWND hWnd) -{ - LPINPUTCONTEXT pIC; - BOOL fOpen; - DWORD dwConversion, dwSentence; - - if (hWnd == NULL || !IS_IME_HKL(hKL)) - return FALSE; - - pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - return TRUE; - - fOpen = pIC->fOpen; - if (fOpen) - { - dwConversion = (pIC->fdwConversion ^ IME_CMODE_SYMBOL); - dwSentence = pIC->fdwSentence; - } - - ImmUnlockIMC(hIMC); - - if (fOpen) - ImmSetConversionStatus(hIMC, dwConversion, dwSentence); - else - ImmSetOpenStatus(hIMC, TRUE); - - return TRUE; -} - -static BOOL APIENTRY Imm32JCloseOpen(HIMC hIMC, HKL hKL, HWND hWnd) -{ - BOOL fOpen; - - if (ImmIsIME(hKL) && LOWORD(hKL) == LANGID_JAPANESE) - { - fOpen = ImmGetOpenStatus(hIMC); - ImmSetOpenStatus(hIMC, !fOpen); - return TRUE; - } - - FIXME("We have to do something here\n"); - return TRUE; -} - -static BOOL APIENTRY Imm32KShapeToggle(HIMC hIMC) -{ - LPINPUTCONTEXT pIC; - DWORD dwConversion, dwSentence; - - pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - return FALSE; - - dwConversion = (pIC->fdwConversion ^ IME_CMODE_FULLSHAPE); - dwSentence = pIC->fdwSentence; - ImmSetConversionStatus(hIMC, dwConversion, dwSentence); - - if (pIC->fdwConversion & (IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE)) - ImmSetOpenStatus(hIMC, TRUE); - else - ImmSetOpenStatus(hIMC, FALSE); - - ImmUnlockIMC(hIMC); - return TRUE; -} - -static BOOL APIENTRY Imm32KHanjaConvert(HIMC hIMC) -{ - LPINPUTCONTEXT pIC; - DWORD dwConversion, dwSentence; - - pIC = ImmLockIMC(hIMC); - if (!pIC) - return FALSE; - - dwConversion = (pIC->fdwConversion ^ IME_CMODE_HANJACONVERT); - dwSentence = pIC->fdwSentence; - ImmUnlockIMC(hIMC); - - ImmSetConversionStatus(hIMC, dwConversion, dwSentence); - return TRUE; -} - -static BOOL APIENTRY Imm32KEnglish(HIMC hIMC) -{ - LPINPUTCONTEXT pIC; - DWORD dwConversion, dwSentence; - BOOL fOpen; - - pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - return FALSE; - - dwConversion = (pIC->fdwConversion ^ IME_CMODE_NATIVE); - dwSentence = pIC->fdwSentence; - ImmSetConversionStatus(hIMC, dwConversion, dwSentence); - - fOpen = ((pIC->fdwConversion & (IME_CMODE_FULLSHAPE | IME_CMODE_NATIVE)) != 0); - ImmSetOpenStatus(hIMC, fOpen); - - ImmUnlockIMC(hIMC); - return TRUE; -} - -static BOOL APIENTRY Imm32ProcessHotKey(HWND hWnd, HIMC hIMC, HKL hKL, DWORD dwHotKeyID) -{ - PIMEDPI pImeDpi; - BOOL ret; - - if (hIMC && Imm32IsCrossThreadAccess(hIMC)) - return FALSE; - - switch (dwHotKeyID) - { - case IME_CHOTKEY_IME_NONIME_TOGGLE: - return Imm32ImeNonImeToggle(hIMC, hKL, hWnd, LANGID_CHINESE_SIMPLIFIED); - - case IME_CHOTKEY_SHAPE_TOGGLE: - return Imm32CShapeToggle(hIMC, hKL, hWnd); - - case IME_CHOTKEY_SYMBOL_TOGGLE: - return Imm32CSymbolToggle(hIMC, hKL, hWnd); - - case IME_JHOTKEY_CLOSE_OPEN: - return Imm32JCloseOpen(hIMC, hKL, hWnd); - - case IME_KHOTKEY_SHAPE_TOGGLE: - return Imm32KShapeToggle(hIMC); - - case IME_KHOTKEY_HANJACONVERT: - return Imm32KHanjaConvert(hIMC); - - case IME_KHOTKEY_ENGLISH: - return Imm32KEnglish(hIMC); - - case IME_THOTKEY_IME_NONIME_TOGGLE: - return Imm32ImeNonImeToggle(hIMC, hKL, hWnd, LANGID_CHINESE_TRADITIONAL); - - case IME_THOTKEY_SHAPE_TOGGLE: - return Imm32CShapeToggle(hIMC, hKL, hWnd); - - case IME_THOTKEY_SYMBOL_TOGGLE: - return Imm32CSymbolToggle(hIMC, hKL, hWnd); - - default: - break; - } - - if (dwHotKeyID < IME_HOTKEY_PRIVATE_FIRST || IME_HOTKEY_PRIVATE_LAST < dwHotKeyID) - return FALSE; - - pImeDpi = ImmLockImeDpi(hKL); - if (pImeDpi == NULL) - return FALSE; - - ret = (BOOL)pImeDpi->ImeEscape(hIMC, IME_ESC_PRIVATE_HOTKEY, &dwHotKeyID); - ImmUnlockImeDpi(pImeDpi); - return ret; -} - /*********************************************************************** * ImmLockClientImc (IMM32.@) */ @@ -1934,671 +825,210 @@ Quit: return hIMC; }
-static DWORD APIENTRY -CandidateListWideToAnsi(const CANDIDATELIST *pWideCL, LPCANDIDATELIST pAnsiCL, DWORD dwBufLen, - UINT uCodePage) + +/* Helpers for the GetCompositionString functions */ + +/* Source encoding is defined by context, source length is always given in respective characters. Destination buffer + length is always in bytes. */ +static INT +CopyCompStringIMEtoClient(const InputContextData *data, const void *src, INT src_len, void *dst, + INT dst_len, BOOL unicode) { - BOOL bUsedDefault; - DWORD dwSize, dwIndex, cbGot, cbLeft; - const BYTE *pbWide; - LPBYTE pbAnsi; - LPDWORD pibOffsets; - - /* calculate total ansi size */ - if (pWideCL->dwCount > 0) + int char_size = unicode ? sizeof(WCHAR) : sizeof(char); + INT ret; + + if (is_himc_ime_unicode(data) ^ unicode) { - dwSize = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * sizeof(DWORD)); - for (dwIndex = 0; dwIndex < pWideCL->dwCount; ++dwIndex) - { - pbWide = (const BYTE *)pWideCL + pWideCL->dwOffset[dwIndex]; - cbGot = WideCharToMultiByte(uCodePage, 0, (LPCWSTR)pbWide, -1, NULL, 0, - NULL, &bUsedDefault); - dwSize += cbGot; - } + if (unicode) + ret = MultiByteToWideChar(CP_ACP, 0, src, src_len, dst, dst_len / sizeof(WCHAR)); + else + ret = WideCharToMultiByte(CP_ACP, 0, src, src_len, dst, dst_len, NULL, NULL); + ret *= char_size; } else { - dwSize = sizeof(CANDIDATELIST); + if (dst_len) + { + ret = min(src_len * char_size, dst_len); + memcpy(dst, src, ret); + } + else + ret = src_len * char_size; }
- dwSize = ROUNDUP4(dwSize); - if (dwBufLen == 0) - return dwSize; - if (dwBufLen < dwSize) - return 0; - - /* store to ansi */ - pAnsiCL->dwSize = dwBufLen; - pAnsiCL->dwStyle = pWideCL->dwStyle; - pAnsiCL->dwCount = pWideCL->dwCount; - pAnsiCL->dwSelection = pWideCL->dwSelection; - pAnsiCL->dwPageStart = pWideCL->dwPageStart; - pAnsiCL->dwPageSize = pWideCL->dwPageSize; + return ret; +}
- pibOffsets = pAnsiCL->dwOffset; - if (pWideCL->dwCount > 0) +/* Composition string encoding is defined by context, returned attributes correspond to string, converted according to + passed mode. String length is in characters, attributes are in byte arrays. */ +static INT +CopyCompAttrIMEtoClient(const InputContextData *data, const BYTE *src, INT src_len, const void *comp_string, + INT str_len, BYTE *dst, INT dst_len, BOOL unicode) +{ + union { - pibOffsets[0] = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * sizeof(DWORD)); - cbLeft = dwBufLen - pibOffsets[0]; - - for (dwIndex = 0; dwIndex < pWideCL->dwCount; ++dwIndex) - { - pbWide = (const BYTE *)pWideCL + pWideCL->dwOffset[dwIndex]; - pbAnsi = (LPBYTE)pAnsiCL + pibOffsets[dwIndex]; + const void *str; + const WCHAR *strW; + const char *strA; + } string; + INT rc;
- /* convert to ansi */ - cbGot = WideCharToMultiByte(uCodePage, 0, (LPCWSTR)pbWide, -1, - (LPSTR)pbAnsi, cbLeft, NULL, &bUsedDefault); - cbLeft -= cbGot; + string.str = comp_string;
- if (dwIndex < pWideCL->dwCount - 1) - pibOffsets[dwIndex + 1] = pibOffsets[dwIndex] + cbGot; - } - } - else + if (is_himc_ime_unicode(data) && !unicode) { - pibOffsets[0] = sizeof(CANDIDATELIST); - } + rc = WideCharToMultiByte(CP_ACP, 0, string.strW, str_len, NULL, 0, NULL, NULL); + if (dst_len) + { + int i, j = 0, k = 0;
- return dwBufLen; -} + if (rc < dst_len) + dst_len = rc; + for (i = 0; i < str_len; ++i) + { + int len;
-static DWORD APIENTRY -CandidateListAnsiToWide(const CANDIDATELIST *pAnsiCL, LPCANDIDATELIST pWideCL, DWORD dwBufLen, - UINT uCodePage) -{ - DWORD dwSize, dwIndex, cchGot, cbGot, cbLeft; - const BYTE *pbAnsi; - LPBYTE pbWide; - LPDWORD pibOffsets; + len = WideCharToMultiByte(CP_ACP, 0, string.strW + i, 1, NULL, 0, NULL, NULL); + for (; len > 0; --len) + { + dst[j++] = src[k];
- /* calculate total wide size */ - if (pAnsiCL->dwCount > 0) - { - dwSize = sizeof(CANDIDATELIST) + ((pAnsiCL->dwCount - 1) * sizeof(DWORD)); - for (dwIndex = 0; dwIndex < pAnsiCL->dwCount; ++dwIndex) - { - pbAnsi = (const BYTE *)pAnsiCL + pAnsiCL->dwOffset[dwIndex]; - cchGot = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, (LPCSTR)pbAnsi, -1, NULL, 0); - dwSize += cchGot * sizeof(WCHAR); + if (j >= dst_len) + goto end; + } + ++k; + } + end: + rc = j; } } - else - { - dwSize = sizeof(CANDIDATELIST); - } - - dwSize = ROUNDUP4(dwSize); - if (dwBufLen == 0) - return dwSize; - if (dwBufLen < dwSize) - return 0; - - /* store to wide */ - pWideCL->dwSize = dwBufLen; - pWideCL->dwStyle = pAnsiCL->dwStyle; - pWideCL->dwCount = pAnsiCL->dwCount; - pWideCL->dwSelection = pAnsiCL->dwSelection; - pWideCL->dwPageStart = pAnsiCL->dwPageStart; - pWideCL->dwPageSize = pAnsiCL->dwPageSize; - - pibOffsets = pWideCL->dwOffset; - if (pAnsiCL->dwCount > 0) + else if (!is_himc_ime_unicode(data) && unicode) { - pibOffsets[0] = sizeof(CANDIDATELIST) + ((pWideCL->dwCount - 1) * sizeof(DWORD)); - cbLeft = dwBufLen - pibOffsets[0]; - - for (dwIndex = 0; dwIndex < pAnsiCL->dwCount; ++dwIndex) + rc = MultiByteToWideChar(CP_ACP, 0, string.strA, str_len, NULL, 0); + if (dst_len) { - pbAnsi = (const BYTE *)pAnsiCL + pAnsiCL->dwOffset[dwIndex]; - pbWide = (LPBYTE)pWideCL + pibOffsets[dwIndex]; + int i, j = 0; + + if (rc < dst_len) + dst_len = rc; + for (i = 0; i < str_len; ++i) + { + if (IsDBCSLeadByte(string.strA[i])) + continue;
- /* convert to wide */ - cchGot = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, (LPCSTR)pbAnsi, -1, - (LPWSTR)pbWide, cbLeft / sizeof(WCHAR)); - cbGot = cchGot * sizeof(WCHAR); - cbLeft -= cbGot; + dst[j++] = src[i];
- if (dwIndex + 1 < pAnsiCL->dwCount) - pibOffsets[dwIndex + 1] = pibOffsets[dwIndex] + cbGot; + if (j >= dst_len) + break; + } + rc = j; } } else { - pibOffsets[0] = sizeof(CANDIDATELIST); + memcpy(dst, src, min(src_len, dst_len)); + rc = src_len; }
- return dwBufLen; + return rc; }
-static DWORD APIENTRY -ImmGetCandidateListAW(HIMC hIMC, DWORD dwIndex, LPCANDIDATELIST lpCandList, DWORD dwBufLen, - BOOL bAnsi) +static INT +CopyCompClauseIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, + LPBYTE target, INT tlen, BOOL unicode ) { - DWORD ret = 0; - LPINPUTCONTEXT pIC; - PCLIENTIMC pClientImc; - LPCANDIDATEINFO pCI; - LPCANDIDATELIST pCL; - DWORD dwSize; - - pClientImc = ImmLockClientImc(hIMC); - if (!pClientImc) - return 0; - - pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - { - ImmUnlockClientImc(pClientImc); - return 0; - } - - pCI = ImmLockIMCC(pIC->hCandInfo); - if (pCI == NULL) - { - ImmUnlockIMC(hIMC); - ImmUnlockClientImc(pClientImc); - return 0; - } - - if (pCI->dwSize < sizeof(CANDIDATEINFO) || pCI->dwCount <= dwIndex) - goto Quit; - - /* get required size */ - pCL = (LPCANDIDATELIST)((LPBYTE)pCI + pCI->dwOffset[dwIndex]); - if (bAnsi) - { - if (pClientImc->dwFlags & CLIENTIMC_WIDE) - dwSize = CandidateListAnsiToWide(pCL, NULL, 0, CP_ACP); - else - dwSize = pCL->dwSize; - } - else - { - if (pClientImc->dwFlags & CLIENTIMC_WIDE) - dwSize = pCL->dwSize; - else - dwSize = CandidateListWideToAnsi(pCL, NULL, 0, CP_ACP); - } + INT rc;
- if (dwBufLen != 0 && dwSize != 0) + if (is_himc_ime_unicode(data) && !unicode) { - if (lpCandList == NULL || dwBufLen < dwSize) - goto Quit; - - /* store */ - if (bAnsi) + if (tlen) { - if (pClientImc->dwFlags & CLIENTIMC_WIDE) - CandidateListAnsiToWide(pCL, lpCandList, dwSize, CP_ACP); - else - RtlCopyMemory(lpCandList, pCL, dwSize); + int i; + + if (slen < tlen) + tlen = slen; + tlen /= sizeof (DWORD); + for (i = 0; i < tlen; ++i) + { + ((DWORD *)target)[i] = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, + ((DWORD *)source)[i], + NULL, 0, + NULL, NULL); + } + rc = sizeof (DWORD) * i; } else - { - if (pClientImc->dwFlags & CLIENTIMC_WIDE) - RtlCopyMemory(lpCandList, pCL, dwSize); - else - CandidateListWideToAnsi(pCL, lpCandList, dwSize, CP_ACP); - } - } - - ret = dwSize; - -Quit: - ImmUnlockIMCC(pIC->hCandInfo); - ImmUnlockIMC(hIMC); - ImmUnlockClientImc(pClientImc); - return ret; -} - -DWORD APIENTRY ImmGetCandidateListCountAW(HIMC hIMC, LPDWORD lpdwListCount, BOOL bAnsi) -{ - DWORD ret = 0, cbGot, dwIndex; - PCLIENTIMC pClientImc; - LPINPUTCONTEXT pIC; - const CANDIDATEINFO *pCI; - const BYTE *pb; - const CANDIDATELIST *pCL; - const DWORD *pdwOffsets; - - if (lpdwListCount == NULL) - return 0; - - *lpdwListCount = 0; - - pClientImc = ImmLockClientImc(hIMC); - if (pClientImc == NULL) - return 0; - - pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - { - ImmUnlockClientImc(pClientImc); - return 0; - } - - pCI = ImmLockIMCC(pIC->hCandInfo); - if (pCI == NULL) - { - ImmUnlockIMC(hIMC); - ImmUnlockClientImc(pClientImc); - return 0; + rc = slen; } - - if (pCI->dwSize < sizeof(CANDIDATEINFO)) - goto Quit; - - *lpdwListCount = pCI->dwCount; /* the number of candidate lists */ - - /* calculate total size of candidate lists */ - if (bAnsi) + else if (!is_himc_ime_unicode(data) && unicode) { - if (pClientImc->dwFlags & CLIENTIMC_WIDE) + if (tlen) { - ret = ROUNDUP4(pCI->dwPrivateSize); - pdwOffsets = pCI->dwOffset; - for (dwIndex = 0; dwIndex < pCI->dwCount; ++dwIndex) + int i; + + if (slen < tlen) + tlen = slen; + tlen /= sizeof (DWORD); + for (i = 0; i < tlen; ++i) { - pb = (const BYTE *)pCI + pdwOffsets[dwIndex]; - pCL = (const CANDIDATELIST *)pb; - cbGot = CandidateListWideToAnsi(pCL, NULL, 0, CP_ACP); - ret += cbGot; + ((DWORD *)target)[i] = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, + ((DWORD *)source)[i], + NULL, 0); } + rc = sizeof (DWORD) * i; } else - { - ret = pCI->dwSize; - } + rc = slen; } else { - if (pClientImc->dwFlags & CLIENTIMC_WIDE) - { - ret = pCI->dwSize; - } - else - { - ret = ROUNDUP4(pCI->dwPrivateSize); - pdwOffsets = pCI->dwOffset; - for (dwIndex = 0; dwIndex < pCI->dwCount; ++dwIndex) - { - pb = (const BYTE *)pCI + pdwOffsets[dwIndex]; - pCL = (const CANDIDATELIST *)pb; - cbGot = CandidateListAnsiToWide(pCL, NULL, 0, CP_ACP); - ret += cbGot; - } - } + memcpy( target, source, min(slen,tlen)); + rc = slen; }
-Quit: - ImmUnlockIMCC(pIC->hCandInfo); - ImmUnlockIMC(hIMC); - ImmUnlockClientImc(pClientImc); - return ret; -} - -/*********************************************************************** - * ImmGetCandidateListA (IMM32.@) - */ -DWORD WINAPI ImmGetCandidateListA( - HIMC hIMC, DWORD dwIndex, - LPCANDIDATELIST lpCandList, DWORD dwBufLen) -{ - return ImmGetCandidateListAW(hIMC, dwIndex, lpCandList, dwBufLen, TRUE); -} - -/*********************************************************************** - * ImmGetCandidateListCountA (IMM32.@) - */ -DWORD WINAPI ImmGetCandidateListCountA( - HIMC hIMC, LPDWORD lpdwListCount) -{ - return ImmGetCandidateListCountAW(hIMC, lpdwListCount, TRUE); -} - -/*********************************************************************** - * ImmGetCandidateListCountW (IMM32.@) - */ -DWORD WINAPI ImmGetCandidateListCountW( - HIMC hIMC, LPDWORD lpdwListCount) -{ - return ImmGetCandidateListCountAW(hIMC, lpdwListCount, FALSE); -} - -/*********************************************************************** - * ImmGetCandidateListW (IMM32.@) - */ -DWORD WINAPI ImmGetCandidateListW( - HIMC hIMC, DWORD dwIndex, - LPCANDIDATELIST lpCandList, DWORD dwBufLen) -{ - return ImmGetCandidateListAW(hIMC, dwIndex, lpCandList, dwBufLen, FALSE); + return rc; }
-/*********************************************************************** - * ImmGetCandidateWindow (IMM32.@) - */ -BOOL WINAPI ImmGetCandidateWindow( - HIMC hIMC, DWORD dwIndex, LPCANDIDATEFORM lpCandidate) +static INT +CopyCompOffsetIMEtoClient(InputContextData *data, DWORD offset, LPBYTE ssource, BOOL unicode) { - BOOL ret = FALSE; - LPINPUTCONTEXT pIC; - LPCANDIDATEFORM pCF; - - TRACE("(%p, %lu, %p)\n", hIMC, dwIndex, lpCandidate); - - pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - return FALSE; + int rc;
- pCF = &pIC->cfCandForm[dwIndex]; - if (pCF->dwIndex != IMM_INVALID_CANDFORM) + if (is_himc_ime_unicode(data) && !unicode) { - *lpCandidate = *pCF; - ret = TRUE; + rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, offset, NULL, 0, NULL, NULL); } + else if (!is_himc_ime_unicode(data) && unicode) + { + rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, offset, NULL, 0); + } + else + rc = offset;
- ImmUnlockIMC(hIMC); - return ret; -} - -static VOID APIENTRY LogFontAnsiToWide(const LOGFONTA *plfA, LPLOGFONTW plfW) -{ - size_t cch; - RtlCopyMemory(plfW, plfA, offsetof(LOGFONTA, lfFaceName)); - StringCchLengthA(plfA->lfFaceName, _countof(plfA->lfFaceName), &cch); - cch = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, plfA->lfFaceName, (INT)cch, - plfW->lfFaceName, _countof(plfW->lfFaceName)); - if (cch > _countof(plfW->lfFaceName) - 1) - cch = _countof(plfW->lfFaceName) - 1; - plfW->lfFaceName[cch] = 0; -} - -static VOID APIENTRY LogFontWideToAnsi(const LOGFONTW *plfW, LPLOGFONTA plfA) -{ - size_t cch; - RtlCopyMemory(plfA, plfW, offsetof(LOGFONTW, lfFaceName)); - StringCchLengthW(plfW->lfFaceName, _countof(plfW->lfFaceName), &cch); - cch = WideCharToMultiByte(CP_ACP, 0, plfW->lfFaceName, (INT)cch, - plfA->lfFaceName, _countof(plfA->lfFaceName), NULL, NULL); - if (cch > _countof(plfA->lfFaceName) - 1) - cch = _countof(plfA->lfFaceName) - 1; - plfA->lfFaceName[cch] = 0; + return rc; }
-/*********************************************************************** - * ImmGetCompositionFontA (IMM32.@) - */ -BOOL WINAPI ImmGetCompositionFontA(HIMC hIMC, LPLOGFONTA lplf) +static LONG +ImmGetCompositionStringT(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, + DWORD dwBufLen, BOOL unicode) { - PCLIENTIMC pClientImc; - BOOL ret = FALSE, bWide; - LPINPUTCONTEXT pIC; + LONG rc = 0; + InputContextData *data = get_imc_data(hIMC); + LPCOMPOSITIONSTRING compstr; + LPBYTE compdata;
- TRACE("(%p, %p)\n", hIMC, lplf); + TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen);
- pClientImc = ImmLockClientImc(hIMC); - if (pClientImc == NULL) - return FALSE; + if (!data) + return FALSE;
- bWide = (pClientImc->dwFlags & CLIENTIMC_WIDE); - ImmUnlockClientImc(pClientImc); + if (!data->IMC.hCompStr) + return FALSE;
- pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - return FALSE; + compdata = ImmLockIMCC(data->IMC.hCompStr); + compstr = (LPCOMPOSITIONSTRING)compdata;
- if (pIC->fdwInit & INIT_LOGFONT) - { - if (bWide) - LogFontWideToAnsi(&pIC->lfFont.W, lplf); - else - *lplf = pIC->lfFont.A; - - ret = TRUE; - } - - ImmUnlockIMC(hIMC); - return ret; -} - -/*********************************************************************** - * ImmGetCompositionFontW (IMM32.@) - */ -BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf) -{ - PCLIENTIMC pClientImc; - BOOL bWide; - LPINPUTCONTEXT pIC; - BOOL ret = FALSE; - - TRACE("(%p, %p)\n", hIMC, lplf); - - pClientImc = ImmLockClientImc(hIMC); - if (pClientImc == NULL) - return FALSE; - - bWide = (pClientImc->dwFlags & CLIENTIMC_WIDE); - ImmUnlockClientImc(pClientImc); - - pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - return FALSE; - - if (pIC->fdwInit & INIT_LOGFONT) - { - if (bWide) - *lplf = pIC->lfFont.W; - else - LogFontAnsiToWide(&pIC->lfFont.A, lplf); - - ret = TRUE; - } - - ImmUnlockIMC(hIMC); - return ret; -} - - -/* Helpers for the GetCompositionString functions */ - -/* Source encoding is defined by context, source length is always given in respective characters. Destination buffer - length is always in bytes. */ -static INT CopyCompStringIMEtoClient(const InputContextData *data, const void *src, INT src_len, void *dst, - INT dst_len, BOOL unicode) -{ - int char_size = unicode ? sizeof(WCHAR) : sizeof(char); - INT ret; - - if (is_himc_ime_unicode(data) ^ unicode) - { - if (unicode) - ret = MultiByteToWideChar(CP_ACP, 0, src, src_len, dst, dst_len / sizeof(WCHAR)); - else - ret = WideCharToMultiByte(CP_ACP, 0, src, src_len, dst, dst_len, NULL, NULL); - ret *= char_size; - } - else - { - if (dst_len) - { - ret = min(src_len * char_size, dst_len); - memcpy(dst, src, ret); - } - else - ret = src_len * char_size; - } - - return ret; -} - -/* Composition string encoding is defined by context, returned attributes correspond to string, converted according to - passed mode. String length is in characters, attributes are in byte arrays. */ -static INT CopyCompAttrIMEtoClient(const InputContextData *data, const BYTE *src, INT src_len, const void *comp_string, - INT str_len, BYTE *dst, INT dst_len, BOOL unicode) -{ - union - { - const void *str; - const WCHAR *strW; - const char *strA; - } string; - INT rc; - - string.str = comp_string; - - if (is_himc_ime_unicode(data) && !unicode) - { - rc = WideCharToMultiByte(CP_ACP, 0, string.strW, str_len, NULL, 0, NULL, NULL); - if (dst_len) - { - int i, j = 0, k = 0; - - if (rc < dst_len) - dst_len = rc; - for (i = 0; i < str_len; ++i) - { - int len; - - len = WideCharToMultiByte(CP_ACP, 0, string.strW + i, 1, NULL, 0, NULL, NULL); - for (; len > 0; --len) - { - dst[j++] = src[k]; - - if (j >= dst_len) - goto end; - } - ++k; - } - end: - rc = j; - } - } - else if (!is_himc_ime_unicode(data) && unicode) - { - rc = MultiByteToWideChar(CP_ACP, 0, string.strA, str_len, NULL, 0); - if (dst_len) - { - int i, j = 0; - - if (rc < dst_len) - dst_len = rc; - for (i = 0; i < str_len; ++i) - { - if (IsDBCSLeadByte(string.strA[i])) - continue; - - dst[j++] = src[i]; - - if (j >= dst_len) - break; - } - rc = j; - } - } - else - { - memcpy(dst, src, min(src_len, dst_len)); - rc = src_len; - } - - return rc; -} - -static INT CopyCompClauseIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, - LPBYTE target, INT tlen, BOOL unicode ) -{ - INT rc; - - if (is_himc_ime_unicode(data) && !unicode) - { - if (tlen) - { - int i; - - if (slen < tlen) - tlen = slen; - tlen /= sizeof (DWORD); - for (i = 0; i < tlen; ++i) - { - ((DWORD *)target)[i] = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, - ((DWORD *)source)[i], - NULL, 0, - NULL, NULL); - } - rc = sizeof (DWORD) * i; - } - else - rc = slen; - } - else if (!is_himc_ime_unicode(data) && unicode) - { - if (tlen) - { - int i; - - if (slen < tlen) - tlen = slen; - tlen /= sizeof (DWORD); - for (i = 0; i < tlen; ++i) - { - ((DWORD *)target)[i] = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, - ((DWORD *)source)[i], - NULL, 0); - } - rc = sizeof (DWORD) * i; - } - else - rc = slen; - } - else - { - memcpy( target, source, min(slen,tlen)); - rc = slen; - } - - return rc; -} - -static INT CopyCompOffsetIMEtoClient(InputContextData *data, DWORD offset, LPBYTE ssource, BOOL unicode) -{ - int rc; - - if (is_himc_ime_unicode(data) && !unicode) - { - rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)ssource, offset, NULL, 0, NULL, NULL); - } - else if (!is_himc_ime_unicode(data) && unicode) - { - rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)ssource, offset, NULL, 0); - } - else - rc = offset; - - return rc; -} - -static LONG ImmGetCompositionStringT( HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, - DWORD dwBufLen, BOOL unicode) -{ - LONG rc = 0; - InputContextData *data = get_imc_data(hIMC); - LPCOMPOSITIONSTRING compstr; - LPBYTE compdata; - - TRACE("(%p, 0x%x, %p, %d)\n", hIMC, dwIndex, lpBuf, dwBufLen); - - if (!data) - return FALSE; - - if (!data->IMC.hCompStr) - return FALSE; - - compdata = ImmLockIMCC(data->IMC.hCompStr); - compstr = (LPCOMPOSITIONSTRING)compdata; - - switch (dwIndex) + switch (dwIndex) { case GCS_RESULTSTR: TRACE("GCS_RESULTSTR\n"); @@ -2673,47 +1103,19 @@ static LONG ImmGetCompositionStringT( HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, /*********************************************************************** * ImmGetCompositionStringA (IMM32.@) */ -LONG WINAPI ImmGetCompositionStringA( - HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen) +LONG WINAPI ImmGetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen) { return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, FALSE); }
- /*********************************************************************** * ImmGetCompositionStringW (IMM32.@) */ -LONG WINAPI ImmGetCompositionStringW( - HIMC hIMC, DWORD dwIndex, - LPVOID lpBuf, DWORD dwBufLen) +LONG WINAPI ImmGetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen) { return ImmGetCompositionStringT(hIMC, dwIndex, lpBuf, dwBufLen, TRUE); }
-/*********************************************************************** - * ImmGetCompositionWindow (IMM32.@) - */ -BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm) -{ - LPINPUTCONTEXT pIC; - BOOL ret = FALSE; - - TRACE("(%p, %p)\n", hIMC, lpCompForm); - - pIC = ImmLockIMC(hIMC); - if (!pIC) - return FALSE; - - if (pIC->fdwInit & INIT_COMPFORM) - { - *lpCompForm = pIC->cfCompForm; - ret = TRUE; - } - - ImmUnlockIMC(hIMC); - return ret; -} - /*********************************************************************** * ImmGetContext (IMM32.@) */ @@ -2726,1806 +1128,96 @@ HIMC WINAPI ImmGetContext(HWND hWnd) }
/*********************************************************************** - * ImmGetConversionListA (IMM32.@) + * CtfImmIsCiceroEnabled (IMM32.@) */ -DWORD WINAPI ImmGetConversionListA( - HKL hKL, HIMC hIMC, - LPCSTR pSrc, LPCANDIDATELIST lpDst, - DWORD dwBufLen, UINT uFlag) +BOOL WINAPI CtfImmIsCiceroEnabled(VOID) { - DWORD ret = 0; - UINT cb; - LPWSTR pszSrcW = NULL; - LPCANDIDATELIST pCL = NULL; - PIMEDPI pImeDpi; - - TRACE("(%p, %p, %s, %p, %lu, 0x%lX)\n", hKL, hIMC, debugstr_a(pSrc), - lpDst, dwBufLen, uFlag); - - pImeDpi = ImmLockOrLoadImeDpi(hKL); - if (pImeDpi == NULL) - return 0; + return (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)); +}
- if (!(pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE)) - { - ret = pImeDpi->ImeConversionList(hIMC, pSrc, lpDst, dwBufLen, uFlag); - ImmUnlockImeDpi(pImeDpi); - return ret; - } +/*********************************************************************** + * ImmInstallIMEA (IMM32.@) + */ +HKL WINAPI ImmInstallIMEA(LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText) +{ + HKL hKL = NULL; + LPWSTR pszFileNameW = NULL, pszLayoutTextW = NULL;
- if (pSrc) - { - pszSrcW = Imm32WideFromAnsi(pSrc); - if (pszSrcW == NULL) - goto Quit; - } + TRACE("(%s, %s)\n", debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText));
- cb = pImeDpi->ImeConversionList(hIMC, pszSrcW, NULL, 0, uFlag); - if (cb == 0) + pszFileNameW = Imm32WideFromAnsi(lpszIMEFileName); + if (pszFileNameW == NULL) goto Quit;
- pCL = Imm32HeapAlloc(0, cb); - if (pCL == NULL) + pszLayoutTextW = Imm32WideFromAnsi(lpszLayoutText); + if (pszLayoutTextW == NULL) goto Quit;
- cb = pImeDpi->ImeConversionList(hIMC, pszSrcW, pCL, cb, uFlag); - if (cb == 0) - goto Quit; - - ret = CandidateListWideToAnsi(pCL, lpDst, dwBufLen, CP_ACP); - -Quit: - if (pszSrcW) - HeapFree(g_hImm32Heap, 0, pszSrcW); - if (pCL) - HeapFree(g_hImm32Heap, 0, pCL); - ImmUnlockImeDpi(pImeDpi); - return ret; -} - -/*********************************************************************** - * ImmGetConversionListW (IMM32.@) - */ -DWORD WINAPI ImmGetConversionListW( - HKL hKL, HIMC hIMC, - LPCWSTR pSrc, LPCANDIDATELIST lpDst, - DWORD dwBufLen, UINT uFlag) -{ - DWORD ret = 0; - INT cb; - PIMEDPI pImeDpi; - LPCANDIDATELIST pCL = NULL; - LPSTR pszSrcA = NULL; - - TRACE("(%p, %p, %s, %p, %lu, 0x%lX)\n", hKL, hIMC, debugstr_w(pSrc), - lpDst, dwBufLen, uFlag); - - pImeDpi = ImmLockOrLoadImeDpi(hKL); - if (!pImeDpi) - return 0; - - if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) - { - ret = pImeDpi->ImeConversionList(hIMC, pSrc, lpDst, dwBufLen, uFlag); - ImmUnlockImeDpi(pImeDpi); - return ret; - } - - if (pSrc) - { - pszSrcA = Imm32AnsiFromWide(pSrc); - if (pszSrcA == NULL) - goto Quit; - } - - cb = pImeDpi->ImeConversionList(hIMC, pszSrcA, NULL, 0, uFlag); - if (cb == 0) - goto Quit; - - pCL = Imm32HeapAlloc(0, cb); - if (!pCL) - goto Quit; - - cb = pImeDpi->ImeConversionList(hIMC, pszSrcA, pCL, cb, uFlag); - if (!cb) - goto Quit; - - ret = CandidateListAnsiToWide(pCL, lpDst, dwBufLen, CP_ACP); - -Quit: - if (pszSrcA) - HeapFree(g_hImm32Heap, 0, pszSrcA); - if (pCL) - HeapFree(g_hImm32Heap, 0, pCL); - ImmUnlockImeDpi(pImeDpi); - return ret; -} - -/*********************************************************************** - * ImmGetConversionStatus (IMM32.@) - */ -BOOL WINAPI ImmGetConversionStatus( - HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence) -{ - LPINPUTCONTEXT pIC; - - TRACE("(%p %p %p)\n", hIMC, lpfdwConversion, lpfdwSentence); - - pIC = ImmLockIMC(hIMC); - if (!pIC) - return FALSE; - - if (lpfdwConversion) - *lpfdwConversion = pIC->fdwConversion; - if (lpfdwSentence) - *lpfdwSentence = pIC->fdwSentence; - - ImmUnlockIMC(hIMC); - return TRUE; -} - -/*********************************************************************** - * ImmGetDefaultIMEWnd (IMM32.@) - */ -HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd) -{ - if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_IMM32)) - return NULL; - - // FIXME: NtUserGetThreadState and enum ThreadStateRoutines are broken. - if (hWnd == NULL) - return (HWND)NtUserGetThreadState(3); - - return (HWND)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_IME); -} - -/*********************************************************************** - * CtfImmIsCiceroEnabled (IMM32.@) - */ -BOOL WINAPI CtfImmIsCiceroEnabled(VOID) -{ - return (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)); -} - -/*********************************************************************** - * ImmGetDescriptionA (IMM32.@) - */ -UINT WINAPI ImmGetDescriptionA( - HKL hKL, LPSTR lpszDescription, UINT uBufLen) -{ - IMEINFOEX info; - size_t cch; - - TRACE("(%p,%p,%d)\n", hKL, lpszDescription, uBufLen); - - if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL)) - return 0; - - StringCchLengthW(info.wszImeDescription, _countof(info.wszImeDescription), &cch); - cch = WideCharToMultiByte(CP_ACP, 0, info.wszImeDescription, (INT)cch, - lpszDescription, uBufLen, NULL, NULL); - if (uBufLen) - lpszDescription[cch] = 0; - return (UINT)cch; -} - -/*********************************************************************** - * ImmGetDescriptionW (IMM32.@) - */ -UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen) -{ - IMEINFOEX info; - size_t cch; - - TRACE("(%p, %p, %d)\n", hKL, lpszDescription, uBufLen); - - if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL)) - return 0; - - if (uBufLen != 0) - StringCchCopyW(lpszDescription, uBufLen, info.wszImeDescription); - - StringCchLengthW(info.wszImeDescription, _countof(info.wszImeDescription), &cch); - return (UINT)cch; -} - -static DWORD APIENTRY -ImmGetGuideLineAW(HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsi) -{ - PCLIENTIMC pClientImc; - LPINPUTCONTEXT pIC; - LPGUIDELINE pGuideLine; - DWORD cb, ret = 0; - LPVOID pvStr, pvPrivate; - BOOL bUsedDefault; - - pClientImc = ImmLockClientImc(hIMC); - if (!pClientImc) - return 0; - - pIC = ImmLockIMC(hIMC); - if (!pIC) - { - ImmUnlockClientImc(pClientImc); - return 0; - } - - pGuideLine = ImmLockIMCC(pIC->hGuideLine); - if (!pGuideLine) - { - ImmUnlockIMC(hIMC); - ImmUnlockClientImc(pClientImc); - return 0; - } - - if (dwIndex == GGL_LEVEL) - { - ret = pGuideLine->dwLevel; - goto Quit; - } - - if (dwIndex == GGL_INDEX) - { - ret = pGuideLine->dwIndex; - goto Quit; - } - - if (dwIndex == GGL_STRING) - { - pvStr = (LPBYTE)pGuideLine + pGuideLine->dwStrOffset; - - /* get size */ - if (bAnsi) - { - if (pClientImc->dwFlags & CLIENTIMC_WIDE) - { - cb = WideCharToMultiByte(CP_ACP, 0, pvStr, pGuideLine->dwStrLen, - NULL, 0, NULL, &bUsedDefault); - } - else - { - cb = pGuideLine->dwStrLen * sizeof(CHAR); - } - } - else - { - if (pClientImc->dwFlags & CLIENTIMC_WIDE) - { - cb = pGuideLine->dwStrLen * sizeof(WCHAR); - } - else - { - cb = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pvStr, pGuideLine->dwStrLen, - NULL, 0) * sizeof(WCHAR); - } - } - - if (dwBufLen == 0 || cb == 0 || lpBuf == NULL || dwBufLen < cb) - { - ret = cb; - goto Quit; - } - - /* store to buffer */ - if (bAnsi) - { - if (pClientImc->dwFlags & CLIENTIMC_WIDE) - { - ret = WideCharToMultiByte(CP_ACP, 0, pvStr, pGuideLine->dwStrLen, - lpBuf, dwBufLen, NULL, &bUsedDefault); - goto Quit; - } - } - else - { - if (!(pClientImc->dwFlags & CLIENTIMC_WIDE)) - { - ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pvStr, pGuideLine->dwStrLen, - lpBuf, dwBufLen) * sizeof(WCHAR); - goto Quit; - } - } - - RtlCopyMemory(lpBuf, pvStr, cb); - ret = cb; - goto Quit; - } - - if (dwIndex == GGL_PRIVATE) - { - pvPrivate = (LPBYTE)pGuideLine + pGuideLine->dwPrivateOffset; - - /* get size */ - if (bAnsi) - { - if ((pClientImc->dwFlags & CLIENTIMC_WIDE) && - pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) - { - cb = CandidateListWideToAnsi(pvPrivate, NULL, 0, CP_ACP); - } - else - { - cb = pGuideLine->dwPrivateSize; - } - } - else - { - if (!(pClientImc->dwFlags & CLIENTIMC_WIDE) && - pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) - { - cb = CandidateListAnsiToWide(pvPrivate, NULL, 0, CP_ACP); - } - else - { - cb = pGuideLine->dwPrivateSize; - } - } - - if (dwBufLen == 0 || cb == 0 || lpBuf == NULL || dwBufLen < cb) - { - ret = cb; - goto Quit; - } - - /* store to buffer */ - if (bAnsi) - { - if ((pClientImc->dwFlags & CLIENTIMC_WIDE) && - pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) - { - ret = CandidateListWideToAnsi(pvPrivate, lpBuf, cb, CP_ACP); - goto Quit; - } - } - else - { - if (!(pClientImc->dwFlags & CLIENTIMC_WIDE) && - pGuideLine->dwIndex == GL_ID_REVERSECONVERSION) - { - ret = CandidateListAnsiToWide(pvPrivate, lpBuf, cb, CP_ACP); - goto Quit; - } - } - - RtlCopyMemory(lpBuf, pvPrivate, cb); - ret = cb; - goto Quit; - } - -Quit: - ImmUnlockIMCC(pIC->hGuideLine); - ImmUnlockIMC(hIMC); - ImmUnlockClientImc(pClientImc); - return ret; -} - -/*********************************************************************** - * ImmGetGuideLineA (IMM32.@) - */ -DWORD WINAPI ImmGetGuideLineA( - HIMC hIMC, DWORD dwIndex, LPSTR lpBuf, DWORD dwBufLen) -{ - TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen); - return ImmGetGuideLineAW(hIMC, dwIndex, lpBuf, dwBufLen, TRUE); -} - -/*********************************************************************** - * ImmGetGuideLineW (IMM32.@) - */ -DWORD WINAPI ImmGetGuideLineW(HIMC hIMC, DWORD dwIndex, LPWSTR lpBuf, DWORD dwBufLen) -{ - TRACE("(%p, %lu, %p, %lu)\n", hIMC, dwIndex, lpBuf, dwBufLen); - return ImmGetGuideLineAW(hIMC, dwIndex, lpBuf, dwBufLen, FALSE); -} - -/*********************************************************************** - * ImmGetIMEFileNameA (IMM32.@) - */ -UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen) -{ - BOOL bDefUsed; - IMEINFOEX info; - size_t cch; - - TRACE("(%p, %p, %u)\n", hKL, lpszFileName, uBufLen); - - if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL)) - { - if (uBufLen > 0) - lpszFileName[0] = 0; - return 0; - } - - StringCchLengthW(info.wszImeFile, _countof(info.wszImeFile), &cch); - - cch = WideCharToMultiByte(CP_ACP, 0, info.wszImeFile, (INT)cch, - lpszFileName, uBufLen, NULL, &bDefUsed); - if (uBufLen == 0) - return (UINT)cch; - - if (cch > uBufLen - 1) - cch = uBufLen - 1; - - lpszFileName[cch] = 0; - return (UINT)cch; -} - -/*********************************************************************** - * ImmGetIMEFileNameW (IMM32.@) - */ -UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen) -{ - IMEINFOEX info; - size_t cch; - - TRACE("(%p, %p, %u)\n", hKL, lpszFileName, uBufLen); - - if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL)) - { - if (uBufLen > 0) - lpszFileName[0] = 0; - return 0; - } - - StringCchLengthW(info.wszImeFile, _countof(info.wszImeFile), &cch); - if (uBufLen == 0) - return (UINT)cch; - - StringCchCopyNW(lpszFileName, uBufLen, info.wszImeFile, cch); - - if (cch > uBufLen - 1) - cch = uBufLen - 1; - - lpszFileName[cch] = 0; - return (UINT)cch; -} - -/*********************************************************************** - * ImmGetOpenStatus (IMM32.@) - */ -BOOL WINAPI ImmGetOpenStatus(HIMC hIMC) -{ - BOOL ret; - LPINPUTCONTEXT pIC; - - TRACE("(%p)\n", hIMC); - - if (!hIMC) - return FALSE; - - pIC = ImmLockIMC(hIMC); - if (!pIC) - return FALSE; - - ret = pIC->fOpen; - - ImmUnlockIMC(hIMC); - return ret; -} - -/*********************************************************************** - * ImmGetProperty (IMM32.@) - */ -DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex) -{ - IMEINFOEX ImeInfoEx; - LPIMEINFO pImeInfo; - DWORD dwValue; - PIMEDPI pImeDpi = NULL; - - TRACE("(%p, %lu)\n", hKL, fdwIndex); - - if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL)) - return FALSE; - - if (fdwIndex == IGP_GETIMEVERSION) - return ImeInfoEx.dwImeWinVersion; - - if (ImeInfoEx.fLoadFlag != 2) - { - pImeDpi = ImmLockOrLoadImeDpi(hKL); - if (pImeDpi == NULL) - return FALSE; - - pImeInfo = &pImeDpi->ImeInfo; - } - else - { - pImeInfo = &ImeInfoEx.ImeInfo; - } - - switch (fdwIndex) - { - case IGP_PROPERTY: dwValue = pImeInfo->fdwProperty; break; - case IGP_CONVERSION: dwValue = pImeInfo->fdwConversionCaps; break; - case IGP_SENTENCE: dwValue = pImeInfo->fdwSentenceCaps; break; - case IGP_UI: dwValue = pImeInfo->fdwUICaps; break; - case IGP_SETCOMPSTR: dwValue = pImeInfo->fdwSCSCaps; break; - case IGP_SELECT: dwValue = pImeInfo->fdwSelectCaps; break; - default: dwValue = 0; break; - } - - if (pImeDpi) - ImmUnlockImeDpi(pImeDpi); - return dwValue; -} - -/*********************************************************************** - * ImmGetRegisterWordStyleA (IMM32.@) - */ -UINT WINAPI ImmGetRegisterWordStyleA( - HKL hKL, UINT nItem, LPSTYLEBUFA lpStyleBuf) -{ - UINT iItem, ret = 0; - PIMEDPI pImeDpi; - LPSTYLEBUFA pDestA; - LPSTYLEBUFW pSrcW, pNewStylesW = NULL; - size_t cchW; - INT cchA; - - TRACE("(%p, %u, %p)\n", hKL, nItem, lpStyleBuf); - - pImeDpi = ImmLockOrLoadImeDpi(hKL); - if (!pImeDpi) - return 0; - - if (!(pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE)) - { - ret = pImeDpi->ImeGetRegisterWordStyle(nItem, lpStyleBuf); - goto Quit; - } - - if (nItem > 0) - { - pNewStylesW = Imm32HeapAlloc(0, nItem * sizeof(STYLEBUFW)); - if (!pNewStylesW) - goto Quit; - } - - ret = pImeDpi->ImeGetRegisterWordStyle(nItem, pNewStylesW); - - if (nItem > 0) - { - /* lpStyleBuf <-- pNewStylesW */ - for (iItem = 0; iItem < ret; ++iItem) - { - pSrcW = &pNewStylesW[iItem]; - pDestA = &lpStyleBuf[iItem]; - pDestA->dwStyle = pSrcW->dwStyle; - StringCchLengthW(pSrcW->szDescription, _countof(pSrcW->szDescription), &cchW); - cchA = WideCharToMultiByte(CP_ACP, MB_PRECOMPOSED, - pSrcW->szDescription, (INT)cchW, - pDestA->szDescription, _countof(pDestA->szDescription), - NULL, NULL); - if (cchA > _countof(pDestA->szDescription) - 1) - cchA = _countof(pDestA->szDescription) - 1; - pDestA->szDescription[cchA] = 0; - } - } - -Quit: - if (pNewStylesW) - HeapFree(g_hImm32Heap, 0, pNewStylesW); - ImmUnlockImeDpi(pImeDpi); - return ret; -} - -/*********************************************************************** - * ImmGetRegisterWordStyleW (IMM32.@) - */ -UINT WINAPI ImmGetRegisterWordStyleW( - HKL hKL, UINT nItem, LPSTYLEBUFW lpStyleBuf) -{ - UINT iItem, ret = 0; - PIMEDPI pImeDpi; - LPSTYLEBUFA pSrcA, pNewStylesA = NULL; - LPSTYLEBUFW pDestW; - size_t cchA; - INT cchW; - - TRACE("(%p, %u, %p)\n", hKL, nItem, lpStyleBuf); - - pImeDpi = ImmLockOrLoadImeDpi(hKL); - if (!pImeDpi) - return 0; - - if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) - { - ret = pImeDpi->ImeGetRegisterWordStyle(nItem, lpStyleBuf); - goto Quit; - } - - if (nItem > 0) - { - pNewStylesA = Imm32HeapAlloc(0, nItem * sizeof(STYLEBUFA)); - if (!pNewStylesA) - goto Quit; - } - - ret = pImeDpi->ImeGetRegisterWordStyle(nItem, pNewStylesA); - - if (nItem > 0) - { - /* lpStyleBuf <-- pNewStylesA */ - for (iItem = 0; iItem < ret; ++iItem) - { - pSrcA = &pNewStylesA[iItem]; - pDestW = &lpStyleBuf[iItem]; - pDestW->dwStyle = pSrcA->dwStyle; - StringCchLengthA(pSrcA->szDescription, _countof(pSrcA->szDescription), &cchA); - cchW = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, - pSrcA->szDescription, (INT)cchA, - pDestW->szDescription, _countof(pDestW->szDescription)); - if (cchW > _countof(pDestW->szDescription) - 1) - cchW = _countof(pDestW->szDescription) - 1; - pDestW->szDescription[cchW] = 0; - } - } - -Quit: - if (pNewStylesA) - HeapFree(g_hImm32Heap, 0, pNewStylesA); - ImmUnlockImeDpi(pImeDpi); - return ret; -} - -/*********************************************************************** - * ImmGetStatusWindowPos (IMM32.@) - */ -BOOL WINAPI ImmGetStatusWindowPos(HIMC hIMC, LPPOINT lpptPos) -{ - LPINPUTCONTEXT pIC; - BOOL ret; - - TRACE("(%p, %p)\n", hIMC, lpptPos); - - pIC = ImmLockIMC(hIMC); - if (pIC == NULL) - return FALSE; - - ret = !!(pIC->fdwInit & INIT_STATUSWNDPOS); - if (ret) - *lpptPos = pIC->ptStatusWndPos; - - ImmUnlockIMC(hIMC); - return ret; -} - -/*********************************************************************** - * ImmGetVirtualKey (IMM32.@) - */ -UINT WINAPI ImmGetVirtualKey(HWND hWnd) -{ - HIMC hIMC; - LPINPUTCONTEXTDX pIC; - UINT ret = VK_PROCESSKEY; - - TRACE("(%p)\n", hWnd); - - hIMC = ImmGetContext(hWnd); - pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC); - if (!pIC) - return ret; - - if (pIC->bNeedsTrans) - ret = pIC->nVKey; - - ImmUnlockIMC(hIMC); - return ret; -} - -/*********************************************************************** - * ImmInstallIMEA (IMM32.@) - */ -HKL WINAPI ImmInstallIMEA( - LPCSTR lpszIMEFileName, LPCSTR lpszLayoutText) -{ - HKL hKL = NULL; - LPWSTR pszFileNameW = NULL, pszLayoutTextW = NULL; - - TRACE("(%s, %s)\n", debugstr_a(lpszIMEFileName), debugstr_a(lpszLayoutText)); - - pszFileNameW = Imm32WideFromAnsi(lpszIMEFileName); - if (pszFileNameW == NULL) - goto Quit; - - pszLayoutTextW = Imm32WideFromAnsi(lpszLayoutText); - if (pszLayoutTextW == NULL) - goto Quit; - - hKL = ImmInstallIMEW(pszFileNameW, pszLayoutTextW); - -Quit: - if (pszFileNameW) - HeapFree(g_hImm32Heap, 0, pszFileNameW); - if (pszLayoutTextW) - HeapFree(g_hImm32Heap, 0, pszLayoutTextW); - return hKL; -} - -/*********************************************************************** - * ImmInstallIMEW (IMM32.@) - */ -HKL WINAPI ImmInstallIMEW( - LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText) -{ - INT lcid = GetUserDefaultLCID(); - INT count; - HKL hkl; - DWORD rc; - HKEY hkey; - WCHAR regKey[ARRAY_SIZE(szImeRegFmt)+8]; - - TRACE ("(%s, %s):\n", debugstr_w(lpszIMEFileName), - debugstr_w(lpszLayoutText)); - - /* Start with 2. e001 will be blank and so default to the wine internal IME */ - count = 2; - - while (count < 0xfff) - { - DWORD disposition = 0; - - hkl = (HKL)MAKELPARAM( lcid, 0xe000 | count ); - wsprintfW( regKey, szImeRegFmt, (ULONG_PTR)hkl); - - rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, regKey, 0, NULL, 0, KEY_WRITE, NULL, &hkey, &disposition); - if (rc == ERROR_SUCCESS && disposition == REG_CREATED_NEW_KEY) - break; - else if (rc == ERROR_SUCCESS) - RegCloseKey(hkey); - - count++; - } - - if (count == 0xfff) - { - WARN("Unable to find slot to install IME\n"); - return 0; - } - - if (rc == ERROR_SUCCESS) - { - rc = RegSetValueExW(hkey, szImeFileW, 0, REG_SZ, (const BYTE*)lpszIMEFileName, - (lstrlenW(lpszIMEFileName) + 1) * sizeof(WCHAR)); - if (rc == ERROR_SUCCESS) - rc = RegSetValueExW(hkey, szLayoutTextW, 0, REG_SZ, (const BYTE*)lpszLayoutText, - (lstrlenW(lpszLayoutText) + 1) * sizeof(WCHAR)); - RegCloseKey(hkey); - return hkl; - } - else - { - WARN("Unable to set IME registry values\n"); - return 0; - } -} - -/*********************************************************************** - * ImmIsIME (IMM32.@) - */ -BOOL WINAPI ImmIsIME(HKL hKL) -{ - IMEINFOEX info; - TRACE("(%p)\n", hKL); - return !!ImmGetImeInfoEx(&info, ImeInfoExImeWindow, &hKL); -} - -static BOOL APIENTRY -ImmIsUIMessageAW(HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam, BOOL bAnsi) -{ - switch (msg) - { - case WM_IME_STARTCOMPOSITION: case WM_IME_ENDCOMPOSITION: - case WM_IME_COMPOSITION: case WM_IME_SETCONTEXT: case WM_IME_NOTIFY: - case WM_IME_COMPOSITIONFULL: case WM_IME_SELECT: case WM_IME_SYSTEM: - break; - default: - return FALSE; - } - - if (!hWndIME) - return TRUE; - - if (bAnsi) - SendMessageA(hWndIME, msg, wParam, lParam); - else - SendMessageW(hWndIME, msg, wParam, lParam); - - return TRUE; -} - -/*********************************************************************** - * ImmIsUIMessageA (IMM32.@) - */ -BOOL WINAPI ImmIsUIMessageA( - HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TRACE("(%p, 0x%X, %p, %p)\n", hWndIME, msg, wParam, lParam); - return ImmIsUIMessageAW(hWndIME, msg, wParam, lParam, TRUE); -} - -/*********************************************************************** - * ImmIsUIMessageW (IMM32.@) - */ -BOOL WINAPI ImmIsUIMessageW( - HWND hWndIME, UINT msg, WPARAM wParam, LPARAM lParam) -{ - TRACE("(%p, 0x%X, %p, %p)\n", hWndIME, msg, wParam, lParam); - return ImmIsUIMessageAW(hWndIME, msg, wParam, lParam, FALSE); -} - -/*********************************************************************** - * ImmNotifyIME (IMM32.@) - */ -BOOL WINAPI ImmNotifyIME( - HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue) -{ - HKL hKL; - PIMEDPI pImeDpi; - BOOL ret; - - TRACE("(%p, %lu, %lu, %lu)\n", hIMC, dwAction, dwIndex, dwValue); - - if (hIMC && Imm32IsCrossThreadAccess(hIMC)) - return FALSE; - - hKL = GetKeyboardLayout(0); - pImeDpi = ImmLockImeDpi(hKL); - if (pImeDpi == NULL) - return FALSE; - - ret = pImeDpi->NotifyIME(hIMC, dwAction, dwIndex, dwValue); - ImmUnlockImeDpi(pImeDpi); - return ret; -} - -/*********************************************************************** - * ImmRegisterWordA (IMM32.@) - */ -BOOL WINAPI ImmRegisterWordA( - HKL hKL, LPCSTR lpszReading, DWORD dwStyle, LPCSTR lpszRegister) -{ - BOOL ret = FALSE; - PIMEDPI pImeDpi; - LPWSTR pszReadingW = NULL, pszRegisterW = NULL; - - TRACE("(%p, %s, 0x%lX, %s)\n", hKL, debugstr_a(lpszReading), dwStyle, - debugstr_a(lpszRegister)); - - pImeDpi = ImmLockOrLoadImeDpi(hKL); - if (!pImeDpi) - return FALSE; - - if (!(pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE)) - { - ret = pImeDpi->ImeRegisterWord(lpszReading, dwStyle, lpszRegister); - ImmUnlockImeDpi(pImeDpi); - return ret; - } - - if (lpszReading) - { - pszReadingW = Imm32WideFromAnsi(lpszReading); - if (pszReadingW == NULL) - goto Quit; - } - - if (lpszRegister) - { - pszRegisterW = Imm32WideFromAnsi(lpszRegister); - if (pszRegisterW == NULL) - goto Quit; - } - - ret = pImeDpi->ImeRegisterWord(pszReadingW, dwStyle, pszRegisterW); - -Quit: - if (pszReadingW) - HeapFree(g_hImm32Heap, 0, pszReadingW); - if (pszRegisterW) - HeapFree(g_hImm32Heap, 0, pszRegisterW); - ImmUnlockImeDpi(pImeDpi); - return ret; -} - -/*********************************************************************** - * ImmRegisterWordW (IMM32.@) - */ -BOOL WINAPI ImmRegisterWordW( - HKL hKL, LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszRegister) -{ - BOOL ret = FALSE; - PIMEDPI pImeDpi; - LPSTR pszReadingA = NULL, pszRegisterA = NULL; - - TRACE("(%p, %s, 0x%lX, %s)\n", hKL, debugstr_w(lpszReading), dwStyle, - debugstr_w(lpszRegister)); - - pImeDpi = ImmLockOrLoadImeDpi(hKL); - if (!pImeDpi) - return FALSE; - - if (pImeDpi->ImeInfo.fdwProperty & IME_PROP_UNICODE) - { - ret = pImeDpi->ImeRegisterWord(lpszReading, dwStyle, lpszRegister); - ImmUnlockImeDpi(pImeDpi); - return ret; - } - - if (lpszReading) - { - pszReadingA = Imm32AnsiFromWide(lpszReading); - if (!pszReadingA) - goto Quit; - } - - if (lpszRegister) - { - pszRegisterA = Imm32AnsiFromWide(lpszRegister); - if (!pszRegisterA) - goto Quit; - } - - ret = pImeDpi->ImeRegisterWord(pszReadingA, dwStyle, pszRegisterA); - -Quit: - if (pszReadingA) - HeapFree(g_hImm32Heap, 0, pszReadingA); - if (pszRegisterA) - HeapFree(g_hImm32Heap, 0, pszRegisterA); - ImmUnlockImeDpi(pImeDpi); - return ret; -} - -/*********************************************************************** - * ImmReleaseContext (IMM32.@) - */ -BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC) -{ - TRACE("(%p, %p)\n", hWnd, hIMC); - UNREFERENCED_PARAMETER(hWnd); - UNREFERENCED_PARAMETER(hIMC); ... 3516 lines suppressed ...