Changeset 3605

Show
Ignore:
Timestamp:
09/26/08 20:37:26 (3 months ago)
Author:
stepan
Message:

* add keyboard layout support to libpayload
* add a reset handler mechanism (CTRL-ALT-DEL)

Signed-off-by: Stefan Reinauer <stepan@…>
Acked-by: Jordan Crouse <jordan.crouse@…>

Location:
trunk/payloads/libpayload
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/payloads/libpayload/Config.in

    r3560 r3605  
    101101        default y 
    102102 
     103config PC_KEYBOARD_LAYOUT_US 
     104        bool "English (US) keyboard layout" 
     105        depends on PC_KEYBOARD 
     106        default y 
     107 
     108config PC_KEYBOARD_LAYOUT_DE 
     109        bool "German keyboard layout" 
     110        depends on PC_KEYBOARD 
     111        default n 
     112 
    103113endmenu 
    104114 
  • trunk/payloads/libpayload/drivers/keyboard.c

    r3581 r3605  
    2929 
    3030#include <libpayload.h> 
     31#include <config.h> 
    3132#include <curses.h> 
    3233 
     
    3637#define I8042_MODE_XLATE     0x40 
    3738 
    38 unsigned short map[4][0x57] = { 
     39static void (*reset_handler)(void) = NULL; 
     40 
     41struct layout_maps { 
     42        char *country; 
     43        unsigned short map[4][0x57]; 
     44}; 
     45 
     46struct layout_maps *map; 
     47 
     48struct layout_maps keyboard_layouts[] = { 
     49#ifdef CONFIG_PC_KEYBOARD_LAYOUT_US 
     50{ .country = "us", .map = { 
    3951        { /* No modifier */ 
    4052         0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 
     
    89101         KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00 
    90102         } 
     103}}, 
     104#endif 
     105#ifdef CONFIG_PC_KEYBOARD_LAYOUT_DE 
     106{ .country = "de", .map = { 
     107        { /* No modifier */ 
     108         0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 
     109         0x37, 0x38, 0x39, 0x30, 0x00, 0x27, 0x08, 0x09, 
     110         0x71, 0x77, 0x65, 0x72, 0x74, 0x7A, 0x75, 0x69, 
     111         0x6F, 0x70, 0x00, 0x2B, 0x0A, 0x00, 0x61, 0x73, 
     112         0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x00, 
     113         0x00, 0x5E, 0x00, 0x23, 0x79, 0x78, 0x63, 0x76, 
     114         0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2D, 0x00, 0x2A, 
     115         0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), 
     116         KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME, 
     117         KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END, 
     118         KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x3C 
     119         }, 
     120        { /* Shift */ 
     121         0x00, 0x1B, 0x21, 0x22, 0xA7, 0x24, 0x25, 0x26, 
     122         0x2F, 0x28, 0x29, 0x3D, 0x3F, 0x60, 0x08, 0x00, 
     123         0x51, 0x57, 0x45, 0x52, 0x54, 0x5A, 0x55, 0x49, 
     124         0x4F, 0x50, 0x00, 0x2A, 0x0A, 0x00, 0x41, 0x53, 
     125         0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x00, 
     126         0x00, 0x7E, 0x00, 0x27, 0x59, 0x58, 0x43, 0x56, 
     127         0x42, 0x4E, 0x4D, 0x3B, 0x3A, 0x5F, 0x00, 0x2A, 
     128         0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), 
     129         KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME, 
     130         KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END, 
     131         KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x3E 
     132         }, 
     133        { /* ALT */ 
     134         0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 
     135         0x7B, 0x5B, 0x5D, 0x7D, 0x5C, 0x3D, 0x08, 0x09, 
     136         0x40, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 
     137         0x6F, 0x70, 0x5B, 0x7E, 0x0A, 0x00, 0x61, 0x73, 
     138         0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 
     139         0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76, 
     140         0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 
     141         0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), 
     142         KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME, 
     143         KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END, 
     144         KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x7C 
     145         }, 
     146        { /* Shift-ALT */ 
     147         /* copied from US */ 
     148         0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 
     149         0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x00, 
     150         0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 
     151         0x4F, 0x50, 0x7B, 0x7D, 0x0A, 0x00, 0x41, 0x53, 
     152         0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 
     153         0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56, 
     154         0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 
     155         0x00, 0x20, 0x00, KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), 
     156         KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10), 0x00, 0x00, KEY_HOME, 
     157         KEY_UP, KEY_NPAGE, 0x00, KEY_LEFT, 0x00, KEY_RIGHT, 0x00, KEY_END, 
     158         KEY_DOWN, KEY_PPAGE, 0x00, KEY_DC, 0x00, 0x00, 0x00 
     159         } 
     160}}, 
     161#endif 
    91162}; 
    92163 
     
    96167#define MOD_ALT      (1 << 3) 
    97168 
     169static void keyboard_cmd(unsigned char cmd, unsigned char val) 
     170{ 
     171        outb(cmd, 0x60); 
     172        /* wait until keyboard controller accepts cmds: */ 
     173        while (inb(0x64) & 2); 
     174        outb(val, 0x60); 
     175        while (inb(0x64) & 2); 
     176} 
     177 
     178 
    98179int keyboard_havechar(void) 
    99180{ 
     
    145226                break; 
    146227        case 0x3a: 
    147                 if (modifier & MOD_CAPSLOCK) 
     228                if (modifier & MOD_CAPSLOCK) { 
    148229                        modifier &= ~MOD_CAPSLOCK; 
    149                 else 
     230                        keyboard_cmd(0xed, (0 << 2)); 
     231                } else { 
    150232                        modifier |= MOD_CAPSLOCK; 
     233                        keyboard_cmd(0xed, (1 << 2)); 
     234                } 
    151235                break; 
    152236        } 
     
    159243                        shift += 2; 
    160244 
    161                 ret = map[shift][ch]; 
    162  
    163                 if (modifier & MOD_CTRL) 
    164                         ret = (ret >= 'a' && ret <= 'z') ? ret & 0x1f : 0; 
    165  
    166                 return ret; 
     245                ret = map->map[shift][ch]; 
     246 
     247                if (modifier & MOD_CTRL) { 
     248                        switch (ret) { 
     249                        case 'a' ... 'z': 
     250                                ret &= 0x1f; 
     251                                break; 
     252                        case KEY_DC: 
     253                                /* vulcan nerve pinch */ 
     254                                if ((modifier & MOD_ALT) && reset_handler) 
     255                                        reset_handler(); 
     256                        default: 
     257                                ret = 0; 
     258                        } 
     259                } 
    167260        } 
    168261 
     
    204297} 
    205298 
     299/** 
     300 * Set keyboard layout 
     301 * @param country string describing the keyboard layout language.  
     302 * Valid values are "en", "de". 
     303 */ 
     304 
     305int keyboard_set_layout(char *country) 
     306{ 
     307        int i; 
     308 
     309        for (i=0; i<ARRAY_SIZE(keyboard_layouts); i++) { 
     310                if (strncmp(keyboard_layouts[i].country, country, 
     311                                        strlen(keyboard_layouts[i].country))) 
     312                        continue; 
     313 
     314                /* Found, changing keyboard layout */ 
     315                map = &keyboard_layouts[i]; 
     316                return 0; 
     317        } 
     318 
     319        /* Nothing found, not changed */ 
     320        return -1; 
     321} 
     322 
     323int keyboard_add_reset_handler(void (*new_handler)(void)) 
     324{ 
     325        reset_handler = new_handler; 
     326 
     327        return 0; 
     328} 
     329 
    206330void keyboard_init(void) 
    207331{ 
    208332        u8 mode; 
     333        map = &keyboard_layouts[0]; 
    209334 
    210335        /* Empty keyboard buffer */ 
  • trunk/payloads/libpayload/include/libpayload.h

    r3604 r3605  
    124124unsigned char keyboard_get_scancode(void); 
    125125int keyboard_getchar(void); 
     126int keyboard_set_layout(char *country); 
     127int keyboard_add_reset_handler(void (*new_handler)(void)); 
    126128/** @} */ 
    127129