X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FDisplayEngineDxe%2FFormDisplay.c;h=3b034a1c82688700601910d5a4fff8a55677f535;hb=9d510e61fceee7b92955ef9a3c20343752d8ce3f;hp=d265a25ec921100d642ee8dbd4c6ac1213f635fa;hpb=72f2eca287ec08dcc32adbf1bb6756b5b97b6f34;p=mirror_edk2.git
diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
index d265a25ec9..3b034a1c82 100644
--- a/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
+++ b/MdeModulePkg/Universal/DisplayEngineDxe/FormDisplay.c
@@ -1,14 +1,9 @@
/** @file
Entry and initialization module for the browser.
-Copyright (c) 2007 - 2013, 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.
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 2014, Hewlett-Packard Development Company, L.P.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -48,7 +43,7 @@ SCAN_CODE_TO_SCREEN_OPERATION gScanCodeToOperation[] = {
}
};
-UINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);
+UINTN mScanCodeNumber = ARRAY_SIZE (gScanCodeToOperation);
SCREEN_OPERATION_T0_CONTROL_FLAG gScreenOperationToControlFlag[] = {
{
@@ -86,7 +81,7 @@ SCREEN_OPERATION_T0_CONTROL_FLAG gScreenOperationToControlFlag[] = {
{
UiPageDown,
CfUiPageDown
- },
+ },
{
UiHotKey,
CfUiHotKey
@@ -97,8 +92,7 @@ EFI_GUID gDisplayEngineGuid = {
0xE38C1029, 0xE38F, 0x45b9, {0x8F, 0x0D, 0xE2, 0xE6, 0x0B, 0xC9, 0xB2, 0x62}
};
-FORM_ENTRY_INFO gFormEntryInfo;
-UINTN gSequence;
+BOOLEAN gMisMatch;
EFI_SCREEN_DESCRIPTOR gStatementDimensions;
BOOLEAN mStatementLayoutIsChanged = TRUE;
USER_INPUT *gUserInput;
@@ -113,10 +107,20 @@ FORM_ENTRY_INFO gOldFormEntry = {0};
//
// Browser Global Strings
//
+CHAR16 *gReconnectConfirmChanges;
+CHAR16 *gReconnectFail;
+CHAR16 *gReconnectRequired;
+CHAR16 *gChangesOpt;
CHAR16 *gFormNotFound;
CHAR16 *gNoSubmitIf;
-CHAR16 *gBrwoserError;
+CHAR16 *gBrowserError;
CHAR16 *gSaveFailed;
+CHAR16 *gNoSubmitIfFailed;
+CHAR16 *gSaveProcess;
+CHAR16 *gSaveNoSubmitProcess;
+CHAR16 *gDiscardChange;
+CHAR16 *gJumpToFormSet;
+CHAR16 *gCheckError;
CHAR16 *gPromptForData;
CHAR16 *gPromptForPassword;
CHAR16 *gPromptForNewPassword;
@@ -129,7 +133,30 @@ 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 *gConfirmOptOk;
+CHAR16 *gConfirmOptCancel;
+CHAR16 *gYesOption;
+CHAR16 *gNoOption;
+CHAR16 *gOkOption;
+CHAR16 *gCancelOption;
+CHAR16 *gErrorPopup;
+CHAR16 *gWarningPopup;
+CHAR16 *gInfoPopup;
+CHAR16 *gConfirmMsgConnect;
+CHAR16 *gConfirmMsgEnd;
+CHAR16 *gPasswordUnsupported;
CHAR16 gModalSkipColumn;
CHAR16 gPromptBlockWidth;
CHAR16 gOptionBlockWidth;
@@ -143,6 +170,10 @@ FORM_DISPLAY_DRIVER_PRIVATE_DATA mPrivateData = {
FormDisplay,
DriverClearDisplayPage,
ConfirmDataChange
+ },
+ {
+ EFI_HII_POPUP_PROTOCOL_REVISION,
+ CreatePopup
}
};
@@ -184,8 +215,18 @@ 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);
@@ -200,7 +241,31 @@ InitializeDisplayStrings (
gProtocolNotFound = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);
gFormNotFound = GetToken (STRING_TOKEN (STATUS_BROWSER_FORM_NOT_FOUND), gHiiHandle);
gNoSubmitIf = GetToken (STRING_TOKEN (STATUS_BROWSER_NO_SUBMIT_IF), gHiiHandle);
- gBrwoserError = GetToken (STRING_TOKEN (STATUS_BROWSER_ERROR), gHiiHandle);
+ 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);
+ gConfirmOptOk = GetToken (STRING_TOKEN (CONFIRM_OPTION_OK), gHiiHandle);
+ gConfirmOptCancel = GetToken (STRING_TOKEN (CONFIRM_OPTION_CANCEL), gHiiHandle);
+ gYesOption = GetToken (STRING_TOKEN (YES_SELECTABLE_OPTION), gHiiHandle);
+ gNoOption = GetToken (STRING_TOKEN (NO_SELECTABLE_OPTION), gHiiHandle);
+ gOkOption = GetToken (STRING_TOKEN (OK_SELECTABLE_OPTION), gHiiHandle);
+ gCancelOption = GetToken (STRING_TOKEN (CANCEL_SELECTABLE_OPTION), gHiiHandle);
+ gErrorPopup = GetToken (STRING_TOKEN (ERROR_POPUP_STRING), gHiiHandle);
+ gWarningPopup = GetToken (STRING_TOKEN (WARNING_POPUP_STRING), gHiiHandle);
+ gInfoPopup = GetToken (STRING_TOKEN (INFO_POPUP_STRING), gHiiHandle);
+ gConfirmMsgConnect = GetToken (STRING_TOKEN (CONFIRM_OPTION_CONNECT), gHiiHandle);
+ gConfirmMsgEnd = GetToken (STRING_TOKEN (CONFIRM_OPTION_END), gHiiHandle);
+ gPasswordUnsupported = GetToken (STRING_TOKEN (PASSWORD_NOT_SUPPORTED ), gHiiHandle);
}
/**
@@ -216,6 +281,16 @@ FreeDisplayStrings (
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);
@@ -227,9 +302,33 @@ FreeDisplayStrings (
FreePool (gOptionMismatch);
FreePool (gFormSuppress);
FreePool (gProtocolNotFound);
- FreePool (gBrwoserError);
+ 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 (gConfirmOptOk);
+ FreePool (gConfirmOptCancel);
+ FreePool (gYesOption);
+ FreePool (gNoOption);
+ FreePool (gOkOption);
+ FreePool (gCancelOption);
+ FreePool (gErrorPopup);
+ FreePool (gWarningPopup);
+ FreePool (gInfoPopup);
+ FreePool (gConfirmMsgConnect);
+ FreePool (gConfirmMsgEnd);
+ FreePool (gPasswordUnsupported);
}
/**
@@ -259,7 +358,7 @@ GetPrompt (
/**
Get the supported width for a particular op-code
- @param Statement The curent statement.
+ @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.
@@ -267,13 +366,17 @@ GetPrompt (
**/
UINT16
GetWidth (
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
- OUT UINT16 *AdjustWidth
+ IN UI_MENU_OPTION *MenuOption,
+ OUT UINT16 *AdjustWidth
)
{
- CHAR16 *String;
- UINTN Size;
- EFI_IFR_TEXT *TestOp;
+ 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.
@@ -309,23 +412,33 @@ GetWidth (
//
((Statement->OpCode->OpCode == EFI_IFR_TEXT_OP) && (Size == 0))
) {
-
+
//
// Return the space width.
- //
+ //
if (AdjustWidth != NULL) {
*AdjustWidth = 2;
}
//
// Keep consistent with current behavior.
//
- return (UINT16) (gPromptBlockWidth + gOptionBlockWidth - 2);
+ ReturnWidth = (UINT16) (gPromptBlockWidth + gOptionBlockWidth - 2);
+ } else {
+ if (AdjustWidth != NULL) {
+ *AdjustWidth = 1;
+ }
+
+ ReturnWidth = (UINT16) (gPromptBlockWidth - 1);
}
- if (AdjustWidth != NULL) {
- *AdjustWidth = 1;
+ //
+ // For nest in statement, should the subtitle indent.
+ //
+ if (MenuOption->NestInStatement) {
+ ReturnWidth -= SUBTITLE_INDENT;
}
- return (UINT16) (gPromptBlockWidth - 1);
+
+ return ReturnWidth;
}
/**
@@ -343,7 +456,7 @@ GetWidth (
@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
+ @return Returns the number of CHAR16 characters that were copied into the OutputString
buffer, include extra glyph info and '\0' info.
**/
@@ -422,7 +535,7 @@ GetLineByWidth (
if (ReturnFlag) {
break;
}
- }
+ }
//
// Rewind the string from the maximum size until we see a space to break the line
@@ -452,7 +565,7 @@ GetLineByWidth (
//
// Need extra glyph info and '\0' info, so +2.
//
- *OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));
+ *OutputString = AllocateZeroPool ((StrOffset + 2) * sizeof(CHAR16));
if (*OutputString == NULL) {
return 0;
}
@@ -471,7 +584,7 @@ GetLineByWidth (
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) {
//
@@ -485,7 +598,7 @@ GetLineByWidth (
} 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 {
@@ -519,7 +632,6 @@ UiAddMenuOption (
UI_MENU_OPTION *MenuOption;
UINTN Index;
UINTN Count;
- CHAR16 *String;
UINT16 NumberOfLines;
UINT16 GlyphWidth;
UINT16 Width;
@@ -536,27 +648,7 @@ UiAddMenuOption (
PromptId = GetPrompt (Statement->OpCode);
ASSERT (PromptId != 0);
- String = GetToken (PromptId, gFormData->HiiHandle);
- ASSERT (String != NULL);
-
- Width = GetWidth (Statement, 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);
- }
-
if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- //
- // Add three MenuOptions for Date/Time
- // Data format : [01/02/2004] [11:22:33]
- // Line number : 0 0 1 0 0 1
- //
- NumberOfLines = 0;
Count = 3;
}
@@ -565,20 +657,12 @@ UiAddMenuOption (
ASSERT (MenuOption);
MenuOption->Signature = UI_MENU_OPTION_SIGNATURE;
- MenuOption->Description = String;
+ MenuOption->Description = GetToken (PromptId, gFormData->HiiHandle);
MenuOption->Handle = gFormData->HiiHandle;
MenuOption->ThisTag = Statement;
MenuOption->NestInStatement = NestIn;
MenuOption->EntryNumber = *MenuItemCount;
- if (Index == 2) {
- //
- // Override LineNumber for the MenuOption in Date/Time sequence
- //
- MenuOption->Skip = 1;
- } else {
- MenuOption->Skip = NumberOfLines;
- }
MenuOption->Sequence = Index;
if ((Statement->Attribute & HII_DISPLAY_GRAYOUT) != 0) {
@@ -615,7 +699,7 @@ UiAddMenuOption (
case EFI_IFR_TEXT_OP:
if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {
//
- // Initializing GrayOut option as TRUE for Text setup options
+ // Initializing GrayOut option as TRUE for Text setup options
// so that those options will be Gray in colour and un selectable.
//
MenuOption->GrayOut = TRUE;
@@ -633,6 +717,37 @@ UiAddMenuOption (
}
}
+ if (Index == 0 &&
+ (Statement->OpCode->OpCode != EFI_IFR_DATE_OP) &&
+ (Statement->OpCode->OpCode != EFI_IFR_TIME_OP)) {
+ Width = GetWidth (MenuOption, NULL);
+ for (; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {
+ //
+ // If there is more string to process print on the next row and increment the Skip value
+ //
+ if (StrLen (&MenuOption->Description[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);
}
@@ -679,6 +794,13 @@ ConvertStatementToMenu (
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);
}
}
@@ -780,7 +902,7 @@ UpdateSkipInfoForMenu (
CHAR16 *OutputString;
UINT16 GlyphWidth;
- Width = (UINT16) gOptionBlockWidth;
+ Width = (UINT16) gOptionBlockWidth - 1;
GlyphWidth = 1;
Row = 1;
@@ -792,8 +914,8 @@ UpdateSkipInfoForMenu (
FreePool (OutputString);
}
- if ((Row > MenuOption->Skip) &&
- (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_DATE_OP) &&
+ if ((Row > MenuOption->Skip) &&
+ (MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_DATE_OP) &&
(MenuOption->ThisTag->OpCode->OpCode != EFI_IFR_TIME_OP)) {
MenuOption->Skip = Row;
}
@@ -832,6 +954,54 @@ UpdateOptionSkipLines (
}
}
+/**
+ 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.
@@ -849,7 +1019,7 @@ IsSelectable (
)
{
if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) ||
- MenuOption->GrayOut || MenuOption->ReadOnly) {
+ MenuOption->GrayOut || MenuOption->ReadOnly || !PrintableMenu (MenuOption)) {
return FALSE;
} else {
return TRUE;
@@ -864,19 +1034,24 @@ IsSelectable (
@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 l
- last menu showing at current form.
+ @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 UINTN GapToTop,
+ IN BOOLEAN FindInForm
)
{
INTN Distance;
@@ -886,6 +1061,11 @@ MoveToNextStatement (
Distance = 0;
Pos = *CurrentPosition;
+
+ if (Pos == &gMenuOption) {
+ return -1;
+ }
+
PreMenuOption = MENU_OPTION_FROM_LINK (Pos);
while (TRUE) {
@@ -897,28 +1077,27 @@ MoveToNextStatement (
if (NextMenuOption->Row == 0) {
UpdateOptionSkipLines (NextMenuOption);
}
-
- if (GoUp && (PreMenuOption != NextMenuOption)) {
- //
- // In this case, still can't find the selectable menu,
- // return the last one in the showing form.
- //
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
+
+ //
+ // Check whether the menu is beyond current showing form,
+ // return the first one beyond the showing form.
+ //
+ if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
+ if (FindInForm) {
NextMenuOption = PreMenuOption;
- break;
}
-
- //
- // Current Position doesn't need to be caculated when go up.
- // Caculate distanct at first when go up
- //
- Distance += NextMenuOption->Skip;
+ break;
}
+ //
+ // return the selectable menu in the showing form.
+ //
if (IsSelectable (NextMenuOption)) {
break;
}
+ Distance += NextMenuOption->Skip;
+
//
// Arrive at begin of the menu list.
//
@@ -927,21 +1106,8 @@ MoveToNextStatement (
break;
}
- if (!GoUp) {
- //
- // In this case, still can't find the selectable menu,
- // return the last one in the showing form.
- //
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
- NextMenuOption = PreMenuOption;
- break;
- }
-
- Distance += NextMenuOption->Skip;
- }
-
- PreMenuOption = NextMenuOption;
Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);
+ PreMenuOption = NextMenuOption;
}
*CurrentPosition = &NextMenuOption->Link;
@@ -954,10 +1120,10 @@ MoveToNextStatement (
@param MenuOption Menu option point to date/time.
@param OptionString Option string input for process.
- @param AddOptCol Whether need to update MenuOption->OptCol.
+ @param AddOptCol Whether need to update MenuOption->OptCol.
**/
-VOID
+VOID
ProcessStringForDateTime (
UI_MENU_OPTION *MenuOption,
CHAR16 *OptionString,
@@ -971,7 +1137,7 @@ ProcessStringForDateTime (
EFI_IFR_TIME *Time;
ASSERT (MenuOption != NULL && OptionString != NULL);
-
+
Statement = MenuOption->ThisTag;
Date = NULL;
Time = NULL;
@@ -980,7 +1146,7 @@ ProcessStringForDateTime (
} else if (Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
Time = (EFI_IFR_TIME *) Statement->OpCode;
}
-
+
//
// If leading spaces on OptionString - remove the spaces
//
@@ -992,13 +1158,13 @@ ProcessStringForDateTime (
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.
//
@@ -1010,21 +1176,21 @@ ProcessStringForDateTime (
//
if ((Date->Flags & EFI_QF_DATE_MONTH_SUPPRESS) && (MenuOption->Sequence == 0)) {
//
- // At this point, only "<**:" in the optionstring.
+ // 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.
+ // 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.
+ // 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) {
@@ -1035,21 +1201,21 @@ ProcessStringForDateTime (
//
if ((Time->Flags & QF_TIME_HOUR_SUPPRESS) && (MenuOption->Sequence == 0)) {
//
- // At this point, only "<**:" in the optionstring.
+ // 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.
+ // 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.
+ // At this point, only "**>" in the optionstring.
// Clean the second's "**" field, after clean, the format is " >"
- //
+ //
SetUnicodeMem (&OptionString[0], 2, L' ');
}
}
@@ -1132,7 +1298,7 @@ AdjustDateAndTimePosition (
/**
Get step info from numeric opcode.
-
+
@param[in] OpCode The input numeric op code.
@return step info for this opcode.
@@ -1146,24 +1312,24 @@ GetFieldFromNum (
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;
@@ -1174,7 +1340,7 @@ GetFieldFromNum (
/**
Find the registered HotKey based on KeyData.
-
+
@param[in] KeyData A pointer to a buffer that describes the keystroke
information for the hot key.
@@ -1191,14 +1357,14 @@ GetHotKeyFromRegisterList (
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;
}
@@ -1268,13 +1434,13 @@ UiWaitForEvent (
Timeout
);
}
-
+
WaitList[0] = Event;
EventNum = 1;
if (gFormData->FormRefreshEvent != NULL) {
WaitList[EventNum] = gFormData->FormRefreshEvent;
EventNum ++;
- }
+ }
if (Timeout != 0) {
WaitList[EventNum] = TimerEvent;
@@ -1307,7 +1473,7 @@ UiWaitForEvent (
if (Timeout != 0) {
gBS->CloseEvent (TimerEvent);
}
-
+
return EventType;
}
@@ -1335,198 +1501,604 @@ GetQuestionIdInfo (
return QuestionHeader->QuestionId;
}
+
/**
- Find the first menu which will be show at the top.
+ Find the top of screen menu base on the current menu.
- @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.
+ @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.
**/
-VOID
-FindTopMenu (
- IN FORM_DISPLAY_ENGINE_FORM *FormData,
- OUT LIST_ENTRY **TopOfScreen,
- OUT LIST_ENTRY **HighlightMenu,
- OUT INTN *SkipValue
+LIST_ENTRY *
+FindTopOfScreenMenu (
+ IN LIST_ENTRY *CurPos,
+ IN UINTN Rows,
+ OUT UINTN *SkipValue
)
{
- LIST_ENTRY *Link;
- LIST_ENTRY *NewPos;
- UINTN TopRow;
- UINTN BottomRow;
- UINTN Index;
- UI_MENU_OPTION *SavedMenuOption;
- UINTN EndRow;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *TopOfScreen;
+ UI_MENU_OPTION *PreviousMenuOption;
- TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;
- BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;
+ Link = CurPos;
+ PreviousMenuOption = NULL;
- //
- // If not has input highlight statement, just return the first one in this form.
- //
- if (FormData->HighLightedStatement == NULL) {
- *TopOfScreen = gMenuOption.ForwardLink;
- *HighlightMenu = gMenuOption.ForwardLink;
- if (!IsListEmpty (&gMenuOption)) {
- MoveToNextStatement (FALSE, HighlightMenu, BottomRow - TopRow);
+ while (Link->BackLink != &gMenuOption) {
+ Link = Link->BackLink;
+ PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
+ if (PreviousMenuOption->Row == 0) {
+ UpdateOptionSkipLines (PreviousMenuOption);
}
- *SkipValue = 0;
- return;
- }
-
- //
- // Now base on the input highlight menu to find the top menu in this page.
- // Will base on the highlight menu show at the bottom to find the top menu.
- //
- NewPos = gMenuOption.ForwardLink;
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
-
- while ((SavedMenuOption->ThisTag != FormData->HighLightedStatement) ||
- (SavedMenuOption->Sequence != gSequence)) {
- NewPos = NewPos->ForwardLink;
- if (NewPos == &gMenuOption) {
- //
- // Not Found it, break
- //
+ if (Rows <= PreviousMenuOption->Skip) {
break;
}
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- }
- ASSERT (SavedMenuOption->ThisTag == FormData->HighLightedStatement);
-
- *HighlightMenu = NewPos;
-
- AdjustDateAndTimePosition(FALSE, &NewPos);
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- UpdateOptionSkipLines (SavedMenuOption);
-
- //
- // If highlight opcode is date/time, keep the highlight row info not change.
- //
- if ((SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP || SavedMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP) &&
- (gHighligthMenuInfo.QuestionId != 0) &&
- (gHighligthMenuInfo.QuestionId == GetQuestionIdInfo(SavedMenuOption->ThisTag->OpCode))) {
- //
- // Still show the highlight menu before exit from display engine.
- //
- EndRow = gHighligthMenuInfo.DisplayRow + SavedMenuOption->Skip;
- } else {
- EndRow = BottomRow;
- }
-
- //
- // Base on the selected menu will show at the bottome of next page,
- // select the menu show at the top of the next page.
- //
- Link = NewPos;
- for (Index = TopRow + SavedMenuOption->Skip; Index <= EndRow; ) {
- Link = Link->BackLink;
- //
- // Already find the first menu in this form, means highlight menu
- // will show in first page of this form.
- //
- if (Link == &gMenuOption) {
- *TopOfScreen = gMenuOption.ForwardLink;
- *SkipValue = 0;
- return;
- }
- SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
- UpdateOptionSkipLines (SavedMenuOption);
- Index += SavedMenuOption->Skip;
+ Rows = Rows - PreviousMenuOption->Skip;
}
- //
- // Found the menu which will show at the top of the page.
- //
- if (Link == NewPos) {
- //
- // The menu can show more than one pages, just show the menu at the top of the page.
- //
- *SkipValue = 0;
- *TopOfScreen = Link;
- } else {
- //
- // Check whether need to skip some line for menu shows at the top of the page.
- //
- *SkipValue = Index - EndRow;
- if (*SkipValue > 0 && *SkipValue < (INTN) SavedMenuOption->Skip) {
- *TopOfScreen = Link;
+ if (Link->BackLink == &gMenuOption) {
+ TopOfScreen = gMenuOption.ForwardLink;
+ if (PreviousMenuOption != NULL && Rows < PreviousMenuOption->Skip) {
+ *SkipValue = PreviousMenuOption->Skip - Rows;
} else {
- *SkipValue = 0;
- *TopOfScreen = Link->ForwardLink;
+ *SkipValue = 0;
}
+ } else {
+ TopOfScreen = Link;
+ *SkipValue = PreviousMenuOption->Skip - Rows;
}
+
+ return TopOfScreen;
}
/**
- Update highlight menu info.
+ Get the index info for this opcode.
+
+ @param OpCode The input opcode for the statement.
- @param MenuOption The menu opton which is highlight.
+ @retval The index of this statement.
**/
-VOID
-UpdateHighlightMenuInfo (
- IN UI_MENU_OPTION *MenuOption
+UINTN
+GetIndexInfoForOpcode (
+ IN EFI_IFR_OP_HEADER *OpCode
)
{
- FORM_DISPLAY_ENGINE_STATEMENT *Statement;
+ LIST_ENTRY *NewPos;
+ UI_MENU_OPTION *MenuOption;
+ UINTN Index;
- //
- // This is the current selected statement
- //
- Statement = MenuOption->ThisTag;
+ NewPos = gMenuOption.ForwardLink;
+ Index = 0;
- //
- // Get the highlight statement.
- //
- gUserInput->SelectedStatement = Statement;
- gSequence = (UINT16) MenuOption->Sequence;
+ for (NewPos = gMenuOption.ForwardLink; NewPos != &gMenuOption; NewPos = NewPos->ForwardLink){
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- //
- // Record highlight row info for date/time opcode.
- //
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- gHighligthMenuInfo.QuestionId = GetQuestionIdInfo(Statement->OpCode);
- gHighligthMenuInfo.DisplayRow = (UINT16) MenuOption->Row;
- } else {
- gHighligthMenuInfo.QuestionId = 0;
- gHighligthMenuInfo.DisplayRow = 0;
+ if (CompareMem (MenuOption->ThisTag->OpCode, OpCode, OpCode->Length) == 0) {
+ if (MenuOption->ThisTag->OpCode == OpCode) {
+ return Index;
+ }
+
+ Index ++;
+ }
}
- RefreshKeyHelp(gFormData, Statement, FALSE);
+ return Index;
}
/**
- Update attribut for this menu.
+ Is this the saved highlight statement.
- @param MenuOption The menu opton which this attribut used to.
- @param Highlight Whether this menu will be highlight.
+ @param HighLightedStatement The input highlight statement.
+
+ @retval TRUE This is the highlight statement.
+ @retval FALSE This is not the highlight statement.
**/
-VOID
-SetDisplayAttribute (
- IN UI_MENU_OPTION *MenuOption,
- IN BOOLEAN Highlight
+BOOLEAN
+IsSavedHighlightStatement (
+ IN FORM_DISPLAY_ENGINE_STATEMENT *HighLightedStatement
)
{
- 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 ());
+ if ((gFormData->HiiHandle == gHighligthMenuInfo.HiiHandle) &&
+ (gFormData->FormId == gHighligthMenuInfo.FormId)) {
+ if (gHighligthMenuInfo.HLTQuestionId != 0) {
+ return (BOOLEAN) (gHighligthMenuInfo.HLTQuestionId == GetQuestionIdInfo (HighLightedStatement->OpCode));
} else {
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
+ 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;
+}
+
+/**
+ Calculate the distance between two menus and include the skip value of StartMenu.
+
+ @param StartMenu The link_entry pointer to start menu.
+ @param EndMenu The link_entry pointer to end menu.
+
+**/
+UINTN
+GetDistanceBetweenMenus(
+ IN LIST_ENTRY *StartMenu,
+ IN LIST_ENTRY *EndMenu
+)
+{
+ LIST_ENTRY *Link;
+ UI_MENU_OPTION *MenuOption;
+ UINTN Distance;
+
+ Distance = 0;
+
+ Link = StartMenu;
+ while (Link != EndMenu) {
+ MenuOption = MENU_OPTION_FROM_LINK (Link);
+ if (MenuOption->Row == 0) {
+ UpdateOptionSkipLines (MenuOption);
+ }
+ Distance += MenuOption->Skip;
+ Link = Link->BackLink;
+ }
+ return Distance;
+}
+
+/**
+ Find the top of screen menu base on the previous record menu info.
+
+ @param HighLightMenu The link_entry pointer to highlight menu.
+
+ @retval Return the the link_entry pointer top of screen menu.
+
+**/
+LIST_ENTRY *
+FindTopOfScreenMenuOption (
+ IN LIST_ENTRY *HighLightMenu
+ )
+{
+ LIST_ENTRY *NewPos;
+ UI_MENU_OPTION *MenuOption;
+ UINTN TopRow;
+ UINTN BottomRow;
+
+ TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;
+ BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT;
+
+ 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) {
+ return NULL;
+ }
+ //
+ // Check whether highlight menu and top of screen menu can be shown within one page,
+ // if can't, return NULL to re-calcaulate the top of scrren menu. Because some new menus
+ // may be dynamically inserted between highlightmenu and previous top of screen menu,
+ // So previous record top of screen menu is not appropriate for current display.
+ //
+ if (GetDistanceBetweenMenus (HighLightMenu, NewPos) + 1 > BottomRow - TopRow) {
+ return 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(*HighlightMenu);
+ 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 default 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(*HighlightMenu);
+ 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 ());
}
}
}
@@ -1562,11 +2134,11 @@ DisplayMenuString (
PrintStringAtWithWidth (Col, Row, String, Width);
return;
}
-
+
//
// Print the highlight menu string.
// First print the highlight string.
- //
+ //
SetDisplayAttribute(MenuOption, TRUE);
Length = PrintStringAt (Col, Row, String);
@@ -1586,7 +2158,7 @@ DisplayMenuString (
@retval FALSE This menu option can't have option string.
**/
-BOOLEAN
+BOOLEAN
HasOptionString (
IN UI_MENU_OPTION *MenuOption
)
@@ -1628,6 +2200,149 @@ HasOptionString (
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.
@@ -1635,9 +2350,10 @@ HasOptionString (
@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 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.
@@ -1649,7 +2365,8 @@ DisplayOneMenu (
IN UINTN BeginCol,
IN UINTN SkipLine,
IN UINTN BottomRow,
- IN BOOLEAN Highlight
+ IN BOOLEAN Highlight,
+ IN BOOLEAN UpdateCol
)
{
FORM_DISPLAY_ENGINE_STATEMENT *Statement;
@@ -1665,6 +2382,7 @@ DisplayOneMenu (
UINTN Temp3;
EFI_STATUS Status;
UINTN Row;
+ BOOLEAN IsProcessingFirstRow;
UINTN Col;
UINTN PromptLineNum;
UINTN OptionLineNum;
@@ -1679,6 +2397,7 @@ DisplayOneMenu (
PromptLineNum = 0;
OptionLineNum = 0;
MaxRow = 0;
+ IsProcessingFirstRow = TRUE;
//
// Set default color.
@@ -1698,14 +2417,14 @@ DisplayOneMenu (
//
// Adjust option string for date/time opcode.
//
- ProcessStringForDateTime(MenuOption, OptionString, TRUE);
+ 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) {
@@ -1723,15 +2442,16 @@ DisplayOneMenu (
} else {
//
// For date/ time, print the first and second past (year for date and second for time)
- //
- DisplayMenuString (MenuOption, MenuOption->OptCol, Row, OutputString, StrLen (OutputString), Highlight);
+ // 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
//
@@ -1750,13 +2470,13 @@ DisplayOneMenu (
}
}
}
-
+
FreePool (OutputString);
if (Temp2 != 0) {
Temp2--;
}
}
-
+
Highlight = FALSE;
FreePool (OptionString);
@@ -1765,7 +2485,7 @@ DisplayOneMenu (
//
// 2. Paint the description.
//
- PromptWidth = GetWidth (Statement, &AdjustValue);
+ PromptWidth = GetWidth (MenuOption, &AdjustValue);
Row = MenuOption->Row;
GlyphWidth = 1;
PromptLineNum = 0;
@@ -1774,14 +2494,14 @@ DisplayOneMenu (
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)) {
+ for (Index = 0; GetLineByWidth (MenuOption->Description, PromptWidth, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
+ if ((Temp == 0) && (Row <= BottomRow)) {
//
- // 1.Clean the start LEFT_SKIPPED_COLUMNS
+ // 1.Clean the start LEFT_SKIPPED_COLUMNS
//
PrintStringAtWithWidth (BeginCol, Row, L"", SkipWidth);
-
- if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2) {
+
+ if (Statement->OpCode->OpCode == EFI_IFR_REF_OP && MenuOption->Col >= 2 && IsProcessingFirstRow) {
//
// Print Arrow for Goto button.
//
@@ -1790,6 +2510,7 @@ DisplayOneMenu (
Row,
GEOMETRICSHAPE_RIGHT_TRIANGLE
);
+ IsProcessingFirstRow = FALSE;
}
DisplayMenuString (MenuOption, MenuOption->Col, Row, OutputString, PromptWidth + AdjustValue, Highlight);
PromptLineNum ++;
@@ -1818,13 +2539,13 @@ DisplayOneMenu (
//
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;) {
+ 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++;
@@ -1835,9 +2556,15 @@ DisplayOneMenu (
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--;
@@ -1856,7 +2583,7 @@ DisplayOneMenu (
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);
}
@@ -1881,7 +2608,7 @@ UiDisplayMenu (
IN FORM_DISPLAY_ENGINE_FORM *FormData
)
{
- INTN SkipValue;
+ UINTN SkipValue;
INTN Difference;
UINTN DistanceValue;
UINTN Row;
@@ -1890,12 +2617,11 @@ UiDisplayMenu (
UINTN Temp2;
UINTN TopRow;
UINTN BottomRow;
- UINTN OriginalRow;
UINTN Index;
- UINT16 Width;
CHAR16 *StringPtr;
+ CHAR16 *StringRightPtr;
+ CHAR16 *StringErrorPtr;
CHAR16 *OptionString;
- CHAR16 *OutputString;
CHAR16 *HelpString;
CHAR16 *HelpHeaderString;
CHAR16 *HelpBottomString;
@@ -1912,10 +2638,8 @@ UiDisplayMenu (
UI_MENU_OPTION *MenuOption;
UI_MENU_OPTION *NextMenuOption;
UI_MENU_OPTION *SavedMenuOption;
- UI_MENU_OPTION *PreviousMenuOption;
UI_CONTROL_FLAG ControlFlag;
UI_SCREEN_OPERATION ScreenOperation;
- UINT16 DefaultId;
FORM_DISPLAY_ENGINE_STATEMENT *Statement;
BROWSER_HOT_KEY *HotKey;
UINTN HelpPageIndex;
@@ -1925,14 +2649,13 @@ UiDisplayMenu (
UINTN HelpHeaderLine;
UINTN HelpBottomLine;
BOOLEAN MultiHelpPage;
- UINT16 GlyphWidth;
UINT16 EachLineWidth;
UINT16 HeaderLineWidth;
UINT16 BottomLineWidth;
EFI_STRING_ID HelpInfo;
UI_EVENT_TYPE EventType;
- FORM_DISPLAY_ENGINE_STATEMENT *InitialHighlight;
BOOLEAN SkipHighLight;
+ EFI_HII_VALUE *StatementValue;
EventType = UIEventNone;
Status = EFI_SUCCESS;
@@ -1942,7 +2665,6 @@ UiDisplayMenu (
OptionString = NULL;
ScreenOperation = UiNoOperation;
NewLine = TRUE;
- DefaultId = 0;
HelpPageCount = 0;
HelpLine = 0;
RowCount = 0;
@@ -1953,33 +2675,20 @@ UiDisplayMenu (
EachLineWidth = 0;
HeaderLineWidth = 0;
BottomLineWidth = 0;
- OutputString = NULL;
UpArrow = FALSE;
DownArrow = FALSE;
SkipValue = 0;
SkipHighLight = FALSE;
NextMenuOption = NULL;
- PreviousMenuOption = NULL;
SavedMenuOption = NULL;
HotKey = NULL;
Repaint = TRUE;
MenuOption = NULL;
gModalSkipColumn = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 6;
- InitialHighlight = gFormData->HighLightedStatement;
ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
- //
- // Left right
- // |<-.->|<-.........->|<- .........->|<-...........->|
- // Skip Prompt Option Help
- //
- Width = (CHAR16) ((gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn) / 3);
- gOptionBlockWidth = Width + 1;
- gHelpBlockWidth = (CHAR16) (Width - LEFT_SKIPPED_COLUMNS);
- gPromptBlockWidth = (CHAR16) (gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn - 2 * Width - 1);
-
TopRow = gStatementDimensions.TopRow + SCROLL_ARROW_HEIGHT;
BottomRow = gStatementDimensions.BottomRow - SCROLL_ARROW_HEIGHT - 1;
@@ -1991,6 +2700,10 @@ UiDisplayMenu (
}
FindTopMenu(FormData, &TopOfScreen, &NewPos, &SkipValue);
+ if (!IsListEmpty (&gMenuOption)) {
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ gUserInput->SelectedStatement = NextMenuOption->ThisTag;
+ }
gST->ConOut->EnableCursor (gST->ConOut, FALSE);
@@ -1998,7 +2711,7 @@ UiDisplayMenu (
while (TRUE) {
switch (ControlFlag) {
case CfInitialization:
- if ((gOldFormEntry.HiiHandle != FormData->HiiHandle) ||
+ if ((gOldFormEntry.HiiHandle != FormData->HiiHandle) ||
(!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))) {
//
// Clear Statement range if different formset is painted.
@@ -2027,7 +2740,7 @@ UiDisplayMenu (
Row = TopRow;
gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
-
+
//
// 1. Check whether need to print the arrow up.
//
@@ -2076,25 +2789,31 @@ UiDisplayMenu (
}
if ((FormData->Attribute & HII_DISPLAY_MODAL) != 0) {
- Status = DisplayOneMenu (MenuOption,
- LEFT_SKIPPED_COLUMNS,
- gStatementDimensions.LeftColumn + gModalSkipColumn,
- Link == TopOfScreen ? SkipValue : 0,
+ Status = DisplayOneMenu (MenuOption,
+ MenuOption->Col - gStatementDimensions.LeftColumn,
+ gStatementDimensions.LeftColumn + gModalSkipColumn,
+ Link == TopOfScreen ? SkipValue : 0,
BottomRow,
- (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption))
+ (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption)),
+ TRUE
);
} else {
- Status = DisplayOneMenu (MenuOption,
- LEFT_SKIPPED_COLUMNS,
- gStatementDimensions.LeftColumn,
- Link == TopOfScreen ? SkipValue : 0,
+ Status = DisplayOneMenu (MenuOption,
+ MenuOption->Col - gStatementDimensions.LeftColumn,
+ gStatementDimensions.LeftColumn,
+ Link == TopOfScreen ? SkipValue : 0,
BottomRow,
- (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption))
- );
+ (BOOLEAN) ((Link == NewPos) && IsSelectable(MenuOption)),
+ TRUE
+ );
}
if (EFI_ERROR (Status)) {
- return Status;
+ if (gMisMatch) {
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
}
//
// 3. Update the row info which will be used by next menu.
@@ -2145,10 +2864,6 @@ UiDisplayMenu (
}
MenuOption = NULL;
-
- if (IsListEmpty (&gMenuOption)) {
- ControlFlag = CfReadKey;
- }
}
break;
@@ -2161,10 +2876,21 @@ UiDisplayMenu (
//
ControlFlag = CfUpdateHelpString;
+ ASSERT (NewPos != NULL);
+ UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
+
if (SkipHighLight) {
- MenuOption = SavedMenuOption;
SkipHighLight = FALSE;
- UpdateHighlightMenuInfo (MenuOption);
+ MenuOption = SavedMenuOption;
+ RefreshKeyHelp(gFormData, SavedMenuOption->ThisTag, FALSE);
+ break;
+ }
+
+ if (IsListEmpty (&gMenuOption)) {
+ //
+ // No menu option, just update the hotkey filed.
+ //
+ RefreshKeyHelp(gFormData, NULL, FALSE);
break;
}
@@ -2179,169 +2905,39 @@ UiDisplayMenu (
Temp2 = 0;
}
- if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {
+ if (MenuOption == NULL || NewPos != &MenuOption->Link) {
if (MenuOption != NULL) {
//
- // Remove highlight on last Menu Option
+ // Remove the old highlight menu.
//
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- if (OptionString != NULL) {
- if ((MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP) ||
- (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)
- ) {
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);
- }
-
- Width = (UINT16) gOptionBlockWidth;
- OriginalRow = MenuOption->Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- FreePool (OptionString);
- } else {
- if (NewLine) {
- if (MenuOption->GrayOut) {
- gST->ConOut->SetAttribute (gST->ConOut, GetGrayedTextColor ());
- } else if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_SUBTITLE_OP) {
- gST->ConOut->SetAttribute (gST->ConOut, GetSubTitleTextColor ());
- }
-
- OriginalRow = MenuOption->Row;
- Width = GetWidth (MenuOption->ThisTag, NULL);
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- MenuOption->Row = OriginalRow;
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
- }
- }
+ 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);
- Statement = MenuOption->ThisTag;
-
- UpdateHighlightMenuInfo (MenuOption);
+ RefreshKeyHelp(gFormData, MenuOption->ThisTag, FALSE);
if (!IsSelectable (MenuOption)) {
break;
}
- //
- // Set reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
-
- ProcessOptions (MenuOption, FALSE, &OptionString, TRUE);
- if (OptionString != NULL) {
- if (Statement->OpCode->OpCode == EFI_IFR_DATE_OP || Statement->OpCode->OpCode == EFI_IFR_TIME_OP) {
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);
- }
- Width = (UINT16) gOptionBlockWidth;
-
- OriginalRow = MenuOption->Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp2 == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- FreePool (OptionString);
- } else {
- if (NewLine) {
- OriginalRow = MenuOption->Row;
-
- Width = GetWidth (Statement, NULL);
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp2 == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- }
- }
-
- //
- // Clear reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ());
+ Status = DisplayOneMenu (MenuOption,
+ MenuOption->Col - gStatementDimensions.LeftColumn,
+ gStatementDimensions.LeftColumn,
+ Temp2,
+ BottomRow,
+ TRUE,
+ FALSE
+ );
}
break;
@@ -2351,16 +2947,43 @@ UiDisplayMenu (
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) {
- //
- // Don't print anything if it is a NULL help token
- //
- ASSERT(MenuOption != NULL);
- HelpInfo = ((EFI_IFR_STATEMENT_HEADER *) ((CHAR8 *)MenuOption->ThisTag->OpCode + sizeof (EFI_IFR_OP_HEADER)))->Help;
- if (HelpInfo == 0 || !IsSelectable (MenuOption)) {
+ if (IsListEmpty (&gMenuOption)) {
+ //
+ // Don't print anything if no mwnu option.
+ //
StringPtr = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
} else {
- StringPtr = GetToken (HelpInfo, gFormData->HiiHandle);
+ //
+ // 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;
@@ -2396,7 +3019,7 @@ UiDisplayMenu (
//
if (HelpLine > 2 * RowCount - 2) {
HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;
- if ((HelpLine - RowCount + 1) % (RowCount - 2) > 1) {
+ if ((HelpLine - RowCount + 1) % (RowCount - 2) != 0) {
HelpPageCount += 1;
}
} else {
@@ -2410,14 +3033,14 @@ UiDisplayMenu (
//
// 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
+ // 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));
+ ASSERT (GetStringWidth (HelpHeaderString) / 2 < ((UINT32) gHelpBlockWidth - 1));
PrintStringAtWithWidth (
gStatementDimensions.RightColumn - gHelpBlockWidth,
Index + TopRow,
@@ -2465,7 +3088,7 @@ UiDisplayMenu (
);
}
} else {
- for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) &&
+ for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) &&
(Index + HelpPageIndex * (RowCount - 2) + 1 < HelpLine); Index++) {
PrintStringAtWithWidth (
gStatementDimensions.RightColumn - gHelpBlockWidth,
@@ -2485,20 +3108,20 @@ UiDisplayMenu (
}
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
+ // 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));
+ ASSERT (GetStringWidth (HelpBottomString) / 2 < ((UINT32) gHelpBlockWidth - 1));
PrintStringAtWithWidth (
gStatementDimensions.RightColumn - gHelpBlockWidth,
BottomRow + Index - HelpBottomLine + 1,
@@ -2543,7 +3166,7 @@ UiDisplayMenu (
if (Status != EFI_NOT_READY) {
continue;
}
-
+
EventType = UiWaitForEvent(gST->ConIn->WaitForKey);
if (EventType == UIEventKey) {
gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
@@ -2552,11 +3175,12 @@ UiDisplayMenu (
}
if (EventType == UIEventDriver) {
+ gMisMatch = TRUE;
gUserInput->Action = BROWSER_ACTION_NONE;
ControlFlag = CfExit;
break;
}
-
+
if (EventType == UIEventTimeOut) {
gUserInput->Action = BROWSER_ACTION_FORM_EXIT;
ControlFlag = CfExit;
@@ -2584,12 +3208,12 @@ UiDisplayMenu (
// 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;
}
- ASSERT(MenuOption != NULL);
Statement = MenuOption->ThisTag;
if ((Statement->OpCode->OpCode == EFI_IFR_DATE_OP)
|| (Statement->OpCode->OpCode == EFI_IFR_TIME_OP)
@@ -2600,7 +3224,7 @@ UiDisplayMenu (
} else {
gDirection = SCAN_LEFT;
}
-
+
Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);
if (OptionString != NULL) {
FreePool (OptionString);
@@ -2631,7 +3255,7 @@ UiDisplayMenu (
ControlFlag = CfReadKey;
break;
}
-
+
ASSERT(MenuOption != NULL);
if (MenuOption->ThisTag->OpCode->OpCode == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut && !MenuOption->ReadOnly) {
ScreenOperation = UiSelect;
@@ -2665,7 +3289,7 @@ UiDisplayMenu (
break;
}
}
-
+
if (((FormData->Attribute & HII_DISPLAY_MODAL) != 0) && (Key.ScanCode == SCAN_ESC || Index == mScanCodeNumber)) {
//
// ModalForm has no ESC key and Hot Key.
@@ -2686,9 +3310,9 @@ UiDisplayMenu (
break;
case CfScreenOperation:
- if (ScreenOperation != UiReset) {
+ if ((ScreenOperation != UiReset) && (ScreenOperation != UiHotKey)) {
//
- // If the screen has no menu items, and the user didn't select UiReset
+ // 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)) {
@@ -2698,7 +3322,7 @@ UiDisplayMenu (
}
for (Index = 0;
- Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);
+ Index < ARRAY_SIZE (gScreenOperationToControlFlag);
Index++
) {
if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {
@@ -2730,11 +3354,11 @@ UiDisplayMenu (
//
RefreshKeyHelp (gFormData, Statement, TRUE);
Status = ProcessOptions (MenuOption, TRUE, &OptionString, TRUE);
-
+
if (OptionString != NULL) {
FreePool (OptionString);
}
-
+
if (EFI_ERROR (Status)) {
Repaint = TRUE;
NewLine = TRUE;
@@ -2759,22 +3383,27 @@ UiDisplayMenu (
break;
}
- //
- // When user press ESC, it will try to show another menu, should clean the gSequence info.
- //
- if (gSequence != 0) {
- gSequence = 0;
- }
-
gUserInput->Action = BROWSER_ACTION_FORM_EXIT;
ControlFlag = CfExit;
break;
case CfUiHotKey:
ControlFlag = CfRepaint;
-
- gUserInput->Action = HotKey->Action;
- ControlFlag = CfExit;
+
+ 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:
@@ -2807,208 +3436,129 @@ UiDisplayMenu (
case CfUiUp:
ControlFlag = CfRepaint;
+ NewLine = TRUE;
SavedListEntry = NewPos;
-
ASSERT(NewPos != NULL);
- //
- // Adjust Date/Time position before we advance forward.
- //
- AdjustDateAndTimePosition (TRUE, &NewPos);
- if (NewPos->BackLink != &gMenuOption) {
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- ASSERT (MenuOption != NULL);
- NewLine = TRUE;
- NewPos = NewPos->BackLink;
-
- PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (PreviousMenuOption->Row == 0) {
- UpdateOptionSkipLines (PreviousMenuOption);
- }
- DistanceValue = PreviousMenuOption->Skip;
- Difference = 0;
- if (MenuOption->Row >= DistanceValue + TopRow) {
- Difference = MoveToNextStatement (TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);
- }
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
-
- if (Difference < 0) {
- //
- // We hit the begining MenuOption that can be focused
- // so we simply scroll to the top.
- //
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- } else {
- //
- // Scroll up to the last page when we have arrived at top page.
- //
- NewPos = &gMenuOption;
- TopOfScreen = &gMenuOption;
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- ScreenOperation = UiPageUp;
- ControlFlag = CfScreenOperation;
- break;
- }
- } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {
- //
- // Previous focus MenuOption is above the TopOfScreen, so we need to scroll
- //
- TopOfScreen = NewPos;
- Repaint = TRUE;
- SkipValue = 0;
- } else if (!IsSelectable (NextMenuOption)) {
- //
- // Continue to go up until scroll to next page or the selectable option is found.
- //
- ScreenOperation = UiUp;
- ControlFlag = CfScreenOperation;
- }
-
- //
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- UpdateStatusBar (INPUT_ERROR, FALSE);
- } else {
- //
- // Scroll up to the last page.
- //
- NewPos = &gMenuOption;
- TopOfScreen = &gMenuOption;
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- ScreenOperation = UiPageUp;
- ControlFlag = CfScreenOperation;
- }
- break;
-
- case CfUiPageUp:
- //
- // SkipValue means lines is skipped when show the top menu option.
- //
- ControlFlag = CfRepaint;
-
- ASSERT(NewPos != NULL);
- //
- // Already at the first menu option, Check the skip value.
- //
- if (NewPos->BackLink == &gMenuOption) {
- if (SkipValue == 0) {
- NewLine = FALSE;
- Repaint = FALSE;
- } else {
- NewLine = TRUE;
- Repaint = TRUE;
- SkipValue = 0;
- }
- break;
- }
- NewLine = TRUE;
- Repaint = TRUE;
+ MenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ ASSERT (MenuOption != NULL);
//
- // 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.
+ // Adjust Date/Time position before we advance forward.
//
- if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {
- SkipValue -= BottomRow - TopRow + 1;
- break;
- }
+ AdjustDateAndTimePosition (TRUE, &NewPos);
- Link = TopOfScreen;
+ NewPos = NewPos->BackLink;
//
- // First minus the menu of the top screen, it's value is SkipValue.
+ // Find next selectable menu or the first menu beyond current form.
//
- Index = (BottomRow + 1) - SkipValue;
- while ((Index > TopRow) && (Link->BackLink != &gMenuOption)) {
- Link = Link->BackLink;
- PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
- if (PreviousMenuOption->Row == 0) {
- UpdateOptionSkipLines (PreviousMenuOption);
- }
- if (Index < PreviousMenuOption->Skip) {
- break;
- }
- Index = Index - PreviousMenuOption->Skip;
- }
-
- if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {
- SkipValue = 0;
- if (TopOfScreen == &gMenuOption) {
+ 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 = gMenuOption.BackLink;
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);
- Repaint = FALSE;
- } else if (TopOfScreen != Link) {
- TopOfScreen = Link;
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
+ NewPos = SavedListEntry;
+ SkipValue = 0;
} else {
//
- // Finally we know that NewPos is the last MenuOption can be focused.
+ // Scroll up to the last page when we have arrived at top page.
//
- Repaint = FALSE;
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
+ TopOfScreen = FindTopOfScreenMenu (gMenuOption.BackLink, BottomRow - TopRow, &SkipValue);
+ NewPos = gMenuOption.BackLink;
+ MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow, TRUE);
}
} else {
- if (Index > TopRow) {
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+
+ if (MenuOption->Row < TopRow + Difference + NextMenuOption->Skip) {
//
- // At here, only case "Index < PreviousMenuOption->Skip" can reach here.
+ // Previous focus MenuOption is above the TopOfScreen, so we need to scroll
//
- SkipValue = PreviousMenuOption->Skip - (Index - TopRow);
- } else if (Index == TopRow) {
- SkipValue = 0;
- } else {
- SkipValue = TopRow - Index;
+ TopOfScreen = NewPos;
+ Repaint = TRUE;
+ SkipValue = 0;
}
//
- // Move to the option in Next page.
+ // Check whether new highlight menu is selectable, if not, keep highlight on the old one.
//
- if (TopOfScreen == &gMenuOption) {
- NewPos = gMenuOption.BackLink;
- MoveToNextStatement (TRUE, &NewPos, BottomRow - TopRow);
- } else {
- NewPos = Link;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
+ // 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) {
//
- // There are more MenuOption needing scrolling up.
+ // 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.
//
- TopOfScreen = Link;
- MenuOption = NULL;
+ 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;
-
- ASSERT (NewPos != NULL);
- if (NewPos->ForwardLink == &gMenuOption) {
- NewLine = FALSE;
- Repaint = FALSE;
- break;
- }
+ ControlFlag = CfRepaint;
+ NewLine = TRUE;
+ Repaint = TRUE;
- NewLine = TRUE;
- Repaint = TRUE;
Link = TopOfScreen;
NextMenuOption = MENU_OPTION_FROM_LINK (Link);
Index = TopRow + NextMenuOption->Skip - SkipValue;
@@ -3023,10 +3573,10 @@ UiDisplayMenu (
if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {
//
- // Finally we know that NewPos is the last MenuOption can be focused.
+ // Highlight on the last menu which can be highlight.
//
Repaint = FALSE;
- MoveToNextStatement (TRUE, &Link, Index - TopRow);
+ MoveToNextStatement (TRUE, &Link, Index - TopRow, TRUE);
} else {
//
// Calculate the skip line for top of screen menu.
@@ -3039,13 +3589,12 @@ UiDisplayMenu (
} else {
SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));
}
-
TopOfScreen = Link;
MenuOption = NULL;
//
// Move to the Next selectable menu.
//
- MoveToNextStatement (FALSE, &Link, BottomRow - TopRow);
+ MoveToNextStatement (FALSE, &Link, BottomRow - TopRow, TRUE);
}
//
@@ -3053,12 +3602,16 @@ UiDisplayMenu (
//
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:
@@ -3067,7 +3620,15 @@ UiDisplayMenu (
// 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
@@ -3076,181 +3637,143 @@ UiDisplayMenu (
// op-code is the last entry in the menu, we need to rewind back to the first op-code of
// the Date/Time op-code.
//
- SavedListEntry = NewPos;
AdjustDateAndTimePosition (FALSE, &NewPos);
- if (NewPos->ForwardLink != &gMenuOption) {
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- NewLine = TRUE;
- NewPos = NewPos->ForwardLink;
-
- Difference = 0;
+ 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) {
//
- // Current menu not at the bottom of the form.
+ // Scroll to the first page.
//
- if (BottomRow >= MenuOption->Row + MenuOption->Skip) {
- //
- // Find the next selectable menu.
- //
- Difference = MoveToNextStatement (FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);
- //
- // We hit the end of MenuOption that can be focused
- // so we simply scroll to the first page.
- //
- if (Difference < 0) {
- //
- // Scroll to the first page.
- //
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
- } else {
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- }
- NewPos = gMenuOption.ForwardLink;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
-
- SkipValue = 0;
- //
- // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
- }
- }
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (NextMenuOption->Row == 0) {
- UpdateOptionSkipLines (NextMenuOption);
- }
- DistanceValue = Difference + NextMenuOption->Skip;
-
- Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;
- if ((MenuOption->Row + MenuOption->Skip == BottomRow + 1) &&
- (NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_DATE_OP ||
- NextMenuOption->ThisTag->OpCode->OpCode == EFI_IFR_TIME_OP)
- ) {
- Temp ++;
+ if (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 going to scroll, update TopOfScreen
+ // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
//
- if (Temp > BottomRow) {
- do {
- //
- // Is the current top of screen a zero-advance op-code?
- // If so, keep moving forward till we hit a >0 advance op-code
- //
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
-
- //
- // If bottom op-code is more than one line or top op-code is more than one line
- //
- if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {
- //
- // Is the bottom op-code greater than or equal in size to the top op-code?
- //
- if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
- //
- // Skip the top op-code
- //
- TopOfScreen = TopOfScreen->ForwardLink;
- Difference = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
-
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
-
- //
- // If we have a remainder, skip that many more op-codes until we drain the remainder
- //
- while (Difference >= (INTN) SavedMenuOption->Skip) {
- //
- // Since the Difference is greater than or equal to this op-code's skip value, skip it
- //
- Difference = Difference - (INTN) SavedMenuOption->Skip;
- TopOfScreen = TopOfScreen->ForwardLink;
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
- }
- //
- // Since we will act on this op-code in the next routine, and increment the
- // SkipValue, set the skips to one less than what is required.
- //
- SkipValue = Difference - 1;
- } else {
- //
- // Since we will act on this op-code in the next routine, and increment the
- // SkipValue, set the skips to one less than what is required.
- //
- SkipValue += (Temp - BottomRow) - 1;
- }
- } else {
- if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {
- TopOfScreen = TopOfScreen->ForwardLink;
- break;
- }
- }
- //
- // If the op-code at the top of the screen is more than one line, let's not skip it yet
- // Let's set a skip flag to smoothly scroll the top of the screen.
- //
- if (SavedMenuOption->Skip > 1) {
- if (SavedMenuOption == NextMenuOption) {
- SkipValue = 0;
- } else {
- SkipValue++;
- }
- } else if (SavedMenuOption->Skip == 1) {
- SkipValue = 0;
- } else {
- SkipValue = 0;
- TopOfScreen = TopOfScreen->ForwardLink;
- }
- } while (SavedMenuOption->Skip == 0);
+ AdjustDateAndTimePosition (TRUE, &TopOfScreen);
+ AdjustDateAndTimePosition (TRUE, &NewPos);
- 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;
- }
+ UpdateHighlightMenuInfo(NewPos, TopOfScreen, SkipValue);
+ break;
+ }
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ //
+ // Get next selected menu info.
+ //
+ AdjustDateAndTimePosition (FALSE, &NewPos);
+ NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
+ if (NextMenuOption->Row == 0) {
+ UpdateOptionSkipLines (NextMenuOption);
+ }
- UpdateStatusBar (INPUT_ERROR, FALSE);
+ //
+ // 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);
- } else {
//
- // Scroll to the first page.
+ // Current Top screen menu occupy (SavedMenuOption->Skip - SkipValue) rows.
+ // Full shows the new selected menu need to skip (Temp - BottomRow - 1) rows.
//
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
+ 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 {
//
- // Need to remove the current highlight menu.
- // MenuOption saved the last highlight menu info.
+ // 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.
//
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
+ SkipValue += Temp - BottomRow;
}
-
- SkipValue = 0;
- NewLine = TRUE;
+ Repaint = TRUE;
+ } else if (!IsSelectable (NextMenuOption)) {
//
- // Get the next highlight menu.
+ // Continue to go down until scroll to next page or the selectable option is found.
//
- NewPos = gMenuOption.ForwardLink;
- MoveToNextStatement (FALSE, &NewPos, BottomRow - TopRow);
+ 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:
@@ -3276,6 +3799,34 @@ UiDisplayMenu (
}
}
+/**
+ Free the UI Menu Option structure data.
+
+ @param MenuOptionList Point to the menu option list which need to be free.
+
+**/
+VOID
+FreeMenuOptionData(
+ LIST_ENTRY *MenuOptionList
+ )
+{
+ LIST_ENTRY *Link;
+ UI_MENU_OPTION *Option;
+
+ //
+ // Free menu option list
+ //
+ while (!IsListEmpty (MenuOptionList)) {
+ Link = GetFirstNode (MenuOptionList);
+ Option = MENU_OPTION_FROM_LINK (Link);
+ if (Option->Description != NULL){
+ FreePool(Option->Description);
+ }
+ RemoveEntryList (&Option->Link);
+ FreePool (Option);
+ }
+}
+
/**
Base on the browser status info to show an pop up message.
@@ -3286,14 +3837,56 @@ BrowserStatusProcess (
VOID
)
{
- CHAR16 *ErrorInfo;
- EFI_INPUT_KEY Key;
+ 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;
}
- if (gFormData->ErrorString != NULL) {
+ 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) {
@@ -3301,10 +3894,6 @@ BrowserStatusProcess (
ErrorInfo = gSaveFailed;
break;
- case BROWSER_NO_SUBMIT_IF:
- ErrorInfo = gNoSubmitIf;
- break;
-
case BROWSER_FORM_NOT_FOUND:
ErrorInfo = gFormNotFound;
break;
@@ -3317,33 +3906,131 @@ BrowserStatusProcess (
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 = gBrwoserError;
+ ErrorInfo = gBrowserError;
break;
}
}
- //
- // Error occur, prompt error message.
- //
- do {
- CreateDialog (&Key, gEmptyString, ErrorInfo, gPressEnter, gEmptyString, NULL);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ 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
+EFIAPI
FormDisplay (
IN FORM_DISPLAY_ENGINE_FORM *FormData,
OUT USER_INPUT *UserInputData
@@ -3363,24 +4050,37 @@ FormDisplay (
// Process the status info first.
//
BrowserStatusProcess();
- if (UserInputData == NULL) {
+ if (gFormData->BrowserStatus != BROWSER_SUCCESS) {
//
- // UserInputData == NULL, means only need to print the error info, return here.
+ // gFormData->BrowserStatus != BROWSER_SUCCESS, means only need to print the error info, return here.
//
return EFI_SUCCESS;
}
- ConvertStatementToMenu();
-
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
+ if (mIsFirstForm
|| (gOldFormEntry.HiiHandle != FormData->HiiHandle)
|| (!CompareGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid))
|| (gOldFormEntry.FormId != FormData->FormId)) {
@@ -3390,7 +4090,7 @@ FormDisplay (
}
Status = UiDisplayMenu(FormData);
-
+
//
// Backup last form info.
//
@@ -3399,6 +4099,11 @@ FormDisplay (
CopyGuid (&gOldFormEntry.FormSetGuid, &FormData->FormSetGuid);
gOldFormEntry.FormId = FormData->FormId;
+ //
+ //Free the Ui menu option list.
+ //
+ FreeMenuOptionData(&gMenuOption);
+
return Status;
}
@@ -3406,7 +4111,7 @@ FormDisplay (
Clear Screen to the initial state.
**/
VOID
-EFIAPI
+EFIAPI
DriverClearDisplayPage (
VOID
)
@@ -3482,14 +4187,25 @@ InitializeDisplayEngine (
);
ASSERT_EFI_ERROR (Status);
+ //
+ // Install HII Popup Protocol.
+ //
+ Status = gBS->InstallProtocolInterface (
+ &mPrivateData.Handle,
+ &gEfiHiiPopupProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mPrivateData.HiiPopup
+ );
+ 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)) {
//
@@ -3500,11 +4216,13 @@ InitializeDisplayEngine (
NewString = HiiGetString (gHiiHandle, STRING_TOKEN (FUNCTION_TEN_STRING), NULL);
ASSERT (NewString != NULL);
FormBrowserEx2->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);
+ FreePool (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);
+ FreePool (NewString);
}
return EFI_SUCCESS;
@@ -3529,5 +4247,13 @@ UnloadDisplayEngine (
FreeDisplayStrings ();
+ if (gHighligthMenuInfo.HLTOpCode != NULL) {
+ FreePool (gHighligthMenuInfo.HLTOpCode);
+ }
+
+ if (gHighligthMenuInfo.TOSOpCode != NULL) {
+ FreePool (gHighligthMenuInfo.TOSOpCode);
+ }
+
return EFI_SUCCESS;
}