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

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