mirror of https://github.com/acidanthera/audk.git
MdeModulePkg/DisplayEngine: Add implementation of HiiPopup protocol
Add the implementation of HiiPopup protocol in DisplayEngineDxe, since DisplayEngineDxe is responsible for drawing tasks. Cc: Eric Dong <eric.dong@intel.com> Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Dandan Bi <dandan.bi@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
parent
3413fe86c6
commit
06aad9a231
|
@ -1,7 +1,7 @@
|
||||||
## @file
|
## @file
|
||||||
# The DXE driver produces FORM DISPLAY ENGIEN protocol.
|
# The DXE driver produces FORM DISPLAY ENGIEN protocol.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
|
# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
#
|
#
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
FormDisplay.h
|
FormDisplay.h
|
||||||
ProcessOptions.c
|
ProcessOptions.c
|
||||||
InputHandler.c
|
InputHandler.c
|
||||||
|
Popup.c
|
||||||
|
|
||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
|
@ -54,6 +55,7 @@
|
||||||
[Protocols]
|
[Protocols]
|
||||||
gEdkiiFormDisplayEngineProtocolGuid ## PRODUCES
|
gEdkiiFormDisplayEngineProtocolGuid ## PRODUCES
|
||||||
gEdkiiFormBrowserEx2ProtocolGuid ## CONSUMES
|
gEdkiiFormBrowserEx2ProtocolGuid ## CONSUMES
|
||||||
|
gEfiHiiPopupProtocolGuid ## PRODUCES
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
gEfiHiiDatabaseProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid AND gEdkiiFormBrowserEx2ProtocolGuid
|
gEfiHiiDatabaseProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid AND gEdkiiFormBrowserEx2ProtocolGuid
|
||||||
|
|
|
@ -151,6 +151,15 @@ CHAR16 *gConfirmExitMsg2nd;
|
||||||
CHAR16 *gConfirmOpt;
|
CHAR16 *gConfirmOpt;
|
||||||
CHAR16 *gConfirmOptYes;
|
CHAR16 *gConfirmOptYes;
|
||||||
CHAR16 *gConfirmOptNo;
|
CHAR16 *gConfirmOptNo;
|
||||||
|
CHAR16 *gConfirmOptOk;
|
||||||
|
CHAR16 *gConfirmOptCancel;
|
||||||
|
CHAR16 *gYesOption;
|
||||||
|
CHAR16 *gNoOption;
|
||||||
|
CHAR16 *gOkOption;
|
||||||
|
CHAR16 *gCancelOption;
|
||||||
|
CHAR16 *gErrorPopup;
|
||||||
|
CHAR16 *gWarningPopup;
|
||||||
|
CHAR16 *gInfoPopup;
|
||||||
CHAR16 *gConfirmMsgConnect;
|
CHAR16 *gConfirmMsgConnect;
|
||||||
CHAR16 *gConfirmMsgEnd;
|
CHAR16 *gConfirmMsgEnd;
|
||||||
CHAR16 *gPasswordUnsupported;
|
CHAR16 *gPasswordUnsupported;
|
||||||
|
@ -167,6 +176,10 @@ FORM_DISPLAY_DRIVER_PRIVATE_DATA mPrivateData = {
|
||||||
FormDisplay,
|
FormDisplay,
|
||||||
DriverClearDisplayPage,
|
DriverClearDisplayPage,
|
||||||
ConfirmDataChange
|
ConfirmDataChange
|
||||||
|
},
|
||||||
|
{
|
||||||
|
EFI_HII_POPUP_PROTOCOL_REVISION,
|
||||||
|
CreatePopup
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -247,6 +260,15 @@ InitializeDisplayStrings (
|
||||||
gConfirmOpt = GetToken (STRING_TOKEN (CONFIRM_OPTION), gHiiHandle);
|
gConfirmOpt = GetToken (STRING_TOKEN (CONFIRM_OPTION), gHiiHandle);
|
||||||
gConfirmOptYes = GetToken (STRING_TOKEN (CONFIRM_OPTION_YES), gHiiHandle);
|
gConfirmOptYes = GetToken (STRING_TOKEN (CONFIRM_OPTION_YES), gHiiHandle);
|
||||||
gConfirmOptNo = GetToken (STRING_TOKEN (CONFIRM_OPTION_NO), gHiiHandle);
|
gConfirmOptNo = GetToken (STRING_TOKEN (CONFIRM_OPTION_NO), gHiiHandle);
|
||||||
|
gConfirmOptOk = GetToken (STRING_TOKEN (CONFIRM_OPTION_OK), gHiiHandle);
|
||||||
|
gConfirmOptCancel = GetToken (STRING_TOKEN (CONFIRM_OPTION_CANCEL), gHiiHandle);
|
||||||
|
gYesOption = GetToken (STRING_TOKEN (YES_SELECTABLE_OPTION), gHiiHandle);
|
||||||
|
gNoOption = GetToken (STRING_TOKEN (NO_SELECTABLE_OPTION), gHiiHandle);
|
||||||
|
gOkOption = GetToken (STRING_TOKEN (OK_SELECTABLE_OPTION), gHiiHandle);
|
||||||
|
gCancelOption = GetToken (STRING_TOKEN (CANCEL_SELECTABLE_OPTION), gHiiHandle);
|
||||||
|
gErrorPopup = GetToken (STRING_TOKEN (ERROR_POPUP_STRING), gHiiHandle);
|
||||||
|
gWarningPopup = GetToken (STRING_TOKEN (WARNING_POPUP_STRING), gHiiHandle);
|
||||||
|
gInfoPopup = GetToken (STRING_TOKEN (INFO_POPUP_STRING), gHiiHandle);
|
||||||
gConfirmMsgConnect = GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT), gHiiHandle);
|
gConfirmMsgConnect = GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT), gHiiHandle);
|
||||||
gConfirmMsgEnd = GetToken (STRING_TOKEN (CONFIRM_OPTION_END), gHiiHandle);
|
gConfirmMsgEnd = GetToken (STRING_TOKEN (CONFIRM_OPTION_END), gHiiHandle);
|
||||||
gPasswordUnsupported = GetToken (STRING_TOKEN (PASSWORD_NOT_SUPPORTED ), gHiiHandle);
|
gPasswordUnsupported = GetToken (STRING_TOKEN (PASSWORD_NOT_SUPPORTED ), gHiiHandle);
|
||||||
|
@ -301,6 +323,15 @@ FreeDisplayStrings (
|
||||||
FreePool (gConfirmOpt);
|
FreePool (gConfirmOpt);
|
||||||
FreePool (gConfirmOptYes);
|
FreePool (gConfirmOptYes);
|
||||||
FreePool (gConfirmOptNo);
|
FreePool (gConfirmOptNo);
|
||||||
|
FreePool (gConfirmOptOk);
|
||||||
|
FreePool (gConfirmOptCancel);
|
||||||
|
FreePool (gYesOption);
|
||||||
|
FreePool (gNoOption);
|
||||||
|
FreePool (gOkOption);
|
||||||
|
FreePool (gCancelOption);
|
||||||
|
FreePool (gErrorPopup);
|
||||||
|
FreePool (gWarningPopup);
|
||||||
|
FreePool (gInfoPopup);
|
||||||
FreePool (gConfirmMsgConnect);
|
FreePool (gConfirmMsgConnect);
|
||||||
FreePool (gConfirmMsgEnd);
|
FreePool (gConfirmMsgEnd);
|
||||||
FreePool (gPasswordUnsupported);
|
FreePool (gPasswordUnsupported);
|
||||||
|
@ -4161,6 +4192,17 @@ InitializeDisplayEngine (
|
||||||
);
|
);
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Install HII Popup Protocol.
|
||||||
|
//
|
||||||
|
Status = gBS->InstallProtocolInterface (
|
||||||
|
&mPrivateData.Handle,
|
||||||
|
&gEfiHiiPopupProtocolGuid,
|
||||||
|
EFI_NATIVE_INTERFACE,
|
||||||
|
&mPrivateData.HiiPopup
|
||||||
|
);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
InitializeDisplayStrings();
|
InitializeDisplayStrings();
|
||||||
|
|
||||||
ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo));
|
ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/** @file
|
/** @file
|
||||||
FormDiplay protocol to show Form
|
FormDiplay protocol to show Form
|
||||||
|
|
||||||
Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials are licensed and made available under
|
This program and the accompanying materials are licensed and made available under
|
||||||
the terms and conditions of the BSD License that accompanies this distribution.
|
the terms and conditions of the BSD License that accompanies this distribution.
|
||||||
The full text of the license may be found at
|
The full text of the license may be found at
|
||||||
|
@ -28,6 +28,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||||
#include <Protocol/FormBrowserEx2.h>
|
#include <Protocol/FormBrowserEx2.h>
|
||||||
#include <Protocol/SimpleTextIn.h>
|
#include <Protocol/SimpleTextIn.h>
|
||||||
#include <Protocol/DisplayProtocol.h>
|
#include <Protocol/DisplayProtocol.h>
|
||||||
|
#include <Protocol/HiiPopup.h>
|
||||||
|
|
||||||
#include <Guid/MdeModuleHii.h>
|
#include <Guid/MdeModuleHii.h>
|
||||||
|
|
||||||
|
@ -41,6 +42,17 @@ extern FORM_DISPLAY_ENGINE_FORM *gFormData;
|
||||||
extern EFI_HII_HANDLE gHiiHandle;
|
extern EFI_HII_HANDLE gHiiHandle;
|
||||||
extern UINT16 gDirection;
|
extern UINT16 gDirection;
|
||||||
extern LIST_ENTRY gMenuOption;
|
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;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Browser Global Strings
|
// Browser Global Strings
|
||||||
|
@ -139,6 +151,7 @@ typedef struct {
|
||||||
// Produced protocol
|
// Produced protocol
|
||||||
//
|
//
|
||||||
EDKII_FORM_DISPLAY_ENGINE_PROTOCOL FromDisplayProt;
|
EDKII_FORM_DISPLAY_ENGINE_PROTOCOL FromDisplayProt;
|
||||||
|
EFI_HII_POPUP_PROTOCOL HiiPopup;
|
||||||
} FORM_DISPLAY_DRIVER_PRIVATE_DATA;
|
} FORM_DISPLAY_DRIVER_PRIVATE_DATA;
|
||||||
|
|
||||||
|
|
||||||
|
@ -272,6 +285,60 @@ typedef struct {
|
||||||
|
|
||||||
#define MENU_OPTION_FROM_LINK(a) CR (a, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE)
|
#define MENU_OPTION_FROM_LINK(a) CR (a, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE)
|
||||||
|
|
||||||
|
#define USER_SELECTABLE_OPTION_OK_WIDTH StrLen (gOkOption)
|
||||||
|
#define USER_SELECTABLE_OPTION_OK_CAL_WIDTH (StrLen (gOkOption) + StrLen (gCancelOption))
|
||||||
|
#define USER_SELECTABLE_OPTION_YES_NO_WIDTH (StrLen (gYesOption) + StrLen (gNoOption))
|
||||||
|
#define USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH (StrLen (gYesOption) + StrLen (gNoOption) + StrLen (gCancelOption))
|
||||||
|
|
||||||
|
#define USER_SELECTABLE_OPTION_SKIP_WIDTH 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// +-------------------------------------------+ // POPUP_BORDER }
|
||||||
|
// | ERROR/WARNING/INFO | // POPUP_STYLE_STRING_HEIGHT } POPUP_HEADER_HEIGHT
|
||||||
|
// |-------------------------------------------| // POPUP_EMPTY_LINE_HEIGHT }
|
||||||
|
// | popup messages |
|
||||||
|
// | | // POPUP_EMPTY_LINE_HEIGHT }
|
||||||
|
// | user selectable options | // POPUP_USER_SELECTABLE_OPTION_HEIGHT } POPUP_FOOTER_HEIGHT
|
||||||
|
// +-------------------------------------------+ // POPUP_BORDER }
|
||||||
|
//
|
||||||
|
#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 + POPUP_EMPTY_LINE_HEIGHT)
|
||||||
|
#define POPUP_FOOTER_HEIGHT (POPUP_EMPTY_LINE_HEIGHT + POPUP_USER_SELECTABLE_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, Link, USER_SELECTABLE_OPTION_SIGNATURE)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Print Question Value according to it's storage width and display attributes.
|
Print Question Value according to it's storage width and display attributes.
|
||||||
|
|
||||||
|
@ -650,4 +717,31 @@ UpdateHighlightMenuInfo (
|
||||||
IN UINTN SkipValue
|
IN UINTN SkipValue
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
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 valid HII string.
|
||||||
|
@retval EFI_INVALID_PARAMETER PopupType is not one of the values defined 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
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// *++
|
// *++
|
||||||
//
|
//
|
||||||
// Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
|
// Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
// This program and the accompanying materials
|
// This program and the accompanying materials
|
||||||
// are licensed and made available under the terms and conditions of the BSD License
|
// 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
|
// which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -103,6 +103,10 @@
|
||||||
#language fr-FR "Y (y)"
|
#language fr-FR "Y (y)"
|
||||||
#string CONFIRM_OPTION_NO #language en-US "N (n)"
|
#string CONFIRM_OPTION_NO #language en-US "N (n)"
|
||||||
#language fr-FR "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 "
|
#string CONFIRM_OPTION_CONNECT #language en-US " and "
|
||||||
#language fr-FR " and "
|
#language fr-FR " and "
|
||||||
#string CONFIRM_OPTION_END #language en-US "?"
|
#string CONFIRM_OPTION_END #language en-US "?"
|
||||||
|
@ -119,4 +123,18 @@
|
||||||
#language fr-FR " Get data/time fail, display ??."
|
#language fr-FR " Get data/time fail, display ??."
|
||||||
#string PASSWORD_NOT_SUPPORTED #language en-US "Unsupported! Because no interactieve flag or no ConfigAccess protocol!"
|
#string PASSWORD_NOT_SUPPORTED #language en-US "Unsupported! Because no interactieve flag or no ConfigAccess protocol!"
|
||||||
#language fr-FR "Unsupported! Because no interactieve flag or no ConfigAccess protocol!"
|
#language fr-FR "Unsupported! Because 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"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,730 @@
|
||||||
|
/** @file
|
||||||
|
Implementation for Hii Popup Protocol.
|
||||||
|
|
||||||
|
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
||||||
|
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.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
#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 = GetFirstNode (OptionList);
|
||||||
|
SelectableOption = 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 = AllocateZeroPool (sizeof (USER_SELECTABLE_OPTION));
|
||||||
|
if (UserSelectableOption == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Initialize the user selectable option based on the PopupType and OptionType.
|
||||||
|
// And then add the option to the option list gUserSelectableOptions.
|
||||||
|
//
|
||||||
|
UserSelectableOption->Signature = USER_SELECTABLE_OPTION_SIGNATURE;
|
||||||
|
UserSelectableOption->OptionString = OptionString;
|
||||||
|
UserSelectableOption->OptionType = OptionType;
|
||||||
|
UserSelectableOption->OptionCol = OptionCol;
|
||||||
|
UserSelectableOption->OptionRow = OptionRow;
|
||||||
|
UserSelectableOption->MinSequence = 0;
|
||||||
|
|
||||||
|
switch (PopupType) {
|
||||||
|
case EfiHiiPopupTypeOk:
|
||||||
|
UserSelectableOption->MaxSequence = 0;
|
||||||
|
UserSelectableOption->Sequence= 0;
|
||||||
|
break;
|
||||||
|
case EfiHiiPopupTypeOkCancel:
|
||||||
|
UserSelectableOption->MaxSequence = 1;
|
||||||
|
if (OptionType == EfiHiiPopupSelectionOk) {
|
||||||
|
UserSelectableOption->Sequence= 0;
|
||||||
|
} else {
|
||||||
|
UserSelectableOption->Sequence= 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EfiHiiPopupTypeYesNo:
|
||||||
|
UserSelectableOption->MaxSequence = 1;
|
||||||
|
if (OptionType == EfiHiiPopupSelectionYes) {
|
||||||
|
UserSelectableOption->Sequence = 0;
|
||||||
|
} else {
|
||||||
|
UserSelectableOption->Sequence = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EfiHiiPopupTypeYesNoCancel:
|
||||||
|
UserSelectableOption->MaxSequence = 2;
|
||||||
|
if (OptionType == EfiHiiPopupSelectionYes) {
|
||||||
|
UserSelectableOption->Sequence = 0;
|
||||||
|
} else if (OptionType == EfiHiiPopupSelectionNo){
|
||||||
|
UserSelectableOption->Sequence = 1;
|
||||||
|
} else {
|
||||||
|
UserSelectableOption->Sequence = 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 = EFI_SUCCESS;
|
||||||
|
EndCol = gPopupDimensions.RightColumn;
|
||||||
|
StartCol = gPopupDimensions.LeftColumn;
|
||||||
|
OptionRow = gPopupDimensions.BottomRow - POPUP_BORDER;
|
||||||
|
ColDimension = EndCol - StartCol + 1;
|
||||||
|
|
||||||
|
InitializeListHead (&gUserSelectableOptions);
|
||||||
|
|
||||||
|
switch (PopupType) {
|
||||||
|
case EfiHiiPopupTypeOk:
|
||||||
|
//
|
||||||
|
// Add [Ok] option to the option list.
|
||||||
|
//
|
||||||
|
OptionCol = StartCol + (ColDimension - USER_SELECTABLE_OPTION_OK_WIDTH) / 2;
|
||||||
|
Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionOk, gOkOption, OptionCol, OptionRow);
|
||||||
|
break;
|
||||||
|
case EfiHiiPopupTypeOkCancel:
|
||||||
|
//
|
||||||
|
// Add [Ok] and [Cancel] options to the option list.
|
||||||
|
//
|
||||||
|
OptionCol = StartCol + (ColDimension - USER_SELECTABLE_OPTION_OK_CAL_WIDTH) / 3;
|
||||||
|
Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionOk, gOkOption, OptionCol, OptionRow);
|
||||||
|
OptionCol = EndCol - (ColDimension - USER_SELECTABLE_OPTION_OK_CAL_WIDTH) / 3 - (GetStringWidth (gCancelOption) -2) / 2 + 1;
|
||||||
|
Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionCancel, gCancelOption, OptionCol, OptionRow);
|
||||||
|
break;
|
||||||
|
case EfiHiiPopupTypeYesNo:
|
||||||
|
//
|
||||||
|
// Add [Yes] and [No] options to the option list.
|
||||||
|
//
|
||||||
|
OptionCol = StartCol + (ColDimension - USER_SELECTABLE_OPTION_YES_NO_WIDTH) / 3;
|
||||||
|
Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionYes, gYesOption, OptionCol, OptionRow);
|
||||||
|
OptionCol = EndCol - (ColDimension - USER_SELECTABLE_OPTION_YES_NO_WIDTH) / 3 - (GetStringWidth (gNoOption)- 2) / 2 + 1;
|
||||||
|
Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionNo, gNoOption, OptionCol, OptionRow);
|
||||||
|
break;
|
||||||
|
case EfiHiiPopupTypeYesNoCancel:
|
||||||
|
//
|
||||||
|
// Add [Yes], [No] and [Cancel] options to the option list.
|
||||||
|
//
|
||||||
|
OptionCol = StartCol + (ColDimension - USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH) / 4;
|
||||||
|
Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionYes, gYesOption, OptionCol, OptionRow);
|
||||||
|
OptionCol = StartCol + (ColDimension - (GetStringWidth (gNoOption) -2) / 2) / 2;
|
||||||
|
Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionNo, gNoOption, OptionCol, OptionRow);
|
||||||
|
OptionCol = EndCol - (ColDimension - USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH) / 4 - (GetStringWidth (gCancelOption) - 2) / 2 + 1;
|
||||||
|
Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionCancel, 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 = gUserSelectableOptions.ForwardLink;
|
||||||
|
do {
|
||||||
|
for (Link = gUserSelectableOptions.ForwardLink; Link != &gUserSelectableOptions; Link = Link->ForwardLink) {
|
||||||
|
SelectableOption = SELECTABLE_OPTION_FROM_LINK (Link);
|
||||||
|
DisplayOneSelectableOption (SelectableOption, (BOOLEAN)(Link == HighlightPos));
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//If UserSelection is NULL, there is no need to handle the key user input, just return.
|
||||||
|
//
|
||||||
|
if (UserSelection == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = WaitForKeyStroke (&KeyValue);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
|
HighlightOption = SELECTABLE_OPTION_FROM_LINK (HighlightPos);
|
||||||
|
switch (KeyValue.UnicodeChar) {
|
||||||
|
case CHAR_NULL:
|
||||||
|
switch (KeyValue.ScanCode) {
|
||||||
|
case SCAN_RIGHT:
|
||||||
|
if (HighlightOption->Sequence < HighlightOption->MaxSequence) {
|
||||||
|
HighlightPos = HighlightPos->ForwardLink;
|
||||||
|
} else {
|
||||||
|
HighlightPos = gUserSelectableOptions.ForwardLink;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SCAN_LEFT:
|
||||||
|
if (HighlightOption->Sequence > HighlightOption->MinSequence) {
|
||||||
|
HighlightPos = HighlightPos->BackLink;
|
||||||
|
} else {
|
||||||
|
HighlightPos = gUserSelectableOptions.BackLink;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CHAR_CARRIAGE_RETURN:
|
||||||
|
*UserSelection = HighlightOption->OptionType;
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
if (((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (*gConfirmOptYes | UPPER_LOWER_CASE_OFFSET)) &&
|
||||||
|
(PopupType == EfiHiiPopupTypeYesNo || PopupType == EfiHiiPopupTypeYesNoCancel)) {
|
||||||
|
*UserSelection = EfiHiiPopupSelectionYes;
|
||||||
|
return;
|
||||||
|
} else if ((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (*gConfirmOptNo| UPPER_LOWER_CASE_OFFSET) &&
|
||||||
|
(PopupType == EfiHiiPopupTypeYesNo || PopupType == EfiHiiPopupTypeYesNoCancel)){
|
||||||
|
*UserSelection = EfiHiiPopupSelectionNo;
|
||||||
|
return;
|
||||||
|
} else if ((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (*gConfirmOptOk | UPPER_LOWER_CASE_OFFSET) &&
|
||||||
|
(PopupType == EfiHiiPopupTypeOk || PopupType == EfiHiiPopupTypeOkCancel)){
|
||||||
|
*UserSelection = EfiHiiPopupSelectionOk;
|
||||||
|
return;
|
||||||
|
} else if ((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (*gConfirmOptCancel| UPPER_LOWER_CASE_OFFSET) &&
|
||||||
|
(PopupType == EfiHiiPopupTypeOkCancel || PopupType == EfiHiiPopupTypeYesNoCancel)){
|
||||||
|
*UserSelection = 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 string'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 = 0;
|
||||||
|
CharWidth = 1;
|
||||||
|
|
||||||
|
for (StrOffset = 0; String[StrOffset] != CHAR_NULL; StrOffset++) {
|
||||||
|
switch (String[StrOffset]) {
|
||||||
|
case NARROW_CHAR:
|
||||||
|
CharWidth = 1;
|
||||||
|
break;
|
||||||
|
case WIDE_CHAR:
|
||||||
|
CharWidth = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
StringWidth += CharWidth;
|
||||||
|
if (StringWidth >= MaxWidth) {
|
||||||
|
*Offset = StrOffset;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*Offset = 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 the string.
|
||||||
|
This function call be called recursively to parse the whole InputString.
|
||||||
|
|
||||||
|
(Notice: current implementation, it only checks \r, \n characters, it deals \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 responsible 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 the 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 == NULL || Index == NULL || OutputString == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*OutputStrWidth = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
//Check the string to see if there are line break characters in the string
|
||||||
|
//
|
||||||
|
for (StrOffset = 0;
|
||||||
|
InputString[*Index + StrOffset] != CHAR_CARRIAGE_RETURN && InputString[*Index + StrOffset] != CHAR_LINEFEED && InputString[*Index + StrOffset] != CHAR_NULL;
|
||||||
|
StrOffset++
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// The CHAR_NULL has process last time, this time just return 0 to stand for finishing parsing the InputString.
|
||||||
|
//
|
||||||
|
if (StrOffset == 0 && (InputString[*Index + StrOffset] == CHAR_NULL)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the string to OutputString buffer and calculate the width of OutputString.
|
||||||
|
//
|
||||||
|
*OutputString = AllocateZeroPool ((StrOffset + 1) * sizeof(CHAR16));
|
||||||
|
if (*OutputString == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
CopyMem ((*OutputString), &InputString[*Index], StrOffset * sizeof(CHAR16));
|
||||||
|
*OutputStrWidth = (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] == CHAR_LINEFEED) {
|
||||||
|
//
|
||||||
|
// Skip the /n or /n/r info.
|
||||||
|
//
|
||||||
|
if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {
|
||||||
|
*Index = (*Index + StrOffset + 2);
|
||||||
|
} else {
|
||||||
|
*Index = (*Index + StrOffset + 1);
|
||||||
|
}
|
||||||
|
} else if (InputString[*Index + StrOffset] == CHAR_CARRIAGE_RETURN) {
|
||||||
|
//
|
||||||
|
// Skip the /r or /r/n info.
|
||||||
|
//
|
||||||
|
if (InputString[*Index + StrOffset + 1] == CHAR_LINEFEED) {
|
||||||
|
*Index = (*Index + StrOffset + 2);
|
||||||
|
} else {
|
||||||
|
*Index = (*Index + StrOffset + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*Index = (*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 = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate the row number which is needed to show the message string and the max width of the string in one row.
|
||||||
|
//
|
||||||
|
for (StringIndex = 0; ParseMessageString (gMessageString, &OutputString, &OutputStrWidth, &StringIndex) != 0;) {
|
||||||
|
gMesStrLineNum ++;
|
||||||
|
if (gMaxRowWidth < OutputStrWidth) {
|
||||||
|
gMaxRowWidth = OutputStrWidth;
|
||||||
|
}
|
||||||
|
FreePool (OutputString);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate the row width for the selectable options.(OptionRowWidth = Number * SkipWidth + OptionWidth)
|
||||||
|
//
|
||||||
|
if (PopupType == EfiHiiPopupTypeOk) {
|
||||||
|
OptionRowWidth = USER_SELECTABLE_OPTION_SKIP_WIDTH *2 + USER_SELECTABLE_OPTION_OK_WIDTH;
|
||||||
|
} else if (PopupType == EfiHiiPopupTypeOkCancel) {
|
||||||
|
OptionRowWidth = USER_SELECTABLE_OPTION_SKIP_WIDTH *3 + USER_SELECTABLE_OPTION_OK_CAL_WIDTH;
|
||||||
|
} else if (PopupType == EfiHiiPopupTypeYesNo) {
|
||||||
|
OptionRowWidth = USER_SELECTABLE_OPTION_SKIP_WIDTH *3 + USER_SELECTABLE_OPTION_YES_NO_WIDTH;
|
||||||
|
} else if (PopupType == EfiHiiPopupTypeYesNoCancel) {
|
||||||
|
OptionRowWidth = USER_SELECTABLE_OPTION_SKIP_WIDTH *4 + USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH;
|
||||||
|
}
|
||||||
|
if (OptionRowWidth > gMaxRowWidth) {
|
||||||
|
gMaxRowWidth = OptionRowWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Avialble row width for message string = screen width - left popup border width - right popup border width.
|
||||||
|
// Avialble line number for message string = 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 = MIN (gMaxRowWidth, Columns - 2 * POPUP_BORDER);
|
||||||
|
gMesStrLineNum = MIN (gMesStrLineNum, Rows -1 - POPUP_FOOTER_HEIGHT - POPUP_HEADER_HEIGHT);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Calculate the start column, end column, top row and bottom row for the popup.
|
||||||
|
//
|
||||||
|
ScreenForPopup->LeftColumn = (Columns -2 * POPUP_BORDER - gMaxRowWidth) / 2;
|
||||||
|
ScreenForPopup->RightColumn = ScreenForPopup->LeftColumn + gMaxRowWidth + 2 * POPUP_BORDER - 1;
|
||||||
|
ScreenForPopup->TopRow = (Rows - 1 - POPUP_FOOTER_HEIGHT - POPUP_HEADER_HEIGHT - gMesStrLineNum) / 2;
|
||||||
|
ScreenForPopup->BottomRow = 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 = gPopupDimensions.RightColumn;
|
||||||
|
TopRow = gPopupDimensions.TopRow;
|
||||||
|
StartCol = gPopupDimensions.LeftColumn;
|
||||||
|
BottomRow = gPopupDimensions.BottomRow;
|
||||||
|
ColDimension = EndCol - StartCol + 1;
|
||||||
|
DrawMesStrRowNum = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 1. Draw the top of the message box.
|
||||||
|
//
|
||||||
|
Character = BOXDRAW_DOWN_RIGHT;
|
||||||
|
PrintCharAt (StartCol, TopRow, Character);
|
||||||
|
Character = BOXDRAW_HORIZONTAL;
|
||||||
|
for (Index = StartCol; Index + 1 < EndCol; Index++) {
|
||||||
|
PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
|
||||||
|
}
|
||||||
|
Character = BOXDRAW_DOWN_LEFT;
|
||||||
|
PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 2. Draw the prompt string for different popup styles.
|
||||||
|
//
|
||||||
|
Character = BOXDRAW_VERTICAL;
|
||||||
|
DisplayRow = TopRow + POPUP_BORDER;
|
||||||
|
ClearLines (StartCol, EndCol, DisplayRow, DisplayRow, GetPopupColor ());
|
||||||
|
PrintCharAt (StartCol, DisplayRow, Character);
|
||||||
|
PrintCharAt (EndCol, DisplayRow, Character);
|
||||||
|
if (PopupStyle == EfiHiiPopupStyleError) {
|
||||||
|
PrintStringAt ((ColDimension - (GetStringWidth (gErrorPopup) - 2) / 2) / 2 + StartCol, DisplayRow, gErrorPopup);
|
||||||
|
} else if (PopupStyle == 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 popup styles.
|
||||||
|
//
|
||||||
|
DisplayRow = TopRow + POPUP_BORDER + POPUP_STYLE_STRING_HEIGHT;
|
||||||
|
ClearLines (StartCol, EndCol, DisplayRow, DisplayRow, GetPopupColor ());
|
||||||
|
Character = BOXDRAW_HORIZONTAL;
|
||||||
|
for (Index = StartCol + 1; Index < EndCol; Index++) {
|
||||||
|
PrintCharAt (Index, DisplayRow, Character);
|
||||||
|
}
|
||||||
|
Character = BOXDRAW_VERTICAL;
|
||||||
|
PrintCharAt (StartCol, DisplayRow, Character);
|
||||||
|
PrintCharAt (EndCol, DisplayRow, Character);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 4. Draw the mesage string.
|
||||||
|
//
|
||||||
|
DisplayRow = TopRow + POPUP_HEADER_HEIGHT;
|
||||||
|
for (Index = DisplayRow ,StringIndex = 0; ParseMessageString (gMessageString, &OutputString, &OutputStrWidth, &StringIndex) != 0 && DrawMesStrRowNum < 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 print ... instead.
|
||||||
|
//
|
||||||
|
GetStringOffsetWithWidth (OutputString, gMaxRowWidth, &Length);
|
||||||
|
TempString = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));
|
||||||
|
if (TempString == 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, if yes, print the ...... in the row.
|
||||||
|
//
|
||||||
|
if (OutputStrWidth > 0 && DrawMesStrRowNum >= gMesStrLineNum) {
|
||||||
|
PrintStringAt ((ColDimension - StrLen (L"......")) / 2 + StartCol, Index, L"......");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 6. Draw an empty line which is used to show user selectable options, will draw concrete option strings in function GetUserSelection().
|
||||||
|
//
|
||||||
|
Character = BOXDRAW_VERTICAL;
|
||||||
|
DisplayRow = 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 = BOXDRAW_UP_RIGHT;
|
||||||
|
PrintCharAt (StartCol, BottomRow, Character);
|
||||||
|
Character = BOXDRAW_HORIZONTAL;
|
||||||
|
for (Index = StartCol; Index + 1 < EndCol; Index++) {
|
||||||
|
PrintCharAt ((UINTN)-1, (UINTN) -1, Character);
|
||||||
|
}
|
||||||
|
Character = 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 valid HII string.
|
||||||
|
@retval EFI_INVALID_PARAMETER PopupType is not one of the values defined 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 > EfiHiiPopupTypeYesNoCancel)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((HiiHandle == NULL) || (Message == 0)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
gMessageString = HiiGetString (HiiHandle, Message, NULL);
|
||||||
|
if((gMessageString == NULL)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConOut = gST->ConOut;
|
||||||
|
gMaxRowWidth = 0;
|
||||||
|
gMesStrLineNum = 0;
|
||||||
|
|
||||||
|
CopyMem (&SavedConsoleMode, ConOut->Mode, sizeof (SavedConsoleMode));
|
||||||
|
ConOut->EnableCursor (ConOut, FALSE);
|
||||||
|
ConOut->SetAttribute (ConOut, GetPopupColor ());
|
||||||
|
|
||||||
|
CalculatePopupPosition (PopupType, &gPopupDimensions);
|
||||||
|
|
||||||
|
Status = DrawMessageBox (PopupStyle);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add user selectable options to option list: gUserSelectableOptions
|
||||||
|
//
|
||||||
|
Status = 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, SavedConsoleMode.CursorRow);
|
||||||
|
ConOut->SetAttribute (ConOut, SavedConsoleMode.Attribute);
|
||||||
|
FreeSelectableOptions (&gUserSelectableOptions);
|
||||||
|
FreePool (gMessageString);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue