📄 kbdjpn.cpp
字号:
The basic pattern for each special key is to see if we are already sending
a virtual key and auto-repeat it or check if its particular modifier is
down and send the modified key or just send the unmodified key.
For modified keys, we need to make it look like the modifier key went up
and then the desired virtual key went down. Additionally, when the
modifier is the Alt key, we need to send a null character before the Alt
up so that menus do not activate.
--*/
static
UINT
ATJpn2RemapVKeyDown(
UINT32 VirtualKey,
UINT32 ScanCode,
KEY_STATE_FLAGS KeyStateFlags,
UINT32 *RemapVKeyBuf,
UINT32 *RemapScanCodeBuf,
KEY_STATE_FLAGS *RemapKeyStateFlagsBuf
)
{
UINT32 vkDown;
UINT32 scDown;
UINT32 vkOnly = VirtualKey & 0xff; // Just the vkey
UINT32 vkOther = VirtualKey & ~0xff; // Just the other stuff
// Normally, we just send the vkey that came in.
vkDown = vkOnly;
scDown = ScanCode;
// If the incoming key is a shift modifier of some sort, turn off keyclick autorepeat by default.
// We will allow the shift key to click on the first press, since many keyboards don't have built-in
// sound generators and users appreciate audible feedback when they press a key.
if(IsShiftModifier(vkOnly) || vkOnly == VK_CAPITAL || vkOnly == VK_NUMLOCK) {
vkDown |= KEYBD_DEVICE_SILENT_REPEAT;
}
if ( vkOnly == VK_RCONTROL )
{
v_bRCtrlDown = TRUE;
}
else if ( vkOnly == VK_LCONTROL )
{
v_bLCtrlDown = TRUE;
}
else if ( vkOnly == VK_RMENU )
{
v_bRAltDown = TRUE;
}
else if ( vkOnly == VK_LMENU )
{
v_bLAltDown = TRUE;
}
else if ( vkOnly == VK_LSHIFT )
{
v_bLShiftDown = TRUE;
}
else if ( vkOnly == VK_RSHIFT )
{
v_bRShiftDown = TRUE;
}
else if ( vkOnly == VK_DBE_SBCSCHAR )
{
if ( v_vkFullHalfSent )
{
vkDown = v_vkFullHalfSent;
scDown = v_scFullHalfSent;
}
else if ( ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() )
{
vkDown = v_vkFullHalfSent = VK_KANJI;
v_scFullHalfSent = ScanCode;
}
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 = v_vkFullHalfSent = VK_DBE_SBCSCHAR;
v_scFullHalfSent = ScanCode;
}
else
{
vkDown = v_vkFullHalfSent = VK_DBE_DBCSCHAR;
v_scFullHalfSent = ScanCode;
}
}
else
{
vkDown = v_vkFullHalfSent = VK_DBE_SBCSCHAR;
v_scFullHalfSent = ScanCode;
}
}
}
else if ( vkOnly == VK_DBE_ALPHANUMERIC )
{
if ( v_vkAlphaNumSent )
{
vkDown = v_vkAlphaNumSent;
scDown = v_scAlphaNumSent;
}
else if ( !ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && !ANY_SHIFT_DOWN() )
{
vkDown = v_vkAlphaNumSent = VK_DBE_ALPHANUMERIC;
v_scAlphaNumSent = ScanCode;
}
else
{
vkDown = v_vkAlphaNumSent = VK_CAPITAL;
v_scAlphaNumSent = ScanCode;
}
}
else if ( vkOnly == VK_DBE_HIRAGANA )
{
if ( v_vkHiraKataSent )
{
vkDown = v_vkHiraKataSent;
scDown = v_scHiraKataSent;
}
else if ( !ANY_ALT_DOWN() && !ANY_CTRL_DOWN() && ANY_SHIFT_DOWN() )
{
vkDown = v_vkHiraKataSent = VK_DBE_KATAKANA;
v_scHiraKataSent = ScanCode;
}
else if ( !ANY_ALT_DOWN() && ANY_CTRL_DOWN() && ANY_SHIFT_DOWN() )
{
vkDown = v_vkHiraKataSent = VK_KANA;
v_scHiraKataSent = ScanCode;
}
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 = v_vkHiraKataSent = VK_DBE_NOROMAN;
v_scHiraKataSent = ScanCode;
}
else
{
vkDown = v_vkHiraKataSent = VK_DBE_ROMAN;
v_scHiraKataSent = ScanCode;
}
}
else
{
vkDown = v_vkHiraKataSent = VK_DBE_NOROMAN;
v_scHiraKataSent = ScanCode;
}
}
}
// Finally! Send the key down.
*RemapVKeyBuf = vkDown | vkOther;
*RemapScanCodeBuf = scDown;
*RemapKeyStateFlagsBuf = KeyStateDownFlag;
return 1;
}
/*++
KeybdDriverRemapKeyUp:
On a key up, undo all of the virtual key re-mapping on the keyboard.
Notes:
When a special key is released, we send an up event for whatever virtual
key was original sent as going down.
If the special key's modifier key is still down, we send a down event for
it to keep the state consistent. (We earlier sent an up event for the modifier
when the special key went down.).
We remember if the modifier key we are resending the down for is the Alt
key. If it is, when it is really released, we send a null through the
system to keep menus from activating. Otherwise, menus would see this
down followed directly by an Alt up and so would activate.
--*/
static
UINT
ATJpn2RemapVKeyUp(
UINT32 VirtualKey,
UINT32 ScanCode,
KEY_STATE_FLAGS KeyStateFlags,
UINT32 *RemapVKeyBuf,
UINT32 *RemapScanCodeBuf,
KEY_STATE_FLAGS *RemapKeyStateFlagsBuf
)
{
UINT32 vkUp;
UINT32 scUp;
UINT32 vkOnly = VirtualKey & 0xff; // Just the vkey
UINT32 vkOther = VirtualKey & ~0xff; // Just the other stuff
// The key up we send is usually this.
vkUp = vkOnly;
scUp = ScanCode;
if ( vkOnly == VK_RCONTROL )
{
v_bRCtrlDown = FALSE;
}
else if ( vkOnly == VK_LCONTROL )
{
v_bLCtrlDown = FALSE;
}
else if ( vkOnly == VK_RMENU )
{
v_bRAltDown = FALSE;
}
else if ( vkOnly == VK_LMENU )
{
v_bLAltDown = FALSE;
}
else if ( vkOnly == VK_LSHIFT )
{
v_bLShiftDown = FALSE;
}
else if ( vkOnly == VK_RSHIFT )
{
v_bRShiftDown = FALSE;
}
else if ( vkOnly == VK_DBE_SBCSCHAR )
{
vkUp = v_vkFullHalfSent;
scUp = v_scFullHalfSent;
v_vkFullHalfSent = 0;
}
else if ( vkOnly == VK_DBE_ALPHANUMERIC )
{
vkUp = v_vkAlphaNumSent;
scUp = v_scAlphaNumSent;
v_vkAlphaNumSent = 0;
}
else if ( vkOnly == VK_DBE_HIRAGANA )
{
vkUp = v_vkHiraKataSent;
scUp = v_scHiraKataSent;
v_vkHiraKataSent = 0;
}
// Send the virtual key up.
*RemapVKeyBuf = vkUp | vkOther;
*RemapScanCodeBuf = scUp;
*RemapKeyStateFlagsBuf = 0;
return 1;
}
static
UINT
WINAPI
ATJpn2RemapVKey(
const KEYBD_EVENT *pKbdEvents,
UINT cKbdEvents,
KEYBD_EVENT *pRmpKbdEvents,
UINT cMaxRmpKbdEvents
)
{
static const DWORD cMapping = 1; // 1 to 1 mapping
PFN_KEYBD_REMAP pfnNumPadRemap = NULL;
UINT (*pfnRemap)(UINT32, UINT32, KEY_STATE_FLAGS,
UINT32*, UINT32*, KEY_STATE_FLAGS*) = NULL;
UINT cRmpKbdEvents;
if (pRmpKbdEvents == NULL) {
// 1 to 1 mapping for whatever NumPadRemapVKey returns
ASSERT(cMaxRmpKbdEvents == 0);
return cMapping * NumPadRemapVKey(pKbdEvents, cKbdEvents, NULL, 0);
}
ASSERT(pKbdEvents != NULL);
// We know that we will only map one input to one output. Thus, we only
// need for NumPadRemapVKey() to check the number of input events since
// we will not use more than it does. If the buffer is not large enough
// cRmpKbdEvents will be 0 and we will return 0.
cRmpKbdEvents = NumPadRemapVKey(pKbdEvents, cKbdEvents,
pRmpKbdEvents, cMaxRmpKbdEvents);
for (UINT ui = 0; ui < cRmpKbdEvents; ++ui)
{
if ((pRmpKbdEvents[ui].KeyStateFlags & KeyStateDownFlag) != 0) {
pfnRemap = ATJpn2RemapVKeyDown;
}
else {
pfnRemap = ATJpn2RemapVKeyUp;
}
PREFAST_ASSERT(pfnRemap != NULL);
UINT cKeys = (*pfnRemap)(pRmpKbdEvents[ui].uiVk, pRmpKbdEvents[ui].uiSc,
pRmpKbdEvents[ui].KeyStateFlags, &pRmpKbdEvents[ui].uiVk,
&pRmpKbdEvents[ui].uiSc, &pRmpKbdEvents[ui].KeyStateFlags);
ASSERT(cKeys == cMapping);
}
return cRmpKbdEvents;
}
#ifdef DEBUG
// Verify function declaration against the typedef.
static PFN_KEYBD_REMAP v_pfnRemapVKey = ATJpn2RemapVKey;
#endif
static DEVICE_LAYOUT dlATJpn2 =
{
sizeof(DEVICE_LAYOUT),
PS2_AT_PDD | PS2_NOP_PDD,
rgscvkATJpn2Tables,
dim(rgscvkATJpn2Tables),
ATJpn2RemapVKey,
};
extern "C"
BOOL
PS2_AT_00000411(
PDEVICE_LAYOUT pDeviceLayout
)
{
PREFAST_ASSERT(pDeviceLayout != NULL);
BOOL fRet = FALSE;
if (pDeviceLayout->dwSize != sizeof(DEVICE_LAYOUT)) {
RETAILMSG(1, (_T("PS2_AT_00000411: data structure size mismatch\r\n")));
goto leave;
}
// Make sure that the Sc->Vk tables are the sizes that we expect
ASSERT(dim(ScanCodeToVKeyTable ) == (1 + ScanCodeTableLast - ScanCodeTableFirst ));
ASSERT(dim(E0ScanCodeToVKeyTable) == (1 + E0ScanCodeTableLast - E0ScanCodeTableFirst));
ASSERT(dim(E1ScanCodeToVKeyTable) == (1 + E1ScanCodeTableLast - E1ScanCodeTableFirst));
*pDeviceLayout = dlATJpn2;
fRet = TRUE;
leave:
return fRet;
}
#ifdef DEBUG
// Verify function declaration against the typedef.
static PFN_DEVICE_LAYOUT_ENTRY v_pfnDLEntry = PS2_AT_00000411;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -