[IMM32] Add some candidate handlings (#3799)

- Implement ImmGetCandidateListA and ImmGetCandidateListW, by using newly added ImmGetCandidateListAW function.
- Implement ImmLockClientImc and ImmUnlockClientImc functions.
- Modify imm32.spec.
- Remove #ifdef's.
CORE-11700
This commit is contained in:
Katayama Hirofumi MZ 2021-07-11 09:48:15 +09:00 committed by GitHub
parent 8379c87b0b
commit 92393a7517
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 378 additions and 237 deletions

View file

@ -22,28 +22,25 @@
#include <stdarg.h>
#include <stdio.h>
#ifdef __REACTOS__
#define WIN32_NO_STATUS
#endif
#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"
#ifdef __REACTOS__
#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 <imm32_undoc.h>
#include <strsafe.h>
#endif
WINE_DEFAULT_DEBUG_CHANNEL(imm);
@ -853,19 +850,7 @@ BOOL WINAPI ImmDestroyContext(HIMC hIMC)
*/
BOOL WINAPI ImmDisableIME(DWORD idThread)
{
#ifdef __REACTOS__
return NtUserDisableThreadIme(idThread);
#else
if (idThread == (DWORD)-1)
disable_ime = TRUE;
else {
IMMThreadData *thread_data = IMM_GetThreadData(NULL, idThread);
if (!thread_data) return FALSE;
thread_data->disableIME = TRUE;
LeaveCriticalSection(&threaddata_cs);
}
return TRUE;
#endif
}
/***********************************************************************
@ -1017,6 +1002,313 @@ LRESULT WINAPI ImmEscapeW(
return 0;
}
#define ROUNDUP4(n) (((n) + 3) & ~3) /* DWORD alignment */
HANDLE g_hImm32Heap = NULL;
LPVOID APIENTRY Imm32HeapAlloc(DWORD dwFlags, DWORD dwBytes)
{
if (!g_hImm32Heap)
{
g_hImm32Heap = GetProcessHeap(); // FIXME: Use TEB
if (g_hImm32Heap == NULL)
return NULL;
}
return HeapAlloc(g_hImm32Heap, dwFlags, dwBytes);
}
static DWORD_PTR APIENTRY
Imm32GetThreadState(DWORD Routine)
{
return NtUserGetThreadState(Routine);
}
static DWORD APIENTRY
Imm32UpdateInputContext(HIMC hIMC, DWORD Unknown1, PCLIENTIMC pClientImc)
{
return NtUserUpdateInputContext(hIMC, Unknown1, pClientImc);
}
static PCLIENTIMC APIENTRY Imm32GetClientImcCache(void)
{
// FIXME: Do something properly here
return NULL;
}
PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
{
PCLIENTIMC pClientImc;
TRACE("ImmLockClientImc(%p)\n", hImc);
if (hImc == NULL)
return NULL;
pClientImc = Imm32GetClientImcCache();
if (!pClientImc)
{
pClientImc = Imm32HeapAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
if (!pClientImc)
return NULL;
RtlInitializeCriticalSection(&pClientImc->cs);
pClientImc->unknown = Imm32GetThreadState(THREADSTATE_UNKNOWN13);
if (!Imm32UpdateInputContext(hImc, 0, pClientImc))
{
HeapFree(g_hImm32Heap, 0, pClientImc);
return NULL;
}
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN2;
}
else
{
if (pClientImc->dwFlags & CLIENTIMC_DISABLED)
return NULL;
}
InterlockedIncrement(&pClientImc->cLockObj);
return pClientImc;
}
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
{
LONG cLocks;
HIMC hImc;
TRACE("ImmUnlockClientImc(%p)\n", pClientImc);
cLocks = InterlockedDecrement(&pClientImc->cLockObj);
if (cLocks != 0 || (pClientImc->dwFlags & CLIENTIMC_DISABLED))
return;
hImc = pClientImc->hImc;
if (hImc)
LocalFree(hImc);
RtlDeleteCriticalSection(&pClientImc->cs);
HeapFree(g_hImm32Heap, 0, pClientImc);
}
static 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;
}
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;
/* 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;
}
/***********************************************************************
* ImmGetCandidateListA (IMM32.@)
*/
@ -1024,36 +1316,7 @@ DWORD WINAPI ImmGetCandidateListA(
HIMC hIMC, DWORD dwIndex,
LPCANDIDATELIST lpCandList, DWORD dwBufLen)
{
InputContextData *data = get_imc_data(hIMC);
LPCANDIDATEINFO candinfo;
LPCANDIDATELIST candlist;
DWORD ret = 0;
TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
if (!data || !data->IMC.hCandInfo)
return 0;
candinfo = ImmLockIMCC(data->IMC.hCandInfo);
if (dwIndex >= candinfo->dwCount || dwIndex >= ARRAY_SIZE(candinfo->dwOffset))
goto done;
candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
if ( !candlist->dwSize || !candlist->dwCount )
goto done;
if ( !is_himc_ime_unicode(data) )
{
ret = candlist->dwSize;
if ( lpCandList && dwBufLen >= ret )
memcpy(lpCandList, candlist, ret);
}
else
ret = convert_candidatelist_WtoA( candlist, lpCandList, dwBufLen);
done:
ImmUnlockIMCC(data->IMC.hCandInfo);
return ret;
return ImmGetCandidateListAW(hIMC, dwIndex, lpCandList, dwBufLen, TRUE);
}
/***********************************************************************
@ -1127,36 +1390,7 @@ DWORD WINAPI ImmGetCandidateListW(
HIMC hIMC, DWORD dwIndex,
LPCANDIDATELIST lpCandList, DWORD dwBufLen)
{
InputContextData *data = get_imc_data(hIMC);
LPCANDIDATEINFO candinfo;
LPCANDIDATELIST candlist;
DWORD ret = 0;
TRACE("%p, %d, %p, %d\n", hIMC, dwIndex, lpCandList, dwBufLen);
if (!data || !data->IMC.hCandInfo)
return 0;
candinfo = ImmLockIMCC(data->IMC.hCandInfo);
if (dwIndex >= candinfo->dwCount || dwIndex >= ARRAY_SIZE(candinfo->dwOffset))
goto done;
candlist = (LPCANDIDATELIST)((LPBYTE)candinfo + candinfo->dwOffset[dwIndex]);
if ( !candlist->dwSize || !candlist->dwCount )
goto done;
if ( is_himc_ime_unicode(data) )
{
ret = candlist->dwSize;
if ( lpCandList && dwBufLen >= ret )
memcpy(lpCandList, candlist, ret);
}
else
ret = convert_candidatelist_AtoW( candlist, lpCandList, dwBufLen);
done:
ImmUnlockIMCC(data->IMC.hCandInfo);
return ret;
return ImmGetCandidateListAW(hIMC, dwIndex, lpCandList, dwBufLen, FALSE);
}
/***********************************************************************
@ -1641,7 +1875,6 @@ DWORD WINAPI ImmGetConversionListW(
BOOL WINAPI ImmGetConversionStatus(
HIMC hIMC, LPDWORD lpfdwConversion, LPDWORD lpfdwSentence)
{
#ifdef __REACTOS__
LPINPUTCONTEXT pIC;
TRACE("ImmGetConversionStatus(%p %p %p)\n", hIMC, lpfdwConversion, lpfdwSentence);
@ -1657,21 +1890,6 @@ BOOL WINAPI ImmGetConversionStatus(
ImmUnlockIMC(hIMC);
return TRUE;
#else
InputContextData *data = get_imc_data(hIMC);
TRACE("%p %p %p\n", hIMC, lpfdwConversion, lpfdwSentence);
if (!data)
return FALSE;
if (lpfdwConversion)
*lpfdwConversion = data->IMC.fdwConversion;
if (lpfdwSentence)
*lpfdwSentence = data->IMC.fdwSentence;
return TRUE;
#endif
}
static BOOL needs_ime_window(HWND hwnd)
@ -1786,13 +2004,12 @@ HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
UINT WINAPI ImmGetDescriptionA(
HKL hKL, LPSTR lpszDescription, UINT uBufLen)
{
#ifdef __REACTOS__
IMEINFOEX info;
size_t cch;
TRACE("ImmGetDescriptionA(%p,%p,%d)\n", hKL, lpszDescription, uBufLen);
if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_KBDLAYOUT(hKL))
if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL))
return 0;
StringCchLengthW(info.wszImeDescription, _countof(info.wszImeDescription), &cch);
@ -1801,36 +2018,6 @@ UINT WINAPI ImmGetDescriptionA(
if (uBufLen)
lpszDescription[cch] = 0;
return cch;
#else
WCHAR *buf;
DWORD len;
TRACE("%p %p %d\n", hKL, lpszDescription, uBufLen);
/* find out how many characters in the unicode buffer */
len = ImmGetDescriptionW( hKL, NULL, 0 );
if (!len)
return 0;
/* allocate a buffer of that size */
buf = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof (WCHAR) );
if( !buf )
return 0;
/* fetch the unicode buffer */
len = ImmGetDescriptionW( hKL, buf, len + 1 );
/* convert it back to ASCII */
len = WideCharToMultiByte( CP_ACP, 0, buf, len + 1,
lpszDescription, uBufLen, NULL, NULL );
HeapFree( GetProcessHeap(), 0, buf );
if (len == 0)
return 0;
return len - 1;
#endif
}
/***********************************************************************
@ -1838,13 +2025,12 @@ UINT WINAPI ImmGetDescriptionA(
*/
UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
{
#ifdef __REACTOS__
IMEINFOEX info;
size_t cch;
TRACE("ImmGetDescriptionW(%p, %p, %d)\n", hKL, lpszDescription, uBufLen);
if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_KBDLAYOUT(hKL))
if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL) || !IS_IME_HKL(hKL))
return 0;
if (uBufLen != 0)
@ -1852,16 +2038,6 @@ UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen)
StringCchLengthW(info.wszImeDescription, _countof(info.wszImeDescription), &cch);
return (UINT)cch;
#else
static const WCHAR name[] = { 'W','i','n','e',' ','X','I','M',0 };
FIXME("(%p, %p, %d): semi stub\n", hKL, lpszDescription, uBufLen);
if (!hKL) return 0;
if (!uBufLen) return lstrlenW( name );
lstrcpynW( lpszDescription, name, uBufLen );
return lstrlenW( lpszDescription );
#endif
}
/***********************************************************************
@ -1973,7 +2149,6 @@ UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen)
*/
BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
{
#ifdef __REACTOS__
BOOL ret;
LPINPUTCONTEXT pIC;
@ -1990,20 +2165,6 @@ BOOL WINAPI ImmGetOpenStatus(HIMC hIMC)
ImmUnlockIMC(hIMC);
return ret;
#else
InputContextData *data = get_imc_data(hIMC);
static int i;
if (!data)
return FALSE;
TRACE("(%p): semi-stub\n", hIMC);
if (!i++)
FIXME("(%p): semi-stub\n", hIMC);
return data->IMC.fOpen;
#endif
}
/***********************************************************************
@ -2219,16 +2380,9 @@ HKL WINAPI ImmInstallIMEW(
*/
BOOL WINAPI ImmIsIME(HKL hKL)
{
#ifdef __REACTOS__
IMEINFOEX info;
TRACE("ImmIsIME(%p)\n", hKL);
return !!ImmGetImeInfoEx(&info, ImeInfoExImeWindow, &hKL);
#else
ImmHkl *ptr;
TRACE("(%p):\n", hKL);
ptr = IMM_GetImmHkl(hKL);
return (ptr && ptr->hIME);
#endif
}
/***********************************************************************
@ -2759,14 +2913,8 @@ HWND WINAPI ImmCreateSoftKeyboard(UINT uType, UINT hOwner, int x, int y)
*/
BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
{
#ifdef __REACTOS__
TRACE("(%p)\n", hSoftWnd);
return DestroyWindow(hSoftWnd);
#else
FIXME("(%p): stub\n", hSoftWnd);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
#endif
}
/***********************************************************************
@ -2774,14 +2922,9 @@ BOOL WINAPI ImmDestroySoftKeyboard(HWND hSoftWnd)
*/
BOOL WINAPI ImmShowSoftKeyboard(HWND hSoftWnd, int nCmdShow)
{
#ifdef __REACTOS__
TRACE("(%p, %d)\n", hSoftWnd, nCmdShow);
if (hSoftWnd)
return ShowWindow(hSoftWnd, nCmdShow);
#else
FIXME("(%p, %d): stub\n", hSoftWnd, nCmdShow);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
#endif
return FALSE;
}
@ -3013,12 +3156,19 @@ LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
*/
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
{
InputContextData *data = get_imc_data(hIMC);
PCLIENTIMC pClientIMC;
HIMC hClientImc;
if (!data)
pClientIMC = ImmLockClientImc(hIMC);
if (pClientIMC == NULL)
return FALSE;
if (data->dwLock)
data->dwLock--;
hClientImc = pClientIMC->hImc;
if (hClientImc)
LocalUnlock(hClientImc);
InterlockedDecrement(&pClientIMC->cLockObj);
ImmUnlockClientImc(pClientIMC);
return TRUE;
}
@ -3027,10 +3177,21 @@ BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
*/
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
{
InputContextData *data = get_imc_data(hIMC);
if (!data)
DWORD ret;
HIMC hClientImc;
PCLIENTIMC pClientImc;
pClientImc = ImmLockClientImc(hIMC);
if (pClientImc == NULL)
return 0;
return data->dwLock;
ret = 0;
hClientImc = pClientImc->hImc;
if (hClientImc)
ret = (LocalFlags(hClientImc) & LMEM_LOCKCOUNT);
ImmUnlockClientImc(pClientImc);
return ret;
}
/***********************************************************************
@ -3038,13 +3199,9 @@ DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
*/
HIMCC WINAPI ImmCreateIMCC(DWORD size)
{
#ifdef __REACTOS__
if (size < 4)
size = 4;
return LocalAlloc(LHND, size);
#else
return GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE, size);
#endif
}
/***********************************************************************
@ -3052,13 +3209,9 @@ HIMCC WINAPI ImmCreateIMCC(DWORD size)
*/
HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
{
#ifdef __REACTOS__
if (block)
return LocalFree(block);
return NULL;
#else
return GlobalFree(block);
#endif
}
/***********************************************************************
@ -3066,13 +3219,9 @@ HIMCC WINAPI ImmDestroyIMCC(HIMCC block)
*/
LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
{
#ifdef __REACTOS__
if (imcc)
return LocalLock(imcc);
return NULL;
#else
return GlobalLock(imcc);
#endif
}
/***********************************************************************
@ -3080,13 +3229,9 @@ LPVOID WINAPI ImmLockIMCC(HIMCC imcc)
*/
BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
{
#ifdef __REACTOS__
if (imcc)
return LocalUnlock(imcc);
return FALSE;
#else
return GlobalUnlock(imcc);
#endif
}
/***********************************************************************
@ -3094,11 +3239,7 @@ BOOL WINAPI ImmUnlockIMCC(HIMCC imcc)
*/
DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
{
#ifdef __REACTOS__
return LocalFlags(imcc) & LMEM_LOCKCOUNT;
#else
return GlobalFlags(imcc) & GMEM_LOCKCOUNT;
#endif
}
/***********************************************************************
@ -3106,13 +3247,9 @@ DWORD WINAPI ImmGetIMCCLockCount(HIMCC imcc)
*/
HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
{
#ifdef __REACTOS__
if (!imcc)
return NULL;
return LocalReAlloc(imcc, size, LHND);
#else
return GlobalReAlloc(imcc, size, GMEM_ZEROINIT | GMEM_MOVEABLE);
#endif
}
/***********************************************************************
@ -3120,13 +3257,9 @@ HIMCC WINAPI ImmReSizeIMCC(HIMCC imcc, DWORD size)
*/
DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
{
#ifdef __REACTOS__
if (imcc)
return LocalSize(imcc);
return 0;
#else
return GlobalSize(imcc);
#endif
}
/***********************************************************************
@ -3302,7 +3435,6 @@ BOOL WINAPI ImmEnumInputContext(DWORD idThread, IMCENUMPROC lpfn, LPARAM lParam)
* ImmGetHotKey(IMM32.@)
*/
#ifdef __REACTOS__
BOOL WINAPI
ImmGetHotKey(IN DWORD dwHotKey,
OUT LPUINT lpuModifiers,
@ -3314,13 +3446,6 @@ ImmGetHotKey(IN DWORD dwHotKey,
return NtUserGetImeHotKey(dwHotKey, lpuModifiers, lpuVKey, lphKL);
return FALSE;
}
#else
BOOL WINAPI ImmGetHotKey(DWORD hotkey, UINT *modifiers, UINT *key, HKL hkl)
{
FIXME("%x, %p, %p, %p: stub\n", hotkey, modifiers, key, hkl);
return FALSE;
}
#endif
/***********************************************************************
* ImmDisableLegacyIME(IMM32.@)
@ -3331,7 +3456,6 @@ BOOL WINAPI ImmDisableLegacyIME(void)
return TRUE;
}
#ifdef __REACTOS__
/***********************************************************************
* ImmSetActiveContext(IMM32.@)
*/
@ -3392,4 +3516,3 @@ ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx,
}
return NtUserGetImeInfoEx(pImeInfoEx, SearchType);
}
#endif

View file

@ -68,7 +68,7 @@
@ stdcall ImmIsUIMessageW(long long long long)
@ stdcall -stub ImmLoadIME(long)
@ stdcall -stub ImmLoadLayout(long ptr)
@ stub ImmLockClientImc
@ stdcall ImmLockClientImc(ptr)
@ stdcall ImmLockIMC(ptr)
@ stdcall ImmLockIMCC(ptr)
@ stdcall -stub ImmLockImeDpi(long)
@ -102,7 +102,7 @@
@ stdcall ImmSimulateHotKey(ptr long)
@ stdcall -stub ImmSystemHandler(ptr long long)
@ stdcall ImmTranslateMessage(ptr long long long)
@ stub ImmUnlockClientImc
@ stdcall ImmUnlockClientImc(ptr)
@ stdcall ImmUnlockIMC(ptr)
@ stdcall ImmUnlockIMCC(ptr)
@ stdcall -stub ImmUnlockImeDpi(ptr)

View file

@ -79,7 +79,7 @@ dll/win32/iccvid # Synced to WineStaging-4.0
dll/win32/ieframe # Synced to WineStaging-4.18
dll/win32/imaadp32.acm # Synced to WineStaging-4.0
dll/win32/imagehlp # Synced to WineStaging-4.18
dll/win32/imm32 # Synced to WineStaging-4.18
dll/win32/imm32 # Forked at WineStaging-4.18
dll/win32/inetcomm # Synced to WineStaging-4.18
dll/win32/inetmib1 # Synced to WineStaging-4.18
dll/win32/initpki # Synced to WineStaging-4.18

View file

@ -7,9 +7,23 @@
#pragma once
#define KBDLAYOUT_MASK 0xF000
#define KBDLAYOUT_IME 0xE000
#define IS_IME_KBDLAYOUT(hKL) ((HIWORD(hKL) & KBDLAYOUT_MASK) == KBDLAYOUT_IME)
/* unconfirmed */
typedef struct tagCLIENTIMC
{
HIMC hImc;
LONG cLockObj;
DWORD dwFlags;
DWORD unknown;
RTL_CRITICAL_SECTION cs;
DWORD unknown2;
DWORD unknown3;
BOOL bUnknown4;
} CLIENTIMC, *PCLIENTIMC;
/* flags for CLIENTIMC */
#define CLIENTIMC_WIDE (1 << 0)
#define CLIENTIMC_DISABLED (1 << 6)
#define CLIENTIMC_UNKNOWN2 (1 << 8)
#ifdef __cplusplus
extern "C" {

View file

@ -2464,7 +2464,8 @@ enum ThreadStateRoutines
THREADSTATE_UPTIMELASTREAD,
THREADSTATE_FOREGROUNDTHREAD,
THREADSTATE_GETCURSOR,
THREADSTATE_GETMESSAGEEXTRAINFO
THREADSTATE_GETMESSAGEEXTRAINFO,
THREADSTATE_UNKNOWN13
};
DWORD_PTR
@ -3445,9 +3446,9 @@ NtUserUnregisterUserApiHook(VOID);
DWORD
NTAPI
NtUserUpdateInputContext(
DWORD Unknown0,
HIMC hIMC,
DWORD Unknown1,
DWORD Unknown2);
LPVOID pClientImc);
DWORD
NTAPI

View file

@ -314,6 +314,9 @@ NtUserGetThreadState(
case THREADSTATE_GETMESSAGEEXTRAINFO:
ret = (DWORD_PTR)MsqGetMessageExtraInfo();
break;
case THREADSTATE_UNKNOWN13:
ret = FALSE; /* FIXME: See imm32 */
break;
}
TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret);

View file

@ -356,9 +356,9 @@ NtUserSetSysColors(
DWORD
APIENTRY
NtUserUpdateInputContext(
DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
HIMC hIMC,
DWORD Unknown1,
LPVOID pClientImc)
{
STUB