test: kbd.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# kbd.c

Go to the documentation of this file.

    00001 /****************************** Module Header ******************************\,
    00002 * Module Name: kbd.c
    00003 *
    00004 * Copyright (c) 1985 - 1999, Microsoft Corporation
    00005 *
    00006 * OEM-specific tables and routines for IBM Extended 101/102 style keyboards
    00007 *
    00008 * History:
    00009 * 30-04-91 IanJa       Created.
    00010 \***************************************************************************/
    00011
    00012 #include "precomp.h"
    00013 #pragma hdrstop
    00014
    00015
    00016 /***************************************************************************\
    00017 * aVkToVsc[] - table associating Virtual Key codes with Virtual Scancodes
    00018 *
    00019 * Ordered, 0-terminated.
    00020 *
    00021 * This is used for those Virtual Keys that do not appear in ausVK_???[]
    00022 * These are not the base Virtual Keys.  They require some modifier key
    00023 * depression (CTRL, ALT, SHIFT) or NumLock On to be generated.
    00024 *
    00025 * All the scancodes listed below should be marked KBDMULTIVK or KBDNUMPAD in
    00026 * ausVK_???[].
    00027 *
    00028 * This table is used by MapVirtualKey(wVk, 0).
    00029 \***************************************************************************/
    00030 BYTE aVkNumpad[] = {
    00031     VK_NUMPAD7,  VK_NUMPAD8,  VK_NUMPAD9, 0xFF, // 0x47 0x48 0x49 (0x4A)
    00032     VK_NUMPAD4,  VK_NUMPAD5,  VK_NUMPAD6, 0xFF, // 0x4B 0x4C 0x4D (0x4E)
    00033     VK_NUMPAD1,  VK_NUMPAD2,  VK_NUMPAD3,       // 0x4F 0x50 0x51
    00034     VK_NUMPAD0,  VK_DECIMAL,  0                 // 0x50 0x51
    00035 };
    00036
    00037 /***************************************************************************\
    00038 * How some Virtual Key values change when a SHIFT key is held down.
    00039 \***************************************************************************/
    00040 ULONG aulShiftCvt_VK[] = {
    00041     MAKELONG(VK_MULTIPLY, VK_SNAPSHOT),
    00042     MAKELONG(0,0)
    00043 };
    00044
    00045 // JPN IMB02
    00046 ULONG aulShiftControlCvt_VK_IBM02[] = {
    00047     MAKELONG(VK_SCROLL, VK_CANCEL | KBDEXT),
    00048     MAKELONG(VK_NUMLOCK, VK_PAUSE | KBDEXT),
    00049     MAKELONG(0,0)
    00050 };
    00051
    00052 /***************************************************************************\
    00053 * How some Virtual Key values change when a CONTROL key is held down.
    00054 \***************************************************************************/
    00055 ULONG aulControlCvt_VK[] = {
    00056     MAKELONG(VK_NUMLOCK,  VK_PAUSE | KBDEXT),
    00057     MAKELONG(VK_SCROLL,   VK_CANCEL),
    00058     MAKELONG(0,0)
    00059 };
    00060
    00061 // JPN IBM02
    00062 ULONG aulControlCvt_VK_IBM02[] = {
    00063     MAKELONG(VK_PAUSE, VK_CANCEL | KBDEXT),
    00064     MAKELONG(VK_SCROLL, VK_CANCEL | KBDEXT),
    00065     MAKELONG(0,0)
    00066 };
    00067
    00068 /***************************************************************************\
    00069 * How some Virtual Key values change when an ALT key is held down.
    00070 * The SHIFT and ALT keys both alter VK values the same way!!
    00071 \***************************************************************************/
    00072 #define aulAltCvt_VK aulShiftCvt_VK
    00073
    00074
    00075 /***************************************************************************\
    00076 * This table list keys that may affect Virtual Key values when held down.
    00077 *
    00078 * See kbd.h for a full description.
    00079 *
    00080 * 101/102key keyboard (type 4):
    00081 *    Virtual Key values vary only if CTRL is held down.
    00082 * 84-86 key keyboards (type 3):
    00083 *    Virtual Key values vary if one of SHIFT, CTRL or ALT is held down.
    00084 \***************************************************************************/
    00085
    00086 VK_TO_BIT aVkToBits_VK[] = {
    00087     { VK_SHIFT,   KBDSHIFT }, // 0x01
    00088     { VK_CONTROL, KBDCTRL  }, // 0x02
    00089     { VK_MENU,    KBDALT   }, // 0x04
    00090     { 0,          0        }
    00091 };
    00092
    00093 // JPN IBM02
    00094 VK_TO_BIT aVkToBits_VK_IBM02[] = {
    00095     { VK_SHIFT,   KBDSHIFT }, // 0x01
    00096     { VK_CONTROL, KBDCTRL  }, // 0x02
    00097     { 0,          0        }
    00098 };
    00099
    00100 /***************************************************************************\
    00101 * Tables defining how some Virtual Key values are modified when other keys
    00102 * are held down.
    00103 * Translates key combinations into indices for gapulCvt_VK_101[] or for
    00104 * gapulCvt_VK_84[] or for
    00105 *
    00106 * See kbd.h for a full description.
    00107 *
    00108 \***************************************************************************/
    00109
    00110 MODIFIERS Modifiers_VK_STANDARD = {
    00111     &aVkToBits_VK[0],
    00112     4,                 // Maximum modifier bitmask/index
    00113     {
    00114         SHFT_INVALID,  // no keys held down    (no VKs are modified)
    00115         0,             // SHIFT held down      84-86 key kbd
    00116         1,             // CTRL held down       101/102 key kbd
    00117         SHFT_INVALID,  // CTRL-SHIFT held down (no VKs are modified)
    00118         2              // ALT held down        84-86 key kbd
    00119     }
    00120 };
    00121
    00122 MODIFIERS Modifiers_VK_IBM02 = {
    00123     &aVkToBits_VK_IBM02[0],
    00124     3,                   // Maximum modifier bitmask/index
    00125     {
    00126         SHFT_INVALID,  // no modifier keys (no VK modification)
    00127         SHFT_INVALID,  // Shift            (no VK modification)
    00128         0,             // Control          (VK modification number 0)
    00129         1              // Control Shift    (VK modification number 1)
    00130     }
    00131 };
    00132
    00133 /***************************************************************************\
    00134 * A tables of pointers indexed by the number obtained from Modify_VK.
    00135 * If a pointer is non-NULL then the table it points to is searched for
    00136 * Virtual Key that should have their values changed.
    00137 * There are two versions: one for 84-86 key kbds, one for 101/102 key kbds.
    00138 * gapulCvt_VK is initialized with the default (101/102 key kbd).
    00139 \***************************************************************************/
    00140 ULONG *gapulCvt_VK_101[] = {
    00141     NULL,                 // No VKs are changed by SHIFT being held down
    00142     aulControlCvt_VK,     // Some VKs are changed by CTRL being held down
    00143     NULL                  // No VKs are changed by ALT being held down
    00144 };
    00145
    00146 ULONG *gapulCvt_VK_84[] = {
    00147     aulShiftCvt_VK,       // Some VKs are changed by SHIFT being held down
    00148     aulControlCvt_VK,     // Some VKs are changed by CTRL being held down
    00149     aulAltCvt_VK          // Some VKs are changed by ALT being held down
    00150 };
    00151
    00152 ULONG *gapulCvt_VK_IBM02[] = {
    00153     aulControlCvt_VK_IBM02,     // VK modification number 0 (Control key)
    00154     aulShiftControlCvt_VK_IBM02,// VK modification number 1 (Shift Control key)
    00155 };
    00156
    00157 PULONG *gapulCvt_VK = gapulCvt_VK_101;
    00158
    00159 PMODIFIERS gpModifiers_VK = &Modifiers_VK_STANDARD;
    00160
    00161 /***************************************************************************\
    00162 * The table ausNumPadCvt is used to convert a cursor movement
    00163 * virtual key value (obtained from ausVK_???[]) into a VK_NUMPAD
    00164 * virtual key value.  This translation is done when NumLock is
    00165 * on and no shift keys are pressed.
    00166 \***************************************************************************/
    00167 USHORT ausNumPadCvt[] =
    00168 {
    00169     MAKEWORD(VK_INSERT, VK_NUMPAD0),
    00170     MAKEWORD(VK_END, VK_NUMPAD1),
    00171     MAKEWORD(VK_DOWN, VK_NUMPAD2),
    00172     MAKEWORD(VK_NEXT, VK_NUMPAD3),
    00173     MAKEWORD(VK_LEFT, VK_NUMPAD4),
    00174     MAKEWORD(VK_CLEAR, VK_NUMPAD5),
    00175     MAKEWORD(VK_RIGHT, VK_NUMPAD6),
    00176     MAKEWORD(VK_HOME, VK_NUMPAD7),
    00177     MAKEWORD(VK_UP, VK_NUMPAD8),
    00178     MAKEWORD(VK_PRIOR, VK_NUMPAD9),
    00179     MAKEWORD(VK_DELETE, VK_DECIMAL),
    00180     MAKEWORD(0, 0)
    00181 };
    00182
    00183 /***************************************************************************\
    00184 * xxxNumpadCursor() - handle special case Numpad Cursor-movement Keys
    00185 *
    00186 * If NumLock is on, and Shift is up then:
    00187 *      VK_INSERT  -> VK_NUMPAD0
    00188 *      VK_END     -> VK_NUMPAD1
    00189 *      VK_DOWN    -> VK_NUMPAD2
    00190 *      VK_NEXT    -> VK_NUMPAD3
    00191 *      VK_LEFT    -> VK_NUMPAD4
    00192 *      VK_CLEAR   -> VK_NUMPAD5
    00193 *      VK_RIGHT   -> VK_NUMPAD6
    00194 *      VK_HOME    -> VK_NUMPAD7
    00195 *      VK_UP      -> VK_NUMPAD8
    00196 *      VK_PRIOR   -> VK_NUMPAD9
    00197 *      VK_DELETE  -> VK_DECIMAL (unless CTRL-ALT-DEL)
    00198 * If Numlock is on, and Shift is down then precede first Numpad Cursor key
    00199 * going down with a fake Shift key coming up & follow the Numpad Cursor key
    00200 * coming up with with a fake Shift key going down.
    00201 *
    00202 * Return value:
    00203 *   TRUE: keep this routine active: continue passing Key Events through here
    00204 *  FALSE: deactivet this routine: stop sending Key Events through here.
    00205 *
    00206 * This function will leave the critical section only if low level hooks
    00207 * are installed and the call to xxxKeyEvent is made
    00208 *
    00209 \***************************************************************************/
    00210 BOOL
    00211 xxxNumpadCursor(
    00212     PKE pKe)
    00213 {
    00214     static BYTE bLastNumpadCursor = 0;
    00215     static USHORT VkFakedShiftUp;  // VK_LSHIFT or VK_RSHIFT
    00216     static BYTE VscFakedShiftUp;   // 0x2A or 0x36 resp.
    00217     int i;
    00218
    00219     CheckCritIn();
    00220
    00221     if (bLastNumpadCursor) {
    00222         if (bLastNumpadCursor == (BYTE)(pKe->usFlaggedVk)) {
    00223             /*
    00224              * Same key as last one: if coming up, or going down?
    00225              */
    00226             if (pKe->usFlaggedVk & KBDBREAK) {
    00227                 /*
    00228                  * Numpad Cursor key came back up. Send this key now, and make
    00229                  * sure that the Shift key will then appear to go back down
    00230                  * again.
    00231                  */
    00232                 xxxKeyEvent(pKe->usFlaggedVk, pKe->bScanCode,
    00233                             pKe->dwTime, 0, FALSE);
    00234                 bLastNumpadCursor = 0;
    00235                 pKe->usFlaggedVk = VkFakedShiftUp;
    00236                 pKe->bScanCode = VscFakedShiftUp;
    00237             }
    00238             /*
    00239              * Going down: this key is repeating, so just pass it on
    00240              * unaltered and keep the KEProc active
    00241              */
    00242             return TRUE;
    00243         } else {
    00244             /*
    00245              * It is a different key.  Fake the Shift key back down again,
    00246              * and continue (it may be another Numpad Cursor key)
    00247              */
    00248             xxxKeyEvent(VkFakedShiftUp,
    00249                     (WORD)(VscFakedShiftUp | SCANCODE_SIMULATED),
    00250                      pKe->dwTime, 0, FALSE);
    00251             bLastNumpadCursor = 0;
    00252         }
    00253     }
    00254
    00255     if (pKe->usFlaggedVk & KBDNUMPAD) {
    00256
    00257         UINT fsModifiers;
    00258         /*
    00259          * This is the numeric pad.
    00260          * Here, if NumLock is set, we change the virtual keycodes to
    00261          * numeric VK_NUMPAD codes, so the keys will be translated
    00262          * as numbers etc.  But if a shift key is down, we handle
    00263          * these as cursor keys, but we need to make sure that these
    00264          * are seen as UNSHIFTED
    00265          */
    00266
    00267         /*
    00268          * Check for SAS.
    00269          */
    00270         if (IsSAS((BYTE)(pKe->usFlaggedVk), &fsModifiers)) {
    00271             return TRUE;
    00272         } else if (TestRawKeyToggle(VK_NUMLOCK)) {
    00273             if (TestRawKeyDown(VK_SHIFT)) {
    00274                 /*
    00275                  * key is down (bit(s) set in BIOS key state), so we are going
    00276                  * to keep this as a cursor key.  To do this, we need to
    00277                  * make sure that Windows' state vector entry for VK_SHIFT is
    00278                  * OFF even though a shift key is actually down.
    00279                  */
    00280                 bLastNumpadCursor = (BYTE)(pKe->usFlaggedVk);
    00281                 if (TestRawKeyDown(VK_RSHIFT)) {
    00282                     VkFakedShiftUp = VK_RSHIFT | KBDEXT;
    00283                     VscFakedShiftUp = 0x36;
    00284                 } else {
    00285                     VkFakedShiftUp = VK_LSHIFT;
    00286                     VscFakedShiftUp = 0x2A;
    00287                 }
    00288                 xxxKeyEvent((USHORT)(VkFakedShiftUp | KBDBREAK),
    00289                         (WORD)(VscFakedShiftUp | SCANCODE_SIMULATED),
    00290                          pKe->dwTime, 0, FALSE);
    00291                 return TRUE;
    00292             }
    00293
    00294             /*
    00295              * NumLock ON but Shift key up: Alter the Virtual Key event,
    00296              * but not for injected virtual keys.
    00297              */
    00298             if ((pKe->usFlaggedVk & KBDINJECTEDVK) == 0) {
    00299                 for (i = 0; ausNumPadCvt[i] != 0; i++) {
    00300                     if (LOBYTE(ausNumPadCvt[i]) == LOBYTE(pKe->usFlaggedVk)) {
    00301                         /*
    00302                          * keep extra bits, but change VK value
    00303                          */
    00304                         pKe->usFlaggedVk &= ~0xFF;
    00305                         pKe->usFlaggedVk |= (UINT)(HIBYTE(ausNumPadCvt[i]));
    00306                         break;
    00307
    00308                     }
    00309                 }
    00310             }
    00311         }
    00312     }
    00313     return TRUE;
    00314 }
    00315
    00316 /***************************************************************************\
    00317 *
    00318 * xxxICO_00() - handle special case '00' key
    00319 *
    00320 * LATER IanJa: should only be in ICO OEM file for kbd with '00' key
    00321 *
    00322 * This function will leave the critical section only if low level hooks
    00323 * are installed ant the call to xxxKeyEvent is made
    00324 *
    00325 \***************************************************************************/
    00326 BOOL
    00327 xxxICO_00(
    00328     PKE pKe)
    00329 {
    00330     CheckCritIn();
    00331
    00332     if ((pKe->usFlaggedVk & 0xFF) != VK_ICO_00) {
    00333         /*
    00334          * Pass the keystroke on unaltered
    00335          */
    00336         return TRUE;
    00337     }
    00338
    00339     if (pKe->usFlaggedVk & KBDBREAK) {
    00340         /*
    00341          * '0' key comes up
    00342          */
    00343         pKe->usFlaggedVk = '0' | KBDEXT | KBDBREAK;
    00344     } else {
    00345         /*
    00346          * '0' down, up, down
    00347          */
    00348         xxxKeyEvent('0', pKe->bScanCode, pKe->dwTime, 0, FALSE);
    00349         xxxKeyEvent('0' | KBDBREAK, pKe->bScanCode, pKe->dwTime, 0, FALSE);
    00350         pKe->usFlaggedVk = '0' | KBDEXT;
    00351     }
    00352
    00353     return TRUE;
    00354 }
    00355
    00356 KEPROC aKEProcOEM[] = {
    00357     xxxICO_00,       // Bitmask 0x01
    00358     xxxNumpadCursor, // Bitmask 0x02
    00359     NULL
    00360 };