/** @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; }