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