efi/console: Do not set text-mode until we actually need it
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. This allows to boot a machine without unnecessary graphical transitions and provide a seamless boot experience to users. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
parent
ea138d11be
commit
2d7c3abd87
2 changed files with 51 additions and 27 deletions
|
@ -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 ? GRUB_ERR_NONE : 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 GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
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) != GRUB_ERR_NONE)
|
||||
return;
|
||||
|
||||
o = grub_efi_system_table->con_out;
|
||||
|
@ -327,14 +361,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;
|
||||
|
@ -349,7 +384,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;
|
||||
|
@ -357,12 +392,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) != GRUB_ERR_NONE)
|
||||
return;
|
||||
|
||||
o = grub_efi_system_table->con_out;
|
||||
|
@ -375,7 +410,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;
|
||||
|
@ -385,19 +420,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;
|
||||
}
|
||||
|
||||
|
@ -412,7 +443,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,
|
||||
|
@ -428,14 +458,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);
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in a new issue