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);
|
int desclen = grub_strlen (cmd->summary);
|
||||||
for (cur = grub_term_outputs; cur; cur = cur->next)
|
for (cur = grub_term_outputs; cur; cur = cur->next)
|
||||||
{
|
{
|
||||||
if (!(cur->flags & GRUB_TERM_ACTIVE))
|
if (!grub_term_is_active (cur))
|
||||||
continue;
|
continue;
|
||||||
int width = grub_term_width(cur);
|
int width = grub_term_width(cur);
|
||||||
char description[width / 2];
|
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. */
|
/* Convert UCS-4 to UTF-8. */
|
||||||
char *grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size);
|
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
|
#endif
|
||||||
|
|
|
@ -27,17 +27,18 @@
|
||||||
|
|
||||||
struct grub_menu_viewer
|
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;
|
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 */
|
#endif /* GRUB_MENU_VIEWER_HEADER */
|
||||||
|
|
|
@ -183,7 +183,7 @@ int EXPORT_FUNC(grub_sprintf) (char *str, const char *fmt, ...) __attribute__ ((
|
||||||
int EXPORT_FUNC(grub_vsprintf) (char *str, const char *fmt, va_list args);
|
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_exit) (void) __attribute__ ((noreturn));
|
||||||
void EXPORT_FUNC(grub_abort) (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 EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
|
||||||
grub_size_t destsize,
|
grub_size_t destsize,
|
||||||
const grub_uint8_t *src,
|
const grub_uint8_t *src,
|
||||||
grub_size_t srcsize,
|
grub_size_t srcsize,
|
||||||
|
|
|
@ -51,15 +51,16 @@ extern struct grub_menu_viewer grub_normal_text_menu_viewer;
|
||||||
/* Defined in `main.c'. */
|
/* Defined in `main.c'. */
|
||||||
void grub_enter_normal_mode (const char *config);
|
void grub_enter_normal_mode (const char *config);
|
||||||
void grub_normal_execute (const char *config, int nested, int batch);
|
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_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,
|
grub_err_t grub_normal_add_menu_entry (int argc, const char **args,
|
||||||
const char *sourcecode);
|
const char *sourcecode);
|
||||||
char *grub_file_getline (grub_file_t file);
|
char *grub_file_getline (grub_file_t file);
|
||||||
void grub_cmdline_run (int nested);
|
void grub_cmdline_run (int nested);
|
||||||
|
|
||||||
/* Defined in `cmdline.c'. */
|
/* 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);
|
grub_err_t grub_set_history (int newsize);
|
||||||
|
|
||||||
/* Defined in `completion.c'. */
|
/* 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'. */
|
/* Defined in `menu_text.c'. */
|
||||||
void grub_wait_after_message (void);
|
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,
|
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,
|
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,
|
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'. */
|
/* Defined in `handler.c'. */
|
||||||
void read_handler_list (void);
|
void read_handler_list (void);
|
||||||
|
|
|
@ -111,37 +111,12 @@ grub_term_color_state;
|
||||||
/* The X position of the left border. */
|
/* The X position of the left border. */
|
||||||
#define GRUB_TERM_LEFT_BORDER_X GRUB_TERM_MARGIN
|
#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. */
|
/* The number of lines of messages at the bottom. */
|
||||||
#define GRUB_TERM_MESSAGE_HEIGHT 8
|
#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. */
|
/* The Y position of the first entry. */
|
||||||
#define GRUB_TERM_FIRST_ENTRY_Y (GRUB_TERM_TOP_BORDER_Y + 1)
|
#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
|
struct grub_term_input
|
||||||
{
|
{
|
||||||
/* The next terminal. */
|
/* 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);
|
grub_uint16_t *grub_term_save_pos (void);
|
||||||
void grub_term_restore_pos (grub_uint16_t *pos);
|
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);
|
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);
|
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. */
|
/* For convenience. */
|
||||||
#define GRUB_TERM_ASCII_CHAR(c) ((c) & 0xff)
|
#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
|
/* 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.
|
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
|
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
|
If SRCEND is not NULL, then *SRCEND is set to the next byte after the
|
||||||
last byte used in SRC. */
|
last byte used in SRC. */
|
||||||
grub_ssize_t
|
grub_size_t
|
||||||
grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
|
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 *src, grub_size_t srcsize,
|
||||||
const grub_uint8_t **srcend)
|
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)
|
if ((c & 0xc0) != 0x80)
|
||||||
{
|
{
|
||||||
/* invalid */
|
/* invalid */
|
||||||
return -1;
|
code = '?';
|
||||||
|
count = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -949,7 +950,11 @@ grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
|
||||||
code = c & 0x01;
|
code = c & 0x01;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -1;
|
{
|
||||||
|
/* invalid */
|
||||||
|
code = '?';
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (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;
|
struct grub_term_output *grub_term_outputs;
|
||||||
|
|
||||||
|
void (*grub_newline_hook) (void) = NULL;
|
||||||
|
|
||||||
/* Put a Unicode character. */
|
/* Put a Unicode character. */
|
||||||
void
|
void
|
||||||
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
|
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
|
||||||
{
|
{
|
||||||
int height;
|
int height;
|
||||||
|
|
||||||
height = term->getwh () & 255;
|
height = grub_term_height (term);
|
||||||
|
|
||||||
if (code == '\t' && term->getxy)
|
if (code == '\t' && term->getxy)
|
||||||
{
|
{
|
||||||
|
@ -50,6 +52,8 @@ grub_putcode (grub_uint32_t code, struct grub_term_output *term)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (code == '\n')
|
||||||
|
(term->putchar) ('\r');
|
||||||
(term->putchar) (code);
|
(term->putchar) (code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +72,7 @@ grub_putchar (int c)
|
||||||
{
|
{
|
||||||
struct grub_term_output *term = (struct grub_term_output *) item;
|
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);
|
grub_putcode (code, term);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -77,14 +81,13 @@ grub_putchar (int c)
|
||||||
buf[size++] = c;
|
buf[size++] = c;
|
||||||
ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0);
|
ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0);
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
code = '?';
|
|
||||||
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
size = 0;
|
size = 0;
|
||||||
grub_list_iterate (GRUB_AS_LIST (grub_term_outputs), do_putcode);
|
grub_list_iterate (GRUB_AS_LIST (grub_term_outputs), do_putcode);
|
||||||
}
|
}
|
||||||
|
if (ret == '\n' && grub_newline_hook)
|
||||||
|
grub_newline_hook ();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -116,7 +119,7 @@ grub_cls (void)
|
||||||
{
|
{
|
||||||
struct grub_term_output *term = (struct grub_term_output *) item;
|
struct grub_term_output *term = (struct grub_term_output *) item;
|
||||||
|
|
||||||
if (!(term->flags & GRUB_TERM_ACTIVE))
|
if (! grub_term_is_active (term))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
|
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;
|
struct grub_term_output *term = (struct grub_term_output *) item;
|
||||||
|
|
||||||
if (!(term->flags & GRUB_TERM_ACTIVE))
|
if (! grub_term_is_active (term))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (term->setcolorstate)
|
grub_term_setcolorstate (term, state);
|
||||||
(term->setcolorstate) (state);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -161,11 +163,10 @@ grub_refresh (void)
|
||||||
{
|
{
|
||||||
struct grub_term_output *term = (struct grub_term_output *) item;
|
struct grub_term_output *term = (struct grub_term_output *) item;
|
||||||
|
|
||||||
if (!(term->flags & GRUB_TERM_ACTIVE))
|
if (!grub_term_is_active (term))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (term->refresh)
|
grub_term_refresh (term);
|
||||||
(term->refresh) ();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
last byte used in SRC. */
|
last byte used in SRC. */
|
||||||
|
|
||||||
#include <grub/charset.h>
|
#include <grub/charset.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
|
||||||
grub_ssize_t
|
grub_ssize_t
|
||||||
grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
|
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;
|
*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);
|
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_err_t
|
||||||
grub_auth_check_authentication (const char *userlist)
|
grub_auth_check_authentication (const char *userlist)
|
||||||
{
|
{
|
||||||
|
@ -187,11 +230,12 @@ grub_auth_check_authentication (const char *userlist)
|
||||||
return GRUB_ERR_NONE;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!grub_cmdline_get (N_("Enter username:"), login, sizeof (login) - 1,
|
grub_puts_ (N_("Enter username: "));
|
||||||
0, 0, 0))
|
|
||||||
|
if (!grub_username_get (login, sizeof (login) - 1))
|
||||||
goto access_denied;
|
goto access_denied;
|
||||||
|
|
||||||
grub_printf ("Enter password: ");
|
grub_puts_ (N_("Enter password: "));
|
||||||
|
|
||||||
if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
|
if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
|
||||||
goto access_denied;
|
goto access_denied;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <grub/file.h>
|
#include <grub/file.h>
|
||||||
#include <grub/env.h>
|
#include <grub/env.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/charset.h>
|
||||||
|
|
||||||
static grub_uint32_t *kill_buf;
|
static grub_uint32_t *kill_buf;
|
||||||
|
|
||||||
|
@ -211,11 +212,12 @@ struct cmdline_term
|
||||||
otherwise return command line. */
|
otherwise return command line. */
|
||||||
/* FIXME: The dumb interface is not supported yet. */
|
/* FIXME: The dumb interface is not supported yet. */
|
||||||
char *
|
char *
|
||||||
grub_cmdline_get (const char *prompt, unsigned max_len)
|
grub_cmdline_get (const char *prompt)
|
||||||
{
|
{
|
||||||
grub_size_t lpos, llen;
|
grub_size_t lpos, llen;
|
||||||
grub_size_t plen;
|
grub_size_t plen;
|
||||||
grub_uint32_t buf[max_len];
|
grub_uint32_t *buf;
|
||||||
|
grub_size_t max_len = 256;
|
||||||
int key;
|
int key;
|
||||||
int histpos = 0;
|
int histpos = 0;
|
||||||
auto void cl_insert (const grub_uint32_t *str);
|
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);
|
auto void cl_set_pos_all (void);
|
||||||
const char *prompt_translated = _(prompt);
|
const char *prompt_translated = _(prompt);
|
||||||
struct cmdline_term *cl_terms;
|
struct cmdline_term *cl_terms;
|
||||||
|
char *ret;
|
||||||
unsigned nterms;
|
unsigned nterms;
|
||||||
|
|
||||||
void cl_set_pos (struct cmdline_term *cl_term)
|
void cl_set_pos (struct cmdline_term *cl_term)
|
||||||
{
|
{
|
||||||
cl_term->xpos = (plen + lpos) % (cl_term->width - 1);
|
cl_term->xpos = (plen + lpos) % (cl_term->width - 1);
|
||||||
cl_term->ypos = cl_term->ystart + (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 ()
|
void cl_set_pos_all ()
|
||||||
|
@ -246,7 +249,7 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
|
||||||
{
|
{
|
||||||
grub_uint32_t *p;
|
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)
|
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);
|
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)
|
if (len + llen < max_len)
|
||||||
{
|
{
|
||||||
grub_memmove (buf + lpos + len, buf + lpos, llen - lpos + 1);
|
grub_memmove (buf + lpos + len, buf + lpos,
|
||||||
grub_memmove (buf + lpos, str, len);
|
(llen - lpos + 1) * sizeof (grub_uint32_t));
|
||||||
|
grub_memmove (buf + lpos, str, len * sizeof (grub_uint32_t));
|
||||||
|
|
||||||
llen += len;
|
llen += len;
|
||||||
lpos += len;
|
lpos += len;
|
||||||
cl_print_all (lpos - len, echo_char);
|
cl_print_all (lpos - len, 0);
|
||||||
cl_set_pos_all ();
|
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);
|
grub_memmove (buf + lpos, buf + lpos + len, llen - lpos + 1);
|
||||||
llen -= len;
|
llen -= len;
|
||||||
cl_print_all (lpos, echo_char);
|
cl_print_all (lpos, 0);
|
||||||
cl_set_pos_all ();
|
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)
|
void init_clterm (struct cmdline_term *cl_term_cur)
|
||||||
{
|
{
|
||||||
cl_term_cur->xpos = plen;
|
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->ystart = cl_term_cur->ypos;
|
||||||
cl_term_cur->width = grub_term_width (cl_term_cur->term);
|
cl_term_cur->width = grub_term_width (cl_term_cur->term);
|
||||||
cl_term_cur->height = grub_term_height (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]);
|
init_clterm (&cl_terms[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf = grub_malloc (max_len * sizeof (grub_uint32_t));
|
||||||
|
if (!buf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
plen = grub_strlen (prompt_translated);
|
plen = grub_strlen (prompt_translated);
|
||||||
lpos = llen = 0;
|
lpos = llen = 0;
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
@ -341,15 +364,15 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
|
||||||
struct grub_term_output *cur;
|
struct grub_term_output *cur;
|
||||||
nterms = 0;
|
nterms = 0;
|
||||||
for (cur = grub_term_outputs; cur; cur = cur->next)
|
for (cur = grub_term_outputs; cur; cur = cur->next)
|
||||||
if (cur->flags & GRUB_TERM_ACTIVE)
|
if (grub_term_is_active (cur))
|
||||||
nterms++;
|
nterms++;
|
||||||
|
|
||||||
cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms);
|
cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms);
|
||||||
if (!cl_terms)
|
if (!cl_terms)
|
||||||
return grub_errno;
|
return 0;
|
||||||
cl_term_cur = cl_terms;
|
cl_term_cur = cl_terms;
|
||||||
for (cur = grub_term_outputs; cur; cur = cur->next)
|
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;
|
cl_term_cur->term = cur;
|
||||||
init_clterm (cl_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);
|
grub_history_add (buf);
|
||||||
|
|
||||||
while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r')
|
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;
|
grub_uint32_t *insert;
|
||||||
int restore;
|
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';
|
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,
|
insertu8 = grub_normal_do_completion (bufu8, &restore,
|
||||||
print_completion);
|
print_completion);
|
||||||
/* Restore the original string. */
|
grub_free (bufu8);
|
||||||
buf[lpos] = backup;
|
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)
|
if (restore)
|
||||||
{
|
{
|
||||||
|
@ -429,7 +473,11 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
|
||||||
grub_free (kill_buf);
|
grub_free (kill_buf);
|
||||||
|
|
||||||
kill_buf = strdup_ucs4 (buf + lpos);
|
kill_buf = strdup_ucs4 (buf + lpos);
|
||||||
|
if (grub_errno)
|
||||||
|
{
|
||||||
|
grub_print_error ();
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
cl_delete (llen - lpos);
|
cl_delete (llen - lpos);
|
||||||
}
|
}
|
||||||
|
@ -481,7 +529,11 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
|
||||||
grub_free (kill_buf);
|
grub_free (kill_buf);
|
||||||
|
|
||||||
kill_buf = grub_malloc (n + 1);
|
kill_buf = grub_malloc (n + 1);
|
||||||
|
if (grub_errno)
|
||||||
|
{
|
||||||
|
grub_print_error ();
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
}
|
||||||
if (kill_buf)
|
if (kill_buf)
|
||||||
{
|
{
|
||||||
grub_memcpy (kill_buf, buf, n);
|
grub_memcpy (kill_buf, buf, n);
|
||||||
|
@ -538,8 +590,6 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
|
||||||
while (buf[lpos] == ' ')
|
while (buf[lpos] == ' ')
|
||||||
lpos++;
|
lpos++;
|
||||||
|
|
||||||
if (history)
|
|
||||||
{
|
|
||||||
histpos = 0;
|
histpos = 0;
|
||||||
if (strlen_ucs4 (buf) > 0)
|
if (strlen_ucs4 (buf) > 0)
|
||||||
{
|
{
|
||||||
|
@ -547,7 +597,8 @@ grub_cmdline_get (const char *prompt, unsigned max_len)
|
||||||
grub_history_replace (histpos, buf);
|
grub_history_replace (histpos, buf);
|
||||||
grub_history_add (empty);
|
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)
|
for (term = grub_term_outputs; term; term = term->next)
|
||||||
{
|
{
|
||||||
if (! (term->flags & GRUB_TERM_ACTIVE))
|
if (! grub_term_is_active (term))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Reloads terminal `normal' and `highlight' colors. */
|
/* Reloads terminal `normal' and `highlight' colors. */
|
||||||
if (term->setcolor)
|
grub_term_setcolor (term, color_normal, color_highlight);
|
||||||
term->setcolor (color_normal, color_highlight);
|
|
||||||
|
|
||||||
/* Propagates `normal' color to terminal current color. */
|
/* Propagates `normal' color to terminal current color. */
|
||||||
if (term->setcolorstate)
|
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
||||||
term->setcolorstate (GRUB_TERM_COLOR_NORMAL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <grub/menu_viewer.h>
|
#include <grub/menu_viewer.h>
|
||||||
#include <grub/auth.h>
|
#include <grub/auth.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/charset.h>
|
||||||
|
|
||||||
#define GRUB_DEFAULT_HISTORY_SIZE 50
|
#define GRUB_DEFAULT_HISTORY_SIZE 50
|
||||||
|
|
||||||
|
@ -420,11 +421,11 @@ grub_normal_init_page (struct grub_term_output *term)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
posx = grub_getstringwidth (unicode_msg, last_position);
|
posx = grub_getstringwidth (unicode_msg, last_position, term);
|
||||||
posx = (grub_term_width (term) - posx) / 2;
|
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_printf("\n\n");
|
||||||
grub_free (unicode_msg);
|
grub_free (unicode_msg);
|
||||||
}
|
}
|
||||||
|
@ -458,7 +459,7 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||||
{
|
{
|
||||||
if (menu && menu->size)
|
if (menu && menu->size)
|
||||||
{
|
{
|
||||||
grub_menu_viewer_show_menu (menu, nested);
|
grub_show_menu (menu, nested);
|
||||||
if (nested)
|
if (nested)
|
||||||
free_menu (menu);
|
free_menu (menu);
|
||||||
}
|
}
|
||||||
|
@ -470,20 +471,19 @@ void
|
||||||
grub_enter_normal_mode (const char *config)
|
grub_enter_normal_mode (const char *config)
|
||||||
{
|
{
|
||||||
grub_normal_execute (config, 0, 0);
|
grub_normal_execute (config, 0, 0);
|
||||||
|
grub_cmdline_run (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enter normal mode from rescue mode. */
|
/* Enter normal mode from rescue mode. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_cmd_normal (struct grub_command *cmd,
|
grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)),
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
{
|
{
|
||||||
grub_unregister_command (cmd);
|
|
||||||
|
|
||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
{
|
{
|
||||||
/* Guess the config filename. It is necessary to make CONFIG static,
|
/* Guess the config filename. It is necessary to make CONFIG static,
|
||||||
so that it won't get broken by longjmp. */
|
so that it won't get broken by longjmp. */
|
||||||
static char *config;
|
char *config;
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
|
|
||||||
prefix = grub_env_get ("prefix");
|
prefix = grub_env_get ("prefix");
|
||||||
|
@ -525,10 +525,9 @@ grub_normal_reader_init (void)
|
||||||
if (! (term->flags & GRUB_TERM_ACTIVE))
|
if (! (term->flags & GRUB_TERM_ACTIVE))
|
||||||
continue;
|
continue;
|
||||||
grub_normal_init_page (term);
|
grub_normal_init_page (term);
|
||||||
if (term->setcursor)
|
grub_term_setcursor (term, 1);
|
||||||
term->setcursor (1);
|
|
||||||
|
|
||||||
grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN);
|
grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term);
|
||||||
grub_puts ("\n");
|
grub_puts ("\n");
|
||||||
}
|
}
|
||||||
grub_free (msg_formatted);
|
grub_free (msg_formatted);
|
||||||
|
@ -536,7 +535,6 @@ grub_normal_reader_init (void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char cmdline[GRUB_MAX_CMDLINE];
|
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
grub_normal_read_line (char **line, int cont)
|
grub_normal_read_line (char **line, int cont)
|
||||||
|
@ -548,18 +546,18 @@ grub_normal_read_line (char **line, int cont)
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
cmdline[0] = 0;
|
*line = grub_cmdline_get (prompt);
|
||||||
if (grub_cmdline_get (prompt, cmdline, sizeof (cmdline), 0, 1, 1))
|
if (*line)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((reader_nested) || (cont))
|
if ((reader_nested) || (cont))
|
||||||
{
|
{
|
||||||
|
grub_free (*line);
|
||||||
*line = 0;
|
*line = 0;
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*line = grub_strdup (cmdline);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,7 +589,7 @@ grub_cmdline_run (int nested)
|
||||||
|
|
||||||
grub_normal_read_line (&line, 0);
|
grub_normal_read_line (&line, 0);
|
||||||
if (! line)
|
if (! line)
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
grub_parser_get_current ()->parse_line (line, grub_normal_read_line);
|
grub_parser_get_current ()->parse_line (line, grub_normal_read_line);
|
||||||
grub_free (line);
|
grub_free (line);
|
||||||
|
@ -612,15 +610,20 @@ GRUB_MOD_INIT(normal)
|
||||||
if (mod)
|
if (mod)
|
||||||
grub_dl_ref (mod);
|
grub_dl_ref (mod);
|
||||||
|
|
||||||
grub_menu_viewer_register (&grub_normal_text_menu_viewer);
|
|
||||||
|
|
||||||
grub_set_history (GRUB_DEFAULT_HISTORY_SIZE);
|
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);
|
grub_register_variable_hook ("pager", 0, grub_env_write_pager);
|
||||||
|
|
||||||
/* Register a command "normal" for the rescue mode. */
|
/* Register a command "normal" for the rescue mode. */
|
||||||
grub_register_command_prio ("normal", grub_cmd_normal,
|
grub_register_command ("normal", grub_cmd_normal,
|
||||||
0, "Enter normal mode", 0);
|
0, "Enter normal mode");
|
||||||
|
|
||||||
/* Reload terminal colors when these variables are written to. */
|
/* Reload terminal colors when these variables are written to. */
|
||||||
grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal);
|
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/command.h>
|
||||||
#include <grub/parser.h>
|
#include <grub/parser.h>
|
||||||
#include <grub/auth.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. */
|
/* Get a menu entry by its index in the entry list. */
|
||||||
grub_menu_entry_t
|
grub_menu_entry_t
|
||||||
|
@ -178,3 +202,364 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
|
||||||
|
|
||||||
callback->notify_failure (callback_data);
|
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/env.h>
|
||||||
#include <grub/menu_viewer.h>
|
#include <grub/menu_viewer.h>
|
||||||
#include <grub/i18n.h>
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/charset.h>
|
||||||
/* Time to delay after displaying an error message about a default/fallback
|
|
||||||
entry failing to boot. */
|
|
||||||
#define DEFAULT_ENTRY_ERROR_DELAY_MS 2500
|
|
||||||
|
|
||||||
static grub_uint8_t grub_color_menu_normal;
|
static grub_uint8_t grub_color_menu_normal;
|
||||||
static grub_uint8_t grub_color_menu_highlight;
|
static grub_uint8_t grub_color_menu_highlight;
|
||||||
|
|
||||||
/* Wait until the user pushes any key so that the user
|
struct menu_viewer_data
|
||||||
can see what happened. */
|
|
||||||
void
|
|
||||||
grub_wait_after_message (void)
|
|
||||||
{
|
{
|
||||||
grub_putchar ('\n');
|
int first, offset;
|
||||||
grub_printf_ (N_("Press any key to continue..."));
|
grub_menu_t menu;
|
||||||
(void) grub_getkey ();
|
struct grub_term_output *term;
|
||||||
grub_putchar ('\n');
|
};
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_spaces (int number_spaces)
|
print_spaces (int number_spaces, struct grub_term_output *term)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < number_spaces; i++)
|
for (i = 0; i < number_spaces; i++)
|
||||||
grub_putchar (' ');
|
grub_putcode (' ', term);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_print_ucs4 (const grub_uint32_t * str,
|
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)
|
while (str < last_position)
|
||||||
{
|
{
|
||||||
grub_putcode (*str);
|
grub_putcode (*str, term);
|
||||||
str++;
|
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_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;
|
grub_ssize_t width = 0;
|
||||||
|
|
||||||
while (str < last_position)
|
while (str < last_position)
|
||||||
{
|
{
|
||||||
width += grub_getcharwidth (*str);
|
width += grub_term_getcharwidth (term, *str);
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
int line_len;
|
||||||
line_len = GRUB_TERM_WIDTH - grub_getcharwidth ('m') *
|
|
||||||
(margin_left + margin_right);
|
|
||||||
|
|
||||||
grub_uint32_t *unicode_msg;
|
grub_uint32_t *unicode_msg;
|
||||||
grub_uint32_t *last_position;
|
grub_uint32_t *last_position;
|
||||||
|
|
||||||
int msg_len;
|
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);
|
msg_len = grub_utf8_to_ucs4_alloc (msg, &unicode_msg, &last_position);
|
||||||
|
|
||||||
if (msg_len < 0)
|
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)
|
while (current_position < last_position)
|
||||||
{
|
{
|
||||||
if (! first_loop)
|
if (! first_loop)
|
||||||
grub_putchar ('\n');
|
grub_putcode ('\n', term);
|
||||||
|
|
||||||
next_new_line = (grub_uint32_t *) last_position;
|
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 != ' ' && next_new_line > current_position &&
|
||||||
next_new_line != last_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;
|
(grub_uint32_t *) last_position : next_new_line + line_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_spaces (margin_left);
|
print_spaces (margin_left, term);
|
||||||
grub_print_ucs4 (current_position, next_new_line);
|
grub_print_ucs4 (current_position, next_new_line, term);
|
||||||
|
|
||||||
next_new_line++;
|
next_new_line++;
|
||||||
current_position = 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
|
static void
|
||||||
draw_border (void)
|
draw_border (struct grub_term_output *term)
|
||||||
{
|
{
|
||||||
unsigned i;
|
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_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y);
|
||||||
grub_putcode (GRUB_TERM_DISP_UL);
|
grub_putcode (GRUB_TERM_DISP_UL, term);
|
||||||
for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++)
|
for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
|
||||||
grub_putcode (GRUB_TERM_DISP_HLINE);
|
grub_putcode (GRUB_TERM_DISP_HLINE, term);
|
||||||
grub_putcode (GRUB_TERM_DISP_UR);
|
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_term_gotoxy (term, GRUB_TERM_MARGIN, GRUB_TERM_TOP_BORDER_Y + i + 1);
|
||||||
grub_putcode (GRUB_TERM_DISP_VLINE);
|
grub_putcode (GRUB_TERM_DISP_VLINE, term);
|
||||||
grub_gotoxy (GRUB_TERM_MARGIN + GRUB_TERM_BORDER_WIDTH - 1,
|
grub_term_gotoxy (term, GRUB_TERM_MARGIN + grub_term_border_width (term)
|
||||||
|
- 1,
|
||||||
GRUB_TERM_TOP_BORDER_Y + i + 1);
|
GRUB_TERM_TOP_BORDER_Y + i + 1);
|
||||||
grub_putcode (GRUB_TERM_DISP_VLINE);
|
grub_putcode (GRUB_TERM_DISP_VLINE, term);
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_gotoxy (GRUB_TERM_MARGIN,
|
grub_term_gotoxy (term, GRUB_TERM_MARGIN,
|
||||||
GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES + 1);
|
GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term) + 1);
|
||||||
grub_putcode (GRUB_TERM_DISP_LL);
|
grub_putcode (GRUB_TERM_DISP_LL, term);
|
||||||
for (i = 0; i < (unsigned) GRUB_TERM_BORDER_WIDTH - 2; i++)
|
for (i = 0; i < (unsigned) grub_term_border_width (term) - 2; i++)
|
||||||
grub_putcode (GRUB_TERM_DISP_HLINE);
|
grub_putcode (GRUB_TERM_DISP_HLINE, term);
|
||||||
grub_putcode (GRUB_TERM_DISP_LR);
|
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_gotoxy (term, GRUB_TERM_MARGIN,
|
||||||
(GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES
|
(GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term)
|
||||||
+ GRUB_TERM_MARGIN + 1));
|
+ GRUB_TERM_MARGIN + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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)
|
if (edit)
|
||||||
{
|
{
|
||||||
grub_putchar ('\n');
|
grub_putcode ('\n', term);
|
||||||
grub_print_message_indented (_("Minimum Emacs-like screen editing is \
|
grub_print_message_indented (_("Minimum Emacs-like screen editing is \
|
||||||
supported. TAB lists completions. Press Ctrl-x to boot, Ctrl-c for a \
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -218,12 +191,14 @@ entry is highlighted.\n");
|
||||||
grub_sprintf (msg_translated, msg, (grub_uint32_t) GRUB_TERM_DISP_UP,
|
grub_sprintf (msg_translated, msg, (grub_uint32_t) GRUB_TERM_DISP_UP,
|
||||||
(grub_uint32_t) GRUB_TERM_DISP_DOWN);
|
(grub_uint32_t) GRUB_TERM_DISP_DOWN);
|
||||||
grub_putchar ('\n');
|
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_free (msg_translated);
|
||||||
|
|
||||||
grub_print_message_indented (_("Press enter to boot the selected OS, \
|
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)
|
if (nested)
|
||||||
{
|
{
|
||||||
|
@ -234,7 +209,8 @@ entry is highlighted.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
int x;
|
||||||
const char *title;
|
const char *title;
|
||||||
|
@ -260,482 +236,248 @@ print_entry (int y, int highlight, grub_menu_entry_t entry)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_getcolor (&old_color_normal, &old_color_highlight);
|
grub_term_getcolor (term, &old_color_normal, &old_color_highlight);
|
||||||
grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight);
|
grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
|
||||||
grub_setcolorstate (highlight
|
grub_term_setcolorstate (term, highlight
|
||||||
? GRUB_TERM_COLOR_HIGHLIGHT
|
? GRUB_TERM_COLOR_HIGHLIGHT
|
||||||
: GRUB_TERM_COLOR_NORMAL);
|
: 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;
|
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++)
|
i++)
|
||||||
{
|
{
|
||||||
if (i < len
|
if (i < len
|
||||||
&& x <= (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH
|
&& x <= (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
|
||||||
- GRUB_TERM_MARGIN - 1))
|
- GRUB_TERM_MARGIN - 1))
|
||||||
{
|
{
|
||||||
grub_ssize_t width;
|
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
|
if (x + width > (int) (GRUB_TERM_LEFT_BORDER_X
|
||||||
|
+ grub_term_border_width (term)
|
||||||
- GRUB_TERM_MARGIN - 1))
|
- GRUB_TERM_MARGIN - 1))
|
||||||
grub_putcode (GRUB_TERM_DISP_RIGHT);
|
grub_putcode (GRUB_TERM_DISP_RIGHT, term);
|
||||||
else
|
else
|
||||||
grub_putcode (unicode_title[i]);
|
grub_putcode (unicode_title[i], term);
|
||||||
|
|
||||||
x += width;
|
x += width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
grub_putchar (' ');
|
grub_putcode (' ', term);
|
||||||
x++;
|
x++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
|
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
||||||
grub_putchar (' ');
|
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_term_setcolor (term, old_color_normal, old_color_highlight);
|
||||||
grub_setcolorstate (GRUB_TERM_COLOR_NORMAL);
|
grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
|
||||||
grub_free (unicode_title);
|
grub_free (unicode_title);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
grub_menu_entry_t e;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
|
grub_term_gotoxy (term,
|
||||||
|
GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term),
|
||||||
GRUB_TERM_FIRST_ENTRY_Y);
|
GRUB_TERM_FIRST_ENTRY_Y);
|
||||||
|
|
||||||
if (first)
|
if (first)
|
||||||
grub_putcode (GRUB_TERM_DISP_UP);
|
grub_putcode (GRUB_TERM_DISP_UP, term);
|
||||||
else
|
else
|
||||||
grub_putchar (' ');
|
grub_putcode (' ', term);
|
||||||
|
|
||||||
e = grub_menu_get_entry (menu, first);
|
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)
|
if (e)
|
||||||
e = e->next;
|
e = e->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
|
grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X
|
||||||
GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES);
|
+ grub_term_border_width (term),
|
||||||
|
GRUB_TERM_TOP_BORDER_Y + grub_term_num_entries (term));
|
||||||
|
|
||||||
if (e)
|
if (e)
|
||||||
grub_putcode (GRUB_TERM_DISP_DOWN);
|
grub_putcode (GRUB_TERM_DISP_DOWN, term);
|
||||||
else
|
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
|
/* 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
|
is run from another menu or a command-line. If EDIT is non-zero, show
|
||||||
a message for the menu entry editor. */
|
a message for the menu entry editor. */
|
||||||
void
|
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_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. */
|
/* By default, use the same colors for the menu. */
|
||||||
grub_color_menu_normal = old_color_normal;
|
grub_color_menu_normal = old_color_normal;
|
||||||
grub_color_menu_highlight = old_color_highlight;
|
grub_color_menu_highlight = old_color_highlight;
|
||||||
|
|
||||||
/* Then give user a chance to replace them. */
|
/* 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_normal,
|
||||||
grub_parse_color_name_pair (&grub_color_menu_highlight, grub_env_get ("menu_color_highlight"));
|
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_normal_init_page (term);
|
||||||
grub_setcolor (grub_color_menu_normal, grub_color_menu_highlight);
|
grub_term_setcolor (term, grub_color_menu_normal, grub_color_menu_highlight);
|
||||||
draw_border ();
|
draw_border (term);
|
||||||
grub_setcolor (old_color_normal, old_color_highlight);
|
grub_term_setcolor (term, old_color_normal, old_color_highlight);
|
||||||
print_message (nested, edit);
|
print_message (nested, edit, term);
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_timeout (int timeout, int offset)
|
menu_text_print_timeout (int timeout, void *dataptr)
|
||||||
{
|
{
|
||||||
const char *msg =
|
const char *msg =
|
||||||
_("The highlighted entry will be booted automatically in %ds.");
|
_("The highlighted entry will be booted automatically in %ds.");
|
||||||
|
struct menu_viewer_data *data = dataptr;
|
||||||
|
char *msg_translated;
|
||||||
|
int posx;
|
||||||
|
|
||||||
grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
|
grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
|
||||||
|
|
||||||
char *msg_translated =
|
msg_translated = grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
|
||||||
grub_malloc (sizeof (char) * grub_strlen (msg) + 5);
|
if (!msg_translated)
|
||||||
|
{
|
||||||
|
grub_print_error ();
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
grub_sprintf (msg_translated, msg, timeout);
|
grub_sprintf (msg_translated, msg, timeout);
|
||||||
grub_print_message_indented (msg_translated, 3, 0);
|
grub_print_message_indented (msg_translated, 3, 0, data->term);
|
||||||
|
|
||||||
int posx;
|
posx = grub_term_getxy (data->term) >> 8;
|
||||||
posx = grub_getxy() >> 8;
|
print_spaces (grub_term_width (data->term) - posx - 1, data->term);
|
||||||
print_spaces (GRUB_TERM_WIDTH - posx - 1);
|
|
||||||
|
|
||||||
grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset);
|
grub_term_gotoxy (data->term,
|
||||||
grub_refresh ();
|
grub_term_cursor_x (data->term),
|
||||||
|
GRUB_TERM_FIRST_ENTRY_Y + data->offset);
|
||||||
|
grub_term_refresh (data->term);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show the menu and handle menu entry selection. Returns the menu entry
|
static void
|
||||||
index that should be executed or -1 if no entry should be executed (e.g.,
|
menu_text_set_chosen_entry (int entry, void *dataptr)
|
||||||
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;
|
struct menu_viewer_data *data = dataptr;
|
||||||
grub_uint64_t saved_time;
|
int oldoffset = data->offset;
|
||||||
int default_entry;
|
int complete_redraw = 0;
|
||||||
int timeout;
|
data->offset = entry - data->first;
|
||||||
|
if (data->offset > grub_term_num_entries (data->term) - 1)
|
||||||
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;
|
data->first = data->offset - (grub_term_num_entries (data->term) - 1);
|
||||||
return default_entry;
|
data->offset = grub_term_num_entries (data->term) - 1;
|
||||||
|
complete_redraw = 1;
|
||||||
}
|
}
|
||||||
|
if (data->offset < 0)
|
||||||
offset = default_entry;
|
|
||||||
if (offset > GRUB_TERM_NUM_ENTRIES - 1)
|
|
||||||
{
|
{
|
||||||
first = offset - (GRUB_TERM_NUM_ENTRIES - 1);
|
data->offset = 0;
|
||||||
offset = GRUB_TERM_NUM_ENTRIES - 1;
|
data->first = entry;
|
||||||
}
|
complete_redraw = 1;
|
||||||
|
|
||||||
/* Initialize the time. */
|
|
||||||
saved_time = grub_get_time_ms ();
|
|
||||||
|
|
||||||
refresh:
|
|
||||||
grub_setcursor (0);
|
|
||||||
grub_menu_init_page (nested, 0);
|
|
||||||
print_entries (menu, first, offset);
|
|
||||||
grub_refresh ();
|
|
||||||
|
|
||||||
timeout = grub_menu_get_timeout ();
|
|
||||||
|
|
||||||
if (timeout > 0)
|
|
||||||
print_timeout (timeout, offset);
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
if (complete_redraw)
|
||||||
|
print_entries (data->menu, data->first, data->offset, data->term);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
first++;
|
print_entry (GRUB_TERM_FIRST_ENTRY_Y + oldoffset, 0,
|
||||||
print_entries (menu, first, offset);
|
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);
|
||||||
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
|
static void
|
||||||
notify_booting (grub_menu_entry_t entry,
|
menu_text_fini (void *dataptr)
|
||||||
void *userdata __attribute__((unused)))
|
|
||||||
{
|
{
|
||||||
grub_printf (" ");
|
struct menu_viewer_data *data = dataptr;
|
||||||
grub_printf_ (N_("Booting \'%s\'"), entry->title);
|
|
||||||
grub_printf ("\n\n");
|
grub_term_setcursor (data->term, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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
|
static void
|
||||||
notify_fallback (grub_menu_entry_t entry,
|
menu_text_clear_timeout (void *dataptr)
|
||||||
void *userdata __attribute__((unused)))
|
|
||||||
{
|
{
|
||||||
grub_printf ("\n ");
|
struct menu_viewer_data *data = dataptr;
|
||||||
grub_printf_ (N_("Falling back to \'%s\'"), entry->title);
|
|
||||||
grub_printf ("\n\n");
|
grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3);
|
||||||
grub_millisleep (DEFAULT_ENTRY_ERROR_DELAY_MS);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback invoked when a menu entry has failed and there is no remaining
|
void
|
||||||
fallback entry to attempt. */
|
grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested)
|
||||||
static void
|
|
||||||
notify_execution_failure (void *userdata __attribute__((unused)))
|
|
||||||
{
|
{
|
||||||
if (grub_errno != GRUB_ERR_NONE)
|
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_print_error ();
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
grub_printf ("\n ");
|
data = grub_zalloc (sizeof (*data));
|
||||||
grub_printf_ (N_("Failed to boot default entries.\n"));
|
if (!data)
|
||||||
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_text_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 ();
|
|
||||||
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_free (instance);
|
||||||
grub_print_error ();
|
grub_print_error ();
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
grub_wait_after_message ();
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GRUB_ERR_NONE;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct grub_menu_viewer grub_normal_text_menu_viewer =
|
|
||||||
{
|
|
||||||
.name = "text",
|
|
||||||
.show_menu = show_text_menu
|
|
||||||
};
|
|
||||||
|
|
|
@ -23,59 +23,4 @@
|
||||||
#include <grub/menu.h>
|
#include <grub/menu.h>
|
||||||
#include <grub/auth.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/>.
|
* 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. */
|
/* The amount of lines counted by the pager. */
|
||||||
static int grub_more_lines;
|
static unsigned grub_more_lines;
|
||||||
|
|
||||||
/* If the more pager is active. */
|
/* If the more pager is active. */
|
||||||
static int grub_more;
|
static int grub_more;
|
||||||
|
@ -25,19 +29,21 @@ static int grub_more;
|
||||||
static void
|
static void
|
||||||
process_newline (void)
|
process_newline (void)
|
||||||
{
|
{
|
||||||
if (code == '\n')
|
struct grub_term_output *cur;
|
||||||
{
|
unsigned height = -1;
|
||||||
grub_putcode ('\r');
|
|
||||||
|
|
||||||
|
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++;
|
grub_more_lines++;
|
||||||
|
|
||||||
if (grub_more && grub_more_lines == height - 1)
|
if (grub_more && grub_more_lines == height - 1)
|
||||||
{
|
{
|
||||||
char key;
|
char key;
|
||||||
int pos = term->getxy ();
|
grub_uint16_t *pos;
|
||||||
|
|
||||||
|
pos = grub_term_save_pos ();
|
||||||
|
|
||||||
/* Show --MORE-- on the lower left side of the screen. */
|
|
||||||
term->gotoxy (1, height - 1);
|
|
||||||
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
|
grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
|
||||||
grub_printf ("--MORE--");
|
grub_printf ("--MORE--");
|
||||||
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
|
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
|
||||||
|
@ -45,9 +51,9 @@ process_newline (void)
|
||||||
key = grub_getkey ();
|
key = grub_getkey ();
|
||||||
|
|
||||||
/* Remove the message. */
|
/* Remove the message. */
|
||||||
term->gotoxy (1, height - 1);
|
grub_term_restore_pos (pos);
|
||||||
grub_printf (" ");
|
grub_printf (" ");
|
||||||
term->gotoxy (pos >> 8, pos & 0xFF);
|
grub_term_restore_pos (pos);
|
||||||
|
|
||||||
/* Scroll one lines or an entire page, depending on the key. */
|
/* Scroll one lines or an entire page, depending on the key. */
|
||||||
if (key == '\r' || key =='\n')
|
if (key == '\r' || key =='\n')
|
||||||
|
@ -55,7 +61,6 @@ process_newline (void)
|
||||||
else
|
else
|
||||||
grub_more_lines = 0;
|
grub_more_lines = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -67,6 +72,7 @@ grub_set_more (int onoff)
|
||||||
grub_more--;
|
grub_more--;
|
||||||
|
|
||||||
grub_more_lines = 0;
|
grub_more_lines = 0;
|
||||||
|
grub_newline_hook = process_newline;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -74,20 +80,13 @@ grub_puts_terminal (const char *str, struct grub_term_output *term)
|
||||||
{
|
{
|
||||||
grub_uint32_t code;
|
grub_uint32_t code;
|
||||||
grub_ssize_t ret;
|
grub_ssize_t ret;
|
||||||
const char *ptr = str;
|
const grub_uint8_t *ptr = (const grub_uint8_t *) str;
|
||||||
unsigned i;
|
const grub_uint8_t *end;
|
||||||
|
end = (const grub_uint8_t *) (str + grub_strlen (str));
|
||||||
|
|
||||||
while (*ptr)
|
while (*ptr)
|
||||||
{
|
{
|
||||||
ret = grub_utf8_to_ucs4 (&code, 1, ptr,
|
ret = grub_utf8_to_ucs4 (&code, 1, ptr, end - ptr, &ptr);
|
||||||
grub_strlen (ptr), &ptr);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
grub_putcode ('?', term);
|
|
||||||
ptr++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
grub_putcode (code, term);
|
grub_putcode (code, term);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,16 +99,17 @@ grub_term_save_pos (void)
|
||||||
grub_uint16_t *ret, *ptr;
|
grub_uint16_t *ret, *ptr;
|
||||||
|
|
||||||
for (cur = grub_term_outputs; cur; cur = cur->next)
|
for (cur = grub_term_outputs; cur; cur = cur->next)
|
||||||
if (cur->flags & GRUB_TERM_ACTIVE)
|
if (grub_term_is_active (cur))
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
ret = grub_malloc (cnt * sizeof (ret[0]));
|
ret = grub_malloc (cnt * sizeof (ret[0]));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
ptr = ret;
|
||||||
for (cur = grub_term_outputs; cur; cur = cur->next)
|
for (cur = grub_term_outputs; cur; cur = cur->next)
|
||||||
if (cur->flags & GRUB_TERM_ACTIVE)
|
if (grub_term_is_active (cur))
|
||||||
*ptr++ = cur->getxy ();
|
*ptr++ = grub_term_getxy (cur);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -118,11 +118,15 @@ void
|
||||||
grub_term_restore_pos (grub_uint16_t *pos)
|
grub_term_restore_pos (grub_uint16_t *pos)
|
||||||
{
|
{
|
||||||
struct grub_term_output *cur;
|
struct grub_term_output *cur;
|
||||||
|
grub_uint16_t *ptr = pos;
|
||||||
|
|
||||||
if (!pos)
|
if (!pos)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (cur = grub_term_outputs; cur; cur = cur->next)
|
for (cur = grub_term_outputs; cur; cur = cur->next)
|
||||||
if (cur->flags & GRUB_TERM_ACTIVE)
|
if (grub_term_is_active (cur))
|
||||||
cur->gotoxy ((*ptr & 0xff00) >> 8, *ptr & 0xff);
|
{
|
||||||
|
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,
|
.setcolor = grub_console_setcolor,
|
||||||
.getcolor = grub_console_getcolor,
|
.getcolor = grub_console_getcolor,
|
||||||
.setcursor = grub_console_setcursor,
|
.setcursor = grub_console_setcursor,
|
||||||
.flags = 0,
|
.flags = GRUB_TERM_ACTIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -66,7 +66,7 @@ static struct grub_term_output grub_console_term_output =
|
||||||
.setcolor = grub_console_setcolor,
|
.setcolor = grub_console_setcolor,
|
||||||
.getcolor = grub_console_getcolor,
|
.getcolor = grub_console_getcolor,
|
||||||
.setcursor = grub_console_setcursor,
|
.setcursor = grub_console_setcursor,
|
||||||
.flags = 0,
|
.flags = GRUB_TERM_ACTIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -164,10 +164,17 @@ static struct grub_term_output grub_vga_text_term =
|
||||||
.setcolor = grub_console_setcolor,
|
.setcolor = grub_console_setcolor,
|
||||||
.getcolor = grub_console_getcolor,
|
.getcolor = grub_console_getcolor,
|
||||||
.setcursor = grub_vga_text_setcursor,
|
.setcursor = grub_vga_text_setcursor,
|
||||||
|
#if defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
|
||||||
|
.flags = GRUB_TERM_ACTIVE,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
GRUB_MOD_INIT(vga_text)
|
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);
|
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,
|
.getcolor = grub_ofconsole_getcolor,
|
||||||
.setcursor = grub_ofconsole_setcursor,
|
.setcursor = grub_ofconsole_setcursor,
|
||||||
.refresh = grub_ofconsole_refresh,
|
.refresh = grub_ofconsole_refresh,
|
||||||
.flags = 0,
|
.flags = GRUB_TERM_ACTIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -368,7 +368,7 @@ static struct grub_term_output grub_ncurses_term_output =
|
||||||
.getcolor = grub_ncurses_getcolor,
|
.getcolor = grub_ncurses_getcolor,
|
||||||
.setcursor = grub_ncurses_setcursor,
|
.setcursor = grub_ncurses_setcursor,
|
||||||
.refresh = grub_ncurses_refresh,
|
.refresh = grub_ncurses_refresh,
|
||||||
.flags = 0,
|
.flags = GRUB_TERM_ACTIVE
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Add table
Reference in a new issue