2009-02-13 20:06:27 +00:00
|
|
|
/* menu_text.c - Basic text menu implementation. */
|
|
|
|
/*
|
|
|
|
* GRUB -- GRand Unified Bootloader
|
|
|
|
* Copyright (C) 2003,2004,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
|
|
|
|
*
|
|
|
|
* GRUB is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* GRUB is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <grub/normal.h>
|
|
|
|
#include <grub/term.h>
|
|
|
|
#include <grub/misc.h>
|
|
|
|
#include <grub/loader.h>
|
|
|
|
#include <grub/mm.h>
|
|
|
|
#include <grub/time.h>
|
|
|
|
#include <grub/env.h>
|
|
|
|
#include <grub/menu_viewer.h>
|
2009-11-22 11:49:54 +00:00
|
|
|
#include <grub/i18n.h>
|
2009-12-24 14:34:33 +00:00
|
|
|
#include <grub/charset.h>
|
2009-02-13 20:06:27 +00:00
|
|
|
|
|
|
|
static grub_uint8_t grub_color_menu_normal;
|
|
|
|
static grub_uint8_t grub_color_menu_highlight;
|
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
struct menu_viewer_data
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2009-12-24 14:34:33 +00:00
|
|
|
int first, offset;
|
2011-04-10 11:56:23 +00:00
|
|
|
/* The number of entries shown at a time. */
|
|
|
|
int num_entries;
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_menu_t menu;
|
|
|
|
struct grub_term_output *term;
|
|
|
|
};
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2009-12-19 23:00:30 +00:00
|
|
|
grub_ssize_t
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
|
|
|
|
struct grub_term_output *term)
|
2009-12-05 11:25:07 +00:00
|
|
|
{
|
|
|
|
grub_ssize_t width = 0;
|
|
|
|
|
|
|
|
while (str < last_position)
|
|
|
|
{
|
2010-03-15 20:14:11 +00:00
|
|
|
struct grub_unicode_glyph glyph;
|
|
|
|
str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph);
|
|
|
|
width += grub_term_getcharwidth (term, &glyph);
|
2009-12-05 11:25:07 +00:00
|
|
|
}
|
|
|
|
return width;
|
|
|
|
}
|
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
static int
|
|
|
|
grub_print_message_indented_real (const char *msg, int margin_left,
|
|
|
|
int margin_right,
|
|
|
|
struct grub_term_output *term, int dry_run)
|
2009-12-05 11:25:07 +00:00
|
|
|
{
|
|
|
|
grub_uint32_t *unicode_msg;
|
2009-12-19 23:00:30 +00:00
|
|
|
grub_uint32_t *last_position;
|
2012-02-26 16:16:05 +00:00
|
|
|
grub_size_t msg_len = grub_strlen (msg) + 2;
|
2012-02-27 09:31:46 +00:00
|
|
|
int ret = 0;
|
2009-12-05 11:25:07 +00:00
|
|
|
|
2012-02-26 16:16:05 +00:00
|
|
|
unicode_msg = grub_malloc (msg_len * sizeof (grub_uint32_t));
|
|
|
|
|
|
|
|
if (!unicode_msg)
|
|
|
|
return 0;
|
2009-12-05 11:25:07 +00:00
|
|
|
|
2012-02-26 16:16:05 +00:00
|
|
|
msg_len = grub_utf8_to_ucs4 (unicode_msg, msg_len,
|
|
|
|
(grub_uint8_t *) msg, -1, 0);
|
|
|
|
|
|
|
|
last_position = unicode_msg + msg_len;
|
|
|
|
*last_position++ = '\n';
|
|
|
|
*last_position = 0;
|
2009-12-05 11:25:07 +00:00
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
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);
|
2010-03-16 13:13:32 +00:00
|
|
|
|
2009-12-05 11:25:07 +00:00
|
|
|
grub_free (unicode_msg);
|
2011-04-10 11:56:23 +00:00
|
|
|
|
|
|
|
return ret;
|
2009-12-05 11:25:07 +00:00
|
|
|
}
|
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
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);
|
|
|
|
}
|
2009-12-05 11:25:07 +00:00
|
|
|
|
2009-02-13 20:06:27 +00:00
|
|
|
static void
|
2011-04-10 11:56:23 +00:00
|
|
|
draw_border (struct grub_term_output *term, int num_entries)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
|
2010-05-09 10:56:32 +00:00
|
|
|
grub_putcode (GRUB_UNICODE_CORNER_UL, term);
|
2009-12-24 14:34:33 +00:00
|
|
|
for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
|
2010-05-09 10:56:32 +00:00
|
|
|
grub_putcode (GRUB_UNICODE_HLINE, term);
|
|
|
|
grub_putcode (GRUB_UNICODE_CORNER_UR, term);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
for (i = 0; i < (unsigned) num_entries; i++)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
|
2010-05-09 10:56:32 +00:00
|
|
|
grub_putcode (GRUB_UNICODE_VLINE, term);
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_gotoxy (term, GRUB_TERM_MARGIN + grub_term_border_width (term)
|
|
|
|
- 1,
|
|
|
|
GRUB_TERM_TOP_BORDER_Y + i + 1);
|
2010-05-09 10:56:32 +00:00
|
|
|
grub_putcode (GRUB_UNICODE_VLINE, term);
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_gotoxy (term, GRUB_TERM_MARGIN,
|
2011-04-10 11:56:23 +00:00
|
|
|
GRUB_TERM_TOP_BORDER_Y + num_entries + 1);
|
2010-05-09 10:56:32 +00:00
|
|
|
grub_putcode (GRUB_UNICODE_CORNER_LL, term);
|
2009-12-24 14:34:33 +00:00
|
|
|
for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
|
2010-05-09 10:56:32 +00:00
|
|
|
grub_putcode (GRUB_UNICODE_HLINE, term);
|
|
|
|
grub_putcode (GRUB_UNICODE_CORNER_LR, term);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_gotoxy (term, GRUB_TERM_MARGIN,
|
2011-04-10 11:56:23 +00:00
|
|
|
(GRUB_TERM_TOP_BORDER_Y + num_entries
|
2009-12-24 14:34:33 +00:00
|
|
|
+ GRUB_TERM_MARGIN + 1));
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
static int
|
|
|
|
print_message (int nested, int edit, struct grub_term_output *term, int dry_run)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2011-04-10 11:56:23 +00:00
|
|
|
int ret = 0;
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
|
|
|
if (edit)
|
|
|
|
{
|
2011-04-10 11:56:23 +00:00
|
|
|
if(dry_run)
|
|
|
|
ret++;
|
|
|
|
else
|
|
|
|
grub_putcode ('\n', term);
|
|
|
|
ret += grub_print_message_indented_real (_("Minimum Emacs-like screen editing is \
|
2010-08-18 23:07:50 +00:00
|
|
|
supported. TAB lists completions. Press Ctrl-x or F10 to boot, Ctrl-c or F2 for a \
|
2010-04-09 19:16:17 +00:00
|
|
|
command-line or ESC to discard edits and return to the GRUB menu."),
|
2011-04-10 11:56:23 +00:00
|
|
|
STANDARD_MARGIN, STANDARD_MARGIN,
|
|
|
|
term, dry_run);
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-12-29 09:04:06 +00:00
|
|
|
const char *msg = _("Use the %C and %C keys to select which "
|
2012-02-26 16:16:05 +00:00
|
|
|
"entry is highlighted.");
|
2009-12-29 09:04:06 +00:00
|
|
|
char *msg_translated;
|
|
|
|
|
2010-05-09 10:56:32 +00:00
|
|
|
msg_translated = grub_xasprintf (msg, GRUB_UNICODE_UPARROW,
|
|
|
|
GRUB_UNICODE_DOWNARROW);
|
2009-12-29 09:04:06 +00:00
|
|
|
if (!msg_translated)
|
2011-04-10 11:56:23 +00:00
|
|
|
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);
|
2009-12-05 11:25:07 +00:00
|
|
|
|
|
|
|
grub_free (msg_translated);
|
|
|
|
|
2009-02-13 20:06:27 +00:00
|
|
|
if (nested)
|
2009-12-25 15:53:54 +00:00
|
|
|
{
|
2011-04-10 11:56:23 +00:00
|
|
|
ret += grub_print_message_indented_real
|
2009-12-25 15:53:54 +00:00
|
|
|
(_("Press enter to boot the selected OS, "
|
2012-03-03 12:05:08 +00:00
|
|
|
"`e' to edit the commands before booting "
|
|
|
|
"or `c' for a command-line. ESC to return previous menu."),
|
2011-04-10 11:56:23 +00:00
|
|
|
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
2009-12-25 15:53:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-04-10 11:56:23 +00:00
|
|
|
ret += grub_print_message_indented_real
|
2009-12-25 15:53:54 +00:00
|
|
|
(_("Press enter to boot the selected OS, "
|
2012-03-03 12:05:08 +00:00
|
|
|
"`e' to edit the commands before booting "
|
|
|
|
"or `c' for a command-line."),
|
2011-04-10 11:56:23 +00:00
|
|
|
STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run);
|
2009-12-25 15:53:54 +00:00
|
|
|
}
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
2011-04-10 11:56:23 +00:00
|
|
|
return ret;
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-12-24 14:34:33 +00:00
|
|
|
print_entry (int y, int highlight, grub_menu_entry_t entry,
|
|
|
|
struct grub_term_output *term)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
|
|
|
int x;
|
|
|
|
const char *title;
|
|
|
|
grub_size_t title_len;
|
|
|
|
grub_ssize_t len;
|
|
|
|
grub_uint32_t *unicode_title;
|
|
|
|
grub_ssize_t i;
|
|
|
|
grub_uint8_t old_color_normal, old_color_highlight;
|
|
|
|
|
|
|
|
title = entry ? entry->title : "";
|
|
|
|
title_len = grub_strlen (title);
|
|
|
|
unicode_title = grub_malloc (title_len * sizeof (*unicode_title));
|
|
|
|
if (! unicode_title)
|
|
|
|
/* XXX How to show this error? */
|
|
|
|
return;
|
|
|
|
|
|
|
|
len = grub_utf8_to_ucs4 (unicode_title, title_len,
|
|
|
|
(grub_uint8_t *) title, -1, 0);
|
|
|
|
if (len < 0)
|
|
|
|
{
|
|
|
|
/* It is an invalid sequence. */
|
|
|
|
grub_free (unicode_title);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-01-21 16:53:41 +00:00
|
|
|
old_color_normal = grub_term_normal_color;
|
|
|
|
old_color_highlight = grub_term_highlight_color;
|
|
|
|
grub_term_normal_color = grub_color_menu_normal;
|
|
|
|
grub_term_highlight_color = grub_color_menu_highlight;
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_setcolorstate (term, highlight
|
|
|
|
? GRUB_TERM_COLOR_HIGHLIGHT
|
|
|
|
: GRUB_TERM_COLOR_NORMAL);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2010-03-15 20:14:11 +00:00
|
|
|
int last_printed = 0;
|
2012-03-27 15:07:26 +00:00
|
|
|
|
|
|
|
for (i = 0; i < len; i++)
|
|
|
|
if (unicode_title[i] == '\n' || unicode_title[i] == '\b'
|
|
|
|
|| unicode_title[i] == '\r' || unicode_title[i] == '\e')
|
|
|
|
unicode_title[i] = ' ';
|
|
|
|
|
2013-04-24 13:07:24 +00:00
|
|
|
for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 2, i = 0;
|
2009-12-24 14:34:33 +00:00
|
|
|
x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
|
2010-03-15 20:14:11 +00:00
|
|
|
- GRUB_TERM_MARGIN);)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
|
|
|
if (i < len
|
2009-12-24 14:34:33 +00:00
|
|
|
&& x <= (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
|
|
|
|
- GRUB_TERM_MARGIN - 1))
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
|
|
|
grub_ssize_t width;
|
2010-03-15 20:14:11 +00:00
|
|
|
struct grub_unicode_glyph glyph;
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2010-03-15 20:14:11 +00:00
|
|
|
i += grub_unicode_aglomerate_comb (unicode_title + i,
|
|
|
|
len - i, &glyph);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2010-03-15 20:14:11 +00:00
|
|
|
width = grub_term_getcharwidth (term, &glyph);
|
2010-03-15 21:12:34 +00:00
|
|
|
grub_free (glyph.combining);
|
2010-03-15 20:14:11 +00:00
|
|
|
|
|
|
|
if (x + width <= (int) (GRUB_TERM_LEFT_BORDER_X
|
2009-12-24 14:34:33 +00:00
|
|
|
+ grub_term_border_width (term)
|
|
|
|
- GRUB_TERM_MARGIN - 1))
|
2010-03-15 20:14:11 +00:00
|
|
|
last_printed = i;
|
2009-02-13 20:06:27 +00:00
|
|
|
x += width;
|
|
|
|
}
|
|
|
|
else
|
2010-03-15 20:14:11 +00:00
|
|
|
break;
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
2010-03-15 20:14:11 +00:00
|
|
|
|
2013-04-24 13:07:24 +00:00
|
|
|
grub_putcode (highlight ? '*' : ' ', term);
|
|
|
|
|
2010-03-15 20:14:11 +00:00
|
|
|
grub_print_ucs4 (unicode_title,
|
2010-03-16 13:13:32 +00:00
|
|
|
unicode_title + last_printed, 0, 0, term);
|
2010-03-15 20:14:11 +00:00
|
|
|
|
|
|
|
if (last_printed != len)
|
|
|
|
{
|
2010-05-09 10:56:32 +00:00
|
|
|
grub_putcode (GRUB_UNICODE_RIGHTARROW, term);
|
2010-03-15 20:14:11 +00:00
|
|
|
struct grub_unicode_glyph pseudo_glyph = {
|
2010-05-09 10:56:32 +00:00
|
|
|
.base = GRUB_UNICODE_RIGHTARROW,
|
2010-03-15 20:14:11 +00:00
|
|
|
.variant = 0,
|
|
|
|
.attributes = 0,
|
|
|
|
.ncomb = 0,
|
2010-03-16 18:55:09 +00:00
|
|
|
.combining = 0,
|
|
|
|
.estimated_width = 1
|
2010-03-15 20:14:11 +00:00
|
|
|
};
|
|
|
|
x += grub_term_getcharwidth (term, &pseudo_glyph);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
|
|
|
|
- GRUB_TERM_MARGIN); x++)
|
|
|
|
grub_putcode (' ', term);
|
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
|
|
|
grub_putcode (' ', term);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_gotoxy (term, grub_term_cursor_x (term), y);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2013-01-21 16:53:41 +00:00
|
|
|
grub_term_normal_color = old_color_normal;
|
|
|
|
grub_term_highlight_color = old_color_highlight;
|
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
2009-02-13 20:06:27 +00:00
|
|
|
grub_free (unicode_title);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-04-10 11:56:23 +00:00
|
|
|
print_entries (grub_menu_t menu, const struct menu_viewer_data *data)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
|
|
|
grub_menu_entry_t e;
|
|
|
|
int i;
|
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
grub_term_gotoxy (data->term,
|
|
|
|
GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (data->term),
|
2009-12-24 14:34:33 +00:00
|
|
|
GRUB_TERM_FIRST_ENTRY_Y);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
if (data->first)
|
|
|
|
grub_putcode (GRUB_UNICODE_UPARROW, data->term);
|
2009-02-13 20:06:27 +00:00
|
|
|
else
|
2011-04-10 11:56:23 +00:00
|
|
|
grub_putcode (' ', data->term);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
e = grub_menu_get_entry (menu, data->first);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
for (i = 0; i < data->num_entries; i++)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2011-04-10 11:56:23 +00:00
|
|
|
print_entry (GRUB_TERM_FIRST_ENTRY_Y + i, data->offset == i,
|
|
|
|
e, data->term);
|
2009-02-13 20:06:27 +00:00
|
|
|
if (e)
|
|
|
|
e = e->next;
|
|
|
|
}
|
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
grub_term_gotoxy (data->term, GRUB_TERM_LEFT_BORDER_X
|
|
|
|
+ grub_term_border_width (data->term),
|
|
|
|
GRUB_TERM_TOP_BORDER_Y + data->num_entries);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
|
|
|
if (e)
|
2011-04-10 11:56:23 +00:00
|
|
|
grub_putcode (GRUB_UNICODE_DOWNARROW, data->term);
|
2009-02-13 20:06:27 +00:00
|
|
|
else
|
2011-04-10 11:56:23 +00:00
|
|
|
grub_putcode (' ', data->term);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
grub_term_gotoxy (data->term, grub_term_cursor_x (data->term),
|
|
|
|
GRUB_TERM_FIRST_ENTRY_Y + data->offset);
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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
|
2011-04-10 11:56:23 +00:00
|
|
|
grub_menu_init_page (int nested, int edit, int *num_entries,
|
2009-12-24 14:34:33 +00:00
|
|
|
struct grub_term_output *term)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
|
|
|
grub_uint8_t old_color_normal, old_color_highlight;
|
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
/* 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;
|
|
|
|
|
2009-02-13 20:06:27 +00:00
|
|
|
/* By default, use the same colors for the menu. */
|
2013-01-21 16:53:41 +00:00
|
|
|
old_color_normal = grub_term_normal_color;
|
|
|
|
old_color_highlight = grub_term_highlight_color;
|
|
|
|
grub_color_menu_normal = grub_term_normal_color;
|
2013-01-27 15:12:05 +00:00
|
|
|
grub_color_menu_highlight = grub_term_highlight_color;
|
2009-02-13 20:06:27 +00:00
|
|
|
|
|
|
|
/* Then give user a chance to replace them. */
|
2009-12-24 14:34:33 +00:00
|
|
|
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);
|
2013-01-21 16:53:41 +00:00
|
|
|
grub_term_normal_color = grub_color_menu_normal;
|
|
|
|
grub_term_highlight_color = grub_color_menu_highlight;
|
2011-04-10 11:56:23 +00:00
|
|
|
draw_border (term, *num_entries);
|
2013-01-21 16:53:41 +00:00
|
|
|
grub_term_normal_color = old_color_normal;
|
|
|
|
grub_term_highlight_color = old_color_highlight;
|
2011-04-10 11:56:23 +00:00
|
|
|
print_message (nested, edit, term, 0);
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-12-24 14:34:33 +00:00
|
|
|
menu_text_print_timeout (int timeout, void *dataptr)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2009-12-05 11:25:07 +00:00
|
|
|
const char *msg =
|
2010-01-03 20:48:09 +00:00
|
|
|
_("The highlighted entry will be executed automatically in %ds.");
|
2009-12-24 14:34:33 +00:00
|
|
|
struct menu_viewer_data *data = dataptr;
|
2009-12-29 09:04:06 +00:00
|
|
|
char *msg_translated;
|
2009-12-24 14:34:33 +00:00
|
|
|
int posx;
|
2009-12-05 11:25:07 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2010-01-20 08:12:47 +00:00
|
|
|
msg_translated = grub_xasprintf (msg, timeout);
|
2009-12-29 09:04:06 +00:00
|
|
|
if (!msg_translated)
|
2009-12-24 14:34:33 +00:00
|
|
|
{
|
|
|
|
grub_print_error ();
|
|
|
|
grub_errno = GRUB_ERR_NONE;
|
|
|
|
return;
|
|
|
|
}
|
2009-12-19 00:05:41 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_print_message_indented (msg_translated, 3, 0, data->term);
|
2009-12-23 16:41:32 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
posx = grub_term_getxy (data->term) >> 8;
|
2010-03-16 13:13:32 +00:00
|
|
|
grub_print_spaces (data->term, grub_term_width (data->term) - posx - 1);
|
2009-12-05 11:25:07 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_gotoxy (data->term,
|
|
|
|
grub_term_cursor_x (data->term),
|
|
|
|
GRUB_TERM_FIRST_ENTRY_Y + data->offset);
|
|
|
|
grub_term_refresh (data->term);
|
2009-12-19 00:05:41 +00:00
|
|
|
}
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
static void
|
|
|
|
menu_text_set_chosen_entry (int entry, void *dataptr)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2009-12-24 14:34:33 +00:00
|
|
|
struct menu_viewer_data *data = dataptr;
|
|
|
|
int oldoffset = data->offset;
|
|
|
|
int complete_redraw = 0;
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
data->offset = entry - data->first;
|
2011-04-10 11:56:23 +00:00
|
|
|
if (data->offset > data->num_entries - 1)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2011-04-10 11:56:23 +00:00
|
|
|
data->first = entry - (data->num_entries - 1);
|
|
|
|
data->offset = data->num_entries - 1;
|
2009-12-24 14:34:33 +00:00
|
|
|
complete_redraw = 1;
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
2009-12-24 14:34:33 +00:00
|
|
|
if (data->offset < 0)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2009-12-24 14:34:33 +00:00
|
|
|
data->offset = 0;
|
|
|
|
data->first = entry;
|
|
|
|
complete_redraw = 1;
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
2009-12-24 14:34:33 +00:00
|
|
|
if (complete_redraw)
|
2011-04-10 11:56:23 +00:00
|
|
|
print_entries (data->menu, data);
|
2009-12-24 14:34:33 +00:00
|
|
|
else
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2009-12-24 14:34:33 +00:00
|
|
|
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);
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_refresh (data->term);
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-12-24 14:34:33 +00:00
|
|
|
menu_text_fini (void *dataptr)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2009-12-24 14:34:33 +00:00
|
|
|
struct menu_viewer_data *data = dataptr;
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_setcursor (data->term, 1);
|
2009-12-25 00:13:21 +00:00
|
|
|
grub_term_cls (data->term);
|
2009-02-13 20:06:27 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-12-24 14:34:33 +00:00
|
|
|
menu_text_clear_timeout (void *dataptr)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2009-12-24 14:34:33 +00:00
|
|
|
struct menu_viewer_data *data = dataptr;
|
|
|
|
|
|
|
|
grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
|
2010-03-16 13:13:32 +00:00
|
|
|
grub_print_spaces (data->term, grub_term_width (data->term) - 1);
|
2009-12-24 14:34:33 +00:00
|
|
|
grub_term_gotoxy (data->term, grub_term_cursor_x (data->term),
|
|
|
|
GRUB_TERM_FIRST_ENTRY_Y + data->offset);
|
|
|
|
grub_term_refresh (data->term);
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
|
|
|
|
2009-12-26 15:39:16 +00:00
|
|
|
grub_err_t
|
|
|
|
grub_menu_try_text (struct grub_term_output *term,
|
|
|
|
int entry, grub_menu_t menu, int nested)
|
2009-02-13 20:06:27 +00:00
|
|
|
{
|
2009-12-24 14:34:33 +00:00
|
|
|
struct menu_viewer_data *data;
|
|
|
|
struct grub_menu_viewer *instance;
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-26 15:39:16 +00:00
|
|
|
instance = grub_zalloc (sizeof (*instance));
|
|
|
|
if (!instance)
|
|
|
|
return grub_errno;
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-26 15:39:16 +00:00
|
|
|
data = grub_zalloc (sizeof (*data));
|
|
|
|
if (!data)
|
|
|
|
{
|
|
|
|
grub_free (instance);
|
|
|
|
return grub_errno;
|
|
|
|
}
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-26 15:39:16 +00:00
|
|
|
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;
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-26 15:39:16 +00:00
|
|
|
data->menu = menu;
|
2009-02-13 20:06:27 +00:00
|
|
|
|
2009-12-26 15:39:16 +00:00
|
|
|
data->offset = entry;
|
|
|
|
data->first = 0;
|
2011-04-10 11:56:23 +00:00
|
|
|
|
|
|
|
grub_term_setcursor (data->term, 0);
|
|
|
|
grub_menu_init_page (nested, 0, &data->num_entries, data->term);
|
|
|
|
|
|
|
|
if (data->offset > data->num_entries - 1)
|
2009-12-26 15:39:16 +00:00
|
|
|
{
|
2011-04-10 11:56:23 +00:00
|
|
|
data->first = data->offset - (data->num_entries - 1);
|
|
|
|
data->offset = data->num_entries - 1;
|
2009-02-13 20:06:27 +00:00
|
|
|
}
|
|
|
|
|
2011-04-10 11:56:23 +00:00
|
|
|
print_entries (menu, data);
|
2009-12-26 15:39:16 +00:00
|
|
|
grub_term_refresh (data->term);
|
|
|
|
grub_menu_register_viewer (instance);
|
|
|
|
|
2009-02-13 20:06:27 +00:00
|
|
|
return GRUB_ERR_NONE;
|
|
|
|
}
|