ReactOS 0.4.15-dev-8145-ga541a46
keyboard.c File Reference
#include <win32k.h>
Include dependency graph for keyboard.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (UserKbd)
 
NTSTATUS NTAPI InitKeyboardImpl (VOID)
 
NTSTATUS APIENTRY IntKeyboardGetIndicatorTrans (HANDLE hKeyboardDevice, PKEYBOARD_INDICATOR_TRANSLATION *ppIndicatorTrans)
 
static NTSTATUS APIENTRY IntKeyboardUpdateLeds (HANDLE hKeyboardDevice, WORD wVk, WORD wScanCode)
 
VOID NTAPI UserInitKeyboard (HANDLE hKeyboardDevice)
 
static WORD IntSimplifyVk (WORD wVk)
 
static WORD IntFixVk (WORD wVk, BOOL bExt)
 
static WORD IntTranslateNumpadKey (WORD wVk)
 
static DWORD IntGetModBits (PKBDTABLES pKbdTbl, PBYTE pKeyState)
 
static BOOL IntTranslateChar (WORD wVirtKey, PBYTE pKeyState, PBOOL pbDead, PBOOL pbLigature, PWCHAR pwcTranslatedChar, PKBDTABLES pKbdTbl)
 
static int APIENTRY IntToUnicodeEx (UINT wVirtKey, UINT wScanCode, PBYTE pKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags, PKBDTABLES pKbdTbl)
 
static WORD FASTCALL IntVkToVsc (WORD wVk, PKBDTABLES pKbdTbl)
 
static WORD FASTCALL IntVscToVk (WORD wScanCode, PKBDTABLES pKbdTbl)
 
static WCHAR FASTCALL IntVkToChar (WORD wVk, PKBDTABLES pKbdTbl)
 
SHORT APIENTRY NtUserGetAsyncKeyState (INT Key)
 
static VOID NTAPI UpdateAsyncKeyState (WORD wVk, BOOL bIsDown)
 
static LRESULT co_CallLowLevelKeyboardHook (WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
 
static VOID SnapWindow (HWND hWnd)
 
static PKL FASTCALL IntGetNextKL (_In_ PKL pKL, _In_ BOOL bNext, _In_ BOOL bSameLang)
 
static VOID IntLanguageToggle (_In_ PUSER_MESSAGE_QUEUE pFocusQueue, _In_ BOOL bSameLang, _In_ INT nKeyState)
 
static BOOL IntCheckLanguageToggle (_In_ PUSER_MESSAGE_QUEUE pFocusQueue, _In_ BOOL bIsDown, _In_ WORD wVk, _Inout_ PINT pKeyState)
 
BOOL NTAPI ProcessKeyEvent (WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
 
BOOL NTAPI UserSendKeyboardInput (KEYBDINPUT *pKbdInput, BOOL bInjected)
 
VOID NTAPI UserProcessKeyboardInput (PKEYBOARD_INPUT_DATA pKbdInputData)
 
BOOL FASTCALL IntTranslateKbdMessage (LPMSG lpMsg, UINT flags)
 
static UINT IntMapVirtualKeyEx (UINT uCode, UINT Type, PKBDTABLES pKbdTbl)
 
UINT APIENTRY NtUserMapVirtualKeyEx (UINT uCode, UINT uType, DWORD keyboardId, HKL dwhkl)
 
int APIENTRY NtUserToUnicodeEx (UINT wVirtKey, UINT wScanCode, PBYTE pKeyStateUnsafe, LPWSTR pwszBuffUnsafe, INT cchBuff, UINT wFlags, HKL dwhkl)
 
DWORD APIENTRY NtUserGetKeyNameText (LONG lParam, LPWSTR lpString, int cchSize)
 
DWORD FASTCALL UserGetKeyboardType (DWORD dwTypeFlag)
 
DWORD APIENTRY NtUserVkKeyScanEx (WCHAR wch, HKL dwhkl, BOOL bUsehKL)
 

Variables

BYTE gafAsyncKeyState [256 *2/8]
 
static BYTE gafAsyncKeyStateRecentDown [256/8]
 
static PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL
 
static KEYBOARD_INDICATOR_PARAMETERS gIndicators = {0, 0}
 
KEYBOARD_ATTRIBUTES gKeyboardInfo
 
INT gLanguageToggleKeyState = 0
 
DWORD gdwLanguageToggleKey = 1
 
INT gLayoutToggleKeyState = 0
 
DWORD gdwLayoutToggleKey = 2
 

Function Documentation

◆ co_CallLowLevelKeyboardHook()

static LRESULT co_CallLowLevelKeyboardHook ( WORD  wVk,
WORD  wScanCode,
DWORD  dwFlags,
BOOL  bInjected,
DWORD  dwTime,
DWORD  dwExtraInfo 
)
static

Definition at line 689 of file keyboard.c.

690{
691 KBDLLHOOKSTRUCT KbdHookData;
692 UINT uMsg;
693
694 KbdHookData.vkCode = wVk;
695 KbdHookData.scanCode = wScanCode;
696 KbdHookData.flags = 0;
698 KbdHookData.flags |= LLKHF_EXTENDED;
700 KbdHookData.flags |= LLKHF_ALTDOWN;
702 KbdHookData.flags |= LLKHF_UP;
703 if (bInjected)
704 KbdHookData.flags |= LLKHF_INJECTED;
705 KbdHookData.time = dwTime;
706 KbdHookData.dwExtraInfo = dwExtraInfo;
707
708 /* Note: it doesnt support WM_SYSKEYUP */
710 uMsg = WM_KEYUP;
712 uMsg = WM_SYSKEYDOWN;
713 else
714 uMsg = WM_KEYDOWN;
715
716 return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, uMsg, (LPARAM)&KbdHookData);
717}
unsigned int UINT
Definition: ndis.h:50
LRESULT APIENTRY co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam)
Definition: hook.c:1102
DWORD dwTime
Definition: solitaire.cpp:27
ULONG_PTR dwExtraInfo
Definition: winuser.h:3812
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:101
BYTE gafAsyncKeyState[256 *2/8]
Definition: keyboard.c:13
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
LONG_PTR LPARAM
Definition: windef.h:208
#define WM_KEYUP
Definition: winuser.h:1716
#define LLKHF_EXTENDED
Definition: winuser.h:2645
#define VK_CONTROL
Definition: winuser.h:2203
#define HC_ACTION
Definition: winuser.h:48
#define LLKHF_ALTDOWN
Definition: winuser.h:2647
#define LLKHF_UP
Definition: winuser.h:2648
#define WH_KEYBOARD_LL
Definition: winuser.h:43
#define LLKHF_INJECTED
Definition: winuser.h:2646
#define KEYEVENTF_EXTENDEDKEY
Definition: winuser.h:1101
#define WM_KEYDOWN
Definition: winuser.h:1715
#define KEYEVENTF_KEYUP
Definition: winuser.h:1102
#define WM_SYSKEYDOWN
Definition: winuser.h:1719
#define VK_MENU
Definition: winuser.h:2204

Referenced by ProcessKeyEvent().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserKbd  )

◆ InitKeyboardImpl()

NTSTATUS NTAPI InitKeyboardImpl ( VOID  )

Definition at line 33 of file keyboard.c.

34{
37 // Clear and set default information.
39 gKeyboardInfo.KeyboardIdentifier.Type = 4; /* AT-101 */
40 gKeyboardInfo.NumberOfFunctionKeys = 12; /* We're doing an 101 for now, so return 12 F-keys */
41 return STATUS_SUCCESS;
42}
#define STATUS_SUCCESS
Definition: shellext.h:65
KEYBOARD_ID KeyboardIdentifier
Definition: ntddkbd.h:124
USHORT NumberOfFunctionKeys
Definition: ntddkbd.h:126
UCHAR Type
Definition: ntddkbd.h:101
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
KEYBOARD_ATTRIBUTES gKeyboardInfo
Definition: keyboard.c:17
static BYTE gafAsyncKeyStateRecentDown[256/8]
Definition: keyboard.c:14

Referenced by DriverEntry().

◆ IntCheckLanguageToggle()

static BOOL IntCheckLanguageToggle ( _In_ PUSER_MESSAGE_QUEUE  pFocusQueue,
_In_ BOOL  bIsDown,
_In_ WORD  wVk,
_Inout_ PINT  pKeyState 
)
static

Definition at line 852 of file keyboard.c.

857{
858 if (bIsDown) /* Toggle key combination is pressed? */
859 {
860 if (wVk == VK_LSHIFT)
861 *pKeyState = INPUTLANGCHANGE_FORWARD;
862 else if (wVk == VK_RSHIFT)
863 *pKeyState = INPUTLANGCHANGE_BACKWARD;
864 else if (!wVk && IS_KEY_DOWN(gafAsyncKeyState, VK_LSHIFT))
865 *pKeyState = INPUTLANGCHANGE_FORWARD;
866 else if (!wVk && IS_KEY_DOWN(gafAsyncKeyState, VK_RSHIFT))
867 *pKeyState = INPUTLANGCHANGE_BACKWARD;
868 else
869 return FALSE;
870 }
871 else
872 {
873 if (*pKeyState == 0)
874 return FALSE;
875
876 IntLanguageToggle(pFocusQueue, (pKeyState == &gLayoutToggleKeyState), *pKeyState);
877 *pKeyState = 0;
878 }
879 return TRUE;
880}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
INT gLayoutToggleKeyState
Definition: keyboard.c:20
static VOID IntLanguageToggle(_In_ PUSER_MESSAGE_QUEUE pFocusQueue, _In_ BOOL bSameLang, _In_ INT nKeyState)
Definition: keyboard.c:819
#define VK_RSHIFT
Definition: winuser.h:2283
#define VK_LSHIFT
Definition: winuser.h:2282

Referenced by ProcessKeyEvent().

◆ IntFixVk()

static WORD IntFixVk ( WORD  wVk,
BOOL  bExt 
)
static

Definition at line 249 of file keyboard.c.

250{
251 switch (wVk)
252 {
253 case VK_SHIFT:
254 return bExt ? VK_RSHIFT : VK_LSHIFT;
255
256 case VK_CONTROL:
257 return bExt ? VK_RCONTROL : VK_LCONTROL;
258
259 case VK_MENU:
260 return bExt ? VK_RMENU : VK_LMENU;
261
262 default:
263 return wVk;
264 }
265}
#define VK_LCONTROL
Definition: winuser.h:2284
#define VK_RCONTROL
Definition: winuser.h:2285
#define VK_RMENU
Definition: winuser.h:2287
#define VK_SHIFT
Definition: winuser.h:2202
#define VK_LMENU
Definition: winuser.h:2286

Referenced by IntMapVirtualKeyEx(), and ProcessKeyEvent().

◆ IntGetModBits()

static DWORD IntGetModBits ( PKBDTABLES  pKbdTbl,
PBYTE  pKeyState 
)
static

Definition at line 300 of file keyboard.c.

301{
302 DWORD i, dwModBits = 0;
303
304 /* DumpKeyState( KeyState ); */
305
306 for (i = 0; pKbdTbl->pCharModifiers->pVkToBit[i].Vk; i++)
307 if (IS_KEY_DOWN(pKeyState, pKbdTbl->pCharModifiers->pVkToBit[i].Vk))
308 dwModBits |= pKbdTbl->pCharModifiers->pVkToBit[i].ModBits;
309
310 TRACE("Current Mod Bits: %lx\n", dwModBits);
311
312 return dwModBits;
313}
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define TRACE(s)
Definition: solgame.cpp:4
PMODIFIERS pCharModifiers
Definition: kbd.h:96
PVK_TO_BIT pVkToBit
Definition: kbd.h:27
BYTE ModBits
Definition: kbd.h:23
BYTE Vk
Definition: kbd.h:22

Referenced by IntTranslateChar().

◆ IntGetNextKL()

static PKL FASTCALL IntGetNextKL ( _In_ PKL  pKL,
_In_ BOOL  bNext,
_In_ BOOL  bSameLang 
)
static

Definition at line 798 of file keyboard.c.

802{
803 PKL pFirstKL = pKL;
804 LANGID LangID = LOWORD(pKL->hkl);
805
806 do
807 {
808 pKL = (bNext ? pKL->pklNext : pKL->pklPrev);
809
810 if (!(pKL->dwKL_Flags & KLF_UNLOAD) && bSameLang == (LangID == LOWORD(pKL->hkl)))
811 return pKL;
812 } while (pKL != pFirstKL);
813
814 return pFirstKL;
815}
USHORT LANGID
Definition: mui.h:9
#define LOWORD(l)
Definition: pedump.c:82
Definition: input.h:27
_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
#define KLF_UNLOAD
Definition: input.h:51

Referenced by IntLanguageToggle().

◆ IntKeyboardGetIndicatorTrans()

NTSTATUS APIENTRY IntKeyboardGetIndicatorTrans ( HANDLE  hKeyboardDevice,
PKEYBOARD_INDICATOR_TRANSLATION ppIndicatorTrans 
)

Definition at line 52 of file keyboard.c.

54{
56 DWORD dwSize = 0;
57 IO_STATUS_BLOCK Block;
59
61
63 dwSize,
65
66 while (pRet)
67 {
68 Status = ZwDeviceIoControlFile(hKeyboardDevice,
69 NULL,
70 NULL,
71 NULL,
72 &Block,
74 NULL, 0,
75 pRet, dwSize);
76
78 break;
79
81
83
85 dwSize,
87 }
88
89 if (!pRet)
91
92 if (!NT_SUCCESS(Status))
93 {
95 return Status;
96 }
97
98 *ppIndicatorTrans = pRet;
99 return Status;
100}
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:25
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
struct _KEYBOARD_INDICATOR_TRANSLATION KEYBOARD_INDICATOR_TRANSLATION
#define IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION
Definition: ntddkbd.h:38
NTSYSAPI NTSTATUS NTAPI ZwDeviceIoControlFile(IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN PVOID UserApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, OUT PVOID OutputBuffer, IN ULONG OutputBufferSize)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define USERTAG_KBDTABLE
Definition: tags.h:247

Referenced by UserInitKeyboard().

◆ IntKeyboardUpdateLeds()

static NTSTATUS APIENTRY IntKeyboardUpdateLeds ( HANDLE  hKeyboardDevice,
WORD  wVk,
WORD  wScanCode 
)
static

Definition at line 109 of file keyboard.c.

112{
114 UINT i;
115 USHORT LedFlag = 0;
116 IO_STATUS_BLOCK Block;
117
120
121 switch (wVk)
122 {
123 case VK_CAPITAL: LedFlag = KEYBOARD_CAPS_LOCK_ON; break;
124 case VK_NUMLOCK: LedFlag = KEYBOARD_NUM_LOCK_ON; break;
125 case VK_SCROLL: LedFlag = KEYBOARD_SCROLL_LOCK_ON; break;
126 default:
128 {
130 {
132 break;
133 }
134 }
135 }
136
137 if (LedFlag)
138 {
139 gIndicators.LedFlags ^= LedFlag;
140
141 /* Update the lights on the hardware */
142 Status = ZwDeviceIoControlFile(hKeyboardDevice,
143 NULL,
144 NULL,
145 NULL,
146 &Block,
148 &gIndicators, sizeof(gIndicators),
149 NULL, 0);
150
151 return Status;
152 }
153
154 return STATUS_SUCCESS;
155}
#define KEYBOARD_CAPS_LOCK_ON
Definition: ntddkbd.h:81
#define IOCTL_KEYBOARD_SET_INDICATORS
Definition: ntddkbd.h:47
#define KEYBOARD_SCROLL_LOCK_ON
Definition: ntddkbd.h:83
#define KEYBOARD_NUM_LOCK_ON
Definition: ntddkbd.h:82
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
unsigned short USHORT
Definition: pedump.c:61
USHORT IndicatorFlags
Definition: ntddkbd.h:115
USHORT MakeCode
Definition: ntddkbd.h:114
INDICATOR_LIST IndicatorList[1]
Definition: ntddkbd.h:120
static KEYBOARD_INDICATOR_PARAMETERS gIndicators
Definition: keyboard.c:16
static PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans
Definition: keyboard.c:15
#define VK_CAPITAL
Definition: winuser.h:2206
#define VK_SCROLL
Definition: winuser.h:2280
#define VK_NUMLOCK
Definition: winuser.h:2279

Referenced by ProcessKeyEvent().

◆ IntLanguageToggle()

static VOID IntLanguageToggle ( _In_ PUSER_MESSAGE_QUEUE  pFocusQueue,
_In_ BOOL  bSameLang,
_In_ INT  nKeyState 
)
static

Definition at line 819 of file keyboard.c.

823{
824 PWND pWnd = pFocusQueue->spwndFocus;
825 HWND hWnd;
826 WPARAM wParam = 0;
827 PTHREADINFO pti;
828 PKL pkl;
829
830 if (!pWnd)
831 pWnd = pFocusQueue->spwndActive;
832 if (!pWnd)
833 return;
834
835 pti = pWnd->head.pti;
836 pkl = pti->KeyboardLayout;
837
838 if (nKeyState == INPUTLANGCHANGE_FORWARD)
839 pkl = IntGetNextKL(pkl, TRUE, bSameLang);
840 else if (nKeyState == INPUTLANGCHANGE_BACKWARD)
841 pkl = IntGetNextKL(pkl, FALSE, bSameLang);
842
843 if (gSystemFS & pkl->dwFontSigs)
844 wParam |= INPUTLANGCHANGE_SYSCHARSET;
845
846 hWnd = UserHMGetHandle(pWnd);
847 UserPostMessage(hWnd, WM_INPUTLANGCHANGEREQUEST, wParam, (LPARAM)pkl->hkl);
848}
HWND hWnd
Definition: settings.c:17
WPARAM wParam
Definition: combotst.c:138
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
struct tagKL * KeyboardLayout
Definition: win32.h:90
Definition: ntuser.h:694
THRDESKHEAD head
Definition: ntuser.h:695
DWORD dwFontSigs
Definition: input.h:34
HKL hkl
Definition: input.h:32
DWORD gSystemFS
Definition: kbdlayout.c:24
static PKL FASTCALL IntGetNextKL(_In_ PKL pKL, _In_ BOOL bNext, _In_ BOOL bSameLang)
Definition: keyboard.c:798
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1345
UINT_PTR WPARAM
Definition: windef.h:207

Referenced by IntCheckLanguageToggle().

◆ IntMapVirtualKeyEx()

static UINT IntMapVirtualKeyEx ( UINT  uCode,
UINT  Type,
PKBDTABLES  pKbdTbl 
)
static

Definition at line 1393 of file keyboard.c.

1394{
1395 UINT uRet = 0;
1396
1397 switch (Type)
1398 {
1399 case MAPVK_VK_TO_VSC:
1400 uCode = IntFixVk(uCode, FALSE);
1401 uRet = IntVkToVsc(uCode, pKbdTbl);
1402 if (uRet > 0xFF) // Fail for scancodes with prefix (e0, e1)
1403 uRet = 0;
1404 break;
1405
1406 case MAPVK_VSC_TO_VK:
1407 uRet = IntVscToVk(uCode, pKbdTbl) & 0xFF;
1408 uRet = IntSimplifyVk(uRet);
1409 break;
1410
1411 case MAPVK_VK_TO_CHAR:
1412 uRet = (UINT)IntVkToChar(uCode, pKbdTbl);
1413 break;
1414
1415 case MAPVK_VSC_TO_VK_EX:
1416 uRet = IntVscToVk(uCode, pKbdTbl) & 0xFF;
1417 break;
1418
1419 case MAPVK_VK_TO_VSC_EX:
1420 uRet = IntVkToVsc(uCode, pKbdTbl);
1421 break;
1422
1423 default:
1425 ERR("Wrong type value: %u\n", Type);
1426 }
1427
1428 return uRet;
1429}
Type
Definition: Type.h:7
#define ERR(fmt,...)
Definition: debug.h:113
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static WORD IntFixVk(WORD wVk, BOOL bExt)
Definition: keyboard.c:249
static WCHAR FASTCALL IntVkToChar(WORD wVk, PKBDTABLES pKbdTbl)
Definition: keyboard.c:607
static WORD FASTCALL IntVkToVsc(WORD wVk, PKBDTABLES pKbdTbl)
Definition: keyboard.c:527
static WORD FASTCALL IntVscToVk(WORD wScanCode, PKBDTABLES pKbdTbl)
Definition: keyboard.c:564
static WORD IntSimplifyVk(WORD wVk)
Definition: keyboard.c:221
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:22
#define MAPVK_VSC_TO_VK_EX
Definition: winuser.h:2358
#define MAPVK_VSC_TO_VK
Definition: winuser.h:2356
#define MAPVK_VK_TO_CHAR
Definition: winuser.h:2357
#define MAPVK_VK_TO_VSC
Definition: winuser.h:2355
#define MAPVK_VK_TO_VSC_EX
Definition: winuser.h:2359

Referenced by NtUserMapVirtualKeyEx().

◆ IntSimplifyVk()

static WORD IntSimplifyVk ( WORD  wVk)
static

Definition at line 221 of file keyboard.c.

222{
223 switch (wVk)
224 {
225 case VK_LSHIFT:
226 case VK_RSHIFT:
227 return VK_SHIFT;
228
229 case VK_LCONTROL:
230 case VK_RCONTROL:
231 return VK_CONTROL;
232
233 case VK_LMENU:
234 case VK_RMENU:
235 return VK_MENU;
236
237 default:
238 return wVk;
239 }
240}

Referenced by IntMapVirtualKeyEx(), and ProcessKeyEvent().

◆ IntToUnicodeEx()

static int APIENTRY IntToUnicodeEx ( UINT  wVirtKey,
UINT  wScanCode,
PBYTE  pKeyState,
LPWSTR  pwszBuff,
int  cchBuff,
UINT  wFlags,
PKBDTABLES  pKbdTbl 
)
static

Definition at line 434 of file keyboard.c.

441{
442 WCHAR wchTranslatedChar;
443 BOOL bDead, bLigature;
444 static WCHAR wchDead = 0;
445 int iRet = 0;
446
447 ASSERT(pKbdTbl);
448
449 if (!IntTranslateChar(wVirtKey,
450 pKeyState,
451 &bDead,
452 &bLigature,
453 &wchTranslatedChar,
454 pKbdTbl))
455 {
456 return 0;
457 }
458
459 if (bLigature)
460 {
461 WARN("Not handling ligature (yet)\n" );
462 return 0;
463 }
464
465 /* If we got dead char in previous call check dead keys in keyboard layout */
466 if (wchDead)
467 {
468 UINT i;
469 WCHAR wchFirst, wchSecond;
470 TRACE("Previous dead char: %lc (%x)\n", wchDead, wchDead);
471
472 if (pKbdTbl->pDeadKey)
473 {
474 for (i = 0; pKbdTbl->pDeadKey[i].dwBoth; i++)
475 {
476 wchFirst = pKbdTbl->pDeadKey[i].dwBoth >> 16;
477 wchSecond = pKbdTbl->pDeadKey[i].dwBoth & 0xFFFF;
478 if (wchFirst == wchDead && wchSecond == wchTranslatedChar)
479 {
480 wchTranslatedChar = pKbdTbl->pDeadKey[i].wchComposed;
481 wchDead = 0;
482 bDead = FALSE;
483 break;
484 }
485 }
486 }
487 else
488 {
489#if defined(__GNUC__)
490 if (wchDead == 0x8000)
491 {
492 ERR("GCC is inventing bits, ignoring fake dead key\n");
493 wchDead = 0;
494 }
495#endif
496 }
497
498 TRACE("Final char: %lc (%x)\n", wchTranslatedChar, wchTranslatedChar);
499 }
500
501 /* Dead char has not been not found */
502 if (wchDead)
503 {
504 /* Treat both characters normally */
505 if (cchBuff > iRet)
506 pwszBuff[iRet++] = wchDead;
507 bDead = FALSE;
508 }
509
510 /* Add character to the buffer */
511 if (cchBuff > iRet)
512 pwszBuff[iRet++] = wchTranslatedChar;
513
514 /* Save dead character */
515 wchDead = bDead ? wchTranslatedChar : 0;
516
517 return bDead ? -iRet : iRet;
518}
#define WARN(fmt,...)
Definition: debug.h:115
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ASSERT(a)
Definition: mode.c:44
WCHAR wchComposed
Definition: kbd.h:58
DWORD dwBoth
Definition: kbd.h:57
PDEADKEY pDeadKey
Definition: kbd.h:98
static BOOL IntTranslateChar(WORD wVirtKey, PBYTE pKeyState, PBOOL pbDead, PBOOL pbLigature, PWCHAR pwcTranslatedChar, PKBDTABLES pKbdTbl)
Definition: keyboard.c:322
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by IntTranslateKbdMessage(), and NtUserToUnicodeEx().

◆ IntTranslateChar()

static BOOL IntTranslateChar ( WORD  wVirtKey,
PBYTE  pKeyState,
PBOOL  pbDead,
PBOOL  pbLigature,
PWCHAR  pwcTranslatedChar,
PKBDTABLES  pKbdTbl 
)
static

Definition at line 322 of file keyboard.c.

328{
329 PVK_TO_WCHAR_TABLE pVkToVchTbl;
330 PVK_TO_WCHARS10 pVkToVch;
331 DWORD i, dwModBits, dwVkModBits, dwModNumber = 0;
332 WCHAR wch;
333 BOOL bAltGr;
334 WORD wCaplokAttr;
335
336 dwModBits = pKeyState ? IntGetModBits(pKbdTbl, pKeyState) : 0;
337 bAltGr = pKeyState && (pKbdTbl->fLocaleFlags & KLLF_ALTGR) && IS_KEY_DOWN(pKeyState, VK_RMENU);
338 wCaplokAttr = bAltGr ? CAPLOKALTGR : CAPLOK;
339
340 TRACE("TryToTranslate: %04x %x\n", wVirtKey, dwModBits);
341
342 /* If ALT without CTRL has ben used, remove ALT flag */
343 if ((dwModBits & (KBDALT|KBDCTRL)) == KBDALT)
344 dwModBits &= ~KBDALT;
345
346 if (dwModBits > pKbdTbl->pCharModifiers->wMaxModBits)
347 {
348 TRACE("dwModBits %x > wMaxModBits %x\n", dwModBits, pKbdTbl->pCharModifiers->wMaxModBits);
349 return FALSE;
350 }
351
352 for (i = 0; pKbdTbl->pVkToWcharTable[i].pVkToWchars; i++)
353 {
354 pVkToVchTbl = &pKbdTbl->pVkToWcharTable[i];
355 pVkToVch = (PVK_TO_WCHARS10)(pVkToVchTbl->pVkToWchars);
356 while (pVkToVch->VirtualKey)
357 {
358 if (wVirtKey == (pVkToVch->VirtualKey & 0xFF))
359 {
360 dwVkModBits = dwModBits;
361
362 /* If CapsLock is enabled for this key and locked, add SHIFT bit */
363 if ((pVkToVch->Attributes & wCaplokAttr) &&
364 pKeyState &&
365 IS_KEY_LOCKED(pKeyState, VK_CAPITAL))
366 {
367 /* Note: we use special value here instead of getting VK_SHIFT mod bit - it's verified */
368 dwVkModBits ^= KBDSHIFT;
369 }
370
371 if (dwVkModBits > pKbdTbl->pCharModifiers->wMaxModBits)
372 break;
373
374 /* Get modification number */
375 dwModNumber = pKbdTbl->pCharModifiers->ModNumber[dwVkModBits];
376 if (dwModNumber >= pVkToVchTbl->nModifications)
377 {
378 TRACE("dwModNumber %u >= nModifications %u\n", dwModNumber, pVkToVchTbl->nModifications);
379 break;
380 }
381
382 /* Read character */
383 wch = pVkToVch->wch[dwModNumber];
384 if (wch == WCH_NONE)
385 break;
386
387 *pbDead = (wch == WCH_DEAD);
388 *pbLigature = (wch == WCH_LGTR);
389 *pwcTranslatedChar = wch;
390
391 TRACE("%lu %04x: dwModNumber %08x Char %04x\n",
392 i, wVirtKey, dwModNumber, wch);
393
394 if (*pbDead)
395 {
396 /* After WCH_DEAD, real character is located */
397 pVkToVch = (PVK_TO_WCHARS10)(((BYTE *)pVkToVch) + pVkToVchTbl->cbSize);
398 if (pVkToVch->VirtualKey != 0xFF)
399 {
400 WARN("Found dead key with no trailer in the table.\n");
401 WARN("VK: %04x, ADDR: %p\n", wVirtKey, pVkToVch);
402 break;
403 }
404 *pwcTranslatedChar = pVkToVch->wch[dwModNumber];
405 }
406 return TRUE;
407 }
408 pVkToVch = (PVK_TO_WCHARS10)(((BYTE *)pVkToVch) + pVkToVchTbl->cbSize);
409 }
410 }
411
412 /* If nothing has been found in layout, check if this is ASCII control character.
413 Note: we could add it to layout table, but windows does not have it there */
414 if (wVirtKey >= 'A' && wVirtKey <= 'Z' &&
415 pKeyState && IS_KEY_DOWN(pKeyState, VK_CONTROL) &&
416 !IS_KEY_DOWN(pKeyState, VK_MENU))
417 {
418 *pwcTranslatedChar = (wVirtKey - 'A') + 1; /* ASCII control character */
419 *pbDead = FALSE;
420 *pbLigature = FALSE;
421 return TRUE;
422 }
423
424 return FALSE;
425}
unsigned short WORD
Definition: ntddk_ex.h:93
#define WCH_DEAD
Definition: kbd.h:114
#define CAPLOK
Definition: kbd.h:118
#define WCH_LGTR
Definition: kbd.h:115
#define KBDALT
Definition: kbd.h:16
#define WCH_NONE
Definition: kbd.h:113
#define CAPLOKALTGR
Definition: kbd.h:120
#define KBDCTRL
Definition: kbd.h:15
#define KLLF_ALTGR
Definition: kbd.h:91
#define KBDSHIFT
Definition: kbd.h:14
PVK_TO_WCHAR_TABLE pVkToWcharTable
Definition: kbd.h:97
DWORD fLocaleFlags
Definition: kbd.h:106
WORD wMaxModBits
Definition: kbd.h:28
BYTE ModNumber[]
Definition: kbd.h:29
BYTE cbSize
Definition: kbd.h:53
PVK_TO_WCHARS1 pVkToWchars
Definition: kbd.h:51
BYTE nModifications
Definition: kbd.h:52
#define IS_KEY_LOCKED(ks, vk)
Definition: input.h:102
static DWORD IntGetModBits(PKBDTABLES pKbdTbl, PBYTE pKeyState)
Definition: keyboard.c:300
unsigned char BYTE
Definition: xxhash.c:193

Referenced by IntToUnicodeEx(), and IntVkToChar().

◆ IntTranslateKbdMessage()

BOOL FASTCALL IntTranslateKbdMessage ( LPMSG  lpMsg,
UINT  flags 
)

Definition at line 1276 of file keyboard.c.

1278{
1279 PTHREADINFO pti;
1280 INT cch = 0, i;
1281 WCHAR wch[3] = { 0 };
1282 MSG NewMsg = { 0 };
1283 PKBDTABLES pKbdTbl;
1284 BOOL bResult = FALSE;
1285
1286 switch(lpMsg->message)
1287 {
1288 case WM_KEYDOWN:
1289 case WM_KEYUP:
1290 case WM_SYSKEYDOWN:
1291 case WM_SYSKEYUP:
1292 break;
1293 default:
1294 return FALSE;
1295 }
1296
1298
1299 if (!pti->KeyboardLayout)
1300 {
1301 PKL pDefKL = W32kGetDefaultKeyLayout();
1302 UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pDefKL);
1303 if (pDefKL)
1304 {
1305 pti->pClientInfo->hKL = pDefKL->hkl;
1306 pKbdTbl = pDefKL->spkf->pKbdTbl;
1307 }
1308 else
1309 {
1310 pti->pClientInfo->hKL = NULL;
1311 pKbdTbl = NULL;
1312 }
1313 }
1314 else
1315 pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
1316 if (!pKbdTbl)
1317 return FALSE;
1318
1319 if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
1320 return FALSE;
1321
1322 /* Init pt, hwnd and time msg fields */
1323 NewMsg.pt = gpsi->ptCursor;
1324 NewMsg.hwnd = lpMsg->hwnd;
1325 NewMsg.time = EngGetTickCount32();
1326
1327 TRACE("Enter IntTranslateKbdMessage msg %s, vk %x\n",
1328 lpMsg->message == WM_SYSKEYDOWN ? "WM_SYSKEYDOWN" : "WM_KEYDOWN", lpMsg->wParam);
1329
1330 if (lpMsg->wParam == VK_PACKET)
1331 {
1332 NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
1333 NewMsg.wParam = HIWORD(lpMsg->lParam);
1334 NewMsg.lParam = LOWORD(lpMsg->lParam);
1335 MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
1336 return TRUE;
1337 }
1338
1339 cch = IntToUnicodeEx(lpMsg->wParam,
1340 HIWORD(lpMsg->lParam) & 0xFF,
1341 pti->MessageQueue->afKeyState,
1342 wch,
1343 sizeof(wch) / sizeof(wch[0]),
1344 0,
1345 pKbdTbl);
1346
1347 if (cch)
1348 {
1349 if (cch > 0) /* Normal characters */
1350 NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
1351 else /* Dead character */
1352 {
1353 cch = -cch;
1354 NewMsg.message =
1356 }
1357 NewMsg.lParam = lpMsg->lParam;
1358
1359 /* Send all characters */
1360 for (i = 0; i < cch; ++i)
1361 {
1362 TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam);
1363 NewMsg.wParam = wch[i];
1364 MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
1365 }
1366 bResult = TRUE;
1367 }
1368
1369 TRACE("Leave IntTranslateKbdMessage ret %d, cch %d, msg %x, wch %x\n",
1370 bResult, cch, NewMsg.message, NewMsg.wParam);
1371 return bResult;
1372}
PSERVERINFO gpsi
Definition: imm.c:18
#define EngGetTickCount32()
Definition: eng.h:43
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
VOID FASTCALL MsqPostMessage(PTHREADINFO pti, MSG *Msg, BOOLEAN HardwareMessage, DWORD MessageBits, DWORD dwQEvent, LONG_PTR ExtraInfo)
Definition: msgqueue.c:1337
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
Definition: kbd.h:95
struct _CLIENTINFO * pClientInfo
Definition: win32.h:94
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
struct _KBDTABLES * pKbdTbl
Definition: input.h:21
PKBDFILE spkf
Definition: input.h:33
UINT message
Definition: winuser.h:3115
HWND hwnd
Definition: winuser.h:3114
WPARAM wParam
Definition: winuser.h:3116
LPARAM lParam
Definition: winuser.h:3117
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
PKL W32kGetDefaultKeyLayout(VOID)
Definition: kbdlayout.c:514
static int APIENTRY IntToUnicodeEx(UINT wVirtKey, UINT wScanCode, PBYTE pKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags, PKBDTABLES pKbdTbl)
Definition: keyboard.c:434
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
Definition: object.c:839
#define QS_KEY
Definition: winuser.h:874
#define WM_SYSCHAR
Definition: winuser.h:1721
#define WM_SYSDEADCHAR
Definition: winuser.h:1722
#define WM_SYSKEYUP
Definition: winuser.h:1720
#define WM_CHAR
Definition: winuser.h:1717
#define WM_DEADCHAR
Definition: winuser.h:1718

Referenced by DefWndDoSizeMove(), DefWndStartSizeMove(), MENU_TrackMenu(), and NtUserTranslateMessage().

◆ IntTranslateNumpadKey()

static WORD IntTranslateNumpadKey ( WORD  wVk)
static

Definition at line 274 of file keyboard.c.

275{
276 switch (wVk)
277 {
278 case VK_INSERT: return VK_NUMPAD0;
279 case VK_END: return VK_NUMPAD1;
280 case VK_DOWN: return VK_NUMPAD2;
281 case VK_NEXT: return VK_NUMPAD3;
282 case VK_LEFT: return VK_NUMPAD4;
283 case VK_CLEAR: return VK_NUMPAD5;
284 case VK_RIGHT: return VK_NUMPAD6;
285 case VK_HOME: return VK_NUMPAD7;
286 case VK_UP: return VK_NUMPAD8;
287 case VK_PRIOR: return VK_NUMPAD9;
288 case VK_DELETE: return VK_DECIMAL;
289 default: return wVk;
290 }
291}
#define VK_CLEAR
Definition: winuser.h:2200
#define VK_NUMPAD3
Definition: winuser.h:2242
#define VK_NUMPAD1
Definition: winuser.h:2240
#define VK_NUMPAD2
Definition: winuser.h:2241
#define VK_NUMPAD4
Definition: winuser.h:2243
#define VK_UP
Definition: winuser.h:2225
#define VK_NUMPAD0
Definition: winuser.h:2239
#define VK_NUMPAD6
Definition: winuser.h:2245
#define VK_NEXT
Definition: winuser.h:2221
#define VK_NUMPAD9
Definition: winuser.h:2248
#define VK_END
Definition: winuser.h:2222
#define VK_HOME
Definition: winuser.h:2223
#define VK_NUMPAD5
Definition: winuser.h:2244
#define VK_LEFT
Definition: winuser.h:2224
#define VK_NUMPAD7
Definition: winuser.h:2246
#define VK_RIGHT
Definition: winuser.h:2226
#define VK_DOWN
Definition: winuser.h:2227
#define VK_PRIOR
Definition: winuser.h:2220
#define VK_DELETE
Definition: winuser.h:2233
#define VK_NUMPAD8
Definition: winuser.h:2247
#define VK_DECIMAL
Definition: winuser.h:2253
#define VK_INSERT
Definition: winuser.h:2232

Referenced by UserProcessKeyboardInput().

◆ IntVkToChar()

static WCHAR FASTCALL IntVkToChar ( WORD  wVk,
PKBDTABLES  pKbdTbl 
)
static

Definition at line 607 of file keyboard.c.

608{
609 WCHAR wch;
610 BOOL bDead, bLigature;
611
612 ASSERT(pKbdTbl);
613
614 if (IntTranslateChar(wVk,
615 NULL,
616 &bDead,
617 &bLigature,
618 &wch,
619 pKbdTbl))
620 {
621 return wch;
622 }
623
624 return 0;
625}

Referenced by IntMapVirtualKeyEx(), and NtUserGetKeyNameText().

◆ IntVkToVsc()

static WORD FASTCALL IntVkToVsc ( WORD  wVk,
PKBDTABLES  pKbdTbl 
)
static

Definition at line 527 of file keyboard.c.

528{
529 unsigned i;
530
531 ASSERT(pKbdTbl);
532
533 /* Check standard keys first */
534 for (i = 0; i < pKbdTbl->bMaxVSCtoVK; i++)
535 {
536 if ((pKbdTbl->pusVSCtoVK[i] & 0xFF) == wVk)
537 return i;
538 }
539
540 /* Check extended keys now */
541 for (i = 0; pKbdTbl->pVSCtoVK_E0[i].Vsc; i++)
542 {
543 if ((pKbdTbl->pVSCtoVK_E0[i].Vk & 0xFF) == wVk)
544 return 0xE000 | pKbdTbl->pVSCtoVK_E0[i].Vsc;
545 }
546
547 for (i = 0; pKbdTbl->pVSCtoVK_E1[i].Vsc; i++)
548 {
549 if ((pKbdTbl->pVSCtoVK_E1[i].Vk & 0xFF) == wVk)
550 return 0xE100 | pKbdTbl->pVSCtoVK_E1[i].Vsc;
551 }
552
553 /* Virtual key has not been found */
554 return 0;
555}
BYTE bMaxVSCtoVK
Definition: kbd.h:103
USHORT * pusVSCtoVK
Definition: kbd.h:102
PVSC_VK pVSCtoVK_E0
Definition: kbd.h:104
PVSC_VK pVSCtoVK_E1
Definition: kbd.h:105
USHORT Vk
Definition: kbd.h:73
BYTE Vsc
Definition: kbd.h:72

Referenced by IntMapVirtualKeyEx().

◆ IntVscToVk()

static WORD FASTCALL IntVscToVk ( WORD  wScanCode,
PKBDTABLES  pKbdTbl 
)
static

Definition at line 564 of file keyboard.c.

565{
566 unsigned i;
567 WORD wVk = 0;
568
569 ASSERT(pKbdTbl);
570
571 if ((wScanCode & 0xFF00) == 0xE000)
572 {
573 for (i = 0; pKbdTbl->pVSCtoVK_E0[i].Vsc; i++)
574 {
575 if (pKbdTbl->pVSCtoVK_E0[i].Vsc == (wScanCode & 0xFF))
576 {
577 wVk = pKbdTbl->pVSCtoVK_E0[i].Vk;
578 }
579 }
580 }
581 else if ((wScanCode & 0xFF00) == 0xE100)
582 {
583 for (i = 0; pKbdTbl->pVSCtoVK_E1[i].Vsc; i++)
584 {
585 if (pKbdTbl->pVSCtoVK_E1[i].Vsc == (wScanCode & 0xFF))
586 {
587 wVk = pKbdTbl->pVSCtoVK_E1[i].Vk;
588 }
589 }
590 }
591 else if (wScanCode < pKbdTbl->bMaxVSCtoVK)
592 {
593 wVk = pKbdTbl->pusVSCtoVK[wScanCode];
594 }
595
596 /* 0xFF nad 0x00 are invalid VKs */
597 return wVk != 0xFF ? wVk : 0;
598}

Referenced by IntMapVirtualKeyEx(), NtUserGetKeyNameText(), UserProcessKeyboardInput(), and UserSendKeyboardInput().

◆ NtUserGetAsyncKeyState()

SHORT APIENTRY NtUserGetAsyncKeyState ( INT  Key)

Definition at line 634 of file keyboard.c.

635{
636 WORD wRet = 0;
637
638 TRACE("Enter NtUserGetAsyncKeyState\n");
639
640 if (Key >= 0x100 || Key < 0)
641 {
643 ERR("Invalid parameter Key\n");
644 return 0;
645 }
646
648
650 wRet |= 0x8000; // If down, windows returns 0x8000.
651 if (gafAsyncKeyStateRecentDown[Key / 8] & (1 << (Key % 8)))
652 wRet |= 0x1;
653 gafAsyncKeyStateRecentDown[Key / 8] &= ~(1 << (Key % 8));
654
655 UserLeave();
656
657 TRACE("Leave NtUserGetAsyncKeyState, ret=%u\n", wRet);
658 return wRet;
659}
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:251
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:242

Referenced by GetAsyncKeyState(), and START_TEST().

◆ NtUserGetKeyNameText()

DWORD APIENTRY NtUserGetKeyNameText ( LONG  lParam,
LPWSTR  lpString,
int  cchSize 
)

Definition at line 1584 of file keyboard.c.

1585{
1586 PTHREADINFO pti;
1587 DWORD i, dwRet = 0;
1588 SIZE_T cchKeyName;
1589 WORD wScanCode = (lParam >> 16) & 0xFF;
1590 BOOL bExtKey = (HIWORD(lParam) & KF_EXTENDED) ? TRUE : FALSE;
1591 PKBDTABLES pKbdTbl;
1592 VSC_LPWSTR *pKeyNames = NULL;
1593 CONST WCHAR *pKeyName = NULL;
1594 WCHAR KeyNameBuf[2];
1595
1596 TRACE("Enter NtUserGetKeyNameText\n");
1597
1599
1600 /* Get current keyboard layout */
1602 pKbdTbl = pti ? pti->KeyboardLayout->spkf->pKbdTbl : 0;
1603
1604 if (!pKbdTbl || cchSize < 1)
1605 {
1606 ERR("Invalid parameter\n");
1607 goto cleanup;
1608 }
1609
1610 /* "Do not care" flag */
1612 {
1613 /* Note: We could do vsc -> vk -> vsc conversion, instead of using
1614 hardcoded scan codes, but it's not what Windows does */
1615 if (wScanCode == SCANCODE_RSHIFT && !bExtKey)
1616 wScanCode = SCANCODE_LSHIFT;
1617 else if (wScanCode == SCANCODE_CTRL || wScanCode == SCANCODE_ALT)
1618 bExtKey = FALSE;
1619 }
1620
1621 if (bExtKey)
1622 pKeyNames = pKbdTbl->pKeyNamesExt;
1623 else
1624 pKeyNames = pKbdTbl->pKeyNames;
1625
1626 for (i = 0; pKeyNames[i].pwsz; i++)
1627 {
1628 if (pKeyNames[i].vsc == wScanCode)
1629 {
1630 pKeyName = pKeyNames[i].pwsz;
1631 break;
1632 }
1633 }
1634
1635 if (!pKeyName)
1636 {
1637 WORD wVk = IntVscToVk(wScanCode, pKbdTbl);
1638
1639 if (wVk)
1640 {
1641 KeyNameBuf[0] = IntVkToChar(wVk, pKbdTbl);
1642 KeyNameBuf[1] = 0;
1643 if (KeyNameBuf[0])
1644 pKeyName = KeyNameBuf;
1645 }
1646 }
1647
1648 if (pKeyName)
1649 {
1650 cchKeyName = wcslen(pKeyName);
1651 if (cchKeyName > (cchSize - 1UL))
1652 cchKeyName = cchSize - 1UL; // Don't count '\0'
1653
1654 _SEH2_TRY
1655 {
1656 ProbeForWrite(lpString, (cchKeyName + 1) * sizeof(WCHAR), 1);
1657 RtlCopyMemory(lpString, pKeyName, cchKeyName * sizeof(WCHAR));
1658 lpString[cchKeyName] = UNICODE_NULL;
1659 dwRet = cchKeyName;
1660 }
1662 {
1664 }
1665 _SEH2_END;
1666 }
1667 else
1668 {
1670 }
1671
1672cleanup:
1673 UserLeave();
1674 TRACE("Leave NtUserGetKeyNameText, ret=%lu\n", dwRet);
1675 return dwRet;
1676}
LPARAM lParam
Definition: combotst.c:139
static void cleanup(void)
Definition: main.c:1335
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define SCANCODE_LSHIFT
Definition: kbd.h:128
#define SCANCODE_ALT
Definition: kbd.h:131
#define SCANCODE_RSHIFT
Definition: kbd.h:129
#define SCANCODE_CTRL
Definition: kbd.h:130
#define UNICODE_NULL
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:235
#define CONST
Definition: pedump.c:81
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
VSC_LPWSTR * pKeyNamesExt
Definition: kbd.h:100
VSC_LPWSTR * pKeyNames
Definition: kbd.h:99
LPWSTR pwsz
Definition: kbd.h:68
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
VOID FASTCALL SetLastNtError(_In_ NTSTATUS Status)
Definition: error.c:31
#define LP_DO_NOT_CARE_BIT
Definition: input.h:59
#define KF_EXTENDED
Definition: winuser.h:2446

Referenced by GetKeyNameTextA(), and GetKeyNameTextW().

◆ NtUserMapVirtualKeyEx()

UINT APIENTRY NtUserMapVirtualKeyEx ( UINT  uCode,
UINT  uType,
DWORD  keyboardId,
HKL  dwhkl 
)

Definition at line 1439 of file keyboard.c.

1440{
1441 PKBDTABLES pKbdTbl = NULL;
1442 UINT ret = 0;
1443
1444 TRACE("Enter NtUserMapVirtualKeyEx\n");
1446
1447 if (!dwhkl)
1448 {
1449 PTHREADINFO pti;
1450
1452 if (pti && pti->KeyboardLayout)
1453 pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
1454 }
1455 else
1456 {
1457 PKL pKl;
1458
1459 pKl = UserHklToKbl(dwhkl);
1460 if (pKl)
1461 pKbdTbl = pKl->spkf->pKbdTbl;
1462 }
1463
1464 if (pKbdTbl)
1465 ret = IntMapVirtualKeyEx(uCode, uType, pKbdTbl);
1466
1467 UserLeave();
1468 TRACE("Leave NtUserMapVirtualKeyEx, ret=%u\n", ret);
1469 return ret;
1470}
int ret
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:541
static UINT IntMapVirtualKeyEx(UINT uCode, UINT Type, PKBDTABLES pKbdTbl)
Definition: keyboard.c:1393

Referenced by MapVirtualKeyExW().

◆ NtUserToUnicodeEx()

int APIENTRY NtUserToUnicodeEx ( UINT  wVirtKey,
UINT  wScanCode,
PBYTE  pKeyStateUnsafe,
LPWSTR  pwszBuffUnsafe,
INT  cchBuff,
UINT  wFlags,
HKL  dwhkl 
)

Definition at line 1479 of file keyboard.c.

1487{
1488 PTHREADINFO pti;
1489 BYTE afKeyState[256 * 2 / 8] = {0};
1490 PWCHAR pwszBuff = NULL;
1491 INT i, iRet = 0;
1492 PKL pKl = NULL;
1494
1495 TRACE("Enter NtUserSetKeyboardState\n");
1496
1497 /* Return 0 if SC_KEY_UP bit is set */
1498 if (wScanCode & SC_KEY_UP || wVirtKey >= 0x100)
1499 {
1500 ERR("Invalid parameter\n");
1501 return 0;
1502 }
1503
1504 _SEH2_TRY
1505 {
1506 /* Probe and copy key state to smaller bitmap */
1507 ProbeForRead(pKeyStateUnsafe, 256 * sizeof(BYTE), 1);
1508 for (i = 0; i < 256; ++i)
1509 {
1510 if (pKeyStateUnsafe[i] & KS_DOWN_BIT)
1511 SET_KEY_DOWN(afKeyState, i, TRUE);
1512 if (pKeyStateUnsafe[i] & KS_LOCK_BIT)
1513 SET_KEY_LOCKED(afKeyState, i, TRUE);
1514 }
1515 }
1517 {
1518 ERR("Cannot copy key state\n");
1520 _SEH2_YIELD(return 0);
1521 }
1522 _SEH2_END;
1523
1524 pwszBuff = ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR) * cchBuff, TAG_STRING);
1525 if (!pwszBuff)
1526 {
1527 ERR("ExAllocatePoolWithTag(%u) failed\n", sizeof(WCHAR) * cchBuff);
1528 return 0;
1529 }
1530 RtlZeroMemory(pwszBuff, sizeof(WCHAR) * cchBuff);
1531
1532 UserEnterExclusive(); // Note: We modify wchDead static variable
1533
1534 if (dwhkl)
1535 pKl = UserHklToKbl(dwhkl);
1536
1537 if (!pKl)
1538 {
1540 pKl = pti->KeyboardLayout;
1541 }
1542
1543 if (pKl)
1544 {
1545 iRet = IntToUnicodeEx(wVirtKey,
1546 wScanCode,
1547 afKeyState,
1548 pwszBuff,
1549 cchBuff,
1550 wFlags,
1551 pKl->spkf->pKbdTbl);
1552
1553 if (iRet)
1554 {
1555 Status = MmCopyToCaller(pwszBuffUnsafe, pwszBuff, cchBuff * sizeof(WCHAR));
1556 }
1557 }
1558 else
1559 {
1560 ERR("No keyboard layout ?!\n");
1562 }
1563
1564 ExFreePoolWithTag(pwszBuff, TAG_STRING);
1565
1566 if (!NT_SUCCESS(Status))
1567 {
1568 iRet = 0;
1570 }
1571
1572 UserLeave();
1573 TRACE("Leave NtUserSetKeyboardState, ret=%i\n", iRet);
1574 return iRet;
1575}
#define NonPagedPool
Definition: env_spec_w32.h:307
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define MmCopyToCaller(x, y, z)
Definition: mmcopy.h:19
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define TAG_STRING
Definition: oslist.h:22
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
uint16_t * PWCHAR
Definition: typedefs.h:56
#define SET_KEY_DOWN(ks, vk, down)
Definition: input.h:103
#define KS_DOWN_BIT
Definition: input.h:54
#define SC_KEY_UP
Definition: input.h:57
#define KS_LOCK_BIT
Definition: input.h:55
#define SET_KEY_LOCKED(ks, vk, down)
Definition: input.h:106
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531

◆ NtUserVkKeyScanEx()

DWORD APIENTRY NtUserVkKeyScanEx ( WCHAR  wch,
HKL  dwhkl,
BOOL  bUsehKL 
)

Definition at line 1709 of file keyboard.c.

1713{
1714 PKBDTABLES pKbdTbl;
1715 PVK_TO_WCHAR_TABLE pVkToWchTbl;
1716 PVK_TO_WCHARS10 pVkToWch;
1717 PKL pKl = NULL;
1718 DWORD i, dwModBits = 0, dwModNumber = 0, Ret = (DWORD)-1;
1719
1720 TRACE("NtUserVkKeyScanEx() wch %u, KbdLayout 0x%p\n", wch, dwhkl);
1722
1723 if (bUsehKL)
1724 {
1725 // Use given keyboard layout
1726 if (dwhkl)
1727 pKl = UserHklToKbl(dwhkl);
1728 }
1729 else
1730 {
1731 // Use thread keyboard layout
1732 pKl = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->KeyboardLayout;
1733 }
1734
1735 if (!pKl)
1736 goto Exit;
1737
1738 pKbdTbl = pKl->spkf->pKbdTbl;
1739
1740 // Interate through all VkToWchar tables while pVkToWchars is not NULL
1741 for (i = 0; pKbdTbl->pVkToWcharTable[i].pVkToWchars; i++)
1742 {
1743 pVkToWchTbl = &pKbdTbl->pVkToWcharTable[i];
1744 pVkToWch = (PVK_TO_WCHARS10)(pVkToWchTbl->pVkToWchars);
1745
1746 // Interate through all virtual keys
1747 while (pVkToWch->VirtualKey)
1748 {
1749 for (dwModNumber = 0; dwModNumber < pVkToWchTbl->nModifications; dwModNumber++)
1750 {
1751 if (pVkToWch->wch[dwModNumber] == wch)
1752 {
1753 dwModBits = pKbdTbl->pCharModifiers->ModNumber[dwModNumber];
1754 TRACE("i %lu wC %04x: dwModBits %08x dwModNumber %08x MaxModBits %08x\n",
1755 i, wch, dwModBits, dwModNumber, pKbdTbl->pCharModifiers->wMaxModBits);
1756 Ret = (dwModBits << 8) | (pVkToWch->VirtualKey & 0xFF);
1757 goto Exit;
1758 }
1759 }
1760 pVkToWch = (PVK_TO_WCHARS10)(((BYTE *)pVkToWch) + pVkToWchTbl->cbSize);
1761 }
1762 }
1763Exit:
1764 UserLeave();
1765 return Ret;
1766}
#define DWORD
Definition: nt_native.h:44
struct _THREADINFO * PTHREADINFO
Definition: ntwin32.h:6
static void Exit(void)
Definition: sock.c:1330

Referenced by VkKeyScanExW(), and VkKeyScanW().

◆ ProcessKeyEvent()

BOOL NTAPI ProcessKeyEvent ( WORD  wVk,
WORD  wScanCode,
DWORD  dwFlags,
BOOL  bInjected,
DWORD  dwTime,
DWORD  dwExtraInfo 
)

Definition at line 888 of file keyboard.c.

889{
890 WORD wSimpleVk = 0, wFixedVk, wVk2;
891 PUSER_MESSAGE_QUEUE pFocusQueue;
892 PTHREADINFO pti;
894 BOOL bIsDown = (dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
895 BOOL bPacket = (dwFlags & KEYEVENTF_UNICODE) ? TRUE : FALSE;
896 BOOL bWasSimpleDown = FALSE, bPostMsg = TRUE, bIsSimpleDown;
897 MSG Msg;
898 static BOOL bMenuDownRecently = FALSE;
899 BOOL bLangToggled = FALSE;
900
901 /* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
902 wSimpleVk = IntSimplifyVk(wVk);
903
905 {
906 /* Japanese special! */
908 {
909 if (wSimpleVk == VK_OEM_ATTN)
910 wSimpleVk = VK_CAPITAL;
911 else if (wSimpleVk == VK_OEM_COPY)
912 wSimpleVk = VK_OEM_FINISH;
913 }
914 }
915
916 bWasSimpleDown = IS_KEY_DOWN(gafAsyncKeyState, wSimpleVk);
917
918 /* Update key without shifts */
919 wVk2 = IntFixVk(wSimpleVk, !bExt);
920 bIsSimpleDown = bIsDown || IS_KEY_DOWN(gafAsyncKeyState, wVk2);
921 UpdateAsyncKeyState(wSimpleVk, bIsSimpleDown);
922
923 if (bIsDown)
924 {
925 /* Update keyboard LEDs */
927 wSimpleVk,
928 wScanCode);
929 }
930
931 /* Call WH_KEYBOARD_LL hook */
932 if (co_CallLowLevelKeyboardHook(wVk, wScanCode, dwFlags, bInjected, dwTime, dwExtraInfo))
933 {
934 ERR("Kbd msg dropped by WH_KEYBOARD_LL hook\n");
935 bPostMsg = FALSE;
936 }
937
938 /* Check if this is a hotkey */
939 if (co_UserProcessHotKeys(wSimpleVk, bIsDown))
940 {
941 TRACE("HotKey Processed\n");
942 bPostMsg = FALSE;
943 }
944
945 wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */
946 if (wSimpleVk == VK_SHIFT) /* shift can't be extended */
947 bExt = FALSE;
948
949 /* If we have a focus queue, post a keyboard message */
950 pFocusQueue = IntGetFocusMessageQueue();
951 TRACE("ProcessKeyEvent Q 0x%p Active pWnd 0x%p Focus pWnd 0x%p\n",
952 pFocusQueue,
953 (pFocusQueue ? pFocusQueue->spwndActive : 0),
954 (pFocusQueue ? pFocusQueue->spwndFocus : 0));
955
956 /* If it is F10 or ALT is down and CTRL is up, it's a system key */
957 if ( wVk == VK_F10 ||
958 (wSimpleVk == VK_MENU && bMenuDownRecently) ||
961 // See MSDN WM_SYSKEYDOWN/UP fixes last wine Win test_keyboard_input.
962 (pFocusQueue && !pFocusQueue->spwndFocus) )
963 {
964 bMenuDownRecently = FALSE; // reset
965 if (bIsDown)
966 {
967 Msg.message = WM_SYSKEYDOWN;
968 if (wSimpleVk == VK_MENU)
969 {
970 // Note: If only LALT is pressed WM_SYSKEYUP is generated instead of WM_KEYUP
971 bMenuDownRecently = TRUE;
972 }
973 }
974 else
975 Msg.message = WM_SYSKEYUP;
976 }
977 else
978 {
979 if (bIsDown)
980 Msg.message = WM_KEYDOWN;
981 else
982 Msg.message = WM_KEYUP;
983 }
984
985 /* Update async state of not simplified vk here.
986 See user32_apitest:GetKeyState */
987 UpdateAsyncKeyState(wFixedVk, bIsDown);
988
989 /* Alt-Tab/Esc Check. Use FocusQueue or RIT Queue */
990 if (bIsSimpleDown && !bWasSimpleDown &&
993 (wVk == VK_ESCAPE || wVk == VK_TAB))
994 {
995 TRACE("Alt-Tab/Esc Pressed wParam %x\n",wVk);
996 }
997
998 /*
999 * Check Language/Layout Toggle by [Left Alt]+Shift or Ctrl+Shift.
1000 * @see https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/cc976564%28v=technet.10%29
1001 */
1003 {
1004 if (wSimpleVk == VK_SHIFT) /* Shift key is pressed or released */
1005 {
1006 UINT targetKey = ((gdwLanguageToggleKey == 1) ? VK_LMENU : VK_CONTROL);
1007 if (IS_KEY_DOWN(gafAsyncKeyState, targetKey))
1008 bLangToggled = IntCheckLanguageToggle(pFocusQueue, bIsDown, wVk, &gLanguageToggleKeyState);
1009 }
1010 else if ((wSimpleVk == VK_MENU && gdwLanguageToggleKey == 1) ||
1011 (wSimpleVk == VK_CONTROL && gdwLanguageToggleKey == 2))
1012 {
1014 bLangToggled = IntCheckLanguageToggle(pFocusQueue, bIsDown, 0, &gLanguageToggleKeyState);
1015 }
1016 }
1017 if (!bLangToggled && (gdwLayoutToggleKey == 1 || gdwLayoutToggleKey == 2))
1018 {
1019 if (wSimpleVk == VK_SHIFT) /* Shift key is pressed or released */
1020 {
1021 UINT targetKey = ((gdwLayoutToggleKey == 1) ? VK_LMENU : VK_CONTROL);
1022 if (IS_KEY_DOWN(gafAsyncKeyState, targetKey))
1023 IntCheckLanguageToggle(pFocusQueue, bIsDown, wVk, &gLayoutToggleKeyState);
1024 }
1025 else if ((wSimpleVk == VK_MENU && gdwLayoutToggleKey == 1) ||
1026 (wSimpleVk == VK_CONTROL && gdwLayoutToggleKey == 2))
1027 {
1029 IntCheckLanguageToggle(pFocusQueue, bIsDown, 0, &gLayoutToggleKeyState);
1030 }
1031 }
1032
1033 if (bIsDown && wVk == VK_SNAPSHOT)
1034 {
1035 if (pFocusQueue &&
1038 {
1039 // Snap from Active Window, Focus can be null.
1040 SnapWindow(pFocusQueue->spwndActive ? UserHMGetHandle(pFocusQueue->spwndActive) : 0);
1041 }
1042 else
1043 SnapWindow(NULL); // Snap Desktop.
1044 }
1045 else if (pFocusQueue && bPostMsg)
1046 {
1047 PWND Wnd = pFocusQueue->spwndFocus; // SysInit.....
1048
1049 pti = pFocusQueue->ptiKeyboard;
1050
1051 if (!Wnd && pFocusQueue->spwndActive) // SysInit.....
1052 {
1053 // Going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input.
1054 Wnd = pFocusQueue->spwndActive;
1055 }
1056 if (Wnd) pti = Wnd->head.pti;
1057
1058 /* Init message */
1059 Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
1060 Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */
1061 Msg.lParam = MAKELPARAM(1, wScanCode);
1062 Msg.time = dwTime;
1063 Msg.pt = gpsi->ptCursor;
1064
1065 if ( Msg.message == WM_KEYDOWN || Msg.message == WM_SYSKEYDOWN )
1066 {
1067 if ( (Msg.wParam == VK_SHIFT ||
1068 Msg.wParam == VK_CONTROL ||
1069 Msg.wParam == VK_MENU ) &&
1071 {
1072 ERR("Set last input\n");
1073 //ptiLastInput = pti;
1074 }
1075 }
1076
1077 /* If it is VK_PACKET, high word of wParam is used for wchar */
1078 if (!bPacket)
1079 {
1080 if (bExt)
1081 Msg.lParam |= KF_EXTENDED << 16;
1083 Msg.lParam |= KF_ALTDOWN << 16;
1084 if (bWasSimpleDown)
1085 Msg.lParam |= KF_REPEAT << 16;
1086 if (!bIsDown)
1087 Msg.lParam |= KF_UP << 16;
1088 /* FIXME: Set KF_DLGMODE and KF_MENUMODE when needed */
1089 if (pFocusQueue->QF_flags & QF_DIALOGACTIVE)
1090 Msg.lParam |= KF_DLGMODE << 16;
1091 if (pFocusQueue->MenuOwner) // pti->pMenuState->fMenuStarted
1092 Msg.lParam |= KF_MENUMODE << 16;
1093 }
1094
1095 // Post mouse move before posting key buttons, to keep it syned.
1096 if (pFocusQueue->QF_flags & QF_MOUSEMOVED)
1097 {
1099 }
1100
1101 /* Post a keyboard message */
1102 TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
1103 if (!Wnd) {ERR("Window is NULL\n");}
1104 MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0, dwExtraInfo);
1105 }
1106 return TRUE;
1107}
struct @1638 Msg[]
VOID FASTCALL IntCoalesceMouseMove(PTHREADINFO pti)
Definition: msgqueue.c:551
#define QF_DIALOGACTIVE
Definition: msgqueue.h:106
#define QF_MOUSEMOVED
Definition: msgqueue.h:99
#define LANG_JAPANESE
Definition: nls.h:76
#define PRIMARYLANGID(l)
Definition: nls.h:16
PTHREADINFO ptiKeyboard
Definition: msgqueue.h:56
USHORT gusLanguageID
Definition: init.c:12
PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue(VOID)
Definition: desktop.c:1307
BOOL NTAPI co_UserProcessHotKeys(WORD wVk, BOOL bIsDown)
Definition: hotkey.c:177
HANDLE ghKeyboardDevice
Definition: input.c:19
static NTSTATUS APIENTRY IntKeyboardUpdateLeds(HANDLE hKeyboardDevice, WORD wVk, WORD wScanCode)
Definition: keyboard.c:109
static VOID SnapWindow(HWND hWnd)
Definition: keyboard.c:725
DWORD gdwLanguageToggleKey
Definition: keyboard.c:19
DWORD gdwLayoutToggleKey
Definition: keyboard.c:21
static BOOL IntCheckLanguageToggle(_In_ PUSER_MESSAGE_QUEUE pFocusQueue, _In_ BOOL bIsDown, _In_ WORD wVk, _Inout_ PINT pKeyState)
Definition: keyboard.c:852
static LRESULT co_CallLowLevelKeyboardHook(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
Definition: keyboard.c:689
static VOID NTAPI UpdateAsyncKeyState(WORD wVk, BOOL bIsDown)
Definition: keyboard.c:668
INT gLanguageToggleKeyState
Definition: keyboard.c:18
#define VK_SNAPSHOT
Definition: winuser.h:2231
#define VK_TAB
Definition: winuser.h:2199
#define MAKELPARAM(l, h)
Definition: winuser.h:4008
#define VK_F10
Definition: winuser.h:2264
#define KF_ALTDOWN
Definition: winuser.h:2449
#define VK_OEM_FINISH
Definition: winuser.h:2339
#define KF_UP
Definition: winuser.h:2451
#define KF_MENUMODE
Definition: winuser.h:2448
#define VK_OEM_ATTN
Definition: winuser.h:2338
#define VK_OEM_COPY
Definition: winuser.h:2340
#define KF_REPEAT
Definition: winuser.h:2450
#define VK_ESCAPE
Definition: winuser.h:2214
#define KF_DLGMODE
Definition: winuser.h:2447

Referenced by UserSendKeyboardInput().

◆ SnapWindow()

static VOID SnapWindow ( HWND  hWnd)
static

Definition at line 725 of file keyboard.c.

726{
727 HBITMAP hbm = NULL, hbmOld;
728 HDC hdc = NULL, hdcMem;
729 SETCLIPBDATA scd;
730 INT cx, cy;
731 PWND pWnd = NULL;
732
733 TRACE("SnapWindow(%p)\n", hWnd);
734
735 /* If no windows is given, make snapshot of desktop window */
736 if (!hWnd)
738
740 if (!pWnd)
741 {
742 ERR("Invalid window\n");
743 goto cleanup;
744 }
745
747 if (!hdc)
748 {
749 ERR("UserGetDCEx failed!\n");
750 goto cleanup;
751 }
752
753 cx = pWnd->rcWindow.right - pWnd->rcWindow.left;
754 cy = pWnd->rcWindow.bottom - pWnd->rcWindow.top;
755
757 if (!hbm)
758 {
759 ERR("NtGdiCreateCompatibleBitmap failed!\n");
760 goto cleanup;
761 }
762
764 if (!hdcMem)
765 {
766 ERR("NtGdiCreateCompatibleDC failed!\n");
767 goto cleanup;
768 }
769
770 hbmOld = NtGdiSelectBitmap(hdcMem, hbm);
771 NtGdiBitBlt(hdcMem, 0, 0, cx, cy, hdc, 0, 0, SRCCOPY, 0, 0);
772 NtGdiSelectBitmap(hdcMem, hbmOld);
774
775 /* Save snapshot in clipboard */
777 {
780 scd.fGlobalHandle = FALSE;
782 {
783 /* Bitmap is managed by system now */
784 hbm = NULL;
785 }
787 }
788
789cleanup:
790 if (hbm)
792 if (hdc)
793 UserReleaseDC(pWnd, hdc, FALSE);
794}
#define DCX_USESTYLE
Definition: GetDCEx.c:10
#define CF_BITMAP
Definition: constants.h:397
BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL)
Definition: dclife.c:892
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:92
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiCreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
__kernel_entry W32KAPI HDC APIENTRY NtGdiCreateCompatibleDC(_In_opt_ HDC hdc)
__kernel_entry W32KAPI BOOL APIENTRY NtGdiBitBlt(_In_ HDC hdcDst, _In_ INT x, _In_ INT y, _In_ INT cx, _In_ INT cy, _In_opt_ HDC hdcSrc, _In_ INT xSrc, _In_ INT ySrc, _In_ DWORD rop4, _In_ DWORD crBackColor, _In_ FLONG fl)
__kernel_entry W32KAPI HBITMAP APIENTRY NtGdiSelectBitmap(_In_ HDC hdc, _In_ HBITMAP hbm)
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
RECT rcWindow
Definition: ntuser.h:716
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
BOOL fIncSerialNumber
Definition: ntuser.h:1169
BOOL fGlobalHandle
Definition: ntuser.h:1168
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:122
INT FASTCALL UserReleaseDC(PWND Window, HDC hDc, BOOL EndPaint)
Definition: windc.c:918
HDC FASTCALL UserGetDCEx(PWND Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
HDC hdcMem
Definition: welcome.c:104
BOOL NTAPI GreDeleteObject(HGDIOBJ hobj)
Definition: gdiobj.c:1158
BOOL NTAPI UserEmptyClipboard(VOID)
Definition: clipboard.c:680
BOOL NTAPI UserCloseClipboard(VOID)
Definition: clipboard.c:545
BOOL NTAPI UserOpenClipboard(HWND hWnd)
Definition: clipboard.c:488
HANDLE NTAPI UserSetClipboardData(UINT fmt, HANDLE hData, PSETCLIPBDATA scd)
Definition: clipboard.c:1023
HWND FASTCALL IntGetDesktopWindow(VOID)
Definition: desktop.c:1374
#define SRCCOPY
Definition: wingdi.h:333
#define DCX_WINDOW
Definition: winuser.h:2113

Referenced by ProcessKeyEvent().

◆ UpdateAsyncKeyState()

static VOID NTAPI UpdateAsyncKeyState ( WORD  wVk,
BOOL  bIsDown 
)
static

Definition at line 668 of file keyboard.c.

669{
670 if (bIsDown)
671 {
672 /* If it's first key down event, xor lock bit */
673 if (!IS_KEY_DOWN(gafAsyncKeyState, wVk))
675
677 gafAsyncKeyStateRecentDown[wVk / 8] |= (1 << (wVk % 8));
678 }
679 else
681}

Referenced by ProcessKeyEvent().

◆ UserGetKeyboardType()

DWORD FASTCALL UserGetKeyboardType ( DWORD  dwTypeFlag)

Definition at line 1684 of file keyboard.c.

1686{
1687 switch (dwTypeFlag)
1688 {
1689 case 0: /* Keyboard type */
1691 case 1: /* Keyboard Subtype */
1693 case 2: /* Number of F-keys */
1695 default:
1696 ERR("Unknown type!\n");
1697 return 0; /* Note: we don't have to set last error here */
1698 }
1699}
UCHAR Subtype
Definition: ntddkbd.h:102

Referenced by NtUserCallOneParam().

◆ UserInitKeyboard()

VOID NTAPI UserInitKeyboard ( HANDLE  hKeyboardDevice)

Definition at line 163 of file keyboard.c.

164{
166 IO_STATUS_BLOCK Block;
167
169
170 Status = ZwDeviceIoControlFile(hKeyboardDevice,
171 NULL,
172 NULL,
173 NULL,
174 &Block,
176 NULL, 0,
178 sizeof(gIndicators));
179
180 if (!NT_SUCCESS(Status))
181 {
182 WARN("NtDeviceIoControlFile() failed, ignored\n");
185 }
186
193
194 // FIXME: Need device driver to work! HID support more than one!!!!
195 Status = ZwDeviceIoControlFile(hKeyboardDevice,
196 NULL,
197 NULL,
198 NULL,
199 &Block,
201 NULL, 0,
202 &gKeyboardInfo, sizeof(gKeyboardInfo));
203
204 if (!NT_SUCCESS(Status))
205 {
206 ERR("NtDeviceIoControlFile() failed, ignored\n");
207 }
208 TRACE("Keyboard type %u, subtype %u and number of func keys %u\n",
212}
#define IOCTL_KEYBOARD_QUERY_INDICATORS
Definition: ntddkbd.h:35
#define IOCTL_KEYBOARD_QUERY_ATTRIBUTES
Definition: ntddkbd.h:32
NTSTATUS APIENTRY IntKeyboardGetIndicatorTrans(HANDLE hKeyboardDevice, PKEYBOARD_INDICATOR_TRANSLATION *ppIndicatorTrans)
Definition: keyboard.c:52

Referenced by RawInputThreadMain().

◆ UserProcessKeyboardInput()

VOID NTAPI UserProcessKeyboardInput ( PKEYBOARD_INPUT_DATA  pKbdInputData)

Definition at line 1191 of file keyboard.c.

1193{
1194 WORD wScanCode, wVk;
1195 PKL pKl = NULL;
1196 PKBDTABLES pKbdTbl;
1197 PUSER_MESSAGE_QUEUE pFocusQueue;
1198
1199 /* Calculate scan code with prefix */
1200 wScanCode = pKbdInputData->MakeCode & 0x7F;
1201 if (pKbdInputData->Flags & KEY_E0)
1202 wScanCode |= 0xE000;
1203 if (pKbdInputData->Flags & KEY_E1)
1204 wScanCode |= 0xE100;
1205
1206 /* Find the target thread whose locale is in effect */
1207 pFocusQueue = IntGetFocusMessageQueue();
1208
1209 if (pFocusQueue && pFocusQueue->ptiKeyboard)
1210 {
1211 pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
1212 }
1213
1214 if (!pKl)
1216 if (!pKl)
1217 return;
1218
1219 pKbdTbl = pKl->spkf->pKbdTbl;
1220
1221 /* Convert scan code to virtual key.
1222 Note: We could call UserSendKeyboardInput using scan code,
1223 but it wouldn't interpret E1 key(s) properly */
1224 wVk = IntVscToVk(wScanCode, pKbdTbl);
1225 TRACE("UserProcessKeyboardInput: %x (break: %u) -> %x\n",
1226 wScanCode, (pKbdInputData->Flags & KEY_BREAK) ? 1u : 0, wVk);
1227
1228 if (wVk)
1229 {
1230 KEYBDINPUT KbdInput;
1231
1232 /* Support numlock */
1234 {
1235 wVk = IntTranslateNumpadKey(wVk & 0xFF);
1236 }
1237
1238 /* Send keyboard input */
1239 KbdInput.wVk = wVk & 0xFF;
1240 KbdInput.wScan = wScanCode & 0x7F;
1241 KbdInput.dwFlags = 0;
1242 if (pKbdInputData->Flags & KEY_BREAK)
1243 KbdInput.dwFlags |= KEYEVENTF_KEYUP;
1244
1245 if (wVk & KBDEXT)
1246 KbdInput.dwFlags |= KEYEVENTF_EXTENDEDKEY;
1247 //
1248 // Based on wine input:test_Input_blackbox this is okay. It seems the
1249 // bit did not get set and more research is needed. Now the right
1250 // shift works.
1251 //
1252 if (wVk == VK_RSHIFT)
1253 KbdInput.dwFlags |= KEYEVENTF_EXTENDEDKEY;
1254
1255 KbdInput.time = 0;
1256 KbdInput.dwExtraInfo = pKbdInputData->ExtraInformation;
1257 UserSendKeyboardInput(&KbdInput, FALSE);
1258
1259 /* E1 keys don't have break code */
1260 if (pKbdInputData->Flags & KEY_E1)
1261 {
1262 /* Send key up event */
1263 KbdInput.dwFlags |= KEYEVENTF_KEYUP;
1264 UserSendKeyboardInput(&KbdInput, FALSE);
1265 }
1266 }
1267}
#define KBDNUMPAD
Definition: kbd.h:11
#define KBDEXT
Definition: kbd.h:8
#define KEY_BREAK
Definition: ntddkbd.h:71
#define KEY_E1
Definition: ntddkbd.h:73
#define KEY_E0
Definition: ntddkbd.h:72
ULONG ExtraInformation
Definition: ntddkbd.h:90
DWORD dwFlags
Definition: winable.h:49
WORD wVk
Definition: winable.h:47
WORD wScan
Definition: winable.h:48
ULONG_PTR dwExtraInfo
Definition: winable.h:51
DWORD time
Definition: winable.h:50
BOOL NTAPI UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
Definition: keyboard.c:1110
static WORD IntTranslateNumpadKey(WORD wVk)
Definition: keyboard.c:274

Referenced by RawInputThreadMain().

◆ UserSendKeyboardInput()

BOOL NTAPI UserSendKeyboardInput ( KEYBDINPUT pKbdInput,
BOOL  bInjected 
)

Definition at line 1110 of file keyboard.c.

1111{
1112 WORD wScanCode, wVk;
1113 PKL pKl = NULL;
1114 PKBDTABLES pKbdTbl;
1115 PUSER_MESSAGE_QUEUE pFocusQueue;
1116 DWORD dwTime;
1117 BOOL bExt = (pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
1118
1120
1121 /* Find the target thread whose locale is in effect */
1122 pFocusQueue = IntGetFocusMessageQueue();
1123
1124 if (pFocusQueue && pFocusQueue->ptiKeyboard)
1125 {
1126 pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
1127 }
1128
1129 if (!pKl)
1131 if (!pKl)
1132 {
1133 ERR("No keyboard layout!\n");
1134 return FALSE;
1135 }
1136
1137 pKbdTbl = pKl->spkf->pKbdTbl;
1138
1139 /* Note: wScan field is always used */
1140 wScanCode = pKbdInput->wScan;
1141
1142 if (pKbdInput->dwFlags & KEYEVENTF_UNICODE)
1143 {
1144 /* Generate WM_KEYDOWN msg with wParam == VK_PACKET and
1145 high order word of lParam == pKbdInput->wScan */
1146 wVk = VK_PACKET;
1147 }
1148 else
1149 {
1150 wScanCode &= 0x7F;
1151 if (pKbdInput->dwFlags & KEYEVENTF_SCANCODE)
1152 {
1153 /* Don't ignore invalid scan codes */
1154 wVk = IntVscToVk(wScanCode | (bExt ? 0xE000 : 0), pKbdTbl);
1155 if (!wVk) /* use 0xFF if vsc is invalid */
1156 wVk = 0xFF;
1157 }
1158 else
1159 {
1160 wVk = pKbdInput->wVk;
1161 }
1162
1163 /* Remove all virtual key flags (KBDEXT, KBDMULTIVK, KBDSPECIAL, KBDNUMPAD) */
1164 wVk &= 0xFF;
1165 }
1166
1167 /* If time is given, use it */
1168 if (pKbdInput->time)
1169 dwTime = pKbdInput->time;
1170 else
1171 {
1173 }
1174
1175 if (wVk == VK_RMENU && (pKbdTbl->fLocaleFlags & KLLF_ALTGR))
1176 {
1177 /* For AltGr keyboards RALT generates CTRL events */
1178 ProcessKeyEvent(VK_LCONTROL, 0, pKbdInput->dwFlags & KEYEVENTF_KEYUP, bInjected, dwTime, 0);
1179 }
1180
1181 /* Finally process this key */
1182 return ProcessKeyEvent(wVk, wScanCode, pKbdInput->dwFlags, bInjected, dwTime, pKbdInput->dwExtraInfo);
1183}
PPROCESSINFO gppiInputProvider
Definition: ntuser.c:16
BOOL NTAPI ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
Definition: keyboard.c:888

Referenced by NtUserSendInput(), and UserProcessKeyboardInput().

Variable Documentation

◆ gafAsyncKeyState

◆ gafAsyncKeyStateRecentDown

BYTE gafAsyncKeyStateRecentDown[256/8]
static

Definition at line 14 of file keyboard.c.

Referenced by InitKeyboardImpl(), NtUserGetAsyncKeyState(), and UpdateAsyncKeyState().

◆ gdwLanguageToggleKey

DWORD gdwLanguageToggleKey = 1

Definition at line 19 of file keyboard.c.

Referenced by ProcessKeyEvent(), SpiGetSet(), and SpiUpdatePerUserSystemParameters().

◆ gdwLayoutToggleKey

DWORD gdwLayoutToggleKey = 2

Definition at line 21 of file keyboard.c.

Referenced by ProcessKeyEvent(), SpiGetSet(), and SpiUpdatePerUserSystemParameters().

◆ gIndicators

KEYBOARD_INDICATOR_PARAMETERS gIndicators = {0, 0}
static

Definition at line 16 of file keyboard.c.

Referenced by IntKeyboardUpdateLeds(), and UserInitKeyboard().

◆ gKeyboardInfo

KEYBOARD_ATTRIBUTES gKeyboardInfo

◆ gLanguageToggleKeyState

INT gLanguageToggleKeyState = 0

Definition at line 18 of file keyboard.c.

Referenced by ProcessKeyEvent().

◆ gLayoutToggleKeyState

INT gLayoutToggleKeyState = 0

Definition at line 20 of file keyboard.c.

Referenced by IntCheckLanguageToggle(), and ProcessKeyEvent().

◆ gpKeyboardIndicatorTrans

PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL
static

Definition at line 15 of file keyboard.c.

Referenced by IntKeyboardUpdateLeds(), and UserInitKeyboard().