Changeset 3580

Show
Ignore:
Timestamp:
09/17/08 20:12:46 (2 months ago)
Author:
oxygene
Message:

- unify keycodes for non-ASCII keys by using curses' codes and labels
- fix ctrl-[a-z]
- get rid of curses' ps/2 driver. uses generic one instead
- #ifdef's around ps/2 keyboard handling and serial handling
- add alt-key handling (necessary for german keymap)
- flush keyboard controller buffer on init

Signed-off-by: Patrick Georgi <patrick.georgi@…>
Acked-by: Stefan Reinauer <stepan@…>

Location:
trunk/payloads/libpayload
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/payloads/libpayload/curses/keyboard.c

    r3568 r3580  
    139139/* ================ Keyboard ================ */ 
    140140 
    141 /* Scancode macros */ 
    142  
    143 #define DOWN(_c) (0x80 | (_c)) 
    144 #define UP(_c) (_c) 
    145  
    146 #define ISDOWN(_c) ((_c) & 0x80) 
    147 #define ISUP(_c) (!ISDOWN((_c))) 
    148  
    149 #define SCANCODE(_c) ((_c) & ~0x80) 
    150  
    151 /* Scancode definitions for the modifiers */ 
    152  
    153 #define SCANCODE_RSHIFT   0x36 
    154 #define SCANCODE_LSHIFT   0x2a 
    155 #define SCANCODE_CAPSLOCK 0x3a 
    156 #define SCANCODE_LALT     0x38 
    157 #define SCANCODE_LCTRL    0x1d 
    158  
    159 /* Modifier flags */ 
    160  
    161 #define SHIFT_MODIFIER    0x1 
    162 #define CAPSLOCK_MODIFIER 0x2 
    163 #define ALT_MODIFIER      0x4 
    164 #define CTRL_MODIFIER     0x8 
    165  
    166 #define CTRL(_c) (_c & 0x1f) 
    167  
    168 struct { 
    169         int normal; 
    170         int shift; 
    171 } scancode_map[] = { 
    172         { }, 
    173         { CTRL('['), CTRL('[')},  
    174         { '1', '!' }, 
    175         { '2', '@' }, 
    176         { '3', '#' }, 
    177         { '4', '$' }, 
    178         { '5', '%' }, 
    179         { '6', '^' }, 
    180         { '7', '&' }, 
    181         { '8', '*' }, 
    182         { '9', '(' }, 
    183         { '0', ')' }, 
    184         { '-', '_' }, 
    185         { '=', '+' }, 
    186         { KEY_BACKSPACE, KEY_BACKSPACE}, 
    187         { CTRL('I' ), KEY_BTAB },          /* 0x0F */ 
    188         { 'q', 'Q' }, 
    189         { 'w', 'W' }, 
    190         { 'e', 'E' }, 
    191         { 'r', 'R' }, 
    192         { 't', 'T' }, 
    193         { 'y', 'Y' }, 
    194         { 'u', 'U' }, 
    195         { 'i', 'I' }, 
    196         { 'o', 'O' }, 
    197         { 'p', 'P' }, 
    198         { '[', '{' }, 
    199         { ']', '{' }, 
    200         { KEY_ENTER, KEY_ENTER }, 
    201         { 0 , 0 }, 
    202         { 'a', 'A' }, 
    203         { 's', 'S' },                    /* 0x1F */ 
    204         { 'd', 'D' }, 
    205         { 'f', 'F' }, 
    206         { 'g', 'G' }, 
    207         { 'h', 'H' }, 
    208         { 'j', 'J' }, 
    209         { 'k', 'K' }, 
    210         { 'l', 'L' }, 
    211         { ';', ':' }, 
    212         { '\'', '\"' }, 
    213         { '`', '~', }, 
    214         { 0, 0 }, 
    215         { '\\', '|' }, 
    216         { 'z', 'Z' }, 
    217         { 'x', 'X' }, 
    218         { 'c', 'C' }, 
    219         { 'v', 'V' },                   /* 0x2F */ 
    220         { 'b', 'B' }, 
    221         { 'n', 'N' }, 
    222         { 'm', 'M' }, 
    223         { ',', '<'}, 
    224         { '.', '>' }, 
    225         { '/', '?' }, 
    226         { 0, 0 },                       /* RSHIFT */ 
    227         { '*', '*' }, 
    228         { 0, 0 },                       /* LALT */ 
    229         { ' ', ' ' },                   /* Space */ 
    230         { 0, 0 },                       /* Capslock */ 
    231         { KEY_F(1), KEY_F(1) }, 
    232         { KEY_F(2), KEY_F(2) }, 
    233         { KEY_F(3), KEY_F(3) }, 
    234         { KEY_F(4), KEY_F(4) }, 
    235         { KEY_F(5), KEY_F(5) },         /* 0x3F */ 
    236         { KEY_F(6), KEY_F(6) }, 
    237         { KEY_F(7), KEY_F(7) }, 
    238         { KEY_F(8), KEY_F(8) }, 
    239         { KEY_F(9), KEY_F(9) }, 
    240         { KEY_F(10), KEY_F(10) }, 
    241         { 0, 0 },                      /* Numlock */ 
    242         { 0, 0 },                      /* Scroll lock */ 
    243         { KEY_HOME, KEY_HOME }, 
    244         { KEY_UP,   KEY_UP }, 
    245         { KEY_PPAGE, KEY_PPAGE }, 
    246         { '-',      '-' }, 
    247         { KEY_LEFT, KEY_LEFT }, 
    248         { 0,        0 }, 
    249         { KEY_RIGHT, KEY_RIGHT }, 
    250         { '-',       '-' }, 
    251         { KEY_END,  KEY_END },         /* 0x4F */ 
    252         { KEY_DOWN, KEY_DOWN }, 
    253         { KEY_NPAGE, KEY_NPAGE }, 
    254         { KEY_IC,    KEY_IC }, 
    255         { KEY_DC,    KEY_DC }, 
    256         { 0, 0 },                     /* sysreq */ 
    257         { 0, 0 }, 
    258         { KEY_F(11), KEY_F(11) }, 
    259         { KEY_F(12), KEY_F(12) }, 
    260 }; 
    261  
    262 static int cook_scancodes(unsigned char code) 
    263 { 
    264         static int modifiers = 0; 
    265         int ch = 0, sc, shift; 
    266  
    267         switch (code) { 
    268         case DOWN(SCANCODE_RSHIFT): 
    269         case DOWN(SCANCODE_LSHIFT): 
    270                 modifiers |= SHIFT_MODIFIER; 
    271                 return 0; 
    272         case UP(SCANCODE_RSHIFT): 
    273         case UP(SCANCODE_LSHIFT): 
    274                 modifiers &= ~SHIFT_MODIFIER; 
    275                 return 0; 
    276         case UP(SCANCODE_CAPSLOCK): 
    277                 if (modifiers & CAPSLOCK_MODIFIER) 
    278                         modifiers &= ~CAPSLOCK_MODIFIER; 
    279                 else 
    280                         modifiers |= CAPSLOCK_MODIFIER; 
    281                 return 0; 
    282         case DOWN(SCANCODE_LALT): 
    283                 modifiers |= ALT_MODIFIER; 
    284                 return 0; 
    285         case UP(SCANCODE_LALT): 
    286                 modifiers &= ~ALT_MODIFIER; 
    287                 return 0; 
    288         case DOWN(SCANCODE_LCTRL): 
    289                 modifiers |= CTRL_MODIFIER; 
    290                 return 0; 
    291         case UP(SCANCODE_LCTRL): 
    292                 modifiers &= ~CTRL_MODIFIER; 
    293                 return 0; 
    294         } 
    295  
    296         /* Only process keys on an upstroke. */ 
    297         if (!ISUP(code)) 
    298                 return 0; 
    299  
    300         sc = SCANCODE(code); 
    301  
    302         if (sc == 0 || sc > 0x59) 
    303                 return ERR; 
    304  
    305         shift = (modifiers & SHIFT_MODIFIER) ^ (modifiers & CAPSLOCK_MODIFIER); 
    306  
    307         ch = shift ? scancode_map[sc].shift : scancode_map[sc].normal; 
    308  
    309         if (modifiers & CTRL_MODIFIER) 
    310                 ch = (ch >= 0x3F && ch <= 0x5F) ? CTRL(ch) : 0; 
    311  
    312         return ch; 
    313 } 
    314  
    315141static int curses_getchar(int delay) 
    316142{ 
    317         unsigned char c = 0; 
    318         int ret; 
     143        unsigned short c; 
    319144 
    320145        do { 
    321                 if (curses_flags & F_ENABLE_CONSOLE) 
    322                         c = inb(0x64); 
    323  
    324                 if ((c & 1) == 0) { 
    325  
    326                         if ((curses_flags & F_ENABLE_SERIAL) && 
    327                             serial_havechar()) { 
    328                                 c = serial_getchar(); 
    329                                 return cook_serial(c); 
    330                         } 
    331  
    332                         if (delay == 0) 
    333                                 break; 
    334  
    335                         if (delay > 0) { 
    336                                 mdelay(100); 
    337                                 delay--; 
    338                         } 
    339  
    340                         continue; 
    341                 } 
    342  
    343                 c = inb(0x60); 
    344  
    345                 ret = cook_scancodes(c); 
    346  
    347                 if (ret != 0) { 
    348                         return ret; 
    349                 } 
     146#ifdef CONFIG_PC_KEYBOARD 
     147                if ((curses_flags & F_ENABLE_CONSOLE) && 
     148                    keyboard_havechar()) { 
     149                        c = keyboard_getchar(); 
     150                        if (c != 0) return c; 
     151                } 
     152#endif 
     153 
     154#ifdef CONFIG_SERIAL_CONSOLE 
     155                if ((curses_flags & F_ENABLE_SERIAL) && 
     156                    serial_havechar()) { 
     157                        c = serial_getchar(); 
     158                        return cook_serial(c); 
     159                } 
     160#endif 
     161 
     162                if (delay == 0) 
     163                        break; 
     164 
     165                if (delay > 0) { 
     166                        mdelay(100); 
     167                        delay--; 
     168                } 
     169 
    350170 
    351171        } while (1); 
  • trunk/payloads/libpayload/drivers/keyboard.c

    r3558 r3580  
    2929 
    3030#include <libpayload.h> 
     31#include <curses.h> 
    3132 
    3233#define I8042_CMD_READ_MODE  0x20 
     
    3536#define I8042_MODE_XLATE     0x40 
    3637 
    37 unsigned char map[2][0x57] = { 
    38         { 
     38unsigned short map[4][0x57] = { 
     39        { /* No modifier */ 
    3940         0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 
    4041         0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, 
     
    4445         0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76, 
    4546         0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 
    46          0x00, 0x20, 
     47         0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     48         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, KEY_HOME, 
     49         KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END, 
     50         KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00 
    4751         }, 
    48         { 
     52        { /* Shift */ 
    4953         0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 
    5054         0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x00, 
     
    5458         0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56, 
    5559         0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 
    56          0x00, 0x20, 
     60         0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     61         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, KEY_HOME, 
     62         KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END, 
     63         KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00 
     64         }, 
     65        { /* ALT */ 
     66         0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 
     67         0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, 
     68         0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 
     69         0x6F, 0x70, 0x5B, 0x5D, 0x0A, 0x00, 0x61, 0x73, 
     70         0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 
     71         0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76, 
     72         0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 
     73         0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     74         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, KEY_HOME, 
     75         KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END, 
     76         KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00 
     77         }, 
     78        { /* Shift-ALT */ 
     79         0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 
     80         0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x00, 
     81         0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 
     82         0x4F, 0x50, 0x7B, 0x7D, 0x0A, 0x00, 0x41, 0x53, 
     83         0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 
     84         0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56, 
     85         0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 
     86         0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
     87         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, KEY_HOME, 
     88         KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END, 
     89         KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00 
    5790         } 
    5891}; 
    5992 
    60 #define MOD_SHIFT    1 
    61 #define MOD_CTRL     2 
    62 #define MOD_CAPSLOCK 4 
     93#define MOD_SHIFT    (1 << 0) 
     94#define MOD_CTRL     (1 << 1) 
     95#define MOD_CAPSLOCK (1 << 2) 
     96#define MOD_ALT      (1 << 3) 
    6397 
    6498int keyboard_havechar(void) 
     
    97131        case 0x80 | 0x2a: 
    98132                modifier &= ~MOD_SHIFT; 
     133                break; 
     134        case 0x38: 
     135                modifier |= MOD_ALT; 
     136                break; 
     137        case 0x80 | 0x38: 
     138                modifier &= ~MOD_ALT; 
    99139                break; 
    100140        case 0x1d: 
     
    115155                shift = 
    116156                    (modifier & MOD_SHIFT) ^ (modifier & MOD_CAPSLOCK) ? 1 : 0; 
     157 
     158                if (modifier & MOD_ALT) 
     159                        shift += 2; 
     160 
    117161                ret = map[shift][ch]; 
    118162 
    119163                if (modifier & MOD_CTRL) 
    120                         ret = (ret >= 0x3F && ret <= 0x5F) ? ret & 0x1f : 0; 
     164                        ret = (ret >= 'a' && ret <= 'z') ? ret & 0x1f : 0; 
    121165 
    122166                return ret; 
     
    164208        u8 mode; 
    165209 
     210        /* Empty keyboard buffer */ 
     211        while (keyboard_havechar()) keyboard_getchar(); 
     212 
    166213        /* Read the current mode */ 
    167214        mode = keyboard_get_mode();