From 6c128c65b5ec0e5b8b5a0ccb165f3afd29e485f8 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Wed, 2 Aug 2017 09:54:47 +0800 Subject: Remove core packages since we can get them from edk2 repository Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../Universal/DisplayEngineDxe/DisplayEngine.uni | Bin 1902 -> 0 bytes .../DisplayEngineDxe/DisplayEngineDxe.inf | 66 - .../DisplayEngineDxe/DisplayEngineExtra.uni | Bin 1334 -> 0 bytes .../Universal/DisplayEngineDxe/FormDisplay.c | 4143 -------------------- .../Universal/DisplayEngineDxe/FormDisplay.h | 652 --- .../Universal/DisplayEngineDxe/FormDisplayStr.uni | Bin 17056 -> 0 bytes .../Universal/DisplayEngineDxe/InputHandler.c | 1673 -------- .../Universal/DisplayEngineDxe/ProcessOptions.c | 1475 ------- 8 files changed, 8009 deletions(-) delete mode 100644 MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngine.uni delete mode 100644 MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf delete mode 100644 MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineExtra.uni delete mode 100644 MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c delete mode 100644 MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h delete mode 100644 MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni delete mode 100644 MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c delete mode 100644 MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c (limited to 'MdeModulePkg/Universal/DisplayEngineDxe') diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngine.uni b/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngine.uni deleted file mode 100644 index 9f9d7cc790..0000000000 Binary files a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngine.uni and /dev/null differ diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf b/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf deleted file mode 100644 index bf5e8e541c..0000000000 --- a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf +++ /dev/null @@ -1,66 +0,0 @@ -## @file -# The DXE driver produces FORM DISPLAY ENGIEN protocol. -# -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which accompanies this distribution. The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = DisplayEngine - MODULE_UNI_FILE = DisplayEngine.uni - 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 ## PRODUCES - gEdkiiFormBrowserEx2ProtocolGuid ## CONSUMES - -[Depex] - gEfiHiiDatabaseProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid AND gEdkiiFormBrowserEx2ProtocolGuid - -[FeaturePcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdBrowerGrayOutReadOnlyMenu ## CONSUMES - -[UserExtensions.TianoCore."ExtraFiles"] - DisplayEngineExtra.uni diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineExtra.uni b/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineExtra.uni deleted file mode 100644 index 31b4ae2f1c..0000000000 Binary files a/MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineExtra.uni and /dev/null differ diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c deleted file mode 100644 index a391442d16..0000000000 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c +++ /dev/null @@ -1,4143 +0,0 @@ -/** @file -Entry and initialization module for the browser. - -Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.
-Copyright (c) 2014, Hewlett-Packard Development Company, L.P.
-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} -}; - -BOOLEAN gMisMatch; -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 *gReconnectConfirmChanges; -CHAR16 *gReconnectFail; -CHAR16 *gReconnectRequired; -CHAR16 *gChangesOpt; -CHAR16 *gFormNotFound; -CHAR16 *gNoSubmitIf; -CHAR16 *gBrowserError; -CHAR16 *gSaveFailed; -CHAR16 *gNoSubmitIfFailed; -CHAR16 *gSaveProcess; -CHAR16 *gSaveNoSubmitProcess; -CHAR16 *gDiscardChange; -CHAR16 *gJumpToFormSet; -CHAR16 *gCheckError; -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 *gConfirmDefaultMsg; -CHAR16 *gConfirmSubmitMsg; -CHAR16 *gConfirmDiscardMsg; -CHAR16 *gConfirmResetMsg; -CHAR16 *gConfirmExitMsg; -CHAR16 *gConfirmSubmitMsg2nd; -CHAR16 *gConfirmDefaultMsg2nd; -CHAR16 *gConfirmResetMsg2nd; -CHAR16 *gConfirmExitMsg2nd; -CHAR16 *gConfirmOpt; -CHAR16 *gConfirmOptYes; -CHAR16 *gConfirmOptNo; -CHAR16 *gConfirmMsgConnect; -CHAR16 *gConfirmMsgEnd; -CHAR16 gModalSkipColumn; -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 - ) -{ - gReconnectConfirmChanges = GetToken (STRING_TOKEN (RECONNECT_CONFIRM_CHANGES), gHiiHandle); - mUnknownString = GetToken (STRING_TOKEN (UNKNOWN_STRING), gHiiHandle); - gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle); - gNoSubmitIfFailed = GetToken (STRING_TOKEN (NO_SUBMIT_IF_CHECK_FAILED), gHiiHandle); - gReconnectFail = GetToken (STRING_TOKEN (RECONNECT_FAILED), gHiiHandle); - gReconnectRequired = GetToken (STRING_TOKEN (RECONNECT_REQUIRED), gHiiHandle); - gChangesOpt = GetToken (STRING_TOKEN (RECONNECT_CHANGES_OPTIONS), gHiiHandle); - gSaveProcess = GetToken (STRING_TOKEN (DISCARD_OR_JUMP), gHiiHandle); - gSaveNoSubmitProcess = GetToken (STRING_TOKEN (DISCARD_OR_CHECK), gHiiHandle); - gDiscardChange = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_DISCARD), gHiiHandle); - gJumpToFormSet = GetToken (STRING_TOKEN (DISCARD_OR_JUMP_JUMP), gHiiHandle); - gCheckError = GetToken (STRING_TOKEN (DISCARD_OR_CHECK_CHECK), 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); - gBrowserError = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle); - gConfirmDefaultMsg = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE), gHiiHandle); - gConfirmDiscardMsg = GetToken (STRING_TOKEN (CONFIRM_DISCARD_MESSAGE), gHiiHandle); - gConfirmSubmitMsg = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE), gHiiHandle); - gConfirmResetMsg = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE), gHiiHandle); - gConfirmExitMsg = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE), gHiiHandle); - gConfirmDefaultMsg2nd = GetToken (STRING_TOKEN (CONFIRM_DEFAULT_MESSAGE_2ND), gHiiHandle); - gConfirmSubmitMsg2nd = GetToken (STRING_TOKEN (CONFIRM_SUBMIT_MESSAGE_2ND), gHiiHandle); - gConfirmResetMsg2nd = GetToken (STRING_TOKEN (CONFIRM_RESET_MESSAGE_2ND), gHiiHandle); - gConfirmExitMsg2nd = GetToken (STRING_TOKEN (CONFIRM_EXIT_MESSAGE_2ND), gHiiHandle); - gConfirmOpt = GetToken (STRING_TOKEN (CONFIRM_OPTION), gHiiHandle); - gConfirmOptYes = GetToken (STRING_TOKEN (CONFIRM_OPTION_YES), gHiiHandle); - gConfirmOptNo = GetToken (STRING_TOKEN (CONFIRM_OPTION_NO), gHiiHandle); - gConfirmMsgConnect = GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT), gHiiHandle); - gConfirmMsgEnd = GetToken (STRING_TOKEN (CONFIRM_OPTION_END), gHiiHandle); -} - -/** - Free up the resource allocated for all strings required - by Setup Browser. - -**/ -VOID -FreeDisplayStrings ( - VOID - ) -{ - FreePool (mUnknownString); - FreePool (gEmptyString); - FreePool (gSaveFailed); - FreePool (gNoSubmitIfFailed); - FreePool (gReconnectFail); - FreePool (gReconnectRequired); - FreePool (gChangesOpt); - FreePool (gReconnectConfirmChanges); - FreePool (gSaveProcess); - FreePool (gSaveNoSubmitProcess); - FreePool (gDiscardChange); - FreePool (gJumpToFormSet); - FreePool (gCheckError); - FreePool (gPromptForData); - FreePool (gPromptForPassword); - FreePool (gPromptForNewPassword); - FreePool (gConfirmPassword); - FreePool (gConfirmError); - FreePool (gPassowordInvalid); - FreePool (gPressEnter); - FreePool (gMiniString); - FreePool (gOptionMismatch); - FreePool (gFormSuppress); - FreePool (gProtocolNotFound); - FreePool (gBrowserError); - FreePool (gNoSubmitIf); - FreePool (gFormNotFound); - FreePool (gConfirmDefaultMsg); - FreePool (gConfirmSubmitMsg); - FreePool (gConfirmDiscardMsg); - FreePool (gConfirmResetMsg); - FreePool (gConfirmExitMsg); - FreePool (gConfirmDefaultMsg2nd); - FreePool (gConfirmSubmitMsg2nd); - FreePool (gConfirmResetMsg2nd); - FreePool (gConfirmExitMsg2nd); - FreePool (gConfirmOpt); - FreePool (gConfirmOptYes); - FreePool (gConfirmOptNo); - FreePool (gConfirmMsgConnect); - FreePool (gConfirmMsgEnd); -} - -/** - 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 MenuOption The menu option. - @param AdjustWidth The width which is saved for the space. - - @return Returns the number of CHAR16 characters that is support. - -**/ -UINT16 -GetWidth ( - IN UI_MENU_OPTION *MenuOption, - OUT UINT16 *AdjustWidth - ) -{ - CHAR16 *String; - UINTN Size; - EFI_IFR_TEXT *TestOp; - UINT16 ReturnWidth; - FORM_DISPLAY_ENGINE_STATEMENT *Statement; - - Statement = MenuOption->ThisTag; - - // - // For modal form, clean the entire row. - // - if ((gFormData->Attribute & HII_DISPLAY_MODAL) != 0) { - if (AdjustWidth != NULL) { - *AdjustWidth = LEFT_SKIPPED_COLUMNS; - } - return (UINT16)(gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * (gModalSkipColumn + LEFT_SKIPPED_COLUMNS)); - } - - 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)) - ) { - - // - // Return the space width. - // - if (AdjustWidth != NULL) { - *AdjustWidth = 2; - } - // - // Keep consistent with current behavior. - // - ReturnWidth = (UINT16) (gPromptBlockWidth + gOptionBlockWidth - 2); - } else { - if (AdjustWidth != NULL) { - *AdjustWidth = 1; - } - - ReturnWidth = (UINT16) (gPromptBlockWidth - 1); - } - - // - // For nest in statement, should the subtitle indent. - // - if (MenuOption->NestInStatement) { - ReturnWidth -= SUBTITLE_INDENT; - } - - return ReturnWidth; -} - -/** - 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); - - if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) { - 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; - - 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; - } - } - - if (Index == 0 && - (Statement->OpCode->OpCode != EFI_IFR_DATE_OP) && - (Statement->OpCode->OpCode != EFI_IFR_TIME_OP)) { - Width = GetWidth (MenuOption, NULL); - 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); - } - } else { - // - // Add three MenuOptions for Date/Time - // Data format : [01/02/2004] [11:22:33] - // Line number : 0 0 1 0 0 1 - // - NumberOfLines = 0; - } - - if (Index == 2) { - // - // Override LineNumber for the MenuOption in Date/Time sequence - // - MenuOption->Skip = 1; - } else { - MenuOption->Skip = NumberOfLines; - } - - 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); - - // - // Skip the opcode not recognized by Display core. - // - if (NestStatement->OpCode->OpCode == EFI_IFR_GUID_OP) { - continue; - } - - 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 print. - - Check Prompt string, option string or text two string not NULL. - - This is an internal function. - - @param MenuOption The MenuOption to be checked. - - @retval TRUE This Menu Option is printable. - @retval FALSE This Menu Option could not be printable. - -**/ -BOOLEAN -PrintableMenu ( - UI_MENU_OPTION *MenuOption - ) -{ - EFI_STATUS Status; - EFI_STRING OptionString; - - OptionString = NULL; - - if (MenuOption->Description[0] != '\0') { - return TRUE; - } - - Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE); - if (EFI_ERROR (Status)) { - return FALSE; - } - if (OptionString != NULL && OptionString[0] != '\0') { - FreePool (OptionString); - return TRUE; - } - - 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); - ASSERT (OptionString != NULL); - if (OptionString[0] != '\0'){ - FreePool (OptionString); - return TRUE; - } - } - - return FALSE; -} - -/** - 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 || !PrintableMenu (MenuOption)) { - 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. - @param FindInForm Whether find menu in current form or beyond. - - @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 - first menu showing beyond current form or last menu showing in - current form. - The value is the line number between the new selected menu and the - current select menu, not include the new selected menu. - -**/ -INTN -MoveToNextStatement ( - IN BOOLEAN GoUp, - IN OUT LIST_ENTRY **CurrentPosition, - IN UINTN GapToTop, - IN BOOLEAN FindInForm - ) -{ - INTN Distance; - LIST_ENTRY *Pos; - UI_MENU_OPTION *NextMenuOption; - UI_MENU_OPTION *PreMenuOption; - - Distance = 0; - Pos = *CurrentPosition; - - if (Pos == &gMenuOption) { - return -1; - } - - 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 (IsSelectable (NextMenuOption)) { - break; - } - - // - // In this case, still can't find the selectable menu, - // return the first one beyond the showing form. - // - if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) { - if (FindInForm) { - NextMenuOption = PreMenuOption; - } - break; - } - - Distance += NextMenuOption->Skip; - - // - // Arrive at begin of the menu list. - // - if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) { - Distance = -1; - break; - } - - Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink); - PreMenuOption = NextMenuOption; - } - - *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 top of screen menu base on the current menu. - - @param CurPos Current input menu. - @param Rows Totol screen rows. - @param SkipValue SkipValue for this new form. - - @retval TopOfScreen Top of screen menu for the new form. - -**/ -LIST_ENTRY * -FindTopOfScreenMenu ( - IN LIST_ENTRY *CurPos, - IN UINTN Rows, - OUT UINTN *SkipValue - ) -{ - LIST_ENTRY *Link; - LIST_ENTRY *TopOfScreen; - UI_MENU_OPTION *PreviousMenuOption; - - Link = CurPos; - PreviousMenuOption = NULL; - - while (Link->BackLink != &gMenuOption) { - Link = Link->BackLink; - PreviousMenuOption = MENU_OPTION_FROM_LINK (Link); - if (PreviousMenuOption->Row == 0) { - UpdateOptionSkipLines (PreviousMenuOption); - } - if (Rows <= PreviousMenuOption->Skip) { - break; - } - Rows = Rows - PreviousMenuOption->Skip; - } - - if (Link->BackLink == &gMenuOption) { - TopOfScreen = gMenuOption.ForwardLink; - if (PreviousMenuOption != NULL && Rows < PreviousMenuOption->Skip) { - *SkipValue = PreviousMenuOption->Skip - Rows; - } else { - *SkipValue = 0; - } - } else { - TopOfScreen = Link; - *SkipValue = PreviousMenuOption->Skip - Rows; - } - - return TopOfScreen; -} - -/** - Get the index info for this opcode. - - @param OpCode The input opcode for the statement. - - @retval The index of this statement. - -**/ -UINTN -GetIndexInfoForOpcode ( - IN EFI_IFR_OP_HEADER *OpCode - ) -{ - LIST_ENTRY *NewPos; - UI_MENU_OPTION *MenuOption; - UINTN Index; - - NewPos = gMenuOption.ForwardLink; - Index = 0; - - for (NewPos = gMenuOption.ForwardLink; NewPos != &gMenuOption; NewPos = NewPos->ForwardLink){ - MenuOption = MENU_OPTION_FROM_LINK (NewPos); - - if (CompareMem (MenuOption->ThisTag->OpCode, OpCode, OpCode->Length) == 0) { - if (MenuOption->ThisTag->OpCode == OpCode) { - return Index; - } - - Index ++; - } - } - - return Index; -} - -/** - Is this the saved highlight statement. - - @param HighLightedStatement The input highlight statement. - - @retval TRUE This is the highlight statement. - @retval FALSE This is not the highlight statement. - -**/ -BOOLEAN -IsSavedHighlightStatement ( - IN FORM_DISPLAY_ENGINE_STATEMENT *HighLightedStatement - ) -{ - if ((gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) && - (gFormData->FormId == gHighligthMenuInfo.FormId)) { - if (gHighligthMenuInfo.HLTQuestionId != 0) { - return (BOOLEAN) (gHighligthMenuInfo.HLTQuestionId == GetQuestionIdInfo (HighLightedStatement->OpCode)); - } else { - if (CompareMem (gHighligthMenuInfo.HLTOpCode, HighLightedStatement->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) { - if (gHighligthMenuInfo.HLTIndex == 0 || gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode(HighLightedStatement->OpCode)) { - return TRUE; - } else { - return FALSE; - } - } - } - } - - return FALSE; -} - -/** - Is this the highlight menu. - - @param MenuOption The input Menu option. - - @retval TRUE This is the highlight menu option. - @retval FALSE This is not the highlight menu option. - -**/ -BOOLEAN -IsHighLightMenuOption ( - IN UI_MENU_OPTION *MenuOption - ) -{ - if (gHighligthMenuInfo.HLTQuestionId != 0) { - if (GetQuestionIdInfo(MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.HLTQuestionId) { - return (BOOLEAN) (MenuOption->Sequence == gHighligthMenuInfo.HLTSequence); - } - } else { - if(CompareMem (gHighligthMenuInfo.HLTOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.HLTOpCode->Length) == 0) { - if (gHighligthMenuInfo.HLTIndex == 0 || gHighligthMenuInfo.HLTIndex == GetIndexInfoForOpcode(MenuOption->ThisTag->OpCode)) { - return (BOOLEAN) (MenuOption->Sequence == gHighligthMenuInfo.HLTSequence); - } else { - return FALSE; - } - } - } - - return FALSE; -} - -/** - Find the highlight menu. - - If the input is NULL, base on the record highlight info in - gHighligthMenuInfo to find the last highlight menu. - - @param HighLightedStatement The input highlight statement. - - @retval The highlight menu index. - -**/ -LIST_ENTRY * -FindHighLightMenuOption ( - IN FORM_DISPLAY_ENGINE_STATEMENT *HighLightedStatement - ) -{ - LIST_ENTRY *NewPos; - UI_MENU_OPTION *MenuOption; - - NewPos = gMenuOption.ForwardLink; - MenuOption = MENU_OPTION_FROM_LINK (NewPos); - - if (HighLightedStatement != NULL) { - while (MenuOption->ThisTag != HighLightedStatement) { - NewPos = NewPos->ForwardLink; - if (NewPos == &gMenuOption) { - // - // Not Found it, break - // - break; - } - MenuOption = MENU_OPTION_FROM_LINK (NewPos); - } - - // - // Must find the highlight statement. - // - ASSERT (NewPos != &gMenuOption); - - } else { - while (!IsHighLightMenuOption (MenuOption)) { - NewPos = NewPos->ForwardLink; - if (NewPos == &gMenuOption) { - // - // Not Found it, break - // - break; - } - MenuOption = MENU_OPTION_FROM_LINK (NewPos); - } - - // - // Highlight statement has disappear (suppressed/disableed) - // - if (NewPos == &gMenuOption) { - NewPos = NULL; - } - } - - return NewPos; -} - -/** - Is this the Top of screen menu. - - @param MenuOption The input Menu option. - - @retval TRUE This is the Top of screen menu option. - @retval FALSE This is not the Top of screen menu option. - -**/ -BOOLEAN -IsTopOfScreeMenuOption ( - IN UI_MENU_OPTION *MenuOption - ) -{ - if (gHighligthMenuInfo.TOSQuestionId != 0) { - return (BOOLEAN) (GetQuestionIdInfo(MenuOption->ThisTag->OpCode) == gHighligthMenuInfo.TOSQuestionId); - } - - if(CompareMem (gHighligthMenuInfo.TOSOpCode, MenuOption->ThisTag->OpCode, gHighligthMenuInfo.TOSOpCode->Length) == 0) { - if (gHighligthMenuInfo.TOSIndex == 0 || gHighligthMenuInfo.TOSIndex == GetIndexInfoForOpcode(MenuOption->ThisTag->OpCode)) { - return TRUE; - } else { - return FALSE; - } - } - - return FALSE; -} - -/** - Find the Top of screen menu. - - If the input is NULL, base on the record highlight info in - gHighligthMenuInfo to find the last highlight menu. - - @param HighLightedStatement The input highlight statement. - - @retval The highlight menu index. - -**/ -LIST_ENTRY * -FindTopOfScreenMenuOption ( - VOID - ) -{ - LIST_ENTRY *NewPos; - UI_MENU_OPTION *MenuOption; - - NewPos = gMenuOption.ForwardLink; - MenuOption = MENU_OPTION_FROM_LINK (NewPos); - - while (!IsTopOfScreeMenuOption(MenuOption)) { - NewPos = NewPos->ForwardLink; - if (NewPos == &gMenuOption) { - // - // Not Found it, break - // - break; - } - MenuOption = MENU_OPTION_FROM_LINK (NewPos); - } - - // - // Last time top of screen menu has disappeared. - // - if (NewPos == &gMenuOption) { - NewPos = NULL; - } - - return NewPos; -} - -/** - 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 UINTN *SkipValue - ) -{ - UINTN TopRow; - UINTN BottomRow; - UI_MENU_OPTION *MenuOption; - UINTN TmpValue; - - TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT; - BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT; - // - // When option mismatch happens,there exist two cases,one is reenter the form, just like the if case below, - // and the other is exit current form and enter last form, it can be covered by the else case. - // - if (gMisMatch && gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle && gFormData->FormId == gHighligthMenuInfo.FormId) { - // - // Reenter caused by option mismatch or auto exit caused by refresh form(refresh interval/guid), - // base on the record highlight info to find the highlight menu. - // - - *HighlightMenu = FindHighLightMenuOption(NULL); - if (*HighlightMenu != NULL) { - // - // Update skip info for this highlight menu. - // - MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu); - UpdateOptionSkipLines (MenuOption); - - // - // Found the last time highlight menu. - // - *TopOfScreen = FindTopOfScreenMenuOption(); - if (*TopOfScreen != NULL) { - // - // Found the last time selectable top of screen menu. - // - AdjustDateAndTimePosition(TRUE, TopOfScreen); - MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen); - UpdateOptionSkipLines (MenuOption); - - *SkipValue = gHighligthMenuInfo.SkipValue; - } else { - // - // Not found last time top of screen menu, so base on current highlight menu - // to find the new top of screen menu. - // Make the current highlight menu at the bottom of the form to calculate the - // top of screen menu. - // - if (MenuOption->Skip >= BottomRow - TopRow) { - *TopOfScreen = *HighlightMenu; - TmpValue = 0; - } else { - *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue); - } - - *SkipValue = TmpValue; - } - } else { - // - // Last time highlight menu has disappear, find the first highlightable menu as the defalut one. - // - *HighlightMenu = gMenuOption.ForwardLink; - if (!IsListEmpty (&gMenuOption)) { - MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE); - } - *TopOfScreen = gMenuOption.ForwardLink; - *SkipValue = 0; - } - - } else if (FormData->HighLightedStatement != NULL) { - if (IsSavedHighlightStatement (FormData->HighLightedStatement)) { - // - // Input highlight menu is same as last time highlight menu. - // Base on last time highlight menu to set the top of screen menu and highlight menu. - // - *HighlightMenu = FindHighLightMenuOption(NULL); - ASSERT (*HighlightMenu != NULL); - - // - // Update skip info for this highlight menu. - // - MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu); - UpdateOptionSkipLines (MenuOption); - - *TopOfScreen = FindTopOfScreenMenuOption(); - if (*TopOfScreen == NULL) { - // - // Not found last time top of screen menu, so base on current highlight menu - // to find the new top of screen menu. - // Make the current highlight menu at the bottom of the form to calculate the - // top of screen menu. - // - if (MenuOption->Skip >= BottomRow - TopRow) { - *TopOfScreen = *HighlightMenu; - TmpValue = 0; - } else { - *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue); - } - - *SkipValue = TmpValue; - } else { - AdjustDateAndTimePosition(TRUE, TopOfScreen); - MenuOption = MENU_OPTION_FROM_LINK (*TopOfScreen); - UpdateOptionSkipLines (MenuOption); - - *SkipValue = gHighligthMenuInfo.SkipValue; - } - AdjustDateAndTimePosition(TRUE, TopOfScreen); - } else { - // - // Input highlight menu is not save as last time highlight menu. - // - *HighlightMenu = FindHighLightMenuOption(FormData->HighLightedStatement); - MenuOption = MENU_OPTION_FROM_LINK (*HighlightMenu); - UpdateOptionSkipLines (MenuOption); - - // - // Make the current highlight menu at the bottom of the form to calculate the - // top of screen menu. - // - if (MenuOption->Skip >= BottomRow - TopRow) { - *TopOfScreen = *HighlightMenu; - TmpValue = 0; - } else { - *TopOfScreen = FindTopOfScreenMenu(*HighlightMenu, BottomRow - TopRow - MenuOption->Skip, &TmpValue); - } - - *SkipValue = TmpValue; - } - AdjustDateAndTimePosition(TRUE, TopOfScreen); - } else { - // - // If not has input highlight statement, just return the first one in this form. - // - *TopOfScreen = gMenuOption.ForwardLink; - *HighlightMenu = gMenuOption.ForwardLink; - if (!IsListEmpty (&gMenuOption)) { - MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow, TRUE); - } - *SkipValue = 0; - } - - gMisMatch = FALSE; - - // - // First enter to show the menu, update highlight info. - // - UpdateHighlightMenuInfo (*HighlightMenu, *TopOfScreen, *SkipValue); -} - -/** - Record the highlight menu and top of screen menu info. - - @param Highlight The menu opton which is highlight. - @param TopOfScreen The menu opton which is at the top of the form. - @param SkipValue The skip line info for the top of screen menu. - -**/ -VOID -UpdateHighlightMenuInfo ( - IN LIST_ENTRY *Highlight, - IN LIST_ENTRY *TopOfScreen, - IN UINTN SkipValue - ) -{ - UI_MENU_OPTION *MenuOption; - FORM_DISPLAY_ENGINE_STATEMENT *Statement; - - gHighligthMenuInfo.HiiHandle = gFormData->HiiHandle; - gHighligthMenuInfo.FormId = gFormData->FormId; - gHighligthMenuInfo.SkipValue = (UINT16)SkipValue; - - if (!IsListEmpty (&gMenuOption)) { - MenuOption = MENU_OPTION_FROM_LINK (Highlight); - Statement = MenuOption->ThisTag; - - gUserInput->SelectedStatement = Statement; - - gHighligthMenuInfo.HLTSequence = MenuOption->Sequence; - gHighligthMenuInfo.HLTQuestionId = GetQuestionIdInfo(Statement->OpCode); - if (gHighligthMenuInfo.HLTQuestionId == 0) { - // - // if question id == 0, save the opcode buffer.. - // - if (gHighligthMenuInfo.HLTOpCode != NULL) { - FreePool (gHighligthMenuInfo.HLTOpCode); - } - gHighligthMenuInfo.HLTOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode); - ASSERT (gHighligthMenuInfo.HLTOpCode != NULL); - - gHighligthMenuInfo.HLTIndex = GetIndexInfoForOpcode(Statement->OpCode); - } - - MenuOption = MENU_OPTION_FROM_LINK (TopOfScreen); - Statement = MenuOption->ThisTag; - - gHighligthMenuInfo.TOSQuestionId = GetQuestionIdInfo(Statement->OpCode); - if (gHighligthMenuInfo.TOSQuestionId == 0) { - // - // if question id == 0, save the opcode buffer.. - // - if (gHighligthMenuInfo.TOSOpCode != NULL) { - FreePool (gHighligthMenuInfo.TOSOpCode); - } - gHighligthMenuInfo.TOSOpCode = AllocateCopyPool (Statement->OpCode->Length, Statement->OpCode); - ASSERT (gHighligthMenuInfo.TOSOpCode != NULL); - - gHighligthMenuInfo.TOSIndex = GetIndexInfoForOpcode(Statement->OpCode); - } - } else { - gUserInput->SelectedStatement = NULL; - - gHighligthMenuInfo.HLTSequence = 0; - gHighligthMenuInfo.HLTQuestionId = 0; - if (gHighligthMenuInfo.HLTOpCode != NULL) { - FreePool (gHighligthMenuInfo.HLTOpCode); - } - gHighligthMenuInfo.HLTOpCode = NULL; - gHighligthMenuInfo.HLTIndex = 0; - - gHighligthMenuInfo.TOSQuestionId = 0; - if (gHighligthMenuInfo.TOSOpCode != NULL) { - FreePool (gHighligthMenuInfo.TOSOpCode); - } - gHighligthMenuInfo.TOSOpCode = NULL; - gHighligthMenuInfo.TOSIndex = 0; - } -} - -/** - Update attribut for this menu. - - @param MenuOption The menu opton which this attribut used to. - @param Highlight Whether this menu will be highlight. - -**/ -VOID -SetDisplayAttribute ( - IN UI_MENU_OPTION *MenuOption, - IN BOOLEAN Highlight - ) -{ - FORM_DISPLAY_ENGINE_STATEMENT *Statement; - - Statement = MenuOption->ThisTag; - - if (Highlight) { - gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ()); - return; - } - - if (MenuOption->GrayOut) { - gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ()); - } else { - if (Statement->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) { - gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ()); - } else { - gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ()); - } - } -} - -/** - Print string for this menu option. - - @param MenuOption The menu opton which this attribut used to. - @param Col The column that this string will be print at. - @param Row The row that this string will be print at. - @param String The string which need to print. - @param Width The width need to print, if string is less than the - width, the block space will be used. - @param Highlight Whether this menu will be highlight. - -**/ -VOID -DisplayMenuString ( - IN UI_MENU_OPTION *MenuOption, - IN UINTN Col, - IN UINTN Row, - IN CHAR16 *String, - IN UINTN Width, - IN BOOLEAN Highlight - ) -{ - UINTN Length; - - // - // Print string with normal color. - // - if (!Highlight) { - PrintStringAtWithWidth (Col, Row, String, Width); - return; - } - - // - // Print the highlight menu string. - // First print the highlight string. - // - SetDisplayAttribute(MenuOption, TRUE); - Length = PrintStringAt (Col, Row, String); - - // - // Second, clean the empty after the string. - // - SetDisplayAttribute(MenuOption, FALSE); - PrintStringAtWithWidth (Col + Length, Row, L"", Width - Length); -} - -/** - Check whether this menu can has option string. - - @param MenuOption The menu opton which this attribut used to. - - @retval TRUE This menu option can have option string. - @retval FALSE This menu option can't have option string. - -**/ -BOOLEAN -HasOptionString ( - IN UI_MENU_OPTION *MenuOption - ) -{ - FORM_DISPLAY_ENGINE_STATEMENT *Statement; - CHAR16 *String; - UINTN Size; - EFI_IFR_TEXT *TestOp; - - Size = 0; - Statement = MenuOption->ThisTag; - - // - // 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)) - ) { - - return FALSE; - } - - return TRUE; -} - -/** - Double confirm with user about the action. - - @param Action The user input action. - - @retval TRUE User confirm with the input or not need user confirm. - @retval FALSE User want ignore this input. - -**/ -BOOLEAN -FxConfirmPopup ( - IN UINT32 Action - ) -{ - EFI_INPUT_KEY Key; - CHAR16 *CfmStr; - UINTN CfmStrLen; - UINT32 CheckFlags; - BOOLEAN RetVal; - UINTN CatLen; - UINTN MaxLen; - - CfmStrLen = 0; - CatLen = StrLen (gConfirmMsgConnect); - - // - // Below action need extra popup dialog to confirm. - // - CheckFlags = BROWSER_ACTION_DISCARD | - BROWSER_ACTION_DEFAULT | - BROWSER_ACTION_SUBMIT | - BROWSER_ACTION_RESET | - BROWSER_ACTION_EXIT; - - // - // Not need to confirm with user, just return TRUE. - // - if ((Action & CheckFlags) == 0) { - return TRUE; - } - - if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) { - CfmStrLen += StrLen (gConfirmDiscardMsg); - } - - if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) { - if (CfmStrLen != 0) { - CfmStrLen += CatLen; - } - - CfmStrLen += StrLen (gConfirmDefaultMsg); - } - - if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) { - if (CfmStrLen != 0) { - CfmStrLen += CatLen; - } - - CfmStrLen += StrLen (gConfirmSubmitMsg); - } - - if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) { - if (CfmStrLen != 0) { - CfmStrLen += CatLen; - } - - CfmStrLen += StrLen (gConfirmResetMsg); - } - - if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) { - if (CfmStrLen != 0) { - CfmStrLen += CatLen; - } - - CfmStrLen += StrLen (gConfirmExitMsg); - } - - // - // Allocate buffer to save the string. - // String + "?" + "\0" - // - MaxLen = CfmStrLen + 1 + 1; - CfmStr = AllocateZeroPool (MaxLen * sizeof (CHAR16)); - ASSERT (CfmStr != NULL); - - if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) { - StrCpyS (CfmStr, MaxLen, gConfirmDiscardMsg); - } - - if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) { - if (CfmStr[0] != 0) { - StrCatS (CfmStr, MaxLen, gConfirmMsgConnect); - StrCatS (CfmStr, MaxLen, gConfirmDefaultMsg2nd); - } else { - StrCpyS (CfmStr, MaxLen, gConfirmDefaultMsg); - } - } - - if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) { - if (CfmStr[0] != 0) { - StrCatS (CfmStr, MaxLen, gConfirmMsgConnect); - StrCatS (CfmStr, MaxLen, gConfirmSubmitMsg2nd); - } else { - StrCpyS (CfmStr, MaxLen, gConfirmSubmitMsg); - } - } - - if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) { - if (CfmStr[0] != 0) { - StrCatS (CfmStr, MaxLen, gConfirmMsgConnect); - StrCatS (CfmStr, MaxLen, gConfirmResetMsg2nd); - } else { - StrCpyS (CfmStr, MaxLen, gConfirmResetMsg); - } - } - - if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) { - if (CfmStr[0] != 0) { - StrCatS (CfmStr, MaxLen, gConfirmMsgConnect); - StrCatS (CfmStr, MaxLen, gConfirmExitMsg2nd); - } else { - StrCpyS (CfmStr, MaxLen, gConfirmExitMsg); - } - } - - StrCatS (CfmStr, MaxLen, gConfirmMsgEnd); - - do { - CreateDialog (&Key, gEmptyString, CfmStr, gConfirmOpt, gEmptyString, NULL); - } while (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) && - ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (gConfirmOptNo[0] | UPPER_LOWER_CASE_OFFSET)) && - (Key.ScanCode != SCAN_ESC)); - - if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (gConfirmOptYes[0] | UPPER_LOWER_CASE_OFFSET)) { - RetVal = TRUE; - } else { - RetVal = FALSE; - } - - FreePool (CfmStr); - - return RetVal; -} - -/** - Print string for this menu option. - - @param MenuOption The menu opton which this attribut used to. - @param SkipWidth The skip width between the left to the start of the prompt. - @param BeginCol The begin column for one menu. - @param SkipLine The skip line for this menu. - @param BottomRow The bottom row for this form. - @param Highlight Whether this menu will be highlight. - @param UpdateCol Whether need to update the column info for Date/Time. - - @retval EFI_SUCESSS Process the user selection success. - -**/ -EFI_STATUS -DisplayOneMenu ( - IN UI_MENU_OPTION *MenuOption, - IN UINTN SkipWidth, - IN UINTN BeginCol, - IN UINTN SkipLine, - IN UINTN BottomRow, - IN BOOLEAN Highlight, - IN BOOLEAN UpdateCol - ) -{ - FORM_DISPLAY_ENGINE_STATEMENT *Statement; - UINTN Index; - UINT16 Width; - UINT16 PromptWidth; - CHAR16 *StringPtr; - CHAR16 *OptionString; - CHAR16 *OutputString; - UINT16 GlyphWidth; - UINTN Temp; - UINTN Temp2; - UINTN Temp3; - EFI_STATUS Status; - UINTN Row; - BOOLEAN IsProcessingFirstRow; - UINTN Col; - UINTN PromptLineNum; - UINTN OptionLineNum; - CHAR16 AdjustValue; - UINTN MaxRow; - - Statement = MenuOption->ThisTag; - Temp = SkipLine; - Temp2 = SkipLine; - Temp3 = SkipLine; - AdjustValue = 0; - PromptLineNum = 0; - OptionLineNum = 0; - MaxRow = 0; - IsProcessingFirstRow = TRUE; - - // - // Set default color. - // - SetDisplayAttribute (MenuOption, FALSE); - - // - // 1. Paint the option string. - // - Status = ProcessOptions (MenuOption, FALSE, &OptionString, FALSE); - if (EFI_ERROR (Status)) { - return Status; - } - - if (OptionString != NULL) { - if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) { - // - // Adjust option string for date/time opcode. - // - ProcessStringForDateTime(MenuOption, OptionString, UpdateCol); - } - - Width = (UINT16) gOptionBlockWidth - 1; - Row = MenuOption->Row; - GlyphWidth = 1; - OptionLineNum = 0; - - for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) { - if (((Temp2 == 0)) && (Row <= BottomRow)) { - if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) { - // - // For date/time question, it has three menu options for this qustion. - // The first/second menu options with the skip value is 0. the last one - // with skip value is 1. - // - if (MenuOption->Skip != 0) { - // - // For date/ time, print the last past (year for date and second for time) - // - 7 means skip [##/##/ for date and [##:##: for time. - // - DisplayMenuString (MenuOption,MenuOption->OptCol, Row, OutputString, Width + 1 - 7, Highlight); - } else { - // - // For date/ time, print the first and second past (year for date and second for time) - // The OutputString has a NARROW_CHAR or WIDE_CHAR at the begin of the string, - // so need to - 1 to remove it, otherwise, it will clean 1 extr char follow it. - DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, StrLen (OutputString) - 1, Highlight); - } - } else { - DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight); - } - OptionLineNum++; - } - - // - // 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 - MenuOption->Row) >= MenuOption->Skip) { - MenuOption->Skip++; - } - } - } - - FreePool (OutputString); - if (Temp2 != 0) { - Temp2--; - } - } - - Highlight = FALSE; - - FreePool (OptionString); - } - - // - // 2. Paint the description. - // - PromptWidth = GetWidth (MenuOption, &AdjustValue); - Row = MenuOption->Row; - GlyphWidth = 1; - PromptLineNum = 0; - - if (MenuOption->Description == NULL || MenuOption->Description[0] == '\0') { - PrintStringAtWithWidth (BeginCol, Row, L"", PromptWidth + AdjustValue + SkipWidth); - PromptLineNum++; - } else { - for (Index = 0; GetLineByWidth (MenuOption->Description, PromptWidth, &GlyphWidth, &Index, &OutputString) != 0x0000;) { - if ((Temp == 0) && (Row <= BottomRow)) { - // - // 1.Clean the start LEFT_SKIPPED_COLUMNS - // - PrintStringAtWithWidth (BeginCol, Row, L"", SkipWidth); - - if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2 && IsProcessingFirstRow) { - // - // Print Arrow for Goto button. - // - PrintCharAt ( - MenuOption->Col - 2, - Row, - GEOMETRICSHAPE_RIGHT_TRIANGLE - ); - IsProcessingFirstRow = FALSE; - } - DisplayMenuString (MenuOption, MenuOption->Col, Row, OutputString, PromptWidth + AdjustValue, Highlight); - PromptLineNum ++; - } - // - // 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--; - } - } - - Highlight = FALSE; - } - - - // - // 3. 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 - 1; - Row = MenuOption->Row; - GlyphWidth = 1; - OptionLineNum = 0; - - for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) { - if ((Temp3 == 0) && (Row <= BottomRow)) { - DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, Width + 1, Highlight); - OptionLineNum++; - } - // - // 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++; - // - // If the rows for text two is greater than or equal to the skip value, increase the skip value - // - if ((Row - MenuOption->Row) >= MenuOption->Skip) { - MenuOption->Skip++; - } - } - } - - FreePool (OutputString); - if (Temp3 != 0) { - Temp3--; - } - } - - FreePool (StringPtr); - } - - // - // 4.Line number for Option string and prompt string are not equal. - // Clean the column whose line number is less. - // - if (HasOptionString(MenuOption) && (OptionLineNum != PromptLineNum)) { - Col = OptionLineNum < PromptLineNum ? MenuOption->OptCol : BeginCol; - Row = (OptionLineNum < PromptLineNum ? OptionLineNum : PromptLineNum) + MenuOption->Row; - Width = (UINT16) (OptionLineNum < PromptLineNum ? gOptionBlockWidth : PromptWidth + AdjustValue + SkipWidth); - MaxRow = (OptionLineNum < PromptLineNum ? PromptLineNum : OptionLineNum) + MenuOption->Row - 1; - - while (Row <= MaxRow) { - DisplayMenuString (MenuOption, Col, Row++, L"", Width, FALSE); - } - } - - return EFI_SUCCESS; -} - -/** - 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 - ) -{ - UINTN SkipValue; - INTN Difference; - UINTN DistanceValue; - UINTN Row; - UINTN Col; - UINTN Temp; - UINTN Temp2; - UINTN TopRow; - UINTN BottomRow; - UINTN Index; - CHAR16 *StringPtr; - CHAR16 *StringRightPtr; - CHAR16 *StringErrorPtr; - CHAR16 *OptionString; - 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_CONTROL_FLAG ControlFlag; - UI_SCREEN_OPERATION ScreenOperation; - FORM_DISPLAY_ENGINE_STATEMENT *Statement; - BROWSER_HOT_KEY *HotKey; - UINTN HelpPageIndex; - UINTN HelpPageCount; - UINTN RowCount; - UINTN HelpLine; - UINTN HelpHeaderLine; - UINTN HelpBottomLine; - BOOLEAN MultiHelpPage; - UINT16 EachLineWidth; - UINT16 HeaderLineWidth; - UINT16 BottomLineWidth; - EFI_STRING_ID HelpInfo; - UI_EVENT_TYPE EventType; - BOOLEAN SkipHighLight; - EFI_HII_VALUE *StatementValue; - - EventType = UIEventNone; - Status = EFI_SUCCESS; - HelpString = NULL; - HelpHeaderString = NULL; - HelpBottomString = NULL; - OptionString = NULL; - ScreenOperation = UiNoOperation; - NewLine = TRUE; - HelpPageCount = 0; - HelpLine = 0; - RowCount = 0; - HelpBottomLine = 0; - HelpHeaderLine = 0; - HelpPageIndex = 0; - MultiHelpPage = FALSE; - EachLineWidth = 0; - HeaderLineWidth = 0; - BottomLineWidth = 0; - UpArrow = FALSE; - DownArrow = FALSE; - SkipValue = 0; - SkipHighLight = FALSE; - - NextMenuOption = NULL; - SavedMenuOption = NULL; - HotKey = NULL; - Repaint = TRUE; - MenuOption = NULL; - gModalSkipColumn = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6; - - ZeroMem (&Key, sizeof (EFI_INPUT_KEY)); - - 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 + gModalSkipColumn; - } else { - Col = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS; - } - - FindTopMenu(FormData, &TopOfScreen, &NewPos, &SkipValue); - if (!IsListEmpty (&gMenuOption)) { - NextMenuOption = MENU_OPTION_FROM_LINK (NewPos); - gUserInput->SelectedStatement = NextMenuOption->ThisTag; - } - - gST->ConOut->EnableCursor (gST->ConOut, FALSE); - - ControlFlag = CfInitialization; - while (TRUE) { - switch (ControlFlag) { - case CfInitialization: - if ((gOldFormEntry.HiiHandle != FormData->HiiHandle) || - (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))) { - // - // Clear Statement range if different formset is painted. - // - ClearLines ( - gStatementDimensions.LeftColumn, - gStatementDimensions.RightColumn, - TopRow - SCROLL_ARROW_HEIGHT, - BottomRow + SCROLL_ARROW_HEIGHT, - GetFieldTextColor () - ); - - } - ControlFlag = CfRepaint; - break; - - case CfRepaint: - ControlFlag = CfRefreshHighLight; - - if (Repaint) { - // - // Display menu - // - DownArrow = FALSE; - UpArrow = FALSE; - Row = TopRow; - - gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ()); - - // - // 1. Check whether need to print the arrow up. - // - if (!ValueIsScroll (TRUE, TopOfScreen)) { - UpArrow = TRUE; - } - - if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { - PrintStringAtWithWidth(gStatementDimensions.LeftColumn + gModalSkipColumn, TopRow - 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * gModalSkipColumn); - } else { - PrintStringAtWithWidth(gStatementDimensions.LeftColumn, TopRow - 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn); - } - 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 ()); - } - - // - // 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 = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gPromptBlockWidth + gModalSkipColumn; - } else { - MenuOption->OptCol = gStatementDimensions.LeftColumn + LEFT_SKIPPED_COLUMNS + gPromptBlockWidth; - } - - if (MenuOption->NestInStatement) { - MenuOption->Col += SUBTITLE_INDENT; - } - - // - // Save the highlight menu, will be used in CfRefreshHighLight case. - // - if (Link == NewPos) { - SavedMenuOption = MenuOption; - SkipHighLight = TRUE; - } - - if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { - Status = DisplayOneMenu (MenuOption, - MenuOption->Col - gStatementDimensions.LeftColumn, - gStatementDimensions.LeftColumn + gModalSkipColumn, - Link == TopOfScreen ? SkipValue : 0, - BottomRow, - (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption)), - TRUE - ); - } else { - Status = DisplayOneMenu (MenuOption, - MenuOption->Col - gStatementDimensions.LeftColumn, - gStatementDimensions.LeftColumn, - Link == TopOfScreen ? SkipValue : 0, - BottomRow, - (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption)), - TRUE - ); - } - - if (EFI_ERROR (Status)) { - if (gMisMatch) { - return EFI_SUCCESS; - } else { - return Status; - } - } - // - // 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; - } - } - - // - // 3. Menus in this form may not cover all form, clean the remain field. - // - while (Row <= BottomRow) { - if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { - PrintStringAtWithWidth(gStatementDimensions.LeftColumn + gModalSkipColumn, Row++, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * gModalSkipColumn); - } else { - PrintStringAtWithWidth(gStatementDimensions.LeftColumn, Row++, L"", gStatementDimensions.RightColumn - gHelpBlockWidth - gStatementDimensions.LeftColumn); - } - } - - // - // 4. Print the down arrow row. - // - if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { - PrintStringAtWithWidth(gStatementDimensions.LeftColumn + gModalSkipColumn, BottomRow + 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * + gModalSkipColumn); - } else { - PrintStringAtWithWidth(gStatementDimensions.LeftColumn, BottomRow + 1, L"", gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn); - } - 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; - - UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); - - if (SkipHighLight) { - SkipHighLight = FALSE; - MenuOption = SavedMenuOption; - RefreshKeyHelp(gFormData, SavedMenuOption->ThisTag, FALSE); - break; - } - - if (IsListEmpty (&gMenuOption)) { - // - // No menu option, just update the hotkey filed. - // - RefreshKeyHelp(gFormData, NULL, FALSE); - break; - } - - 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 the old highlight menu. - // - Status = DisplayOneMenu (MenuOption, - MenuOption->Col - gStatementDimensions.LeftColumn, - gStatementDimensions.LeftColumn, - Temp, - BottomRow, - FALSE, - FALSE - ); - } - - // - // This is the current selected statement - // - MenuOption = MENU_OPTION_FROM_LINK (NewPos); - RefreshKeyHelp(gFormData, MenuOption->ThisTag, FALSE); - - if (!IsSelectable (MenuOption)) { - break; - } - - Status = DisplayOneMenu (MenuOption, - MenuOption->Col - gStatementDimensions.LeftColumn, - gStatementDimensions.LeftColumn, - Temp2, - BottomRow, - TRUE, - FALSE - ); - } - break; - - case CfUpdateHelpString: - ControlFlag = CfPrepareToReadKey; - if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) { - break; - } - - // - // NewLine means only update highlight menu (remove old highlight and highlith - // the new one), not need to full repain the form. - // - if (Repaint || NewLine) { - if (IsListEmpty (&gMenuOption)) { - // - // Don't print anything if no mwnu option. - // - StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle); - } else { - // - // 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; - Statement = MenuOption->ThisTag; - StatementValue = &Statement->CurrentValue; - if (HelpInfo == 0 || !IsSelectable (MenuOption)) { - if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP && StatementValue->Value.date.Month== 0xff)||(Statement->OpCode->OpCode == EFI_IFR_TIME_OP && StatementValue->Value.time.Hour == 0xff)){ - StringPtr = GetToken (STRING_TOKEN (GET_TIME_FAIL), gHiiHandle); - } else { - StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle); - } - } else { - if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP && StatementValue->Value.date.Month== 0xff)||(Statement->OpCode->OpCode == EFI_IFR_TIME_OP && StatementValue->Value.time.Hour == 0xff)){ - StringRightPtr = GetToken (HelpInfo, gFormData->HiiHandle); - StringErrorPtr = GetToken (STRING_TOKEN (GET_TIME_FAIL), gHiiHandle); - StringPtr = AllocateZeroPool ((StrLen (StringRightPtr) + StrLen (StringErrorPtr)+ 1 ) * sizeof (CHAR16)); - StrCpyS (StringPtr, StrLen (StringRightPtr) + StrLen (StringErrorPtr) + 1, StringRightPtr); - StrCatS (StringPtr, StrLen (StringRightPtr) + StrLen (StringErrorPtr) + 1, StringErrorPtr); - FreePool (StringRightPtr); - FreePool (StringErrorPtr); - } 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) != 0) { - 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) { - gMisMatch = TRUE; - 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. - // - ASSERT(MenuOption != NULL); - if(IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) { - ControlFlag = CfReadKey; - break; - } - - 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) && (ScreenOperation != UiHotKey)) { - // - // If the screen has no menu items, and the user didn't select UiReset or UiHotKey - // 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; - } - - gUserInput->Action = BROWSER_ACTION_FORM_EXIT; - ControlFlag = CfExit; - break; - - case CfUiHotKey: - ControlFlag = CfRepaint; - - ASSERT (HotKey != NULL); - - if (FxConfirmPopup(HotKey->Action)) { - gUserInput->Action = HotKey->Action; - if ((HotKey->Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) { - gUserInput->DefaultId = HotKey->DefaultId; - } - ControlFlag = CfExit; - } else { - Repaint = TRUE; - NewLine = TRUE; - ControlFlag = CfRepaint; - } - - 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; - NewLine = TRUE; - - SavedListEntry = NewPos; - ASSERT(NewPos != NULL); - - MenuOption = MENU_OPTION_FROM_LINK (NewPos); - ASSERT (MenuOption != NULL); - - // - // Adjust Date/Time position before we advance forward. - // - AdjustDateAndTimePosition (TRUE, &NewPos); - - NewPos = NewPos->BackLink; - // - // Find next selectable menu or the first menu beyond current form. - // - Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow, FALSE); - if (Difference < 0) { - // - // We hit the begining MenuOption that can be focused - // so we simply scroll to the top. - // - Repaint = TRUE; - if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) { - TopOfScreen = gMenuOption.ForwardLink; - NewPos = SavedListEntry; - SkipValue = 0; - } else { - // - // Scroll up to the last page when we have arrived at top page. - // - TopOfScreen = FindTopOfScreenMenu (gMenuOption.BackLink, BottomRow - TopRow, &SkipValue); - NewPos = gMenuOption.BackLink; - MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow, TRUE); - } - } else { - NextMenuOption = MENU_OPTION_FROM_LINK (NewPos); - - if (MenuOption->Row < TopRow + Difference + NextMenuOption->Skip) { - // - // Previous focus MenuOption is above the TopOfScreen, so we need to scroll - // - TopOfScreen = NewPos; - Repaint = TRUE; - SkipValue = 0; - } - - // - // Check whether new highlight menu is selectable, if not, keep highlight on the old one. - // - // BottomRow - TopRow + 1 means the total rows current forms supported. - // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu - // and new top menu. New top menu will all shows in next form, but last highlight menu - // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the - // last highlight menu. - // - if (!IsSelectable(NextMenuOption) && IsSelectable(MenuOption) && - (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1)) { - NewPos = SavedListEntry; - } - } - - UpdateStatusBar (INPUT_ERROR, FALSE); - - // - // If we encounter a Date/Time op-code set, rewind to the first op-code of the set. - // - AdjustDateAndTimePosition (TRUE, &TopOfScreen); - AdjustDateAndTimePosition (TRUE, &NewPos); - - UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); - break; - - case CfUiPageUp: - // - // SkipValue means lines is skipped when show the top menu option. - // - ControlFlag = CfRepaint; - NewLine = TRUE; - Repaint = TRUE; - - Link = TopOfScreen; - // - // First minus the menu of the top screen, it's value is SkipValue. - // - if (SkipValue >= BottomRow - TopRow + 1) { - // - // 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. - // - SkipValue -= BottomRow - TopRow + 1; - NewPos = TopOfScreen; - break; - } else { - Index = (BottomRow + 1) - SkipValue - TopRow; - } - - TopOfScreen = FindTopOfScreenMenu(TopOfScreen, Index, &SkipValue); - NewPos = TopOfScreen; - MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, FALSE); - - UpdateStatusBar (INPUT_ERROR, FALSE); - - // - // 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); - - UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); - break; - - case CfUiPageDown: - // - // SkipValue means lines is skipped when show the top menu option. - // - ControlFlag = CfRepaint; - 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)) { - // - // Highlight on the last menu which can be highlight. - // - Repaint = FALSE; - MoveToNextStatement (TRUE, &Link, Index - TopRow, TRUE); - } 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, TRUE); - } - - // - // Save the menu as the next highlight menu. - // - NewPos = Link; - - UpdateStatusBar (INPUT_ERROR, FALSE); - - // - // 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); - - UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); - 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; - NewLine = TRUE; - - if (NewPos == TopOfScreen) { - Temp2 = SkipValue; - } else { - Temp2 = 0; - } - - SavedListEntry = NewPos; - // - // 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. - // - AdjustDateAndTimePosition (FALSE, &NewPos); - - MenuOption = MENU_OPTION_FROM_LINK (NewPos); - NewPos = NewPos->ForwardLink; - // - // Find the next selectable menu. - // - if (MenuOption->Row + MenuOption->Skip - Temp2 > BottomRow + 1) { - if (gMenuOption.ForwardLink == NewPos || &gMenuOption == NewPos) { - Difference = -1; - } else { - Difference = 0; - } - } else { - Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow + 1 - (MenuOption->Row + MenuOption->Skip - Temp2), FALSE); - } - if (Difference < 0) { - // - // Scroll to the first page. - // - if (TopOfScreen != gMenuOption.ForwardLink || SkipValue != 0) { - TopOfScreen = gMenuOption.ForwardLink; - Repaint = TRUE; - MenuOption = NULL; - } else { - MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry); - } - NewPos = gMenuOption.ForwardLink; - MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow, TRUE); - - 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); - - UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); - break; - } - - // - // Get next selected menu info. - // - AdjustDateAndTimePosition (FALSE, &NewPos); - NextMenuOption = MENU_OPTION_FROM_LINK (NewPos); - if (NextMenuOption->Row == 0) { - UpdateOptionSkipLines (NextMenuOption); - } - - // - // Calculate new highlight menu end row. - // - Temp = (MenuOption->Row + MenuOption->Skip - Temp2) + Difference + NextMenuOption->Skip - 1; - if (Temp > BottomRow) { - // - // Get the top screen menu info. - // - AdjustDateAndTimePosition (FALSE, &TopOfScreen); - SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen); - - // - // Current Top screen menu occupy (SavedMenuOption->Skip - SkipValue) rows. - // Full shows the new selected menu need to skip (Temp - BottomRow - 1) rows. - // - if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) { - // - // Skip the top op-code - // - TopOfScreen = TopOfScreen->ForwardLink; - DistanceValue = (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 - // Special case is the selected highlight menu has more than one form of menus. - // - while (DistanceValue >= SavedMenuOption->Skip && TopOfScreen != NewPos) { - // - // Since the Difference is greater than or equal to this op-code's skip value, skip it - // - DistanceValue = DistanceValue - (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. - // - if (TopOfScreen != NewPos) { - SkipValue = DistanceValue; - } else { - SkipValue = 0; - } - } 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; - } - 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; - break; - } - - MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry); - - // - // Check whether new highlight menu is selectable, if not, keep highlight on the old one. - // - // BottomRow - TopRow + 1 means the total rows current forms supported. - // Difference + NextMenuOption->Skip + 1 means the distance between last highlight menu - // and new top menu. New top menu will all shows in next form, but last highlight menu - // may only shows 1 line. + 1 at right part means at least need to keep 1 line for the - // last highlight menu. - // - if (!IsSelectable (NextMenuOption) && IsSelectable (MenuOption) && - (BottomRow - TopRow + 1 >= Difference + NextMenuOption->Skip + 1)) { - NewPos = SavedListEntry; - } - - UpdateStatusBar (INPUT_ERROR, FALSE); - - // - // 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); - - UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue); - 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; - EFI_EVENT WaitList[2]; - EFI_EVENT RefreshIntervalEvent; - EFI_EVENT TimeOutEvent; - UINT8 TimeOut; - EFI_STATUS Status; - UINTN Index; - WARNING_IF_CONTEXT EventContext; - EFI_IFR_OP_HEADER *OpCodeBuf; - EFI_STRING_ID StringToken; - CHAR16 DiscardChange; - CHAR16 JumpToFormSet; - CHAR16 *PrintString; - - if (gFormData->BrowserStatus == BROWSER_SUCCESS) { - return; - } - - StringToken = 0; - TimeOutEvent = NULL; - RefreshIntervalEvent = NULL; - OpCodeBuf = NULL; - if (gFormData->HighLightedStatement != NULL) { - OpCodeBuf = gFormData->HighLightedStatement->OpCode; - } - - if (gFormData->BrowserStatus == (BROWSER_WARNING_IF)) { - ASSERT (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_WARNING_IF_OP); - - TimeOut = ((EFI_IFR_WARNING_IF *) OpCodeBuf)->TimeOut; - StringToken = ((EFI_IFR_WARNING_IF *) OpCodeBuf)->Warning; - } else { - TimeOut = 0; - if ((gFormData->BrowserStatus == (BROWSER_NO_SUBMIT_IF)) && - (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_NO_SUBMIT_IF_OP)) { - StringToken = ((EFI_IFR_NO_SUBMIT_IF *) OpCodeBuf)->Error; - } else if ((gFormData->BrowserStatus == (BROWSER_INCONSISTENT_IF)) && - (OpCodeBuf != NULL && OpCodeBuf->OpCode == EFI_IFR_INCONSISTENT_IF_OP)) { - StringToken = ((EFI_IFR_INCONSISTENT_IF *) OpCodeBuf)->Error; - } - } - - if (StringToken != 0) { - ErrorInfo = GetToken (StringToken, gFormData->HiiHandle); - } else if (gFormData->ErrorString != NULL) { - // - // Only used to compatible with old setup browser. - // Not use this field in new browser core. - // - ErrorInfo = gFormData->ErrorString; - } else { - switch (gFormData->BrowserStatus) { - case BROWSER_SUBMIT_FAIL: - ErrorInfo = gSaveFailed; - break; - - case BROWSER_FORM_NOT_FOUND: - ErrorInfo = gFormNotFound; - break; - - case BROWSER_FORM_SUPPRESS: - ErrorInfo = gFormSuppress; - break; - - case BROWSER_PROTOCOL_NOT_FOUND: - ErrorInfo = gProtocolNotFound; - break; - - case BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF: - ErrorInfo = gNoSubmitIfFailed; - break; - - case BROWSER_RECONNECT_FAIL: - ErrorInfo = gReconnectFail; - break; - - case BROWSER_RECONNECT_SAVE_CHANGES: - ErrorInfo = gReconnectConfirmChanges; - break; - - case BROWSER_RECONNECT_REQUIRED: - ErrorInfo = gReconnectRequired; - break; - - default: - ErrorInfo = gBrowserError; - break; - } - } - - switch (gFormData->BrowserStatus) { - case BROWSER_SUBMIT_FAIL: - case BROWSER_SUBMIT_FAIL_NO_SUBMIT_IF: - case BROWSER_RECONNECT_SAVE_CHANGES: - ASSERT (gUserInput != NULL); - if (gFormData->BrowserStatus == (BROWSER_SUBMIT_FAIL)) { - PrintString = gSaveProcess; - JumpToFormSet = gJumpToFormSet[0]; - DiscardChange = gDiscardChange[0]; - } else if (gFormData->BrowserStatus == (BROWSER_RECONNECT_SAVE_CHANGES)){ - PrintString = gChangesOpt; - JumpToFormSet = gConfirmOptYes[0]; - DiscardChange = gConfirmOptNo[0]; - } else { - PrintString = gSaveNoSubmitProcess; - JumpToFormSet = gCheckError[0]; - DiscardChange = gDiscardChange[0]; - } - - do { - CreateDialog (&Key, gEmptyString, ErrorInfo, PrintString, gEmptyString, NULL); - } while (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (DiscardChange | UPPER_LOWER_CASE_OFFSET)) && - ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (JumpToFormSet | UPPER_LOWER_CASE_OFFSET))); - - if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (DiscardChange | UPPER_LOWER_CASE_OFFSET)) { - gUserInput->Action = BROWSER_ACTION_DISCARD; - } else { - gUserInput->Action = BROWSER_ACTION_GOTO; - } - break; - - default: - if (TimeOut == 0) { - do { - CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL); - } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - } else { - Status = gBS->CreateEvent (EVT_NOTIFY_WAIT, TPL_CALLBACK, EmptyEventProcess, NULL, &TimeOutEvent); - ASSERT_EFI_ERROR (Status); - - EventContext.SyncEvent = TimeOutEvent; - EventContext.TimeOut = &TimeOut; - EventContext.ErrorInfo = ErrorInfo; - - Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshTimeOutProcess, &EventContext, &RefreshIntervalEvent); - ASSERT_EFI_ERROR (Status); - - // - // Show the dialog first to avoid long time not reaction. - // - gBS->SignalEvent (RefreshIntervalEvent); - - Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, ONE_SECOND); - ASSERT_EFI_ERROR (Status); - - while (TRUE) { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - if (!EFI_ERROR (Status) && Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { - break; - } - - if (Status != EFI_NOT_READY) { - continue; - } - - WaitList[0] = TimeOutEvent; - WaitList[1] = gST->ConIn->WaitForKey; - - Status = gBS->WaitForEvent (2, WaitList, &Index); - ASSERT_EFI_ERROR (Status); - - if (Index == 0) { - // - // Timeout occur, close the hoot time out event. - // - break; - } - } - - gBS->CloseEvent (TimeOutEvent); - gBS->CloseEvent (RefreshIntervalEvent); - } - break; - } - - if (StringToken != 0) { - FreePool (ErrorInfo); - } -} - -/** - 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 (gFormData->BrowserStatus != BROWSER_SUCCESS) { - // - // gFormData->BrowserStatus != BROWSER_SUCCESS, means only need to print the error info, return here. - // - return EFI_SUCCESS; - } - - Status = DisplayPageFrame (FormData, &gStatementDimensions); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Global Widths should be initialized before any MenuOption creation - // or the GetWidth() used in UiAddMenuOption() will return incorrect value. - // - // - // Left right - // |<-.->|<-.........->|<- .........->|<-...........->| - // Skip Prompt Option Help - // - gOptionBlockWidth = (CHAR16) ((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3) + 1; - gHelpBlockWidth = (CHAR16) (gOptionBlockWidth - 1 - LEFT_SKIPPED_COLUMNS); - gPromptBlockWidth = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * (gOptionBlockWidth - 1) - 1); - - ConvertStatementToMenu(); - - // - // 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 (); - - if (gHighligthMenuInfo.HLTOpCode != NULL) { - FreePool (gHighligthMenuInfo.HLTOpCode); - } - - if (gHighligthMenuInfo.TOSOpCode != NULL) { - FreePool (gHighligthMenuInfo.TOSOpCode); - } - - return EFI_SUCCESS; -} diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h deleted file mode 100644 index 063e94c6bc..0000000000 --- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.h +++ /dev/null @@ -1,652 +0,0 @@ -/** @file - FormDiplay protocol to show Form - -Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.
-This program and the accompanying materials are licensed and made available under -the terms and conditions of the BSD License 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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -// -// 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; -extern BOOLEAN gMisMatch; - -// -// Screen definitions -// - -#define LEFT_SKIPPED_COLUMNS 3 -#define SCROLL_ARROW_HEIGHT 1 -#define POPUP_PAD_SPACE_COUNT 5 -#define POPUP_FRAME_WIDTH 2 - -#define UPPER_LOWER_CASE_OFFSET 0x20 - -// -// 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] -// with extra '-' flat, set the width to 24. -// -#define MAX_NUMERIC_INPUT_WIDTH 24 - -#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, - 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_HII_HANDLE HiiHandle; - UINT16 FormId; - - // - // Info for the highlight question. - // HLT means highlight - // - // If one statement has questionid, save questionid info to find the question. - // If one statement not has questionid info, save the opcode info to find the - // statement. If more than one statement has same opcode in one form(just like - // empty subtitle info may has more than one info one form), also use Index - // info to find the statement. - // - EFI_QUESTION_ID HLTQuestionId; - EFI_IFR_OP_HEADER *HLTOpCode; - UINTN HLTIndex; - UINTN HLTSequence; - - // - // Info for the top of screen question. - // TOS means Top Of Screen - // - EFI_QUESTION_ID TOSQuestionId; - EFI_IFR_OP_HEADER *TOSOpCode; - UINTN TOSIndex; - - UINT16 SkipValue; -} DISPLAY_HIGHLIGHT_MENU_INFO; - -typedef struct { - EFI_EVENT SyncEvent; - UINT8 *TimeOut; - CHAR16 *ErrorInfo; -} WARNING_IF_CONTEXT; - -#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 nothing. - - @param Event The Event need to be process - @param Context The context of the event. - -**/ -VOID -EFIAPI -EmptyEventProcess ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Process for the refresh interval statement. - - @param Event The Event need to be process - @param Context The context of the event. - -**/ -VOID -EFIAPI -RefreshTimeOutProcess ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Record the highlight menu and top of screen menu info. - - @param Highlight The menu opton which is highlight. - @param TopOfScreen The menu opton which is at the top of the form. - @param SkipValue The skip line info for the top of screen menu. - -**/ -VOID -UpdateHighlightMenuInfo ( - IN LIST_ENTRY *Highlight, - IN LIST_ENTRY *TopOfScreen, - IN UINTN SkipValue - ); - -#endif diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni deleted file mode 100644 index ff94518b06..0000000000 Binary files a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplayStr.uni and /dev/null differ diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c b/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c deleted file mode 100644 index bbbbdaa8c1..0000000000 --- a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c +++ /dev/null @@ -1,1673 +0,0 @@ -/** @file -Implementation for handling user input from the User Interfaces. - -Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "FormDisplay.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. - - @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 - ) -{ - EFI_STATUS Status; - EFI_INPUT_KEY Key; - CHAR16 NullCharacter; - UINTN ScreenSize; - CHAR16 Space[2]; - CHAR16 KeyPad[2]; - CHAR16 *TempString; - CHAR16 *BufferedString; - UINTN Index; - UINTN Index2; - UINTN Count; - UINTN Start; - UINTN Top; - UINTN DimensionsWidth; - UINTN DimensionsHeight; - UINTN CurrentCursor; - BOOLEAN CursorVisible; - UINTN Minimum; - UINTN Maximum; - FORM_DISPLAY_ENGINE_STATEMENT *Question; - BOOLEAN IsPassword; - UINTN MaxLen; - - DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn; - DimensionsHeight = gStatementDimensions.BottomRow - gStatementDimensions.TopRow; - - NullCharacter = CHAR_NULL; - ScreenSize = GetStringWidth (Prompt) / sizeof (CHAR16); - Space[0] = L' '; - Space[1] = CHAR_NULL; - - Question = MenuOption->ThisTag; - GetFieldFromOp(Question->OpCode, &Minimum, &Maximum); - - if (Question->OpCode->OpCode == EFI_IFR_PASSWORD_OP) { - IsPassword = TRUE; - } else { - IsPassword = FALSE; - } - - MaxLen = Maximum + 1; - TempString = AllocateZeroPool (MaxLen * sizeof (CHAR16)); - ASSERT (TempString); - - if (ScreenSize < (Maximum + 1)) { - ScreenSize = Maximum + 1; - } - - if ((ScreenSize + 2) > DimensionsWidth) { - ScreenSize = DimensionsWidth - 2; - } - - BufferedString = AllocateZeroPool (ScreenSize * 2); - ASSERT (BufferedString); - - Start = (DimensionsWidth - ScreenSize - 2) / 2 + gStatementDimensions.LeftColumn + 1; - Top = ((DimensionsHeight - 6) / 2) + gStatementDimensions.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; - gST->ConOut->EnableCursor (gST->ConOut, TRUE); - - CurrentCursor = GetStringWidth (StringPtr) / 2 - 1; - if (CurrentCursor != 0) { - // - // Show the string which has beed saved before. - // - SetUnicodeMem (BufferedString, ScreenSize - 1, L' '); - PrintStringAt (Start + 1, Top + 3, BufferedString); - - if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { - Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; - } else { - Index = 0; - } - - if (IsPassword) { - gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3); - } - - for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { - BufferedString[Count] = StringPtr[Index]; - - if (IsPassword) { - PrintCharAt ((UINTN)-1, (UINTN)-1, L'*'); - } - } - - if (!IsPassword) { - PrintStringAt (Start + 1, Top + 3, BufferedString); - } - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3); - } - - do { - Status = WaitForKeyStroke (&Key); - ASSERT_EFI_ERROR (Status); - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); - switch (Key.UnicodeChar) { - case CHAR_NULL: - switch (Key.ScanCode) { - case SCAN_LEFT: - if (CurrentCursor > 0) { - CurrentCursor--; - } - break; - - case SCAN_RIGHT: - if (CurrentCursor < (GetStringWidth (StringPtr) / 2 - 1)) { - CurrentCursor++; - } - break; - - case SCAN_ESC: - FreePool (TempString); - FreePool (BufferedString); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); - return EFI_DEVICE_ERROR; - - case SCAN_DELETE: - for (Index = CurrentCursor; StringPtr[Index] != CHAR_NULL; Index++) { - StringPtr[Index] = StringPtr[Index + 1]; - PrintCharAt (Start + Index + 1, Top + 3, IsPassword && StringPtr[Index] != CHAR_NULL? L'*' : StringPtr[Index]); - } - break; - - default: - break; - } - - break; - - case CHAR_CARRIAGE_RETURN: - if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) { - - FreePool (TempString); - FreePool (BufferedString); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); - return EFI_SUCCESS; - } else { - // - // Simply create a popup to tell the user that they had typed in too few characters. - // 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); - } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - - FreePool (TempString); - FreePool (BufferedString); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); - return EFI_DEVICE_ERROR; - } - - break; - - case CHAR_BACKSPACE: - if (StringPtr[0] != CHAR_NULL && CurrentCursor != 0) { - for (Index = 0; Index < CurrentCursor - 1; Index++) { - TempString[Index] = StringPtr[Index]; - } - Count = GetStringWidth (StringPtr) / 2 - 1; - if (Count >= CurrentCursor) { - for (Index = CurrentCursor - 1, Index2 = CurrentCursor; Index2 < Count; Index++, Index2++) { - TempString[Index] = StringPtr[Index2]; - } - TempString[Index] = CHAR_NULL; - } - // - // Effectively truncate string by 1 character - // - StrCpyS (StringPtr, MaxLen, TempString); - CurrentCursor --; - } - - default: - // - // If it is the beginning of the string, don't worry about checking maximum limits - // - if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) { - StrnCpyS (StringPtr, MaxLen, &Key.UnicodeChar, 1); - CurrentCursor++; - } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) { - KeyPad[0] = Key.UnicodeChar; - KeyPad[1] = CHAR_NULL; - Count = GetStringWidth (StringPtr) / 2 - 1; - if (CurrentCursor < Count) { - for (Index = 0; Index < CurrentCursor; Index++) { - TempString[Index] = StringPtr[Index]; - } - TempString[Index] = CHAR_NULL; - StrCatS (TempString, MaxLen, KeyPad); - StrCatS (TempString, MaxLen, StringPtr + CurrentCursor); - StrCpyS (StringPtr, MaxLen, TempString); - } else { - StrCatS (StringPtr, MaxLen, KeyPad); - } - CurrentCursor++; - } - - // - // 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, ScreenSize - 1, L' '); - PrintStringAt (Start + 1, Top + 3, BufferedString); - - if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { - Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; - } else { - Index = 0; - } - - if (IsPassword) { - gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3); - } - - for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { - BufferedString[Count] = StringPtr[Index]; - - if (IsPassword) { - PrintCharAt ((UINTN)-1, (UINTN)-1, L'*'); - } - } - - if (!IsPassword) { - PrintStringAt (Start + 1, Top + 3, BufferedString); - } - break; - } - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->SetCursorPosition (gST->ConOut, Start + CurrentCursor + 1, Top + 3); - } while (TRUE); - -} - -/** - Adjust the value to the correct one. Rules follow the sample: - 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 Sequence The sequence of the field in the question. -**/ -VOID -AdjustQuestionValue ( - IN EFI_HII_VALUE *QuestionValue, - IN UINT8 Sequence - ) -{ - UINT8 Month; - UINT16 Year; - UINT8 Maximum; - UINT8 Minimum; - - Month = QuestionValue->Value.date.Month; - Year = QuestionValue->Value.date.Year; - Minimum = 1; - - switch (Month) { - case 2: - if ((Year % 4) == 0 && ((Year % 100) != 0 || (Year % 400) == 0)) { - Maximum = 29; - } else { - Maximum = 28; - } - break; - case 4: - case 6: - case 9: - case 11: - Maximum = 30; - break; - default: - Maximum = 31; - break; - } - - // - // Change the month area. - // - if (Sequence == 0) { - if (QuestionValue->Value.date.Day > Maximum) { - QuestionValue->Value.date.Day = Maximum; - } - } - - // - // Change the Year area. - // - if (Sequence == 2) { - if (QuestionValue->Value.date.Day > Maximum) { - QuestionValue->Value.date.Day = Minimum; - } - } -} - -/** - Get field info from numeric opcode. - - @param OpCode Pointer to the current input opcode. - @param IntInput Whether question shows with EFI_IFR_DISPLAY_INT_DEC type. - @param QuestionValue Input question value, with EFI_HII_VALUE type. - @param Value Return question value, always return UINT64 type. - @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, - IN BOOLEAN IntInput, - IN EFI_HII_VALUE *QuestionValue, - OUT UINT64 *Value, - 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: - if (IntInput) { - *Minimum = (INT64) (INT8) NumericOp->data.u8.MinValue; - *Maximum = (INT64) (INT8) NumericOp->data.u8.MaxValue; - *Value = (INT64) (INT8) QuestionValue->Value.u8; - } else { - *Minimum = NumericOp->data.u8.MinValue; - *Maximum = NumericOp->data.u8.MaxValue; - *Value = QuestionValue->Value.u8; - } - *Step = NumericOp->data.u8.Step; - *StorageWidth = (UINT16) sizeof (UINT8); - break; - - case EFI_IFR_NUMERIC_SIZE_2: - if (IntInput) { - *Minimum = (INT64) (INT16) NumericOp->data.u16.MinValue; - *Maximum = (INT64) (INT16) NumericOp->data.u16.MaxValue; - *Value = (INT64) (INT16) QuestionValue->Value.u16; - } else { - *Minimum = NumericOp->data.u16.MinValue; - *Maximum = NumericOp->data.u16.MaxValue; - *Value = QuestionValue->Value.u16; - } - *Step = NumericOp->data.u16.Step; - *StorageWidth = (UINT16) sizeof (UINT16); - break; - - case EFI_IFR_NUMERIC_SIZE_4: - if (IntInput) { - *Minimum = (INT64) (INT32) NumericOp->data.u32.MinValue; - *Maximum = (INT64) (INT32) NumericOp->data.u32.MaxValue; - *Value = (INT64) (INT32) QuestionValue->Value.u32; - } else { - *Minimum = NumericOp->data.u32.MinValue; - *Maximum = NumericOp->data.u32.MaxValue; - *Value = QuestionValue->Value.u32; - } - *Step = NumericOp->data.u32.Step; - *StorageWidth = (UINT16) sizeof (UINT32); - break; - - case EFI_IFR_NUMERIC_SIZE_8: - if (IntInput) { - *Minimum = (INT64) NumericOp->data.u64.MinValue; - *Maximum = (INT64) NumericOp->data.u64.MaxValue; - *Value = (INT64) QuestionValue->Value.u64; - } else { - *Minimum = NumericOp->data.u64.MinValue; - *Maximum = NumericOp->data.u64.MaxValue; - *Value = QuestionValue->Value.u64; - } - *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 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 - ) -{ - UINTN Column; - UINTN Row; - CHAR16 InputText[MAX_NUMERIC_INPUT_WIDTH]; - CHAR16 FormattedNumber[MAX_NUMERIC_INPUT_WIDTH - 1]; - UINT64 PreviousNumber[MAX_NUMERIC_INPUT_WIDTH - 3]; - UINTN Count; - UINTN Loop; - BOOLEAN ManualInput; - BOOLEAN HexInput; - BOOLEAN IntInput; - BOOLEAN Negative; - BOOLEAN ValidateFail; - BOOLEAN DateOrTime; - UINTN InputWidth; - UINT64 EditValue; - UINT64 Step; - UINT64 Minimum; - UINT64 Maximum; - UINTN EraseLen; - UINT8 Digital; - EFI_INPUT_KEY Key; - EFI_HII_VALUE *QuestionValue; - FORM_DISPLAY_ENGINE_STATEMENT *Question; - EFI_IFR_NUMERIC *NumericOp; - UINT16 StorageWidth; - - Column = MenuOption->OptCol; - Row = MenuOption->Row; - PreviousNumber[0] = 0; - Count = 0; - InputWidth = 0; - Digital = 0; - StorageWidth = 0; - Minimum = 0; - Maximum = 0; - NumericOp = NULL; - IntInput = FALSE; - HexInput = FALSE; - Negative = FALSE; - ValidateFail = FALSE; - - Question = MenuOption->ThisTag; - QuestionValue = &Question->CurrentValue; - - // - // Only two case, user can enter to this function: Enter and +/- case. - // In Enter case, gDirection = 0; in +/- case, gDirection = SCAN_LEFT/SCAN_WRIGHT - // - ManualInput = (BOOLEAN)(gDirection == 0 ? TRUE : FALSE); - - if ((Question->OpCode->OpCode == EFI_IFR_DATE_OP) || (Question->OpCode->OpCode == EFI_IFR_TIME_OP)) { - DateOrTime = TRUE; - } else { - DateOrTime = FALSE; - } - - // - // Prepare Value to be edit - // - EraseLen = 0; - EditValue = 0; - if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) { - Step = 1; - Minimum = 1; - - switch (MenuOption->Sequence) { - case 0: - Maximum = 12; - EraseLen = 4; - EditValue = QuestionValue->Value.date.Month; - break; - - case 1: - switch (QuestionValue->Value.date.Month) { - case 2: - if ((QuestionValue->Value.date.Year % 4) == 0 && - ((QuestionValue->Value.date.Year % 100) != 0 || - (QuestionValue->Value.date.Year % 400) == 0)) { - Maximum = 29; - } else { - Maximum = 28; - } - break; - case 4: - case 6: - case 9: - case 11: - Maximum = 30; - break; - default: - Maximum = 31; - break; - } - - EraseLen = 3; - EditValue = QuestionValue->Value.date.Day; - break; - - case 2: - Maximum = 0xffff; - EraseLen = 5; - EditValue = QuestionValue->Value.date.Year; - break; - - default: - break; - } - } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) { - Step = 1; - Minimum = 0; - - switch (MenuOption->Sequence) { - case 0: - Maximum = 23; - EraseLen = 4; - EditValue = QuestionValue->Value.time.Hour; - break; - - case 1: - Maximum = 59; - EraseLen = 3; - EditValue = QuestionValue->Value.time.Minute; - break; - - case 2: - Maximum = 59; - EraseLen = 3; - EditValue = QuestionValue->Value.time.Second; - break; - - default: - break; - } - } else { - ASSERT (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP); - NumericOp = (EFI_IFR_NUMERIC *) Question->OpCode; - GetValueFromNum(Question->OpCode, (NumericOp->Flags & EFI_IFR_DISPLAY) == 0, QuestionValue, &EditValue, &Minimum, &Maximum, &Step, &StorageWidth); - EraseLen = gOptionBlockWidth; - } - - if ((Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL)) { - if ((NumericOp->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX){ - HexInput = TRUE; - } else if ((NumericOp->Flags & EFI_IFR_DISPLAY) == 0){ - // - // Display with EFI_IFR_DISPLAY_INT_DEC type. Support negative number. - // - IntInput = TRUE; - } - } - - // - // Enter from "Enter" input, clear the old word showing. - // - if (ManualInput) { - if (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) { - if (HexInput) { - InputWidth = StorageWidth * 2; - } else { - switch (StorageWidth) { - case 1: - InputWidth = 3; - break; - - case 2: - InputWidth = 5; - break; - - case 4: - InputWidth = 10; - break; - - case 8: - InputWidth = 20; - break; - - default: - InputWidth = 0; - break; - } - - if (IntInput) { - // - // Support an extra '-' for negative number. - // - InputWidth += 1; - } - } - - InputText[0] = LEFT_NUMERIC_DELIMITER; - SetUnicodeMem (InputText + 1, InputWidth, L' '); - ASSERT (InputWidth + 2 < MAX_NUMERIC_INPUT_WIDTH); - InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER; - InputText[InputWidth + 2] = L'\0'; - - PrintStringAt (Column, Row, InputText); - Column++; - } - - if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) { - if (MenuOption->Sequence == 2) { - InputWidth = 4; - } else { - InputWidth = 2; - } - - if (MenuOption->Sequence == 0) { - InputText[0] = LEFT_NUMERIC_DELIMITER; - SetUnicodeMem (InputText + 1, InputWidth, L' '); - } else { - SetUnicodeMem (InputText, InputWidth, L' '); - } - - if (MenuOption->Sequence == 2) { - InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER; - } else { - InputText[InputWidth + 1] = DATE_SEPARATOR; - } - InputText[InputWidth + 2] = L'\0'; - - PrintStringAt (Column, Row, InputText); - if (MenuOption->Sequence == 0) { - Column++; - } - } - - if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) { - InputWidth = 2; - - if (MenuOption->Sequence == 0) { - InputText[0] = LEFT_NUMERIC_DELIMITER; - SetUnicodeMem (InputText + 1, InputWidth, L' '); - } else { - SetUnicodeMem (InputText, InputWidth, L' '); - } - - if (MenuOption->Sequence == 2) { - InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER; - } else { - InputText[InputWidth + 1] = TIME_SEPARATOR; - } - InputText[InputWidth + 2] = L'\0'; - - PrintStringAt (Column, Row, InputText); - if (MenuOption->Sequence == 0) { - Column++; - } - } - } - - // - // First time we enter this handler, we need to check to see if - // we were passed an increment or decrement directive - // - do { - Key.UnicodeChar = CHAR_NULL; - if (gDirection != 0) { - Key.ScanCode = gDirection; - gDirection = 0; - goto TheKey2; - } - - WaitForKeyStroke (&Key); - -TheKey2: - switch (Key.UnicodeChar) { - - case '+': - case '-': - if (ManualInput && IntInput) { - // - // In Manual input mode, check whether input the negative flag. - // - if (Key.UnicodeChar == '-') { - if (Negative) { - break; - } - Negative = TRUE; - PrintCharAt (Column++, Row, Key.UnicodeChar); - } - } else { - if (Key.UnicodeChar == '+') { - Key.ScanCode = SCAN_RIGHT; - } else { - Key.ScanCode = SCAN_LEFT; - } - Key.UnicodeChar = CHAR_NULL; - goto TheKey2; - } - break; - - case CHAR_NULL: - switch (Key.ScanCode) { - case SCAN_LEFT: - case SCAN_RIGHT: - if (DateOrTime && !ManualInput) { - // - // By setting this value, we will return back to the caller. - // We need to do this since an auto-refresh will destroy the adjustment - // based on what the real-time-clock is showing. So we always commit - // upon changing the value. - // - gDirection = SCAN_DOWN; - } - - if ((Step != 0) && !ManualInput) { - if (Key.ScanCode == SCAN_LEFT) { - if (IntInput) { - if ((INT64) EditValue >= (INT64) Minimum + (INT64) Step) { - EditValue = EditValue - Step; - } else if ((INT64) EditValue > (INT64) Minimum){ - EditValue = Minimum; - } else { - EditValue = Maximum; - } - } else { - if (EditValue >= Minimum + Step) { - EditValue = EditValue - Step; - } else if (EditValue > Minimum){ - EditValue = Minimum; - } else { - EditValue = Maximum; - } - } - } else if (Key.ScanCode == SCAN_RIGHT) { - if (IntInput) { - if ((INT64) EditValue + (INT64) Step <= (INT64) Maximum) { - EditValue = EditValue + Step; - } else if ((INT64) EditValue < (INT64) Maximum) { - EditValue = Maximum; - } else { - EditValue = Minimum; - } - } else { - if (EditValue + Step <= Maximum) { - EditValue = EditValue + Step; - } else if (EditValue < Maximum) { - EditValue = Maximum; - } else { - EditValue = Minimum; - } - } - } - - ZeroMem (FormattedNumber, 21 * sizeof (CHAR16)); - if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) { - if (MenuOption->Sequence == 2) { - // - // Year - // - UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%04d", (UINT16) EditValue); - } else { - // - // Month/Day - // - UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue); - } - - if (MenuOption->Sequence == 0) { - ASSERT (EraseLen >= 2); - FormattedNumber[EraseLen - 2] = DATE_SEPARATOR; - } else if (MenuOption->Sequence == 1) { - ASSERT (EraseLen >= 1); - FormattedNumber[EraseLen - 1] = DATE_SEPARATOR; - } - } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) { - UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue); - - if (MenuOption->Sequence == 0) { - ASSERT (EraseLen >= 2); - FormattedNumber[EraseLen - 2] = TIME_SEPARATOR; - } else if (MenuOption->Sequence == 1) { - ASSERT (EraseLen >= 1); - FormattedNumber[EraseLen - 1] = TIME_SEPARATOR; - } - } else { - QuestionValue->Value.u64 = EditValue; - PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16)); - } - - gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ()); - for (Loop = 0; Loop < EraseLen; Loop++) { - PrintStringAt (MenuOption->OptCol + Loop, MenuOption->Row, L" "); - } - gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ()); - - if (MenuOption->Sequence == 0) { - PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER); - Column = MenuOption->OptCol + 1; - } - - PrintStringAt (Column, Row, FormattedNumber); - - if (!DateOrTime || MenuOption->Sequence == 2) { - PrintCharAt ((UINTN)-1, (UINTN)-1, RIGHT_NUMERIC_DELIMITER); - } - } - - goto EnterCarriageReturn; - break; - - case SCAN_UP: - case SCAN_DOWN: - goto EnterCarriageReturn; - - case SCAN_ESC: - return EFI_DEVICE_ERROR; - - default: - break; - } - - break; - -EnterCarriageReturn: - - case CHAR_CARRIAGE_RETURN: - // - // Validate input value with Minimum value. - // - ValidateFail = FALSE; - if (IntInput) { - // - // After user input Enter, need to check whether the input value. - // If input a negative value, should compare with maximum value. - // else compare with the minimum value. - // - if (Negative) { - ValidateFail = (INT64) EditValue > (INT64) Maximum ? TRUE : FALSE; - } else { - ValidateFail = (INT64) EditValue < (INT64) Minimum ? TRUE : FALSE; - } - - if (ValidateFail) { - UpdateStatusBar (INPUT_ERROR, TRUE); - break; - } - } else if (EditValue < Minimum) { - UpdateStatusBar (INPUT_ERROR, TRUE); - break; - } - - UpdateStatusBar (INPUT_ERROR, 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) { - switch (MenuOption->Sequence) { - case 0: - QuestionValue->Value.date.Month = (UINT8) EditValue; - break; - - case 1: - QuestionValue->Value.date.Day = (UINT8) EditValue; - break; - - case 2: - QuestionValue->Value.date.Year = (UINT16) EditValue; - break; - - default: - break; - } - } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) { - switch (MenuOption->Sequence) { - case 0: - QuestionValue->Value.time.Hour = (UINT8) EditValue; - break; - - case 1: - QuestionValue->Value.time.Minute = (UINT8) EditValue; - break; - - case 2: - QuestionValue->Value.time.Second = (UINT8) EditValue; - break; - - default: - break; - } - } else { - // - // Numeric - // - QuestionValue->Value.u64 = EditValue; - } - - // - // Adjust the value to the correct one. - // 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 && - (MenuOption->Sequence == 0 || MenuOption->Sequence == 2)) { - AdjustQuestionValue (QuestionValue, (UINT8)MenuOption->Sequence); - } - - return EFI_SUCCESS; - break; - - case CHAR_BACKSPACE: - if (ManualInput) { - if (Count == 0) { - if (Negative) { - Negative = FALSE; - Column--; - PrintStringAt (Column, Row, L" "); - } - break; - } - // - // Remove a character - // - EditValue = PreviousNumber[Count - 1]; - UpdateStatusBar (INPUT_ERROR, FALSE); - Count--; - Column--; - PrintStringAt (Column, Row, L" "); - } - break; - - default: - if (ManualInput) { - if (HexInput) { - if ((Key.UnicodeChar >= L'0') && (Key.UnicodeChar <= L'9')) { - Digital = (UINT8) (Key.UnicodeChar - L'0'); - } else if ((Key.UnicodeChar >= L'A') && (Key.UnicodeChar <= L'F')) { - Digital = (UINT8) (Key.UnicodeChar - L'A' + 0x0A); - } else if ((Key.UnicodeChar >= L'a') && (Key.UnicodeChar <= L'f')) { - Digital = (UINT8) (Key.UnicodeChar - L'a' + 0x0A); - } else { - UpdateStatusBar (INPUT_ERROR, TRUE); - break; - } - } else { - if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') { - UpdateStatusBar (INPUT_ERROR, TRUE); - break; - } - } - - // - // If Count exceed input width, there is no way more is valid - // - if (Count >= InputWidth) { - break; - } - // - // Someone typed something valid! - // - if (Count != 0) { - if (HexInput) { - EditValue = LShiftU64 (EditValue, 4) + Digital; - } else if (IntInput && Negative) { - // - // Save the negative number. - // - EditValue = ~(MultU64x32 (~(EditValue - 1), 10) + (Key.UnicodeChar - L'0')) + 1; - } else { - EditValue = MultU64x32 (EditValue, 10) + (Key.UnicodeChar - L'0'); - } - } else { - if (HexInput) { - EditValue = Digital; - } else if (IntInput && Negative) { - // - // Save the negative number. - // - EditValue = ~(Key.UnicodeChar - L'0') + 1; - } else { - EditValue = Key.UnicodeChar - L'0'; - } - } - - if (IntInput) { - ValidateFail = FALSE; - // - // When user input a new value, should check the current value. - // If user input a negative value, should compare it with minimum - // value, else compare it with maximum value. - // - if (Negative) { - ValidateFail = (INT64) EditValue < (INT64) Minimum ? TRUE : FALSE; - } else { - ValidateFail = (INT64) EditValue > (INT64) Maximum ? TRUE : FALSE; - } - - if (ValidateFail) { - UpdateStatusBar (INPUT_ERROR, TRUE); - ASSERT (Count < sizeof (PreviousNumber) / sizeof (PreviousNumber[0])); - EditValue = PreviousNumber[Count]; - break; - } - } else { - if (EditValue > Maximum) { - UpdateStatusBar (INPUT_ERROR, TRUE); - ASSERT (Count < sizeof (PreviousNumber) / sizeof (PreviousNumber[0])); - EditValue = PreviousNumber[Count]; - break; - } - } - - UpdateStatusBar (INPUT_ERROR, 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 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 - ) -{ - EFI_INPUT_KEY Key; - UINTN Index; - CHAR16 *StringPtr; - CHAR16 *TempStringPtr; - UINTN Index2; - UINTN TopOptionIndex; - UINTN HighlightOptionIndex; - UINTN Start; - UINTN End; - UINTN Top; - UINTN Bottom; - UINTN PopUpMenuLines; - UINTN MenuLinesInView; - UINTN PopUpWidth; - CHAR16 Character; - INT32 SavedAttribute; - BOOLEAN ShowDownArrow; - BOOLEAN ShowUpArrow; - UINTN DimensionsWidth; - 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; - INTN Result; - EFI_IFR_ORDERED_LIST *OrderList; - - DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn; - - ValueArray = NULL; - ValueType = 0; - CurrentOption = NULL; - ShowDownArrow = FALSE; - ShowUpArrow = FALSE; - - 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; - OrderedList = TRUE; - OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode; - } else { - OrderedList = FALSE; - OrderList = NULL; - } - - // - // Calculate Option count - // - PopUpMenuLines = 0; - if (OrderedList) { - AdjustOptionOrder(Question, &PopUpMenuLines); - } else { - Link = GetFirstNode (&Question->OptionListHead); - while (!IsNull (&Question->OptionListHead, Link)) { - OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); - PopUpMenuLines++; - Link = GetNextNode (&Question->OptionListHead, Link); - } - } - - // - // Get the number of one of options present and its size - // - PopUpWidth = 0; - HighlightOptionIndex = 0; - Link = GetFirstNode (&Question->OptionListHead); - for (Index = 0; Index < PopUpMenuLines; Index++) { - OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); - - StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); - 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)) { - // - // Find current selected Option for OneOf - // - HighlightOptionIndex = Index; - } - - Link = GetNextNode (&Question->OptionListHead, Link); - } - - // - // Perform popup menu initialization. - // - PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT; - - SavedAttribute = gST->ConOut->Mode->Attribute; - gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); - - if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) { - PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH; - } - - Start = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gStatementDimensions.LeftColumn; - End = Start + PopUpWidth + POPUP_FRAME_WIDTH; - Top = gStatementDimensions.TopRow; - Bottom = gStatementDimensions.BottomRow - 1; - - MenuLinesInView = Bottom - Top - 1; - if (MenuLinesInView >= PopUpMenuLines) { - Top = Top + (MenuLinesInView - PopUpMenuLines) / 2; - Bottom = Top + PopUpMenuLines + 1; - } else { - ShowDownArrow = TRUE; - } - - if (HighlightOptionIndex > (MenuLinesInView - 1)) { - TopOptionIndex = HighlightOptionIndex - MenuLinesInView + 1; - } else { - TopOptionIndex = 0; - } - - do { - // - // Clear that portion of the screen - // - ClearLines (Start, End, Top, Bottom, GetPopupColor ()); - - // - // Draw "One of" pop-up menu - // - Character = BOXDRAW_DOWN_RIGHT; - PrintCharAt (Start, Top, Character); - for (Index = Start; Index + 2 < End; Index++) { - if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) { - Character = GEOMETRICSHAPE_UP_TRIANGLE; - } else { - Character = BOXDRAW_HORIZONTAL; - } - - PrintCharAt ((UINTN)-1, (UINTN)-1, Character); - } - - Character = BOXDRAW_DOWN_LEFT; - PrintCharAt ((UINTN)-1, (UINTN)-1, Character); - Character = BOXDRAW_VERTICAL; - for (Index = Top + 1; Index < Bottom; Index++) { - PrintCharAt (Start, Index, Character); - PrintCharAt (End - 1, Index, Character); - } - - // - // Move to top Option - // - Link = GetFirstNode (&Question->OptionListHead); - for (Index = 0; Index < TopOptionIndex; Index++) { - Link = GetNextNode (&Question->OptionListHead, Link); - } - - // - // Display the One of options - // - Index2 = Top + 1; - for (Index = TopOptionIndex; (Index < PopUpMenuLines) && (Index2 < Bottom); Index++) { - OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); - Link = GetNextNode (&Question->OptionListHead, Link); - - StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); - ASSERT (StringPtr != NULL); - // - // If the string occupies multiple lines, truncate it to fit in one line, - // and append a "..." for indication. - // - if (StrLen (StringPtr) > (PopUpWidth - 1)) { - TempStringPtr = AllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1)); - ASSERT ( TempStringPtr != NULL ); - CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5))); - FreePool (StringPtr); - StringPtr = TempStringPtr; - StrCatS (StringPtr, PopUpWidth - 1, L"..."); - } - - if (Index == HighlightOptionIndex) { - // - // Highlight the selected one - // - CurrentOption = OneOfOption; - - gST->ConOut->SetAttribute (gST->ConOut, GetPickListColor ()); - PrintStringAt (Start + 2, Index2, StringPtr); - gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); - } else { - gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); - PrintStringAt (Start + 2, Index2, StringPtr); - } - - Index2++; - FreePool (StringPtr); - } - - Character = BOXDRAW_UP_RIGHT; - PrintCharAt (Start, Bottom, Character); - for (Index = Start; Index + 2 < End; Index++) { - if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) { - Character = GEOMETRICSHAPE_DOWN_TRIANGLE; - } else { - Character = BOXDRAW_HORIZONTAL; - } - - PrintCharAt ((UINTN)-1, (UINTN)-1, Character); - } - - Character = BOXDRAW_UP_LEFT; - PrintCharAt ((UINTN)-1, (UINTN)-1, Character); - - // - // Get User selection - // - Key.UnicodeChar = CHAR_NULL; - if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) { - Key.ScanCode = gDirection; - gDirection = 0; - goto TheKey; - } - - WaitForKeyStroke (&Key); - -TheKey: - switch (Key.UnicodeChar) { - case '+': - if (OrderedList) { - if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) { - // - // Highlight reaches the top of the popup window, scroll one menu item. - // - TopOptionIndex--; - ShowDownArrow = TRUE; - } - - if (TopOptionIndex == 0) { - ShowUpArrow = FALSE; - } - - if (HighlightOptionIndex > 0) { - HighlightOptionIndex--; - - ASSERT (CurrentOption != NULL); - SwapListEntries (CurrentOption->Link.BackLink, &CurrentOption->Link); - } - } - break; - - case '-': - // - // If an ordered list op-code, we will allow for a popup of +/- keys - // to create an ordered list of items - // - if (OrderedList) { - if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) && - (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) { - // - // Highlight reaches the bottom of the popup window, scroll one menu item. - // - TopOptionIndex++; - ShowUpArrow = TRUE; - } - - if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) { - ShowDownArrow = FALSE; - } - - if (HighlightOptionIndex < (PopUpMenuLines - 1)) { - HighlightOptionIndex++; - - ASSERT (CurrentOption != NULL); - SwapListEntries (&CurrentOption->Link, CurrentOption->Link.ForwardLink); - } - } - break; - - case CHAR_NULL: - switch (Key.ScanCode) { - case SCAN_UP: - case SCAN_DOWN: - if (Key.ScanCode == SCAN_UP) { - if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) { - // - // Highlight reaches the top of the popup window, scroll one menu item. - // - TopOptionIndex--; - ShowDownArrow = TRUE; - } - - if (TopOptionIndex == 0) { - ShowUpArrow = FALSE; - } - - if (HighlightOptionIndex > 0) { - HighlightOptionIndex--; - } - } else { - if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) && - (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) { - // - // Highlight reaches the bottom of the popup window, scroll one menu item. - // - TopOptionIndex++; - ShowUpArrow = TRUE; - } - - if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) { - ShowDownArrow = FALSE; - } - - if (HighlightOptionIndex < (PopUpMenuLines - 1)) { - HighlightOptionIndex++; - } - } - break; - - case SCAN_ESC: - gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); - - // - // Restore link list order for orderedlist - // - if (OrderedList) { - 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) { - break; - } - - OneOfOption = ValueToOption (Question, &HiiValue); - if (OneOfOption == NULL) { - return EFI_NOT_FOUND; - } - - RemoveEntryList (&OneOfOption->Link); - InsertTailList (&Question->OptionListHead, &OneOfOption->Link); - } - } - - return EFI_DEVICE_ERROR; - - default: - break; - } - - break; - - case CHAR_CARRIAGE_RETURN: - // - // 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); - Link = GetNextNode (&Question->OptionListHead, Link); - - SetArrayData (ReturnValue, ValueType, Index, OneOfOption->OptionOpCode->Value.u64); - - Index++; - if (Index > OrderList->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; - } - } 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); - } - } - - gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); - - return EFI_SUCCESS; - - default: - break; - } - } while (TRUE); - -} - diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c b/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c deleted file mode 100644 index c074f4b4a3..0000000000 --- a/MdeModulePkg/Universal/DisplayEngineDxe/ProcessOptions.c +++ /dev/null @@ -1,1475 +0,0 @@ -/** @file -Implementation for handling the User Interface option processing. - - -Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "FormDisplay.h" - -#define MAX_TIME_OUT_LEN 0x10 - -/** - Concatenate a narrow string to another string. - - @param Destination The destination string. - @param DestMax The Max length of destination string. - @param Source The source string. The string to be concatenated. - to the end of Destination. - -**/ -VOID -NewStrCat ( - IN OUT CHAR16 *Destination, - IN UINTN DestMax, - 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++; - - StrCpyS (Destination + Length, DestMax - Length, Source); -} - -/** - Get UINT64 type value. - - @param Value Input Hii value. - - @retval UINT64 Return the UINT64 type value. - -**/ -UINT64 -HiiValueToUINT64 ( - IN EFI_HII_VALUE *Value - ) -{ - UINT64 RetVal; - - RetVal = 0; - - switch (Value->Type) { - case EFI_IFR_TYPE_NUM_SIZE_8: - RetVal = Value->Value.u8; - break; - - case EFI_IFR_TYPE_NUM_SIZE_16: - RetVal = Value->Value.u16; - break; - - case EFI_IFR_TYPE_NUM_SIZE_32: - RetVal = Value->Value.u32; - break; - - case EFI_IFR_TYPE_BOOLEAN: - RetVal = Value->Value.b; - break; - - case EFI_IFR_TYPE_DATE: - RetVal = *(UINT64*) &Value->Value.date; - break; - - case EFI_IFR_TYPE_TIME: - RetVal = (*(UINT64*) &Value->Value.time) & 0xffffff; - break; - - default: - RetVal = Value->Value.u64; - break; - } - - return RetVal; -} - -/** - Check whether this value type can be transfer to EFI_IFR_TYPE_BUFFER type. - - EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to - EFI_IFR_TYPE_BUFFER when do the value compare. - - @param Value Expression value to compare on. - - @retval TRUE This value type can be transter to EFI_IFR_TYPE_BUFFER type. - @retval FALSE This value type can't be transter to EFI_IFR_TYPE_BUFFER type. - -**/ -BOOLEAN -IsTypeInBuffer ( - IN EFI_HII_VALUE *Value - ) -{ - switch (Value->Type) { - case EFI_IFR_TYPE_BUFFER: - case EFI_IFR_TYPE_DATE: - case EFI_IFR_TYPE_TIME: - case EFI_IFR_TYPE_REF: - return TRUE; - - default: - return FALSE; - } -} - -/** - Check whether this value type can be transfer to EFI_IFR_TYPE_UINT64 - - @param Value Expression value to compare on. - - @retval TRUE This value type can be transter to EFI_IFR_TYPE_BUFFER type. - @retval FALSE This value type can't be transter to EFI_IFR_TYPE_BUFFER type. - -**/ -BOOLEAN -IsTypeInUINT64 ( - IN EFI_HII_VALUE *Value - ) -{ - switch (Value->Type) { - case EFI_IFR_TYPE_NUM_SIZE_8: - case EFI_IFR_TYPE_NUM_SIZE_16: - case EFI_IFR_TYPE_NUM_SIZE_32: - case EFI_IFR_TYPE_NUM_SIZE_64: - case EFI_IFR_TYPE_BOOLEAN: - return TRUE; - - default: - return FALSE; - } -} - -/** - Return the buffer length and buffer pointer for this value. - - EFI_IFR_TYPE_REF, EFI_IFR_TYPE_DATE and EFI_IFR_TYPE_TIME are converted to - EFI_IFR_TYPE_BUFFER when do the value compare. - - @param Value Expression value to compare on. - @param Buf Return the buffer pointer. - @param BufLen Return the buffer length. - -**/ -VOID -GetBufAndLenForValue ( - IN EFI_HII_VALUE *Value, - OUT UINT8 **Buf, - OUT UINT16 *BufLen - ) -{ - switch (Value->Type) { - case EFI_IFR_TYPE_BUFFER: - *Buf = Value->Buffer; - *BufLen = Value->BufferLen; - break; - - case EFI_IFR_TYPE_DATE: - *Buf = (UINT8 *) (&Value->Value.date); - *BufLen = (UINT16) sizeof (EFI_HII_DATE); - break; - - case EFI_IFR_TYPE_TIME: - *Buf = (UINT8 *) (&Value->Value.time); - *BufLen = (UINT16) sizeof (EFI_HII_TIME); - break; - - case EFI_IFR_TYPE_REF: - *Buf = (UINT8 *) (&Value->Value.ref); - *BufLen = (UINT16) sizeof (EFI_HII_REF); - break; - - default: - *Buf = NULL; - *BufLen = 0; - } -} - -/** - 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; - UINT8 *Buf1; - UINT16 Buf1Len; - UINT8 *Buf2; - UINT16 Buf2Len; - - if (Value1->Type == EFI_IFR_TYPE_STRING && Value2->Type == EFI_IFR_TYPE_STRING) { - 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; - } - - // - // Take types(date, time, ref, buffer) as buffer - // - if (IsTypeInBuffer(Value1) && IsTypeInBuffer(Value2)) { - GetBufAndLenForValue(Value1, &Buf1, &Buf1Len); - GetBufAndLenForValue(Value2, &Buf2, &Buf2Len); - - Len = Buf1Len > Buf2Len ? Buf2Len : Buf1Len; - *Result = CompareMem (Buf1, Buf2, Len); - if ((*Result == 0) && (Buf1Len != Buf2Len)) { - // - // In this case, means base on samll number buffer, the data is same - // So which value has more data, which value is bigger. - // - *Result = Buf1Len > Buf2Len ? 1 : -1; - } - return EFI_SUCCESS; - } - - // - // Take remain types(integer, boolean, date/time) as integer - // - if (IsTypeInUINT64(Value1) && IsTypeInUINT64(Value2)) { - Temp64 = HiiValueToUINT64(Value1) - HiiValueToUINT64(Value2); - if (Temp64 > 0) { - *Result = 1; - } else if (Temp64 < 0) { - *Result = -1; - } else { - *Result = 0; - } - return EFI_SUCCESS; - } - - return EFI_UNSUPPORTED; -} - -/** - 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 nothing. - - @param Event The Event need to be process - @param Context The context of the event. - -**/ -VOID -EFIAPI -EmptyEventProcess ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ -} - -/** - Process for the refresh interval statement. - - @param Event The Event need to be process - @param Context The context of the event. - -**/ -VOID -EFIAPI -RefreshTimeOutProcess ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - WARNING_IF_CONTEXT *EventInfo; - CHAR16 TimeOutString[MAX_TIME_OUT_LEN]; - - EventInfo = (WARNING_IF_CONTEXT *) Context; - - if (*(EventInfo->TimeOut) == 0) { - gBS->CloseEvent (Event); - - gBS->SignalEvent (EventInfo->SyncEvent); - return; - } - - UnicodeSPrint(TimeOutString, MAX_TIME_OUT_LEN, L"%d", *(EventInfo->TimeOut)); - - CreateDialog (NULL, gEmptyString, EventInfo->ErrorInfo, gPressEnter, gEmptyString, TimeOutString, NULL); - - *(EventInfo->TimeOut) -= 1; -} - -/** - 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 = EFI_SUCCESS; - - 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_IFR_ORDERED_LIST *OrderList; - BOOLEAN ValueInvalid; - UINTN MaxLen; - - Status = EFI_SUCCESS; - - StringPtr = NULL; - Character[1] = L'\0'; - *OptionString = NULL; - 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. - // - MaxLen = OrderList->MaxContainers * BufferSize / sizeof (CHAR16); - *OptionString = AllocateZeroPool (MaxLen * sizeof (CHAR16)); - 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; - gMisMatch = TRUE; - 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], MaxLen, Character); - StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); - ASSERT (StringPtr != NULL); - NewStrCat (OptionString[0], MaxLen, StringPtr); - Character[0] = RIGHT_ONEOF_DELIMITER; - NewStrCat (OptionString[0], MaxLen, Character); - Character[0] = CHAR_CARRIAGE_RETURN; - NewStrCat (OptionString[0], MaxLen, 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], MaxLen, Character); - StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); - ASSERT (StringPtr != NULL); - NewStrCat (OptionString[0], MaxLen, StringPtr); - Character[0] = RIGHT_ONEOF_DELIMITER; - NewStrCat (OptionString[0], MaxLen, Character); - Character[0] = CHAR_CARRIAGE_RETURN; - NewStrCat (OptionString[0], MaxLen, 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; - gMisMatch = TRUE; - 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 { - MaxLen = BufferSize / sizeof(CHAR16); - *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); - - gUserInput->InputValue.Type = Option->OptionOpCode->Type; - switch (gUserInput->InputValue.Type) { - case EFI_IFR_TYPE_NUM_SIZE_8: - gUserInput->InputValue.Value.u8 = Option->OptionOpCode->Value.u8; - break; - case EFI_IFR_TYPE_NUM_SIZE_16: - CopyMem (&gUserInput->InputValue.Value.u16, &Option->OptionOpCode->Value.u16, sizeof (UINT16)); - break; - case EFI_IFR_TYPE_NUM_SIZE_32: - CopyMem (&gUserInput->InputValue.Value.u32, &Option->OptionOpCode->Value.u32, sizeof (UINT32)); - break; - case EFI_IFR_TYPE_NUM_SIZE_64: - CopyMem (&gUserInput->InputValue.Value.u64, &Option->OptionOpCode->Value.u64, sizeof (UINT64)); - break; - default: - ASSERT (FALSE); - break; - } - gUserInput->SelectedStatement = Question; - gMisMatch = TRUE; - FreePool (*OptionString); - *OptionString = NULL; - return EFI_NOT_FOUND; - } - } - - Character[0] = LEFT_ONEOF_DELIMITER; - NewStrCat (OptionString[0], MaxLen, Character); - StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); - ASSERT (StringPtr != NULL); - NewStrCat (OptionString[0], MaxLen, StringPtr); - Character[0] = RIGHT_ONEOF_DELIMITER; - NewStrCat (OptionString[0], MaxLen, 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 EFI_SUCCESS; - } 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; - if (QuestionValue->Value.date.Month == 0xff){ - UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"??"); - } else { - 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' '); - if (QuestionValue->Value.date.Day == 0xff){ - UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"??"); - } else { - 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' '); - if (QuestionValue->Value.date.Year == 0xff){ - UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"????"); - } else { - 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; - if (QuestionValue->Value.time.Hour == 0xff){ - UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"??"); - } else { - 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' '); - if (QuestionValue->Value.time.Minute == 0xff){ - UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"??"); - } else { - 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' '); - if (QuestionValue->Value.time.Second == 0xff){ - UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"??"); - } else { - 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 EFI_SUCCESS; - } 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; -} -- cgit v1.2.3