From nobody Fri Dec 27 05:23:54 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1503304411371194.07991709157784; Mon, 21 Aug 2017 01:33:31 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id CA9DB21E2DA71; Mon, 21 Aug 2017 01:30:57 -0700 (PDT) Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 1645D2095B9C7 for ; Mon, 21 Aug 2017 01:30:57 -0700 (PDT) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga104.jf.intel.com with ESMTP; 21 Aug 2017 01:33:28 -0700 Received: from shwdeopenpsi114.ccr.corp.intel.com ([10.239.157.135]) by orsmga004.jf.intel.com with ESMTP; 21 Aug 2017 01:33:27 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,408,1498546800"; d="scan'208";a="121071560" From: Dandan Bi To: edk2-devel@lists.01.org Date: Mon, 21 Aug 2017 16:33:12 +0800 Message-Id: <1503304393-304300-3-git-send-email-dandan.bi@intel.com> X-Mailer: git-send-email 1.9.5.msysgit.1 In-Reply-To: <1503304393-304300-1-git-send-email-dandan.bi@intel.com> References: <1503304393-304300-1-git-send-email-dandan.bi@intel.com> Subject: [edk2] [PATCH V3 2/3] MdeModulePkg/DisplayEngine: Add implementation of HiiPopup protocol X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Dong , Liming Gao MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" V3: Separate DrawMessageBox() function into CalculatePopupPosition() DrawMessageBox() and GetUserSelection() three functions and refine related codes. Add the implementation of HiiPopup protocol in DisplayEngineDxe, since DisplayEngineDxe is responsible for drawing tasks. Cc: Eric Dong Cc: Liming Gao Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Dandan Bi --- .../DisplayEngineDxe/DisplayEngineDxe.inf | 4 +- .../Universal/DisplayEngineDxe/FormDisplay.c | 42 ++ .../Universal/DisplayEngineDxe/FormDisplay.h | 87 ++- .../Universal/DisplayEngineDxe/FormDisplayStr.uni | 20 +- MdeModulePkg/Universal/DisplayEngineDxe/Popup.c | 731 +++++++++++++++++= ++++ 5 files changed, 881 insertions(+), 3 deletions(-) create mode 100644 MdeModulePkg/Universal/DisplayEngineDxe/Popup.c diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf b= /MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf index bf5e8e5..fa7b2ca 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf +++ b/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf @@ -1,9 +1,9 @@ ## @file # The DXE driver produces FORM DISPLAY ENGIEN protocol. # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the B= SD License # which accompanies this distribution. The full text of the license may b= e found at # http://opensource.org/licenses/bsd-license.php @@ -33,10 +33,11 @@ FormDisplayStr.uni FormDisplay.c FormDisplay.h ProcessOptions.c InputHandler.c + Popup.c =20 [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec =20 @@ -52,10 +53,11 @@ CustomizedDisplayLib =20 [Protocols] gEdkiiFormDisplayEngineProtocolGuid ## PRODUCES gEdkiiFormBrowserEx2ProtocolGuid ## CONSUMES + gEfiHiiPopupProtocolGuid ## PRODUCES =20 [Depex] gEfiHiiDatabaseProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid AND gEd= kiiFormBrowserEx2ProtocolGuid =20 [FeaturePcd] diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeMod= ulePkg/Universal/DisplayEngineDxe/FormDisplay.c index dc4ae4b..8b2beaa 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c @@ -149,10 +149,19 @@ CHAR16 *gConfirmDefaultMsg2nd; CHAR16 *gConfirmResetMsg2nd; CHAR16 *gConfirmExitMsg2nd; CHAR16 *gConfirmOpt; CHAR16 *gConfirmOptYes; CHAR16 *gConfirmOptNo; +CHAR16 *gConfirmOptOk; +CHAR16 *gConfirmOptCancel; +CHAR16 *gYesOption; +CHAR16 *gNoOption; +CHAR16 *gOkOption; +CHAR16 *gCancelOption; +CHAR16 *gErrorPopup; +CHAR16 *gWarningPopup; +CHAR16 *gInfoPopup; CHAR16 *gConfirmMsgConnect; CHAR16 *gConfirmMsgEnd; CHAR16 *gPasswordUnsupported; CHAR16 gModalSkipColumn; CHAR16 gPromptBlockWidth; @@ -165,10 +174,14 @@ FORM_DISPLAY_DRIVER_PRIVATE_DATA mPrivateData =3D { NULL, { FormDisplay, DriverClearDisplayPage, ConfirmDataChange + }, + { + EFI_HII_POPUP_PROTOCOL_REVISION, + CreatePopup } }; =20 =20 /** @@ -245,10 +258,19 @@ InitializeDisplayStrings ( gConfirmResetMsg2nd =3D GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE_= 2ND), gHiiHandle); gConfirmExitMsg2nd =3D GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE_2= ND), gHiiHandle); gConfirmOpt =3D GetToken (STRING_TOKEN (CONFIRM_OPTION), gHiiH= andle); gConfirmOptYes =3D GetToken (STRING_TOKEN (CONFIRM_OPTION_YES), g= HiiHandle); gConfirmOptNo =3D GetToken (STRING_TOKEN (CONFIRM_OPTION_NO), gH= iiHandle); + gConfirmOptOk =3D GetToken (STRING_TOKEN (CONFIRM_OPTION_OK), gH= iiHandle); + gConfirmOptCancel =3D GetToken (STRING_TOKEN (CONFIRM_OPTION_CANCEL)= , gHiiHandle); + gYesOption =3D GetToken (STRING_TOKEN (YES_SELECTABLE_OPTION)= , gHiiHandle); + gNoOption =3D GetToken (STRING_TOKEN (NO_SELECTABLE_OPTION),= gHiiHandle); + gOkOption =3D GetToken (STRING_TOKEN (OK_SELECTABLE_OPTION),= gHiiHandle); + gCancelOption =3D GetToken (STRING_TOKEN (CANCEL_SELECTABLE_OPTI= ON), gHiiHandle); + gErrorPopup =3D GetToken (STRING_TOKEN (ERROR_POPUP_STRING), g= HiiHandle); + gWarningPopup =3D GetToken (STRING_TOKEN (WARNING_POPUP_STRING),= gHiiHandle); + gInfoPopup =3D GetToken (STRING_TOKEN (INFO_POPUP_STRING), gH= iiHandle); gConfirmMsgConnect =3D GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT= ), gHiiHandle); gConfirmMsgEnd =3D GetToken (STRING_TOKEN (CONFIRM_OPTION_END), g= HiiHandle); gPasswordUnsupported =3D GetToken (STRING_TOKEN (PASSWORD_NOT_SUPPORTED= ), gHiiHandle); } =20 @@ -299,10 +321,19 @@ FreeDisplayStrings ( FreePool (gConfirmResetMsg2nd); FreePool (gConfirmExitMsg2nd); FreePool (gConfirmOpt); FreePool (gConfirmOptYes); FreePool (gConfirmOptNo); + FreePool (gConfirmOptOk); + FreePool (gConfirmOptCancel); + FreePool (gYesOption); + FreePool (gNoOption); + FreePool (gOkOption); + FreePool (gCancelOption); + FreePool (gErrorPopup); + FreePool (gWarningPopup); + FreePool (gInfoPopup); FreePool (gConfirmMsgConnect); FreePool (gConfirmMsgEnd); FreePool (gPasswordUnsupported); } =20 @@ -4117,10 +4148,21 @@ InitializeDisplayEngine ( EFI_NATIVE_INTERFACE, &mPrivateData.FromDisplayProt ); ASSERT_EFI_ERROR (Status); =20 + // + // Install HII Popup Protocol. + // + Status =3D gBS->InstallProtocolInterface ( + &mPrivateData.Handle, + &gEfiHiiPopupProtocolGuid, + EFI_NATIVE_INTERFACE, + &mPrivateData.HiiPopup + ); + ASSERT_EFI_ERROR (Status); + InitializeDisplayStrings(); =20 ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo)); ZeroMem (&gOldFormEntry, sizeof (gOldFormEntry)); =20 diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h b/MdeMod= ulePkg/Universal/DisplayEngineDxe/FormDisplay.h index 45532ab..4231cb8 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h @@ -1,9 +1,9 @@ /** @file FormDiplay protocol to show Form =20 -Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
+Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made availabl= e under=20 the terms and conditions of the BSD License that accompanies this distribu= tion. =20 The full text of the license may be found at http://opensource.org/licenses/bsd-license.php. = =20 =20 @@ -26,10 +26,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITH= ER EXPRESS OR IMPLIED. #include =20 #include #include #include +#include =20 #include =20 // // This is the generated header file which includes whatever needs to be e= xported (strings + IFR) @@ -39,10 +40,21 @@ extern EFI_SCREEN_DESCRIPTOR gStatementDimensio= ns; extern USER_INPUT *gUserInput; extern FORM_DISPLAY_ENGINE_FORM *gFormData; extern EFI_HII_HANDLE gHiiHandle; extern UINT16 gDirection; extern LIST_ENTRY gMenuOption; +extern CHAR16 *gConfirmOptYes; +extern CHAR16 *gConfirmOptNo; +extern CHAR16 *gConfirmOptOk; +extern CHAR16 *gConfirmOptCancel; +extern CHAR16 *gYesOption; +extern CHAR16 *gNoOption; +extern CHAR16 *gOkOption; +extern CHAR16 *gCancelOption; +extern CHAR16 *gErrorPopup; +extern CHAR16 *gWarningPopup; +extern CHAR16 *gInfoPopup; =20 // // Browser Global Strings // extern CHAR16 *gSaveFailed; @@ -137,10 +149,11 @@ typedef struct { =20 // // Produced protocol // EDKII_FORM_DISPLAY_ENGINE_PROTOCOL FromDisplayProt; + EFI_HII_POPUP_PROTOCOL HiiPopup; } FORM_DISPLAY_DRIVER_PRIVATE_DATA; =20 =20 typedef enum { UiNoOperation, @@ -270,10 +283,55 @@ typedef struct { BOOLEAN NestInStatement; } UI_MENU_OPTION; =20 #define MENU_OPTION_FROM_LINK(a) CR (a, UI_MENU_OPTION, Link, UI_MENU_OPT= ION_SIGNATURE) =20 +#define USER_SELECTABLE_OPTION_OK_WIDTH StrLen (gOkOption) +#define USER_SELECTABLE_OPTION_OK_CAL_WIDTH (StrLen (gOkOption) + St= rLen (gCancelOption)) +#define USER_SELECTABLE_OPTION_YES_NO_WIDTH (StrLen (gYesOption) + S= trLen (gNoOption)) +#define USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH (StrLen (gYesOption) + S= trLen (gNoOption) + StrLen (gCancelOption)) + +#define USER_SELECTABLE_OPTION_SKIP_WIDTH 2 + +#define POPUP_BORDER 1 +#define POPUP_EMPTY_LINE_HEIGHT 1 +#define POPUP_STYLE_STRING_HEIGHT 1 +#define POPUP_USER_SELECTABLE_OPTION_HEIGHT 1 + +#define POPUP_HEADER_HEIGHT (POPUP_BORDER + POPUP_STYLE_STRING_HEIGHT + P= OPUP_EMPTY_LINE_HEIGHT) +#define POPUP_FOOTER_HEIGHT (POPUP_EMPTY_LINE_HEIGHT + POPUP_USER_SELECTA= BLE_OPTION_HEIGHT + POPUP_BORDER) + +#define USER_SELECTABLE_OPTION_SIGNATURE SIGNATURE_32 ('u', 's', 's', 'o') + +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + EFI_HII_POPUP_SELECTION OptionType; + CHAR16 *OptionString; + // + // Display item sequence for user select options + // Ok: Ok + // Sequence: 0 + // + // Ok/Cancel: Ok : Cancel + // Sequence: 0 1 + // + // Yes/No: Yes : No + // Sequence: 0 1 + // + // Yes/No/Cancel: Yes : No: Cancel + // Sequence: 0 1 2 + // + UINTN Sequence; + UINTN OptionRow; + UINTN OptionCol; + UINTN MaxSequence; + UINTN MinSequence; +} USER_SELECTABLE_OPTION; + +#define SELECTABLE_OPTION_FROM_LINK(a) CR (a, USER_SELECTABLE_OPTION, Lin= k, USER_SELECTABLE_OPTION_SIGNATURE) + /** Print Question Value according to it's storage width and display attribu= tes. =20 @param Question The Question to be printed. @param FormattedNumber Buffer for output string. @@ -648,6 +706,33 @@ UpdateHighlightMenuInfo ( IN LIST_ENTRY *Highlight, IN LIST_ENTRY *TopOfScreen, IN UINTN SkipValue ); =20 +/** + Displays a popup window. + + @param This A pointer to the EFI_HII_POPUP_PROTOCOL instance. + @param PopupStyle Popup style to use. + @param PopupType Type of the popup to display. + @param HiiHandle HII handle of the string pack containing Message + @param Message A message to display in the popup box. + @param UserSelection User selection. + + @retval EFI_SUCCESS The popup box was successfully displayed. + @retval EFI_INVALID_PARAMETER HiiHandle and Message do not define a val= id HII string. + @retval EFI_INVALID_PARAMETER PopupType is not one of the values define= d by this specification. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available = to display the popup box. + +**/ +EFI_STATUS +EFIAPI +CreatePopup ( + IN EFI_HII_POPUP_PROTOCOL *This, + IN EFI_HII_POPUP_STYLE PopupStyle, + IN EFI_HII_POPUP_TYPE PopupType, + IN EFI_HII_HANDLE HiiHandle, + IN EFI_STRING_ID Message, + OUT EFI_HII_POPUP_SELECTION *UserSelection OPTIONAL + ); + #endif diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni b/M= deModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni index bd9c8b4..5020cfb 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni @@ -1,8 +1,8 @@ // *++ // -// Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.
+// Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.
// This program and the accompanying materials // are licensed and made available under the terms and conditions of the B= SD License // which accompanies this distribution. The full text of the license may = be found at // http://opensource.org/licenses/bsd-license.php // @@ -101,10 +101,14 @@ #language fr-FR "Press 'Y' to conf= irm, 'N'/'ESC' to ignore." #string CONFIRM_OPTION_YES #language en-US "Y (y)" #language fr-FR "Y (y)" #string CONFIRM_OPTION_NO #language en-US "N (n)" #language fr-FR "N (n)" +#string CONFIRM_OPTION_OK #language en-US "O (o)" + #language fr-FR "O (o)" +#string CONFIRM_OPTION_CANCEL #language en-US "C (c)" + #language fr-FR "C (c)" #string CONFIRM_OPTION_CONNECT #language en-US " and " #language fr-FR " and " #string CONFIRM_OPTION_END #language en-US "?" #language fr-FR "?" #string RECONNECT_FAILED #language en-US "Reconnect the con= troller failed!" @@ -117,6 +121,20 @@ #language fr-FR "Reconnect is requ= ired, exit and reconnect" #string GET_TIME_FAIL #language en-US " Get date/time fa= il, display ??." #language fr-FR " Get data/time fa= il, display ??." #string PASSWORD_NOT_SUPPORTED #language en-US "Unsupported! Beca= use no interactieve flag or no ConfigAccess protocol!" #language fr-FR "Unsupported! Beca= use no interactieve flag or no ConfigAccess protocol!" +#string OK_SELECTABLE_OPTION #language en-US "[ Ok ]" + #language fr-FR "[ Ok ]" +#string CANCEL_SELECTABLE_OPTION #language en-US "[Cancel]" + #language fr-FR "[Cancel]" +#string YES_SELECTABLE_OPTION #language en-US "[ Yes ]" + #language fr-FR "[ Yes ]" +#string NO_SELECTABLE_OPTION #language en-US "[ No ]" + #language fr-FR "[ No ]" +#string ERROR_POPUP_STRING #language en-US "ERROR" + #language fr-FR "ERROR" +#string WARNING_POPUP_STRING #language en-US "WARNING" + #language fr-FR "WARNING" +#string INFO_POPUP_STRING #language en-US "INFO" + #language fr-FR "INFO" =20 diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/Popup.c b/MdeModulePkg= /Universal/DisplayEngineDxe/Popup.c new file mode 100644 index 0000000..5472b7e --- /dev/null +++ b/MdeModulePkg/Universal/DisplayEngineDxe/Popup.c @@ -0,0 +1,731 @@ +/** @file +Implementation for Hii Popup Protocol. + +Copyright (c) 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 IMPLI= ED. + +**/ + +#include "FormDisplay.h" + +EFI_SCREEN_DESCRIPTOR gPopupDimensions; +LIST_ENTRY gUserSelectableOptions; +EFI_STRING gMessageString; +UINTN gMesStrLineNum; +UINTN gMaxRowWidth; + +/** + Free the user selectable option structure data. + + @param OptionList Point to the selectable option list which need to be= freed. + +**/ +VOID +FreeSelectableOptions( + LIST_ENTRY *OptionList + ) +{ + LIST_ENTRY *Link; + USER_SELECTABLE_OPTION *SelectableOption; + + while (!IsListEmpty (OptionList)) { + Link =3D GetFirstNode (OptionList); + SelectableOption =3D SELECTABLE_OPTION_FROM_LINK (Link); + RemoveEntryList (&SelectableOption->Link); + FreePool (SelectableOption); + } +} + +/** + Display one selectable option. + + @param SelectableOption The selectable option need to be drew. + @param Highlight Whether the option need to be highlighted. + +**/ +VOID +DisplayOneSelectableOption( + IN USER_SELECTABLE_OPTION *SelectableOption, + IN BOOLEAN Highlight + ) +{ + if (Highlight) { + gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ()); + } + PrintStringAt (SelectableOption->OptionCol, SelectableOption->OptionRow,= SelectableOption->OptionString); + gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); +} + +/** + Add one selectable option to option list. This is the work function for = AddUserSelectableOptions. + + @param PopupType The option need to be drew. + @param OptionType The type of this selection option. + @param OptionString Point to the option string that to be shown. + @param OptionCol The column that the option need to be drew at. + @param OptionRow The row that the option need to be drew at. + + @retval EFI_SUCCESS This function implement successfully. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available. + +**/ +EFI_STATUS +AddOneSelectableOption ( + IN EFI_HII_POPUP_TYPE PopupType, + IN EFI_HII_POPUP_SELECTION OptionType, + IN CHAR16 *OptionString, + IN UINTN OptionCol, + IN UINTN OptionRow + ) +{ + USER_SELECTABLE_OPTION *UserSelectableOption; + + UserSelectableOption =3D AllocateZeroPool (sizeof (USER_SELECTABLE_OPTIO= N)); + if (UserSelectableOption =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Initialize the user selectable option based on the PopupType and Opti= onType. + // And then add the option to the option list gUserSelectableOptions. + // + UserSelectableOption->Signature =3D USER_SELECTABLE_OPTION_SIGNATURE; + UserSelectableOption->OptionString =3D OptionString; + UserSelectableOption->OptionType =3D OptionType; + UserSelectableOption->OptionCol =3D OptionCol; + UserSelectableOption->OptionRow =3D OptionRow; + UserSelectableOption->MinSequence =3D 0; + + switch (PopupType) { + case EfiHiiPopupTypeOk: + UserSelectableOption->MaxSequence =3D 0; + UserSelectableOption->Sequence=3D 0; + break; + case EfiHiiPopupTypeOkCancel: + UserSelectableOption->MaxSequence =3D 1; + if (OptionType =3D=3D EfiHiiPopupSelectionOk) { + UserSelectableOption->Sequence=3D 0; + } else { + UserSelectableOption->Sequence=3D 1; + } + break; + case EfiHiiPopupTypeYesNo: + UserSelectableOption->MaxSequence =3D 1; + if (OptionType =3D=3D EfiHiiPopupSelectionYes) { + UserSelectableOption->Sequence =3D 0; + } else { + UserSelectableOption->Sequence =3D 1; + } + break; + case EfiHiiPopupTypeYesNoCancel: + UserSelectableOption->MaxSequence =3D 2; + if (OptionType =3D=3D EfiHiiPopupSelectionYes) { + UserSelectableOption->Sequence =3D 0; + } else if (OptionType =3D=3D EfiHiiPopupSelectionNo){ + UserSelectableOption->Sequence =3D 1; + } else { + UserSelectableOption->Sequence =3D 2; + } + break; + default: + break; + } + InsertTailList (&gUserSelectableOptions, &UserSelectableOption->Link); + + return EFI_SUCCESS; +} + +/** + Add user selectable options to option list for different types of Popup. + + @param PopupType Type of the popup to display. + + @retval EFI_SUCCESS This function implement successfully. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available. + +**/ +EFI_STATUS +AddUserSelectableOptions ( + IN EFI_HII_POPUP_TYPE PopupType + ) +{ + EFI_STATUS Status; + UINTN EndCol; + UINTN StartCol; + UINTN OptionCol; + UINTN OptionRow; + UINTN ColDimension; + + Status =3D EFI_SUCCESS; + EndCol =3D gPopupDimensions.RightColumn; + StartCol =3D gPopupDimensions.LeftColumn; + OptionRow =3D gPopupDimensions.BottomRow - POPUP_BORDER; + ColDimension =3D EndCol - StartCol + 1; + + InitializeListHead (&gUserSelectableOptions); + + switch (PopupType) { + case EfiHiiPopupTypeOk: + // + // Add [Ok] option to the option list. + // + OptionCol =3D StartCol + (ColDimension - USER_SELECTABLE_OPTION_OK_WID= TH) / 2; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionOk, = gOkOption, OptionCol, OptionRow); + break; + case EfiHiiPopupTypeOkCancel: + // + // Add [Ok] and [Cancel] options to the option list. + // + OptionCol =3D StartCol + (ColDimension - USER_SELECTABLE_OPTION_OK_CAL= _WIDTH) / 3; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionOk, = gOkOption, OptionCol, OptionRow); + OptionCol =3D EndCol - (ColDimension - USER_SELECTABLE_OPTION_OK_CAL_W= IDTH) / 3 - (GetStringWidth (gCancelOption) -2) / 2 + 1; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionCanc= el, gCancelOption, OptionCol, OptionRow); + break; + case EfiHiiPopupTypeYesNo: + // + // Add [Yes] and [No] options to the option list. + // + OptionCol =3D StartCol + (ColDimension - USER_SELECTABLE_OPTION_YES_NO= _WIDTH) / 3; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionYes,= gYesOption, OptionCol, OptionRow); + OptionCol =3D EndCol - (ColDimension - USER_SELECTABLE_OPTION_YES_NO_W= IDTH) / 3 - (GetStringWidth (gNoOption)- 2) / 2 + 1; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionNo, = gNoOption, OptionCol, OptionRow); + break; + case EfiHiiPopupTypeYesNoCancel: + // + // Add [Yes], [No] and [Cancel] options to the option list. + // + OptionCol =3D StartCol + (ColDimension - USER_SELECTABLE_OPTION_YES_NO= _CAL_WIDTH) / 4; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionYes,= gYesOption, OptionCol, OptionRow); + OptionCol =3D StartCol + (ColDimension - (GetStringWidth (gNoOption) -= 2) / 2) / 2; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionNo, = gNoOption, OptionCol, OptionRow); + OptionCol =3D EndCol - (ColDimension - USER_SELECTABLE_OPTION_YES_NO_C= AL_WIDTH) / 4 - (GetStringWidth (gCancelOption) - 2) / 2 + 1; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionCanc= el, gCancelOption, OptionCol, OptionRow); + break; + default: + break; + } + return Status; +} + +/** + Show selectable options to user and get the one that user select. + + @param PopupType Type of the popup to display. + @param UserSelection User selection. + +**/ +VOID +GetUserSelection ( + IN EFI_HII_POPUP_TYPE PopupType, + OUT EFI_HII_POPUP_SELECTION *UserSelection + ) +{ + LIST_ENTRY *HighlightPos; + LIST_ENTRY *Link; + USER_SELECTABLE_OPTION *SelectableOption; + USER_SELECTABLE_OPTION *HighlightOption; + EFI_INPUT_KEY KeyValue; + EFI_STATUS Status; + + // + // Display user selectable options in gUserSelectableOptions and get the= option which user selects. + // + HighlightPos =3D gUserSelectableOptions.ForwardLink; + do { + for (Link =3D gUserSelectableOptions.ForwardLink; Link !=3D &gUserSele= ctableOptions; Link =3D Link->ForwardLink) { + SelectableOption =3D SELECTABLE_OPTION_FROM_LINK (Link); + DisplayOneSelectableOption (SelectableOption, (BOOLEAN)(Link =3D=3D = HighlightPos)); + } + // + //If UserSelection is NULL, there is no need to handle the key user in= put, just return. + // + if (UserSelection =3D=3D NULL) { + return; + } + + Status =3D WaitForKeyStroke (&KeyValue); + ASSERT_EFI_ERROR (Status); + + HighlightOption =3D SELECTABLE_OPTION_FROM_LINK (HighlightPos); + switch (KeyValue.UnicodeChar) { + case CHAR_NULL: + switch (KeyValue.ScanCode) { + case SCAN_RIGHT: + if (HighlightOption->Sequence < HighlightOption->MaxSequence) { + HighlightPos =3D HighlightPos->ForwardLink; + } else { + HighlightPos =3D gUserSelectableOptions.ForwardLink; + } + break; + case SCAN_LEFT: + if (HighlightOption->Sequence > HighlightOption->MinSequence) { + HighlightPos =3D HighlightPos->BackLink; + } else { + HighlightPos =3D gUserSelectableOptions.BackLink; + } + break; + default: + break; + } + break; + + case CHAR_CARRIAGE_RETURN: + *UserSelection =3D HighlightOption->OptionType; + return; + default: + if (((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) =3D=3D (*gConf= irmOptYes | UPPER_LOWER_CASE_OFFSET)) && + (PopupType =3D=3D EfiHiiPopupTypeYesNo || PopupType =3D=3D EfiHiiP= opupTypeYesNoCancel)) { + *UserSelection =3D EfiHiiPopupSelectionYes; + return; + } else if ((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) =3D=3D (= *gConfirmOptNo| UPPER_LOWER_CASE_OFFSET) && + (PopupType =3D=3D EfiHiiPopupTypeYesNo || PopupType =3D=3D EfiHiiP= opupTypeYesNoCancel)){ + *UserSelection =3D EfiHiiPopupSelectionNo; + return; + } else if ((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) =3D=3D (= *gConfirmOptOk | UPPER_LOWER_CASE_OFFSET) && + (PopupType =3D=3D EfiHiiPopupTypeOk || PopupType =3D=3D EfiHiiPopu= pTypeOkCancel)){ + *UserSelection =3D EfiHiiPopupSelectionOk; + return; + } else if ((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) =3D=3D (= *gConfirmOptCancel| UPPER_LOWER_CASE_OFFSET) && + (PopupType =3D=3D EfiHiiPopupTypeOkCancel || PopupType =3D=3D EfiH= iiPopupTypeYesNoCancel)){ + *UserSelection =3D EfiHiiPopupSelectionCancel; + return; + } + break; + } + } while (TRUE); +} + +/** + Get the offset in the input string when the width reaches to a fixed one. + + The input string may contain NARROW_CHAR and WIDE_CHAR. + Notice: the input string doesn't contain line break characters. + + @param String The input string to be counted. + @param MaxWidth The max length this function supported. + @param Offset The max index of the string can be show out. If stri= ng's width less than MaxWidth, offset will point to the "\0" of the string. + +**/ +VOID +GetStringOffsetWithWidth ( + IN CHAR16 *String, + IN UINTN MaxWidth, + OUT UINTN *Offset + ) +{ + UINTN StringWidth; + UINTN CharWidth; + UINTN StrOffset; + + StringWidth =3D 0; + CharWidth =3D 1; + + for (StrOffset =3D 0; String[StrOffset] !=3D CHAR_NULL; StrOffset++) { + switch (String[StrOffset]) { + case NARROW_CHAR: + CharWidth =3D 1; + break; + case WIDE_CHAR: + CharWidth =3D 2; + break; + default: + StringWidth +=3D CharWidth; + if (StringWidth >=3D MaxWidth) { + *Offset =3D StrOffset; + return; + } + } + } + *Offset =3D StrOffset; +} + +/** + Parse the message to check if it contains line break characters. + For once call, caller can get the string for one line and the width of t= he string. + This function call be called recursively to parse the whole InputString. + + (Notice: current implementation, it only checks \r, \n characters, it de= als \r,\n,\n\r same as \r\n.) + + @param InputString String description for this option. + @param OutputString Buffer to copy the string into, caller is resp= onsible for freeing the buffer. + @param OutputStrWidth The width of OutputString. + @param Index Where in InputString to start the copy process + + @return Returns the number of CHAR16 characters that were copied into th= e OutputString buffer, include the '\0' info. + +**/ +UINTN +ParseMessageString ( + IN CHAR16 *InputString, + OUT CHAR16 **OutputString, + OUT UINTN *OutputStrWidth, + IN OUT UINTN *Index + ) +{ + UINTN StrOffset; + + if (InputString =3D=3D NULL || Index =3D=3D NULL || OutputString =3D=3D = NULL) { + return 0; + } + + *OutputStrWidth =3D 0; + + // + //Check the string to see if there are line break characters in the stri= ng + // + for (StrOffset =3D 0; InputString[StrOffset] !=3D CHAR_NULL; StrOffset++= ) { + if (InputString[*Index + StrOffset] =3D=3D CHAR_CARRIAGE_RETURN || Inp= utString[*Index + StrOffset] =3D=3D CHAR_LINEFEED || InputString[*Index + S= trOffset] =3D=3D CHAR_NULL) { + break; + } + } + + // + // The CHAR_NULL has process last time, this time just return 0 to stand= for finishing parsing the InputString. + // + if (StrOffset =3D=3D 0 && (InputString[*Index + StrOffset] =3D=3D CHAR_N= ULL)) { + return 0; + } + + // + // Copy the string to OutputString buffer and calculate the width of Out= putString. + // + *OutputString =3D AllocateZeroPool ((StrOffset + 1) * sizeof(CHAR16)); + if (*OutputString =3D=3D NULL) { + return 0; + } + CopyMem ((*OutputString), &InputString[*Index], StrOffset * sizeof(CHAR1= 6)); + *OutputStrWidth =3D (GetStringWidth (*OutputString) -2) / 2; + + // + // Update the value of Index, can be used for marking where to check the= input string for next call. + // + if (InputString[*Index + StrOffset] =3D=3D CHAR_LINEFEED) { + // + // Skip the /n or /n/r info. + // + if (InputString[*Index + StrOffset + 1] =3D=3D CHAR_CARRIAGE_RETURN) { + *Index =3D (*Index + StrOffset + 2); + } else { + *Index =3D (*Index + StrOffset + 1); + } + } else if (InputString[*Index + StrOffset] =3D=3D CHAR_CARRIAGE_RETURN) { + // + // Skip the /r or /r/n info. + // + if (InputString[*Index + StrOffset + 1] =3D=3D CHAR_LINEFEED) { + *Index =3D (*Index + StrOffset + 2); + } else { + *Index =3D (*Index + StrOffset + 1); + } + } else { + *Index =3D (*Index + StrOffset); + } + + return StrOffset + 1; +} + +/** + Calculate the position of the popup. + + @param PopupType Type of the popup to display. + @param ScreenForPopup The screen dimensions for the popup. + +**/ +VOID +CalculatePopupPosition ( + IN EFI_HII_POPUP_TYPE PopupType, + OUT EFI_SCREEN_DESCRIPTOR *ScreenForPopup + ) +{ + CHAR16 *OutputString; + UINTN StringIndex; + UINTN OutputStrWidth; + UINTN OptionRowWidth; + UINTN Columns; + UINTN Rows; + + OptionRowWidth =3D 0; + + // + // Calculate the row number which is needed to show the message string a= nd the max width of the string in one row. + // + for (StringIndex =3D 0; ParseMessageString (gMessageString, &OutputStrin= g, &OutputStrWidth, &StringIndex) !=3D 0;) { + gMesStrLineNum ++; + if (gMaxRowWidth < OutputStrWidth) { + gMaxRowWidth =3D OutputStrWidth; + } + FreePool (OutputString); + } + + // + // Calculate the row width for the selectable options.(OptionRowWidth = =3D Number * SkipWidth + OptionWidth) + // + if (PopupType =3D=3D EfiHiiPopupTypeOk) { + OptionRowWidth =3D USER_SELECTABLE_OPTION_SKIP_WIDTH *2 + USER_SELECTA= BLE_OPTION_OK_WIDTH; + } else if (PopupType =3D=3D EfiHiiPopupTypeOkCancel) { + OptionRowWidth =3D USER_SELECTABLE_OPTION_SKIP_WIDTH *3 + USER_SELECTA= BLE_OPTION_OK_CAL_WIDTH; + } else if (PopupType =3D=3D EfiHiiPopupTypeYesNo) { + OptionRowWidth =3D USER_SELECTABLE_OPTION_SKIP_WIDTH *3 + USER_SELECTA= BLE_OPTION_YES_NO_WIDTH; + } else if (PopupType =3D=3D EfiHiiPopupTypeYesNoCancel) { + OptionRowWidth =3D USER_SELECTABLE_OPTION_SKIP_WIDTH *4 + USER_SELECTA= BLE_OPTION_YES_NO_CAL_WIDTH; + } + if (OptionRowWidth > gMaxRowWidth) { + gMaxRowWidth =3D OptionRowWidth; + } + + // + // Avialble row width for message string =3D screen width - left popup b= order width - right popup border width. + // Avialble line number for message string =3D screen height - 1 - popup= header height - popup footer height. + // (Notice: screen height - 1 because in current UI page, the bottom row= of srceen is usded to show Status Bar,not for form itself. + // So we don't use the bottom row for popup either. If macro STATUS_BAR_= HEIGHT changed, we also need to update the height here.) + // + // Select the smaller one between actual dimension of message string and= the avialble dimension for message string. + // + gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Columns, = &Rows); + gMaxRowWidth =3D MIN (gMaxRowWidth, Columns - 2 * POPUP_BORDER); + gMesStrLineNum =3D MIN (gMesStrLineNum, Rows -1 - POPUP_FOOTER_HEIGHT - = POPUP_HEADER_HEIGHT); + + // + // Calculate the start column, end column, top row and bottom row for th= e popup. + // + ScreenForPopup->LeftColumn =3D (Columns -2 * POPUP_BORDER - gMaxRowWidth= ) / 2; + ScreenForPopup->RightColumn =3D ScreenForPopup->LeftColumn + gMaxRowWidt= h + 2 * POPUP_BORDER - 1; + ScreenForPopup->TopRow =3D (Rows - 1 - POPUP_FOOTER_HEIGHT - POPUP_HEADE= R_HEIGHT - gMesStrLineNum) / 2; + ScreenForPopup->BottomRow =3D ScreenForPopup->TopRow + gMesStrLineNum + = POPUP_FOOTER_HEIGHT + POPUP_HEADER_HEIGHT - 1; +} + +/** + Draw the Message box. + +-------------------------------------------+ + | ERROR/WARNING/INFO | + |-------------------------------------------| + | popup messages | + | | + | user selectable options | + +-------------------------------------------+ + + @param PopupStyle Popup style to use. + +**/ +EFI_STATUS +DrawMessageBox ( + IN EFI_HII_POPUP_STYLE PopupStyle + ) +{ + UINTN Index; + UINTN Length; + UINTN EndCol; + UINTN TopRow; + UINTN StartCol; + UINTN BottomRow; + CHAR16 Character; + UINTN DisplayRow; + UINTN StringIndex; + CHAR16 *TempString; + CHAR16 *OutputString; + UINTN ColDimension; + UINTN OutputStrWidth; + UINTN DrawMesStrRowNum; + + EndCol =3D gPopupDimensions.RightColumn; + TopRow =3D gPopupDimensions.TopRow; + StartCol =3D gPopupDimensions.LeftColumn; + BottomRow =3D gPopupDimensions.BottomRow; + ColDimension =3D EndCol - StartCol + 1; + DrawMesStrRowNum =3D 0; + + // + // 1. Draw the top of the message box. + // + Character =3D BOXDRAW_DOWN_RIGHT; + PrintCharAt (StartCol, TopRow, Character); + Character =3D BOXDRAW_HORIZONTAL; + for (Index =3D StartCol; Index + 1 < EndCol; Index++) { + PrintCharAt ((UINTN)-1, (UINTN)-1, Character); + } + Character =3D BOXDRAW_DOWN_LEFT; + PrintCharAt ((UINTN)-1, (UINTN)-1, Character); + + // + // 2. Draw the prompt string for different popup styles. + // + Character =3D BOXDRAW_VERTICAL; + DisplayRow =3D TopRow + POPUP_BORDER; + ClearLines (StartCol, EndCol, DisplayRow, DisplayRow, GetPopupColor ()); + PrintCharAt (StartCol, DisplayRow, Character); + PrintCharAt (EndCol, DisplayRow, Character); + if (PopupStyle =3D=3D EfiHiiPopupStyleError) { + PrintStringAt ((ColDimension - (GetStringWidth (gErrorPopup) - 2) / 2)= / 2 + StartCol, DisplayRow, gErrorPopup); + } else if (PopupStyle =3D=3D EfiHiiPopupStyleWarning) { + PrintStringAt ((ColDimension - (GetStringWidth (gWarningPopup) - 2) / = 2) / 2 + StartCol, DisplayRow, gWarningPopup); + } else { + PrintStringAt ((ColDimension - (GetStringWidth (gInfoPopup) - 2) / 2) = / 2 + StartCol, DisplayRow, gInfoPopup); + } + + // + // 3. Draw the horizontal line below the prompt string for different pop= up styles. + // + DisplayRow =3D TopRow + POPUP_BORDER + POPUP_STYLE_STRING_HEIGHT; + ClearLines (StartCol, EndCol, DisplayRow, DisplayRow, GetPopupColor ()); + Character =3D BOXDRAW_HORIZONTAL; + for (Index =3D StartCol + 1; Index < EndCol; Index++) { + PrintCharAt (Index, DisplayRow, Character); + } + Character =3D BOXDRAW_VERTICAL; + PrintCharAt (StartCol, DisplayRow, Character); + PrintCharAt (EndCol, DisplayRow, Character); + + // + // 4. Draw the mesage string. + // + DisplayRow =3D TopRow + POPUP_HEADER_HEIGHT; + for (Index =3D DisplayRow ,StringIndex =3D 0; ParseMessageString (gMessa= geString, &OutputString, &OutputStrWidth, &StringIndex) !=3D 0 && DrawMesS= trRowNum < gMesStrLineNum;) { + ClearLines (StartCol, EndCol, Index, Index, GetPopupColor ()); + PrintCharAt (StartCol, Index, Character); + PrintCharAt (EndCol, Index, Character); + if (OutputStrWidth > gMaxRowWidth) { + // + //OutputStrWidth > MaxMesStrWidth, cut off the string and print prin= t ... instead. + // + GetStringOffsetWithWidth (OutputString, gMaxRowWidth, &Length); + TempString =3D AllocateZeroPool ((Length + 1) * sizeof (CHAR16)); + if (TempString =3D=3D NULL) { + FreePool (OutputString); + return EFI_OUT_OF_RESOURCES; + } + StrnCpyS (TempString, Length + 1, OutputString, Length - 3); + StrCatS (TempString, Length + 1, L"..."); + PrintStringAt ((ColDimension - gMaxRowWidth) / 2 + StartCol, Index, = TempString); + FreePool (TempString); + } else { + PrintStringAt ((ColDimension - OutputStrWidth) / 2 + StartCol, Index= , OutputString); + } + Index ++; + DrawMesStrRowNum ++; + FreePool (OutputString); + } + + // + // 5. Draw an empty line after message string. + // + ClearLines (StartCol, EndCol, Index, Index, GetPopupColor ()); + PrintCharAt (StartCol, Index, Character); + PrintCharAt (EndCol, Index, Character); + // + // Check whether the actual string row number beyond the MesStrRowNum, i= f yes, print the ...... in the row. + // + if (OutputStrWidth > 0 && DrawMesStrRowNum >=3D gMesStrLineNum) { + PrintStringAt ((ColDimension - StrLen (L"......")) / 2 + StartCol, Ind= ex, L"......"); + } + + // + // 6. Draw an empty line which is used to show user selectable options, = will draw concrete option strings in function GetUserSelection(). + // + Character =3D BOXDRAW_VERTICAL; + DisplayRow =3D BottomRow - POPUP_BORDER; + ClearLines (StartCol, EndCol, DisplayRow, DisplayRow, GetPopupColor ()); + PrintCharAt (StartCol, DisplayRow, Character); + PrintCharAt (EndCol, DisplayRow, Character); + + // + // 7. Draw the bottom of the message box. + // + Character =3D BOXDRAW_UP_RIGHT; + PrintCharAt (StartCol, BottomRow, Character); + Character =3D BOXDRAW_HORIZONTAL; + for (Index =3D StartCol; Index + 1 < EndCol; Index++) { + PrintCharAt ((UINTN)-1, (UINTN) -1, Character); + } + Character =3D BOXDRAW_UP_LEFT; + PrintCharAt ((UINTN)-1, (UINTN) -1, Character); + + return EFI_SUCCESS; +} + +/** + Displays a popup window. + + @param This A pointer to the EFI_HII_POPUP_PROTOCOL instance. + @param PopupStyle Popup style to use. + @param PopupType Type of the popup to display. + @param HiiHandle HII handle of the string pack containing Message + @param Message A message to display in the popup box. + @param UserSelection User selection. + + @retval EFI_SUCCESS The popup box was successfully displayed. + @retval EFI_INVALID_PARAMETER HiiHandle and Message do not define a val= id HII string. + @retval EFI_INVALID_PARAMETER PopupType is not one of the values define= d by this specification. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available = to display the popup box. + +**/ +EFI_STATUS +EFIAPI +CreatePopup ( + IN EFI_HII_POPUP_PROTOCOL *This, + IN EFI_HII_POPUP_STYLE PopupStyle, + IN EFI_HII_POPUP_TYPE PopupType, + IN EFI_HII_HANDLE HiiHandle, + IN EFI_STRING_ID Message, + OUT EFI_HII_POPUP_SELECTION *UserSelection OPTIONAL + ) +{ + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; + EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode; + EFI_STATUS Status; + + if ((PopupType < EfiHiiPopupTypeOk) || (PopupType > EfiHiiPopupTypeYesNo= Cancel)) { + return EFI_INVALID_PARAMETER; + } + + if((HiiHandle =3D=3D NULL) || (Message =3D=3D 0)) { + return EFI_INVALID_PARAMETER; + } + + gMessageString =3D HiiGetString (HiiHandle, Message, NULL); + if((gMessageString =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + ConOut =3D gST->ConOut; + gMaxRowWidth =3D 0; + gMesStrLineNum =3D 0; + + CopyMem (&SavedConsoleMode, ConOut->Mode, sizeof (SavedConsoleMode)); + ConOut->EnableCursor (ConOut, FALSE); + ConOut->SetAttribute (ConOut, GetPopupColor ()); + + CalculatePopupPosition (PopupType, &gPopupDimensions); + + Status =3D DrawMessageBox (PopupStyle); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // Add user selectable options to option list: gUserSelectableOptions + // + Status =3D AddUserSelectableOptions (PopupType); + if (EFI_ERROR (Status)) { + goto Done; + } + + GetUserSelection (PopupType, UserSelection); + +Done: + // + // Restore Conout attributes and free the resources allocate before. + // + ConOut->EnableCursor (ConOut, SavedConsoleMode.CursorVisible); + ConOut->SetCursorPosition (ConOut, SavedConsoleMode.CursorColumn, SavedC= onsoleMode.CursorRow); + ConOut->SetAttribute (ConOut, SavedConsoleMode.Attribute); + FreeSelectableOptions (&gUserSelectableOptions); + FreePool (gMessageString); + + return Status; +} + --=20 1.9.5.msysgit.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel