From: Hans de Goede <hdego...@redhat.com> If we're running with a hidden menu we may never need text mode, so do not change the video-mode to text until we actually need it.
Signed-off-by: Hans de Goede <hdego...@redhat.com> Signed-off-by: Javier Martinez Canillas <javi...@redhat.com> --- grub-core/term/efi/console.c | 74 +++++++++++++++++++++++------------- include/grub/term.h | 4 +- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c index 59d9604472a..16ccd350ee0 100644 --- a/grub-core/term/efi/console.c +++ b/grub-core/term/efi/console.c @@ -24,6 +24,16 @@ #include <grub/efi/api.h> #include <grub/efi/console.h> +typedef enum { + GRUB_TEXT_MODE_UNDEFINED = -1, + GRUB_TEXT_MODE_UNAVAILABLE = 0, + GRUB_TEXT_MODE_AVAILABLE +} +grub_text_mode; + +static grub_text_mode text_mode = GRUB_TEXT_MODE_UNDEFINED; +static grub_term_color_state text_colorstate = GRUB_TERM_COLOR_UNDEFINED; + static grub_uint32_t map_char (grub_uint32_t c) { @@ -106,15 +116,39 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), efi_call_2 (o->enable_cursor, o, on); } +static grub_err_t +grub_prepare_for_text_output(struct grub_term_output *term) +{ + if (grub_efi_is_finished) + return GRUB_ERR_BAD_DEVICE; + + if (text_mode != GRUB_TEXT_MODE_UNDEFINED) + return text_mode ? 0 : GRUB_ERR_BAD_DEVICE; + + if (! grub_efi_set_text_mode (1)) + { + /* This really should never happen */ + grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode"); + text_mode = GRUB_TEXT_MODE_UNAVAILABLE; + return GRUB_ERR_BAD_DEVICE; + } + + grub_console_setcursor (term, 1); + if (text_colorstate != GRUB_TERM_COLOR_UNDEFINED) + grub_console_setcolorstate (term, text_colorstate); + text_mode = GRUB_TEXT_MODE_AVAILABLE; + return 0; +} + static void -grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)), +grub_console_putchar (struct grub_term_output *term, const struct grub_unicode_glyph *c) { grub_efi_char16_t str[2 + 30]; grub_efi_simple_text_output_interface_t *o; unsigned i, j; - if (grub_efi_is_finished) + if (grub_prepare_for_text_output (term)) return; o = grub_efi_system_table->con_out; @@ -264,14 +298,15 @@ grub_console_getkey (struct grub_term_input *term) } static struct grub_term_coordinate -grub_console_getwh (struct grub_term_output *term __attribute__ ((unused))) +grub_console_getwh (struct grub_term_output *term) { grub_efi_simple_text_output_interface_t *o; grub_efi_uintn_t columns, rows; o = grub_efi_system_table->con_out; - if (grub_efi_is_finished || efi_call_4 (o->query_mode, o, o->mode->mode, - &columns, &rows) != GRUB_EFI_SUCCESS) + if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE || + efi_call_4 (o->query_mode, o, o->mode->mode, + &columns, &rows) != GRUB_EFI_SUCCESS) { /* Why does this fail? */ columns = 80; @@ -286,7 +321,7 @@ grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) { grub_efi_simple_text_output_interface_t *o; - if (grub_efi_is_finished) + if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) return (struct grub_term_coordinate) { 0, 0 }; o = grub_efi_system_table->con_out; @@ -294,12 +329,12 @@ grub_console_getxy (struct grub_term_output *term __attribute__ ((unused))) } static void -grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)), +grub_console_gotoxy (struct grub_term_output *term, struct grub_term_coordinate pos) { grub_efi_simple_text_output_interface_t *o; - if (grub_efi_is_finished) + if (grub_prepare_for_text_output (term)) return; o = grub_efi_system_table->con_out; @@ -312,7 +347,7 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused))) grub_efi_simple_text_output_interface_t *o; grub_efi_int32_t orig_attr; - if (grub_efi_is_finished) + if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) return; o = grub_efi_system_table->con_out; @@ -322,19 +357,15 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused))) efi_call_2 (o->set_attributes, o, orig_attr); } -static grub_err_t -grub_efi_console_output_init (struct grub_term_output *term) -{ - grub_efi_set_text_mode (1); - grub_console_setcursor (term, 1); - return 0; -} - static grub_err_t grub_efi_console_output_fini (struct grub_term_output *term) { + if (text_mode != GRUB_TEXT_MODE_AVAILABLE) + return 0; + grub_console_setcursor (term, 0); grub_efi_set_text_mode (0); + text_mode = GRUB_TEXT_MODE_UNDEFINED; return 0; } @@ -348,7 +379,6 @@ static struct grub_term_input grub_console_term_input = static struct grub_term_output grub_console_term_output = { .name = "console", - .init = grub_efi_console_output_init, .fini = grub_efi_console_output_fini, .putchar = grub_console_putchar, .getwh = grub_console_getwh, @@ -364,14 +394,6 @@ static struct grub_term_output grub_console_term_output = void grub_console_init (void) { - /* FIXME: it is necessary to consider the case where no console control - is present but the default is already in text mode. */ - if (! grub_efi_set_text_mode (1)) - { - grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode"); - return; - } - grub_term_register_output ("console", &grub_console_term_output); grub_term_register_input ("console", &grub_console_term_input); } diff --git a/include/grub/term.h b/include/grub/term.h index 8117e2a24da..486b30e7125 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -75,9 +75,11 @@ /* These are used to represent the various color states we use. */ typedef enum { + /* Used for uninitialized grub_term_color_state variables */ + GRUB_TERM_COLOR_UNDEFINED = -1, /* The color used to display all text that does not use the user defined colors below. */ - GRUB_TERM_COLOR_STANDARD, + GRUB_TERM_COLOR_STANDARD = 0, /* The user defined colors for normal text. */ GRUB_TERM_COLOR_NORMAL, /* The user defined colors for highlighted text. */ -- 2.24.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel