ReactOS 0.4.15-dev-7953-g1f49173
ime.c File Reference
#include <win32k.h>
#include <jpnvkeys.h>
Include dependency graph for ime.c:

Go to the source code of this file.

Classes

struct  tagIMEHOTKEY
 

Macros

#define INVALID_THREAD_ID   ((ULONG)-1)
 
#define INVALID_HOTKEY   ((UINT)-1)
 
#define MOD_KEYS   (MOD_CONTROL | MOD_SHIFT | MOD_ALT | MOD_WIN)
 
#define MOD_LEFT_RIGHT   (MOD_LEFT | MOD_RIGHT)
 
#define LANGID_CHINESE_SIMPLIFIED   MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
 
#define LANGID_JAPANESE   MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT)
 
#define LANGID_KOREAN   MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN)
 
#define LANGID_CHINESE_TRADITIONAL   MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
 
#define LANGID_NEUTRAL   MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)
 
#define IME_CHOTKEY   0x10
 
#define IME_JHOTKEY   0x30
 
#define IME_KHOTKEY   0x50
 
#define IME_THOTKEY   0x70
 
#define IME_XHOTKEY   0x90
 

Typedefs

typedef struct tagIMEHOTKEY IMEHOTKEY
 
typedef struct tagIMEHOTKEYPIMEHOTKEY
 

Functions

 DBG_DEFAULT_CHANNEL (UserMisc)
 
DWORD FASTCALL IntGetImeCompatFlags (PTHREADINFO pti)
 
UINT FASTCALL IntGetImeHotKeyLanguageScore (HKL hKL, LANGID HotKeyLangId)
 
HKL FASTCALL IntGetActiveKeyboardLayout (VOID)
 
static LANGID FASTCALL IntGetImeHotKeyLangId (DWORD dwHotKeyId)
 
static VOID FASTCALL IntAddImeHotKey (PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
 
static PIMEHOTKEY FASTCALL IntGetImeHotKeyById (PIMEHOTKEY pList, DWORD dwHotKeyId)
 
static PIMEHOTKEY APIENTRY IntGetImeHotKeyByKeyAndLang (PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey, LANGID TargetLangId)
 
static VOID FASTCALL IntDeleteImeHotKey (PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
 
PIMEHOTKEY IntGetImeHotKeyByKey (PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey)
 
PIMEHOTKEY IntCheckImeHotKey (PUSER_MESSAGE_QUEUE MessageQueue, UINT uVirtualKey, LPARAM lParam)
 
VOID FASTCALL IntFreeImeHotKeys (VOID)
 
static BOOL APIENTRY IntSetImeHotKey (DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DWORD dwAction)
 
BOOL NTAPI NtUserGetImeHotKey (DWORD dwHotKeyId, LPUINT lpuModifiers, LPUINT lpuVirtualKey, LPHKL lphKL)
 
BOOL NTAPI NtUserSetImeHotKey (DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DWORD dwAction)
 
DWORD NTAPI NtUserCheckImeHotKey (UINT uVirtualKey, LPARAM lParam)
 
PWND FASTCALL IntGetTopLevelWindow (PWND pwnd)
 
HIMC FASTCALL IntAssociateInputContext (PWND pWnd, PIMC pImc)
 
DWORD NTAPI NtUserSetThreadLayoutHandles (HKL hNewKL, HKL hOldKL)
 
DWORD FASTCALL UserBuildHimcList (PTHREADINFO pti, DWORD dwCount, HIMC *phList)
 
UINT FASTCALL IntImmProcessKey (PUSER_MESSAGE_QUEUE MessageQueue, PWND pWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
NTSTATUS NTAPI NtUserBuildHimcList (DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD pdwCount)
 
static VOID FASTCALL UserSetImeConversionKeyState (PTHREADINFO pti, DWORD dwConversion)
 
DWORD NTAPI NtUserNotifyIMEStatus (HWND hwnd, BOOL fOpen, DWORD dwConversion)
 
BOOL NTAPI NtUserDisableThreadIme (DWORD dwThreadID)
 
DWORD NTAPI NtUserGetAppImeLevel (HWND hWnd)
 
BOOL FASTCALL UserGetImeInfoEx (_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pInfoEx, _In_ IMEINFOEXCLASS SearchType)
 
BOOL NTAPI NtUserGetImeInfoEx (PIMEINFOEX pImeInfoEx, IMEINFOEXCLASS SearchType)
 
BOOL NTAPI NtUserSetAppImeLevel (HWND hWnd, DWORD dwLevel)
 
BOOL FASTCALL UserSetImeInfoEx (_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pImeInfoEx)
 
BOOL NTAPI NtUserSetImeInfoEx (PIMEINFOEX pImeInfoEx)
 
VOID FASTCALL IntImeSetFutureOwner (PWND pImeWnd, PWND pwndOwner)
 
PWND FASTCALL IntGetLastTopMostWindowNoIME (PWND pImeWnd)
 
VOID FASTCALL IntImeSetTopMost (PWND pImeWnd, BOOL bTopMost, PWND pwndInsertBefore)
 
VOID FASTCALL IntImeCheckTopmost (PWND pImeWnd)
 
BOOL NTAPI NtUserSetImeOwnerWindow (HWND hImeWnd, HWND hwndFocus)
 
PVOID AllocInputContextObject (PDESKTOP pDesk, PTHREADINFO pti, SIZE_T Size, PVOID *HandleOwner)
 
VOID UserFreeInputContext (PVOID Object)
 
BOOLEAN UserDestroyInputContext (PVOID Object)
 
BOOL IntDestroyInputContext (PIMC pIMC)
 
BOOL NTAPI NtUserDestroyInputContext (HIMC hIMC)
 
PIMC FASTCALL UserCreateInputContext (ULONG_PTR dwClientImcData)
 
HIMC NTAPI NtUserCreateInputContext (ULONG_PTR dwClientImcData)
 
DWORD FASTCALL IntAssociateInputContextEx (PWND pWnd, PIMC pIMC, DWORD dwFlags)
 
DWORD NTAPI NtUserAssociateInputContext (HWND hWnd, HIMC hIMC, DWORD dwFlags)
 
BOOL FASTCALL UserUpdateInputContext (PIMC pIMC, DWORD dwType, DWORD_PTR dwValue)
 
BOOL NTAPI NtUserUpdateInputContext (HIMC hIMC, DWORD dwType, DWORD_PTR dwValue)
 
DWORD_PTR NTAPI NtUserQueryInputContext (HIMC hIMC, DWORD dwType)
 
BOOL IntFindNonImeRelatedWndOfSameThread (PWND pwndParent, PWND pwndTarget)
 
BOOL FASTCALL IntWantImeWindow (PWND pwndTarget)
 
PWND FASTCALL co_IntCreateDefaultImeWindow (PWND pwndTarget, HINSTANCE hInst)
 
BOOL FASTCALL IntImeCanDestroyDefIMEforChild (PWND pImeWnd, PWND pwndTarget)
 
BOOL FASTCALL IntImeCanDestroyDefIME (PWND pImeWnd, PWND pwndTarget)
 
BOOL FASTCALL IntCheckImeShowStatus (PWND pwndIme, PTHREADINFO pti)
 
LRESULT FASTCALL IntSendMessageToUI (PTHREADINFO ptiIME, PIMEUI pimeui, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
VOID FASTCALL IntSendOpenStatusNotify (PTHREADINFO ptiIME, PIMEUI pimeui, PWND pWnd, BOOL bOpen)
 
VOID FASTCALL IntNotifyImeShowStatus (PWND pImeWnd)
 
BOOL FASTCALL IntBroadcastImeShowStatusChange (PWND pImeWnd, BOOL bShow)
 
VOID FASTCALL IntCheckImeShowStatusInThread (PWND pImeWnd)
 

Variables

HIMC ghIMC = NULL
 
BOOL gfImeOpen = (BOOL)-1
 
DWORD gdwImeConversion = (DWORD)-1
 
BOOL gfIMEShowStatus = (BOOL)-1
 
PIMEHOTKEY gpImeHotKeyList = NULL
 
LCID glcidSystem = 0
 

Macro Definition Documentation

◆ IME_CHOTKEY

#define IME_CHOTKEY   0x10

◆ IME_JHOTKEY

#define IME_JHOTKEY   0x30

◆ IME_KHOTKEY

#define IME_KHOTKEY   0x50

◆ IME_THOTKEY

#define IME_THOTKEY   0x70

◆ IME_XHOTKEY

#define IME_XHOTKEY   0x90

◆ INVALID_HOTKEY

#define INVALID_HOTKEY   ((UINT)-1)

Definition at line 16 of file ime.c.

◆ INVALID_THREAD_ID

#define INVALID_THREAD_ID   ((ULONG)-1)

Definition at line 15 of file ime.c.

◆ LANGID_CHINESE_SIMPLIFIED

#define LANGID_CHINESE_SIMPLIFIED   MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)

Definition at line 20 of file ime.c.

◆ LANGID_CHINESE_TRADITIONAL

#define LANGID_CHINESE_TRADITIONAL   MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)

Definition at line 23 of file ime.c.

◆ LANGID_JAPANESE

Definition at line 21 of file ime.c.

◆ LANGID_KOREAN

Definition at line 22 of file ime.c.

◆ LANGID_NEUTRAL

Definition at line 24 of file ime.c.

◆ MOD_KEYS

#define MOD_KEYS   (MOD_CONTROL | MOD_SHIFT | MOD_ALT | MOD_WIN)

Definition at line 17 of file ime.c.

◆ MOD_LEFT_RIGHT

#define MOD_LEFT_RIGHT   (MOD_LEFT | MOD_RIGHT)

Definition at line 18 of file ime.c.

Typedef Documentation

◆ IMEHOTKEY

◆ PIMEHOTKEY

Function Documentation

◆ AllocInputContextObject()

PVOID AllocInputContextObject ( PDESKTOP  pDesk,
PTHREADINFO  pti,
SIZE_T  Size,
PVOID HandleOwner 
)

Definition at line 1428 of file ime.c.

1432{
1433 PTHRDESKHEAD ObjHead;
1434
1435 ASSERT(Size > sizeof(*ObjHead));
1436 ASSERT(pti != NULL);
1437
1438 if (!pDesk)
1439 pDesk = pti->rpdesk;
1440
1441 ObjHead = DesktopHeapAlloc(pDesk, Size);
1442 if (!ObjHead)
1443 return NULL;
1444
1445 RtlZeroMemory(ObjHead, Size);
1446
1447 ObjHead->pSelf = ObjHead;
1448 ObjHead->rpdesk = pDesk;
1449 ObjHead->pti = pti;
1451 *HandleOwner = pti;
1452 pti->ppi->UserHandleCount++;
1453
1454 return ObjHead;
1455}
#define NULL
Definition: types.h:112
#define ASSERT(a)
Definition: mode.c:44
struct _DESKTOP * rpdesk
Definition: ntuser.h:194
PVOID pSelf
Definition: ntuser.h:195
PPROCESSINFO ppi
Definition: win32.h:88
struct _DESKTOP * rpdesk
Definition: win32.h:92
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define IntReferenceThreadInfo(pti)
Definition: win32.h:166
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:204

◆ co_IntCreateDefaultImeWindow()

PWND FASTCALL co_IntCreateDefaultImeWindow ( PWND  pwndTarget,
HINSTANCE  hInst 
)

Definition at line 1957 of file ime.c.

1958{
1959 LARGE_UNICODE_STRING WindowName;
1960 UNICODE_STRING ClassName;
1961 PWND pImeWnd;
1962 PIMEUI pimeui;
1963 CREATESTRUCTW Cs;
1966 HANDLE pid = PsGetThreadProcessId(pti->pEThread);
1967
1968 if (!(pti->spDefaultImc) && pid == gpidLogon)
1970
1971 if (!(pti->spDefaultImc) || IS_WND_IMELIKE(pwndTarget) || !(pti->rpdesk->pheapDesktop))
1972 return NULL;
1973
1974 if (IS_WND_CHILD(pwndTarget) && !(pwndTarget->style & WS_VISIBLE) &&
1975 pwndTarget->spwndParent->head.pti->ppi != pti->ppi)
1976 {
1977 return NULL;
1978 }
1979
1980 RtlInitLargeUnicodeString(&WindowName, L"Default IME", 0);
1981
1983 ClassName.Length = 0;
1984 ClassName.MaximumLength = 0;
1985
1986 UserRefObjectCo(pwndTarget, &Ref);
1987
1988 RtlZeroMemory(&Cs, sizeof(Cs));
1989 Cs.style = WS_POPUP | WS_DISABLED;
1990 Cs.hInstance = hInst;
1991 Cs.hwndParent = UserHMGetHandle(pwndTarget);
1992 Cs.lpszName = WindowName.Buffer;
1993 Cs.lpszClass = ClassName.Buffer;
1994
1995 // NOTE: LARGE_UNICODE_STRING is compatible to LARGE_STRING.
1996 pImeWnd = co_UserCreateWindowEx(&Cs, &ClassName, (PLARGE_STRING)&WindowName, NULL, WINVER);
1997 if (pImeWnd)
1998 {
1999 pimeui = ((PIMEWND)pImeWnd)->pimeui;
2000 _SEH2_TRY
2001 {
2002 ProbeForWrite(pimeui, sizeof(IMEUI), 1);
2003 pimeui->fDefault = TRUE;
2004 if (IS_WND_CHILD(pwndTarget) && pwndTarget->spwndParent->head.pti != pti)
2005 pimeui->fChildThreadDef = TRUE;
2006 }
2008 {
2009 ERR("%p\n", pimeui);
2010 }
2011 _SEH2_END;
2012 }
2013
2014 UserDerefObjectCo(pwndTarget);
2015 return pImeWnd;
2016}
#define ERR(fmt,...)
Definition: debug.h:110
#define TRUE
Definition: types.h:120
PSERVERINFO gpsi
Definition: imm.c:18
HINSTANCE hInst
Definition: dxdiag.c:13
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ICLS_IME
Definition: ntuser.h:927
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
struct _IMEWND * PIMEWND
VOID NTAPI RtlInitLargeUnicodeString(IN OUT PLARGE_UNICODE_STRING, IN PCWSTR, IN INT)
Definition: rtlstr.c:42
WCHAR * PWCH
Definition: ntbasedef.h:410
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
HANDLE NTAPI PsGetThreadProcessId(IN PETHREAD Thread)
Definition: thread.c:745
#define L(x)
Definition: ntvdm.h:50
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:40
static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
Definition: object.h:27
#define WS_POPUP
Definition: pedump.c:616
#define WS_VISIBLE
Definition: pedump.c:620
#define WS_DISABLED
Definition: pedump.c:621
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
HANDLE gpidLogon
Definition: simplecall.c:15
struct tagIMC * spDefaultImc
Definition: win32.h:132
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: object.h:4
Definition: ntuser.h:694
DWORD style
Definition: ntuser.h:706
struct _WND * spwndParent
Definition: ntuser.h:713
LPCWSTR lpszClass
Definition: winuser.h:2965
LPCWSTR lpszName
Definition: winuser.h:2964
HINSTANCE hInstance
Definition: winuser.h:2956
UINT fDefault
Definition: ntuser.h:1225
UINT fChildThreadDef
Definition: ntuser.h:1226
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1060
#define WINVER
Definition: targetver.h:11
uint32_t ULONG_PTR
Definition: typedefs.h:65
PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData)
Definition: ime.c:1558
PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW *Cs, PUNICODE_STRING ClassName, PLARGE_STRING WindowName, PVOID acbiBuffer, DWORD dwVer)
Definition: window.c:2173
#define IS_WND_IMELIKE(pWnd)
Definition: window.h:114
#define IS_WND_CHILD(pWnd)
Definition: window.h:108
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837

Referenced by co_UserCreateWindowEx().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserMisc  )

◆ IntAddImeHotKey()

static VOID FASTCALL IntAddImeHotKey ( PIMEHOTKEY ppList,
PIMEHOTKEY  pHotKey 
)
static

Definition at line 125 of file ime.c.

126{
127 PIMEHOTKEY pNode;
128
129 if (!*ppList)
130 {
131 *ppList = pHotKey;
132 return;
133 }
134
135 for (pNode = *ppList; pNode; pNode = pNode->pNext)
136 {
137 if (!pNode->pNext)
138 {
139 pNode->pNext = pHotKey;
140 return;
141 }
142 }
143}
struct tagIMEHOTKEY * pNext
Definition: ime.c:33

Referenced by IntSetImeHotKey().

◆ IntAssociateInputContext()

HIMC FASTCALL IntAssociateInputContext ( PWND  pWnd,
PIMC  pImc 
)

Definition at line 499 of file ime.c.

500{
501 HIMC hOldImc = pWnd->hImc;
502 pWnd->hImc = (pImc ? UserHMGetHandle(pImc) : NULL);
503 return hOldImc;
504}
DWORD HIMC
Definition: dimm.idl:75
HIMC hImc
Definition: ntuser.h:740

Referenced by IntAssociateInputContextEx(), and IntDestroyInputContext().

◆ IntAssociateInputContextEx()

DWORD FASTCALL IntAssociateInputContextEx ( PWND  pWnd,
PIMC  pIMC,
DWORD  dwFlags 
)

Definition at line 1636 of file ime.c.

1637{
1638 DWORD ret = 0;
1639 PWINDOWLIST pwl;
1640 BOOL bIgnoreNullImc = (dwFlags & IACE_IGNORENOCONTEXT);
1641 PTHREADINFO pti = pWnd->head.pti;
1642 PWND pwndTarget, pwndFocus = pti->MessageQueue->spwndFocus;
1643 HWND *phwnd;
1644 HIMC hIMC;
1645
1646 if (dwFlags & IACE_DEFAULT)
1647 {
1648 pIMC = pti->spDefaultImc;
1649 }
1650 else
1651 {
1652 if (pIMC && pti != pIMC->head.pti)
1653 return 2;
1654 }
1655
1656 if (pWnd->head.pti->ppi != GetW32ThreadInfo()->ppi ||
1657 (pIMC && pIMC->head.rpdesk != pWnd->head.rpdesk))
1658 {
1659 return 2;
1660 }
1661
1662 if ((dwFlags & IACE_CHILDREN) && pWnd->spwndChild)
1663 {
1664 pwl = IntBuildHwndList(pWnd->spwndChild, IACE_CHILDREN | IACE_LIST, pti);
1665 if (pwl)
1666 {
1667 for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1668 {
1669 pwndTarget = ValidateHwndNoErr(*phwnd);
1670 if (!pwndTarget)
1671 continue;
1672
1673 hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1674 if (pwndTarget->hImc == hIMC || (bIgnoreNullImc && !pwndTarget->hImc))
1675 continue;
1676
1677 IntAssociateInputContext(pwndTarget, pIMC);
1678 if (pwndTarget == pwndFocus)
1679 ret = 1;
1680 }
1681
1682 IntFreeHwndList(pwl);
1683 }
1684 }
1685
1686 if (!bIgnoreNullImc || pWnd->hImc)
1687 {
1688 hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1689 if (pWnd->hImc != hIMC)
1690 {
1691 IntAssociateInputContext(pWnd, pIMC);
1692 if (pWnd == pwndFocus)
1693 ret = 1;
1694 }
1695 }
1696
1697 return ret;
1698}
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:84
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:805
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
THRDESKHEAD head
Definition: ntuser.h:695
struct _WND * spwndChild
Definition: ntuser.h:714
THRDESKHEAD head
Definition: ntuser.h:200
HWND ahwnd[ANYSIZE_ARRAY]
Definition: window.h:91
int ret
HIMC FASTCALL IntAssociateInputContext(PWND pWnd, PIMC pImc)
Definition: ime.c:499
VOID FASTCALL IntFreeHwndList(PWINDOWLIST pwlTarget)
Definition: window.c:1470
PWINDOWLIST FASTCALL IntBuildHwndList(PWND pwnd, DWORD dwFlags, PTHREADINFO pti)
Definition: window.c:1424
#define HWND_TERMINATOR
Definition: window.h:83
#define IACE_LIST
Definition: window.h:106
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176

Referenced by NtUserAssociateInputContext().

◆ IntBroadcastImeShowStatusChange()

BOOL FASTCALL IntBroadcastImeShowStatusChange ( PWND  pImeWnd,
BOOL  bShow 
)

Definition at line 2386 of file ime.c.

2387{
2388 if (gfIMEShowStatus == bShow || !IS_IMM_MODE())
2389 return TRUE;
2390
2391 gfIMEShowStatus = bShow;
2392 IntNotifyImeShowStatus(pImeWnd);
2393 return TRUE;
2394}
#define IS_IMM_MODE()
Definition: ntuser.h:1209
BOOL gfIMEShowStatus
Definition: ime.c:29
VOID FASTCALL IntNotifyImeShowStatus(PWND pImeWnd)
Definition: ime.c:2326

Referenced by NtUserCallHwndParamLock().

◆ IntCheckImeHotKey()

PIMEHOTKEY IntCheckImeHotKey ( PUSER_MESSAGE_QUEUE  MessageQueue,
UINT  uVirtualKey,
LPARAM  lParam 
)

Definition at line 275 of file ime.c.

276{
277 PIMEHOTKEY pHotKey;
278 UINT uModifiers;
279 BOOL bKeyUp = (lParam & 0x80000000);
280 const BYTE *KeyState = MessageQueue->afKeyState;
281 static UINT s_uKeyUpVKey = 0;
282
283 if (bKeyUp)
284 {
285 if (s_uKeyUpVKey != uVirtualKey)
286 {
287 s_uKeyUpVKey = 0;
288 return NULL;
289 }
290
291 s_uKeyUpVKey = 0;
292 }
293
294 uModifiers = 0;
295 if (IS_KEY_DOWN(KeyState, VK_LSHIFT)) uModifiers |= (MOD_SHIFT | MOD_LEFT);
296 if (IS_KEY_DOWN(KeyState, VK_RSHIFT)) uModifiers |= (MOD_SHIFT | MOD_RIGHT);
297 if (IS_KEY_DOWN(KeyState, VK_LCONTROL)) uModifiers |= (MOD_CONTROL | MOD_LEFT);
298 if (IS_KEY_DOWN(KeyState, VK_RCONTROL)) uModifiers |= (MOD_CONTROL | MOD_RIGHT);
299 if (IS_KEY_DOWN(KeyState, VK_LMENU)) uModifiers |= (MOD_ALT | MOD_LEFT);
300 if (IS_KEY_DOWN(KeyState, VK_RMENU)) uModifiers |= (MOD_ALT | MOD_RIGHT);
301
303 (uModifiers & MOD_KEYS),
304 (uModifiers & MOD_LEFT_RIGHT),
305 uVirtualKey);
306 if (pHotKey)
307 {
308 if (bKeyUp)
309 {
310 if (pHotKey->uModifiers & MOD_ON_KEYUP)
311 return pHotKey;
312 }
313 else
314 {
315 if (pHotKey->uModifiers & MOD_ON_KEYUP)
316 s_uKeyUpVKey = uVirtualKey;
317 else
318 return pHotKey;
319 }
320 }
321
322 return NULL;
323}
LPARAM lParam
Definition: combotst.c:139
#define MOD_LEFT
Definition: imm.h:188
#define MOD_ON_KEYUP
Definition: imm.h:191
#define MOD_ALT
Definition: imm.h:184
#define MOD_SHIFT
Definition: imm.h:186
#define MOD_CONTROL
Definition: imm.h:185
#define MOD_RIGHT
Definition: imm.h:189
unsigned int UINT
Definition: ndis.h:50
BYTE afKeyState[256 *2/8]
Definition: msgqueue.h:84
UINT uModifiers
Definition: ime.c:36
PIMEHOTKEY IntGetImeHotKeyByKey(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey)
Definition: ime.c:214
#define MOD_LEFT_RIGHT
Definition: ime.c:18
#define MOD_KEYS
Definition: ime.c:17
PIMEHOTKEY gpImeHotKeyList
Definition: ime.c:40
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:101
#define VK_RSHIFT
Definition: winuser.h:2283
#define VK_LSHIFT
Definition: winuser.h:2282
#define VK_LCONTROL
Definition: winuser.h:2284
#define VK_RCONTROL
Definition: winuser.h:2285
#define VK_RMENU
Definition: winuser.h:2287
#define VK_LMENU
Definition: winuser.h:2286
unsigned char BYTE
Definition: xxhash.c:193

Referenced by IntImmProcessKey(), and NtUserCheckImeHotKey().

◆ IntCheckImeShowStatus()

BOOL FASTCALL IntCheckImeShowStatus ( PWND  pwndIme,
PTHREADINFO  pti 
)

Definition at line 2129 of file ime.c.

2130{
2131 BOOL ret = FALSE, bDifferent;
2132 PWINDOWLIST pwl;
2133 HWND *phwnd;
2134 PWND pwndNode, pwndIMC;
2135 PTHREADINFO ptiCurrent = GetW32ThreadInfo();
2136 PIMEUI pimeui;
2137 IMEUI SafeImeUI;
2138
2139 if (pwndIme->state2 & WNDS2_INDESTROY)
2140 return FALSE;
2141
2142 // Build a window list
2143 pwl = IntBuildHwndList(pwndIme->spwndParent->spwndChild, IACE_LIST, NULL);
2144 if (!pwl)
2145 return FALSE;
2146
2147 ret = TRUE;
2148 for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
2149 {
2150 pwndNode = ValidateHwndNoErr(*phwnd);
2151
2152 if (!pwndNode || pwndIme == pwndNode)
2153 continue;
2154
2155 if (pwndNode->pcls->atomClassName != gpsi->atomSysClass[ICLS_IME] ||
2156 (pwndNode->state2 & WNDS2_INDESTROY))
2157 {
2158 continue;
2159 }
2160
2161 pimeui = ((PIMEWND)pwndNode)->pimeui;
2162 if (!pimeui || pimeui == (PIMEUI)-1)
2163 continue;
2164
2165 if (pti && pti != pwndNode->head.pti)
2166 continue;
2167
2168 // Attach to the process if necessary
2169 bDifferent = FALSE;
2170 if (pwndNode->head.pti->ppi != ptiCurrent->ppi)
2171 {
2172 KeAttachProcess(&(pwndNode->head.pti->ppi->peProcess->Pcb));
2173 bDifferent = TRUE;
2174 }
2175
2176 // Get pwndIMC and update IMEUI.fShowStatus flag
2177 _SEH2_TRY
2178 {
2179 ProbeForWrite(pimeui, sizeof(IMEUI), 1);
2180 SafeImeUI = *pimeui;
2181 if (SafeImeUI.fShowStatus)
2182 {
2183 pwndIMC = ValidateHwndNoErr(pimeui->hwndIMC);
2184 if (pwndIMC)
2185 pimeui->fShowStatus = FALSE;
2186 }
2187 else
2188 {
2189 pwndIMC = NULL;
2190 }
2191 }
2193 {
2194 ERR("%p\n", pimeui);
2195 pwndIMC = NULL;
2196 }
2197 _SEH2_END;
2198
2199 // Detach from the process if necessary
2200 if (bDifferent)
2202
2203 // Send the WM_IME_NOTIFY message
2204 if (pwndIMC && pwndIMC->head.pti && !(pwndIMC->head.pti->TIF_flags & TIF_INCLEANUP))
2205 {
2206 HWND hImeWnd;
2208
2209 UserRefObjectCo(pwndIMC, &Ref);
2210
2211 hImeWnd = UserHMGetHandle(pwndIMC);
2213
2214 UserDerefObjectCo(pwndIMC);
2215 }
2216 }
2217
2218 // Free the window list
2219 IntFreeHwndList(pwl);
2220 return ret;
2221}
#define FALSE
Definition: types.h:117
#define IMN_CLOSESTATUSWINDOW
Definition: imm.h:372
#define TIF_INCLEANUP
Definition: ntuser.h:263
#define WNDS2_INDESTROY
Definition: ntuser.h:648
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
RTL_ATOM atomClassName
Definition: ntuser.h:568
PCLS pcls
Definition: ntuser.h:720
DWORD state2
Definition: ntuser.h:702
HWND hwndIMC
Definition: ntuser.h:1217
UINT fShowStatus
Definition: ntuser.h:1222
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1445
#define WM_IME_NOTIFY
Definition: winuser.h:1830

Referenced by IntCheckImeShowStatusInThread(), and IntNotifyImeShowStatus().

◆ IntCheckImeShowStatusInThread()

VOID FASTCALL IntCheckImeShowStatusInThread ( PWND  pImeWnd)

Definition at line 2397 of file ime.c.

2398{
2399 if (IS_IMM_MODE() && !(pImeWnd->state2 & WNDS2_INDESTROY))
2400 IntCheckImeShowStatus(pImeWnd, pImeWnd->head.pti);
2401}
BOOL FASTCALL IntCheckImeShowStatus(PWND pwndIme, PTHREADINFO pti)
Definition: ime.c:2129

Referenced by NtUserCallHwndLock().

◆ IntDeleteImeHotKey()

static VOID FASTCALL IntDeleteImeHotKey ( PIMEHOTKEY ppList,
PIMEHOTKEY  pHotKey 
)
static

Definition at line 190 of file ime.c.

191{
192 PIMEHOTKEY pNode;
193
194 if (*ppList == pHotKey)
195 {
196 *ppList = pHotKey->pNext;
198 return;
199 }
200
201 for (pNode = *ppList; pNode; pNode = pNode->pNext)
202 {
203 if (pNode->pNext == pHotKey)
204 {
205 pNode->pNext = pHotKey->pNext;
207 return;
208 }
209 }
210}
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define USERTAG_IMEHOTKEY
Definition: tags.h:239

Referenced by IntSetImeHotKey().

◆ IntDestroyInputContext()

BOOL IntDestroyInputContext ( PIMC  pIMC)

Definition at line 1496 of file ime.c.

1497{
1498 HIMC hIMC = UserHMGetHandle(pIMC);
1499 PTHREADINFO pti = pIMC->head.pti;
1500 PWND pwndChild;
1501 PWINDOWLIST pwl;
1502 HWND *phwnd;
1503 PWND pWnd;
1504
1505 if (pti != gptiCurrent)
1506 {
1508 return FALSE;
1509 }
1510
1511 if (pIMC == pti->spDefaultImc)
1512 {
1514 return FALSE;
1515 }
1516
1517 pwndChild = pti->rpdesk->pDeskInfo->spwnd->spwndChild;
1518 pwl = IntBuildHwndList(pwndChild, IACE_LIST | IACE_CHILDREN, pti);
1519 if (pwl)
1520 {
1521 for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1522 {
1524 if (pWnd && pWnd->hImc == hIMC)
1526 }
1527
1528 IntFreeHwndList(pwl);
1529 }
1530
1532 return TRUE;
1533}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
@ TYPE_WINDOW
Definition: ntuser.h:41
@ TYPE_INPUTCONTEXT
Definition: ntuser.h:57
PTHREADINFO gptiCurrent
Definition: ntuser.c:15
BOOL FASTCALL UserDeleteObject(HANDLE h, HANDLE_TYPE type)
Definition: object.c:717
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13
PVOID UserGetObjectNoErr(PUSER_HANDLE_TABLE ht, HANDLE handle, HANDLE_TYPE type)
Definition: object.c:481
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22

Referenced by NtUserDestroyInputContext().

◆ IntFindNonImeRelatedWndOfSameThread()

BOOL IntFindNonImeRelatedWndOfSameThread ( PWND  pwndParent,
PWND  pwndTarget 
)

Definition at line 1841 of file ime.c.

1842{
1843 PWND pwnd, pwndOwner, pwndNode;
1844 PTHREADINFO ptiTarget = pwndTarget->head.pti;
1845
1846 // For all the children of pwndParent, ...
1847 for (pwnd = pwndParent->spwndChild; pwnd; pwnd = pwnd->spwndNext)
1848 {
1849 if (pwnd == pwndTarget || pwnd->head.pti != ptiTarget || IS_WND_MENU(pwnd))
1850 continue;
1851
1852 if (!IS_WND_CHILD(pwnd))
1853 {
1854 // Check if any IME-like owner.
1855 BOOL bFound1 = FALSE;
1856 for (pwndOwner = pwnd; pwndOwner; pwndOwner = pwndOwner->spwndOwner)
1857 {
1858 if (IS_WND_IMELIKE(pwndOwner))
1859 {
1860 bFound1 = TRUE;
1861 break;
1862 }
1863 }
1864 if (bFound1)
1865 continue; // Skip if any IME-like owner.
1866 }
1867
1868 pwndNode = pwnd;
1869
1870 if (IS_WND_CHILD(pwndNode))
1871 {
1872 // Check if any same-thread IME-like ancestor.
1873 BOOL bFound2 = FALSE;
1874 for (; IS_WND_CHILD(pwndNode); pwndNode = pwndNode->spwndParent)
1875 {
1876 if (pwndNode->head.pti != ptiTarget)
1877 break;
1878
1879 if (IS_WND_IMELIKE(pwndNode))
1880 {
1881 bFound2 = TRUE;
1882 break;
1883 }
1884 }
1885 if (bFound2)
1886 continue;
1887 // Now, pwndNode is non-child or non-same-thread window.
1888 }
1889
1890 if (!IS_WND_CHILD(pwndNode)) // pwndNode is non-child
1891 {
1892 // Check if any same-thread IME-like owner.
1893 BOOL bFound3 = FALSE;
1894 for (; pwndNode; pwndNode = pwndNode->spwndOwner)
1895 {
1896 if (pwndNode->head.pti != ptiTarget)
1897 break;
1898
1899 if (IS_WND_IMELIKE(pwndNode))
1900 {
1901 bFound3 = TRUE;
1902 break;
1903 }
1904 }
1905 if (bFound3)
1906 continue;
1907 }
1908
1909 return TRUE;
1910 }
1911
1912 return FALSE;
1913}
struct _WND * spwndOwner
Definition: ntuser.h:715
struct _WND * spwndNext
Definition: ntuser.h:711
#define IS_WND_MENU(pWnd)
Definition: window.h:109

Referenced by IntImeCanDestroyDefIMEforChild().

◆ IntFreeImeHotKeys()

VOID FASTCALL IntFreeImeHotKeys ( VOID  )

Definition at line 326 of file ime.c.

327{
328 PIMEHOTKEY pNode, pNext;
329 for (pNode = gpImeHotKeyList; pNode; pNode = pNext)
330 {
331 pNext = pNode->pNext;
333 }
335}

Referenced by IntSetImeHotKey(), and UserProcessDestroy().

◆ IntGetActiveKeyboardLayout()

HKL FASTCALL IntGetActiveKeyboardLayout ( VOID  )

Definition at line 84 of file ime.c.

85{
86 PTHREADINFO pti;
87
89 {
90 pti = gpqForeground->spwndActive->head.pti;
91 if (pti && pti->KeyboardLayout)
92 return pti->KeyboardLayout->hkl;
93 }
94
95 return UserGetKeyboardLayout(0);
96}
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:13
struct tagKL * KeyboardLayout
Definition: win32.h:90
HKL FASTCALL UserGetKeyboardLayout(DWORD dwThreadId)
Definition: kbdlayout.c:1032

Referenced by IntGetImeHotKeyByKey().

◆ IntGetImeCompatFlags()

DWORD FASTCALL IntGetImeCompatFlags ( PTHREADINFO  pti)

Definition at line 44 of file ime.c.

45{
46 if (!pti)
48
49 return pti->ppi->dwImeCompatFlags;
50}
DWORD dwImeCompatFlags
Definition: win32.h:276

Referenced by IntImmProcessKey().

◆ IntGetImeHotKeyById()

static PIMEHOTKEY FASTCALL IntGetImeHotKeyById ( PIMEHOTKEY  pList,
DWORD  dwHotKeyId 
)
static

Definition at line 146 of file ime.c.

147{
148 PIMEHOTKEY pNode;
149 for (pNode = pList; pNode; pNode = pNode->pNext)
150 {
151 if (pNode->dwHotKeyId == dwHotKeyId)
152 return pNode;
153 }
154 return NULL;
155}
FxChildList * pList
DWORD dwHotKeyId
Definition: ime.c:34

Referenced by IntSetImeHotKey(), and NtUserGetImeHotKey().

◆ IntGetImeHotKeyByKey()

PIMEHOTKEY IntGetImeHotKeyByKey ( PIMEHOTKEY  pList,
UINT  uModKeys,
UINT  uLeftRight,
UINT  uVirtualKey 
)

Definition at line 214 of file ime.c.

215{
216 PIMEHOTKEY pNode, ret = NULL;
218 LANGID LangId;
220 BOOL fKorean = (PRIMARYLANGID(LOWORD(hKL)) == LANG_KOREAN);
221 UINT nScore, nMaxScore = 0;
222
223 for (pNode = pList; pNode; pNode = pNode->pNext)
224 {
225 if (pNode->uVirtualKey != uVirtualKey)
226 continue;
227
228 if ((pNode->uModifiers & MOD_IGNORE_ALL_MODIFIER))
229 {
230 ;
231 }
232 else if ((pNode->uModifiers & MOD_KEYS) != uModKeys)
233 {
234 continue;
235 }
236 else if ((pNode->uModifiers & uLeftRight) ||
237 (pNode->uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
238 {
239 ;
240 }
241 else
242 {
243 continue;
244 }
245
246 LangId = IntGetImeHotKeyLangId(pNode->dwHotKeyId);
247 nScore = IntGetImeHotKeyLanguageScore(hKL, LangId);
248 if (nScore >= 3)
249 return pNode;
250
251 if (fKorean)
252 continue;
253
254 if (nScore == 0)
255 {
258 {
259 if (LOWORD(pti->hklPrev) == LangId)
260 return pNode;
261 }
262 }
263
264 if (nMaxScore < nScore)
265 {
266 nMaxScore = nScore;
267 ret = pNode;
268 }
269 }
270
271 return ret;
272}
#define IME_THOTKEY_IME_NONIME_TOGGLE
Definition: imm.h:207
#define MOD_IGNORE_ALL_MODIFIER
Definition: imm.h:192
#define IME_CHOTKEY_IME_NONIME_TOGGLE
Definition: imm.h:195
USHORT LANGID
Definition: mui.h:9
UINT_PTR HKL
Definition: msctf.idl:143
#define LOWORD(l)
Definition: pedump.c:82
#define PRIMARYLANGID(l)
Definition: nls.h:16
#define LANG_KOREAN
Definition: nls.h:84
HKL hklPrev
Definition: win32.h:133
UINT uVirtualKey
Definition: ime.c:35
static LANGID FASTCALL IntGetImeHotKeyLangId(DWORD dwHotKeyId)
Definition: ime.c:99
UINT FASTCALL IntGetImeHotKeyLanguageScore(HKL hKL, LANGID HotKeyLangId)
Definition: ime.c:53
HKL FASTCALL IntGetActiveKeyboardLayout(VOID)
Definition: ime.c:84

Referenced by IntCheckImeHotKey().

◆ IntGetImeHotKeyByKeyAndLang()

static PIMEHOTKEY APIENTRY IntGetImeHotKeyByKeyAndLang ( PIMEHOTKEY  pList,
UINT  uModKeys,
UINT  uLeftRight,
UINT  uVirtualKey,
LANGID  TargetLangId 
)
static

Definition at line 159 of file ime.c.

161{
162 PIMEHOTKEY pNode;
164 UINT uModifiers;
165
166 for (pNode = pList; pNode; pNode = pNode->pNext)
167 {
168 if (pNode->uVirtualKey != uVirtualKey)
169 continue;
170
172 if (LangID != TargetLangId && LangID != 0)
173 continue;
174
175 uModifiers = pNode->uModifiers;
176 if (uModifiers & MOD_IGNORE_ALL_MODIFIER)
177 return pNode;
178
179 if ((uModifiers & MOD_KEYS) != uModKeys)
180 continue;
181
182 if ((uModifiers & uLeftRight) || (uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
183 return pNode;
184 }
185
186 return NULL;
187}
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1083

Referenced by IntSetImeHotKey().

◆ IntGetImeHotKeyLangId()

static LANGID FASTCALL IntGetImeHotKeyLangId ( DWORD  dwHotKeyId)
static

Definition at line 99 of file ime.c.

100{
101#define IME_CHOTKEY 0x10
102#define IME_JHOTKEY 0x30
103#define IME_KHOTKEY 0x50
104#define IME_THOTKEY 0x70
105#define IME_XHOTKEY 0x90
106 static const LANGID s_array[] =
107 {
108 /* 0x00 */ (WORD)-1,
109 /* 0x10 */ LANGID_CHINESE_SIMPLIFIED,
110 /* 0x20 */ LANGID_CHINESE_SIMPLIFIED,
111 /* 0x30 */ LANGID_JAPANESE,
112 /* 0x40 */ LANGID_JAPANESE,
113 /* 0x50 */ LANGID_KOREAN,
114 /* 0x60 */ LANGID_KOREAN,
117 };
118
119 if (IME_CHOTKEY <= dwHotKeyId && dwHotKeyId < IME_XHOTKEY)
120 return s_array[(dwHotKeyId & 0xF0) >> 4];
121 return LANGID_NEUTRAL;
122}
unsigned short WORD
Definition: ntddk_ex.h:93
#define LANGID_KOREAN
Definition: ime.c:22
#define LANGID_JAPANESE
Definition: ime.c:21
#define LANGID_CHINESE_SIMPLIFIED
Definition: ime.c:20
#define IME_XHOTKEY
#define LANGID_NEUTRAL
Definition: ime.c:24
#define IME_CHOTKEY
#define LANGID_CHINESE_TRADITIONAL
Definition: ime.c:23

Referenced by IntGetImeHotKeyByKey(), IntGetImeHotKeyByKeyAndLang(), and IntSetImeHotKey().

◆ IntGetImeHotKeyLanguageScore()

UINT FASTCALL IntGetImeHotKeyLanguageScore ( HKL  hKL,
LANGID  HotKeyLangId 
)

Definition at line 53 of file ime.c.

54{
55 LCID lcid;
56
57 if (HotKeyLangId == LANGID_NEUTRAL || HotKeyLangId == LOWORD(hKL))
58 return 3;
59
61 {
62 lcid = NtCurrentTeb()->CurrentLocale;
63 }
65 {
66 ERR("%p\n", NtCurrentTeb());
68 }
70
71 if (HotKeyLangId == LANGIDFROMLCID(lcid))
72 return 2;
73
74 if (glcidSystem == 0)
76
77 if (HotKeyLangId == LANGIDFROMLCID(glcidSystem))
78 return 1;
79
80 return 0;
81}
#define NtCurrentTeb
NTSYSAPI NTSTATUS NTAPI ZwQueryDefaultLocale(_In_ BOOLEAN UserProfile, _Out_ PLCID DefaultLocaleId)
#define SORT_DEFAULT
#define MAKELCID(lgid, srtid)
#define LANGIDFROMLCID(l)
Definition: nls.h:18
DWORD LCID
Definition: nls.h:13
LCID glcidSystem
Definition: ime.c:41

Referenced by IntGetImeHotKeyByKey().

◆ IntGetLastTopMostWindowNoIME()

PWND FASTCALL IntGetLastTopMostWindowNoIME ( PWND  pImeWnd)

Definition at line 1219 of file ime.c.

1220{
1221 PWND pwndNode, pwndOwner, pwndLastTopMost = NULL;
1222 BOOL bFound;
1223
1224 pwndNode = UserGetDesktopWindow();
1225 if (!pwndNode || pwndNode->spwndChild == NULL)
1226 return NULL;
1227
1228 for (pwndNode = pwndNode->spwndChild;
1229 pwndNode && (pwndNode->ExStyle & WS_EX_TOPMOST);
1230 pwndNode = pwndNode->spwndNext)
1231 {
1232 bFound = FALSE;
1233
1234 if (IS_WND_IMELIKE(pwndNode)) // An IME-like window
1235 {
1236 // Search the IME window from owners
1237 for (pwndOwner = pwndNode; pwndOwner; pwndOwner = pwndOwner->spwndOwner)
1238 {
1239 if (pImeWnd == pwndOwner)
1240 {
1241 bFound = TRUE;
1242 break;
1243 }
1244 }
1245 }
1246
1247 if (!bFound)
1248 pwndLastTopMost = pwndNode;
1249 }
1250
1251 return pwndLastTopMost;
1252}
#define WS_EX_TOPMOST
Definition: pedump.c:647
DWORD ExStyle
Definition: ntuser.h:704
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1386

Referenced by IntImeSetTopMost().

◆ IntGetTopLevelWindow()

PWND FASTCALL IntGetTopLevelWindow ( PWND  pwnd)

Definition at line 487 of file ime.c.

488{
489 if (!pwnd)
490 return NULL;
491
492 while (pwnd->style & WS_CHILD)
493 pwnd = pwnd->spwndParent;
494
495 return pwnd;
496}
#define WS_CHILD
Definition: pedump.c:617

Referenced by NtUserSetImeOwnerWindow().

◆ IntImeCanDestroyDefIME()

BOOL FASTCALL IntImeCanDestroyDefIME ( PWND  pImeWnd,
PWND  pwndTarget 
)

Definition at line 2065 of file ime.c.

2066{
2067 PWND pwndNode;
2068 PIMEUI pimeui;
2069 IMEUI SafeImeUI;
2070
2071 pimeui = ((PIMEWND)pImeWnd)->pimeui;
2072 if (!pimeui || (LONG_PTR)pimeui == (LONG_PTR)-1)
2073 return FALSE;
2074
2075 // Check IMEUI.fDestroy
2076 _SEH2_TRY
2077 {
2078 ProbeForRead(pimeui, sizeof(IMEUI), 1);
2079 SafeImeUI = *pimeui;
2080 if (SafeImeUI.fDestroy)
2081 return FALSE;
2082 }
2084 {
2085 ERR("%p\n", pimeui);
2086 }
2087 _SEH2_END;
2088
2089 // Any ancestor of pImeWnd is pwndTarget?
2090 if (pImeWnd->spwndOwner)
2091 {
2092 for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndOwner)
2093 {
2094 if (pwndNode == pwndTarget)
2095 break;
2096 }
2097
2098 if (!pwndNode)
2099 return FALSE;
2100 }
2101
2102 // Any ancestor of pwndTarget is IME-like?
2103 for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndOwner)
2104 {
2105 if (IS_WND_IMELIKE(pwndNode))
2106 return FALSE;
2107 }
2108
2109 // Adjust the ordering and top-mode status
2110 IntImeSetFutureOwner(pImeWnd, pwndTarget);
2111 for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndNext)
2112 {
2113 if (pwndNode == pImeWnd)
2114 break;
2115 }
2116 if (pwndNode == pImeWnd)
2117 IntImeCheckTopmost(pImeWnd);
2118
2119 // Is the owner of pImeWnd NULL or pwndTarget?
2120 if (pImeWnd->spwndOwner && pwndTarget != pImeWnd->spwndOwner)
2121 return FALSE;
2122
2123 WndSetOwner(pImeWnd, NULL);
2124 return TRUE;
2125}
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
UINT fDestroy
Definition: ntuser.h:1224
#define LONG_PTR
Definition: treelist.c:79
VOID FASTCALL IntImeSetFutureOwner(PWND pImeWnd, PWND pwndOwner)
Definition: ime.c:1162
VOID FASTCALL IntImeCheckTopmost(PWND pImeWnd)
Definition: ime.c:1346
static VOID WndSetOwner(_Inout_ PWND pwnd, _In_opt_ PWND pwndOwner)
Definition: window.h:150

Referenced by co_UserDestroyWindow().

◆ IntImeCanDestroyDefIMEforChild()

BOOL FASTCALL IntImeCanDestroyDefIMEforChild ( PWND  pImeWnd,
PWND  pwndTarget 
)

Definition at line 2020 of file ime.c.

2021{
2022 PWND pwndNode;
2023 PIMEUI pimeui;
2024 IMEUI SafeImeUI;
2025
2026 pimeui = ((PIMEWND)pImeWnd)->pimeui;
2027 if (!pimeui || (LONG_PTR)pimeui == (LONG_PTR)-1)
2028 return FALSE;
2029
2030 // Check IMEUI.fChildThreadDef
2031 _SEH2_TRY
2032 {
2033 ProbeForRead(pimeui, sizeof(IMEUI), 1);
2034 SafeImeUI = *pimeui;
2035 if (!SafeImeUI.fChildThreadDef)
2036 return FALSE;
2037 }
2039 {
2040 ERR("%p\n", pimeui);
2041 }
2042 _SEH2_END;
2043
2044 // The parent of pwndTarget is NULL or of the same thread of pwndTarget?
2045 if (pwndTarget->spwndParent == NULL ||
2046 pwndTarget->head.pti == pwndTarget->spwndParent->head.pti)
2047 {
2048 return FALSE;
2049 }
2050
2051 for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndParent)
2052 {
2053 if (pwndNode == pwndNode->head.rpdesk->pDeskInfo->spwnd)
2054 break;
2055
2056 if (IntFindNonImeRelatedWndOfSameThread(pwndNode->spwndParent, pwndTarget))
2057 return FALSE;
2058 }
2059
2060 return TRUE;
2061}
BOOL IntFindNonImeRelatedWndOfSameThread(PWND pwndParent, PWND pwndTarget)
Definition: ime.c:1841

Referenced by co_UserDestroyWindow().

◆ IntImeCheckTopmost()

VOID FASTCALL IntImeCheckTopmost ( PWND  pImeWnd)

Definition at line 1346 of file ime.c.

1347{
1348 BOOL bTopMost;
1349 PWND pwndOwner = pImeWnd->spwndOwner, pwndInsertBefore = NULL;
1350
1351 if (!pwndOwner)
1352 return;
1353
1354 if (pImeWnd->head.pti != gptiForeground)
1355 pwndInsertBefore = pwndOwner;
1356
1357 bTopMost = !!(pwndOwner->ExStyle & WS_EX_TOPMOST);
1358 IntImeSetTopMost(pImeWnd, bTopMost, pwndInsertBefore);
1359}
PTHREADINFO gptiForeground
Definition: focus.c:15
VOID FASTCALL IntImeSetTopMost(PWND pImeWnd, BOOL bTopMost, PWND pwndInsertBefore)
Definition: ime.c:1256

Referenced by IntImeCanDestroyDefIME(), and NtUserSetImeOwnerWindow().

◆ IntImeSetFutureOwner()

VOID FASTCALL IntImeSetFutureOwner ( PWND  pImeWnd,
PWND  pwndOwner 
)

Definition at line 1162 of file ime.c.

1163{
1164 PWND pwndNode, pwndNextOwner, pwndParent, pwndSibling;
1165 PTHREADINFO pti = pImeWnd->head.pti;
1166
1167 if (!pwndOwner || (pwndOwner->style & WS_CHILD)) // invalid owner
1168 return;
1169
1170 // Get the top-level owner of the same thread
1171 for (pwndNode = pwndOwner; ; pwndNode = pwndNextOwner)
1172 {
1173 pwndNextOwner = pwndNode->spwndOwner;
1174 if (!pwndNextOwner || pwndNextOwner->head.pti != pti)
1175 break;
1176 }
1177
1178 // Don't choose the IME-like windows and the bottom-most windows unless necessary.
1179 if (IS_WND_IMELIKE(pwndNode) ||
1180 ((pwndNode->state2 & WNDS2_BOTTOMMOST) && !(pwndOwner->state2 & WNDS2_BOTTOMMOST)))
1181 {
1182 pwndNode = pwndOwner;
1183 }
1184
1185 pwndParent = pwndNode->spwndParent;
1186 if (!pwndParent || pwndOwner != pwndNode)
1187 {
1188 WndSetOwner(pImeWnd, pwndNode);
1189 return;
1190 }
1191
1192 for (pwndSibling = pwndParent->spwndChild; pwndSibling; pwndSibling = pwndSibling->spwndNext)
1193 {
1194 if (pwndNode->head.pti != pwndSibling->head.pti)
1195 continue;
1196
1197 if (IS_WND_MENU(pwndSibling) || IS_WND_IMELIKE(pwndSibling))
1198 continue;
1199
1200 if (pwndSibling->state2 & WNDS2_INDESTROY)
1201 continue;
1202
1203 if (pwndNode == pwndSibling || (pwndSibling->style & WS_CHILD))
1204 continue;
1205
1206 if (pwndSibling->spwndOwner == NULL ||
1207 pwndSibling->head.pti != pwndSibling->spwndOwner->head.pti)
1208 {
1209 pwndNode = pwndSibling;
1210 break;
1211 }
1212 }
1213
1214 WndSetOwner(pImeWnd, pwndNode);
1215}
#define WNDS2_BOTTOMMOST
Definition: ntuser.h:646

Referenced by IntImeCanDestroyDefIME(), and NtUserSetImeOwnerWindow().

◆ IntImeSetTopMost()

VOID FASTCALL IntImeSetTopMost ( PWND  pImeWnd,
BOOL  bTopMost,
PWND  pwndInsertBefore 
)

Definition at line 1256 of file ime.c.

1257{
1258 PWND pwndParent, pwndChild, pwndNode, pwndNext, pwndInsertAfter = NULL;
1259 PWND pwndInsertAfterSave;
1260
1261 pwndParent = pImeWnd->spwndParent;
1262 if (!pwndParent)
1263 return;
1264
1265 pwndChild = pwndParent->spwndChild;
1266
1267 if (!bTopMost)
1268 {
1269 // Calculate pwndInsertAfter
1270 pwndInsertAfter = IntGetLastTopMostWindowNoIME(pImeWnd);
1271 if (pwndInsertBefore)
1272 {
1273 for (pwndNode = pwndInsertAfter; pwndNode; pwndNode = pwndNode->spwndNext)
1274 {
1275 if (pwndNode->spwndNext == pwndInsertBefore)
1276 break;
1277
1278 if (pwndNode == pImeWnd)
1279 return;
1280 }
1281
1282 if (!pwndNode)
1283 return;
1284
1285 pwndInsertAfter = pwndNode;
1286 }
1287
1288 // Adjust pwndInsertAfter if the owner is bottom-most
1289 if (pImeWnd->spwndOwner->state2 & WNDS2_BOTTOMMOST)
1290 {
1291 for (pwndNode = pwndInsertAfter; pwndNode; pwndNode = pwndNode->spwndNext)
1292 {
1293 if (pwndNode == pImeWnd->spwndOwner)
1294 break;
1295
1296 if (!IS_WND_IMELIKE(pwndNode))
1297 pwndInsertAfter = pwndNode;
1298 }
1299 }
1300 }
1301
1302 pwndInsertAfterSave = pwndInsertAfter;
1303
1304 while (pwndChild)
1305 {
1306 pwndNext = pwndChild->spwndNext;
1307
1308 // If pwndChild is a good IME-like window, ...
1309 if (IS_WND_IMELIKE(pwndChild) && pwndChild != pwndInsertAfter &&
1310 pwndChild->head.pti == pImeWnd->head.pti)
1311 {
1312 // Find pImeWnd from the owners
1313 for (pwndNode = pwndChild; pwndNode; pwndNode = pwndNode->spwndOwner)
1314 {
1315 if (pwndNode != pImeWnd)
1316 continue;
1317
1318 // Adjust the ordering and the linking
1319 IntUnlinkWindow(pwndChild);
1320
1321 if (bTopMost)
1322 pwndChild->ExStyle |= WS_EX_TOPMOST;
1323 else
1324 pwndChild->ExStyle &= ~WS_EX_TOPMOST;
1325
1326 if (!pwndInsertAfter)
1327 IntLinkHwnd(pwndChild, HWND_TOP);
1328 else
1329 IntLinkHwnd(pwndChild, UserHMGetHandle(pwndInsertAfter));
1330
1331 // Update the preferred position
1332 pwndInsertAfter = pwndChild;
1333 break;
1334 }
1335 }
1336
1337 // Get the next child, with ignoring pwndInsertAfterSave
1338 pwndChild = pwndNext;
1339 if (pwndChild && pwndChild == pwndInsertAfterSave && pwndInsertAfter)
1340 pwndChild = pwndInsertAfter->spwndNext;
1341 }
1342}
PWND FASTCALL IntGetLastTopMostWindowNoIME(PWND pImeWnd)
Definition: ime.c:1219
VOID FASTCALL IntUnlinkWindow(PWND Wnd)
Definition: window.c:1354
VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
Definition: window.c:983
#define HWND_TOP
Definition: winuser.h:1207

Referenced by IntImeCheckTopmost().

◆ IntImmProcessKey()

UINT FASTCALL IntImmProcessKey ( PUSER_MESSAGE_QUEUE  MessageQueue,
PWND  pWnd,
UINT  uMsg,
WPARAM  wParam,
LPARAM  lParam 
)

Definition at line 569 of file ime.c.

571{
572 UINT uVirtualKey, ret;
573 DWORD dwHotKeyId;
574 PKL pKL;
575 PIMC pIMC;
576 PIMEHOTKEY pImeHotKey;
577 HKL hKL;
578 HWND hWnd;
579
580 ASSERT_REFS_CO(pWnd);
581
582 switch (uMsg)
583 {
584 case WM_KEYDOWN:
585 case WM_KEYUP:
586 case WM_SYSKEYDOWN:
587 case WM_SYSKEYUP:
588 break;
589
590 default:
591 return 0;
592 }
593
594 pIMC = NULL;
595 hWnd = UserHMGetHandle(pWnd);
596 pKL = pWnd->head.pti->KeyboardLayout;
597 if (!pKL)
598 return 0;
599
600 uVirtualKey = LOBYTE(wParam);
601 pImeHotKey = IntCheckImeHotKey(MessageQueue, uVirtualKey, lParam);
602 if (pImeHotKey)
603 {
604 dwHotKeyId = pImeHotKey->dwHotKeyId;
605 hKL = pImeHotKey->hKL;
606 }
607 else
608 {
609 dwHotKeyId = INVALID_HOTKEY;
610 hKL = NULL;
611 }
612
613 if (IME_HOTKEY_DSWITCH_FIRST <= dwHotKeyId && dwHotKeyId <= IME_HOTKEY_DSWITCH_LAST)
614 {
615 if (pKL->hkl != hKL)
616 {
617 UserPostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST,
618 ((pKL->dwFontSigs & gSystemFS) ? INPUTLANGCHANGE_SYSCHARSET : 0),
619 (LPARAM)hKL);
620 }
621
622 if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
623 return 0;
624
625 return IPHK_HOTKEY;
626 }
627
628 if (!IS_IMM_MODE())
629 return 0;
630
631 if (dwHotKeyId == INVALID_HOTKEY)
632 {
633 if (!pKL->piiex)
634 return 0;
635
636 if (pWnd->hImc)
638 if (!pIMC)
639 return 0;
640
641 if ((lParam & (KF_UP << 16)) &&
643 {
644 return 0;
645 }
646
647 switch (uVirtualKey)
648 {
649 case VK_DBE_CODEINPUT:
652 case VK_DBE_HIRAGANA:
653 case VK_DBE_KATAKANA:
655 case VK_DBE_NOROMAN:
656 case VK_DBE_ROMAN:
657 break;
658
659 default:
660 {
661 if (uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP)
662 {
663 if (uVirtualKey != VK_MENU && uVirtualKey != VK_F10)
664 return 0;
665 }
666
668 {
669 if (uVirtualKey == VK_MENU || (lParam & 0x20000000))
670 return 0;
671 }
672 break;
673 }
674 }
675 }
676
677 if (LOBYTE(uVirtualKey) == VK_PACKET)
678 uVirtualKey = MAKELONG(wParam, GetW32ThreadInfo()->wchInjected);
679
680 ret = co_IntImmProcessKey(hWnd, pKL->hkl, uVirtualKey, lParam, dwHotKeyId);
681
682 if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
683 ret &= ~IPHK_HOTKEY;
684
685 return ret;
686}
HWND hWnd
Definition: settings.c:17
WPARAM wParam
Definition: combotst.c:138
#define IME_HOTKEY_DSWITCH_LAST
Definition: imm.h:213
#define IME_HOTKEY_DSWITCH_FIRST
Definition: imm.h:212
#define IME_PROP_NEED_ALTKEY
Definition: immdev.h:387
#define IME_PROP_IGNORE_UPKEYS
Definition: immdev.h:386
#define LOBYTE(W)
Definition: jmemdos.c:487
#define VK_DBE_ROMAN
Definition: jpnvkeys.h:19
#define VK_DBE_HIRAGANA
Definition: jpnvkeys.h:16
#define VK_DBE_CODEINPUT
Definition: jpnvkeys.h:24
#define VK_DBE_NOROMAN
Definition: jpnvkeys.h:20
#define VK_DBE_KATAKANA
Definition: jpnvkeys.h:15
#define VK_DBE_ENTERCONFIGMODE
Definition: jpnvkeys.h:22
#define VK_DBE_ENTERWORDREGISTERMODE
Definition: jpnvkeys.h:21
#define VK_DBE_NOCODEINPUT
Definition: jpnvkeys.h:25
DWORD fdwProperty
Definition: immdev.h:22
Definition: ntuser.h:199
HKL hKL
Definition: ime.c:37
IMEINFO ImeInfo
Definition: imm32_undoc.h:30
Definition: input.h:27
PIMEINFOEX piiex
Definition: input.h:38
DWORD dwFontSigs
Definition: input.h:34
HKL hkl
Definition: input.h:32
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define IPHK_HOTKEY
Definition: undocuser.h:139
#define ASSERT_REFS_CO(_obj_)
Definition: userfuncs.h:14
DWORD APIENTRY co_IntImmProcessKey(HWND hWnd, HKL hKL, UINT vKey, LPARAM lParam, DWORD dwHotKeyID)
Definition: callback.c:1253
#define INVALID_HOTKEY
Definition: ime.c:16
PIMEHOTKEY IntCheckImeHotKey(PUSER_MESSAGE_QUEUE MessageQueue, UINT uVirtualKey, LPARAM lParam)
Definition: ime.c:275
DWORD FASTCALL IntGetImeCompatFlags(PTHREADINFO pti)
Definition: ime.c:44
DWORD gSystemFS
Definition: kbdlayout.c:24
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1345
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, HANDLE_TYPE type)
Definition: object.c:495
LONG_PTR LPARAM
Definition: windef.h:208
#define WM_KEYUP
Definition: winuser.h:1716
#define VK_F10
Definition: winuser.h:2264
#define KF_UP
Definition: winuser.h:2451
#define WM_SYSKEYUP
Definition: winuser.h:1720
#define WM_KEYDOWN
Definition: winuser.h:1715
#define WM_SYSKEYDOWN
Definition: winuser.h:1719
#define VK_MENU
Definition: winuser.h:2204

Referenced by co_IntProcessKeyboardMessage().

◆ IntNotifyImeShowStatus()

VOID FASTCALL IntNotifyImeShowStatus ( PWND  pImeWnd)

Definition at line 2326 of file ime.c.

2327{
2328 PIMEUI pimeui;
2329 PWND pWnd;
2330 PTHREADINFO pti, ptiIME;
2331 BOOL bShow, bSendNotify = FALSE;
2332 IMEUI SafeImeUI;
2333
2334 if (!IS_IMM_MODE() || (pImeWnd->state2 & WNDS2_INDESTROY))
2335 return;
2336
2338 ptiIME = pImeWnd->head.pti;
2339
2340 // Attach to the process if necessary
2341 if (pti != ptiIME)
2342 KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2343
2344 // Get an IMEUI and check whether hwndIMC is valid and update fShowStatus
2345 _SEH2_TRY
2346 {
2347 ProbeForWrite(pImeWnd, sizeof(IMEWND), 1);
2348 pimeui = ((PIMEWND)pImeWnd)->pimeui;
2349 SafeImeUI = *pimeui;
2350
2351 bShow = (gfIMEShowStatus == TRUE) && SafeImeUI.fCtrlShowStatus;
2352
2353 pWnd = ValidateHwndNoErr(SafeImeUI.hwndIMC);
2354 if (!pWnd)
2355 pWnd = ptiIME->MessageQueue->spwndFocus;
2356
2357 if (pWnd)
2358 {
2359 bSendNotify = TRUE;
2360 pimeui->fShowStatus = bShow;
2361 }
2362 }
2364 {
2365 ERR("%p, %p\n", pImeWnd, pimeui);
2366
2367 if (pti != ptiIME)
2369
2370 _SEH2_YIELD(return);
2371 }
2372 _SEH2_END;
2373
2374 // Detach from the process if necessary
2375 if (pti != ptiIME)
2377
2378 if (bSendNotify)
2379 IntSendOpenStatusNotify(ptiIME, &SafeImeUI, pWnd, bShow);
2380
2381 if (!(pImeWnd->state2 & WNDS2_INDESTROY))
2382 IntCheckImeShowStatus(pImeWnd, NULL);
2383}
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
UINT fCtrlShowStatus
Definition: ntuser.h:1227
VOID FASTCALL IntSendOpenStatusNotify(PTHREADINFO ptiIME, PIMEUI pimeui, PWND pWnd, BOOL bOpen)
Definition: ime.c:2307

Referenced by IntBroadcastImeShowStatusChange().

◆ IntSendMessageToUI()

LRESULT FASTCALL IntSendMessageToUI ( PTHREADINFO  ptiIME,
PIMEUI  pimeui,
UINT  uMsg,
WPARAM  wParam,
LPARAM  lParam 
)

Definition at line 2225 of file ime.c.

2226{
2227 PWND pwndUI;
2228 LRESULT ret = 0;
2229 IMEUI SafeImeUI;
2230 BOOL bDifferent = FALSE;
2232
2233 // Attach to the process if necessary
2234 if (ptiIME != GetW32ThreadInfo())
2235 {
2236 bDifferent = TRUE;
2237 KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2238 }
2239
2240 // Get the pwndUI
2241 _SEH2_TRY
2242 {
2243 ProbeForRead(pimeui, sizeof(IMEUI), 1);
2244 SafeImeUI = *pimeui;
2245 pwndUI = ValidateHwndNoErr(SafeImeUI.hwndUI);
2246 }
2248 {
2249 ERR("%p\n", pimeui);
2250 pwndUI = NULL;
2251 }
2252 _SEH2_END;
2253
2254 if (!pwndUI)
2255 goto Quit;
2256
2257 // Increment the recursion count of the IME procedure.
2258 // See also ImeWndProc_common of user32.
2259 _SEH2_TRY
2260 {
2261 ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1);
2263 }
2265 {
2266 ERR("%p\n", pimeui);
2267 _SEH2_YIELD(goto Quit);
2268 }
2269 _SEH2_END;
2270
2271 // Detach from the process if necessary
2272 if (bDifferent)
2274
2275 UserRefObjectCo(pwndUI, &Ref);
2277 UserDerefObjectCo(pwndUI);
2278
2279 // Attach to the process if necessary
2280 if (bDifferent)
2281 KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2282
2283 // Decrement the recursion count of the IME procedure
2284 _SEH2_TRY
2285 {
2286 ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1);
2288 }
2290 {
2291 ERR("%p\n", pimeui);
2292 _SEH2_YIELD(goto Quit);
2293 }
2294 _SEH2_END;
2295
2296Quit:
2297 // Detach from the process if necessary
2298 if (bDifferent)
2300
2301 return ret;
2302}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
long LONG
Definition: pedump.c:60
HWND hwndUI
Definition: ntuser.h:1219
LONG nCntInIMEProc
Definition: ntuser.h:1220
LONG_PTR LRESULT
Definition: windef.h:209

Referenced by IntSendOpenStatusNotify().

◆ IntSendOpenStatusNotify()

VOID FASTCALL IntSendOpenStatusNotify ( PTHREADINFO  ptiIME,
PIMEUI  pimeui,
PWND  pWnd,
BOOL  bOpen 
)

Definition at line 2307 of file ime.c.

2308{
2310 PTHREADINFO ptiWnd = pWnd->head.pti;
2312
2313 if (ptiWnd->dwExpWinVer >= WINVER_WINNT4 && pWnd->hImc)
2314 {
2315 UserRefObjectCo(pWnd, &Ref);
2317 UserDerefObjectCo(pWnd);
2318 }
2319 else
2320 {
2321 IntSendMessageToUI(ptiIME, pimeui, WM_IME_NOTIFY, wParam, 0);
2322 }
2323}
#define IMN_OPENSTATUSWINDOW
Definition: imm.h:373
DWORD dwExpWinVer
Definition: win32.h:112
LRESULT FASTCALL IntSendMessageToUI(PTHREADINFO ptiIME, PIMEUI pimeui, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: ime.c:2225
#define WINVER_WINNT4
Definition: window.h:57
UINT_PTR WPARAM
Definition: windef.h:207

Referenced by IntNotifyImeShowStatus().

◆ IntSetImeHotKey()

static BOOL APIENTRY IntSetImeHotKey ( DWORD  dwHotKeyId,
UINT  uModifiers,
UINT  uVirtualKey,
HKL  hKL,
DWORD  dwAction 
)
static

Definition at line 339 of file ime.c.

340{
341 PIMEHOTKEY pNode;
342 LANGID LangId;
343
344 switch (dwAction)
345 {
347 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); /* Find hotkey by ID */
348 if (!pNode)
349 {
350 ERR("dwHotKeyId: 0x%lX\n", dwHotKeyId);
351 return FALSE;
352 }
353
354 IntDeleteImeHotKey(&gpImeHotKeyList, pNode); /* Delete it */
355 return TRUE;
356
357 case SETIMEHOTKEY_ADD:
358 if (LOWORD(uVirtualKey) == VK_PACKET) /* In case of VK_PACKET */
359 return FALSE;
360
361 LangId = IntGetImeHotKeyLangId(dwHotKeyId);
362 if (LangId == LANGID_KOREAN)
363 return FALSE; /* Korean can't add IME hotkeys */
364
365 /* Find hotkey by key and language */
367 (uModifiers & MOD_KEYS),
368 (uModifiers & MOD_LEFT_RIGHT),
369 uVirtualKey, LangId);
370 if (pNode == NULL) /* If not found */
371 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); /* Find by ID */
372
373 if (pNode) /* Already exists */
374 {
375 pNode->uModifiers = uModifiers;
376 pNode->uVirtualKey = uVirtualKey;
377 pNode->hKL = hKL;
378 return TRUE;
379 }
380
381 /* Allocate new hotkey */
383 if (!pNode)
384 return FALSE;
385
386 /* Populate */
387 pNode->pNext = NULL;
388 pNode->dwHotKeyId = dwHotKeyId;
389 pNode->uModifiers = uModifiers;
390 pNode->uVirtualKey = uVirtualKey;
391 pNode->hKL = hKL;
392 IntAddImeHotKey(&gpImeHotKeyList, pNode); /* Add it */
393 return TRUE;
394
396 IntFreeImeHotKeys(); /* Delete all the IME hotkeys */
397 return TRUE;
398
399 default:
400 ERR("0x%lX\n", dwAction);
401 return FALSE;
402 }
403}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
@ SETIMEHOTKEY_INITIALIZE
Definition: undocuser.h:403
@ SETIMEHOTKEY_ADD
Definition: undocuser.h:402
@ SETIMEHOTKEY_DELETE
Definition: undocuser.h:401
static PIMEHOTKEY FASTCALL IntGetImeHotKeyById(PIMEHOTKEY pList, DWORD dwHotKeyId)
Definition: ime.c:146
VOID FASTCALL IntFreeImeHotKeys(VOID)
Definition: ime.c:326
static VOID FASTCALL IntDeleteImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
Definition: ime.c:190
static VOID FASTCALL IntAddImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
Definition: ime.c:125
static PIMEHOTKEY APIENTRY IntGetImeHotKeyByKeyAndLang(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey, LANGID TargetLangId)
Definition: ime.c:159

Referenced by NtUserSetImeHotKey().

◆ IntWantImeWindow()

BOOL FASTCALL IntWantImeWindow ( PWND  pwndTarget)

Definition at line 1917 of file ime.c.

1918{
1919 PDESKTOP rpdesk;
1920 PWINSTATION_OBJECT rpwinstaParent;
1921 PWND pwndNode, pwndParent = pwndTarget->spwndParent;
1922
1924 return FALSE;
1925
1926 if (IS_WND_IMELIKE(pwndTarget))
1927 return FALSE;
1928
1929 if (pwndTarget->fnid == FNID_DESKTOP || pwndTarget->fnid == FNID_MESSAGEWND)
1930 return FALSE;
1931
1932 if (pwndTarget->state & WNDS_SERVERSIDEWINDOWPROC)
1933 return FALSE;
1934
1935 rpdesk = pwndTarget->head.rpdesk;
1936 if (!rpdesk)
1937 return FALSE;
1938
1939 rpwinstaParent = rpdesk->rpwinstaParent;
1940 if (!rpwinstaParent || (rpwinstaParent->Flags & WSS_NOIO))
1941 return FALSE;
1942
1943 for (pwndNode = pwndParent; pwndNode; pwndNode = pwndNode->spwndParent)
1944 {
1945 if (rpdesk != pwndNode->head.rpdesk)
1946 break;
1947
1948 if (pwndNode == rpdesk->spwndMessage)
1949 return FALSE;
1950 }
1951
1952 return TRUE;
1953}
#define FNID_DESKTOP
Definition: ntuser.h:862
#define WNDS_SERVERSIDEWINDOWPROC
Definition: ntuser.h:623
#define TIF_DISABLEIME
Definition: ntuser.h:288
#define FNID_MESSAGEWND
Definition: ntuser.h:864
struct _WINSTATION_OBJECT * rpwinstaParent
Definition: desktop.h:11
PWND spwndMessage
Definition: desktop.h:20
FLONG TIF_flags
Definition: win32.h:95
DWORD fnid
Definition: ntuser.h:709
DWORD state
Definition: ntuser.h:701
#define WSS_NOIO
Definition: winsta.h:9

Referenced by co_UserCreateWindowEx().

◆ NtUserAssociateInputContext()

DWORD NTAPI NtUserAssociateInputContext ( HWND  hWnd,
HIMC  hIMC,
DWORD  dwFlags 
)

Definition at line 1702 of file ime.c.

1703{
1704 DWORD ret = 2;
1705 PWND pWnd;
1706 PIMC pIMC;
1707
1709
1710 if (!IS_IMM_MODE())
1711 {
1712 ERR("!IS_IMM_MODE()\n");
1713 goto Quit;
1714 }
1715
1716 pWnd = ValidateHwndNoErr(hWnd);
1717 if (!pWnd)
1718 goto Quit;
1719
1720 pIMC = (hIMC ? UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT) : NULL);
1721 ret = IntAssociateInputContextEx(pWnd, pIMC, dwFlags);
1722
1723Quit:
1724 UserLeave();
1725 return ret;
1726}
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:251
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:242
DWORD FASTCALL IntAssociateInputContextEx(PWND pWnd, PIMC pIMC, DWORD dwFlags)
Definition: ime.c:1636

Referenced by ImmAssociateContext(), and ImmAssociateContextEx().

◆ NtUserBuildHimcList()

NTSTATUS NTAPI NtUserBuildHimcList ( DWORD  dwThreadId,
DWORD  dwCount,
HIMC phList,
LPDWORD  pdwCount 
)

Definition at line 690 of file ime.c.

691{
693 DWORD dwRealCount;
694 PTHREADINFO pti;
695
697
698 if (!IS_IMM_MODE())
699 {
700 ERR("!IS_IMM_MODE()\n");
702 goto Quit;
703 }
704
705 if (dwThreadId == 0)
706 {
707 pti = gptiCurrent;
708 }
709 else if (dwThreadId == INVALID_THREAD_ID)
710 {
711 pti = NULL;
712 }
713 else
714 {
716 if (!pti || !pti->rpdesk)
717 goto Quit;
718 }
719
721 {
722 ProbeForWrite(phList, dwCount * sizeof(HIMC), 1);
723 ProbeForWrite(pdwCount, sizeof(DWORD), 1);
724 *pdwCount = dwRealCount = UserBuildHimcList(pti, dwCount, phList);
725 }
727 {
728 ERR("%p, %p\n", phList, pdwCount);
729 _SEH2_YIELD(goto Quit);
730 }
731 _SEH2_END;
732
733 if (dwCount < dwRealCount)
735 else
737
738Quit:
739 UserLeave();
740 return ret;
741}
LONG NTSTATUS
Definition: precomp.h:26
#define UlongToHandle(ul)
Definition: basetsd.h:97
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
DWORD dwThreadId
Definition: fdebug.c:31
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define INVALID_THREAD_ID
Definition: ime.c:15
DWORD FASTCALL UserBuildHimcList(PTHREADINFO pti, DWORD dwCount, HIMC *phList)
Definition: ime.c:536
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:42

Referenced by Imm32BuildHimcList().

◆ NtUserCheckImeHotKey()

DWORD NTAPI NtUserCheckImeHotKey ( UINT  uVirtualKey,
LPARAM  lParam 
)

Definition at line 467 of file ime.c.

468{
469 PIMEHOTKEY pNode;
471
473
474 if (!gpqForeground || !IS_IMM_MODE())
475 goto Quit;
476
477 pNode = IntCheckImeHotKey(gpqForeground, uVirtualKey, lParam);
478 if (pNode)
479 ret = pNode->dwHotKeyId;
480
481Quit:
482 UserLeave();
483 return ret;
484}

◆ NtUserCreateInputContext()

HIMC NTAPI NtUserCreateInputContext ( ULONG_PTR  dwClientImcData)

Definition at line 1606 of file ime.c.

1607{
1608 PIMC pIMC;
1609 HIMC ret = NULL;
1610
1612
1613 if (!IS_IMM_MODE())
1614 {
1615 ERR("!IS_IMM_MODE()\n");
1617 goto Quit;
1618 }
1619
1620 if (!dwClientImcData)
1621 {
1623 goto Quit;
1624 }
1625
1626 pIMC = UserCreateInputContext(dwClientImcData);
1627 if (pIMC)
1628 ret = UserHMGetHandle(pIMC);
1629
1630Quit:
1631 UserLeave();
1632 return ret;
1633}

Referenced by ImmCreateContext().

◆ NtUserDestroyInputContext()

BOOL NTAPI NtUserDestroyInputContext ( HIMC  hIMC)

Definition at line 1535 of file ime.c.

1536{
1537 BOOL ret = FALSE;
1538 PIMC pIMC;
1539
1541
1542 if (!IS_IMM_MODE())
1543 {
1545 goto Quit;
1546 }
1547
1549 if (pIMC)
1551
1552Quit:
1553 UserLeave();
1554 return ret;
1555}
BOOL IntDestroyInputContext(PIMC pIMC)
Definition: ime.c:1496

Referenced by Imm32DestroyInputContext().

◆ NtUserDisableThreadIme()

BOOL NTAPI NtUserDisableThreadIme ( DWORD  dwThreadID)

Definition at line 852 of file ime.c.

854{
855 PTHREADINFO pti, ptiCurrent;
856 PPROCESSINFO ppi;
857 BOOL ret = FALSE;
858
860
861 if (!IS_IMM_MODE())
862 {
863 ERR("!IS_IMM_MODE()\n");
865 goto Quit;
866 }
867
868 ptiCurrent = GetW32ThreadInfo();
869
870 if (dwThreadID == INVALID_THREAD_ID)
871 {
872 ppi = ptiCurrent->ppi;
873 ppi->W32PF_flags |= W32PF_DISABLEIME;
874
875Retry:
876 for (pti = ppi->ptiList; pti; pti = pti->ptiSibling)
877 {
879
880 if (pti->spwndDefaultIme)
881 {
883 pti->spwndDefaultIme = NULL;
884 goto Retry; /* The contents of ppi->ptiList may be changed. */
885 }
886 }
887 }
888 else
889 {
890 if (dwThreadID == 0)
891 {
892 pti = ptiCurrent;
893 }
894 else
895 {
896 pti = IntTID2PTI(UlongToHandle(dwThreadID));
897
898 /* The thread needs to reside in the current process. */
899 if (!pti || pti->ppi != ptiCurrent->ppi)
900 goto Quit;
901 }
902
904
905 if (pti->spwndDefaultIme)
906 {
908 pti->spwndDefaultIme = NULL;
909 }
910 }
911
912 ret = TRUE;
913
914Quit:
915 UserLeave();
916 return ret;
917}
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
PTHREADINFO ptiList
Definition: win32.h:256
PTHREADINFO ptiSibling
Definition: win32.h:116
struct _WND * spwndDefaultIme
Definition: win32.h:131
BOOLEAN co_UserDestroyWindow(PVOID Object)
Definition: window.c:2853
#define W32PF_DISABLEIME
Definition: win32.h:28

Referenced by ImmDisableIME().

◆ NtUserGetAppImeLevel()

DWORD NTAPI NtUserGetAppImeLevel ( HWND  hWnd)

Definition at line 921 of file ime.c.

922{
923 DWORD ret = 0;
924 PWND pWnd;
925 PTHREADINFO pti;
926
928
929 pWnd = ValidateHwndNoErr(hWnd);
930 if (!pWnd)
931 goto Quit;
932
933 if (!IS_IMM_MODE())
934 {
935 ERR("!IS_IMM_MODE()\n");
937 goto Quit;
938 }
939
941 if (pWnd->head.pti->ppi == pti->ppi)
943
944Quit:
945 UserLeave();
946 return ret;
947}
#define DWORD
Definition: nt_native.h:44
ATOM AtomImeLevel
Definition: ntuser.c:28
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:235
HANDLE FASTCALL UserGetProp(_In_ PWND Window, _In_ ATOM Atom, _In_ BOOLEAN SystemProp)
Definition: prop.c:46

Referenced by ImmGenerateMessage(), and ImmPostMessages().

◆ NtUserGetImeHotKey()

BOOL NTAPI NtUserGetImeHotKey ( DWORD  dwHotKeyId,
LPUINT  lpuModifiers,
LPUINT  lpuVirtualKey,
LPHKL  lphKL 
)

Definition at line 406 of file ime.c.

407{
408 PIMEHOTKEY pNode = NULL;
409
411
413 {
414 ProbeForWrite(lpuModifiers, sizeof(UINT), 1);
415 ProbeForWrite(lpuVirtualKey, sizeof(UINT), 1);
416 if (lphKL)
417 ProbeForWrite(lphKL, sizeof(HKL), 1);
418 }
420 {
421 ERR("%p, %p, %p\n", lpuModifiers, lpuVirtualKey, lphKL);
422 _SEH2_YIELD(goto Quit);
423 }
424 _SEH2_END;
425
426 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId);
427 if (!pNode)
428 goto Quit;
429
431 {
432 *lpuModifiers = pNode->uModifiers;
433 *lpuVirtualKey = pNode->uVirtualKey;
434 if (lphKL)
435 *lphKL = pNode->hKL;
436 }
438 {
439 ERR("%p, %p, %p, %p\n", pNode, lpuModifiers, lpuVirtualKey, lphKL);
440 pNode = NULL;
441 }
442 _SEH2_END;
443
444Quit:
445 UserLeave();
446 return !!pNode;
447}

Referenced by CliSetDefaultImeHotKeys(), and ImmGetHotKey().

◆ NtUserGetImeInfoEx()

BOOL NTAPI NtUserGetImeInfoEx ( PIMEINFOEX  pImeInfoEx,
IMEINFOEXCLASS  SearchType 
)

Definition at line 1008 of file ime.c.

1011{
1012 IMEINFOEX ImeInfoEx;
1013 BOOL ret = FALSE;
1014 PWINSTATION_OBJECT pWinSta;
1015
1017
1018 if (!IS_IMM_MODE())
1019 {
1020 ERR("!IS_IMM_MODE()\n");
1021 goto Quit;
1022 }
1023
1024 _SEH2_TRY
1025 {
1026 ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1);
1027 ImeInfoEx = *pImeInfoEx;
1028 }
1030 {
1031 ERR("%p\n", pImeInfoEx);
1032 _SEH2_YIELD(goto Quit);
1033 }
1034 _SEH2_END;
1035
1037 ret = UserGetImeInfoEx(pWinSta, &ImeInfoEx, SearchType);
1038 if (!ret)
1039 goto Quit;
1040
1041 _SEH2_TRY
1042 {
1043 ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1);
1044 *pImeInfoEx = ImeInfoEx;
1045 }
1047 {
1048 ERR("%p\n", pImeInfoEx);
1049 ret = FALSE;
1050 }
1051 _SEH2_END;
1052
1053Quit:
1054 UserLeave();
1055 return ret;
1056}
PWINSTATION_OBJECT FASTCALL IntGetProcessWindowStation(HWINSTA *phWinSta OPTIONAL)
Definition: winsta.c:400
BOOL FASTCALL UserGetImeInfoEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pInfoEx, _In_ IMEINFOEXCLASS SearchType)
Definition: ime.c:951

Referenced by ImmGetImeInfoEx().

◆ NtUserNotifyIMEStatus()

DWORD NTAPI NtUserNotifyIMEStatus ( HWND  hwnd,
BOOL  fOpen,
DWORD  dwConversion 
)

Definition at line 803 of file ime.c.

804{
805 PWND pwnd;
806 PTHREADINFO pti;
807 HKL hKL;
808
810
811 if (!IS_IMM_MODE())
812 {
813 ERR("!IS_IMM_MODE()\n");
814 goto Quit;
815 }
816
817 pwnd = ValidateHwndNoErr(hwnd);
818 if (!pwnd)
819 goto Quit;
820
821 pti = pwnd->head.pti;
822 if (!pti || !gptiForeground)
823 goto Quit;
825 goto Quit;
826 if (ghIMC == pwnd->hImc && gfImeOpen == !!fOpen && gdwImeConversion == dwConversion)
827 goto Quit;
828
829 ghIMC = pwnd->hImc;
830 if (ghIMC)
831 {
832 gfImeOpen = !!fOpen;
833 gdwImeConversion = dwConversion;
834 UserSetImeConversionKeyState(pti, (fOpen ? dwConversion : IME_CMODE_ALPHANUMERIC));
835 }
836
837 if (ISITHOOKED(WH_SHELL))
838 {
839 hKL = (pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL);
840 co_HOOK_CallHooks(WH_SHELL, HSHELL_LANGUAGE, (WPARAM)hwnd, (LPARAM)hKL);
841 }
842
843 // TODO:
844
845Quit:
846 UserLeave();
847 return 0;
848}
#define ISITHOOKED(HookId)
Definition: hook.h:6
#define IME_CMODE_ALPHANUMERIC
Definition: imm.h:336
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1102
HIMC ghIMC
Definition: ime.c:26
DWORD gdwImeConversion
Definition: ime.c:28
static VOID FASTCALL UserSetImeConversionKeyState(PTHREADINFO pti, DWORD dwConversion)
Definition: ime.c:744
BOOL gfImeOpen
Definition: ime.c:27
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WH_SHELL
Definition: winuser.h:40

Referenced by ImeWnd_OnImeNotify(), Imm32SendNotificationProc(), ImmSetActiveContext(), ImmSetConversionStatus(), and ImmSetOpenStatus().

◆ NtUserQueryInputContext()

DWORD_PTR NTAPI NtUserQueryInputContext ( HIMC  hIMC,
DWORD  dwType 
)

Definition at line 1791 of file ime.c.

1792{
1793 PIMC pIMC;
1794 PTHREADINFO ptiIMC;
1795 DWORD_PTR ret = 0;
1796
1798
1799 if (!IS_IMM_MODE())
1800 {
1801 ERR("!IS_IMM_MODE()\n");
1802 goto Quit;
1803 }
1804
1806 if (!pIMC)
1807 goto Quit;
1808
1809 ptiIMC = pIMC->head.pti;
1810
1811 switch (dwType)
1812 {
1813 case QIC_INPUTPROCESSID:
1814 ret = (DWORD_PTR)PsGetThreadProcessId(ptiIMC->pEThread);
1815 break;
1816
1817 case QIC_INPUTTHREADID:
1818 ret = (DWORD_PTR)PsGetThreadId(ptiIMC->pEThread);
1819 break;
1820
1822 if (ptiIMC->spwndDefaultIme)
1824 break;
1825
1826 case QIC_DEFAULTIMC:
1827 if (ptiIMC->spDefaultImc)
1829 break;
1830 }
1831
1832Quit:
1833 UserLeave();
1834 return ret;
1835}
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
@ QIC_DEFAULTWINDOWIME
Definition: undocuser.h:394
@ QIC_DEFAULTIMC
Definition: undocuser.h:395
@ QIC_INPUTTHREADID
Definition: undocuser.h:393
@ QIC_INPUTPROCESSID
Definition: undocuser.h:392

Referenced by CtfImmGenerateMessage(), CtfImmGetGuidAtom(), CtfImmIsGuidMapEnable(), CtfImmTIMCreateInputContext(), Imm32CheckImcProcess(), Imm32GetImeMenuItemWInterProcess(), Imm32InternalLockIMC(), Imm32IsCrossThreadAccess(), Imm32MakeIMENotify(), ImmGetImeMenuItemsAW(), and ImmSetCompositionStringAW().

◆ NtUserSetAppImeLevel()

BOOL NTAPI NtUserSetAppImeLevel ( HWND  hWnd,
DWORD  dwLevel 
)

Definition at line 1060 of file ime.c.

1061{
1062 BOOL ret = FALSE;
1063 PWND pWnd;
1064 PTHREADINFO pti;
1065
1067
1068 if (!IS_IMM_MODE())
1069 {
1070 ERR("!IS_IMM_MODE()\n");
1072 goto Quit;
1073 }
1074
1075 pWnd = ValidateHwndNoErr(hWnd);
1076 if (!pWnd)
1077 goto Quit;
1078
1080 if (pWnd->head.pti->ppi == pti->ppi)
1081 ret = UserSetProp(pWnd, AtomImeLevel, (HANDLE)(ULONG_PTR)dwLevel, TRUE);
1082
1083Quit:
1084 UserLeave();
1085 return ret;
1086}

◆ NtUserSetImeHotKey()

BOOL NTAPI NtUserSetImeHotKey ( DWORD  dwHotKeyId,
UINT  uModifiers,
UINT  uVirtualKey,
HKL  hKL,
DWORD  dwAction 
)

Definition at line 451 of file ime.c.

457{
458 BOOL ret;
460 ret = IntSetImeHotKey(dwHotKeyId, uModifiers, uVirtualKey, hKL, dwAction);
461 UserLeave();
462 return ret;
463}
static BOOL APIENTRY IntSetImeHotKey(DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DWORD dwAction)
Definition: ime.c:339

Referenced by CliImmInitializeHotKeys(), and CliImmSetHotKeyWorker().

◆ NtUserSetImeInfoEx()

BOOL NTAPI NtUserSetImeInfoEx ( PIMEINFOEX  pImeInfoEx)

Definition at line 1126 of file ime.c.

1127{
1128 BOOL ret = FALSE;
1129 IMEINFOEX ImeInfoEx;
1130 PWINSTATION_OBJECT pWinSta;
1131
1133
1134 if (!IS_IMM_MODE())
1135 {
1136 ERR("!IS_IMM_MODE()\n");
1137 goto Quit;
1138 }
1139
1140 _SEH2_TRY
1141 {
1142 ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1);
1143 ImeInfoEx = *pImeInfoEx;
1144 }
1146 {
1147 ERR("%p\n", pImeInfoEx);
1148 _SEH2_YIELD(goto Quit);
1149 }
1150 _SEH2_END;
1151
1153 ret = UserSetImeInfoEx(pWinSta, &ImeInfoEx);
1154
1155Quit:
1156 UserLeave();
1157 return ret;
1158}
BOOL FASTCALL UserSetImeInfoEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pImeInfoEx)
Definition: ime.c:1090

Referenced by Imm32LoadIME().

◆ NtUserSetImeOwnerWindow()

BOOL NTAPI NtUserSetImeOwnerWindow ( HWND  hImeWnd,
HWND  hwndFocus 
)

Definition at line 1362 of file ime.c.

1363{
1364 BOOL ret = FALSE;
1365 PWND pImeWnd, pwndFocus, pwndTopLevel, pwndNode, pwndActive;
1366 PTHREADINFO ptiIme;
1367
1369
1370 if (!IS_IMM_MODE())
1371 {
1372 ERR("!IS_IMM_MODE()\n");
1373 goto Quit;
1374 }
1375
1376 pImeWnd = ValidateHwndNoErr(hImeWnd);
1377 if (!pImeWnd || pImeWnd->fnid != FNID_IME)
1378 goto Quit;
1379
1380 pwndFocus = ValidateHwndNoErr(hwndFocus);
1381 if (pwndFocus)
1382 {
1383 if (IS_WND_IMELIKE(pwndFocus))
1384 goto Quit;
1385
1386 pwndTopLevel = IntGetTopLevelWindow(pwndFocus);
1387
1388 for (pwndNode = pwndTopLevel; pwndNode; pwndNode = pwndNode->spwndOwner)
1389 {
1390 if (pwndNode->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME])
1391 {
1392 pwndTopLevel = NULL;
1393 break;
1394 }
1395 }
1396
1397 WndSetOwner(pImeWnd, pwndTopLevel);
1398 IntImeCheckTopmost(pImeWnd);
1399 }
1400 else
1401 {
1402 ptiIme = pImeWnd->head.pti;
1403 pwndActive = ptiIme->MessageQueue->spwndActive;
1404
1405 if (!pwndActive || pwndActive != pImeWnd->spwndOwner)
1406 {
1407 if (pwndActive && ptiIme == pwndActive->head.pti && !IS_WND_IMELIKE(pwndActive))
1408 {
1409 WndSetOwner(pImeWnd, pwndActive);
1410 }
1411 else
1412 {
1413 IntImeSetFutureOwner(pImeWnd, pImeWnd->spwndOwner);
1414 }
1415
1416 IntImeCheckTopmost(pImeWnd);
1417 }
1418 }
1419
1420 ret = TRUE;
1421
1422Quit:
1423 UserLeave();
1424 return ret;
1425}
#define FNID_IME
Definition: ntuser.h:874
PWND FASTCALL IntGetTopLevelWindow(PWND pwnd)
Definition: ime.c:487

Referenced by ImeWnd_OnImeSetContext().

◆ NtUserSetThreadLayoutHandles()

DWORD NTAPI NtUserSetThreadLayoutHandles ( HKL  hNewKL,
HKL  hOldKL 
)

Definition at line 508 of file ime.c.

509{
510 PTHREADINFO pti;
511 PKL pOldKL, pNewKL;
512
514
515 pti = GetW32ThreadInfo();
516 pOldKL = pti->KeyboardLayout;
517 if (pOldKL && pOldKL->hkl != hOldKL)
518 goto Quit;
519
520 pNewKL = UserHklToKbl(hNewKL);
521 if (!pNewKL)
522 goto Quit;
523
524 if (IS_IME_HKL(hNewKL) != IS_IME_HKL(hOldKL))
525 pti->hklPrev = hOldKL;
526
527 UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pNewKL);
528 pti->pClientInfo->hKL = pNewKL->hkl;
529
530Quit:
531 UserLeave();
532 return 0;
533}
#define IS_IME_HKL(hKL)
Definition: imm32_undoc.h:20
struct _CLIENTINFO * pClientInfo
Definition: win32.h:94
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:541
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
Definition: object.c:839

Referenced by ImmActivateLayout().

◆ NtUserUpdateInputContext()

BOOL NTAPI NtUserUpdateInputContext ( HIMC  hIMC,
DWORD  dwType,
DWORD_PTR  dwValue 
)

Definition at line 1762 of file ime.c.

1766{
1767 PIMC pIMC;
1768 BOOL ret = FALSE;
1769
1771
1772 if (!IS_IMM_MODE())
1773 {
1774 ERR("!IS_IMM_MODE()\n");
1775 goto Quit;
1776 }
1777
1779 if (!pIMC)
1780 goto Quit;
1781
1782 ret = UserUpdateInputContext(pIMC, dwType, dwValue);
1783
1784Quit:
1785 UserLeave();
1786 return ret;
1787}
BOOL FASTCALL UserUpdateInputContext(PIMC pIMC, DWORD dwType, DWORD_PTR dwValue)
Definition: ime.c:1729

Referenced by ImmLockClientImc(), and User32SetImeWindowOfImc().

◆ UserBuildHimcList()

DWORD FASTCALL UserBuildHimcList ( PTHREADINFO  pti,
DWORD  dwCount,
HIMC phList 
)

Definition at line 536 of file ime.c.

537{
538 PIMC pIMC;
539 DWORD dwRealCount = 0;
540
541 if (pti)
542 {
543 for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
544 {
545 if (dwRealCount < dwCount)
546 phList[dwRealCount] = UserHMGetHandle(pIMC);
547
548 ++dwRealCount;
549 }
550 }
551 else
552 {
553 for (pti = gptiCurrent->ppi->ptiList; pti; pti = pti->ptiSibling)
554 {
555 for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
556 {
557 if (dwRealCount < dwCount)
558 phList[dwRealCount] = UserHMGetHandle(pIMC);
559
560 ++dwRealCount;
561 }
562 }
563 }
564
565 return dwRealCount;
566}
struct tagIMC * pImcNext
Definition: ntuser.h:201

Referenced by NtUserBuildHimcList().

◆ UserCreateInputContext()

PIMC FASTCALL UserCreateInputContext ( ULONG_PTR  dwClientImcData)

Definition at line 1558 of file ime.c.

1559{
1560 PIMC pIMC;
1562 PDESKTOP pdesk = pti->rpdesk;
1563
1564 if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled?
1565 {
1566 ERR("IME is disabled\n");
1567 return NULL;
1568 }
1569
1570 if (!pdesk) // No desktop?
1571 return NULL;
1572
1573 // pti->spDefaultImc should be already set if non-first time.
1574 if (dwClientImcData && !pti->spDefaultImc)
1575 return NULL;
1576
1577 // Create an input context user object.
1578 pIMC = UserCreateObject(gHandleTable, pdesk, pti, NULL, TYPE_INPUTCONTEXT, sizeof(IMC));
1579 if (!pIMC)
1580 return NULL;
1581
1582 // Release the extra reference (UserCreateObject added 2 references).
1584 ASSERT(pIMC->head.cLockObj == 1);
1585
1586 if (dwClientImcData) // Non-first time.
1587 {
1588 // Insert pIMC to the second position (non-default) of the list.
1589 pIMC->pImcNext = pti->spDefaultImc->pImcNext;
1590 pti->spDefaultImc->pImcNext = pIMC;
1591 }
1592 else // First time. It's the default IMC.
1593 {
1594 // Add the first one (default) to the list.
1595 UserAssignmentLock((PVOID*)&pti->spDefaultImc, pIMC);
1596 pIMC->pImcNext = NULL;
1597 ASSERT(pIMC->head.cLockObj == 2); // UserAssignmentUnlock'ed at ExitThreadCallback
1598 }
1599
1600 pIMC->dwClientImcData = dwClientImcData; // Set it.
1601 return pIMC;
1602}
ULONG_PTR dwClientImcData
Definition: ntuser.h:202
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:644
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, PDESKTOP pDesktop, PTHREADINFO pti, HANDLE *h, HANDLE_TYPE type, ULONG size)
Definition: object.c:568

Referenced by co_IntCreateDefaultImeWindow(), InitThreadCallback(), and NtUserCreateInputContext().

◆ UserDestroyInputContext()

BOOLEAN UserDestroyInputContext ( PVOID  Object)

Definition at line 1484 of file ime.c.

1485{
1486 PIMC pIMC = Object;
1487 if (!pIMC)
1488 return TRUE;
1489
1492 return TRUE;
1493}
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
BOOL FASTCALL UserMarkObjectDestroy(PVOID Object)
Definition: object.c:621

◆ UserFreeInputContext()

VOID UserFreeInputContext ( PVOID  Object)

Definition at line 1457 of file ime.c.

1458{
1459 PTHRDESKHEAD ObjHead = Object;
1460 PDESKTOP pDesk = ObjHead->rpdesk;
1461 PIMC pNode, pIMC = Object;
1462 PTHREADINFO pti;
1463
1464 if (!pIMC)
1465 return;
1466
1467 // Remove pIMC from the list except spDefaultImc
1468 pti = pIMC->head.pti;
1469 for (pNode = pti->spDefaultImc; pNode; pNode = pNode->pImcNext)
1470 {
1471 if (pNode->pImcNext == pIMC)
1472 {
1473 pNode->pImcNext = pIMC->pImcNext;
1474 break;
1475 }
1476 }
1477
1478 DesktopHeapFree(pDesk, Object);
1479
1480 pti->ppi->UserHandleCount--;
1482}
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:171
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:215

◆ UserGetImeInfoEx()

BOOL FASTCALL UserGetImeInfoEx ( _Inout_ PWINSTATION_OBJECT  pWinSta,
_Inout_ PIMEINFOEX  pInfoEx,
_In_ IMEINFOEXCLASS  SearchType 
)

Definition at line 951 of file ime.c.

955{
956 PKL pkl, pklHead;
957
958 if (!pWinSta || !gspklBaseLayout)
959 return FALSE;
960
961 pkl = pklHead = gspklBaseLayout;
962
963 /* Find the matching entry from the list and get info */
964 if (SearchType == ImeInfoExKeyboardLayout)
965 {
966 do
967 {
968 if (pInfoEx->hkl == pkl->hkl)
969 {
970 if (!pkl->piiex)
971 {
972 ERR("!pkl->piiex at %p\n", pkl->hkl);
973 break;
974 }
975
976 *pInfoEx = *pkl->piiex;
977 return TRUE;
978 }
979
980 pkl = pkl->pklNext;
981 } while (pkl != pklHead);
982 }
983 else if (SearchType == ImeInfoExImeFileName)
984 {
985 do
986 {
987 if (pkl->piiex &&
988 _wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile,
989 RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0)
990 {
991 *pInfoEx = *pkl->piiex;
992 return TRUE;
993 }
994
995 pkl = pkl->pklNext;
996 } while (pkl != pklHead);
997 }
998 else
999 {
1000 ERR("SearchType: %d\n", SearchType);
1001 }
1002
1003 return FALSE;
1004}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
@ ImeInfoExImeFileName
Definition: imm32_undoc.h:51
@ ImeInfoExKeyboardLayout
Definition: imm32_undoc.h:48
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
WCHAR wszImeFile[80]
Definition: imm32_undoc.h:38
struct tagKL * pklNext
Definition: input.h:29
PKL gspklBaseLayout
Definition: kbdlayout.c:22

Referenced by NtUserGetImeInfoEx().

◆ UserSetImeConversionKeyState()

static VOID FASTCALL UserSetImeConversionKeyState ( PTHREADINFO  pti,
DWORD  dwConversion 
)
static

Definition at line 744 of file ime.c.

745{
746 HKL hKL;
748 LPBYTE KeyState;
749 BOOL bAlphaNumeric, bKatakana, bHiragana, bFullShape, bRoman, bCharCode;
750
751 if (!pti->KeyboardLayout)
752 return;
753
754 hKL = pti->KeyboardLayout->hkl;
755 LangID = LOWORD(hKL);
756 KeyState = pti->MessageQueue->afKeyState;
757
758 switch (PRIMARYLANGID(LangID))
759 {
760 case LANG_JAPANESE:
761 bAlphaNumeric = !(dwConversion & IME_CMODE_NATIVE);
762 bKatakana = !bAlphaNumeric && (dwConversion & IME_CMODE_KATAKANA);
763 bHiragana = !bAlphaNumeric && !(dwConversion & IME_CMODE_KATAKANA);
764 SET_KEY_DOWN(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
765 SET_KEY_LOCKED(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
766 SET_KEY_DOWN(KeyState, VK_DBE_HIRAGANA, bHiragana);
767 SET_KEY_LOCKED(KeyState, VK_DBE_HIRAGANA, bHiragana);
768 SET_KEY_DOWN(KeyState, VK_DBE_KATAKANA, bKatakana);
769 SET_KEY_LOCKED(KeyState, VK_DBE_KATAKANA, bKatakana);
770
771 bFullShape = (dwConversion & IME_CMODE_FULLSHAPE);
772 SET_KEY_DOWN(KeyState, VK_DBE_DBCSCHAR, bFullShape);
773 SET_KEY_LOCKED(KeyState, VK_DBE_DBCSCHAR, bFullShape);
774 SET_KEY_DOWN(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
775 SET_KEY_LOCKED(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
776
777 bRoman = (dwConversion & IME_CMODE_ROMAN);
778 SET_KEY_DOWN(KeyState, VK_DBE_ROMAN, bRoman);
779 SET_KEY_LOCKED(KeyState, VK_DBE_ROMAN, bRoman);
780 SET_KEY_DOWN(KeyState, VK_DBE_NOROMAN, !bRoman);
781 SET_KEY_LOCKED(KeyState, VK_DBE_NOROMAN, !bRoman);
782
783 bCharCode = (dwConversion & IME_CMODE_CHARCODE);
784 SET_KEY_DOWN(KeyState, VK_DBE_CODEINPUT, bCharCode);
785 SET_KEY_LOCKED(KeyState, VK_DBE_CODEINPUT, bCharCode);
786 SET_KEY_DOWN(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
787 SET_KEY_LOCKED(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
788 break;
789
790 case LANG_KOREAN:
791 SET_KEY_LOCKED(KeyState, VK_HANGUL, (dwConversion & IME_CMODE_NATIVE));
792 SET_KEY_LOCKED(KeyState, VK_JUNJA, (dwConversion & IME_CMODE_FULLSHAPE));
793 SET_KEY_LOCKED(KeyState, VK_HANJA, (dwConversion & IME_CMODE_HANJACONVERT));
794 break;
795
796 default:
797 break;
798 }
799}
#define IME_CMODE_KATAKANA
Definition: imm.h:343
#define IME_CMODE_ROMAN
Definition: imm.h:346
#define IME_CMODE_NATIVE
Definition: imm.h:337
#define IME_CMODE_HANJACONVERT
Definition: imm.h:348
#define IME_CMODE_CHARCODE
Definition: imm.h:347
#define IME_CMODE_FULLSHAPE
Definition: imm.h:345
#define VK_DBE_DBCSCHAR
Definition: jpnvkeys.h:18
#define VK_DBE_ALPHANUMERIC
Definition: jpnvkeys.h:14
#define VK_DBE_SBCSCHAR
Definition: jpnvkeys.h:17
#define LANG_JAPANESE
Definition: nls.h:76
unsigned char * LPBYTE
Definition: typedefs.h:53
#define SET_KEY_DOWN(ks, vk, down)
Definition: input.h:103
#define SET_KEY_LOCKED(ks, vk, down)
Definition: input.h:106
#define VK_HANGUL
Definition: winuser.h:2209
#define VK_JUNJA
Definition: winuser.h:2210
#define VK_HANJA
Definition: winuser.h:2212

Referenced by NtUserNotifyIMEStatus().

◆ UserSetImeInfoEx()

BOOL FASTCALL UserSetImeInfoEx ( _Inout_ PWINSTATION_OBJECT  pWinSta,
_Inout_ PIMEINFOEX  pImeInfoEx 
)

Definition at line 1090 of file ime.c.

1093{
1094 PKL pklHead, pkl;
1095
1096 if (!pWinSta || !gspklBaseLayout)
1097 return FALSE;
1098
1099 pkl = pklHead = gspklBaseLayout;
1100
1101 do
1102 {
1103 if (pkl->hkl != pImeInfoEx->hkl)
1104 {
1105 pkl = pkl->pklNext;
1106 continue;
1107 }
1108
1109 if (!pkl->piiex)
1110 {
1111 ERR("!pkl->piiex at %p\n", pkl->hkl);
1112 return FALSE;
1113 }
1114
1115 if (!pkl->piiex->fLoadFlag)
1116 *pkl->piiex = *pImeInfoEx;
1117
1118 return TRUE;
1119 } while (pkl != pklHead);
1120
1121 return FALSE;
1122}

Referenced by NtUserSetImeInfoEx().

◆ UserUpdateInputContext()

BOOL FASTCALL UserUpdateInputContext ( PIMC  pIMC,
DWORD  dwType,
DWORD_PTR  dwValue 
)

Definition at line 1729 of file ime.c.

1730{
1732 PTHREADINFO ptiIMC = pIMC->head.pti;
1733
1734 if (pti->ppi != ptiIMC->ppi) // Different process?
1735 return FALSE;
1736
1737 switch (dwType)
1738 {
1739 case UIC_CLIENTIMCDATA:
1740 if (pIMC->dwClientImcData)
1741 return FALSE; // Already set
1742
1743 pIMC->dwClientImcData = dwValue;
1744 break;
1745
1746 case UIC_IMEWINDOW:
1747 if (!ValidateHwndNoErr((HWND)dwValue))
1748 return FALSE; // Invalid HWND
1749
1750 pIMC->hImeWnd = (HWND)dwValue;
1751 break;
1752
1753 default:
1754 return FALSE;
1755 }
1756
1757 return TRUE;
1758}
HANDLE HWND
Definition: compat.h:19
HWND hImeWnd
Definition: ntuser.h:203
@ UIC_CLIENTIMCDATA
Definition: undocuser.h:303
@ UIC_IMEWINDOW
Definition: undocuser.h:304

Referenced by NtUserUpdateInputContext().

Variable Documentation

◆ gdwImeConversion

DWORD gdwImeConversion = (DWORD)-1

Definition at line 28 of file ime.c.

Referenced by NtUserNotifyIMEStatus().

◆ gfImeOpen

BOOL gfImeOpen = (BOOL)-1

Definition at line 27 of file ime.c.

Referenced by NtUserNotifyIMEStatus().

◆ gfIMEShowStatus

BOOL gfIMEShowStatus = (BOOL)-1

◆ ghIMC

HIMC ghIMC = NULL

Definition at line 26 of file ime.c.

Referenced by NtUserNotifyIMEStatus().

◆ glcidSystem

LCID glcidSystem = 0

Definition at line 41 of file ime.c.

Referenced by IntGetImeHotKeyLanguageScore().

◆ gpImeHotKeyList

PIMEHOTKEY gpImeHotKeyList = NULL

Definition at line 40 of file ime.c.

Referenced by IntCheckImeHotKey(), IntFreeImeHotKeys(), IntSetImeHotKey(), and NtUserGetImeHotKey().