support for Fn keys

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-08-19 01:07:50 +02:00
parent 2cccf4b0c4
commit 7a6459e12d
11 changed files with 123 additions and 185 deletions

View file

@ -23,39 +23,13 @@
#include <grub/env.h>
#include <grub/time.h>
#include <grub/dl.h>
#include <grub/at_keyboard.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
GRUB_AT_KEY_KEYBOARD_MAP (keyboard_map);
static int
get_abstract_code (grub_term_input_t term, int in)
{
unsigned flags = 0;
switch (term->flags & GRUB_TERM_INPUT_FLAGS_TYPE_MASK)
{
case GRUB_TERM_INPUT_FLAGS_TYPE_TERMCODES:
@ -64,32 +38,18 @@ get_abstract_code (grub_term_input_t term, int in)
case GRUB_TERM_INPUT_FLAGS_TYPE_BIOS:
{
unsigned status = 0;
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},
{0x5600 | '\\', GRUB_TERM_KEY_102},
{0x5600 | '|', GRUB_TERM_KEY_SHIFT_102},
};
unsigned i;
unsigned flags = 0;
if (term->getkeystatus)
status = term->getkeystatus ();
status = term->getkeystatus (term);
if (status & GRUB_TERM_CAPS)
flags |= GRUB_TERM_CAPS;
for (i = 0; i < ARRAY_SIZE (translations); i++)
if (translations[i].from == (in & 0xffff))
return translations[i].to | flags;
if ((0x5600 | '\\') == (in & 0xffff))
return GRUB_TERM_KEY_102 | flags;
if ((0x5600 | '|') == (in & 0xffff))
return GRUB_TERM_KEY_SHIFT_102 | flags;
/* Detect CTRL'ed keys. */
if ((in & 0xff) > 0 && (in & 0xff) < 0x20
@ -105,6 +65,9 @@ get_abstract_code (grub_term_input_t term, int in)
&& keyboard_map[(in & 0xff00) >> 8] <= 'z')
return keyboard_map[(in & 0xff00) >> 8] | flags | GRUB_TERM_ALT_GR;
if ((in & 0xff) == 0)
return keyboard_map[(in & 0xff00) >> 8] | flags;
return (in & 0xff) | flags;
}
}
@ -165,9 +128,9 @@ grub_getkey_smart (void)
{
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey ();
int key = term->checkkey (term);
if (key != -1)
return translate (term, term->getkey ());
return translate (term, term->getkey (term));
}
grub_cpu_idle ();
@ -181,7 +144,7 @@ grub_checkkey (void)
FOR_ACTIVE_TERM_INPUTS(term)
{
int key = term->checkkey ();
int key = term->checkkey (term);
if (key != -1)
return translate (term, key);
}

View file

@ -40,7 +40,7 @@ grub_getkeystatus (void)
FOR_ACTIVE_TERM_INPUTS(term)
{
if (term->getkeystatus)
status |= term->getkeystatus ();
status |= term->getkeystatus (term);
}
return status;

View file

@ -51,4 +51,28 @@
#define OLPC_RIGHT '\0'
#endif
#define GRUB_AT_KEY_KEYBOARD_MAP(name) \
static const int name[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', GRUB_TERM_KEY_F1, \
GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, \
GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, \
GRUB_TERM_KEY_F10, '\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, \
GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC, \
'\0', '\0', GRUB_TERM_KEY_102, GRUB_TERM_KEY_F11, \
GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0', \
'\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT, \
OLPC_RIGHT \
}
#endif

View file

@ -38,10 +38,23 @@
#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)
/* Used by keylayouts code. Never returned in grub_getkey. */
#define GRUB_TERM_KEY_102 (GRUB_TERM_EXTENDED | 10)
#define GRUB_TERM_KEY_SHIFT_102 (GRUB_TERM_EXTENDED | 11)
#define GRUB_TERM_KEY_102 (GRUB_TERM_EXTENDED | 23)
#define GRUB_TERM_KEY_SHIFT_102 (GRUB_TERM_EXTENDED | 24)
#define GRUB_TERM_ESC '\e'
#define GRUB_TERM_TAB '\t'

View file

@ -164,7 +164,20 @@ static struct
{
{"backspace", '\b'},
{"tab", '\t'},
{"delete", GRUB_TERM_KEY_DC}
{"delete", GRUB_TERM_KEY_DC},
{"insert", GRUB_TERM_KEY_INSERT},
{"f1", GRUB_TERM_KEY_F1},
{"f2", GRUB_TERM_KEY_F2},
{"f3", GRUB_TERM_KEY_F3},
{"f4", GRUB_TERM_KEY_F4},
{"f5", GRUB_TERM_KEY_F5},
{"f6", GRUB_TERM_KEY_F6},
{"f7", GRUB_TERM_KEY_F7},
{"f8", GRUB_TERM_KEY_F8},
{"f9", GRUB_TERM_KEY_F9},
{"f10", GRUB_TERM_KEY_F10},
{"f11", GRUB_TERM_KEY_F11},
{"f12", GRUB_TERM_KEY_F12},
};
/* Add a menu entry to the current menu context (as given by the environment

View file

@ -1337,6 +1337,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
break;
case GRUB_TERM_CTRL | 'h':
case '\b':
if (! backward_delete_char (screen, 1))
goto fail;
break;
@ -1375,10 +1376,12 @@ grub_menu_entry_run (grub_menu_entry_t entry)
return;
case GRUB_TERM_CTRL | 'c':
case GRUB_TERM_KEY_F2:
grub_cmdline_run (1);
goto refresh;
case GRUB_TERM_CTRL | 'x':
case GRUB_TERM_KEY_F10:
{
int chars_before = grub_normal_get_char_counter ();
run (screen);

View file

@ -120,17 +120,10 @@ print_message (int nested, int edit, struct grub_term_output *term)
if (edit)
{
grub_putcode ('\n', term);
#ifdef GRUB_MACHINE_EFI
grub_print_message_indented (_("Minimum Emacs-like screen editing is \
supported. TAB lists completions. Press F1 to boot, F2=Ctrl-a, F3=Ctrl-e, \
F4 for a command-line or ESC to discard edits and return to the GRUB menu."),
STANDARD_MARGIN, STANDARD_MARGIN, term);
#else
grub_print_message_indented (_("Minimum Emacs-like screen editing is \
supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \
supported. TAB lists completions. Press Ctrl-x or F10 to boot, Ctrl-c or F2 for a \
command-line or ESC to discard edits and return to the GRUB menu."),
STANDARD_MARGIN, STANDARD_MARGIN, term);
#endif
}
else
{

View file

@ -41,24 +41,7 @@ static grub_uint8_t led_status;
#define KEYBOARD_LED_NUM (1 << 1)
#define KEYBOARD_LED_CAPS (1 << 2)
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, '\0', '\0',
GRUB_TERM_KEY_102, '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', OLPC_UP, OLPC_DOWN, OLPC_LEFT,
OLPC_RIGHT
};
GRUB_AT_KEY_KEYBOARD_MAP (keyboard_map);
static int keyboard_map_shift[128] =
{

View file

@ -100,6 +100,17 @@ grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)),
efi_call_2 (o->output_string, o, str);
}
const unsigned efi_codes[] =
{
0, GRUB_TERM_UP, GRUB_TERM_DOWN, GRUB_TERM_RIGHT,
GRUB_TERM_LEFT, GRUB_TERM_HOME, GRUB_TERM_END, GRUB_TERM_KEY_INSERT,
GRUB_TERM_DC, GRUB_TERM_KEY_PPAGE, GRUB_TERM_KEY_NPAGE, GRUB_TERM_KEY_F1,
GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5,
GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9,
GRUB_TERM_KEY_F10, 0, 0, '\e'
};
static int
grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused)))
{
@ -112,85 +123,14 @@ grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused)))
i = grub_efi_system_table->con_in;
status = efi_call_2 (i->read_key_stroke, i, &key);
#if 0
switch (status)
{
case GRUB_EFI_SUCCESS:
{
grub_uint16_t xy;
xy = grub_getxy ();
grub_gotoxy (0, 0);
grub_printf ("scan_code=%x,unicode_char=%x ",
(unsigned) key.scan_code,
(unsigned) key.unicode_char);
grub_gotoxy (xy >> 8, xy & 0xff);
}
break;
if (status != GRUB_EFI_SUCCESS)
return -1;
case GRUB_EFI_NOT_READY:
//grub_printf ("not ready ");
break;
default:
//grub_printf ("device error ");
break;
}
#endif
if (status == GRUB_EFI_SUCCESS)
{
switch (key.scan_code)
{
case 0x00:
read_key = key.unicode_char;
break;
case 0x01:
read_key = GRUB_TERM_UP;
break;
case 0x02:
read_key = GRUB_TERM_DOWN;
break;
case 0x03:
read_key = GRUB_TERM_RIGHT;
break;
case 0x04:
read_key = GRUB_TERM_LEFT;
break;
case 0x05:
read_key = GRUB_TERM_HOME;
break;
case 0x06:
read_key = GRUB_TERM_END;
break;
case 0x07:
break;
case 0x08:
read_key = GRUB_TERM_DC;
break;
case 0x09:
break;
case 0x0a:
break;
case 0x0b:
read_key = 24;
break;
case 0x0c:
read_key = 1;
break;
case 0x0d:
read_key = 5;
break;
case 0x0e:
read_key = 3;
break;
case 0x17:
read_key = '\e';
break;
default:
break;
}
}
if (key.scan_code == 0)
read_key = key.unicode_char;
else if (key.scan_code < ARRAY_SIZE (efi_codes))
read_key = efi_codes[key.scan_code];
return read_key;
}

View file

@ -402,34 +402,34 @@ grub_terminfo_readkey (int *keys, int *len, int (*readkey) (void))
static struct
{
char key;
char ascii;
unsigned ascii;
}
three_code_table[] =
{
{'4', GRUB_TERM_DC},
{'A', GRUB_TERM_UP},
{'B', GRUB_TERM_DOWN},
{'C', GRUB_TERM_RIGHT},
{'D', GRUB_TERM_LEFT},
{'F', GRUB_TERM_END},
{'H', GRUB_TERM_HOME},
{'K', GRUB_TERM_END},
{'P', GRUB_TERM_DC},
{'?', GRUB_TERM_PPAGE},
{'/', GRUB_TERM_NPAGE}
{'4', GRUB_TERM_KEY_DC},
{'A', GRUB_TERM_KEY_UP},
{'B', GRUB_TERM_KEY_DOWN},
{'C', GRUB_TERM_KEY_RIGHT},
{'D', GRUB_TERM_KEY_LEFT},
{'F', GRUB_TERM_KEY_END},
{'H', GRUB_TERM_KEY_HOME},
{'K', GRUB_TERM_KEY_END},
{'P', GRUB_TERM_KEY_DC},
{'?', GRUB_TERM_KEY_PPAGE},
{'/', GRUB_TERM_KEY_NPAGE}
};
static struct
{
char key;
char ascii;
unsigned ascii;
}
four_code_table[] =
{
{'1', GRUB_TERM_HOME},
{'3', GRUB_TERM_DC},
{'5', GRUB_TERM_PPAGE},
{'6', GRUB_TERM_NPAGE}
{'1', GRUB_TERM_KEY_HOME},
{'3', GRUB_TERM_KEY_DC},
{'5', GRUB_TERM_KEY_PPAGE},
{'6', GRUB_TERM_KEY_NPAGE}
};
unsigned i;

View file

@ -27,7 +27,7 @@
#include <grub/time.h>
static int keyboard_map[128] =
static unsigned keyboard_map[128] =
{
'\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
@ -36,13 +36,17 @@ static int keyboard_map[128] =
'3', '4', '5', '6', '7', '8', '9', '0',
'\n', GRUB_TERM_ESC, GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, ' ', '-', '=', '[',
']', '\\', '#', ';', '\'', '`', ',', '.',
'/', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\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
'/', '\0', GRUB_TERM_KEY_F1, GRUB_TERM_KEY_F2,
GRUB_TERM_KEY_F3, GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5, GRUB_TERM_KEY_F6,
GRUB_TERM_KEY_F7, GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9, GRUB_TERM_KEY_F10,
GRUB_TERM_KEY_F11, GRUB_TERM_KEY_F12, '\0', '\0',
'\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
};
static char keyboard_map_shift[128] =
static unsigned keyboard_map_shift[128] =
{
'\0', '\0', '\0', '\0', 'A', 'B', 'C', 'D',
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
@ -51,7 +55,8 @@ static char keyboard_map_shift[128] =
'#', '$', '%', '^', '&', '*', '(', ')',
'\n', '\0', '\0', '\0', ' ', '_', '+', '{',
'}', '|', '#', ':', '"', '`', '<', '>',
'?'
'?',
[0x64] = GRUB_TERM_KEY_SHIFT_102
};
static grub_usb_device_t usbdev;
@ -157,8 +162,9 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused)
#define GRUB_USB_KEYBOARD_RIGHT_ALT 0x40
/* Check if the Shift key was pressed. */
if (data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT
|| data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT)
if ((data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT
|| data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT)
&& keyboard_map_shift[data[2]])
key = keyboard_map_shift[data[2]];
else
key = keyboard_map[data[2]];