]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Dynamically count the number of lines for the lower banner.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 10 Apr 2011 11:56:23 +0000 (13:56 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 10 Apr 2011 11:56:23 +0000 (13:56 +0200)
* grub-core/normal/menu_entry.c (per_term_screen): New member
num_entries.
(print_down): Use num_entries.
(update_screen): Likewise.
(grub_menu_entry_run): Set num_entries.
* grub-core/normal/menu_text.c (menu_viewer_data): New member
num_entries.
(grub_print_message_indented): Move real part to ...
(grub_print_message_indented_real): ... here. Additional argument
dry_run.
(draw_border): Additional argument num_entries.
(print_message): Additional argument dry_run.
(print_entries): Receive menu viewer data.
(grub_menu_init_page): New argment num_entries.
(menu_text_set_chosen_entry): Use num_entries.
(grub_menu_try_text): Likewise.
* grub-core/normal/term.c (print_ucs4_terminal): New argument dry_run.
All users updated.
(grub_ucs4_count_lines): New function.
* include/grub/term.h (grub_term_cursor_x): Moved from here ..
* grub-core/normal/menu_text.c (grub_term_cursor_x): ... to here.
* include/grub/term.h (GRUB_TERM_MESSAGE_HEIGHT): Removed.
(grub_term_border_height): Likewise.
(grub_term_num_entries): Likewise.

ChangeLog
grub-core/normal/menu_entry.c
grub-core/normal/menu_text.c
grub-core/normal/term.c
include/grub/normal.h
include/grub/term.h

index 1bb8cf27823ccc5dbcc3149ebcceb87b90231e6f..3f4913ec1a44eecdc3dc11d86d2742d74c579224 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2011-04-10  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Dynamically count the number of lines for the lower banner.
+
+       * grub-core/normal/menu_entry.c (per_term_screen): New member
+       num_entries.
+       (print_down): Use num_entries.
+       (update_screen): Likewise.
+       (grub_menu_entry_run): Set num_entries.
+       * grub-core/normal/menu_text.c (menu_viewer_data): New member
+       num_entries.
+       (grub_print_message_indented): Move real part to ...
+       (grub_print_message_indented_real): ... here. Additional argument
+       dry_run.
+       (draw_border): Additional argument num_entries.
+       (print_message): Additional argument dry_run.
+       (print_entries): Receive menu viewer data.
+       (grub_menu_init_page): New argment num_entries.
+       (menu_text_set_chosen_entry): Use num_entries.
+       (grub_menu_try_text): Likewise.
+       * grub-core/normal/term.c (print_ucs4_terminal): New argument dry_run.
+       All users updated.
+       (grub_ucs4_count_lines): New function.
+       * include/grub/term.h (grub_term_cursor_x): Moved from here ..
+       * grub-core/normal/menu_text.c (grub_term_cursor_x): ... to here.
+       * include/grub/term.h (GRUB_TERM_MESSAGE_HEIGHT): Removed.
+       (grub_term_border_height): Likewise.
+       (grub_term_num_entries): Likewise.
+
 2011-04-10  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/boot/mips/yeeloong/fwstart.S: Fix address to error message.
index 30af2c1dca0330c458a201f62decd32251e43f03..dc5ab528fe6f97bf2f08ff21be7a457ee5d3d899 100644 (file)
@@ -52,6 +52,8 @@ struct per_term_screen
   int x;
   /* The Y coordinate.  */
   int y;
+  /* Number of entries.  */
+  int num_entries;
 };
 
 struct screen
@@ -188,7 +190,7 @@ print_down (int flag, struct per_term_screen *term_screen)
   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));
+                   + term_screen->num_entries);
 
   if (flag)
     grub_putcode (GRUB_UNICODE_DOWNARROW, term_screen->term);
@@ -209,13 +211,12 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
   struct line *linep;
 
   /* Check if scrolling is necessary.  */
-  if (term_screen->y < 0 || term_screen->y
-      >= grub_term_num_entries (term_screen->term))
+  if (term_screen->y < 0 || term_screen->y >= term_screen->num_entries)
     {
       if (term_screen->y < 0)
        term_screen->y = 0;
       else
-       term_screen->y = grub_term_num_entries (term_screen->term) - 1;
+       term_screen->y = term_screen->num_entries - 1;
 
       region_start = 0;
       region_column = 0;
@@ -251,7 +252,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
 
          for (column = 0;
               column <= linep->len
-                && y < grub_term_num_entries (term_screen->term);
+                && y < term_screen->num_entries;
               column += grub_term_entry_width (term_screen->term), y++)
            {
              if (y < 0)
@@ -272,7 +273,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
                print_line (linep, column, 0, y, term_screen);
            }
 
-         if (y == grub_term_num_entries (term_screen->term))
+         if (y == term_screen->num_entries)
            {
              if (column <= linep->len || i + 1 < screen->num_lines)
                down_flag = 1;
@@ -282,11 +283,11 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
          i++;
 
          if (mode == ALL_LINES && i == screen->num_lines)
-           for (; y < grub_term_num_entries (term_screen->term); y++)
+           for (; y < term_screen->num_entries; y++)
              print_empty_line (y, term_screen);
 
        }
-      while (y < grub_term_num_entries (term_screen->term));
+      while (y < term_screen->num_entries);
 
       /* Draw up and down arrows.  */
       if (up)
@@ -1290,7 +1291,8 @@ grub_menu_entry_run (grub_menu_entry_t entry)
   }
   /* Draw the screen.  */
   for (i = 0; i < screen->nterms; i++)
-    grub_menu_init_page (0, 1, screen->terms[i].term);
+    grub_menu_init_page (0, 1, &screen->terms[i].num_entries,
+                        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);
index fc4a8919653799a0911a4bc9ece5b52ce814bc0d..93f0492bc9bb24ff8a696fec93ce0d9dda6bdd0d 100644 (file)
@@ -34,10 +34,19 @@ static grub_uint8_t grub_color_menu_highlight;
 struct menu_viewer_data
 {
   int first, offset;
+  /* The number of entries shown at a time.  */
+  int num_entries;
   grub_menu_t menu;
   struct grub_term_output *term;
 };
 
+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);
+}
+
 grub_ssize_t
 grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
                     struct grub_term_output *term)
@@ -53,30 +62,45 @@ grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
   return width;
 }
 
-void
-grub_print_message_indented (const char *msg, int margin_left, int margin_right,
-                            struct grub_term_output *term)
+static int
+grub_print_message_indented_real (const char *msg, int margin_left,
+                                 int margin_right,
+                                 struct grub_term_output *term, int dry_run)
 {
   grub_uint32_t *unicode_msg;
   grub_uint32_t *last_position;
 
   int msg_len;
+  int ret = 0;
 
   msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position);
 
   if (msg_len < 0)
     {
-      return;
+      return 0;
     }
 
-  grub_print_ucs4 (unicode_msg, last_position, margin_left, margin_right, term);
+  if (dry_run)
+    ret = grub_ucs4_count_lines (unicode_msg, last_position, margin_left,
+                                margin_right, term);
+  else
+    grub_print_ucs4 (unicode_msg, last_position, margin_left,
+                    margin_right, term);
 
   grub_free (unicode_msg);
+
+  return ret;
 }
 
+void
+grub_print_message_indented (const char *msg, int margin_left, int margin_right,
+                            struct grub_term_output *term)
+{
+  grub_print_message_indented_real (msg, margin_left, margin_right, term, 0);
+}
 
 static void
-draw_border (struct grub_term_output *term)
+draw_border (struct grub_term_output *term, int num_entries)
 {
   unsigned i;
 
@@ -88,7 +112,7 @@ draw_border (struct grub_term_output *term)
     grub_putcode (GRUB_UNICODE_HLINE, term);
   grub_putcode (GRUB_UNICODE_CORNER_UR, term);
 
-  for (i = 0; i < (unsigned) grub_term_num_entries (term); i++)
+  for (i = 0; i < (unsigned) num_entries; i++)
     {
       grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
       grub_putcode (GRUB_UNICODE_VLINE, term);
@@ -99,7 +123,7 @@ draw_border (struct grub_term_output *term)
     }
 
   grub_term_gotoxy (term, GRUB_TERM_MARGIN,
-                   GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1);
+                   GRUB_TERM_TOP_BORDER_Y + num_entries + 1);
   grub_putcode (GRUB_UNICODE_CORNER_LL, term);
   for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
     grub_putcode (GRUB_UNICODE_HLINE, term);
@@ -108,22 +132,27 @@ draw_border (struct grub_term_output *term)
   grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
 
   grub_term_gotoxy (term, GRUB_TERM_MARGIN,
-                   (GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term)
+                   (GRUB_TERM_TOP_BORDER_Y + num_entries
                     + GRUB_TERM_MARGIN + 1));
 }
 
-static void
-print_message (int nested, int edit, struct grub_term_output *term)
+static int
+print_message (int nested, int edit, struct grub_term_output *term, int dry_run)
 {
+  int ret = 0;
   grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
 
   if (edit)
     {
-      grub_putcode ('\n', term);
-      grub_print_message_indented (_("Minimum Emacs-like screen editing is \
+      if(dry_run)
+       ret++;
+      else
+       grub_putcode ('\n', term);
+      ret += grub_print_message_indented_real (_("Minimum Emacs-like screen editing is \
 supported. TAB lists completions. Press Ctrl-x or F10 to boot, Ctrl-c or F2 for a \
 command-line or ESC to discard edits and return to the GRUB menu."),
-                                   STANDARD_MARGIN, STANDARD_MARGIN, term);
+                                              STANDARD_MARGIN, STANDARD_MARGIN,
+                                              term, dry_run);
     }
   else
     {
@@ -134,30 +163,34 @@ command-line or ESC to discard edits and return to the GRUB menu."),
       msg_translated = grub_xasprintf (msg, GRUB_UNICODE_UPARROW,
                                       GRUB_UNICODE_DOWNARROW);
       if (!msg_translated)
-       return;
-      grub_putcode ('\n', term);
-      grub_print_message_indented (msg_translated, STANDARD_MARGIN,
-                                  STANDARD_MARGIN, term);
+       return 0;
+      if(dry_run)
+       ret++;
+      else
+       grub_putcode ('\n', term);
+      ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN,
+                                              STANDARD_MARGIN, term, dry_run);
 
       grub_free (msg_translated);
 
       if (nested)
        {
-         grub_print_message_indented
+         ret += grub_print_message_indented_real
            (_("Press enter to boot the selected OS, "
               "\'e\' to edit the commands before booting "
               "or \'c\' for a command-line. ESC to return previous menu.\n"),
-            STANDARD_MARGIN, STANDARD_MARGIN, term);
+            STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
        }
       else
        {
-         grub_print_message_indented
+         ret += grub_print_message_indented_real
            (_("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, term);
+            STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
        }       
     }
+  return ret;
 }
 
 static void
@@ -256,52 +289,56 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
 }
 
 static void
-print_entries (grub_menu_t menu, int first, int offset,
-              struct grub_term_output *term)
+print_entries (grub_menu_t menu, const struct menu_viewer_data *data)
 {
   grub_menu_entry_t e;
   int i;
 
-  grub_term_gotoxy (term,
-                   GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term),
+  grub_term_gotoxy (data->term,
+                   GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (data->term),
                    GRUB_TERM_FIRST_ENTRY_Y);
 
-  if (first)
-    grub_putcode (GRUB_UNICODE_UPARROW, term);
+  if (data->first)
+    grub_putcode (GRUB_UNICODE_UPARROW, data->term);
   else
-    grub_putcode (' ', term);
+    grub_putcode (' ', data->term);
 
-  e = grub_menu_get_entry (menu, first);
+  e = grub_menu_get_entry (menu, data->first);
 
-  for (i = 0; i < grub_term_num_entries (term); i++)
+  for (i = 0; i < data->num_entries; i++)
     {
-      print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, offset == i, e, term);
+      print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, data->offset == i,
+                  e, data->term);
       if (e)
        e = e->next;
     }
 
-  grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X
-                   + grub_term_border_width (term),
-                   GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term));
+  grub_term_gotoxy (data->term, GRUB_TERM_LEFT_BORDER_X
+                   + grub_term_border_width (data->term),
+                   GRUB_TERM_TOP_BORDER_Y + data->num_entries);
 
   if (e)
-    grub_putcode (GRUB_UNICODE_DOWNARROW, term);
+    grub_putcode (GRUB_UNICODE_DOWNARROW, data->term);
   else
-    grub_putcode (' ', term);
+    grub_putcode (' ', data->term);
 
-  grub_term_gotoxy (term, grub_term_cursor_x (term),
-                   GRUB_TERM_FIRST_ENTRY_Y + offset);
+  grub_term_gotoxy (data->term, grub_term_cursor_x (data->term),
+                   GRUB_TERM_FIRST_ENTRY_Y + data->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, int *num_entries,
                     struct grub_term_output *term)
 {
   grub_uint8_t old_color_normal, old_color_highlight;
 
+  /* 3 lines for timeout message and bottom margin.  2 lines for the border.  */
+  *num_entries = grub_term_height (term) - GRUB_TERM_TOP_BORDER_Y
+    - (print_message (nested, edit, term, 1) + 3) - 2;
+
   grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
 
   /* By default, use the same colors for the menu.  */
@@ -316,9 +353,9 @@ grub_menu_init_page (int nested, int edit,
 
   grub_normal_init_page (term);
   grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
-  draw_border (term);
+  draw_border (term, *num_entries);
   grub_term_setcolor (term, old_color_normal, old_color_highlight);
-  print_message (nested, edit, term);
+  print_message (nested, edit, term, 0);
 }
 
 static void
@@ -359,10 +396,10 @@ menu_text_set_chosen_entry (int entry, void *dataptr)
   int complete_redraw = 0;
 
   data->offset = entry - data->first;
-  if (data->offset > grub_term_num_entries (data->term) - 1)
+  if (data->offset > data->num_entries - 1)
     {
-      data->first = entry - (grub_term_num_entries (data->term) - 1);
-      data->offset = grub_term_num_entries (data->term) - 1;
+      data->first = entry - (data->num_entries - 1);
+      data->offset = data->num_entries - 1;
       complete_redraw = 1;
     }
   if (data->offset < 0)
@@ -372,7 +409,7 @@ menu_text_set_chosen_entry (int entry, void *dataptr)
       complete_redraw = 1;
     }
   if (complete_redraw)
-    print_entries (data->menu, data->first, data->offset, data->term);
+    print_entries (data->menu, data);
   else
     {
       print_entry (GRUB_TERM_FIRST_ENTRY_Y + oldoffset, 0,
@@ -436,15 +473,17 @@ grub_menu_try_text (struct grub_term_output *term,
 
   data->offset = entry;
   data->first = 0;
-  if (data->offset > grub_term_num_entries (data->term) - 1)
+
+  grub_term_setcursor (data->term, 0);
+  grub_menu_init_page (nested, 0, &data->num_entries, data->term);
+
+  if (data->offset > data->num_entries - 1)
     {
-      data->first = data->offset - (grub_term_num_entries (data->term) - 1);
-      data->offset = grub_term_num_entries (data->term) - 1;
+      data->first = data->offset - (data->num_entries - 1);
+      data->offset = data->num_entries - 1;
     }
 
-  grub_term_setcursor (data->term, 0);
-  grub_menu_init_page (nested, 0, data->term);
-  print_entries (menu, data->first, data->offset, data->term);
+  print_entries (menu, data);
   grub_term_refresh (data->term);
   grub_menu_register_viewer (instance);
 
index 9c4b491f5008cc8e6e0a979ebc7d2d05b7400830..a8b9e6683d212afdc094f76704d561d9862421c6 100644 (file)
@@ -515,14 +515,16 @@ print_ucs4_terminal (const grub_uint32_t * str,
                     const grub_uint32_t * last_position,
                     int margin_left, int margin_right,
                     struct grub_term_output *term,
-                    struct term_state *state)
+                    struct term_state *state,
+                    int dry_run)
 {
   const grub_uint32_t *ptr;
-  grub_ssize_t startwidth = get_startwidth (term, margin_left);
+  grub_ssize_t startwidth = dry_run ? 0 : get_startwidth (term, margin_left);
   grub_ssize_t line_width = startwidth;
   grub_ssize_t lastspacewidth = 0;
   grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right);
   const grub_uint32_t *line_start = str, *last_space = str - 1;
+  int lines = 0;
 
   for (ptr = str; ptr < last_position; ptr++)
     {
@@ -560,50 +562,59 @@ print_ucs4_terminal (const grub_uint32_t * str,
          else
            lastspacewidth = line_width - last_width;
 
-         for (ptr2 = line_start; ptr2 < ptr; ptr2++)
-           {
-             /* Skip combining characters on non-UTF8 terminals.  */
-             if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) 
-                 != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
-                 && grub_unicode_get_comb_type (*ptr2)
-                 != GRUB_UNICODE_COMB_NONE)
-               continue;
-             putcode_real (*ptr2, term);
-           }
+         lines++;
 
-         grub_print_spaces (term, margin_right);
-         grub_putcode ('\n', term);
-         if (state && ++state->num_lines
-             >= (grub_ssize_t) grub_term_height (term) - 2)
+         if (!dry_run)
            {
-             state->backlog_ucs4 = (ptr == last_space || *ptr == '\n') 
-               ? ptr + 1 : ptr;
-             state->backlog_len = last_position - state->backlog_ucs4;
-             return 1;
+             for (ptr2 = line_start; ptr2 < ptr; ptr2++)
+               {
+                 /* Skip combining characters on non-UTF8 terminals.  */
+                 if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) 
+                     != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
+                     && grub_unicode_get_comb_type (*ptr2)
+                     != GRUB_UNICODE_COMB_NONE)
+                   continue;
+                 putcode_real (*ptr2, term);
+               }
+
+             grub_print_spaces (term, margin_right);
+             grub_putcode ('\n', term);
+             if (state && ++state->num_lines
+                 >= (grub_ssize_t) grub_term_height (term) - 2)
+               {
+                 state->backlog_ucs4 = (ptr == last_space || *ptr == '\n') 
+                   ? ptr + 1 : ptr;
+                 state->backlog_len = last_position - state->backlog_ucs4;
+                 return 1;
+               }
            }
 
          line_width -= lastspacewidth;
-         grub_print_spaces (term, margin_left);
+         if (!dry_run)
+           grub_print_spaces (term, margin_left);
          if (ptr == last_space || *ptr == '\n')
            ptr++;
          line_start = ptr;
        }
     }
 
-  {
-    const grub_uint32_t *ptr2;
-    for (ptr2 = line_start; ptr2 < last_position; ptr2++)
-      {
-       /* Skip combining characters on non-UTF8 terminals.  */
-       if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) 
-           != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
-           && grub_unicode_get_comb_type (*ptr2)
-           != GRUB_UNICODE_COMB_NONE)
-         continue;
-       putcode_real (*ptr2, term);
-      }
-  }
-  return 0;
+  if (line_start < last_position)
+    lines++;
+  if (!dry_run)
+    {
+      const grub_uint32_t *ptr2;
+      for (ptr2 = line_start; ptr2 < last_position; ptr2++)
+       {
+         /* Skip combining characters on non-UTF8 terminals.  */
+         if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) 
+             != GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
+             && grub_unicode_get_comb_type (*ptr2)
+             != GRUB_UNICODE_COMB_NONE)
+           continue;
+         putcode_real (*ptr2, term);
+       }
+    }
+  return dry_run ? lines : 0;
 }
 
 static struct term_state *
@@ -672,7 +683,7 @@ print_backlog (struct grub_term_output *term,
       int ret;
       ret = print_ucs4_terminal (state->backlog_ucs4,
                                 state->backlog_ucs4 + state->backlog_len,
-                                margin_left, margin_right, term, state);
+                                margin_left, margin_right, term, state, 0);
       if (!ret)
        {
          grub_free (state->free);
@@ -706,15 +717,19 @@ static int
 print_ucs4_real (const grub_uint32_t * str,
                 const grub_uint32_t * last_position,
                 int margin_left, int margin_right,
-                struct grub_term_output *term, int backlog)
+                struct grub_term_output *term, int backlog,
+                int dry_run)
 {
   struct term_state *state = NULL;
 
-  if (backlog)
-    state = find_term_state (term);
+  if (!dry_run)
+    {
+      if (backlog)
+       state = find_term_state (term);
 
-  if (((term->getxy (term) >> 8) & 0xff) < margin_left)
-    grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff));
+      if (((term->getxy (term) >> 8) & 0xff) < margin_left)
+       grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff));
+    }
 
   if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) 
       == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
@@ -743,16 +758,30 @@ print_ucs4_real (const grub_uint32_t * str,
          grub_print_error ();
          return 0;
        }
-      ret = put_glyphs_terminal (visual, visual_len, margin_left, margin_right,
-                                term, state);
-      if (!ret)
-       grub_free (visual);
+      if (dry_run)
+       {
+         struct grub_unicode_glyph *vptr;
+         ret = 0;
+         for (vptr = visual; vptr < visual + visual_len; vptr++)
+           if (vptr->base == '\n')
+             ret++;
+         if (visual_len && visual[visual_len - 1].base != '\n')
+           ret++;
+         grub_free (visual);
+       }
       else
-       state->free = visual;
+       {
+         ret = put_glyphs_terminal (visual, visual_len, margin_left,
+                                    margin_right, term, state);
+         if (!ret)
+           grub_free (visual);
+         else
+           state->free = visual;
+       }
       return ret;
     }
   return print_ucs4_terminal (str, last_position, margin_left, margin_right,
-                             term, state);
+                             term, state, dry_run);
 }
 
 void
@@ -762,9 +791,18 @@ grub_print_ucs4 (const grub_uint32_t * str,
                 struct grub_term_output *term)
 {
   print_ucs4_real (str, last_position, margin_left, margin_right,
-                  term, 0);
+                  term, 0, 0);
 }
 
+int
+grub_ucs4_count_lines (const grub_uint32_t * str,
+                      const grub_uint32_t * last_position,
+                      int margin_left, int margin_right,
+                      struct grub_term_output *term)
+{
+  return print_ucs4_real (str, last_position, margin_left, margin_right,
+                         term, 0, 1);
+}
 
 void
 grub_xputs_normal (const char *str)
@@ -813,7 +851,7 @@ grub_xputs_normal (const char *str)
   {
     int cur;
     cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0,
-                          term, grub_more);
+                          term, grub_more, 0);
     if (cur)
       backlog = 1;
   }
index 3b99e073a76ea818f5457310776282aaee7e0652..08c14d20914befabf6ffdcf3cbfe9d3f9691fafb 100644 (file)
@@ -51,7 +51,7 @@ extern int grub_normal_exit_level;
 /* 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,
+void grub_menu_init_page (int nested, int edit, int *num_entries,
                          struct grub_term_output *term);
 void grub_normal_init_page (struct grub_term_output *term);
 char *grub_file_getline (grub_file_t file);
@@ -80,6 +80,11 @@ grub_print_ucs4 (const grub_uint32_t * str,
                 const grub_uint32_t * last_position,
                 int margin_left, int margin_right,
                 struct grub_term_output *term);
+int
+grub_ucs4_count_lines (const grub_uint32_t * str,
+                      const grub_uint32_t * last_position,
+                      int margin_left, int margin_right,
+                      struct grub_term_output *term);
 grub_ssize_t grub_getstringwidth (grub_uint32_t * str,
                                  const grub_uint32_t * last_position,
                                  struct grub_term_output *term);
index dbcb2f52cc4fab43c90dedd50c7f1762e3b06c5a..726c84dbfebc4c921e43dbcd0b18074c02e0f359 100644 (file)
@@ -140,9 +140,6 @@ grub_term_color_state;
 /* The X position of the left border.  */
 #define GRUB_TERM_LEFT_BORDER_X        GRUB_TERM_MARGIN
 
-/* The number of lines of messages at the bottom.  */
-#define GRUB_TERM_MESSAGE_HEIGHT       8
-
 /* The Y position of the first entry.  */
 #define GRUB_TERM_FIRST_ENTRY_Y        (GRUB_TERM_TOP_BORDER_Y + 1)
 
@@ -339,29 +336,6 @@ 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)
 {