ReactOS 0.4.16-dev-2613-g9533ad7
ime.c File Reference
#include <win32k.h>
#include <ime.h>
#include <cjkcode.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 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)
 
static PIMEUI FASTCALL IntGetImeUIFromWnd (_In_ PWND pWnd)
 
static DWORD FASTCALL IntGetImeCompatFlags (_In_opt_ PTHREADINFO pti)
 
UINT FASTCALL IntGetImeHotKeyLanguageScore (_In_ HKL hKL, _In_ LANGID HotKeyLangId)
 
HKL FASTCALL IntGetActiveKeyboardLayout (VOID)
 
static LANGID FASTCALL IntGetImeHotKeyLangId (_In_ DWORD dwHotKeyId)
 
static VOID FASTCALL IntAddImeHotKey (_In_ PIMEHOTKEY *ppList, _In_ PIMEHOTKEY pHotKey)
 
static PIMEHOTKEY FASTCALL IntGetImeHotKeyById (_In_ PIMEHOTKEY pList, _In_ DWORD dwHotKeyId)
 
static PIMEHOTKEY APIENTRY IntGetImeHotKeyByKeyAndLang (_In_ PIMEHOTKEY pList, _In_ UINT uModKeys, _In_ UINT uLeftRight, _In_ UINT uVirtualKey, _In_ LANGID TargetLangId)
 
static VOID FASTCALL IntDeleteImeHotKey (_Inout_ PIMEHOTKEY *ppList, _In_ PIMEHOTKEY pHotKey)
 
static PIMEHOTKEY IntGetImeHotKeyByKey (_In_ PIMEHOTKEY pList, _In_ UINT uModKeys, _In_ UINT uLeftRight, _In_ UINT uVirtualKey)
 
static PIMEHOTKEY IntCheckImeHotKey (_In_ const USER_MESSAGE_QUEUE *MessageQueue, _In_ UINT uVirtualKey, _In_ LPARAM lParam)
 
VOID FASTCALL IntFreeImeHotKeys (VOID)
 
static BOOL APIENTRY IntSetImeHotKey (_In_ DWORD dwHotKeyId, _In_ UINT uModifiers, _In_ UINT uVirtualKey, _In_opt_ HKL hKL, _In_ DWORD dwAction)
 
BOOL NTAPI NtUserGetImeHotKey (_In_ DWORD dwHotKeyId, _Out_ PUINT lpuModifiers, _Out_ PUINT lpuVirtualKey, _Out_opt_ LPHKL lphKL)
 
BOOL NTAPI NtUserSetImeHotKey (_In_ DWORD dwHotKeyId, _In_ UINT uModifiers, _In_ UINT uVirtualKey, _In_opt_ HKL hKL, _In_ DWORD dwAction)
 
DWORD NTAPI NtUserCheckImeHotKey (_In_ UINT uVirtualKey, _In_ LPARAM lParam)
 
PWND FASTCALL IntGetTopLevelWindow (_In_ PWND pwnd)
 
static HIMC FASTCALL IntAssociateInputContext (_Inout_ PWND pWnd, _In_ PIMC pImc)
 
DWORD NTAPI NtUserSetThreadLayoutHandles (_In_ HKL hNewKL, _In_ HKL hOldKL)
 
DWORD FASTCALL UserBuildHimcList (_Inout_ PTHREADINFO pti, _In_ DWORD dwCount, _Inout_ HIMC *phList)
 
UINT FASTCALL IntImmProcessKey (_In_ PUSER_MESSAGE_QUEUE MessageQueue, _In_ PWND pWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
 
NTSTATUS NTAPI NtUserBuildHimcList (_In_ DWORD dwThreadId, _In_ DWORD dwCount, _Out_ HIMC *phList, _Out_ PDWORD pdwCount)
 
static VOID FASTCALL UserSetImeConversionKeyState (PTHREADINFO pti, DWORD dwConversion)
 
DWORD NTAPI NtUserNotifyIMEStatus (_In_ HWND hwnd, _In_ BOOL fOpen, _In_ DWORD dwConversion)
 
BOOL NTAPI NtUserDisableThreadIme (_In_ DWORD dwThreadID)
 
DWORD NTAPI NtUserGetAppImeLevel (_In_ HWND hWnd)
 
BOOL FASTCALL UserGetImeInfoEx (_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pInfoEx, _In_ IMEINFOEXCLASS SearchType)
 
BOOL NTAPI NtUserGetImeInfoEx (_Inout_ PIMEINFOEX pImeInfoEx, _In_ IMEINFOEXCLASS SearchType)
 
BOOL NTAPI NtUserSetAppImeLevel (_In_ HWND hWnd, _In_ DWORD dwLevel)
 
BOOL FASTCALL UserSetImeInfoEx (_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pImeInfoEx)
 
BOOL NTAPI NtUserSetImeInfoEx (_In_ const IMEINFOEX *pImeInfoEx)
 
VOID FASTCALL IntImeSetFutureOwner (PWND pImeWnd, PWND pwndOwner)
 
static PWND FASTCALL IntGetLastTopMostWindowNoIME (_In_ PWND pImeWnd)
 
static VOID FASTCALL IntImeSetTopMost (_In_ PWND pImeWnd, _In_ BOOL bTopMost, _In_ PWND pwndInsertBefore)
 
static VOID FASTCALL IntImeCheckTopmost (_In_ PWND pImeWnd)
 
BOOL NTAPI NtUserSetImeOwnerWindow (_In_ HWND hImeWnd, _In_opt_ HWND hwndFocus)
 
PVOID AllocInputContextObject (_In_ PDESKTOP pDesk, _In_ PTHREADINFO pti, _In_ SIZE_T Size, _Out_ PVOID *HandleOwner)
 
VOID UserFreeInputContext (_In_opt_ PVOID Object)
 
BOOLEAN UserDestroyInputContext (_In_opt_ PVOID Object)
 
static BOOL IntDestroyInputContext (_In_ PIMC pIMC)
 
BOOL NTAPI NtUserDestroyInputContext (_In_ HIMC hIMC)
 
PIMC FASTCALL UserCreateInputContext (_In_ ULONG_PTR dwClientImcData)
 
HIMC NTAPI NtUserCreateInputContext (_In_ ULONG_PTR dwClientImcData)
 
static DWORD FASTCALL IntAssociateInputContextEx (_In_ PWND pWnd, _In_ PIMC pIMC, _In_ DWORD dwFlags)
 
DWORD NTAPI NtUserAssociateInputContext (_In_ HWND hWnd, _In_opt_ HIMC hIMC, _In_ DWORD dwFlags)
 
static BOOL FASTCALL UserUpdateInputContext (_In_ PIMC pIMC, _In_ DWORD dwType, _In_ 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 (_In_ PWND pwndTarget)
 
PWND FASTCALL co_IntCreateDefaultImeWindow (_In_ PWND pwndTarget, _In_ HINSTANCE hInst)
 
BOOL FASTCALL IntImeCanDestroyDefIMEforChild (_In_ PWND pImeWnd, _In_ PWND pwndTarget)
 
BOOL FASTCALL IntImeCanDestroyDefIME (_In_ PWND pImeWnd, _In_ PWND pwndTarget)
 
BOOL FASTCALL IntCheckImeShowStatus (_In_ PWND pwndIme, _In_ PTHREADINFO pti)
 
LRESULT FASTCALL IntSendMessageToUI (_In_ PTHREADINFO ptiIME, _In_ PIMEUI pimeui, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
 
VOID FASTCALL IntSendOpenStatusNotify (PTHREADINFO ptiIME, PIMEUI pimeui, PWND pWnd, BOOL bOpen)
 
VOID FASTCALL IntNotifyImeShowStatus (_In_ PWND pImeWnd)
 
BOOL FASTCALL IntBroadcastImeShowStatusChange (_In_ PWND pImeWnd, _In_ BOOL bShow)
 
VOID FASTCALL IntCheckImeShowStatusInThread (_In_ 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 17 of file ime.c.

◆ INVALID_THREAD_ID

#define INVALID_THREAD_ID   ((ULONG)-1)

Definition at line 16 of file ime.c.

◆ MOD_KEYS

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

Definition at line 18 of file ime.c.

◆ MOD_LEFT_RIGHT

#define MOD_LEFT_RIGHT   (MOD_LEFT | MOD_RIGHT)

Definition at line 19 of file ime.c.

Typedef Documentation

◆ IMEHOTKEY

◆ PIMEHOTKEY

Function Documentation

◆ AllocInputContextObject()

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

Definition at line 1517 of file ime.c.

1522{
1523 PTHRDESKHEAD ObjHead;
1524
1525 ASSERT(Size > sizeof(*ObjHead));
1526 ASSERT(pti != NULL);
1527
1528 if (!pDesk)
1529 pDesk = pti->rpdesk;
1530
1531 ObjHead = DesktopHeapAlloc(pDesk, Size);
1532 if (!ObjHead)
1533 return NULL;
1534
1535 RtlZeroMemory(ObjHead, Size);
1536
1537 ObjHead->pSelf = ObjHead;
1538 ObjHead->rpdesk = pDesk;
1539 ObjHead->pti = pti;
1541 *HandleOwner = pti;
1542 pti->ppi->UserHandleCount++;
1543
1544 return ObjHead;
1545}
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:204
#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
#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:4539
#define IntReferenceThreadInfo(pti)
Definition: win32.h:167

◆ co_IntCreateDefaultImeWindow()

PWND FASTCALL co_IntCreateDefaultImeWindow ( _In_ PWND  pwndTarget,
_In_ HINSTANCE  hInst 
)

Definition at line 2064 of file ime.c.

2067{
2068 LARGE_UNICODE_STRING WindowName;
2069 UNICODE_STRING ClassName;
2070 PWND pImeWnd;
2071 PIMEUI pimeui;
2072 CREATESTRUCTW Cs;
2075 HANDLE pid = PsGetThreadProcessId(pti->pEThread);
2076
2077 if (!(pti->spDefaultImc) && pid == gpidLogon)
2079
2080 if (!(pti->spDefaultImc) || IS_WND_IMELIKE(pwndTarget) || !(pti->rpdesk->pheapDesktop))
2081 return NULL;
2082
2083 if (IS_WND_CHILD(pwndTarget) && !(pwndTarget->style & WS_VISIBLE) &&
2084 pwndTarget->spwndParent->head.pti->ppi != pti->ppi)
2085 {
2086 return NULL;
2087 }
2088
2089 RtlInitLargeUnicodeString(&WindowName, L"Default IME", 0);
2090
2092 ClassName.Length = 0;
2093 ClassName.MaximumLength = 0;
2094
2095 UserRefObjectCo(pwndTarget, &Ref);
2096
2097 RtlZeroMemory(&Cs, sizeof(Cs));
2098 Cs.style = WS_POPUP | WS_DISABLED;
2099 Cs.hInstance = hInst;
2100 Cs.hwndParent = UserHMGetHandle(pwndTarget);
2101 Cs.lpszName = WindowName.Buffer;
2102 Cs.lpszClass = ClassName.Buffer;
2103
2104 // NOTE: LARGE_UNICODE_STRING is compatible to LARGE_STRING.
2105 pImeWnd = co_UserCreateWindowEx(&Cs, &ClassName, (PLARGE_STRING)&WindowName, NULL, WINVER);
2106 if (pImeWnd)
2107 {
2108 pimeui = IntGetImeUIFromWnd(pImeWnd);
2109 ASSERT(pimeui);
2110 _SEH2_TRY
2111 {
2112 ProbeForWrite(pimeui, sizeof(*pimeui), 1);
2113 pimeui->fDefault = TRUE;
2114 if (IS_WND_CHILD(pwndTarget) && pwndTarget->spwndParent->head.pti != pti)
2115 pimeui->fChildThreadDef = TRUE;
2116 }
2118 {
2119 ERR("Exception in co_IntCreateDefaultImeWindow: %p\n", pimeui);
2120 }
2121 _SEH2_END;
2122 }
2123
2124 UserDerefObjectCo(pwndTarget);
2125 return pImeWnd;
2126}
#define ERR(fmt,...)
Definition: precomp.h:57
#define TRUE
Definition: types.h:120
#define L(x)
Definition: resources.c:13
#define UlongToPtr(u)
Definition: config.h:106
HINSTANCE hInst
Definition: dxdiag.c:13
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
PSERVERINFO gpsi
Definition: imm.c:18
#define ICLS_IME
Definition: ntuser.h:927
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
VOID NTAPI RtlInitLargeUnicodeString(IN OUT PLARGE_UNICODE_STRING, IN PCWSTR, IN INT)
Definition: rtlstr.c:42
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
HANDLE NTAPI PsGetThreadProcessId(IN PETHREAD Thread)
Definition: thread.c:745
PIMC FASTCALL UserCreateInputContext(_In_ ULONG_PTR dwClientImcData)
Definition: ime.c:1651
static PIMEUI FASTCALL IntGetImeUIFromWnd(_In_ PWND pWnd)
Definition: ime.c:38
static __inline VOID UserDerefObjectCo(PVOID obj)
Definition: object.h:43
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:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
HANDLE gpidLogon
Definition: simplecall.c:15
PPROCESSINFO ppi
Definition: win32.h:88
struct tagIMC * spDefaultImc
Definition: win32.h:132
struct _DESKTOP * rpdesk
Definition: win32.h:92
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: object.h:4
Definition: ntuser.h:694
LPCWSTR lpszClass
Definition: winuser.h:3073
LPCWSTR lpszName
Definition: winuser.h:3072
HINSTANCE hInstance
Definition: winuser.h:3064
UINT fDefault
Definition: ntuser.h:1230
UINT fChildThreadDef
Definition: ntuser.h:1231
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1060
#define WINVER
Definition: targetver.h:11
PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW *Cs, PUNICODE_STRING ClassName, PLARGE_STRING WindowName, PVOID acbiBuffer, DWORD dwVer)
Definition: window.c:2183
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
#define IS_WND_IMELIKE(pWnd)
Definition: window.h:114
#define IS_WND_CHILD(pWnd)
Definition: window.h:108

Referenced by co_UserCreateWindowEx().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserMisc  )

◆ IntAddImeHotKey()

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

Definition at line 129 of file ime.c.

132{
133 PIMEHOTKEY pNode;
134
135 if (!*ppList)
136 {
137 *ppList = pHotKey;
138 return;
139 }
140
141 for (pNode = *ppList; pNode; pNode = pNode->pNext)
142 {
143 if (!pNode->pNext)
144 {
145 pNode->pNext = pHotKey;
146 return;
147 }
148 }
149}
struct tagIMEHOTKEY * pNext
Definition: ime.c:28

Referenced by IntSetImeHotKey().

◆ IntAssociateInputContext()

static HIMC FASTCALL IntAssociateInputContext ( _Inout_ PWND  pWnd,
_In_ PIMC  pImc 
)
static

Definition at line 528 of file ime.c.

529{
530 HIMC hOldImc = pWnd->hImc;
531 pWnd->hImc = (pImc ? UserHMGetHandle(pImc) : NULL);
532 return hOldImc;
533}
DWORD HIMC
Definition: dimm.idl:75

Referenced by IntAssociateInputContextEx(), and IntDestroyInputContext().

◆ IntAssociateInputContextEx()

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

Definition at line 1729 of file ime.c.

1730{
1731 DWORD ret = 0;
1732 PWINDOWLIST pwl;
1733 BOOL bIgnoreNullImc = (dwFlags & IACE_IGNORENOCONTEXT);
1734 PTHREADINFO pti = pWnd->head.pti;
1735 PWND pwndTarget, pwndFocus = pti->MessageQueue->spwndFocus;
1736 HWND *phwnd;
1737 HIMC hIMC;
1738
1739 if (dwFlags & IACE_DEFAULT)
1740 {
1741 pIMC = pti->spDefaultImc;
1742 }
1743 else
1744 {
1745 if (pIMC && pti != pIMC->head.pti)
1746 return 2;
1747 }
1748
1749 if (pWnd->head.pti->ppi != GetW32ThreadInfo()->ppi ||
1750 (pIMC && pIMC->head.rpdesk != pWnd->head.rpdesk))
1751 {
1752 return 2;
1753 }
1754
1755 if ((dwFlags & IACE_CHILDREN) && pWnd->spwndChild)
1756 {
1757 pwl = IntBuildHwndList(pWnd->spwndChild, IACE_CHILDREN | IACE_LIST, pti);
1758 if (pwl)
1759 {
1760 for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1761 {
1762 pwndTarget = ValidateHwndNoErr(*phwnd);
1763 if (!pwndTarget)
1764 continue;
1765
1766 hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1767 if (pwndTarget->hImc == hIMC || (bIgnoreNullImc && !pwndTarget->hImc))
1768 continue;
1769
1770 IntAssociateInputContext(pwndTarget, pIMC);
1771 if (pwndTarget == pwndFocus)
1772 ret = 1;
1773 }
1774
1775 IntFreeHwndList(pwl);
1776 }
1777 }
1778
1779 if (!bIgnoreNullImc || pWnd->hImc)
1780 {
1781 hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1782 if (pWnd->hImc != hIMC)
1783 {
1784 IntAssociateInputContext(pWnd, pIMC);
1785 if (pWnd == pwndFocus)
1786 ret = 1;
1787 }
1788 }
1789
1790 return ret;
1791}
return ret
Definition: mutex.c:146
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:807
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
static HIMC FASTCALL IntAssociateInputContext(_Inout_ PWND pWnd, _In_ PIMC pImc)
Definition: ime.c:528
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
HIMC hImc
Definition: ntuser.h:740
HWND ahwnd[ANYSIZE_ARRAY]
Definition: window.h:91
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:97
VOID FASTCALL IntFreeHwndList(PWINDOWLIST pwlTarget)
Definition: window.c:1473
PWINDOWLIST FASTCALL IntBuildHwndList(PWND pwnd, DWORD dwFlags, PTHREADINFO pti)
Definition: window.c:1427
#define HWND_TERMINATOR
Definition: window.h:83
#define IACE_LIST
Definition: window.h:106

Referenced by NtUserAssociateInputContext().

◆ IntBroadcastImeShowStatusChange()

BOOL FASTCALL IntBroadcastImeShowStatusChange ( _In_ PWND  pImeWnd,
_In_ BOOL  bShow 
)

Definition at line 2514 of file ime.c.

2517{
2518 if (gfIMEShowStatus == bShow || !IS_IMM_MODE())
2519 return TRUE;
2520
2521 gfIMEShowStatus = bShow;
2522 IntNotifyImeShowStatus(pImeWnd);
2523 return TRUE;
2524}
#define IS_IMM_MODE()
Definition: ntuser.h:1212
VOID FASTCALL IntNotifyImeShowStatus(_In_ PWND pImeWnd)
Definition: ime.c:2447
BOOL gfIMEShowStatus
Definition: ime.c:24

Referenced by NtUserCallHwndParamLock().

◆ IntCheckImeHotKey()

static PIMEHOTKEY IntCheckImeHotKey ( _In_ const USER_MESSAGE_QUEUE MessageQueue,
_In_ UINT  uVirtualKey,
_In_ LPARAM  lParam 
)
static

Definition at line 291 of file ime.c.

295{
296 PIMEHOTKEY pHotKey;
297 UINT uModifiers;
298 BOOL bKeyUp = (lParam & 0x80000000);
299 const BYTE *KeyState = MessageQueue->afKeyState;
300 static UINT s_uKeyUpVKey = 0;
301
302 if (bKeyUp)
303 {
304 if (s_uKeyUpVKey != uVirtualKey)
305 {
306 s_uKeyUpVKey = 0;
307 return NULL;
308 }
309
310 s_uKeyUpVKey = 0;
311 }
312
313 uModifiers = 0;
314 if (IS_KEY_DOWN(KeyState, VK_LSHIFT)) uModifiers |= (MOD_SHIFT | MOD_LEFT);
315 if (IS_KEY_DOWN(KeyState, VK_RSHIFT)) uModifiers |= (MOD_SHIFT | MOD_RIGHT);
316 if (IS_KEY_DOWN(KeyState, VK_LCONTROL)) uModifiers |= (MOD_CONTROL | MOD_LEFT);
317 if (IS_KEY_DOWN(KeyState, VK_RCONTROL)) uModifiers |= (MOD_CONTROL | MOD_RIGHT);
318 if (IS_KEY_DOWN(KeyState, VK_LMENU)) uModifiers |= (MOD_ALT | MOD_LEFT);
319 if (IS_KEY_DOWN(KeyState, VK_RMENU)) uModifiers |= (MOD_ALT | MOD_RIGHT);
320
322 (uModifiers & MOD_KEYS),
323 (uModifiers & MOD_LEFT_RIGHT),
324 uVirtualKey);
325 if (pHotKey)
326 {
327 if (bKeyUp)
328 {
329 if (pHotKey->uModifiers & MOD_ON_KEYUP)
330 return pHotKey;
331 }
332 else
333 {
334 if (pHotKey->uModifiers & MOD_ON_KEYUP)
335 s_uKeyUpVKey = uVirtualKey;
336 else
337 return pHotKey;
338 }
339 }
340
341 return NULL;
342}
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
static PIMEHOTKEY IntGetImeHotKeyByKey(_In_ PIMEHOTKEY pList, _In_ UINT uModKeys, _In_ UINT uLeftRight, _In_ UINT uVirtualKey)
Definition: ime.c:226
#define MOD_LEFT_RIGHT
Definition: ime.c:19
#define MOD_KEYS
Definition: ime.c:18
PIMEHOTKEY gpImeHotKeyList
Definition: ime.c:35
UINT uModifiers
Definition: ime.c:31
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:102
#define VK_RSHIFT
Definition: winuser.h:2319
#define VK_LSHIFT
Definition: winuser.h:2318
#define VK_LCONTROL
Definition: winuser.h:2320
#define VK_RCONTROL
Definition: winuser.h:2321
#define VK_RMENU
Definition: winuser.h:2323
#define VK_LMENU
Definition: winuser.h:2322
unsigned char BYTE
Definition: xxhash.c:193

Referenced by IntImmProcessKey(), and NtUserCheckImeHotKey().

◆ IntCheckImeShowStatus()

BOOL FASTCALL IntCheckImeShowStatus ( _In_ PWND  pwndIme,
_In_ PTHREADINFO  pti 
)

Definition at line 2243 of file ime.c.

2246{
2247 BOOL ret = FALSE, bDifferent;
2248 PWINDOWLIST pwl;
2249 HWND *phwnd;
2250 PWND pwndNode, pwndIMC;
2251 PTHREADINFO ptiCurrent = GetW32ThreadInfo();
2252 PIMEUI pimeui;
2253 IMEUI SafeImeUI;
2254
2255 if (pwndIme->state2 & WNDS2_INDESTROY)
2256 return FALSE;
2257
2258 // Build a window list
2259 pwl = IntBuildHwndList(pwndIme->spwndParent->spwndChild, IACE_LIST, NULL);
2260 if (!pwl)
2261 return FALSE;
2262
2263 ret = TRUE;
2264 for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
2265 {
2266 pwndNode = ValidateHwndNoErr(*phwnd);
2267
2268 if (!pwndNode || pwndIme == pwndNode)
2269 continue;
2270
2271 if (pwndNode->pcls->atomClassName != gpsi->atomSysClass[ICLS_IME] ||
2272 (pwndNode->state2 & WNDS2_INDESTROY))
2273 {
2274 continue;
2275 }
2276
2277 pimeui = IntGetImeUIFromWnd(pwndNode);
2278 if (!pimeui)
2279 continue;
2280
2281 if (pti && pti != pwndNode->head.pti)
2282 continue;
2283
2284 // Attach to the process if necessary
2285 bDifferent = FALSE;
2286 if (pwndNode->head.pti->ppi != ptiCurrent->ppi)
2287 {
2288 KeAttachProcess(&(pwndNode->head.pti->ppi->peProcess->Pcb));
2289 bDifferent = TRUE;
2290 }
2291
2292 // Get pwndIMC and update IMEUI.fShowStatus flag
2293 _SEH2_TRY
2294 {
2295 ProbeForWrite(pimeui, sizeof(IMEUI), 1);
2296 SafeImeUI = *pimeui;
2297 if (SafeImeUI.fShowStatus)
2298 {
2299 pwndIMC = ValidateHwndNoErr(pimeui->hwndIMC);
2300 if (pwndIMC)
2301 pimeui->fShowStatus = FALSE;
2302 }
2303 else
2304 {
2305 pwndIMC = NULL;
2306 }
2307 }
2309 {
2310 ERR("Exception in IntCheckImeShowStatus: %p\n", pimeui);
2311 pwndIMC = NULL;
2312 }
2313 _SEH2_END;
2314
2315 // Detach from the process if necessary
2316 if (bDifferent)
2318
2319 // Send the WM_IME_NOTIFY message
2320 if (pwndIMC && pwndIMC->head.pti && !(pwndIMC->head.pti->TIF_flags & TIF_INCLEANUP))
2321 {
2322 HWND hImeWnd;
2324
2325 UserRefObjectCo(pwndIMC, &Ref);
2326
2327 hImeWnd = UserHMGetHandle(pwndIMC);
2329
2330 UserDerefObjectCo(pwndIMC);
2331 }
2332 }
2333
2334 // Free the window list
2335 IntFreeHwndList(pwl);
2336 return ret;
2337}
#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
THRDESKHEAD head
Definition: ntuser.h:695
DWORD state2
Definition: ntuser.h:702
HWND hwndIMC
Definition: ntuser.h:1222
UINT fShowStatus
Definition: ntuser.h:1227
LRESULT FASTCALL co_IntSendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1495
#define WM_IME_NOTIFY
Definition: winuser.h:1858

Referenced by IntCheckImeShowStatusInThread(), and IntNotifyImeShowStatus().

◆ IntCheckImeShowStatusInThread()

VOID FASTCALL IntCheckImeShowStatusInThread ( _In_ PWND  pImeWnd)

Definition at line 2527 of file ime.c.

2528{
2529 if (IS_IMM_MODE() && !(pImeWnd->state2 & WNDS2_INDESTROY))
2530 IntCheckImeShowStatus(pImeWnd, pImeWnd->head.pti);
2531}
BOOL FASTCALL IntCheckImeShowStatus(_In_ PWND pwndIme, _In_ PTHREADINFO pti)
Definition: ime.c:2243

Referenced by NtUserCallHwndLock().

◆ IntDeleteImeHotKey()

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

Definition at line 201 of file ime.c.

204{
205 PIMEHOTKEY pNode;
206
207 if (*ppList == pHotKey)
208 {
209 *ppList = pHotKey->pNext;
211 return;
212 }
213
214 for (pNode = *ppList; pNode; pNode = pNode->pNext)
215 {
216 if (pNode->pNext == pHotKey)
217 {
218 pNode->pNext = pHotKey->pNext;
220 return;
221 }
222 }
223}
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define USERTAG_IMEHOTKEY
Definition: tags.h:239

Referenced by IntSetImeHotKey().

◆ IntDestroyInputContext()

static BOOL IntDestroyInputContext ( _In_ PIMC  pIMC)
static

Definition at line 1588 of file ime.c.

1589{
1590 HIMC hIMC = UserHMGetHandle(pIMC);
1591 PTHREADINFO pti = pIMC->head.pti;
1592 PWND pwndChild;
1593 PWINDOWLIST pwl;
1594 HWND *phwnd;
1595 PWND pWnd;
1596
1597 if (pti != gptiCurrent)
1598 {
1600 return FALSE;
1601 }
1602
1603 if (pIMC == pti->spDefaultImc)
1604 {
1606 return FALSE;
1607 }
1608
1609 pwndChild = pti->rpdesk->pDeskInfo->spwnd->spwndChild;
1610 pwl = IntBuildHwndList(pwndChild, IACE_LIST | IACE_CHILDREN, pti);
1611 if (pwl)
1612 {
1613 for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1614 {
1616 if (pWnd && pWnd->hImc == hIMC)
1618 }
1619
1620 IntFreeHwndList(pwl);
1621 }
1622
1624 return TRUE;
1625}
#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 1948 of file ime.c.

1949{
1950 PWND pwnd, pwndOwner, pwndNode;
1951 PTHREADINFO ptiTarget = pwndTarget->head.pti;
1952
1953 // For all the children of pwndParent, ...
1954 for (pwnd = pwndParent->spwndChild; pwnd; pwnd = pwnd->spwndNext)
1955 {
1956 if (pwnd == pwndTarget || pwnd->head.pti != ptiTarget || IS_WND_MENU(pwnd))
1957 continue;
1958
1959 if (!IS_WND_CHILD(pwnd))
1960 {
1961 // Check if any IME-like owner.
1962 BOOL bFound1 = FALSE;
1963 for (pwndOwner = pwnd; pwndOwner; pwndOwner = pwndOwner->spwndOwner)
1964 {
1965 if (IS_WND_IMELIKE(pwndOwner))
1966 {
1967 bFound1 = TRUE;
1968 break;
1969 }
1970 }
1971 if (bFound1)
1972 continue; // Skip if any IME-like owner.
1973 }
1974
1975 pwndNode = pwnd;
1976
1977 if (IS_WND_CHILD(pwndNode))
1978 {
1979 // Check if any same-thread IME-like ancestor.
1980 BOOL bFound2 = FALSE;
1981 for (; IS_WND_CHILD(pwndNode); pwndNode = pwndNode->spwndParent)
1982 {
1983 if (pwndNode->head.pti != ptiTarget)
1984 break;
1985
1986 if (IS_WND_IMELIKE(pwndNode))
1987 {
1988 bFound2 = TRUE;
1989 break;
1990 }
1991 }
1992 if (bFound2)
1993 continue;
1994 // Now, pwndNode is non-child or non-same-thread window.
1995 }
1996
1997 if (!IS_WND_CHILD(pwndNode)) // pwndNode is non-child
1998 {
1999 // Check if any same-thread IME-like owner.
2000 BOOL bFound3 = FALSE;
2001 for (; pwndNode; pwndNode = pwndNode->spwndOwner)
2002 {
2003 if (pwndNode->head.pti != ptiTarget)
2004 break;
2005
2006 if (IS_WND_IMELIKE(pwndNode))
2007 {
2008 bFound3 = TRUE;
2009 break;
2010 }
2011 }
2012 if (bFound3)
2013 continue;
2014 }
2015
2016 return TRUE;
2017 }
2018
2019 return FALSE;
2020}
struct _WND * spwndOwner
Definition: ntuser.h:715
struct _WND * spwndChild
Definition: ntuser.h:714
struct _WND * spwndNext
Definition: ntuser.h:711
struct _WND * spwndParent
Definition: ntuser.h:713
#define IS_WND_MENU(pWnd)
Definition: window.h:109

Referenced by IntImeCanDestroyDefIMEforChild().

◆ IntFreeImeHotKeys()

VOID FASTCALL IntFreeImeHotKeys ( VOID  )

Definition at line 345 of file ime.c.

346{
347 PIMEHOTKEY pNode, pNext;
348 for (pNode = gpImeHotKeyList; pNode; pNode = pNext)
349 {
350 pNext = pNode->pNext;
352 }
354}

Referenced by IntSetImeHotKey(), and UserProcessDestroy().

◆ IntGetActiveKeyboardLayout()

HKL FASTCALL IntGetActiveKeyboardLayout ( VOID  )

Definition at line 88 of file ime.c.

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

Referenced by IntGetImeHotKeyByKey().

◆ IntGetImeCompatFlags()

static DWORD FASTCALL IntGetImeCompatFlags ( _In_opt_ PTHREADINFO  pti)
static

Definition at line 46 of file ime.c.

47{
48 if (!pti)
50
51 return pti->ppi->dwImeCompatFlags;
52}

Referenced by IntImmProcessKey().

◆ IntGetImeHotKeyById()

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

Definition at line 152 of file ime.c.

155{
156 PIMEHOTKEY pNode;
157 for (pNode = pList; pNode; pNode = pNode->pNext)
158 {
159 if (pNode->dwHotKeyId == dwHotKeyId)
160 return pNode;
161 }
162 return NULL;
163}
FxChildList * pList
DWORD dwHotKeyId
Definition: ime.c:29

Referenced by IntSetImeHotKey(), and NtUserGetImeHotKey().

◆ IntGetImeHotKeyByKey()

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

Definition at line 226 of file ime.c.

231{
232 PIMEHOTKEY pNode, ret = NULL;
234 LANGID LangId;
236 BOOL fKorean = (PRIMARYLANGID(LOWORD(hKL)) == LANG_KOREAN);
237 UINT nScore, nMaxScore = 0;
238
239 for (pNode = pList; pNode; pNode = pNode->pNext)
240 {
241 if (pNode->uVirtualKey != uVirtualKey)
242 continue;
243
244 if ((pNode->uModifiers & MOD_IGNORE_ALL_MODIFIER))
245 {
246 ;
247 }
248 else if ((pNode->uModifiers & MOD_KEYS) != uModKeys)
249 {
250 continue;
251 }
252 else if ((pNode->uModifiers & uLeftRight) ||
253 (pNode->uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
254 {
255 ;
256 }
257 else
258 {
259 continue;
260 }
261
262 LangId = IntGetImeHotKeyLangId(pNode->dwHotKeyId);
263 nScore = IntGetImeHotKeyLanguageScore(hKL, LangId);
264 if (nScore >= 3)
265 return pNode;
266
267 if (fKorean)
268 continue;
269
270 if (nScore == 0)
271 {
274 {
275 if (LOWORD(pti->hklPrev) == LangId)
276 return pNode;
277 }
278 }
279
280 if (nMaxScore < nScore)
281 {
282 nMaxScore = nScore;
283 ret = pNode;
284 }
285 }
286
287 return ret;
288}
#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:125
static LANGID FASTCALL IntGetImeHotKeyLangId(_In_ DWORD dwHotKeyId)
Definition: ime.c:103
UINT FASTCALL IntGetImeHotKeyLanguageScore(_In_ HKL hKL, _In_ LANGID HotKeyLangId)
Definition: ime.c:55
HKL FASTCALL IntGetActiveKeyboardLayout(VOID)
Definition: ime.c:88
#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:30

Referenced by IntCheckImeHotKey().

◆ IntGetImeHotKeyByKeyAndLang()

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

Definition at line 166 of file ime.c.

172{
173 PIMEHOTKEY pNode;
175 UINT uModifiers;
176
177 for (pNode = pList; pNode; pNode = pNode->pNext)
178 {
179 if (pNode->uVirtualKey != uVirtualKey)
180 continue;
181
183 if (LangID != TargetLangId && LangID != 0)
184 continue;
185
186 uModifiers = pNode->uModifiers;
187 if (uModifiers & MOD_IGNORE_ALL_MODIFIER)
188 return pNode;
189
190 if ((uModifiers & MOD_KEYS) != uModKeys)
191 continue;
192
193 if ((uModifiers & uLeftRight) || (uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
194 return pNode;
195 }
196
197 return NULL;
198}
_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 ( _In_ DWORD  dwHotKeyId)
static

Definition at line 103 of file ime.c.

104{
105#define IME_CHOTKEY 0x10
106#define IME_JHOTKEY 0x30
107#define IME_KHOTKEY 0x50
108#define IME_THOTKEY 0x70
109#define IME_XHOTKEY 0x90
110 static const LANGID s_array[] =
111 {
112 /* 0x00 */ (WORD)-1,
113 /* 0x10 */ LANGID_CHINESE_SIMPLIFIED,
114 /* 0x20 */ LANGID_CHINESE_SIMPLIFIED,
115 /* 0x30 */ LANGID_JAPANESE,
116 /* 0x40 */ LANGID_JAPANESE,
117 /* 0x50 */ LANGID_KOREAN,
118 /* 0x60 */ LANGID_KOREAN,
121 };
122
123 if (IME_CHOTKEY <= dwHotKeyId && dwHotKeyId < IME_XHOTKEY)
124 return s_array[(dwHotKeyId & 0xF0) >> 4];
125 return LANGID_NEUTRAL;
126}
#define LANGID_KOREAN
Definition: cjkcode.h:53
#define LANGID_JAPANESE
Definition: cjkcode.h:52
#define LANGID_CHINESE_SIMPLIFIED
Definition: cjkcode.h:50
#define LANGID_NEUTRAL
Definition: cjkcode.h:54
#define LANGID_CHINESE_TRADITIONAL
Definition: cjkcode.h:51
unsigned short WORD
Definition: ntddk_ex.h:93
#define IME_XHOTKEY
#define IME_CHOTKEY

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

◆ IntGetImeHotKeyLanguageScore()

UINT FASTCALL IntGetImeHotKeyLanguageScore ( _In_ HKL  hKL,
_In_ LANGID  HotKeyLangId 
)

Definition at line 55 of file ime.c.

58{
59 LCID lcid;
60
61 if (HotKeyLangId == LANGID_NEUTRAL || HotKeyLangId == LOWORD(hKL))
62 return 3;
63
65 {
66 lcid = NtCurrentTeb()->CurrentLocale;
67 }
69 {
70 ERR("Exception in IntGetImeHotKeyLanguageScore: TEB=%p, hKL=%p, HotKeyLangId=0x%04x\n", NtCurrentTeb(), hKL, HotKeyLangId);
72 }
74
75 if (HotKeyLangId == LANGIDFROMLCID(lcid))
76 return 2;
77
78 if (glcidSystem == 0)
80
81 if (HotKeyLangId == LANGIDFROMLCID(glcidSystem))
82 return 1;
83
84 return 0;
85}
LCID lcid
Definition: locale.c:5656
#define NtCurrentTeb
NTSYSAPI NTSTATUS NTAPI ZwQueryDefaultLocale(_In_ BOOLEAN UserProfile, _Out_ PLCID DefaultLocaleId)
#define SORT_DEFAULT
#define MAKELCID(lgid, srtid)
LCID glcidSystem
Definition: ime.c:36
#define LANGIDFROMLCID(l)
Definition: nls.h:18
DWORD LCID
Definition: nls.h:13

Referenced by IntGetImeHotKeyByKey().

◆ IntGetImeUIFromWnd()

static PIMEUI FASTCALL IntGetImeUIFromWnd ( _In_ PWND  pWnd)
inlinestatic

Definition at line 38 of file ime.c.

39{
40 ASSERT(pWnd->cbwndExtra >= sizeof(PIMEUI));
41 PIMEWND pImeWnd = (PIMEWND)pWnd;
42 return pImeWnd->pimeui;
43}
struct tagIMEWND * PIMEWND
PIMEUI pimeui
Definition: ntuser.h:1241

Referenced by co_IntCreateDefaultImeWindow(), IntCheckImeShowStatus(), IntImeCanDestroyDefIME(), IntImeCanDestroyDefIMEforChild(), and IntNotifyImeShowStatus().

◆ IntGetLastTopMostWindowNoIME()

static PWND FASTCALL IntGetLastTopMostWindowNoIME ( _In_ PWND  pImeWnd)
static

Definition at line 1303 of file ime.c.

1304{
1305 PWND pwndNode, pwndOwner, pwndLastTopMost = NULL;
1306 BOOL bFound;
1307
1308 pwndNode = UserGetDesktopWindow();
1309 if (!pwndNode || pwndNode->spwndChild == NULL)
1310 return NULL;
1311
1312 for (pwndNode = pwndNode->spwndChild;
1313 pwndNode && (pwndNode->ExStyle & WS_EX_TOPMOST);
1314 pwndNode = pwndNode->spwndNext)
1315 {
1316 bFound = FALSE;
1317
1318 if (IS_WND_IMELIKE(pwndNode)) // An IME-like window
1319 {
1320 // Search the IME window from owners
1321 for (pwndOwner = pwndNode; pwndOwner; pwndOwner = pwndOwner->spwndOwner)
1322 {
1323 if (pImeWnd == pwndOwner)
1324 {
1325 bFound = TRUE;
1326 break;
1327 }
1328 }
1329 }
1330
1331 if (!bFound)
1332 pwndLastTopMost = pwndNode;
1333 }
1334
1335 return pwndLastTopMost;
1336}
#define WS_EX_TOPMOST
Definition: pedump.c:647
DWORD ExStyle
Definition: ntuser.h:704
PWND FASTCALL UserGetDesktopWindow(VOID)
Definition: desktop.c:1403

Referenced by IntImeSetTopMost().

◆ IntGetTopLevelWindow()

PWND FASTCALL IntGetTopLevelWindow ( _In_ PWND  pwnd)

Definition at line 516 of file ime.c.

517{
518 if (!pwnd)
519 return NULL;
520
521 while (pwnd->style & WS_CHILD)
522 pwnd = pwnd->spwndParent;
523
524 return pwnd;
525}
#define WS_CHILD
Definition: pedump.c:617

Referenced by NtUserSetImeOwnerWindow().

◆ IntImeCanDestroyDefIME()

BOOL FASTCALL IntImeCanDestroyDefIME ( _In_ PWND  pImeWnd,
_In_ PWND  pwndTarget 
)

Definition at line 2177 of file ime.c.

2180{
2181 PWND pwndNode;
2182 PIMEUI pimeui;
2183 IMEUI SafeImeUI;
2184
2185 pimeui = IntGetImeUIFromWnd(pImeWnd);
2186 if (!pimeui)
2187 return FALSE;
2188
2189 // Check IMEUI.fDestroy
2190 _SEH2_TRY
2191 {
2192 ProbeForRead(pimeui, sizeof(IMEUI), 1);
2193 SafeImeUI = *pimeui;
2194 if (SafeImeUI.fDestroy)
2195 return FALSE;
2196 }
2198 {
2199 ERR("Exception in IntImeCanDestroyDefIME: %p\n", pimeui);
2200 }
2201 _SEH2_END;
2202
2203 // Any ancestor of pImeWnd is pwndTarget?
2204 if (pImeWnd->spwndOwner)
2205 {
2206 for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndOwner)
2207 {
2208 if (pwndNode == pwndTarget)
2209 break;
2210 }
2211
2212 if (!pwndNode)
2213 return FALSE;
2214 }
2215
2216 // Any ancestor of pwndTarget is IME-like?
2217 for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndOwner)
2218 {
2219 if (IS_WND_IMELIKE(pwndNode))
2220 return FALSE;
2221 }
2222
2223 // Adjust the ordering and top-mode status
2224 IntImeSetFutureOwner(pImeWnd, pwndTarget);
2225 for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndNext)
2226 {
2227 if (pwndNode == pImeWnd)
2228 break;
2229 }
2230 if (pwndNode == pImeWnd)
2231 IntImeCheckTopmost(pImeWnd);
2232
2233 // Is the owner of pImeWnd NULL or pwndTarget?
2234 if (pImeWnd->spwndOwner && pwndTarget != pImeWnd->spwndOwner)
2235 return FALSE;
2236
2237 WndSetOwner(pImeWnd, NULL);
2238 return TRUE;
2239}
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
static VOID FASTCALL IntImeCheckTopmost(_In_ PWND pImeWnd)
Definition: ime.c:1430
VOID FASTCALL IntImeSetFutureOwner(PWND pImeWnd, PWND pwndOwner)
Definition: ime.c:1246
UINT fDestroy
Definition: ntuser.h:1229
static VOID WndSetOwner(_Inout_ PWND pwnd, _In_opt_ PWND pwndOwner)
Definition: window.h:150

Referenced by co_UserDestroyWindow().

◆ IntImeCanDestroyDefIMEforChild()

BOOL FASTCALL IntImeCanDestroyDefIMEforChild ( _In_ PWND  pImeWnd,
_In_ PWND  pwndTarget 
)

Definition at line 2130 of file ime.c.

2133{
2134 PWND pwndNode;
2135 PIMEUI pimeui;
2136 IMEUI SafeImeUI;
2137
2138 pimeui = IntGetImeUIFromWnd(pImeWnd);
2139 if (!pimeui)
2140 return FALSE;
2141
2142 // Check IMEUI.fChildThreadDef
2143 _SEH2_TRY
2144 {
2145 ProbeForRead(pimeui, sizeof(IMEUI), 1);
2146 SafeImeUI = *pimeui;
2147 if (!SafeImeUI.fChildThreadDef)
2148 return FALSE;
2149 }
2151 {
2152 ERR("Exception in IntImeCanDestroyDefIMEforChild: %p\n", pimeui);
2153 }
2154 _SEH2_END;
2155
2156 // The parent of pwndTarget is NULL or of the same thread of pwndTarget?
2157 if (pwndTarget->spwndParent == NULL ||
2158 pwndTarget->head.pti == pwndTarget->spwndParent->head.pti)
2159 {
2160 return FALSE;
2161 }
2162
2163 for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndParent)
2164 {
2165 if (pwndNode == pwndNode->head.rpdesk->pDeskInfo->spwnd)
2166 break;
2167
2168 if (IntFindNonImeRelatedWndOfSameThread(pwndNode->spwndParent, pwndTarget))
2169 return FALSE;
2170 }
2171
2172 return TRUE;
2173}
BOOL IntFindNonImeRelatedWndOfSameThread(PWND pwndParent, PWND pwndTarget)
Definition: ime.c:1948

Referenced by co_UserDestroyWindow().

◆ IntImeCheckTopmost()

static VOID FASTCALL IntImeCheckTopmost ( _In_ PWND  pImeWnd)
static

Definition at line 1430 of file ime.c.

1431{
1432 BOOL bTopMost;
1433 PWND pwndOwner = pImeWnd->spwndOwner, pwndInsertBefore = NULL;
1434
1435 if (!pwndOwner)
1436 return;
1437
1438 if (pImeWnd->head.pti != gptiForeground)
1439 pwndInsertBefore = pwndOwner;
1440
1441 bTopMost = !!(pwndOwner->ExStyle & WS_EX_TOPMOST);
1442 IntImeSetTopMost(pImeWnd, bTopMost, pwndInsertBefore);
1443}
PTHREADINFO gptiForeground
Definition: focus.c:15
static VOID FASTCALL IntImeSetTopMost(_In_ PWND pImeWnd, _In_ BOOL bTopMost, _In_ PWND pwndInsertBefore)
Definition: ime.c:1340

Referenced by IntImeCanDestroyDefIME(), and NtUserSetImeOwnerWindow().

◆ IntImeSetFutureOwner()

VOID FASTCALL IntImeSetFutureOwner ( PWND  pImeWnd,
PWND  pwndOwner 
)

Definition at line 1246 of file ime.c.

1247{
1248 PWND pwndNode, pwndNextOwner, pwndParent, pwndSibling;
1249 PTHREADINFO pti = pImeWnd->head.pti;
1250
1251 if (!pwndOwner || (pwndOwner->style & WS_CHILD)) // invalid owner
1252 return;
1253
1254 // Get the top-level owner of the same thread
1255 for (pwndNode = pwndOwner; ; pwndNode = pwndNextOwner)
1256 {
1257 pwndNextOwner = pwndNode->spwndOwner;
1258 if (!pwndNextOwner || pwndNextOwner->head.pti != pti)
1259 break;
1260 }
1261
1262 // Don't choose the IME-like windows and the bottom-most windows unless necessary.
1263 if (IS_WND_IMELIKE(pwndNode) ||
1264 ((pwndNode->state2 & WNDS2_BOTTOMMOST) && !(pwndOwner->state2 & WNDS2_BOTTOMMOST)))
1265 {
1266 pwndNode = pwndOwner;
1267 }
1268
1269 pwndParent = pwndNode->spwndParent;
1270 if (!pwndParent || pwndOwner != pwndNode)
1271 {
1272 WndSetOwner(pImeWnd, pwndNode);
1273 return;
1274 }
1275
1276 for (pwndSibling = pwndParent->spwndChild; pwndSibling; pwndSibling = pwndSibling->spwndNext)
1277 {
1278 if (pwndNode->head.pti != pwndSibling->head.pti)
1279 continue;
1280
1281 if (IS_WND_MENU(pwndSibling) || IS_WND_IMELIKE(pwndSibling))
1282 continue;
1283
1284 if (pwndSibling->state2 & WNDS2_INDESTROY)
1285 continue;
1286
1287 if (pwndNode == pwndSibling || (pwndSibling->style & WS_CHILD))
1288 continue;
1289
1290 if (pwndSibling->spwndOwner == NULL ||
1291 pwndSibling->head.pti != pwndSibling->spwndOwner->head.pti)
1292 {
1293 pwndNode = pwndSibling;
1294 break;
1295 }
1296 }
1297
1298 WndSetOwner(pImeWnd, pwndNode);
1299}
#define WNDS2_BOTTOMMOST
Definition: ntuser.h:646
DWORD style
Definition: ntuser.h:706

Referenced by IntImeCanDestroyDefIME(), and NtUserSetImeOwnerWindow().

◆ IntImeSetTopMost()

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

Definition at line 1340 of file ime.c.

1341{
1342 PWND pwndParent, pwndChild, pwndNode, pwndNext, pwndInsertAfter = NULL;
1343 PWND pwndInsertAfterSave;
1344
1345 pwndParent = pImeWnd->spwndParent;
1346 if (!pwndParent)
1347 return;
1348
1349 pwndChild = pwndParent->spwndChild;
1350
1351 if (!bTopMost)
1352 {
1353 // Calculate pwndInsertAfter
1354 pwndInsertAfter = IntGetLastTopMostWindowNoIME(pImeWnd);
1355 if (pwndInsertBefore)
1356 {
1357 for (pwndNode = pwndInsertAfter; pwndNode; pwndNode = pwndNode->spwndNext)
1358 {
1359 if (pwndNode->spwndNext == pwndInsertBefore)
1360 break;
1361
1362 if (pwndNode == pImeWnd)
1363 return;
1364 }
1365
1366 if (!pwndNode)
1367 return;
1368
1369 pwndInsertAfter = pwndNode;
1370 }
1371
1372 // Adjust pwndInsertAfter if the owner is bottom-most
1373 if (pImeWnd->spwndOwner->state2 & WNDS2_BOTTOMMOST)
1374 {
1375 for (pwndNode = pwndInsertAfter; pwndNode; pwndNode = pwndNode->spwndNext)
1376 {
1377 if (pwndNode == pImeWnd->spwndOwner)
1378 break;
1379
1380 if (!IS_WND_IMELIKE(pwndNode))
1381 pwndInsertAfter = pwndNode;
1382 }
1383 }
1384 }
1385
1386 pwndInsertAfterSave = pwndInsertAfter;
1387
1388 while (pwndChild)
1389 {
1390 pwndNext = pwndChild->spwndNext;
1391
1392 // If pwndChild is a good IME-like window, ...
1393 if (IS_WND_IMELIKE(pwndChild) && pwndChild != pwndInsertAfter &&
1394 pwndChild->head.pti == pImeWnd->head.pti)
1395 {
1396 // Find pImeWnd from the owners
1397 for (pwndNode = pwndChild; pwndNode; pwndNode = pwndNode->spwndOwner)
1398 {
1399 if (pwndNode != pImeWnd)
1400 continue;
1401
1402 // Adjust the ordering and the linking
1403 IntUnlinkWindow(pwndChild);
1404
1405 if (bTopMost)
1406 pwndChild->ExStyle |= WS_EX_TOPMOST;
1407 else
1408 pwndChild->ExStyle &= ~WS_EX_TOPMOST;
1409
1410 if (!pwndInsertAfter)
1411 IntLinkHwnd(pwndChild, HWND_TOP);
1412 else
1413 IntLinkHwnd(pwndChild, UserHMGetHandle(pwndInsertAfter));
1414
1415 // Update the preferred position
1416 pwndInsertAfter = pwndChild;
1417 break;
1418 }
1419 }
1420
1421 // Get the next child, with ignoring pwndInsertAfterSave
1422 pwndChild = pwndNext;
1423 if (pwndChild && pwndChild == pwndInsertAfterSave && pwndInsertAfter)
1424 pwndChild = pwndInsertAfter->spwndNext;
1425 }
1426}
static PWND FASTCALL IntGetLastTopMostWindowNoIME(_In_ PWND pImeWnd)
Definition: ime.c:1303
VOID FASTCALL IntUnlinkWindow(PWND Wnd)
Definition: window.c:1357
VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
Definition: window.c:986
#define HWND_TOP
Definition: winuser.h:1218

Referenced by IntImeCheckTopmost().

◆ IntImmProcessKey()

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

Definition at line 603 of file ime.c.

609{
610 UINT uVirtualKey, ret;
611 DWORD dwHotKeyId;
612 PKL pKL;
613 PIMC pIMC;
614 PIMEHOTKEY pImeHotKey;
615 HKL hKL;
616 HWND hWnd;
617
618 ASSERT_REFS_CO(pWnd);
619
620 switch (uMsg)
621 {
622 case WM_KEYDOWN:
623 case WM_KEYUP:
624 case WM_SYSKEYDOWN:
625 case WM_SYSKEYUP:
626 break;
627
628 default:
629 return 0;
630 }
631
632 pIMC = NULL;
633 hWnd = UserHMGetHandle(pWnd);
634 pKL = pWnd->head.pti->KeyboardLayout;
635 if (!pKL)
636 return 0;
637
638 uVirtualKey = LOBYTE(wParam);
639 pImeHotKey = IntCheckImeHotKey(MessageQueue, uVirtualKey, lParam);
640 if (pImeHotKey)
641 {
642 dwHotKeyId = pImeHotKey->dwHotKeyId;
643 hKL = pImeHotKey->hKL;
644 }
645 else
646 {
647 dwHotKeyId = INVALID_HOTKEY;
648 hKL = NULL;
649 }
650
651 if (IME_HOTKEY_DSWITCH_FIRST <= dwHotKeyId && dwHotKeyId <= IME_HOTKEY_DSWITCH_LAST)
652 {
653 if (pKL->hkl != hKL)
654 {
655 UserPostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST,
656 ((pKL->dwFontSigs & gSystemFS) ? INPUTLANGCHANGE_SYSCHARSET : 0),
657 (LPARAM)hKL);
658 }
659
660 if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
661 return 0;
662
663 return IPHK_HOTKEY;
664 }
665
666 if (!IS_IMM_MODE())
667 {
668 if (dwHotKeyId != INVALID_HOTKEY)
669 WARN("!IS_IMM_MODE(): dwHotKeyId 0x%X\n", dwHotKeyId);
670
671 return 0;
672 }
673
674 if (dwHotKeyId == INVALID_HOTKEY)
675 {
676 if (!pKL->piiex)
677 return 0;
678
679 if (pWnd->hImc)
680 pIMC = UserGetObject(gHandleTable, pWnd->hImc, TYPE_INPUTCONTEXT);
681 if (!pIMC)
682 return 0;
683
684 if ((lParam & (KF_UP << 16)) &&
686 {
687 return 0;
688 }
689
690 switch (uVirtualKey)
691 {
692 case VK_DBE_CODEINPUT:
695 case VK_DBE_HIRAGANA:
696 case VK_DBE_KATAKANA:
698 case VK_DBE_NOROMAN:
699 case VK_DBE_ROMAN:
700 break;
701
702 default:
703 {
704 if (uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP)
705 {
706 if (uVirtualKey != VK_MENU && uVirtualKey != VK_F10)
707 return 0;
708 }
709
711 {
712 if (uVirtualKey == VK_MENU || (lParam & 0x20000000))
713 return 0;
714 }
715 break;
716 }
717 }
718 }
719
720 if (LOBYTE(uVirtualKey) == VK_PACKET)
721 uVirtualKey = MAKELONG(wParam, GetW32ThreadInfo()->wchInjected);
722
723 ret = co_IntImmProcessKey(hWnd, pKL->hkl, uVirtualKey, lParam, dwHotKeyId);
724
725 if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
726 ret &= ~IPHK_HOTKEY;
727
728 return ret;
729}
HWND hWnd
Definition: settings.c:17
#define WARN(fmt,...)
Definition: precomp.h:61
WPARAM wParam
Definition: combotst.c:138
#define VK_DBE_ROMAN
Definition: ime.h:46
#define VK_DBE_HIRAGANA
Definition: ime.h:43
#define VK_DBE_CODEINPUT
Definition: ime.h:51
#define VK_DBE_NOROMAN
Definition: ime.h:47
#define VK_DBE_KATAKANA
Definition: ime.h:42
#define VK_DBE_ENTERWORDREGISTERMODE
Definition: ime.h:48
#define VK_DBE_ENTERIMECONFIGMODE
Definition: ime.h:49
#define VK_DBE_NOCODEINPUT
Definition: ime.h:52
#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:347
#define IME_PROP_IGNORE_UPKEYS
Definition: immdev.h:346
#define LOBYTE(W)
Definition: jmemdos.c:487
LONG_PTR LPARAM
Definition: minwindef.h:175
#define INVALID_HOTKEY
Definition: ime.c:17
static PIMEHOTKEY IntCheckImeHotKey(_In_ const USER_MESSAGE_QUEUE *MessageQueue, _In_ UINT uVirtualKey, _In_ LPARAM lParam)
Definition: ime.c:291
static DWORD FASTCALL IntGetImeCompatFlags(_In_opt_ PTHREADINFO pti)
Definition: ime.c:46
DWORD fdwProperty
Definition: immdev.h:22
Definition: ntuser.h:199
HKL hKL
Definition: ime.c:32
IMEINFO ImeInfo
Definition: imm32_undoc.h:75
Definition: input.h:27
PIMEINFOEX piiex
Definition: input.h:38
DWORD dwFontSigs
Definition: input.h:34
HEAD head
Definition: input.h:28
HKL hkl
Definition: input.h:32
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define IPHK_HOTKEY
Definition: undocuser.h:140
#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
DWORD gSystemFS
Definition: kbdlayout.c:24
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1395
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, HANDLE_TYPE type)
Definition: object.c:495
#define WM_KEYUP
Definition: winuser.h:1744
#define VK_F10
Definition: winuser.h:2300
#define KF_UP
Definition: winuser.h:2487
#define WM_SYSKEYUP
Definition: winuser.h:1748
#define WM_KEYDOWN
Definition: winuser.h:1743
#define WM_SYSKEYDOWN
Definition: winuser.h:1747
#define VK_MENU
Definition: winuser.h:2240

Referenced by co_IntProcessKeyboardMessage().

◆ IntNotifyImeShowStatus()

VOID FASTCALL IntNotifyImeShowStatus ( _In_ PWND  pImeWnd)

Definition at line 2447 of file ime.c.

2448{
2449 PIMEUI pimeui;
2450 PWND pWnd;
2451 PTHREADINFO pti, ptiIME;
2452 BOOL bShow, bSendNotify = FALSE;
2453 IMEUI SafeImeUI;
2454
2455 if (!IS_IMM_MODE() || (pImeWnd->state2 & WNDS2_INDESTROY))
2456 return;
2457
2459 ptiIME = pImeWnd->head.pti;
2460
2461 pimeui = IntGetImeUIFromWnd(pImeWnd);
2462 if (!pimeui)
2463 {
2464 ERR("Invalid IMEWND %p\n", pImeWnd);
2465 return;
2466 }
2467
2468 // Attach to the process if necessary
2469 if (pti != ptiIME)
2470 KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2471
2472 // Get an IMEUI and check whether hwndIMC is valid and update fShowStatus
2473 _SEH2_TRY
2474 {
2475 ProbeForWrite(pimeui, sizeof(*pimeui), 1);
2476 SafeImeUI = *pimeui;
2477
2478 bShow = (gfIMEShowStatus == TRUE) && SafeImeUI.fCtrlShowStatus;
2479
2480 pWnd = ValidateHwndNoErr(SafeImeUI.hwndIMC);
2481 if (!pWnd)
2482 pWnd = ptiIME->MessageQueue->spwndFocus;
2483
2484 if (pWnd)
2485 {
2486 bSendNotify = TRUE;
2487 pimeui->fShowStatus = bShow;
2488 }
2489 }
2491 {
2492 ERR("Exception in IntNotifyImeShowStatus: %p, %p, %p, %d, %d\n",
2493 pImeWnd, pimeui, ptiIME, SafeImeUI.fCtrlShowStatus, gfIMEShowStatus);
2494
2495 if (pti != ptiIME)
2497
2498 _SEH2_YIELD(return);
2499 }
2500 _SEH2_END;
2501
2502 // Detach from the process if necessary
2503 if (pti != ptiIME)
2505
2506 if (bSendNotify)
2507 IntSendOpenStatusNotify(ptiIME, &SafeImeUI, pWnd, bShow);
2508
2509 if (!(pImeWnd->state2 & WNDS2_INDESTROY))
2510 IntCheckImeShowStatus(pImeWnd, NULL);
2511}
VOID FASTCALL IntSendOpenStatusNotify(PTHREADINFO ptiIME, PIMEUI pimeui, PWND pWnd, BOOL bOpen)
Definition: ime.c:2427
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
UINT fCtrlShowStatus
Definition: ntuser.h:1232

Referenced by IntBroadcastImeShowStatusChange().

◆ IntSendMessageToUI()

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

Definition at line 2341 of file ime.c.

2347{
2348 PWND pwndUI;
2349 LRESULT ret = 0;
2350 IMEUI SafeImeUI;
2351 BOOL bDifferent = FALSE;
2353
2354 // Attach to the process if necessary
2355 if (ptiIME != GetW32ThreadInfo())
2356 {
2357 bDifferent = TRUE;
2358 KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2359 }
2360
2361 // Get the pwndUI
2362 _SEH2_TRY
2363 {
2364 ProbeForRead(pimeui, sizeof(IMEUI), 1);
2365 SafeImeUI = *pimeui;
2366 pwndUI = ValidateHwndNoErr(SafeImeUI.hwndUI);
2367 }
2369 {
2370 ERR("Exception in IntSendMessageToUI: %p\n", pimeui);
2371 pwndUI = NULL;
2372 }
2373 _SEH2_END;
2374
2375 if (!pwndUI)
2376 goto Quit;
2377
2378 // Increment the recursion count of the IME procedure.
2379 // See also ImeWndProc_common of user32.
2380 _SEH2_TRY
2381 {
2382 ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1);
2383 InterlockedIncrement(&pimeui->nCntInIMEProc);
2384 }
2386 {
2387 ERR("Exception in IntSendMessageToUI: %p\n", pimeui);
2388 _SEH2_YIELD(goto Quit);
2389 }
2390 _SEH2_END;
2391
2392 // Detach from the process if necessary
2393 if (bDifferent)
2395
2396 UserRefObjectCo(pwndUI, &Ref);
2398 UserDerefObjectCo(pwndUI);
2399
2400 // Attach to the process if necessary
2401 if (bDifferent)
2402 KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2403
2404 // Decrement the recursion count of the IME procedure
2405 _SEH2_TRY
2406 {
2407 ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1);
2408 InterlockedDecrement(&pimeui->nCntInIMEProc);
2409 }
2411 {
2412 ERR("Exception in IntSendMessageToUI: %p\n", pimeui);
2413 _SEH2_YIELD(goto Quit);
2414 }
2415 _SEH2_END;
2416
2417Quit:
2418 // Detach from the process if necessary
2419 if (bDifferent)
2421
2422 return ret;
2423}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG_PTR LRESULT
Definition: minwindef.h:176
long LONG
Definition: pedump.c:60
HWND hwndUI
Definition: ntuser.h:1224

Referenced by IntSendOpenStatusNotify().

◆ IntSendOpenStatusNotify()

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

Definition at line 2427 of file ime.c.

2428{
2430 PTHREADINFO ptiWnd = pWnd->head.pti;
2432
2433 if (ptiWnd->dwExpWinVer >= WINVER_WINNT4 && pWnd->hImc)
2434 {
2435 UserRefObjectCo(pWnd, &Ref);
2437 UserDerefObjectCo(pWnd);
2438 }
2439 else
2440 {
2441 IntSendMessageToUI(ptiIME, pimeui, WM_IME_NOTIFY, wParam, 0);
2442 }
2443}
#define IMN_OPENSTATUSWINDOW
Definition: imm.h:373
UINT_PTR WPARAM
Definition: minwindef.h:174
LRESULT FASTCALL IntSendMessageToUI(_In_ PTHREADINFO ptiIME, _In_ PIMEUI pimeui, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
Definition: ime.c:2341
DWORD dwExpWinVer
Definition: win32.h:112
#define WINVER_WINNT4
Definition: window.h:57

Referenced by IntNotifyImeShowStatus().

◆ IntSetImeHotKey()

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

Definition at line 357 of file ime.c.

363{
364 PIMEHOTKEY pNode;
365 LANGID LangId;
366
367 switch (dwAction)
368 {
370 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); /* Find hotkey by ID */
371 if (!pNode)
372 {
373 ERR("dwHotKeyId: 0x%lX\n", dwHotKeyId);
374 return FALSE;
375 }
376
377 IntDeleteImeHotKey(&gpImeHotKeyList, pNode); /* Delete it */
378 return TRUE;
379
380 case SETIMEHOTKEY_ADD:
381 if (LOWORD(uVirtualKey) == VK_PACKET) /* In case of VK_PACKET */
382 return FALSE;
383
384 LangId = IntGetImeHotKeyLangId(dwHotKeyId);
385 if (LangId == LANGID_KOREAN)
386 return FALSE; /* Korean can't add IME hotkeys */
387
388 /* Find hotkey by key and language */
390 (uModifiers & MOD_KEYS),
391 (uModifiers & MOD_LEFT_RIGHT),
392 uVirtualKey, LangId);
393 if (pNode == NULL) /* If not found */
394 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); /* Find by ID */
395
396 if (pNode) /* Already exists */
397 {
398 pNode->uModifiers = uModifiers;
399 pNode->uVirtualKey = uVirtualKey;
400 pNode->hKL = hKL;
401 return TRUE;
402 }
403
404 /* Allocate new hotkey */
406 if (!pNode)
407 return FALSE;
408
409 /* Populate */
410 pNode->pNext = NULL;
411 pNode->dwHotKeyId = dwHotKeyId;
412 pNode->uModifiers = uModifiers;
413 pNode->uVirtualKey = uVirtualKey;
414 pNode->hKL = hKL;
415 IntAddImeHotKey(&gpImeHotKeyList, pNode); /* Add it */
416 return TRUE;
417
419 IntFreeImeHotKeys(); /* Delete all the IME hotkeys */
420 return TRUE;
421
422 default:
423 ERR("0x%lX\n", dwAction);
424 return FALSE;
425 }
426}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
VOID FASTCALL IntFreeImeHotKeys(VOID)
Definition: ime.c:345
static PIMEHOTKEY FASTCALL IntGetImeHotKeyById(_In_ PIMEHOTKEY pList, _In_ DWORD dwHotKeyId)
Definition: ime.c:152
static PIMEHOTKEY APIENTRY IntGetImeHotKeyByKeyAndLang(_In_ PIMEHOTKEY pList, _In_ UINT uModKeys, _In_ UINT uLeftRight, _In_ UINT uVirtualKey, _In_ LANGID TargetLangId)
Definition: ime.c:166
static VOID FASTCALL IntDeleteImeHotKey(_Inout_ PIMEHOTKEY *ppList, _In_ PIMEHOTKEY pHotKey)
Definition: ime.c:201
static VOID FASTCALL IntAddImeHotKey(_In_ PIMEHOTKEY *ppList, _In_ PIMEHOTKEY pHotKey)
Definition: ime.c:129
@ SETIMEHOTKEY_INITIALIZE
Definition: undocuser.h:423
@ SETIMEHOTKEY_ADD
Definition: undocuser.h:422
@ SETIMEHOTKEY_DELETE
Definition: undocuser.h:421

Referenced by NtUserSetImeHotKey().

◆ IntWantImeWindow()

BOOL FASTCALL IntWantImeWindow ( _In_ PWND  pwndTarget)

Definition at line 2024 of file ime.c.

2025{
2026 PDESKTOP rpdesk;
2027 PWINSTATION_OBJECT rpwinstaParent;
2028 PWND pwndNode, pwndParent = pwndTarget->spwndParent;
2029
2031 return FALSE;
2032
2033 if (IS_WND_IMELIKE(pwndTarget))
2034 return FALSE;
2035
2036 if (pwndTarget->fnid == FNID_DESKTOP || pwndTarget->fnid == FNID_MESSAGEWND)
2037 return FALSE;
2038
2039 if (pwndTarget->state & WNDS_SERVERSIDEWINDOWPROC)
2040 return FALSE;
2041
2042 rpdesk = pwndTarget->head.rpdesk;
2043 if (!rpdesk)
2044 return FALSE;
2045
2046 rpwinstaParent = rpdesk->rpwinstaParent;
2047 if (!rpwinstaParent || (rpwinstaParent->Flags & WSS_NOIO))
2048 return FALSE;
2049
2050 for (pwndNode = pwndParent; pwndNode; pwndNode = pwndNode->spwndParent)
2051 {
2052 if (rpdesk != pwndNode->head.rpdesk)
2053 break;
2054
2055 if (pwndNode == rpdesk->spwndMessage)
2056 return FALSE;
2057 }
2058
2059 return TRUE;
2060}
#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
#define WSS_NOIO
Definition: winsta.h:9

Referenced by co_UserCreateWindowEx().

◆ NtUserAssociateInputContext()

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

Definition at line 1795 of file ime.c.

1799{
1800 DWORD ret = 2;
1801 PWND pWnd;
1802 PIMC pIMC;
1803
1805
1806 if (!IS_IMM_MODE())
1807 {
1808 ERR("!IS_IMM_MODE()\n");
1809 goto Quit;
1810 }
1811
1812 pWnd = ValidateHwndNoErr(hWnd);
1813 if (!pWnd)
1814 {
1815 ERR("Invalid HWND: %p\n", hWnd);
1816 goto Quit;
1817 }
1818
1819 pIMC = (hIMC ? UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT) : NULL);
1820 ret = IntAssociateInputContextEx(pWnd, pIMC, dwFlags);
1821
1822Quit:
1823 UserLeave();
1824 return ret;
1825}
static DWORD FASTCALL IntAssociateInputContextEx(_In_ PWND pWnd, _In_ PIMC pIMC, _In_ DWORD dwFlags)
Definition: ime.c:1729
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:258
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249

Referenced by ImmAssociateContext(), and ImmAssociateContextEx().

◆ NtUserBuildHimcList()

NTSTATUS NTAPI NtUserBuildHimcList ( _In_ DWORD  dwThreadId,
_In_ DWORD  dwCount,
_Out_ HIMC phList,
_Out_ PDWORD  pdwCount 
)

Definition at line 733 of file ime.c.

738{
740 DWORD dwRealCount;
741 PTHREADINFO pti;
742
744
745 if (!IS_IMM_MODE())
746 {
747 ERR("!IS_IMM_MODE()\n");
749 goto Quit;
750 }
751
752 if (dwThreadId == 0)
753 {
754 pti = gptiCurrent;
755 }
756 else if (dwThreadId == INVALID_THREAD_ID)
757 {
758 pti = NULL;
759 }
760 else
761 {
763 if (!pti || !pti->rpdesk)
764 goto Quit;
765 }
766
768 {
769 ProbeForWrite(phList, dwCount * sizeof(HIMC), 1);
770 ProbeForWrite(pdwCount, sizeof(DWORD), 1);
771 *pdwCount = dwRealCount = UserBuildHimcList(pti, dwCount, phList);
772 }
774 {
775 ERR("Exception in NtUserBuildHimcList: %p, %p\n", phList, pdwCount);
776 _SEH2_YIELD(goto Quit);
777 }
778 _SEH2_END;
779
780 if (dwCount < dwRealCount)
782 else
784
785Quit:
786 UserLeave();
787 return ret;
788}
LONG NTSTATUS
Definition: precomp.h:26
#define UlongToHandle(ul)
Definition: basetsd.h:91
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
DWORD dwThreadId
Definition: fdebug.c:31
#define INVALID_THREAD_ID
Definition: ime.c:16
DWORD FASTCALL UserBuildHimcList(_Inout_ PTHREADINFO pti, _In_ DWORD dwCount, _Inout_ HIMC *phList)
Definition: ime.c:567
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:42

Referenced by Imm32BuildHimcList().

◆ NtUserCheckImeHotKey()

DWORD NTAPI NtUserCheckImeHotKey ( _In_ UINT  uVirtualKey,
_In_ LPARAM  lParam 
)

Definition at line 494 of file ime.c.

497{
498 PIMEHOTKEY pNode;
500
502
503 if (!gpqForeground || !IS_IMM_MODE())
504 goto Quit;
505
506 pNode = IntCheckImeHotKey(gpqForeground, uVirtualKey, lParam);
507 if (pNode)
508 ret = pNode->dwHotKeyId;
509
510Quit:
511 UserLeave();
512 return ret;
513}

◆ NtUserCreateInputContext()

HIMC NTAPI NtUserCreateInputContext ( _In_ ULONG_PTR  dwClientImcData)

Definition at line 1699 of file ime.c.

1700{
1701 PIMC pIMC;
1702 HIMC ret = NULL;
1703
1705
1706 if (!IS_IMM_MODE())
1707 {
1708 ERR("!IS_IMM_MODE()\n");
1710 goto Quit;
1711 }
1712
1713 if (!dwClientImcData)
1714 {
1716 goto Quit;
1717 }
1718
1719 pIMC = UserCreateInputContext(dwClientImcData);
1720 if (pIMC)
1721 ret = UserHMGetHandle(pIMC);
1722
1723Quit:
1724 UserLeave();
1725 return ret;
1726}

Referenced by ImmCreateContext().

◆ NtUserDestroyInputContext()

BOOL NTAPI NtUserDestroyInputContext ( _In_ HIMC  hIMC)

Definition at line 1628 of file ime.c.

1629{
1630 BOOL ret = FALSE;
1631 PIMC pIMC;
1632
1634
1635 if (!IS_IMM_MODE())
1636 {
1638 goto Quit;
1639 }
1640
1642 if (pIMC)
1644
1645Quit:
1646 UserLeave();
1647 return ret;
1648}
static BOOL IntDestroyInputContext(_In_ PIMC pIMC)
Definition: ime.c:1588

Referenced by Imm32DestroyInputContext().

◆ NtUserDisableThreadIme()

BOOL NTAPI NtUserDisableThreadIme ( _In_ DWORD  dwThreadID)

Definition at line 905 of file ime.c.

906{
907 PTHREADINFO pti, ptiCurrent;
908 PPROCESSINFO ppi;
909 BOOL ret = FALSE;
910
912
913 if (!IS_IMM_MODE())
914 {
915 ERR("!IS_IMM_MODE()\n");
917 goto Quit;
918 }
919
920 ptiCurrent = GetW32ThreadInfo();
921
922 if (dwThreadID == INVALID_THREAD_ID)
923 {
924 ppi = ptiCurrent->ppi;
925 ppi->W32PF_flags |= W32PF_DISABLEIME;
926
927Retry:
928 for (pti = ppi->ptiList; pti; pti = pti->ptiSibling)
929 {
931
932 if (pti->spwndDefaultIme)
933 {
935 pti->spwndDefaultIme = NULL;
936 goto Retry; /* The contents of ppi->ptiList may be changed. */
937 }
938 }
939 }
940 else
941 {
942 if (dwThreadID == 0)
943 {
944 pti = ptiCurrent;
945 }
946 else
947 {
948 pti = IntTID2PTI(UlongToHandle(dwThreadID));
949
950 /* The thread needs to reside in the current process. */
951 if (!pti || pti->ppi != ptiCurrent->ppi)
952 goto Quit;
953 }
954
956
957 if (pti->spwndDefaultIme)
958 {
960 pti->spwndDefaultIme = NULL;
961 }
962 }
963
964 ret = TRUE;
965
966Quit:
967 UserLeave();
968 return ret;
969}
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
PTHREADINFO ptiList
Definition: win32.h:257
PTHREADINFO ptiSibling
Definition: win32.h:116
struct _WND * spwndDefaultIme
Definition: win32.h:131
BOOLEAN co_UserDestroyWindow(PVOID Object)
Definition: window.c:2873
#define W32PF_DISABLEIME
Definition: win32.h:28

Referenced by ImmDisableIME().

◆ NtUserGetAppImeLevel()

DWORD NTAPI NtUserGetAppImeLevel ( _In_ HWND  hWnd)

Definition at line 973 of file ime.c.

974{
975 DWORD ret = 0;
976 PWND pWnd;
977 PTHREADINFO pti;
978
980
981 pWnd = ValidateHwndNoErr(hWnd);
982 if (!pWnd)
983 {
984 ERR("Invalid HWND %p\n", hWnd);
985 goto Quit;
986 }
987
988 if (!IS_IMM_MODE())
989 {
990 ERR("!IS_IMM_MODE()\n");
992 goto Quit;
993 }
994
996 if (pWnd->head.pti->ppi == pti->ppi)
998
999Quit:
1000 UserLeave();
1001 return ret;
1002}
#define HandleToUlong(h)
Definition: basetsd.h:73
ATOM AtomImeLevel
Definition: ntuser.c:28
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:242
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 ( _In_ DWORD  dwHotKeyId,
_Out_ PUINT  lpuModifiers,
_Out_ PUINT  lpuVirtualKey,
_Out_opt_ LPHKL  lphKL 
)

Definition at line 429 of file ime.c.

434{
435 PIMEHOTKEY pNode = NULL;
436
438
440 {
441 ProbeForWrite(lpuModifiers, sizeof(UINT), 1);
442 ProbeForWrite(lpuVirtualKey, sizeof(UINT), 1);
443 if (lphKL)
444 ProbeForWrite(lphKL, sizeof(HKL), 1);
445 }
447 {
448 ERR("Exception in NtUserGetImeHotKey: %p, %p, %p\n", lpuModifiers, lpuVirtualKey, lphKL);
449 _SEH2_YIELD(goto Quit);
450 }
451 _SEH2_END;
452
453 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId);
454 if (!pNode)
455 goto Quit;
456
458 {
459 *lpuModifiers = pNode->uModifiers;
460 *lpuVirtualKey = pNode->uVirtualKey;
461 if (lphKL)
462 *lphKL = pNode->hKL;
463 }
465 {
466 ERR("Exception in NtUserGetImeHotKey: %p, %p, %p, %p\n", pNode, lpuModifiers, lpuVirtualKey, lphKL);
467 pNode = NULL;
468 }
469 _SEH2_END;
470
471Quit:
472 UserLeave();
473 return !!pNode;
474}

Referenced by CliSetDefaultImeHotKeys(), and ImmGetHotKey().

◆ NtUserGetImeInfoEx()

BOOL NTAPI NtUserGetImeInfoEx ( _Inout_ PIMEINFOEX  pImeInfoEx,
_In_ IMEINFOEXCLASS  SearchType 
)

Definition at line 1069 of file ime.c.

1072{
1073 IMEINFOEX ImeInfoEx;
1074 BOOL ret = FALSE;
1075 PWINSTATION_OBJECT pWinSta;
1076
1078
1079 if (!IS_IMM_MODE())
1080 {
1081 ERR("!IS_IMM_MODE()\n");
1083 goto Quit;
1084 }
1085
1086 _SEH2_TRY
1087 {
1088 ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1);
1089 ImeInfoEx = *pImeInfoEx;
1090 }
1092 {
1093 ERR("Exception in NtUserGetImeInfoEx: %p\n", pImeInfoEx);
1094 _SEH2_YIELD(goto Quit);
1095 }
1096 _SEH2_END;
1097
1099 ret = UserGetImeInfoEx(pWinSta, &ImeInfoEx, SearchType);
1100 if (!ret)
1101 goto Quit;
1102
1103 _SEH2_TRY
1104 {
1105 ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1);
1106 *pImeInfoEx = ImeInfoEx;
1107 }
1109 {
1110 ERR("Exception in NtUserGetImeInfoEx: %p\n", pImeInfoEx);
1111 ret = FALSE;
1112 }
1113 _SEH2_END;
1114
1115Quit:
1116 UserLeave();
1117 return ret;
1118}
BOOL FASTCALL UserGetImeInfoEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pInfoEx, _In_ IMEINFOEXCLASS SearchType)
Definition: ime.c:1005
PWINSTATION_OBJECT FASTCALL IntGetProcessWindowStation(HWINSTA *phWinSta OPTIONAL)
Definition: winsta.c:411

Referenced by ImmGetImeInfoEx().

◆ NtUserNotifyIMEStatus()

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

Definition at line 850 of file ime.c.

854{
855 PWND pwnd;
856 PTHREADINFO pti;
857 HKL hKL;
858
860
861 if (!IS_IMM_MODE())
862 {
863 ERR("!IS_IMM_MODE()\n");
864 goto Quit;
865 }
866
867 pwnd = ValidateHwndNoErr(hwnd);
868 if (!pwnd)
869 {
870 ERR("Invalid HWND %p\n", hwnd);
871 goto Quit;
872 }
873
874 pti = pwnd->head.pti;
875 if (!pti || !gptiForeground)
876 goto Quit;
878 goto Quit;
879 if (ghIMC == pwnd->hImc && gfImeOpen == !!fOpen && gdwImeConversion == dwConversion)
880 goto Quit;
881
882 ghIMC = pwnd->hImc;
883 if (ghIMC)
884 {
885 gfImeOpen = !!fOpen;
886 gdwImeConversion = dwConversion;
887 UserSetImeConversionKeyState(pti, (fOpen ? dwConversion : IME_CMODE_ALPHANUMERIC));
888 }
889
890 if (ISITHOOKED(WH_SHELL))
891 {
892 hKL = (pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL);
893 co_HOOK_CallHooks(WH_SHELL, HSHELL_LANGUAGE, (WPARAM)hwnd, (LPARAM)hKL);
894 }
895
896 // TODO:
897
898Quit:
899 UserLeave();
900 return 0;
901}
#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:21
DWORD gdwImeConversion
Definition: ime.c:23
static VOID FASTCALL UserSetImeConversionKeyState(PTHREADINFO pti, DWORD dwConversion)
Definition: ime.c:791
BOOL gfImeOpen
Definition: ime.c:22
_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 1894 of file ime.c.

1895{
1896 PIMC pIMC;
1897 PTHREADINFO ptiIMC;
1898 DWORD_PTR ret = 0;
1899
1901
1902 if (!IS_IMM_MODE())
1903 goto Quit;
1904
1906 if (!pIMC)
1907 {
1908 ERR("Invalid HIMC %p\n", hIMC);
1909 goto Quit;
1910 }
1911
1912 ptiIMC = pIMC->head.pti;
1913
1914 switch (dwType)
1915 {
1916 case QIC_INPUTPROCESSID:
1917 ret = (DWORD_PTR)PsGetThreadProcessId(ptiIMC->pEThread);
1918 break;
1919
1920 case QIC_INPUTTHREADID:
1921 ret = (DWORD_PTR)PsGetThreadId(ptiIMC->pEThread);
1922 break;
1923
1925 if (ptiIMC->spwndDefaultIme)
1927 break;
1928
1929 case QIC_DEFAULTIMC:
1930 if (ptiIMC->spDefaultImc)
1932 break;
1933
1934 default:
1935 {
1936 FIXME("dwType: %ld\n", dwType);
1937 break;
1938 }
1939 }
1940
1941Quit:
1942 UserLeave();
1943 return ret;
1944}
#define FIXME(fmt,...)
Definition: precomp.h:53
HANDLE NTAPI PsGetThreadId(IN PETHREAD Thread)
Definition: thread.c:705
THRDESKHEAD head
Definition: ntuser.h:200
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
@ QIC_DEFAULTWINDOWIME
Definition: undocuser.h:414
@ QIC_DEFAULTIMC
Definition: undocuser.h:415
@ QIC_INPUTTHREADID
Definition: undocuser.h:413
@ QIC_INPUTPROCESSID
Definition: undocuser.h:412

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

◆ NtUserSetAppImeLevel()

BOOL NTAPI NtUserSetAppImeLevel ( _In_ HWND  hWnd,
_In_ DWORD  dwLevel 
)

Definition at line 1136 of file ime.c.

1139{
1140 BOOL ret = FALSE;
1141 PWND pWnd;
1142 PTHREADINFO pti;
1143
1145
1146 if (!IS_IMM_MODE())
1147 {
1148 ERR("!IS_IMM_MODE()\n");
1150 goto Quit;
1151 }
1152
1153 pWnd = ValidateHwndNoErr(hWnd);
1154 if (!pWnd)
1155 {
1156 ERR("Invalid HWND: %p\n", hWnd);
1157 goto Quit;
1158 }
1159
1161 if (pWnd->head.pti->ppi == pti->ppi)
1162 ret = UserSetProp(pWnd, AtomImeLevel, UlongToHandle(dwLevel), TRUE);
1163
1164Quit:
1165 UserLeave();
1166 return ret;
1167}

◆ NtUserSetImeHotKey()

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

Definition at line 478 of file ime.c.

484{
485 BOOL ret;
487 ret = IntSetImeHotKey(dwHotKeyId, uModifiers, uVirtualKey, hKL, dwAction);
488 UserLeave();
489 return ret;
490}
static BOOL APIENTRY IntSetImeHotKey(_In_ DWORD dwHotKeyId, _In_ UINT uModifiers, _In_ UINT uVirtualKey, _In_opt_ HKL hKL, _In_ DWORD dwAction)
Definition: ime.c:357

Referenced by CliImmInitializeHotKeys(), and CliImmSetHotKeyWorker().

◆ NtUserSetImeInfoEx()

BOOL NTAPI NtUserSetImeInfoEx ( _In_ const IMEINFOEX pImeInfoEx)

Definition at line 1210 of file ime.c.

1211{
1212 BOOL ret = FALSE;
1213 IMEINFOEX ImeInfoEx;
1214 PWINSTATION_OBJECT pWinSta;
1215
1217
1218 if (!IS_IMM_MODE())
1219 {
1220 ERR("!IS_IMM_MODE()\n");
1221 goto Quit;
1222 }
1223
1224 _SEH2_TRY
1225 {
1226 ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1);
1227 ImeInfoEx = *pImeInfoEx;
1228 }
1230 {
1231 ERR("Exception in NtUserSetImeInfoEx: pImeInfoEx=%p\n", pImeInfoEx);
1232 _SEH2_YIELD(goto Quit);
1233 }
1234 _SEH2_END;
1235
1237 ret = UserSetImeInfoEx(pWinSta, &ImeInfoEx);
1238
1239Quit:
1240 UserLeave();
1241 return ret;
1242}
BOOL FASTCALL UserSetImeInfoEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pImeInfoEx)
Definition: ime.c:1170

Referenced by Imm32LoadIME().

◆ NtUserSetImeOwnerWindow()

BOOL NTAPI NtUserSetImeOwnerWindow ( _In_ HWND  hImeWnd,
_In_opt_ HWND  hwndFocus 
)

Definition at line 1446 of file ime.c.

1449{
1450 BOOL ret = FALSE;
1451 PWND pImeWnd, pwndFocus, pwndTopLevel, pwndNode, pwndActive;
1452 PTHREADINFO ptiIme;
1453
1455
1456 if (!IS_IMM_MODE())
1457 {
1458 ERR("!IS_IMM_MODE()\n");
1459 goto Quit;
1460 }
1461
1462 pImeWnd = ValidateHwndNoErr(hImeWnd);
1463 if (!pImeWnd || pImeWnd->fnid != FNID_IME)
1464 {
1465 ERR("Not IME window: %p\n", hImeWnd);
1466 goto Quit;
1467 }
1468
1469 pwndFocus = ValidateHwndNoErr(hwndFocus);
1470 if (pwndFocus)
1471 {
1472 if (IS_WND_IMELIKE(pwndFocus))
1473 goto Quit;
1474
1475 pwndTopLevel = IntGetTopLevelWindow(pwndFocus);
1476
1477 for (pwndNode = pwndTopLevel; pwndNode; pwndNode = pwndNode->spwndOwner)
1478 {
1479 if (pwndNode->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME])
1480 {
1481 pwndTopLevel = NULL;
1482 break;
1483 }
1484 }
1485
1486 WndSetOwner(pImeWnd, pwndTopLevel);
1487 IntImeCheckTopmost(pImeWnd);
1488 }
1489 else
1490 {
1491 ptiIme = pImeWnd->head.pti;
1492 pwndActive = ptiIme->MessageQueue->spwndActive;
1493
1494 if (!pwndActive || pwndActive != pImeWnd->spwndOwner)
1495 {
1496 if (pwndActive && ptiIme == pwndActive->head.pti && !IS_WND_IMELIKE(pwndActive))
1497 {
1498 WndSetOwner(pImeWnd, pwndActive);
1499 }
1500 else
1501 {
1502 IntImeSetFutureOwner(pImeWnd, pImeWnd->spwndOwner);
1503 }
1504
1505 IntImeCheckTopmost(pImeWnd);
1506 }
1507 }
1508
1509 ret = TRUE;
1510
1511Quit:
1512 UserLeave();
1513 return ret;
1514}
#define FNID_IME
Definition: ntuser.h:874
PWND FASTCALL IntGetTopLevelWindow(_In_ PWND pwnd)
Definition: ime.c:516
DWORD fnid
Definition: ntuser.h:709

Referenced by ImeWnd_OnImeSetContext().

◆ NtUserSetThreadLayoutHandles()

DWORD NTAPI NtUserSetThreadLayoutHandles ( _In_ HKL  hNewKL,
_In_ HKL  hOldKL 
)

Definition at line 537 of file ime.c.

540{
541 PTHREADINFO pti;
542 PKL pOldKL, pNewKL;
543
545
546 pti = GetW32ThreadInfo();
547 pOldKL = pti->KeyboardLayout;
548 if (pOldKL && pOldKL->hkl != hOldKL)
549 goto Quit;
550
551 pNewKL = UserHklToKbl(hNewKL);
552 if (!pNewKL)
553 goto Quit;
554
555 if (IS_IME_HKL(hNewKL) != IS_IME_HKL(hOldKL))
556 pti->hklPrev = hOldKL;
557
558 UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pNewKL);
559 pti->pClientInfo->hKL = pNewKL->hkl;
560
561Quit:
562 UserLeave();
563 return 0;
564}
#define IS_IME_HKL(hKL)
Definition: imm32_undoc.h:21
struct _CLIENTINFO * pClientInfo
Definition: win32.h:94
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:539
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 1862 of file ime.c.

1866{
1867 PIMC pIMC;
1868 BOOL ret = FALSE;
1869
1871
1872 if (!IS_IMM_MODE())
1873 {
1874 ERR("!IS_IMM_MODE()\n");
1875 goto Quit;
1876 }
1877
1879 if (!pIMC)
1880 {
1881 ERR("Invalid HIMC %p\n", hIMC);
1882 goto Quit;
1883 }
1884
1885 ret = UserUpdateInputContext(pIMC, dwType, dwValue);
1886
1887Quit:
1888 UserLeave();
1889 return ret;
1890}
static BOOL FASTCALL UserUpdateInputContext(_In_ PIMC pIMC, _In_ DWORD dwType, _In_ DWORD_PTR dwValue)
Definition: ime.c:1828

Referenced by ImmLockClientImc(), and User32SetImeWindowOfImc().

◆ UserBuildHimcList()

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

Definition at line 567 of file ime.c.

571{
572 PIMC pIMC;
573 DWORD dwRealCount = 0;
574
575 if (pti)
576 {
577 for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
578 {
579 if (dwRealCount < dwCount)
580 phList[dwRealCount] = UserHMGetHandle(pIMC);
581
582 ++dwRealCount;
583 }
584 }
585 else
586 {
587 for (pti = gptiCurrent->ppi->ptiList; pti; pti = pti->ptiSibling)
588 {
589 for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
590 {
591 if (dwRealCount < dwCount)
592 phList[dwRealCount] = UserHMGetHandle(pIMC);
593
594 ++dwRealCount;
595 }
596 }
597 }
598
599 return dwRealCount;
600}
struct tagIMC * pImcNext
Definition: ntuser.h:201

Referenced by NtUserBuildHimcList().

◆ UserCreateInputContext()

PIMC FASTCALL UserCreateInputContext ( _In_ ULONG_PTR  dwClientImcData)

Definition at line 1651 of file ime.c.

1652{
1653 PIMC pIMC;
1655 PDESKTOP pdesk = pti->rpdesk;
1656
1657 if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled?
1658 {
1659 ERR("IME is disabled\n");
1660 return NULL;
1661 }
1662
1663 if (!pdesk) // No desktop?
1664 return NULL;
1665
1666 // pti->spDefaultImc should be already set if non-first time.
1667 if (dwClientImcData && !pti->spDefaultImc)
1668 return NULL;
1669
1670 // Create an input context user object.
1671 pIMC = UserCreateObject(gHandleTable, pdesk, pti, NULL, TYPE_INPUTCONTEXT, sizeof(IMC));
1672 if (!pIMC)
1673 return NULL;
1674
1675 // Release the extra reference (UserCreateObject added 2 references).
1677 ASSERT(pIMC->head.cLockObj == 1);
1678
1679 if (dwClientImcData) // Non-first time.
1680 {
1681 // Insert pIMC to the second position (non-default) of the list.
1682 pIMC->pImcNext = pti->spDefaultImc->pImcNext;
1683 pti->spDefaultImc->pImcNext = pIMC;
1684 }
1685 else // First time. It's the default IMC.
1686 {
1687 // Add the first one (default) to the list.
1688 UserAssignmentLock((PVOID*)&pti->spDefaultImc, pIMC);
1689 pIMC->pImcNext = NULL;
1690 ASSERT(pIMC->head.cLockObj == 2); // UserAssignmentUnlock'ed at ExitThreadCallback
1691 }
1692
1693 pIMC->dwClientImcData = dwClientImcData; // Set it.
1694 return pIMC;
1695}
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 ( _In_opt_ PVOID  Object)

Definition at line 1576 of file ime.c.

1577{
1578 PIMC pIMC = Object;
1579 if (!pIMC)
1580 return TRUE;
1581
1584 return TRUE;
1585}
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
BOOL FASTCALL UserMarkObjectDestroy(PVOID Object)
Definition: object.c:621

◆ UserFreeInputContext()

VOID UserFreeInputContext ( _In_opt_ PVOID  Object)

Definition at line 1548 of file ime.c.

1549{
1550 PTHRDESKHEAD ObjHead = Object;
1551 PDESKTOP pDesk = ObjHead->rpdesk;
1552 PIMC pNode, pIMC = Object;
1553 PTHREADINFO pti;
1554
1555 if (!pIMC)
1556 return;
1557
1558 // Remove pIMC from the list except spDefaultImc
1559 pti = pIMC->head.pti;
1560 for (pNode = pti->spDefaultImc; pNode; pNode = pNode->pImcNext)
1561 {
1562 if (pNode->pImcNext == pIMC)
1563 {
1564 pNode->pImcNext = pIMC->pImcNext;
1565 break;
1566 }
1567 }
1568
1569 DesktopHeapFree(pDesk, Object);
1570
1571 pti->ppi->UserHandleCount--;
1573}
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:215
#define IntDereferenceThreadInfo(pti)
Definition: win32.h:172

◆ UserGetImeInfoEx()

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

Definition at line 1005 of file ime.c.

1009{
1010 PKL pkl, pklHead;
1011
1012 if (!pWinSta || !gspklBaseLayout)
1013 {
1014 ERR("pWinSta:%p, gspklBaseLayout:%p\n", pWinSta, gspklBaseLayout);
1015 return FALSE;
1016 }
1017
1018 pkl = pklHead = gspklBaseLayout;
1019
1020 /* Find the matching entry from the list and get info */
1021 if (SearchType == ImeInfoExKeyboardLayout)
1022 {
1023 do
1024 {
1025 if (pInfoEx->hkl == pkl->hkl)
1026 {
1027 if (!pkl->piiex)
1028 {
1029 ERR("!pkl->piiex at %p\n", pkl->hkl);
1030 break;
1031 }
1032
1033 *pInfoEx = *pkl->piiex;
1034 return TRUE;
1035 }
1036
1037 pkl = pkl->pklNext;
1038 } while (pkl != pklHead);
1039
1040 ERR("HKL not found: %p\n", pInfoEx->hkl);
1041 }
1042 else if (SearchType == ImeInfoExImeFileName)
1043 {
1044 do
1045 {
1046 if (pkl->piiex &&
1047 _wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile,
1048 RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0)
1049 {
1050 *pInfoEx = *pkl->piiex;
1051 return TRUE;
1052 }
1053
1054 pkl = pkl->pklNext;
1055 } while (pkl != pklHead);
1056
1057 ERR("wszImeFile not found: '%S'\n", pInfoEx->wszImeFile);
1058 }
1059 else
1060 {
1061 ERR("SearchType: %d\n", SearchType);
1062 }
1063
1064 return FALSE;
1065}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:195
@ ImeInfoExImeFileName
Definition: imm32_undoc.h:96
@ ImeInfoExKeyboardLayout
Definition: imm32_undoc.h:93
WCHAR wszImeFile[80]
Definition: imm32_undoc.h:83
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 791 of file ime.c.

792{
793 HKL hKL;
795 LPBYTE KeyState;
796 BOOL bAlphaNumeric, bKatakana, bHiragana, bFullShape, bRoman, bCharCode;
797
798 if (!pti->KeyboardLayout)
799 return;
800
801 hKL = pti->KeyboardLayout->hkl;
802 LangID = LOWORD(hKL);
803 KeyState = pti->MessageQueue->afKeyState;
804
805 switch (PRIMARYLANGID(LangID))
806 {
807 case LANG_JAPANESE:
808 bAlphaNumeric = !(dwConversion & IME_CMODE_NATIVE);
809 bKatakana = !bAlphaNumeric && (dwConversion & IME_CMODE_KATAKANA);
810 bHiragana = !bAlphaNumeric && !(dwConversion & IME_CMODE_KATAKANA);
811 SET_KEY_DOWN(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
812 SET_KEY_LOCKED(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
813 SET_KEY_DOWN(KeyState, VK_DBE_HIRAGANA, bHiragana);
814 SET_KEY_LOCKED(KeyState, VK_DBE_HIRAGANA, bHiragana);
815 SET_KEY_DOWN(KeyState, VK_DBE_KATAKANA, bKatakana);
816 SET_KEY_LOCKED(KeyState, VK_DBE_KATAKANA, bKatakana);
817
818 bFullShape = (dwConversion & IME_CMODE_FULLSHAPE);
819 SET_KEY_DOWN(KeyState, VK_DBE_DBCSCHAR, bFullShape);
820 SET_KEY_LOCKED(KeyState, VK_DBE_DBCSCHAR, bFullShape);
821 SET_KEY_DOWN(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
822 SET_KEY_LOCKED(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
823
824 bRoman = (dwConversion & IME_CMODE_ROMAN);
825 SET_KEY_DOWN(KeyState, VK_DBE_ROMAN, bRoman);
826 SET_KEY_LOCKED(KeyState, VK_DBE_ROMAN, bRoman);
827 SET_KEY_DOWN(KeyState, VK_DBE_NOROMAN, !bRoman);
828 SET_KEY_LOCKED(KeyState, VK_DBE_NOROMAN, !bRoman);
829
830 bCharCode = (dwConversion & IME_CMODE_CHARCODE);
831 SET_KEY_DOWN(KeyState, VK_DBE_CODEINPUT, bCharCode);
832 SET_KEY_LOCKED(KeyState, VK_DBE_CODEINPUT, bCharCode);
833 SET_KEY_DOWN(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
834 SET_KEY_LOCKED(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
835 break;
836
837 case LANG_KOREAN:
838 SET_KEY_LOCKED(KeyState, VK_HANGUL, (dwConversion & IME_CMODE_NATIVE));
839 SET_KEY_LOCKED(KeyState, VK_JUNJA, (dwConversion & IME_CMODE_FULLSHAPE));
840 SET_KEY_LOCKED(KeyState, VK_HANJA, (dwConversion & IME_CMODE_HANJACONVERT));
841 break;
842
843 default:
844 break;
845 }
846}
#define VK_DBE_DBCSCHAR
Definition: ime.h:45
#define VK_DBE_ALPHANUMERIC
Definition: ime.h:41
#define VK_DBE_SBCSCHAR
Definition: ime.h:44
#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 LANG_JAPANESE
Definition: nls.h:76
unsigned char * LPBYTE
Definition: typedefs.h:53
#define SET_KEY_DOWN(ks, vk, down)
Definition: input.h:104
#define SET_KEY_LOCKED(ks, vk, down)
Definition: input.h:107
#define VK_HANGUL
Definition: winuser.h:2245
#define VK_JUNJA
Definition: winuser.h:2246
#define VK_HANJA
Definition: winuser.h:2248

Referenced by NtUserNotifyIMEStatus().

◆ UserSetImeInfoEx()

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

Definition at line 1170 of file ime.c.

1173{
1174 PKL pklHead, pkl;
1175
1176 if (!pWinSta || !gspklBaseLayout)
1177 {
1178 ERR("pWinSta:%p, gspklBaseLayout:%p\n", pWinSta, gspklBaseLayout);
1179 return FALSE;
1180 }
1181
1182 pkl = pklHead = gspklBaseLayout;
1183
1184 do
1185 {
1186 if (pkl->hkl != pImeInfoEx->hkl)
1187 {
1188 pkl = pkl->pklNext;
1189 continue;
1190 }
1191
1192 if (!pkl->piiex)
1193 {
1194 ERR("!pkl->piiex at %p\n", pkl->hkl);
1195 return FALSE;
1196 }
1197
1198 if (!pkl->piiex->fLoadFlag)
1199 *pkl->piiex = *pImeInfoEx;
1200
1201 return TRUE;
1202 } while (pkl != pklHead);
1203
1204 ERR("HKL not found: %p\n", pImeInfoEx->hkl);
1205 return FALSE;
1206}

Referenced by NtUserSetImeInfoEx().

◆ UserUpdateInputContext()

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

Definition at line 1828 of file ime.c.

1829{
1831 PTHREADINFO ptiIMC = pIMC->head.pti;
1832
1833 if (pti->ppi != ptiIMC->ppi) // Different process?
1834 return FALSE;
1835
1836 switch (dwType)
1837 {
1838 case UIC_CLIENTIMCDATA:
1839 if (pIMC->dwClientImcData)
1840 return FALSE; // Already set
1841
1842 pIMC->dwClientImcData = dwValue;
1843 break;
1844
1845 case UIC_IMEWINDOW:
1846 if (!ValidateHwndNoErr((HWND)dwValue))
1847 return FALSE; // Invalid HWND
1848
1849 pIMC->hImeWnd = (HWND)dwValue;
1850 break;
1851
1852 default:
1853 ERR("Unhandled dwType: %lu\n", dwType);
1854 return FALSE;
1855 }
1856
1857 return TRUE;
1858}
HANDLE HWND
Definition: compat.h:19
@ UIC_CLIENTIMCDATA
Definition: undocuser.h:323
@ UIC_IMEWINDOW
Definition: undocuser.h:324

Referenced by NtUserUpdateInputContext().

Variable Documentation

◆ gdwImeConversion

DWORD gdwImeConversion = (DWORD)-1

Definition at line 23 of file ime.c.

Referenced by NtUserNotifyIMEStatus().

◆ gfImeOpen

BOOL gfImeOpen = (BOOL)-1

Definition at line 22 of file ime.c.

Referenced by NtUserNotifyIMEStatus().

◆ gfIMEShowStatus

BOOL gfIMEShowStatus = (BOOL)-1

◆ ghIMC

HIMC ghIMC = NULL

Definition at line 21 of file ime.c.

Referenced by NtUserNotifyIMEStatus().

◆ glcidSystem

LCID glcidSystem = 0

Definition at line 36 of file ime.c.

Referenced by IntGetImeHotKeyLanguageScore().

◆ gpImeHotKeyList

PIMEHOTKEY gpImeHotKeyList = NULL

Definition at line 35 of file ime.c.

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