ReactOS 0.4.15-dev-5672-gf73ac17
ime.c File Reference
#include <win32k.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 VK_DBE_ALPHANUMERIC   0xF0
 
#define VK_DBE_KATAKANA   0xF1
 
#define VK_DBE_HIRAGANA   0xF2
 
#define VK_DBE_SBCSCHAR   0xF3
 
#define VK_DBE_DBCSCHAR   0xF4
 
#define VK_DBE_ROMAN   0xF5
 
#define VK_DBE_NOROMAN   0xF6
 
#define VK_DBE_ENTERWORDREGISTERMODE   0xF7
 
#define VK_DBE_ENTERCONFIGMODE   0xF8
 
#define VK_DBE_FLUSHSTRING   0xF9
 
#define VK_DBE_CODEINPUT   0xFA
 
#define VK_DBE_NOCODEINPUT   0xFB
 
#define VK_DBE_DETERINESTRING   0xFC
 
#define VK_DBE_ENTERDLGCONVERSIONMODE   0xFD
 
#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 14 of file ime.c.

◆ INVALID_THREAD_ID

#define INVALID_THREAD_ID   ((ULONG)-1)

Definition at line 13 of file ime.c.

◆ LANGID_CHINESE_SIMPLIFIED

#define LANGID_CHINESE_SIMPLIFIED   MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)

Definition at line 18 of file ime.c.

◆ LANGID_CHINESE_TRADITIONAL

#define LANGID_CHINESE_TRADITIONAL   MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)

Definition at line 21 of file ime.c.

◆ LANGID_JAPANESE

Definition at line 19 of file ime.c.

◆ LANGID_KOREAN

Definition at line 20 of file ime.c.

◆ LANGID_NEUTRAL

Definition at line 22 of file ime.c.

◆ MOD_KEYS

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

Definition at line 15 of file ime.c.

◆ MOD_LEFT_RIGHT

#define MOD_LEFT_RIGHT   (MOD_LEFT | MOD_RIGHT)

Definition at line 16 of file ime.c.

◆ VK_DBE_ALPHANUMERIC

#define VK_DBE_ALPHANUMERIC   0xF0

Definition at line 26 of file ime.c.

◆ VK_DBE_CODEINPUT

#define VK_DBE_CODEINPUT   0xFA

Definition at line 36 of file ime.c.

◆ VK_DBE_DBCSCHAR

#define VK_DBE_DBCSCHAR   0xF4

Definition at line 30 of file ime.c.

◆ VK_DBE_DETERINESTRING

#define VK_DBE_DETERINESTRING   0xFC

Definition at line 38 of file ime.c.

◆ VK_DBE_ENTERCONFIGMODE

#define VK_DBE_ENTERCONFIGMODE   0xF8

Definition at line 34 of file ime.c.

◆ VK_DBE_ENTERDLGCONVERSIONMODE

#define VK_DBE_ENTERDLGCONVERSIONMODE   0xFD

Definition at line 39 of file ime.c.

◆ VK_DBE_ENTERWORDREGISTERMODE

#define VK_DBE_ENTERWORDREGISTERMODE   0xF7

Definition at line 33 of file ime.c.

◆ VK_DBE_FLUSHSTRING

#define VK_DBE_FLUSHSTRING   0xF9

Definition at line 35 of file ime.c.

◆ VK_DBE_HIRAGANA

#define VK_DBE_HIRAGANA   0xF2

Definition at line 28 of file ime.c.

◆ VK_DBE_KATAKANA

#define VK_DBE_KATAKANA   0xF1

Definition at line 27 of file ime.c.

◆ VK_DBE_NOCODEINPUT

#define VK_DBE_NOCODEINPUT   0xFB

Definition at line 37 of file ime.c.

◆ VK_DBE_NOROMAN

#define VK_DBE_NOROMAN   0xF6

Definition at line 32 of file ime.c.

◆ VK_DBE_ROMAN

#define VK_DBE_ROMAN   0xF5

Definition at line 31 of file ime.c.

◆ VK_DBE_SBCSCHAR

#define VK_DBE_SBCSCHAR   0xF3

Definition at line 29 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 1435 of file ime.c.

1439{
1440 PTHRDESKHEAD ObjHead;
1441
1442 ASSERT(Size > sizeof(*ObjHead));
1443 ASSERT(pti != NULL);
1444
1445 if (!pDesk)
1446 pDesk = pti->rpdesk;
1447
1448 ObjHead = DesktopHeapAlloc(pDesk, Size);
1449 if (!ObjHead)
1450 return NULL;
1451
1452 RtlZeroMemory(ObjHead, Size);
1453
1454 ObjHead->pSelf = ObjHead;
1455 ObjHead->rpdesk = pDesk;
1456 ObjHead->pti = pti;
1458 *HandleOwner = pti;
1459 pti->ppi->UserHandleCount++;
1460
1461 return ObjHead;
1462}
#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 1964 of file ime.c.

1965{
1966 LARGE_UNICODE_STRING WindowName;
1967 UNICODE_STRING ClassName;
1968 PWND pImeWnd;
1969 PIMEUI pimeui;
1970 CREATESTRUCTW Cs;
1973 HANDLE pid = PsGetThreadProcessId(pti->pEThread);
1974
1975 if (!(pti->spDefaultImc) && pid == gpidLogon)
1977
1978 if (!(pti->spDefaultImc) || IS_WND_IMELIKE(pwndTarget) || !(pti->rpdesk->pheapDesktop))
1979 return NULL;
1980
1981 if (IS_WND_CHILD(pwndTarget) && !(pwndTarget->style & WS_VISIBLE) &&
1982 pwndTarget->spwndParent->head.pti->ppi != pti->ppi)
1983 {
1984 return NULL;
1985 }
1986
1987 RtlInitLargeUnicodeString(&WindowName, L"Default IME", 0);
1988
1990 ClassName.Length = 0;
1991 ClassName.MaximumLength = 0;
1992
1993 UserRefObjectCo(pwndTarget, &Ref);
1994
1995 RtlZeroMemory(&Cs, sizeof(Cs));
1996 Cs.style = WS_POPUP | WS_DISABLED;
1997 Cs.hInstance = hInst;
1998 Cs.hwndParent = UserHMGetHandle(pwndTarget);
1999 Cs.lpszName = WindowName.Buffer;
2000 Cs.lpszClass = ClassName.Buffer;
2001
2002 // NOTE: LARGE_UNICODE_STRING is compatible to LARGE_STRING.
2003 pImeWnd = co_UserCreateWindowEx(&Cs, &ClassName, (PLARGE_STRING)&WindowName, NULL, WINVER);
2004 if (pImeWnd)
2005 {
2006 pimeui = ((PIMEWND)pImeWnd)->pimeui;
2007 _SEH2_TRY
2008 {
2009 ProbeForWrite(pimeui, sizeof(IMEUI), 1);
2010 pimeui->fDefault = TRUE;
2011 if (IS_WND_CHILD(pwndTarget) && pwndTarget->spwndParent->head.pti != pti)
2012 pimeui->fChildThreadDef = TRUE;
2013 }
2015 {
2016 NOTHING;
2017 }
2018 _SEH2_END;
2019 }
2020
2021 UserDerefObjectCo(pwndTarget);
2022 return pImeWnd;
2023}
#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:922
#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
#define NOTHING
Definition: input_list.c:10
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:689
DWORD style
Definition: ntuser.h:701
struct _WND * spwndParent
Definition: ntuser.h:708
LPCWSTR lpszClass
Definition: winuser.h:2955
LPCWSTR lpszName
Definition: winuser.h:2954
HINSTANCE hInstance
Definition: winuser.h:2946
UINT fDefault
Definition: ntuser.h:1247
UINT fChildThreadDef
Definition: ntuser.h:1248
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1055
#define WINVER
Definition: targetver.h:11
uint32_t ULONG_PTR
Definition: typedefs.h:65
PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData)
Definition: ime.c:1565
PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW *Cs, PUNICODE_STRING ClassName, PLARGE_STRING WindowName, PVOID acbiBuffer, DWORD dwVer)
Definition: window.c:2161
#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 139 of file ime.c.

140{
141 PIMEHOTKEY pNode;
142
143 if (!*ppList)
144 {
145 *ppList = pHotKey;
146 return;
147 }
148
149 for (pNode = *ppList; pNode; pNode = pNode->pNext)
150 {
151 if (!pNode->pNext)
152 {
153 pNode->pNext = pHotKey;
154 return;
155 }
156 }
157}
struct tagIMEHOTKEY * pNext
Definition: ime.c:48

Referenced by IntSetImeHotKey().

◆ IntAssociateInputContext()

HIMC FASTCALL IntAssociateInputContext ( PWND  pWnd,
PIMC  pImc 
)

Definition at line 511 of file ime.c.

512{
513 HIMC hOldImc = pWnd->hImc;
514 pWnd->hImc = (pImc ? UserHMGetHandle(pImc) : NULL);
515 return hOldImc;
516}
DWORD HIMC
Definition: dimm.idl:75
HIMC hImc
Definition: ntuser.h:735

Referenced by IntAssociateInputContextEx(), and IntDestroyInputContext().

◆ IntAssociateInputContextEx()

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

Definition at line 1643 of file ime.c.

1644{
1645 DWORD ret = 0;
1646 PWINDOWLIST pwl;
1647 BOOL bIgnoreNullImc = (dwFlags & IACE_IGNORENOCONTEXT);
1648 PTHREADINFO pti = pWnd->head.pti;
1649 PWND pwndTarget, pwndFocus = pti->MessageQueue->spwndFocus;
1650 HWND *phwnd;
1651 HIMC hIMC;
1652
1653 if (dwFlags & IACE_DEFAULT)
1654 {
1655 pIMC = pti->spDefaultImc;
1656 }
1657 else
1658 {
1659 if (pIMC && pti != pIMC->head.pti)
1660 return 2;
1661 }
1662
1663 if (pWnd->head.pti->ppi != GetW32ThreadInfo()->ppi ||
1664 (pIMC && pIMC->head.rpdesk != pWnd->head.rpdesk))
1665 {
1666 return 2;
1667 }
1668
1669 if ((dwFlags & IACE_CHILDREN) && pWnd->spwndChild)
1670 {
1672 if (pwl)
1673 {
1674 for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1675 {
1676 pwndTarget = ValidateHwndNoErr(*phwnd);
1677 if (!pwndTarget)
1678 continue;
1679
1680 hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1681 if (pwndTarget->hImc == hIMC || (bIgnoreNullImc && !pwndTarget->hImc))
1682 continue;
1683
1684 IntAssociateInputContext(pwndTarget, pIMC);
1685 if (pwndTarget == pwndFocus)
1686 ret = 1;
1687 }
1688
1689 IntFreeHwndList(pwl);
1690 }
1691 }
1692
1693 if (!bIgnoreNullImc || pWnd->hImc)
1694 {
1695 hIMC = (pIMC ? UserHMGetHandle(pIMC) : NULL);
1696 if (pWnd->hImc != hIMC)
1697 {
1698 IntAssociateInputContext(pWnd, pIMC);
1699 if (pWnd == pwndFocus)
1700 ret = 1;
1701 }
1702 }
1703
1704 return ret;
1705}
#define ValidateHwndNoErr(hwnd)
Definition: precomp.h:84
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IACE_IGNORENOCONTEXT
Definition: imm.h:583
#define IACE_DEFAULT
Definition: imm.h:582
#define IACE_CHILDREN
Definition: imm.h:581
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:801
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
THRDESKHEAD head
Definition: ntuser.h:690
struct _WND * spwndChild
Definition: ntuser.h:709
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:511
VOID FASTCALL IntFreeHwndList(PWINDOWLIST pwlTarget)
Definition: window.c:1459
PWINDOWLIST FASTCALL IntBuildHwndList(PWND pwnd, DWORD dwFlags, PTHREADINFO pti)
Definition: window.c:1413
#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 2388 of file ime.c.

2389{
2390 if (gfIMEShowStatus == bShow || !IS_IMM_MODE())
2391 return TRUE;
2392
2393 gfIMEShowStatus = bShow;
2394 IntNotifyImeShowStatus(pImeWnd);
2395 return TRUE;
2396}
#define IS_IMM_MODE()
Definition: ntuser.h:1232
BOOL gfIMEShowStatus
Definition: ime.c:44
VOID FASTCALL IntNotifyImeShowStatus(PWND pImeWnd)
Definition: ime.c:2331

Referenced by NtUserCallHwndParamLock().

◆ IntCheckImeHotKey()

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

Definition at line 289 of file ime.c.

290{
291 PIMEHOTKEY pHotKey;
292 UINT uModifiers;
293 BOOL bKeyUp = (lParam & 0x80000000);
294 const BYTE *KeyState = MessageQueue->afKeyState;
295 static UINT s_uKeyUpVKey = 0;
296
297 if (bKeyUp)
298 {
299 if (s_uKeyUpVKey != uVirtualKey)
300 {
301 s_uKeyUpVKey = 0;
302 return NULL;
303 }
304
305 s_uKeyUpVKey = 0;
306 }
307
308 uModifiers = 0;
309 if (IS_KEY_DOWN(KeyState, VK_LSHIFT)) uModifiers |= (MOD_SHIFT | MOD_LEFT);
310 if (IS_KEY_DOWN(KeyState, VK_RSHIFT)) uModifiers |= (MOD_SHIFT | MOD_RIGHT);
311 if (IS_KEY_DOWN(KeyState, VK_LCONTROL)) uModifiers |= (MOD_CONTROL | MOD_LEFT);
312 if (IS_KEY_DOWN(KeyState, VK_RCONTROL)) uModifiers |= (MOD_CONTROL | MOD_RIGHT);
313 if (IS_KEY_DOWN(KeyState, VK_LMENU)) uModifiers |= (MOD_ALT | MOD_LEFT);
314 if (IS_KEY_DOWN(KeyState, VK_RMENU)) uModifiers |= (MOD_ALT | MOD_RIGHT);
315
317 (uModifiers & MOD_KEYS),
318 (uModifiers & MOD_LEFT_RIGHT),
319 uVirtualKey);
320 if (pHotKey)
321 {
322 if (bKeyUp)
323 {
324 if (pHotKey->uModifiers & MOD_ON_KEYUP)
325 return pHotKey;
326 }
327 else
328 {
329 if (pHotKey->uModifiers & MOD_ON_KEYUP)
330 s_uKeyUpVKey = uVirtualKey;
331 else
332 return pHotKey;
333 }
334 }
335
336 return NULL;
337}
LPARAM lParam
Definition: combotst.c:139
#define MOD_LEFT
Definition: imm.h:323
#define MOD_ON_KEYUP
Definition: imm.h:326
#define MOD_ALT
Definition: imm.h:319
#define MOD_SHIFT
Definition: imm.h:321
#define MOD_CONTROL
Definition: imm.h:320
#define MOD_RIGHT
Definition: imm.h:324
unsigned int UINT
Definition: ndis.h:50
BYTE afKeyState[256 *2/8]
Definition: msgqueue.h:84
UINT uModifiers
Definition: ime.c:51
PIMEHOTKEY IntGetImeHotKeyByKey(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey)
Definition: ime.c:228
#define MOD_LEFT_RIGHT
Definition: ime.c:16
#define MOD_KEYS
Definition: ime.c:15
PIMEHOTKEY gpImeHotKeyList
Definition: ime.c:55
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:99
#define VK_RSHIFT
Definition: winuser.h:2273
#define VK_LSHIFT
Definition: winuser.h:2272
#define VK_LCONTROL
Definition: winuser.h:2274
#define VK_RCONTROL
Definition: winuser.h:2275
#define VK_RMENU
Definition: winuser.h:2277
#define VK_LMENU
Definition: winuser.h:2276
unsigned char BYTE
Definition: xxhash.c:193

Referenced by IntImmProcessKey(), and NtUserCheckImeHotKey().

◆ IntCheckImeShowStatus()

BOOL FASTCALL IntCheckImeShowStatus ( PWND  pwndIme,
PTHREADINFO  pti 
)

Definition at line 2136 of file ime.c.

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

Referenced by IntCheckImeShowStatusInThread(), and IntNotifyImeShowStatus().

◆ IntCheckImeShowStatusInThread()

VOID FASTCALL IntCheckImeShowStatusInThread ( PWND  pImeWnd)

Definition at line 2399 of file ime.c.

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

Referenced by NtUserCallHwndLock().

◆ IntDeleteImeHotKey()

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

Definition at line 204 of file ime.c.

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

Referenced by IntSetImeHotKey().

◆ IntDestroyInputContext()

BOOL IntDestroyInputContext ( PIMC  pIMC)

Definition at line 1503 of file ime.c.

1504{
1505 HIMC hIMC = UserHMGetHandle(pIMC);
1506 PTHREADINFO pti = pIMC->head.pti;
1507 PWND pwndChild;
1508 PWINDOWLIST pwl;
1509 HWND *phwnd;
1510 PWND pWnd;
1511
1512 if (pti != gptiCurrent)
1513 {
1515 return FALSE;
1516 }
1517
1518 if (pIMC == pti->spDefaultImc)
1519 {
1521 return FALSE;
1522 }
1523
1524 pwndChild = pti->rpdesk->pDeskInfo->spwnd->spwndChild;
1525 pwl = IntBuildHwndList(pwndChild, IACE_LIST | IACE_CHILDREN, pti);
1526 if (pwl)
1527 {
1528 for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
1529 {
1531 if (pWnd && pWnd->hImc == hIMC)
1533 }
1534
1535 IntFreeHwndList(pwl);
1536 }
1537
1539 return TRUE;
1540}
#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:28

Referenced by NtUserDestroyInputContext().

◆ IntFindNonImeRelatedWndOfSameThread()

BOOL IntFindNonImeRelatedWndOfSameThread ( PWND  pwndParent,
PWND  pwndTarget 
)

Definition at line 1848 of file ime.c.

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

Referenced by IntImeCanDestroyDefIMEforChild().

◆ IntFreeImeHotKeys()

VOID FASTCALL IntFreeImeHotKeys ( VOID  )

Definition at line 340 of file ime.c.

341{
342 PIMEHOTKEY pNode, pNext;
343 for (pNode = gpImeHotKeyList; pNode; pNode = pNext)
344 {
345 pNext = pNode->pNext;
347 }
349}

Referenced by IntSetImeHotKey(), and UserProcessDestroy().

◆ IntGetActiveKeyboardLayout()

HKL FASTCALL IntGetActiveKeyboardLayout ( VOID  )

Definition at line 98 of file ime.c.

99{
100 PTHREADINFO pti;
101
103 {
104 pti = gpqForeground->spwndActive->head.pti;
105 if (pti && pti->KeyboardLayout)
106 return pti->KeyboardLayout->hkl;
107 }
108
109 return UserGetKeyboardLayout(0);
110}
PUSER_MESSAGE_QUEUE gpqForeground
Definition: focus.c:13
struct tagKL * KeyboardLayout
Definition: win32.h:90
HKL FASTCALL UserGetKeyboardLayout(DWORD dwThreadId)
Definition: kbdlayout.c:857

Referenced by IntGetImeHotKeyByKey().

◆ IntGetImeCompatFlags()

DWORD FASTCALL IntGetImeCompatFlags ( PTHREADINFO  pti)

Definition at line 59 of file ime.c.

60{
61 if (!pti)
63
64 return pti->ppi->dwImeCompatFlags;
65}
DWORD dwImeCompatFlags
Definition: win32.h:276

Referenced by IntImmProcessKey().

◆ IntGetImeHotKeyById()

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

Definition at line 160 of file ime.c.

161{
162 PIMEHOTKEY pNode;
163 for (pNode = pList; pNode; pNode = pNode->pNext)
164 {
165 if (pNode->dwHotKeyId == dwHotKeyId)
166 return pNode;
167 }
168 return NULL;
169}
FxChildList * pList
DWORD dwHotKeyId
Definition: ime.c:49

Referenced by IntSetImeHotKey(), and NtUserGetImeHotKey().

◆ IntGetImeHotKeyByKey()

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

Definition at line 228 of file ime.c.

229{
230 PIMEHOTKEY pNode, ret = NULL;
232 LANGID LangId;
234 BOOL fKorean = (PRIMARYLANGID(LOWORD(hKL)) == LANG_KOREAN);
235 UINT nScore, nMaxScore = 0;
236
237 for (pNode = pList; pNode; pNode = pNode->pNext)
238 {
239 if (pNode->uVirtualKey != uVirtualKey)
240 continue;
241
242 if ((pNode->uModifiers & MOD_IGNORE_ALL_MODIFIER))
243 {
244 ;
245 }
246 else if ((pNode->uModifiers & MOD_KEYS) != uModKeys)
247 {
248 continue;
249 }
250 else if ((pNode->uModifiers & uLeftRight) ||
251 (pNode->uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
252 {
253 ;
254 }
255 else
256 {
257 continue;
258 }
259
260 LangId = IntGetImeHotKeyLangId(pNode->dwHotKeyId);
261 nScore = IntGetImeHotKeyLanguageScore(hKL, LangId);
262 if (nScore >= 3)
263 return pNode;
264
265 if (fKorean)
266 continue;
267
268 if (nScore == 0)
269 {
272 {
273 if (LOWORD(pti->hklPrev) == LangId)
274 return pNode;
275 }
276 }
277
278 if (nMaxScore < nScore)
279 {
280 nMaxScore = nScore;
281 ret = pNode;
282 }
283 }
284
285 return ret;
286}
#define IME_THOTKEY_IME_NONIME_TOGGLE
Definition: imm.h:343
#define MOD_IGNORE_ALL_MODIFIER
Definition: imm.h:327
#define IME_CHOTKEY_IME_NONIME_TOGGLE
Definition: imm.h:331
UINT_PTR HKL
Definition: msctf.idl:104
#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:50
WORD LANGID
Definition: typedefs.h:81
static LANGID FASTCALL IntGetImeHotKeyLangId(DWORD dwHotKeyId)
Definition: ime.c:113
UINT FASTCALL IntGetImeHotKeyLanguageScore(HKL hKL, LANGID HotKeyLangId)
Definition: ime.c:68
HKL FASTCALL IntGetActiveKeyboardLayout(VOID)
Definition: ime.c:98

Referenced by IntCheckImeHotKey().

◆ IntGetImeHotKeyByKeyAndLang()

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

Definition at line 173 of file ime.c.

175{
176 PIMEHOTKEY pNode;
178 UINT uModifiers;
179
180 for (pNode = pList; pNode; pNode = pNode->pNext)
181 {
182 if (pNode->uVirtualKey != uVirtualKey)
183 continue;
184
186 if (LangID != TargetLangId && LangID != 0)
187 continue;
188
189 uModifiers = pNode->uModifiers;
190 if (uModifiers & MOD_IGNORE_ALL_MODIFIER)
191 return pNode;
192
193 if ((uModifiers & MOD_KEYS) != uModKeys)
194 continue;
195
196 if ((uModifiers & uLeftRight) || (uModifiers & MOD_LEFT_RIGHT) == uLeftRight)
197 return pNode;
198 }
199
200 return NULL;
201}
_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 113 of file ime.c.

114{
115#define IME_CHOTKEY 0x10
116#define IME_JHOTKEY 0x30
117#define IME_KHOTKEY 0x50
118#define IME_THOTKEY 0x70
119#define IME_XHOTKEY 0x90
120 static const LANGID s_array[] =
121 {
122 /* 0x00 */ (WORD)-1,
123 /* 0x10 */ LANGID_CHINESE_SIMPLIFIED,
124 /* 0x20 */ LANGID_CHINESE_SIMPLIFIED,
125 /* 0x30 */ LANGID_JAPANESE,
126 /* 0x40 */ LANGID_JAPANESE,
127 /* 0x50 */ LANGID_KOREAN,
128 /* 0x60 */ LANGID_KOREAN,
131 };
132
133 if (IME_CHOTKEY <= dwHotKeyId && dwHotKeyId < IME_XHOTKEY)
134 return s_array[(dwHotKeyId & 0xF0) >> 4];
135 return LANGID_NEUTRAL;
136}
unsigned short WORD
Definition: ntddk_ex.h:93
#define LANGID_KOREAN
Definition: ime.c:20
#define LANGID_JAPANESE
Definition: ime.c:19
#define LANGID_CHINESE_SIMPLIFIED
Definition: ime.c:18
#define IME_XHOTKEY
#define LANGID_NEUTRAL
Definition: ime.c:22
#define IME_CHOTKEY
#define LANGID_CHINESE_TRADITIONAL
Definition: ime.c:21

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

◆ IntGetImeHotKeyLanguageScore()

UINT FASTCALL IntGetImeHotKeyLanguageScore ( HKL  hKL,
LANGID  HotKeyLangId 
)

Definition at line 68 of file ime.c.

69{
70 LCID lcid;
71
72 if (HotKeyLangId == LANGID_NEUTRAL || HotKeyLangId == LOWORD(hKL))
73 return 3;
74
76 {
77 lcid = NtCurrentTeb()->CurrentLocale;
78 }
80 {
82 }
84
85 if (HotKeyLangId == LANGIDFROMLCID(lcid))
86 return 2;
87
88 if (glcidSystem == 0)
90
91 if (HotKeyLangId == LANGIDFROMLCID(glcidSystem))
92 return 1;
93
94 return 0;
95}
#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:56

Referenced by IntGetImeHotKeyByKey().

◆ IntGetLastTopMostWindowNoIME()

PWND FASTCALL IntGetLastTopMostWindowNoIME ( PWND  pImeWnd)

Definition at line 1226 of file ime.c.

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

Referenced by IntImeSetTopMost().

◆ IntGetTopLevelWindow()

PWND FASTCALL IntGetTopLevelWindow ( PWND  pwnd)

Definition at line 499 of file ime.c.

500{
501 if (!pwnd)
502 return NULL;
503
504 while (pwnd->style & WS_CHILD)
505 pwnd = pwnd->spwndParent;
506
507 return pwnd;
508}
#define WS_CHILD
Definition: pedump.c:617

Referenced by NtUserSetImeOwnerWindow().

◆ IntImeCanDestroyDefIME()

BOOL FASTCALL IntImeCanDestroyDefIME ( PWND  pImeWnd,
PWND  pwndTarget 
)

Definition at line 2072 of file ime.c.

2073{
2074 PWND pwndNode;
2075 PIMEUI pimeui;
2076 IMEUI SafeImeUI;
2077
2078 pimeui = ((PIMEWND)pImeWnd)->pimeui;
2079 if (!pimeui || (LONG_PTR)pimeui == (LONG_PTR)-1)
2080 return FALSE;
2081
2082 // Check IMEUI.fDestroy
2083 _SEH2_TRY
2084 {
2085 ProbeForRead(pimeui, sizeof(IMEUI), 1);
2086 SafeImeUI = *pimeui;
2087 if (SafeImeUI.fDestroy)
2088 return FALSE;
2089 }
2091 {
2092 NOTHING;
2093 }
2094 _SEH2_END;
2095
2096 // Any ancestor of pImeWnd is pwndTarget?
2097 if (pImeWnd->spwndOwner)
2098 {
2099 for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndOwner)
2100 {
2101 if (pwndNode == pwndTarget)
2102 break;
2103 }
2104
2105 if (!pwndNode)
2106 return FALSE;
2107 }
2108
2109 // Any ancestor of pwndTarget is IME-like?
2110 for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndOwner)
2111 {
2112 if (IS_WND_IMELIKE(pwndNode))
2113 return FALSE;
2114 }
2115
2116 // Adjust the ordering and top-mode status
2117 IntImeSetFutureOwner(pImeWnd, pwndTarget);
2118 for (pwndNode = pImeWnd->spwndOwner; pwndNode; pwndNode = pwndNode->spwndNext)
2119 {
2120 if (pwndNode == pImeWnd)
2121 break;
2122 }
2123 if (pwndNode == pImeWnd)
2124 IntImeCheckTopmost(pImeWnd);
2125
2126 // Is the owner of pImeWnd NULL or pwndTarget?
2127 if (pImeWnd->spwndOwner && pwndTarget != pImeWnd->spwndOwner)
2128 return FALSE;
2129
2130 WndSetOwner(pImeWnd, NULL);
2131 return TRUE;
2132}
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:1246
#define LONG_PTR
Definition: treelist.c:79
VOID FASTCALL IntImeSetFutureOwner(PWND pImeWnd, PWND pwndOwner)
Definition: ime.c:1169
VOID FASTCALL IntImeCheckTopmost(PWND pImeWnd)
Definition: ime.c:1353
static VOID WndSetOwner(_Inout_ PWND pwnd, _In_opt_ PWND pwndOwner)
Definition: window.h:130

Referenced by co_UserDestroyWindow().

◆ IntImeCanDestroyDefIMEforChild()

BOOL FASTCALL IntImeCanDestroyDefIMEforChild ( PWND  pImeWnd,
PWND  pwndTarget 
)

Definition at line 2027 of file ime.c.

2028{
2029 PWND pwndNode;
2030 PIMEUI pimeui;
2031 IMEUI SafeImeUI;
2032
2033 pimeui = ((PIMEWND)pImeWnd)->pimeui;
2034 if (!pimeui || (LONG_PTR)pimeui == (LONG_PTR)-1)
2035 return FALSE;
2036
2037 // Check IMEUI.fChildThreadDef
2038 _SEH2_TRY
2039 {
2040 ProbeForRead(pimeui, sizeof(IMEUI), 1);
2041 SafeImeUI = *pimeui;
2042 if (!SafeImeUI.fChildThreadDef)
2043 return FALSE;
2044 }
2046 {
2047 NOTHING;
2048 }
2049 _SEH2_END;
2050
2051 // The parent of pwndTarget is NULL or of the same thread of pwndTarget?
2052 if (pwndTarget->spwndParent == NULL ||
2053 pwndTarget->head.pti == pwndTarget->spwndParent->head.pti)
2054 {
2055 return FALSE;
2056 }
2057
2058 for (pwndNode = pwndTarget; pwndNode; pwndNode = pwndNode->spwndParent)
2059 {
2060 if (pwndNode == pwndNode->head.rpdesk->pDeskInfo->spwnd)
2061 break;
2062
2063 if (IntFindNonImeRelatedWndOfSameThread(pwndNode->spwndParent, pwndTarget))
2064 return FALSE;
2065 }
2066
2067 return TRUE;
2068}
BOOL IntFindNonImeRelatedWndOfSameThread(PWND pwndParent, PWND pwndTarget)
Definition: ime.c:1848

Referenced by co_UserDestroyWindow().

◆ IntImeCheckTopmost()

VOID FASTCALL IntImeCheckTopmost ( PWND  pImeWnd)

Definition at line 1353 of file ime.c.

1354{
1355 BOOL bTopMost;
1356 PWND pwndOwner = pImeWnd->spwndOwner, pwndInsertBefore = NULL;
1357
1358 if (!pwndOwner)
1359 return;
1360
1361 if (pImeWnd->head.pti != gptiForeground)
1362 pwndInsertBefore = pwndOwner;
1363
1364 bTopMost = !!(pwndOwner->ExStyle & WS_EX_TOPMOST);
1365 IntImeSetTopMost(pImeWnd, bTopMost, pwndInsertBefore);
1366}
PTHREADINFO gptiForeground
Definition: focus.c:15
VOID FASTCALL IntImeSetTopMost(PWND pImeWnd, BOOL bTopMost, PWND pwndInsertBefore)
Definition: ime.c:1263

Referenced by IntImeCanDestroyDefIME(), and NtUserSetImeOwnerWindow().

◆ IntImeSetFutureOwner()

VOID FASTCALL IntImeSetFutureOwner ( PWND  pImeWnd,
PWND  pwndOwner 
)

Definition at line 1169 of file ime.c.

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

Referenced by IntImeCanDestroyDefIME(), and NtUserSetImeOwnerWindow().

◆ IntImeSetTopMost()

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

Definition at line 1263 of file ime.c.

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

Referenced by IntImeCheckTopmost().

◆ IntImmProcessKey()

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

Definition at line 582 of file ime.c.

584{
585 UINT uVirtualKey, ret = 0;
586 DWORD dwHotKeyId;
587 PKL pKL;
588 PIMC pIMC = NULL;
589 PIMEHOTKEY pImeHotKey;
590 HKL hKL;
591 HWND hWnd;
592
593 ASSERT_REFS_CO(pWnd);
594
595 switch (uMsg)
596 {
597 case WM_KEYDOWN:
598 case WM_KEYUP:
599 case WM_SYSKEYDOWN:
600 case WM_SYSKEYUP:
601 break;
602
603 default:
604 return 0;
605 }
606
607 hWnd = UserHMGetHandle(pWnd);
608 pKL = pWnd->head.pti->KeyboardLayout;
609 if (!pKL)
610 return 0;
611
612 uVirtualKey = LOBYTE(wParam);
613 pImeHotKey = IntCheckImeHotKey(MessageQueue, uVirtualKey, lParam);
614 if (pImeHotKey)
615 {
616 dwHotKeyId = pImeHotKey->dwHotKeyId;
617 hKL = pImeHotKey->hKL;
618 }
619 else
620 {
621 dwHotKeyId = INVALID_HOTKEY;
622 hKL = NULL;
623 }
624
625 if (IME_HOTKEY_DSWITCH_FIRST <= dwHotKeyId && dwHotKeyId <= IME_HOTKEY_DSWITCH_LAST)
626 {
627 if (pKL->hkl != hKL)
628 {
629 UserPostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST,
630 ((pKL->dwFontSigs & gSystemFS) ? INPUTLANGCHANGE_SYSCHARSET : 0),
631 (LPARAM)hKL);
632 }
633
634 if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
635 return 0;
636
637 return IPHK_HOTKEY;
638 }
639
640 if (!IS_IMM_MODE())
641 return 0;
642
643 if (dwHotKeyId == INVALID_HOTKEY)
644 {
645 if (!pKL->piiex)
646 return 0;
647
648 if (pWnd->hImc)
650 if (!pIMC)
651 return 0;
652
653 if ((lParam & 0x80000000) &&
655 {
656 return 0;
657 }
658
659 switch (uVirtualKey)
660 {
661 case VK_DBE_CODEINPUT:
664 case VK_DBE_HIRAGANA:
665 case VK_DBE_KATAKANA:
667 case VK_DBE_NOROMAN:
668 case VK_DBE_ROMAN:
669 break;
670
671 default:
672 {
673 if (uMsg == WM_SYSKEYDOWN || uMsg == WM_SYSKEYUP)
674 {
675 if (uVirtualKey != VK_MENU && uVirtualKey != VK_F10)
676 return 0;
677 }
678
680 {
681 if (uVirtualKey == VK_MENU || (lParam & 0x20000000))
682 return 0;
683 }
684 break;
685 }
686 }
687 }
688
689 if (LOBYTE(uVirtualKey) == VK_PACKET)
690 uVirtualKey = MAKELONG(wParam, GetW32ThreadInfo()->wchInjected);
691
692 ret = co_IntImmProcessKey(hWnd, pKL->hkl, uVirtualKey, lParam, dwHotKeyId);
693
694 if (IntGetImeCompatFlags(pWnd->head.pti) & 0x800000)
695 ret &= ~IPHK_HOTKEY;
696
697 return ret;
698}
HWND hWnd
Definition: settings.c:17
WPARAM wParam
Definition: combotst.c:138
#define IME_HOTKEY_DSWITCH_LAST
Definition: imm.h:349
#define IME_PROP_NEED_ALTKEY
Definition: imm.h:216
#define IME_HOTKEY_DSWITCH_FIRST
Definition: imm.h:348
#define IME_PROP_IGNORE_UPKEYS
Definition: imm.h:215
#define LOBYTE(W)
Definition: jmemdos.c:487
DWORD fdwProperty
Definition: imm.h:158
Definition: ntuser.h:199
HKL hKL
Definition: ime.c:52
IMEINFO ImeInfo
Definition: ntuser.h:1207
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 VK_DBE_ROMAN
Definition: ime.c:31
#define INVALID_HOTKEY
Definition: ime.c:14
#define VK_DBE_HIRAGANA
Definition: ime.c:28
#define VK_DBE_CODEINPUT
Definition: ime.c:36
#define VK_DBE_NOROMAN
Definition: ime.c:32
#define VK_DBE_KATAKANA
Definition: ime.c:27
#define VK_DBE_ENTERCONFIGMODE
Definition: ime.c:34
#define VK_DBE_ENTERWORDREGISTERMODE
Definition: ime.c:33
#define VK_DBE_NOCODEINPUT
Definition: ime.c:37
PIMEHOTKEY IntCheckImeHotKey(PUSER_MESSAGE_QUEUE MessageQueue, UINT uVirtualKey, LPARAM lParam)
Definition: ime.c:289
DWORD FASTCALL IntGetImeCompatFlags(PTHREADINFO pti)
Definition: ime.c:59
DWORD gSystemFS
Definition: kbdlayout.c:24
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1346
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:1706
#define VK_F10
Definition: winuser.h:2254
#define WM_SYSKEYUP
Definition: winuser.h:1710
#define WM_KEYDOWN
Definition: winuser.h:1705
#define WM_SYSKEYDOWN
Definition: winuser.h:1709
#define VK_MENU
Definition: winuser.h:2194

Referenced by co_IntProcessKeyboardMessage().

◆ IntNotifyImeShowStatus()

VOID FASTCALL IntNotifyImeShowStatus ( PWND  pImeWnd)

Definition at line 2331 of file ime.c.

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

Referenced by IntBroadcastImeShowStatusChange().

◆ IntSendMessageToUI()

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

Definition at line 2232 of file ime.c.

2233{
2234 PWND pwndUI;
2235 LRESULT ret = 0;
2236 IMEUI SafeImeUI;
2237 BOOL bDifferent = FALSE;
2239
2240 // Attach to the process if necessary
2241 if (ptiIME != GetW32ThreadInfo())
2242 {
2243 bDifferent = TRUE;
2244 KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2245 }
2246
2247 // Get the pwndUI
2248 _SEH2_TRY
2249 {
2250 ProbeForRead(pimeui, sizeof(IMEUI), 1);
2251 SafeImeUI = *pimeui;
2252 pwndUI = ValidateHwndNoErr(SafeImeUI.hwndUI);
2253 }
2255 {
2256 pwndUI = NULL;
2257 }
2258 _SEH2_END;
2259
2260 if (!pwndUI)
2261 goto Quit;
2262
2263 // Increment the recursion count of the IME procedure.
2264 // See also ImeWndProc_common of user32.
2265 _SEH2_TRY
2266 {
2267 ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1);
2269 }
2271 {
2272 goto Quit;
2273 }
2274 _SEH2_END;
2275
2276 // Detach from the process if necessary
2277 if (bDifferent)
2279
2280 UserRefObjectCo(pwndUI, &Ref);
2282 UserDerefObjectCo(pwndUI);
2283
2284 // Attach to the process if necessary
2285 if (bDifferent)
2286 KeAttachProcess(&(ptiIME->ppi->peProcess->Pcb));
2287
2288 // Decrement the recursion count of the IME procedure
2289 _SEH2_TRY
2290 {
2291 ProbeForWrite(&pimeui->nCntInIMEProc, sizeof(LONG), 1);
2293 }
2295 {
2296 goto Quit;
2297 }
2298 _SEH2_END;
2299
2300Quit:
2301 // Detach from the process if necessary
2302 if (bDifferent)
2304
2305 return ret;
2306}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
long LONG
Definition: pedump.c:60
HWND hwndUI
Definition: ntuser.h:1241
LONG nCntInIMEProc
Definition: ntuser.h:1242
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 2311 of file ime.c.

2312{
2314 PTHREADINFO ptiWnd = pWnd->head.pti;
2316
2317 if (ptiWnd->dwExpWinVer >= WINVER_WINNT4 && pWnd->hImc)
2318 {
2319 UserRefObjectCo(pWnd, &Ref);
2321 UserDerefObjectCo(pWnd);
2322 }
2323 else
2324 {
2325 IntSendMessageToUI(ptiIME, pimeui, WM_IME_NOTIFY, wParam, 0);
2326 }
2327}
#define IMN_OPENSTATUSWINDOW
Definition: imm.h:522
DWORD dwExpWinVer
Definition: win32.h:112
LRESULT FASTCALL IntSendMessageToUI(PTHREADINFO ptiIME, PIMEUI pimeui, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: ime.c:2232
#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 353 of file ime.c.

354{
355 PIMEHOTKEY pNode;
356 LANGID LangId;
357
358 switch (dwAction)
359 {
361 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); /* Find hotkey by ID */
362 if (!pNode)
363 {
364 ERR("dwHotKeyId: 0x%lX\n", dwHotKeyId);
365 return FALSE;
366 }
367
368 IntDeleteImeHotKey(&gpImeHotKeyList, pNode); /* Delete it */
369 return TRUE;
370
371 case SETIMEHOTKEY_ADD:
372 if (LOWORD(uVirtualKey) == VK_PACKET) /* In case of VK_PACKET */
373 return FALSE;
374
375 LangId = IntGetImeHotKeyLangId(dwHotKeyId);
376 if (LangId == LANGID_KOREAN)
377 return FALSE; /* Korean can't add IME hotkeys */
378
379 /* Find hotkey by key and language */
381 (uModifiers & MOD_KEYS),
382 (uModifiers & MOD_LEFT_RIGHT),
383 uVirtualKey, LangId);
384 if (pNode == NULL) /* If not found */
385 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId); /* Find by ID */
386
387 if (pNode) /* Already exists */
388 {
389 pNode->uModifiers = uModifiers;
390 pNode->uVirtualKey = uVirtualKey;
391 pNode->hKL = hKL;
392 return TRUE;
393 }
394
395 /* Allocate new hotkey */
397 if (!pNode)
398 return FALSE;
399
400 /* Populate */
401 pNode->pNext = NULL;
402 pNode->dwHotKeyId = dwHotKeyId;
403 pNode->uModifiers = uModifiers;
404 pNode->uVirtualKey = uVirtualKey;
405 pNode->hKL = hKL;
406 IntAddImeHotKey(&gpImeHotKeyList, pNode); /* Add it */
407 return TRUE;
408
410 IntFreeImeHotKeys(); /* Delete all the IME hotkeys */
411 return TRUE;
412
413 default:
414 ERR("0x%lX\n", dwAction);
415 return FALSE;
416 }
417}
#define ERR(fmt,...)
Definition: debug.h:110
#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:160
VOID FASTCALL IntFreeImeHotKeys(VOID)
Definition: ime.c:340
static VOID FASTCALL IntDeleteImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
Definition: ime.c:204
static VOID FASTCALL IntAddImeHotKey(PIMEHOTKEY *ppList, PIMEHOTKEY pHotKey)
Definition: ime.c:139
static PIMEHOTKEY APIENTRY IntGetImeHotKeyByKeyAndLang(PIMEHOTKEY pList, UINT uModKeys, UINT uLeftRight, UINT uVirtualKey, LANGID TargetLangId)
Definition: ime.c:173

Referenced by NtUserSetImeHotKey().

◆ IntWantImeWindow()

BOOL FASTCALL IntWantImeWindow ( PWND  pwndTarget)

Definition at line 1924 of file ime.c.

1925{
1926 PDESKTOP rpdesk;
1927 PWINSTATION_OBJECT rpwinstaParent;
1928 PWND pwndNode, pwndParent = pwndTarget->spwndParent;
1929
1931 return FALSE;
1932
1933 if (IS_WND_IMELIKE(pwndTarget))
1934 return FALSE;
1935
1936 if (pwndTarget->fnid == FNID_DESKTOP || pwndTarget->fnid == FNID_MESSAGEWND)
1937 return FALSE;
1938
1939 if (pwndTarget->state & WNDS_SERVERSIDEWINDOWPROC)
1940 return FALSE;
1941
1942 rpdesk = pwndTarget->head.rpdesk;
1943 if (!rpdesk)
1944 return FALSE;
1945
1946 rpwinstaParent = rpdesk->rpwinstaParent;
1947 if (!rpwinstaParent || (rpwinstaParent->Flags & WSS_NOIO))
1948 return FALSE;
1949
1950 for (pwndNode = pwndParent; pwndNode; pwndNode = pwndNode->spwndParent)
1951 {
1952 if (rpdesk != pwndNode->head.rpdesk)
1953 break;
1954
1955 if (pwndNode == rpdesk->spwndMessage)
1956 return FALSE;
1957 }
1958
1959 return TRUE;
1960}
#define FNID_DESKTOP
Definition: ntuser.h:857
#define WNDS_SERVERSIDEWINDOWPROC
Definition: ntuser.h:618
#define TIF_DISABLEIME
Definition: ntuser.h:287
#define FNID_MESSAGEWND
Definition: ntuser.h:859
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:704
DWORD state
Definition: ntuser.h:696
#define WSS_NOIO
Definition: winsta.h:9

Referenced by co_UserCreateWindowEx().

◆ NtUserAssociateInputContext()

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

Definition at line 1709 of file ime.c.

1710{
1711 DWORD ret = 2;
1712 PWND pWnd;
1713 PIMC pIMC;
1714
1716
1717 if (!IS_IMM_MODE())
1718 {
1719 ERR("!IS_IMM_MODE()\n");
1720 goto Quit;
1721 }
1722
1723 pWnd = ValidateHwndNoErr(hWnd);
1724 if (!pWnd)
1725 goto Quit;
1726
1727 pIMC = (hIMC ? UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT) : NULL);
1728 ret = IntAssociateInputContextEx(pWnd, pIMC, dwFlags);
1729
1730Quit:
1731 UserLeave();
1732 return ret;
1733}
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:254
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:245
DWORD FASTCALL IntAssociateInputContextEx(PWND pWnd, PIMC pIMC, DWORD dwFlags)
Definition: ime.c:1643

Referenced by ImmAssociateContext(), and ImmAssociateContextEx().

◆ NtUserBuildHimcList()

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

Definition at line 702 of file ime.c.

703{
705 DWORD dwRealCount;
706 PTHREADINFO pti;
707
709
710 if (!IS_IMM_MODE())
711 {
712 ERR("!IS_IMM_MODE()\n");
714 goto Quit;
715 }
716
717 if (dwThreadId == 0)
718 {
719 pti = gptiCurrent;
720 }
721 else if (dwThreadId == INVALID_THREAD_ID)
722 {
723 pti = NULL;
724 }
725 else
726 {
728 if (!pti || !pti->rpdesk)
729 goto Quit;
730 }
731
733 {
734 ProbeForWrite(phList, dwCount * sizeof(HIMC), 1);
735 ProbeForWrite(pdwCount, sizeof(DWORD), 1);
736 *pdwCount = dwRealCount = UserBuildHimcList(pti, dwCount, phList);
737 }
739 {
740 goto Quit;
741 }
742 _SEH2_END;
743
744 if (dwCount < dwRealCount)
746 else
748
749Quit:
750 UserLeave();
751 return ret;
752}
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:13
DWORD FASTCALL UserBuildHimcList(PTHREADINFO pti, DWORD dwCount, HIMC *phList)
Definition: ime.c:548
PTHREADINFO FASTCALL IntTID2PTI(HANDLE id)
Definition: misc.c:42

Referenced by Imm32BuildHimcList().

◆ NtUserCheckImeHotKey()

DWORD NTAPI NtUserCheckImeHotKey ( UINT  uVirtualKey,
LPARAM  lParam 
)

Definition at line 479 of file ime.c.

480{
481 PIMEHOTKEY pNode;
483
485
486 if (!gpqForeground || !IS_IMM_MODE())
487 goto Quit;
488
489 pNode = IntCheckImeHotKey(gpqForeground, uVirtualKey, lParam);
490 if (pNode)
491 ret = pNode->dwHotKeyId;
492
493Quit:
494 UserLeave();
495 return ret;
496}

◆ NtUserCreateInputContext()

HIMC NTAPI NtUserCreateInputContext ( ULONG_PTR  dwClientImcData)

Definition at line 1613 of file ime.c.

1614{
1615 PIMC pIMC;
1616 HIMC ret = NULL;
1617
1619
1620 if (!IS_IMM_MODE())
1621 {
1622 ERR("!IS_IMM_MODE()\n");
1624 goto Quit;
1625 }
1626
1627 if (!dwClientImcData)
1628 {
1630 goto Quit;
1631 }
1632
1633 pIMC = UserCreateInputContext(dwClientImcData);
1634 if (pIMC)
1635 ret = UserHMGetHandle(pIMC);
1636
1637Quit:
1638 UserLeave();
1639 return ret;
1640}

Referenced by ImmCreateContext().

◆ NtUserDestroyInputContext()

BOOL NTAPI NtUserDestroyInputContext ( HIMC  hIMC)

Definition at line 1542 of file ime.c.

1543{
1544 BOOL ret = FALSE;
1545 PIMC pIMC;
1546
1548
1549 if (!IS_IMM_MODE())
1550 {
1552 goto Quit;
1553 }
1554
1556 if (pIMC)
1558
1559Quit:
1560 UserLeave();
1561 return ret;
1562}
BOOL IntDestroyInputContext(PIMC pIMC)
Definition: ime.c:1503

Referenced by Imm32DestroyInputContext().

◆ NtUserDisableThreadIme()

BOOL NTAPI NtUserDisableThreadIme ( DWORD  dwThreadID)

Definition at line 863 of file ime.c.

865{
866 PTHREADINFO pti, ptiCurrent;
867 PPROCESSINFO ppi;
868 BOOL ret = FALSE;
869
871
872 if (!IS_IMM_MODE())
873 {
874 ERR("!IS_IMM_MODE()\n");
876 goto Quit;
877 }
878
879 ptiCurrent = GetW32ThreadInfo();
880
881 if (dwThreadID == INVALID_THREAD_ID)
882 {
883 ppi = ptiCurrent->ppi;
884 ppi->W32PF_flags |= W32PF_DISABLEIME;
885
886Retry:
887 for (pti = ppi->ptiList; pti; pti = pti->ptiSibling)
888 {
890
891 if (pti->spwndDefaultIme)
892 {
894 pti->spwndDefaultIme = NULL;
895 goto Retry; /* The contents of ppi->ptiList may be changed. */
896 }
897 }
898 }
899 else
900 {
901 if (dwThreadID == 0)
902 {
903 pti = ptiCurrent;
904 }
905 else
906 {
907 pti = IntTID2PTI(UlongToHandle(dwThreadID));
908
909 /* The thread needs to reside in the current process. */
910 if (!pti || pti->ppi != ptiCurrent->ppi)
911 goto Quit;
912 }
913
915
916 if (pti->spwndDefaultIme)
917 {
919 pti->spwndDefaultIme = NULL;
920 }
921 }
922
923 ret = TRUE;
924
925Quit:
926 UserLeave();
927 return ret;
928}
_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:2848
#define W32PF_DISABLEIME
Definition: win32.h:28

Referenced by ImmDisableIME().

◆ NtUserGetAppImeLevel()

DWORD NTAPI NtUserGetAppImeLevel ( HWND  hWnd)

Definition at line 932 of file ime.c.

933{
934 DWORD ret = 0;
935 PWND pWnd;
936 PTHREADINFO pti;
937
939
940 pWnd = ValidateHwndNoErr(hWnd);
941 if (!pWnd)
942 goto Quit;
943
944 if (!IS_IMM_MODE())
945 {
946 ERR("!IS_IMM_MODE()\n");
948 goto Quit;
949 }
950
952 if (pWnd->head.pti->ppi == pti->ppi)
954
955Quit:
956 UserLeave();
957 return ret;
958}
#define DWORD
Definition: nt_native.h:44
ATOM AtomImeLevel
Definition: ntuser.c:28
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:238
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 420 of file ime.c.

421{
422 PIMEHOTKEY pNode = NULL;
423
425
427 {
428 ProbeForWrite(lpuModifiers, sizeof(UINT), 1);
429 ProbeForWrite(lpuVirtualKey, sizeof(UINT), 1);
430 if (lphKL)
431 ProbeForWrite(lphKL, sizeof(HKL), 1);
432 }
434 {
435 goto Quit;
436 }
437 _SEH2_END;
438
439 pNode = IntGetImeHotKeyById(gpImeHotKeyList, dwHotKeyId);
440 if (!pNode)
441 goto Quit;
442
444 {
445 *lpuModifiers = pNode->uModifiers;
446 *lpuVirtualKey = pNode->uVirtualKey;
447 if (lphKL)
448 *lphKL = pNode->hKL;
449 }
451 {
452 pNode = NULL;
453 }
454 _SEH2_END;
455
456Quit:
457 UserLeave();
458 return !!pNode;
459}

Referenced by CliSetDefaultImeHotKeys(), and ImmGetHotKey().

◆ NtUserGetImeInfoEx()

BOOL NTAPI NtUserGetImeInfoEx ( PIMEINFOEX  pImeInfoEx,
IMEINFOEXCLASS  SearchType 
)

Definition at line 1019 of file ime.c.

1022{
1023 IMEINFOEX ImeInfoEx;
1024 BOOL ret = FALSE;
1025 PWINSTATION_OBJECT pWinSta;
1026
1028
1029 if (!IS_IMM_MODE())
1030 {
1031 ERR("!IS_IMM_MODE()\n");
1032 goto Quit;
1033 }
1034
1035 _SEH2_TRY
1036 {
1037 ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1);
1038 ImeInfoEx = *pImeInfoEx;
1039 }
1041 {
1042 goto Quit;
1043 }
1044 _SEH2_END;
1045
1047 ret = UserGetImeInfoEx(pWinSta, &ImeInfoEx, SearchType);
1048 if (!ret)
1049 goto Quit;
1050
1051 _SEH2_TRY
1052 {
1053 *pImeInfoEx = ImeInfoEx;
1054 }
1056 {
1057 ret = FALSE;
1058 }
1059 _SEH2_END;
1060
1061Quit:
1062 UserLeave();
1063 return ret;
1064}
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:962

Referenced by ImmGetImeInfoEx().

◆ NtUserNotifyIMEStatus()

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

Definition at line 814 of file ime.c.

815{
816 PWND pwnd;
817 PTHREADINFO pti;
818 HKL hKL;
819
821
822 if (!IS_IMM_MODE())
823 {
824 ERR("!IS_IMM_MODE()\n");
825 goto Quit;
826 }
827
828 pwnd = ValidateHwndNoErr(hwnd);
829 if (!pwnd)
830 goto Quit;
831
832 pti = pwnd->head.pti;
833 if (!pti || !gptiForeground)
834 goto Quit;
836 goto Quit;
837 if (ghIMC == pwnd->hImc && gfImeOpen == !!fOpen && gdwImeConversion == dwConversion)
838 goto Quit;
839
840 ghIMC = pwnd->hImc;
841 if (ghIMC)
842 {
843 gfImeOpen = !!fOpen;
844 gdwImeConversion = dwConversion;
845 UserSetImeConversionKeyState(pti, (fOpen ? dwConversion : IME_CMODE_ALPHANUMERIC));
846 }
847
848 if (ISITHOOKED(WH_SHELL))
849 {
850 hKL = (pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL);
851 co_HOOK_CallHooks(WH_SHELL, HSHELL_LANGUAGE, (WPARAM)hwnd, (LPARAM)hKL);
852 }
853
854 // TODO:
855
856Quit:
857 UserLeave();
858 return 0;
859}
#define ISITHOOKED(HookId)
Definition: hook.h:6
#define IME_CMODE_ALPHANUMERIC
Definition: imm.h:484
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1103
HIMC ghIMC
Definition: ime.c:41
DWORD gdwImeConversion
Definition: ime.c:43
static VOID FASTCALL UserSetImeConversionKeyState(PTHREADINFO pti, DWORD dwConversion)
Definition: ime.c:755
BOOL gfImeOpen
Definition: ime.c:42
_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 1798 of file ime.c.

1799{
1800 PIMC pIMC;
1801 PTHREADINFO ptiIMC;
1802 DWORD_PTR ret = 0;
1803
1805
1806 if (!IS_IMM_MODE())
1807 {
1808 ERR("!IS_IMM_MODE()\n");
1809 goto Quit;
1810 }
1811
1813 if (!pIMC)
1814 goto Quit;
1815
1816 ptiIMC = pIMC->head.pti;
1817
1818 switch (dwType)
1819 {
1820 case QIC_INPUTPROCESSID:
1821 ret = (DWORD_PTR)PsGetThreadProcessId(ptiIMC->pEThread);
1822 break;
1823
1824 case QIC_INPUTTHREADID:
1825 ret = (DWORD_PTR)PsGetThreadId(ptiIMC->pEThread);
1826 break;
1827
1829 if (ptiIMC->spwndDefaultIme)
1831 break;
1832
1833 case QIC_DEFAULTIMC:
1834 if (ptiIMC->spDefaultImc)
1836 break;
1837 }
1838
1839Quit:
1840 UserLeave();
1841 return ret;
1842}
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 CtfImmGetGuidAtom(), CtfImmIsGuidMapEnable(), Imm32CheckImcProcess(), Imm32GetImeMenuItemWInterProcess(), Imm32InternalLockIMC(), Imm32IsCrossThreadAccess(), Imm32MakeIMENotify(), ImmGetImeMenuItemsAW(), and ImmSetCompositionStringAW().

◆ NtUserSetAppImeLevel()

BOOL NTAPI NtUserSetAppImeLevel ( HWND  hWnd,
DWORD  dwLevel 
)

Definition at line 1068 of file ime.c.

1069{
1070 BOOL ret = FALSE;
1071 PWND pWnd;
1072 PTHREADINFO pti;
1073
1075
1076 if (!IS_IMM_MODE())
1077 {
1078 ERR("!IS_IMM_MODE()\n");
1080 goto Quit;
1081 }
1082
1083 pWnd = ValidateHwndNoErr(hWnd);
1084 if (!pWnd)
1085 goto Quit;
1086
1088 if (pWnd->head.pti->ppi == pti->ppi)
1089 ret = UserSetProp(pWnd, AtomImeLevel, (HANDLE)(ULONG_PTR)dwLevel, TRUE);
1090
1091Quit:
1092 UserLeave();
1093 return ret;
1094}

◆ NtUserSetImeHotKey()

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

Definition at line 463 of file ime.c.

469{
470 BOOL ret;
472 ret = IntSetImeHotKey(dwHotKeyId, uModifiers, uVirtualKey, hKL, dwAction);
473 UserLeave();
474 return ret;
475}
static BOOL APIENTRY IntSetImeHotKey(DWORD dwHotKeyId, UINT uModifiers, UINT uVirtualKey, HKL hKL, DWORD dwAction)
Definition: ime.c:353

Referenced by CliImmInitializeHotKeys(), and CliImmSetHotKeyWorker().

◆ NtUserSetImeInfoEx()

BOOL NTAPI NtUserSetImeInfoEx ( PIMEINFOEX  pImeInfoEx)

Definition at line 1134 of file ime.c.

1135{
1136 BOOL ret = FALSE;
1137 IMEINFOEX ImeInfoEx;
1138 PWINSTATION_OBJECT pWinSta;
1139
1141
1142 if (!IS_IMM_MODE())
1143 {
1144 ERR("!IS_IMM_MODE()\n");
1145 goto Quit;
1146 }
1147
1148 _SEH2_TRY
1149 {
1150 ProbeForRead(pImeInfoEx, sizeof(*pImeInfoEx), 1);
1151 ImeInfoEx = *pImeInfoEx;
1152 }
1154 {
1155 goto Quit;
1156 }
1157 _SEH2_END;
1158
1160 ret = UserSetImeInfoEx(pWinSta, &ImeInfoEx);
1161
1162Quit:
1163 UserLeave();
1164 return ret;
1165}
BOOL FASTCALL UserSetImeInfoEx(_Inout_ PWINSTATION_OBJECT pWinSta, _Inout_ PIMEINFOEX pImeInfoEx)
Definition: ime.c:1098

Referenced by Imm32LoadIME().

◆ NtUserSetImeOwnerWindow()

BOOL NTAPI NtUserSetImeOwnerWindow ( HWND  hImeWnd,
HWND  hwndFocus 
)

Definition at line 1369 of file ime.c.

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

Referenced by ImeWnd_OnImeSetContext().

◆ NtUserSetThreadLayoutHandles()

DWORD NTAPI NtUserSetThreadLayoutHandles ( HKL  hNewKL,
HKL  hOldKL 
)

Definition at line 520 of file ime.c.

521{
522 PTHREADINFO pti;
523 PKL pOldKL, pNewKL;
524
526
527 pti = GetW32ThreadInfo();
528 pOldKL = pti->KeyboardLayout;
529 if (pOldKL && pOldKL->hkl != hOldKL)
530 goto Quit;
531
532 pNewKL = UserHklToKbl(hNewKL);
533 if (!pNewKL)
534 goto Quit;
535
536 if (IS_IME_HKL(hNewKL) != IS_IME_HKL(hOldKL))
537 pti->hklPrev = hOldKL;
538
539 UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pNewKL);
540 pti->pClientInfo->hKL = pNewKL->hkl;
541
542Quit:
543 UserLeave();
544 return 0;
545}
#define IS_IME_HKL(hKL)
Definition: input.h:88
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:840

Referenced by ImmActivateLayout().

◆ NtUserUpdateInputContext()

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

Definition at line 1769 of file ime.c.

1773{
1774 PIMC pIMC;
1775 BOOL ret = FALSE;
1776
1778
1779 if (!IS_IMM_MODE())
1780 {
1781 ERR("!IS_IMM_MODE()\n");
1782 goto Quit;
1783 }
1784
1786 if (!pIMC)
1787 goto Quit;
1788
1789 ret = UserUpdateInputContext(pIMC, dwType, dwValue);
1790
1791Quit:
1792 UserLeave();
1793 return ret;
1794}
BOOL FASTCALL UserUpdateInputContext(PIMC pIMC, DWORD dwType, DWORD_PTR dwValue)
Definition: ime.c:1736

Referenced by ImmLockClientImc(), and User32SetImeWindowOfImc().

◆ UserBuildHimcList()

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

Definition at line 548 of file ime.c.

549{
550 PIMC pIMC;
551 DWORD dwRealCount = 0;
552
553 if (pti)
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 else
564 {
565 for (pti = gptiCurrent->ppi->ptiList; pti; pti = pti->ptiSibling)
566 {
567 for (pIMC = pti->spDefaultImc; pIMC; pIMC = pIMC->pImcNext)
568 {
569 if (dwRealCount < dwCount)
570 phList[dwRealCount] = UserHMGetHandle(pIMC);
571
572 ++dwRealCount;
573 }
574 }
575 }
576
577 return dwRealCount;
578}
struct tagIMC * pImcNext
Definition: ntuser.h:201

Referenced by NtUserBuildHimcList().

◆ UserCreateInputContext()

PIMC FASTCALL UserCreateInputContext ( ULONG_PTR  dwClientImcData)

Definition at line 1565 of file ime.c.

1566{
1567 PIMC pIMC;
1569 PDESKTOP pdesk = pti->rpdesk;
1570
1571 if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled?
1572 {
1573 ERR("IME is disabled\n");
1574 return NULL;
1575 }
1576
1577 if (!pdesk) // No desktop?
1578 return NULL;
1579
1580 // pti->spDefaultImc should be already set if non-first time.
1581 if (dwClientImcData && !pti->spDefaultImc)
1582 return NULL;
1583
1584 // Create an input context user object.
1585 pIMC = UserCreateObject(gHandleTable, pdesk, pti, NULL, TYPE_INPUTCONTEXT, sizeof(IMC));
1586 if (!pIMC)
1587 return NULL;
1588
1589 // Release the extra reference (UserCreateObject added 2 references).
1591 ASSERT(pIMC->head.cLockObj == 1);
1592
1593 if (dwClientImcData) // Non-first time.
1594 {
1595 // Insert pIMC to the second position (non-default) of the list.
1596 pIMC->pImcNext = pti->spDefaultImc->pImcNext;
1597 pti->spDefaultImc->pImcNext = pIMC;
1598 }
1599 else // First time. It's the default IMC.
1600 {
1601 // Add the first one (default) to the list.
1602 UserAssignmentLock((PVOID*)&pti->spDefaultImc, pIMC);
1603 pIMC->pImcNext = NULL;
1604 ASSERT(pIMC->head.cLockObj == 2); // UserAssignmentUnlock'ed at ExitThreadCallback
1605 }
1606
1607 pIMC->dwClientImcData = dwClientImcData; // Set it.
1608 return pIMC;
1609}
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 1491 of file ime.c.

1492{
1493 PIMC pIMC = Object;
1494 if (!pIMC)
1495 return TRUE;
1496
1499 return TRUE;
1500}
_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 1464 of file ime.c.

1465{
1466 PTHRDESKHEAD ObjHead = Object;
1467 PDESKTOP pDesk = ObjHead->rpdesk;
1468 PIMC pNode, pIMC = Object;
1469 PTHREADINFO pti;
1470
1471 if (!pIMC)
1472 return;
1473
1474 // Remove pIMC from the list except spDefaultImc
1475 pti = pIMC->head.pti;
1476 for (pNode = pti->spDefaultImc; pNode; pNode = pNode->pImcNext)
1477 {
1478 if (pNode->pImcNext == pIMC)
1479 {
1480 pNode->pImcNext = pIMC->pImcNext;
1481 break;
1482 }
1483 }
1484
1485 DesktopHeapFree(pDesk, Object);
1486
1487 pti->ppi->UserHandleCount--;
1489}
#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 962 of file ime.c.

966{
967 PKL pkl, pklHead;
968
969 if (!pWinSta || !gspklBaseLayout)
970 return FALSE;
971
972 pkl = pklHead = gspklBaseLayout;
973
974 /* Find the matching entry from the list and get info */
975 if (SearchType == ImeInfoExKeyboardLayout)
976 {
977 do
978 {
979 if (pInfoEx->hkl == pkl->hkl)
980 {
981 if (!pkl->piiex)
982 {
983 ERR("!pkl->piiex at %p\n", pkl->hkl);
984 break;
985 }
986
987 *pInfoEx = *pkl->piiex;
988 return TRUE;
989 }
990
991 pkl = pkl->pklNext;
992 } while (pkl != pklHead);
993 }
994 else if (SearchType == ImeInfoExImeFileName)
995 {
996 do
997 {
998 if (pkl->piiex &&
999 _wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile,
1000 RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0)
1001 {
1002 *pInfoEx = *pkl->piiex;
1003 return TRUE;
1004 }
1005
1006 pkl = pkl->pklNext;
1007 } while (pkl != pklHead);
1008 }
1009 else
1010 {
1011 ERR("SearchType: %d\n", SearchType);
1012 }
1013
1014 return FALSE;
1015}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
@ ImeInfoExImeFileName
Definition: ntuser.h:1228
@ ImeInfoExKeyboardLayout
Definition: ntuser.h:1225
_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: ntuser.h:1215
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 755 of file ime.c.

756{
757 HKL hKL;
759 LPBYTE KeyState;
760 BOOL bAlphaNumeric, bKatakana, bHiragana, bFullShape, bRoman, bCharCode;
761
762 if (!pti->KeyboardLayout)
763 return;
764
765 hKL = pti->KeyboardLayout->hkl;
766 LangID = LOWORD(hKL);
767 KeyState = pti->MessageQueue->afKeyState;
768
769 switch (PRIMARYLANGID(LangID))
770 {
771 case LANG_JAPANESE:
772 bAlphaNumeric = !(dwConversion & IME_CMODE_NATIVE);
773 bKatakana = !bAlphaNumeric && (dwConversion & IME_CMODE_KATAKANA);
774 bHiragana = !bAlphaNumeric && !(dwConversion & IME_CMODE_KATAKANA);
775 SET_KEY_DOWN(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
776 SET_KEY_LOCKED(KeyState, VK_DBE_ALPHANUMERIC, bAlphaNumeric);
777 SET_KEY_DOWN(KeyState, VK_DBE_HIRAGANA, bHiragana);
778 SET_KEY_LOCKED(KeyState, VK_DBE_HIRAGANA, bHiragana);
779 SET_KEY_DOWN(KeyState, VK_DBE_KATAKANA, bKatakana);
780 SET_KEY_LOCKED(KeyState, VK_DBE_KATAKANA, bKatakana);
781
782 bFullShape = (dwConversion & IME_CMODE_FULLSHAPE);
783 SET_KEY_DOWN(KeyState, VK_DBE_DBCSCHAR, bFullShape);
784 SET_KEY_LOCKED(KeyState, VK_DBE_DBCSCHAR, bFullShape);
785 SET_KEY_DOWN(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
786 SET_KEY_LOCKED(KeyState, VK_DBE_SBCSCHAR, !bFullShape);
787
788 bRoman = (dwConversion & IME_CMODE_ROMAN);
789 SET_KEY_DOWN(KeyState, VK_DBE_ROMAN, bRoman);
790 SET_KEY_LOCKED(KeyState, VK_DBE_ROMAN, bRoman);
791 SET_KEY_DOWN(KeyState, VK_DBE_NOROMAN, !bRoman);
792 SET_KEY_LOCKED(KeyState, VK_DBE_NOROMAN, !bRoman);
793
794 bCharCode = (dwConversion & IME_CMODE_CHARCODE);
795 SET_KEY_DOWN(KeyState, VK_DBE_CODEINPUT, bCharCode);
796 SET_KEY_LOCKED(KeyState, VK_DBE_CODEINPUT, bCharCode);
797 SET_KEY_DOWN(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
798 SET_KEY_LOCKED(KeyState, VK_DBE_NOCODEINPUT, !bCharCode);
799 break;
800
801 case LANG_KOREAN:
802 SET_KEY_LOCKED(KeyState, VK_HANGUL, (dwConversion & IME_CMODE_NATIVE));
803 SET_KEY_LOCKED(KeyState, VK_JUNJA, (dwConversion & IME_CMODE_FULLSHAPE));
804 SET_KEY_LOCKED(KeyState, VK_HANJA, (dwConversion & IME_CMODE_HANJACONVERT));
805 break;
806
807 default:
808 break;
809 }
810}
#define IME_CMODE_KATAKANA
Definition: imm.h:491
#define IME_CMODE_ROMAN
Definition: imm.h:494
#define IME_CMODE_NATIVE
Definition: imm.h:485
#define IME_CMODE_HANJACONVERT
Definition: imm.h:496
#define IME_CMODE_CHARCODE
Definition: imm.h:495
#define IME_CMODE_FULLSHAPE
Definition: imm.h:493
#define LANG_JAPANESE
Definition: nls.h:76
unsigned char * LPBYTE
Definition: typedefs.h:53
#define VK_DBE_DBCSCHAR
Definition: ime.c:30
#define VK_DBE_ALPHANUMERIC
Definition: ime.c:26
#define VK_DBE_SBCSCHAR
Definition: ime.c:29
#define SET_KEY_DOWN(ks, vk, down)
Definition: input.h:101
#define SET_KEY_LOCKED(ks, vk, down)
Definition: input.h:104
#define VK_HANGUL
Definition: winuser.h:2199
#define VK_JUNJA
Definition: winuser.h:2200
#define VK_HANJA
Definition: winuser.h:2202

Referenced by NtUserNotifyIMEStatus().

◆ UserSetImeInfoEx()

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

Definition at line 1098 of file ime.c.

1101{
1102 PKL pklHead, pkl;
1103
1104 if (!pWinSta || !gspklBaseLayout)
1105 return FALSE;
1106
1107 pkl = pklHead = gspklBaseLayout;
1108
1109 do
1110 {
1111 if (pkl->hkl != pImeInfoEx->hkl)
1112 {
1113 pkl = pkl->pklNext;
1114 continue;
1115 }
1116
1117 if (!pkl->piiex)
1118 {
1119 ERR("!pkl->piiex at %p\n", pkl->hkl);
1120 return FALSE;
1121 }
1122
1123 if (!pkl->piiex->fLoadFlag)
1124 *pkl->piiex = *pImeInfoEx;
1125
1126 return TRUE;
1127 } while (pkl != pklHead);
1128
1129 return FALSE;
1130}
INT fLoadFlag
Definition: ntuser.h:1211

Referenced by NtUserSetImeInfoEx().

◆ UserUpdateInputContext()

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

Definition at line 1736 of file ime.c.

1737{
1739 PTHREADINFO ptiIMC = pIMC->head.pti;
1740
1741 if (pti->ppi != ptiIMC->ppi) // Different process?
1742 return FALSE;
1743
1744 switch (dwType)
1745 {
1746 case UIC_CLIENTIMCDATA:
1747 if (pIMC->dwClientImcData)
1748 return FALSE; // Already set
1749
1750 pIMC->dwClientImcData = dwValue;
1751 break;
1752
1753 case UIC_IMEWINDOW:
1754 if (!ValidateHwndNoErr((HWND)dwValue))
1755 return FALSE; // Invalid HWND
1756
1757 pIMC->hImeWnd = (HWND)dwValue;
1758 break;
1759
1760 default:
1761 return FALSE;
1762 }
1763
1764 return TRUE;
1765}
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 43 of file ime.c.

Referenced by NtUserNotifyIMEStatus().

◆ gfImeOpen

BOOL gfImeOpen = (BOOL)-1

Definition at line 42 of file ime.c.

Referenced by NtUserNotifyIMEStatus().

◆ gfIMEShowStatus

BOOL gfIMEShowStatus = (BOOL)-1

◆ ghIMC

HIMC ghIMC = NULL

Definition at line 41 of file ime.c.

Referenced by NtUserNotifyIMEStatus().

◆ glcidSystem

LCID glcidSystem = 0

Definition at line 56 of file ime.c.

Referenced by IntGetImeHotKeyLanguageScore().

◆ gpImeHotKeyList

PIMEHOTKEY gpImeHotKeyList = NULL

Definition at line 55 of file ime.c.

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