Core changes hopefully finished

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2009-12-24 15:34:33 +01:00
parent e48625a306
commit 2e71383172
23 changed files with 1493 additions and 947 deletions

View 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];

View 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

View file

@ -27,17 +27,18 @@
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 */

View 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);

View 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);

View 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)

View 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)

View 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;
}

View 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;
}

View 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;

View 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;
}
insert = grub_normal_do_completion (buf, &restore,
print_completion);
/* Restore the original string. */
buf[lpos] = backup;
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;
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;
}

View 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);
}
}

View 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);

View file

@ -27,6 +27,30 @@
#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;
}

File diff suppressed because it is too large Load diff

View file

@ -26,96 +26,66 @@
#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_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_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.");
grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
char *msg_translated =
grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
grub_sprintf (msg_translated, msg, timeout);
grub_print_message_indented (msg_translated, 3, 0);
struct menu_viewer_data *data = dataptr;
char *msg_translated;
int posx;
posx = grub_getxy() >> 8;
print_spaces (GRUB_TERM_WIDTH - posx - 1);
grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
grub_refresh ();
}
grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
/* 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)
{
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)
{
*auto_boot = 1;
return default_entry;
}
offset = default_entry;
if (offset > GRUB_TERM_NUM_ENTRIES - 1)
{
first = offset - (GRUB_TERM_NUM_ENTRIES - 1);
offset = GRUB_TERM_NUM_ENTRIES - 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)
{
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 ();
}
}
/* 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)
msg_translated = grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
if (!msg_translated)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
return;
}
grub_printf ("\n ");
grub_printf_ (N_("Failed to boot default entries.\n"));
grub_wait_after_message ();
grub_sprintf (msg_translated, msg, timeout);
grub_print_message_indented (msg_translated, 3, 0, data->term);
posx = grub_term_getxy (data->term) >> 8;
print_spaces (grub_term_width (data->term) - posx - 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 =
static void
menu_text_set_chosen_entry (int entry, void *dataptr)
{
.notify_booting = notify_booting,
.notify_fallback = notify_fallback,
.notify_failure = notify_execution_failure
};
static grub_err_t
show_text_menu (grub_menu_t menu, int nested)
{
while (1)
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)
{
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 (auto_boot)
{
grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
}
else
{
grub_errno = GRUB_ERR_NONE;
grub_menu_execute_entry (e);
if (grub_errno != GRUB_ERR_NONE)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
grub_wait_after_message ();
}
}
data->first = data->offset - (grub_term_num_entries (data->term) - 1);
data->offset = grub_term_num_entries (data->term) - 1;
complete_redraw = 1;
}
return GRUB_ERR_NONE;
if (data->offset < 0)
{
data->offset = 0;
data->first = entry;
complete_redraw = 1;
}
if (complete_redraw)
print_entries (data->menu, data->first, data->offset, data->term);
else
{
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);
}
grub_term_refresh (data->term);
}
struct grub_menu_viewer grub_normal_text_menu_viewer =
static void
menu_text_fini (void *dataptr)
{
.name = "text",
.show_menu = show_text_menu
};
struct menu_viewer_data *data = dataptr;
grub_term_setcursor (data->term, 1);
}
static void
menu_text_clear_timeout (void *dataptr)
{
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);
}
void
grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested)
{
struct menu_viewer_data *data;
struct grub_menu_viewer *instance;
struct grub_term_output *term;
for (term = grub_term_outputs; term; term = term->next)
{
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;
}
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);
}
}

View file

@ -23,59 +23,4 @@
#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;
}

View file

@ -16,8 +16,12 @@
* 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');
char key;
grub_uint16_t *pos;
grub_more_lines++;
pos = grub_term_save_pos ();
if (grub_more && grub_more_lines == height - 1)
{
char key;
int pos = term->getxy ();
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
grub_printf ("--MORE--");
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
/* 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 ();
key = grub_getkey ();
/* Remove the message. */
grub_term_restore_pos (pos);
grub_printf (" ");
grub_term_restore_pos (pos);
/* 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;
}
/* 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++;
}
}

View 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

View 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

View 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);
}

View 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

View 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