Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenoutput.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Build Tools [Keyboard Layout Compiler] 00003 * LICENSE: BSD - See COPYING.BSD in the top level directory 00004 * FILE: tools/kbdtool/output.c 00005 * PURPOSE: Output Logic (Source Builder) 00006 * PROGRAMMERS: ReactOS Foundation 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include "kbdtool.h" 00012 00013 /* GLOBALS ********************************************************************/ 00014 00015 ULONG gStringIdForDescriptions = 1000; 00016 ULONG gStringIdForLanguageNames = 1100; 00017 ULONG gStringIdForLocaleName = 1200; 00018 time_t Clock; 00019 struct tm *Now; 00020 CHAR gCharName[32]; 00021 00022 /* FUNCTIONS ******************************************************************/ 00023 00024 PCHAR 00025 WChName(IN ULONG Char, 00026 IN BOOLEAN AddZero) 00027 { 00028 PCHAR p; 00029 00030 /* Check for invalid character */ 00031 if (Char == -1) 00032 { 00033 /* No name */ 00034 strcpy(gCharName, "WCH_NONE"); 00035 } 00036 else if ((Char > 31) && (Char < 128)) 00037 { 00038 /* Use our global buffer */ 00039 p = gCharName; 00040 00041 /* Add the first quote unless this was a zero-string */ 00042 if (!AddZero) *p++ = '\''; 00043 00044 /* Now replace any other quote or comment character with a slash */ 00045 if ((Char == '\"') || (Char == '\'') || (Char == '\\')) *p++ = '\\'; 00046 00047 /* Now plug in the character */ 00048 *p++ = Char; 00049 00050 /* And add the terminating quote, unless this was a zero-string */ 00051 if (!AddZero) *p++ = '\''; 00052 00053 /* Terminate the buffer */ 00054 *p = '\0'; 00055 } 00056 else 00057 { 00058 /* Handle special cases */ 00059 if (Char == '\b') 00060 { 00061 /* Bell */ 00062 strcpy(gCharName, "'\\b'"); 00063 } 00064 else if (Char == '\n') 00065 { 00066 /* New line */ 00067 strcpy(gCharName, "'\\n'"); 00068 } 00069 else if (Char == '\r') 00070 { 00071 /* Return */ 00072 strcpy(gCharName, "'\\r'"); 00073 } 00074 else if (!AddZero) 00075 { 00076 /* Char value, in hex */ 00077 sprintf(gCharName, "0x%04x", Char); 00078 } 00079 else 00080 { 00081 /* Char value, C-style */ 00082 sprintf(gCharName, "\\x%04x", Char); 00083 } 00084 } 00085 00086 /* Return the name */ 00087 return gCharName; 00088 } 00089 00090 VOID 00091 PrintNameTable(FILE* FileHandle, 00092 PKEYNAME KeyName, 00093 BOOL DeadKey) 00094 { 00095 CHAR CharBuffer[255]; 00096 PKEYNAME NextName; 00097 PCHAR Name, Buffer; 00098 ULONG i; 00099 00100 /* Loop all key names */ 00101 while (KeyName) 00102 { 00103 /* Go to the next key name */ 00104 NextName = KeyName->Next; 00105 00106 /* Remember the name and our buffer address */ 00107 Name = KeyName->Name; 00108 Buffer = CharBuffer; 00109 00110 /* Check if it's an IDS name */ 00111 if (strncmp(Name, "IDS_", 4)) 00112 { 00113 /* No, so start parsing it. First, handle initial quote */ 00114 if (*Name != '\"') *Buffer++ = '\"'; 00115 00116 /* Next, parse the name */ 00117 while (*Name) 00118 { 00119 /* Check if this is a C-style hex string */ 00120 if ((*Name != '\\') || ((*(Name + 1) != 'x') && (*(Name + 1) != 'X'))) 00121 { 00122 /* It's not, so just copy straight into our buffer */ 00123 *Buffer++ = *Name++; 00124 } 00125 else 00126 { 00127 /* Continue scanning as long as this is a C-style hex string */ 00128 while ((*Name == '\\') && ((*(Name + 1) == 'x') || (*(Name + 1) == 'X'))) 00129 { 00130 /* Copy 6 characters */ 00131 for (i = 0; (*Name) && (i < 6); i++) *Buffer++ = *Name++; 00132 } 00133 00134 /* Check if we still have something at the end */ 00135 if (*Name) 00136 { 00137 /* Terminate our buffer */ 00138 *Buffer++ = '\"'; 00139 *Buffer++ = ' '; 00140 *Buffer++ = 'L'; 00141 *Buffer++ = '\"'; 00142 } 00143 } 00144 } 00145 00146 /* Check for terminating quote */ 00147 if (*(Buffer - 1) != '\"') *Buffer++ = '\"'; 00148 00149 /* Terminate the buffer */ 00150 *Buffer++ = '\0'; 00151 } 00152 else 00153 { 00154 /* Not yet supported */ 00155 printf("IDS Entries not yet handled!\n"); 00156 exit(1); 00157 } 00158 00159 /* Is this a dead key? */ 00160 if (DeadKey) 00161 { 00162 /* Not yet handled */ 00163 printf("Dead keys not yet handled\n"); 00164 exit(1); 00165 } 00166 else 00167 { 00168 /* Print the entry */ 00169 fprintf(FileHandle, " 0x%02x, L%s,\n", KeyName->Code, CharBuffer); 00170 } 00171 00172 /* Cleanup allocation */ 00173 free(KeyName->Name); 00174 free(KeyName); 00175 00176 /* Move on */ 00177 KeyName = NextName; 00178 } 00179 00180 /* Is this a dead key? */ 00181 if (DeadKey) 00182 { 00183 /* Not yet handled */ 00184 printf("Dead keys not yet handled\n"); 00185 exit(1); 00186 } 00187 else 00188 { 00189 /* Terminate the table */ 00190 fprintf(FileHandle, " 0 , NULL\n"); 00191 } 00192 } 00193 00194 BOOLEAN 00195 kbd_h(IN PLAYOUT Layout) 00196 { 00197 CHAR OutputFile[13]; 00198 FILE *FileHandle; 00199 ULONG i; 00200 CHAR UndefChar; 00201 USHORT SubCode; 00202 00203 /* Build the keyboard name */ 00204 strcpy(OutputFile, gKBDName); 00205 strcat(OutputFile, ".H"); 00206 00207 /* Open it */ 00208 FileHandle = fopen(OutputFile, "wt"); 00209 if (!FileHandle) 00210 { 00211 /* Fail */ 00212 printf(" %12s : can't open for write.\n", OutputFile); 00213 return FALSE; 00214 } 00215 00216 /* Print the module header */ 00217 fprintf(FileHandle, 00218 "/****************************** Module Header ******************************\\\n" 00219 "* Module Name: %s\n*\n* keyboard layout header\n" 00220 "*\n" 00221 "* Copyright (c) 2009, ReactOS Foundation\n" 00222 "*\n" 00223 "* Various defines for use by keyboard input code.\n*\n* History:\n" 00224 "*\n" 00225 "* created by KBDTOOL v%d.%02d %s*\n" 00226 "\\***************************************************************************/\n\n", 00227 OutputFile, 00228 gVersion, 00229 gSubVersion, 00230 asctime(Now)); 00231 00232 /* Print out the includes and defines */ 00233 fprintf(FileHandle, 00234 "/*\n" 00235 " * kbd type should be controlled by cl command-line argument\n" 00236 " *\\n" 00237 "#define KBD_TYPE 4\n\n" 00238 "/*\n" 00239 "* Include the basis of all keyboard table values\n" 00240 "*/\n" 00241 "#include \"kbd.h\"\n"); 00242 00243 /* Now print out the virtual key conversion table */ 00244 fprintf(FileHandle, 00245 "/***************************************************************************\\\n" 00246 "* The table below defines the virtual keys for various keyboard types where\n" 00247 "* the keyboard differ from the US keyboard.\n" 00248 "*\n" 00249 "* _EQ() : all keyboard types have the same virtual key for this scancode\n" 00250 "* _NE() : different virtual keys for this scancode, depending on kbd type\n" 00251 "*\n" 00252 "* +------+ +----------+----------+----------+----------+----------+----------+\n" 00253 "* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd |\n" 00254 "* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 |\n" 00255 "\\****+-------+_+----------+----------+----------+----------+----------+----------+*/\n\n"); 00256 00257 /* Loop all keys */ 00258 for (i = 0; i < 110; i++) 00259 { 00260 /* Check if we processed this key */ 00261 if (Layout->Entry[i].Processed) 00262 { 00263 /* Check if it redefined a virtual key */ 00264 if (Layout->Entry[i].VirtualKey != Layout->Entry[i].OriginalVirtualKey) 00265 { 00266 /* Do we have a subcode? */ 00267 SubCode = Layout->Entry[i].ScanCode & 0xFF00; 00268 if (SubCode) 00269 { 00270 /* Which kind is it? */ 00271 if (SubCode == 0xE000) 00272 { 00273 /* Extended 0 */ 00274 UndefChar = 'X'; 00275 } 00276 else 00277 { 00278 /* Illegal */ 00279 if (SubCode != 0xE100) 00280 { 00281 /* Unrecognized */ 00282 printf("Weird scancode value %04x: expected xx, E0xx, or E1xx\n", SubCode); 00283 exit(1); 00284 } 00285 00286 /* Extended 1 */ 00287 UndefChar = 'Y'; 00288 } 00289 } 00290 else 00291 { 00292 /* Normal key */ 00293 UndefChar = 'T'; 00294 } 00295 00296 /* Print out the virtual key redefinition */ 00297 fprintf(FileHandle, 00298 "#undef %c%02X\n#define %c%02X _EQ(%43s%23s\n", 00299 UndefChar, 00300 Layout->Entry[i].ScanCode, 00301 UndefChar, 00302 Layout->Entry[i].ScanCode, 00303 getVKName(Layout->Entry[i].VirtualKey, 0), 00304 ")"); 00305 } 00306 } 00307 } 00308 00309 /* Cleanup and close */ 00310 fprintf(FileHandle,"\n"); 00311 fclose(FileHandle); 00312 00313 /* We made it */ 00314 return TRUE; 00315 } 00316 00317 BOOLEAN 00318 kbd_rc(IN PKEYNAME DescriptionData, 00319 IN PKEYNAME LanguageData) 00320 { 00321 CHAR OutputFile[13]; 00322 CHAR InternalName[13]; 00323 CHAR TimeBuffer[5]; 00324 FILE *FileHandle; 00325 ULONG Length; 00326 PCHAR p; 00327 PKEYNAME NextDescription, NextLanguage; 00328 00329 /* Build the keyboard name and internal name */ 00330 strcpy(OutputFile, gKBDName); 00331 strcat(OutputFile, ".RC"); 00332 strcpy(InternalName, gKBDName); 00333 for (p = InternalName; *p; p++) *p = tolower(*p); 00334 00335 /* Open it */ 00336 FileHandle = fopen(OutputFile, "wb"); 00337 if (!FileHandle) 00338 { 00339 /* Fail */ 00340 printf(" %12s : can't open for write.\n", OutputFile); 00341 return FALSE; 00342 } 00343 00344 /* Check if we have copyright */ 00345 Length = strlen(gCopyright); 00346 if (!Length) 00347 { 00348 /* Set time string */ 00349 strftime(TimeBuffer, 5, "%Y", Now); 00350 00351 /* Add copyright character */ 00352 strcpy(gCopyright, "(C)"); 00353 00354 /* Add the year */ 00355 strcat(gCopyright, TimeBuffer); 00356 00357 /* Add blank company */ 00358 strcat(gCopyright, " "); 00359 } 00360 00361 /* Write the resource file header */ 00362 fprintf(FileHandle, 00363 "#include \"winver.h\"\r\n" 00364 "1 VERSIONINFO\r\n" 00365 " FILEVERSION 1,0,%d,%d\r\n" 00366 " PRODUCTVERSION 1,0,%d,%d\r\n" 00367 " FILEFLAGSMASK 0x3fL\r\n" 00368 " FILEFLAGS 0x0L\r\n" 00369 "FILEOS 0x40004L\r\n" 00370 " FILETYPE VFT_DLL\r\n" 00371 " FILESUBTYPE VFT2_DRV_KEYBOARD\r\n" 00372 "BEGIN\r\n" 00373 " BLOCK \"StringFileInfo\"\r\n" 00374 " BEGIN\r\n" 00375 " BLOCK \"000004B0\"\r\n" 00376 " BEGIN\r\n" 00377 " VALUE \"CompanyName\", \"%s\\0\"\r\n" 00378 " VALUE \"FileDescription\", \"%s Keyboard Layout\\0\"\r\n" 00379 " VALUE \"FileVersion\", \"1, 0, %d, %d\\0\"\r\n", 00380 gVersion, 00381 gSubVersion, 00382 gVersion, 00383 gSubVersion, 00384 gCompany, 00385 gDescription, 00386 gVersion, 00387 gSubVersion); 00388 00389 /* Continue writing it */ 00390 fprintf(FileHandle, 00391 " VALUE \"InternalName\", \"%s (%d.%d)\\0\"\r\n" 00392 " VALUE \"ProductName\",\"%s\\0\"\r\n" 00393 " VALUE \"Release Information\",\"%s\\0\"\r\n" 00394 " VALUE \"LegalCopyright\", \"%s\\0\"\r\n" 00395 " VALUE \"OriginalFilename\",\"%s\\0\"\r\n" 00396 " VALUE \"ProductVersion\", \"1, 0, %d, %d\\0\"\r\n" 00397 " END\r\n" 00398 " END\r\n" 00399 " BLOCK \"VarFileInfo\"\r\n" 00400 " BEGIN\r\n" 00401 " VALUE \"Translation\", 0x0000, 0x04B0\r\n" 00402 " END\r\n" 00403 "END\r\n", 00404 InternalName, 00405 gVersion, 00406 gSubVersion, 00407 "Created by ReactOS KbdTool", 00408 "Created by ReactOS KbdTool", 00409 gCopyright, 00410 InternalName, 00411 gVersion, 00412 gSubVersion); 00413 00414 /* Now check if we have a locale name */ 00415 Length = strlen(gLocaleName); 00416 if (Length) 00417 { 00418 /* Write the stringtable header */ 00419 fprintf(FileHandle, 00420 "\r\nSTRINGTABLE DISCARDABLE\r\nLANGUAGE %d, %d\r\n", 00421 9, 00422 1); 00423 fprintf(FileHandle, "BEGIN\r\n"); 00424 00425 /* Language or locale? */ 00426 if (strchr(gLocaleName, '\"')) 00427 { 00428 /* Write the language name */ 00429 fprintf(FileHandle, " %d %s\r\n", gStringIdForLanguageNames, gLocaleName); 00430 } 00431 else 00432 { 00433 /* Write the locale name */ 00434 fprintf(FileHandle, " %d \"%s\"\r\n", gStringIdForLocaleName, gLocaleName); 00435 } 00436 00437 /* Terminate the entry */ 00438 fprintf(FileHandle, "END\r\n\r\n"); 00439 } 00440 00441 /* Check for description information */ 00442 while (DescriptionData) 00443 { 00444 /* Remember the next pointer */ 00445 NextDescription = DescriptionData->Next; 00446 00447 /* Write the header */ 00448 fprintf(FileHandle, 00449 "\r\nSTRINGTABLE DISCARDABLE\r\nLANGUAGE %d, %d\r\n", 00450 DescriptionData->Code & 0x3FF, 00451 DescriptionData->Code >> 10); 00452 fprintf(FileHandle, "BEGIN\r\n"); 00453 00454 /* Quoted string or not? */ 00455 if (strchr(DescriptionData->Name, '\"')) 00456 { 00457 /* Write the description name */ 00458 fprintf(FileHandle, " %d %s\r\n", gStringIdForDescriptions, DescriptionData->Name); 00459 } 00460 else 00461 { 00462 /* Write the description name */ 00463 fprintf(FileHandle, " %d \"%s\"\r\n", gStringIdForDescriptions, DescriptionData->Name); 00464 } 00465 00466 /* Terminate the entry */ 00467 fprintf(FileHandle, "END\r\n\r\n"); 00468 00469 /* Free the allocation */ 00470 free(DescriptionData->Name); 00471 free(DescriptionData); 00472 00473 /* Move to the next entry */ 00474 DescriptionData = NextDescription; 00475 } 00476 00477 /* Check for language information */ 00478 while (LanguageData) 00479 { 00480 /* Remember the next pointer */ 00481 NextLanguage = LanguageData->Next; 00482 00483 /* Write the header */ 00484 fprintf(FileHandle, 00485 "\r\nSTRINGTABLE DISCARDABLE\r\nLANGUAGE %d, %d\r\n", 00486 LanguageData->Code & 0x3FF, 00487 LanguageData->Code >> 10); 00488 fprintf(FileHandle, "BEGIN\r\n"); 00489 00490 /* Quoted string or not? */ 00491 if (strchr(LanguageData->Name, '\"')) 00492 { 00493 /* Write the language name */ 00494 fprintf(FileHandle, " %d %s\r\n", gStringIdForLanguageNames, LanguageData->Name); 00495 } 00496 else 00497 { 00498 /* Write the language name */ 00499 fprintf(FileHandle, " %d \"%s\"\r\n", gStringIdForLanguageNames, LanguageData->Name); 00500 } 00501 00502 /* Terminate the entry */ 00503 fprintf(FileHandle, "END\r\n\r\n"); 00504 00505 /* Free the allocation */ 00506 free(LanguageData->Name); 00507 free(LanguageData); 00508 00509 /* Move to the next entry */ 00510 LanguageData = NextLanguage; 00511 } 00512 00513 /* We're done! */ 00514 fclose(FileHandle); 00515 return TRUE; 00516 } 00517 00518 BOOLEAN 00519 kbd_def(VOID) 00520 { 00521 CHAR OutputFile[13]; 00522 FILE *FileHandle; 00523 00524 /* Build the keyboard name and internal name */ 00525 strcpy(OutputFile, gKBDName); 00526 strcat(OutputFile, ".DEF"); 00527 00528 /* Open it */ 00529 FileHandle = fopen(OutputFile, "wt"); 00530 if (!FileHandle) 00531 { 00532 /* Fail */ 00533 printf(" %12s : can't open for write.\n", OutputFile); 00534 return FALSE; 00535 } 00536 00537 /* Write the file exports */ 00538 fprintf(FileHandle, 00539 "LIBRARY %s\n\n" 00540 "EXPORTS\n" 00541 " KbdLayerDescriptor @1\n", 00542 gKBDName); 00543 00544 /* Clean up */ 00545 fclose(FileHandle); 00546 return TRUE; 00547 } 00548 00549 BOOLEAN 00550 kbd_c(IN ULONG StateCount, 00551 IN PULONG ShiftStates, 00552 IN PVOID AttributeData, 00553 IN PLAYOUT Layout, 00554 IN PVOID DeadKeyData, 00555 IN PVOID LigatureData, 00556 IN PKEYNAME KeyNameData, 00557 IN PKEYNAME KeyNameExtData, 00558 IN PKEYNAME KeyNameDeadData) 00559 { 00560 CHAR OutputFile[13]; 00561 CHAR KeyNameBuffer[50]; 00562 CHAR LineBuffer[256]; 00563 BOOLEAN NeedPlus; 00564 FILE *FileHandle; 00565 ULONG States[8]; 00566 ULONG i, j, k; 00567 ULONG HighestState; 00568 PVKNAME Entry; 00569 PCHAR p; 00570 00571 /* Build the keyboard name and internal name */ 00572 strcpy(OutputFile, gKBDName); 00573 strcat(OutputFile, ".C"); 00574 00575 /* Open it */ 00576 FileHandle = fopen(OutputFile, "wt"); 00577 if (!FileHandle) 00578 { 00579 /* Fail */ 00580 printf(" %12s : can't open for write.\n", OutputFile); 00581 return FALSE; 00582 } 00583 00584 /* Print the header */ 00585 fprintf(FileHandle, 00586 "/***************************************************************************\\\n" 00587 "* Module Name: %s\n*\n* keyboard layout\n" 00588 "*\n" 00589 "* Copyright (c) 2009, ReactOS Foundation\n" 00590 "*\n" 00591 "* History:\n" 00592 "* KBDTOOL v%d.%02d - Created %s" 00593 "\\***************************************************************************/\n\n", 00594 OutputFile, 00595 gVersion, 00596 gSubVersion, 00597 asctime(Now)); 00598 00599 /* What kind of driver is this? */ 00600 if (FallbackDriver) 00601 { 00602 /* Fallback only */ 00603 fprintf(FileHandle, "#include \"precomp.h\"\n"); 00604 } 00605 else 00606 { 00607 /* Add the includes */ 00608 fprintf(FileHandle, 00609 "#include <windows.h>\n" 00610 "#include \"kbd.h\"\n" 00611 "#include \"%s.h\"\n\n", 00612 gKBDName); 00613 } 00614 00615 /* What kind of driver is this? */ 00616 if (FallbackDriver) 00617 { 00618 /* Only one section */ 00619 fprintf(FileHandle, 00620 "#pragma data_seg(\"%s\")\n#define ALLOC_SECTION_LDATA\n\n", 00621 ".kbdfallback"); 00622 } 00623 else 00624 { 00625 /* Section and attributes depend on architecture */ 00626 fprintf(FileHandle, 00627 "#if defined(_M_IA64)\n" 00628 "#pragma section(\"%s\")\n" 00629 "#define ALLOC_SECTION_LDATA __declspec(allocate(\"%s\"))\n" 00630 "#else\n" 00631 "#pragma data_seg(\"%s\")\n" 00632 "#define ALLOC_SECTION_LDATA\n" 00633 "#endif\n\n", 00634 ".data", 00635 ".data", 00636 ".data"); 00637 } 00638 00639 /* Scan code to virtual key conversion table header */ 00640 fprintf(FileHandle, 00641 "/***************************************************************************\\\n" 00642 "* ausVK[] - Virtual Scan Code to Virtual Key conversion table\n" 00643 "\\***************************************************************************/\n\n"); 00644 00645 /* Table begin */ 00646 fprintf(FileHandle, 00647 "static ALLOC_SECTION_LDATA USHORT ausVK[] = {\n" 00648 " T00, T01, T02, T03, T04, T05, T06, T07,\n" 00649 " T08, T09, T0A, T0B, T0C, T0D, T0E, T0F,\n" 00650 " T10, T11, T12, T13, T14, T15, T16, T17,\n" 00651 " T18, T19, T1A, T1B, T1C, T1D, T1E, T1F,\n" 00652 " T20, T21, T22, T23, T24, T25, T26, T27,\n" 00653 " T28, T29, T2A, T2B, T2C, T2D, T2E, T2F,\n" 00654 " T30, T31, T32, T33, T34, T35,\n\n"); 00655 00656 /* Table continue */ 00657 fprintf(FileHandle, 00658 " /*\n" 00659 " * Right-hand Shift key must have KBDEXT bit set.\n" 00660 " */\n" 00661 " T36 | KBDEXT,\n\n" 00662 " T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot\n\n" 00663 " T38, T39, T3A, T3B, T3C, T3D, T3E,\n" 00664 " T3F, T40, T41, T42, T43, T44,\n\n"); 00665 00666 /* Table continue */ 00667 fprintf(FileHandle, 00668 " /*\n" 00669 " * NumLock Key:\n" 00670 " * KBDEXT - VK_NUMLOCK is an Extended key\n" 00671 " * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL)\n" 00672 " */\n" 00673 " T45 | KBDEXT | KBDMULTIVK,\n\n" 00674 " T46 | KBDMULTIVK,\n\n"); 00675 00676 /* Numpad table */ 00677 fprintf(FileHandle, 00678 " /*\n" 00679 " * Number Pad keys:\n" 00680 " * KBDNUMPAD - digits 0-9 and decimal point.\n" 00681 " * KBDSPECIAL - require special processing by Windows\n" 00682 " */\n" 00683 " T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home)\n" 00684 " T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up),\n" 00685 " T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp),\n" 00686 " T4A,\n" 00687 " T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left),\n" 00688 " T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear),\n" 00689 " T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right),\n" 00690 " T4E,\n" 00691 " T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End),\n" 00692 " T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down),\n" 00693 " T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn),\n" 00694 " T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins),\n" 00695 " T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del),\n\n"); 00696 00697 /* Table finish */ 00698 fprintf(FileHandle, 00699 " T54, T55, T56, T57, T58, T59, T5A, T5B,\n" 00700 " T5C, T5D, T5E, T5F, T60, T61, T62, T63,\n" 00701 " T64, T65, T66, T67, T68, T69, T6A, T6B,\n" 00702 " T6C, T6D, T6E, T6F, T70, T71, T72, T73,\n" 00703 " T74, T75, T76, T77, T78, T79, T7A, T7B,\n" 00704 " T7C, T7D, T7E\n\n" 00705 "};\n\n"); 00706 00707 /* Key name table header */ 00708 fprintf(FileHandle, "static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = {\n"); 00709 00710 /* Loop 110-key table */ 00711 for (i = 0; i < 110; i++) 00712 { 00713 /* Check for non-extended keys */ 00714 if ((Layout->Entry[i].ScanCode & 0xFF00) == 0xE000) 00715 { 00716 /* Which are valid */ 00717 if (Layout->Entry[i].ScanCode != 0xFF) 00718 { 00719 /* And mapped */ 00720 if (Layout->Entry[i].VirtualKey != 0xFF) 00721 { 00722 /* Output them */ 00723 fprintf(FileHandle, 00724 " { 0x%02X, X%02X | KBDEXT }, // %s\n", 00725 Layout->Entry[i].ScanCode, 00726 Layout->Entry[i].ScanCode, 00727 Layout->Entry[i].Name); 00728 } 00729 } 00730 } 00731 } 00732 00733 /* Key name table finish */ 00734 fprintf(FileHandle, " { 0, 0 }\n};\n\n"); 00735 00736 /* Extended key name table header */ 00737 fprintf(FileHandle, "static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = {\n"); 00738 00739 /* Loop 110-key table */ 00740 for (i = 0; i < 110; i++) 00741 { 00742 /* Check for extended keys */ 00743 if ((Layout->Entry[i].ScanCode & 0xFF00) == 0xE100) 00744 { 00745 /* Which are valid */ 00746 if (Layout->Entry[i].ScanCode != 0xFF) 00747 { 00748 /* And mapped */ 00749 if (Layout->Entry[i].VirtualKey != 0xFF) 00750 { 00751 /* Output them */ 00752 fprintf(FileHandle, 00753 " { 0x%02X, Y%02X | KBDEXT }, // %s\n", 00754 Layout->Entry[i].ScanCode, 00755 Layout->Entry[i].ScanCode, 00756 Layout->Entry[i].Name); 00757 } 00758 } 00759 } 00760 } 00761 00762 /* Extended key name table finish */ 00763 fprintf(FileHandle, 00764 " { 0x1D, Y1D }, // Pause\n" 00765 " { 0 , 0 }\n};\n\n"); 00766 00767 /* Modifier table description */ 00768 fprintf(FileHandle, 00769 "/***************************************************************************\\\n" 00770 "* aVkToBits[] - map Virtual Keys to Modifier Bits\n" 00771 "*\n" 00772 "* See kbd.h for a full description.\n" 00773 "*\n" 00774 "* The keyboard has only three shifter keys:\n" 00775 "* SHIFT (L & R) affects alphabnumeric keys,\n" 00776 "* CTRL (L & R) is used to generate control characters\n" 00777 "* ALT (L & R) used for generating characters by number with numpad\n" 00778 "\\***************************************************************************/\n"); 00779 00780 /* Modifier table header */ 00781 fprintf(FileHandle, "static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = {\n"); 00782 00783 /* Loop modifier table */ 00784 i = 0; 00785 Entry = &Modifiers[0]; 00786 while (Entry->VirtualKey) 00787 { 00788 /* Print out entry */ 00789 fprintf(FileHandle, 00790 " { %-12s, %-12s },\n", 00791 getVKName(Entry->VirtualKey, 1), 00792 Entry->Name); 00793 00794 /* Move to the next one */ 00795 Entry = &Modifiers[++i]; 00796 } 00797 00798 /* Modifier table finish */ 00799 fprintf(FileHandle, " { 0, 0 }\n};\n\n"); 00800 00801 /* Modifier conversion table description */ 00802 fprintf(FileHandle, 00803 "/***************************************************************************\\\n" 00804 "* aModification[] - map character modifier bits to modification number\n" 00805 "*\n" 00806 "* See kbd.h for a full description.\n" 00807 "*\n" 00808 "\\***************************************************************************/\n\n"); 00809 00810 /* Zero out local state data */ 00811 for (i = 0; i < 8; i++) States[i] = -1; 00812 00813 /* Find the highest set state */ 00814 for (HighestState = 1, i = 0; (i < 8) && (ShiftStates[i] != -1); i++) 00815 { 00816 /* Save all state values */ 00817 States[ShiftStates[i]] = i; 00818 if (ShiftStates[i] > HighestState) HighestState = ShiftStates[i]; 00819 } 00820 00821 /* Modifier conversion table header */ 00822 fprintf(FileHandle, 00823 "static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = {\n" 00824 " &aVkToBits[0],\n" 00825 " %d,\n" 00826 " {\n" 00827 " // Modification# // Keys Pressed\n" 00828 " // ============= // =============\n", 00829 HighestState); 00830 00831 /* Loop states */ 00832 for (i = 0; i <= HighestState; i++) 00833 { 00834 /* Check for invalid state */ 00835 if (States[i] == -1) 00836 { 00837 /* Invalid state header */ 00838 fprintf(FileHandle, " SHFT_INVALID, // "); 00839 } 00840 else 00841 { 00842 /* Is this the last one? */ 00843 if (i == HighestState) 00844 { 00845 /* Last state header */ 00846 fprintf(FileHandle, " %d // ", States[i]); 00847 } 00848 else 00849 { 00850 /* Normal state header */ 00851 fprintf(FileHandle, " %d, // ", States[i]); 00852 } 00853 00854 /* State 1 or higher? */ 00855 if (i >= 1) 00856 { 00857 /* J is the loop variable, K is the double */ 00858 for (NeedPlus = 0, j = 0, k = 1; (1 << j) <= i; j++, k = (1 << j)) 00859 { 00860 /* Do we need to add a plus? */ 00861 if (NeedPlus) 00862 { 00863 /* Add it */ 00864 fprintf(FileHandle, "+"); 00865 NeedPlus = FALSE; 00866 } 00867 00868 /* Check if it's time to add a modifier */ 00869 if (i & k) 00870 { 00871 /* Get the key state name and copy it into our buffer */ 00872 strcpy(KeyNameBuffer, getVKName(Modifiers[j].VirtualKey, 1)); 00873 00874 /* Go go the 4th char (past the "KBD") and lower name */ 00875 for (p = &KeyNameBuffer[4]; *p; p++) *p = tolower(*p); 00876 00877 /* Print it */ 00878 fprintf(FileHandle, "%s", &KeyNameBuffer[3]); 00879 00880 /* We'll need a plus sign next */ 00881 NeedPlus = TRUE; 00882 } 00883 } 00884 } 00885 00886 /* Terminate the entry */ 00887 fprintf(FileHandle, "\n"); 00888 } 00889 } 00890 00891 00892 /* Modifier conversion table end */ 00893 fprintf(FileHandle," }\n" "};\n\n"); 00894 00895 /* Shift state translation table description */ 00896 fprintf(FileHandle, 00897 "/***************************************************************************\\\n" 00898 "*\n" 00899 "* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states\n" 00900 "* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states\n" 00901 "* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states\n"); 00902 00903 /* Check if there's exta shift states */ 00904 for (i = 5; i < HighestState; i++) 00905 { 00906 /* Print out extra information */ 00907 fprintf(FileHandle, 00908 "* aVkToWch%d[] - Virtual Key to WCHAR translation for %d shift states\n", 00909 i, 00910 i); 00911 } 00912 00913 /* Shift state translation table description continue */ 00914 fprintf(FileHandle, 00915 "*\n" 00916 "* Table attributes: Unordered Scan, null-terminated\n" 00917 "*\n" 00918 "* Search this table for an entry with a matching Virtual Key to find the\n" 00919 "* corresponding unshifted and shifted WCHAR characters.\n" 00920 "*\n" 00921 "* Special values for VirtualKey (column 1)\n" 00922 "* 0xff - dead chars for the previous entry\n" 00923 "* 0 - terminate the list\n" 00924 "*\n" 00925 "* Special values for Attributes (column 2)\n" 00926 "* CAPLOK bit - CAPS-LOCK affect this key like SHIFT\n" 00927 "*\n" 00928 "* Special values for wch[*] (column 3 & 4)\n" 00929 "* WCH_NONE - No character\n" 00930 "* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none)\n" 00931 "* WCH_LGTR - Ligature (generates multiple characters)\n" 00932 "*\n" 00933 "\\***************************************************************************/\n\n"); 00934 00935 /* Loop all the states */ 00936 for (i = 2; i <= StateCount; i++) 00937 { 00938 /* Check if this something else than state 2 */ 00939 if (i != 2) 00940 { 00941 /* Loop all the scan codes */ 00942 for (j = 0; j < 110; j++) 00943 { 00944 /* Check if this is the state for the entry */ 00945 if (i == Layout->Entry[j].StateCount) break; 00946 } 00947 } 00948 00949 /* Print the table header */ 00950 fprintf(FileHandle, 00951 "static ALLOC_SECTION_LDATA VK_TO_WCHARS%d aVkToWch%d[] = {\n" 00952 "// | | Shift |", 00953 i, 00954 i); 00955 00956 /* Print the correct state label */ 00957 for (k = 2; k < i; k++) fprintf(FileHandle, "%-9.9s|", 00958 StateLabel[ShiftStates[k]]); 00959 00960 /* Print the next separator */ 00961 fprintf(FileHandle, "\n// |=========|=========|"); 00962 00963 /* Check for extra states and print their separators too */ 00964 for (k = 2; k < i; k++) fprintf(FileHandle, "=========|"); 00965 00966 /* Finalize the separator header */ 00967 fprintf(FileHandle, "\n"); 00968 00969 /* Loop all the scan codes */ 00970 for (j = 0; j < 110; j++) 00971 { 00972 /* Check if this is the state for the entry */ 00973 if (i != Layout->Entry[j].StateCount) continue; 00974 00975 /* Print out the entry for this key */ 00976 fprintf(FileHandle, 00977 " {%-13s,%-7s", 00978 getVKName(Layout->Entry[j].VirtualKey, 1), 00979 CapState[Layout->Entry[j].Cap]); 00980 00981 /* Initialize the buffer for this line */ 00982 *LineBuffer = '\0'; 00983 00984 /* Loop states */ 00985 for (k = 0; k < i; k++) 00986 { 00987 /* Check for dead key data */ 00988 if (DeadKeyData) 00989 { 00990 /* Not yet supported */ 00991 printf("Dead key data not supported!\n"); 00992 exit(1); 00993 } 00994 00995 /* Check if it's a ligature key */ 00996 if (Layout->Entry[j].LigatureCharData[k]) 00997 { 00998 /* Not yet supported */ 00999 printf("Ligature key data not supported!\n"); 01000 exit(1); 01001 } 01002 01003 /* Print out the WCH_ name */ 01004 fprintf(FileHandle, 01005 ",%-9s", 01006 WChName(Layout->Entry[j].CharData[k], 0)); 01007 01008 /* If we have something on the line buffer by now, add WCH_NONE */ 01009 if (*LineBuffer != '\0') strcpy(LineBuffer, "WCH_NONE "); 01010 } 01011 01012 /* Finish the line */ 01013 fprintf(FileHandle, "},\n"); 01014 01015 /* Do we have any data at all? */ 01016 if (*LineBuffer != '\0') 01017 { 01018 /* Print it, we're done */ 01019 fprintf(FileHandle, "%s},\n", LineBuffer); 01020 continue; 01021 } 01022 01023 /* Otherwise, we're done, unless this requires SGCAP data */ 01024 if (Layout->Entry[j].Cap != 2) continue; 01025 01026 /* Not yet supported */ 01027 printf("SGCAP not yet supported!\n"); 01028 exit(1); 01029 } 01030 01031 /* Did we only have two states? */ 01032 if (i == 2) 01033 { 01034 /* Print out the built-in table */ 01035 fprintf(FileHandle, 01036 " {VK_TAB ,0 ,'\\t' ,'\\t' },\n" 01037 " {VK_ADD ,0 ,'+' ,'+' },\n" 01038 " {VK_DIVIDE ,0 ,'/' ,'/' },\n" 01039 " {VK_MULTIPLY ,0 ,'*' ,'*' },\n" 01040 " {VK_SUBTRACT ,0 ,'-' ,'-' },\n"); 01041 } 01042 01043 /* Terminate the table */ 01044 fprintf(FileHandle, " {0 ,0 "); 01045 for (k = 0; k < i; k++) fprintf(FileHandle, ",0 "); 01046 01047 /* Terminate the structure */ 01048 fprintf(FileHandle, "}\n" "};\n\n"); 01049 } 01050 01051 /* Numpad translation table */ 01052 fprintf(FileHandle, 01053 "// Put this last so that VkKeyScan interprets number characters\n" 01054 "// as coming from the main section of the kbd (aVkToWch2 and\n" 01055 "// aVkToWch5) before considering the numpad (aVkToWch1).\n\n" 01056 "static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = {\n" 01057 " { VK_NUMPAD0 , 0 , '0' },\n" 01058 " { VK_NUMPAD1 , 0 , '1' },\n" 01059 " { VK_NUMPAD2 , 0 , '2' },\n" 01060 " { VK_NUMPAD3 , 0 , '3' },\n" 01061 " { VK_NUMPAD4 , 0 , '4' },\n" 01062 " { VK_NUMPAD5 , 0 , '5' },\n" 01063 " { VK_NUMPAD6 , 0 , '6' },\n" 01064 " { VK_NUMPAD7 , 0 , '7' },\n" 01065 " { VK_NUMPAD8 , 0 , '8' },\n" 01066 " { VK_NUMPAD9 , 0 , '9' },\n" 01067 " { 0 , 0 , '\\0' }\n" 01068 "};\n\n"); 01069 01070 /* Translation tables header */ 01071 fprintf(FileHandle,"static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = {\n"); 01072 01073 /* Loop states higher than 3 */ 01074 for (i = 3; i <= StateCount; i++) 01075 { 01076 /* Print out the extra tables */ 01077 fprintf(FileHandle, 01078 " { (PVK_TO_WCHARS1)aVkToWch%d, %d, sizeof(aVkToWch%d[0]) },\n", 01079 i, 01080 i, 01081 i); 01082 } 01083 01084 /* Array of translation tables */ 01085 fprintf(FileHandle, 01086 " { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) },\n" 01087 " { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) },\n" 01088 " { NULL, 0, 0 },\n" 01089 "};\n\n"); 01090 01091 /* Scan code to key name conversion table description */ 01092 fprintf(FileHandle, 01093 "/***************************************************************************\\\n" 01094 "* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables\n" 01095 "*\n" 01096 "* Table attributes: Ordered Scan (by scancode), null-terminated\n" 01097 "*\n" 01098 "* Only the names of Extended, NumPad, Dead and Non-Printable keys are here.\n" 01099 "* (Keys producing printable characters are named by that character)\n" 01100 "\\***************************************************************************/\n\n"); 01101 01102 /* Check for key name data */ 01103 if (KeyNameData) 01104 { 01105 /* Table header */ 01106 fprintf(FileHandle, "static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNames[] = {\n"); 01107 01108 /* Print table */ 01109 PrintNameTable(FileHandle, KeyNameData, FALSE); 01110 01111 /* Table end */ 01112 fprintf(FileHandle, "};\n\n"); 01113 } 01114 01115 /* Check for extended key name data */ 01116 if (KeyNameExtData) 01117 { 01118 /* Table header */ 01119 fprintf(FileHandle, "static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNamesExt[] = {\n"); 01120 01121 /* Print table */ 01122 PrintNameTable(FileHandle, KeyNameExtData, FALSE); 01123 01124 /* Table end */ 01125 fprintf(FileHandle, "};\n\n"); 01126 } 01127 01128 /* Check for dead key name data */ 01129 if (KeyNameDeadData) 01130 { 01131 /* Not yet supported */ 01132 printf("Dead key name data not supported!\n"); 01133 exit(1); 01134 } 01135 01136 /* Check for dead key data */ 01137 if (DeadKeyData) 01138 { 01139 /* Not yet supported */ 01140 printf("Dead key data not supported!\n"); 01141 exit(1); 01142 } 01143 01144 /* Check for ligature data */ 01145 if (LigatureData) 01146 { 01147 /* Not yet supported */ 01148 printf("Ligature key data not supported!\n"); 01149 exit(1); 01150 } 01151 01152 /* Main keyboard table descriptor type */ 01153 fprintf(FileHandle, "static "); 01154 01155 /* FIXME? */ 01156 01157 /* Main keyboard table descriptor header */ 01158 fprintf(FileHandle, 01159 "ALLOC_SECTION_LDATA KBDTABLES KbdTables%s = {\n" 01160 " /*\n" 01161 " * Modifier keys\n" 01162 " */\n" 01163 " &CharModifiers,\n\n" 01164 " /*\n" 01165 " * Characters tables\n" 01166 " */\n" 01167 " aVkToWcharTable,\n\n" 01168 " /*\n" 01169 " * Diacritics\n" 01170 " */\n", 01171 FallbackDriver ? "Fallback" : "" ); 01172 01173 /* Descriptor dead key data section */ 01174 if (DeadKeyData) 01175 { 01176 fprintf(FileHandle, " aDeadKey,\n\n"); 01177 } 01178 else 01179 { 01180 fprintf(FileHandle, " NULL,\n\n"); 01181 } 01182 01183 /* Descriptor key name comment */ 01184 fprintf(FileHandle, 01185 " /*\n" 01186 " * Names of Keys\n" 01187 " */\n"); 01188 01189 /* Descriptor key name section */ 01190 if (KeyNameData) 01191 { 01192 fprintf(FileHandle, " aKeyNames,\n"); 01193 } 01194 else 01195 { 01196 fprintf(FileHandle, " NULL,\n"); 01197 } 01198 01199 /* Descriptor extended key name section */ 01200 if (KeyNameExtData) 01201 { 01202 fprintf(FileHandle, " aKeyNamesExt,\n"); 01203 } 01204 else 01205 { 01206 fprintf(FileHandle, " NULL,\n"); 01207 } 01208 01209 /* Descriptor dead key name section */ 01210 if ((DeadKeyData) && (KeyNameDeadData)) 01211 { 01212 fprintf(FileHandle, " aKeyNamesDead,\n\n"); 01213 } 01214 else 01215 { 01216 fprintf(FileHandle, " NULL,\n\n"); 01217 } 01218 01219 /* Descriptor conversion table section */ 01220 fprintf(FileHandle, 01221 " /*\n" 01222 " * Scan codes to Virtual Keys\n" 01223 " */\n" 01224 " ausVK,\n" 01225 " sizeof(ausVK) / sizeof(ausVK[0]),\n" 01226 " aE0VscToVk,\n" 01227 " aE1VscToVk,\n\n" 01228 " /*\n" 01229 " * Locale-specific special processing\n" 01230 " */\n"); 01231 01232 /* FIXME: AttributeData and KLLF_ALTGR stuff */ 01233 01234 /* Descriptor locale-specific section */ 01235 fprintf(FileHandle, " MAKELONG(%s, KBD_VERSION),\n\n", "0"); /* FIXME */ 01236 01237 /* Descriptor ligature data comment */ 01238 fprintf(FileHandle, " /*\n * Ligatures\n */\n %d,\n", 0); /* FIXME */ 01239 01240 /* Descriptor ligature data section */ 01241 if (!LigatureData) 01242 { 01243 fprintf(FileHandle, " 0,\n"); 01244 fprintf(FileHandle, " NULL\n"); 01245 } 01246 else 01247 { 01248 fprintf(FileHandle, " sizeof(aLigature[0]),\n"); 01249 fprintf(FileHandle, " (PLIGATURE1)aLigature\n"); 01250 } 01251 01252 /* Descriptor finish */ 01253 fprintf(FileHandle, "};\n\n"); 01254 01255 /* Keyboard layout callback function */ 01256 if (!FallbackDriver) fprintf(FileHandle, 01257 "PKBDTABLES KbdLayerDescriptor(VOID)\n" 01258 "{\n" 01259 " return &KbdTables;\n" 01260 "}\n"); 01261 01262 /* Clean up */ 01263 fclose(FileHandle); 01264 return TRUE; 01265 } 01266 01267 ULONG 01268 DoOutput(IN ULONG StateCount, 01269 IN PULONG ShiftStates, 01270 IN PKEYNAME DescriptionData, 01271 IN PKEYNAME LanguageData, 01272 IN PVOID AttributeData, 01273 IN PVOID DeadKeyData, 01274 IN PVOID LigatureData, 01275 IN PKEYNAME KeyNameData, 01276 IN PKEYNAME KeyNameExtData, 01277 IN PKEYNAME KeyNameDeadData) 01278 { 01279 ULONG FailureCode = 0; 01280 01281 /* Take the time */ 01282 time(&Clock); 01283 Now = localtime(&Clock); 01284 01285 /* Check if this just a fallback driver*/ 01286 if (!FallbackDriver) 01287 { 01288 /* It's not, create header file */ 01289 if (!kbd_h(&g_Layout)) FailureCode = 1; 01290 01291 /* Create the resource file */ 01292 if (!kbd_rc(DescriptionData, LanguageData)) FailureCode = 2; 01293 } 01294 01295 /* Create the C file */ 01296 if (!kbd_c(StateCount, 01297 ShiftStates, 01298 AttributeData, 01299 &g_Layout, 01300 DeadKeyData, 01301 LigatureData, 01302 KeyNameData, 01303 KeyNameExtData, 01304 KeyNameDeadData)) 01305 { 01306 /* Failed in C file generation */ 01307 FailureCode = 3; 01308 } 01309 01310 /* Check if this just a fallback driver*/ 01311 if (!FallbackDriver) 01312 { 01313 /* Generate the definition file */ 01314 if (!kbd_def()) FailureCode = 4; 01315 } 01316 01317 /* Done */ 01318 return FailureCode; 01319 } 01320 01321 01322 /* EOF */ Generated on Sat May 26 2012 04:36:35 for ReactOS by
1.7.6.1
|