Hook AT keyboard mapping
This commit is contained in:
parent
ed19677fe3
commit
e55e09628d
9 changed files with 290 additions and 173 deletions
|
@ -28,6 +28,115 @@
|
|||
#include <grub/gzio.h>
|
||||
#include <grub/i18n.h>
|
||||
|
||||
static struct grub_keyboard_layout layout_us = {
|
||||
.at = {
|
||||
.keyboard_map = {
|
||||
/* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6',
|
||||
/* 0x08 */ '7', '8', '9', '0',
|
||||
/* 0x0c */ '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB,
|
||||
/* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
||||
/* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's',
|
||||
/* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
|
||||
/* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',
|
||||
/* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*',
|
||||
/* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1,
|
||||
/* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3,
|
||||
/* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5,
|
||||
/* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7,
|
||||
/* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9,
|
||||
/* 0x44 */ GRUB_TERM_KEY_F10, '\0', '\0', GRUB_TERM_KEY_HOME,
|
||||
/* 0x48 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT,
|
||||
/* 0x4c */ GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT,
|
||||
/* 0x4e */ '+', GRUB_TERM_KEY_END,
|
||||
/* 0x50 */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE,
|
||||
/* 0x52 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC,
|
||||
/* 0x54 */ '\0', '\0', '\\', GRUB_TERM_KEY_F11,
|
||||
/* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
/* 0x60 */ '\0', '\0', '\0', '\0',
|
||||
/* 0x64 */ '\0', GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_LEFT,
|
||||
/* 0x68 */ GRUB_TERM_KEY_RIGHT
|
||||
},
|
||||
.keyboard_map_shift = {
|
||||
'\0', '\0', '!', '@', '#', '$', '%', '^',
|
||||
'&', '*', '(', ')', '_', '+', '\0', '\0',
|
||||
'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', '<', '>', '?',
|
||||
[0x56] = '|'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static struct grub_keyboard_layout *grub_current_layout = &layout_us;
|
||||
|
||||
static int
|
||||
map_key_core (int code, int status, int *alt_gr_consumed)
|
||||
{
|
||||
*alt_gr_consumed = 0;
|
||||
|
||||
if (status & GRUB_TERM_STATUS_RALT)
|
||||
{
|
||||
if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT))
|
||||
{
|
||||
if (grub_current_layout->at.keyboard_map_shift_l3[code])
|
||||
{
|
||||
*alt_gr_consumed = 1;
|
||||
return grub_current_layout->at.keyboard_map_shift_l3[code];
|
||||
}
|
||||
else if (grub_current_layout->at.keyboard_map_shift[code])
|
||||
{
|
||||
*alt_gr_consumed = 1;
|
||||
return grub_current_layout->at.keyboard_map_l3[code]
|
||||
| GRUB_TERM_SHIFT;
|
||||
}
|
||||
}
|
||||
else if (grub_current_layout->at.keyboard_map_shift[code])
|
||||
{
|
||||
*alt_gr_consumed = 1;
|
||||
return grub_current_layout->at.keyboard_map_l3[code];
|
||||
}
|
||||
}
|
||||
if (status & (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT))
|
||||
{
|
||||
if (grub_current_layout->at.keyboard_map_shift[code])
|
||||
return grub_current_layout->at.keyboard_map_shift[code];
|
||||
else
|
||||
return grub_current_layout->at.keyboard_map[code] | GRUB_TERM_SHIFT;
|
||||
}
|
||||
else
|
||||
return grub_current_layout->at.keyboard_map[code];
|
||||
}
|
||||
|
||||
unsigned
|
||||
grub_term_map_key (int code, int status)
|
||||
{
|
||||
int alt_gr_consumed;
|
||||
int key;
|
||||
|
||||
key = map_key_core (code, status, &alt_gr_consumed);
|
||||
|
||||
if (key == 0 || key == GRUB_TERM_SHIFT)
|
||||
grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code);
|
||||
|
||||
if (status & GRUB_TERM_STATUS_CAPS)
|
||||
{
|
||||
if ((key >= 'a') && (key <= 'z'))
|
||||
key += 'A' - 'a';
|
||||
else if ((key >= 'A') && (key <= 'Z'))
|
||||
key += 'a' - 'A';
|
||||
}
|
||||
|
||||
if ((status & GRUB_TERM_STATUS_LALT) ||
|
||||
((status & GRUB_TERM_STATUS_RALT) && !alt_gr_consumed))
|
||||
key |= GRUB_TERM_ALT;
|
||||
if (status & (GRUB_TERM_STATUS_LCTRL | GRUB_TERM_STATUS_RCTRL))
|
||||
key |= GRUB_TERM_CTRL;
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
|
@ -110,6 +219,23 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)),
|
|||
newmap->at.keyboard_map_shift_l3[i]
|
||||
= grub_le_to_cpu32(newmap->at.keyboard_map_shift_l3[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map); i++)
|
||||
newmap->usb.keyboard_map[i] = grub_le_to_cpu32(newmap->usb.keyboard_map[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map_shift); i++)
|
||||
newmap->usb.keyboard_map_shift[i]
|
||||
= grub_le_to_cpu32(newmap->usb.keyboard_map_shift[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map_l3); i++)
|
||||
newmap->usb.keyboard_map_l3[i]
|
||||
= grub_le_to_cpu32(newmap->usb.keyboard_map_l3[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (newmap->usb.keyboard_map_shift_l3); i++)
|
||||
newmap->usb.keyboard_map_shift_l3[i]
|
||||
= grub_le_to_cpu32(newmap->usb.keyboard_map_shift_l3[i]);
|
||||
|
||||
grub_current_layout = newmap;
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
|
||||
fail:
|
||||
|
@ -131,6 +257,5 @@ GRUB_MOD_INIT(keylayouts)
|
|||
|
||||
GRUB_MOD_FINI(keylayouts)
|
||||
{
|
||||
grub_current_layout = NULL;
|
||||
grub_unregister_command (cmd);
|
||||
}
|
||||
|
|
|
@ -56,11 +56,11 @@ grub_cmd_keystatus (grub_extcmd_t cmd,
|
|||
int mods;
|
||||
|
||||
if (state[0].set)
|
||||
expect_mods |= GRUB_TERM_STATUS_SHIFT;
|
||||
expect_mods |= (GRUB_TERM_STATUS_LSHIFT | GRUB_TERM_STATUS_RSHIFT);
|
||||
if (state[1].set)
|
||||
expect_mods |= GRUB_TERM_STATUS_CTRL;
|
||||
expect_mods |= (GRUB_TERM_STATUS_LCTRL | GRUB_TERM_STATUS_RCTRL);
|
||||
if (state[2].set)
|
||||
expect_mods |= GRUB_TERM_STATUS_ALT;
|
||||
expect_mods |= (GRUB_TERM_STATUS_LALT | GRUB_TERM_STATUS_RALT);
|
||||
|
||||
grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods);
|
||||
|
||||
|
|
|
@ -21,28 +21,24 @@
|
|||
|
||||
#define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO"
|
||||
#define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE (sizeof(GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1)
|
||||
#define GRUB_KEYBOARD_LAYOUTS_VERSION 4
|
||||
#define GRUB_KEYBOARD_LAYOUTS_VERSION 5
|
||||
|
||||
#define GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE 128
|
||||
|
||||
struct grub_keyboard_layout
|
||||
struct grub_keyboard_layout_kbd
|
||||
{
|
||||
struct
|
||||
{
|
||||
grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE];
|
||||
grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE];
|
||||
grub_uint32_t keyboard_map_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE];
|
||||
grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE];
|
||||
} at;
|
||||
struct
|
||||
{
|
||||
grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE];
|
||||
grub_uint32_t keyboard_map_shift[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE];
|
||||
grub_uint32_t keyboard_map_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE];
|
||||
grub_uint32_t keyboard_map_shift_l3[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE];
|
||||
} usb;
|
||||
};
|
||||
|
||||
struct grub_keyboard_layout *EXPORT_VAR (grub_current_layout);
|
||||
struct grub_keyboard_layout
|
||||
{
|
||||
struct grub_keyboard_layout_kbd at;
|
||||
struct grub_keyboard_layout_kbd usb;
|
||||
};
|
||||
|
||||
unsigned grub_term_map_key (int code, int status);
|
||||
|
||||
#endif /* GRUB_KEYBOARD_LAYOUTS */
|
||||
|
|
|
@ -110,9 +110,15 @@ grub_term_color_state;
|
|||
|
||||
|
||||
/* Bitmasks for modifier keys returned by grub_getkeystatus. */
|
||||
#define GRUB_TERM_STATUS_SHIFT (1 << 0)
|
||||
#define GRUB_TERM_STATUS_CTRL (1 << 1)
|
||||
#define GRUB_TERM_STATUS_ALT (1 << 2)
|
||||
#define GRUB_TERM_STATUS_RSHIFT (1 << 0)
|
||||
#define GRUB_TERM_STATUS_LSHIFT (1 << 1)
|
||||
#define GRUB_TERM_STATUS_RCTRL (1 << 2)
|
||||
#define GRUB_TERM_STATUS_RALT (1 << 3)
|
||||
#define GRUB_TERM_STATUS_SCROLL (1 << 4)
|
||||
#define GRUB_TERM_STATUS_NUM (1 << 5)
|
||||
#define GRUB_TERM_STATUS_CAPS (1 << 6)
|
||||
#define GRUB_TERM_STATUS_LCTRL (1 << 8)
|
||||
#define GRUB_TERM_STATUS_LALT (1 << 9)
|
||||
|
||||
/* Menu-related geometrical constants. */
|
||||
|
||||
|
|
|
@ -22,13 +22,11 @@
|
|||
#include <grub/misc.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/keyboard_layouts.h>
|
||||
|
||||
struct grub_term_output *grub_term_outputs_disabled;
|
||||
struct grub_term_input *grub_term_inputs_disabled;
|
||||
struct grub_term_output *grub_term_outputs;
|
||||
struct grub_term_input *grub_term_inputs;
|
||||
struct grub_keyboard_layout *grub_current_layout;
|
||||
|
||||
/* Put a Unicode character. */
|
||||
static void
|
||||
|
|
|
@ -22,64 +22,18 @@
|
|||
#include <grub/cpu/io.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/keyboard_layouts.h>
|
||||
|
||||
static short at_keyboard_status = 0;
|
||||
static int extended_pending = 0;
|
||||
static int pending_key = -1;
|
||||
|
||||
#define KEYBOARD_STATUS_SHIFT_L (1 << 0)
|
||||
#define KEYBOARD_STATUS_SHIFT_R (1 << 1)
|
||||
#define KEYBOARD_STATUS_ALT_L (1 << 2)
|
||||
#define KEYBOARD_STATUS_ALT_R (1 << 3)
|
||||
#define KEYBOARD_STATUS_CTRL_L (1 << 4)
|
||||
#define KEYBOARD_STATUS_CTRL_R (1 << 5)
|
||||
#define KEYBOARD_STATUS_CAPS_LOCK (1 << 6)
|
||||
#define KEYBOARD_STATUS_NUM_LOCK (1 << 7)
|
||||
#define KEYBOARD_STATUS_EXTENDED (1 << 8)
|
||||
|
||||
static grub_uint8_t led_status;
|
||||
|
||||
#define KEYBOARD_LED_SCROLL (1 << 0)
|
||||
#define KEYBOARD_LED_NUM (1 << 1)
|
||||
#define KEYBOARD_LED_CAPS (1 << 2)
|
||||
|
||||
static const unsigned keyboard_map[128] =
|
||||
{
|
||||
/* 0x00 */ '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6',
|
||||
/* 0x08 */ '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB,
|
||||
/* 0x10 */ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
|
||||
/* 0x18 */ 'o', 'p', '[', ']', '\n', '\0', 'a', 's',
|
||||
/* 0x20 */ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
|
||||
/* 0x28 */ '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',
|
||||
/* 0x30 */ 'b', 'n', 'm', ',', '.', '/', '\0', '*',
|
||||
/* 0x38 */ '\0', ' ', '\0', GRUB_TERM_KEY_F1,
|
||||
/* 0x3c */ GRUB_TERM_KEY_F2, GRUB_TERM_KEY_F3,
|
||||
/* 0x3e */ GRUB_TERM_KEY_F4, GRUB_TERM_KEY_F5,
|
||||
/* 0x40 */ GRUB_TERM_KEY_F6, GRUB_TERM_KEY_F7,
|
||||
/* 0x42 */ GRUB_TERM_KEY_F8, GRUB_TERM_KEY_F9,
|
||||
/* 0x44 */ GRUB_TERM_KEY_F10, '\0', '\0', GRUB_TERM_KEY_HOME,
|
||||
/* 0x48 */ GRUB_TERM_KEY_UP, GRUB_TERM_KEY_NPAGE, '-', GRUB_TERM_KEY_LEFT,
|
||||
/* 0x4c */ GRUB_TERM_KEY_CENTER, GRUB_TERM_KEY_RIGHT, '+', GRUB_TERM_KEY_END,
|
||||
/* 0x50 */ GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_PPAGE,
|
||||
/* 0x52 */ GRUB_TERM_KEY_INSERT, GRUB_TERM_KEY_DC,
|
||||
/* 0x54 */ '\0', '\0', '\\', GRUB_TERM_KEY_F11,
|
||||
/* 0x58 */ GRUB_TERM_KEY_F12, '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
/* 0x60 */ '\0', '\0', '\0', '\0',
|
||||
/* 0x64 */ '\0', GRUB_TERM_KEY_UP, GRUB_TERM_KEY_DOWN, GRUB_TERM_KEY_LEFT,
|
||||
/* 0x68 */ GRUB_TERM_KEY_RIGHT
|
||||
};
|
||||
|
||||
static unsigned keyboard_map_shift[128] =
|
||||
{
|
||||
'\0', '\0', '!', '@', '#', '$', '%', '^',
|
||||
'&', '*', '(', ')', '_', '+', '\0', '\0',
|
||||
'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', '<', '>', '?',
|
||||
[0x56] = '|'
|
||||
};
|
||||
|
||||
static grub_uint8_t grub_keyboard_controller_orig;
|
||||
|
||||
static void
|
||||
|
@ -122,45 +76,41 @@ grub_keyboard_isr (grub_uint8_t key)
|
|||
switch (KEYBOARD_SCANCODE (key))
|
||||
{
|
||||
case SHIFT_L:
|
||||
at_keyboard_status |= KEYBOARD_STATUS_SHIFT_L;
|
||||
at_keyboard_status |= GRUB_TERM_STATUS_LSHIFT;
|
||||
break;
|
||||
case SHIFT_R:
|
||||
at_keyboard_status |= KEYBOARD_STATUS_SHIFT_R;
|
||||
at_keyboard_status |= GRUB_TERM_STATUS_RSHIFT;
|
||||
break;
|
||||
case CTRL:
|
||||
at_keyboard_status |= KEYBOARD_STATUS_CTRL_L;
|
||||
at_keyboard_status |= GRUB_TERM_STATUS_LCTRL;
|
||||
break;
|
||||
case ALT:
|
||||
if (at_keyboard_status & KEYBOARD_STATUS_EXTENDED)
|
||||
at_keyboard_status |= KEYBOARD_STATUS_ALT_R;
|
||||
if (extended_pending)
|
||||
at_keyboard_status |= GRUB_TERM_STATUS_RALT;
|
||||
else
|
||||
at_keyboard_status |= KEYBOARD_STATUS_ALT_L;
|
||||
at_keyboard_status |= GRUB_TERM_STATUS_LALT;
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (KEYBOARD_SCANCODE (key))
|
||||
{
|
||||
case SHIFT_L:
|
||||
at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_L;
|
||||
at_keyboard_status &= ~GRUB_TERM_STATUS_LSHIFT;
|
||||
break;
|
||||
case SHIFT_R:
|
||||
at_keyboard_status &= ~KEYBOARD_STATUS_SHIFT_R;
|
||||
at_keyboard_status &= ~GRUB_TERM_STATUS_RSHIFT;
|
||||
break;
|
||||
case CTRL:
|
||||
at_keyboard_status &= ~KEYBOARD_STATUS_CTRL_L;
|
||||
at_keyboard_status &= ~GRUB_TERM_STATUS_LCTRL;
|
||||
break;
|
||||
case ALT:
|
||||
if (at_keyboard_status & KEYBOARD_STATUS_EXTENDED)
|
||||
at_keyboard_status &= ~KEYBOARD_STATUS_ALT_R;
|
||||
if (extended_pending)
|
||||
at_keyboard_status &= ~GRUB_TERM_STATUS_RALT;
|
||||
else
|
||||
at_keyboard_status &= ~KEYBOARD_STATUS_ALT_L;
|
||||
at_keyboard_status &= ~GRUB_TERM_STATUS_LALT;
|
||||
break;
|
||||
}
|
||||
if (key == 0xe0)
|
||||
at_keyboard_status |= KEYBOARD_STATUS_EXTENDED;
|
||||
else
|
||||
at_keyboard_status &= ~KEYBOARD_STATUS_EXTENDED;
|
||||
|
||||
extended_pending = (key == 0xe0);
|
||||
}
|
||||
|
||||
/* If there is a raw key pending, return it; otherwise return -1. */
|
||||
|
@ -177,11 +127,12 @@ grub_keyboard_getkey (void)
|
|||
return (KEYBOARD_SCANCODE (key));
|
||||
}
|
||||
|
||||
|
||||
/* If there is a character pending, return it; otherwise return -1. */
|
||||
static int
|
||||
grub_at_keyboard_getkey_noblock (void)
|
||||
{
|
||||
int code, key;
|
||||
int code;
|
||||
code = grub_keyboard_getkey ();
|
||||
if (code == -1)
|
||||
return -1;
|
||||
|
@ -194,66 +145,34 @@ grub_at_keyboard_getkey_noblock (void)
|
|||
/* Caps lock sends scan code twice. Get the second one and discard it. */
|
||||
while (grub_keyboard_getkey () == -1);
|
||||
|
||||
at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK;
|
||||
at_keyboard_status ^= GRUB_TERM_STATUS_CAPS;
|
||||
led_status ^= KEYBOARD_LED_CAPS;
|
||||
keyboard_controller_led (led_status);
|
||||
|
||||
#ifdef DEBUG_AT_KEYBOARD
|
||||
grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK));
|
||||
#endif
|
||||
key = -1;
|
||||
break;
|
||||
return -1;
|
||||
case NUM_LOCK:
|
||||
/* Num lock sends scan code twice. Get the second one and discard it. */
|
||||
while (grub_keyboard_getkey () == -1);
|
||||
|
||||
at_keyboard_status ^= KEYBOARD_STATUS_NUM_LOCK;
|
||||
at_keyboard_status ^= GRUB_TERM_STATUS_NUM;
|
||||
led_status ^= KEYBOARD_LED_NUM;
|
||||
keyboard_controller_led (led_status);
|
||||
|
||||
#ifdef DEBUG_AT_KEYBOARD
|
||||
grub_dprintf ("atkeyb", "num_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_NUM_LOCK));
|
||||
#endif
|
||||
key = -1;
|
||||
break;
|
||||
return -1;
|
||||
case SCROLL_LOCK:
|
||||
/* For scroll lock we don't keep track of status. Only update its led. */
|
||||
at_keyboard_status ^= GRUB_TERM_STATUS_SCROLL;
|
||||
led_status ^= KEYBOARD_LED_SCROLL;
|
||||
keyboard_controller_led (led_status);
|
||||
key = -1;
|
||||
break;
|
||||
return -1;
|
||||
default:
|
||||
if (at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L
|
||||
| KEYBOARD_STATUS_SHIFT_R))
|
||||
{
|
||||
if (keyboard_map_shift[code])
|
||||
key = keyboard_map_shift[code];
|
||||
else
|
||||
key = keyboard_map[code] | GRUB_TERM_SHIFT;
|
||||
return grub_term_map_key (code, at_keyboard_status);
|
||||
}
|
||||
else
|
||||
key = keyboard_map[code];
|
||||
|
||||
if (key == 0)
|
||||
grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code);
|
||||
|
||||
if (at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK)
|
||||
{
|
||||
if ((key >= 'a') && (key <= 'z'))
|
||||
key += 'A' - 'a';
|
||||
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;
|
||||
if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L
|
||||
| KEYBOARD_STATUS_CTRL_R))
|
||||
key |= GRUB_TERM_CTRL;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -24,25 +24,11 @@
|
|||
static const struct grub_machine_bios_data_area *bios_data_area =
|
||||
(struct grub_machine_bios_data_area *) GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
|
||||
|
||||
#define KEYBOARD_LEFT_SHIFT (1 << 0)
|
||||
#define KEYBOARD_RIGHT_SHIFT (1 << 1)
|
||||
#define KEYBOARD_CTRL (1 << 2)
|
||||
#define KEYBOARD_ALT (1 << 3)
|
||||
|
||||
static int
|
||||
grub_console_getkeystatus (struct grub_term_input *term __attribute__ ((unused)))
|
||||
{
|
||||
grub_uint8_t status = bios_data_area->keyboard_flag_lower;
|
||||
int mods = 0;
|
||||
|
||||
if (status & (KEYBOARD_LEFT_SHIFT | KEYBOARD_RIGHT_SHIFT))
|
||||
mods |= GRUB_TERM_STATUS_SHIFT;
|
||||
if (status & KEYBOARD_CTRL)
|
||||
mods |= GRUB_TERM_STATUS_CTRL;
|
||||
if (status & KEYBOARD_ALT)
|
||||
mods |= GRUB_TERM_STATUS_ALT;
|
||||
|
||||
return mods;
|
||||
/* conveniently GRUB keystatus is modelled after BIOS one. */
|
||||
return bios_data_area->keyboard_flag_lower & ~0x80;
|
||||
}
|
||||
|
||||
static struct grub_term_input grub_console_term_input =
|
||||
|
|
|
@ -323,12 +323,18 @@ grub_usb_keyboard_getkeystatus (struct grub_term_input *term __attribute__ ((unu
|
|||
data[4], data[5], data[6], data[7]);
|
||||
|
||||
/* Check Shift, Control, and Alt status. */
|
||||
if (data[0] & 0x02 || data[0] & 0x20)
|
||||
mods |= GRUB_TERM_STATUS_SHIFT;
|
||||
if (data[0] & 0x01 || data[0] & 0x10)
|
||||
mods |= GRUB_TERM_STATUS_CTRL;
|
||||
if (data[0] & 0x04 || data[0] & 0x40)
|
||||
mods |= GRUB_TERM_STATUS_ALT;
|
||||
if (data[0] & GRUB_USB_KEYBOARD_LEFT_SHIFT)
|
||||
mods |= GRUB_TERM_STATUS_LSHIFT;
|
||||
if (data[0] & GRUB_USB_KEYBOARD_RIGHT_SHIFT)
|
||||
mods |= GRUB_TERM_STATUS_RSHIFT;
|
||||
if (data[0] & GRUB_USB_KEYBOARD_LEFT_CTRL)
|
||||
mods |= GRUB_TERM_STATUS_LCTRL;
|
||||
if (data[0] & GRUB_USB_KEYBOARD_RIGHT_CTRL)
|
||||
mods |= GRUB_TERM_STATUS_RCTRL;
|
||||
if (data[0] & GRUB_USB_KEYBOARD_LEFT_ALT)
|
||||
mods |= GRUB_TERM_STATUS_LALT;
|
||||
if (data[0] & GRUB_USB_KEYBOARD_RIGHT_ALT)
|
||||
mods |= GRUB_TERM_STATUS_RALT;
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
|
|
|
@ -46,6 +46,26 @@ struct console_grub_equivalence
|
|||
grub_uint32_t grub;
|
||||
};
|
||||
|
||||
static int at_to_usb_map[128] =
|
||||
{
|
||||
0, 41, 30, 31, 32, 33, 34, 35,
|
||||
36, 37, 38, 39, 45, 46, 42, 43,
|
||||
20, 26, 8, 21, 23, 28, 24, 12,
|
||||
18, 19, 47, 48, 40, 0, 4, 22,
|
||||
7, 9, 10, 11, 13, 14, 15, 51,
|
||||
52, 53, 0, 49, 29, 27, 6, 25,
|
||||
5, 17, 16, 54, 55, 56, 0, 0,
|
||||
0, 44, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 74,
|
||||
82, 78, 45, 80, 0, 79, 0, 77,
|
||||
81, 75, 0, 76, 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, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static struct console_grub_equivalence console_grub_equivalences[] = {
|
||||
{"KP_1", '1'},
|
||||
{"KP_2", '2'},
|
||||
|
@ -85,7 +105,26 @@ Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT);
|
|||
exit (status);
|
||||
}
|
||||
|
||||
char
|
||||
void
|
||||
add_special_keys (struct grub_keyboard_layout *layout)
|
||||
{
|
||||
layout->at.keyboard_map[71] = GRUB_TERM_KEY_HOME;
|
||||
layout->at.keyboard_map[72] = GRUB_TERM_KEY_UP;
|
||||
layout->at.keyboard_map[73] = GRUB_TERM_KEY_NPAGE;
|
||||
layout->at.keyboard_map[75] = GRUB_TERM_KEY_LEFT;
|
||||
layout->at.keyboard_map[77] = GRUB_TERM_KEY_RIGHT;
|
||||
layout->at.keyboard_map[79] = GRUB_TERM_KEY_END;
|
||||
layout->at.keyboard_map[80] = GRUB_TERM_KEY_DOWN;
|
||||
layout->at.keyboard_map[81] = GRUB_TERM_KEY_PPAGE;
|
||||
layout->at.keyboard_map[83] = GRUB_TERM_KEY_DC;
|
||||
|
||||
layout->at.keyboard_map[101] = GRUB_TERM_KEY_UP;
|
||||
layout->at.keyboard_map[102] = GRUB_TERM_KEY_DOWN;
|
||||
layout->at.keyboard_map[103] = GRUB_TERM_KEY_LEFT;
|
||||
layout->at.keyboard_map[104] = GRUB_TERM_KEY_RIGHT;
|
||||
}
|
||||
|
||||
static char
|
||||
lookup (char *code)
|
||||
{
|
||||
int i;
|
||||
|
@ -97,7 +136,7 @@ lookup (char *code)
|
|||
return '\0';
|
||||
}
|
||||
|
||||
unsigned int
|
||||
static unsigned int
|
||||
get_grub_code (char *layout_code)
|
||||
{
|
||||
unsigned int code;
|
||||
|
@ -111,9 +150,8 @@ get_grub_code (char *layout_code)
|
|||
return code;
|
||||
}
|
||||
|
||||
void
|
||||
write_file (char* filename, grub_uint32_t *keyboard_map,
|
||||
grub_uint32_t *keyboard_map_alt)
|
||||
static void
|
||||
write_file (char* filename, struct grub_keyboard_layout *layout)
|
||||
{
|
||||
FILE *fp_output;
|
||||
grub_uint32_t version;
|
||||
|
@ -121,11 +159,35 @@ write_file (char* filename, grub_uint32_t *keyboard_map,
|
|||
|
||||
version = grub_cpu_to_le32 (GRUB_KEYBOARD_LAYOUTS_VERSION);
|
||||
|
||||
for (i = 0; i < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE; i++)
|
||||
keyboard_map[i] = grub_cpu_to_le32 (keyboard_map[i]);
|
||||
for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map); i++)
|
||||
layout->at.keyboard_map[i] = grub_cpu_to_le32(layout->at.keyboard_map[i]);
|
||||
|
||||
for (i = 0; i < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE; i++)
|
||||
keyboard_map_alt[i] = grub_cpu_to_le32 (keyboard_map_alt[i]);
|
||||
for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map_shift); i++)
|
||||
layout->at.keyboard_map_shift[i]
|
||||
= grub_cpu_to_le32(layout->at.keyboard_map_shift[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map_l3); i++)
|
||||
layout->at.keyboard_map_l3[i]
|
||||
= grub_cpu_to_le32(layout->at.keyboard_map_l3[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (layout->at.keyboard_map_shift_l3); i++)
|
||||
layout->at.keyboard_map_shift_l3[i]
|
||||
= grub_cpu_to_le32(layout->at.keyboard_map_shift_l3[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map); i++)
|
||||
layout->usb.keyboard_map[i] = grub_cpu_to_le32(layout->usb.keyboard_map[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map_shift); i++)
|
||||
layout->usb.keyboard_map_shift[i]
|
||||
= grub_cpu_to_le32(layout->usb.keyboard_map_shift[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map_l3); i++)
|
||||
layout->usb.keyboard_map_l3[i]
|
||||
= grub_cpu_to_le32(layout->usb.keyboard_map_l3[i]);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (layout->usb.keyboard_map_shift_l3); i++)
|
||||
layout->usb.keyboard_map_shift_l3[i]
|
||||
= grub_cpu_to_le32(layout->usb.keyboard_map_shift_l3[i]);
|
||||
|
||||
fp_output = fopen (filename, "w");
|
||||
|
||||
|
@ -138,23 +200,19 @@ write_file (char* filename, grub_uint32_t *keyboard_map,
|
|||
fwrite (GRUB_KEYBOARD_LAYOUTS_FILEMAGIC, 1,
|
||||
GRUB_KEYBOARD_LAYOUTS_FILEMAGIC_SIZE, fp_output);
|
||||
fwrite (&version, sizeof (version), 1, fp_output);
|
||||
fwrite (keyboard_map, sizeof (keyboard_map[0]),
|
||||
GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE, fp_output);
|
||||
fwrite (keyboard_map_alt, sizeof (keyboard_map_alt[0]),
|
||||
GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE, fp_output);
|
||||
fwrite (layout, 1, sizeof (*layout), fp_output);
|
||||
fclose (fp_output);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
write_keymaps (char *keymap, char *file_basename)
|
||||
{
|
||||
grub_uint32_t keyboard_map[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE];
|
||||
grub_uint32_t keyboard_map_alt[GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE];
|
||||
|
||||
struct grub_keyboard_layout layout;
|
||||
char line[2048];
|
||||
pid_t pid;
|
||||
int pipe_communication[2];
|
||||
int ok;
|
||||
unsigned i;
|
||||
|
||||
FILE *fp_pipe;
|
||||
|
||||
|
@ -182,7 +240,7 @@ write_keymaps (char *keymap, char *file_basename)
|
|||
close (pipe_communication[1]);
|
||||
fp_pipe = fdopen (pipe_communication[0], "r");
|
||||
|
||||
memset (keyboard_map, 0, sizeof (keyboard_map));
|
||||
memset (&layout, 0, sizeof (layout));
|
||||
|
||||
/* Process the ckbcomp output and prepare the layouts. */
|
||||
ok = 0;
|
||||
|
@ -198,8 +256,29 @@ write_keymaps (char *keymap, char *file_basename)
|
|||
|
||||
sscanf (line, "keycode %u = %60s %60s %60s %60s", &keycode,
|
||||
normal, shift, normalalt, shiftalt);
|
||||
if (keycode < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE)
|
||||
{
|
||||
layout.at.keyboard_map[keycode] = get_grub_code (normal);
|
||||
layout.at.keyboard_map_shift[keycode] = get_grub_code (shift);
|
||||
layout.at.keyboard_map_l3[keycode] = get_grub_code (normalalt);
|
||||
layout.at.keyboard_map_shift_l3[keycode]
|
||||
= get_grub_code (shiftalt);
|
||||
ok = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < GRUB_KEYBOARD_LAYOUTS_ARRAY_SIZE; i++)
|
||||
{
|
||||
layout.usb.keyboard_map[at_to_usb_map[i]] = layout.at.keyboard_map[i];
|
||||
layout.usb.keyboard_map_shift[at_to_usb_map[i]]
|
||||
= layout.at.keyboard_map_shift[i];
|
||||
layout.usb.keyboard_map_l3[at_to_usb_map[i]]
|
||||
= layout.at.keyboard_map_l3[i];
|
||||
layout.usb.keyboard_map_shift_l3[at_to_usb_map[i]]
|
||||
= layout.at.keyboard_map_shift_l3[i];
|
||||
}
|
||||
|
||||
|
||||
if (ok == 0)
|
||||
{
|
||||
|
@ -208,7 +287,9 @@ write_keymaps (char *keymap, char *file_basename)
|
|||
exit (1);
|
||||
}
|
||||
|
||||
write_file (file_basename, keyboard_map, keyboard_map_alt);
|
||||
add_special_keys (&layout);
|
||||
|
||||
write_file (file_basename, &layout);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Loading…
Reference in a new issue