CHAR16 *entry_oneshot;
CHAR16 *options_edit;
BOOLEAN no_editor;
+ UINTN console_mode;
+ enum console_mode_change_type console_mode_change;
} Config;
static VOID cursor_left(UINTN *cursor, UINTN *first) {
BOOLEAN exit = FALSE;
BOOLEAN run = TRUE;
BOOLEAN wait = FALSE;
+ BOOLEAN cleared_screen = FALSE;
graphics_mode(FALSE);
uefi_call_wrapper(ST->ConIn->Reset, 2, ST->ConIn, FALSE);
/* draw a single character to make ClearScreen work on some firmware */
uefi_call_wrapper(ST->ConOut->OutputString, 2, ST->ConOut, L" ");
- uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+ if (config->console_mode_change != CONSOLE_MODE_KEEP) {
+ err = console_set_mode(&config->console_mode, config->console_mode_change);
+ if (!EFI_ERROR(err))
+ cleared_screen = TRUE;
+ }
+
+ if (!cleared_screen)
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+
+ if (config->console_mode_change != CONSOLE_MODE_KEEP && EFI_ERROR(err))
+ Print(L"Error switching console mode to %ld: %r.\r", (UINT64)config->console_mode, err);
err = uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &x_max, &y_max);
if (EFI_ERROR(err)) {
continue;
config->no_editor = !on;
}
+
+ if (strcmpa((CHAR8 *)"console-mode", key) == 0) {
+ CHAR16 *s;
+
+ if (strcmpa((CHAR8 *)"auto", value) == 0)
+ config->console_mode_change = CONSOLE_MODE_AUTO;
+ else if (strcmpa((CHAR8 *)"max", value) == 0)
+ config->console_mode_change = CONSOLE_MODE_MAX;
+ else if (strcmpa((CHAR8 *)"keep", value) == 0)
+ config->console_mode_change = CONSOLE_MODE_KEEP;
+ else {
+ s = stra_to_str(value);
+ config->console_mode = Atoi(s);
+ config->console_mode_change = CONSOLE_MODE_SET;
+ FreePool(s);
+ }
+
+ continue;
+ }
+
}
}
*key = KEYPRESS(0, k.ScanCode, k.UnicodeChar);
return 0;
}
+
+static EFI_STATUS change_mode(UINTN mode) {
+ EFI_STATUS err;
+
+ err = uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, mode);
+
+ /* Special case mode 1: when using OVMF and qemu, setting it returns error
+ * and breaks console output. */
+ if (EFI_ERROR(err) && mode == 1)
+ uefi_call_wrapper(ST->ConOut->SetMode, 2, ST->ConOut, (UINTN)0);
+
+ return err;
+}
+
+static EFI_STATUS mode_auto(UINTN *mode) {
+ /* Mode number 2 is first non standard mode, which is provided by
+ * the device manufacturer, so it should be a good mode.
+ * Note: MaxMode is the number of modes, not the last mode. */
+ if (ST->ConOut->Mode->MaxMode > 2)
+ *mode = 2;
+ /* Try again with mode different than zero (assume user requests
+ * auto mode due to some problem with mode zero). */
+ else if (ST->ConOut->Mode->MaxMode == 2)
+ *mode = 1;
+ /* Else force mode change to zero. */
+ else
+ *mode = 0;
+
+ return change_mode(*mode);
+}
+
+EFI_STATUS console_set_mode(UINTN *mode, enum console_mode_change_type how) {
+ if (how == CONSOLE_MODE_AUTO)
+ return mode_auto(mode);
+
+ if (how == CONSOLE_MODE_MAX) {
+ /* Note: MaxMode is the number of modes, not the last mode. */
+ if (ST->ConOut->Mode->MaxMode > 0)
+ *mode = ST->ConOut->Mode->MaxMode-1;
+ else
+ *mode = 0;
+ }
+
+ return change_mode(*mode);
+}
#define KEYCHAR(k) ((k) & 0xffff)
#define CHAR_CTRL(c) ((c) - 'a' + 1)
+enum console_mode_change_type {
+ CONSOLE_MODE_KEEP = 0,
+ CONSOLE_MODE_SET,
+ CONSOLE_MODE_AUTO,
+ CONSOLE_MODE_MAX,
+};
+
EFI_STATUS console_key_read(UINT64 *key, BOOLEAN wait);
+EFI_STATUS console_set_mode(UINTN *mode, enum console_mode_change_type how);
#endif