home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 December / CHIPNET Aralık 1997.iso / linux / redhat / misc / src / install / kbd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-11  |  5.3 KB  |  237 lines

  1. #include <alloca.h>
  2. #include <errno.h>
  3. #include <fcntl.h>
  4. #include <sys/ioctl.h>
  5. #include <linux/keyboard.h>
  6. #include <linux/kd.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <zlib.h>
  11.  
  12. #include "install.h"
  13. #include "kbd.h"
  14. #include "log.h"
  15. #include "newt.h"
  16. #include "windows.h"
  17.  
  18. /* the file pointer must be at the beginning of the section already! */
  19. static int loadKeymap(gzFile stream) {
  20.     int console;
  21.     int kmap, key;
  22.     struct kbentry entry;
  23.     int keymaps[MAX_NR_KEYMAPS];
  24.     int count = 0;
  25.     int magic;
  26.     short keymap[NR_KEYS];
  27.  
  28.     if (gzread(stream, &magic, sizeof(magic)) != sizeof(magic)) {
  29.     logMessage("failed to read kmap magic: %s", strerror(errno));
  30.     return INST_ERROR;
  31.     }
  32.  
  33.     if (magic != KMAP_MAGIC) {
  34.     logMessage("bad magic for keymap!");
  35.     return INST_ERROR;
  36.     }
  37.  
  38.     if (gzread(stream, keymaps, sizeof(keymaps)) != sizeof(keymaps)) {
  39.     logMessage("failed to read keymap header: %s", strerror(errno));
  40.     return INST_ERROR;
  41.     }
  42.  
  43.  
  44.     console = open("/dev/console", O_RDWR);
  45.     if (console < 0) {
  46.     logMessage("failed to open /dev/console: %s", strerror(errno));
  47.     return INST_ERROR;
  48.     }
  49.  
  50.     for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) {
  51.     if (!keymaps[kmap]) continue;
  52.  
  53.     if (gzread(stream, keymap, sizeof(keymap)) != sizeof(keymap)) {
  54.         logMessage("failed to read keymap data: %s", strerror(errno));
  55.         close(console);
  56.         return INST_ERROR;
  57.     }
  58.  
  59.     count++;
  60.     for (key = 0; key < NR_KEYS; key++) {
  61.         entry.kb_index = key;
  62.         entry.kb_table = kmap;
  63.         entry.kb_value = keymap[key];
  64.         if (KTYP(entry.kb_value) != KT_SPEC) {
  65.         if (ioctl(console, KDSKBENT, &entry)) {
  66.             close(console);
  67.             logMessage("keymap ioctl failed: %s", strerror(errno));
  68.         }
  69.         }
  70.     }
  71.     }
  72.  
  73.     logMessage("loaded %d keymap tables", count);
  74.  
  75.     close(console);
  76.  
  77.     return 0;
  78. }
  79.  
  80. int setupKeyboard(void) {
  81.     newtComponent form, okay, listbox, answer;
  82.     int num;
  83.     int rc;
  84.     gzFile f;
  85.     struct kmapHeader hdr;
  86.     struct kmapInfo * infoTable;
  87.     char buf[16384];             /* I hope this is big enough */
  88.     int i;
  89.  
  90.     f = gzopen("/etc/keymaps.gz", "r");
  91.     if (!f) {
  92.     errorWindow("cannot open /etc/keymaps.gz: %s");
  93.     return INST_ERROR;
  94.     }
  95.  
  96.     if (gzread(f, &hdr, sizeof(hdr)) != sizeof(hdr)) {
  97.     errorWindow("failed to read keymaps header: %s");
  98.     gzclose(f);
  99.     return INST_ERROR;
  100.     }
  101.  
  102.     logMessage("%d keymaps are available", hdr.numEntries);
  103.  
  104.     i = hdr.numEntries * sizeof(*infoTable);
  105.     infoTable = alloca(i);
  106.     if (gzread(f, infoTable, i) != i) {
  107.     errorWindow("failed to read keymap information: %s");
  108.     gzclose(f);
  109.     return INST_ERROR;
  110.     }
  111.  
  112.     newtOpenWindow(20, 3, 40, 16, "Keyboard Type");
  113.  
  114.     form = newtForm(NULL, NULL, 0);
  115.  
  116.     newtFormAddComponent(form, 
  117.              newtLabel(3, 1, "What type of keyboard do you have?"));
  118.  
  119.     listbox = newtListbox(8, 3, 8, NEWT_LISTBOX_RETURNEXIT);
  120.  
  121.     for (i = 0; i < hdr.numEntries; i++) {
  122.     newtListboxAddEntry(listbox, infoTable[i].name, (void *) i);
  123.  
  124.     if (!strcmp(infoTable[i].name, "us")) 
  125.         newtListboxSetCurrent(listbox, i);
  126.     }
  127.  
  128.     okay = newtButton(18, 12, "Ok");
  129.  
  130.     newtFormAddComponents(form, listbox, okay, NULL);
  131.  
  132.     answer = newtRunForm(form);
  133.  
  134.     num = (int) newtListboxGetCurrent(listbox);
  135.     rc = 0;
  136.  
  137.     logMessage("using keymap %s", infoTable[num].name);
  138.  
  139.     for (i = 0; i < num; i++) {
  140.     if (gzread(f, buf, infoTable[i].size) != infoTable[i].size) {
  141.         logMessage("error reading %d bytes from file: %s", 
  142.                 infoTable[i].size, strerror(errno));
  143.         gzclose(f);
  144.         rc = INST_ERROR;
  145.     }
  146.     }
  147.  
  148.     if (!rc) rc = loadKeymap(f);
  149.  
  150.     gzclose(f);
  151.  
  152.     writeKbdConfig("/tmp", infoTable[num].name);
  153.  
  154.     newtFormDestroy(form);
  155.     newtPopWindow();
  156.  
  157.     return rc;
  158. }
  159.  
  160. int writeKbdConfig(char * prefix, char * keymap) {
  161.     FILE * f;
  162.     char * filename;
  163.  
  164.     if (testing || !keymap) return 0;
  165.  
  166.     filename = alloca(strlen(prefix) + 20);
  167.     sprintf(filename, "%s/keyboard", prefix);
  168.  
  169.     f = fopen(filename, "w");
  170.     if (!f) {
  171.     errorWindow("failed to create keyboard configuration: %s");
  172.     return INST_ERROR;
  173.     }
  174.  
  175.     if (fprintf(f, "KEYTABLE=\"/usr/lib/kbd/keytables/%s.map\"\n", 
  176.             keymap) < 0) {
  177.     errorWindow("failed to write keyboard configuration: %s");
  178.     return INST_ERROR;
  179.     }
  180.  
  181.     fclose(f);
  182.  
  183.     return 0;
  184. }
  185.  
  186. int readKbdConfig(char * prefix, char ** keymap) {
  187.     FILE * f;
  188.     char * filename;
  189.     char buf[255];
  190.     char * chptr;
  191.  
  192.     *keymap = NULL;
  193.  
  194.     if (testing) return 0;
  195.  
  196.     filename = alloca(strlen(prefix) + 20);
  197.     sprintf(filename, "%s/keyboard", prefix);
  198.  
  199.     f = fopen(filename, "r");
  200.     if (!f) {
  201.     /* fail silently -- old bootdisks won't create this */
  202.     logMessage("failed to read keyboard configuration (proably ok)");
  203.     return 0;
  204.     }
  205.  
  206.     /* this is a bit braindead -- we can steal better parsing from
  207.        kbdconfig if we ever need it */
  208.     if (!fgets(buf, sizeof(buf) - 1, f)) {
  209.     errorWindow("empty keyboard configuration file");
  210.     fclose(f);
  211.     return INST_ERROR;
  212.     }
  213.  
  214.     fclose(f);
  215.  
  216.     if (strncmp("KEYTABLE=", buf, 9)) {
  217.     errorWindow("unrecognized entry in keyboard configuration file");
  218.     return INST_ERROR;
  219.     }
  220.  
  221.     chptr = buf + strlen(buf) - 1;
  222.     /* ignore the '\n' on the end */
  223.     *chptr-- = '\0';
  224.     if (*chptr == '"') 
  225.     *chptr-- = '\0';
  226.  
  227.     while (chptr > buf && *chptr != '.') chptr--;
  228.     if (*chptr == '.') *chptr-- = '\0';
  229.  
  230.     while (chptr > buf && *chptr != '/') chptr--;
  231.     if (*chptr == '/') chptr++;
  232.  
  233.     *keymap = strdup(chptr);
  234.  
  235.     return 0;
  236. }
  237.