|
|
d9d99f |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
d9d99f |
From: Hans de Goede <hdegoede@redhat.com>
|
|
|
d9d99f |
Date: Tue, 6 Mar 2018 17:11:15 +0100
|
|
|
d9d99f |
Subject: [PATCH] EFI: console: Do not set text-mode until we actually need it
|
|
|
d9d99f |
|
|
|
d9d99f |
If we're running with a hidden menu we may never need text mode, so do not
|
|
|
d9d99f |
change the video-mode to text until we actually need it.
|
|
|
d9d99f |
|
|
|
d9d99f |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
|
d9d99f |
---
|
|
|
d9d99f |
grub-core/term/efi/console.c | 65 ++++++++++++++++++++++++++++++--------------
|
|
|
d9d99f |
1 file changed, 44 insertions(+), 21 deletions(-)
|
|
|
d9d99f |
|
|
|
d9d99f |
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
|
|
|
d9d99f |
index 4840cc59d3f..051633d71e9 100644
|
|
|
d9d99f |
--- a/grub-core/term/efi/console.c
|
|
|
d9d99f |
+++ b/grub-core/term/efi/console.c
|
|
|
d9d99f |
@@ -24,6 +24,11 @@
|
|
|
d9d99f |
#include <grub/efi/api.h>
|
|
|
d9d99f |
#include <grub/efi/console.h>
|
|
|
d9d99f |
|
|
|
d9d99f |
+static grub_err_t grub_prepare_for_text_output(struct grub_term_output *term);
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+static int text_mode_available = -1;
|
|
|
d9d99f |
+static int text_colorstate = -1;
|
|
|
d9d99f |
+
|
|
|
d9d99f |
static grub_uint32_t
|
|
|
d9d99f |
map_char (grub_uint32_t c)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
@@ -66,14 +71,14 @@ map_char (grub_uint32_t c)
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
static void
|
|
|
d9d99f |
-grub_console_putchar (struct grub_term_output *term __attribute__ ((unused)),
|
|
|
d9d99f |
+grub_console_putchar (struct grub_term_output *term,
|
|
|
d9d99f |
const struct grub_unicode_glyph *c)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
grub_efi_char16_t str[2 + 30];
|
|
|
d9d99f |
grub_efi_simple_text_output_interface_t *o;
|
|
|
d9d99f |
unsigned i, j;
|
|
|
d9d99f |
|
|
|
d9d99f |
- if (grub_efi_is_finished)
|
|
|
d9d99f |
+ if (grub_prepare_for_text_output (term))
|
|
|
d9d99f |
return;
|
|
|
d9d99f |
|
|
|
d9d99f |
o = grub_efi_system_table->con_out;
|
|
|
d9d99f |
@@ -223,14 +228,15 @@ grub_console_getkey (struct grub_term_input *term)
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
static struct grub_term_coordinate
|
|
|
d9d99f |
-grub_console_getwh (struct grub_term_output *term __attribute__ ((unused)))
|
|
|
d9d99f |
+grub_console_getwh (struct grub_term_output *term)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
grub_efi_simple_text_output_interface_t *o;
|
|
|
d9d99f |
grub_efi_uintn_t columns, rows;
|
|
|
d9d99f |
|
|
|
d9d99f |
o = grub_efi_system_table->con_out;
|
|
|
d9d99f |
- if (grub_efi_is_finished || efi_call_4 (o->query_mode, o, o->mode->mode,
|
|
|
d9d99f |
- &columns, &rows) != GRUB_EFI_SUCCESS)
|
|
|
d9d99f |
+ if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE ||
|
|
|
d9d99f |
+ efi_call_4 (o->query_mode, o, o->mode->mode,
|
|
|
d9d99f |
+ &columns, &rows) != GRUB_EFI_SUCCESS)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
/* Why does this fail? */
|
|
|
d9d99f |
columns = 80;
|
|
|
d9d99f |
@@ -245,7 +251,7 @@ grub_console_getxy (struct grub_term_output *term __attribute__ ((unused)))
|
|
|
d9d99f |
{
|
|
|
d9d99f |
grub_efi_simple_text_output_interface_t *o;
|
|
|
d9d99f |
|
|
|
d9d99f |
- if (grub_efi_is_finished)
|
|
|
d9d99f |
+ if (grub_efi_is_finished || text_mode_available != 1)
|
|
|
d9d99f |
return (struct grub_term_coordinate) { 0, 0 };
|
|
|
d9d99f |
|
|
|
d9d99f |
o = grub_efi_system_table->con_out;
|
|
|
d9d99f |
@@ -253,12 +259,12 @@ grub_console_getxy (struct grub_term_output *term __attribute__ ((unused)))
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
static void
|
|
|
d9d99f |
-grub_console_gotoxy (struct grub_term_output *term __attribute__ ((unused)),
|
|
|
d9d99f |
+grub_console_gotoxy (struct grub_term_output *term,
|
|
|
d9d99f |
struct grub_term_coordinate pos)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
grub_efi_simple_text_output_interface_t *o;
|
|
|
d9d99f |
|
|
|
d9d99f |
- if (grub_efi_is_finished)
|
|
|
d9d99f |
+ if (grub_prepare_for_text_output (term))
|
|
|
d9d99f |
return;
|
|
|
d9d99f |
|
|
|
d9d99f |
o = grub_efi_system_table->con_out;
|
|
|
d9d99f |
@@ -271,7 +277,7 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
|
|
|
d9d99f |
grub_efi_simple_text_output_interface_t *o;
|
|
|
d9d99f |
grub_efi_int32_t orig_attr;
|
|
|
d9d99f |
|
|
|
d9d99f |
- if (grub_efi_is_finished)
|
|
|
d9d99f |
+ if (grub_efi_is_finished || text_mode_available != 1)
|
|
|
d9d99f |
return;
|
|
|
d9d99f |
|
|
|
d9d99f |
o = grub_efi_system_table->con_out;
|
|
|
d9d99f |
@@ -291,6 +297,12 @@ grub_console_setcolorstate (struct grub_term_output *term
|
|
|
d9d99f |
if (grub_efi_is_finished)
|
|
|
d9d99f |
return;
|
|
|
d9d99f |
|
|
|
d9d99f |
+ if (text_mode_available != 1) {
|
|
|
d9d99f |
+ /* Avoid "color_normal" environment writes causing a switch to textmode */
|
|
|
d9d99f |
+ text_colorstate = state;
|
|
|
d9d99f |
+ return;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+
|
|
|
d9d99f |
o = grub_efi_system_table->con_out;
|
|
|
d9d99f |
|
|
|
d9d99f |
switch (state) {
|
|
|
d9d99f |
@@ -315,7 +327,7 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
|
|
|
d9d99f |
{
|
|
|
d9d99f |
grub_efi_simple_text_output_interface_t *o;
|
|
|
d9d99f |
|
|
|
d9d99f |
- if (grub_efi_is_finished)
|
|
|
d9d99f |
+ if (grub_efi_is_finished || text_mode_available != 1)
|
|
|
d9d99f |
return;
|
|
|
d9d99f |
|
|
|
d9d99f |
o = grub_efi_system_table->con_out;
|
|
|
d9d99f |
@@ -323,18 +335,38 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
static grub_err_t
|
|
|
d9d99f |
-grub_efi_console_output_init (struct grub_term_output *term)
|
|
|
d9d99f |
+grub_prepare_for_text_output(struct grub_term_output *term)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
- grub_efi_set_text_mode (1);
|
|
|
d9d99f |
+ if (grub_efi_is_finished)
|
|
|
d9d99f |
+ return GRUB_ERR_BAD_DEVICE;
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ if (text_mode_available != -1)
|
|
|
d9d99f |
+ return text_mode_available ? 0 : GRUB_ERR_BAD_DEVICE;
|
|
|
d9d99f |
+
|
|
|
d9d99f |
+ if (! grub_efi_set_text_mode (1))
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ /* This really should never happen */
|
|
|
d9d99f |
+ grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode");
|
|
|
d9d99f |
+ text_mode_available = 0;
|
|
|
d9d99f |
+ return GRUB_ERR_BAD_DEVICE;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+
|
|
|
d9d99f |
grub_console_setcursor (term, 1);
|
|
|
d9d99f |
+ if (text_colorstate != -1)
|
|
|
d9d99f |
+ grub_console_setcolorstate (term, text_colorstate);
|
|
|
d9d99f |
+ text_mode_available = 1;
|
|
|
d9d99f |
return 0;
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
static grub_err_t
|
|
|
d9d99f |
grub_efi_console_output_fini (struct grub_term_output *term)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
+ if (text_mode_available != 1)
|
|
|
d9d99f |
+ return 0;
|
|
|
d9d99f |
+
|
|
|
d9d99f |
grub_console_setcursor (term, 0);
|
|
|
d9d99f |
grub_efi_set_text_mode (0);
|
|
|
d9d99f |
+ text_mode_available = -1;
|
|
|
d9d99f |
return 0;
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
@@ -348,7 +380,6 @@ static struct grub_term_input grub_console_term_input =
|
|
|
d9d99f |
static struct grub_term_output grub_console_term_output =
|
|
|
d9d99f |
{
|
|
|
d9d99f |
.name = "console",
|
|
|
d9d99f |
- .init = grub_efi_console_output_init,
|
|
|
d9d99f |
.fini = grub_efi_console_output_fini,
|
|
|
d9d99f |
.putchar = grub_console_putchar,
|
|
|
d9d99f |
.getwh = grub_console_getwh,
|
|
|
d9d99f |
@@ -364,14 +395,6 @@ static struct grub_term_output grub_console_term_output =
|
|
|
d9d99f |
void
|
|
|
d9d99f |
grub_console_init (void)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
- /* FIXME: it is necessary to consider the case where no console control
|
|
|
d9d99f |
- is present but the default is already in text mode. */
|
|
|
d9d99f |
- if (! grub_efi_set_text_mode (1))
|
|
|
d9d99f |
- {
|
|
|
d9d99f |
- grub_error (GRUB_ERR_BAD_DEVICE, "cannot set text mode");
|
|
|
d9d99f |
- return;
|
|
|
d9d99f |
- }
|
|
|
d9d99f |
-
|
|
|
d9d99f |
grub_term_register_output ("console", &grub_console_term_output);
|
|
|
d9d99f |
grub_term_register_input ("console", &grub_console_term_input);
|
|
|
d9d99f |
}
|