1a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/** @file
2a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  The application to show the Boot Manager Menu.
3a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
4a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiCopyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
5a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiThis program and the accompanying materials
6a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Niare licensed and made available under the terms and conditions of the BSD License
7a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Niwhich accompanies this distribution.  The full text of the license may be found at
8a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Nihttp://opensource.org/licenses/bsd-license.php
9a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
10a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
13a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
14a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
15a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni#include "BootManagerMenu.h"
16a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
17a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiEFI_HII_HANDLE gStringPackHandle;
18a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
19a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiBOOLEAN   mModeInitialized = FALSE;
20a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
21a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni//
22a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni// Boot video resolution and text mode.
23a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni//
24a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINT32    mBootHorizontalResolution    = 0;
25a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINT32    mBootVerticalResolution      = 0;
26a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINT32    mBootTextModeColumn          = 0;
27a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINT32    mBootTextModeRow             = 0;
28a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni//
29a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni// BIOS setup video resolution and text mode.
30a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni//
31a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINT32    mSetupTextModeColumn         = 0;
32a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINT32    mSetupTextModeRow            = 0;
33a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINT32    mSetupHorizontalResolution   = 0;
34a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINT32    mSetupVerticalResolution     = 0;
35a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
36a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
37a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Prints a unicode string to the default console, at
38a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  the supplied cursor position, using L"%s" format.
39a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
40a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param  Column     The cursor position to print the string at.
41a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param  Row        The cursor position to print the string at
42a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param  String     String pointer.
43a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
44a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @return Length of string printed to the console
45a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
46a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
47a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINTN
48a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiPrintStringAt (
49a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN UINTN     Column,
50a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN UINTN     Row,
51a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN CHAR16    *String
52a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
53a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
54a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
55a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gST->ConOut->SetCursorPosition (gST->ConOut, Column, Row);
56a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  return Print (L"%s", String);
57a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
58a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
59a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
60a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Prints a chracter to the default console, at
61a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  the supplied cursor position, using L"%c" format.
62a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
63a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param  Column     The cursor position to print the string at.
64a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param  Row        The cursor position to print the string at.
65a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param  Character  Character to print.
66a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
67a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @return Length of string printed to the console.
68a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
69a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
70a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINTN
71a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiPrintCharAt (
72a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN UINTN     Column,
73a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN UINTN     Row,
74a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  CHAR16       Character
75a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
76a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
77a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gST->ConOut->SetCursorPosition (gST->ConOut, Column, Row);
78a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  return Print (L"%c", Character);
79a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
80a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
81a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
82a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Count the storage space of a Unicode string which uses current lanaguag to get
83a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  from input string ID.
84a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
85a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param StringId          The input string to be counted.
86a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
87a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @return Storage space for the input string.
88a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
89a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
90a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiUINTN
91a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiGetLineWidth (
92a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN EFI_STRING_ID       StringId
93a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
94a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
95a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN        Index;
96a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN        IncrementValue;
97a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_STRING   String;
98a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN        LineWidth;
99a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
100a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  LineWidth = 0;
101a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  String = HiiGetString (gStringPackHandle, StringId, NULL);
102a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
103a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (String != NULL) {
104a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    Index           = 0;
105a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    IncrementValue  = 1;
106a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
107a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    do {
108a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      //
109a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      // Advance to the null-terminator or to the first width directive
110a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      //
111a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      for (;
112a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni           (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
113a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni           Index++, LineWidth = LineWidth + IncrementValue
114a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          )
115a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        ;
116a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
117a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      //
118a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      // We hit the null-terminator, we now have a count
119a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      //
120a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      if (String[Index] == 0) {
121a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        break;
122a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      }
123a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      //
124a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
125a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
126a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      //
127a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      if (String[Index] == NARROW_CHAR) {
128a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        //
129a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        // Skip to the next character
130a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        //
131a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        Index++;
132a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        IncrementValue = 1;
133a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      } else {
134a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        //
135a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        // Skip to the next character
136a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        //
137a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        Index++;
138a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        IncrementValue = 2;
139a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      }
140a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    } while (String[Index] != 0);
141a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    FreePool (String);
142a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
143a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
144a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  return LineWidth;
145a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
146a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
147a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
148a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  This function uses calculate the boot menu location, size and scroll bar information.
149a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
150a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param  BootMenuData            The boot menu data to be proccessed.
151a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
152a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @return EFI_SUCCESS             calculate boot menu information successful.
153a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval EFI_INVALID_PARAMETER   Input parameter is invalid
154a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
155a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
156a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiEFI_STATUS
157a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiInitializeBootMenuScreen (
158a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN OUT  BOOT_MENU_POPUP_DATA  *BootMenuData
159a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
160a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
161a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN         MaxStrWidth;
162a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN         StrWidth;
163a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN         Index;
164a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN         Column;
165a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN         Row;
166a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN         MaxPrintRows;
167a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN         UnSelectableItmes;
168a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
169a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (BootMenuData == NULL) {
170a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    return EFI_INVALID_PARAMETER;
171a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
172a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
173a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Get maximum string width
174a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
175a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  MaxStrWidth = 0;
176a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 0; Index < TITLE_TOKEN_COUNT; Index++) {
177a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    StrWidth = GetLineWidth (BootMenuData->TitleToken[Index]);
178a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    MaxStrWidth = MaxStrWidth > StrWidth ? MaxStrWidth : StrWidth;
179a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
180a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
181a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 0; Index < BootMenuData->ItemCount; Index++) {
182a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    StrWidth = GetLineWidth (BootMenuData->PtrTokens[Index]);
183a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    MaxStrWidth = MaxStrWidth > StrWidth ? MaxStrWidth : StrWidth;
184a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
185a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
186a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 0; Index < HELP_TOKEN_COUNT; Index++) {
187a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    StrWidth = GetLineWidth (BootMenuData->HelpToken[Index]);
188a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    MaxStrWidth = MaxStrWidth > StrWidth ? MaxStrWidth : StrWidth;
189a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
190a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
191a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // query current row and column to calculate boot menu location
192a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
193a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gST->ConOut->QueryMode (
194a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                 gST->ConOut,
195a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                 gST->ConOut->Mode->Mode,
196a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                 &Column,
197a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                 &Row
198a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                 );
199a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
200a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  MaxPrintRows = Row - 6;
201a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UnSelectableItmes = TITLE_TOKEN_COUNT + 2 + HELP_TOKEN_COUNT + 2;
202a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->MenuScreen.Width = MaxStrWidth + 8;
203a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (BootMenuData->ItemCount + UnSelectableItmes > MaxPrintRows) {
204a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->MenuScreen.Height = MaxPrintRows;
205a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->ScrollBarControl.HasScrollBar = TRUE;
206a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->ScrollBarControl.ItemCountPerScreen = MaxPrintRows - UnSelectableItmes;
207a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->ScrollBarControl.FirstItem = 0;
208a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->ScrollBarControl.LastItem = MaxPrintRows - UnSelectableItmes - 1;
209a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  } else {
210a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->MenuScreen.Height = BootMenuData->ItemCount + UnSelectableItmes;
211a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->ScrollBarControl.HasScrollBar = FALSE;
212a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->ScrollBarControl.ItemCountPerScreen = BootMenuData->ItemCount;
213a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->ScrollBarControl.FirstItem = 0;
214a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->ScrollBarControl.LastItem = BootMenuData->ItemCount - 1;
215a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
216a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->MenuScreen.StartCol = (Column -  BootMenuData->MenuScreen.Width) / 2;
217a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->MenuScreen.StartRow = (Row -  BootMenuData->MenuScreen.Height) / 2;
218a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
219a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  return EFI_SUCCESS;
220a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
221a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
222a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  This funciton uses check boot option is wheher setup application or no
223a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
224a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param   BootOption   Pointer to EFI_BOOT_MANAGER_LOAD_OPTION array.
225a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
226a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval  TRUE         This boot option is setup application.
227a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval  FALSE        This boot options isn't setup application
228a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
229a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
230a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiBOOLEAN
231a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiIsBootManagerMenu (
232a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN  EFI_BOOT_MANAGER_LOAD_OPTION    *BootOption
233a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
234a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
235a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_STATUS                          Status;
236a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_BOOT_MANAGER_LOAD_OPTION        BootManagerMenu;
237a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
238a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
239a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (!EFI_ERROR (Status)) {
240a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    EfiBootManagerFreeLoadOption (&BootManagerMenu);
241a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
242a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
243a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  return (BOOLEAN) (!EFI_ERROR (Status) && (BootOption->OptionNumber == BootManagerMenu.OptionNumber));
244a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
2457df23f85f5e344546392016725e99805a667381fRuiyu Ni
2467df23f85f5e344546392016725e99805a667381fRuiyu Ni/**
2477df23f85f5e344546392016725e99805a667381fRuiyu Ni  Return whether to ignore the boot option.
2487df23f85f5e344546392016725e99805a667381fRuiyu Ni
2497df23f85f5e344546392016725e99805a667381fRuiyu Ni  @param BootOption  Pointer to EFI_BOOT_MANAGER_LOAD_OPTION to check.
2507df23f85f5e344546392016725e99805a667381fRuiyu Ni
2517df23f85f5e344546392016725e99805a667381fRuiyu Ni  @retval TRUE  Ignore the boot optin.
2527df23f85f5e344546392016725e99805a667381fRuiyu Ni  @retval FALSE Do not ignore the boot option.
2537df23f85f5e344546392016725e99805a667381fRuiyu Ni**/
2547df23f85f5e344546392016725e99805a667381fRuiyu NiBOOLEAN
2557df23f85f5e344546392016725e99805a667381fRuiyu NiIgnoreBootOption (
2567df23f85f5e344546392016725e99805a667381fRuiyu Ni  IN   EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption
2577df23f85f5e344546392016725e99805a667381fRuiyu Ni  )
2587df23f85f5e344546392016725e99805a667381fRuiyu Ni{
2597df23f85f5e344546392016725e99805a667381fRuiyu Ni  EFI_STATUS                    Status;
2607df23f85f5e344546392016725e99805a667381fRuiyu Ni  EFI_DEVICE_PATH_PROTOCOL      *ImageDevicePath;
2617df23f85f5e344546392016725e99805a667381fRuiyu Ni
2627df23f85f5e344546392016725e99805a667381fRuiyu Ni  //
2637df23f85f5e344546392016725e99805a667381fRuiyu Ni  // Ignore myself.
2647df23f85f5e344546392016725e99805a667381fRuiyu Ni  //
2657df23f85f5e344546392016725e99805a667381fRuiyu Ni  Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageDevicePathProtocolGuid, (VOID **) &ImageDevicePath);
2667df23f85f5e344546392016725e99805a667381fRuiyu Ni  ASSERT_EFI_ERROR (Status);
2677df23f85f5e344546392016725e99805a667381fRuiyu Ni  if (CompareMem (BootOption->FilePath, ImageDevicePath, GetDevicePathSize (ImageDevicePath)) == 0) {
2687df23f85f5e344546392016725e99805a667381fRuiyu Ni    return TRUE;
2697df23f85f5e344546392016725e99805a667381fRuiyu Ni  }
2707df23f85f5e344546392016725e99805a667381fRuiyu Ni
2717df23f85f5e344546392016725e99805a667381fRuiyu Ni  //
2727df23f85f5e344546392016725e99805a667381fRuiyu Ni  // Do not ignore Boot Manager Menu.
2737df23f85f5e344546392016725e99805a667381fRuiyu Ni  //
2747df23f85f5e344546392016725e99805a667381fRuiyu Ni  if (IsBootManagerMenu (BootOption)) {
2757df23f85f5e344546392016725e99805a667381fRuiyu Ni    return FALSE;
2767df23f85f5e344546392016725e99805a667381fRuiyu Ni  }
2777df23f85f5e344546392016725e99805a667381fRuiyu Ni
2787df23f85f5e344546392016725e99805a667381fRuiyu Ni  //
2797df23f85f5e344546392016725e99805a667381fRuiyu Ni  // Ignore the hidden/inactive boot option.
2807df23f85f5e344546392016725e99805a667381fRuiyu Ni  //
2817df23f85f5e344546392016725e99805a667381fRuiyu Ni  if (((BootOption->Attributes & LOAD_OPTION_HIDDEN) != 0) || ((BootOption->Attributes & LOAD_OPTION_ACTIVE) == 0)) {
2827df23f85f5e344546392016725e99805a667381fRuiyu Ni    return TRUE;
2837df23f85f5e344546392016725e99805a667381fRuiyu Ni  }
2847df23f85f5e344546392016725e99805a667381fRuiyu Ni
2857df23f85f5e344546392016725e99805a667381fRuiyu Ni  return FALSE;
2867df23f85f5e344546392016725e99805a667381fRuiyu Ni}
287a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
288a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
289a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  This funciton uses to initialize boot menu data
290a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
291a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param   BootOption             Pointer to EFI_BOOT_MANAGER_LOAD_OPTION array.
292a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param   BootOptionCount        Number of boot option.
293a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param   BootMenuData           The Input BootMenuData to be initialized.
294a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
295a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval  EFI_SUCCESS            Initialize boot menu data successful.
296a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval  EFI_INVALID_PARAMETER  Input parameter is invalid.
297a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
298a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
299a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiEFI_STATUS
300a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiInitializeBootMenuData (
301a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN   EFI_BOOT_MANAGER_LOAD_OPTION  *BootOption,
302a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN   UINTN                         BootOptionCount,
303a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  OUT  BOOT_MENU_POPUP_DATA          *BootMenuData
304a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
305a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
306a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                         Index;
307a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                         StrIndex;
308a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
309a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (BootOption == NULL || BootMenuData == NULL) {
310a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    return EFI_INVALID_PARAMETER;
31126da0b64df29c2a7c266661a7fe0325e0444c96cRuiyu Ni  }
31226da0b64df29c2a7c266661a7fe0325e0444c96cRuiyu Ni
313a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->TitleToken[0] = STRING_TOKEN (STR_BOOT_POPUP_MENU_TITLE_STRING);
314a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->PtrTokens     = AllocateZeroPool (BootOptionCount * sizeof (EFI_STRING_ID));
315a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  ASSERT (BootMenuData->PtrTokens != NULL);
316a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
317a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
318a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Skip boot option which created by BootNext Variable
319a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
320a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (StrIndex = 0, Index = 0; Index < BootOptionCount; Index++) {
3217df23f85f5e344546392016725e99805a667381fRuiyu Ni    if (IgnoreBootOption (&BootOption[Index])) {
32226da0b64df29c2a7c266661a7fe0325e0444c96cRuiyu Ni      continue;
32326da0b64df29c2a7c266661a7fe0325e0444c96cRuiyu Ni    }
32426da0b64df29c2a7c266661a7fe0325e0444c96cRuiyu Ni
325a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    ASSERT (BootOption[Index].Description != NULL);
326a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    BootMenuData->PtrTokens[StrIndex++] = HiiSetString (
327a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                            gStringPackHandle,
328a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                            0,
329a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                            BootOption[Index].Description,
330a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                            NULL
331a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                            );
332a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
333a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
334a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->ItemCount           = StrIndex;
335a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->HelpToken[0] = STRING_TOKEN (STR_BOOT_POPUP_MENU_HELP1_STRING);
336a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->HelpToken[1] = STRING_TOKEN (STR_BOOT_POPUP_MENU_HELP2_STRING);
337a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->HelpToken[2] = STRING_TOKEN (STR_BOOT_POPUP_MENU_HELP3_STRING);
338a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  InitializeBootMenuScreen (BootMenuData);
339a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->SelectItem = 0;
340a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  return EFI_SUCCESS;
341a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
342a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
343a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
344a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  This function uses input select item to highlight selected item
345a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  and set current selected item in BootMenuData
346a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
347a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param  WantSelectItem          The user wants to select item.
348a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param  BootMenuData            The boot menu data to be proccessed
349a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
350a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @return EFI_SUCCESS             Highlight selected item and update current selected
351a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                  item successful
352a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval EFI_INVALID_PARAMETER   Input parameter is invalid
353a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
354a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiEFI_STATUS
355a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiBootMenuSelectItem (
356a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN     UINTN                 WantSelectItem,
357a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN OUT BOOT_MENU_POPUP_DATA  *BootMenuData
358a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
359a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
360a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  INT32                 SavedAttribute;
361a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_STRING            String;
362a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 StartCol;
363a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 StartRow;
364a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 PrintCol;
365a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 PrintRow;
366a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 TopShadeNum;
367a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 LowShadeNum;
368a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 FirstItem;
369a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 LastItem;
370a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 ItemCountPerScreen;
371a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 Index;
372a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BOOLEAN               RePaintItems;
373a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
374a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (BootMenuData == NULL || WantSelectItem >= BootMenuData->ItemCount) {
375a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    return EFI_INVALID_PARAMETER;
376a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
377a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  SavedAttribute = gST->ConOut->Mode->Attribute;
378a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  RePaintItems = FALSE;
379a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  StartCol = BootMenuData->MenuScreen.StartCol;
380a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  StartRow = BootMenuData->MenuScreen.StartRow;
381a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
382a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // print selectable items again and adjust scroll bar if need
383a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
384a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (BootMenuData->ScrollBarControl.HasScrollBar &&
385a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      (WantSelectItem < BootMenuData->ScrollBarControl.FirstItem ||
386a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      WantSelectItem > BootMenuData->ScrollBarControl.LastItem ||
387a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      WantSelectItem == BootMenuData->SelectItem)) {
388a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    ItemCountPerScreen   = BootMenuData->ScrollBarControl.ItemCountPerScreen;
389a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
390a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    // Set first item and last item
391a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
392a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (WantSelectItem < BootMenuData->ScrollBarControl.FirstItem) {
393a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      BootMenuData->ScrollBarControl.FirstItem = WantSelectItem;
394a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      BootMenuData->ScrollBarControl.LastItem = WantSelectItem + ItemCountPerScreen - 1;
395a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    } else if (WantSelectItem > BootMenuData->ScrollBarControl.LastItem) {
396a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      BootMenuData->ScrollBarControl.FirstItem = WantSelectItem - ItemCountPerScreen + 1;
397a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      BootMenuData->ScrollBarControl.LastItem = WantSelectItem;
398a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
399a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLUE);
400a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    FirstItem = BootMenuData->ScrollBarControl.FirstItem;
401a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    LastItem  = BootMenuData->ScrollBarControl.LastItem;
402a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    TopShadeNum = 0;
403a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (FirstItem != 0) {
404a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      TopShadeNum = (FirstItem * ItemCountPerScreen) / BootMenuData->ItemCount;
405a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      if ((FirstItem * ItemCountPerScreen) % BootMenuData->ItemCount != 0) {
406a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        TopShadeNum++;
407a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      }
408a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      PrintCol = StartCol  + BootMenuData->MenuScreen.Width - 2;
409a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      PrintRow = StartRow + TITLE_TOKEN_COUNT + 2;
410a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      for (Index = 0; Index < TopShadeNum; Index++, PrintRow++) {
411a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        PrintCharAt (PrintCol, PrintRow, BLOCKELEMENT_LIGHT_SHADE);
412a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      }
413a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
414a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    LowShadeNum = 0;
415a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (LastItem != BootMenuData->ItemCount - 1) {
416a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      LowShadeNum = ((BootMenuData->ItemCount - 1 - LastItem) * ItemCountPerScreen) / BootMenuData->ItemCount;
417a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      if (((BootMenuData->ItemCount - 1 - LastItem) * ItemCountPerScreen) % BootMenuData->ItemCount != 0) {
418a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        LowShadeNum++;
419a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      }
420a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      PrintCol = StartCol  + BootMenuData->MenuScreen.Width - 2;
421a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + ItemCountPerScreen - LowShadeNum;
422a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      for (Index = 0; Index < LowShadeNum; Index++, PrintRow++) {
423a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        PrintCharAt (PrintCol, PrintRow, BLOCKELEMENT_LIGHT_SHADE);
424a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      }
425a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
426a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCol = StartCol  + BootMenuData->MenuScreen.Width - 2;
427a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + TopShadeNum;
428a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    for (Index = TopShadeNum; Index < ItemCountPerScreen - LowShadeNum; Index++, PrintRow++) {
429a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      PrintCharAt (PrintCol, PrintRow, BLOCKELEMENT_FULL_BLOCK);
430a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
431a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
432a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
433a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
434a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    // Clear selectable items first
435a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
436a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCol = StartCol  + 1;
437a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintRow = StartRow + TITLE_TOKEN_COUNT + 2;
438a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    String = AllocateZeroPool ((BootMenuData->MenuScreen.Width - 2) * sizeof (CHAR16));
439a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    ASSERT (String != NULL);
440a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    for (Index = 0; Index < BootMenuData->MenuScreen.Width - 3; Index++) {
441a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      String[Index] = 0x20;
442a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
443a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    for (Index = 0; Index < ItemCountPerScreen; Index++) {
444a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      PrintStringAt (PrintCol, PrintRow + Index, String);
445a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
446a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    FreePool (String);
447a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
448a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    // print selectable items
449a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
450a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    for (Index = 0; Index < ItemCountPerScreen; Index++, PrintRow++) {
451a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[Index + FirstItem], NULL);
452a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      PrintStringAt (PrintCol, PrintRow, String);
453a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      FreePool (String);
454a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
455a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    RePaintItems = TRUE;
456a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
457a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
458a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
459a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Print want to select item
460a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
461a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  FirstItem = BootMenuData->ScrollBarControl.FirstItem;
462a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLACK);
463a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[WantSelectItem], NULL);
464a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintCol = StartCol  + 1;
465a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + WantSelectItem - FirstItem;
466a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintStringAt (PrintCol, PrintRow, String);
467a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  FreePool (String);
468a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
469a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
470a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // if Want Select and selected item isn't the same and doesn't re-draw selectable
471a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // items, clear select item
472a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
473a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (WantSelectItem != BootMenuData->SelectItem && !RePaintItems) {
474a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLUE);
475a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[BootMenuData->SelectItem], NULL);
476a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCol = StartCol  + 1;
477a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintRow = StartRow + 3 + BootMenuData->SelectItem - FirstItem;
478a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintStringAt (PrintCol, PrintRow, String);
479a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    FreePool (String);
480a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
481a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
482a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
483a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuData->SelectItem = WantSelectItem;
484a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  return EFI_SUCCESS;
485a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
486a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
487a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
488a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  This funciton uses to draw boot popup menu
489a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
490a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param   BootMenuData           The Input BootMenuData to be processed.
491a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
492a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval  EFI_SUCCESS            Draw boot popup menu successful.
493a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
494a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
495a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiEFI_STATUS
496a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiDrawBootPopupMenu (
497a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN  BOOT_MENU_POPUP_DATA  *BootMenuData
498a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
499a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
500a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_STRING            String;
501a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 Index;
502a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 Width;
503a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 Height;
504a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 StartCol;
505a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 StartRow;
506a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 PrintRow;
507a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 PrintCol;
508a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 LineWidth;
509a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  INT32                 SavedAttribute;
510a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 ItemCountPerScreen;
511a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
512a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gST->ConOut->ClearScreen (gST->ConOut);
513a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
514a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  SavedAttribute = gST->ConOut->Mode->Attribute;
515a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLUE);
516a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Width    = BootMenuData->MenuScreen.Width;
517a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Height   = BootMenuData->MenuScreen.Height;
518a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  StartCol = BootMenuData->MenuScreen.StartCol;
519a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  StartRow = BootMenuData->MenuScreen.StartRow;
520a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  ItemCountPerScreen = BootMenuData->ScrollBarControl.ItemCountPerScreen;
521a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintRow = StartRow;
522a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
523a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gST->ConOut->EnableCursor (gST->ConOut, FALSE);
524a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
525a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Draw Boot popup menu screen
526a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
527a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintCharAt (StartCol, PrintRow, BOXDRAW_DOWN_RIGHT);
528a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 1; Index < Width - 1; Index++) {
529a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL);
530a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
531a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_DOWN_LEFT);
532a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
533a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
534a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Draw the screen for title
535a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
536a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  String = AllocateZeroPool ((Width - 1) * sizeof (CHAR16));
537a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  ASSERT (String != NULL);
538a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 0; Index < Width - 2; Index++) {
539a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    String[Index] = 0x20;
540a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
541a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
542a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 0; Index < TITLE_TOKEN_COUNT; Index++) {
543a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintRow++;
544a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL);
545a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintStringAt (StartCol + 1, PrintRow, String);
546a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL);
547a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
548a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
549a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintRow++;
550a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL_RIGHT);
551a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 1; Index < Width - 1; Index++) {
552a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL);
553a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
554a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL_LEFT);
555a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
556a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
557a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Draw screen for selectable items
558a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
559a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 0; Index < ItemCountPerScreen; Index++) {
560a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintRow++;
561a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL);
562a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintStringAt (StartCol + 1, PrintRow, String);
563a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL);
564a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
565a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
566a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintRow++;
567a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL_RIGHT);
568a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 1; Index < Width - 1; Index++) {
569a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL);
570a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
571a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL_LEFT);
572a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
573a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
574a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Draw screen for Help
575a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
576a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 0; Index < HELP_TOKEN_COUNT; Index++) {
577a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintRow++;
578a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL);
579a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintStringAt (StartCol + 1, PrintRow, String);
580a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL);
581a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
582a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  FreePool (String);
583a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
584a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintRow++;
585a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintCharAt (StartCol, PrintRow, BOXDRAW_UP_RIGHT);
586a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 1; Index < Width - 1; Index++) {
587a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL);
588a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
589a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_UP_LEFT);
590a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
591a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
592a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
593a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // print title strings
594a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
595a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintRow = StartRow + 1;
596a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 0; Index < TITLE_TOKEN_COUNT; Index++, PrintRow++) {
597a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    String = HiiGetString (gStringPackHandle, BootMenuData->TitleToken[Index], NULL);
598a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    LineWidth = GetLineWidth (BootMenuData->TitleToken[Index]);
599a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCol = StartCol + (Width - LineWidth) / 2;
600a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintStringAt (PrintCol, PrintRow, String);
601a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    FreePool (String);
602a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
603a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
604a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
605a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // print selectable items
606a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
607a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintCol = StartCol + 1;
608a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintRow = StartRow + TITLE_TOKEN_COUNT + 2;
609a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 0; Index < ItemCountPerScreen; Index++, PrintRow++) {
610a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[Index], NULL);
611a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintStringAt (PrintCol, PrintRow, String);
612a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    FreePool (String);
613a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
614a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
615a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
616a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Print Help strings
617a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
618a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  PrintRow++;
619a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (Index = 0; Index < HELP_TOKEN_COUNT; Index++, PrintRow++) {
620a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    String = HiiGetString (gStringPackHandle, BootMenuData->HelpToken[Index], NULL);
621a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    LineWidth = GetLineWidth (BootMenuData->HelpToken[Index]);
622a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCol = StartCol + (Width - LineWidth) / 2;
623a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintStringAt (PrintCol, PrintRow, String);
624a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    FreePool (String);
625a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
626a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
627a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
628a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Print scroll bar if has scroll bar
629a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
630a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (BootMenuData->ScrollBarControl.HasScrollBar) {
631a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCol = StartCol + Width - 2;
632a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintRow = StartRow + 2;
633a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (PrintCol, PrintRow, GEOMETRICSHAPE_UP_TRIANGLE);
634a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (PrintCol + 1, PrintRow, BOXDRAW_VERTICAL);
635a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintRow += (ItemCountPerScreen + 1);
636a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (PrintCol, PrintRow, GEOMETRICSHAPE_DOWN_TRIANGLE);
637a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    PrintCharAt (PrintCol + 1, PrintRow, BOXDRAW_VERTICAL);
638a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
639a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
640a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
641a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
642a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Print Selected item
643a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
644a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootMenuSelectItem (BootMenuData->SelectItem, BootMenuData);
645a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  return EFI_SUCCESS;
646a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
647a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
648a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
649a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  This funciton uses to boot from selected item
650a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
651a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param   BootOptions            Pointer to EFI_BOOT_MANAGER_LOAD_OPTION array.
652a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param   BootOptionCount        Number of boot option.
653a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param   SelectItem             Current selected item.
654a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
655a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiVOID
656a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiBootFromSelectOption (
657a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN   EFI_BOOT_MANAGER_LOAD_OPTION  *BootOptions,
658a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN   UINTN                         BootOptionCount,
659a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN   UINTN                         SelectItem
660a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
661a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
662a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 ItemNum;
663a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                 Index;
664a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
665a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  ASSERT (BootOptions != NULL);
666a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
667a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (ItemNum = 0, Index = 0; Index < BootOptionCount; Index++) {
6687df23f85f5e344546392016725e99805a667381fRuiyu Ni    if (IgnoreBootOption (&BootOptions[Index])) {
669a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      continue;
670a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
6717df23f85f5e344546392016725e99805a667381fRuiyu Ni
672a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (ItemNum++ == SelectItem) {
673a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      EfiBootManagerBoot (&BootOptions[Index]);
674a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      break;
675a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
676a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
677a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
678a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
679a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
680a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  This function will change video resolution and text mode
681a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  according to defined setup mode or defined boot mode
682a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
683a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param  IsSetupMode   Indicate mode is changed to setup mode or boot mode.
684a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
685a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval  EFI_SUCCESS  Mode is changed successfully.
686a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval  Others             Mode failed to be changed.
687a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
688a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
689a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiEFI_STATUS
690a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiEFIAPI
691a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiBdsSetConsoleMode (
692a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BOOLEAN  IsSetupMode
693a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
694a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
695a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_GRAPHICS_OUTPUT_PROTOCOL          *GraphicsOutput;
696a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL       *SimpleTextOut;
697a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                                 SizeOfInfo;
698a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;
699a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINT32                                MaxGopMode;
700a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINT32                                MaxTextMode;
701a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINT32                                ModeNumber;
702a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINT32                                NewHorizontalResolution;
703a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINT32                                NewVerticalResolution;
704a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINT32                                NewColumns;
705a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINT32                                NewRows;
706a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                                 HandleCount;
707a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_HANDLE                            *HandleBuffer;
708a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_STATUS                            Status;
709a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                                 Index;
710a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                                 CurrentColumn;
711a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                                 CurrentRow;
712a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
713a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  MaxGopMode  = 0;
714a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  MaxTextMode = 0;
715a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
716a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
717a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Get current video resolution and text mode
718a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
719a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Status = gBS->HandleProtocol (
720a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  gST->ConsoleOutHandle,
721a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  &gEfiGraphicsOutputProtocolGuid,
722a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  (VOID**)&GraphicsOutput
723a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  );
724a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (EFI_ERROR (Status)) {
725a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    GraphicsOutput = NULL;
726a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
727a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
728a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Status = gBS->HandleProtocol (
729a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  gST->ConsoleOutHandle,
730a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  &gEfiSimpleTextOutProtocolGuid,
731a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  (VOID**)&SimpleTextOut
732a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  );
733a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (EFI_ERROR (Status)) {
734a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    SimpleTextOut = NULL;
735a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
736a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
737a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
738a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    return EFI_UNSUPPORTED;
739a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
740a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
741a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (IsSetupMode) {
742a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
743a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    // The requried resolution and text mode is setup mode.
744a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
745a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    NewHorizontalResolution = mSetupHorizontalResolution;
746a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    NewVerticalResolution   = mSetupVerticalResolution;
747a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    NewColumns              = mSetupTextModeColumn;
748a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    NewRows                 = mSetupTextModeRow;
749a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  } else {
750a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
751a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    // The required resolution and text mode is boot mode.
752a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
753a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    NewHorizontalResolution = mBootHorizontalResolution;
754a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    NewVerticalResolution   = mBootVerticalResolution;
755a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    NewColumns              = mBootTextModeColumn;
756a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    NewRows                 = mBootTextModeRow;
757a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
758a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
759a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (GraphicsOutput != NULL) {
760a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    MaxGopMode  = GraphicsOutput->Mode->MaxMode;
761a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
762a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
763a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (SimpleTextOut != NULL) {
764a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    MaxTextMode = SimpleTextOut->Mode->MaxMode;
765a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
766a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
767a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
768a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // 1. If current video resolution is same with required video resolution,
769a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //    video resolution need not be changed.
770a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //    1.1. If current text mode is same with required text mode, text mode need not be changed.
771a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //    1.2. If current text mode is different from required text mode, text mode need be changed.
772a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
773a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
774a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
775a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    Status = GraphicsOutput->QueryMode (
776a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                       GraphicsOutput,
777a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                       ModeNumber,
778a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                       &SizeOfInfo,
779a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                       &Info
780a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                       );
781a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (!EFI_ERROR (Status)) {
782a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      if ((Info->HorizontalResolution == NewHorizontalResolution) &&
783a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          (Info->VerticalResolution == NewVerticalResolution)) {
784a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&
785a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {
786a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          //
787a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          // Current resolution is same with required resolution, check if text mode need be set
788a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          //
789a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
790a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          ASSERT_EFI_ERROR (Status);
791a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          if (CurrentColumn == NewColumns && CurrentRow == NewRows) {
792a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            //
793a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            // If current text mode is same with required text mode. Do nothing
794a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            //
795a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            FreePool (Info);
796a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            return EFI_SUCCESS;
797a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          } else {
798a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            //
799a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            // If current text mode is different from requried text mode.  Set new video mode
800a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            //
801a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            for (Index = 0; Index < MaxTextMode; Index++) {
802a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni              Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
803a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni              if (!EFI_ERROR(Status)) {
804a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
805a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  //
806a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  // Required text mode is supported, set it.
807a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  //
808a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
809a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  ASSERT_EFI_ERROR (Status);
810a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  //
811a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  // Update text mode PCD.
812a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  //
813377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong                  Status = PcdSet32S (PcdConOutColumn, mSetupTextModeColumn);
814377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong                  ASSERT_EFI_ERROR (Status);
815377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong                  Status = PcdSet32S (PcdConOutRow, mSetupTextModeRow);
816377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong                  ASSERT_EFI_ERROR (Status);
817a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  FreePool (Info);
818a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                  return EFI_SUCCESS;
819a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                }
820a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni              }
821a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            }
822a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            if (Index == MaxTextMode) {
823a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni              //
824a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni              // If requried text mode is not supported, return error.
825a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni              //
826a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni              FreePool (Info);
827a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni              return EFI_UNSUPPORTED;
828a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            }
829a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          }
830a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        } else {
831a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          //
832a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          // If current video resolution is not same with the new one, set new video resolution.
833a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          // In this case, the driver which produces simple text out need be restarted.
834a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          //
835a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
836a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          if (!EFI_ERROR (Status)) {
837a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            FreePool (Info);
838a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni            break;
839a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          }
840a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        }
841a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      }
842a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      FreePool (Info);
843a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
844a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
845a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
846a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (ModeNumber == MaxGopMode) {
847a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
848a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    // If the resolution is not supported, return error.
849a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
850a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    return EFI_UNSUPPORTED;
851a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
852a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
853a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
854a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Set PCD to Inform GraphicsConsole to change video resolution.
855a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Set PCD to Inform Consplitter to change text mode.
856a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
857377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong  Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);
858377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong  ASSERT_EFI_ERROR (Status);
859377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong  Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);
860377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong  ASSERT_EFI_ERROR (Status);
861377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong  Status = PcdSet32S (PcdConOutColumn, NewColumns);
862377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong  ASSERT_EFI_ERROR (Status);
863377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong  Status = PcdSet32S (PcdConOutRow, NewRows);
864377680ae64bd6f702bfac7c98e65f73019b7d285Eric Dong  ASSERT_EFI_ERROR (Status);
865a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
866a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
867a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Video mode is changed, so restart graphics console driver and higher level driver.
868a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Reconnect graphics console driver and higher level driver.
869a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Locate all the handles with GOP protocol and reconnect it.
870a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
871a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Status = gBS->LocateHandleBuffer (
872a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                   ByProtocol,
873a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                   &gEfiSimpleTextOutProtocolGuid,
874a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                   NULL,
875a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                   &HandleCount,
876a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                   &HandleBuffer
877a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                   );
878a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (!EFI_ERROR (Status)) {
879a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    for (Index = 0; Index < HandleCount; Index++) {
880a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
881a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
882a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    for (Index = 0; Index < HandleCount; Index++) {
883a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
884a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
885a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (HandleBuffer != NULL) {
886a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      FreePool (HandleBuffer);
887a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
888a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
889a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
890a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  return EFI_SUCCESS;
891a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
892a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
893a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni/**
894a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Display the boot popup menu and allow user select boot item.
895a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
896a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param   ImageHandle     The image handle.
897a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @param   SystemTable     The system table.
898a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
899a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval  EFI_SUCCESS          Boot from selected boot option, and return success from boot option
900a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  @retval  EFI_NOT_FOUND        User select to enter setup or can not find boot option
901a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
902a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni**/
903a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiEFI_STATUS
904a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiEFIAPI
905a382952f8255863116dde495f0b1eaf9925287a0Ruiyu NiBootManagerMenuEntry (
906a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN EFI_HANDLE                            ImageHandle,
907a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  IN EFI_SYSTEM_TABLE                      *SystemTable
908a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  )
909a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni{
910a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_BOOT_MANAGER_LOAD_OPTION    *BootOption;
911a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                           BootOptionCount;
912a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_STATUS                      Status;
913a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BOOT_MENU_POPUP_DATA            BootMenuData;
914a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                           Index;
915a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_INPUT_KEY                   Key;
916a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BOOLEAN                         ExitApplication;
917a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                           SelectItem;
918a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_BOOT_LOGO_PROTOCOL          *BootLogo;
919a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_GRAPHICS_OUTPUT_PROTOCOL    *GraphicsOutput;
920a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
921a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                           BootTextColumn;
922a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  UINTN                           BootTextRow;
923a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
924a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
925a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Set Logo status invalid when boot manager menu is launched
926a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
927a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootLogo = NULL;
928a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
929a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (!EFI_ERROR (Status) && (BootLogo != NULL)) {
930a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    Status = BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
931a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    ASSERT_EFI_ERROR (Status);
932a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
933a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
934a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
935a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
936a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  gStringPackHandle = HiiAddPackages (
937a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                         &gEfiCallerIdGuid,
938a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                         gImageHandle,
939a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                         BootManagerMenuAppStrings,
940a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                         NULL
941a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                         );
942a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  ASSERT (gStringPackHandle != NULL);
943a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
944a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
945a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Connect all prior to entering the platform setup menu.
946a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
947a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EfiBootManagerConnectAll ();
948a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EfiBootManagerRefreshAllBootOption ();
949a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
950a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BootOption = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
951a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
952a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  if (!mModeInitialized) {
953a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
954a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    // After the console is ready, get current video resolution
955a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    // and text mode before launching setup at first time.
956a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
957a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    Status = gBS->HandleProtocol (
958a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                    gST->ConsoleOutHandle,
959a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                    &gEfiGraphicsOutputProtocolGuid,
960a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                    (VOID**)&GraphicsOutput
961a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                    );
962a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (EFI_ERROR (Status)) {
963a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      GraphicsOutput = NULL;
964a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
965a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
966a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    Status = gBS->HandleProtocol (
967a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                    gST->ConsoleOutHandle,
968a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                    &gEfiSimpleTextOutProtocolGuid,
969a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                    (VOID**)&SimpleTextOut
970a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                    );
971a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (EFI_ERROR (Status)) {
972a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      SimpleTextOut = NULL;
973a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
974a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
975a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (GraphicsOutput != NULL) {
976a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      //
977a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      // Get current video resolution and text mode.
978a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      //
979a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
980a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      mBootVerticalResolution   = GraphicsOutput->Mode->Info->VerticalResolution;
981a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
982a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
983a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (SimpleTextOut != NULL) {
984a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      Status = SimpleTextOut->QueryMode (
985a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                SimpleTextOut,
986a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                SimpleTextOut->Mode->Mode,
987a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                &BootTextColumn,
988a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                &BootTextRow
989a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni                                );
990a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      mBootTextModeColumn = (UINT32)BootTextColumn;
991a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      mBootTextModeRow    = (UINT32)BootTextRow;
992a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
993a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
994a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
995a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    // Get user defined text mode for setup.
996a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    //
997a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
998a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    mSetupVerticalResolution   = PcdGet32 (PcdSetupVideoVerticalResolution);
999a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    mSetupTextModeColumn       = PcdGet32 (PcdSetupConOutColumn);
1000a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    mSetupTextModeRow          = PcdGet32 (PcdSetupConOutRow);
1001a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    mModeInitialized           = TRUE;
1002a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
1003a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1004a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
1005a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Set back to conventional setup resolution
1006a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
1007a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  BdsSetConsoleMode (TRUE);
1008a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1009a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
1010a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // Initialize Boot menu data
1011a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
1012a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  Status = InitializeBootMenuData (BootOption, BootOptionCount, &BootMenuData);
1013a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
1014a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // According to boot menu data to draw boot popup menu
1015a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
1016a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  DrawBootPopupMenu (&BootMenuData);
1017a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1018a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
1019a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  // check user input to determine want to re-draw or boot from user selected item
1020a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  //
1021a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  ExitApplication = FALSE;
1022a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  while (!ExitApplication) {
1023a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);
1024a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
1025a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    if (!EFI_ERROR (Status)) {
1026a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      switch (Key.UnicodeChar) {
1027a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1028a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      case CHAR_NULL:
1029a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        switch (Key.ScanCode) {
1030a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1031a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        case SCAN_UP:
1032a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          SelectItem = BootMenuData.SelectItem == 0 ? BootMenuData.ItemCount - 1 : BootMenuData.SelectItem - 1;
1033a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          BootMenuSelectItem (SelectItem, &BootMenuData);
1034a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          break;
1035a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1036a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        case SCAN_DOWN:
1037a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          SelectItem = BootMenuData.SelectItem == BootMenuData.ItemCount - 1 ? 0 : BootMenuData.SelectItem + 1;
1038a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          BootMenuSelectItem (SelectItem, &BootMenuData);
1039a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          break;
1040a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1041a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        case SCAN_ESC:
1042a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          gST->ConOut->ClearScreen (gST->ConOut);
1043a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          ExitApplication = TRUE;
1044a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          //
1045a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          // Set boot resolution for normal boot
1046a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          //
1047a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          BdsSetConsoleMode (FALSE);
1048a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          break;
1049a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1050a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        default:
1051a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni          break;
1052a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        }
1053a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        break;
1054a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1055a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      case CHAR_CARRIAGE_RETURN:
1056a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        gST->ConOut->ClearScreen (gST->ConOut);
1057a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        //
1058a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        // Set boot resolution for normal boot
1059a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        //
1060a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        BdsSetConsoleMode (FALSE);
1061a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        BootFromSelectOption (BootOption, BootOptionCount, BootMenuData.SelectItem);
1062a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        //
1063a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        // Back to boot manager menu again, set back to setup resolution
1064a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        //
1065a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        BdsSetConsoleMode (TRUE);
1066a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        DrawBootPopupMenu (&BootMenuData);
1067a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        break;
1068a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1069a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      default:
1070a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni        break;
1071a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni      }
1072a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni    }
1073a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  }
1074a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount);
1075a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  FreePool (BootMenuData.PtrTokens);
1076a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1077a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  HiiRemovePackages (gStringPackHandle);
1078a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1079a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni  return Status;
1080a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni
1081a382952f8255863116dde495f0b1eaf9925287a0Ruiyu Ni}
1082