mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +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
6 changed files with 206 additions and 37 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue