ReactOS 0.4.16-dev-1946-g52006dd
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}
LONG_PTR LPARAM
Definition: minwindef.h:175
unsigned int UINT
Definition: ndis.h:50
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
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:3914
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:103
BYTE gafAsyncKeyState[256 *2/8]
Definition: keyboard.c:13
#define WM_KEYUP
Definition: winuser.h:1744
#define LLKHF_EXTENDED
Definition: winuser.h:2687
#define VK_CONTROL
Definition: winuser.h:2239
#define HC_ACTION
Definition: winuser.h:48
#define LLKHF_ALTDOWN
Definition: winuser.h:2689
#define LLKHF_UP
Definition: winuser.h:2690
#define WH_KEYBOARD_LL
Definition: winuser.h:43
#define LLKHF_INJECTED
Definition: winuser.h:2688
#define KEYEVENTF_EXTENDEDKEY
Definition: winuser.h:1112
#define WM_KEYDOWN
Definition: winuser.h:1743
#define KEYEVENTF_KEYUP
Definition: winuser.h:1113
#define WM_SYSKEYDOWN
Definition: winuser.h:1747
#define VK_MENU
Definition: winuser.h:2240

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

861{
862 if (bIsDown) /* Toggle key combination is pressed? */
863 {
864 if (wVk == VK_LSHIFT)
865 *pKeyState = INPUTLANGCHANGE_FORWARD;
866 else if (wVk == VK_RSHIFT)
867 *pKeyState = INPUTLANGCHANGE_BACKWARD;
868 else if (!wVk && IS_KEY_DOWN(gafAsyncKeyState, VK_LSHIFT))
869 *pKeyState = INPUTLANGCHANGE_FORWARD;
870 else if (!wVk && IS_KEY_DOWN(gafAsyncKeyState, VK_RSHIFT))
871 *pKeyState = INPUTLANGCHANGE_BACKWARD;
872 else
873 return FALSE;
874 }
875 else
876 {
877 if (*pKeyState == 0)
878 return FALSE;
879
880 IntLanguageToggle(pFocusQueue, (pKeyState == &gLayoutToggleKeyState), *pKeyState);
881 *pKeyState = 0;
882 }
883 return TRUE;
884}
#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:2319
#define VK_LSHIFT
Definition: winuser.h:2318

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:2320
#define VK_RCONTROL
Definition: winuser.h:2321
#define VK_RMENU
Definition: winuser.h:2323
#define VK_SHIFT
Definition: winuser.h:2238
#define VK_LMENU
Definition: winuser.h:2322

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 & KL_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
#define KL_UNLOAD
Definition: undocuser.h:183
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_writes_opt_ NumCharacters PUSHORT _Inout_ PUSHORT _In_ UCHAR _In_opt_ USHORT LangID
Definition: wdfusb.h:1083

Referenced by 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:33
#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 STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#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
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:2242
#define VK_SCROLL
Definition: winuser.h:2316
#define VK_NUMLOCK
Definition: winuser.h:2315

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;
825 PTHREADINFO pti;
826 PKL pkl;
827 WPARAM wParam = 0;
828
829 if (!pFocusQueue)
830 {
831 ERR("IntLanguageToggle(): NULL pFocusQueue\n");
832 return;
833 }
834 pWnd = pFocusQueue->spwndFocus;
835 if (!pWnd)
836 pWnd = pFocusQueue->spwndActive;
837 if (!pWnd)
838 return;
839
840 pti = pWnd->head.pti;
841 pkl = pti->KeyboardLayout;
842
843 if (nKeyState == INPUTLANGCHANGE_FORWARD)
844 pkl = IntGetNextKL(pkl, TRUE, bSameLang);
845 else if (nKeyState == INPUTLANGCHANGE_BACKWARD)
846 pkl = IntGetNextKL(pkl, FALSE, bSameLang);
847
848 if (gSystemFS & pkl->dwFontSigs)
849 wParam |= INPUTLANGCHANGE_SYSCHARSET;
850
851 UserPostMessage(UserHMGetHandle(pWnd), WM_INPUTLANGCHANGEREQUEST, wParam, (LPARAM)pkl->hkl);
852}
#define ERR(fmt,...)
Definition: precomp.h:57
WPARAM wParam
Definition: combotst.c:138
#define UserHMGetHandle(obj)
Definition: ntuser.h:230
UINT_PTR WPARAM
Definition: minwindef.h:174
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:1395

Referenced by IntCheckLanguageToggle().

◆ IntMapVirtualKeyEx()

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

Definition at line 1397 of file keyboard.c.

1398{
1399 UINT uRet = 0;
1400
1401 switch (Type)
1402 {
1403 case MAPVK_VK_TO_VSC:
1404 uCode = IntFixVk(uCode, FALSE);
1405 uRet = IntVkToVsc(uCode, pKbdTbl);
1406 if (uRet > 0xFF) // Fail for scancodes with prefix (e0, e1)
1407 uRet = 0;
1408 break;
1409
1410 case MAPVK_VSC_TO_VK:
1411 uRet = IntVscToVk(uCode, pKbdTbl) & 0xFF;
1412 uRet = IntSimplifyVk(uRet);
1413 break;
1414
1415 case MAPVK_VK_TO_CHAR:
1416 uRet = (UINT)IntVkToChar(uCode, pKbdTbl);
1417 break;
1418
1419 case MAPVK_VSC_TO_VK_EX:
1420 uRet = IntVscToVk(uCode, pKbdTbl) & 0xFF;
1421 break;
1422
1423 case MAPVK_VK_TO_VSC_EX:
1424 uRet = IntVkToVsc(uCode, pKbdTbl);
1425 break;
1426
1427 default:
1429 ERR("Wrong type value: %u\n", Type);
1430 }
1431
1432 return uRet;
1433}
Type
Definition: Type.h:7
#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:2394
#define MAPVK_VSC_TO_VK
Definition: winuser.h:2392
#define MAPVK_VK_TO_CHAR
Definition: winuser.h:2393
#define MAPVK_VK_TO_VSC
Definition: winuser.h:2391
#define MAPVK_VK_TO_VSC_EX
Definition: winuser.h:2395

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: precomp.h:61
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:104
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 1280 of file keyboard.c.

1282{
1283 PTHREADINFO pti;
1284 INT cch = 0, i;
1285 WCHAR wch[3] = { 0 };
1286 MSG NewMsg = { 0 };
1287 PKBDTABLES pKbdTbl;
1288 BOOL bResult = FALSE;
1289
1290 switch(lpMsg->message)
1291 {
1292 case WM_KEYDOWN:
1293 case WM_KEYUP:
1294 case WM_SYSKEYDOWN:
1295 case WM_SYSKEYUP:
1296 break;
1297 default:
1298 return FALSE;
1299 }
1300
1302
1303 if (!pti->KeyboardLayout)
1304 {
1305 PKL pDefKL = W32kGetDefaultKeyLayout();
1306 UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pDefKL);
1307 if (pDefKL)
1308 {
1309 pti->pClientInfo->hKL = pDefKL->hkl;
1310 pKbdTbl = pDefKL->spkf->pKbdTbl;
1311 }
1312 else
1313 {
1314 pti->pClientInfo->hKL = NULL;
1315 pKbdTbl = NULL;
1316 }
1317 }
1318 else
1319 pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
1320 if (!pKbdTbl)
1321 return FALSE;
1322
1323 if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
1324 return FALSE;
1325
1326 /* Init pt, hwnd and time msg fields */
1327 NewMsg.pt = gpsi->ptCursor;
1328 NewMsg.hwnd = lpMsg->hwnd;
1329 NewMsg.time = EngGetTickCount32();
1330
1331 TRACE("Enter IntTranslateKbdMessage msg %s, vk %x\n",
1332 lpMsg->message == WM_SYSKEYDOWN ? "WM_SYSKEYDOWN" : "WM_KEYDOWN", lpMsg->wParam);
1333
1334 if (lpMsg->wParam == VK_PACKET)
1335 {
1336 NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
1337 NewMsg.wParam = HIWORD(lpMsg->lParam);
1338 NewMsg.lParam = LOWORD(lpMsg->lParam);
1339 MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
1340 return TRUE;
1341 }
1342
1343 cch = IntToUnicodeEx(lpMsg->wParam,
1344 HIWORD(lpMsg->lParam) & 0xFF,
1345 pti->MessageQueue->afKeyState,
1346 wch,
1347 sizeof(wch) / sizeof(wch[0]),
1348 0,
1349 pKbdTbl);
1350
1351 if (cch)
1352 {
1353 if (cch > 0) /* Normal characters */
1354 NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
1355 else /* Dead character */
1356 {
1357 cch = -cch;
1358 NewMsg.message =
1360 }
1361 NewMsg.lParam = lpMsg->lParam;
1362
1363 /* Send all characters */
1364 for (i = 0; i < cch; ++i)
1365 {
1366 TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam);
1367 NewMsg.wParam = wch[i];
1368 MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
1369 }
1370 bResult = TRUE;
1371 }
1372
1373 TRACE("Leave IntTranslateKbdMessage ret %d, cch %d, msg %x, wch %x\n",
1374 bResult, cch, NewMsg.message, NewMsg.wParam);
1375 return bResult;
1376}
#define EngGetTickCount32()
Definition: eng.h:43
PSERVERINFO gpsi
Definition: imm.c:18
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
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
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:3217
HWND hwnd
Definition: winuser.h:3216
WPARAM wParam
Definition: winuser.h:3218
LPARAM lParam
Definition: winuser.h:3219
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:512
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:885
#define WM_SYSCHAR
Definition: winuser.h:1749
#define WM_SYSDEADCHAR
Definition: winuser.h:1750
#define WM_SYSKEYUP
Definition: winuser.h:1748
#define WM_CHAR
Definition: winuser.h:1745
#define WM_DEADCHAR
Definition: winuser.h:1746

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:2236
#define VK_NUMPAD3
Definition: winuser.h:2278
#define VK_NUMPAD1
Definition: winuser.h:2276
#define VK_NUMPAD2
Definition: winuser.h:2277
#define VK_NUMPAD4
Definition: winuser.h:2279
#define VK_UP
Definition: winuser.h:2261
#define VK_NUMPAD0
Definition: winuser.h:2275
#define VK_NUMPAD6
Definition: winuser.h:2281
#define VK_NEXT
Definition: winuser.h:2257
#define VK_NUMPAD9
Definition: winuser.h:2284
#define VK_END
Definition: winuser.h:2258
#define VK_HOME
Definition: winuser.h:2259
#define VK_NUMPAD5
Definition: winuser.h:2280
#define VK_LEFT
Definition: winuser.h:2260
#define VK_NUMPAD7
Definition: winuser.h:2282
#define VK_RIGHT
Definition: winuser.h:2262
#define VK_DOWN
Definition: winuser.h:2263
#define VK_PRIOR
Definition: winuser.h:2256
#define VK_DELETE
Definition: winuser.h:2269
#define VK_NUMPAD8
Definition: winuser.h:2283
#define VK_DECIMAL
Definition: winuser.h:2289
#define VK_INSERT
Definition: winuser.h:2268

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:258
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:249

Referenced by GetAsyncKeyState(), and START_TEST().

◆ NtUserGetKeyNameText()

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

Definition at line 1588 of file keyboard.c.

1589{
1590 PTHREADINFO pti;
1591 DWORD i, dwRet = 0;
1592 SIZE_T cchKeyName;
1593 WORD wScanCode = (lParam >> 16) & 0xFF;
1594 BOOL bExtKey = (HIWORD(lParam) & KF_EXTENDED) ? TRUE : FALSE;
1595 PKBDTABLES pKbdTbl;
1596 VSC_LPWSTR *pKeyNames = NULL;
1597 CONST WCHAR *pKeyName = NULL;
1598 WCHAR KeyNameBuf[2];
1599
1600 TRACE("Enter NtUserGetKeyNameText\n");
1601
1603
1604 /* Get current keyboard layout */
1606 pKbdTbl = pti ? pti->KeyboardLayout->spkf->pKbdTbl : 0;
1607
1608 if (!pKbdTbl || cchSize < 1)
1609 {
1610 ERR("Invalid parameter\n");
1611 goto cleanup;
1612 }
1613
1614 /* "Do not care" flag */
1616 {
1617 /* Note: We could do vsc -> vk -> vsc conversion, instead of using
1618 hardcoded scan codes, but it's not what Windows does */
1619 if (wScanCode == SCANCODE_RSHIFT && !bExtKey)
1620 wScanCode = SCANCODE_LSHIFT;
1621 else if (wScanCode == SCANCODE_CTRL || wScanCode == SCANCODE_ALT)
1622 bExtKey = FALSE;
1623 }
1624
1625 if (bExtKey)
1626 pKeyNames = pKbdTbl->pKeyNamesExt;
1627 else
1628 pKeyNames = pKbdTbl->pKeyNames;
1629
1630 for (i = 0; pKeyNames[i].pwsz; i++)
1631 {
1632 if (pKeyNames[i].vsc == wScanCode)
1633 {
1634 pKeyName = pKeyNames[i].pwsz;
1635 break;
1636 }
1637 }
1638
1639 if (!pKeyName)
1640 {
1641 WORD wVk = IntVscToVk(wScanCode, pKbdTbl);
1642
1643 if (wVk)
1644 {
1645 KeyNameBuf[0] = IntVkToChar(wVk, pKbdTbl);
1646 KeyNameBuf[1] = 0;
1647 if (KeyNameBuf[0])
1648 pKeyName = KeyNameBuf;
1649 }
1650 }
1651
1652 if (pKeyName)
1653 {
1654 cchKeyName = wcslen(pKeyName);
1655 if (cchKeyName > (cchSize - 1UL))
1656 cchKeyName = cchSize - 1UL; // Don't count '\0'
1657
1658 _SEH2_TRY
1659 {
1660 ProbeForWrite(lpString, (cchKeyName + 1) * sizeof(WCHAR), 1);
1661 RtlCopyMemory(lpString, pKeyName, cchKeyName * sizeof(WCHAR));
1662 lpString[cchKeyName] = UNICODE_NULL;
1663 dwRet = cchKeyName;
1664 }
1666 {
1668 }
1669 _SEH2_END;
1670 }
1671 else
1672 {
1674 }
1675
1676cleanup:
1677 UserLeave();
1678 TRACE("Leave NtUserGetKeyNameText, ret=%lu\n", dwRet);
1679 return dwRet;
1680}
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#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:242
#define CONST
Definition: pedump.c:81
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
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:56
#define KF_EXTENDED
Definition: winuser.h:2482

Referenced by GetKeyNameTextA(), and GetKeyNameTextW().

◆ NtUserMapVirtualKeyEx()

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

Definition at line 1443 of file keyboard.c.

1444{
1445 PKBDTABLES pKbdTbl = NULL;
1446 UINT ret = 0;
1447
1448 TRACE("Enter NtUserMapVirtualKeyEx\n");
1450
1451 if (!dwhkl)
1452 {
1453 PTHREADINFO pti;
1454
1456 if (pti && pti->KeyboardLayout)
1457 pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
1458 }
1459 else
1460 {
1461 PKL pKl;
1462
1463 pKl = UserHklToKbl(dwhkl);
1464 if (pKl)
1465 pKbdTbl = pKl->spkf->pKbdTbl;
1466 }
1467
1468 if (pKbdTbl)
1469 ret = IntMapVirtualKeyEx(uCode, uType, pKbdTbl);
1470
1471 UserLeave();
1472 TRACE("Leave NtUserMapVirtualKeyEx, ret=%u\n", ret);
1473 return ret;
1474}
return ret
Definition: mutex.c:146
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:539
static UINT IntMapVirtualKeyEx(UINT uCode, UINT Type, PKBDTABLES pKbdTbl)
Definition: keyboard.c:1397

Referenced by MapVirtualKeyExA(), MapVirtualKeyExW(), and MapVirtualKeyW().

◆ NtUserToUnicodeEx()

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

Definition at line 1483 of file keyboard.c.

1491{
1492 PTHREADINFO pti;
1493 BYTE afKeyState[256 * 2 / 8] = {0};
1494 PWCHAR pwszBuff = NULL;
1495 INT i, iRet = 0;
1496 PKL pKl = NULL;
1498
1499 TRACE("Enter NtUserSetKeyboardState\n");
1500
1501 /* Return 0 if SC_KEY_UP bit is set */
1502 if (wScanCode & SC_KEY_UP || wVirtKey >= 0x100)
1503 {
1504 ERR("Invalid parameter\n");
1505 return 0;
1506 }
1507
1508 _SEH2_TRY
1509 {
1510 /* Probe and copy key state to smaller bitmap */
1511 ProbeForRead(pKeyStateUnsafe, 256 * sizeof(BYTE), 1);
1512 for (i = 0; i < 256; ++i)
1513 {
1514 if (pKeyStateUnsafe[i] & KS_DOWN_BIT)
1515 SET_KEY_DOWN(afKeyState, i, TRUE);
1516 if (pKeyStateUnsafe[i] & KS_LOCK_BIT)
1517 SET_KEY_LOCKED(afKeyState, i, TRUE);
1518 }
1519 }
1521 {
1522 ERR("Cannot copy key state\n");
1524 _SEH2_YIELD(return 0);
1525 }
1526 _SEH2_END;
1527
1528 pwszBuff = ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR) * cchBuff, TAG_STRING);
1529 if (!pwszBuff)
1530 {
1531 ERR("ExAllocatePoolWithTag(%u) failed\n", sizeof(WCHAR) * cchBuff);
1532 return 0;
1533 }
1534 RtlZeroMemory(pwszBuff, sizeof(WCHAR) * cchBuff);
1535
1536 UserEnterExclusive(); // Note: We modify wchDead static variable
1537
1538 if (dwhkl)
1539 pKl = UserHklToKbl(dwhkl);
1540
1541 if (!pKl)
1542 {
1544 pKl = pti->KeyboardLayout;
1545 }
1546
1547 if (pKl)
1548 {
1549 iRet = IntToUnicodeEx(wVirtKey,
1550 wScanCode,
1551 afKeyState,
1552 pwszBuff,
1553 cchBuff,
1554 wFlags,
1555 pKl->spkf->pKbdTbl);
1556
1557 if (iRet)
1558 {
1559 Status = MmCopyToCaller(pwszBuffUnsafe, pwszBuff, cchBuff * sizeof(WCHAR));
1560 }
1561 }
1562 else
1563 {
1564 ERR("No keyboard layout ?!\n");
1566 }
1567
1568 ExFreePoolWithTag(pwszBuff, TAG_STRING);
1569
1570 if (!NT_SUCCESS(Status))
1571 {
1572 iRet = 0;
1574 }
1575
1576 UserLeave();
1577 TRACE("Leave NtUserSetKeyboardState, ret=%i\n", iRet);
1578 return iRet;
1579}
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#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 TAG_STRING
Definition: oslist.h:22
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:184
uint16_t * PWCHAR
Definition: typedefs.h:56
#define SET_KEY_DOWN(ks, vk, down)
Definition: input.h:105
#define KS_DOWN_BIT
Definition: input.h:51
#define SC_KEY_UP
Definition: input.h:54
#define KS_LOCK_BIT
Definition: input.h:52
#define SET_KEY_LOCKED(ks, vk, down)
Definition: input.h:108
WINBASEAPI _In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon_undoc.h:337

◆ NtUserVkKeyScanEx()

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

Definition at line 1713 of file keyboard.c.

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

Referenced by VkKeyScanExA(), VkKeyScanExW(), and VkKeyScanW().

◆ ProcessKeyEvent()

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

Definition at line 892 of file keyboard.c.

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

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
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:88
_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:102
LONG bottom
Definition: windef.h:103
LONG top
Definition: windef.h:101
LONG left
Definition: windef.h:100
BOOL fIncSerialNumber
Definition: ntuser.h:1169
BOOL fGlobalHandle
Definition: ntuser.h:1168
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:124
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:1165
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:1391
#define SRCCOPY
Definition: wingdi.h:333
#define DCX_WINDOW
Definition: winuser.h:2149

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

1690{
1691 switch (dwTypeFlag)
1692 {
1693 case 0: /* Keyboard type */
1695 case 1: /* Keyboard Subtype */
1697 case 2: /* Number of F-keys */
1699 default:
1700 ERR("Unknown type!\n");
1701 return 0; /* Note: we don't have to set last error here */
1702 }
1703}
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 1195 of file keyboard.c.

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

Referenced by RawInputThreadMain().

◆ UserSendKeyboardInput()

BOOL NTAPI UserSendKeyboardInput ( KEYBDINPUT pKbdInput,
BOOL  bInjected 
)

Definition at line 1114 of file keyboard.c.

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

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