Skeleton for keyboard layouts

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-05-10 14:54:51 +02:00
parent c6e5caab1d
commit 87fae34a1f
21 changed files with 337 additions and 168 deletions

View file

@ -63,7 +63,7 @@ grub_cmd_cat (grub_command_t cmd __attribute__ ((unused)),
} }
while (grub_checkkey () >= 0 && while (grub_checkkey () >= 0 &&
(key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != GRUB_TERM_ESC) (key = grub_getkey ()) != GRUB_TERM_ESC)
; ;
} }

186
commands/keylayouts.c Normal file
View file

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <grub/term.h>
#include <grub/err.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/env.h>
#include <grub/time.h>
#include <grub/dl.h>
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;
}

View file

@ -31,7 +31,20 @@ static const struct grub_arg_option options[] =
{0, 0, 0, 0, 0, 0} {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 static grub_err_t
grub_cmd_keystatus (grub_extcmd_t cmd, grub_cmd_keystatus (grub_extcmd_t cmd,

View file

@ -52,8 +52,7 @@ grub_interruptible_millisleep (grub_uint32_t ms)
start = grub_get_time_ms (); start = grub_get_time_ms ();
while (grub_get_time_ms () - start < ms) while (grub_get_time_ms () - start < ms)
if (grub_checkkey () >= 0 && if (grub_checkkey () >= 0 && grub_getkey () == GRUB_TERM_ESC)
GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC)
return 1; return 1;
return 0; return 0;

View file

@ -491,6 +491,11 @@ extcmd_mod_SOURCES = commands/extcmd.c lib/arg.c
extcmd_mod_CFLAGS = $(COMMON_CFLAGS) extcmd_mod_CFLAGS = $(COMMON_CFLAGS)
extcmd_mod_LDFLAGS = $(COMMON_LDFLAGS) 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. # For hello.mod.
hello_mod_SOURCES = hello/hello.c hello_mod_SOURCES = hello/hello.c
hello_mod_CFLAGS = $(COMMON_CFLAGS) hello_mod_CFLAGS = $(COMMON_CFLAGS)

View file

@ -20,18 +20,27 @@
#define GRUB_TERM_HEADER 1 #define GRUB_TERM_HEADER 1
/* Internal codes used by GRUB to represent terminal input. */ /* Internal codes used by GRUB to represent terminal input. */
#define GRUB_TERM_LEFT 2 #define GRUB_TERM_CTRL 0x02000000
#define GRUB_TERM_RIGHT 6 #define GRUB_TERM_ALT 0x04000000
#define GRUB_TERM_UP 16 /* Used by keylayouts code. Never returned in grub_getkey. */
#define GRUB_TERM_DOWN 14 #define GRUB_TERM_ALT_GR 0x08000000
#define GRUB_TERM_HOME 1 #define GRUB_TERM_CAPS 0x10000000
#define GRUB_TERM_END 5
#define GRUB_TERM_DC 4 /* Keys without associated character. */
#define GRUB_TERM_PPAGE 7 #define GRUB_TERM_EXTENDED 0x1000000
#define GRUB_TERM_NPAGE 3 #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_ESC '\e'
#define GRUB_TERM_TAB '\t' #define GRUB_TERM_TAB '\t'
#define GRUB_TERM_BACKSPACE 8 #define GRUB_TERM_BACKSPACE '\b'
#ifndef ASM_FILE #ifndef ASM_FILE
@ -135,9 +144,15 @@ struct grub_term_input
/* Get keyboard modifier status. */ /* Get keyboard modifier status. */
int (*getkeystatus) (void); int (*getkeystatus) (void);
grub_uint32_t flags;
}; };
typedef struct grub_term_input *grub_term_input_t; 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 struct grub_term_output
{ {
/* The next terminal. */ /* 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_putchar) (int c);
void EXPORT_FUNC(grub_putcode) (grub_uint32_t code, void EXPORT_FUNC(grub_putcode) (grub_uint32_t code,
struct grub_term_output *term); struct grub_term_output *term);
int EXPORT_FUNC(grub_getkey) (void); extern int (*EXPORT_VAR(grub_getkey)) (void);
int EXPORT_FUNC(grub_checkkey) (void); int grub_checkkey (void);
int EXPORT_FUNC(grub_getkeystatus) (void);
void EXPORT_FUNC(grub_cls) (void); void EXPORT_FUNC(grub_cls) (void);
void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state); void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
void EXPORT_FUNC(grub_refresh) (void); void EXPORT_FUNC(grub_refresh) (void);
@ -409,10 +423,6 @@ grub_print_spaces (struct grub_term_output *term, int number_spaces)
grub_putcode (' ', term); grub_putcode (' ', term);
} }
/* For convenience. */
#define GRUB_TERM_ASCII_CHAR(c) ((c) & 0xff)
#endif /* ! ASM_FILE */ #endif /* ! ASM_FILE */
#endif /* ! GRUB_TERM_HEADER */ #endif /* ! GRUB_TERM_HEADER */

View file

@ -1154,54 +1154,6 @@ FUNCTION(grub_console_real_putchar)
* %al = ASCII character * %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) FUNCTION(grub_console_getkey)
pushl %ebp pushl %ebp
@ -1228,7 +1180,6 @@ FUNCTION(grub_console_getkey)
int $0x16 int $0x16
movw %ax, %dx /* real_to_prot uses %eax */ movw %ax, %dx /* real_to_prot uses %eax */
call translate_keycode
DATA32 call real_to_prot DATA32 call real_to_prot
.code32 .code32

View file

@ -38,7 +38,7 @@ grub_rescue_read_line (char **line, int cont)
grub_printf ((cont) ? "> " : "grub rescue> "); grub_printf ((cont) ? "> " : "grub rescue> ");
grub_memset (linebuf, 0, GRUB_RESCUE_BUF_SIZE); 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)) if (grub_isprint (c))
{ {

View file

@ -75,8 +75,8 @@ grub_putchar (int c)
} }
} }
int static int
grub_getkey (void) grub_getkey_dumb (void)
{ {
grub_term_input_t term; grub_term_input_t term;
@ -88,42 +88,14 @@ grub_getkey (void)
{ {
int key = term->checkkey (); int key = term->checkkey ();
if (key != -1) if (key != -1)
return term->getkey (); return term->getkey () & 0xff;
} }
grub_cpu_idle (); grub_cpu_idle ();
} }
} }
int int (*grub_getkey) (void) = grub_getkey_dumb;
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;
}
void void
grub_cls (void) grub_cls (void)

View file

@ -420,7 +420,7 @@ grub_password_get (char buf[], unsigned buf_size)
while (1) while (1)
{ {
key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); key = grub_getkey ();
if (key == '\n' || key == '\r') if (key == '\n' || key == '\r')
break; break;

View file

@ -162,7 +162,7 @@ grub_username_get (char buf[], unsigned buf_size)
while (1) while (1)
{ {
key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); key = grub_getkey ();
if (key == '\n' || key == '\r') if (key == '\n' || key == '\r')
break; break;

View file

@ -387,16 +387,18 @@ grub_cmdline_get (const char *prompt)
grub_refresh (); grub_refresh ();
while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r') while ((key = grub_getkey ()) != '\n' && key != '\r')
{ {
switch (key) switch (key)
{ {
case 1: /* Ctrl-a */ case GRUB_TERM_CTRL | 'a':
case GRUB_TERM_KEY_HOME:
lpos = 0; lpos = 0;
cl_set_pos_all (); cl_set_pos_all ();
break; break;
case 2: /* Ctrl-b */ case GRUB_TERM_CTRL | 'b':
case GRUB_TERM_KEY_LEFT:
if (lpos > 0) if (lpos > 0)
{ {
lpos--; lpos--;
@ -404,12 +406,14 @@ grub_cmdline_get (const char *prompt)
} }
break; break;
case 5: /* Ctrl-e */ case GRUB_TERM_CTRL | 'e':
case GRUB_TERM_KEY_END:
lpos = llen; lpos = llen;
cl_set_pos_all (); cl_set_pos_all ();
break; break;
case 6: /* Ctrl-f */ case GRUB_TERM_CTRL | 'f':
case GRUB_TERM_KEY_RIGHT:
if (lpos < llen) if (lpos < llen)
{ {
lpos++; lpos++;
@ -417,7 +421,8 @@ grub_cmdline_get (const char *prompt)
} }
break; break;
case 9: /* Ctrl-i or TAB */ case GRUB_TERM_CTRL | 'i':
case '\t':
{ {
int restore; int restore;
char *insertu8; char *insertu8;
@ -489,7 +494,7 @@ grub_cmdline_get (const char *prompt)
} }
break; break;
case 11: /* Ctrl-k */ case GRUB_TERM_CTRL | 'k':
if (lpos < llen) if (lpos < llen)
{ {
if (kill_buf) if (kill_buf)
@ -513,7 +518,8 @@ grub_cmdline_get (const char *prompt)
} }
break; break;
case 14: /* Ctrl-n */ case GRUB_TERM_CTRL | 'n':
case GRUB_TERM_KEY_DOWN:
{ {
grub_uint32_t *hist; grub_uint32_t *hist;
@ -531,7 +537,9 @@ grub_cmdline_get (const char *prompt)
break; break;
} }
case 16: /* Ctrl-p */
case GRUB_TERM_KEY_UP:
case GRUB_TERM_CTRL | 'p':
{ {
grub_uint32_t *hist; grub_uint32_t *hist;
@ -550,7 +558,7 @@ grub_cmdline_get (const char *prompt)
} }
break; break;
case 21: /* Ctrl-u */ case GRUB_TERM_CTRL | 'u':
if (lpos > 0) if (lpos > 0)
{ {
grub_size_t n = lpos; grub_size_t n = lpos;
@ -576,7 +584,7 @@ grub_cmdline_get (const char *prompt)
} }
break; break;
case 25: /* Ctrl-y */ case GRUB_TERM_CTRL | 'y':
if (kill_buf) if (kill_buf)
cl_insert (kill_buf); cl_insert (kill_buf);
break; break;
@ -594,7 +602,8 @@ grub_cmdline_get (const char *prompt)
break; break;
/* fall through */ /* fall through */
case 4: /* Ctrl-d */ case GRUB_TERM_CTRL | 'd':
case GRUB_TERM_KEY_DC:
if (lpos < llen) if (lpos < llen)
cl_delete (1); cl_delete (1);
break; break;

View file

@ -163,7 +163,7 @@ static struct
{ {
{"backspace", '\b'}, {"backspace", '\b'},
{"tab", '\t'}, {"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 /* Add a menu entry to the current menu context (as given by the environment

View file

@ -397,7 +397,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
if (grub_checkkey () >= 0 || timeout < 0) if (grub_checkkey () >= 0 || timeout < 0)
{ {
c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); c = grub_getkey ();
if (timeout >= 0) if (timeout >= 0)
{ {
@ -408,31 +408,36 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
switch (c) switch (c)
{ {
case GRUB_TERM_HOME: case GRUB_TERM_KEY_HOME:
case GRUB_TERM_CTRL | 'a':
current_entry = 0; current_entry = 0;
menu_set_chosen_entry (current_entry); menu_set_chosen_entry (current_entry);
break; break;
case GRUB_TERM_END: case GRUB_TERM_KEY_END:
case GRUB_TERM_CTRL | 'e':
current_entry = menu->size - 1; current_entry = menu->size - 1;
menu_set_chosen_entry (current_entry); menu_set_chosen_entry (current_entry);
break; break;
case GRUB_TERM_UP: case GRUB_TERM_KEY_UP:
case GRUB_TERM_CTRL | 'p':
case '^': case '^':
if (current_entry > 0) if (current_entry > 0)
current_entry--; current_entry--;
menu_set_chosen_entry (current_entry); menu_set_chosen_entry (current_entry);
break; break;
case GRUB_TERM_DOWN: case GRUB_TERM_CTRL | 'n':
case GRUB_TERM_KEY_DOWN:
case 'v': case 'v':
if (current_entry < menu->size - 1) if (current_entry < menu->size - 1)
current_entry++; current_entry++;
menu_set_chosen_entry (current_entry); menu_set_chosen_entry (current_entry);
break; break;
case GRUB_TERM_PPAGE: case GRUB_TERM_CTRL | 'g':
case GRUB_TERM_KEY_PPAGE:
if (current_entry < GRUB_MENU_PAGE_SIZE) if (current_entry < GRUB_MENU_PAGE_SIZE)
current_entry = 0; current_entry = 0;
else else
@ -440,7 +445,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
menu_set_chosen_entry (current_entry); menu_set_chosen_entry (current_entry);
break; break;
case GRUB_TERM_NPAGE: case GRUB_TERM_CTRL | 'c':
case GRUB_TERM_KEY_NPAGE:
if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size) if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size)
current_entry += GRUB_MENU_PAGE_SIZE; current_entry += GRUB_MENU_PAGE_SIZE;
else else
@ -450,7 +456,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot)
case '\n': case '\n':
case '\r': case '\r':
case 6: case GRUB_TERM_KEY_RIGHT:
case GRUB_TERM_CTRL | 'f':
menu_fini (); menu_fini ();
*auto_boot = 0; *auto_boot = 0;
return current_entry; return current_entry;

View file

@ -1262,7 +1262,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
while (1) while (1)
{ {
int c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); int c = grub_getkey ();
if (screen->completion_shown) if (screen->completion_shown)
{ {
@ -1278,70 +1278,78 @@ grub_menu_entry_run (grub_menu_entry_t entry)
switch (c) switch (c)
{ {
case 16: /* C-p */ case GRUB_TERM_KEY_UP:
case GRUB_TERM_CTRL | 'p':
if (! previous_line (screen, 1)) if (! previous_line (screen, 1))
goto fail; goto fail;
break; break;
case 14: /* C-n */ case GRUB_TERM_CTRL | 'n':
case GRUB_TERM_KEY_DOWN:
if (! next_line (screen, 1)) if (! next_line (screen, 1))
goto fail; goto fail;
break; break;
case 6: /* C-f */ case GRUB_TERM_CTRL | 'f':
case GRUB_TERM_KEY_RIGHT:
if (! forward_char (screen, 1)) if (! forward_char (screen, 1))
goto fail; goto fail;
break; break;
case 2: /* C-b */ case GRUB_TERM_CTRL | 'b':
case GRUB_TERM_KEY_LEFT:
if (! backward_char (screen, 1)) if (! backward_char (screen, 1))
goto fail; goto fail;
break; break;
case 1: /* C-a */ case GRUB_TERM_CTRL | 'a':
case GRUB_TERM_KEY_HOME:
if (! beginning_of_line (screen, 1)) if (! beginning_of_line (screen, 1))
goto fail; goto fail;
break; break;
case 5: /* C-e */ case GRUB_TERM_CTRL | 'e':
case GRUB_TERM_KEY_END:
if (! end_of_line (screen, 1)) if (! end_of_line (screen, 1))
goto fail; goto fail;
break; break;
case '\t': /* C-i */ case GRUB_TERM_CTRL | 'i':
case '\t':
if (! complete (screen, prev_c == c, 1)) if (! complete (screen, prev_c == c, 1))
goto fail; goto fail;
break; break;
case 4: /* C-d */ case GRUB_TERM_CTRL | 'd':
case GRUB_TERM_KEY_DC:
if (! delete_char (screen, 1)) if (! delete_char (screen, 1))
goto fail; goto fail;
break; break;
case 8: /* C-h */ case GRUB_TERM_CTRL | 'h':
if (! backward_delete_char (screen, 1)) if (! backward_delete_char (screen, 1))
goto fail; goto fail;
break; break;
case 11: /* C-k */ case GRUB_TERM_CTRL | 'k':
if (! kill_line (screen, prev_c == c, 1)) if (! kill_line (screen, prev_c == c, 1))
goto fail; goto fail;
break; break;
case 21: /* C-u */ case GRUB_TERM_CTRL | 'u':
/* FIXME: What behavior is good for this key? */ /* FIXME: What behavior is good for this key? */
break; break;
case 25: /* C-y */ case GRUB_TERM_CTRL | 'y':
if (! yank (screen, 1)) if (! yank (screen, 1))
goto fail; goto fail;
break; break;
case 12: /* C-l */ case GRUB_TERM_CTRL | 'l':
/* FIXME: centering. */ /* FIXME: centering. */
goto refresh; goto refresh;
case 15: /* C-o */ case GRUB_TERM_CTRL | 'o':
if (! open_line (screen, 1)) if (! open_line (screen, 1))
goto fail; goto fail;
break; break;
@ -1356,18 +1364,18 @@ grub_menu_entry_run (grub_menu_entry_t entry)
destroy_screen (screen); destroy_screen (screen);
return; return;
case 3: /* C-c */ case GRUB_TERM_CTRL | 'c':
grub_cmdline_run (1); grub_cmdline_run (1);
goto refresh; goto refresh;
case 24: /* C-x */ case GRUB_TERM_CTRL | 'x':
if (! run (screen)) if (! run (screen))
goto fail; goto fail;
goto refresh; goto refresh;
case 18: /* C-r */ case GRUB_TERM_CTRL | 'r':
case 19: /* C-s */ case GRUB_TERM_CTRL | 's':
case 20: /* C-t */ case GRUB_TERM_CTRL | 't':
/* FIXME */ /* FIXME */
break; break;

View file

@ -41,7 +41,7 @@ static grub_uint8_t led_status;
#define KEYBOARD_LED_NUM (1 << 1) #define KEYBOARD_LED_NUM (1 << 1)
#define KEYBOARD_LED_CAPS (1 << 2) #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', '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6',
'7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB,
@ -51,9 +51,9 @@ static char keyboard_map[128] =
'\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',
'b', 'n', 'm', ',', '.', '/', '\0', '*', 'b', 'n', 'm', ',', '.', '/', '\0', '*',
'\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0', '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_HOME, '\0', '\0', '\0', '\0', '\0', '\0', '\0', GRUB_TERM_KEY_HOME,
GRUB_TERM_UP, GRUB_TERM_NPAGE, '-', GRUB_TERM_LEFT, '\0', GRUB_TERM_RIGHT, '+', GRUB_TERM_END, GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT, '\0', GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END,
GRUB_TERM_DOWN, GRUB_TERM_PPAGE, '\0', GRUB_TERM_DC, '\0', '\0', '\0', '\0', 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', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, '\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT,
OLPC_RIGHT OLPC_RIGHT
@ -213,9 +213,8 @@ grub_at_keyboard_getkey_noblock (void)
key = -1; key = -1;
break; break;
default: default:
if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R)) if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L
key = keyboard_map[code] - 'a' + 1; | KEYBOARD_STATUS_SHIFT_R))
else if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L | KEYBOARD_STATUS_SHIFT_R))
&& keyboard_map_shift[code]) && keyboard_map_shift[code])
key = keyboard_map_shift[code]; key = keyboard_map_shift[code];
else else
@ -231,6 +230,17 @@ grub_at_keyboard_getkey_noblock (void)
else if ((key >= 'A') && (key <= 'Z')) else if ((key >= 'A') && (key <= 'Z'))
key += 'a' - 'A'; 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; return key;
} }
@ -290,6 +300,7 @@ static struct grub_term_input grub_at_keyboard_term =
.fini = grub_keyboard_controller_fini, .fini = grub_keyboard_controller_fini,
.checkkey = grub_at_keyboard_checkkey, .checkkey = grub_at_keyboard_checkkey,
.getkey = grub_at_keyboard_getkey, .getkey = grub_at_keyboard_getkey,
.flags = GRUB_TERM_INPUT_FLAGS_TYPE_AT
}; };
GRUB_MOD_INIT(at_keyboard) GRUB_MOD_INIT(at_keyboard)

View file

@ -51,6 +51,7 @@ static struct grub_term_input grub_console_term_input =
.checkkey = grub_console_checkkey, .checkkey = grub_console_checkkey,
.getkey = grub_console_getkey, .getkey = grub_console_getkey,
.getkeystatus = grub_console_getkeystatus, .getkeystatus = grub_console_getkeystatus,
.flags = GRUB_TERM_INPUT_FLAGS_TYPE_BIOS
}; };
static struct grub_term_output grub_console_term_output = static struct grub_term_output grub_console_term_output =

View file

@ -28,7 +28,7 @@
#include <grub/time.h> #include <grub/time.h>
static char keyboard_map[128] = static int keyboard_map[128] =
{ {
'\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd', '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', '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', '\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, '\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_LEFT, GRUB_TERM_DOWN, GRUB_TERM_UP GRUB_TERM_KEY_LEFT, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_UP
}; };
static char keyboard_map_shift[128] = static char keyboard_map_shift[128] =

View file

@ -49,14 +49,13 @@ grub_putchar (int c)
putchar (c); putchar (c);
} }
int static int
grub_getkey (void) grub_getkey_real (void)
{ {
return -1; return -1;
} }
struct grub_handler_class grub_term_input_class; int (*grub_getkey) (void) = grub_getkey_real;
struct grub_handler_class grub_term_output_class;
void void
grub_refresh (void) grub_refresh (void)

View file

@ -64,14 +64,13 @@ grub_putchar (int c)
putchar (c); putchar (c);
} }
int static int
grub_getkey (void) grub_getkey_real (void)
{ {
return -1; return -1;
} }
struct grub_handler_class grub_term_input_class; int (*grub_getkey) (void) = grub_getkey_real;
struct grub_handler_class grub_term_output_class;
void void
grub_refresh (void) grub_refresh (void)

View file

@ -63,14 +63,13 @@ grub_putchar (int c)
putchar (c); putchar (c);
} }
int static int
grub_getkey (void) grub_getkey_real (void)
{ {
return -1; return -1;
} }
struct grub_handler_class grub_term_input_class; int (*grub_getkey) (void) = grub_getkey_real;
struct grub_handler_class grub_term_output_class;
void void
grub_refresh (void) grub_refresh (void)