diff --git a/commands/keylayouts.c b/commands/keylayouts.c index 25a117560..bfe30d2ab 100644 --- a/commands/keylayouts.c +++ b/commands/keylayouts.c @@ -23,167 +23,11 @@ #include #include #include -#include #include #include #include #include -GRUB_AT_KEY_KEYBOARD_MAP (keyboard_map); - -static int -get_abstract_code (grub_term_input_t term, int in) -{ - switch (term->flags & GRUB_TERM_INPUT_FLAGS_TYPE_MASK) - { - case GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES: - default: - return in; - case GRUB_TERM_INPUT_FLAGS_TYPE_BIOS: - { - unsigned status = 0; - unsigned flags = 0; - - if (term->getkeystatus) - status = term->getkeystatus (term); - if (status & GRUB_TERM_CAPS) - flags |= GRUB_TERM_CAPS; - - if ((0x5600 | '\\') == (in & 0xffff)) - return GRUB_TERM_KEY_102 | flags; - - if ((0x5600 | '|') == (in & 0xffff)) - return GRUB_TERM_KEY_SHIFT_102 | flags; - - if ((in & 0xff00) == 0x3500 || (in & 0xff00) == 0x3700 - || (in & 0xff00) == 0x4500 - || ((in & 0xff00) >= 0x4700 && (in & 0xff00) <= 0x5300)) - flags |= GRUB_TERM_KEYPAD; - - /* Detect CTRL'ed keys. */ - if ((in & 0xff) > 0 && (in & 0xff) < 0x20 - && ((in & 0xffff) != (0x0100 | '\e')) - && ((in & 0xffff) != (0x0f00 | '\t')) - && ((in & 0xffff) != (0x0e00 | '\b')) - && ((in & 0xffff) != (0x1c00 | '\r')) - && ((in & 0xffff) != (0x1c00 | '\n'))) - return ((in & 0xff) - 1 + 'a') | flags | GRUB_TERM_CTRL; - /* Detect ALT'ed keys. */ - /* XXX no way to distinguish left and right ALT. */ - if (((in & 0xff) == 0) && keyboard_map[(in & 0xff00) >> 8] >= 'a' - && keyboard_map[(in & 0xff00) >> 8] <= 'z') - return keyboard_map[(in & 0xff00) >> 8] | flags | GRUB_TERM_ALT_GR; - if ((in & 0xff) == 0 && (in & 0xff00) >= 0x7800 - && (in & 0xff00) <= 0x8000) - return (((in & 0xff00) >> 8) - 0x78 + '1') | flags | GRUB_TERM_ALT_GR; - - if ((in & 0xff00) == 0x8100) - return '0' | flags | GRUB_TERM_ALT_GR; - - if ((in & 0xffff) == 0x8200) - return '-' | flags | GRUB_TERM_ALT_GR; - - if ((in & 0xffff) == 0x8300) - return '+' | flags | GRUB_TERM_ALT_GR; - - if ((in & 0xff) == 0) - return keyboard_map[(in & 0xff00) >> 8] | flags; - - return (in & 0xff) | flags; - } - } -} - -static grub_uint32_t mapping[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; -static grub_uint32_t mapping_alt[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - -static unsigned -map (grub_term_input_t term __attribute__ ((unused)), unsigned in) -{ - if (in & GRUB_TERM_KEYPAD) - return in; - - if ((in & GRUB_TERM_EXTENDED) || (in & GRUB_TERM_KEY_MASK) == '\b' - || (in & GRUB_TERM_KEY_MASK) == '\n' || (in & GRUB_TERM_KEY_MASK) == ' ' - || (in & GRUB_TERM_KEY_MASK) == '\t' || (in & GRUB_TERM_KEY_MASK) == '\e' - || (in & GRUB_TERM_KEY_MASK) == '\r' - || (in & GRUB_TERM_KEY_MASK) >= ARRAY_SIZE (mapping)) - return in; - - if ((in & GRUB_TERM_ALT_GR) && mapping_alt[in & GRUB_TERM_KEY_MASK]) - return mapping_alt[in & GRUB_TERM_KEY_MASK] | (in & ~GRUB_TERM_KEY_MASK & ~GRUB_TERM_ALT_GR); - - return mapping[in & GRUB_TERM_KEY_MASK] | (in & ~GRUB_TERM_KEY_MASK); -} - -static int -translate (grub_term_input_t term, int in) -{ - int code, flags; - code = get_abstract_code (term, in); - - flags = code & ~(GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR | GRUB_TERM_KEYPAD | GRUB_TERM_CAPS); - - if ((code & GRUB_TERM_CAPS) && (code & GRUB_TERM_KEY_MASK) >= 'a' - && (code & GRUB_TERM_KEY_MASK) <= 'z') - code = (code & GRUB_TERM_KEY_MASK) + 'A' - 'a'; - else if ((code & GRUB_TERM_CAPS) && (code & GRUB_TERM_KEY_MASK) >= 'A' - && (code & GRUB_TERM_KEY_MASK) <= 'Z') - code = (code & GRUB_TERM_KEY_MASK) + 'a' - 'A'; - - code &= (GRUB_TERM_KEY_MASK | GRUB_TERM_ALT_GR | GRUB_TERM_KEYPAD); - code = map (term, code); - /* Transform unconsumed AltGr into Alt. */ - if (code & GRUB_TERM_ALT_GR) - { - flags |= GRUB_TERM_ALT; - code &= ~GRUB_TERM_ALT_GR; - } - code &= ~GRUB_TERM_KEYPAD; - - if ((flags & GRUB_TERM_CAPS) && code >= 'a' && code <= 'z') - code += 'A' - 'a'; - else if ((flags & GRUB_TERM_CAPS) && code >= 'A' - && code <= 'Z') - code += 'a' - 'A'; - return code | flags; -} - -static int -grub_getkey_smart (void) -{ - grub_term_input_t term; - - grub_refresh (); - - while (1) - { - FOR_ACTIVE_TERM_INPUTS(term) - { - int key = term->checkkey (term); - if (key != -1) - return translate (term, term->getkey (term)); - } - - grub_cpu_idle (); - } -} - -int -grub_checkkey (void) -{ - grub_term_input_t term; - - FOR_ACTIVE_TERM_INPUTS(term) - { - int key = term->checkkey (term); - if (key != -1) - return translate (term, key); - } - - return -1; -} - static grub_err_t grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), int argc, char *argv[]) @@ -192,8 +36,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), grub_file_t file; grub_uint32_t version; grub_uint8_t magic[GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE]; - grub_uint32_t newmapping[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; - grub_uint32_t newmapping_alt[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + struct grub_keyboard_layout *newmap = NULL; unsigned i; if (argc < 1) @@ -241,60 +84,53 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)), goto fail; } - if (grub_file_read (file, newmapping, sizeof (newmapping)) - != sizeof (newmapping)) + newmap = grub_malloc (sizeof (*newmap)); + if (!newmap) + goto fail; + + if (grub_file_read (file, newmap, sizeof (*newmap)) != sizeof (*newmap)) { if (!grub_errno) grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short"); goto fail; } - if (grub_file_read (file, newmapping_alt, sizeof (newmapping_alt)) - != sizeof (newmapping_alt)) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_ARGUMENT, "file is too short"); - goto fail; - } + for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map); i++) + newmap->at.keyboard_map[i] = grub_le_to_cpu32(newmap->at.keyboard_map[i]); - for (i = 0; i < ARRAY_SIZE (mapping); i++) - mapping[i] = grub_le_to_cpu32(newmapping[i]); + for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map_shift); i++) + newmap->at.keyboard_map_shift[i] + = grub_le_to_cpu32(newmap->at.keyboard_map_shift[i]); - for (i = 0; i < ARRAY_SIZE (mapping_alt); i++) - mapping_alt[i] = grub_le_to_cpu32(newmapping_alt[i]); + for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map_l3); i++) + newmap->at.keyboard_map_l3[i] + = grub_le_to_cpu32(newmap->at.keyboard_map_l3[i]); + + for (i = 0; i < ARRAY_SIZE (newmap->at.keyboard_map_shift_l3); i++) + newmap->at.keyboard_map_shift_l3[i] + = grub_le_to_cpu32(newmap->at.keyboard_map_shift_l3[i]); return GRUB_ERR_NONE; fail: if (filename != argv[0]) grub_free (filename); + grub_free (newmap); if (file) grub_file_close (file); return grub_errno; } -static int (*grub_getkey_saved) (void); - static grub_command_t cmd; GRUB_MOD_INIT(keylayouts) { - unsigned i; - for (i = 0; i < ARRAY_SIZE (mapping); i++) - mapping[i] = i; - grub_memset (mapping_alt, 0, sizeof (mapping_alt)); - mapping[GRUB_TERM_KEY_102] = '\\'; - mapping[GRUB_TERM_KEY_SHIFT_102] = '|'; - - grub_getkey_saved = grub_getkey; - grub_getkey = grub_getkey_smart; - cmd = grub_register_command ("keymap", grub_cmd_keymap, 0, N_("Load a keyboard layout.")); } GRUB_MOD_FINI(keylayouts) { - grub_getkey = grub_getkey_saved; + grub_current_layout = NULL; grub_unregister_command (cmd); } diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index e8289d672..10421540a 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -51,53 +51,4 @@ #define OLPC_RIGHT '\0' #endif -#define GRUB_AT_KEY_KEYBOARD_MAP(name) \ -static const unsigned name[128] = \ -{ \ - /* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', \ - /* 0x08 */ '7', '8', '9', '0', \ - /* 0x0c */ '-', '=', 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', '*' | GRUB_TERM_KEYPAD, \ - /* 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', \ - /* 0x46 */ '\0', GRUB_TERM_KEY_HOME, \ - /* 0x48 */ GRUB_TERM_KEY_UP, \ - /* 0x49 */ GRUB_TERM_KEY_NPAGE, \ - /* 0x4a */ '-' | GRUB_TERM_KEYPAD, \ - /* 0x4b */ GRUB_TERM_KEY_LEFT, \ - /* 0x4c */ GRUB_TERM_KEY_CENTER | GRUB_TERM_KEYPAD, \ - /* 0x4d */ GRUB_TERM_KEY_RIGHT, \ - /* 0x4e */ '+' | GRUB_TERM_KEYPAD, \ - /* 0x4f */ GRUB_TERM_KEY_END, \ - /* 0x50 */ GRUB_TERM_KEY_DOWN, \ - /* 0x51 */ GRUB_TERM_KEY_PPAGE, \ - /* 0x52 */ GRUB_TERM_KEY_INSERT, \ - /* 0x53 */ GRUB_TERM_KEY_DC, \ - /* 0x54 */ '\0', '\0', GRUB_TERM_KEY_102, GRUB_TERM_KEY_F11, \ - /* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', \ - /* 0x60 */ '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, \ - /* 0x68 */ OLPC_RIGHT \ -} - -#define GRUB_AT_KEY_KEYBOARD_MAP_SHIFT(name) \ -static unsigned name[128] = \ -{ \ - '\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] = GRUB_TERM_KEY_SHIFT_102 \ -} - #endif diff --git a/include/grub/i386/pc/console.h b/include/grub/i386/pc/console.h index 7f58344ec..fabb13d5c 100644 --- a/include/grub/i386/pc/console.h +++ b/include/grub/i386/pc/console.h @@ -19,19 +19,6 @@ #ifndef GRUB_CONSOLE_MACHINE_HEADER #define GRUB_CONSOLE_MACHINE_HEADER 1 -/* Define scan codes. */ -#define GRUB_CONSOLE_KEY_LEFT 0x4B00 -#define GRUB_CONSOLE_KEY_RIGHT 0x4D00 -#define GRUB_CONSOLE_KEY_UP 0x4800 -#define GRUB_CONSOLE_KEY_DOWN 0x5000 -#define GRUB_CONSOLE_KEY_IC 0x5200 -#define GRUB_CONSOLE_KEY_DC 0x5300 -#define GRUB_CONSOLE_KEY_BACKSPACE 0x0008 -#define GRUB_CONSOLE_KEY_HOME 0x4700 -#define GRUB_CONSOLE_KEY_END 0x4F00 -#define GRUB_CONSOLE_KEY_NPAGE 0x5100 -#define GRUB_CONSOLE_KEY_PPAGE 0x4900 - #ifndef ASM_FILE #include diff --git a/include/grub/keyboard_layouts.h b/include/grub/keyboard_layouts.h index 081e9ca98..2d6e3d54c 100644 --- a/include/grub/keyboard_layouts.h +++ b/include/grub/keyboard_layouts.h @@ -21,8 +21,28 @@ #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO" #define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) -#define GRUB_KEYBOARD_LAYOUTS_VERSION 3 +#define GRUB_KEYBOARD_LAYOUTS_VERSION 4 -#define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 256 +#define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 128 + +struct grub_keyboard_layout +{ + struct + { + grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + } at; + struct + { + grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE]; + } usb; +}; + +struct grub_keyboard_layout *EXPORT_VAR (grub_current_layout); #endif /* GRUB_KEYBOARD_LAYOUTS */ diff --git a/include/grub/term.h b/include/grub/term.h index f2f80152f..036e8caaa 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -24,41 +24,34 @@ #define GRUB_TERM_SHIFT 0x01000000 #define GRUB_TERM_CTRL 0x02000000 #define GRUB_TERM_ALT 0x04000000 -/* Used by keylayouts code. Never returned in grub_getkey. */ -#define GRUB_TERM_ALT_GR 0x08000000 -#define GRUB_TERM_CAPS 0x10000000 -#define GRUB_TERM_KEYPAD 0x20000000 /* Keys without associated character. */ #define GRUB_TERM_EXTENDED 0x00800000 #define GRUB_TERM_KEY_MASK 0x00ffffff -#define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 1) -#define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 2) -#define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 3) -#define GRUB_TERM_KEY_DOWN (GRUB_TERM_EXTENDED | 4) -#define GRUB_TERM_KEY_HOME (GRUB_TERM_EXTENDED | 5) -#define GRUB_TERM_KEY_END (GRUB_TERM_EXTENDED | 6) -#define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 7) -#define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 8) -#define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 9) -#define GRUB_TERM_KEY_F1 (GRUB_TERM_EXTENDED | 10) -#define GRUB_TERM_KEY_F2 (GRUB_TERM_EXTENDED | 11) -#define GRUB_TERM_KEY_F3 (GRUB_TERM_EXTENDED | 12) -#define GRUB_TERM_KEY_F4 (GRUB_TERM_EXTENDED | 13) -#define GRUB_TERM_KEY_F5 (GRUB_TERM_EXTENDED | 14) -#define GRUB_TERM_KEY_F6 (GRUB_TERM_EXTENDED | 15) -#define GRUB_TERM_KEY_F7 (GRUB_TERM_EXTENDED | 16) -#define GRUB_TERM_KEY_F8 (GRUB_TERM_EXTENDED | 17) -#define GRUB_TERM_KEY_F9 (GRUB_TERM_EXTENDED | 18) -#define GRUB_TERM_KEY_F10 (GRUB_TERM_EXTENDED | 19) -#define GRUB_TERM_KEY_F11 (GRUB_TERM_EXTENDED | 20) -#define GRUB_TERM_KEY_F12 (GRUB_TERM_EXTENDED | 21) -#define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 22) -#define GRUB_TERM_KEY_CENTER (GRUB_TERM_EXTENDED | 23) -/* Used by keylayouts code. Never returned in grub_getkey. */ -#define GRUB_TERM_KEY_102 0x80 -#define GRUB_TERM_KEY_SHIFT_102 0x81 +#define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 0x4b) +#define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 0x4d) +#define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 0x48) +#define GRUB_TERM_KEY_DOWN (GRUB_TERM_EXTENDED | 0x50) +#define GRUB_TERM_KEY_HOME (GRUB_TERM_EXTENDED | 0x47) +#define GRUB_TERM_KEY_END (GRUB_TERM_EXTENDED | 0x4f) +#define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 0x53) +#define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 0x49) +#define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 0x51) +#define GRUB_TERM_KEY_F1 (GRUB_TERM_EXTENDED | 0x3b) +#define GRUB_TERM_KEY_F2 (GRUB_TERM_EXTENDED | 0x3c) +#define GRUB_TERM_KEY_F3 (GRUB_TERM_EXTENDED | 0x3d) +#define GRUB_TERM_KEY_F4 (GRUB_TERM_EXTENDED | 0x3e) +#define GRUB_TERM_KEY_F5 (GRUB_TERM_EXTENDED | 0x3f) +#define GRUB_TERM_KEY_F6 (GRUB_TERM_EXTENDED | 0x40) +#define GRUB_TERM_KEY_F7 (GRUB_TERM_EXTENDED | 0x41) +#define GRUB_TERM_KEY_F8 (GRUB_TERM_EXTENDED | 0x42) +#define GRUB_TERM_KEY_F9 (GRUB_TERM_EXTENDED | 0x43) +#define GRUB_TERM_KEY_F10 (GRUB_TERM_EXTENDED | 0x44) +#define GRUB_TERM_KEY_F11 (GRUB_TERM_EXTENDED | 0x57) +#define GRUB_TERM_KEY_F12 (GRUB_TERM_EXTENDED | 0x58) +#define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 0x52) +#define GRUB_TERM_KEY_CENTER (GRUB_TERM_EXTENDED | 0x4c) #define GRUB_TERM_ESC '\e' #define GRUB_TERM_TAB '\t' @@ -168,16 +161,10 @@ struct grub_term_input /* Get keyboard modifier status. */ int (*getkeystatus) (struct grub_term_input *term); - grub_uint32_t flags; - void *data; }; typedef struct grub_term_input *grub_term_input_t; -#define GRUB_TERM_INPUT_FLAGS_TYPE_MASK 0xf -#define GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES 0x0 -#define GRUB_TERM_INPUT_FLAGS_TYPE_BIOS 0x1 - struct grub_term_output { /* The next terminal. */ @@ -314,8 +301,8 @@ grub_term_unregister_output (grub_term_output_t term) #define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled)) void grub_putcode (grub_uint32_t code, struct grub_term_output *term); -extern int (*EXPORT_VAR(grub_getkey)) (void); -int grub_checkkey (void); +int EXPORT_FUNC(grub_getkey) (void); +int EXPORT_FUNC(grub_checkkey) (void); void grub_cls (void); void EXPORT_FUNC(grub_refresh) (void); void grub_puts_terminal (const char *str, struct grub_term_output *term); diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index cbc4c5cfb..ef5904bb2 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1147,6 +1147,11 @@ FUNCTION(grub_console_putchar) ret +LOCAL(bypass_table): + .word 0x0100 | '\e',0x0f00 | '\t', 0x0e00 | '\b', 0x1c00 | '\r' + .word 0x1c00 | '\n' +LOCAL(bypass_table_end): + /* * int grub_console_getkey (void) * BIOS call "INT 16H Function 00H" to read character from keyboard @@ -1180,17 +1185,39 @@ FUNCTION(grub_console_getkey) movb $0, %ah int $0x16 + xorl %edx, %edx movw %ax, %dx /* real_to_prot uses %eax */ DATA32 call real_to_prot .code32 - movw %dx, %ax + movl $0xff, %eax + testl %eax, %edx + jz 1f + + andl %edx, %eax + cmp %eax, 0x20 + ja 2f + movl %edx, %eax + leal LOCAL(bypass_table), %esi + movl $((LOCAL(bypass_table_end) - LOCAL(bypass_table)) / 2), %ecx + repne cmpsw + jz 3f + + addl $('a' - 1 | GRUB_TERM_CTRL), %eax + jmp 2f +3: + andl $0xff, %eax + jmp 2f + +1: movl %edx, %eax + shrl $8, %eax + orl $GRUB_TERM_EXTENDED, %eax +2: popl %ebp ret - /* * int grub_console_checkkey (void) * if there is a character pending, return it; otherwise return -1 @@ -1216,6 +1243,7 @@ FUNCTION(grub_console_checkkey) jz notpending + xorl %edx, %edx movw %ax, %dx DATA32 jmp pending @@ -1226,8 +1254,6 @@ pending: DATA32 call real_to_prot .code32 - movl %edx, %eax - popl %ebp ret diff --git a/kern/term.c b/kern/term.c index d582dbb68..04d20364a 100644 --- a/kern/term.c +++ b/kern/term.c @@ -22,11 +22,13 @@ #include #include #include +#include struct grub_term_output *grub_term_outputs_disabled; struct grub_term_input *grub_term_inputs_disabled; struct grub_term_output *grub_term_outputs; struct grub_term_input *grub_term_inputs; +struct grub_keyboard_layout *grub_current_layout; /* Put a Unicode character. */ static void @@ -76,8 +78,8 @@ grub_xputs_dumb (const char *str) void (*grub_xputs) (const char *str) = grub_xputs_dumb; -static int -grub_getkey_dumb (void) +int +grub_getkey (void) { grub_term_input_t term; @@ -89,14 +91,27 @@ grub_getkey_dumb (void) { int key = term->checkkey (term); if (key != -1) - return term->getkey (term) & 0xff; + return term->getkey (term); } grub_cpu_idle (); } } -int (*grub_getkey) (void) = grub_getkey_dumb; +int +grub_checkkey (void) +{ + grub_term_input_t term; + + FOR_ACTIVE_TERM_INPUTS(term) + { + int key = term->checkkey (term); + if (key != -1) + return key; + } + + return -1; +} void grub_refresh (void) diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 5adc8b4da..492075115 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -42,8 +42,43 @@ static grub_uint8_t led_status; #define KEYBOARD_LED_NUM (1 << 1) #define KEYBOARD_LED_CAPS (1 << 2) -GRUB_AT_KEY_KEYBOARD_MAP (keyboard_map); -GRUB_AT_KEY_KEYBOARD_MAP_SHIFT (keyboard_map_shift); +static const unsigned keyboard_map[128] = +{ + /* 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, '+', 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 +}; + +static unsigned keyboard_map_shift[128] = +{ + '\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] = '|' +}; static grub_uint8_t grub_keyboard_controller_orig; @@ -211,21 +246,12 @@ grub_at_keyboard_getkey_noblock (void) } if (at_keyboard_status & KEYBOARD_STATUS_ALT_L) - { - key |= GRUB_TERM_ALT; - grub_printf ("AltL"); - } + key |= GRUB_TERM_ALT; if (at_keyboard_status & KEYBOARD_STATUS_ALT_R) - { - key |= GRUB_TERM_ALT_GR; - grub_printf ("AltGr"); - } + key |= GRUB_TERM_ALT; if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R)) key |= GRUB_TERM_CTRL; - - if (at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK) - key |= GRUB_TERM_CAPS; } return key; } @@ -284,8 +310,7 @@ static struct grub_term_input grub_at_keyboard_term = .init = grub_keyboard_controller_init, .fini = grub_keyboard_controller_fini, .checkkey = grub_at_keyboard_checkkey, - .getkey = grub_at_keyboard_getkey, - .flags = GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES + .getkey = grub_at_keyboard_getkey }; GRUB_MOD_INIT(at_keyboard) diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 1bf954874..74df4c27f 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -50,8 +50,7 @@ static struct grub_term_input grub_console_term_input = .name = "console", .checkkey = grub_console_checkkey, .getkey = grub_console_getkey, - .getkeystatus = grub_console_getkeystatus, - .flags = GRUB_TERM_INPUT_FLAGS_TYPE_BIOS + .getkeystatus = grub_console_getkeystatus }; static struct grub_term_output grub_console_term_output = diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 9e1ce5e60..3432f700c 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -43,7 +43,7 @@ static unsigned keyboard_map[128] = '\0', GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_HOME, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_DC, GRUB_TERM_KEY_END, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_RIGHT, GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_UP, - [0x64] = GRUB_TERM_KEY_102 + [0x64] = '\\' }; static unsigned keyboard_map_shift[128] = @@ -56,7 +56,7 @@ static unsigned keyboard_map_shift[128] = '\n', '\0', '\0', '\0', ' ', '_', '+', '{', '}', '|', '#', ':', '"', '`', '<', '>', '?', - [0x64] = GRUB_TERM_KEY_SHIFT_102 + [0x64] = '|' }; static grub_usb_device_t usbdev; @@ -186,7 +186,7 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused) key |= GRUB_TERM_ALT; if (data[0] & GRUB_USB_KEYBOARD_RIGHT_ALT) - key |= GRUB_TERM_ALT_GR; + key |= GRUB_TERM_ALT; #if 0 /* Wait until the key is released. */ @@ -341,7 +341,6 @@ static struct grub_term_input grub_usb_keyboard_term = .checkkey = grub_usb_keyboard_checkkey, .getkey = grub_usb_keyboard_getkey, .getkeystatus = grub_usb_keyboard_getkeystatus, - .flags = GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES, .next = 0 }; diff --git a/util/grub-fstest.c b/util/grub-fstest.c index 715dfe2dd..2c80b964c 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -51,14 +51,12 @@ grub_xputs_real (const char *str) void (*grub_xputs) (const char *str) = grub_xputs_real; -static int -grub_getkey_real (void) +int +grub_getkey (void) { return -1; } -int (*grub_getkey) (void) = grub_getkey_real; - void grub_refresh (void) { diff --git a/util/grub-mklayouts.c b/util/grub-mklayouts.c index 434f9f4f8..9aca88cb1 100644 --- a/util/grub-mklayouts.c +++ b/util/grub-mklayouts.c @@ -67,9 +67,6 @@ static struct console_grub_equivalence console_grub_equivalences[] = { {"", '\0'} }; -GRUB_AT_KEY_KEYBOARD_MAP (us_keyboard_map); -GRUB_AT_KEY_KEYBOARD_MAP_SHIFT (us_keyboard_map_shifted); - static void usage (int status) { @@ -201,23 +198,6 @@ write_keymaps (char *keymap, char *file_basename) sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode, normal, shift, normalalt, shiftalt); - if (keycode < ARRAY_SIZE (us_keyboard_map) - && us_keyboard_map[keycode] < ARRAY_SIZE (keyboard_map)) - { - keyboard_map[us_keyboard_map[keycode]] = get_grub_code (normal); - keyboard_map_alt[us_keyboard_map[keycode]] - = get_grub_code (normalalt); - ok = 1; - } - if (keycode < ARRAY_SIZE (us_keyboard_map_shifted) - && us_keyboard_map_shifted[keycode] < ARRAY_SIZE (keyboard_map)) - { - keyboard_map[us_keyboard_map_shifted[keycode]] - = get_grub_code (shift); - keyboard_map_alt[us_keyboard_map_shifted[keycode]] - = get_grub_code (shiftalt); - ok = 1; - } } } diff --git a/util/grub-probe.c b/util/grub-probe.c index e4d3f2906..56cbc5592 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -68,14 +68,12 @@ grub_xputs_real (const char *str) void (*grub_xputs) (const char *str) = grub_xputs_real; -static int -grub_getkey_real (void) +int +grub_getkey (void) { return -1; } -int (*grub_getkey) (void) = grub_getkey_real; - void grub_refresh (void) { diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 4e3980965..524572fad 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -72,14 +72,12 @@ grub_xputs_real (const char *str) void (*grub_xputs) (const char *str) = grub_xputs_real; -static int -grub_getkey_real (void) +int +grub_getkey (void) { return -1; } -int (*grub_getkey) (void) = grub_getkey_real; - void grub_refresh (void) {