mirror of
https://github.com/reactos/reactos.git
synced 2024-08-26 13:18:51 +00:00
1323 lines
41 KiB
C
1323 lines
41 KiB
C
/*
|
|
* PROJECT: ReactOS Build Tools [Keyboard Layout Compiler]
|
|
* LICENSE: BSD - See COPYING.BSD in the top level directory
|
|
* FILE: tools/kbdtool/output.c
|
|
* PURPOSE: Output Logic (Source Builder)
|
|
* PROGRAMMERS: ReactOS Foundation
|
|
*/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include "kbdtool.h"
|
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
ULONG gStringIdForDescriptions = 1000;
|
|
ULONG gStringIdForLanguageNames = 1100;
|
|
ULONG gStringIdForLocaleName = 1200;
|
|
time_t Clock;
|
|
struct tm *Now;
|
|
CHAR gCharName[32];
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
PCHAR
|
|
WChName(IN ULONG Char,
|
|
IN BOOLEAN AddZero)
|
|
{
|
|
PCHAR p;
|
|
|
|
/* Check for invalid character */
|
|
if (Char == -1)
|
|
{
|
|
/* No name */
|
|
strcpy(gCharName, "WCH_NONE");
|
|
}
|
|
else if ((Char > 31) && (Char < 128))
|
|
{
|
|
/* Use our global buffer */
|
|
p = gCharName;
|
|
|
|
/* Add the first quote unless this was a zero-string */
|
|
if (!AddZero) *p++ = '\'';
|
|
|
|
/* Now replace any other quote or comment character with a slash */
|
|
if ((Char == '\"') || (Char == '\'') || (Char == '\\')) *p++ = '\\';
|
|
|
|
/* Now plug in the character */
|
|
*p++ = Char;
|
|
|
|
/* And add the terminating quote, unless this was a zero-string */
|
|
if (!AddZero) *p++ = '\'';
|
|
|
|
/* Terminate the buffer */
|
|
*p = '\0';
|
|
}
|
|
else
|
|
{
|
|
/* Handle special cases */
|
|
if (Char == '\b')
|
|
{
|
|
/* Bell */
|
|
strcpy(gCharName, "'\\b'");
|
|
}
|
|
else if (Char == '\n')
|
|
{
|
|
/* New line */
|
|
strcpy(gCharName, "'\\n'");
|
|
}
|
|
else if (Char == '\r')
|
|
{
|
|
/* Return */
|
|
strcpy(gCharName, "'\\r'");
|
|
}
|
|
else if (!AddZero)
|
|
{
|
|
/* Char value, in hex */
|
|
sprintf(gCharName, "0x%04x", Char);
|
|
}
|
|
else
|
|
{
|
|
/* Char value, C-style */
|
|
sprintf(gCharName, "\\x%04x", Char);
|
|
}
|
|
}
|
|
|
|
/* Return the name */
|
|
return gCharName;
|
|
}
|
|
|
|
VOID
|
|
PrintNameTable(FILE* FileHandle,
|
|
PKEYNAME KeyName,
|
|
BOOL DeadKey)
|
|
{
|
|
CHAR CharBuffer[255];
|
|
PKEYNAME NextName;
|
|
PCHAR Name, Buffer;
|
|
ULONG i;
|
|
|
|
/* Loop all key names */
|
|
while (KeyName)
|
|
{
|
|
/* Go to the next key name */
|
|
NextName = KeyName->Next;
|
|
|
|
/* Remember the name and our buffer address */
|
|
Name = KeyName->Name;
|
|
Buffer = CharBuffer;
|
|
|
|
/* Check if it's an IDS name */
|
|
if (strncmp(Name, "IDS_", 4))
|
|
{
|
|
/* No, so start parsing it. First, handle initial quote */
|
|
if (*Name != '\"') *Buffer++ = '\"';
|
|
|
|
/* Next, parse the name */
|
|
while (*Name)
|
|
{
|
|
/* Check if this is a C-style hex string */
|
|
if ((*Name != '\\') || ((*(Name + 1) != 'x') && (*(Name + 1) != 'X')))
|
|
{
|
|
/* It's not, so just copy straight into our buffer */
|
|
*Buffer++ = *Name++;
|
|
}
|
|
else
|
|
{
|
|
/* Continue scanning as long as this is a C-style hex string */
|
|
while ((*Name == '\\') && ((*(Name + 1) == 'x') || (*(Name + 1) == 'X')))
|
|
{
|
|
/* Copy 6 characters */
|
|
for (i = 0; (*Name) && (i < 6); i++) *Buffer++ = *Name++;
|
|
}
|
|
|
|
/* Check if we still have something at the end */
|
|
if (*Name)
|
|
{
|
|
/* Terminate our buffer */
|
|
*Buffer++ = '\"';
|
|
*Buffer++ = ' ';
|
|
*Buffer++ = 'L';
|
|
*Buffer++ = '\"';
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Check for terminating quote */
|
|
if (*(Buffer - 1) != '\"') *Buffer++ = '\"';
|
|
|
|
/* Terminate the buffer */
|
|
*Buffer++ = '\0';
|
|
}
|
|
else
|
|
{
|
|
/* Not yet supported */
|
|
printf("IDS Entries not yet handled!\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* Is this a dead key? */
|
|
if (DeadKey)
|
|
{
|
|
/* Not yet handled */
|
|
printf("Dead keys not yet handled\n");
|
|
exit(1);
|
|
}
|
|
else
|
|
{
|
|
/* Print the entry */
|
|
fprintf(FileHandle, " 0x%02x, L%s,\n", KeyName->Code, CharBuffer);
|
|
}
|
|
|
|
/* Cleanup allocation */
|
|
free(KeyName->Name);
|
|
free(KeyName);
|
|
|
|
/* Move on */
|
|
KeyName = NextName;
|
|
}
|
|
|
|
/* Is this a dead key? */
|
|
if (DeadKey)
|
|
{
|
|
/* Not yet handled */
|
|
printf("Dead keys not yet handled\n");
|
|
exit(1);
|
|
}
|
|
else
|
|
{
|
|
/* Terminate the table */
|
|
fprintf(FileHandle, " 0 , NULL\n");
|
|
}
|
|
}
|
|
|
|
BOOLEAN
|
|
kbd_h(IN PLAYOUT Layout)
|
|
{
|
|
CHAR OutputFile[13];
|
|
FILE *FileHandle;
|
|
ULONG i;
|
|
CHAR UndefChar;
|
|
USHORT SubCode;
|
|
|
|
/* Build the keyboard name */
|
|
strcpy(OutputFile, gKBDName);
|
|
strcat(OutputFile, ".H");
|
|
|
|
/* Open it */
|
|
FileHandle = fopen(OutputFile, "wt");
|
|
if (!FileHandle)
|
|
{
|
|
/* Fail */
|
|
printf(" %12s : can't open for write.\n", OutputFile);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Print the module header */
|
|
fprintf(FileHandle,
|
|
"/****************************** Module Header ******************************\\\n"
|
|
"* Module Name: %s\n*\n* keyboard layout header\n"
|
|
"*\n"
|
|
"* Copyright (c) 2009, ReactOS Foundation\n"
|
|
"*\n"
|
|
"* Various defines for use by keyboard input code.\n*\n* History:\n"
|
|
"*\n"
|
|
"* created by KBDTOOL v%d.%02d %s*\n"
|
|
"\\***************************************************************************/\n\n",
|
|
OutputFile,
|
|
gVersion,
|
|
gSubVersion,
|
|
asctime(Now));
|
|
|
|
/* Print out the includes and defines */
|
|
fprintf(FileHandle,
|
|
"/*\n"
|
|
" * kbd type should be controlled by cl command-line argument\n"
|
|
" *\\n"
|
|
"#define KBD_TYPE 4\n\n"
|
|
"/*\n"
|
|
"* Include the basis of all keyboard table values\n"
|
|
"*/\n"
|
|
"#include \"kbd.h\"\n");
|
|
|
|
/* Now print out the virtual key conversion table */
|
|
fprintf(FileHandle,
|
|
"/***************************************************************************\\\n"
|
|
"* The table below defines the virtual keys for various keyboard types where\n"
|
|
"* the keyboard differ from the US keyboard.\n"
|
|
"*\n"
|
|
"* _EQ() : all keyboard types have the same virtual key for this scancode\n"
|
|
"* _NE() : different virtual keys for this scancode, depending on kbd type\n"
|
|
"*\n"
|
|
"* +------+ +----------+----------+----------+----------+----------+----------+\n"
|
|
"* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd |\n"
|
|
"* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 |\n"
|
|
"\\****+-------+_+----------+----------+----------+----------+----------+----------+*/\n\n");
|
|
|
|
/* Loop all keys */
|
|
for (i = 0; i < 110; i++)
|
|
{
|
|
/* Check if we processed this key */
|
|
if (Layout->Entry[i].Processed)
|
|
{
|
|
/* Check if it redefined a virtual key */
|
|
if (Layout->Entry[i].VirtualKey != Layout->Entry[i].OriginalVirtualKey)
|
|
{
|
|
/* Do we have a subcode? */
|
|
SubCode = Layout->Entry[i].ScanCode & 0xFF00;
|
|
if (SubCode)
|
|
{
|
|
/* Which kind is it? */
|
|
if (SubCode == 0xE000)
|
|
{
|
|
/* Extended 0 */
|
|
UndefChar = 'X';
|
|
}
|
|
else
|
|
{
|
|
/* Illegal */
|
|
if (SubCode != 0xE100)
|
|
{
|
|
/* Unrecognized */
|
|
printf("Weird scancode value %04x: expected xx, E0xx, or E1xx\n", SubCode);
|
|
exit(1);
|
|
}
|
|
|
|
/* Extended 1 */
|
|
UndefChar = 'Y';
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Normal key */
|
|
UndefChar = 'T';
|
|
}
|
|
|
|
/* Print out the virtual key redefinition */
|
|
fprintf(FileHandle,
|
|
"#undef %c%02X\n#define %c%02X _EQ(%43s%23s\n",
|
|
UndefChar,
|
|
Layout->Entry[i].ScanCode,
|
|
UndefChar,
|
|
Layout->Entry[i].ScanCode,
|
|
getVKName(Layout->Entry[i].VirtualKey, 0),
|
|
")");
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Cleanup and close */
|
|
fprintf(FileHandle,"\n");
|
|
fclose(FileHandle);
|
|
|
|
/* We made it */
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
kbd_rc(IN PKEYNAME DescriptionData,
|
|
IN PKEYNAME LanguageData)
|
|
{
|
|
CHAR OutputFile[13];
|
|
CHAR InternalName[13];
|
|
CHAR TimeBuffer[5];
|
|
FILE *FileHandle;
|
|
ULONG Length;
|
|
PCHAR p;
|
|
PKEYNAME NextDescription, NextLanguage;
|
|
|
|
/* Build the keyboard name and internal name */
|
|
strcpy(OutputFile, gKBDName);
|
|
strcat(OutputFile, ".RC");
|
|
strcpy(InternalName, gKBDName);
|
|
for (p = InternalName; *p; p++) *p = tolower(*p);
|
|
|
|
/* Open it */
|
|
FileHandle = fopen(OutputFile, "wb");
|
|
if (!FileHandle)
|
|
{
|
|
/* Fail */
|
|
printf(" %12s : can't open for write.\n", OutputFile);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Check if we have copyright */
|
|
Length = strlen(gCopyright);
|
|
if (!Length)
|
|
{
|
|
/* Set time string */
|
|
strftime(TimeBuffer, 5, "%Y", Now);
|
|
|
|
/* Add copyright character */
|
|
strcpy(gCopyright, "(C)");
|
|
|
|
/* Add the year */
|
|
strcat(gCopyright, TimeBuffer);
|
|
|
|
/* Add blank company */
|
|
strcat(gCopyright, " ");
|
|
}
|
|
|
|
/* Write the resource file header */
|
|
fprintf(FileHandle,
|
|
"#include \"winver.h\"\r\n"
|
|
"1 VERSIONINFO\r\n"
|
|
" FILEVERSION 1,0,%d,%d\r\n"
|
|
" PRODUCTVERSION 1,0,%d,%d\r\n"
|
|
" FILEFLAGSMASK 0x3fL\r\n"
|
|
" FILEFLAGS 0x0L\r\n"
|
|
"FILEOS 0x40004L\r\n"
|
|
" FILETYPE VFT_DLL\r\n"
|
|
" FILESUBTYPE VFT2_DRV_KEYBOARD\r\n"
|
|
"BEGIN\r\n"
|
|
" BLOCK \"StringFileInfo\"\r\n"
|
|
" BEGIN\r\n"
|
|
" BLOCK \"000004B0\"\r\n"
|
|
" BEGIN\r\n"
|
|
" VALUE \"CompanyName\", \"%s\\0\"\r\n"
|
|
" VALUE \"FileDescription\", \"%s Keyboard Layout\\0\"\r\n"
|
|
" VALUE \"FileVersion\", \"1, 0, %d, %d\\0\"\r\n",
|
|
gVersion,
|
|
gSubVersion,
|
|
gVersion,
|
|
gSubVersion,
|
|
gCompany,
|
|
gDescription,
|
|
gVersion,
|
|
gSubVersion);
|
|
|
|
/* Continue writing it */
|
|
fprintf(FileHandle,
|
|
" VALUE \"InternalName\", \"%s (%d.%d)\\0\"\r\n"
|
|
" VALUE \"ProductName\",\"%s\\0\"\r\n"
|
|
" VALUE \"Release Information\",\"%s\\0\"\r\n"
|
|
" VALUE \"LegalCopyright\", \"%s\\0\"\r\n"
|
|
" VALUE \"OriginalFilename\",\"%s\\0\"\r\n"
|
|
" VALUE \"ProductVersion\", \"1, 0, %d, %d\\0\"\r\n"
|
|
" END\r\n"
|
|
" END\r\n"
|
|
" BLOCK \"VarFileInfo\"\r\n"
|
|
" BEGIN\r\n"
|
|
" VALUE \"Translation\", 0x0000, 0x04B0\r\n"
|
|
" END\r\n"
|
|
"END\r\n",
|
|
InternalName,
|
|
gVersion,
|
|
gSubVersion,
|
|
"Created by ReactOS KbdTool",
|
|
"Created by ReactOS KbdTool",
|
|
gCopyright,
|
|
InternalName,
|
|
gVersion,
|
|
gSubVersion);
|
|
|
|
/* Now check if we have a locale name */
|
|
Length = strlen(gLocaleName);
|
|
if (Length)
|
|
{
|
|
/* Write the stringtable header */
|
|
fprintf(FileHandle,
|
|
"\r\nSTRINGTABLE DISCARDABLE\r\nLANGUAGE %d, %d\r\n",
|
|
9,
|
|
1);
|
|
fprintf(FileHandle, "BEGIN\r\n");
|
|
|
|
/* Language or locale? */
|
|
if (strchr(gLocaleName, '\"'))
|
|
{
|
|
/* Write the language name */
|
|
fprintf(FileHandle, " %d %s\r\n", gStringIdForLanguageNames, gLocaleName);
|
|
}
|
|
else
|
|
{
|
|
/* Write the locale name */
|
|
fprintf(FileHandle, " %d \"%s\"\r\n", gStringIdForLocaleName, gLocaleName);
|
|
}
|
|
|
|
/* Terminate the entry */
|
|
fprintf(FileHandle, "END\r\n\r\n");
|
|
}
|
|
|
|
/* Check for description information */
|
|
while (DescriptionData)
|
|
{
|
|
/* Remember the next pointer */
|
|
NextDescription = DescriptionData->Next;
|
|
|
|
/* Write the header */
|
|
fprintf(FileHandle,
|
|
"\r\nSTRINGTABLE DISCARDABLE\r\nLANGUAGE %d, %d\r\n",
|
|
DescriptionData->Code & 0x3FF,
|
|
DescriptionData->Code >> 10);
|
|
fprintf(FileHandle, "BEGIN\r\n");
|
|
|
|
/* Quoted string or not? */
|
|
if (strchr(DescriptionData->Name, '\"'))
|
|
{
|
|
/* Write the description name */
|
|
fprintf(FileHandle, " %d %s\r\n", gStringIdForDescriptions, DescriptionData->Name);
|
|
}
|
|
else
|
|
{
|
|
/* Write the description name */
|
|
fprintf(FileHandle, " %d \"%s\"\r\n", gStringIdForDescriptions, DescriptionData->Name);
|
|
}
|
|
|
|
/* Terminate the entry */
|
|
fprintf(FileHandle, "END\r\n\r\n");
|
|
|
|
/* Free the allocation */
|
|
free(DescriptionData->Name);
|
|
free(DescriptionData);
|
|
|
|
/* Move to the next entry */
|
|
DescriptionData = NextDescription;
|
|
}
|
|
|
|
/* Check for language information */
|
|
while (LanguageData)
|
|
{
|
|
/* Remember the next pointer */
|
|
NextLanguage = LanguageData->Next;
|
|
|
|
/* Write the header */
|
|
fprintf(FileHandle,
|
|
"\r\nSTRINGTABLE DISCARDABLE\r\nLANGUAGE %d, %d\r\n",
|
|
LanguageData->Code & 0x3FF,
|
|
LanguageData->Code >> 10);
|
|
fprintf(FileHandle, "BEGIN\r\n");
|
|
|
|
/* Quoted string or not? */
|
|
if (strchr(LanguageData->Name, '\"'))
|
|
{
|
|
/* Write the language name */
|
|
fprintf(FileHandle, " %d %s\r\n", gStringIdForLanguageNames, LanguageData->Name);
|
|
}
|
|
else
|
|
{
|
|
/* Write the language name */
|
|
fprintf(FileHandle, " %d \"%s\"\r\n", gStringIdForLanguageNames, LanguageData->Name);
|
|
}
|
|
|
|
/* Terminate the entry */
|
|
fprintf(FileHandle, "END\r\n\r\n");
|
|
|
|
/* Free the allocation */
|
|
free(LanguageData->Name);
|
|
free(LanguageData);
|
|
|
|
/* Move to the next entry */
|
|
LanguageData = NextLanguage;
|
|
}
|
|
|
|
/* We're done! */
|
|
fclose(FileHandle);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
kbd_def(VOID)
|
|
{
|
|
CHAR OutputFile[13];
|
|
FILE *FileHandle;
|
|
|
|
/* Build the keyboard name and internal name */
|
|
strcpy(OutputFile, gKBDName);
|
|
strcat(OutputFile, ".DEF");
|
|
|
|
/* Open it */
|
|
FileHandle = fopen(OutputFile, "wt");
|
|
if (!FileHandle)
|
|
{
|
|
/* Fail */
|
|
printf(" %12s : can't open for write.\n", OutputFile);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Write the file exports */
|
|
fprintf(FileHandle,
|
|
"LIBRARY %s\n\n"
|
|
"EXPORTS\n"
|
|
" KbdLayerDescriptor @1\n",
|
|
gKBDName);
|
|
|
|
/* Clean up */
|
|
fclose(FileHandle);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOLEAN
|
|
kbd_c(IN ULONG StateCount,
|
|
IN PULONG ShiftStates,
|
|
IN PVOID AttributeData,
|
|
IN PLAYOUT Layout,
|
|
IN PVOID DeadKeyData,
|
|
IN PVOID LigatureData,
|
|
IN PKEYNAME KeyNameData,
|
|
IN PKEYNAME KeyNameExtData,
|
|
IN PKEYNAME KeyNameDeadData)
|
|
{
|
|
CHAR OutputFile[13];
|
|
CHAR KeyNameBuffer[50];
|
|
CHAR LineBuffer[256];
|
|
BOOLEAN NeedPlus;
|
|
FILE *FileHandle;
|
|
ULONG States[8];
|
|
ULONG i, j, k;
|
|
ULONG HighestState;
|
|
PVKNAME Entry;
|
|
PCHAR p;
|
|
|
|
/* Build the keyboard name and internal name */
|
|
strcpy(OutputFile, gKBDName);
|
|
strcat(OutputFile, ".C");
|
|
|
|
/* Open it */
|
|
FileHandle = fopen(OutputFile, "wt");
|
|
if (!FileHandle)
|
|
{
|
|
/* Fail */
|
|
printf(" %12s : can't open for write.\n", OutputFile);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Print the header */
|
|
fprintf(FileHandle,
|
|
"/***************************************************************************\\\n"
|
|
"* Module Name: %s\n*\n* keyboard layout\n"
|
|
"*\n"
|
|
"* Copyright (c) 2009, ReactOS Foundation\n"
|
|
"*\n"
|
|
"* History:\n"
|
|
"* KBDTOOL v%d.%02d - Created %s"
|
|
"\\***************************************************************************/\n\n",
|
|
OutputFile,
|
|
gVersion,
|
|
gSubVersion,
|
|
asctime(Now));
|
|
|
|
/* What kind of driver is this? */
|
|
if (FallbackDriver)
|
|
{
|
|
/* Fallback only */
|
|
fprintf(FileHandle, "#include \"precomp.h\"\n");
|
|
}
|
|
else
|
|
{
|
|
/* Add the includes */
|
|
fprintf(FileHandle,
|
|
"#include <windows.h>\n"
|
|
"#include \"kbd.h\"\n"
|
|
"#include \"%s.h\"\n\n",
|
|
gKBDName);
|
|
}
|
|
|
|
/* What kind of driver is this? */
|
|
if (FallbackDriver)
|
|
{
|
|
/* Only one section */
|
|
fprintf(FileHandle,
|
|
"#pragma data_seg(\"%s\")\n#define ALLOC_SECTION_LDATA\n\n",
|
|
".kbdfallback");
|
|
}
|
|
else
|
|
{
|
|
/* Section and attributes depend on architecture */
|
|
fprintf(FileHandle,
|
|
"#if defined(_M_IA64)\n"
|
|
"#pragma section(\"%s\")\n"
|
|
"#define ALLOC_SECTION_LDATA __declspec(allocate(\"%s\"))\n"
|
|
"#else\n"
|
|
"#pragma data_seg(\"%s\")\n"
|
|
"#define ALLOC_SECTION_LDATA\n"
|
|
"#endif\n\n",
|
|
".data",
|
|
".data",
|
|
".data");
|
|
}
|
|
|
|
/* Scan code to virtual key conversion table header */
|
|
fprintf(FileHandle,
|
|
"/***************************************************************************\\\n"
|
|
"* ausVK[] - Virtual Scan Code to Virtual Key conversion table\n"
|
|
"\\***************************************************************************/\n\n");
|
|
|
|
/* Table begin */
|
|
fprintf(FileHandle,
|
|
"static ALLOC_SECTION_LDATA USHORT ausVK[] = {\n"
|
|
" T00, T01, T02, T03, T04, T05, T06, T07,\n"
|
|
" T08, T09, T0A, T0B, T0C, T0D, T0E, T0F,\n"
|
|
" T10, T11, T12, T13, T14, T15, T16, T17,\n"
|
|
" T18, T19, T1A, T1B, T1C, T1D, T1E, T1F,\n"
|
|
" T20, T21, T22, T23, T24, T25, T26, T27,\n"
|
|
" T28, T29, T2A, T2B, T2C, T2D, T2E, T2F,\n"
|
|
" T30, T31, T32, T33, T34, T35,\n\n");
|
|
|
|
/* Table continue */
|
|
fprintf(FileHandle,
|
|
" /*\n"
|
|
" * Right-hand Shift key must have KBDEXT bit set.\n"
|
|
" */\n"
|
|
" T36 | KBDEXT,\n\n"
|
|
" T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot\n\n"
|
|
" T38, T39, T3A, T3B, T3C, T3D, T3E,\n"
|
|
" T3F, T40, T41, T42, T43, T44,\n\n");
|
|
|
|
/* Table continue */
|
|
fprintf(FileHandle,
|
|
" /*\n"
|
|
" * NumLock Key:\n"
|
|
" * KBDEXT - VK_NUMLOCK is an Extended key\n"
|
|
" * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL)\n"
|
|
" */\n"
|
|
" T45 | KBDEXT | KBDMULTIVK,\n\n"
|
|
" T46 | KBDMULTIVK,\n\n");
|
|
|
|
/* Numpad table */
|
|
fprintf(FileHandle,
|
|
" /*\n"
|
|
" * Number Pad keys:\n"
|
|
" * KBDNUMPAD - digits 0-9 and decimal point.\n"
|
|
" * KBDSPECIAL - require special processing by Windows\n"
|
|
" */\n"
|
|
" T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home)\n"
|
|
" T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up),\n"
|
|
" T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp),\n"
|
|
" T4A,\n"
|
|
" T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left),\n"
|
|
" T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear),\n"
|
|
" T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right),\n"
|
|
" T4E,\n"
|
|
" T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End),\n"
|
|
" T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down),\n"
|
|
" T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn),\n"
|
|
" T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins),\n"
|
|
" T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del),\n\n");
|
|
|
|
/* Table finish */
|
|
fprintf(FileHandle,
|
|
" T54, T55, T56, T57, T58, T59, T5A, T5B,\n"
|
|
" T5C, T5D, T5E, T5F, T60, T61, T62, T63,\n"
|
|
" T64, T65, T66, T67, T68, T69, T6A, T6B,\n"
|
|
" T6C, T6D, T6E, T6F, T70, T71, T72, T73,\n"
|
|
" T74, T75, T76, T77, T78, T79, T7A, T7B,\n"
|
|
" T7C, T7D, T7E\n\n"
|
|
"};\n\n");
|
|
|
|
/* Key name table header */
|
|
fprintf(FileHandle, "static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = {\n");
|
|
|
|
/* Loop 110-key table */
|
|
for (i = 0; i < 110; i++)
|
|
{
|
|
/* Check for non-extended keys */
|
|
if ((Layout->Entry[i].ScanCode & 0xFF00) == 0xE000)
|
|
{
|
|
/* Which are valid */
|
|
if (Layout->Entry[i].ScanCode != 0xFF)
|
|
{
|
|
/* And mapped */
|
|
if (Layout->Entry[i].VirtualKey != 0xFF)
|
|
{
|
|
/* Output them */
|
|
fprintf(FileHandle,
|
|
" { 0x%02X, X%02X | KBDEXT }, // %s\n",
|
|
Layout->Entry[i].ScanCode,
|
|
Layout->Entry[i].ScanCode,
|
|
Layout->Entry[i].Name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Key name table finish */
|
|
fprintf(FileHandle, " { 0, 0 }\n};\n\n");
|
|
|
|
/* Extended key name table header */
|
|
fprintf(FileHandle, "static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = {\n");
|
|
|
|
/* Loop 110-key table */
|
|
for (i = 0; i < 110; i++)
|
|
{
|
|
/* Check for extended keys */
|
|
if ((Layout->Entry[i].ScanCode & 0xFF00) == 0xE100)
|
|
{
|
|
/* Which are valid */
|
|
if (Layout->Entry[i].ScanCode != 0xFF)
|
|
{
|
|
/* And mapped */
|
|
if (Layout->Entry[i].VirtualKey != 0xFF)
|
|
{
|
|
/* Output them */
|
|
fprintf(FileHandle,
|
|
" { 0x%02X, Y%02X | KBDEXT }, // %s\n",
|
|
Layout->Entry[i].ScanCode,
|
|
Layout->Entry[i].ScanCode,
|
|
Layout->Entry[i].Name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Extended key name table finish */
|
|
fprintf(FileHandle,
|
|
" { 0x1D, Y1D }, // Pause\n"
|
|
" { 0 , 0 }\n};\n\n");
|
|
|
|
/* Modifier table description */
|
|
fprintf(FileHandle,
|
|
"/***************************************************************************\\\n"
|
|
"* aVkToBits[] - map Virtual Keys to Modifier Bits\n"
|
|
"*\n"
|
|
"* See kbd.h for a full description.\n"
|
|
"*\n"
|
|
"* The keyboard has only three shifter keys:\n"
|
|
"* SHIFT (L & R) affects alphabnumeric keys,\n"
|
|
"* CTRL (L & R) is used to generate control characters\n"
|
|
"* ALT (L & R) used for generating characters by number with numpad\n"
|
|
"\\***************************************************************************/\n");
|
|
|
|
/* Modifier table header */
|
|
fprintf(FileHandle, "static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = {\n");
|
|
|
|
/* Loop modifier table */
|
|
i = 0;
|
|
Entry = &Modifiers[0];
|
|
while (Entry->VirtualKey)
|
|
{
|
|
/* Print out entry */
|
|
fprintf(FileHandle,
|
|
" { %-12s, %-12s },\n",
|
|
getVKName(Entry->VirtualKey, 1),
|
|
Entry->Name);
|
|
|
|
/* Move to the next one */
|
|
Entry = &Modifiers[++i];
|
|
}
|
|
|
|
/* Modifier table finish */
|
|
fprintf(FileHandle, " { 0, 0 }\n};\n\n");
|
|
|
|
/* Modifier conversion table description */
|
|
fprintf(FileHandle,
|
|
"/***************************************************************************\\\n"
|
|
"* aModification[] - map character modifier bits to modification number\n"
|
|
"*\n"
|
|
"* See kbd.h for a full description.\n"
|
|
"*\n"
|
|
"\\***************************************************************************/\n\n");
|
|
|
|
/* Zero out local state data */
|
|
for (i = 0; i < 8; i++) States[i] = -1;
|
|
|
|
/* Find the highest set state */
|
|
for (HighestState = 1, i = 0; (i < 8) && (ShiftStates[i] != -1); i++)
|
|
{
|
|
/* Save all state values */
|
|
States[ShiftStates[i]] = i;
|
|
if (ShiftStates[i] > HighestState) HighestState = ShiftStates[i];
|
|
}
|
|
|
|
/* Modifier conversion table header */
|
|
fprintf(FileHandle,
|
|
"static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = {\n"
|
|
" &aVkToBits[0],\n"
|
|
" %d,\n"
|
|
" {\n"
|
|
" // Modification# // Keys Pressed\n"
|
|
" // ============= // =============\n",
|
|
HighestState);
|
|
|
|
/* Loop states */
|
|
for (i = 0; i <= HighestState; i++)
|
|
{
|
|
/* Check for invalid state */
|
|
if (States[i] == -1)
|
|
{
|
|
/* Invalid state header */
|
|
fprintf(FileHandle, " SHFT_INVALID, // ");
|
|
}
|
|
else
|
|
{
|
|
/* Is this the last one? */
|
|
if (i == HighestState)
|
|
{
|
|
/* Last state header */
|
|
fprintf(FileHandle, " %d // ", States[i]);
|
|
}
|
|
else
|
|
{
|
|
/* Normal state header */
|
|
fprintf(FileHandle, " %d, // ", States[i]);
|
|
}
|
|
|
|
/* State 1 or higher? */
|
|
if (i >= 1)
|
|
{
|
|
/* J is the loop variable, K is the double */
|
|
for (NeedPlus = 0, j = 0, k = 1; (1u << j) <= i; j++, k = (1 << j))
|
|
{
|
|
/* Do we need to add a plus? */
|
|
if (NeedPlus)
|
|
{
|
|
/* Add it */
|
|
fprintf(FileHandle, "+");
|
|
NeedPlus = FALSE;
|
|
}
|
|
|
|
/* Check if it's time to add a modifier */
|
|
if (i & k)
|
|
{
|
|
/* Get the key state name and copy it into our buffer */
|
|
strcpy(KeyNameBuffer, getVKName(Modifiers[j].VirtualKey, 1));
|
|
|
|
/* Go go the 4th char (past the "KBD") and lower name */
|
|
for (p = &KeyNameBuffer[4]; *p; p++) *p = tolower(*p);
|
|
|
|
/* Print it */
|
|
fprintf(FileHandle, "%s", &KeyNameBuffer[3]);
|
|
|
|
/* We'll need a plus sign next */
|
|
NeedPlus = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Terminate the entry */
|
|
fprintf(FileHandle, "\n");
|
|
}
|
|
}
|
|
|
|
|
|
/* Modifier conversion table end */
|
|
fprintf(FileHandle," }\n" "};\n\n");
|
|
|
|
/* Shift state translation table description */
|
|
fprintf(FileHandle,
|
|
"/***************************************************************************\\\n"
|
|
"*\n"
|
|
"* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states\n"
|
|
"* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states\n"
|
|
"* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states\n");
|
|
|
|
/* Check if there's exta shift states */
|
|
for (i = 5; i < HighestState; i++)
|
|
{
|
|
/* Print out extra information */
|
|
fprintf(FileHandle,
|
|
"* aVkToWch%d[] - Virtual Key to WCHAR translation for %d shift states\n",
|
|
i,
|
|
i);
|
|
}
|
|
|
|
/* Shift state translation table description continue */
|
|
fprintf(FileHandle,
|
|
"*\n"
|
|
"* Table attributes: Unordered Scan, null-terminated\n"
|
|
"*\n"
|
|
"* Search this table for an entry with a matching Virtual Key to find the\n"
|
|
"* corresponding unshifted and shifted WCHAR characters.\n"
|
|
"*\n"
|
|
"* Special values for VirtualKey (column 1)\n"
|
|
"* 0xff - dead chars for the previous entry\n"
|
|
"* 0 - terminate the list\n"
|
|
"*\n"
|
|
"* Special values for Attributes (column 2)\n"
|
|
"* CAPLOK bit - CAPS-LOCK affect this key like SHIFT\n"
|
|
"*\n"
|
|
"* Special values for wch[*] (column 3 & 4)\n"
|
|
"* WCH_NONE - No character\n"
|
|
"* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none)\n"
|
|
"* WCH_LGTR - Ligature (generates multiple characters)\n"
|
|
"*\n"
|
|
"\\***************************************************************************/\n\n");
|
|
|
|
/* Loop all the states */
|
|
for (i = 2; i <= StateCount; i++)
|
|
{
|
|
/* Check if this something else than state 2 */
|
|
if (i != 2)
|
|
{
|
|
/* Loop all the scan codes */
|
|
for (j = 0; j < 110; j++)
|
|
{
|
|
/* Check if this is the state for the entry */
|
|
if (i == Layout->Entry[j].StateCount) break;
|
|
}
|
|
}
|
|
|
|
/* Print the table header */
|
|
fprintf(FileHandle,
|
|
"static ALLOC_SECTION_LDATA VK_TO_WCHARS%d aVkToWch%d[] = {\n"
|
|
"// | | Shift |",
|
|
i,
|
|
i);
|
|
|
|
/* Print the correct state label */
|
|
for (k = 2; k < i; k++) fprintf(FileHandle, "%-9.9s|",
|
|
StateLabel[ShiftStates[k]]);
|
|
|
|
/* Print the next separator */
|
|
fprintf(FileHandle, "\n// |=========|=========|");
|
|
|
|
/* Check for extra states and print their separators too */
|
|
for (k = 2; k < i; k++) fprintf(FileHandle, "=========|");
|
|
|
|
/* Finalize the separator header */
|
|
fprintf(FileHandle, "\n");
|
|
|
|
/* Loop all the scan codes */
|
|
for (j = 0; j < 110; j++)
|
|
{
|
|
/* Check if this is the state for the entry */
|
|
if (i != Layout->Entry[j].StateCount) continue;
|
|
|
|
/* Print out the entry for this key */
|
|
fprintf(FileHandle,
|
|
" {%-13s,%-7s",
|
|
getVKName(Layout->Entry[j].VirtualKey, 1),
|
|
CapState[Layout->Entry[j].Cap]);
|
|
|
|
/* Initialize the buffer for this line */
|
|
*LineBuffer = '\0';
|
|
|
|
/* Loop states */
|
|
for (k = 0; k < i; k++)
|
|
{
|
|
/* Check for dead key data */
|
|
if (DeadKeyData)
|
|
{
|
|
/* Not yet supported */
|
|
printf("Dead key data not supported!\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* Check if it's a ligature key */
|
|
if (Layout->Entry[j].LigatureCharData[k])
|
|
{
|
|
/* Not yet supported */
|
|
printf("Ligature key data not supported!\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* Print out the WCH_ name */
|
|
fprintf(FileHandle,
|
|
",%-9s",
|
|
WChName(Layout->Entry[j].CharData[k], 0));
|
|
|
|
/* If we have something on the line buffer by now, add WCH_NONE */
|
|
if (*LineBuffer != '\0') strcpy(LineBuffer, "WCH_NONE ");
|
|
}
|
|
|
|
/* Finish the line */
|
|
fprintf(FileHandle, "},\n");
|
|
|
|
/* Do we have any data at all? */
|
|
if (*LineBuffer != '\0')
|
|
{
|
|
/* Print it, we're done */
|
|
fprintf(FileHandle, "%s},\n", LineBuffer);
|
|
continue;
|
|
}
|
|
|
|
/* Otherwise, we're done, unless this requires SGCAP data */
|
|
if (Layout->Entry[j].Cap != 2) continue;
|
|
|
|
/* Not yet supported */
|
|
printf("SGCAP not yet supported!\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* Did we only have two states? */
|
|
if (i == 2)
|
|
{
|
|
/* Print out the built-in table */
|
|
fprintf(FileHandle,
|
|
" {VK_TAB ,0 ,'\\t' ,'\\t' },\n"
|
|
" {VK_ADD ,0 ,'+' ,'+' },\n"
|
|
" {VK_DIVIDE ,0 ,'/' ,'/' },\n"
|
|
" {VK_MULTIPLY ,0 ,'*' ,'*' },\n"
|
|
" {VK_SUBTRACT ,0 ,'-' ,'-' },\n");
|
|
}
|
|
|
|
/* Terminate the table */
|
|
fprintf(FileHandle, " {0 ,0 ");
|
|
for (k = 0; k < i; k++) fprintf(FileHandle, ",0 ");
|
|
|
|
/* Terminate the structure */
|
|
fprintf(FileHandle, "}\n" "};\n\n");
|
|
}
|
|
|
|
/* Numpad translation table */
|
|
fprintf(FileHandle,
|
|
"// Put this last so that VkKeyScan interprets number characters\n"
|
|
"// as coming from the main section of the kbd (aVkToWch2 and\n"
|
|
"// aVkToWch5) before considering the numpad (aVkToWch1).\n\n"
|
|
"static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = {\n"
|
|
" { VK_NUMPAD0 , 0 , '0' },\n"
|
|
" { VK_NUMPAD1 , 0 , '1' },\n"
|
|
" { VK_NUMPAD2 , 0 , '2' },\n"
|
|
" { VK_NUMPAD3 , 0 , '3' },\n"
|
|
" { VK_NUMPAD4 , 0 , '4' },\n"
|
|
" { VK_NUMPAD5 , 0 , '5' },\n"
|
|
" { VK_NUMPAD6 , 0 , '6' },\n"
|
|
" { VK_NUMPAD7 , 0 , '7' },\n"
|
|
" { VK_NUMPAD8 , 0 , '8' },\n"
|
|
" { VK_NUMPAD9 , 0 , '9' },\n"
|
|
" { 0 , 0 , '\\0' }\n"
|
|
"};\n\n");
|
|
|
|
/* Translation tables header */
|
|
fprintf(FileHandle,"static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = {\n");
|
|
|
|
/* Loop states higher than 3 */
|
|
for (i = 3; i <= StateCount; i++)
|
|
{
|
|
/* Print out the extra tables */
|
|
fprintf(FileHandle,
|
|
" { (PVK_TO_WCHARS1)aVkToWch%d, %d, sizeof(aVkToWch%d[0]) },\n",
|
|
i,
|
|
i,
|
|
i);
|
|
}
|
|
|
|
/* Array of translation tables */
|
|
fprintf(FileHandle,
|
|
" { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) },\n"
|
|
" { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) },\n"
|
|
" { NULL, 0, 0 },\n"
|
|
"};\n\n");
|
|
|
|
/* Scan code to key name conversion table description */
|
|
fprintf(FileHandle,
|
|
"/***************************************************************************\\\n"
|
|
"* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables\n"
|
|
"*\n"
|
|
"* Table attributes: Ordered Scan (by scancode), null-terminated\n"
|
|
"*\n"
|
|
"* Only the names of Extended, NumPad, Dead and Non-Printable keys are here.\n"
|
|
"* (Keys producing printable characters are named by that character)\n"
|
|
"\\***************************************************************************/\n\n");
|
|
|
|
/* Check for key name data */
|
|
if (KeyNameData)
|
|
{
|
|
/* Table header */
|
|
fprintf(FileHandle, "static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNames[] = {\n");
|
|
|
|
/* Print table */
|
|
PrintNameTable(FileHandle, KeyNameData, FALSE);
|
|
|
|
/* Table end */
|
|
fprintf(FileHandle, "};\n\n");
|
|
}
|
|
|
|
/* Check for extended key name data */
|
|
if (KeyNameExtData)
|
|
{
|
|
/* Table header */
|
|
fprintf(FileHandle, "static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNamesExt[] = {\n");
|
|
|
|
/* Print table */
|
|
PrintNameTable(FileHandle, KeyNameExtData, FALSE);
|
|
|
|
/* Table end */
|
|
fprintf(FileHandle, "};\n\n");
|
|
}
|
|
|
|
/* Check for dead key name data */
|
|
if (KeyNameDeadData)
|
|
{
|
|
/* Not yet supported */
|
|
printf("Dead key name data not supported!\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* Check for dead key data */
|
|
if (DeadKeyData)
|
|
{
|
|
/* Not yet supported */
|
|
printf("Dead key data not supported!\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* Check for ligature data */
|
|
if (LigatureData)
|
|
{
|
|
/* Not yet supported */
|
|
printf("Ligature key data not supported!\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* Main keyboard table descriptor type */
|
|
fprintf(FileHandle, "static ");
|
|
|
|
/* FIXME? */
|
|
|
|
/* Main keyboard table descriptor header */
|
|
fprintf(FileHandle,
|
|
"ALLOC_SECTION_LDATA KBDTABLES KbdTables%s = {\n"
|
|
" /*\n"
|
|
" * Modifier keys\n"
|
|
" */\n"
|
|
" &CharModifiers,\n\n"
|
|
" /*\n"
|
|
" * Characters tables\n"
|
|
" */\n"
|
|
" aVkToWcharTable,\n\n"
|
|
" /*\n"
|
|
" * Diacritics\n"
|
|
" */\n",
|
|
FallbackDriver ? "Fallback" : "" );
|
|
|
|
/* Descriptor dead key data section */
|
|
if (DeadKeyData)
|
|
{
|
|
fprintf(FileHandle, " aDeadKey,\n\n");
|
|
}
|
|
else
|
|
{
|
|
fprintf(FileHandle, " NULL,\n\n");
|
|
}
|
|
|
|
/* Descriptor key name comment */
|
|
fprintf(FileHandle,
|
|
" /*\n"
|
|
" * Names of Keys\n"
|
|
" */\n");
|
|
|
|
/* Descriptor key name section */
|
|
if (KeyNameData)
|
|
{
|
|
fprintf(FileHandle, " aKeyNames,\n");
|
|
}
|
|
else
|
|
{
|
|
fprintf(FileHandle, " NULL,\n");
|
|
}
|
|
|
|
/* Descriptor extended key name section */
|
|
if (KeyNameExtData)
|
|
{
|
|
fprintf(FileHandle, " aKeyNamesExt,\n");
|
|
}
|
|
else
|
|
{
|
|
fprintf(FileHandle, " NULL,\n");
|
|
}
|
|
|
|
/* Descriptor dead key name section */
|
|
if ((DeadKeyData) && (KeyNameDeadData))
|
|
{
|
|
fprintf(FileHandle, " aKeyNamesDead,\n\n");
|
|
}
|
|
else
|
|
{
|
|
fprintf(FileHandle, " NULL,\n\n");
|
|
}
|
|
|
|
/* Descriptor conversion table section */
|
|
fprintf(FileHandle,
|
|
" /*\n"
|
|
" * Scan codes to Virtual Keys\n"
|
|
" */\n"
|
|
" ausVK,\n"
|
|
" sizeof(ausVK) / sizeof(ausVK[0]),\n"
|
|
" aE0VscToVk,\n"
|
|
" aE1VscToVk,\n\n"
|
|
" /*\n"
|
|
" * Locale-specific special processing\n"
|
|
" */\n");
|
|
|
|
/* FIXME: AttributeData and KLLF_ALTGR stuff */
|
|
|
|
/* Descriptor locale-specific section */
|
|
fprintf(FileHandle, " MAKELONG(%s, KBD_VERSION),\n\n", "0"); /* FIXME */
|
|
|
|
/* Descriptor ligature data comment */
|
|
fprintf(FileHandle, " /*\n * Ligatures\n */\n %d,\n", 0); /* FIXME */
|
|
|
|
/* Descriptor ligature data section */
|
|
if (!LigatureData)
|
|
{
|
|
fprintf(FileHandle, " 0,\n");
|
|
fprintf(FileHandle, " NULL\n");
|
|
}
|
|
else
|
|
{
|
|
fprintf(FileHandle, " sizeof(aLigature[0]),\n");
|
|
fprintf(FileHandle, " (PLIGATURE1)aLigature\n");
|
|
}
|
|
|
|
/* Descriptor finish */
|
|
fprintf(FileHandle, "};\n\n");
|
|
|
|
/* Keyboard layout callback function */
|
|
if (!FallbackDriver) fprintf(FileHandle,
|
|
"PKBDTABLES KbdLayerDescriptor(VOID)\n"
|
|
"{\n"
|
|
" return &KbdTables;\n"
|
|
"}\n");
|
|
|
|
/* Clean up */
|
|
fclose(FileHandle);
|
|
return TRUE;
|
|
}
|
|
|
|
ULONG
|
|
DoOutput(IN ULONG StateCount,
|
|
IN PULONG ShiftStates,
|
|
IN PKEYNAME DescriptionData,
|
|
IN PKEYNAME LanguageData,
|
|
IN PVOID AttributeData,
|
|
IN PVOID DeadKeyData,
|
|
IN PVOID LigatureData,
|
|
IN PKEYNAME KeyNameData,
|
|
IN PKEYNAME KeyNameExtData,
|
|
IN PKEYNAME KeyNameDeadData)
|
|
{
|
|
ULONG FailureCode = 0;
|
|
|
|
/* Take the time */
|
|
time(&Clock);
|
|
Now = localtime(&Clock);
|
|
|
|
/* Check if this just a fallback driver*/
|
|
if (!FallbackDriver)
|
|
{
|
|
/* It's not, create header file */
|
|
if (!kbd_h(&g_Layout)) FailureCode = 1;
|
|
|
|
/* Create the resource file */
|
|
if (!kbd_rc(DescriptionData, LanguageData)) FailureCode = 2;
|
|
}
|
|
|
|
/* Create the C file */
|
|
if (!kbd_c(StateCount,
|
|
ShiftStates,
|
|
AttributeData,
|
|
&g_Layout,
|
|
DeadKeyData,
|
|
LigatureData,
|
|
KeyNameData,
|
|
KeyNameExtData,
|
|
KeyNameDeadData))
|
|
{
|
|
/* Failed in C file generation */
|
|
FailureCode = 3;
|
|
}
|
|
|
|
/* Check if this just a fallback driver*/
|
|
if (!FallbackDriver)
|
|
{
|
|
/* Generate the definition file */
|
|
if (!kbd_def()) FailureCode = 4;
|
|
}
|
|
|
|
/* Done */
|
|
return FailureCode;
|
|
}
|
|
|
|
|
|
/* EOF */
|