Hi,

I've done a test, mainly to get more feedback from you.

Find it attached.

What it does:
a) It defines a new Kernel symbol to be used from at_keyboard.c and from
the new module keyboard_layouts.

b) When the new module "wants" it changes the active keyboard_layouts.

Big question:
* How to deal with USB keyboards? One option would be to add a middle
layer who receive some Grub key code and layouts are based on this
level. I have not looked into it yet

(doing some tests I renamed somethiing in the USB module, this is just a
test to avoid some clashes before)

If the proof of concept approach is the correct one I would define and
export a structure who would have the keymap and keymap_shift, instead
of having to export one variable per thing. Plus will be more scalable
for dead keys.

When this looks fine, my idea is to use the output of ckbcomp to prepare
the files that will be in /boot/grub/layouts and that Grub (the new
module) will read easily. Something like grub-mklayouts. 

I will think and implement other fancy things that we would need, like
changing between keyboards easily. I just want to go step by step and
maybe have something for trunk soon.

Now (only for some time) and tomorrow I'll be on the IRC, so feel free
to comment here (better for archiving) or there (better for questions
and answers).

Thanks,

-- 
Carles Pina i Estany
        http://pinux.info
=== modified file 'conf/common.rmk'
--- conf/common.rmk	2010-01-14 14:04:44 +0000
+++ conf/common.rmk	2010-01-17 01:12:20 +0000
@@ -647,6 +647,12 @@ gettext_mod_SOURCES = gettext/gettext.c
 gettext_mod_CFLAGS = $(COMMON_CFLAGS)
 gettext_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For keyboard_layouts.mod
+pkglib_MODULES += keyboard_layouts.mod
+keyboard_layouts_mod_SOURCES = keyboard_layouts/keyboard_layouts.c
+keyboard_layouts_mod_CFLAGS = $(COMMON_CFLAGS)
+keyboard_layouts_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # Misc.
 pkglib_MODULES += xnu_uuid.mod
 

=== modified file 'include/grub/term.h'
--- include/grub/term.h	2010-01-09 22:42:17 +0000
+++ include/grub/term.h	2010-01-17 01:16:32 +0000
@@ -197,6 +197,7 @@ extern struct grub_term_output *EXPORT_V
 extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled);
 extern struct grub_term_output *EXPORT_VAR(grub_term_outputs);
 extern struct grub_term_input *EXPORT_VAR(grub_term_inputs);
+extern char *EXPORT_VAR(grub_keyboard_map);
 
 static inline void
 grub_term_register_input (const char *name __attribute__ ((unused)),

=== modified file 'kern/term.c'
--- kern/term.c	2009-12-27 21:35:40 +0000
+++ kern/term.c	2010-01-17 01:17:34 +0000
@@ -30,6 +30,8 @@ struct grub_term_input *grub_term_inputs
 
 void (*grub_newline_hook) (void) = NULL;
 
+char* grub_keyboard_map = NULL;
+
 /* Put a Unicode character.  */
 void
 grub_putcode (grub_uint32_t code, struct grub_term_output *term)

=== added directory 'keyboard_layouts'
=== added file 'keyboard_layouts/keyboard_layouts.c'
--- keyboard_layouts/keyboard_layouts.c	1970-01-01 00:00:00 +0000
+++ keyboard_layouts/keyboard_layouts.c	2010-01-17 01:12:31 +0000
@@ -0,0 +1,36 @@
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/file.h>
+#include <grub/kernel.h>
+#include <grub/i18n.h>
+
+#include <grub/term.h>
+
+static grub_err_t
+grub_cmd_load_keyboardlayout (grub_command_t cmd __attribute__ ((unused)),
+			      int argc, char **args)
+{
+  if (argc != 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "usage: load_keyboard layout");
+
+  grub_printf ("Load layout %s", args[0]);
+  
+  grub_keyboard_map [2] = 'X';	/* '1' is 'X'.  */
+  return 0;
+}
+
+GRUB_MOD_INIT (keyboard_layouts)
+{
+  grub_register_command_p1 ("load_keyboard", grub_cmd_load_keyboardlayout,
+  			    N_("layout"),
+			    N_("Set ups the new layout."));
+}
+
+GRUB_MOD_FINI (keyboard_layouts)
+{
+  /* TODO: Restore the default layout.  */
+}

=== modified file 'term/i386/pc/at_keyboard.c'
--- term/i386/pc/at_keyboard.c	2010-01-09 22:42:17 +0000
+++ term/i386/pc/at_keyboard.c	2010-01-17 00:59:51 +0000
@@ -22,6 +22,7 @@
 #include <grub/i386/io.h>
 #include <grub/misc.h>
 #include <grub/term.h>
+#include <grub/mm.h>
 
 static short at_keyboard_status = 0;
 
@@ -40,7 +41,7 @@ static grub_uint8_t led_status;
 #define KEYBOARD_LED_NUM		(1 << 1)
 #define KEYBOARD_LED_CAPS		(1 << 2)
 
-static char keyboard_map[128] =
+static char keyboard_map_default[128] =
 {
   '\0', GRUB_TERM_ESC, '1', '2', '3', '4', '5', '6',
   '7', '8', '9', '0', '-', '=', GRUB_TERM_BACKSPACE, GRUB_TERM_TAB,
@@ -213,12 +214,12 @@ grub_at_keyboard_getkey_noblock (void)
 	break;
       default:
 	if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R))
-	  key = keyboard_map[code] - 'a' + 1;
+	  key = grub_keyboard_map[code] - 'a' + 1;
 	else if ((at_keyboard_status & (KEYBOARD_STATUS_SHIFT_L | KEYBOARD_STATUS_SHIFT_R))
 	    && keyboard_map_shift[code])
 	  key = keyboard_map_shift[code];
 	else
-	  key = keyboard_map[code];
+	  key = grub_keyboard_map[code];
 
 	if (key == 0)
 	  grub_dprintf ("atkeyb", "Unknown key 0x%x detected\n", code);
@@ -279,6 +280,8 @@ static struct grub_term_input grub_at_ke
 GRUB_MOD_INIT(at_keyboard)
 {
   grub_term_register_input ("at_keyboard", &grub_at_keyboard_term);
+
+  grub_keyboard_map = keyboard_map_default;
 }
 
 GRUB_MOD_FINI(at_keyboard)

=== modified file 'term/usb_keyboard.c'
--- term/usb_keyboard.c	2009-11-23 15:31:54 +0000
+++ term/usb_keyboard.c	2010-01-16 21:15:46 +0000
@@ -28,7 +28,7 @@
 #include <grub/time.h>
 
 
-static char keyboard_map[128] =
+static char keyboard_map_usb[128] =
   {
     '\0', '\0', '\0', '\0', 'a', 'b', 'c', 'd',
     'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
@@ -152,11 +152,11 @@ grub_usb_keyboard_checkkey (void)
 
   /* Check if the Control or Shift key was pressed.  */
   if (data[0] & 0x01 || data[0] & 0x10)
-    key = keyboard_map[data[2]] - 'a' + 1;
+    key = keyboard_map_usb[data[2]] - 'a' + 1;
   else if (data[0] & 0x02 || data[0] & 0x20)
     key = keyboard_map_shift[data[2]];
   else
-    key = keyboard_map[data[2]];
+    key = keyboard_map_usb[data[2]];
 
   if (key == 0)
     grub_printf ("Unknown key 0x%x detected\n", data[2]);

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to