All of lore.kernel.org
 help / color / mirror / Atom feed
From: Carles Pina i Estany <carles@pina.cat>
To: grub-devel@gnu.org
Subject: keyboard layouts
Date: Fri, 19 Mar 2010 23:45:17 +0000	[thread overview]
Message-ID: <20100319234517.GA29665@pina.cat> (raw)

[-- Attachment #1: Type: text/plain, Size: 1274 bytes --]


Hello,

I have been one month and something without doing lot of Grub things. I
think that last time that I did something was going/coming from Fosdem
:-/

Hopefully soon I can finish the keyboard layouts. See my branch:
sftp://cpina@bzr.savannah.gnu.org/srv/bzr/grub/people/cpina/keyboard_layouts/

Or my attached patch.

Right now (and this needs a change) the modules at_keyboard and
usb_keyboard doesn't need the at_keyboard_layouts and
usb_keyboard_layouts (they have the default layout hardcoded).

If the user loads usb_keyboard_layouts, usb_keyboard gets loaded (same
with AT).

Vladimir suggested, to simplify (usb_keyboard_layouts and
at_keyboard_layouts are mainly the same with some defines) that
usb_keyboard should depend on keyboard_layouts (generic) and at_keyboard
should depen on keyboard_layouts (generic as well).
Vladimir: is it what you suggested? Was some time ago...

I didn't like a lot because in some circumstancies maybe we don't want
layouts at all (some users, environments, etc.)

Vladimir liked (if I remember correctly) to avoid having two modules
(instead of only one).

I have the feeling that I'm biased and I've ate some vladimir reason :-/

I'll do the changes when we will agree.

Cheers,

-- 
Carles Pina i Estany
	http://pinux.info

[-- Attachment #2: keyboard_layouts.patch --]
[-- Type: text/x-diff, Size: 28296 bytes --]

=== added file 'ChangeLog.keyboard_layouts'
--- ChangeLog.keyboard_layouts	1970-01-01 00:00:00 +0000
+++ ChangeLog.keyboard_layouts	2010-02-13 23:49:34 +0000
@@ -0,0 +1,31 @@
+2010-01-18  Carles Pina i Estany  <carles@pina.cat>
+
+	Adds keyboard layouts support (AT and USB)
+
+	* conf/common.rmk (bin_UTILITIES): Add grub-mklayouts rules.
+	(pkglib_MODULES): Add module `at_keyboard_layouts.mod' and
+	`usb_keyboard_layouts.mod'.
+	* include/grub/at_keyboard.h: Include `"keyboard.h"'. New EXPORT_VAR
+	`grub_keyboard_map'.
+	* include/grub/keyboard.h: New file.
+	* include/grub/keyboard_layouts.h: New file.
+	* include/grub/term.h: Move macros from here ...
+	* include/grub/keys.h: ... to here. New file.
+	* include/grub/usb_keyboard.h: New file.
+	* keyboard_layouts/keyboard_layouts.c: New file.
+	* keyboard_layouts/at_keyboard_layouts.c: New file.
+	* keyboard_layouts/usb_keyboard_layouts.c: New file.
+	* term/at_keyboard.c: Include `<grub/mm.h>'.
+	(grub_at_keyboard_map): Declare.
+	(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_MOD_INIT): Initialise `grub_at_keyboard_map'.
+	* term/usb_keyboard.c: Include `<grub/mm.h>' and
+	`<grub/usb_keyboard.h>'.
+	(grub_usb_keyboard_map): Declare.
+	(keyboard_map_normal): Renamed from keyboard_map.
+	(grub_usb_keyboard_checkkey): Use `keyboard_map_normal' instead of
+	`keyboard_map'.
+	(GRUB_MOD_INIT): Initialise `grub_usb_keyboard_map'.
+	* util/grub-mklayouts.c: New file.

=== modified file 'conf/common.rmk'
--- conf/common.rmk	2010-03-14 16:50:55 +0000
+++ conf/common.rmk	2010-03-19 23:20:58 +0000
@@ -91,6 +91,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
+
 bin_UTILITIES += grub-bin2h
 grub_bin2h_SOURCES = gnulib/progname.c util/bin2h.c
 
@@ -131,6 +135,18 @@ grub_script.tab.c grub_script.tab.h: scr
 	$(YACC) -d -p grub_script_yy -b grub_script $(srcdir)/script/parser.y
 DISTCLEANFILES += grub_script.tab.c grub_script.tab.h
 
+# For at_keyboard_layouts.mod
+pkglib_MODULES += at_keyboard_layouts.mod
+at_keyboard_layouts_mod_SOURCES = keyboard_layouts/at_keyboard_layouts.c 
+at_keyboard_layouts_mod_CFLAGS = $(COMMON_CFLAGS)
+at_keyboard_layouts_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For usb_keyboard_layouts.mod
+pkglib_MODULES += usb_keyboard_layouts.mod
+usb_keyboard_layouts_mod_SOURCES = keyboard_layouts/usb_keyboard_layouts.c 
+usb_keyboard_layouts_mod_CFLAGS = $(COMMON_CFLAGS)
+usb_keyboard_layouts_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For grub-script-check.
 grub_script_check_init.lst: geninit.sh $(filter-out grub_script_check_init.c,$(grub_script_check_SOURCES))
 	rm -f $@; grep GRUB_MOD_INIT $(filter %.c,$^) /dev/null > $@

=== modified file 'include/grub/at_keyboard.h'
--- include/grub/at_keyboard.h	2009-12-25 22:29:47 +0000
+++ include/grub/at_keyboard.h	2010-02-13 23:05:39 +0000
@@ -19,6 +19,10 @@
 #ifndef GRUB_AT_KEYBOARD_HEADER
 #define GRUB_AT_KEYBOARD_HEADER	1
 
+#include "keyboard.h"
+
+extern struct grub_keyboard_map_s *EXPORT_VAR(grub_at_keyboard_map);
+
 #define SHIFT_L		0x2a
 #define SHIFT_R		0x36
 #define CTRL		0x1d

=== added file 'include/grub/keyboard.h'
--- include/grub/keyboard.h	1970-01-01 00:00:00 +0000
+++ include/grub/keyboard.h	2010-02-13 23:29:48 +0000
@@ -0,0 +1,28 @@
+/*
+ *  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_HEADER
+#define GRUB_KEYBOARD_HEADER 1
+
+struct grub_keyboard_map_s
+{
+  char *normal;
+  char *shift;
+};
+
+#endif

=== 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-02-05 18:58:05 +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_KEYBOARD_LAYOUTS  */

=== 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-02-03 00:24:07 +0000
+++ include/grub/term.h	2010-01-29 23:31:29 +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
 

=== added file 'include/grub/usb_keyboard.h'
--- include/grub/usb_keyboard.h	1970-01-01 00:00:00 +0000
+++ include/grub/usb_keyboard.h	2010-02-13 23:29:58 +0000
@@ -0,0 +1,26 @@
+/*
+ *  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_USB_KEYBOARD_HEADER
+#define GRUB_USB_KEYBOARD_HEADER	1
+
+#include "keyboard.h"
+
+extern struct grub_keyboard_map_s *EXPORT_VAR(grub_usb_keyboard_map);
+
+#endif

=== added directory 'keyboard_layouts'
=== added file 'keyboard_layouts/at_keyboard_layouts.c'
--- keyboard_layouts/at_keyboard_layouts.c	1970-01-01 00:00:00 +0000
+++ keyboard_layouts/at_keyboard_layouts.c	2010-02-13 23:22:51 +0000
@@ -0,0 +1,6 @@
+#define DO_AT_KEYBOARD_LAYOUT 1
+#define COMMAND_NAME_LOAD "at_load_layout"
+#define COMMAND_NAME_SHOW "at_show_layout"
+#define COMMAND_NAME_RESTORE "at**"
+#define FILE_SUFFIX ".at"
+#include "keyboard_layouts.c"

=== 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-02-13 23:24:16 +0000
@@ -0,0 +1,213 @@
+/* at_keyboard_layouts.c - at_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>
+
+#ifdef DO_AT_KEYBOARD_LAYOUT
+  #include <grub/at_keyboard.h>
+#else
+  #include <grub/usb_keyboard.h>
+#endif
+
+#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 struct grub_keyboard_map_s *keyboard_map;
+
+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;
+  int filename_length;
+
+  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_length = grub_strlen (prefix) + grub_strlen ("/") +
+                    grub_strlen (args[0]) + grub_strlen(FILE_SUFFIX) + 1;
+
+  filename =
+    grub_malloc (filename_length);
+  
+  if (! filename)
+    return grub_errno;
+
+  grub_snprintf (filename, filename_length, "%s/%s%s", prefix, args[0],
+  						       FILE_SUFFIX);
+
+  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, 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, 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 (keyboard_map->normal, original_keyboard_layout_normal,
+	       128);
+  grub_memcpy (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;
+}
+
+#ifdef DO_AT_KEYBOARD_LAYOUT
+GRUB_MOD_INIT (at_keyboard_layouts)
+#else
+GRUB_MOD_INIT (usb_keyboard_layouts)
+#endif
+{
+#ifdef DO_AT_KEYBOARD_LAYOUT
+  keyboard_map = grub_at_keyboard_map;
+#else
+  keyboard_map = grub_usb_keyboard_map;
+#endif
+
+  grub_memcpy (original_keyboard_layout_normal, keyboard_map->normal,
+	       128);
+  grub_memcpy (original_keyboard_layout_shift, keyboard_map->shift, 128);
+
+  active_layout = grub_strdup("default");
+
+  grub_register_command_p1 (COMMAND_NAME_LOAD, grub_cmd_load_layout,
+			    N_("LAYOUT"), N_("Set up the new layout."));
+
+  grub_register_command_p1 (COMMAND_NAME_SHOW,
+			    grub_cmd_show_active_keyboardlayout, 0,
+			    N_("Show the active layout."));
+
+  grub_register_command_p1 (COMMAND_NAME_RESTORE,
+  			    grub_cmd_set_default_keyboard, 0,
+			    N_("Set up the default keyboard."));
+
+}
+
+GRUB_MOD_FINI (at_keyboard_layouts)
+{
+  set_default_keyboard();
+}

=== added file 'keyboard_layouts/usb_keyboard_layouts.c'
--- keyboard_layouts/usb_keyboard_layouts.c	1970-01-01 00:00:00 +0000
+++ keyboard_layouts/usb_keyboard_layouts.c	2010-02-13 23:22:53 +0000
@@ -0,0 +1,6 @@
+#define DO_USB_KEYBOARD_LAYOUT 1
+#define COMMAND_NAME_LOAD "usb_load_layout"
+#define COMMAND_NAME_SHOW "usb_show_layout"
+#define COMMAND_NAME_RESTORE "usb**"
+#define FILE_SUFFIX ".usb"
+#include "keyboard_layouts.c"

=== modified file 'term/at_keyboard.c'
--- term/at_keyboard.c	2010-01-10 12:34:48 +0000
+++ term/at_keyboard.c	2010-02-13 23:05:51 +0000
@@ -22,6 +22,9 @@
 #include <grub/cpu/io.h>
 #include <grub/misc.h>
 #include <grub/term.h>
+#include <grub/mm.h>
+
+struct grub_keyboard_map_s *grub_at_keyboard_map = NULL;
 
 static short at_keyboard_status = 0;
 static int pending_key = -1;
@@ -41,7 +44,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,
@@ -214,12 +217,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_at_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_at_keyboard_map->shift[code])
+	  key = grub_at_keyboard_map->shift[code];
 	else
-	  key = keyboard_map[code];
+	  key = grub_at_keyboard_map->normal[code];
 
 	if (key == 0)
 	  grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code);
@@ -295,6 +298,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_at_keyboard_map->normal = keyboard_map_normal;
+  grub_at_keyboard_map->shift = keyboard_map_shift;
 }
 
 GRUB_MOD_FINI(at_keyboard)

=== modified file 'term/usb_keyboard.c'
--- term/usb_keyboard.c	2009-12-02 09:00:54 +0000
+++ term/usb_keyboard.c	2010-02-13 23:05:58 +0000
@@ -26,9 +26,14 @@
 #include <grub/usb.h>
 #include <grub/dl.h>
 #include <grub/time.h>
+#include <grub/mm.h>
+#include <grub/usb_keyboard.h>
 
 \f
-static char keyboard_map[128] =
+
+struct grub_keyboard_map_s *grub_usb_keyboard_map = NULL;
+
+static char keyboard_map_normal[128] =
   {
     '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd',
     'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
@@ -152,11 +157,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_normal[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_normal[data[2]];
 
   if (key == 0)
     grub_printf ("Unknown key 0x%x detected\n", data[2]);
@@ -321,6 +326,9 @@ GRUB_MOD_INIT(usb_keyboard)
 {
   grub_usb_hid ();
   grub_term_register_input ("usb_keyboard", &grub_usb_keyboard_term);
+
+  grub_usb_keyboard_map->normal = keyboard_map_normal;
+  grub_usb_keyboard_map->shift = keyboard_map_shift;
 }
 
 GRUB_MOD_FINI(usb_keyboard)

=== added file 'util/grub-mklayouts.c'
--- util/grub-mklayouts.c	1970-01-01 00:00:00 +0000
+++ util/grub-mklayouts.c	2010-01-31 18:08:14 +0000
@@ -0,0 +1,396 @@
+/*
+ *  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 int at_to_usb_map_normal[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 int at_to_usb_map_shift[128] =
+{
+  0, 0, 30, 31, 32, 33, 34, 35, 
+  36, 37, 38, 39, 45, 46, 0, 0, 
+  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, 0, 0, 49, 29, 27, 6, 25, 
+  5, 17, 16, 54, 55, 56,
+  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, 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 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 base name file. Default is LAYOUT\n\
+  			.at or .usb suffixes will be automatically added.\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_file (char* filename, char keyboard_map_normal[128],
+	    char keyboard_map_shift[128])
+{
+  FILE *fp_output;
+  int version;
+  int i;
+
+  fp_output = fopen (filename, "w");
+  
+  if (!fp_output)
+    {
+      grub_util_error ("cannot open `%s'", filename);
+      exit (1);
+    }
+  
+  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);
+
+}
+
+void
+write_files_at_usb (char* base_filename, char at_keyboard_map_normal[128],
+		  char at_keyboard_map_shift[128])
+{
+  char *at_file;
+  char *usb_file;
+  int i;
+  char usb_keyboard_map_normal[128];
+  char usb_keyboard_map_shift[128];
+
+  /* AT layout.  */
+  at_file = (char*) xmalloc (strlen(base_filename) + strlen(".at") + 1);
+  sprintf (at_file, "%s.at", base_filename);
+
+  write_file (at_file, at_keyboard_map_normal, at_keyboard_map_shift);
+  free (at_file);
+
+  /* Convert and write USB layout.  */
+  memset (usb_keyboard_map_normal, 0, 128);
+  memset (usb_keyboard_map_shift, 0, 128);
+
+  usb_file = (char*) xmalloc (strlen(base_filename) + strlen(".usb") + 1); 
+  sprintf (usb_file, "%s.usb", base_filename);
+
+  for (i=0; i<128; i++)
+    {
+      usb_keyboard_map_normal[at_to_usb_map_normal[i] ] = 
+      				at_keyboard_map_normal[i];
+
+      usb_keyboard_map_shift[at_to_usb_map_shift[i] ] =
+      				at_keyboard_map_shift[i];
+    }
+
+  write_file (usb_file, usb_keyboard_map_normal, usb_keyboard_map_shift);
+  free (usb_file);
+}
+
+void
+write_keymaps (char *keymap, char *file_basename)
+{
+  char at_keyboard_map_normal[128];
+  char at_keyboard_map_shift[128];
+
+  char line[2048];
+  char normal[64];
+  char shift[64];
+  int key_code;
+  pid_t pid;
+  int pipe_communication[2];
+  int ok;
+
+  FILE *fp_pipe;
+
+  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 (at_keyboard_map_normal, 0, 128);
+  memset (at_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)
+	    {
+	      at_keyboard_map_normal[key_code] = (char) get_grub_code (normal);
+	      at_keyboard_map_shift[key_code] = (char) get_grub_code (shift);
+	      ok = 1;
+	    }
+	}
+    }
+
+  add_special_keys (at_keyboard_map_normal);
+
+  if (ok == 0)
+    {
+      fprintf (stderr, "ERROR: no keycodes found. Check output of %s %s.\n",
+	       CKBCOMP, keymap);
+      exit (1);
+    }
+
+  write_files_at_usb (file_basename, at_keyboard_map_normal,
+  		      at_keyboard_map_shift);
+}
+
+int
+main (int argc, char *argv[])
+{
+  int verbosity;
+  char *file_basename = 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':
+	    file_basename = 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 (file_basename == NULL)
+    {
+      file_basename = argv[optind];
+    }
+
+  write_keymaps (argv[optind], file_basename);
+
+  return 0;
+}


             reply	other threads:[~2010-03-19 23:46 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-19 23:45 Carles Pina i Estany [this message]
  -- strict thread matches above, loose matches on Subject: below --
2011-04-22 22:34 Keyboard layouts (was Re: GRUB 1.99~rc2 released) Vladimir 'φ-coder/phcoder' Serbinenko
2011-05-23 13:22 ` Keyboard layouts Treutwein Bernhard
2010-02-09 23:23 keyboard layouts Carles Pina i Estany
2010-01-12 21:47 Carles Pina i Estany
2010-01-12 22:53 ` Colin Watson
2010-01-12 23:29   ` Carles Pina i Estany
2010-01-12 23:51     ` Colin Watson
2010-01-13  9:24 ` Yves Blusseau
2010-01-13 16:23   ` Vladimir 'φ-coder/phcoder' Serbinenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100319234517.GA29665@pina.cat \
    --to=carles@pina.cat \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.