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