[IMM32] Imm(Lock|Unlock)ImeDpi and ImmSetOpenStatus (#3830)

- Add IMEDPI structure to ntuser.h.
- Implement ImmLockImeDpi/ImmUnlockImeDpi functions.
- Rewrite ImmSetOpenStatus function.
- Modify some NTUSER function prototypes.
- Modify imm32.spec.
CORE-11700
This commit is contained in:
Katayama Hirofumi MZ 2021-07-25 11:57:57 +09:00 committed by GitHub
parent 97847f2078
commit ecb0c0963d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 206 additions and 37 deletions

View file

@ -48,8 +48,63 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm);
#define IMM_INIT_MAGIC 0x19650412
#define IMM_INVALID_CANDFORM ULONG_MAX
RTL_CRITICAL_SECTION g_csImeDpi;
PIMEDPI g_pImeDpiList = NULL;
BOOL WINAPI User32InitializeImmEntryTable(DWORD);
static DWORD APIENTRY Imm32QueryInputContext(HIMC hIMC, DWORD dwUnknown2)
{
return NtUserQueryInputContext(hIMC, dwUnknown2);
}
static DWORD APIENTRY Imm32NotifyIMEStatus(HWND hwnd, HIMC hIMC, DWORD dwConversion)
{
return NtUserNotifyIMEStatus(hwnd, hIMC, dwConversion);
}
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 = Imm32QueryInputContext(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;
}
typedef struct _tagImmHkl{
struct list entry;
HKL hkl;
@ -2951,40 +3006,119 @@ BOOL WINAPI ImmSetConversionStatus(
return TRUE;
}
/***********************************************************************
* ImmLockImeDpi (IMM32.@)
*/
PIMEDPI WINAPI ImmLockImeDpi(HKL hKL)
{
PIMEDPI pImeDpi = NULL;
TRACE("ImmLockImeDpi(%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("ImmUnlockImeDpi(%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_UNKNOWN2) == 0 ||
(pImeDpi->dwUnknown1 & 1) == 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);
}
/***********************************************************************
* ImmSetOpenStatus (IMM32.@)
*/
BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
{
InputContextData *data = get_imc_data(hIMC);
DWORD idImeThread, idThread, dwConversion;
LPINPUTCONTEXT pIC;
HWND hWnd;
BOOL bHasChange = FALSE;
TRACE("%p %d\n", hIMC, fOpen);
TRACE("ImmSetOpenStatus(%p, %d)\n", hIMC, fOpen);
if (!data)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (IMM_IsCrossThreadAccess(NULL, hIMC))
idImeThread = Imm32QueryInputContext(hIMC, 1);
idThread = GetCurrentThreadId();
if (idImeThread != idThread)
return FALSE;
if (data->immKbd->UIWnd == NULL)
{
/* create the ime window */
data->immKbd->UIWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
data->immKbd->imeClassName, NULL, WS_POPUP, 0, 0, 1, 1, 0,
0, data->immKbd->hIME, 0);
SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
}
else if (fOpen)
SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
pIC = ImmLockIMC(hIMC);
if (pIC == NULL)
return FALSE;
if (!fOpen != !data->IMC.fOpen)
if (pIC->fOpen != fOpen)
{
data->IMC.fOpen = fOpen;
ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS);
ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0);
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);
Imm32NotifyIMEStatus(hWnd, hIMC, dwConversion);
}
return TRUE;

View file

@ -73,7 +73,7 @@
@ stdcall ImmLockClientImc(ptr)
@ stdcall ImmLockIMC(ptr)
@ stdcall ImmLockIMCC(ptr)
@ stdcall -stub ImmLockImeDpi(long)
@ stdcall ImmLockImeDpi(ptr)
@ stdcall ImmNotifyIME(ptr long long long)
@ stub ImmPenAuxInput
@ stdcall ImmProcessKey(ptr long long long long)
@ -107,7 +107,7 @@
@ stdcall ImmUnlockClientImc(ptr)
@ stdcall ImmUnlockIMC(ptr)
@ stdcall ImmUnlockIMCC(ptr)
@ stdcall -stub ImmUnlockImeDpi(ptr)
@ stdcall ImmUnlockImeDpi(ptr)
@ stdcall ImmUnregisterWordA(long str long str)
@ stdcall ImmUnregisterWordW(long wstr long wstr)
@ stdcall -stub ImmWINNLSEnableIME(ptr long)

View file

@ -34,6 +34,8 @@ ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx, IMEINFOEXCLASS SearchType, PVOID pvSearch
PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc);
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc);
PIMEDPI WINAPI ImmLockImeDpi(HKL hKL);
VOID WINAPI ImmUnlockImeDpi(PIMEDPI pImeDpi);
#ifdef __cplusplus
} // extern "C"

View file

@ -1212,6 +1212,40 @@ typedef struct _IMEWND
PIMEUI pimeui;
} IMEWND, *PIMEWND;
typedef BOOL (WINAPI *FN_ImeDestroy)(UINT uReserved);
typedef BOOL (WINAPI *FN_NotifyIME)(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue);
typedef struct IMEDPI /* unconfirmed */
{
struct IMEDPI *pNext;
HINSTANCE hInst;
HKL hKL;
DWORD dwUnknown0;
DWORD dwUnknown1;
DWORD dwUnknown2[14];
DWORD cLockObj;
DWORD dwFlags;
DWORD dwUnknown3[7];
FN_ImeDestroy ImeDestroy;
DWORD dwUnknown4[5];
FN_NotifyIME NotifyIME;
/* ... */
} IMEDPI, *PIMEDPI;
#ifndef _WIN64
C_ASSERT(offsetof(IMEDPI, pNext) == 0x0);
C_ASSERT(offsetof(IMEDPI, hInst) == 0x4);
C_ASSERT(offsetof(IMEDPI, hKL) == 0x8);
C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c);
C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50);
C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70);
C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88);
#endif
/* flags for IMEDPI.dwFlags */
#define IMEDPI_FLAG_UNKNOWN 1
#define IMEDPI_FLAG_UNKNOWN2 2
DWORD
NTAPI
NtUserAssociateInputContext(
@ -2676,9 +2710,9 @@ NtUserMoveWindow(
DWORD
NTAPI
NtUserNotifyIMEStatus(
DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2);
HWND hwnd,
HIMC hIMC,
DWORD dwConversion);
BOOL
NTAPI
@ -2787,7 +2821,7 @@ NtUserQueryInformationThread(
DWORD
NTAPI
NtUserQueryInputContext(
DWORD dwUnknown1,
HIMC hIMC,
DWORD dwUnknown2);
DWORD

View file

@ -50,13 +50,12 @@ NtUserGetImeHotKey(IN DWORD dwHotKey,
DWORD
APIENTRY
NtUserNotifyIMEStatus(
DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
HWND hwnd,
HIMC hIMC,
DWORD dwConversion)
{
STUB
return 0;
TRACE("NtUserNotifyIMEStatus(%p, %p, 0x%lX)\n", hwnd, hIMC, dwConversion);
return 0;
}

View file

@ -630,10 +630,10 @@ Quit:
DWORD
APIENTRY
NtUserQueryInputContext(
DWORD dwUnknown1,
HIMC hIMC,
DWORD dwUnknown2)
{
STUB;
TRACE("NtUserQueryInputContext(%p, 0x%lX)\n", hIMC, dwUnknown2);
return 0;
}