]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Merge mainline into multiterm
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 5 Jan 2010 15:27:41 +0000 (16:27 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 5 Jan 2010 15:27:41 +0000 (16:27 +0100)
30 files changed:
1  2 
Makefile.in
commands/handler.c
commands/help.c
commands/keystatus.c
commands/password.c
commands/sleep.c
commands/terminal.c
commands/xnu_uuid.c
conf/any-emu.rmk
conf/common.rmk
genmk.rb
include/grub/disk.h
include/grub/misc.h
include/grub/term.h
kern/main.c
kern/misc.c
loader/i386/efi/linux.c
loader/i386/ieee1275/linux.c
loader/i386/linux.c
normal/cmdline.c
normal/main.c
normal/menu_entry.c
normal/menu_text.c
normal/menu_viewer.c
term/gfxterm.c
term/i386/pc/at_keyboard.c
term/i386/pc/serial.c
term/ieee1275/ofconsole.c
term/terminfo.c
util/grub-editenv.c

diff --cc Makefile.in
Simple merge
index 60889dd5ebf7579abb33cfb9d5d67b04624ca3a4,7316db3049e7224e4064b806e3aaa7f7d1ec9754..f9270972bb65a8a66971e23914a1f79023990f34
  #include <grub/term.h>
  #include <grub/handler.h>
  #include <grub/command.h>
+ #include <grub/i18n.h>
  
  static grub_err_t
 -grub_cmd_handler (struct grub_command *cmd,
 +grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)),
                  int argc, char **args)
  {
 -  char *class_name;
    void *curr_item = 0;
    grub_handler_class_t head;
  
@@@ -90,8 -96,16 +91,8 @@@ GRUB_MOD_INIT(handler
  {
    cmd_handler =
      grub_register_command ("handler", grub_cmd_handler,
-                          "handler [class [handler]]",
-                          "List or select a handler.");
+                          N_("[class [handler]]"),
+                          N_("List or select a handler."));
 -  cmd_terminal_input =
 -    grub_register_command ("terminal_input", grub_cmd_handler,
 -                         N_("[handler]"),
 -                         N_("List or select an input terminal."));
 -  cmd_terminal_output =
 -    grub_register_command ("terminal_output", grub_cmd_handler,
 -                         N_("[handler]"),
 -                         N_("List or select an output terminal."));
  }
  
  GRUB_MOD_FINI(handler)
diff --cc commands/help.c
index bfca5e0cc1070b92a016a7312c258fff5ff1c92f,7edc23563bd6d431748fb23685bf5d3e80da3481..9234a3697da75886a166f1719b39960d10a4670e
  #include <grub/misc.h>
  #include <grub/term.h>
  #include <grub/extcmd.h>
+ #include <grub/i18n.h>
+ #include <grub/mm.h>
+ #include <grub/normal.h>
++#include <grub/charset.h>
  
  static grub_err_t
  grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
        if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) &&
          (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE))
        {
-         struct grub_term_output *cur;
-         int desclen = grub_strlen (cmd->summary);
-         FOR_ACTIVE_TERM_OUTPUTS(cur)
++        struct grub_term_output *term;
++        const char *summary_translated = _(cmd->summary);
+         char *command_help;
 -        int stringwidth;
+         grub_uint32_t *unicode_command_help;
+         grub_uint32_t *unicode_last_position;
 -        grub_uint32_t *unicode_last_screen_position;
 -        const char *summary_translated = _(cmd->summary);
+         command_help = grub_malloc (grub_strlen (cmd->name) +
+                                     sizeof (" ") - 1 +
+                                     grub_strlen (summary_translated));
+                                     
+         grub_sprintf(command_help, "%s %s", cmd->name, summary_translated);
+         grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help,
+                                  &unicode_last_position);
 -        
 -        unicode_last_screen_position = unicode_command_help;
 -
 -        stringwidth = 0;
 -
 -        while (unicode_last_screen_position < unicode_last_position && 
 -               stringwidth < ((GRUB_TERM_WIDTH / 2) - 2))
 -          {
 -            stringwidth += grub_getcharwidth (*unicode_last_screen_position);
 -            unicode_last_screen_position++;
 -          }
 -        grub_print_ucs4 (unicode_command_help, unicode_last_screen_position);
 -        
 -        if ((cnt++) % 2)
 -          {
 -            grub_putchar ('\n');
 -          }
 -          else
 -          {
 -            grub_print_spaces (GRUB_TERM_WIDTH / 2 - stringwidth);
 -          }
++        FOR_ACTIVE_TERM_OUTPUTS(term)
 +        {
-           int width = grub_term_width(cur);
-           char description[width / 2];
-           /* Make a string with a length of GRUB_TERM_WIDTH / 2 - 1 filled
-              with the description followed by spaces.  */
-           grub_memset (description, ' ', width / 2 - 1);
-           description[width / 2 - 1] = '\0';
-           grub_memcpy (description, cmd->summary,
-                        (desclen < width / 2 - 1
-                         ? desclen : width / 2 - 1));
-           grub_puts_terminal (description, cur);
++          unsigned stringwidth;
++          grub_uint32_t *unicode_last_screen_position;
++
++          unicode_last_screen_position = unicode_command_help;
++
++          stringwidth = 0;
++
++          while (unicode_last_screen_position < unicode_last_position && 
++                 stringwidth < ((grub_term_width (term) / 2) - 2))
++            {
++              stringwidth
++                += grub_term_getcharwidth (term,
++                                           *unicode_last_screen_position);
++              unicode_last_screen_position++;
++            }
++
++          grub_print_ucs4 (unicode_command_help,
++                           unicode_last_screen_position, term);
++          if (!(cnt % 2))
++            grub_print_spaces (term, grub_term_width (term) / 2
++                               - stringwidth);
 +        }
-         if ((cnt++) % 2)
++        if (cnt % 2)
 +          grub_printf ("\n");
-         else
-           grub_printf (" ");
++        cnt++;
+         
+         grub_free (command_help);
+         grub_free (unicode_command_help);
        }
        return 0;
      }
Simple merge
index 7bb2f0ae59e1f49b73a5bd5c0ed97e5cac863675,2869ffc53b33c467025e91207877382b031fb0b7..04285254e31f8d4554d214270ee8a97bae58bb9f
@@@ -45,18 -52,13 +46,18 @@@ grub_cmd_password (grub_command_t cmd _
  {
    grub_err_t err;
    char *pass;
 +  int copylen;
  
    if (argc != 2)
-     return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected.");
+     return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected");
  
 -  pass = grub_strdup (args[1]);
 +  pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN);
    if (!pass)
      return grub_errno;
 +  copylen = grub_strlen (args[1]);
 +  if (copylen >= GRUB_AUTH_MAX_PASSLEN)
 +    copylen = GRUB_AUTH_MAX_PASSLEN - 1;
 +  grub_memcpy (pass, args[1], copylen);
  
    err = grub_auth_register_authentication (args[0], check_password, pass);
    if (err)
Simple merge
index 0fff70a69597665a653f5df85c6629a159b5c7a2,0000000000000000000000000000000000000000..b30f43130fb91be1e4e956c69fa48d5e77587fcf
mode 100644,000000..100644
--- /dev/null
@@@ -1,364 -1,0 +1,364 @@@
-                          "terminal_input [--append|--remove] "
 +/*
 + *  GRUB  --  GRand Unified Bootloader
 + *  Copyright (C) 2009  Free Software Foundation, Inc.
 + *
 + *  GRUB is free software: you can redistribute it and/or modify
 + *  it under the terms of the GNU General Public License as published by
 + *  the Free Software Foundation, either version 3 of the License, or
 + *  (at your option) any later version.
 + *
 + *  GRUB is distributed in the hope that it will be useful,
 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + *  GNU General Public License for more details.
 + *
 + *  You should have received a copy of the GNU General Public License
 + *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 + */
 +
 +#include <grub/mm.h>
 +#include <grub/dl.h>
 +#include <grub/command.h>
 +#include <grub/term.h>
 +#include <grub/i18n.h>
 +#include <grub/misc.h>
 +
 +struct grub_term_autoload *grub_term_input_autoload = NULL;
 +struct grub_term_autoload *grub_term_output_autoload = NULL;
 +
 +static grub_err_t
 +grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
 +                       int argc, char **args)
 +{
 +  int i;
 +  grub_term_input_t term;
 +  struct grub_term_autoload *aut;
 +
 +  if (argc == 0)
 +    {
 +      grub_puts_ (N_ ("Active input terminals:"));
 +      FOR_ACTIVE_TERM_INPUTS(term)
 +      grub_printf ("%s ", term->name);
 +      grub_printf ("\n");
 +      grub_puts_ (N_ ("Available input terminals:"));
 +      FOR_DISABLED_TERM_INPUTS(term)
 +      grub_printf ("%s ", term->name);
 +      /* This is quadratic but we don't expect mode than 30 terminal
 +       modules ever.  */
 +      for (aut = grub_term_input_autoload; aut; aut = aut->next)
 +      {
 +        FOR_DISABLED_TERM_INPUTS(term)
 +          if (grub_strcmp (term->name, aut->name) == 0)
 +            break;
 +        if (!term)
 +          FOR_ACTIVE_TERM_INPUTS(term)
 +            if (grub_strcmp (term->name, aut->name) == 0)
 +              break;
 +        if (!term)
 +          grub_printf ("%s ", aut->name);
 +      }
 +      grub_printf ("\n");
 +      return GRUB_ERR_NONE;
 +    }
 +  i = 0;
 +
 +  if (grub_strcmp (args[0], "--append") == 0
 +      || grub_strcmp (args[0], "--remove") == 0)
 +    i++;
 +
 +  if (i == argc)
 +    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
 +
 +  for (; i < argc; i++)
 +    {
 +      int again = 0;
 +      while (1)
 +      {
 +        FOR_DISABLED_TERM_INPUTS(term)
 +          if (grub_strcmp (args[i], term->name) == 0)
 +            break;
 +        if (term == 0)
 +          FOR_ACTIVE_TERM_INPUTS(term)
 +            if (grub_strcmp (args[i], term->name) == 0)
 +              break;
 +        if (term)
 +          break;
 +        if (again)
 +          return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
 +                             args[i]);
 +        for (aut = grub_term_input_autoload; aut; aut = aut->next)
 +          if (grub_strcmp (args[i], aut->name) == 0)
 +            {
 +              grub_dl_t mod;
 +              mod = grub_dl_load (aut->modname);
 +              if (mod)
 +                grub_dl_ref (mod);
 +              grub_errno = GRUB_ERR_NONE;
 +              break;
 +            }
 +        if (!aut)
 +          return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
 +                             args[i]);
 +        again = 1;
 +      }
 +    }
 +
 +  if (grub_strcmp (args[0], "--append") == 0)
 +    {
 +      for (i = 1; i < argc; i++)
 +      {
 +        FOR_DISABLED_TERM_INPUTS(term)
 +          if (grub_strcmp (args[i], term->name) == 0)
 +            break;
 +        if (term)
 +          {
 +            grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
 +                              GRUB_AS_LIST (term));
 +            if (term->init)
 +              term->init ();
 +            grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
 +                            GRUB_AS_LIST (term));
 +          }
 +      }
 +      return GRUB_ERR_NONE;
 +    }
 +
 +  if (grub_strcmp (args[0], "--remove") == 0)
 +    {
 +      for (i = 1; i < argc; i++)
 +      {
 +        FOR_ACTIVE_TERM_INPUTS(term)
 +          if (grub_strcmp (args[i], term->name) == 0)
 +            break;
 +        if (term)
 +          {
 +            if (!term->next && term == grub_term_inputs)
 +              return grub_error (GRUB_ERR_BAD_ARGUMENT,
 +                                 "can't remove the last terminal");
 +            grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
 +                              GRUB_AS_LIST (term));
 +            if (term->fini)
 +              term->fini ();
 +            grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
 +                            GRUB_AS_LIST (term));
 +          }
 +      }
 +      return GRUB_ERR_NONE;
 +    }
 +  for (i = 0; i < argc; i++)
 +    {
 +      FOR_DISABLED_TERM_INPUTS(term)
 +      if (grub_strcmp (args[i], term->name) == 0)
 +        break;
 +      if (term)
 +      {
 +        grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)),
 +                          GRUB_AS_LIST (term));
 +        if (term->init)
 +          term->init ();
 +        grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs),
 +                        GRUB_AS_LIST (term));
 +      }       
 +    }
 +
 +  FOR_ACTIVE_TERM_INPUTS(term)
 +  {
 +    for (i = 0; i < argc; i++)
 +      if (grub_strcmp (args[i], term->name) == 0)
 +      break;
 +    if (i == argc)
 +      {
 +      if (!term->next && term == grub_term_inputs)
 +        return grub_error (GRUB_ERR_BAD_ARGUMENT,
 +                           "can't remove the last terminal");
 +      grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)),
 +                        GRUB_AS_LIST (term));
 +      if (term->fini)
 +        term->fini ();
 +      grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled),
 +                      GRUB_AS_LIST (term));
 +      }
 +  }
 +
 +  return GRUB_ERR_NONE;
 +}
 +
 +static grub_err_t
 +grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
 +                       int argc, char **args)
 +{
 +  int i;
 +  grub_term_output_t term;
 +  struct grub_term_autoload *aut;
 +
 +  if (argc == 0)
 +    {
 +      grub_puts_ (N_ ("Active output terminals:"));
 +      FOR_ACTIVE_TERM_OUTPUTS(term)
 +      grub_printf ("%s ", term->name);
 +      grub_printf ("\n");
 +      grub_puts_ (N_ ("Available output terminals:"));
 +      FOR_DISABLED_TERM_OUTPUTS(term)
 +      grub_printf ("%s ", term->name);
 +      /* This is quadratic but we don't expect mode than 30 terminal
 +       modules ever.  */
 +      for (aut = grub_term_output_autoload; aut; aut = aut->next)
 +      {
 +        FOR_DISABLED_TERM_OUTPUTS(term)
 +          if (grub_strcmp (term->name, aut->name) == 0)
 +            break;
 +        if (!term)
 +          FOR_ACTIVE_TERM_OUTPUTS(term)
 +            if (grub_strcmp (term->name, aut->name) == 0)
 +              break;
 +        if (!term)
 +          grub_printf ("%s ", aut->name);
 +      }
 +      grub_printf ("\n");
 +      return GRUB_ERR_NONE;
 +    }
 +  i = 0;
 +
 +  if (grub_strcmp (args[0], "--append") == 0
 +      || grub_strcmp (args[0], "--remove") == 0)
 +    i++;
 +
 +  if (i == argc)
 +    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified"));
 +
 +  for (; i < argc; i++)
 +    {
 +      int again = 0;
 +      while (1)
 +      {
 +        FOR_DISABLED_TERM_OUTPUTS(term)
 +          if (grub_strcmp (args[i], term->name) == 0)
 +            break;
 +        if (term == 0)
 +          FOR_ACTIVE_TERM_OUTPUTS(term)
 +            if (grub_strcmp (args[i], term->name) == 0)
 +              break;
 +        if (term)
 +          break;
 +        if (again)
 +          return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
 +                             args[i]);
 +        for (aut = grub_term_output_autoload; aut; aut = aut->next)
 +          if (grub_strcmp (args[i], aut->name) == 0)
 +            {
 +              grub_dl_t mod;
 +              mod = grub_dl_load (aut->modname);
 +              if (mod)
 +                grub_dl_ref (mod);
 +              grub_errno = GRUB_ERR_NONE;
 +              break;
 +            }
 +        if (!aut)
 +          return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n",
 +                             args[i]);
 +        again = 1;
 +      }
 +    }
 +
 +  if (grub_strcmp (args[0], "--append") == 0)
 +    {
 +      for (i = 1; i < argc; i++)
 +      {
 +        FOR_DISABLED_TERM_OUTPUTS(term)
 +          if (grub_strcmp (args[i], term->name) == 0)
 +            break;
 +        if (term)
 +          {
 +            grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
 +                              GRUB_AS_LIST (term));
 +            if (term->init)
 +              term->init ();
 +            grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
 +                            GRUB_AS_LIST (term));
 +          }
 +      }
 +      return GRUB_ERR_NONE;
 +    }
 +
 +  if (grub_strcmp (args[0], "--remove") == 0)
 +    {
 +      for (i = 1; i < argc; i++)
 +      {
 +        FOR_ACTIVE_TERM_OUTPUTS(term)
 +          if (grub_strcmp (args[i], term->name) == 0)
 +            break;
 +        if (term)
 +          {
 +            if (!term->next && term == grub_term_outputs)
 +              return grub_error (GRUB_ERR_BAD_ARGUMENT,
 +                                 "can't remove the last terminal");
 +            grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
 +                              GRUB_AS_LIST (term));
 +            if (term->fini)
 +              term->fini ();
 +            grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
 +                            GRUB_AS_LIST (term));
 +          }
 +      }
 +      return GRUB_ERR_NONE;
 +    }
 +
 +  for (i = 0; i < argc; i++)
 +    {
 +      FOR_DISABLED_TERM_OUTPUTS(term)
 +      if (grub_strcmp (args[i], term->name) == 0)
 +        break;
 +      if (term)
 +      {
 +        grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
 +                          GRUB_AS_LIST (term));
 +        if (term->init)
 +          term->init ();
 +        grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs),
 +                        GRUB_AS_LIST (term));
 +      }       
 +    }
 +
 +  FOR_ACTIVE_TERM_OUTPUTS(term)
 +  {
 +    for (i = 0; i < argc; i++)
 +      if (grub_strcmp (args[i], term->name) == 0)
 +      break;
 +    if (i == argc)
 +      {
 +      if (!term->next && term == grub_term_outputs)
 +        return grub_error (GRUB_ERR_BAD_ARGUMENT,
 +                           "can't remove the last terminal");
 +      grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)),
 +                        GRUB_AS_LIST (term));
 +      if (term->fini)
 +        term->fini ();
 +      grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled),
 +                      GRUB_AS_LIST (term));
 +      }
 +  }
 +
 +  return GRUB_ERR_NONE;
 +}
 +
 +static grub_command_t cmd_terminal_input, cmd_terminal_output;
 +
 +GRUB_MOD_INIT(terminal)
 +{
 +  cmd_terminal_input =
 +    grub_register_command ("terminal_input", grub_cmd_terminal_input,
-                          "terminal_output [--append|--remove] "
++                         "[--append|--remove] "
 +                         "[TERMINAL1] [TERMINAL2] ...",
 +                         "List or select an input terminal.");
 +  cmd_terminal_output =
 +    grub_register_command ("terminal_output", grub_cmd_terminal_output,
++                         "[--append|--remove] "
 +                         "[TERMINAL1] [TERMINAL2] ...",
 +                         "List or select an output terminal.");
 +}
 +
 +GRUB_MOD_FINI(terminal)
 +{
 +  grub_unregister_command (cmd_terminal_input);
 +  grub_unregister_command (cmd_terminal_output);
 +}
index c43c4bf37738a9d7a61adef78ab24f438f726f5a,b94dc0dc7c0f0b27e172f72c67af0457008eb54f..b01352269a46c72d6427e1953453b89323921895
  #include <grub/misc.h>
  #include <grub/env.h>
  #include <grub/command.h>
 +#include <grub/crypto.h>
+ #include <grub/i18n.h>
  
 -struct tohash
 -{
 -  grub_uint8_t prefix[16];
 -  grub_uint64_t serial;
 -} __attribute__ ((packed));
 -
  /* This prefix is used by xnu and boot-132 to hash
     together with volume serial. */
  static grub_uint8_t hash_prefix[16]
Simple merge
diff --cc conf/common.rmk
Simple merge
diff --cc genmk.rb
Simple merge
Simple merge
Simple merge
index 922ccb2d2b09450865482d77b684e46620e101b6,ec158353d0055455f4ddaf8bb3f1b0ba8fd73f0a..1c57a4ede4b608ab0584564235806f98a07b537f
@@@ -243,168 -250,63 +243,176 @@@ grub_term_unregister_input (grub_term_i
  static inline void
  grub_term_unregister_output (grub_term_output_t term)
  {
 -  grub_handler_unregister (&grub_term_output_class, GRUB_AS_HANDLER (term));
 +  grub_list_remove (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term));
 +  grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)),
 +                  GRUB_AS_LIST (term));
  }
  
 -static inline grub_err_t
 -grub_term_set_current_input (grub_term_input_t term)
 +#define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next)
 +#define FOR_DISABLED_TERM_INPUTS(var) for (var = grub_term_inputs_disabled; var; var = var->next)
 +#define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next)
 +#define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next)
 +
 +void EXPORT_FUNC(grub_putchar) (int c);
 +void EXPORT_FUNC(grub_putcode) (grub_uint32_t code,
 +                              struct grub_term_output *term);
 +int EXPORT_FUNC(grub_getkey) (void);
 +int EXPORT_FUNC(grub_checkkey) (void);
 +int EXPORT_FUNC(grub_getkeystatus) (void);
 +void EXPORT_FUNC(grub_cls) (void);
 +void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
 +void EXPORT_FUNC(grub_refresh) (void);
 +void grub_puts_terminal (const char *str, struct grub_term_output *term);
 +grub_uint16_t *grub_term_save_pos (void);
 +void grub_term_restore_pos (grub_uint16_t *pos);
 +
 +static inline unsigned grub_term_width (struct grub_term_output *term)
  {
 -  return grub_handler_set_current (&grub_term_input_class,
 -                                 GRUB_AS_HANDLER (term));
 +  return ((term->getwh()&0xFF00)>>8);
  }
  
 -static inline grub_err_t
 -grub_term_set_current_output (grub_term_output_t term)
 +static inline unsigned grub_term_height (struct grub_term_output *term)
  {
 -  return grub_handler_set_current (&grub_term_output_class,
 -                                 GRUB_AS_HANDLER (term));
 +  return (term->getwh()&0xFF);
  }
  
 -static inline grub_term_input_t
 -grub_term_get_current_input (void)
 +/* The width of the border.  */
 +static inline unsigned
 +grub_term_border_width (struct grub_term_output *term)
  {
 -  return (grub_term_input_t) grub_term_input_class.cur_handler;
 +  return grub_term_width (term) - GRUB_TERM_MARGIN * 3 - GRUB_TERM_SCROLL_WIDTH;
  }
  
 -static inline grub_term_output_t
 -grub_term_get_current_output (void)
 +/* The max column number of an entry. The last "-1" is for a
 +   continuation marker.  */
 +static inline int
 +grub_term_entry_width (struct grub_term_output *term)
  {
 -  return (grub_term_output_t) grub_term_output_class.cur_handler;
 +  return grub_term_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1;
  }
  
 -void EXPORT_FUNC(grub_putchar) (int c);
 -void EXPORT_FUNC(grub_putcode) (grub_uint32_t code);
 -grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code);
 -int EXPORT_FUNC(grub_getkey) (void);
 -int EXPORT_FUNC(grub_checkkey) (void);
 -int EXPORT_FUNC(grub_getkeystatus) (void);
 -grub_uint16_t EXPORT_FUNC(grub_getwh) (void);
 -grub_uint16_t EXPORT_FUNC(grub_getxy) (void);
 -void EXPORT_FUNC(grub_gotoxy) (grub_uint8_t x, grub_uint8_t y);
 -void EXPORT_FUNC(grub_cls) (void);
 -void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state);
 -void EXPORT_FUNC(grub_setcolor) (grub_uint8_t normal_color,
 -                               grub_uint8_t highlight_color);
 -void EXPORT_FUNC(grub_getcolor) (grub_uint8_t *normal_color,
 -                               grub_uint8_t *highlight_color);
 -int EXPORT_FUNC(grub_setcursor) (int on);
 -int EXPORT_FUNC(grub_getcursor) (void);
 -void EXPORT_FUNC(grub_refresh) (void);
 -void EXPORT_FUNC(grub_set_more) (int onoff);
 +/* The height of the border.  */
 +
 +static inline unsigned
 +grub_term_border_height (struct grub_term_output *term)
 +{
 +  return grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y
 +    - GRUB_TERM_MESSAGE_HEIGHT;
 +}
 +
 +/* The number of entries shown at a time.  */
 +static inline int
 +grub_term_num_entries (struct grub_term_output *term)
 +{
 +  return grub_term_border_height (term) - 2;
 +}
 +
 +static inline int
 +grub_term_cursor_x (struct grub_term_output *term)
 +{
 +  return (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term) 
 +        - GRUB_TERM_MARGIN - 1);
 +}
 +
 +static inline grub_uint16_t
 +grub_term_getxy (struct grub_term_output *term)
 +{
 +  return term->getxy ();
 +}
 +
 +static inline void
 +grub_term_refresh (struct grub_term_output *term)
 +{
 +  if (term->refresh)
 +    term->refresh ();
 +}
 +
 +static inline void
 +grub_term_gotoxy (struct grub_term_output *term, grub_uint8_t x, grub_uint8_t y)
 +{
 +  term->gotoxy (x, y);
 +}
 +
 +static inline void 
 +grub_term_setcolorstate (struct grub_term_output *term, 
 +                       grub_term_color_state state)
 +{
 +  if (term->setcolorstate)
 +    term->setcolorstate (state);
 +}
 +
 +  /* Set the normal color and the highlight color. The format of each
 +     color is VGA's.  */
 +static inline void 
 +grub_term_setcolor (struct grub_term_output *term,
 +                  grub_uint8_t normal_color, grub_uint8_t highlight_color)
 +{
 +  if (term->setcolor)
 +    term->setcolor (normal_color, highlight_color);
 +}
 +
 +/* Turn on/off the cursor.  */
 +static inline void 
 +grub_term_setcursor (struct grub_term_output *term, int on)
 +{
 +  if (term->setcursor)
 +    term->setcursor (on);
 +}
 +
 +static inline void 
 +grub_term_cls (struct grub_term_output *term)
 +{
 +  if (term->cls)
 +    (term->cls) ();
 +  else
 +    {
 +      grub_putcode ('\n', term);
 +      grub_term_refresh (term);
 +    }
 +}
 +
 +static inline grub_ssize_t 
 +grub_term_getcharwidth (struct grub_term_output *term, grub_uint32_t c)
 +{
 +  if (term->getcharwidth)
 +    return term->getcharwidth (c);
 +  else
 +    return 1;
 +}
 +
 +static inline void 
 +grub_term_getcolor (struct grub_term_output *term, 
 +                  grub_uint8_t *normal_color, grub_uint8_t *highlight_color)
 +{
 +  if (term->getcolor)
 +    term->getcolor (normal_color, highlight_color);
 +  else
 +    {
 +      *normal_color = 0x07;
 +      *highlight_color = 0x07;
 +    }
 +}
 +
 +extern void (*EXPORT_VAR (grub_newline_hook)) (void);
 +
 +struct grub_term_autoload
 +{
 +  struct grub_term_autoload *next;
 +  char *name;
 +  char *modname;
 +};
 +
 +extern struct grub_term_autoload *grub_term_input_autoload;
 +extern struct grub_term_autoload *grub_term_output_autoload;
  
 -grub_print_spaces (int number_spaces)
+ static inline void
 -      grub_putchar (' ');
++grub_print_spaces (struct grub_term_output *term, int number_spaces)
+ {
+   while (--number_spaces >= 0)
++    grub_putcode (' ', term);
+ }
  /* For convenience.  */
  #define GRUB_TERM_ASCII_CHAR(c)       ((c) & 0xff)
  
diff --cc kern/main.c
Simple merge
diff --cc kern/misc.c
Simple merge
Simple merge
Simple merge
Simple merge
index f2c2edf9bc9d46a148c45d372908cbe8abf4b32f,19b83951a02328b857ad81479bdb3283e274bb89..656b14c6abe9d0270935041ddd26401fad330d09
@@@ -318,73 -254,36 +318,73 @@@ grub_cmdline_get (const char *prompt
          grub_size_t saved_lpos = lpos;
  
          lpos = llen - len;
 -        cl_set_pos ();
 -        cl_print (lpos, ' ');
 +        cl_set_pos_all ();
 +        cl_print_all (lpos, ' ');
          lpos = saved_lpos;
 -        cl_set_pos ();
 +        cl_set_pos_all ();
  
 -        grub_memmove (buf + lpos, buf + lpos + len, llen - lpos + 1);
 +        grub_memmove (buf + lpos, buf + lpos + len,
 +                      sizeof (grub_uint32_t) * (llen - lpos + 1));
          llen -= len;
 -        cl_print (lpos, echo_char);
 -        cl_set_pos ();
 +        cl_print_all (lpos, 0);
 +        cl_set_pos_all ();
        }
 -
 -      grub_refresh ();
      }
  
-   plen = grub_strlen (prompt_translated);
 +  void init_clterm (struct cmdline_term *cl_term_cur)
 +  {
 +    cl_term_cur->xpos = plen;
 +    cl_term_cur->ypos = (grub_term_getxy (cl_term_cur->term) & 0xFF);
 +    cl_term_cur->ystart = cl_term_cur->ypos;
 +    cl_term_cur->width = grub_term_width (cl_term_cur->term);
 +    cl_term_cur->height = grub_term_height (cl_term_cur->term);
 +  }
 +
 +  void init_clterm_all (void)
 +  {
 +    unsigned i;
 +    for (i = 0; i < nterms; i++)
 +      init_clterm (&cl_terms[i]);
 +  }
 +
 +  buf = grub_malloc (max_len * sizeof (grub_uint32_t));
 +  if (!buf)
 +    return 0;
 +
+   plen = grub_strlen (prompt_translated) + sizeof (" ") - 1;
    lpos = llen = 0;
    buf[0] = '\0';
  
 -  if ((grub_getxy () >> 8) != 0)
 -    grub_putchar ('\n');
 +  {
 +    grub_term_output_t term;
  
-   grub_printf ("%s", prompt_translated);
 +    FOR_ACTIVE_TERM_OUTPUTS(term)
 +      if ((grub_term_getxy (term) >> 8) != 0)
 +      grub_putcode ('\n', term);
 +  }
+   grub_printf ("%s ", prompt_translated);
  
 -  xpos = plen;
 -  ystart = ypos = (grub_getxy () & 0xFF);
 -
 -  cl_insert (cmdline);
 +  {
 +    struct cmdline_term *cl_term_cur;
 +    struct grub_term_output *cur;
 +    nterms = 0;
 +    FOR_ACTIVE_TERM_OUTPUTS(cur)
 +      nterms++;
 +
 +    cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms);
 +    if (!cl_terms)
 +      return 0;
 +    cl_term_cur = cl_terms;
 +    FOR_ACTIVE_TERM_OUTPUTS(cur)
 +    {
 +      cl_term_cur->term = cur;
 +      init_clterm (cl_term_cur);
 +      cl_term_cur++;
 +    }
 +  }
  
 -  if (history && hist_used == 0)
 -    grub_history_add (buf);
 +  if (hist_used == 0)
 +    grub_history_add (buf, llen);
  
    while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
      {
diff --cc normal/main.c
index 6d7a558f387279608ed30828772daf783455864a,23de7e2388f827d804b1b90cd0d8b435c5ed3de4..cdb816bfc26c4be4abd688f78fbf434ee53bb193
@@@ -549,17 -540,15 +549,17 @@@ grub_normal_reader_init (int nested
    return 0;
  }
  
 -static char cmdline[GRUB_MAX_CMDLINE];
  
  static grub_err_t
 -grub_normal_read_line (char **line, int cont)
 +grub_normal_read_line_real (char **line, int cont, int nested)
  {
    grub_parser_t parser = grub_parser_get_current ();
-   char prompt[sizeof("> ") + grub_strlen (parser->name)];
+   char prompt[sizeof(">") + grub_strlen (parser->name)];
  
 -  grub_sprintf (prompt, "%s>", parser->name);
 +  if (cont)
-     grub_sprintf (prompt, "> ");
++    grub_sprintf (prompt, ">");
 +  else
-     grub_sprintf (prompt, "%s> ", parser->name);
++    grub_sprintf (prompt, "%s>", parser->name);
  
    while (1)
      {
@@@ -639,10 -595,10 +639,10 @@@ GRUB_MOD_INIT(normal
    grub_register_variable_hook ("pager", 0, grub_env_write_pager);
  
    /* Register a command "normal" for the rescue mode.  */
 -  grub_register_command_prio ("normal", grub_cmd_normal,
 -                            0, "Enter normal mode.", 0);
 +  grub_register_command ("normal", grub_cmd_normal,
-                        0, "Enter normal mode");
++                       0, "Enter normal mode.");
 +  grub_register_command ("normal_exit", grub_cmd_normal_exit,
-                        0, "Exit from normal mode");
++                       0, "Exit from normal mode.");
  
    /* Reload terminal colors when these variables are written to.  */
    grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal);
Simple merge
index 91000c1d41a61cd182e4c5735ed140ebb118884d,8ab67a35c97c4e0cec747048acb29551eb619b59..cab1d22f86d92cacb554c48cc5581da32177ba0e
@@@ -106,10 -128,9 +106,10 @@@ grub_print_message_indented (const cha
       
        next_new_line = (grub_uint32_t *) last_position;
  
 -      while (grub_getstringwidth (current_position, next_new_line) > line_len
 +      while (grub_getstringwidth (current_position, next_new_line,term) 
 +           > line_len
-             || (*next_new_line != ' ' && next_new_line > current_position &&
-                 next_new_line != last_position))
+             || (next_new_line != last_position && *next_new_line != ' '
+               && next_new_line > current_position))
         {
           next_new_line--;
         }
@@@ -356,132 -382,352 +356,132 @@@ grub_menu_init_page (int nested, int ed
  }
  
  static void
 -print_timeout (int timeout, int offset)
 +menu_text_print_timeout (int timeout, void *dataptr)
  {
    const char *msg =
-     _("The highlighted entry will be booted automatically in %ds.");
+     _("The highlighted entry will be executed automatically in %ds.");
 +  struct menu_viewer_data *data = dataptr;
 +  char *msg_translated;
 +  int posx;
  
 -  grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
 +  grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
  
 -  char *msg_translated =
 -    grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
 +  msg_translated = grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
 +  if (!msg_translated)
 +    {
 +      grub_print_error ();
 +      grub_errno = GRUB_ERR_NONE;
 +      return;
 +    }
  
    grub_sprintf (msg_translated, msg, timeout);
 -  grub_print_message_indented (msg_translated, 3, 0);
 +  grub_print_message_indented (msg_translated, 3, 0, data->term);
   
 -  int posx;
 -  posx = grub_getxy() >> 8;
 -  grub_print_spaces (GRUB_TERM_WIDTH - posx - 1);
 +  posx = grub_term_getxy (data->term) >> 8;
 +  print_spaces (grub_term_width (data->term) - posx - 1, data->term);
  
 -  grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
 -  grub_refresh ();
 +  grub_term_gotoxy (data->term,
 +                  grub_term_cursor_x (data->term),
 +                  GRUB_TERM_FIRST_ENTRY_Y + data->offset);
 +  grub_term_refresh (data->term);
  }
  
 -/* Show the menu and handle menu entry selection.  Returns the menu entry
 -   index that should be executed or -1 if no entry should be executed (e.g.,
 -   Esc pressed to exit a sub-menu or switching menu viewers).
 -   If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu
 -   entry to be executed is a result of an automatic default selection because
 -   of the timeout.  */
 -static int
 -run_menu (grub_menu_t menu, int nested, int *auto_boot)
 +static void
 +menu_text_set_chosen_entry (int entry, void *dataptr)
  {
 -  int first, offset;
 -  grub_uint64_t saved_time;
 -  int default_entry;
 -  int timeout;
 -
 -  first = 0;
 +  struct menu_viewer_data *data = dataptr;
 +  int oldoffset = data->offset;
 +  int complete_redraw = 0;
  
 -  default_entry = get_entry_number ("default");
 -
 -  /* If DEFAULT_ENTRY is not within the menu entries, fall back to
 -     the first entry.  */
 -  if (default_entry < 0 || default_entry >= menu->size)
 -    default_entry = 0;
 -
 -  /* If timeout is 0, drawing is pointless (and ugly).  */
 -  if (grub_menu_get_timeout () == 0)
 +  data->offset = entry - data->first;
 +  if (data->offset > grub_term_num_entries (data->term) - 1)
      {
 -      *auto_boot = 1;
 -      return default_entry;
 +      data->first = entry - (grub_term_num_entries (data->term) - 1);
 +      data->offset = grub_term_num_entries (data->term) - 1;
 +      complete_redraw = 1;
      }
 -
 -  offset = default_entry;
 -  if (offset > GRUB_TERM_NUM_ENTRIES - 1)
 +  if (data->offset < 0)
      {
 -      first = offset - (GRUB_TERM_NUM_ENTRIES - 1);
 -      offset = GRUB_TERM_NUM_ENTRIES - 1;
 +      data->offset = 0;
 +      data->first = entry;
 +      complete_redraw = 1;
      }
 -
 -  /* Initialize the time.  */
 -  saved_time = grub_get_time_ms ();
 -
 - refresh:
 -  grub_setcursor (0);
 -  grub_menu_init_page (nested, 0);
 -  print_entries (menu, first, offset);
 -  grub_refresh ();
 -
 -  timeout = grub_menu_get_timeout ();
 -
 -  if (timeout > 0)
 -    print_timeout (timeout, offset);
 -
 -  while (1)
 +  if (complete_redraw)
 +    print_entries (data->menu, data->first, data->offset, data->term);
 +  else
      {
 -      int c;
 -      timeout = grub_menu_get_timeout ();
 -
 -      if (timeout > 0)
 -      {
 -        grub_uint64_t current_time;
 -
 -        current_time = grub_get_time_ms ();
 -        if (current_time - saved_time >= 1000)
 -          {
 -            timeout--;
 -            grub_menu_set_timeout (timeout);
 -            saved_time = current_time;
 -            print_timeout (timeout, offset);
 -          }
 -      }
 -
 -      if (timeout == 0)
 -      {
 -        grub_env_unset ("timeout");
 -          *auto_boot = 1;
 -        return default_entry;
 -      }
 -
 -      if (grub_checkkey () >= 0 || timeout < 0)
 -      {
 -        c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
 -
 -        if (timeout >= 0)
 -          {
 -            grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
 -              grub_print_spaces (GRUB_TERM_WIDTH - 1);
 -
 -            grub_env_unset ("timeout");
 -            grub_env_unset ("fallback");
 -            grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
 -          }
 -
 -        switch (c)
 -          {
 -          case GRUB_TERM_HOME:
 -            first = 0;
 -            offset = 0;
 -            print_entries (menu, first, offset);
 -            break;
 -
 -          case GRUB_TERM_END:
 -            offset = menu->size - 1;
 -            if (offset > GRUB_TERM_NUM_ENTRIES - 1)
 -              {
 -                first = offset - (GRUB_TERM_NUM_ENTRIES - 1);
 -                offset = GRUB_TERM_NUM_ENTRIES - 1;
 -              }
 -              print_entries (menu, first, offset);
 -            break;
 -
 -          case GRUB_TERM_UP:
 -          case '^':
 -            if (offset > 0)
 -              {
 -                print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0,
 -                             grub_menu_get_entry (menu, first + offset));
 -                offset--;
 -                print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1,
 -                             grub_menu_get_entry (menu, first + offset));
 -              }
 -            else if (first > 0)
 -              {
 -                first--;
 -                print_entries (menu, first, offset);
 -              }
 -            break;
 -
 -          case GRUB_TERM_DOWN:
 -          case 'v':
 -            if (menu->size > first + offset + 1)
 -              {
 -                if (offset < GRUB_TERM_NUM_ENTRIES - 1)
 -                  {
 -                    print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0,
 -                                 grub_menu_get_entry (menu, first + offset));
 -                    offset++;
 -                    print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1,
 -                                 grub_menu_get_entry (menu, first + offset));
 -                  }
 -                else
 -                  {
 -                    first++;
 -                    print_entries (menu, first, offset);
 -                  }
 -              }
 -            break;
 -
 -          case GRUB_TERM_PPAGE:
 -            if (first == 0)
 -              {
 -                offset = 0;
 -              }
 -            else
 -              {
 -                first -= GRUB_TERM_NUM_ENTRIES;
 -
 -                if (first < 0)
 -                  {
 -                    offset += first;
 -                    first = 0;
 -                  }
 -              }
 -            print_entries (menu, first, offset);
 -            break;
 -
 -          case GRUB_TERM_NPAGE:
 -            if (offset == 0)
 -              {
 -                offset += GRUB_TERM_NUM_ENTRIES - 1;
 -                if (first + offset >= menu->size)
 -                  {
 -                    offset = menu->size - first - 1;
 -                  }
 -              }
 -            else
 -              {
 -                first += GRUB_TERM_NUM_ENTRIES;
 -
 -                if (first + offset >= menu->size)
 -                  {
 -                    first -= GRUB_TERM_NUM_ENTRIES;
 -                    offset += GRUB_TERM_NUM_ENTRIES;
 -
 -                    if (offset > menu->size - 1 ||
 -                        offset > GRUB_TERM_NUM_ENTRIES - 1)
 -                      {
 -                        offset = menu->size - first - 1;
 -                      }
 -                    if (offset > GRUB_TERM_NUM_ENTRIES)
 -                      {
 -                        first += offset - GRUB_TERM_NUM_ENTRIES + 1;
 -                        offset = GRUB_TERM_NUM_ENTRIES - 1;
 -                      }
 -                  }
 -              }
 -            print_entries (menu, first, offset);
 -            break;
 -
 -          case '\n':
 -          case '\r':
 -          case 6:
 -            grub_setcursor (1);
 -              *auto_boot = 0;
 -            return first + offset;
 -
 -          case '\e':
 -            if (nested)
 -              {
 -                grub_setcursor (1);
 -                return -1;
 -              }
 -            break;
 -
 -          case 'c':
 -            grub_cmdline_run (1);
 -            goto refresh;
 -
 -          case 'e':
 -              {
 -                grub_menu_entry_t e = grub_menu_get_entry (menu, first + offset);
 -                if (e)
 -                  grub_menu_entry_run (e);
 -              }
 -            goto refresh;
 -
 -          default:
 -            break;
 -          }
 -
 -        grub_refresh ();
 -      }
 +      print_entry (GRUB_TERM_FIRST_ENTRY_Y + oldoffset, 0,
 +                 grub_menu_get_entry (data->menu, data->first + oldoffset),
 +                 data->term);
 +      print_entry (GRUB_TERM_FIRST_ENTRY_Y + data->offset, 1,
 +                 grub_menu_get_entry (data->menu, data->first + data->offset),
 +                 data->term);
      }
 -
 -  /* Never reach here.  */
 -  return -1;
 +  grub_term_refresh (data->term);
  }
  
 -/* Callback invoked immediately before a menu entry is executed.  */
  static void
 -notify_booting (grub_menu_entry_t entry,
 -              void *userdata __attribute__((unused)))
 +menu_text_fini (void *dataptr)
  {
 -  grub_printf ("  ");
 -  grub_printf_ (N_("Booting \'%s\'"), entry->title);
 -  grub_printf ("\n\n");
 -}
 +  struct menu_viewer_data *data = dataptr;
 +
 +  grub_term_setcursor (data->term, 1);
 +  grub_term_cls (data->term);
  
 -/* Callback invoked when a default menu entry executed because of a timeout
 -   has failed and an attempt will be made to execute the next fallback
 -   entry, ENTRY.  */
 -static void
 -notify_fallback (grub_menu_entry_t entry,
 -               void *userdata __attribute__((unused)))
 -{
 -  grub_printf ("\n   ");
 -  grub_printf_ (N_("Falling back to \'%s\'"), entry->title);
 -  grub_printf ("\n\n");
 -  grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS);
  }
  
 -/* Callback invoked when a menu entry has failed and there is no remaining
 -   fallback entry to attempt.  */
  static void
 -notify_execution_failure (void *userdata __attribute__((unused)))
 +menu_text_clear_timeout (void *dataptr)
  {
 -  if (grub_errno != GRUB_ERR_NONE)
 -    {
 -      grub_print_error ();
 -      grub_errno = GRUB_ERR_NONE;
 -    }
 -  grub_printf ("\n  ");
 -  grub_printf_ (N_("Failed to boot default entries.\n"));
 -  grub_wait_after_message ();
 +  struct menu_viewer_data *data = dataptr;
 +
 +  grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
 +  print_spaces (grub_term_width (data->term) - 1, data->term);
 +  grub_term_gotoxy (data->term, grub_term_cursor_x (data->term),
 +                  GRUB_TERM_FIRST_ENTRY_Y + data->offset);
 +  grub_term_refresh (data->term);
  }
  
 -/* Callbacks used by the text menu to provide user feedback when menu entries
 -   are executed.  */
 -static struct grub_menu_execute_callback execution_callback =
 +grub_err_t 
 +grub_menu_try_text (struct grub_term_output *term, 
 +                  int entry, grub_menu_t menu, int nested)
  {
 -  .notify_booting = notify_booting,
 -  .notify_fallback = notify_fallback,
 -  .notify_failure = notify_execution_failure
 -};
 +  struct menu_viewer_data *data;
 +  struct grub_menu_viewer *instance;
  
 -static grub_err_t
 -show_text_menu (grub_menu_t menu, int nested)
 -{
 -  while (1)
 -    {
 -      int boot_entry;
 -      grub_menu_entry_t e;
 -      int auto_boot;
 +  instance = grub_zalloc (sizeof (*instance));
 +  if (!instance)
 +    return grub_errno;
  
 -      boot_entry = run_menu (menu, nested, &auto_boot);
 -      if (boot_entry < 0)
 -      break;
 +  data = grub_zalloc (sizeof (*data));
 +  if (!data)
 +    {
 +      grub_free (instance);
 +      return grub_errno;
 +    }
  
 -      e = grub_menu_get_entry (menu, boot_entry);
 -      if (! e)
 -      continue; /* Menu is empty.  */
 +  data->term = term;
 +  instance->data = data;
 +  instance->set_chosen_entry = menu_text_set_chosen_entry;
 +  instance->print_timeout = menu_text_print_timeout;
 +  instance->clear_timeout = menu_text_clear_timeout;
 +  instance->fini = menu_text_fini;
  
 -      grub_cls ();
 -      grub_setcursor (1);
 +  data->menu = menu;
  
 -      if (auto_boot)
 -        {
 -          grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
 -        }
 -      else
 -        {
 -          grub_errno = GRUB_ERR_NONE;
 -          grub_menu_execute_entry (e);
 -          if (grub_errno != GRUB_ERR_NONE)
 -            {
 -              grub_print_error ();
 -              grub_errno = GRUB_ERR_NONE;
 -              grub_wait_after_message ();
 -            }
 -        }
 +  data->offset = entry;
 +  data->first = 0;
 +  if (data->offset > grub_term_num_entries (data->term) - 1)
 +    {
 +      data->first = data->offset - (grub_term_num_entries (data->term) - 1);
 +      data->offset = grub_term_num_entries (data->term) - 1;
      }
  
 +  grub_term_setcursor (data->term, 0);
 +  grub_menu_init_page (nested, 0, data->term);
 +  print_entries (menu, data->first, data->offset, data->term);
 +  grub_term_refresh (data->term);
 +  grub_menu_register_viewer (instance);
 +
    return GRUB_ERR_NONE;
  }
 -
 -struct grub_menu_viewer grub_normal_text_menu_viewer =
 -{
 -  .name = "text",
 -  .show_menu = show_text_menu
 -};
index b600e75007a919f8b756d419e7b157460dfcb4b6,f870ccd53e6e42884decc57a6d530f39d42bddbb..b52442f402cf96c5cb1d63afbe8e79ee8814cf61
  #include <grub/menu.h>
  #include <grub/auth.h>
  
 -/* The list of menu viewers.  */
 -static grub_menu_viewer_t menu_viewer_list;
 -
 -void
 -grub_menu_viewer_register (grub_menu_viewer_t viewer)
 -{
 -  viewer->next = menu_viewer_list;
 -  menu_viewer_list = viewer;
 -}
 -
 -static grub_menu_viewer_t get_current_menu_viewer (void)
 -{
 -  const char *selected_name = grub_env_get ("menuviewer");
 -
 -  /* If none selected, pick the last registered one. */
 -  if (selected_name == 0)
 -    return menu_viewer_list;
 -
 -  grub_menu_viewer_t cur;
 -  for (cur = menu_viewer_list; cur; cur = cur->next)
 -    {
 -      if (grub_strcmp (cur->name, selected_name) == 0)
 -        return cur;
 -    }
 -
 -  /* Fall back to the first entry (or null).  */
 -  return menu_viewer_list;
 -}
 -
 -grub_err_t
 -grub_menu_viewer_show_menu (grub_menu_t menu, int nested)
 -{
 -  grub_menu_viewer_t cur = get_current_menu_viewer ();
 -  grub_err_t err1, err2;
 -  if (!cur)
 -    return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menu viewer available");
 -
 -  while (1)
 -    {
 -      err1 = cur->show_menu (menu, nested);
 -      grub_print_error ();
 -
 -      err2 = grub_auth_check_authentication (NULL);
 -      if (err2)
 -      {
 -        grub_print_error ();
 -        grub_errno = GRUB_ERR_NONE;
 -        continue;
 -      }
 -
 -      break;
 -    }
 -
 -  return err1;
 -}
--
diff --cc term/gfxterm.c
index 2a22b9168190c50b7c04617c004e019bbe83bd88,fa19a5d85e2e09182a4aa2852202a0e62dbc65ac..2a7886aa094ec13e62d4119974f5a9be67b02f30
@@@ -953,14 -953,10 +953,14 @@@ static grub_command_t cmd
  
  GRUB_MOD_INIT(term_gfxterm)
  {
 +#ifdef GRUB_MACHINE_MIPS_YEELOONG
 +  grub_term_register_output_active ("gfxterm", &grub_video_term);
 +#else
    grub_term_register_output ("gfxterm", &grub_video_term);
 +#endif
    cmd = grub_register_command ("background_image",
                               grub_gfxterm_background_image_cmd,
-                              0, "Load background image for active terminal");
+                              0, "Load background image for active terminal.");
  }
  
  GRUB_MOD_FINI(term_gfxterm)
Simple merge
Simple merge
Simple merge
diff --cc term/terminfo.c
Simple merge
Simple merge