diff --git a/meson_options.txt b/meson_options.txt index 110a471b6b..bcde759044 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -430,6 +430,14 @@ option('sbat-distro-version', type : 'string', description : 'SBAT distribution package version, e.g. 248-7.fc34') option('sbat-distro-url', type : 'string', description : 'SBAT distribution URL, e.g. https://src.fedoraproject.org/rpms/systemd') +option('efi-color-normal', type : 'string', value : 'lightgray,black', + description : 'general boot loader color in "foreground,background" form, see constants from eficon.h') +option('efi-color-entry', type : 'string', value : 'lightgray,black', + description : 'boot loader color for entries') +option('efi-color-highlight', type : 'string', value : 'black,lightgray', + description : 'boot loader color for selected entries') +option('efi-color-edit', type : 'string', value : 'lightgray,black', + description : 'boot loader color for option line edit') option('bashcompletiondir', type : 'string', description : 'directory for bash completion scripts ["no" disables]') diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 908a268a4e..549a4814eb 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -24,9 +24,6 @@ /* magic string to find in the binary image */ static const char _used_ _section_(".sdmagic") magic[] = "#### LoaderInfo: systemd-boot " GIT_VERSION " ####"; -#define COLOR_NORMAL (EFI_LIGHTGRAY|EFI_BACKGROUND_BLACK) -#define COLOR_HIGHLIGHT (EFI_BLACK|EFI_BACKGROUND_LIGHTGRAY) - enum loader_type { LOADER_UNDEFINED, LOADER_EFI, @@ -141,8 +138,9 @@ static BOOLEAN line_edit( } print[j] = '\0'; - print_at(0, y_pos, COLOR_NORMAL, print); - uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, cursor, y_pos); + /* See comment at call site. */ + print_at(1, y_pos, COLOR_EDIT, print); + uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut, cursor + 1, y_pos); err = console_key_read(&key, 0); if (EFI_ERROR(err)) @@ -532,6 +530,7 @@ static BOOLEAN menu_run( graphics_mode(FALSE); uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE); uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE); + uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut, COLOR_NORMAL); /* draw a single character to make ClearScreen work on some firmware */ Print(L" "); @@ -609,19 +608,19 @@ static BOOLEAN menu_run( if (i < idx_first || i > idx_last) continue; print_at(x_start, y_start + i - idx_first, - (i == idx_highlight) ? COLOR_HIGHLIGHT : COLOR_NORMAL, + (i == idx_highlight) ? COLOR_HIGHLIGHT : COLOR_ENTRY, lines[i]); if ((INTN)i == config->idx_default_efivar) print_at(x_start, y_start + i - idx_first, - (i == idx_highlight) ? COLOR_HIGHLIGHT : COLOR_NORMAL, + (i == idx_highlight) ? COLOR_HIGHLIGHT : COLOR_ENTRY, (CHAR16*) L"=>"); } refresh = FALSE; } else if (highlight) { - print_at(x_start, y_start + idx_highlight_prev - idx_first, COLOR_NORMAL, lines[idx_highlight_prev]); + 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 ((INTN)idx_highlight_prev == config->idx_default_efivar) - print_at(x_start , y_start + idx_highlight_prev - idx_first, COLOR_NORMAL, (CHAR16*) L"=>"); + print_at(x_start , y_start + idx_highlight_prev - idx_first, COLOR_ENTRY, (CHAR16*) L"=>"); if ((INTN)idx_highlight == config->idx_default_efivar) print_at(x_start, y_start + idx_highlight - idx_first, COLOR_HIGHLIGHT, (CHAR16*) L"=>"); highlight = FALSE; @@ -802,10 +801,14 @@ static BOOLEAN menu_run( /* only the options of configured entries can be edited */ if (!config->editor || config->entries[idx_highlight]->type == LOADER_UNDEFINED) break; - print_at(0, y_max - 1, COLOR_NORMAL, clearline + 1); - if (line_edit(config->entries[idx_highlight]->options, &config->options_edit, x_max-1, y_max-1)) - exit = TRUE; - print_at(0, y_max - 1, COLOR_NORMAL, clearline + 1); + /* The edit line may end up on the last line of the screen. And even though we're + * not telling the firmware to advance the line, it still does in this one case, + * causing a scroll to happen that screws with our beautiful boot loader output. + * Since we cannot paint the last character of the edit line, we simply start + * at x-offset 1 for symmetry. */ + print_at(1, y_max - 1, COLOR_EDIT, clearline + 2); + exit = line_edit(config->entries[idx_highlight]->options, &config->options_edit, x_max-2, y_max-1); + print_at(1, y_max - 1, COLOR_NORMAL, clearline + 2); break; case KEYPRESS(0, 0, 'v'): diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 3d16ce84b5..9cbe661746 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -103,6 +103,13 @@ if have_gnu_efi efi_conf.set10('ENABLE_TPM', get_option('tpm')) efi_conf.set('SD_TPM_PCR', get_option('tpm-pcrindex')) + foreach ctype : ['color-normal', 'color-entry', 'color-highlight', 'color-edit'] + c = get_option('efi-' + ctype).split(',') + fg = 'EFI_' + c[0].strip().underscorify().to_upper() + bg = 'EFI_BACKGROUND_' + c[1].strip().underscorify().to_upper() + efi_conf.set(ctype.underscorify().to_upper(), '(' + fg + '|' + bg + ')') + endforeach + if get_option('sbat-distro') != '' efi_conf.set_quoted('SBAT_PROJECT', meson.project_name()) efi_conf.set_quoted('PROJECT_VERSION', meson.project_version())