Hi, I've done a test, mainly to get more feedback from you.
Find it attached. What it does: a) It defines a new Kernel symbol to be used from at_keyboard.c and from the new module keyboard_layouts. b) When the new module "wants" it changes the active keyboard_layouts. Big question: * How to deal with USB keyboards? One option would be to add a middle layer who receive some Grub key code and layouts are based on this level. I have not looked into it yet (doing some tests I renamed somethiing in the USB module, this is just a test to avoid some clashes before) If the proof of concept approach is the correct one I would define and export a structure who would have the keymap and keymap_shift, instead of having to export one variable per thing. Plus will be more scalable for dead keys. When this looks fine, my idea is to use the output of ckbcomp to prepare the files that will be in /boot/grub/layouts and that Grub (the new module) will read easily. Something like grub-mklayouts. I will think and implement other fancy things that we would need, like changing between keyboards easily. I just want to go step by step and maybe have something for trunk soon. Now (only for some time) and tomorrow I'll be on the IRC, so feel free to comment here (better for archiving) or there (better for questions and answers). Thanks, -- Carles Pina i Estany http://pinux.info
=== modified file 'conf/common.rmk' --- conf/common.rmk 2010-01-14 14:04:44 +0000 +++ conf/common.rmk 2010-01-17 01:12:20 +0000 @@ -647,6 +647,12 @@ gettext_mod_SOURCES = gettext/gettext.c gettext_mod_CFLAGS = $(COMMON_CFLAGS) gettext_mod_LDFLAGS = $(COMMON_LDFLAGS) +# For keyboard_layouts.mod +pkglib_MODULES += keyboard_layouts.mod +keyboard_layouts_mod_SOURCES = keyboard_layouts/keyboard_layouts.c +keyboard_layouts_mod_CFLAGS = $(COMMON_CFLAGS) +keyboard_layouts_mod_LDFLAGS = $(COMMON_LDFLAGS) + # Misc. pkglib_MODULES += xnu_uuid.mod === modified file 'include/grub/term.h' --- include/grub/term.h 2010-01-09 22:42:17 +0000 +++ include/grub/term.h 2010-01-17 01:16:32 +0000 @@ -197,6 +197,7 @@ extern struct grub_term_output *EXPORT_V extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled); extern struct grub_term_output *EXPORT_VAR(grub_term_outputs); extern struct grub_term_input *EXPORT_VAR(grub_term_inputs); +extern char *EXPORT_VAR(grub_keyboard_map); static inline void grub_term_register_input (const char *name __attribute__ ((unused)), === modified file 'kern/term.c' --- kern/term.c 2009-12-27 21:35:40 +0000 +++ kern/term.c 2010-01-17 01:17:34 +0000 @@ -30,6 +30,8 @@ struct grub_term_input *grub_term_inputs void (*grub_newline_hook) (void) = NULL; +char* grub_keyboard_map = NULL; + /* Put a Unicode character. */ void grub_putcode (grub_uint32_t code, struct grub_term_output *term) === added directory 'keyboard_layouts' === added file 'keyboard_layouts/keyboard_layouts.c' --- keyboard_layouts/keyboard_layouts.c 1970-01-01 00:00:00 +0000 +++ keyboard_layouts/keyboard_layouts.c 2010-01-17 01:12:31 +0000 @@ -0,0 +1,36 @@ +#include <grub/types.h> +#include <grub/misc.h> +#include <grub/mm.h> +#include <grub/err.h> +#include <grub/dl.h> +#include <grub/normal.h> +#include <grub/file.h> +#include <grub/kernel.h> +#include <grub/i18n.h> + +#include <grub/term.h> + +static grub_err_t +grub_cmd_load_keyboardlayout (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "usage: load_keyboard layout"); + + grub_printf ("Load layout %s", args[0]); + + grub_keyboard_map [2] = 'X'; /* '1' is 'X'. */ + return 0; +} + +GRUB_MOD_INIT (keyboard_layouts) +{ + grub_register_command_p1 ("load_keyboard", grub_cmd_load_keyboardlayout, + N_("layout"), + N_("Set ups the new layout.")); +} + +GRUB_MOD_FINI (keyboard_layouts) +{ + /* TODO: Restore the default layout. */ +} === modified file 'term/i386/pc/at_keyboard.c' --- term/i386/pc/at_keyboard.c 2010-01-09 22:42:17 +0000 +++ term/i386/pc/at_keyboard.c 2010-01-17 00:59:51 +0000 @@ -22,6 +22,7 @@ #include <grub/i386/io.h> #include <grub/misc.h> #include <grub/term.h> +#include <grub/mm.h> static short at_keyboard_status = 0; @@ -40,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 char keyboard_map_default[128] = { '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB, @@ -213,12 +214,12 @@ grub_at_keyboard_getkey_noblock (void) break; default: if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R)) - key = keyboard_map[code] - 'a' + 1; + key = grub_keyboard_map[code] - 'a' + 1; else if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L | KEYBOARD_STATUS_SHIFT_R)) && keyboard_map_shift[code]) key = keyboard_map_shift[code]; else - key = keyboard_map[code]; + key = grub_keyboard_map[code]; if (key == 0) grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code); @@ -279,6 +280,8 @@ static struct grub_term_input grub_at_ke GRUB_MOD_INIT(at_keyboard) { grub_term_register_input ("at_keyboard", &grub_at_keyboard_term); + + grub_keyboard_map = keyboard_map_default; } GRUB_MOD_FINI(at_keyboard) === modified file 'term/usb_keyboard.c' --- term/usb_keyboard.c 2009-11-23 15:31:54 +0000 +++ term/usb_keyboard.c 2010-01-16 21:15:46 +0000 @@ -28,7 +28,7 @@ #include <grub/time.h> -static char keyboard_map[128] = +static char keyboard_map_usb[128] = { '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', @@ -152,11 +152,11 @@ grub_usb_keyboard_checkkey (void) /* Check if the Control or Shift key was pressed. */ if (data[0] & 0x01 || data[0] & 0x10) - key = keyboard_map[data[2]] - 'a' + 1; + key = keyboard_map_usb[data[2]] - 'a' + 1; else if (data[0] & 0x02 || data[0] & 0x20) key = keyboard_map_shift[data[2]]; else - key = keyboard_map[data[2]]; + key = keyboard_map_usb[data[2]]; if (key == 0) grub_printf ("Unknown key 0x%x detected\n", data[2]);
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel