2 * PROJECT: ReactOS Build Tools [Keyboard Layout Compiler]
3 * LICENSE: BSD - See COPYING.BSD in the top level directory
4 * FILE: tools/kbdtool/output.c
5 * PURPOSE: Output Logic (Source Builder)
6 * PROGRAMMERS: ReactOS Foundation
9 /* INCLUDES *******************************************************************/
13 /* GLOBALS ********************************************************************/
15 ULONG gStringIdForDescriptions
= 1000;
16 ULONG gStringIdForLanguageNames
= 1100;
17 ULONG gStringIdForLocaleName
= 1200;
22 /* FUNCTIONS ******************************************************************/
25 WChName(IN ULONG Char
,
30 /* Check for invalid character */
34 strcpy(gCharName
, "WCH_NONE");
36 else if ((Char
> 31) && (Char
< 128))
38 /* Use our global buffer */
41 /* Add the first quote unless this was a zero-string */
42 if (!AddZero
) *p
++ = '\'';
44 /* Now replace any other quote or comment character with a slash */
45 if ((Char
== '\"') || (Char
== '\'') || (Char
== '\\')) *p
++ = '\\';
47 /* Now plug in the character */
50 /* And add the terminating quote, unless this was a zero-string */
51 if (!AddZero
) *p
++ = '\'';
53 /* Terminate the buffer */
58 /* Handle special cases */
62 strcpy(gCharName
, "'\\b'");
64 else if (Char
== '\n')
67 strcpy(gCharName
, "'\\n'");
69 else if (Char
== '\r')
72 strcpy(gCharName
, "'\\r'");
76 /* Char value, in hex */
77 sprintf(gCharName
, "0x%04x", Char
);
81 /* Char value, C-style */
82 sprintf(gCharName
, "\\x%04x", Char
);
91 PrintNameTable(FILE* FileHandle
,
100 /* Loop all key names */
103 /* Go to the next key name */
104 NextName
= KeyName
->Next
;
106 /* Remember the name and our buffer address */
107 Name
= KeyName
->Name
;
110 /* Check if it's an IDS name */
111 if (strncmp(Name
, "IDS_", 4))
113 /* No, so start parsing it. First, handle initial quote */
114 if (*Name
!= '\"') *Buffer
++ = '\"';
116 /* Next, parse the name */
119 /* Check if this is a C-style hex string */
120 if ((*Name
!= '\\') || ((*(Name
+ 1) != 'x') && (*(Name
+ 1) != 'X')))
122 /* It's not, so just copy straight into our buffer */
127 /* Continue scanning as long as this is a C-style hex string */
128 while ((*Name
== '\\') && ((*(Name
+ 1) == 'x') || (*(Name
+ 1) == 'X')))
130 /* Copy 6 characters */
131 for (i
= 0; (*Name
) && (i
< 6); i
++) *Buffer
++ = *Name
++;
134 /* Check if we still have something at the end */
137 /* Terminate our buffer */
146 /* Check for terminating quote */
147 if (*(Buffer
- 1) != '\"') *Buffer
++ = '\"';
149 /* Terminate the buffer */
154 /* Not yet supported */
155 printf("IDS Entries not yet handled!\n");
159 /* Is this a dead key? */
162 /* Not yet handled */
163 printf("Dead keys not yet handled\n");
168 /* Print the entry */
169 fprintf(FileHandle
, " 0x%02x, L%s,\n", KeyName
->Code
, CharBuffer
);
172 /* Cleanup allocation */
180 /* Is this a dead key? */
183 /* Not yet handled */
184 printf("Dead keys not yet handled\n");
189 /* Terminate the table */
190 fprintf(FileHandle
, " 0 , NULL\n");
195 kbd_h(IN PLAYOUT Layout
)
203 /* Build the keyboard name */
204 strcpy(OutputFile
, gKBDName
);
205 strcat(OutputFile
, ".H");
208 FileHandle
= fopen(OutputFile
, "wt");
212 printf(" %12s : can't open for write.\n", OutputFile
);
216 /* Print the module header */
218 "/****************************** Module Header ******************************\\\n"
219 "* Module Name: %s\n*\n* keyboard layout header\n"
221 "* Copyright (c) 2009, ReactOS Foundation\n"
223 "* Various defines for use by keyboard input code.\n*\n* History:\n"
225 "* created by KBDTOOL v%d.%02d %s*\n"
226 "\\***************************************************************************/\n\n",
232 /* Print out the includes and defines */
235 " * kbd type should be controlled by cl command-line argument\n"
237 "#define KBD_TYPE 4\n\n"
239 "* Include the basis of all keyboard table values\n"
241 "#include \"kbd.h\"\n");
243 /* Now print out the virtual key conversion table */
245 "/***************************************************************************\\\n"
246 "* The table below defines the virtual keys for various keyboard types where\n"
247 "* the keyboard differ from the US keyboard.\n"
249 "* _EQ() : all keyboard types have the same virtual key for this scancode\n"
250 "* _NE() : different virtual keys for this scancode, depending on kbd type\n"
252 "* +------+ +----------+----------+----------+----------+----------+----------+\n"
253 "* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd |\n"
254 "* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 |\n"
255 "\\****+-------+_+----------+----------+----------+----------+----------+----------+*/\n\n");
258 for (i
= 0; i
< 110; i
++)
260 /* Check if we processed this key */
261 if (Layout
->Entry
[i
].Processed
)
263 /* Check if it redefined a virtual key */
264 if (Layout
->Entry
[i
].VirtualKey
!= Layout
->Entry
[i
].OriginalVirtualKey
)
266 /* Do we have a subcode? */
267 SubCode
= Layout
->Entry
[i
].ScanCode
& 0xFF00;
270 /* Which kind is it? */
271 if (SubCode
== 0xE000)
279 if (SubCode
!= 0xE100)
282 printf("Weird scancode value %04x: expected xx, E0xx, or E1xx\n", SubCode
);
296 /* Print out the virtual key redefinition */
298 "#undef %c%02X\n#define %c%02X _EQ(%43s%23s\n",
300 Layout
->Entry
[i
].ScanCode
,
302 Layout
->Entry
[i
].ScanCode
,
303 getVKName(Layout
->Entry
[i
].VirtualKey
, 0),
309 /* Cleanup and close */
310 fprintf(FileHandle
,"\n");
318 kbd_rc(IN PKEYNAME DescriptionData
,
319 IN PKEYNAME LanguageData
)
322 CHAR InternalName
[13];
327 PKEYNAME NextDescription
, NextLanguage
;
329 /* Build the keyboard name and internal name */
330 strcpy(OutputFile
, gKBDName
);
331 strcat(OutputFile
, ".RC");
332 strcpy(InternalName
, gKBDName
);
333 for (p
= InternalName
; *p
; p
++) *p
= tolower(*p
);
336 FileHandle
= fopen(OutputFile
, "wb");
340 printf(" %12s : can't open for write.\n", OutputFile
);
344 /* Check if we have copyright */
345 Length
= strlen(gCopyright
);
348 /* Set time string */
349 strftime(TimeBuffer
, 5, "%Y", Now
);
351 /* Add copyright character */
352 strcpy(gCopyright
, "(C)");
355 strcat(gCopyright
, TimeBuffer
);
357 /* Add blank company */
358 strcat(gCopyright
, " ");
361 /* Write the resource file header */
363 "#include \"winver.h\"\r\n"
365 " FILEVERSION 1,0,%d,%d\r\n"
366 " PRODUCTVERSION 1,0,%d,%d\r\n"
367 " FILEFLAGSMASK 0x3fL\r\n"
368 " FILEFLAGS 0x0L\r\n"
369 "FILEOS 0x40004L\r\n"
370 " FILETYPE VFT_DLL\r\n"
371 " FILESUBTYPE VFT2_DRV_KEYBOARD\r\n"
373 " BLOCK \"StringFileInfo\"\r\n"
375 " BLOCK \"000004B0\"\r\n"
377 " VALUE \"CompanyName\", \"%s\\0\"\r\n"
378 " VALUE \"FileDescription\", \"%s Keyboard Layout\\0\"\r\n"
379 " VALUE \"FileVersion\", \"1, 0, %d, %d\\0\"\r\n",
389 /* Continue writing it */
391 " VALUE \"InternalName\", \"%s (%d.%d)\\0\"\r\n"
392 " VALUE \"ProductName\",\"%s\\0\"\r\n"
393 " VALUE \"Release Information\",\"%s\\0\"\r\n"
394 " VALUE \"LegalCopyright\", \"%s\\0\"\r\n"
395 " VALUE \"OriginalFilename\",\"%s\\0\"\r\n"
396 " VALUE \"ProductVersion\", \"1, 0, %d, %d\\0\"\r\n"
399 " BLOCK \"VarFileInfo\"\r\n"
401 " VALUE \"Translation\", 0x0000, 0x04B0\r\n"
407 "Created by ReactOS KbdTool",
408 "Created by ReactOS KbdTool",
414 /* Now check if we have a locale name */
415 Length
= strlen(gLocaleName
);
418 /* Write the stringtable header */
420 "\r\nSTRINGTABLE DISCARDABLE\r\nLANGUAGE %d, %d\r\n",
423 fprintf(FileHandle
, "BEGIN\r\n");
425 /* Language or locale? */
426 if (strchr(gLocaleName
, '\"'))
428 /* Write the language name */
429 fprintf(FileHandle
, " %d %s\r\n", gStringIdForLanguageNames
, gLocaleName
);
433 /* Write the locale name */
434 fprintf(FileHandle
, " %d \"%s\"\r\n", gStringIdForLocaleName
, gLocaleName
);
437 /* Terminate the entry */
438 fprintf(FileHandle
, "END\r\n\r\n");
441 /* Check for description information */
442 while (DescriptionData
)
444 /* Remember the next pointer */
445 NextDescription
= DescriptionData
->Next
;
447 /* Write the header */
449 "\r\nSTRINGTABLE DISCARDABLE\r\nLANGUAGE %d, %d\r\n",
450 DescriptionData
->Code
& 0x3FF,
451 DescriptionData
->Code
>> 10);
452 fprintf(FileHandle
, "BEGIN\r\n");
454 /* Quoted string or not? */
455 if (strchr(DescriptionData
->Name
, '\"'))
457 /* Write the description name */
458 fprintf(FileHandle
, " %d %s\r\n", gStringIdForDescriptions
, DescriptionData
->Name
);
462 /* Write the description name */
463 fprintf(FileHandle
, " %d \"%s\"\r\n", gStringIdForDescriptions
, DescriptionData
->Name
);
466 /* Terminate the entry */
467 fprintf(FileHandle
, "END\r\n\r\n");
469 /* Free the allocation */
470 free(DescriptionData
->Name
);
471 free(DescriptionData
);
473 /* Move to the next entry */
474 DescriptionData
= NextDescription
;
477 /* Check for language information */
480 /* Remember the next pointer */
481 NextLanguage
= LanguageData
->Next
;
483 /* Write the header */
485 "\r\nSTRINGTABLE DISCARDABLE\r\nLANGUAGE %d, %d\r\n",
486 LanguageData
->Code
& 0x3FF,
487 LanguageData
->Code
>> 10);
488 fprintf(FileHandle
, "BEGIN\r\n");
490 /* Quoted string or not? */
491 if (strchr(LanguageData
->Name
, '\"'))
493 /* Write the language name */
494 fprintf(FileHandle
, " %d %s\r\n", gStringIdForLanguageNames
, LanguageData
->Name
);
498 /* Write the language name */
499 fprintf(FileHandle
, " %d \"%s\"\r\n", gStringIdForLanguageNames
, LanguageData
->Name
);
502 /* Terminate the entry */
503 fprintf(FileHandle
, "END\r\n\r\n");
505 /* Free the allocation */
506 free(LanguageData
->Name
);
509 /* Move to the next entry */
510 LanguageData
= NextLanguage
;
524 /* Build the keyboard name and internal name */
525 strcpy(OutputFile
, gKBDName
);
526 strcat(OutputFile
, ".DEF");
529 FileHandle
= fopen(OutputFile
, "wt");
533 printf(" %12s : can't open for write.\n", OutputFile
);
537 /* Write the file exports */
541 " KbdLayerDescriptor @1\n",
550 kbd_c(IN ULONG StateCount
,
551 IN PULONG ShiftStates
,
552 IN PVOID AttributeData
,
554 IN PVOID DeadKeyData
,
555 IN PVOID LigatureData
,
556 IN PKEYNAME KeyNameData
,
557 IN PKEYNAME KeyNameExtData
,
558 IN PKEYNAME KeyNameDeadData
)
561 CHAR KeyNameBuffer
[50];
562 CHAR LineBuffer
[256];
571 /* Build the keyboard name and internal name */
572 strcpy(OutputFile
, gKBDName
);
573 strcat(OutputFile
, ".C");
576 FileHandle
= fopen(OutputFile
, "wt");
580 printf(" %12s : can't open for write.\n", OutputFile
);
584 /* Print the header */
586 "/***************************************************************************\\\n"
587 "* Module Name: %s\n*\n* keyboard layout\n"
589 "* Copyright (c) 2009, ReactOS Foundation\n"
592 "* KBDTOOL v%d.%02d - Created %s"
593 "\\***************************************************************************/\n\n",
599 /* What kind of driver is this? */
603 fprintf(FileHandle
, "#include \"precomp.h\"\n");
607 /* Add the includes */
609 "#include <windows.h>\n"
610 "#include \"kbd.h\"\n"
611 "#include \"%s.h\"\n\n",
615 /* What kind of driver is this? */
618 /* Only one section */
620 "#pragma data_seg(\"%s\")\n#define ALLOC_SECTION_LDATA\n\n",
625 /* Section and attributes depend on architecture */
627 "#if defined(_M_IA64)\n"
628 "#pragma section(\"%s\")\n"
629 "#define ALLOC_SECTION_LDATA __declspec(allocate(\"%s\"))\n"
631 "#pragma data_seg(\"%s\")\n"
632 "#define ALLOC_SECTION_LDATA\n"
639 /* Scan code to virtual key conversion table header */
641 "/***************************************************************************\\\n"
642 "* ausVK[] - Virtual Scan Code to Virtual Key conversion table\n"
643 "\\***************************************************************************/\n\n");
647 "static ALLOC_SECTION_LDATA USHORT ausVK[] = {\n"
648 " T00, T01, T02, T03, T04, T05, T06, T07,\n"
649 " T08, T09, T0A, T0B, T0C, T0D, T0E, T0F,\n"
650 " T10, T11, T12, T13, T14, T15, T16, T17,\n"
651 " T18, T19, T1A, T1B, T1C, T1D, T1E, T1F,\n"
652 " T20, T21, T22, T23, T24, T25, T26, T27,\n"
653 " T28, T29, T2A, T2B, T2C, T2D, T2E, T2F,\n"
654 " T30, T31, T32, T33, T34, T35,\n\n");
659 " * Right-hand Shift key must have KBDEXT bit set.\n"
662 " T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot\n\n"
663 " T38, T39, T3A, T3B, T3C, T3D, T3E,\n"
664 " T3F, T40, T41, T42, T43, T44,\n\n");
670 " * KBDEXT - VK_NUMLOCK is an Extended key\n"
671 " * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL)\n"
673 " T45 | KBDEXT | KBDMULTIVK,\n\n"
674 " T46 | KBDMULTIVK,\n\n");
679 " * Number Pad keys:\n"
680 " * KBDNUMPAD - digits 0-9 and decimal point.\n"
681 " * KBDSPECIAL - require special processing by Windows\n"
683 " T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home)\n"
684 " T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up),\n"
685 " T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp),\n"
687 " T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left),\n"
688 " T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear),\n"
689 " T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right),\n"
691 " T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End),\n"
692 " T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down),\n"
693 " T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn),\n"
694 " T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins),\n"
695 " T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del),\n\n");
699 " T54, T55, T56, T57, T58, T59, T5A, T5B,\n"
700 " T5C, T5D, T5E, T5F, T60, T61, T62, T63,\n"
701 " T64, T65, T66, T67, T68, T69, T6A, T6B,\n"
702 " T6C, T6D, T6E, T6F, T70, T71, T72, T73,\n"
703 " T74, T75, T76, T77, T78, T79, T7A, T7B,\n"
707 /* Key name table header */
708 fprintf(FileHandle
, "static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = {\n");
710 /* Loop 110-key table */
711 for (i
= 0; i
< 110; i
++)
713 /* Check for non-extended keys */
714 if ((Layout
->Entry
[i
].ScanCode
& 0xFF00) == 0xE000)
716 /* Which are valid */
717 if (Layout
->Entry
[i
].ScanCode
!= 0xFF)
720 if (Layout
->Entry
[i
].VirtualKey
!= 0xFF)
724 " { 0x%02X, X%02X | KBDEXT }, // %s\n",
725 Layout
->Entry
[i
].ScanCode
,
726 Layout
->Entry
[i
].ScanCode
,
727 Layout
->Entry
[i
].Name
);
733 /* Key name table finish */
734 fprintf(FileHandle
, " { 0, 0 }\n};\n\n");
736 /* Extended key name table header */
737 fprintf(FileHandle
, "static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = {\n");
739 /* Loop 110-key table */
740 for (i
= 0; i
< 110; i
++)
742 /* Check for extended keys */
743 if ((Layout
->Entry
[i
].ScanCode
& 0xFF00) == 0xE100)
745 /* Which are valid */
746 if (Layout
->Entry
[i
].ScanCode
!= 0xFF)
749 if (Layout
->Entry
[i
].VirtualKey
!= 0xFF)
753 " { 0x%02X, Y%02X | KBDEXT }, // %s\n",
754 Layout
->Entry
[i
].ScanCode
,
755 Layout
->Entry
[i
].ScanCode
,
756 Layout
->Entry
[i
].Name
);
762 /* Extended key name table finish */
764 " { 0x1D, Y1D }, // Pause\n"
765 " { 0 , 0 }\n};\n\n");
767 /* Modifier table description */
769 "/***************************************************************************\\\n"
770 "* aVkToBits[] - map Virtual Keys to Modifier Bits\n"
772 "* See kbd.h for a full description.\n"
774 "* The keyboard has only three shifter keys:\n"
775 "* SHIFT (L & R) affects alphabnumeric keys,\n"
776 "* CTRL (L & R) is used to generate control characters\n"
777 "* ALT (L & R) used for generating characters by number with numpad\n"
778 "\\***************************************************************************/\n");
780 /* Modifier table header */
781 fprintf(FileHandle
, "static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = {\n");
783 /* Loop modifier table */
785 Entry
= &Modifiers
[0];
786 while (Entry
->VirtualKey
)
788 /* Print out entry */
790 " { %-12s, %-12s },\n",
791 getVKName(Entry
->VirtualKey
, 1),
794 /* Move to the next one */
795 Entry
= &Modifiers
[++i
];
798 /* Modifier table finish */
799 fprintf(FileHandle
, " { 0, 0 }\n};\n\n");
801 /* Modifier conversion table description */
803 "/***************************************************************************\\\n"
804 "* aModification[] - map character modifier bits to modification number\n"
806 "* See kbd.h for a full description.\n"
808 "\\***************************************************************************/\n\n");
810 /* Zero out local state data */
811 for (i
= 0; i
< 8; i
++) States
[i
] = -1;
813 /* Find the highest set state */
814 for (HighestState
= 1, i
= 0; (i
< 8) && (ShiftStates
[i
] != -1); i
++)
816 /* Save all state values */
817 States
[ShiftStates
[i
]] = i
;
818 if (ShiftStates
[i
] > HighestState
) HighestState
= ShiftStates
[i
];
821 /* Modifier conversion table header */
823 "static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = {\n"
827 " // Modification# // Keys Pressed\n"
828 " // ============= // =============\n",
832 for (i
= 0; i
<= HighestState
; i
++)
834 /* Check for invalid state */
837 /* Invalid state header */
838 fprintf(FileHandle
, " SHFT_INVALID, // ");
842 /* Is this the last one? */
843 if (i
== HighestState
)
845 /* Last state header */
846 fprintf(FileHandle
, " %d // ", States
[i
]);
850 /* Normal state header */
851 fprintf(FileHandle
, " %d, // ", States
[i
]);
854 /* State 1 or higher? */
857 /* J is the loop variable, K is the double */
858 for (NeedPlus
= 0, j
= 0, k
= 1; (1u << j
) <= i
; j
++, k
= (1 << j
))
860 /* Do we need to add a plus? */
864 fprintf(FileHandle
, "+");
868 /* Check if it's time to add a modifier */
871 /* Get the key state name and copy it into our buffer */
872 strcpy(KeyNameBuffer
, getVKName(Modifiers
[j
].VirtualKey
, 1));
874 /* Go go the 4th char (past the "KBD") and lower name */
875 for (p
= &KeyNameBuffer
[4]; *p
; p
++) *p
= tolower(*p
);
878 fprintf(FileHandle
, "%s", &KeyNameBuffer
[3]);
880 /* We'll need a plus sign next */
886 /* Terminate the entry */
887 fprintf(FileHandle
, "\n");
892 /* Modifier conversion table end */
893 fprintf(FileHandle
," }\n" "};\n\n");
895 /* Shift state translation table description */
897 "/***************************************************************************\\\n"
899 "* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states\n"
900 "* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states\n"
901 "* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states\n");
903 /* Check if there's exta shift states */
904 for (i
= 5; i
< HighestState
; i
++)
906 /* Print out extra information */
908 "* aVkToWch%d[] - Virtual Key to WCHAR translation for %d shift states\n",
913 /* Shift state translation table description continue */
916 "* Table attributes: Unordered Scan, null-terminated\n"
918 "* Search this table for an entry with a matching Virtual Key to find the\n"
919 "* corresponding unshifted and shifted WCHAR characters.\n"
921 "* Special values for VirtualKey (column 1)\n"
922 "* 0xff - dead chars for the previous entry\n"
923 "* 0 - terminate the list\n"
925 "* Special values for Attributes (column 2)\n"
926 "* CAPLOK bit - CAPS-LOCK affect this key like SHIFT\n"
928 "* Special values for wch[*] (column 3 & 4)\n"
929 "* WCH_NONE - No character\n"
930 "* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none)\n"
931 "* WCH_LGTR - Ligature (generates multiple characters)\n"
933 "\\***************************************************************************/\n\n");
935 /* Loop all the states */
936 for (i
= 2; i
<= StateCount
; i
++)
938 /* Check if this something else than state 2 */
941 /* Loop all the scan codes */
942 for (j
= 0; j
< 110; j
++)
944 /* Check if this is the state for the entry */
945 if (i
== Layout
->Entry
[j
].StateCount
) break;
949 /* Print the table header */
951 "static ALLOC_SECTION_LDATA VK_TO_WCHARS%d aVkToWch%d[] = {\n"
956 /* Print the correct state label */
957 for (k
= 2; k
< i
; k
++) fprintf(FileHandle
, "%-9.9s|",
958 StateLabel
[ShiftStates
[k
]]);
960 /* Print the next separator */
961 fprintf(FileHandle
, "\n// |=========|=========|");
963 /* Check for extra states and print their separators too */
964 for (k
= 2; k
< i
; k
++) fprintf(FileHandle
, "=========|");
966 /* Finalize the separator header */
967 fprintf(FileHandle
, "\n");
969 /* Loop all the scan codes */
970 for (j
= 0; j
< 110; j
++)
972 /* Check if this is the state for the entry */
973 if (i
!= Layout
->Entry
[j
].StateCount
) continue;
975 /* Print out the entry for this key */
978 getVKName(Layout
->Entry
[j
].VirtualKey
, 1),
979 CapState
[Layout
->Entry
[j
].Cap
]);
981 /* Initialize the buffer for this line */
985 for (k
= 0; k
< i
; k
++)
987 /* Check for dead key data */
990 /* Not yet supported */
991 printf("Dead key data not supported!\n");
995 /* Check if it's a ligature key */
996 if (Layout
->Entry
[j
].LigatureCharData
[k
])
998 /* Not yet supported */
999 printf("Ligature key data not supported!\n");
1003 /* Print out the WCH_ name */
1006 WChName(Layout
->Entry
[j
].CharData
[k
], 0));
1008 /* If we have something on the line buffer by now, add WCH_NONE */
1009 if (*LineBuffer
!= '\0') strcpy(LineBuffer
, "WCH_NONE ");
1012 /* Finish the line */
1013 fprintf(FileHandle
, "},\n");
1015 /* Do we have any data at all? */
1016 if (*LineBuffer
!= '\0')
1018 /* Print it, we're done */
1019 fprintf(FileHandle
, "%s},\n", LineBuffer
);
1023 /* Otherwise, we're done, unless this requires SGCAP data */
1024 if (Layout
->Entry
[j
].Cap
!= 2) continue;
1026 /* Not yet supported */
1027 printf("SGCAP not yet supported!\n");
1031 /* Did we only have two states? */
1034 /* Print out the built-in table */
1036 " {VK_TAB ,0 ,'\\t' ,'\\t' },\n"
1037 " {VK_ADD ,0 ,'+' ,'+' },\n"
1038 " {VK_DIVIDE ,0 ,'/' ,'/' },\n"
1039 " {VK_MULTIPLY ,0 ,'*' ,'*' },\n"
1040 " {VK_SUBTRACT ,0 ,'-' ,'-' },\n");
1043 /* Terminate the table */
1044 fprintf(FileHandle
, " {0 ,0 ");
1045 for (k
= 0; k
< i
; k
++) fprintf(FileHandle
, ",0 ");
1047 /* Terminate the structure */
1048 fprintf(FileHandle
, "}\n" "};\n\n");
1051 /* Numpad translation table */
1053 "// Put this last so that VkKeyScan interprets number characters\n"
1054 "// as coming from the main section of the kbd (aVkToWch2 and\n"
1055 "// aVkToWch5) before considering the numpad (aVkToWch1).\n\n"
1056 "static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = {\n"
1057 " { VK_NUMPAD0 , 0 , '0' },\n"
1058 " { VK_NUMPAD1 , 0 , '1' },\n"
1059 " { VK_NUMPAD2 , 0 , '2' },\n"
1060 " { VK_NUMPAD3 , 0 , '3' },\n"
1061 " { VK_NUMPAD4 , 0 , '4' },\n"
1062 " { VK_NUMPAD5 , 0 , '5' },\n"
1063 " { VK_NUMPAD6 , 0 , '6' },\n"
1064 " { VK_NUMPAD7 , 0 , '7' },\n"
1065 " { VK_NUMPAD8 , 0 , '8' },\n"
1066 " { VK_NUMPAD9 , 0 , '9' },\n"
1067 " { 0 , 0 , '\\0' }\n"
1070 /* Translation tables header */
1071 fprintf(FileHandle
,"static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = {\n");
1073 /* Loop states higher than 3 */
1074 for (i
= 3; i
<= StateCount
; i
++)
1076 /* Print out the extra tables */
1078 " { (PVK_TO_WCHARS1)aVkToWch%d, %d, sizeof(aVkToWch%d[0]) },\n",
1084 /* Array of translation tables */
1086 " { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) },\n"
1087 " { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) },\n"
1088 " { NULL, 0, 0 },\n"
1091 /* Scan code to key name conversion table description */
1093 "/***************************************************************************\\\n"
1094 "* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables\n"
1096 "* Table attributes: Ordered Scan (by scancode), null-terminated\n"
1098 "* Only the names of Extended, NumPad, Dead and Non-Printable keys are here.\n"
1099 "* (Keys producing printable characters are named by that character)\n"
1100 "\\***************************************************************************/\n\n");
1102 /* Check for key name data */
1106 fprintf(FileHandle
, "static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNames[] = {\n");
1109 PrintNameTable(FileHandle
, KeyNameData
, FALSE
);
1112 fprintf(FileHandle
, "};\n\n");
1115 /* Check for extended key name data */
1119 fprintf(FileHandle
, "static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNamesExt[] = {\n");
1122 PrintNameTable(FileHandle
, KeyNameExtData
, FALSE
);
1125 fprintf(FileHandle
, "};\n\n");
1128 /* Check for dead key name data */
1129 if (KeyNameDeadData
)
1131 /* Not yet supported */
1132 printf("Dead key name data not supported!\n");
1136 /* Check for dead key data */
1139 /* Not yet supported */
1140 printf("Dead key data not supported!\n");
1144 /* Check for ligature data */
1147 /* Not yet supported */
1148 printf("Ligature key data not supported!\n");
1152 /* Main keyboard table descriptor type */
1153 fprintf(FileHandle
, "static ");
1157 /* Main keyboard table descriptor header */
1159 "ALLOC_SECTION_LDATA KBDTABLES KbdTables%s = {\n"
1161 " * Modifier keys\n"
1163 " &CharModifiers,\n\n"
1165 " * Characters tables\n"
1167 " aVkToWcharTable,\n\n"
1171 FallbackDriver
? "Fallback" : "" );
1173 /* Descriptor dead key data section */
1176 fprintf(FileHandle
, " aDeadKey,\n\n");
1180 fprintf(FileHandle
, " NULL,\n\n");
1183 /* Descriptor key name comment */
1186 " * Names of Keys\n"
1189 /* Descriptor key name section */
1192 fprintf(FileHandle
, " aKeyNames,\n");
1196 fprintf(FileHandle
, " NULL,\n");
1199 /* Descriptor extended key name section */
1202 fprintf(FileHandle
, " aKeyNamesExt,\n");
1206 fprintf(FileHandle
, " NULL,\n");
1209 /* Descriptor dead key name section */
1210 if ((DeadKeyData
) && (KeyNameDeadData
))
1212 fprintf(FileHandle
, " aKeyNamesDead,\n\n");
1216 fprintf(FileHandle
, " NULL,\n\n");
1219 /* Descriptor conversion table section */
1222 " * Scan codes to Virtual Keys\n"
1225 " sizeof(ausVK) / sizeof(ausVK[0]),\n"
1229 " * Locale-specific special processing\n"
1232 /* FIXME: AttributeData and KLLF_ALTGR stuff */
1234 /* Descriptor locale-specific section */
1235 fprintf(FileHandle
, " MAKELONG(%s, KBD_VERSION),\n\n", "0"); /* FIXME */
1237 /* Descriptor ligature data comment */
1238 fprintf(FileHandle
, " /*\n * Ligatures\n */\n %d,\n", 0); /* FIXME */
1240 /* Descriptor ligature data section */
1243 fprintf(FileHandle
, " 0,\n");
1244 fprintf(FileHandle
, " NULL\n");
1248 fprintf(FileHandle
, " sizeof(aLigature[0]),\n");
1249 fprintf(FileHandle
, " (PLIGATURE1)aLigature\n");
1252 /* Descriptor finish */
1253 fprintf(FileHandle
, "};\n\n");
1255 /* Keyboard layout callback function */
1256 if (!FallbackDriver
) fprintf(FileHandle
,
1257 "PKBDTABLES KbdLayerDescriptor(VOID)\n"
1259 " return &KbdTables;\n"
1268 DoOutput(IN ULONG StateCount
,
1269 IN PULONG ShiftStates
,
1270 IN PKEYNAME DescriptionData
,
1271 IN PKEYNAME LanguageData
,
1272 IN PVOID AttributeData
,
1273 IN PVOID DeadKeyData
,
1274 IN PVOID LigatureData
,
1275 IN PKEYNAME KeyNameData
,
1276 IN PKEYNAME KeyNameExtData
,
1277 IN PKEYNAME KeyNameDeadData
)
1279 ULONG FailureCode
= 0;
1283 Now
= localtime(&Clock
);
1285 /* Check if this just a fallback driver*/
1286 if (!FallbackDriver
)
1288 /* It's not, create header file */
1289 if (!kbd_h(&g_Layout
)) FailureCode
= 1;
1291 /* Create the resource file */
1292 if (!kbd_rc(DescriptionData
, LanguageData
)) FailureCode
= 2;
1295 /* Create the C file */
1296 if (!kbd_c(StateCount
,
1306 /* Failed in C file generation */
1310 /* Check if this just a fallback driver*/
1311 if (!FallbackDriver
)
1313 /* Generate the definition file */
1314 if (!kbd_def()) FailureCode
= 4;