diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 3442d42e7..c68919aef 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -30,39 +30,96 @@ static struct grub_keyboard_layout layout_us = { .keyboard_map = { - /* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', - /* 0x08 */ '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, - /* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - /* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's', - /* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', - /* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', - /* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*', - /* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1, - /* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, - /* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, - /* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, - /* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, - /* 0x44 */ GRUB_TERM_KEY_F10, '\0', '\0', GRUB_TERM_KEY_HOME, - /* 0x48 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, - /* 0x4c */ GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, - /* 0x4e */ '+', GRUB_TERM_KEY_END, - /* 0x50 */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, - /* 0x52 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, - /* 0x54 */ '\0', '\0', '\\', GRUB_TERM_KEY_F11, - /* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', - /* 0x60 */ '\0', '\0', '\0', '\0', - /* 0x64 */ '\0', GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_LEFT, - /* 0x68 */ GRUB_TERM_KEY_RIGHT + /* Keyboard errors. Handled by driver. */ + /* 0x00 */ 0, 0, 0, 0, + + /* 0x04 */ 'a', 'b', 'c', 'd', + /* 0x08 */ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + /* 0x10 */ 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + /* 0x18 */ 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', + /* 0x20 */ '3', '4', '5', '6', '7', '8', '9', '0', + /* 0x28 */ '\n', '\e', '\b', '\t', ' ', '-', '=', '[', + /* According to usage table 0x31 should be mapped to '/' + but testing with real keyboard shows that 0x32 is remapped to '/'. + Map 0x31 to 0. + */ + /* 0x30 */ ']', 0, '\\', ';', '\'', '`', ',', '.', + /* 0x39 is CapsLock. Handled by driver. */ + /* 0x38 */ '/', 0, GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2, + /* 0x3c */ GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, + /* 0x3e */ GRUB_TERM_KEY_F5, GRUB_TERM_KEY_F6, + /* 0x40 */ GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, + /* 0x42 */ GRUB_TERM_KEY_F9, GRUB_TERM_KEY_F10, + /* 0x44 */ GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12, + /* PrtScr and ScrollLock. Not handled yet. */ + /* 0x46 */ 0, 0, + /* 0x48 is Pause. Not handled yet. */ + /* 0x48 */ 0, GRUB_TERM_KEY_INSERT, + /* 0x4a */ GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_PPAGE, + /* 0x4c */ GRUB_TERM_KEY_DC, GRUB_TERM_KEY_END, + /* 0x4e */ GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_RIGHT, + /* 0x50 */ GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN, + /* 0x53 is NumLock. Handled by driver. */ + /* 0x52 */ GRUB_TERM_KEY_UP, 0, + /* 0x54 */ '/', '*', + /* 0x56 */ '-', '+', + /* 0x58 */ '\n', GRUB_TERM_KEY_END, + /* 0x5a */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_NPAGE, + /* 0x5c */ GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_CENTER, + /* 0x5e */ GRUB_TERM_KEY_RIGHT, GRUB_TERM_KEY_HOME, + /* 0x60 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_PPAGE, + /* 0x62 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, + /* 0x64 */ '\\' }, .keyboard_map_shift = { - '\0', '\0', '!', '@', '#', '$', '%', '^', - '&', '*', '(', ')', '_', '+', '\0', '\0', - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', - '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', - [0x56] = '|' + /* Keyboard errors. Handled by driver. */ + /* 0x00 */ 0, 0, 0, 0, + + /* 0x04 */ 'A', 'B', 'C', 'D', + /* 0x08 */ 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + /* 0x10 */ 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + /* 0x18 */ 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '@', + /* 0x20 */ '#', '$', '%', '^', '&', '*', '(', ')', + /* 0x28 */ '\n' | GRUB_TERM_SHIFT, '\e' | GRUB_TERM_SHIFT, + /* 0x2a */ '\b' | GRUB_TERM_SHIFT, '\t' | GRUB_TERM_SHIFT, + /* 0x2c */ ' ' | GRUB_TERM_SHIFT, '_', '+', '{', + /* According to usage table 0x31 should be mapped to '/' + but testing with real keyboard shows that 0x32 is remapped to '/'. + Map 0x31 to 0. + */ + /* 0x30 */ '}', 0, '|', ':', '"', '~', '<', '>', + /* 0x39 is CapsLock. Handled by driver. */ + /* 0x38 */ '?', 0, + /* 0x3a */ GRUB_TERM_KEY_F1 | GRUB_TERM_SHIFT, + /* 0x3b */ GRUB_TERM_KEY_F2 | GRUB_TERM_SHIFT, + /* 0x3c */ GRUB_TERM_KEY_F3 | GRUB_TERM_SHIFT, + /* 0x3d */ GRUB_TERM_KEY_F4 | GRUB_TERM_SHIFT, + /* 0x3e */ GRUB_TERM_KEY_F5 | GRUB_TERM_SHIFT, + /* 0x3f */ GRUB_TERM_KEY_F6 | GRUB_TERM_SHIFT, + /* 0x40 */ GRUB_TERM_KEY_F7 | GRUB_TERM_SHIFT, + /* 0x41 */ GRUB_TERM_KEY_F8 | GRUB_TERM_SHIFT, + /* 0x42 */ GRUB_TERM_KEY_F9 | GRUB_TERM_SHIFT, + /* 0x43 */ GRUB_TERM_KEY_F10 | GRUB_TERM_SHIFT, + /* 0x44 */ GRUB_TERM_KEY_F11 | GRUB_TERM_SHIFT, + /* 0x45 */ GRUB_TERM_KEY_F12 | GRUB_TERM_SHIFT, + /* PrtScr and ScrollLock. Not handled yet. */ + /* 0x46 */ 0, 0, + /* 0x48 is Pause. Not handled yet. */ + /* 0x48 */ 0, GRUB_TERM_KEY_INSERT | GRUB_TERM_SHIFT, + /* 0x4a */ GRUB_TERM_KEY_HOME | GRUB_TERM_SHIFT, + /* 0x4b */ GRUB_TERM_KEY_PPAGE | GRUB_TERM_SHIFT, + /* 0x4c */ GRUB_TERM_KEY_DC | GRUB_TERM_SHIFT, + /* 0x4d */ GRUB_TERM_KEY_END | GRUB_TERM_SHIFT, + /* 0x4e */ GRUB_TERM_KEY_NPAGE | GRUB_TERM_SHIFT, + /* 0x4f */ GRUB_TERM_KEY_RIGHT | GRUB_TERM_SHIFT, + /* 0x50 */ GRUB_TERM_KEY_LEFT | GRUB_TERM_SHIFT, + /* 0x51 */ GRUB_TERM_KEY_DOWN | GRUB_TERM_SHIFT, + /* 0x53 is NumLock. Handled by driver. */ + /* 0x52 */ GRUB_TERM_KEY_UP | GRUB_TERM_SHIFT, 0, + /* 0x54 */ '/', '*', + /* 0x56 */ '-', '+', + /* 0x58 */ '\n' | GRUB_TERM_SHIFT, '1', '2', '3', '4', '5','6', '7', + /* 0x60 */ '8', '9', '0', '.', '|' } }; @@ -82,88 +139,37 @@ map_key_core (int code, int status, int *alt_gr_consumed) *alt_gr_consumed = 1; return grub_current_layout->keyboard_map_shift_l3[code]; } - else if (grub_current_layout->keyboard_map_shift[code]) - { - *alt_gr_consumed = 1; - return grub_current_layout->keyboard_map_l3[code] - | GRUB_TERM_SHIFT; - } } - else if (grub_current_layout->keyboard_map_shift[code]) + else if (grub_current_layout->keyboard_map_l3[code]) { *alt_gr_consumed = 1; return grub_current_layout->keyboard_map_l3[code]; } } if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT)) - { - if (grub_current_layout->keyboard_map_shift[code]) - return grub_current_layout->keyboard_map_shift[code]; - else - return grub_current_layout->keyboard_map[code] | GRUB_TERM_SHIFT; - } + return grub_current_layout->keyboard_map_shift[code]; else return grub_current_layout->keyboard_map[code]; } -static int -map_high_key (int code, int status) -{ - int ret = 0; - if (status & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT)) - ret |= GRUB_TERM_SHIFT; - - if (code == 0xb5) - return '/'; - - if (code == 0xb7) - return '*'; - - if (code == 0x9c) - return '\n'; - - if (code < 0xc7 || code > 0xd3 || code == 0xca || code == 0xce - || code == 0xcc) - return ret; - /* GRUB keyboard codes are conveniently similar to AT codes. */ - return ret | GRUB_TERM_EXTENDED | (code & ~0x80); -} - -static int -map_num_key (int code, int state) -{ - const int map_arrows[] - = { GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_UP, GRUB_TERM_KEY_PPAGE, - '-', GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, '+', - GRUB_TERM_KEY_END, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_NPAGE, - GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC }; - const int map_nums[] - = { '7', '8', '9', '-', '4', '5', '6', '+', '1', '2', '3', '0', '.'}; - - if (((state & GRUB_TERM_STATUS_NUM) - && !(state & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT))) - || ((state & GRUB_TERM_STATUS_NUM) - && !(state & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT)))) - return map_nums [code - 0x47]; - else - return map_arrows [code - 0x47]; -} - unsigned grub_term_map_key (int code, int status) { int alt_gr_consumed = 0; int key; - if (code >= 0x47 && code <= 0x53) - key = map_num_key (code, status); - else if (code & 0x80) - key = map_high_key (code, status); - else - key = map_key_core (code, status, &alt_gr_consumed); + if (code >= 0x59 && code <= 0x63 && (status & GRUB_TERM_STATUS_NUM)) + { + if (status & (GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT)) + status &= ~(GRUB_TERM_STATUS_RSHIFT | GRUB_TERM_STATUS_LSHIFT); + else + status |= GRUB_TERM_STATUS_RSHIFT; + } + + key = map_key_core (code, status, &alt_gr_consumed); if (key == 0 || key == GRUB_TERM_SHIFT) - grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code); + grub_printf ("Unknown key 0x%x detected\n", code); if (status & GRUB_TERM_STATUS_CAPS) { diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index 10421540a..350ce3bf9 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -39,16 +39,4 @@ #define KEYBOARD_ISREADY(x) ((x) & 0x01) #define KEYBOARD_SCANCODE(x) ((x) & 0x7f) -#ifdef GRUB_MACHINE_IEEE1275 -#define OLPC_UP GRUB_TERM_UP -#define OLPC_DOWN GRUB_TERM_DOWN -#define OLPC_LEFT GRUB_TERM_LEFT -#define OLPC_RIGHT GRUB_TERM_RIGHT -#else -#define OLPC_UP '\0' -#define OLPC_DOWN '\0' -#define OLPC_LEFT '\0' -#define OLPC_RIGHT '\0' -#endif - #endif diff --git a/include/grub/atkeymap.h b/include/grub/atkeymap.h new file mode 100644 index 000000000..a8b9140ff --- /dev/null +++ b/include/grub/atkeymap.h @@ -0,0 +1,111 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_AT_KEYMAP_HEADER +#define GRUB_AT_KEYMAP_HEADER 1 + +static inline int +grub_at_map_to_usb (grub_uint8_t keycode) +{ + /* Modifier keys (ctrl, alt, shift, capslock, numlock and scrolllock + are handled by driver and hence here are mapped to 0)*/ + + static const grub_uint8_t at_to_usb_map[] = + { + /* 0x00 */ 0x00 /* Unused */, 0x29 /* Escape */, + /* 0x02 */ 0x1e /* 1 */, 0x1f /* 2 */, + /* 0x04 */ 0x20 /* 3 */, 0x21 /* 4 */, + /* 0x06 */ 0x22 /* 5 */, 0x23 /* 6 */, + /* 0x08 */ 0x24 /* 7 */, 0x25 /* 8 */, + /* 0x0a */ 0x26 /* 9 */, 0x27 /* 0 */, + /* 0x0c */ 0x2d /* - */, 0x2e /* = */, + /* 0x0e */ 0x2a /* \b */, 0x2b /* \t */, + /* 0x10 */ 0x14 /* q */, 0x1a /* w */, + /* 0x12 */ 0x08 /* e */, 0x15 /* r */, + /* 0x14 */ 0x17 /* t */, 0x1c /* y */, + /* 0x16 */ 0x18 /* u */, 0x0c /* i */, + /* 0x18 */ 0x12 /* o */, 0x13 /* p */, + /* 0x1a */ 0x2f /* [ */, 0x30 /* ] */, + /* 0x1c */ 0x28 /* Enter */, 0x00 /* Left CTRL */, + /* 0x1e */ 0x04 /* a */, 0x16 /* s */, + /* 0x20 */ 0x07 /* d */, 0x09 /* f */, + /* 0x22 */ 0x0a /* g */, 0x0b /* h */, + /* 0x24 */ 0x0d /* j */, 0x0e /* k */, + /* 0x26 */ 0x0f /* l */, 0x33 /* ; */, + /* 0x28 */ 0x34 /* " */, 0x35 /* ` */, + /* 0x2a */ 0x00 /* Left Shift */, 0x32 /* \ */, + /* 0x2c */ 0x1d /* z */, 0x1b /* x */, + /* 0x2e */ 0x06 /* c */, 0x19 /* v */, + /* 0x30 */ 0x05 /* b */, 0x11 /* n */, + /* 0x32 */ 0x10 /* m */, 0x36 /* , */, + /* 0x34 */ 0x37 /* . */, 0x38 /* / */, + /* 0x36 */ 0x00 /* Right Shift */, 0x55 /* Num * */, + /* 0x38 */ 0x00 /* Left ALT */, 0x2c /* Space */, + /* 0x3a */ 0x39 /* Caps Lock */, 0x3a /* F1 */, + /* 0x3c */ 0x3b /* F2 */, 0x3c /* F3 */, + /* 0x3e */ 0x3d /* F4 */, 0x3e /* F5 */, + /* 0x40 */ 0x3f /* F6 */, 0x40 /* F7 */, + /* 0x42 */ 0x41 /* F8 */, 0x42 /* F9 */, + /* 0x44 */ 0x43 /* F10 */, 0x53 /* NumLock */, + /* 0x46 */ 0x47 /* Scroll Lock */, 0x5f /* Num 7 */, + /* 0x48 */ 0x60 /* Num 8 */, 0x61 /* Num 9 */, + /* 0x4a */ 0x56 /* Num - */, 0x5c /* Num 4 */, + /* 0x4c */ 0x5d /* Num 5 */, 0x5e /* Num 6 */, + /* 0x4e */ 0x57 /* Num + */, 0x59 /* Num 1 */, + /* 0x50 */ 0x5a /* Num 2 */, 0x5b /* Num 3 */, + /* 0x52 */ 0x62 /* Num 0 */, 0x63 /* Num . */, + /* 0x54 */ 0x00, 0x00, + /* 0x56 */ 0x64 /* 102nd key. */, 0x44 /* F11 */, + /* 0x58 */ 0x45 /* F12 */, 0x00 + }; + + static const struct + { + grub_uint8_t from, to; + } at_to_usb_extended[] = + { + /* OLPC keys. Just mapped to normal keys. */ + {0x65, 0x52 /* Up */ }, + {0x66, 0x51 /* Down */ }, + {0x67, 0x50 /* Left */ }, + {0x68, 0x4f /* Right */ }, + + {0x9c, 0x58 /* Num \n */}, + {0xb5, 0x54 /* Num / */ }, + {0xc7, 0x4a /* Home */ }, + {0xc8, 0x52 /* Up */ }, + {0xc9, 0x4e /* NPage */ }, + {0xcb, 0x50 /* Left */ }, + {0xcd, 0x4f /* Right */ }, + {0xcf, 0x4d /* End */ }, + {0xd0, 0x51 /* Down */ }, + {0xd1, 0x4b /* PPage */ }, + {0xd2, 0x49 /* Insert */}, + {0xd3, 0x4c /* DC */ }, + }; + if (keycode >= ARRAY_SIZE (at_to_usb_map)) + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (at_to_usb_extended); i++) + if (at_to_usb_extended[i].from == keycode) + return at_to_usb_extended[i].to; + return 0; + } + return at_to_usb_map[keycode]; +} +#endif diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h index f1d2fb282..b562d671e 100644 --- a/include/grub/keyboard_layouts.h +++ b/include/grub/keyboard_layouts.h @@ -21,7 +21,7 @@ #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) -#define GRUB_KEYBOARD_LAYOUTS_VERSION 6 +#define GRUB_KEYBOARD_LAYOUTS_VERSION 7 #define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 128 diff --git a/term/at_keyboard.c b/term/at_keyboard.c index c98fc8255..f8595a41a 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -23,6 +23,7 @@ #include #include #include +#include static short at_keyboard_status = 0; static int extended_pending = 0; @@ -123,6 +124,8 @@ grub_keyboard_getkey (void) key = grub_inb (KEYBOARD_REG_DATA); /* FIXME */ grub_keyboard_isr (key); ret = KEYBOARD_SCANCODE (key); + if (ret == SHIFT_L || ret == SHIFT_R || ret == ALT || ret == CTRL) + return -1; if (extended_pending) ret |= 0x80; extended_pending = (key == 0xe0); @@ -175,7 +178,8 @@ grub_at_keyboard_getkey_noblock (void) keyboard_controller_led (led_status); return -1; default: - return grub_term_map_key (code, at_keyboard_status); + return grub_term_map_key (grub_at_map_to_usb (code), + at_keyboard_status); } } diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 1082e62d0..b57b171f8 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -29,76 +29,6 @@ -static grub_uint8_t usb_to_at_map[128] = -{ - /* 0x00 */ 0x00, 0x00, - /* 0x02 */ 0x00, 0x00, - /* 0x04 */ 0x1e /* a */, 0x30 /* b */, - /* 0x06 */ 0x2e /* c */, 0x20 /* d */, - /* 0x08 */ 0x12 /* e */, 0x21 /* f */, - /* 0x0a */ 0x22 /* g */, 0x23 /* h */, - /* 0x0c */ 0x17 /* i */, 0x24 /* j */, - /* 0x0e */ 0x25 /* k */, 0x26 /* l */, - /* 0x10 */ 0x32 /* m */, 0x31 /* n */, - /* 0x12 */ 0x18 /* o */, 0x19 /* p */, - /* 0x14 */ 0x10 /* q */, 0x13 /* r */, - /* 0x16 */ 0x1f /* s */, 0x14 /* t */, - /* 0x18 */ 0x16 /* u */, 0x2f /* v */, - /* 0x1a */ 0x11 /* w */, 0x2d /* x */, - /* 0x1c */ 0x15 /* y */, 0x2c /* z */, - /* 0x1e */ 0x02 /* 1 */, 0x03 /* 2 */, - /* 0x20 */ 0x04 /* 3 */, 0x05 /* 4 */, - /* 0x22 */ 0x06 /* 5 */, 0x07 /* 6 */, - /* 0x24 */ 0x08 /* 7 */, 0x09 /* 8 */, - /* 0x26 */ 0x0a /* 9 */, 0x0b /* 0 */, - /* 0x28 */ 0x1c /* Enter */, 0x01 /* Escape */, - /* 0x2a */ 0x0e /* \b */, 0x0f /* \t */, - /* 0x2c */ 0x39 /* Space */, 0x0c /* - */, - /* 0x2e */ 0x0d /* = */, 0x1a /* [ */, - /* According to usage table 0x31 should be remapped to 0x2b - but testing with real keyboard shows that 0x32 is remapped to 0x2b. */ - /* 0x30 */ 0x1b /* ] */, 0x00, - /* 0x32 */ 0x2b /* \ */, 0x27 /* ; */, - /* 0x34 */ 0x28 /* " */, 0x29 /* ` */, - /* 0x36 */ 0x33 /* , */, 0x34 /* . */, - /* 0x38 */ 0x35 /* / */, 0x00, - /* 0x3a */ 0x3b /* F1 */, 0x3c /* F2 */, - /* 0x3c */ 0x3d /* F3 */, 0x3e /* F4 */, - /* 0x3e */ 0x3f /* F5 */, 0x40 /* F6 */, - /* 0x40 */ 0x41 /* F7 */, 0x42 /* F8 */, - /* 0x42 */ 0x43 /* F9 */, 0x44 /* F10 */, - /* 0x44 */ 0x57 /* F11 */, 0x58 /* F12 */, - /* 0x46 */ 0x00, 0x00, - /* 0x48 */ 0x00, 0xd2 /* Insert */, - /* 0x4a */ 0xc7 /* HOME */, 0xd1 /* PPAGE */, - /* 0x4c */ 0xd3 /* DC */, 0xcf /* END */, - /* 0x4e */ 0xc9 /* NPAGE */, 0xcd /* RIGHT */, - /* 0x50 */ 0xcb /* LEFT */, 0xd0 /* DOWN */, - /* 0x52 */ 0xc8 /* UP */, 0x00, - /* 0x54 */ 0xb5 /* Num / */, 0xb7 /* Num * */, - /* 0x56 */ 0x4a /* Num - */, 0x4e /* Num + */, - /* 0x58 */ 0x9c /* Num \n */, 0x4f /* Num 1 */, - /* 0x5a */ 0x50 /* Num 2 */, 0x51 /* Num 3 */, - /* 0x5c */ 0x4b /* Num 4 */, 0x4c /* Num 5 */, - /* 0x5e */ 0x4d /* Num 6 */, 0x47 /* Num 7 */, - /* 0x60 */ 0x48 /* Num 8 */, 0x49 /* Num 9 */, - /* 0x62 */ 0x52 /* Num 0 */, 0x53 /* Num . */, - /* 0x64 */ 0x56 /* 102nd key. */, 0x00, - /* 0x66 */ 0x00, 0x00, - /* 0x68 */ 0x00, 0x00, - /* 0x6a */ 0x00, 0x00, - /* 0x6c */ 0x00, 0x00, - /* 0x6e */ 0x00, 0x00, - /* 0x70 */ 0x00, 0x00, - /* 0x72 */ 0x00, 0x00, - /* 0x74 */ 0x00, 0x00, - /* 0x76 */ 0x00, 0x00, - /* 0x78 */ 0x00, 0x00, - /* 0x7a */ 0x00, 0x00, - /* 0x7c */ 0x00, 0x00, - /* 0x7e */ 0x00, 0x00, -}; - enum { KEY_NO_KEY = 0x00, @@ -428,16 +358,9 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) return -1; } - if (data[2] >= ARRAY_SIZE (usb_to_at_map) || usb_to_at_map[data[2]] == 0) - grub_printf ("Unknown key 0x%02x detected\n", data[2]); - else - { - termdata->last_key = termdata->key - = grub_term_map_key (usb_to_at_map[data[2]], - interpret_status (data[0]) | termdata->mods); - termdata->repeat_time = grub_get_time_ms () - + GRUB_TERM_REPEAT_PRE_INTERVAL; - } + termdata->last_key = termdata->key + = grub_term_map_key (data[2], interpret_status (data[0]) | termdata->mods); + termdata->repeat_time = grub_get_time_ms () + GRUB_TERM_REPEAT_PRE_INTERVAL; grub_errno = GRUB_ERR_NONE; diff --git a/util/grub-mklayout.c b/util/grub-mklayout.c index 91dea87a6..3aafd8837 100644 --- a/util/grub-mklayout.c +++ b/util/grub-mklayout.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include @@ -47,19 +47,47 @@ struct console_grub_equivalence grub_uint32_t grub; }; -static struct console_grub_equivalence console_grub_equivalences[] = { +static struct console_grub_equivalence console_grub_equivalences_shift[] = { + {"KP_0", '0'}, + {"KP_1", '1'}, + {"KP_2", '2'}, + {"KP_3", '3'}, + {"KP_4", '4'}, + {"KP_5", '5'}, + {"KP_6", '6'}, + {"KP_7", '7'}, + {"KP_8", '8'}, + {"KP_9", '9'}, + {"KP_Period", '.'}, +}; + +static struct console_grub_equivalence console_grub_equivalences_unshift[] = { + {"KP_0", GRUB_TERM_KEY_INSERT}, + {"KP_1", GRUB_TERM_KEY_END}, + {"KP_2", GRUB_TERM_KEY_DOWN}, + {"KP_3", GRUB_TERM_KEY_NPAGE}, + {"KP_4", GRUB_TERM_KEY_LEFT}, + {"KP_5", GRUB_TERM_KEY_CENTER}, + {"KP_6", GRUB_TERM_KEY_RIGHT}, + {"KP_7", GRUB_TERM_KEY_HOME}, + {"KP_8", GRUB_TERM_KEY_UP}, + {"KP_9", GRUB_TERM_KEY_PPAGE}, + {"KP_Period", GRUB_TERM_KEY_DC}, +}; + +static struct console_grub_equivalence console_grub_equivalences_common[] = { {"Escape", GRUB_TERM_ESC}, {"Tab", GRUB_TERM_TAB}, {"Delete", GRUB_TERM_BACKSPACE}, + {"KP_Enter", '\n'}, + {"Return", '\n'}, + {"KP_Multiply", '*'}, {"KP_Subtract", '-'}, {"KP_Add", '+'}, {"KP_Divide", '/'}, - {"KP_Enter", '\n'}, - {"Return", '\n'}, - {"F1", GRUB_TERM_KEY_F1}, {"F2", GRUB_TERM_KEY_F2}, {"F3", GRUB_TERM_KEY_F3}, @@ -116,6 +144,9 @@ static struct console_grub_equivalence console_grub_equivalences[] = { {"End", GRUB_TERM_KEY_END}, {"Right", GRUB_TERM_KEY_RIGHT}, {"Left", GRUB_TERM_KEY_LEFT}, + {"Next", GRUB_TERM_KEY_NPAGE}, + {"Prior", GRUB_TERM_KEY_PPAGE}, + {"Remove", GRUB_TERM_KEY_DC}, {"VoidSymbol", 0}, /* "Undead" keys since no dead key support in GRUB. */ @@ -132,24 +163,8 @@ static struct console_grub_equivalence console_grub_equivalences[] = { {"dead_breve", 0}, {"dead_doubleacute", 0}, - /* NumLock not supported yet. */ - {"KP_0", GRUB_TERM_KEY_INSERT}, - {"KP_1", GRUB_TERM_KEY_END}, - {"KP_2", GRUB_TERM_KEY_DOWN}, - {"KP_3", GRUB_TERM_KEY_NPAGE}, - {"KP_4", GRUB_TERM_KEY_LEFT}, - {"KP_5", 0}, - {"KP_6", GRUB_TERM_KEY_RIGHT}, - {"KP_7", GRUB_TERM_KEY_HOME}, - {"KP_8", GRUB_TERM_KEY_UP}, - {"KP_9", GRUB_TERM_KEY_PPAGE}, - {"KP_Period", GRUB_TERM_KEY_DC}, - /* Unused in GRUB. */ {"Pause", 0}, - {"Remove", 0}, - {"Next", 0}, - {"Prior", 0}, {"Scroll_Forward", 0}, {"Scroll_Backward", 0}, {"Hex_0", 0}, @@ -174,16 +189,6 @@ static struct console_grub_equivalence console_grub_equivalences[] = { {"Control_backslash", 0}, {"Compose", 0}, - /* Keys currently not remappable. */ - {"CtrlL_Lock", 0}, - {"Caps_Lock", 0}, - {"ShiftL", 0}, - {"Num_Lock", 0}, - {"Alt", 0}, - {"AltGr", 0}, - {"Control", 0}, - {"Shift", 0}, - {NULL, '\0'} }; @@ -205,24 +210,30 @@ Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT); exit (status); } -void +static void add_special_keys (struct grub_keyboard_layout *layout) { - /* OLPC keys. */ - layout->keyboard_map[101] = GRUB_TERM_KEY_UP; - layout->keyboard_map[102] = GRUB_TERM_KEY_DOWN; - layout->keyboard_map[103] = GRUB_TERM_KEY_LEFT; - layout->keyboard_map[104] = GRUB_TERM_KEY_RIGHT; + (void) layout; } static unsigned -lookup (char *code) +lookup (char *code, int shift) { int i; + struct console_grub_equivalence *pr; - for (i = 0; console_grub_equivalences[i].layout != NULL; i++) - if (strcmp (code, console_grub_equivalences[i].layout) == 0) - return console_grub_equivalences[i].grub; + if (shift) + pr = console_grub_equivalences_shift; + else + pr = console_grub_equivalences_unshift; + + for (i = 0; pr[i].layout != NULL; i++) + if (strcmp (code, pr[i].layout) == 0) + return pr[i].grub; + + for (i = 0; console_grub_equivalences_common[i].layout != NULL; i++) + if (strcmp (code, console_grub_equivalences_common[i].layout) == 0) + return console_grub_equivalences_common[i].grub; fprintf (stderr, "Unknown key %s\n", code); @@ -230,7 +241,7 @@ lookup (char *code) } static unsigned int -get_grub_code (char *layout_code) +get_grub_code (char *layout_code, int shift) { unsigned int code; @@ -239,7 +250,7 @@ get_grub_code (char *layout_code) else if (strncmp (layout_code, "+U+", sizeof ("+U+") - 1) == 0) sscanf (layout_code, "+U+%x", &code); else - code = lookup (layout_code); + code = lookup (layout_code, shift); return code; } @@ -287,21 +298,60 @@ write_keymaps (FILE *in, FILE *out) { if (strncmp (line, "keycode", sizeof ("keycode") - 1) == 0) { - unsigned keycode; + unsigned keycode_at, orig; + unsigned keycode_usb; char normal[64]; char shift[64]; char normalalt[64]; char shiftalt[64]; + static grub_uint8_t e0_remap[] = { + 0x9c /* Num \n */, 0x9d /* Right CTRL */, 0xb5 /* Num / */, + 0, 0xb8 /* Right ALT */, 0, + 0xc7 /* Home */, 0xc8 /* Up */, 0xc9 /* NPage*/, 0xcb /* Left */, + 0xcd /* Right */, 0xcf /* End */, 0xd0 /* Down */, 0xd1 /* PPage */, + 0xd2 /* Insert */, 0xd3 /* Delete */ + }; - sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode, + sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode_at, normal, shift, normalalt, shiftalt); - if (keycode < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) + orig = keycode_at; + + /* Not used. */ + if (keycode_at == 0x77 /* Pause */ + /* Some obscure keys */ + || keycode_at == 0x63 || keycode_at == 0x7d || keycode_at == 0x7e) + continue; + + if (keycode_at >= 96 && keycode_at < 96 + ARRAY_SIZE (e0_remap)) + keycode_at = e0_remap[keycode_at - 96]; + + /* Not remappable. */ + if (keycode_at == 0x1d /* Left CTRL */ + || keycode_at == 0x9d /* Right CTRL */ + || keycode_at == 0x2a /* Left Shift. */ + || keycode_at == 0x36 /* Right Shift. */ + || keycode_at == 0x38 /* Left ALT. */ + || keycode_at == 0xb8 /* Right ALT. */ + || keycode_at == 0x3a /* CapsLock. */ + || keycode_at == 0x45 /* NumLock. */ + || keycode_at == 0x46 /* ScrollLock. */) + continue; + + keycode_usb = grub_at_map_to_usb (keycode_at); + if (keycode_usb == 0 + || keycode_usb >= GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) { - layout.keyboard_map[keycode] = get_grub_code (normal); - layout.keyboard_map_shift[keycode] = get_grub_code (shift); - layout.keyboard_map_l3[keycode] = get_grub_code (normalalt); - layout.keyboard_map_shift_l3[keycode] - = get_grub_code (shiftalt); + fprintf (stderr, "Unknown keycode 0x%02x\n", orig); + continue; + } + if (keycode_usb < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE) + { + layout.keyboard_map[keycode_usb] = get_grub_code (normal, 0); + layout.keyboard_map_shift[keycode_usb] = get_grub_code (shift, 1); + layout.keyboard_map_l3[keycode_usb] + = get_grub_code (normalalt, 0); + layout.keyboard_map_shift_l3[keycode_usb] + = get_grub_code (shiftalt, 1); ok = 1; } }