From: Vladimir 'phcoder' Serbinenko Date: Mon, 10 May 2010 12:54:51 +0000 (+0200) Subject: Skeleton for keyboard layouts X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=87fae34a1ff2b165ad532b251e328494797cfc8e;p=grub2.git Skeleton for keyboard layouts --- diff --git a/commands/cat.c b/commands/cat.c index 3bdafc4c6..556196b4a 100644 --- a/commands/cat.c +++ b/commands/cat.c @@ -63,7 +63,7 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)), } while (grub_checkkey () >= 0 && - (key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != GRUB_TERM_ESC) + (key = grub_getkey ()) != GRUB_TERM_ESC) ; } diff --git a/commands/keylayouts.c b/commands/keylayouts.c new file mode 100644 index 000000000..35bbb8376 --- /dev/null +++ b/commands/keylayouts.c @@ -0,0 +1,186 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007,2008,2009 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +static int keyboard_map[128] = +{ + '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, + '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', ',', '.', '/', '\0', '*', + '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_KEY_HOME, + GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, '\0', GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, + GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, '\0', GRUB_TERM_KEY_DC +}; + +/* Define scan codes. */ +#define GRUB_TERM_AT_KEY_LEFT 0x4B00 +#define GRUB_TERM_AT_KEY_RIGHT 0x4D00 +#define GRUB_TERM_AT_KEY_UP 0x4800 +#define GRUB_TERM_AT_KEY_DOWN 0x5000 +#define GRUB_TERM_AT_KEY_IC 0x5200 +#define GRUB_TERM_AT_KEY_DC 0x5300 +#define GRUB_TERM_AT_KEY_BACKSPACE 0x0008 +#define GRUB_TERM_AT_KEY_HOME 0x4700 +#define GRUB_TERM_AT_KEY_END 0x4F00 +#define GRUB_TERM_AT_KEY_NPAGE 0x5100 +#define GRUB_TERM_AT_KEY_PPAGE 0x4900 + +static int +get_abstract_code (grub_term_input_t term, int in) +{ + unsigned flags = 0; + switch (term->flags & GRUB_TERM_INPUT_FLAGS_TYPE_MASK) + { + default: + return in; + case GRUB_TERM_INPUT_FLAGS_TYPE_BIOS: + { + unsigned status = 0; + if (term->getkeystatus) + status = term->getkeystatus (); + if (status & GRUB_TERM_CAPS) + flags |= GRUB_TERM_CAPS; + } + /* Fall through. */ + case GRUB_TERM_INPUT_FLAGS_TYPE_AT: + { + struct { + int from, to; + } translations[] = + { + {GRUB_TERM_AT_KEY_LEFT, GRUB_TERM_KEY_LEFT}, + {GRUB_TERM_AT_KEY_RIGHT, GRUB_TERM_KEY_RIGHT}, + {GRUB_TERM_AT_KEY_UP, GRUB_TERM_KEY_UP}, + {GRUB_TERM_AT_KEY_DOWN, GRUB_TERM_KEY_DOWN}, + {GRUB_TERM_AT_KEY_HOME, GRUB_TERM_KEY_HOME}, + {GRUB_TERM_AT_KEY_END, GRUB_TERM_KEY_END}, + {GRUB_TERM_AT_KEY_DC, GRUB_TERM_KEY_DC}, + {GRUB_TERM_AT_KEY_PPAGE, GRUB_TERM_KEY_PPAGE}, + {GRUB_TERM_AT_KEY_NPAGE, GRUB_TERM_KEY_NPAGE} + }; + unsigned i; + for (i = 0; i < ARRAY_SIZE (translations); i++) + if (translations[i].from == (in & 0xffff)) + return translations[i].to | flags; + if ((term->flags & GRUB_TERM_INPUT_FLAGS_TYPE_MASK) + == GRUB_TERM_INPUT_FLAGS_TYPE_AT) + return in & ~0xff00; + /* 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; + + return (in & 0xff) | flags; + } + } +} + +static int +map (grub_term_input_t term __attribute__ ((unused)), int in) +{ + return in; +} + +static int +translate (grub_term_input_t term, int in) +{ + int code, code2; + code = get_abstract_code (term, in); + if ((code & GRUB_TERM_CAPS) && (code & 0xff) >= 'a' && (code & 0xff) <= 'z') + code = (code & 0xff) + 'A' - 'a'; + else if ((code & GRUB_TERM_CAPS) && (code & 0xff) >= 'A' + && (code & 0xff) <= 'Z') + code = (code & 0xff) + 'a' - 'A'; + + code2 = map (term, code & 0xff); + if ((code & GRUB_TERM_CAPS) && (code2 & 0xff) >= 'a' && (code2 & 0xff) <= 'z') + code2 = code2 + 'A' - 'a'; + else if ((code & GRUB_TERM_CAPS) && (code2 & 0xff) >= 'A' + && (code2 & 0xff) <= 'Z') + code2 = code2 + 'a' - 'A'; + return code2 | (code & ~0xffffff); +} + +static int +grub_getkey_smart (void) +{ + grub_term_input_t term; + + grub_refresh (); + + while (1) + { + FOR_ACTIVE_TERM_INPUTS(term) + { + int key = term->checkkey (); + if (key != -1) + return translate (term, term->getkey ()); + } + + grub_cpu_idle (); + } +} + +int +grub_checkkey (void) +{ + grub_term_input_t term; + + FOR_ACTIVE_TERM_INPUTS(term) + { + int key = term->checkkey (); + if (key != -1) + return translate (term, key); + } + + return -1; +} + +static int (*grub_getkey_saved) (void); + +GRUB_MOD_INIT(keylayouts) +{ + grub_getkey_saved = grub_getkey; + grub_getkey = grub_getkey_smart; +} + +GRUB_MOD_FINI(keylayouts) +{ + grub_getkey = grub_getkey_saved; +} diff --git a/commands/keystatus.c b/commands/keystatus.c index 838792889..fc4d11d73 100644 --- a/commands/keystatus.c +++ b/commands/keystatus.c @@ -31,7 +31,20 @@ static const struct grub_arg_option options[] = {0, 0, 0, 0, 0, 0} }; -#define grub_cur_term_input grub_term_get_current_input () +static int +grub_getkeystatus (void) +{ + int status = 0; + grub_term_input_t term; + + FOR_ACTIVE_TERM_INPUTS(term) + { + if (term->getkeystatus) + status |= term->getkeystatus (); + } + + return status; +} static grub_err_t grub_cmd_keystatus (grub_extcmd_t cmd, diff --git a/commands/sleep.c b/commands/sleep.c index ead279506..bce1aee1d 100644 --- a/commands/sleep.c +++ b/commands/sleep.c @@ -52,8 +52,7 @@ grub_interruptible_millisleep (grub_uint32_t ms) start = grub_get_time_ms (); while (grub_get_time_ms () - start < ms) - if (grub_checkkey () >= 0 && - GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC) + if (grub_checkkey () >= 0 && grub_getkey () == GRUB_TERM_ESC) return 1; return 0; diff --git a/conf/common.rmk b/conf/common.rmk index 4b39e9b71..13e1c7a6c 100644 --- a/conf/common.rmk +++ b/conf/common.rmk @@ -491,6 +491,11 @@ extcmd_mod_SOURCES = commands/extcmd.c lib/arg.c extcmd_mod_CFLAGS = $(COMMON_CFLAGS) extcmd_mod_LDFLAGS = $(COMMON_LDFLAGS) +pkglib_MODULES += keylayouts.mod +keylayouts_mod_SOURCES = commands/keylayouts.c +keylayouts_mod_CFLAGS = $(COMMON_CFLAGS) +keylayouts_mod_LDFLAGS = $(COMMON_LDFLAGS) + # For hello.mod. hello_mod_SOURCES = hello/hello.c hello_mod_CFLAGS = $(COMMON_CFLAGS) diff --git a/include/grub/term.h b/include/grub/term.h index 143aabe1e..a2fa80c1f 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -20,18 +20,27 @@ #define GRUB_TERM_HEADER 1 /* Internal codes used by GRUB to represent terminal input. */ -#define GRUB_TERM_LEFT 2 -#define GRUB_TERM_RIGHT 6 -#define GRUB_TERM_UP 16 -#define GRUB_TERM_DOWN 14 -#define GRUB_TERM_HOME 1 -#define GRUB_TERM_END 5 -#define GRUB_TERM_DC 4 -#define GRUB_TERM_PPAGE 7 -#define GRUB_TERM_NPAGE 3 +#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 + +/* Keys without associated character. */ +#define GRUB_TERM_EXTENDED 0x1000000 +#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_ESC '\e' #define GRUB_TERM_TAB '\t' -#define GRUB_TERM_BACKSPACE 8 +#define GRUB_TERM_BACKSPACE '\b' #ifndef ASM_FILE @@ -135,9 +144,15 @@ struct grub_term_input /* Get keyboard modifier status. */ int (*getkeystatus) (void); + + grub_uint32_t flags; }; typedef struct grub_term_input *grub_term_input_t; +#define GRUB_TERM_INPUT_FLAGS_TYPE_MASK 0xf +#define GRUB_TERM_INPUT_FLAGS_TYPE_AT 0x1 +#define GRUB_TERM_INPUT_FLAGS_TYPE_BIOS 0x2 + struct grub_term_output { /* The next terminal. */ @@ -253,9 +268,8 @@ grub_term_unregister_output (grub_term_output_t term) void EXPORT_FUNC(grub_putchar) (int c); void EXPORT_FUNC(grub_putcode) (grub_uint32_t code, struct grub_term_output *term); -int EXPORT_FUNC(grub_getkey) (void); -int EXPORT_FUNC(grub_checkkey) (void); -int EXPORT_FUNC(grub_getkeystatus) (void); +extern int (*EXPORT_VAR(grub_getkey)) (void); +int grub_checkkey (void); void EXPORT_FUNC(grub_cls) (void); void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state); void EXPORT_FUNC(grub_refresh) (void); @@ -409,10 +423,6 @@ grub_print_spaces (struct grub_term_output *term, int number_spaces) grub_putcode (' ', term); } - -/* For convenience. */ -#define GRUB_TERM_ASCII_CHAR(c) ((c) & 0xff) - #endif /* ! ASM_FILE */ #endif /* ! GRUB_TERM_HEADER */ diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index 374277767..6aa3297ab 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -1154,54 +1154,6 @@ FUNCTION(grub_console_real_putchar) * %al = ASCII character */ -/* this table is used in translate_keycode below */ -LOCAL (translation_table): - .word GRUB_CONSOLE_KEY_LEFT, GRUB_TERM_LEFT - .word GRUB_CONSOLE_KEY_RIGHT, GRUB_TERM_RIGHT - .word GRUB_CONSOLE_KEY_UP, GRUB_TERM_UP - .word GRUB_CONSOLE_KEY_DOWN, GRUB_TERM_DOWN - .word GRUB_CONSOLE_KEY_HOME, GRUB_TERM_HOME - .word GRUB_CONSOLE_KEY_END, GRUB_TERM_END - .word GRUB_CONSOLE_KEY_DC, GRUB_TERM_DC - .word GRUB_CONSOLE_KEY_BACKSPACE, GRUB_TERM_BACKSPACE - .word GRUB_CONSOLE_KEY_PPAGE, GRUB_TERM_PPAGE - .word GRUB_CONSOLE_KEY_NPAGE, GRUB_TERM_NPAGE - .word 0 - -/* - * translate_keycode translates the key code %dx to an ascii code. - */ - .code16 - -translate_keycode: - pushw %bx - pushw %si - -#ifdef __APPLE__ - movw $(ABS(LOCAL (translation_table)) - 0x10000), %si -#else - movw $ABS(LOCAL (translation_table)), %si -#endif - -1: lodsw - /* check if this is the end */ - testw %ax, %ax - jz 2f - /* load the ascii code into %ax */ - movw %ax, %bx - lodsw - /* check if this matches the key code */ - cmpw %bx, %dx - jne 1b - /* translate %dx, if successful */ - movw %ax, %dx - -2: popw %si - popw %bx - ret - - .code32 - FUNCTION(grub_console_getkey) pushl %ebp @@ -1228,7 +1180,6 @@ FUNCTION(grub_console_getkey) int $0x16 movw %ax, %dx /* real_to_prot uses %eax */ - call translate_keycode DATA32 call real_to_prot .code32 diff --git a/kern/rescue_reader.c b/kern/rescue_reader.c index f573cf41f..7cecac6ec 100644 --- a/kern/rescue_reader.c +++ b/kern/rescue_reader.c @@ -38,7 +38,7 @@ grub_rescue_read_line (char **line, int cont) grub_printf ((cont) ? "> " : "grub rescue> "); grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE); - while ((c = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && c != '\r') + while ((c = grub_getkey ()) != '\n' && c != '\r') { if (grub_isprint (c)) { diff --git a/kern/term.c b/kern/term.c index 6e3a2b454..ab3d952fa 100644 --- a/kern/term.c +++ b/kern/term.c @@ -75,8 +75,8 @@ grub_putchar (int c) } } -int -grub_getkey (void) +static int +grub_getkey_dumb (void) { grub_term_input_t term; @@ -88,42 +88,14 @@ grub_getkey (void) { int key = term->checkkey (); if (key != -1) - return term->getkey (); + return term->getkey () & 0xff; } grub_cpu_idle (); } } -int -grub_checkkey (void) -{ - grub_term_input_t term; - - FOR_ACTIVE_TERM_INPUTS(term) - { - int key = term->checkkey (); - if (key != -1) - return key; - } - - return -1; -} - -int -grub_getkeystatus (void) -{ - int status = 0; - grub_term_input_t term; - - FOR_ACTIVE_TERM_INPUTS(term) - { - if (term->getkeystatus) - status |= term->getkeystatus (); - } - - return status; -} +int (*grub_getkey) (void) = grub_getkey_dumb; void grub_cls (void) diff --git a/lib/crypto.c b/lib/crypto.c index d11f0994f..405d18911 100644 --- a/lib/crypto.c +++ b/lib/crypto.c @@ -420,7 +420,7 @@ grub_password_get (char buf[], unsigned buf_size) while (1) { - key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + key = grub_getkey (); if (key == '\n' || key == '\r') break; diff --git a/normal/auth.c b/normal/auth.c index 156b84c37..76dfddb53 100644 --- a/normal/auth.c +++ b/normal/auth.c @@ -162,7 +162,7 @@ grub_username_get (char buf[], unsigned buf_size) while (1) { - key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + key = grub_getkey (); if (key == '\n' || key == '\r') break; diff --git a/normal/cmdline.c b/normal/cmdline.c index 05d665411..618e25e08 100644 --- a/normal/cmdline.c +++ b/normal/cmdline.c @@ -387,16 +387,18 @@ grub_cmdline_get (const char *prompt) grub_refresh (); - while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r') + while ((key = grub_getkey ()) != '\n' && key != '\r') { switch (key) { - case 1: /* Ctrl-a */ + case GRUB_TERM_CTRL | 'a': + case GRUB_TERM_KEY_HOME: lpos = 0; cl_set_pos_all (); break; - case 2: /* Ctrl-b */ + case GRUB_TERM_CTRL | 'b': + case GRUB_TERM_KEY_LEFT: if (lpos > 0) { lpos--; @@ -404,12 +406,14 @@ grub_cmdline_get (const char *prompt) } break; - case 5: /* Ctrl-e */ + case GRUB_TERM_CTRL | 'e': + case GRUB_TERM_KEY_END: lpos = llen; cl_set_pos_all (); break; - case 6: /* Ctrl-f */ + case GRUB_TERM_CTRL | 'f': + case GRUB_TERM_KEY_RIGHT: if (lpos < llen) { lpos++; @@ -417,7 +421,8 @@ grub_cmdline_get (const char *prompt) } break; - case 9: /* Ctrl-i or TAB */ + case GRUB_TERM_CTRL | 'i': + case '\t': { int restore; char *insertu8; @@ -489,7 +494,7 @@ grub_cmdline_get (const char *prompt) } break; - case 11: /* Ctrl-k */ + case GRUB_TERM_CTRL | 'k': if (lpos < llen) { if (kill_buf) @@ -513,7 +518,8 @@ grub_cmdline_get (const char *prompt) } break; - case 14: /* Ctrl-n */ + case GRUB_TERM_CTRL | 'n': + case GRUB_TERM_KEY_DOWN: { grub_uint32_t *hist; @@ -531,7 +537,9 @@ grub_cmdline_get (const char *prompt) break; } - case 16: /* Ctrl-p */ + + case GRUB_TERM_KEY_UP: + case GRUB_TERM_CTRL | 'p': { grub_uint32_t *hist; @@ -550,7 +558,7 @@ grub_cmdline_get (const char *prompt) } break; - case 21: /* Ctrl-u */ + case GRUB_TERM_CTRL | 'u': if (lpos > 0) { grub_size_t n = lpos; @@ -576,7 +584,7 @@ grub_cmdline_get (const char *prompt) } break; - case 25: /* Ctrl-y */ + case GRUB_TERM_CTRL | 'y': if (kill_buf) cl_insert (kill_buf); break; @@ -594,7 +602,8 @@ grub_cmdline_get (const char *prompt) break; /* fall through */ - case 4: /* Ctrl-d */ + case GRUB_TERM_CTRL | 'd': + case GRUB_TERM_KEY_DC: if (lpos < llen) cl_delete (1); break; diff --git a/normal/main.c b/normal/main.c index 4ed17e82c..ff4be3a79 100644 --- a/normal/main.c +++ b/normal/main.c @@ -163,7 +163,7 @@ static struct { {"backspace", '\b'}, {"tab", '\t'}, - {"delete", GRUB_TERM_DC} + {"delete", GRUB_TERM_KEY_DC} }; /* Add a menu entry to the current menu context (as given by the environment diff --git a/normal/menu.c b/normal/menu.c index 09c5fd1eb..b740ea3ca 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -397,7 +397,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) if (grub_checkkey () >= 0 || timeout < 0) { - c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + c = grub_getkey (); if (timeout >= 0) { @@ -408,31 +408,36 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) switch (c) { - case GRUB_TERM_HOME: + case GRUB_TERM_KEY_HOME: + case GRUB_TERM_CTRL | 'a': current_entry = 0; menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_END: + case GRUB_TERM_KEY_END: + case GRUB_TERM_CTRL | 'e': current_entry = menu->size - 1; menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_UP: + case GRUB_TERM_KEY_UP: + case GRUB_TERM_CTRL | 'p': case '^': if (current_entry > 0) current_entry--; menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_DOWN: + case GRUB_TERM_CTRL | 'n': + case GRUB_TERM_KEY_DOWN: case 'v': if (current_entry < menu->size - 1) current_entry++; menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_PPAGE: + case GRUB_TERM_CTRL | 'g': + case GRUB_TERM_KEY_PPAGE: if (current_entry < GRUB_MENU_PAGE_SIZE) current_entry = 0; else @@ -440,7 +445,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) menu_set_chosen_entry (current_entry); break; - case GRUB_TERM_NPAGE: + case GRUB_TERM_CTRL | 'c': + case GRUB_TERM_KEY_NPAGE: if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size) current_entry += GRUB_MENU_PAGE_SIZE; else @@ -450,7 +456,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) case '\n': case '\r': - case 6: + case GRUB_TERM_KEY_RIGHT: + case GRUB_TERM_CTRL | 'f': menu_fini (); *auto_boot = 0; return current_entry; diff --git a/normal/menu_entry.c b/normal/menu_entry.c index 644fe90fd..0b03147dd 100644 --- a/normal/menu_entry.c +++ b/normal/menu_entry.c @@ -1262,7 +1262,7 @@ grub_menu_entry_run (grub_menu_entry_t entry) while (1) { - int c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); + int c = grub_getkey (); if (screen->completion_shown) { @@ -1278,70 +1278,78 @@ grub_menu_entry_run (grub_menu_entry_t entry) switch (c) { - case 16: /* C-p */ + case GRUB_TERM_KEY_UP: + case GRUB_TERM_CTRL | 'p': if (! previous_line (screen, 1)) goto fail; break; - case 14: /* C-n */ + case GRUB_TERM_CTRL | 'n': + case GRUB_TERM_KEY_DOWN: if (! next_line (screen, 1)) goto fail; break; - case 6: /* C-f */ + case GRUB_TERM_CTRL | 'f': + case GRUB_TERM_KEY_RIGHT: if (! forward_char (screen, 1)) goto fail; break; - case 2: /* C-b */ + case GRUB_TERM_CTRL | 'b': + case GRUB_TERM_KEY_LEFT: if (! backward_char (screen, 1)) goto fail; break; - case 1: /* C-a */ + case GRUB_TERM_CTRL | 'a': + case GRUB_TERM_KEY_HOME: if (! beginning_of_line (screen, 1)) goto fail; break; - case 5: /* C-e */ + case GRUB_TERM_CTRL | 'e': + case GRUB_TERM_KEY_END: if (! end_of_line (screen, 1)) goto fail; break; - case '\t': /* C-i */ + case GRUB_TERM_CTRL | 'i': + case '\t': if (! complete (screen, prev_c == c, 1)) goto fail; break; - case 4: /* C-d */ + case GRUB_TERM_CTRL | 'd': + case GRUB_TERM_KEY_DC: if (! delete_char (screen, 1)) goto fail; break; - case 8: /* C-h */ + case GRUB_TERM_CTRL | 'h': if (! backward_delete_char (screen, 1)) goto fail; break; - case 11: /* C-k */ + case GRUB_TERM_CTRL | 'k': if (! kill_line (screen, prev_c == c, 1)) goto fail; break; - case 21: /* C-u */ + case GRUB_TERM_CTRL | 'u': /* FIXME: What behavior is good for this key? */ break; - case 25: /* C-y */ + case GRUB_TERM_CTRL | 'y': if (! yank (screen, 1)) goto fail; break; - case 12: /* C-l */ + case GRUB_TERM_CTRL | 'l': /* FIXME: centering. */ goto refresh; - case 15: /* C-o */ + case GRUB_TERM_CTRL | 'o': if (! open_line (screen, 1)) goto fail; break; @@ -1356,18 +1364,18 @@ grub_menu_entry_run (grub_menu_entry_t entry) destroy_screen (screen); return; - case 3: /* C-c */ + case GRUB_TERM_CTRL | 'c': grub_cmdline_run (1); goto refresh; - case 24: /* C-x */ + case GRUB_TERM_CTRL | 'x': if (! run (screen)) goto fail; goto refresh; - case 18: /* C-r */ - case 19: /* C-s */ - case 20: /* C-t */ + case GRUB_TERM_CTRL | 'r': + case GRUB_TERM_CTRL | 's': + case GRUB_TERM_CTRL | 't': /* FIXME */ break; diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 1f84ae71a..f1932f64e 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -41,7 +41,7 @@ static grub_uint8_t led_status; #define KEYBOARD_LED_NUM (1 << 1) #define KEYBOARD_LED_CAPS (1 << 2) -static char keyboard_map[128] = +static int keyboard_map[128] = { '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, @@ -51,9 +51,9 @@ static char keyboard_map[128] = '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '\0', '*', '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_HOME, - GRUB_TERM_UP, GRUB_TERM_NPAGE, '-', GRUB_TERM_LEFT, '\0', GRUB_TERM_RIGHT, '+', GRUB_TERM_END, - GRUB_TERM_DOWN, GRUB_TERM_PPAGE, '\0', GRUB_TERM_DC, '\0', '\0', '\0', '\0', + '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_KEY_HOME, + GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, '\0', GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END, + GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE, '\0', GRUB_TERM_KEY_DC, '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, OLPC_RIGHT @@ -213,9 +213,8 @@ grub_at_keyboard_getkey_noblock (void) key = -1; break; default: - if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R)) - key = keyboard_map[code] - 'a' + 1; - else if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L | KEYBOARD_STATUS_SHIFT_R)) + if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L + | KEYBOARD_STATUS_SHIFT_R)) && keyboard_map_shift[code]) key = keyboard_map_shift[code]; else @@ -231,6 +230,17 @@ grub_at_keyboard_getkey_noblock (void) else if ((key >= 'A') && (key <= 'Z')) key += 'a' - 'A'; } + + if (at_keyboard_status & KEYBOARD_STATUS_ALT_L) + key |= GRUB_TERM_ALT; + if (at_keyboard_status & KEYBOARD_STATUS_ALT_R) + key |= GRUB_TERM_ALT_GR; + 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; } @@ -290,6 +300,7 @@ static struct grub_term_input grub_at_keyboard_term = .fini = grub_keyboard_controller_fini, .checkkey = grub_at_keyboard_checkkey, .getkey = grub_at_keyboard_getkey, + .flags = GRUB_TERM_INPUT_FLAGS_TYPE_AT }; GRUB_MOD_INIT(at_keyboard) diff --git a/term/i386/pc/console.c b/term/i386/pc/console.c index 43cfe2f2a..09baabd8f 100644 --- a/term/i386/pc/console.c +++ b/term/i386/pc/console.c @@ -51,6 +51,7 @@ static struct grub_term_input grub_console_term_input = .checkkey = grub_console_checkkey, .getkey = grub_console_getkey, .getkeystatus = grub_console_getkeystatus, + .flags = GRUB_TERM_INPUT_FLAGS_TYPE_BIOS }; static struct grub_term_output grub_console_term_output = diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 5d76c5e02..8f9a79ec4 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -28,7 +28,7 @@ #include -static char keyboard_map[128] = +static int keyboard_map[128] = { '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', @@ -39,8 +39,8 @@ static char keyboard_map[128] = ']', '\\', '#', ';', '\'', '`', ',', '.', '/', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', - '\0', '\0', GRUB_TERM_HOME, GRUB_TERM_PPAGE, GRUB_TERM_DC, GRUB_TERM_END, GRUB_TERM_NPAGE, GRUB_TERM_RIGHT, - GRUB_TERM_LEFT, GRUB_TERM_DOWN, GRUB_TERM_UP + '\0', '\0', 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 }; static char keyboard_map_shift[128] = diff --git a/util/grub-fstest.c b/util/grub-fstest.c index c03c43451..14ddf2ad8 100644 --- a/util/grub-fstest.c +++ b/util/grub-fstest.c @@ -49,14 +49,13 @@ grub_putchar (int c) putchar (c); } -int -grub_getkey (void) +static int +grub_getkey_real (void) { return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; +int (*grub_getkey) (void) = grub_getkey_real; void grub_refresh (void) diff --git a/util/grub-probe.c b/util/grub-probe.c index bb41480e2..cb082da6d 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -64,14 +64,13 @@ grub_putchar (int c) putchar (c); } -int -grub_getkey (void) +static int +grub_getkey_real (void) { return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; +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 63fa8c328..ffdb356a6 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -63,14 +63,13 @@ grub_putchar (int c) putchar (c); } -int -grub_getkey (void) +static int +grub_getkey_real (void) { return -1; } -struct grub_handler_class grub_term_input_class; -struct grub_handler_class grub_term_output_class; +int (*grub_getkey) (void) = grub_getkey_real; void grub_refresh (void)