All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] terminal split
@ 2008-11-02 18:11 Robert Millan
  2008-11-04 15:52 ` Yoshinori K. Okuji
  2008-11-04 18:53 ` Vesa Jääskeläinen
  0 siblings, 2 replies; 19+ messages in thread
From: Robert Millan @ 2008-11-02 18:11 UTC (permalink / raw)
  To: grub-devel

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


Hi,

This patch splits terminal handling in input and output.  While at it, it
resolves/removes some of the kludges we had to work around this limitation.

For example, gfxterm/vga no longer need to assume the input is bios console,
at_keyboard can be used in combination with any output terminal, etc.

It will also be possible to turn vga_text.c into a standalone output term,
but this needs more work since it is currently sharing much code with the
bios console in console.c.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."

[-- Attachment #2: terminal_split.diff --]
[-- Type: text/x-diff, Size: 36250 bytes --]

Index: conf/i386.rmk
===================================================================
--- conf/i386.rmk	(revision 1891)
+++ conf/i386.rmk	(working copy)
@@ -1,8 +1,11 @@
 # -*- makefile -*-
 
 pkglib_MODULES += cpuid.mod
-
-# For cpuid.mod.
 cpuid_mod_SOURCES = commands/i386/cpuid.c
 cpuid_mod_CFLAGS = $(COMMON_CFLAGS)
 cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += at_keyboard.mod
+at_keyboard_mod_SOURCES = term/i386/pc/at_keyboard.c
+at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
+at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
Index: conf/i386-ieee1275.rmk
===================================================================
--- conf/i386-ieee1275.rmk	(revision 1891)
+++ conf/i386-ieee1275.rmk	(working copy)
@@ -22,7 +22,7 @@
 	kern/time.c \
 	kern/generic/millisleep.c \
 	kern/ieee1275/ieee1275.c \
-	term/ieee1275/ofconsole.c term/i386/pc/at_keyboard.c \
+	term/ieee1275/ofconsole.c \
 	disk/ieee1275/ofdisk.c \
 	symlist.c
 kernel_elf_HEADERS = arg.h cache.h device.h disk.h dl.h elf.h elfload.h \
Index: kern/ieee1275/init.c
===================================================================
--- kern/ieee1275/init.c	(revision 1891)
+++ kern/ieee1275/init.c	(working copy)
@@ -217,7 +217,6 @@
   grub_console_init ();
 #ifdef __i386__
   grub_get_extended_memory ();
-  grub_keyboard_controller_init ();
 #endif
   grub_claim_heap ();
   grub_ofdisk_init ();
Index: kern/term.c
===================================================================
--- kern/term.c	(revision 1891)
+++ kern/term.c	(working copy)
@@ -23,10 +23,12 @@
 #include <grub/env.h>
 
 /* The list of terminals.  */
-static grub_term_t grub_term_list;
+static grub_term_input_t grub_term_list_input;
+static grub_term_output_t grub_term_list_output;
 
 /* The current terminal.  */
-static grub_term_t grub_cur_term;
+static grub_term_input_t grub_cur_term_input;
+static grub_term_output_t grub_cur_term_output;
 
 /* The amount of lines counted by the pager.  */
 static int grub_more_lines;
@@ -38,18 +40,25 @@
 static int cursor_state = 1;
 
 void
-grub_term_register (grub_term_t term)
+grub_term_register_input (grub_term_input_t term)
 {
-  term->next = grub_term_list;
-  grub_term_list = term;
+  term->next = grub_term_list_input;
+  grub_term_list_input = term;
 }
 
 void
-grub_term_unregister (grub_term_t term)
+grub_term_register_output (grub_term_output_t term)
 {
-  grub_term_t *p, q;
+  term->next = grub_term_list_output;
+  grub_term_list_output = term;
+}
+
+void
+grub_term_unregister_input (grub_term_input_t term)
+{
+  grub_term_input_t *p, q;
   
-  for (p = &grub_term_list, q = *p; q; p = &(q->next), q = q->next)
+  for (p = &grub_term_list_input, q = *p; q; p = &(q->next), q = q->next)
     if (q == term)
       {
         *p = q->next;
@@ -58,45 +67,87 @@
 }
 
 void
-grub_term_iterate (int (*hook) (grub_term_t term))
+grub_term_unregister_output (grub_term_output_t term)
 {
-  grub_term_t p;
+  grub_term_output_t *p, q;
   
-  for (p = grub_term_list; p; p = p->next)
+  for (p = &grub_term_list_output, q = *p; q; p = &(q->next), q = q->next)
+    if (q == term)
+      {
+        *p = q->next;
+	break;
+      }
+}
+
+void
+grub_term_iterate_input (int (*hook) (grub_term_input_t term))
+{
+  grub_term_input_t p;
+  
+  for (p = grub_term_list_input; p; p = p->next)
     if (hook (p))
       break;
 }
 
+void
+grub_term_iterate_output (int (*hook) (grub_term_output_t term))
+{
+  grub_term_output_t p;
+  
+  for (p = grub_term_list_output; p; p = p->next)
+    if (hook (p))
+      break;
+}
+
 grub_err_t
-grub_term_set_current (grub_term_t term)
+grub_term_set_current_input (grub_term_input_t term)
 {
-  if (grub_cur_term && grub_cur_term->fini)
-    if ((grub_cur_term->fini) () != GRUB_ERR_NONE)
+  if (grub_cur_term_input && grub_cur_term_input->fini)
+    if ((grub_cur_term_input->fini) () != GRUB_ERR_NONE)
       return grub_errno;
 
   if (term->init)
     if ((term->init) () != GRUB_ERR_NONE)
       return grub_errno;
   
-  grub_cur_term = term;
-  grub_cls ();
-  grub_setcursor (grub_getcursor ());
+  grub_cur_term_input = term;
   return GRUB_ERR_NONE;
 }
 
-grub_term_t
-grub_term_get_current (void)
+grub_err_t
+grub_term_set_current_output (grub_term_output_t term)
 {
-  return grub_cur_term;
+  if (grub_cur_term_output && grub_cur_term_output->fini)
+    if ((grub_cur_term_output->fini) () != GRUB_ERR_NONE)
+      return grub_errno;
+
+  if (term->init)
+    if ((term->init) () != GRUB_ERR_NONE)
+      return grub_errno;
+  
+  grub_cur_term_output = term;
+  return GRUB_ERR_NONE;
 }
 
+grub_term_input_t
+grub_term_get_current_input (void)
+{
+  return grub_cur_term_input;
+}
+
+grub_term_output_t
+grub_term_get_current_output (void)
+{
+  return grub_cur_term_output;
+}
+
 /* Put a Unicode character.  */
 void
 grub_putcode (grub_uint32_t code)
 {
   int height = grub_getwh () & 255;
 
-  if (code == '\t' && grub_cur_term->getxy)
+  if (code == '\t' && grub_cur_term_output->getxy)
     {
       int n;
       
@@ -107,7 +158,7 @@
       return;
     }
   
-  (grub_cur_term->putchar) (code);
+  (grub_cur_term_output->putchar) (code);
   
   if (code == '\n')
     {
@@ -171,70 +222,70 @@
 grub_ssize_t
 grub_getcharwidth (grub_uint32_t code)
 {
-  return (grub_cur_term->getcharwidth) (code);
+  return (grub_cur_term_output->getcharwidth) (code);
 }
 
 int
 grub_getkey (void)
 {
-  return (grub_cur_term->getkey) ();
+  return (grub_cur_term_input->getkey) ();
 }
 
 int
 grub_checkkey (void)
 {
-  return (grub_cur_term->checkkey) ();
+  return (grub_cur_term_input->checkkey) ();
 }
 
 grub_uint16_t
 grub_getxy (void)
 {
-  return (grub_cur_term->getxy) ();
+  return (grub_cur_term_output->getxy) ();
 }
 
 grub_uint16_t
 grub_getwh (void)
 {
-  return (grub_cur_term->getwh) ();
+  return (grub_cur_term_output->getwh) ();
 }
 
 void
 grub_gotoxy (grub_uint8_t x, grub_uint8_t y)
 {
-  (grub_cur_term->gotoxy) (x, y);
+  (grub_cur_term_output->gotoxy) (x, y);
 }
 
 void
 grub_cls (void)
 {
-  if ((grub_cur_term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
+  if ((grub_cur_term_output->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
     {
       grub_putchar ('\n');
       grub_refresh ();
     }
   else
-    (grub_cur_term->cls) ();
+    (grub_cur_term_output->cls) ();
 }
 
 void
 grub_setcolorstate (grub_term_color_state state)
 {
-  if (grub_cur_term->setcolorstate)
-    (grub_cur_term->setcolorstate) (state);
+  if (grub_cur_term_output->setcolorstate)
+    (grub_cur_term_output->setcolorstate) (state);
 }
 
 void
 grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
 {
-  if (grub_cur_term->setcolor)
-    (grub_cur_term->setcolor) (normal_color, highlight_color);
+  if (grub_cur_term_output->setcolor)
+    (grub_cur_term_output->setcolor) (normal_color, highlight_color);
 }
 
 void
 grub_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
 {
-  if (grub_cur_term->getcolor)
-    (grub_cur_term->getcolor) (normal_color, highlight_color);
+  if (grub_cur_term_output->getcolor)
+    (grub_cur_term_output->getcolor) (normal_color, highlight_color);
 }
 
 int
@@ -242,9 +293,9 @@
 {
   int ret = cursor_state;
 
-  if (grub_cur_term->setcursor)
+  if (grub_cur_term_output->setcursor)
     {
-      (grub_cur_term->setcursor) (on);
+      (grub_cur_term_output->setcursor) (on);
       cursor_state = on;
     }
   
@@ -260,8 +311,8 @@
 void
 grub_refresh (void)
 {
-  if (grub_cur_term->refresh)
-    (grub_cur_term->refresh) ();
+  if (grub_cur_term_output->refresh)
+    (grub_cur_term_output->refresh) ();
 }
 
 void
Index: kern/i386/coreboot/init.c
===================================================================
--- kern/i386/coreboot/init.c	(revision 1891)
+++ kern/i386/coreboot/init.c	(working copy)
@@ -138,6 +138,7 @@
   grub_upper_mem -= GRUB_MEMORY_MACHINE_UPPER_START;
 
   grub_tsc_init ();
+  grub_at_keyboard_init ();
 }
 
 void
Index: kern/misc.c
===================================================================
--- kern/misc.c	(revision 1891)
+++ kern/misc.c	(working copy)
@@ -1026,9 +1026,12 @@
 void
 grub_abort (void)
 {
-  if (grub_term_get_current ())
+  if (grub_term_get_current_output ())
+    grub_printf ("\nAborted.");
+
+  if (grub_term_get_current_input ())
     {
-      grub_printf ("\nAborted. Press any key to exit.");
+      grub_printf (" Press any key to exit.");
       grub_getkey ();
     }
 
Index: include/grub/term.h
===================================================================
--- include/grub/term.h	(revision 1891)
+++ include/grub/term.h	(working copy)
@@ -137,7 +137,7 @@
                                  - 1)
 
 
-struct grub_term
+struct grub_term_input
 {
   /* The terminal name.  */
   const char *name;
@@ -148,6 +148,28 @@
   /* Clean up the terminal.  */
   grub_err_t (*fini) (void);
   
+  /* Check if any input character is available.  */
+  int (*checkkey) (void);
+  
+  /* Get a character.  */
+  int (*getkey) (void);
+
+  /* The next terminal.  */
+  struct grub_term_input *next;
+};
+typedef struct grub_term_input *grub_term_input_t;
+
+struct grub_term_output
+{
+  /* The terminal name.  */
+  const char *name;
+
+  /* Initialize the terminal.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the terminal.  */
+  grub_err_t (*fini) (void);
+  
   /* Put a character. C is encoded in Unicode.  */
   void (*putchar) (grub_uint32_t c);
 
@@ -155,12 +177,6 @@
      encoded in Unicode.  */
   grub_ssize_t (*getcharwidth) (grub_uint32_t c);
   
-  /* Check if any input character is available.  */
-  int (*checkkey) (void);
-  
-  /* Get a character.  */
-  int (*getkey) (void);
-  
   /* Get the screen size. The return value is ((Width << 8) | Height).  */
   grub_uint16_t (*getwh) (void);
 
@@ -194,16 +210,21 @@
   grub_uint32_t flags;
   
   /* The next terminal.  */
-  struct grub_term *next;
+  struct grub_term_output *next;
 };
-typedef struct grub_term *grub_term_t;
+typedef struct grub_term_output *grub_term_output_t;
 
-void EXPORT_FUNC(grub_term_register) (grub_term_t term);
-void EXPORT_FUNC(grub_term_unregister) (grub_term_t term);
-void EXPORT_FUNC(grub_term_iterate) (int (*hook) (grub_term_t term));
+void EXPORT_FUNC(grub_term_register_input) (grub_term_input_t term);
+void EXPORT_FUNC(grub_term_register_output) (grub_term_output_t term);
+void EXPORT_FUNC(grub_term_unregister_input) (grub_term_input_t term);
+void EXPORT_FUNC(grub_term_unregister_output) (grub_term_output_t term);
+void EXPORT_FUNC(grub_term_iterate_input) (int (*hook) (grub_term_input_t term));
+void EXPORT_FUNC(grub_term_iterate_output) (int (*hook) (grub_term_output_t term));
 
-grub_err_t EXPORT_FUNC(grub_term_set_current) (grub_term_t term);
-grub_term_t EXPORT_FUNC(grub_term_get_current) (void);
+grub_err_t EXPORT_FUNC(grub_term_set_current_input) (grub_term_input_t term);
+grub_err_t EXPORT_FUNC(grub_term_set_current_output) (grub_term_output_t term);
+grub_term_input_t EXPORT_FUNC(grub_term_get_current_input) (void);
+grub_term_output_t EXPORT_FUNC(grub_term_get_current_output) (void);
 
 void EXPORT_FUNC(grub_putchar) (int c);
 void EXPORT_FUNC(grub_putcode) (grub_uint32_t code);
Index: include/grub/i386/ieee1275/console.h
===================================================================
--- include/grub/i386/ieee1275/console.h	(revision 1891)
+++ include/grub/i386/ieee1275/console.h	(working copy)
@@ -21,10 +21,6 @@
 
 #include <grub/symbol.h>
 
-void EXPORT_FUNC(grub_keyboard_controller_init) (void);
-int EXPORT_FUNC(grub_console_checkkey) (void);
-int EXPORT_FUNC(grub_console_getkey) (void);
-
 /* Initialize the console system.  */
 void grub_console_init (void);
 
Index: include/grub/i386/pc/console.h
===================================================================
--- include/grub/i386/pc/console.h	(revision 1891)
+++ include/grub/i386/pc/console.h	(working copy)
@@ -40,8 +40,8 @@
 /* These are global to share code between C and asm.  */
 extern grub_uint8_t grub_console_cur_color;
 void grub_console_real_putchar (int c);
-int EXPORT_FUNC(grub_console_checkkey) (void);
-int EXPORT_FUNC(grub_console_getkey) (void);
+int grub_console_checkkey (void);
+int grub_console_getkey (void);
 grub_uint16_t grub_console_getxy (void);
 void grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y);
 void grub_console_cls (void);
Index: include/grub/i386/coreboot/console.h
===================================================================
--- include/grub/i386/coreboot/console.h	(revision 1891)
+++ include/grub/i386/coreboot/console.h	(working copy)
@@ -1,25 +1 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  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_CONSOLE_MACHINE_LB_HEADER
-#define _GRUB_CONSOLE_MACHINE_LB_HEADER 1
 #include <grub/i386/pc/console.h>
-
-void grub_keyboard_controller_init (void);
-
-#endif /* ! _GRUB_CONSOLE_MACHINE_LB_HEADER */
Index: commands/terminal.c
===================================================================
--- commands/terminal.c	(revision 1891)
+++ commands/terminal.c	(working copy)
@@ -24,21 +24,21 @@
 #include <grub/term.h>
 
 static grub_err_t
-grub_cmd_terminal (struct grub_arg_list *state __attribute__ ((unused)),
-		   int argc, char **args)
+grub_cmd_terminal_input (struct grub_arg_list *state __attribute__ ((unused)),
+			 int argc, char **args)
 {
-  grub_term_t term = 0;
+  grub_term_input_t term = 0;
   
-  auto int print_terminal (grub_term_t);
-  auto int find_terminal (grub_term_t);
+  auto int print_terminal (grub_term_input_t);
+  auto int find_terminal (grub_term_input_t);
   
-  int print_terminal (grub_term_t t)
+  int print_terminal (grub_term_input_t t)
     {
       grub_printf (" %s", t->name);
       return 0;
     }
 
-  int find_terminal (grub_term_t t)
+  int find_terminal (grub_term_input_t t)
     {
       if (grub_strcmp (t->name, args[0]) == 0)
 	{
@@ -51,30 +51,78 @@
   
   if (argc == 0)
     {
-      grub_printf ("Available terminal(s):");
-      grub_term_iterate (print_terminal);
+      grub_printf ("Available input terminal(s):");
+      grub_term_iterate_input (print_terminal);
       grub_putchar ('\n');
       
-      grub_printf ("Current terminal: %s\n", grub_term_get_current ()->name);
+      grub_printf ("Current input terminal: %s\n", grub_term_get_current_input ()->name);
     }
   else
     {
-      grub_term_iterate (find_terminal);
+      grub_term_iterate_input (find_terminal);
       if (! term)
-	return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such terminal");
+	return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such input terminal");
 
-      grub_term_set_current (term);
+      grub_term_set_current_input (term);
     }
 
   return GRUB_ERR_NONE;
 }
 
+static grub_err_t
+grub_cmd_terminal_output (struct grub_arg_list *state __attribute__ ((unused)),
+			  int argc, char **args)
+{
+  grub_term_output_t term = 0;
+  
+  auto int print_terminal (grub_term_output_t);
+  auto int find_terminal (grub_term_output_t);
+  
+  int print_terminal (grub_term_output_t t)
+    {
+      grub_printf (" %s", t->name);
+      return 0;
+    }
+
+  int find_terminal (grub_term_output_t t)
+    {
+      if (grub_strcmp (t->name, args[0]) == 0)
+	{
+	  term = t;
+	  return 1;
+	}
+
+      return 0;
+    }
+  
+  if (argc == 0)
+    {
+      grub_printf ("Available output terminal(s):");
+      grub_term_iterate_output (print_terminal);
+      grub_putchar ('\n');
+      
+      grub_printf ("Current output terminal: %s\n", grub_term_get_current_output ()->name);
+    }
+  else
+    {
+      grub_term_iterate_output (find_terminal);
+      if (! term)
+	return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such output terminal");
+
+      grub_term_set_current_output (term);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
 \f
 GRUB_MOD_INIT(terminal)
 {
   (void)mod;			/* To stop warning. */
-  grub_register_command ("terminal", grub_cmd_terminal, GRUB_COMMAND_FLAG_BOTH,
-			 "terminal [TERM...]", "Select a terminal.", 0);
+  grub_register_command ("terminal_input", grub_cmd_terminal_input, GRUB_COMMAND_FLAG_BOTH,
+			 "terminal_input [TERM...]", "Select an input terminal.", 0);
+  grub_register_command ("terminal_output", grub_cmd_terminal_output, GRUB_COMMAND_FLAG_BOTH,
+			 "terminal_output [TERM...]", "Select an output terminal.", 0);
 }
 
 GRUB_MOD_FINI(terminal)
Index: term/efi/console.c
===================================================================
--- term/efi/console.c	(revision 1891)
+++ term/efi/console.c	(working copy)
@@ -332,15 +332,18 @@
   efi_call_2 (o->enable_cursor, o, on);
 }
 
-static struct grub_term grub_console_term =
+static struct grub_term_input grub_console_term_input =
   {
     .name = "console",
-    .init = 0,
-    .fini = 0,
+    .checkkey = grub_console_checkkey,
+    .getkey = grub_console_getkey,
+  };
+
+static struct grub_term_output grub_console_term_output =
+  {
+    .name = "console",
     .putchar = grub_console_putchar,
     .getcharwidth = grub_console_getcharwidth,
-    .checkkey = grub_console_checkkey,
-    .getkey = grub_console_getkey,
     .getwh = grub_console_getwh,
     .getxy = grub_console_getxy,
     .gotoxy = grub_console_gotoxy,
@@ -350,7 +353,6 @@
     .getcolor = grub_console_getcolor,
     .setcursor = grub_console_setcursor,
     .flags = 0,
-    .next = 0
   };
 
 void
@@ -364,12 +366,15 @@
       return;
     }
 
-  grub_term_register (&grub_console_term);
-  grub_term_set_current (&grub_console_term);
+  grub_term_register_input (&grub_console_term_input);
+  grub_term_register_output (&grub_console_term_output);
+  grub_term_set_current_output (&grub_console_term_output);
+  grub_term_set_current_input (&grub_console_term_input);
 }
 
 void
 grub_console_fini (void)
 {
-  grub_term_unregister (&grub_console_term);
+  grub_term_unregister_input (&grub_console_term_input);
+  grub_term_unregister_output (&grub_console_term_output);
 }
Index: term/ieee1275/ofconsole.c
===================================================================
--- term/ieee1275/ofconsole.c	(revision 1891)
+++ term/ieee1275/ofconsole.c	(working copy)
@@ -33,10 +33,8 @@
 static int grub_curr_x;
 static int grub_curr_y;
 
-#ifndef __i386__
 static int grub_keybuf;
 static int grub_buflen;
-#endif
 
 struct color
 {
@@ -144,7 +142,6 @@
   *highlight_color = grub_ofconsole_highlight_color;
 }
 
-#ifndef __i386__
 static int
 grub_ofconsole_readkey (int *key)
 {
@@ -342,9 +339,22 @@
 }
 
 static grub_err_t
-grub_ofconsole_init (void)
+grub_ofconsole_init_input (void)
 {
   grub_ssize_t actual;
+
+  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle,
+					  sizeof stdin_ihandle, &actual)
+      || actual != sizeof stdin_ihandle)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdin");
+
+  return 0;
+}
+
+static grub_err_t
+grub_ofconsole_init_output (void)
+{
+  grub_ssize_t actual;
   int col;
 
   /* The latest PowerMacs don't actually initialize the screen for us, so we
@@ -358,11 +368,6 @@
       || actual != sizeof stdout_ihandle)
     return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdout");
 
-  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle,
-					  sizeof stdin_ihandle, &actual)
-      || actual != sizeof stdin_ihandle)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdin");
-
   /* Initialize colors.  */
   if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS))
     {
@@ -385,20 +390,22 @@
 
 
 \f
-static struct grub_term grub_ofconsole_term =
+static struct grub_term_input grub_ofconsole_term_input =
   {
     .name = "ofconsole",
-    .init = grub_ofconsole_init,
+    .init = grub_ofconsole_init_input,
     .fini = grub_ofconsole_fini,
+    .checkkey = grub_ofconsole_checkkey,
+    .getkey = grub_ofconsole_getkey,
+  };
+
+static struct grub_term_output grub_ofconsole_term_output =
+  {
+    .name = "ofconsole",
+    .init = grub_ofconsole_init_output,
+    .fini = grub_ofconsole_fini,
     .putchar = grub_ofconsole_putchar,
     .getcharwidth = grub_ofconsole_getcharwidth,
-#ifdef __i386__
-    .checkkey = grub_console_checkkey,
-    .getkey = grub_console_getkey,
-#else
-    .checkkey = grub_ofconsole_checkkey,
-    .getkey = grub_ofconsole_getkey,
-#endif
     .getxy = grub_ofconsole_getxy,
     .getwh = grub_ofconsole_getwh,
     .gotoxy = grub_ofconsole_gotoxy,
@@ -409,18 +416,20 @@
     .setcursor = grub_ofconsole_setcursor,
     .refresh = grub_ofconsole_refresh,
     .flags = 0,
-    .next = 0
   };
 
 void
 grub_console_init (void)
 {
-  grub_term_register (&grub_ofconsole_term);
-  grub_term_set_current (&grub_ofconsole_term);
+  grub_term_register_input (&grub_ofconsole_term_input);
+  grub_term_register_output (&grub_ofconsole_term_output);
+  grub_term_set_current_output (&grub_ofconsole_term_output);
+  grub_term_set_current_input (&grub_ofconsole_term_input);
 }
 
 void
 grub_console_fini (void)
 {
-  grub_term_unregister (&grub_ofconsole_term);
+  grub_term_unregister_input (&grub_ofconsole_term_input);
+  grub_term_unregister_output (&grub_ofconsole_term_output);
 }
Index: term/i386/pc/serial.c
===================================================================
--- term/i386/pc/serial.c	(revision 1891)
+++ term/i386/pc/serial.c	(working copy)
@@ -467,15 +467,18 @@
     grub_terminfo_cursor_off ();
 }
 
-static struct grub_term grub_serial_term =
+static struct grub_term_input grub_serial_term_input =
 {
   .name = "serial",
-  .init = 0,
-  .fini = 0,
+  .checkkey = grub_serial_checkkey,
+  .getkey = grub_serial_getkey,
+};
+
+static struct grub_term_output grub_serial_term_output =
+{
+  .name = "serial",
   .putchar = grub_serial_putchar,
   .getcharwidth = grub_serial_getcharwidth,
-  .checkkey = grub_serial_checkkey,
-  .getkey = grub_serial_getkey,
   .getwh = grub_serial_getwh,
   .getxy = grub_serial_getxy,
   .gotoxy = grub_serial_gotoxy,
@@ -483,7 +486,6 @@
   .setcolorstate = grub_serial_setcolorstate,
   .setcursor = grub_serial_setcursor,
   .flags = 0,
-  .next = 0
 };
 
 \f
@@ -575,7 +577,8 @@
       /* Register terminal if not yet registered.  */
       if (registered == 0)
 	{
-	  grub_term_register (&grub_serial_term);
+	  grub_term_register_input (&grub_serial_term_input);
+	  grub_term_register_output (&grub_serial_term_output);
 	  registered = 1;
 	}
     }
@@ -590,7 +593,8 @@
 	  if (serial_hw_init () != GRUB_ERR_NONE)
 	    {
 	      /* If unable to restore settings, unregister terminal.  */
-	      grub_term_unregister (&grub_serial_term);
+	      grub_term_unregister_input (&grub_serial_term_input);
+	      grub_term_unregister_output (&grub_serial_term_output);
 	      registered = 0;
 	    }
 	}
@@ -616,5 +620,8 @@
 {
   grub_unregister_command ("serial");
   if (registered == 1)		/* Unregister terminal only if registered. */
-    grub_term_unregister (&grub_serial_term);
+    {
+      grub_term_unregister_input (&grub_serial_term_input);
+      grub_term_unregister_output (&grub_serial_term_output);
+    }
 }
Index: term/i386/pc/console.c
===================================================================
--- term/i386/pc/console.c	(revision 1891)
+++ term/i386/pc/console.c	(working copy)
@@ -125,15 +125,22 @@
   *highlight_color = grub_console_highlight_color;
 }
 
-static struct grub_term grub_console_term =
+/* On non-BIOS platforms, console.c is used in combination with vga_text.c
+   (only to handle output).  */
+#ifdef GRUB_MACHINE_PCBIOS
+static struct grub_term_input grub_console_term_input =
   {
     .name = "console",
-    .init = 0,
-    .fini = 0,
+    .checkkey = grub_console_checkkey,
+    .getkey = grub_console_getkey,
+  };
+#endif
+
+static struct grub_term_output grub_console_term_output =
+  {
+    .name = "console",
     .putchar = grub_console_putchar,
     .getcharwidth = grub_console_getcharwidth,
-    .checkkey = grub_console_checkkey,
-    .getkey = grub_console_getkey,
     .getwh = grub_console_getwh,
     .getxy = grub_console_getxy,
     .gotoxy = grub_console_gotoxy,
@@ -143,23 +150,26 @@
     .getcolor = grub_console_getcolor,
     .setcursor = grub_console_setcursor,
     .flags = 0,
-    .next = 0
   };
 
 void
 grub_console_init (void)
 {
-  grub_term_register (&grub_console_term);
-  grub_term_set_current (&grub_console_term);
-
-#ifdef GRUB_MACHINE_LINUXBIOS
-  grub_keyboard_controller_init ();
+  grub_term_register_output (&grub_console_term_output);
+  grub_term_set_current_output (&grub_console_term_output);
+#ifdef GRUB_MACHINE_PCBIOS
+  grub_term_register_input (&grub_console_term_input);
+  grub_term_set_current_input (&grub_console_term_input);
 #endif
 }
 
 void
 grub_console_fini (void)
 {
-  grub_term_set_current (&grub_console_term);
-  grub_term_unregister (&grub_console_term);
+  grub_term_set_current_output (&grub_console_term_output);
+#ifdef GRUB_MACHINE_PCBIOS
+  grub_term_set_current_input (&grub_console_term_input);
+  grub_term_unregister_input (&grub_console_term_input);
+#endif
+  grub_term_unregister_output (&grub_console_term_output);
 }
Index: term/i386/pc/at_keyboard.c
===================================================================
--- term/i386/pc/at_keyboard.c	(revision 1891)
+++ term/i386/pc/at_keyboard.c	(working copy)
@@ -16,9 +16,10 @@
  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <grub/machine/console.h>
-#include <grub/cpu/at_keyboard.h>
-#include <grub/cpu/io.h>
+#include <grub/dl.h>
+#include <grub/i386/pc/console.h>
+#include <grub/i386/at_keyboard.h>
+#include <grub/i386/io.h>
 #include <grub/misc.h>
 #include <grub/term.h>
 
@@ -61,6 +62,8 @@
   'B', 'N', 'M', '<', '>', '?'
 };
 
+static grub_uint8_t grub_keyboard_controller_orig;
+
 static void
 grub_keyboard_controller_write (grub_uint8_t c)
 {
@@ -77,12 +80,6 @@
   return grub_inb (KEYBOARD_REG_DATA);
 }
 
-void
-grub_keyboard_controller_init (void)
-{
-  grub_keyboard_controller_write (grub_keyboard_controller_read () | KEYBOARD_SCANCODE_SET1);
-}
-
 /* FIXME: This should become an interrupt service routine.  For now
    it's just used to catch events from control keys.  */
 static void
@@ -148,8 +145,8 @@
 }
 
 /* If there is a character pending, return it; otherwise return -1.  */
-int
-grub_console_checkkey (void)
+static int
+grub_at_keyboard_checkkey (void)
 {
   int code, key;
   code = grub_keyboard_getkey ();
@@ -192,13 +189,47 @@
   return (int) key;
 }
 
-int
-grub_console_getkey (void)
+static int
+grub_at_keyboard_getkey (void)
 {
   int key;
   do
     {
-      key = grub_console_checkkey ();
+      key = grub_at_keyboard_checkkey ();
     } while (key == -1);
   return key;
 }
+
+static grub_err_t
+grub_keyboard_controller_init (void)
+{
+  grub_keyboard_controller_orig = grub_keyboard_controller_read ();
+  grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_keyboard_controller_fini (void)
+{
+  grub_keyboard_controller_write (grub_keyboard_controller_orig);
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_term_input grub_at_keyboard_term =
+  {
+    .name = "at_keyboard",
+    .init = grub_keyboard_controller_init,
+    .fini = grub_keyboard_controller_fini,
+    .checkkey = grub_at_keyboard_checkkey,
+    .getkey = grub_at_keyboard_getkey,
+  };
+
+GRUB_MOD_INIT(at_keyboard)
+{
+  grub_term_register_input (&grub_at_keyboard_term);
+}
+
+GRUB_MOD_FINI(at_keyboard)
+{
+  grub_term_unregister_output (&grub_at_keyboard_term);
+}
Index: term/i386/pc/vga.c
===================================================================
--- term/i386/pc/vga.c	(revision 1891)
+++ term/i386/pc/vga.c	(working copy)
@@ -473,15 +473,13 @@
     }
 }
 
-static struct grub_term grub_vga_term =
+static struct grub_term_output grub_vga_term =
   {
     .name = "vga",
     .init = grub_vga_mod_init,
     .fini = grub_vga_mod_fini,
     .putchar = grub_vga_putchar,
     .getcharwidth = grub_vga_getcharwidth,
-    .checkkey = grub_console_checkkey,
-    .getkey = grub_console_getkey,
     .getwh = grub_vga_getwh,
     .getxy = grub_vga_getxy,
     .gotoxy = grub_vga_gotoxy,
@@ -489,7 +487,6 @@
     .setcolorstate = grub_vga_setcolorstate,
     .setcursor = grub_vga_setcursor,
     .flags = 0,
-    .next = 0
   };
 
 GRUB_MOD_INIT(vga)
@@ -497,10 +494,10 @@
 #ifndef GRUB_UTIL
   my_mod = mod;
 #endif
-  grub_term_register (&grub_vga_term);
+  grub_term_register_output (&grub_vga_term);
 }
 
 GRUB_MOD_FINI(vga)
 {
-  grub_term_unregister (&grub_vga_term);
+  grub_term_unregister_output (&grub_vga_term);
 }
Index: term/gfxterm.c
===================================================================
--- term/gfxterm.c	(revision 1891)
+++ term/gfxterm.c	(working copy)
@@ -1056,15 +1056,13 @@
   return grub_errno;
 }
 
-static struct grub_term grub_video_term =
+static struct grub_term_output grub_video_term =
   {
     .name = "gfxterm",
     .init = grub_gfxterm_init,
     .fini = grub_gfxterm_fini,
     .putchar = grub_gfxterm_putchar,
     .getcharwidth = grub_gfxterm_getcharwidth,
-    .checkkey = grub_console_checkkey,
-    .getkey = grub_console_getkey,
     .getwh = grub_virtual_screen_getwh,
     .getxy = grub_virtual_screen_getxy,
     .gotoxy = grub_gfxterm_gotoxy,
@@ -1081,7 +1079,7 @@
 GRUB_MOD_INIT(term_gfxterm)
 {
   my_mod = mod;
-  grub_term_register (&grub_video_term);
+  grub_term_register_output (&grub_video_term);
 
   grub_register_command ("background_image",
                          grub_gfxterm_background_image_cmd,
@@ -1094,5 +1092,5 @@
 GRUB_MOD_FINI(term_gfxterm)
 {
   grub_unregister_command ("bgimage");
-  grub_term_unregister (&grub_video_term);
+  grub_term_unregister_output (&grub_video_term);
 }
Index: util/grub.d/00_header.in
===================================================================
--- util/grub.d/00_header.in	(revision 1891)
+++ util/grub.d/00_header.in	(working copy)
@@ -40,8 +40,31 @@
 set timeout=${GRUB_TIMEOUT}
 EOF
 
-case x${GRUB_TERMINAL} in
-  xgfxterm)
+case ${GRUB_TERMINAL_INPUT}:${GRUB_TERMINAL_OUTPUT} in
+  serial:* | *: serial)
+    if ! test -e ${grub_prefix}/serial.mod ; then
+      echo "Serial terminal not available on this platform." >&2 ; exit 1
+    fi
+
+    if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then
+      echo "Warning, requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used." >&2
+      GRUB_SERIAL_COMMAND=serial
+    fi
+    echo "${GRUB_SERIAL_COMMAND}"
+  ;;
+esac
+
+case x${GRUB_TERMINAL_INPUT} in
+  x)
+    # Just use the native terminal
+  ;;
+  x*)
+    echo "terminal_input ${GRUB_TERMINAL_INPUT}"
+  ;;
+esac
+
+case x${GRUB_TERMINAL_OUTPUT} in
+ xgfxterm)
     # Make the font accessible
     prepare_grub_to_access_device `${grub_probe} --target=device ${GRUB_FONT_PATH}`
 
@@ -62,26 +85,14 @@
   set gfxmode=${GRUB_GFXMODE}
   insmod gfxterm
   insmod ${video_backend}
-  terminal gfxterm
+  terminal_output gfxterm
 fi
 EOF
   ;;
-  xserial)
-    if ! test -e ${grub_prefix}/serial.mod ; then
-      echo "Serial terminal not available on this platform." >&2 ; exit 1
-    fi
-
-    if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then
-      echo "Warning, requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used." >&2
-      GRUB_SERIAL_COMMAND=serial
-    fi
-    echo "${GRUB_SERIAL_COMMAND}"
-    echo "terminal serial"
-  ;;
   x)
     # Just use the native terminal
   ;;
   x*)
-    echo "terminal ${GRUB_TERMINAL}"
+    echo "terminal_output ${GRUB_TERMINAL_OUTPUT}"
   ;;
 esac
Index: util/console.c
===================================================================
--- util/console.c	(revision 1891)
+++ util/console.c	(working copy)
@@ -371,7 +371,8 @@
 grub_console_init (void)
 {
   grub_term_register (&grub_ncurses_term);
-  grub_term_set_current (&grub_ncurses_term);
+  grub_term_set_current_input (&grub_ncurses_term);
+  grub_term_set_current_output (&grub_ncurses_term);
 }
 
 void
Index: util/grub-probe.c
===================================================================
--- util/grub-probe.c	(revision 1891)
+++ util/grub-probe.c	(working copy)
@@ -66,12 +66,18 @@
   return -1;
 }
 
-grub_term_t
-grub_term_get_current (void)
+grub_term_input_t
+grub_term_get_current_input (void)
 {
   return 0;
 }
 
+grub_term_output_t
+grub_term_get_current_output (void)
+{
+  return 0;
+}
+
 void
 grub_refresh (void)
 {
Index: util/grub-fstest.c
===================================================================
--- util/grub-fstest.c	(revision 1891)
+++ util/grub-fstest.c	(working copy)
@@ -54,11 +54,17 @@
 }
 
 grub_term_t
-grub_term_get_current (void)
+grub_term_get_current_input (void)
 {
   return 0;
 }
 
+grub_term_t
+grub_term_get_current_output (void)
+{
+  return 0;
+}
+
 void
 grub_refresh (void)
 {
Index: util/i386/pc/grub-setup.c
===================================================================
--- util/i386/pc/grub-setup.c	(revision 1891)
+++ util/i386/pc/grub-setup.c	(working copy)
@@ -74,12 +74,18 @@
   return -1;
 }
 
-grub_term_t
-grub_term_get_current (void)
+grub_term_input_t
+grub_term_get_current_input (void)
 {
   return 0;
 }
 
+grub_term_output_t
+grub_term_get_current_output (void)
+{
+  return 0;
+}
+
 void
 grub_refresh (void)
 {
Index: util/grub-mkconfig.in
===================================================================
--- util/grub-mkconfig.in	(revision 1891)
+++ util/grub-mkconfig.in	(working copy)
@@ -130,31 +130,37 @@
   . ${sysconfdir}/default/grub
 fi
 
-case x${GRUB_TERMINAL} in
+# XXX: should this be deprecated at some point?
+if [ "x${GRUB_TERMINAL}" != "x" ] ; then
+  GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}"
+  GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}"
+fi
+
+case x${GRUB_TERMINAL_OUTPUT} in
   x)
     # If this platform supports gfxterm, try to use it.
     if test -e ${grub_prefix}/gfxterm.mod ; then
-      GRUB_TERMINAL=gfxterm
+      GRUB_TERMINAL_OUTPUT=gfxterm
     fi
   ;;
   xconsole | xserial | xofconsole | xgfxterm) ;;
-  *) echo "Invalid terminal \"${GRUB_TERMINAL}\"" >&2 ; exit 1 ;;
+  *) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;;
 esac
 
 # check for terminals that require fonts
-case ${GRUB_TERMINAL} in
+case ${GRUB_TERMINAL_OUTPUT} in
   gfxterm)
     if path=`font_path` ; then
       GRUB_FONT_PATH="${path}"
     else
       # fallback to the native terminal for this platform
-      unset GRUB_TERMINAL
+      unset GRUB_TERMINAL_OUTPUT
     fi
   ;;
 esac
 
 # does our terminal support utf-8 ?
-case ${GRUB_TERMINAL} in
+case ${GRUB_TERMINAL_OUTPUT} in
   gfxterm) ;;
   *)
     # make sure all our children behave in conformance with ascii..
@@ -167,7 +173,7 @@
 export GRUB_DEVICE GRUB_DEVICE_UUID GRUB_DEVICE_BOOT GRUB_DEVICE_BOOT_UUID GRUB_FS GRUB_FONT_PATH GRUB_PRELOAD_MODULES
 
 # These are optional, user-defined variables.
-export GRUB_DEFAULT GRUB_TIMEOUT GRUB_DISTRIBUTOR GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT GRUB_TERMINAL GRUB_SERIAL_COMMAND GRUB_DISABLE_LINUX_UUID GRUB_GFXMODE
+export GRUB_DEFAULT GRUB_TIMEOUT GRUB_DISTRIBUTOR GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT GRUB_TERMINAL_OUTPUT GRUB_SERIAL_COMMAND GRUB_DISABLE_LINUX_UUID GRUB_GFXMODE
 
 if test "x${grub_cfg}" != "x"; then
   rm -f ${grub_cfg}.new
Index: util/grub-editenv.c
===================================================================
--- util/grub-editenv.c	(revision 1891)
+++ util/grub-editenv.c	(working copy)
@@ -41,11 +41,17 @@
 }
 
 void *
-grub_term_get_current (void)
+grub_term_get_current_input (void)
 {
   return 0;
 }
 
+void *
+grub_term_get_current_output (void)
+{
+  return 0;
+}
+
 int
 grub_getkey (void)
 {

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-02 18:11 [PATCH] terminal split Robert Millan
@ 2008-11-04 15:52 ` Yoshinori K. Okuji
  2008-11-04 17:14   ` Robert Millan
  2008-11-04 18:31   ` Vesa Jääskeläinen
  2008-11-04 18:53 ` Vesa Jääskeläinen
  1 sibling, 2 replies; 19+ messages in thread
From: Yoshinori K. Okuji @ 2008-11-04 15:52 UTC (permalink / raw)
  To: The development of GRUB 2

On Sunday 02 November 2008 19:11:32 Robert Millan wrote:
> Hi,
>
> This patch splits terminal handling in input and output.  While at it, it
> resolves/removes some of the kludges we had to work around this limitation.
>
> For example, gfxterm/vga no longer need to assume the input is bios
> console, at_keyboard can be used in combination with any output terminal,
> etc.
>
> It will also be possible to turn vga_text.c into a standalone output term,
> but this needs more work since it is currently sharing much code with the
> bios console in console.c.

No ChangeLog?

The idea is good. I agree with your patch, basically. I can review it more 
seriously, once you write up ChangeLog entries.

BTW, I would like to obtain the capability of handling pipes, so that we can, 
say, "help | more". I guess you have the same idea in your mind. This should 
be trivial, once the input and output are separate, right?

Regards,
Okuji



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-04 15:52 ` Yoshinori K. Okuji
@ 2008-11-04 17:14   ` Robert Millan
  2008-11-06 17:05     ` Yoshinori K. Okuji
  2008-11-04 18:31   ` Vesa Jääskeläinen
  1 sibling, 1 reply; 19+ messages in thread
From: Robert Millan @ 2008-11-04 17:14 UTC (permalink / raw)
  To: The development of GRUB 2

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

On Tue, Nov 04, 2008 at 04:52:20PM +0100, Yoshinori K. Okuji wrote:
> 
> No ChangeLog?

Here.  I ommitted it because I wanted to see if it would need big
adjustments first.

> BTW, I would like to obtain the capability of handling pipes, so that we can, 
> say, "help | more". I guess you have the same idea in your mind.

Actually, I didn't think about this possibility.  My goal was to simplify
things on the backend side, so many of the quirks we have can be removed
(some examples in my previous mail), and we can integrate USB keyboard
support cleanly.

> This should 
> be trivial, once the input and output are separate, right?

Well, I suppose one could write a "pipe" output terminal that stores output
in a buffer, and then a "pipe" input terminal that reads from it.  My code
probably makes pipes easier, but I don't know how much is left (I assume you
don't want real pipes since that implies multi-threading).

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."

[-- Attachment #2: terminal_split.diff --]
[-- Type: text/x-diff, Size: 43297 bytes --]

2008-11-04  Robert Millan  <rmh@aybabtu.com>

	Modularize at_keyboard.mod:

	* conf/i386.rmk (pkglib_MODULES): Add `at_keyboard.mod'.
	(at_keyboard_mod_SOURCES, at_keyboard_mod_CFLAGS)
	(at_keyboard_mod_LDFLAGS): New variables.

	Actual terminal split:

	* include/grub/term.h (struct grub_term): Split in ...
	(struct grub_term_input): ... this, and ...
	(struct grub_term_output): ... this.  Update all users.
	(grub_term_set_current): Split in ...
	(grub_term_set_current_input): ... this, and ...
	(grub_term_set_current_output): ... this.
	(grub_term_get_current): Split in ...
	(grub_term_get_current_input): ... this, and ...
	(grub_term_get_current_output): ... this.
	(grub_term_register): Split in ...
	(grub_term_register_input): ... this, and ...
	(grub_term_register_output): ... this.
	(grub_term_unregister): Split in ...
	(grub_term_unregister_input): ... this, and ...
	(grub_term_unregister_output): ... this.
	(grub_term_iterate): Split in ...
	(grub_term_iterate_input): ... this, and ...
	(grub_term_iterate_output): ... this.

	* kern/term.c (grub_term_list): Split in ...
	(grub_term_list_input): ... this, and ...
	(grub_term_list_output): ... this.  Update all users.
	(grub_cur_term): Split in ...
	(grub_cur_term_input): ... this, and ...
	(grub_cur_term_output): ... this.  Update all users.
	(grub_term_set_current): Split in ...
	(grub_term_set_current_input): ... this, and ...
	(grub_term_set_current_output): ... this.
	(grub_term_get_current): Split in ...
	(grub_term_get_current_input): ... this, and ...
	(grub_term_get_current_output): ... this.
	(grub_term_register): Split in ...
	(grub_term_register_input): ... this, and ...
	(grub_term_register_output): ... this.
	(grub_term_unregister): Split in ...
	(grub_term_unregister_input): ... this, and ...
	(grub_term_unregister_output): ... this.
	(grub_term_iterate): Split in ...
	(grub_term_iterate_input): ... this, and ...
	(grub_term_iterate_output): ... this.

	* kern/misc.c (grub_abort): Split use of grub_term_get_current() into
	a check for input and one for output (and only attempt to get keys
	from user when input works).

	* util/grub-probe.c (grub_term_get_current): Split in ...
	(grub_term_get_current_input): ... this, and ...
	(grub_term_get_current_output): ... this.
	* util/grub-fstest.c: Likewise.
	* util/i386/pc/grub-setup.c: Likewise.
	* util/grub-editenv.c: Likewise.

	Portability adjustments:

	* conf/i386-ieee1275.rmk (kernel_elf_SOURCES): Remove
	`term/i386/pc/at_keyboard.c'.
	* kern/ieee1275/init.c [__i386__] (grub_machine_init): Remove call to
	grub_keyboard_controller_init() (now handled by terminal .init).
	* kern/i386/coreboot/init.c (grub_machine_init): Add call to
	grub_at_keyboard_init().
	* include/grub/i386/ieee1275/console.h (grub_keyboard_controller_init)
	(grub_console_checkkey, grub_console_getkey): Remove (now provided by
	at_keyboard.mod via input terminal interface).
	* include/grub/i386/coreboot/console.h: Convert into a stub for
	`<grub/i386/pc/console.h>'.

	Migrate full terminals to new API:

	* term/efi/console.c (grub_console_term): Split into ...
	(grub_console_term_input): ... this, and ...
	(grub_console_term_output): ... this.  Update all users.
	* term/ieee1275/ofconsole.c: Remove __i386__ hack.
	(grub_ofconsole_init): Split into ...
	(grub_ofconsole_init_input): ... this, and ...
	(grub_ofconsole_init_output): ... this.
	(grub_ofconsole_term): Split into ...
	(grub_ofconsole_term_input): ... this, and ...
	(grub_ofconsole_term_output): ... this.  Update all users.
	* term/i386/pc/serial.c (grub_serial_term): Split into ...
	(grub_serial_term_input): ... this, and ...
	(grub_serial_term_output): ... this.  Update all users.
	* term/i386/pc/console.c (grub_console_term): Split into ...
	(grub_console_term_input): ... this, and ...
	(grub_console_term_output): ... this.  Update all users.
	(grub_console_term_input): Only enable it on PC/BIOS platform.
	(grub_console_init): Remove grub_keyboard_controller_init() call.

	Migrate input terminals to new API:

	* term/i386/pc/at_keyboard.c: Replace `cpu' and `machine' with
	`i386' and `i386/pc' to enable build on x86_64 (this driver is
	i386-specific anyway).
	(grub_console_checkkey): Rename to ...
	(grub_at_keyboard_checkkey): ... this.  Static-ize.  Update all
	users.
	(grub_keyboard_controller_orig): New variable.
	(grub_console_getkey): Rename to ...
	(grub_at_keyboard_getkey): ... this.  Static-ize.  Update all
	users.
	(grub_keyboard_controller_init): Static-ize.  Save original
	controller value so that it can be restored ...
	(grub_keyboard_controller_fini): ... here (new function).
	(grub_at_keyboard_term): New structure.
	(GRUB_MOD_INIT(at_keyboard), GRUB_MOD_FINI(at_keyboard)): New
	functions.

	Migrate output terminals to new API:

	* term/i386/pc/vga.c (grub_vga_term): Change type to
	`struct  grub_term_output'.  Remove `.checkkey' and `.getkey'
	members.  Update all users.
	* term/gfxterm.c (grub_video_term): Change type to
	`struct  grub_term_output'.  Remove `.checkkey' and `.getkey'
	members.  Update all users.
	* include/grub/i386/pc/console.h (grub_console_checkkey)
	(grub_console_getkey): Do not export (no longer needed by gfxterm,
	etc).

	Migrate `terminal' command and userland tools to new API:

	* commands/terminal.c (grub_cmd_terminal): Split into ...
	(grub_cmd_terminal_input): ... this, and ...
	(grub_cmd_terminal_output): ... this.
	(GRUB_MOD_INIT(terminal)): Split `terminal' command in two commands:
	`terminal_input' and `terminal_output'.
	* util/grub.d/00_header.in: Adjust `terminal' calls to new
	`terminal_input' / `terminal_output' API.
	* util/grub-mkconfig.in: Export ${GRUB_TERMINAL_INPUT} and
	${GRUB_TERMINAL_OUTPUT} instead of ${GRUB_TERMINAL} (and if user
	provided ${GRUB_TERMINAL}, convert it).

Index: conf/i386.rmk
===================================================================
--- conf/i386.rmk	(revision 1893)
+++ conf/i386.rmk	(working copy)
@@ -1,8 +1,11 @@
 # -*- makefile -*-
 
 pkglib_MODULES += cpuid.mod
-
-# For cpuid.mod.
 cpuid_mod_SOURCES = commands/i386/cpuid.c
 cpuid_mod_CFLAGS = $(COMMON_CFLAGS)
 cpuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += at_keyboard.mod
+at_keyboard_mod_SOURCES = term/i386/pc/at_keyboard.c
+at_keyboard_mod_CFLAGS = $(COMMON_CFLAGS)
+at_keyboard_mod_LDFLAGS = $(COMMON_LDFLAGS)
Index: conf/i386-ieee1275.rmk
===================================================================
--- conf/i386-ieee1275.rmk	(revision 1893)
+++ conf/i386-ieee1275.rmk	(working copy)
@@ -22,7 +22,7 @@ kernel_elf_SOURCES = kern/i386/ieee1275/
 	kern/time.c \
 	kern/generic/millisleep.c \
 	kern/ieee1275/ieee1275.c \
-	term/ieee1275/ofconsole.c term/i386/pc/at_keyboard.c \
+	term/ieee1275/ofconsole.c \
 	disk/ieee1275/ofdisk.c \
 	symlist.c
 kernel_elf_HEADERS = arg.h cache.h device.h disk.h dl.h elf.h elfload.h \
Index: kern/ieee1275/init.c
===================================================================
--- kern/ieee1275/init.c	(revision 1893)
+++ kern/ieee1275/init.c	(working copy)
@@ -217,7 +217,6 @@ grub_machine_init (void)
   grub_console_init ();
 #ifdef __i386__
   grub_get_extended_memory ();
-  grub_keyboard_controller_init ();
 #endif
   grub_claim_heap ();
   grub_ofdisk_init ();
Index: kern/term.c
===================================================================
--- kern/term.c	(revision 1893)
+++ kern/term.c	(working copy)
@@ -23,10 +23,12 @@
 #include <grub/env.h>
 
 /* The list of terminals.  */
-static grub_term_t grub_term_list;
+static grub_term_input_t grub_term_list_input;
+static grub_term_output_t grub_term_list_output;
 
 /* The current terminal.  */
-static grub_term_t grub_cur_term;
+static grub_term_input_t grub_cur_term_input;
+static grub_term_output_t grub_cur_term_output;
 
 /* The amount of lines counted by the pager.  */
 static int grub_more_lines;
@@ -38,18 +40,38 @@ static int grub_more;
 static int cursor_state = 1;
 
 void
-grub_term_register (grub_term_t term)
+grub_term_register_input (grub_term_input_t term)
 {
-  term->next = grub_term_list;
-  grub_term_list = term;
+  term->next = grub_term_list_input;
+  grub_term_list_input = term;
 }
 
 void
-grub_term_unregister (grub_term_t term)
+grub_term_register_output (grub_term_output_t term)
 {
-  grub_term_t *p, q;
+  term->next = grub_term_list_output;
+  grub_term_list_output = term;
+}
+
+void
+grub_term_unregister_input (grub_term_input_t term)
+{
+  grub_term_input_t *p, q;
+  
+  for (p = &grub_term_list_input, q = *p; q; p = &(q->next), q = q->next)
+    if (q == term)
+      {
+        *p = q->next;
+	break;
+      }
+}
+
+void
+grub_term_unregister_output (grub_term_output_t term)
+{
+  grub_term_output_t *p, q;
   
-  for (p = &grub_term_list, q = *p; q; p = &(q->next), q = q->next)
+  for (p = &grub_term_list_output, q = *p; q; p = &(q->next), q = q->next)
     if (q == term)
       {
         *p = q->next;
@@ -58,36 +80,65 @@ grub_term_unregister (grub_term_t term)
 }
 
 void
-grub_term_iterate (int (*hook) (grub_term_t term))
+grub_term_iterate_input (int (*hook) (grub_term_input_t term))
 {
-  grub_term_t p;
+  grub_term_input_t p;
   
-  for (p = grub_term_list; p; p = p->next)
+  for (p = grub_term_list_input; p; p = p->next)
+    if (hook (p))
+      break;
+}
+
+void
+grub_term_iterate_output (int (*hook) (grub_term_output_t term))
+{
+  grub_term_output_t p;
+  
+  for (p = grub_term_list_output; p; p = p->next)
     if (hook (p))
       break;
 }
 
 grub_err_t
-grub_term_set_current (grub_term_t term)
+grub_term_set_current_input (grub_term_input_t term)
 {
-  if (grub_cur_term && grub_cur_term->fini)
-    if ((grub_cur_term->fini) () != GRUB_ERR_NONE)
+  if (grub_cur_term_input && grub_cur_term_input->fini)
+    if ((grub_cur_term_input->fini) () != GRUB_ERR_NONE)
       return grub_errno;
 
   if (term->init)
     if ((term->init) () != GRUB_ERR_NONE)
       return grub_errno;
   
-  grub_cur_term = term;
-  grub_cls ();
-  grub_setcursor (grub_getcursor ());
+  grub_cur_term_input = term;
   return GRUB_ERR_NONE;
 }
 
-grub_term_t
-grub_term_get_current (void)
+grub_err_t
+grub_term_set_current_output (grub_term_output_t term)
+{
+  if (grub_cur_term_output && grub_cur_term_output->fini)
+    if ((grub_cur_term_output->fini) () != GRUB_ERR_NONE)
+      return grub_errno;
+
+  if (term->init)
+    if ((term->init) () != GRUB_ERR_NONE)
+      return grub_errno;
+  
+  grub_cur_term_output = term;
+  return GRUB_ERR_NONE;
+}
+
+grub_term_input_t
+grub_term_get_current_input (void)
+{
+  return grub_cur_term_input;
+}
+
+grub_term_output_t
+grub_term_get_current_output (void)
 {
-  return grub_cur_term;
+  return grub_cur_term_output;
 }
 
 /* Put a Unicode character.  */
@@ -96,7 +147,7 @@ grub_putcode (grub_uint32_t code)
 {
   int height = grub_getwh () & 255;
 
-  if (code == '\t' && grub_cur_term->getxy)
+  if (code == '\t' && grub_cur_term_output->getxy)
     {
       int n;
       
@@ -107,7 +158,7 @@ grub_putcode (grub_uint32_t code)
       return;
     }
   
-  (grub_cur_term->putchar) (code);
+  (grub_cur_term_output->putchar) (code);
   
   if (code == '\n')
     {
@@ -171,70 +222,70 @@ grub_putchar (int c)
 grub_ssize_t
 grub_getcharwidth (grub_uint32_t code)
 {
-  return (grub_cur_term->getcharwidth) (code);
+  return (grub_cur_term_output->getcharwidth) (code);
 }
 
 int
 grub_getkey (void)
 {
-  return (grub_cur_term->getkey) ();
+  return (grub_cur_term_input->getkey) ();
 }
 
 int
 grub_checkkey (void)
 {
-  return (grub_cur_term->checkkey) ();
+  return (grub_cur_term_input->checkkey) ();
 }
 
 grub_uint16_t
 grub_getxy (void)
 {
-  return (grub_cur_term->getxy) ();
+  return (grub_cur_term_output->getxy) ();
 }
 
 grub_uint16_t
 grub_getwh (void)
 {
-  return (grub_cur_term->getwh) ();
+  return (grub_cur_term_output->getwh) ();
 }
 
 void
 grub_gotoxy (grub_uint8_t x, grub_uint8_t y)
 {
-  (grub_cur_term->gotoxy) (x, y);
+  (grub_cur_term_output->gotoxy) (x, y);
 }
 
 void
 grub_cls (void)
 {
-  if ((grub_cur_term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
+  if ((grub_cur_term_output->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
     {
       grub_putchar ('\n');
       grub_refresh ();
     }
   else
-    (grub_cur_term->cls) ();
+    (grub_cur_term_output->cls) ();
 }
 
 void
 grub_setcolorstate (grub_term_color_state state)
 {
-  if (grub_cur_term->setcolorstate)
-    (grub_cur_term->setcolorstate) (state);
+  if (grub_cur_term_output->setcolorstate)
+    (grub_cur_term_output->setcolorstate) (state);
 }
 
 void
 grub_setcolor (grub_uint8_t normal_color, grub_uint8_t highlight_color)
 {
-  if (grub_cur_term->setcolor)
-    (grub_cur_term->setcolor) (normal_color, highlight_color);
+  if (grub_cur_term_output->setcolor)
+    (grub_cur_term_output->setcolor) (normal_color, highlight_color);
 }
 
 void
 grub_getcolor (grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
 {
-  if (grub_cur_term->getcolor)
-    (grub_cur_term->getcolor) (normal_color, highlight_color);
+  if (grub_cur_term_output->getcolor)
+    (grub_cur_term_output->getcolor) (normal_color, highlight_color);
 }
 
 int
@@ -242,9 +293,9 @@ grub_setcursor (int on)
 {
   int ret = cursor_state;
 
-  if (grub_cur_term->setcursor)
+  if (grub_cur_term_output->setcursor)
     {
-      (grub_cur_term->setcursor) (on);
+      (grub_cur_term_output->setcursor) (on);
       cursor_state = on;
     }
   
@@ -260,8 +311,8 @@ grub_getcursor (void)
 void
 grub_refresh (void)
 {
-  if (grub_cur_term->refresh)
-    (grub_cur_term->refresh) ();
+  if (grub_cur_term_output->refresh)
+    (grub_cur_term_output->refresh) ();
 }
 
 void
Index: kern/i386/coreboot/init.c
===================================================================
--- kern/i386/coreboot/init.c	(revision 1893)
+++ kern/i386/coreboot/init.c	(working copy)
@@ -138,6 +138,7 @@ grub_machine_init (void)
   grub_upper_mem -= GRUB_MEMORY_MACHINE_UPPER_START;
 
   grub_tsc_init ();
+  grub_at_keyboard_init ();
 }
 
 void
Index: kern/misc.c
===================================================================
--- kern/misc.c	(revision 1893)
+++ kern/misc.c	(working copy)
@@ -1026,10 +1026,15 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, 
 void
 grub_abort (void)
 {
-  if (grub_term_get_current ())
+  if (grub_term_get_current_output ())
     {
-      grub_printf ("\nAborted. Press any key to exit.");
-      grub_getkey ();
+      grub_printf ("\nAborted.");
+
+      if (grub_term_get_current_input ())
+	{
+	  grub_printf (" Press any key to exit.");
+	  grub_getkey ();
+	}
     }
 
   grub_exit ();
Index: include/grub/term.h
===================================================================
--- include/grub/term.h	(revision 1893)
+++ include/grub/term.h	(working copy)
@@ -137,7 +137,29 @@ grub_term_color_state;
                                  - 1)
 
 
-struct grub_term
+struct grub_term_input
+{
+  /* The terminal name.  */
+  const char *name;
+
+  /* Initialize the terminal.  */
+  grub_err_t (*init) (void);
+
+  /* Clean up the terminal.  */
+  grub_err_t (*fini) (void);
+  
+  /* Check if any input character is available.  */
+  int (*checkkey) (void);
+  
+  /* Get a character.  */
+  int (*getkey) (void);
+
+  /* The next terminal.  */
+  struct grub_term_input *next;
+};
+typedef struct grub_term_input *grub_term_input_t;
+
+struct grub_term_output
 {
   /* The terminal name.  */
   const char *name;
@@ -155,12 +177,6 @@ struct grub_term
      encoded in Unicode.  */
   grub_ssize_t (*getcharwidth) (grub_uint32_t c);
   
-  /* Check if any input character is available.  */
-  int (*checkkey) (void);
-  
-  /* Get a character.  */
-  int (*getkey) (void);
-  
   /* Get the screen size. The return value is ((Width << 8) | Height).  */
   grub_uint16_t (*getwh) (void);
 
@@ -194,16 +210,21 @@ struct grub_term
   grub_uint32_t flags;
   
   /* The next terminal.  */
-  struct grub_term *next;
+  struct grub_term_output *next;
 };
-typedef struct grub_term *grub_term_t;
-
-void EXPORT_FUNC(grub_term_register) (grub_term_t term);
-void EXPORT_FUNC(grub_term_unregister) (grub_term_t term);
-void EXPORT_FUNC(grub_term_iterate) (int (*hook) (grub_term_t term));
+typedef struct grub_term_output *grub_term_output_t;
 
-grub_err_t EXPORT_FUNC(grub_term_set_current) (grub_term_t term);
-grub_term_t EXPORT_FUNC(grub_term_get_current) (void);
+void EXPORT_FUNC(grub_term_register_input) (grub_term_input_t term);
+void EXPORT_FUNC(grub_term_register_output) (grub_term_output_t term);
+void EXPORT_FUNC(grub_term_unregister_input) (grub_term_input_t term);
+void EXPORT_FUNC(grub_term_unregister_output) (grub_term_output_t term);
+void EXPORT_FUNC(grub_term_iterate_input) (int (*hook) (grub_term_input_t term));
+void EXPORT_FUNC(grub_term_iterate_output) (int (*hook) (grub_term_output_t term));
+
+grub_err_t EXPORT_FUNC(grub_term_set_current_input) (grub_term_input_t term);
+grub_err_t EXPORT_FUNC(grub_term_set_current_output) (grub_term_output_t term);
+grub_term_input_t EXPORT_FUNC(grub_term_get_current_input) (void);
+grub_term_output_t EXPORT_FUNC(grub_term_get_current_output) (void);
 
 void EXPORT_FUNC(grub_putchar) (int c);
 void EXPORT_FUNC(grub_putcode) (grub_uint32_t code);
Index: include/grub/i386/ieee1275/console.h
===================================================================
--- include/grub/i386/ieee1275/console.h	(revision 1893)
+++ include/grub/i386/ieee1275/console.h	(working copy)
@@ -21,10 +21,6 @@
 
 #include <grub/symbol.h>
 
-void EXPORT_FUNC(grub_keyboard_controller_init) (void);
-int EXPORT_FUNC(grub_console_checkkey) (void);
-int EXPORT_FUNC(grub_console_getkey) (void);
-
 /* Initialize the console system.  */
 void grub_console_init (void);
 
Index: include/grub/i386/pc/console.h
===================================================================
--- include/grub/i386/pc/console.h	(revision 1893)
+++ include/grub/i386/pc/console.h	(working copy)
@@ -40,8 +40,8 @@
 /* These are global to share code between C and asm.  */
 extern grub_uint8_t grub_console_cur_color;
 void grub_console_real_putchar (int c);
-int EXPORT_FUNC(grub_console_checkkey) (void);
-int EXPORT_FUNC(grub_console_getkey) (void);
+int grub_console_checkkey (void);
+int grub_console_getkey (void);
 grub_uint16_t grub_console_getxy (void);
 void grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y);
 void grub_console_cls (void);
Index: include/grub/i386/coreboot/console.h
===================================================================
--- include/grub/i386/coreboot/console.h	(revision 1893)
+++ include/grub/i386/coreboot/console.h	(working copy)
@@ -1,25 +1 @@
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2008  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_CONSOLE_MACHINE_LB_HEADER
-#define _GRUB_CONSOLE_MACHINE_LB_HEADER 1
 #include <grub/i386/pc/console.h>
-
-void grub_keyboard_controller_init (void);
-
-#endif /* ! _GRUB_CONSOLE_MACHINE_LB_HEADER */
Index: commands/terminal.c
===================================================================
--- commands/terminal.c	(revision 1893)
+++ commands/terminal.c	(working copy)
@@ -24,21 +24,21 @@
 #include <grub/term.h>
 
 static grub_err_t
-grub_cmd_terminal (struct grub_arg_list *state __attribute__ ((unused)),
-		   int argc, char **args)
+grub_cmd_terminal_input (struct grub_arg_list *state __attribute__ ((unused)),
+			 int argc, char **args)
 {
-  grub_term_t term = 0;
+  grub_term_input_t term = 0;
   
-  auto int print_terminal (grub_term_t);
-  auto int find_terminal (grub_term_t);
+  auto int print_terminal (grub_term_input_t);
+  auto int find_terminal (grub_term_input_t);
   
-  int print_terminal (grub_term_t t)
+  int print_terminal (grub_term_input_t t)
     {
       grub_printf (" %s", t->name);
       return 0;
     }
 
-  int find_terminal (grub_term_t t)
+  int find_terminal (grub_term_input_t t)
     {
       if (grub_strcmp (t->name, args[0]) == 0)
 	{
@@ -51,19 +51,65 @@ grub_cmd_terminal (struct grub_arg_list 
   
   if (argc == 0)
     {
-      grub_printf ("Available terminal(s):");
-      grub_term_iterate (print_terminal);
+      grub_printf ("Available input terminal(s):");
+      grub_term_iterate_input (print_terminal);
       grub_putchar ('\n');
       
-      grub_printf ("Current terminal: %s\n", grub_term_get_current ()->name);
+      grub_printf ("Current input terminal: %s\n", grub_term_get_current_input ()->name);
     }
   else
     {
-      grub_term_iterate (find_terminal);
+      grub_term_iterate_input (find_terminal);
       if (! term)
-	return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such terminal");
+	return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such input terminal");
 
-      grub_term_set_current (term);
+      grub_term_set_current_input (term);
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_cmd_terminal_output (struct grub_arg_list *state __attribute__ ((unused)),
+			  int argc, char **args)
+{
+  grub_term_output_t term = 0;
+  
+  auto int print_terminal (grub_term_output_t);
+  auto int find_terminal (grub_term_output_t);
+  
+  int print_terminal (grub_term_output_t t)
+    {
+      grub_printf (" %s", t->name);
+      return 0;
+    }
+
+  int find_terminal (grub_term_output_t t)
+    {
+      if (grub_strcmp (t->name, args[0]) == 0)
+	{
+	  term = t;
+	  return 1;
+	}
+
+      return 0;
+    }
+  
+  if (argc == 0)
+    {
+      grub_printf ("Available output terminal(s):");
+      grub_term_iterate_output (print_terminal);
+      grub_putchar ('\n');
+      
+      grub_printf ("Current output terminal: %s\n", grub_term_get_current_output ()->name);
+    }
+  else
+    {
+      grub_term_iterate_output (find_terminal);
+      if (! term)
+	return grub_error (GRUB_ERR_BAD_ARGUMENT, "no such output terminal");
+
+      grub_term_set_current_output (term);
     }
 
   return GRUB_ERR_NONE;
@@ -73,8 +119,10 @@ grub_cmd_terminal (struct grub_arg_list 
 GRUB_MOD_INIT(terminal)
 {
   (void)mod;			/* To stop warning. */
-  grub_register_command ("terminal", grub_cmd_terminal, GRUB_COMMAND_FLAG_BOTH,
-			 "terminal [TERM...]", "Select a terminal.", 0);
+  grub_register_command ("terminal_input", grub_cmd_terminal_input, GRUB_COMMAND_FLAG_BOTH,
+			 "terminal_input [TERM...]", "Select an input terminal.", 0);
+  grub_register_command ("terminal_output", grub_cmd_terminal_output, GRUB_COMMAND_FLAG_BOTH,
+			 "terminal_output [TERM...]", "Select an output terminal.", 0);
 }
 
 GRUB_MOD_FINI(terminal)
Index: term/efi/console.c
===================================================================
--- term/efi/console.c	(revision 1893)
+++ term/efi/console.c	(working copy)
@@ -332,15 +332,18 @@ grub_console_setcursor (int on)
   efi_call_2 (o->enable_cursor, o, on);
 }
 
-static struct grub_term grub_console_term =
+static struct grub_term_input grub_console_term_input =
   {
     .name = "console",
-    .init = 0,
-    .fini = 0,
-    .putchar = grub_console_putchar,
-    .getcharwidth = grub_console_getcharwidth,
     .checkkey = grub_console_checkkey,
     .getkey = grub_console_getkey,
+  };
+
+static struct grub_term_output grub_console_term_output =
+  {
+    .name = "console",
+    .putchar = grub_console_putchar,
+    .getcharwidth = grub_console_getcharwidth,
     .getwh = grub_console_getwh,
     .getxy = grub_console_getxy,
     .gotoxy = grub_console_gotoxy,
@@ -350,7 +353,6 @@ static struct grub_term grub_console_ter
     .getcolor = grub_console_getcolor,
     .setcursor = grub_console_setcursor,
     .flags = 0,
-    .next = 0
   };
 
 void
@@ -364,12 +366,15 @@ grub_console_init (void)
       return;
     }
 
-  grub_term_register (&grub_console_term);
-  grub_term_set_current (&grub_console_term);
+  grub_term_register_input (&grub_console_term_input);
+  grub_term_register_output (&grub_console_term_output);
+  grub_term_set_current_output (&grub_console_term_output);
+  grub_term_set_current_input (&grub_console_term_input);
 }
 
 void
 grub_console_fini (void)
 {
-  grub_term_unregister (&grub_console_term);
+  grub_term_unregister_input (&grub_console_term_input);
+  grub_term_unregister_output (&grub_console_term_output);
 }
Index: term/ieee1275/ofconsole.c
===================================================================
--- term/ieee1275/ofconsole.c	(revision 1893)
+++ term/ieee1275/ofconsole.c	(working copy)
@@ -33,10 +33,8 @@ static grub_uint8_t grub_ofconsole_heigh
 static int grub_curr_x;
 static int grub_curr_y;
 
-#ifndef __i386__
 static int grub_keybuf;
 static int grub_buflen;
-#endif
 
 struct color
 {
@@ -144,7 +142,6 @@ grub_ofconsole_getcolor (grub_uint8_t *n
   *highlight_color = grub_ofconsole_highlight_color;
 }
 
-#ifndef __i386__
 static int
 grub_ofconsole_readkey (int *key)
 {
@@ -342,7 +339,20 @@ grub_ofconsole_refresh (void)
 }
 
 static grub_err_t
-grub_ofconsole_init (void)
+grub_ofconsole_init_input (void)
+{
+  grub_ssize_t actual;
+
+  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle,
+					  sizeof stdin_ihandle, &actual)
+      || actual != sizeof stdin_ihandle)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdin");
+
+  return 0;
+}
+
+static grub_err_t
+grub_ofconsole_init_output (void)
 {
   grub_ssize_t actual;
   int col;
@@ -358,11 +368,6 @@ grub_ofconsole_init (void)
       || actual != sizeof stdout_ihandle)
     return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdout");
 
-  if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle,
-					  sizeof stdin_ihandle, &actual)
-      || actual != sizeof stdin_ihandle)
-    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdin");
-
   /* Initialize colors.  */
   if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CANNOT_SET_COLORS))
     {
@@ -385,20 +390,22 @@ grub_ofconsole_fini (void)
 
 
 \f
-static struct grub_term grub_ofconsole_term =
+static struct grub_term_input grub_ofconsole_term_input =
   {
     .name = "ofconsole",
-    .init = grub_ofconsole_init,
+    .init = grub_ofconsole_init_input,
     .fini = grub_ofconsole_fini,
-    .putchar = grub_ofconsole_putchar,
-    .getcharwidth = grub_ofconsole_getcharwidth,
-#ifdef __i386__
-    .checkkey = grub_console_checkkey,
-    .getkey = grub_console_getkey,
-#else
     .checkkey = grub_ofconsole_checkkey,
     .getkey = grub_ofconsole_getkey,
-#endif
+  };
+
+static struct grub_term_output grub_ofconsole_term_output =
+  {
+    .name = "ofconsole",
+    .init = grub_ofconsole_init_output,
+    .fini = grub_ofconsole_fini,
+    .putchar = grub_ofconsole_putchar,
+    .getcharwidth = grub_ofconsole_getcharwidth,
     .getxy = grub_ofconsole_getxy,
     .getwh = grub_ofconsole_getwh,
     .gotoxy = grub_ofconsole_gotoxy,
@@ -409,18 +416,20 @@ static struct grub_term grub_ofconsole_t
     .setcursor = grub_ofconsole_setcursor,
     .refresh = grub_ofconsole_refresh,
     .flags = 0,
-    .next = 0
   };
 
 void
 grub_console_init (void)
 {
-  grub_term_register (&grub_ofconsole_term);
-  grub_term_set_current (&grub_ofconsole_term);
+  grub_term_register_input (&grub_ofconsole_term_input);
+  grub_term_register_output (&grub_ofconsole_term_output);
+  grub_term_set_current_output (&grub_ofconsole_term_output);
+  grub_term_set_current_input (&grub_ofconsole_term_input);
 }
 
 void
 grub_console_fini (void)
 {
-  grub_term_unregister (&grub_ofconsole_term);
+  grub_term_unregister_input (&grub_ofconsole_term_input);
+  grub_term_unregister_output (&grub_ofconsole_term_output);
 }
Index: term/i386/pc/serial.c
===================================================================
--- term/i386/pc/serial.c	(revision 1893)
+++ term/i386/pc/serial.c	(working copy)
@@ -467,15 +467,18 @@ grub_serial_setcursor (const int on)
     grub_terminfo_cursor_off ();
 }
 
-static struct grub_term grub_serial_term =
+static struct grub_term_input grub_serial_term_input =
 {
   .name = "serial",
-  .init = 0,
-  .fini = 0,
-  .putchar = grub_serial_putchar,
-  .getcharwidth = grub_serial_getcharwidth,
   .checkkey = grub_serial_checkkey,
   .getkey = grub_serial_getkey,
+};
+
+static struct grub_term_output grub_serial_term_output =
+{
+  .name = "serial",
+  .putchar = grub_serial_putchar,
+  .getcharwidth = grub_serial_getcharwidth,
   .getwh = grub_serial_getwh,
   .getxy = grub_serial_getxy,
   .gotoxy = grub_serial_gotoxy,
@@ -483,7 +486,6 @@ static struct grub_term grub_serial_term
   .setcolorstate = grub_serial_setcolorstate,
   .setcursor = grub_serial_setcursor,
   .flags = 0,
-  .next = 0
 };
 
 \f
@@ -575,7 +577,8 @@ grub_cmd_serial (struct grub_arg_list *s
       /* Register terminal if not yet registered.  */
       if (registered == 0)
 	{
-	  grub_term_register (&grub_serial_term);
+	  grub_term_register_input (&grub_serial_term_input);
+	  grub_term_register_output (&grub_serial_term_output);
 	  registered = 1;
 	}
     }
@@ -590,7 +593,8 @@ grub_cmd_serial (struct grub_arg_list *s
 	  if (serial_hw_init () != GRUB_ERR_NONE)
 	    {
 	      /* If unable to restore settings, unregister terminal.  */
-	      grub_term_unregister (&grub_serial_term);
+	      grub_term_unregister_input (&grub_serial_term_input);
+	      grub_term_unregister_output (&grub_serial_term_output);
 	      registered = 0;
 	    }
 	}
@@ -616,5 +620,8 @@ GRUB_MOD_FINI(serial)
 {
   grub_unregister_command ("serial");
   if (registered == 1)		/* Unregister terminal only if registered. */
-    grub_term_unregister (&grub_serial_term);
+    {
+      grub_term_unregister_input (&grub_serial_term_input);
+      grub_term_unregister_output (&grub_serial_term_output);
+    }
 }
Index: term/i386/pc/console.c
===================================================================
--- term/i386/pc/console.c	(revision 1893)
+++ term/i386/pc/console.c	(working copy)
@@ -125,15 +125,22 @@ grub_console_getcolor (grub_uint8_t *nor
   *highlight_color = grub_console_highlight_color;
 }
 
-static struct grub_term grub_console_term =
+/* On non-BIOS platforms, console.c is used in combination with vga_text.c
+   (only to handle output).  */
+#ifdef GRUB_MACHINE_PCBIOS
+static struct grub_term_input grub_console_term_input =
   {
     .name = "console",
-    .init = 0,
-    .fini = 0,
-    .putchar = grub_console_putchar,
-    .getcharwidth = grub_console_getcharwidth,
     .checkkey = grub_console_checkkey,
     .getkey = grub_console_getkey,
+  };
+#endif
+
+static struct grub_term_output grub_console_term_output =
+  {
+    .name = "console",
+    .putchar = grub_console_putchar,
+    .getcharwidth = grub_console_getcharwidth,
     .getwh = grub_console_getwh,
     .getxy = grub_console_getxy,
     .gotoxy = grub_console_gotoxy,
@@ -143,23 +150,26 @@ static struct grub_term grub_console_ter
     .getcolor = grub_console_getcolor,
     .setcursor = grub_console_setcursor,
     .flags = 0,
-    .next = 0
   };
 
 void
 grub_console_init (void)
 {
-  grub_term_register (&grub_console_term);
-  grub_term_set_current (&grub_console_term);
-
-#ifdef GRUB_MACHINE_LINUXBIOS
-  grub_keyboard_controller_init ();
+  grub_term_register_output (&grub_console_term_output);
+  grub_term_set_current_output (&grub_console_term_output);
+#ifdef GRUB_MACHINE_PCBIOS
+  grub_term_register_input (&grub_console_term_input);
+  grub_term_set_current_input (&grub_console_term_input);
 #endif
 }
 
 void
 grub_console_fini (void)
 {
-  grub_term_set_current (&grub_console_term);
-  grub_term_unregister (&grub_console_term);
+  grub_term_set_current_output (&grub_console_term_output);
+#ifdef GRUB_MACHINE_PCBIOS
+  grub_term_set_current_input (&grub_console_term_input);
+  grub_term_unregister_input (&grub_console_term_input);
+#endif
+  grub_term_unregister_output (&grub_console_term_output);
 }
Index: term/i386/pc/at_keyboard.c
===================================================================
--- term/i386/pc/at_keyboard.c	(revision 1893)
+++ term/i386/pc/at_keyboard.c	(working copy)
@@ -16,9 +16,10 @@
  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <grub/machine/console.h>
-#include <grub/cpu/at_keyboard.h>
-#include <grub/cpu/io.h>
+#include <grub/dl.h>
+#include <grub/i386/pc/console.h>
+#include <grub/i386/at_keyboard.h>
+#include <grub/i386/io.h>
 #include <grub/misc.h>
 #include <grub/term.h>
 
@@ -61,6 +62,8 @@ static char keyboard_map_shift[128] =
   'B', 'N', 'M', '<', '>', '?'
 };
 
+static grub_uint8_t grub_keyboard_controller_orig;
+
 static void
 grub_keyboard_controller_write (grub_uint8_t c)
 {
@@ -77,12 +80,6 @@ grub_keyboard_controller_read (void)
   return grub_inb (KEYBOARD_REG_DATA);
 }
 
-void
-grub_keyboard_controller_init (void)
-{
-  grub_keyboard_controller_write (grub_keyboard_controller_read () | KEYBOARD_SCANCODE_SET1);
-}
-
 /* FIXME: This should become an interrupt service routine.  For now
    it's just used to catch events from control keys.  */
 static void
@@ -148,8 +145,8 @@ grub_keyboard_getkey (void)
 }
 
 /* If there is a character pending, return it; otherwise return -1.  */
-int
-grub_console_checkkey (void)
+static int
+grub_at_keyboard_checkkey (void)
 {
   int code, key;
   code = grub_keyboard_getkey ();
@@ -192,13 +189,47 @@ grub_console_checkkey (void)
   return (int) key;
 }
 
-int
-grub_console_getkey (void)
+static int
+grub_at_keyboard_getkey (void)
 {
   int key;
   do
     {
-      key = grub_console_checkkey ();
+      key = grub_at_keyboard_checkkey ();
     } while (key == -1);
   return key;
 }
+
+static grub_err_t
+grub_keyboard_controller_init (void)
+{
+  grub_keyboard_controller_orig = grub_keyboard_controller_read ();
+  grub_keyboard_controller_write (grub_keyboard_controller_orig | KEYBOARD_SCANCODE_SET1);
+  return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_keyboard_controller_fini (void)
+{
+  grub_keyboard_controller_write (grub_keyboard_controller_orig);
+  return GRUB_ERR_NONE;
+}
+
+static struct grub_term_input grub_at_keyboard_term =
+  {
+    .name = "at_keyboard",
+    .init = grub_keyboard_controller_init,
+    .fini = grub_keyboard_controller_fini,
+    .checkkey = grub_at_keyboard_checkkey,
+    .getkey = grub_at_keyboard_getkey,
+  };
+
+GRUB_MOD_INIT(at_keyboard)
+{
+  grub_term_register_input (&grub_at_keyboard_term);
+}
+
+GRUB_MOD_FINI(at_keyboard)
+{
+  grub_term_unregister_output (&grub_at_keyboard_term);
+}
Index: term/i386/pc/vga.c
===================================================================
--- term/i386/pc/vga.c	(revision 1893)
+++ term/i386/pc/vga.c	(working copy)
@@ -473,15 +473,13 @@ grub_vga_setcursor (int on)
     }
 }
 
-static struct grub_term grub_vga_term =
+static struct grub_term_output grub_vga_term =
   {
     .name = "vga",
     .init = grub_vga_mod_init,
     .fini = grub_vga_mod_fini,
     .putchar = grub_vga_putchar,
     .getcharwidth = grub_vga_getcharwidth,
-    .checkkey = grub_console_checkkey,
-    .getkey = grub_console_getkey,
     .getwh = grub_vga_getwh,
     .getxy = grub_vga_getxy,
     .gotoxy = grub_vga_gotoxy,
@@ -489,7 +487,6 @@ static struct grub_term grub_vga_term =
     .setcolorstate = grub_vga_setcolorstate,
     .setcursor = grub_vga_setcursor,
     .flags = 0,
-    .next = 0
   };
 
 GRUB_MOD_INIT(vga)
@@ -497,10 +494,10 @@ GRUB_MOD_INIT(vga)
 #ifndef GRUB_UTIL
   my_mod = mod;
 #endif
-  grub_term_register (&grub_vga_term);
+  grub_term_register_output (&grub_vga_term);
 }
 
 GRUB_MOD_FINI(vga)
 {
-  grub_term_unregister (&grub_vga_term);
+  grub_term_unregister_output (&grub_vga_term);
 }
Index: term/gfxterm.c
===================================================================
--- term/gfxterm.c	(revision 1893)
+++ term/gfxterm.c	(working copy)
@@ -1056,15 +1056,13 @@ grub_gfxterm_background_image_cmd (struc
   return grub_errno;
 }
 
-static struct grub_term grub_video_term =
+static struct grub_term_output grub_video_term =
   {
     .name = "gfxterm",
     .init = grub_gfxterm_init,
     .fini = grub_gfxterm_fini,
     .putchar = grub_gfxterm_putchar,
     .getcharwidth = grub_gfxterm_getcharwidth,
-    .checkkey = grub_console_checkkey,
-    .getkey = grub_console_getkey,
     .getwh = grub_virtual_screen_getwh,
     .getxy = grub_virtual_screen_getxy,
     .gotoxy = grub_gfxterm_gotoxy,
@@ -1081,7 +1079,7 @@ static struct grub_term grub_video_term 
 GRUB_MOD_INIT(term_gfxterm)
 {
   my_mod = mod;
-  grub_term_register (&grub_video_term);
+  grub_term_register_output (&grub_video_term);
 
   grub_register_command ("background_image",
                          grub_gfxterm_background_image_cmd,
@@ -1094,5 +1092,5 @@ GRUB_MOD_INIT(term_gfxterm)
 GRUB_MOD_FINI(term_gfxterm)
 {
   grub_unregister_command ("bgimage");
-  grub_term_unregister (&grub_video_term);
+  grub_term_unregister_output (&grub_video_term);
 }
Index: util/grub.d/00_header.in
===================================================================
--- util/grub.d/00_header.in	(revision 1893)
+++ util/grub.d/00_header.in	(working copy)
@@ -40,8 +40,31 @@ set default=${GRUB_DEFAULT}
 set timeout=${GRUB_TIMEOUT}
 EOF
 
-case x${GRUB_TERMINAL} in
-  xgfxterm)
+case ${GRUB_TERMINAL_INPUT}:${GRUB_TERMINAL_OUTPUT} in
+  serial:* | *: serial)
+    if ! test -e ${grub_prefix}/serial.mod ; then
+      echo "Serial terminal not available on this platform." >&2 ; exit 1
+    fi
+
+    if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then
+      echo "Warning, requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used." >&2
+      GRUB_SERIAL_COMMAND=serial
+    fi
+    echo "${GRUB_SERIAL_COMMAND}"
+  ;;
+esac
+
+case x${GRUB_TERMINAL_INPUT} in
+  x)
+    # Just use the native terminal
+  ;;
+  x*)
+    echo "terminal_input ${GRUB_TERMINAL_INPUT}"
+  ;;
+esac
+
+case x${GRUB_TERMINAL_OUTPUT} in
+ xgfxterm)
     # Make the font accessible
     prepare_grub_to_access_device `${grub_probe} --target=device ${GRUB_FONT_PATH}`
 
@@ -62,26 +85,14 @@ if font `make_system_path_relative_to_it
   set gfxmode=${GRUB_GFXMODE}
   insmod gfxterm
   insmod ${video_backend}
-  terminal gfxterm
+  terminal_output gfxterm
 fi
 EOF
   ;;
-  xserial)
-    if ! test -e ${grub_prefix}/serial.mod ; then
-      echo "Serial terminal not available on this platform." >&2 ; exit 1
-    fi
-
-    if [ "x${GRUB_SERIAL_COMMAND}" = "x" ] ; then
-      echo "Warning, requested serial terminal but GRUB_SERIAL_COMMAND is unspecified. Default parameters will be used." >&2
-      GRUB_SERIAL_COMMAND=serial
-    fi
-    echo "${GRUB_SERIAL_COMMAND}"
-    echo "terminal serial"
-  ;;
   x)
     # Just use the native terminal
   ;;
   x*)
-    echo "terminal ${GRUB_TERMINAL}"
+    echo "terminal_output ${GRUB_TERMINAL_OUTPUT}"
   ;;
 esac
Index: util/console.c
===================================================================
--- util/console.c	(revision 1893)
+++ util/console.c	(working copy)
@@ -371,7 +371,8 @@ void
 grub_console_init (void)
 {
   grub_term_register (&grub_ncurses_term);
-  grub_term_set_current (&grub_ncurses_term);
+  grub_term_set_current_input (&grub_ncurses_term);
+  grub_term_set_current_output (&grub_ncurses_term);
 }
 
 void
Index: util/grub-probe.c
===================================================================
--- util/grub-probe.c	(revision 1893)
+++ util/grub-probe.c	(working copy)
@@ -66,8 +66,14 @@ grub_getkey (void)
   return -1;
 }
 
-grub_term_t
-grub_term_get_current (void)
+grub_term_input_t
+grub_term_get_current_input (void)
+{
+  return 0;
+}
+
+grub_term_output_t
+grub_term_get_current_output (void)
 {
   return 0;
 }
Index: util/grub-fstest.c
===================================================================
--- util/grub-fstest.c	(revision 1893)
+++ util/grub-fstest.c	(working copy)
@@ -54,7 +54,13 @@ grub_getkey (void)
 }
 
 grub_term_t
-grub_term_get_current (void)
+grub_term_get_current_input (void)
+{
+  return 0;
+}
+
+grub_term_t
+grub_term_get_current_output (void)
 {
   return 0;
 }
Index: util/i386/pc/grub-setup.c
===================================================================
--- util/i386/pc/grub-setup.c	(revision 1893)
+++ util/i386/pc/grub-setup.c	(working copy)
@@ -74,8 +74,14 @@ grub_getkey (void)
   return -1;
 }
 
-grub_term_t
-grub_term_get_current (void)
+grub_term_input_t
+grub_term_get_current_input (void)
+{
+  return 0;
+}
+
+grub_term_output_t
+grub_term_get_current_output (void)
 {
   return 0;
 }
Index: util/grub-mkconfig.in
===================================================================
--- util/grub-mkconfig.in	(revision 1893)
+++ util/grub-mkconfig.in	(working copy)
@@ -130,31 +130,37 @@ if test -f ${sysconfdir}/default/grub ; 
   . ${sysconfdir}/default/grub
 fi
 
-case x${GRUB_TERMINAL} in
+# XXX: should this be deprecated at some point?
+if [ "x${GRUB_TERMINAL}" != "x" ] ; then
+  GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}"
+  GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}"
+fi
+
+case x${GRUB_TERMINAL_OUTPUT} in
   x)
     # If this platform supports gfxterm, try to use it.
     if test -e ${grub_prefix}/gfxterm.mod ; then
-      GRUB_TERMINAL=gfxterm
+      GRUB_TERMINAL_OUTPUT=gfxterm
     fi
   ;;
   xconsole | xserial | xofconsole | xgfxterm) ;;
-  *) echo "Invalid terminal \"${GRUB_TERMINAL}\"" >&2 ; exit 1 ;;
+  *) echo "Invalid output terminal \"${GRUB_TERMINAL_OUTPUT}\"" >&2 ; exit 1 ;;
 esac
 
 # check for terminals that require fonts
-case ${GRUB_TERMINAL} in
+case ${GRUB_TERMINAL_OUTPUT} in
   gfxterm)
     if path=`font_path` ; then
       GRUB_FONT_PATH="${path}"
     else
       # fallback to the native terminal for this platform
-      unset GRUB_TERMINAL
+      unset GRUB_TERMINAL_OUTPUT
     fi
   ;;
 esac
 
 # does our terminal support utf-8 ?
-case ${GRUB_TERMINAL} in
+case ${GRUB_TERMINAL_OUTPUT} in
   gfxterm) ;;
   *)
     # make sure all our children behave in conformance with ascii..
@@ -167,7 +173,7 @@ esac
 export GRUB_DEVICE GRUB_DEVICE_UUID GRUB_DEVICE_BOOT GRUB_DEVICE_BOOT_UUID GRUB_FS GRUB_FONT_PATH GRUB_PRELOAD_MODULES
 
 # These are optional, user-defined variables.
-export GRUB_DEFAULT GRUB_TIMEOUT GRUB_DISTRIBUTOR GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT GRUB_TERMINAL GRUB_SERIAL_COMMAND GRUB_DISABLE_LINUX_UUID GRUB_GFXMODE
+export GRUB_DEFAULT GRUB_TIMEOUT GRUB_DISTRIBUTOR GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT GRUB_TERMINAL_OUTPUT GRUB_SERIAL_COMMAND GRUB_DISABLE_LINUX_UUID GRUB_GFXMODE
 
 if test "x${grub_cfg}" != "x"; then
   rm -f ${grub_cfg}.new
Index: util/grub-editenv.c
===================================================================
--- util/grub-editenv.c	(revision 1893)
+++ util/grub-editenv.c	(working copy)
@@ -41,7 +41,13 @@ grub_refresh (void)
 }
 
 void *
-grub_term_get_current (void)
+grub_term_get_current_input (void)
+{
+  return 0;
+}
+
+void *
+grub_term_get_current_output (void)
 {
   return 0;
 }

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-04 15:52 ` Yoshinori K. Okuji
  2008-11-04 17:14   ` Robert Millan
@ 2008-11-04 18:31   ` Vesa Jääskeläinen
  2008-11-06 17:20     ` Yoshinori K. Okuji
  1 sibling, 1 reply; 19+ messages in thread
From: Vesa Jääskeläinen @ 2008-11-04 18:31 UTC (permalink / raw)
  To: The development of GRUB 2

Yoshinori K. Okuji wrote:
> BTW, I would like to obtain the capability of handling pipes, so that we can, 
> say, "help | more". I guess you have the same idea in your mind. This should 
> be trivial, once the input and output are separate, right?

I think this would need separated streams design in order to be
functional. Not a bad idea as such.... I am wondering the gain however.
What kind of implementation plan did you have for piping in example more?



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-02 18:11 [PATCH] terminal split Robert Millan
  2008-11-04 15:52 ` Yoshinori K. Okuji
@ 2008-11-04 18:53 ` Vesa Jääskeläinen
  2008-11-04 19:12   ` Robert Millan
  1 sibling, 1 reply; 19+ messages in thread
From: Vesa Jääskeläinen @ 2008-11-04 18:53 UTC (permalink / raw)
  To: The development of GRUB 2

Robert Millan wrote:
> Hi,
> 
> This patch splits terminal handling in input and output.  While at it, it
> resolves/removes some of the kludges we had to work around this limitation.
> 
> For example, gfxterm/vga no longer need to assume the input is bios console,
> at_keyboard can be used in combination with any output terminal, etc.
> 
> It will also be possible to turn vga_text.c into a standalone output term,
> but this needs more work since it is currently sharing much code with the
> bios console in console.c.

I think multipath would be nice feature. Eg. you can have serial/other
remote connected and then have local terminal at same time.

This would allow remote maintenance for server and then if user is
locally there he can operate machine too.

For this there would need to be a way to say send output to these
terminals and gather input from these terminals.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-04 18:53 ` Vesa Jääskeläinen
@ 2008-11-04 19:12   ` Robert Millan
  2008-11-04 19:49     ` Colin D Bennett
  2008-11-07 19:26     ` [RFC] Multi-terminal support (Re: [PATCH] terminal split) Robert Millan
  0 siblings, 2 replies; 19+ messages in thread
From: Robert Millan @ 2008-11-04 19:12 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, Nov 04, 2008 at 08:53:22PM +0200, Vesa Jääskeläinen wrote:
> 
> I think multipath would be nice feature. Eg. you can have serial/other
> remote connected and then have local terminal at same time.

In fact we need that if we ever want to support reading from AT keyboards
and USB keyboards at the same time (we don't know which one is there, so
whenever using hardware access for one of them, we need to try both).

I was thinking that after terminal split is merged, we could either:

  - Turn the grub_cur_term_{input,output} pointers into lists, so that
    multiple terminals can be "current" at the same time.

  - Implement a "magic" input (or output) terminal that can be attached to
    other terminals and reads from (or writes to) more than one of them.
    The advantage of this is that the code doesn't have to be in kernel.

But I suppose we agree that the change I'm currently proposing is in the
right direction?

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-04 19:12   ` Robert Millan
@ 2008-11-04 19:49     ` Colin D Bennett
  2008-11-07 19:26     ` [RFC] Multi-terminal support (Re: [PATCH] terminal split) Robert Millan
  1 sibling, 0 replies; 19+ messages in thread
From: Colin D Bennett @ 2008-11-04 19:49 UTC (permalink / raw)
  To: The development of GRUB 2; +Cc: rmh

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

On Tue, 4 Nov 2008 20:12:56 +0100
Robert Millan <rmh@aybabtu.com> wrote:

> On Tue, Nov 04, 2008 at 08:53:22PM +0200, Vesa Jääskeläinen wrote:
> > 
> > I think multipath would be nice feature. Eg. you can have
> > serial/other remote connected and then have local terminal at same
> > time.
> 
> In fact we need that if we ever want to support reading from AT
> keyboards and USB keyboards at the same time (we don't know which one
> is there, so whenever using hardware access for one of them, we need
> to try both).

Good point.  Don't forget that machines may have multiple USB keyboards
attached, as well.  I have used multi-keyboard, multi-mouse machines
before in a pair programming environment. (This does not necessarily
promote good pair programming practices, however.)

Regards,
Colin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-04 17:14   ` Robert Millan
@ 2008-11-06 17:05     ` Yoshinori K. Okuji
  2008-11-07 19:13       ` Robert Millan
  0 siblings, 1 reply; 19+ messages in thread
From: Yoshinori K. Okuji @ 2008-11-06 17:05 UTC (permalink / raw)
  To: The development of GRUB 2

On Tuesday 04 November 2008 18:14:17 Robert Millan wrote:
> On Tue, Nov 04, 2008 at 04:52:20PM +0100, Yoshinori K. Okuji wrote:
> > No ChangeLog?
>
> Here.  I ommitted it because I wanted to see if it would need big
> adjustments first.

OK. The patch looks perfect for me.

> > BTW, I would like to obtain the capability of handling pipes, so that we
> > can, say, "help | more". I guess you have the same idea in your mind.
>
> Actually, I didn't think about this possibility.  My goal was to simplify
> things on the backend side, so many of the quirks we have can be removed
> (some examples in my previous mail), and we can integrate USB keyboard
> support cleanly.
>
> > This should
> > be trivial, once the input and output are separate, right?
>
> Well, I suppose one could write a "pipe" output terminal that stores output
> in a buffer, and then a "pipe" input terminal that reads from it.  My code
> probably makes pipes easier, but I don't know how much is left (I assume
> you don't want real pipes since that implies multi-threading).

Surely, I don't want multi-processing or multi-threading in GRUB. This is 
overkill. A pipe should be implemented in the same way as in DOS.

Regards,
Okuji



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-04 18:31   ` Vesa Jääskeläinen
@ 2008-11-06 17:20     ` Yoshinori K. Okuji
  2008-11-07 19:07       ` Robert Millan
  0 siblings, 1 reply; 19+ messages in thread
From: Yoshinori K. Okuji @ 2008-11-06 17:20 UTC (permalink / raw)
  To: The development of GRUB 2

On Tuesday 04 November 2008 19:31:09 Vesa Jääskeläinen wrote:
> Yoshinori K. Okuji wrote:
> > BTW, I would like to obtain the capability of handling pipes, so that we
> > can, say, "help | more". I guess you have the same idea in your mind.
> > This should be trivial, once the input and output are separate, right?
>
> I think this would need separated streams design in order to be
> functional. Not a bad idea as such.... I am wondering the gain however.
> What kind of implementation plan did you have for piping in example more?

In "if" conditions, pipes can be sometimes very useful. For example:

  if ls | grep eth; then
    # if any ethernet device is present, change the strategy...
    set fallback="1 2"
  fi

Also, a similar technique can be used to implement "getting an output as a 
string". For example:

  # Use the same password as the super user.
  set password=$(sed -ne '/^root:/{s/root:\([^:]*\).*/\1/;p}' /etc/shadow)

Regards,
Okuji



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-06 17:20     ` Yoshinori K. Okuji
@ 2008-11-07 19:07       ` Robert Millan
  2008-11-09  7:22         ` Yoshinori K. Okuji
  0 siblings, 1 reply; 19+ messages in thread
From: Robert Millan @ 2008-11-07 19:07 UTC (permalink / raw)
  To: The development of GRUB 2

On Thu, Nov 06, 2008 at 06:20:57PM +0100, Yoshinori K. Okuji wrote:
> 
> Also, a similar technique can be used to implement "getting an output as a 
> string". For example:
> 
>   # Use the same password as the super user.
>   set password=$(sed -ne '/^root:/{s/root:\([^:]*\).*/\1/;p}' /etc/shadow)

This would work much better in grub-mkconfig.  You don't want to implement
(or port) sed do you? ;-)

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-06 17:05     ` Yoshinori K. Okuji
@ 2008-11-07 19:13       ` Robert Millan
  0 siblings, 0 replies; 19+ messages in thread
From: Robert Millan @ 2008-11-07 19:13 UTC (permalink / raw)
  To: The development of GRUB 2

On Thu, Nov 06, 2008 at 06:05:21PM +0100, Yoshinori K. Okuji wrote:
> On Tuesday 04 November 2008 18:14:17 Robert Millan wrote:
> > On Tue, Nov 04, 2008 at 04:52:20PM +0100, Yoshinori K. Okuji wrote:
> > > No ChangeLog?
> >
> > Here.  I ommitted it because I wanted to see if it would need big
> > adjustments first.
> 
> OK. The patch looks perfect for me.

Ok, I just committed it.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC] Multi-terminal support (Re: [PATCH] terminal split)
  2008-11-04 19:12   ` Robert Millan
  2008-11-04 19:49     ` Colin D Bennett
@ 2008-11-07 19:26     ` Robert Millan
  2008-11-22 17:42       ` Yoshinori K. Okuji
  1 sibling, 1 reply; 19+ messages in thread
From: Robert Millan @ 2008-11-07 19:26 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, Nov 04, 2008 at 08:12:56PM +0100, Robert Millan wrote:
> 
>   - Turn the grub_cur_term_{input,output} pointers into lists, so that
>     multiple terminals can be "current" at the same time.
> 
>   - Implement a "magic" input (or output) terminal that can be attached to
>     other terminals and reads from (or writes to) more than one of them.
>     The advantage of this is that the code doesn't have to be in kernel.

Or a third option, which derives from the second one:

 - Move the whole terminal selection code away from kernel, into a module
   (e.g. terminal.mod) that manages multiple terminals, and can possibly
   enable them simultaneously.

This basicaly would mean:

  - There's always a "default" terminal that is built into kernel already.
    Before terminal.mod is loaded, the kernel would map generic terminal
    functions (grub_getkey(), etc) to this terminal (e.g. using a single
    grub_term_{input,output} couple of pointers).

  - When loading terminal.mod, it hooks itself by replacing those two
    pointers, and implements the whole register / unregister / iterate
    enchilada.

  - Some special casing would be needed so that the in-kernel terminals
    can be part of terminal.mod's scheme.

What I like in this option is that it moves complexity (and code) away from
kernel without removing any functionality from it.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH] terminal split
  2008-11-07 19:07       ` Robert Millan
@ 2008-11-09  7:22         ` Yoshinori K. Okuji
  0 siblings, 0 replies; 19+ messages in thread
From: Yoshinori K. Okuji @ 2008-11-09  7:22 UTC (permalink / raw)
  To: The development of GRUB 2

On Friday 07 November 2008 20:07:07 Robert Millan wrote:
> On Thu, Nov 06, 2008 at 06:20:57PM +0100, Yoshinori K. Okuji wrote:
> > Also, a similar technique can be used to implement "getting an output as
> > a string". For example:
> >
> >   # Use the same password as the super user.
> >   set password=$(sed -ne '/^root:/{s/root:\([^:]*\).*/\1/;p}'
> > /etc/shadow)
>
> This would work much better in grub-mkconfig.  You don't want to implement
> (or port) sed do you? ;-)

I don't want to duplicate information when they should be indentical. 
Synchronization is a nightmare. sed is just an example. You can use 'cut' in 
this case as well.

Regards,
Okuji



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Multi-terminal support (Re: [PATCH] terminal split)
  2008-11-07 19:26     ` [RFC] Multi-terminal support (Re: [PATCH] terminal split) Robert Millan
@ 2008-11-22 17:42       ` Yoshinori K. Okuji
  2008-11-22 19:54         ` Robert Millan
  0 siblings, 1 reply; 19+ messages in thread
From: Yoshinori K. Okuji @ 2008-11-22 17:42 UTC (permalink / raw)
  To: The development of GRUB 2

On Friday 07 November 2008 20:26:32 Robert Millan wrote:
> On Tue, Nov 04, 2008 at 08:12:56PM +0100, Robert Millan wrote:
> >   - Turn the grub_cur_term_{input,output} pointers into lists, so that
> >     multiple terminals can be "current" at the same time.
> >
> >   - Implement a "magic" input (or output) terminal that can be attached
> > to other terminals and reads from (or writes to) more than one of them.
> > The advantage of this is that the code doesn't have to be in kernel.
>
> Or a third option, which derives from the second one:
>
>  - Move the whole terminal selection code away from kernel, into a module
>    (e.g. terminal.mod) that manages multiple terminals, and can possibly
>    enable them simultaneously.

My feeling is that it is better to include all the functionality in the kernel 
itself, because the users of the terminal API would have to be aware of the 
presence of multiple terminals in some cases, anyway.

When you just print out a string, you can treat all kinds of terminals as dumb 
terminals, so it is very simple. No need to care about their differences.

However, whenever you want to do more than that, you must control each 
terminal differently. In particular, the menu code. The menu interface may 
not be uniform with all terminals. A terminal might have the size 80x25. 
Another might have 120x40. This is more complex with graphical terminals.

I like the idea that GRUB displays the user interface simultaneously. But this 
requires a lot of refactoring. Probably, the menu code will have to iterate 
all terminals explicitly, and make actions differently for each terminal, 
based on the capabilities. With the menu editor, how should the cursor be 
managed? We need to think a lot.

Regards,
Okuji



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Multi-terminal support (Re: [PATCH] terminal split)
  2008-11-22 17:42       ` Yoshinori K. Okuji
@ 2008-11-22 19:54         ` Robert Millan
  2008-11-25 21:23           ` Yoshinori K. Okuji
  0 siblings, 1 reply; 19+ messages in thread
From: Robert Millan @ 2008-11-22 19:54 UTC (permalink / raw)
  To: The development of GRUB 2

On Sat, Nov 22, 2008 at 06:42:54PM +0100, Yoshinori K. Okuji wrote:
> 
> However, whenever you want to do more than that, you must control each 
> terminal differently. In particular, the menu code. The menu interface may 
> not be uniform with all terminals. A terminal might have the size 80x25. 
> Another might have 120x40. This is more complex with graphical terminals.

This problem does only happen with output terminals, right?  My primary
concern are input terminals, because if we want to support USB keyboards
we need to probe from both USB and AT ones at the same time.

> I like the idea that GRUB displays the user interface simultaneously. But this 
> requires a lot of refactoring. Probably, the menu code will have to iterate 
> all terminals explicitly, and make actions differently for each terminal, 
> based on the capabilities. With the menu editor, how should the cursor be 
> managed? We need to think a lot.

I've been thinking... what if we make this generic?  I.e. with an event loop,
then terminals can register their poll functions to it, and write their stuff
to a shared resource the rest of GRUB can read from.

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Multi-terminal support (Re: [PATCH] terminal split)
  2008-11-22 19:54         ` Robert Millan
@ 2008-11-25 21:23           ` Yoshinori K. Okuji
  2008-11-26 11:41             ` SPAM-LOW: " Amin Azez
  2008-11-28 20:38             ` Robert Millan
  0 siblings, 2 replies; 19+ messages in thread
From: Yoshinori K. Okuji @ 2008-11-25 21:23 UTC (permalink / raw)
  To: The development of GRUB 2

On Saturday 22 November 2008 20:54:57 Robert Millan wrote:
> On Sat, Nov 22, 2008 at 06:42:54PM +0100, Yoshinori K. Okuji wrote:
> > However, whenever you want to do more than that, you must control each
> > terminal differently. In particular, the menu code. The menu interface
> > may not be uniform with all terminals. A terminal might have the size
> > 80x25. Another might have 120x40. This is more complex with graphical
> > terminals.
>
> This problem does only happen with output terminals, right?  My primary
> concern are input terminals, because if we want to support USB keyboards
> we need to probe from both USB and AT ones at the same time.

Yes.

> > I like the idea that GRUB displays the user interface simultaneously. But
> > this requires a lot of refactoring. Probably, the menu code will have to
> > iterate all terminals explicitly, and make actions differently for each
> > terminal, based on the capabilities. With the menu editor, how should the
> > cursor be managed? We need to think a lot.
>
> I've been thinking... what if we make this generic?  I.e. with an event
> loop, then terminals can register their poll functions to it, and write
> their stuff to a shared resource the rest of GRUB can read from.

For inputs, this is trivial for me. But, for outputs, not simple. For example, 
although we don't support yet in GRUB 2, if we have a dumb terminal, the menu 
interface must be very different from others.

Regards,
Okuji



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: SPAM-LOW: Re: [RFC] Multi-terminal support (Re: [PATCH] terminal split)
  2008-11-25 21:23           ` Yoshinori K. Okuji
@ 2008-11-26 11:41             ` Amin Azez
  2008-11-28 20:38             ` Robert Millan
  1 sibling, 0 replies; 19+ messages in thread
From: Amin Azez @ 2008-11-26 11:41 UTC (permalink / raw)
  To: The development of GRUB 2

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

* Yoshinori K. Okuji wrote, On 25/11/08 21:23:
> On Saturday 22 November 2008 20:54:57 Robert Millan wrote:
>   
>> On Sat, Nov 22, 2008 at 06:42:54PM +0100, Yoshinori K. Okuji wrote:
>>     
>>> However, whenever you want to do more than that, you must control each
>>> terminal differently. In particular, the menu code. The menu interface
>>> may not be uniform with all terminals. A terminal might have the size
>>> 80x25. Another might have 120x40. This is more complex with graphical
>>> terminals.
>>>       
>> This problem does only happen with output terminals, right?  My primary
>> concern are input terminals, because if we want to support USB keyboards
>> we need to probe from both USB and AT ones at the same time.
>>     
>
> Yes.
>
>   
>>> I like the idea that GRUB displays the user interface simultaneously. But
>>> this requires a lot of refactoring. Probably, the menu code will have to
>>> iterate all terminals explicitly, and make actions differently for each
>>> terminal, based on the capabilities. With the menu editor, how should the
>>> cursor be managed? We need to think a lot.
>>>       
>> I've been thinking... what if we make this generic?  I.e. with an event
>> loop, then terminals can register their poll functions to it, and write
>> their stuff to a shared resource the rest of GRUB can read from.
>>     
>
> For inputs, this is trivial for me. But, for outputs, not simple. For example, 
> although we don't support yet in GRUB 2, if we have a dumb terminal, the menu 
> interface must be very different from others.
>   

I just noticed this converation.

I use 2x16 character 4 button serial terminals, and on "some" of them
you have to poll for keypresses! (And ideally convert a bitmap into
keycodes, and debounce).

Sam

[-- Attachment #2: Type: text/html, Size: 2373 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Multi-terminal support (Re: [PATCH] terminal split)
  2008-11-25 21:23           ` Yoshinori K. Okuji
  2008-11-26 11:41             ` SPAM-LOW: " Amin Azez
@ 2008-11-28 20:38             ` Robert Millan
  2008-11-29 21:20               ` Vesa Jääskeläinen
  1 sibling, 1 reply; 19+ messages in thread
From: Robert Millan @ 2008-11-28 20:38 UTC (permalink / raw)
  To: The development of GRUB 2

On Tue, Nov 25, 2008 at 10:23:52PM +0100, Yoshinori K. Okuji wrote:
> >
> > I've been thinking... what if we make this generic?  I.e. with an event
> > loop, then terminals can register their poll functions to it, and write
> > their stuff to a shared resource the rest of GRUB can read from.
> 
> For inputs, this is trivial for me. But, for outputs, not simple. For example, 
> although we don't support yet in GRUB 2, if we have a dumb terminal, the menu 
> interface must be very different from others.

Aside from the problem with output ones, what to you think of the event loop
idea?  It can be useful exploit the parellelism in hardware initialisations.
Currently GRUB can do silly things like:

  - wait for keyboard controller in grub_keyboard_controller_read() and in
    grub_keyboard_controller_write()
  - move on
  - wait for ATA disk in grub_atapi_read()
  - move on
  - wait for _user_ to stare at the menu and pick an option
  - move on

which could be avoided this way (instead of waiting, each function would
register a hook that will be repeatedly run untill it returns non-zero).

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC] Multi-terminal support (Re: [PATCH] terminal split)
  2008-11-28 20:38             ` Robert Millan
@ 2008-11-29 21:20               ` Vesa Jääskeläinen
  0 siblings, 0 replies; 19+ messages in thread
From: Vesa Jääskeläinen @ 2008-11-29 21:20 UTC (permalink / raw)
  To: The development of GRUB 2

Robert Millan wrote:
> On Tue, Nov 25, 2008 at 10:23:52PM +0100, Yoshinori K. Okuji wrote:
>>> I've been thinking... what if we make this generic?  I.e. with an event
>>> loop, then terminals can register their poll functions to it, and write
>>> their stuff to a shared resource the rest of GRUB can read from.
>> For inputs, this is trivial for me. But, for outputs, not simple. For example, 
>> although we don't support yet in GRUB 2, if we have a dumb terminal, the menu 
>> interface must be very different from others.
> 
> Aside from the problem with output ones, what to you think of the event loop
> idea?  It can be useful exploit the parellelism in hardware initialisations.
> Currently GRUB can do silly things like:
> 
>   - wait for keyboard controller in grub_keyboard_controller_read() and in
>     grub_keyboard_controller_write()
>   - move on
>   - wait for ATA disk in grub_atapi_read()
>   - move on
>   - wait for _user_ to stare at the menu and pick an option
>   - move on
> 
> which could be avoided this way (instead of waiting, each function would
> register a hook that will be repeatedly run untill it returns non-zero).

Well... I think better road would be co-operative multitasking. While
waiting for hardware to respond you could give time to other tasks to
handle their stuff. This would also make easier to write such tasks as
you do not have to think about complex event system. System you propose
can get quite complex to understand and maintain.



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2008-11-29 21:21 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-02 18:11 [PATCH] terminal split Robert Millan
2008-11-04 15:52 ` Yoshinori K. Okuji
2008-11-04 17:14   ` Robert Millan
2008-11-06 17:05     ` Yoshinori K. Okuji
2008-11-07 19:13       ` Robert Millan
2008-11-04 18:31   ` Vesa Jääskeläinen
2008-11-06 17:20     ` Yoshinori K. Okuji
2008-11-07 19:07       ` Robert Millan
2008-11-09  7:22         ` Yoshinori K. Okuji
2008-11-04 18:53 ` Vesa Jääskeläinen
2008-11-04 19:12   ` Robert Millan
2008-11-04 19:49     ` Colin D Bennett
2008-11-07 19:26     ` [RFC] Multi-terminal support (Re: [PATCH] terminal split) Robert Millan
2008-11-22 17:42       ` Yoshinori K. Okuji
2008-11-22 19:54         ` Robert Millan
2008-11-25 21:23           ` Yoshinori K. Okuji
2008-11-26 11:41             ` SPAM-LOW: " Amin Azez
2008-11-28 20:38             ` Robert Millan
2008-11-29 21:20               ` Vesa Jääskeläinen

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.