From: Vladimir 'phcoder' Serbinenko Date: Tue, 5 Jan 2010 15:27:41 +0000 (+0100) Subject: Merge mainline into multiterm X-Git-Tag: 1.98~93^2~16^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=519634516f724feddfdf0fe915322cf9d85e7471;p=thirdparty%2Fgrub.git Merge mainline into multiterm --- 519634516f724feddfdf0fe915322cf9d85e7471 diff --cc commands/handler.c index 60889dd5e,7316db304..f9270972b --- a/commands/handler.c +++ b/commands/handler.c @@@ -23,11 -23,13 +23,12 @@@ #include #include #include + #include static grub_err_t -grub_cmd_handler (struct grub_command *cmd, +grub_cmd_handler (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) { - char *class_name; void *curr_item = 0; grub_handler_class_t head; @@@ -90,8 -96,16 +91,8 @@@ GRUB_MOD_INIT(handler { cmd_handler = grub_register_command ("handler", grub_cmd_handler, - "handler [class [handler]]", - "List or select a handler."); + N_("[class [handler]]"), + N_("List or select a handler.")); - cmd_terminal_input = - grub_register_command ("terminal_input", grub_cmd_handler, - N_("[handler]"), - N_("List or select an input terminal.")); - cmd_terminal_output = - grub_register_command ("terminal_output", grub_cmd_handler, - N_("[handler]"), - N_("List or select an output terminal.")); } GRUB_MOD_FINI(handler) diff --cc commands/help.c index bfca5e0cc,7edc23563..9234a3697 --- a/commands/help.c +++ b/commands/help.c @@@ -21,6 -21,9 +21,10 @@@ #include #include #include + #include + #include + #include ++#include static grub_err_t grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, @@@ -37,26 -40,46 +41,51 @@@ if ((cmd->prio & GRUB_PRIO_LIST_FLAG_ACTIVE) && (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)) { - struct grub_term_output *cur; - int desclen = grub_strlen (cmd->summary); - FOR_ACTIVE_TERM_OUTPUTS(cur) ++ struct grub_term_output *term; ++ const char *summary_translated = _(cmd->summary); + char *command_help; - int stringwidth; + grub_uint32_t *unicode_command_help; + grub_uint32_t *unicode_last_position; - grub_uint32_t *unicode_last_screen_position; - const char *summary_translated = _(cmd->summary); + + command_help = grub_malloc (grub_strlen (cmd->name) + + sizeof (" ") - 1 + + grub_strlen (summary_translated)); + + grub_sprintf(command_help, "%s %s", cmd->name, summary_translated); + + grub_utf8_to_ucs4_alloc (command_help, &unicode_command_help, + &unicode_last_position); - - unicode_last_screen_position = unicode_command_help; - - stringwidth = 0; - - while (unicode_last_screen_position < unicode_last_position && - stringwidth < ((GRUB_TERM_WIDTH / 2) - 2)) - { - stringwidth += grub_getcharwidth (*unicode_last_screen_position); - unicode_last_screen_position++; - } + - grub_print_ucs4 (unicode_command_help, unicode_last_screen_position); - - if ((cnt++) % 2) - { - grub_putchar ('\n'); - } - else - { - grub_print_spaces (GRUB_TERM_WIDTH / 2 - stringwidth); - } ++ FOR_ACTIVE_TERM_OUTPUTS(term) + { - int width = grub_term_width(cur); - char description[width / 2]; - - /* Make a string with a length of GRUB_TERM_WIDTH / 2 - 1 filled - with the description followed by spaces. */ - grub_memset (description, ' ', width / 2 - 1); - description[width / 2 - 1] = '\0'; - grub_memcpy (description, cmd->summary, - (desclen < width / 2 - 1 - ? desclen : width / 2 - 1)); - grub_puts_terminal (description, cur); ++ unsigned stringwidth; ++ grub_uint32_t *unicode_last_screen_position; ++ ++ unicode_last_screen_position = unicode_command_help; ++ ++ stringwidth = 0; ++ ++ while (unicode_last_screen_position < unicode_last_position && ++ stringwidth < ((grub_term_width (term) / 2) - 2)) ++ { ++ stringwidth ++ += grub_term_getcharwidth (term, ++ *unicode_last_screen_position); ++ unicode_last_screen_position++; ++ } ++ ++ grub_print_ucs4 (unicode_command_help, ++ unicode_last_screen_position, term); ++ if (!(cnt % 2)) ++ grub_print_spaces (term, grub_term_width (term) / 2 ++ - stringwidth); + } - if ((cnt++) % 2) ++ if (cnt % 2) + grub_printf ("\n"); - else - grub_printf (" "); ++ cnt++; + + grub_free (command_help); + grub_free (unicode_command_help); } return 0; } diff --cc commands/password.c index 7bb2f0ae5,2869ffc53..04285254e --- a/commands/password.c +++ b/commands/password.c @@@ -45,18 -52,13 +46,18 @@@ grub_cmd_password (grub_command_t cmd _ { grub_err_t err; char *pass; + int copylen; if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected"); - pass = grub_strdup (args[1]); + pass = grub_zalloc (GRUB_AUTH_MAX_PASSLEN); if (!pass) return grub_errno; + copylen = grub_strlen (args[1]); + if (copylen >= GRUB_AUTH_MAX_PASSLEN) + copylen = GRUB_AUTH_MAX_PASSLEN - 1; + grub_memcpy (pass, args[1], copylen); err = grub_auth_register_authentication (args[0], check_password, pass); if (err) diff --cc commands/terminal.c index 0fff70a69,000000000..b30f43130 mode 100644,000000..100644 --- a/commands/terminal.c +++ b/commands/terminal.c @@@ -1,364 -1,0 +1,364 @@@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +struct grub_term_autoload *grub_term_input_autoload = NULL; +struct grub_term_autoload *grub_term_output_autoload = NULL; + +static grub_err_t +grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + int i; + grub_term_input_t term; + struct grub_term_autoload *aut; + + if (argc == 0) + { + grub_puts_ (N_ ("Active input terminals:")); + FOR_ACTIVE_TERM_INPUTS(term) + grub_printf ("%s ", term->name); + grub_printf ("\n"); + grub_puts_ (N_ ("Available input terminals:")); + FOR_DISABLED_TERM_INPUTS(term) + grub_printf ("%s ", term->name); + /* This is quadratic but we don't expect mode than 30 terminal + modules ever. */ + for (aut = grub_term_input_autoload; aut; aut = aut->next) + { + FOR_DISABLED_TERM_INPUTS(term) + if (grub_strcmp (term->name, aut->name) == 0) + break; + if (!term) + FOR_ACTIVE_TERM_INPUTS(term) + if (grub_strcmp (term->name, aut->name) == 0) + break; + if (!term) + grub_printf ("%s ", aut->name); + } + grub_printf ("\n"); + return GRUB_ERR_NONE; + } + i = 0; + + if (grub_strcmp (args[0], "--append") == 0 + || grub_strcmp (args[0], "--remove") == 0) + i++; + + if (i == argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified")); + + for (; i < argc; i++) + { + int again = 0; + while (1) + { + FOR_DISABLED_TERM_INPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term == 0) + FOR_ACTIVE_TERM_INPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + break; + if (again) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", + args[i]); + for (aut = grub_term_input_autoload; aut; aut = aut->next) + if (grub_strcmp (args[i], aut->name) == 0) + { + grub_dl_t mod; + mod = grub_dl_load (aut->modname); + if (mod) + grub_dl_ref (mod); + grub_errno = GRUB_ERR_NONE; + break; + } + if (!aut) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", + args[i]); + again = 1; + } + } + + if (grub_strcmp (args[0], "--append") == 0) + { + for (i = 1; i < argc; i++) + { + FOR_DISABLED_TERM_INPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)), + GRUB_AS_LIST (term)); + if (term->init) + term->init (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), + GRUB_AS_LIST (term)); + } + } + return GRUB_ERR_NONE; + } + + if (grub_strcmp (args[0], "--remove") == 0) + { + for (i = 1; i < argc; i++) + { + FOR_ACTIVE_TERM_INPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { + if (!term->next && term == grub_term_inputs) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)), + GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), + GRUB_AS_LIST (term)); + } + } + return GRUB_ERR_NONE; + } + for (i = 0; i < argc; i++) + { + FOR_DISABLED_TERM_INPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs_disabled)), + GRUB_AS_LIST (term)); + if (term->init) + term->init (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), + GRUB_AS_LIST (term)); + } + } + + FOR_ACTIVE_TERM_INPUTS(term) + { + for (i = 0; i < argc; i++) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (i == argc) + { + if (!term->next && term == grub_term_inputs) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_inputs)), + GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), + GRUB_AS_LIST (term)); + } + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)), + int argc, char **args) +{ + int i; + grub_term_output_t term; + struct grub_term_autoload *aut; + + if (argc == 0) + { + grub_puts_ (N_ ("Active output terminals:")); + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_printf ("%s ", term->name); + grub_printf ("\n"); + grub_puts_ (N_ ("Available output terminals:")); + FOR_DISABLED_TERM_OUTPUTS(term) + grub_printf ("%s ", term->name); + /* This is quadratic but we don't expect mode than 30 terminal + modules ever. */ + for (aut = grub_term_output_autoload; aut; aut = aut->next) + { + FOR_DISABLED_TERM_OUTPUTS(term) + if (grub_strcmp (term->name, aut->name) == 0) + break; + if (!term) + FOR_ACTIVE_TERM_OUTPUTS(term) + if (grub_strcmp (term->name, aut->name) == 0) + break; + if (!term) + grub_printf ("%s ", aut->name); + } + grub_printf ("\n"); + return GRUB_ERR_NONE; + } + i = 0; + + if (grub_strcmp (args[0], "--append") == 0 + || grub_strcmp (args[0], "--remove") == 0) + i++; + + if (i == argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no terminal specified")); + + for (; i < argc; i++) + { + int again = 0; + while (1) + { + FOR_DISABLED_TERM_OUTPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term == 0) + FOR_ACTIVE_TERM_OUTPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + break; + if (again) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", + args[i]); + for (aut = grub_term_output_autoload; aut; aut = aut->next) + if (grub_strcmp (args[i], aut->name) == 0) + { + grub_dl_t mod; + mod = grub_dl_load (aut->modname); + if (mod) + grub_dl_ref (mod); + grub_errno = GRUB_ERR_NONE; + break; + } + if (!aut) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminal '%s'\n", + args[i]); + again = 1; + } + } + + if (grub_strcmp (args[0], "--append") == 0) + { + for (i = 1; i < argc; i++) + { + FOR_DISABLED_TERM_OUTPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)), + GRUB_AS_LIST (term)); + if (term->init) + term->init (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); + } + } + return GRUB_ERR_NONE; + } + + if (grub_strcmp (args[0], "--remove") == 0) + { + for (i = 1; i < argc; i++) + { + FOR_ACTIVE_TERM_OUTPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { + if (!term->next && term == grub_term_outputs) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)), + GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), + GRUB_AS_LIST (term)); + } + } + return GRUB_ERR_NONE; + } + + for (i = 0; i < argc; i++) + { + FOR_DISABLED_TERM_OUTPUTS(term) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (term) + { + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)), + GRUB_AS_LIST (term)); + if (term->init) + term->init (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); + } + } + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + for (i = 0; i < argc; i++) + if (grub_strcmp (args[i], term->name) == 0) + break; + if (i == argc) + { + if (!term->next && term == grub_term_outputs) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "can't remove the last terminal"); + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs)), + GRUB_AS_LIST (term)); + if (term->fini) + term->fini (); + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), + GRUB_AS_LIST (term)); + } + } + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd_terminal_input, cmd_terminal_output; + +GRUB_MOD_INIT(terminal) +{ + cmd_terminal_input = + grub_register_command ("terminal_input", grub_cmd_terminal_input, - "terminal_input [--append|--remove] " ++ "[--append|--remove] " + "[TERMINAL1] [TERMINAL2] ...", + "List or select an input terminal."); + cmd_terminal_output = + grub_register_command ("terminal_output", grub_cmd_terminal_output, - "terminal_output [--append|--remove] " ++ "[--append|--remove] " + "[TERMINAL1] [TERMINAL2] ...", + "List or select an output terminal."); +} + +GRUB_MOD_FINI(terminal) +{ + grub_unregister_command (cmd_terminal_input); + grub_unregister_command (cmd_terminal_output); +} diff --cc commands/xnu_uuid.c index c43c4bf37,b94dc0dc7..b01352269 --- a/commands/xnu_uuid.c +++ b/commands/xnu_uuid.c @@@ -31,8 -31,14 +31,9 @@@ #include #include #include +#include + #include -struct tohash -{ - grub_uint8_t prefix[16]; - grub_uint64_t serial; -} __attribute__ ((packed)); - /* This prefix is used by xnu and boot-132 to hash together with volume serial. */ static grub_uint8_t hash_prefix[16] diff --cc include/grub/term.h index 922ccb2d2,ec158353d..1c57a4ede --- a/include/grub/term.h +++ b/include/grub/term.h @@@ -243,168 -250,63 +243,176 @@@ grub_term_unregister_input (grub_term_i static inline void grub_term_unregister_output (grub_term_output_t term) { - grub_handler_unregister (&grub_term_output_class, GRUB_AS_HANDLER (term)); + grub_list_remove (GRUB_AS_LIST_P (&grub_term_outputs), GRUB_AS_LIST (term)); + grub_list_remove (GRUB_AS_LIST_P (&(grub_term_outputs_disabled)), + GRUB_AS_LIST (term)); } -static inline grub_err_t -grub_term_set_current_input (grub_term_input_t term) +#define FOR_ACTIVE_TERM_INPUTS(var) for (var = grub_term_inputs; var; var = var->next) +#define FOR_DISABLED_TERM_INPUTS(var) for (var = grub_term_inputs_disabled; var; var = var->next) +#define FOR_ACTIVE_TERM_OUTPUTS(var) for (var = grub_term_outputs; var; var = var->next) +#define FOR_DISABLED_TERM_OUTPUTS(var) for (var = grub_term_outputs_disabled; var; var = var->next) + +void EXPORT_FUNC(grub_putchar) (int c); +void EXPORT_FUNC(grub_putcode) (grub_uint32_t code, + struct grub_term_output *term); +int EXPORT_FUNC(grub_getkey) (void); +int EXPORT_FUNC(grub_checkkey) (void); +int EXPORT_FUNC(grub_getkeystatus) (void); +void EXPORT_FUNC(grub_cls) (void); +void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state); +void EXPORT_FUNC(grub_refresh) (void); +void grub_puts_terminal (const char *str, struct grub_term_output *term); +grub_uint16_t *grub_term_save_pos (void); +void grub_term_restore_pos (grub_uint16_t *pos); + +static inline unsigned grub_term_width (struct grub_term_output *term) { - return grub_handler_set_current (&grub_term_input_class, - GRUB_AS_HANDLER (term)); + return ((term->getwh()&0xFF00)>>8); } -static inline grub_err_t -grub_term_set_current_output (grub_term_output_t term) +static inline unsigned grub_term_height (struct grub_term_output *term) { - return grub_handler_set_current (&grub_term_output_class, - GRUB_AS_HANDLER (term)); + return (term->getwh()&0xFF); } -static inline grub_term_input_t -grub_term_get_current_input (void) +/* The width of the border. */ +static inline unsigned +grub_term_border_width (struct grub_term_output *term) { - return (grub_term_input_t) grub_term_input_class.cur_handler; + return grub_term_width (term) - GRUB_TERM_MARGIN * 3 - GRUB_TERM_SCROLL_WIDTH; } -static inline grub_term_output_t -grub_term_get_current_output (void) +/* 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_output_t) grub_term_output_class.cur_handler; + return grub_term_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1; } -void EXPORT_FUNC(grub_putchar) (int c); -void EXPORT_FUNC(grub_putcode) (grub_uint32_t code); -grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code); -int EXPORT_FUNC(grub_getkey) (void); -int EXPORT_FUNC(grub_checkkey) (void); -int EXPORT_FUNC(grub_getkeystatus) (void); -grub_uint16_t EXPORT_FUNC(grub_getwh) (void); -grub_uint16_t EXPORT_FUNC(grub_getxy) (void); -void EXPORT_FUNC(grub_gotoxy) (grub_uint8_t x, grub_uint8_t y); -void EXPORT_FUNC(grub_cls) (void); -void EXPORT_FUNC(grub_setcolorstate) (grub_term_color_state state); -void EXPORT_FUNC(grub_setcolor) (grub_uint8_t normal_color, - grub_uint8_t highlight_color); -void EXPORT_FUNC(grub_getcolor) (grub_uint8_t *normal_color, - grub_uint8_t *highlight_color); -int EXPORT_FUNC(grub_setcursor) (int on); -int EXPORT_FUNC(grub_getcursor) (void); -void EXPORT_FUNC(grub_refresh) (void); -void EXPORT_FUNC(grub_set_more) (int onoff); +/* 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 void +grub_term_cls (struct grub_term_output *term) +{ + if (term->cls) + (term->cls) (); + else + { + grub_putcode ('\n', term); + grub_term_refresh (term); + } +} + +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) +{ + if (term->getcolor) + term->getcolor (normal_color, highlight_color); + else + { + *normal_color = 0x07; + *highlight_color = 0x07; + } +} + +extern void (*EXPORT_VAR (grub_newline_hook)) (void); + +struct grub_term_autoload +{ + struct grub_term_autoload *next; + char *name; + char *modname; +}; + +extern struct grub_term_autoload *grub_term_input_autoload; +extern struct grub_term_autoload *grub_term_output_autoload; + static inline void -grub_print_spaces (int number_spaces) ++grub_print_spaces (struct grub_term_output *term, int number_spaces) + { + while (--number_spaces >= 0) - grub_putchar (' '); ++ grub_putcode (' ', term); + } + + /* For convenience. */ #define GRUB_TERM_ASCII_CHAR(c) ((c) & 0xff) diff --cc normal/cmdline.c index f2c2edf9b,19b83951a..656b14c6a --- a/normal/cmdline.c +++ b/normal/cmdline.c @@@ -318,73 -254,36 +318,73 @@@ grub_cmdline_get (const char *prompt grub_size_t saved_lpos = lpos; lpos = llen - len; - cl_set_pos (); - cl_print (lpos, ' '); + cl_set_pos_all (); + cl_print_all (lpos, ' '); lpos = saved_lpos; - cl_set_pos (); + cl_set_pos_all (); - grub_memmove (buf + lpos, buf + lpos + len, llen - lpos + 1); + grub_memmove (buf + lpos, buf + lpos + len, + sizeof (grub_uint32_t) * (llen - lpos + 1)); llen -= len; - cl_print (lpos, echo_char); - cl_set_pos (); + cl_print_all (lpos, 0); + cl_set_pos_all (); } - - grub_refresh (); } + void init_clterm (struct cmdline_term *cl_term_cur) + { + cl_term_cur->xpos = plen; + cl_term_cur->ypos = (grub_term_getxy (cl_term_cur->term) & 0xFF); + cl_term_cur->ystart = cl_term_cur->ypos; + cl_term_cur->width = grub_term_width (cl_term_cur->term); + cl_term_cur->height = grub_term_height (cl_term_cur->term); + } + + void init_clterm_all (void) + { + unsigned i; + for (i = 0; i < nterms; 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) + sizeof (" ") - 1; lpos = llen = 0; buf[0] = '\0'; - if ((grub_getxy () >> 8) != 0) - grub_putchar ('\n'); + { + grub_term_output_t term; + FOR_ACTIVE_TERM_OUTPUTS(term) + if ((grub_term_getxy (term) >> 8) != 0) + grub_putcode ('\n', term); + } - grub_printf ("%s", prompt_translated); + grub_printf ("%s ", prompt_translated); - xpos = plen; - ystart = ypos = (grub_getxy () & 0xFF); - - cl_insert (cmdline); + { + struct cmdline_term *cl_term_cur; + struct grub_term_output *cur; + nterms = 0; + FOR_ACTIVE_TERM_OUTPUTS(cur) + nterms++; + + cl_terms = grub_malloc (sizeof (cl_terms[0]) * nterms); + if (!cl_terms) + return 0; + cl_term_cur = cl_terms; + FOR_ACTIVE_TERM_OUTPUTS(cur) + { + cl_term_cur->term = cur; + init_clterm (cl_term_cur); + cl_term_cur++; + } + } - if (history && hist_used == 0) - grub_history_add (buf); + if (hist_used == 0) + grub_history_add (buf, llen); while ((key = GRUB_TERM_ASCII_CHAR (grub_getkey ())) != '\n' && key != '\r') { diff --cc normal/main.c index 6d7a558f3,23de7e238..cdb816bfc --- a/normal/main.c +++ b/normal/main.c @@@ -549,17 -540,15 +549,17 @@@ grub_normal_reader_init (int nested return 0; } -static char cmdline[GRUB_MAX_CMDLINE]; static grub_err_t -grub_normal_read_line (char **line, int cont) +grub_normal_read_line_real (char **line, int cont, int nested) { grub_parser_t parser = grub_parser_get_current (); - char prompt[sizeof("> ") + grub_strlen (parser->name)]; + char prompt[sizeof(">") + grub_strlen (parser->name)]; - grub_sprintf (prompt, "%s>", parser->name); + if (cont) - grub_sprintf (prompt, "> "); ++ grub_sprintf (prompt, ">"); + else - grub_sprintf (prompt, "%s> ", parser->name); ++ grub_sprintf (prompt, "%s>", parser->name); while (1) { @@@ -639,10 -595,10 +639,10 @@@ GRUB_MOD_INIT(normal grub_register_variable_hook ("pager", 0, grub_env_write_pager); /* Register a command "normal" for the rescue mode. */ - grub_register_command_prio ("normal", grub_cmd_normal, - 0, "Enter normal mode.", 0); + grub_register_command ("normal", grub_cmd_normal, - 0, "Enter normal mode"); ++ 0, "Enter normal mode."); + grub_register_command ("normal_exit", grub_cmd_normal_exit, - 0, "Exit from normal mode"); ++ 0, "Exit from normal mode."); /* Reload terminal colors when these variables are written to. */ grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); diff --cc normal/menu_text.c index 91000c1d4,8ab67a35c..cab1d22f8 --- a/normal/menu_text.c +++ b/normal/menu_text.c @@@ -106,10 -128,9 +106,10 @@@ grub_print_message_indented (const cha next_new_line = (grub_uint32_t *) last_position; - while (grub_getstringwidth (current_position, next_new_line) > line_len + while (grub_getstringwidth (current_position, next_new_line,term) + > line_len - || (*next_new_line != ' ' && next_new_line > current_position && - next_new_line != last_position)) + || (next_new_line != last_position && *next_new_line != ' ' + && next_new_line > current_position)) { next_new_line--; } @@@ -356,132 -382,352 +356,132 @@@ grub_menu_init_page (int nested, int ed } static void -print_timeout (int timeout, int offset) +menu_text_print_timeout (int timeout, void *dataptr) { const char *msg = - _("The highlighted entry will be booted automatically in %ds."); + _("The highlighted entry will be executed 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 = - grub_malloc (sizeof (char) * grub_strlen (msg) + 5); + msg_translated = 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_print_message_indented (msg_translated, 3, 0); + grub_print_message_indented (msg_translated, 3, 0, data->term); - int posx; - posx = grub_getxy() >> 8; - grub_print_spaces (GRUB_TERM_WIDTH - posx - 1); + posx = grub_term_getxy (data->term) >> 8; + print_spaces (grub_term_width (data->term) - posx - 1, data->term); - grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); - grub_refresh (); + grub_term_gotoxy (data->term, + 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 - 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) +static void +menu_text_set_chosen_entry (int entry, void *dataptr) { - int first, offset; - grub_uint64_t saved_time; - int default_entry; - int timeout; - - first = 0; + struct menu_viewer_data *data = dataptr; + int oldoffset = data->offset; + int complete_redraw = 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) + data->offset = entry - data->first; + if (data->offset > grub_term_num_entries (data->term) - 1) { - *auto_boot = 1; - return default_entry; + data->first = entry - (grub_term_num_entries (data->term) - 1); + data->offset = grub_term_num_entries (data->term) - 1; + complete_redraw = 1; } - - offset = default_entry; - if (offset > GRUB_TERM_NUM_ENTRIES - 1) + if (data->offset < 0) { - first = offset - (GRUB_TERM_NUM_ENTRIES - 1); - offset = GRUB_TERM_NUM_ENTRIES - 1; + data->offset = 0; + 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) + if (complete_redraw) + print_entries (data->menu, data->first, data->offset, data->term); + else { - 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); - grub_print_spaces (GRUB_TERM_WIDTH - 1); - - grub_env_unset ("timeout"); - grub_env_unset ("fallback"); - grub_gotoxy (GRUB_TERM_CURSOR_X, GRUB_TERM_FIRST_ENTRY_Y + offset); - } - - switch (c) - { - case GRUB_TERM_HOME: - first = 0; - offset = 0; - print_entries (menu, first, offset); - break; - - case GRUB_TERM_END: - offset = menu->size - 1; - if (offset > GRUB_TERM_NUM_ENTRIES - 1) - { - first = offset - (GRUB_TERM_NUM_ENTRIES - 1); - offset = GRUB_TERM_NUM_ENTRIES - 1; - } - print_entries (menu, first, offset); - break; - - case GRUB_TERM_UP: - case '^': - if (offset > 0) - { - print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0, - grub_menu_get_entry (menu, first + offset)); - offset--; - print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1, - grub_menu_get_entry (menu, first + offset)); - } - else if (first > 0) - { - first--; - print_entries (menu, first, offset); - } - break; - - case GRUB_TERM_DOWN: - case 'v': - if (menu->size > first + offset + 1) - { - if (offset < GRUB_TERM_NUM_ENTRIES - 1) - { - print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 0, - grub_menu_get_entry (menu, first + offset)); - offset++; - print_entry (GRUB_TERM_FIRST_ENTRY_Y + offset, 1, - grub_menu_get_entry (menu, first + offset)); - } - else - { - first++; - print_entries (menu, first, offset); - } - } - break; - - case GRUB_TERM_PPAGE: - if (first == 0) - { - offset = 0; - } - else - { - first -= GRUB_TERM_NUM_ENTRIES; - - if (first < 0) - { - offset += first; - first = 0; - } - } - print_entries (menu, first, offset); - break; - - case GRUB_TERM_NPAGE: - if (offset == 0) - { - offset += GRUB_TERM_NUM_ENTRIES - 1; - if (first + offset >= menu->size) - { - offset = menu->size - first - 1; - } - } - else - { - first += GRUB_TERM_NUM_ENTRIES; - - if (first + offset >= menu->size) - { - first -= GRUB_TERM_NUM_ENTRIES; - offset += GRUB_TERM_NUM_ENTRIES; - - if (offset > menu->size - 1 || - offset > GRUB_TERM_NUM_ENTRIES - 1) - { - offset = menu->size - first - 1; - } - if (offset > GRUB_TERM_NUM_ENTRIES) - { - first += offset - GRUB_TERM_NUM_ENTRIES + 1; - offset = GRUB_TERM_NUM_ENTRIES - 1; - } - } - } - print_entries (menu, first, offset); - break; - - case '\n': - case '\r': - case 6: - grub_setcursor (1); - *auto_boot = 0; - return first + offset; - - case '\e': - if (nested) - { - grub_setcursor (1); - return -1; - } - break; - - case 'c': - grub_cmdline_run (1); - goto refresh; - - case 'e': - { - grub_menu_entry_t e = grub_menu_get_entry (menu, first + offset); - if (e) - grub_menu_entry_run (e); - } - goto refresh; - - default: - break; - } - - grub_refresh (); - } + print_entry (GRUB_TERM_FIRST_ENTRY_Y + oldoffset, 0, + grub_menu_get_entry (data->menu, data->first + oldoffset), + data->term); + print_entry (GRUB_TERM_FIRST_ENTRY_Y + data->offset, 1, + grub_menu_get_entry (data->menu, data->first + data->offset), + data->term); } - - /* Never reach here. */ - return -1; + grub_term_refresh (data->term); } -/* Callback invoked immediately before a menu entry is executed. */ static void -notify_booting (grub_menu_entry_t entry, - void *userdata __attribute__((unused))) +menu_text_fini (void *dataptr) { - grub_printf (" "); - grub_printf_ (N_("Booting \'%s\'"), entry->title); - grub_printf ("\n\n"); -} + struct menu_viewer_data *data = dataptr; + + grub_term_setcursor (data->term, 1); + grub_term_cls (data->term); -/* 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))) +menu_text_clear_timeout (void *dataptr) { - 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 (); + struct menu_viewer_data *data = dataptr; + + grub_term_gotoxy (data->term, 0, grub_term_height (data->term) - 3); + print_spaces (grub_term_width (data->term) - 1, data->term); + grub_term_gotoxy (data->term, grub_term_cursor_x (data->term), + GRUB_TERM_FIRST_ENTRY_Y + data->offset); + grub_term_refresh (data->term); } -/* Callbacks used by the text menu to provide user feedback when menu entries - are executed. */ -static struct grub_menu_execute_callback execution_callback = +grub_err_t +grub_menu_try_text (struct grub_term_output *term, + int entry, grub_menu_t menu, int nested) { - .notify_booting = notify_booting, - .notify_fallback = notify_fallback, - .notify_failure = notify_execution_failure -}; + struct menu_viewer_data *data; + struct grub_menu_viewer *instance; -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; + instance = grub_zalloc (sizeof (*instance)); + if (!instance) + return grub_errno; - boot_entry = run_menu (menu, nested, &auto_boot); - if (boot_entry < 0) - break; + data = grub_zalloc (sizeof (*data)); + if (!data) + { + grub_free (instance); + return grub_errno; + } - e = grub_menu_get_entry (menu, boot_entry); - if (! e) - continue; /* Menu is empty. */ + 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; - grub_cls (); - grub_setcursor (1); + data->menu = menu; - if (auto_boot) - { - grub_menu_execute_with_fallback (menu, e, &execution_callback, 0); - } - else - { - grub_errno = GRUB_ERR_NONE; - grub_menu_execute_entry (e); - if (grub_errno != GRUB_ERR_NONE) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; - grub_wait_after_message (); - } - } + data->offset = entry; + data->first = 0; + if (data->offset > grub_term_num_entries (data->term) - 1) + { + data->first = data->offset - (grub_term_num_entries (data->term) - 1); + data->offset = grub_term_num_entries (data->term) - 1; } + grub_term_setcursor (data->term, 0); + grub_menu_init_page (nested, 0, data->term); + print_entries (menu, data->first, data->offset, data->term); + grub_term_refresh (data->term); + grub_menu_register_viewer (instance); + return GRUB_ERR_NONE; } - -struct grub_menu_viewer grub_normal_text_menu_viewer = -{ - .name = "text", - .show_menu = show_text_menu -}; diff --cc normal/menu_viewer.c index b600e7500,f870ccd53..b52442f40 --- a/normal/menu_viewer.c +++ b/normal/menu_viewer.c @@@ -23,4 -23,59 +23,3 @@@ #include #include -/* 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; -} -- diff --cc term/gfxterm.c index 2a22b9168,fa19a5d85..2a7886aa0 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@@ -953,14 -953,10 +953,14 @@@ static grub_command_t cmd GRUB_MOD_INIT(term_gfxterm) { +#ifdef GRUB_MACHINE_MIPS_YEELOONG + grub_term_register_output_active ("gfxterm", &grub_video_term); +#else grub_term_register_output ("gfxterm", &grub_video_term); +#endif cmd = grub_register_command ("background_image", grub_gfxterm_background_image_cmd, - 0, "Load background image for active terminal"); + 0, "Load background image for active terminal."); } GRUB_MOD_FINI(term_gfxterm)