ReactOS 0.4.17-dev-1321-g5c122a9
keyboard.c File Reference
#include <win32k.h>
#include <cjkcode.h>
Include dependency graph for keyboard.c:

Go to the source code of this file.

Enumerations

enum  _ALTNUM_STATE {
  ALTNUM_INACTIVE , ALTNUM_OEM , ALTNUM_ACP , ALTNUM_HEX_ACP ,
  ALTNUM_HEX_UTF
}
 

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)
 
static BOOL IntHandleAltNumpad (_In_ WORD wVk, _In_ BOOL bIsDown, _In_ DWORD dwTime)
 Handles Alt+Numpad character composition.
 
BOOL NTAPI ProcessKeyEvent (WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
 
BOOL NTAPI UserSendKeyboardInput (KEYBDINPUT *pKbdInput, BOOL bInjected)
 
VOID WINAPI UserRawInputProcessKeyboardInput (PINPUT_DEVICE_INFO pDeviceInfo, PKEYBOARD_INPUT_DATA pKbdInputData, WORD wScanCode, WORD wVk)
 
VOID NTAPI UserProcessKeyboardInput (PINPUT_DEVICE_INFO pDeviceInfo, 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
 
static INT gLanguageToggleKeyState = 0
 
DWORD gdwLanguageToggleKey = 1
 
static INT gLayoutToggleKeyState = 0
 
DWORD gdwLayoutToggleKey = 2
 
static enum _ALTNUM_STATE gAltNumPadState = ALTNUM_INACTIVE
 
static ULONG gAltNumPadValue = 0
 
BOOL gbEnableHexNumpad = FALSE
 

Enumeration Type Documentation

◆ _ALTNUM_STATE

Enumerator
ALTNUM_INACTIVE 
ALTNUM_OEM 
ALTNUM_ACP 
ALTNUM_HEX_ACP 
ALTNUM_HEX_UTF 

Definition at line 26 of file keyboard.c.

27{
29 ALTNUM_OEM, // Alt xxx
30 ALTNUM_ACP, // Alt 0xxx
31 ALTNUM_HEX_ACP, // Alt .xxx
32 ALTNUM_HEX_UTF // Alt +xxx
static enum _ALTNUM_STATE gAltNumPadState
@ ALTNUM_INACTIVE
Definition: keyboard.c:28
@ ALTNUM_HEX_UTF
Definition: keyboard.c:32
@ ALTNUM_OEM
Definition: keyboard.c:29
@ ALTNUM_HEX_ACP
Definition: keyboard.c:31
@ ALTNUM_ACP
Definition: keyboard.c:30

Function Documentation

◆ co_CallLowLevelKeyboardHook()

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

Definition at line 685 of file keyboard.c.

686{
687 KBDLLHOOKSTRUCT KbdHookData;
688 UINT uMsg;
689
690 KbdHookData.vkCode = wVk;
691 KbdHookData.scanCode = wScanCode;
692 KbdHookData.flags = 0;
694 KbdHookData.flags |= LLKHF_EXTENDED;
696 KbdHookData.flags |= LLKHF_ALTDOWN;
698 KbdHookData.flags |= LLKHF_UP;
699 if (bInjected)
700 KbdHookData.flags |= LLKHF_INJECTED;
701 KbdHookData.time = dwTime;
702 KbdHookData.dwExtraInfo = dwExtraInfo;
703
704 /* Note: it doesnt support WM_SYSKEYUP */
706 uMsg = WM_KEYUP;
708 uMsg = WM_SYSKEYDOWN;
709 else
710 uMsg = WM_KEYDOWN;
711
712 return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, uMsg, (LPARAM)&KbdHookData);
713}
unsigned int UINT
Definition: sysinfo.c:13
LONG_PTR LPARAM
Definition: minwindef.h:175
_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
#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
DWORD dwTime
Definition: solitaire.cpp:27
ULONG_PTR dwExtraInfo
Definition: winuser.h:3920
#define IS_KEY_DOWN(ks, vk)
Definition: input.h:174
BYTE gafAsyncKeyState[256 *2/8]
Definition: keyboard.c:13

Referenced by ProcessKeyEvent().

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserKbd  )

◆ InitKeyboardImpl()

NTSTATUS NTAPI InitKeyboardImpl ( VOID  )

Definition at line 48 of file keyboard.c.

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

Referenced by DriverEntry().

◆ IntCheckLanguageToggle()

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

Definition at line 852 of file keyboard.c.

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

Referenced by ProcessKeyEvent().

◆ IntFixVk()

static WORD IntFixVk ( WORD  wVk,
BOOL  bExt 
)
static

Definition at line 245 of file keyboard.c.

246{
247 switch (wVk)
248 {
249 case VK_SHIFT:
250 return bExt ? VK_RSHIFT : VK_LSHIFT;
251
252 case VK_CONTROL:
253 return bExt ? VK_RCONTROL : VK_LCONTROL;
254
255 case VK_MENU:
256 return bExt ? VK_RMENU : VK_LMENU;
257
258 default:
259 return wVk;
260 }
261}
#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 296 of file keyboard.c.

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

Referenced by IntTranslateChar().

◆ IntGetNextKL()

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

Definition at line 794 of file keyboard.c.

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

◆ IntHandleAltNumpad()

static BOOL IntHandleAltNumpad ( _In_ WORD  wVk,
_In_ BOOL  bIsDown,
_In_ DWORD  dwTime 
)
static

Handles Alt+Numpad character composition.

Parameters
[in]wVkThe virtual key code of the key being input, in its "simplified" shift-less version, as given by IntSimplifyVk().
[in]bIsDownTRUE if the current key is being pressed; FALSE if it is released.
Returns
TRUE if no further key processing needs to be done; FALSE if regular key processing has to be done by the caller.

Definition at line 897 of file keyboard.c.

902{
903 if (bIsDown &&
906 {
907 TRACE("VK_MENU && !VK_CONTROL - wVk: 0x%04x\n", wVk);
908
909 /* Initialize the Alt+Numpad state if necessary */
911 {
912 if (gbEnableHexNumpad && (wVk == VK_DECIMAL)) // || (wVk == VK_OEM_PERIOD)
913 gAltNumPadState = ALTNUM_HEX_ACP, wVk = VK_NUMPAD0; // Replace '.' by '0'
914 else if (gbEnableHexNumpad && (wVk == VK_ADD)) // || (wVk == VK_OEM_PLUS)
915 gAltNumPadState = ALTNUM_HEX_UTF, wVk = VK_NUMPAD0; // Replace '+' by '0'
916 else if (wVk >= VK_NUMPAD0 && wVk <= VK_NUMPAD9) // || (wVk >= '0' && wVk <= '9')
918 else
919 return FALSE; /* Unhandled, do regular key processing */
920 }
921
922 /* Check the incoming key */
923 switch (gAltNumPadState)
924 {
925 case ALTNUM_OEM: case ALTNUM_ACP:
926 {
927 UINT uDigit;
928
929 /* Check if it is a numpad digit */
930 if (wVk >= VK_NUMPAD0 && wVk <= VK_NUMPAD9)
931 uDigit = wVk - VK_NUMPAD0;
932 // else if (wVk >= '0' && wVk <= '9')
933 // uDigit = wVk - '0';
934 else
935 break;
936
937 /* Build the decimal value; the value can overflow
938 * and be truncated (same behaviour as on Windows) */
939 gAltNumPadValue = (gAltNumPadValue * 10) + uDigit;
940 return TRUE; /* No key processing needs to be done */
941 }
943 {
944 UINT uDigit;
945
946 /* Check if it represents a valid hexadecimal digit */
947 if (wVk >= VK_NUMPAD0 && wVk <= VK_NUMPAD9)
948 uDigit = wVk - VK_NUMPAD0;
949 else if (wVk >= '0' && wVk <= '9')
950 uDigit = wVk - '0';
951 else if (wVk >= 'A' && wVk <= 'F')
952 uDigit = wVk - 'A' + 10;
953 else
954 break;
955
956 /* Build the hexadecimal value; the value can overflow
957 * and be truncated (same behaviour as on Windows) */
958 gAltNumPadValue = (gAltNumPadValue * 16) + uDigit;
959 return TRUE; /* No key processing needs to be done */
960 }
962 }
963
964 /* If the incoming key is not the ALT key, reset the Alt+Numpad state */
965 if (wVk != VK_MENU)
966 {
968 gAltNumPadValue = 0;
969 }
970 }
971 TRACE("gAltNumPadState: %lu, gAltNumPadValue: %lu\n",
973
974 /* Check for the end of an Alt+Numpad sequence, triggered by the ALT key release */
975 if ((gAltNumPadState != ALTNUM_INACTIVE) && !bIsDown && (wVk == VK_MENU))
976 {
978
979 TRACE("End of Alt+Numpad\n");
980 if (gAltNumPadValue != 0 && pFocusQueue && pFocusQueue->ptiKeyboard)
981 {
983 WCHAR wchUnicodeChar;
984
985 /* Convert the input codepoint value to UTF-16 */
987 {
988 /* Convert the Unicode codepoint to UTF-16 */
989 // FIXME: We currently support only the Basic Multilingual Plane
990 // (equivalent to UCS-2) and don't exclude the surrogate range
991 // (U+D800 to U+DFFF). In the future, we should handle all the
992 // valid values, generating two UTF-16 code units if necessary
993 // so as to support the other Unicode planes.
994 // See https://en.wikipedia.org/wiki/UTF-16#Description
995 wchUnicodeChar = (WCHAR)(gAltNumPadValue & 0xFFFF);
997 }
998 else
999 {
1000 NTSTATUS (NTAPI* pRtlCPToUnicodeN)(
1004 _In_reads_bytes_(BytesInString) PCCH String,
1005 _In_ ULONG BytesInString);
1006
1007 USHORT AnsiCP, OemCP, wCodePage, mbChar;
1008
1009 /* Check the current codepage and select a conversion function.
1010 * NOTE: Windows WIN32K invokes the ClientCharToWchar
1011 * USER32 callback to perform the conversion. */
1012 RtlGetDefaultCodePage(&AnsiCP, &OemCP);
1014 {
1015 // TODO: Handle console where we do not know its active
1016 // OEM codepage. In this case we need to directly send
1017 // the raw OEM numpad value, OR'ed with ALTNUMPAD_BIT.
1018 // For more details, see:
1019 // https://github.com/microsoft/terminal/blob/e20e1f7bf92b61580baea69483a74a7f4578a586/src/host/stream.cpp#L170
1020
1021 /* Use the current OEM codepage -> Unicode function */
1022 wCodePage = OemCP;
1023 pRtlCPToUnicodeN = RtlOemToUnicodeN;
1024 }
1025 else // if ((gAltNumPadState == ALTNUM_ACP) ||
1026 // (gAltNumPadState == ALTNUM_HEX_ACP))
1027 {
1028 /* Use the current ANSI codepage (ACP) MultiByte -> Unicode function */
1029 wCodePage = AnsiCP;
1030 pRtlCPToUnicodeN = RtlMultiByteToUnicodeN;
1031 }
1032
1033 /* For CJK codepages, keep the input value on 2 bytes,
1034 * otherwise truncate it to 1 byte for legacy behaviour. */
1035 if (IsCJKCodePage(wCodePage))
1036 {
1037 mbChar = (USHORT)(gAltNumPadValue & 0xFFFF);
1038 }
1039 else
1040 {
1041 /*
1042 * NOTE: the input value is considered modulo 256 as it is
1043 * stored in a 1-byte CHAR. Other input systems that hook and
1044 * re-implement the Alt+Numpad system (e.g. RichEdit, ...)
1045 * store instead the value in a 2-byte WORD, i.e. consider
1046 * the value modulo 65536.
1047 * See: https://devblogs.microsoft.com/oldnewthing/20240702-00/?p=109951
1048 */
1049 mbChar = (USHORT)(gAltNumPadValue & 0xFF);
1050 }
1051
1052 Status = pRtlCPToUnicodeN(&wchUnicodeChar,
1053 sizeof(wchUnicodeChar),
1054 NULL,
1055 (PCCH)&mbChar,
1056 sizeof(mbChar));
1057 }
1058
1059 /* Post the Unicode character to the focused message queue if conversion succeeded */
1060 if (NT_SUCCESS(Status))
1061 {
1062 MSG msgChar;
1063 msgChar.hwnd = pFocusQueue->spwndFocus ? UserHMGetHandle(pFocusQueue->spwndFocus) : NULL;
1064 msgChar.message = WM_CHAR;
1065 msgChar.wParam = wchUnicodeChar;
1066 msgChar.lParam = 1;
1067 msgChar.time = dwTime;
1068 msgChar.pt = gpsi->ptCursor;
1069
1070 MsqPostMessage(pFocusQueue->ptiKeyboard, &msgChar, FALSE, QS_KEY, 0, 0);
1071 }
1072 }
1073
1074 /* Reset the Alt+Numpad state */
1076 gAltNumPadValue = 0;
1077 }
1078
1079 return FALSE; /* More key processing has to be done */
1080}
LONG NTSTATUS
Definition: precomp.h:26
#define IsCJKCodePage(CodePage)
Definition: cjkcode.h:27
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define NTSTATUS
Definition: precomp.h:19
Status
Definition: gdiplustypes.h:24
PSERVERINFO gpsi
Definition: imm.c:18
#define UserHMGetHandle(obj)
Definition: ntuser.h:233
BOOL FASTCALL MsqPostMessage(PTHREADINFO pti, MSG *Msg, BOOLEAN HardwareMessage, DWORD MessageBits, DWORD dwQEvent, LONG_PTR ExtraInfo)
Definition: msgqueue.c:1337
*BytesInUnicodeString PWCH _In_ ULONG _Out_opt_ PULONG BytesInUnicodeString
Definition: rtlfuncs.h:2082
NTSYSAPI VOID NTAPI RtlGetDefaultCodePage(_Out_ PUSHORT AnsiCodePage, _Out_ PUSHORT OemCodePage)
*BytesInUnicodeString PWCH _In_ ULONG MaxBytesInUnicodeString
Definition: rtlfuncs.h:2081
_Use_decl_annotations_ NTSTATUS NTAPI RtlMultiByteToUnicodeN(_Out_ PWCH UnicodeString, _In_ ULONG UnicodeSize, _Out_opt_ PULONG ResultSize, _In_ PCCH MbString, _In_ ULONG MbSize)
Definition: nlsboot.c:63
_Use_decl_annotations_ NTSTATUS NTAPI RtlOemToUnicodeN(_Out_ PWCHAR UnicodeString, _In_ ULONG UnicodeSize, _Out_opt_ PULONG ResultSize, _In_ PCCH OemString, _In_ ULONG OemSize)
Definition: nlsboot.c:283
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _Out_opt_
Definition: no_sal2.h:214
#define _Out_writes_bytes_to_(s, c)
Definition: no_sal2.h:190
#define _In_
Definition: no_sal2.h:158
WCHAR * PWCH
Definition: ntbasedef.h:422
#define DEFAULT_UNREACHABLE
CONST CHAR * PCCH
Definition: ntbasedef.h:404
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
#define QS_KEY
Definition: winuser.h:885
#define VK_NUMPAD0
Definition: winuser.h:2275
#define VK_NUMPAD9
Definition: winuser.h:2284
#define VK_ADD
Definition: winuser.h:2286
#define WM_CHAR
Definition: winuser.h:1745
#define VK_DECIMAL
Definition: winuser.h:2289
PTHREADINFO ptiKeyboard
Definition: msgqueue.h:56
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2439
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_opt_ PCUNICODE_STRING UnicodeString
Definition: wdfstring.h:64
PUSER_MESSAGE_QUEUE FASTCALL IntGetFocusMessageQueue(VOID)
Definition: desktop.c:1335
static ULONG gAltNumPadValue
Definition: keyboard.c:35
BOOL gbEnableHexNumpad
Definition: keyboard.c:36

Referenced by ProcessKeyEvent().

◆ IntKeyboardGetIndicatorTrans()

NTSTATUS APIENTRY IntKeyboardGetIndicatorTrans ( HANDLE  hKeyboardDevice,
PKEYBOARD_INDICATOR_TRANSLATION *  ppIndicatorTrans 
)

Definition at line 67 of file keyboard.c.

69{
71 DWORD dwSize = 0;
74
76
78 dwSize,
80
81 while (pRet)
82 {
83 Status = ZwDeviceIoControlFile(hKeyboardDevice,
84 NULL,
85 NULL,
86 NULL,
87 &Block,
89 NULL, 0,
90 pRet, dwSize);
91
93 break;
94
96
98
100 dwSize,
102 }
103
104 if (!pRet)
106
107 if (!NT_SUCCESS(Status))
108 {
110 return Status;
111 }
112
113 *ppIndicatorTrans = pRet;
114 return Status;
115}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#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
PUSBUSER_REQUEST_HEADER Block
Definition: userreq.cpp:697
#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 124 of file keyboard.c.

127{
129 UINT i;
130 USHORT LedFlag = 0;
132
135
136 switch (wVk)
137 {
138 case VK_CAPITAL: LedFlag = KEYBOARD_CAPS_LOCK_ON; break;
139 case VK_NUMLOCK: LedFlag = KEYBOARD_NUM_LOCK_ON; break;
140 case VK_SCROLL: LedFlag = KEYBOARD_SCROLL_LOCK_ON; break;
141 default:
143 {
145 {
147 break;
148 }
149 }
150 }
151
152 if (LedFlag)
153 {
154 gIndicators.LedFlags ^= LedFlag;
155
156 /* Update the lights on the hardware */
157 Status = ZwDeviceIoControlFile(hKeyboardDevice,
158 NULL,
159 NULL,
160 NULL,
161 &Block,
163 &gIndicators, sizeof(gIndicators),
164 NULL, 0);
165
166 return Status;
167 }
168
169 return STATUS_SUCCESS;
170}
#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
#define VK_CAPITAL
Definition: winuser.h:2242
#define VK_SCROLL
Definition: winuser.h:2316
#define VK_NUMLOCK
Definition: winuser.h:2315
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

Referenced by ProcessKeyEvent().

◆ IntLanguageToggle()

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

Definition at line 815 of file keyboard.c.

819{
820 PWND pWnd;
821 PTHREADINFO pti;
822 PKL pkl;
823 WPARAM wParam = 0;
824
825 if (!pFocusQueue)
826 {
827 ERR("IntLanguageToggle(): NULL pFocusQueue\n");
828 return;
829 }
830 pWnd = pFocusQueue->spwndFocus;
831 if (!pWnd)
832 pWnd = pFocusQueue->spwndActive;
833 if (!pWnd)
834 return;
835
836 pti = pWnd->head.pti;
837 pkl = pti->KeyboardLayout;
838
839 if (nKeyState == INPUTLANGCHANGE_FORWARD)
840 pkl = IntGetNextKL(pkl, TRUE, bSameLang);
841 else if (nKeyState == INPUTLANGCHANGE_BACKWARD)
842 pkl = IntGetNextKL(pkl, FALSE, bSameLang);
843
844 if (gSystemFS & pkl->dwFontSigs)
845 wParam |= INPUTLANGCHANGE_SYSCHARSET;
846
847 UserPostMessage(UserHMGetHandle(pWnd), WM_INPUTLANGCHANGEREQUEST, wParam, (LPARAM)pkl->hkl);
848}
#define ERR(fmt,...)
Definition: precomp.h:57
WPARAM wParam
Definition: combotst.c:138
UINT_PTR WPARAM
Definition: minwindef.h:174
struct tagKL * KeyboardLayout
Definition: win32.h:91
Definition: ntuser.h:698
THRDESKHEAD head
Definition: ntuser.h:699
DWORD dwFontSigs
Definition: input.h:35
HKL hkl
Definition: input.h:33
DWORD gSystemFS
Definition: kbdlayout.c:24
static PKL FASTCALL IntGetNextKL(_In_ PKL pKL, _In_ BOOL bNext, _In_ BOOL bSameLang)
Definition: keyboard.c:794
BOOL FASTCALL UserPostMessage(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Definition: message.c:1397

Referenced by IntCheckLanguageToggle().

◆ IntMapVirtualKeyEx()

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

Definition at line 1661 of file keyboard.c.

1662{
1663 UINT uRet = 0;
1664
1665 switch (Type)
1666 {
1667 case MAPVK_VK_TO_VSC:
1668 uCode = IntFixVk(uCode, FALSE);
1669 uRet = IntVkToVsc(uCode, pKbdTbl);
1670 if (uRet > 0xFF) // Fail for scancodes with prefix (e0, e1)
1671 uRet = 0;
1672 break;
1673
1674 case MAPVK_VSC_TO_VK:
1675 uRet = IntVscToVk(uCode, pKbdTbl) & 0xFF;
1676 uRet = IntSimplifyVk(uRet);
1677 break;
1678
1679 case MAPVK_VK_TO_CHAR:
1680 uRet = (UINT)IntVkToChar(uCode, pKbdTbl);
1681 break;
1682
1683 case MAPVK_VSC_TO_VK_EX:
1684 uRet = IntVscToVk(uCode, pKbdTbl) & 0xFF;
1685 break;
1686
1687 case MAPVK_VK_TO_VSC_EX:
1688 uRet = IntVkToVsc(uCode, pKbdTbl);
1689 break;
1690
1691 default:
1693 ERR("Wrong type value: %u\n", Type);
1694 }
1695
1696 return uRet;
1697}
Type
Definition: Type.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#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
#define UINT
Definition: utils.c:29
static WORD IntFixVk(WORD wVk, BOOL bExt)
Definition: keyboard.c:245
static WCHAR FASTCALL IntVkToChar(WORD wVk, PKBDTABLES pKbdTbl)
Definition: keyboard.c:603
static WORD FASTCALL IntVkToVsc(WORD wVk, PKBDTABLES pKbdTbl)
Definition: keyboard.c:523
static WORD FASTCALL IntVscToVk(WORD wScanCode, PKBDTABLES pKbdTbl)
Definition: keyboard.c:560
static WORD IntSimplifyVk(WORD wVk)
Definition: keyboard.c:217
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:21

Referenced by NtUserMapVirtualKeyEx().

◆ IntSimplifyVk()

static WORD IntSimplifyVk ( WORD  wVk)
static

Definition at line 217 of file keyboard.c.

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

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

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

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

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

Referenced by IntToUnicodeEx(), and IntVkToChar().

◆ IntTranslateKbdMessage()

BOOL FASTCALL IntTranslateKbdMessage ( LPMSG  lpMsg,
UINT  flags 
)

Definition at line 1544 of file keyboard.c.

1546{
1547 PTHREADINFO pti;
1548 INT cch = 0, i;
1549 WCHAR wch[3] = { 0 };
1550 MSG NewMsg = { 0 };
1551 PKBDTABLES pKbdTbl;
1552 BOOL bResult = FALSE;
1553
1554 switch(lpMsg->message)
1555 {
1556 case WM_KEYDOWN:
1557 case WM_KEYUP:
1558 case WM_SYSKEYDOWN:
1559 case WM_SYSKEYUP:
1560 break;
1561 default:
1562 return FALSE;
1563 }
1564
1566
1567 if (!pti->KeyboardLayout)
1568 {
1569 PKL pDefKL = W32kGetDefaultKeyLayout();
1570 UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pDefKL);
1571 if (pDefKL)
1572 {
1573 pti->pClientInfo->hKL = pDefKL->hkl;
1574 pKbdTbl = pDefKL->spkf->pKbdTbl;
1575 }
1576 else
1577 {
1578 pti->pClientInfo->hKL = NULL;
1579 pKbdTbl = NULL;
1580 }
1581 }
1582 else
1583 pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
1584 if (!pKbdTbl)
1585 return FALSE;
1586
1587 if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
1588 return FALSE;
1589
1590 /* Init pt, hwnd and time msg fields */
1591 NewMsg.pt = gpsi->ptCursor;
1592 NewMsg.hwnd = lpMsg->hwnd;
1593 NewMsg.time = EngGetTickCount32();
1594
1595 TRACE("Enter IntTranslateKbdMessage msg %s, vk %x\n",
1596 lpMsg->message == WM_SYSKEYDOWN ? "WM_SYSKEYDOWN" : "WM_KEYDOWN", lpMsg->wParam);
1597
1598 if (lpMsg->wParam == VK_PACKET)
1599 {
1600 NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
1601 NewMsg.wParam = HIWORD(lpMsg->lParam);
1602 NewMsg.lParam = LOWORD(lpMsg->lParam);
1603 MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
1604 return TRUE;
1605 }
1606
1607 cch = IntToUnicodeEx(lpMsg->wParam,
1608 HIWORD(lpMsg->lParam) & 0xFF,
1609 pti->MessageQueue->afKeyState,
1610 wch,
1611 sizeof(wch) / sizeof(wch[0]),
1612 0,
1613 pKbdTbl);
1614
1615 if (cch)
1616 {
1617 if (cch > 0) /* Normal characters */
1618 NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
1619 else /* Dead character */
1620 {
1621 cch = -cch;
1622 NewMsg.message =
1624 }
1625 NewMsg.lParam = lpMsg->lParam;
1626
1627 /* Send all characters */
1628 for (i = 0; i < cch; ++i)
1629 {
1630 TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam);
1631 NewMsg.wParam = wch[i];
1632 MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
1633 }
1634 bResult = TRUE;
1635 }
1636
1637 TRACE("Leave IntTranslateKbdMessage ret %d, cch %d, msg %x, wch %x\n",
1638 bResult, cch, NewMsg.message, NewMsg.wParam);
1639 return bResult;
1640}
#define EngGetTickCount32()
Definition: eng.h:43
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:829
#define WM_SYSCHAR
Definition: winuser.h:1749
#define WM_SYSDEADCHAR
Definition: winuser.h:1750
#define WM_SYSKEYUP
Definition: winuser.h:1748
#define WM_DEADCHAR
Definition: winuser.h:1746
_In_ UINT _In_ UINT cch
Definition: shellapi.h:428
struct _CLIENTINFO * pClientInfo
Definition: win32.h:95
struct _USER_MESSAGE_QUEUE * MessageQueue
Definition: win32.h:90
struct _KBDTABLES * pKbdTbl
Definition: input.h:22
PKBDFILE spkf
Definition: input.h:34
UINT message
Definition: winuser.h:3223
HWND hwnd
Definition: winuser.h:3222
WPARAM wParam
Definition: winuser.h:3224
LPARAM lParam
Definition: winuser.h:3225
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:430
PVOID FASTCALL UserAssignmentLock(PVOID *ppvObj, PVOID pvNew)
Definition: object.c:861

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

◆ IntTranslateNumpadKey()

static WORD IntTranslateNumpadKey ( WORD  wVk)
static

Definition at line 270 of file keyboard.c.

271{
272 switch (wVk)
273 {
274 case VK_INSERT: return VK_NUMPAD0;
275 case VK_END: return VK_NUMPAD1;
276 case VK_DOWN: return VK_NUMPAD2;
277 case VK_NEXT: return VK_NUMPAD3;
278 case VK_LEFT: return VK_NUMPAD4;
279 case VK_CLEAR: return VK_NUMPAD5;
280 case VK_RIGHT: return VK_NUMPAD6;
281 case VK_HOME: return VK_NUMPAD7;
282 case VK_UP: return VK_NUMPAD8;
283 case VK_PRIOR: return VK_NUMPAD9;
284 case VK_DELETE: return VK_DECIMAL;
285 default: return wVk;
286 }
287}
#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_NUMPAD6
Definition: winuser.h:2281
#define VK_NEXT
Definition: winuser.h:2257
#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_INSERT
Definition: winuser.h:2268

Referenced by UserProcessKeyboardInput().

◆ IntVkToChar()

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

Definition at line 603 of file keyboard.c.

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

Referenced by IntMapVirtualKeyEx(), and NtUserGetKeyNameText().

◆ IntVkToVsc()

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

Definition at line 523 of file keyboard.c.

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

Referenced by IntMapVirtualKeyEx().

◆ IntVscToVk()

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

Definition at line 560 of file keyboard.c.

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

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

◆ NtUserGetAsyncKeyState()

SHORT APIENTRY NtUserGetAsyncKeyState ( INT  Key)

Definition at line 630 of file keyboard.c.

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

Referenced by GetAsyncKeyState(), and START_TEST().

◆ NtUserGetKeyNameText()

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

Definition at line 1852 of file keyboard.c.

1853{
1854 PTHREADINFO pti;
1855 DWORD i, dwRet = 0;
1856 SIZE_T cchKeyName;
1857 WORD wScanCode = (lParam >> 16) & 0xFF;
1858 BOOL bExtKey = (HIWORD(lParam) & KF_EXTENDED) ? TRUE : FALSE;
1859 PKBDTABLES pKbdTbl;
1860 VSC_LPWSTR *pKeyNames = NULL;
1861 CONST WCHAR *pKeyName = NULL;
1862 WCHAR KeyNameBuf[2];
1863
1864 TRACE("Enter NtUserGetKeyNameText\n");
1865
1867
1868 /* Get current keyboard layout */
1870 pKbdTbl = pti ? pti->KeyboardLayout->spkf->pKbdTbl : NULL;
1871
1872 if (!pKbdTbl || cchSize < 1)
1873 {
1874 ERR("Invalid parameter\n");
1875 goto cleanup;
1876 }
1877
1878 /* "Do not care" flag */
1880 {
1881 /* Note: We could do vsc -> vk -> vsc conversion, instead of using
1882 hardcoded scan codes, but it's not what Windows does */
1883 if (wScanCode == SCANCODE_RSHIFT && !bExtKey)
1884 wScanCode = SCANCODE_LSHIFT;
1885 else if (wScanCode == SCANCODE_CTRL || wScanCode == SCANCODE_ALT)
1886 bExtKey = FALSE;
1887 }
1888
1889 if (bExtKey)
1890 pKeyNames = pKbdTbl->pKeyNamesExt;
1891 else
1892 pKeyNames = pKbdTbl->pKeyNames;
1893
1894 for (i = 0; pKeyNames[i].pwsz; i++)
1895 {
1896 if (pKeyNames[i].vsc == wScanCode)
1897 {
1898 pKeyName = pKeyNames[i].pwsz;
1899 break;
1900 }
1901 }
1902
1903 if (!pKeyName)
1904 {
1905 WORD wVk = IntVscToVk(wScanCode, pKbdTbl);
1906
1907 if (wVk)
1908 {
1909 KeyNameBuf[0] = IntVkToChar(wVk, pKbdTbl);
1910 KeyNameBuf[1] = 0;
1911 if (KeyNameBuf[0])
1912 pKeyName = KeyNameBuf;
1913 }
1914 }
1915
1916 if (pKeyName)
1917 {
1918 cchKeyName = wcslen(pKeyName);
1919 if (cchKeyName > (cchSize - 1UL))
1920 cchKeyName = cchSize - 1UL; // Don't count '\0'
1921
1922 _SEH2_TRY
1923 {
1924 ProbeForWrite(lpString, (cchKeyName + 1) * sizeof(WCHAR), 1);
1925 RtlCopyMemory(lpString, pKeyName, cchKeyName * sizeof(WCHAR));
1926 lpString[cchKeyName] = UNICODE_NULL;
1927 dwRet = cchKeyName;
1928 }
1930 {
1932 }
1933 _SEH2_END;
1934 }
1935 else
1936 {
1938 }
1939
1940cleanup:
1941 UserLeave();
1942 TRACE("Leave NtUserGetKeyNameText, ret=%lu\n", dwRet);
1943 return dwRet;
1944}
LPARAM lParam
Definition: combotst.c:139
static void cleanup(void)
Definition: main.c:1335
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define SCANCODE_LSHIFT
Definition: kbd.h:184
#define SCANCODE_ALT
Definition: kbd.h:187
#define SCANCODE_RSHIFT
Definition: kbd.h:185
#define SCANCODE_CTRL
Definition: kbd.h:186
#define UNICODE_NULL
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:241
#define CONST
Definition: pedump.c:81
#define KF_EXTENDED
Definition: winuser.h:2482
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
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:30
#define LP_DO_NOT_CARE_BIT
Definition: input.h:93

Referenced by GetKeyNameTextA(), and GetKeyNameTextW().

◆ NtUserMapVirtualKeyEx()

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

Definition at line 1707 of file keyboard.c.

1708{
1709 PKBDTABLES pKbdTbl = NULL;
1710 UINT ret = 0;
1711
1712 TRACE("Enter NtUserMapVirtualKeyEx\n");
1714
1715 if (!dwhkl)
1716 {
1717 PTHREADINFO pti;
1718
1720 if (pti && pti->KeyboardLayout)
1721 pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
1722 }
1723 else
1724 {
1725 PKL pKl;
1726
1727 pKl = UserHklToKbl(dwhkl);
1728 if (pKl)
1729 pKbdTbl = pKl->spkf->pKbdTbl;
1730 }
1731
1732 if (pKbdTbl)
1733 ret = IntMapVirtualKeyEx(uCode, uType, pKbdTbl);
1734
1735 UserLeave();
1736 TRACE("Leave NtUserMapVirtualKeyEx, ret=%u\n", ret);
1737 return ret;
1738}
return ret
Definition: mutex.c:147
PKL NTAPI UserHklToKbl(HKL hKl)
Definition: kbdlayout.c:539
static UINT IntMapVirtualKeyEx(UINT uCode, UINT Type, PKBDTABLES pKbdTbl)
Definition: keyboard.c:1661

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

1755{
1756 PTHREADINFO pti;
1757 BYTE afKeyState[256 * 2 / 8] = {0};
1758 PWCHAR pwszBuff = NULL;
1759 INT i, iRet = 0;
1760 PKL pKl = NULL;
1762
1763 TRACE("Enter NtUserSetKeyboardState\n");
1764
1765 /* Return 0 if SC_KEY_UP bit is set */
1766 if (wScanCode & SC_KEY_UP || wVirtKey >= 0x100)
1767 {
1768 ERR("Invalid parameter\n");
1769 return 0;
1770 }
1771
1772 _SEH2_TRY
1773 {
1774 /* Probe and copy key state to smaller bitmap */
1775 ProbeForRead(pKeyStateUnsafe, 256 * sizeof(BYTE), 1);
1776 for (i = 0; i < 256; ++i)
1777 {
1778 if (pKeyStateUnsafe[i] & KS_DOWN_BIT)
1779 SET_KEY_DOWN(afKeyState, i, TRUE);
1780 if (pKeyStateUnsafe[i] & KS_LOCK_BIT)
1781 SET_KEY_LOCKED(afKeyState, i, TRUE);
1782 }
1783 }
1785 {
1786 ERR("Cannot copy key state\n");
1788 _SEH2_YIELD(return 0);
1789 }
1790 _SEH2_END;
1791
1792 pwszBuff = ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR) * cchBuff, TAG_STRING);
1793 if (!pwszBuff)
1794 {
1795 ERR("ExAllocatePoolWithTag(%u) failed\n", sizeof(WCHAR) * cchBuff);
1796 return 0;
1797 }
1798 RtlZeroMemory(pwszBuff, sizeof(WCHAR) * cchBuff);
1799
1800 UserEnterExclusive(); // Note: We modify wchDead static variable
1801
1802 if (dwhkl)
1803 pKl = UserHklToKbl(dwhkl);
1804
1805 if (!pKl)
1806 {
1808 pKl = pti->KeyboardLayout;
1809 }
1810
1811 if (pKl)
1812 {
1813 iRet = IntToUnicodeEx(wVirtKey,
1814 wScanCode,
1815 afKeyState,
1816 pwszBuff,
1817 cchBuff,
1818 wFlags,
1819 pKl->spkf->pKbdTbl);
1820
1821 if (iRet)
1822 {
1823 Status = MmCopyToCaller(pwszBuffUnsafe, pwszBuff, cchBuff * sizeof(WCHAR));
1824 }
1825 }
1826 else
1827 {
1828 ERR("No keyboard layout ?!\n");
1830 }
1831
1832 ExFreePoolWithTag(pwszBuff, TAG_STRING);
1833
1834 if (!NT_SUCCESS(Status))
1835 {
1836 iRet = 0;
1838 }
1839
1840 UserLeave();
1841 TRACE("Leave NtUserSetKeyboardState, ret=%i\n", iRet);
1842 return iRet;
1843}
#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:207
uint16_t * PWCHAR
Definition: typedefs.h:56
#define SET_KEY_DOWN(ks, vk, down)
Definition: input.h:176
#define KS_DOWN_BIT
Definition: input.h:88
#define SC_KEY_UP
Definition: input.h:91
#define KS_LOCK_BIT
Definition: input.h:89
#define SET_KEY_LOCKED(ks, vk, down)
Definition: input.h:179
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 1977 of file keyboard.c.

1981{
1982 PKBDTABLES pKbdTbl;
1983 PVK_TO_WCHAR_TABLE pVkToWchTbl;
1984 PVK_TO_WCHARS10 pVkToWch;
1985 PKL pKl = NULL;
1986 DWORD i, dwModBits = 0, dwModNumber = 0, Ret = (DWORD)-1;
1987
1988 TRACE("NtUserVkKeyScanEx() wch %u, KbdLayout 0x%p\n", wch, dwhkl);
1990
1991 if (bUsehKL)
1992 {
1993 // Use given keyboard layout
1994 if (dwhkl)
1995 pKl = UserHklToKbl(dwhkl);
1996 }
1997 else
1998 {
1999 // Use thread keyboard layout
2000 pKl = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->KeyboardLayout;
2001 }
2002
2003 if (!pKl)
2004 goto Exit;
2005
2006 pKbdTbl = pKl->spkf->pKbdTbl;
2007
2008 // Interate through all VkToWchar tables while pVkToWchars is not NULL
2009 for (i = 0; pKbdTbl->pVkToWcharTable[i].pVkToWchars; i++)
2010 {
2011 pVkToWchTbl = &pKbdTbl->pVkToWcharTable[i];
2012 pVkToWch = (PVK_TO_WCHARS10)(pVkToWchTbl->pVkToWchars);
2013
2014 // Interate through all virtual keys
2015 while (pVkToWch->VirtualKey)
2016 {
2017 for (dwModNumber = 0; dwModNumber < pVkToWchTbl->nModifications; dwModNumber++)
2018 {
2019 if (pVkToWch->wch[dwModNumber] == wch)
2020 {
2021 dwModBits = pKbdTbl->pCharModifiers->ModNumber[dwModNumber];
2022 TRACE("i %lu wC %04x: dwModBits %08x dwModNumber %08x MaxModBits %08x\n",
2023 i, wch, dwModBits, dwModNumber, pKbdTbl->pCharModifiers->wMaxModBits);
2024 Ret = (dwModBits << 8) | (pVkToWch->VirtualKey & 0xFF);
2025 goto Exit;
2026 }
2027 }
2028 pVkToWch = (PVK_TO_WCHARS10)(((BYTE *)pVkToWch) + pVkToWchTbl->cbSize);
2029 }
2030 }
2031Exit:
2032 UserLeave();
2033 return Ret;
2034}
#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 1088 of file keyboard.c.

1089{
1090 WORD wSimpleVk, wFixedVk, wVk2;
1091 PUSER_MESSAGE_QUEUE pFocusQueue;
1092 PTHREADINFO pti;
1094 BOOL bIsDown = (dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
1095 BOOL bPacket = (dwFlags & KEYEVENTF_UNICODE) ? TRUE : FALSE;
1096 BOOL bWasSimpleDown = FALSE, bPostMsg = TRUE, bIsSimpleDown;
1097 MSG Msg;
1098 static BOOL bMenuDownRecently = FALSE;
1099 BOOL bLangToggled = FALSE;
1100
1101 /* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
1102 wSimpleVk = IntSimplifyVk(wVk);
1103
1105 {
1106 /* Japanese special! */
1108 {
1109 if (wSimpleVk == VK_OEM_ATTN)
1110 wSimpleVk = VK_CAPITAL;
1111 else if (wSimpleVk == VK_OEM_COPY)
1112 wSimpleVk = VK_OEM_FINISH;
1113 }
1114 }
1115
1116 /* Handle Alt+Numpad character composition */
1117 if (IntHandleAltNumpad(wSimpleVk, bIsDown, dwTime))
1118 return TRUE;
1119
1120 bWasSimpleDown = IS_KEY_DOWN(gafAsyncKeyState, wSimpleVk);
1121
1122 /* Update key without shifts */
1123 wVk2 = IntFixVk(wSimpleVk, !bExt);
1124 bIsSimpleDown = bIsDown || IS_KEY_DOWN(gafAsyncKeyState, wVk2);
1125 UpdateAsyncKeyState(wSimpleVk, bIsSimpleDown);
1126
1127 if (bIsDown)
1128 {
1129 /* Update keyboard LEDs */
1131 wSimpleVk,
1132 wScanCode);
1133 }
1134
1135 /* Call WH_KEYBOARD_LL hook */
1136 if (co_CallLowLevelKeyboardHook(wVk, wScanCode, dwFlags, bInjected, dwTime, dwExtraInfo))
1137 {
1138 ERR("Kbd msg dropped by WH_KEYBOARD_LL hook\n");
1139 bPostMsg = FALSE;
1140 }
1141
1142 /* Check if this is a hotkey */
1143 if (co_UserProcessHotKeys(wSimpleVk, bIsDown))
1144 {
1145 TRACE("HotKey Processed\n");
1146 bPostMsg = FALSE;
1147 }
1148
1149 wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */
1150 if (wSimpleVk == VK_SHIFT) /* shift can't be extended */
1151 bExt = FALSE;
1152
1153 /* If we have a focus queue, post a keyboard message */
1154 pFocusQueue = IntGetFocusMessageQueue();
1155 TRACE("ProcessKeyEvent Q 0x%p Active pWnd 0x%p Focus pWnd 0x%p\n",
1156 pFocusQueue,
1157 (pFocusQueue ? pFocusQueue->spwndActive : NULL),
1158 (pFocusQueue ? pFocusQueue->spwndFocus : NULL));
1159
1160 /* If it is F10 or ALT is down and CTRL is up, it's a system key */
1161 if ( wVk == VK_F10 ||
1162 (wSimpleVk == VK_MENU && bMenuDownRecently) ||
1165 // See MSDN WM_SYSKEYDOWN/UP fixes last wine Win test_keyboard_input.
1166 (pFocusQueue && !pFocusQueue->spwndFocus) )
1167 {
1168 bMenuDownRecently = FALSE; // reset
1169 if (bIsDown)
1170 {
1171 Msg.message = WM_SYSKEYDOWN;
1172 if (wSimpleVk == VK_MENU)
1173 {
1174 // Note: If only LALT is pressed WM_SYSKEYUP is generated instead of WM_KEYUP
1175 bMenuDownRecently = TRUE;
1176 }
1177 }
1178 else
1179 Msg.message = WM_SYSKEYUP;
1180 }
1181 else
1182 {
1183 if (bIsDown)
1184 Msg.message = WM_KEYDOWN;
1185 else
1186 Msg.message = WM_KEYUP;
1187 }
1188
1189 /* Update async state of not simplified vk here.
1190 See user32_apitest:GetKeyState */
1191 UpdateAsyncKeyState(wFixedVk, bIsDown);
1192
1193 /* Alt-Tab/Esc Check. Use FocusQueue or RIT Queue */
1194 if (bIsSimpleDown && !bWasSimpleDown &&
1197 (wVk == VK_ESCAPE || wVk == VK_TAB))
1198 {
1199 TRACE("Alt-Tab/Esc Pressed wParam %x\n",wVk);
1200 }
1201
1202 /*
1203 * Check Language/Layout Toggle by [Left Alt]+Shift or Ctrl+Shift.
1204 * @see https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-2000-server/cc976564%28v=technet.10%29
1205 */
1207 {
1208 if (wSimpleVk == VK_SHIFT) /* Shift key is pressed or released */
1209 {
1210 UINT targetKey = ((gdwLanguageToggleKey == 1) ? VK_LMENU : VK_CONTROL);
1211 if (IS_KEY_DOWN(gafAsyncKeyState, targetKey))
1212 bLangToggled = IntCheckLanguageToggle(pFocusQueue, bIsDown, wVk, &gLanguageToggleKeyState);
1213 }
1214 else if ((wSimpleVk == VK_MENU && gdwLanguageToggleKey == 1) ||
1215 (wSimpleVk == VK_CONTROL && gdwLanguageToggleKey == 2))
1216 {
1218 bLangToggled = IntCheckLanguageToggle(pFocusQueue, bIsDown, 0, &gLanguageToggleKeyState);
1219 }
1220 }
1221 if (!bLangToggled && (gdwLayoutToggleKey == 1 || gdwLayoutToggleKey == 2))
1222 {
1223 if (wSimpleVk == VK_SHIFT) /* Shift key is pressed or released */
1224 {
1225 UINT targetKey = ((gdwLayoutToggleKey == 1) ? VK_LMENU : VK_CONTROL);
1226 if (IS_KEY_DOWN(gafAsyncKeyState, targetKey))
1227 IntCheckLanguageToggle(pFocusQueue, bIsDown, wVk, &gLayoutToggleKeyState);
1228 }
1229 else if ((wSimpleVk == VK_MENU && gdwLayoutToggleKey == 1) ||
1230 (wSimpleVk == VK_CONTROL && gdwLayoutToggleKey == 2))
1231 {
1233 IntCheckLanguageToggle(pFocusQueue, bIsDown, 0, &gLayoutToggleKeyState);
1234 }
1235 }
1236
1237 if (bIsDown && wVk == VK_SNAPSHOT)
1238 {
1239 if (pFocusQueue &&
1242 {
1243 // Snap from Active Window, Focus can be null.
1244 SnapWindow(pFocusQueue->spwndActive ? UserHMGetHandle(pFocusQueue->spwndActive) : NULL);
1245 }
1246 else
1247 SnapWindow(NULL); // Snap Desktop.
1248 }
1249 else if (pFocusQueue && bPostMsg)
1250 {
1251 PWND Wnd = pFocusQueue->spwndFocus; // SysInit.....
1252
1253 pti = pFocusQueue->ptiKeyboard;
1254
1255 if (!Wnd && pFocusQueue->spwndActive) // SysInit.....
1256 {
1257 // Going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input.
1258 Wnd = pFocusQueue->spwndActive;
1259 }
1260 if (Wnd) pti = Wnd->head.pti;
1261
1262 /* Init message */
1263 Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
1264 Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */
1265 Msg.lParam = MAKELPARAM(1, wScanCode);
1266 Msg.time = dwTime;
1267 Msg.pt = gpsi->ptCursor;
1268
1269 if ( Msg.message == WM_KEYDOWN || Msg.message == WM_SYSKEYDOWN )
1270 {
1271 if ( (Msg.wParam == VK_SHIFT ||
1272 Msg.wParam == VK_CONTROL ||
1273 Msg.wParam == VK_MENU ) &&
1275 {
1276 ERR("Set last input\n");
1277 //ptiLastInput = pti;
1278 }
1279 }
1280
1281 /* If it is VK_PACKET, high word of wParam is used for wchar */
1282 if (!bPacket)
1283 {
1284 if (bExt)
1285 Msg.lParam |= KF_EXTENDED << 16;
1287 Msg.lParam |= KF_ALTDOWN << 16;
1288 if (bWasSimpleDown)
1289 Msg.lParam |= KF_REPEAT << 16;
1290 if (!bIsDown)
1291 Msg.lParam |= KF_UP << 16;
1292 /* FIXME: Set KF_DLGMODE and KF_MENUMODE when needed */
1293 if (pFocusQueue->QF_flags & QF_DIALOGACTIVE)
1294 Msg.lParam |= KF_DLGMODE << 16;
1295 if (pFocusQueue->MenuOwner) // pti->pMenuState->fMenuStarted
1296 Msg.lParam |= KF_MENUMODE << 16;
1297 }
1298
1299 // Post mouse move before posting key buttons, to keep it syned.
1300 if (pFocusQueue->QF_flags & QF_MOUSEMOVED)
1301 {
1303 }
1304
1305 /* Post a keyboard message */
1306 TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
1307 if (!Wnd) {ERR("Window is NULL\n");}
1308 MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0, dwExtraInfo);
1309 }
1310 return TRUE;
1311}
struct @1907 Msg[]
VOID FASTCALL IntCoalesceMouseMove(PTHREADINFO pti)
Definition: msgqueue.c:551
#define QF_DIALOGACTIVE
Definition: msgqueue.h:109
#define QF_MOUSEMOVED
Definition: msgqueue.h:102
#define VK_SNAPSHOT
Definition: winuser.h:2267
#define VK_TAB
Definition: winuser.h:2235
#define MAKELPARAM(l, h)
Definition: winuser.h:4116
#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
#define LANG_JAPANESE
Definition: nls.h:76
#define PRIMARYLANGID(l)
Definition: nls.h:16
USHORT gusLanguageID
Definition: init.c:12
BOOL NTAPI co_UserProcessHotKeys(WORD wVk, BOOL bIsDown)
Definition: hotkey.c:191
HANDLE ghKeyboardDevice
Definition: input.c:33
static NTSTATUS APIENTRY IntKeyboardUpdateLeds(HANDLE hKeyboardDevice, WORD wVk, WORD wScanCode)
Definition: keyboard.c:124
static VOID SnapWindow(HWND hWnd)
Definition: keyboard.c:721
DWORD gdwLanguageToggleKey
Definition: keyboard.c:19
DWORD gdwLayoutToggleKey
Definition: keyboard.c:21
static BOOL IntCheckLanguageToggle(_In_ PUSER_MESSAGE_QUEUE pFocusQueue, _In_ BOOL bIsDown, _In_ WORD wVk, _Inout_ PINT pKeyState)
Definition: keyboard.c:852
static LRESULT co_CallLowLevelKeyboardHook(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
Definition: keyboard.c:685
static BOOL IntHandleAltNumpad(_In_ WORD wVk, _In_ BOOL bIsDown, _In_ DWORD dwTime)
Handles Alt+Numpad character composition.
Definition: keyboard.c:897
static VOID NTAPI UpdateAsyncKeyState(WORD wVk, BOOL bIsDown)
Definition: keyboard.c:664
static INT gLanguageToggleKeyState
Definition: keyboard.c:18

Referenced by UserSendKeyboardInput().

◆ SnapWindow()

static VOID SnapWindow ( HWND  hWnd)
static

Definition at line 721 of file keyboard.c.

722{
723 HBITMAP hbm = NULL, hbmOld;
724 HDC hdc = NULL, hdcMem;
725 SETCLIPBDATA scd;
726 INT cx, cy;
727 PWND pWnd = NULL;
728
729 TRACE("SnapWindow(%p)\n", hWnd);
730
731 /* If no windows is given, make snapshot of desktop window */
732 if (!hWnd)
734
736 if (!pWnd)
737 {
738 ERR("Invalid window\n");
739 goto cleanup;
740 }
741
743 if (!hdc)
744 {
745 ERR("UserGetDCEx failed!\n");
746 goto cleanup;
747 }
748
749 cx = pWnd->rcWindow.right - pWnd->rcWindow.left;
750 cy = pWnd->rcWindow.bottom - pWnd->rcWindow.top;
751
753 if (!hbm)
754 {
755 ERR("NtGdiCreateCompatibleBitmap failed!\n");
756 goto cleanup;
757 }
758
760 if (!hdcMem)
761 {
762 ERR("NtGdiCreateCompatibleDC failed!\n");
763 goto cleanup;
764 }
765
766 hbmOld = NtGdiSelectBitmap(hdcMem, hbm);
767 NtGdiBitBlt(hdcMem, 0, 0, cx, cy, hdc, 0, 0, SRCCOPY, CLR_INVALID, 0);
768 NtGdiSelectBitmap(hdcMem, hbmOld);
770
771 /* Save snapshot in clipboard */
773 {
776 scd.fGlobalHandle = FALSE;
778 {
779 /* Bitmap is managed by system now */
780 hbm = NULL;
781 }
783 }
784
785cleanup:
786 if (hbm)
788 if (hdc)
789 UserReleaseDC(pWnd, hdc, FALSE);
790}
#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
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
_In_ HBITMAP hbm
Definition: ntgdi.h:2804
__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)
#define DCX_WINDOW
Definition: winuser.h:2149
long bottom
Definition: dcommon.idl:29
long right
Definition: dcommon.idl:29
long left
Definition: dcommon.idl:29
long top
Definition: dcommon.idl:29
RECT rcWindow
Definition: ntuser.h:720
BOOL fIncSerialNumber
Definition: ntuser.h:1176
BOOL fGlobalHandle
Definition: ntuser.h:1175
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:123
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:1402
#define CLR_INVALID
Definition: wingdi.h:883
#define SRCCOPY
Definition: wingdi.h:333

Referenced by ProcessKeyEvent().

◆ UpdateAsyncKeyState()

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

Definition at line 664 of file keyboard.c.

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

Referenced by ProcessKeyEvent().

◆ UserGetKeyboardType()

DWORD FASTCALL UserGetKeyboardType ( DWORD  dwTypeFlag)

Definition at line 1952 of file keyboard.c.

1954{
1955 switch (dwTypeFlag)
1956 {
1957 case 0: /* Keyboard type */
1959 case 1: /* Keyboard Subtype */
1961 case 2: /* Number of F-keys */
1963 default:
1964 ERR("Unknown type!\n");
1965 return 0; /* Note: we don't have to set last error here */
1966 }
1967}
UCHAR Subtype
Definition: ntddkbd.h:102

Referenced by NtUserCallOneParam().

◆ UserInitKeyboard()

VOID NTAPI UserInitKeyboard ( HANDLE  hKeyboardDevice)

Definition at line 178 of file keyboard.c.

179{
182
184
185 Status = ZwDeviceIoControlFile(hKeyboardDevice,
186 NULL,
187 NULL,
188 NULL,
189 &Block,
191 NULL, 0,
193 sizeof(gIndicators));
194
195 if (!NT_SUCCESS(Status))
196 {
197 WARN("NtDeviceIoControlFile() failed, ignored\n");
200 }
201
208}
#define IOCTL_KEYBOARD_QUERY_INDICATORS
Definition: ntddkbd.h:35
NTSTATUS APIENTRY IntKeyboardGetIndicatorTrans(HANDLE hKeyboardDevice, PKEYBOARD_INDICATOR_TRANSLATION *ppIndicatorTrans)
Definition: keyboard.c:67

Referenced by ProcessDeviceChanges().

◆ UserProcessKeyboardInput()

VOID NTAPI UserProcessKeyboardInput ( PINPUT_DEVICE_INFO  pDeviceInfo,
PKEYBOARD_INPUT_DATA  pKbdInputData 
)

Definition at line 1455 of file keyboard.c.

1458{
1459 WORD wScanCode, wVk;
1460 PKL pKl = NULL;
1461 PKBDTABLES pKbdTbl;
1462 PUSER_MESSAGE_QUEUE pFocusQueue;
1463
1464 /* Calculate scan code with prefix */
1465 wScanCode = pKbdInputData->MakeCode & 0x7F;
1466 if (pKbdInputData->Flags & KEY_E0)
1467 wScanCode |= 0xE000;
1468 if (pKbdInputData->Flags & KEY_E1)
1469 wScanCode |= 0xE100;
1470
1471 /* Find the target thread whose locale is in effect */
1472 pFocusQueue = IntGetFocusMessageQueue();
1473
1474 if (pFocusQueue && pFocusQueue->ptiKeyboard)
1475 {
1476 pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
1477 }
1478
1479 if (!pKl)
1481 if (!pKl)
1482 return;
1483
1484 pKbdTbl = pKl->spkf->pKbdTbl;
1485
1486 /* Convert scan code to virtual key.
1487 Note: We could call UserSendKeyboardInput using scan code,
1488 but it wouldn't interpret E1 key(s) properly */
1489 wVk = IntVscToVk(wScanCode, pKbdTbl);
1490 TRACE("UserProcessKeyboardInput: %x (break: %u) -> %x\n",
1491 wScanCode, (pKbdInputData->Flags & KEY_BREAK) ? 1u : 0, wVk);
1492
1493 if (RawInputEnabled == TRUE)
1494 UserRawInputProcessKeyboardInput(pDeviceInfo, pKbdInputData, wScanCode, wVk);
1495
1496 if (wVk)
1497 {
1498 KEYBDINPUT KbdInput;
1499
1500 /* Support numlock */
1502 {
1503 wVk = IntTranslateNumpadKey(wVk & 0xFF);
1504 }
1505
1506 /* Send keyboard input */
1507 KbdInput.wVk = wVk & 0xFF;
1508 KbdInput.wScan = wScanCode & 0x7F;
1509 KbdInput.dwFlags = 0;
1510 if (pKbdInputData->Flags & KEY_BREAK)
1511 KbdInput.dwFlags |= KEYEVENTF_KEYUP;
1512
1513 if (wVk & KBDEXT)
1514 KbdInput.dwFlags |= KEYEVENTF_EXTENDEDKEY;
1515 //
1516 // Based on wine input:test_Input_blackbox this is okay. It seems the
1517 // bit did not get set and more research is needed. Now the right
1518 // shift works.
1519 //
1520 if (wVk == VK_RSHIFT)
1521 KbdInput.dwFlags |= KEYEVENTF_EXTENDEDKEY;
1522
1523 KbdInput.time = 0;
1524 KbdInput.dwExtraInfo = pKbdInputData->ExtraInformation;
1525 UserSendKeyboardInput(&KbdInput, FALSE);
1526
1527 /* E1 keys don't have break code */
1528 if (pKbdInputData->Flags & KEY_E1)
1529 {
1530 /* Send key up event */
1531 KbdInput.dwFlags |= KEYEVENTF_KEYUP;
1532 UserSendKeyboardInput(&KbdInput, FALSE);
1533 }
1534 }
1535}
#define KBDNUMPAD
Definition: kbd.h:66
#define KBDEXT
Definition: kbd.h:63
#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
BOOLEAN RawInputEnabled
Definition: rawinput.c:38
VOID WINAPI UserRawInputProcessKeyboardInput(PINPUT_DEVICE_INFO pDeviceInfo, PKEYBOARD_INPUT_DATA pKbdInputData, WORD wScanCode, WORD wVk)
Definition: keyboard.c:1391
BOOL NTAPI UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
Definition: keyboard.c:1314
static WORD IntTranslateNumpadKey(WORD wVk)
Definition: keyboard.c:270

Referenced by RITReadApc().

◆ UserRawInputProcessKeyboardInput()

VOID WINAPI UserRawInputProcessKeyboardInput ( PINPUT_DEVICE_INFO  pDeviceInfo,
PKEYBOARD_INPUT_DATA  pKbdInputData,
WORD  wScanCode,
WORD  wVk 
)

Definition at line 1391 of file keyboard.c.

1395{
1396 PTHREADINFO pti;
1397 HWND hwndTarget;
1398 WPARAM wParam;
1399 HRAWINPUT hRawInput;
1400 RAWKEYBOARD kb = {0};
1401 MSG Msg = {0};
1402 BOOL bIsDown = (pKbdInputData->Flags & KEY_BREAK) ? FALSE : TRUE;
1403
1404 if (!UserGetRawInputTarget(RIM_TYPEKEYBOARD, &pti, &hwndTarget, &wParam))
1405 return;
1406
1407 kb.MakeCode = wScanCode & 0x7F;
1408
1409 if (bIsDown)
1410 kb.Flags = RI_KEY_MAKE;
1411 else
1412 kb.Flags = RI_KEY_BREAK;
1413 kb.VKey = wVk & 0xFF; // Note: wVk is simplified by msg queue
1414
1415 if (bIsDown)
1416 kb.Message = WM_KEYDOWN;
1417 else
1418 kb.Message = WM_KEYUP;
1419 if (pKbdInputData->Flags & KEY_E1)
1420 {
1421 kb.Flags |= RI_KEY_E1;
1422 }
1423 if (pKbdInputData->Flags & KEY_E0)
1424 {
1425 kb.Flags |= RI_KEY_E0;
1426 }
1427
1428 kb.ExtraInformation = pKbdInputData->ExtraInformation;
1429 hRawInput = UserCreateRawInput(pti,
1430 RIM_TYPEKEYBOARD,
1431 (HANDLE)pDeviceInfo,
1432 wParam,
1433 &kb,
1434 sizeof(kb));
1435 if (!hRawInput)
1436 return;
1437
1438 Msg.hwnd = hwndTarget;
1439 Msg.message = WM_INPUT;
1440 Msg.wParam = wParam;
1441 Msg.lParam = (LPARAM)hRawInput;
1442 Msg.time = EngGetTickCount32();
1443 Msg.pt = gpsi->ptCursor;
1444
1445 if (!MsqPostMessage(pti, &Msg, TRUE, QS_RAWINPUT, 0, 0))
1446 UserFreeRawInput(pti->MessageQueue, hRawInput);
1447}
#define WM_INPUT
Definition: winuser.h:1740
BOOL FASTCALL UserFreeRawInput(PUSER_MESSAGE_QUEUE MessageQueue, HRAWINPUT hRawInput)
Definition: rawinput.c:364
BOOL FASTCALL UserGetRawInputTarget(DWORD dwType, PTHREADINFO *ppti, HWND *phwndTarget, WPARAM *pwParam)
Definition: rawinput.c:413
HRAWINPUT FASTCALL UserCreateRawInput(PTHREADINFO pti, DWORD dwType, HANDLE hDevice, WPARAM wParam, CONST VOID *pData, UINT cbData)
Definition: rawinput.c:323

Referenced by UserProcessKeyboardInput().

◆ UserSendKeyboardInput()

BOOL NTAPI UserSendKeyboardInput ( KEYBDINPUT *  pKbdInput,
BOOL  bInjected 
)

Definition at line 1314 of file keyboard.c.

1315{
1316 WORD wScanCode, wVk;
1317 PKL pKl = NULL;
1318 PKBDTABLES pKbdTbl;
1319 PUSER_MESSAGE_QUEUE pFocusQueue;
1320 DWORD dwTime;
1321 BOOL bExt = (pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
1322
1324
1325 /* Find the target thread whose locale is in effect */
1326 pFocusQueue = IntGetFocusMessageQueue();
1327
1328 if (pFocusQueue && pFocusQueue->ptiKeyboard)
1329 {
1330 pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
1331 }
1332
1333 if (!pKl)
1335 if (!pKl)
1336 {
1337 ERR("No keyboard layout!\n");
1338 return FALSE;
1339 }
1340
1341 pKbdTbl = pKl->spkf->pKbdTbl;
1342
1343 /* Note: wScan field is always used */
1344 wScanCode = pKbdInput->wScan;
1345
1346 if (pKbdInput->dwFlags & KEYEVENTF_UNICODE)
1347 {
1348 /* Generate WM_KEYDOWN msg with wParam == VK_PACKET and
1349 high order word of lParam == pKbdInput->wScan */
1350 wVk = VK_PACKET;
1351 }
1352 else
1353 {
1354 wScanCode &= 0x7F;
1355 if (pKbdInput->dwFlags & KEYEVENTF_SCANCODE)
1356 {
1357 /* Don't ignore invalid scan codes */
1358 wVk = IntVscToVk(wScanCode | (bExt ? 0xE000 : 0), pKbdTbl);
1359 if (!wVk) /* use 0xFF if vsc is invalid */
1360 wVk = 0xFF;
1361 }
1362 else
1363 {
1364 wVk = pKbdInput->wVk;
1365 }
1366
1367 /* Remove all virtual key flags (KBDEXT, KBDMULTIVK, KBDSPECIAL, KBDNUMPAD) */
1368 wVk &= 0xFF;
1369 }
1370
1371 /* If time is given, use it */
1372 if (pKbdInput->time)
1373 dwTime = pKbdInput->time;
1374 else
1375 {
1377 }
1378
1379 if (wVk == VK_RMENU && (pKbdTbl->fLocaleFlags & KLLF_ALTGR))
1380 {
1381 /* For AltGr keyboards RALT generates CTRL events */
1382 ProcessKeyEvent(VK_LCONTROL, 0, pKbdInput->dwFlags & KEYEVENTF_KEYUP, bInjected, dwTime, 0);
1383 }
1384
1385 /* Finally process this key */
1386 return ProcessKeyEvent(wVk, wScanCode, pKbdInput->dwFlags, bInjected, dwTime, pKbdInput->dwExtraInfo);
1387}
PPROCESSINFO gppiInputProvider
Definition: ntuser.c:16
BOOL NTAPI ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
Definition: keyboard.c:1088

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

◆ gAltNumPadState

enum _ALTNUM_STATE gAltNumPadState = ALTNUM_INACTIVE
static

Referenced by IntHandleAltNumpad().

◆ gAltNumPadValue

ULONG gAltNumPadValue = 0
static

Definition at line 35 of file keyboard.c.

Referenced by IntHandleAltNumpad().

◆ gbEnableHexNumpad

BOOL gbEnableHexNumpad = FALSE

Definition at line 36 of file keyboard.c.

Referenced by IntHandleAltNumpad(), and SpiUpdatePerUserSystemParameters().

◆ 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

◆ gLanguageToggleKeyState

INT gLanguageToggleKeyState = 0
static

Definition at line 18 of file keyboard.c.

Referenced by ProcessKeyEvent().

◆ gLayoutToggleKeyState

INT gLayoutToggleKeyState = 0
static

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