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