1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-21 02:50:18 +03:00

boot: Draw unicode separator line for status messages

This commit is contained in:
Jan Janssen 2022-01-25 13:48:27 +01:00 committed by Zbigniew Jędrzejewski-Szmek
parent 5f1077af1e
commit 592d576552

View File

@ -429,6 +429,17 @@ static CHAR16 *update_timeout_efivar(UINT32 *t, BOOLEAN inc) {
}
}
static BOOLEAN unicode_supported(void) {
static INTN cache = -1;
if (cache < 0)
/* Basic unicode box drawing support is mandated by the spec, but it does
* not hurt to make sure it works. */
cache = !EFI_ERROR(ST->ConOut->TestString(ST->ConOut, (CHAR16 *) L""));
return cache;
}
static void ps_string(const CHAR16 *fmt, const void *value) {
assert(fmt);
if (value)
@ -444,7 +455,11 @@ static BOOLEAN ps_continue(void) {
UINT64 key;
EFI_STATUS err;
Print(L"\n--- Press any key to continue, ESC or q to quit. ---\n\n");
if (unicode_supported())
Print(L"\n─── Press any key to continue, ESC or q to quit. ───\n\n");
else
Print(L"\n--- Press any key to continue, ESC or q to quit. ---\n\n");
err = console_key_read(&key, UINT64_MAX);
return !EFI_ERROR(err) && !IN_SET(key, KEYPRESS(0, SCAN_ESC, 0), KEYPRESS(0, 0, 'q'), KEYPRESS(0, 0, 'Q'));
}
@ -600,7 +615,7 @@ static BOOLEAN menu_run(
UINTN x_start = 0, y_start = 0, y_status = 0;
UINTN x_max, y_max;
_cleanup_(strv_freep) CHAR16 **lines = NULL;
_cleanup_freepool_ CHAR16 *clearline = NULL, *status = NULL;
_cleanup_freepool_ CHAR16 *clearline = NULL, *separator = NULL, *status = NULL;
UINT32 timeout_efivar_saved = config->timeout_sec_efivar;
UINT32 timeout_remain = config->timeout_sec == TIMEOUT_MENU_FORCE ? 0 : config->timeout_sec;
BOOLEAN exit = FALSE, run = TRUE, firmware_setup = FALSE;
@ -621,12 +636,11 @@ static BOOLEAN menu_run(
log_error_stall(L"Error switching console mode: %r", err);
}
UINTN line_width = 0, entry_padding = 3;
while (!exit) {
UINT64 key;
if (new_mode) {
UINTN line_width = 0, entry_padding = 3;
console_query_mode(&x_max, &y_max);
/* account for padding+status */
@ -645,6 +659,7 @@ static BOOLEAN menu_run(
idx_last = idx_first + visible_max - 1;
/* length of the longest entry */
line_width = 0;
for (UINTN i = 0; i < config->entry_count; i++)
line_width = MAX(line_width, StrLen(config->entries[i]->title_show));
line_width = MIN(line_width + 2 * entry_padding, x_max);
@ -657,10 +672,11 @@ static BOOLEAN menu_run(
y_start = 0;
/* Put status line after the entry list, but give it some breathing room. */
y_status = MIN(y_start + MIN(visible_max, config->entry_count) + 4, y_max - 1);
y_status = MIN(y_start + MIN(visible_max, config->entry_count) + 1, y_max - 1);
lines = strv_free(lines);
clearline = mfree(clearline);
separator = mfree(separator);
/* menu entries title lines */
lines = xnew(CHAR16*, config->entry_count + 1);
@ -684,9 +700,13 @@ static BOOLEAN menu_run(
lines[config->entry_count] = NULL;
clearline = xnew(CHAR16, x_max + 1);
for (UINTN i = 0; i < x_max; i++)
separator = xnew(CHAR16, x_max + 1);
for (UINTN i = 0; i < x_max; i++) {
clearline[i] = ' ';
separator[i] = unicode_supported() ? L'' : L'-';
}
clearline[x_max] = 0;
separator[x_max] = 0;
new_mode = FALSE;
clear = TRUE;
@ -706,16 +726,16 @@ static BOOLEAN menu_run(
if (i == config->idx_default_efivar)
print_at(x_start, y_start + i - idx_first,
(i == idx_highlight) ? COLOR_HIGHLIGHT : COLOR_ENTRY,
(CHAR16*) L"=>");
(CHAR16*) (unicode_supported() ? L"" : L"=>"));
}
refresh = FALSE;
} else if (highlight) {
print_at(x_start, y_start + idx_highlight_prev - idx_first, COLOR_ENTRY, lines[idx_highlight_prev]);
print_at(x_start, y_start + idx_highlight - idx_first, COLOR_HIGHLIGHT, lines[idx_highlight]);
if (idx_highlight_prev == config->idx_default_efivar)
print_at(x_start , y_start + idx_highlight_prev - idx_first, COLOR_ENTRY, (CHAR16*) L"=>");
print_at(x_start , y_start + idx_highlight_prev - idx_first, COLOR_ENTRY, (CHAR16*) (unicode_supported() ? L"" : L"=>"));
if (idx_highlight == config->idx_default_efivar)
print_at(x_start, y_start + idx_highlight - idx_first, COLOR_HIGHLIGHT, (CHAR16*) L"=>");
print_at(x_start, y_start + idx_highlight - idx_first, COLOR_HIGHLIGHT, (CHAR16*) (unicode_supported() ? L"" : L"=>"));
highlight = FALSE;
}
@ -724,20 +744,24 @@ static BOOLEAN menu_run(
status = xpool_print(L"Boot in %u s.", timeout_remain);
}
/* print status at last line of screen */
if (status) {
UINTN len;
UINTN x;
/* center line */
len = StrLen(status);
if (len < x_max)
x = (x_max - len) / 2;
else
x = 0;
print_at(0, y_status, COLOR_NORMAL, clearline + (x_max - x));
/* If we draw the last char of the last line, the screen will scroll and break our
* input. Therefore, draw one less character then we could for the status message.
* Note that the same does not apply for the separator line as it will never be drawn
* on the last line. */
UINTN len = StrnLen(status, x_max - 1);
UINTN x = (x_max - len) / 2;
status[len] = '\0';
print_at(0, y_status, COLOR_NORMAL, clearline + x_max - x);
ST->ConOut->OutputString(ST->ConOut, status);
ST->ConOut->OutputString(ST->ConOut, clearline + 1 + x + len);
len = MIN(MAX(len, line_width) + 2 * entry_padding, x_max);
x = (x_max - len) / 2;
print_at(x, y_status - 1, COLOR_NORMAL, separator + x_max - len);
} else {
print_at(0, y_status - 1, COLOR_NORMAL, clearline);
print_at(0, y_status, COLOR_NORMAL, clearline + 1); /* See comment above. */
}
/* Beep several times so that the selected entry can be distinguished. */
@ -768,11 +792,7 @@ static BOOLEAN menu_run(
timeout_remain = 0;
/* clear status after keystroke */
if (status) {
FreePool(status);
status = NULL;
print_at(0, y_status, COLOR_NORMAL, clearline + 1);
}
status = mfree(status);
idx_highlight_prev = idx_highlight;