Skip to content

Commit ecb0c09

Browse files
authored
[IMM32] Imm(Lock|Unlock)ImeDpi and ImmSetOpenStatus (reactos#3830)
- Add IMEDPI structure to ntuser.h. - Implement ImmLockImeDpi/ImmUnlockImeDpi functions. - Rewrite ImmSetOpenStatus function. - Modify some NTUSER function prototypes. - Modify imm32.spec. CORE-11700
1 parent 97847f2 commit ecb0c09

File tree

6 files changed

+202
-33
lines changed

6 files changed

+202
-33
lines changed

dll/win32/imm32/imm.c

Lines changed: 153 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,63 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm);
4848
#define IMM_INIT_MAGIC 0x19650412
4949
#define IMM_INVALID_CANDFORM ULONG_MAX
5050

51+
RTL_CRITICAL_SECTION g_csImeDpi;
52+
PIMEDPI g_pImeDpiList = NULL;
53+
5154
BOOL WINAPI User32InitializeImmEntryTable(DWORD);
5255

56+
static DWORD APIENTRY Imm32QueryInputContext(HIMC hIMC, DWORD dwUnknown2)
57+
{
58+
return NtUserQueryInputContext(hIMC, dwUnknown2);
59+
}
60+
61+
static DWORD APIENTRY Imm32NotifyIMEStatus(HWND hwnd, HIMC hIMC, DWORD dwConversion)
62+
{
63+
return NtUserNotifyIMEStatus(hwnd, hIMC, dwConversion);
64+
}
65+
66+
static VOID APIENTRY Imm32FreeImeDpi(PIMEDPI pImeDpi, BOOL bDestroy)
67+
{
68+
if (pImeDpi->hInst == NULL)
69+
return;
70+
if (bDestroy)
71+
pImeDpi->ImeDestroy(0);
72+
FreeLibrary(pImeDpi->hInst);
73+
pImeDpi->hInst = NULL;
74+
}
75+
76+
static BOOL APIENTRY
77+
Imm32NotifyAction(HIMC hIMC, HWND hwnd, DWORD dwAction, DWORD_PTR dwIndex, DWORD_PTR dwValue,
78+
DWORD_PTR dwCommand, DWORD_PTR dwData)
79+
{
80+
DWORD dwLayout;
81+
HKL hKL;
82+
PIMEDPI pImeDpi;
83+
84+
if (dwAction)
85+
{
86+
dwLayout = Imm32QueryInputContext(hIMC, 1);
87+
if (dwLayout)
88+
{
89+
/* find keyboard layout and lock it */
90+
hKL = GetKeyboardLayout(dwLayout);
91+
pImeDpi = ImmLockImeDpi(hKL);
92+
if (pImeDpi)
93+
{
94+
/* do notify */
95+
pImeDpi->NotifyIME(hIMC, dwAction, dwIndex, dwValue);
96+
97+
ImmUnlockImeDpi(pImeDpi); /* unlock */
98+
}
99+
}
100+
}
101+
102+
if (hwnd && dwCommand)
103+
SendMessageW(hwnd, WM_IME_NOTIFY, dwCommand, dwData);
104+
105+
return TRUE;
106+
}
107+
53108
typedef struct _tagImmHkl{
54109
struct list entry;
55110
HKL hkl;
@@ -2951,40 +3006,119 @@ BOOL WINAPI ImmSetConversionStatus(
29513006
return TRUE;
29523007
}
29533008

3009+
/***********************************************************************
3010+
* ImmLockImeDpi (IMM32.@)
3011+
*/
3012+
PIMEDPI WINAPI ImmLockImeDpi(HKL hKL)
3013+
{
3014+
PIMEDPI pImeDpi = NULL;
3015+
3016+
TRACE("ImmLockImeDpi(%p)\n", hKL);
3017+
3018+
RtlEnterCriticalSection(&g_csImeDpi);
3019+
3020+
/* Find by hKL */
3021+
for (pImeDpi = g_pImeDpiList; pImeDpi; pImeDpi = pImeDpi->pNext)
3022+
{
3023+
if (pImeDpi->hKL == hKL) /* found */
3024+
{
3025+
/* lock if possible */
3026+
if (pImeDpi->dwFlags & IMEDPI_FLAG_UNKNOWN)
3027+
pImeDpi = NULL;
3028+
else
3029+
++(pImeDpi->cLockObj);
3030+
break;
3031+
}
3032+
}
3033+
3034+
RtlLeaveCriticalSection(&g_csImeDpi);
3035+
return pImeDpi;
3036+
}
3037+
3038+
/***********************************************************************
3039+
* ImmUnlockImeDpi (IMM32.@)
3040+
*/
3041+
VOID WINAPI ImmUnlockImeDpi(PIMEDPI pImeDpi)
3042+
{
3043+
PIMEDPI *ppEntry;
3044+
3045+
TRACE("ImmUnlockImeDpi(%p)\n", pImeDpi);
3046+
3047+
if (pImeDpi == NULL)
3048+
return;
3049+
3050+
RtlEnterCriticalSection(&g_csImeDpi);
3051+
3052+
/* unlock */
3053+
--(pImeDpi->cLockObj);
3054+
if (pImeDpi->cLockObj != 0)
3055+
{
3056+
RtlLeaveCriticalSection(&g_csImeDpi);
3057+
return;
3058+
}
3059+
3060+
if ((pImeDpi->dwFlags & IMEDPI_FLAG_UNKNOWN) == 0)
3061+
{
3062+
if ((pImeDpi->dwFlags & IMEDPI_FLAG_UNKNOWN2) == 0 ||
3063+
(pImeDpi->dwUnknown1 & 1) == 0)
3064+
{
3065+
RtlLeaveCriticalSection(&g_csImeDpi);
3066+
return;
3067+
}
3068+
}
3069+
3070+
/* Remove from list */
3071+
for (ppEntry = &g_pImeDpiList; *ppEntry; ppEntry = &((*ppEntry)->pNext))
3072+
{
3073+
if (*ppEntry == pImeDpi) /* found */
3074+
{
3075+
*ppEntry = pImeDpi->pNext;
3076+
break;
3077+
}
3078+
}
3079+
3080+
Imm32FreeImeDpi(pImeDpi, TRUE);
3081+
HeapFree(g_hImm32Heap, 0, pImeDpi);
3082+
3083+
RtlLeaveCriticalSection(&g_csImeDpi);
3084+
}
3085+
29543086
/***********************************************************************
29553087
* ImmSetOpenStatus (IMM32.@)
29563088
*/
29573089
BOOL WINAPI ImmSetOpenStatus(HIMC hIMC, BOOL fOpen)
29583090
{
2959-
InputContextData *data = get_imc_data(hIMC);
3091+
DWORD idImeThread, idThread, dwConversion;
3092+
LPINPUTCONTEXT pIC;
3093+
HWND hWnd;
3094+
BOOL bHasChange = FALSE;
29603095

2961-
TRACE("%p %d\n", hIMC, fOpen);
3096+
TRACE("ImmSetOpenStatus(%p, %d)\n", hIMC, fOpen);
29623097

2963-
if (!data)
2964-
{
2965-
SetLastError(ERROR_INVALID_HANDLE);
3098+
idImeThread = Imm32QueryInputContext(hIMC, 1);
3099+
idThread = GetCurrentThreadId();
3100+
if (idImeThread != idThread)
29663101
return FALSE;
2967-
}
29683102

2969-
if (IMM_IsCrossThreadAccess(NULL, hIMC))
3103+
pIC = ImmLockIMC(hIMC);
3104+
if (pIC == NULL)
29703105
return FALSE;
29713106

2972-
if (data->immKbd->UIWnd == NULL)
3107+
if (pIC->fOpen != fOpen)
29733108
{
2974-
/* create the ime window */
2975-
data->immKbd->UIWnd = CreateWindowExW( WS_EX_TOOLWINDOW,
2976-
data->immKbd->imeClassName, NULL, WS_POPUP, 0, 0, 1, 1, 0,
2977-
0, data->immKbd->hIME, 0);
2978-
SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
3109+
pIC->fOpen = fOpen;
3110+
hWnd = pIC->hWnd;
3111+
dwConversion = pIC->fdwConversion;
3112+
bHasChange = TRUE;
29793113
}
2980-
else if (fOpen)
2981-
SetWindowLongPtrW(data->immKbd->UIWnd, IMMGWL_IMC, (LONG_PTR)data);
29823114

2983-
if (!fOpen != !data->IMC.fOpen)
3115+
ImmUnlockIMC(hIMC);
3116+
3117+
if (bHasChange)
29843118
{
2985-
data->IMC.fOpen = fOpen;
2986-
ImmNotifyIME( hIMC, NI_CONTEXTUPDATED, 0, IMC_SETOPENSTATUS);
2987-
ImmInternalSendIMENotify(data, IMN_SETOPENSTATUS, 0);
3119+
Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0,
3120+
IMC_SETOPENSTATUS, IMN_SETOPENSTATUS, 0);
3121+
Imm32NotifyIMEStatus(hWnd, hIMC, dwConversion);
29883122
}
29893123

29903124
return TRUE;

dll/win32/imm32/imm32.spec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
@ stdcall ImmLockClientImc(ptr)
7474
@ stdcall ImmLockIMC(ptr)
7575
@ stdcall ImmLockIMCC(ptr)
76-
@ stdcall -stub ImmLockImeDpi(long)
76+
@ stdcall ImmLockImeDpi(ptr)
7777
@ stdcall ImmNotifyIME(ptr long long long)
7878
@ stub ImmPenAuxInput
7979
@ stdcall ImmProcessKey(ptr long long long long)
@@ -107,7 +107,7 @@
107107
@ stdcall ImmUnlockClientImc(ptr)
108108
@ stdcall ImmUnlockIMC(ptr)
109109
@ stdcall ImmUnlockIMCC(ptr)
110-
@ stdcall -stub ImmUnlockImeDpi(ptr)
110+
@ stdcall ImmUnlockImeDpi(ptr)
111111
@ stdcall ImmUnregisterWordA(long str long str)
112112
@ stdcall ImmUnregisterWordW(long wstr long wstr)
113113
@ stdcall -stub ImmWINNLSEnableIME(ptr long)

sdk/include/reactos/imm32_undoc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx, IMEINFOEXCLASS SearchType, PVOID pvSearch
3434

3535
PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc);
3636
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc);
37+
PIMEDPI WINAPI ImmLockImeDpi(HKL hKL);
38+
VOID WINAPI ImmUnlockImeDpi(PIMEDPI pImeDpi);
3739

3840
#ifdef __cplusplus
3941
} // extern "C"

win32ss/include/ntuser.h

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,40 @@ typedef struct _IMEWND
12121212
PIMEUI pimeui;
12131213
} IMEWND, *PIMEWND;
12141214

1215+
typedef BOOL (WINAPI *FN_ImeDestroy)(UINT uReserved);
1216+
typedef BOOL (WINAPI *FN_NotifyIME)(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue);
1217+
1218+
typedef struct IMEDPI /* unconfirmed */
1219+
{
1220+
struct IMEDPI *pNext;
1221+
HINSTANCE hInst;
1222+
HKL hKL;
1223+
DWORD dwUnknown0;
1224+
DWORD dwUnknown1;
1225+
DWORD dwUnknown2[14];
1226+
DWORD cLockObj;
1227+
DWORD dwFlags;
1228+
DWORD dwUnknown3[7];
1229+
FN_ImeDestroy ImeDestroy;
1230+
DWORD dwUnknown4[5];
1231+
FN_NotifyIME NotifyIME;
1232+
/* ... */
1233+
} IMEDPI, *PIMEDPI;
1234+
1235+
#ifndef _WIN64
1236+
C_ASSERT(offsetof(IMEDPI, pNext) == 0x0);
1237+
C_ASSERT(offsetof(IMEDPI, hInst) == 0x4);
1238+
C_ASSERT(offsetof(IMEDPI, hKL) == 0x8);
1239+
C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c);
1240+
C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50);
1241+
C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70);
1242+
C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88);
1243+
#endif
1244+
1245+
/* flags for IMEDPI.dwFlags */
1246+
#define IMEDPI_FLAG_UNKNOWN 1
1247+
#define IMEDPI_FLAG_UNKNOWN2 2
1248+
12151249
DWORD
12161250
NTAPI
12171251
NtUserAssociateInputContext(
@@ -2676,9 +2710,9 @@ NtUserMoveWindow(
26762710
DWORD
26772711
NTAPI
26782712
NtUserNotifyIMEStatus(
2679-
DWORD Unknown0,
2680-
DWORD Unknown1,
2681-
DWORD Unknown2);
2713+
HWND hwnd,
2714+
HIMC hIMC,
2715+
DWORD dwConversion);
26822716

26832717
BOOL
26842718
NTAPI
@@ -2787,7 +2821,7 @@ NtUserQueryInformationThread(
27872821
DWORD
27882822
NTAPI
27892823
NtUserQueryInputContext(
2790-
DWORD dwUnknown1,
2824+
HIMC hIMC,
27912825
DWORD dwUnknown2);
27922826

27932827
DWORD

win32ss/user/ntuser/ime.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,12 @@ NtUserGetImeHotKey(IN DWORD dwHotKey,
5050
DWORD
5151
APIENTRY
5252
NtUserNotifyIMEStatus(
53-
DWORD Unknown0,
54-
DWORD Unknown1,
55-
DWORD Unknown2)
53+
HWND hwnd,
54+
HIMC hIMC,
55+
DWORD dwConversion)
5656
{
57-
STUB
58-
59-
return 0;
57+
TRACE("NtUserNotifyIMEStatus(%p, %p, 0x%lX)\n", hwnd, hIMC, dwConversion);
58+
return 0;
6059
}
6160

6261

win32ss/user/ntuser/ntstubs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,10 +630,10 @@ NtUserQueryInformationThread(IN HANDLE ThreadHandle,
630630
DWORD
631631
APIENTRY
632632
NtUserQueryInputContext(
633-
DWORD dwUnknown1,
633+
HIMC hIMC,
634634
DWORD dwUnknown2)
635635
{
636-
STUB;
636+
TRACE("NtUserQueryInputContext(%p, 0x%lX)\n", hIMC, dwUnknown2);
637637
return 0;
638638
}
639639

0 commit comments

Comments
 (0)