Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

385 lines
14 KiB

/****************************** Module Header ******************************\,
* Module Name: kbd.c
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* OEM-specific tables and routines for IBM Extended 101/102 style keyboards
*
* History:
* 30-04-91 IanJa Created.
\***************************************************************************/
#include "precomp.h"
#pragma hdrstop
/***************************************************************************\
* aVkToVsc[] - table associating Virtual Key codes with Virtual Scancodes
*
* Ordered, 0-terminated.
*
* This is used for those Virtual Keys that do not appear in ausVK_???[]
* These are not the base Virtual Keys. They require some modifier key
* depression (CTRL, ALT, SHIFT) or NumLock On to be generated.
*
* All the scancodes listed below should be marked KBDMULTIVK or KBDNUMPAD in
* ausVK_???[].
*
* This table is used by MapVirtualKey(wVk, 0).
\***************************************************************************/
BYTE aVkNumpad[] = {
VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, 0xFF, // 0x47 0x48 0x49 (0x4A)
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, 0xFF, // 0x4B 0x4C 0x4D (0x4E)
VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, // 0x4F 0x50 0x51
VK_NUMPAD0, VK_DECIMAL, 0 // 0x50 0x51
};
/***************************************************************************\
* How some Virtual Key values change when a SHIFT key is held down.
\***************************************************************************/
ULONG aulShiftCvt_VK[] = {
MAKELONG(VK_MULTIPLY, VK_SNAPSHOT),
MAKELONG(0,0)
};
// JPN IMB02
ULONG aulShiftControlCvt_VK_IBM02[] = {
MAKELONG(VK_SCROLL, VK_CANCEL | KBDEXT),
MAKELONG(VK_NUMLOCK, VK_PAUSE | KBDEXT),
MAKELONG(0,0)
};
/***************************************************************************\
* How some Virtual Key values change when a CONTROL key is held down.
\***************************************************************************/
ULONG aulControlCvt_VK[] = {
MAKELONG(VK_NUMLOCK, VK_PAUSE | KBDEXT),
MAKELONG(VK_SCROLL, VK_CANCEL),
MAKELONG(0,0)
};
// JPN IBM02
ULONG aulControlCvt_VK_IBM02[] = {
MAKELONG(VK_PAUSE, VK_CANCEL | KBDEXT),
MAKELONG(VK_SCROLL, VK_CANCEL | KBDEXT),
MAKELONG(0,0)
};
/***************************************************************************\
* How some Virtual Key values change when an ALT key is held down.
* The SHIFT and ALT keys both alter VK values the same way!!
\***************************************************************************/
#define aulAltCvt_VK aulShiftCvt_VK
/***************************************************************************\
* This table list keys that may affect Virtual Key values when held down.
*
* See kbd.h for a full description.
*
* 101/102key keyboard (type 4):
* Virtual Key values vary only if CTRL is held down.
* 84-86 key keyboards (type 3):
* Virtual Key values vary if one of SHIFT, CTRL or ALT is held down.
\***************************************************************************/
VK_TO_BIT aVkToBits_VK[] = {
{ VK_SHIFT, KBDSHIFT }, // 0x01
{ VK_CONTROL, KBDCTRL }, // 0x02
{ VK_MENU, KBDALT }, // 0x04
{ 0, 0 }
};
// JPN IBM02
VK_TO_BIT aVkToBits_VK_IBM02[] = {
{ VK_SHIFT, KBDSHIFT }, // 0x01
{ VK_CONTROL, KBDCTRL }, // 0x02
{ 0, 0 }
};
/***************************************************************************\
* Tables defining how some Virtual Key values are modified when other keys
* are held down.
* Translates key combinations into indices for gapulCvt_VK_101[] or for
* gapulCvt_VK_84[] or for
*
* See kbd.h for a full description.
*
\***************************************************************************/
MODIFIERS Modifiers_VK_STANDARD = {
&aVkToBits_VK[0],
4, // Maximum modifier bitmask/index
{
SHFT_INVALID, // no keys held down (no VKs are modified)
0, // SHIFT held down 84-86 key kbd
1, // CTRL held down 101/102 key kbd
SHFT_INVALID, // CTRL-SHIFT held down (no VKs are modified)
2 // ALT held down 84-86 key kbd
}
};
MODIFIERS Modifiers_VK_IBM02 = {
&aVkToBits_VK_IBM02[0],
3, // Maximum modifier bitmask/index
{
SHFT_INVALID, // no modifier keys (no VK modification)
SHFT_INVALID, // Shift (no VK modification)
0, // Control (VK modification number 0)
1 // Control Shift (VK modification number 1)
}
};
/***************************************************************************\
* A tables of pointers indexed by the number obtained from Modify_VK.
* If a pointer is non-NULL then the table it points to is searched for
* Virtual Key that should have their values changed.
* There are two versions: one for 84-86 key kbds, one for 101/102 key kbds.
* gapulCvt_VK is initialized with the default (101/102 key kbd).
\***************************************************************************/
ULONG *gapulCvt_VK_101[] = {
NULL, // No VKs are changed by SHIFT being held down
aulControlCvt_VK, // Some VKs are changed by CTRL being held down
NULL // No VKs are changed by ALT being held down
};
ULONG *gapulCvt_VK_84[] = {
aulShiftCvt_VK, // Some VKs are changed by SHIFT being held down
aulControlCvt_VK, // Some VKs are changed by CTRL being held down
aulAltCvt_VK // Some VKs are changed by ALT being held down
};
ULONG *gapulCvt_VK_IBM02[] = {
aulControlCvt_VK_IBM02, // VK modification number 0 (Control key)
aulShiftControlCvt_VK_IBM02,// VK modification number 1 (Shift Control key)
};
PULONG *gapulCvt_VK = gapulCvt_VK_101;
PMODIFIERS gpModifiers_VK = &Modifiers_VK_STANDARD;
/***************************************************************************\
* The table ausNumPadCvt is used to convert a cursor movement
* virtual key value (obtained from ausVK_???[]) into a VK_NUMPAD
* virtual key value. This translation is done when NumLock is
* on and no shift keys are pressed.
\***************************************************************************/
USHORT ausNumPadCvt[] =
{
MAKEWORD(VK_INSERT, VK_NUMPAD0),
MAKEWORD(VK_END, VK_NUMPAD1),
MAKEWORD(VK_DOWN, VK_NUMPAD2),
MAKEWORD(VK_NEXT, VK_NUMPAD3),
MAKEWORD(VK_LEFT, VK_NUMPAD4),
MAKEWORD(VK_CLEAR, VK_NUMPAD5),
MAKEWORD(VK_RIGHT, VK_NUMPAD6),
MAKEWORD(VK_HOME, VK_NUMPAD7),
MAKEWORD(VK_UP, VK_NUMPAD8),
MAKEWORD(VK_PRIOR, VK_NUMPAD9),
MAKEWORD(VK_DELETE, VK_DECIMAL),
MAKEWORD(0, 0)
};
/***************************************************************************\
* xxxNumpadCursor() - handle special case Numpad Cursor-movement Keys
*
* If NumLock is on, and Shift is up then:
* VK_INSERT -> VK_NUMPAD0
* VK_END -> VK_NUMPAD1
* VK_DOWN -> VK_NUMPAD2
* VK_NEXT -> VK_NUMPAD3
* VK_LEFT -> VK_NUMPAD4
* VK_CLEAR -> VK_NUMPAD5
* VK_RIGHT -> VK_NUMPAD6
* VK_HOME -> VK_NUMPAD7
* VK_UP -> VK_NUMPAD8
* VK_PRIOR -> VK_NUMPAD9
* VK_DELETE -> VK_DECIMAL (unless CTRL-ALT-DEL)
* If Numlock is on, and Shift is down then precede first Numpad Cursor key
* going down with a fake Shift key coming up & follow the Numpad Cursor key
* coming up with with a fake Shift key going down.
*
* Return value:
* TRUE: keep this routine active: continue passing Key Events through here
* FALSE: deactivet this routine: stop sending Key Events through here.
*
* This function will leave the critical section only if low level hooks
* are installed and the call to xxxKeyEvent is made
*
\***************************************************************************/
BOOL
xxxNumpadCursor(
PKE pKe)
{
static BYTE bLastNumpadCursor = 0;
static USHORT VkFakedShiftUp; // VK_LSHIFT or VK_RSHIFT
static BYTE VscFakedShiftUp; // 0x2A or 0x36 resp.
int i;
CheckCritIn();
if (bLastNumpadCursor) {
if (bLastNumpadCursor == (BYTE)(pKe->usFlaggedVk)) {
/*
* Same key as last one: if coming up, or going down?
*/
if (pKe->usFlaggedVk & KBDBREAK) {
/*
* Numpad Cursor key came back up. Send this key now, and make
* sure that the Shift key will then appear to go back down
* again.
*/
xxxKeyEvent(pKe->usFlaggedVk, pKe->bScanCode,
pKe->dwTime, 0,
#ifdef GENERIC_INPUT
pKe->hDevice,
&pKe->data,
#endif
FALSE);
bLastNumpadCursor = 0;
pKe->usFlaggedVk = VkFakedShiftUp;
pKe->bScanCode = VscFakedShiftUp;
}
/*
* Going down: this key is repeating, so just pass it on
* unaltered and keep the KEProc active
*/
return TRUE;
} else {
/*
* It is a different key. Fake the Shift key back down again,
* and continue (it may be another Numpad Cursor key)
*/
xxxKeyEvent(VkFakedShiftUp,
(WORD)(VscFakedShiftUp | SCANCODE_SIMULATED),
pKe->dwTime, 0,
#ifdef GENERIC_INPUT
pKe->hDevice,
&pKe->data,
#endif
FALSE);
bLastNumpadCursor = 0;
}
}
if (pKe->usFlaggedVk & KBDNUMPAD) {
UINT fsModifiers;
/*
* This is the numeric pad.
* Here, if NumLock is set, we change the virtual keycodes to
* numeric VK_NUMPAD codes, so the keys will be translated
* as numbers etc. But if a shift key is down, we handle
* these as cursor keys, but we need to make sure that these
* are seen as UNSHIFTED
*/
/*
* Check for SAS.
*/
if (IsSAS((BYTE)(pKe->usFlaggedVk), &fsModifiers)) {
return TRUE;
} else if (TestRawKeyToggle(VK_NUMLOCK)) {
if (TestRawKeyDown(VK_SHIFT)) {
/*
* key is down (bit(s) set in BIOS key state), so we are going
* to keep this as a cursor key. To do this, we need to
* make sure that Windows' state vector entry for VK_SHIFT is
* OFF even though a shift key is actually down.
*/
bLastNumpadCursor = (BYTE)(pKe->usFlaggedVk);
if (TestRawKeyDown(VK_RSHIFT)) {
VkFakedShiftUp = VK_RSHIFT | KBDEXT;
VscFakedShiftUp = 0x36;
} else {
VkFakedShiftUp = VK_LSHIFT;
VscFakedShiftUp = 0x2A;
}
xxxKeyEvent((USHORT)(VkFakedShiftUp | KBDBREAK),
(WORD)(VscFakedShiftUp | SCANCODE_SIMULATED),
pKe->dwTime, 0,
#ifdef GENERIC_INPUT
pKe->hDevice,
&pKe->data,
#endif
FALSE);
return TRUE;
}
/*
* NumLock ON but Shift key up: Alter the Virtual Key event,
* but not for injected virtual keys.
*/
if ((pKe->usFlaggedVk & KBDINJECTEDVK) == 0) {
for (i = 0; ausNumPadCvt[i] != 0; i++) {
if (LOBYTE(ausNumPadCvt[i]) == LOBYTE(pKe->usFlaggedVk)) {
/*
* keep extra bits, but change VK value
*/
pKe->usFlaggedVk &= ~0xFF;
pKe->usFlaggedVk |= (UINT)(HIBYTE(ausNumPadCvt[i]));
break;
}
}
}
}
}
return TRUE;
}
/***************************************************************************\
*
* xxxICO_00() - handle special case '00' key
*
* LATER IanJa: should only be in ICO OEM file for kbd with '00' key
*
* This function will leave the critical section only if low level hooks
* are installed ant the call to xxxKeyEvent is made
*
\***************************************************************************/
BOOL
xxxICO_00(
PKE pKe)
{
CheckCritIn();
if ((pKe->usFlaggedVk & 0xFF) != VK_ICO_00) {
/*
* Pass the keystroke on unaltered
*/
return TRUE;
}
if (pKe->usFlaggedVk & KBDBREAK) {
/*
* '0' key comes up
*/
pKe->usFlaggedVk = '0' | KBDEXT | KBDBREAK;
} else {
/*
* '0' down, up, down
*/
xxxKeyEvent('0', pKe->bScanCode, pKe->dwTime, 0,
#ifdef GENERIC_INPUT
pKe->hDevice,
&pKe->data,
#endif
FALSE);
xxxKeyEvent('0' | KBDBREAK, pKe->bScanCode, pKe->dwTime, 0,
#ifdef GENERIC_INPUT
pKe->hDevice,
&pKe->data,
#endif
FALSE);
pKe->usFlaggedVk = '0' | KBDEXT;
}
return TRUE;
}
KEPROC aKEProcOEM[] = {
xxxICO_00, // Bitmask 0x01
xxxNumpadCursor, // Bitmask 0x02
NULL
};