diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 715994872..e24603c32 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -205,6 +205,7 @@ kernel = { efi = kern/efi/init.c; efi = kern/efi/mm.c; efi = term/efi/console.c; + efi = commands/keylayouts.c; efi = kern/acpi.c; efi = kern/efi/acpi.c; efi = kern/efi/sb.c; @@ -269,6 +270,7 @@ kernel = { i386_pc = kern/i386/pc/init.c; i386_pc = kern/i386/pc/mmap.c; i386_pc = term/i386/pc/console.c; + i386_pc = commands/keylayouts.c; i386_qemu = bus/pci.c; i386_qemu = kern/vga_init.c; diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c index a3622e4fe..37d5a971b 100644 --- a/grub-core/term/efi/console.c +++ b/grub-core/term/efi/console.c @@ -23,6 +23,7 @@ #include #include #include +#include typedef enum { GRUB_TEXT_MODE_UNDEFINED = -1, @@ -374,13 +375,25 @@ grub_efi_console_input_init (struct grub_term_input *term) static int grub_console_getkey (struct grub_term_input *term) { + int key; + int status = 0; + if (grub_efi_is_finished) return 0; if (term->data) - return grub_console_getkey_ex(term); + key = grub_console_getkey_ex(term); else - return grub_console_getkey_con(term); + key = grub_console_getkey_con(term); + + if (key & GRUB_TERM_SHIFT) + status |= GRUB_TERM_STATUS_RSHIFT; + if (key & GRUB_TERM_ALT) + status |= GRUB_TERM_STATUS_RALT; + if (key & GRUB_TERM_CTRL) + status |= GRUB_TERM_STATUS_RCTRL + + return grub_term_map_key(key & GRUB_TERM_KEY_MASK, status); } static struct grub_term_coordinate diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c index 9403390f1..b7b3bfc12 100644 --- a/grub-core/term/i386/pc/console.c +++ b/grub-core/term/i386/pc/console.c @@ -21,6 +21,7 @@ #include #include #include +#include static grub_uint8_t grub_console_cur_color = 0x7; @@ -183,6 +184,21 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), grub_bios_interrupt (0x10, ®s); } +static int +map_key (int key) +{ + int status = 0; + + if (key & GRUB_TERM_SHIFT) + status |= GRUB_TERM_STATUS_RSHIFT; + if (key & GRUB_TERM_ALT) + status |= GRUB_TERM_STATUS_RALT; + if (key & GRUB_TERM_CTRL) + status |= GRUB_TERM_STATUS_RCTRL; + + return grub_term_map_key(key & GRUB_TERM_KEY_MASK, status); +} + /* * if there is a character pending, return it; otherwise return -1 * BIOS call "INT 16H Function 01H" to check whether a character is pending @@ -226,16 +242,16 @@ grub_console_getkey (struct grub_term_input *term __attribute__ ((unused))) regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; grub_bios_interrupt (0x16, ®s); if (!(regs.eax & 0xff)) - return ((regs.eax >> 8) & 0xff) | GRUB_TERM_EXTENDED; + return map_key (((regs.eax >> 8) & 0xff) | GRUB_TERM_EXTENDED); if ((regs.eax & 0xff) >= ' ') - return regs.eax & 0xff; + return map_key (regs.eax & 0xff); for (i = 0; i < ARRAY_SIZE (bypass_table); i++) if (bypass_table[i] == (regs.eax & 0xffff)) - return regs.eax & 0xff; + return map_key (regs.eax & 0xff); - return (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL); + return map_key ((regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL)); } static int