MODULE WinKey;
IMPORT Word, VBT;
IMPORT KeyboardKey AS KK, Latin1Key AS LK, WinUser AS WU;
PROCEDURE Translate (vk: [0 .. 255]): VBT.KeySym =
VAR
shifted := Word.And (WU.GetKeyState (WU.VK_SHIFT), 16_8000) # 0;
caps_lock := Word.And (WU.GetKeyState (WU.VK_CAPITAL), 16_0001) # 0;
BEGIN
IF (shifted # caps_lock)
THEN RETURN Map [vk].shifted;
ELSE RETURN Map [vk].normal;
END;
END Translate;
CONST
XX = KK.VoidSymbol;
TYPE
KD = RECORD (*KeyDesc*)
win_key : [0..255];
normal : [0..16_FFFFFF];
shifted : [0..16_FFFFFF];
END;
CONST
Map = ARRAY [0..255] OF KD {
(* 00 *) KD{ 16_00, XX, XX },
(* 01 *) KD{ WU.VK_LBUTTON, XX, XX },
(* 02 *) KD{ WU.VK_RBUTTON, XX, XX },
(* 03 *) KD{ WU.VK_CANCEL, KK.Cancel, KK.Cancel },
(* 04 *) KD{ WU.VK_MBUTTON, XX, XX },
(* 05 *) KD{ 16_05, XX, XX },
(* 06 *) KD{ 16_06, XX, XX },
(* 07 *) KD{ 16_07, XX, XX },
(* 08 *) KD{ WU.VK_BACK, KK.BackSpace, KK.BackSpace },
(* 09 *) KD{ WU.VK_TAB, KK.Tab, KK.Tab },
(* 0A *) KD{ 16_0A, XX, XX },
(* 0B *) KD{ 16_0B, XX, XX },
(* 0C *) KD{ WU.VK_CLEAR, KK.Clear, KK.Clear },
(* 0D *) KD{ WU.VK_RETURN, KK.Return, KK.Return },
(* 0E *) KD{ 16_0E, XX, XX },
(* 0F *) KD{ 16_0F, XX, XX },
(* 10 *) KD{ WU.VK_SHIFT, KK.Shift_L, KK.Shift_L },
(* 11 *) KD{ WU.VK_CONTROL, KK.Control_L, KK.Control_L },
(* 12 *) KD{ WU.VK_MENU, KK.Menu, KK.Menu },
(* 13 *) KD{ WU.VK_PAUSE, KK.Pause, KK.Pause },
(* 14 *) KD{ WU.VK_CAPITAL, KK.Caps_Lock, KK.Caps_Lock },
(* 15 *) KD{ 16_15, XX, XX },
(* 16 *) KD{ 16_16, XX, XX },
(* 17 *) KD{ 16_17, XX, XX },
(* 18 *) KD{ 16_18, XX, XX },
(* 19 *) KD{ 16_19, XX, XX },
(* 1A *) KD{ 16_1A, XX, XX },
(* 1B *) KD{ WU.VK_ESCAPE, KK.Escape, KK.Escape },
(* 1C *) KD{ 16_1C, XX, XX },
(* 1D *) KD{ 16_1D, XX, XX },
(* 1E *) KD{ 16_1E, XX, XX },
(* 1F *) KD{ 16_1F, XX, XX },
(* 20 *) KD{ WU.VK_SPACE, LK.space, LK.space },
(* 21 *) KD{ WU.VK_PRIOR, KK.Prior, KK.Prior },
(* 22 *) KD{ WU.VK_NEXT, KK.Next, KK.Next },
(* 23 *) KD{ WU.VK_END, KK.End, KK.End },
(* 24 *) KD{ WU.VK_HOME, KK.Home, KK.Home },
(* 25 *) KD{ WU.VK_LEFT, KK.Left, KK.Left },
(* 26 *) KD{ WU.VK_UP, KK.Up, KK.Up },
(* 27 *) KD{ WU.VK_RIGHT, KK.Right, KK.Right },
(* 28 *) KD{ WU.VK_DOWN, KK.Down, KK.Down },
(* 29 *) KD{ WU.VK_SELECT, KK.Select, KK.Select },
(* 2A *) KD{ WU.VK_PRINT, KK.Print, KK.Print },
(* 2B *) KD{ WU.VK_EXECUTE, KK.Execute, KK.Execute },
(* 2C *) KD{ WU.VK_SNAPSHOT, XX, XX },
(* 2D *) KD{ WU.VK_INSERT, KK.Insert, KK.Insert },
(* 2E *) KD{ WU.VK_DELETE, KK.Delete, KK.Delete },
(* 2F *) KD{ WU.VK_HELP, KK.Help, KK.Help },
(* 30 *) KD{ 16_30, LK.zero, LK.parenright },
(* 31 *) KD{ 16_31, LK.one, LK.exclam },
(* 32 *) KD{ 16_32, LK.two, LK.at },
(* 33 *) KD{ 16_33, LK.three, LK.numbersign },
(* 34 *) KD{ 16_34, LK.four, LK.dollar },
(* 35 *) KD{ 16_35, LK.five, LK.percent },
(* 36 *) KD{ 16_36, LK.six, LK.asciicircum },
(* 37 *) KD{ 16_37, LK.seven, LK.ampersand },
(* 38 *) KD{ 16_38, LK.eight, LK.asterisk },
(* 39 *) KD{ 16_39, LK.nine, LK.parenleft },
(* 3A *) KD{ 16_3A, XX, XX },
(* 3B *) KD{ 16_3B, XX, XX },
(* 3C *) KD{ 16_3C, XX, XX },
(* 3D *) KD{ 16_3D, XX, XX },
(* 3E *) KD{ 16_3E, XX, XX },
(* 3F *) KD{ 16_3F, XX, XX },
(* 40 *) KD{ 16_40, XX, XX },
(* 41 *) KD{ 16_41, LK.a, LK.A },
(* 42 *) KD{ 16_42, LK.b, LK.B },
(* 43 *) KD{ 16_43, LK.c, LK.C },
(* 44 *) KD{ 16_44, LK.d, LK.D },
(* 45 *) KD{ 16_45, LK.e, LK.E },
(* 46 *) KD{ 16_46, LK.f, LK.F },
(* 47 *) KD{ 16_47, LK.g, LK.G },
(* 48 *) KD{ 16_48, LK.h, LK.H },
(* 49 *) KD{ 16_49, LK.i, LK.I },
(* 4A *) KD{ 16_4A, LK.j, LK.J },
(* 4B *) KD{ 16_4B, LK.k, LK.K },
(* 4C *) KD{ 16_4C, LK.l, LK.L },
(* 4D *) KD{ 16_4D, LK.m, LK.M },
(* 4E *) KD{ 16_4E, LK.n, LK.N },
(* 4F *) KD{ 16_4F, LK.o, LK.O },
(* 50 *) KD{ 16_50, LK.p, LK.P },
(* 51 *) KD{ 16_51, LK.q, LK.Q },
(* 52 *) KD{ 16_52, LK.r, LK.R },
(* 53 *) KD{ 16_53, LK.s, LK.S },
(* 54 *) KD{ 16_54, LK.t, LK.T },
(* 55 *) KD{ 16_55, LK.u, LK.U },
(* 56 *) KD{ 16_56, LK.v, LK.V },
(* 57 *) KD{ 16_57, LK.w, LK.W },
(* 58 *) KD{ 16_58, LK.x, LK.X },
(* 59 *) KD{ 16_59, LK.y, LK.Y },
(* 5A *) KD{ 16_5A, LK.z, LK.Z },
(* 5B *) KD{ 16_5B, XX, XX },
(* 5C *) KD{ 16_5C, XX, XX },
(* 5D *) KD{ 16_5D, XX, XX },
(* 5E *) KD{ 16_5E, XX, XX },
(* 5F *) KD{ 16_5F, XX, XX },
(* 60 *) KD{ WU.VK_NUMPAD0, KK.KP_0, KK.KP_0 },
(* 61 *) KD{ WU.VK_NUMPAD1, KK.KP_1, KK.KP_1 },
(* 62 *) KD{ WU.VK_NUMPAD2, KK.KP_2, KK.KP_2 },
(* 63 *) KD{ WU.VK_NUMPAD3, KK.KP_3, KK.KP_3 },
(* 64 *) KD{ WU.VK_NUMPAD4, KK.KP_4, KK.KP_4 },
(* 65 *) KD{ WU.VK_NUMPAD5, KK.KP_5, KK.KP_5 },
(* 66 *) KD{ WU.VK_NUMPAD6, KK.KP_6, KK.KP_6 },
(* 67 *) KD{ WU.VK_NUMPAD7, KK.KP_7, KK.KP_7 },
(* 68 *) KD{ WU.VK_NUMPAD8, KK.KP_8, KK.KP_8 },
(* 69 *) KD{ WU.VK_NUMPAD9, KK.KP_9, KK.KP_9 },
(* 6A *) KD{ WU.VK_MULTIPLY, KK.KP_Multiply, KK.KP_Multiply },
(* 6B *) KD{ WU.VK_ADD, KK.KP_Add, KK.KP_Add },
(* 6C *) KD{ WU.VK_SEPARATOR, KK.KP_Separator, KK.KP_Separator },
(* 6D *) KD{ WU.VK_SUBTRACT, KK.KP_Subtract, KK.KP_Subtract },
(* 6E *) KD{ WU.VK_DECIMAL, KK.KP_Decimal, KK.KP_Decimal },
(* 6F *) KD{ WU.VK_DIVIDE, KK.KP_Divide, KK.KP_Divide },
(* 70 *) KD{ WU.VK_F1, KK.F1, KK.F1 },
(* 71 *) KD{ WU.VK_F2, KK.F2, KK.F2 },
(* 72 *) KD{ WU.VK_F3, KK.F3, KK.F3 },
(* 73 *) KD{ WU.VK_F4, KK.F4, KK.F4 },
(* 74 *) KD{ WU.VK_F5, KK.F5, KK.F5 },
(* 75 *) KD{ WU.VK_F6, KK.F6, KK.F6 },
(* 76 *) KD{ WU.VK_F7, KK.F7, KK.F7 },
(* 77 *) KD{ WU.VK_F8, KK.F8, KK.F8 },
(* 78 *) KD{ WU.VK_F9, KK.F9, KK.F9 },
(* 79 *) KD{ WU.VK_F10, KK.F10, KK.F10 },
(* 7A *) KD{ WU.VK_F11, KK.F11, KK.F11 },
(* 7B *) KD{ WU.VK_F12, KK.F12, KK.F12 },
(* 7C *) KD{ WU.VK_F13, KK.F13, KK.F13 },
(* 7D *) KD{ WU.VK_F14, KK.F14, KK.F14 },
(* 7E *) KD{ WU.VK_F15, KK.F15, KK.F15 },
(* 7F *) KD{ WU.VK_F16, KK.F16, KK.F16 },
(* 80 *) KD{ WU.VK_F17, KK.F17, KK.F17 },
(* 81 *) KD{ WU.VK_F18, KK.F18, KK.F18 },
(* 82 *) KD{ WU.VK_F19, KK.F19, KK.F19 },
(* 83 *) KD{ WU.VK_F20, KK.F20, KK.F20 },
(* 84 *) KD{ WU.VK_F21, KK.F21, KK.F21 },
(* 85 *) KD{ WU.VK_F22, KK.F22, KK.F22 },
(* 86 *) KD{ WU.VK_F23, KK.F23, KK.F23 },
(* 87 *) KD{ WU.VK_F24, KK.F24, KK.F24 },
(* 88 *) KD{ 16_88, XX, XX },
(* 89 *) KD{ 16_89, XX, XX },
(* 8A *) KD{ 16_8A, XX, XX },
(* 8B *) KD{ 16_8B, XX, XX },
(* 8C *) KD{ 16_8C, XX, XX },
(* 8D *) KD{ 16_8D, XX, XX },
(* 8E *) KD{ 16_8E, XX, XX },
(* 8F *) KD{ 16_8F, XX, XX },
(* 90 *) KD{ WU.VK_NUMLOCK, KK.Num_Lock, KK.Num_Lock },
(* 91 *) KD{ WU.VK_SCROLL, KK.Scroll_Lock, KK.Scroll_Lock },
(* 92 *) KD{ 16_92, XX, XX },
(* 93 *) KD{ 16_93, XX, XX },
(* 94 *) KD{ 16_94, XX, XX },
(* 95 *) KD{ 16_95, XX, XX },
(* 96 *) KD{ 16_96, XX, XX },
(* 97 *) KD{ 16_97, XX, XX },
(* 98 *) KD{ 16_98, XX, XX },
(* 99 *) KD{ 16_99, XX, XX },
(* 9A *) KD{ 16_9A, XX, XX },
(* 9B *) KD{ 16_9B, XX, XX },
(* 9C *) KD{ 16_9C, XX, XX },
(* 9D *) KD{ 16_9D, XX, XX },
(* 9E *) KD{ 16_9E, XX, XX },
(* 9F *) KD{ 16_9F, XX, XX },
(* A0 *) KD{ WU.VK_LSHIFT, KK.Shift_L, KK.Shift_L },
(* A1 *) KD{ WU.VK_RSHIFT, KK.Shift_R, KK.Shift_R },
(* A2 *) KD{ WU.VK_LCONTROL, KK.Control_L, KK.Control_L },
(* A3 *) KD{ WU.VK_RCONTROL, KK.Control_R, KK.Control_R },
(* A4 *) KD{ WU.VK_LMENU, KK.Alt_L, KK.Alt_L },
(* A5 *) KD{ WU.VK_RMENU, KK.Alt_R, KK.Alt_R },
(* A6 *) KD{ 16_A6, XX, XX },
(* A7 *) KD{ 16_A7, XX, XX },
(* A8 *) KD{ 16_A8, XX, XX },
(* A9 *) KD{ 16_A9, XX, XX },
(* AA *) KD{ 16_AA, XX, XX },
(* AB *) KD{ 16_AB, XX, XX },
(* AC *) KD{ 16_AC, XX, XX },
(* AD *) KD{ 16_AD, XX, XX },
(* AE *) KD{ 16_AE, XX, XX },
(* AF *) KD{ 16_AF, XX, XX },
(* B0 *) KD{ 16_B0, XX, XX },
(* B1 *) KD{ 16_B1, XX, XX },
(* B2 *) KD{ 16_B2, XX, XX },
(* B3 *) KD{ 16_B3, XX, XX },
(* B4 *) KD{ 16_B4, XX, XX },
(* B5 *) KD{ 16_B5, XX, XX },
(* B6 *) KD{ 16_B6, XX, XX },
(* B7 *) KD{ 16_B7, XX, XX },
(* B8 *) KD{ 16_B8, XX, XX },
(* B9 *) KD{ 16_B9, XX, XX },
(* BA *) KD{ 16_BA, LK.semicolon, LK.colon },
(* BB *) KD{ 16_BB, LK.equal, LK.plus },
(* BC *) KD{ 16_BC, LK.comma, LK.less },
(* BD *) KD{ 16_BD, LK.minus, LK.underscore },
(* BE *) KD{ 16_BE, LK.period, LK.greater },
(* BF *) KD{ 16_BF, LK.slash, LK.question },
(* C0 *) KD{ 16_C0, LK.grave, LK.asciitilde },
(* C1 *) KD{ 16_C1, XX, XX },
(* C2 *) KD{ 16_C2, XX, XX },
(* C3 *) KD{ 16_C3, XX, XX },
(* C4 *) KD{ 16_C4, XX, XX },
(* C5 *) KD{ 16_C5, XX, XX },
(* C6 *) KD{ 16_C6, XX, XX },
(* C7 *) KD{ 16_C7, XX, XX },
(* C8 *) KD{ 16_C8, XX, XX },
(* C9 *) KD{ 16_C9, XX, XX },
(* CA *) KD{ 16_CA, XX, XX },
(* CB *) KD{ 16_CB, XX, XX },
(* CC *) KD{ 16_CC, XX, XX },
(* CD *) KD{ 16_CD, XX, XX },
(* CE *) KD{ 16_CE, XX, XX },
(* CF *) KD{ 16_CF, XX, XX },
(* D0 *) KD{ 16_D0, XX, XX },
(* D1 *) KD{ 16_D1, XX, XX },
(* D2 *) KD{ 16_D2, XX, XX },
(* D3 *) KD{ 16_D3, XX, XX },
(* D4 *) KD{ 16_D4, XX, XX },
(* D5 *) KD{ 16_D5, XX, XX },
(* D6 *) KD{ 16_D6, XX, XX },
(* D7 *) KD{ 16_D7, XX, XX },
(* D8 *) KD{ 16_D8, XX, XX },
(* D9 *) KD{ 16_D9, XX, XX },
(* DA *) KD{ 16_DA, XX, XX },
(* DB *) KD{ 16_DB, LK.bracketleft, LK.braceleft },
(* DC *) KD{ 16_DC, LK.backslash, LK.bar },
(* DD *) KD{ 16_DD, LK.bracketright, LK.braceright },
(* DE *) KD{ 16_DE, LK.apostrophe, LK.quotedbl },
(* DF *) KD{ 16_DF, XX, XX },
(* E0 *) KD{ 16_E0, XX, XX },
(* E1 *) KD{ 16_E1, XX, XX },
(* E2 *) KD{ 16_E2, XX, XX },
(* E3 *) KD{ 16_E3, XX, XX },
(* E4 *) KD{ 16_E4, XX, XX },
(* E5 *) KD{ 16_E5, XX, XX },
(* E6 *) KD{ 16_E6, XX, XX },
(* E7 *) KD{ 16_E7, XX, XX },
(* E8 *) KD{ 16_E8, XX, XX },
(* E9 *) KD{ 16_E9, XX, XX },
(* EA *) KD{ 16_EA, XX, XX },
(* EB *) KD{ 16_EB, XX, XX },
(* EC *) KD{ 16_EC, XX, XX },
(* ED *) KD{ 16_ED, XX, XX },
(* EE *) KD{ 16_EE, XX, XX },
(* EF *) KD{ 16_EF, XX, XX },
(* F0 *) KD{ 16_F0, XX, XX },
(* F1 *) KD{ 16_F1, XX, XX },
(* F2 *) KD{ 16_F2, XX, XX },
(* F3 *) KD{ 16_F3, XX, XX },
(* F4 *) KD{ 16_F4, XX, XX },
(* F5 *) KD{ 16_F5, XX, XX },
(* F6 *) KD{ WU.VK_ATTN, XX, XX },
(* F7 *) KD{ WU.VK_CRSEL, XX, XX },
(* F8 *) KD{ WU.VK_EXSEL, XX, XX },
(* F9 *) KD{ WU.VK_EREOF, XX, XX },
(* FA *) KD{ WU.VK_PLAY, XX, XX },
(* FB *) KD{ WU.VK_ZOOM, XX, XX },
(* FC *) KD{ WU.VK_NONAME, XX, XX },
(* FD *) KD{ WU.VK_PA1, XX, XX },
(* FE *) KD{ WU.VK_OEM_CLEAR, XX, XX },
(* FF *) KD{ 16_FF, XX, XX }
};
BEGIN
(* verify that the Windows mapping didn't change... *)
FOR i := FIRST (Map) TO LAST (Map) DO
<* ASSERT Map[i].win_key = i *>
END;
END WinKey.