X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FApplication%2FBootManagerMenuApp%2FBootManagerMenu.c;h=ef1931961432da8ee1481adfd1b38004de0dd64b;hb=1436aea4d5707e672672a11bda72be2c63c936c3;hp=a25f2ca298c758ee6e7e145b79ebe2cd25ed17b3;hpb=51a1db9b24d850c785d240da599c4bf9ba1c0fd3;p=mirror_edk2.git diff --git a/MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenu.c b/MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenu.c index a25f2ca298..ef19319614 100644 --- a/MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenu.c +++ b/MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenu.c @@ -1,37 +1,31 @@ /** @file The application to show the Boot Manager Menu. -Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "BootManagerMenu.h" -EFI_HII_HANDLE gStringPackHandle; +EFI_HII_HANDLE gStringPackHandle; -BOOLEAN mModeInitialized = FALSE; +BOOLEAN mModeInitialized = FALSE; // // Boot video resolution and text mode. // -UINT32 mBootHorizontalResolution = 0; -UINT32 mBootVerticalResolution = 0; -UINT32 mBootTextModeColumn = 0; -UINT32 mBootTextModeRow = 0; +UINT32 mBootHorizontalResolution = 0; +UINT32 mBootVerticalResolution = 0; +UINT32 mBootTextModeColumn = 0; +UINT32 mBootTextModeRow = 0; // // BIOS setup video resolution and text mode. // -UINT32 mSetupTextModeColumn = 0; -UINT32 mSetupTextModeRow = 0; -UINT32 mSetupHorizontalResolution = 0; -UINT32 mSetupVerticalResolution = 0; +UINT32 mSetupTextModeColumn = 0; +UINT32 mSetupTextModeRow = 0; +UINT32 mSetupHorizontalResolution = 0; +UINT32 mSetupVerticalResolution = 0; /** Prints a unicode string to the default console, at @@ -46,14 +40,61 @@ UINT32 mSetupVerticalResolution = 0; **/ UINTN PrintStringAt ( - IN UINTN Column, - IN UINTN Row, - IN CHAR16 *String + IN UINTN Column, + IN UINTN Row, + IN CHAR16 *String ) { + UINTN ScreenWidth; + UINTN ScreenRows; + CHAR16 *TurncateString; + EFI_STATUS Status; + UINTN ShowingLength; gST->ConOut->SetCursorPosition (gST->ConOut, Column, Row); - return Print (L"%s", String); + + gST->ConOut->QueryMode ( + gST->ConOut, + gST->ConOut->Mode->Mode, + &ScreenWidth, + &ScreenRows + ); + + if ((Column > (ScreenWidth - 1)) || (Row > (ScreenRows - 1))) { + return 0; + } + + if ((StrLen (String) + Column) > (ScreenWidth - 1)) { + // + // | - ScreenWidth - | + // ...Column..................... + // TurncateString length should leave one character for draw box and + // require one character for string end. + // + ShowingLength = ScreenWidth - Column - 1; + TurncateString = AllocatePool ((ShowingLength + 1) * sizeof (CHAR16)); + + if (TurncateString == NULL) { + return 0; + } + + Status = StrnCpyS (TurncateString, ShowingLength + 1, String, ShowingLength - 3); + + if (EFI_ERROR (Status)) { + FreePool (TurncateString); + return 0; + } + + *(TurncateString + ShowingLength - 3) = L'.'; + *(TurncateString + ShowingLength - 2) = L'.'; + *(TurncateString + ShowingLength - 1) = L'.'; + *(TurncateString + ShowingLength) = L'\0'; + ShowingLength = Print (L"%s", TurncateString); + FreePool (TurncateString); + return ShowingLength; + } else { + return Print (L"%s", String); + } } /** @@ -69,12 +110,27 @@ PrintStringAt ( **/ UINTN PrintCharAt ( - IN UINTN Column, - IN UINTN Row, - CHAR16 Character + IN UINTN Column, + IN UINTN Row, + CHAR16 Character ) { + UINTN ScreenWidth; + UINTN ScreenRows; + gST->ConOut->SetCursorPosition (gST->ConOut, Column, Row); + + gST->ConOut->QueryMode ( + gST->ConOut, + gST->ConOut->Mode->Mode, + &ScreenWidth, + &ScreenRows + ); + + if ((Column > (ScreenWidth - 1)) || (Row > (ScreenRows - 1))) { + return 0; + } + return Print (L"%c", Character); } @@ -89,37 +145,39 @@ PrintCharAt ( **/ UINTN GetLineWidth ( - IN EFI_STRING_ID StringId + IN EFI_STRING_ID StringId ) -{ - UINTN Index; - UINTN IncrementValue; - EFI_STRING String; - UINTN LineWidth; - +{ + UINTN Index; + UINTN IncrementValue; + EFI_STRING String; + UINTN LineWidth; + LineWidth = 0; - String = HiiGetString (gStringPackHandle, StringId, NULL); - + String = HiiGetString (gStringPackHandle, StringId, NULL); + if (String != NULL) { - Index = 0; - IncrementValue = 1; - + Index = 0; + IncrementValue = 1; + do { // // Advance to the null-terminator or to the first width directive // - for (; - (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0); - Index++, LineWidth = LineWidth + IncrementValue - ) - ; - + for ( ; + (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0); + Index++, LineWidth = LineWidth + IncrementValue + ) + { + } + // // We hit the null-terminator, we now have a count // if (String[Index] == 0) { break; } + // // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2) @@ -137,11 +195,12 @@ GetLineWidth ( Index++; IncrementValue = 2; } - } while (String[Index] != 0); + } while (String[Index] != 0); + FreePool (String); } - - return LineWidth; + + return LineWidth; } /** @@ -150,43 +209,45 @@ GetLineWidth ( @param BootMenuData The boot menu data to be processed. @return EFI_SUCCESS calculate boot menu information successful. - @retval EFI_INVALID_PARAMETER Input parameter is invalid + @retval EFI_INVALID_PARAMETER Input parameter is invalid **/ -EFI_STATUS +EFI_STATUS InitializeBootMenuScreen ( IN OUT BOOT_MENU_POPUP_DATA *BootMenuData ) { - UINTN MaxStrWidth; - UINTN StrWidth; - UINTN Index; - UINTN Column; - UINTN Row; - UINTN MaxPrintRows; - UINTN UnSelectableItmes; + UINTN MaxStrWidth; + UINTN StrWidth; + UINTN Index; + UINTN Column; + UINTN Row; + UINTN MaxPrintRows; + UINTN UnSelectableItmes; if (BootMenuData == NULL) { return EFI_INVALID_PARAMETER; } + // // Get maximum string width // - MaxStrWidth = 0; - for (Index = 0; Index < TITLE_TOKEN_COUNT; Index++) { - StrWidth = GetLineWidth (BootMenuData->TitleToken[Index]); + MaxStrWidth = 0; + for (Index = 0; Index < TITLE_TOKEN_COUNT; Index++) { + StrWidth = GetLineWidth (BootMenuData->TitleToken[Index]); MaxStrWidth = MaxStrWidth > StrWidth ? MaxStrWidth : StrWidth; } - + for (Index = 0; Index < BootMenuData->ItemCount; Index++) { - StrWidth = GetLineWidth (BootMenuData->PtrTokens[Index]); - MaxStrWidth = MaxStrWidth > StrWidth ? MaxStrWidth : StrWidth; - } - - for (Index = 0; Index < HELP_TOKEN_COUNT; Index++) { - StrWidth = GetLineWidth (BootMenuData->HelpToken[Index]); + StrWidth = GetLineWidth (BootMenuData->PtrTokens[Index]); + MaxStrWidth = MaxStrWidth > StrWidth ? MaxStrWidth : StrWidth; + } + + for (Index = 0; Index < HELP_TOKEN_COUNT; Index++) { + StrWidth = GetLineWidth (BootMenuData->HelpToken[Index]); MaxStrWidth = MaxStrWidth > StrWidth ? MaxStrWidth : StrWidth; - } + } + // // query current row and column to calculate boot menu location // @@ -195,52 +256,59 @@ InitializeBootMenuScreen ( gST->ConOut->Mode->Mode, &Column, &Row - ); - - MaxPrintRows = Row - 6; - UnSelectableItmes = TITLE_TOKEN_COUNT + 2 + HELP_TOKEN_COUNT + 2; - BootMenuData->MenuScreen.Width = MaxStrWidth + 8; + ); + + MaxPrintRows = Row - 6; + UnSelectableItmes = TITLE_TOKEN_COUNT + 2 + HELP_TOKEN_COUNT + 2; + if (MaxStrWidth + 8 > Column) { + BootMenuData->MenuScreen.Width = Column; + } else { + BootMenuData->MenuScreen.Width = MaxStrWidth + 8; + } + if (BootMenuData->ItemCount + UnSelectableItmes > MaxPrintRows) { - BootMenuData->MenuScreen.Height = MaxPrintRows; - BootMenuData->ScrollBarControl.HasScrollBar = TRUE; + BootMenuData->MenuScreen.Height = MaxPrintRows; + BootMenuData->ScrollBarControl.HasScrollBar = TRUE; BootMenuData->ScrollBarControl.ItemCountPerScreen = MaxPrintRows - UnSelectableItmes; - BootMenuData->ScrollBarControl.FirstItem = 0; - BootMenuData->ScrollBarControl.LastItem = MaxPrintRows - UnSelectableItmes - 1; + BootMenuData->ScrollBarControl.FirstItem = 0; + BootMenuData->ScrollBarControl.LastItem = MaxPrintRows - UnSelectableItmes - 1; } else { - BootMenuData->MenuScreen.Height = BootMenuData->ItemCount + UnSelectableItmes; - BootMenuData->ScrollBarControl.HasScrollBar = FALSE; + BootMenuData->MenuScreen.Height = BootMenuData->ItemCount + UnSelectableItmes; + BootMenuData->ScrollBarControl.HasScrollBar = FALSE; BootMenuData->ScrollBarControl.ItemCountPerScreen = BootMenuData->ItemCount; - BootMenuData->ScrollBarControl.FirstItem = 0; - BootMenuData->ScrollBarControl.LastItem = BootMenuData->ItemCount - 1; + BootMenuData->ScrollBarControl.FirstItem = 0; + BootMenuData->ScrollBarControl.LastItem = BootMenuData->ItemCount - 1; } - BootMenuData->MenuScreen.StartCol = (Column - BootMenuData->MenuScreen.Width) / 2; - BootMenuData->MenuScreen.StartRow = (Row - BootMenuData->MenuScreen.Height) / 2; + + BootMenuData->MenuScreen.StartCol = (Column - BootMenuData->MenuScreen.Width) / 2; + BootMenuData->MenuScreen.StartRow = (Row - BootMenuData->MenuScreen.Height) / 2; return EFI_SUCCESS; } + /** This function uses check boot option is wheher setup application or no @param BootOption Pointer to EFI_BOOT_MANAGER_LOAD_OPTION array. - + @retval TRUE This boot option is setup application. @retval FALSE This boot options isn't setup application **/ BOOLEAN IsBootManagerMenu ( - IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption + IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption ) { - EFI_STATUS Status; - EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu; + EFI_STATUS Status; + EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu; Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu); if (!EFI_ERROR (Status)) { EfiBootManagerFreeLoadOption (&BootManagerMenu); } - return (BOOLEAN) (!EFI_ERROR (Status) && (BootOption->OptionNumber == BootManagerMenu.OptionNumber)); + return (BOOLEAN)(!EFI_ERROR (Status) && (BootOption->OptionNumber == BootManagerMenu.OptionNumber)); } /** @@ -256,13 +324,13 @@ IgnoreBootOption ( IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOption ) { - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; // // Ignore myself. // - Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageDevicePathProtocolGuid, (VOID **) &ImageDevicePath); + Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageDevicePathProtocolGuid, (VOID **)&ImageDevicePath); ASSERT_EFI_ERROR (Status); if (CompareMem (BootOption->FilePath, ImageDevicePath, GetDevicePathSize (ImageDevicePath)) == 0) { return TRUE; @@ -291,9 +359,9 @@ IgnoreBootOption ( @param BootOption Pointer to EFI_BOOT_MANAGER_LOAD_OPTION array. @param BootOptionCount Number of boot option. @param BootMenuData The Input BootMenuData to be initialized. - + @retval EFI_SUCCESS Initialize boot menu data successful. - @retval EFI_INVALID_PARAMETER Input parameter is invalid. + @retval EFI_INVALID_PARAMETER Input parameter is invalid. **/ EFI_STATUS @@ -303,10 +371,10 @@ InitializeBootMenuData ( OUT BOOT_MENU_POPUP_DATA *BootMenuData ) { - UINTN Index; - UINTN StrIndex; - - if (BootOption == NULL || BootMenuData == NULL) { + UINTN Index; + UINTN StrIndex; + + if ((BootOption == NULL) || (BootMenuData == NULL)) { return EFI_INVALID_PARAMETER; } @@ -324,21 +392,21 @@ InitializeBootMenuData ( ASSERT (BootOption[Index].Description != NULL); BootMenuData->PtrTokens[StrIndex++] = HiiSetString ( - gStringPackHandle, + gStringPackHandle, 0, BootOption[Index].Description, NULL ); } - BootMenuData->ItemCount = StrIndex; + BootMenuData->ItemCount = StrIndex; BootMenuData->HelpToken[0] = STRING_TOKEN (STR_BOOT_POPUP_MENU_HELP1_STRING); BootMenuData->HelpToken[1] = STRING_TOKEN (STR_BOOT_POPUP_MENU_HELP2_STRING); BootMenuData->HelpToken[2] = STRING_TOKEN (STR_BOOT_POPUP_MENU_HELP3_STRING); InitializeBootMenuScreen (BootMenuData); BootMenuData->SelectItem = 0; return EFI_SUCCESS; -} +} /** This function uses input select item to highlight selected item @@ -347,9 +415,9 @@ InitializeBootMenuData ( @param WantSelectItem The user wants to select item. @param BootMenuData The boot menu data to be processed - @return EFI_SUCCESS Highlight selected item and update current selected - item successful - @retval EFI_INVALID_PARAMETER Input parameter is invalid + @return EFI_SUCCESS Highlight selected item and update current selected + item successful + @retval EFI_INVALID_PARAMETER Input parameter is invalid **/ EFI_STATUS BootMenuSelectItem ( @@ -357,129 +425,138 @@ BootMenuSelectItem ( IN OUT BOOT_MENU_POPUP_DATA *BootMenuData ) { - INT32 SavedAttribute; - EFI_STRING String; - UINTN StartCol; - UINTN StartRow; - UINTN PrintCol; - UINTN PrintRow; - UINTN TopShadeNum; - UINTN LowShadeNum; - UINTN FirstItem; - UINTN LastItem; - UINTN ItemCountPerScreen; - UINTN Index; - BOOLEAN RePaintItems; - - if (BootMenuData == NULL || WantSelectItem >= BootMenuData->ItemCount) { + INT32 SavedAttribute; + EFI_STRING String; + UINTN StartCol; + UINTN StartRow; + UINTN PrintCol; + UINTN PrintRow; + UINTN TopShadeNum; + UINTN LowShadeNum; + UINTN FirstItem; + UINTN LastItem; + UINTN ItemCountPerScreen; + UINTN Index; + BOOLEAN RePaintItems; + + if ((BootMenuData == NULL) || (WantSelectItem >= BootMenuData->ItemCount)) { return EFI_INVALID_PARAMETER; } + ASSERT (BootMenuData->ItemCount != 0); SavedAttribute = gST->ConOut->Mode->Attribute; - RePaintItems = FALSE; - StartCol = BootMenuData->MenuScreen.StartCol; - StartRow = BootMenuData->MenuScreen.StartRow; + RePaintItems = FALSE; + StartCol = BootMenuData->MenuScreen.StartCol; + StartRow = BootMenuData->MenuScreen.StartRow; // // print selectable items again and adjust scroll bar if need - // + // if (BootMenuData->ScrollBarControl.HasScrollBar && - (WantSelectItem < BootMenuData->ScrollBarControl.FirstItem || - WantSelectItem > BootMenuData->ScrollBarControl.LastItem || - WantSelectItem == BootMenuData->SelectItem)) { - ItemCountPerScreen = BootMenuData->ScrollBarControl.ItemCountPerScreen; + ((WantSelectItem < BootMenuData->ScrollBarControl.FirstItem) || + (WantSelectItem > BootMenuData->ScrollBarControl.LastItem) || + (WantSelectItem == BootMenuData->SelectItem))) + { + ItemCountPerScreen = BootMenuData->ScrollBarControl.ItemCountPerScreen; // // Set first item and last item - // + // if (WantSelectItem < BootMenuData->ScrollBarControl.FirstItem) { BootMenuData->ScrollBarControl.FirstItem = WantSelectItem; - BootMenuData->ScrollBarControl.LastItem = WantSelectItem + ItemCountPerScreen - 1; + BootMenuData->ScrollBarControl.LastItem = WantSelectItem + ItemCountPerScreen - 1; } else if (WantSelectItem > BootMenuData->ScrollBarControl.LastItem) { - BootMenuData->ScrollBarControl.FirstItem = WantSelectItem - ItemCountPerScreen + 1; - BootMenuData->ScrollBarControl.LastItem = WantSelectItem; + BootMenuData->ScrollBarControl.FirstItem = WantSelectItem - ItemCountPerScreen + 1; + BootMenuData->ScrollBarControl.LastItem = WantSelectItem; } + gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLUE); - FirstItem = BootMenuData->ScrollBarControl.FirstItem; - LastItem = BootMenuData->ScrollBarControl.LastItem; + FirstItem = BootMenuData->ScrollBarControl.FirstItem; + LastItem = BootMenuData->ScrollBarControl.LastItem; TopShadeNum = 0; if (FirstItem != 0) { TopShadeNum = (FirstItem * ItemCountPerScreen) / BootMenuData->ItemCount; if ((FirstItem * ItemCountPerScreen) % BootMenuData->ItemCount != 0) { TopShadeNum++; } + PrintCol = StartCol + BootMenuData->MenuScreen.Width - 2; - PrintRow = StartRow + TITLE_TOKEN_COUNT + 2; + PrintRow = StartRow + TITLE_TOKEN_COUNT + 2; for (Index = 0; Index < TopShadeNum; Index++, PrintRow++) { PrintCharAt (PrintCol, PrintRow, BLOCKELEMENT_LIGHT_SHADE); } } + LowShadeNum = 0; if (LastItem != BootMenuData->ItemCount - 1) { LowShadeNum = ((BootMenuData->ItemCount - 1 - LastItem) * ItemCountPerScreen) / BootMenuData->ItemCount; if (((BootMenuData->ItemCount - 1 - LastItem) * ItemCountPerScreen) % BootMenuData->ItemCount != 0) { LowShadeNum++; } + PrintCol = StartCol + BootMenuData->MenuScreen.Width - 2; - PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + ItemCountPerScreen - LowShadeNum; + PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + ItemCountPerScreen - LowShadeNum; for (Index = 0; Index < LowShadeNum; Index++, PrintRow++) { PrintCharAt (PrintCol, PrintRow, BLOCKELEMENT_LIGHT_SHADE); - } + } } + PrintCol = StartCol + BootMenuData->MenuScreen.Width - 2; - PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + TopShadeNum; + PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + TopShadeNum; for (Index = TopShadeNum; Index < ItemCountPerScreen - LowShadeNum; Index++, PrintRow++) { PrintCharAt (PrintCol, PrintRow, BLOCKELEMENT_FULL_BLOCK); - } - + } // // Clear selectable items first // PrintCol = StartCol + 1; - PrintRow = StartRow + TITLE_TOKEN_COUNT + 2; - String = AllocateZeroPool ((BootMenuData->MenuScreen.Width - 2) * sizeof (CHAR16)); + PrintRow = StartRow + TITLE_TOKEN_COUNT + 2; + String = AllocateZeroPool ((BootMenuData->MenuScreen.Width - 2) * sizeof (CHAR16)); ASSERT (String != NULL); for (Index = 0; Index < BootMenuData->MenuScreen.Width - 3; Index++) { String[Index] = 0x20; - } - for (Index = 0; Index < ItemCountPerScreen; Index++) { - PrintStringAt (PrintCol, PrintRow + Index, String); } + + for (Index = 0; Index < ItemCountPerScreen; Index++) { + PrintStringAt (PrintCol, PrintRow + Index, String); + } + FreePool (String); // - // print selectable items + // print selectable items // for (Index = 0; Index < ItemCountPerScreen; Index++, PrintRow++) { String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[Index + FirstItem], NULL); PrintStringAt (PrintCol, PrintRow, String); - FreePool (String); + FreePool (String); } + RePaintItems = TRUE; } - - // - // Print want to select item - // - FirstItem = BootMenuData->ScrollBarControl.FirstItem; - gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLACK); - String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[WantSelectItem], NULL); - PrintCol = StartCol + 1; - PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + WantSelectItem - FirstItem; - PrintStringAt (PrintCol, PrintRow, String); - FreePool (String); - + // - // if Want Select and selected item isn't the same and doesn't re-draw selectable + // if Want Select and selected item isn't the same and doesn't re-draw selectable // items, clear select item // - if (WantSelectItem != BootMenuData->SelectItem && !RePaintItems) { + FirstItem = BootMenuData->ScrollBarControl.FirstItem; + if ((WantSelectItem != BootMenuData->SelectItem) && !RePaintItems) { gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLUE); - String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[BootMenuData->SelectItem], NULL); - PrintCol = StartCol + 1; - PrintRow = StartRow + 3 + BootMenuData->SelectItem - FirstItem; + String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[BootMenuData->SelectItem], NULL); + PrintCol = StartCol + 1; + PrintRow = StartRow + 3 + BootMenuData->SelectItem - FirstItem; PrintStringAt (PrintCol, PrintRow, String); - FreePool (String); + FreePool (String); } + // + // Print want to select item + // + gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLACK); + String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[WantSelectItem], NULL); + PrintCol = StartCol + 1; + PrintRow = StartRow + TITLE_TOKEN_COUNT + 2 + WantSelectItem - FirstItem; + PrintStringAt (PrintCol, PrintRow, String); + FreePool (String); + gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); BootMenuData->SelectItem = WantSelectItem; return EFI_SUCCESS; @@ -489,46 +566,47 @@ BootMenuSelectItem ( This function uses to draw boot popup menu @param BootMenuData The Input BootMenuData to be processed. - + @retval EFI_SUCCESS Draw boot popup menu successful. **/ -EFI_STATUS +EFI_STATUS DrawBootPopupMenu ( IN BOOT_MENU_POPUP_DATA *BootMenuData ) { - EFI_STRING String; - UINTN Index; - UINTN Width; - UINTN StartCol; - UINTN StartRow; - UINTN PrintRow; - UINTN PrintCol; - UINTN LineWidth; - INT32 SavedAttribute; - UINTN ItemCountPerScreen; + EFI_STRING String; + UINTN Index; + UINTN Width; + UINTN StartCol; + UINTN StartRow; + UINTN PrintRow; + UINTN PrintCol; + UINTN LineWidth; + INT32 SavedAttribute; + UINTN ItemCountPerScreen; gST->ConOut->ClearScreen (gST->ConOut); - + SavedAttribute = gST->ConOut->Mode->Attribute; gST->ConOut->SetAttribute (gST->ConOut, EFI_WHITE | EFI_BACKGROUND_BLUE); - Width = BootMenuData->MenuScreen.Width; - StartCol = BootMenuData->MenuScreen.StartCol; - StartRow = BootMenuData->MenuScreen.StartRow; + Width = BootMenuData->MenuScreen.Width; + StartCol = BootMenuData->MenuScreen.StartCol; + StartRow = BootMenuData->MenuScreen.StartRow; ItemCountPerScreen = BootMenuData->ScrollBarControl.ItemCountPerScreen; - PrintRow = StartRow; - + PrintRow = StartRow; + gST->ConOut->EnableCursor (gST->ConOut, FALSE); // // Draw Boot popup menu screen // PrintCharAt (StartCol, PrintRow, BOXDRAW_DOWN_RIGHT); for (Index = 1; Index < Width - 1; Index++) { - PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); + PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); } + PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_DOWN_LEFT); - + // // Draw the screen for title // @@ -540,18 +618,19 @@ DrawBootPopupMenu ( for (Index = 0; Index < TITLE_TOKEN_COUNT; Index++) { PrintRow++; - PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL); + PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL); PrintStringAt (StartCol + 1, PrintRow, String); PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL); } - + PrintRow++; PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL_RIGHT); for (Index = 1; Index < Width - 1; Index++) { - PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); + PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); } - PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL_LEFT); - + + PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL_LEFT); + // // Draw screen for selectable items // @@ -560,15 +639,16 @@ DrawBootPopupMenu ( PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL); PrintStringAt (StartCol + 1, PrintRow, String); PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL); - } + } PrintRow++; PrintCharAt (StartCol, PrintRow, BOXDRAW_VERTICAL_RIGHT); for (Index = 1; Index < Width - 1; Index++) { - PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); + PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); } + PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL_LEFT); - + // // Draw screen for Help // @@ -578,64 +658,65 @@ DrawBootPopupMenu ( PrintStringAt (StartCol + 1, PrintRow, String); PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_VERTICAL); } - FreePool (String); - - PrintRow++; + + FreePool (String); + + PrintRow++; PrintCharAt (StartCol, PrintRow, BOXDRAW_UP_RIGHT); for (Index = 1; Index < Width - 1; Index++) { - PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); + PrintCharAt (StartCol + Index, PrintRow, BOXDRAW_HORIZONTAL); } - PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_UP_LEFT); - - + + PrintCharAt (StartCol + Width - 1, PrintRow, BOXDRAW_UP_LEFT); + // // print title strings // PrintRow = StartRow + 1; for (Index = 0; Index < TITLE_TOKEN_COUNT; Index++, PrintRow++) { - String = HiiGetString (gStringPackHandle, BootMenuData->TitleToken[Index], NULL); - LineWidth = GetLineWidth (BootMenuData->TitleToken[Index]); - PrintCol = StartCol + (Width - LineWidth) / 2; + String = HiiGetString (gStringPackHandle, BootMenuData->TitleToken[Index], NULL); + LineWidth = GetLineWidth (BootMenuData->TitleToken[Index]); + PrintCol = StartCol + (Width - LineWidth) / 2; PrintStringAt (PrintCol, PrintRow, String); FreePool (String); } - + // // print selectable items // PrintCol = StartCol + 1; - PrintRow = StartRow + TITLE_TOKEN_COUNT + 2; + PrintRow = StartRow + TITLE_TOKEN_COUNT + 2; for (Index = 0; Index < ItemCountPerScreen; Index++, PrintRow++) { String = HiiGetString (gStringPackHandle, BootMenuData->PtrTokens[Index], NULL); PrintStringAt (PrintCol, PrintRow, String); - FreePool (String); + FreePool (String); } - + // // Print Help strings // PrintRow++; for (Index = 0; Index < HELP_TOKEN_COUNT; Index++, PrintRow++) { - String = HiiGetString (gStringPackHandle, BootMenuData->HelpToken[Index], NULL); + String = HiiGetString (gStringPackHandle, BootMenuData->HelpToken[Index], NULL); LineWidth = GetLineWidth (BootMenuData->HelpToken[Index]); - PrintCol = StartCol + (Width - LineWidth) / 2; + PrintCol = StartCol + (Width - LineWidth) / 2; PrintStringAt (PrintCol, PrintRow, String); FreePool (String); } - + // // Print scroll bar if has scroll bar // if (BootMenuData->ScrollBarControl.HasScrollBar) { PrintCol = StartCol + Width - 2; - PrintRow = StartRow + 2; - PrintCharAt (PrintCol, PrintRow, GEOMETRICSHAPE_UP_TRIANGLE); - PrintCharAt (PrintCol + 1, PrintRow, BOXDRAW_VERTICAL); - PrintRow += (ItemCountPerScreen + 1); + PrintRow = StartRow + 2; + PrintCharAt (PrintCol, PrintRow, GEOMETRICSHAPE_UP_TRIANGLE); + PrintCharAt (PrintCol + 1, PrintRow, BOXDRAW_VERTICAL); + PrintRow += (ItemCountPerScreen + 1); PrintCharAt (PrintCol, PrintRow, GEOMETRICSHAPE_DOWN_TRIANGLE); - PrintCharAt (PrintCol + 1, PrintRow, BOXDRAW_VERTICAL); - } - + PrintCharAt (PrintCol + 1, PrintRow, BOXDRAW_VERTICAL); + } + gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); // // Print Selected item @@ -645,7 +726,7 @@ DrawBootPopupMenu ( } /** - This function uses to boot from selected item + This function uses to boot from selected item @param BootOptions Pointer to EFI_BOOT_MANAGER_LOAD_OPTION array. @param BootOptionCount Number of boot option. @@ -654,12 +735,12 @@ DrawBootPopupMenu ( VOID BootFromSelectOption ( IN EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions, - IN UINTN BootOptionCount, + IN UINTN BootOptionCount, IN UINTN SelectItem ) { - UINTN ItemNum; - UINTN Index; + UINTN ItemNum; + UINTN Index; ASSERT (BootOptions != NULL); @@ -677,9 +758,9 @@ BootFromSelectOption ( /** This function will change video resolution and text mode - according to defined setup mode or defined boot mode + according to defined setup mode or defined boot mode - @param IsSetupMode Indicate mode is changed to setup mode or boot mode. + @param IsSetupMode Indicate mode is changed to setup mode or boot mode. @retval EFI_SUCCESS Mode is changed successfully. @retval Others Mode failed to be changed. @@ -707,18 +788,18 @@ BdsSetConsoleMode ( EFI_STATUS Status; UINTN Index; UINTN CurrentColumn; - UINTN CurrentRow; + UINTN CurrentRow; MaxGopMode = 0; MaxTextMode = 0; // - // Get current video resolution and text mode + // Get current video resolution and text mode // Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, - (VOID**)&GraphicsOutput + (VOID **)&GraphicsOutput ); if (EFI_ERROR (Status)) { GraphicsOutput = NULL; @@ -727,11 +808,11 @@ BdsSetConsoleMode ( Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiSimpleTextOutProtocolGuid, - (VOID**)&SimpleTextOut + (VOID **)&SimpleTextOut ); if (EFI_ERROR (Status)) { SimpleTextOut = NULL; - } + } if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) { return EFI_UNSUPPORTED; @@ -752,12 +833,12 @@ BdsSetConsoleMode ( NewHorizontalResolution = mBootHorizontalResolution; NewVerticalResolution = mBootVerticalResolution; NewColumns = mBootTextModeColumn; - NewRows = mBootTextModeRow; + NewRows = mBootTextModeRow; } - + if (GraphicsOutput != NULL) { - MaxGopMode = GraphicsOutput->Mode->MaxMode; - } + MaxGopMode = GraphicsOutput->Mode->MaxMode; + } if (SimpleTextOut != NULL) { MaxTextMode = SimpleTextOut->Mode->MaxMode; @@ -772,22 +853,24 @@ BdsSetConsoleMode ( // for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) { Status = GraphicsOutput->QueryMode ( - GraphicsOutput, - ModeNumber, - &SizeOfInfo, - &Info - ); + GraphicsOutput, + ModeNumber, + &SizeOfInfo, + &Info + ); if (!EFI_ERROR (Status)) { if ((Info->HorizontalResolution == NewHorizontalResolution) && - (Info->VerticalResolution == NewVerticalResolution)) { + (Info->VerticalResolution == NewVerticalResolution)) + { if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) && - (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) { + (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) + { // // Current resolution is same with required resolution, check if text mode need be set // Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow); ASSERT_EFI_ERROR (Status); - if (CurrentColumn == NewColumns && CurrentRow == NewRows) { + if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) { // // If current text mode is same with required text mode. Do nothing // @@ -799,7 +882,7 @@ BdsSetConsoleMode ( // for (Index = 0; Index < MaxTextMode; Index++) { Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow); - if (!EFI_ERROR(Status)) { + if (!EFI_ERROR (Status)) { if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) { // // Required text mode is supported, set it. @@ -818,6 +901,7 @@ BdsSetConsoleMode ( } } } + if (Index == MaxTextMode) { // // If required text mode is not supported, return error. @@ -838,6 +922,7 @@ BdsSetConsoleMode ( } } } + FreePool (Info); } } @@ -861,26 +946,28 @@ BdsSetConsoleMode ( ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdConOutRow, NewRows); ASSERT_EFI_ERROR (Status); - + // // Video mode is changed, so restart graphics console driver and higher level driver. // Reconnect graphics console driver and higher level driver. // Locate all the handles with GOP protocol and reconnect it. // Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleTextOutProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); + ByProtocol, + &gEfiSimpleTextOutProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); if (!EFI_ERROR (Status)) { for (Index = 0; Index < HandleCount; Index++) { gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); } + for (Index = 0; Index < HandleCount; Index++) { gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); } + if (HandleBuffer != NULL) { FreePool (HandleBuffer); } @@ -894,37 +981,37 @@ BdsSetConsoleMode ( @param ImageHandle The image handle. @param SystemTable The system table. - + @retval EFI_SUCCESS Boot from selected boot option, and return success from boot option @retval EFI_NOT_FOUND User select to enter setup or can not find boot option - + **/ EFI_STATUS EFIAPI BootManagerMenuEntry ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_BOOT_MANAGER_LOAD_OPTION *BootOption; - UINTN BootOptionCount; - EFI_STATUS Status; - BOOT_MENU_POPUP_DATA BootMenuData; - UINTN Index; - EFI_INPUT_KEY Key; - BOOLEAN ExitApplication; - UINTN SelectItem; - EFI_BOOT_LOGO_PROTOCOL *BootLogo; - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; - UINTN BootTextColumn; - UINTN BootTextRow; + EFI_BOOT_MANAGER_LOAD_OPTION *BootOption; + UINTN BootOptionCount; + EFI_STATUS Status; + BOOT_MENU_POPUP_DATA BootMenuData; + UINTN Index; + EFI_INPUT_KEY Key; + BOOLEAN ExitApplication; + UINTN SelectItem; + EFI_BOOT_LOGO_PROTOCOL *BootLogo; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; + UINTN BootTextColumn; + UINTN BootTextRow; // // Set Logo status invalid when boot manager menu is launched // BootLogo = NULL; - Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo); + Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **)&BootLogo); if (!EFI_ERROR (Status) && (BootLogo != NULL)) { Status = BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0); ASSERT_EFI_ERROR (Status); @@ -933,11 +1020,11 @@ BootManagerMenuEntry ( gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); gStringPackHandle = HiiAddPackages ( - &gEfiCallerIdGuid, - gImageHandle, - BootManagerMenuAppStrings, - NULL - ); + &gEfiCallerIdGuid, + gImageHandle, + BootManagerMenuAppStrings, + NULL + ); ASSERT (gStringPackHandle != NULL); // @@ -950,26 +1037,26 @@ BootManagerMenuEntry ( if (!mModeInitialized) { // - // After the console is ready, get current video resolution + // After the console is ready, get current video resolution // and text mode before launching setup at first time. // Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, - (VOID**)&GraphicsOutput + (VOID **)&GraphicsOutput ); if (EFI_ERROR (Status)) { GraphicsOutput = NULL; } - + Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiSimpleTextOutProtocolGuid, - (VOID**)&SimpleTextOut + (VOID **)&SimpleTextOut ); if (EFI_ERROR (Status)) { SimpleTextOut = NULL; - } + } if (GraphicsOutput != NULL) { // @@ -992,14 +1079,14 @@ BootManagerMenuEntry ( // // Get user defined text mode for setup. - // + // mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution); - mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution); + mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution); mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn); mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow); mModeInitialized = TRUE; } - + // // Set back to conventional setup resolution // @@ -1013,7 +1100,7 @@ BootManagerMenuEntry ( // According to boot menu data to draw boot popup menu // DrawBootPopupMenu (&BootMenuData); - + // // check user input to determine want to re-draw or boot from user selected item // @@ -1023,58 +1110,57 @@ BootManagerMenuEntry ( Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); if (!EFI_ERROR (Status)) { switch (Key.UnicodeChar) { - - case CHAR_NULL: - switch (Key.ScanCode) { - - case SCAN_UP: - SelectItem = BootMenuData.SelectItem == 0 ? BootMenuData.ItemCount - 1 : BootMenuData.SelectItem - 1; - BootMenuSelectItem (SelectItem, &BootMenuData); - break; - - case SCAN_DOWN: - SelectItem = BootMenuData.SelectItem == BootMenuData.ItemCount - 1 ? 0 : BootMenuData.SelectItem + 1; - BootMenuSelectItem (SelectItem, &BootMenuData); + case CHAR_NULL: + switch (Key.ScanCode) { + case SCAN_UP: + SelectItem = BootMenuData.SelectItem == 0 ? BootMenuData.ItemCount - 1 : BootMenuData.SelectItem - 1; + BootMenuSelectItem (SelectItem, &BootMenuData); + break; + + case SCAN_DOWN: + SelectItem = BootMenuData.SelectItem == BootMenuData.ItemCount - 1 ? 0 : BootMenuData.SelectItem + 1; + BootMenuSelectItem (SelectItem, &BootMenuData); + break; + + case SCAN_ESC: + gST->ConOut->ClearScreen (gST->ConOut); + ExitApplication = TRUE; + // + // Set boot resolution for normal boot + // + BdsSetConsoleMode (FALSE); + break; + + default: + break; + } + break; - case SCAN_ESC: + case CHAR_CARRIAGE_RETURN: gST->ConOut->ClearScreen (gST->ConOut); - ExitApplication = TRUE; // // Set boot resolution for normal boot // BdsSetConsoleMode (FALSE); + BootFromSelectOption (BootOption, BootOptionCount, BootMenuData.SelectItem); + // + // Back to boot manager menu again, set back to setup resolution + // + BdsSetConsoleMode (TRUE); + DrawBootPopupMenu (&BootMenuData); break; - + default: break; - } - break; - - case CHAR_CARRIAGE_RETURN: - gST->ConOut->ClearScreen (gST->ConOut); - // - // Set boot resolution for normal boot - // - BdsSetConsoleMode (FALSE); - BootFromSelectOption (BootOption, BootOptionCount, BootMenuData.SelectItem); - // - // Back to boot manager menu again, set back to setup resolution - // - BdsSetConsoleMode (TRUE); - DrawBootPopupMenu (&BootMenuData); - break; - - default: - break; } } } + EfiBootManagerFreeLoadOptions (BootOption, BootOptionCount); FreePool (BootMenuData.PtrTokens); HiiRemovePackages (gStringPackHandle); return Status; - }