=== added file 'ChangeLog.keyboard_layouts'
--- ChangeLog.keyboard_layouts 1970-01-01 00:00:00 +0000
+++ ChangeLog.keyboard_layouts 2010-01-18 21:27:43 +0000
@@ -0,0 +1,22 @@
+2010-01-18 Carles Pina i Estany
+
+ Adds keyboard layouts support.
+
+ * conf/common.rmk (bin_UTILITIES): Add grub-mklayouts rules.
+ (pkglib_MODULES): Add module `keyboard_layouts.mod'.
+ * include/grub/keyboard_layouts.h: New file.
+ * include/grub/term.h: New struct `grub_keyboard_map_s'. New
+ EXPORTED_VAR `grub_keyboard_map'. Move GRUB_TERM_* keys definitions
+ to...
+ * include/grub/keys.h: ... here. New file.
+ * kern/term.c (grub_keyboard_map): Initialise to NULL.
+ * keyboard_layouts/keyboard_layouts.c: New file.
+ * term/i386/pc/at_keyboard.c: Include `'.
+ (keyboard_map_normal): Renamed from `keyboard_map'.
+ (grub_at_keyboard_getkey_noblock): Use `grub_keyboard_map' instead of
+ `keyboard_map' and `keyboard_map_shift'.
+ (grub_term_input): Initialise `grub_keyboard_map->normal' and
+ `grub_keyboard_map->shift'.
+ * util/grub-mklayouts.c: New file.
+ * util/grub-mkconfig.in: New variable `GRUB_KEYBOARD_LAYOUT'.
+ * util/grub.d/00_header.in: Set up layout configuration.
=== modified file 'conf/common.rmk'
--- conf/common.rmk 2010-01-14 14:04:44 +0000
+++ conf/common.rmk 2010-01-17 14:35:00 +0000
@@ -88,6 +88,10 @@ endif
bin_UTILITIES += grub-mkrelpath
grub_mkrelpath_SOURCES = gnulib/progname.c util/grub-mkrelpath.c util/misc.c
+# For grub-mklayouts.
+bin_UTILITIES += grub-mklayouts
+grub_mklayouts_SOURCES = gnulib/progname.c util/grub-mklayouts.c util/misc.c
+
# For the parser.
grub_script.tab.c grub_script.tab.h: script/parser.y
$(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y
@@ -647,6 +651,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
=== added file 'include/grub/keyboard_layouts.h'
--- include/grub/keyboard_layouts.h 1970-01-01 00:00:00 +0000
+++ include/grub/keyboard_layouts.h 2010-01-18 22:13:06 +0000
@@ -0,0 +1,25 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2010 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 .
+ */
+
+#ifndef GRUB_KEYBOARD_LAYOUTS_H
+#define GRUB_KEYBOARD_LAYOUTS_H 1
+
+#define GRUB_KEYBOARD_LAYOUTS_FILEMAGIC "GRUBLAYO"
+#define GRUB_KEYBOARD_LAYOUTS_VERSION 1
+
+#endif /* GRUB_USB_H */
=== added file 'include/grub/keys.h'
--- include/grub/keys.h 1970-01-01 00:00:00 +0000
+++ include/grub/keys.h 2010-01-17 18:21:42 +0000
@@ -0,0 +1,36 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2010 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 .
+ */
+
+#ifndef GRUB_KEYS_HEADER
+#define GRUB_KEYS_HEADER 1
+
+/* Internal codes used by GRUB to represent terminal input. */
+#define GRUB_TERM_LEFT 2
+#define GRUB_TERM_RIGHT 6
+#define GRUB_TERM_UP 16
+#define GRUB_TERM_DOWN 14
+#define GRUB_TERM_HOME 1
+#define GRUB_TERM_END 5
+#define GRUB_TERM_DC 4
+#define GRUB_TERM_PPAGE 7
+#define GRUB_TERM_NPAGE 3
+#define GRUB_TERM_ESC '\e'
+#define GRUB_TERM_TAB '\t'
+#define GRUB_TERM_BACKSPACE 8
+
+#endif /* ! GRUB_KEYS_HEADER */
=== modified file 'include/grub/term.h'
--- include/grub/term.h 2010-01-09 22:42:17 +0000
+++ include/grub/term.h 2010-01-17 22:25:58 +0000
@@ -19,19 +19,7 @@
#ifndef GRUB_TERM_HEADER
#define GRUB_TERM_HEADER 1
-/* Internal codes used by GRUB to represent terminal input. */
-#define GRUB_TERM_LEFT 2
-#define GRUB_TERM_RIGHT 6
-#define GRUB_TERM_UP 16
-#define GRUB_TERM_DOWN 14
-#define GRUB_TERM_HOME 1
-#define GRUB_TERM_END 5
-#define GRUB_TERM_DC 4
-#define GRUB_TERM_PPAGE 7
-#define GRUB_TERM_NPAGE 3
-#define GRUB_TERM_ESC '\e'
-#define GRUB_TERM_TAB '\t'
-#define GRUB_TERM_BACKSPACE 8
+#include
#ifndef ASM_FILE
@@ -198,6 +186,14 @@ extern struct grub_term_input *EXPORT_VA
extern struct grub_term_output *EXPORT_VAR(grub_term_outputs);
extern struct grub_term_input *EXPORT_VAR(grub_term_inputs);
+struct grub_keyboard_map_s
+{
+ char *normal;
+ char *shift;
+};
+
+extern struct grub_keyboard_map_s *EXPORT_VAR(grub_keyboard_map);
+
static inline void
grub_term_register_input (const char *name __attribute__ ((unused)),
grub_term_input_t term)
=== modified file 'kern/term.c'
--- kern/term.c 2009-12-27 21:35:40 +0000
+++ kern/term.c 2010-01-17 21:52:16 +0000
@@ -30,6 +30,8 @@ struct grub_term_input *grub_term_inputs
void (*grub_newline_hook) (void) = NULL;
+struct grub_keyboard_map_s *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-18 22:47:22 +0000
@@ -0,0 +1,186 @@
+/* keyboard_layouts.c - keyboard_layouts module */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2010 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 .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+static char original_keyboard_layout_normal[128];
+static char original_keyboard_layout_shift[128];
+
+static char *active_layout;
+
+static grub_err_t
+grub_cmd_load_layout(grub_command_t cmd __attribute__ ((unused)),
+ int argc, char **args)
+{
+ char magic[8];
+ int check;
+ char *filename;
+ char *prefix;
+
+ if (argc != 1)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "usage: load_layout LAYOUT");
+
+ prefix = grub_env_get ("keymaps_dir");
+ if (!prefix)
+ return grub_error (GRUB_ERR_READ_ERROR,
+ "`keymaps_dir' variable not set up");
+
+ filename =
+ grub_malloc (grub_strlen (prefix) + grub_strlen ("/") +
+ grub_strlen (args[0]) + 1);
+ grub_sprintf (filename, "%s/%s", prefix, args[0]);
+
+ grub_file_t keyboard_file;
+ keyboard_file = grub_file_open (filename);
+
+ if (!keyboard_file)
+ {
+ return grub_error (GRUB_ERR_READ_ERROR, "cannot open file `%s'",
+ filename);
+ return 0;
+ }
+
+ check =
+ grub_file_read (keyboard_file, magic,
+ sizeof (GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1);
+
+ if (check != sizeof (GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1)
+ {
+ return grub_error (GRUB_ERR_READ_ERROR,
+ "cannot read the file header from `%s'", filename);
+ }
+
+ if (grub_memcmp
+ (magic, GRUB_KEYBOARD_LAYOUTS_FILEMAGIC,
+ sizeof (GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1) != 0)
+ {
+ grub_file_close (keyboard_file);
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "file not recognised (`%s')",
+ filename);
+ }
+ grub_uint32_t version;
+ check = grub_file_read (keyboard_file, &version, 4);
+
+ if (check != 4)
+ {
+ grub_file_close (keyboard_file);
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "cannot check file version (`%s')", filename);
+ }
+
+ version = grub_be_to_cpu32 (version);
+ if (version != GRUB_KEYBOARD_LAYOUTS_VERSION)
+ {
+ grub_file_close (keyboard_file);
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "invalid file version: %d (`%s')", version,
+ filename);
+ }
+
+
+
+ check = grub_file_read (keyboard_file, grub_keyboard_map->normal, 128);
+ if (check != 128)
+ {
+ grub_file_close (keyboard_file);
+ return grub_error (GRUB_ERR_READ_ERROR,
+ "problem reading normal keyboard from `%s'",
+ filename);
+ }
+
+ check = grub_file_read (keyboard_file, grub_keyboard_map->shift, 128);
+ if (check != 128)
+ {
+ grub_file_close (keyboard_file);
+ return grub_error (GRUB_ERR_READ_ERROR,
+ "problem reading shift keyboard from `%s'",
+ filename);
+ }
+
+ grub_free (active_layout);
+ active_layout = grub_strdup (args[0]);
+
+ grub_file_close (keyboard_file);
+ return 0;
+}
+
+static grub_err_t
+grub_cmd_show_active_keyboardlayout (grub_command_t cmd
+ __attribute__ ((unused)), int argc
+ __attribute__ ((unused)), char **args
+ __attribute__ ((unused)))
+{
+ grub_printf ("Active layout: `%s'.\n", active_layout);
+ return 0;
+}
+
+static void
+set_default_keyboard(void)
+{
+ grub_free (active_layout);
+ active_layout = grub_strdup("default");
+ grub_memcpy (grub_keyboard_map->normal, original_keyboard_layout_normal,
+ 128);
+ grub_memcpy (grub_keyboard_map->shift, original_keyboard_layout_shift, 128);
+}
+
+static grub_err_t
+grub_cmd_set_default_keyboard (grub_command_t cmd __attribute__ ((unused)), int argc __attribute__ ((unused)), char **args __attribute__ ((unused)))
+{
+ set_default_keyboard();
+ grub_printf_ (N_("Reverted to default keymap layout.\n"));
+ return 0;
+}
+
+GRUB_MOD_INIT (keyboard_layouts)
+{
+ grub_memcpy (original_keyboard_layout_normal, grub_keyboard_map->normal,
+ 128);
+ grub_memcpy (original_keyboard_layout_shift, grub_keyboard_map->shift, 128);
+
+ active_layout = grub_strdup("default");
+
+ grub_register_command_p1 ("load_layout", grub_cmd_load_layout,
+ N_("LAYOUT"), N_("Set up the new layout."));
+
+ grub_register_command_p1 ("show_layout",
+ grub_cmd_show_active_keyboardlayout, 0,
+ N_("Show the active layout."));
+
+ grub_register_command_p1 ("**",
+ grub_cmd_set_default_keyboard, 0,
+ N_("Set up the default keyboard."));
+
+}
+
+GRUB_MOD_FINI (keyboard_layouts)
+{
+ set_default_keyboard();
+}
=== 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-18 21:15:59 +0000
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
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_normal[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->normal[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];
+ && grub_keyboard_map->shift[code])
+ key = grub_keyboard_map->shift[code];
else
- key = keyboard_map[code];
+ key = grub_keyboard_map->normal[code];
if (key == 0)
grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code);
@@ -279,6 +280,9 @@ 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->normal = keyboard_map_normal;
+ grub_keyboard_map->shift = keyboard_map_shift;
}
GRUB_MOD_FINI(at_keyboard)
=== modified file 'util/grub-mkconfig.in'
--- util/grub-mkconfig.in 2009-12-12 00:43:32 +0000
+++ util/grub-mkconfig.in 2010-01-18 22:44:55 +0000
@@ -220,7 +220,8 @@ export GRUB_DEFAULT \
GRUB_DISABLE_LINUX_UUID \
GRUB_DISABLE_LINUX_RECOVERY \
GRUB_GFXMODE \
- GRUB_DISABLE_OS_PROBER
+ GRUB_DISABLE_OS_PROBER \
+ GRUB_KEYBOARD_LAYOUT
if test "x${grub_cfg}" != "x"; then
rm -f ${grub_cfg}.new
=== added file 'util/grub-mklayouts.c'
--- util/grub-mklayouts.c 1970-01-01 00:00:00 +0000
+++ util/grub-mklayouts.c 2010-01-18 22:36:46 +0000
@@ -0,0 +1,308 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2010 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 .
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "progname.h"
+
+#define CKBCOMP "ckbcomp"
+
+static struct option options[] = {
+ {"output", required_argument, 0, 'o'},
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'V'},
+ {"verbose", no_argument, 0, 'v'},
+ {0, 0, 0, 0}
+};
+
+struct console_grub_equivalence
+{
+ char *layout;
+ char grub;
+};
+
+static struct console_grub_equivalence console_grub_equivalences[] = {
+ {"Escape", GRUB_TERM_ESC},
+ {"Tab", GRUB_TERM_TAB},
+ {"Delete", GRUB_TERM_BACKSPACE},
+
+ {"KP_1", '1'},
+ {"KP_2", '2'},
+ {"KP_3", '3'},
+ {"KP_4", '4'},
+ {"KP_5", '5'},
+ {"KP_6", '6'},
+ {"KP_7", '7'},
+ {"KP_8", '8'},
+ {"KP_9", '9'},
+
+ {"KP_Multiply", '*'},
+ {"KP_Substract", '-'},
+ {"KP_Add", '+'},
+ {"KP_Divide", '/'},
+
+ {"KP_Enter", '\n'},
+ {"Return", '\n'},
+ {"", '\0'}
+};
+
+static void
+usage (int status)
+{
+ if (status)
+ fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
+ else
+ printf ("\
+Usage: %s [OPTIONS] LAYOUT\n\
+ -o, --output set output file name. Default is LAYOUT.\n\
+ -h, --help display this message and exit.\n\
+ -V, --version print version information and exit.\n\
+ -v, --verbose print verbose messages.\n\
+\n\
+Report bugs to <%s>.\n", program_name, PACKAGE_BUGREPORT);
+
+ exit (status);
+}
+
+void
+add_special_keys (char keyboard_map[128])
+{
+ keyboard_map[71] = GRUB_TERM_HOME;
+ keyboard_map[72] = GRUB_TERM_UP;
+ keyboard_map[73] = GRUB_TERM_NPAGE;
+ keyboard_map[75] = GRUB_TERM_LEFT;
+ keyboard_map[77] = GRUB_TERM_RIGHT;
+ keyboard_map[79] = GRUB_TERM_END;
+ keyboard_map[80] = GRUB_TERM_DOWN;
+ keyboard_map[81] = GRUB_TERM_PPAGE;
+ keyboard_map[83] = GRUB_TERM_DC;
+
+/*
+ * TODO: defined in include/grub/i386/at_keyboard.h
+ keyboard_map[101] = OLPC_UP;
+ keyboard_map[102] = OLPC_DOWN;
+ keyboard_map[103] = OLPC_LEFT;
+ keyboard_map[104] = OLPC_RIGHT;
+*/
+
+}
+
+char
+lookup (char *code)
+{
+ int i;
+
+ for (i = 0; console_grub_equivalences[i].grub != '\0'; i++)
+ {
+ if (strcmp (code, console_grub_equivalences[i].layout) == 0)
+ {
+ return console_grub_equivalences[i].grub;
+ }
+ }
+
+ return '\0';
+}
+
+unsigned int
+get_grub_code (char *layout_code)
+{
+ unsigned int code;
+
+ if (strncmp (layout_code, "U+", sizeof ("U+") - 1) == 0)
+ {
+ sscanf (layout_code, "U+%x", &code);
+ }
+ else if (strncmp (layout_code, "+U+", sizeof ("+U+") - 1) == 0)
+ {
+ sscanf (layout_code, "+U+%x", &code);
+ }
+ else
+ {
+ code = lookup (layout_code);
+ }
+ return code;
+}
+
+void
+write_keymap (char *keymap, char *output_file)
+{
+ char keyboard_map_normal[128];
+ char keyboard_map_shift[128];
+
+ char line[2048];
+ char normal[64];
+ char shift[64];
+ int key_code;
+ int i;
+ pid_t pid;
+ int pipe_communication[2];
+ int ok;
+
+ FILE *fp_pipe;
+ FILE *fp_output;
+
+ if (pipe (pipe_communication) == -1)
+ {
+ grub_util_error ("cannot prepare the pipe");
+ exit (2);
+ }
+
+ pid = fork ();
+ if (pid < 0)
+ {
+ grub_util_error ("cannot fork");
+ exit (2);
+ }
+ else if (pid == 0)
+ {
+ close (1);
+ dup (pipe_communication[1]);
+ close (pipe_communication[0]);
+ execlp (CKBCOMP, CKBCOMP, keymap, NULL);
+ grub_util_error ("%s %s cannot be executed", CKBCOMP, keymap);
+ exit (3);
+ }
+ close (pipe_communication[1]);
+ fp_pipe = fdopen (pipe_communication[0], "r");
+
+ memset (keyboard_map_normal, 0, 128);
+ memset (keyboard_map_shift, 0, 128);
+
+ /* Process the ckbcomp output and prepare the layouts. */
+ ok = 0;
+ while (fgets (line, sizeof (line), fp_pipe))
+ {
+ if (strncmp (line, "keycode", sizeof ("keycode") - 1) == 0)
+ {
+ sscanf (line, "keycode %d = %s %s", &key_code, normal, shift);
+ if (key_code < 128)
+ {
+ keyboard_map_normal[key_code] = (char) get_grub_code (normal);
+ keyboard_map_shift[key_code] = (char) get_grub_code (shift);
+ ok = 1;
+ }
+ }
+ }
+
+ add_special_keys (keyboard_map_normal);
+
+ if (ok == 0)
+ {
+ fprintf (stderr, "ERROR: no keycodes found. Check output of %s %s.\n",
+ CKBCOMP, keymap);
+ exit (1);
+ }
+
+ /* Save the layouts to the file. */
+ fp_output = fopen (output_file, "w");
+
+ if (!fp_output)
+ {
+ grub_util_error ("cannot open `%s'", output_file);
+ exit (1);
+ }
+
+ int version;
+ version = GRUB_KEYBOARD_LAYOUTS_VERSION;
+ version = grub_cpu_to_be32 (version);
+
+ grub_util_write_image (GRUB_KEYBOARD_LAYOUTS_FILEMAGIC,
+ sizeof (GRUB_KEYBOARD_LAYOUTS_FILEMAGIC) - 1, fp_output);
+
+ grub_util_write_image ((char *) &version, 4, fp_output);
+
+ for (i = 0; i < 128; i++)
+ {
+ fprintf (fp_output, "%c", keyboard_map_normal[i]);
+ }
+
+ for (i = 0; i < 128; i++)
+ {
+ fprintf (fp_output, "%c", keyboard_map_shift[i]);
+ }
+ fclose (fp_output);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int verbosity;
+ char *output_file = NULL;
+
+ set_program_name (argv[0]);
+
+ verbosity = 0;
+
+ /* Check for options. */
+ while (1)
+ {
+ int c = getopt_long (argc, argv, "o:hVv", options, 0);
+
+ if (c == -1)
+ break;
+ else
+ switch (c)
+ {
+ case 'h':
+ usage (0);
+ break;
+
+ case 'o':
+ output_file = optarg;
+ break;
+
+ case 'V':
+ printf ("%s (%s) %s\n", program_name, PACKAGE_NAME,
+ PACKAGE_VERSION);
+ return 0;
+
+ case 'v':
+ verbosity++;
+ break;
+
+ default:
+ usage (1);
+ break;
+ }
+ }
+
+ /* Obtain LAYOUT. */
+ if (optind >= argc)
+ {
+ fprintf (stderr, "No layout is specified.\n");
+ usage (1);
+ }
+
+ if (output_file == NULL)
+ {
+ output_file = argv[optind];
+ }
+
+ write_keymap (argv[optind], output_file);
+
+ return 0;
+}
=== modified file 'util/grub.d/00_header.in'
--- util/grub.d/00_header.in 2010-01-05 10:53:03 +0000
+++ util/grub.d/00_header.in 2010-01-18 22:45:47 +0000
@@ -129,6 +129,14 @@ insmod gettext
EOF
fi
+if [ "x${GRUB_KEYBOARD_LAYOUT}" != "x" ] ; then
+ cat << EOF
+insmod keyboard_layouts
+set keymaps_dir=${grub_prefix}/layouts
+load_layout ${GRUB_KEYBOARD_LAYOUT}
+EOF
+fi
+
if [ "x${GRUB_HIDDEN_TIMEOUT}" != "x" ] ; then
if [ "x${GRUB_HIDDEN_TIMEOUT_QUIET}" = "xtrue" ] ; then
verbose=