mirror of
https://github.com/reactos/reactos.git
synced 2025-04-05 13:11:22 +00:00
[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
This commit is contained in:
parent
c23ce9dfad
commit
692a30a84a
10 changed files with 586 additions and 296 deletions
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(new_context->IMC.cfCandForm); i++)
|
||||
new_context->IMC.cfCandForm[i].dwIndex = ~0u;
|
||||
|
||||
/* Initialize the IME Private */
|
||||
new_context->IMC.hPrivate = ImmCreateIMCC(new_context->immKbd->imeInfo.dwPrivateDataSize);
|
||||
|
||||
new_context->IMC.fdwConversion = new_context->immKbd->imeInfo.fdwConversionCaps;
|
||||
new_context->IMC.fdwSentence = new_context->immKbd->imeInfo.fdwSentenceCaps;
|
||||
|
||||
if (!new_context->immKbd->pImeSelect(new_context, TRUE))
|
||||
{
|
||||
TRACE("Selection of IME failed\n");
|
||||
IMM_DestroyContext(new_context);
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
|
||||
new_context->magic = WINE_IMC_VALID_MAGIC;
|
||||
return new_context;
|
||||
RtlInitializeCriticalSection(&pClientImc->cs);
|
||||
pClientImc->unknown = Imm32GetThreadState(THREADSTATE_UNKNOWN13);
|
||||
return hIMC;
|
||||
}
|
||||
|
||||
static BOOL IMM_DestroyContext(HIMC hIMC)
|
||||
static VOID APIENTRY Imm32CleanupContextExtra(LPINPUTCONTEXT pIC)
|
||||
{
|
||||
InputContextData *data = get_imc_data(hIMC);
|
||||
FIXME("We have to do something do here");
|
||||
}
|
||||
|
||||
TRACE("Destroying %p\n",hIMC);
|
||||
static PCLIENTIMC APIENTRY Imm32FindClientImc(HIMC hIMC)
|
||||
{
|
||||
// FIXME
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!data)
|
||||
BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
|
||||
{
|
||||
PIMEDPI pImeDpi;
|
||||
LPINPUTCONTEXT pIC;
|
||||
PCLIENTIMC pClientImc;
|
||||
|
||||
if (g_psi == NULL || !(g_psi->dwSRVIFlags & SRVINFO_IMM32) || hIMC == NULL)
|
||||
return FALSE;
|
||||
|
||||
data->immKbd->uSelected --;
|
||||
data->immKbd->pImeSelect(hIMC, FALSE);
|
||||
SendMessageW(data->IMC.hWnd, WM_IME_SELECT, FALSE, (LPARAM)data->immKbd);
|
||||
FIXME("We have do something to do here\n");
|
||||
pClientImc = Imm32FindClientImc(hIMC);
|
||||
if (!pClientImc)
|
||||
return FALSE;
|
||||
|
||||
ImmDestroyIMCC(data->IMC.hCompStr);
|
||||
ImmDestroyIMCC(data->IMC.hCandInfo);
|
||||
ImmDestroyIMCC(data->IMC.hGuideLine);
|
||||
ImmDestroyIMCC(data->IMC.hPrivate);
|
||||
ImmDestroyIMCC(data->IMC.hMsgBuf);
|
||||
if (pClientImc->hImc == NULL)
|
||||
{
|
||||
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
|
||||
ImmUnlockClientImc(pClientImc);
|
||||
if (!bKeep)
|
||||
return Imm32DestroyInputContext(hIMC);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
data->magic = 0;
|
||||
HeapFree(GetProcessHeap(),0,data);
|
||||
pIC = ImmLockIMC(hIMC);
|
||||
if (pIC == NULL)
|
||||
{
|
||||
ImmUnlockClientImc(pClientImc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FIXME("We have do something to do here\n");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ImmDestroyIMCC(pIC->hPrivate);
|
||||
ImmDestroyIMCC(pIC->hMsgBuf);
|
||||
ImmDestroyIMCC(pIC->hGuideLine);
|
||||
ImmDestroyIMCC(pIC->hCandInfo);
|
||||
ImmDestroyIMCC(pIC->hCompStr);
|
||||
|
||||
Imm32CleanupContextExtra(pIC);
|
||||
|
||||
ImmUnlockIMC(hIMC);
|
||||
|
||||
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
|
||||
ImmUnlockClientImc(pClientImc);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
22
win32ss/include/imetable.h
Normal file
22
win32ss/include/imetable.h
Normal file
|
@ -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)
|
|
@ -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
|
||||
|
|
|
@ -133,11 +133,9 @@ NtUserSetImeInfoEx(
|
|||
}
|
||||
|
||||
DWORD APIENTRY
|
||||
NtUserSetImeOwnerWindow(DWORD Unknown0,
|
||||
DWORD Unknown1)
|
||||
NtUserSetImeOwnerWindow(PIMEINFOEX pImeInfoEx, BOOL fFlag)
|
||||
{
|
||||
STUB
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ InitMetrics(VOID)
|
|||
piSysMet[90] = 0;
|
||||
#endif
|
||||
|
||||
gpsi->dwSRVIFlags |= SRVINFO_METRICS;
|
||||
gpsi->dwSRVIFlags |= SRVINFO_CICERO_ENABLED;
|
||||
Setup = TRUE;
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue