* keyboard layout patches
@ 2010-01-18 0:10 Carles Pina i Estany
2010-01-18 8:15 ` Felix Zielcke
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Carles Pina i Estany @ 2010-01-18 0:10 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 1020 bytes --]
Hello,
I've done a first version of keyboard_layout. Find a patch attached, or
check the branch:
bzr.savannah.gnu.org/srv/bzr/grub/people/cpina/keyboard_layouts
I've tested only in at_keyboard. Using something like:
insmod at_keyboard
terminal_input at_keyboard
insmod keyboard_layouts
set keymaps_dir=/boot/grub/layouts
load_keyboard es
and before I generate the file called "es" and copied into
/boot/grub/layouts using grub-mklayout es
How could grub-mkinstall (00_header.in) know the current keyboard in the
system? I wold tweak 00_header.in to generate the keymap file and setup
it.
Comments about the current patch are welcomed, I would change it on next
days.
Some days ago I read:
"There are 2 hard problems in computer science: cache invalidation,
naming things, and off-by-1 errors."
Don't hesitate to tell me how would you rename some things, I'll do.
I'm not happy with the name of some variables/functions but I cannot
think about it today :-)
Cheers,
--
Carles Pina i Estany
http://pinux.info
[-- Attachment #2: keyboard_layout01.patch --]
[-- Type: text/x-diff, Size: 16743 bytes --]
=== 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/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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 <grub/keys.h>
#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-17 22:59:21 +0000
@@ -0,0 +1,160 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 char original_keyboard_layout_normal[128];
+static char original_keyboard_layout_shift[128];
+
+static char *active_layout;
+
+/* Layout file format constants. */
+static const char file_magic[7] = { 'G', 'R', 'U', 'B', 'L', 'A', 'Y' };
+
+static grub_err_t
+grub_cmd_load_keyboardlayout (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_keyboard 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, 7);
+
+ if (check != 7)
+ {
+ return grub_error (GRUB_ERR_READ_ERROR,
+ "cannot read the file header from `%s'", filename);
+ }
+
+ if (grub_memcmp (magic, file_magic, 7) != 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 != 1)
+ {
+ 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;
+}
+
+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_keyboard", grub_cmd_load_keyboardlayout,
+ 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_MOD_FINI (keyboard_layouts)
+{
+ grub_memcpy (grub_keyboard_map->normal, original_keyboard_layout_normal, 128);
+ grub_memcpy (grub_keyboard_map->shift, original_keyboard_layout_shift, 128);
+}
=== 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 21:56:50 +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_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];
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)
=== added file 'util/grub-mklayouts.c'
--- util/grub-mklayouts.c 1970-01-01 00:00:00 +0000
+++ util/grub-mklayouts.c 2010-01-17 23:17:07 +0000
@@ -0,0 +1,287 @@
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/util/misc.h>
+#include <grub/keys.h>
+#include <grub/i18n.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#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_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;
+ int exit_status;
+
+ FILE *fp;
+ char *command;
+
+ command =
+ (char *) malloc (strlen (CKBCOMP) + strlen (keymap) + strlen (" ") + 1);
+
+ if (!command)
+ {
+ grub_util_error ("cannot prepare command");
+ exit (2);
+ }
+
+ sprintf (command, CKBCOMP " %s", keymap);
+
+ fp = popen (command, "r");
+
+ if (fp == NULL)
+ {
+ grub_util_error ("cannot execute `ckbcomp'");
+ exit (1);
+ }
+
+ for (i= 0; i < 128; i++)
+ {
+ keyboard_map_normal[i] = '\0';
+ keyboard_map_shift[i] = '\0';
+ }
+
+ /* Process the ckbcomp output and prepare the layouts. */
+ while (fgets (line, sizeof (line), fp))
+ {
+ 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);
+ }
+ }
+ }
+
+ add_special_keys (keyboard_map_normal);
+
+ exit_status = pclose (fp);
+
+ if (exit_status != 0)
+ {
+ fprintf (stderr, "ERROR: `%s' returned exit status %d.\n", command,
+ exit_status);
+ exit (1);
+ }
+
+ /* Save the layouts to the file. */
+ fp = fopen (output_file, "w");
+
+ if (!fp)
+ {
+ grub_util_error ("cannot open `%s'", output_file);
+ exit (1);
+ }
+
+ int version;
+ version = 1;
+ version = grub_cpu_to_be32 (version);
+
+ grub_util_write_image ("GRUBLAY", 7, fp);
+ grub_util_write_image ((char *) &version, 4, fp);
+
+ for (i= 0; i < 128; i++)
+ {
+ fprintf (fp, "%c", keyboard_map_normal[i]);
+ }
+
+ for (i = 0; i < 128; i++)
+ {
+ fprintf (fp, "%c", keyboard_map_shift[i]);
+ }
+ fclose (fp);
+
+ free (command);
+}
+
+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;
+}
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 0:10 keyboard layout patches Carles Pina i Estany
@ 2010-01-18 8:15 ` Felix Zielcke
2010-01-18 13:20 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-18 23:27 ` Carles Pina i Estany
2 siblings, 0 replies; 14+ messages in thread
From: Felix Zielcke @ 2010-01-18 8:15 UTC (permalink / raw)
To: The development of GNU GRUB
Am Montag, den 18.01.2010, 00:10 +0000 schrieb Carles Pina i Estany:
> Hello,
>
> I've done a first version of keyboard_layout. Find a patch attached, or
> check the branch:
> bzr.savannah.gnu.org/srv/bzr/grub/people/cpina/keyboard_layouts
Nice work, though I haven't yet looked at the patch itself.
>
> How could grub-mkinstall (00_header.in) know the current keyboard in the
> system? I wold tweak 00_header.in to generate the keymap file and setup
> it.
I think that's completely distribution specific and maybe even can
depend on the window manager/desktop enviromnent you use (if you use
one).
So I suggest to just use a variable in /etc/default/grub for that.
--
Felix Zielcke
Proud Debian Maintainer and GNU GRUB developer
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 0:10 keyboard layout patches Carles Pina i Estany
2010-01-18 8:15 ` Felix Zielcke
@ 2010-01-18 13:20 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-18 13:53 ` Carles Pina i Estany
2010-01-18 20:04 ` Carles Pina i Estany
2010-01-18 23:27 ` Carles Pina i Estany
2 siblings, 2 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-01-18 13:20 UTC (permalink / raw)
To: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 2596 bytes --]
Carles Pina i Estany wrote:
> Hello,
>
> I've done a first version of keyboard_layout. Find a patch attached, or
> check the branch:
> bzr.savannah.gnu.org/srv/bzr/grub/people/cpina/keyboard_layouts
>
> I've tested only in at_keyboard. Using something like:
>
> insmod at_keyboard
> terminal_input at_keyboard
> insmod keyboard_layouts
> set keymaps_dir=/boot/grub/layouts
> load_keyboard es
>
> and before I generate the file called "es" and copied into
> /boot/grub/layouts using grub-mklayout es
>
> How could grub-mkinstall (00_header.in) know the current keyboard in the
> system?
setxkbmap -print will give you the x layout but it won't work outside of X.
> I wold tweak 00_header.in to generate the keymap file and setup
> it.
>
It may be executed by a daemon with no X available.
> Comments about the current patch are welcomed, I would change it on next
> days.
>
> Some days ago I read:
> "There are 2 hard problems in computer science: cache invalidation,
> naming things, and off-by-1 errors."
>
> Don't hesitate to tell me how would you rename some things, I'll do.
> I'm not happy with the name of some variables/functions but I cannot
> think about it today :-)
>
>
+/* Layout file format constants. */
+static const char file_magic[7] = { 'G', 'R', 'U', 'B', 'L', 'A', 'Y' };
Don't use misaligned magics.
+ 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);
Can you add support for complete filenames?
+ grub_sprintf (filename, "%s/%s", prefix, args[0]);
+ sprintf (command, CKBCOMP " %s", keymap);
+
+ fp = popen (command, "r");
+
Opens the possibility to execute any code by specifying layouts like |rm -rf /
+ for (i= 0; i < 128; i++)
+ {
+ keyboard_map_normal[i] = '\0';
+ keyboard_map_shift[i] = '\0';
+ }
use memset
+ grub_util_write_image ("GRUBLAY", 7, fp);
+ grub_util_write_image ((char *) &version, 4, fp);
should be macroified and put somewhere in a header instead of duplicating
Can you think of a way to restoring keyboard map to English?
> Cheers,
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 293 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 13:20 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-01-18 13:53 ` Carles Pina i Estany
2010-01-18 15:00 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-19 23:19 ` Robert Millan
2010-01-18 20:04 ` Carles Pina i Estany
1 sibling, 2 replies; 14+ messages in thread
From: Carles Pina i Estany @ 2010-01-18 13:53 UTC (permalink / raw)
To: The development of GNU GRUB
Hi,
I answer in fast way... more at evening. Items that I don't comment I
understand and agree.
On Jan/18/2010, Vladimir '??-coder/phcoder' Serbinenko wrote:
> > How could grub-mkinstall (00_header.in) know the current keyboard in the
> > system?
> setxkbmap -print will give you the x layout but it won't work outside of X.
> > I wold tweak 00_header.in to generate the keymap file and setup
> > it.
> >
> It may be executed by a daemon with no X available.
I'll use Felix suggestion: do whatever is in /etc/grub/default
> + filename =
> + grub_malloc (grub_strlen (prefix) + grub_strlen ("/") +
> + grub_strlen (args[0]) + 1);
> Can you add support for complete filenames?
do you mean that, for example, if args[0] starts by "/" then filename =
args[0]?
Actually if prefix (that it's a variable) is "/" then args[0] acts as a
filename. Would be like "///test/filename" and it's a valid directory.
> Can you think of a way to restoring keyboard map to English?
unloading the module restores the original keyboard (so, English one). I save
the original one when the module is loaded.
Thanks for the other comments,
--
Carles Pina i Estany
http://pinux.info
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 13:53 ` Carles Pina i Estany
@ 2010-01-18 15:00 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-18 19:25 ` Carles Pina i Estany
2010-01-19 23:19 ` Robert Millan
1 sibling, 1 reply; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2010-01-18 15:00 UTC (permalink / raw)
To: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 1726 bytes --]
Carles Pina i Estany wrote:
> Hi,
>
> I answer in fast way... more at evening. Items that I don't comment I
> understand and agree.
>
> On Jan/18/2010, Vladimir '??-coder/phcoder' Serbinenko wrote:
>
>
>>> How could grub-mkinstall (00_header.in) know the current keyboard in the
>>> system?
>>>
>> setxkbmap -print will give you the x layout but it won't work outside of X.
>>
>>> I wold tweak 00_header.in to generate the keymap file and setup
>>> it.
>>>
>>>
>> It may be executed by a daemon with no X available.
>>
>
> I'll use Felix suggestion: do whatever is in /etc/grub/default
>
>
>
>> + filename =
>> + grub_malloc (grub_strlen (prefix) + grub_strlen ("/") +
>> + grub_strlen (args[0]) + 1);
>> Can you add support for complete filenames?
>>
>
> do you mean that, for example, if args[0] starts by "/" then filename =
> args[0]?
>
> Actually if prefix (that it's a variable) is "/" then args[0] acts as a
> filename. Would be like "///test/filename" and it's a valid directory.
>
>
Perhaps we should remove prefix variables altogether.
>> Can you think of a way to restoring keyboard map to English?
>>
>
> unloading the module restores the original keyboard (so, English one). I save
> the original one when the module is loaded.
>
>
I mean imagine that you're in a face to a grub with klingon keyboard how
would you find your way out?
Also keyboard_layouts is pretty small. Perhaps we can just make
*_keyboard depend on it and put US keyboard into it as default and shave
some complexity this way
> Thanks for the other comments,
>
>
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 293 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 15:00 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-01-18 19:25 ` Carles Pina i Estany
2010-01-18 19:31 ` Colin Watson
2010-01-19 23:21 ` Robert Millan
0 siblings, 2 replies; 14+ messages in thread
From: Carles Pina i Estany @ 2010-01-18 19:25 UTC (permalink / raw)
To: The development of GNU GRUB
Hi,
On Jan/18/2010, Vladimir '??-coder/phcoder' Serbinenko wrote:
> Carles Pina i Estany wrote:
> > Actually if prefix (that it's a variable) is "/" then args[0] acts as a
> > filename. Would be like "///test/filename" and it's a valid directory.
> >
> >
> Perhaps we should remove prefix variables altogether.
I understand that you mean that the user would type:
load_keyboard /boot/grub/layouts/es
right? (in the shell or the config file)
Comments on this?
(I don't like it, I would even prefer to have the prefix hardcoded or
like it's now)
> >> Can you think of a way to restoring keyboard map to English?
> >>
> >
> > unloading the module restores the original keyboard (so, English one). I save
> > the original one when the module is loaded.
> >
> >
> I mean imagine that you're in a face to a grub with klingon keyboard
> how would you find your way out?
Klingon is my primary layout! :-)
I have different things to say and we could discuss quite long, but
let's jump to the ideas:
a) very short term: what about to register a command to "something"
(like "1234", numbers doesn't usually change between keyboard, right? or
"**" for the keypad -I should check that it works, but would fix if it
doesn't) that reverts to English?
b) medium term: as you suggested some days ago on IRC: Shift+Shift, or
Ctrl+Shift or something like this reverts to English.
I'm not sure about the infrastructure needed for b)
> Also keyboard_layouts is pretty small. Perhaps we can just make
> *_keyboard depend on it and put US keyboard into it as default and shave
> some complexity this way
How it would work in rescue mode and at_keyboard? I mean, extreme cases
that Grub for some reason could not reach the keyboard layout file.
The complexitity that we save is very reduced.
--
Carles Pina i Estany
http://pinux.info
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 19:25 ` Carles Pina i Estany
@ 2010-01-18 19:31 ` Colin Watson
2010-01-18 22:17 ` Carles Pina i Estany
2010-01-19 23:21 ` Robert Millan
1 sibling, 1 reply; 14+ messages in thread
From: Colin Watson @ 2010-01-18 19:31 UTC (permalink / raw)
To: The development of GNU GRUB
On Mon, Jan 18, 2010 at 07:25:37PM +0000, Carles Pina i Estany wrote:
> a) very short term: what about to register a command to "something"
> (like "1234", numbers doesn't usually change between keyboard, right?
The standard counterexample is French. Function keys do stay constant,
though.
--
Colin Watson [cjwatson@ubuntu.com]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 13:20 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-18 13:53 ` Carles Pina i Estany
@ 2010-01-18 20:04 ` Carles Pina i Estany
2010-01-19 23:22 ` Robert Millan
1 sibling, 1 reply; 14+ messages in thread
From: Carles Pina i Estany @ 2010-01-18 20:04 UTC (permalink / raw)
To: The development of GNU GRUB
Hi,
On Jan/18/2010, Vladimir '??-coder/phcoder' Serbinenko wrote:
> + grub_util_write_image ("GRUBLAY", 7, fp);
> + grub_util_write_image ((char *) &version, 4, fp);
>
> should be macroified and put somewhere in a header instead of duplicating
I agree. Any reason that I don't see that in util/grub-mkfont.c:
grub_util_write_image ("FILE", 4, file);
grub_util_write_image ("PFF2", 4, file);
and then in font/font.c:
static const char section_names_file[4] = { 'F', 'I', 'L', 'E' };
static const char pff2_magic[4] = { 'P', 'F', 'F', '2' };
?
If should be in a macro (as I think so) I will fix after finishing other
things.
Cheers,
--
Carles Pina i Estany
http://pinux.info
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 19:31 ` Colin Watson
@ 2010-01-18 22:17 ` Carles Pina i Estany
0 siblings, 0 replies; 14+ messages in thread
From: Carles Pina i Estany @ 2010-01-18 22:17 UTC (permalink / raw)
To: The development of GNU GRUB
Hi,
On Jan/18/2010, Colin Watson wrote:
> On Mon, Jan 18, 2010 at 07:25:37PM +0000, Carles Pina i Estany wrote:
> > a) very short term: what about to register a command to "something"
> > (like "1234", numbers doesn't usually change between keyboard, right?
>
> The standard counterexample is French. Function keys do stay constant,
> though.
Usually are not mapped to any ASCII output to call a command.
I know that I can do it idfferent, but then it's not option a).
What about the star in the numeric pad? Is it constant for all
keyboards? (I can check generating all keymaps and a script, but maybe
you know on the top of your head)
--
Carles Pina i Estany
http://pinux.info
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 0:10 keyboard layout patches Carles Pina i Estany
2010-01-18 8:15 ` Felix Zielcke
2010-01-18 13:20 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-01-18 23:27 ` Carles Pina i Estany
2 siblings, 0 replies; 14+ messages in thread
From: Carles Pina i Estany @ 2010-01-18 23:27 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 963 bytes --]
Hi,
On Jan/18/2010, Carles Pina i Estany wrote:
> I've done a first version of keyboard_layout. Find a patch attached, or
Thanks to the comments from different people in the thread, I send a new
version.
It does, on from my head:
a) Constants used in util/ and Grub are in a common header file.
b) Use 8 bytes magic file, instead of 7
c) Adds a new command "**" to revert to the default keyboard
d) Don't use popen and use fork + execlp + pipe
e) Change some names that I didn't like
f) Implements a new variable in /etc/grub/default
And some other small bugfixes.
Everything is tested but not f).
The solution of c) is temporary, but I think that good enough for this
stage. When this is in trunk/experimental (I think that can go to trunk
straight away since there isn't major changes, but I give it up to you)
I can implement some other solution.
What else I should change, or some other comment?
Thanks,
--
Carles Pina i Estany
http://pinux.info
[-- Attachment #2: keyboard_layout02.patch --]
[-- Type: text/x-diff, Size: 21398 bytes --]
=== 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 <carles@pina.cat>
+
+ 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 `<grub/mm.h>'.
+ (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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ */
+
+#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 <grub/keys.h>
#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 <http://www.gnu.org/licenses/>.
+ */
+
+#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/keyboard_layouts.h>
+
+#include <grub/term.h>
+
+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 <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_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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/util/misc.h>
+#include <grub/keys.h>
+#include <grub/i18n.h>
+#include <grub/keyboard_layouts.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#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=
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 13:53 ` Carles Pina i Estany
2010-01-18 15:00 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2010-01-19 23:19 ` Robert Millan
1 sibling, 0 replies; 14+ messages in thread
From: Robert Millan @ 2010-01-19 23:19 UTC (permalink / raw)
To: The development of GNU GRUB
On Mon, Jan 18, 2010 at 02:53:36PM +0100, Carles Pina i Estany wrote:
> > Can you think of a way to restoring keyboard map to English?
>
> unloading the module restores the original keyboard (so, English one). I save
> the original one when the module is loaded.
Don't confuse keyboard layouts with languages! You probably meant US
keyboard.
--
Robert Millan
"Be the change you want to see in the world" -- Gandhi
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 19:25 ` Carles Pina i Estany
2010-01-18 19:31 ` Colin Watson
@ 2010-01-19 23:21 ` Robert Millan
2010-01-20 0:03 ` Carles Pina i Estany
1 sibling, 1 reply; 14+ messages in thread
From: Robert Millan @ 2010-01-19 23:21 UTC (permalink / raw)
To: The development of GNU GRUB
On Mon, Jan 18, 2010 at 07:25:37PM +0000, Carles Pina i Estany wrote:
> > Also keyboard_layouts is pretty small. Perhaps we can just make
> > *_keyboard depend on it and put US keyboard into it as default and shave
> > some complexity this way
>
> How it would work in rescue mode and at_keyboard? I mean, extreme cases
> that Grub for some reason could not reach the keyboard layout file.
What's the total size we're talking about?
--
Robert Millan
"Be the change you want to see in the world" -- Gandhi
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-18 20:04 ` Carles Pina i Estany
@ 2010-01-19 23:22 ` Robert Millan
0 siblings, 0 replies; 14+ messages in thread
From: Robert Millan @ 2010-01-19 23:22 UTC (permalink / raw)
To: The development of GNU GRUB
On Mon, Jan 18, 2010 at 08:04:35PM +0000, Carles Pina i Estany wrote:
> On Jan/18/2010, Vladimir '??-coder/phcoder' Serbinenko wrote:
>
> > + grub_util_write_image ("GRUBLAY", 7, fp);
> > + grub_util_write_image ((char *) &version, 4, fp);
> >
> > should be macroified and put somewhere in a header instead of duplicating
>
> I agree. Any reason that I don't see that in util/grub-mkfont.c:
>
> grub_util_write_image ("FILE", 4, file);
> grub_util_write_image ("PFF2", 4, file);
>
> and then in font/font.c:
>
> static const char section_names_file[4] = { 'F', 'I', 'L', 'E' };
> static const char pff2_magic[4] = { 'P', 'F', 'F', '2' };
>
> ?
>
> If should be in a macro (as I think so) I will fix after finishing other
> things.
Yeah it should.
--
Robert Millan
"Be the change you want to see in the world" -- Gandhi
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: keyboard layout patches
2010-01-19 23:21 ` Robert Millan
@ 2010-01-20 0:03 ` Carles Pina i Estany
0 siblings, 0 replies; 14+ messages in thread
From: Carles Pina i Estany @ 2010-01-20 0:03 UTC (permalink / raw)
To: The development of GNU GRUB
Hi,
On Jan/20/2010, Robert Millan wrote:
> On Mon, Jan 18, 2010 at 07:25:37PM +0000, Carles Pina i Estany wrote:
> > > Also keyboard_layouts is pretty small. Perhaps we can just make
> > > *_keyboard depend on it and put US keyboard into it as default and shave
> > > some complexity this way
> >
> > How it would work in rescue mode and at_keyboard? I mean, extreme cases
> > that Grub for some reason could not reach the keyboard layout file.
>
> What's the total size we're talking about?
Layout files are 268 bytes (128 for standard layout, 128 for shift and
some headers, 8 bytes for filemagic, 4 bytes for version)
keyboard_layouts.mod is 3164. Aprox 520 with error messages, maybe now
is too much detailed.
--
Carles Pina i Estany
http://pinux.info
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2010-01-20 0:03 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-18 0:10 keyboard layout patches Carles Pina i Estany
2010-01-18 8:15 ` Felix Zielcke
2010-01-18 13:20 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-18 13:53 ` Carles Pina i Estany
2010-01-18 15:00 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-18 19:25 ` Carles Pina i Estany
2010-01-18 19:31 ` Colin Watson
2010-01-18 22:17 ` Carles Pina i Estany
2010-01-19 23:21 ` Robert Millan
2010-01-20 0:03 ` Carles Pina i Estany
2010-01-19 23:19 ` Robert Millan
2010-01-18 20:04 ` Carles Pina i Estany
2010-01-19 23:22 ` Robert Millan
2010-01-18 23:27 ` Carles Pina i Estany
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.