329 lines
9.7 KiB
C
329 lines
9.7 KiB
C
/** @file
|
|
|
|
;******************************************************************************
|
|
;* Copyright (c) 2012 - 2018, Insyde Software Corporation. All Rights Reserved.
|
|
;*
|
|
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
|
|
;* transmit, broadcast, present, recite, release, license or otherwise exploit
|
|
;* any part of this publication in any form, by any means, without the prior
|
|
;* written permission of Insyde Software Corporation.
|
|
;*
|
|
;******************************************************************************
|
|
*/
|
|
|
|
#include "L05NovoButtonMenu.h"
|
|
|
|
CHAR16 *mOptionStringList[] = {
|
|
NOVO_BUTTON_MENU_NORMAL_STARTUP_STRING,
|
|
NOVO_BUTTON_MENU_SETUP_STRING,
|
|
NOVO_BUTTON_MENU_BOOT_MANAGER_STRING,
|
|
NOVO_BUTTON_MENU_ONEKEY_RECOVERY_STRING,
|
|
NOVO_BUTTON_MENU_UEFI_DIAGNOSTICS_STRING,
|
|
};
|
|
UINTN mOptionStringListCount = sizeof (mOptionStringList) / sizeof (CHAR16 *);
|
|
|
|
UINTN mMaxColumn;
|
|
UINTN mMaxRow;
|
|
BOOLEAN mFindSystemRecovery = FALSE;
|
|
BOOLEAN mFindDiagnostics = FALSE;
|
|
|
|
UINTN
|
|
PrintAt (
|
|
IN UINTN Column,
|
|
IN UINTN Row,
|
|
IN CHAR16 *Fmt,
|
|
...
|
|
)
|
|
{
|
|
CHAR16 *Buffer;
|
|
UINTN StrLen;
|
|
VA_LIST Marker;
|
|
|
|
Buffer = AllocateZeroPool (0x10000);
|
|
ASSERT (Buffer);
|
|
|
|
if (Column != (UINTN) -1) {
|
|
gST->ConOut->SetCursorPosition (gST->ConOut, Column, Row);
|
|
}
|
|
|
|
VA_START (Marker, Fmt);
|
|
StrLen = UnicodeVSPrint (Buffer, 0x10000 , Fmt, Marker);
|
|
VA_END (Marker);
|
|
|
|
if (gST->ConOut != NULL) {
|
|
gST->ConOut->OutputString (gST->ConOut, Buffer);
|
|
}
|
|
|
|
gBS->FreePool (Buffer);
|
|
return StrLen;
|
|
}
|
|
|
|
VOID
|
|
DrawNovoButtonMenuDialog (
|
|
IN UINTN DialogColumn,
|
|
IN UINTN DialogRow
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINTN Color;
|
|
UINTN LeftCol;
|
|
UINTN RightCol;
|
|
UINTN UpRow;
|
|
UINTN DownRow;
|
|
CHAR16 CleanLine[MAX_STRING_LENGTH];
|
|
|
|
LeftCol = (mMaxColumn - DialogColumn) / 2;
|
|
RightCol = LeftCol + DialogColumn + 1;
|
|
UpRow = (mMaxRow - DialogRow) / 2 ;
|
|
DownRow = UpRow + DialogRow + 1;
|
|
|
|
if (!mFindSystemRecovery) {
|
|
DownRow--;
|
|
}
|
|
|
|
if (!mFindDiagnostics) {
|
|
DownRow--;
|
|
}
|
|
|
|
Color = EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLUE);
|
|
|
|
gST->ConOut->SetAttribute (gST->ConOut, Color);
|
|
|
|
for (Index = 0; Index <= DialogColumn; Index++) {
|
|
CleanLine[Index] = 0x20;
|
|
}
|
|
|
|
CleanLine[Index] = 0;
|
|
|
|
for (Index = UpRow; Index <= DownRow; Index++) {
|
|
PrintAt (LeftCol, Index, L"%s", CleanLine);
|
|
}
|
|
|
|
for (Index = LeftCol; Index < RightCol; Index++) {
|
|
PrintAt (Index, UpRow, L"%c", BOXDRAW_HORIZONTAL);
|
|
PrintAt (Index, UpRow + 2, L"%c", BOXDRAW_HORIZONTAL);
|
|
PrintAt (Index, DownRow, L"%c", BOXDRAW_HORIZONTAL);
|
|
}
|
|
|
|
for (Index = UpRow; Index < DownRow; Index++) {
|
|
PrintAt (LeftCol, Index, L"%c", BOXDRAW_VERTICAL);
|
|
PrintAt (RightCol, Index, L"%c", BOXDRAW_VERTICAL);
|
|
}
|
|
|
|
PrintAt (RightCol, DownRow, L"%c", BOXDRAW_UP_LEFT);
|
|
PrintAt (RightCol, UpRow, L"%c", BOXDRAW_DOWN_LEFT);
|
|
PrintAt (LeftCol, DownRow, L"%c", BOXDRAW_UP_RIGHT);
|
|
PrintAt (LeftCol, UpRow, L"%c", BOXDRAW_DOWN_RIGHT);
|
|
|
|
PrintAt (LeftCol, UpRow + 2, L"%c", BOXDRAW_VERTICAL_RIGHT);
|
|
PrintAt (RightCol, UpRow + 2, L"%c", BOXDRAW_VERTICAL_LEFT);
|
|
|
|
PrintAt (LeftCol + 1, UpRow + 1, L"%s", NOVO_BUTTON_MENU_TITLE_STRING);
|
|
|
|
Color = EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK);
|
|
gST->ConOut->SetAttribute (gST->ConOut, Color);
|
|
PrintAt ((mMaxColumn - (StrSize (NOVO_BUTTON_MENU_HELP_STRING) / sizeof (CHAR16))) / 2, mMaxRow - 1, L"%s", NOVO_BUTTON_MENU_HELP_STRING);
|
|
}
|
|
|
|
VOID
|
|
DrawNovoButtonMenuOptionArea (
|
|
IN UINTN DialogColumn,
|
|
IN UINTN DialogRow,
|
|
IN UINTN MaxSelection,
|
|
IN UINT16 Selection
|
|
)
|
|
{
|
|
UINTN Index;
|
|
UINTN Index_Row;
|
|
UINTN NormalColor;
|
|
UINTN HighLightColor;
|
|
UINTN LeftCol;
|
|
UINTN UpRow;
|
|
|
|
Index_Row = 0;
|
|
LeftCol = (mMaxColumn - DialogColumn) / 2;
|
|
UpRow = (mMaxRow - DialogRow) / 2 ;
|
|
NormalColor = EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLUE);
|
|
HighLightColor = EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_CYAN);
|
|
|
|
for (Index = 0; Index < MaxSelection; Index++) {
|
|
if (Selection == Index) {
|
|
gST->ConOut->SetAttribute (gST->ConOut, HighLightColor);
|
|
|
|
} else {
|
|
gST->ConOut->SetAttribute (gST->ConOut, NormalColor);
|
|
}
|
|
|
|
if (((!mFindSystemRecovery) && (Index == NovoButtonMenuOneKey)) ||
|
|
((!mFindDiagnostics) && (Index == NovoButtonMenuDiagnostics))) {
|
|
//
|
|
// 1. [Lenovo China Minimum BIOS Spec 1.39]
|
|
// [3.3.3.3 Novo button power on Menu]
|
|
// 5 System Recovery item must be hidden if the recovery partition do not exist.
|
|
// 2. Skip inactive items.
|
|
//
|
|
continue;
|
|
}
|
|
|
|
PrintAt (LeftCol + 1, UpRow + 3 + Index_Row, L"%s", mOptionStringList[Index]);
|
|
Index_Row++;
|
|
}
|
|
}
|
|
|
|
EFI_STATUS
|
|
L05NovoButtonMenu (
|
|
IN OUT UINTN *L05NovoButtonMenuSelection
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT16 Selection;
|
|
EFI_INPUT_KEY Key;
|
|
UINTN OldAttribute;
|
|
UINTN OldColumn;
|
|
UINTN OldRow;
|
|
UINTN DialogColumn;
|
|
UINTN DialogRow;
|
|
UINTN MaxSelection;
|
|
UINT16 Count;
|
|
UINT16 MaxSkip;
|
|
|
|
Status = EFI_UNSUPPORTED;
|
|
Selection = 0;
|
|
MaxSkip = 0;
|
|
|
|
//
|
|
// Init environment variable
|
|
//
|
|
gST->ConOut->QueryMode (
|
|
gST->ConOut,
|
|
gST->ConOut->Mode->Mode,
|
|
&mMaxColumn,
|
|
&mMaxRow
|
|
);
|
|
|
|
#ifdef L05_ONE_KEY_RECOVERY_ENABLE
|
|
mFindSystemRecovery = mFindSystemRecovery | IsOkrSystemRecovery ();
|
|
#endif
|
|
|
|
#ifdef L05_PUSH_BUTTON_RESET_ENABLE
|
|
mFindSystemRecovery = mFindSystemRecovery | IsPbrSystemRecovery ();
|
|
#endif
|
|
|
|
#ifdef L05_DIAGNOSTICS_SUPPORT
|
|
mFindDiagnostics = TRUE;
|
|
#endif
|
|
|
|
if (mFindSystemRecovery == FALSE) {
|
|
MaxSkip++;
|
|
}
|
|
|
|
if (mFindDiagnostics == FALSE) {
|
|
MaxSkip++;
|
|
}
|
|
|
|
//
|
|
// By L05 Dual mode BIOS spec v0.1a, show Novo menu when pressed Novo Menu.
|
|
//
|
|
MaxSelection = mOptionStringListCount;
|
|
|
|
DialogColumn = NOVO_BUTTON_MENU_STRING_MAX_LENGTH;
|
|
DialogRow = MaxSelection + 2;
|
|
|
|
DisableQuietBoot ();
|
|
gST->ConOut->EnableCursor (gST->ConOut, FALSE);
|
|
gST->ConOut->ClearScreen (gST->ConOut);
|
|
OldAttribute = gST->ConOut->Mode->Attribute;
|
|
OldColumn = gST->ConOut->Mode->CursorColumn;
|
|
OldRow = gST->ConOut->Mode->CursorRow;
|
|
|
|
//
|
|
// Draw Menu dialog
|
|
//
|
|
DrawNovoButtonMenuDialog (DialogColumn, DialogRow);
|
|
|
|
//
|
|
// Process input
|
|
//
|
|
do {
|
|
DrawNovoButtonMenuOptionArea (DialogColumn, DialogRow, MaxSelection, Selection);
|
|
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
if (Key.ScanCode == SCAN_UP) {
|
|
if (Selection != 0) {
|
|
Selection--;
|
|
}
|
|
|
|
} else if (Key.ScanCode == SCAN_DOWN) {
|
|
if (Selection != MaxSelection - 1) {
|
|
Selection++;
|
|
}
|
|
|
|
} else if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
|
|
break;
|
|
}
|
|
|
|
Count = 0;
|
|
while (((!mFindSystemRecovery) && (Selection == NovoButtonMenuOneKey)) ||
|
|
((!mFindDiagnostics) && (Selection == NovoButtonMenuDiagnostics))) {
|
|
//
|
|
// 1. [Lenovo China Minimum BIOS Spec 1.39]
|
|
// [3.3.3.3 Novo button power on Menu]
|
|
// 5 System Recovery item must be hidden if the recovery partition do not exist.
|
|
// 2. Skip inactive items.
|
|
//
|
|
if (Key.ScanCode == SCAN_UP) {
|
|
if (Selection != 0) {
|
|
Selection--;
|
|
}
|
|
|
|
} else if (Key.ScanCode == SCAN_DOWN) {
|
|
if (Selection != MaxSelection - 1) {
|
|
Selection++;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Special handling for consecutive hidden items
|
|
//
|
|
Count++;
|
|
if ((Count >= MaxSkip) && (Selection == (MaxSelection - 1))) {
|
|
if (Key.ScanCode == SCAN_UP) {
|
|
Selection = Selection + MaxSkip;
|
|
|
|
} else if (Key.ScanCode == SCAN_DOWN) {
|
|
Selection = Selection - MaxSkip;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
} while (TRUE);
|
|
|
|
gST->ConOut->SetAttribute (gST->ConOut, OldAttribute);
|
|
gST->ConOut->SetCursorPosition (gST->ConOut, OldColumn, OldRow);
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
switch (Selection) {
|
|
|
|
case NovoButtonMenuNormalBoot:
|
|
case NovoButtonMenuSetup:
|
|
case NovoButtonMenuBootManager:
|
|
case NovoButtonMenuOneKey:
|
|
case NovoButtonMenuDiagnostics:
|
|
//
|
|
// Enter One Key Recovery would be handled by NovoRecovery function.
|
|
//
|
|
default:
|
|
*L05NovoButtonMenuSelection = Selection;
|
|
break;
|
|
}
|
|
|
|
gST->ConOut->ClearScreen (gST->ConOut);
|
|
|
|
return Status;
|
|
}
|