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