/** @file\r
Utility functions for UI presentation.\r
\r
-Copyright (c) 2004 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
+Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
http://opensource.org/licenses/bsd-license.php\r
**/\r
\r
#include "Setup.h"\r
-#include "Ui.h"\r
\r
BOOLEAN mHiiPackageListUpdated;\r
UI_MENU_SELECTION *gCurrentSelection;\r
-\r
+EFI_HII_HANDLE mCurrentHiiHandle = NULL;\r
+EFI_GUID mCurrentFormSetGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
+UINT16 mCurrentFormId = 0;\r
\r
/**\r
Clear retangle with specified text attribute.\r
**/\r
VOID\r
ClearLines (\r
- UINTN LeftColumn,\r
- UINTN RightColumn,\r
- UINTN TopRow,\r
- UINTN BottomRow,\r
- UINTN TextAttribute\r
+ IN UINTN LeftColumn,\r
+ IN UINTN RightColumn,\r
+ IN UINTN TopRow,\r
+ IN UINTN BottomRow,\r
+ IN UINTN TextAttribute\r
)\r
{\r
CHAR16 *Buffer;\r
\r
gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);\r
\r
- gBS->FreePool (Buffer);\r
+ FreePool (Buffer);\r
return ;\r
}\r
\r
**/\r
VOID\r
NewStrCat (\r
- CHAR16 *Destination,\r
- CHAR16 *Source\r
+ IN OUT CHAR16 *Destination,\r
+ IN CHAR16 *Source\r
)\r
{\r
UINTN Length;\r
\r
This function handles the Unicode string with NARROW_CHAR\r
and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR\r
- does not count in the resultant output. If a WIDE_CHAR is \r
+ does not count in the resultant output. If a WIDE_CHAR is\r
hit, then 2 Unicode character will consume an output storage\r
space with size of CHAR16 till a NARROW_CHAR is hit.\r
\r
+ If String is NULL, then ASSERT ().\r
+\r
@param String The input string to be counted.\r
\r
@return Storage space for the input string.\r
**/\r
UINTN\r
GetStringWidth (\r
- CHAR16 *String\r
+ IN CHAR16 *String\r
)\r
{\r
UINTN Index;\r
UINTN Count;\r
UINTN IncrementValue;\r
\r
+ ASSERT (String != NULL);\r
+ if (String == NULL) {\r
+ return 0;\r
+ }\r
+\r
Index = 0;\r
Count = 0;\r
IncrementValue = 1;\r
/**\r
This function displays the page frame.\r
\r
+ @param Selection Selection contains the information about \r
+ the Selection, form and formset to be displayed.\r
+ Selection action may be updated in retrieve callback.\r
**/\r
VOID\r
DisplayPageFrame (\r
- VOID\r
+ IN UI_MENU_SELECTION *Selection\r
)\r
{\r
UINTN Index;\r
CHAR16 *StrFrontPageBanner;\r
UINTN Row;\r
EFI_SCREEN_DESCRIPTOR LocalScreen;\r
+ UINT8 RowIdx;\r
+ UINT8 ColumnIdx;\r
\r
ZeroMem (&LocalScreen, sizeof (EFI_SCREEN_DESCRIPTOR));\r
gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &LocalScreen.RightColumn, &LocalScreen.BottomRow);\r
ClearLines (0, LocalScreen.RightColumn, 0, LocalScreen.BottomRow, KEYHELP_BACKGROUND);\r
\r
+ if (Selection->Form->ModalForm) {\r
+ return;\r
+ }\r
+\r
CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
\r
//\r
Buffer[Index] = Character;\r
}\r
\r
- if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {\r
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
//\r
// ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);\r
//\r
Alignment < BANNER_COLUMNS + (UINT8) LocalScreen.LeftColumn;\r
Alignment++\r
) {\r
- if (BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn] != 0x0000) {\r
+ RowIdx = (UINT8) (Line - (UINT8) LocalScreen.TopRow);\r
+ ColumnIdx = (UINT8) (Alignment - (UINT8) LocalScreen.LeftColumn);\r
+\r
+ ASSERT (RowIdx < BANNER_HEIGHT);\r
+ ASSERT (ColumnIdx < BANNER_COLUMNS);\r
+\r
+ if (gBannerData->Banner[RowIdx][ColumnIdx] != 0x0000) {\r
StrFrontPageBanner = GetToken (\r
- BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn],\r
- FrontPageHandle\r
+ gBannerData->Banner[RowIdx][ColumnIdx],\r
+ gFrontPageHandle\r
);\r
} else {\r
continue;\r
//\r
// Handle left column\r
//\r
- PrintStringAt (LocalScreen.LeftColumn, Line, StrFrontPageBanner);\r
+ PrintStringAt (LocalScreen.LeftColumn + BANNER_LEFT_COLUMN_INDENT, Line, StrFrontPageBanner);\r
break;\r
\r
case 1:\r
break;\r
}\r
\r
- gBS->FreePool (StrFrontPageBanner);\r
+ FreePool (StrFrontPageBanner);\r
}\r
}\r
}\r
ClearLines (\r
LocalScreen.LeftColumn,\r
LocalScreen.RightColumn,\r
- LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT,\r
+ LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight,\r
LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,\r
KEYHELP_TEXT | KEYHELP_BACKGROUND\r
);\r
\r
- if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {\r
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {\r
ClearLines (\r
LocalScreen.LeftColumn,\r
LocalScreen.RightColumn,\r
Character = BOXDRAW_UP_LEFT;\r
PrintChar (Character);\r
\r
- if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {\r
+ if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
//\r
// Print Bottom border line\r
// +------------------------------------------------------------------------------+\r
// +------------------------------------------------------------------------------+\r
//\r
Character = BOXDRAW_DOWN_RIGHT;\r
- PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT, Character);\r
+ PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight, Character);\r
\r
PrintString (Buffer);\r
\r
Character = BOXDRAW_DOWN_LEFT;\r
PrintChar (Character);\r
Character = BOXDRAW_VERTICAL;\r
- for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT + 1;\r
+ for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;\r
Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;\r
Row++\r
) {\r
}\r
}\r
\r
- gBS->FreePool (Buffer);\r
+ FreePool (Buffer);\r
\r
}\r
\r
Link = GetNextNode (&Form->ExpressionListHead, Link);\r
\r
if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF ||\r
- Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {\r
+ Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF ||\r
+ Expression->Type == EFI_HII_EXPRESSION_WRITE ||\r
+ (Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) {\r
//\r
- // Postpone Form validation to Question editing or Form submiting\r
+ // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.\r
//\r
continue;\r
}\r
\r
/*\r
+------------------------------------------------------------------------------+\r
-?F2=Previous Page Setup Page ?\r
+? Setup Page ?\r
+------------------------------------------------------------------------------+\r
\r
\r
\r
/**\r
\r
- \r
+\r
Display form and wait for user to select one menu option, then return it.\r
- \r
+\r
@param Selection On input, Selection tell setup browser the information\r
about the Selection, form and formset to be displayed.\r
On output, Selection return the screen item that is selected\r
FORM_BROWSER_STATEMENT *Statement;\r
UINT16 NumberOfLines;\r
EFI_STATUS Status;\r
+ UI_MENU_OPTION *MenuOption;\r
\r
Handle = Selection->Handle;\r
MenuItemCount = 0;\r
\r
StringPtr = GetToken (Selection->Form->FormTitle, Handle);\r
\r
- if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {\r
- gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);\r
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {\r
+ if (Selection->Form->ModalForm) {\r
+ gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | EFI_BACKGROUND_BLACK);\r
+ } else {\r
+ gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);\r
+ }\r
PrintStringAt (\r
(LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,\r
LocalScreen.TopRow + 1,\r
);\r
}\r
\r
- if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {\r
- gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
-\r
- //\r
- // Display the infrastructure strings\r
- //\r
- if (!IsListEmpty (&gMenuList)) {\r
- PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.TopRow + 1, gFunctionTwoString);\r
- }\r
-\r
- PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 4, gFunctionOneString);\r
- PrintStringAt (\r
- LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,\r
- LocalScreen.BottomRow - 4,\r
- gFunctionNineString\r
- );\r
- PrintStringAt (\r
- LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,\r
- LocalScreen.BottomRow - 4,\r
- gFunctionTenString\r
- );\r
- PrintAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 3, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
- PrintStringAt (\r
- LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,\r
- LocalScreen.BottomRow - 3,\r
- gEscapeString\r
- );\r
- }\r
//\r
// Remove Buffer allocated for StringPtr after it has been used.\r
//\r
- gBS->FreePool (StringPtr);\r
+ FreePool (StringPtr);\r
\r
//\r
// Evaluate all the Expressions in this Form\r
return Status;\r
}\r
\r
+ Selection->FormEditable = FALSE;\r
Link = GetFirstNode (&Selection->Form->StatementListHead);\r
while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
Suppress = FALSE;\r
}\r
\r
+ if (Statement->DisableExpression != NULL) {\r
+ Suppress = (BOOLEAN) (Suppress || Statement->DisableExpression->Result.Value.b);\r
+ }\r
+\r
if (!Suppress) {\r
StringPtr = GetToken (Statement->Prompt, Handle);\r
+ ASSERT (StringPtr != NULL);\r
\r
Width = GetWidth (Statement, Handle);\r
\r
//\r
// If there is more string to process print on the next row and increment the Skip value\r
//\r
- if (StrLen (&StringPtr[ArrayEntry])) {\r
+ if (StrLen (&StringPtr[ArrayEntry]) != 0) {\r
NumberOfLines++;\r
}\r
\r
- gBS->FreePool (OutputString);\r
+ FreePool (OutputString);\r
}\r
\r
//\r
// We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do\r
// it in UiFreeMenu.\r
//\r
- UiAddMenuOption (StringPtr, Selection->Handle, Statement, NumberOfLines, MenuItemCount);\r
+ MenuOption = UiAddMenuOption (StringPtr, Selection->Handle, Selection->Form, Statement, NumberOfLines, MenuItemCount);\r
MenuItemCount++;\r
+\r
+ if (MenuOption->IsQuestion && !MenuOption->ReadOnly) {\r
+ //\r
+ // At least one item is not readonly, this Form is considered as editable\r
+ //\r
+ Selection->FormEditable = TRUE;\r
+ }\r
}\r
\r
Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
VOID\r
)\r
{\r
- gFunctionOneString = GetToken (STRING_TOKEN (FUNCTION_ONE_STRING), gHiiHandle);\r
- gFunctionTwoString = GetToken (STRING_TOKEN (FUNCTION_TWO_STRING), gHiiHandle);\r
- gFunctionNineString = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);\r
- gFunctionTenString = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);\r
gEnterString = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle);\r
gEnterCommitString = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle);\r
+ gEnterEscapeString = GetToken (STRING_TOKEN (ENTER_ESCAPE_STRING), gHiiHandle);\r
gEscapeString = GetToken (STRING_TOKEN (ESCAPE_STRING), gHiiHandle);\r
- gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);\r
gMoveHighlight = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle);\r
gMakeSelection = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle);\r
gDecNumericInput = GetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), gHiiHandle);\r
gPlusString = GetToken (STRING_TOKEN (PLUS_STRING), gHiiHandle);\r
gMinusString = GetToken (STRING_TOKEN (MINUS_STRING), gHiiHandle);\r
gAdjustNumber = GetToken (STRING_TOKEN (ADJUST_NUMBER), gHiiHandle);\r
+ gSaveChanges = GetToken (STRING_TOKEN (SAVE_CHANGES), gHiiHandle);\r
+ gOptionMismatch = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);\r
+ gFormSuppress = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);\r
return ;\r
}\r
\r
VOID\r
)\r
{\r
- SafeFreePool (gFunctionOneString);\r
- SafeFreePool (gFunctionTwoString);\r
- SafeFreePool (gFunctionNineString);\r
- SafeFreePool (gFunctionTenString);\r
- SafeFreePool (gEnterString);\r
- SafeFreePool (gEnterCommitString);\r
- SafeFreePool (gEscapeString);\r
- SafeFreePool (gMoveHighlight);\r
- SafeFreePool (gMakeSelection);\r
- SafeFreePool (gDecNumericInput);\r
- SafeFreePool (gHexNumericInput);\r
- SafeFreePool (gToggleCheckBox);\r
- SafeFreePool (gPromptForData);\r
- SafeFreePool (gPromptForPassword);\r
- SafeFreePool (gPromptForNewPassword);\r
- SafeFreePool (gConfirmPassword);\r
- SafeFreePool (gPassowordInvalid);\r
- SafeFreePool (gConfirmError);\r
- SafeFreePool (gPressEnter);\r
- SafeFreePool (gEmptyString);\r
- SafeFreePool (gAreYouSure);\r
- SafeFreePool (gYesResponse);\r
- SafeFreePool (gNoResponse);\r
- SafeFreePool (gMiniString);\r
- SafeFreePool (gPlusString);\r
- SafeFreePool (gMinusString);\r
- SafeFreePool (gAdjustNumber);\r
+ FreePool (gEnterString);\r
+ FreePool (gEnterCommitString);\r
+ FreePool (gEnterEscapeString);\r
+ FreePool (gEscapeString);\r
+ FreePool (gMoveHighlight);\r
+ FreePool (gMakeSelection);\r
+ FreePool (gDecNumericInput);\r
+ FreePool (gHexNumericInput);\r
+ FreePool (gToggleCheckBox);\r
+ FreePool (gPromptForData);\r
+ FreePool (gPromptForPassword);\r
+ FreePool (gPromptForNewPassword);\r
+ FreePool (gConfirmPassword);\r
+ FreePool (gPassowordInvalid);\r
+ FreePool (gConfirmError);\r
+ FreePool (gPressEnter);\r
+ FreePool (gEmptyString);\r
+ FreePool (gAreYouSure);\r
+ FreePool (gYesResponse);\r
+ FreePool (gNoResponse);\r
+ FreePool (gMiniString);\r
+ FreePool (gPlusString);\r
+ FreePool (gMinusString);\r
+ FreePool (gAdjustNumber);\r
+ FreePool (gSaveChanges);\r
+ FreePool (gOptionMismatch);\r
+ FreePool (gFormSuppress);\r
return ;\r
}\r
\r
+/**\r
+ Show all registered HotKey help strings on bottom Rows.\r
+\r
+**/\r
+VOID\r
+PrintHotKeyHelpString (\r
+ VOID\r
+ )\r
+{\r
+ UINTN CurrentCol;\r
+ UINTN CurrentRow;\r
+ UINTN BottomRowOfHotKeyHelp;\r
+ UINTN ColumnWidth;\r
+ UINTN Index;\r
+ EFI_SCREEN_DESCRIPTOR LocalScreen;\r
+ LIST_ENTRY *Link;\r
+ BROWSER_HOT_KEY *HotKey;\r
+\r
+ CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+ ColumnWidth = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;\r
+ BottomRowOfHotKeyHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3;\r
+\r
+ //\r
+ // Calculate total number of Register HotKeys. \r
+ //\r
+ Index = 0;\r
+ Link = GetFirstNode (&gBrowserHotKeyList);\r
+ while (!IsNull (&gBrowserHotKeyList, Link)) {\r
+ HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
+ //\r
+ // Help string can't exceed ColumnWidth. One Row will show three Help information. \r
+ //\r
+ if (StrLen (HotKey->HelpString) > ColumnWidth) {\r
+ HotKey->HelpString[ColumnWidth] = L'\0';\r
+ }\r
+ //\r
+ // Calculate help information Column and Row.\r
+ //\r
+ if ((Index % 3) != 2) {\r
+ CurrentCol = LocalScreen.LeftColumn + (2 - Index % 3) * ColumnWidth;\r
+ } else {\r
+ CurrentCol = LocalScreen.LeftColumn + 2;\r
+ }\r
+ CurrentRow = BottomRowOfHotKeyHelp - Index / 3;\r
+ //\r
+ // Print HotKey help string on bottom Row.\r
+ //\r
+ PrintStringAt (CurrentCol, CurrentRow, HotKey->HelpString);\r
+\r
+ //\r
+ // Get Next Hot Key.\r
+ //\r
+ Link = GetNextNode (&gBrowserHotKeyList, Link);\r
+ Index ++;\r
+ }\r
+ \r
+ return;\r
+}\r
\r
/**\r
Update key's help imformation.\r
\r
+ @param Selection Tell setup browser the information about the Selection\r
@param MenuOption The Menu option\r
@param Selected Whether or not a tag be selected\r
\r
**/\r
VOID\r
UpdateKeyHelp (\r
+ IN UI_MENU_SELECTION *Selection,\r
IN UI_MENU_OPTION *MenuOption,\r
IN BOOLEAN Selected\r
)\r
EFI_SCREEN_DESCRIPTOR LocalScreen;\r
FORM_BROWSER_STATEMENT *Statement;\r
\r
+ gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
+\r
+ if (Selection->Form->ModalForm) {\r
+ return;\r
+ }\r
+\r
CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
\r
SecCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;\r
- ThdCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3;\r
+ ThdCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3 * 2;\r
\r
StartColumnOfHelp = LocalScreen.LeftColumn + 2;\r
LeftColumnOfHelp = LocalScreen.LeftColumn + 1;\r
RightColumnOfHelp = LocalScreen.RightColumn - 2;\r
- TopRowOfHelp = LocalScreen.BottomRow - 4;\r
- BottomRowOfHelp = LocalScreen.BottomRow - 3;\r
-\r
- if (gClassOfVfr == EFI_GENERAL_APPLICATION_SUBCLASS) {\r
- return ;\r
- }\r
-\r
- gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
+ TopRowOfHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;\r
+ BottomRowOfHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;\r
\r
Statement = MenuOption->ThisTag;\r
switch (Statement->Operand) {\r
ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
\r
if (!Selected) {\r
- if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {\r
- PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);\r
- PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);\r
- PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);\r
+ //\r
+ // On system setting, HotKey will show on every form.\r
+ //\r
+ if (gBrowserSettingScope == SystemLevel ||\r
+ (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {\r
+ PrintHotKeyHelpString ();\r
+ }\r
+\r
+ if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
}\r
\r
if ((Statement->Operand == EFI_IFR_DATE_OP) ||\r
- (Statement->Operand == EFI_IFR_TIME_OP) ||\r
- (Statement->Operand == EFI_IFR_NUMERIC_OP && Statement->Step != 0)) {\r
+ (Statement->Operand == EFI_IFR_TIME_OP)) {\r
PrintAt (\r
StartColumnOfHelp,\r
BottomRowOfHelp,\r
ARROW_LEFT,\r
gMoveHighlight\r
);\r
- PrintStringAt (SecCol, BottomRowOfHelp, gAdjustNumber);\r
+ PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);\r
+ PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);\r
} else {\r
PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
+ if (Statement->Operand == EFI_IFR_NUMERIC_OP && Statement->Step != 0) {\r
+ PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);\r
+ } \r
PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);\r
}\r
} else {\r
//\r
// If it is a selected numeric with manual input, display different message\r
//\r
- if ((Statement->Operand == EFI_IFR_NUMERIC_OP) && (Statement->Step == 0)) {\r
+ if ((Statement->Operand == EFI_IFR_NUMERIC_OP) || \r
+ (Statement->Operand == EFI_IFR_DATE_OP) ||\r
+ (Statement->Operand == EFI_IFR_TIME_OP)) {\r
PrintStringAt (\r
SecCol,\r
TopRowOfHelp,\r
PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);\r
}\r
\r
- PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
+ PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);\r
}\r
break;\r
\r
case EFI_IFR_CHECKBOX_OP:\r
ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
\r
- if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {\r
- PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);\r
- PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);\r
- PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);\r
+ //\r
+ // On system setting, HotKey will show on every form.\r
+ //\r
+ if (gBrowserSettingScope == SystemLevel ||\r
+ (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {\r
+ PrintHotKeyHelpString ();\r
+ }\r
+ if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
}\r
\r
case EFI_IFR_TEXT_OP:\r
case EFI_IFR_ACTION_OP:\r
case EFI_IFR_RESET_BUTTON_OP:\r
+ case EFI_IFR_SUBTITLE_OP:\r
ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
\r
if (!Selected) {\r
- if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {\r
- PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);\r
- PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);\r
- PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);\r
+ //\r
+ // On system setting, HotKey will show on every form.\r
+ //\r
+ if (gBrowserSettingScope == SystemLevel ||\r
+ (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {\r
+ PrintHotKeyHelpString ();\r
+ }\r
+ if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
}\r
\r
PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
- if (Statement->Operand != EFI_IFR_TEXT_OP) {\r
+ if (Statement->Operand != EFI_IFR_TEXT_OP && Statement->Operand != EFI_IFR_SUBTITLE_OP) {\r
PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);\r
}\r
} else {\r
BottomRowOfHelp,\r
gEnterCommitString\r
);\r
- PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
+ PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);\r
}\r
}\r
break;\r
\r
**/\r
EFI_STATUS\r
+EFIAPI\r
FormUpdateNotify (\r
IN UINT8 PackageType,\r
IN CONST EFI_GUID *PackageGuid,\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ check whether the formset need to update the NV.\r
+\r
+ @param FormSet FormSet data structure.\r
+\r
+ @retval TRUE Need to update the NV.\r
+ @retval FALSE No need to update the NV.\r
+**/\r
+BOOLEAN \r
+IsNvUpdateRequired (\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_FORM *Form;\r
+\r
+ Link = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, Link)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+ if (Form->NvUpdateRequired ) {\r
+ return TRUE;\r
+ }\r
+\r
+ Link = GetNextNode (&FormSet->FormListHead, Link);\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+/**\r
+ check whether the formset need to update the NV.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param SetValue Whether set new value or clear old value.\r
+\r
+**/\r
+VOID\r
+UpdateNvInfoInForm (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN BOOLEAN SetValue\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_FORM *Form;\r
+ \r
+ Link = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, Link)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+\r
+ Form->NvUpdateRequired = SetValue;\r
+\r
+ Link = GetNextNode (&FormSet->FormListHead, Link);\r
+ }\r
+}\r
+/**\r
+ Find menu which will show next time.\r
+\r
+ @param Selection On input, Selection tell setup browser the information\r
+ about the Selection, form and formset to be displayed.\r
+ On output, Selection return the screen item that is selected\r
+ by user.\r
+ @param Repaint Whether need to repaint the menu.\r
+ @param NewLine Whether need to show at new line.\r
+ \r
+ @retval TRUE Need return.\r
+ @retval FALSE No need to return.\r
+**/\r
+BOOLEAN\r
+FindNextMenu (\r
+ IN OUT UI_MENU_SELECTION *Selection,\r
+ IN BOOLEAN *Repaint, \r
+ IN BOOLEAN *NewLine \r
+ )\r
+{\r
+ UI_MENU_LIST *CurrentMenu;\r
+ CHAR16 YesResponse;\r
+ CHAR16 NoResponse;\r
+ EFI_INPUT_KEY Key;\r
+ BROWSER_SETTING_SCOPE Scope;\r
+ \r
+ CurrentMenu = Selection->CurrentMenu;\r
+\r
+ if (CurrentMenu != NULL && CurrentMenu->Parent != NULL) {\r
+ //\r
+ // we have a parent, so go to the parent menu\r
+ //\r
+ if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) {\r
+ //\r
+ // The parent menu and current menu are in the same formset\r
+ //\r
+ Selection->Action = UI_ACTION_REFRESH_FORM;\r
+ Scope = FormLevel;\r
+ } else {\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ CopyMem (&Selection->FormSetGuid, &CurrentMenu->Parent->FormSetGuid, sizeof (EFI_GUID));\r
+ Selection->Handle = CurrentMenu->Parent->HiiHandle;\r
+ Scope = FormSetLevel;\r
+ }\r
+\r
+ //\r
+ // Form Level Check whether the data is changed.\r
+ //\r
+ if ((gBrowserSettingScope == FormLevel && Selection->Form->NvUpdateRequired) ||\r
+ (gBrowserSettingScope == FormSetLevel && IsNvUpdateRequired(Selection->FormSet) && Scope == FormSetLevel)) {\r
+ gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+ \r
+ YesResponse = gYesResponse[0];\r
+ NoResponse = gNoResponse[0];\r
+ \r
+ //\r
+ // If NV flag is up, prompt user\r
+ //\r
+ do {\r
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString);\r
+ } while\r
+ (\r
+ (Key.ScanCode != SCAN_ESC) &&\r
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&\r
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))\r
+ );\r
+ \r
+ if (Key.ScanCode == SCAN_ESC) {\r
+ //\r
+ // User hits the ESC key, Ingore. \r
+ //\r
+ if (Repaint != NULL) {\r
+ *Repaint = TRUE;\r
+ }\r
+ if (NewLine != NULL) {\r
+ *NewLine = TRUE;\r
+ }\r
+\r
+ Selection->Action = UI_ACTION_NONE;\r
+ return FALSE;\r
+ }\r
+ \r
+ if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {\r
+ //\r
+ // If the user hits the YesResponse key\r
+ //\r
+ SubmitForm (Selection->FormSet, Selection->Form, Scope);\r
+ } else {\r
+ //\r
+ // If the user hits the NoResponse key\r
+ //\r
+ DiscardForm (Selection->FormSet, Selection->Form, Scope);\r
+ }\r
+ }\r
+\r
+ Selection->Statement = NULL;\r
+\r
+ Selection->FormId = CurrentMenu->Parent->FormId;\r
+ Selection->QuestionId = CurrentMenu->Parent->QuestionId;\r
+\r
+ //\r
+ // Clear highlight record for this menu\r
+ //\r
+ CurrentMenu->QuestionId = 0;\r
+ return FALSE;\r
+ }\r
+\r
+ if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {\r
+ //\r
+ // We never exit FrontPage, so skip the ESC\r
+ //\r
+ Selection->Action = UI_ACTION_NONE;\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // We are going to leave current FormSet, so check uncommited data in this FormSet\r
+ //\r
+ if (gBrowserSettingScope != SystemLevel && IsNvUpdateRequired(Selection->FormSet)) {\r
+ gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
+\r
+ YesResponse = gYesResponse[0];\r
+ NoResponse = gNoResponse[0];\r
+\r
+ //\r
+ // If NV flag is up, prompt user\r
+ //\r
+ do {\r
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString);\r
+ } while\r
+ (\r
+ (Key.ScanCode != SCAN_ESC) &&\r
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&\r
+ ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))\r
+ );\r
+\r
+ if (Key.ScanCode == SCAN_ESC) {\r
+ //\r
+ // User hits the ESC key\r
+ //\r
+ if (Repaint != NULL) {\r
+ *Repaint = TRUE;\r
+ }\r
+\r
+ if (NewLine != NULL) {\r
+ *NewLine = TRUE;\r
+ }\r
+\r
+ Selection->Action = UI_ACTION_NONE;\r
+ return FALSE;\r
+ }\r
+\r
+ if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {\r
+ //\r
+ // If the user hits the YesResponse key\r
+ //\r
+ SubmitForm (Selection->FormSet, Selection->Form, FormSetLevel);\r
+ } else {\r
+ //\r
+ // If the user hits the NoResponse key\r
+ //\r
+ DiscardForm (Selection->FormSet, Selection->Form, FormSetLevel);\r
+ }\r
+ }\r
+\r
+ Selection->Statement = NULL;\r
+ if (CurrentMenu != NULL) {\r
+ CurrentMenu->QuestionId = 0;\r
+ }\r
+\r
+ Selection->Action = UI_ACTION_EXIT;\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Call the call back function for the question and process the return action.\r
+\r
+ @param Selection On input, Selection tell setup browser the information\r
+ about the Selection, form and formset to be displayed.\r
+ On output, Selection return the screen item that is selected\r
+ by user.\r
+ @param Question The Question which need to call.\r
+ @param Action The action request.\r
+ @param SkipSaveOrDiscard Whether skip save or discard action.\r
+\r
+ @retval EFI_SUCCESS The call back function excutes successfully.\r
+ @return Other value if the call back function failed to excute. \r
+**/\r
+EFI_STATUS \r
+ProcessCallBackFunction (\r
+ IN OUT UI_MENU_SELECTION *Selection,\r
+ IN FORM_BROWSER_STATEMENT *Question,\r
+ IN EFI_BROWSER_ACTION Action,\r
+ IN BOOLEAN SkipSaveOrDiscard\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
+ EFI_HII_VALUE *HiiValue;\r
+ EFI_IFR_TYPE_VALUE *TypeValue;\r
+ FORM_BROWSER_STATEMENT *Statement;\r
+ BOOLEAN SubmitFormIsRequired;\r
+ BOOLEAN DiscardFormIsRequired;\r
+ BOOLEAN NeedExit;\r
+ LIST_ENTRY *Link;\r
+ BROWSER_SETTING_SCOPE SettingLevel;\r
+\r
+ ConfigAccess = Selection->FormSet->ConfigAccess;\r
+ SubmitFormIsRequired = FALSE;\r
+ SettingLevel = FormSetLevel;\r
+ DiscardFormIsRequired = FALSE;\r
+ NeedExit = FALSE;\r
+ Status = EFI_SUCCESS;\r
+ ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+\r
+ if (ConfigAccess == NULL) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Link = GetFirstNode (&Selection->Form->StatementListHead);\r
+ while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+\r
+ //\r
+ // if Question != NULL, only process the question. Else, process all question in this form.\r
+ //\r
+ if ((Question != NULL) && (Statement != Question)) {\r
+ continue;\r
+ }\r
+ \r
+ if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check whether Statement is disabled.\r
+ //\r
+ if (Statement->DisableExpression != NULL) {\r
+ Status = EvaluateExpression (Selection->FormSet, Selection->Form, Statement->DisableExpression);\r
+ if (!EFI_ERROR (Status) && \r
+ (Statement->DisableExpression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && \r
+ (Statement->DisableExpression->Result.Value.b)) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ HiiValue = &Statement->HiiValue;\r
+ TypeValue = &HiiValue->Value;\r
+ if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+ //\r
+ // For OrderedList, passing in the value buffer to Callback()\r
+ //\r
+ TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
+ }\r
+ \r
+ ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+ Status = ConfigAccess->Callback (\r
+ ConfigAccess,\r
+ Action,\r
+ Statement->QuestionId,\r
+ HiiValue->Type,\r
+ TypeValue,\r
+ &ActionRequest\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ switch (ActionRequest) {\r
+ case EFI_BROWSER_ACTION_REQUEST_RESET:\r
+ gResetRequired = TRUE;\r
+ Selection->Action = UI_ACTION_EXIT;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
+ SubmitFormIsRequired = TRUE;\r
+ Selection->Action = UI_ACTION_EXIT;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+ Selection->Action = UI_ACTION_EXIT;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT:\r
+ SubmitFormIsRequired = TRUE;\r
+ SettingLevel = FormLevel;\r
+ NeedExit = TRUE;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT:\r
+ DiscardFormIsRequired = TRUE;\r
+ SettingLevel = FormLevel; \r
+ NeedExit = TRUE;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY:\r
+ SubmitFormIsRequired = TRUE;\r
+ SettingLevel = FormLevel;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD:\r
+ DiscardFormIsRequired = TRUE;\r
+ SettingLevel = FormLevel;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ //\r
+ // According the spec, return value from call back of "changing" and \r
+ // "retrieve" should update to the question's temp buffer.\r
+ //\r
+ if (Action == EFI_BROWSER_ACTION_CHANGING || Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
+ SetQuestionValue(Selection->FormSet, Selection->Form, Statement, TRUE);\r
+ }\r
+ } else {\r
+ //\r
+ // According the spec, return fail from call back of "changing" and \r
+ // "retrieve", should restore the question's value.\r
+ //\r
+ if (Action == EFI_BROWSER_ACTION_CHANGING || Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
+ GetQuestionValue(Selection->FormSet, Selection->Form, Statement, TRUE);\r
+ }\r
+\r
+ if (Status == EFI_UNSUPPORTED) {\r
+ //\r
+ // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.\r
+ //\r
+ Status = EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (SubmitFormIsRequired && !SkipSaveOrDiscard) {\r
+ SubmitForm (Selection->FormSet, Selection->Form, SettingLevel);\r
+ }\r
+\r
+ if (DiscardFormIsRequired && !SkipSaveOrDiscard) {\r
+ DiscardForm (Selection->FormSet, Selection->Form, SettingLevel);\r
+ }\r
+\r
+ if (NeedExit) {\r
+ FindNextMenu (Selection, NULL, NULL);\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
The worker function that send the displays to the screen. On output,\r
the selection made by user is returned.\r
{\r
EFI_STATUS Status;\r
LIST_ENTRY *Link;\r
- EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
EFI_HANDLE NotifyHandle;\r
- EFI_HII_VALUE *HiiValue;\r
FORM_BROWSER_STATEMENT *Statement;\r
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
+ EFI_INPUT_KEY Key;\r
\r
gMenuRefreshHead = NULL;\r
- gResetRequired = FALSE;\r
- gNvUpdateRequired = FALSE;\r
-\r
- UiInitMenuList ();\r
+ ConfigAccess = Selection->FormSet->ConfigAccess;\r
\r
//\r
// Register notify for Form package update\r
//\r
Status = mHiiDatabase->RegisterPackageNotify (\r
mHiiDatabase,\r
- EFI_HII_PACKAGE_FORM,\r
+ EFI_HII_PACKAGE_FORMS,\r
NULL,\r
FormUpdateNotify,\r
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
return Status;\r
}\r
\r
- do {\r
- //\r
- // Displays the Header and Footer borders\r
- //\r
- DisplayPageFrame ();\r
+ //\r
+ // Initialize current settings of Questions in this FormSet\r
+ //\r
+ Status = InitializeCurrentSetting (Selection->FormSet);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
\r
+ //\r
+ // Update gOldFormSet on maintain back up FormSet list.\r
+ // And, make gOldFormSet point to current FormSet. \r
+ //\r
+ if (gOldFormSet != NULL) {\r
+ RemoveEntryList (&gOldFormSet->Link);\r
+ DestroyFormSet (gOldFormSet);\r
+ }\r
+ gOldFormSet = Selection->FormSet;\r
+ InsertTailList (&gBrowserFormSetList, &gOldFormSet->Link);\r
+\r
+ do {\r
//\r
// Initialize Selection->Form\r
//\r
Selection->Form = IdToForm (Selection->FormSet, Selection->FormId);\r
}\r
\r
+ if (Selection->Form == NULL) {\r
+ //\r
+ // No Form to display\r
+ //\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // Check Form is suppressed.\r
+ //\r
+ if (Selection->Form->SuppressExpression != NULL) {\r
+ Status = EvaluateExpression (Selection->FormSet, Selection->Form, Selection->Form->SuppressExpression);\r
+ if (EFI_ERROR (Status) || (Selection->Form->SuppressExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN)) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ goto Done;\r
+ }\r
+\r
+ if (Selection->Form->SuppressExpression->Result.Value.b) {\r
+ //\r
+ // Form is suppressed. \r
+ //\r
+ do {\r
+ CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);\r
+ } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+\r
+ Status = EFI_NOT_FOUND;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Reset FormPackage update flag\r
+ //\r
+ mHiiPackageListUpdated = FALSE;\r
+\r
+ //\r
+ // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN\r
+ // for each question with callback flag.\r
+ // New form may be the first form, or the different form after another form close.\r
+ //\r
+ if ((ConfigAccess != NULL) &&\r
+ ((Selection->Handle != mCurrentHiiHandle) ||\r
+ (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
+ (Selection->FormId != mCurrentFormId))) {\r
+\r
+ //\r
+ // Keep current form information\r
+ //\r
+ mCurrentHiiHandle = Selection->Handle;\r
+ CopyGuid (&mCurrentFormSetGuid, &Selection->FormSetGuid);\r
+ mCurrentFormId = Selection->FormId;\r
+\r
+ Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_OPEN, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
+ //\r
+ // EXIT requests to close form.\r
+ //\r
+ if (Selection->Action == UI_ACTION_EXIT) {\r
+ goto Done;\r
+ }\r
+ //\r
+ // IFR is updated during callback of open form, force to reparse the IFR binary\r
+ //\r
+ if (mHiiPackageListUpdated) {\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ mHiiPackageListUpdated = FALSE;\r
+ break;\r
+ }\r
+ }\r
+\r
//\r
// Load Questions' Value for display\r
//\r
- Status = LoadFormConfig (Selection->FormSet, Selection->Form);\r
+ Status = LoadFormSetConfig (Selection, Selection->FormSet);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
+ //\r
+ // EXIT requests to close form.\r
+ //\r
+ if (Selection->Action == UI_ACTION_EXIT) {\r
+ goto Done;\r
+ }\r
+ //\r
+ // IFR is updated during callback of read value, force to reparse the IFR binary\r
+ //\r
+ if (mHiiPackageListUpdated) {\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ mHiiPackageListUpdated = FALSE;\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Displays the Header and Footer borders\r
+ //\r
+ DisplayPageFrame (Selection);\r
+\r
//\r
// Display form\r
//\r
Status = DisplayForm (Selection);\r
if (EFI_ERROR (Status)) {\r
- return Status;\r
+ goto Done;\r
}\r
\r
//\r
//\r
mHiiPackageListUpdated = FALSE;\r
\r
- if (((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
- ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+ if ((ConfigAccess != NULL) && \r
+ ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \r
+ (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
\r
- HiiValue = &Statement->HiiValue;\r
- if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
+ Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE); \r
+ if (Statement->Operand == EFI_IFR_REF_OP && Selection->Action != UI_ACTION_EXIT) {\r
//\r
- // Create String in HII database for Configuration Driver to retrieve\r
+ // Process dynamic update ref opcode.\r
//\r
- HiiValue->Value.string = NewString ((CHAR16 *) Statement->BufferValue, Selection->FormSet->HiiHandle);\r
- }\r
-\r
- ConfigAccess = Selection->FormSet->ConfigAccess;\r
- if (ConfigAccess == NULL) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- Status = ConfigAccess->Callback (\r
- ConfigAccess,\r
- EFI_BROWSER_ACTION_CHANGING,\r
- Statement->QuestionId,\r
- HiiValue->Type,\r
- &HiiValue->Value,\r
- &ActionRequest\r
- );\r
-\r
- if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = ProcessGotoOpCode(Statement, Selection, NULL, NULL);\r
+ }\r
+ \r
//\r
- // Clean the String in HII Database\r
+ // Callback return error status or status return from process goto opcode.\r
//\r
- DeleteString (HiiValue->Value.string, Selection->FormSet->HiiHandle);\r
- }\r
-\r
- if (!EFI_ERROR (Status)) {\r
- switch (ActionRequest) {\r
- case EFI_BROWSER_ACTION_REQUEST_RESET:\r
- gResetRequired = TRUE;\r
- break;\r
-\r
- case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
- SubmitForm (Selection->FormSet, Selection->Form);\r
- break;\r
-\r
- case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
- Selection->Action = UI_ACTION_EXIT;\r
- gNvUpdateRequired = FALSE;\r
- break;\r
-\r
- default:\r
- break;\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Cross reference will not be taken\r
+ //\r
+ Selection->FormId = Selection->Form->FormId;\r
+ Selection->QuestionId = 0;\r
}\r
}\r
}\r
//\r
// Force to reparse IFR binary of target Formset\r
//\r
+ mHiiPackageListUpdated = FALSE;\r
Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
}\r
}\r
+\r
+ //\r
+ // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE\r
+ // for each question with callback flag.\r
+ //\r
+ if ((ConfigAccess != NULL) && \r
+ ((Selection->Action == UI_ACTION_EXIT) || \r
+ (Selection->Handle != mCurrentHiiHandle) ||\r
+ (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
+ (Selection->FormId != mCurrentFormId))) {\r
+\r
+ Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_CLOSE, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ }\r
} while (Selection->Action == UI_ACTION_REFRESH_FORM);\r
\r
+Done:\r
+ //\r
+ // Reset current form information to the initial setting when error happens or form exit.\r
+ //\r
+ if (EFI_ERROR (Status) || Selection->Action == UI_ACTION_EXIT) {\r
+ mCurrentHiiHandle = NULL;\r
+ CopyGuid (&mCurrentFormSetGuid, &gZeroGuid);\r
+ mCurrentFormId = 0;\r
+ }\r
+\r
//\r
// Unregister notify for Form package update\r
//\r
- Status = mHiiDatabase->UnregisterPackageNotify (\r
- mHiiDatabase,\r
- NotifyHandle\r
- );\r
+ mHiiDatabase->UnregisterPackageNotify (\r
+ mHiiDatabase,\r
+ NotifyHandle\r
+ );\r
return Status;\r
}\r