📄 jsthid.cpp
字号:
pvkshiftCurr = &rgVKeyDownToShiftState[dwIdx];
if (pvkshiftCurr->vk == vk) {
if (hidpKeyEvent == HidP_Keyboard_Make) {
*pKeyStateFlags |= pvkshiftCurr->ksf;
}
else {
*pKeyStateFlags &= ~pvkshiftCurr->ksf;
}
break;
}
}
}
// Send an LControl keyboard event
static
void
GenerateLControl(
HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
KEY_STATE_FLAGS *pKeyStateFlags
)
{
DEBUGCHK(pKeyStateFlags);
const USAGE_TO_SCANCODE *pUsageToSc = FindUsageToSc(HID_USAGE_KEYBOARD_LCTRL);
DEBUGCHK(pUsageToSc);
UINT uiVk;
UINT uiSc;
DWORD dwFlags;
GenerateKeyInfo(pUsageToSc, &uiVk, &uiSc, &dwFlags, hidpKeyEvent);
if (uiVk == VK_LCONTROL) {
UpdateKeyState(pKeyStateFlags, (UINT8) uiVk, hidpKeyEvent);
KeyboardEvent(uiVk, uiSc, dwFlags);
}
else {
RETAILMSG(1, (_T("Keyboard: AltGr processing failed. Returned vkey 0x%02X\r\n"),
uiVk));
}
}
// Modifier key processing.
static
void
ProcessModifier(
UINT uiVk,
UINT uiSc,
DWORD dwFlags,
HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
KEY_STATE_FLAGS *pKeyStateFlags
)
{
// Handle AltGr
if ( (uiVk == VK_RMENU) && (g_dwLocaleFlags & KLLF_ALTGR) ) {
// Also send a Left Control
GenerateLControl(hidpKeyEvent, pKeyStateFlags);
}
UpdateKeyState(pKeyStateFlags, (UINT8) uiVk, hidpKeyEvent);
KeyboardEvent(uiVk, uiSc, dwFlags);
}
// NumPad key processing.
static
void
ProcessNumPad(
UINT uiVk,
UINT uiSc,
DWORD dwFlags,
HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
KEY_STATE_FLAGS *pKeyStateFlags
)
{
static const UINT8 rgVkNumLockOff[] = {
VK_INSERT, // VK_NUMPAD0 0x60
VK_END, // VK_NUMPAD1 0x61
VK_DOWN, // VK_NUMPAD2 0x62
VK_NEXT, // VK_NUMPAD3 0x63
VK_LEFT, // VK_NUMPAD4 0x64
VK_CLEAR, // VK_NUMPAD5 0x65
VK_RIGHT, // VK_NUMPAD6 0x66
VK_HOME, // VK_NUMPAD7 0x67
VK_UP, // VK_NUMPAD8 0x68
VK_PRIOR, // VK_NUMPAD9 0x69
VK_MULTIPLY, // VK_MULTIPLY 0x6A
VK_ADD, // VK_ADD 0x6B
VK_SEPARATOR, // VK_SEPARATOR 0x6C
VK_SUBTRACT, // VK_SUBTRACT 0x6D
VK_DELETE // VK_DECIMAL 0x6E
};
DWORD dwNormalizedIdx;
PREFAST_DEBUGCHK(pKeyStateFlags != NULL);
DEBUGCHK(uiVk >= VK_NUMPAD0);
DEBUGCHK(uiVk < VK_NUMPAD0 + dim(rgVkNumLockOff));
if (IS_NUMLOCK_ENABLED() == FALSE) {
dwNormalizedIdx = uiVk - VK_NUMPAD0;
DEBUGCHK(dwNormalizedIdx < dim(rgVkNumLockOff));
uiVk = rgVkNumLockOff[dwNormalizedIdx];
}
KeyboardEvent(uiVk, uiSc, dwFlags);
}
// Special key processing that does not fit into any other category.
static
void
ProcessSpecial(
UINT uiVk,
UINT uiSc,
DWORD dwFlags,
HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
KEY_STATE_FLAGS *pKeyStateFlags
)
{
UINT uiScOld = uiSc;
PREFAST_DEBUGCHK(pKeyStateFlags != NULL);
if (uiSc == SC_PRTSCRN) {
if (ANY_ALT_DOWN()) {
uiSc = 0x84;
}
}
else if (uiSc == SC_PAUSE) {
if (ANY_CTRL_DOWN()) {
uiSc = 0xE07E;
}
}
// If the scan code changed, update the virtual key and extended flag.
if (uiSc != uiScOld)
{
uiVk = MapVirtualKey(uiSc, MAP_SC_TO_VK);
if ((uiSc & SC_EXTENDED_MASK) == SC_EXTENDED_BITS) {
dwFlags |= KEYEVENTF_EXTENDEDKEY;
}
else {
dwFlags &= ~KEYEVENTF_EXTENDEDKEY;
}
}
KeyboardEvent(uiVk, uiSc, dwFlags);
}
// Remap the Japanese keydowns.
static
UINT8
RemapJpnKeyDown(
UINT8 vkOnly,
KEY_STATE_FLAGS *pKeyStateFlags
)
{
UINT8 vkDown = vkOnly;
if ( vkOnly == VK_DBE_SBCSCHAR ) {
if ( g_vkFullHalfSent ) {
vkDown = g_vkFullHalfSent;
}
else if ( ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() ) {
vkDown = g_vkFullHalfSent = VK_KANJI;
}
else {
// Don't use imm function if not configured.
// The remapping won't work correctly but at least there won't be link errors.
DWORD fdwConversion;
DWORD fdwSentence;
if ( ImmGetConversionStatus(NULL, &fdwConversion, &fdwSentence) ) {
if ( fdwConversion & IME_CMODE_FULLSHAPE ) {
vkDown = g_vkFullHalfSent = VK_DBE_SBCSCHAR;
}
else {
vkDown = g_vkFullHalfSent = VK_DBE_DBCSCHAR;
}
}
else {
vkDown = g_vkFullHalfSent = VK_DBE_SBCSCHAR;
}
}
}
else if ( vkOnly == VK_DBE_ALPHANUMERIC ) {
if ( g_vkAlphaNumSent ) {
vkDown = g_vkAlphaNumSent;
}
else if ( !ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() ) {
vkDown = g_vkAlphaNumSent = VK_DBE_ALPHANUMERIC;
}
else {
vkDown = g_vkAlphaNumSent = VK_CAPITAL;
}
}
else if ( vkOnly == VK_DBE_HIRAGANA ) {
if ( g_vkHiraKataSent ) {
vkDown = g_vkHiraKataSent;
}
else if ( !ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && ANY_SHIFT_DOWN() ) {
vkDown = g_vkHiraKataSent = VK_DBE_KATAKANA;
}
else if ( !ANY_ALT_DOWN() && ANY_CTRL_DOWN() && ANY_SHIFT_DOWN() ) {
vkDown = g_vkHiraKataSent = VK_KANA;
}
else if ( ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() ) {
DWORD fdwConversion;
DWORD fdwSentence;
if ( ImmGetConversionStatus(NULL, &fdwConversion, &fdwSentence) ) {
if ( fdwConversion & IME_CMODE_ROMAN ) {
vkDown = g_vkHiraKataSent = VK_DBE_NOROMAN;
}
else {
vkDown = g_vkHiraKataSent = VK_DBE_ROMAN;
}
}
else {
vkDown = g_vkHiraKataSent = VK_DBE_NOROMAN;
}
}
else {
g_vkHiraKataSent = vkOnly;
}
}
return vkDown;
}
// Remap the Japanese keyup.
static
UINT8
RemapJpnKeyUp(
UINT8 vkOnly,
KEY_STATE_FLAGS *pKeyStateFlags
)
{
UINT8 vkUp = vkOnly;
if ( vkOnly == VK_DBE_SBCSCHAR ) {
vkUp = g_vkFullHalfSent;
g_vkFullHalfSent = 0;
}
else if ( vkOnly == VK_DBE_ALPHANUMERIC ) {
vkUp = g_vkAlphaNumSent;
g_vkAlphaNumSent = 0;
}
else if ( vkOnly == VK_DBE_HIRAGANA ) {
vkUp = g_vkHiraKataSent;
g_vkHiraKataSent = 0;
}
return vkUp;
}
// Japanese key processing.
static
void
ProcessJpn(
UINT uiVk,
UINT uiSc,
DWORD dwFlags,
HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
KEY_STATE_FLAGS *pKeyStateFlags
)
{
DEBUGCHK(pKeyStateFlags != NULL);
if (hidpKeyEvent == HidP_Keyboard_Make) {
uiVk = RemapJpnKeyDown(uiVk, pKeyStateFlags);
}
else {
uiVk = RemapJpnKeyUp(uiVk, pKeyStateFlags);
}
KeyboardEvent(uiVk, uiSc, dwFlags);
}
// Do not send a key up for this key.
static
void
ProcessNoBreak(
UINT uiVk,
UINT uiSc,
DWORD dwFlags,
HIDP_KEYBOARD_DIRECTION hidpKeyEvent,
KEY_STATE_FLAGS *pKeyStateFlags
)
{
DEBUGCHK(pKeyStateFlags != NULL);
if (hidpKeyEvent == HidP_Keyboard_Make) {
KeyboardEvent(uiVk, uiSc, dwFlags);
}
}
#ifdef DEBUG
// Validate a PHID_KBD structure
void
ValidateHidKbd(
PHID_KBD pHidKbd
)
{
DWORD cbUsageList;
PREFAST_DEBUGCHK(pHidKbd != NULL);
DEBUGCHK(pHidKbd->dwSig == HID_KBD_SIG);
DEBUGCHK(pHidKbd->hDevice != NULL);
DEBUGCHK(pHidKbd->pHidFuncs != NULL);
DEBUGCHK(pHidKbd->phidpPreparsedData != NULL);
DEBUGCHK(pHidKbd->hidpCaps.UsagePage == HID_USAGE_PAGE_GENERIC);
DEBUGCHK(pHidKbd->hidpCaps.Usage == HID_USAGE_GENERIC_KEYBOARD);
DEBUGCHK(pHidKbd->pbOutputBuffer != NULL);
if (pHidKbd->fhThreadInited == TRUE) {
DEBUGCHK(pHidKbd->hThread != NULL);
}
DEBUGCHK(pHidKbd->ARState <= AR_AUTOREPEATING);
if (pHidKbd->fhOSDeviceInited == TRUE) {
DEBUGCHK(pHidKbd->hOSDevice != NULL);
}
DEBUGCHK(pHidKbd->hevClosing != NULL);
cbUsageList = pHidKbd->dwMaxUsages * sizeof(USAGE_AND_PAGE);
DEBUGCHK(pHidKbd->puapPrevUsages != NULL);
DEBUGCHK(LocalSize(pHidKbd->puapPrevUsages) >= cbUsageList * 5);
DEBUGCHK((DWORD) pHidKbd->puapCurrUsages == ((DWORD) pHidKbd->puapPrevUsages) + cbUsageList);
DEBUGCHK((DWORD) pHidKbd->puapBreakUsages == ((DWORD) pHidKbd->puapCurrUsages) + cbUsageList);
DEBUGCHK((DWORD) pHidKbd->puapMakeUsages == ((DWORD) pHidKbd->puapBreakUsages) + cbUsageList);
DEBUGCHK((DWORD) pHidKbd->puapOldMakeUsages == ((DWORD) pHidKbd->puapMakeUsages) + cbUsageList);
}
// Validate the given USAGE_TO_SC_INFO structure.
static
void
ValidateUsageToSc(
const USAGE_TO_SC_INFO *pUsageToScInfo
)
{
DEBUGCHK(pUsageToScInfo->pUsageToSc != NULL);
DEBUGCHK(pUsageToScInfo->uFirstUsage <= pUsageToScInfo->uLastUsage);
}
// Validate the list of USAGE_TO_SC_INFO structures.
static
void
ValidateAllUsageToSc(
)
{
const USAGE_TO_SC_INFO *pUsageToScInfo;
DWORD cUsageToScInfo = dim(g_rgUsageToScInfo);
DWORD dwOuter, dwInner;
// Check the definitions of EB and EP
DEBUGCHK(SET_EB(EB_COUNT) <= SET_PT(1));
for (dwOuter = 0; dwOuter < cUsageToScInfo; ++dwOuter)
{
pUsageToScInfo = &g_rgUsageToScInfo[dwOuter];
ValidateUsageToSc(pUsageToScInfo);
// Verify that this range does not overlap with any of the later ones
USHORT uFirstUsage = pUsageToScInfo->uFirstUsage;
USHORT uLastUsage = pUsageToScInfo->uLastUsage;
for (dwInner = dwOuter + 1; dwInner < cUsageToScInfo; ++dwInner) {
DEBUGCHK( (uFirstUsage < g_rgUsageToScInfo[dwInner].uFirstUsage) ||
(uLastUsage > g_rgUsageToScInfo[dwInner].uLastUsage) );
}
// Now make sure that each USAGE_TO_SCANCODE is valid
for (dwInner = 0; dwInner < (USHORT)(uLastUsage - uFirstUsage + 1); ++dwInner)
{
const USAGE_TO_SCANCODE *pUsageToSc = pUsageToScInfo->pUsageToSc;
DEBUGCHK(GET_EB(pUsageToSc->uiFlags) < EB_COUNT);
DEBUGCHK(GET_PT(pUsageToSc->uiFlags) < PT_COUNT);
}
}
}
#endif // DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -