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)