ReactOS 0.4.15-dev-6069-g56a4501
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)
 
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 = 0
 

Function Documentation

◆ co_CallLowLevelKeyboardHook()

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

Definition at line 687 of file keyboard.c.

688{
689 KBDLLHOOKSTRUCT KbdHookData;
690 UINT uMsg;
691
692 KbdHookData.vkCode = wVk;
693 KbdHookData.scanCode = wScanCode;
694 KbdHookData.flags = 0;
696 KbdHookData.flags |= LLKHF_EXTENDED;
698 KbdHookData.flags |= LLKHF_ALTDOWN;
700 KbdHookData.flags |= LLKHF_UP;
701 if (bInjected)
702 KbdHookData.flags |= LLKHF_INJECTED;
703 KbdHookData.time = dwTime;
704 KbdHookData.dwExtraInfo = dwExtraInfo;
705
706 /* Note: it doesnt support WM_SYSKEYUP */
708 uMsg = WM_KEYUP;
710 uMsg = WM_SYSKEYDOWN;
711 else
712 uMsg = WM_KEYDOWN;
713
714 return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, uMsg, (LPARAM)&KbdHookData);
715}
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:26
ULONG_PTR dwExtraInfo
Definition: winuser.h:3802
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:99
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:1706
#define LLKHF_EXTENDED
Definition: winuser.h:2635
#define VK_CONTROL
Definition: winuser.h:2193
#define HC_ACTION
Definition: winuser.h:48
#define LLKHF_ALTDOWN
Definition: winuser.h:2637
#define LLKHF_UP
Definition: winuser.h:2638
#define WH_KEYBOARD_LL
Definition: winuser.h:43
#define LLKHF_INJECTED
Definition: winuser.h:2636
#define KEYEVENTF_EXTENDEDKEY
Definition: winuser.h:1095
#define WM_KEYDOWN
Definition: winuser.h:1705
#define KEYEVENTF_KEYUP
Definition: winuser.h:1096
#define WM_SYSKEYDOWN
Definition: winuser.h:1709
#define VK_MENU
Definition: winuser.h:2194

Referenced by ProcessKeyEvent().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserKbd  )

◆ InitKeyboardImpl()

NTSTATUS NTAPI InitKeyboardImpl ( VOID  )

Definition at line 31 of file keyboard.c.

32{
35 // Clear and set default information.
37 gKeyboardInfo.KeyboardIdentifier.Type = 4; /* AT-101 */
38 gKeyboardInfo.NumberOfFunctionKeys = 12; /* We're doing an 101 for now, so return 12 F-keys */
39 return STATUS_SUCCESS;
40}
#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().

◆ IntFixVk()

static WORD IntFixVk ( WORD  wVk,
BOOL  bExt 
)
static

Definition at line 247 of file keyboard.c.

248{
249 switch (wVk)
250 {
251 case VK_SHIFT:
252 return bExt ? VK_RSHIFT : VK_LSHIFT;
253
254 case VK_CONTROL:
255 return bExt ? VK_RCONTROL : VK_LCONTROL;
256
257 case VK_MENU:
258 return bExt ? VK_RMENU : VK_LMENU;
259
260 default:
261 return wVk;
262 }
263}
#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_SHIFT
Definition: winuser.h:2192
#define VK_LMENU
Definition: winuser.h:2276

Referenced by IntMapVirtualKeyEx(), and ProcessKeyEvent().

◆ IntGetModBits()

static DWORD IntGetModBits ( PKBDTABLES  pKbdTbl,
PBYTE  pKeyState 
)
static

Definition at line 298 of file keyboard.c.

299{
300 DWORD i, dwModBits = 0;
301
302 /* DumpKeyState( KeyState ); */
303
304 for (i = 0; pKbdTbl->pCharModifiers->pVkToBit[i].Vk; i++)
305 if (IS_KEY_DOWN(pKeyState, pKbdTbl->pCharModifiers->pVkToBit[i].Vk))
306 dwModBits |= pKbdTbl->pCharModifiers->pVkToBit[i].ModBits;
307
308 TRACE("Current Mod Bits: %lx\n", dwModBits);
309
310 return dwModBits;
311}
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().

◆ IntKeyboardGetIndicatorTrans()

NTSTATUS APIENTRY IntKeyboardGetIndicatorTrans ( HANDLE  hKeyboardDevice,
PKEYBOARD_INDICATOR_TRANSLATION ppIndicatorTrans 
)

Definition at line 50 of file keyboard.c.

52{
54 DWORD dwSize = 0;
55 IO_STATUS_BLOCK Block;
57
59
61 dwSize,
63
64 while (pRet)
65 {
66 Status = ZwDeviceIoControlFile(hKeyboardDevice,
67 NULL,
68 NULL,
69 NULL,
70 &Block,
72 NULL, 0,
73 pRet, dwSize);
74
76 break;
77
79
81
83 dwSize,
85 }
86
87 if (!pRet)
89
90 if (!NT_SUCCESS(Status))
91 {
93 return Status;
94 }
95
96 *ppIndicatorTrans = pRet;
97 return Status;
98}
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 107 of file keyboard.c.

110{
112 UINT i;
113 USHORT LedFlag = 0;
114 IO_STATUS_BLOCK Block;
115
118
119 switch (wVk)
120 {
121 case VK_CAPITAL: LedFlag = KEYBOARD_CAPS_LOCK_ON; break;
122 case VK_NUMLOCK: LedFlag = KEYBOARD_NUM_LOCK_ON; break;
123 case VK_SCROLL: LedFlag = KEYBOARD_SCROLL_LOCK_ON; break;
124 default:
126 {
128 {
130 break;
131 }
132 }
133 }
134
135 if (LedFlag)
136 {
137 gIndicators.LedFlags ^= LedFlag;
138
139 /* Update the lights on the hardware */
140 Status = ZwDeviceIoControlFile(hKeyboardDevice,
141 NULL,
142 NULL,
143 NULL,
144 &Block,
146 &gIndicators, sizeof(gIndicators),
147 NULL, 0);
148
149 return Status;
150 }
151
152 return STATUS_SUCCESS;
153}
#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:2196
#define VK_SCROLL
Definition: winuser.h:2270
#define VK_NUMLOCK
Definition: winuser.h:2269

Referenced by ProcessKeyEvent().

◆ IntMapVirtualKeyEx()

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

Definition at line 1269 of file keyboard.c.

1270{
1271 UINT uRet = 0;
1272
1273 switch (Type)
1274 {
1275 case MAPVK_VK_TO_VSC:
1276 uCode = IntFixVk(uCode, FALSE);
1277 uRet = IntVkToVsc(uCode, pKbdTbl);
1278 if (uRet > 0xFF) // Fail for scancodes with prefix (e0, e1)
1279 uRet = 0;
1280 break;
1281
1282 case MAPVK_VSC_TO_VK:
1283 uRet = IntVscToVk(uCode, pKbdTbl) & 0xFF;
1284 uRet = IntSimplifyVk(uRet);
1285 break;
1286
1287 case MAPVK_VK_TO_CHAR:
1288 uRet = (UINT)IntVkToChar(uCode, pKbdTbl);
1289 break;
1290
1291 case MAPVK_VSC_TO_VK_EX:
1292 uRet = IntVscToVk(uCode, pKbdTbl) & 0xFF;
1293 break;
1294
1295 case MAPVK_VK_TO_VSC_EX:
1296 uRet = IntVkToVsc(uCode, pKbdTbl);
1297 break;
1298
1299 default:
1301 ERR("Wrong type value: %u\n", Type);
1302 }
1303
1304 return uRet;
1305}
Type
Definition: Type.h:7
#define ERR(fmt,...)
Definition: debug.h:110
#define FALSE
Definition: types.h:117
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static WORD IntFixVk(WORD wVk, BOOL bExt)
Definition: keyboard.c:247
static WCHAR FASTCALL IntVkToChar(WORD wVk, PKBDTABLES pKbdTbl)
Definition: keyboard.c:605
static WORD FASTCALL IntVkToVsc(WORD wVk, PKBDTABLES pKbdTbl)
Definition: keyboard.c:525
static WORD FASTCALL IntVscToVk(WORD wScanCode, PKBDTABLES pKbdTbl)
Definition: keyboard.c:562
static WORD IntSimplifyVk(WORD wVk)
Definition: keyboard.c:219
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:28
#define MAPVK_VSC_TO_VK_EX
Definition: winuser.h:2348
#define MAPVK_VSC_TO_VK
Definition: winuser.h:2346
#define MAPVK_VK_TO_CHAR
Definition: winuser.h:2347
#define MAPVK_VK_TO_VSC
Definition: winuser.h:2345
#define MAPVK_VK_TO_VSC_EX
Definition: winuser.h:2349

Referenced by NtUserMapVirtualKeyEx().

◆ IntSimplifyVk()

static WORD IntSimplifyVk ( WORD  wVk)
static

Definition at line 219 of file keyboard.c.

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

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 432 of file keyboard.c.

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

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

Referenced by IntToUnicodeEx(), and IntVkToChar().

◆ IntTranslateKbdMessage()

BOOL FASTCALL IntTranslateKbdMessage ( LPMSG  lpMsg,
UINT  flags 
)

Definition at line 1152 of file keyboard.c.

1154{
1155 PTHREADINFO pti;
1156 INT cch = 0, i;
1157 WCHAR wch[3] = { 0 };
1158 MSG NewMsg = { 0 };
1159 PKBDTABLES pKbdTbl;
1160 BOOL bResult = FALSE;
1161
1162 switch(lpMsg->message)
1163 {
1164 case WM_KEYDOWN:
1165 case WM_KEYUP:
1166 case WM_SYSKEYDOWN:
1167 case WM_SYSKEYUP:
1168 break;
1169 default:
1170 return FALSE;
1171 }
1172
1174
1175 if (!pti->KeyboardLayout)
1176 {
1177 PKL pDefKL = W32kGetDefaultKeyLayout();
1178 UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pDefKL);
1179 if (pDefKL)
1180 {
1181 pti->pClientInfo->hKL = pDefKL->hkl;
1182 pKbdTbl = pDefKL->spkf->pKbdTbl;
1183 }
1184 else
1185 {
1186 pti->pClientInfo->hKL = NULL;
1187 pKbdTbl = NULL;
1188 }
1189 }
1190 else
1191 pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
1192 if (!pKbdTbl)
1193 return FALSE;
1194
1195 if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
1196 return FALSE;
1197
1198 /* Init pt, hwnd and time msg fields */
1199 NewMsg.pt = gpsi->ptCursor;
1200 NewMsg.hwnd = lpMsg->hwnd;
1201 NewMsg.time = EngGetTickCount32();
1202
1203 TRACE("Enter IntTranslateKbdMessage msg %s, vk %x\n",
1204 lpMsg->message == WM_SYSKEYDOWN ? "WM_SYSKEYDOWN" : "WM_KEYDOWN", lpMsg->wParam);
1205
1206 if (lpMsg->wParam == VK_PACKET)
1207 {
1208 NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
1209 NewMsg.wParam = HIWORD(lpMsg->lParam);
1210 NewMsg.lParam = LOWORD(lpMsg->lParam);
1211 MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
1212 return TRUE;
1213 }
1214
1215 cch = IntToUnicodeEx(lpMsg->wParam,
1216 HIWORD(lpMsg->lParam) & 0xFF,
1217 pti->MessageQueue->afKeyState,
1218 wch,
1219 sizeof(wch) / sizeof(wch[0]),
1220 0,
1221 pKbdTbl);
1222
1223 if (cch)
1224 {
1225 if (cch > 0) /* Normal characters */
1226 NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
1227 else /* Dead character */
1228 {
1229 cch = -cch;
1230 NewMsg.message =
1232 }
1233 NewMsg.lParam = lpMsg->lParam;
1234
1235 /* Send all characters */
1236 for (i = 0; i < cch; ++i)
1237 {
1238 TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam);
1239 NewMsg.wParam = wch[i];
1240 MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
1241 }
1242 bResult = TRUE;
1243 }
1244
1245 TRACE("Leave IntTranslateKbdMessage ret %d, cch %d, msg %x, wch %x\n",
1246 bResult, cch, NewMsg.message, NewMsg.wParam);
1247 return bResult;
1248}
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
#define LOWORD(l)
Definition: pedump.c:82
Definition: kbd.h:95
struct _CLIENTINFO * pClientInfo
Definition: win32.h:94
struct tagKL * KeyboardLayout
Definition: win32.h:90
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:89
struct _KBDTABLES * pKbdTbl
Definition: input.h:21
Definition: input.h:27
PKBDFILE spkf
Definition: input.h:33
HKL hkl
Definition: input.h:32
UINT message
Definition: winuser.h:3105
HWND hwnd
Definition: winuser.h:3104
WPARAM wParam
Definition: winuser.h:3106
LPARAM lParam
Definition: winuser.h:3107
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:432
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
Definition: object.c:840
#define QS_KEY
Definition: winuser.h:868
#define WM_SYSCHAR
Definition: winuser.h:1711
#define WM_SYSDEADCHAR
Definition: winuser.h:1712
#define WM_SYSKEYUP
Definition: winuser.h:1710
#define WM_CHAR
Definition: winuser.h:1707
#define WM_DEADCHAR
Definition: winuser.h:1708

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

◆ IntTranslateNumpadKey()

static WORD IntTranslateNumpadKey ( WORD  wVk)
static

Definition at line 272 of file keyboard.c.

273{
274 switch (wVk)
275 {
276 case VK_INSERT: return VK_NUMPAD0;
277 case VK_END: return VK_NUMPAD1;
278 case VK_DOWN: return VK_NUMPAD2;
279 case VK_NEXT: return VK_NUMPAD3;
280 case VK_LEFT: return VK_NUMPAD4;
281 case VK_CLEAR: return VK_NUMPAD5;
282 case VK_RIGHT: return VK_NUMPAD6;
283 case VK_HOME: return VK_NUMPAD7;
284 case VK_UP: return VK_NUMPAD8;
285 case VK_PRIOR: return VK_NUMPAD9;
286 case VK_DELETE: return VK_DECIMAL;
287 default: return wVk;
288 }
289}
#define VK_CLEAR
Definition: winuser.h:2190
#define VK_NUMPAD3
Definition: winuser.h:2232
#define VK_NUMPAD1
Definition: winuser.h:2230
#define VK_NUMPAD2
Definition: winuser.h:2231
#define VK_NUMPAD4
Definition: winuser.h:2233
#define VK_UP
Definition: winuser.h:2215
#define VK_NUMPAD0
Definition: winuser.h:2229
#define VK_NUMPAD6
Definition: winuser.h:2235
#define VK_NEXT
Definition: winuser.h:2211
#define VK_NUMPAD9
Definition: winuser.h:2238
#define VK_END
Definition: winuser.h:2212
#define VK_HOME
Definition: winuser.h:2213
#define VK_NUMPAD5
Definition: winuser.h:2234
#define VK_LEFT
Definition: winuser.h:2214
#define VK_NUMPAD7
Definition: winuser.h:2236
#define VK_RIGHT
Definition: winuser.h:2216
#define VK_DOWN
Definition: winuser.h:2217
#define VK_PRIOR
Definition: winuser.h:2210
#define VK_DELETE
Definition: winuser.h:2223
#define VK_NUMPAD8
Definition: winuser.h:2237
#define VK_DECIMAL
Definition: winuser.h:2243
#define VK_INSERT
Definition: winuser.h:2222

Referenced by UserProcessKeyboardInput().

◆ IntVkToChar()

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

Definition at line 605 of file keyboard.c.

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

Referenced by IntMapVirtualKeyEx(), and NtUserGetKeyNameText().

◆ IntVkToVsc()

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

Definition at line 525 of file keyboard.c.

526{
527 unsigned i;
528
529 ASSERT(pKbdTbl);
530
531 /* Check standard keys first */
532 for (i = 0; i < pKbdTbl->bMaxVSCtoVK; i++)
533 {
534 if ((pKbdTbl->pusVSCtoVK[i] & 0xFF) == wVk)
535 return i;
536 }
537
538 /* Check extended keys now */
539 for (i = 0; pKbdTbl->pVSCtoVK_E0[i].Vsc; i++)
540 {
541 if ((pKbdTbl->pVSCtoVK_E0[i].Vk & 0xFF) == wVk)
542 return 0xE000 | pKbdTbl->pVSCtoVK_E0[i].Vsc;
543 }
544
545 for (i = 0; pKbdTbl->pVSCtoVK_E1[i].Vsc; i++)
546 {
547 if ((pKbdTbl->pVSCtoVK_E1[i].Vk & 0xFF) == wVk)
548 return 0xE100 | pKbdTbl->pVSCtoVK_E1[i].Vsc;
549 }
550
551 /* Virtual key has not been found */
552 return 0;
553}
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 562 of file keyboard.c.

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

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

◆ NtUserGetAsyncKeyState()

SHORT APIENTRY NtUserGetAsyncKeyState ( INT  Key)

Definition at line 632 of file keyboard.c.

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

Referenced by GetAsyncKeyState(), and START_TEST().

◆ NtUserGetKeyNameText()

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

Definition at line 1460 of file keyboard.c.

1461{
1462 PTHREADINFO pti;
1463 DWORD i, dwRet = 0;
1464 SIZE_T cchKeyName;
1465 WORD wScanCode = (lParam >> 16) & 0xFF;
1466 BOOL bExtKey = (HIWORD(lParam) & KF_EXTENDED) ? TRUE : FALSE;
1467 PKBDTABLES pKbdTbl;
1468 VSC_LPWSTR *pKeyNames = NULL;
1469 CONST WCHAR *pKeyName = NULL;
1470 WCHAR KeyNameBuf[2];
1471
1472 TRACE("Enter NtUserGetKeyNameText\n");
1473
1475
1476 /* Get current keyboard layout */
1478 pKbdTbl = pti ? pti->KeyboardLayout->spkf->pKbdTbl : 0;
1479
1480 if (!pKbdTbl || cchSize < 1)
1481 {
1482 ERR("Invalid parameter\n");
1483 goto cleanup;
1484 }
1485
1486 /* "Do not care" flag */
1488 {
1489 /* Note: We could do vsc -> vk -> vsc conversion, instead of using
1490 hardcoded scan codes, but it's not what Windows does */
1491 if (wScanCode == SCANCODE_RSHIFT && !bExtKey)
1492 wScanCode = SCANCODE_LSHIFT;
1493 else if (wScanCode == SCANCODE_CTRL || wScanCode == SCANCODE_ALT)
1494 bExtKey = FALSE;
1495 }
1496
1497 if (bExtKey)
1498 pKeyNames = pKbdTbl->pKeyNamesExt;
1499 else
1500 pKeyNames = pKbdTbl->pKeyNames;
1501
1502 for (i = 0; pKeyNames[i].pwsz; i++)
1503 {
1504 if (pKeyNames[i].vsc == wScanCode)
1505 {
1506 pKeyName = pKeyNames[i].pwsz;
1507 break;
1508 }
1509 }
1510
1511 if (!pKeyName)
1512 {
1513 WORD wVk = IntVscToVk(wScanCode, pKbdTbl);
1514
1515 if (wVk)
1516 {
1517 KeyNameBuf[0] = IntVkToChar(wVk, pKbdTbl);
1518 KeyNameBuf[1] = 0;
1519 if (KeyNameBuf[0])
1520 pKeyName = KeyNameBuf;
1521 }
1522 }
1523
1524 if (pKeyName)
1525 {
1526 cchKeyName = wcslen(pKeyName);
1527 if (cchKeyName > (cchSize - 1UL))
1528 cchKeyName = cchSize - 1UL; // Don't count '\0'
1529
1530 _SEH2_TRY
1531 {
1532 ProbeForWrite(lpString, (cchKeyName + 1) * sizeof(WCHAR), 1);
1533 RtlCopyMemory(lpString, pKeyName, cchKeyName * sizeof(WCHAR));
1534 lpString[cchKeyName] = UNICODE_NULL;
1535 dwRet = cchKeyName;
1536 }
1538 {
1540 }
1541 _SEH2_END;
1542 }
1543 else
1544 {
1546 }
1547
1548cleanup:
1549 UserLeave();
1550 TRACE("Leave NtUserGetKeyNameText, ret=%lu\n", dwRet);
1551 return dwRet;
1552}
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:238
#define CONST
Definition: pedump.c:81
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
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(NTSTATUS Status)
Definition: error.c:37
#define LP_DO_NOT_CARE_BIT
Definition: input.h:59
#define KF_EXTENDED
Definition: winuser.h:2436

Referenced by GetKeyNameTextA(), and GetKeyNameTextW().

◆ NtUserMapVirtualKeyEx()

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

Definition at line 1315 of file keyboard.c.

1316{
1317 PKBDTABLES pKbdTbl = NULL;
1318 UINT ret = 0;
1319
1320 TRACE("Enter NtUserMapVirtualKeyEx\n");
1322
1323 if (!dwhkl)
1324 {
1325 PTHREADINFO pti;
1326
1328 if (pti && pti->KeyboardLayout)
1329 pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
1330 }
1331 else
1332 {
1333 PKL pKl;
1334
1335 pKl = UserHklToKbl(dwhkl);
1336 if (pKl)
1337 pKbdTbl = pKl->spkf->pKbdTbl;
1338 }
1339
1340 if (pKbdTbl)
1341 ret = IntMapVirtualKeyEx(uCode, uType, pKbdTbl);
1342
1343 UserLeave();
1344 TRACE("Leave NtUserMapVirtualKeyEx, ret=%u\n", ret);
1345 return ret;
1346}
int ret
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:541
static UINT IntMapVirtualKeyEx(UINT uCode, UINT Type, PKBDTABLES pKbdTbl)
Definition: keyboard.c:1269

Referenced by MapVirtualKeyExW().

◆ NtUserToUnicodeEx()

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

Definition at line 1355 of file keyboard.c.

1363{
1364 PTHREADINFO pti;
1365 BYTE afKeyState[256 * 2 / 8] = {0};
1366 PWCHAR pwszBuff = NULL;
1367 INT i, iRet = 0;
1368 PKL pKl = NULL;
1370
1371 TRACE("Enter NtUserSetKeyboardState\n");
1372
1373 /* Return 0 if SC_KEY_UP bit is set */
1374 if (wScanCode & SC_KEY_UP || wVirtKey >= 0x100)
1375 {
1376 ERR("Invalid parameter\n");
1377 return 0;
1378 }
1379
1380 _SEH2_TRY
1381 {
1382 /* Probe and copy key state to smaller bitmap */
1383 ProbeForRead(pKeyStateUnsafe, 256 * sizeof(BYTE), 1);
1384 for (i = 0; i < 256; ++i)
1385 {
1386 if (pKeyStateUnsafe[i] & KS_DOWN_BIT)
1387 SET_KEY_DOWN(afKeyState, i, TRUE);
1388 if (pKeyStateUnsafe[i] & KS_LOCK_BIT)
1389 SET_KEY_LOCKED(afKeyState, i, TRUE);
1390 }
1391 }
1393 {
1394 ERR("Cannot copy key state\n");
1396 _SEH2_YIELD(return 0);
1397 }
1398 _SEH2_END;
1399
1400 pwszBuff = ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR) * cchBuff, TAG_STRING);
1401 if (!pwszBuff)
1402 {
1403 ERR("ExAllocatePoolWithTag(%u) failed\n", sizeof(WCHAR) * cchBuff);
1404 return 0;
1405 }
1406 RtlZeroMemory(pwszBuff, sizeof(WCHAR) * cchBuff);
1407
1408 UserEnterExclusive(); // Note: We modify wchDead static variable
1409
1410 if (dwhkl)
1411 pKl = UserHklToKbl(dwhkl);
1412
1413 if (!pKl)
1414 {
1416 pKl = pti->KeyboardLayout;
1417 }
1418
1419 if (pKl)
1420 {
1421 iRet = IntToUnicodeEx(wVirtKey,
1422 wScanCode,
1423 afKeyState,
1424 pwszBuff,
1425 cchBuff,
1426 wFlags,
1427 pKl->spkf->pKbdTbl);
1428
1429 if (iRet)
1430 {
1431 Status = MmCopyToCaller(pwszBuffUnsafe, pwszBuff, cchBuff * sizeof(WCHAR));
1432 }
1433 }
1434 else
1435 {
1436 ERR("No keyboard layout ?!\n");
1438 }
1439
1440 ExFreePoolWithTag(pwszBuff, TAG_STRING);
1441
1442 if (!NT_SUCCESS(Status))
1443 {
1444 iRet = 0;
1446 }
1447
1448 UserLeave();
1449 TRACE("Leave NtUserSetKeyboardState, ret=%i\n", iRet);
1450 return iRet;
1451}
#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:162
uint16_t * PWCHAR
Definition: typedefs.h:56
#define SET_KEY_DOWN(ks, vk, down)
Definition: input.h:101
#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:104
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531

◆ NtUserVkKeyScanEx()

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

Definition at line 1585 of file keyboard.c.

1589{
1590 PKBDTABLES pKbdTbl;
1591 PVK_TO_WCHAR_TABLE pVkToWchTbl;
1592 PVK_TO_WCHARS10 pVkToWch;
1593 PKL pKl = NULL;
1594 DWORD i, dwModBits = 0, dwModNumber = 0, Ret = (DWORD)-1;
1595
1596 TRACE("NtUserVkKeyScanEx() wch %u, KbdLayout 0x%p\n", wch, dwhkl);
1598
1599 if (bUsehKL)
1600 {
1601 // Use given keyboard layout
1602 if (dwhkl)
1603 pKl = UserHklToKbl(dwhkl);
1604 }
1605 else
1606 {
1607 // Use thread keyboard layout
1608 pKl = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->KeyboardLayout;
1609 }
1610
1611 if (!pKl)
1612 goto Exit;
1613
1614 pKbdTbl = pKl->spkf->pKbdTbl;
1615
1616 // Interate through all VkToWchar tables while pVkToWchars is not NULL
1617 for (i = 0; pKbdTbl->pVkToWcharTable[i].pVkToWchars; i++)
1618 {
1619 pVkToWchTbl = &pKbdTbl->pVkToWcharTable[i];
1620 pVkToWch = (PVK_TO_WCHARS10)(pVkToWchTbl->pVkToWchars);
1621
1622 // Interate through all virtual keys
1623 while (pVkToWch->VirtualKey)
1624 {
1625 for (dwModNumber = 0; dwModNumber < pVkToWchTbl->nModifications; dwModNumber++)
1626 {
1627 if (pVkToWch->wch[dwModNumber] == wch)
1628 {
1629 dwModBits = pKbdTbl->pCharModifiers->ModNumber[dwModNumber];
1630 TRACE("i %lu wC %04x: dwModBits %08x dwModNumber %08x MaxModBits %08x\n",
1631 i, wch, dwModBits, dwModNumber, pKbdTbl->pCharModifiers->wMaxModBits);
1632 Ret = (dwModBits << 8) | (pVkToWch->VirtualKey & 0xFF);
1633 goto Exit;
1634 }
1635 }
1636 pVkToWch = (PVK_TO_WCHARS10)(((BYTE *)pVkToWch) + pVkToWchTbl->cbSize);
1637 }
1638 }
1639Exit:
1640 UserLeave();
1641 return Ret;
1642}
#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 800 of file keyboard.c.

801{
802 WORD wSimpleVk = 0, wFixedVk, wVk2;
803 PUSER_MESSAGE_QUEUE pFocusQueue;
804 PTHREADINFO pti;
806 BOOL bIsDown = (dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
807 BOOL bPacket = (dwFlags & KEYEVENTF_UNICODE) ? TRUE : FALSE;
808 BOOL bWasSimpleDown = FALSE, bPostMsg = TRUE, bIsSimpleDown;
809 MSG Msg;
810 static BOOL bMenuDownRecently = FALSE;
811
812 /* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
813 wSimpleVk = IntSimplifyVk(wVk);
814
816 {
817 /* Japanese special! */
819 {
820 if (wSimpleVk == VK_OEM_ATTN)
821 wSimpleVk = VK_CAPITAL;
822 else if (wSimpleVk == VK_OEM_COPY)
823 wSimpleVk = VK_OEM_FINISH;
824 }
825 }
826
827 bWasSimpleDown = IS_KEY_DOWN(gafAsyncKeyState, wSimpleVk);
828
829 /* Update key without shifts */
830 wVk2 = IntFixVk(wSimpleVk, !bExt);
831 bIsSimpleDown = bIsDown || IS_KEY_DOWN(gafAsyncKeyState, wVk2);
832 UpdateAsyncKeyState(wSimpleVk, bIsSimpleDown);
833
834 if (bIsDown)
835 {
836 /* Update keyboard LEDs */
838 wSimpleVk,
839 wScanCode);
840 }
841
842 /* Call WH_KEYBOARD_LL hook */
843 if (co_CallLowLevelKeyboardHook(wVk, wScanCode, dwFlags, bInjected, dwTime, dwExtraInfo))
844 {
845 ERR("Kbd msg dropped by WH_KEYBOARD_LL hook\n");
846 bPostMsg = FALSE;
847 }
848
849 /* Check if this is a hotkey */
850 if (co_UserProcessHotKeys(wSimpleVk, bIsDown))
851 {
852 TRACE("HotKey Processed\n");
853 bPostMsg = FALSE;
854 }
855
856 wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */
857 if (wSimpleVk == VK_SHIFT) /* shift can't be extended */
858 bExt = FALSE;
859
860 /* If we have a focus queue, post a keyboard message */
861 pFocusQueue = IntGetFocusMessageQueue();
862 TRACE("ProcessKeyEvent Q 0x%p Active pWnd 0x%p Focus pWnd 0x%p\n",
863 pFocusQueue,
864 (pFocusQueue ? pFocusQueue->spwndActive : 0),
865 (pFocusQueue ? pFocusQueue->spwndFocus : 0));
866
867 /* If it is F10 or ALT is down and CTRL is up, it's a system key */
868 if ( wVk == VK_F10 ||
869 (wSimpleVk == VK_MENU && bMenuDownRecently) ||
872 // See MSDN WM_SYSKEYDOWN/UP fixes last wine Win test_keyboard_input.
873 (pFocusQueue && !pFocusQueue->spwndFocus) )
874 {
875 bMenuDownRecently = FALSE; // reset
876 if (bIsDown)
877 {
878 Msg.message = WM_SYSKEYDOWN;
879 if (wSimpleVk == VK_MENU)
880 {
881 // Note: If only LALT is pressed WM_SYSKEYUP is generated instead of WM_KEYUP
882 bMenuDownRecently = TRUE;
883 }
884 }
885 else
886 Msg.message = WM_SYSKEYUP;
887 }
888 else
889 {
890 if (bIsDown)
891 Msg.message = WM_KEYDOWN;
892 else
893 Msg.message = WM_KEYUP;
894 }
895
896 /* Update async state of not simplified vk here.
897 See user32_apitest:GetKeyState */
898 UpdateAsyncKeyState(wFixedVk, bIsDown);
899
900 /* Alt-Tab/Esc Check. Use FocusQueue or RIT Queue */
901 if (bIsSimpleDown && !bWasSimpleDown &&
904 (wVk == VK_ESCAPE || wVk == VK_TAB))
905 {
906 TRACE("Alt-Tab/Esc Pressed wParam %x\n",wVk);
907 }
908
909 if (bIsDown && wVk == VK_SNAPSHOT)
910 {
911 if (pFocusQueue &&
914 {
915 // Snap from Active Window, Focus can be null.
916 SnapWindow(pFocusQueue->spwndActive ? UserHMGetHandle(pFocusQueue->spwndActive) : 0);
917 }
918 else
919 SnapWindow(NULL); // Snap Desktop.
920 }
921 else if (pFocusQueue && bPostMsg)
922 {
923 PWND Wnd = pFocusQueue->spwndFocus; // SysInit.....
924
925 pti = pFocusQueue->ptiKeyboard;
926
927 if (!Wnd && pFocusQueue->spwndActive) // SysInit.....
928 {
929 // Going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input.
930 Wnd = pFocusQueue->spwndActive;
931 }
932 if (Wnd) pti = Wnd->head.pti;
933
934 /* Init message */
935 Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
936 Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */
937 Msg.lParam = MAKELPARAM(1, wScanCode);
938 Msg.time = dwTime;
939 Msg.pt = gpsi->ptCursor;
940
941 if ( Msg.message == WM_KEYDOWN || Msg.message == WM_SYSKEYDOWN )
942 {
943 if ( (Msg.wParam == VK_SHIFT ||
944 Msg.wParam == VK_CONTROL ||
945 Msg.wParam == VK_MENU ) &&
947 {
948 ERR("Set last input\n");
949 //ptiLastInput = pti;
950 }
951 }
952
953 /* If it is VK_PACKET, high word of wParam is used for wchar */
954 if (!bPacket)
955 {
956 if (bExt)
957 Msg.lParam |= KF_EXTENDED << 16;
959 Msg.lParam |= KF_ALTDOWN << 16;
960 if (bWasSimpleDown)
961 Msg.lParam |= KF_REPEAT << 16;
962 if (!bIsDown)
963 Msg.lParam |= KF_UP << 16;
964 /* FIXME: Set KF_DLGMODE and KF_MENUMODE when needed */
965 if (pFocusQueue->QF_flags & QF_DIALOGACTIVE)
966 Msg.lParam |= KF_DLGMODE << 16;
967 if (pFocusQueue->MenuOwner) // pti->pMenuState->fMenuStarted
968 Msg.lParam |= KF_MENUMODE << 16;
969 }
970
971 // Post mouse move before posting key buttons, to keep it syned.
972 if (pFocusQueue->QF_flags & QF_MOUSEMOVED)
973 {
975 }
976
977 /* Post a keyboard message */
978 TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
979 if (!Wnd) {ERR("Window is NULL\n");}
980 MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0, dwExtraInfo);
981 }
982 return TRUE;
983}
struct @1609 Msg[]
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
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
Definition: ntuser.h:689
THRDESKHEAD head
Definition: ntuser.h:690
USHORT gusLanguageID
Definition: main.c:29
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:107
static VOID SnapWindow(HWND hWnd)
Definition: keyboard.c:723
static LRESULT co_CallLowLevelKeyboardHook(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
Definition: keyboard.c:687
static VOID NTAPI UpdateAsyncKeyState(WORD wVk, BOOL bIsDown)
Definition: keyboard.c:666
#define VK_SNAPSHOT
Definition: winuser.h:2221
#define VK_TAB
Definition: winuser.h:2189
#define MAKELPARAM(l, h)
Definition: winuser.h:3998
#define VK_F10
Definition: winuser.h:2254
#define KF_ALTDOWN
Definition: winuser.h:2439
#define VK_OEM_FINISH
Definition: winuser.h:2329
#define KF_UP
Definition: winuser.h:2441
#define KF_MENUMODE
Definition: winuser.h:2438
#define VK_OEM_ATTN
Definition: winuser.h:2328
#define VK_OEM_COPY
Definition: winuser.h:2330
#define KF_REPEAT
Definition: winuser.h:2440
#define VK_ESCAPE
Definition: winuser.h:2204
#define KF_DLGMODE
Definition: winuser.h:2437

Referenced by UserSendKeyboardInput().

◆ SnapWindow()

static VOID SnapWindow ( HWND  hWnd)
static

Definition at line 723 of file keyboard.c.

724{
725 HBITMAP hbm = NULL, hbmOld;
726 HDC hdc = NULL, hdcMem;
727 SETCLIPBDATA scd;
728 INT cx, cy;
729 PWND pWnd = NULL;
730
731 TRACE("SnapWindow(%p)\n", hWnd);
732
733 /* If no windows is given, make snapshot of desktop window */
734 if (!hWnd)
736
738 if (!pWnd)
739 {
740 ERR("Invalid window\n");
741 goto cleanup;
742 }
743
745 if (!hdc)
746 {
747 ERR("UserGetDCEx failed!\n");
748 goto cleanup;
749 }
750
751 cx = pWnd->rcWindow.right - pWnd->rcWindow.left;
752 cy = pWnd->rcWindow.bottom - pWnd->rcWindow.top;
753
755 if (!hbm)
756 {
757 ERR("NtGdiCreateCompatibleBitmap failed!\n");
758 goto cleanup;
759 }
760
762 if (!hdcMem)
763 {
764 ERR("NtGdiCreateCompatibleDC failed!\n");
765 goto cleanup;
766 }
767
768 hbmOld = NtGdiSelectBitmap(hdcMem, hbm);
769 NtGdiBitBlt(hdcMem, 0, 0, cx, cy, hdc, 0, 0, SRCCOPY, 0, 0);
770 NtGdiSelectBitmap(hdcMem, hbmOld);
772
773 /* Save snapshot in clipboard */
775 {
778 scd.fGlobalHandle = FALSE;
780 {
781 /* Bitmap is managed by system now */
782 hbm = NULL;
783 }
785 }
786
787cleanup:
788 if (hbm)
790 if (hdc)
791 UserReleaseDC(pWnd, hdc, FALSE);
792}
#define DCX_USESTYLE
Definition: GetDCEx.c:10
HWND hWnd
Definition: settings.c:17
#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:711
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:1164
BOOL fGlobalHandle
Definition: ntuser.h:1163
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:2103

Referenced by ProcessKeyEvent().

◆ UpdateAsyncKeyState()

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

Definition at line 666 of file keyboard.c.

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

Referenced by ProcessKeyEvent().

◆ UserGetKeyboardType()

DWORD FASTCALL UserGetKeyboardType ( DWORD  dwTypeFlag)

Definition at line 1560 of file keyboard.c.

1562{
1563 switch (dwTypeFlag)
1564 {
1565 case 0: /* Keyboard type */
1567 case 1: /* Keyboard Subtype */
1569 case 2: /* Number of F-keys */
1571 default:
1572 ERR("Unknown type!\n");
1573 return 0; /* Note: we don't have to set last error here */
1574 }
1575}
UCHAR Subtype
Definition: ntddkbd.h:102

Referenced by NtUserCallOneParam().

◆ UserInitKeyboard()

VOID NTAPI UserInitKeyboard ( HANDLE  hKeyboardDevice)

Definition at line 161 of file keyboard.c.

162{
164 IO_STATUS_BLOCK Block;
165
167
168 Status = ZwDeviceIoControlFile(hKeyboardDevice,
169 NULL,
170 NULL,
171 NULL,
172 &Block,
174 NULL, 0,
176 sizeof(gIndicators));
177
178 if (!NT_SUCCESS(Status))
179 {
180 WARN("NtDeviceIoControlFile() failed, ignored\n");
183 }
184
191
192 // FIXME: Need device driver to work! HID support more than one!!!!
193 Status = ZwDeviceIoControlFile(hKeyboardDevice,
194 NULL,
195 NULL,
196 NULL,
197 &Block,
199 NULL, 0,
200 &gKeyboardInfo, sizeof(gKeyboardInfo));
201
202 if (!NT_SUCCESS(Status))
203 {
204 ERR("NtDeviceIoControlFile() failed, ignored\n");
205 }
206 TRACE("Keyboard type %u, subtype %u and number of func keys %u\n",
210}
#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:50

Referenced by RawInputThreadMain().

◆ UserProcessKeyboardInput()

VOID NTAPI UserProcessKeyboardInput ( PKEYBOARD_INPUT_DATA  pKbdInputData)

Definition at line 1067 of file keyboard.c.

1069{
1070 WORD wScanCode, wVk;
1071 PKL pKl = NULL;
1072 PKBDTABLES pKbdTbl;
1073 PUSER_MESSAGE_QUEUE pFocusQueue;
1074
1075 /* Calculate scan code with prefix */
1076 wScanCode = pKbdInputData->MakeCode & 0x7F;
1077 if (pKbdInputData->Flags & KEY_E0)
1078 wScanCode |= 0xE000;
1079 if (pKbdInputData->Flags & KEY_E1)
1080 wScanCode |= 0xE100;
1081
1082 /* Find the target thread whose locale is in effect */
1083 pFocusQueue = IntGetFocusMessageQueue();
1084
1085 if (pFocusQueue && pFocusQueue->ptiKeyboard)
1086 {
1087 pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
1088 }
1089
1090 if (!pKl)
1092 if (!pKl)
1093 return;
1094
1095 pKbdTbl = pKl->spkf->pKbdTbl;
1096
1097 /* Convert scan code to virtual key.
1098 Note: We could call UserSendKeyboardInput using scan code,
1099 but it wouldn't interpret E1 key(s) properly */
1100 wVk = IntVscToVk(wScanCode, pKbdTbl);
1101 TRACE("UserProcessKeyboardInput: %x (break: %u) -> %x\n",
1102 wScanCode, (pKbdInputData->Flags & KEY_BREAK) ? 1u : 0, wVk);
1103
1104 if (wVk)
1105 {
1106 KEYBDINPUT KbdInput;
1107
1108 /* Support numlock */
1110 {
1111 wVk = IntTranslateNumpadKey(wVk & 0xFF);
1112 }
1113
1114 /* Send keyboard input */
1115 KbdInput.wVk = wVk & 0xFF;
1116 KbdInput.wScan = wScanCode & 0x7F;
1117 KbdInput.dwFlags = 0;
1118 if (pKbdInputData->Flags & KEY_BREAK)
1119 KbdInput.dwFlags |= KEYEVENTF_KEYUP;
1120
1121 if (wVk & KBDEXT)
1122 KbdInput.dwFlags |= KEYEVENTF_EXTENDEDKEY;
1123 //
1124 // Based on wine input:test_Input_blackbox this is okay. It seems the
1125 // bit did not get set and more research is needed. Now the right
1126 // shift works.
1127 //
1128 if (wVk == VK_RSHIFT)
1129 KbdInput.dwFlags |= KEYEVENTF_EXTENDEDKEY;
1130
1131 KbdInput.time = 0;
1132 KbdInput.dwExtraInfo = pKbdInputData->ExtraInformation;
1133 UserSendKeyboardInput(&KbdInput, FALSE);
1134
1135 /* E1 keys don't have break code */
1136 if (pKbdInputData->Flags & KEY_E1)
1137 {
1138 /* Send key up event */
1139 KbdInput.dwFlags |= KEYEVENTF_KEYUP;
1140 UserSendKeyboardInput(&KbdInput, FALSE);
1141 }
1142 }
1143}
#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:986
static WORD IntTranslateNumpadKey(WORD wVk)
Definition: keyboard.c:272

Referenced by RawInputThreadMain().

◆ UserSendKeyboardInput()

BOOL NTAPI UserSendKeyboardInput ( KEYBDINPUT pKbdInput,
BOOL  bInjected 
)

Definition at line 986 of file keyboard.c.

987{
988 WORD wScanCode, wVk;
989 PKL pKl = NULL;
990 PKBDTABLES pKbdTbl;
991 PUSER_MESSAGE_QUEUE pFocusQueue;
993 BOOL bExt = (pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
994
996
997 /* Find the target thread whose locale is in effect */
998 pFocusQueue = IntGetFocusMessageQueue();
999
1000 if (pFocusQueue && pFocusQueue->ptiKeyboard)
1001 {
1002 pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
1003 }
1004
1005 if (!pKl)
1007 if (!pKl)
1008 {
1009 ERR("No keyboard layout!\n");
1010 return FALSE;
1011 }
1012
1013 pKbdTbl = pKl->spkf->pKbdTbl;
1014
1015 /* Note: wScan field is always used */
1016 wScanCode = pKbdInput->wScan;
1017
1018 if (pKbdInput->dwFlags & KEYEVENTF_UNICODE)
1019 {
1020 /* Generate WM_KEYDOWN msg with wParam == VK_PACKET and
1021 high order word of lParam == pKbdInput->wScan */
1022 wVk = VK_PACKET;
1023 }
1024 else
1025 {
1026 wScanCode &= 0x7F;
1027 if (pKbdInput->dwFlags & KEYEVENTF_SCANCODE)
1028 {
1029 /* Don't ignore invalid scan codes */
1030 wVk = IntVscToVk(wScanCode | (bExt ? 0xE000 : 0), pKbdTbl);
1031 if (!wVk) /* use 0xFF if vsc is invalid */
1032 wVk = 0xFF;
1033 }
1034 else
1035 {
1036 wVk = pKbdInput->wVk;
1037 }
1038
1039 /* Remove all virtual key flags (KBDEXT, KBDMULTIVK, KBDSPECIAL, KBDNUMPAD) */
1040 wVk &= 0xFF;
1041 }
1042
1043 /* If time is given, use it */
1044 if (pKbdInput->time)
1045 dwTime = pKbdInput->time;
1046 else
1047 {
1049 }
1050
1051 if (wVk == VK_RMENU && (pKbdTbl->fLocaleFlags & KLLF_ALTGR))
1052 {
1053 /* For AltGr keyboards RALT generates CTRL events */
1054 ProcessKeyEvent(VK_LCONTROL, 0, pKbdInput->dwFlags & KEYEVENTF_KEYUP, bInjected, dwTime, 0);
1055 }
1056
1057 /* Finally process this key */
1058 return ProcessKeyEvent(wVk, wScanCode, pKbdInput->dwFlags, bInjected, dwTime, pKbdInput->dwExtraInfo);
1059}
PPROCESSINFO gppiInputProvider
Definition: ntuser.c:16
BOOL NTAPI ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
Definition: keyboard.c:800

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 = 0

◆ 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 co_IntProcessKeyboardMessage().

◆ gpKeyboardIndicatorTrans

PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL
static

Definition at line 15 of file keyboard.c.

Referenced by IntKeyboardUpdateLeds(), and UserInitKeyboard().