https://git.reactos.org/?p=reactos.git;a=commitdiff;h=692a30a84ab8df23e4885…
commit 692a30a84ab8df23e48851d62c6552678180636e
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Aug 4 09:41:59 2021 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Wed Aug 4 09:41:59 2021 +0900
[IMM32] ImmCreateContext, ImmDestroyContext, DllMain etc. (#3867)
- Rewrite ImmCreateContext, ImmDestroyContext, and DllMain functions.
- Add g_hImm32Inst, g_bClientRegd, and g_SharedInfo global variables. Delete
g_dwImm32Flags (that was g_psi->dwSRVIFlags).
- Implement ImmLoadIME and ImmRegisterClient functions.
- Modify CLIENTIMC and IMEDPI structures. Move CLIENTIMC definition into ntuser.h.
- Add file win32ss/include/imetable.h.
- Rename SRVINFO_METRICS macro as SRVINFO_CICERO_ENABLED.
CORE-11700
---
dll/win32/imm32/CMakeLists.txt | 2 +-
dll/win32/imm32/imm.c | 710 +++++++++++++++++++++++++-------------
dll/win32/imm32/imm32.spec | 2 +-
sdk/include/psdk/imm.h | 6 +-
sdk/include/reactos/imm32_undoc.h | 18 -
win32ss/include/imetable.h | 22 ++
win32ss/include/ntuser.h | 92 +++--
win32ss/user/ntuser/ime.c | 4 +-
win32ss/user/ntuser/metric.c | 2 +-
win32ss/user/ntuser/ntstubs.c | 14 +-
10 files changed, 581 insertions(+), 291 deletions(-)
diff --git a/dll/win32/imm32/CMakeLists.txt b/dll/win32/imm32/CMakeLists.txt
index 10c1a6e3708..9ccdcd26f20 100644
--- a/dll/win32/imm32/CMakeLists.txt
+++ b/dll/win32/imm32/CMakeLists.txt
@@ -15,5 +15,5 @@ list(APPEND SOURCE
add_library(imm32 MODULE ${SOURCE} version.rc)
set_module_type(imm32 win32dll)
target_link_libraries(imm32 wine win32ksys)
-add_importlibs(imm32 advapi32 user32 msvcrt kernel32 ntdll)
+add_importlibs(imm32 advapi32 user32 gdi32 msvcrt kernel32 ntdll)
add_cd_file(TARGET imm32 DESTINATION reactos/system32 FOR all)
diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index 62f1569c354..7e3f932b517 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -57,11 +57,55 @@ WINE_DEFAULT_DEBUG_CHANNEL(imm);
#define REGKEY_IMM \
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\IMM"
+#define ROUNDUP4(n) (((n) + 3) & ~3) /* DWORD alignment */
+
+HMODULE g_hImm32Inst = NULL;
RTL_CRITICAL_SECTION g_csImeDpi;
PIMEDPI g_pImeDpiList = NULL;
PSERVERINFO g_psi = NULL;
+SHAREDINFO g_SharedInfo = { NULL };
+BYTE g_bClientRegd = FALSE;
+HANDLE g_hImm32Heap = NULL;
-BOOL WINAPI User32InitializeImmEntryTable(DWORD);
+static BOOL APIENTRY Imm32InitInstance(HMODULE hMod)
+{
+ NTSTATUS status;
+
+ if (hMod)
+ g_hImm32Inst = hMod;
+
+ if (g_bClientRegd)
+ return TRUE;
+
+ status = RtlInitializeCriticalSection(&g_csImeDpi);
+ if (NT_ERROR(status))
+ return FALSE;
+
+ g_bClientRegd = TRUE;
+ return TRUE;
+}
+
+LPVOID APIENTRY Imm32HeapAlloc(DWORD dwFlags, DWORD dwBytes)
+{
+ if (!g_hImm32Heap)
+ {
+ g_hImm32Heap = RtlGetProcessHeap();
+ if (g_hImm32Heap == NULL)
+ return NULL;
+ }
+ return HeapAlloc(g_hImm32Heap, dwFlags, dwBytes);
+}
+
+static DWORD_PTR APIENTRY Imm32QueryWindow(HWND hWnd, DWORD Index)
+{
+ return NtUserQueryWindow(hWnd, Index);
+}
+
+static DWORD APIENTRY
+Imm32UpdateInputContext(HIMC hIMC, DWORD Unknown1, PCLIENTIMC pClientImc)
+{
+ return NtUserUpdateInputContext(hIMC, Unknown1, pClientImc);
+}
static DWORD APIENTRY Imm32QueryInputContext(HIMC hIMC, DWORD dwUnknown2)
{
@@ -73,6 +117,21 @@ static DWORD APIENTRY Imm32NotifyIMEStatus(HWND hwnd, HIMC hIMC, DWORD
dwConvers
return NtUserNotifyIMEStatus(hwnd, hIMC, dwConversion);
}
+static HIMC APIENTRY Imm32CreateInputContext(PCLIENTIMC pClientImc)
+{
+ return NtUserCreateInputContext(pClientImc);
+}
+
+static BOOL APIENTRY Imm32DestroyInputContext(HIMC hIMC)
+{
+ return NtUserDestroyInputContext(hIMC);
+}
+
+DWORD_PTR APIENTRY Imm32GetThreadState(DWORD Routine)
+{
+ return NtUserGetThreadState(Routine);
+}
+
static VOID APIENTRY Imm32FreeImeDpi(PIMEDPI pImeDpi, BOOL bDestroy)
{
if (pImeDpi->hInst == NULL)
@@ -115,6 +174,269 @@ Imm32NotifyAction(HIMC hIMC, HWND hwnd, DWORD dwAction, DWORD_PTR
dwIndex, DWORD
return TRUE;
}
+static PIMEDPI APIENTRY Imm32FindImeDpi(HKL hKL)
+{
+ PIMEDPI pImeDpi;
+
+ RtlEnterCriticalSection(&g_csImeDpi);
+ for (pImeDpi = g_pImeDpiList; pImeDpi != NULL; pImeDpi = pImeDpi->pNext)
+ {
+ if (pImeDpi->hKL == hKL)
+ break;
+ }
+ RtlLeaveCriticalSection(&g_csImeDpi);
+
+ return pImeDpi;
+}
+
+static BOOL Imm32GetSystemLibraryPath(LPWSTR pszPath, DWORD cchPath, LPCWSTR
pszFileName)
+{
+ if (!pszFileName[0] || !GetSystemDirectoryW(pszPath, cchPath))
+ return FALSE;
+ StringCchCatW(pszPath, cchPath, L"\\");
+ StringCchCatW(pszPath, cchPath, pszFileName);
+ return TRUE;
+}
+
+DWORD APIENTRY Imm32SetImeOwnerWindow(PIMEINFOEX pImeInfoEx, BOOL fFlag)
+{
+ return NtUserSetImeOwnerWindow(pImeInfoEx, fFlag);
+}
+
+static BOOL APIENTRY Imm32InquireIme(PIMEDPI pImeDpi)
+{
+ WCHAR szUIClass[64];
+ WNDCLASSW wcW;
+ DWORD dwSysInfoFlags = 0; // TODO: ???
+ LPIMEINFO pImeInfo = &pImeDpi->ImeInfo;
+
+ // TODO: Imm32GetThreadState(THREADSTATE_UNKNOWN16);
+
+ if (!IS_IME_HKL(pImeDpi->hKL))
+ {
+ if (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)
&&
+ pImeDpi->CtfImeInquireExW)
+ {
+ // TODO:
+ return FALSE;
+ }
+ }
+
+ if (!pImeDpi->ImeInquire(pImeInfo, szUIClass, dwSysInfoFlags))
+ return FALSE;
+
+ szUIClass[_countof(szUIClass) - 1] = 0;
+
+ if (pImeInfo->dwPrivateDataSize == 0)
+ pImeInfo->dwPrivateDataSize = 4;
+
+#define VALID_IME_PROP (IME_PROP_AT_CARET | \
+ IME_PROP_SPECIAL_UI | \
+ IME_PROP_CANDLIST_START_FROM_1 | \
+ IME_PROP_UNICODE | \
+ IME_PROP_COMPLETE_ON_UNSELECT | \
+ IME_PROP_END_UNLOAD | \
+ IME_PROP_KBD_CHAR_FIRST | \
+ IME_PROP_IGNORE_UPKEYS | \
+ IME_PROP_NEED_ALTKEY | \
+ IME_PROP_NO_KEYS_ON_CLOSE | \
+ IME_PROP_ACCEPT_WIDE_VKEY)
+#define VALID_CMODE_CAPS (IME_CMODE_ALPHANUMERIC | \
+ IME_CMODE_NATIVE | \
+ IME_CMODE_KATAKANA | \
+ IME_CMODE_LANGUAGE | \
+ IME_CMODE_FULLSHAPE | \
+ IME_CMODE_ROMAN | \
+ IME_CMODE_CHARCODE | \
+ IME_CMODE_HANJACONVERT | \
+ IME_CMODE_SOFTKBD | \
+ IME_CMODE_NOCONVERSION | \
+ IME_CMODE_EUDC | \
+ IME_CMODE_SYMBOL | \
+ IME_CMODE_FIXED)
+#define VALID_SMODE_CAPS (IME_SMODE_NONE | \
+ IME_SMODE_PLAURALCLAUSE | \
+ IME_SMODE_SINGLECONVERT | \
+ IME_SMODE_AUTOMATIC | \
+ IME_SMODE_PHRASEPREDICT | \
+ IME_SMODE_CONVERSATION)
+#define VALID_UI_CAPS (UI_CAP_2700 | \
+ UI_CAP_ROT90 | \
+ UI_CAP_ROTANY | \
+ UI_CAP_SOFTKBD)
+#define VALID_SCS_CAPS (SCS_CAP_COMPSTR | \
+ SCS_CAP_MAKEREAD | \
+ SCS_CAP_SETRECONVERTSTRING)
+#define VALID_SELECT_CAPS (SELECT_CAP_CONVERSION | SELECT_CAP_SENTENCE)
+
+ if (pImeInfo->fdwProperty & ~VALID_IME_PROP)
+ return FALSE;
+ if (pImeInfo->fdwConversionCaps & ~VALID_CMODE_CAPS)
+ return FALSE;
+ if (pImeInfo->fdwSentenceCaps & ~VALID_SMODE_CAPS)
+ return FALSE;
+ if (pImeInfo->fdwUICaps & ~VALID_UI_CAPS)
+ return FALSE;
+ if (pImeInfo->fdwSCSCaps & ~VALID_SCS_CAPS)
+ return FALSE;
+ if (pImeInfo->fdwSelectCaps & ~VALID_SELECT_CAPS)
+ return FALSE;
+
+#undef VALID_IME_PROP
+#undef VALID_CMODE_CAPS
+#undef VALID_SMODE_CAPS
+#undef VALID_UI_CAPS
+#undef VALID_SCS_CAPS
+#undef VALID_SELECT_CAPS
+
+ if (pImeInfo->fdwProperty & IME_PROP_UNICODE)
+ {
+ StringCchCopyW(pImeDpi->szUIClass, _countof(pImeDpi->szUIClass),
szUIClass);
+ }
+ else
+ {
+ if (pImeDpi->uCodePage != GetACP() && pImeDpi->uCodePage)
+ return FALSE;
+
+ MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPSTR)szUIClass, -1,
+ pImeDpi->szUIClass, _countof(pImeDpi->szUIClass));
+ }
+
+ return GetClassInfoW(pImeDpi->hInst, pImeDpi->szUIClass, &wcW);
+}
+
+static BOOL APIENTRY Imm32LoadImeInfo(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi)
+{
+ WCHAR szPath[MAX_PATH];
+ HINSTANCE hIME;
+ FARPROC fn;
+
+ if (!Imm32GetSystemLibraryPath(szPath, _countof(szPath), pImeInfoEx->wszImeFile))
+ return FALSE;
+
+ hIME = GetModuleHandleW(szPath);
+ if (hIME == NULL)
+ {
+ hIME = LoadLibraryW(szPath);
+ if (hIME == NULL)
+ {
+ ERR("Imm32LoadImeInfo: LoadLibraryW(%S) failed\n", szPath);
+ return FALSE;
+ }
+ }
+ pImeDpi->hInst = hIME;
+
+#define DEFINE_IME_ENTRY(type, name, params, extended) \
+ do { \
+ fn = GetProcAddress(hIME, #name); \
+ if (fn) pImeDpi->name = (FN_##name)fn; \
+ else if (!extended) goto Failed; \
+ } while (0);
+#include "../../../win32ss/include/imetable.h"
+#undef DEFINE_IME_ENTRY
+
+ if (!Imm32InquireIme(pImeDpi))
+ {
+ ERR("Imm32LoadImeInfo: Imm32InquireIme failed\n");
+ goto Failed;
+ }
+
+ if (pImeInfoEx->fLoadFlag)
+ return TRUE;
+
+ Imm32SetImeOwnerWindow(pImeInfoEx, TRUE);
+ return TRUE;
+
+Failed:
+ FreeLibrary(pImeDpi->hInst);
+ pImeDpi->hInst = NULL;
+ return FALSE;
+}
+
+static PIMEDPI APIENTRY Ime32LoadImeDpi(HKL hKL, BOOL bLock)
+{
+ IMEINFOEX ImeInfoEx;
+ CHARSETINFO ci;
+ PIMEDPI pImeDpiNew, pImeDpiFound;
+ UINT uCodePage;
+ LCID lcid;
+
+ if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL) ||
+ ImeInfoEx.fLoadFlag == 1)
+ {
+ return NULL;
+ }
+
+ pImeDpiNew = Imm32HeapAlloc(HEAP_ZERO_MEMORY, sizeof(IMEDPI));
+ if (pImeDpiNew == NULL)
+ return NULL;
+
+ pImeDpiNew->hKL = hKL;
+
+ lcid = LOWORD(hKL);
+ if (TranslateCharsetInfo((LPDWORD)(DWORD_PTR)lcid, &ci, TCI_SRCLOCALE))
+ uCodePage = ci.ciACP;
+ else
+ uCodePage = CP_ACP;
+ pImeDpiNew->uCodePage = uCodePage;
+
+ if (!Imm32LoadImeInfo(&ImeInfoEx, pImeDpiNew))
+ {
+ HeapFree(g_hImm32Heap, 0, pImeDpiNew);
+ return FALSE;
+ }
+
+ RtlEnterCriticalSection(&g_csImeDpi);
+
+ pImeDpiFound = Imm32FindImeDpi(hKL);
+ if (pImeDpiFound)
+ {
+ if (!bLock)
+ pImeDpiFound->dwFlags &= ~IMEDPI_FLAG_LOCKED;
+
+ RtlLeaveCriticalSection(&g_csImeDpi);
+
+ Imm32FreeImeDpi(pImeDpiNew, FALSE);
+ HeapFree(g_hImm32Heap, 0, pImeDpiNew);
+ return pImeDpiFound;
+ }
+ else
+ {
+ if (bLock)
+ {
+ pImeDpiNew->dwFlags |= IMEDPI_FLAG_LOCKED;
+ pImeDpiNew->cLockObj = 1;
+ }
+
+ pImeDpiNew->pNext = g_pImeDpiList;
+ g_pImeDpiList = pImeDpiNew;
+
+ RtlLeaveCriticalSection(&g_csImeDpi);
+ return pImeDpiNew;
+ }
+}
+
+BOOL WINAPI ImmLoadIME(HKL hKL)
+{
+ PW32CLIENTINFO pInfo;
+ PIMEDPI pImeDpi;
+
+ if (!IS_IME_HKL(hKL))
+ {
+ if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED))
+ return FALSE;
+
+ pInfo = (PW32CLIENTINFO)(NtCurrentTeb()->Win32ClientInfo);
+ if ((pInfo->W32ClientInfo[0] & 2))
+ return FALSE;
+ }
+
+ pImeDpi = Imm32FindImeDpi(hKL);
+ if (pImeDpi == NULL)
+ pImeDpi = Ime32LoadImeDpi(hKL, FALSE);
+ return (pImeDpi != NULL);
+}
+
HKL WINAPI ImmLoadLayout(HKL hKL, PIMEINFOEX pImeInfoEx)
{
DWORD cbData;
@@ -127,7 +449,7 @@ HKL WINAPI ImmLoadLayout(HKL hKL, PIMEINFOEX pImeInfoEx)
TRACE("ImmLoadLayout(%p, %p)\n", hKL, pImeInfoEx);
if (IS_IME_HKL(hKL) ||
- !g_psi || (g_psi->dwSRVIFlags & SRVINFO_METRICS) == 0 ||
+ !g_psi || !(g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED) ||
((PW32CLIENTINFO)NtCurrentTeb()->Win32ClientInfo)->W32ClientInfo[0] &
2)
{
UnicodeString.Buffer = szLayout;
@@ -256,7 +578,6 @@ static inline BOOL is_kbd_ime_unicode(const ImmHkl *hkl)
return !!(hkl->imeInfo.fdwProperty & IME_PROP_UNICODE);
}
-static BOOL IMM_DestroyContext(HIMC hIMC);
static InputContextData* get_imc_data(HIMC hIMC);
static inline WCHAR *strdupAtoW( const char *str )
@@ -393,36 +714,6 @@ static IMMThreadData *IMM_GetThreadData(HWND hwnd, DWORD thread)
return data;
}
-static BOOL IMM_IsDefaultContext(HIMC imc)
-{
- InputContextData *data = get_imc_data(imc);
-
- if (!data)
- return FALSE;
-
- return data->threadDefault;
-}
-
-static void IMM_FreeThreadData(void)
-{
- IMMThreadData *data;
-
- EnterCriticalSection(&threaddata_cs);
- LIST_FOR_EACH_ENTRY(data, &ImmThreadDataList, IMMThreadData, entry)
- {
- if (data->threadID == GetCurrentThreadId())
- {
- list_remove(&data->entry);
- LeaveCriticalSection(&threaddata_cs);
- IMM_DestroyContext(data->defaultContext);
- HeapFree(GetProcessHeap(),0,data);
- TRACE("Thread Data Destroyed\n");
- return;
- }
- }
- LeaveCriticalSection(&threaddata_cs);
-}
-
static HMODULE load_graphics_driver(void)
{
static const WCHAR display_device_guid_propW[] = {
@@ -531,49 +822,6 @@ HWND WINAPI __wine_get_ui_window(HKL hkl)
return immHkl->UIWnd;
}
-static void IMM_FreeAllImmHkl(void)
-{
- ImmHkl *ptr,*cursor2;
-
- LIST_FOR_EACH_ENTRY_SAFE(ptr, cursor2, &ImmHklList, ImmHkl, entry)
- {
- list_remove(&ptr->entry);
- if (ptr->hIME)
- {
- ptr->pImeDestroy(1);
- FreeLibrary(ptr->hIME);
- }
- if (ptr->UIWnd)
- DestroyWindow(ptr->UIWnd);
- HeapFree(GetProcessHeap(),0,ptr);
- }
-}
-
-BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpReserved)
-{
- TRACE("%p, %x, %p\n",hInstDLL,fdwReason,lpReserved);
- switch (fdwReason)
- {
- case DLL_PROCESS_ATTACH:
- if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
- {
- return FALSE;
- }
- break;
- case DLL_THREAD_ATTACH:
- break;
- case DLL_THREAD_DETACH:
- IMM_FreeThreadData();
- break;
- case DLL_PROCESS_DETACH:
- if (lpReserved) break;
- IMM_FreeThreadData();
- IMM_FreeAllImmHkl();
- break;
- }
- return TRUE;
-}
-
/* for posting messages as the IME */
static void ImmInternalPostIMEMessage(InputContextData *data, UINT msg, WPARAM wParam,
LPARAM lParam)
{
@@ -607,18 +855,6 @@ static LRESULT ImmInternalSendIMENotify(InputContextData *data,
WPARAM notify, L
return 0;
}
-static HIMCC ImmCreateBlankCompStr(void)
-{
- HIMCC rc;
- LPCOMPOSITIONSTRING ptr;
- rc = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
- ptr = ImmLockIMCC(rc);
- memset(ptr,0,sizeof(COMPOSITIONSTRING));
- ptr->dwSize = sizeof(COMPOSITIONSTRING);
- ImmUnlockIMCC(rc);
- return rc;
-}
-
static InputContextData* get_imc_data(HIMC hIMC)
{
InputContextData *data = hIMC;
@@ -636,43 +872,8 @@ static InputContextData* get_imc_data(HIMC hIMC)
static HIMC get_default_context( HWND hwnd )
{
- HIMC ret;
- IMMThreadData* thread_data = IMM_GetThreadData( hwnd, 0 );
-
- if (!thread_data) return 0;
-
- if (thread_data->defaultContext)
- {
- ret = thread_data->defaultContext;
- LeaveCriticalSection(&threaddata_cs);
- return ret;
- }
-
- /* can't create a default context in another thread */
- if (thread_data->threadID != GetCurrentThreadId())
- {
- LeaveCriticalSection(&threaddata_cs);
- return 0;
- }
-
- LeaveCriticalSection(&threaddata_cs);
-
- ret = ImmCreateContext();
- if (!ret) return 0;
- ((InputContextData*)ret)->threadDefault = TRUE;
-
- /* thread_data is in the current thread so we can assume it's still valid */
- EnterCriticalSection(&threaddata_cs);
-
- if (thread_data->defaultContext) /* someone beat us */
- {
- IMM_DestroyContext( ret );
- ret = thread_data->defaultContext;
- }
- else thread_data->defaultContext = ret;
-
- LeaveCriticalSection(&threaddata_cs);
- return ret;
+ FIXME("Don't use this function\n");
+ return FALSE;
}
static BOOL IMM_IsCrossThreadAccess(HWND hWnd, HIMC hIMC)
@@ -873,83 +1074,106 @@ BOOL WINAPI ImmConfigureIMEW(
*/
HIMC WINAPI ImmCreateContext(void)
{
- InputContextData *new_context;
- LPGUIDELINE gl;
- LPCANDIDATEINFO ci;
- int i;
+ PCLIENTIMC pClientImc;
+ HIMC hIMC;
- new_context = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(InputContextData));
+ TRACE("ImmCreateContext()\n");
- /* Load the IME */
- new_context->immKbd = IMM_GetImmHkl(GetKeyboardLayout(0));
+ if (g_psi == NULL || !(g_psi->dwSRVIFlags & SRVINFO_IMM32))
+ return NULL;
- if (!new_context->immKbd->hIME)
+ pClientImc = Imm32HeapAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
+ if (pClientImc == NULL)
+ return NULL;
+
+ hIMC = Imm32CreateInputContext(pClientImc);
+ if (hIMC == NULL)
{
- TRACE("IME dll could not be loaded\n");
- HeapFree(GetProcessHeap(),0,new_context);
- return 0;
+ HeapFree(g_hImm32Heap, 0, pClientImc);
+ return NULL;
}
- /* the HIMCCs are never NULL */
- new_context->IMC.hCompStr = ImmCreateBlankCompStr();
- new_context->IMC.hMsgBuf = ImmCreateIMCC(0);
- new_context->IMC.hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
- ci = ImmLockIMCC(new_context->IMC.hCandInfo);
- memset(ci,0,sizeof(CANDIDATEINFO));
- ci->dwSize = sizeof(CANDIDATEINFO);
- ImmUnlockIMCC(new_context->IMC.hCandInfo);
- new_context->IMC.hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
- gl = ImmLockIMCC(new_context->IMC.hGuideLine);
- memset(gl,0,sizeof(GUIDELINE));
- gl->dwSize = sizeof(GUIDELINE);
- ImmUnlockIMCC(new_context->IMC.hGuideLine);
+ RtlInitializeCriticalSection(&pClientImc->cs);
+ pClientImc->unknown = Imm32GetThreadState(THREADSTATE_UNKNOWN13);
+ return hIMC;
+}
- for (i = 0; i < ARRAY_SIZE(new_context->IMC.cfCandForm); i++)
- new_context->IMC.cfCandForm[i].dwIndex = ~0u;
+static VOID APIENTRY Imm32CleanupContextExtra(LPINPUTCONTEXT pIC)
+{
+ FIXME("We have to do something do here");
+}
- /* Initialize the IME Private */
- new_context->IMC.hPrivate =
ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
+static PCLIENTIMC APIENTRY Imm32FindClientImc(HIMC hIMC)
+{
+ // FIXME
+ return NULL;
+}
- new_context->IMC.fdwConversion =
new_context->immKbd->imeInfo.fdwConversionCaps;
- new_context->IMC.fdwSentence =
new_context->immKbd->imeInfo.fdwSentenceCaps;
+BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
+{
+ PIMEDPI pImeDpi;
+ LPINPUTCONTEXT pIC;
+ PCLIENTIMC pClientImc;
- if (!new_context->immKbd->pImeSelect(new_context, TRUE))
+ if (g_psi == NULL || !(g_psi->dwSRVIFlags & SRVINFO_IMM32) || hIMC == NULL)
+ return FALSE;
+
+ FIXME("We have do something to do here\n");
+ pClientImc = Imm32FindClientImc(hIMC);
+ if (!pClientImc)
+ return FALSE;
+
+ if (pClientImc->hImc == NULL)
{
- TRACE("Selection of IME failed\n");
- IMM_DestroyContext(new_context);
- return 0;
+ pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
+ ImmUnlockClientImc(pClientImc);
+ if (!bKeep)
+ return Imm32DestroyInputContext(hIMC);
+ return TRUE;
}
- new_context->threadID = GetCurrentThreadId();
- SendMessageW(GetFocus(), WM_IME_SELECT, TRUE, (LPARAM)new_context->immKbd);
- new_context->immKbd->uSelected++;
- TRACE("Created context %p\n",new_context);
+ pIC = ImmLockIMC(hIMC);
+ if (pIC == NULL)
+ {
+ ImmUnlockClientImc(pClientImc);
+ return FALSE;
+ }
- new_context->magic = WINE_IMC_VALID_MAGIC;
- return new_context;
-}
+ FIXME("We have do something to do here\n");
-static BOOL IMM_DestroyContext(HIMC hIMC)
-{
- InputContextData *data = get_imc_data(hIMC);
+ if (pClientImc->hKL == hKL)
+ {
+ pImeDpi = ImmLockImeDpi(hKL);
+ if (pImeDpi != NULL)
+ {
+ if (IS_IME_HKL(hKL))
+ {
+ pImeDpi->ImeSelect(hIMC, FALSE);
+ }
+ else if (g_psi && (g_psi->dwSRVIFlags &
SRVINFO_CICERO_ENABLED))
+ {
+ FIXME("We have do something to do here\n");
+ }
+ ImmUnlockImeDpi(pImeDpi);
+ }
+ pClientImc->hKL = NULL;
+ }
- TRACE("Destroying %p\n",hIMC);
+ ImmDestroyIMCC(pIC->hPrivate);
+ ImmDestroyIMCC(pIC->hMsgBuf);
+ ImmDestroyIMCC(pIC->hGuideLine);
+ ImmDestroyIMCC(pIC->hCandInfo);
+ ImmDestroyIMCC(pIC->hCompStr);
- if (!data)
- return FALSE;
+ Imm32CleanupContextExtra(pIC);
- data->immKbd->uSelected --;
- data->immKbd->pImeSelect(hIMC, FALSE);
- SendMessageW(data->IMC.hWnd, WM_IME_SELECT, FALSE, (LPARAM)data->immKbd);
+ ImmUnlockIMC(hIMC);
- ImmDestroyIMCC(data->IMC.hCompStr);
- ImmDestroyIMCC(data->IMC.hCandInfo);
- ImmDestroyIMCC(data->IMC.hGuideLine);
- ImmDestroyIMCC(data->IMC.hPrivate);
- ImmDestroyIMCC(data->IMC.hMsgBuf);
+ pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
+ ImmUnlockClientImc(pClientImc);
- data->magic = 0;
- HeapFree(GetProcessHeap(),0,data);
+ if (!bKeep)
+ return Imm32DestroyInputContext(hIMC);
return TRUE;
}
@@ -959,10 +1183,21 @@ static BOOL IMM_DestroyContext(HIMC hIMC)
*/
BOOL WINAPI ImmDestroyContext(HIMC hIMC)
{
- if (!IMM_IsDefaultContext(hIMC) && !IMM_IsCrossThreadAccess(NULL, hIMC))
- return IMM_DestroyContext(hIMC);
- else
+ DWORD dwImeThreadId, dwThreadId;
+ HKL hKL;
+
+ TRACE("ImmDestroyContext(%p)\n", hIMC);
+
+ if (g_psi == NULL || !(g_psi->dwSRVIFlags & SRVINFO_IMM32))
return FALSE;
+
+ dwImeThreadId = Imm32QueryInputContext(hIMC, 1);
+ dwThreadId = GetCurrentThreadId();
+ if (dwImeThreadId != dwThreadId)
+ return FALSE;
+
+ hKL = GetKeyboardLayout(0);
+ return Imm32CleanupContext(hIMC, hKL, FALSE);
}
/***********************************************************************
@@ -1122,43 +1357,6 @@ LRESULT WINAPI ImmEscapeW(
return 0;
}
-#define ROUNDUP4(n) (((n) + 3) & ~3) /* DWORD alignment */
-
-HANDLE g_hImm32Heap = NULL;
-DWORD g_dwImm32Flags = 0;
-
-/* flags for g_dwImm32Flags */
-#define IMM32_FLAG_UNKNOWN 0x4
-#define IMM32_FLAG_CICERO_ENABLED 0x20
-
-LPVOID APIENTRY Imm32HeapAlloc(DWORD dwFlags, DWORD dwBytes)
-{
- if (!g_hImm32Heap)
- {
- g_hImm32Heap = RtlGetProcessHeap();
- if (g_hImm32Heap == NULL)
- return NULL;
- }
- return HeapAlloc(g_hImm32Heap, dwFlags, dwBytes);
-}
-
-static DWORD_PTR APIENTRY
-Imm32GetThreadState(DWORD Routine)
-{
- return NtUserGetThreadState(Routine);
-}
-
-static DWORD_PTR APIENTRY Imm32QueryWindow(HWND hWnd, DWORD Index)
-{
- return NtUserQueryWindow(hWnd, Index);
-}
-
-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
@@ -2501,7 +2699,7 @@ void WINAPI __wine_unregister_window(HWND hwnd)
*/
HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
{
- if (!(g_dwImm32Flags & IMM32_FLAG_UNKNOWN))
+ if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_IMM32))
return NULL;
if (hWnd == NULL)
@@ -2515,7 +2713,7 @@ HWND WINAPI ImmGetDefaultIMEWnd(HWND hWnd)
*/
BOOL WINAPI CtfImmIsCiceroEnabled(VOID)
{
- return !!(g_dwImm32Flags & IMM32_FLAG_CICERO_ENABLED);
+ return (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED));
}
/***********************************************************************
@@ -3401,8 +3599,8 @@ VOID WINAPI ImmUnlockImeDpi(PIMEDPI pImeDpi)
if ((pImeDpi->dwFlags & IMEDPI_FLAG_UNKNOWN) == 0)
{
- if ((pImeDpi->dwFlags & IMEDPI_FLAG_UNKNOWN2) == 0 ||
- (pImeDpi->dwUnknown1 & 1) == 0)
+ if ((pImeDpi->dwFlags & IMEDPI_FLAG_LOCKED) == 0 ||
+ (pImeDpi->ImeInfo.fdwProperty & IME_PROP_END_UNLOAD) == 0)
{
RtlLeaveCriticalSection(&g_csImeDpi);
return;
@@ -4110,11 +4308,11 @@ BOOL WINAPI ImmSetActiveContextConsoleIME(HWND hwnd, BOOL fFlag)
* ImmRegisterClient(IMM32.@)
* ( Undocumented, called from user32.dll )
*/
-BOOL WINAPI ImmRegisterClient(PVOID ptr, /* FIXME: should point to SHAREDINFO structure
*/
- HINSTANCE hMod)
+BOOL WINAPI ImmRegisterClient(PSHAREDINFO ptr, HINSTANCE hMod)
{
- FIXME("Stub\n");
- return TRUE;
+ g_SharedInfo = *ptr;
+ g_psi = g_SharedInfo.psi;
+ return Imm32InitInstance(hMod);
}
/***********************************************************************
@@ -4167,7 +4365,7 @@ ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx,
if (!IS_IME_HKL(hKL))
{
- if (g_dwImm32Flags & IMM32_FLAG_CICERO_ENABLED)
+ if (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED))
{
pTeb = NtCurrentTeb();
if (((PW32CLIENTINFO)pTeb->Win32ClientInfo)->W32ClientInfo[0] & 2)
@@ -4181,3 +4379,53 @@ ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx,
Quit:
return Imm32GetImeInfoEx(pImeInfoEx, SearchType);
}
+
+BOOL WINAPI User32InitializeImmEntryTable(DWORD);
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+ HKL hKL;
+ HWND hWnd;
+ PTEB pTeb;
+
+ TRACE("DllMain(%p, 0x%X, %p)\n", hinstDLL, fdwReason, lpReserved);
+
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ //Imm32GenerateRandomSeed(hinstDLL, 1, lpReserved); // Non-sense
+ if (!Imm32InitInstance(hinstDLL))
+ {
+ ERR("Imm32InitInstance failed\n");
+ return FALSE;
+ }
+ if (!User32InitializeImmEntryTable(IMM_INIT_MAGIC))
+ {
+ ERR("User32InitializeImmEntryTable failed\n");
+ return FALSE;
+ }
+ break;
+
+ case DLL_THREAD_ATTACH:
+ break;
+
+ case DLL_THREAD_DETACH:
+ if (g_psi == NULL || !(g_psi->dwSRVIFlags & SRVINFO_IMM32))
+ return TRUE;
+
+ pTeb = NtCurrentTeb();
+ if (pTeb->Win32ThreadInfo == NULL)
+ return TRUE;
+
+ hKL = GetKeyboardLayout(0);
+ hWnd = (HWND)Imm32GetThreadState(THREADSTATE_CAPTUREWINDOW);
+ Imm32CleanupContext(hWnd, hKL, TRUE);
+ break;
+
+ case DLL_PROCESS_DETACH:
+ RtlDeleteCriticalSection(&g_csImeDpi);
+ break;
+ }
+
+ return TRUE;
+}
diff --git a/dll/win32/imm32/imm32.spec b/dll/win32/imm32/imm32.spec
index d7a269dd5be..104e4242fc0 100644
--- a/dll/win32/imm32/imm32.spec
+++ b/dll/win32/imm32/imm32.spec
@@ -68,7 +68,7 @@
@ stdcall ImmIsIME(long)
@ stdcall ImmIsUIMessageA(long long long long)
@ stdcall ImmIsUIMessageW(long long long long)
-@ stdcall -stub ImmLoadIME(long)
+@ stdcall ImmLoadIME(ptr)
@ stdcall ImmLoadLayout(ptr ptr)
@ stdcall ImmLockClientImc(ptr)
@ stdcall ImmLockIMC(ptr)
diff --git a/sdk/include/psdk/imm.h b/sdk/include/psdk/imm.h
index e856648c170..7b0888b033e 100644
--- a/sdk/include/psdk/imm.h
+++ b/sdk/include/psdk/imm.h
@@ -215,6 +215,7 @@ typedef struct tagCANDIDATEINFO {
#define IME_PROP_IGNORE_UPKEYS 0x0004
#define IME_PROP_NEED_ALTKEY 0x0008
#define IME_PROP_NO_KEYS_ON_CLOSE 0x0010
+#define IME_PROP_ACCEPT_WIDE_VKEY 0x0020
/* for NI_CONTEXTUPDATED */
#define IMC_SETCONVERSIONMODE 0x0002
@@ -381,7 +382,6 @@ DWORD WINAPI ImeGetImeMenuItems(HIMC, DWORD, DWORD,
LPIMEMENUITEMINFOW, LPIMEMEN
#define IMEVER_0310 0x0003000A
#define IMEVER_0400 0x00040000
-
/* IME property bits */
#define IME_PROP_AT_CARET 0x00010000
#define IME_PROP_SPECIAL_UI 0x00020000
@@ -389,17 +389,17 @@ DWORD WINAPI ImeGetImeMenuItems(HIMC, DWORD, DWORD,
LPIMEMENUITEMINFOW, LPIMEMEN
#define IME_PROP_UNICODE 0x00080000
#define IME_PROP_COMPLETE_ON_UNSELECT 0x00100000
-
/* IME UICapability bits */
#define UI_CAP_2700 0x00000001
#define UI_CAP_ROT90 0x00000002
#define UI_CAP_ROTANY 0x00000004
+#define UI_CAP_SOFTKBD 0x00010000
+
/* ImmSetCompositionString Capability bits */
#define SCS_CAP_COMPSTR 0x00000001
#define SCS_CAP_MAKEREAD 0x00000002
#define SCS_CAP_SETRECONVERTSTRING 0x00000004
-
/* IME WM_IME_SELECT inheritance Capability bits */
#define SELECT_CAP_CONVERSION 0x00000001
#define SELECT_CAP_SENTENCE 0x00000002
diff --git a/sdk/include/reactos/imm32_undoc.h b/sdk/include/reactos/imm32_undoc.h
index a9a20c49b18..be00e353492 100644
--- a/sdk/include/reactos/imm32_undoc.h
+++ b/sdk/include/reactos/imm32_undoc.h
@@ -7,24 +7,6 @@
#pragma once
-/* 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 0x1
-#define CLIENTIMC_UNKNOWN1 0x40
-#define CLIENTIMC_UNKNOWN2 0x100
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/win32ss/include/imetable.h b/win32ss/include/imetable.h
new file mode 100644
index 00000000000..5157ec43030
--- /dev/null
+++ b/win32ss/include/imetable.h
@@ -0,0 +1,22 @@
+/* DEFINE_IME_ENTRY(type, name, params, extended) */
+DEFINE_IME_ENTRY(BOOL, ImeInquire, (LPIMEINFO lpIMEInfo, LPWSTR lpszWndClass, DWORD
dwSystemInfoFlags), FALSE)
+DEFINE_IME_ENTRY(DWORD, ImeConversionList, (HIMC hIMC, LPCWSTR lpSrc, LPCANDIDATELIST
lpDst, DWORD dwBufLen, UINT uFlag), FALSE)
+DEFINE_IME_ENTRY(BOOL, ImeRegisterWord, (LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR
lpszString), FALSE)
+DEFINE_IME_ENTRY(BOOL, ImeUnregisterWord, (LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR
lpszString), FALSE)
+DEFINE_IME_ENTRY(UINT, ImeGetRegisterWordStyle, (UINT nItem, LPSTYLEBUFW lpStyleBuf),
FALSE)
+DEFINE_IME_ENTRY(UINT, ImeEnumRegisterWord, (HKL hKL, REGISTERWORDENUMPROCW lpfnEnumProc,
LPCWSTR lpszReading, DWORD dwStyle, LPCWSTR lpszString, LPVOID lpData), FALSE)
+DEFINE_IME_ENTRY(BOOL, ImeConfigure, (HKL hKL, HWND hWnd, DWORD dwMode, LPVOID lpData),
FALSE)
+DEFINE_IME_ENTRY(BOOL, ImeDestroy, (UINT uReserved), FALSE)
+DEFINE_IME_ENTRY(LRESULT, ImeEscape, (HIMC hIMC, UINT uEscape, LPVOID lpData), FALSE)
+DEFINE_IME_ENTRY(BOOL, ImeSelect, (HIMC hIMC, BOOL fSelect), FALSE)
+DEFINE_IME_ENTRY(BOOL, ImeProcessKey, (HIMC hIMC, UINT uVirKey, DWORD lParam, CONST
LPBYTE lpbKeyState), FALSE)
+DEFINE_IME_ENTRY(BOOL, ImeSetActiveContext, (HIMC hIMC, BOOL fFlag), FALSE)
+DEFINE_IME_ENTRY(UINT, ImeToAsciiEx, (UINT uVirKey, UINT uScanCode, CONST LPBYTE
lpbKeyState, /*FIXME: LPTRANSMSGLIST*/ LPVOID lpTransMsgList, UINT fuState, HIMC hIMC),
FALSE)
+DEFINE_IME_ENTRY(BOOL, NotifyIME, (HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD
dwValue), FALSE)
+DEFINE_IME_ENTRY(BOOL, ImeSetCompositionString, (HIMC hIMC, DWORD dwIndex, LPCVOID
lpComp, DWORD dwCompLen, LPCVOID lpRead, DWORD dwReadLen), FALSE)
+DEFINE_IME_ENTRY(DWORD, ImeGetImeMenuItems, (HIMC hIMC, DWORD dwFlags, DWORD dwType,
LPIMEMENUITEMINFOW lpImeParentMenu, LPIMEMENUITEMINFOW lpImeMenu, DWORD dwSize), FALSE)
+DEFINE_IME_ENTRY(DWORD, CtfImeInquireExW, (VOID /* FIXME: unknown */), TRUE)
+DEFINE_IME_ENTRY(DWORD, CtfImeSelectEx, (VOID /* FIXME: unknown */), TRUE)
+DEFINE_IME_ENTRY(DWORD, CtfImeEscapeEx, (VOID /* FIXME: unknown */), TRUE)
+DEFINE_IME_ENTRY(DWORD, CtfImeGetGuidAtom, (VOID /* FIXME: unknown */), TRUE)
+DEFINE_IME_ENTRY(DWORD, CtfImeIsGuidMapEnable, (VOID /* FIXME: unknown */), TRUE)
diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h
index 024e9413a0a..26e89fb396a 100644
--- a/win32ss/include/ntuser.h
+++ b/win32ss/include/ntuser.h
@@ -912,7 +912,7 @@ typedef LONG_PTR
#define SRVINFO_DBCSENABLED 0x0002
#define SRVINFO_IMM32 0x0004
#define SRVINFO_APIHOOK 0x0010
-#define SRVINFO_METRICS 0x0020
+#define SRVINFO_CICERO_ENABLED 0x0020
#define SRVINFO_KBDPREF 0x0080
#define NUM_SYSCOLORS 31
@@ -1212,42 +1212,88 @@ typedef struct _IMEWND
PIMEUI pimeui;
} IMEWND, *PIMEWND;
-typedef BOOL (WINAPI *FN_ImeDestroy)(UINT uReserved);
-typedef LRESULT (WINAPI *FN_ImeEscape)(HIMC hIMC, UINT uEscape, LPVOID lpData);
-typedef BOOL (WINAPI *FN_NotifyIME)(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD
dwValue);
+#define DEFINE_IME_ENTRY(type, name, params, extended) typedef type (WINAPI *FN_##name)
params;
+#include "imetable.h"
+#undef DEFINE_IME_ENTRY
-typedef struct IMEDPI /* unconfirmed */
+typedef struct IMEDPI
{
struct IMEDPI *pNext;
HINSTANCE hInst;
HKL hKL;
- DWORD dwUnknown0;
- DWORD dwUnknown1;
- DWORD dwUnknown2[14];
+ IMEINFO ImeInfo;
+ UINT uCodePage;
+ WCHAR szUIClass[16];
DWORD cLockObj;
DWORD dwFlags;
- DWORD dwUnknown3[7];
- FN_ImeDestroy ImeDestroy;
- FN_ImeEscape ImeEscape;
- DWORD dwUnknown4[4];
- FN_NotifyIME NotifyIME;
- /* ... */
+#define DEFINE_IME_ENTRY(type, name, params, extended) FN_##name name;
+#include "imetable.h"
+#undef DEFINE_IME_ENTRY
} 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, ImeInfo) == 0xc);
+C_ASSERT(offsetof(IMEDPI, uCodePage) == 0x28);
+C_ASSERT(offsetof(IMEDPI, szUIClass) == 0x2c);
C_ASSERT(offsetof(IMEDPI, cLockObj) == 0x4c);
C_ASSERT(offsetof(IMEDPI, dwFlags) == 0x50);
+C_ASSERT(offsetof(IMEDPI, ImeInquire) == 0x54);
+C_ASSERT(offsetof(IMEDPI, ImeConversionList) == 0x58);
+C_ASSERT(offsetof(IMEDPI, ImeRegisterWord) == 0x5c);
+C_ASSERT(offsetof(IMEDPI, ImeUnregisterWord) == 0x60);
+C_ASSERT(offsetof(IMEDPI, ImeGetRegisterWordStyle) == 0x64);
+C_ASSERT(offsetof(IMEDPI, ImeEnumRegisterWord) == 0x68);
+C_ASSERT(offsetof(IMEDPI, ImeConfigure) == 0x6c);
C_ASSERT(offsetof(IMEDPI, ImeDestroy) == 0x70);
C_ASSERT(offsetof(IMEDPI, ImeEscape) == 0x74);
+C_ASSERT(offsetof(IMEDPI, ImeSelect) == 0x78);
+C_ASSERT(offsetof(IMEDPI, ImeProcessKey) == 0x7c);
+C_ASSERT(offsetof(IMEDPI, ImeSetActiveContext) == 0x80);
+C_ASSERT(offsetof(IMEDPI, ImeToAsciiEx) == 0x84);
C_ASSERT(offsetof(IMEDPI, NotifyIME) == 0x88);
+C_ASSERT(offsetof(IMEDPI, ImeSetCompositionString) == 0x8c);
+C_ASSERT(offsetof(IMEDPI, ImeGetImeMenuItems) == 0x90);
+C_ASSERT(offsetof(IMEDPI, CtfImeInquireExW) == 0x94);
+C_ASSERT(offsetof(IMEDPI, CtfImeSelectEx) == 0x98);
+C_ASSERT(offsetof(IMEDPI, CtfImeEscapeEx) == 0x9c);
+C_ASSERT(offsetof(IMEDPI, CtfImeGetGuidAtom) == 0xa0);
+C_ASSERT(offsetof(IMEDPI, CtfImeIsGuidMapEnable) == 0xa4);
+C_ASSERT(sizeof(IMEDPI) == 0xa8);
#endif
/* flags for IMEDPI.dwFlags */
-#define IMEDPI_FLAG_UNKNOWN 1
-#define IMEDPI_FLAG_UNKNOWN2 2
+#define IMEDPI_FLAG_UNKNOWN 0x1
+#define IMEDPI_FLAG_LOCKED 0x2
+
+/* unconfirmed */
+typedef struct tagCLIENTIMC
+{
+ HIMC hImc;
+ LONG cLockObj;
+ DWORD dwFlags;
+ DWORD unknown;
+ RTL_CRITICAL_SECTION cs;
+ DWORD unknown2;
+ HKL hKL;
+ BOOL bUnknown4;
+} CLIENTIMC, *PCLIENTIMC;
+
+#ifndef _WIN64
+C_ASSERT(offsetof(CLIENTIMC, hImc) == 0x0);
+C_ASSERT(offsetof(CLIENTIMC, cLockObj) == 0x4);
+C_ASSERT(offsetof(CLIENTIMC, dwFlags) == 0x8);
+C_ASSERT(offsetof(CLIENTIMC, cs) == 0x10);
+C_ASSERT(offsetof(CLIENTIMC, hKL) == 0x2c);
+C_ASSERT(sizeof(CLIENTIMC) == 0x34);
+#endif
+
+/* flags for CLIENTIMC */
+#define CLIENTIMC_WIDE 0x1
+#define CLIENTIMC_UNKNOWN1 0x40
+#define CLIENTIMC_UNKNOWN2 0x100
DWORD
NTAPI
@@ -1869,10 +1915,9 @@ NtUserCreateDesktop(
DWORD dwFlags,
ACCESS_MASK dwDesiredAccess);
-DWORD
+HIMC
NTAPI
-NtUserCreateInputContext(
- DWORD dwUnknown1);
+NtUserCreateInputContext(PCLIENTIMC pClientImc);
NTSTATUS
NTAPI
@@ -1964,10 +2009,9 @@ NtUserDestroyCursor(
_In_ HANDLE Handle,
_In_ BOOL bForce);
-DWORD
+BOOL
NTAPI
-NtUserDestroyInputContext(
- DWORD dwUnknown1);
+NtUserDestroyInputContext(HIMC hIMC);
BOOLEAN
NTAPI
@@ -3130,9 +3174,7 @@ NtUserSetImeInfoEx(
DWORD
NTAPI
-NtUserSetImeOwnerWindow(
- DWORD Unknown0,
- DWORD Unknown1);
+NtUserSetImeOwnerWindow(PIMEINFOEX pImeInfoEx, BOOL fFlag);
DWORD
NTAPI
diff --git a/win32ss/user/ntuser/ime.c b/win32ss/user/ntuser/ime.c
index dd5ccbc874a..cac0d64b662 100644
--- a/win32ss/user/ntuser/ime.c
+++ b/win32ss/user/ntuser/ime.c
@@ -133,11 +133,9 @@ NtUserSetImeInfoEx(
}
DWORD APIENTRY
-NtUserSetImeOwnerWindow(DWORD Unknown0,
- DWORD Unknown1)
+NtUserSetImeOwnerWindow(PIMEINFOEX pImeInfoEx, BOOL fFlag)
{
STUB
-
return 0;
}
diff --git a/win32ss/user/ntuser/metric.c b/win32ss/user/ntuser/metric.c
index df7138b999b..cae66b0807d 100644
--- a/win32ss/user/ntuser/metric.c
+++ b/win32ss/user/ntuser/metric.c
@@ -169,7 +169,7 @@ InitMetrics(VOID)
piSysMet[90] = 0;
#endif
- gpsi->dwSRVIFlags |= SRVINFO_METRICS;
+ gpsi->dwSRVIFlags |= SRVINFO_CICERO_ENABLED;
Setup = TRUE;
return TRUE;
diff --git a/win32ss/user/ntuser/ntstubs.c b/win32ss/user/ntuser/ntstubs.c
index 9ee6b4f8a39..c770f883e25 100644
--- a/win32ss/user/ntuser/ntstubs.c
+++ b/win32ss/user/ntuser/ntstubs.c
@@ -419,22 +419,20 @@ NtUserYieldTask(VOID)
return 0;
}
-DWORD
+HIMC
APIENTRY
-NtUserCreateInputContext(
- DWORD dwUnknown1)
+NtUserCreateInputContext(PCLIENTIMC pClientImc)
{
STUB;
- return 0;
+ return NULL;
}
-DWORD
+BOOL
APIENTRY
-NtUserDestroyInputContext(
- DWORD dwUnknown1)
+NtUserDestroyInputContext(HIMC hIMC)
{
STUB;
- return 0;
+ return FALSE;
}
DWORD