Hi there,
I've been trying to set up my grub for my Dvorak keyboard. It seems
that everywhere I look points to something like:
insmod keylayouts
keymap /boot/grub/bepo.gkb
In practice however, this does NOT work at all.
After some debugging, here's what I've found:
- grub-core/commands/keylayouts.c has grub_term_map_key() which does
the actual mapping.
- This function is only referred by
- grub-core/term/at_keyboard.c (via ps2.c)
- grub-core/term/usb_keyboard.c
In my case, at GRUB command prompt, terminal_input tells:
- Current terminal is console.
- Neither at_keyboard nor usb_keyboard are available.
So no wonder the keymap does not work...
I drafted the attached patch to grub-core/term/efi/console.c and
grub-core/i386/pc/console.c, which should make use of
grub_term_map_key() and fix the problem. I unfortunately can't test it
because of this Ubuntu build issue
https://bugs.launchpad.net/ubuntu/+source/grub2/+bug/1914953/comments/7
... separate issue though.
Anyhow, any advice on whether this patch would / would not work?
It seems reasonable to me that keyboard mapping should happen at
grub-core/kern/term.c at grub_getkey_noblock() instead though, as
fixing it there (immediately after term->getkey (term) call), in
theory, would fix things for all cases.
WDYT?
Thanks.
Fabio Pugliese Ornellas
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 715994872..e24603c32 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -205,6 +205,7 @@ kernel = {
efi = kern/efi/init.c;
efi = kern/efi/mm.c;
efi = term/efi/console.c;
+ efi = commands/keylayouts.c;
efi = kern/acpi.c;
efi = kern/efi/acpi.c;
efi = kern/efi/sb.c;
@@ -269,6 +270,7 @@ kernel = {
i386_pc = kern/i386/pc/init.c;
i386_pc = kern/i386/pc/mmap.c;
i386_pc = term/i386/pc/console.c;
+ i386_pc = commands/keylayouts.c;
i386_qemu = bus/pci.c;
i386_qemu = kern/vga_init.c;
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
index a3622e4fe..37d5a971b 100644
--- a/grub-core/term/efi/console.c
+++ b/grub-core/term/efi/console.c
@@ -23,6 +23,7 @@
#include <grub/efi/efi.h>
#include <grub/efi/api.h>
#include <grub/efi/console.h>
+#include <grub/keyboard_layouts.h>
typedef enum {
GRUB_TEXT_MODE_UNDEFINED = -1,
@@ -374,13 +375,25 @@ grub_efi_console_input_init (struct grub_term_input *term)
static int
grub_console_getkey (struct grub_term_input *term)
{
+ int key;
+ int status = 0;
+
if (grub_efi_is_finished)
return 0;
if (term->data)
- return grub_console_getkey_ex(term);
+ key = grub_console_getkey_ex(term);
else
- return grub_console_getkey_con(term);
+ key = grub_console_getkey_con(term);
+
+ if (key & GRUB_TERM_SHIFT)
+ status |= GRUB_TERM_STATUS_RSHIFT;
+ if (key & GRUB_TERM_ALT)
+ status |= GRUB_TERM_STATUS_RALT;
+ if (key & GRUB_TERM_CTRL)
+ status |= GRUB_TERM_STATUS_RCTRL
+
+ return grub_term_map_key(key & GRUB_TERM_KEY_MASK, status);
}
static struct grub_term_coordinate
diff --git a/grub-core/term/i386/pc/console.c b/grub-core/term/i386/pc/console.c
index 9403390f1..b7b3bfc12 100644
--- a/grub-core/term/i386/pc/console.c
+++ b/grub-core/term/i386/pc/console.c
@@ -21,6 +21,7 @@
#include <grub/term.h>
#include <grub/types.h>
#include <grub/machine/int.h>
+#include <grub/keyboard_layouts.h>
static grub_uint8_t grub_console_cur_color = 0x7;
@@ -183,6 +184,21 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
grub_bios_interrupt (0x10, ®s);
}
+static int
+map_key (int key)
+{
+ int status = 0;
+
+ if (key & GRUB_TERM_SHIFT)
+ status |= GRUB_TERM_STATUS_RSHIFT;
+ if (key & GRUB_TERM_ALT)
+ status |= GRUB_TERM_STATUS_RALT;
+ if (key & GRUB_TERM_CTRL)
+ status |= GRUB_TERM_STATUS_RCTRL;
+
+ return grub_term_map_key(key & GRUB_TERM_KEY_MASK, status);
+}
+
/*
* if there is a character pending, return it; otherwise return -1
* BIOS call "INT 16H Function 01H" to check whether a character is pending
@@ -226,16 +242,16 @@ grub_console_getkey (struct grub_term_input *term __attribute__ ((unused)))
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
grub_bios_interrupt (0x16, ®s);
if (!(regs.eax & 0xff))
- return ((regs.eax >> 8) & 0xff) | GRUB_TERM_EXTENDED;
+ return map_key (((regs.eax >> 8) & 0xff) | GRUB_TERM_EXTENDED);
if ((regs.eax & 0xff) >= ' ')
- return regs.eax & 0xff;
+ return map_key (regs.eax & 0xff);
for (i = 0; i < ARRAY_SIZE (bypass_table); i++)
if (bypass_table[i] == (regs.eax & 0xffff))
- return regs.eax & 0xff;
+ return map_key (regs.eax & 0xff);
- return (regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL);
+ return map_key ((regs.eax & 0xff) + (('a' - 1) | GRUB_TERM_CTRL));
}
static int
_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel