-
Notifications
You must be signed in to change notification settings - Fork 5
/
kbd.h
2182 lines (2063 loc) · 98.1 KB
/
kbd.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/****************************** Module Header ******************************\
* Module Name: kbd.h
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* Keyboard table values that form the basis for languages and keyboard types.
* The basis is US, kbd type 4 - all others are a variation on this.
* This file is included by all kbd**.h files.
*
* History:
\***************************************************************************/
#ifndef _KBD_
#define _KBD_
#include <winapifamily.h>
#pragma region Desktop Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#if defined(BUILD_WOW6432)
#define KBD_LONG_POINTER __ptr64
#else
#define KBD_LONG_POINTER
#endif
/****************************************************************************\
*
* Keyboard Layers. Used in kdb??.dll and in usersrv.dll
*
\****************************************************************************/
/*
* KE.usFlaggedVk values, also used in the keyboard layer tables.
*/
#define KBDEXT (USHORT)0x0100
#define KBDMULTIVK (USHORT)0x0200
#define KBDSPECIAL (USHORT)0x0400
#define KBDNUMPAD (USHORT)0x0800
#define KBDUNICODE (USHORT)0x1000
#define KBDINJECTEDVK (USHORT)0x2000
#if (NTDDI_VERSION >= NTDDI_WINXP)
#define KBDMAPPEDVK (USHORT)0x4000
#endif
#define KBDBREAK (USHORT)0x8000
/*
* Key message lParam bits
*/
#define EXTENDED_BIT 0x01000000
#define DONTCARE_BIT 0x02000000
#define FAKE_KEYSTROKE 0x02000000
#define ALTNUMPAD_BIT 0x04000000 // copied from windows\inc\wincon.w
/*
* Keyboard Shift State defines. These correspond to the bit mask defined
* by the VkKeyScan() API.
*/
#define KBDBASE 0
#define KBDSHIFT 1
#define KBDCTRL 2
#define KBDALT 4
// three symbols KANA, ROYA, LOYA are for FE
#define KBDKANA 8
#define KBDROYA 0x10
#define KBDLOYA 0x20
#define KBDGRPSELTAP 0x80
/*
* Handy diacritics
*/
#define GRAVE 0x0300
#define ACUTE 0x0301
#define CIRCUMFLEX 0x0302
#define TILDE 0x0303
#define MACRON 0x0304
#define OVERSCORE 0x0305
#define BREVE 0x0306
#define DOT_ABOVE 0x0307
#define UMLAUT 0x0308
#define DIARESIS UMLAUT
#define HOOK_ABOVE 0x0309
#define RING 0x030A
#define DOUBLE_ACUTE 0x030B
#define HACEK 0x030C
#define CEDILLA 0x0327
#define OGONEK 0x0328
#define TONOS 0x0384
#define DIARESIS_TONOS 0x0385
#define wszGRAVE L"\x0300"
#define wszACUTE L"\x0301"
#define wszCIRCUMFLEX L"\x0302"
#define wszTILDE L"\x0303"
#define wszMACRON L"\x0304"
#define wszOVERSCORE L"\x0305"
#define wszBREVE L"\x0306"
#define wszDOT_ABOVE L"\x0307"
#define wszUMLAUT L"\x0308"
#define wszHOOK_ABOVE L"\x0309"
#define wszRING L"\x030A"
#define wszDOUBLE_ACUTE L"\x030B"
#define wszHACEK L"\x030C"
#define wszCEDILLA L"\x0327"
#define wszOGONEK L"\x0328"
#define wszTONOS L"\x0384"
#define wszDIARESIS_TONOS L"\x0385"
#define IDS_FROM_SCANCODE(prefix, base) \
(0xc000 + ((0x ## prefix) >= 0xE0 ? 0x100 : 0) + (0x ## base))
/***************************************************************************\
* MODIFIER KEYS
*
* All keyboards have "Modifier" keys which are used to alter the behaviour of
* some of the other keys. These shifter keys are usually:
* Shift (left and/or right Shift key)
* Ctrl (left and/or right Ctrl key)
* Alt (left and/or right Alt key)
* AltGr (right Alt key only)
*
* NOTE:
* All keyboards use the Shift key.
* All keyboards use a Ctrl key to generate ASCII control characters.
* All keyboards with a number pad use the Alt key and the NumPad to
* generate characters by number.
* Keyboards using AltGr as a Modifier Key usually translate the Virtual
* ScanCode to Virtual Keys VK_CTRL + VK_ALT at input time: the Modifier
* tables should be written to treat Ctrl + Alt as a valid shifter
* key combination in these cases.
*
* By holding down 0 or more of these Modifier keys, a "shift state" is
* obtained : the shift state may affect the translation of Virtual Scancodes
* to Virtual Keys and/or the translation of Virtuals Key to Characters.
*
* EXAMPLES:
*
* Each key on a particular keyboard may be marked with up to five different
* characters in five different positions:
*
* .-------.
* /| |\
* : | 2 4 | :
* | | | |
* | | | |
* | | 1 3 | |
* | |_______| |
* | / \ |
* |/ 5 \|
* `-----------'
*
* A key may also be able to generate a character that is not marked on it:
* these are ASCII Control chars, lower-case letters and/or "invisible keys".
* .-------.
* An example of an "Invisible Key": /| |\
* : | > | :
* The German M24 keyboard 2 should produce the | | | |
* '|' character when ALT SHIFT is is held down | | | |
* while the '<' key (shown here) is pressed: | | < \ | |
* This keyboard has four other invisible | |_______| |
* characters. France, Italy and Spain also | / \ |
* support invisible characters on the M24 |/ \|
* Keyboard 2 with ALT SHIFT depressed. `-----------'
*
* The keyboard table must list the keys that contribute to it's shift state,
* and indicate which combinations are valid. This is done with
* aCharModifiers[] - convert combinations of Modifier Keys to Bitmasks.
* and
* aModification[]; - convert Modifier Bitmasks to enumerated Modifications
*
* AN EXAMPLE OF VALID AND INVALID MODIFIER KEY COMBINATIONS
*
* The US English keyboard has 3 Modifier keys:
* Shift (left or right); Ctrl (left or right); and Alt (left or right).
*
* The only valid combinations of these Modifier Keys are:
* none pressed : Character at position (1) on the key.
* Shift : Character at position (2) on the key.
* Ctrl : Ascii Control characters
* Shift + Ctrl : Ascii Control characters
* Alt : Character-by-number on the numpad
*
* The invalid combinations (that do not generate any characters) are:
* Shift + Alt
* Alt + Ctrl
* Shift + Alt + Ctrl
*
* Something (???) :
* -----------------
* Modifier keys Character produced
* ------------------------- ------------------
* 0 No shifter key depressed position 1
* 1 Shift key is depressed position 2
* 2 AltGr (r.h. Alt) depressed position 4 or 5 (whichever is marked)
*
* However, note that 3 shifter keys (SHIFT, can be combined in a
* characters, depending on the Keyboards
* Consider the following keyboards:
*
* .-------. STRANGE KBD PECULIAR KBD
* /| |\ ================== ==================
* : | 2 4 | : 1 -
* | | | | 2 - SHIFT SHIFT
* | | | | 3 - MENU MENU
* | | 1 3 | | 4 - SHIFT + MENU SHIFT + MENU
* | |_______| | 5 - no such keys CTRL + MENU
* | / \ |
* |/ 5 \|
* `-----------'
* Both STRANGE and PECULIAR keyboards could have aVkToBits[] =
* { VK_SHIFT , KBDSHIFT }, // 0x01
* { VK_CONTROL, KBDCTRL }, // 0x02
* { VK_MENU , KBDALT }, // 0x04
* { 0, 0 }
*
* The STRANGE keyboard has 4 distinct shift states, while the PECULIAR kbd
* has 5. However, note that 3 shifter bits can be combined in a
* total of 2^3 == 8 ways. Each such combination must be related to one (or
* none) of the enumerated shift states.
* Each shifter key combination can be represented by three binary bits:
* Bit 0 is set if VK_SHIFT is down
* Bit 1 is set if VK_CONTROL is down
* Bit 2 is set if VK_MENU is down
*
* Example: If the STRANGE keyboard generates no characters in combination
* when just the ALT key is held down, nor when the SHIFT, CTRL and ALT keys
* are all held down, then the tables might look like this:
*
* VK_MENU,
* VK_CTRL, 0
* };
* aModification[] = {
* 0, // 0 0 0 = 000 <none>
* 1, // 0 0 1 = 001 SHIFT
* SHFT_INVALID, // 0 1 0 = 010 ALT
* 2, // 0 1 1 = 011 SHIFT ALT
* 3, // 1 0 0 = 100 CTRL
* 4, // 1 0 1 = 101 SHIFT CTRL
* 5, // 1 1 0 = 110 CTRL ALT
* SHFT_INVALID // 1 1 1 = 111 SHIFT CTRL ALT
* };
*
*
\***************************************************************************/
/***************************************************************************\
* VK_TO_BIT - associate a Virtual Key with a Modifier bitmask.
*
* Vk - the Virtual key (eg: VK_SHIFT, VK_RMENU, VK_CONTROL etc.)
* Special Values:
* 0 null terminator
* ModBits - a combination of KBDALT, KBDCTRL, KBDSHIFT and kbd-specific bits
* Any kbd-specific shift bits must be the lowest-order bits other
* than KBDSHIFT, KBDCTRL and KBDALT (0, 1 & 2)
*
* Those languages that use AltGr (VK_RMENU) to shift keys convert it to
* CTRL+ALT with the KBDSPECIAL bit in the ausVK[] entry for VK_RMENU
* and by having an entry in aVkToPfnOem[] to simulate the right Vk sequence.
*
\***************************************************************************/
typedef struct {
BYTE Vk;
BYTE ModBits;
} VK_TO_BIT, *KBD_LONG_POINTER PVK_TO_BIT;
/***************************************************************************\
* pModNumber - a table to map shift bits to enumerated shift states
*
* Table attributes: Ordered table
*
* Maps all possible shifter key combinations to an enumerated shift state.
* The size of the table depends on the value of the highest order bit used
* in aCharModifiers[*].ModBits
*
* Special values for aModification[*]
* SHFT_INVALID - no characters produced with this shift state.
LATER: (ianja) no SHFT_CTRL - control characters encoded in tables like others
* SHFT_CTRL - standard control character production (all keyboards must
* be able to produce CTRL-C == 0x0003 etc.)
* Other - enumerated shift state (not less than 0)
*
* This table is indexed by the Modifier Bits to obtain an Modification Number.
*
* CONTROL MENU SHIFT
*
* aModification[] = {
* 0, // 0 0 0 = 000 <none>
* 1, // 0 0 1 = 001 SHIFT
* SHFT_INVALID, // 0 1 0 = 010 ALT
* 2, // 0 1 1 = 011 SHIFT ALT
* 3, // 1 0 0 = 100 CTRL
* 4, // 1 0 1 = 101 SHIFT CTRL
* 5, // 1 1 0 = 110 CTRL ALT
* SHFT_INVALID // 1 1 1 = 111 SHIFT CTRL ALT
* };
*
\***************************************************************************/
#pragma warning(push)
#pragma warning(disable : 4200) // zero-sized array in struct/union
typedef struct {
PVK_TO_BIT pVkToBit; // Virtual Keys -> Mod bits
WORD wMaxModBits; // max Modification bit combination value
BYTE ModNumber[]; // Mod bits -> Modification Number
} MODIFIERS, *KBD_LONG_POINTER PMODIFIERS;
#pragma warning(pop)
#define SHFT_INVALID 0x0F
/***************************************************************************\
* VSC_VK - Associate a Virtual Scancode with a Virtual Key
* Vsc - Virtual Scancode
* Vk - Virtual Key | flags
* Used by VKFromVSC() for scancodes prefixed 0xE0 or 0xE1
\***************************************************************************/
typedef struct _VSC_VK {
BYTE Vsc;
USHORT Vk;
} VSC_VK, *KBD_LONG_POINTER PVSC_VK;
/***************************************************************************\
* VK_VSC - Associate a Virtual Key with a Virtual Scancode
* Vk - Virtual Key
* Vsc - Virtual Scancode
* Used by MapVirtualKey for Virtual Keys not appearing in ausVK[]
\***************************************************************************/
typedef struct _VK_VSC {
BYTE Vk;
BYTE Vsc;
} VK_VSC, *KBD_LONG_POINTER PVK_VSC;
/***************************************************************************\
*
* VK_TO_WCHARS<n> - Associate a Virtual Key with <n> UNICODE characters
*
* VirtualKey - The Virtual Key.
* wch[] - An array of characters, one for each shift state that
* applies to the specified Virtual Key.
*
* Special values for VirtualKey:
* -1 - This entry contains dead chars for the previous entry
* 0 - Terminates a VK_TO_WCHARS[] table
*
* Special values for Attributes:
* CAPLOK - The CAPS-LOCK key affects this key like SHIFT
* SGCAPS - CapsLock uppercases the unshifted char (Swiss-German)
*
* Special values for wch[*]:
* WCH_NONE - No character is generated by pressing this key with the
* current shift state.
* WCH_DEAD - The character is a dead-key: the next VK_TO_WCHARS[] entry
* will contain the values of the dead characters (diaresis)
* that can be produced by the Virtual Key.
* WCH_LGTR - The character is a ligature. The characters generated by
* this keystroke are found in the ligature table.
*
\***************************************************************************/
#define WCH_NONE 0xF000
#define WCH_DEAD 0xF001
#define WCH_LGTR 0xF002
#define CAPLOK 0x01
#define SGCAPS 0x02
#define CAPLOKALTGR 0x04
// KANALOK is for FE
#define KANALOK 0x08
#define GRPSELTAP 0x80
/*
* Macro for VK to WCHAR with "n" shift states
*/
#define TYPEDEF_VK_TO_WCHARS(n) typedef struct _VK_TO_WCHARS##n { \
BYTE VirtualKey; \
BYTE Attributes; \
WCHAR wch[n]; \
} VK_TO_WCHARS##n, *KBD_LONG_POINTER PVK_TO_WCHARS##n;
/*
* To facilitate coding the table scanning routine.
*/
/*
* Table element types (for various numbers of shift states), used
* to facilitate static initializations of tables.
* VK_TO_WCHARS1 and PVK_TO_WCHARS1 may be used as the generic type
*/
TYPEDEF_VK_TO_WCHARS(1) // VK_TO_WCHARS1, *PVK_TO_WCHARS1;
TYPEDEF_VK_TO_WCHARS(2) // VK_TO_WCHARS2, *PVK_TO_WCHARS2;
TYPEDEF_VK_TO_WCHARS(3) // VK_TO_WCHARS3, *PVK_TO_WCHARS3;
TYPEDEF_VK_TO_WCHARS(4) // VK_TO_WCHARS4, *PVK_TO_WCHARS4;
TYPEDEF_VK_TO_WCHARS(5) // VK_TO_WCHARS5, *PVK_TO_WCHARS5;
TYPEDEF_VK_TO_WCHARS(6) // VK_TO_WCHARS6, *PVK_TO_WCHARS5;
TYPEDEF_VK_TO_WCHARS(7) // VK_TO_WCHARS7, *PVK_TO_WCHARS7;
// these three (8,9,10) are for FE
TYPEDEF_VK_TO_WCHARS(8) // VK_TO_WCHARS8, *PVK_TO_WCHARS8;
TYPEDEF_VK_TO_WCHARS(9) // VK_TO_WCHARS9, *PVK_TO_WCHARS9;
TYPEDEF_VK_TO_WCHARS(10) // VK_TO_WCHARS10, *PVK_TO_WCHARS10;
/***************************************************************************\
*
* VK_TO_WCHAR_TABLE - Describe a table of VK_TO_WCHARS1
*
* pVkToWchars - points to the table.
* nModifications - the number of shift-states supported by this table.
* (this is the number of elements in pVkToWchars[*].wch[])
*
* A keyboard may have several such tables: all keys with the same number of
* shift-states are grouped together in one table.
*
* Special values for pVktoWchars:
* NULL - Terminates a VK_TO_WCHAR_TABLE[] list.
*
\***************************************************************************/
typedef struct _VK_TO_WCHAR_TABLE {
PVK_TO_WCHARS1 pVkToWchars;
BYTE nModifications;
BYTE cbSize;
} VK_TO_WCHAR_TABLE, *KBD_LONG_POINTER PVK_TO_WCHAR_TABLE;
/***************************************************************************\
*
* Dead Key (diaresis) tables
*
\***************************************************************************/
typedef struct {
DWORD dwBoth; // diacritic & char
WCHAR wchComposed;
USHORT uFlags;
} DEADKEY, *KBD_LONG_POINTER PDEADKEY;
#define DEADTRANS(ch, accent, comp, flags) { MAKELONG(ch, accent), comp, flags}
/*
* Bit values for uFlags
*/
#define DKF_DEAD 0x0001
/***************************************************************************\
*
* Ligature table
*
\***************************************************************************/
/*
* Macro for ligature with "n" characters
*/
#define TYPEDEF_LIGATURE(n) typedef struct _LIGATURE##n { \
BYTE VirtualKey; \
WORD ModificationNumber; \
WCHAR wch[n]; \
} LIGATURE##n, *KBD_LONG_POINTER PLIGATURE##n;
/*
* To facilitate coding the table scanning routine.
*/
/*
* Table element types (for various numbers of ligatures), used
* to facilitate static initializations of tables.
*
* LIGATURE1 and PLIGATURE1 are used as the generic type
*/
TYPEDEF_LIGATURE(1) // LIGATURE1, *PLIGATURE1;
TYPEDEF_LIGATURE(2) // LIGATURE2, *PLIGATURE2;
TYPEDEF_LIGATURE(3) // LIGATURE3, *PLIGATURE3;
TYPEDEF_LIGATURE(4) // LIGATURE4, *PLIGATURE4;
TYPEDEF_LIGATURE(5) // LIGATURE5, *PLIGATURE5;
/***************************************************************************\
* VSC_LPWSTR - associate a Virtual Scancode with a Text string
*
* Uses:
* GetKeyNameText(), aKeyNames[] Map virtual scancode to name of key
*
\***************************************************************************/
typedef struct {
BYTE vsc;
WCHAR *KBD_LONG_POINTER pwsz;
} VSC_LPWSTR, *KBD_LONG_POINTER PVSC_LPWSTR;
typedef WCHAR *KBD_LONG_POINTER DEADKEY_LPWSTR;
/*
* Along with ligature support we're adding a proper version number.
* The previous version number (actually just unused bits...) was
* always zero. The version number will live in the high word of
* fLocaleFlags.
*/
#define KBD_VERSION 1
#define GET_KBD_VERSION(p) (HIWORD((p)->fLocaleFlags))
/*
* Attributes such as AltGr, LRM_RLM, ShiftLock are stored in the the low word
* of fLocaleFlags (layout specific) or in gdwKeyboardAttributes (all layouts)
*/
#define KLLF_ALTGR 0x0001
#define KLLF_SHIFTLOCK 0x0002
#define KLLF_LRM_RLM 0x0004
/*
* Some attributes are per-layout (specific to an individual layout), some
* attributes are per-user (apply globally to all layouts). Some are both.
*/
#define KLLF_LAYOUT_ATTRS (KLLF_SHIFTLOCK | KLLF_ALTGR | KLLF_LRM_RLM)
#define KLLF_GLOBAL_ATTRS (KLLF_SHIFTLOCK)
/*
* Flags passed in to the KeyboardLayout API (KLF_*) as can be converted to
* internal (KLLF_*) attributes:
*/
#define KLL_ATTR_FROM_KLF(x) ((x) >> 15)
#define KLL_LAYOUT_ATTR_FROM_KLF(x) (KLL_ATTR_FROM_KLF(x) & KLLF_LAYOUT_ATTRS)
#define KLL_GLOBAL_ATTR_FROM_KLF(x) (KLL_ATTR_FROM_KLF(x) & KLLF_GLOBAL_ATTRS)
/*
* If KLF_SHIFTLOCK & KLF_LRM_RLM are defined, we can check the KLLF_* values
*/
#ifdef KLF_SHIFTLOCK
#if KLLF_SHIFTLOCK != KLL_ATTR_FROM_KLF(KLF_SHIFTLOCK)
#error KLLF_SHIFTLOCK != KLL_ATTR_FROM_KLF(KLF_SHIFTLOCK)
#endif
#endif // KLF_SHIFTLOCK
#ifdef KLF_LRM_RLM
#if KLLF_LRM_RLM != KLL_ATTR_FROM_KLF(KLF_LRM_RLM)
#error KLLF_LRM_RLM != KLL_ATTR_FROM_KLF(KLF_LRM_RLM)
#endif
#endif // KLF_LRM_RLM
/***************************************************************************\
* KBDTABLES
*
* This structure describes all the tables that implement the keyboard layer.
*
* When switching to a new layer, we get a new KBDTABLES structure: all key
* processing tables are accessed indirectly through this structure.
*
\***************************************************************************/
typedef struct tagKbdLayer {
/*
* Modifier keys
*/
PMODIFIERS pCharModifiers;
/*
* Characters
*/
PVK_TO_WCHAR_TABLE pVkToWcharTable; // ptr to tbl of ptrs to tbl
/*
* Diacritics
*/
PDEADKEY pDeadKey;
/*
* Names of Keys
*/
PVSC_LPWSTR pKeyNames;
PVSC_LPWSTR pKeyNamesExt;
WCHAR *KBD_LONG_POINTER *KBD_LONG_POINTER pKeyNamesDead;
/*
* Scan codes to Virtual Keys
*/
USHORT *KBD_LONG_POINTER pusVSCtoVK;
BYTE bMaxVSCtoVK;
PVSC_VK pVSCtoVK_E0; // Scancode has E0 prefix
PVSC_VK pVSCtoVK_E1; // Scancode has E1 prefix
/*
* Locale-specific special processing
*/
DWORD fLocaleFlags;
/*
* Ligatures
*/
BYTE nLgMax;
BYTE cbLgEntry;
PLIGATURE1 pLigature;
#if (NTDDI_VERSION >= NTDDI_WINXP)
/*
* Type and subtype. These are optional.
*/
DWORD dwType; // Keyboard Type
DWORD dwSubType; // Keyboard SubType: may contain OemId
#endif
} KBDTABLES, *KBD_LONG_POINTER PKBDTABLES;
/*
* FarEast-specific special...
*/
typedef struct _VK_FUNCTION_PARAM {
BYTE NLSFEProcIndex;
ULONG NLSFEProcParam;
} VK_FPARAM, *KBD_LONG_POINTER PVK_FPARAM;
typedef struct _VK_TO_FUNCTION_TABLE {
BYTE Vk;
BYTE NLSFEProcType;
BYTE NLSFEProcCurrent;
// Index[0] : Base
// Index[1] : Shift
// Index[2] : Control
// Index[3] : Shift+Control
// Index[4] : Alt
// Index[5] : Shift+Alt
// Index[6] : Control+Alt
// Index[7] : Shift+Control+Alt
BYTE NLSFEProcSwitch; // 8 bits
VK_FPARAM NLSFEProc[8];
VK_FPARAM NLSFEProcAlt[8];
} VK_F, *KBD_LONG_POINTER PVK_F;
typedef struct tagKbdNlsLayer {
USHORT OEMIdentifier;
USHORT LayoutInformation;
UINT NumOfVkToF;
PVK_F pVkToF;
//
// The pusMouseVKey array provides a translation from the virtual key
// value to an index. The index is used to select the appropriate
// routine to process the virtual key, as well as to select extra
// information that is used by this routine during its processing.
// If this value is NULL, following default will be used.
//
// ausMouseVKey[] = {
// VK_CLEAR, // Numpad 5: Click active button
// VK_PRIOR, // Numpad 9: Up & Right
// VK_NEXT, // Numpad 3: Down & Right
// VK_END, // Numpad 1: Down & Left
// VK_HOME, // Numpad 7: Up & Left
// VK_LEFT, // Numpad 4: Left
// VK_UP, // Numpad 8: Up
// VK_RIGHT, // Numpad 6: Right
// VK_DOWN, // Numpad 2: Down
// VK_INSERT, // Numpad 0: Active button down
// VK_DELETE, // Numpad .: Active button up
// VK_MULTIPLY, // Numpad *: Select both buttons
// VK_ADD, // Numpad +: Double click active button
// VK_SUBTRACT, // Numpad -: Select right button
// VK_DEVIDE|KBDEXT, // Numpad /: Select left button
// VK_NUMLOCK|KBDEXT}; // Num Lock
//
INT NumOfMouseVKey;
USHORT *KBD_LONG_POINTER pusMouseVKey;
} KBDNLSTABLES, *KBD_LONG_POINTER PKBDNLSTABLES;
#if (NTDDI_VERSION >= NTDDI_WINXP)
/*
* The maximum number of layout tables in a DLL
*/
#define KBDTABLE_MULTI_MAX (8)
/*
* Multiple keyboard layout table in a DLL
*/
typedef struct tagKBDTABLE_DESC {
WCHAR wszDllName[32];
DWORD dwType; // Keyboard type ID
DWORD dwSubType; // Combined SubType ID (OEMID : SubType)
} KBDTABLE_DESC, *KBD_LONG_POINTER PKBDTABLE_DESC;
typedef struct tagKBDTABLE_MULTI {
UINT nTables;
KBDTABLE_DESC aKbdTables[KBDTABLE_MULTI_MAX];
} KBDTABLE_MULTI, *KBD_LONG_POINTER PKBDTABLE_MULTI;
/*
* Format of the registry value for the Dynamic Layout Switching
*/
typedef struct tagKBD_TYPE_INFO {
DWORD dwVersion;
DWORD dwType;
DWORD dwSubType;
} KBD_TYPE_INFO, *PKBD_TYPE_INFO;
//
// Keyboard type
//
#define KEYBOARD_TYPE_GENERIC_101 (4)
//
// Keyboard Type = 7 : Japanese Keyboard
// Keyboard Type = 8 : Korean Keyboard
//
#define KEYBOARD_TYPE_JAPAN (7)
#define KEYBOARD_TYPE_KOREA (8)
// Unknown keyboard type
#define KEYBOARD_TYPE_UNKNOWN (0x51)
#endif
//
// OEM Ids - KBDNLSTABLES.OEMIdentifier
//
// PSS ID Number: Q130054
// Article last modified on 05-16-1995
//
// 3.10 1.20 | 3.50 1.20
// WINDOWS | WINDOWS NT
//
// ---------------------------------------------------------------------
// The information in this article applies to:
// - Microsoft Windows Software Development Kit (SDK) for Windows
// version 3.1
// - Microsoft Win32 Software Development Kit (SDK) version 3.5
// - Microsoft Win32s version 1.2
// ---------------------------------------------------------------------
// SUMMARY
// =======
// Because of the variety of computer manufacturers (NEC, Fujitsu, IBMJ, and
// so on) in Japan, sometimes Windows-based applications need to know which
// OEM (original equipment manufacturer) manufactured the computer that is
// running the application. This article explains how.
//
// MORE INFORMATION
// ================
// There is no documented way to detect the manufacturer of the computer that
// is currently running an application. However, a Windows-based application
// can detect the type of OEM Windows by using the return value of the
// GetKeyboardType() function.
//
// If an application uses the GetKeyboardType API, it can get OEM ID by
// specifying "1" (keyboard subtype) as argument of the function. Each OEM ID
// is listed here:
//
// OEM Windows OEM ID
// ------------------------------
// Microsoft 00H (DOS/V)
// all AX 01H
// EPSON 04H
// Fujitsu 05H
// IBMJ 07H
// Matsushita 0AH
// NEC 0DH
// Toshiba 12H
//
// Application programs can use these OEM IDs to distinguish the type of OEM
// Windows. Note, however, that this method is not documented, so Microsoft
// may not support it in the future version of Windows.
//
// As a rule, application developers should write hardware-independent code,
// especially when making Windows-based applications. If they need to make a
// hardware-dependent application, they must prepare the separated program
// file for each different hardware architecture.
//
// Additional reference words: 3.10 1.20 3.50 1.20 kbinf
// KBCategory: kbhw
// KBSubcategory: wintldev
// =============================================================================
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#define NLSKBD_OEM_MICROSOFT 0x00
#define NLSKBD_OEM_AX 0x01
#define NLSKBD_OEM_EPSON 0x04
#define NLSKBD_OEM_FUJITSU 0x05
#define NLSKBD_OEM_IBM 0x07
#define NLSKBD_OEM_MATSUSHITA 0x0A
#define NLSKBD_OEM_NEC 0x0D
#define NLSKBD_OEM_TOSHIBA 0x12
#define NLSKBD_OEM_DEC 0x18 // only NT
//
// Microsoft (default) - keyboards hardware/layout
//
#define MICROSOFT_KBD_101_TYPE 0
#define MICROSOFT_KBD_AX_TYPE 1
#define MICROSOFT_KBD_106_TYPE 2
#define MICROSOFT_KBD_002_TYPE 3
#define MICROSOFT_KBD_001_TYPE 4
#define MICROSOFT_KBD_FUNC 12
//
// AX consortium - keyboards hardware/layout
//
#define AX_KBD_DESKTOP_TYPE 1
//
// Fujitsu - keyboards hardware/layout
//
#define FMR_KBD_JIS_TYPE 0
#define FMR_KBD_OASYS_TYPE 1
#define FMV_KBD_OASYS_TYPE 2
//
// NEC - keyboards hardware/layout
//
#define NEC_KBD_NORMAL_TYPE 1
#define NEC_KBD_N_MODE_TYPE 2
#define NEC_KBD_H_MODE_TYPE 3
#define NEC_KBD_LAPTOP_TYPE 4
#define NEC_KBD_106_TYPE 5
//
// Toshiba - keyboards hardware/layout
//
#define TOSHIBA_KBD_DESKTOP_TYPE 13
#define TOSHIBA_KBD_LAPTOP_TYPE 15
//
// DEC - keyboards hardware/layout
//
#define DEC_KBD_ANSI_LAYOUT_TYPE 1 // only NT
#define DEC_KBD_JIS_LAYOUT_TYPE 2 // only NT
#if (NTDDI_VERSION >= NTDDI_WINXP)
//
// Korean keyboard subtype
//
#define MICROSOFT_KBD_101A_TYPE MICROSOFT_KBD_101_TYPE
#define MICROSOFT_KBD_101B_TYPE 4
#define MICROSOFT_KBD_101C_TYPE 5
#define MICROSOFT_KBD_103_TYPE 6
#endif
//
// Keyboard layout information - KBDNLSTABLE.LayoutInformation
//
//
// If this flag is on, System sends notification to keyboard
// drivers (leyout/kernel mode). when IME (Input-Mehod-Editor)
// status become changed.
//
#define NLSKBD_INFO_SEND_IME_NOTIFICATION 0x0001
//
// If this flag is on, System will use VK_HOME/VK_KANA instead of
// VK_NUMLOCK/VK_SCROLL for Accessibility toggle keys.
// + Typically, NEC PC-9800 Series will use this bit, because
// they does not have 'NumLock' and 'ScrollLock' keys.
//
#define NLSKBD_INFO_ACCESSIBILITY_KEYMAP 0x0002
//
// If this flag is on, System will return 101 or 106 Japanese
// keyboard type/subtype id, when GetKeyboardType() is called.
//
#define NLSKBD_INFO_EMURATE_101_KEYBOARD 0x0010
#define NLSKBD_INFO_EMURATE_106_KEYBOARD 0x0020
//
// Keyboard layout function types
//
// - VK_F.NLSFEProcType
//
#define KBDNLS_TYPE_NULL 0
#define KBDNLS_TYPE_NORMAL 1
#define KBDNLS_TYPE_TOGGLE 2
//
// - VK_F.NLSFEProcCurrent
//
#define KBDNLS_INDEX_NORMAL 1
#define KBDNLS_INDEX_ALT 2
//
// - VK_F.NLSFEProc[]
//
#define KBDNLS_NULL 0 // Invalid function
#define KBDNLS_NOEVENT 1 // Drop keyevent
#define KBDNLS_SEND_BASE_VK 2 // Send Base VK_xxx
#define KBDNLS_SEND_PARAM_VK 3 // Send Parameter VK_xxx
#define KBDNLS_KANALOCK 4 // VK_KANA (with hardware lock)
#define KBDNLS_ALPHANUM 5 // VK_DBE_ALPHANUMERIC
#define KBDNLS_HIRAGANA 6 // VK_DBE_HIRAGANA
#define KBDNLS_KATAKANA 7 // VK_DBE_KATAKANA
#define KBDNLS_SBCSDBCS 8 // VK_DBE_SBCSCHAR/VK_DBE_DBCSCHAR
#define KBDNLS_ROMAN 9 // VK_DBE_ROMAN/VK_DBE_NOROMAN
#define KBDNLS_CODEINPUT 10 // VK_DBE_CODEINPUT/VK_DBE_NOCODEINPUT
#define KBDNLS_HELP_OR_END 11 // VK_HELP or VK_END [NEC PC-9800 Only]
#define KBDNLS_HOME_OR_CLEAR 12 // VK_HOME or VK_CLEAR [NEC PC-9800 Only]
#define KBDNLS_NUMPAD 13 // VK_NUMPAD? for Numpad key [NEC PC-9800 Only]
#define KBDNLS_KANAEVENT 14 // VK_KANA [Fujitsu FMV oyayubi Only]
#define KBDNLS_CONV_OR_NONCONV 15 // VK_CONVERT and VK_NONCONVERT [Fujitsu FMV oyayubi Only]
#if (NTDDI_VERSION < NTDDI_WINXP)
//
// Keyboard Type = 7 : Japanese Keyboard
// Keyboard Type = 8 : Korean Keyboard
//
#define JAPANESE_KEYBOARD(Id) ((Id).Type == 7)
#define KOREAN_KEYBOARD(Id) ((Id).Type == 8)
#else
#define JAPANESE_KEYBOARD(Id) ((Id).Type == KEYBOARD_TYPE_JAPAN)
#define KOREAN_KEYBOARD(Id) ((Id).Type == KEYBOARD_TYPE_KOREA)
#endif
// Fujitsu Oyayubi-shift keyboard
#define FUJITSU_KBD_CONSOLE(Id) (JAPANESE_KEYBOARD(Id) && \
(Id).Subtype == ((NLSKBD_OEM_FUJITSU<<4)|FMV_KBD_OASYS_TYPE))
// This number 0x00020002 is registered in registry key as
// HKLM\System\CurrentControlSet\Control\Terminal Server\KeyboardType Mapping\JPN
#define FUJITSU_KBD_REMOTE(Id) (JAPANESE_KEYBOARD(Id) && \
(Id).SubType == 0x00020002)
#define KBD_LAYOUT_LANG(hkl) (PRIMARYLANGID(HandleToUlong(hkl)))
#define JAPANESE_KBD_LAYOUT(hkl) (KBD_LAYOUT_LANG(hkl) == LANG_JAPANESE)
#define KOREAN_KBD_LAYOUT(hkl) (KBD_LAYOUT_LANG(hkl) == LANG_KOREAN)
// end of FE specific
/***************************************************************************\
* Macros for ausVK[] values (used below)
*
* These macros prefix each argument with VK_ to produce the name of a Virtual
* Key defined in "winuser.h" (eg: ESCAPE becomes VK_ESCAPE).
\***************************************************************************/
#ifndef KBD_TYPE
#define KBD_TYPE 4
#endif
/*
* _NE() selects the Virtual Key according to keyboard type
*/
#if (KBD_TYPE == 1)
#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v1)
#elif (KBD_TYPE == 2)
#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v2)
#elif (KBD_TYPE == 3)
#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v3)
#elif (KBD_TYPE == 4)
#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v4)
#elif (KBD_TYPE == 5)
#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v5)
#elif (KBD_TYPE == 6)
#define _NE(v1,v2,v3,v4,v5,v6) (VK_##v6)
#elif (KBD_TYPE == 7)
#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v7)
#elif (KBD_TYPE == 8)
#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v8)
#elif (KBD_TYPE == 10)
#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v10)
#elif (KBD_TYPE == 11)
#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v11)
#elif (KBD_TYPE == 12)
#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v12)
#elif (KBD_TYPE == 13)
#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v13)
#elif (KBD_TYPE == 16)
#define _NE(v7,v8,v16,v10,v11,v12,v13) (VK_##v16)
#elif (KBD_TYPE == 20)
#define _NE(v20,v21,v22) (VK_##v20)
#elif (KBD_TYPE == 21)
#define _NE(v20,v21,v22) (VK_##v21)
#elif (KBD_TYPE == 22)
#define _NE(v20,v21,v22) (VK_##v22)
#elif (KBD_TYPE == 30)
#define _NE(v30,v33,v34) (VK_##v30)
#elif (KBD_TYPE == 33)
#define _NE(v30,v33,v34) (VK_##v33)
#elif (KBD_TYPE == 34)
#define _NE(v30,v33,v34) (VK_##v34)
#elif (KBD_TYPE == 40)
#define _NE(v40,v41) (VK_##v40)
#elif (KBD_TYPE == 41)
#define _NE(v40,v41) (VK_##v41)
#endif
/*
* _EQ() selects the same Virtual Key for all keyboard types
*/
#if (KBD_TYPE <= 6)
#define _EQ( v4 ) (VK_##v4)
#elif (KBD_TYPE >= 7) && (KBD_TYPE <= 16)
#define _EQ( v8 ) (VK_##v8)
#elif (KBD_TYPE > 20) && (KBD_TYPE <= 22)
#define _EQ(v20 ) (VK_##v20)
#elif (KBD_TYPE >= 30) && (KBD_TYPE <= 34)
#define _EQ( v30 ) (VK_##v30)
#elif (KBD_TYPE == 37)
#define _EQ( v37 ) (VK_##v37)
#elif (KBD_TYPE >= 40) && (KBD_TYPE <= 41)
#define _EQ( v40 ) (VK_##v40)
#endif
/*
* A bit of trickery for virtual key names 'A' to 'Z' and '0' to '9' so
* that they are not converted to a VK_* name.
* With this macro, VK_'A' equates to 'A' etc.
*/
#define VK_
#define VK__none_ 0xFF
#define VK_ABNT_C1 0xC1
#define VK_ABNT_C2 0xC2
#if (KBD_TYPE <= 6)
/***************************************************************************\