]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Core changes hopefully finished
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 24 Dec 2009 14:34:33 +0000 (15:34 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 24 Dec 2009 14:34:33 +0000 (15:34 +0100)
23 files changed:
commands/help.c
include/grub/charset.h
include/grub/menu_viewer.h
include/grub/misc.h
include/grub/normal.h
include/grub/term.h
kern/misc.c
kern/term.c
lib/charset.c
normal/auth.c
normal/cmdline.c
normal/color.c
normal/main.c
normal/menu.c
normal/menu_entry.c
normal/menu_text.c
normal/menu_viewer.c
normal/term.c
term/efi/console.c
term/i386/pc/console.c
term/i386/pc/vga_text.c
term/ieee1275/ofconsole.c
util/console.c

index 4d16945af5e6f0a0a66544fffac02b877149d0e3..5e8f0b27a8e8c4cbb02655b5bbda06ca0a772cd0 100644 (file)
@@ -41,7 +41,7 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc,
          int desclen = grub_strlen (cmd->summary);
          for (cur = grub_term_outputs; cur; cur = cur->next)
            {
-             if (!(cur->flags & GRUB_TERM_ACTIVE))
+             if (!grub_term_is_active (cur))
                continue;
              int width = grub_term_width(cur);
              char description[width / 2];
index daaa5c99fabedd7009f44573fbf4b2444eb1096d..fc050da24febbd0976bb8731dfc6cbabe3ba0862 100644 (file)
@@ -112,4 +112,10 @@ grub_utf16_to_utf8 (grub_uint8_t *dest, grub_uint16_t *src,
 /* Convert UCS-4 to UTF-8.  */
 char *grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size);
 
+int
+grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize);
+
+int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
+                            grub_uint32_t **last_position);
+
 #endif
index 725c975488f79142f365eb958d3453eb56aa8e4d..3821219a35c01e4a427685a34bdf2412c27fdbf3 100644 (file)
 
 struct grub_menu_viewer
 {
-  /* The menu viewer name.  */
-  const char *name;
-
-  grub_err_t (*show_menu) (grub_menu_t menu, int nested);
-
   struct grub_menu_viewer *next;
+  void *data;
+  void (*set_chosen_entry) (int entry, void *data);
+  void (*print_timeout) (int timeout, void *data);
+  void (*clear_timeout) (void *data);
+  void (*fini) (void *fini);
 };
-typedef struct grub_menu_viewer *grub_menu_viewer_t;
 
-void grub_menu_viewer_register (grub_menu_viewer_t viewer);
+void grub_menu_register_viewer (struct grub_menu_viewer *viewer);
 
-grub_err_t grub_menu_viewer_show_menu (grub_menu_t menu, int nested);
+grub_err_t grub_menu_register_viewer_init (void (*callback) (int entry,
+                                                            grub_menu_t menu,
+                                                            int nested));
 
 #endif /* GRUB_MENU_VIEWER_HEADER */
index 92fb460cfada50d30971e19f60b23d49ccba3056..9c3193f884c5099f97399fcd215754101c05510a 100644 (file)
@@ -183,11 +183,11 @@ int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ ((
 int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args);
 void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn));
 void EXPORT_FUNC(grub_abort) (void) __attribute__ ((noreturn));
-grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
-                                            grub_size_t destsize,
-                                            const grub_uint8_t *src,
-                                            grub_size_t srcsize,
-                                            const grub_uint8_t **srcend);
+grub_size_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
+                                           grub_size_t destsize,
+                                           const grub_uint8_t *src,
+                                           grub_size_t srcsize,
+                                           const grub_uint8_t **srcend);
 grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
                                          grub_uint32_t d, grub_uint32_t *r);
 
index 33c30b22a5f07ed165cd63fdd41b8ab1402dfccb..91457fc09a80ba5e6fa78bde562887c6ec5f8d12 100644 (file)
@@ -51,15 +51,16 @@ extern struct grub_menu_viewer grub_normal_text_menu_viewer;
 /* Defined in `main.c'.  */
 void grub_enter_normal_mode (const char *config);
 void grub_normal_execute (const char *config, int nested, int batch);
+void grub_menu_init_page (int nested, int edit,
+                         struct grub_term_output *term);
 void grub_normal_init_page (struct grub_term_output *term);
-void grub_menu_init_page (int nested, int edit);
 grub_err_t grub_normal_add_menu_entry (int argc, const char **args,
                                       const char *sourcecode);
 char *grub_file_getline (grub_file_t file);
 void grub_cmdline_run (int nested);
 
 /* Defined in `cmdline.c'.  */
-char *grub_cmdline_get (const char *prompt, unsigned max_len);
+char *grub_cmdline_get (const char *prompt);
 grub_err_t grub_set_history (int newsize);
 
 /* Defined in `completion.c'.  */
@@ -76,14 +77,19 @@ void grub_parse_color_name_pair (grub_uint8_t *ret, const char *name);
 
 /* Defined in `menu_text.c'.  */
 void grub_wait_after_message (void);
-int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
-                            grub_uint32_t **last_position);
 void grub_print_ucs4 (const grub_uint32_t * str,
-                     const grub_uint32_t * last_position);
+                     const grub_uint32_t * last_position,
+                     struct grub_term_output *term);
 grub_ssize_t grub_getstringwidth (grub_uint32_t * str,
-                                 const grub_uint32_t * last_position);
+                                 const grub_uint32_t * last_position,
+                                 struct grub_term_output *term);
 void grub_print_message_indented (const char *msg, int margin_left,
-                                 int margin_right);
+                                 int margin_right,
+                                 struct grub_term_output *term);
+void
+grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested);
+grub_err_t
+grub_show_menu (grub_menu_t menu, int nested);
 
 /* Defined in `handler.c'.  */
 void read_handler_list (void);
index 39a10ed71c76d8d7ecde011aeb5c04426fdf2079..a0b96b4973a5b22ca856dc3f8a35797498c3d1d8 100644 (file)
@@ -111,37 +111,12 @@ grub_term_color_state;
 /* The X position of the left border.  */
 #define GRUB_TERM_LEFT_BORDER_X        GRUB_TERM_MARGIN
 
-/* The width of the border.  */
-#define GRUB_TERM_BORDER_WIDTH (GRUB_TERM_WIDTH \
-                                 - GRUB_TERM_MARGIN * 3 \
-                                - GRUB_TERM_SCROLL_WIDTH)
-
 /* The number of lines of messages at the bottom.  */
 #define GRUB_TERM_MESSAGE_HEIGHT       8
 
-/* The height of the border.  */
-#define GRUB_TERM_BORDER_HEIGHT        (GRUB_TERM_HEIGHT \
-                                 - GRUB_TERM_TOP_BORDER_Y \
-                                 - GRUB_TERM_MESSAGE_HEIGHT)
-
-/* The number of entries shown at a time.  */
-#define GRUB_TERM_NUM_ENTRIES  (GRUB_TERM_BORDER_HEIGHT - 2)
-
 /* The Y position of the first entry.  */
 #define GRUB_TERM_FIRST_ENTRY_Y        (GRUB_TERM_TOP_BORDER_Y + 1)
 
-/* The max column number of an entry. The last "-1" is for a
-   continuation marker.  */
-#define GRUB_TERM_ENTRY_WIDTH  (GRUB_TERM_BORDER_WIDTH - 2 \
-                                 - GRUB_TERM_MARGIN * 2 - 1)
-
-/* The standard X position of the cursor.  */
-#define GRUB_TERM_CURSOR_X     (GRUB_TERM_LEFT_BORDER_X \
-                                 + GRUB_TERM_BORDER_WIDTH \
-                                 - GRUB_TERM_MARGIN \
-                                 - 1)
-
-
 struct grub_term_input
 {
   /* The next terminal.  */
@@ -277,16 +252,123 @@ 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 int grub_term_width (struct grub_term_output *term)
+static inline unsigned grub_term_width (struct grub_term_output *term)
 {
   return ((term->getwh()&0xFF00)>>8);
 }
 
-static inline int grub_term_height (struct grub_term_output *term)
+static inline unsigned grub_term_height (struct grub_term_output *term)
 {
   return (term->getwh()&0xFF);
 }
 
+/* The width of the border.  */
+static inline unsigned
+grub_term_border_width (struct grub_term_output *term)
+{
+  return grub_term_width (term) - GRUB_TERM_MARGIN * 3 - GRUB_TERM_SCROLL_WIDTH;
+}
+
+/* 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_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1;
+}
+
+/* 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 int
+grub_term_is_active (struct grub_term_output *term)
+{
+  return !!(term->flags & GRUB_TERM_ACTIVE);
+}
+
+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)
+{
+  term->getcolor (normal_color, highlight_color);
+}
+
+extern void (*EXPORT_VAR (grub_newline_hook)) (void);
+
 /* For convenience.  */
 #define GRUB_TERM_ASCII_CHAR(c)        ((c) & 0xff)
 
index 7dd9bd18a6c624c8ae4140961c2ab800e1441b32..ef782f5ddeb0ef13cd6396169500941eead71c6e 100644 (file)
@@ -882,10 +882,10 @@ grub_sprintf (char *str, const char *fmt, ...)
 /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
    bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
    Return the number of characters converted. DEST must be able to hold
-   at least DESTSIZE characters. If an invalid sequence is found, return -1.
+   at least DESTSIZE characters.
    If SRCEND is not NULL, then *SRCEND is set to the next byte after the
    last byte used in SRC.  */
-grub_ssize_t
+grub_size_t
 grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
                   const grub_uint8_t *src, grub_size_t srcsize,
                   const grub_uint8_t **srcend)
@@ -907,7 +907,8 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
          if ((c & 0xc0) != 0x80)
            {
              /* invalid */
-             return -1;
+             code = '?';
+             count = 0;
            }
          else
            {
@@ -949,7 +950,11 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
              code = c & 0x01;
            }
          else
-           return -1;
+           {
+             /* invalid */
+             code = '?';
+             count = 0;
+           }
        }
 
       if (count == 0)
index 35660273e4ec19314631e627694fc09f9f04d5f0..b71c1233471e08ba2068bd9d0ddf349e50eddb26 100644 (file)
@@ -31,13 +31,15 @@ struct grub_handler_class grub_term_input_class =
 
 struct grub_term_output *grub_term_outputs;
 
+void (*grub_newline_hook) (void) = NULL;
+
 /* Put a Unicode character.  */
 void
 grub_putcode (grub_uint32_t code, struct grub_term_output *term)
 {
   int height;
 
-  height = term->getwh () & 255;
+  height = grub_term_height (term);
 
   if (code == '\t' && term->getxy)
     {
@@ -50,6 +52,8 @@ grub_putcode (grub_uint32_t code, struct grub_term_output *term)
       return;
     }
 
+  if (code == '\n')
+    (term->putchar) ('\r');
   (term->putchar) (code);
 }
 
@@ -68,7 +72,7 @@ grub_putchar (int c)
   {
     struct grub_term_output *term = (struct grub_term_output *) item;
 
-    if (term->flags & GRUB_TERM_ACTIVE)
+    if (grub_term_is_active (term))
       grub_putcode (code, term);
 
     return 0;
@@ -77,14 +81,13 @@ grub_putchar (int c)
   buf[size++] = c;
   ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0);
 
-  if (ret < 0)
-    code = '?';
-
   if (ret != 0)
     {
       size = 0;
       grub_list_iterate (GRUB_AS_LIST (grub_term_outputs), do_putcode);
     }
+  if (ret == '\n' && grub_newline_hook)
+    grub_newline_hook ();
 }
 
 int
@@ -116,7 +119,7 @@ grub_cls (void)
   {
     struct grub_term_output *term = (struct grub_term_output *) item;
 
-    if (!(term->flags & GRUB_TERM_ACTIVE))
+    if (! grub_term_is_active (term))
       return 0;
 
     if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
@@ -141,11 +144,10 @@ grub_setcolorstate (grub_term_color_state state)
   {
     struct grub_term_output *term = (struct grub_term_output *) item;
 
-    if (!(term->flags & GRUB_TERM_ACTIVE))
+    if (! grub_term_is_active (term))
       return 0;
 
-    if (term->setcolorstate)
-      (term->setcolorstate) (state);
+    grub_term_setcolorstate (term, state);
 
     return 0;
   }
@@ -161,11 +163,10 @@ grub_refresh (void)
   {
     struct grub_term_output *term = (struct grub_term_output *) item;
 
-    if (!(term->flags & GRUB_TERM_ACTIVE))
+    if (!grub_term_is_active (term))
       return 0;
 
-    if (term->refresh)
-      (term->refresh) ();
+    grub_term_refresh (term);
 
     return 0;
   }
index 0f2c2c8eea8a5fa3fd44946a30617ee795cadb4f..f2e1b036def31604960d36661840f721c11374d3 100644 (file)
@@ -24,6 +24,8 @@
    last byte used in SRC.  */
 
 #include <grub/charset.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
 
 grub_ssize_t
 grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
@@ -176,5 +178,92 @@ grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
     }
   *dest = 0;
 
-  return ret;
+  return (char *) ret;
+}
+
+int
+grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize)
+{
+  grub_uint32_t code = 0;
+  int count = 0;
+
+  while (srcsize)
+    {
+      grub_uint32_t c = *src++;
+      if (srcsize != (grub_size_t)-1)
+       srcsize--;
+      if (count)
+       {
+         if ((c & 0xc0) != 0x80)
+           {
+             /* invalid */
+             return 0;
+           }
+         else
+           {
+             code <<= 6;
+             code |= (c & 0x3f);
+             count--;
+           }
+       }
+      else
+       {
+         if (c == 0)
+           break;
+
+         if ((c & 0x80) == 0x00)
+           code = c;
+         else if ((c & 0xe0) == 0xc0)
+           {
+             count = 1;
+             code = c & 0x1f;
+           }
+         else if ((c & 0xf0) == 0xe0)
+           {
+             count = 2;
+             code = c & 0x0f;
+           }
+         else if ((c & 0xf8) == 0xf0)
+           {
+             count = 3;
+             code = c & 0x07;
+           }
+         else if ((c & 0xfc) == 0xf8)
+           {
+             count = 4;
+             code = c & 0x03;
+           }
+         else if ((c & 0xfe) == 0xfc)
+           {
+             count = 5;
+             code = c & 0x01;
+           }
+         else
+           return 0;
+       }
+    }
+
+  return 1;
+}
+
+int
+grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
+                       grub_uint32_t **last_position)
+{
+  grub_size_t msg_len = grub_strlen (msg);
+
+  *unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t));
+  if (!*unicode_msg)
+    {
+      grub_printf ("utf8_to_ucs4 ERROR1: %s", msg);
+      return -1;
+    }
+
+  msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
+                             (grub_uint8_t *) msg, -1, 0);
+
+  *last_position = *unicode_msg + msg_len;
+
+  return msg_len;
 }
index 240a77aeeec860762e1d96c2cfb95256cbd36e95..156b84c3744313d70cc8cc68ef675ff9d3f35c3b 100644 (file)
@@ -154,6 +154,49 @@ is_authenticated (const char *userlist)
   return grub_list_iterate (GRUB_AS_LIST (users), hook);
 }
 
+static int
+grub_username_get (char buf[], unsigned buf_size)
+{
+  unsigned cur_len = 0;
+  int key;
+
+  while (1)
+    {
+      key = GRUB_TERM_ASCII_CHAR (grub_getkey ()); 
+      if (key == '\n' || key == '\r')
+       break;
+
+      if (key == '\e')
+       {
+         cur_len = 0;
+         break;
+       }
+
+      if (key == '\b')
+       {
+         cur_len--;
+         grub_printf ("\b");
+         continue;
+       }
+
+      if (!grub_isprint (key))
+       continue;
+
+      if (cur_len + 2 < buf_size)
+       {
+         buf[cur_len++] = key;
+         grub_putchar (key);
+       }
+    }
+
+  grub_memset (buf + cur_len, 0, buf_size - cur_len);
+
+  grub_putchar ('\n');
+  grub_refresh ();
+
+  return (key != '\e');
+}
+
 grub_err_t
 grub_auth_check_authentication (const char *userlist)
 {
@@ -187,11 +230,12 @@ grub_auth_check_authentication (const char *userlist)
       return GRUB_ERR_NONE;
     }
 
-  if (!grub_cmdline_get (N_("Enter username:"), login, sizeof (login) - 1,
-                        0, 0, 0))
+  grub_puts_ (N_("Enter username: "));
+
+  if (!grub_username_get (login, sizeof (login) - 1))
     goto access_denied;
 
-  grub_printf ("Enter password: ");
+  grub_puts_ (N_("Enter password: "));
 
   if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
     goto access_denied;
index c104709c568534e98a294da767d0c9de59e1c9ce..1412a6d6a64fccff6f8d586a6c06910ccd80a8e1 100644 (file)
@@ -27,6 +27,7 @@
 #include <grub/file.h>
 #include <grub/env.h>
 #include <grub/i18n.h>
+#include <grub/charset.h>
 
 static grub_uint32_t *kill_buf;
 
@@ -211,11 +212,12 @@ struct cmdline_term
    otherwise return command line.  */
 /* FIXME: The dumb interface is not supported yet.  */
 char *
-grub_cmdline_get (const char *prompt, unsigned max_len)
+grub_cmdline_get (const char *prompt)
 {
   grub_size_t lpos, llen;
   grub_size_t plen;
-  grub_uint32_t buf[max_len];
+  grub_uint32_t *buf;
+  grub_size_t max_len = 256;
   int key;
   int histpos = 0;
   auto void cl_insert (const grub_uint32_t *str);
@@ -226,13 +228,14 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
   auto void cl_set_pos_all (void);
   const char *prompt_translated = _(prompt);
   struct cmdline_term *cl_terms;
+  char *ret;
   unsigned nterms;
 
   void cl_set_pos (struct cmdline_term *cl_term)
   {
     cl_term->xpos = (plen + lpos) % (cl_term->width - 1);
     cl_term->ypos = cl_term->ystart + (plen + lpos) / (cl_term->width - 1);
-    cl_term->term->gotoxy (cl_term->xpos, cl_term->ypos);
+    grub_term_gotoxy (cl_term->term, cl_term->xpos, cl_term->ypos);
   }
 
   void cl_set_pos_all ()
@@ -246,7 +249,7 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
     {
       grub_uint32_t *p;
 
-      for (p = buf + pos; *p; p++)
+      for (p = buf + pos; p < buf + llen; p++)
        {
          if (cl_term->xpos++ > cl_term->width - 2)
            {
@@ -277,14 +280,30 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
     {
       grub_size_t len = strlen_ucs4 (str);
 
+      if (len + llen >= max_len)
+       {
+         grub_uint32_t *nbuf;
+         max_len *= 2;
+         nbuf = grub_realloc (buf, sizeof (grub_uint32_t) * max_len);
+         if (nbuf)
+           buf = nbuf;
+         else
+           {
+             grub_print_error ();
+             grub_errno = GRUB_ERR_NONE;
+             max_len /= 2;
+           }
+       }
+
       if (len + llen < max_len)
        {
-         grub_memmove (buf + lpos + len, buf + lpos, llen - lpos + 1);
-         grub_memmove (buf + lpos, str, len);
+         grub_memmove (buf + lpos + len, buf + lpos,
+                       (llen - lpos + 1) * sizeof (grub_uint32_t));
+         grub_memmove (buf + lpos, str, len * sizeof (grub_uint32_t));
 
          llen += len;
          lpos += len;
-         cl_print_all (lpos - len, echo_char);
+         cl_print_all (lpos - len, 0);
          cl_set_pos_all ();
        }
 
@@ -305,7 +324,7 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
 
          grub_memmove (buf + lpos, buf + lpos + len, llen - lpos + 1);
          llen -= len;
-         cl_print_all (lpos, echo_char);
+         cl_print_all (lpos, 0);
          cl_set_pos_all ();
        }
 
@@ -315,7 +334,7 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
   void init_clterm (struct cmdline_term *cl_term_cur)
   {
     cl_term_cur->xpos = plen;
-    cl_term_cur->ypos = (cl_term_cur->term->getxy () & 0xFF);
+    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);
@@ -328,6 +347,10 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
       init_clterm (&cl_terms[i]);
   }
 
+  buf = grub_malloc (max_len * sizeof (grub_uint32_t));
+  if (!buf)
+    return 0;
+
   plen = grub_strlen (prompt_translated);
   lpos = llen = 0;
   buf[0] = '\0';
@@ -341,15 +364,15 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
     struct grub_term_output *cur;
     nterms = 0;
     for (cur = grub_term_outputs; cur; cur = cur->next)
-      if (cur->flags & GRUB_TERM_ACTIVE)
+      if (grub_term_is_active (cur))
        nterms++;
 
     cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms);
     if (!cl_terms)
-      return grub_errno;
+      return 0;
     cl_term_cur = cl_terms;
     for (cur = grub_term_outputs; cur; cur = cur->next)
-      if (cur->flags & GRUB_TERM_ACTIVE)
+      if (grub_term_is_active (cur))
        {
          cl_term_cur->term = cur;
          init_clterm (cl_term_cur);
@@ -357,7 +380,7 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
        }
   }
 
-  if (history && hist_used == 0)
+  if (hist_used == 0)
     grub_history_add (buf);
 
   while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
@@ -394,17 +417,38 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
          {
            grub_uint32_t *insert;
            int restore;
+           char *bufu8, *insertu8;
+           grub_size_t insertlen;
+           grub_size_t t;
 
-           /* Backup the next character and make it 0 so it will
-              be easy to use string functions.  */
-           char backup = buf[lpos];
            buf[lpos] = '\0';
 
+           bufu8 = grub_ucs4_to_utf8_alloc (buf, lpos);
+           if (!bufu8)
+             {
+               grub_print_error ();
+               grub_errno = GRUB_ERR_NONE;
+               break;
+             }
+
+           insertu8 = grub_normal_do_completion (bufu8, &restore,
+                                                 print_completion);
+           grub_free (bufu8);
+           insertlen = grub_strlen (bufu8);
+           insert = grub_malloc ((insertlen + 1) * sizeof (grub_uint32_t));
+           if (!insert)
+             {
+               grub_free (insertu8);
+               grub_print_error ();
+               grub_errno = GRUB_ERR_NONE;
+               break;
+             }
+           t = grub_utf8_to_ucs4 (insert, insertlen,
+                                  (grub_uint8_t *) insertu8,
+                                  insertlen, 0);
+           insert[t] = 0;
 
-           insert = grub_normal_do_completion (buf, &restore,
-                                               print_completion);
-           /* Restore the original string.  */
-           buf[lpos] = backup;
+           grub_free (insertu8);
 
            if (restore)
              {
@@ -429,7 +473,11 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
                grub_free (kill_buf);
 
              kill_buf = strdup_ucs4 (buf + lpos);
-             grub_errno = GRUB_ERR_NONE;
+             if (grub_errno)
+               {
+                 grub_print_error ();
+                 grub_errno = GRUB_ERR_NONE;
+               }
 
              cl_delete (llen - lpos);
            }
@@ -481,7 +529,11 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
                grub_free (kill_buf);
 
              kill_buf = grub_malloc (n + 1);
-             grub_errno = GRUB_ERR_NONE;
+             if (grub_errno)
+               {
+                 grub_print_error ();
+                 grub_errno = GRUB_ERR_NONE;
+               }
              if (kill_buf)
                {
                  grub_memcpy (kill_buf, buf, n);
@@ -538,16 +590,15 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
   while (buf[lpos] == ' ')
     lpos++;
 
-  if (history)
+  histpos = 0;
+  if (strlen_ucs4 (buf) > 0)
     {
-      histpos = 0;
-      if (strlen_ucs4 (buf) > 0)
-       {
-         grub_uint32_t empty[] = { 0 };
-         grub_history_replace (histpos, buf);
-         grub_history_add (empty);
-       }
+      grub_uint32_t empty[] = { 0 };
+      grub_history_replace (histpos, buf);
+      grub_history_add (empty);
     }
 
-  return grub_ucs4_to_utf8_alloc (buf + lpos, llen - lpos + 1);
+  ret = grub_ucs4_to_utf8_alloc (buf + lpos, llen - lpos + 1);
+  grub_free (buf);
+  return ret;
 }
index 63bd889a5b99ec2bca5285d4edc691ebca06ae50..80a285787e56739ffd05ec8236100e241c0a0941 100644 (file)
@@ -112,16 +112,14 @@ set_colors (void)
 
   for (term = grub_term_outputs; term; term = term->next)
     {
-      if (! (term->flags & GRUB_TERM_ACTIVE))
+      if (! grub_term_is_active (term))
        continue;
 
       /* Reloads terminal `normal' and `highlight' colors.  */
-      if (term->setcolor)
-       term->setcolor (color_normal, color_highlight);
+      grub_term_setcolor (term, color_normal, color_highlight);
 
       /* Propagates `normal' color to terminal current color.  */
-      if (term->setcolorstate)
-       term->setcolorstate (GRUB_TERM_COLOR_NORMAL);
+      grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
     }
 }
 
index 0dab9e09eff9f6361947a56745e9435a56ccd7e7..b490f49e58670dffccfbb4736e41e80bc8333b3e 100644 (file)
@@ -30,6 +30,7 @@
 #include <grub/menu_viewer.h>
 #include <grub/auth.h>
 #include <grub/i18n.h>
+#include <grub/charset.h>
 
 #define GRUB_DEFAULT_HISTORY_SIZE      50
 
@@ -420,11 +421,11 @@ grub_normal_init_page (struct grub_term_output *term)
       return;
     }
 
-  posx = grub_getstringwidth (unicode_msg, last_position);
+  posx = grub_getstringwidth (unicode_msg, last_position, term);
   posx = (grub_term_width (term) - posx) / 2;
-  term->gotoxy (posx, 1);
+  grub_term_gotoxy (term, posx, 1);
 
-  grub_print_ucs4 (unicode_msg, last_position);
+  grub_print_ucs4 (unicode_msg, last_position, term);
   grub_printf("\n\n");
   grub_free (unicode_msg);
 }
@@ -458,7 +459,7 @@ grub_normal_execute (const char *config, int nested, int batch)
     {
       if (menu && menu->size)
        {
-         grub_menu_viewer_show_menu (menu, nested);
+         grub_show_menu (menu, nested);
          if (nested)
            free_menu (menu);
        }
@@ -470,20 +471,19 @@ void
 grub_enter_normal_mode (const char *config)
 {
   grub_normal_execute (config, 0, 0);
+  grub_cmdline_run (1);
 }
 
 /* Enter normal mode from rescue mode.  */
 static grub_err_t
-grub_cmd_normal (struct grub_command *cmd,
+grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
                 int argc, char *argv[])
 {
-  grub_unregister_command (cmd);
-
   if (argc == 0)
     {
       /* Guess the config filename. It is necessary to make CONFIG static,
         so that it won't get broken by longjmp.  */
-      static char *config;
+      char *config;
       const char *prefix;
 
       prefix = grub_env_get ("prefix");
@@ -525,10 +525,9 @@ grub_normal_reader_init (void)
       if (! (term->flags & GRUB_TERM_ACTIVE))
        continue;
       grub_normal_init_page (term);
-      if (term->setcursor)
-       term->setcursor (1);
+      grub_term_setcursor (term, 1);
       
-      grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN);
+      grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term);
       grub_puts ("\n");
     }
   grub_free (msg_formatted);
@@ -536,7 +535,6 @@ grub_normal_reader_init (void)
   return 0;
 }
 
-static char cmdline[GRUB_MAX_CMDLINE];
 
 static grub_err_t
 grub_normal_read_line (char **line, int cont)
@@ -548,18 +546,18 @@ grub_normal_read_line (char **line, int cont)
 
   while (1)
     {
-      cmdline[0] = 0;
-      if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1, 1))
+      *line = grub_cmdline_get (prompt);
+      if (*line)
        break;
 
       if ((reader_nested) || (cont))
        {
+         grub_free (*line);
          *line = 0;
          return grub_errno;
        }
     }
 
-  *line = grub_strdup (cmdline);
   return 0;
 }
 
@@ -591,7 +589,7 @@ grub_cmdline_run (int nested)
 
       grub_normal_read_line (&line, 0);
       if (! line)
-       continue;
+       break;
 
       grub_parser_get_current ()->parse_line (line, grub_normal_read_line);
       grub_free (line);
@@ -612,15 +610,20 @@ GRUB_MOD_INIT(normal)
   if (mod)
     grub_dl_ref (mod);
 
-  grub_menu_viewer_register (&grub_normal_text_menu_viewer);
-
   grub_set_history (GRUB_DEFAULT_HISTORY_SIZE);
 
+  grub_menu_register_viewer_init (grub_menu_text_register_instances);
+  if (grub_errno)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+    }
+
   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");
 
   /* Reload terminal colors when these variables are written to.  */
   grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal);
index 8ee7d1c224d46ca667eff63abdc77039bde68166..824779db60c58ffa02951e3234038b7755a3e3e8 100644 (file)
 #include <grub/command.h>
 #include <grub/parser.h>
 #include <grub/auth.h>
+#include <grub/i18n.h>
+
+/* Time to delay after displaying an error message about a default/fallback
+   entry failing to boot.  */
+#define DEFAULT_ENTRY_ERROR_DELAY_MS  2500
+
+struct menu_run_callback
+{
+  struct menu_run_callback *next;
+  void (*hook) (int entry, grub_menu_t menu, int nested);
+};
+
+struct menu_run_callback *callbacks = NULL;
+
+/* Wait until the user pushes any key so that the user
+   can see what happened.  */
+void
+grub_wait_after_message (void)
+{
+  grub_putchar ('\n');
+  grub_printf_ (N_("Press any key to continue..."));
+  (void) grub_getkey ();
+  grub_putchar ('\n');
+}
 
 /* Get a menu entry by its index in the entry list.  */
 grub_menu_entry_t
@@ -178,3 +202,364 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
 
   callback->notify_failure (callback_data);
 }
+
+static struct grub_menu_viewer *viewers;
+
+static void
+menu_set_chosen_entry (int entry)
+{
+  struct grub_menu_viewer *cur;
+  for (cur = viewers; cur; cur = cur->next)
+    cur->set_chosen_entry (entry, cur->data);
+}
+
+static void
+menu_print_timeout (int timeout)
+{
+  struct grub_menu_viewer *cur;
+  for (cur = viewers; cur; cur = cur->next)
+    cur->print_timeout (timeout, cur->data);
+}
+
+static void
+menu_fini (void)
+{
+  struct grub_menu_viewer *cur, *next;
+  for (cur = viewers; cur; cur = next)
+    {
+      next = cur->next;
+      cur->fini (cur->data);
+      grub_free (cur);
+    }
+  viewers = NULL;
+}
+
+static void
+menu_init (int entry, grub_menu_t menu, int nested)
+{
+  struct menu_run_callback *cb;
+  for (cb = callbacks; cb; cb = cb->next)
+    cb->hook (entry, menu, nested);
+}
+
+static void
+clear_timeout (void)
+{
+  struct grub_menu_viewer *cur;
+  for (cur = viewers; cur; cur = cur->next)
+    cur->clear_timeout (cur->data);
+}
+
+void
+grub_menu_register_viewer (struct grub_menu_viewer *viewer)
+{
+  viewer->next = viewers;
+  viewers = viewer;
+}
+
+grub_err_t
+grub_menu_register_viewer_init (void (*callback) (int entry, grub_menu_t menu,
+                                                 int nested))
+{
+  struct menu_run_callback *cb;
+  cb = grub_malloc (sizeof (*cb));
+  if (!cb)
+    return grub_errno;
+  cb->hook = callback;
+  cb->next = callbacks;
+  callbacks = cb;
+  return GRUB_ERR_NONE;
+}
+
+/* Get the entry number from the variable NAME.  */
+static int
+get_entry_number (const char *name)
+{
+  char *val;
+  int entry;
+
+  val = grub_env_get (name);
+  if (! val)
+    return -1;
+
+  grub_error_push ();
+
+  entry = (int) grub_strtoul (val, 0, 0);
+
+  if (grub_errno != GRUB_ERR_NONE)
+    {
+      grub_errno = GRUB_ERR_NONE;
+      entry = -1;
+    }
+
+  grub_error_pop ();
+
+  return entry;
+}
+
+#define GRUB_MENU_PAGE_SIZE 10
+
+/* 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)
+{
+  grub_uint64_t saved_time;
+  int default_entry, current_entry;
+  int timeout;
+
+  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)
+    {
+      *auto_boot = 1;
+      return default_entry;
+    }
+
+  current_entry = default_entry;
+
+  /* Initialize the time.  */
+  saved_time = grub_get_time_ms ();
+
+ refresh:
+  menu_init (current_entry, menu, nested);
+
+  timeout = grub_menu_get_timeout ();
+
+  if (timeout > 0)
+    menu_print_timeout (timeout);
+
+  while (1)
+    {
+      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;
+             menu_print_timeout (timeout);
+           }
+       }
+
+      if (timeout == 0)
+       {
+         grub_env_unset ("timeout");
+          *auto_boot = 1;
+         menu_fini ();
+         return default_entry;
+       }
+
+      if (grub_checkkey () >= 0 || timeout < 0)
+       {
+         c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
+
+         if (timeout >= 0)
+           {
+             grub_env_unset ("timeout");
+             grub_env_unset ("fallback");
+             clear_timeout ();
+           }
+
+         switch (c)
+           {
+           case GRUB_TERM_HOME:
+             current_entry = 0;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case GRUB_TERM_END:
+             current_entry = menu->size - 1;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case GRUB_TERM_UP:
+           case '^':
+             current_entry--;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case GRUB_TERM_DOWN:
+           case 'v':
+             current_entry++;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case GRUB_TERM_PPAGE:
+             if (current_entry < GRUB_MENU_PAGE_SIZE)
+               current_entry = 0;
+             else
+               current_entry -= GRUB_MENU_PAGE_SIZE;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case GRUB_TERM_NPAGE:
+             if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size)
+               current_entry = 0;
+             else
+               current_entry += GRUB_MENU_PAGE_SIZE;
+             menu_set_chosen_entry (current_entry);
+             break;
+
+           case '\n':
+           case '\r':
+           case 6:
+             menu_fini ();
+              *auto_boot = 0;
+             return current_entry;
+
+           case '\e':
+             if (nested)
+               {
+                 menu_fini ();
+                 return -1;
+               }
+             break;
+
+           case 'c':
+             grub_cmdline_run (1);
+             goto refresh;
+
+           case 'e':
+               {
+                 grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry);
+                 if (e)
+                   grub_menu_entry_run (e);
+               }
+             goto refresh;
+
+           default:
+             break;
+           }
+       }
+    }
+
+  /* Never reach here.  */
+  return -1;
+}
+
+/* Callback invoked immediately before a menu entry is executed.  */
+static void
+notify_booting (grub_menu_entry_t entry,
+               void *userdata __attribute__((unused)))
+{
+  grub_printf ("  ");
+  grub_printf_ (N_("Booting \'%s\'"), entry->title);
+  grub_printf ("\n\n");
+}
+
+/* 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)))
+{
+  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 ();
+}
+
+/* Callbacks used by the text menu to provide user feedback when menu entries
+   are executed.  */
+static struct grub_menu_execute_callback execution_callback =
+{
+  .notify_booting = notify_booting,
+  .notify_fallback = notify_fallback,
+  .notify_failure = notify_execution_failure
+};
+
+static grub_err_t
+show_menu (grub_menu_t menu, int nested)
+{
+  while (1)
+    {
+      int boot_entry;
+      grub_menu_entry_t e;
+      int auto_boot;
+
+      boot_entry = run_menu (menu, nested, &auto_boot);
+      if (boot_entry < 0)
+       break;
+
+      e = grub_menu_get_entry (menu, boot_entry);
+      if (! e)
+       continue; /* Menu is empty.  */
+
+      grub_cls ();
+
+      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 ();
+            }
+        }
+    }
+
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_show_menu (grub_menu_t menu, int nested)
+{
+  grub_err_t err1, err2;
+
+  while (1)
+    {
+      err1 = 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;
+}
index 7a31c27af13790de0f321067e857f0ca70ae06c1..da4eff49639ab89825e47da9c3fae1f106a41bd6 100644 (file)
@@ -43,6 +43,15 @@ struct line
   int max_len;
 };
 
+struct per_term_screen
+{
+  struct grub_term_output *term;
+  /* The X coordinate.  */
+  int x;
+  /* The Y coordinate.  */
+  int y;
+};
+
 struct screen
 {
   /* The array of lines.  */
@@ -55,18 +64,18 @@ struct screen
   int real_column;
   /* The current line.  */
   int line;
-  /* The X coordinate.  */
-  int x;
-  /* The Y coordinate.  */
-  int y;
   /* The kill buffer.  */
   char *killed_text;
   /* The flag of a completion window.  */
   int completion_shown;
+
+  struct per_term_screen *terms;
+  unsigned nterms;
 };
 
 /* Used for storing completion items temporarily.  */
 static struct line completion_buffer;
+static int completion_type;
 
 /* Initialize a line.  */
 static int
@@ -98,77 +107,88 @@ ensure_space (struct line *linep, int extra)
 
 /* Return the number of lines occupied by this line on the screen.  */
 static int
-get_logical_num_lines (struct line *linep)
+get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen)
 {
-  return (linep->len / GRUB_TERM_ENTRY_WIDTH) + 1;
+  return (linep->len / grub_term_entry_width (term_screen->term)) + 1;
 }
 
 /* Print a line.  */
 static void
-print_line (struct line *linep, int offset, int start, int y)
+print_line (struct line *linep, int offset, int start, int y,
+           struct per_term_screen *term_screen)
 {
-  int i;
-  char *p;
-
-  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1,
-              y + GRUB_TERM_FIRST_ENTRY_Y);
-
-  for (p = linep->buf + offset + start, i = start;
-       i < GRUB_TERM_ENTRY_WIDTH && offset + i < linep->len;
-       p++, i++)
-    grub_putchar (*p);
-
-  for (; i < GRUB_TERM_ENTRY_WIDTH; i++)
-    grub_putchar (' ');
+  grub_term_gotoxy (term_screen->term, 
+                   GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1,
+                   y + GRUB_TERM_FIRST_ENTRY_Y);
 
-  if (linep->len >= offset + GRUB_TERM_ENTRY_WIDTH)
-    grub_putchar ('\\');
+  if (linep->len >= offset + grub_term_entry_width (term_screen->term))
+    {
+      char *p, c;
+      p = linep->buf + offset + start
+       + grub_term_entry_width (term_screen->term);
+      c = *p;
+      *p = 0;
+      grub_puts_terminal (linep->buf + offset + start, term_screen->term);
+      *p = c;
+      grub_putcode ('\\', term_screen->term);
+    }
   else
-    grub_putchar (' ');
+    {
+      int i;
+      for (i = 0;
+          i <= grub_term_entry_width (term_screen->term) - linep->len + offset;
+          i++)
+       grub_putcode (' ', term_screen->term);
+    }
 }
 
 /* Print an empty line.  */
 static void
-print_empty_line (int y)
+print_empty_line (int y, struct per_term_screen *term_screen)
 {
   int i;
 
-  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
-              y + GRUB_TERM_FIRST_ENTRY_Y);
+  grub_term_gotoxy (term_screen->term,
+                   GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
+                   y + GRUB_TERM_FIRST_ENTRY_Y);
 
-  for (i = 0; i < GRUB_TERM_ENTRY_WIDTH + 1; i++)
-    grub_putchar (' ');
+  for (i = 0; i < grub_term_entry_width (term_screen->term) + 1; i++)
+    grub_putcode (' ', term_screen->term);
 }
 
 /* Print an up arrow.  */
 static void
-print_up (int flag)
+print_up (int flag, struct per_term_screen *term_screen)
 {
-  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
-              GRUB_TERM_FIRST_ENTRY_Y);
+  grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X 
+                   + grub_term_entry_width (term_screen->term),
+                   GRUB_TERM_FIRST_ENTRY_Y);
 
   if (flag)
-    grub_putcode (GRUB_TERM_DISP_UP);
+    grub_putcode (GRUB_TERM_DISP_UP, term_screen->term);
   else
-    grub_putchar (' ');
+    grub_putcode (' ', term_screen->term);
 }
 
 /* Print a down arrow.  */
 static void
-print_down (int flag)
+print_down (int flag, struct per_term_screen *term_screen)
 {
-  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
-              GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES);
+  grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
+                   + grub_term_border_width (term_screen->term),
+                   GRUB_TERM_TOP_BORDER_Y 
+                   + grub_term_num_entries (term_screen->term));
 
   if (flag)
-    grub_putcode (GRUB_TERM_DISP_DOWN);
+    grub_putcode (GRUB_TERM_DISP_DOWN, term_screen->term);
   else
-    grub_putchar (' ');
+    grub_putcode (' ', term_screen->term);
 }
 
 /* Draw the lines of the screen SCREEN.  */
 static void
-update_screen (struct screen *screen, int region_start, int region_column,
+update_screen (struct screen *screen, struct per_term_screen *term_screen,
+              int region_start, int region_column,
               int up, int down, enum update_mode mode)
 {
   int up_flag = 0;
@@ -178,12 +198,13 @@ update_screen (struct screen *screen, int region_start, int region_column,
   struct line *linep;
 
   /* Check if scrolling is necessary.  */
-  if (screen->y < 0 || screen->y >= GRUB_TERM_NUM_ENTRIES)
+  if (term_screen->y < 0 || term_screen->y
+      >= grub_term_num_entries (term_screen->term))
     {
-      if (screen->y < 0)
-       screen->y = 0;
+      if (term_screen->y < 0)
+       term_screen->y = 0;
       else
-       screen->y = GRUB_TERM_NUM_ENTRIES - 1;
+       term_screen->y = grub_term_num_entries (term_screen->term) - 1;
 
       region_start = 0;
       region_column = 0;
@@ -196,14 +217,15 @@ update_screen (struct screen *screen, int region_start, int region_column,
     {
       /* Draw lines. This code is tricky, because this must calculate logical
         positions.  */
-      y = screen->y - screen->column / GRUB_TERM_ENTRY_WIDTH;
+      y = term_screen->y - screen->column
+       / grub_term_entry_width (term_screen->term);
       i = screen->line;
       linep = screen->lines + i;
       while (y > 0)
        {
           i--;
           linep--;
-          y -= get_logical_num_lines (linep);
+          y -= get_logical_num_lines (linep, term_screen);
        }
 
       if (y < 0 || i > 0)
@@ -214,8 +236,9 @@ update_screen (struct screen *screen, int region_start, int region_column,
          int column;
 
          for (column = 0;
-              column <= linep->len && y < GRUB_TERM_NUM_ENTRIES;
-              column += GRUB_TERM_ENTRY_WIDTH, y++)
+              column <= linep->len
+                && y < grub_term_num_entries (term_screen->term);
+              column += grub_term_entry_width (term_screen->term), y++)
            {
              if (y < 0)
                continue;
@@ -223,16 +246,19 @@ update_screen (struct screen *screen, int region_start, int region_column,
              if (i == region_start)
                {
                  if (region_column >= column
-                     && region_column < column + GRUB_TERM_ENTRY_WIDTH)
-                   print_line (linep, column, region_column - column, y);
+                     && region_column
+                     < (column
+                        + grub_term_entry_width (term_screen->term)))
+                   print_line (linep, column, region_column - column, y,
+                               term_screen);
                  else if (region_column < column)
-                   print_line (linep, column, 0, y);
+                   print_line (linep, column, 0, y, term_screen);
                }
              else if (i > region_start && mode == ALL_LINES)
-               print_line (linep, column, 0, y);
+               print_line (linep, column, 0, y, term_screen);
            }
 
-         if (y == GRUB_TERM_NUM_ENTRIES)
+         if (y == grub_term_num_entries (term_screen->term))
            {
              if (column <= linep->len || i + 1 < screen->num_lines)
                down_flag = 1;
@@ -242,35 +268,53 @@ update_screen (struct screen *screen, int region_start, int region_column,
          i++;
 
          if (mode == ALL_LINES && i == screen->num_lines)
-           for (; y < GRUB_TERM_NUM_ENTRIES; y++)
-             print_empty_line (y);
+           for (; y < grub_term_num_entries (term_screen->term); y++)
+             print_empty_line (y, term_screen);
 
        }
-      while (y < GRUB_TERM_NUM_ENTRIES);
+      while (y < grub_term_num_entries (term_screen->term));
 
       /* Draw up and down arrows.  */
       if (up)
-       print_up (up_flag);
+       print_up (up_flag, term_screen);
       if (down)
-       print_down (down_flag);
+       print_down (down_flag, term_screen);
     }
 
   /* Place the cursor.  */
-  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1 + screen->x,
-              GRUB_TERM_FIRST_ENTRY_Y + screen->y);
+  grub_term_gotoxy (term_screen->term, 
+                   GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1
+                   + term_screen->x,
+                   GRUB_TERM_FIRST_ENTRY_Y + term_screen->y);
 
-  grub_refresh ();
+  grub_term_refresh (term_screen->term);
+}
+
+static void
+update_screen_all (struct screen *screen,
+                  int region_start, int region_column,
+                  int up, int down, enum update_mode mode)
+{
+  unsigned i;
+  for (i = 0; i < screen->nterms; i++)
+    update_screen (screen, &screen->terms[i], region_start, region_column,
+                  up, down, mode);
 }
 
-/* Insert the string S into the screen SCREEN. This updates the cursor
-   position and redraw the screen. Return zero if fails.  */
 static int
 insert_string (struct screen *screen, char *s, int update)
 {
   int region_start = screen->num_lines;
   int region_column = 0;
-  int down = 0;
-  enum update_mode mode = NO_LINE;
+  int down[screen->nterms];
+  enum update_mode mode[screen->nterms];
+  unsigned i;
+
+  for (i = 0; i < screen->nterms; i++)
+    {
+      down[i] = 0;
+      mode[i] = NO_LINE;
+    }
 
   while (*s)
     {
@@ -319,15 +363,20 @@ insert_string (struct screen *screen, char *s, int update)
              region_column = screen->column;
            }
 
-         mode = ALL_LINES;
-         down = 1; /* XXX not optimal.  */
+         for (i = 0; i < screen->nterms; i++)
+           {
+             mode[i] = ALL_LINES;
+             down[i] = 1; /* XXX not optimal.  */
+           }
 
          /* Move the cursor.  */
          screen->column = screen->real_column = 0;
          screen->line++;
-         screen->x = 0;
-         screen->y++;
-
+         for (i = 0; i < screen->nterms; i++)
+           {
+             screen->terms[i].x = 0;
+             screen->terms[i].y++;
+           }
          s++;
        }
       else
@@ -336,7 +385,7 @@ insert_string (struct screen *screen, char *s, int update)
          char *p;
          struct line *current_linep;
          int size;
-         int orig_num, new_num;
+         int orig_num[screen->nterms], new_num[screen->nterms];
 
          /* Find a string delimited by LF.  */
          p = grub_strchr (s, '\n');
@@ -355,9 +404,13 @@ insert_string (struct screen *screen, char *s, int update)
          grub_memmove (current_linep->buf + screen->column,
                        s,
                        size);
-         orig_num = get_logical_num_lines (current_linep);
+         for (i = 0; i < screen->nterms; i++)
+           orig_num[i] = get_logical_num_lines (current_linep,
+                                                &screen->terms[i]);
          current_linep->len += size;
-         new_num = get_logical_num_lines (current_linep);
+         for (i = 0; i < screen->nterms; i++)
+           new_num[i] = get_logical_num_lines (current_linep,
+                                               &screen->terms[i]);
 
          /* Update the dirty region.  */
          if (region_start > screen->line)
@@ -366,27 +419,34 @@ insert_string (struct screen *screen, char *s, int update)
              region_column = screen->column;
            }
 
-         if (orig_num != new_num)
-           {
-             mode = ALL_LINES;
-             down = 1; /* XXX not optimal.  */
-           }
-         else if (mode != ALL_LINES)
-           mode = SINGLE_LINE;
+         for (i = 0; i < screen->nterms; i++)
+           if (orig_num[i] != new_num[i])
+             {
+               mode[i] = ALL_LINES;
+               down[i] = 1; /* XXX not optimal.  */
+             }
+           else if (mode[i] != ALL_LINES)
+             mode[i] = SINGLE_LINE;
 
          /* Move the cursor.  */
          screen->column += size;
          screen->real_column = screen->column;
-         screen->x += size;
-         screen->y += screen->x / GRUB_TERM_ENTRY_WIDTH;
-         screen->x %= GRUB_TERM_ENTRY_WIDTH;
-
+         for (i = 0; i < screen->nterms; i++)
+           {
+             screen->terms[i].x += size;
+             screen->terms[i].y += screen->terms[i].x
+               / grub_term_entry_width (screen->terms[i].term);
+             screen->terms[i].x
+               %= grub_term_entry_width (screen->terms[i].term);
+           }
          s = p;
        }
     }
 
   if (update)
-    update_screen (screen, region_start, region_column, 0, down, mode);
+    for (i = 0; i < screen->nterms; i++)
+      update_screen (screen, &screen->terms[i],
+                    region_start, region_column, 0, down[i], mode[i]);
 
   return 1;
 }
@@ -408,6 +468,7 @@ destroy_screen (struct screen *screen)
 
   grub_free (screen->killed_text);
   grub_free (screen->lines);
+  grub_free (screen->terms);
   grub_free (screen);
 }
 
@@ -416,6 +477,7 @@ static struct screen *
 make_screen (grub_menu_entry_t entry)
 {
   struct screen *screen;
+  unsigned i;
 
   /* Initialize the screen.  */
   screen = grub_zalloc (sizeof (*screen));
@@ -437,8 +499,11 @@ make_screen (grub_menu_entry_t entry)
   screen->column = 0;
   screen->real_column = 0;
   screen->line = 0;
-  screen->x = 0;
-  screen->y = 0;
+  for (i = 0; i < screen->nterms; i++)
+    {
+      screen->terms[i].x = 0;
+      screen->terms[i].y = 0;
+    }
 
   return screen;
 
@@ -451,44 +516,58 @@ static int
 forward_char (struct screen *screen, int update)
 {
   struct line *linep;
+  unsigned i;
 
   linep = screen->lines + screen->line;
   if (screen->column < linep->len)
     {
       screen->column++;
-      screen->x++;
-      if (screen->x == GRUB_TERM_ENTRY_WIDTH)
+      for (i = 0; i < screen->nterms; i++)
        {
-         screen->x = 0;
-         screen->y++;
+         screen->terms[i].x++;
+         if (screen->terms[i].x
+             == grub_term_entry_width (screen->terms[i].term))
+           {
+             screen->terms[i].x = 0;
+             screen->terms[i].y++;
+           }
        }
     }
   else if (screen->num_lines > screen->line + 1)
     {
       screen->column = 0;
       screen->line++;
-      screen->x = 0;
-      screen->y++;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         screen->terms[i].x = 0;
+         screen->terms[i].y++;
+       }
     }
 
   screen->real_column = screen->column;
 
   if (update)
-    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
   return 1;
 }
 
 static int
 backward_char (struct screen *screen, int update)
 {
+  unsigned i;
+
   if (screen->column > 0)
     {
       screen->column--;
-      screen->x--;
-      if (screen->x == -1)
+      for (i = 0; i < screen->nterms; i++)
        {
-         screen->x = GRUB_TERM_ENTRY_WIDTH - 1;
-         screen->y--;
+         screen->terms[i].x--;
+         if (screen->terms[i].x == -1)
+           {
+             screen->terms[i].x
+               = grub_term_entry_width (screen->terms[i].term) - 1;
+             screen->terms[i].y--;
+           }
        }
     }
   else if (screen->line > 0)
@@ -498,14 +577,18 @@ backward_char (struct screen *screen, int update)
       screen->line--;
       linep = screen->lines + screen->line;
       screen->column = linep->len;
-      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
-      screen->y--;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         screen->terms[i].x = screen->column
+           % grub_term_entry_width (screen->terms[i].term);
+         screen->terms[i].y--;
+       }
     }
 
   screen->real_column = screen->column;
 
   if (update)
-    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
 
   return 1;
 }
@@ -513,14 +596,16 @@ backward_char (struct screen *screen, int update)
 static int
 previous_line (struct screen *screen, int update)
 {
+  unsigned i;
+
   if (screen->line > 0)
     {
       struct line *linep;
-      int dy;
+      int col;
 
       /* How many physical lines from the current position
         to the first physical line?  */
-      dy = screen->column / GRUB_TERM_ENTRY_WIDTH;
+      col = screen->column;
 
       screen->line--;
 
@@ -530,23 +615,35 @@ previous_line (struct screen *screen, int update)
       else
        screen->column = screen->real_column;
 
-      /* How many physical lines from the current position
-        to the last physical line?  */
-      dy += (linep->len / GRUB_TERM_ENTRY_WIDTH
-            - screen->column / GRUB_TERM_ENTRY_WIDTH);
-
-      screen->y -= dy + 1;
-      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         int dy;
+         dy = col / grub_term_entry_width (screen->terms[i].term);
+
+         /* How many physical lines from the current position
+            to the last physical line?  */
+         dy += (linep->len / grub_term_entry_width (screen->terms[i].term)
+                - screen->column
+                / grub_term_entry_width (screen->terms[i].term));
+       
+         screen->terms[i].y -= dy + 1;
+         screen->terms[i].x
+           = screen->column % grub_term_entry_width (screen->terms[i].term);
+      }
     }
   else
     {
-      screen->y -= screen->column / GRUB_TERM_ENTRY_WIDTH;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         screen->terms[i].y
+           -= screen->column / grub_term_entry_width (screen->terms[i].term);
+         screen->terms[i].x = 0;
+       }
       screen->column = 0;
-      screen->x = 0;
     }
 
   if (update)
-    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
 
   return 1;
 }
@@ -554,16 +651,18 @@ previous_line (struct screen *screen, int update)
 static int
 next_line (struct screen *screen, int update)
 {
+  unsigned i;
+
   if (screen->line < screen->num_lines - 1)
     {
       struct line *linep;
-      int dy;
+      int l1, c1;
 
       /* How many physical lines from the current position
         to the last physical line?  */
       linep = screen->lines + screen->line;
-      dy = (linep->len / GRUB_TERM_ENTRY_WIDTH
-           - screen->column / GRUB_TERM_ENTRY_WIDTH);
+      l1 = linep->len;
+      c1 = screen->column;
 
       screen->line++;
 
@@ -573,26 +672,40 @@ next_line (struct screen *screen, int update)
       else
        screen->column = screen->real_column;
 
-      /* How many physical lines from the current position
-        to the first physical line?  */
-      dy += screen->column / GRUB_TERM_ENTRY_WIDTH;
-
-      screen->y += dy + 1;
-      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         int dy;
+         dy = l1 / grub_term_entry_width (screen->terms[i].term)
+           - c1 / grub_term_entry_width (screen->terms[i].term);
+         /* How many physical lines from the current position
+            to the first physical line?  */
+         dy += screen->column / grub_term_entry_width (screen->terms[i].term);
+         screen->terms[i].y += dy + 1;
+         screen->terms[i].x = screen->column
+           % grub_term_entry_width (screen->terms[i].term);
+       }
     }
   else
     {
       struct line *linep;
-
+      int l, s;
+      
       linep = screen->lines + screen->line;
-      screen->y += (linep->len / GRUB_TERM_ENTRY_WIDTH
-                   - screen->column / GRUB_TERM_ENTRY_WIDTH);
+      l = linep->len;
+      s = screen->column;
       screen->column = linep->len;
-      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
+      for (i = 0; i < screen->nterms; i++)
+       {
+         screen->terms[i].y 
+           += (l / grub_term_entry_width (screen->terms[i].term)
+               -  s / grub_term_entry_width (screen->terms[i].term));
+         screen->terms[i].x
+           = screen->column % grub_term_entry_width (screen->terms[i].term);
+       }
     }
 
   if (update)
-    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
 
   return 1;
 }
@@ -600,12 +713,19 @@ next_line (struct screen *screen, int update)
 static int
 beginning_of_line (struct screen *screen, int update)
 {
-  screen->y -= screen->column / GRUB_TERM_ENTRY_WIDTH;
+  unsigned i;
+  int col;
+  
+  col = screen->column;
   screen->column = screen->real_column = 0;
-  screen->x = 0;
+  for (i = 0; i < screen->nterms; i++)
+    {
+      screen->terms[i].x = 0;
+      screen->terms[i].y -= col / grub_term_entry_width (screen->terms[i].term);
+    }
 
   if (update)
-    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
 
   return 1;
 }
@@ -614,15 +734,23 @@ static int
 end_of_line (struct screen *screen, int update)
 {
   struct line *linep;
+  unsigned i;
+  int col;
 
   linep = screen->lines + screen->line;
-  screen->y += (linep->len / GRUB_TERM_ENTRY_WIDTH
-               - screen->column / GRUB_TERM_ENTRY_WIDTH);
+  col = screen->column;
   screen->column = screen->real_column = linep->len;
-  screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
+  for (i = 0; i < screen->nterms; i++)
+    {
+      screen->terms[i].y 
+       += (linep->len / grub_term_entry_width (screen->terms->term)
+           - col / grub_term_entry_width (screen->terms->term));
+      screen->terms[i].x
+       = screen->column % grub_term_entry_width (screen->terms->term);
+    }
 
   if (update)
-    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
+    update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
 
   return 1;
 }
@@ -631,32 +759,41 @@ static int
 delete_char (struct screen *screen, int update)
 {
   struct line *linep;
-  enum update_mode mode = NO_LINE;
   int start = screen->num_lines;
   int column = 0;
-  int down = 0;
 
   linep = screen->lines + screen->line;
   if (linep->len > screen->column)
     {
-      int orig_num, new_num;
+      int orig_num[screen->nterms], new_num;
+      unsigned i;
 
-      orig_num = get_logical_num_lines (linep);
+      for (i = 0; i < screen->nterms; i++)
+       orig_num[i] = get_logical_num_lines (linep, &screen->terms[i]);
 
       grub_memmove (linep->buf + screen->column,
                    linep->buf + screen->column + 1,
                    linep->len - screen->column - 1);
       linep->len--;
 
-      new_num = get_logical_num_lines (linep);
-
-      if (orig_num != new_num)
-       mode = ALL_LINES;
-      else
-       mode = SINGLE_LINE;
-
       start = screen->line;
       column = screen->column;
+
+      screen->real_column = screen->column;
+
+      if (update)
+       {
+         for (i = 0; i < screen->nterms; i++)
+           {
+             new_num = get_logical_num_lines (linep, &screen->terms[i]);
+             if (orig_num[i] != new_num)
+               update_screen (screen, &screen->terms[i],
+                              start, column, 0, 0, ALL_LINES);
+             else
+               update_screen (screen, &screen->terms[i],
+                              start, column, 0, 0, SINGLE_LINE);
+           }
+       }
     }
   else if (screen->num_lines > screen->line + 1)
     {
@@ -676,16 +813,13 @@ delete_char (struct screen *screen, int update)
                    * sizeof (struct line));
       screen->num_lines--;
 
-      mode = ALL_LINES;
       start = screen->line;
       column = screen->column;
-      down = 1;
-    }
-
-  screen->real_column = screen->column;
 
-  if (update)
-    update_screen (screen, start, column, 0, down, mode);
+      screen->real_column = screen->column;
+      if (update)
+       update_screen_all (screen, start, column, 0, 1, ALL_LINES);
+    }
 
   return 1;
 }
@@ -731,9 +865,8 @@ kill_line (struct screen *screen, int continuous, int update)
 
   if (size > 0)
     {
-      enum update_mode mode = SINGLE_LINE;
-      int down = 0;
-      int orig_num, new_num;
+      int orig_num[screen->nterms], new_num;
+      unsigned i;
 
       p = grub_realloc (p, offset + size + 1);
       if (! p)
@@ -744,18 +877,23 @@ kill_line (struct screen *screen, int continuous, int update)
 
       screen->killed_text = p;
 
-      orig_num = get_logical_num_lines (linep);
+      for (i = 0; i < screen->nterms; i++)
+       orig_num[i] = get_logical_num_lines (linep, &screen->terms[i]);
       linep->len = screen->column;
-      new_num = get_logical_num_lines (linep);
 
-      if (orig_num != new_num)
+      if (update)
        {
-         mode = ALL_LINES;
-         down = 1;
+         new_num = get_logical_num_lines (linep, &screen->terms[i]);
+         for (i = 0; i < screen->nterms; i++)
+           {
+             if (orig_num[i] != new_num)
+               update_screen (screen, &screen->terms[i],
+                              screen->line, screen->column, 0, 1, ALL_LINES);
+             else
+               update_screen (screen, &screen->terms[i],
+                              screen->line, screen->column, 0, 0, SINGLE_LINE);
+           }
        }
-
-      if (update)
-       update_screen (screen, screen->line, screen->column, 0, down, mode);
     }
   else if (screen->line + 1 < screen->num_lines)
     {
@@ -786,7 +924,11 @@ yank (struct screen *screen, int update)
 static int
 open_line (struct screen *screen, int update)
 {
-  int saved_y = screen->y;
+  int saved_y[screen->nterms];
+  unsigned i;
+
+  for (i = 0; i < screen->nterms; i++)
+    saved_y[i] = screen->terms[i].y;
 
   if (! insert_string (screen, "\n", 0))
     return 0;
@@ -794,52 +936,23 @@ open_line (struct screen *screen, int update)
   if (! backward_char (screen, 0))
     return 0;
 
-  screen->y = saved_y;
+  for (i = 0; i < screen->nterms; i++)
+    screen->terms[i].y = saved_y[i];
 
   if (update)
-    update_screen (screen, screen->line, screen->column, 0, 1, ALL_LINES);
+    update_screen_all (screen, screen->line, screen->column, 0, 1, ALL_LINES);
 
   return 1;
 }
 
 /* A completion hook to print items.  */
 static void
-store_completion (const char *item, grub_completion_type_t type, int count)
+store_completion (const char *item, grub_completion_type_t type,
+                 int count __attribute__ ((unused)))
 {
   char *p;
 
-  if (count == 0)
-    {
-      /* If this is the first time, print a label.  */
-      const char *what;
-
-      switch (type)
-       {
-       case GRUB_COMPLETION_TYPE_COMMAND:
-         what = "commands";
-         break;
-       case GRUB_COMPLETION_TYPE_DEVICE:
-         what = "devices";
-         break;
-       case GRUB_COMPLETION_TYPE_FILE:
-         what = "files";
-         break;
-       case GRUB_COMPLETION_TYPE_PARTITION:
-         what = "partitions";
-         break;
-       case GRUB_COMPLETION_TYPE_ARGUMENT:
-         what = "arguments";
-         break;
-       default:
-         what = "things";
-         break;
-       }
-
-      grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
-      grub_printf ("   ");
-      grub_printf_ (N_("Possible %s are:"), what);
-      grub_printf ("\n    ");
-    }
+  completion_type = type;
 
   /* Make sure that the completion buffer has enough room.  */
   if (completion_buffer.max_len < (completion_buffer.len
@@ -873,21 +986,21 @@ store_completion (const char *item, grub_completion_type_t type, int count)
 static int
 complete (struct screen *screen, int continuous, int update)
 {
-  grub_uint16_t pos;
   char saved_char;
   struct line *linep;
   int restore;
   char *insert;
   static int count = -1;
+  unsigned i;
+  grub_uint32_t *ucs4;
+  grub_size_t buflen;
+  grub_ssize_t ucs4len;
 
   if (continuous)
     count++;
   else
     count = 0;
 
-  pos = grub_getxy ();
-  grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
-
   completion_buffer.buf = 0;
   completion_buffer.len = 0;
   completion_buffer.max_len = 0;
@@ -900,35 +1013,86 @@ complete (struct screen *screen, int continuous, int update)
 
   linep->buf[screen->column] = saved_char;
 
-  if (restore)
-    {
-      char *p = completion_buffer.buf;
-
-      screen->completion_shown = 1;
-
-      if (p)
-       {
-         int num_sections = ((completion_buffer.len + GRUB_TERM_WIDTH - 8 - 1)
-                             / (GRUB_TERM_WIDTH - 8));
-         char *endp;
-
-         p += (count % num_sections) * (GRUB_TERM_WIDTH - 8);
-         endp = p + (GRUB_TERM_WIDTH - 8);
-
-         if (p != completion_buffer.buf)
-           grub_putcode (GRUB_TERM_DISP_LEFT);
-         else
-           grub_putchar (' ');
+  buflen = grub_strlen (completion_buffer.buf);
+  ucs4 = grub_malloc (sizeof (grub_uint32_t) * (buflen + 1));
 
-         while (*p && p < endp)
-           grub_putchar (*p++);
-
-         if (*p)
-           grub_putcode (GRUB_TERM_DISP_RIGHT);
-       }
+  if (!ucs4)
+    {
+      grub_print_error ();
+      grub_errno = GRUB_ERR_NONE;
+      return 1;
     }
 
-  grub_gotoxy (pos >> 8, pos & 0xFF);
+  ucs4len = grub_utf8_to_ucs4 (ucs4, buflen,
+                              (grub_uint8_t *) completion_buffer.buf,
+                              buflen, 0);
+  ucs4[ucs4len] = 0;
+
+  if (restore)
+    for (i = 0; i < screen->nterms; i++)
+      {
+       int num_sections = ((completion_buffer.len
+                            + grub_term_width (screen->terms[i].term) - 8 - 1)
+                           / (grub_term_width (screen->terms[i].term) - 8));
+       grub_uint32_t *endp;
+       grub_uint16_t pos;
+       grub_uint32_t *p = ucs4;
+
+       pos = grub_term_getxy (screen->terms[i].term);
+       grub_term_gotoxy (screen->terms[i].term, 0,
+                         grub_term_height (screen->terms[i].term) - 3);
+
+       screen->completion_shown = 1;
+
+       grub_term_gotoxy (screen->terms[i].term, 0,
+                         grub_term_height (screen->terms[i].term) - 3);
+       grub_puts_terminal ("   ", screen->terms[i].term);
+       switch (completion_type)
+         {
+         case GRUB_COMPLETION_TYPE_COMMAND:
+           grub_puts_terminal (_("Possible commands are:"),
+                               screen->terms[i].term);
+           break;
+         case GRUB_COMPLETION_TYPE_DEVICE:
+           grub_puts_terminal (_("Possible devices are:"),
+                               screen->terms[i].term);
+           break;
+         case GRUB_COMPLETION_TYPE_FILE:
+           grub_puts_terminal (_("Possible files are:"),
+                               screen->terms[i].term);
+           break;
+         case GRUB_COMPLETION_TYPE_PARTITION:
+           grub_puts_terminal (_("Possible partitions are:"),
+                               screen->terms[i].term);
+           break;
+         case GRUB_COMPLETION_TYPE_ARGUMENT:
+           grub_puts_terminal (_("Possible arguments are:"),
+                               screen->terms[i].term);
+           break;
+         default:
+           grub_puts_terminal (_("Possible things are:"),
+                               screen->terms[i].term);
+           break;
+         }
+
+       grub_puts_terminal ("\n    ", screen->terms[i].term);
+
+       p += (count % num_sections)
+         * (grub_term_width (screen->terms[i].term) - 8);
+       endp = p + (grub_term_width (screen->terms[i].term) - 8);
+
+       if (p != ucs4)
+         grub_putcode (GRUB_TERM_DISP_LEFT, screen->terms[i].term);
+       else
+         grub_putcode (' ', screen->terms[i].term);
+
+       while (*p && p < endp)
+         grub_putcode (*p++, screen->terms[i].term);
+
+       if (*p)
+         grub_putcode (GRUB_TERM_DISP_RIGHT, screen->terms[i].term);
+       grub_term_gotoxy (screen->terms[i].term, pos >> 8, pos & 0xFF);
+      }
 
   if (insert)
     {
@@ -945,23 +1109,33 @@ complete (struct screen *screen, int continuous, int update)
 
 /* Clear displayed completions.  */
 static void
-clear_completions (void)
+clear_completions (struct per_term_screen *term_screen)
 {
   grub_uint16_t pos;
-  int i, j;
+  unsigned i, j;
 
-  pos = grub_getxy ();
-  grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
+  pos = grub_term_getxy (term_screen->term);
+  grub_term_gotoxy (term_screen->term, 0,
+                   grub_term_height (term_screen->term) - 3);
 
   for (i = 0; i < 2; i++)
     {
-      for (j = 0; j < GRUB_TERM_WIDTH - 1; j++)
-       grub_putchar (' ');
-      grub_putchar ('\n');
+      for (j = 0; j < grub_term_width (term_screen->term) - 1; j++)
+       grub_putcode (' ', term_screen->term);
+      grub_putcode ('\n', term_screen->term);
     }
 
-  grub_gotoxy (pos >> 8, pos & 0xFF);
-  grub_refresh ();
+  grub_term_gotoxy (term_screen->term, pos >> 8, pos & 0xFF);
+  grub_term_refresh (term_screen->term);
+}
+
+static void
+clear_completions_all (struct screen *screen)
+{
+  unsigned i;
+
+  for (i = 0; i < screen->nterms; i++)
+    clear_completions (&screen->terms[i]);
 }
 
 /* Execute the command list in the screen SCREEN.  */
@@ -1033,6 +1207,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
   struct screen *screen;
   int prev_c;
   grub_err_t err = GRUB_ERR_NONE;
+  unsigned i;
 
   err = grub_auth_check_authentication (NULL);
 
@@ -1049,9 +1224,11 @@ grub_menu_entry_run (grub_menu_entry_t entry)
 
  refresh:
   /* Draw the screen.  */
-  grub_menu_init_page (0, 1);
-  update_screen (screen, 0, 0, 1, 1, ALL_LINES);
-  grub_setcursor (1);
+  for (i = 0; i < screen->nterms; i++)
+    grub_menu_init_page (0, 1, screen->terms[i].term);
+  update_screen_all (screen, 0, 0, 1, 1, ALL_LINES);
+  for (i = 0; i < screen->nterms; i++)
+    grub_term_setcursor (screen->terms[i].term, 1);
   prev_c = '\0';
 
   while (1)
@@ -1060,7 +1237,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
 
       if (screen->completion_shown)
        {
-         clear_completions ();
+         clear_completions_all (screen);
          screen->completion_shown = 0;
        }
 
index 4f2dfb78e34e2b6abca62b9712af8eecbd59257a..edb315524545321a5a39989829cd68f74259a1ac 100644 (file)
 #include <grub/env.h>
 #include <grub/menu_viewer.h>
 #include <grub/i18n.h>
-
-/* Time to delay after displaying an error message about a default/fallback
-   entry failing to boot.  */
-#define DEFAULT_ENTRY_ERROR_DELAY_MS  2500
+#include <grub/charset.h>
 
 static grub_uint8_t grub_color_menu_normal;
 static grub_uint8_t grub_color_menu_highlight;
 
-/* Wait until the user pushes any key so that the user
-   can see what happened.  */
-void
-grub_wait_after_message (void)
+struct menu_viewer_data
 {
-  grub_putchar ('\n');
-  grub_printf_ (N_("Press any key to continue..."));
-  (void) grub_getkey ();
-  grub_putchar ('\n');
-}
+  int first, offset;
+  grub_menu_t menu;
+  struct grub_term_output *term;
+};
 
 static void
-print_spaces (int number_spaces)
+print_spaces (int number_spaces, struct grub_term_output *term)
 {
   int i;
   for (i = 0; i < number_spaces; i++)
-    grub_putchar (' ');
+    grub_putcode (' ', term);
 }
 
 void
 grub_print_ucs4 (const grub_uint32_t * str,
-                const grub_uint32_t * last_position)
+                const grub_uint32_t * last_position,
+                struct grub_term_output *term)
 {
   while (str < last_position)
     {
-      grub_putcode (*str);
+      grub_putcode (*str, term);
       str++;
     }
 }
 
-int
-grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
-                       grub_uint32_t **last_position)
-{
-  grub_ssize_t msg_len = grub_strlen (msg);
-
-  *unicode_msg = grub_malloc (grub_strlen (msg) * sizeof (grub_uint32_t));
-  if (!*unicode_msg)
-    {
-      grub_printf ("utf8_to_ucs4 ERROR1: %s", msg);
-      return -1;
-    }
-
-  msg_len = grub_utf8_to_ucs4 (*unicode_msg, msg_len,
-                             (grub_uint8_t *) msg, -1, 0);
-
-  *last_position = *unicode_msg + msg_len;
-
-  if (msg_len < 0)
-    {
-      grub_printf ("utf8_to_ucs4 ERROR2: %s", msg);
-      grub_free (*unicode_msg);
-    }
-  return msg_len;
-}
-
 grub_ssize_t
-grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position)
+grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
+                    struct grub_term_output *term)
 {
   grub_ssize_t width = 0;
 
   while (str < last_position)
     {
-      width += grub_getcharwidth (*str);
+      width += grub_term_getcharwidth (term, *str);
       str++;
     }
   return width;
 }
 
 void
-grub_print_message_indented (const char *msg, int margin_left, int margin_right)
+grub_print_message_indented (const char *msg, int margin_left, int margin_right,
+                            struct grub_term_output *term)
 {
   int line_len;
-  line_len = GRUB_TERM_WIDTH - grub_getcharwidth ('m') *
-    (margin_left + margin_right);
 
   grub_uint32_t *unicode_msg;
   grub_uint32_t *last_position;
 
   int msg_len;
 
+  line_len = grub_term_width (term) - grub_term_getcharwidth (term, 'm') *
+    (margin_left + margin_right);
+
   msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position);
 
   if (msg_len < 0)
@@ -132,11 +102,12 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right)
   while (current_position < last_position)
     {
       if (! first_loop)
-        grub_putchar ('\n');
+        grub_putcode ('\n', term);
      
       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))
        {
@@ -149,8 +120,8 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right)
            (grub_uint32_t *) last_position : next_new_line + line_len;
        }
 
-      print_spaces (margin_left);
-      grub_print_ucs4 (current_position, next_new_line);
+      print_spaces (margin_left, term);
+      grub_print_ucs4 (current_position, next_new_line, term);
 
       next_new_line++;
       current_position = next_new_line;
@@ -161,52 +132,54 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right)
 
 
 static void
-draw_border (void)
+draw_border (struct grub_term_output *term)
 {
   unsigned i;
 
-  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
 
-  grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
-  grub_putcode (GRUB_TERM_DISP_UL);
-  for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++)
-    grub_putcode (GRUB_TERM_DISP_HLINE);
-  grub_putcode (GRUB_TERM_DISP_UR);
+  grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
+  grub_putcode (GRUB_TERM_DISP_UL, term);
+  for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
+    grub_putcode (GRUB_TERM_DISP_HLINE, term);
+  grub_putcode (GRUB_TERM_DISP_UR, term);
 
-  for (i = 0; i < (unsigned) GRUB_TERM_NUM_ENTRIES; i++)
+  for (i = 0; i < (unsigned) grub_term_num_entries (term); i++)
     {
-      grub_gotoxy (GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
-      grub_putcode (GRUB_TERM_DISP_VLINE);
-      grub_gotoxy (GRUB_TERM_MARGIN + GRUB_TERM_BORDER_WIDTH - 1,
-                  GRUB_TERM_TOP_BORDER_Y + i + 1);
-      grub_putcode (GRUB_TERM_DISP_VLINE);
+      grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
+      grub_putcode (GRUB_TERM_DISP_VLINE, term);
+      grub_term_gotoxy (term, GRUB_TERM_MARGIN + grub_term_border_width (term)
+                       - 1,
+                       GRUB_TERM_TOP_BORDER_Y + i + 1);
+      grub_putcode (GRUB_TERM_DISP_VLINE, term);
     }
 
-  grub_gotoxy (GRUB_TERM_MARGIN,
-              GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + 1);
-  grub_putcode (GRUB_TERM_DISP_LL);
-  for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++)
-    grub_putcode (GRUB_TERM_DISP_HLINE);
-  grub_putcode (GRUB_TERM_DISP_LR);
+  grub_term_gotoxy (term, GRUB_TERM_MARGIN,
+                   GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1);
+  grub_putcode (GRUB_TERM_DISP_LL, term);
+  for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
+    grub_putcode (GRUB_TERM_DISP_HLINE, term);
+  grub_putcode (GRUB_TERM_DISP_LR, term);
 
-  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
 
-  grub_gotoxy (GRUB_TERM_MARGIN,
-              (GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES
-               + GRUB_TERM_MARGIN + 1));
+  grub_term_gotoxy (term, GRUB_TERM_MARGIN,
+                   (GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term)
+                    + GRUB_TERM_MARGIN + 1));
 }
 
 static void
-print_message (int nested, int edit)
+print_message (int nested, int edit, struct grub_term_output *term)
 {
-  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
 
   if (edit)
     {
-      grub_putchar ('\n');
+      grub_putcode ('\n', term);
       grub_print_message_indented (_("Minimum Emacs-like screen editing is \
 supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \
-command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN);
+command-line or ESC to return menu."), STANDARD_MARGIN, STANDARD_MARGIN,
+                                  term);
     }
   else
     {
@@ -218,12 +191,14 @@ entry is highlighted.\n");
       grub_sprintf (msg_translated, msg, (grub_uint32_t) GRUB_TERM_DISP_UP,
                    (grub_uint32_t) GRUB_TERM_DISP_DOWN);
       grub_putchar ('\n');
-      grub_print_message_indented (msg_translated, STANDARD_MARGIN, STANDARD_MARGIN);
+      grub_print_message_indented (msg_translated, STANDARD_MARGIN,
+                                  STANDARD_MARGIN, term);
 
       grub_free (msg_translated);
 
       grub_print_message_indented (_("Press enter to boot the selected OS, \
-\'e\' to edit the commands before booting or \'c\' for a command-line.\n"), STANDARD_MARGIN, STANDARD_MARGIN);
+\'e\' to edit the commands before booting or \'c\' for a command-line.\n"),
+                                  STANDARD_MARGIN, STANDARD_MARGIN, term);
 
       if (nested)
         {
@@ -234,7 +209,8 @@ entry is highlighted.\n");
 }
 
 static void
-print_entry (int y, int highlight, grub_menu_entry_t entry)
+print_entry (int y, int highlight, grub_menu_entry_t entry,
+            struct grub_term_output *term)
 {
   int x;
   const char *title;
@@ -260,482 +236,248 @@ print_entry (int y, int highlight, grub_menu_entry_t entry)
       return;
     }
 
-  grub_getcolor (&old_color_normal, &old_color_highlight);
-  grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight);
-  grub_setcolorstate (highlight
-                     ? GRUB_TERM_COLOR_HIGHLIGHT
-                     : GRUB_TERM_COLOR_NORMAL);
+  grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
+  grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
+  grub_term_setcolorstate (term, highlight
+                          ? GRUB_TERM_COLOR_HIGHLIGHT
+                          : GRUB_TERM_COLOR_NORMAL);
 
-  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
+  grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
 
   for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0;
-       x < GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH - GRUB_TERM_MARGIN;
+       x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
+                 - GRUB_TERM_MARGIN);
        i++)
     {
       if (i < len
-         && x <= (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH
-                  - GRUB_TERM_MARGIN - 1))
+         && x <= (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
+                        - GRUB_TERM_MARGIN - 1))
        {
          grub_ssize_t width;
 
-         width = grub_getcharwidth (unicode_title[i]);
+         width = grub_term_getcharwidth (term, unicode_title[i]);
 
-         if (x + width > (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH
-                          - GRUB_TERM_MARGIN - 1))
-           grub_putcode (GRUB_TERM_DISP_RIGHT);
+         if (x + width > (int) (GRUB_TERM_LEFT_BORDER_X 
+                                + grub_term_border_width (term)
+                                - GRUB_TERM_MARGIN - 1))
+           grub_putcode (GRUB_TERM_DISP_RIGHT, term);
          else
-           grub_putcode (unicode_title[i]);
+           grub_putcode (unicode_title[i], term);
 
          x += width;
        }
       else
        {
-         grub_putchar (' ');
+         grub_putcode (' ', term);
          x++;
        }
     }
-  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
-  grub_putchar (' ');
+  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
+  grub_putcode (' ', term);
 
-  grub_gotoxy (GRUB_TERM_CURSOR_X, y);
+  grub_term_gotoxy (term, grub_term_cursor_x (term), y);
 
-  grub_setcolor (old_color_normal, old_color_highlight);
-  grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
+  grub_term_setcolor (term, old_color_normal, old_color_highlight);
+  grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
   grub_free (unicode_title);
 }
 
 static void
-print_entries (grub_menu_t menu, int first, int offset)
+print_entries (grub_menu_t menu, int first, int offset,
+              struct grub_term_output *term)
 {
   grub_menu_entry_t e;
   int i;
 
-  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
-              GRUB_TERM_FIRST_ENTRY_Y);
+  grub_term_gotoxy (term,
+                   GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term),
+                   GRUB_TERM_FIRST_ENTRY_Y);
 
   if (first)
-    grub_putcode (GRUB_TERM_DISP_UP);
+    grub_putcode (GRUB_TERM_DISP_UP, term);
   else
-    grub_putchar (' ');
+    grub_putcode (' ', term);
 
   e = grub_menu_get_entry (menu, first);
 
-  for (i = 0; i < GRUB_TERM_NUM_ENTRIES; i++)
+  for (i = 0; i < grub_term_num_entries (term); i++)
     {
-      print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e);
+      print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e, term);
       if (e)
        e = e->next;
     }
 
-  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
-              GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES);
+  grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X
+                   + grub_term_border_width (term),
+                   GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term));
 
   if (e)
-    grub_putcode (GRUB_TERM_DISP_DOWN);
+    grub_putcode (GRUB_TERM_DISP_DOWN, term);
   else
-    grub_putchar (' ');
+    grub_putcode (' ', term);
 
-  grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
+  grub_term_gotoxy (term, grub_term_cursor_x (term),
+                   GRUB_TERM_FIRST_ENTRY_Y + offset);
 }
 
 /* Initialize the screen.  If NESTED is non-zero, assume that this menu
    is run from another menu or a command-line. If EDIT is non-zero, show
    a message for the menu entry editor.  */
 void
-grub_menu_init_page (int nested, int edit)
+grub_menu_init_page (int nested, int edit,
+                    struct grub_term_output *term)
 {
   grub_uint8_t old_color_normal, old_color_highlight;
 
-  grub_getcolor (&old_color_normal, &old_color_highlight);
+  grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
 
   /* By default, use the same colors for the menu.  */
   grub_color_menu_normal = old_color_normal;
   grub_color_menu_highlight = old_color_highlight;
 
   /* Then give user a chance to replace them.  */
-  grub_parse_color_name_pair (&grub_color_menu_normal, grub_env_get ("menu_color_normal"));
-  grub_parse_color_name_pair (&grub_color_menu_highlight, grub_env_get ("menu_color_highlight"));
-
-  grub_normal_init_page ();
-  grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight);
-  draw_border ();
-  grub_setcolor (old_color_normal, old_color_highlight);
-  print_message (nested, edit);
-}
-
-/* Get the entry number from the variable NAME.  */
-static int
-get_entry_number (const char *name)
-{
-  char *val;
-  int entry;
-
-  val = grub_env_get (name);
-  if (! val)
-    return -1;
-
-  grub_error_push ();
-
-  entry = (int) grub_strtoul (val, 0, 0);
-
-  if (grub_errno != GRUB_ERR_NONE)
-    {
-      grub_errno = GRUB_ERR_NONE;
-      entry = -1;
-    }
-
-  grub_error_pop ();
-
-  return entry;
+  grub_parse_color_name_pair (&grub_color_menu_normal,
+                             grub_env_get ("menu_color_normal"));
+  grub_parse_color_name_pair (&grub_color_menu_highlight,
+                             grub_env_get ("menu_color_highlight"));
+
+  grub_normal_init_page (term);
+  grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
+  draw_border (term);
+  grub_term_setcolor (term, old_color_normal, old_color_highlight);
+  print_message (nested, edit, term);
 }
 
 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.");
+  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;
-  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;
-
-  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)
+  struct menu_viewer_data *data = dataptr;
+  int oldoffset = data->offset;
+  int complete_redraw = 0;
+  data->offset = entry - data->first;
+  if (data->offset > grub_term_num_entries (data->term) - 1)
     {
-      *auto_boot = 1;
-      return default_entry;
+      data->first = data->offset - (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);
-              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;
 
-/* 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);
+  grub_term_setcursor (data->term, 1);
 }
 
-/* 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 =
+void
+grub_menu_text_register_instances (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;
+  struct grub_term_output *term;
 
-static grub_err_t
-show_text_menu (grub_menu_t menu, int nested)
-{
-  while (1)
+  for (term = grub_term_outputs; term; term = term->next)
     {
-      int boot_entry;
-      grub_menu_entry_t e;
-      int auto_boot;
-
-      boot_entry = run_menu (menu, nested, &auto_boot);
-      if (boot_entry < 0)
-       break;
-
-      e = grub_menu_get_entry (menu, boot_entry);
-      if (! e)
-       continue; /* Menu is empty.  */
-
-      grub_cls ();
-      grub_setcursor (1);
+      if (!grub_term_is_active (term))
+       continue;
+      instance = grub_zalloc (sizeof (*instance));
+      if (!instance)
+       {
+         grub_print_error ();
+         grub_errno = GRUB_ERR_NONE;
+         continue;
+       }
+      data = grub_zalloc (sizeof (*data));
+      if (!data)
+       {
+         grub_free (instance);
+         grub_print_error ();
+         grub_errno = GRUB_ERR_NONE;
+         continue;
+       }
+      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;
+
+      data->menu = menu;
+
+      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;
+       }
 
-      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 ();
-            }
-        }
+      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);
     }
-
-  return GRUB_ERR_NONE;
 }
-
-struct grub_menu_viewer grub_normal_text_menu_viewer =
-{
-  .name = "text",
-  .show_menu = show_text_menu
-};
index 1bd271a212e574decffdac1bd9e9b737bcae900b..b600e75007a919f8b756d419e7b157460dfcb4b6 100644 (file)
 #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;
-}
 
index 73eab548af4407d74e5ecbe3aa3fd536b08bc863..ff5120d48e54ddd1a2c338de72b1db215e70441b 100644 (file)
  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+
 /* The amount of lines counted by the pager.  */
-static int grub_more_lines;
+static unsigned grub_more_lines;
 
 /* If the more pager is active.  */
 static int grub_more;
@@ -25,36 +29,37 @@ static int grub_more;
 static void
 process_newline (void)
 {
-  if (code == '\n')
+  struct grub_term_output *cur;
+  unsigned height = -1;
+
+  for (cur = grub_term_outputs; cur; cur = cur->next)
+    if (grub_term_is_active(cur) && grub_term_height (cur) < height)
+      height = grub_term_height (cur);
+  grub_more_lines++;
+
+  if (grub_more && grub_more_lines == height - 1)
     {
-      grub_putcode ('\r');
-
-      grub_more_lines++;
-
-      if (grub_more && grub_more_lines == height - 1)
-       {
-         char key;
-         int pos = term->getxy ();
-
-         /* Show --MORE-- on the lower left side of the screen.  */
-         term->gotoxy (1, height - 1);
-         grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
-         grub_printf ("--MORE--");
-         grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
-
-         key = grub_getkey ();
-
-         /* Remove the message.  */
-         term->gotoxy (1, height - 1);
-         grub_printf ("        ");
-         term->gotoxy (pos >> 8, pos & 0xFF);
-
-         /* Scroll one lines or an entire page, depending on the key.  */
-         if (key == '\r' || key =='\n')
-           grub_more_lines--;
-         else
-           grub_more_lines = 0;
-       }
+      char key;
+      grub_uint16_t *pos;
+
+      pos = grub_term_save_pos ();
+
+      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
+      grub_printf ("--MORE--");
+      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
+
+      key = grub_getkey ();
+
+      /* Remove the message.  */
+      grub_term_restore_pos (pos);
+      grub_printf ("        ");
+      grub_term_restore_pos (pos);
+
+      /* Scroll one lines or an entire page, depending on the key.  */
+      if (key == '\r' || key =='\n')
+       grub_more_lines--;
+      else
+       grub_more_lines = 0;
     }
 }
 
@@ -67,6 +72,7 @@ grub_set_more (int onoff)
     grub_more--;
 
   grub_more_lines = 0;
+  grub_newline_hook = process_newline;
 }
 
 void
@@ -74,21 +80,14 @@ grub_puts_terminal (const char *str, struct grub_term_output *term)
 {
   grub_uint32_t code;
   grub_ssize_t ret;
-  const char *ptr = str;
-  unsigned i;
+  const grub_uint8_t *ptr = (const grub_uint8_t *) str;
+  const grub_uint8_t *end;
+  end = (const grub_uint8_t *) (str + grub_strlen (str));
 
   while (*ptr)
     {
-      ret = grub_utf8_to_ucs4 (&code, 1, ptr,
-                              grub_strlen (ptr), &ptr);
-      if (ret < 0)
-       {
-         grub_putcode ('?', term);
-         ptr++;
-         continue;
-       }
-      else
-       grub_putcode (code, term);      
+      ret = grub_utf8_to_ucs4 (&code, 1, ptr, end - ptr, &ptr);
+      grub_putcode (code, term);       
     }
 }
 
@@ -100,16 +99,17 @@ grub_term_save_pos (void)
   grub_uint16_t *ret, *ptr;
   
   for (cur = grub_term_outputs; cur; cur = cur->next)
-    if (cur->flags & GRUB_TERM_ACTIVE)
+    if (grub_term_is_active (cur))
       cnt++;
 
   ret = grub_malloc (cnt * sizeof (ret[0]));
   if (!ret)
     return NULL;
 
+  ptr = ret;
   for (cur = grub_term_outputs; cur; cur = cur->next)
-    if (cur->flags & GRUB_TERM_ACTIVE)
-      *ptr++ = cur->getxy ();
+    if (grub_term_is_active (cur))
+      *ptr++ = grub_term_getxy (cur);
 
   return ret;
 }
@@ -118,11 +118,15 @@ void
 grub_term_restore_pos (grub_uint16_t *pos)
 {
   struct grub_term_output *cur;
+  grub_uint16_t *ptr = pos;
 
   if (!pos)
     return;
 
   for (cur = grub_term_outputs; cur; cur = cur->next)
-    if (cur->flags & GRUB_TERM_ACTIVE)
-      cur->gotoxy ((*ptr & 0xff00) >> 8, *ptr & 0xff);
+    if (grub_term_is_active (cur))
+      {
+       grub_term_gotoxy (cur, (*ptr & 0xff00) >> 8, *ptr & 0xff);
+       ptr++;
+      }
 }
index f3845089cdd25a1ce7c15fc8042e30a5bb46c947..bde101ebc09a0b6859083ae496ab0f659f7eb539 100644 (file)
@@ -352,7 +352,7 @@ static struct grub_term_output grub_console_term_output =
     .setcolor = grub_console_setcolor,
     .getcolor = grub_console_getcolor,
     .setcursor = grub_console_setcursor,
-    .flags = 0,
+    .flags = GRUB_TERM_ACTIVE,
   };
 
 void
index b54e2f6f184fcb7d136428206e439807f6dd36be..6f56fc0d75b17c8b2aaf516ef95d95fa9c183a4a 100644 (file)
@@ -66,7 +66,7 @@ static struct grub_term_output grub_console_term_output =
     .setcolor = grub_console_setcolor,
     .getcolor = grub_console_getcolor,
     .setcursor = grub_console_setcursor,
-    .flags = 0,
+    .flags = GRUB_TERM_ACTIVE,
   };
 
 void
index 170f74de8eaf58a56a6beb1e709d66beb8649b4a..4fc54a60d88cb960d37699c946b47eb17df3b540 100644 (file)
@@ -164,10 +164,17 @@ static struct grub_term_output grub_vga_text_term =
     .setcolor = grub_console_setcolor,
     .getcolor = grub_console_getcolor,
     .setcursor = grub_vga_text_setcursor,
+#if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
+    .flags = GRUB_TERM_ACTIVE,
+#endif
   };
 
 GRUB_MOD_INIT(vga_text)
 {
+#if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
+  grub_vga_text_init_fini ();
+#endif
+
   grub_term_register_output ("vga_text", &grub_vga_text_term);
 }
 
index ab11e9fb256adb4cf5d46111ae49cc646ce3808c..95479379e2a78f832bb745c2d281b30b386ed95a 100644 (file)
@@ -415,7 +415,7 @@ static struct grub_term_output grub_ofconsole_term_output =
     .getcolor = grub_ofconsole_getcolor,
     .setcursor = grub_ofconsole_setcursor,
     .refresh = grub_ofconsole_refresh,
-    .flags = 0,
+    .flags = GRUB_TERM_ACTIVE,
   };
 
 void
index 9d8bb1a634140137fc9796940b4358e268b1b451..d9a907308abeb1e8ee00c743c796b14a82cef6cf 100644 (file)
@@ -368,7 +368,7 @@ static struct grub_term_output grub_ncurses_term_output =
     .getcolor = grub_ncurses_getcolor,
     .setcursor = grub_ncurses_setcursor,
     .refresh = grub_ncurses_refresh,
-    .flags = 0,
+    .flags = GRUB_TERM_ACTIVE
   };
 
 void