Core changes hopefully finished
This commit is contained in:
parent
e48625a306
commit
2e71383172
23 changed files with 1493 additions and 947 deletions
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
13
kern/misc.c
13
kern/misc.c
|
@ -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)
|
||||
|
|
25
kern/term.c
25
kern/term.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
113
normal/cmdline.c
113
normal/cmdline.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
385
normal/menu.c
385
normal/menu.c
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue