|
|
1.1 root 1: /***************************************************************************\
2: * Module Name: kbdgr.c
3: *
4: * Copyright (c) 1985-93, Microsoft Corporation
5: *
6: * History:
7: * 15-01-92 PamelaO Created.
8: * 04/21/92 a-kchang Modified.
9: \***************************************************************************/
10:
11: #include <windows.h>
12: #include "vkoem.h"
13: #include "kbd.h"
14: #include "kbdgr.h"
15:
16: /***************************************************************************\
17: * asuVK[] - Virtual Scan Code to Virtual Key conversion table for GR
18: \***************************************************************************/
19:
20: static USHORT ausVK[] = {
21: T00, T01, T02, T03, T04, T05, T06, T07,
22: T08, T09, T0A, T0B, T0C, T0D, T0E, T0F,
23: T10, T11, T12, T13, T14, T15, T16, T17,
24: T18, T19, T1A, T1B, T1C, T1D, T1E, T1F,
25: T20, T21, T22, T23, T24, T25, T26, T27,
26: T28, T29, T2A, T2B, T2C, T2D, T2E, T2F,
27: T30, T31, T32, T33, T34, T35,
28:
29: /*
30: * Right-hand Shift key must have KBDEXT bit set.
31: */
32: T36 | KBDEXT,
33:
34: T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot
35:
36: T38, T39, T3A, T3B, T3C, T3D, T3E,
37: T3F, T40, T41, T42, T43, T44,
38:
39: /*
40: * NumLock Key:
41: * KBDEXT - VK_NUMLOCK is an Extended key
42: * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL)
43: */
44: T45 | KBDEXT | KBDMULTIVK,
45:
46: T46 | KBDMULTIVK,
47:
48: /*
49: * Number Pad keys:
50: * KBDNUMPAD - digits 0-9 and decimal point.
51: * KBDSPECIAL - require special processing by Windows
52: */
53: T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home)
54: T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up),
55: T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp),
56: T4A,
57: T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left),
58: T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear),
59: T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right),
60: T4E,
61: T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End),
62: T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down),
63: T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn),
64: T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins),
65: T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del),
66:
67: T54, T55, T56, T57, T58
68:
69: };
70:
71: static VSC_VK aE0VscToVk[] = {
72: { 0x1C, X1C | KBDEXT }, // Numpad Enter
73: { 0x1D, X1D | KBDEXT }, // RControl
74: { 0x35, X35 | KBDEXT }, // Numpad Divide
75: { 0x37, X37 | KBDEXT }, // Snapshot
76: { 0x38, X38 | KBDEXT | KBDSPECIAL }, // RMenu (AltGr)
77: { 0x46, X46 | KBDEXT }, // Break (Ctrl + Pause)
78: { 0x47, X47 | KBDEXT }, // Home
79: { 0x48, X48 | KBDEXT }, // Up
80: { 0x49, X49 | KBDEXT }, // Prior
81: { 0x4B, X4B | KBDEXT }, // Left
82: { 0x4D, X4D | KBDEXT }, // Right
83: { 0x4F, X4F | KBDEXT }, // End
84: { 0x50, X50 | KBDEXT }, // Down
85: { 0x51, X51 | KBDEXT }, // Next
86: { 0x52, X52 | KBDEXT }, // Insert
87: { 0x53, X53 | KBDEXT }, // Delete
88: { 0, 0 }
89: };
90:
91: static VSC_VK aE1VscToVk[] = {
92: { 0x1D, Y1D }, // Pause
93: { 0 , 0 }
94: };
95:
96: /***************************************************************************\
97: * aVkToBits[] - define bitmask values for character-modifier keys
98: *
99: * typedef struct {
100: * BYTE Vk; // Virtual Key that modifies character production
101: * BYTE ModBits; // Bitmask to represent this key.
102: * } [];
103: *
104: * Vk - Virtual Key code (eg: VK_SHIFT, VK_RMENU, VK_CONTROL,...)
105: * Reserved Values:
106: * 0 null terminator
107: *
108: * ModBits - A bitmask encoding the shifter key for use in CharModifiers (blow)
109: * Reserved Values:
110: * KBDSHIFT 0
111: * KBDCTRL 1
112: * KBDALT 2
113: *
114: * Layouts that use AltGr (VK_RMENU) to modify characters do not use this
115: * method to map the right-hand Alt key to Ctrl+Alt. The KLLF_ALTGR flag
116: * is used instead (below).
117: *
118: * German keyboard has only three shifter keys (may be used in combination)
119: * SHIFT (L & R) affects alphabnumeric keys,
120: * CTRL (L & R) is used to generate control characters
121: * ALT (L & R) used for generating characters by number with numpad
122: \***************************************************************************/
123:
124: static VK_TO_BIT aVkToBits[] = {
125: { VK_SHIFT, KBDSHIFT },
126: { VK_CONTROL, KBDCTRL },
127: { VK_MENU, KBDALT },
128: { 0, 0 }
129: };
130:
131: /***************************************************************************\
132: * aModification[] - map character-modifier bitmask to character table index.
133: *
134: * typedef struct {
135: * PVK_TO_BIT pVkToBit; // Points to the aVkToBits[] table (above)
136: * WORD wMaxModBits; // max valid character-modifier bitmask.
137: * BYTE ModNumber[]; // table to map char-modifier bitmask to index.
138: * } MODIFIERS, *PMODIFIERS;
139: *
140: * Reserved index values (in ModNumber[character-modifier bitmask])
141: * SHFT_INVALID - no characters produced with this shift state.
142: *
143: * Note: index values are chosen to minimise character table sizes: the least
144: * used char-modifier key combinations are given the highest indices.
145: \***************************************************************************/
146:
147: static MODIFIERS CharModifiers = {
148: &aVkToBits[0],
149: 6,
150: {
151: // Character Char-Mod
152: // Table Index Bitmask Keys Pressed : notes
153: // =========== ======== ============== : ============
154: 0, // 000 : unshifted characters
155: 1, // 001 SHIFT : capitals, ~!@# etc.
156: 3, // 010 CTRL : control characters
157: 4, // 011 CTRL SHIFT : control characters
158: SHFT_INVALID, // 100 ALT : -- invalid --
159: SHFT_INVALID, // 101 ALT SHIFT : -- invalid --
160: 2 // 110 ALT CTRL : equivalent to AltGr
161: // 111 ALT CTRL SHIFT : -- invalid --
162: }
163: };
164:
165: /***************************************************************************\
166: * aVkToWch2[] - Virtual Key -> WCHAR for keys with max char-mod index == 2
167: * aVkToWch3[] - Virtual Key -> WCHAR for keys with max char-mod index == 3
168: * aVkToWch4[] - Virtual Key -> WCHAR for keys with max char-mod index == 4
169: * aVkToWch5[] - Virtual Key -> WCHAR for keys with max char-mod index == 5
170: *
171: * This table is searched for a matching Virtual Key, then indexed with
172: * the character-modifier index to find the corresponding characters.
173: * typedef struct _VK_TO_WCHARS3 {
174: * BYTE VirtualKey; \\ The Virtual Key code
175: * BYTE Attributes; \\ does the CapsLock key modify the character
176: * WCHAR wch[3]; \\ Array of characters, index by char-mod index
177: * };
178: *
179: * Reserved VirtualKey values (first column)
180: * 0xff - this line contains dead characters (diacritic)
181: * 0 - terminator
182: *
183: * Reserved Attribute values (second column)
184: * CAPLOK - CapsLock affects this key like Shift
185: *
186: * Reserved character values (third through last column)
187: * WCH_NONE - No character
188: * WCH_DEAD - Dead character (diacritic) value is in next line
189: *
190: \***************************************************************************/
191:
192: static VK_TO_WCHARS2 aVkToWch2[] = {
193: {'1' , CAPLOK ,'1' ,'!' },
194: {'4' , CAPLOK ,'4' ,'$' },
195: {'5' , CAPLOK ,'5' ,'%' },
196: {'A' , CAPLOK ,'a' ,'A' },
197: {'B' , CAPLOK ,'b' ,'B' },
198: {'C' , CAPLOK ,'c' ,'C' },
199: {'D' , CAPLOK ,'d' ,'D' },
200: {'E' , CAPLOK ,'e' ,'E' },
201: {'F' , CAPLOK ,'f' ,'F' },
202: {'G' , CAPLOK ,'g' ,'G' },
203: {'H' , CAPLOK ,'h' ,'H' },
204: {'I' , CAPLOK ,'i' ,'I' },
205: {'J' , CAPLOK ,'j' ,'J' },
206: {'K' , CAPLOK ,'k' ,'K' },
207: {'L' , CAPLOK ,'l' ,'L' },
208: {'N' , CAPLOK ,'n' ,'N' },
209: {'O' , CAPLOK ,'o' ,'O' },
210: {'P' , CAPLOK ,'p' ,'P' },
211: {'R' , CAPLOK ,'r' ,'R' },
212: {'S' , CAPLOK ,'s' ,'S' },
213: {'T' , CAPLOK ,'t' ,'T' },
214: {'U' , CAPLOK ,'u' ,'U' },
215: {'V' , CAPLOK ,'v' ,'V' },
216: {'W' , CAPLOK ,'w' ,'W' },
217: {'X' , CAPLOK ,'x' ,'X' },
218: {'Y' , CAPLOK ,'y' ,'Y' },
219: {'Z' , CAPLOK ,'z' ,'Z' },
220: {VK_OEM_3 , CAPLOK ,0xf6 ,0xd6 },
221: {VK_OEM_5 , 0 ,WCH_DEAD ,0xb0 },
222: { 0xff , CAPLOK ,'^' ,WCH_NONE },
223: {VK_OEM_6 , 0 ,WCH_DEAD ,WCH_DEAD },
224: { 0xff , CAPLOK ,0xb4 ,0x60 }, // Acute, Grave
225: {VK_OEM_7 , CAPLOK ,0xe4 ,0xc4 },
226: {VK_OEM_8 , 0 ,WCH_NONE ,WCH_NONE },
227: {VK_OEM_COMMA , CAPLOK ,',' ,';' },
228: {VK_OEM_PERIOD, CAPLOK ,'.' ,':' },
229: {VK_TAB , 0 ,'\t' ,'\t' },
230: {VK_ADD , 0 ,'+' ,'+' }, // Jun-03-92
231: {VK_DECIMAL , 0 ,',' ,',' },
232: {VK_DIVIDE , 0 ,'/' ,'/' },
233: {VK_MULTIPLY , 0 ,'*' ,'*' },
234: {VK_SUBTRACT , CAPLOK ,'-' ,'-' },
235: {0 , 0 ,0 ,0 }
236: };
237:
238: static VK_TO_WCHARS3 aVkToWch3[] = {
239: // | | SHIFT | CTRL+ALT |
240: // | |==========|===========|
241: {'0' , CAPLOK ,'0' ,'=' , '}' },
242: {'3' , CAPLOK ,'3' ,0xa7 , 0xb3 },
243: {'7' , CAPLOK ,'7' ,'/' , '{' },
244: {'8' , CAPLOK ,'8' ,'(' , '[' },
245: {'9' , CAPLOK ,'9' ,')' , ']' },
246: {'M' , CAPLOK ,'m' ,'M' , 0xb5 },
247: {'Q' , CAPLOK ,'q' ,'Q' , '@' },
248: {VK_OEM_102 , 0 ,'<' ,'>' , '|' },
249: {VK_OEM_4 , CAPLOK ,0xdf ,'?' , '\\' },
250: {0 , 0 ,0 ,0 , 0 }
251: };
252:
253: static VK_TO_WCHARS4 aVkToWch4[] = {
254: // | | SHIFT | CTRL+ALT | CONTROL |
255: // | |==========|===========|===========|
256: {VK_BACK , 0 ,'\b' ,'\b' , WCH_NONE , 0x7f },
257: {VK_CANCEL , 0 ,0x03 ,0x03 , WCH_NONE , 0x03 },
258: {VK_ESCAPE , 0 ,0x1b ,0x1b , WCH_NONE , 0x1b },
259: {VK_OEM_1 , CAPLOK ,0xfc ,0xdc , WCH_NONE , 0x1b },
260: {VK_OEM_2 , CAPLOK ,'#' ,0x27 , WCH_NONE , 0x1c },
261: {VK_OEM_PLUS , CAPLOK ,'+' ,'*' , '~' , 0x1d },
262: {VK_RETURN , 0 ,'\r' ,'\r' , WCH_NONE , '\n' },
263: {VK_SPACE , 0 ,' ' ,' ' , WCH_NONE , 0x20 },
264: {0 , 0 ,0 ,0 , 0 , 0 }
265: };
266:
267: static VK_TO_WCHARS5 aVkToWch5[] = {
268: // | | SHIFT | CTRL+ALT | CONTROL | SHFT+CTRL |
269: // | |========|===========|===========|===========|
270: {'2' , CAPLOK ,'2' ,'"' , 0xb2 , WCH_NONE , 0x00 },
271: {'6' , CAPLOK ,'6' ,'&' , WCH_NONE , WCH_NONE , 0x1e },
272: {VK_OEM_MINUS , 0 ,'-' ,'_' , WCH_NONE , WCH_NONE , 0x1f },
273: {0 , 0 ,0 ,0 , 0 , 0 , 0 }
274: };
275:
276: static VK_TO_WCHARS1 aVkToWch1[] = {
277: { VK_NUMPAD0 , 0 , '0' },
278: { VK_NUMPAD1 , 0 , '1' },
279: { VK_NUMPAD2 , 0 , '2' },
280: { VK_NUMPAD3 , 0 , '3' },
281: { VK_NUMPAD4 , 0 , '4' },
282: { VK_NUMPAD5 , 0 , '5' },
283: { VK_NUMPAD6 , 0 , '6' },
284: { VK_NUMPAD7 , 0 , '7' },
285: { VK_NUMPAD8 , 0 , '8' },
286: { VK_NUMPAD9 , 0 , '9' },
287: { 0 , 0 , '\0' } //null terminator
288: };
289:
290: /***************************************************************************\
291: * aVkToWcharTable: table of pointers to Character Tables
292: *
293: * Describes the character tables and the order they should be searched.
294: *
295: * Note: the order determines the behavior of VkKeyScan() : this function
296: * takes a character and attempts to find a Virtual Key and character-
297: * modifier key combination that produces that character. The table
298: * containing the numeric keypad (aVkToWch1) must appear last so that
299: * VkKeyScan('0') will be interpreted as one of keys from the main
300: * section, not the numpad. etc.
301: \***************************************************************************/
302:
303: static VK_TO_WCHAR_TABLE aVkToWcharTable[] = {
304: { (PVK_TO_WCHARS1)aVkToWch3, 3, sizeof(aVkToWch3[0]) },
305: { (PVK_TO_WCHARS1)aVkToWch4, 4, sizeof(aVkToWch4[0]) },
306: { (PVK_TO_WCHARS1)aVkToWch5, 5, sizeof(aVkToWch5[0]) },
307: { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) },
308: { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) }, // must come last
309: { NULL, 0, 0 }
310: };
311:
312: /***************************************************************************\
313: * aKeyNames[], aKeyNamesExt[] - Scan Code -> Key Name tables
314: *
315: * For the GetKeyNameText() API function
316: *
317: * Tables for non-extended and extended (KBDEXT) keys.
318: * (Keys producing printable characters are named by the character itself)
319: \***************************************************************************/
320:
321: static VSC_LPWSTR aKeyNames[] = {
322: 0x01, L"ESC",
323: 0x0e, L"R\xDC" L"CK",
324: 0x0f, L"TABULATOR",
325: 0x1c, L"EINGABE",
326: 0x1d, L"STRG",
327: 0x2a, L"UMSCHALT",
328: 0x36, L"UMSCHALT RECHTS",
329: 0x37, L" (ZEHNERTASTATUR)",
330: 0x38, L"ALT",
331: 0x39, L"LEER",
332: 0x3a, L"FESTSTELL",
333: 0x3b, L"F1",
334: 0x3c, L"F2",
335: 0x3d, L"F3",
336: 0x3e, L"F4",
337: 0x3f, L"F5",
338: 0x40, L"F6",
339: 0x41, L"F7",
340: 0x42, L"F8",
341: 0x43, L"F9",
342: 0x44, L"F10",
343: 0x45, L"PAUSE",
344: 0x46, L"ROLLEN-FESTSTELL",
345: 0x47, L"7 (ZEHNERTASTATUR)",
346: 0x48, L"8 (ZEHNERTASTATUR)",
347: 0x49, L"9 (ZEHNERTASTATUR)",
348: 0x4a, L"- (ZEHNERTASTATUR)",
349: 0x4b, L"4 (ZEHNERTASTATUR)",
350: 0x4c, L"5 (ZEHNERTASTATUR)",
351: 0x4d, L"6 (ZEHNERTASTATUR)",
352: 0x4e, L"+ (ZEHNERTASTATUR)",
353: 0x4f, L"1 (ZEHNERTASTATUR)",
354: 0x50, L"2 (ZEHNERTASTATUR)",
355: 0x51, L"3 (ZEHNERTASTATUR)",
356: 0x52, L"0 (ZEHNERTASTATUR)",
357: 0x53, L"KOMMA (ZEHNERTASTATUR)",
358: 0x57, L"F11",
359: 0x58, L"F12",
360: 0 , NULL
361: };
362:
363: static VSC_LPWSTR aKeyNamesExt[] = {
364: 0x1c, L"EINGABE (ZEHNERTASTATUR)",
365: 0x1d, L"STRG-RECHTS",
366: 0x35, L" (ZEHNERTASTATUR)",
367: 0x37, L"DRUCK",
368: 0x38, L"ALT GR",
369: 0x45, L"NUM-FESTSTELL",
370: 0x46, L"UNTBR", // ICO Break
371: 0x47, L"POS1",
372: 0x48, L"NACH-OBEN",
373: 0x49, L"BILD-NACH-OBEN",
374: 0x4b, L"NACH-LINKS",
375: 0x4d, L"NACH-RECHTS",
376: 0x4f, L"ENDE",
377: 0x50, L"NACH-UNTEN",
378: 0x51, L"BILD-NACH-UNTEN",
379: 0x52, L"EINFG",
380: 0x53, L"ENTF",
381: 0x54, L"<00>", // ICO 00
382: 0x56, L"HILFE", // ICO Help
383: 0x5c, L"L\x00D6SCH", // ICO Clear
384: 0 , NULL
385: };
386:
387: static LPWSTR aKeyNamesDead[] = {
388: L"\x00B4" L"AKUT",
389: L"`" L"GRAVIS",
390: L"^" L"ZIRKUMFLEX",
391: NULL
392: };
393:
394: static DEADKEY aDeadKey[] = {
395: DEADTRANS(L'a', L'`', 0x00E0), // GRAVE
396: DEADTRANS(L'e', L'`', 0x00E8),
397: DEADTRANS(L'i', L'`', 0x00EC),
398: DEADTRANS(L'o', L'`', 0x00F2),
399: DEADTRANS(L'u', L'`', 0x00F9),
400: DEADTRANS(L'A', L'`', 0x00C0),
401: DEADTRANS(L'E', L'`', 0x00C8),
402: DEADTRANS(L'I', L'`', 0x00CC),
403: DEADTRANS(L'O', L'`', 0x00D2),
404: DEADTRANS(L'U', L'`', 0x00D9),
405: DEADTRANS(L' ', L'`', L'`' ),
406:
407: DEADTRANS(L'a', 0x00B4, 0x00E1), // ACUTE
408: DEADTRANS(L'e', 0x00B4, 0x00E9),
409: DEADTRANS(L'i', 0x00B4, 0x00ED),
410: DEADTRANS(L'o', 0x00B4, 0x00F3),
411: DEADTRANS(L'u', 0x00B4, 0x00FA),
412: DEADTRANS(L'y', 0x00B4, 0x00FD),
413: DEADTRANS(L'A', 0x00B4, 0x00C1),
414: DEADTRANS(L'E', 0x00B4, 0x00C9),
415: DEADTRANS(L'I', 0x00B4, 0x00CD),
416: DEADTRANS(L'O', 0x00B4, 0x00D3),
417: DEADTRANS(L'U', 0x00B4, 0x00DA),
418: DEADTRANS(L'Y', 0x00B4, 0x00DD),
419: DEADTRANS(L' ', 0x00B4, 0x00B4),
420:
421: DEADTRANS(L'a', L'^', 0x00E2), // CIRCUMFLEX
422: DEADTRANS(L'e', L'^', 0x00EA),
423: DEADTRANS(L'i', L'^', 0x00EE),
424: DEADTRANS(L'o', L'^', 0x00F4),
425: DEADTRANS(L'u', L'^', 0x00FB),
426: DEADTRANS(L'A', L'^', 0x00C2),
427: DEADTRANS(L'E', L'^', 0x00CA),
428: DEADTRANS(L'I', L'^', 0x00CE),
429: DEADTRANS(L'O', L'^', 0x00D4),
430: DEADTRANS(L'U', L'^', 0x00DB),
431: DEADTRANS(L' ', L'^', L'^' ),
432: 0, 0
433: };
434:
435: /***************************************************************************\
436: * Structure describing all tables for the layout, plus some additional flags.
437: *
438: \***************************************************************************/
439:
440: static KBDTABLES KbdTables = {
441: /*
442: * Modifier keys
443: */
444: &CharModifiers,
445:
446: /*
447: * Characters tables
448: */
449: aVkToWcharTable,
450:
451: /*
452: * Diacritics
453: */
454: aDeadKey,
455:
456: /*
457: * Names of Keys
458: */
459: aKeyNames,
460: aKeyNamesExt,
461: aKeyNamesDead,
462:
463: /*
464: * Scan codes to Virtual Keys
465: */
466: ausVK,
467: sizeof(ausVK) / sizeof(ausVK[0]),
468: aE0VscToVk,
469: aE1VscToVk,
470:
471: /*
472: * layout-specific flags
473: */
474: KLLF_ALTGR // Windows must convert AltGr key to Ctrl+Alt
475: };
476:
477: /*
478: * Returns the address of the layout's KbdTables struct
479: * Must be exported.
480: */
481: PKBDTABLES KbdLayerDescriptor(VOID)
482: {
483: return &KbdTables;
484: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.