📄 jsthid.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
//由CE下的键盘驱动修改: coke
#include "jsthid.h"
#include "InputLang.h"
#ifdef DEBUG
// Debug Zones
#define DBG_ERROR 0x0001
#define DBG_WARNING 0x0002
#define DBG_INIT 0x0004
#define DBG_FUNCTION 0x0008
#define DBG_USAGES 0x0010
DBGPARAM dpCurSettings = {
TEXT("KbdHid"), {
TEXT("Errors"), TEXT("Warnings"), TEXT("Init"), TEXT("Function"),
TEXT("Usages"), TEXT(""), TEXT(""), TEXT(""),
TEXT(""), TEXT(""), TEXT(""), TEXT(""),
TEXT(""), TEXT(""), TEXT(""), TEXT("") },
DBG_ERROR | DBG_WARNING };
#endif // DEBUG
// MapVirtualKey(x, 3) converts scan codes to virtual keys
#define MAP_SC_TO_VK 3
#define SC_EXTENDED_MASK 0xFFFFFF00
#define SC_EXTENDED_BITS 0xE000
#define SC_E1_BITS 0xE11400
#define SC_PRTSCRN 0xE07C
#define SC_PAUSE 0xE11477
// Zero usage and page for convenience
static const USAGE_AND_PAGE g_uapZero = { 0, 0 };
// Variables used by the Japanese key remapper. Global, so simultaneous
// use of two Japanese HID keyboards might cause certain Japanese remappings
// to produce the incorrect virtual key.
static UINT8 g_vkAlphaNumSent;
static UINT8 g_vkFullHalfSent;
static UINT8 g_vkHiraKataSent;
// AutoRepeat variables. Global since all HID keyboards share the same
// timings. Not protected since the Layout Manager serializes change
// requests (IOCTLs).
DWORD g_dwAutoRepeatInitialDelay = KBD_AUTO_REPEAT_INITIAL_DELAY_DEFAULT;
DWORD g_dwAutoRepeatKeysPerSec = KBD_AUTO_REPEAT_KEYS_PER_SEC_DEFAULT;
// Locale flags specify locale-specific features such as AltGr.
DWORD g_dwLocaleFlags = 0;
// Defines for checking the state of modifier keys
#define ANY_ALT_DOWN() (*pKeyStateFlags & (KeyShiftLeftAltFlag | KeyShiftRightAltFlag))
#define ANY_CTRL_DOWN() (*pKeyStateFlags & (KeyShiftLeftCtrlFlag | KeyShiftRightCtrlFlag))
#define ANY_SHIFT_DOWN() (*pKeyStateFlags & (KeyShiftLeftShiftFlag | KeyShiftRightShiftFlag))
#define IS_NUMLOCK_ENABLED() ((*pKeyStateFlags & KeyShiftNumLockFlag) != 0)
// Two bits represent extended bytes to prepend to the scan codes.
enum ExtendedBytes {
EB_NONE = 0,
EB_E0,
EB_E114,
EB_COUNT,
};
// Six bits represent the type of processing that needs to be performed.
enum ProcessingType {
PT_STANDARD = 0,
PT_MODIFIER,
PT_NUMPAD,
PT_SPECIAL,
PT_JPN,
PT_NO_BREAK,
PT_COUNT,
};
// Describes a Scan Code that is associated with a Usage
struct USAGE_TO_SCANCODE {
UINT8 uiFlags; // Top six bits = ProcessingType. Bottom two = ExtendedBytes
UINT8 uiSc;
};
// Describes an association from a Usage to an AT Scan Code
struct USAGE_TO_SC_ASSOCIATION {
USAGE usage;
UINT16 uiSc;
};
// Helper macros to get the right bits out of and into the uiFlags field.
#define SET_EB(x) ((x) & 0x3)
#define GET_EB(flags) ( (ExtendedBytes) ((flags) & 0x3) )
#define SET_PT(x) ((x) << 2)
#define GET_PT(flags) ( (ProcessingType) ((UINT8) ((flags) >> 2)) )
#define MAKE_FLAGS(eb, pt) (SET_EB(eb) | SET_PT(pt))
// The general Usage to AT Scan Code mapping.
#define FIRST_USAGE HID_USAGE_KEYBOARD_NOEVENT // 0x00
#define LAST_USAGE (FIRST_USAGE + dim(g_rgUsageToSc) - 1)
static const USAGE_TO_SCANCODE g_rgUsageToSc[] = {
{ 0, 0x00 }, // 00 - No Event
{ 0, 0x00 }, // 01 - Overrun
{ 0, 0x00 }, // 02 - POST Fail
{ 0, 0x00 }, // 03 - ErrorUndefined
{ 0, 0x1C }, // 04 - a A
{ 0, 0x32 }, // 05 - b B
{ 0, 0x21 }, // 06 - c C
{ 0, 0x23 }, // 07 - d D
{ 0, 0x24 }, // 08 - e E
{ 0, 0x2B }, // 09 - f F
{ 0, 0x34 }, // 0a - g G
{ 0, 0x33 }, // 0b - h H
{ 0, 0x43 }, // 0c - i I
{ 0, 0x3B }, // 0d - j J
{ 0, 0x42 }, // 0e - k K
{ 0, 0x4B }, // 0f - l L
{ 0, 0x3A }, // 10 - m M
{ 0, 0x31 }, // 11 - n N
{ 0, 0x44 }, // 12 - o O
{ 0, 0x4D }, // 13 - p P
{ 0, 0x15 }, // 14 - q Q
{ 0, 0x2D }, // 15 - r R
{ 0, 0x1B }, // 16 - s S
{ 0, 0x2C }, // 17 - t T
{ 0, 0x3C }, // 18 - u U
{ 0, 0x2A }, // 19 - v V
{ 0, 0x1D }, // 1a - w W
{ 0, 0x22 }, // 1b - x X
{ 0, 0x35 }, // 1c - y Y
{ 0, 0x1A }, // 1d - z Z
{ 0, 0x16 }, // 1e - 1 !
{ 0, 0x1E }, // 1f - 2 @
{ 0, 0x26 }, // 20 - 3 #
{ 0, 0x25 }, // 21 - 4 $
{ 0, 0x2E }, // 22 - 5 %
{ 0, 0x36 }, // 23 - 6 ^
{ 0, 0x3D }, // 24 - 7 &
{ 0, 0x3E }, // 25 - 8 *
{ 0, 0x46 }, // 26 - 9 (
{ 0, 0x45 }, // 27 - 0 )
{ 0, 0x5A }, // 28 - Return
{ 0, 0x76 }, // 29 - Escape
{ 0, 0x66 }, // 2a - Backspace
{ 0, 0x0D }, // 2b - Tab
{ 0, 0x29 }, // 2c - Space
{ 0, 0x4E }, // 2d - - _
{ 0, 0x55 }, // 2e - = +
{ 0, 0x54 }, // 2f - [ {
{ 0, 0x5B }, // 30 - ] }
{ 0, 0x5D }, // 31 - \ |
{ 0, 0x5D }, // 32 - Europe 1 (Note 2)
{ 0, 0x4C }, // 33 - ; :
{ 0, 0x52 }, // 34 - "' """
{ MAKE_FLAGS(0, PT_JPN), 0x0E }, // 35 - ` ~
{ 0, 0x41 }, // 36 - ", <"
{ 0, 0x49 }, // 37 - . >
{ 0, 0x4A }, // 38 - / ?
{ MAKE_FLAGS(0, PT_JPN), 0x58 }, // 39 - Caps Lock
{ 0, 0x05 }, // 3a - F1
{ 0, 0x06 }, // 3b - F2
{ 0, 0x04 }, // 3c - F3
{ 0, 0x0C }, // 3d - F4
{ 0, 0x03 }, // 3e - F5
{ 0, 0x0B }, // 3f - F6
{ 0, 0x83 }, // 40 - F7
{ 0, 0x0A }, // 41 - F8
{ 0, 0x01 }, // 42 - F9
{ 0, 0x09 }, // 43 - F10
{ 0, 0x78 }, // 44 - F11
{ 0, 0x07 }, // 45 - F12
{ MAKE_FLAGS(EB_E0, PT_SPECIAL), 0x7C }, // 46 - Print Screen (Note 1)
{ 0, 0x7E }, // 47 - Scroll Lock
{ MAKE_FLAGS(EB_E114, PT_SPECIAL), 0x77 }, // 48 - Pause
{ MAKE_FLAGS(EB_E0, 0), 0x70 }, // 49 - Insert (Note 1)
{ MAKE_FLAGS(EB_E0, 0), 0x6C }, // 4a - Home (Note 1)
{ MAKE_FLAGS(EB_E0, 0), 0x7D }, // 4b - Page Up (Note 1)
{ MAKE_FLAGS(EB_E0, 0), 0x71 }, // 4c - Delete (Note 1)
{ MAKE_FLAGS(EB_E0, 0), 0x69 }, // 4d - End (Note 1)
{ MAKE_FLAGS(EB_E0, 0), 0x7A }, // 4e - Page Down (Note 1)
{ MAKE_FLAGS(EB_E0, 0), 0x74 }, // 4f - Right Arrow (Note 1)
{ MAKE_FLAGS(EB_E0, 0), 0x6B }, // 50 - Left Arrow (Note 1)
{ MAKE_FLAGS(EB_E0, 0), 0x72 }, // 51 - Down Arrow (Note 1)
{ MAKE_FLAGS(EB_E0, 0), 0x75 }, // 52 - Up Arrow (Note 1)
{ 0, 0x77 }, // 53 - Num Lock
{ MAKE_FLAGS(EB_E0, 0), 0x4A }, // 54 - Keypad / (Note 1)
{ 0, 0x7C }, // 55 - Keypad *
{ 0, 0x7B }, // 56 - Keypad -
{ 0, 0x79 }, // 57 - Keypad +
{ MAKE_FLAGS(EB_E0, 0), 0x5A }, // 58 - Keypad Enter
{ MAKE_FLAGS(0, PT_NUMPAD), 0x69 }, // 59 - Keypad 1 End
{ MAKE_FLAGS(0, PT_NUMPAD), 0x72 }, // 5a - Keypad 2 Down
{ MAKE_FLAGS(0, PT_NUMPAD), 0x7A }, // 5b - Keypad 3 PageDn
{ MAKE_FLAGS(0, PT_NUMPAD), 0x6B }, // 5c - Keypad 4 Left
{ MAKE_FLAGS(0, PT_NUMPAD), 0x73 }, // 5d - Keypad 5
{ MAKE_FLAGS(0, PT_NUMPAD), 0x74 }, // 5e - Keypad 6 Right
{ MAKE_FLAGS(0, PT_NUMPAD), 0x6C }, // 5f - Keypad 7 Home
{ MAKE_FLAGS(0, PT_NUMPAD), 0x75 }, // 60 - Keypad 8 Up
{ MAKE_FLAGS(0, PT_NUMPAD), 0x7D }, // 61 - Keypad 9 PageUp
{ MAKE_FLAGS(0, PT_NUMPAD), 0x70 }, // 62 - Keypad 0 Insert
{ MAKE_FLAGS(0, PT_NUMPAD), 0x71 }, // 63 - Keypad . Delete
{ 0, 0x61 }, // 64 - Europe 2 (Note 2)
{ MAKE_FLAGS(EB_E0, 0), 0x2F }, // 65 - App
{ 0, 0x00 }, // 66 - Keyboard Power
{ 0, 0x0F }, // 67 - Keypad =
{ 0, 0x2F }, // 68 - F13
{ 0, 0x37 }, // 69 - F14
{ 0, 0x3F }, // 6a - F15
};
// Mapping from international Usages to AT Scan Codes
#define FIRST_GLOBAL_USAGE 0x85
#define LAST_GLOBAL_USAGE (FIRST_GLOBAL_USAGE + dim(g_rgGlobalUsageToSc) - 1)
static const USAGE_TO_SCANCODE g_rgGlobalUsageToSc[] =
{
{ 0, 0x51 }, // 85 - Keybad , (Brazillian)
{ 0, 0x00 }, // 86 - Keypad =
{ MAKE_FLAGS(0, PT_JPN), 0x51 }, // 87 - Ro
{ MAKE_FLAGS(0, PT_JPN), 0x13 }, // 88 - Katakana/Hiragana
{ MAKE_FLAGS(0, PT_JPN), 0x6A }, // 89 - Yen
{ MAKE_FLAGS(0, PT_JPN), 0x64 }, // 8a - Henkan
{ MAKE_FLAGS(0, PT_JPN), 0x67 }, // 8b - Muhenkan
{ 0, 0x00 }, // 8c - Int'l 6
{ 0, 0x00 }, // 8d - Int'l 7
{ 0, 0x00 }, // 8e - Int'l 8
{ 0, 0x00 }, // 8f - Int'l 9
{ MAKE_FLAGS(0, PT_NO_BREAK), 0xF2 }, // 90 - Hanguel/English
{ MAKE_FLAGS(0, PT_NO_BREAK), 0xF1 }, // 91 - Hanja
{ 0, 0x63 }, // 92 - LANG Katakana
{ 0, 0x62 }, // 93 - LANG Hiragana
{ 0, 0x5F }, // 94 - LANG Zenkaku/Hankaku
};
// Mapping from modifier Usages to AT Scan Codes
#define FIRST_MODIFIER_USAGE HID_USAGE_KEYBOARD_LCTRL // 0xE0
#define LAST_MODIFIER_USAGE (FIRST_MODIFIER_USAGE + dim(g_rgModifierUsageToSc) - 1)
static const USAGE_TO_SCANCODE g_rgModifierUsageToSc[] = {
{ MAKE_FLAGS(0, PT_MODIFIER), 0x14 }, // E0 - Left Control
{ MAKE_FLAGS(0, PT_MODIFIER), 0x12 }, // E1 - Left Shift
{ MAKE_FLAGS(0, PT_MODIFIER), 0x11 }, // E2 - Left Alt
{ MAKE_FLAGS(EB_E0, PT_MODIFIER), 0x1F }, // E3 - Left GUI
{ MAKE_FLAGS(EB_E0, PT_MODIFIER), 0x14 }, // E4 - Right Control
{ MAKE_FLAGS(0, PT_MODIFIER), 0x59 }, // E5 - Right Shift
{ MAKE_FLAGS(EB_E0, PT_MODIFIER), 0x11 }, // E6 - Right Alt
{ MAKE_FLAGS(EB_E0, PT_MODIFIER), 0x27 }, // E7 - Right GUI
};
// Describes a table listing a direct mapping from Usages to Scan Codes
struct USAGE_TO_SC_INFO {
const USAGE_TO_SCANCODE *pUsageToSc;
USHORT uFirstUsage;
USHORT uLastUsage;
};
// Our list of direct Usage to Virtual Key mapping tables
static const USAGE_TO_SC_INFO g_rgUsageToScInfo[] = {
{ g_rgModifierUsageToSc, FIRST_MODIFIER_USAGE, LAST_MODIFIER_USAGE },
{ g_rgUsageToSc, FIRST_USAGE, LAST_USAGE },
{ g_rgGlobalUsageToSc, FIRST_GLOBAL_USAGE, LAST_GLOBAL_USAGE },
};
// Consumer page (0xC) usage to virtual key.
// Note that most Consumer usages will be sent in
// Consumer Control (0xC 0x1) top level collections
// and will be handled in the consumer control client.
static const USAGE_TO_SC_ASSOCIATION g_rgConsumerToScAssn[] = {
{ 0x018A, 0xE048 }, // 018A - Mail
{ 0x0221, 0xE010 }, // 0221 - WWW Search
{ 0x0223, 0xE03A }, // 0223 - WWW Home
{ 0x0224, 0xE038 }, // 0224 - WWW Back
{ 0x0225, 0xE030 }, // 0225 - WWW Forward
{ 0x0226, 0xE028 }, // 0226 - WWW Stop
{ 0x0227, 0xE020 }, // 0227 - WWW Refresh
{ 0x022A, 0xE018 }, // 022A - WWW Favorites
};
// Declare all the processing functions.
typedef void (*PFN_PROCESSING_TYPE) (
UINT uiVk,
UINT uiSc,
DWORD dwFlags,
HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
KEY_STATE_FLAGS *pKeyStateFlags
);
#define DECLARE_PROCESSING_TYPE_FN(fn) void Process ## fn ## ( \
UINT uiVk, UINT uiSc, DWORD dwFlags, HIDP_KEYBOARD_DIRECTION hidpKeyEvent, \
KEY_STATE_FLAGS *pKeyStateFlags)
DECLARE_PROCESSING_TYPE_FN(Standard);
DECLARE_PROCESSING_TYPE_FN(Modifier);
DECLARE_PROCESSING_TYPE_FN(NumPad);
DECLARE_PROCESSING_TYPE_FN(Special);
DECLARE_PROCESSING_TYPE_FN(Jpn);
DECLARE_PROCESSING_TYPE_FN(NoBreak);
// Array of processing functions. Indexed by a ProcessingType.
static const PFN_PROCESSING_TYPE g_rgpfnProcessingType[] = {
&ProcessStandard,
&ProcessModifier,
&ProcessNumPad,
&ProcessSpecial,
&ProcessJpn,
&ProcessNoBreak,
};
#ifdef DEBUG
void
ValidateUsageToSc(
const USAGE_TO_SC_INFO *pUsageToScInfo
);
void
ValidateAllUsageToSc(
);
#else
#define ValidateUsageToSc(ptr)
#define ValidateAllUsageToSc()
#endif // DEBUG
DWORD
SendKeyboardUsages(
PUSAGE_AND_PAGE puapUsages,
DWORD dwMaxUsages,
HIDP_KEYBOARD_DIRECTION keyEvent,
KEY_STATE_FLAGS *pKeyStateFlags
);
void
KeyboardEvent(
UINT vk,
UINT sc,
DWORD dwFlags
);
const USAGE_TO_SCANCODE *
FindUsageToSc(
USAGE usage
);
void
ProcessKeyboardReport(
PHID_KBD pHidKbd,
PCHAR pbHidPacket,
DWORD cbHidPacket
);
BOOL
AllocateUsageLists(
PHID_KBD pHidKbd,
size_t cbUsages
);
VOID
FreeHidKbd(
PHID_KBD pHidKbd
);
BOOL
FlashLEDs(
PHID_KBD pHidKbd
);
// Dll entry function.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -