From nobody Fri Dec 27 18:00:17 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 1502766520587265.4988945148085; Mon, 14 Aug 2017 20:08:40 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 70A2421DFC882; Mon, 14 Aug 2017 20:06:14 -0700 (PDT) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (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 DA3C321B06E9B for ; Mon, 14 Aug 2017 20:06:13 -0700 (PDT) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga105.fm.intel.com with ESMTP; 14 Aug 2017 20:08:38 -0700 Received: from shwdeopenpsi114.ccr.corp.intel.com ([10.239.157.135]) by fmsmga004.fm.intel.com with ESMTP; 14 Aug 2017 20:08:35 -0700 X-Original-To: edk2-devel@lists.01.org X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,376,1498546800"; d="scan'208";a="300158138" From: Dandan Bi To: edk2-devel@lists.01.org Date: Tue, 15 Aug 2017 11:07:59 +0800 Message-Id: <1502766480-258908-3-git-send-email-dandan.bi@intel.com> X-Mailer: git-send-email 1.9.5.msysgit.1 In-Reply-To: <1502766480-258908-1-git-send-email-dandan.bi@intel.com> References: <1502766480-258908-1-git-send-email-dandan.bi@intel.com> Subject: [edk2] [patch 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" 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 | 33 ++ .../Universal/DisplayEngineDxe/FormDisplay.h | 76 ++- .../Universal/DisplayEngineDxe/FormDisplayStr.uni | 14 +- MdeModulePkg/Universal/DisplayEngineDxe/Popup.c | 610 +++++++++++++++++= ++++ 5 files changed, 734 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..8d48ed1 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c +++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c @@ -149,10 +149,16 @@ 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 *gConfirmMsgConnect; CHAR16 *gConfirmMsgEnd; CHAR16 *gPasswordUnsupported; CHAR16 gModalSkipColumn; CHAR16 gPromptBlockWidth; @@ -165,10 +171,14 @@ FORM_DISPLAY_DRIVER_PRIVATE_DATA mPrivateData =3D { NULL, { FormDisplay, DriverClearDisplayPage, ConfirmDataChange + }, + { + EFI_HII_POPUP_PROTOCOL_REVISION, + CreatePopup } }; =20 =20 /** @@ -245,10 +255,16 @@ 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); 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 +315,16 @@ FreeDisplayStrings ( FreePool (gConfirmResetMsg2nd); FreePool (gConfirmExitMsg2nd); FreePool (gConfirmOpt); FreePool (gConfirmOptYes); FreePool (gConfirmOptNo); + FreePool (gConfirmOptOk); + FreePool (gConfirmOptCancel); + FreePool (gYesOption); + FreePool (gNoOption); + FreePool (gOkOption); + FreePool (gCancelOption); FreePool (gConfirmMsgConnect); FreePool (gConfirmMsgEnd); FreePool (gPasswordUnsupported); } =20 @@ -4117,10 +4139,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..658528a 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,18 @@ 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; =20 // // Browser Global Strings // extern CHAR16 *gSaveFailed; @@ -137,10 +146,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 +280,47 @@ 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 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: Ok : Cancel + // 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 +695,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..534890e 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,14 @@ #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 ]" =20 diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/Popup.c b/MdeModulePkg= /Universal/DisplayEngineDxe/Popup.c new file mode 100644 index 0000000..42ea092 --- /dev/null +++ b/MdeModulePkg/Universal/DisplayEngineDxe/Popup.c @@ -0,0 +1,610 @@ +/** @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" + +LIST_ENTRY gUserSelectableOptions; + +/** + 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. + +**/ +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. + @param OptionRow The Row that the options need to be drew at. + @param StartCol The sart column of the popup, used to calculate th= e column that the options need to be drew at. + @param EndCol The end column of the popup, used to calculate the= column that the options need to be drew at. + +**/ +EFI_STATUS +AddUserSelectableOptions ( + IN EFI_HII_POPUP_TYPE PopupType, + IN UINTN OptionRow, + IN UINTN StartCol, + IN UINTN EndCol + ) +{ + UINTN OptionCol; + EFI_STATUS Status; + + Status =3D EFI_SUCCESS; + + switch (PopupType) { + case EfiHiiPopupTypeOk: + // + // Add [Ok] option to the option list. + // + OptionCol =3D StartCol + (EndCol - StartCol - USER_SELECTABLE_OPTION_O= K_WIDTH) / 2; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionOk, = gOkOption, OptionCol, OptionRow); + break; + case EfiHiiPopupTypeOkCancel: + // + // Add [Ok] and [Cancel] options to the option list. + // + OptionCol =3D StartCol + (EndCol - StartCol - USER_SELECTABLE_OPTION_O= K_CAL_WIDTH) / 3; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionOk, = gOkOption, OptionCol, OptionRow); + OptionCol =3D EndCol - (EndCol - StartCol - USER_SELECTABLE_OPTION_OK_= CAL_WIDTH) / 3 - StrLen (gCancelOption); + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionCanc= el, gCancelOption, OptionCol, OptionRow); + break; + case EfiHiiPopupTypeYesNo: + // + // Add [Yes] and [No] options to the option list. + // + OptionCol =3D StartCol + (EndCol - StartCol - USER_SELECTABLE_OPTION_Y= ES_NO_WIDTH) / 3; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionYes,= gYesOption, OptionCol, OptionRow); + OptionCol =3D EndCol - (EndCol - StartCol - USER_SELECTABLE_OPTION_YES= _NO_WIDTH) / 3 - StrLen (gNoOption); + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionNo, = gNoOption, OptionCol, OptionRow); + break; + case EfiHiiPopupTypeYesNoCancel: + // + // Add [Yes], [No] and [Cancel] options to the option list. + // + OptionCol =3D StartCol + (EndCol - StartCol - USER_SELECTABLE_OPTION_Y= ES_NO_CAL_WIDTH) / 4; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionYes,= gYesOption, OptionCol, OptionRow); + OptionCol =3D StartCol + (EndCol - StartCol - StrLen (gNoOption)) / 2; + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionNo, = gNoOption, OptionCol, OptionRow); + OptionCol =3D EndCol - (EndCol - StartCol - USER_SELECTABLE_OPTION_YES= _NO_CAL_WIDTH) / 4 - StrLen (gCancelOption); + Status =3D AddOneSelectableOption (PopupType, EfiHiiPopupSelectionCanc= el, gCancelOption, OptionCol, OptionRow); + break; + default: + break; + } + return Status; +} + +/** + 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 Index Where in InputString to start the copy process + @param OutputString Buffer to copy the string into, caller is resp= onsible for freeing the buffer. + @param OutputStrWidth The width of OutputString. + + @return Returns the number of CHAR16 characters that were copied into th= e OutputString buffer, include the '\0' info. + +**/ +UINTN +ParseMessageString ( + IN CHAR16 *InputString, + IN OUT UINTN *Index, + OUT CHAR16 **OutputString, + OUT UINTN *OutputStrWidth + ) +{ + 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; + + // + // 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; +} + +/** + This is the main implementation function of CreatePopup API, to draw the= message box. + + @param MessageString A message to display in the message box. + @param PopupStyle Popup style to use. + @param PopupType Type of the popup to display. + @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 +DrawMessageBox ( + IN EFI_STRING MessageString, + IN EFI_HII_POPUP_STYLE PopupStyle, + IN EFI_HII_POPUP_TYPE PopupType, + OUT EFI_HII_POPUP_SELECTION *UserSelection + ) +{ + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; + EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode; + USER_SELECTABLE_OPTION *HighlightOption; + USER_SELECTABLE_OPTION *SelectableOption; + EFI_INPUT_KEY KeyValue; + LIST_ENTRY *HighlightPos; + LIST_ENTRY *Link; + EFI_STATUS Status; + CHAR16 *OutputString; + CHAR16 *TempString; + CHAR16 Character; + UINTN OutputStrWidth; + UINTN MaxMesStrWidth; + UINTN MesStrRowNum; + UINTN DrawMesStrNum; + UINTN OptionRowWidth; + UINTN StringIndex; + UINTN Index; + UINTN Columns; + UINTN Rows; + UINTN StartCol; + UINTN EndCol; + UINTN TopRow; + UINTN BottomRow; + UINTN SelectableOptionRow; + + ConOut =3D gST->ConOut; + MesStrRowNum =3D 0; + DrawMesStrNum =3D 0; + MaxMesStrWidth =3D 0; + OptionRowWidth =3D 0; + + CopyMem (&SavedConsoleMode, ConOut->Mode, sizeof (SavedConsoleMode)); + ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &Columns, &Rows); + ConOut->EnableCursor (ConOut, FALSE); + ConOut->SetAttribute (ConOut, GetPopupColor ()); + + // + // Calculate the row number of message string and the max width of the s= tring in one row. + // + for (StringIndex =3D 0; ParseMessageString (MessageString, &StringIndex,= &OutputString, &OutputStrWidth) !=3D 0;) { + MesStrRowNum ++; + if (MaxMesStrWidth < OutputStrWidth) { + MaxMesStrWidth =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 > MaxMesStrWidth) { + MaxMesStrWidth =3D OptionRowWidth; + } + + // + //Columns -2 : 2 for the message box itself. + //(Rows -1) -5: 4 for message box itself (empty line, border) and 1 for = user selectable options. + // + MaxMesStrWidth =3D MIN (MaxMesStrWidth, Columns - 2); + MesStrRowNum =3D MIN (MesStrRowNum, Rows -1 - 5); + + // + // Calculate the starting row, starting column, ending row and ending co= lumn for the popup. + // + StartCol =3D (Columns -2 - MaxMesStrWidth) / 2; + EndCol =3D StartCol + MaxMesStrWidth + 2; + TopRow =3D (Rows - 1 - 5 - MesStrRowNum) / 2; + BottomRow =3D TopRow + MesStrRowNum + 5; + + // + // 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 + 2 < EndCol; Index++) { + PrintCharAt ((UINTN)-1, (UINTN)-1, Character); + } + Character =3D BOXDRAW_DOWN_LEFT; + PrintCharAt ((UINTN)-1, (UINTN)-1, Character); + + // + // 2. Draw an empty line before message string. + // + Character =3D BOXDRAW_VERTICAL; + ClearLines (StartCol, EndCol, TopRow + 1, TopRow + 1, GetPopupColor ()); + PrintCharAt (StartCol, TopRow + 1, Character); + PrintCharAt (EndCol - 1, TopRow + 1, Character); + + // + // 3. Draw the mesage string + // + for (Index =3D TopRow + 2,StringIndex =3D 0; ParseMessageString (Message= String, &StringIndex, &OutputString, &OutputStrWidth) !=3D 0 && DrawMesStrN= um < MesStrRowNum;) { + ClearLines (StartCol, EndCol, Index, Index, GetPopupColor ()); + PrintCharAt (StartCol, Index, Character); + PrintCharAt (EndCol - 1, Index, Character); + if (OutputStrWidth > MaxMesStrWidth) { + // + //OutputStrWidth > MaxMesStrWidth, cut off the string and print prin= t ... instead. + // + TempString =3D AllocateZeroPool ((MaxMesStrWidth + 1) * sizeof (CHAR= 16)); + if (TempString =3D=3D NULL) { + FreePool (OutputString); + Status =3D EFI_OUT_OF_RESOURCES; + goto Done; + } + StrnCpyS (TempString, MaxMesStrWidth + 1, OutputString, MaxMesStrWid= th - 3); + StrCatS (TempString, MaxMesStrWidth + 1, L"..."); + PrintStringAt ((Columns - MaxMesStrWidth) / 2, Index, TempString); + FreePool (TempString); + } else { + PrintStringAt ((Columns - OutputStrWidth) / 2, Index, OutputString); + } + Index ++; + DrawMesStrNum ++; + FreePool (OutputString); + } + + // + // 4. Draw an empty line after message string. + // + ClearLines (StartCol, EndCol, Index, Index, GetPopupColor ()); + PrintCharAt (StartCol, Index, Character); + PrintCharAt (EndCol - 1, Index, Character); + + // + // Check whether the actual string row number beyond the MesStrRowNum, i= f yes, print the ...... in the row. + // + if (OutputStrWidth > 0 && DrawMesStrNum >=3D MesStrRowNum) { + PrintStringAt ((Columns - StrLen (L"......")) / 2, Index, L"......"); + } + SelectableOptionRow =3D Index + 1; + + // + // 5. Draw an empty line which is used to show user selectable options, = will draw concrete string options later. + // + Character =3D BOXDRAW_VERTICAL; + ClearLines (StartCol, EndCol, Index + 1, Index + 1, GetPopupColor ()); + PrintCharAt (StartCol, Index + 1, Character); + PrintCharAt (EndCol - 1, Index + 1, Character); + + // + // 6.Draw the bottom of the message box + // + Character =3D BOXDRAW_UP_RIGHT; + PrintCharAt (StartCol, BottomRow - 1, Character); + Character =3D BOXDRAW_HORIZONTAL; + for (Index =3D StartCol; Index + 2 < EndCol; Index++) { + PrintCharAt ((UINTN)-1, (UINTN) -1, Character); + } + Character =3D BOXDRAW_UP_LEFT; + PrintCharAt ((UINTN)-1, (UINTN) -1, Character); + + // + // Add user selectable options to option list. + // + Status =3D AddUserSelectableOptions (PopupType, SelectableOptionRow, Sta= rtCol, EndCol); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // 7. Draw selectable options and wait for user's selection. + // + 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, so there is no need to handle the key user= input, just return. + // + if (UserSelection =3D=3D NULL) { + goto Done; + } + + Status =3D WaitForKeyStroke (&KeyValue); + if (EFI_ERROR (Status)) { + goto Done; + } + 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; + goto Done; + 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; + goto Done; + } 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; + goto Done; + } else if ((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) =3D=3D (= *gConfirmOptOk | UPPER_LOWER_CASE_OFFSET) && + (PopupType =3D=3D EfiHiiPopupTypeOk|| PopupType =3D=3D EfiHiiPopup= TypeOkCancel)){ + *UserSelection =3D EfiHiiPopupSelectionOk; + goto Done; + } else if ((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) =3D=3D (= *gConfirmOptCancel| UPPER_LOWER_CASE_OFFSET) && + (PopupType =3D=3D EfiHiiPopupTypeOkCancel|| PopupType =3D=3D EfiHi= iPopupTypeYesNoCancel)){ + *UserSelection =3D EfiHiiPopupSelectionCancel; + goto Done; + } + break; + } + } while (TRUE); + + // + // Restore the cursor visibility, position, and attributes + // +Done: + ConOut->EnableCursor (ConOut, SavedConsoleMode.CursorVisible); + ConOut->SetCursorPosition (ConOut, SavedConsoleMode.CursorColumn, SavedC= onsoleMode.CursorRow); + ConOut->SetAttribute (ConOut, SavedConsoleMode.Attribute); + + return Status; +} + +/** + 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_STRING MessageString; + EFI_STATUS Status; + + if((HiiHandle =3D=3D NULL) || (Message =3D=3D0)) { + return EFI_INVALID_PARAMETER; + } + + MessageString =3D HiiGetString (HiiHandle, Message, NULL); + + if((MessageString =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + if ((PopupType !=3D EfiHiiPopupTypeOk) && (PopupType !=3D EfiHiiPopupTyp= eOkCancel)&& (PopupType !=3D EfiHiiPopupTypeYesNo)&& (PopupType !=3D EfiHii= PopupTypeYesNoCancel)) { + return EFI_INVALID_PARAMETER; + } + + InitializeListHead (&gUserSelectableOptions); + + Status =3D DrawMessageBox (MessageString, PopupStyle, PopupType, UserSel= ection); + + FreeSelectableOptions (&gUserSelectableOptions); + + 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