diff options
Diffstat (limited to 'MdeModulePkg')
28 files changed, 8884 insertions, 12296 deletions
diff --git a/MdeModulePkg/Include/Library/CustomizedDisplayLib.h b/MdeModulePkg/Include/Library/CustomizedDisplayLib.h deleted file mode 100644 index 31e1091e88..0000000000 --- a/MdeModulePkg/Include/Library/CustomizedDisplayLib.h +++ /dev/null @@ -1,356 +0,0 @@ -/** @file
- This library class defines a set of interfaces to customize Display module
-
-Copyright (c) 2013, 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 that 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.
-
-**/
-
-#ifndef __CUSTOMIZED_DISPLAY_LIB_H__
-#define __CUSTOMIZED_DISPLAY_LIB_H__
-
-#include <Protocol/DisplayProtocol.h>
-
-/**
-+------------------------------------------------------------------------------+
-| Setup Page |
-+------------------------------------------------------------------------------+
-
-Statement
-Statement
-Statement
-
-
-
-
-
-+------------------------------------------------------------------------------+
-| F9=Reset to Defaults F10=Save |
-| ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Exit |
-+------------------------------------------------------------------------------+
- StatusBar
-**/
-
-/**
- This funtion defines Page Frame and Backgroud.
-
- Based on the above layout, it will be responsible for HeaderHeight, FooterHeight,
- StatusBarHeight and Backgroud. And, it will reserve Screen for Statement.
-
- @param[in] FormData Form Data to be shown in Page.
- @param[out] ScreenForStatement Screen to be used for Statement. (Prompt, Value and Help)
-
- @return Status
-**/
-EFI_STATUS
-EFIAPI
-DisplayPageFrame (
- IN FORM_DISPLAY_ENGINE_FORM *FormData,
- OUT EFI_SCREEN_DESCRIPTOR *ScreenForStatement
- );
-
-/**
- Clear Screen to the initial state.
-**/
-VOID
-EFIAPI
-ClearDisplayPage (
- VOID
- );
-
-/**
- This function updates customized key panel's help information.
- The library will prepare those Strings for the basic key, ESC, Enter, Up/Down/Left/Right, +/-.
- and arrange them in Footer panel.
-
- @param[in] FormData Form Data to be shown in Page. FormData has the highlighted statement.
- @param[in] Statement The statement current selected.
- @param[in] Selected Whether or not a tag be selected. TRUE means Enter has hit this question.
-**/
-VOID
-EFIAPI
-RefreshKeyHelp (
- IN FORM_DISPLAY_ENGINE_FORM *FormData,
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
- IN BOOLEAN Selected
- );
-
-/**
- Update status bar.
-
- This function updates the status bar on the bottom of menu screen. It just shows StatusBar.
- Original logic in this function should be splitted out.
-
- @param[in] MessageType The type of message to be shown. InputError or Configuration Changed.
- @param[in] State Show or Clear Message.
-**/
-VOID
-EFIAPI
-UpdateStatusBar (
- IN UINTN MessageType,
- IN BOOLEAN State
- );
-
-/**
- Create popup window.
-
- This function draws OEM/Vendor specific pop up windows.
-
- @param[out] Key User Input Key
- @param ... String to be shown in Popup. The variable argument list is terminated by a NULL.
-
-**/
-VOID
-EFIAPI
-CreateDialog (
- OUT EFI_INPUT_KEY *Key, OPTIONAL
- ...
- );
-
-/**
- Confirm how to handle the changed data.
-
- @return Action BROWSER_ACTION_SUBMIT, BROWSER_ACTION_DISCARD or other values.
-**/
-UINTN
-EFIAPI
-ConfirmDataChange (
- VOID
- );
-
-/**
- OEM specifies whether Setup exits Page by ESC key.
-
- This function customized the behavior that whether Setup exits Page so that
- system able to boot when configuration is not changed.
-
- @retval TRUE Exits FrontPage
- @retval FALSE Don't exit FrontPage.
-**/
-BOOLEAN
-EFIAPI
-FormExitPolicy (
- VOID
- );
-
-/**
- Set Timeout value for a ceratain Form to get user response.
-
- This function allows to set timeout value on a ceratain form if necessary.
- If timeout is not zero, the form will exit if user has no response in timeout.
-
- @param[in] FormData Form Data to be shown in Page
-
- @return 0 No timeout for this form.
- @return > 0 Timeout value in 100 ns units.
-**/
-UINT64
-EFIAPI
-FormExitTimeout (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- );
-
-//
-// Print Functions
-//
-/**
- Prints a unicode string to the default console, at
- the supplied cursor position, using L"%s" format.
-
- @param Column The cursor position to print the string at. When it is -1, use current Position.
- @param Row The cursor position to print the string at. When it is -1, use current Position.
- @param String String pointer.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-EFIAPI
-PrintStringAt (
- IN UINTN Column,
- IN UINTN Row,
- IN CHAR16 *String
- );
-
-
-/**
- Prints a unicode string with the specified width to the default console, at
- the supplied cursor position, using L"%s" format.
-
- @param Column The cursor position to print the string at. When it is -1, use current Position.
- @param Row The cursor position to print the string at. When it is -1, use current Position.
- @param String String pointer.
- @param Width Width for String to be printed. If the print length of String < Width,
- Space char (L' ') will be used to append String.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-EFIAPI
-PrintStringAtWithWidth (
- IN UINTN Column,
- IN UINTN Row,
- IN CHAR16 *String,
- IN UINTN Width
- );
-
-/**
- Prints a chracter to the default console, at
- the supplied cursor position, using L"%c" format.
-
- @param Column The cursor position to print the string at. When it is -1, use current Position.
- @param Row The cursor position to print the string at. When it is -1, use current Position.
- @param Character Character to print.
-
- @return Length of string printed to the console.
-
-**/
-UINTN
-EFIAPI
-PrintCharAt (
- IN UINTN Column,
- IN UINTN Row,
- CHAR16 Character
- );
-
-/**
- Clear retangle with specified text attribute.
-
- @param LeftColumn Left column of retangle.
- @param RightColumn Right column of retangle.
- @param TopRow Start row of retangle.
- @param BottomRow End row of retangle.
- @param TextAttribute The character foreground and background.
-
-**/
-VOID
-EFIAPI
-ClearLines (
- IN UINTN LeftColumn,
- IN UINTN RightColumn,
- IN UINTN TopRow,
- IN UINTN BottomRow,
- IN UINTN TextAttribute
- );
-
-//
-// Color Setting Functions
-//
-/**
- Get OEM/Vendor specific popup attribute colors.
-
- @retval Byte code color setting for popup color.
-**/
-UINT8
-EFIAPI
-GetPopupColor (
- VOID
- );
-
-/**
- Get OEM/Vendor specific popup attribute colors.
-
- @retval Byte code color setting for popup inverse color.
-**/
-UINT8
-EFIAPI
-GetPopupInverseColor (
- VOID
- );
-
-/**
- Get OEM/Vendor specific PickList color attribute.
-
- @retval Byte code color setting for pick list color.
-**/
-UINT8
-EFIAPI
-GetPickListColor (
- VOID
- );
-
-/**
- Get OEM/Vendor specific arrow color attribute.
-
- @retval Byte code color setting for arrow color.
-**/
-UINT8
-EFIAPI
-GetArrowColor (
- VOID
- );
-
-/**
- Get OEM/Vendor specific info text color attribute.
-
- @retval Byte code color setting for info text color.
-**/
-UINT8
-EFIAPI
-GetInfoTextColor (
- VOID
- );
-
-/**
- Get OEM/Vendor specific help text color attribute.
-
- @retval Byte code color setting for help text color.
-**/
-UINT8
-EFIAPI
-GetHelpTextColor (
- VOID
- );
-
-/**
- Get OEM/Vendor specific grayed out text color attribute.
-
- @retval Byte code color setting for grayed out text color.
-**/
-UINT8
-EFIAPI
-GetGrayedTextColor (
- VOID
- );
-
-/**
- Get OEM/Vendor specific highlighted text color attribute.
-
- @retval Byte code color setting for highlight text color.
-**/
-UINT8
-EFIAPI
-GetHighlightTextColor (
- VOID
- );
-
-/**
- Get OEM/Vendor specific field text color attribute.
-
- @retval Byte code color setting for field text color.
-**/
-UINT8
-EFIAPI
-GetFieldTextColor (
- VOID
- );
-
-/**
- Get OEM/Vendor specific subtitle text color attribute.
-
- @retval Byte code color setting for subtitle text color.
-**/
-UINT8
-EFIAPI
-GetSubTitleTextColor (
- VOID
- );
-
-#endif
diff --git a/MdeModulePkg/Include/Protocol/DisplayProtocol.h b/MdeModulePkg/Include/Protocol/DisplayProtocol.h deleted file mode 100644 index d4f0debf9c..0000000000 --- a/MdeModulePkg/Include/Protocol/DisplayProtocol.h +++ /dev/null @@ -1,350 +0,0 @@ -/** @file
- FormDiplay protocol to show Form
-
-Copyright (c) 2013, 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 that 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.
-
-**/
-
-#ifndef __DISPLAY_PROTOCOL_H__
-#define __DISPLAY_PROTOCOL_H__
-
-#include <Protocol/FormBrowser2.h>
-
-#define EDKII_FORM_DISPLAY_ENGINE_PROTOCOL_GUID \
- { 0x9bbe29e9, 0xfda1, 0x41ec, { 0xad, 0x52, 0x45, 0x22, 0x13, 0x74, 0x2d, 0x2e } }
-
-//
-// Do nothing.
-//
-#define BROWSER_ACTION_NONE BIT16
-//
-// ESC Exit
-//
-#define BROWSER_ACTION_FORM_EXIT BIT17
-
-#define BROWSER_SUCCESS 0x0
-#define BROWSER_ERROR BIT31
-#define BROWSER_SUBMIT_FAIL BROWSER_ERROR | 0x01
-#define BROWSER_NO_SUBMIT_IF BROWSER_ERROR | 0x02
-#define BROWSER_FORM_NOT_FOUND BROWSER_ERROR | 0x03
-#define BROWSER_FORM_SUPPRESS BROWSER_ERROR | 0x04
-#define BROWSER_PROTOCOL_NOT_FOUND BROWSER_ERROR | 0x05
-
-#define FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1 0x10000
-#define FORM_DISPLAY_ENGINE_VERSION_1 0x10000
-
-typedef struct {
- //
- // HII Data Type
- //
- UINT8 Type;
- //
- // Buffer Data and Length if Type is EFI_IFR_TYPE_BUFFER or EFI_IFR_TYPE_STRING
- //
- UINT8 *Buffer;
- UINT16 BufferLen;
- EFI_IFR_TYPE_VALUE Value;
-} EFI_HII_VALUE;
-
-#define DISPLAY_QUESTION_OPTION_SIGNATURE SIGNATURE_32 ('Q', 'O', 'P', 'T')
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
- //
- // OneOfOption Data
- //
- EFI_IFR_ONE_OF_OPTION *OptionOpCode;
- //
- // Option ImageId and AnimationId
- //
- EFI_IMAGE_ID ImageId;
- EFI_ANIMATION_ID AnimationId;
-} DISPLAY_QUESTION_OPTION;
-
-#define DISPLAY_QUESTION_OPTION_FROM_LINK(a) CR (a, DISPLAY_QUESTION_OPTION, Link, DISPLAY_QUESTION_OPTION_SIGNATURE)
-
-typedef struct _FORM_DISPLAY_ENGINE_STATEMENT FORM_DISPLAY_ENGINE_STATEMENT;
-typedef struct _FORM_DISPLAY_ENGINE_FORM FORM_DISPLAY_ENGINE_FORM;
-
-#define STATEMENT_VALID 0x0
-#define STATEMENT_INVALID BIT31
-
-#define INCOSISTENT_IF_TRUE STATEMENT_INVALID | 0x01
-#define WARNING_IF_TRUE STATEMENT_INVALID | 0x02
-#define STRING_TOO_LONG STATEMENT_INVALID | 0x03
-// ... to be extended.
-
-typedef struct {
- //
- // StringId for INCONSITENT_IF or WARNING_IF
- //
- EFI_STRING_ID StringId;
- //
- // TimeOut for WARNING_IF
- //
- UINT8 TimeOut;
-} STATEMENT_ERROR_INFO;
-
-/**
- Perform value check for a question.
-
- @param Form Form where Statement is in.
- @param Statement Value will check for it.
- @param Value New value will be checked.
-
- @retval Status Value Status
-
-**/
-typedef
-UINT32
-(EFIAPI *VALIDATE_QUESTION) (
- IN FORM_DISPLAY_ENGINE_FORM *Form,
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
- IN EFI_HII_VALUE *Value,
- OUT STATEMENT_ERROR_INFO *ErrorInfo
- );
-
-/**
- Perform Password check.
- Passwork may be encrypted by driver that requires the specific check.
-
- @param Form Form where Password Statement is in.
- @param Statement Password statement
- @param PasswordString Password string to be checked. It may be NULL.
- NULL means to restore password.
- "" string can be used to checked whether old password does exist.
-
- @return Status Status of Password check.
-**/
-typedef
-EFI_STATUS
-(EFIAPI *PASSWORD_CHECK) (
- IN FORM_DISPLAY_ENGINE_FORM *Form,
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
- IN EFI_STRING PasswordString OPTIONAL
- );
-
-#define FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE SIGNATURE_32 ('F', 'S', 'T', 'A')
-
-//
-// Attribute for Statement and Form
-//
-#define HII_DISPLAY_GRAYOUT BIT0
-#define HII_DISPLAY_LOCK BIT1
-#define HII_DISPLAY_READONLY BIT2
-#define HII_DISPLAY_MODAL BIT3
-
-struct _FORM_DISPLAY_ENGINE_STATEMENT{
- UINTN Signature;
- //
- // Version for future structure extension
- //
- UINTN Version;
- //
- // link to all the statement which will show in the display form.
- //
- LIST_ENTRY DisplayLink;
- //
- // Pointer to statement opcode.
- // for Guided Opcode. All buffers will be here if GUIDED opcode scope is set.
- //
- EFI_IFR_OP_HEADER *OpCode;
- //
- // Question CurrentValue
- //
- EFI_HII_VALUE CurrentValue;
- //
- // Flag to describe whether setting is changed or not.
- // Displayer may depend on it to show it with the different color.
- //
- BOOLEAN SettingChangedFlag;
- //
- // nested Statement list inside of EFI_IFR_SUBTITLE
- //
- LIST_ENTRY NestStatementList;
- //
- // nested EFI_IFR_ONE_OF_OPTION list (QUESTION_OPTION)
- //
- LIST_ENTRY OptionListHead;
- //
- // Statement attributes: GRAYOUT, LOCK and READONLY
- //
- UINT32 Attribute;
-
- //
- // ValidateQuestion to do InconsistIf check
- // It may be NULL if any value is valid.
- //
- VALIDATE_QUESTION ValidateQuestion;
-
- //
- // Password additional check. It may be NULL when the additional check is not required.
- //
- PASSWORD_CHECK PasswordCheck;
-
- //
- // Statement ImageId and AnimationId
- //
- EFI_IMAGE_ID ImageId;
- EFI_ANIMATION_ID AnimationId;
-};
-
-#define FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK(a) CR (a, FORM_DISPLAY_ENGINE_STATEMENT, DisplayLink, FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE)
-
-#define BROWSER_HOT_KEY_SIGNATURE SIGNATURE_32 ('B', 'H', 'K', 'S')
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
-
- EFI_INPUT_KEY *KeyData;
- //
- // Action is Discard, Default, Submit, Reset and Exit.
- //
- UINT32 Action;
- UINT16 DefaultId;
- //
- // HotKey Help String
- //
- EFI_STRING HelpString;
-} BROWSER_HOT_KEY;
-
-#define BROWSER_HOT_KEY_FROM_LINK(a) CR (a, BROWSER_HOT_KEY, Link, BROWSER_HOT_KEY_SIGNATURE)
-
-#define FORM_DISPLAY_ENGINE_FORM_SIGNATURE SIGNATURE_32 ('F', 'F', 'R', 'M')
-
-struct _FORM_DISPLAY_ENGINE_FORM {
- UINTN Signature;
- //
- // Version for future structure extension
- //
- UINTN Version;
- //
- // Statement List inside of Form
- //
- LIST_ENTRY StatementListHead;
- //
- // Statement List outside of Form
- //
- LIST_ENTRY StatementListOSF;
- //
- // The input screen dimenstions info.
- //
- EFI_SCREEN_DESCRIPTOR *ScreenDimensions;
- //
- // FormSet information
- //
- EFI_GUID FormSetGuid;
- //
- // HiiHandle can be used to get String, Image or Animation
- //
- EFI_HII_HANDLE HiiHandle;
-
- //
- // Form ID and Title.
- //
- UINT16 FormId;
- EFI_STRING_ID FormTitle;
- //
- // Form Attributes: Lock, Modal.
- //
- UINT32 Attribute;
- //
- // Flag to describe whether setting is changed or not.
- // Displayer depends on it to show ChangedFlag.
- //
- BOOLEAN SettingChangedFlag;
-
- //
- // Statement to be HighLighted
- //
- FORM_DISPLAY_ENGINE_STATEMENT *HighLightedStatement;
- //
- // Event to notify Displayer that FormData is updated to be refreshed.
- //
- EFI_EVENT FormRefreshEvent;
- //
- // Additional Hotkey registered by BrowserEx protocol.
- //
- LIST_ENTRY HotKeyListHead;
-
- //
- // Form ImageId and AnimationId
- //
- EFI_IMAGE_ID ImageId;
- EFI_ANIMATION_ID AnimationId;
-
- //
- // If Status is error, display needs to handle it.
- //
- UINT32 BrowserStatus;
- //
- // String for error status. It may be NULL.
- //
- EFI_STRING ErrorString;
-};
-
-#define FORM_DISPLAY_ENGINE_FORM_FROM_LINK(a) CR (a, FORM_DISPLAY_ENGINE_FORM, Link, FORM_DISPLAY_ENGINE_FORM_SIGNATURE)
-
-typedef struct {
- FORM_DISPLAY_ENGINE_STATEMENT *SelectedStatement; // Selected Statement and InputValue
-
- EFI_HII_VALUE InputValue;
-
- UINT32 Action; // If SelectedStatement is NULL, Action will be used.
- // Trig Action (Discard, Default, Submit, Reset and Exit)
- UINT16 DefaultId;
-} USER_INPUT;
-
-/**
- Display one form, and return user input.
-
- @param FormData Form Data to be shown.
- @param UserInputData User input data.
-
- @retval EFI_SUCCESS Form Data is shown, and user input is got.
-**/
-typedef
-EFI_STATUS
-(EFIAPI *FORM_DISPLAY) (
- IN FORM_DISPLAY_ENGINE_FORM *FormData,
- OUT USER_INPUT *UserInputData
-);
-
-/**
- Exit Display and Clear Screen to the original state.
-
-**/
-typedef
-VOID
-(EFIAPI *EXIT_DISPLAY) (
- VOID
-);
-
-/**
- Confirm how to handle the changed data.
-
- @return Action of Submit, Discard and None
-**/
-typedef
-UINTN
-(EFIAPI *CONFIRM_DATA_CHANGE) (
- VOID
-);
-
-typedef struct {
- FORM_DISPLAY FormDisplay;
- EXIT_DISPLAY ExitDisplay;
- CONFIRM_DATA_CHANGE ConfirmDataChange;
-} EDKII_FORM_DISPLAY_ENGINE_PROTOCOL;
-
-extern EFI_GUID gEdkiiFormDisplayEngineProtocolGuid;
-#endif
diff --git a/MdeModulePkg/Include/Protocol/FormBrowserEx2.h b/MdeModulePkg/Include/Protocol/FormBrowserEx2.h deleted file mode 100644 index 105ac0308f..0000000000 --- a/MdeModulePkg/Include/Protocol/FormBrowserEx2.h +++ /dev/null @@ -1,90 +0,0 @@ -/** @file
- Extension Form Browser Protocol provides the services that can be used to
- register the different hot keys for the standard Browser actions described in UEFI specification.
-
-Copyright (c) 2013, 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 that 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.
-
-**/
-
-#ifndef __FORM_BROWSER_EXTENSION2_H__
-#define __FORM_BROWSER_EXTENSION2_H__
-
-#include <Protocol/FormBrowserEx.h>
-
-#define EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL_GUID \
- { 0xa770c357, 0xb693, 0x4e6d, { 0xa6, 0xcf, 0xd2, 0x1c, 0x72, 0x8e, 0x55, 0xb }}
-
-typedef struct _EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL;
-
-#define BROWSER_EXTENSION2_VERSION_1 0x10000
-
-/**
- Check whether the browser data has been modified.
-
- @retval TRUE Browser data is modified.
- @retval FALSE No browser data is modified.
-
-**/
-typedef
-BOOLEAN
-(EFIAPI *IS_BROWSER_DATA_MODIFIED) (
- VOID
- );
-
-/**
- Execute the action requested by the Action parameter.
-
- @param[in] Action Execute the request action.
- @param[in] DefaultId The default Id info when need to load default value.
-
- @retval EFI_SUCCESS Execute the request action succss.
-
-**/
-typedef
-EFI_STATUS
-(EFIAPI *EXECUTE_ACTION) (
- IN UINT32 Action,
- IN UINT16 DefaultId
- );
-
-#define FORM_ENTRY_INFO_SIGNATURE SIGNATURE_32 ('f', 'e', 'i', 's')
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
-
- EFI_HII_HANDLE HiiHandle;
- EFI_GUID FormSetGuid;
- EFI_FORM_ID FormId;
- EFI_QUESTION_ID QuestionId;
-} FORM_ENTRY_INFO;
-
-#define FORM_ENTRY_INFO_FROM_LINK(a) CR (a, FORM_ENTRY_INFO, Link, FORM_ENTRY_INFO_SIGNATURE)
-
-struct _EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL {
- ///
- /// Version for protocol future extension.
- ///
- UINT32 Version;
- SET_SCOPE SetScope;
- REGISTER_HOT_KEY RegisterHotKey;
- REGISTER_EXIT_HANDLER RegiserExitHandler;
- IS_BROWSER_DATA_MODIFIED IsBrowserDataModified;
- EXECUTE_ACTION ExecuteAction;
- ///
- /// A list of type FORMID_INFO is Browser View Form History List.
- ///
- LIST_ENTRY FormViewHistoryHead;
-};
-
-extern EFI_GUID gEdkiiFormBrowserEx2ProtocolGuid;
-
-#endif
-
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c deleted file mode 100644 index aa28146b02..0000000000 --- a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.c +++ /dev/null @@ -1,921 +0,0 @@ -/** @file
-
- This library class defines a set of interfaces to customize Display module
-
-Copyright (c) 2013, 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 that 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 "CustomizedDisplayLibInternal.h"
-
-EFI_GUID gCustomizedDisplayLibGuid = { 0x99fdc8fd, 0x849b, 0x4eba, { 0xad, 0x13, 0xfb, 0x96, 0x99, 0xc9, 0xa, 0x4d } };
-
-EFI_HII_HANDLE mCDLStringPackHandle;
-UINT16 gClassOfVfr; // Formset class information
-BOOLEAN gLibIsFirstForm = TRUE;
-BANNER_DATA *gBannerData;
-
-UINTN gFooterHeight;
-
-/**
-+------------------------------------------------------------------------------+
-| Setup Page |
-+------------------------------------------------------------------------------+
-
-Statement
-Statement
-Statement
-
-
-
-
-
-+------------------------------------------------------------------------------+
-| F9=Reset to Defaults F10=Save |
-| ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Exit |
-+------------------------------------------------------------------------------+
- StatusBar
-**/
-
-/**
- This funtion defines Page Frame and Backgroud.
-
- Based on the above layout, it will be responsible for HeaderHeight, FooterHeight,
- StatusBarHeight and Backgroud. And, it will reserve Screen for Statement.
-
- @param[in] FormData Form Data to be shown in Page.
- @param[out] ScreenForStatement Screen to be used for Statement. (Prompt, Value and Help)
-
- @return Status
-**/
-EFI_STATUS
-EFIAPI
-DisplayPageFrame (
- IN FORM_DISPLAY_ENGINE_FORM *FormData,
- OUT EFI_SCREEN_DESCRIPTOR *ScreenForStatement
- )
-{
- EFI_STATUS Status;
-
- ASSERT (FormData != NULL && ScreenForStatement != NULL);
- if (FormData == NULL || ScreenForStatement == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = ScreenDiemensionInfoValidate (FormData);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP;
-
- ProcessExternedOpcode(FormData);
-
- //
- // Calculate the ScreenForStatement.
- //
- ScreenForStatement->BottomRow = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight;
- if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {
- ScreenForStatement->TopRow = gScreenDimensions.TopRow + FRONT_PAGE_HEADER_HEIGHT;
- } else {
- ScreenForStatement->TopRow = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT;
- }
- ScreenForStatement->LeftColumn = gScreenDimensions.LeftColumn;
- ScreenForStatement->RightColumn = gScreenDimensions.RightColumn;
-
- if ((gLibIsFirstForm) || ((FormData->Attribute & HII_DISPLAY_MODAL) != 0)) {
- //
- // Ensure we are in Text mode
- //
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- ClearLines (0, gScreenDimensions.RightColumn, 0, gScreenDimensions.BottomRow, KEYHELP_BACKGROUND);
- gLibIsFirstForm = FALSE;
- }
-
- //
- // Don't print frame for modal form.
- //
- if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
- return EFI_SUCCESS;
- }
-
- if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {
- PrintBannerInfo (FormData);
- }
-
- PrintFramework (FormData);
-
- UpdateStatusBar(NV_UPDATE_REQUIRED, FormData->SettingChangedFlag);
-
- return EFI_SUCCESS;
-}
-
-/**
- This function updates customized key panel's help information.
- The library will prepare those Strings for the basic key, ESC, Enter, Up/Down/Left/Right, +/-.
- and arrange them in Footer panel.
-
- @param[in] FormData Form Data to be shown in Page. FormData has the highlighted statement.
- @param[in] Statement The statement current selected.
- @param[in] Selected Whether or not a tag be selected. TRUE means Enter has hit this question.
-**/
-VOID
-EFIAPI
-RefreshKeyHelp (
- IN FORM_DISPLAY_ENGINE_FORM *FormData,
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
- IN BOOLEAN Selected
- )
-{
- UINTN SecCol;
- UINTN ThdCol;
- UINTN LeftColumnOfHelp;
- UINTN RightColumnOfHelp;
- UINTN TopRowOfHelp;
- UINTN BottomRowOfHelp;
- UINTN StartColumnOfHelp;
- EFI_IFR_NUMERIC *NumericOp;
- EFI_IFR_DATE *DateOp;
- EFI_IFR_TIME *TimeOp;
- BOOLEAN HexDisplay;
-
- ASSERT (FormData != NULL);
- if (FormData == NULL) {
- return;
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
-
- if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
- return;
- }
-
- SecCol = gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3;
- ThdCol = gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3 * 2;
-
- StartColumnOfHelp = gScreenDimensions.LeftColumn + 2;
- LeftColumnOfHelp = gScreenDimensions.LeftColumn + 1;
- RightColumnOfHelp = gScreenDimensions.RightColumn - 2;
- TopRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;
- BottomRowOfHelp = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2;
-
- ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
- if (Statement == NULL) {
- //
- // Print Key for Form without showable statement.
- //
- PrintHotKeyHelpString (FormData);
- PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
- return;
- }
-
- HexDisplay = FALSE;
- NumericOp = NULL;
- DateOp = NULL;
- TimeOp = NULL;
- if (Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) {
- NumericOp = (EFI_IFR_NUMERIC *) Statement->OpCode;
- HexDisplay = (NumericOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX;
- } else if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {
- DateOp = (EFI_IFR_DATE *) Statement->OpCode;
- HexDisplay = (DateOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX;
- } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- TimeOp = (EFI_IFR_TIME *) Statement->OpCode;
- HexDisplay = (TimeOp->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX;
- }
- switch (Statement->OpCode->OpCode) {
- case EFI_IFR_ORDERED_LIST_OP:
- case EFI_IFR_ONE_OF_OP:
- case EFI_IFR_NUMERIC_OP:
- case EFI_IFR_TIME_OP:
- case EFI_IFR_DATE_OP:
- if (!Selected) {
- PrintHotKeyHelpString (FormData);
-
- if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {
- PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
- }
-
- if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP) ||
- (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) {
- PrintAt (
- 0,
- StartColumnOfHelp,
- BottomRowOfHelp,
- L"%c%c%c%c%s",
- ARROW_UP,
- ARROW_DOWN,
- ARROW_RIGHT,
- ARROW_LEFT,
- gMoveHighlight
- );
- PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
- PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);
- } else {
- PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
- if (Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP && NumericOp != NULL && LibGetFieldFromNum(Statement->OpCode) != 0) {
- PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);
- }
- PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
- }
- } else {
- PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString);
-
- //
- // If it is a selected numeric with manual input, display different message
- //
- if ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) ||
- (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) ||
- (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)) {
- PrintStringAt (
- SecCol,
- TopRowOfHelp,
- HexDisplay ? gHexNumericInput : gDecNumericInput
- );
- } else if (Statement->OpCode->OpCode != EFI_IFR_ORDERED_LIST_OP) {
- PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
- }
-
- if (Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) {
- PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString);
- PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);
- }
-
- PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);
- }
- break;
-
- case EFI_IFR_CHECKBOX_OP:
- PrintHotKeyHelpString (FormData);
-
- if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {
- PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
- }
-
- PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
- PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox);
- break;
-
- case EFI_IFR_REF_OP:
- case EFI_IFR_PASSWORD_OP:
- case EFI_IFR_STRING_OP:
- case EFI_IFR_TEXT_OP:
- case EFI_IFR_ACTION_OP:
- case EFI_IFR_RESET_BUTTON_OP:
- case EFI_IFR_SUBTITLE_OP:
- if (!Selected) {
- PrintHotKeyHelpString (FormData);
-
- if (gClassOfVfr == FORMSET_CLASS_PLATFORM_SETUP) {
- PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
- }
-
- PrintAt (0, StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
- if (Statement->OpCode->OpCode != EFI_IFR_TEXT_OP && Statement->OpCode->OpCode != EFI_IFR_SUBTITLE_OP) {
- PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
- }
- } else {
- if (Statement->OpCode->OpCode != EFI_IFR_REF_OP) {
- PrintStringAt (
- (gScreenDimensions.RightColumn - LibGetStringWidth (gEnterCommitString) / 2) / 2,
- BottomRowOfHelp,
- gEnterCommitString
- );
- PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);
- }
- }
- break;
-
- default:
- break;
- }
-}
-
-/**
- Update status bar.
-
- This function updates the status bar on the bottom of menu screen. It just shows StatusBar.
- Original logic in this function should be splitted out.
-
- @param[in] MessageType The type of message to be shown. InputError or Configuration Changed.
- @param[in] State Show or Clear Message.
-**/
-VOID
-EFIAPI
-UpdateStatusBar (
- IN UINTN MessageType,
- IN BOOLEAN State
- )
-{
- UINTN Index;
- CHAR16 OptionWidth;
-
- OptionWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);
-
- switch (MessageType) {
- case INPUT_ERROR:
- if (State) {
- gST->ConOut->SetAttribute (gST->ConOut, ERROR_TEXT);
- PrintStringAt (
- gScreenDimensions.LeftColumn + OptionWidth,
- gScreenDimensions.BottomRow - 1,
- gInputErrorMessage
- );
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_BACKGROUND);
- for (Index = 0; Index < (LibGetStringWidth (gInputErrorMessage) - 2) / 2; Index++) {
- PrintStringAt (gScreenDimensions.LeftColumn + OptionWidth + Index, gScreenDimensions.BottomRow - 1, L" ");
- }
- }
- break;
-
- case NV_UPDATE_REQUIRED:
- //
- // Global setting support. Show configuration change on every form.
- //
- if (State) {
- gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT);
- PrintStringAt (
- gScreenDimensions.LeftColumn + OptionWidth * 2,
- gScreenDimensions.BottomRow - 1,
- gNvUpdateMessage
- );
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_BACKGROUND);
- for (Index = 0; Index < (LibGetStringWidth (gNvUpdateMessage) - 2) / 2; Index++) {
- PrintStringAt (
- (gScreenDimensions.LeftColumn + OptionWidth * 2 + Index),
- gScreenDimensions.BottomRow - 1,
- L" "
- );
- }
- }
- break;
-
- default:
- break;
- }
-}
-
-/**
- Create popup window. It will replace CreateDialog().
-
- This function draws OEM/Vendor specific pop up windows.
-
- @param[out] Key User Input Key
- @param ... String to be shown in Popup. The variable argument list is terminated by a NULL.
-
-**/
-VOID
-EFIAPI
-CreateDialog (
- OUT EFI_INPUT_KEY *Key, OPTIONAL
- ...
- )
-{
- VA_LIST Marker;
- EFI_INPUT_KEY KeyValue;
- EFI_STATUS Status;
- UINTN LargestString;
- UINTN LineNum;
- UINTN Index;
- UINTN Count;
- CHAR16 Character;
- UINTN Start;
- UINTN End;
- UINTN Top;
- UINTN Bottom;
- CHAR16 *String;
- UINTN DimensionsWidth;
- UINTN DimensionsHeight;
- UINTN CurrentAttribute;
-
- //
- // If screen dimension info is not ready, get it from console.
- //
- if (gScreenDimensions.RightColumn == 0 || gScreenDimensions.BottomRow == 0) {
- ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
- gST->ConOut->QueryMode (
- gST->ConOut,
- gST->ConOut->Mode->Mode,
- &gScreenDimensions.RightColumn,
- &gScreenDimensions.BottomRow
- );
- }
-
- DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
- DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;
-
- LargestString = 0;
- LineNum = 0;
- VA_START (Marker, Key);
- while ((String = VA_ARG (Marker, CHAR16 *)) != NULL) {
- LineNum ++;
-
- if ((LibGetStringWidth (String) / 2) > LargestString) {
- LargestString = (LibGetStringWidth (String) / 2);
- }
- }
- VA_END (Marker);
-
- if ((LargestString + 2) > DimensionsWidth) {
- LargestString = DimensionsWidth - 2;
- }
-
- CurrentAttribute = gST->ConOut->Mode->Attribute;
- gST->ConOut->EnableCursor (gST->ConOut, FALSE);
- gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
-
- //
- // Subtract the PopUp width from total Columns, allow for one space extra on
- // each end plus a border.
- //
- Start = (DimensionsWidth - LargestString - 2) / 2 + gScreenDimensions.LeftColumn + 1;
- End = Start + LargestString + 1;
-
- Top = ((DimensionsHeight - LineNum - 2) / 2) + gScreenDimensions.TopRow - 1;
- Bottom = Top + LineNum + 2;
-
- Character = BOXDRAW_DOWN_RIGHT;
- PrintCharAt (Start, Top, Character);
- Character = BOXDRAW_HORIZONTAL;
- for (Index = Start; Index + 2 < End; Index++) {
- PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
- }
-
- Character = BOXDRAW_DOWN_LEFT;
- PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
- Character = BOXDRAW_VERTICAL;
-
- Count = 0;
- VA_START (Marker, Key);
- for (Index = Top; Index + 2 < Bottom; Index++, Count++) {
- String = VA_ARG (Marker, CHAR16*);
-
- if (String[0] == CHAR_NULL) {
- //
- // Passing in a NULL results in a blank space
- //
- ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());
- } else if (String[0] == L' ') {
- //
- // Passing in a space results in the assumption that this is where typing will occur
- //
- ClearLines (Start + 1, End - 1, Index + 1, Index + 1, POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND);
- PrintStringAt (
- ((DimensionsWidth - LibGetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1,
- Index + 1,
- String + 1
- );
- } else {
- //
- // This will clear the background of the line - we never know who might have been
- // here before us. This differs from the next clear in that it used the non-reverse
- // video for normal printing.
- //
- ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());
- PrintStringAt (
- ((DimensionsWidth - LibGetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1,
- Index + 1,
- String
- );
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
- PrintCharAt (Start, Index + 1, Character);
- PrintCharAt (End - 1, Index + 1, Character);
- }
- VA_END (Marker);
-
- Character = BOXDRAW_UP_RIGHT;
- PrintCharAt (Start, Bottom - 1, Character);
- Character = BOXDRAW_HORIZONTAL;
- for (Index = Start; Index + 2 < End; Index++) {
- PrintCharAt ((UINTN)-1, (UINTN) -1, Character);
- }
-
- Character = BOXDRAW_UP_LEFT;
- PrintCharAt ((UINTN)-1, (UINTN) -1, Character);
-
- if (Key != NULL) {
- Status = WaitForKeyStroke (&KeyValue);
- ASSERT_EFI_ERROR (Status);
- CopyMem (Key, &KeyValue, sizeof (EFI_INPUT_KEY));
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
-}
-
-/**
- Confirm how to handle the changed data.
-
- @return Action BROWSER_ACTION_SUBMIT, BROWSER_ACTION_DISCARD or other values.
-**/
-UINTN
-EFIAPI
-ConfirmDataChange (
- VOID
- )
-{
- CHAR16 YesResponse;
- CHAR16 NoResponse;
- EFI_INPUT_KEY Key;
-
- gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
-
- YesResponse = gYesResponse[0];
- NoResponse = gNoResponse[0];
-
- //
- // If NV flag is up, prompt user
- //
- do {
- CreateDialog (&Key, gLibEmptyString, gSaveChanges, gAreYouSure, gLibEmptyString, NULL);
- } while
- (
- (Key.ScanCode != SCAN_ESC) &&
- ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&
- ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))
- );
-
- if (Key.ScanCode == SCAN_ESC) {
- return BROWSER_ACTION_NONE;
- } else if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {
- return BROWSER_ACTION_SUBMIT;
- } else {
- return BROWSER_ACTION_DISCARD;
- }
-}
-
-/**
- OEM specifies whether Setup exits Page by ESC key.
-
- This function customized the behavior that whether Setup exits Page so that
- system able to boot when configuration is not changed.
-
- @retval TRUE Exits FrontPage
- @retval FALSE Don't exit FrontPage.
-**/
-BOOLEAN
-EFIAPI
-FormExitPolicy (
- VOID
- )
-{
- return gClassOfVfr == FORMSET_CLASS_FRONT_PAGE ? FALSE : TRUE;
-}
-
-/**
- Set Timeout value for a ceratain Form to get user response.
-
- This function allows to set timeout value on a ceratain form if necessary.
- If timeout is not zero, the form will exit if user has no response in timeout.
-
- @param[in] FormData Form Data to be shown in Page
-
- @return 0 No timeout for this form.
- @return > 0 Timeout value in 100 ns units.
-**/
-UINT64
-EFIAPI
-FormExitTimeout (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- )
-{
- return 0;
-}
-//
-// Print Functions
-//
-/**
- Prints a unicode string to the default console, at
- the supplied cursor position, using L"%s" format.
-
- @param Column The cursor position to print the string at. When it is -1, use current Position.
- @param Row The cursor position to print the string at. When it is -1, use current Position.
- @param String String pointer.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-EFIAPI
-PrintStringAt (
- IN UINTN Column,
- IN UINTN Row,
- IN CHAR16 *String
- )
-{
- return PrintAt (0, Column, Row, L"%s", String);
-}
-
-/**
- Prints a unicode string to the default console, at
- the supplied cursor position, using L"%s" format.
-
- @param Column The cursor position to print the string at. When it is -1, use current Position.
- @param Row The cursor position to print the string at. When it is -1, use current Position.
- @param String String pointer.
- @param Width Width for String.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-EFIAPI
-PrintStringAtWithWidth (
- IN UINTN Column,
- IN UINTN Row,
- IN CHAR16 *String,
- IN UINTN Width
- )
-{
- return PrintAt (Width, Column, Row, L"%s", String);
-}
-
-/**
- Prints a chracter to the default console, at
- the supplied cursor position, using L"%c" format.
-
- @param Column The cursor position to print the string at. When it is -1, use current Position.
- @param Row The cursor position to print the string at. When it is -1, use current Position.
- @param Character Character to print.
-
- @return Length of string printed to the console.
-
-**/
-UINTN
-EFIAPI
-PrintCharAt (
- IN UINTN Column,
- IN UINTN Row,
- CHAR16 Character
- )
-{
- return PrintAt (0, Column, Row, L"%c", Character);
-}
-
-/**
- Clear retangle with specified text attribute.
-
- @param LeftColumn Left column of retangle.
- @param RightColumn Right column of retangle.
- @param TopRow Start row of retangle.
- @param BottomRow End row of retangle.
- @param TextAttribute The character foreground and background.
-
-**/
-VOID
-EFIAPI
-ClearLines (
- IN UINTN LeftColumn,
- IN UINTN RightColumn,
- IN UINTN TopRow,
- IN UINTN BottomRow,
- IN UINTN TextAttribute
- )
-{
- CHAR16 *Buffer;
- UINTN Row;
-
- //
- // For now, allocate an arbitrarily long buffer
- //
- Buffer = AllocateZeroPool (0x10000);
- ASSERT (Buffer != NULL);
-
- //
- // Set foreground and background as defined
- //
- gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);
-
- //
- // Much faster to buffer the long string instead of print it a character at a time
- //
- LibSetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');
-
- //
- // Clear the desired area with the appropriate foreground/background
- //
- for (Row = TopRow; Row <= BottomRow; Row++) {
- PrintStringAt (LeftColumn, Row, Buffer);
- }
-
- gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);
-
- FreePool (Buffer);
-}
-
-//
-// Color Setting Functions
-//
-
-/**
- Get OEM/Vendor specific popup attribute colors.
-
- @retval Byte code color setting for popup color.
-**/
-UINT8
-EFIAPI
-GetPopupColor (
- VOID
- )
-{
- return POPUP_TEXT | POPUP_BACKGROUND;
-}
-
-/**
- Get OEM/Vendor specific popup attribute colors.
-
- @retval Byte code color setting for popup inverse color.
-**/
-UINT8
-EFIAPI
-GetPopupInverseColor (
- VOID
- )
-{
- return POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND;
-}
-
-/**
- Get OEM/Vendor specific PickList color attribute.
-
- @retval Byte code color setting for pick list color.
-**/
-UINT8
-EFIAPI
-GetPickListColor (
- VOID
- )
-{
- return PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND;
-}
-
-/**
- Get OEM/Vendor specific arrow color attribute.
-
- @retval Byte code color setting for arrow color.
-**/
-UINT8
-EFIAPI
-GetArrowColor (
- VOID
- )
-{
- return ARROW_TEXT | ARROW_BACKGROUND;
-}
-
-/**
- Get OEM/Vendor specific info text color attribute.
-
- @retval Byte code color setting for info text color.
-**/
-UINT8
-EFIAPI
-GetInfoTextColor (
- VOID
- )
-{
- return INFO_TEXT | FIELD_BACKGROUND;
-}
-
-/**
- Get OEM/Vendor specific help text color attribute.
-
- @retval Byte code color setting for help text color.
-**/
-UINT8
-EFIAPI
-GetHelpTextColor (
- VOID
- )
-{
- return HELP_TEXT | FIELD_BACKGROUND;
-}
-
-/**
- Get OEM/Vendor specific grayed out text color attribute.
-
- @retval Byte code color setting for grayed out text color.
-**/
-UINT8
-EFIAPI
-GetGrayedTextColor (
- VOID
- )
-{
- return FIELD_TEXT_GRAYED | FIELD_BACKGROUND;
-}
-
-/**
- Get OEM/Vendor specific highlighted text color attribute.
-
- @retval Byte code color setting for highlight text color.
-**/
-UINT8
-EFIAPI
-GetHighlightTextColor (
- VOID
- )
-{
- return PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor);
-}
-
-/**
- Get OEM/Vendor specific field text color attribute.
-
- @retval Byte code color setting for field text color.
-**/
-UINT8
-EFIAPI
-GetFieldTextColor (
- VOID
- )
-{
- return PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;
-}
-
-/**
- Get OEM/Vendor specific subtitle text color attribute.
-
- @retval Byte code color setting for subtitle text color.
-**/
-UINT8
-EFIAPI
-GetSubTitleTextColor (
- VOID
- )
-{
- return PcdGet8 (PcdBrowserSubtitleTextColor) | FIELD_BACKGROUND;
-}
-
-/**
- Clear Screen to the initial state.
-**/
-VOID
-EFIAPI
-ClearDisplayPage (
- VOID
- )
-{
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- gST->ConOut->ClearScreen (gST->ConOut);
- gLibIsFirstForm = TRUE;
-}
-
-/**
- Constructor of Customized Display Library Instance.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
- @param SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
-
-**/
-EFI_STATUS
-EFIAPI
-CustomizedDisplayLibConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- mCDLStringPackHandle = HiiAddPackages (&gCustomizedDisplayLibGuid, ImageHandle, CustomizedDisplayLibStrings, NULL);
- ASSERT (mCDLStringPackHandle != NULL);
-
- InitializeLibStrings();
-
- return EFI_SUCCESS;
-}
-
-/**
- Destructor of Customized Display Library Instance.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
- @param SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The destructor completed successfully.
- @retval Other value The destructor did not complete successfully.
-
-**/
-EFI_STATUS
-EFIAPI
-CustomizedDisplayLibDestructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- HiiRemovePackages(mCDLStringPackHandle);
-
- FreeLibStrings ();
-
- return EFI_SUCCESS;
-}
-
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf deleted file mode 100644 index ade45b6a51..0000000000 --- a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf +++ /dev/null @@ -1,74 +0,0 @@ -##
-# This file contains an 'Intel Peripheral Driver' and is
-# licensed for Intel CPUs and chipsets under the terms of your
-# license agreement with Intel or your vendor. This file may
-# be modified by the user, subject to additional terms of the
-# license agreement
-##
-## @file
-#
-# General BDS defines and produce general interfaces for platform BDS driver including:
-# 1) BDS boot policy interface;
-# 2) BDS boot device connect interface;
-# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc.
-#
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
-# This software and associated documentation (if any) is furnished
-# under a license and may only be used or copied in accordance
-# with the terms of the license. Except as permitted by such
-# license, no part of this software or documentation may be
-# reproduced, stored in a retrieval system, or transmitted in any
-# form or by any means without the express written consent of
-# Intel Corporation.
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = CustomizedDisplayLib
- FILE_GUID = 80B92017-EC64-4923-938D-94FAEE85832E
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- LIBRARY_CLASS = CustomizedDisplayLib|DXE_DRIVER UEFI_APPLICATION
- CONSTRUCTOR = CustomizedDisplayLibConstructor
- DESTRUCTOR = CustomizedDisplayLibDestructor
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC
-#
-
-[Sources]
- CustomizedDisplayLib.c
- Colors.h
- CustomizedDisplayLibInternal.h
- CustomizedDisplayLibInternal.c
- CustomizedDisplayLib.uni
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- MemoryAllocationLib
- BaseLib
- UefiBootServicesTableLib
- UefiDriverEntryPoint
- UefiRuntimeServicesTableLib
- BaseMemoryLib
- DebugLib
- PrintLib
- HiiLib
- DevicePathLib
- PcdLib
-
-[Guids]
- gEfiIfrTianoGuid
-
-[Protocols]
-
-[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextHighlightColor ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldBackgroundHighlightColor ## CONSUMES
\ No newline at end of file diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.uni b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.uni Binary files differdeleted file mode 100644 index 18a5c3b563..0000000000 --- a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.uni +++ /dev/null diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c deleted file mode 100644 index b6b4055b6d..0000000000 --- a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.c +++ /dev/null @@ -1,914 +0,0 @@ -/** @file
-
- This library class defines a set of interfaces to customize Display module
-
-Copyright (c) 2013, 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 that 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 "CustomizedDisplayLibInternal.h"
-
-EFI_SCREEN_DESCRIPTOR gScreenDimensions;
-CHAR16 *mLibUnknownString;
-extern EFI_HII_HANDLE mCDLStringPackHandle;
-CHAR16 *mSpaceBuffer;
-#define SPACE_BUFFER_SIZE 1000
-
-//
-// Browser Global Strings
-//
-CHAR16 *gEnterString;
-CHAR16 *gEnterCommitString;
-CHAR16 *gEnterEscapeString;
-CHAR16 *gEscapeString;
-CHAR16 *gMoveHighlight;
-CHAR16 *gDecNumericInput;
-CHAR16 *gHexNumericInput;
-CHAR16 *gToggleCheckBox;
-CHAR16 *gLibEmptyString;
-CHAR16 *gAreYouSure;
-CHAR16 *gYesResponse;
-CHAR16 *gNoResponse;
-CHAR16 *gPlusString;
-CHAR16 *gMinusString;
-CHAR16 *gAdjustNumber;
-CHAR16 *gSaveChanges;
-CHAR16 *gNvUpdateMessage;
-CHAR16 *gInputErrorMessage;
-
-/**
-
- Print banner info for front page.
-
- @param[in] FormData Form Data to be shown in Page
-
-**/
-VOID
-PrintBannerInfo (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- )
-{
- UINT8 Line;
- UINT8 Alignment;
- CHAR16 *StrFrontPageBanner;
- UINT8 RowIdx;
- UINT8 ColumnIdx;
-
- //
- // ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);
- //
- ClearLines (
- gScreenDimensions.LeftColumn,
- gScreenDimensions.RightColumn,
- gScreenDimensions.TopRow,
- FRONT_PAGE_HEADER_HEIGHT - 1 + gScreenDimensions.TopRow,
- BANNER_TEXT | BANNER_BACKGROUND
- );
-
- //
- // for (Line = 0; Line < BANNER_HEIGHT; Line++) {
- //
- for (Line = (UINT8) gScreenDimensions.TopRow; Line < BANNER_HEIGHT + (UINT8) gScreenDimensions.TopRow; Line++) {
- //
- // for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {
- //
- for (Alignment = (UINT8) gScreenDimensions.LeftColumn;
- Alignment < BANNER_COLUMNS + (UINT8) gScreenDimensions.LeftColumn;
- Alignment++
- ) {
- RowIdx = (UINT8) (Line - (UINT8) gScreenDimensions.TopRow);
- ColumnIdx = (UINT8) (Alignment - (UINT8) gScreenDimensions.LeftColumn);
-
- ASSERT (RowIdx < BANNER_HEIGHT && ColumnIdx < BANNER_COLUMNS);
-
- if (gBannerData!= NULL && gBannerData->Banner[RowIdx][ColumnIdx] != 0x0000) {
- StrFrontPageBanner = LibGetToken (gBannerData->Banner[RowIdx][ColumnIdx], FormData->HiiHandle);
- } else {
- continue;
- }
-
- switch (Alignment - gScreenDimensions.LeftColumn) {
- case 0:
- //
- // Handle left column
- //
- PrintStringAt (gScreenDimensions.LeftColumn + BANNER_LEFT_COLUMN_INDENT, Line, StrFrontPageBanner);
- break;
-
- case 1:
- //
- // Handle center column
- //
- PrintStringAt (
- gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3,
- Line,
- StrFrontPageBanner
- );
- break;
-
- case 2:
- //
- // Handle right column
- //
- PrintStringAt (
- gScreenDimensions.LeftColumn + (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) * 2 / 3,
- Line,
- StrFrontPageBanner
- );
- break;
- }
-
- FreePool (StrFrontPageBanner);
- }
- }
-}
-
-/**
- Print framework and form title for a page.
-
- @param[in] FormData Form Data to be shown in Page
-**/
-VOID
-PrintFramework (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- )
-{
- UINTN Index;
- CHAR16 Character;
- CHAR16 *Buffer;
- UINTN Row;
- CHAR16 *TitleStr;
-
- if (gClassOfVfr != FORMSET_CLASS_PLATFORM_SETUP) {
- //
- // Only Setup page needs Framework
- //
- ClearLines (
- gScreenDimensions.LeftColumn,
- gScreenDimensions.RightColumn,
- gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight,
- gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 1,
- KEYHELP_TEXT | KEYHELP_BACKGROUND
- );
- return;
- }
-
- Buffer = AllocateZeroPool (0x10000);
- ASSERT (Buffer != NULL);
- Character = BOXDRAW_HORIZONTAL;
- for (Index = 0; Index + 2 < (gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn); Index++) {
- Buffer[Index] = Character;
- }
-
- //
- // Print Top border line
- // +------------------------------------------------------------------------------+
- // ? ?
- // +------------------------------------------------------------------------------+
- //
- gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);
- Character = BOXDRAW_DOWN_RIGHT;
-
- PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.TopRow, Character);
- PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);
-
- Character = BOXDRAW_DOWN_LEFT;
- PrintCharAt ((UINTN) -1, (UINTN) -1, Character);
-
- Character = BOXDRAW_VERTICAL;
- for (Row = gScreenDimensions.TopRow + 1; Row <= gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {
- PrintCharAt (gScreenDimensions.LeftColumn, Row, Character);
- PrintCharAt (gScreenDimensions.RightColumn - 1, Row, Character);
- }
-
- //
- // Print Form Title
- //
- ClearLines (
- gScreenDimensions.LeftColumn + 1,
- gScreenDimensions.RightColumn - 1,
- gScreenDimensions.TopRow + 1,
- gScreenDimensions.TopRow + 1,
- TITLE_TEXT | TITLE_BACKGROUND
- );
-
- TitleStr = LibGetToken (FormData->FormTitle, FormData->HiiHandle);
- ASSERT (TitleStr != NULL);
- PrintStringAt (
- (gScreenDimensions.RightColumn + gScreenDimensions.LeftColumn - LibGetStringWidth (TitleStr) / 2) / 2,
- gScreenDimensions.TopRow + 1,
- TitleStr
- );
- FreePool (TitleStr);
-
- Character = BOXDRAW_UP_RIGHT;
- PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);
- PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);
-
- Character = BOXDRAW_UP_LEFT;
- PrintCharAt ((UINTN) -1, (UINTN) -1, Character);
-
- //
- // Print Bottom border line
- // +------------------------------------------------------------------------------+
- // ? ?
- // +------------------------------------------------------------------------------+
- //
- Character = BOXDRAW_DOWN_RIGHT;
- PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight, Character);
-
- PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);
-
- Character = BOXDRAW_DOWN_LEFT;
- PrintCharAt ((UINTN) -1, (UINTN) -1, Character);
- Character = BOXDRAW_VERTICAL;
- for (Row = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;
- Row <= gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 2;
- Row++
- ) {
- PrintCharAt (gScreenDimensions.LeftColumn, Row, Character);
- PrintCharAt (gScreenDimensions.RightColumn - 1, Row, Character);
- }
-
- Character = BOXDRAW_UP_RIGHT;
- PrintCharAt (gScreenDimensions.LeftColumn, gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - 1, Character);
-
- PrintStringAt ((UINTN) -1, (UINTN) -1, Buffer);
-
- Character = BOXDRAW_UP_LEFT;
- PrintCharAt ((UINTN) -1, (UINTN) -1, Character);
-
- FreePool (Buffer);
-}
-
-/**
- Process some op code which is not recognized by browser core.
-
- @param OpCodeData The pointer to the op code buffer.
-
- @return EFI_SUCCESS Pass the statement success.
-
-**/
-VOID
-ProcessUserOpcode(
- IN EFI_IFR_OP_HEADER *OpCodeData
- )
-{
- switch (OpCodeData->OpCode) {
- case EFI_IFR_GUID_OP:
- if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)((CHAR8*) OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
- //
- // Tiano specific GUIDed opcodes
- //
- switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {
- case EFI_IFR_EXTEND_OP_LABEL:
- //
- // just ignore label
- //
- break;
-
- case EFI_IFR_EXTEND_OP_BANNER:
- //
- // Only in front page form set, we care about the banner data.
- //
- if (gClassOfVfr == FORMSET_CLASS_FRONT_PAGE) {
- //
- // Initialize Driver private data
- //
- if (gBannerData == NULL) {
- gBannerData = AllocateZeroPool (sizeof (BANNER_DATA));
- ASSERT (gBannerData != NULL);
- }
-
- CopyMem (
- &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][
- ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],
- &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,
- sizeof (EFI_STRING_ID)
- );
- }
- break;
-
- case EFI_IFR_EXTEND_OP_SUBCLASS:
- if (((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass == EFI_FRONT_PAGE_SUBCLASS) {
- gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;
- }
- break;
-
- default:
- break;
- }
- }
- break;
-
- default:
- break;
- }
-}
-
-/**
- Process some op codes which is out side of current form.
-
- @param FormData Pointer to the form data.
-
- @return EFI_SUCCESS Pass the statement success.
-
-**/
-VOID
-ProcessExternedOpcode (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- )
-{
- LIST_ENTRY *Link;
- FORM_DISPLAY_ENGINE_STATEMENT *Statement;
-
- Link = GetFirstNode (&FormData->StatementListOSF);
- while (!IsNull (&FormData->StatementListOSF, Link)) {
- Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
- Link = GetNextNode (&FormData->StatementListOSF, Link);
-
- ProcessUserOpcode(Statement->OpCode);
- }
-
- Link = GetFirstNode (&FormData->StatementListHead);
- while (!IsNull (&FormData->StatementListHead, Link)) {
- Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
- Link = GetNextNode (&FormData->StatementListHead, Link);
-
- ProcessUserOpcode(Statement->OpCode);
- }
-}
-
-/**
- Validate the input screen diemenstion info.
-
- @param FormData The input form data info.
-
- @return EFI_SUCCESS The input screen info is acceptable.
- @return EFI_INVALID_PARAMETER The input screen info is not acceptable.
-
-**/
-EFI_STATUS
-ScreenDiemensionInfoValidate (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- )
-{
- LIST_ENTRY *Link;
- UINTN Index;
-
- //
- // Calculate total number of Register HotKeys.
- //
- Index = 0;
- if (!IsListEmpty (&FormData->HotKeyListHead)){
- Link = GetFirstNode (&FormData->HotKeyListHead);
- while (!IsNull (&FormData->HotKeyListHead, Link)) {
- Link = GetNextNode (&FormData->HotKeyListHead, Link);
- Index ++;
- }
- }
-
- //
- // Show three HotKeys help information on one row.
- //
- gFooterHeight = FOOTER_HEIGHT + (Index / 3);
-
-
- ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
- gST->ConOut->QueryMode (
- gST->ConOut,
- gST->ConOut->Mode->Mode,
- &gScreenDimensions.RightColumn,
- &gScreenDimensions.BottomRow
- );
-
- //
- // Check local dimension vs. global dimension.
- //
- if (FormData->ScreenDimensions != NULL) {
- if ((gScreenDimensions.RightColumn < FormData->ScreenDimensions->RightColumn) ||
- (gScreenDimensions.BottomRow < FormData->ScreenDimensions->BottomRow)
- ) {
- return EFI_INVALID_PARAMETER;
- } else {
- //
- // Local dimension validation.
- //
- if ((FormData->ScreenDimensions->RightColumn > FormData->ScreenDimensions->LeftColumn) &&
- (FormData->ScreenDimensions->BottomRow > FormData->ScreenDimensions->TopRow) &&
- ((FormData->ScreenDimensions->RightColumn - FormData->ScreenDimensions->LeftColumn) > 2) &&
- ((FormData->ScreenDimensions->BottomRow - FormData->ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +
- FRONT_PAGE_HEADER_HEIGHT + gFooterHeight + 3)) {
- CopyMem (&gScreenDimensions, (VOID *) FormData->ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
- } else {
- return EFI_INVALID_PARAMETER;
- }
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Get the string based on the StringId and HII Package List Handle.
-
- @param Token The String's ID.
- @param HiiHandle The package list in the HII database to search for
- the specified string.
-
- @return The output string.
-
-**/
-CHAR16 *
-LibGetToken (
- IN EFI_STRING_ID Token,
- IN EFI_HII_HANDLE HiiHandle
- )
-{
- EFI_STRING String;
-
- String = HiiGetString (HiiHandle, Token, NULL);
- if (String == NULL) {
- String = AllocateCopyPool (StrSize (mLibUnknownString), mLibUnknownString);
- ASSERT (String != NULL);
- }
-
- return (CHAR16 *) String;
-}
-
-
-/**
- Count the storage space of a Unicode string.
-
- This function handles the Unicode string with NARROW_CHAR
- and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
- does not count in the resultant output. If a WIDE_CHAR is
- hit, then 2 Unicode character will consume an output storage
- space with size of CHAR16 till a NARROW_CHAR is hit.
-
- If String is NULL, then ASSERT ().
-
- @param String The input string to be counted.
-
- @return Storage space for the input string.
-
-**/
-UINTN
-LibGetStringWidth (
- IN CHAR16 *String
- )
-{
- UINTN Index;
- UINTN Count;
- UINTN IncrementValue;
-
- ASSERT (String != NULL);
- if (String == NULL) {
- return 0;
- }
-
- Index = 0;
- Count = 0;
- IncrementValue = 1;
-
- do {
- //
- // Advance to the null-terminator or to the first width directive
- //
- for (;
- (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
- Index++, Count = Count + IncrementValue
- )
- ;
-
- //
- // We hit the null-terminator, we now have a count
- //
- if (String[Index] == 0) {
- break;
- }
- //
- // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
- // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
- //
- if (String[Index] == NARROW_CHAR) {
- //
- // Skip to the next character
- //
- Index++;
- IncrementValue = 1;
- } else {
- //
- // Skip to the next character
- //
- Index++;
- IncrementValue = 2;
- }
- } while (String[Index] != 0);
-
- //
- // Increment by one to include the null-terminator in the size
- //
- Count++;
-
- return Count * sizeof (CHAR16);
-}
-
-/**
- Show all registered HotKey help strings on bottom Rows.
-
- @param FormData The curent input form data info.
-
-**/
-VOID
-PrintHotKeyHelpString (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- )
-{
- UINTN CurrentCol;
- UINTN CurrentRow;
- UINTN BottomRowOfHotKeyHelp;
- UINTN ColumnWidth;
- UINTN Index;
- EFI_SCREEN_DESCRIPTOR LocalScreen;
- LIST_ENTRY *Link;
- BROWSER_HOT_KEY *HotKey;
-
- if (IsListEmpty (&FormData->HotKeyListHead)) {
- return;
- }
-
- CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
- ColumnWidth = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
- BottomRowOfHotKeyHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3;
-
- //
- // Calculate total number of Register HotKeys.
- //
- Index = 0;
- Link = GetFirstNode (&FormData->HotKeyListHead);
- while (!IsNull (&FormData->HotKeyListHead, Link)) {
- HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
- //
- // Help string can't exceed ColumnWidth. One Row will show three Help information.
- //
- if (StrLen (HotKey->HelpString) > ColumnWidth) {
- HotKey->HelpString[ColumnWidth] = L'\0';
- }
- //
- // Calculate help information Column and Row.
- //
- if ((Index % 3) != 2) {
- CurrentCol = LocalScreen.LeftColumn + (2 - Index % 3) * ColumnWidth;
- } else {
- CurrentCol = LocalScreen.LeftColumn + 2;
- }
- CurrentRow = BottomRowOfHotKeyHelp - Index / 3;
- //
- // Print HotKey help string on bottom Row.
- //
- PrintStringAt (CurrentCol, CurrentRow, HotKey->HelpString);
-
- //
- // Get Next Hot Key.
- //
- Link = GetNextNode (&FormData->HotKeyListHead, Link);
- Index ++;
- }
-
- return;
-}
-
-/**
- Get step info from numeric opcode.
-
- @param[in] OpCode The input numeric op code.
-
- @return step info for this opcode.
-**/
-UINT64
-LibGetFieldFromNum (
- IN EFI_IFR_OP_HEADER *OpCode
- )
-{
- EFI_IFR_NUMERIC *NumericOp;
- UINT64 Step;
-
- NumericOp = (EFI_IFR_NUMERIC *) OpCode;
-
- switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {
- case EFI_IFR_NUMERIC_SIZE_1:
- Step = NumericOp->data.u8.Step;
- break;
-
- case EFI_IFR_NUMERIC_SIZE_2:
- Step = NumericOp->data.u16.Step;
- break;
-
- case EFI_IFR_NUMERIC_SIZE_4:
- Step = NumericOp->data.u32.Step;
- break;
-
- case EFI_IFR_NUMERIC_SIZE_8:
- Step = NumericOp->data.u64.Step;
- break;
-
- default:
- Step = 0;
- break;
- }
-
- return Step;
-}
-
-/**
- Initialize the HII String Token to the correct values.
-
-**/
-VOID
-InitializeLibStrings (
- VOID
- )
-{
- mLibUnknownString = L"!";
-
- gEnterString = LibGetToken (STRING_TOKEN (ENTER_STRING), mCDLStringPackHandle);
- gEnterCommitString = LibGetToken (STRING_TOKEN (ENTER_COMMIT_STRING), mCDLStringPackHandle);
- gEnterEscapeString = LibGetToken (STRING_TOKEN (ENTER_ESCAPE_STRING), mCDLStringPackHandle);
- gEscapeString = LibGetToken (STRING_TOKEN (ESCAPE_STRING), mCDLStringPackHandle);
- gMoveHighlight = LibGetToken (STRING_TOKEN (MOVE_HIGHLIGHT), mCDLStringPackHandle);
- gDecNumericInput = LibGetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), mCDLStringPackHandle);
- gHexNumericInput = LibGetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), mCDLStringPackHandle);
- gToggleCheckBox = LibGetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), mCDLStringPackHandle);
-
- gAreYouSure = LibGetToken (STRING_TOKEN (ARE_YOU_SURE), mCDLStringPackHandle);
- gYesResponse = LibGetToken (STRING_TOKEN (ARE_YOU_SURE_YES), mCDLStringPackHandle);
- gNoResponse = LibGetToken (STRING_TOKEN (ARE_YOU_SURE_NO), mCDLStringPackHandle);
- gPlusString = LibGetToken (STRING_TOKEN (PLUS_STRING), mCDLStringPackHandle);
- gMinusString = LibGetToken (STRING_TOKEN (MINUS_STRING), mCDLStringPackHandle);
- gAdjustNumber = LibGetToken (STRING_TOKEN (ADJUST_NUMBER), mCDLStringPackHandle);
- gSaveChanges = LibGetToken (STRING_TOKEN (SAVE_CHANGES), mCDLStringPackHandle);
-
- gLibEmptyString = LibGetToken (STRING_TOKEN (EMPTY_STRING), mCDLStringPackHandle);
-
- gNvUpdateMessage = LibGetToken (STRING_TOKEN (NV_UPDATE_MESSAGE), mCDLStringPackHandle);
- gInputErrorMessage = LibGetToken (STRING_TOKEN (INPUT_ERROR_MESSAGE), mCDLStringPackHandle);
-
- //
- // SpaceBuffer;
- //
- mSpaceBuffer = AllocatePool ((SPACE_BUFFER_SIZE + 1) * sizeof (CHAR16));
- ASSERT (mSpaceBuffer != NULL);
- LibSetUnicodeMem (mSpaceBuffer, SPACE_BUFFER_SIZE, L' ');
- mSpaceBuffer[SPACE_BUFFER_SIZE] = L'\0';
-}
-
-
-/**
- Free the HII String.
-
-**/
-VOID
-FreeLibStrings (
- VOID
- )
-{
- FreePool (gEnterString);
- FreePool (gEnterCommitString);
- FreePool (gEnterEscapeString);
- FreePool (gEscapeString);
- FreePool (gMoveHighlight);
- FreePool (gDecNumericInput);
- FreePool (gHexNumericInput);
- FreePool (gToggleCheckBox);
-
- FreePool (gAreYouSure);
- FreePool (gYesResponse);
- FreePool (gNoResponse);
- FreePool (gPlusString);
- FreePool (gMinusString);
- FreePool (gAdjustNumber);
- FreePool (gSaveChanges);
-
- FreePool (gLibEmptyString);
-
- FreePool (gNvUpdateMessage);
- FreePool (gInputErrorMessage);
-
- FreePool (mSpaceBuffer);
-}
-
-/**
- Wait for a key to be pressed by user.
-
- @param Key The key which is pressed by user.
-
- @retval EFI_SUCCESS The function always completed successfully.
-
-**/
-EFI_STATUS
-WaitForKeyStroke (
- OUT EFI_INPUT_KEY *Key
- )
-{
- EFI_STATUS Status;
- UINTN Index;
-
- while (TRUE) {
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);
- if (!EFI_ERROR (Status)) {
- break;
- }
-
- if (Status != EFI_NOT_READY) {
- continue;
- }
-
- gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);
- }
- return Status;
-}
-
-
-/**
- Set Buffer to Value for Size bytes.
-
- @param Buffer Memory to set.
- @param Size Number of bytes to set
- @param Value Value of the set operation.
-
-**/
-VOID
-LibSetUnicodeMem (
- IN VOID *Buffer,
- IN UINTN Size,
- IN CHAR16 Value
- )
-{
- CHAR16 *Ptr;
-
- Ptr = Buffer;
- while ((Size--) != 0) {
- *(Ptr++) = Value;
- }
-}
-
-/**
- The internal function prints to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
- protocol instance.
-
- @param Width Width of string to be print.
- @param Column The position of the output string.
- @param Row The position of the output string.
- @param Out The EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL instance.
- @param Fmt The format string.
- @param Args The additional argument for the variables in the format string.
-
- @return Number of Unicode character printed.
-
-**/
-UINTN
-PrintInternal (
- IN UINTN Width,
- IN UINTN Column,
- IN UINTN Row,
- IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Out,
- IN CHAR16 *Fmt,
- IN VA_LIST Args
- )
-{
- CHAR16 *Buffer;
- CHAR16 *BackupBuffer;
- UINTN Index;
- UINTN PreviousIndex;
- UINTN Count;
- UINTN PrintWidth;
- UINTN CharWidth;
-
- //
- // For now, allocate an arbitrarily long buffer
- //
- Buffer = AllocateZeroPool (0x10000);
- BackupBuffer = AllocateZeroPool (0x10000);
- ASSERT (Buffer);
- ASSERT (BackupBuffer);
-
- if (Column != (UINTN) -1) {
- Out->SetCursorPosition (Out, Column, Row);
- }
-
- UnicodeVSPrint (Buffer, 0x10000, Fmt, Args);
-
- Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;
-
- Out->SetAttribute (Out, Out->Mode->Attribute);
-
- Index = 0;
- PreviousIndex = 0;
- Count = 0;
- PrintWidth = 0;
- CharWidth = 1;
-
- do {
- for (; (Buffer[Index] != NARROW_CHAR) && (Buffer[Index] != WIDE_CHAR) && (Buffer[Index] != 0); Index++) {
- BackupBuffer[Index] = Buffer[Index];
- }
-
- if (Buffer[Index] == 0) {
- break;
- }
- //
- // Null-terminate the temporary string
- //
- BackupBuffer[Index] = 0;
-
- //
- // Print this out, we are about to switch widths
- //
- Out->OutputString (Out, &BackupBuffer[PreviousIndex]);
- Count += StrLen (&BackupBuffer[PreviousIndex]);
- PrintWidth += Count * CharWidth;
-
- //
- // Preserve the current index + 1, since this is where we will start printing from next
- //
- PreviousIndex = Index + 1;
-
- //
- // We are at a narrow or wide character directive. Set attributes and strip it and print it
- //
- if (Buffer[Index] == NARROW_CHAR) {
- //
- // Preserve bits 0 - 6 and zero out the rest
- //
- Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;
- Out->SetAttribute (Out, Out->Mode->Attribute);
- CharWidth = 1;
- } else {
- //
- // Must be wide, set bit 7 ON
- //
- Out->Mode->Attribute = Out->Mode->Attribute | EFI_WIDE_ATTRIBUTE;
- Out->SetAttribute (Out, Out->Mode->Attribute);
- CharWidth = 2;
- }
-
- Index++;
-
- } while (Buffer[Index] != 0);
-
- //
- // We hit the end of the string - print it
- //
- Out->OutputString (Out, &BackupBuffer[PreviousIndex]);
- Count += StrLen (&BackupBuffer[PreviousIndex]);
- PrintWidth += Count * CharWidth;
- if (PrintWidth < Width) {
- Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;
- Out->SetAttribute (Out, Out->Mode->Attribute);
- Out->OutputString (Out, &mSpaceBuffer[SPACE_BUFFER_SIZE - Width + PrintWidth]);
- }
-
- FreePool (Buffer);
- FreePool (BackupBuffer);
- return Count;
-}
-
-/**
- Prints a formatted unicode string to the default console, at
- the supplied cursor position.
-
- @param Width Width of String to be printed.
- @param Column The cursor position to print the string at.
- @param Row The cursor position to print the string at.
- @param Fmt Format string.
- @param ... Variable argument list for format string.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-EFIAPI
-PrintAt (
- IN UINTN Width,
- IN UINTN Column,
- IN UINTN Row,
- IN CHAR16 *Fmt,
- ...
- )
-{
- VA_LIST Args;
- UINTN LengthOfPrinted;
-
- VA_START (Args, Fmt);
- LengthOfPrinted = PrintInternal (Width, Column, Row, gST->ConOut, Fmt, Args);
- VA_END (Args);
- return LengthOfPrinted;
-}
-
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.h b/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.h deleted file mode 100644 index ccbd45f425..0000000000 --- a/MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLibInternal.h +++ /dev/null @@ -1,295 +0,0 @@ -/** @file
-
- This library class defines a set of interfaces to customize Display module
-
-Copyright (c) 2013, 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 that 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.
-
-**/
-
-#ifndef __CUSTOMIZED_DISPLAY_LIB_INTERNAL_H__
-#define __CUSTOMIZED_DISPLAY_LIB_INTERNAL_H__
-
-
-
-#include <PiDxe.h>
-
-#include <Protocol/SimpleTextOut.h>
-#include <Protocol/SimpleTextIn.h>
-#include <Protocol/FormBrowser2.h>
-#include <Protocol/FormBrowserEx2.h>
-#include <Protocol/DisplayProtocol.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/UnicodeCollation.h>
-#include <Protocol/HiiConfigAccess.h>
-#include <Protocol/HiiConfigRouting.h>
-#include <Protocol/HiiDatabase.h>
-#include <Protocol/HiiString.h>
-#include <Protocol/UserManager.h>
-#include <Protocol/DevicePathFromText.h>
-
-#include <Guid/MdeModuleHii.h>
-#include <Guid/HiiPlatformSetupFormset.h>
-#include <Guid/HiiFormMapMethodGuid.h>
-
-#include <Library/PrintLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/BaseLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/HiiLib.h>
-#include <Library/PcdLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/CustomizedDisplayLib.h>
-
-#include "Colors.h"
-
-
-
-#define FORMSET_CLASS_PLATFORM_SETUP 0x0001
-#define FORMSET_CLASS_FRONT_PAGE 0x0002
-
-
-#define FRONT_PAGE_HEADER_HEIGHT 6
-#define NONE_FRONT_PAGE_HEADER_HEIGHT 3
-#define FOOTER_HEIGHT 4
-#define STATUS_BAR_HEIGHT 1
-
-//
-// Screen definitions
-//
-#define BANNER_HEIGHT 6
-#define BANNER_COLUMNS 3
-#define BANNER_LEFT_COLUMN_INDENT 1
-
-//
-// Character definitions
-//
-#define UPPER_LOWER_CASE_OFFSET 0x20
-
-//
-// This is the Input Error Message
-//
-#define INPUT_ERROR 1
-
-//
-// This is the NV RAM update required Message
-//
-#define NV_UPDATE_REQUIRED 2
-
-typedef struct {
- EFI_STRING_ID Banner[BANNER_HEIGHT][BANNER_COLUMNS];
-} BANNER_DATA;
-
-extern UINT16 gClassOfVfr; // Formset class information
-extern BANNER_DATA *gBannerData;
-extern EFI_SCREEN_DESCRIPTOR gScreenDimensions;
-extern UINTN gFooterHeight;
-
-//
-// Browser Global Strings
-//
-extern CHAR16 *gEnterString;
-extern CHAR16 *gEnterCommitString;
-extern CHAR16 *gEnterEscapeString;
-extern CHAR16 *gEscapeString;
-extern CHAR16 *gMoveHighlight;
-extern CHAR16 *gDecNumericInput;
-extern CHAR16 *gHexNumericInput;
-extern CHAR16 *gToggleCheckBox;
-extern CHAR16 *gLibEmptyString;
-extern CHAR16 *gAreYouSure;
-extern CHAR16 *gYesResponse;
-extern CHAR16 *gNoResponse;
-extern CHAR16 *gPlusString;
-extern CHAR16 *gMinusString;
-extern CHAR16 *gAdjustNumber;
-extern CHAR16 *gSaveChanges;
-extern CHAR16 *gNvUpdateMessage;
-extern CHAR16 *gInputErrorMessage;
-/**
-
- Print banner info for front page.
-
- @param[in] FormData Form Data to be shown in Page
-
-**/
-VOID
-PrintBannerInfo (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- );
-
-/**
- Print framework and form title for a page.
-
- @param[in] FormData Form Data to be shown in Page
-**/
-VOID
-PrintFramework (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- );
-
-/**
- Validate the input screen diemenstion info.
-
- @param FormData The input form data info.
-
- @return EFI_SUCCESS The input screen info is acceptable.
- @return EFI_INVALID_PARAMETER The input screen info is not acceptable.
-
-**/
-EFI_STATUS
-ScreenDiemensionInfoValidate (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- );
-
-/**
- Get the string based on the StringId and HII Package List Handle.
-
- @param Token The String's ID.
- @param HiiHandle The package list in the HII database to search for
- the specified string.
-
- @return The output string.
-
-**/
-CHAR16 *
-LibGetToken (
- IN EFI_STRING_ID Token,
- IN EFI_HII_HANDLE HiiHandle
- );
-
-/**
- Count the storage space of a Unicode string.
-
- This function handles the Unicode string with NARROW_CHAR
- and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
- does not count in the resultant output. If a WIDE_CHAR is
- hit, then 2 Unicode character will consume an output storage
- space with size of CHAR16 till a NARROW_CHAR is hit.
-
- If String is NULL, then ASSERT ().
-
- @param String The input string to be counted.
-
- @return Storage space for the input string.
-
-**/
-UINTN
-LibGetStringWidth (
- IN CHAR16 *String
- );
-
-/**
- Show all registered HotKey help strings on bottom Rows.
-
- @param FormData The curent input form data info.
-
-**/
-VOID
-PrintHotKeyHelpString (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- );
-
-/**
- Get step info from numeric opcode.
-
- @param[in] OpCode The input numeric op code.
-
- @return step info for this opcode.
-**/
-UINT64
-LibGetFieldFromNum (
- IN EFI_IFR_OP_HEADER *OpCode
- );
-
-/**
- Initialize the HII String Token to the correct values.
-
-**/
-VOID
-InitializeLibStrings (
- VOID
- );
-
-/**
- Free the HII String.
-
-**/
-VOID
-FreeLibStrings (
- VOID
- );
-
-/**
- Wait for a key to be pressed by user.
-
- @param Key The key which is pressed by user.
-
- @retval EFI_SUCCESS The function always completed successfully.
-
-**/
-EFI_STATUS
-WaitForKeyStroke (
- OUT EFI_INPUT_KEY *Key
- );
-
-/**
- Set Buffer to Value for Size bytes.
-
- @param Buffer Memory to set.
- @param Size Number of bytes to set
- @param Value Value of the set operation.
-
-**/
-VOID
-LibSetUnicodeMem (
- IN VOID *Buffer,
- IN UINTN Size,
- IN CHAR16 Value
- );
-
-/**
- Prints a formatted unicode string to the default console, at
- the supplied cursor position.
-
- @param Width Width of String to be printed.
- @param Column The cursor position to print the string at.
- @param Row The cursor position to print the string at.
- @param Fmt Format string.
- @param ... Variable argument list for format string.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-EFIAPI
-PrintAt (
- IN UINTN Width,
- IN UINTN Column,
- IN UINTN Row,
- IN CHAR16 *Fmt,
- ...
- );
-
-/**
- Process some op codes which is out side of current form.
-
- @param FormData Pointer to the form data.
-
-**/
-VOID
-ProcessExternedOpcode (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- );
-
-#endif
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 4ae24eb80e..3105519297 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -98,10 +98,6 @@ #
CpuExceptionHandlerLib|Include/Library/CpuExceptionHandlerLib.h
- ## @libraryclass Provides platform specific display interface.
- #
- CustomizedDisplayLib|Include/Library/CustomizedDisplayLib.h
-
[Guids]
## MdeModule package token space guid
# Include/Guid/MdeModulePkgTokenSpace.h
@@ -365,12 +361,6 @@ ## Include/Protocol/BootLogo.h
gEfiBootLogoProtocolGuid = { 0xcdea2bd3, 0xfc25, 0x4c1c, { 0xb9, 0x7c, 0xb3, 0x11, 0x86, 0x6, 0x49, 0x90 } }
- ## Include/Protocol/DisplayProtocol.h
- gEdkiiFormDisplayEngineProtocolGuid = { 0x9bbe29e9, 0xfda1, 0x41ec, { 0xad, 0x52, 0x45, 0x22, 0x13, 0x74, 0x2d, 0x2e } }
-
- ## Include/Protocol/FormBrowserEx2.h
- gEdkiiFormBrowserEx2ProtocolGuid = { 0xa770c357, 0xb693, 0x4e6d, { 0xa6, 0xcf, 0xd2, 0x1c, 0x72, 0x8e, 0x55, 0xb } }
-
[PcdsFeatureFlag]
## Indicate whether platform can support update capsule across a system reset
gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE|BOOLEAN|0x0001001d
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 7895834c24..781fbbf3b4 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -76,7 +76,6 @@ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
PalLib|MdePkg/Library/BasePalLibNull/BasePalLibNull.inf
- CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
#
# Misc
#
@@ -294,7 +293,6 @@ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
- MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
MdeModulePkg/Application/VariableInfo/VariableInfo.inf
MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf b/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf deleted file mode 100644 index 323fcadb85..0000000000 --- a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf +++ /dev/null @@ -1,66 +0,0 @@ -## @file
-# The DXE driver produces FORM BROWSER protocols defined in UEFI HII 2.1 specificatin.
-#
-# Copyright (c) 2007 - 2013, 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.
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = DisplayEngine
- FILE_GUID = E660EA85-058E-4b55-A54B-F02F83A24707
- MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = InitializeDisplayEngine
- UNLOAD_IMAGE = UnloadDisplayEngine
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64 IPF EBC
-#
-
-[Sources]
- FormDisplayStr.uni
- FormDisplay.c
- FormDisplay.h
- ProcessOptions.c
- InputHandler.c
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- UefiDriverEntryPoint
- UefiBootServicesTableLib
- DebugLib
- BaseMemoryLib
- BaseLib
- PrintLib
- HiiLib
- MemoryAllocationLib
- CustomizedDisplayLib
-
-[Protocols]
- gEdkiiFormDisplayEngineProtocolGuid
- gEdkiiFormBrowserEx2ProtocolGuid
-
-[Guids]
- gEfiIfrTianoGuid ## CONSUMES ## GUID
-
-[Depex]
- gEfiHiiDatabaseProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid AND gEdkiiFormBrowserEx2ProtocolGuid
-
-[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowerGrayOutReadOnlyMenu ## CONSUMES
-
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c deleted file mode 100644 index a07cc75a47..0000000000 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c +++ /dev/null @@ -1,3255 +0,0 @@ -/** @file
-Entry and initialization module for the browser.
-
-Copyright (c) 2007 - 2013, 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"
-
-//
-// Search table for UiDisplayMenu()
-//
-SCAN_CODE_TO_SCREEN_OPERATION gScanCodeToOperation[] = {
- {
- SCAN_UP,
- UiUp,
- },
- {
- SCAN_DOWN,
- UiDown,
- },
- {
- SCAN_PAGE_UP,
- UiPageUp,
- },
- {
- SCAN_PAGE_DOWN,
- UiPageDown,
- },
- {
- SCAN_ESC,
- UiReset,
- },
- {
- SCAN_LEFT,
- UiLeft,
- },
- {
- SCAN_RIGHT,
- UiRight,
- }
-};
-
-UINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);
-
-SCREEN_OPERATION_T0_CONTROL_FLAG gScreenOperationToControlFlag[] = {
- {
- UiNoOperation,
- CfUiNoOperation,
- },
- {
- UiSelect,
- CfUiSelect,
- },
- {
- UiUp,
- CfUiUp,
- },
- {
- UiDown,
- CfUiDown,
- },
- {
- UiLeft,
- CfUiLeft,
- },
- {
- UiRight,
- CfUiRight,
- },
- {
- UiReset,
- CfUiReset,
- },
- {
- UiPageUp,
- CfUiPageUp,
- },
- {
- UiPageDown,
- CfUiPageDown
- },
- {
- UiHotKey,
- CfUiHotKey
- }
-};
-
-EFI_GUID gDisplayEngineGuid = {
- 0xE38C1029, 0xE38F, 0x45b9, {0x8F, 0x0D, 0xE2, 0xE6, 0x0B, 0xC9, 0xB2, 0x62}
-};
-
-FORM_ENTRY_INFO gFormEntryInfo;
-UINTN gSequence;
-EFI_SCREEN_DESCRIPTOR gStatementDimensions;
-BOOLEAN mStatementLayoutIsChanged = TRUE;
-USER_INPUT *gUserInput;
-FORM_DISPLAY_ENGINE_FORM *gFormData;
-EFI_HII_HANDLE gHiiHandle;
-UINT16 gDirection;
-LIST_ENTRY gMenuOption;
-DISPLAY_HIGHLIGHT_MENU_INFO gHighligthMenuInfo = {0};
-BOOLEAN mIsFirstForm = TRUE;
-FORM_ENTRY_INFO gOldFormEntry = {0};
-
-//
-// Browser Global Strings
-//
-CHAR16 *gFormNotFound;
-CHAR16 *gNoSubmitIf;
-CHAR16 *gBrwoserError;
-CHAR16 *gSaveFailed;
-CHAR16 *gPromptForData;
-CHAR16 *gPromptForPassword;
-CHAR16 *gPromptForNewPassword;
-CHAR16 *gConfirmPassword;
-CHAR16 *gConfirmError;
-CHAR16 *gPassowordInvalid;
-CHAR16 *gPressEnter;
-CHAR16 *gEmptyString;
-CHAR16 *gMiniString;
-CHAR16 *gOptionMismatch;
-CHAR16 *gFormSuppress;
-CHAR16 *gProtocolNotFound;
-
-CHAR16 gPromptBlockWidth;
-CHAR16 gOptionBlockWidth;
-CHAR16 gHelpBlockWidth;
-CHAR16 *mUnknownString;
-
-FORM_DISPLAY_DRIVER_PRIVATE_DATA mPrivateData = {
- FORM_DISPLAY_DRIVER_SIGNATURE,
- NULL,
- {
- FormDisplay,
- DriverClearDisplayPage,
- ConfirmDataChange
- }
-};
-
-
-/**
- Get the string based on the StringId and HII Package List Handle.
-
- @param Token The String's ID.
- @param HiiHandle The package list in the HII database to search for
- the specified string.
-
- @return The output string.
-
-**/
-CHAR16 *
-GetToken (
- IN EFI_STRING_ID Token,
- IN EFI_HII_HANDLE HiiHandle
- )
-{
- EFI_STRING String;
-
- String = HiiGetString (HiiHandle, Token, NULL);
- if (String == NULL) {
- String = AllocateCopyPool (StrSize (mUnknownString), mUnknownString);
- ASSERT (String != NULL);
- }
-
- return (CHAR16 *) String;
-}
-
-
-/**
- Initialize the HII String Token to the correct values.
-
-**/
-VOID
-InitializeDisplayStrings (
- VOID
- )
-{
- mUnknownString = GetToken (STRING_TOKEN (UNKNOWN_STRING), gHiiHandle);
- gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);
- gPromptForData = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);
- gPromptForPassword = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);
- gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);
- gConfirmPassword = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);
- gConfirmError = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);
- gPassowordInvalid = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);
- gPressEnter = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);
- gEmptyString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
- gMiniString = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);
- gOptionMismatch = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);
- gFormSuppress = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);
- gProtocolNotFound = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);
- gFormNotFound = GetToken (STRING_TOKEN (STATUS_BROWSER_FORM_NOT_FOUND), gHiiHandle);
- gNoSubmitIf = GetToken (STRING_TOKEN (STATUS_BROWSER_NO_SUBMIT_IF), gHiiHandle);
- gBrwoserError = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle);
-}
-
-/**
- Free up the resource allocated for all strings required
- by Setup Browser.
-
-**/
-VOID
-FreeDisplayStrings (
- VOID
- )
-{
- FreePool (mUnknownString);
- FreePool (gEmptyString);
- FreePool (gSaveFailed);
- FreePool (gPromptForData);
- FreePool (gPromptForPassword);
- FreePool (gPromptForNewPassword);
- FreePool (gConfirmPassword);
- FreePool (gConfirmError);
- FreePool (gPassowordInvalid);
- FreePool (gPressEnter);
- FreePool (gMiniString);
- FreePool (gOptionMismatch);
- FreePool (gFormSuppress);
- FreePool (gProtocolNotFound);
- FreePool (gBrwoserError);
- FreePool (gNoSubmitIf);
- FreePool (gFormNotFound);
-}
-
-/**
- Get prompt string id from the opcode data buffer.
-
- @param OpCode The input opcode buffer.
-
- @return The prompt string id.
-
-**/
-EFI_STRING_ID
-GetPrompt (
- IN EFI_IFR_OP_HEADER *OpCode
- )
-{
- EFI_IFR_STATEMENT_HEADER *Header;
-
- if (OpCode->Length <= sizeof (EFI_IFR_OP_HEADER)) {
- return 0;
- }
-
- Header = (EFI_IFR_STATEMENT_HEADER *) (OpCode + 1);
-
- return Header->Prompt;
-}
-
-/**
- Get the supported width for a particular op-code
-
- @param Statement The curent statement.
-
- @return Returns the number of CHAR16 characters that is support.
-
-**/
-UINT16
-GetWidth (
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement
- )
-{
- CHAR16 *String;
- UINTN Size;
- UINT16 Width;
- EFI_IFR_TEXT *TestOp;
-
- Size = 0;
-
- //
- // See if the second text parameter is really NULL
- //
- if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
- TestOp = (EFI_IFR_TEXT *) Statement->OpCode;
- if (TestOp->TextTwo != 0) {
- String = GetToken (TestOp->TextTwo, gFormData->HiiHandle);
- Size = StrLen (String);
- FreePool (String);
- }
- }
-
- if ((Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
- (Statement->OpCode->OpCode == EFI_IFR_REF_OP) ||
- (Statement->OpCode->OpCode == EFI_IFR_PASSWORD_OP) ||
- (Statement->OpCode->OpCode == EFI_IFR_ACTION_OP) ||
- (Statement->OpCode->OpCode == EFI_IFR_RESET_BUTTON_OP) ||
- //
- // Allow a wide display if text op-code and no secondary text op-code
- //
- ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0))
- ) {
- Width = (UINT16) (gPromptBlockWidth + gOptionBlockWidth);
- } else {
- Width = (UINT16) gPromptBlockWidth;
- }
-
- return (UINT16) (Width - LEFT_SKIPPED_COLUMNS);
-}
-
-/**
- Will copy LineWidth amount of a string in the OutputString buffer and return the
- number of CHAR16 characters that were copied into the OutputString buffer.
- The output string format is:
- Glyph Info + String info + '\0'.
-
- In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.
-
- @param InputString String description for this option.
- @param LineWidth Width of the desired string to extract in CHAR16
- characters
- @param GlyphWidth The glyph width of the begin of the char in the string.
- @param Index Where in InputString to start the copy process
- @param OutputString Buffer to copy the string into
-
- @return Returns the number of CHAR16 characters that were copied into the OutputString
- buffer, include extra glyph info and '\0' info.
-
-**/
-UINT16
-GetLineByWidth (
- IN CHAR16 *InputString,
- IN UINT16 LineWidth,
- IN OUT UINT16 *GlyphWidth,
- IN OUT UINTN *Index,
- OUT CHAR16 **OutputString
- )
-{
- UINT16 StrOffset;
- UINT16 GlyphOffset;
- UINT16 OriginalGlyphWidth;
- BOOLEAN ReturnFlag;
- UINT16 LastSpaceOffset;
- UINT16 LastGlyphWidth;
-
- if (InputString == NULL || Index == NULL || OutputString == NULL) {
- return 0;
- }
-
- if (LineWidth == 0 || *GlyphWidth == 0) {
- return 0;
- }
-
- //
- // Save original glyph width.
- //
- OriginalGlyphWidth = *GlyphWidth;
- LastGlyphWidth = OriginalGlyphWidth;
- ReturnFlag = FALSE;
- LastSpaceOffset = 0;
-
- //
- // NARROW_CHAR can not be printed in screen, so if a line only contain the two CHARs: 'NARROW_CHAR + CHAR_CARRIAGE_RETURN' , it is a empty line in Screen.
- // To avoid displaying this empty line in screen, just skip the two CHARs here.
- //
- if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {
- *Index = *Index + 2;
- }
-
- //
- // Fast-forward the string and see if there is a carriage-return in the string
- //
- for (StrOffset = 0, GlyphOffset = 0; GlyphOffset <= LineWidth; StrOffset++) {
- switch (InputString[*Index + StrOffset]) {
- case NARROW_CHAR:
- *GlyphWidth = 1;
- break;
-
- case WIDE_CHAR:
- *GlyphWidth = 2;
- break;
-
- case CHAR_CARRIAGE_RETURN:
- case CHAR_LINEFEED:
- case CHAR_NULL:
- ReturnFlag = TRUE;
- break;
-
- default:
- GlyphOffset = GlyphOffset + *GlyphWidth;
-
- //
- // Record the last space info in this line. Will be used in rewind.
- //
- if ((InputString[*Index + StrOffset] == CHAR_SPACE) && (GlyphOffset <= LineWidth)) {
- LastSpaceOffset = StrOffset;
- LastGlyphWidth = *GlyphWidth;
- }
- break;
- }
-
- if (ReturnFlag) {
- break;
- }
- }
-
- //
- // Rewind the string from the maximum size until we see a space to break the line
- //
- if (GlyphOffset > LineWidth) {
- //
- // Rewind the string to last space char in this line.
- //
- if (LastSpaceOffset != 0) {
- StrOffset = LastSpaceOffset;
- *GlyphWidth = LastGlyphWidth;
- } else {
- //
- // Roll back to last char in the line width.
- //
- StrOffset--;
- }
- }
-
- //
- // The CHAR_NULL has process last time, this time just return 0 to stand for the end.
- //
- if (StrOffset == 0 && (InputString[*Index + StrOffset] == CHAR_NULL)) {
- return 0;
- }
-
- //
- // Need extra glyph info and '\0' info, so +2.
- //
- *OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));
- if (*OutputString == NULL) {
- return 0;
- }
-
- //
- // Save the glyph info at the begin of the string, will used by Print function.
- //
- if (OriginalGlyphWidth == 1) {
- *(*OutputString) = NARROW_CHAR;
- } else {
- *(*OutputString) = WIDE_CHAR;
- }
-
- CopyMem ((*OutputString) + 1, &InputString[*Index], StrOffset * sizeof(CHAR16));
-
- if (InputString[*Index + StrOffset] == CHAR_SPACE) {
- //
- // Skip the space info at the begin of next line.
- //
- *Index = (UINT16) (*Index + StrOffset + 1);
- } else if (InputString[*Index + StrOffset] == CHAR_LINEFEED) {
- //
- // Skip the /n or /n/r info.
- //
- if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {
- *Index = (UINT16) (*Index + StrOffset + 2);
- } else {
- *Index = (UINT16) (*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 = (UINT16) (*Index + StrOffset + 2);
- } else {
- *Index = (UINT16) (*Index + StrOffset + 1);
- }
- } else {
- *Index = (UINT16) (*Index + StrOffset);
- }
-
- //
- // Include extra glyph info and '\0' info, so +2.
- //
- return StrOffset + 2;
-}
-
-/**
- Add one menu option by specified description and context.
-
- @param Statement Statement of this Menu Option.
- @param MenuItemCount The index for this Option in the Menu.
- @param NestIn Whether this statement is nest in another statement.
-
-**/
-VOID
-UiAddMenuOption (
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
- IN UINT16 *MenuItemCount,
- IN BOOLEAN NestIn
- )
-{
- UI_MENU_OPTION *MenuOption;
- UINTN Index;
- UINTN Count;
- CHAR16 *String;
- UINT16 NumberOfLines;
- UINT16 GlyphWidth;
- UINT16 Width;
- UINTN ArrayEntry;
- CHAR16 *OutputString;
- EFI_STRING_ID PromptId;
-
- NumberOfLines = 1;
- ArrayEntry = 0;
- GlyphWidth = 1;
- Count = 1;
- MenuOption = NULL;
-
- PromptId = GetPrompt (Statement->OpCode);
- ASSERT (PromptId != 0);
-
- String = GetToken (PromptId, gFormData->HiiHandle);
- ASSERT (String != NULL);
-
- Width = GetWidth (Statement);
- for (; GetLineByWidth (String, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&String[ArrayEntry]) != 0) {
- NumberOfLines++;
- }
- FreePool (OutputString);
- }
-
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- //
- // Add three MenuOptions for Date/Time
- // Data format : [01/02/2004] [11:22:33]
- // Line number : 0 0 1 0 0 1
- //
- NumberOfLines = 0;
- Count = 3;
- }
-
- for (Index = 0; Index < Count; Index++) {
- MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));
- ASSERT (MenuOption);
-
- MenuOption->Signature = UI_MENU_OPTION_SIGNATURE;
- MenuOption->Description = String;
- MenuOption->Handle = gFormData->HiiHandle;
- MenuOption->ThisTag = Statement;
- MenuOption->NestInStatement = NestIn;
- MenuOption->EntryNumber = *MenuItemCount;
-
- if (Index == 2) {
- //
- // Override LineNumber for the MenuOption in Date/Time sequence
- //
- MenuOption->Skip = 1;
- } else {
- MenuOption->Skip = NumberOfLines;
- }
- MenuOption->Sequence = Index;
-
- if ((Statement->Attribute & HII_DISPLAY_GRAYOUT) != 0) {
- MenuOption->GrayOut = TRUE;
- } else {
- MenuOption->GrayOut = FALSE;
- }
-
- if ((Statement->Attribute & HII_DISPLAY_LOCK) != 0 || (gFormData->Attribute & HII_DISPLAY_LOCK) != 0) {
- MenuOption->GrayOut = TRUE;
- }
-
- //
- // If the form or the question has the lock attribute, deal same as grayout.
- //
- if ((gFormData->Attribute & HII_DISPLAY_LOCK) != 0 || (Statement->Attribute & HII_DISPLAY_LOCK) != 0) {
- MenuOption->GrayOut = TRUE;
- }
-
- switch (Statement->OpCode->OpCode) {
- case EFI_IFR_ORDERED_LIST_OP:
- case EFI_IFR_ONE_OF_OP:
- case EFI_IFR_NUMERIC_OP:
- case EFI_IFR_TIME_OP:
- case EFI_IFR_DATE_OP:
- case EFI_IFR_CHECKBOX_OP:
- case EFI_IFR_PASSWORD_OP:
- case EFI_IFR_STRING_OP:
- //
- // User could change the value of these items
- //
- MenuOption->IsQuestion = TRUE;
- break;
- case EFI_IFR_TEXT_OP:
- if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {
- //
- // Initializing GrayOut option as TRUE for Text setup options
- // so that those options will be Gray in colour and un selectable.
- //
- MenuOption->GrayOut = TRUE;
- }
- break;
- default:
- MenuOption->IsQuestion = FALSE;
- break;
- }
-
- if ((Statement->Attribute & HII_DISPLAY_READONLY) != 0) {
- MenuOption->ReadOnly = TRUE;
- if (FeaturePcdGet (PcdBrowerGrayOutReadOnlyMenu)) {
- MenuOption->GrayOut = TRUE;
- }
- }
-
- InsertTailList (&gMenuOption, &MenuOption->Link);
- }
-
- (*MenuItemCount)++;
-}
-
-/**
- Create the menu list base on the form data info.
-
-**/
-VOID
-ConvertStatementToMenu (
- VOID
- )
-{
- UINT16 MenuItemCount;
- LIST_ENTRY *Link;
- LIST_ENTRY *NestLink;
- FORM_DISPLAY_ENGINE_STATEMENT *Statement;
- FORM_DISPLAY_ENGINE_STATEMENT *NestStatement;
-
- MenuItemCount = 0;
- InitializeListHead (&gMenuOption);
-
- Link = GetFirstNode (&gFormData->StatementListHead);
- while (!IsNull (&gFormData->StatementListHead, Link)) {
- Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
- Link = GetNextNode (&gFormData->StatementListHead, Link);
-
- //
- // Skip the opcode not recognized by Display core.
- //
- if (Statement->OpCode->OpCode == EFI_IFR_GUID_OP) {
- continue;
- }
-
- UiAddMenuOption (Statement, &MenuItemCount, FALSE);
-
- //
- // Check the statement nest in this host statement.
- //
- NestLink = GetFirstNode (&Statement->NestStatementList);
- while (!IsNull (&Statement->NestStatementList, NestLink)) {
- NestStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (NestLink);
- NestLink = GetNextNode (&Statement->NestStatementList, NestLink);
-
- UiAddMenuOption (NestStatement, &MenuItemCount, TRUE);
- }
- }
-}
-
-/**
- Count the storage space of a Unicode string.
-
- This function handles the Unicode string with NARROW_CHAR
- and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
- does not count in the resultant output. If a WIDE_CHAR is
- hit, then 2 Unicode character will consume an output storage
- space with size of CHAR16 till a NARROW_CHAR is hit.
-
- If String is NULL, then ASSERT ().
-
- @param String The input string to be counted.
-
- @return Storage space for the input string.
-
-**/
-UINTN
-GetStringWidth (
- IN CHAR16 *String
- )
-{
- UINTN Index;
- UINTN Count;
- UINTN IncrementValue;
-
- ASSERT (String != NULL);
- if (String == NULL) {
- return 0;
- }
-
- Index = 0;
- Count = 0;
- IncrementValue = 1;
-
- do {
- //
- // Advance to the null-terminator or to the first width directive
- //
- for (;
- (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
- Index++, Count = Count + IncrementValue
- )
- ;
-
- //
- // We hit the null-terminator, we now have a count
- //
- if (String[Index] == 0) {
- break;
- }
- //
- // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
- // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
- //
- if (String[Index] == NARROW_CHAR) {
- //
- // Skip to the next character
- //
- Index++;
- IncrementValue = 1;
- } else {
- //
- // Skip to the next character
- //
- Index++;
- IncrementValue = 2;
- }
- } while (String[Index] != 0);
-
- //
- // Increment by one to include the null-terminator in the size
- //
- Count++;
-
- return Count * sizeof (CHAR16);
-}
-
-/**
- Base on the input option string to update the skip value for a menu option.
-
- @param MenuOption The MenuOption to be checked.
- @param OptionString The input option string.
-
-**/
-VOID
-UpdateSkipInfoForMenu (
- IN UI_MENU_OPTION *MenuOption,
- IN CHAR16 *OptionString
- )
-{
- UINTN Index;
- UINT16 Width;
- UINTN Row;
- CHAR16 *OutputString;
- UINT16 GlyphWidth;
-
- Width = (UINT16) gOptionBlockWidth;
- GlyphWidth = 1;
- Row = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if (StrLen (&OptionString[Index]) != 0) {
- Row++;
- }
-
- FreePool (OutputString);
- }
-
- if ((Row > MenuOption->Skip) &&
- (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_DATE_OP) &&
- (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_TIME_OP)) {
- MenuOption->Skip = Row;
- }
-}
-
-/**
- Update display lines for a Menu Option.
-
- @param MenuOption The MenuOption to be checked.
-
-**/
-VOID
-UpdateOptionSkipLines (
- IN UI_MENU_OPTION *MenuOption
- )
-{
- CHAR16 *OptionString;
-
- OptionString = NULL;
-
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
- if (OptionString != NULL) {
- UpdateSkipInfoForMenu (MenuOption, OptionString);
-
- FreePool (OptionString);
- }
-
- if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo != 0)) {
- OptionString = GetToken (((EFI_IFR_TEXT*)MenuOption->ThisTag->OpCode)->TextTwo, gFormData->HiiHandle);
-
- if (OptionString != NULL) {
- UpdateSkipInfoForMenu (MenuOption, OptionString);
-
- FreePool (OptionString);
- }
- }
-}
-
-/**
- Check whether this Menu Option could be highlighted.
-
- This is an internal function.
-
- @param MenuOption The MenuOption to be checked.
-
- @retval TRUE This Menu Option is selectable.
- @retval FALSE This Menu Option could not be selected.
-
-**/
-BOOLEAN
-IsSelectable (
- UI_MENU_OPTION *MenuOption
- )
-{
- if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
- MenuOption->GrayOut || MenuOption->ReadOnly) {
- return FALSE;
- } else {
- return TRUE;
- }
-}
-
-/**
- Move to next selectable statement.
-
- This is an internal function.
-
- @param GoUp The navigation direction. TRUE: up, FALSE: down.
- @param CurrentPosition Current position.
- @param GapToTop Gap position to top or bottom.
-
- @return The row distance from current MenuOption to next selectable MenuOption.
-
- @retval -1 Reach the begin of the menu, still can't find the selectable menu.
- @retval Value Find the selectable menu, maybe the truly selectable, maybe the l
- last menu showing at current form.
-
-**/
-INTN
-MoveToNextStatement (
- IN BOOLEAN GoUp,
- IN OUT LIST_ENTRY **CurrentPosition,
- IN UINTN GapToTop
- )
-{
- INTN Distance;
- LIST_ENTRY *Pos;
- UI_MENU_OPTION *NextMenuOption;
- UI_MENU_OPTION *PreMenuOption;
-
- Distance = 0;
- Pos = *CurrentPosition;
- PreMenuOption = MENU_OPTION_FROM_LINK (Pos);
-
- while (TRUE) {
- NextMenuOption = MENU_OPTION_FROM_LINK (Pos);
- //
- // NextMenuOption->Row == 0 means this menu has not calculate
- // the NextMenuOption->Skip value yet, just calculate here.
- //
- if (NextMenuOption->Row == 0) {
- UpdateOptionSkipLines (NextMenuOption);
- }
-
- if (GoUp && (PreMenuOption != NextMenuOption)) {
- //
- // In this case, still can't find the selectable menu,
- // return the last one in the showing form.
- //
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
- NextMenuOption = PreMenuOption;
- break;
- }
-
- //
- // Current Position doesn't need to be caculated when go up.
- // Caculate distanct at first when go up
- //
- Distance += NextMenuOption->Skip;
- }
-
- if (IsSelectable (NextMenuOption)) {
- break;
- }
-
- //
- // Arrive at begin of the menu list.
- //
- if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {
- Distance = -1;
- break;
- }
-
- if (!GoUp) {
- //
- // In this case, still can't find the selectable menu,
- // return the last one in the showing form.
- //
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
- NextMenuOption = PreMenuOption;
- break;
- }
-
- Distance += NextMenuOption->Skip;
- }
-
- PreMenuOption = NextMenuOption;
- Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);
- }
-
- *CurrentPosition = &NextMenuOption->Link;
- return Distance;
-}
-
-
-/**
- Process option string for date/time opcode.
-
- @param MenuOption Menu option point to date/time.
- @param OptionString Option string input for process.
- @param AddOptCol Whether need to update MenuOption->OptCol.
-
-**/
-VOID
-ProcessStringForDateTime (
- UI_MENU_OPTION *MenuOption,
- CHAR16 *OptionString,
- BOOLEAN AddOptCol
- )
-{
- UINTN Index;
- UINTN Count;
- FORM_DISPLAY_ENGINE_STATEMENT *Statement;
- EFI_IFR_DATE *Date;
- EFI_IFR_TIME *Time;
-
- ASSERT (MenuOption != NULL && OptionString != NULL);
-
- Statement = MenuOption->ThisTag;
- Date = NULL;
- Time = NULL;
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {
- Date = (EFI_IFR_DATE *) Statement->OpCode;
- } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- Time = (EFI_IFR_TIME *) Statement->OpCode;
- }
-
- //
- // If leading spaces on OptionString - remove the spaces
- //
- for (Index = 0; OptionString[Index] == L' '; Index++) {
- //
- // Base on the blockspace to get the option column info.
- //
- if (AddOptCol) {
- MenuOption->OptCol++;
- }
- }
-
- for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {
- OptionString[Count] = OptionString[Index];
- Count++;
- }
- OptionString[Count] = CHAR_NULL;
-
- //
- // Enable to suppress field in the opcode base on the flag.
- //
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP) {
- //
- // OptionString format is: <**: **: ****>
- // |month|day|year|
- // 4 3 5
- //
- if ((Date->Flags & EFI_QF_DATE_MONTH_SUPPRESS) && (MenuOption->Sequence == 0)) {
- //
- // At this point, only "<**:" in the optionstring.
- // Clean the day's ** field, after clean, the format is "< :"
- //
- SetUnicodeMem (&OptionString[1], 2, L' ');
- } else if ((Date->Flags & EFI_QF_DATE_DAY_SUPPRESS) && (MenuOption->Sequence == 1)) {
- //
- // At this point, only "**:" in the optionstring.
- // Clean the month's "**" field, after clean, the format is " :"
- //
- SetUnicodeMem (&OptionString[0], 2, L' ');
- } else if ((Date->Flags & EFI_QF_DATE_YEAR_SUPPRESS) && (MenuOption->Sequence == 2)) {
- //
- // At this point, only "****>" in the optionstring.
- // Clean the year's "****" field, after clean, the format is " >"
- //
- SetUnicodeMem (&OptionString[0], 4, L' ');
- }
- } else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- //
- // OptionString format is: <**: **: **>
- // |hour|minute|second|
- // 4 3 3
- //
- if ((Time->Flags & QF_TIME_HOUR_SUPPRESS) && (MenuOption->Sequence == 0)) {
- //
- // At this point, only "<**:" in the optionstring.
- // Clean the hour's ** field, after clean, the format is "< :"
- //
- SetUnicodeMem (&OptionString[1], 2, L' ');
- } else if ((Time->Flags & QF_TIME_MINUTE_SUPPRESS) && (MenuOption->Sequence == 1)) {
- //
- // At this point, only "**:" in the optionstring.
- // Clean the minute's "**" field, after clean, the format is " :"
- //
- SetUnicodeMem (&OptionString[0], 2, L' ');
- } else if ((Time->Flags & QF_TIME_SECOND_SUPPRESS) && (MenuOption->Sequence == 2)) {
- //
- // At this point, only "**>" in the optionstring.
- // Clean the second's "**" field, after clean, the format is " >"
- //
- SetUnicodeMem (&OptionString[0], 2, L' ');
- }
- }
-}
-
-
-/**
- Adjust Data and Time position accordingly.
- Data format : [01/02/2004] [11:22:33]
- Line number : 0 0 1 0 0 1
-
- This is an internal function.
-
- @param DirectionUp the up or down direction. False is down. True is
- up.
- @param CurrentPosition Current position. On return: Point to the last
- Option (Year or Second) if up; Point to the first
- Option (Month or Hour) if down.
-
- @return Return line number to pad. It is possible that we stand on a zero-advance
- @return data or time opcode, so pad one line when we judge if we are going to scroll outside.
-
-**/
-UINTN
-AdjustDateAndTimePosition (
- IN BOOLEAN DirectionUp,
- IN OUT LIST_ENTRY **CurrentPosition
- )
-{
- UINTN Count;
- LIST_ENTRY *NewPosition;
- UI_MENU_OPTION *MenuOption;
- UINTN PadLineNumber;
-
- PadLineNumber = 0;
- NewPosition = *CurrentPosition;
- MenuOption = MENU_OPTION_FROM_LINK (NewPosition);
-
- if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||
- (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
- //
- // Calculate the distance from current position to the last Date/Time MenuOption
- //
- Count = 0;
- while (MenuOption->Skip == 0) {
- Count++;
- NewPosition = NewPosition->ForwardLink;
- MenuOption = MENU_OPTION_FROM_LINK (NewPosition);
- PadLineNumber = 1;
- }
-
- NewPosition = *CurrentPosition;
- if (DirectionUp) {
- //
- // Since the behavior of hitting the up arrow on a Date/Time MenuOption is intended
- // to be one that back to the previous set of MenuOptions, we need to advance to the first
- // Date/Time MenuOption and leave the remaining logic in CfUiUp intact so the appropriate
- // checking can be done.
- //
- while (Count++ < 2) {
- NewPosition = NewPosition->BackLink;
- }
- } else {
- //
- // Since the behavior of hitting the down arrow on a Date/Time MenuOption is intended
- // to be one that progresses to the next set of MenuOptions, we need to advance to the last
- // Date/Time MenuOption and leave the remaining logic in CfUiDown intact so the appropriate
- // checking can be done.
- //
- while (Count-- > 0) {
- NewPosition = NewPosition->ForwardLink;
- }
- }
-
- *CurrentPosition = NewPosition;
- }
-
- return PadLineNumber;
-}
-
-/**
- Get step info from numeric opcode.
-
- @param[in] OpCode The input numeric op code.
-
- @return step info for this opcode.
-**/
-UINT64
-GetFieldFromNum (
- IN EFI_IFR_OP_HEADER *OpCode
- )
-{
- EFI_IFR_NUMERIC *NumericOp;
- UINT64 Step;
-
- NumericOp = (EFI_IFR_NUMERIC *) OpCode;
-
- switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {
- case EFI_IFR_NUMERIC_SIZE_1:
- Step = NumericOp->data.u8.Step;
- break;
-
- case EFI_IFR_NUMERIC_SIZE_2:
- Step = NumericOp->data.u16.Step;
- break;
-
- case EFI_IFR_NUMERIC_SIZE_4:
- Step = NumericOp->data.u32.Step;
- break;
-
- case EFI_IFR_NUMERIC_SIZE_8:
- Step = NumericOp->data.u64.Step;
- break;
-
- default:
- Step = 0;
- break;
- }
-
- return Step;
-}
-
-/**
- Find the registered HotKey based on KeyData.
-
- @param[in] KeyData A pointer to a buffer that describes the keystroke
- information for the hot key.
-
- @return The registered HotKey context. If no found, NULL will return.
-**/
-BROWSER_HOT_KEY *
-GetHotKeyFromRegisterList (
- IN EFI_INPUT_KEY *KeyData
- )
-{
- LIST_ENTRY *Link;
- BROWSER_HOT_KEY *HotKey;
-
- Link = GetFirstNode (&gFormData->HotKeyListHead);
- while (!IsNull (&gFormData->HotKeyListHead, Link)) {
- HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
-
- if (HotKey->KeyData->ScanCode == KeyData->ScanCode) {
- return HotKey;
- }
-
- Link = GetNextNode (&gFormData->HotKeyListHead, Link);
- }
-
- return NULL;
-}
-
-
-/**
- Determine if the menu is the last menu that can be selected.
-
- This is an internal function.
-
- @param Direction The scroll direction. False is down. True is up.
- @param CurrentPos The current focus.
-
- @return FALSE -- the menu isn't the last menu that can be selected.
- @return TRUE -- the menu is the last menu that can be selected.
-
-**/
-BOOLEAN
-ValueIsScroll (
- IN BOOLEAN Direction,
- IN LIST_ENTRY *CurrentPos
- )
-{
- LIST_ENTRY *Temp;
-
- Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;
-
- if (Temp == &gMenuOption) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- Wait for a given event to fire, or for an optional timeout to expire.
-
- @param Event The event to wait for
-
- @retval UI_EVENT_TYPE The type of the event which is trigged.
-
-**/
-UI_EVENT_TYPE
-UiWaitForEvent (
- IN EFI_EVENT Event
- )
-{
- EFI_STATUS Status;
- UINTN Index;
- UINTN EventNum;
- UINT64 Timeout;
- EFI_EVENT TimerEvent;
- EFI_EVENT WaitList[3];
- UI_EVENT_TYPE EventType;
-
- TimerEvent = NULL;
- Timeout = FormExitTimeout(gFormData);
-
- if (Timeout != 0) {
- Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
-
- //
- // Set the timer event
- //
- gBS->SetTimer (
- TimerEvent,
- TimerRelative,
- Timeout
- );
- }
-
- WaitList[0] = Event;
- EventNum = 1;
- if (gFormData->FormRefreshEvent != NULL) {
- WaitList[EventNum] = gFormData->FormRefreshEvent;
- EventNum ++;
- }
-
- if (Timeout != 0) {
- WaitList[EventNum] = TimerEvent;
- EventNum ++;
- }
-
- Status = gBS->WaitForEvent (EventNum, WaitList, &Index);
- ASSERT_EFI_ERROR (Status);
-
- switch (Index) {
- case 0:
- EventType = UIEventKey;
- break;
-
- case 1:
- if (gFormData->FormRefreshEvent != NULL) {
- EventType = UIEventDriver;
- } else {
- ASSERT (Timeout != 0 && EventNum == 2);
- EventType = UIEventTimeOut;
- }
- break;
-
- default:
- ASSERT (Index == 2 && EventNum == 3);
- EventType = UIEventTimeOut;
- break;
- }
-
- if (Timeout != 0) {
- gBS->CloseEvent (TimerEvent);
- }
-
- return EventType;
-}
-
-/**
- Get question id info from the input opcode header.
-
- @param OpCode The input opcode header pointer.
-
- @retval The question id for this opcode.
-
-**/
-EFI_QUESTION_ID
-GetQuestionIdInfo (
- IN EFI_IFR_OP_HEADER *OpCode
- )
-{
- EFI_IFR_QUESTION_HEADER *QuestionHeader;
-
- if (OpCode->Length < sizeof (EFI_IFR_OP_HEADER) + sizeof (EFI_IFR_QUESTION_HEADER)) {
- return 0;
- }
-
- QuestionHeader = (EFI_IFR_QUESTION_HEADER *)((UINT8 *) OpCode + sizeof(EFI_IFR_OP_HEADER));
-
- return QuestionHeader->QuestionId;
-}
-
-/**
- Find the first menu which will be show at the top.
-
- @param FormData The data info for this form.
- @param TopOfScreen The link_entry pointer to top menu.
- @param HighlightMenu The menu which will be highlight.
- @param SkipValue The skip value for the top menu.
-
-**/
-VOID
-FindTopMenu (
- IN FORM_DISPLAY_ENGINE_FORM *FormData,
- OUT LIST_ENTRY **TopOfScreen,
- OUT LIST_ENTRY **HighlightMenu,
- OUT INTN *SkipValue
- )
-{
- LIST_ENTRY *Link;
- LIST_ENTRY *NewPos;
- UINTN TopRow;
- UINTN BottomRow;
- UINTN Index;
- UI_MENU_OPTION *SavedMenuOption;
- UINTN EndRow;
-
- TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;
- BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;
-
- //
- // If not has input highlight statement, just return the first one in this form.
- //
- if (FormData->HighLightedStatement == NULL) {
- *TopOfScreen = gMenuOption.ForwardLink;
- *HighlightMenu = gMenuOption.ForwardLink;
- if (!IsListEmpty (&gMenuOption)) {
- MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow);
- }
- *SkipValue = 0;
- return;
- }
-
- //
- // Now base on the input highlight menu to find the top menu in this page.
- // Will base on the highlight menu show at the bottom to find the top menu.
- //
- NewPos = gMenuOption.ForwardLink;
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
-
- while ((SavedMenuOption->ThisTag != FormData->HighLightedStatement) ||
- (SavedMenuOption->Sequence != gSequence)) {
- NewPos = NewPos->ForwardLink;
- if (NewPos == &gMenuOption) {
- //
- // Not Found it, break
- //
- break;
- }
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- }
- ASSERT (SavedMenuOption->ThisTag == FormData->HighLightedStatement);
-
- *HighlightMenu = NewPos;
-
- AdjustDateAndTimePosition(FALSE, &NewPos);
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- UpdateOptionSkipLines (SavedMenuOption);
-
- //
- // If highlight opcode is date/time, keep the highlight row info not change.
- //
- if ((SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP || SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP) &&
- (gHighligthMenuInfo.QuestionId != 0) &&
- (gHighligthMenuInfo.QuestionId == GetQuestionIdInfo(SavedMenuOption->ThisTag->OpCode))) {
- //
- // Still show the highlight menu before exit from display engine.
- //
- EndRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;
- } else {
- EndRow = BottomRow;
- }
-
- //
- // Base on the selected menu will show at the bottome of next page,
- // select the menu show at the top of the next page.
- //
- Link = NewPos;
- for (Index = TopRow + SavedMenuOption->Skip; Index <= EndRow; ) {
- Link = Link->BackLink;
- //
- // Already find the first menu in this form, means highlight menu
- // will show in first page of this form.
- //
- if (Link == &gMenuOption) {
- *TopOfScreen = gMenuOption.ForwardLink;
- *SkipValue = 0;
- return;
- }
- SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
- UpdateOptionSkipLines (SavedMenuOption);
- Index += SavedMenuOption->Skip;
- }
-
- //
- // Found the menu which will show at the top of the page.
- //
- if (Link == NewPos) {
- //
- // The menu can show more than one pages, just show the menu at the top of the page.
- //
- *SkipValue = 0;
- *TopOfScreen = Link;
- } else {
- //
- // Check whether need to skip some line for menu shows at the top of the page.
- //
- *SkipValue = Index - EndRow;
- if (*SkipValue > 0 && *SkipValue < (INTN) SavedMenuOption->Skip) {
- *TopOfScreen = Link;
- } else {
- *SkipValue = 0;
- *TopOfScreen = Link->ForwardLink;
- }
- }
-}
-
-/**
- Display menu and wait for user to select one menu option, then return it.
- If AutoBoot is enabled, then if user doesn't select any option,
- after period of time, it will automatically return the first menu option.
-
- @param FormData The current form data info.
-
- @retval EFI_SUCESSS Process the user selection success.
- @retval EFI_NOT_FOUND Process option string for orderedlist/Oneof fail.
-
-**/
-EFI_STATUS
-UiDisplayMenu (
- IN FORM_DISPLAY_ENGINE_FORM *FormData
- )
-{
- INTN SkipValue;
- INTN Difference;
- UINTN DistanceValue;
- UINTN Row;
- UINTN Col;
- UINTN TempRightCol;
- UINTN Temp;
- UINTN Temp2;
- UINTN Temp3;
- UINTN TopRow;
- UINTN BottomRow;
- UINTN OriginalRow;
- UINTN Index;
- UINT16 Width;
- CHAR16 *StringPtr;
- CHAR16 *OptionString;
- CHAR16 *OutputString;
- CHAR16 *HelpString;
- CHAR16 *HelpHeaderString;
- CHAR16 *HelpBottomString;
- BOOLEAN NewLine;
- BOOLEAN Repaint;
- BOOLEAN UpArrow;
- BOOLEAN DownArrow;
- EFI_STATUS Status;
- EFI_INPUT_KEY Key;
- LIST_ENTRY *Link;
- LIST_ENTRY *NewPos;
- LIST_ENTRY *TopOfScreen;
- LIST_ENTRY *SavedListEntry;
- UI_MENU_OPTION *MenuOption;
- UI_MENU_OPTION *NextMenuOption;
- UI_MENU_OPTION *SavedMenuOption;
- UI_MENU_OPTION *PreviousMenuOption;
- UI_CONTROL_FLAG ControlFlag;
- UI_SCREEN_OPERATION ScreenOperation;
- UINT16 DefaultId;
- FORM_DISPLAY_ENGINE_STATEMENT *Statement;
- UINTN ModalSkipColumn;
- BROWSER_HOT_KEY *HotKey;
- UINTN HelpPageIndex;
- UINTN HelpPageCount;
- UINTN RowCount;
- UINTN HelpLine;
- UINTN HelpHeaderLine;
- UINTN HelpBottomLine;
- BOOLEAN MultiHelpPage;
- UINT16 GlyphWidth;
- UINT16 EachLineWidth;
- UINT16 HeaderLineWidth;
- UINT16 BottomLineWidth;
- EFI_STRING_ID HelpInfo;
- UI_EVENT_TYPE EventType;
- FORM_DISPLAY_ENGINE_STATEMENT *InitialHighlight;
-
- EventType = UIEventNone;
- Status = EFI_SUCCESS;
- HelpString = NULL;
- HelpHeaderString = NULL;
- HelpBottomString = NULL;
- OptionString = NULL;
- ScreenOperation = UiNoOperation;
- NewLine = TRUE;
- DefaultId = 0;
- HelpPageCount = 0;
- HelpLine = 0;
- RowCount = 0;
- HelpBottomLine = 0;
- HelpHeaderLine = 0;
- HelpPageIndex = 0;
- MultiHelpPage = FALSE;
- EachLineWidth = 0;
- HeaderLineWidth = 0;
- BottomLineWidth = 0;
- OutputString = NULL;
- UpArrow = FALSE;
- DownArrow = FALSE;
- SkipValue = 0;
-
- NextMenuOption = NULL;
- PreviousMenuOption = NULL;
- SavedMenuOption = NULL;
- HotKey = NULL;
- Repaint = TRUE;
- MenuOption = NULL;
- ModalSkipColumn = (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6;
- InitialHighlight = gFormData->HighLightedStatement;
-
- ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
-
- gOptionBlockWidth = (CHAR16) ((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3);
- gPromptBlockWidth = (CHAR16) (gOptionBlockWidth + LEFT_SKIPPED_COLUMNS);
- gHelpBlockWidth = (CHAR16) (gOptionBlockWidth - LEFT_SKIPPED_COLUMNS);
-
- TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;
- BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT - 1;
-
- Row = TopRow;
- if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
- Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + ModalSkipColumn;
- } else {
- Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS;
- }
-
- FindTopMenu(FormData, &TopOfScreen, &NewPos, &SkipValue);
-
- gST->ConOut->EnableCursor (gST->ConOut, FALSE);
-
- ControlFlag = CfInitialization;
- while (TRUE) {
- switch (ControlFlag) {
- case CfInitialization:
- if (IsListEmpty (&gMenuOption)) {
-
- if ((FormData->Attribute & HII_DISPLAY_MODAL) == 0) {
- //
- // Clear Statement range.
- //
- ClearLines (
- gStatementDimensions.LeftColumn,
- gStatementDimensions.RightColumn,
- TopRow - SCROLL_ARROW_HEIGHT,
- BottomRow + SCROLL_ARROW_HEIGHT,
- GetFieldTextColor ()
- );
-
- //
- // Clear Key Range
- //
- RefreshKeyHelp (gFormData, NULL, FALSE);
- }
-
- ControlFlag = CfReadKey;
- } else {
- ControlFlag = CfRepaint;
- }
- break;
-
- case CfRepaint:
- ControlFlag = CfRefreshHighLight;
-
- if (Repaint) {
- //
- // Display menu
- //
- DownArrow = FALSE;
- UpArrow = FALSE;
- Row = TopRow;
-
- Temp = (UINTN) SkipValue;
- Temp2 = (UINTN) SkipValue;
- Temp3 = (UINTN) SkipValue;
-
- //
- // 1. Clear the screen.
- //
- if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
- ClearLines (
- gStatementDimensions.LeftColumn + ModalSkipColumn,
- gStatementDimensions.LeftColumn + ModalSkipColumn + gPromptBlockWidth + gOptionBlockWidth,
- TopRow - SCROLL_ARROW_HEIGHT,
- BottomRow + SCROLL_ARROW_HEIGHT,
- GetFieldTextColor ()
- );
- } else {
- TempRightCol = gStatementDimensions.RightColumn;
- if (!mStatementLayoutIsChanged) {
- TempRightCol = gStatementDimensions.RightColumn - gHelpBlockWidth;
- }
- ClearLines (
- gStatementDimensions.LeftColumn,
- gStatementDimensions.RightColumn,
- TopRow - SCROLL_ARROW_HEIGHT,
- TopRow - 1,
- GetFieldTextColor ()
- );
- ClearLines (
- gStatementDimensions.LeftColumn,
- TempRightCol,
- TopRow,
- BottomRow,
- GetFieldTextColor ()
- );
- ClearLines (
- gStatementDimensions.LeftColumn,
- gStatementDimensions.RightColumn,
- BottomRow + 1,
- BottomRow + SCROLL_ARROW_HEIGHT,
- GetFieldTextColor ()
- );
- }
-
- //
- // 2.Paint the menu.
- //
- for (Link = TopOfScreen; Link != &gMenuOption; Link = Link->ForwardLink) {
- MenuOption = MENU_OPTION_FROM_LINK (Link);
- MenuOption->Row = Row;
- MenuOption->Col = Col;
- if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
- MenuOption->OptCol = gPromptBlockWidth + 1 + gStatementDimensions.LeftColumn + ModalSkipColumn;
- } else {
- MenuOption->OptCol = gPromptBlockWidth + 1 + gStatementDimensions.LeftColumn;
- }
-
- Statement = MenuOption->ThisTag;
- if (MenuOption->NestInStatement) {
- MenuOption->Col += SUBTITLE_INDENT;
- }
-
- if (MenuOption->GrayOut) {
- gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());
- } else {
- if (Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {
- gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());
- }
- }
-
- Width = GetWidth (Statement);
- OriginalRow = Row;
- GlyphWidth = 1;
-
- if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2) {
- //
- // Print Arrow for Goto button.
- //
- PrintCharAt (
- MenuOption->Col - 2,
- Row,
- GEOMETRICSHAPE_RIGHT_TRIANGLE
- );
- }
-
- //
- // 2.1. Paint the description.
- //
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- //
- // Temp means need to skip how many lines from the start.
- //
- if ((Temp == 0) && (Row <= BottomRow)) {
- PrintStringAt (MenuOption->Col, Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp == 0) {
- Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- Temp = 0;
- Row = OriginalRow;
-
- //
- // 2.2. Paint the option string.
- //
- Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE);
- //
- // If Error occur, question value update in ProcessOptions.
- // Exit current FormDisplay with new question value.
- //
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (OptionString != NULL) {
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- ProcessStringForDateTime(MenuOption, OptionString, TRUE);
- }
-
- Width = (UINT16) gOptionBlockWidth;
- OriginalRow = Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (Row <= BottomRow)) {
- PrintStringAt (MenuOption->OptCol, Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp2 == 0) {
- Row++;
- //
- // Since the Number of lines for this menu entry may or may not be reflected accurately
- // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
- // some testing to ensure we are keeping this in-sync.
- //
- // If the difference in rows is greater than or equal to the skip value, increase the skip value
- //
- if ((Row - OriginalRow) >= MenuOption->Skip) {
- MenuOption->Skip++;
- }
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- Row = OriginalRow;
-
- FreePool (OptionString);
- }
- Temp2 = 0;
-
- //
- // If this is a text op with secondary text information
- //
- if ((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo != 0)) {
- StringPtr = GetToken (((EFI_IFR_TEXT*)Statement->OpCode)->TextTwo, gFormData->HiiHandle);
-
- Width = (UINT16) gOptionBlockWidth;
- OriginalRow = Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp3 == 0) && (Row <= BottomRow)) {
- PrintStringAt (MenuOption->OptCol, Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&StringPtr[Index]) != 0) {
- if (Temp3 == 0) {
- Row++;
- //
- // Since the Number of lines for this menu entry may or may not be reflected accurately
- // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
- // some testing to ensure we are keeping this in-sync.
- //
- // If the difference in rows is greater than or equal to the skip value, increase the skip value
- //
- if ((Row - OriginalRow) >= MenuOption->Skip) {
- MenuOption->Skip++;
- }
- }
- }
-
- FreePool (OutputString);
- if (Temp3 != 0) {
- Temp3--;
- }
- }
-
- Row = OriginalRow;
- FreePool (StringPtr);
- }
- Temp3 = 0;
-
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
-
- //
- // 3. Update the row info which will be used by next menu.
- //
- if (Link == TopOfScreen) {
- Row += MenuOption->Skip - SkipValue;
- } else {
- Row += MenuOption->Skip;
- }
-
- if (Row > BottomRow) {
- if (!ValueIsScroll (FALSE, Link)) {
- DownArrow = TRUE;
- }
-
- Row = BottomRow + 1;
- break;
- }
- }
-
- if (!ValueIsScroll (TRUE, TopOfScreen)) {
- UpArrow = TRUE;
- }
-
- if (UpArrow) {
- gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ());
- PrintCharAt (
- gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
- TopRow - SCROLL_ARROW_HEIGHT,
- ARROW_UP
- );
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- }
-
- if (DownArrow) {
- gST->ConOut->SetAttribute (gST->ConOut, GetArrowColor ());
- PrintCharAt (
- gStatementDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
- BottomRow + SCROLL_ARROW_HEIGHT,
- ARROW_DOWN
- );
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- }
-
- MenuOption = NULL;
- }
- break;
-
- case CfRefreshHighLight:
-
- //
- // MenuOption: Last menu option that need to remove hilight
- // MenuOption is set to NULL in Repaint
- // NewPos: Current menu option that need to hilight
- //
- ControlFlag = CfUpdateHelpString;
-
- if (MenuOption != NULL && TopOfScreen == &MenuOption->Link) {
- Temp = SkipValue;
- } else {
- Temp = 0;
- }
- if (NewPos == TopOfScreen) {
- Temp2 = SkipValue;
- } else {
- Temp2 = 0;
- }
-
- if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {
- if (MenuOption != NULL) {
- //
- // Remove highlight on last Menu Option
- //
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- if (OptionString != NULL) {
- if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||
- (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)
- ) {
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);
- }
-
- Width = (UINT16) gOptionBlockWidth;
- OriginalRow = MenuOption->Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- FreePool (OptionString);
- } else {
- if (NewLine) {
- if (MenuOption->GrayOut) {
- gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());
- } else if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {
- gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());
- }
-
- OriginalRow = MenuOption->Row;
- Width = GetWidth (MenuOption->ThisTag);
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- MenuOption->Row = OriginalRow;
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- }
- }
- }
-
- //
- // This is the current selected statement
- //
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- Statement = MenuOption->ThisTag;
-
- //
- // Get the highlight statement.
- //
- gUserInput->SelectedStatement = Statement;
- gSequence = (UINT16) MenuOption->Sequence;
-
- //
- // Record highlight row info for date/time opcode.
- //
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- gHighligthMenuInfo.QuestionId = GetQuestionIdInfo(Statement->OpCode);
- gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row;
- } else {
- gHighligthMenuInfo.QuestionId = 0;
- gHighligthMenuInfo.DisplayRow = 0;
- }
-
- if (!IsSelectable (MenuOption)) {
- RefreshKeyHelp(gFormData, Statement, FALSE);
- break;
- }
-
- //
- // Set reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
-
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
- if (OptionString != NULL) {
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);
- }
- Width = (UINT16) gOptionBlockWidth;
-
- OriginalRow = MenuOption->Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp2 == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- FreePool (OptionString);
- } else {
- if (NewLine) {
- OriginalRow = MenuOption->Row;
-
- Width = GetWidth (Statement);
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp2 == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- }
- }
-
- RefreshKeyHelp(gFormData, MenuOption->ThisTag, FALSE);
-
- //
- // Clear reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- }
- break;
-
- case CfUpdateHelpString:
- ControlFlag = CfPrepareToReadKey;
- if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
- break;
- }
-
- if (Repaint || NewLine) {
- //
- // Don't print anything if it is a NULL help token
- //
- ASSERT(MenuOption != NULL);
- HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;
- if (HelpInfo == 0 || !IsSelectable (MenuOption)) {
- StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
- } else {
- StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);
- }
-
- RowCount = BottomRow - TopRow + 1;
- HelpPageIndex = 0;
- //
- // 1.Calculate how many line the help string need to print.
- //
- if (HelpString != NULL) {
- FreePool (HelpString);
- HelpString = NULL;
- }
- HelpLine = ProcessHelpString (StringPtr, &HelpString, &EachLineWidth, RowCount);
- FreePool (StringPtr);
-
- if (HelpLine > RowCount) {
- MultiHelpPage = TRUE;
- StringPtr = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_UP), gHiiHandle);
- if (HelpHeaderString != NULL) {
- FreePool (HelpHeaderString);
- HelpHeaderString = NULL;
- }
- HelpHeaderLine = ProcessHelpString (StringPtr, &HelpHeaderString, &HeaderLineWidth, 0);
- FreePool (StringPtr);
- StringPtr = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_DOWN), gHiiHandle);
- if (HelpBottomString != NULL) {
- FreePool (HelpBottomString);
- HelpBottomString = NULL;
- }
- HelpBottomLine = ProcessHelpString (StringPtr, &HelpBottomString, &BottomLineWidth, 0);
- FreePool (StringPtr);
- //
- // Calculate the help page count.
- //
- if (HelpLine > 2 * RowCount - 2) {
- HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;
- if ((HelpLine - RowCount + 1) % (RowCount - 2) > 1) {
- HelpPageCount += 1;
- }
- } else {
- HelpPageCount = 2;
- }
- } else {
- MultiHelpPage = FALSE;
- }
- }
-
- //
- // Check whether need to show the 'More(U/u)' at the begin.
- // Base on current direct info, here shows aligned to the right side of the column.
- // If the direction is multi line and aligned to right side may have problem, so
- // add ASSERT code here.
- //
- if (HelpPageIndex > 0) {
- gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());
- for (Index = 0; Index < HelpHeaderLine; Index++) {
- ASSERT (HelpHeaderLine == 1);
- ASSERT (GetStringWidth (HelpHeaderString) / 2 < (UINTN) (gHelpBlockWidth - 1));
- PrintStringAtWithWidth (
- gStatementDimensions.RightColumn - gHelpBlockWidth,
- Index + TopRow,
- gEmptyString,
- gHelpBlockWidth
- );
- PrintStringAt (
- gStatementDimensions.RightColumn - GetStringWidth (HelpHeaderString) / 2 - 1,
- Index + TopRow,
- &HelpHeaderString[Index * HeaderLineWidth]
- );
- }
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, GetHelpTextColor ());
- //
- // Print the help string info.
- //
- if (!MultiHelpPage) {
- for (Index = 0; Index < HelpLine; Index++) {
- PrintStringAtWithWidth (
- gStatementDimensions.RightColumn - gHelpBlockWidth,
- Index + TopRow,
- &HelpString[Index * EachLineWidth],
- gHelpBlockWidth
- );
- }
- for (; Index < RowCount; Index ++) {
- PrintStringAtWithWidth (
- gStatementDimensions.RightColumn - gHelpBlockWidth,
- Index + TopRow,
- gEmptyString,
- gHelpBlockWidth
- );
- }
- gST->ConOut->SetCursorPosition(gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);
- } else {
- if (HelpPageIndex == 0) {
- for (Index = 0; Index < RowCount - HelpBottomLine; Index++) {
- PrintStringAtWithWidth (
- gStatementDimensions.RightColumn - gHelpBlockWidth,
- Index + TopRow,
- &HelpString[Index * EachLineWidth],
- gHelpBlockWidth
- );
- }
- } else {
- for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) &&
- (Index + HelpPageIndex * (RowCount - 2) + 1 < HelpLine); Index++) {
- PrintStringAtWithWidth (
- gStatementDimensions.RightColumn - gHelpBlockWidth,
- Index + TopRow + HelpHeaderLine,
- &HelpString[(Index + HelpPageIndex * (RowCount - 2) + 1)* EachLineWidth],
- gHelpBlockWidth
- );
- }
- if (HelpPageIndex == HelpPageCount - 1) {
- for (; Index < RowCount - HelpHeaderLine; Index ++) {
- PrintStringAtWithWidth (
- gStatementDimensions.RightColumn - gHelpBlockWidth,
- Index + TopRow + HelpHeaderLine,
- gEmptyString,
- gHelpBlockWidth
- );
- }
- gST->ConOut->SetCursorPosition(gST->ConOut, gStatementDimensions.RightColumn-1, BottomRow);
- }
- }
- }
-
- //
- // Check whether need to print the 'More(D/d)' at the bottom.
- // Base on current direct info, here shows aligned to the right side of the column.
- // If the direction is multi line and aligned to right side may have problem, so
- // add ASSERT code here.
- //
- if (HelpPageIndex < HelpPageCount - 1 && MultiHelpPage) {
- gST->ConOut->SetAttribute (gST->ConOut, GetInfoTextColor ());
- for (Index = 0; Index < HelpBottomLine; Index++) {
- ASSERT (HelpBottomLine == 1);
- ASSERT (GetStringWidth (HelpBottomString) / 2 < (UINTN) (gHelpBlockWidth - 1));
- PrintStringAtWithWidth (
- gStatementDimensions.RightColumn - gHelpBlockWidth,
- BottomRow + Index - HelpBottomLine + 1,
- gEmptyString,
- gHelpBlockWidth
- );
- PrintStringAt (
- gStatementDimensions.RightColumn - GetStringWidth (HelpBottomString) / 2 - 1,
- BottomRow + Index - HelpBottomLine + 1,
- &HelpBottomString[Index * BottomLineWidth]
- );
- }
- }
- //
- // Reset this flag every time we finish using it.
- //
- Repaint = FALSE;
- NewLine = FALSE;
- break;
-
- case CfPrepareToReadKey:
- ControlFlag = CfReadKey;
- ScreenOperation = UiNoOperation;
- break;
-
- case CfReadKey:
- ControlFlag = CfScreenOperation;
-
- //
- // Wait for user's selection
- //
- while (TRUE) {
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
- if (!EFI_ERROR (Status)) {
- EventType = UIEventKey;
- break;
- }
-
- //
- // If we encounter error, continue to read another key in.
- //
- if (Status != EFI_NOT_READY) {
- continue;
- }
-
- EventType = UiWaitForEvent(gST->ConIn->WaitForKey);
- if (EventType == UIEventKey) {
- gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
- }
- break;
- }
-
- if (EventType == UIEventDriver) {
- gUserInput->Action = BROWSER_ACTION_NONE;
- ControlFlag = CfExit;
- break;
- }
-
- if (EventType == UIEventTimeOut) {
- gUserInput->Action = BROWSER_ACTION_FORM_EXIT;
- ControlFlag = CfExit;
- break;
- }
-
- switch (Key.UnicodeChar) {
- case CHAR_CARRIAGE_RETURN:
- if(MenuOption == NULL || MenuOption->GrayOut || MenuOption->ReadOnly) {
- ControlFlag = CfReadKey;
- break;
- }
-
- ScreenOperation = UiSelect;
- gDirection = 0;
- break;
-
- //
- // We will push the adjustment of these numeric values directly to the input handler
- // NOTE: we won't handle manual input numeric
- //
- case '+':
- case '-':
- //
- // If the screen has no menu items, and the user didn't select UiReset
- // ignore the selection and go back to reading keys.
- //
- if(IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) {
- ControlFlag = CfReadKey;
- break;
- }
-
- ASSERT(MenuOption != NULL);
- Statement = MenuOption->ThisTag;
- if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP)
- || (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)
- || ((Statement->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (GetFieldFromNum(Statement->OpCode) != 0))
- ){
- if (Key.UnicodeChar == '+') {
- gDirection = SCAN_RIGHT;
- } else {
- gDirection = SCAN_LEFT;
- }
-
- Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);
- if (OptionString != NULL) {
- FreePool (OptionString);
- }
- if (EFI_ERROR (Status)) {
- //
- // Repaint to clear possible error prompt pop-up
- //
- Repaint = TRUE;
- NewLine = TRUE;
- } else {
- ControlFlag = CfExit;
- }
- }
- break;
-
- case '^':
- ScreenOperation = UiUp;
- break;
-
- case 'V':
- case 'v':
- ScreenOperation = UiDown;
- break;
-
- case ' ':
- if(IsListEmpty (&gMenuOption)) {
- ControlFlag = CfReadKey;
- break;
- }
-
- ASSERT(MenuOption != NULL);
- if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut && !MenuOption->ReadOnly) {
- ScreenOperation = UiSelect;
- }
- break;
-
- case 'D':
- case 'd':
- if (!MultiHelpPage) {
- ControlFlag = CfReadKey;
- break;
- }
- ControlFlag = CfUpdateHelpString;
- HelpPageIndex = HelpPageIndex < HelpPageCount - 1 ? HelpPageIndex + 1 : HelpPageCount - 1;
- break;
-
- case 'U':
- case 'u':
- if (!MultiHelpPage) {
- ControlFlag = CfReadKey;
- break;
- }
- ControlFlag = CfUpdateHelpString;
- HelpPageIndex = HelpPageIndex > 0 ? HelpPageIndex - 1 : 0;
- break;
-
- case CHAR_NULL:
- for (Index = 0; Index < mScanCodeNumber; Index++) {
- if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {
- ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;
- break;
- }
- }
-
- if (((FormData->Attribute & HII_DISPLAY_MODAL) != 0) && (Key.ScanCode == SCAN_ESC || Index == mScanCodeNumber)) {
- //
- // ModalForm has no ESC key and Hot Key.
- //
- ControlFlag = CfReadKey;
- } else if (Index == mScanCodeNumber) {
- //
- // Check whether Key matches the registered hot key.
- //
- HotKey = NULL;
- HotKey = GetHotKeyFromRegisterList (&Key);
- if (HotKey != NULL) {
- ScreenOperation = UiHotKey;
- }
- }
- break;
- }
- break;
-
- case CfScreenOperation:
- if (ScreenOperation != UiReset) {
- //
- // If the screen has no menu items, and the user didn't select UiReset
- // ignore the selection and go back to reading keys.
- //
- if (IsListEmpty (&gMenuOption)) {
- ControlFlag = CfReadKey;
- break;
- }
- }
-
- for (Index = 0;
- Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);
- Index++
- ) {
- if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {
- ControlFlag = gScreenOperationToControlFlag[Index].ControlFlag;
- break;
- }
- }
- break;
-
- case CfUiSelect:
- ControlFlag = CfRepaint;
-
- ASSERT(MenuOption != NULL);
- Statement = MenuOption->ThisTag;
- if (Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) {
- break;
- }
-
- switch (Statement->OpCode->OpCode) {
- case EFI_IFR_REF_OP:
- case EFI_IFR_ACTION_OP:
- case EFI_IFR_RESET_BUTTON_OP:
- ControlFlag = CfExit;
- break;
-
- default:
- //
- // Editable Questions: oneof, ordered list, checkbox, numeric, string, password
- //
- RefreshKeyHelp (gFormData, Statement, TRUE);
- Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);
-
- if (OptionString != NULL) {
- FreePool (OptionString);
- }
-
- if (EFI_ERROR (Status)) {
- Repaint = TRUE;
- NewLine = TRUE;
- RefreshKeyHelp (gFormData, Statement, FALSE);
- break;
- } else {
- ControlFlag = CfExit;
- break;
- }
- }
- break;
-
- case CfUiReset:
- //
- // We come here when someone press ESC
- // If the policy is not exit front page when user press ESC, process here.
- //
- if (!FormExitPolicy()) {
- Repaint = TRUE;
- NewLine = TRUE;
- ControlFlag = CfRepaint;
- break;
- }
-
- //
- // When user press ESC, it will try to show another menu, should clean the gSequence info.
- //
- if (gSequence != 0) {
- gSequence = 0;
- }
-
- gUserInput->Action = BROWSER_ACTION_FORM_EXIT;
- ControlFlag = CfExit;
- break;
-
- case CfUiHotKey:
- ControlFlag = CfRepaint;
-
- gUserInput->Action = HotKey->Action;
- ControlFlag = CfExit;
- break;
-
- case CfUiLeft:
- ControlFlag = CfRepaint;
- ASSERT(MenuOption != NULL);
- if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
- if (MenuOption->Sequence != 0) {
- //
- // In the middle or tail of the Date/Time op-code set, go left.
- //
- ASSERT(NewPos != NULL);
- NewPos = NewPos->BackLink;
- }
- }
- break;
-
- case CfUiRight:
- ControlFlag = CfRepaint;
- ASSERT(MenuOption != NULL);
- if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)) {
- if (MenuOption->Sequence != 2) {
- //
- // In the middle or tail of the Date/Time op-code set, go left.
- //
- ASSERT(NewPos != NULL);
- NewPos = NewPos->ForwardLink;
- }
- }
- break;
-
- case CfUiUp:
- ControlFlag = CfRepaint;
-
- SavedListEntry = NewPos;
-
- ASSERT(NewPos != NULL);
- //
- // Adjust Date/Time position before we advance forward.
- //
- AdjustDateAndTimePosition (TRUE, &NewPos);
- if (NewPos->BackLink != &gMenuOption) {
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- ASSERT (MenuOption != NULL);
- NewLine = TRUE;
- NewPos = NewPos->BackLink;
-
- PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (PreviousMenuOption->Row == 0) {
- UpdateOptionSkipLines (PreviousMenuOption);
- }
- DistanceValue = PreviousMenuOption->Skip;
- Difference = 0;
- if (MenuOption->Row >= DistanceValue + TopRow) {
- Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);
- }
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
-
- if (Difference < 0) {
- //
- // We hit the begining MenuOption that can be focused
- // so we simply scroll to the top.
- //
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- } else {
- //
- // Scroll up to the last page when we have arrived at top page.
- //
- NewPos = &gMenuOption;
- TopOfScreen = &gMenuOption;
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- ScreenOperation = UiPageUp;
- ControlFlag = CfScreenOperation;
- break;
- }
- } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {
- //
- // Previous focus MenuOption is above the TopOfScreen, so we need to scroll
- //
- TopOfScreen = NewPos;
- Repaint = TRUE;
- SkipValue = 0;
- } else if (!IsSelectable (NextMenuOption)) {
- //
- // Continue to go up until scroll to next page or the selectable option is found.
- //
- ScreenOperation = UiUp;
- ControlFlag = CfScreenOperation;
- }
-
- //
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- UpdateStatusBar (INPUT_ERROR, FALSE);
- } else {
- //
- // Scroll up to the last page.
- //
- NewPos = &gMenuOption;
- TopOfScreen = &gMenuOption;
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- ScreenOperation = UiPageUp;
- ControlFlag = CfScreenOperation;
- }
- break;
-
- case CfUiPageUp:
- //
- // SkipValue means lines is skipped when show the top menu option.
- //
- ControlFlag = CfRepaint;
-
- ASSERT(NewPos != NULL);
- //
- // Already at the first menu option, Check the skip value.
- //
- if (NewPos->BackLink == &gMenuOption) {
- if (SkipValue == 0) {
- NewLine = FALSE;
- Repaint = FALSE;
- } else {
- NewLine = TRUE;
- Repaint = TRUE;
- SkipValue = 0;
- }
- break;
- }
-
- NewLine = TRUE;
- Repaint = TRUE;
-
- //
- // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
- // form of options to be show, so just update the SkipValue to show the next
- // parts of options.
- //
- if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {
- SkipValue -= BottomRow - TopRow + 1;
- break;
- }
-
- Link = TopOfScreen;
- //
- // First minus the menu of the top screen, it's value is SkipValue.
- //
- Index = (BottomRow + 1) - SkipValue;
- while ((Index > TopRow) && (Link->BackLink != &gMenuOption)) {
- Link = Link->BackLink;
- PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
- if (PreviousMenuOption->Row == 0) {
- UpdateOptionSkipLines (PreviousMenuOption);
- }
- if (Index < PreviousMenuOption->Skip) {
- break;
- }
- Index = Index - PreviousMenuOption->Skip;
- }
-
- if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {
- SkipValue = 0;
- if (TopOfScreen == &gMenuOption) {
- TopOfScreen = gMenuOption.ForwardLink;
- NewPos = gMenuOption.BackLink;
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);
- Repaint = FALSE;
- } else if (TopOfScreen != Link) {
- TopOfScreen = Link;
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
- } else {
- //
- // Finally we know that NewPos is the last MenuOption can be focused.
- //
- Repaint = FALSE;
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
- }
- } else {
- if (Index > TopRow) {
- //
- // At here, only case "Index < PreviousMenuOption->Skip" can reach here.
- //
- SkipValue = PreviousMenuOption->Skip - (Index - TopRow);
- } else if (Index == TopRow) {
- SkipValue = 0;
- } else {
- SkipValue = TopRow - Index;
- }
-
- //
- // Move to the option in Next page.
- //
- if (TopOfScreen == &gMenuOption) {
- NewPos = gMenuOption.BackLink;
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);
- } else {
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
- }
-
- //
- // There are more MenuOption needing scrolling up.
- //
- TopOfScreen = Link;
- MenuOption = NULL;
- }
-
- //
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
- // Don't do this when we are already in the first page.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
-
- case CfUiPageDown:
- //
- // SkipValue means lines is skipped when show the top menu option.
- //
- ControlFlag = CfRepaint;
-
- ASSERT (NewPos != NULL);
- if (NewPos->ForwardLink == &gMenuOption) {
- NewLine = FALSE;
- Repaint = FALSE;
- break;
- }
-
- NewLine = TRUE;
- Repaint = TRUE;
- Link = TopOfScreen;
- NextMenuOption = MENU_OPTION_FROM_LINK (Link);
- Index = TopRow + NextMenuOption->Skip - SkipValue;
- //
- // Count to the menu option which will show at the top of the next form.
- //
- while ((Index <= BottomRow + 1) && (Link->ForwardLink != &gMenuOption)) {
- Link = Link->ForwardLink;
- NextMenuOption = MENU_OPTION_FROM_LINK (Link);
- Index = Index + NextMenuOption->Skip;
- }
-
- if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {
- //
- // Finally we know that NewPos is the last MenuOption can be focused.
- //
- Repaint = FALSE;
- MoveToNextStatement (TRUE, &Link, Index - TopRow);
- } else {
- //
- // Calculate the skip line for top of screen menu.
- //
- if (Link == TopOfScreen) {
- //
- // The top of screen menu option occupies the entire form.
- //
- SkipValue += BottomRow - TopRow + 1;
- } else {
- SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));
- }
-
- TopOfScreen = Link;
- MenuOption = NULL;
- //
- // Move to the Next selectable menu.
- //
- MoveToNextStatement (FALSE, &Link, BottomRow - TopRow);
- }
-
- //
- // Save the menu as the next highlight menu.
- //
- NewPos = Link;
-
- //
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
- // Don't do this when we are already in the last page.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
-
- case CfUiDown:
- //
- // SkipValue means lines is skipped when show the top menu option.
- // NewPos points to the menu which is highlighted now.
- //
- ControlFlag = CfRepaint;
-
- //
- // Since the behavior of hitting the down arrow on a Date/Time op-code is intended
- // to be one that progresses to the next set of op-codes, we need to advance to the last
- // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate
- // checking can be done. The only other logic we need to introduce is that if a Date/Time
- // op-code is the last entry in the menu, we need to rewind back to the first op-code of
- // the Date/Time op-code.
- //
- SavedListEntry = NewPos;
- AdjustDateAndTimePosition (FALSE, &NewPos);
-
- if (NewPos->ForwardLink != &gMenuOption) {
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- NewLine = TRUE;
- NewPos = NewPos->ForwardLink;
-
- Difference = 0;
- //
- // Current menu not at the bottom of the form.
- //
- if (BottomRow >= MenuOption->Row + MenuOption->Skip) {
- //
- // Find the next selectable menu.
- //
- Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);
- //
- // We hit the end of MenuOption that can be focused
- // so we simply scroll to the first page.
- //
- if (Difference < 0) {
- //
- // Scroll to the first page.
- //
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
- } else {
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- }
- NewPos = gMenuOption.ForwardLink;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
-
- SkipValue = 0;
- //
- // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
- }
- }
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (NextMenuOption->Row == 0) {
- UpdateOptionSkipLines (NextMenuOption);
- }
- DistanceValue = Difference + NextMenuOption->Skip;
-
- Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;
- if ((MenuOption->Row + MenuOption->Skip == BottomRow + 1) &&
- (NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP ||
- NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)
- ) {
- Temp ++;
- }
-
- //
- // If we are going to scroll, update TopOfScreen
- //
- if (Temp > BottomRow) {
- do {
- //
- // Is the current top of screen a zero-advance op-code?
- // If so, keep moving forward till we hit a >0 advance op-code
- //
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
-
- //
- // If bottom op-code is more than one line or top op-code is more than one line
- //
- if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {
- //
- // Is the bottom op-code greater than or equal in size to the top op-code?
- //
- if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
- //
- // Skip the top op-code
- //
- TopOfScreen = TopOfScreen->ForwardLink;
- Difference = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
-
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
-
- //
- // If we have a remainder, skip that many more op-codes until we drain the remainder
- //
- while (Difference >= (INTN) SavedMenuOption->Skip) {
- //
- // Since the Difference is greater than or equal to this op-code's skip value, skip it
- //
- Difference = Difference - (INTN) SavedMenuOption->Skip;
- TopOfScreen = TopOfScreen->ForwardLink;
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
- }
- //
- // Since we will act on this op-code in the next routine, and increment the
- // SkipValue, set the skips to one less than what is required.
- //
- SkipValue = Difference - 1;
- } else {
- //
- // Since we will act on this op-code in the next routine, and increment the
- // SkipValue, set the skips to one less than what is required.
- //
- SkipValue += (Temp - BottomRow) - 1;
- }
- } else {
- if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {
- TopOfScreen = TopOfScreen->ForwardLink;
- break;
- }
- }
- //
- // If the op-code at the top of the screen is more than one line, let's not skip it yet
- // Let's set a skip flag to smoothly scroll the top of the screen.
- //
- if (SavedMenuOption->Skip > 1) {
- if (SavedMenuOption == NextMenuOption) {
- SkipValue = 0;
- } else {
- SkipValue++;
- }
- } else if (SavedMenuOption->Skip == 1) {
- SkipValue = 0;
- } else {
- SkipValue = 0;
- TopOfScreen = TopOfScreen->ForwardLink;
- }
- } while (SavedMenuOption->Skip == 0);
-
- Repaint = TRUE;
- } else if (!IsSelectable (NextMenuOption)) {
- //
- // Continue to go down until scroll to next page or the selectable option is found.
- //
- ScreenOperation = UiDown;
- ControlFlag = CfScreenOperation;
- }
-
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
-
- UpdateStatusBar (INPUT_ERROR, FALSE);
-
- } else {
- //
- // Scroll to the first page.
- //
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
- } else {
- //
- // Need to remove the current highlight menu.
- // MenuOption saved the last highlight menu info.
- //
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- }
-
- SkipValue = 0;
- NewLine = TRUE;
- //
- // Get the next highlight menu.
- //
- NewPos = gMenuOption.ForwardLink;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
- }
-
- //
- // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
-
- case CfUiNoOperation:
- ControlFlag = CfRepaint;
- break;
-
- case CfExit:
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- if (HelpString != NULL) {
- FreePool (HelpString);
- }
- if (HelpHeaderString != NULL) {
- FreePool (HelpHeaderString);
- }
- if (HelpBottomString != NULL) {
- FreePool (HelpBottomString);
- }
- return EFI_SUCCESS;
-
- default:
- break;
- }
- }
-}
-
-/**
-
- Base on the browser status info to show an pop up message.
-
-**/
-VOID
-BrowserStatusProcess (
- VOID
- )
-{
- CHAR16 *ErrorInfo;
- EFI_INPUT_KEY Key;
-
- if (gFormData->BrowserStatus == BROWSER_SUCCESS) {
- return;
- }
-
- if (gFormData->ErrorString != NULL) {
- ErrorInfo = gFormData->ErrorString;
- } else {
- switch (gFormData->BrowserStatus) {
- case BROWSER_SUBMIT_FAIL:
- ErrorInfo = gSaveFailed;
- break;
-
- case BROWSER_NO_SUBMIT_IF:
- ErrorInfo = gNoSubmitIf;
- break;
-
- case BROWSER_FORM_NOT_FOUND:
- ErrorInfo = gFormNotFound;
- break;
-
- case BROWSER_FORM_SUPPRESS:
- ErrorInfo = gFormSuppress;
- break;
-
- case BROWSER_PROTOCOL_NOT_FOUND:
- ErrorInfo = gProtocolNotFound;
- break;
-
- default:
- ErrorInfo = gBrwoserError;
- break;
- }
- }
-
- //
- // Error occur, prompt error message.
- //
- do {
- CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-}
-
-/**
- Display one form, and return user input.
-
- @param FormData Form Data to be shown.
- @param UserInputData User input data.
-
- @retval EFI_SUCCESS 1.Form Data is shown, and user input is got.
- 2.Error info has show and return.
- @retval EFI_INVALID_PARAMETER The input screen dimension is not valid
- @retval EFI_NOT_FOUND New form data has some error.
-**/
-EFI_STATUS
-EFIAPI
-FormDisplay (
- IN FORM_DISPLAY_ENGINE_FORM *FormData,
- OUT USER_INPUT *UserInputData
- )
-{
- EFI_STATUS Status;
-
- ASSERT (FormData != NULL);
- if (FormData == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- gUserInput = UserInputData;
- gFormData = FormData;
-
- //
- // Process the status info first.
- //
- BrowserStatusProcess();
- if (UserInputData == NULL) {
- //
- // UserInputData == NULL, means only need to print the error info, return here.
- //
- return EFI_SUCCESS;
- }
-
- ConvertStatementToMenu();
-
- Status = DisplayPageFrame (FormData, &gStatementDimensions);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Check whether layout is changed.
- //
- if (mIsFirstForm
- || (gOldFormEntry.HiiHandle != FormData->HiiHandle)
- || (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))
- || (gOldFormEntry.FormId != FormData->FormId)) {
- mStatementLayoutIsChanged = TRUE;
- } else {
- mStatementLayoutIsChanged = FALSE;
- }
-
- Status = UiDisplayMenu(FormData);
-
- //
- // Backup last form info.
- //
- mIsFirstForm = FALSE;
- gOldFormEntry.HiiHandle = FormData->HiiHandle;
- CopyGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid);
- gOldFormEntry.FormId = FormData->FormId;
-
- return Status;
-}
-
-/**
- Clear Screen to the initial state.
-**/
-VOID
-EFIAPI
-DriverClearDisplayPage (
- VOID
- )
-{
- ClearDisplayPage ();
- mIsFirstForm = TRUE;
-}
-
-/**
- Set Buffer to Value for Size bytes.
-
- @param Buffer Memory to set.
- @param Size Number of bytes to set
- @param Value Value of the set operation.
-
-**/
-VOID
-SetUnicodeMem (
- IN VOID *Buffer,
- IN UINTN Size,
- IN CHAR16 Value
- )
-{
- CHAR16 *Ptr;
-
- Ptr = Buffer;
- while ((Size--) != 0) {
- *(Ptr++) = Value;
- }
-}
-
-/**
- Initialize Setup Browser driver.
-
- @param ImageHandle The image handle.
- @param SystemTable The system table.
-
- @retval EFI_SUCCESS The Setup Browser module is initialized correctly..
- @return Other value if failed to initialize the Setup Browser module.
-
-**/
-EFI_STATUS
-EFIAPI
-InitializeDisplayEngine (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- EFI_INPUT_KEY HotKey;
- EFI_STRING NewString;
- EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL *FormBrowserEx2;
-
- //
- // Publish our HII data
- //
- gHiiHandle = HiiAddPackages (
- &gDisplayEngineGuid,
- ImageHandle,
- DisplayEngineStrings,
- NULL
- );
- ASSERT (gHiiHandle != NULL);
-
- //
- // Install Form Display protocol
- //
- Status = gBS->InstallProtocolInterface (
- &mPrivateData.Handle,
- &gEdkiiFormDisplayEngineProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mPrivateData.FromDisplayProt
- );
- ASSERT_EFI_ERROR (Status);
-
- InitializeDisplayStrings();
-
- ZeroMem (&gHighligthMenuInfo, sizeof (gHighligthMenuInfo));
- ZeroMem (&gOldFormEntry, sizeof (gOldFormEntry));
-
- //
- // Use BrowserEx2 protocol to register HotKey.
- //
- Status = gBS->LocateProtocol (&gEdkiiFormBrowserEx2ProtocolGuid, NULL, (VOID **) &FormBrowserEx2);
- if (!EFI_ERROR (Status)) {
- //
- // Register the default HotKey F9 and F10 again.
- //
- HotKey.UnicodeChar = CHAR_NULL;
- HotKey.ScanCode = SCAN_F10;
- NewString = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_TEN_STRING), NULL);
- ASSERT (NewString != NULL);
- FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);
-
- HotKey.ScanCode = SCAN_F9;
- NewString = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_NINE_STRING), NULL);
- ASSERT (NewString != NULL);
- FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- This is the default unload handle for display core drivers.
-
- @param[in] ImageHandle The drivers' driver image.
-
- @retval EFI_SUCCESS The image is unloaded.
- @retval Others Failed to unload the image.
-
-**/
-EFI_STATUS
-EFIAPI
-UnloadDisplayEngine (
- IN EFI_HANDLE ImageHandle
- )
-{
- HiiRemovePackages(gHiiHandle);
-
- FreeDisplayStrings ();
-
- return EFI_SUCCESS;
-}
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h deleted file mode 100644 index 45bcadc7e6..0000000000 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h +++ /dev/null @@ -1,589 +0,0 @@ -/** @file
- FormDiplay protocol to show Form
-
-Copyright (c) 2013, 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 that 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.
-
-**/
-
-#ifndef __FORM_DISPLAY_H__
-#define __FORM_DISPLAY_H__
-
-
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/BaseLib.h>
-#include <Library/HiiLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PrintLib.h>
-#include <Library/CustomizedDisplayLib.h>
-
-#include <Protocol/FormBrowserEx2.h>
-#include <Protocol/SimpleTextIn.h>
-#include <Protocol/DisplayProtocol.h>
-
-#include <Guid/MdeModuleHii.h>
-
-//
-// This is the generated header file which includes whatever needs to be exported (strings + IFR)
-//
-extern UINT8 DisplayEngineStrings[];
-extern EFI_SCREEN_DESCRIPTOR gStatementDimensions;
-extern USER_INPUT *gUserInput;
-extern FORM_DISPLAY_ENGINE_FORM *gFormData;
-extern EFI_HII_HANDLE gHiiHandle;
-extern UINT16 gDirection;
-extern LIST_ENTRY gMenuOption;
-
-//
-// Browser Global Strings
-//
-extern CHAR16 *gSaveFailed;
-extern CHAR16 *gPromptForData;
-extern CHAR16 *gPromptForPassword;
-extern CHAR16 *gPromptForNewPassword;
-extern CHAR16 *gConfirmPassword;
-extern CHAR16 *gConfirmError;
-extern CHAR16 *gPassowordInvalid;
-extern CHAR16 *gPressEnter;
-extern CHAR16 *gEmptyString;
-extern CHAR16 *gMiniString;
-extern CHAR16 *gOptionMismatch;
-extern CHAR16 *gFormSuppress;
-extern CHAR16 *gProtocolNotFound;
-
-extern CHAR16 gPromptBlockWidth;
-extern CHAR16 gOptionBlockWidth;
-extern CHAR16 gHelpBlockWidth;
-extern CHAR16 *mUnknownString;
-
-//
-// Screen definitions
-//
-
-#define LEFT_SKIPPED_COLUMNS 3
-#define SCROLL_ARROW_HEIGHT 1
-#define POPUP_PAD_SPACE_COUNT 5
-#define POPUP_FRAME_WIDTH 2
-
-//
-// Display definitions
-//
-#define LEFT_ONEOF_DELIMITER L'<'
-#define RIGHT_ONEOF_DELIMITER L'>'
-
-#define LEFT_NUMERIC_DELIMITER L'['
-#define RIGHT_NUMERIC_DELIMITER L']'
-
-#define LEFT_CHECKBOX_DELIMITER L'['
-#define RIGHT_CHECKBOX_DELIMITER L']'
-
-#define CHECK_ON L'X'
-#define CHECK_OFF L' '
-
-#define TIME_SEPARATOR L':'
-#define DATE_SEPARATOR L'/'
-
-#define SUBTITLE_INDENT 2
-
-//
-// This is the Input Error Message
-//
-#define INPUT_ERROR 1
-
-//
-// This is the NV RAM update required Message
-//
-#define NV_UPDATE_REQUIRED 2
-//
-// Time definitions
-//
-#define ONE_SECOND 10000000
-
-//
-// It take 23 characters including the NULL to print a 64 bits number with "[" and "]".
-// pow(2, 64) = [18446744073709551616]
-//
-#define MAX_NUMERIC_INPUT_WIDTH 23
-
-#define EFI_HII_EXPRESSION_INCONSISTENT_IF 0
-#define EFI_HII_EXPRESSION_NO_SUBMIT_IF 1
-#define EFI_HII_EXPRESSION_GRAY_OUT_IF 2
-#define EFI_HII_EXPRESSION_SUPPRESS_IF 3
-#define EFI_HII_EXPRESSION_DISABLE_IF 4
-
-//
-// Character definitions
-//
-#define CHAR_SPACE 0x0020
-
-#define FORM_DISPLAY_DRIVER_SIGNATURE SIGNATURE_32 ('F', 'D', 'D', 'V')
-typedef struct {
- UINT32 Signature;
-
- EFI_HANDLE Handle;
-
- //
- // Produced protocol
- //
- EDKII_FORM_DISPLAY_ENGINE_PROTOCOL FromDisplayProt;
-} FORM_DISPLAY_DRIVER_PRIVATE_DATA;
-
-
-typedef enum {
- UiNoOperation,
- UiSelect,
- UiUp,
- UiDown,
- UiLeft,
- UiRight,
- UiReset,
- UiPrevious,
- UiPageUp,
- UiPageDown,
- UiHotKey,
- UiMaxOperation
-} UI_SCREEN_OPERATION;
-
-typedef enum {
- CfInitialization,
- CfCheckSelection,
- CfRepaint,
- CfRefreshHighLight,
- CfUpdateHelpString,
- CfPrepareToReadKey,
- CfReadKey,
- CfScreenOperation,
- CfUiSelect,
- CfUiReset,
- CfUiLeft,
- CfUiRight,
- CfUiUp,
- CfUiPageUp,
- CfUiPageDown,
- CfUiDown,
- CfUiDefault,
- CfUiNoOperation,
- CfExit,
- CfUiHotKey,
- CfMaxControlFlag
-} UI_CONTROL_FLAG;
-
-typedef enum {
- UIEventNone,
- UIEventKey,
- UIEventTimeOut,
- UIEventDriver
-} UI_EVENT_TYPE;
-
-typedef struct {
- UINT16 ScanCode;
- UI_SCREEN_OPERATION ScreenOperation;
-} SCAN_CODE_TO_SCREEN_OPERATION;
-
-typedef struct {
- UI_SCREEN_OPERATION ScreenOperation;
- UI_CONTROL_FLAG ControlFlag;
-} SCREEN_OPERATION_T0_CONTROL_FLAG;
-
-typedef struct {
- EFI_QUESTION_ID QuestionId;
- UINT16 DisplayRow;
-} DISPLAY_HIGHLIGHT_MENU_INFO;
-
-#define UI_MENU_OPTION_SIGNATURE SIGNATURE_32 ('u', 'i', 'm', 'm')
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
-
- EFI_HII_HANDLE Handle;
- FORM_DISPLAY_ENGINE_STATEMENT *ThisTag;
- UINT16 EntryNumber;
-
- UINTN Row;
- UINTN Col;
- UINTN OptCol;
- CHAR16 *Description;
- UINTN Skip; // Number of lines
-
- //
- // Display item sequence for date/time
- // Date: Month/Day/Year
- // Sequence: 0 1 2
- //
- // Time: Hour : Minute : Second
- // Sequence: 0 1 2
- //
- //
- UINTN Sequence;
-
- BOOLEAN GrayOut;
- BOOLEAN ReadOnly;
-
- //
- // Whether user could change value of this item
- //
- BOOLEAN IsQuestion;
- BOOLEAN NestInStatement;
-} UI_MENU_OPTION;
-
-#define MENU_OPTION_FROM_LINK(a) CR (a, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE)
-
-/**
- Print Question Value according to it's storage width and display attributes.
-
- @param Question The Question to be printed.
- @param FormattedNumber Buffer for output string.
- @param BufferSize The FormattedNumber buffer size in bytes.
-
- @retval EFI_SUCCESS Print success.
- @retval EFI_BUFFER_TOO_SMALL Buffer size is not enough for formatted number.
-
-**/
-EFI_STATUS
-PrintFormattedNumber (
- IN FORM_DISPLAY_ENGINE_STATEMENT *Question,
- IN OUT CHAR16 *FormattedNumber,
- IN UINTN BufferSize
- );
-
-/**
- Set value of a data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
- @param Value The value to be set.
-
-**/
-VOID
-SetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index,
- IN UINT64 Value
- );
-
-/**
- Return data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
-
- @retval Value The data to be returned
-
-**/
-UINT64
-GetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index
- );
-
-/**
- Search an Option of a Question by its value.
-
- @param Question The Question
- @param OptionValue Value for Option to be searched.
-
- @retval Pointer Pointer to the found Option.
- @retval NULL Option not found.
-
-**/
-DISPLAY_QUESTION_OPTION *
-ValueToOption (
- IN FORM_DISPLAY_ENGINE_STATEMENT *Question,
- IN EFI_HII_VALUE *OptionValue
- );
-
-/**
- Compare two Hii value.
-
- @param Value1 Expression value to compare on left-hand.
- @param Value2 Expression value to compare on right-hand.
- @param Result Return value after compare.
- retval 0 Two operators equal.
- return Positive value if Value1 is greater than Value2.
- retval Negative value if Value1 is less than Value2.
- @param HiiHandle Only required for string compare.
-
- @retval other Could not perform compare on two values.
- @retval EFI_SUCCESS Compare the value success.
-
-**/
-EFI_STATUS
-CompareHiiValue (
- IN EFI_HII_VALUE *Value1,
- IN EFI_HII_VALUE *Value2,
- OUT INTN *Result,
- IN EFI_HII_HANDLE HiiHandle OPTIONAL
- );
-
-/**
- Draw a pop up windows based on the dimension, number of lines and
- strings specified.
-
- @param RequestedWidth The width of the pop-up.
- @param NumberOfLines The number of lines.
- @param ... A series of text strings that displayed in the pop-up.
-
-**/
-VOID
-EFIAPI
-CreateMultiStringPopUp (
- IN UINTN RequestedWidth,
- IN UINTN NumberOfLines,
- ...
- );
-
-/**
- Will copy LineWidth amount of a string in the OutputString buffer and return the
- number of CHAR16 characters that were copied into the OutputString buffer.
- The output string format is:
- Glyph Info + String info + '\0'.
-
- In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.
-
- @param InputString String description for this option.
- @param LineWidth Width of the desired string to extract in CHAR16
- characters
- @param GlyphWidth The glyph width of the begin of the char in the string.
- @param Index Where in InputString to start the copy process
- @param OutputString Buffer to copy the string into
-
- @return Returns the number of CHAR16 characters that were copied into the OutputString
- buffer, include extra glyph info and '\0' info.
-
-**/
-UINT16
-GetLineByWidth (
- IN CHAR16 *InputString,
- IN UINT16 LineWidth,
- IN OUT UINT16 *GlyphWidth,
- IN OUT UINTN *Index,
- OUT CHAR16 **OutputString
- );
-
-
-/**
- Get the string based on the StringId and HII Package List Handle.
-
- @param Token The String's ID.
- @param HiiHandle The Hii handle for this string package.
-
- @return The output string.
-
-**/
-CHAR16 *
-GetToken (
- IN EFI_STRING_ID Token,
- IN EFI_HII_HANDLE HiiHandle
- );
-
-/**
- Count the storage space of a Unicode string.
-
- This function handles the Unicode string with NARROW_CHAR
- and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
- does not count in the resultant output. If a WIDE_CHAR is
- hit, then 2 Unicode character will consume an output storage
- space with size of CHAR16 till a NARROW_CHAR is hit.
-
- If String is NULL, then ASSERT ().
-
- @param String The input string to be counted.
-
- @return Storage space for the input string.
-
-**/
-UINTN
-GetStringWidth (
- IN CHAR16 *String
- );
-
-/**
- This routine reads a numeric value from the user input.
-
- @param MenuOption Pointer to the current input menu.
-
- @retval EFI_SUCCESS If numerical input is read successfully
- @retval EFI_DEVICE_ERROR If operation fails
-
-**/
-EFI_STATUS
-GetNumericInput (
- IN UI_MENU_OPTION *MenuOption
- );
-
-/**
- Get string or password input from user.
-
- @param MenuOption Pointer to the current input menu.
- @param Prompt The prompt string shown on popup window.
- @param StringPtr Old user input and destination for use input string.
-
- @retval EFI_SUCCESS If string input is read successfully
- @retval EFI_DEVICE_ERROR If operation fails
-
-**/
-EFI_STATUS
-ReadString (
- IN UI_MENU_OPTION *MenuOption,
- IN CHAR16 *Prompt,
- IN OUT CHAR16 *StringPtr
- );
-
-/**
- Draw a pop up windows based on the dimension, number of lines and
- strings specified.
-
- @param RequestedWidth The width of the pop-up.
- @param NumberOfLines The number of lines.
- @param Marker The variable argument list for the list of string to be printed.
-
-**/
-VOID
-CreateSharedPopUp (
- IN UINTN RequestedWidth,
- IN UINTN NumberOfLines,
- IN VA_LIST Marker
- );
-
-/**
- Wait for a key to be pressed by user.
-
- @param Key The key which is pressed by user.
-
- @retval EFI_SUCCESS The function always completed successfully.
-
-**/
-EFI_STATUS
-WaitForKeyStroke (
- OUT EFI_INPUT_KEY *Key
- );
-
-/**
- Get selection for OneOf and OrderedList (Left/Right will be ignored).
-
- @param MenuOption Pointer to the current input menu.
-
- @retval EFI_SUCCESS If Option input is processed successfully
- @retval EFI_DEVICE_ERROR If operation fails
-
-**/
-EFI_STATUS
-GetSelectionInputPopUp (
- IN UI_MENU_OPTION *MenuOption
- );
-
-/**
- Process the help string: Split StringPtr to several lines of strings stored in
- FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.
-
- @param StringPtr The entire help string.
- @param FormattedString The oupput formatted string.
- @param EachLineWidth The max string length of each line in the formatted string.
- @param RowCount TRUE: if Question is selected.
-
-**/
-UINTN
-ProcessHelpString (
- IN CHAR16 *StringPtr,
- OUT CHAR16 **FormattedString,
- OUT UINT16 *EachLineWidth,
- IN UINTN RowCount
- );
-
-/**
- Process a Question's Option (whether selected or un-selected).
-
- @param MenuOption The MenuOption for this Question.
- @param Selected TRUE: if Question is selected.
- @param OptionString Pointer of the Option String to be displayed.
- @param SkipErrorValue Whether need to return when value without option for it.
-
- @retval EFI_SUCCESS Question Option process success.
- @retval Other Question Option process fail.
-
-**/
-EFI_STATUS
-ProcessOptions (
- IN UI_MENU_OPTION *MenuOption,
- IN BOOLEAN Selected,
- OUT CHAR16 **OptionString,
- IN BOOLEAN SkipErrorValue
- );
-
-/**
- Set Buffer to Value for Size bytes.
-
- @param Buffer Memory to set.
- @param Size Number of bytes to set
- @param Value Value of the set operation.
-
-**/
-VOID
-SetUnicodeMem (
- IN VOID *Buffer,
- IN UINTN Size,
- IN CHAR16 Value
- );
-
-/**
- Display one form, and return user input.
-
- @param FormData Form Data to be shown.
- @param UserInputData User input data.
-
- @retval EFI_SUCCESS Form Data is shown, and user input is got.
-**/
-EFI_STATUS
-EFIAPI
-FormDisplay (
- IN FORM_DISPLAY_ENGINE_FORM *FormData,
- OUT USER_INPUT *UserInputData
- );
-
-/**
- Clear Screen to the initial state.
-**/
-VOID
-EFIAPI
-DriverClearDisplayPage (
- VOID
- );
-
-/**
- Exit Display and Clear Screen to the original state.
-
-**/
-VOID
-EFIAPI
-ExitDisplay (
- VOID
- );
-
-/**
- Process validate for one question.
-
- @param Question The question which need to validate.
-
- @retval EFI_SUCCESS Question Option process success.
- @retval Other Question Option process fail.
-
-**/
-EFI_STATUS
-ValidateQuestion (
- IN FORM_DISPLAY_ENGINE_STATEMENT *Question
- );
-
-#endif
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c deleted file mode 100644 index aca043a8c2..0000000000 --- a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c +++ /dev/null @@ -1,1286 +0,0 @@ -/** @file
-Implementation for handling the User Interface option processing.
-
-
-Copyright (c) 2004 - 2012, 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"
-
-/**
- Concatenate a narrow string to another string.
-
- @param Destination The destination string.
- @param Source The source string. The string to be concatenated.
- to the end of Destination.
-
-**/
-VOID
-NewStrCat (
- IN OUT CHAR16 *Destination,
- IN CHAR16 *Source
- )
-{
- UINTN Length;
-
- for (Length = 0; Destination[Length] != 0; Length++)
- ;
-
- //
- // We now have the length of the original string
- // We can safely assume for now that we are concatenating a narrow value to this string.
- // For instance, the string is "XYZ" and cat'ing ">"
- // If this assumption changes, we need to make this routine a bit more complex
- //
- Destination[Length] = NARROW_CHAR;
- Length++;
-
- StrCpy (Destination + Length, Source);
-}
-
-/**
- Compare two Hii value.
-
- @param Value1 Expression value to compare on left-hand.
- @param Value2 Expression value to compare on right-hand.
- @param Result Return value after compare.
- retval 0 Two operators equal.
- return Positive value if Value1 is greater than Value2.
- retval Negative value if Value1 is less than Value2.
- @param HiiHandle Only required for string compare.
-
- @retval other Could not perform compare on two values.
- @retval EFI_SUCCESS Compare the value success.
-
-**/
-EFI_STATUS
-CompareHiiValue (
- IN EFI_HII_VALUE *Value1,
- IN EFI_HII_VALUE *Value2,
- OUT INTN *Result,
- IN EFI_HII_HANDLE HiiHandle OPTIONAL
- )
-{
- INT64 Temp64;
- CHAR16 *Str1;
- CHAR16 *Str2;
- UINTN Len;
-
- if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {
- if (Value1->Type != EFI_IFR_TYPE_BUFFER && Value2->Type != EFI_IFR_TYPE_BUFFER) {
- return EFI_UNSUPPORTED;
- }
- }
-
- if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {
- if (Value1->Type != Value2->Type) {
- //
- // Both Operator should be type of String
- //
- return EFI_UNSUPPORTED;
- }
-
- if (Value1->Value.string == 0 || Value2->Value.string == 0) {
- //
- // StringId 0 is reserved
- //
- return EFI_INVALID_PARAMETER;
- }
-
- if (Value1->Value.string == Value2->Value.string) {
- *Result = 0;
- return EFI_SUCCESS;
- }
-
- Str1 = GetToken (Value1->Value.string, HiiHandle);
- if (Str1 == NULL) {
- //
- // String not found
- //
- return EFI_NOT_FOUND;
- }
-
- Str2 = GetToken (Value2->Value.string, HiiHandle);
- if (Str2 == NULL) {
- FreePool (Str1);
- return EFI_NOT_FOUND;
- }
-
- *Result = StrCmp (Str1, Str2);
-
- FreePool (Str1);
- FreePool (Str2);
-
- return EFI_SUCCESS;
- }
-
- if (Value1->Type == EFI_IFR_TYPE_BUFFER || Value2->Type == EFI_IFR_TYPE_BUFFER ) {
- if (Value1->Type != Value2->Type) {
- //
- // Both Operator should be type of Buffer.
- //
- return EFI_UNSUPPORTED;
- }
- Len = Value1->BufferLen > Value2->BufferLen ? Value2->BufferLen : Value1->BufferLen;
- *Result = CompareMem (Value1->Buffer, Value2->Buffer, Len);
- if ((*Result == 0) && (Value1->BufferLen != Value2->BufferLen))
- {
- //
- // In this case, means base on samll number buffer, the data is same
- // So which value has more data, which value is bigger.
- //
- *Result = Value1->BufferLen > Value2->BufferLen ? 1 : -1;
- }
- return EFI_SUCCESS;
- }
-
- //
- // Take remain types(integer, boolean, date/time) as integer
- //
- Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);
- if (Temp64 > 0) {
- *Result = 1;
- } else if (Temp64 < 0) {
- *Result = -1;
- } else {
- *Result = 0;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Search an Option of a Question by its value.
-
- @param Question The Question
- @param OptionValue Value for Option to be searched.
-
- @retval Pointer Pointer to the found Option.
- @retval NULL Option not found.
-
-**/
-DISPLAY_QUESTION_OPTION *
-ValueToOption (
- IN FORM_DISPLAY_ENGINE_STATEMENT *Question,
- IN EFI_HII_VALUE *OptionValue
- )
-{
- LIST_ENTRY *Link;
- DISPLAY_QUESTION_OPTION *Option;
- INTN Result;
- EFI_HII_VALUE Value;
-
- Link = GetFirstNode (&Question->OptionListHead);
- while (!IsNull (&Question->OptionListHead, Link)) {
- Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
-
- ZeroMem (&Value, sizeof (EFI_HII_VALUE));
- Value.Type = Option->OptionOpCode->Type;
- CopyMem (&Value.Value, &Option->OptionOpCode->Value, Option->OptionOpCode->Header.Length - OFFSET_OF (EFI_IFR_ONE_OF_OPTION, Value));
-
- if ((CompareHiiValue (&Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
- return Option;
- }
-
- Link = GetNextNode (&Question->OptionListHead, Link);
- }
-
- return NULL;
-}
-
-
-/**
- Return data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
-
- @retval Value The data to be returned
-
-**/
-UINT64
-GetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index
- )
-{
- UINT64 Data;
-
- ASSERT (Array != NULL);
-
- Data = 0;
- switch (Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data = (UINT64) *(((UINT8 *) Array) + Index);
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data = (UINT64) *(((UINT16 *) Array) + Index);
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data = (UINT64) *(((UINT32 *) Array) + Index);
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data = (UINT64) *(((UINT64 *) Array) + Index);
- break;
-
- default:
- break;
- }
-
- return Data;
-}
-
-
-/**
- Set value of a data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
- @param Value The value to be set.
-
-**/
-VOID
-SetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index,
- IN UINT64 Value
- )
-{
-
- ASSERT (Array != NULL);
-
- switch (Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- *(((UINT8 *) Array) + Index) = (UINT8) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_16:
- *(((UINT16 *) Array) + Index) = (UINT16) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_32:
- *(((UINT32 *) Array) + Index) = (UINT32) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_64:
- *(((UINT64 *) Array) + Index) = (UINT64) Value;
- break;
-
- default:
- break;
- }
-}
-
-/**
- Check whether this value already in the array, if yes, return the index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Value The value to be find.
- @param Index The index in the array which has same value with Value.
-
- @retval TRUE Found the value in the array.
- @retval FALSE Not found the value.
-
-**/
-BOOLEAN
-FindArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINT64 Value,
- OUT UINTN *Index OPTIONAL
- )
-{
- UINTN Count;
- UINT64 TmpValue;
- UINT64 ValueComp;
-
- ASSERT (Array != NULL);
-
- Count = 0;
- TmpValue = 0;
-
- switch (Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- ValueComp = (UINT8) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_16:
- ValueComp = (UINT16) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_32:
- ValueComp = (UINT32) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_64:
- ValueComp = (UINT64) Value;
- break;
-
- default:
- ValueComp = 0;
- break;
- }
-
- while ((TmpValue = GetArrayData (Array, Type, Count)) != 0) {
- if (ValueComp == TmpValue) {
- if (Index != NULL) {
- *Index = Count;
- }
- return TRUE;
- }
-
- Count ++;
- }
-
- return FALSE;
-}
-
-/**
- Print Question Value according to it's storage width and display attributes.
-
- @param Question The Question to be printed.
- @param FormattedNumber Buffer for output string.
- @param BufferSize The FormattedNumber buffer size in bytes.
-
- @retval EFI_SUCCESS Print success.
- @retval EFI_BUFFER_TOO_SMALL Buffer size is not enough for formatted number.
-
-**/
-EFI_STATUS
-PrintFormattedNumber (
- IN FORM_DISPLAY_ENGINE_STATEMENT *Question,
- IN OUT CHAR16 *FormattedNumber,
- IN UINTN BufferSize
- )
-{
- INT64 Value;
- CHAR16 *Format;
- EFI_HII_VALUE *QuestionValue;
- EFI_IFR_NUMERIC *NumericOp;
-
- if (BufferSize < (21 * sizeof (CHAR16))) {
- return EFI_BUFFER_TOO_SMALL;
- }
-
- QuestionValue = &Question->CurrentValue;
- NumericOp = (EFI_IFR_NUMERIC *) Question->OpCode;
-
- Value = (INT64) QuestionValue->Value.u64;
- switch (NumericOp->Flags & EFI_IFR_DISPLAY) {
- case EFI_IFR_DISPLAY_INT_DEC:
- switch (QuestionValue->Type) {
- case EFI_IFR_NUMERIC_SIZE_1:
- Value = (INT64) ((INT8) QuestionValue->Value.u8);
- break;
-
- case EFI_IFR_NUMERIC_SIZE_2:
- Value = (INT64) ((INT16) QuestionValue->Value.u16);
- break;
-
- case EFI_IFR_NUMERIC_SIZE_4:
- Value = (INT64) ((INT32) QuestionValue->Value.u32);
- break;
-
- case EFI_IFR_NUMERIC_SIZE_8:
- default:
- break;
- }
-
- if (Value < 0) {
- Value = -Value;
- Format = L"-%ld";
- } else {
- Format = L"%ld";
- }
- break;
-
- case EFI_IFR_DISPLAY_UINT_DEC:
- Format = L"%ld";
- break;
-
- case EFI_IFR_DISPLAY_UINT_HEX:
- Format = L"%lx";
- break;
-
- default:
- return EFI_UNSUPPORTED;
- break;
- }
-
- UnicodeSPrint (FormattedNumber, BufferSize, Format, Value);
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Draw a pop up windows based on the dimension, number of lines and
- strings specified.
-
- @param RequestedWidth The width of the pop-up.
- @param NumberOfLines The number of lines.
- @param Marker The variable argument list for the list of string to be printed.
-
-**/
-VOID
-CreateSharedPopUp (
- IN UINTN RequestedWidth,
- IN UINTN NumberOfLines,
- IN VA_LIST Marker
- )
-{
- UINTN Index;
- UINTN Count;
- CHAR16 Character;
- UINTN Start;
- UINTN End;
- UINTN Top;
- UINTN Bottom;
- CHAR16 *String;
- UINTN DimensionsWidth;
- UINTN DimensionsHeight;
-
- DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;
- DimensionsHeight = gStatementDimensions.BottomRow - gStatementDimensions.TopRow;
-
- gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
-
- if ((RequestedWidth + 2) > DimensionsWidth) {
- RequestedWidth = DimensionsWidth - 2;
- }
-
- //
- // Subtract the PopUp width from total Columns, allow for one space extra on
- // each end plus a border.
- //
- Start = (DimensionsWidth - RequestedWidth - 2) / 2 + gStatementDimensions.LeftColumn + 1;
- End = Start + RequestedWidth + 1;
-
- Top = ((DimensionsHeight - NumberOfLines - 2) / 2) + gStatementDimensions.TopRow - 1;
- Bottom = Top + NumberOfLines + 2;
-
- Character = BOXDRAW_DOWN_RIGHT;
- PrintCharAt (Start, Top, Character);
- Character = BOXDRAW_HORIZONTAL;
- for (Index = Start; Index + 2 < End; Index++) {
- PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
- }
-
- Character = BOXDRAW_DOWN_LEFT;
- PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
- Character = BOXDRAW_VERTICAL;
-
- Count = 0;
- for (Index = Top; Index + 2 < Bottom; Index++, Count++) {
- String = VA_ARG (Marker, CHAR16*);
-
- //
- // This will clear the background of the line - we never know who might have been
- // here before us. This differs from the next clear in that it used the non-reverse
- // video for normal printing.
- //
- if (GetStringWidth (String) / 2 > 1) {
- ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());
- }
-
- //
- // Passing in a space results in the assumption that this is where typing will occur
- //
- if (String[0] == L' ') {
- ClearLines (Start + 1, End - 1, Index + 1, Index + 1, GetPopupInverseColor ());
- }
-
- //
- // Passing in a NULL results in a blank space
- //
- if (String[0] == CHAR_NULL) {
- ClearLines (Start, End, Index + 1, Index + 1, GetPopupColor ());
- }
-
- PrintStringAt (
- ((DimensionsWidth - GetStringWidth (String) / 2) / 2) + gStatementDimensions.LeftColumn + 1,
- Index + 1,
- String
- );
- gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
- PrintCharAt (Start, Index + 1, Character);
- PrintCharAt (End - 1, Index + 1, Character);
- }
-
- Character = BOXDRAW_UP_RIGHT;
- PrintCharAt (Start, Bottom - 1, Character);
- Character = BOXDRAW_HORIZONTAL;
- for (Index = Start; Index + 2 < End; Index++) {
- PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
- }
-
- Character = BOXDRAW_UP_LEFT;
- PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
-}
-
-/**
- Draw a pop up windows based on the dimension, number of lines and
- strings specified.
-
- @param RequestedWidth The width of the pop-up.
- @param NumberOfLines The number of lines.
- @param ... A series of text strings that displayed in the pop-up.
-
-**/
-VOID
-EFIAPI
-CreateMultiStringPopUp (
- IN UINTN RequestedWidth,
- IN UINTN NumberOfLines,
- ...
- )
-{
- VA_LIST Marker;
-
- VA_START (Marker, NumberOfLines);
-
- CreateSharedPopUp (RequestedWidth, NumberOfLines, Marker);
-
- VA_END (Marker);
-}
-
-/**
- Process validate for one question.
-
- @param Question The question need to be validate.
-
- @retval EFI_SUCCESS Question Option process success.
- @retval EFI_INVALID_PARAMETER Question Option process fail.
-
-**/
-EFI_STATUS
-ValidateQuestion (
- IN FORM_DISPLAY_ENGINE_STATEMENT *Question
- )
-{
- CHAR16 *ErrorInfo;
- EFI_INPUT_KEY Key;
- EFI_STATUS Status;
- STATEMENT_ERROR_INFO RetInfo;
- UINT32 RetVal;
-
- if (Question->ValidateQuestion == NULL) {
- return EFI_SUCCESS;
- }
-
- Status = EFI_SUCCESS;
- RetVal = Question->ValidateQuestion(gFormData, Question, &gUserInput->InputValue, &RetInfo);
-
- switch (RetVal) {
- case INCOSISTENT_IF_TRUE:
- //
- // Condition meet, show up error message
- //
- ASSERT (RetInfo.StringId != 0);
- ErrorInfo = GetToken (RetInfo.StringId, gFormData->HiiHandle);
- do {
- CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- FreePool (ErrorInfo);
-
- Status = EFI_INVALID_PARAMETER;
- break;
-
- default:
- break;
- }
-
- return Status;
-}
-
-/**
- Display error message for invalid password.
-
-**/
-VOID
-PasswordInvalid (
- VOID
- )
-{
- EFI_INPUT_KEY Key;
-
- //
- // Invalid password, prompt error message
- //
- do {
- CreateDialog (&Key, gEmptyString, gPassowordInvalid, gPressEnter, gEmptyString, NULL);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-}
-
-/**
- Process password op code.
-
- @param MenuOption The menu for current password op code.
-
- @retval EFI_SUCCESS Question Option process success.
- @retval Other Question Option process fail.
-
-**/
-EFI_STATUS
-PasswordProcess (
- IN UI_MENU_OPTION *MenuOption
- )
-{
- CHAR16 *StringPtr;
- CHAR16 *TempString;
- UINTN Maximum;
- EFI_STATUS Status;
- EFI_IFR_PASSWORD *PasswordInfo;
- FORM_DISPLAY_ENGINE_STATEMENT *Question;
- EFI_INPUT_KEY Key;
-
- Question = MenuOption->ThisTag;
- PasswordInfo = (EFI_IFR_PASSWORD *) Question->OpCode;
- Maximum = PasswordInfo->MaxSize;
- Status = EFI_SUCCESS;
-
- StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
- ASSERT (StringPtr);
-
- //
- // Use a NULL password to test whether old password is required
- //
- *StringPtr = 0;
- Status = Question->PasswordCheck (gFormData, Question, StringPtr);
- if (Status == EFI_NOT_AVAILABLE_YET || Status == EFI_UNSUPPORTED) {
- //
- // Password can't be set now.
- //
- FreePool (StringPtr);
- return EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- //
- // Old password exist, ask user for the old password
- //
- Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
- if (EFI_ERROR (Status)) {
- FreePool (StringPtr);
- return Status;
- }
-
- //
- // Check user input old password
- //
- Status = Question->PasswordCheck (gFormData, Question, StringPtr);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_NOT_READY) {
- //
- // Typed in old password incorrect
- //
- PasswordInvalid ();
- } else {
- Status = EFI_SUCCESS;
- }
-
- FreePool (StringPtr);
- return Status;
- }
- }
-
- //
- // Ask for new password
- //
- ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
- Status = ReadString (MenuOption, gPromptForNewPassword, StringPtr);
- if (EFI_ERROR (Status)) {
- //
- // Reset state machine for password
- //
- Question->PasswordCheck (gFormData, Question, NULL);
- FreePool (StringPtr);
- return Status;
- }
-
- //
- // Confirm new password
- //
- TempString = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
- ASSERT (TempString);
- Status = ReadString (MenuOption, gConfirmPassword, TempString);
- if (EFI_ERROR (Status)) {
- //
- // Reset state machine for password
- //
- Question->PasswordCheck (gFormData, Question, NULL);
- FreePool (StringPtr);
- FreePool (TempString);
- return Status;
- }
-
- //
- // Compare two typed-in new passwords
- //
- if (StrCmp (StringPtr, TempString) == 0) {
- gUserInput->InputValue.Buffer = AllocateCopyPool (Question->CurrentValue.BufferLen, StringPtr);
- gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
- gUserInput->InputValue.Type = Question->CurrentValue.Type;
- gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL);
- FreePool (StringPtr);
-
- Status = ValidateQuestion (Question);
-
- if (EFI_ERROR (Status)) {
- //
- // Reset state machine for password
- //
- Question->PasswordCheck (gFormData, Question, NULL);
- }
-
- return Status;
- } else {
- //
- // Reset state machine for password
- //
- Question->PasswordCheck (gFormData, Question, NULL);
-
- //
- // Two password mismatch, prompt error message
- //
- do {
- CreateDialog (&Key, gEmptyString, gConfirmError, gPressEnter, gEmptyString, NULL);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-
- Status = EFI_INVALID_PARAMETER;
- }
-
- FreePool (TempString);
- FreePool (StringPtr);
-
- return Status;
-}
-
-/**
- Process a Question's Option (whether selected or un-selected).
-
- @param MenuOption The MenuOption for this Question.
- @param Selected TRUE: if Question is selected.
- @param OptionString Pointer of the Option String to be displayed.
- @param SkipErrorValue Whether need to return when value without option for it.
-
- @retval EFI_SUCCESS Question Option process success.
- @retval Other Question Option process fail.
-
-**/
-EFI_STATUS
-ProcessOptions (
- IN UI_MENU_OPTION *MenuOption,
- IN BOOLEAN Selected,
- OUT CHAR16 **OptionString,
- IN BOOLEAN SkipErrorValue
- )
-{
- EFI_STATUS Status;
- CHAR16 *StringPtr;
- UINTN Index;
- FORM_DISPLAY_ENGINE_STATEMENT *Question;
- CHAR16 FormattedNumber[21];
- UINT16 Number;
- CHAR16 Character[2];
- EFI_INPUT_KEY Key;
- UINTN BufferSize;
- DISPLAY_QUESTION_OPTION *OneOfOption;
- LIST_ENTRY *Link;
- EFI_HII_VALUE HiiValue;
- EFI_HII_VALUE *QuestionValue;
- DISPLAY_QUESTION_OPTION *Option;
- UINTN Index2;
- UINT8 *ValueArray;
- UINT8 ValueType;
- EFI_STRING_ID StringId;
- EFI_IFR_ORDERED_LIST *OrderList;
- BOOLEAN ValueInvalid;
-
- Status = EFI_SUCCESS;
-
- StringPtr = NULL;
- Character[1] = L'\0';
- *OptionString = NULL;
- StringId = 0;
- ValueInvalid = FALSE;
-
- ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
- BufferSize = (gOptionBlockWidth + 1) * 2 * gStatementDimensions.BottomRow;
-
- Question = MenuOption->ThisTag;
- QuestionValue = &Question->CurrentValue;
-
- switch (Question->OpCode->OpCode) {
- case EFI_IFR_ORDERED_LIST_OP:
-
- //
- // Check whether there are Options of this OrderedList
- //
- if (IsListEmpty (&Question->OptionListHead)) {
- break;
- }
-
- OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode;
-
- Link = GetFirstNode (&Question->OptionListHead);
- OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
-
- ValueType = OneOfOption->OptionOpCode->Type;
- ValueArray = Question->CurrentValue.Buffer;
-
- if (Selected) {
- //
- // Go ask for input
- //
- Status = GetSelectionInputPopUp (MenuOption);
- } else {
- //
- // We now know how many strings we will have, so we can allocate the
- // space required for the array or strings.
- //
- *OptionString = AllocateZeroPool (OrderList->MaxContainers * BufferSize);
- ASSERT (*OptionString);
-
- HiiValue.Type = ValueType;
- HiiValue.Value.u64 = 0;
- for (Index = 0; Index < OrderList->MaxContainers; Index++) {
- HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
- if (HiiValue.Value.u64 == 0) {
- //
- // Values for the options in ordered lists should never be a 0
- //
- break;
- }
-
- OneOfOption = ValueToOption (Question, &HiiValue);
- if (OneOfOption == NULL) {
- if (SkipErrorValue) {
- //
- // Just try to get the option string, skip the value which not has option.
- //
- continue;
- }
-
- //
- // Show error message
- //
- do {
- CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-
- //
- // The initial value of the orderedlist is invalid, force to be valid value
- // Exit current DisplayForm with new value.
- //
- gUserInput->SelectedStatement = Question;
-
- ValueArray = AllocateZeroPool (Question->CurrentValue.BufferLen);
- ASSERT (ValueArray != NULL);
- gUserInput->InputValue.Buffer = ValueArray;
- gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
- gUserInput->InputValue.Type = Question->CurrentValue.Type;
-
- Link = GetFirstNode (&Question->OptionListHead);
- Index2 = 0;
- while (!IsNull (&Question->OptionListHead, Link) && Index2 < OrderList->MaxContainers) {
- Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
- Link = GetNextNode (&Question->OptionListHead, Link);
- SetArrayData (ValueArray, ValueType, Index2, Option->OptionOpCode->Value.u64);
- Index2++;
- }
- SetArrayData (ValueArray, ValueType, Index2, 0);
-
- FreePool (*OptionString);
- *OptionString = NULL;
- return EFI_NOT_FOUND;
- }
-
- Character[0] = LEFT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
- StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
- ASSERT (StringPtr != NULL);
- NewStrCat (OptionString[0], StringPtr);
- Character[0] = RIGHT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
- Character[0] = CHAR_CARRIAGE_RETURN;
- NewStrCat (OptionString[0], Character);
- FreePool (StringPtr);
- }
-
- //
- // If valid option more than the max container, skip these options.
- //
- if (Index >= OrderList->MaxContainers) {
- break;
- }
-
- //
- // Search the other options, try to find the one not in the container.
- //
- Link = GetFirstNode (&Question->OptionListHead);
- while (!IsNull (&Question->OptionListHead, Link)) {
- OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
- Link = GetNextNode (&Question->OptionListHead, Link);
-
- if (FindArrayData (ValueArray, ValueType, OneOfOption->OptionOpCode->Value.u64, NULL)) {
- continue;
- }
-
- if (SkipErrorValue) {
- //
- // Not report error, just get the correct option string info.
- //
- Character[0] = LEFT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
- StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
- ASSERT (StringPtr != NULL);
- NewStrCat (OptionString[0], StringPtr);
- Character[0] = RIGHT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
- Character[0] = CHAR_CARRIAGE_RETURN;
- NewStrCat (OptionString[0], Character);
- FreePool (StringPtr);
-
- continue;
- }
-
- if (!ValueInvalid) {
- ValueInvalid = TRUE;
- //
- // Show error message
- //
- do {
- CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-
- //
- // The initial value of the orderedlist is invalid, force to be valid value
- // Exit current DisplayForm with new value.
- //
- gUserInput->SelectedStatement = Question;
-
- ValueArray = AllocateCopyPool (Question->CurrentValue.BufferLen, Question->CurrentValue.Buffer);
- ASSERT (ValueArray != NULL);
- gUserInput->InputValue.Buffer = ValueArray;
- gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
- gUserInput->InputValue.Type = Question->CurrentValue.Type;
- }
-
- SetArrayData (ValueArray, ValueType, Index++, OneOfOption->OptionOpCode->Value.u64);
- }
-
- if (ValueInvalid) {
- FreePool (*OptionString);
- *OptionString = NULL;
- return EFI_NOT_FOUND;
- }
- }
- break;
-
- case EFI_IFR_ONE_OF_OP:
- //
- // Check whether there are Options of this OneOf
- //
- if (IsListEmpty (&Question->OptionListHead)) {
- break;
- }
- if (Selected) {
- //
- // Go ask for input
- //
- Status = GetSelectionInputPopUp (MenuOption);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- OneOfOption = ValueToOption (Question, QuestionValue);
- if (OneOfOption == NULL) {
- if (SkipErrorValue) {
- //
- // Not report error, just get the correct option string info.
- //
- Link = GetFirstNode (&Question->OptionListHead);
- OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
- } else {
- //
- // Show error message
- //
- do {
- CreateDialog (&Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString, NULL);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-
- //
- // Force the Question value to be valid
- // Exit current DisplayForm with new value.
- //
- Link = GetFirstNode (&Question->OptionListHead);
- Option = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
-
- CopyMem (&gUserInput->InputValue.Value, &Option->OptionOpCode->Value, sizeof (EFI_IFR_TYPE_VALUE));
- gUserInput->InputValue.Type = Option->OptionOpCode->Type;
- gUserInput->SelectedStatement = Question;
-
- FreePool (*OptionString);
- *OptionString = NULL;
- return EFI_NOT_FOUND;
- }
- }
-
- Character[0] = LEFT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
- StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
- ASSERT (StringPtr != NULL);
- NewStrCat (OptionString[0], StringPtr);
- Character[0] = RIGHT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
-
- FreePool (StringPtr);
- }
- break;
-
- case EFI_IFR_CHECKBOX_OP:
- if (Selected) {
- //
- // Since this is a BOOLEAN operation, flip it upon selection
- //
- gUserInput->InputValue.Type = QuestionValue->Type;
- gUserInput->InputValue.Value.b = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);
-
- //
- // Perform inconsistent check
- //
- return ValidateQuestion (Question);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- *OptionString[0] = LEFT_CHECKBOX_DELIMITER;
-
- if (QuestionValue->Value.b) {
- *(OptionString[0] + 1) = CHECK_ON;
- } else {
- *(OptionString[0] + 1) = CHECK_OFF;
- }
- *(OptionString[0] + 2) = RIGHT_CHECKBOX_DELIMITER;
- }
- break;
-
- case EFI_IFR_NUMERIC_OP:
- if (Selected) {
- //
- // Go ask for input
- //
- Status = GetNumericInput (MenuOption);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- *OptionString[0] = LEFT_NUMERIC_DELIMITER;
-
- //
- // Formatted print
- //
- PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
- Number = (UINT16) GetStringWidth (FormattedNumber);
- CopyMem (OptionString[0] + 1, FormattedNumber, Number);
-
- *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER;
- }
- break;
-
- case EFI_IFR_DATE_OP:
- if (Selected) {
- //
- // This is similar to numerics
- //
- Status = GetNumericInput (MenuOption);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- switch (MenuOption->Sequence) {
- case 0:
- *OptionString[0] = LEFT_NUMERIC_DELIMITER;
- UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Month);
- *(OptionString[0] + 3) = DATE_SEPARATOR;
- break;
-
- case 1:
- SetUnicodeMem (OptionString[0], 4, L' ');
- UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Day);
- *(OptionString[0] + 6) = DATE_SEPARATOR;
- break;
-
- case 2:
- SetUnicodeMem (OptionString[0], 7, L' ');
- UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", QuestionValue->Value.date.Year);
- *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER;
- break;
- }
- }
- break;
-
- case EFI_IFR_TIME_OP:
- if (Selected) {
- //
- // This is similar to numerics
- //
- Status = GetNumericInput (MenuOption);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- switch (MenuOption->Sequence) {
- case 0:
- *OptionString[0] = LEFT_NUMERIC_DELIMITER;
- UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Hour);
- *(OptionString[0] + 3) = TIME_SEPARATOR;
- break;
-
- case 1:
- SetUnicodeMem (OptionString[0], 4, L' ');
- UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Minute);
- *(OptionString[0] + 6) = TIME_SEPARATOR;
- break;
-
- case 2:
- SetUnicodeMem (OptionString[0], 7, L' ');
- UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Second);
- *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER;
- break;
- }
- }
- break;
-
- case EFI_IFR_STRING_OP:
- if (Selected) {
- StringPtr = AllocateZeroPool (Question->CurrentValue.BufferLen + sizeof (CHAR16));
- ASSERT (StringPtr);
- CopyMem(StringPtr, Question->CurrentValue.Buffer, Question->CurrentValue.BufferLen);
-
- Status = ReadString (MenuOption, gPromptForData, StringPtr);
- if (EFI_ERROR (Status)) {
- FreePool (StringPtr);
- return Status;
- }
-
- gUserInput->InputValue.Buffer = AllocateCopyPool (Question->CurrentValue.BufferLen, StringPtr);
- gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
- gUserInput->InputValue.Type = Question->CurrentValue.Type;
- gUserInput->InputValue.Value.string = HiiSetString(gFormData->HiiHandle, gUserInput->InputValue.Value.string, StringPtr, NULL);
- FreePool (StringPtr);
- return ValidateQuestion (Question);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- if (((CHAR16 *) Question->CurrentValue.Buffer)[0] == 0x0000) {
- *(OptionString[0]) = '_';
- } else {
- if (Question->CurrentValue.BufferLen < BufferSize) {
- BufferSize = Question->CurrentValue.BufferLen;
- }
- CopyMem (OptionString[0], (CHAR16 *) Question->CurrentValue.Buffer, BufferSize);
- }
- }
- break;
-
- case EFI_IFR_PASSWORD_OP:
- if (Selected) {
- Status = PasswordProcess (MenuOption);
- }
- break;
-
- default:
- break;
- }
-
- return Status;
-}
-
-
-/**
- Process the help string: Split StringPtr to several lines of strings stored in
- FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.
-
- @param StringPtr The entire help string.
- @param FormattedString The oupput formatted string.
- @param EachLineWidth The max string length of each line in the formatted string.
- @param RowCount TRUE: if Question is selected.
-
-**/
-UINTN
-ProcessHelpString (
- IN CHAR16 *StringPtr,
- OUT CHAR16 **FormattedString,
- OUT UINT16 *EachLineWidth,
- IN UINTN RowCount
- )
-{
- UINTN Index;
- CHAR16 *OutputString;
- UINTN TotalRowNum;
- UINTN CheckedNum;
- UINT16 GlyphWidth;
- UINT16 LineWidth;
- UINT16 MaxStringLen;
- UINT16 StringLen;
-
- TotalRowNum = 0;
- CheckedNum = 0;
- GlyphWidth = 1;
- Index = 0;
- MaxStringLen = 0;
- StringLen = 0;
-
- //
- // Set default help string width.
- //
- LineWidth = (UINT16) (gHelpBlockWidth - 1);
-
- //
- // Get row number of the String.
- //
- while ((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {
- if (StringLen > MaxStringLen) {
- MaxStringLen = StringLen;
- }
-
- TotalRowNum ++;
- FreePool (OutputString);
- }
- *EachLineWidth = MaxStringLen;
-
- *FormattedString = AllocateZeroPool (TotalRowNum * MaxStringLen * sizeof (CHAR16));
- ASSERT (*FormattedString != NULL);
-
- //
- // Generate formatted help string array.
- //
- GlyphWidth = 1;
- Index = 0;
- while((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {
- CopyMem (*FormattedString + CheckedNum * MaxStringLen, OutputString, StringLen * sizeof (CHAR16));
- CheckedNum ++;
- FreePool (OutputString);
- }
-
- return TotalRowNum;
-}
diff --git a/MdeModulePkg/Library/CustomizedDisplayLib/Colors.h b/MdeModulePkg/Universal/SetupBrowserDxe/Colors.h index 2db8b99614..2db8b99614 100644 --- a/MdeModulePkg/Library/CustomizedDisplayLib/Colors.h +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Colors.h diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c index 44dae1ba03..cd29e29438 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c @@ -787,7 +787,7 @@ FORM_BROWSER_FORM * IdToForm (
IN FORM_BROWSER_FORMSET *FormSet,
IN UINT16 FormId
- )
+)
{
LIST_ENTRY *Link;
FORM_BROWSER_FORM *Form;
@@ -2105,7 +2105,7 @@ GetQuestionValueFromForm ( //
FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
ASSERT (FormSet != NULL);
- Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet);
+ Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet, FALSE);
if (EFI_ERROR (Status)) {
GetTheVal = FALSE;
goto Done;
@@ -2800,7 +2800,7 @@ EvaluateExpression ( for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) {
StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2);
}
- Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer, NULL);
+ Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer);
FreePool (NameValue);
if (!EFI_ERROR (Status)) {
Data1.Value.b = TRUE;
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.h b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.h deleted file mode 100644 index 5660a997b8..0000000000 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.h +++ /dev/null @@ -1,265 +0,0 @@ -/** @file
-Private structure, MACRO and function definitions for User Interface related functionalities.
-
-Copyright (c) 2004 - 2013, 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.
-
-**/
-
-#ifndef _EXPRESSION_H_
-#define _EXPRESSION_H_
-
-/**
- Get the expression list count.
-
- @param Level Which type this expression belong to. Form,
- statement or option?
-
- @retval >=0 The expression count
- @retval -1 Input parameter error.
-
-**/
-INTN
-GetConditionalExpressionCount (
- IN EXPRESS_LEVEL Level
- );
-
-/**
- Reset stack pointer to begin of the stack.
-
-**/
-VOID
-ResetCurrentExpressionStack (
- VOID
- );
-
-/**
- Reset stack pointer to begin of the stack.
-
-**/
-VOID
-ResetMapExpressionListStack (
- VOID
- );
-
-/**
- Reset stack pointer to begin of the stack.
-
-**/
-VOID
-ResetScopeStack (
- VOID
- );
-
-/**
- Push an Operand onto the Stack
-
- @param Operand Operand to push.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
- stack.
-
-**/
-EFI_STATUS
-PushScope (
- IN UINT8 Operand
- );
-
-/**
- Get the expression Buffer pointer.
-
- @param Level Which type this expression belong to. Form,
- statement or option?
-
- @retval The start pointer of the expression buffer or NULL.
-
-**/
-FORM_EXPRESSION **
-GetConditionalExpressionList (
- IN EXPRESS_LEVEL Level
- );
-
-/**
- Pop an Operand from the Stack
-
- @param Operand Operand to pop.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
- stack.
-
-**/
-EFI_STATUS
-PopScope (
- OUT UINT8 *Operand
- );
-
-/**
- Push the list of map expression onto the Stack
-
- @param Pointer Pointer to the list of map expression to be pushed.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PushMapExpressionList (
- IN VOID *Pointer
- );
-
-/**
- Push current expression onto the Stack
-
- @param Pointer Pointer to current expression.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PushCurrentExpression (
- IN VOID *Pointer
- );
-
-/**
- Zero extend integer/boolean/date/time to UINT64 for comparing.
-
- @param Value HII Value to be converted.
-
-**/
-VOID
-ExtendValueToU64 (
- IN EFI_HII_VALUE *Value
- );
-
-/**
- Push the expression options onto the Stack.
-
- @param Pointer Pointer to the current expression.
- @param Level Which type this expression belong to. Form,
- statement or option?
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PushConditionalExpression (
- IN FORM_EXPRESSION *Pointer,
- IN EXPRESS_LEVEL Level
- );
-
-/**
- Pop the expression options from the Stack
-
- @param Level Which type this expression belong to. Form,
- statement or option?
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PopConditionalExpression (
- IN EXPRESS_LEVEL Level
- );
-
-/**
- Pop the list of map expression from the Stack
-
- @param Pointer Pointer to the list of map expression to be pop.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PopMapExpressionList (
- OUT VOID **Pointer
- );
-
-/**
- Pop current expression from the Stack
-
- @param Pointer Pointer to current expression to be pop.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PopCurrentExpression (
- OUT VOID **Pointer
- );
-
-/**
- Evaluate the result of a HII expression.
-
- If Expression is NULL, then ASSERT.
-
- @param FormSet FormSet associated with this expression.
- @param Form Form associated with this expression.
- @param Expression Expression to be evaluated.
-
- @retval EFI_SUCCESS The expression evaluated successfuly
- @retval EFI_NOT_FOUND The Question which referenced by a QuestionId
- could not be found.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
- stack.
- @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
- @retval EFI_INVALID_PARAMETER Syntax error with the Expression
-
-**/
-EFI_STATUS
-EvaluateExpression (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN FORM_BROWSER_FORM *Form,
- IN OUT FORM_EXPRESSION *Expression
- );
-/**
- Return the result of the expression list. Check the expression list and
- return the highest priority express result.
- Priority: DisableIf > SuppressIf > GrayOutIf > FALSE
-
- @param ExpList The input expression list.
- @param Evaluate Whether need to evaluate the expression first.
- @param FormSet FormSet associated with this expression.
- @param Form Form associated with this expression.
-
- @retval EXPRESS_RESULT Return the higher priority express result.
- DisableIf > SuppressIf > GrayOutIf > FALSE
-
-**/
-EXPRESS_RESULT
-EvaluateExpressionList (
- IN FORM_EXPRESSION_LIST *ExpList,
- IN BOOLEAN Evaluate,
- IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL
- IN FORM_BROWSER_FORM *Form OPTIONAL
- );
-
-/**
- Get Form given its FormId.
-
- @param FormSet The formset which contains this form.
- @param FormId Id of this form.
-
- @retval Pointer The form.
- @retval NULL Specified Form is not found in the formset.
-
-**/
-FORM_BROWSER_FORM *
-IdToForm (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN UINT16 FormId
- );
-
-#endif // _EXPRESSION_H
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c index 1c3ab2bedc..2464aebd09 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c @@ -16,7 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. UINT16 mStatementIndex;
UINT16 mExpressionOpCodeIndex;
-EFI_QUESTION_ID mUsedQuestionId;
+
BOOLEAN mInScopeSubtitle;
extern LIST_ENTRY gBrowserStorageList;
/**
@@ -42,9 +42,9 @@ CreateStatement ( if (Form == NULL) {
//
- // Only guid op may out side the form level.
+ // We are currently not in a Form Scope, so just skip this Statement
//
- ASSERT (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP);
+ return NULL;
}
Statement = &FormSet->StatementBuffer[mStatementIndex];
@@ -58,7 +58,6 @@ CreateStatement ( Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
- Statement->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;
StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
@@ -83,11 +82,8 @@ CreateStatement ( //
// Insert this Statement into current Form
//
- if (Form == NULL) {
- InsertTailList (&FormSet->StatementListOSF, &Statement->Link);
- } else {
- InsertTailList (&Form->StatementListHead, &Statement->Link);
- }
+ InsertTailList (&Form->StatementListHead, &Statement->Link);
+
return Statement;
}
@@ -1137,7 +1133,6 @@ ParseOpCodes ( CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
mStatementIndex = 0;
- mUsedQuestionId = 1;
FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
if (FormSet->StatementBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
@@ -1149,7 +1144,6 @@ ParseOpCodes ( return EFI_OUT_OF_RESOURCES;
}
- InitializeListHead (&FormSet->StatementListOSF);
InitializeListHead (&FormSet->StorageListHead);
InitializeListHead (&FormSet->DefaultStoreListHead);
InitializeListHead (&FormSet->FormListHead);
@@ -1508,6 +1502,7 @@ ParseOpCodes ( InitializeListHead (&CurrentForm->ConfigRequestHead);
CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
+ CurrentForm->NvUpdateRequired = FALSE;
CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
@@ -1544,6 +1539,7 @@ ParseOpCodes ( CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
ASSERT (CurrentForm != NULL);
CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
+ CurrentForm->NvUpdateRequired = FALSE;
InitializeListHead (&CurrentForm->ExpressionListHead);
InitializeListHead (&CurrentForm->StatementListHead);
InitializeListHead (&CurrentForm->ConfigRequestHead);
@@ -1657,7 +1653,7 @@ ParseOpCodes ( ASSERT (CurrentStatement != NULL);
CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
- CurrentStatement->FakeQuestionId = mUsedQuestionId++;
+
if (Scope != 0) {
mInScopeSubtitle = TRUE;
}
@@ -1666,14 +1662,13 @@ ParseOpCodes ( case EFI_IFR_TEXT_OP:
CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
ASSERT (CurrentStatement != NULL);
- CurrentStatement->FakeQuestionId = mUsedQuestionId++;
+
CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
break;
case EFI_IFR_RESET_BUTTON_OP:
CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
ASSERT (CurrentStatement != NULL);
- CurrentStatement->FakeQuestionId = mUsedQuestionId++;
CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
break;
@@ -1918,7 +1913,6 @@ ParseOpCodes ( CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
ASSERT (CurrentOption != NULL);
CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
- CurrentOption->OpCode = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;
CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
@@ -2276,8 +2270,45 @@ ParseOpCodes ( //
// Vendor specific
//
- case EFI_IFR_GUID_OP:
- CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
+ case EFI_IFR_GUID_OP:
+ if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
+ //
+ // Tiano specific GUIDed opcodes
+ //
+ switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {
+ case EFI_IFR_EXTEND_OP_LABEL:
+ //
+ // just ignore label
+ //
+ break;
+
+ case EFI_IFR_EXTEND_OP_BANNER:
+ //
+ // By SubClass to get Banner Data from Front Page
+ //
+ if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {
+ CopyMem (
+ &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][
+ ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],
+ &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,
+ sizeof (EFI_STRING_ID)
+ );
+ }
+ break;
+
+ case EFI_IFR_EXTEND_OP_CLASS:
+ CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
+ break;
+
+ case EFI_IFR_EXTEND_OP_SUBCLASS:
+ CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));
+ break;
+
+ default:
+ break;
+ }
+ }
+
break;
//
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c b/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c index a58e12f12c..844590770a 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c @@ -12,38 +12,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/
-#include "FormDisplay.h"
+#include "Setup.h"
-/**
- Get maximum and minimum info from this opcode.
-
- @param OpCode Pointer to the current input opcode.
- @param Minimum The minimum size info for this opcode.
- @param Maximum The maximum size info for this opcode.
-
-**/
-VOID
-GetFieldFromOp (
- IN EFI_IFR_OP_HEADER *OpCode,
- OUT UINTN *Minimum,
- OUT UINTN *Maximum
- )
-{
- EFI_IFR_STRING *StringOp;
- EFI_IFR_PASSWORD *PasswordOp;
- if (OpCode->OpCode == EFI_IFR_STRING_OP) {
- StringOp = (EFI_IFR_STRING *) OpCode;
- *Minimum = StringOp->MinSize;
- *Maximum = StringOp->MaxSize;
- } else if (OpCode->OpCode == EFI_IFR_PASSWORD_OP) {
- PasswordOp = (EFI_IFR_PASSWORD *) OpCode;
- *Minimum = PasswordOp->MinSize;
- *Maximum = PasswordOp->MaxSize;
- } else {
- *Minimum = 0;
- *Maximum = 0;
- }
-}
/**
Get string or password input from user.
@@ -82,11 +52,11 @@ ReadString ( BOOLEAN CursorVisible;
UINTN Minimum;
UINTN Maximum;
- FORM_DISPLAY_ENGINE_STATEMENT *Question;
+ FORM_BROWSER_STATEMENT *Question;
BOOLEAN IsPassword;
- DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;
- DimensionsHeight = gStatementDimensions.BottomRow - gStatementDimensions.TopRow;
+ DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
+ DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;
NullCharacter = CHAR_NULL;
ScreenSize = GetStringWidth (Prompt) / sizeof (CHAR16);
@@ -94,9 +64,10 @@ ReadString ( Space[1] = CHAR_NULL;
Question = MenuOption->ThisTag;
- GetFieldFromOp(Question->OpCode, &Minimum, &Maximum);
+ Minimum = (UINTN) Question->Minimum;
+ Maximum = (UINTN) Question->Maximum;
- if (Question->OpCode->OpCode == EFI_IFR_PASSWORD_OP) {
+ if (Question->Operand == EFI_IFR_PASSWORD_OP) {
IsPassword = TRUE;
} else {
IsPassword = FALSE;
@@ -116,14 +87,14 @@ ReadString ( BufferedString = AllocateZeroPool (ScreenSize * 2);
ASSERT (BufferedString);
- Start = (DimensionsWidth - ScreenSize - 2) / 2 + gStatementDimensions.LeftColumn + 1;
- Top = ((DimensionsHeight - 6) / 2) + gStatementDimensions.TopRow - 1;
+ Start = (DimensionsWidth - ScreenSize - 2) / 2 + gScreenDimensions.LeftColumn + 1;
+ Top = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1;
//
// Display prompt for string
//
- // CreateDialog (NULL, "", Prompt, Space, "", NULL);
CreateMultiStringPopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter);
+
gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));
CursorVisible = gST->ConOut->Mode->CursorVisible;
@@ -151,7 +122,7 @@ ReadString ( BufferedString[Count] = StringPtr[Index];
if (IsPassword) {
- PrintCharAt ((UINTN)-1, (UINTN)-1, L'*');
+ PrintChar (L'*');
}
}
@@ -210,7 +181,7 @@ ReadString ( // To save code space, we can then treat this as an error and return back to the menu.
//
do {
- CreateDialog (&Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter, NULL);
+ CreateDialog (4, TRUE, 0, NULL, &Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter);
} while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
FreePool (TempString);
@@ -287,7 +258,7 @@ ReadString ( BufferedString[Count] = StringPtr[Index];
if (IsPassword) {
- PrintCharAt ((UINTN)-1, (UINTN)-1, L'*');
+ PrintChar (L'*');
}
}
@@ -308,12 +279,12 @@ ReadString ( like: Year change: 2012.02.29 -> 2013.02.29 -> 2013.02.01
Month change: 2013.03.29 -> 2013.02.29 -> 2013.02.28
- @param QuestionValue Pointer to current question.
+ @param Question Pointer to current question.
@param Sequence The sequence of the field in the question.
**/
VOID
AdjustQuestionValue (
- IN EFI_HII_VALUE *QuestionValue,
+ IN FORM_BROWSER_STATEMENT *Question,
IN UINT8 Sequence
)
{
@@ -322,8 +293,12 @@ AdjustQuestionValue ( UINT8 Maximum;
UINT8 Minimum;
- Month = QuestionValue->Value.date.Month;
- Year = QuestionValue->Value.date.Year;
+ if (Question->Operand != EFI_IFR_DATE_OP) {
+ return;
+ }
+
+ Month = Question->HiiValue.Value.date.Month;
+ Year = Question->HiiValue.Value.date.Year;
Minimum = 1;
switch (Month) {
@@ -349,8 +324,8 @@ AdjustQuestionValue ( // Change the month area.
//
if (Sequence == 0) {
- if (QuestionValue->Value.date.Day > Maximum) {
- QuestionValue->Value.date.Day = Maximum;
+ if (Question->HiiValue.Value.date.Day > Maximum) {
+ Question->HiiValue.Value.date.Day = Maximum;
}
}
@@ -358,76 +333,16 @@ AdjustQuestionValue ( // Change the Year area.
//
if (Sequence == 2) {
- if (QuestionValue->Value.date.Day > Maximum) {
- QuestionValue->Value.date.Day = Minimum;
+ if (Question->HiiValue.Value.date.Day > Maximum) {
+ Question->HiiValue.Value.date.Day = Minimum;
}
}
}
/**
- Get field info from numeric opcode.
-
- @param OpCode Pointer to the current input opcode.
- @param Minimum The minimum size info for this opcode.
- @param Maximum The maximum size info for this opcode.
- @param Step The step size info for this opcode.
- @param StorageWidth The storage width info for this opcode.
-
-**/
-VOID
-GetValueFromNum (
- IN EFI_IFR_OP_HEADER *OpCode,
- OUT UINT64 *Minimum,
- OUT UINT64 *Maximum,
- OUT UINT64 *Step,
- OUT UINT16 *StorageWidth
-)
-{
- EFI_IFR_NUMERIC *NumericOp;
-
- NumericOp = (EFI_IFR_NUMERIC *) OpCode;
-
- switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) {
- case EFI_IFR_NUMERIC_SIZE_1:
- *Minimum = NumericOp->data.u8.MinValue;
- *Maximum = NumericOp->data.u8.MaxValue;
- *Step = NumericOp->data.u8.Step;
- *StorageWidth = (UINT16) sizeof (UINT8);
- break;
-
- case EFI_IFR_NUMERIC_SIZE_2:
- *Minimum = NumericOp->data.u16.MinValue;
- *Maximum = NumericOp->data.u16.MaxValue;
- *Step = NumericOp->data.u16.Step;
- *StorageWidth = (UINT16) sizeof (UINT16);
- break;
-
- case EFI_IFR_NUMERIC_SIZE_4:
- *Minimum = NumericOp->data.u32.MinValue;
- *Maximum = NumericOp->data.u32.MaxValue;
- *Step = NumericOp->data.u32.Step;
- *StorageWidth = (UINT16) sizeof (UINT32);
- break;
-
- case EFI_IFR_NUMERIC_SIZE_8:
- *Minimum = NumericOp->data.u64.MinValue;
- *Maximum = NumericOp->data.u64.MaxValue;
- *Step = NumericOp->data.u64.Step;
- *StorageWidth = (UINT16) sizeof (UINT64);
- break;
-
- default:
- break;
- }
-
- if (*Maximum == 0) {
- *Maximum = (UINT64) -1;
- }
-}
-
-/**
This routine reads a numeric value from the user input.
+ @param Selection Pointer to current selection.
@param MenuOption Pointer to the current input menu.
@retval EFI_SUCCESS If numerical input is read successfully
@@ -436,6 +351,7 @@ GetValueFromNum ( **/
EFI_STATUS
GetNumericInput (
+ IN UI_MENU_SELECTION *Selection,
IN UI_MENU_OPTION *MenuOption
)
{
@@ -459,9 +375,9 @@ GetNumericInput ( UINT8 Digital;
EFI_INPUT_KEY Key;
EFI_HII_VALUE *QuestionValue;
- FORM_DISPLAY_ENGINE_STATEMENT *Question;
- EFI_IFR_NUMERIC *NumericOp;
- UINT16 StorageWidth;
+ FORM_BROWSER_FORM *Form;
+ FORM_BROWSER_FORMSET *FormSet;
+ FORM_BROWSER_STATEMENT *Question;
Column = MenuOption->OptCol;
Row = MenuOption->Row;
@@ -469,13 +385,14 @@ GetNumericInput ( Count = 0;
InputWidth = 0;
Digital = 0;
- StorageWidth = 0;
- Minimum = 0;
- Maximum = 0;
- NumericOp = NULL;
+ FormSet = Selection->FormSet;
+ Form = Selection->Form;
Question = MenuOption->ThisTag;
- QuestionValue = &Question->CurrentValue;
+ QuestionValue = &Question->HiiValue;
+ Step = Question->Step;
+ Minimum = Question->Minimum;
+ Maximum = Question->Maximum;
//
// Only two case, user can enter to this function: Enter and +/- case.
@@ -483,7 +400,7 @@ GetNumericInput ( //
ManualInput = (BOOLEAN)(gDirection == 0 ? TRUE : FALSE);
- if ((Question->OpCode->OpCode == EFI_IFR_DATE_OP) || (Question->OpCode->OpCode == EFI_IFR_TIME_OP)) {
+ if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) {
DateOrTime = TRUE;
} else {
DateOrTime = FALSE;
@@ -494,7 +411,7 @@ GetNumericInput ( //
EraseLen = 0;
EditValue = 0;
- if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {
+ if (Question->Operand == EFI_IFR_DATE_OP) {
Step = 1;
Minimum = 1;
@@ -540,7 +457,7 @@ GetNumericInput ( default:
break;
}
- } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) {
+ } else if (Question->Operand == EFI_IFR_TIME_OP) {
Step = 1;
Minimum = 0;
@@ -567,15 +484,18 @@ GetNumericInput ( break;
}
} else {
- ASSERT (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP);
- NumericOp = (EFI_IFR_NUMERIC *) Question->OpCode;
- GetValueFromNum(Question->OpCode, &Minimum, &Maximum, &Step, &StorageWidth);
+ //
+ // Numeric
+ //
+ EraseLen = gOptionBlockWidth;
EditValue = QuestionValue->Value.u64;
- EraseLen = gOptionBlockWidth;
+ if (Maximum == 0) {
+ Maximum = (UINT64) -1;
+ }
}
- if ((Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL) &&
- ((NumericOp->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) {
+ if ((Question->Operand == EFI_IFR_NUMERIC_OP) &&
+ ((Question->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) {
HexInput = TRUE;
} else {
HexInput = FALSE;
@@ -585,11 +505,11 @@ GetNumericInput ( // Enter from "Enter" input, clear the old word showing.
//
if (ManualInput) {
- if (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) {
+ if (Question->Operand == EFI_IFR_NUMERIC_OP) {
if (HexInput) {
- InputWidth = StorageWidth * 2;
+ InputWidth = Question->StorageWidth * 2;
} else {
- switch (StorageWidth) {
+ switch (Question->StorageWidth) {
case 1:
InputWidth = 3;
break;
@@ -618,11 +538,11 @@ GetNumericInput ( InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;
InputText[InputWidth + 2] = L'\0';
- PrintStringAt (Column, Row, InputText);
+ PrintAt (Column, Row, InputText);
Column++;
}
- if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {
+ if (Question->Operand == EFI_IFR_DATE_OP) {
if (MenuOption->Sequence == 2) {
InputWidth = 4;
} else {
@@ -643,13 +563,13 @@ GetNumericInput ( }
InputText[InputWidth + 2] = L'\0';
- PrintStringAt (Column, Row, InputText);
+ PrintAt (Column, Row, InputText);
if (MenuOption->Sequence == 0) {
Column++;
}
}
- if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) {
+ if (Question->Operand == EFI_IFR_TIME_OP) {
InputWidth = 2;
if (MenuOption->Sequence == 0) {
@@ -666,7 +586,7 @@ GetNumericInput ( }
InputText[InputWidth + 2] = L'\0';
- PrintStringAt (Column, Row, InputText);
+ PrintAt (Column, Row, InputText);
if (MenuOption->Sequence == 0) {
Column++;
}
@@ -734,7 +654,7 @@ TheKey2: }
ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
- if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {
+ if (Question->Operand == EFI_IFR_DATE_OP) {
if (MenuOption->Sequence == 2) {
//
// Year
@@ -754,7 +674,7 @@ TheKey2: ASSERT (EraseLen >= 1);
FormattedNumber[EraseLen - 1] = DATE_SEPARATOR;
}
- } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) {
+ } else if (Question->Operand == EFI_IFR_TIME_OP) {
UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue);
if (MenuOption->Sequence == 0) {
@@ -769,11 +689,11 @@ TheKey2: PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
}
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
for (Loop = 0; Loop < EraseLen; Loop++) {
- PrintStringAt (MenuOption->OptCol + Loop, MenuOption->Row, L" ");
+ PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, L" ");
}
- gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor));
if (MenuOption->Sequence == 0) {
PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER);
@@ -783,7 +703,7 @@ TheKey2: PrintStringAt (Column, Row, FormattedNumber);
if (!DateOrTime || MenuOption->Sequence == 2) {
- PrintCharAt ((UINTN)-1, (UINTN)-1, RIGHT_NUMERIC_DELIMITER);
+ PrintChar (RIGHT_NUMERIC_DELIMITER);
}
}
@@ -810,18 +730,16 @@ EnterCarriageReturn: // Validate input value with Minimum value.
//
if (EditValue < Minimum) {
- UpdateStatusBar (INPUT_ERROR, TRUE);
+ UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);
break;
} else {
- UpdateStatusBar (INPUT_ERROR, FALSE);
+ UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);
}
-
- CopyMem (&gUserInput->InputValue, &Question->CurrentValue, sizeof (EFI_HII_VALUE));
- QuestionValue = &gUserInput->InputValue;
+
//
// Store Edit value back to Question
//
- if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) {
+ if (Question->Operand == EFI_IFR_DATE_OP) {
switch (MenuOption->Sequence) {
case 0:
QuestionValue->Value.date.Month = (UINT8) EditValue;
@@ -838,7 +756,7 @@ EnterCarriageReturn: default:
break;
}
- } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) {
+ } else if (Question->Operand == EFI_IFR_TIME_OP) {
switch (MenuOption->Sequence) {
case 0:
QuestionValue->Value.time.Hour = (UINT8) EditValue;
@@ -867,12 +785,32 @@ EnterCarriageReturn: // Sample like: 2012.02.29 -> 2013.02.29 -> 2013.02.01
// 2013.03.29 -> 2013.02.29 -> 2013.02.28
//
- if (Question->OpCode->OpCode == EFI_IFR_DATE_OP &&
+ if (Question->Operand == EFI_IFR_DATE_OP &&
(MenuOption->Sequence == 0 || MenuOption->Sequence == 2)) {
- AdjustQuestionValue (QuestionValue, (UINT8)MenuOption->Sequence);
+ AdjustQuestionValue (Question, (UINT8)MenuOption->Sequence);
+ }
+
+ //
+ // Check to see if the Value is something reasonable against consistency limitations.
+ // If not, let's kick the error specified.
+ //
+ Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
+ if (EFI_ERROR (Status)) {
+ //
+ // Input value is not valid, restore Question Value
+ //
+ GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
+ } else {
+ SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
+ if (!DateOrTime || (Question->Storage != NULL)) {
+ //
+ // NV flag is unnecessary for RTC type of Date/Time
+ //
+ UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
+ }
}
- return ValidateQuestion (Question);
+ return Status;
break;
case CHAR_BACKSPACE:
@@ -884,10 +822,10 @@ EnterCarriageReturn: // Remove a character
//
EditValue = PreviousNumber[Count - 1];
- UpdateStatusBar (INPUT_ERROR, FALSE);
+ UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);
Count--;
Column--;
- PrintStringAt (Column, Row, L" ");
+ PrintAt (Column, Row, L" ");
}
break;
@@ -901,12 +839,12 @@ EnterCarriageReturn: } else if ((Key.UnicodeChar >= L'a') && (Key.UnicodeChar <= L'f')) {
Digital = (UINT8) (Key.UnicodeChar - L'a' + 0x0A);
} else {
- UpdateStatusBar (INPUT_ERROR, TRUE);
+ UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);
break;
}
} else {
if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') {
- UpdateStatusBar (INPUT_ERROR, TRUE);
+ UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);
break;
}
}
@@ -935,178 +873,32 @@ EnterCarriageReturn: }
if (EditValue > Maximum) {
- UpdateStatusBar (INPUT_ERROR, TRUE);
+ UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);
ASSERT (Count < sizeof (PreviousNumber) / sizeof (PreviousNumber[0]));
EditValue = PreviousNumber[Count];
break;
} else {
- UpdateStatusBar (INPUT_ERROR, FALSE);
+ UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);
}
Count++;
ASSERT (Count < (sizeof (PreviousNumber) / sizeof (PreviousNumber[0])));
PreviousNumber[Count] = EditValue;
- gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
PrintCharAt (Column, Row, Key.UnicodeChar);
Column++;
}
break;
}
} while (TRUE);
-}
-
-/**
- Adjust option order base on the question value.
-
- @param Question Pointer to current question.
- @param PopUpMenuLines The line number of the pop up menu.
-
- @retval EFI_SUCCESS If Option input is processed successfully
- @retval EFI_DEVICE_ERROR If operation fails
-
-**/
-EFI_STATUS
-AdjustOptionOrder (
- IN FORM_DISPLAY_ENGINE_STATEMENT *Question,
- OUT UINTN *PopUpMenuLines
- )
-{
- UINTN Index;
- EFI_IFR_ORDERED_LIST *OrderList;
- UINT8 *ValueArray;
- UINT8 ValueType;
- LIST_ENTRY *Link;
- DISPLAY_QUESTION_OPTION *OneOfOption;
- EFI_HII_VALUE *HiiValueArray;
-
- Link = GetFirstNode (&Question->OptionListHead);
- OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
- ValueArray = Question->CurrentValue.Buffer;
- ValueType = OneOfOption->OptionOpCode->Type;
- OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode;
-
- for (Index = 0; Index < OrderList->MaxContainers; Index++) {
- if (GetArrayData (ValueArray, ValueType, Index) == 0) {
- break;
- }
- }
-
- *PopUpMenuLines = Index;
-
- //
- // Prepare HiiValue array
- //
- HiiValueArray = AllocateZeroPool (*PopUpMenuLines * sizeof (EFI_HII_VALUE));
- ASSERT (HiiValueArray != NULL);
-
- for (Index = 0; Index < *PopUpMenuLines; Index++) {
- HiiValueArray[Index].Type = ValueType;
- HiiValueArray[Index].Value.u64 = GetArrayData (ValueArray, ValueType, Index);
- }
-
- for (Index = 0; Index < *PopUpMenuLines; Index++) {
- OneOfOption = ValueToOption (Question, &HiiValueArray[*PopUpMenuLines - Index - 1]);
- if (OneOfOption == NULL) {
- return EFI_NOT_FOUND;
- }
-
- RemoveEntryList (&OneOfOption->Link);
-
- //
- // Insert to head.
- //
- InsertHeadList (&Question->OptionListHead, &OneOfOption->Link);
- }
-
- FreePool (HiiValueArray);
- return EFI_SUCCESS;
}
-/**
- Base on the type to compare the value.
-
- @param Value1 The first value need to compare.
- @param Value2 The second value need to compare.
- @param Type The value type for above two values.
-
- @retval TRUE The two value are same.
- @retval FALSE The two value are different.
-
-**/
-BOOLEAN
-IsValuesEqual (
- IN EFI_IFR_TYPE_VALUE *Value1,
- IN EFI_IFR_TYPE_VALUE *Value2,
- IN UINT8 Type
- )
-{
- switch (Type) {
- case EFI_IFR_TYPE_BOOLEAN:
- case EFI_IFR_TYPE_NUM_SIZE_8:
- return (BOOLEAN) (Value1->u8 == Value2->u8);
-
- case EFI_IFR_TYPE_NUM_SIZE_16:
- return (BOOLEAN) (Value1->u16 == Value2->u16);
-
- case EFI_IFR_TYPE_NUM_SIZE_32:
- return (BOOLEAN) (Value1->u32 == Value2->u32);
-
- case EFI_IFR_TYPE_NUM_SIZE_64:
- return (BOOLEAN) (Value1->u64 == Value2->u64);
-
- default:
- ASSERT (FALSE);
- return FALSE;
- }
-}
-
-/**
- Base on the type to set the value.
-
- @param Dest The dest value.
- @param Source The source value.
- @param Type The value type for above two values.
-
-**/
-VOID
-SetValuesByType (
- OUT EFI_IFR_TYPE_VALUE *Dest,
- IN EFI_IFR_TYPE_VALUE *Source,
- IN UINT8 Type
- )
-{
- switch (Type) {
- case EFI_IFR_TYPE_BOOLEAN:
- Dest->b = Source->b;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Dest->u8 = Source->u8;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Dest->u16 = Source->u16;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Dest->u32 = Source->u32;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Dest->u64 = Source->u64;
- break;
-
- default:
- ASSERT (FALSE);
- break;
- }
-}
/**
Get selection for OneOf and OrderedList (Left/Right will be ignored).
+ @param Selection Pointer to current selection.
@param MenuOption Pointer to the current input menu.
@retval EFI_SUCCESS If Option input is processed successfully
@@ -1115,6 +907,7 @@ SetValuesByType ( **/
EFI_STATUS
GetSelectionInputPopUp (
+ IN UI_MENU_SELECTION *Selection,
IN UI_MENU_OPTION *MenuOption
)
{
@@ -1141,16 +934,16 @@ GetSelectionInputPopUp ( LIST_ENTRY *Link;
BOOLEAN OrderedList;
UINT8 *ValueArray;
- UINT8 *ReturnValue;
UINT8 ValueType;
EFI_HII_VALUE HiiValue;
- DISPLAY_QUESTION_OPTION *OneOfOption;
- DISPLAY_QUESTION_OPTION *CurrentOption;
- FORM_DISPLAY_ENGINE_STATEMENT *Question;
+ EFI_HII_VALUE *HiiValueArray;
+ UINTN OptionCount;
+ QUESTION_OPTION *OneOfOption;
+ QUESTION_OPTION *CurrentOption;
+ FORM_BROWSER_STATEMENT *Question;
INTN Result;
- EFI_IFR_ORDERED_LIST *OrderList;
- DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn;
+ DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
ValueArray = NULL;
ValueType = 0;
@@ -1161,33 +954,81 @@ GetSelectionInputPopUp ( StringPtr = AllocateZeroPool ((gOptionBlockWidth + 1) * 2);
ASSERT (StringPtr);
- ZeroMem (&HiiValue, sizeof (EFI_HII_VALUE));
-
Question = MenuOption->ThisTag;
- if (Question->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) {
- Link = GetFirstNode (&Question->OptionListHead);
- OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
- ValueArray = Question->CurrentValue.Buffer;
- ValueType = OneOfOption->OptionOpCode->Type;
+ if (Question->Operand == EFI_IFR_ORDERED_LIST_OP) {
+ ValueArray = Question->BufferValue;
+ ValueType = Question->ValueType;
OrderedList = TRUE;
- OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode;
} else {
OrderedList = FALSE;
- OrderList = NULL;
}
//
// Calculate Option count
//
- PopUpMenuLines = 0;
if (OrderedList) {
- AdjustOptionOrder(Question, &PopUpMenuLines);
+ for (Index = 0; Index < Question->MaxContainers; Index++) {
+ if (GetArrayData (ValueArray, ValueType, Index) == 0) {
+ break;
+ }
+ }
+
+ OptionCount = Index;
} else {
+ OptionCount = 0;
Link = GetFirstNode (&Question->OptionListHead);
while (!IsNull (&Question->OptionListHead, Link)) {
- OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
+ OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
+
+ OptionCount++;
+
+ Link = GetNextNode (&Question->OptionListHead, Link);
+ }
+ }
+
+ //
+ // Move valid Option to list head.
+ //
+ PopUpMenuLines = 0;
+ if (OrderedList) {
+ //
+ // Prepare HiiValue array
+ //
+ HiiValueArray = AllocateZeroPool (OptionCount * sizeof (EFI_HII_VALUE));
+ ASSERT (HiiValueArray != NULL);
+ for (Index = 0; Index < OptionCount; Index++) {
+ HiiValueArray[Index].Type = ValueType;
+ HiiValueArray[Index].Value.u64 = GetArrayData (ValueArray, ValueType, Index);
+ }
+
+ for (Index = 0; Index < OptionCount; Index++) {
+ OneOfOption = ValueToOption (Question, &HiiValueArray[OptionCount - Index - 1]);
+ if (OneOfOption == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ RemoveEntryList (&OneOfOption->Link);
+
+ //
+ // Insert to head.
+ //
+ InsertHeadList (&Question->OptionListHead, &OneOfOption->Link);
+
PopUpMenuLines++;
+ }
+
+ FreePool (HiiValueArray);
+ } else {
+ Link = GetFirstNode (&Question->OptionListHead);
+ for (Index = 0; Index < OptionCount; Index++) {
+ OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
Link = GetNextNode (&Question->OptionListHead, Link);
+ if ((OneOfOption->SuppressExpression != NULL) &&
+ EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {
+ continue;
+ } else {
+ PopUpMenuLines++;
+ }
}
}
@@ -1198,23 +1039,27 @@ GetSelectionInputPopUp ( HighlightOptionIndex = 0;
Link = GetFirstNode (&Question->OptionListHead);
for (Index = 0; Index < PopUpMenuLines; Index++) {
- OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
+ OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
+ Link = GetNextNode (&Question->OptionListHead, Link);
+
+ if (!OrderedList && (OneOfOption->SuppressExpression != NULL) &&
+ EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {
+ Index--;
+ continue;
+ }
- StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
+ StringPtr = GetToken (OneOfOption->Text, MenuOption->Handle);
if (StrLen (StringPtr) > PopUpWidth) {
PopUpWidth = StrLen (StringPtr);
}
FreePool (StringPtr);
- HiiValue.Type = OneOfOption->OptionOpCode->Type;
- SetValuesByType (&HiiValue.Value, &OneOfOption->OptionOpCode->Value, HiiValue.Type);
- if (!OrderedList && (CompareHiiValue (&Question->CurrentValue, &HiiValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
+
+ if (!OrderedList && (CompareHiiValue (&Question->HiiValue, &OneOfOption->Value, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
//
// Find current selected Option for OneOf
//
HighlightOptionIndex = Index;
}
-
- Link = GetNextNode (&Question->OptionListHead, Link);
}
//
@@ -1223,16 +1068,16 @@ GetSelectionInputPopUp ( PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT;
SavedAttribute = gST->ConOut->Mode->Attribute;
- gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
+ gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) {
PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH;
}
- Start = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gStatementDimensions.LeftColumn;
+ Start = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gScreenDimensions.LeftColumn;
End = Start + PopUpWidth + POPUP_FRAME_WIDTH;
- Top = gStatementDimensions.TopRow;
- Bottom = gStatementDimensions.BottomRow - 1;
+ Top = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT;
+ Bottom = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight - 1;
MenuLinesInView = Bottom - Top - 1;
if (MenuLinesInView >= PopUpMenuLines) {
@@ -1252,7 +1097,7 @@ GetSelectionInputPopUp ( //
// Clear that portion of the screen
//
- ClearLines (Start, End, Top, Bottom, GetPopupColor ());
+ ClearLines (Start, End, Top, Bottom, POPUP_TEXT | POPUP_BACKGROUND);
//
// Draw "One of" pop-up menu
@@ -1266,11 +1111,11 @@ GetSelectionInputPopUp ( Character = BOXDRAW_HORIZONTAL;
}
- PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
+ PrintChar (Character);
}
Character = BOXDRAW_DOWN_LEFT;
- PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
+ PrintChar (Character);
Character = BOXDRAW_VERTICAL;
for (Index = Top + 1; Index < Bottom; Index++) {
PrintCharAt (Start, Index, Character);
@@ -1283,6 +1128,13 @@ GetSelectionInputPopUp ( Link = GetFirstNode (&Question->OptionListHead);
for (Index = 0; Index < TopOptionIndex; Index++) {
Link = GetNextNode (&Question->OptionListHead, Link);
+
+ OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
+ if (!OrderedList && (OneOfOption->SuppressExpression != NULL) &&
+ EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {
+ Index--;
+ continue;
+ }
}
//
@@ -1290,10 +1142,16 @@ GetSelectionInputPopUp ( //
Index2 = Top + 1;
for (Index = TopOptionIndex; (Index < PopUpMenuLines) && (Index2 < Bottom); Index++) {
- OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
+ OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
Link = GetNextNode (&Question->OptionListHead, Link);
- StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle);
+ if (!OrderedList && (OneOfOption->SuppressExpression != NULL) &&
+ EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {
+ Index--;
+ continue;
+ }
+
+ StringPtr = GetToken (OneOfOption->Text, MenuOption->Handle);
ASSERT (StringPtr != NULL);
//
// If the string occupies multiple lines, truncate it to fit in one line,
@@ -1314,11 +1172,11 @@ GetSelectionInputPopUp ( //
CurrentOption = OneOfOption;
- gST->ConOut->SetAttribute (gST->ConOut, GetPickListColor ());
+ gST->ConOut->SetAttribute (gST->ConOut, PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND);
PrintStringAt (Start + 2, Index2, StringPtr);
- gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
+ gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
} else {
- gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
+ gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
PrintStringAt (Start + 2, Index2, StringPtr);
}
@@ -1335,11 +1193,11 @@ GetSelectionInputPopUp ( Character = BOXDRAW_HORIZONTAL;
}
- PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
+ PrintChar (Character);
}
Character = BOXDRAW_UP_LEFT;
- PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
+ PrintChar (Character);
//
// Get User selection
@@ -1455,7 +1313,7 @@ TheKey: if (OrderedList) {
HiiValue.Type = ValueType;
HiiValue.Value.u64 = 0;
- for (Index = 0; Index < OrderList->MaxContainers; Index++) {
+ for (Index = 0; Index < Question->MaxContainers; Index++) {
HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
if (HiiValue.Value.u64 == 0) {
break;
@@ -1484,44 +1342,44 @@ TheKey: // return the current selection
//
if (OrderedList) {
- ReturnValue = AllocateZeroPool (Question->CurrentValue.BufferLen);
- ASSERT (ReturnValue != NULL);
Index = 0;
Link = GetFirstNode (&Question->OptionListHead);
while (!IsNull (&Question->OptionListHead, Link)) {
- OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link);
+ OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
Link = GetNextNode (&Question->OptionListHead, Link);
- SetArrayData (ReturnValue, ValueType, Index, OneOfOption->OptionOpCode->Value.u64);
+ if ((OneOfOption->SuppressExpression != NULL) &&
+ EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse) {
+ continue;
+ }
+
+ SetArrayData (ValueArray, ValueType, Index, OneOfOption->Value.Value.u64);
Index++;
- if (Index > OrderList->MaxContainers) {
+ if (Index > Question->MaxContainers) {
break;
}
}
- if (CompareMem (ReturnValue, ValueArray, Question->CurrentValue.BufferLen) == 0) {
- FreePool (ReturnValue);
- return EFI_DEVICE_ERROR;
- } else {
- gUserInput->InputValue.Buffer = ReturnValue;
- gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen;
- Status = EFI_SUCCESS;
- }
} else {
ASSERT (CurrentOption != NULL);
- gUserInput->InputValue.Type = CurrentOption->OptionOpCode->Type;
- if (IsValuesEqual (&Question->CurrentValue.Value, &CurrentOption->OptionOpCode->Value, gUserInput->InputValue.Type)) {
- return EFI_DEVICE_ERROR;
- } else {
- SetValuesByType (&gUserInput->InputValue.Value, &CurrentOption->OptionOpCode->Value, gUserInput->InputValue.Type);
- Status = EFI_SUCCESS;
- }
+ CopyMem (&Question->HiiValue, &CurrentOption->Value, sizeof (EFI_HII_VALUE));
}
gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
- return ValidateQuestion (Question);
-
+ Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
+ if (EFI_ERROR (Status)) {
+ //
+ // Input value is not valid, restore Question Value
+ //
+ GetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
+ } else {
+ SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
+ UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
+ }
+
+ return Status;
+
default:
break;
}
@@ -1529,3 +1387,32 @@ TheKey: }
+/**
+ Wait for a key to be pressed by user.
+
+ @param Key The key which is pressed by user.
+
+ @retval EFI_SUCCESS The function always completed successfully.
+
+**/
+EFI_STATUS
+WaitForKeyStroke (
+ OUT EFI_INPUT_KEY *Key
+ )
+{
+ EFI_STATUS Status;
+
+ while (TRUE) {
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (Status != EFI_NOT_READY) {
+ continue;
+ }
+
+ UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0, 0);
+ }
+ return Status;
+}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c index def18fd9f9..4cd71e5d44 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c @@ -19,1658 +19,863 @@ UI_MENU_SELECTION *gCurrentSelection; EFI_HII_HANDLE mCurrentHiiHandle = NULL;
EFI_GUID mCurrentFormSetGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
UINT16 mCurrentFormId = 0;
-EFI_EVENT mValueChangedEvent = NULL;
-LIST_ENTRY mRefreshEventList = INITIALIZE_LIST_HEAD_VARIABLE (mRefreshEventList);
-UINT32 gBrowserStatus = BROWSER_SUCCESS;
-CHAR16 *gErrorInfo;
-UINT16 mCurFakeQestId;
-FORM_DISPLAY_ENGINE_FORM gDisplayFormData;
/**
- Evaluate all expressions in a Form.
-
- @param FormSet FormSet this Form belongs to.
- @param Form The Form.
-
- @retval EFI_SUCCESS The expression evaluated successfuly
-
-**/
-EFI_STATUS
-EvaluateFormExpressions (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN FORM_BROWSER_FORM *Form
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Link;
- FORM_EXPRESSION *Expression;
-
- Link = GetFirstNode (&Form->ExpressionListHead);
- while (!IsNull (&Form->ExpressionListHead, Link)) {
- Expression = FORM_EXPRESSION_FROM_LINK (Link);
- Link = GetNextNode (&Form->ExpressionListHead, Link);
-
- if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF ||
- Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF ||
- Expression->Type == EFI_HII_EXPRESSION_WRITE ||
- (Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) {
- //
- // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.
- //
- continue;
- }
-
- Status = EvaluateExpression (FormSet, Form, Expression);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Add empty function for event process function.
+ Clear retangle with specified text attribute.
- @param Event The Event need to be process
- @param Context The context of the event.
+ @param LeftColumn Left column of retangle.
+ @param RightColumn Right column of retangle.
+ @param TopRow Start row of retangle.
+ @param BottomRow End row of retangle.
+ @param TextAttribute The character foreground and background.
**/
VOID
-EFIAPI
-SetupBrowserEmptyFunction (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
-}
-
-/**
- Base on the opcode buffer info to get the display statement.
-
- @param OpCode The input opcode buffer for this statement.
-
- @retval Statement The statement use this opcode buffer.
-
-**/
-FORM_DISPLAY_ENGINE_STATEMENT *
-GetDisplayStatement (
- IN EFI_IFR_OP_HEADER *OpCode
+ClearLines (
+ IN UINTN LeftColumn,
+ IN UINTN RightColumn,
+ IN UINTN TopRow,
+ IN UINTN BottomRow,
+ IN UINTN TextAttribute
)
{
- FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement;
- LIST_ENTRY *Link;
-
- Link = GetFirstNode (&gDisplayFormData.StatementListHead);
- while (!IsNull (&gDisplayFormData.StatementListHead, Link)) {
- DisplayStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
-
- if (DisplayStatement->OpCode == OpCode) {
- return DisplayStatement;
- }
- Link = GetNextNode (&gDisplayFormData.StatementListHead, Link);
- }
-
- return NULL;
-}
-
-/**
- Free the refresh event list.
-
-**/
-VOID
-FreeRefreshEvent (
- VOID
- )
-{
- LIST_ENTRY *Link;
- FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;
-
- while (!IsListEmpty (&mRefreshEventList)) {
- Link = GetFirstNode (&mRefreshEventList);
- EventNode = FORM_BROWSER_REFRESH_EVENT_FROM_LINK (Link);
- RemoveEntryList (&EventNode->Link);
-
- gBS->CloseEvent (EventNode->RefreshEvent);
-
- FreePool (EventNode);
- }
-}
-
-/**
- Check whether this statement value is changed. If yes, update the statement value and return TRUE;
- else return FALSE.
-
- @param Statement The statement need to check.
-
-**/
-VOID
-UpdateStatement (
- IN OUT FORM_BROWSER_STATEMENT *Statement
- )
-{
- GetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);
+ CHAR16 *Buffer;
+ UINTN Row;
//
- // Reset FormPackage update flag
+ // For now, allocate an arbitrarily long buffer
//
- mHiiPackageListUpdated = FALSE;
+ Buffer = AllocateZeroPool (0x10000);
+ ASSERT (Buffer != NULL);
//
- // Question value may be changed, need invoke its Callback()
+ // Set foreground and background as defined
//
- ProcessCallBackFunction (gCurrentSelection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);
-
- if (mHiiPackageListUpdated) {
- //
- // Package list is updated, force to reparse IFR binary of target Formset
- //
- mHiiPackageListUpdated = FALSE;
- gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;
- }
-}
-
-/**
- Refresh the question which has refresh guid event attribute.
-
- @param Event The event which has this function related.
- @param Context The input context info related to this event or the status code return to the caller.
-**/
-VOID
-EFIAPI
-RefreshEventNotify(
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- FORM_BROWSER_STATEMENT *Statement;
-
- Statement = (FORM_BROWSER_STATEMENT *)Context;
- UpdateStatement(Statement);
- gBS->SignalEvent (mValueChangedEvent);
-}
-
-
-/**
- Create refresh hook event for statement which has refresh event or interval.
-
- @param Statement The statement need to check.
-
-**/
-VOID
-CreateRefreshEvent (
- IN FORM_BROWSER_STATEMENT *Statement
- )
-{
- EFI_STATUS Status;
- EFI_EVENT RefreshEvent;
- FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;
-
- //
- // If question has refresh guid, create the notify function.
- //
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- RefreshEventNotify,
- Statement,
- &Statement->RefreshGuid,
- &RefreshEvent);
- ASSERT_EFI_ERROR (Status);
-
- EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));
- ASSERT (EventNode != NULL);
- EventNode->RefreshEvent = RefreshEvent;
- InsertTailList(&mRefreshEventList, &EventNode->Link);
-}
-
-/**
- Perform value check for a question.
-
- @param Question The question need to do check.
- @param ErrorInfo Return info about the error.
-
- @retval The check result.
-**/
-UINT32
-InConsistentIfCheck (
- IN FORM_BROWSER_STATEMENT *Question,
- OUT STATEMENT_ERROR_INFO *ErrorInfo
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Link;
- FORM_EXPRESSION *Expression;
- LIST_ENTRY *ListHead;
- UINT32 RetVal;
-
- RetVal = STATEMENT_VALID;
- ListHead = &Question->InconsistentListHead;
-
- Link = GetFirstNode (ListHead);
- while (!IsNull (ListHead, Link)) {
- Expression = FORM_EXPRESSION_FROM_LINK (Link);
- Link = GetNextNode (ListHead, Link);
-
- //
- // Evaluate the expression
- //
- Status = EvaluateExpression (gCurrentSelection->FormSet, gCurrentSelection->Form, Expression);
- if (EFI_ERROR (Status)) {
- continue;
- }
-
- if ((Expression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && Expression->Result.Value.b) {
- ErrorInfo->StringId = Expression->Error;
- ErrorInfo->TimeOut = 0;
- RetVal = INCOSISTENT_IF_TRUE;
- break;
- }
- }
-
- return RetVal;
-}
-
-/**
- Perform value check for a question.
-
- @param Form Form where Statement is in.
- @param Statement Value will check for it.
- @param InputValue New value will be checked.
- @param ErrorInfo Return the error info for this check.
-
- @retval TRUE Input Value is valid.
- @retval FALSE Input Value is invalid.
-**/
-UINT32
-EFIAPI
-QuestionCheck (
- IN FORM_DISPLAY_ENGINE_FORM *Form,
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
- IN EFI_HII_VALUE *InputValue,
- OUT STATEMENT_ERROR_INFO *ErrorInfo
- )
-{
- FORM_BROWSER_STATEMENT *Question;
- EFI_HII_VALUE BackUpValue;
- UINT8 *BackUpBuffer;
- UINT32 RetVal;
-
- BackUpBuffer = NULL;
- RetVal = STATEMENT_VALID;
-
- ASSERT (Form != NULL && Statement != NULL && InputValue != NULL && ErrorInfo != NULL);
-
- Question = GetBrowserStatement(Statement);
- ASSERT (Question != NULL);
+ gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);
//
- // Back up the quesion value.
+ // Much faster to buffer the long string instead of print it a character at a time
//
- switch (Question->Operand) {
- case EFI_IFR_ORDERED_LIST_OP:
- BackUpBuffer = AllocateCopyPool (Question->StorageWidth, Question->BufferValue);
- ASSERT (BackUpBuffer != NULL);
- CopyMem (Question->BufferValue, InputValue->Buffer, Question->StorageWidth);
- break;
-
- default:
- CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));
- CopyMem (&Question->HiiValue, InputValue, sizeof (EFI_HII_VALUE));
- break;
- }
+ SetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');
//
- // Do the inconsistentif check.
+ // Clear the desired area with the appropriate foreground/background
//
- if (!IsListEmpty (&Question->InconsistentListHead)) {
- RetVal = InConsistentIfCheck(Question, ErrorInfo);
+ for (Row = TopRow; Row <= BottomRow; Row++) {
+ PrintStringAt (LeftColumn, Row, Buffer);
}
- //
- // Restore the quesion value.
- //
- switch (Question->Operand) {
- case EFI_IFR_ORDERED_LIST_OP:
- CopyMem (Question->BufferValue, BackUpBuffer, Question->StorageWidth);
- break;
-
- default:
- CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));
- break;
- }
+ gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);
- return RetVal;
+ FreePool (Buffer);
+ return ;
}
/**
+ Concatenate a narrow string to another string.
- Initialize the Display statement structure data.
+ @param Destination The destination string.
+ @param Source The source string. The string to be concatenated.
+ to the end of Destination.
- @param DisplayStatement Pointer to the display Statement data strucure.
- @param Statement The statement need to check.
- @param HostDisplayStatement Pointer to the display Statement data strucure which is an host statement.
**/
VOID
-InitializeDisplayStatement (
- IN OUT FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement,
- IN FORM_BROWSER_STATEMENT *Statement,
- IN FORM_DISPLAY_ENGINE_STATEMENT *HostDisplayStatement
+NewStrCat (
+ IN OUT CHAR16 *Destination,
+ IN CHAR16 *Source
)
{
- LIST_ENTRY *Link;
- QUESTION_OPTION *Option;
- DISPLAY_QUESTION_OPTION *DisplayOption;
-
- DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;
- DisplayStatement->Version = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;
- DisplayStatement->OpCode = Statement->OpCode;
- InitializeListHead (&DisplayStatement->NestStatementList);
- InitializeListHead (&DisplayStatement->OptionListHead);
-
- if ((EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut) || Statement->Locked) {
- DisplayStatement->Attribute |= HII_DISPLAY_GRAYOUT;
- }
- if ((Statement->ValueExpression != NULL) || ((Statement->QuestionFlags & EFI_IFR_FLAG_READ_ONLY) != 0)) {
- DisplayStatement->Attribute |= HII_DISPLAY_READONLY;
- }
-
- //
- // Initilize the option list in statement.
- //
- Link = GetFirstNode (&Statement->OptionListHead);
- while (!IsNull (&Statement->OptionListHead, Link)) {
- Option = QUESTION_OPTION_FROM_LINK (Link);
- Link = GetNextNode (&Statement->OptionListHead, Link);
- if ((Option->SuppressExpression != NULL) &&
- ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {
- continue;
- }
+ UINTN Length;
- DisplayOption = AllocateZeroPool (sizeof (DISPLAY_QUESTION_OPTION));
- ASSERT (DisplayOption != NULL);
-
- DisplayOption->ImageId = Option->ImageId;
- DisplayOption->Signature = DISPLAY_QUESTION_OPTION_SIGNATURE;
- DisplayOption->OptionOpCode = Option->OpCode;
- InsertTailList(&DisplayStatement->OptionListHead, &DisplayOption->Link);
- }
-
- CopyMem (&DisplayStatement->CurrentValue, &Statement->HiiValue, sizeof (EFI_HII_VALUE));
+ for (Length = 0; Destination[Length] != 0; Length++)
+ ;
//
- // Some special op code need an extra buffer to save the data.
- // Such as string, password, orderedlist...
+ // We now have the length of the original string
+ // We can safely assume for now that we are concatenating a narrow value to this string.
+ // For instance, the string is "XYZ" and cat'ing ">"
+ // If this assumption changes, we need to make this routine a bit more complex
//
- if (Statement->BufferValue != NULL) {
- //
- // Ordered list opcode may not initilized, get default value here.
- //
- if (Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP && GetArrayData (Statement->BufferValue, Statement->ValueType, 0) == 0) {
- GetQuestionDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, 0);
- }
-
- DisplayStatement->CurrentValue.Buffer = AllocateCopyPool(Statement->StorageWidth,Statement->BufferValue);
- DisplayStatement->CurrentValue.BufferLen = Statement->StorageWidth;
- }
-
- DisplayStatement->SettingChangedFlag = Statement->ValueChanged;
-
- //
- // Get the highlight statement for current form.
- //
- if (((gCurrentSelection->QuestionId != 0) && (Statement->QuestionId == gCurrentSelection->QuestionId)) ||
- ((mCurFakeQestId != 0) && (Statement->FakeQuestionId == mCurFakeQestId))) {
- gDisplayFormData.HighLightedStatement = DisplayStatement;
- }
-
- //
- // Create the refresh event process function.
- //
- if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {
- CreateRefreshEvent (Statement);
- }
-
- //
- // For RTC type of date/time, set default refresh interval to be 1 second.
- //
- if ((Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) && Statement->Storage == NULL) {
- Statement->RefreshInterval = 1;
- }
-
- //
- // Create the refresh guid hook event.
- // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.
- //
- if ((!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) || (Statement->RefreshInterval != 0)) {
- gDisplayFormData.FormRefreshEvent = mValueChangedEvent;
- }
+ Destination[Length] = NARROW_CHAR;
+ Length++;
- //
- // Save the password check function for later use.
- //
- if (Statement->Operand == EFI_IFR_PASSWORD_OP) {
- DisplayStatement->PasswordCheck = PasswordCheck;
- }
-
- //
- // Save the validate check question for later use.
- //
- if (!IsListEmpty (&Statement->InconsistentListHead)) {
- DisplayStatement->ValidateQuestion = QuestionCheck;
- }
-
- //
- // If this statement is nest in the subtitle, insert to the host statement.
- // else insert to the form it belongs to.
- //
- if (Statement->InSubtitle) {
- InsertTailList(&HostDisplayStatement->NestStatementList, &DisplayStatement->DisplayLink);
- } else {
- InsertTailList(&gDisplayFormData.StatementListHead, &DisplayStatement->DisplayLink);
- }
+ StrCpy (Destination + Length, Source);
}
/**
- Process for the refresh interval statement.
+ Count the storage space of a Unicode string.
- @param Event The Event need to be process
- @param Context The context of the event.
-
-**/
-VOID
-EFIAPI
-RefreshIntervalProcess (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- FORM_BROWSER_STATEMENT *Statement;
- LIST_ENTRY *Link;
+ This function handles the Unicode string with NARROW_CHAR
+ and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
+ does not count in the resultant output. If a WIDE_CHAR is
+ hit, then 2 Unicode character will consume an output storage
+ space with size of CHAR16 till a NARROW_CHAR is hit.
- Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);
- while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {
- Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
- Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);
+ If String is NULL, then ASSERT ().
- if (Statement->RefreshInterval == 0) {
- continue;
- }
+ @param String The input string to be counted.
- UpdateStatement(Statement);
- }
-
- gBS->SignalEvent (mValueChangedEvent);
-}
-
-/**
-
- Make a copy of the global hotkey info.
+ @return Storage space for the input string.
**/
-VOID
-UpdateHotkeyList (
- VOID
+UINTN
+GetStringWidth (
+ IN CHAR16 *String
)
{
- BROWSER_HOT_KEY *HotKey;
- BROWSER_HOT_KEY *CopyKey;
- LIST_ENTRY *Link;
-
- Link = GetFirstNode (&gBrowserHotKeyList);
- while (!IsNull (&gBrowserHotKeyList, Link)) {
- HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
-
- CopyKey = AllocateCopyPool(sizeof (BROWSER_HOT_KEY), HotKey);
- CopyKey->KeyData = AllocateCopyPool(sizeof (EFI_INPUT_KEY), HotKey->KeyData);
- CopyKey->HelpString = AllocateCopyPool(StrSize (HotKey->HelpString), HotKey->HelpString);
-
- InsertTailList(&gDisplayFormData.HotKeyListHead, &CopyKey->Link);
+ UINTN Index;
+ UINTN Count;
+ UINTN IncrementValue;
- Link = GetNextNode (&gBrowserHotKeyList, Link);
- }
-}
-
-/**
-
- Enum all statement in current form, find all the statement can be display and
- add to the display form.
-
-**/
-VOID
-AddStatementToDisplayForm (
- VOID
- )
-{
- EFI_STATUS Status;
- LIST_ENTRY *Link;
- FORM_BROWSER_STATEMENT *Statement;
- FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement;
- FORM_DISPLAY_ENGINE_STATEMENT *HostDisplayStatement;
- UINT8 MinRefreshInterval;
- EFI_EVENT RefreshIntervalEvent;
- FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;
- BOOLEAN FormEditable;
-
- HostDisplayStatement = NULL;
- MinRefreshInterval = 0;
- FormEditable = FALSE;
-
- //
- // Process the statement outside the form, these statements are not recognized
- // by browser core.
- //
- Link = GetFirstNode (&gCurrentSelection->FormSet->StatementListOSF);
- while (!IsNull (&gCurrentSelection->FormSet->StatementListOSF, Link)) {
- Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
- Link = GetNextNode (&gCurrentSelection->FormSet->StatementListOSF, Link);
-
- DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));
- ASSERT (DisplayStatement != NULL);
- DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;
- DisplayStatement->Version = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;
- DisplayStatement->OpCode = Statement->OpCode;
-
- InitializeListHead (&DisplayStatement->NestStatementList);
- InitializeListHead (&DisplayStatement->OptionListHead);
-
- InsertTailList(&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);
+ ASSERT (String != NULL);
+ if (String == NULL) {
+ return 0;
}
- //
- // Process the statement in this form.
- //
- Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);
- while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {
- Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
- Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);
-
- //
- // This statement can't be show, skip it.
- //
- if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) > ExpressGrayOut) {
- continue;
- }
-
- DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));
- ASSERT (DisplayStatement != NULL);
+ Index = 0;
+ Count = 0;
+ IncrementValue = 1;
+ do {
//
- // Initialize this statement and add it to the display form.
+ // Advance to the null-terminator or to the first width directive
//
- InitializeDisplayStatement(DisplayStatement, Statement, HostDisplayStatement);
+ for (;
+ (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
+ Index++, Count = Count + IncrementValue
+ )
+ ;
//
- // Save the Host statement info.
- // Host statement may has nest statement follow it.
+ // We hit the null-terminator, we now have a count
//
- if (!Statement->InSubtitle) {
- HostDisplayStatement = DisplayStatement;
- }
-
- if (Statement->Storage != NULL) {
- FormEditable = TRUE;
+ if (String[Index] == 0) {
+ break;
}
-
//
- // Get the minimal refresh interval value for later use.
+ // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
+ // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
//
- if ((Statement->RefreshInterval != 0) &&
- (MinRefreshInterval == 0 || Statement->RefreshInterval < MinRefreshInterval)) {
- MinRefreshInterval = Statement->RefreshInterval;
+ if (String[Index] == NARROW_CHAR) {
+ //
+ // Skip to the next character
+ //
+ Index++;
+ IncrementValue = 1;
+ } else {
+ //
+ // Skip to the next character
+ //
+ Index++;
+ IncrementValue = 2;
}
- }
+ } while (String[Index] != 0);
//
- // Create the periodic timer for refresh interval statement.
+ // Increment by one to include the null-terminator in the size
//
- if (MinRefreshInterval != 0) {
- Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshIntervalProcess, NULL, &RefreshIntervalEvent);
- ASSERT_EFI_ERROR (Status);
- Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, MinRefreshInterval * ONE_SECOND);
- ASSERT_EFI_ERROR (Status);
-
- EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));
- ASSERT (EventNode != NULL);
- EventNode->RefreshEvent = RefreshIntervalEvent;
- InsertTailList(&mRefreshEventList, &EventNode->Link);
- }
+ Count++;
- //
- // Update hotkey list field.
- //
- if (gBrowserSettingScope == SystemLevel || FormEditable) {
- UpdateHotkeyList();
- }
+ return Count * sizeof (CHAR16);
}
/**
+ This function displays the page frame.
- Initialize the SettingChangedFlag variable in the display form.
-
+ @param Selection Selection contains the information about
+ the Selection, form and formset to be displayed.
+ Selection action may be updated in retrieve callback.
**/
VOID
-UpdateDataChangedFlag (
- VOID
+DisplayPageFrame (
+ IN UI_MENU_SELECTION *Selection
)
{
- LIST_ENTRY *Link;
- FORM_BROWSER_FORMSET *LocalFormSet;
-
- gDisplayFormData.SettingChangedFlag = FALSE;
-
- if (IsNvUpdateRequiredForForm (gCurrentSelection->Form)) {
- gDisplayFormData.SettingChangedFlag = TRUE;
+ UINTN Index;
+ UINT8 Line;
+ UINT8 Alignment;
+ CHAR16 Character;
+ CHAR16 *Buffer;
+ CHAR16 *StrFrontPageBanner;
+ UINTN Row;
+ EFI_SCREEN_DESCRIPTOR LocalScreen;
+ UINT8 RowIdx;
+ UINT8 ColumnIdx;
+
+ ZeroMem (&LocalScreen, sizeof (EFI_SCREEN_DESCRIPTOR));
+ gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &LocalScreen.RightColumn, &LocalScreen.BottomRow);
+ ClearLines (0, LocalScreen.RightColumn, 0, LocalScreen.BottomRow, KEYHELP_BACKGROUND);
+
+ if (Selection->Form->ModalForm) {
return;
}
+ CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
+
//
- // Base on the system level to check whether need to show the NV flag.
- //
- switch (gBrowserSettingScope) {
- case SystemLevel:
- //
- // Check the maintain list to see whether there is any change.
- //
- Link = GetFirstNode (&gBrowserFormSetList);
- while (!IsNull (&gBrowserFormSetList, Link)) {
- LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
- if (IsNvUpdateRequiredForFormSet(LocalFormSet)) {
- gDisplayFormData.SettingChangedFlag = TRUE;
- return;
- }
- Link = GetNextNode (&gBrowserFormSetList, Link);
- }
- break;
+ // For now, allocate an arbitrarily long buffer
+ //
+ Buffer = AllocateZeroPool (0x10000);
+ ASSERT (Buffer != NULL);
- case FormSetLevel:
- if (IsNvUpdateRequiredForFormSet(gCurrentSelection->FormSet)) {
- gDisplayFormData.SettingChangedFlag = TRUE;
- return;
- }
- break;
+ Character = BOXDRAW_HORIZONTAL;
- default:
- break;
+ for (Index = 0; Index + 2 < (LocalScreen.RightColumn - LocalScreen.LeftColumn); Index++) {
+ Buffer[Index] = Character;
}
-}
-
-/**
-
- Initialize the Display form structure data.
-
-**/
-VOID
-InitializeDisplayFormData (
- VOID
- )
-{
- EFI_STATUS Status;
-
- gDisplayFormData.Signature = FORM_DISPLAY_ENGINE_FORM_SIGNATURE;
- gDisplayFormData.Version = FORM_DISPLAY_ENGINE_VERSION_1;
- gDisplayFormData.ImageId = 0;
- gDisplayFormData.AnimationId = 0;
-
- InitializeListHead (&gDisplayFormData.StatementListHead);
- InitializeListHead (&gDisplayFormData.StatementListOSF);
- InitializeListHead (&gDisplayFormData.HotKeyListHead);
-
- Status = gBS->CreateEvent (
- EVT_NOTIFY_WAIT,
- TPL_CALLBACK,
- SetupBrowserEmptyFunction,
- NULL,
- &mValueChangedEvent
- );
- ASSERT_EFI_ERROR (Status);
-}
-
-/**
- Free the kotkey info saved in form data.
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {
+ //
+ // ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);
+ //
+ ClearLines (
+ LocalScreen.LeftColumn,
+ LocalScreen.RightColumn,
+ LocalScreen.TopRow,
+ FRONT_PAGE_HEADER_HEIGHT - 1 + LocalScreen.TopRow,
+ BANNER_TEXT | BANNER_BACKGROUND
+ );
+ //
+ // for (Line = 0; Line < BANNER_HEIGHT; Line++) {
+ //
+ for (Line = (UINT8) LocalScreen.TopRow; Line < BANNER_HEIGHT + (UINT8) LocalScreen.TopRow; Line++) {
+ //
+ // for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {
+ //
+ for (Alignment = (UINT8) LocalScreen.LeftColumn;
+ Alignment < BANNER_COLUMNS + (UINT8) LocalScreen.LeftColumn;
+ Alignment++
+ ) {
+ RowIdx = (UINT8) (Line - (UINT8) LocalScreen.TopRow);
+ ColumnIdx = (UINT8) (Alignment - (UINT8) LocalScreen.LeftColumn);
+
+ ASSERT (RowIdx < BANNER_HEIGHT);
+ ASSERT (ColumnIdx < BANNER_COLUMNS);
+
+ if (gBannerData->Banner[RowIdx][ColumnIdx] != 0x0000) {
+ StrFrontPageBanner = GetToken (
+ gBannerData->Banner[RowIdx][ColumnIdx],
+ gFrontPageHandle
+ );
+ } else {
+ continue;
+ }
-**/
-VOID
-FreeHotkeyList (
- VOID
- )
-{
- BROWSER_HOT_KEY *HotKey;
- LIST_ENTRY *Link;
+ switch (Alignment - LocalScreen.LeftColumn) {
+ case 0:
+ //
+ // Handle left column
+ //
+ PrintStringAt (LocalScreen.LeftColumn + BANNER_LEFT_COLUMN_INDENT, Line, StrFrontPageBanner);
+ break;
- while (!IsListEmpty (&gDisplayFormData.HotKeyListHead)) {
- Link = GetFirstNode (&gDisplayFormData.HotKeyListHead);
- HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
+ case 1:
+ //
+ // Handle center column
+ //
+ PrintStringAt (
+ LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
+ Line,
+ StrFrontPageBanner
+ );
+ break;
- RemoveEntryList (&HotKey->Link);
+ case 2:
+ //
+ // Handle right column
+ //
+ PrintStringAt (
+ LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,
+ Line,
+ StrFrontPageBanner
+ );
+ break;
+ }
- FreePool (HotKey->KeyData);
- FreePool (HotKey->HelpString);
- FreePool (HotKey);
+ FreePool (StrFrontPageBanner);
+ }
+ }
}
-}
-/**
+ ClearLines (
+ LocalScreen.LeftColumn,
+ LocalScreen.RightColumn,
+ LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight,
+ LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,
+ KEYHELP_TEXT | KEYHELP_BACKGROUND
+ );
+
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {
+ ClearLines (
+ LocalScreen.LeftColumn,
+ LocalScreen.RightColumn,
+ LocalScreen.TopRow,
+ LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1,
+ TITLE_TEXT | TITLE_BACKGROUND
+ );
+ //
+ // Print Top border line
+ // +------------------------------------------------------------------------------+
+ // ? ?
+ // +------------------------------------------------------------------------------+
+ //
+ Character = BOXDRAW_DOWN_RIGHT;
+
+ PrintChar (Character);
+ PrintString (Buffer);
+
+ Character = BOXDRAW_DOWN_LEFT;
+ PrintChar (Character);
+
+ Character = BOXDRAW_VERTICAL;
+ for (Row = LocalScreen.TopRow + 1; Row <= LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {
+ PrintCharAt (LocalScreen.LeftColumn, Row, Character);
+ PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
+ }
- Update the Display form structure data.
+ Character = BOXDRAW_UP_RIGHT;
+ PrintCharAt (LocalScreen.LeftColumn, LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);
+ PrintString (Buffer);
-**/
-VOID
-UpdateDisplayFormData (
- VOID
- )
-{
- gDisplayFormData.FormTitle = gCurrentSelection->Form->FormTitle;
- gDisplayFormData.FormId = gCurrentSelection->FormId;
- gDisplayFormData.HiiHandle = gCurrentSelection->Handle;
- CopyGuid (&gDisplayFormData.FormSetGuid, &gCurrentSelection->FormSetGuid);
+ Character = BOXDRAW_UP_LEFT;
+ PrintChar (Character);
- gDisplayFormData.Attribute = 0;
- gDisplayFormData.Attribute |= gCurrentSelection->Form->ModalForm ? HII_DISPLAY_MODAL : 0;
- gDisplayFormData.Attribute |= gCurrentSelection->Form->Locked ? HII_DISPLAY_LOCK : 0;
+ if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {
+ //
+ // Print Bottom border line
+ // +------------------------------------------------------------------------------+
+ // ? ?
+ // +------------------------------------------------------------------------------+
+ //
+ Character = BOXDRAW_DOWN_RIGHT;
+ PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight, Character);
+
+ PrintString (Buffer);
+
+ Character = BOXDRAW_DOWN_LEFT;
+ PrintChar (Character);
+ Character = BOXDRAW_VERTICAL;
+ for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;
+ Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;
+ Row++
+ ) {
+ PrintCharAt (LocalScreen.LeftColumn, Row, Character);
+ PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
+ }
- gDisplayFormData.FormRefreshEvent = NULL;
- gDisplayFormData.HighLightedStatement = NULL;
+ Character = BOXDRAW_UP_RIGHT;
+ PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character);
- gDisplayFormData.BrowserStatus = gBrowserStatus;
- gDisplayFormData.ErrorString = gErrorInfo;
+ PrintString (Buffer);
- gBrowserStatus = BROWSER_SUCCESS;
- gErrorInfo = NULL;
+ Character = BOXDRAW_UP_LEFT;
+ PrintChar (Character);
+ }
+ }
- UpdateDataChangedFlag ();
+ FreePool (Buffer);
- AddStatementToDisplayForm ();
}
+
/**
+ Evaluate all expressions in a Form.
- Free the Display Statement structure data.
+ @param FormSet FormSet this Form belongs to.
+ @param Form The Form.
- @param StatementList Point to the statement list which need to be free.
+ @retval EFI_SUCCESS The expression evaluated successfuly
**/
-VOID
-FreeStatementData (
- LIST_ENTRY *StatementList
+EFI_STATUS
+EvaluateFormExpressions (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN FORM_BROWSER_FORM *Form
)
{
- LIST_ENTRY *Link;
- LIST_ENTRY *OptionLink;
- FORM_DISPLAY_ENGINE_STATEMENT *Statement;
- DISPLAY_QUESTION_OPTION *Option;
+ EFI_STATUS Status;
+ LIST_ENTRY *Link;
+ FORM_EXPRESSION *Expression;
- //
- // Free Statements/Questions
- //
- while (!IsListEmpty (StatementList)) {
- Link = GetFirstNode (StatementList);
- Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
+ Link = GetFirstNode (&Form->ExpressionListHead);
+ while (!IsNull (&Form->ExpressionListHead, Link)) {
+ Expression = FORM_EXPRESSION_FROM_LINK (Link);
+ Link = GetNextNode (&Form->ExpressionListHead, Link);
- //
- // Free Options List
- //
- while (!IsListEmpty (&Statement->OptionListHead)) {
- OptionLink = GetFirstNode (&Statement->OptionListHead);
- Option = DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink);
- RemoveEntryList (&Option->Link);
- FreePool (Option);
+ if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF ||
+ Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF ||
+ Expression->Type == EFI_HII_EXPRESSION_WRITE ||
+ (Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) {
+ //
+ // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.
+ //
+ continue;
}
- //
- // Free nest statement List
- //
- if (!IsListEmpty (&Statement->NestStatementList)) {
- FreeStatementData(&Statement->NestStatementList);
+ Status = EvaluateExpression (FormSet, Form, Expression);
+ if (EFI_ERROR (Status)) {
+ return Status;
}
-
- RemoveEntryList (&Statement->DisplayLink);
- FreePool (Statement);
}
+
+ return EFI_SUCCESS;
}
-/**
+/*
++------------------------------------------------------------------------------+
+? Setup Page ?
++------------------------------------------------------------------------------+
+
- Free the Display form structure data.
-**/
-VOID
-FreeDisplayFormData (
- VOID
- )
-{
- FreeStatementData (&gDisplayFormData.StatementListHead);
- FreeStatementData (&gDisplayFormData.StatementListOSF);
- FreeRefreshEvent();
- FreeHotkeyList();
-}
-/**
- Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
- @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
- @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
-**/
-FORM_BROWSER_STATEMENT *
-GetBrowserStatement (
- IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement
- )
-{
- FORM_BROWSER_STATEMENT *Statement;
- LIST_ENTRY *Link;
- Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);
- while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {
- Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
- if (Statement->OpCode == DisplayStatement->OpCode) {
- return Statement;
- }
- Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);
- }
- return NULL;
-}
+
+
+
++------------------------------------------------------------------------------+
+?F1=Scroll Help F9=Reset to Defaults F10=Save and Exit ?
+| ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Discard Changes |
++------------------------------------------------------------------------------+
+*/
/**
- Process the action request in user input.
- @param Action The user input action request info.
- @param DefaultId The user input default Id info.
+ Display form and wait for user to select one menu option, then return it.
+ @param Selection On input, Selection tell setup browser the information
+ about the Selection, form and formset to be displayed.
+ On output, Selection return the screen item that is selected
+ by user.
@retval EFI_SUCESSS This function always return successfully for now.
**/
-EFI_STATUS
-ProcessAction (
- IN UINT32 Action,
- IN UINT16 DefaultId
+EFI_STATUS
+DisplayForm (
+ IN OUT UI_MENU_SELECTION *Selection
)
{
- EFI_STATUS Status;
-
- //
- // This is caused by use press ESC, and it should not combine with other action type.
- //
- if ((Action & BROWSER_ACTION_FORM_EXIT) == BROWSER_ACTION_FORM_EXIT) {
- FindNextMenu (gCurrentSelection, FormLevel);
- return EFI_SUCCESS;
- }
+ CHAR16 *StringPtr;
+ UINT16 MenuItemCount;
+ EFI_HII_HANDLE Handle;
+ EFI_SCREEN_DESCRIPTOR LocalScreen;
+ UINT16 Width;
+ UINTN ArrayEntry;
+ CHAR16 *OutputString;
+ LIST_ENTRY *Link;
+ FORM_BROWSER_STATEMENT *Statement;
+ UINT16 NumberOfLines;
+ EFI_STATUS Status;
+ UI_MENU_OPTION *MenuOption;
+ UINT16 GlyphWidth;
- //
- // Below is normal hotkey trigged action, these action maybe combine with each other.
- //
- if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {
- DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
- }
+ Handle = Selection->Handle;
+ MenuItemCount = 0;
+ ArrayEntry = 0;
+ OutputString = NULL;
- if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
- ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);
- }
+ UiInitMenu ();
- if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {
- Status = SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
- if (EFI_ERROR (Status)) {
- gBrowserStatus = BROWSER_SUBMIT_FAIL;
- }
- }
+ CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
- if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {
- gResetRequired = TRUE;
- }
+ StringPtr = GetToken (Selection->Form->FormTitle, Handle);
- if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {
- //
- // Form Exit without saving, Similar to ESC Key.
- // FormSet Exit without saving, Exit SendForm.
- // System Exit without saving, CallExitHandler and Exit SendForm.
- //
- DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
- if (gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) {
- FindNextMenu (gCurrentSelection, gBrowserSettingScope);
- } else if (gBrowserSettingScope == SystemLevel) {
- if (ExitHandlerFunction != NULL) {
- ExitHandlerFunction ();
- }
- gCurrentSelection->Action = UI_ACTION_EXIT;
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {
+ if (Selection->Form->ModalForm) {
+ gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | EFI_BACKGROUND_BLACK);
+ } else {
+ gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);
}
+ PrintStringAt (
+ (LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,
+ LocalScreen.TopRow + 1,
+ StringPtr
+ );
}
- return EFI_SUCCESS;
-}
-
-
-/**
- Find HII Handle in the HII database associated with given Device Path.
-
- If DevicePath is NULL, then ASSERT.
-
- @param DevicePath Device Path associated with the HII package list
- handle.
-
- @retval Handle HII package list Handle associated with the Device
- Path.
- @retval NULL Hii Package list handle is not found.
-
-**/
-EFI_HII_HANDLE
-EFIAPI
-DevicePathToHiiHandle (
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
- UINTN BufferSize;
- UINTN HandleCount;
- UINTN Index;
- EFI_HANDLE Handle;
- EFI_HANDLE DriverHandle;
- EFI_HII_HANDLE *HiiHandles;
- EFI_HII_HANDLE HiiHandle;
-
- ASSERT (DevicePath != NULL);
-
- TmpDevicePath = DevicePath;
//
- // Locate Device Path Protocol handle buffer
+ // Remove Buffer allocated for StringPtr after it has been used.
//
- Status = gBS->LocateDevicePath (
- &gEfiDevicePathProtocolGuid,
- &TmpDevicePath,
- &DriverHandle
- );
- if (EFI_ERROR (Status) || !IsDevicePathEnd (TmpDevicePath)) {
- return NULL;
- }
+ FreePool (StringPtr);
//
- // Retrieve all HII Handles from HII database
+ // Evaluate all the Expressions in this Form
//
- BufferSize = 0x1000;
- HiiHandles = AllocatePool (BufferSize);
- ASSERT (HiiHandles != NULL);
- Status = mHiiDatabase->ListPackageLists (
- mHiiDatabase,
- EFI_HII_PACKAGE_TYPE_ALL,
- NULL,
- &BufferSize,
- HiiHandles
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FreePool (HiiHandles);
- HiiHandles = AllocatePool (BufferSize);
- ASSERT (HiiHandles != NULL);
-
- Status = mHiiDatabase->ListPackageLists (
- mHiiDatabase,
- EFI_HII_PACKAGE_TYPE_ALL,
- NULL,
- &BufferSize,
- HiiHandles
- );
- }
-
+ Status = EvaluateFormExpressions (Selection->FormSet, Selection->Form);
if (EFI_ERROR (Status)) {
- FreePool (HiiHandles);
- return NULL;
- }
-
- //
- // Search Hii Handle by Driver Handle
- //
- HiiHandle = NULL;
- HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
- for (Index = 0; Index < HandleCount; Index++) {
- Status = mHiiDatabase->GetPackageListHandle (
- mHiiDatabase,
- HiiHandles[Index],
- &Handle
- );
- if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
- HiiHandle = HiiHandles[Index];
- break;
- }
+ return Status;
}
- FreePool (HiiHandles);
- return HiiHandle;
-}
-
-/**
- Find HII Handle in the HII database associated with given form set guid.
-
- If FormSetGuid is NULL, then ASSERT.
-
- @param ComparingGuid FormSet Guid associated with the HII package list
- handle.
+ Selection->FormEditable = FALSE;
+ Link = GetFirstNode (&Selection->Form->StatementListHead);
+ while (!IsNull (&Selection->Form->StatementListHead, Link)) {
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
- @retval Handle HII package list Handle associated with the Device
- Path.
- @retval NULL Hii Package list handle is not found.
+ if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) <= ExpressGrayOut) {
+ StringPtr = GetToken (Statement->Prompt, Handle);
+ ASSERT (StringPtr != NULL);
-**/
-EFI_HII_HANDLE
-FormSetGuidToHiiHandle (
- EFI_GUID *ComparingGuid
- )
-{
- EFI_HII_HANDLE *HiiHandles;
- UINTN Index;
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
- UINTN BufferSize;
- UINT32 Offset;
- UINT32 Offset2;
- UINT32 PackageListLength;
- EFI_HII_PACKAGE_HEADER PackageHeader;
- UINT8 *Package;
- UINT8 *OpCodeData;
- EFI_STATUS Status;
- EFI_HII_HANDLE HiiHandle;
-
- ASSERT (ComparingGuid != NULL);
-
- HiiHandle = NULL;
- //
- // Get all the Hii handles
- //
- HiiHandles = HiiGetHiiHandles (NULL);
- ASSERT (HiiHandles != NULL);
+ Width = GetWidth (Statement, Handle);
- //
- // Search for formset of each class type
- //
- for (Index = 0; HiiHandles[Index] != NULL; Index++) {
- BufferSize = 0;
- HiiPackageList = NULL;
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- HiiPackageList = AllocatePool (BufferSize);
- ASSERT (HiiPackageList != NULL);
-
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
- }
- if (EFI_ERROR (Status) || HiiPackageList == NULL) {
- return NULL;
- }
+ NumberOfLines = 1;
+ ArrayEntry = 0;
+ GlyphWidth = 1;
+ for (; GetLineByWidth (StringPtr, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&StringPtr[ArrayEntry]) != 0) {
+ NumberOfLines++;
+ }
- //
- // Get Form package from this HII package List
- //
- Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
- Offset2 = 0;
- CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
+ FreePool (OutputString);
+ }
- while (Offset < PackageListLength) {
- Package = ((UINT8 *) HiiPackageList) + Offset;
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ //
+ // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
+ // it in UiFreeMenu.
+ //
+ MenuOption = UiAddMenuOption (StringPtr, Selection->Handle, Selection->Form, Statement, NumberOfLines, MenuItemCount);
+ MenuItemCount++;
- if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
+ if (MenuOption->IsQuestion && !MenuOption->ReadOnly) {
//
- // Search FormSet in this Form Package
+ // At least one item is not readonly, this Form is considered as editable
//
- Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
- while (Offset2 < PackageHeader.Length) {
- OpCodeData = Package + Offset2;
-
- if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
- //
- // Try to compare against formset GUID
- //
- if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
- HiiHandle = HiiHandles[Index];
- break;
- }
- }
-
- Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
- }
- }
- if (HiiHandle != NULL) {
- break;
+ Selection->FormEditable = TRUE;
}
- Offset += PackageHeader.Length;
}
-
- FreePool (HiiPackageList);
- if (HiiHandle != NULL) {
- break;
- }
+
+ Link = GetNextNode (&Selection->Form->StatementListHead, Link);
}
- FreePool (HiiHandles);
+ Status = UiDisplayMenu (Selection);
+
+ UiFreeMenu ();
- return HiiHandle;
+ return Status;
}
/**
- check how to process the changed data in current form or form set.
-
- @param Selection On input, Selection tell setup browser the information
- about the Selection, form and formset to be displayed.
- On output, Selection return the screen item that is selected
- by user.
-
- @param Scope Data save or discard scope, form or formset.
+ Initialize the HII String Token to the correct values.
- @retval TRUE Success process the changed data, will return to the parent form.
- @retval FALSE Reject to process the changed data, will stay at current form.
**/
-BOOLEAN
-ProcessChangedData (
- IN OUT UI_MENU_SELECTION *Selection,
- IN BROWSER_SETTING_SCOPE Scope
+VOID
+InitializeBrowserStrings (
+ VOID
)
{
- BOOLEAN RetValue;
-
- RetValue = TRUE;
- switch (mFormDisplay->ConfirmDataChange()) {
- case BROWSER_ACTION_DISCARD:
- DiscardForm (Selection->FormSet, Selection->Form, Scope);
- break;
-
- case BROWSER_ACTION_SUBMIT:
- SubmitForm (Selection->FormSet, Selection->Form, Scope);
- break;
-
- case BROWSER_ACTION_NONE:
- RetValue = FALSE;
- break;
-
- default:
- //
- // if Invalid value return, process same as BROWSER_ACTION_NONE.
- //
- RetValue = FALSE;
- break;
- }
-
- return RetValue;
+ gEnterString = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle);
+ gEnterCommitString = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle);
+ gEnterEscapeString = GetToken (STRING_TOKEN (ENTER_ESCAPE_STRING), gHiiHandle);
+ gEscapeString = GetToken (STRING_TOKEN (ESCAPE_STRING), gHiiHandle);
+ gMoveHighlight = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle);
+ gMakeSelection = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle);
+ gDecNumericInput = GetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), gHiiHandle);
+ gHexNumericInput = GetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), gHiiHandle);
+ gToggleCheckBox = GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), gHiiHandle);
+ gPromptForData = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);
+ gPromptForPassword = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);
+ gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);
+ gConfirmPassword = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);
+ gConfirmError = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);
+ gPassowordInvalid = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);
+ gPressEnter = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);
+ gEmptyString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
+ gAreYouSure = GetToken (STRING_TOKEN (ARE_YOU_SURE), gHiiHandle);
+ gYesResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);
+ gNoResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);
+ gMiniString = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);
+ gPlusString = GetToken (STRING_TOKEN (PLUS_STRING), gHiiHandle);
+ gMinusString = GetToken (STRING_TOKEN (MINUS_STRING), gHiiHandle);
+ gAdjustNumber = GetToken (STRING_TOKEN (ADJUST_NUMBER), gHiiHandle);
+ gSaveChanges = GetToken (STRING_TOKEN (SAVE_CHANGES), gHiiHandle);
+ gOptionMismatch = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);
+ gFormSuppress = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);
+ gProtocolNotFound = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);
+ return ;
}
/**
- Find parent formset menu(the first menu which has different formset) for current menu.
- If not find, just return to the first menu.
-
- @param Selection The selection info.
+ Free up the resource allocated for all strings required
+ by Setup Browser.
**/
VOID
-FindParentFormSet (
- IN OUT UI_MENU_SELECTION *Selection
+FreeBrowserStrings (
+ VOID
)
{
- FORM_ENTRY_INFO *CurrentMenu;
- FORM_ENTRY_INFO *ParentMenu;
-
- CurrentMenu = Selection->CurrentMenu;
- ParentMenu = UiFindParentMenu(CurrentMenu);
-
- //
- // Find a menu which has different formset guid with current.
- //
- while (ParentMenu != NULL && CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {
- CurrentMenu = ParentMenu;
- ParentMenu = UiFindParentMenu(CurrentMenu);
- }
-
- if (ParentMenu != NULL) {
- CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));
- Selection->Handle = ParentMenu->HiiHandle;
- Selection->FormId = ParentMenu->FormId;
- Selection->QuestionId = ParentMenu->QuestionId;
- } else {
- Selection->FormId = CurrentMenu->FormId;
- Selection->QuestionId = CurrentMenu->QuestionId;
- }
-
- Selection->Statement = NULL;
+ FreePool (gEnterString);
+ FreePool (gEnterCommitString);
+ FreePool (gEnterEscapeString);
+ FreePool (gEscapeString);
+ FreePool (gMoveHighlight);
+ FreePool (gMakeSelection);
+ FreePool (gDecNumericInput);
+ FreePool (gHexNumericInput);
+ FreePool (gToggleCheckBox);
+ FreePool (gPromptForData);
+ FreePool (gPromptForPassword);
+ FreePool (gPromptForNewPassword);
+ FreePool (gConfirmPassword);
+ FreePool (gPassowordInvalid);
+ FreePool (gConfirmError);
+ FreePool (gPressEnter);
+ FreePool (gEmptyString);
+ FreePool (gAreYouSure);
+ FreePool (gYesResponse);
+ FreePool (gNoResponse);
+ FreePool (gMiniString);
+ FreePool (gPlusString);
+ FreePool (gMinusString);
+ FreePool (gAdjustNumber);
+ FreePool (gSaveChanges);
+ FreePool (gOptionMismatch);
+ FreePool (gFormSuppress);
+ FreePool (gProtocolNotFound);
+ return ;
}
/**
- Process the goto op code, update the info in the selection structure.
-
- @param Statement The statement belong to goto op code.
- @param Selection The selection info.
+ Show all registered HotKey help strings on bottom Rows.
- @retval EFI_SUCCESS The menu process successfully.
- @return Other value if the process failed.
**/
-EFI_STATUS
-ProcessGotoOpCode (
- IN OUT FORM_BROWSER_STATEMENT *Statement,
- IN OUT UI_MENU_SELECTION *Selection
+VOID
+PrintHotKeyHelpString (
+ VOID
)
{
- CHAR16 *StringPtr;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- FORM_BROWSER_FORM *RefForm;
- EFI_STATUS Status;
- EFI_HII_HANDLE HiiHandle;
-
- Status = EFI_SUCCESS;
- StringPtr = NULL;
- HiiHandle = NULL;
+ UINTN CurrentCol;
+ UINTN CurrentRow;
+ UINTN BottomRowOfHotKeyHelp;
+ UINTN ColumnWidth;
+ UINTN Index;
+ EFI_SCREEN_DESCRIPTOR LocalScreen;
+ LIST_ENTRY *Link;
+ BROWSER_HOT_KEY *HotKey;
- //
- // Prepare the device path check, get the device path info first.
- //
- if (Statement->HiiValue.Value.ref.DevicePath != 0) {
- StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);
- }
+ CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
+ ColumnWidth = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
+ BottomRowOfHotKeyHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3;
//
- // Check whether the device path string is a valid string.
+ // Calculate total number of Register HotKeys.
//
- if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL) {
- if (Selection->Form->ModalForm) {
- return Status;
+ Index = 0;
+ Link = GetFirstNode (&gBrowserHotKeyList);
+ while (!IsNull (&gBrowserHotKeyList, Link)) {
+ HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
+ //
+ // Help string can't exceed ColumnWidth. One Row will show three Help information.
+ //
+ if (StrLen (HotKey->HelpString) > ColumnWidth) {
+ HotKey->HelpString[ColumnWidth] = L'\0';
}
-
//
- // Goto another Hii Package list
+ // Calculate help information Column and Row.
//
- if (mPathFromText != NULL) {
- DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);
- if (DevicePath != NULL) {
- HiiHandle = DevicePathToHiiHandle (DevicePath);
- FreePool (DevicePath);
- }
- FreePool (StringPtr);
+ if ((Index % 3) != 2) {
+ CurrentCol = LocalScreen.LeftColumn + (2 - Index % 3) * ColumnWidth;
} else {
- //
- // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
- //
- gBrowserStatus = BROWSER_PROTOCOL_NOT_FOUND;
- FreePool (StringPtr);
- return Status;
- }
-
- if (HiiHandle != Selection->Handle) {
- //
- // Goto another Formset, check for uncommitted data
- //
- if ((gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) &&
- IsNvUpdateRequiredForFormSet(Selection->FormSet)) {
- if (!ProcessChangedData(Selection, FormSetLevel)) {
- return EFI_SUCCESS;
- }
- }
- }
-
- Selection->Action = UI_ACTION_REFRESH_FORMSET;
- Selection->Handle = HiiHandle;
- if (Selection->Handle == NULL) {
- //
- // If target Hii Handle not found, exit current formset.
- //
- FindParentFormSet(Selection);
- return EFI_SUCCESS;
- }
-
- CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
- Selection->FormId = Statement->HiiValue.Value.ref.FormId;
- Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
- } else if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {
- if (Selection->Form->ModalForm) {
- return Status;
- }
- if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &Selection->FormSetGuid)) {
- //
- // Goto another Formset, check for uncommitted data
- //
- if ((gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) &&
- IsNvUpdateRequiredForFormSet(Selection->FormSet)) {
- if (!ProcessChangedData(Selection, FormSetLevel)) {
- return EFI_SUCCESS;
- }
- }
- }
-
- Selection->Action = UI_ACTION_REFRESH_FORMSET;
- Selection->Handle = FormSetGuidToHiiHandle(&Statement->HiiValue.Value.ref.FormSetGuid);
- if (Selection->Handle == NULL) {
- //
- // If target Hii Handle not found, exit current formset.
- //
- FindParentFormSet(Selection);
- return EFI_SUCCESS;
+ CurrentCol = LocalScreen.LeftColumn + 2;
}
-
- CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
- Selection->FormId = Statement->HiiValue.Value.ref.FormId;
- Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
- } else if (Statement->HiiValue.Value.ref.FormId != 0) {
+ CurrentRow = BottomRowOfHotKeyHelp - Index / 3;
//
- // Goto another Form, check for uncommitted data
+ // Print HotKey help string on bottom Row.
//
- if (Statement->HiiValue.Value.ref.FormId != Selection->FormId) {
- if ((gBrowserSettingScope == FormLevel && IsNvUpdateRequiredForForm(Selection->Form))) {
- if (!ProcessChangedData (Selection, FormLevel)) {
- return EFI_SUCCESS;
- }
- }
- }
-
- RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);
- if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {
- if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {
- //
- // Form is suppressed.
- //
- gBrowserStatus = BROWSER_FORM_SUPPRESS;
- return EFI_SUCCESS;
- }
- }
+ PrintStringAt (CurrentCol, CurrentRow, HotKey->HelpString);
- Selection->FormId = Statement->HiiValue.Value.ref.FormId;
- Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
- } else if (Statement->HiiValue.Value.ref.QuestionId != 0) {
- Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
+ //
+ // Get Next Hot Key.
+ //
+ Link = GetNextNode (&gBrowserHotKeyList, Link);
+ Index ++;
}
-
- return Status;
+
+ return;
}
-
/**
- Process Question Config.
+ Update key's help imformation.
- @param Selection The UI menu selection.
- @param Question The Question to be peocessed.
-
- @retval EFI_SUCCESS Question Config process success.
- @retval Other Question Config process fail.
+ @param Selection Tell setup browser the information about the Selection
+ @param MenuOption The Menu option
+ @param Selected Whether or not a tag be selected
**/
-EFI_STATUS
-ProcessQuestionConfig (
- IN UI_MENU_SELECTION *Selection,
- IN FORM_BROWSER_STATEMENT *Question
+VOID
+UpdateKeyHelp (
+ IN UI_MENU_SELECTION *Selection,
+ IN UI_MENU_OPTION *MenuOption,
+ IN BOOLEAN Selected
)
{
- EFI_STATUS Status;
- CHAR16 *ConfigResp;
- CHAR16 *Progress;
- EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
-
- if (Question->QuestionConfig == 0) {
- return EFI_SUCCESS;
- }
+ UINTN SecCol;
+ UINTN ThdCol;
+ UINTN LeftColumnOfHelp;
+ UINTN RightColumnOfHelp;
+ UINTN TopRowOfHelp;
+ UINTN BottomRowOfHelp;
+ UINTN StartColumnOfHelp;
+ EFI_SCREEN_DESCRIPTOR LocalScreen;
+ FORM_BROWSER_STATEMENT *Statement;
- //
- // Get <ConfigResp>
- //
- ConfigResp = GetToken (Question->QuestionConfig, Selection->FormSet->HiiHandle);
- if (ConfigResp == NULL) {
- return EFI_NOT_FOUND;
- }
+ gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
- //
- // Send config to Configuration Driver
- //
- ConfigAccess = Selection->FormSet->ConfigAccess;
- if (ConfigAccess == NULL) {
- return EFI_UNSUPPORTED;
+ if (Selection->Form->ModalForm) {
+ return;
}
- Status = ConfigAccess->RouteConfig (
- ConfigAccess,
- ConfigResp,
- &Progress
- );
-
- return Status;
-}
-
-/**
-
- Process the user input data.
- @param UserInput The user input data.
- @param ChangeHighlight Whether need to change the highlight statement.
+ CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
- @retval EFI_SUCESSS This function always return successfully for now.
+ SecCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
+ ThdCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3 * 2;
-**/
-EFI_STATUS
-ProcessUserInput (
- IN USER_INPUT *UserInput,
- IN BOOLEAN ChangeHighlight
- )
-{
- EFI_STATUS Status;
- FORM_BROWSER_STATEMENT *Statement;
+ StartColumnOfHelp = LocalScreen.LeftColumn + 2;
+ LeftColumnOfHelp = LocalScreen.LeftColumn + 1;
+ RightColumnOfHelp = LocalScreen.RightColumn - 2;
+ TopRowOfHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;
+ BottomRowOfHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;
- Status = EFI_SUCCESS;
-
- //
- // When Exit from FormDisplay function, one of the below two cases must be true.
- //
- ASSERT (UserInput->Action != 0 || UserInput->SelectedStatement != NULL);
-
- //
- // Remove the last highligh question id, this id will update when show next form.
- //
- gCurrentSelection->QuestionId = 0;
-
- //
- // First process the Action field in USER_INPUT.
- //
- if (UserInput->Action != 0) {
- Status = ProcessAction (UserInput->Action, UserInput->DefaultId);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Clear the highlight info.
- //
- gCurrentSelection->Statement = NULL;
+ Statement = MenuOption->ThisTag;
+ switch (Statement->Operand) {
+ case EFI_IFR_ORDERED_LIST_OP:
+ case EFI_IFR_ONE_OF_OP:
+ case EFI_IFR_NUMERIC_OP:
+ case EFI_IFR_TIME_OP:
+ case EFI_IFR_DATE_OP:
+ ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
- if (UserInput->SelectedStatement != NULL) {
- Statement = GetBrowserStatement(UserInput->SelectedStatement);
- ASSERT (Statement != NULL);
- //
- // Save the current highlight menu in the menu history data.
- // which will be used when later browse back to this form.
- //
- gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;
+ if (!Selected) {
//
- // For statement like text, actio, it not has question id.
- // So use FakeQuestionId to save the question.
+ // On system setting, HotKey will show on every form.
//
- if (gCurrentSelection->CurrentMenu->QuestionId == 0) {
- mCurFakeQestId = Statement->FakeQuestionId;
- } else {
- mCurFakeQestId = 0;
+ if (gBrowserSettingScope == SystemLevel ||
+ (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
+ PrintHotKeyHelpString ();
}
- }
- } else {
- Statement = GetBrowserStatement(UserInput->SelectedStatement);
- ASSERT (Statement != NULL);
- gCurrentSelection->Statement = Statement;
+ if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {
+ PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
+ }
- if (ChangeHighlight) {
- //
- // This question is the current user select one,record it and later
- // show it as the highlight question.
- //
- gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;
- //
- // For statement like text, actio, it not has question id.
- // So use FakeQuestionId to save the question.
- //
- if (gCurrentSelection->CurrentMenu->QuestionId == 0) {
- mCurFakeQestId = Statement->FakeQuestionId;
+ if ((Statement->Operand == EFI_IFR_DATE_OP) ||
+ (Statement->Operand == EFI_IFR_TIME_OP)) {
+ PrintAt (
+ StartColumnOfHelp,
+ BottomRowOfHelp,
+ L"%c%c%c%c%s",
+ ARROW_UP,
+ ARROW_DOWN,
+ ARROW_RIGHT,
+ ARROW_LEFT,
+ gMoveHighlight
+ );
+ PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
+ PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);
} else {
- mCurFakeQestId = 0;
+ PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
+ if (Statement->Operand == EFI_IFR_NUMERIC_OP && Statement->Step != 0) {
+ PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);
+ }
+ PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
}
- }
+ } else {
+ PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString);
- switch (Statement->Operand) {
- case EFI_IFR_REF_OP:
- Status = ProcessGotoOpCode(Statement, gCurrentSelection);
- break;
-
- case EFI_IFR_ACTION_OP:
- //
- // Process the Config string <ConfigResp>
//
- Status = ProcessQuestionConfig (gCurrentSelection, Statement);
- break;
-
- case EFI_IFR_RESET_BUTTON_OP:
+ // If it is a selected numeric with manual input, display different message
//
- // Reset Question to default value specified by DefaultId
- //
- Status = ExtractDefault (gCurrentSelection->FormSet, NULL, Statement->DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE);
- break;
-
- default:
- switch (Statement->Operand) {
- case EFI_IFR_STRING_OP:
- DeleteString(Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);
- Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;
- CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);
- FreePool (UserInput->InputValue.Buffer);
- break;
-
- case EFI_IFR_PASSWORD_OP:
- if (UserInput->InputValue.Buffer == NULL) {
- //
- // User not input new password, just return.
- //
- break;
- }
-
- DeleteString(Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);
- Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;
- CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);
- FreePool (UserInput->InputValue.Buffer);
- //
- // Two password match, send it to Configuration Driver
- //
- if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- PasswordCheck (NULL, UserInput->SelectedStatement, (CHAR16 *) Statement->BufferValue);
- //
- // Clean the value after saved it.
- //
- ZeroMem (Statement->BufferValue, (UINTN) UserInput->InputValue.BufferLen);
- HiiSetString (gCurrentSelection->FormSet->HiiHandle, Statement->HiiValue.Value.string, (CHAR16*)Statement->BufferValue, NULL);
- } else {
- SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);
- }
- break;
-
- case EFI_IFR_ORDERED_LIST_OP:
- CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, UserInput->InputValue.BufferLen);
- break;
-
- default:
- CopyMem (&Statement->HiiValue, &UserInput->InputValue, sizeof (EFI_HII_VALUE));
- break;
- }
- if (Statement->Operand != EFI_IFR_PASSWORD_OP) {
- SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);
+ if ((Statement->Operand == EFI_IFR_NUMERIC_OP) ||
+ (Statement->Operand == EFI_IFR_DATE_OP) ||
+ (Statement->Operand == EFI_IFR_TIME_OP)) {
+ PrintStringAt (
+ SecCol,
+ TopRowOfHelp,
+ ((Statement->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX) ? gHexNumericInput : gDecNumericInput
+ );
+ } else if (Statement->Operand != EFI_IFR_ORDERED_LIST_OP) {
+ PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
}
- break;
- }
- }
-
- return Status;
-}
-
-/**
- Display form and wait for user to select one menu option, then return it.
-
- @retval EFI_SUCESSS This function always return successfully for now.
-
-**/
-EFI_STATUS
-DisplayForm (
- VOID
- )
-{
- EFI_STATUS Status;
- USER_INPUT UserInput;
- FORM_ENTRY_INFO *CurrentMenu;
- BOOLEAN ChangeHighlight;
+ if (Statement->Operand == EFI_IFR_ORDERED_LIST_OP) {
+ PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString);
+ PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);
+ }
- ZeroMem (&UserInput, sizeof (USER_INPUT));
+ PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);
+ }
+ break;
- //
- // Update the menu history data.
- //
- CurrentMenu = UiFindMenuList (gCurrentSelection->Handle, &gCurrentSelection->FormSetGuid, gCurrentSelection->FormId);
- if (CurrentMenu == NULL) {
- //
- // Current menu not found, add it to the menu tree
- //
- CurrentMenu = UiAddMenuList (gCurrentSelection->Handle, &gCurrentSelection->FormSetGuid,
- gCurrentSelection->FormId, gCurrentSelection->QuestionId);
- ASSERT (CurrentMenu != NULL);
- }
- gCurrentSelection->CurrentMenu = CurrentMenu;
+ case EFI_IFR_CHECKBOX_OP:
+ ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
- //
- // Find currrent highlight statement.
- //
- if (gCurrentSelection->QuestionId == 0) {
//
- // Highlight not specified, fetch it from cached menu
+ // On system setting, HotKey will show on every form.
//
- gCurrentSelection->QuestionId = CurrentMenu->QuestionId;
- }
-
- //
- // Evaluate all the Expressions in this Form
- //
- Status = EvaluateFormExpressions (gCurrentSelection->FormSet, gCurrentSelection->Form);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- UpdateDisplayFormData ();
+ if (gBrowserSettingScope == SystemLevel ||
+ (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
+ PrintHotKeyHelpString ();
+ }
+ if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {
+ PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
+ }
- //
- // Three possible status maybe return.
- //
- // EFI_INVALID_PARAMETER: The input dimension info is not valid.
- // EFI_NOT_FOUND: The input value for oneof/orderedlist opcode is not valid
- // and an valid value has return.
- // EFI_SUCCESS: Success shows form and get user input in UserInput paramenter.
- //
- Status = mFormDisplay->FormDisplay (&gDisplayFormData, &UserInput);
- if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {
- FreeDisplayFormData();
- return Status;
- }
+ PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
+ PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox);
+ break;
- //
- // If status is EFI_SUCCESS, means user has change the highlight menu and new user input return.
- // in this case, browser need to change the highlight menu.
- // If status is EFI_NOT_FOUND, means the input DisplayFormData has error for oneof/orderedlist
- // opcode and new valid value has return, browser core need to adjust
- // value for this opcode and shows this form again.
- //
- ChangeHighlight = (Status == EFI_SUCCESS ? TRUE :FALSE);
+ case EFI_IFR_REF_OP:
+ case EFI_IFR_PASSWORD_OP:
+ case EFI_IFR_STRING_OP:
+ case EFI_IFR_TEXT_OP:
+ case EFI_IFR_ACTION_OP:
+ case EFI_IFR_RESET_BUTTON_OP:
+ case EFI_IFR_SUBTITLE_OP:
+ ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
- Status = ProcessUserInput (&UserInput, ChangeHighlight);
+ if (!Selected) {
+ //
+ // On system setting, HotKey will show on every form.
+ //
+ if (gBrowserSettingScope == SystemLevel ||
+ (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
+ PrintHotKeyHelpString ();
+ }
+ if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {
+ PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
+ }
- FreeDisplayFormData();
+ PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
+ if (Statement->Operand != EFI_IFR_TEXT_OP && Statement->Operand != EFI_IFR_SUBTITLE_OP) {
+ PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
+ }
+ } else {
+ if (Statement->Operand != EFI_IFR_REF_OP) {
+ PrintStringAt (
+ (LocalScreen.RightColumn - GetStringWidth (gEnterCommitString) / 2) / 2,
+ BottomRowOfHelp,
+ gEnterCommitString
+ );
+ PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);
+ }
+ }
+ break;
- return Status;
+ default:
+ break;
+ }
}
/**
@@ -1715,136 +920,60 @@ FormUpdateNotify ( }
/**
- Update the NV flag info for this form set.
+ check whether the formset need to update the NV.
@param FormSet FormSet data structure.
+ @retval TRUE Need to update the NV.
+ @retval FALSE No need to update the NV.
**/
-BOOLEAN
-IsNvUpdateRequiredForFormSet (
+BOOLEAN
+IsNvUpdateRequired (
IN FORM_BROWSER_FORMSET *FormSet
)
{
LIST_ENTRY *Link;
FORM_BROWSER_FORM *Form;
- BOOLEAN RetVal;
-
- //
- // Not finished question initialization, return FALSE.
- //
- if (!FormSet->QuestionInited) {
- return FALSE;
- }
-
- RetVal = FALSE;
Link = GetFirstNode (&FormSet->FormListHead);
while (!IsNull (&FormSet->FormListHead, Link)) {
Form = FORM_BROWSER_FORM_FROM_LINK (Link);
- RetVal = IsNvUpdateRequiredForForm(Form);
- if (RetVal) {
- break;
- }
-
- Link = GetNextNode (&FormSet->FormListHead, Link);
- }
-
- return RetVal;
-}
-
-/**
- Update the NvUpdateRequired flag for a form.
-
- @param Form Form data structure.
-
-**/
-BOOLEAN
-IsNvUpdateRequiredForForm (
- IN FORM_BROWSER_FORM *Form
- )
-{
- LIST_ENTRY *Link;
- FORM_BROWSER_STATEMENT *Statement;
-
- Link = GetFirstNode (&Form->StatementListHead);
- while (!IsNull (&Form->StatementListHead, Link)) {
- Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
-
- if (Statement->ValueChanged) {
+ if (Form->NvUpdateRequired ) {
return TRUE;
}
- Link = GetNextNode (&Form->StatementListHead, Link);
+ Link = GetNextNode (&FormSet->FormListHead, Link);
}
return FALSE;
}
/**
- Check whether the storage data for current form set is changed.
+ check whether the formset need to update the NV.
- @param FormSet FormSet data structure.
+ @param FormSet FormSet data structure.
+ @param SetValue Whether set new value or clear old value.
- @retval TRUE Data is changed.
- @retval FALSE Data is not changed.
**/
-BOOLEAN
-IsStorageDataChangedForFormSet (
- IN FORM_BROWSER_FORMSET *FormSet
+VOID
+UpdateNvInfoInForm (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN BOOLEAN SetValue
)
{
LIST_ENTRY *Link;
- FORMSET_STORAGE *Storage;
- BROWSER_STORAGE *BrowserStorage;
- CHAR16 *ConfigRespNew;
- CHAR16 *ConfigRespOld;
- BOOLEAN RetVal;
-
- RetVal = FALSE;
- ConfigRespNew = NULL;
- ConfigRespOld = NULL;
-
- //
- // Request current settings from Configuration Driver
- //
- Link = GetFirstNode (&FormSet->StorageListHead);
- while (!IsNull (&FormSet->StorageListHead, Link)) {
- Storage = FORMSET_STORAGE_FROM_LINK (Link);
- Link = GetNextNode (&FormSet->StorageListHead, Link);
-
- BrowserStorage = Storage->BrowserStorage;
-
- if (BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
- continue;
- }
-
- if (Storage->ElementCount == 0) {
- continue;
- }
-
- StorageToConfigResp (BrowserStorage, &ConfigRespNew, Storage->ConfigRequest, TRUE);
- StorageToConfigResp (BrowserStorage, &ConfigRespOld, Storage->ConfigRequest, FALSE);
- ASSERT (ConfigRespNew != NULL && ConfigRespOld != NULL);
-
- if (StrCmp (ConfigRespNew, ConfigRespOld) != 0) {
- RetVal = TRUE;
- }
-
- FreePool (ConfigRespNew);
- ConfigRespNew = NULL;
+ FORM_BROWSER_FORM *Form;
+
+ Link = GetFirstNode (&FormSet->FormListHead);
+ while (!IsNull (&FormSet->FormListHead, Link)) {
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);
- FreePool (ConfigRespOld);
- ConfigRespOld = NULL;
+ Form->NvUpdateRequired = SetValue;
- if (RetVal) {
- break;
- }
+ Link = GetNextNode (&FormSet->FormListHead, Link);
}
-
- return RetVal;
}
-
/**
Find menu which will show next time.
@@ -1852,79 +981,98 @@ IsStorageDataChangedForFormSet ( about the Selection, form and formset to be displayed.
On output, Selection return the screen item that is selected
by user.
- @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.
- else, we need to exit current formset.
+ @param Repaint Whether need to repaint the menu.
+ @param NewLine Whether need to show at new line.
- @retval TRUE Exit current form.
- @retval FALSE User press ESC and keep in current form.
+ @retval TRUE Need return.
+ @retval FALSE No need to return.
**/
BOOLEAN
FindNextMenu (
- IN OUT UI_MENU_SELECTION *Selection,
- IN BROWSER_SETTING_SCOPE SettingLevel
+ IN OUT UI_MENU_SELECTION *Selection,
+ IN BOOLEAN *Repaint,
+ IN BOOLEAN *NewLine
)
{
- FORM_ENTRY_INFO *CurrentMenu;
- FORM_ENTRY_INFO *ParentMenu;
- BROWSER_SETTING_SCOPE Scope;
+ UI_MENU_LIST *CurrentMenu;
+ CHAR16 YesResponse;
+ CHAR16 NoResponse;
+ EFI_INPUT_KEY Key;
+ BROWSER_SETTING_SCOPE Scope;
CurrentMenu = Selection->CurrentMenu;
- ParentMenu = NULL;
- Scope = FormSetLevel;
- if (CurrentMenu != NULL && (ParentMenu = UiFindParentMenu(CurrentMenu)) != NULL) {
+ if (CurrentMenu != NULL && CurrentMenu->Parent != NULL) {
//
// we have a parent, so go to the parent menu
//
- if (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {
- if (SettingLevel == FormSetLevel) {
+ if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) {
+ //
+ // The parent menu and current menu are in the same formset
+ //
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+ Scope = FormLevel;
+ } else {
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;
+ CopyMem (&Selection->FormSetGuid, &CurrentMenu->Parent->FormSetGuid, sizeof (EFI_GUID));
+ Selection->Handle = CurrentMenu->Parent->HiiHandle;
+ Scope = FormSetLevel;
+ }
+
+ //
+ // Form Level Check whether the data is changed.
+ //
+ if ((gBrowserSettingScope == FormLevel && Selection->Form->NvUpdateRequired) ||
+ (gBrowserSettingScope == FormSetLevel && IsNvUpdateRequired(Selection->FormSet) && Scope == FormSetLevel)) {
+ gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+
+ YesResponse = gYesResponse[0];
+ NoResponse = gNoResponse[0];
+
+ //
+ // If NV flag is up, prompt user
+ //
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString);
+ } while
+ (
+ (Key.ScanCode != SCAN_ESC) &&
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))
+ );
+
+ if (Key.ScanCode == SCAN_ESC) {
//
- // Find a menu which has different formset guid with current.
+ // User hits the ESC key, Ingore.
//
- while (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {
- CurrentMenu = ParentMenu;
- if ((ParentMenu = UiFindParentMenu(CurrentMenu)) == NULL) {
- break;
- }
+ if (Repaint != NULL) {
+ *Repaint = TRUE;
}
-
- if (ParentMenu != NULL) {
- Scope = FormSetLevel;
+ if (NewLine != NULL) {
+ *NewLine = TRUE;
}
+
+ Selection->Action = UI_ACTION_NONE;
+ return FALSE;
+ }
+
+ if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {
+ //
+ // If the user hits the YesResponse key
+ //
+ SubmitForm (Selection->FormSet, Selection->Form, Scope);
} else {
- Scope = FormLevel;
+ //
+ // If the user hits the NoResponse key
+ //
+ DiscardForm (Selection->FormSet, Selection->Form, Scope);
}
- } else {
- Scope = FormSetLevel;
- }
- }
-
- //
- // Form Level Check whether the data is changed.
- //
- if ((gBrowserSettingScope == FormLevel && IsNvUpdateRequiredForForm (Selection->Form)) ||
- (gBrowserSettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet(Selection->FormSet) && Scope == FormSetLevel)) {
- if (!ProcessChangedData(Selection, Scope)) {
- return FALSE;
- }
- }
-
- if (ParentMenu != NULL) {
- //
- // ParentMenu is found. Then, go to it.
- //
- if (Scope == FormLevel) {
- Selection->Action = UI_ACTION_REFRESH_FORM;
- } else {
- Selection->Action = UI_ACTION_REFRESH_FORMSET;
- CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));
- Selection->Handle = ParentMenu->HiiHandle;
}
Selection->Statement = NULL;
- Selection->FormId = ParentMenu->FormId;
- Selection->QuestionId = ParentMenu->QuestionId;
+ Selection->FormId = CurrentMenu->Parent->FormId;
+ Selection->QuestionId = CurrentMenu->Parent->QuestionId;
//
// Clear highlight record for this menu
@@ -1933,11 +1081,70 @@ FindNextMenu ( return FALSE;
}
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {
+ //
+ // We never exit FrontPage, so skip the ESC
+ //
+ Selection->Action = UI_ACTION_NONE;
+ return FALSE;
+ }
+
//
- // Current in root page, exit the SendForm
+ // We are going to leave current FormSet, so check uncommited data in this FormSet
//
- Selection->Action = UI_ACTION_EXIT;
+ if (gBrowserSettingScope != SystemLevel && IsNvUpdateRequired(Selection->FormSet)) {
+ gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+
+ YesResponse = gYesResponse[0];
+ NoResponse = gNoResponse[0];
+
+ //
+ // If NV flag is up, prompt user
+ //
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString);
+ } while
+ (
+ (Key.ScanCode != SCAN_ESC) &&
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))
+ );
+
+ if (Key.ScanCode == SCAN_ESC) {
+ //
+ // User hits the ESC key
+ //
+ if (Repaint != NULL) {
+ *Repaint = TRUE;
+ }
+
+ if (NewLine != NULL) {
+ *NewLine = TRUE;
+ }
+
+ Selection->Action = UI_ACTION_NONE;
+ return FALSE;
+ }
+
+ if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {
+ //
+ // If the user hits the YesResponse key
+ //
+ SubmitForm (Selection->FormSet, Selection->Form, FormSetLevel);
+ } else {
+ //
+ // If the user hits the NoResponse key
+ //
+ DiscardForm (Selection->FormSet, Selection->Form, FormSetLevel);
+ }
+ }
+
+ Selection->Statement = NULL;
+ if (CurrentMenu != NULL) {
+ CurrentMenu->QuestionId = 0;
+ }
+ Selection->Action = UI_ACTION_EXIT;
return TRUE;
}
@@ -2039,17 +1246,17 @@ ProcessCallBackFunction ( case EFI_BROWSER_ACTION_REQUEST_RESET:
DiscardFormIsRequired = TRUE;
gResetRequired = TRUE;
- NeedExit = TRUE;
+ Selection->Action = UI_ACTION_EXIT;
break;
case EFI_BROWSER_ACTION_REQUEST_SUBMIT:
SubmitFormIsRequired = TRUE;
- NeedExit = TRUE;
+ Selection->Action = UI_ACTION_EXIT;
break;
case EFI_BROWSER_ACTION_REQUEST_EXIT:
DiscardFormIsRequired = TRUE;
- NeedExit = TRUE;
+ Selection->Action = UI_ACTION_EXIT;
break;
case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT:
@@ -2060,7 +1267,7 @@ ProcessCallBackFunction ( case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT:
DiscardFormIsRequired = TRUE;
- SettingLevel = FormLevel;
+ SettingLevel = FormLevel;
NeedExit = TRUE;
break;
@@ -2113,7 +1320,7 @@ ProcessCallBackFunction ( }
if (NeedExit) {
- FindNextMenu (Selection, SettingLevel);
+ FindNextMenu (Selection, NULL, NULL);
}
return Status;
@@ -2193,7 +1400,9 @@ SetupBrowser ( EFI_HANDLE NotifyHandle;
FORM_BROWSER_STATEMENT *Statement;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
+ EFI_INPUT_KEY Key;
+ gMenuRefreshHead = NULL;
ConfigAccess = Selection->FormSet->ConfigAccess;
//
@@ -2214,17 +1423,21 @@ SetupBrowser ( //
// Initialize current settings of Questions in this FormSet
//
- InitializeCurrentSetting (Selection->FormSet);
-
- //
- // Initilize Action field.
- //
- Selection->Action = UI_ACTION_REFRESH_FORM;
+ Status = InitializeCurrentSetting (Selection->FormSet);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
//
- // Clean the mCurFakeQestId value is formset refreshed.
+ // Update gOldFormSet on maintain back up FormSet list.
+ // And, make gOldFormSet point to current FormSet.
//
- mCurFakeQestId = 0;
+ if (gOldFormSet != NULL) {
+ RemoveEntryList (&gOldFormSet->Link);
+ DestroyFormSet (gOldFormSet);
+ }
+ gOldFormSet = Selection->FormSet;
+ InsertTailList (&gBrowserFormSetList, &gOldFormSet->Link);
do {
//
@@ -2267,7 +1480,10 @@ SetupBrowser ( //
// Form is suppressed.
//
- gBrowserStatus = BROWSER_FORM_SUPPRESS;
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+
Status = EFI_NOT_FOUND;
goto Done;
}
@@ -2282,6 +1498,7 @@ SetupBrowser ( ((Selection->Handle != mCurrentHiiHandle) ||
(!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||
(Selection->FormId != mCurrentFormId))) {
+
//
// Keep current form information
//
@@ -2295,6 +1512,12 @@ SetupBrowser ( }
//
+ // EXIT requests to close form.
+ //
+ if (Selection->Action == UI_ACTION_EXIT) {
+ goto Done;
+ }
+ //
// IFR is updated during callback of open form, force to reparse the IFR binary
//
if (mHiiPackageListUpdated) {
@@ -2313,6 +1536,12 @@ SetupBrowser ( }
//
+ // EXIT requests to close form.
+ //
+ if (Selection->Action == UI_ACTION_EXIT) {
+ goto Done;
+ }
+ //
// IFR is updated during callback of read value, force to reparse the IFR binary
//
if (mHiiPackageListUpdated) {
@@ -2322,9 +1551,14 @@ SetupBrowser ( }
//
+ // Displays the Header and Footer borders
+ //
+ DisplayPageFrame (Selection);
+
+ //
// Display form
//
- Status = DisplayForm ();
+ Status = DisplayForm (Selection);
if (EFI_ERROR (Status)) {
goto Done;
}
@@ -2334,16 +1568,20 @@ SetupBrowser ( //
Statement = Selection->Statement;
if (Statement != NULL) {
+ if ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED) {
+ gResetRequired = TRUE;
+ }
+
if ((ConfigAccess != NULL) &&
((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) &&
(Statement->Operand != EFI_IFR_PASSWORD_OP)) {
- Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);
- if (Statement->Operand == EFI_IFR_REF_OP) {
+ Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);
+ if (Statement->Operand == EFI_IFR_REF_OP && Selection->Action != UI_ACTION_EXIT) {
//
// Process dynamic update ref opcode.
//
if (!EFI_ERROR (Status)) {
- Status = ProcessGotoOpCode(Statement, Selection);
+ Status = ProcessGotoOpCode(Statement, Selection, NULL, NULL);
}
//
@@ -2365,27 +1603,6 @@ SetupBrowser ( }
//
- // Check whether Exit flag is TRUE.
- //
- if (gExitRequired) {
- switch (gBrowserSettingScope) {
- case SystemLevel:
- Selection->Action = UI_ACTION_EXIT;
- break;
-
- case FormSetLevel:
- case FormLevel:
- FindNextMenu (Selection, gBrowserSettingScope);
- break;
-
- default:
- break;
- }
-
- gExitRequired = FALSE;
- }
-
- //
// Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE
// for each question with callback flag.
//
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Print.c b/MdeModulePkg/Universal/SetupBrowserDxe/Print.c new file mode 100644 index 0000000000..eeadf2494f --- /dev/null +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Print.c @@ -0,0 +1,272 @@ +/** @file
+Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very
+simple implemenation of SPrint() and Print() to support debug.
+
+You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a
+time. This makes the implementation very simple.
+
+VSPrint, Print, SPrint format specification has the follwoing form
+
+%type
+
+type:
+ 'S','s' - argument is an Unicode string
+ 'c' - argument is an ascii character
+ '%' - Print a %
+
+
+Copyright (c) 2004 - 2012, 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 "Setup.h"
+
+/**
+ The internal function prints to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
+ protocol instance.
+
+ @param Column The position of the output string.
+ @param Row The position of the output string.
+ @param Out The EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL instance.
+ @param Fmt The format string.
+ @param Args The additional argument for the variables in the format string.
+
+ @return Number of Unicode character printed.
+
+**/
+UINTN
+PrintInternal (
+ IN UINTN Column,
+ IN UINTN Row,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Out,
+ IN CHAR16 *Fmt,
+ IN VA_LIST Args
+ )
+{
+ CHAR16 *Buffer;
+ CHAR16 *BackupBuffer;
+ UINTN Index;
+ UINTN PreviousIndex;
+ UINTN Count;
+
+ //
+ // For now, allocate an arbitrarily long buffer
+ //
+ Buffer = AllocateZeroPool (0x10000);
+ BackupBuffer = AllocateZeroPool (0x10000);
+ ASSERT (Buffer);
+ ASSERT (BackupBuffer);
+
+ if (Column != (UINTN) -1) {
+ Out->SetCursorPosition (Out, Column, Row);
+ }
+
+ UnicodeVSPrint (Buffer, 0x10000, Fmt, Args);
+
+ Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;
+
+ Out->SetAttribute (Out, Out->Mode->Attribute);
+
+ Index = 0;
+ PreviousIndex = 0;
+ Count = 0;
+
+ do {
+ for (; (Buffer[Index] != NARROW_CHAR) && (Buffer[Index] != WIDE_CHAR) && (Buffer[Index] != 0); Index++) {
+ BackupBuffer[Index] = Buffer[Index];
+ }
+
+ if (Buffer[Index] == 0) {
+ break;
+ }
+ //
+ // Null-terminate the temporary string
+ //
+ BackupBuffer[Index] = 0;
+
+ //
+ // Print this out, we are about to switch widths
+ //
+ Out->OutputString (Out, &BackupBuffer[PreviousIndex]);
+ Count += StrLen (&BackupBuffer[PreviousIndex]);
+
+ //
+ // Preserve the current index + 1, since this is where we will start printing from next
+ //
+ PreviousIndex = Index + 1;
+
+ //
+ // We are at a narrow or wide character directive. Set attributes and strip it and print it
+ //
+ if (Buffer[Index] == NARROW_CHAR) {
+ //
+ // Preserve bits 0 - 6 and zero out the rest
+ //
+ Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;
+ Out->SetAttribute (Out, Out->Mode->Attribute);
+ } else {
+ //
+ // Must be wide, set bit 7 ON
+ //
+ Out->Mode->Attribute = Out->Mode->Attribute | EFI_WIDE_ATTRIBUTE;
+ Out->SetAttribute (Out, Out->Mode->Attribute);
+ }
+
+ Index++;
+
+ } while (Buffer[Index] != 0);
+
+ //
+ // We hit the end of the string - print it
+ //
+ Out->OutputString (Out, &BackupBuffer[PreviousIndex]);
+ Count += StrLen (&BackupBuffer[PreviousIndex]);
+
+ FreePool (Buffer);
+ FreePool (BackupBuffer);
+ return Count;
+}
+
+
+/**
+ Prints a formatted unicode string to the default console.
+
+ @param Fmt Format string
+ @param ... Variable argument list for format string.
+
+ @return Length of string printed to the console.
+
+**/
+UINTN
+EFIAPI
+ConsolePrint (
+ IN CHAR16 *Fmt,
+ ...
+ )
+{
+ VA_LIST Args;
+ UINTN LengthOfPrinted;
+
+ VA_START (Args, Fmt);
+ LengthOfPrinted = PrintInternal ((UINTN) -1, (UINTN) -1, gST->ConOut, Fmt, Args);
+ VA_END (Args);
+ return LengthOfPrinted;
+}
+
+
+/**
+ Prints a unicode string to the default console,
+ using L"%s" format.
+
+ @param String String pointer.
+
+ @return Length of string printed to the console
+
+**/
+UINTN
+PrintString (
+ IN CHAR16 *String
+ )
+{
+ return ConsolePrint (L"%s", String);
+}
+
+
+/**
+ Prints a chracter to the default console,
+ using L"%c" format.
+
+ @param Character Character to print.
+
+ @return Length of string printed to the console.
+
+**/
+UINTN
+PrintChar (
+ CHAR16 Character
+ )
+{
+ return ConsolePrint (L"%c", Character);
+}
+
+
+/**
+ Prints a formatted unicode string to the default console, at
+ the supplied cursor position.
+
+ @param Column The cursor position to print the string at.
+ @param Row The cursor position to print the string at.
+ @param Fmt Format string.
+ @param ... Variable argument list for format string.
+
+ @return Length of string printed to the console
+
+**/
+UINTN
+EFIAPI
+PrintAt (
+ IN UINTN Column,
+ IN UINTN Row,
+ IN CHAR16 *Fmt,
+ ...
+ )
+{
+ VA_LIST Args;
+ UINTN LengthOfPrinted;
+
+ VA_START (Args, Fmt);
+ LengthOfPrinted = PrintInternal (Column, Row, gST->ConOut, Fmt, Args);
+ VA_END (Args);
+ return LengthOfPrinted;
+}
+
+
+/**
+ Prints a unicode string to the default console, at
+ the supplied cursor position, using L"%s" format.
+
+ @param Column The cursor position to print the string at.
+ @param Row The cursor position to print the string at
+ @param String String pointer.
+
+ @return Length of string printed to the console
+
+**/
+UINTN
+PrintStringAt (
+ IN UINTN Column,
+ IN UINTN Row,
+ IN CHAR16 *String
+ )
+{
+ return PrintAt (Column, Row, L"%s", String);
+}
+
+
+/**
+ Prints a chracter to the default console, at
+ the supplied cursor position, using L"%c" format.
+
+ @param Column The cursor position to print the string at.
+ @param Row The cursor position to print the string at.
+ @param Character Character to print.
+
+ @return Length of string printed to the console.
+
+**/
+UINTN
+PrintCharAt (
+ IN UINTN Column,
+ IN UINTN Row,
+ CHAR16 Character
+ )
+{
+ return PrintAt (Column, Row, L"%c", Character);
+}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c b/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c new file mode 100644 index 0000000000..fecb98e8bf --- /dev/null +++ b/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c @@ -0,0 +1,1075 @@ +/** @file
+Implementation for handling the User Interface option processing.
+
+
+Copyright (c) 2004 - 2012, 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 "Setup.h"
+
+
+/**
+ Process Question Config.
+
+ @param Selection The UI menu selection.
+ @param Question The Question to be peocessed.
+
+ @retval EFI_SUCCESS Question Config process success.
+ @retval Other Question Config process fail.
+
+**/
+EFI_STATUS
+ProcessQuestionConfig (
+ IN UI_MENU_SELECTION *Selection,
+ IN FORM_BROWSER_STATEMENT *Question
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *ConfigResp;
+ CHAR16 *Progress;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
+
+ if (Question->QuestionConfig == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Get <ConfigResp>
+ //
+ ConfigResp = GetToken (Question->QuestionConfig, Selection->FormSet->HiiHandle);
+ if (ConfigResp == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Send config to Configuration Driver
+ //
+ ConfigAccess = Selection->FormSet->ConfigAccess;
+ if (ConfigAccess == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ Status = ConfigAccess->RouteConfig (
+ ConfigAccess,
+ ConfigResp,
+ &Progress
+ );
+
+ return Status;
+}
+
+
+/**
+ Search an Option of a Question by its value.
+
+ @param Question The Question
+ @param OptionValue Value for Option to be searched.
+
+ @retval Pointer Pointer to the found Option.
+ @retval NULL Option not found.
+
+**/
+QUESTION_OPTION *
+ValueToOption (
+ IN FORM_BROWSER_STATEMENT *Question,
+ IN EFI_HII_VALUE *OptionValue
+ )
+{
+ LIST_ENTRY *Link;
+ QUESTION_OPTION *Option;
+ INTN Result;
+
+ Link = GetFirstNode (&Question->OptionListHead);
+ while (!IsNull (&Question->OptionListHead, Link)) {
+ Option = QUESTION_OPTION_FROM_LINK (Link);
+
+ if ((CompareHiiValue (&Option->Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
+ //
+ // Check the suppressif condition, only a valid option can be return.
+ //
+ if ((Option->SuppressExpression == NULL) ||
+ ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse))) {
+ return Option;
+ }
+ }
+
+ Link = GetNextNode (&Question->OptionListHead, Link);
+ }
+
+ return NULL;
+}
+
+
+/**
+ Return data element in an Array by its Index.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+
+ @retval Value The data to be returned
+
+**/
+UINT64
+GetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index
+ )
+{
+ UINT64 Data;
+
+ ASSERT (Array != NULL);
+
+ Data = 0;
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data = (UINT64) *(((UINT8 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data = (UINT64) *(((UINT16 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data = (UINT64) *(((UINT32 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data = (UINT64) *(((UINT64 *) Array) + Index);
+ break;
+
+ default:
+ break;
+ }
+
+ return Data;
+}
+
+
+/**
+ Set value of a data element in an Array by its Index.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+ @param Value The value to be set.
+
+**/
+VOID
+SetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index,
+ IN UINT64 Value
+ )
+{
+
+ ASSERT (Array != NULL);
+
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ *(((UINT8 *) Array) + Index) = (UINT8) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ *(((UINT16 *) Array) + Index) = (UINT16) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ *(((UINT32 *) Array) + Index) = (UINT32) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ *(((UINT64 *) Array) + Index) = (UINT64) Value;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ Check whether this value already in the array, if yes, return the index.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Value The value to be find.
+ @param Index The index in the array which has same value with Value.
+
+ @retval TRUE Found the value in the array.
+ @retval FALSE Not found the value.
+
+**/
+BOOLEAN
+FindArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINT64 Value,
+ OUT UINTN *Index OPTIONAL
+ )
+{
+ UINTN Count;
+ UINT64 TmpValue;
+
+ ASSERT (Array != NULL);
+
+ Count = 0;
+ TmpValue = 0;
+
+ while ((TmpValue = GetArrayData (Array, Type, Count)) != 0) {
+ if (Value == TmpValue) {
+ if (Index != NULL) {
+ *Index = Count;
+ }
+ return TRUE;
+ }
+
+ Count ++;
+ }
+
+ return FALSE;
+}
+
+/**
+ Print Question Value according to it's storage width and display attributes.
+
+ @param Question The Question to be printed.
+ @param FormattedNumber Buffer for output string.
+ @param BufferSize The FormattedNumber buffer size in bytes.
+
+ @retval EFI_SUCCESS Print success.
+ @retval EFI_BUFFER_TOO_SMALL Buffer size is not enough for formatted number.
+
+**/
+EFI_STATUS
+PrintFormattedNumber (
+ IN FORM_BROWSER_STATEMENT *Question,
+ IN OUT CHAR16 *FormattedNumber,
+ IN UINTN BufferSize
+ )
+{
+ INT64 Value;
+ CHAR16 *Format;
+ EFI_HII_VALUE *QuestionValue;
+
+ if (BufferSize < (21 * sizeof (CHAR16))) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ QuestionValue = &Question->HiiValue;
+
+ Value = (INT64) QuestionValue->Value.u64;
+ switch (Question->Flags & EFI_IFR_DISPLAY) {
+ case EFI_IFR_DISPLAY_INT_DEC:
+ switch (QuestionValue->Type) {
+ case EFI_IFR_NUMERIC_SIZE_1:
+ Value = (INT64) ((INT8) QuestionValue->Value.u8);
+ break;
+
+ case EFI_IFR_NUMERIC_SIZE_2:
+ Value = (INT64) ((INT16) QuestionValue->Value.u16);
+ break;
+
+ case EFI_IFR_NUMERIC_SIZE_4:
+ Value = (INT64) ((INT32) QuestionValue->Value.u32);
+ break;
+
+ case EFI_IFR_NUMERIC_SIZE_8:
+ default:
+ break;
+ }
+
+ if (Value < 0) {
+ Value = -Value;
+ Format = L"-%ld";
+ } else {
+ Format = L"%ld";
+ }
+ break;
+
+ case EFI_IFR_DISPLAY_UINT_DEC:
+ Format = L"%ld";
+ break;
+
+ case EFI_IFR_DISPLAY_UINT_HEX:
+ Format = L"%lx";
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ break;
+ }
+
+ UnicodeSPrint (FormattedNumber, BufferSize, Format, Value);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Password may be stored as encrypted by Configuration Driver. When change a
+ password, user will be challenged with old password. To validate user input old
+ password, we will send the clear text to Configuration Driver via Callback().
+ Configuration driver is responsible to check the passed in password and return
+ the validation result. If validation pass, state machine in password Callback()
+ will transit from BROWSER_STATE_VALIDATE_PASSWORD to BROWSER_STATE_SET_PASSWORD.
+ After user type in new password twice, Callback() will be invoked to send the
+ new password to Configuration Driver.
+
+ @param Selection Pointer to UI_MENU_SELECTION.
+ @param MenuOption The MenuOption for this password Question.
+ @param String The clear text of password.
+
+ @retval EFI_NOT_AVAILABLE_YET Callback() request to terminate password input.
+ @return In state of BROWSER_STATE_VALIDATE_PASSWORD:
+ @retval EFI_SUCCESS Password correct, Browser will prompt for new
+ password.
+ @retval EFI_NOT_READY Password incorrect, Browser will show error
+ message.
+ @retval Other Browser will do nothing.
+ @return In state of BROWSER_STATE_SET_PASSWORD:
+ @retval EFI_SUCCESS Set password success.
+ @retval Other Set password failed.
+
+**/
+EFI_STATUS
+PasswordCallback (
+ IN UI_MENU_SELECTION *Selection,
+ IN UI_MENU_OPTION *MenuOption,
+ IN CHAR16 *String
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
+ EFI_BROWSER_ACTION_REQUEST ActionRequest;
+ EFI_IFR_TYPE_VALUE IfrTypeValue;
+
+ ConfigAccess = Selection->FormSet->ConfigAccess;
+ if (ConfigAccess == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Prepare password string in HII database
+ //
+ if (String != NULL) {
+ IfrTypeValue.string = NewString (String, Selection->FormSet->HiiHandle);
+ } else {
+ IfrTypeValue.string = 0;
+ }
+
+ //
+ // Send password to Configuration Driver for validation
+ //
+ Status = ConfigAccess->Callback (
+ ConfigAccess,
+ EFI_BROWSER_ACTION_CHANGING,
+ MenuOption->ThisTag->QuestionId,
+ MenuOption->ThisTag->HiiValue.Type,
+ &IfrTypeValue,
+ &ActionRequest
+ );
+
+ //
+ // Remove password string from HII database
+ //
+ if (String != NULL) {
+ DeleteString (IfrTypeValue.string, Selection->FormSet->HiiHandle);
+ }
+
+ return Status;
+}
+
+
+/**
+ Display error message for invalid password.
+
+**/
+VOID
+PasswordInvalid (
+ VOID
+ )
+{
+ EFI_INPUT_KEY Key;
+
+ //
+ // Invalid password, prompt error message
+ //
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gPassowordInvalid, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+}
+
+
+/**
+ Process a Question's Option (whether selected or un-selected).
+
+ @param Selection Pointer to UI_MENU_SELECTION.
+ @param MenuOption The MenuOption for this Question.
+ @param Selected TRUE: if Question is selected.
+ @param OptionString Pointer of the Option String to be displayed.
+
+ @retval EFI_SUCCESS Question Option process success.
+ @retval Other Question Option process fail.
+
+**/
+EFI_STATUS
+ProcessOptions (
+ IN UI_MENU_SELECTION *Selection,
+ IN UI_MENU_OPTION *MenuOption,
+ IN BOOLEAN Selected,
+ OUT CHAR16 **OptionString
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 *StringPtr;
+ CHAR16 *TempString;
+ UINTN Index;
+ FORM_BROWSER_STATEMENT *Question;
+ CHAR16 FormattedNumber[21];
+ UINT16 Number;
+ CHAR16 Character[2];
+ EFI_INPUT_KEY Key;
+ UINTN BufferSize;
+ QUESTION_OPTION *OneOfOption;
+ LIST_ENTRY *Link;
+ EFI_HII_VALUE HiiValue;
+ EFI_HII_VALUE *QuestionValue;
+ UINT16 Maximum;
+ QUESTION_OPTION *Option;
+ UINTN Index2;
+ UINT8 *ValueArray;
+ UINT8 ValueType;
+ EFI_STRING_ID StringId;
+
+ Status = EFI_SUCCESS;
+
+ StringPtr = NULL;
+ Character[1] = L'\0';
+ *OptionString = NULL;
+ StringId = 0;
+
+ ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
+ BufferSize = (gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow;
+
+ Question = MenuOption->ThisTag;
+ QuestionValue = &Question->HiiValue;
+ Maximum = (UINT16) Question->Maximum;
+
+ ValueArray = Question->BufferValue;
+ ValueType = Question->ValueType;
+
+ switch (Question->Operand) {
+ case EFI_IFR_ORDERED_LIST_OP:
+ //
+ // Check whether there are Options of this OrderedList
+ //
+ if (IsListEmpty (&Question->OptionListHead)) {
+ break;
+ }
+ //
+ // Initialize Option value array
+ //
+ if (GetArrayData (ValueArray, ValueType, 0) == 0) {
+ GetQuestionDefault (Selection->FormSet, Selection->Form, Question, 0);
+ }
+
+ if (Selected) {
+ //
+ // Go ask for input
+ //
+ Status = GetSelectionInputPopUp (Selection, MenuOption);
+ } else {
+ //
+ // We now know how many strings we will have, so we can allocate the
+ // space required for the array or strings.
+ //
+ *OptionString = AllocateZeroPool (Question->MaxContainers * BufferSize);
+ ASSERT (*OptionString);
+
+ HiiValue.Type = ValueType;
+ HiiValue.Value.u64 = 0;
+ for (Index = 0; Index < Question->MaxContainers; Index++) {
+ HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
+ if (HiiValue.Value.u64 == 0) {
+ //
+ // Values for the options in ordered lists should never be a 0
+ //
+ break;
+ }
+
+ OneOfOption = ValueToOption (Question, &HiiValue);
+ if (OneOfOption == NULL) {
+ //
+ // Show error message
+ //
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+
+ //
+ // The initial value of the orderedlist is invalid, force to be valid value
+ //
+ Link = GetFirstNode (&Question->OptionListHead);
+ Index2 = 0;
+ while (!IsNull (&Question->OptionListHead, Link) && Index2 < Question->MaxContainers) {
+ Option = QUESTION_OPTION_FROM_LINK (Link);
+ Link = GetNextNode (&Question->OptionListHead, Link);
+ if ((Option->SuppressExpression != NULL) &&
+ ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {
+ continue;
+ }
+ SetArrayData (ValueArray, ValueType, Index2, Option->Value.Value.u64);
+ Index2++;
+ }
+ SetArrayData (ValueArray, ValueType, Index2, 0);
+
+ Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
+ UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
+
+ FreePool (*OptionString);
+ *OptionString = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ Character[0] = LEFT_ONEOF_DELIMITER;
+ NewStrCat (OptionString[0], Character);
+ StringPtr = GetToken (OneOfOption->Text, Selection->Handle);
+ ASSERT (StringPtr != NULL);
+ NewStrCat (OptionString[0], StringPtr);
+ Character[0] = RIGHT_ONEOF_DELIMITER;
+ NewStrCat (OptionString[0], Character);
+ Character[0] = CHAR_CARRIAGE_RETURN;
+ NewStrCat (OptionString[0], Character);
+ FreePool (StringPtr);
+ }
+
+ //
+ // Search the other options, try to find the one not in the container.
+ //
+ Link = GetFirstNode (&Question->OptionListHead);
+ while (!IsNull (&Question->OptionListHead, Link)) {
+ OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
+ Link = GetNextNode (&Question->OptionListHead, Link);
+ if ((OneOfOption->SuppressExpression != NULL) &&
+ ((EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {
+ continue;
+ }
+
+ if (FindArrayData (ValueArray, ValueType, OneOfOption->Value.Value.u64, NULL)) {
+ continue;
+ }
+
+ SetArrayData (ValueArray, ValueType, Index++, OneOfOption->Value.Value.u64);
+
+ Character[0] = LEFT_ONEOF_DELIMITER;
+ NewStrCat (OptionString[0], Character);
+ StringPtr = GetToken (OneOfOption->Text, Selection->Handle);
+ ASSERT (StringPtr != NULL);
+ NewStrCat (OptionString[0], StringPtr);
+ Character[0] = RIGHT_ONEOF_DELIMITER;
+ NewStrCat (OptionString[0], Character);
+ Character[0] = CHAR_CARRIAGE_RETURN;
+ NewStrCat (OptionString[0], Character);
+ FreePool (StringPtr);
+ }
+ }
+ break;
+
+ case EFI_IFR_ONE_OF_OP:
+ //
+ // Check whether there are Options of this OneOf
+ //
+ if (IsListEmpty (&Question->OptionListHead)) {
+ break;
+ }
+ if (Selected) {
+ //
+ // Go ask for input
+ //
+ Status = GetSelectionInputPopUp (Selection, MenuOption);
+ } else {
+ *OptionString = AllocateZeroPool (BufferSize);
+ ASSERT (*OptionString);
+
+ OneOfOption = ValueToOption (Question, QuestionValue);
+ if (OneOfOption == NULL) {
+ //
+ // Show error message
+ //
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+
+ //
+ // Force the Question value to be valid
+ //
+ Link = GetFirstNode (&Question->OptionListHead);
+ while (!IsNull (&Question->OptionListHead, Link)) {
+ Option = QUESTION_OPTION_FROM_LINK (Link);
+
+ if ((Option->SuppressExpression == NULL) ||
+ (EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)) {
+ CopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE));
+ SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
+ UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
+ break;
+ }
+
+ Link = GetNextNode (&Question->OptionListHead, Link);
+ }
+
+ FreePool (*OptionString);
+ *OptionString = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ Character[0] = LEFT_ONEOF_DELIMITER;
+ NewStrCat (OptionString[0], Character);
+ StringPtr = GetToken (OneOfOption->Text, Selection->Handle);
+ ASSERT (StringPtr != NULL);
+ NewStrCat (OptionString[0], StringPtr);
+ Character[0] = RIGHT_ONEOF_DELIMITER;
+ NewStrCat (OptionString[0], Character);
+
+ FreePool (StringPtr);
+ }
+ break;
+
+ case EFI_IFR_CHECKBOX_OP:
+ *OptionString = AllocateZeroPool (BufferSize);
+ ASSERT (*OptionString);
+
+ *OptionString[0] = LEFT_CHECKBOX_DELIMITER;
+
+ if (Selected) {
+ //
+ // Since this is a BOOLEAN operation, flip it upon selection
+ //
+ QuestionValue->Value.b = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);
+
+ //
+ // Perform inconsistent check
+ //
+ Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
+ if (EFI_ERROR (Status)) {
+ //
+ // Inconsistent check fail, restore Question Value
+ //
+ QuestionValue->Value.b = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);
+ FreePool (*OptionString);
+ *OptionString = NULL;
+ return Status;
+ }
+
+ //
+ // Save Question value
+ //
+ Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
+ UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
+ }
+
+ if (QuestionValue->Value.b) {
+ *(OptionString[0] + 1) = CHECK_ON;
+ } else {
+ *(OptionString[0] + 1) = CHECK_OFF;
+ }
+ *(OptionString[0] + 2) = RIGHT_CHECKBOX_DELIMITER;
+ break;
+
+ case EFI_IFR_NUMERIC_OP:
+ if (Selected) {
+ //
+ // Go ask for input
+ //
+ Status = GetNumericInput (Selection, MenuOption);
+ } else {
+ *OptionString = AllocateZeroPool (BufferSize);
+ ASSERT (*OptionString);
+
+ *OptionString[0] = LEFT_NUMERIC_DELIMITER;
+
+ //
+ // Formatted print
+ //
+ PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
+ Number = (UINT16) GetStringWidth (FormattedNumber);
+ CopyMem (OptionString[0] + 1, FormattedNumber, Number);
+
+ *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER;
+ }
+ break;
+
+ case EFI_IFR_DATE_OP:
+ if (Selected) {
+ //
+ // This is similar to numerics
+ //
+ Status = GetNumericInput (Selection, MenuOption);
+ } else {
+ *OptionString = AllocateZeroPool (BufferSize);
+ ASSERT (*OptionString);
+
+ switch (MenuOption->Sequence) {
+ case 0:
+ *OptionString[0] = LEFT_NUMERIC_DELIMITER;
+ UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Month);
+ *(OptionString[0] + 3) = DATE_SEPARATOR;
+ break;
+
+ case 1:
+ SetUnicodeMem (OptionString[0], 4, L' ');
+ UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Day);
+ *(OptionString[0] + 6) = DATE_SEPARATOR;
+ break;
+
+ case 2:
+ SetUnicodeMem (OptionString[0], 7, L' ');
+ UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", QuestionValue->Value.date.Year);
+ *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER;
+ break;
+ }
+ }
+ break;
+
+ case EFI_IFR_TIME_OP:
+ if (Selected) {
+ //
+ // This is similar to numerics
+ //
+ Status = GetNumericInput (Selection, MenuOption);
+ } else {
+ *OptionString = AllocateZeroPool (BufferSize);
+ ASSERT (*OptionString);
+
+ switch (MenuOption->Sequence) {
+ case 0:
+ *OptionString[0] = LEFT_NUMERIC_DELIMITER;
+ UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Hour);
+ *(OptionString[0] + 3) = TIME_SEPARATOR;
+ break;
+
+ case 1:
+ SetUnicodeMem (OptionString[0], 4, L' ');
+ UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Minute);
+ *(OptionString[0] + 6) = TIME_SEPARATOR;
+ break;
+
+ case 2:
+ SetUnicodeMem (OptionString[0], 7, L' ');
+ UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Second);
+ *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER;
+ break;
+ }
+ }
+ break;
+
+ case EFI_IFR_STRING_OP:
+ if (Selected) {
+ StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
+ ASSERT (StringPtr);
+ CopyMem(StringPtr, Question->BufferValue, Maximum * sizeof (CHAR16));
+
+ Status = ReadString (MenuOption, gPromptForData, StringPtr);
+ if (!EFI_ERROR (Status)) {
+ HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, StringPtr, NULL);
+ Status = ValidateQuestion(Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
+ if (EFI_ERROR (Status)) {
+ HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);
+ } else {
+ CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));
+ SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
+
+ UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
+ }
+ }
+
+ FreePool (StringPtr);
+ } else {
+ *OptionString = AllocateZeroPool (BufferSize);
+ ASSERT (*OptionString);
+
+ if (((CHAR16 *) Question->BufferValue)[0] == 0x0000) {
+ *(OptionString[0]) = '_';
+ } else {
+ if ((Maximum * sizeof (CHAR16)) < BufferSize) {
+ BufferSize = Maximum * sizeof (CHAR16);
+ }
+ CopyMem (OptionString[0], (CHAR16 *) Question->BufferValue, BufferSize);
+ }
+ }
+ break;
+
+ case EFI_IFR_PASSWORD_OP:
+ if (Selected) {
+ StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
+ ASSERT (StringPtr);
+
+ //
+ // For interactive passwords, old password is validated by callback
+ //
+ if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ //
+ // Use a NULL password to test whether old password is required
+ //
+ *StringPtr = 0;
+ Status = PasswordCallback (Selection, MenuOption, StringPtr);
+ if (Status == EFI_NOT_AVAILABLE_YET || Status == EFI_UNSUPPORTED) {
+ //
+ // Callback is not supported, or
+ // Callback request to terminate password input
+ //
+ FreePool (StringPtr);
+ return EFI_SUCCESS;
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Old password exist, ask user for the old password
+ //
+ Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
+ if (EFI_ERROR (Status)) {
+ FreePool (StringPtr);
+ return Status;
+ }
+
+ //
+ // Check user input old password
+ //
+ Status = PasswordCallback (Selection, MenuOption, StringPtr);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_NOT_READY) {
+ //
+ // Typed in old password incorrect
+ //
+ PasswordInvalid ();
+ } else {
+ Status = EFI_SUCCESS;
+ }
+
+ FreePool (StringPtr);
+ return Status;
+ }
+ }
+ } else {
+ //
+ // For non-interactive password, validate old password in local
+ //
+ if (*((CHAR16 *) Question->BufferValue) != 0) {
+ //
+ // There is something there! Prompt for password
+ //
+ Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
+ if (EFI_ERROR (Status)) {
+ FreePool (StringPtr);
+ return Status;
+ }
+
+ TempString = AllocateCopyPool ((Maximum + 1) * sizeof (CHAR16), Question->BufferValue);
+ ASSERT (TempString != NULL);
+
+ TempString[Maximum] = L'\0';
+
+ if (StrCmp (StringPtr, TempString) != 0) {
+ //
+ // Typed in old password incorrect
+ //
+ PasswordInvalid ();
+
+ FreePool (StringPtr);
+ FreePool (TempString);
+ return Status;
+ }
+
+ FreePool (TempString);
+ }
+ }
+
+ //
+ // Ask for new password
+ //
+ ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
+ Status = ReadString (MenuOption, gPromptForNewPassword, StringPtr);
+ if (EFI_ERROR (Status)) {
+ //
+ // Reset state machine for interactive password
+ //
+ if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ PasswordCallback (Selection, MenuOption, NULL);
+ }
+
+ FreePool (StringPtr);
+ return Status;
+ }
+
+ //
+ // Confirm new password
+ //
+ TempString = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
+ ASSERT (TempString);
+ Status = ReadString (MenuOption, gConfirmPassword, TempString);
+ if (EFI_ERROR (Status)) {
+ //
+ // Reset state machine for interactive password
+ //
+ if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ PasswordCallback (Selection, MenuOption, NULL);
+ }
+
+ FreePool (StringPtr);
+ FreePool (TempString);
+ return Status;
+ }
+
+ //
+ // Compare two typed-in new passwords
+ //
+ if (StrCmp (StringPtr, TempString) == 0) {
+ //
+ // Prepare the Question->HiiValue.Value.string for ValidateQuestion use.
+ //
+ if((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ StringId = Question->HiiValue.Value.string;
+ Question->HiiValue.Value.string = NewString (StringPtr, Selection->FormSet->HiiHandle);
+ } else {
+ HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, StringPtr, NULL);
+ }
+
+ Status = ValidateQuestion(Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
+
+ //
+ // Researve the Question->HiiValue.Value.string.
+ //
+ if((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ DeleteString(Question->HiiValue.Value.string, Selection->FormSet->HiiHandle);
+ Question->HiiValue.Value.string = StringId;
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Reset state machine for interactive password
+ //
+ if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ PasswordCallback (Selection, MenuOption, NULL);
+ } else {
+ //
+ // Researve the Question->HiiValue.Value.string.
+ //
+ HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);
+ }
+ } else {
+ //
+ // Two password match, send it to Configuration Driver
+ //
+ if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ PasswordCallback (Selection, MenuOption, StringPtr);
+ } else {
+ CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));
+ SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithHiiDriver);
+ }
+ }
+ } else {
+ //
+ // Reset state machine for interactive password
+ //
+ if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ PasswordCallback (Selection, MenuOption, NULL);
+ }
+
+ //
+ // Two password mismatch, prompt error message
+ //
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gConfirmError, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ }
+
+ FreePool (TempString);
+ FreePool (StringPtr);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return Status;
+}
+
+
+/**
+ Process the help string: Split StringPtr to several lines of strings stored in
+ FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.
+
+ @param StringPtr The entire help string.
+ @param FormattedString The oupput formatted string.
+ @param EachLineWidth The max string length of each line in the formatted string.
+ @param RowCount TRUE: if Question is selected.
+
+**/
+UINTN
+ProcessHelpString (
+ IN CHAR16 *StringPtr,
+ OUT CHAR16 **FormattedString,
+ OUT UINT16 *EachLineWidth,
+ IN UINTN RowCount
+ )
+{
+ UINTN Index;
+ CHAR16 *OutputString;
+ UINTN TotalRowNum;
+ UINTN CheckedNum;
+ UINT16 GlyphWidth;
+ UINT16 LineWidth;
+ UINT16 MaxStringLen;
+ UINT16 StringLen;
+
+ TotalRowNum = 0;
+ CheckedNum = 0;
+ GlyphWidth = 1;
+ Index = 0;
+ MaxStringLen = 0;
+ StringLen = 0;
+
+ //
+ // Set default help string width.
+ //
+ LineWidth = (UINT16) (gHelpBlockWidth - 1);
+
+ //
+ // Get row number of the String.
+ //
+ while ((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {
+ if (StringLen > MaxStringLen) {
+ MaxStringLen = StringLen;
+ }
+
+ TotalRowNum ++;
+ FreePool (OutputString);
+ }
+ *EachLineWidth = MaxStringLen;
+
+ *FormattedString = AllocateZeroPool (TotalRowNum * MaxStringLen * sizeof (CHAR16));
+ ASSERT (*FormattedString != NULL);
+
+ //
+ // Generate formatted help string array.
+ //
+ GlyphWidth = 1;
+ Index = 0;
+ while((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {
+ CopyMem (*FormattedString + CheckedNum * MaxStringLen, OutputString, StringLen * sizeof (CHAR16));
+ CheckedNum ++;
+ FreePool (OutputString);
+ }
+
+ return TotalRowNum;
+}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c index ba72d1220b..ed904161b6 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c @@ -26,281 +26,167 @@ SETUP_DRIVER_PRIVATE_DATA mPrivateData = { RegisterHotKey,
RegiserExitHandler,
SaveReminder
- },
- {
- BROWSER_EXTENSION2_VERSION_1,
- SetScope,
- RegisterHotKey,
- RegiserExitHandler,
- IsBrowserDataModified,
- ExecuteAction,
}
};
EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
+EFI_HII_STRING_PROTOCOL *mHiiString;
EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;
EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;
-EDKII_FORM_DISPLAY_ENGINE_PROTOCOL *mFormDisplay;
UINTN gBrowserContextCount = 0;
LIST_ENTRY gBrowserContextList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList);
LIST_ENTRY gBrowserFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserFormSetList);
LIST_ENTRY gBrowserHotKeyList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserHotKeyList);
-LIST_ENTRY gBrowserStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);
+LIST_ENTRY gBrowserStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);
+BANNER_DATA *gBannerData;
+EFI_HII_HANDLE gFrontPageHandle;
+UINTN gClassOfVfr;
+UINTN gFunctionKeySetting;
BOOLEAN gResetRequired;
-BOOLEAN gExitRequired;
+EFI_HII_HANDLE gHiiHandle;
+UINT16 gDirection;
+EFI_SCREEN_DESCRIPTOR gScreenDimensions;
BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;
BOOLEAN mBrowserScopeFirstSet = TRUE;
EXIT_HANDLER ExitHandlerFunction = NULL;
+UINTN gFooterHeight;
//
// Browser Global Strings
//
+CHAR16 *gSaveFailed;
+CHAR16 *gDiscardFailed;
+CHAR16 *gDefaultFailed;
+CHAR16 *gEnterString;
+CHAR16 *gEnterCommitString;
+CHAR16 *gEnterEscapeString;
+CHAR16 *gEscapeString;
+CHAR16 *gMoveHighlight;
+CHAR16 *gMakeSelection;
+CHAR16 *gDecNumericInput;
+CHAR16 *gHexNumericInput;
+CHAR16 *gToggleCheckBox;
+CHAR16 *gPromptForData;
+CHAR16 *gPromptForPassword;
+CHAR16 *gPromptForNewPassword;
+CHAR16 *gConfirmPassword;
+CHAR16 *gConfirmError;
+CHAR16 *gPassowordInvalid;
+CHAR16 *gPressEnter;
CHAR16 *gEmptyString;
-CHAR16 *mUnknownString = L"!";
-
-EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
-
-extern UINT32 gBrowserStatus;
-extern CHAR16 *gErrorInfo;
-extern EFI_GUID mCurrentFormSetGuid;
-extern EFI_HII_HANDLE mCurrentHiiHandle;
-extern UINT16 mCurrentFormId;
-extern FORM_DISPLAY_ENGINE_FORM gDisplayFormData;
+CHAR16 *gAreYouSure;
+CHAR16 *gYesResponse;
+CHAR16 *gNoResponse;
+CHAR16 *gMiniString;
+CHAR16 *gPlusString;
+CHAR16 *gMinusString;
+CHAR16 *gAdjustNumber;
+CHAR16 *gSaveChanges;
+CHAR16 *gOptionMismatch;
+CHAR16 *gFormSuppress;
+CHAR16 *gProtocolNotFound;
-/**
- Create a menu with specified formset GUID and form ID, and add it as a child
- of the given parent menu.
-
- @param HiiHandle Hii handle related to this formset.
- @param FormSetGuid The Formset Guid of menu to be added.
- @param FormId The Form ID of menu to be added.
- @param QuestionId The question id of this menu to be added.
-
- @return A pointer to the newly added menu or NULL if memory is insufficient.
-
-**/
-FORM_ENTRY_INFO *
-UiAddMenuList (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_GUID *FormSetGuid,
- IN UINT16 FormId,
- IN UINT16 QuestionId
- )
-{
- FORM_ENTRY_INFO *MenuList;
+CHAR16 *mUnknownString = L"!";
- MenuList = AllocateZeroPool (sizeof (FORM_ENTRY_INFO));
- if (MenuList == NULL) {
- return NULL;
- }
+CHAR16 gPromptBlockWidth;
+CHAR16 gOptionBlockWidth;
+CHAR16 gHelpBlockWidth;
- MenuList->Signature = FORM_ENTRY_INFO_SIGNATURE;
+EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
+EFI_GUID gSetupBrowserGuid = {
+ 0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}
+};
- MenuList->HiiHandle = HiiHandle;
- CopyMem (&MenuList->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));
- MenuList->FormId = FormId;
- MenuList->QuestionId = QuestionId;
+FORM_BROWSER_FORMSET *gOldFormSet = NULL;
+FUNCTIION_KEY_SETTING gFunctionKeySettingTable[] = {
//
- // If parent is not specified, it is the root Form of a Formset
+ // Boot Manager
//
- InsertTailList (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &MenuList->Link);
-
- return MenuList;
-}
-
-/**
- Return the form id for the input hiihandle and formset.
-
- @param HiiHandle HiiHandle for FormSet.
- @param FormSetGuid The Formset GUID of the menu to search.
-
- @return First form's id for this form set.
-
-**/
-EFI_FORM_ID
-GetFirstFormId (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_GUID *FormSetGuid
- )
-{
- LIST_ENTRY *Link;
- FORM_BROWSER_FORM *Form;
-
- Link = GetFirstNode (&gCurrentSelection->FormSet->FormListHead);
- Form = FORM_BROWSER_FORM_FROM_LINK (Link);
-
- return Form->FormId;
-}
-
-/**
- Search Menu with given FormSetGuid and FormId in all cached menu list.
-
- @param HiiHandle HiiHandle for FormSet.
- @param FormSetGuid The Formset GUID of the menu to search.
- @param FormId The Form ID of menu to search.
-
- @return A pointer to menu found or NULL if not found.
-
-**/
-FORM_ENTRY_INFO *
-UiFindMenuList (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_GUID *FormSetGuid,
- IN UINT16 FormId
- )
-{
- LIST_ENTRY *Link;
- FORM_ENTRY_INFO *MenuList;
- FORM_ENTRY_INFO *RetMenu;
- EFI_FORM_ID FirstFormId;
-
- RetMenu = NULL;
-
- Link = GetFirstNode (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);
- while (!IsNull (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, Link)) {
- MenuList = FORM_ENTRY_INFO_FROM_LINK (Link);
- Link = GetNextNode (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, Link);
-
- //
- // If already find the menu, free the menus behind it.
- //
- if (RetMenu != NULL) {
- RemoveEntryList (&MenuList->Link);
- FreePool (MenuList);
- continue;
- }
-
- //
- // Find the same FromSet.
- //
- if (MenuList->HiiHandle == HiiHandle) {
- if (CompareGuid (&MenuList->FormSetGuid, &gZeroGuid)) {
- //
- // FormSetGuid is not specified.
- //
- RetMenu = MenuList;
- } else if (CompareGuid (&MenuList->FormSetGuid, FormSetGuid)) {
- if (MenuList->FormId == FormId) {
- RetMenu = MenuList;
- } else if (FormId == 0 || MenuList->FormId == 0 ) {
- FirstFormId = GetFirstFormId (HiiHandle, FormSetGuid);
- if ((FormId == 0 && FirstFormId == MenuList->FormId) || (MenuList->FormId ==0 && FirstFormId == FormId)) {
- RetMenu = MenuList;
- }
- }
+ {
+ {
+ 0x847bc3fe,
+ 0xb974,
+ 0x446d,
+ {
+ 0x94,
+ 0x49,
+ 0x5a,
+ 0xd5,
+ 0x41,
+ 0x2e,
+ 0x99,
+ 0x3b
}
- }
- }
-
- return RetMenu;
-}
-
-/**
- Find parent menu for current menu.
-
- @param CurrentMenu Current Menu
-
- @retval The parent menu for current menu.
-**/
-FORM_ENTRY_INFO *
-UiFindParentMenu (
- IN FORM_ENTRY_INFO *CurrentMenu
- )
-{
- FORM_ENTRY_INFO *ParentMenu;
-
- ParentMenu = NULL;
- if (CurrentMenu->Link.BackLink != &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {
- ParentMenu = FORM_ENTRY_INFO_FROM_LINK (CurrentMenu->Link.BackLink);
- }
-
- return ParentMenu;
-}
-
-/**
- Free Menu list linked list.
-
- @param MenuListHead One Menu list point in the menu list.
-
-**/
-VOID
-UiFreeMenuList (
- LIST_ENTRY *MenuListHead
- )
-{
- FORM_ENTRY_INFO *MenuList;
-
- while (!IsListEmpty (MenuListHead)) {
- MenuList = FORM_ENTRY_INFO_FROM_LINK (MenuListHead->ForwardLink);
- RemoveEntryList (&MenuList->Link);
-
- FreePool (MenuList);
- }
-}
-
-/**
- Load all hii formset to the browser.
-
-**/
-VOID
-LoadAllHiiFormset (
- VOID
- )
-{
- FORM_BROWSER_FORMSET *LocalFormSet;
- EFI_HII_HANDLE *HiiHandles;
- UINTN Index;
- EFI_GUID ZeroGuid;
- EFI_STATUS Status;
-
+ },
+ NONE_FUNCTION_KEY_SETTING
+ },
//
- // Get all the Hii handles
+ // Device Manager
//
- HiiHandles = HiiGetHiiHandles (NULL);
- ASSERT (HiiHandles != NULL);
-
+ {
+ {
+ 0x3ebfa8e6,
+ 0x511d,
+ 0x4b5b,
+ {
+ 0xa9,
+ 0x5f,
+ 0xfb,
+ 0x38,
+ 0x26,
+ 0xf,
+ 0x1c,
+ 0x27
+ }
+ },
+ NONE_FUNCTION_KEY_SETTING
+ },
//
- // Search for formset of each class type
+ // BMM FormSet.
//
- for (Index = 0; HiiHandles[Index] != NULL; Index++) {
- //
- // Check HiiHandles[Index] does exist in global maintain list.
- //
- if (GetFormSetFromHiiHandle (HiiHandles[Index]) != NULL) {
- continue;
- }
-
- //
- // Initilize FormSet Setting
- //
- LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
- ASSERT (LocalFormSet != NULL);
- ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
- Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet);
- if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {
- DestroyFormSet (LocalFormSet);
- continue;
- }
- InitializeCurrentSetting (LocalFormSet);
-
- //
- // Initilize Questions' Value
- //
- Status = LoadFormSetConfig (NULL, LocalFormSet);
- if (EFI_ERROR (Status)) {
- DestroyFormSet (LocalFormSet);
- continue;
- }
- }
-
+ {
+ {
+ 0x642237c7,
+ 0x35d4,
+ 0x472d,
+ {
+ 0x83,
+ 0x65,
+ 0x12,
+ 0xe0,
+ 0xcc,
+ 0xf2,
+ 0x7a,
+ 0x22
+ }
+ },
+ NONE_FUNCTION_KEY_SETTING
+ },
//
- // Free resources, and restore gOldFormSet and gClassOfVfr
+ // BMM File Explorer FormSet.
//
- FreePool (HiiHandles);
-}
+ {
+ {
+ 0x1f2d63e1,
+ 0xfebd,
+ 0x4dc7,
+ {
+ 0x9c,
+ 0xc5,
+ 0xba,
+ 0x2b,
+ 0x1c,
+ 0xef,
+ 0x9c,
+ 0x5b
+ }
+ },
+ NONE_FUNCTION_KEY_SETTING
+ },
+};
/**
This is the routine which an external caller uses to direct the browser
@@ -343,14 +229,26 @@ SendForm ( UI_MENU_SELECTION *Selection;
UINTN Index;
FORM_BROWSER_FORMSET *FormSet;
- FORM_ENTRY_INFO *MenuList;
+ LIST_ENTRY *Link;
//
- // If EDKII_FORM_DISPLAY_ENGINE_PROTOCOL not found, return EFI_UNSUPPORTED.
+ // Calculate total number of Register HotKeys.
//
- if (mFormDisplay == NULL) {
- return EFI_UNSUPPORTED;
+ Index = 0;
+ Link = GetFirstNode (&gBrowserHotKeyList);
+ while (!IsNull (&gBrowserHotKeyList, Link)) {
+ Link = GetNextNode (&gBrowserHotKeyList, Link);
+ Index ++;
}
+ //
+ // Show three HotKeys help information on one ROW.
+ //
+ gFooterHeight = FOOTER_HEIGHT + (Index / 3);
+
+ //
+ // Clean the history menu list.
+ //
+ InitializeListHead (&gMenuList);
//
// Save globals used by SendForm()
@@ -358,10 +256,65 @@ SendForm ( SaveBrowserContext ();
gResetRequired = FALSE;
- gExitRequired = FALSE;
- Status = EFI_SUCCESS;
- gEmptyString = L"";
- gDisplayFormData.ScreenDimensions = (EFI_SCREEN_DESCRIPTOR *) ScreenDimensions;
+ Status = EFI_SUCCESS;
+ ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
+
+ //
+ // Seed the dimensions in the global
+ //
+ gST->ConOut->QueryMode (
+ gST->ConOut,
+ gST->ConOut->Mode->Mode,
+ &gScreenDimensions.RightColumn,
+ &gScreenDimensions.BottomRow
+ );
+
+ if (ScreenDimensions != NULL) {
+ //
+ // Check local dimension vs. global dimension.
+ //
+ if ((gScreenDimensions.RightColumn < ScreenDimensions->RightColumn) ||
+ (gScreenDimensions.BottomRow < ScreenDimensions->BottomRow)
+ ) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ } else {
+ //
+ // Local dimension validation.
+ //
+ if ((ScreenDimensions->RightColumn > ScreenDimensions->LeftColumn) &&
+ (ScreenDimensions->BottomRow > ScreenDimensions->TopRow) &&
+ ((ScreenDimensions->RightColumn - ScreenDimensions->LeftColumn) > 2) &&
+ (
+ (ScreenDimensions->BottomRow - ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +
+ SCROLL_ARROW_HEIGHT *
+ 2 +
+ FRONT_PAGE_HEADER_HEIGHT +
+ gFooterHeight +
+ 1
+ )
+ ) {
+ CopyMem (&gScreenDimensions, (VOID *) ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+ }
+ }
+
+ gOptionBlockWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);
+ gPromptBlockWidth = (CHAR16) (gOptionBlockWidth + LEFT_SKIPPED_COLUMNS);
+ gHelpBlockWidth = (CHAR16) (gOptionBlockWidth - LEFT_SKIPPED_COLUMNS);
+
+ //
+ // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
+ //
+ InitializeBrowserStrings ();
+
+ //
+ // Ensure we are in Text mode
+ //
+ gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
for (Index = 0; Index < HandleCount; Index++) {
Selection = AllocateZeroPool (sizeof (UI_MENU_SELECTION));
@@ -382,7 +335,7 @@ SendForm ( //
// Initialize internal data structures of FormSet
//
- Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet);
+ Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet, TRUE);
if (EFI_ERROR (Status) || IsListEmpty (&FormSet->FormListHead)) {
DestroyFormSet (FormSet);
break;
@@ -390,6 +343,11 @@ SendForm ( Selection->FormSet = FormSet;
//
+ // Try to find pre FormSet in the maintain backup list.
+ //
+ gOldFormSet = GetFormSetFromHiiHandle (Selection->Handle);
+
+ //
// Display this formset
//
gCurrentSelection = Selection;
@@ -398,34 +356,25 @@ SendForm ( gCurrentSelection = NULL;
- //
- // If no data is changed, don't need to save current FormSet into the maintain list.
- //
- if (!IsNvUpdateRequiredForFormSet (FormSet) && !IsStorageDataChangedForFormSet(FormSet)) {
- CleanBrowserStorage(FormSet);
- RemoveEntryList (&FormSet->Link);
- DestroyFormSet (FormSet);
- }
-
if (EFI_ERROR (Status)) {
break;
}
- } while (Selection->Action == UI_ACTION_REFRESH_FORMSET);
- FreePool (Selection);
- }
-
- //
- // Still has error info, pop up a message.
- //
- if (gBrowserStatus != BROWSER_SUCCESS) {
- gDisplayFormData.BrowserStatus = gBrowserStatus;
- gDisplayFormData.ErrorString = gErrorInfo;
+ } while (Selection->Action == UI_ACTION_REFRESH_FORMSET);
- gBrowserStatus = BROWSER_SUCCESS;
- gErrorInfo = NULL;
+ if (gOldFormSet != NULL) {
+ //
+ // If no data is changed, don't need to save current FormSet into the maintain list.
+ //
+ if (!IsNvUpdateRequired (gOldFormSet)) {
+ CleanBrowserStorage(gOldFormSet);
+ RemoveEntryList (&gOldFormSet->Link);
+ DestroyFormSet (gOldFormSet);
+ }
+ gOldFormSet = NULL;
+ }
- mFormDisplay->FormDisplay (&gDisplayFormData, NULL);
+ FreePool (Selection);
}
if (ActionRequest != NULL) {
@@ -435,17 +384,13 @@ SendForm ( }
}
- mFormDisplay->ExitDisplay();
+ FreeBrowserStrings ();
+ UiFreeMenuList(&gMenuList);
- //
- // Clear the menu history data.
- //
- while (!IsListEmpty (&mPrivateData.FormBrowserEx2.FormViewHistoryHead)) {
- MenuList = FORM_ENTRY_INFO_FROM_LINK (mPrivateData.FormBrowserEx2.FormViewHistoryHead.ForwardLink);
- RemoveEntryList (&MenuList->Link);
- FreePool (MenuList);
- }
+ gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
+ gST->ConOut->ClearScreen (gST->ConOut);
+Done:
//
// Restore globals used by SendForm()
//
@@ -454,93 +399,10 @@ SendForm ( return Status;
}
-/**
- Get or set data to the storage.
-
- @param ResultsDataSize The size of the buffer associatedwith ResultsData.
- @param ResultsData A string returned from an IFR browser or
- equivalent. The results string will have no
- routing information in them.
- @param RetrieveData A BOOLEAN field which allows an agent to retrieve
- (if RetrieveData = TRUE) data from the uncommitted
- browser state information or set (if RetrieveData
- = FALSE) data in the uncommitted browser state
- information.
- @param Storage The pointer to the storage.
-
- @retval EFI_SUCCESS The results have been distributed or are awaiting
- distribution.
-
-**/
-EFI_STATUS
-ProcessStorage (
- IN OUT UINTN *ResultsDataSize,
- IN OUT EFI_STRING *ResultsData,
- IN BOOLEAN RetrieveData,
- IN BROWSER_STORAGE *Storage
- )
-{
- CHAR16 *ConfigResp;
- EFI_STATUS Status;
- CHAR16 *StrPtr;
- UINTN BufferSize;
- UINTN TmpSize;
-
- if (RetrieveData) {
- //
- // Generate <ConfigResp>
- //
- Status = StorageToConfigResp (Storage, &ConfigResp, Storage->ConfigRequest, TRUE);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Skip <ConfigHdr> and '&' to point to <ConfigBody> when first copy the configbody.
- // Also need to consider add "\0" at first time.
- //
- StrPtr = ConfigResp + StrLen (Storage->ConfigHdr) + 1;
- BufferSize = StrSize (StrPtr);
-
-
- //
- // Copy the data if the input buffer is bigger enough.
- //
- if (*ResultsDataSize >= BufferSize) {
- StrCpy (*ResultsData, StrPtr);
- }
-
- *ResultsDataSize = BufferSize;
- FreePool (ConfigResp);
- } else {
- //
- // Prepare <ConfigResp>
- //
- TmpSize = StrLen (*ResultsData);
- BufferSize = (TmpSize + StrLen (Storage->ConfigHdr) + 2) * sizeof (CHAR16);
- ConfigResp = AllocateZeroPool (BufferSize);
- ASSERT (ConfigResp != NULL);
-
- StrCpy (ConfigResp, Storage->ConfigHdr);
- StrCat (ConfigResp, L"&");
- StrCat (ConfigResp, *ResultsData);
-
- //
- // Update Browser uncommited data
- //
- Status = ConfigRespToStorage (Storage, ConfigResp);
- FreePool (ConfigResp);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
-
- return EFI_SUCCESS;
-}
/**
- This routine called this service in the browser to retrieve or set certain uncommitted
- state information that resides in the open formsets.
+ This function is called by a callback handler to retrieve uncommitted state
+ data from the browser.
@param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL
instance.
@@ -578,69 +440,60 @@ BrowserCallback ( {
EFI_STATUS Status;
LIST_ENTRY *Link;
- BROWSER_STORAGE *Storage;
- FORMSET_STORAGE *FormsetStorage;
+ FORMSET_STORAGE *Storage;
FORM_BROWSER_FORMSET *FormSet;
- UINTN TotalSize;
BOOLEAN Found;
+ CHAR16 *ConfigResp;
+ CHAR16 *StrPtr;
+ UINTN BufferSize;
+ UINTN TmpSize;
if (ResultsDataSize == NULL || ResultsData == NULL) {
return EFI_INVALID_PARAMETER;
}
- TotalSize = *ResultsDataSize;
- Storage = NULL;
- Found = FALSE;
- Status = EFI_SUCCESS;
+ if (gCurrentSelection == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ Storage = NULL;
+ ConfigResp = NULL;
+ FormSet = gCurrentSelection->FormSet;
//
- // If set browser data, pre load all hii formset to avoid set the varstore which is not
- // saved in browser.
+ // Find target storage
//
- if (!RetrieveData && (gBrowserSettingScope == SystemLevel)) {
- LoadAllHiiFormset();
+ Link = GetFirstNode (&FormSet->StorageListHead);
+ if (IsNull (&FormSet->StorageListHead, Link)) {
+ return EFI_UNSUPPORTED;
}
if (VariableGuid != NULL) {
//
- // Try to find target storage in the current formset.
+ // Try to find target storage
//
- Link = GetFirstNode (&gBrowserStorageList);
- while (!IsNull (&gBrowserStorageList, Link)) {
- Storage = BROWSER_STORAGE_FROM_LINK (Link);
- Link = GetNextNode (&gBrowserStorageList, Link);
- //
- // Check the current storage.
- //
- if (!CompareGuid (&Storage->Guid, (EFI_GUID *) VariableGuid)) {
- continue;
- }
+ Found = FALSE;
+ while (!IsNull (&FormSet->StorageListHead, Link)) {
+ Storage = FORMSET_STORAGE_FROM_LINK (Link);
+ Link = GetNextNode (&FormSet->StorageListHead, Link);
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
- Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- //
- // Buffer storage require both GUID and Name
- //
- if (VariableName == NULL) {
- return EFI_NOT_FOUND;
- }
+ if (CompareGuid (&Storage->BrowserStorage->Guid, (EFI_GUID *) VariableGuid)) {
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ //
+ // Buffer storage require both GUID and Name
+ //
+ if (VariableName == NULL) {
+ return EFI_NOT_FOUND;
+ }
- if (StrCmp (Storage->Name, (CHAR16 *) VariableName) != 0) {
- continue;
+ if (StrCmp (Storage->BrowserStorage->Name, (CHAR16 *) VariableName) != 0) {
+ continue;
+ }
}
+ Found = TRUE;
+ break;
}
-
- Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, Storage);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Different formsets may have same varstore, so here just set the flag
- // not exit the circle.
- //
- Found = TRUE;
- break;
}
if (!Found) {
@@ -650,62 +503,65 @@ BrowserCallback ( //
// GUID/Name is not specified, take the first storage in FormSet
//
- if (gCurrentSelection == NULL) {
- return EFI_NOT_READY;
- }
+ Storage = FORMSET_STORAGE_FROM_LINK (Link);
+ }
+ if (RetrieveData) {
//
- // Generate <ConfigResp>
+ // Skip if there is no RequestElement
//
- FormSet = gCurrentSelection->FormSet;
- Link = GetFirstNode (&FormSet->StorageListHead);
- if (IsNull (&FormSet->StorageListHead, Link)) {
- return EFI_UNSUPPORTED;
+ if (Storage->ElementCount == 0) {
+ return EFI_SUCCESS;
}
- FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);
-
- Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, FormsetStorage->BrowserStorage);
+ //
+ // Generate <ConfigResp>
+ //
+ Status = StorageToConfigResp (Storage->BrowserStorage, &ConfigResp, Storage->ConfigRequest);
if (EFI_ERROR (Status)) {
return Status;
}
- }
- if (RetrieveData) {
- Status = TotalSize <= *ResultsDataSize ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
- *ResultsDataSize = TotalSize;
- }
-
- return Status;
+ //
+ // Skip <ConfigHdr> and '&' to point to <ConfigBody>
+ //
+ StrPtr = ConfigResp + StrLen (Storage->BrowserStorage->ConfigHdr) + 1;
-}
+ BufferSize = StrSize (StrPtr);
+ if (*ResultsDataSize < BufferSize) {
+ *ResultsDataSize = BufferSize;
+ FreePool (ConfigResp);
+ return EFI_BUFFER_TOO_SMALL;
+ }
-/**
- Callback function for SimpleTextInEx protocol install events
+ *ResultsDataSize = BufferSize;
+ CopyMem (ResultsData, StrPtr, BufferSize);
- @param Event the event that is signaled.
- @param Context not used here.
+ FreePool (ConfigResp);
+ } else {
+ //
+ // Prepare <ConfigResp>
+ //
+ TmpSize = StrLen (ResultsData);
+ BufferSize = (TmpSize + StrLen (Storage->BrowserStorage->ConfigHdr) + 2) * sizeof (CHAR16);
+ ConfigResp = AllocateZeroPool (BufferSize);
+ ASSERT (ConfigResp != NULL);
-**/
-VOID
-EFIAPI
-FormDisplayCallback (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
+ StrCpy (ConfigResp, Storage->BrowserStorage->ConfigHdr);
+ StrCat (ConfigResp, L"&");
+ StrCat (ConfigResp, ResultsData);
- if (mFormDisplay != NULL) {
- return;
+ //
+ // Update Browser uncommited data
+ //
+ Status = ConfigRespToStorage (Storage->BrowserStorage, ConfigResp);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
}
- Status = gBS->LocateProtocol (
- &gEdkiiFormDisplayEngineProtocolGuid,
- NULL,
- (VOID **) &mFormDisplay
- );
+ return EFI_SUCCESS;
}
/**
@@ -726,7 +582,8 @@ InitializeSetup ( )
{
EFI_STATUS Status;
- VOID *Registration;
+ EFI_INPUT_KEY DefaultHotKey;
+ EFI_STRING HelpString;
//
// Locate required Hii relative protocols
@@ -739,6 +596,13 @@ InitializeSetup ( ASSERT_EFI_ERROR (Status);
Status = gBS->LocateProtocol (
+ &gEfiHiiStringProtocolGuid,
+ NULL,
+ (VOID **) &mHiiString
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (
&gEfiHiiConfigRoutingProtocolGuid,
NULL,
(VOID **) &mHiiConfigRouting
@@ -752,6 +616,30 @@ InitializeSetup ( );
//
+ // Publish our HII data
+ //
+ gHiiHandle = HiiAddPackages (
+ &gSetupBrowserGuid,
+ ImageHandle,
+ SetupBrowserStrings,
+ NULL
+ );
+ ASSERT (gHiiHandle != NULL);
+
+ //
+ // Initialize Driver private data
+ //
+ gBannerData = AllocateZeroPool (sizeof (BANNER_DATA));
+ ASSERT (gBannerData != NULL);
+
+ //
+ // Initialize generic help strings.
+ //
+ gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);
+ gDiscardFailed = GetToken (STRING_TOKEN (DISCARD_FAILED), gHiiHandle);
+ gDefaultFailed = GetToken (STRING_TOKEN (DEFAULT_FAILED), gHiiHandle);
+
+ //
// Install FormBrowser2 protocol
//
mPrivateData.Handle = NULL;
@@ -764,45 +652,34 @@ InitializeSetup ( ASSERT_EFI_ERROR (Status);
//
- // Install FormBrowserEx2 protocol
+ // Install default HotKey F10 for Save
+ //
+ DefaultHotKey.UnicodeChar = CHAR_NULL;
+ HelpString = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);
+ DefaultHotKey.ScanCode = SCAN_F10;
+ RegisterHotKey (&DefaultHotKey, BROWSER_ACTION_SUBMIT, 0, HelpString);
+ FreePool (HelpString);
+ //
+ // Install default HotKey F9 for Reset To Defaults
+ //
+ DefaultHotKey.ScanCode = SCAN_F9;
+ HelpString = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);
+ RegisterHotKey (&DefaultHotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, HelpString);
+ FreePool (HelpString);
+
+ //
+ // Install FormBrowserEx protocol
//
- InitializeListHead (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);
mPrivateData.Handle = NULL;
Status = gBS->InstallProtocolInterface (
&mPrivateData.Handle,
- &gEdkiiFormBrowserEx2ProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mPrivateData.FormBrowserEx2
- );
- ASSERT_EFI_ERROR (Status);
-
- Status = gBS->InstallProtocolInterface (
- &mPrivateData.Handle,
&gEfiFormBrowserExProtocolGuid,
EFI_NATIVE_INTERFACE,
&mPrivateData.FormBrowserEx
);
ASSERT_EFI_ERROR (Status);
- InitializeDisplayFormData ();
-
- Status = gBS->LocateProtocol (
- &gEdkiiFormDisplayEngineProtocolGuid,
- NULL,
- (VOID **) &mFormDisplay
- );
-
- if (EFI_ERROR (Status)) {
- EfiCreateProtocolNotifyEvent (
- &gEdkiiFormDisplayEngineProtocolGuid,
- TPL_CALLBACK,
- FormDisplayCallback,
- NULL,
- &Registration
- );
- }
-
- return EFI_SUCCESS;
+ return Status;
}
@@ -938,6 +815,58 @@ NewStringCat ( *Dest = NewString;
}
+
+/**
+ Synchronize or restore Storage's Edit copy and Shadow copy.
+
+ @param Storage The Storage to be synchronized.
+ @param SyncOrRestore Sync the buffer to editbuffer or Restore the
+ editbuffer to buffer
+ if TRUE, copy the editbuffer to the buffer.
+ if FALSE, copy the buffer to the editbuffer.
+
+**/
+VOID
+SynchronizeStorage (
+ IN BROWSER_STORAGE *Storage,
+ IN BOOLEAN SyncOrRestore
+ )
+{
+ LIST_ENTRY *Link;
+ NAME_VALUE_NODE *Node;
+
+ switch (Storage->Type) {
+ case EFI_HII_VARSTORE_BUFFER:
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
+ if (SyncOrRestore) {
+ CopyMem (Storage->Buffer, Storage->EditBuffer, Storage->Size);
+ } else {
+ CopyMem (Storage->EditBuffer, Storage->Buffer, Storage->Size);
+ }
+ break;
+
+ case EFI_HII_VARSTORE_NAME_VALUE:
+ Link = GetFirstNode (&Storage->NameValueListHead);
+ while (!IsNull (&Storage->NameValueListHead, Link)) {
+ Node = NAME_VALUE_NODE_FROM_LINK (Link);
+
+ if (SyncOrRestore) {
+ NewStringCpy (&Node->Value, Node->EditValue);
+ } else {
+ NewStringCpy (&Node->EditValue, Node->Value);
+ }
+
+ Link = GetNextNode (&Storage->NameValueListHead, Link);
+ }
+ break;
+
+ case EFI_HII_VARSTORE_EFI_VARIABLE:
+ default:
+ break;
+ }
+}
+
+
/**
Get Value for given Name from a NameValue Storage.
@@ -994,7 +923,6 @@ GetValueByName ( @param Name The Name.
@param Value The Value to set.
@param SetValueTo Whether update editValue or Value.
- @param ReturnNode The node use the input name.
@retval EFI_SUCCESS Value found for given Name.
@retval EFI_NOT_FOUND No such Name found in NameValue storage.
@@ -1002,11 +930,10 @@ GetValueByName ( **/
EFI_STATUS
SetValueByName (
- IN BROWSER_STORAGE *Storage,
- IN CHAR16 *Name,
- IN CHAR16 *Value,
- IN GET_SET_QUESTION_VALUE_WITH SetValueTo,
- OUT NAME_VALUE_NODE **ReturnNode
+ IN BROWSER_STORAGE *Storage,
+ IN CHAR16 *Name,
+ IN CHAR16 *Value,
+ IN GET_SET_QUESTION_VALUE_WITH SetValueTo
)
{
LIST_ENTRY *Link;
@@ -1037,11 +964,6 @@ SetValueByName ( } else {
Node->Value = Buffer;
}
-
- if (ReturnNode != NULL) {
- *ReturnNode = Node;
- }
-
return EFI_SUCCESS;
}
@@ -1058,7 +980,6 @@ SetValueByName ( @param Storage The Storage to be conveted.
@param ConfigResp The returned <ConfigResp>.
@param ConfigRequest The ConfigRequest string.
- @param GetEditBuf Get the data from editbuffer or buffer.
@retval EFI_SUCCESS Convert success.
@retval EFI_INVALID_PARAMETER Incorrect storage type.
@@ -1068,26 +989,23 @@ EFI_STATUS StorageToConfigResp (
IN BROWSER_STORAGE *Storage,
IN CHAR16 **ConfigResp,
- IN CHAR16 *ConfigRequest,
- IN BOOLEAN GetEditBuf
+ IN CHAR16 *ConfigRequest
)
{
EFI_STATUS Status;
EFI_STRING Progress;
LIST_ENTRY *Link;
NAME_VALUE_NODE *Node;
- UINT8 *SourceBuf;
Status = EFI_SUCCESS;
switch (Storage->Type) {
case EFI_HII_VARSTORE_BUFFER:
case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
- SourceBuf = GetEditBuf ? Storage->EditBuffer : Storage->Buffer;
Status = mHiiConfigRouting->BlockToConfig (
mHiiConfigRouting,
ConfigRequest,
- SourceBuf,
+ Storage->EditBuffer,
Storage->Size,
ConfigResp,
&Progress
@@ -1106,11 +1024,7 @@ StorageToConfigResp ( NewStringCat (ConfigResp, L"&");
NewStringCat (ConfigResp, Node->Name);
NewStringCat (ConfigResp, L"=");
- if (GetEditBuf) {
- NewStringCat (ConfigResp, Node->EditValue);
- } else {
- NewStringCat (ConfigResp, Node->Value);
- }
+ NewStringCat (ConfigResp, Node->EditValue);
}
Link = GetNextNode (&Storage->NameValueListHead, Link);
}
@@ -1191,7 +1105,7 @@ ConfigRespToStorage ( if (StrPtr != NULL) {
*StrPtr = 0;
}
- SetValueByName (Storage, Name, Value, GetSetValueWithEditBuffer, NULL);
+ SetValueByName (Storage, Name, Value, GetSetValueWithEditBuffer);
}
break;
@@ -1617,7 +1531,7 @@ GetQuestionValue ( if (IsBufferStorage) {
CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth);
} else {
- SetValueByName (Storage, Question->VariableName, Value, GetSetValueWithEditBuffer, NULL);
+ SetValueByName (Storage, Question->VariableName, Value, GetSetValueWithEditBuffer);
}
if (Result != NULL) {
@@ -1667,10 +1581,8 @@ SetQuestionValue ( CHAR16 *TemName;
CHAR16 *TemString;
UINTN Index;
- NAME_VALUE_NODE *Node;
Status = EFI_SUCCESS;
- Node = NULL;
if (SetValueTo >= GetSetValueWithMax) {
return EFI_INVALID_PARAMETER;
@@ -1805,14 +1717,6 @@ SetQuestionValue ( //
CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);
}
- //
- // Check whether question value has been changed.
- //
- if (CompareMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, StorageWidth) != 0) {
- Question->ValueChanged = TRUE;
- } else {
- Question->ValueChanged = FALSE;
- }
} else {
if (IsString) {
//
@@ -1844,19 +1748,8 @@ SetQuestionValue ( }
}
- Status = SetValueByName (Storage, Question->VariableName, Value, SetValueTo, &Node);
+ Status = SetValueByName (Storage, Question->VariableName, Value, SetValueTo);
FreePool (Value);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Check whether question value has been changed.
- //
- if (StrCmp (Node->Value, Node->EditValue) != 0) {
- Question->ValueChanged = TRUE;
- } else {
- Question->ValueChanged = FALSE;
- }
}
} else if (SetValueTo == GetSetValueWithHiiDriver) {
if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
@@ -1975,12 +1868,12 @@ SetQuestionValue ( /**
- Perform nosubmitif check for a Form.
+ Perform inconsistent check for a Form.
@param FormSet FormSet data structure.
@param Form Form data structure.
@param Question The Question to be validated.
- @param Type Validation type: NoSubmit
+ @param Type Validation type: InConsistent or NoSubmit
@retval EFI_SUCCESS Form validation pass.
@retval other Form validation failed.
@@ -1998,9 +1891,12 @@ ValidateQuestion ( LIST_ENTRY *Link;
LIST_ENTRY *ListHead;
EFI_STRING PopUp;
+ EFI_INPUT_KEY Key;
FORM_EXPRESSION *Expression;
- if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {
+ if (Type == EFI_HII_EXPRESSION_INCONSISTENT_IF) {
+ ListHead = &Question->InconsistentListHead;
+ } else if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {
ListHead = &Question->NoSubmitListHead;
} else {
return EFI_UNSUPPORTED;
@@ -2024,10 +1920,10 @@ ValidateQuestion ( //
if (Expression->Error != 0) {
PopUp = GetToken (Expression->Error, FormSet->HiiHandle);
- if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {
- gBrowserStatus = BROWSER_NO_SUBMIT_IF;
- gErrorInfo = PopUp;
- }
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, PopUp, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ FreePool (PopUp);
}
return EFI_NOT_READY;
@@ -2091,8 +1987,7 @@ NoSubmitCheck ( Fill storage's edit copy with settings requested from Configuration Driver.
@param FormSet FormSet data structure.
- @param Storage The storage which need to sync.
- @param ConfigRequest The config request string which used to sync storage.
+ @param ConfigInfo The config info related to this form.
@param SyncOrRestore Sync the buffer to editbuffer or Restore the
editbuffer to buffer
if TRUE, copy the editbuffer to the buffer.
@@ -2102,11 +1997,10 @@ NoSubmitCheck ( **/
EFI_STATUS
-SynchronizeStorage (
- IN FORM_BROWSER_FORMSET *FormSet,
- OUT BROWSER_STORAGE *Storage,
- IN CHAR16 *ConfigRequest,
- IN BOOLEAN SyncOrRestore
+SynchronizeStorageForForm (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo,
+ IN BOOLEAN SyncOrRestore
)
{
EFI_STATUS Status;
@@ -2120,52 +2014,57 @@ SynchronizeStorage ( Status = EFI_SUCCESS;
Result = NULL;
+ if (FormSet->ConfigAccess == NULL && ConfigInfo->Storage->Type != EFI_HII_VARSTORE_NAME_VALUE) {
+ return EFI_NOT_FOUND;
+ }
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
- (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
- BufferSize = Storage->Size;
+ if (ConfigInfo->ElementCount == 0) {
+ //
+ // Skip if there is no RequestElement
+ //
+ return EFI_SUCCESS;
+ }
+
+ if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
+ BufferSize = ConfigInfo->Storage->Size;
if (SyncOrRestore) {
- Src = Storage->EditBuffer;
- Dst = Storage->Buffer;
+ Src = ConfigInfo->Storage->EditBuffer;
+ Dst = ConfigInfo->Storage->Buffer;
} else {
- Src = Storage->Buffer;
- Dst = Storage->EditBuffer;
+ Src = ConfigInfo->Storage->Buffer;
+ Dst = ConfigInfo->Storage->EditBuffer;
}
- if (ConfigRequest != NULL) {
- Status = mHiiConfigRouting->BlockToConfig(
- mHiiConfigRouting,
- ConfigRequest,
- Src,
- BufferSize,
- &Result,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ Status = mHiiConfigRouting->BlockToConfig(
+ mHiiConfigRouting,
+ ConfigInfo->ConfigRequest,
+ Src,
+ BufferSize,
+ &Result,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- Status = mHiiConfigRouting->ConfigToBlock (
- mHiiConfigRouting,
- Result,
- Dst,
- &BufferSize,
- &Progress
- );
- if (Result != NULL) {
- FreePool (Result);
- }
- } else {
- CopyMem (Dst, Src, BufferSize);
+ Status = mHiiConfigRouting->ConfigToBlock (
+ mHiiConfigRouting,
+ Result,
+ Dst,
+ &BufferSize,
+ &Progress
+ );
+ if (Result != NULL) {
+ FreePool (Result);
}
- } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
- Link = GetFirstNode (&Storage->NameValueListHead);
- while (!IsNull (&Storage->NameValueListHead, Link)) {
+ } else if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
+ Link = GetFirstNode (&ConfigInfo->Storage->NameValueListHead);
+ while (!IsNull (&ConfigInfo->Storage->NameValueListHead, Link)) {
Node = NAME_VALUE_NODE_FROM_LINK (Link);
- if ((ConfigRequest != NULL && StrStr (ConfigRequest, Node->Name) != NULL) ||
- (ConfigRequest == NULL)) {
+ if (StrStr (ConfigInfo->ConfigRequest, Node->Name) != NULL) {
if (SyncOrRestore) {
NewStringCpy (&Node->Value, Node->EditValue);
} else {
@@ -2173,7 +2072,7 @@ SynchronizeStorage ( }
}
- Link = GetNextNode (&Storage->NameValueListHead, Link);
+ Link = GetNextNode (&ConfigInfo->Storage->NameValueListHead, Link);
}
}
@@ -2196,9 +2095,20 @@ SendDiscardInfoToDriver ( {
LIST_ENTRY *Link;
FORM_BROWSER_STATEMENT *Question;
+ EFI_STATUS Status;
+ EFI_HII_VALUE HiiValue;
+ UINT8 *BufferValue;
+ BOOLEAN ValueChanged;
EFI_IFR_TYPE_VALUE *TypeValue;
EFI_BROWSER_ACTION_REQUEST ActionRequest;
+ ValueChanged = FALSE;
+ BufferValue = NULL;
+
+ if(!Form->NvUpdateRequired) {
+ return;
+ }
+
Link = GetFirstNode (&Form->StatementListHead);
while (!IsNull (&Form->StatementListHead, Link)) {
Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
@@ -2212,10 +2122,45 @@ SendDiscardInfoToDriver ( continue;
}
- if (!Question->ValueChanged) {
+ if (Question->BufferValue != NULL) {
+ BufferValue = AllocateZeroPool (Question->StorageWidth);
+ ASSERT (BufferValue != NULL);
+ CopyMem (BufferValue, Question->BufferValue, Question->StorageWidth);
+ } else {
+ HiiValue.Type = Question->HiiValue.Type;
+ CopyMem (&HiiValue.Value, &Question->HiiValue.Value, sizeof (EFI_IFR_TYPE_VALUE));
+ }
+
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);
+ if (EFI_ERROR (Status)) {
+ if (BufferValue != NULL) {
+ FreePool (BufferValue);
+ BufferValue = NULL;
+ }
+ continue;
+ }
+
+ if (Question->BufferValue != NULL) {
+ if (CompareMem (BufferValue, Question->BufferValue, Question->StorageWidth)) {
+ ValueChanged = TRUE;
+ }
+ } else {
+ if (CompareMem (&HiiValue.Value, &Question->HiiValue.Value, sizeof (EFI_IFR_TYPE_VALUE))) {
+ ValueChanged = TRUE;
+ }
+ }
+
+ if (BufferValue != NULL) {
+ FreePool (BufferValue);
+ BufferValue = NULL;
+ }
+
+ if (!ValueChanged) {
continue;
}
+ ValueChanged = FALSE;
+
if (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {
TypeValue = (EFI_IFR_TYPE_VALUE *) Question->BufferValue;
} else {
@@ -2280,78 +2225,6 @@ ValidateFormSet ( return Find;
}
-/**
- Check whether need to enable the reset flag in form level.
- Also clean all ValueChanged flag in question.
-
- @param SetFlag Whether need to set the Reset Flag.
- @param Form Form data structure.
-
-**/
-VOID
-UpdateFlagForForm (
- IN BOOLEAN SetFlag,
- IN FORM_BROWSER_FORM *Form
- )
-{
- LIST_ENTRY *Link;
- FORM_BROWSER_STATEMENT *Question;
- BOOLEAN FindOne;
-
- FindOne = FALSE;
- Link = GetFirstNode (&Form->StatementListHead);
- while (!IsNull (&Form->StatementListHead, Link)) {
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
-
- if (SetFlag && Question->ValueChanged && ((Question->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0)) {
- gResetRequired = TRUE;
- }
-
- if (Question->ValueChanged) {
- Question->ValueChanged = FALSE;
- }
-
- Link = GetNextNode (&Form->StatementListHead, Link);
- }
-}
-
-/**
- Check whether need to enable the reset flag.
- Also clean ValueChanged flag for all statements.
-
- Form level or formset level, only one.
-
- @param SetFlag Whether need to set the Reset Flag.
- @param FormSet FormSet data structure.
- @param Form Form data structure.
-
-**/
-VOID
-ValueChangeResetFlagUpdate (
- IN BOOLEAN SetFlag,
- IN FORM_BROWSER_FORMSET *FormSet,
- IN FORM_BROWSER_FORM *Form
- )
-{
- FORM_BROWSER_FORM *CurrentForm;
- LIST_ENTRY *Link;
-
- //
- // Form != NULL means only check form level.
- //
- if (Form != NULL) {
- UpdateFlagForForm(SetFlag, Form);
- return;
- }
-
- Link = GetFirstNode (&FormSet->FormListHead);
- while (!IsNull (&FormSet->FormListHead, Link)) {
- CurrentForm = FORM_BROWSER_FORM_FROM_LINK (Link);
- Link = GetNextNode (&FormSet->FormListHead, Link);
-
- UpdateFlagForForm(SetFlag, CurrentForm);
- }
-}
/**
Discard data based on the input setting scope (Form, FormSet or System).
@@ -2383,7 +2256,7 @@ DiscardForm ( return EFI_UNSUPPORTED;
}
- if (SettingScope == FormLevel && IsNvUpdateRequiredForForm (Form)) {
+ if (SettingScope == FormLevel && Form->NvUpdateRequired) {
ConfigInfo = NULL;
Link = GetFirstNode (&Form->ConfigRequestHead);
while (!IsNull (&Form->ConfigRequestHead, Link)) {
@@ -2404,7 +2277,7 @@ DiscardForm ( //
// Prepare <ConfigResp>
//
- SynchronizeStorage(FormSet, ConfigInfo->Storage, ConfigInfo->ConfigRequest, FALSE);
+ SynchronizeStorageForForm(FormSet, ConfigInfo, FALSE);
//
// Call callback with Changed type to inform the driver.
@@ -2412,8 +2285,8 @@ DiscardForm ( SendDiscardInfoToDriver (FormSet, Form);
}
- ValueChangeResetFlagUpdate (FALSE, NULL, Form);
- } else if (SettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet (FormSet)) {
+ Form->NvUpdateRequired = FALSE;
+ } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {
//
// Discard Buffer storage or Name/Value storage
@@ -2434,7 +2307,7 @@ DiscardForm ( continue;
}
- SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigRequest, FALSE);
+ SynchronizeStorage(Storage->BrowserStorage, FALSE);
}
Link = GetFirstNode (&FormSet->FormListHead);
@@ -2448,7 +2321,7 @@ DiscardForm ( SendDiscardInfoToDriver (FormSet, Form);
}
- ValueChangeResetFlagUpdate(FALSE, FormSet, NULL);
+ UpdateNvInfoInForm (FormSet, FALSE);
} else if (SettingScope == SystemLevel) {
//
// System Level Discard.
@@ -2528,7 +2401,7 @@ SubmitForm ( return Status;
}
- if (SettingScope == FormLevel && IsNvUpdateRequiredForForm (Form)) {
+ if (SettingScope == FormLevel && Form->NvUpdateRequired) {
ConfigInfo = NULL;
Link = GetFirstNode (&Form->ConfigRequestHead);
while (!IsNull (&Form->ConfigRequestHead, Link)) {
@@ -2550,7 +2423,7 @@ SubmitForm ( //
// 1. Prepare <ConfigResp>
//
- Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest, TRUE);
+ Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -2626,14 +2499,14 @@ SubmitForm ( //
// 3. Config success, update storage shadow Buffer, only update the data belong to this form.
//
- SynchronizeStorage (FormSet, ConfigInfo->Storage, ConfigInfo->ConfigRequest, TRUE);
+ SynchronizeStorageForForm(FormSet, ConfigInfo, TRUE);
}
//
// 4. Update the NV flag.
//
- ValueChangeResetFlagUpdate(TRUE, NULL, Form);
- } else if (SettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet (FormSet)) {
+ Form->NvUpdateRequired = FALSE;
+ } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {
//
// Submit Buffer storage or Name/Value storage
//
@@ -2657,7 +2530,7 @@ SubmitForm ( //
// 1. Prepare <ConfigResp>
//
- Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest, TRUE);
+ Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -2729,13 +2602,13 @@ SubmitForm ( //
// 3. Config success, update storage shadow Buffer
//
- SynchronizeStorage (FormSet, Storage, FormSetStorage->ConfigRequest, TRUE);
+ SynchronizeStorage (Storage, TRUE);
}
//
// 4. Update the NV flag.
//
- ValueChangeResetFlagUpdate(TRUE, FormSet, NULL);
+ UpdateNvInfoInForm (FormSet, FALSE);
} else if (SettingScope == SystemLevel) {
//
// System Level Save.
@@ -2991,138 +2864,6 @@ GetDefaultIdForCallBack ( }
}
-
-
-/**
- Return data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
-
- @retval Value The data to be returned
-
-**/
-UINT64
-GetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index
- )
-{
- UINT64 Data;
-
- ASSERT (Array != NULL);
-
- Data = 0;
- switch (Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data = (UINT64) *(((UINT8 *) Array) + Index);
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data = (UINT64) *(((UINT16 *) Array) + Index);
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data = (UINT64) *(((UINT32 *) Array) + Index);
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data = (UINT64) *(((UINT64 *) Array) + Index);
- break;
-
- default:
- break;
- }
-
- return Data;
-}
-
-
-/**
- Set value of a data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
- @param Value The value to be set.
-
-**/
-VOID
-SetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index,
- IN UINT64 Value
- )
-{
-
- ASSERT (Array != NULL);
-
- switch (Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- *(((UINT8 *) Array) + Index) = (UINT8) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_16:
- *(((UINT16 *) Array) + Index) = (UINT16) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_32:
- *(((UINT32 *) Array) + Index) = (UINT32) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_64:
- *(((UINT64 *) Array) + Index) = (UINT64) Value;
- break;
-
- default:
- break;
- }
-}
-
-/**
- Search an Option of a Question by its value.
-
- @param Question The Question
- @param OptionValue Value for Option to be searched.
-
- @retval Pointer Pointer to the found Option.
- @retval NULL Option not found.
-
-**/
-QUESTION_OPTION *
-ValueToOption (
- IN FORM_BROWSER_STATEMENT *Question,
- IN EFI_HII_VALUE *OptionValue
- )
-{
- LIST_ENTRY *Link;
- QUESTION_OPTION *Option;
- INTN Result;
-
- Link = GetFirstNode (&Question->OptionListHead);
- while (!IsNull (&Question->OptionListHead, Link)) {
- Option = QUESTION_OPTION_FROM_LINK (Link);
-
- if ((CompareHiiValue (&Option->Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
- //
- // Check the suppressif condition, only a valid option can be return.
- //
- if ((Option->SuppressExpression == NULL) ||
- ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse))) {
- return Option;
- }
- }
-
- Link = GetNextNode (&Question->OptionListHead, Link);
- }
-
- return NULL;
-}
-
-
/**
Reset Question to its default value.
@@ -3414,7 +3155,11 @@ ExtractDefault ( LIST_ENTRY *FormLink;
LIST_ENTRY *Link;
FORM_BROWSER_STATEMENT *Question;
+ FORM_BROWSER_FORMSET *BackUpFormSet;
FORM_BROWSER_FORMSET *LocalFormSet;
+ EFI_HII_HANDLE *HiiHandles;
+ UINTN Index;
+ EFI_GUID ZeroGuid;
Status = EFI_SUCCESS;
@@ -3484,6 +3229,10 @@ ExtractDefault ( if ((Question->Storage != NULL) &&
(Question->Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE)) {
SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
+ //
+ // Update Form NV flag.
+ //
+ Form->NvUpdateRequired = TRUE;
}
}
} else if (SettingScope == FormSetLevel) {
@@ -3495,9 +3244,65 @@ ExtractDefault ( }
} else if (SettingScope == SystemLevel) {
//
- // Preload all Hii formset.
+ // Open all FormSet by locate HII packages.
+ // Initiliaze the maintain FormSet to store default data as back up data.
+ //
+ BackUpFormSet = gOldFormSet;
+ gOldFormSet = NULL;
+
+ //
+ // Get all the Hii handles
+ //
+ HiiHandles = HiiGetHiiHandles (NULL);
+ ASSERT (HiiHandles != NULL);
+
+ //
+ // Search for formset of each class type
+ //
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {
+ //
+ // Check HiiHandles[Index] does exist in global maintain list.
+ //
+ if (GetFormSetFromHiiHandle (HiiHandles[Index]) != NULL) {
+ continue;
+ }
+
+ //
+ // Initilize FormSet Setting
+ //
+ LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
+ ASSERT (LocalFormSet != NULL);
+ ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
+ Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet, FALSE);
+ if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {
+ DestroyFormSet (LocalFormSet);
+ continue;
+ }
+ Status = InitializeCurrentSetting (LocalFormSet);
+ if (EFI_ERROR (Status)) {
+ DestroyFormSet (LocalFormSet);
+ continue;
+ }
+ //
+ // Initilize Questions' Value
+ //
+ Status = LoadFormSetConfig (NULL, LocalFormSet);
+ if (EFI_ERROR (Status)) {
+ DestroyFormSet (LocalFormSet);
+ continue;
+ }
+
+ //
+ // Add FormSet into the maintain list.
+ //
+ InsertTailList (&gBrowserFormSetList, &LocalFormSet->Link);
+ }
+
+ //
+ // Free resources, and restore gOldFormSet and gClassOfVfr
//
- LoadAllHiiFormset();
+ FreePool (HiiHandles);
+ gOldFormSet = BackUpFormSet;
//
// Set Default Value for each FormSet in the maintain list.
@@ -3516,81 +3321,6 @@ ExtractDefault ( return EFI_SUCCESS;
}
-
-/**
- Validate whether this question's value has changed.
-
- @param FormSet FormSet data structure.
- @param Form Form data structure.
- @param Question Question to be initialized.
- @param GetValueFrom Where to get value, may from editbuffer, buffer or hii driver.
-
- @retval TRUE Question's value has changed.
- @retval FALSE Question's value has not changed
-
-**/
-BOOLEAN
-IsQuestionValueChanged (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN FORM_BROWSER_FORM *Form,
- IN OUT FORM_BROWSER_STATEMENT *Question,
- IN GET_SET_QUESTION_VALUE_WITH GetValueFrom
- )
-{
- EFI_HII_VALUE BackUpValue;
- CHAR8 *BackUpBuffer;
- EFI_STATUS Status;
- BOOLEAN ValueChanged;
- UINTN BufferWidth;
-
- //
- // For quetion without storage, always mark it as data not changed.
- //
- if (Question->Storage == NULL && Question->Operand != EFI_IFR_TIME_OP && Question->Operand != EFI_IFR_DATE_OP) {
- return FALSE;
- }
-
- BackUpBuffer = NULL;
- ValueChanged = FALSE;
-
- switch (Question->Operand) {
- case EFI_IFR_ORDERED_LIST_OP:
- BufferWidth = Question->StorageWidth;
- BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);
- ASSERT (BackUpBuffer != NULL);
- break;
-
- case EFI_IFR_STRING_OP:
- case EFI_IFR_PASSWORD_OP:
- BufferWidth = (UINTN) Question->Maximum * sizeof (CHAR16);
- BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);
- ASSERT (BackUpBuffer != NULL);
- break;
-
- default:
- BufferWidth = 0;
- break;
- }
- CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));
-
- Status = GetQuestionValue (FormSet, Form, Question, GetValueFrom);
- ASSERT_EFI_ERROR(Status);
-
- if (CompareMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE)) != 0 ||
- CompareMem (BackUpBuffer, Question->BufferValue, BufferWidth) != 0) {
- ValueChanged = TRUE;
- }
-
- CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));
- CopyMem (Question->BufferValue, BackUpBuffer, BufferWidth);
-
- if (BackUpBuffer != NULL) {
- FreePool (BackUpBuffer);
- }
-
- return ValueChanged;
-}
-
/**
Initialize Question's Edit copy from Storage.
@@ -3624,11 +3354,7 @@ LoadFormConfig ( //
// Initialize local copy of Value for each Question
//
- if (Question->Operand == EFI_IFR_PASSWORD_OP && (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)== 0) {
- Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithHiiDriver);
- } else {
- Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
- }
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -3668,11 +3394,6 @@ LoadFormConfig ( Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);
}
- //
- // Update Question Value changed flag.
- //
- Question->ValueChanged = IsQuestionValueChanged(FormSet, Form, Question, GetSetValueWithBuffer);
-
Link = GetNextNode (&Form->StatementListHead, Link);
}
@@ -3716,11 +3437,6 @@ LoadFormSetConfig ( Link = GetNextNode (&FormSet->FormListHead, Link);
}
- //
- // Finished question initialization.
- //
- FormSet->QuestionInited = TRUE;
-
return EFI_SUCCESS;
}
@@ -3775,13 +3491,6 @@ RemoveConfigRequest ( CHAR16 *NextRequestElement;
CHAR16 *SearchKey;
- //
- // No request element in it, just return.
- //
- if (ConfigRequest == NULL) {
- return;
- }
-
if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
//
// "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage
@@ -3856,7 +3565,6 @@ CleanBrowserStorage ( {
LIST_ENTRY *Link;
FORMSET_STORAGE *Storage;
- CHAR16 *ConfigRequest;
Link = GetFirstNode (&FormSet->StorageListHead);
while (!IsNull (&FormSet->StorageListHead, Link)) {
@@ -3864,8 +3572,7 @@ CleanBrowserStorage ( Link = GetNextNode (&FormSet->StorageListHead, Link);
if ((Storage->BrowserStorage->Type != EFI_HII_VARSTORE_BUFFER) &&
- (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE) &&
- (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
+ (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE)) {
continue;
}
@@ -3873,8 +3580,7 @@ CleanBrowserStorage ( continue;
}
- ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;
- RemoveConfigRequest (Storage->BrowserStorage, ConfigRequest);
+ RemoveConfigRequest (Storage->BrowserStorage, Storage->ConfigRequest);
}
}
@@ -3945,6 +3651,7 @@ AppendConfigRequest ( Adjust the config request info, remove the request elements which already in AllConfigRequest string.
@param Storage Form set Storage.
+ @param ConfigRequest Return the ConfigRequest info.
@retval TRUE Has element not covered by current used elements, need to continue to call ExtractConfig
@retval FALSE All elements covered by current used elements.
@@ -3952,7 +3659,8 @@ AppendConfigRequest ( **/
BOOLEAN
ConfigRequestAdjust (
- IN FORMSET_STORAGE *Storage
+ IN FORMSET_STORAGE *Storage,
+ OUT CHAR16 **ConfigRequest
)
{
CHAR16 *RequestElement;
@@ -3968,10 +3676,7 @@ ConfigRequestAdjust ( if (Storage->BrowserStorage->ConfigRequest == NULL) {
Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
- if (Storage->ConfigElements != NULL) {
- FreePool (Storage->ConfigElements);
- }
- Storage->ConfigElements = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
+ *ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
return TRUE;
}
@@ -4040,10 +3745,7 @@ ConfigRequestAdjust ( }
if (RetVal) {
- if (Storage->ConfigElements != NULL) {
- FreePool (Storage->ConfigElements);
- }
- Storage->ConfigElements = RetBuf;
+ *ConfigRequest = RetBuf;
} else {
FreePool (RetBuf);
}
@@ -4052,162 +3754,15 @@ ConfigRequestAdjust ( }
/**
-
- Base on ConfigRequest info to get default value for current formset.
-
- ConfigRequest info include the info about which questions in current formset need to
- get default value. This function only get these questions default value.
-
- @param FormSet FormSet data structure.
- @param Storage Storage need to update value.
- @param ConfigRequest The config request string.
-
-**/
-VOID
-GetDefaultForFormset (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN BROWSER_STORAGE *Storage,
- IN CHAR16 *ConfigRequest
- )
-{
- UINT8 *BackUpBuf;
- UINTN BufferSize;
- LIST_ENTRY BackUpList;
- NAME_VALUE_NODE *Node;
- LIST_ENTRY *Link;
- LIST_ENTRY *NodeLink;
- NAME_VALUE_NODE *TmpNode;
- EFI_STATUS Status;
- EFI_STRING Progress;
- EFI_STRING Result;
-
- BackUpBuf = NULL;
- InitializeListHead(&BackUpList);
-
- //
- // Back update the edit buffer.
- //
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
- (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
- BackUpBuf = AllocateCopyPool (Storage->Size, Storage->EditBuffer);
- ASSERT (BackUpBuf != NULL);
- } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
- Link = GetFirstNode (&Storage->NameValueListHead);
- while (!IsNull (&Storage->NameValueListHead, Link)) {
- Node = NAME_VALUE_NODE_FROM_LINK (Link);
- Link = GetNextNode (&Storage->NameValueListHead, Link);
-
- //
- // Only back Node belong to this formset.
- //
- if (StrStr (Storage->ConfigRequest, Node->Name) == NULL) {
- continue;
- }
-
- TmpNode = AllocateCopyPool (sizeof (NAME_VALUE_NODE), Node);
- TmpNode->Name = AllocateCopyPool (StrSize(Node->Name) * sizeof (CHAR16), Node->Name);
- TmpNode->EditValue = AllocateCopyPool (StrSize(Node->EditValue) * sizeof (CHAR16), Node->EditValue);
-
- InsertTailList(&BackUpList, &TmpNode->Link);
- }
- }
-
- //
- // Get default value.
- //
- ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage, TRUE);
-
- //
- // Update the question value based on the input ConfigRequest.
- //
- if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
- (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
- ASSERT (BackUpBuf != NULL);
- BufferSize = Storage->Size;
- Status = mHiiConfigRouting->BlockToConfig(
- mHiiConfigRouting,
- ConfigRequest,
- Storage->EditBuffer,
- BufferSize,
- &Result,
- &Progress
- );
- ASSERT_EFI_ERROR (Status);
-
- Status = mHiiConfigRouting->ConfigToBlock (
- mHiiConfigRouting,
- Result,
- BackUpBuf,
- &BufferSize,
- &Progress
- );
- ASSERT_EFI_ERROR (Status);
-
- if (Result != NULL) {
- FreePool (Result);
- }
-
- CopyMem (Storage->EditBuffer, BackUpBuf, Storage->Size);
- FreePool (BackUpBuf);
- } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
- //
- // Update question value, only element in ConfigReqeust will be update.
- //
- Link = GetFirstNode (&BackUpList);
- while (!IsNull (&BackUpList, Link)) {
- Node = NAME_VALUE_NODE_FROM_LINK (Link);
- Link = GetNextNode (&BackUpList, Link);
-
- if (StrStr (ConfigRequest, Node->Name) != NULL) {
- continue;
- }
-
- NodeLink = GetFirstNode (&Storage->NameValueListHead);
- while (!IsNull (&Storage->NameValueListHead, NodeLink)) {
- TmpNode = NAME_VALUE_NODE_FROM_LINK (NodeLink);
- NodeLink = GetNextNode (&Storage->NameValueListHead, NodeLink);
-
- if (StrCmp (Node->Name, TmpNode->Name) != 0) {
- continue;
- }
-
- FreePool (TmpNode->EditValue);
- TmpNode->EditValue = AllocateCopyPool (StrSize(Node->EditValue) * sizeof (CHAR16), Node->EditValue);
-
- RemoveEntryList (&Node->Link);
- FreePool (Node->EditValue);
- FreePool (Node->Name);
- FreePool (Node);
- }
- }
-
- //
- // Restore the Name/Value node.
- //
- Link = GetFirstNode (&BackUpList);
- while (!IsNull (&BackUpList, Link)) {
- Node = NAME_VALUE_NODE_FROM_LINK (Link);
- Link = GetNextNode (&BackUpList, Link);
-
- //
- // Free this node.
- //
- RemoveEntryList (&Node->Link);
- FreePool (Node->EditValue);
- FreePool (Node->Name);
- FreePool (Node);
- }
- }
-}
-
-/**
Fill storage's edit copy with settings requested from Configuration Driver.
@param FormSet FormSet data structure.
@param Storage Buffer Storage.
+ @retval EFI_SUCCESS The function completed successfully.
+
**/
-VOID
+EFI_STATUS
LoadStorage (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORMSET_STORAGE *Storage
@@ -4217,17 +3772,18 @@ LoadStorage ( EFI_STRING Progress;
EFI_STRING Result;
CHAR16 *StrPtr;
+ CHAR16 *ConfigRequest;
- switch (Storage->BrowserStorage->Type) {
- case EFI_HII_VARSTORE_EFI_VARIABLE:
- return;
-
- case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
- if (Storage->BrowserStorage->ReferenceCount > 1) {
- ConfigRequestAdjust(Storage);
- return;
- }
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
+ return EFI_SUCCESS;
+ }
+ if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ Status = EFI_SUCCESS;
+ //
+ // EFI varstore data all get from variable, so no need to get again.
+ //
+ if (Storage->BrowserStorage->ReferenceCount == 1) {
Status = gRT->GetVariable (
Storage->BrowserStorage->Name,
&Storage->BrowserStorage->Guid,
@@ -4235,78 +3791,55 @@ LoadStorage ( (UINTN*)&Storage->BrowserStorage->Size,
Storage->BrowserStorage->EditBuffer
);
- //
- // If get variable fail, extract default from IFR binary
- //
- if (EFI_ERROR (Status)) {
- ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);
- }
-
- Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
- //
- // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer.
- //
- SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);
- break;
+ }
+ return Status;
+ }
- case EFI_HII_VARSTORE_BUFFER:
- case EFI_HII_VARSTORE_NAME_VALUE:
- //
- // Skip if there is no RequestElement
- //
- if (Storage->ElementCount == 0) {
- return;
- }
+ if (FormSet->ConfigAccess == NULL) {
+ return EFI_NOT_FOUND;
+ }
- //
- // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig
- // will used to call ExtractConfig.
- // If not elements need to udpate, return.
- //
- if (!ConfigRequestAdjust(Storage)) {
- return;
- }
- ASSERT (Storage->ConfigElements != NULL);
+ if (Storage->ElementCount == 0) {
+ //
+ // Skip if there is no RequestElement
+ //
+ return EFI_SUCCESS;
+ }
- Status = EFI_NOT_FOUND;
- if (FormSet->ConfigAccess != NULL) {
- //
- // Request current settings from Configuration Driver
- //
- Status = FormSet->ConfigAccess->ExtractConfig (
- FormSet->ConfigAccess,
- Storage->ConfigElements,
- &Progress,
- &Result
- );
-
- if (!EFI_ERROR (Status)) {
- //
- // Convert Result from <ConfigAltResp> to <ConfigResp>
- //
- StrPtr = StrStr (Result, L"&GUID=");
- if (StrPtr != NULL) {
- *StrPtr = L'\0';
- }
-
- Status = ConfigRespToStorage (Storage->BrowserStorage, Result);
- FreePool (Result);
- }
- }
+ //
+ // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig
+ // will used to call ExtractConfig.
+ //
+ if (!ConfigRequestAdjust(Storage, &ConfigRequest)) {
+ return EFI_SUCCESS;
+ }
- if (EFI_ERROR (Status)) {
- //
- // Base on the configRequest string to get default value.
- //
- GetDefaultForFormset (FormSet, Storage->BrowserStorage, Storage->ConfigElements);
- }
+ //
+ // Request current settings from Configuration Driver
+ //
+ Status = FormSet->ConfigAccess->ExtractConfig (
+ FormSet->ConfigAccess,
+ ConfigRequest,
+ &Progress,
+ &Result
+ );
+ FreePool (ConfigRequest);
- SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigElements, TRUE);
- break;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- default:
- break;
+ //
+ // Convert Result from <ConfigAltResp> to <ConfigResp>
+ //
+ StrPtr = StrStr (Result, L"&GUID=");
+ if (StrPtr != NULL) {
+ *StrPtr = L'\0';
}
+
+ Status = ConfigRespToStorage (Storage->BrowserStorage, Result);
+ FreePool (Result);
+ return Status;
}
/**
@@ -4314,15 +3847,22 @@ LoadStorage ( @param FormSet FormSet data structure.
+ @retval EFI_SUCCESS The function completed successfully.
+
**/
-VOID
+EFI_STATUS
InitializeCurrentSetting (
IN OUT FORM_BROWSER_FORMSET *FormSet
)
{
LIST_ENTRY *Link;
+ LIST_ENTRY *Link2;
FORMSET_STORAGE *Storage;
- FORM_BROWSER_FORMSET *OldFormSet;
+ FORMSET_STORAGE *StorageSrc;
+ FORMSET_STORAGE *OldStorage;
+ FORM_BROWSER_FORM *Form;
+ FORM_BROWSER_FORM *Form2;
+ EFI_STATUS Status;
//
// Extract default from IFR binary for no storage questions.
@@ -4336,21 +3876,77 @@ InitializeCurrentSetting ( while (!IsNull (&FormSet->StorageListHead, Link)) {
Storage = FORMSET_STORAGE_FROM_LINK (Link);
- LoadStorage (FormSet, Storage);
+ OldStorage = NULL;
+ if (gOldFormSet != NULL) {
+ //
+ // Try to find the Storage in backup formset gOldFormSet
+ //
+ Link2 = GetFirstNode (&gOldFormSet->StorageListHead);
+ while (!IsNull (&gOldFormSet->StorageListHead, Link2)) {
+ StorageSrc = FORMSET_STORAGE_FROM_LINK (Link2);
+
+ if (StorageSrc->VarStoreId == Storage->VarStoreId) {
+ OldStorage = StorageSrc;
+ break;
+ }
+
+ Link2 = GetNextNode (&gOldFormSet->StorageListHead, Link2);
+ }
+ }
+
+ //
+ // Storage is not found in backup formset and current global storage not has other driver used,
+ // request it from ConfigDriver
+ //
+ if (OldStorage == NULL) {
+ Status = LoadStorage (FormSet, Storage);
+
+ if (EFI_ERROR (Status)) {
+ //
+ // If get last time changed value failed, extract default from IFR binary
+ //
+ ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);
+ //
+ // ExtractDefault will set the NV flag to TRUE, so need this function to clean the flag
+ // in current situation.
+ //
+ UpdateNvInfoInForm (FormSet, FALSE);
+ }
+
+ //
+ // Now Edit Buffer is filled with default values(lower priority) or current
+ // settings(higher priority), sychronize it to shadow Buffer
+ //
+ SynchronizeStorage (Storage->BrowserStorage, TRUE);
+ }
Link = GetNextNode (&FormSet->StorageListHead, Link);
}
//
- // Try to find pre FormSet in the maintain backup list.
- // If old formset != NULL, destroy this formset. Add new formset to gBrowserFormSetList.
+ // If has old formset, get the old nv update status.
//
- OldFormSet = GetFormSetFromHiiHandle (FormSet->HiiHandle);
- if (OldFormSet != NULL) {
- RemoveEntryList (&OldFormSet->Link);
- DestroyFormSet (OldFormSet);
+ if (gOldFormSet != NULL) {
+ Link = GetFirstNode (&FormSet->FormListHead);
+ while (!IsNull (&FormSet->FormListHead, Link)) {
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);
+
+ Link2 = GetFirstNode (&gOldFormSet->FormListHead);
+ while (!IsNull (&gOldFormSet->FormListHead, Link2)) {
+ Form2 = FORM_BROWSER_FORM_FROM_LINK (Link2);
+
+ if (Form->FormId == Form2->FormId) {
+ Form->NvUpdateRequired = Form2->NvUpdateRequired;
+ break;
+ }
+
+ Link2 = GetNextNode (&gOldFormSet->FormListHead, Link2);
+ }
+ Link = GetNextNode (&FormSet->FormListHead, Link);
+ }
}
- InsertTailList (&gBrowserFormSetList, &FormSet->Link);
+
+ return EFI_SUCCESS;
}
@@ -4533,6 +4129,7 @@ GetIfrBinaryData ( found in package list.
On output, GUID of the formset found(if not NULL).
@param FormSet FormSet data structure.
+ @param UpdateGlobalVar Whether need to update the global variable.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The specified FormSet could not be found.
@@ -4542,11 +4139,13 @@ EFI_STATUS InitializeFormSet (
IN EFI_HII_HANDLE Handle,
IN OUT EFI_GUID *FormSetGuid,
- OUT FORM_BROWSER_FORMSET *FormSet
+ OUT FORM_BROWSER_FORMSET *FormSet,
+ IN BOOLEAN UpdateGlobalVar
)
{
EFI_STATUS Status;
EFI_HANDLE DriverHandle;
+ UINT16 Index;
Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);
if (EFI_ERROR (Status)) {
@@ -4556,7 +4155,6 @@ InitializeFormSet ( FormSet->Signature = FORM_BROWSER_FORMSET_SIGNATURE;
FormSet->HiiHandle = Handle;
CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));
- FormSet->QuestionInited = FALSE;
//
// Retrieve ConfigAccess Protocol associated with this HiiPackageList
@@ -4583,8 +4181,55 @@ InitializeFormSet ( // Parse the IFR binary OpCodes
//
Status = ParseOpCodes (FormSet);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- return Status;
+ //
+ // If not need to update the global variable, just return.
+ //
+ if (!UpdateGlobalVar) {
+ return Status;
+ }
+
+ //
+ // Set VFR type by FormSet SubClass field
+ //
+ gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP;
+ if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {
+ gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;
+ }
+
+ //
+ // Set VFR type by FormSet class guid
+ //
+ for (Index = 0; Index < 3; Index ++) {
+ if (CompareGuid (&FormSet->ClassGuid[Index], &gEfiHiiPlatformSetupFormsetGuid)) {
+ gClassOfVfr |= FORMSET_CLASS_PLATFORM_SETUP;
+ break;
+ }
+ }
+
+ gFunctionKeySetting = ENABLE_FUNCTION_KEY_SETTING;
+
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {
+ gFrontPageHandle = FormSet->HiiHandle;
+ gFunctionKeySetting = NONE_FUNCTION_KEY_SETTING;
+ }
+
+ //
+ // Match GUID to find out the function key setting. If match fail, use the default setting.
+ //
+ for (Index = 0; Index < sizeof (gFunctionKeySettingTable) / sizeof (FUNCTIION_KEY_SETTING); Index++) {
+ if (CompareGuid (&FormSet->Guid, &(gFunctionKeySettingTable[Index].FormSetGuid))) {
+ //
+ // Update the function key setting.
+ //
+ gFunctionKeySetting = gFunctionKeySettingTable[Index].KeySetting;
+ }
+ }
+
+ return EFI_SUCCESS;
}
@@ -4600,7 +4245,6 @@ SaveBrowserContext ( )
{
BROWSER_CONTEXT *Context;
- FORM_ENTRY_INFO *MenuList;
gBrowserContextCount++;
if (gBrowserContextCount == 1) {
@@ -4618,23 +4262,47 @@ SaveBrowserContext ( //
// Save FormBrowser context
//
- Context->Selection = gCurrentSelection;
+ Context->BannerData = gBannerData;
+ Context->ClassOfVfr = gClassOfVfr;
+ Context->FunctionKeySetting = gFunctionKeySetting;
Context->ResetRequired = gResetRequired;
- Context->ExitRequired = gExitRequired;
- Context->HiiHandle = mCurrentHiiHandle;
- Context->FormId = mCurrentFormId;
- CopyGuid (&Context->FormSetGuid, &mCurrentFormSetGuid);
-
- //
- // Save the menu history data.
- //
- InitializeListHead(&Context->FormHistoryList);
- while (!IsListEmpty (&mPrivateData.FormBrowserEx2.FormViewHistoryHead)) {
- MenuList = FORM_ENTRY_INFO_FROM_LINK (mPrivateData.FormBrowserEx2.FormViewHistoryHead.ForwardLink);
- RemoveEntryList (&MenuList->Link);
-
- InsertTailList(&Context->FormHistoryList, &MenuList->Link);
- }
+ Context->Direction = gDirection;
+ Context->EnterString = gEnterString;
+ Context->EnterCommitString = gEnterCommitString;
+ Context->EnterEscapeString = gEnterEscapeString;
+ Context->EscapeString = gEscapeString;
+ Context->MoveHighlight = gMoveHighlight;
+ Context->MakeSelection = gMakeSelection;
+ Context->DecNumericInput = gDecNumericInput;
+ Context->HexNumericInput = gHexNumericInput;
+ Context->ToggleCheckBox = gToggleCheckBox;
+ Context->PromptForData = gPromptForData;
+ Context->PromptForPassword = gPromptForPassword;
+ Context->PromptForNewPassword = gPromptForNewPassword;
+ Context->ConfirmPassword = gConfirmPassword;
+ Context->ConfirmError = gConfirmError;
+ Context->PassowordInvalid = gPassowordInvalid;
+ Context->PressEnter = gPressEnter;
+ Context->EmptyString = gEmptyString;
+ Context->AreYouSure = gAreYouSure;
+ Context->YesResponse = gYesResponse;
+ Context->NoResponse = gNoResponse;
+ Context->MiniString = gMiniString;
+ Context->PlusString = gPlusString;
+ Context->MinusString = gMinusString;
+ Context->AdjustNumber = gAdjustNumber;
+ Context->SaveChanges = gSaveChanges;
+ Context->OptionMismatch = gOptionMismatch;
+ Context->FormSuppress = gFormSuppress;
+ Context->PromptBlockWidth = gPromptBlockWidth;
+ Context->OptionBlockWidth = gOptionBlockWidth;
+ Context->HelpBlockWidth = gHelpBlockWidth;
+ Context->OldFormSet = gOldFormSet;
+ Context->MenuRefreshHead = gMenuRefreshHead;
+ Context->ProtocolNotFound = gProtocolNotFound;
+
+ CopyMem (&Context->ScreenDimensions, &gScreenDimensions, sizeof (gScreenDimensions));
+ CopyMem (&Context->MenuOption, &gMenuOption, sizeof (gMenuOption));
//
// Insert to FormBrowser context list
@@ -4654,7 +4322,6 @@ RestoreBrowserContext ( {
LIST_ENTRY *Link;
BROWSER_CONTEXT *Context;
- FORM_ENTRY_INFO *MenuList;
ASSERT (gBrowserContextCount != 0);
gBrowserContextCount--;
@@ -4673,22 +4340,47 @@ RestoreBrowserContext ( //
// Restore FormBrowser context
//
- gCurrentSelection = Context->Selection;
+ gBannerData = Context->BannerData;
+ gClassOfVfr = Context->ClassOfVfr;
+ gFunctionKeySetting = Context->FunctionKeySetting;
gResetRequired = Context->ResetRequired;
- gExitRequired = Context->ExitRequired;
- mCurrentHiiHandle = Context->HiiHandle;
- mCurrentFormId = Context->FormId;
- CopyGuid (&mCurrentFormSetGuid, &Context->FormSetGuid);
-
- //
- // Restore the menu history data.
- //
- while (!IsListEmpty (&Context->FormHistoryList)) {
- MenuList = FORM_ENTRY_INFO_FROM_LINK (Context->FormHistoryList.ForwardLink);
- RemoveEntryList (&MenuList->Link);
-
- InsertTailList(&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &MenuList->Link);
- }
+ gDirection = Context->Direction;
+ gEnterString = Context->EnterString;
+ gEnterCommitString = Context->EnterCommitString;
+ gEnterEscapeString = Context->EnterEscapeString;
+ gEscapeString = Context->EscapeString;
+ gMoveHighlight = Context->MoveHighlight;
+ gMakeSelection = Context->MakeSelection;
+ gDecNumericInput = Context->DecNumericInput;
+ gHexNumericInput = Context->HexNumericInput;
+ gToggleCheckBox = Context->ToggleCheckBox;
+ gPromptForData = Context->PromptForData;
+ gPromptForPassword = Context->PromptForPassword;
+ gPromptForNewPassword = Context->PromptForNewPassword;
+ gConfirmPassword = Context->ConfirmPassword;
+ gConfirmError = Context->ConfirmError;
+ gPassowordInvalid = Context->PassowordInvalid;
+ gPressEnter = Context->PressEnter;
+ gEmptyString = Context->EmptyString;
+ gAreYouSure = Context->AreYouSure;
+ gYesResponse = Context->YesResponse;
+ gNoResponse = Context->NoResponse;
+ gMiniString = Context->MiniString;
+ gPlusString = Context->PlusString;
+ gMinusString = Context->MinusString;
+ gAdjustNumber = Context->AdjustNumber;
+ gSaveChanges = Context->SaveChanges;
+ gOptionMismatch = Context->OptionMismatch;
+ gFormSuppress = Context->FormSuppress;
+ gPromptBlockWidth = Context->PromptBlockWidth;
+ gOptionBlockWidth = Context->OptionBlockWidth;
+ gHelpBlockWidth = Context->HelpBlockWidth;
+ gOldFormSet = Context->OldFormSet;
+ gMenuRefreshHead = Context->MenuRefreshHead;
+ gProtocolNotFound = Context->ProtocolNotFound;
+
+ CopyMem (&gScreenDimensions, &Context->ScreenDimensions, sizeof (gScreenDimensions));
+ CopyMem (&gMenuOption, &Context->MenuOption, sizeof (gMenuOption));
//
// Remove from FormBrowser context list
@@ -4748,7 +4440,7 @@ IsHiiHandleInBrowserContext ( //
// HiiHandle is Current FormSet.
//
- if (mCurrentHiiHandle == Handle) {
+ if ((gOldFormSet != NULL) && (gOldFormSet->HiiHandle == Handle)) {
return TRUE;
}
@@ -4758,7 +4450,7 @@ IsHiiHandleInBrowserContext ( Link = GetFirstNode (&gBrowserContextList);
while (!IsNull (&gBrowserContextList, Link)) {
Context = BROWSER_CONTEXT_FROM_LINK (Link);
- if (Context->HiiHandle == Handle) {
+ if (Context->OldFormSet->HiiHandle == Handle) {
//
// HiiHandle is in BrowserContext
//
@@ -4771,83 +4463,6 @@ IsHiiHandleInBrowserContext ( }
/**
- Perform Password check.
- Passwork may be encrypted by driver that requires the specific check.
-
- @param Form Form where Password Statement is in.
- @param Statement Password statement
- @param PasswordString Password string to be checked. It may be NULL.
- NULL means to restore password.
- "" string can be used to checked whether old password does exist.
-
- @return Status Status of Password check.
-**/
-EFI_STATUS
-EFIAPI
-PasswordCheck (
- IN FORM_DISPLAY_ENGINE_FORM *Form,
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
- IN EFI_STRING PasswordString OPTIONAL
- )
-{
- EFI_STATUS Status;
- EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
- EFI_BROWSER_ACTION_REQUEST ActionRequest;
- EFI_IFR_TYPE_VALUE IfrTypeValue;
- FORM_BROWSER_STATEMENT *Question;
-
- ConfigAccess = gCurrentSelection->FormSet->ConfigAccess;
- Question = GetBrowserStatement(Statement);
- ASSERT (Question != NULL);
-
- if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) {
- if (ConfigAccess == NULL) {
- return EFI_UNSUPPORTED;
- }
- } else {
- if (PasswordString == NULL) {
- return EFI_SUCCESS;
- }
-
- if (StrnCmp (PasswordString, (CHAR16 *) Question->BufferValue, Question->StorageWidth/sizeof (CHAR16)) == 0) {
- return EFI_SUCCESS;
- } else {
- return EFI_NOT_READY;
- }
- }
-
- //
- // Prepare password string in HII database
- //
- if (PasswordString != NULL) {
- IfrTypeValue.string = NewString (PasswordString, gCurrentSelection->FormSet->HiiHandle);
- } else {
- IfrTypeValue.string = 0;
- }
-
- //
- // Send password to Configuration Driver for validation
- //
- Status = ConfigAccess->Callback (
- ConfigAccess,
- EFI_BROWSER_ACTION_CHANGING,
- Question->QuestionId,
- Question->HiiValue.Type,
- &IfrTypeValue,
- &ActionRequest
- );
-
- //
- // Remove password string from HII database
- //
- if (PasswordString != NULL) {
- DeleteString (IfrTypeValue.string, gCurrentSelection->FormSet->HiiHandle);
- }
-
- return Status;
-}
-
-/**
Find the registered HotKey based on KeyData.
@param[in] KeyData A pointer to a buffer that describes the keystroke
@@ -4897,7 +4512,7 @@ SetScope ( if (Scope >= MaxLevel) {
return EFI_INVALID_PARAMETER;
}
-
+
//
// When no hot key registered in system or on the first setting,
// Scope can be set.
@@ -5022,128 +4637,6 @@ RegiserExitHandler ( }
/**
- Check whether the browser data has been modified.
-
- @retval TRUE Browser data is modified.
- @retval FALSE No browser data is modified.
-
-**/
-BOOLEAN
-EFIAPI
-IsBrowserDataModified (
- VOID
- )
-{
- LIST_ENTRY *Link;
- FORM_BROWSER_FORMSET *FormSet;
-
- if (gCurrentSelection == NULL) {
- return FALSE;
- }
-
- switch (gBrowserSettingScope) {
- case FormLevel:
- return IsNvUpdateRequiredForForm (gCurrentSelection->Form);
-
- case FormSetLevel:
- return IsNvUpdateRequiredForFormSet (gCurrentSelection->FormSet);
-
- case SystemLevel:
- Link = GetFirstNode (&gBrowserFormSetList);
- while (!IsNull (&gBrowserFormSetList, Link)) {
- FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
- if (IsNvUpdateRequiredForFormSet (FormSet)) {
- return TRUE;
- }
- Link = GetNextNode (&gBrowserFormSetList, Link);
- }
- return FALSE;
-
- default:
- return FALSE;
- }
-}
-
-/**
- Execute the action requested by the Action parameter.
-
- @param[in] Action Execute the request action.
- @param[in] DefaultId The default Id info when need to load default value. Only used when Action is BROWSER_ACTION_DEFAULT.
-
- @retval EFI_SUCCESS Execute the request action succss.
- @retval EFI_INVALID_PARAMETER The input action value is invalid.
-
-**/
-EFI_STATUS
-EFIAPI
-ExecuteAction (
- IN UINT32 Action,
- IN UINT16 DefaultId
- )
-{
- EFI_STATUS Status;
-
- if (gCurrentSelection == NULL) {
- return EFI_NOT_READY;
- }
-
- Status = EFI_SUCCESS;
-
- //
- // Executet the discard action.
- //
- if ((Action & BROWSER_ACTION_DISCARD) != 0) {
- Status = DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
-
- //
- // Executet the difault action.
- //
- if ((Action & BROWSER_ACTION_DEFAULT) != 0) {
- Status = ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
-
- //
- // Executet the submit action.
- //
- if ((Action & BROWSER_ACTION_SUBMIT) != 0) {
- Status = SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
-
- //
- // Executet the reset action.
- //
- if ((Action & BROWSER_ACTION_RESET) != 0) {
- gResetRequired = TRUE;
- }
-
- //
- // Executet the exit action.
- //
- if ((Action & BROWSER_ACTION_EXIT) != 0) {
- DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
- if (gBrowserSettingScope == SystemLevel) {
- if (ExitHandlerFunction != NULL) {
- ExitHandlerFunction ();
- }
- }
-
- gExitRequired = TRUE;
- }
-
- return Status;
-}
-
-/**
Create reminder to let user to choose save or discard the changed browser data.
Caller can use it to actively check the changed browser data.
@@ -5162,6 +4655,12 @@ SaveReminder ( FORM_BROWSER_FORMSET *FormSet;
BOOLEAN IsDataChanged;
UINT32 DataSavedAction;
+ CHAR16 *YesResponse;
+ CHAR16 *NoResponse;
+ CHAR16 *EmptyString;
+ CHAR16 *ChangeReminderString;
+ CHAR16 *SaveConfirmString;
+ EFI_INPUT_KEY Key;
DataSavedAction = BROWSER_NO_CHANGES;
IsDataChanged = FALSE;
@@ -5172,7 +4671,7 @@ SaveReminder ( if (!ValidateFormSet(FormSet)) {
continue;
}
- if (IsNvUpdateRequiredForFormSet (FormSet)) {
+ if (IsNvUpdateRequired (FormSet)) {
IsDataChanged = TRUE;
break;
}
@@ -5186,19 +4685,42 @@ SaveReminder ( }
//
- // If data is changed, prompt user to save or discard it.
+ // If data is changed, prompt user
//
+ gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+
+ YesResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);
+ ASSERT (YesResponse != NULL);
+ NoResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);
+ ASSERT (NoResponse != NULL);
+ EmptyString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
+ ChangeReminderString = GetToken (STRING_TOKEN (CHANGE_REMINDER), gHiiHandle);
+ SaveConfirmString = GetToken (STRING_TOKEN (SAVE_CONFIRM), gHiiHandle);
+
do {
- DataSavedAction = (UINT32) mFormDisplay->ConfirmDataChange();
+ CreateDialog (4, TRUE, 0, NULL, &Key, EmptyString, ChangeReminderString, SaveConfirmString, EmptyString);
+ } while
+ (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse[0] | UPPER_LOWER_CASE_OFFSET)) &&
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse[0] | UPPER_LOWER_CASE_OFFSET))
+ );
- if (DataSavedAction == BROWSER_SAVE_CHANGES) {
- SubmitForm (NULL, NULL, SystemLevel);
- break;
- } else if (DataSavedAction == BROWSER_DISCARD_CHANGES) {
- DiscardForm (NULL, NULL, SystemLevel);
- break;
- }
- } while (1);
+ //
+ // If the user hits the YesResponse key
+ //
+ if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse[0] | UPPER_LOWER_CASE_OFFSET)) {
+ SubmitForm (NULL, NULL, SystemLevel);
+ DataSavedAction = BROWSER_SAVE_CHANGES;
+ } else {
+ DiscardForm (NULL, NULL, SystemLevel);
+ DataSavedAction = BROWSER_DISCARD_CHANGES;
+ gResetRequired = FALSE;
+ }
+
+ FreePool (YesResponse);
+ FreePool (NoResponse);
+ FreePool (EmptyString);
+ FreePool (SaveConfirmString);
+ FreePool (ChangeReminderString);
return DataSavedAction;
}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h index 030cf32eac..9a0c739094 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h @@ -22,8 +22,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include <Protocol/SimpleTextOut.h>
#include <Protocol/SimpleTextIn.h>
#include <Protocol/FormBrowser2.h>
-#include <Protocol/FormBrowserEx2.h>
-#include <Protocol/DisplayProtocol.h>
+#include <Protocol/FormBrowserEx.h>
#include <Protocol/DevicePath.h>
#include <Protocol/UnicodeCollation.h>
#include <Protocol/HiiConfigAccess.h>
@@ -48,29 +47,106 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include <Library/HiiLib.h>
#include <Library/PcdLib.h>
#include <Library/DevicePathLib.h>
-#include <Library/UefiLib.h>
+#include "Colors.h"
//
// This is the generated header file which includes whatever needs to be exported (strings + IFR)
//
-#define UI_ACTION_NONE 0
-#define UI_ACTION_REFRESH_FORM 1
-#define UI_ACTION_REFRESH_FORMSET 2
-#define UI_ACTION_EXIT 3
+extern UINT8 SetupBrowserStrings[];
//
+// Screen definitions
+//
+#define BANNER_HEIGHT 6
+#define BANNER_COLUMNS 3
+#define BANNER_LEFT_COLUMN_INDENT 1
+
+#define FRONT_PAGE_HEADER_HEIGHT 6
+#define NONE_FRONT_PAGE_HEADER_HEIGHT 3
+#define LEFT_SKIPPED_COLUMNS 3
+#define FOOTER_HEIGHT 4
+#define STATUS_BAR_HEIGHT 1
+#define SCROLL_ARROW_HEIGHT 1
+#define POPUP_PAD_SPACE_COUNT 5
+#define POPUP_FRAME_WIDTH 2
+
+//
+// Definition for function key setting
+//
+#define NONE_FUNCTION_KEY_SETTING 0
+#define ENABLE_FUNCTION_KEY_SETTING 1
+
+typedef struct {
+ EFI_GUID FormSetGuid;
+ UINTN KeySetting;
+} FUNCTIION_KEY_SETTING;
+
+//
+// Character definitions
+//
+#define CHAR_SPACE 0x0020
+#define UPPER_LOWER_CASE_OFFSET 0x20
+
//
// Time definitions
//
#define ONE_SECOND 10000000
+//
+// Display definitions
+//
+#define LEFT_HYPER_DELIMITER L'<'
+#define RIGHT_HYPER_DELIMITER L'>'
+
+#define LEFT_ONEOF_DELIMITER L'<'
+#define RIGHT_ONEOF_DELIMITER L'>'
+
+#define LEFT_NUMERIC_DELIMITER L'['
+#define RIGHT_NUMERIC_DELIMITER L']'
+
+#define LEFT_CHECKBOX_DELIMITER L'['
+#define RIGHT_CHECKBOX_DELIMITER L']'
+
+#define CHECK_ON L'X'
+#define CHECK_OFF L' '
+
+#define TIME_SEPARATOR L':'
+#define DATE_SEPARATOR L'/'
+
+#define YES_ANSWER L'Y'
+#define NO_ANSWER L'N'
+
+//
+// This is the Input Error Message
+//
+#define INPUT_ERROR 1
+
+//
+// This is the NV RAM update required Message
+//
+#define NV_UPDATE_REQUIRED 2
+
+//
+// Refresh the Status Bar with flags
+//
+#define REFRESH_STATUS_BAR 0xff
+
+//
// Incremental string lenght of ConfigRequest
//
#define CONFIG_REQUEST_STRING_INCREMENTAL 1024
//
+// HII value compare result
+//
+#define HII_VALUE_UNDEFINED 0
+#define HII_VALUE_EQUAL 1
+#define HII_VALUE_LESS_THAN 2
+#define HII_VALUE_GREATER_THAN 3
+
+//
// Incremental size of stack for expression
//
#define EXPRESSION_STACK_SIZE_INCREMENT 0x100
@@ -87,13 +163,16 @@ typedef struct { //
// Produced protocol
//
- EFI_FORM_BROWSER2_PROTOCOL FormBrowser2;
- EFI_FORM_BROWSER_EXTENSION_PROTOCOL FormBrowserEx;
-
- EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL FormBrowserEx2;
+ EFI_FORM_BROWSER2_PROTOCOL FormBrowser2;
+
+ EFI_FORM_BROWSER_EXTENSION_PROTOCOL FormBrowserEx;
} SETUP_DRIVER_PRIVATE_DATA;
+typedef struct {
+ EFI_STRING_ID Banner[BANNER_HEIGHT][BANNER_COLUMNS];
+} BANNER_DATA;
+
//
// IFR relative definition
//
@@ -115,6 +194,16 @@ typedef struct { #define FORM_INCONSISTENT_VALIDATION 0
#define FORM_NO_SUBMIT_VALIDATION 1
+#define FORMSET_CLASS_PLATFORM_SETUP 0x0001
+#define FORMSET_CLASS_FRONT_PAGE 0x0002
+
+typedef struct {
+ UINT8 Type;
+ UINT8 *Buffer;
+ UINT16 BufferLen;
+ EFI_IFR_TYPE_VALUE Value;
+} EFI_HII_VALUE;
+
#define NAME_VALUE_NODE_SIGNATURE SIGNATURE_32 ('N', 'V', 'S', 'T')
typedef struct {
@@ -166,7 +255,6 @@ typedef struct { BROWSER_STORAGE *BrowserStorage;
CHAR16 *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement>
- CHAR16 *ConfigElements;// Elements need to load initial data.
UINTN ElementCount; // Number of <RequestElement> in the <ConfigRequest>
UINTN SpareStrLen; // Spare length of ConfigRequest string buffer
} FORMSET_STORAGE;
@@ -256,8 +344,6 @@ typedef struct { typedef struct {
UINTN Signature;
LIST_ENTRY Link;
-
- EFI_IFR_ONE_OF_OPTION *OpCode; // OneOfOption Data
EFI_STRING_ID Text;
UINT8 Flags;
@@ -290,7 +376,6 @@ typedef struct { LIST_ENTRY Link;
UINT8 Operand; // The operand (first byte) of this Statement or Question
- EFI_IFR_OP_HEADER *OpCode;
//
// Statement Header
@@ -300,11 +385,6 @@ typedef struct { EFI_STRING_ID TextTwo; // For EFI_IFR_TEXT
//
- // Fake Question Id, used for statement not has true QuestionId.
- //
- EFI_QUESTION_ID FakeQuestionId;
-
- //
// Question Header
//
EFI_QUESTION_ID QuestionId; // The value of zero is reserved
@@ -337,7 +417,6 @@ typedef struct { EFI_DEFAULT_ID DefaultId; // for EFI_IFR_RESET_BUTTON
EFI_GUID RefreshGuid; // for EFI_IFR_REFRESH_ID
BOOLEAN Locked; // Whether this statement is locked.
- BOOLEAN ValueChanged; // Whether this statement's value is changed.
//
// Get from IFR parsing
//
@@ -388,6 +467,8 @@ typedef struct { BOOLEAN ModalForm; // Whether this is a modal form.
BOOLEAN Locked; // Whether this form is locked.
+ BOOLEAN NvUpdateRequired; // Whether this form has NV update request.
+
LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)
LIST_ENTRY StatementListHead; // List of Statements and Questions (FORM_BROWSER_STATEMENT)
LIST_ENTRY ConfigRequestHead; // List of configreques for all storage.
@@ -421,7 +502,6 @@ typedef struct { UINTN IfrBinaryLength;
UINT8 *IfrBinaryData;
- BOOLEAN QuestionInited; // Have finished question initilization?
EFI_GUID Guid;
EFI_STRING_ID FormSetTitle;
EFI_STRING_ID Help;
@@ -434,82 +514,84 @@ typedef struct { FORM_BROWSER_STATEMENT *StatementBuffer; // Buffer for all Statements and Questions
EXPRESSION_OPCODE *ExpressionBuffer; // Buffer for all Expression OpCode
- LIST_ENTRY StatementListOSF; // Statement list out side of the form.
LIST_ENTRY StorageListHead; // Storage list (FORMSET_STORAGE)
LIST_ENTRY DefaultStoreListHead; // DefaultStore list (FORMSET_DEFAULTSTORE)
LIST_ENTRY FormListHead; // Form list (FORM_BROWSER_FORM)
LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)
} FORM_BROWSER_FORMSET;
-#define FORM_BROWSER_FORMSET_FROM_LINK(a) CR (a, FORM_BROWSER_FORMSET, Link, FORM_BROWSER_FORMSET_SIGNATURE)
-
-typedef struct {
- LIST_ENTRY Link;
- EFI_EVENT RefreshEvent;
-} FORM_BROWSER_REFRESH_EVENT_NODE;
-#define FORM_BROWSER_REFRESH_EVENT_FROM_LINK(a) BASE_CR (a, FORM_BROWSER_REFRESH_EVENT_NODE, Link)
+#define FORM_BROWSER_FORMSET_FROM_LINK(a) CR (a, FORM_BROWSER_FORMSET, Link, FORM_BROWSER_FORMSET_SIGNATURE)
+#define BROWSER_CONTEXT_SIGNATURE SIGNATURE_32 ('B', 'C', 'T', 'X')
typedef struct {
- EFI_HII_HANDLE Handle;
-
- //
- // Target formset/form/Question information
- //
- EFI_GUID FormSetGuid;
- UINT16 FormId;
- UINT16 QuestionId;
- UINTN Sequence; // used for time/date only.
-
- UINTN TopRow;
- UINTN BottomRow;
- UINTN PromptCol;
- UINTN OptionCol;
- UINTN CurrentRow;
-
- //
- // Ation for Browser to taken:
- // UI_ACTION_NONE - navigation inside a form
- // UI_ACTION_REFRESH_FORM - re-evaluate expressions and repaint form
- // UI_ACTION_REFRESH_FORMSET - re-parse formset IFR binary
- //
- UINTN Action;
+ UINTN Signature;
+ LIST_ENTRY Link;
//
- // Current selected fomset/form/Question
+ // Globals defined in Setup.c
//
- FORM_BROWSER_FORMSET *FormSet;
- FORM_BROWSER_FORM *Form;
- FORM_BROWSER_STATEMENT *Statement;
+ BANNER_DATA *BannerData;
+ UINTN ClassOfVfr;
+ UINTN FunctionKeySetting;
+ BOOLEAN ResetRequired;
+ UINT16 Direction;
+ EFI_SCREEN_DESCRIPTOR ScreenDimensions;
+ CHAR16 *EnterString;
+ CHAR16 *EnterCommitString;
+ CHAR16 *EnterEscapeString;
+ CHAR16 *EscapeString;
+ CHAR16 *MoveHighlight;
+ CHAR16 *MakeSelection;
+ CHAR16 *DecNumericInput;
+ CHAR16 *HexNumericInput;
+ CHAR16 *ToggleCheckBox;
+ CHAR16 *PromptForData;
+ CHAR16 *PromptForPassword;
+ CHAR16 *PromptForNewPassword;
+ CHAR16 *ConfirmPassword;
+ CHAR16 *ConfirmError;
+ CHAR16 *PassowordInvalid;
+ CHAR16 *PressEnter;
+ CHAR16 *EmptyString;
+ CHAR16 *AreYouSure;
+ CHAR16 *YesResponse;
+ CHAR16 *NoResponse;
+ CHAR16 *MiniString;
+ CHAR16 *PlusString;
+ CHAR16 *MinusString;
+ CHAR16 *AdjustNumber;
+ CHAR16 *SaveChanges;
+ CHAR16 *OptionMismatch;
+ CHAR16 *FormSuppress;
+ CHAR16 *ProtocolNotFound;
+ CHAR16 PromptBlockWidth;
+ CHAR16 OptionBlockWidth;
+ CHAR16 HelpBlockWidth;
+ FORM_BROWSER_FORMSET *OldFormSet;
//
- // Whether the Form is editable
+ // Globals defined in Ui.c
//
- BOOLEAN FormEditable;
+ LIST_ENTRY MenuOption;
+ VOID *MenuRefreshHead;
+} BROWSER_CONTEXT;
- FORM_ENTRY_INFO *CurrentMenu;
-} UI_MENU_SELECTION;
+#define BROWSER_CONTEXT_FROM_LINK(a) CR (a, BROWSER_CONTEXT, Link, BROWSER_CONTEXT_SIGNATURE)
-#define BROWSER_CONTEXT_SIGNATURE SIGNATURE_32 ('B', 'C', 'T', 'X')
+#define BROWSER_HOT_KEY_SIGNATURE SIGNATURE_32 ('B', 'H', 'K', 'S')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
+
+ EFI_INPUT_KEY *KeyData;
+ IN UINT32 Action;
+ IN UINT16 DefaultId;
+ IN EFI_STRING HelpString;
+} BROWSER_HOT_KEY;
- //
- // Globals defined in Setup.c
- //
- BOOLEAN ResetRequired;
- BOOLEAN ExitRequired;
- EFI_HII_HANDLE HiiHandle;
- EFI_GUID FormSetGuid;
- EFI_FORM_ID FormId;
- UI_MENU_SELECTION *Selection;
-
- LIST_ENTRY FormHistoryList;
-} BROWSER_CONTEXT;
-
-#define BROWSER_CONTEXT_FROM_LINK(a) CR (a, BROWSER_CONTEXT, Link, BROWSER_CONTEXT_SIGNATURE)
+#define BROWSER_HOT_KEY_FROM_LINK(a) CR (a, BROWSER_HOT_KEY, Link, BROWSER_HOT_KEY_SIGNATURE)
//
// Scope for get defaut value. It may be GetDefaultForNoStorage, GetDefaultForStorage or GetDefaultForAll.
@@ -532,31 +614,72 @@ typedef enum { } GET_SET_QUESTION_VALUE_WITH;
extern EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
+extern EFI_HII_STRING_PROTOCOL *mHiiString;
extern EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;
extern EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;
-extern EDKII_FORM_DISPLAY_ENGINE_PROTOCOL *mFormDisplay;
+extern BANNER_DATA *gBannerData;
+extern EFI_HII_HANDLE gFrontPageHandle;
+extern UINTN gClassOfVfr;
+extern UINTN gFunctionKeySetting;
extern BOOLEAN gResetRequired;
-extern BOOLEAN gExitRequired;
+extern EFI_HII_HANDLE gHiiHandle;
+extern UINT16 gDirection;
+extern EFI_SCREEN_DESCRIPTOR gScreenDimensions;
+extern FORM_BROWSER_FORMSET *gOldFormSet;
extern LIST_ENTRY gBrowserFormSetList;
extern LIST_ENTRY gBrowserHotKeyList;
extern BROWSER_SETTING_SCOPE gBrowserSettingScope;
extern EXIT_HANDLER ExitHandlerFunction;
-extern EFI_HII_HANDLE mCurrentHiiHandle;
+extern UINTN gFooterHeight;
+
//
// Browser Global Strings
//
+extern CHAR16 *gDiscardFailed;
+extern CHAR16 *gDefaultFailed;
+extern CHAR16 *gEnterString;
+extern CHAR16 *gEnterCommitString;
+extern CHAR16 *gEnterEscapeString;
+extern CHAR16 *gEscapeString;
+extern CHAR16 *gSaveFailed;
+extern CHAR16 *gMoveHighlight;
+extern CHAR16 *gMakeSelection;
+extern CHAR16 *gDecNumericInput;
+extern CHAR16 *gHexNumericInput;
+extern CHAR16 *gToggleCheckBox;
+extern CHAR16 *gPromptForData;
+extern CHAR16 *gPromptForPassword;
+extern CHAR16 *gPromptForNewPassword;
+extern CHAR16 *gConfirmPassword;
+extern CHAR16 *gConfirmError;
+extern CHAR16 *gPassowordInvalid;
+extern CHAR16 *gPressEnter;
extern CHAR16 *gEmptyString;
+extern CHAR16 *gAreYouSure;
+extern CHAR16 *gYesResponse;
+extern CHAR16 *gNoResponse;
+extern CHAR16 *gMiniString;
+extern CHAR16 *gPlusString;
+extern CHAR16 *gMinusString;
+extern CHAR16 *gAdjustNumber;
+extern CHAR16 *gSaveChanges;
+extern CHAR16 *gOptionMismatch;
+extern CHAR16 *gFormSuppress;
+extern CHAR16 *gProtocolNotFound;
+
+extern CHAR16 gPromptBlockWidth;
+extern CHAR16 gOptionBlockWidth;
+extern CHAR16 gHelpBlockWidth;
extern EFI_GUID gZeroGuid;
+extern EFI_GUID gTianoHiiIfrGuid;
-extern UI_MENU_SELECTION *gCurrentSelection;
-
+#include "Ui.h"
//
// Global Procedure Defines
//
-#include "Expression.h"
/**
Initialize the HII String Token to the correct values.
@@ -568,6 +691,91 @@ InitializeBrowserStrings ( );
/**
+ Prints a unicode string to the default console,
+ using L"%s" format.
+
+ @param String String pointer.
+
+ @return Length of string printed to the console
+
+**/
+UINTN
+PrintString (
+ IN CHAR16 *String
+ );
+
+/**
+ Prints a chracter to the default console,
+ using L"%c" format.
+
+ @param Character Character to print.
+
+ @return Length of string printed to the console.
+
+**/
+UINTN
+PrintChar (
+ CHAR16 Character
+ );
+
+/**
+ Prints a formatted unicode string to the default console, at
+ the supplied cursor position.
+
+ @param Column The cursor position to print the string at.
+ @param Row The cursor position to print the string at
+ @param Fmt Format string
+ @param ... Variable argument list for formating string.
+
+ @return Length of string printed to the console
+
+**/
+UINTN
+EFIAPI
+PrintAt (
+ IN UINTN Column,
+ IN UINTN Row,
+ IN CHAR16 *Fmt,
+ ...
+ );
+
+/**
+ Prints a unicode string to the default console, at
+ the supplied cursor position, using L"%s" format.
+
+ @param Column The cursor position to print the string at.
+ @param Row The cursor position to print the string at
+ @param String String pointer.
+
+ @return Length of string printed to the console
+
+**/
+UINTN
+PrintStringAt (
+ IN UINTN Column,
+ IN UINTN Row,
+ IN CHAR16 *String
+ );
+
+/**
+ Prints a chracter to the default console, at
+ the supplied cursor position, using L"%c" format.
+
+ @param Column The cursor position to print the string at.
+ @param Row The cursor position to print the string at.
+ @param Character Character to print.
+
+ @return Length of string printed to the console.
+
+**/
+UINTN
+PrintCharAt (
+ IN UINTN Column,
+ IN UINTN Row,
+ CHAR16 Character
+ );
+
+/**
Parse opcodes in the formset IFR binary.
@param FormSet Pointer of the FormSet data structure.
@@ -592,6 +800,17 @@ DestroyFormSet ( IN OUT FORM_BROWSER_FORMSET *FormSet
);
+/**
+ This function displays the page frame.
+
+ @param Selection Selection contains the information about
+ the Selection, form and formset to be displayed.
+ Selection action may be updated in retrieve callback.
+**/
+VOID
+DisplayPageFrame (
+ IN UI_MENU_SELECTION *Selection
+ );
/**
Create a new string in HII Package List.
@@ -641,6 +860,59 @@ GetToken ( );
/**
+ Draw a pop up windows based on the dimension, number of lines and
+ strings specified.
+
+ @param RequestedWidth The width of the pop-up.
+ @param NumberOfLines The number of lines.
+ @param Marker The variable argument list for the list of string to be printed.
+
+**/
+VOID
+CreateSharedPopUp (
+ IN UINTN RequestedWidth,
+ IN UINTN NumberOfLines,
+ IN VA_LIST Marker
+ );
+
+/**
+ Routine used to abstract a generic dialog interface and return the selected key or string
+
+ @param NumberOfLines The number of lines for the dialog box
+ @param HotKey Defines whether a single character is parsed
+ (TRUE) and returned in KeyValue or a string is
+ returned in StringBuffer. Two special characters
+ are considered when entering a string, a SCAN_ESC
+ and an CHAR_CARRIAGE_RETURN. SCAN_ESC terminates
+ string input and returns
+ @param MaximumStringSize The maximum size in bytes of a typed in string
+ (each character is a CHAR16) and the minimum
+ string returned is two bytes
+ @param StringBuffer The passed in pointer to the buffer which will
+ hold the typed in string if HotKey is FALSE
+ @param KeyValue The EFI_KEY value returned if HotKey is TRUE..
+ @param ... A series of (quantity == NumberOfLines) text
+ strings which will be used to construct the dialog
+ box
+
+ @retval EFI_SUCCESS Displayed dialog and received user interaction
+ @retval EFI_INVALID_PARAMETER One of the parameters was invalid (e.g.
+ (StringBuffer == NULL) && (HotKey == FALSE))
+ @retval EFI_DEVICE_ERROR User typed in an ESC character to exit the routine
+
+**/
+EFI_STATUS
+EFIAPI
+CreateDialog (
+ IN UINTN NumberOfLines,
+ IN BOOLEAN HotKey,
+ IN UINTN MaximumStringSize,
+ OUT CHAR16 *StringBuffer,
+ OUT EFI_INPUT_KEY *KeyValue,
+ ...
+ );
+
+/**
Get Value for given Name from a NameValue Storage.
@param Storage The NameValue Storage.
@@ -667,7 +939,6 @@ GetValueByName ( @param Name The Name.
@param Value The Value to set.
@param SetValueTo Whether update editValue or Value.
- @param ReturnNode The node use the input name.
@retval EFI_SUCCESS Value found for given Name.
@retval EFI_NOT_FOUND No such Name found in NameValue storage.
@@ -675,31 +946,10 @@ GetValueByName ( **/
EFI_STATUS
SetValueByName (
- IN BROWSER_STORAGE *Storage,
- IN CHAR16 *Name,
- IN CHAR16 *Value,
- IN GET_SET_QUESTION_VALUE_WITH SetValueTo,
- OUT NAME_VALUE_NODE **ReturnNode
- );
-
-/**
- Validate whether this question's value has changed.
-
- @param FormSet FormSet data structure.
- @param Form Form data structure.
- @param Question Question to be initialized.
- @param GetValueFrom Where to get value, may from editbuffer, buffer or hii driver.
-
- @retval TRUE Question's value has changed.
- @retval FALSE Question's value has not changed
-
-**/
-BOOLEAN
-IsQuestionValueChanged (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN FORM_BROWSER_FORM *Form,
- IN OUT FORM_BROWSER_STATEMENT *Question,
- IN GET_SET_QUESTION_VALUE_WITH GetValueFrom
+ IN BROWSER_STORAGE *Storage,
+ IN CHAR16 *Name,
+ IN CHAR16 *Value,
+ IN GET_SET_QUESTION_VALUE_WITH SetValueTo
);
/**
@@ -821,8 +1071,10 @@ GetQuestionDefault ( @param FormSet FormSet data structure.
+ @retval EFI_SUCCESS The function completed successfully.
+
**/
-VOID
+EFI_STATUS
InitializeCurrentSetting (
IN OUT FORM_BROWSER_FORMSET *FormSet
);
@@ -835,6 +1087,7 @@ InitializeCurrentSetting ( GUID), take the first FormSet found in package
list.
@param FormSet FormSet data structure.
+ @param UpdateGlobalVar Whether need to update the global variable.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The specified FormSet could not be found.
@@ -844,7 +1097,8 @@ EFI_STATUS InitializeFormSet (
IN EFI_HII_HANDLE Handle,
IN OUT EFI_GUID *FormSetGuid,
- OUT FORM_BROWSER_FORMSET *FormSet
+ OUT FORM_BROWSER_FORMSET *FormSet,
+ IN BOOLEAN UpdateGlobalVar
);
/**
@@ -922,7 +1176,6 @@ LoadFormSetConfig ( @param Storage The Storage to be conveted.
@param ConfigResp The returned <ConfigResp>.
@param ConfigRequest The ConfigRequest string.
- @param GetEditBuf Get the data from editbuffer or buffer.
@retval EFI_SUCCESS Convert success.
@retval EFI_INVALID_PARAMETER Incorrect storage type.
@@ -932,8 +1185,7 @@ EFI_STATUS StorageToConfigResp (
IN BROWSER_STORAGE *Storage,
IN CHAR16 **ConfigResp,
- IN CHAR16 *ConfigRequest,
- IN BOOLEAN GetEditBuf
+ IN CHAR16 *ConfigRequest
);
/**
@@ -958,8 +1210,10 @@ ConfigRespToStorage ( @param FormSet FormSet data structure.
@param Storage Buffer Storage.
+ @retval EFI_SUCCESS The function completed successfully.
+
**/
-VOID
+EFI_STATUS
LoadStorage (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORMSET_STORAGE *Storage
@@ -1095,29 +1349,30 @@ BrowserCallback ( about the Selection, form and formset to be displayed.
On output, Selection return the screen item that is selected
by user.
- @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.
- else, we need to exit current formset.
+ @param Repaint Whether need to repaint the menu.
+ @param NewLine Whether need to show at new line.
- @retval TRUE Exit current form.
- @retval FALSE User press ESC and keep in current form.
+ @retval TRUE Need return.
+ @retval FALSE No need to return.
**/
BOOLEAN
FindNextMenu (
- IN OUT UI_MENU_SELECTION *Selection,
- IN BROWSER_SETTING_SCOPE SettingLevel
+ IN OUT UI_MENU_SELECTION *Selection,
+ IN BOOLEAN *Repaint,
+ IN BOOLEAN *NewLine
);
/**
- check whether the form need to update the NV.
+ check whether the formset need to update the NV.
- @param Form Form data structure.
+ @param FormSet FormSet data structure.
+ @param SetValue Whether set new value or clear old value.
- @retval TRUE Need to update the NV.
- @retval FALSE No need to update the NV.
**/
-BOOLEAN
-IsNvUpdateRequiredForForm (
- IN FORM_BROWSER_FORM *Form
+VOID
+UpdateNvInfoInForm (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN BOOLEAN SetValue
);
/**
@@ -1128,22 +1383,9 @@ IsNvUpdateRequiredForForm ( @retval TRUE Need to update the NV.
@retval FALSE No need to update the NV.
**/
-BOOLEAN
-IsNvUpdateRequiredForFormSet (
- IN FORM_BROWSER_FORMSET *FormSet
- );
-
-/**
- Check whether the storage data for current form set is changed.
-
- @param FormSet FormSet data structure.
-
- @retval TRUE Data is changed.
- @retval FALSE Data is not changed.
-**/
BOOLEAN
-IsStorageDataChangedForFormSet (
- IN FORM_BROWSER_FORMSET *FormSet
+IsNvUpdateRequired (
+ IN FORM_BROWSER_FORMSET *FormSet
);
/**
@@ -1275,38 +1517,6 @@ RegiserExitHandler ( );
/**
-
- Check whether the browser data has been modified.
-
- @retval TRUE Browser data is changed.
- @retval FALSE No browser data is changed.
-
-**/
-BOOLEAN
-EFIAPI
-IsBrowserDataModified (
- VOID
- );
-
-/**
-
- Execute the action requested by the Action parameter.
-
- @param[in] Action Execute the request action.
- @param[in] DefaultId The default Id info when need to load default value.
-
- @retval EFI_SUCCESS Execute the request action succss.
- @retval EFI_INVALID_PARAMETER The input action value is invalid.
-
-**/
-EFI_STATUS
-EFIAPI
-ExecuteAction (
- IN UINT32 Action,
- IN UINT16 DefaultId
- );
-
-/**
Create reminder to let user to choose save or discard the changed browser data.
Caller can use it to actively check the changed browser data.
@@ -1335,267 +1545,6 @@ GetHotKeyFromRegisterList ( );
/**
-
- Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
-
- @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
-
- @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
-
-**/
-FORM_BROWSER_STATEMENT *
-GetBrowserStatement (
- IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement
- );
-
-/**
- Password may be stored as encrypted by Configuration Driver. When change a
- password, user will be challenged with old password. To validate user input old
- password, we will send the clear text to Configuration Driver via Callback().
- Configuration driver is responsible to check the passed in password and return
- the validation result. If validation pass, state machine in password Callback()
- will transit from BROWSER_STATE_VALIDATE_PASSWORD to BROWSER_STATE_SET_PASSWORD.
- After user type in new password twice, Callback() will be invoked to send the
- new password to Configuration Driver.
-
- @param Selection Pointer to UI_MENU_SELECTION.
- @param MenuOption The MenuOption for this password Question.
- @param String The clear text of password.
-
- @retval EFI_NOT_AVAILABLE_YET Callback() request to terminate password input.
- @return In state of BROWSER_STATE_VALIDATE_PASSWORD:
- @retval EFI_SUCCESS Password correct, Browser will prompt for new
- password.
- @retval EFI_NOT_READY Password incorrect, Browser will show error
- message.
- @retval Other Browser will do nothing.
- @return In state of BROWSER_STATE_SET_PASSWORD:
- @retval EFI_SUCCESS Set password success.
- @retval Other Set password failed.
-
-**/
-EFI_STATUS
-PasswordCallback (
- IN UI_MENU_SELECTION *Selection,
- IN FORM_BROWSER_STATEMENT *Question,
- IN CHAR16 *String
- );
-
-/**
- Display error message for invalid password.
-
-**/
-VOID
-PasswordInvalid (
- VOID
- );
-
-/**
- The worker function that send the displays to the screen. On output,
- the selection made by user is returned.
-
- @param Selection On input, Selection tell setup browser the information
- about the Selection, form and formset to be displayed.
- On output, Selection return the screen item that is selected
- by user.
-
- @retval EFI_SUCCESS The page is displayed successfully.
- @return Other value if the page failed to be diplayed.
-
-**/
-EFI_STATUS
-SetupBrowser (
- IN OUT UI_MENU_SELECTION *Selection
- );
-
-/**
- Free up the resource allocated for all strings required
- by Setup Browser.
-
-**/
-VOID
-FreeBrowserStrings (
- VOID
- );
-
-/**
- Create a menu with specified formset GUID and form ID, and add it as a child
- of the given parent menu.
-
- @param HiiHandle Hii handle related to this formset.
- @param FormSetGuid The Formset Guid of menu to be added.
- @param FormId The Form ID of menu to be added.
- @param QuestionId The question id of this menu to be added.
-
- @return A pointer to the newly added menu or NULL if memory is insufficient.
-
-**/
-FORM_ENTRY_INFO *
-UiAddMenuList (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_GUID *FormSetGuid,
- IN UINT16 FormId,
- IN UINT16 QuestionId
- );
-
-/**
- Search Menu with given FormSetGuid and FormId in all cached menu list.
-
- @param HiiHandle HiiHandle for FormSet.
- @param FormSetGuid The Formset GUID of the menu to search.
- @param FormId The Form ID of menu to search.
-
- @return A pointer to menu found or NULL if not found.
-
-**/
-FORM_ENTRY_INFO *
-UiFindMenuList (
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_GUID *FormSetGuid,
- IN UINT16 FormId
- );
-
-/**
- Free Menu list linked list.
-
- @param MenuListHead One Menu list point in the menu list.
-
-**/
-VOID
-UiFreeMenuList (
- LIST_ENTRY *MenuListHead
- );
-
-/**
- Find parent menu for current menu.
-
- @param CurrentMenu Current Menu
-
- @retval The parent menu for current menu.
-**/
-FORM_ENTRY_INFO *
-UiFindParentMenu (
- IN FORM_ENTRY_INFO *CurrentMenu
- );
-
-/**
- Search an Option of a Question by its value.
-
- @param Question The Question
- @param OptionValue Value for Option to be searched.
-
- @retval Pointer Pointer to the found Option.
- @retval NULL Option not found.
-
-**/
-QUESTION_OPTION *
-ValueToOption (
- IN FORM_BROWSER_STATEMENT *Question,
- IN EFI_HII_VALUE *OptionValue
- );
-/**
- Return data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
-
- @retval Value The data to be returned
-
-**/
-UINT64
-GetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index
- );
-
-/**
- Set value of a data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
- @param Value The value to be set.
-
-**/
-VOID
-SetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index,
- IN UINT64 Value
- );
-
-/**
- Compare two Hii value.
-
- @param Value1 Expression value to compare on left-hand.
- @param Value2 Expression value to compare on right-hand.
- @param Result Return value after compare.
- retval 0 Two operators equal.
- return Positive value if Value1 is greater than Value2.
- retval Negative value if Value1 is less than Value2.
- @param HiiHandle Only required for string compare.
-
- @retval other Could not perform compare on two values.
- @retval EFI_SUCCESS Compare the value success.
-
-**/
-EFI_STATUS
-CompareHiiValue (
- IN EFI_HII_VALUE *Value1,
- IN EFI_HII_VALUE *Value2,
- OUT INTN *Result,
- IN EFI_HII_HANDLE HiiHandle OPTIONAL
- );
-
-/**
- Perform Password check.
- Passwork may be encrypted by driver that requires the specific check.
-
- @param Form Form where Password Statement is in.
- @param Statement Password statement
- @param PasswordString Password string to be checked. It may be NULL.
- NULL means to restore password.
- "" string can be used to checked whether old password does exist.
-
- @return Status Status of Password check.
-**/
-EFI_STATUS
-EFIAPI
-PasswordCheck (
- IN FORM_DISPLAY_ENGINE_FORM *Form,
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
- IN EFI_STRING PasswordString OPTIONAL
- );
-
-/**
-
- Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
-
- @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
-
- @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
-
-**/
-FORM_BROWSER_STATEMENT *
-GetBrowserStatement (
- IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement
- );
-
-/**
-
- Initialize the Display form structure data.
-
-**/
-VOID
-InitializeDisplayFormData (
- VOID
- );
-
-
-/**
Base on the current formset info, clean the ConfigRequest string in browser storage.
@param FormSet Pointer of the FormSet
@@ -1605,5 +1554,5 @@ VOID CleanBrowserStorage (
IN OUT FORM_BROWSER_FORMSET *FormSet
);
-
+
#endif
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf index a3f3a6fc2c..7e740bc099 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf +++ b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf @@ -19,7 +19,7 @@ BASE_NAME = SetupBrowser
FILE_GUID = EBf342FE-B1D3-4EF8-957C-8048606FF671
MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 2.0
+ VERSION_STRING = 1.0
ENTRY_POINT = InitializeSetup
#
@@ -29,12 +29,19 @@ #
[Sources]
+ SetupBrowserStr.uni
Setup.c
Setup.h
IfrParse.c
Expression.c
+ InputHandler.c
+ Print.c
Presentation.c
- Expression.h
+ ProcessOptions.c
+ Ui.c
+ Ui.h
+ Colors.h
+
[Packages]
MdePkg/MdePkg.dec
@@ -52,27 +59,34 @@ HiiLib
DevicePathLib
PcdLib
- UefiLib
[Guids]
+ gEfiIfrTianoGuid ## CONSUMES ## GUID
gEfiIfrFrameworkGuid ## CONSUMES ## GUID
gEfiHiiPlatformSetupFormsetGuid
gEfiHiiStandardFormGuid ## SOMETIMES_CONSUMES ## GUID
[Protocols]
gEfiHiiConfigAccessProtocolGuid ## CONSUMES
+ gEfiHiiStringProtocolGuid ## CONSUMES
gEfiFormBrowser2ProtocolGuid ## PRODUCES
- gEdkiiFormBrowserEx2ProtocolGuid ## PRODUCES
+ gEfiFormBrowserExProtocolGuid ## PRODUCES
gEfiHiiConfigRoutingProtocolGuid ## CONSUMES
gEfiHiiDatabaseProtocolGuid ## CONSUMES
gEfiUnicodeCollation2ProtocolGuid ## CONSUMES
gEfiUserManagerProtocolGuid ## SOMETIMES_CONSUMES
gEfiDevicePathFromTextProtocolGuid ## SOMETIMES_CONSUMES
- gEdkiiFormDisplayEngineProtocolGuid ## PRODUCE
- gEfiFormBrowserExProtocolGuid ## PRODUCE
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBrowerGrayOutReadOnlyMenu ## CONSUMES
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextHighlightColor ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldBackgroundHighlightColor ## CONSUMES
[Depex]
gEfiHiiDatabaseProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni Binary files differindex 0ee7f46302..bb6414d206 100644 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni +++ b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c new file mode 100644 index 0000000000..7c246b60e1 --- /dev/null +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c @@ -0,0 +1,4027 @@ +/** @file
+Utility functions for User Interface functions.
+
+Copyright (c) 2004 - 2013, 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 "Setup.h"
+
+LIST_ENTRY gMenuOption;
+LIST_ENTRY gMenuList;
+MENU_REFRESH_ENTRY *gMenuRefreshHead; // Menu list used for refresh timer opcode.
+MENU_REFRESH_ENTRY *gMenuEventGuidRefreshHead; // Menu list used for refresh event guid opcode.
+
+//
+// Search table for UiDisplayMenu()
+//
+SCAN_CODE_TO_SCREEN_OPERATION gScanCodeToOperation[] = {
+ {
+ SCAN_UP,
+ UiUp,
+ },
+ {
+ SCAN_DOWN,
+ UiDown,
+ },
+ {
+ SCAN_PAGE_UP,
+ UiPageUp,
+ },
+ {
+ SCAN_PAGE_DOWN,
+ UiPageDown,
+ },
+ {
+ SCAN_ESC,
+ UiReset,
+ },
+ {
+ SCAN_LEFT,
+ UiLeft,
+ },
+ {
+ SCAN_RIGHT,
+ UiRight,
+ }
+};
+
+UINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);
+
+SCREEN_OPERATION_T0_CONTROL_FLAG gScreenOperationToControlFlag[] = {
+ {
+ UiNoOperation,
+ CfUiNoOperation,
+ },
+ {
+ UiSelect,
+ CfUiSelect,
+ },
+ {
+ UiUp,
+ CfUiUp,
+ },
+ {
+ UiDown,
+ CfUiDown,
+ },
+ {
+ UiLeft,
+ CfUiLeft,
+ },
+ {
+ UiRight,
+ CfUiRight,
+ },
+ {
+ UiReset,
+ CfUiReset,
+ },
+ {
+ UiPageUp,
+ CfUiPageUp,
+ },
+ {
+ UiPageDown,
+ CfUiPageDown
+ },
+ {
+ UiHotKey,
+ CfUiHotKey
+ }
+};
+
+BOOLEAN mInputError;
+BOOLEAN GetLineByWidthFinished = FALSE;
+
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Size Number of bytes to set
+ @param Value Value of the set operation.
+
+**/
+VOID
+SetUnicodeMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN CHAR16 Value
+ )
+{
+ CHAR16 *Ptr;
+
+ Ptr = Buffer;
+ while ((Size--) != 0) {
+ *(Ptr++) = Value;
+ }
+}
+
+
+/**
+ Initialize Menu option list.
+
+**/
+VOID
+UiInitMenu (
+ VOID
+ )
+{
+ InitializeListHead (&gMenuOption);
+}
+
+
+/**
+ Free Menu option linked list.
+
+**/
+VOID
+UiFreeMenu (
+ VOID
+ )
+{
+ UI_MENU_OPTION *MenuOption;
+
+ while (!IsListEmpty (&gMenuOption)) {
+ MenuOption = MENU_OPTION_FROM_LINK (gMenuOption.ForwardLink);
+ RemoveEntryList (&MenuOption->Link);
+
+ //
+ // We allocated space for this description when we did a GetToken, free it here
+ //
+ if (MenuOption->Skip != 0) {
+ //
+ // For date/time, MenuOption->Description is shared by three Menu Options
+ // Data format : [01/02/2004] [11:22:33]
+ // Line number : 0 0 1 0 0 1
+ //
+ FreePool (MenuOption->Description);
+ }
+ FreePool (MenuOption);
+ }
+}
+
+
+/**
+ Create a menu with specified formset GUID and form ID, and add it as a child
+ of the given parent menu.
+
+ @param Parent The parent of menu to be added.
+ @param HiiHandle Hii handle related to this formset.
+ @param FormSetGuid The Formset Guid of menu to be added.
+ @param FormId The Form ID of menu to be added.
+
+ @return A pointer to the newly added menu or NULL if memory is insufficient.
+
+**/
+UI_MENU_LIST *
+UiAddMenuList (
+ IN OUT UI_MENU_LIST *Parent,
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid,
+ IN UINT16 FormId
+ )
+{
+ UI_MENU_LIST *MenuList;
+
+ MenuList = AllocateZeroPool (sizeof (UI_MENU_LIST));
+ if (MenuList == NULL) {
+ return NULL;
+ }
+
+ MenuList->Signature = UI_MENU_LIST_SIGNATURE;
+ InitializeListHead (&MenuList->ChildListHead);
+
+ MenuList->HiiHandle = HiiHandle;
+ CopyMem (&MenuList->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));
+ MenuList->FormId = FormId;
+ MenuList->Parent = Parent;
+
+ if (Parent == NULL) {
+ //
+ // If parent is not specified, it is the root Form of a Formset
+ //
+ InsertTailList (&gMenuList, &MenuList->Link);
+ } else {
+ InsertTailList (&Parent->ChildListHead, &MenuList->Link);
+ }
+
+ return MenuList;
+}
+
+
+/**
+ Search Menu with given FormId, FormSetGuid and Handle in all cached menu list.
+
+ @param Parent The parent of menu to search.
+ @param Handle Hii handle related to this formset.
+ @param FormSetGuid The Formset GUID of the menu to search.
+ @param FormId The Form ID of menu to search.
+
+ @return A pointer to menu found or NULL if not found.
+
+**/
+UI_MENU_LIST *
+UiFindChildMenuList (
+ IN UI_MENU_LIST *Parent,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_GUID *FormSetGuid,
+ IN UINT16 FormId
+ )
+{
+ LIST_ENTRY *Link;
+ UI_MENU_LIST *Child;
+ UI_MENU_LIST *MenuList;
+
+ ASSERT (Parent != NULL);
+
+ if (Parent->FormId == FormId && CompareGuid (FormSetGuid, &Parent->FormSetGuid) && Parent->HiiHandle == Handle) {
+ return Parent;
+ }
+
+ Link = GetFirstNode (&Parent->ChildListHead);
+ while (!IsNull (&Parent->ChildListHead, Link)) {
+ Child = UI_MENU_LIST_FROM_LINK (Link);
+
+ MenuList = UiFindChildMenuList (Child, Handle, FormSetGuid, FormId);
+ if (MenuList != NULL) {
+ return MenuList;
+ }
+
+ Link = GetNextNode (&Parent->ChildListHead, Link);
+ }
+
+ return NULL;
+}
+
+
+/**
+ Search Menu with given Handle, FormSetGuid and FormId in all cached menu list.
+
+ @param Handle Hii handle related to this formset.
+ @param FormSetGuid The Formset GUID of the menu to search.
+ @param FormId The Form ID of menu to search.
+
+ @return A pointer to menu found or NULL if not found.
+
+**/
+UI_MENU_LIST *
+UiFindMenuList (
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_GUID *FormSetGuid,
+ IN UINT16 FormId
+ )
+{
+ LIST_ENTRY *Link;
+ UI_MENU_LIST *MenuList;
+ UI_MENU_LIST *Child;
+
+ Link = GetFirstNode (&gMenuList);
+ while (!IsNull (&gMenuList, Link)) {
+ MenuList = UI_MENU_LIST_FROM_LINK (Link);
+
+ Child = UiFindChildMenuList(MenuList, Handle, FormSetGuid, FormId);
+ if (Child != NULL) {
+
+ //
+ // If this form already in the menu history list,
+ // just free the list between old this form.
+ //
+ UiFreeMenuList(&Child->ChildListHead);
+ return Child;
+ }
+
+ Link = GetNextNode (&gMenuList, Link);
+ }
+
+ return NULL;
+}
+
+/**
+ Free Menu list linked list.
+
+ @param MenuListHead One Menu list point in the menu list.
+
+**/
+VOID
+UiFreeMenuList (
+ LIST_ENTRY *MenuListHead
+ )
+{
+ UI_MENU_LIST *MenuList;
+
+ while (!IsListEmpty (MenuListHead)) {
+ MenuList = UI_MENU_LIST_FROM_LINK (MenuListHead->ForwardLink);
+ RemoveEntryList (&MenuList->Link);
+
+ UiFreeMenuList(&MenuList->ChildListHead);
+ FreePool (MenuList);
+ }
+
+}
+
+/**
+ Free Menu option linked list.
+
+**/
+VOID
+UiFreeRefreshList (
+ VOID
+ )
+{
+ MENU_REFRESH_ENTRY *OldMenuRefreshEntry;
+
+ while (gMenuRefreshHead != NULL) {
+ OldMenuRefreshEntry = gMenuRefreshHead->Next;
+ FreePool (gMenuRefreshHead);
+ gMenuRefreshHead = OldMenuRefreshEntry;
+ }
+
+ while (gMenuEventGuidRefreshHead != NULL) {
+ OldMenuRefreshEntry = gMenuEventGuidRefreshHead->Next;
+ if (gMenuEventGuidRefreshHead != NULL) {
+ gBS->CloseEvent(gMenuEventGuidRefreshHead->Event);
+ }
+ FreePool (gMenuEventGuidRefreshHead);
+ gMenuEventGuidRefreshHead = OldMenuRefreshEntry;
+ }
+}
+
+
+/**
+ Process option string for date/time opcode.
+
+ @param MenuOption Menu option point to date/time.
+ @param OptionString Option string input for process.
+ @param AddOptCol Whether need to update MenuOption->OptCol.
+
+**/
+VOID
+ProcessStringForDateTime (
+ UI_MENU_OPTION *MenuOption,
+ CHAR16 *OptionString,
+ BOOLEAN AddOptCol
+ )
+{
+ UINTN Index;
+ UINTN Count;
+ FORM_BROWSER_STATEMENT *Statement;
+
+ ASSERT (MenuOption != NULL && OptionString != NULL);
+
+ Statement = MenuOption->ThisTag;
+
+ //
+ // If leading spaces on OptionString - remove the spaces
+ //
+ for (Index = 0; OptionString[Index] == L' '; Index++) {
+ //
+ // Base on the blockspace to get the option column info.
+ //
+ if (AddOptCol) {
+ MenuOption->OptCol++;
+ }
+ }
+
+ for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {
+ OptionString[Count] = OptionString[Index];
+ Count++;
+ }
+ OptionString[Count] = CHAR_NULL;
+
+ //
+ // Enable to suppress field in the opcode base on the flag.
+ //
+ if (Statement->Operand == EFI_IFR_DATE_OP) {
+ //
+ // OptionString format is: <**: **: ****>
+ // |month|day|year|
+ // 4 3 5
+ //
+ if ((Statement->Flags & EFI_QF_DATE_MONTH_SUPPRESS) && (MenuOption->Sequence == 0)) {
+ //
+ // At this point, only "<**:" in the optionstring.
+ // Clean the day's ** field, after clean, the format is "< :"
+ //
+ SetUnicodeMem (&OptionString[1], 2, L' ');
+ } else if ((Statement->Flags & EFI_QF_DATE_DAY_SUPPRESS) && (MenuOption->Sequence == 1)) {
+ //
+ // At this point, only "**:" in the optionstring.
+ // Clean the month's "**" field, after clean, the format is " :"
+ //
+ SetUnicodeMem (&OptionString[0], 2, L' ');
+ } else if ((Statement->Flags & EFI_QF_DATE_YEAR_SUPPRESS) && (MenuOption->Sequence == 2)) {
+ //
+ // At this point, only "****>" in the optionstring.
+ // Clean the year's "****" field, after clean, the format is " >"
+ //
+ SetUnicodeMem (&OptionString[0], 4, L' ');
+ }
+ } else if (Statement->Operand == EFI_IFR_TIME_OP) {
+ //
+ // OptionString format is: <**: **: **>
+ // |hour|minute|second|
+ // 4 3 3
+ //
+ if ((Statement->Flags & QF_TIME_HOUR_SUPPRESS) && (MenuOption->Sequence == 0)) {
+ //
+ // At this point, only "<**:" in the optionstring.
+ // Clean the hour's ** field, after clean, the format is "< :"
+ //
+ SetUnicodeMem (&OptionString[1], 2, L' ');
+ } else if ((Statement->Flags & QF_TIME_MINUTE_SUPPRESS) && (MenuOption->Sequence == 1)) {
+ //
+ // At this point, only "**:" in the optionstring.
+ // Clean the minute's "**" field, after clean, the format is " :"
+ //
+ SetUnicodeMem (&OptionString[0], 2, L' ');
+ } else if ((Statement->Flags & QF_TIME_SECOND_SUPPRESS) && (MenuOption->Sequence == 2)) {
+ //
+ // At this point, only "**>" in the optionstring.
+ // Clean the second's "**" field, after clean, the format is " >"
+ //
+ SetUnicodeMem (&OptionString[0], 2, L' ');
+ }
+ }
+}
+
+/**
+ Refresh question.
+
+ @param MenuRefreshEntry Menu refresh structure which has info about the refresh question.
+**/
+EFI_STATUS
+RefreshQuestion (
+ IN MENU_REFRESH_ENTRY *MenuRefreshEntry
+ )
+{
+ CHAR16 *OptionString;
+ EFI_STATUS Status;
+ UI_MENU_SELECTION *Selection;
+ FORM_BROWSER_STATEMENT *Question;
+
+ Selection = MenuRefreshEntry->Selection;
+ Question = MenuRefreshEntry->MenuOption->ThisTag;
+
+ Status = GetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithHiiDriver);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ OptionString = NULL;
+ ProcessOptions (Selection, MenuRefreshEntry->MenuOption, FALSE, &OptionString);
+
+ if (OptionString != NULL) {
+ //
+ // If old Text is longer than new string, need to clean the old string before paint the newer.
+ // This option is no need for time/date opcode, because time/data opcode has fixed string length.
+ //
+ if ((MenuRefreshEntry->MenuOption->ThisTag->Operand != EFI_IFR_DATE_OP) &&
+ (MenuRefreshEntry->MenuOption->ThisTag->Operand != EFI_IFR_TIME_OP)) {
+ ClearLines (
+ MenuRefreshEntry->CurrentColumn,
+ MenuRefreshEntry->CurrentColumn + gOptionBlockWidth - 1,
+ MenuRefreshEntry->CurrentRow,
+ MenuRefreshEntry->CurrentRow,
+ PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND
+ );
+ }
+
+ gST->ConOut->SetAttribute (gST->ConOut, MenuRefreshEntry->CurrentAttribute);
+ ProcessStringForDateTime(MenuRefreshEntry->MenuOption, OptionString, FALSE);
+ PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, OptionString);
+ FreePool (OptionString);
+ }
+
+ //
+ // Question value may be changed, need invoke its Callback()
+ //
+ Status = ProcessCallBackFunction (Selection, Question, EFI_BROWSER_ACTION_CHANGING, FALSE);
+
+ return Status;
+}
+
+/**
+ Refresh the question which has refresh guid event attribute.
+
+ @param Event The event which has this function related.
+ @param Context The input context info related to this event or the status code return to the caller.
+**/
+VOID
+EFIAPI
+RefreshQuestionNotify(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ MENU_REFRESH_ENTRY *MenuRefreshEntry;
+ UI_MENU_SELECTION *Selection;
+
+ //
+ // Reset FormPackage update flag
+ //
+ mHiiPackageListUpdated = FALSE;
+
+ MenuRefreshEntry = (MENU_REFRESH_ENTRY *)Context;
+ ASSERT (MenuRefreshEntry != NULL);
+ Selection = MenuRefreshEntry->Selection;
+
+ RefreshQuestion (MenuRefreshEntry);
+
+ if (mHiiPackageListUpdated) {
+ //
+ // Package list is updated, force to reparse IFR binary of target Formset
+ //
+ mHiiPackageListUpdated = FALSE;
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;
+ }
+}
+
+
+/**
+ Refresh screen.
+
+**/
+EFI_STATUS
+RefreshForm (
+ VOID
+ )
+{
+ MENU_REFRESH_ENTRY *MenuRefreshEntry;
+ EFI_STATUS Status;
+ UI_MENU_SELECTION *Selection;
+
+ if (gMenuRefreshHead != NULL) {
+ //
+ // call from refresh interval process.
+ //
+ MenuRefreshEntry = gMenuRefreshHead;
+ Selection = MenuRefreshEntry->Selection;
+ //
+ // Reset FormPackage update flag
+ //
+ mHiiPackageListUpdated = FALSE;
+
+ do {
+ Status = RefreshQuestion (MenuRefreshEntry);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MenuRefreshEntry = MenuRefreshEntry->Next;
+
+ } while (MenuRefreshEntry != NULL);
+
+ if (mHiiPackageListUpdated) {
+ //
+ // Package list is updated, force to reparse IFR binary of target Formset
+ //
+ mHiiPackageListUpdated = FALSE;
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_TIMEOUT;
+}
+
+
+/**
+ Wait for a given event to fire, or for an optional timeout to expire.
+
+ @param Event The event to wait for
+ @param Timeout An optional timeout value in 100 ns units.
+ @param RefreshInterval Menu refresh interval (in seconds).
+
+ @retval EFI_SUCCESS Event fired before Timeout expired.
+ @retval EFI_TIME_OUT Timout expired before Event fired.
+
+**/
+EFI_STATUS
+UiWaitForSingleEvent (
+ IN EFI_EVENT Event,
+ IN UINT64 Timeout, OPTIONAL
+ IN UINT8 RefreshInterval OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_EVENT TimerEvent;
+ EFI_EVENT WaitList[2];
+
+ if (Timeout != 0) {
+ //
+ // Create a timer event
+ //
+ Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Set the timer event
+ //
+ gBS->SetTimer (
+ TimerEvent,
+ TimerRelative,
+ Timeout
+ );
+
+ //
+ // Wait for the original event or the timer
+ //
+ WaitList[0] = Event;
+ WaitList[1] = TimerEvent;
+ Status = gBS->WaitForEvent (2, WaitList, &Index);
+ gBS->CloseEvent (TimerEvent);
+
+ //
+ // If the timer expired, change the return to timed out
+ //
+ if (!EFI_ERROR (Status) && Index == 1) {
+ Status = EFI_TIMEOUT;
+ }
+ }
+ } else {
+ //
+ // Update screen every second
+ //
+ if (RefreshInterval == 0) {
+ Timeout = ONE_SECOND;
+ } else {
+ Timeout = RefreshInterval * ONE_SECOND;
+ }
+
+ do {
+ Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
+
+ //
+ // Set the timer event
+ //
+ gBS->SetTimer (
+ TimerEvent,
+ TimerRelative,
+ Timeout
+ );
+
+ //
+ // Wait for the original event or the timer
+ //
+ WaitList[0] = Event;
+ WaitList[1] = TimerEvent;
+ Status = gBS->WaitForEvent (2, WaitList, &Index);
+
+ //
+ // If the timer expired, update anything that needs a refresh and keep waiting
+ //
+ if (!EFI_ERROR (Status) && Index == 1) {
+ Status = EFI_TIMEOUT;
+ if (RefreshInterval != 0) {
+ Status = RefreshForm ();
+ }
+ }
+
+ gBS->CloseEvent (TimerEvent);
+ } while (Status == EFI_TIMEOUT);
+ }
+
+ return Status;
+}
+
+
+/**
+ Add one menu option by specified description and context.
+
+ @param String String description for this option.
+ @param Handle Hii handle for the package list.
+ @param Form The form this statement belong to.
+ @param Statement Statement of this Menu Option.
+ @param NumberOfLines Display lines for this Menu Option.
+ @param MenuItemCount The index for this Option in the Menu.
+
+ @retval Pointer Pointer to the added Menu Option.
+
+**/
+UI_MENU_OPTION *
+UiAddMenuOption (
+ IN CHAR16 *String,
+ IN EFI_HII_HANDLE Handle,
+ IN FORM_BROWSER_FORM *Form,
+ IN FORM_BROWSER_STATEMENT *Statement,
+ IN UINT16 NumberOfLines,
+ IN UINT16 MenuItemCount
+ )
+{
+ UI_MENU_OPTION *MenuOption;
+ UINTN Index;
+ UINTN Count;
+
+ Count = 1;
+ MenuOption = NULL;
+
+ if (Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) {
+ //
+ // Add three MenuOptions for Date/Time
+ // Data format : [01/02/2004] [11:22:33]
+ // Line number : 0 0 1 0 0 1
+ //
+ NumberOfLines = 0;
+ Count = 3;
+
+ if (Statement->Storage == NULL) {
+ //
+ // For RTC type of date/time, set default refresh interval to be 1 second
+ //
+ if (Statement->RefreshInterval == 0) {
+ Statement->RefreshInterval = 1;
+ }
+ }
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));
+ ASSERT (MenuOption);
+
+ MenuOption->Signature = UI_MENU_OPTION_SIGNATURE;
+ MenuOption->Description = String;
+ MenuOption->Handle = Handle;
+ MenuOption->ThisTag = Statement;
+ MenuOption->EntryNumber = MenuItemCount;
+
+ if (Index == 2) {
+ //
+ // Override LineNumber for the MenuOption in Date/Time sequence
+ //
+ MenuOption->Skip = 1;
+ } else {
+ MenuOption->Skip = NumberOfLines;
+ }
+ MenuOption->Sequence = Index;
+
+ if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut ) {
+ MenuOption->GrayOut = TRUE;
+ } else {
+ MenuOption->GrayOut = FALSE;
+ }
+
+ //
+ // If the form or the question has the lock attribute, deal same as grayout.
+ //
+ if (Form->Locked || Statement->Locked) {
+ MenuOption->GrayOut = TRUE;
+ }
+
+ switch (Statement->Operand) {
+ case EFI_IFR_ORDERED_LIST_OP:
+ case EFI_IFR_ONE_OF_OP:
+ case EFI_IFR_NUMERIC_OP:
+ case EFI_IFR_TIME_OP:
+ case EFI_IFR_DATE_OP:
+ case EFI_IFR_CHECKBOX_OP:
+ case EFI_IFR_PASSWORD_OP:
+ case EFI_IFR_STRING_OP:
+ //
+ // User could change the value of these items
+ //
+ MenuOption->IsQuestion = TRUE;
+ break;
+
+ case EFI_IFR_TEXT_OP:
+ if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {
+ //
+ // Initializing GrayOut option as TRUE for Text setup options
+ // so that those options will be Gray in colour and un selectable.
+ //
+ MenuOption->GrayOut = TRUE;
+ }
+ //
+ // break skipped on purpose
+ //
+ default:
+ MenuOption->IsQuestion = FALSE;
+ break;
+ }
+
+ if ((Statement->ValueExpression != NULL) ||
+ ((Statement->QuestionFlags & EFI_IFR_FLAG_READ_ONLY) != 0)) {
+ MenuOption->ReadOnly = TRUE;
+ if (FeaturePcdGet (PcdBrowerGrayOutReadOnlyMenu)) {
+ MenuOption->GrayOut = TRUE;
+ }
+ }
+
+ InsertTailList (&gMenuOption, &MenuOption->Link);
+ }
+
+ return MenuOption;
+}
+
+
+/**
+ Routine used to abstract a generic dialog interface and return the selected key or string
+
+ @param NumberOfLines The number of lines for the dialog box
+ @param HotKey Defines whether a single character is parsed
+ (TRUE) and returned in KeyValue or a string is
+ returned in StringBuffer. Two special characters
+ are considered when entering a string, a SCAN_ESC
+ and an CHAR_CARRIAGE_RETURN. SCAN_ESC terminates
+ string input and returns
+ @param MaximumStringSize The maximum size in bytes of a typed in string
+ (each character is a CHAR16) and the minimum
+ string returned is two bytes
+ @param StringBuffer The passed in pointer to the buffer which will
+ hold the typed in string if HotKey is FALSE
+ @param KeyValue The EFI_KEY value returned if HotKey is TRUE..
+ @param ... A series of (quantity == NumberOfLines) text
+ strings which will be used to construct the dialog
+ box
+
+ @retval EFI_SUCCESS Displayed dialog and received user interaction
+ @retval EFI_INVALID_PARAMETER One of the parameters was invalid (e.g.
+ (StringBuffer == NULL) && (HotKey == FALSE))
+ @retval EFI_DEVICE_ERROR User typed in an ESC character to exit the routine
+
+**/
+EFI_STATUS
+EFIAPI
+CreateDialog (
+ IN UINTN NumberOfLines,
+ IN BOOLEAN HotKey,
+ IN UINTN MaximumStringSize,
+ OUT CHAR16 *StringBuffer,
+ OUT EFI_INPUT_KEY *KeyValue,
+ ...
+ )
+{
+ VA_LIST Marker;
+ UINTN Count;
+ EFI_INPUT_KEY Key;
+ UINTN LargestString;
+ CHAR16 *TempString;
+ CHAR16 *BufferedString;
+ CHAR16 *StackString;
+ CHAR16 KeyPad[2];
+ UINTN Start;
+ UINTN Top;
+ UINTN Index;
+ EFI_STATUS Status;
+ BOOLEAN SelectionComplete;
+ UINTN InputOffset;
+ UINTN CurrentAttribute;
+ UINTN DimensionsWidth;
+ UINTN DimensionsHeight;
+
+ DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
+ DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;
+
+ SelectionComplete = FALSE;
+ InputOffset = 0;
+ TempString = AllocateZeroPool (MaximumStringSize * 2);
+ BufferedString = AllocateZeroPool (MaximumStringSize * 2);
+ CurrentAttribute = gST->ConOut->Mode->Attribute;
+
+ ASSERT (TempString);
+ ASSERT (BufferedString);
+
+ //
+ // Zero the outgoing buffer
+ //
+ ZeroMem (StringBuffer, MaximumStringSize);
+
+ if (HotKey) {
+ if (KeyValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ if (StringBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Disable cursor
+ //
+ gST->ConOut->EnableCursor (gST->ConOut, FALSE);
+
+ LargestString = 0;
+
+ VA_START (Marker, KeyValue);
+
+ //
+ // Determine the largest string in the dialog box
+ // Notice we are starting with 1 since String is the first string
+ //
+ for (Count = 0; Count < NumberOfLines; Count++) {
+ StackString = VA_ARG (Marker, CHAR16 *);
+
+ if (StackString[0] == L' ') {
+ InputOffset = Count + 1;
+ }
+
+ if ((GetStringWidth (StackString) / 2) > LargestString) {
+ //
+ // Size of the string visually and subtract the width by one for the null-terminator
+ //
+ LargestString = (GetStringWidth (StackString) / 2);
+ }
+ }
+ VA_END (Marker);
+
+ Start = (DimensionsWidth - LargestString - 2) / 2 + gScreenDimensions.LeftColumn + 1;
+ Top = ((DimensionsHeight - NumberOfLines - 2) / 2) + gScreenDimensions.TopRow - 1;
+
+ Count = 0;
+
+ //
+ // Display the Popup
+ //
+ VA_START (Marker, KeyValue);
+ CreateSharedPopUp (LargestString, NumberOfLines, Marker);
+ VA_END (Marker);
+
+ //
+ // Take the first key typed and report it back?
+ //
+ if (HotKey) {
+ Status = WaitForKeyStroke (&Key);
+ ASSERT_EFI_ERROR (Status);
+ CopyMem (KeyValue, &Key, sizeof (EFI_INPUT_KEY));
+
+ } else {
+ do {
+ Status = WaitForKeyStroke (&Key);
+
+ switch (Key.UnicodeChar) {
+ case CHAR_NULL:
+ switch (Key.ScanCode) {
+ case SCAN_ESC:
+ FreePool (TempString);
+ FreePool (BufferedString);
+ gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);
+ gST->ConOut->EnableCursor (gST->ConOut, TRUE);
+ return EFI_DEVICE_ERROR;
+
+ default:
+ break;
+ }
+
+ break;
+
+ case CHAR_CARRIAGE_RETURN:
+ SelectionComplete = TRUE;
+ FreePool (TempString);
+ FreePool (BufferedString);
+ gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);
+ gST->ConOut->EnableCursor (gST->ConOut, TRUE);
+ return EFI_SUCCESS;
+ break;
+
+ case CHAR_BACKSPACE:
+ if (StringBuffer[0] != CHAR_NULL) {
+ for (Index = 0; StringBuffer[Index] != CHAR_NULL; Index++) {
+ TempString[Index] = StringBuffer[Index];
+ }
+ //
+ // Effectively truncate string by 1 character
+ //
+ TempString[Index - 1] = CHAR_NULL;
+ StrCpy (StringBuffer, TempString);
+ }
+ //
+ // break skipped on purpose
+ //
+
+ default:
+ //
+ // If it is the beginning of the string, don't worry about checking maximum limits
+ //
+ if ((StringBuffer[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
+ StrnCpy (StringBuffer, &Key.UnicodeChar, 1);
+ StrnCpy (TempString, &Key.UnicodeChar, 1);
+ } else if ((GetStringWidth (StringBuffer) < MaximumStringSize) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
+ KeyPad[0] = Key.UnicodeChar;
+ KeyPad[1] = CHAR_NULL;
+ StrCat (StringBuffer, KeyPad);
+ StrCat (TempString, KeyPad);
+ }
+ //
+ // If the width of the input string is now larger than the screen, we nee to
+ // adjust the index to start printing portions of the string
+ //
+ SetUnicodeMem (BufferedString, LargestString, L' ');
+
+ PrintStringAt (Start + 1, Top + InputOffset, BufferedString);
+
+ if ((GetStringWidth (StringBuffer) / 2) > (DimensionsWidth - 2)) {
+ Index = (GetStringWidth (StringBuffer) / 2) - DimensionsWidth + 2;
+ } else {
+ Index = 0;
+ }
+
+ for (Count = 0; Index + 1 < GetStringWidth (StringBuffer) / 2; Index++, Count++) {
+ BufferedString[Count] = StringBuffer[Index];
+ }
+
+ PrintStringAt (Start + 1, Top + InputOffset, BufferedString);
+ break;
+ }
+ } while (!SelectionComplete);
+ }
+
+ gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);
+ gST->ConOut->EnableCursor (gST->ConOut, TRUE);
+ return EFI_SUCCESS;
+}
+
+/**
+ Draw a pop up windows based on the dimension, number of lines and
+ strings specified.
+
+ @param RequestedWidth The width of the pop-up.
+ @param NumberOfLines The number of lines.
+ @param Marker The variable argument list for the list of string to be printed.
+
+**/
+VOID
+CreateSharedPopUp (
+ IN UINTN RequestedWidth,
+ IN UINTN NumberOfLines,
+ IN VA_LIST Marker
+ )
+{
+ UINTN Index;
+ UINTN Count;
+ CHAR16 Character;
+ UINTN Start;
+ UINTN End;
+ UINTN Top;
+ UINTN Bottom;
+ CHAR16 *String;
+ UINTN DimensionsWidth;
+ UINTN DimensionsHeight;
+
+ DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
+ DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;
+
+ gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
+
+ if ((RequestedWidth + 2) > DimensionsWidth) {
+ RequestedWidth = DimensionsWidth - 2;
+ }
+
+ //
+ // Subtract the PopUp width from total Columns, allow for one space extra on
+ // each end plus a border.
+ //
+ Start = (DimensionsWidth - RequestedWidth - 2) / 2 + gScreenDimensions.LeftColumn + 1;
+ End = Start + RequestedWidth + 1;
+
+ Top = ((DimensionsHeight - NumberOfLines - 2) / 2) + gScreenDimensions.TopRow - 1;
+ Bottom = Top + NumberOfLines + 2;
+
+ Character = BOXDRAW_DOWN_RIGHT;
+ PrintCharAt (Start, Top, Character);
+ Character = BOXDRAW_HORIZONTAL;
+ for (Index = Start; Index + 2 < End; Index++) {
+ PrintChar (Character);
+ }
+
+ Character = BOXDRAW_DOWN_LEFT;
+ PrintChar (Character);
+ Character = BOXDRAW_VERTICAL;
+
+ Count = 0;
+ for (Index = Top; Index + 2 < Bottom; Index++, Count++) {
+ String = VA_ARG (Marker, CHAR16*);
+
+ //
+ // This will clear the background of the line - we never know who might have been
+ // here before us. This differs from the next clear in that it used the non-reverse
+ // video for normal printing.
+ //
+ if (GetStringWidth (String) / 2 > 1) {
+ ClearLines (Start, End, Index + 1, Index + 1, POPUP_TEXT | POPUP_BACKGROUND);
+ }
+
+ //
+ // Passing in a space results in the assumption that this is where typing will occur
+ //
+ if (String[0] == L' ') {
+ ClearLines (Start + 1, End - 1, Index + 1, Index + 1, POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND);
+ }
+
+ //
+ // Passing in a NULL results in a blank space
+ //
+ if (String[0] == CHAR_NULL) {
+ ClearLines (Start, End, Index + 1, Index + 1, POPUP_TEXT | POPUP_BACKGROUND);
+ }
+
+ PrintStringAt (
+ ((DimensionsWidth - GetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1,
+ Index + 1,
+ String
+ );
+ gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
+ PrintCharAt (Start, Index + 1, Character);
+ PrintCharAt (End - 1, Index + 1, Character);
+ }
+
+ Character = BOXDRAW_UP_RIGHT;
+ PrintCharAt (Start, Bottom - 1, Character);
+ Character = BOXDRAW_HORIZONTAL;
+ for (Index = Start; Index + 2 < End; Index++) {
+ PrintChar (Character);
+ }
+
+ Character = BOXDRAW_UP_LEFT;
+ PrintChar (Character);
+}
+
+/**
+ Draw a pop up windows based on the dimension, number of lines and
+ strings specified.
+
+ @param RequestedWidth The width of the pop-up.
+ @param NumberOfLines The number of lines.
+ @param ... A series of text strings that displayed in the pop-up.
+
+**/
+VOID
+EFIAPI
+CreateMultiStringPopUp (
+ IN UINTN RequestedWidth,
+ IN UINTN NumberOfLines,
+ ...
+ )
+{
+ VA_LIST Marker;
+
+ VA_START (Marker, NumberOfLines);
+
+ CreateSharedPopUp (RequestedWidth, NumberOfLines, Marker);
+
+ VA_END (Marker);
+}
+
+
+/**
+ Update status bar on the bottom of menu.
+
+ @param Selection Current Selction info.
+ @param MessageType The type of message to be shown.
+ @param Flags The flags in Question header.
+ @param State Set or clear.
+
+**/
+VOID
+UpdateStatusBar (
+ IN UI_MENU_SELECTION *Selection,
+ IN UINTN MessageType,
+ IN UINT8 Flags,
+ IN BOOLEAN State
+ )
+{
+ UINTN Index;
+ CHAR16 *NvUpdateMessage;
+ CHAR16 *InputErrorMessage;
+ LIST_ENTRY *Link;
+ FORM_BROWSER_FORMSET *LocalFormSet;
+ FORM_BROWSER_STATEMENT *Question;
+
+ NvUpdateMessage = GetToken (STRING_TOKEN (NV_UPDATE_MESSAGE), gHiiHandle);
+ InputErrorMessage = GetToken (STRING_TOKEN (INPUT_ERROR_MESSAGE), gHiiHandle);
+
+ switch (MessageType) {
+ case INPUT_ERROR:
+ if (State) {
+ gST->ConOut->SetAttribute (gST->ConOut, ERROR_TEXT);
+ PrintStringAt (
+ gScreenDimensions.LeftColumn + gPromptBlockWidth,
+ gScreenDimensions.BottomRow - 1,
+ InputErrorMessage
+ );
+ mInputError = TRUE;
+ } else {
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor));
+ for (Index = 0; Index < (GetStringWidth (InputErrorMessage) - 2) / 2; Index++) {
+ PrintAt (gScreenDimensions.LeftColumn + gPromptBlockWidth + Index, gScreenDimensions.BottomRow - 1, L" ");
+ }
+
+ mInputError = FALSE;
+ }
+ break;
+
+ case NV_UPDATE_REQUIRED:
+ //
+ // Global setting support. Show configuration change on every form.
+ //
+ if (State) {
+ gResetRequired = (BOOLEAN) (gResetRequired | ((Flags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED));
+
+ if (Selection != NULL && Selection->Statement != NULL) {
+ Question = Selection->Statement;
+ if (Question->Storage != NULL || Question->Operand == EFI_IFR_DATE_OP || Question->Operand == EFI_IFR_TIME_OP) {
+ //
+ // Update only for Question value that need to be saved into Storage.
+ //
+ Selection->Form->NvUpdateRequired = TRUE;
+ }
+ }
+
+ if (Selection == NULL || IsNvUpdateRequired (Selection->FormSet)) {
+ gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT);
+ PrintStringAt (
+ gScreenDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth,
+ gScreenDimensions.BottomRow - 1,
+ NvUpdateMessage
+ );
+ }
+ } else {
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor));
+ for (Index = 0; Index < (GetStringWidth (NvUpdateMessage) - 2) / 2; Index++) {
+ PrintAt (
+ (gScreenDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + Index),
+ gScreenDimensions.BottomRow - 1,
+ L" "
+ );
+ }
+ }
+ break;
+
+ case REFRESH_STATUS_BAR:
+ if (mInputError) {
+ UpdateStatusBar (Selection, INPUT_ERROR, Flags, TRUE);
+ }
+
+ switch (gBrowserSettingScope) {
+ case SystemLevel:
+ //
+ // Check the maintain list to see whether there is any change.
+ //
+ Link = GetFirstNode (&gBrowserFormSetList);
+ while (!IsNull (&gBrowserFormSetList, Link)) {
+ LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
+ if (IsNvUpdateRequired(LocalFormSet)) {
+ UpdateStatusBar (NULL, NV_UPDATE_REQUIRED, Flags, TRUE);
+ break;
+ }
+ Link = GetNextNode (&gBrowserFormSetList, Link);
+ }
+ break;
+ case FormSetLevel:
+ case FormLevel:
+ UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Flags, TRUE);
+ default:
+ break;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ FreePool (InputErrorMessage);
+ FreePool (NvUpdateMessage);
+ return ;
+}
+
+
+/**
+ Get the supported width for a particular op-code
+
+ @param Statement The FORM_BROWSER_STATEMENT structure passed in.
+ @param Handle The handle in the HII database being used
+
+ @return Returns the number of CHAR16 characters that is support.
+
+**/
+UINT16
+GetWidth (
+ IN FORM_BROWSER_STATEMENT *Statement,
+ IN EFI_HII_HANDLE Handle
+ )
+{
+ CHAR16 *String;
+ UINTN Size;
+ UINT16 Width;
+
+ Size = 0;
+
+ //
+ // See if the second text parameter is really NULL
+ //
+ if ((Statement->Operand == EFI_IFR_TEXT_OP) && (Statement->TextTwo != 0)) {
+ String = GetToken (Statement->TextTwo, Handle);
+ Size = StrLen (String);
+ FreePool (String);
+ }
+
+ if ((Statement->Operand == EFI_IFR_SUBTITLE_OP) ||
+ (Statement->Operand == EFI_IFR_REF_OP) ||
+ (Statement->Operand == EFI_IFR_PASSWORD_OP) ||
+ (Statement->Operand == EFI_IFR_ACTION_OP) ||
+ (Statement->Operand == EFI_IFR_RESET_BUTTON_OP) ||
+ //
+ // Allow a wide display if text op-code and no secondary text op-code
+ //
+ ((Statement->Operand == EFI_IFR_TEXT_OP) && (Size == 0))
+ ) {
+ Width = (UINT16) (gPromptBlockWidth + gOptionBlockWidth);
+ } else {
+ Width = (UINT16) gPromptBlockWidth;
+ }
+
+ if (Statement->InSubtitle) {
+ Width -= SUBTITLE_INDENT;
+ }
+
+ return (UINT16) (Width - LEFT_SKIPPED_COLUMNS);
+}
+
+/**
+ Will copy LineWidth amount of a string in the OutputString buffer and return the
+ number of CHAR16 characters that were copied into the OutputString buffer.
+ The output string format is:
+ Glyph Info + String info + '\0'.
+
+ In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.
+
+ @param InputString String description for this option.
+ @param LineWidth Width of the desired string to extract in CHAR16
+ characters
+ @param GlyphWidth The glyph width of the begin of the char in the string.
+ @param Index Where in InputString to start the copy process
+ @param OutputString Buffer to copy the string into
+
+ @return Returns the number of CHAR16 characters that were copied into the OutputString
+ buffer, include extra glyph info and '\0' info.
+
+**/
+UINT16
+GetLineByWidth (
+ IN CHAR16 *InputString,
+ IN UINT16 LineWidth,
+ IN OUT UINT16 *GlyphWidth,
+ IN OUT UINTN *Index,
+ OUT CHAR16 **OutputString
+ )
+{
+ UINT16 StrOffset;
+ UINT16 GlyphOffset;
+ UINT16 OriginalGlyphWidth;
+ BOOLEAN ReturnFlag;
+ UINT16 LastSpaceOffset;
+ UINT16 LastGlyphWidth;
+
+ if (InputString == NULL || Index == NULL || OutputString == NULL) {
+ return 0;
+ }
+
+ if (LineWidth == 0 || *GlyphWidth == 0) {
+ return 0;
+ }
+
+ //
+ // Save original glyph width.
+ //
+ OriginalGlyphWidth = *GlyphWidth;
+ LastGlyphWidth = OriginalGlyphWidth;
+ ReturnFlag = FALSE;
+ LastSpaceOffset = 0;
+
+ //
+ // NARROW_CHAR can not be printed in screen, so if a line only contain the two CHARs: 'NARROW_CHAR + CHAR_CARRIAGE_RETURN' , it is a empty line in Screen.
+ // To avoid displaying this empty line in screen, just skip the two CHARs here.
+ //
+ if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {
+ *Index = *Index + 2;
+ }
+
+ //
+ // Fast-forward the string and see if there is a carriage-return in the string
+ //
+ for (StrOffset = 0, GlyphOffset = 0; GlyphOffset <= LineWidth; StrOffset++) {
+ switch (InputString[*Index + StrOffset]) {
+ case NARROW_CHAR:
+ *GlyphWidth = 1;
+ break;
+
+ case WIDE_CHAR:
+ *GlyphWidth = 2;
+ break;
+
+ case CHAR_CARRIAGE_RETURN:
+ case CHAR_LINEFEED:
+ case CHAR_NULL:
+ ReturnFlag = TRUE;
+ break;
+
+ default:
+ GlyphOffset = GlyphOffset + *GlyphWidth;
+
+ //
+ // Record the last space info in this line. Will be used in rewind.
+ //
+ if ((InputString[*Index + StrOffset] == CHAR_SPACE) && (GlyphOffset <= LineWidth)) {
+ LastSpaceOffset = StrOffset;
+ LastGlyphWidth = *GlyphWidth;
+ }
+ break;
+ }
+
+ if (ReturnFlag) {
+ break;
+ }
+ }
+
+ //
+ // Rewind the string from the maximum size until we see a space to break the line
+ //
+ if (GlyphOffset > LineWidth) {
+ //
+ // Rewind the string to last space char in this line.
+ //
+ if (LastSpaceOffset != 0) {
+ StrOffset = LastSpaceOffset;
+ *GlyphWidth = LastGlyphWidth;
+ } else {
+ //
+ // Roll back to last char in the line width.
+ //
+ StrOffset--;
+ }
+ }
+
+ //
+ // The CHAR_NULL has process last time, this time just return 0 to stand for the end.
+ //
+ if (StrOffset == 0 && (InputString[*Index + StrOffset] == CHAR_NULL)) {
+ return 0;
+ }
+
+ //
+ // Need extra glyph info and '\0' info, so +2.
+ //
+ *OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));
+ if (*OutputString == NULL) {
+ return 0;
+ }
+
+ //
+ // Save the glyph info at the begin of the string, will used by Print function.
+ //
+ if (OriginalGlyphWidth == 1) {
+ *(*OutputString) = NARROW_CHAR;
+ } else {
+ *(*OutputString) = WIDE_CHAR;
+ }
+
+ CopyMem ((*OutputString) + 1, &InputString[*Index], StrOffset * sizeof(CHAR16));
+
+ if (InputString[*Index + StrOffset] == CHAR_SPACE) {
+ //
+ // Skip the space info at the begin of next line.
+ //
+ *Index = (UINT16) (*Index + StrOffset + 1);
+ } else if (InputString[*Index + StrOffset] == CHAR_LINEFEED) {
+ //
+ // Skip the /n or /n/r info.
+ //
+ if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {
+ *Index = (UINT16) (*Index + StrOffset + 2);
+ } else {
+ *Index = (UINT16) (*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 = (UINT16) (*Index + StrOffset + 2);
+ } else {
+ *Index = (UINT16) (*Index + StrOffset + 1);
+ }
+ } else {
+ *Index = (UINT16) (*Index + StrOffset);
+ }
+
+ //
+ // Include extra glyph info and '\0' info, so +2.
+ //
+ return StrOffset + 2;
+}
+
+
+/**
+ Update display lines for a Menu Option.
+
+ @param Selection The user's selection.
+ @param MenuOption The MenuOption to be checked.
+
+**/
+VOID
+UpdateOptionSkipLines (
+ IN UI_MENU_SELECTION *Selection,
+ IN UI_MENU_OPTION *MenuOption
+ )
+{
+ UINTN Index;
+ UINT16 Width;
+ UINTN Row;
+ UINTN OriginalRow;
+ CHAR16 *OutputString;
+ CHAR16 *OptionString;
+ UINT16 GlyphWidth;
+
+ Row = 0;
+ OptionString = NULL;
+ Width = (UINT16) gOptionBlockWidth;
+ OriginalRow = 0;
+ GlyphWidth = 1;
+
+ ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
+ if (OptionString == NULL) {
+ return;
+ }
+
+ for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&OptionString[Index]) != 0) {
+ Row++;
+ //
+ // Since the Number of lines for this menu entry may or may not be reflected accurately
+ // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
+ // some testing to ensure we are keeping this in-sync.
+ //
+ // If the difference in rows is greater than or equal to the skip value, increase the skip value
+ //
+ if ((Row - OriginalRow) >= MenuOption->Skip) {
+ MenuOption->Skip++;
+ }
+ }
+
+ FreePool (OutputString);
+ }
+
+ if (OptionString != NULL) {
+ FreePool (OptionString);
+ }
+}
+
+
+/**
+ Check whether this Menu Option could be highlighted.
+
+ This is an internal function.
+
+ @param MenuOption The MenuOption to be checked.
+
+ @retval TRUE This Menu Option is selectable.
+ @retval FALSE This Menu Option could not be selected.
+
+**/
+BOOLEAN
+IsSelectable (
+ UI_MENU_OPTION *MenuOption
+ )
+{
+ if ((MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP) ||
+ MenuOption->GrayOut || MenuOption->ReadOnly) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+
+/**
+ Determine if the menu is the last menu that can be selected.
+
+ This is an internal function.
+
+ @param Direction The scroll direction. False is down. True is up.
+ @param CurrentPos The current focus.
+
+ @return FALSE -- the menu isn't the last menu that can be selected.
+ @return TRUE -- the menu is the last menu that can be selected.
+
+**/
+BOOLEAN
+ValueIsScroll (
+ IN BOOLEAN Direction,
+ IN LIST_ENTRY *CurrentPos
+ )
+{
+ LIST_ENTRY *Temp;
+
+ Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;
+
+ if (Temp == &gMenuOption) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Move to next selectable statement.
+
+ This is an internal function.
+
+ @param Selection Menu selection.
+ @param GoUp The navigation direction. TRUE: up, FALSE: down.
+ @param CurrentPosition Current position.
+ @param GapToTop Gap position to top or bottom.
+
+ @return The row distance from current MenuOption to next selectable MenuOption.
+
+ @retval -1 Reach the begin of the menu, still can't find the selectable menu.
+ @retval Value Find the selectable menu, maybe the truly selectable, maybe the l
+ last menu showing at current form.
+
+**/
+INTN
+MoveToNextStatement (
+ IN UI_MENU_SELECTION *Selection,
+ IN BOOLEAN GoUp,
+ IN OUT LIST_ENTRY **CurrentPosition,
+ IN UINTN GapToTop
+ )
+{
+ INTN Distance;
+ LIST_ENTRY *Pos;
+ UI_MENU_OPTION *NextMenuOption;
+ UI_MENU_OPTION *PreMenuOption;
+
+ Distance = 0;
+ Pos = *CurrentPosition;
+ PreMenuOption = MENU_OPTION_FROM_LINK (Pos);
+
+ while (TRUE) {
+ NextMenuOption = MENU_OPTION_FROM_LINK (Pos);
+ //
+ // NextMenuOption->Row == 0 means this menu has not calculate
+ // the NextMenuOption->Skip value yet, just calculate here.
+ //
+ if (NextMenuOption->Row == 0) {
+ UpdateOptionSkipLines (Selection, NextMenuOption);
+ }
+
+ if (GoUp && (PreMenuOption != NextMenuOption)) {
+ //
+ // In this case, still can't find the selectable menu,
+ // return the last one in the showing form.
+ //
+ if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
+ NextMenuOption = PreMenuOption;
+ break;
+ }
+
+ //
+ // Current Position doesn't need to be caculated when go up.
+ // Caculate distanct at first when go up
+ //
+ Distance += NextMenuOption->Skip;
+ }
+
+ if (IsSelectable (NextMenuOption)) {
+ break;
+ }
+
+ //
+ // Arrive at begin of the menu list.
+ //
+ if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {
+ Distance = -1;
+ break;
+ }
+
+ if (!GoUp) {
+ //
+ // In this case, still can't find the selectable menu,
+ // return the last one in the showing form.
+ //
+ if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
+ NextMenuOption = PreMenuOption;
+ break;
+ }
+
+ Distance += NextMenuOption->Skip;
+ }
+
+ PreMenuOption = NextMenuOption;
+ Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);
+ }
+
+ *CurrentPosition = &NextMenuOption->Link;
+ return Distance;
+}
+
+
+/**
+ Adjust Data and Time position accordingly.
+ Data format : [01/02/2004] [11:22:33]
+ Line number : 0 0 1 0 0 1
+
+ This is an internal function.
+
+ @param DirectionUp the up or down direction. False is down. True is
+ up.
+ @param CurrentPosition Current position. On return: Point to the last
+ Option (Year or Second) if up; Point to the first
+ Option (Month or Hour) if down.
+
+ @return Return line number to pad. It is possible that we stand on a zero-advance
+ @return data or time opcode, so pad one line when we judge if we are going to scroll outside.
+
+**/
+UINTN
+AdjustDateAndTimePosition (
+ IN BOOLEAN DirectionUp,
+ IN OUT LIST_ENTRY **CurrentPosition
+ )
+{
+ UINTN Count;
+ LIST_ENTRY *NewPosition;
+ UI_MENU_OPTION *MenuOption;
+ UINTN PadLineNumber;
+
+ PadLineNumber = 0;
+ NewPosition = *CurrentPosition;
+ MenuOption = MENU_OPTION_FROM_LINK (NewPosition);
+
+ if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) ||
+ (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {
+ //
+ // Calculate the distance from current position to the last Date/Time MenuOption
+ //
+ Count = 0;
+ while (MenuOption->Skip == 0) {
+ Count++;
+ NewPosition = NewPosition->ForwardLink;
+ MenuOption = MENU_OPTION_FROM_LINK (NewPosition);
+ PadLineNumber = 1;
+ }
+
+ NewPosition = *CurrentPosition;
+ if (DirectionUp) {
+ //
+ // Since the behavior of hitting the up arrow on a Date/Time MenuOption is intended
+ // to be one that back to the previous set of MenuOptions, we need to advance to the first
+ // Date/Time MenuOption and leave the remaining logic in CfUiUp intact so the appropriate
+ // checking can be done.
+ //
+ while (Count++ < 2) {
+ NewPosition = NewPosition->BackLink;
+ }
+ } else {
+ //
+ // Since the behavior of hitting the down arrow on a Date/Time MenuOption is intended
+ // to be one that progresses to the next set of MenuOptions, we need to advance to the last
+ // Date/Time MenuOption and leave the remaining logic in CfUiDown intact so the appropriate
+ // checking can be done.
+ //
+ while (Count-- > 0) {
+ NewPosition = NewPosition->ForwardLink;
+ }
+ }
+
+ *CurrentPosition = NewPosition;
+ }
+
+ return PadLineNumber;
+}
+
+/**
+ Find HII Handle in the HII database associated with given Device Path.
+
+ If DevicePath is NULL, then ASSERT.
+
+ @param DevicePath Device Path associated with the HII package list
+ handle.
+
+ @retval Handle HII package list Handle associated with the Device
+ Path.
+ @retval NULL Hii Package list handle is not found.
+
+**/
+EFI_HII_HANDLE
+EFIAPI
+DevicePathToHiiHandle (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
+ UINTN BufferSize;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_HANDLE Handle;
+ EFI_HANDLE DriverHandle;
+ EFI_HII_HANDLE *HiiHandles;
+ EFI_HII_HANDLE HiiHandle;
+
+ ASSERT (DevicePath != NULL);
+
+ TmpDevicePath = DevicePath;
+ //
+ // Locate Device Path Protocol handle buffer
+ //
+ Status = gBS->LocateDevicePath (
+ &gEfiDevicePathProtocolGuid,
+ &TmpDevicePath,
+ &DriverHandle
+ );
+ if (EFI_ERROR (Status) || !IsDevicePathEnd (TmpDevicePath)) {
+ return NULL;
+ }
+
+ //
+ // Retrieve all HII Handles from HII database
+ //
+ BufferSize = 0x1000;
+ HiiHandles = AllocatePool (BufferSize);
+ ASSERT (HiiHandles != NULL);
+ Status = mHiiDatabase->ListPackageLists (
+ mHiiDatabase,
+ EFI_HII_PACKAGE_TYPE_ALL,
+ NULL,
+ &BufferSize,
+ HiiHandles
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (HiiHandles);
+ HiiHandles = AllocatePool (BufferSize);
+ ASSERT (HiiHandles != NULL);
+
+ Status = mHiiDatabase->ListPackageLists (
+ mHiiDatabase,
+ EFI_HII_PACKAGE_TYPE_ALL,
+ NULL,
+ &BufferSize,
+ HiiHandles
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ FreePool (HiiHandles);
+ return NULL;
+ }
+
+ //
+ // Search Hii Handle by Driver Handle
+ //
+ HiiHandle = NULL;
+ HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = mHiiDatabase->GetPackageListHandle (
+ mHiiDatabase,
+ HiiHandles[Index],
+ &Handle
+ );
+ if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
+ HiiHandle = HiiHandles[Index];
+ break;
+ }
+ }
+
+ FreePool (HiiHandles);
+ return HiiHandle;
+}
+
+/**
+ Find HII Handle in the HII database associated with given form set guid.
+
+ If FormSetGuid is NULL, then ASSERT.
+
+ @param ComparingGuid FormSet Guid associated with the HII package list
+ handle.
+
+ @retval Handle HII package list Handle associated with the Device
+ Path.
+ @retval NULL Hii Package list handle is not found.
+
+**/
+EFI_HII_HANDLE
+FormSetGuidToHiiHandle (
+ EFI_GUID *ComparingGuid
+ )
+{
+ EFI_HII_HANDLE *HiiHandles;
+ UINTN Index;
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
+ UINTN BufferSize;
+ UINT32 Offset;
+ UINT32 Offset2;
+ UINT32 PackageListLength;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ UINT8 *Package;
+ UINT8 *OpCodeData;
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+
+ ASSERT (ComparingGuid != NULL);
+
+ HiiHandle = NULL;
+ //
+ // Get all the Hii handles
+ //
+ HiiHandles = HiiGetHiiHandles (NULL);
+ ASSERT (HiiHandles != NULL);
+
+ //
+ // Search for formset of each class type
+ //
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {
+ BufferSize = 0;
+ HiiPackageList = NULL;
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ HiiPackageList = AllocatePool (BufferSize);
+ ASSERT (HiiPackageList != NULL);
+
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
+ }
+ if (EFI_ERROR (Status) || HiiPackageList == NULL) {
+ return NULL;
+ }
+
+ //
+ // Get Form package from this HII package List
+ //
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+ Offset2 = 0;
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
+
+ while (Offset < PackageListLength) {
+ Package = ((UINT8 *) HiiPackageList) + Offset;
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
+ //
+ // Search FormSet in this Form Package
+ //
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
+ while (Offset2 < PackageHeader.Length) {
+ OpCodeData = Package + Offset2;
+
+ if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
+ //
+ // Try to compare against formset GUID
+ //
+ if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
+ HiiHandle = HiiHandles[Index];
+ break;
+ }
+ }
+
+ Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
+ }
+ }
+ if (HiiHandle != NULL) {
+ break;
+ }
+ Offset += PackageHeader.Length;
+ }
+
+ FreePool (HiiPackageList);
+ if (HiiHandle != NULL) {
+ break;
+ }
+ }
+
+ FreePool (HiiHandles);
+
+ return HiiHandle;
+}
+
+/**
+ Process the goto op code, update the info in the selection structure.
+
+ @param Statement The statement belong to goto op code.
+ @param Selection The selection info.
+ @param Repaint Whether need to repaint the menu.
+ @param NewLine Whether need to create new line.
+
+ @retval EFI_SUCCESS The menu process successfully.
+ @return Other value if the process failed.
+**/
+EFI_STATUS
+ProcessGotoOpCode (
+ IN OUT FORM_BROWSER_STATEMENT *Statement,
+ IN OUT UI_MENU_SELECTION *Selection,
+ OUT BOOLEAN *Repaint,
+ OUT BOOLEAN *NewLine
+ )
+{
+ CHAR16 *StringPtr;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ FORM_BROWSER_FORM *RefForm;
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ StringPtr = NULL;
+
+ //
+ // Prepare the device path check, get the device path info first.
+ //
+ if (Statement->HiiValue.Value.ref.DevicePath != 0) {
+ StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);
+ }
+
+ //
+ // Check whether the device path string is a valid string.
+ //
+ if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL) {
+ if (Selection->Form->ModalForm) {
+ return Status;
+ }
+
+ //
+ // Goto another Hii Package list
+ //
+ if (mPathFromText != NULL) {
+ DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);
+ if (DevicePath != NULL) {
+ Selection->Handle = DevicePathToHiiHandle (DevicePath);
+ FreePool (DevicePath);
+ }
+ FreePool (StringPtr);
+ } else {
+ //
+ // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
+ //
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gProtocolNotFound, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ if (Repaint != NULL) {
+ *Repaint = TRUE;
+ }
+ FreePool (StringPtr);
+ return Status;
+ }
+
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;
+ if (Selection->Handle == NULL) {
+ //
+ // If target Hii Handle not found, exit
+ //
+ Selection->Action = UI_ACTION_EXIT;
+ Selection->Statement = NULL;
+ return Status;
+ }
+
+ CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
+ Selection->FormId = Statement->HiiValue.Value.ref.FormId;
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
+ } else if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {
+ if (Selection->Form->ModalForm) {
+ return Status;
+ }
+ //
+ // Goto another Formset, check for uncommitted data
+ //
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;
+
+ Selection->Handle = FormSetGuidToHiiHandle(&Statement->HiiValue.Value.ref.FormSetGuid);
+ if (Selection->Handle == NULL) {
+ //
+ // If target Hii Handle not found, exit
+ //
+ Selection->Action = UI_ACTION_EXIT;
+ Selection->Statement = NULL;
+ return Status;
+ }
+
+ CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
+ Selection->FormId = Statement->HiiValue.Value.ref.FormId;
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
+ } else if (Statement->HiiValue.Value.ref.FormId != 0) {
+ //
+ // Check whether target From is suppressed.
+ //
+ RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);
+
+ if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {
+ if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {
+ //
+ // Form is suppressed.
+ //
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ if (Repaint != NULL) {
+ *Repaint = TRUE;
+ }
+ return Status;
+ }
+ }
+
+ //
+ // Goto another form inside this formset,
+ //
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+
+ Selection->FormId = Statement->HiiValue.Value.ref.FormId;
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
+ } else if (Statement->HiiValue.Value.ref.QuestionId != 0) {
+ //
+ // Goto another Question
+ //
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
+
+ if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+ } else {
+ if (Repaint != NULL) {
+ *Repaint = TRUE;
+ }
+ if (NewLine != NULL) {
+ *NewLine = TRUE;
+ }
+ }
+ } else {
+ if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Display menu and wait for user to select one menu option, then return it.
+ If AutoBoot is enabled, then if user doesn't select any option,
+ after period of time, it will automatically return the first menu option.
+
+ @param Selection Menu selection.
+
+ @retval EFI_SUCESSS This function always return successfully for now.
+
+**/
+EFI_STATUS
+UiDisplayMenu (
+ IN OUT UI_MENU_SELECTION *Selection
+ )
+{
+ INTN SkipValue;
+ INTN Difference;
+ UINTN DistanceValue;
+ UINTN Row;
+ UINTN Col;
+ UINTN Temp;
+ UINTN Temp2;
+ UINTN TopRow;
+ UINTN BottomRow;
+ UINTN OriginalRow;
+ UINTN Index;
+ UINT16 Width;
+ CHAR16 *StringPtr;
+ CHAR16 *OptionString;
+ CHAR16 *OutputString;
+ CHAR16 *HelpString;
+ CHAR16 *HelpHeaderString;
+ CHAR16 *HelpBottomString;
+ BOOLEAN NewLine;
+ BOOLEAN Repaint;
+ BOOLEAN SavedValue;
+ BOOLEAN UpArrow;
+ BOOLEAN DownArrow;
+ BOOLEAN InitializedFlag;
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Key;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NewPos;
+ LIST_ENTRY *TopOfScreen;
+ LIST_ENTRY *SavedListEntry;
+ UI_MENU_OPTION *MenuOption;
+ UI_MENU_OPTION *NextMenuOption;
+ UI_MENU_OPTION *SavedMenuOption;
+ UI_MENU_OPTION *PreviousMenuOption;
+ UI_CONTROL_FLAG ControlFlag;
+ EFI_SCREEN_DESCRIPTOR LocalScreen;
+ MENU_REFRESH_ENTRY *MenuRefreshEntry;
+ MENU_REFRESH_ENTRY *MenuUpdateEntry;
+ UI_SCREEN_OPERATION ScreenOperation;
+ UINT8 MinRefreshInterval;
+ UINT16 DefaultId;
+ FORM_BROWSER_STATEMENT *Statement;
+ UI_MENU_LIST *CurrentMenu;
+ UINTN ModalSkipColumn;
+ BROWSER_HOT_KEY *HotKey;
+ UINTN HelpPageIndex;
+ UINTN HelpPageCount;
+ UINTN RowCount;
+ UINTN HelpLine;
+ UINTN HelpHeaderLine;
+ UINTN HelpBottomLine;
+ BOOLEAN MultiHelpPage;
+ UINT16 GlyphWidth;
+ UINT16 EachLineWidth;
+ UINT16 HeaderLineWidth;
+ UINT16 BottomLineWidth;
+
+ CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
+
+ Status = EFI_SUCCESS;
+ HelpString = NULL;
+ HelpHeaderString = NULL;
+ HelpBottomString = NULL;
+ OptionString = NULL;
+ ScreenOperation = UiNoOperation;
+ NewLine = TRUE;
+ MinRefreshInterval = 0;
+ DefaultId = 0;
+ HelpPageCount = 0;
+ HelpLine = 0;
+ RowCount = 0;
+ HelpBottomLine = 0;
+ HelpHeaderLine = 0;
+ HelpPageIndex = 0;
+ MultiHelpPage = FALSE;
+ EachLineWidth = 0;
+ HeaderLineWidth = 0;
+ BottomLineWidth = 0;
+ OutputString = NULL;
+ UpArrow = FALSE;
+ DownArrow = FALSE;
+ SkipValue = 0;
+ MenuRefreshEntry = gMenuRefreshHead;
+
+ NextMenuOption = NULL;
+ PreviousMenuOption = NULL;
+ SavedMenuOption = NULL;
+ HotKey = NULL;
+ ModalSkipColumn = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 6;
+
+ ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
+
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE){
+ TopRow = LocalScreen.TopRow + FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;
+ Row = LocalScreen.TopRow + FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;
+ } else {
+ TopRow = LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;
+ Row = LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;
+ }
+
+ if (Selection->Form->ModalForm) {
+ Col = LocalScreen.LeftColumn + LEFT_SKIPPED_COLUMNS + ModalSkipColumn;
+ } else {
+ Col = LocalScreen.LeftColumn + LEFT_SKIPPED_COLUMNS;
+ }
+
+ BottomRow = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight - SCROLL_ARROW_HEIGHT - 1;
+
+ Selection->TopRow = TopRow;
+ Selection->BottomRow = BottomRow;
+ Selection->PromptCol = Col;
+ Selection->OptionCol = gPromptBlockWidth + 1 + LocalScreen.LeftColumn;
+ Selection->Statement = NULL;
+
+ TopOfScreen = gMenuOption.ForwardLink;
+ Repaint = TRUE;
+ MenuOption = NULL;
+
+ //
+ // Find current Menu
+ //
+ CurrentMenu = UiFindMenuList (Selection->Handle, &Selection->FormSetGuid, Selection->FormId);
+ if (CurrentMenu == NULL) {
+ //
+ // Current menu not found, add it to the menu tree
+ //
+ CurrentMenu = UiAddMenuList (Selection->CurrentMenu, Selection->Handle, &Selection->FormSetGuid, Selection->FormId);
+ }
+ ASSERT (CurrentMenu != NULL);
+ Selection->CurrentMenu = CurrentMenu;
+
+ if (Selection->QuestionId == 0) {
+ //
+ // Highlight not specified, fetch it from cached menu
+ //
+ Selection->QuestionId = CurrentMenu->QuestionId;
+ Selection->Sequence = CurrentMenu->Sequence;
+ }
+
+ //
+ // Init option as the current user's selection
+ //
+ InitializedFlag = TRUE;
+ NewPos = gMenuOption.ForwardLink;
+
+ gST->ConOut->EnableCursor (gST->ConOut, FALSE);
+ UpdateStatusBar (Selection, REFRESH_STATUS_BAR, (UINT8) 0, TRUE);
+
+ ControlFlag = CfInitialization;
+ Selection->Action = UI_ACTION_NONE;
+ while (TRUE) {
+ switch (ControlFlag) {
+ case CfInitialization:
+ if (IsListEmpty (&gMenuOption)) {
+ ControlFlag = CfReadKey;
+ } else {
+ ControlFlag = CfCheckSelection;
+ }
+ break;
+
+ case CfCheckSelection:
+ if (Selection->Action != UI_ACTION_NONE) {
+ ControlFlag = CfExit;
+ } else {
+ ControlFlag = CfRepaint;
+ }
+ break;
+
+ case CfRepaint:
+ ControlFlag = CfRefreshHighLight;
+
+ if (Repaint) {
+ //
+ // Display menu
+ //
+ DownArrow = FALSE;
+ UpArrow = FALSE;
+ Row = TopRow;
+
+ Temp = (UINTN) SkipValue;
+ Temp2 = (UINTN) SkipValue;
+
+ //
+ // 1. Clear the screen.
+ //
+ if (Selection->Form->ModalForm) {
+ ClearLines (
+ LocalScreen.LeftColumn + ModalSkipColumn,
+ LocalScreen.LeftColumn + ModalSkipColumn + gPromptBlockWidth + gOptionBlockWidth,
+ TopRow - SCROLL_ARROW_HEIGHT,
+ BottomRow + SCROLL_ARROW_HEIGHT,
+ PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND
+ );
+ } else {
+ ClearLines (
+ LocalScreen.LeftColumn,
+ LocalScreen.RightColumn,
+ TopRow - SCROLL_ARROW_HEIGHT,
+ BottomRow + SCROLL_ARROW_HEIGHT,
+ PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND
+ );
+ }
+ UiFreeRefreshList ();
+ MinRefreshInterval = 0;
+
+ //
+ // 2.Paint the menu.
+ //
+ for (Link = TopOfScreen; Link != &gMenuOption; Link = Link->ForwardLink) {
+ MenuOption = MENU_OPTION_FROM_LINK (Link);
+ MenuOption->Row = Row;
+ MenuOption->Col = Col;
+ if (Selection->Form->ModalForm) {
+ MenuOption->OptCol = gPromptBlockWidth + 1 + LocalScreen.LeftColumn + ModalSkipColumn;
+ } else {
+ MenuOption->OptCol = gPromptBlockWidth + 1 + LocalScreen.LeftColumn;
+ }
+
+ Statement = MenuOption->ThisTag;
+ if (Statement->InSubtitle) {
+ MenuOption->Col += SUBTITLE_INDENT;
+ }
+
+ if (MenuOption->GrayOut) {
+ gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | FIELD_BACKGROUND);
+ } else {
+ if (Statement->Operand == EFI_IFR_SUBTITLE_OP) {
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserSubtitleTextColor) | FIELD_BACKGROUND);
+ }
+ }
+
+ Width = GetWidth (Statement, MenuOption->Handle);
+ OriginalRow = Row;
+ GlyphWidth = 1;
+
+ if (Statement->Operand == EFI_IFR_REF_OP && MenuOption->Col >= 2) {
+ //
+ // Print Arrow for Goto button.
+ //
+ PrintAt (
+ MenuOption->Col - 2,
+ Row,
+ L"%c",
+ GEOMETRICSHAPE_RIGHT_TRIANGLE
+ );
+ }
+
+ //
+ // 2.1. Paint the description.
+ //
+ for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ //
+ // Temp means need to skip how many lines from the start.
+ //
+ if ((Temp == 0) && (Row <= BottomRow)) {
+ PrintStringAt (MenuOption->Col, Row, OutputString);
+ }
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&MenuOption->Description[Index]) != 0) {
+ if (Temp == 0) {
+ Row++;
+ }
+ }
+
+ FreePool (OutputString);
+ if (Temp != 0) {
+ Temp--;
+ }
+ }
+
+ Temp = 0;
+ Row = OriginalRow;
+
+ //
+ // 2.2. Paint the option string.
+ //
+ Status = ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
+ if (EFI_ERROR (Status)) {
+ //
+ // Repaint to clear possible error prompt pop-up
+ //
+ Repaint = TRUE;
+ NewLine = TRUE;
+ ControlFlag = CfRepaint;
+ break;
+ }
+
+ if (OptionString != NULL) {
+ if (Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) {
+ ProcessStringForDateTime(MenuOption, OptionString, TRUE);
+ }
+
+ Width = (UINT16) gOptionBlockWidth;
+ OriginalRow = Row;
+ GlyphWidth = 1;
+
+ for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ if ((Temp2 == 0) && (Row <= BottomRow)) {
+ PrintStringAt (MenuOption->OptCol, Row, OutputString);
+ }
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&OptionString[Index]) != 0) {
+ if (Temp2 == 0) {
+ Row++;
+ //
+ // Since the Number of lines for this menu entry may or may not be reflected accurately
+ // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
+ // some testing to ensure we are keeping this in-sync.
+ //
+ // If the difference in rows is greater than or equal to the skip value, increase the skip value
+ //
+ if ((Row - OriginalRow) >= MenuOption->Skip) {
+ MenuOption->Skip++;
+ }
+ }
+ }
+
+ FreePool (OutputString);
+ if (Temp2 != 0) {
+ Temp2--;
+ }
+ }
+
+ Temp2 = 0;
+ Row = OriginalRow;
+
+ FreePool (OptionString);
+ }
+
+ //
+ // 2.4 Special process for Test opcode with test two.
+ //
+ if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {
+ if (gMenuEventGuidRefreshHead == NULL) {
+ MenuUpdateEntry = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));
+ gMenuEventGuidRefreshHead = MenuUpdateEntry;
+ } else {
+ MenuUpdateEntry = gMenuEventGuidRefreshHead;
+ while (MenuUpdateEntry->Next != NULL) {
+ MenuUpdateEntry = MenuUpdateEntry->Next;
+ }
+ MenuUpdateEntry->Next = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));
+ MenuUpdateEntry = MenuUpdateEntry->Next;
+ }
+ ASSERT (MenuUpdateEntry != NULL);
+ Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, RefreshQuestionNotify, MenuUpdateEntry, &Statement->RefreshGuid, &MenuUpdateEntry->Event);
+ ASSERT (!EFI_ERROR (Status));
+ MenuUpdateEntry->MenuOption = MenuOption;
+ MenuUpdateEntry->Selection = Selection;
+ MenuUpdateEntry->CurrentColumn = MenuOption->OptCol;
+ MenuUpdateEntry->CurrentRow = MenuOption->Row;
+ if (MenuOption->GrayOut) {
+ MenuUpdateEntry->CurrentAttribute = FIELD_TEXT_GRAYED | FIELD_BACKGROUND;
+ } else {
+ MenuUpdateEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;
+ }
+ }
+
+ //
+ // If Question request refresh, register the op-code
+ //
+ if (Statement->RefreshInterval != 0) {
+ //
+ // Menu will be refreshed at minimal interval of all Questions
+ // which have refresh request
+ //
+ if (MinRefreshInterval == 0 || Statement->RefreshInterval < MinRefreshInterval) {
+ MinRefreshInterval = Statement->RefreshInterval;
+ }
+
+ if (gMenuRefreshHead == NULL) {
+ MenuRefreshEntry = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));
+ gMenuRefreshHead = MenuRefreshEntry;
+ } else {
+ MenuRefreshEntry = gMenuRefreshHead;
+ while (MenuRefreshEntry->Next != NULL) {
+ MenuRefreshEntry = MenuRefreshEntry->Next;
+ }
+ MenuRefreshEntry->Next = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));
+ MenuRefreshEntry = MenuRefreshEntry->Next;
+ }
+ ASSERT (MenuRefreshEntry != NULL);
+ MenuRefreshEntry->MenuOption = MenuOption;
+ MenuRefreshEntry->Selection = Selection;
+ MenuRefreshEntry->CurrentColumn = MenuOption->OptCol;
+ MenuRefreshEntry->CurrentRow = MenuOption->Row;
+ if (MenuOption->GrayOut) {
+ MenuRefreshEntry->CurrentAttribute = FIELD_TEXT_GRAYED | FIELD_BACKGROUND;
+ } else {
+ MenuRefreshEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;
+ }
+ }
+
+ //
+ // If this is a text op with secondary text information
+ //
+ if ((Statement->Operand == EFI_IFR_TEXT_OP) && (Statement->TextTwo != 0)) {
+ StringPtr = GetToken (Statement->TextTwo, MenuOption->Handle);
+
+ Width = (UINT16) gOptionBlockWidth;
+ OriginalRow = Row;
+ GlyphWidth = 1;
+
+ for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ if ((Temp == 0) && (Row <= BottomRow)) {
+ PrintStringAt (MenuOption->OptCol, Row, OutputString);
+ }
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&StringPtr[Index]) != 0) {
+ if (Temp2 == 0) {
+ Row++;
+ //
+ // Since the Number of lines for this menu entry may or may not be reflected accurately
+ // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
+ // some testing to ensure we are keeping this in-sync.
+ //
+ // If the difference in rows is greater than or equal to the skip value, increase the skip value
+ //
+ if ((Row - OriginalRow) >= MenuOption->Skip) {
+ MenuOption->Skip++;
+ }
+ }
+ }
+
+ FreePool (OutputString);
+ if (Temp2 != 0) {
+ Temp2--;
+ }
+ }
+
+ Row = OriginalRow;
+ FreePool (StringPtr);
+ }
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
+
+ //
+ // 3. Update the row info which will be used by next menu.
+ //
+ if (Link == TopOfScreen) {
+ Row += MenuOption->Skip - SkipValue;
+ } else {
+ Row += MenuOption->Skip;
+ }
+
+ if (Row > BottomRow) {
+ if (!ValueIsScroll (FALSE, Link)) {
+ DownArrow = TRUE;
+ }
+
+ Row = BottomRow + 1;
+ break;
+ }
+ }
+
+ if (!ValueIsScroll (TRUE, TopOfScreen)) {
+ UpArrow = TRUE;
+ }
+
+ if (UpArrow) {
+ gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);
+ PrintAt (
+ LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
+ TopRow - SCROLL_ARROW_HEIGHT,
+ L"%c",
+ ARROW_UP
+ );
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
+ }
+
+ if (DownArrow) {
+ gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);
+ PrintAt (
+ LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
+ BottomRow + SCROLL_ARROW_HEIGHT,
+ L"%c",
+ ARROW_DOWN
+ );
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
+ }
+
+ MenuOption = NULL;
+ }
+ break;
+
+ case CfRefreshHighLight:
+ //
+ // MenuOption: Last menu option that need to remove hilight
+ // MenuOption is set to NULL in Repaint
+ // NewPos: Current menu option that need to hilight
+ //
+ ControlFlag = CfUpdateHelpString;
+ if (TopOfScreen == &MenuOption->Link) {
+ Temp = SkipValue;
+ } else {
+ Temp = 0;
+ }
+ if (NewPos == TopOfScreen) {
+ Temp2 = SkipValue;
+ } else {
+ Temp2 = 0;
+ }
+ if (InitializedFlag) {
+ InitializedFlag = FALSE;
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
+ }
+
+ //
+ // Repaint flag is normally reset when finish processing CfUpdateHelpString. Temporarily
+ // reset Repaint flag because we may break halfway and skip CfUpdateHelpString processing.
+ //
+ SavedValue = Repaint;
+ Repaint = FALSE;
+
+ if (Selection->QuestionId != 0) {
+ NewPos = gMenuOption.ForwardLink;
+ SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+
+ while ((SavedMenuOption->ThisTag->QuestionId != Selection->QuestionId ||
+ SavedMenuOption->Sequence != Selection->Sequence) &&
+ NewPos->ForwardLink != &gMenuOption) {
+ NewPos = NewPos->ForwardLink;
+ SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ }
+ if (SavedMenuOption->ThisTag->QuestionId == Selection->QuestionId) {
+ //
+ // Target Question found, find its MenuOption
+ //
+ Link = TopOfScreen;
+
+ for (Index = TopRow; Index <= BottomRow && Link != NewPos;) {
+ SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
+ Index += SavedMenuOption->Skip;
+ if (Link == TopOfScreen) {
+ Index -= SkipValue;
+ }
+ Link = Link->ForwardLink;
+ }
+ if (NewPos == Link) {
+ SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
+ }
+
+ //
+ // Not find the selected menu in current show page.
+ // Have two case to enter this if:
+ // 1. Not find the menu at current page.
+ // 2. Find the menu in current page, but the menu shows at the bottom and not all info shows.
+ // For case 2, has an exception: The menu can show more than one pages and now only this menu shows.
+ //
+ // Base on the selected menu will show at the bottom of the page,
+ // select the menu which will show at the top of the page.
+ //
+ if (Link != NewPos || Index > BottomRow ||
+ (Link == NewPos && (SavedMenuOption->Row + SavedMenuOption->Skip - 1 > BottomRow) && (Link != TopOfScreen))) {
+ //
+ // Find the MenuOption which has the skip value for Date/Time opcode.
+ //
+ AdjustDateAndTimePosition(FALSE, &NewPos);
+ //
+ // NewPos is not in the current page, simply scroll page so that NewPos is in the end of the page
+ //
+ SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ //
+ // SavedMenuOption->Row == 0 means the menu not show yet.
+ //
+ if (SavedMenuOption->Row == 0) {
+ UpdateOptionSkipLines (Selection, SavedMenuOption);
+ }
+
+ //
+ // Base on the selected menu will show at the bottome of next page,
+ // select the menu show at the top of the next page.
+ //
+ Link = NewPos;
+ for (Index = TopRow + SavedMenuOption->Skip; Index <= BottomRow + 1; ) {
+ Link = Link->BackLink;
+ SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
+ if (SavedMenuOption->Row == 0) {
+ UpdateOptionSkipLines (Selection, SavedMenuOption);
+ }
+ Index += SavedMenuOption->Skip;
+ }
+
+ //
+ // Found the menu which will show at the top of the page.
+ //
+ if (Link == NewPos) {
+ //
+ // The menu can show more than one pages, just show the menu at the top of the page.
+ //
+ SkipValue = 0;
+ TopOfScreen = Link;
+ } else {
+ //
+ // Check whether need to skip some line for menu shows at the top of the page.
+ //
+ SkipValue = Index - BottomRow - 1;
+ if (SkipValue > 0 && SkipValue < (INTN) SavedMenuOption->Skip) {
+ TopOfScreen = Link;
+ } else {
+ SkipValue = 0;
+ TopOfScreen = Link->ForwardLink;
+ }
+ }
+
+ Repaint = TRUE;
+ NewLine = TRUE;
+ ControlFlag = CfRepaint;
+ break;
+ }
+ } else {
+ //
+ // Target Question not found, highlight the default menu option
+ //
+ NewPos = TopOfScreen;
+ }
+
+ Selection->QuestionId = 0;
+ }
+
+ if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {
+ if (MenuOption != NULL) {
+ //
+ // Remove highlight on last Menu Option
+ //
+ gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
+ ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
+ if (OptionString != NULL) {
+ if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) ||
+ (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)
+ ) {
+ ProcessStringForDateTime(MenuOption, OptionString, FALSE);
+ }
+
+ Width = (UINT16) gOptionBlockWidth;
+ OriginalRow = MenuOption->Row;
+ GlyphWidth = 1;
+
+ for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
+ PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
+ }
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&OptionString[Index]) != 0) {
+ if (Temp == 0) {
+ MenuOption->Row++;
+ }
+ }
+
+ FreePool (OutputString);
+ if (Temp != 0) {
+ Temp--;
+ }
+ }
+
+ MenuOption->Row = OriginalRow;
+
+ FreePool (OptionString);
+ } else {
+ if (NewLine) {
+ if (MenuOption->GrayOut) {
+ gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | FIELD_BACKGROUND);
+ } else if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP) {
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserSubtitleTextColor) | FIELD_BACKGROUND);
+ }
+
+ OriginalRow = MenuOption->Row;
+ Width = GetWidth (MenuOption->ThisTag, MenuOption->Handle);
+ GlyphWidth = 1;
+
+ for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
+ PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
+ }
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&MenuOption->Description[Index]) != 0) {
+ if (Temp == 0) {
+ MenuOption->Row++;
+ }
+ }
+
+ FreePool (OutputString);
+ if (Temp != 0) {
+ Temp--;
+ }
+ }
+
+ MenuOption->Row = OriginalRow;
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
+ }
+ }
+ }
+
+ //
+ // This is the current selected statement
+ //
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ Statement = MenuOption->ThisTag;
+ Selection->Statement = Statement;
+ if (!IsSelectable (MenuOption)) {
+ Repaint = SavedValue;
+ UpdateKeyHelp (Selection, MenuOption, FALSE);
+ break;
+ }
+
+ //
+ // Record highlight for current menu
+ //
+ CurrentMenu->QuestionId = Statement->QuestionId;
+ CurrentMenu->Sequence = MenuOption->Sequence;
+
+ //
+ // Set reverse attribute
+ //
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor));
+ gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
+
+ //
+ // Assuming that we have a refresh linked-list created, lets annotate the
+ // appropriate entry that we are highlighting with its new attribute. Just prior to this
+ // lets reset all of the entries' attribute so we do not get multiple highlights in he refresh
+ //
+ if (gMenuRefreshHead != NULL) {
+ for (MenuRefreshEntry = gMenuRefreshHead; MenuRefreshEntry != NULL; MenuRefreshEntry = MenuRefreshEntry->Next) {
+ if (MenuRefreshEntry->MenuOption->GrayOut) {
+ MenuRefreshEntry->CurrentAttribute = FIELD_TEXT_GRAYED | FIELD_BACKGROUND;
+ } else {
+ MenuRefreshEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;
+ }
+ if (MenuRefreshEntry->MenuOption == MenuOption) {
+ MenuRefreshEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor);
+ }
+ }
+ }
+
+ ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
+ if (OptionString != NULL) {
+ if (Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) {
+ ProcessStringForDateTime(MenuOption, OptionString, FALSE);
+ }
+ Width = (UINT16) gOptionBlockWidth;
+
+ OriginalRow = MenuOption->Row;
+ GlyphWidth = 1;
+
+ for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
+ PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
+ }
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&OptionString[Index]) != 0) {
+ if (Temp2 == 0) {
+ MenuOption->Row++;
+ }
+ }
+
+ FreePool (OutputString);
+ if (Temp2 != 0) {
+ Temp2--;
+ }
+ }
+
+ MenuOption->Row = OriginalRow;
+
+ FreePool (OptionString);
+ } else {
+ if (NewLine) {
+ OriginalRow = MenuOption->Row;
+
+ Width = GetWidth (Statement, MenuOption->Handle);
+ GlyphWidth = 1;
+
+ for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
+ PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
+ }
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&MenuOption->Description[Index]) != 0) {
+ if (Temp2 == 0) {
+ MenuOption->Row++;
+ }
+ }
+
+ FreePool (OutputString);
+ if (Temp2 != 0) {
+ Temp2--;
+ }
+ }
+
+ MenuOption->Row = OriginalRow;
+
+ }
+ }
+
+ UpdateKeyHelp (Selection, MenuOption, FALSE);
+
+ //
+ // Clear reverse attribute
+ //
+ gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
+ }
+ //
+ // Repaint flag will be used when process CfUpdateHelpString, so restore its value
+ // if we didn't break halfway when process CfRefreshHighLight.
+ //
+ Repaint = SavedValue;
+ break;
+
+ case CfUpdateHelpString:
+ ControlFlag = CfPrepareToReadKey;
+ if (Selection->Form->ModalForm) {
+ break;
+ }
+
+ if (Repaint || NewLine) {
+ //
+ // Don't print anything if it is a NULL help token
+ //
+ ASSERT(MenuOption != NULL);
+ if (MenuOption->ThisTag->Help == 0 || !IsSelectable (MenuOption)) {
+ StringPtr = L"\0";
+ } else {
+ StringPtr = GetToken (MenuOption->ThisTag->Help, MenuOption->Handle);
+ }
+
+ RowCount = BottomRow - TopRow;
+ HelpPageIndex = 0;
+ //
+ // 1.Calculate how many line the help string need to print.
+ //
+ if (HelpString != NULL) {
+ FreePool (HelpString);
+ }
+ HelpLine = ProcessHelpString (StringPtr, &HelpString, &EachLineWidth, RowCount);
+ if (HelpLine > RowCount) {
+ MultiHelpPage = TRUE;
+ StringPtr = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_UP), gHiiHandle);
+ if (HelpHeaderString != NULL) {
+ FreePool (HelpHeaderString);
+ }
+ HelpHeaderLine = ProcessHelpString (StringPtr, &HelpHeaderString, &HeaderLineWidth, RowCount);
+ StringPtr = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_DOWN), gHiiHandle);
+ if (HelpBottomString != NULL) {
+ FreePool (HelpBottomString);
+ }
+ HelpBottomLine = ProcessHelpString (StringPtr, &HelpBottomString, &BottomLineWidth, RowCount);
+ //
+ // Calculate the help page count.
+ //
+ if (HelpLine > 2 * RowCount - 2) {
+ HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;
+ if ((HelpLine - RowCount + 1) % (RowCount - 2) > 1) {
+ HelpPageCount += 1;
+ }
+ } else {
+ HelpPageCount = 2;
+ }
+ } else {
+ MultiHelpPage = FALSE;
+ }
+ }
+
+ //
+ // Clean the help field first.
+ //
+ ClearLines (
+ LocalScreen.RightColumn - gHelpBlockWidth,
+ LocalScreen.RightColumn,
+ TopRow,
+ BottomRow,
+ PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND
+ );
+
+ //
+ // Check whether need to show the 'More(U/u)' at the begin.
+ // Base on current direct info, here shows aligned to the right side of the column.
+ // If the direction is multi line and aligned to right side may have problem, so
+ // add ASSERT code here.
+ //
+ if (HelpPageIndex > 0) {
+ gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT | FIELD_BACKGROUND);
+ for (Index = 0; Index < HelpHeaderLine; Index++) {
+ ASSERT (HelpHeaderLine == 1);
+ ASSERT (GetStringWidth (HelpHeaderString) / 2 < (UINTN) (gHelpBlockWidth - 1));
+ PrintStringAt (
+ LocalScreen.RightColumn - GetStringWidth (HelpHeaderString) / 2 - 1,
+ Index + TopRow,
+ &HelpHeaderString[Index * HeaderLineWidth]
+ );
+ }
+ }
+
+ gST->ConOut->SetAttribute (gST->ConOut, HELP_TEXT | FIELD_BACKGROUND);
+ //
+ // Print the help string info.
+ //
+ if (!MultiHelpPage) {
+ for (Index = 0; Index < HelpLine; Index++) {
+ PrintStringAt (
+ LocalScreen.RightColumn - gHelpBlockWidth,
+ Index + TopRow,
+ &HelpString[Index * EachLineWidth]
+ );
+ }
+ gST->ConOut->SetCursorPosition(gST->ConOut, LocalScreen.RightColumn-1, BottomRow);
+ } else {
+ if (HelpPageIndex == 0) {
+ for (Index = 0; Index < RowCount - HelpBottomLine; Index++) {
+ PrintStringAt (
+ LocalScreen.RightColumn - gHelpBlockWidth,
+ Index + TopRow,
+ &HelpString[Index * EachLineWidth]
+ );
+ }
+ } else {
+ for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) &&
+ (Index + HelpPageIndex * (RowCount - 2) + 1 < HelpLine); Index++) {
+ PrintStringAt (
+ LocalScreen.RightColumn - gHelpBlockWidth,
+ Index + TopRow + HelpHeaderLine,
+ &HelpString[(Index + HelpPageIndex * (RowCount - 2) + 1)* EachLineWidth]
+ );
+ }
+ if (HelpPageIndex == HelpPageCount - 1) {
+ gST->ConOut->SetCursorPosition(gST->ConOut, LocalScreen.RightColumn-1, BottomRow);
+ }
+ }
+ }
+
+ //
+ // Check whether need to print the 'More(D/d)' at the bottom.
+ // Base on current direct info, here shows aligned to the right side of the column.
+ // If the direction is multi line and aligned to right side may have problem, so
+ // add ASSERT code here.
+ //
+ if (HelpPageIndex < HelpPageCount - 1 && MultiHelpPage) {
+ gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT | FIELD_BACKGROUND);
+ for (Index = 0; Index < HelpBottomLine; Index++) {
+ ASSERT (HelpBottomLine == 1);
+ ASSERT (GetStringWidth (HelpBottomString) / 2 < (UINTN) (gHelpBlockWidth - 1));
+ PrintStringAt (
+ LocalScreen.RightColumn - GetStringWidth (HelpBottomString) / 2 - 1,
+ Index + BottomRow - HelpBottomLine,
+ &HelpBottomString[Index * BottomLineWidth]
+ );
+ }
+ }
+ //
+ // Reset this flag every time we finish using it.
+ //
+ Repaint = FALSE;
+ NewLine = FALSE;
+ break;
+
+ case CfPrepareToReadKey:
+ ControlFlag = CfReadKey;
+ ScreenOperation = UiNoOperation;
+ break;
+
+ case CfReadKey:
+ ControlFlag = CfScreenOperation;
+
+ //
+ // Wait for user's selection
+ //
+ while (TRUE) {
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+
+ //
+ // If we encounter error, continue to read another key in.
+ //
+ if (Status != EFI_NOT_READY) {
+ continue;
+ }
+
+ Status = UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0, MinRefreshInterval);
+ ASSERT_EFI_ERROR (Status);
+
+ if (Selection->Action == UI_ACTION_REFRESH_FORMSET) {
+ //
+ // IFR is updated in Callback of refresh opcode, re-parse it
+ //
+ ControlFlag = CfCheckSelection;
+ Selection->Statement = NULL;
+ break;
+ }
+ }
+
+ if (ControlFlag == CfCheckSelection) {
+ break;
+ }
+
+ switch (Key.UnicodeChar) {
+ case CHAR_CARRIAGE_RETURN:
+ if(MenuOption->GrayOut || MenuOption->ReadOnly) {
+ ControlFlag = CfReadKey;
+ break;
+ }
+
+ ScreenOperation = UiSelect;
+ gDirection = 0;
+ break;
+
+ //
+ // We will push the adjustment of these numeric values directly to the input handler
+ // NOTE: we won't handle manual input numeric
+ //
+ case '+':
+ case '-':
+ //
+ // If the screen has no menu items, and the user didn't select UiReset
+ // ignore the selection and go back to reading keys.
+ //
+ if(IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) {
+ ControlFlag = CfReadKey;
+ break;
+ }
+
+ ASSERT(MenuOption != NULL);
+ Statement = MenuOption->ThisTag;
+ if ((Statement->Operand == EFI_IFR_DATE_OP)
+ || (Statement->Operand == EFI_IFR_TIME_OP)
+ || ((Statement->Operand == EFI_IFR_NUMERIC_OP) && (Statement->Step != 0))
+ ){
+ if (Key.UnicodeChar == '+') {
+ gDirection = SCAN_RIGHT;
+ } else {
+ gDirection = SCAN_LEFT;
+ }
+ Status = ProcessOptions (Selection, MenuOption, TRUE, &OptionString);
+ if (EFI_ERROR (Status)) {
+ //
+ // Repaint to clear possible error prompt pop-up
+ //
+ Repaint = TRUE;
+ NewLine = TRUE;
+ } else {
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+ }
+ if (OptionString != NULL) {
+ FreePool (OptionString);
+ }
+ }
+ break;
+
+ case '^':
+ ScreenOperation = UiUp;
+ break;
+
+ case 'V':
+ case 'v':
+ ScreenOperation = UiDown;
+ break;
+
+ case ' ':
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {
+ //
+ // If the screen has no menu items, and the user didn't select UiReset
+ // ignore the selection and go back to reading keys.
+ //
+ if(IsListEmpty (&gMenuOption)) {
+ ControlFlag = CfReadKey;
+ break;
+ }
+
+ ASSERT(MenuOption != NULL);
+ if (MenuOption->ThisTag->Operand == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut && !MenuOption->ReadOnly) {
+ ScreenOperation = UiSelect;
+ }
+ }
+ break;
+
+ case 'D':
+ case 'd':
+ if (!MultiHelpPage) {
+ ControlFlag = CfReadKey;
+ break;
+ }
+ ControlFlag = CfUpdateHelpString;
+ HelpPageIndex = HelpPageIndex < HelpPageCount - 1 ? HelpPageIndex + 1 : HelpPageCount - 1;
+ break;
+
+ case 'U':
+ case 'u':
+ if (!MultiHelpPage) {
+ ControlFlag = CfReadKey;
+ break;
+ }
+ ControlFlag = CfUpdateHelpString;
+ HelpPageIndex = HelpPageIndex > 0 ? HelpPageIndex - 1 : 0;
+ break;
+
+ case CHAR_NULL:
+ for (Index = 0; Index < mScanCodeNumber; Index++) {
+ if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {
+ ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;
+ break;
+ }
+ }
+
+ if (Selection->Form->ModalForm && (Key.ScanCode == SCAN_ESC || Index == mScanCodeNumber)) {
+ //
+ // ModalForm has no ESC key and Hot Key.
+ //
+ ControlFlag = CfReadKey;
+ } else if (Index == mScanCodeNumber) {
+ //
+ // Check whether Key matches the registered hot key.
+ //
+ HotKey = NULL;
+ if ((gBrowserSettingScope == SystemLevel) ||
+ (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
+ HotKey = GetHotKeyFromRegisterList (&Key);
+ }
+ if (HotKey != NULL) {
+ ScreenOperation = UiHotKey;
+ }
+ }
+ break;
+ }
+ break;
+
+ case CfScreenOperation:
+ if (ScreenOperation != UiReset) {
+ //
+ // If the screen has no menu items, and the user didn't select UiReset
+ // ignore the selection and go back to reading keys.
+ //
+ if (IsListEmpty (&gMenuOption)) {
+ ControlFlag = CfReadKey;
+ break;
+ }
+ }
+
+ for (Index = 0;
+ Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);
+ Index++
+ ) {
+ if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {
+ ControlFlag = gScreenOperationToControlFlag[Index].ControlFlag;
+ break;
+ }
+ }
+ break;
+
+ case CfUiSelect:
+ ControlFlag = CfCheckSelection;
+
+ ASSERT(MenuOption != NULL);
+ Statement = MenuOption->ThisTag;
+ if (Statement->Operand == EFI_IFR_TEXT_OP) {
+ break;
+ }
+
+ //
+ // Keep highlight on current MenuOption
+ //
+ Selection->QuestionId = Statement->QuestionId;
+
+ switch (Statement->Operand) {
+ case EFI_IFR_REF_OP:
+ ProcessGotoOpCode(Statement, Selection, &Repaint, &NewLine);
+ break;
+
+ case EFI_IFR_ACTION_OP:
+ //
+ // Process the Config string <ConfigResp>
+ //
+ Status = ProcessQuestionConfig (Selection, Statement);
+
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ //
+ // The action button may change some Question value, so refresh the form
+ //
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+ break;
+
+ case EFI_IFR_RESET_BUTTON_OP:
+ //
+ // Reset Question to default value specified by DefaultId
+ //
+ ControlFlag = CfUiDefault;
+ DefaultId = Statement->DefaultId;
+ break;
+
+ default:
+ //
+ // Editable Questions: oneof, ordered list, checkbox, numeric, string, password
+ //
+ UpdateKeyHelp (Selection, MenuOption, TRUE);
+ Status = ProcessOptions (Selection, MenuOption, TRUE, &OptionString);
+
+ if (EFI_ERROR (Status)) {
+ Repaint = TRUE;
+ NewLine = TRUE;
+ UpdateKeyHelp (Selection, MenuOption, FALSE);
+ } else {
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+ }
+
+ if (OptionString != NULL) {
+ FreePool (OptionString);
+ }
+ break;
+ }
+ break;
+
+ case CfUiReset:
+ //
+ // We come here when someone press ESC
+ //
+ ControlFlag = CfCheckSelection;
+ FindNextMenu (Selection, &Repaint, &NewLine);
+ break;
+
+ case CfUiLeft:
+ ControlFlag = CfCheckSelection;
+ ASSERT(MenuOption != NULL);
+ if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {
+ if (MenuOption->Sequence != 0) {
+ //
+ // In the middle or tail of the Date/Time op-code set, go left.
+ //
+ ASSERT(NewPos != NULL);
+ NewPos = NewPos->BackLink;
+ }
+ }
+ break;
+
+ case CfUiRight:
+ ControlFlag = CfCheckSelection;
+ ASSERT(MenuOption != NULL);
+ if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {
+ if (MenuOption->Sequence != 2) {
+ //
+ // In the middle or tail of the Date/Time op-code set, go left.
+ //
+ ASSERT(NewPos != NULL);
+ NewPos = NewPos->ForwardLink;
+ }
+ }
+ break;
+
+ case CfUiUp:
+ ControlFlag = CfCheckSelection;
+
+ SavedListEntry = NewPos;
+
+ ASSERT(NewPos != NULL);
+ //
+ // Adjust Date/Time position before we advance forward.
+ //
+ AdjustDateAndTimePosition (TRUE, &NewPos);
+ if (NewPos->BackLink != &gMenuOption) {
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ ASSERT (MenuOption != NULL);
+ NewLine = TRUE;
+ NewPos = NewPos->BackLink;
+
+ PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ if (PreviousMenuOption->Row == 0) {
+ UpdateOptionSkipLines (Selection, PreviousMenuOption);
+ }
+ DistanceValue = PreviousMenuOption->Skip;
+ Difference = 0;
+ if (MenuOption->Row >= DistanceValue + TopRow) {
+ Difference = MoveToNextStatement (Selection, TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);
+ }
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+
+ if (Difference < 0) {
+ //
+ // We hit the begining MenuOption that can be focused
+ // so we simply scroll to the top.
+ //
+ if (TopOfScreen != gMenuOption.ForwardLink) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ Repaint = TRUE;
+ } else {
+ //
+ // Scroll up to the last page when we have arrived at top page.
+ //
+ NewPos = &gMenuOption;
+ TopOfScreen = &gMenuOption;
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ ScreenOperation = UiPageUp;
+ ControlFlag = CfScreenOperation;
+ break;
+ }
+ } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {
+ //
+ // Previous focus MenuOption is above the TopOfScreen, so we need to scroll
+ //
+ TopOfScreen = NewPos;
+ Repaint = TRUE;
+ SkipValue = 0;
+ } else if (!IsSelectable (NextMenuOption)) {
+ //
+ // Continue to go up until scroll to next page or the selectable option is found.
+ //
+ ScreenOperation = UiUp;
+ ControlFlag = CfScreenOperation;
+ }
+
+ //
+ // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
+ //
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);
+ AdjustDateAndTimePosition (TRUE, &NewPos);
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);
+ } else {
+ //
+ // Scroll up to the last page.
+ //
+ NewPos = &gMenuOption;
+ TopOfScreen = &gMenuOption;
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ ScreenOperation = UiPageUp;
+ ControlFlag = CfScreenOperation;
+ }
+ break;
+
+ case CfUiPageUp:
+ //
+ // SkipValue means lines is skipped when show the top menu option.
+ //
+ ControlFlag = CfCheckSelection;
+
+ ASSERT(NewPos != NULL);
+ //
+ // Already at the first menu option, so do nothing.
+ //
+ if (NewPos->BackLink == &gMenuOption) {
+ NewLine = FALSE;
+ Repaint = FALSE;
+ break;
+ }
+
+ NewLine = TRUE;
+ Repaint = TRUE;
+
+ //
+ // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
+ // form of options to be show, so just update the SkipValue to show the next
+ // parts of options.
+ //
+ if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {
+ SkipValue -= BottomRow - TopRow + 1;
+ break;
+ }
+
+ Link = TopOfScreen;
+ //
+ // First minus the menu of the top screen, it's value is SkipValue.
+ //
+ Index = (BottomRow + 1) - SkipValue;
+ while ((Index >= TopRow) && (Link->BackLink != &gMenuOption)) {
+ Link = Link->BackLink;
+ PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
+ if (PreviousMenuOption->Row == 0) {
+ UpdateOptionSkipLines (Selection, PreviousMenuOption);
+ }
+ if (Index < PreviousMenuOption->Skip) {
+ break;
+ }
+ Index = Index - PreviousMenuOption->Skip;
+ }
+
+ if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {
+ SkipValue = 0;
+ if (TopOfScreen == &gMenuOption) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ NewPos = gMenuOption.BackLink;
+ MoveToNextStatement (Selection, TRUE, &NewPos, BottomRow - TopRow);
+ Repaint = FALSE;
+ } else if (TopOfScreen != Link) {
+ TopOfScreen = Link;
+ NewPos = Link;
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
+ } else {
+ //
+ // Finally we know that NewPos is the last MenuOption can be focused.
+ //
+ Repaint = FALSE;
+ NewPos = Link;
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
+ }
+ } else {
+ if (Index >= TopRow) {
+ //
+ // At here, only case "Index < PreviousMenuOption->Skip" can reach here.
+ //
+ SkipValue = PreviousMenuOption->Skip - (Index - TopRow);
+ } else {
+ SkipValue = PreviousMenuOption->Skip - (TopRow - Index);
+ Link = Link->ForwardLink;
+ }
+
+ //
+ // Move to the option in Next page.
+ //
+ if (TopOfScreen == &gMenuOption) {
+ NewPos = gMenuOption.BackLink;
+ MoveToNextStatement (Selection, TRUE, &NewPos, BottomRow - TopRow);
+ } else {
+ NewPos = Link;
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
+ }
+
+ //
+ // There are more MenuOption needing scrolling up.
+ //
+ TopOfScreen = Link;
+ MenuOption = NULL;
+ }
+
+ //
+ // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
+ // Don't do this when we are already in the first page.
+ //
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);
+ AdjustDateAndTimePosition (TRUE, &NewPos);
+ break;
+
+ case CfUiPageDown:
+ //
+ // SkipValue means lines is skipped when show the top menu option.
+ //
+ ControlFlag = CfCheckSelection;
+
+ ASSERT (NewPos != NULL);
+ if (NewPos->ForwardLink == &gMenuOption) {
+ NewLine = FALSE;
+ Repaint = FALSE;
+ break;
+ }
+
+ NewLine = TRUE;
+ Repaint = TRUE;
+ Link = TopOfScreen;
+ NextMenuOption = MENU_OPTION_FROM_LINK (Link);
+ Index = TopRow + NextMenuOption->Skip - SkipValue;
+ //
+ // Count to the menu option which will show at the top of the next form.
+ //
+ while ((Index <= BottomRow + 1) && (Link->ForwardLink != &gMenuOption)) {
+ Link = Link->ForwardLink;
+ NextMenuOption = MENU_OPTION_FROM_LINK (Link);
+ Index = Index + NextMenuOption->Skip;
+ }
+
+ if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {
+ //
+ // Finally we know that NewPos is the last MenuOption can be focused.
+ //
+ Repaint = FALSE;
+ MoveToNextStatement (Selection, TRUE, &Link, Index - TopRow);
+ SkipValue = 0;
+ } else {
+ //
+ // Calculate the skip line for top of screen menu.
+ //
+ if (Link == TopOfScreen) {
+ //
+ // The top of screen menu option occupies the entire form.
+ //
+ SkipValue += BottomRow - TopRow + 1;
+ } else {
+ SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));
+ }
+
+ TopOfScreen = Link;
+ MenuOption = NULL;
+ //
+ // Move to the Next selectable menu.
+ //
+ MoveToNextStatement (Selection, FALSE, &Link, BottomRow - TopRow);
+ }
+
+ //
+ // Save the menu as the next highlight menu.
+ //
+ NewPos = Link;
+
+ //
+ // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
+ // Don't do this when we are already in the last page.
+ //
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);
+ AdjustDateAndTimePosition (TRUE, &NewPos);
+ break;
+
+ case CfUiDown:
+ //
+ // SkipValue means lines is skipped when show the top menu option.
+ // NewPos points to the menu which is highlighted now.
+ //
+ ControlFlag = CfCheckSelection;
+ //
+ // Since the behavior of hitting the down arrow on a Date/Time op-code is intended
+ // to be one that progresses to the next set of op-codes, we need to advance to the last
+ // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate
+ // checking can be done. The only other logic we need to introduce is that if a Date/Time
+ // op-code is the last entry in the menu, we need to rewind back to the first op-code of
+ // the Date/Time op-code.
+ //
+ SavedListEntry = NewPos;
+ AdjustDateAndTimePosition (FALSE, &NewPos);
+
+ if (NewPos->ForwardLink != &gMenuOption) {
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ NewLine = TRUE;
+ NewPos = NewPos->ForwardLink;
+
+ Difference = 0;
+ //
+ // Current menu not at the bottom of the form.
+ //
+ if (BottomRow >= MenuOption->Row + MenuOption->Skip) {
+ //
+ // Find the next selectable menu.
+ //
+ Difference = MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);
+ //
+ // We hit the end of MenuOption that can be focused
+ // so we simply scroll to the first page.
+ //
+ if (Difference < 0) {
+ //
+ // Scroll to the first page.
+ //
+ if (TopOfScreen != gMenuOption.ForwardLink) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ Repaint = TRUE;
+ MenuOption = NULL;
+ } else {
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ }
+ NewPos = gMenuOption.ForwardLink;
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
+
+ SkipValue = 0;
+ //
+ // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
+ //
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);
+ AdjustDateAndTimePosition (TRUE, &NewPos);
+ break;
+ }
+ }
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ if (NextMenuOption->Row == 0) {
+ UpdateOptionSkipLines (Selection, NextMenuOption);
+ }
+ DistanceValue = Difference + NextMenuOption->Skip;
+
+ Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;
+ if ((MenuOption->Row + MenuOption->Skip == BottomRow + 1) &&
+ (NextMenuOption->ThisTag->Operand == EFI_IFR_DATE_OP ||
+ NextMenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)
+ ) {
+ Temp ++;
+ }
+
+ //
+ // If we are going to scroll, update TopOfScreen
+ //
+ if (Temp > BottomRow) {
+ do {
+ //
+ // Is the current top of screen a zero-advance op-code?
+ // If so, keep moving forward till we hit a >0 advance op-code
+ //
+ SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
+
+ //
+ // If bottom op-code is more than one line or top op-code is more than one line
+ //
+ if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {
+ //
+ // Is the bottom op-code greater than or equal in size to the top op-code?
+ //
+ if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
+ //
+ // Skip the top op-code
+ //
+ TopOfScreen = TopOfScreen->ForwardLink;
+ Difference = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
+
+ SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
+
+ //
+ // If we have a remainder, skip that many more op-codes until we drain the remainder
+ //
+ while (Difference >= (INTN) SavedMenuOption->Skip) {
+ //
+ // Since the Difference is greater than or equal to this op-code's skip value, skip it
+ //
+ Difference = Difference - (INTN) SavedMenuOption->Skip;
+ TopOfScreen = TopOfScreen->ForwardLink;
+ SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
+ }
+ //
+ // Since we will act on this op-code in the next routine, and increment the
+ // SkipValue, set the skips to one less than what is required.
+ //
+ SkipValue = Difference - 1;
+ } else {
+ //
+ // Since we will act on this op-code in the next routine, and increment the
+ // SkipValue, set the skips to one less than what is required.
+ //
+ SkipValue += (Temp - BottomRow) - 1;
+ }
+ } else {
+ if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {
+ TopOfScreen = TopOfScreen->ForwardLink;
+ break;
+ }
+ }
+ //
+ // If the op-code at the top of the screen is more than one line, let's not skip it yet
+ // Let's set a skip flag to smoothly scroll the top of the screen.
+ //
+ if (SavedMenuOption->Skip > 1) {
+ if (SavedMenuOption == NextMenuOption) {
+ SkipValue = 0;
+ } else {
+ SkipValue++;
+ }
+ } else if (SavedMenuOption->Skip == 1) {
+ SkipValue = 0;
+ } else {
+ SkipValue = 0;
+ TopOfScreen = TopOfScreen->ForwardLink;
+ }
+ } while (SavedMenuOption->Skip == 0);
+
+ Repaint = TRUE;
+ } else if (!IsSelectable (NextMenuOption)) {
+ //
+ // Continue to go down until scroll to next page or the selectable option is found.
+ //
+ ScreenOperation = UiDown;
+ ControlFlag = CfScreenOperation;
+ }
+
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+
+ UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);
+
+ } else {
+ //
+ // Scroll to the first page.
+ //
+ if (TopOfScreen != gMenuOption.ForwardLink) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ Repaint = TRUE;
+ MenuOption = NULL;
+ } else {
+ //
+ // Need to remove the current highlight menu.
+ // MenuOption saved the last highlight menu info.
+ //
+ MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ }
+
+ SkipValue = 0;
+ NewLine = TRUE;
+ //
+ // Get the next highlight menu.
+ //
+ NewPos = gMenuOption.ForwardLink;
+ MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
+ }
+
+ //
+ // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
+ //
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);
+ AdjustDateAndTimePosition (TRUE, &NewPos);
+ break;
+
+ case CfUiHotKey:
+ ControlFlag = CfCheckSelection;
+
+ Status = EFI_SUCCESS;
+ //
+ // Discard changes. After it, no NV flag is showed.
+ //
+ if ((HotKey->Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {
+ Status = DiscardForm (Selection->FormSet, Selection->Form, gBrowserSettingScope);
+ if (!EFI_ERROR (Status)) {
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+ Selection->Statement = NULL;
+ gResetRequired = FALSE;
+ } else {
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, HotKey->HelpString, gDiscardFailed, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ //
+ // Still show current page.
+ //
+ Selection->Action = UI_ACTION_NONE;
+ Repaint = TRUE;
+ NewLine = TRUE;
+ break;
+ }
+ }
+
+ //
+ // Reterieve default setting. After it. NV flag will be showed.
+ //
+ if ((HotKey->Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
+ Status = ExtractDefault (Selection->FormSet, Selection->Form, HotKey->DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);
+ if (!EFI_ERROR (Status)) {
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+ Selection->Statement = NULL;
+ gResetRequired = TRUE;
+ } else {
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, HotKey->HelpString, gDefaultFailed, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ //
+ // Still show current page.
+ //
+ Selection->Action = UI_ACTION_NONE;
+ Repaint = TRUE;
+ NewLine = TRUE;
+ break;
+ }
+ }
+
+ //
+ // Save changes. After it, no NV flag is showed.
+ //
+ if ((HotKey->Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {
+ Status = SubmitForm (Selection->FormSet, Selection->Form, gBrowserSettingScope);
+ if (!EFI_ERROR (Status)) {
+ ASSERT(MenuOption != NULL);
+ UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);
+ UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, MenuOption->ThisTag->QuestionFlags, FALSE);
+ } else {
+ do {
+ CreateDialog (4, TRUE, 0, NULL, &Key, HotKey->HelpString, gSaveFailed, gPressEnter, gEmptyString);
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ //
+ // Still show current page.
+ //
+ Selection->Action = UI_ACTION_NONE;
+ Repaint = TRUE;
+ NewLine = TRUE;
+ break;
+ }
+ }
+
+ //
+ // Set Reset required Flag
+ //
+ if ((HotKey->Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {
+ gResetRequired = TRUE;
+ }
+
+ //
+ // Exit Action
+ //
+ if ((HotKey->Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {
+ //
+ // Form Exit without saving, Similar to ESC Key.
+ // FormSet Exit without saving, Exit SendForm.
+ // System Exit without saving, CallExitHandler and Exit SendForm.
+ //
+ DiscardForm (Selection->FormSet, Selection->Form, gBrowserSettingScope);
+ if (gBrowserSettingScope == FormLevel) {
+ ControlFlag = CfUiReset;
+ } else if (gBrowserSettingScope == FormSetLevel) {
+ Selection->Action = UI_ACTION_EXIT;
+ } else if (gBrowserSettingScope == SystemLevel) {
+ if (ExitHandlerFunction != NULL) {
+ ExitHandlerFunction ();
+ }
+ Selection->Action = UI_ACTION_EXIT;
+ }
+ Selection->Statement = NULL;
+ }
+ break;
+
+ case CfUiDefault:
+ ControlFlag = CfCheckSelection;
+ //
+ // Reset to default value for all forms in the whole system.
+ //
+ Status = ExtractDefault (Selection->FormSet, NULL, DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE);
+
+ if (!EFI_ERROR (Status)) {
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+ Selection->Statement = NULL;
+ gResetRequired = TRUE;
+ }
+ break;
+
+ case CfUiNoOperation:
+ ControlFlag = CfCheckSelection;
+ break;
+
+ case CfExit:
+ UiFreeRefreshList ();
+
+ gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
+ gST->ConOut->SetCursorPosition (gST->ConOut, 0, Row + 4);
+ gST->ConOut->EnableCursor (gST->ConOut, TRUE);
+ gST->ConOut->OutputString (gST->ConOut, L"\n");
+ if (HelpString != NULL) {
+ FreePool (HelpString);
+ }
+ if (HelpHeaderString != NULL) {
+ FreePool (HelpHeaderString);
+ }
+ if (HelpBottomString != NULL) {
+ FreePool (HelpBottomString);
+ }
+
+ return EFI_SUCCESS;
+
+ default:
+ break;
+ }
+ }
+}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h new file mode 100644 index 0000000000..03cb0cd753 --- /dev/null +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h @@ -0,0 +1,1067 @@ +/** @file
+Private structure, MACRO and function definitions for User Interface related functionalities.
+
+Copyright (c) 2004 - 2013, 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.
+
+**/
+
+#ifndef _UI_H_
+#define _UI_H_
+
+//
+// Globals
+//
+#define REGULAR_NUMERIC 0
+#define TIME_NUMERIC 1
+#define DATE_NUMERIC 2
+
+#define SUBTITLE_INDENT 2
+
+
+//
+// It take 23 characters including the NULL to print a 64 bits number with "[" and "]".
+// pow(2, 64) = [18446744073709551616]
+//
+#define MAX_NUMERIC_INPUT_WIDTH 23
+
+typedef enum {
+ UiNoOperation,
+ UiSelect,
+ UiUp,
+ UiDown,
+ UiLeft,
+ UiRight,
+ UiReset,
+ UiPrevious,
+ UiPageUp,
+ UiPageDown,
+ UiHotKey,
+ UiMaxOperation
+} UI_SCREEN_OPERATION;
+
+typedef enum {
+ CfInitialization,
+ CfCheckSelection,
+ CfRepaint,
+ CfRefreshHighLight,
+ CfUpdateHelpString,
+ CfPrepareToReadKey,
+ CfReadKey,
+ CfScreenOperation,
+ CfUiSelect,
+ CfUiReset,
+ CfUiLeft,
+ CfUiRight,
+ CfUiUp,
+ CfUiPageUp,
+ CfUiPageDown,
+ CfUiDown,
+ CfUiDefault,
+ CfUiNoOperation,
+ CfExit,
+ CfUiHotKey,
+ CfMaxControlFlag
+} UI_CONTROL_FLAG;
+
+#define UI_ACTION_NONE 0
+#define UI_ACTION_REFRESH_FORM 1
+#define UI_ACTION_REFRESH_FORMSET 2
+#define UI_ACTION_EXIT 3
+
+typedef struct _UI_MENU_LIST UI_MENU_LIST;
+
+typedef struct {
+ EFI_HII_HANDLE Handle;
+
+ //
+ // Target formset/form/Question information
+ //
+ EFI_GUID FormSetGuid;
+ UINT16 FormId;
+ UINT16 QuestionId;
+ UINTN Sequence; // used for time/date only.
+
+ UINTN TopRow;
+ UINTN BottomRow;
+ UINTN PromptCol;
+ UINTN OptionCol;
+ UINTN CurrentRow;
+
+ //
+ // Ation for Browser to taken:
+ // UI_ACTION_NONE - navigation inside a form
+ // UI_ACTION_REFRESH_FORM - re-evaluate expressions and repaint form
+ // UI_ACTION_REFRESH_FORMSET - re-parse formset IFR binary
+ //
+ UINTN Action;
+
+ //
+ // Current selected fomset/form/Question
+ //
+ FORM_BROWSER_FORMSET *FormSet;
+ FORM_BROWSER_FORM *Form;
+ FORM_BROWSER_STATEMENT *Statement;
+
+ //
+ // Whether the Form is editable
+ //
+ BOOLEAN FormEditable;
+
+ UI_MENU_LIST *CurrentMenu;
+} UI_MENU_SELECTION;
+
+#define UI_MENU_OPTION_SIGNATURE SIGNATURE_32 ('u', 'i', 'm', 'm')
+#define UI_MENU_LIST_SIGNATURE SIGNATURE_32 ('u', 'i', 'm', 'l')
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link;
+
+ EFI_HII_HANDLE Handle;
+ FORM_BROWSER_STATEMENT *ThisTag;
+ UINT16 EntryNumber;
+
+ UINTN Row;
+ UINTN Col;
+ UINTN OptCol;
+ CHAR16 *Description;
+ UINTN Skip; // Number of lines
+
+ //
+ // Display item sequence for date/time
+ // Date: Month/Day/Year
+ // Sequence: 0 1 2
+ //
+ // Time: Hour : Minute : Second
+ // Sequence: 0 1 2
+ //
+ //
+ UINTN Sequence;
+
+ BOOLEAN GrayOut;
+ BOOLEAN ReadOnly;
+
+ //
+ // Whether user could change value of this item
+ //
+ BOOLEAN IsQuestion;
+} UI_MENU_OPTION;
+
+#define MENU_OPTION_FROM_LINK(a) CR (a, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE)
+
+struct _UI_MENU_LIST {
+ UINTN Signature;
+ LIST_ENTRY Link;
+
+ EFI_HII_HANDLE HiiHandle;
+ EFI_GUID FormSetGuid;
+ UINT16 FormId;
+ UINT16 QuestionId;
+ UINTN Sequence; // used for time/date only.
+
+ UI_MENU_LIST *Parent;
+ LIST_ENTRY ChildListHead;
+};
+
+#define UI_MENU_LIST_FROM_LINK(a) CR (a, UI_MENU_LIST, Link, UI_MENU_LIST_SIGNATURE)
+
+typedef struct _MENU_REFRESH_ENTRY MENU_REFRESH_ENTRY;
+struct _MENU_REFRESH_ENTRY {
+ MENU_REFRESH_ENTRY *Next;
+ UI_MENU_OPTION *MenuOption; // Describes the entry needing an update
+ UI_MENU_SELECTION *Selection;
+ UINTN CurrentColumn;
+ UINTN CurrentRow;
+ UINTN CurrentAttribute;
+ EFI_EVENT Event;
+};
+
+typedef struct {
+ UINT16 ScanCode;
+ UI_SCREEN_OPERATION ScreenOperation;
+} SCAN_CODE_TO_SCREEN_OPERATION;
+
+typedef struct {
+ UI_SCREEN_OPERATION ScreenOperation;
+ UI_CONTROL_FLAG ControlFlag;
+} SCREEN_OPERATION_T0_CONTROL_FLAG;
+
+
+extern LIST_ENTRY gMenuOption;
+extern LIST_ENTRY gMenuList;
+extern MENU_REFRESH_ENTRY *gMenuRefreshHead;
+extern UI_MENU_SELECTION *gCurrentSelection;
+extern BOOLEAN mHiiPackageListUpdated;
+
+//
+// Global Functions
+//
+/**
+ Initialize Menu option list.
+
+**/
+VOID
+UiInitMenu (
+ VOID
+ );
+
+/**
+ Initialize Menu option list.
+
+**/
+VOID
+UiInitMenuList (
+ VOID
+ );
+
+/**
+ Free Menu option linked list.
+
+**/
+VOID
+UiFreeMenu (
+ VOID
+ );
+
+/**
+ Create a menu with specified formset GUID and form ID, and add it as a child
+ of the given parent menu.
+
+ @param Parent The parent of menu to be added.
+ @param HiiHandle Hii handle related to this formset.
+ @param FormSetGuid The Formset Guid of menu to be added.
+ @param FormId The Form ID of menu to be added.
+
+ @return A pointer to the newly added menu or NULL if memory is insufficient.
+
+**/
+UI_MENU_LIST *
+UiAddMenuList (
+ IN OUT UI_MENU_LIST *Parent,
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid,
+ IN UINT16 FormId
+ );
+
+/**
+ Search Menu with given FormId, FormSetGuid and Handle in all cached menu list.
+
+ @param Parent The parent of menu to search.
+ @param Handle Hii handle related to this formset.
+ @param FormSetGuid The Formset GUID of the menu to search.
+ @param FormId The Form ID of menu to search.
+
+ @return A pointer to menu found or NULL if not found.
+
+**/
+UI_MENU_LIST *
+UiFindChildMenuList (
+ IN UI_MENU_LIST *Parent,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_GUID *FormSetGuid,
+ IN UINT16 FormId
+ );
+
+/**
+ Search Menu with given Handle, FormSetGuid and FormId in all cached menu list.
+
+ @param Handle Hii handle related to this formset.
+ @param FormSetGuid The Formset GUID of the menu to search.
+ @param FormId The Form ID of menu to search.
+
+ @return A pointer to menu found or NULL if not found.
+
+**/
+UI_MENU_LIST *
+UiFindMenuList (
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_GUID *FormSetGuid,
+ IN UINT16 FormId
+ );
+
+/**
+ Free Menu list linked list.
+
+ @param MenuListHead One Menu list point in the menu list.
+
+**/
+VOID
+UiFreeMenuList (
+ LIST_ENTRY *MenuListHead
+ );
+
+/**
+ Free Menu option linked list.
+
+**/
+VOID
+UiFreeRefreshList (
+ VOID
+ );
+
+/**
+ Add one menu option by specified description and context.
+
+ @param String String description for this option.
+ @param Handle Hii handle for the package list.
+ @param Form The form this statement belong to.
+ @param Statement Statement of this Menu Option.
+ @param NumberOfLines Display lines for this Menu Option.
+ @param MenuItemCount The index for this Option in the Menu.
+
+ @retval Pointer Pointer to the added Menu Option.
+
+**/
+UI_MENU_OPTION *
+UiAddMenuOption (
+ IN CHAR16 *String,
+ IN EFI_HII_HANDLE Handle,
+ IN FORM_BROWSER_FORM *Form,
+ IN FORM_BROWSER_STATEMENT *Statement,
+ IN UINT16 NumberOfLines,
+ IN UINT16 MenuItemCount
+ );
+
+/**
+ Display menu and wait for user to select one menu option, then return it.
+ If AutoBoot is enabled, then if user doesn't select any option,
+ after period of time, it will automatically return the first menu option.
+
+ @param Selection Menu selection.
+
+ @return Return the pointer of the menu which selected,
+ @return otherwise return NULL.
+
+**/
+EFI_STATUS
+UiDisplayMenu (
+ IN OUT UI_MENU_SELECTION *Selection
+ );
+
+/**
+ Free up the resource allocated for all strings required
+ by Setup Browser.
+
+**/
+VOID
+FreeBrowserStrings (
+ VOID
+ );
+
+/**
+ Process the goto op code, update the info in the selection structure.
+
+ @param Statement The statement belong to goto op code.
+ @param Selection The selection info.
+ @param Repaint Whether need to repaint the menu.
+ @param NewLine Whether need to create new line.
+
+ @retval EFI_SUCCESS The menu process successfully.
+ @return Other value if the process failed.
+**/
+EFI_STATUS
+ProcessGotoOpCode (
+ IN OUT FORM_BROWSER_STATEMENT *Statement,
+ IN OUT UI_MENU_SELECTION *Selection,
+ OUT BOOLEAN *Repaint,
+ OUT BOOLEAN *NewLine
+ );
+
+
+/**
+ The worker function that send the displays to the screen. On output,
+ the selection made by user is returned.
+
+ @param Selection On input, Selection tell setup browser the information
+ about the Selection, form and formset to be displayed.
+ On output, Selection return the screen item that is selected
+ by user.
+
+ @retval EFI_SUCCESS The page is displayed successfully.
+ @return Other value if the page failed to be diplayed.
+
+**/
+EFI_STATUS
+SetupBrowser (
+ IN OUT UI_MENU_SELECTION *Selection
+ );
+
+/**
+ Set Buffer to Value for Size bytes.
+
+ @param Buffer Memory to set.
+ @param Size Number of bytes to set
+ @param Value Value of the set operation.
+
+**/
+VOID
+SetUnicodeMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN CHAR16 Value
+ );
+
+/**
+ Wait for a given event to fire, or for an optional timeout to expire.
+
+ @param Event The event to wait for
+ @param Timeout An optional timeout value in 100 ns units.
+ @param RefreshInterval Menu refresh interval (in seconds).
+
+ @retval EFI_SUCCESS Event fired before Timeout expired.
+ @retval EFI_TIME_OUT Timout expired before Event fired.
+
+**/
+EFI_STATUS
+UiWaitForSingleEvent (
+ IN EFI_EVENT Event,
+ IN UINT64 Timeout, OPTIONAL
+ IN UINT8 RefreshInterval OPTIONAL
+ );
+
+/**
+ Draw a pop up windows based on the dimension, number of lines and
+ strings specified.
+
+ @param ScreenWidth The width of the pop-up.
+ @param NumberOfLines The number of lines.
+ @param ... A series of text strings that displayed in the pop-up.
+
+**/
+VOID
+EFIAPI
+CreateMultiStringPopUp (
+ IN UINTN ScreenWidth,
+ IN UINTN NumberOfLines,
+ ...
+ );
+
+/**
+ Get string or password input from user.
+
+ @param MenuOption Pointer to the current input menu.
+ @param Prompt The prompt string shown on popup window.
+ @param StringPtr Old user input and destination for use input string.
+
+ @retval EFI_SUCCESS If string input is read successfully
+ @retval EFI_DEVICE_ERROR If operation fails
+
+**/
+EFI_STATUS
+ReadString (
+ IN UI_MENU_OPTION *MenuOption,
+ IN CHAR16 *Prompt,
+ IN OUT CHAR16 *StringPtr
+ );
+
+/**
+ Get selection for OneOf and OrderedList (Left/Right will be ignored).
+
+ @param Selection Pointer to current selection.
+ @param MenuOption Pointer to the current input menu.
+
+ @retval EFI_SUCCESS If Option input is processed successfully
+ @retval EFI_DEVICE_ERROR If operation fails
+
+**/
+EFI_STATUS
+GetSelectionInputPopUp (
+ IN UI_MENU_SELECTION *Selection,
+ IN UI_MENU_OPTION *MenuOption
+ );
+
+/**
+ This routine reads a numeric value from the user input.
+
+ @param Selection Pointer to current selection.
+ @param MenuOption Pointer to the current input menu.
+
+ @retval EFI_SUCCESS If numerical input is read successfully
+ @retval EFI_DEVICE_ERROR If operation fails
+
+**/
+EFI_STATUS
+GetNumericInput (
+ IN UI_MENU_SELECTION *Selection,
+ IN UI_MENU_OPTION *MenuOption
+ );
+
+/**
+ Update status bar on the bottom of menu.
+
+ @param Selection Current selection info.
+ @param MessageType The type of message to be shown.
+ @param Flags The flags in Question header.
+ @param State Set or clear.
+
+**/
+VOID
+UpdateStatusBar (
+ IN UI_MENU_SELECTION *Selection,
+ IN UINTN MessageType,
+ IN UINT8 Flags,
+ IN BOOLEAN State
+ );
+
+/**
+ Process Question Config.
+
+ @param Selection The UI menu selection.
+ @param Question The Question to be peocessed.
+
+ @retval EFI_SUCCESS Question Config process success.
+ @retval Other Question Config process fail.
+
+**/
+EFI_STATUS
+ProcessQuestionConfig (
+ IN UI_MENU_SELECTION *Selection,
+ IN FORM_BROWSER_STATEMENT *Question
+ );
+
+/**
+ Print Question Value according to it's storage width and display attributes.
+
+ @param Question The Question to be printed.
+ @param FormattedNumber Buffer for output string.
+ @param BufferSize The FormattedNumber buffer size in bytes.
+
+ @retval EFI_SUCCESS Print success.
+ @retval EFI_BUFFER_TOO_SMALL Buffer size is not enough for formatted number.
+
+**/
+EFI_STATUS
+PrintFormattedNumber (
+ IN FORM_BROWSER_STATEMENT *Question,
+ IN OUT CHAR16 *FormattedNumber,
+ IN UINTN BufferSize
+ );
+
+/**
+ Search an Option of a Question by its value.
+
+ @param Question The Question
+ @param OptionValue Value for Option to be searched.
+
+ @retval Pointer Pointer to the found Option.
+ @retval NULL Option not found.
+
+**/
+QUESTION_OPTION *
+ValueToOption (
+ IN FORM_BROWSER_STATEMENT *Question,
+ IN EFI_HII_VALUE *OptionValue
+ );
+
+/**
+ Return data element in an Array by its Index.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+
+ @retval Value The data to be returned
+
+**/
+UINT64
+GetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index
+ );
+
+/**
+ Set value of a data element in an Array by its Index.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+ @param Value The value to be set.
+
+**/
+VOID
+SetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index,
+ IN UINT64 Value
+ );
+
+/**
+ Check whether this value already in the array, if yes, return the index.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Value The value to be find.
+ @param Index The index in the array which has same value with Value.
+
+ @retval TRUE Found the value in the array.
+ @retval FALSE Not found the value.
+
+**/
+BOOLEAN
+FindArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINT64 Value,
+ OUT UINTN *Index OPTIONAL
+ );
+
+/**
+ Process a Question's Option (whether selected or un-selected).
+
+ @param Selection Pointer to UI_MENU_SELECTION.
+ @param MenuOption The MenuOption for this Question.
+ @param Selected TRUE: if Question is selected.
+ @param OptionString Pointer of the Option String to be displayed.
+
+ @retval EFI_SUCCESS Question Option process success.
+ @retval Other Question Option process fail.
+
+**/
+EFI_STATUS
+ProcessOptions (
+ IN UI_MENU_SELECTION *Selection,
+ IN UI_MENU_OPTION *MenuOption,
+ IN BOOLEAN Selected,
+ OUT CHAR16 **OptionString
+ );
+
+/**
+ Process the help string: Split StringPtr to several lines of strings stored in
+ FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.
+
+ @param StringPtr The entire help string.
+ @param FormattedString The oupput formatted string.
+ @param EachLineWidth The string length of each line in the formatted string.
+ @param RowCount TRUE: if Question is selected.
+
+**/
+UINTN
+ProcessHelpString (
+ IN CHAR16 *StringPtr,
+ OUT CHAR16 **FormattedString,
+ OUT UINT16 *EachLineWidth,
+ IN UINTN RowCount
+ );
+
+/**
+ Update key's help imformation.
+
+ @param Selection Tell setup browser the information about the Selection
+ @param MenuOption The Menu option
+ @param Selected Whether or not a tag be selected
+
+**/
+VOID
+UpdateKeyHelp (
+ IN UI_MENU_SELECTION *Selection,
+ IN UI_MENU_OPTION *MenuOption,
+ IN BOOLEAN Selected
+ );
+
+/**
+ Clear retangle with specified text attribute.
+
+ @param LeftColumn Left column of retangle.
+ @param RightColumn Right column of retangle.
+ @param TopRow Start row of retangle.
+ @param BottomRow End row of retangle.
+ @param TextAttribute The character foreground and background.
+
+**/
+VOID
+ClearLines (
+ IN UINTN LeftColumn,
+ IN UINTN RightColumn,
+ IN UINTN TopRow,
+ IN UINTN BottomRow,
+ IN UINTN TextAttribute
+ );
+
+/**
+ Count the storage space of a Unicode string.
+
+ This function handles the Unicode string with NARROW_CHAR
+ and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
+ does not count in the resultant output. If a WIDE_CHAR is
+ hit, then 2 Unicode character will consume an output storage
+ space with size of CHAR16 till a NARROW_CHAR is hit.
+
+ If String is NULL, then ASSERT ().
+
+ @param String The input string to be counted.
+
+ @return Storage space for the input string.
+
+**/
+UINTN
+GetStringWidth (
+ IN CHAR16 *String
+ );
+
+/**
+ Will copy LineWidth amount of a string in the OutputString buffer and return the
+ number of CHAR16 characters that were copied into the OutputString buffer.
+ In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.
+
+ @param InputString String description for this option.
+ @param LineWidth Width of the desired string to extract in CHAR16
+ characters
+ @param GlyphWidth The glyph width of the beging char in the string.
+ @param Index Where in InputString to start the copy process
+ @param OutputString Buffer to copy the string into
+
+ @return Returns the number of CHAR16 characters that were copied into the OutputString buffer.
+
+**/
+UINT16
+GetLineByWidth (
+ IN CHAR16 *InputString,
+ IN UINT16 LineWidth,
+ IN OUT UINT16 *GlyphWidth,
+ IN OUT UINTN *Index,
+ OUT CHAR16 **OutputString
+ );
+
+/**
+ Get the supported width for a particular op-code
+
+ @param Statement The FORM_BROWSER_STATEMENT structure passed in.
+ @param Handle The handle in the HII database being used
+
+ @return Returns the number of CHAR16 characters that is support.
+
+**/
+UINT16
+GetWidth (
+ IN FORM_BROWSER_STATEMENT *Statement,
+ IN EFI_HII_HANDLE Handle
+ );
+
+/**
+ Concatenate a narrow string to another string.
+
+ @param Destination The destination string.
+ @param Source The source string. The string to be concatenated.
+ to the end of Destination.
+
+**/
+VOID
+NewStrCat (
+ IN OUT CHAR16 *Destination,
+ IN CHAR16 *Source
+ );
+
+/**
+ Wait for a key to be pressed by user.
+
+ @param Key The key which is pressed by user.
+
+ @retval EFI_SUCCESS The function always completed successfully.
+
+**/
+EFI_STATUS
+WaitForKeyStroke (
+ OUT EFI_INPUT_KEY *Key
+ );
+
+/**
+ Reset stack pointer to begin of the stack.
+
+**/
+VOID
+ResetScopeStack (
+ VOID
+ );
+
+/**
+ Push the expression options onto the Stack.
+
+ @param Pointer Pointer to the current expression.
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushConditionalExpression (
+ IN FORM_EXPRESSION *Pointer,
+ IN EXPRESS_LEVEL Level
+ );
+
+/**
+ Pop the expression options from the Stack
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopConditionalExpression (
+ IN EXPRESS_LEVEL Level
+ );
+
+/**
+ Get the expression Buffer pointer.
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval The start pointer of the expression buffer or NULL.
+
+**/
+FORM_EXPRESSION **
+GetConditionalExpressionList (
+ IN EXPRESS_LEVEL Level
+ );
+
+/**
+ Get the expression list count.
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval >=0 The expression count
+ @retval -1 Input parameter error.
+
+**/
+INTN
+GetConditionalExpressionCount (
+ IN EXPRESS_LEVEL Level
+ );
+
+/**
+ Push an Operand onto the Stack
+
+ @param Operand Operand to push.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
+ stack.
+
+**/
+EFI_STATUS
+PushScope (
+ IN UINT8 Operand
+ );
+
+/**
+ Pop an Operand from the Stack
+
+ @param Operand Operand to pop.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
+ stack.
+
+**/
+EFI_STATUS
+PopScope (
+ OUT UINT8 *Operand
+ );
+
+/**
+ Reset stack pointer to begin of the stack.
+
+**/
+VOID
+ResetCurrentExpressionStack (
+ VOID
+ );
+
+/**
+ Push current expression onto the Stack
+
+ @param Pointer Pointer to current expression.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushCurrentExpression (
+ IN VOID *Pointer
+ );
+
+/**
+ Pop current expression from the Stack
+
+ @param Pointer Pointer to current expression to be pop.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopCurrentExpression (
+ OUT VOID **Pointer
+ );
+
+/**
+ Reset stack pointer to begin of the stack.
+
+**/
+VOID
+ResetMapExpressionListStack (
+ VOID
+ );
+
+/**
+ Push the list of map expression onto the Stack
+
+ @param Pointer Pointer to the list of map expression to be pushed.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushMapExpressionList (
+ IN VOID *Pointer
+ );
+
+/**
+ Pop the list of map expression from the Stack
+
+ @param Pointer Pointer to the list of map expression to be pop.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopMapExpressionList (
+ OUT VOID **Pointer
+ );
+
+/**
+ Get Form given its FormId.
+
+ @param FormSet The formset which contains this form.
+ @param FormId Id of this form.
+
+ @retval Pointer The form.
+ @retval NULL Specified Form is not found in the formset.
+
+**/
+FORM_BROWSER_FORM *
+IdToForm (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN UINT16 FormId
+ );
+
+/**
+ Search a Question in Formset scope using its QuestionId.
+
+ @param FormSet The formset which contains this form.
+ @param Form The form which contains this Question.
+ @param QuestionId Id of this Question.
+
+ @retval Pointer The Question.
+ @retval NULL Specified Question not found in the form.
+
+**/
+FORM_BROWSER_STATEMENT *
+IdToQuestion (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN FORM_BROWSER_FORM *Form,
+ IN UINT16 QuestionId
+ );
+
+/**
+ Zero extend integer/boolean/date/time to UINT64 for comparing.
+
+ @param Value HII Value to be converted.
+
+**/
+VOID
+ExtendValueToU64 (
+ IN EFI_HII_VALUE *Value
+ );
+
+/**
+ Compare two Hii value.
+
+ @param Value1 Expression value to compare on left-hand.
+ @param Value2 Expression value to compare on right-hand.
+ @param Result Return value after compare.
+ retval 0 Two operators equal.
+ return Positive value if Value1 is greater than Value2.
+ retval Negative value if Value1 is less than Value2.
+ @param HiiHandle Only required for string compare.
+
+ @retval other Could not perform compare on two values.
+ @retval EFI_SUCCESS Compare the value success.
+
+**/
+EFI_STATUS
+CompareHiiValue (
+ IN EFI_HII_VALUE *Value1,
+ IN EFI_HII_VALUE *Value2,
+ OUT INTN *Result,
+ IN EFI_HII_HANDLE HiiHandle OPTIONAL
+ );
+
+/**
+ Evaluate the result of a HII expression
+
+ If Expression is NULL, then ASSERT.
+
+ @param FormSet FormSet associated with this expression.
+ @param Form Form associated with this expression.
+ @param Expression Expression to be evaluated.
+
+ @retval EFI_SUCCESS The expression evaluated successfuly
+ @retval EFI_NOT_FOUND The Question which referenced by a QuestionId
+ could not be found.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
+ stack.
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
+ @retval EFI_INVALID_PARAMETER Syntax error with the Expression
+
+**/
+EFI_STATUS
+EvaluateExpression (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN FORM_BROWSER_FORM *Form,
+ IN OUT FORM_EXPRESSION *Expression
+ );
+
+/**
+ Return the result of the expression list. Check the expression list and
+ return the highest priority express result.
+ Priority: DisableIf > SuppressIf > GrayOutIf > FALSE
+
+ @param ExpList The input expression list.
+ @param Evaluate Whether need to evaluate the expression first.
+ @param FormSet FormSet associated with this expression. Only
+ needed when Evaluate is TRUE
+ @param Form Form associated with this expression. Only
+ needed when Evaluate is TRUE
+
+ @retval EXPRESS_RESULT Return the higher priority express result.
+ DisableIf > SuppressIf > GrayOutIf > FALSE
+
+**/
+EXPRESS_RESULT
+EvaluateExpressionList (
+ IN FORM_EXPRESSION_LIST *ExpList,
+ IN BOOLEAN Evaluate,
+ IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL
+ IN FORM_BROWSER_FORM *Form OPTIONAL
+ );
+
+#endif // _UI_H
|