mirror of
https://github.com/reactos/reactos.git
synced 2024-06-29 01:12:06 +00:00
[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:
parent
97847f2078
commit
ecb0c0963d
|
@ -48,8 +48,63 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm);
|
||||||
#define IMM_INIT_MAGIC 0x19650412
|
#define IMM_INIT_MAGIC 0x19650412
|
||||||
#define IMM_INVALID_CANDFORM ULONG_MAX
|
#define IMM_INVALID_CANDFORM ULONG_MAX
|
||||||
|
|
||||||
|
RTL_CRITICAL_SECTION g_csImeDpi;
|
||||||
|
PIMEDPI g_pImeDpiList = NULL;
|
||||||
|
|
||||||
BOOL WINAPI User32InitializeImmEntryTable(DWORD);
|
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{
|
typedef struct _tagImmHkl{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
HKL hkl;
|
HKL hkl;
|
||||||
|
@ -2951,40 +3006,119 @@ BOOL WINAPI ImmSetConversionStatus(
|
||||||
return TRUE;
|
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.@)
|
* ImmSetOpenStatus (IMM32.@)
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
|
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)
|
idImeThread = Imm32QueryInputContext(hIMC, 1);
|
||||||
{
|
idThread = GetCurrentThreadId();
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
if (idImeThread != idThread)
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IMM_IsCrossThreadAccess(NULL, hIMC))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (data->immKbd->UIWnd == NULL)
|
pIC = ImmLockIMC(hIMC);
|
||||||
{
|
if (pIC == NULL)
|
||||||
/* create the ime window */
|
return FALSE;
|
||||||
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);
|
|
||||||
|
|
||||||
if (!fOpen != !data->IMC.fOpen)
|
if (pIC->fOpen != fOpen)
|
||||||
{
|
{
|
||||||
data->IMC.fOpen = fOpen;
|
pIC->fOpen = fOpen;
|
||||||
ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS);
|
hWnd = pIC->hWnd;
|
||||||
ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0);
|
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;
|
return TRUE;
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
@ stdcall ImmLockClientImc(ptr)
|
@ stdcall ImmLockClientImc(ptr)
|
||||||
@ stdcall ImmLockIMC(ptr)
|
@ stdcall ImmLockIMC(ptr)
|
||||||
@ stdcall ImmLockIMCC(ptr)
|
@ stdcall ImmLockIMCC(ptr)
|
||||||
@ stdcall -stub ImmLockImeDpi(long)
|
@ stdcall ImmLockImeDpi(ptr)
|
||||||
@ stdcall ImmNotifyIME(ptr long long long)
|
@ stdcall ImmNotifyIME(ptr long long long)
|
||||||
@ stub ImmPenAuxInput
|
@ stub ImmPenAuxInput
|
||||||
@ stdcall ImmProcessKey(ptr long long long long)
|
@ stdcall ImmProcessKey(ptr long long long long)
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
@ stdcall ImmUnlockClientImc(ptr)
|
@ stdcall ImmUnlockClientImc(ptr)
|
||||||
@ stdcall ImmUnlockIMC(ptr)
|
@ stdcall ImmUnlockIMC(ptr)
|
||||||
@ stdcall ImmUnlockIMCC(ptr)
|
@ stdcall ImmUnlockIMCC(ptr)
|
||||||
@ stdcall -stub ImmUnlockImeDpi(ptr)
|
@ stdcall ImmUnlockImeDpi(ptr)
|
||||||
@ stdcall ImmUnregisterWordA(long str long str)
|
@ stdcall ImmUnregisterWordA(long str long str)
|
||||||
@ stdcall ImmUnregisterWordW(long wstr long wstr)
|
@ stdcall ImmUnregisterWordW(long wstr long wstr)
|
||||||
@ stdcall -stub ImmWINNLSEnableIME(ptr long)
|
@ stdcall -stub ImmWINNLSEnableIME(ptr long)
|
||||||
|
|
|
@ -34,6 +34,8 @@ ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx, IMEINFOEXCLASS SearchType, PVOID pvSearch
|
||||||
|
|
||||||
PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc);
|
PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc);
|
||||||
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc);
|
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc);
|
||||||
|
PIMEDPI WINAPI ImmLockImeDpi(HKL hKL);
|
||||||
|
VOID WINAPI ImmUnlockImeDpi(PIMEDPI pImeDpi);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
|
@ -1212,6 +1212,40 @@ typedef struct _IMEWND
|
||||||
PIMEUI pimeui;
|
PIMEUI pimeui;
|
||||||
} IMEWND, *PIMEWND;
|
} 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
|
DWORD
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserAssociateInputContext(
|
NtUserAssociateInputContext(
|
||||||
|
@ -2676,9 +2710,9 @@ NtUserMoveWindow(
|
||||||
DWORD
|
DWORD
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserNotifyIMEStatus(
|
NtUserNotifyIMEStatus(
|
||||||
DWORD Unknown0,
|
HWND hwnd,
|
||||||
DWORD Unknown1,
|
HIMC hIMC,
|
||||||
DWORD Unknown2);
|
DWORD dwConversion);
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -2787,7 +2821,7 @@ NtUserQueryInformationThread(
|
||||||
DWORD
|
DWORD
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserQueryInputContext(
|
NtUserQueryInputContext(
|
||||||
DWORD dwUnknown1,
|
HIMC hIMC,
|
||||||
DWORD dwUnknown2);
|
DWORD dwUnknown2);
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
|
|
|
@ -50,13 +50,12 @@ NtUserGetImeHotKey(IN DWORD dwHotKey,
|
||||||
DWORD
|
DWORD
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserNotifyIMEStatus(
|
NtUserNotifyIMEStatus(
|
||||||
DWORD Unknown0,
|
HWND hwnd,
|
||||||
DWORD Unknown1,
|
HIMC hIMC,
|
||||||
DWORD Unknown2)
|
DWORD dwConversion)
|
||||||
{
|
{
|
||||||
STUB
|
TRACE("NtUserNotifyIMEStatus(%p, %p, 0x%lX)\n", hwnd, hIMC, dwConversion);
|
||||||
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -630,10 +630,10 @@ Quit:
|
||||||
DWORD
|
DWORD
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserQueryInputContext(
|
NtUserQueryInputContext(
|
||||||
DWORD dwUnknown1,
|
HIMC hIMC,
|
||||||
DWORD dwUnknown2)
|
DWORD dwUnknown2)
|
||||||
{
|
{
|
||||||
STUB;
|
TRACE("NtUserQueryInputContext(%p, 0x%lX)\n", hIMC, dwUnknown2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue