root/kernel/chr_drv/keyboard.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. keyboard_interrupt
  2. put_queue
  3. puts_queue
  4. ctrl
  5. alt
  6. unctrl
  7. unalt
  8. lshift
  9. unlshift
  10. rshift
  11. unrshift
  12. caps
  13. set_leds
  14. uncaps
  15. show_ptregs
  16. scroll
  17. num
  18. applkey
  19. do_self
  20. handle_diacr
  21. cursor
  22. cur
  23. func
  24. slash
  25. star
  26. enter
  27. minus
  28. plus
  29. none
  30. kb_wait
  31. kb_ack
  32. hard_reset_now

   1 /*
   2  * linux/kernel/chr_drv/keyboard.c
   3  *
   4  * Keyboard driver for Linux v0.96 using Latin-1.
   5  *
   6  * Written for linux by Johan Myreen as a translation from
   7  * the assembly version by Linus (with diacriticals added)
   8  */
   9 
  10 #include <linux/sched.h>
  11 #include <linux/ctype.h>
  12 #include <linux/tty.h>
  13 #include <linux/mm.h>
  14 #include <linux/ptrace.h>
  15 
  16 /*
  17  * The default IO slowdown is doing 'inb()'s from 0x61, which should be
  18  * safe. But as that is the keyboard controller chip address, we do our
  19  * slowdowns here by doing short jumps: the keyboard controller should
  20  * be able to keep up
  21  */
  22 #define REALLY_SLOW_IO
  23 #define SLOW_IO_BY_JUMPING
  24 #include <asm/io.h>
  25 #include <asm/system.h>
  26 
  27 #define LSHIFT          0x01
  28 #define RSHIFT          0x02
  29 #define LCTRL           0x04
  30 #define RCTRL           0x08
  31 #define ALT             0x10
  32 #define ALTGR           0x20
  33 #define CAPS            0x40
  34 #define CAPSDOWN        0x80
  35 
  36 #define SCRLED          0x01
  37 #define NUMLED          0x02
  38 #define CAPSLED         0x04
  39 
  40 #define NO_META_BIT 0x80
  41 
  42 #ifndef KBD_DEFLOCK
  43 #define KBD_DEFLOCK NUMLED
  44 #endif
  45 
  46 unsigned char kapplic = 0;
  47 unsigned char ckmode = 0;
  48 unsigned char krepeat = 1;
  49 unsigned char kmode = 0;
  50 unsigned char default_kleds = KBD_DEFLOCK;
  51 unsigned char kleds = KBD_DEFLOCK;
  52 unsigned char ke0 = 0;
  53 unsigned char kraw = 0;
  54 unsigned char kbd_flags = KBDFLAGS;
  55 unsigned char lfnlmode = 0;
  56 
  57 extern void do_keyboard_interrupt(void);
  58 extern void ctrl_alt_del(void);
  59 extern void change_console(unsigned int new_console);
  60 extern struct tty_queue *table_list[];
  61 
  62 typedef void (*fptr)(int);
  63 
  64 static unsigned char old_leds = NUMLED;
  65 static int diacr = -1;
  66 static int npadch = 0;
  67 fptr key_table[];
  68 
  69 static void put_queue(int);
  70 void set_leds(void);
  71 static void applkey(int);
  72 static void cur(int);
  73 static void kb_wait(void), kb_ack(void);
  74 static unsigned int handle_diacr(unsigned int);
  75 
  76 static struct pt_regs * pt_regs;
  77 
  78 void keyboard_interrupt(int int_pt_regs)
     /* [previous][next][first][last][top][bottom][index][help] */
  79 {
  80         static unsigned char rep = 0xff, repke0 = 0;
  81         unsigned char scancode, x;
  82         struct tty_struct * tty = TTY_TABLE(0);
  83 
  84         pt_regs = (struct pt_regs *) int_pt_regs;
  85         scancode=inb_p(0x60);
  86         x=inb_p(0x61);
  87         outb_p(x|0x80, 0x61);
  88         outb_p(x&0x7f, 0x61);
  89         outb(0x20, 0x20);
  90         sti();
  91 
  92         if (kraw) {
  93                 put_queue(scancode);
  94                 do_keyboard_interrupt();
  95                 return;
  96         }
  97         if (scancode == 0xe0) {
  98                 ke0 = 1;
  99                 return;
 100         }
 101         if (scancode == 0xe1) {
 102                 ke0 = 2;
 103                 return;
 104         }
 105         /*
 106          *  The keyboard maintains its own internal caps lock and num lock
 107          *  statuses. In caps lock mode E0 AA precedes make code and E0 2A
 108          *  follows break code. In num lock mode, E0 2A precedes make
 109          *  code and E0 AA follows break code. We do our own book-keeping,
 110          *  so we will just ignore these.
 111          */
 112         if (ke0 == 1 && (scancode == 0x2a || scancode == 0xaa)) {
 113                 ke0 = 0;
 114                 return;
 115         }
 116         /*
 117          *  Repeat a key only if the input buffers are empty or the
 118          *  characters get echoed locally. This makes key repeat usable
 119          *  with slow applications and unders heavy loads.
 120          */
 121         if (rep == 0xff) {
 122                 if (scancode < 0x80) {
 123                         rep = scancode;
 124                         repke0 = ke0;
 125                 }
 126         } else if (ke0 == repke0 && (scancode & 0x7f) == rep)
 127                 if (scancode & 0x80)
 128                         rep = 0xff;
 129                 else if (!(krepeat && tty && (L_ECHO(tty) ||
 130                                               (EMPTY(&tty->secondary) &&
 131                                                EMPTY(&tty->read_q))))) {
 132                         ke0 = 0;
 133                         return;
 134                 }
 135         key_table[scancode](scancode);
 136         do_keyboard_interrupt();
 137         ke0 = 0;
 138 }
 139 
 140 static void put_queue(int ch)
     /* [previous][next][first][last][top][bottom][index][help] */
 141 {
 142         struct tty_queue *qp;
 143         struct tty_struct *tty = TTY_TABLE(0);
 144         unsigned long new_head;
 145 
 146         wake_up(&keypress_wait);
 147         if (!tty)
 148                 return;
 149         qp = &tty->read_q;
 150 
 151         qp->buf[qp->head]=ch;
 152         if ((new_head=(qp->head+1)&(TTY_BUF_SIZE-1)) != qp->tail)
 153                 qp->head=new_head;
 154         wake_up(&qp->proc_list);
 155 }
 156 
 157 static void puts_queue(char *cp)
     /* [previous][next][first][last][top][bottom][index][help] */
 158 {
 159         struct tty_queue *qp;
 160         struct tty_struct *tty = TTY_TABLE(0);
 161         unsigned long new_head;
 162         char ch;
 163         
 164         wake_up(&keypress_wait);
 165         if (!tty)
 166                 return;
 167         qp = &tty->read_q;
 168 
 169         while (ch=*cp++) {
 170                 qp->buf[qp->head]=ch;
 171                 if ((new_head=(qp->head+1)&(TTY_BUF_SIZE-1))
 172                                  != qp->tail)
 173                         qp->head=new_head;
 174         }
 175         wake_up(&qp->proc_list);
 176 }
 177 
 178 static void ctrl(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 179 {
 180         if (ke0)
 181                 kmode|=RCTRL;
 182         else
 183                 kmode|=LCTRL;
 184 }
 185 
 186 static void alt(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188         if (ke0)
 189                 kmode|=ALTGR;
 190         else
 191                 kmode|=ALT;
 192 }
 193 
 194 static void unctrl(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 195 {
 196         if (ke0)
 197                 kmode&=(~RCTRL);
 198         else
 199                 kmode&=(~LCTRL);
 200 }
 201 
 202 static void unalt(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 203 {
 204         if (ke0)
 205                 kmode&=(~ALTGR);
 206         else {
 207                 kmode&=(~ALT);
 208                 if (npadch != 0) {
 209                         put_queue(npadch);
 210                         npadch=0;
 211                 }
 212         }
 213 }
 214 
 215 static void lshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 216 {
 217         kmode|=LSHIFT;
 218 }
 219 
 220 static void unlshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 221 {
 222         kmode&=(~LSHIFT);
 223 }
 224 
 225 static void rshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 226 {
 227         kmode|=RSHIFT;
 228 }
 229 
 230 static void unrshift(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 231 {
 232         kmode&=(~RSHIFT);
 233 }
 234 
 235 static void caps(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 236 {
 237         if (!(kmode & CAPSDOWN)) {
 238                 kleds ^= CAPSLED;
 239                 kmode ^= CAPS;
 240                 kmode |= CAPSDOWN;
 241                 set_leds();
 242         }
 243 }
 244 
 245 void set_leds(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247         if (kleds != old_leds) {
 248                 old_leds = kleds;
 249                 kb_wait();
 250                 outb(0xed, 0x60);       /* set leds command */
 251                 kb_ack();
 252                 kb_wait();
 253                 outb(kleds, 0x60);
 254                 kb_ack();
 255         }
 256 }
 257 
 258 static void uncaps(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 259 {
 260         kmode &= ~CAPSDOWN;
 261 }
 262 
 263 static void show_ptregs(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 264 {
 265         printk("\nEIP: %04x:%08x",0xffff & pt_regs->cs,pt_regs->eip);
 266         if (pt_regs->cs & 3)
 267                 printk(" ESP: %04x:%08x",0xffff & pt_regs->cs,pt_regs->eip);
 268         printk(" EFLAGS: %08x",pt_regs->eflags);
 269         printk("\nEAX: %08x EBX: %08x ECX: %08x EDX: %08x",
 270                 pt_regs->orig_eax,pt_regs->ebx,pt_regs->ecx,pt_regs->edx);
 271         printk("\nESI: %08x EDI: %08x EBP: %08x",
 272                 pt_regs->esi, pt_regs->edi, pt_regs->ebp);
 273         printk(" DS: %04x ES: %04x FS: %04x GS: %04x\n",
 274                 0xffff & pt_regs->ds,0xffff & pt_regs->es,
 275                 0xffff & pt_regs->fs,0xffff & pt_regs->gs);
 276 }
 277 
 278 static void scroll(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 279 {
 280         if (kmode & (LSHIFT | RSHIFT))
 281                 show_mem();
 282         else if (kmode & (ALT | ALTGR))
 283                 show_ptregs();
 284         else if (kmode & (LCTRL | RCTRL))
 285                 show_state();
 286         kleds ^= SCRLED;
 287         set_leds();
 288 }
 289 
 290 static void num(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 291 {
 292         if (kapplic)
 293                 applkey(0x50);
 294         else {
 295                 kleds ^= NUMLED;
 296                 set_leds();
 297         }
 298 }
 299 
 300 static void applkey(int key)
     /* [previous][next][first][last][top][bottom][index][help] */
 301 {
 302         char buf[] = { 0x1b, 0x4f, 0x00, 0x00 };
 303 
 304         buf[2] = key;
 305         puts_queue(buf);
 306 }
 307 
 308 #if defined KBD_FINNISH
 309 
 310 static unsigned char key_map[] = {
 311           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 312         '7',  '8',  '9',  '0',  '+', '\'',  127,    9,
 313         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 314         'o',  'p',  '}',    0,   13,    0,  'a',  's',
 315         'd',  'f',  'g',  'h',  'j',  'k',  'l',  '|',
 316         '{',    0,    0, '\'',  'z',  'x',  'c',  'v',
 317         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 318           0,   32,    0,    0,    0,    0,    0,    0,
 319           0,    0,    0,    0,    0,    0,    0,    0,
 320           0,    0,  '-',    0,    0,    0,  '+',    0,
 321           0,    0,    0,    0,    0,    0,  '<',    0,
 322           0,    0,    0,    0,    0,    0,    0,    0,
 323           0 };
 324 
 325 static unsigned char shift_map[] = {
 326           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 327         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 328         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 329         'O',  'P',  ']',  '^',   13,    0,  'A',  'S',
 330         'D',  'F',  'G',  'H',  'J',  'K',  'L', '\\',
 331         '[',    0,    0,  '*',  'Z',  'X',  'C',  'V',
 332         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 333           0,   32,    0,    0,    0,    0,    0,    0,
 334           0,    0,    0,    0,    0,    0,    0,    0,
 335           0,    0,  '-',    0,    0,    0,  '+',    0,
 336           0,    0,    0,    0,    0,    0,  '>',    0,
 337           0,    0,    0,    0,    0,    0,    0,    0,
 338           0 };
 339 
 340 static unsigned char alt_map[] = {
 341           0,    0,    0,  '@',  163,  '$',    0,    0,
 342         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 343           0,    0,    0,    0,    0,    0,    0,    0,
 344           0,    0,    0,  '~',   13,    0,    0,    0,
 345           0,    0,    0,    0,    0,    0,    0,    0,
 346           0,    0,    0,    0,    0,    0,    0,    0,
 347           0,    0,    0,    0,    0,    0,    0,    0,
 348           0,    0,    0,    0,    0,    0,    0,    0,
 349           0,    0,    0,    0,    0,    0,    0,    0,
 350           0,    0,    0,    0,    0,    0,    0,    0,
 351           0,    0,    0,    0,    0,    0,  '|',    0,
 352           0,    0,    0,    0,    0,    0,    0,    0,
 353           0 };
 354 
 355 #elif defined KBD_FINNISH_LATIN1
 356 
 357 static unsigned char key_map[] = {
 358           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 359         '7',  '8',  '9',  '0',  '+',  180,  127,    9,
 360         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 361         'o',  'p',  229,  168,   13,    0,  'a',  's',
 362         'd',  'f',  'g',  'h',  'j',  'k',  'l',  246,
 363         228,  167,    0, '\'',  'z',  'x',  'c',  'v',
 364         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 365           0,   32,    0,    0,    0,    0,    0,    0,
 366           0,    0,    0,    0,    0,    0,    0,    0,
 367           0,    0,  '-',    0,    0,    0,  '+',    0,
 368           0,    0,    0,    0,    0,    0,  '<',    0,
 369           0,    0,    0,    0,    0,    0,    0,    0,
 370           0 };
 371 
 372 static unsigned char shift_map[] = {
 373           0,   27,  '!',  '"',  '#',  '$',  '%',  '&',
 374         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 375         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 376         'O',  'P',  197,  '^',   13,    0,  'A',  'S',
 377         'D',  'F',  'G',  'H',  'J',  'K',  'L',  214,
 378         196,  189,    0,  '*',  'Z',  'X',  'C',  'V',
 379         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 380           0,   32,    0,    0,    0,    0,    0,    0,
 381           0,    0,    0,    0,    0,    0,    0,    0,
 382           0,    0,  '-',    0,    0,    0,  '+',    0,
 383           0,    0,    0,    0,    0,    0,  '>',    0,
 384           0,    0,    0,    0,    0,    0,    0,    0,
 385           0 };
 386 
 387 static unsigned char alt_map[] = {
 388           0,    0,    0,  '@',  163,  '$',    0,    0,
 389         '{',  '[',  ']',  '}', '\\',    0,    0,    0,
 390           0,    0,    0,    0,    0,    0,    0,    0,
 391           0,    0,    0,  '~',   13,    0,    0,    0,
 392           0,    0,    0,    0,    0,    0,    0,    0,
 393           0,    0,    0,    0,    0,    0,    0,    0,
 394           0,    0,    0,    0,    0,    0,    0,    0,
 395           0,    0,    0,    0,    0,    0,    0,    0,
 396           0,    0,    0,    0,    0,    0,    0,    0,
 397           0,    0,    0,    0,    0,    0,    0,    0,
 398           0,    0,    0,    0,    0,    0,  '|',    0,
 399           0,    0,    0,    0,    0,    0,    0,    0,
 400           0 };
 401 
 402 #elif defined KBD_US
 403 
 404 static unsigned char key_map[] = {
 405           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 406         '7',  '8',  '9',  '0',  '-',  '=',  127,    9,
 407         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 408         'o',  'p',  '[',  ']',   13,    0,  'a',  's',
 409         'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',
 410         '\'', '`',    0, '\\',  'z',  'x',  'c',  'v',
 411         'b',  'n',  'm',  ',',  '.',  '/',    0,  '*',
 412           0,   32,    0,    0,    0,    0,    0,    0,
 413           0,    0,    0,    0,    0,    0,    0,    0,
 414           0,    0,  '-',    0,    0,    0,  '+',    0,
 415           0,    0,    0,    0,    0,    0,  '<',    0,
 416           0,    0,    0,    0,    0,    0,    0,    0,
 417           0 };
 418 
 419 static unsigned char shift_map[] = {
 420           0,   27,  '!',  '@',  '#',  '$',  '%',  '^',
 421         '&',  '*',  '(',  ')',  '_',  '+',  127,    9,
 422         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 423         'O',  'P',  '{',  '}',   13,    0,  'A',  'S',
 424         'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',
 425         '"',  '~',  '0',  '|',  'Z',  'X',  'C',  'V',
 426         'B',  'N',  'M',  '<',  '>',  '?',    0,  '*',
 427           0,   32,    0,    0,    0,    0,    0,    0,
 428           0,    0,    0,    0,    0,    0,    0,    0,
 429           0,    0,  '-',    0,    0,    0,  '+',    0,
 430           0,    0,    0,    0,    0,    0,  '>',    0,
 431           0,    0,    0,    0,    0,    0,    0,    0,
 432           0 };
 433 
 434 static unsigned char alt_map[] = {
 435           0,    0,    0,  '@',    0,  '$',    0,    0,
 436         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 437           0,    0,    0,    0,    0,    0,    0,    0,
 438           0,    0,    0,  '~',   13,    0,    0,    0,
 439           0,    0,    0,    0,    0,    0,    0,    0,
 440           0,    0,    0,    0,    0,    0,    0,    0,
 441           0,    0,    0,    0,    0,    0,    0,    0,
 442           0,    0,    0,    0,    0,    0,    0,    0,
 443           0,    0,    0,    0,    0,    0,    0,    0,
 444           0,    0,    0,    0,    0,    0,    0,    0,
 445           0,    0,    0,    0,    0,    0,  '|',    0,
 446           0,    0,    0,    0,    0,    0,    0,    0,
 447           0 };
 448 
 449 #elif defined KBD_UK
 450 
 451 static unsigned char key_map[] = {
 452           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 453         '7',  '8',  '9',  '0',  '-',  '=',  127,    9,
 454         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 455         'o',  'p',  '[',  ']',   13,    0,  'a',  's',
 456         'd',  'f',  'g',  'h',  'j',  'k',  'l',  ';',
 457         '\'', '`',    0,  '#',  'z',  'x',  'c',  'v',
 458         'b',  'n',  'm',  ',',  '.',  '/',    0,  '*',
 459           0,   32,    0,    0,    0,    0,    0,    0,
 460           0,    0,    0,    0,    0,    0,    0,    0,
 461           0,    0,  '-',    0,    0,    0,  '+',    0,
 462           0,    0,    0,    0,    0,    0, '\\',    0,
 463           0,    0,    0,    0,    0,    0,    0,    0,
 464           0 };
 465 
 466 static unsigned char shift_map[] = {
 467           0,   27,  '!',  '"',  163,  '$',  '%',  '^',
 468         '&',  '*',  '(',  ')',  '_',  '+',  127,    9,
 469         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 470         'O',  'P',  '{',  '}',   13,    0,  'A',  'S',
 471         'D',  'F',  'G',  'H',  'J',  'K',  'L',  ':',
 472         '@',  '~',  '0',  '~',  'Z',  'X',  'C',  'V',
 473         'B',  'N',  'M',  '<',  '>',  '?',    0,  '*',
 474           0,   32,    0,    0,    0,    0,    0,    0,
 475           0,    0,    0,    0,    0,    0,    0,    0,
 476           0,    0,  '-',    0,    0,    0,  '+',    0,
 477           0,    0,    0,    0,    0,    0,  '|',    0,
 478           0,    0,    0,    0,    0,    0,    0,    0,
 479           0 };
 480 
 481 static unsigned char alt_map[] = {
 482           0,    0,    0,  '@',    0,  '$',    0,    0,
 483         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 484           0,    0,    0,    0,    0,    0,    0,    0,
 485           0,    0,    0,  '~',   13,    0,    0,    0,
 486           0,    0,    0,    0,    0,    0,    0,    0,
 487           0,    0,    0,    0,    0,    0,    0,    0,
 488           0,    0,    0,    0,    0,    0,    0,    0,
 489           0,    0,    0,    0,    0,    0,    0,    0,
 490           0,    0,    0,    0,    0,    0,    0,    0,
 491           0,    0,    0,    0,    0,    0,    0,    0,
 492           0,    0,    0,    0,    0,    0,  '|',    0,
 493           0,    0,    0,    0,    0,    0,    0,    0,
 494           0 };
 495 
 496 #elif defined KBD_GR
 497 
 498 static unsigned char key_map[] = {
 499           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 500         '7',  '8',  '9',  '0', '\\', '\'',  127,    9,
 501         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 502         'o',  'p',  '@',  '+',   13,    0,  'a',  's',
 503         'd',  'f',  'g',  'h',  'j',  'k',  'l',  '[',
 504         ']',  '^',    0,  '#',  'y',  'x',  'c',  'v',
 505         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 506           0,   32,    0,    0,    0,    0,    0,    0,
 507           0,    0,    0,    0,    0,    0,    0,    0,
 508           0,    0,  '-',    0,    0,    0,  '+',    0,
 509           0,    0,    0,    0,    0,    0,  '<',    0,
 510           0,    0,    0,    0,    0,    0,    0,    0,
 511           0 };
 512 
 513 static unsigned char shift_map[] = {
 514           0,   27,  '!',  '"',  '#',  '$',  '%',  '&',
 515         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 516         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 517         'O',  'P', '\\',  '*',   13,    0,  'A',  'S',
 518         'D',  'F',  'G',  'H',  'J',  'K',  'L',  '{',
 519         '}',  '~',    0, '\'',  'Y',  'X',  'C',  'V',
 520         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 521           0,   32,    0,    0,    0,    0,    0,    0,
 522           0,    0,    0,    0,    0,    0,    0,    0,
 523           0,    0,  '-',    0,    0,    0,  '+',    0,
 524           0,    0,    0,    0,    0,    0,  '>',    0,
 525           0,    0,    0,    0,    0,    0,    0,    0,
 526           0 };
 527 
 528 static unsigned char alt_map[] = {
 529           0,    0,    0,  '@',    0,  '$',    0,    0,
 530         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 531         '@',    0,    0,    0,    0,    0,    0,    0,
 532           0,    0,    0,  '~',   13,    0,    0,    0,
 533           0,    0,    0,    0,    0,    0,    0,    0,
 534           0,    0,    0,    0,    0,    0,    0,    0,
 535           0,    0,    0,    0,    0,    0,    0,    0,
 536           0,    0,    0,    0,    0,    0,    0,    0,
 537           0,    0,    0,    0,    0,    0,    0,    0,
 538           0,    0,    0,    0,    0,    0,    0,    0,
 539           0,    0,    0,    0,    0,    0,  '|',    0,
 540           0,    0,    0,    0,    0,    0,    0,    0,
 541           0 };
 542 
 543 #elif defined KBD_GR_LATIN1
 544 
 545 static unsigned char key_map[] = {
 546           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 547         '7',  '8',  '9',  '0', 223,  180,  127,    9,
 548         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 549         'o',  'p',  252,  '+',   13,    0,  'a',  's',
 550         'd',  'f',  'g',  'h',  'j',  'k',  'l', 246,
 551         228,   94,    0,  '#',  'y',  'x',  'c',  'v',
 552         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 553           0,   32,    0,    0,    0,    0,    0,    0,
 554           0,    0,    0,    0,    0,    0,    0,    0,
 555           0,    0,  '-',    0,    0,    0,  '+',    0,
 556           0,    0,    0,    0,    0,    0,  '<',    0,
 557           0,    0,    0,    0,    0,    0,    0,    0,
 558           0 };
 559 
 560 static unsigned char shift_map[] = {
 561           0,   27,  '!',  '"',  167,  '$',  '%',  '&',
 562         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 563         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 564         'O',  'P',  220,  '*',   13,    0,  'A',  'S',
 565         'D',  'F',  'G',  'H',  'J',  'K',  'L',  214,
 566         196,  176,    0, '\'',  'Y',  'X',  'C',  'V',
 567         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 568           0,   32,    0,    0,    0,    0,    0,    0,
 569           0,    0,    0,    0,    0,    0,    0,    0,
 570           0,    0,  '-',    0,    0,    0,  '+',    0,
 571           0,    0,    0,    0,    0,    0,  '>',    0,
 572           0,    0,    0,    0,    0,    0,    0,    0,
 573           0 };
 574 
 575 static unsigned char alt_map[] = {
 576           0,    0,    0,  178,  179,  '$',    0,    0,
 577         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 578         '@',    0,    0,    0,    0,    0,    0,    0,
 579           0,    0,    0,  '~',   13,    0,    0,    0,
 580           0,    0,    0,    0,    0,    0,    0,    0,
 581           0,    0,    0,    0,    0,    0,    0,    0,
 582           0,    0,  181,    0,    0,    0,    0,    0,
 583           0,    0,    0,    0,    0,    0,    0,    0,
 584           0,    0,    0,    0,    0,    0,    0,    0,
 585           0,    0,    0,    0,    0,    0,    0,    0,
 586           0,    0,    0,    0,    0,    0,  '|',    0,
 587           0,    0,    0,    0,    0,    0,    0,    0,
 588           0 };
 589 
 590 #elif defined KBD_FR
 591 
 592 static unsigned char key_map[] = {
 593           0,   27,  '&',  '{',  '"', '\'',  '(',  '-',
 594         '}',  '_',  '/',  '@',  ')',  '=',  127,    9,
 595         'a',  'z',  'e',  'r',  't',  'y',  'u',  'i',
 596         'o',  'p',  '^',  '$',   13,    0,  'q',  's',
 597         'd',  'f',  'g',  'h',  'j',  'k',  'l',  'm',
 598         '|',  '`',    0,   42,  'w',  'x',  'c',  'v',
 599         'b',  'n',  ',',  ';',  ':',  '!',    0,  '*',
 600           0,   32,    0,    0,    0,    0,    0,    0,
 601           0,    0,    0,    0,    0,    0,    0,    0,
 602           0,    0,  '-',    0,    0,    0,  '+',    0,
 603           0,    0,    0,    0,    0,    0,  '<',    0,
 604           0,    0,    0,    0,    0,    0,    0,    0,
 605           0 };
 606 
 607 static unsigned char shift_map[] = {
 608           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 609         '7',  '8',  '9',  '0',  ']',  '+',  127,    9,
 610         'A',  'Z',  'E',  'R',  'T',  'Y',  'U',  'I',
 611         'O',  'P',  '<',  '>',   13,    0,  'Q',  'S',
 612         'D',  'F',  'G',  'H',  'J',  'K',  'L',  'M',
 613         '%',  '~',    0,  '#',  'W',  'X',  'C',  'V',
 614         'B',  'N',  '?',  '.',  '/', '\\',    0,  '*',
 615           0,   32,    0,    0,    0,    0,    0,    0,
 616           0,    0,    0,    0,    0,    0,    0,    0,
 617           0,    0,  '-',    0,    0,    0,  '+',    0,
 618           0,    0,    0,    0,    0,    0,  '>',    0,
 619           0,    0,    0,    0,    0,    0,    0,    0,
 620           0 };
 621 
 622 static unsigned char alt_map[] = {
 623           0,    0,    0,  '~',  '#',  '{',  '[',  '|',
 624         '`', '\\',   '^',  '@', ']',  '}',    0,    0,
 625         '@',    0,    0,    0,    0,    0,    0,    0,
 626           0,    0,    0,  '~',   13,    0,    0,    0,
 627           0,    0,    0,    0,    0,    0,    0,    0,
 628           0,    0,    0,    0,    0,    0,    0,    0,
 629           0,    0,    0,    0,    0,    0,    0,    0,
 630           0,    0,    0,    0,    0,    0,    0,    0,
 631           0,    0,    0,    0,    0,    0,    0,    0,
 632           0,    0,    0,    0,    0,    0,    0,    0,
 633           0,    0,    0,    0,    0,    0,  '|',    0,
 634           0,    0,    0,    0,    0,    0,    0,    0,
 635           0 };
 636 
 637 #elif defined KBD_FR_LATIN1
 638 
 639 static unsigned char key_map[] = {
 640           0,   27,  '&',  233,  '"', '\'',  '(',  '-',
 641         232,  '_',  231,  224,  ')',  '=',  127,    9,
 642         'a',  'z',  'e',  'r',  't',  'y',  'u',  'i',
 643         'o',  'p',  '^',  '$',   13,    0,  'q',  's',
 644         'd',  'f',  'g',  'h',  'j',  'k',  'l',  'm',
 645         249,  178,    0,   42,  'w',  'x',  'c',  'v',
 646         'b',  'n',  ',',  ';',  ':',  '!',    0,  '*',
 647           0,   32,    0,    0,    0,    0,    0,    0,
 648           0,    0,    0,    0,    0,    0,    0,    0,
 649           0,    0,  '-',    0,    0,    0,  '+',    0,
 650           0,    0,    0,    0,    0,    0,  '<',    0,
 651           0,    0,    0,    0,    0,    0,    0,    0,
 652           0 };
 653 
 654 static unsigned char shift_map[] = {
 655           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 656         '7',  '8',  '9',  '0',  176,  '+',  127,    9,
 657         'A',  'Z',  'E',  'R',  'T',  'Y',  'U',  'I',
 658         'O',  'P',  168,  163,   13,    0,  'Q',  'S',
 659         'D',  'F',  'G',  'H',  'J',  'K',  'L',  'M',
 660         '%',    0,    0,  181,  'W',  'X',  'C',  'V',
 661         'B',  'N',  '?',  '.',  '/',  167,    0,  '*',
 662           0,   32,    0,    0,    0,    0,    0,    0,
 663           0,    0,    0,    0,    0,    0,    0,    0,
 664           0,    0,  '-',    0,    0,    0,  '+',    0,
 665           0,    0,    0,    0,    0,    0,  '>',    0,
 666           0,    0,    0,    0,    0,    0,    0,    0,
 667           0 };
 668 
 669 static unsigned char alt_map[] = {
 670           0,    0,    0,  '~',  '#',  '{',  '[',  '|',
 671         '`', '\\',   '^',  '@', ']',  '}',    0,    0,
 672         '@',    0,    0,    0,    0,    0,    0,    0,
 673           0,    0,    0,  164,   13,    0,    0,    0,
 674           0,    0,    0,    0,    0,    0,    0,    0,
 675           0,    0,    0,    0,    0,    0,    0,    0,
 676           0,    0,    0,    0,    0,    0,    0,    0,
 677           0,    0,    0,    0,    0,    0,    0,    0,
 678           0,    0,    0,    0,    0,    0,    0,    0,
 679           0,    0,    0,    0,    0,    0,    0,    0,
 680           0,    0,    0,    0,    0,    0,  '|',    0,
 681           0,    0,    0,    0,    0,    0,    0,    0,
 682           0 };
 683 
 684 #elif defined KBD_DK
 685 
 686 static unsigned char key_map[] = {
 687           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 688         '7',  '8',  '9',  '0',  '+', '\'',  127,    9,
 689         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 690         'o',  'p',  229,    0,   13,    0,  'a',  's',
 691         'd',  'f',  'g',  'h',  'j',  'k',  'l',  230,
 692         162,    0,    0, '\'',  'z',  'x',  'c',  'v',
 693         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 694           0,   32,    0,    0,    0,    0,    0,    0,
 695           0,    0,    0,    0,    0,    0,    0,    0,
 696           0,    0,  '-',    0,    0,    0,  '+',    0,
 697           0,    0,    0,    0,    0,    0,  '<',    0,
 698           0,    0,    0,    0,    0,    0,    0,    0,
 699           0 };
 700 
 701 static unsigned char shift_map[] = {
 702           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 703         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 704         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 705         'O',  'P',  197,  '^',   13,    0,  'A',  'S',
 706         'D',  'F',  'G',  'H',  'J',  'K',  'L',  198,
 707         165,    0,    0,  '*',  'Z',  'X',  'C',  'V',
 708         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 709           0,   32,    0,    0,    0,    0,    0,    0,
 710           0,    0,    0,    0,    0,    0,    0,    0,
 711           0,    0,  '-',    0,    0,    0,  '+',    0,
 712           0,    0,    0,    0,    0,    0,  '>',    0,
 713           0,    0,    0,    0,    0,    0,    0,    0,
 714           0 };
 715 
 716 static unsigned char alt_map[] = {
 717           0,    0,    0,  '@',  163,  '$',    0,    0,
 718         '{',   '[',  ']', '}',    0,  '|',    0,    0,
 719           0,    0,    0,    0,    0,    0,    0,    0,
 720           0,    0,    0,  '~',   13,    0,    0,    0,
 721           0,    0,    0,    0,    0,    0,    0,    0,
 722           0,    0,    0,    0,    0,    0,    0,    0,
 723           0,    0,    0,    0,    0,    0,    0,    0,
 724           0,    0,    0,    0,    0,    0,    0,    0,
 725           0,    0,    0,    0,    0,    0,    0,    0,
 726           0,    0,    0,    0,    0,    0,    0,    0,
 727           0,    0,    0,    0,    0,    0,  '\\',    0,
 728           0,    0,    0,    0,    0,    0,    0,    0,
 729           0 };
 730 
 731 #elif defined KBD_DK_LATIN1
 732 
 733 static unsigned char key_map[] = {
 734           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 735         '7',  '8',  '9',  '0',  '+',  180,  127,    9,
 736         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 737         'o',  'p',  229,  168,   13,    0,  'a',  's',
 738         'd',  'f',  'g',  'h',  'j',  'k',  'l',  230,
 739         162,  189,    0, '\'',  'z',  'x',  'c',  'v',
 740         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 741           0,   32,    0,    0,    0,    0,    0,    0,
 742           0,    0,    0,    0,    0,    0,    0,    0,
 743           0,    0,  '-',    0,    0,    0,  '+',    0,
 744           0,    0,    0,    0,    0,    0,  '<',    0,
 745           0,    0,    0,    0,    0,    0,    0,    0,
 746           0 };
 747 
 748 static unsigned char shift_map[] = {
 749           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 750         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 751         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 752         'O',  'P',  197,  '^',   13,    0,  'A',  'S',
 753         'D',  'F',  'G',  'H',  'J',  'K',  'L',  198,
 754         165,  167,    0,  '*',  'Z',  'X',  'C',  'V',
 755         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 756           0,   32,    0,    0,    0,    0,    0,    0,
 757           0,    0,    0,    0,    0,    0,    0,    0,
 758           0,    0,  '-',    0,    0,    0,  '+',    0,
 759           0,    0,    0,    0,    0,    0,  '>',    0,
 760           0,    0,    0,    0,    0,    0,    0,    0,
 761           0 };
 762 
 763 static unsigned char alt_map[] = {
 764           0,    0,    0,  '@',  163,  '$',    0,    0,
 765         '{',   '[',  ']', '}',    0,  '|',    0,    0,
 766           0,    0,    0,    0,    0,    0,    0,    0,
 767           0,    0,    0,  '~',   13,    0,    0,    0,
 768           0,    0,    0,    0,    0,    0,    0,    0,
 769           0,    0,    0,    0,    0,    0,    0,    0,
 770           0,    0,    0,    0,    0,    0,    0,    0,
 771           0,    0,    0,    0,    0,    0,    0,    0,
 772           0,    0,    0,    0,    0,    0,    0,    0,
 773           0,    0,    0,    0,    0,    0,    0,    0,
 774           0,    0,    0,    0,    0,    0, '\\',    0,
 775           0,    0,    0,    0,    0,    0,    0,    0,
 776           0 };
 777 
 778 #elif defined KBD_DVORAK
 779 
 780 static unsigned char key_map[] = {
 781           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 782         '7',  '8',  '9',  '0', '\\',  '=',  127,    9,
 783         '\'', ',',  '.',  'p',  'y',  'f',  'g',  'c',
 784         'r',  'l',  '/',  ']',   13,    0,  'a',  'o',
 785         'e',  'u',  'i',  'd',  'h',  't',  'n',  's',
 786         '-',  '`',    0,  '[',  ';',  'q',  'j',  'k',
 787         'x',  'b',  'm',  'w',  'v',  'z',    0,  '*',
 788           0,   32,    0,    0,    0,    0,    0,    0,
 789           0,    0,    0,    0,    0,    0,    0,    0,
 790           0,    0,  '-',    0,    0,    0,  '+',    0,
 791           0,    0,    0,    0,    0,    0,  '<',    0,
 792           0,    0,    0,    0,    0,    0,    0,    0,
 793           0 };
 794 
 795 static unsigned char shift_map[] = {
 796           0,   27,  '!',  '@',  '#',  '$',  '%',  '^',
 797         '&',  '*',  '(',  ')',  '|',  '+',  127,    9,
 798         '"',  '<',  '>',  'P',  'Y',  'F',  'G',  'C',
 799         'R',  'L',  '?',  '}',   13,    0,  'A',  'O',
 800         'E',  'U',  'I',  'D',  'H',  'T',  'N',  'S',
 801         '_',  '~',    0,  '{',  ':',  'Q',  'J',  'K',
 802         'X',  'B',  'M',  'W',  'V',  'Z',    0,  '*',
 803           0,   32,    0,    0,    0,    0,    0,    0,
 804           0,    0,    0,    0,    0,    0,    0,    0,
 805           0,    0,  '-',    0,    0,    0,  '+',    0,
 806           0,    0,    0,    0,    0,    0,  '<',    0,
 807           0,    0,    0,    0,    0,    0,    0,    0,
 808           0 };
 809 
 810 static unsigned char alt_map[] = {
 811           0,    0,    0,  '@',    0,  '$',    0,    0,
 812         '{',   '[',  ']', '}', '\\',    0,    0,    0,
 813           0,    0,    0,    0,    0,    0,    0,    0,
 814           0,    0,    0,  '~',   13,    0,    0,    0,
 815           0,    0,    0,    0,    0,    0,    0,    0,
 816           0,    0,    0,    0,    0,    0,    0,    0,
 817           0,    0,    0,    0,    0,    0,    0,    0,
 818           0,    0,    0,    0,    0,    0,    0,    0,
 819           0,    0,    0,    0,    0,    0,    0,    0,
 820           0,    0,    0,    0,    0,    0,    0,    0,
 821           0,    0,    0,    0,    0,    0,  '|',    0,
 822           0,    0,    0,    0,    0,    0,    0,    0,
 823           0 };
 824 
 825 #elif defined KBD_SG
 826 
 827 static unsigned char key_map[] = {
 828           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 829         '7',  '8',  '9',  '0', '\'',  '^',  127,    9,
 830         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 831         'o',  'p',    0,    0,   13,    0,  'a',  's',
 832         'd',  'f',  'g',  'h',  'j',  'k',  'l',    0,
 833           0,    0,    0,  '$',  'y',  'x',  'c',  'v',
 834         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 835           0,   32,    0,    0,    0,    0,    0,    0,
 836           0,    0,    0,    0,    0,    0,    0,    0,
 837           0,    0,  '-',    0,    0,    0,  '+',    0,
 838           0,    0,    0,    0,    0,    0,  '<',    0,
 839           0,    0,    0,    0,    0,    0,    0,    0,
 840           0 };
 841 
 842 static unsigned char shift_map[] = {
 843           0,   27,  '+',  '"',  '*',    0,  '%',  '&',
 844         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 845         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 846         'O',  'P',    0,  '!',   13,    0,  'A',  'S',
 847         'D',  'F',  'G',  'H',  'J',  'K',  'L',    0,
 848           0,    0,    0,    0,  'Y',  'X',  'C',  'V',
 849         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 850           0,   32,    0,    0,    0,    0,    0,    0,
 851           0,    0,    0,    0,    0,    0,    0,    0,
 852           0,    0,  '-',    0,    0,    0,  '+',    0,
 853           0,    0,    0,    0,    0,    0,  '>',    0,
 854           0,    0,    0,    0,    0,    0,    0,    0,
 855           0 };
 856 
 857 static unsigned char alt_map[] = {
 858           0,    0,    0,  '@',  '#',    0,    0,    0,
 859         '|',    0,    0,    0, '\'',  '~',    0,    0,
 860         '@',    0,    0,    0,    0,    0,    0,    0,
 861           0,    0,   '[',  ']',  13,    0,    0,    0,
 862           0,    0,    0,    0,    0,    0,    0,    0,
 863         '{',    0,    0,  '}',    0,    0,    0,    0,
 864           0,    0,    0,    0,    0,    0,    0,    0,
 865           0,    0,    0,    0,    0,    0,    0,    0,
 866           0,    0,    0,    0,    0,    0,    0,    0,
 867           0,    0,    0,    0,    0,    0,    0,    0,
 868           0,    0,    0,    0,    0,    0, '\\',    0,
 869           0,    0,    0,    0,    0,    0,    0,    0,
 870           0 };
 871 
 872 #elif defined KBD_SG_LATIN1
 873 
 874 static unsigned char key_map[] = {
 875           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 876         '7',  '8',  '9',  '0', '\'',  '^',  127,    9,
 877         'q',  'w',  'e',  'r',  't',  'z',  'u',  'i',
 878         'o',  'p',  252,    0,   13,    0,  'a',  's',
 879         'd',  'f',  'g',  'h',  'j',  'k',  'l',  246,
 880         228,  167,    0,  '$',  'y',  'x',  'c',  'v',
 881         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 882           0,   32,    0,    0,    0,    0,    0,    0,
 883           0,    0,    0,    0,    0,    0,    0,    0,
 884           0,    0,  '-',    0,    0,    0,  '+',    0,
 885           0,    0,    0,    0,    0,    0,  '<',    0,
 886           0,    0,    0,    0,    0,    0,    0,    0,
 887           0 };
 888 
 889 static unsigned char shift_map[] = {
 890           0,   27,  '+',  '"',  '*',  231,  '%',  '&',
 891         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 892         'Q',  'W',  'E',  'R',  'T',  'Z',  'U',  'I',
 893         'O',  'P',  220,  '!',   13,    0,  'A',  'S',
 894         'D',  'F',  'G',  'H',  'J',  'K',  'L',  214,
 895         196,  176,    0,  163,  'Y',  'X',  'C',  'V',
 896         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 897           0,   32,    0,    0,    0,    0,    0,    0,
 898           0,    0,    0,    0,    0,    0,    0,    0,
 899           0,    0,  '-',    0,    0,    0,  '+',    0,
 900           0,    0,    0,    0,    0,    0,  '>',    0,
 901           0,    0,    0,    0,    0,    0,    0,    0,
 902           0 };
 903 
 904 static unsigned char alt_map[] = {
 905           0,    0,    0,  '@',  '#',    0,    0,  172,
 906         '|',  162,    0,    0, '\'',  '~',    0,    0,
 907         '@',    0,    0,    0,    0,    0,    0,    0,
 908           0,    0,  '[',  ']',   13,    0,    0,    0,
 909           0,    0,    0,    0,    0,    0,    0,  233,
 910         '{',    0,    0,  '}',    0,    0,    0,    0,
 911           0,    0,    0,    0,    0,    0,    0,    0,
 912           0,    0,    0,    0,    0,    0,    0,    0,
 913           0,    0,    0,    0,    0,    0,    0,    0,
 914           0,    0,    0,    0,    0,    0,    0,    0,
 915           0,    0,    0,    0,    0,    0, '\\',    0,
 916           0,    0,    0,    0,    0,    0,    0,    0,
 917           0 };
 918 
 919 #elif defined KBD_NO
 920 
 921 static unsigned char key_map[] = {
 922           0,   27,  '1',  '2',  '3',  '4',  '5',  '6',
 923         '7',  '8',  '9',  '0',  '+', '\\',  127,    9,
 924         'q',  'w',  'e',  'r',  't',  'y',  'u',  'i',
 925         'o',  'p',  '}',  '~',   13,    0,  'a',  's',
 926         'd',  'f',  'g',  'h',  'j',  'k',  'l',  '|',
 927         '{',  '|',    0, '\'',  'z',  'x',  'c',  'v',
 928         'b',  'n',  'm',  ',',  '.',  '-',    0,  '*',
 929           0,   32,    0,    0,    0,    0,    0,    0,
 930           0,    0,    0,    0,    0,    0,    0,    0,
 931           0,    0,  '-',    0,    0,    0,  '+',    0,
 932           0,    0,    0,    0,    0,    0,  '<',    0,
 933           0,    0,    0,    0,    0,    0,    0,    0,
 934           0 };
 935 
 936 static unsigned char shift_map[] = {
 937           0,   27,  '!', '\"',  '#',  '$',  '%',  '&',
 938         '/',  '(',  ')',  '=',  '?',  '`',  127,    9,
 939         'Q',  'W',  'E',  'R',  'T',  'Y',  'U',  'I',
 940         'O',  'P',  ']',  '^',   13,    0,  'A',  'S',
 941         'D',  'F',  'G',  'H',  'J',  'K',  'L', '\\',
 942         '[',    0,    0,  '*',  'Z',  'X',  'C',  'V',
 943         'B',  'N',  'M',  ';',  ':',  '_',    0,  '*',
 944           0,   32,    0,    0,    0,    0,    0,    0,
 945           0,    0,    0,    0,    0,    0,    0,    0,
 946           0,    0,  '-',    0,    0,    0,  '+',    0,
 947           0,    0,    0,    0,    0,    0,  '>',    0,
 948           0,    0,    0,    0,    0,    0,    0,    0,
 949           0 };
 950 
 951 static unsigned char alt_map[] = {
 952           0,    0,    0,  '@',    0,  '$',    0,    0,
 953         '{',   '[',  ']', '}',    0, '\'',    0,    0,
 954           0,    0,    0,    0,    0,    0,    0,    0,
 955           0,    0,    0,  '~',   13,    0,    0,    0,
 956           0,    0,    0,    0,    0,    0,    0,    0,
 957           0,    0,    0,    0,    0,    0,    0,    0,
 958           0,    0,    0,    0,    0,    0,    0,    0,
 959           0,    0,    0,    0,    0,    0,    0,    0,
 960           0,    0,    0,    0,    0,    0,    0,    0,
 961           0,    0,    0,    0,    0,    0,    0,    0,
 962           0,    0,    0,    0,    0,    0,    0,    0,
 963           0,    0,    0,    0,    0,    0,    0,    0,
 964           0 };
 965 
 966 #else
 967 #error "KBD-type not defined"
 968 #endif
 969 
 970 static void do_self(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
 971 {
 972         unsigned char ch;
 973 
 974         if (kmode & ALTGR)
 975                 ch = alt_map[sc];
 976         else if (kmode & (LSHIFT | RSHIFT | LCTRL | RCTRL))
 977                 ch = shift_map[sc];
 978         else
 979                 ch = key_map[sc];
 980 
 981         if (ch == 0)
 982                 return;
 983 
 984         if ((ch = handle_diacr(ch)) == 0)
 985                 return;
 986 
 987         if (kmode & (LCTRL | RCTRL | CAPS))     /* ctrl or caps */
 988                 if ((ch >= 'a' && ch <= 'z') || (ch >= 224 && ch <= 254))
 989                         ch -= 32;
 990         if (kmode & (LCTRL | RCTRL))            /* ctrl */
 991                 ch &= 0x1f;
 992 
 993         if (kmode & ALT)
 994                 if (kbd_flags & NO_META_BIT) {
 995                         put_queue('\033');
 996                         put_queue(ch);
 997                 } else
 998                         put_queue(ch|0x80);
 999         else
1000                 put_queue(ch);
1001 }
1002 
1003 unsigned char accent_table[5][64] = {
1004         " \300BCD\310FGH\314JKLMN\322PQRST\331VWXYZ[\\]^_"
1005         "`\340bcd\350fgh\354jklmn\362pqrst\371vwxyz{|}~",   /* accent grave */
1006 
1007         " \301BCD\311FGH\315JKLMN\323PQRST\332VWX\335Z[\\]^_"
1008         "`\341bcd\351fgh\355jklmn\363pqrst\372vwxyz{|}~",   /* accent acute */
1009 
1010         " \302BCD\312FGH\316JKLMN\324PQRST\333VWXYZ[\\]^_"
1011         "`\342bcd\352fgh\356jklmn\364pqrst\373vwxyz{|}~",   /* circumflex */
1012 
1013         " \303BCDEFGHIJKLMN\325PQRSTUVWXYZ[\\]^_"
1014         "`\343bcdefghijklm\361\365pqrstuvwxyz{|}~",         /* tilde */
1015 
1016         " \304BCD\313FGH\316JKLMN\326PQRST\334VWXYZ[\\]^_"
1017         "`\344bcd\353fgh\357jklmn\366pqrst\374vwx\377z{|}~" /* dieresis */
1018 };
1019 
1020 /*
1021  * Check if dead key pressed. If so, check if same key pressed twice;
1022  * in that case return the char, otherwise store char and return 0.
1023  * If dead key not pressed, check if accented character pending. If
1024  * not: return the char, otherwise check if char is a space. If it is
1025  * a space return the diacritical. Else combine char with diacritical
1026  * mark and return.
1027  */
1028 
1029 unsigned int handle_diacr(unsigned int ch)
     /* [previous][next][first][last][top][bottom][index][help] */
1030 {
1031         static unsigned char diacr_table[] =
1032                 {'`', 180, '^', '~', 168, 0};           /* Must end with 0 */
1033         int i;
1034 
1035         for(i=0; diacr_table[i]; i++)
1036                 if (ch==diacr_table[i] && ((1<<i)&kbd_flags)) {
1037                         if (diacr == i) {
1038                                 diacr=-1;
1039                                 return ch;              /* pressed twice */
1040                         } else {
1041                                 diacr=i;                /* key is dead */
1042                                 return 0;
1043                         }
1044                 }
1045         if (diacr == -1)
1046                 return ch;
1047         else if (ch == ' ') {
1048                 ch=diacr_table[diacr];
1049                 diacr=-1;
1050                 return ch;
1051         } else if (ch<64 || ch>122) {
1052                 diacr=-1;
1053                 return ch;
1054         } else {
1055                 ch=accent_table[diacr][ch-64];
1056                 diacr=-1;
1057                 return ch;
1058         }
1059 }
1060 
1061 #if defined KBD_FR || defined KBD_US || defined KBD_UK
1062 static unsigned char num_table[] = "789-456+1230.";
1063 #else
1064 static unsigned char num_table[] = "789-456+1230,";
1065 #endif
1066 
1067 static unsigned char cur_table[] = "1A5-DGC+4B623";
1068 static unsigned int pad_table[] = { 7,8,9,0,4,5,6,0,1,2,3,0,0 };
1069 
1070 /*
1071     Keypad /                    35      B7      Q
1072     Keypad *  (PrtSc)           37      B7      R
1073     Keypad NumLock              45      ??      P
1074     Keypad 7  (Home)            47      C7      w
1075     Keypad 8  (Up arrow)        48      C8      x
1076     Keypad 9  (PgUp)            49      C9      y
1077     Keypad -                    4A      CA      S
1078     Keypad 4  (Left arrow)      4B      CB      t
1079     Keypad 5                    4C      CC      u
1080     Keypad 6  (Right arrow)     4D      CD      v
1081     Keypad +                    4E      CE      l
1082     Keypad 1  (End)             4F      CF      q
1083     Keypad 2  (Down arrow)      50      D0      r
1084     Keypad 3  (PgDn)            51      D1      s
1085     Keypad 0  (Ins)             52      D2      p
1086     Keypad .  (Del)             53      D3      n
1087 */
1088 
1089 static unsigned char appl_table[] = "wxyStuvlqrspn";
1090 
1091 /*
1092   Set up keyboard to generate DEC VT200 F-keys.
1093   DEC F1  - F5  not implemented (DEC HOLD, LOCAL PRINT, SETUP, SW SESS, BREAK)
1094   DEC F6  - F10 are mapped to F6 - F10
1095   DEC F11 - F20 are mapped to Shift-F1 - Shift-F10
1096   DEC HELP and DEC DO are mapped to F11, F12 or Shift- F11, F12.
1097   Regular (?) Linux F1-F5 remain the same.
1098 */
1099 
1100 static char *func_table[2][12] = { /* DEC F1 - F10 */ {
1101         "\033[[A",  "\033[[B",  "\033[[C",  "\033[[D",
1102         "\033[[E",  "\033[17~", "\033[18~", "\033[19~",
1103         "\033[20~", "\033[21~", "\033[28~", "\033[29~"
1104 }, /* DEC F11 - F20 */ {
1105         "\033[23~", "\033[24~", "\033[25~", "\033[26~",
1106         "\033[28~", "\033[29~", "\033[31~", "\033[32~",
1107         "\033[33~", "\033[34~", "\033[28~", "\033[29~"
1108 }};
1109 
1110 static void cursor(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1111 {
1112         if (sc < 0x47 || sc > 0x53)
1113                 return;
1114         sc-=0x47;
1115         if (sc == 12 && (kmode&(LCTRL|RCTRL)) && (kmode&(ALT|ALTGR))) {
1116                 ctrl_alt_del();
1117                 return;
1118         }
1119         if (ke0 == 1) {
1120                 cur(sc);
1121                 return;
1122         }
1123 
1124         if ((kmode&ALT) && sc!=12) {                    /* Alt-numpad */
1125                 npadch=npadch*10+pad_table[sc];
1126                 return;
1127         }
1128 
1129         if (kapplic && !(kmode&(LSHIFT|RSHIFT))) {      /* shift forces cursor */
1130                 applkey(appl_table[sc]);
1131                 return;
1132         }
1133 
1134         if (kleds&NUMLED) {
1135                 put_queue(num_table[sc]);
1136         } else
1137                 cur(sc);
1138 }
1139 
1140 static void cur(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1141 {
1142         char buf[] = { 0x1b, '[', 0, 0, 0 };            /* must not be static */
1143 
1144         buf[2]=cur_table[sc];
1145         if (buf[2] < '9')
1146                 buf[3]='~';
1147         else
1148                 if ((buf[2] >= 'A' && buf[2] <= 'D') ? ckmode : kapplic)
1149                         buf[1]='O';
1150         puts_queue(buf);
1151 }
1152 
1153 static void func(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1154 {
1155         if (sc < 0x3b)
1156                 return;
1157         sc-=0x3b;
1158         if (sc > 9) {
1159                 sc-=18;
1160                 if (sc < 10 || sc > 11)
1161                         return;
1162         }
1163         if (kmode&ALT)
1164                 change_console(sc);
1165         else
1166                 if (kmode & ( LSHIFT | RSHIFT))         /* DEC F11 - F20 */
1167                         puts_queue(func_table[1][sc]);
1168                 else                                    /* DEC F1 - F10 */
1169                         puts_queue(func_table[0][sc]);
1170 }
1171 
1172 static void slash(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1173 {
1174         if (ke0 != 1)
1175                 do_self(sc);
1176         else if (kapplic)
1177                 applkey('Q');
1178         else
1179                 put_queue('/');
1180 }
1181 
1182 static void star(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1183 {
1184         if (kapplic)
1185                 applkey('R');
1186         else
1187                 do_self(sc);
1188 }
1189 
1190 static void enter(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1191 {
1192         if (ke0 == 1 && kapplic)
1193                 applkey('M');
1194         else {
1195                 put_queue(13);
1196                 if (lfnlmode)
1197                         put_queue(10);
1198         }
1199 }
1200 
1201 static void minus(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1202 {
1203         if (kapplic)
1204                 applkey('S');
1205         else
1206                 do_self(sc);
1207 }
1208 
1209 static void plus(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1210 {
1211         if (kapplic)
1212                 applkey('l');
1213         else
1214                 do_self(sc);
1215 }
1216 
1217 static void none(int sc)
     /* [previous][next][first][last][top][bottom][index][help] */
1218 {
1219 }
1220 
1221 /*
1222  * kb_wait waits for the keyboard controller buffer to empty.
1223  */
1224 
1225 static void kb_wait(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1226 {
1227         int i;
1228 
1229         for (i=0; i<0x10000; i++)
1230                 if ((inb(0x64)&0x02) == 0)
1231                         break;
1232 }
1233 
1234 /*
1235  * kb_ack waits for 0xfa to appear in port 0x60
1236  *
1237  * Suggested by Bruce Evans
1238  * Added by Niels Skou Olsen [NSO]
1239  * April 21, 1992
1240  *
1241  * Heavily inspired by kb_wait :-)
1242  * I don't know how much waiting actually is required,
1243  * but this seems to work
1244  */
1245 
1246 void kb_ack(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1247 {
1248         int i;
1249 
1250         for(i=0; i<0x10000; i++)
1251                 if (inb(0x60) == 0xfa)
1252                         break;
1253 }
1254 
1255 long no_idt[2] = {0, 0};
1256 
1257 /*
1258  * This routine reboots the machine by asking the keyboard
1259  * controller to pulse the reset-line low. We try that for a while,
1260  * and if it doesn't work, we do some other stupid things.
1261  */
1262 void hard_reset_now(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1263 {
1264         int i;
1265 
1266         sti();
1267         for (;;) {
1268                 for (i=0; i<100; i++) {
1269                         kb_wait();
1270                         *((unsigned short *)0x472)=0x1234;
1271                         outb(0xfe,0x64);         /* pulse reset low */
1272                 }
1273                 __asm__("\tlidt _no_idt"::);
1274         }
1275 }
1276 
1277 static fptr key_table[] = {
1278         none,do_self,do_self,do_self,           /* 00-03 s0 esc 1 2 */
1279         do_self,do_self,do_self,do_self,        /* 04-07 3 4 5 6 */
1280         do_self,do_self,do_self,do_self,        /* 08-0B 7 8 9 0 */
1281         do_self,do_self,do_self,do_self,        /* 0C-0F + ' bs tab */
1282         do_self,do_self,do_self,do_self,        /* 10-13 q w e r */
1283         do_self,do_self,do_self,do_self,        /* 14-17 t y u i */
1284         do_self,do_self,do_self,do_self,        /* 18-1B o p } ^ */
1285         enter,ctrl,do_self,do_self,             /* 1C-1F enter ctrl a s */
1286         do_self,do_self,do_self,do_self,        /* 20-23 d f g h */
1287         do_self,do_self,do_self,do_self,        /* 24-27 j k l | */
1288         do_self,do_self,lshift,do_self,         /* 28-2B { para lshift , */
1289         do_self,do_self,do_self,do_self,        /* 2C-2F z x c v */
1290         do_self,do_self,do_self,do_self,        /* 30-33 b n m , */
1291         do_self,slash,rshift,star,              /* 34-37 . - rshift * */
1292         alt,do_self,caps,func,                  /* 38-3B alt sp caps f1 */
1293         func,func,func,func,                    /* 3C-3F f2 f3 f4 f5 */
1294         func,func,func,func,                    /* 40-43 f6 f7 f8 f9 */
1295         func,num,scroll,cursor,                 /* 44-47 f10 num scr home */
1296         cursor,cursor,minus,cursor,             /* 48-4B up pgup - left */
1297         cursor,cursor,plus,cursor,              /* 4C-4F n5 right + end */
1298         cursor,cursor,cursor,cursor,            /* 50-53 dn pgdn ins del */
1299         none,none,do_self,func,                 /* 54-57 sysreq ? < f11 */
1300         func,none,none,none,                    /* 58-5B f12 ? ? ? */
1301         none,none,none,none,                    /* 5C-5F ? ? ? ? */
1302         none,none,none,none,                    /* 60-63 ? ? ? ? */
1303         none,none,none,none,                    /* 64-67 ? ? ? ? */
1304         none,none,none,none,                    /* 68-6B ? ? ? ? */
1305         none,none,none,none,                    /* 6C-6F ? ? ? ? */
1306         none,none,none,none,                    /* 70-73 ? ? ? ? */
1307         none,none,none,none,                    /* 74-77 ? ? ? ? */
1308         none,none,none,none,                    /* 78-7B ? ? ? ? */
1309         none,none,none,none,                    /* 7C-7F ? ? ? ? */
1310         none,none,none,none,                    /* 80-83 ? br br br */
1311         none,none,none,none,                    /* 84-87 br br br br */
1312         none,none,none,none,                    /* 88-8B br br br br */
1313         none,none,none,none,                    /* 8C-8F br br br br */
1314         none,none,none,none,                    /* 90-93 br br br br */
1315         none,none,none,none,                    /* 94-97 br br br br */
1316         none,none,none,none,                    /* 98-9B br br br br */
1317         none,unctrl,none,none,                  /* 9C-9F br unctrl br br */
1318         none,none,none,none,                    /* A0-A3 br br br br */
1319         none,none,none,none,                    /* A4-A7 br br br br */
1320         none,none,unlshift,none,                /* A8-AB br br unlshift br */
1321         none,none,none,none,                    /* AC-AF br br br br */
1322         none,none,none,none,                    /* B0-B3 br br br br */
1323         none,none,unrshift,none,                /* B4-B7 br br unrshift br */
1324         unalt,none,uncaps,none,                 /* B8-BB unalt br uncaps br */
1325         none,none,none,none,                    /* BC-BF br br br br */
1326         none,none,none,none,                    /* C0-C3 br br br br */
1327         none,none,none,none,                    /* C4-C7 br br br br */
1328         none,none,none,none,                    /* C8-CB br br br br */
1329         none,none,none,none,                    /* CC-CF br br br br */
1330         none,none,none,none,                    /* D0-D3 br br br br */
1331         none,none,none,none,                    /* D4-D7 br br br br */
1332         none,none,none,none,                    /* D8-DB br ? ? ? */
1333         none,none,none,none,                    /* DC-DF ? ? ? ? */
1334         none,none,none,none,                    /* E0-E3 e0 e1 ? ? */
1335         none,none,none,none,                    /* E4-E7 ? ? ? ? */
1336         none,none,none,none,                    /* E8-EB ? ? ? ? */
1337         none,none,none,none,                    /* EC-EF ? ? ? ? */
1338         none,none,none,none,                    /* F0-F3 ? ? ? ? */
1339         none,none,none,none,                    /* F4-F7 ? ? ? ? */
1340         none,none,none,none,                    /* F8-FB ? ? ? ? */
1341         none,none,none,none                     /* FC-FF ? ? ? ? */
1342 };

/* [previous][next][first][last][top][bottom][index][help] */