/** @file\r
Utility functions for UI presentation.\r
\r
-Copyright (c) 2004 - 2013, 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
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#include "Setup.h"\r
+\r
+BOOLEAN mHiiPackageListUpdated;\r
+UI_MENU_SELECTION *gCurrentSelection;\r
+EFI_HII_HANDLE mCurrentHiiHandle = NULL;\r
+EFI_GUID mCurrentFormSetGuid = {\r
+ 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }\r
+};\r
+UINT16 mCurrentFormId = 0;\r
+EFI_EVENT mValueChangedEvent = NULL;\r
+LIST_ENTRY mRefreshEventList = INITIALIZE_LIST_HEAD_VARIABLE (mRefreshEventList);\r
+UINT16 mCurFakeQestId;\r
+FORM_DISPLAY_ENGINE_FORM gDisplayFormData;\r
+BOOLEAN mFinishRetrieveCall = FALSE;\r
+BOOLEAN mDynamicFormUpdated = FALSE;\r
+\r
+/**\r
+ Check whether the ConfigAccess protocol is available.\r
+\r
+ @param FormSet FormSet of which the ConfigAcces protocol need to be checked.\r
+\r
+ @retval EFI_SUCCESS The function executed successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+CheckConfigAccess (\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->HandleProtocol (\r
+ FormSet->DriverHandle,\r
+ &gEfiHiiConfigAccessProtocolGuid,\r
+ (VOID **)&FormSet->ConfigAccess\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Configuration Driver don't attach ConfigAccess protocol to its HII package\r
+ // list, then there will be no configuration action required.\r
+ // Or the ConfigAccess protocol has been uninstalled.\r
+ //\r
+ FormSet->ConfigAccess = NULL;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Evaluate all expressions in a Form.\r
+\r
+ @param FormSet FormSet this Form belongs to.\r
+ @param Form The Form.\r
+\r
+ @retval EFI_SUCCESS The expression evaluated successfuly\r
+\r
+**/\r
+EFI_STATUS\r
+EvaluateFormExpressions (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ FORM_EXPRESSION *Expression;\r
+\r
+ Link = GetFirstNode (&Form->ExpressionListHead);\r
+ while (!IsNull (&Form->ExpressionListHead, Link)) {\r
+ Expression = FORM_EXPRESSION_FROM_LINK (Link);\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_WARNING_IF) ||\r
+ (Expression->Type == EFI_HII_EXPRESSION_WRITE) ||\r
+ ((Expression->Type == EFI_HII_EXPRESSION_READ) && (Form->FormType != STANDARD_MAP_FORM_TYPE)))\r
+ {\r
+ //\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
+ Status = EvaluateExpression (FormSet, Form, Expression);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Base on the opcode buffer info to get the display statement.\r
+\r
+ @param OpCode The input opcode buffer for this statement.\r
+\r
+ @retval Statement The statement use this opcode buffer.\r
+\r
+**/\r
+FORM_DISPLAY_ENGINE_STATEMENT *\r
+GetDisplayStatement (\r
+ IN EFI_IFR_OP_HEADER *OpCode\r
+ )\r
+{\r
+ FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement;\r
+ LIST_ENTRY *Link;\r
+\r
+ Link = GetFirstNode (&gDisplayFormData.StatementListHead);\r
+ while (!IsNull (&gDisplayFormData.StatementListHead, Link)) {\r
+ DisplayStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
+\r
+ if (DisplayStatement->OpCode == OpCode) {\r
+ return DisplayStatement;\r
+ }\r
+\r
+ Link = GetNextNode (&gDisplayFormData.StatementListHead, Link);\r
+ }\r
+\r
+ return NULL;\r
+}\r
\r
+/**\r
+ Free the refresh event list.\r
+\r
+**/\r
+VOID\r
+FreeRefreshEvent (\r
+ VOID\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
+\r
+ while (!IsListEmpty (&mRefreshEventList)) {\r
+ Link = GetFirstNode (&mRefreshEventList);\r
+ EventNode = FORM_BROWSER_REFRESH_EVENT_FROM_LINK (Link);\r
+ RemoveEntryList (&EventNode->Link);\r
+\r
+ gBS->CloseEvent (EventNode->RefreshEvent);\r
+\r
+ FreePool (EventNode);\r
+ }\r
+}\r
+\r
+/**\r
+ Check whether this statement value is changed. If yes, update the statement value and return TRUE;\r
+ else return FALSE.\r
+\r
+ @param Statement The statement need to check.\r
+\r
+**/\r
+VOID\r
+UpdateStatement (\r
+ IN OUT FORM_BROWSER_STATEMENT *Statement\r
+ )\r
+{\r
+ GetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);\r
+\r
+ //\r
+ // Reset FormPackage update flag\r
+ //\r
+ mHiiPackageListUpdated = FALSE;\r
+\r
+ //\r
+ // Question value may be changed, need invoke its Callback()\r
+ //\r
+ ProcessCallBackFunction (gCurrentSelection, gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, EFI_BROWSER_ACTION_RETRIEVE, FALSE);\r
+\r
+ if (mHiiPackageListUpdated) {\r
+ //\r
+ // Package list is updated, force to reparse IFR binary of target Formset\r
+ //\r
+ mHiiPackageListUpdated = FALSE;\r
+ gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ }\r
+}\r
+\r
+/**\r
+ Refresh the question which has refresh guid event attribute.\r
+\r
+ @param Event The event which has this function related.\r
+ @param Context The input context info related to this event or the status code return to the caller.\r
+**/\r
+VOID\r
+EFIAPI\r
+RefreshEventNotifyForStatement (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ FORM_BROWSER_STATEMENT *Statement;\r
+\r
+ Statement = (FORM_BROWSER_STATEMENT *)Context;\r
+ UpdateStatement (Statement);\r
+ gBS->SignalEvent (mValueChangedEvent);\r
+}\r
+\r
+/**\r
+ Refresh the questions within this form.\r
+\r
+ @param Event The event which has this function related.\r
+ @param Context The input context info related to this event or the status code return to the caller.\r
**/\r
+VOID\r
+EFIAPI\r
+RefreshEventNotifyForForm (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;\r
+\r
+ gBS->SignalEvent (mValueChangedEvent);\r
+}\r
+\r
+/**\r
+ Create refresh hook event for statement which has refresh event or interval.\r
+\r
+ @param Statement The statement need to check.\r
+\r
+**/\r
+VOID\r
+CreateRefreshEventForStatement (\r
+ IN FORM_BROWSER_STATEMENT *Statement\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_EVENT RefreshEvent;\r
+ FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
+\r
+ //\r
+ // If question has refresh guid, create the notify function.\r
+ //\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ RefreshEventNotifyForStatement,\r
+ Statement,\r
+ &Statement->RefreshGuid,\r
+ &RefreshEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));\r
+ ASSERT (EventNode != NULL);\r
+ EventNode->RefreshEvent = RefreshEvent;\r
+ InsertTailList (&mRefreshEventList, &EventNode->Link);\r
+}\r
+\r
+/**\r
+ Create refresh hook event for form which has refresh event or interval.\r
+\r
+ @param Form The form need to check.\r
+\r
+**/\r
+VOID\r
+CreateRefreshEventForForm (\r
+ IN FORM_BROWSER_FORM *Form\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_EVENT RefreshEvent;\r
+ FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
+\r
+ //\r
+ // If question has refresh guid, create the notify function.\r
+ //\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ RefreshEventNotifyForForm,\r
+ Form,\r
+ &Form->RefreshGuid,\r
+ &RefreshEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));\r
+ ASSERT (EventNode != NULL);\r
+ EventNode->RefreshEvent = RefreshEvent;\r
+ InsertTailList (&mRefreshEventList, &EventNode->Link);\r
+}\r
+\r
+/**\r
+\r
+ Initialize the Display statement structure data.\r
+\r
+ @param DisplayStatement Pointer to the display Statement data strucure.\r
+ @param Statement The statement need to check.\r
+**/\r
+VOID\r
+InitializeDisplayStatement (\r
+ IN OUT FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement,\r
+ IN FORM_BROWSER_STATEMENT *Statement\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ QUESTION_OPTION *Option;\r
+ DISPLAY_QUESTION_OPTION *DisplayOption;\r
+ FORM_DISPLAY_ENGINE_STATEMENT *ParentStatement;\r
+\r
+ DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;\r
+ DisplayStatement->Version = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;\r
+ DisplayStatement->OpCode = Statement->OpCode;\r
+ InitializeListHead (&DisplayStatement->NestStatementList);\r
+ InitializeListHead (&DisplayStatement->OptionListHead);\r
+\r
+ if ((EvaluateExpressionList (Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut) || Statement->Locked) {\r
+ DisplayStatement->Attribute |= HII_DISPLAY_GRAYOUT;\r
+ }\r
+\r
+ if ((Statement->ValueExpression != NULL) || ((Statement->QuestionFlags & EFI_IFR_FLAG_READ_ONLY) != 0)) {\r
+ DisplayStatement->Attribute |= HII_DISPLAY_READONLY;\r
+ }\r
+\r
+ //\r
+ // Initilize the option list in statement.\r
+ //\r
+ Link = GetFirstNode (&Statement->OptionListHead);\r
+ while (!IsNull (&Statement->OptionListHead, Link)) {\r
+ Option = QUESTION_OPTION_FROM_LINK (Link);\r
+ Link = GetNextNode (&Statement->OptionListHead, Link);\r
+ if ((Option->SuppressExpression != NULL) &&\r
+ ((EvaluateExpressionList (Option->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress)))\r
+ {\r
+ continue;\r
+ }\r
+\r
+ DisplayOption = AllocateZeroPool (sizeof (DISPLAY_QUESTION_OPTION));\r
+ ASSERT (DisplayOption != NULL);\r
+\r
+ DisplayOption->ImageId = Option->ImageId;\r
+ DisplayOption->Signature = DISPLAY_QUESTION_OPTION_SIGNATURE;\r
+ DisplayOption->OptionOpCode = Option->OpCode;\r
+ InsertTailList (&DisplayStatement->OptionListHead, &DisplayOption->Link);\r
+ }\r
+\r
+ CopyMem (&DisplayStatement->CurrentValue, &Statement->HiiValue, sizeof (EFI_HII_VALUE));\r
+\r
+ //\r
+ // Some special op code need an extra buffer to save the data.\r
+ // Such as string, password, orderedlist...\r
+ //\r
+ if (Statement->BufferValue != NULL) {\r
+ //\r
+ // Ordered list opcode may not initilized, get default value here.\r
+ //\r
+ if ((Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) && (GetArrayData (Statement->BufferValue, Statement->ValueType, 0) == 0)) {\r
+ GetQuestionDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, 0);\r
+ }\r
+\r
+ DisplayStatement->CurrentValue.Buffer = AllocateCopyPool (Statement->StorageWidth, Statement->BufferValue);\r
+ DisplayStatement->CurrentValue.BufferLen = Statement->StorageWidth;\r
+ }\r
+\r
+ DisplayStatement->SettingChangedFlag = Statement->ValueChanged;\r
+\r
+ //\r
+ // Get the highlight statement for current form.\r
+ //\r
+ if (((gCurrentSelection->QuestionId != 0) && (Statement->QuestionId == gCurrentSelection->QuestionId)) ||\r
+ ((mCurFakeQestId != 0) && (Statement->FakeQuestionId == mCurFakeQestId)))\r
+ {\r
+ gDisplayFormData.HighLightedStatement = DisplayStatement;\r
+ }\r
+\r
+ //\r
+ // Create the refresh event process function.\r
+ //\r
+ if (!IsZeroGuid (&Statement->RefreshGuid)) {\r
+ CreateRefreshEventForStatement (Statement);\r
+ }\r
+\r
+ //\r
+ // For RTC type of date/time, set default refresh interval to be 1 second.\r
+ //\r
+ if (((Statement->Operand == EFI_IFR_DATE_OP) || (Statement->Operand == EFI_IFR_TIME_OP)) && (Statement->Storage == NULL)) {\r
+ Statement->RefreshInterval = 1;\r
+ }\r
+\r
+ //\r
+ // Create the refresh guid hook event.\r
+ // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.\r
+ //\r
+ if ((!IsZeroGuid (&Statement->RefreshGuid)) || (Statement->RefreshInterval != 0)) {\r
+ gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
+ }\r
+\r
+ //\r
+ // Save the password check function for later use.\r
+ //\r
+ if (Statement->Operand == EFI_IFR_PASSWORD_OP) {\r
+ DisplayStatement->PasswordCheck = PasswordCheck;\r
+ }\r
+\r
+ //\r
+ // If this statement is nest in the subtitle, insert to the host statement.\r
+ // else insert to the form it belongs to.\r
+ //\r
+ if (Statement->ParentStatement != NULL) {\r
+ ParentStatement = GetDisplayStatement (Statement->ParentStatement->OpCode);\r
+ ASSERT (ParentStatement != NULL);\r
+ InsertTailList (&ParentStatement->NestStatementList, &DisplayStatement->DisplayLink);\r
+ } else {\r
+ InsertTailList (&gDisplayFormData.StatementListHead, &DisplayStatement->DisplayLink);\r
+ }\r
+}\r
+\r
+/**\r
+ Process for the refresh interval statement.\r
+\r
+ @param Event The Event need to be process\r
+ @param Context The context of the event.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+RefreshIntervalProcess (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ FORM_BROWSER_STATEMENT *Statement;\r
+ LIST_ENTRY *Link;\r
+\r
+ Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);\r
+ while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);\r
+\r
+ if (Statement->RefreshInterval == 0) {\r
+ continue;\r
+ }\r
+\r
+ UpdateStatement (Statement);\r
+ }\r
+\r
+ gBS->SignalEvent (mValueChangedEvent);\r
+}\r
+\r
+/**\r
+\r
+ Make a copy of the global hotkey info.\r
+\r
+**/\r
+VOID\r
+UpdateHotkeyList (\r
+ VOID\r
+ )\r
+{\r
+ BROWSER_HOT_KEY *HotKey;\r
+ BROWSER_HOT_KEY *CopyKey;\r
+ LIST_ENTRY *Link;\r
+\r
+ Link = GetFirstNode (&gBrowserHotKeyList);\r
+ while (!IsNull (&gBrowserHotKeyList, Link)) {\r
+ HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
+\r
+ CopyKey = AllocateCopyPool (sizeof (BROWSER_HOT_KEY), HotKey);\r
+ ASSERT (CopyKey != NULL);\r
+ CopyKey->KeyData = AllocateCopyPool (sizeof (EFI_INPUT_KEY), HotKey->KeyData);\r
+ ASSERT (CopyKey->KeyData != NULL);\r
+ CopyKey->HelpString = AllocateCopyPool (StrSize (HotKey->HelpString), HotKey->HelpString);\r
+ ASSERT (CopyKey->HelpString != NULL);\r
+\r
+ InsertTailList (&gDisplayFormData.HotKeyListHead, &CopyKey->Link);\r
+\r
+ Link = GetNextNode (&gBrowserHotKeyList, Link);\r
+ }\r
+}\r
+\r
+/**\r
+\r
+ Get the extra question attribute from override question list.\r
+\r
+ @param QuestionId The question id for this request question.\r
+\r
+ @retval The attribute for this question or NULL if not found this\r
+ question in the list.\r
+\r
+**/\r
+UINT32\r
+ProcessQuestionExtraAttr (\r
+ IN EFI_QUESTION_ID QuestionId\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ QUESTION_ATTRIBUTE_OVERRIDE *QuestionDesc;\r
+\r
+ //\r
+ // Return HII_DISPLAY_NONE if input a invalid question id.\r
+ //\r
+ if (QuestionId == 0) {\r
+ return HII_DISPLAY_NONE;\r
+ }\r
+\r
+ Link = GetFirstNode (&mPrivateData.FormBrowserEx2.OverrideQestListHead);\r
+ while (!IsNull (&mPrivateData.FormBrowserEx2.OverrideQestListHead, Link)) {\r
+ QuestionDesc = FORM_QUESTION_ATTRIBUTE_OVERRIDE_FROM_LINK (Link);\r
+ Link = GetNextNode (&mPrivateData.FormBrowserEx2.OverrideQestListHead, Link);\r
+\r
+ if ((QuestionDesc->QuestionId == QuestionId) &&\r
+ (QuestionDesc->FormId == gCurrentSelection->FormId) &&\r
+ (QuestionDesc->HiiHandle == gCurrentSelection->Handle) &&\r
+ CompareGuid (&QuestionDesc->FormSetGuid, &gCurrentSelection->FormSetGuid))\r
+ {\r
+ return QuestionDesc->Attribute;\r
+ }\r
+ }\r
+\r
+ return HII_DISPLAY_NONE;\r
+}\r
+\r
+/**\r
+\r
+ Enum all statement in current form, find all the statement can be display and\r
+ add to the display form.\r
+\r
+**/\r
+VOID\r
+AddStatementToDisplayForm (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_STATEMENT *Statement;\r
+ FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement;\r
+ UINT8 MinRefreshInterval;\r
+ EFI_EVENT RefreshIntervalEvent;\r
+ FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
+ BOOLEAN FormEditable;\r
+ UINT32 ExtraAttribute;\r
+\r
+ MinRefreshInterval = 0;\r
+ FormEditable = FALSE;\r
+\r
+ //\r
+ // Process the statement outside the form, these statements are not recognized\r
+ // by browser core.\r
+ //\r
+ Link = GetFirstNode (&gCurrentSelection->FormSet->StatementListOSF);\r
+ while (!IsNull (&gCurrentSelection->FormSet->StatementListOSF, Link)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ Link = GetNextNode (&gCurrentSelection->FormSet->StatementListOSF, Link);\r
+\r
+ DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
+ ASSERT (DisplayStatement != NULL);\r
+ DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;\r
+ DisplayStatement->Version = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;\r
+ DisplayStatement->OpCode = Statement->OpCode;\r
+\r
+ InitializeListHead (&DisplayStatement->NestStatementList);\r
+ InitializeListHead (&DisplayStatement->OptionListHead);\r
+\r
+ InsertTailList (&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);\r
+ }\r
+\r
+ //\r
+ // treat formset as statement outside the form,get its opcode.\r
+ //\r
+ DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
+ ASSERT (DisplayStatement != NULL);\r
+\r
+ DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;\r
+ DisplayStatement->Version = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;\r
+ DisplayStatement->OpCode = gCurrentSelection->FormSet->OpCode;\r
+\r
+ InitializeListHead (&DisplayStatement->NestStatementList);\r
+ InitializeListHead (&DisplayStatement->OptionListHead);\r
+\r
+ InsertTailList (&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);\r
+\r
+ //\r
+ // Process the statement in this form.\r
+ //\r
+ Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);\r
+ while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);\r
+\r
+ //\r
+ // This statement can't be show, skip it.\r
+ //\r
+ if (EvaluateExpressionList (Statement->Expression, FALSE, NULL, NULL) > ExpressGrayOut) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check the extra attribute.\r
+ //\r
+ ExtraAttribute = ProcessQuestionExtraAttr (Statement->QuestionId);\r
+ if ((ExtraAttribute & HII_DISPLAY_SUPPRESS) != 0) {\r
+ continue;\r
+ }\r
\r
-#include "Setup.h"\r
+ DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));\r
+ ASSERT (DisplayStatement != NULL);\r
\r
-BOOLEAN mHiiPackageListUpdated;\r
-UI_MENU_SELECTION *gCurrentSelection;\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
+ // Initialize this statement and add it to the display form.\r
+ //\r
+ InitializeDisplayStatement (DisplayStatement, Statement);\r
\r
-/**\r
- Clear retangle with specified text attribute.\r
+ //\r
+ // Set the extra attribute.\r
+ //\r
+ DisplayStatement->Attribute |= ExtraAttribute;\r
\r
- @param LeftColumn Left column of retangle.\r
- @param RightColumn Right column of retangle.\r
- @param TopRow Start row of retangle.\r
- @param BottomRow End row of retangle.\r
- @param TextAttribute The character foreground and background.\r
+ if (Statement->Storage != NULL) {\r
+ FormEditable = TRUE;\r
+ }\r
\r
-**/\r
-VOID\r
-ClearLines (\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
- UINTN Row;\r
+ //\r
+ // Get the minimal refresh interval value for later use.\r
+ //\r
+ if ((Statement->RefreshInterval != 0) &&\r
+ ((MinRefreshInterval == 0) || (Statement->RefreshInterval < MinRefreshInterval)))\r
+ {\r
+ MinRefreshInterval = Statement->RefreshInterval;\r
+ }\r
+ }\r
\r
//\r
- // For now, allocate an arbitrarily long buffer\r
+ // Create the periodic timer for refresh interval statement.\r
//\r
- Buffer = AllocateZeroPool (0x10000);\r
- ASSERT (Buffer != NULL);\r
+ if (MinRefreshInterval != 0) {\r
+ Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshIntervalProcess, NULL, &RefreshIntervalEvent);\r
+ ASSERT_EFI_ERROR (Status);\r
+ Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, MinRefreshInterval * ONE_SECOND);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));\r
+ ASSERT (EventNode != NULL);\r
+ EventNode->RefreshEvent = RefreshIntervalEvent;\r
+ InsertTailList (&mRefreshEventList, &EventNode->Link);\r
+ }\r
\r
//\r
- // Set foreground and background as defined\r
+ // Create the refresh event process function for Form.\r
//\r
- gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);\r
+ if (!IsZeroGuid (&gCurrentSelection->Form->RefreshGuid)) {\r
+ CreateRefreshEventForForm (gCurrentSelection->Form);\r
+ if (gDisplayFormData.FormRefreshEvent == NULL) {\r
+ gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
+ }\r
+ }\r
\r
//\r
- // Much faster to buffer the long string instead of print it a character at a time\r
+ // Update hotkey list field.\r
//\r
- SetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');\r
+ if ((gBrowserSettingScope == SystemLevel) || FormEditable) {\r
+ UpdateHotkeyList ();\r
+ }\r
+}\r
+\r
+/**\r
+\r
+ Initialize the SettingChangedFlag variable in the display form.\r
+\r
+**/\r
+VOID\r
+UpdateDataChangedFlag (\r
+ VOID\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_FORMSET *LocalFormSet;\r
+\r
+ gDisplayFormData.SettingChangedFlag = FALSE;\r
+\r
+ if (IsNvUpdateRequiredForForm (gCurrentSelection->Form)) {\r
+ gDisplayFormData.SettingChangedFlag = TRUE;\r
+ return;\r
+ }\r
\r
//\r
- // Clear the desired area with the appropriate foreground/background\r
+ // Base on the system level to check whether need to show the NV flag.\r
//\r
- for (Row = TopRow; Row <= BottomRow; Row++) {\r
- PrintStringAt (LeftColumn, Row, Buffer);\r
+ switch (gBrowserSettingScope) {\r
+ case SystemLevel:\r
+ //\r
+ // Check the maintain list to see whether there is any change.\r
+ //\r
+ Link = GetFirstNode (&gBrowserFormSetList);\r
+ while (!IsNull (&gBrowserFormSetList, Link)) {\r
+ LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
+ if (IsNvUpdateRequiredForFormSet (LocalFormSet)) {\r
+ gDisplayFormData.SettingChangedFlag = TRUE;\r
+ return;\r
+ }\r
+\r
+ Link = GetNextNode (&gBrowserFormSetList, Link);\r
+ }\r
+\r
+ break;\r
+\r
+ case FormSetLevel:\r
+ if (IsNvUpdateRequiredForFormSet (gCurrentSelection->FormSet)) {\r
+ gDisplayFormData.SettingChangedFlag = TRUE;\r
+ return;\r
+ }\r
+\r
+ break;\r
+\r
+ default:\r
+ break;\r
}\r
+}\r
+\r
+/**\r
\r
- gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);\r
+ Initialize the Display form structure data.\r
\r
- FreePool (Buffer);\r
- return ;\r
+**/\r
+VOID\r
+InitializeDisplayFormData (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ gDisplayFormData.Signature = FORM_DISPLAY_ENGINE_FORM_SIGNATURE;\r
+ gDisplayFormData.Version = FORM_DISPLAY_ENGINE_VERSION_1;\r
+ gDisplayFormData.ImageId = 0;\r
+ gDisplayFormData.AnimationId = 0;\r
+\r
+ InitializeListHead (&gDisplayFormData.StatementListHead);\r
+ InitializeListHead (&gDisplayFormData.StatementListOSF);\r
+ InitializeListHead (&gDisplayFormData.HotKeyListHead);\r
+\r
+ Status = gBS->CreateEvent (\r
+ EVT_NOTIFY_WAIT,\r
+ TPL_CALLBACK,\r
+ EfiEventEmptyFunction,\r
+ NULL,\r
+ &mValueChangedEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
}\r
\r
/**\r
- Concatenate a narrow string to another string.\r
\r
- @param Destination The destination string.\r
- @param Source The source string. The string to be concatenated.\r
- to the end of Destination.\r
+ Free the kotkey info saved in form data.\r
\r
**/\r
VOID\r
-NewStrCat (\r
- IN OUT CHAR16 *Destination,\r
- IN CHAR16 *Source\r
+FreeHotkeyList (\r
+ VOID\r
)\r
{\r
- UINTN Length;\r
+ BROWSER_HOT_KEY *HotKey;\r
+ LIST_ENTRY *Link;\r
\r
- for (Length = 0; Destination[Length] != 0; Length++)\r
- ;\r
+ while (!IsListEmpty (&gDisplayFormData.HotKeyListHead)) {\r
+ Link = GetFirstNode (&gDisplayFormData.HotKeyListHead);\r
+ HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
\r
- //\r
- // We now have the length of the original string\r
- // We can safely assume for now that we are concatenating a narrow value to this string.\r
- // For instance, the string is "XYZ" and cat'ing ">"\r
- // If this assumption changes, we need to make this routine a bit more complex\r
- //\r
- Destination[Length] = NARROW_CHAR;\r
- Length++;\r
+ RemoveEntryList (&HotKey->Link);\r
\r
- StrCpy (Destination + Length, Source);\r
+ FreePool (HotKey->KeyData);\r
+ FreePool (HotKey->HelpString);\r
+ FreePool (HotKey);\r
+ }\r
}\r
\r
/**\r
- Count the storage space of a Unicode string.\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
- hit, then 2 Unicode character will consume an output storage\r
- space with size of CHAR16 till a NARROW_CHAR is hit.\r
+ Update the Display form structure data.\r
+\r
+**/\r
+VOID\r
+UpdateDisplayFormData (\r
+ VOID\r
+ )\r
+{\r
+ gDisplayFormData.FormTitle = gCurrentSelection->Form->FormTitle;\r
+ gDisplayFormData.FormId = gCurrentSelection->FormId;\r
+ gDisplayFormData.HiiHandle = gCurrentSelection->Handle;\r
+ CopyGuid (&gDisplayFormData.FormSetGuid, &gCurrentSelection->FormSetGuid);\r
+\r
+ gDisplayFormData.Attribute = 0;\r
+ gDisplayFormData.Attribute |= gCurrentSelection->Form->ModalForm ? HII_DISPLAY_MODAL : 0;\r
+ gDisplayFormData.Attribute |= gCurrentSelection->Form->Locked ? HII_DISPLAY_LOCK : 0;\r
+\r
+ gDisplayFormData.FormRefreshEvent = NULL;\r
+ gDisplayFormData.HighLightedStatement = NULL;\r
\r
- If String is NULL, then ASSERT ().\r
+ UpdateDataChangedFlag ();\r
+\r
+ AddStatementToDisplayForm ();\r
+}\r
+\r
+/**\r
\r
- @param String The input string to be counted.\r
+ Free the Display Statement structure data.\r
\r
- @return Storage space for the input string.\r
+ @param StatementList Point to the statement list which need to be free.\r
\r
**/\r
-UINTN\r
-GetStringWidth (\r
- IN CHAR16 *String\r
+VOID\r
+FreeStatementData (\r
+ LIST_ENTRY *StatementList\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
+ LIST_ENTRY *Link;\r
+ LIST_ENTRY *OptionLink;\r
+ FORM_DISPLAY_ENGINE_STATEMENT *Statement;\r
+ DISPLAY_QUESTION_OPTION *Option;\r
\r
- Index = 0;\r
- Count = 0;\r
- IncrementValue = 1;\r
+ //\r
+ // Free Statements/Questions\r
+ //\r
+ while (!IsListEmpty (StatementList)) {\r
+ Link = GetFirstNode (StatementList);\r
+ Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);\r
\r
- do {\r
//\r
- // Advance to the null-terminator or to the first width directive\r
+ // Free Options List\r
//\r
- for (;\r
- (String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);\r
- Index++, Count = Count + IncrementValue\r
- )\r
- ;\r
+ while (!IsListEmpty (&Statement->OptionListHead)) {\r
+ OptionLink = GetFirstNode (&Statement->OptionListHead);\r
+ Option = DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink);\r
+ RemoveEntryList (&Option->Link);\r
+ FreePool (Option);\r
+ }\r
\r
//\r
- // We hit the null-terminator, we now have a count\r
+ // Free nest statement List\r
//\r
- if (String[Index] == 0) {\r
- break;\r
+ if (!IsListEmpty (&Statement->NestStatementList)) {\r
+ FreeStatementData (&Statement->NestStatementList);\r
+ }\r
+\r
+ RemoveEntryList (&Statement->DisplayLink);\r
+ FreePool (Statement);\r
+ }\r
+}\r
+\r
+/**\r
+\r
+ Free the Display form structure data.\r
+\r
+**/\r
+VOID\r
+FreeDisplayFormData (\r
+ VOID\r
+ )\r
+{\r
+ FreeStatementData (&gDisplayFormData.StatementListHead);\r
+ FreeStatementData (&gDisplayFormData.StatementListOSF);\r
+\r
+ FreeRefreshEvent ();\r
+\r
+ FreeHotkeyList ();\r
+}\r
+\r
+/**\r
+\r
+ Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.\r
+\r
+ @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.\r
+\r
+ @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.\r
+\r
+**/\r
+FORM_BROWSER_STATEMENT *\r
+GetBrowserStatement (\r
+ IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement\r
+ )\r
+{\r
+ FORM_BROWSER_STATEMENT *Statement;\r
+ LIST_ENTRY *Link;\r
+\r
+ Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);\r
+ while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+\r
+ if (Statement->OpCode == DisplayStatement->OpCode) {\r
+ return Statement;\r
}\r
+\r
+ Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Update the ValueChanged status for questions in this form.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Form Form data structure.\r
+\r
+**/\r
+VOID\r
+UpdateStatementStatusForForm (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_STATEMENT *Question;\r
+\r
+ Link = GetFirstNode (&Form->StatementListHead);\r
+ while (!IsNull (&Form->StatementListHead, Link)) {\r
+ Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
+\r
//\r
- // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed\r
- // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)\r
+ // For password opcode, not set the the value changed flag.\r
//\r
- if (String[Index] == NARROW_CHAR) {\r
- //\r
- // Skip to the next character\r
- //\r
- Index++;\r
- IncrementValue = 1;\r
- } else {\r
- //\r
- // Skip to the next character\r
- //\r
- Index++;\r
- IncrementValue = 2;\r
+ if (Question->Operand == EFI_IFR_PASSWORD_OP) {\r
+ continue;\r
}\r
- } while (String[Index] != 0);\r
\r
- //\r
- // Increment by one to include the null-terminator in the size\r
- //\r
- Count++;\r
+ IsQuestionValueChanged (FormSet, Form, Question, GetSetValueWithBuffer);\r
+ }\r
+}\r
+\r
+/**\r
+ Update the ValueChanged status for questions in this formset.\r
+\r
+ @param FormSet FormSet data structure.\r
+\r
+**/\r
+VOID\r
+UpdateStatementStatusForFormSet (\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
+ Link = GetNextNode (&FormSet->FormListHead, Link);\r
\r
- return Count * sizeof (CHAR16);\r
+ UpdateStatementStatusForForm (FormSet, Form);\r
+ }\r
}\r
\r
/**\r
- This function displays the page frame.\r
+ Update the ValueChanged status for questions.\r
+\r
+ @param FormSet FormSet data structure.\r
+ @param Form Form data structure.\r
+ @param SettingScope Setting Scope for Default action.\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
- IN UI_MENU_SELECTION *Selection\r
+UpdateStatementStatus (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN BROWSER_SETTING_SCOPE SettingScope\r
)\r
{\r
- UINTN Index;\r
- UINT8 Line;\r
- UINT8 Alignment;\r
- CHAR16 Character;\r
- CHAR16 *Buffer;\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
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_FORMSET *LocalFormSet;\r
+\r
+ switch (SettingScope) {\r
+ case SystemLevel:\r
+ Link = GetFirstNode (&gBrowserFormSetList);\r
+ while (!IsNull (&gBrowserFormSetList, Link)) {\r
+ LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);\r
+ Link = GetNextNode (&gBrowserFormSetList, Link);\r
+ if (!ValidateFormSet (LocalFormSet)) {\r
+ continue;\r
+ }\r
+\r
+ UpdateStatementStatusForFormSet (LocalFormSet);\r
+ }\r
+\r
+ break;\r
+\r
+ case FormSetLevel:\r
+ UpdateStatementStatusForFormSet (FormSet);\r
+ break;\r
+\r
+ case FormLevel:\r
+ UpdateStatementStatusForForm (FormSet, Form);\r
+ break;\r
+\r
+ default:\r
+ break;\r
}\r
+}\r
+\r
+/**\r
+\r
+ Process the action request in user input.\r
\r
- CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+ @param Action The user input action request info.\r
+ @param DefaultId The user input default Id info.\r
+\r
+ @retval EFI_SUCESSS This function always return successfully for now.\r
+\r
+**/\r
+EFI_STATUS\r
+ProcessAction (\r
+ IN UINT32 Action,\r
+ IN UINT16 DefaultId\r
+ )\r
+{\r
+ //\r
+ // This is caused by use press ESC, and it should not combine with other action type.\r
+ //\r
+ if ((Action & BROWSER_ACTION_FORM_EXIT) == BROWSER_ACTION_FORM_EXIT) {\r
+ FindNextMenu (gCurrentSelection, FormLevel);\r
+ return EFI_SUCCESS;\r
+ }\r
\r
//\r
- // For now, allocate an arbitrarily long buffer\r
+ // Below is normal hotkey trigged action, these action maybe combine with each other.\r
//\r
- Buffer = AllocateZeroPool (0x10000);\r
- ASSERT (Buffer != NULL);\r
+ if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {\r
+ DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
+ }\r
\r
- Character = BOXDRAW_HORIZONTAL;\r
+ if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
+ ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE, FALSE);\r
+ UpdateStatementStatus (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
+ }\r
\r
- for (Index = 0; Index + 2 < (LocalScreen.RightColumn - LocalScreen.LeftColumn); Index++) {\r
- Buffer[Index] = Character;\r
+ if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {\r
+ SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
}\r
\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
- ClearLines (\r
- LocalScreen.LeftColumn,\r
- LocalScreen.RightColumn,\r
- LocalScreen.TopRow,\r
- FRONT_PAGE_HEADER_HEIGHT - 1 + LocalScreen.TopRow,\r
- BANNER_TEXT | BANNER_BACKGROUND\r
- );\r
+ if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {\r
+ gResetRequiredFormLevel = TRUE;\r
+ gResetRequiredSystemLevel = TRUE;\r
+ }\r
+\r
+ if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {\r
//\r
- // for (Line = 0; Line < BANNER_HEIGHT; Line++) {\r
+ // Form Exit without saving, Similar to ESC Key.\r
+ // FormSet Exit without saving, Exit SendForm.\r
+ // System Exit without saving, CallExitHandler and Exit SendForm.\r
//\r
- for (Line = (UINT8) LocalScreen.TopRow; Line < BANNER_HEIGHT + (UINT8) LocalScreen.TopRow; Line++) {\r
- //\r
- // for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {\r
- //\r
- for (Alignment = (UINT8) LocalScreen.LeftColumn;\r
- Alignment < BANNER_COLUMNS + (UINT8) LocalScreen.LeftColumn;\r
- Alignment++\r
- ) {\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
- gBannerData->Banner[RowIdx][ColumnIdx],\r
- gFrontPageHandle\r
- );\r
- } else {\r
- continue;\r
- }\r
+ DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
+ if ((gBrowserSettingScope == FormLevel) || (gBrowserSettingScope == FormSetLevel)) {\r
+ FindNextMenu (gCurrentSelection, gBrowserSettingScope);\r
+ } else if (gBrowserSettingScope == SystemLevel) {\r
+ if (ExitHandlerFunction != NULL) {\r
+ ExitHandlerFunction ();\r
+ }\r
\r
- switch (Alignment - LocalScreen.LeftColumn) {\r
- case 0:\r
- //\r
- // Handle left column\r
- //\r
- PrintStringAt (LocalScreen.LeftColumn + BANNER_LEFT_COLUMN_INDENT, Line, StrFrontPageBanner);\r
- break;\r
+ gCurrentSelection->Action = UI_ACTION_EXIT;\r
+ }\r
+ }\r
\r
- case 1:\r
- //\r
- // Handle center column\r
- //\r
- PrintStringAt (\r
- LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,\r
- Line,\r
- StrFrontPageBanner\r
- );\r
- break;\r
+ return EFI_SUCCESS;\r
+}\r
\r
- case 2:\r
- //\r
- // Handle right column\r
- //\r
- PrintStringAt (\r
- LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,\r
- Line,\r
- StrFrontPageBanner\r
- );\r
- break;\r
+/**\r
+ Check whether the formset guid is in this Hii package list.\r
+\r
+ @param HiiHandle The HiiHandle for this HII package list.\r
+ @param FormSetGuid The formset guid for the request formset.\r
+\r
+ @retval TRUE Find the formset guid.\r
+ @retval FALSE Not found the formset guid.\r
+\r
+**/\r
+BOOLEAN\r
+GetFormsetGuidFromHiiHandle (\r
+ IN EFI_HII_HANDLE HiiHandle,\r
+ IN EFI_GUID *FormSetGuid\r
+ )\r
+{\r
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
+ UINTN BufferSize;\r
+ UINT32 Offset;\r
+ UINT32 Offset2;\r
+ UINT32 PackageListLength;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader;\r
+ UINT8 *Package;\r
+ UINT8 *OpCodeData;\r
+ EFI_STATUS Status;\r
+ BOOLEAN FindGuid;\r
+\r
+ BufferSize = 0;\r
+ HiiPackageList = NULL;\r
+ FindGuid = FALSE;\r
+\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HiiPackageList = AllocatePool (BufferSize);\r
+ ASSERT (HiiPackageList != NULL);\r
+\r
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
+ }\r
+\r
+ if (EFI_ERROR (Status) || (HiiPackageList == NULL)) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Get Form package from this HII package List\r
+ //\r
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+ Offset2 = 0;\r
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
+\r
+ while (Offset < PackageListLength) {\r
+ Package = ((UINT8 *)HiiPackageList) + Offset;\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+ Offset += PackageHeader.Length;\r
+\r
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {\r
+ //\r
+ // Search FormSet in this Form Package\r
+ //\r
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ while (Offset2 < PackageHeader.Length) {\r
+ OpCodeData = Package + Offset2;\r
+\r
+ if (((EFI_IFR_OP_HEADER *)OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {\r
+ if (CompareGuid (FormSetGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
+ FindGuid = TRUE;\r
+ break;\r
+ }\r
}\r
\r
- FreePool (StrFrontPageBanner);\r
+ Offset2 += ((EFI_IFR_OP_HEADER *)OpCodeData)->Length;\r
}\r
}\r
- }\r
\r
- ClearLines (\r
- LocalScreen.LeftColumn,\r
- LocalScreen.RightColumn,\r
- LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight,\r
- LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,\r
- KEYHELP_TEXT | KEYHELP_BACKGROUND\r
- );\r
-\r
- if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {\r
- ClearLines (\r
- LocalScreen.LeftColumn,\r
- LocalScreen.RightColumn,\r
- LocalScreen.TopRow,\r
- LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1,\r
- TITLE_TEXT | TITLE_BACKGROUND\r
- );\r
- //\r
- // Print Top border line\r
- // +------------------------------------------------------------------------------+\r
- // ? ?\r
- // +------------------------------------------------------------------------------+\r
- //\r
- Character = BOXDRAW_DOWN_RIGHT;\r
-\r
- PrintChar (Character);\r
- PrintString (Buffer);\r
-\r
- Character = BOXDRAW_DOWN_LEFT;\r
- PrintChar (Character);\r
-\r
- Character = BOXDRAW_VERTICAL;\r
- for (Row = LocalScreen.TopRow + 1; Row <= LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {\r
- PrintCharAt (LocalScreen.LeftColumn, Row, Character);\r
- PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);\r
+ if (FindGuid) {\r
+ break;\r
}\r
+ }\r
\r
- Character = BOXDRAW_UP_RIGHT;\r
- PrintCharAt (LocalScreen.LeftColumn, LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);\r
- PrintString (Buffer);\r
+ FreePool (HiiPackageList);\r
\r
- Character = BOXDRAW_UP_LEFT;\r
- PrintChar (Character);\r
+ return FindGuid;\r
+}\r
\r
- if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
- //\r
- // Print Bottom border line\r
- // +------------------------------------------------------------------------------+\r
- // ? ?\r
- // +------------------------------------------------------------------------------+\r
- //\r
- Character = BOXDRAW_DOWN_RIGHT;\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 - gFooterHeight + 1;\r
- Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;\r
- Row++\r
- ) {\r
- PrintCharAt (LocalScreen.LeftColumn, Row, Character);\r
- PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);\r
+/**\r
+ Find HII Handle in the HII database associated with given Device Path.\r
+\r
+ If DevicePath is NULL, then ASSERT.\r
+\r
+ @param DevicePath Device Path associated with the HII package list\r
+ handle.\r
+ @param FormsetGuid The formset guid for this formset.\r
+\r
+ @retval Handle HII package list Handle associated with the Device\r
+ Path.\r
+ @retval NULL Hii Package list handle is not found.\r
+\r
+**/\r
+EFI_HII_HANDLE\r
+DevicePathToHiiHandle (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN EFI_GUID *FormsetGuid\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
+ UINTN Index;\r
+ EFI_HANDLE Handle;\r
+ EFI_HANDLE DriverHandle;\r
+ EFI_HII_HANDLE *HiiHandles;\r
+ EFI_HII_HANDLE HiiHandle;\r
+\r
+ ASSERT (DevicePath != NULL);\r
+\r
+ TmpDevicePath = DevicePath;\r
+ //\r
+ // Locate Device Path Protocol handle buffer\r
+ //\r
+ Status = gBS->LocateDevicePath (\r
+ &gEfiDevicePathProtocolGuid,\r
+ &TmpDevicePath,\r
+ &DriverHandle\r
+ );\r
+ if (EFI_ERROR (Status) || !IsDevicePathEnd (TmpDevicePath)) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Retrieve all HII Handles from HII database\r
+ //\r
+ HiiHandles = HiiGetHiiHandles (NULL);\r
+ if (HiiHandles == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Search Hii Handle by Driver Handle\r
+ //\r
+ HiiHandle = NULL;\r
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
+ Status = mHiiDatabase->GetPackageListHandle (\r
+ mHiiDatabase,\r
+ HiiHandles[Index],\r
+ &Handle\r
+ );\r
+ if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {\r
+ if (GetFormsetGuidFromHiiHandle (HiiHandles[Index], FormsetGuid)) {\r
+ HiiHandle = HiiHandles[Index];\r
+ break;\r
}\r
\r
- Character = BOXDRAW_UP_RIGHT;\r
- PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character);\r
-\r
- PrintString (Buffer);\r
-\r
- Character = BOXDRAW_UP_LEFT;\r
- PrintChar (Character);\r
+ if (HiiHandle != NULL) {\r
+ break;\r
+ }\r
}\r
}\r
\r
- FreePool (Buffer);\r
-\r
+ FreePool (HiiHandles);\r
+ return HiiHandle;\r
}\r
\r
-\r
/**\r
- Evaluate all expressions in a Form.\r
+ Find HII Handle in the HII database associated with given form set guid.\r
\r
- @param FormSet FormSet this Form belongs to.\r
- @param Form The Form.\r
+ If FormSetGuid is NULL, then ASSERT.\r
\r
- @retval EFI_SUCCESS The expression evaluated successfuly\r
+ @param ComparingGuid FormSet Guid associated with the HII package list\r
+ handle.\r
+\r
+ @retval Handle HII package list Handle associated with the Device\r
+ Path.\r
+ @retval NULL Hii Package list handle is not found.\r
\r
**/\r
-EFI_STATUS\r
-EvaluateFormExpressions (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form\r
+EFI_HII_HANDLE\r
+FormSetGuidToHiiHandle (\r
+ EFI_GUID *ComparingGuid\r
)\r
{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Link;\r
- FORM_EXPRESSION *Expression;\r
+ EFI_HII_HANDLE *HiiHandles;\r
+ EFI_HII_HANDLE HiiHandle;\r
+ UINTN Index;\r
\r
- Link = GetFirstNode (&Form->ExpressionListHead);\r
- while (!IsNull (&Form->ExpressionListHead, Link)) {\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
- Link = GetNextNode (&Form->ExpressionListHead, Link);\r
+ ASSERT (ComparingGuid != NULL);\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_WRITE ||\r
- (Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) {\r
- //\r
- // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.\r
- //\r
- continue;\r
+ HiiHandle = NULL;\r
+ //\r
+ // Get all the Hii handles\r
+ //\r
+ HiiHandles = HiiGetHiiHandles (NULL);\r
+ ASSERT (HiiHandles != NULL);\r
+\r
+ //\r
+ // Search for formset of each class type\r
+ //\r
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
+ if (GetFormsetGuidFromHiiHandle (HiiHandles[Index], ComparingGuid)) {\r
+ HiiHandle = HiiHandles[Index];\r
+ break;\r
}\r
\r
- Status = EvaluateExpression (FormSet, Form, Expression);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if (HiiHandle != NULL) {\r
+ break;\r
}\r
}\r
\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/*\r
-+------------------------------------------------------------------------------+\r
-? Setup Page ?\r
-+------------------------------------------------------------------------------+\r
-\r
+ FreePool (HiiHandles);\r
\r
+ return HiiHandle;\r
+}\r
\r
+/**\r
+ check how to process the changed data in current form or form set.\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
\r
+ @param Scope Data save or discard scope, form or formset.\r
\r
+ @retval TRUE Success process the changed data, will return to the parent form.\r
+ @retval FALSE Reject to process the changed data, will stay at current form.\r
+**/\r
+BOOLEAN\r
+ProcessChangedData (\r
+ IN OUT UI_MENU_SELECTION *Selection,\r
+ IN BROWSER_SETTING_SCOPE Scope\r
+ )\r
+{\r
+ BOOLEAN RetValue;\r
+ EFI_STATUS Status;\r
\r
+ RetValue = TRUE;\r
+ switch (mFormDisplay->ConfirmDataChange ()) {\r
+ case BROWSER_ACTION_DISCARD:\r
+ DiscardForm (Selection->FormSet, Selection->Form, Scope);\r
+ break;\r
\r
+ case BROWSER_ACTION_SUBMIT:\r
+ Status = SubmitForm (Selection->FormSet, Selection->Form, Scope);\r
+ if (EFI_ERROR (Status)) {\r
+ RetValue = FALSE;\r
+ }\r
\r
+ break;\r
\r
+ case BROWSER_ACTION_NONE:\r
+ RetValue = FALSE;\r
+ break;\r
\r
+ default:\r
+ //\r
+ // if Invalid value return, process same as BROWSER_ACTION_NONE.\r
+ //\r
+ RetValue = FALSE;\r
+ break;\r
+ }\r
\r
+ return RetValue;\r
+}\r
\r
+/**\r
+ Find parent formset menu(the first menu which has different formset) for current menu.\r
+ If not find, just return to the first menu.\r
\r
+ @param Selection The selection info.\r
\r
+**/\r
+VOID\r
+FindParentFormSet (\r
+ IN OUT UI_MENU_SELECTION *Selection\r
+ )\r
+{\r
+ FORM_ENTRY_INFO *CurrentMenu;\r
+ FORM_ENTRY_INFO *ParentMenu;\r
\r
+ CurrentMenu = Selection->CurrentMenu;\r
+ ParentMenu = UiFindParentMenu (CurrentMenu, FormSetLevel);\r
+\r
+ if (ParentMenu != NULL) {\r
+ CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));\r
+ Selection->Handle = ParentMenu->HiiHandle;\r
+ Selection->FormId = ParentMenu->FormId;\r
+ Selection->QuestionId = ParentMenu->QuestionId;\r
+ } else {\r
+ Selection->FormId = CurrentMenu->FormId;\r
+ Selection->QuestionId = CurrentMenu->QuestionId;\r
+ }\r
\r
-+------------------------------------------------------------------------------+\r
-?F1=Scroll Help F9=Reset to Defaults F10=Save and Exit ?\r
-| ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Discard Changes |\r
-+------------------------------------------------------------------------------+\r
-*/\r
+ Selection->Statement = NULL;\r
+}\r
\r
/**\r
+ Process the goto op code, update the info in the selection structure.\r
\r
+ @param Statement The statement belong to goto op code.\r
+ @param Selection The selection info.\r
\r
- Display form and wait for user to select one menu option, then return it.\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
- @retval EFI_SUCESSS This function always return successfully for now.\r
-\r
+ @retval EFI_SUCCESS The menu process successfully.\r
+ @return Other value if the process failed.\r
**/\r
EFI_STATUS\r
-DisplayForm (\r
- IN OUT UI_MENU_SELECTION *Selection\r
+ProcessGotoOpCode (\r
+ IN OUT FORM_BROWSER_STATEMENT *Statement,\r
+ IN OUT UI_MENU_SELECTION *Selection\r
)\r
{\r
- CHAR16 *StringPtr;\r
- UINT16 MenuItemCount;\r
- EFI_HII_HANDLE Handle;\r
- EFI_SCREEN_DESCRIPTOR LocalScreen;\r
- UINT16 Width;\r
- UINTN ArrayEntry;\r
- CHAR16 *OutputString;\r
- LIST_ENTRY *Link;\r
- FORM_BROWSER_STATEMENT *Statement;\r
- UINT16 NumberOfLines;\r
- EFI_STATUS Status;\r
- UI_MENU_OPTION *MenuOption;\r
- UINT16 GlyphWidth;\r
-\r
- Handle = Selection->Handle;\r
- MenuItemCount = 0;\r
- ArrayEntry = 0;\r
- OutputString = NULL;\r
-\r
- UiInitMenu ();\r
-\r
- CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
-\r
- StringPtr = GetToken (Selection->Form->FormTitle, Handle);\r
-\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
- StringPtr\r
- );\r
- }\r
+ CHAR16 *StringPtr;\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ FORM_BROWSER_FORM *RefForm;\r
+ EFI_STATUS Status;\r
+ EFI_HII_HANDLE HiiHandle;\r
\r
- //\r
- // Remove Buffer allocated for StringPtr after it has been used.\r
- //\r
- FreePool (StringPtr);\r
+ Status = EFI_SUCCESS;\r
+ StringPtr = NULL;\r
+ HiiHandle = NULL;\r
\r
//\r
- // Evaluate all the Expressions in this Form\r
+ // Prepare the device path check, get the device path info first.\r
//\r
- Status = EvaluateFormExpressions (Selection->FormSet, Selection->Form);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ if (Statement->HiiValue.Value.ref.DevicePath != 0) {\r
+ StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);\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
+ //\r
+ // Check whether the device path string is a valid string.\r
+ //\r
+ if ((Statement->HiiValue.Value.ref.DevicePath != 0) && (StringPtr != NULL) && (StringPtr[0] != L'\0')) {\r
+ if (Selection->Form->ModalForm) {\r
+ return Status;\r
+ }\r
\r
- if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) <= ExpressGrayOut) {\r
- StringPtr = GetToken (Statement->Prompt, Handle);\r
- ASSERT (StringPtr != NULL);\r
+ //\r
+ // Goto another Hii Package list\r
+ //\r
+ if (mPathFromText != NULL) {\r
+ DevicePath = mPathFromText->ConvertTextToDevicePath (StringPtr);\r
+ if (DevicePath != NULL) {\r
+ HiiHandle = DevicePathToHiiHandle (DevicePath, &Statement->HiiValue.Value.ref.FormSetGuid);\r
+ FreePool (DevicePath);\r
+ }\r
\r
- Width = GetWidth (Statement, Handle);\r
+ FreePool (StringPtr);\r
+ } else {\r
+ //\r
+ // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.\r
+ //\r
+ PopupErrorMessage (BROWSER_PROTOCOL_NOT_FOUND, NULL, NULL, NULL);\r
+ FreePool (StringPtr);\r
+ return Status;\r
+ }\r
\r
- NumberOfLines = 1;\r
- ArrayEntry = 0;\r
- GlyphWidth = 1;\r
- for (; GetLineByWidth (StringPtr, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {\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]) != 0) {\r
- NumberOfLines++;\r
+ if (HiiHandle != Selection->Handle) {\r
+ //\r
+ // Goto another Formset, check for uncommitted data\r
+ //\r
+ if (((gBrowserSettingScope == FormLevel) || (gBrowserSettingScope == FormSetLevel)) &&\r
+ IsNvUpdateRequiredForFormSet (Selection->FormSet))\r
+ {\r
+ if (!ProcessChangedData (Selection, FormSetLevel)) {\r
+ return EFI_SUCCESS;\r
}\r
+ }\r
+ }\r
+\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ Selection->Handle = HiiHandle;\r
+ if (Selection->Handle == NULL) {\r
+ //\r
+ // If target Hii Handle not found, exit current formset.\r
+ //\r
+ FindParentFormSet (Selection);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
+ Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
+ } else if (!IsZeroGuid (&Statement->HiiValue.Value.ref.FormSetGuid)) {\r
+ if (Selection->Form->ModalForm) {\r
+ return Status;\r
+ }\r
\r
- FreePool (OutputString);\r
+ if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &Selection->FormSetGuid)) {\r
+ //\r
+ // Goto another Formset, check for uncommitted data\r
+ //\r
+ if (((gBrowserSettingScope == FormLevel) || (gBrowserSettingScope == FormSetLevel)) &&\r
+ IsNvUpdateRequiredForFormSet (Selection->FormSet))\r
+ {\r
+ if (!ProcessChangedData (Selection, FormSetLevel)) {\r
+ return EFI_SUCCESS;\r
+ }\r
}\r
+ }\r
\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ Selection->Handle = FormSetGuidToHiiHandle (&Statement->HiiValue.Value.ref.FormSetGuid);\r
+ if (Selection->Handle == NULL) {\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
+ // If target Hii Handle not found, exit current formset.\r
//\r
- MenuOption = UiAddMenuOption (StringPtr, Selection->Handle, Selection->Form, Statement, NumberOfLines, MenuItemCount);\r
- MenuItemCount++;\r
+ FindParentFormSet (Selection);\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));\r
+ Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
+ } else if (Statement->HiiValue.Value.ref.FormId != 0) {\r
+ //\r
+ // Goto another Form, check for uncommitted data\r
+ //\r
+ if (Statement->HiiValue.Value.ref.FormId != Selection->FormId) {\r
+ if (((gBrowserSettingScope == FormLevel) && IsNvUpdateRequiredForForm (Selection->Form))) {\r
+ if (!ProcessChangedData (Selection, FormLevel)) {\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+ }\r
\r
- if (MenuOption->IsQuestion && !MenuOption->ReadOnly) {\r
+ RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);\r
+ if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {\r
+ if (EvaluateExpressionList (RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {\r
//\r
- // At least one item is not readonly, this Form is considered as editable\r
+ // Form is suppressed.\r
//\r
- Selection->FormEditable = TRUE;\r
+ PopupErrorMessage (BROWSER_FORM_SUPPRESS, NULL, NULL, NULL);\r
+ return EFI_SUCCESS;\r
}\r
}\r
\r
- Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+ Selection->FormId = Statement->HiiValue.Value.ref.FormId;\r
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
+ } else if (Statement->HiiValue.Value.ref.QuestionId != 0) {\r
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;\r
}\r
\r
- Status = UiDisplayMenu (Selection);\r
-\r
- UiFreeMenu ();\r
-\r
return Status;\r
}\r
\r
/**\r
- Initialize the HII String Token to the correct values.\r
+ Process Question Config.\r
\r
-**/\r
-VOID\r
-InitializeBrowserStrings (\r
- VOID\r
- )\r
-{\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
- 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
- gHexNumericInput = GetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), gHiiHandle);\r
- gToggleCheckBox = GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), gHiiHandle);\r
- gPromptForData = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);\r
- gPromptForPassword = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);\r
- gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);\r
- gConfirmPassword = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);\r
- gConfirmError = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);\r
- gPassowordInvalid = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);\r
- gPressEnter = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);\r
- gEmptyString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);\r
- gAreYouSure = GetToken (STRING_TOKEN (ARE_YOU_SURE), gHiiHandle);\r
- gYesResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);\r
- gNoResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);\r
- gMiniString = GetToken (STRING_TOKEN (MINI_STRING), 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
- gProtocolNotFound = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);\r
- return ;\r
-}\r
+ @param Selection The UI menu selection.\r
+ @param Question The Question to be peocessed.\r
\r
-/**\r
- Free up the resource allocated for all strings required\r
- by Setup Browser.\r
+ @retval EFI_SUCCESS Question Config process success.\r
+ @retval Other Question Config process fail.\r
\r
**/\r
-VOID\r
-FreeBrowserStrings (\r
- VOID\r
+EFI_STATUS\r
+ProcessQuestionConfig (\r
+ IN UI_MENU_SELECTION *Selection,\r
+ IN FORM_BROWSER_STATEMENT *Question\r
)\r
{\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
- FreePool (gProtocolNotFound);\r
- return ;\r
+ EFI_STATUS Status;\r
+ CHAR16 *ConfigResp;\r
+ CHAR16 *Progress;\r
+\r
+ if (Question->QuestionConfig == 0) {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Get <ConfigResp>\r
+ //\r
+ ConfigResp = GetToken (Question->QuestionConfig, Selection->FormSet->HiiHandle);\r
+ if (ConfigResp == NULL) {\r
+ return EFI_NOT_FOUND;\r
+ } else if (ConfigResp[0] == L'\0') {\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Send config to Configuration Driver\r
+ //\r
+ Status = mHiiConfigRouting->RouteConfig (\r
+ mHiiConfigRouting,\r
+ ConfigResp,\r
+ &Progress\r
+ );\r
+\r
+ return Status;\r
}\r
\r
/**\r
- Show all registered HotKey help strings on bottom Rows.\r
+\r
+ Process the user input data.\r
+\r
+ @param UserInput The user input data.\r
+\r
+ @retval EFI_SUCESSS This function always return successfully for now.\r
\r
**/\r
-VOID\r
-PrintHotKeyHelpString (\r
- VOID\r
+EFI_STATUS\r
+ProcessUserInput (\r
+ IN USER_INPUT *UserInput\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
+ EFI_STATUS Status;\r
+ FORM_BROWSER_STATEMENT *Statement;\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
+ Status = EFI_SUCCESS;\r
+ Statement = NULL;\r
\r
//\r
- // Calculate total number of Register HotKeys. \r
+ // When Exit from FormDisplay function, one of the below two cases must be true.\r
//\r
- Index = 0;\r
- Link = GetFirstNode (&gBrowserHotKeyList);\r
- while (!IsNull (&gBrowserHotKeyList, Link)) {\r
- HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);\r
+ ASSERT (UserInput->Action != 0 || UserInput->SelectedStatement != NULL);\r
+\r
+ //\r
+ // Remove the last highligh question id, this id will update when show next form.\r
+ //\r
+ gCurrentSelection->QuestionId = 0;\r
+ if (UserInput->SelectedStatement != NULL) {\r
+ Statement = GetBrowserStatement (UserInput->SelectedStatement);\r
+ ASSERT (Statement != NULL);\r
+\r
//\r
- // Help string can't exceed ColumnWidth. One Row will show three Help information. \r
+ // This question is the current user select one,record it and later\r
+ // show it as the highlight question.\r
//\r
- if (StrLen (HotKey->HelpString) > ColumnWidth) {\r
- HotKey->HelpString[ColumnWidth] = L'\0';\r
- }\r
+ gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;\r
//\r
- // Calculate help information Column and Row.\r
+ // For statement like text, actio, it not has question id.\r
+ // So use FakeQuestionId to save the question.\r
//\r
- if ((Index % 3) != 2) {\r
- CurrentCol = LocalScreen.LeftColumn + (2 - Index % 3) * ColumnWidth;\r
+ if (gCurrentSelection->CurrentMenu->QuestionId == 0) {\r
+ mCurFakeQestId = Statement->FakeQuestionId;\r
} else {\r
- CurrentCol = LocalScreen.LeftColumn + 2;\r
+ mCurFakeQestId = 0;\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
+ // First process the Action field in USER_INPUT.\r
+ //\r
+ if (UserInput->Action != 0) {\r
+ Status = ProcessAction (UserInput->Action, UserInput->DefaultId);\r
+ gCurrentSelection->Statement = NULL;\r
+ } else {\r
+ ASSERT (Statement != NULL);\r
+ gCurrentSelection->Statement = Statement;\r
+ switch (Statement->Operand) {\r
+ case EFI_IFR_REF_OP:\r
+ Status = ProcessGotoOpCode (Statement, gCurrentSelection);\r
+ break;\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
+ case EFI_IFR_ACTION_OP:\r
+ //\r
+ // Process the Config string <ConfigResp>\r
+ //\r
+ Status = ProcessQuestionConfig (gCurrentSelection, Statement);\r
+ break;\r
\r
-**/\r
-VOID\r
-UpdateKeyHelp (\r
- IN UI_MENU_SELECTION *Selection,\r
- IN UI_MENU_OPTION *MenuOption,\r
- IN BOOLEAN Selected\r
- )\r
-{\r
- UINTN SecCol;\r
- UINTN ThdCol;\r
- UINTN LeftColumnOfHelp;\r
- UINTN RightColumnOfHelp;\r
- UINTN TopRowOfHelp;\r
- UINTN BottomRowOfHelp;\r
- UINTN StartColumnOfHelp;\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
+ case EFI_IFR_RESET_BUTTON_OP:\r
+ //\r
+ // Reset Question to default value specified by DefaultId\r
+ //\r
+ Status = ExtractDefault (gCurrentSelection->FormSet, NULL, Statement->DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE, FALSE);\r
+ UpdateStatementStatus (gCurrentSelection->FormSet, NULL, FormSetLevel);\r
+ break;\r
\r
- CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));\r
+ default:\r
+ switch (Statement->Operand) {\r
+ case EFI_IFR_STRING_OP:\r
+ DeleteString (Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);\r
+ Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;\r
+ CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN)UserInput->InputValue.BufferLen);\r
+ FreePool (UserInput->InputValue.Buffer);\r
+ break;\r
+\r
+ case EFI_IFR_PASSWORD_OP:\r
+ if (UserInput->InputValue.Buffer == NULL) {\r
+ //\r
+ // User not input new password, just return.\r
+ //\r
+ break;\r
+ }\r
+\r
+ DeleteString (Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);\r
+ Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;\r
+ CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN)UserInput->InputValue.BufferLen);\r
+ ZeroMem (UserInput->InputValue.Buffer, (UINTN)UserInput->InputValue.BufferLen);\r
+ FreePool (UserInput->InputValue.Buffer);\r
+ //\r
+ // Two password match, send it to Configuration Driver\r
+ //\r
+ if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+ PasswordCheck (NULL, UserInput->SelectedStatement, (CHAR16 *)Statement->BufferValue);\r
+ //\r
+ // Clean the value after saved it.\r
+ //\r
+ ZeroMem (Statement->BufferValue, (UINTN)UserInput->InputValue.BufferLen);\r
+ HiiSetString (gCurrentSelection->FormSet->HiiHandle, Statement->HiiValue.Value.string, (CHAR16 *)Statement->BufferValue, NULL);\r
+ } else {\r
+ SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);\r
+ }\r
+\r
+ break;\r
+\r
+ case EFI_IFR_ORDERED_LIST_OP:\r
+ CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, UserInput->InputValue.BufferLen);\r
+ break;\r
+\r
+ default:\r
+ CopyMem (&Statement->HiiValue, &UserInput->InputValue, sizeof (EFI_HII_VALUE));\r
+ break;\r
+ }\r
\r
- SecCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;\r
- ThdCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3 * 2;\r
+ break;\r
+ }\r
+ }\r
\r
- StartColumnOfHelp = LocalScreen.LeftColumn + 2;\r
- LeftColumnOfHelp = LocalScreen.LeftColumn + 1;\r
- RightColumnOfHelp = LocalScreen.RightColumn - 2;\r
- TopRowOfHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;\r
- BottomRowOfHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;\r
+ return Status;\r
+}\r
\r
- Statement = MenuOption->ThisTag;\r
- switch (Statement->Operand) {\r
- case EFI_IFR_ORDERED_LIST_OP:\r
- case EFI_IFR_ONE_OF_OP:\r
- case EFI_IFR_NUMERIC_OP:\r
- case EFI_IFR_TIME_OP:\r
- case EFI_IFR_DATE_OP:\r
- ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
+/**\r
\r
- if (!Selected) {\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
+ Display form and wait for user to select one menu option, then return it.\r
\r
- if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {\r
- PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);\r
- }\r
+ @retval EFI_SUCESSS This function always return successfully for now.\r
\r
- if ((Statement->Operand == EFI_IFR_DATE_OP) ||\r
- (Statement->Operand == EFI_IFR_TIME_OP)) {\r
- PrintAt (\r
- StartColumnOfHelp,\r
- BottomRowOfHelp,\r
- L"%c%c%c%c%s",\r
- ARROW_UP,\r
- ARROW_DOWN,\r
- ARROW_RIGHT,\r
- ARROW_LEFT,\r
- gMoveHighlight\r
- );\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
- PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString);\r
+**/\r
+EFI_STATUS\r
+DisplayForm (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ USER_INPUT UserInput;\r
+ FORM_ENTRY_INFO *CurrentMenu;\r
\r
- //\r
- // If it is a selected numeric with manual input, display different message\r
- //\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
- ((Statement->Flags & EFI_IFR_DISPLAY_UINT_HEX) == EFI_IFR_DISPLAY_UINT_HEX) ? gHexNumericInput : gDecNumericInput\r
- );\r
- } else if (Statement->Operand != EFI_IFR_ORDERED_LIST_OP) {\r
- PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
- }\r
+ ZeroMem (&UserInput, sizeof (USER_INPUT));\r
\r
- if (Statement->Operand == EFI_IFR_ORDERED_LIST_OP) {\r
- PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString);\r
- PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);\r
- }\r
+ //\r
+ // Update the menu history data.\r
+ //\r
+ CurrentMenu = UiFindMenuList (gCurrentSelection->Handle, &gCurrentSelection->FormSetGuid, gCurrentSelection->FormId);\r
+ if (CurrentMenu == NULL) {\r
+ //\r
+ // Current menu not found, add it to the menu tree\r
+ //\r
+ CurrentMenu = UiAddMenuList (\r
+ gCurrentSelection->Handle,\r
+ &gCurrentSelection->FormSetGuid,\r
+ gCurrentSelection->FormId,\r
+ gCurrentSelection->QuestionId\r
+ );\r
+ ASSERT (CurrentMenu != NULL);\r
+ }\r
\r
- PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);\r
- }\r
- break;\r
+ //\r
+ // Back up the form view history data for this form.\r
+ //\r
+ UiCopyMenuList (&gCurrentSelection->Form->FormViewListHead, &mPrivateData.FormBrowserEx2.FormViewHistoryHead);\r
\r
- case EFI_IFR_CHECKBOX_OP:\r
- ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);\r
+ gCurrentSelection->CurrentMenu = CurrentMenu;\r
\r
+ if (gCurrentSelection->QuestionId == 0) {\r
//\r
- // On system setting, HotKey will show on every form.\r
+ // Highlight not specified, fetch it from cached menu\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
+ gCurrentSelection->QuestionId = CurrentMenu->QuestionId;\r
+ }\r
\r
- PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
- PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox);\r
- break;\r
+ Status = EvaluateFormExpressions (gCurrentSelection->FormSet, gCurrentSelection->Form);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
\r
- case EFI_IFR_REF_OP:\r
- case EFI_IFR_PASSWORD_OP:\r
- case EFI_IFR_STRING_OP:\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
+ UpdateDisplayFormData ();\r
\r
- if (!Selected) {\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
+ ASSERT (gDisplayFormData.BrowserStatus == BROWSER_SUCCESS);\r
+ Status = mFormDisplay->FormDisplay (&gDisplayFormData, &UserInput);\r
+ if (EFI_ERROR (Status)) {\r
+ FreeDisplayFormData ();\r
+ return Status;\r
+ }\r
\r
- PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);\r
- if (Statement->Operand != EFI_IFR_TEXT_OP && Statement->Operand != EFI_IFR_SUBTITLE_OP) {\r
- PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);\r
- }\r
- } else {\r
- if (Statement->Operand != EFI_IFR_REF_OP) {\r
- PrintStringAt (\r
- (LocalScreen.RightColumn - GetStringWidth (gEnterCommitString) / 2) / 2,\r
- BottomRowOfHelp,\r
- gEnterCommitString\r
- );\r
- PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);\r
- }\r
- }\r
- break;\r
+ CheckConfigAccess (gCurrentSelection->FormSet);\r
\r
- default:\r
- break;\r
- }\r
+ Status = ProcessUserInput (&UserInput);\r
+ FreeDisplayFormData ();\r
+ return Status;\r
}\r
\r
/**\r
EFI_STATUS\r
EFIAPI\r
FormUpdateNotify (\r
- IN UINT8 PackageType,\r
- IN CONST EFI_GUID *PackageGuid,\r
- IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
- IN EFI_HII_HANDLE Handle,\r
- IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
+ IN UINT8 PackageType,\r
+ IN CONST EFI_GUID *PackageGuid,\r
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
)\r
{\r
mHiiPackageListUpdated = TRUE;\r
+ mDynamicFormUpdated = TRUE;\r
\r
return EFI_SUCCESS;\r
}\r
\r
/**\r
- check whether the formset need to update the NV.\r
+ Update the NV flag info for this form set.\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
+BOOLEAN\r
+IsNvUpdateRequiredForFormSet (\r
IN FORM_BROWSER_FORMSET *FormSet\r
)\r
{\r
- LIST_ENTRY *Link;\r
- FORM_BROWSER_FORM *Form;\r
+ LIST_ENTRY *Link;\r
+ FORM_BROWSER_FORM *Form;\r
+ BOOLEAN RetVal;\r
+\r
+ //\r
+ // Not finished question initialization, return FALSE.\r
+ //\r
+ if (!FormSet->QuestionInited) {\r
+ return FALSE;\r
+ }\r
+\r
+ RetVal = FALSE;\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
+ RetVal = IsNvUpdateRequiredForForm (Form);\r
+ if (RetVal) {\r
+ break;\r
}\r
\r
Link = GetNextNode (&FormSet->FormListHead, Link);\r
}\r
\r
- return FALSE;\r
+ return RetVal;\r
}\r
\r
/**\r
- check whether the formset need to update the NV.\r
+ Update the NvUpdateRequired flag for a form.\r
\r
- @param FormSet FormSet data structure.\r
- @param SetValue Whether set new value or clear old value.\r
+ @param Form Form data structure.\r
\r
**/\r
-VOID\r
-UpdateNvInfoInForm (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN BOOLEAN SetValue\r
+BOOLEAN\r
+IsNvUpdateRequiredForForm (\r
+ IN FORM_BROWSER_FORM *Form\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
+ FORM_BROWSER_STATEMENT *Statement;\r
\r
- Form->NvUpdateRequired = SetValue;\r
+ Link = GetFirstNode (&Form->StatementListHead);\r
+ while (!IsNull (&Form->StatementListHead, Link)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
\r
- Link = GetNextNode (&FormSet->FormListHead, Link);\r
+ if (Statement->ValueChanged) {\r
+ return TRUE;\r
+ }\r
+\r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
}\r
+\r
+ return FALSE;\r
}\r
+\r
/**\r
Find menu which will show next time.\r
\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
+ @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.\r
+ else, we need to exit current formset.\r
+\r
+ @retval TRUE Exit current form.\r
+ @retval FALSE User press ESC and keep in current form.\r
**/\r
BOOLEAN\r
FindNextMenu (\r
- IN OUT UI_MENU_SELECTION *Selection,\r
- IN BOOLEAN *Repaint, \r
- IN BOOLEAN *NewLine \r
+ IN OUT UI_MENU_SELECTION *Selection,\r
+ IN BROWSER_SETTING_SCOPE SettingLevel\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
+ FORM_ENTRY_INFO *CurrentMenu;\r
+ FORM_ENTRY_INFO *ParentMenu;\r
+ BROWSER_SETTING_SCOPE Scope;\r
+\r
CurrentMenu = Selection->CurrentMenu;\r
+ Scope = FormSetLevel;\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
+ ParentMenu = UiFindParentMenu (CurrentMenu, SettingLevel);\r
+ while (ParentMenu != NULL && !ValidateHiiHandle (ParentMenu->HiiHandle)) {\r
+ ParentMenu = UiFindParentMenu (ParentMenu, SettingLevel);\r
+ }\r
+\r
+ if (ParentMenu != NULL) {\r
+ if (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\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
+ Scope = FormSetLevel;\r
}\r
+ }\r
+\r
+ //\r
+ // Form Level Check whether the data is changed.\r
+ //\r
+ if (((gBrowserSettingScope == FormLevel) && IsNvUpdateRequiredForForm (Selection->Form)) ||\r
+ ((gBrowserSettingScope == FormSetLevel) && IsNvUpdateRequiredForFormSet (Selection->FormSet) && (Scope == FormSetLevel)))\r
+ {\r
+ if (!ProcessChangedData (Selection, gBrowserSettingScope)) {\r
+ return FALSE;\r
+ }\r
+ }\r
\r
+ if (ParentMenu != NULL) {\r
//\r
- // Form Level Check whether the data is changed.\r
+ // ParentMenu is found. Then, go to it.\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
+ if (Scope == FormLevel) {\r
+ Selection->Action = UI_ACTION_REFRESH_FORM;\r
+ } else {\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));\r
+ Selection->Handle = ParentMenu->HiiHandle;\r
}\r
\r
Selection->Statement = NULL;\r
\r
- Selection->FormId = CurrentMenu->Parent->FormId;\r
- Selection->QuestionId = CurrentMenu->Parent->QuestionId;\r
+ Selection->FormId = ParentMenu->FormId;\r
+ Selection->QuestionId = ParentMenu->QuestionId;\r
\r
//\r
// Clear highlight record for this menu\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
+ // Current in root page, exit the SendForm\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
+ Selection->Action = UI_ACTION_EXIT;\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
+ return TRUE;\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
+ Reconnect the controller.\r
\r
- if (NewLine != NULL) {\r
- *NewLine = TRUE;\r
- }\r
+ @param DriverHandle The controller handle which need to be reconnect.\r
\r
- Selection->Action = UI_ACTION_NONE;\r
- return FALSE;\r
- }\r
+ @retval TRUE do the reconnect behavior success.\r
+ @retval FALSE do the reconnect behavior failed.\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
+BOOLEAN\r
+ReconnectController (\r
+ IN EFI_HANDLE DriverHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
\r
- Selection->Statement = NULL;\r
- if (CurrentMenu != NULL) {\r
- CurrentMenu->QuestionId = 0;\r
+ Status = gBS->DisconnectController (DriverHandle, NULL, NULL);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->ConnectController (DriverHandle, NULL, NULL, TRUE);\r
}\r
\r
- Selection->Action = UI_ACTION_EXIT;\r
- return TRUE;\r
+ return Status == EFI_SUCCESS;\r
}\r
\r
/**\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 FormSet The formset this question belong to.\r
+ @param Form The form this question belong to.\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
+ @retval EFI_SUCCESS The call back function executes successfully.\r
+ @return Other value if the call back function failed to execute.\r
**/\r
-EFI_STATUS \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
+ IN OUT UI_MENU_SELECTION *Selection,\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN FORM_BROWSER_STATEMENT *Question,\r
+ IN EFI_BROWSER_ACTION Action,\r
+ IN BOOLEAN SkipSaveOrDiscard\r
)\r
{\r
EFI_STATUS Status;\r
+ EFI_STATUS InternalStatus;\r
EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
EFI_HII_VALUE *HiiValue;\r
BOOLEAN NeedExit;\r
LIST_ENTRY *Link;\r
BROWSER_SETTING_SCOPE SettingLevel;\r
+ EFI_IFR_TYPE_VALUE BackUpValue;\r
+ UINT8 *BackUpBuffer;\r
+ CHAR16 *NewString;\r
\r
- ConfigAccess = Selection->FormSet->ConfigAccess;\r
+ ConfigAccess = 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
+ BackUpBuffer = NULL;\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
+ Link = GetFirstNode (&Form->StatementListHead);\r
+ while (!IsNull (&Form->StatementListHead, Link)) {\r
Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
- Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
\r
//\r
// if Question != NULL, only process the question. Else, process all question in this form.\r
if ((Question != NULL) && (Statement != Question)) {\r
continue;\r
}\r
- \r
+\r
if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
continue;\r
}\r
// Check whether Statement is disabled.\r
//\r
if (Statement->Expression != NULL) {\r
- if (EvaluateExpressionList(Statement->Expression, TRUE, Selection->FormSet, Selection->Form) == ExpressDisable) {\r
+ if (EvaluateExpressionList (Statement->Expression, TRUE, FormSet, Form) == ExpressDisable) {\r
continue;\r
}\r
}\r
\r
- HiiValue = &Statement->HiiValue;\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
+ TypeValue = (EFI_IFR_TYPE_VALUE *)Statement->BufferValue;\r
+ }\r
+\r
+ //\r
+ // If EFI_BROWSER_ACTION_CHANGING type, back up the new question value.\r
+ //\r
+ if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+ if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+ BackUpBuffer = AllocateCopyPool (Statement->StorageWidth, Statement->BufferValue);\r
+ ASSERT (BackUpBuffer != NULL);\r
+ } else {\r
+ CopyMem (&BackUpValue, &HiiValue->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
+ }\r
}\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
+ Status = ConfigAccess->Callback (\r
+ ConfigAccess,\r
+ Action,\r
+ Statement->QuestionId,\r
+ HiiValue->Type,\r
+ TypeValue,\r
+ &ActionRequest\r
+ );\r
if (!EFI_ERROR (Status)) {\r
//\r
- // Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.\r
+ // Need to sync the value between Statement->HiiValue->Value and Statement->BufferValue\r
//\r
- if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
- switch (ActionRequest) {\r
- case EFI_BROWSER_ACTION_REQUEST_RESET:\r
- gResetRequired = TRUE;\r
- Selection->Action = UI_ACTION_EXIT;\r
- break;\r
+ if (HiiValue->Type == EFI_IFR_TYPE_STRING) {\r
+ NewString = GetToken (Statement->HiiValue.Value.string, FormSet->HiiHandle);\r
+ ASSERT (NewString != NULL);\r
+\r
+ ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth);\r
+ if (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth) {\r
+ ZeroMem (Statement->BufferValue, Statement->StorageWidth);\r
+ CopyMem (Statement->BufferValue, NewString, StrSize (NewString));\r
+ } else {\r
+ CopyMem (Statement->BufferValue, NewString, Statement->StorageWidth);\r
+ }\r
\r
- case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
- SubmitFormIsRequired = TRUE;\r
- Selection->Action = UI_ACTION_EXIT;\r
- break;\r
+ FreePool (NewString);\r
+ }\r
\r
- case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
- DiscardFormIsRequired = TRUE;\r
- Selection->Action = UI_ACTION_EXIT;\r
- break;\r
+ //\r
+ // Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.\r
+ //\r
+ switch (Action) {\r
+ case EFI_BROWSER_ACTION_CHANGED:\r
+ switch (ActionRequest) {\r
+ case EFI_BROWSER_ACTION_REQUEST_RESET:\r
+ DiscardFormIsRequired = TRUE;\r
+ gResetRequiredFormLevel = TRUE;\r
+ gResetRequiredSystemLevel = TRUE;\r
+ NeedExit = TRUE;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
+ SubmitFormIsRequired = TRUE;\r
+ NeedExit = TRUE;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+ DiscardFormIsRequired = TRUE;\r
+ NeedExit = TRUE;\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
+ case EFI_BROWSER_ACTION_REQUEST_RECONNECT:\r
+ gCallbackReconnect = TRUE;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\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
+ case EFI_BROWSER_ACTION_CHANGING:\r
+ //\r
+ // Do the question validation.\r
+ //\r
+ Status = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);\r
+ if (!EFI_ERROR (Status)) {\r
+ //\r
+ // check whether the question value changed compared with edit buffer before updating edit buffer\r
+ // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function\r
+ //\r
+ IsQuestionValueChanged (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\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
+ SetQuestionValue (FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
+ }\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
+ case EFI_BROWSER_ACTION_RETRIEVE:\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
+ SetQuestionValue (FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
break;\r
\r
default:\r
break;\r
- }\r
}\r
-\r
+ } else {\r
//\r
- // According the spec, return value from call back of "changing" and \r
- // "retrieve" should update to the question's temp buffer.\r
+ // If the callback returns EFI_UNSUPPORTED for EFI_BROWSER_ACTION_CHANGING,\r
+ // then the browser will use the value passed to Callback() and ignore the\r
+ // value returned by Callback().\r
//\r
- if (Action == EFI_BROWSER_ACTION_CHANGING || Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
- SetQuestionValue(Selection->FormSet, Selection->Form, Statement, GetSetValueWithEditBuffer);\r
+ if ((Action == EFI_BROWSER_ACTION_CHANGING) && (Status == EFI_UNSUPPORTED)) {\r
+ if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
+ CopyMem (Statement->BufferValue, BackUpBuffer, Statement->StorageWidth);\r
+ } else {\r
+ CopyMem (&HiiValue->Value, &BackUpValue, sizeof (EFI_IFR_TYPE_VALUE));\r
+ }\r
+\r
+ //\r
+ // Do the question validation.\r
+ //\r
+ InternalStatus = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);\r
+ if (!EFI_ERROR (InternalStatus)) {\r
+ //\r
+ // check whether the question value changed compared with edit buffer before updating edit buffer\r
+ // if changed, set the ValueChanged flag to TRUE,in order to trig the CHANGED callback function\r
+ //\r
+ IsQuestionValueChanged (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
+ SetQuestionValue (FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
+ }\r
}\r
- } else {\r
+\r
//\r
- // According the spec, return fail from call back of "changing" and \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, GetSetValueWithEditBuffer);\r
+ if ((Action == EFI_BROWSER_ACTION_CHANGING) && (Status != EFI_UNSUPPORTED)) {\r
+ if (Statement->Storage != NULL) {\r
+ GetQuestionValue (FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
+ } else if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {\r
+ ProcessCallBackFunction (Selection, FormSet, Form, Question, EFI_BROWSER_ACTION_RETRIEVE, FALSE);\r
+ }\r
+ }\r
+\r
+ if (Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
+ GetQuestionValue (FormSet, Form, Statement, GetSetValueWithEditBuffer);\r
}\r
\r
if (Status == EFI_UNSUPPORTED) {\r
Status = EFI_SUCCESS;\r
}\r
}\r
+\r
+ if (BackUpBuffer != NULL) {\r
+ FreePool (BackUpBuffer);\r
+ }\r
+\r
+ //\r
+ // If Question != NULL, means just process one question\r
+ // and if code reach here means this question has finished\r
+ // processing, so just break.\r
+ //\r
+ if (Question != NULL) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (gCallbackReconnect && (EFI_BROWSER_ACTION_CHANGED == Action)) {\r
+ //\r
+ // Confirm changes with user first.\r
+ //\r
+ if (IsNvUpdateRequiredForFormSet (FormSet)) {\r
+ if (BROWSER_ACTION_DISCARD == PopupErrorMessage (BROWSER_RECONNECT_SAVE_CHANGES, NULL, NULL, NULL)) {\r
+ gCallbackReconnect = FALSE;\r
+ DiscardFormIsRequired = TRUE;\r
+ } else {\r
+ SubmitFormIsRequired = TRUE;\r
+ }\r
+ } else {\r
+ PopupErrorMessage (BROWSER_RECONNECT_REQUIRED, NULL, NULL, NULL);\r
+ }\r
+\r
+ //\r
+ // Exit current formset before do the reconnect.\r
+ //\r
+ NeedExit = TRUE;\r
+ SettingLevel = FormSetLevel;\r
}\r
\r
if (SubmitFormIsRequired && !SkipSaveOrDiscard) {\r
- SubmitForm (Selection->FormSet, Selection->Form, SettingLevel);\r
+ SubmitForm (FormSet, Form, SettingLevel);\r
}\r
\r
if (DiscardFormIsRequired && !SkipSaveOrDiscard) {\r
- DiscardForm (Selection->FormSet, Selection->Form, SettingLevel);\r
+ DiscardForm (FormSet, Form, SettingLevel);\r
}\r
\r
if (NeedExit) {\r
- FindNextMenu (Selection, NULL, NULL);\r
+ FindNextMenu (Selection, SettingLevel);\r
}\r
\r
return Status;\r
\r
/**\r
Call the retrieve type call back function for one question to get the initialize data.\r
- \r
- This function only used when in the initialize stage, because in this stage, the \r
+\r
+ This function only used when in the initialize stage, because in this stage, the\r
Selection->Form is not ready. For other case, use the ProcessCallBackFunction instead.\r
\r
@param ConfigAccess The config access protocol produced by the hii driver.\r
@param Statement The Question which need to call.\r
+ @param FormSet The formset this question belong to.\r
\r
- @retval EFI_SUCCESS The call back function excutes successfully.\r
- @return Other value if the call back function failed to excute. \r
+ @retval EFI_SUCCESS The call back function executes successfully.\r
+ @return Other value if the call back function failed to execute.\r
**/\r
-EFI_STATUS \r
+EFI_STATUS\r
ProcessRetrieveForQuestion (\r
IN EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess,\r
- IN FORM_BROWSER_STATEMENT *Statement\r
+ IN FORM_BROWSER_STATEMENT *Statement,\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
- EFI_HII_VALUE *HiiValue;\r
- EFI_IFR_TYPE_VALUE *TypeValue;\r
+ EFI_STATUS Status;\r
+ EFI_BROWSER_ACTION_REQUEST ActionRequest;\r
+ EFI_HII_VALUE *HiiValue;\r
+ EFI_IFR_TYPE_VALUE *TypeValue;\r
+ CHAR16 *NewString;\r
\r
- Status = EFI_SUCCESS;\r
- ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
- \r
- if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
+ Status = EFI_SUCCESS;\r
+ ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+\r
+ if (((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) || (ConfigAccess == NULL)) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
//\r
// For OrderedList, passing in the value buffer to Callback()\r
//\r
- TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue;\r
+ TypeValue = (EFI_IFR_TYPE_VALUE *)Statement->BufferValue;\r
}\r
- \r
+\r
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
- Status = ConfigAccess->Callback (\r
- ConfigAccess,\r
- EFI_BROWSER_ACTION_RETRIEVE,\r
- Statement->QuestionId,\r
- HiiValue->Type,\r
- TypeValue,\r
- &ActionRequest\r
- );\r
+ Status = ConfigAccess->Callback (\r
+ ConfigAccess,\r
+ EFI_BROWSER_ACTION_RETRIEVE,\r
+ Statement->QuestionId,\r
+ HiiValue->Type,\r
+ TypeValue,\r
+ &ActionRequest\r
+ );\r
+ if (!EFI_ERROR (Status) && (HiiValue->Type == EFI_IFR_TYPE_STRING)) {\r
+ NewString = GetToken (Statement->HiiValue.Value.string, FormSet->HiiHandle);\r
+ ASSERT (NewString != NULL);\r
+\r
+ ASSERT (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth);\r
+ if (StrLen (NewString) * sizeof (CHAR16) <= Statement->StorageWidth) {\r
+ ZeroMem (Statement->BufferValue, Statement->StorageWidth);\r
+ CopyMem (Statement->BufferValue, NewString, StrSize (NewString));\r
+ } else {\r
+ CopyMem (Statement->BufferValue, NewString, Statement->StorageWidth);\r
+ }\r
+\r
+ FreePool (NewString);\r
+ }\r
+\r
return Status;\r
}\r
\r
**/\r
EFI_STATUS\r
SetupBrowser (\r
- IN OUT UI_MENU_SELECTION *Selection\r
+ IN OUT UI_MENU_SELECTION *Selection\r
)\r
{\r
EFI_STATUS Status;\r
EFI_HANDLE NotifyHandle;\r
FORM_BROWSER_STATEMENT *Statement;\r
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
- EFI_INPUT_KEY Key;\r
\r
- gMenuRefreshHead = NULL;\r
ConfigAccess = Selection->FormSet->ConfigAccess;\r
\r
//\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
+ InitializeCurrentSetting (Selection->FormSet);\r
\r
//\r
- // Update gOldFormSet on maintain back up FormSet list.\r
- // And, make gOldFormSet point to current FormSet. \r
+ // Initilize Action field.\r
//\r
- if (gOldFormSet != NULL) {\r
- RemoveEntryList (&gOldFormSet->Link);\r
- DestroyFormSet (gOldFormSet);\r
- }\r
- gOldFormSet = Selection->FormSet;\r
- InsertTailList (&gBrowserFormSetList, &gOldFormSet->Link);\r
+ Selection->Action = UI_ACTION_REFRESH_FORM;\r
+\r
+ //\r
+ // Clean the mCurFakeQestId value is formset refreshed.\r
+ //\r
+ mCurFakeQestId = 0;\r
\r
do {\r
+ //\r
+ // Reset Status to prevent the next break from returning incorrect error status.\r
+ //\r
+ Status = EFI_SUCCESS;\r
+\r
//\r
// IFR is updated, force to reparse the IFR binary\r
+ // This check is shared by EFI_BROWSER_ACTION_FORM_CLOSE and\r
+ // EFI_BROWSER_ACTION_RETRIEVE, so code place here.\r
//\r
if (mHiiPackageListUpdated) {\r
- Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
mHiiPackageListUpdated = FALSE;\r
break;\r
}\r
//\r
Link = GetFirstNode (&Selection->FormSet->FormListHead);\r
\r
- Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
+ Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
Selection->FormId = Selection->Form->FormId;\r
} else {\r
Selection->Form = IdToForm (Selection->FormSet, Selection->FormId);\r
// Check Form is suppressed.\r
//\r
if (Selection->Form->SuppressExpression != NULL) {\r
- if (EvaluateExpressionList(Selection->Form->SuppressExpression, TRUE, Selection->FormSet, Selection->Form) == ExpressSuppress) {\r
+ if (EvaluateExpressionList (Selection->Form->SuppressExpression, TRUE, Selection->FormSet, Selection->Form) == ExpressSuppress) {\r
//\r
- // Form is suppressed. \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
+ PopupErrorMessage (BROWSER_FORM_SUPPRESS, NULL, NULL, NULL);\r
Status = EFI_NOT_FOUND;\r
goto Done;\r
}\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
+ if (((Selection->Handle != mCurrentHiiHandle) ||\r
+ (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
+ (Selection->FormId != mCurrentFormId)))\r
+ {\r
+ //\r
+ // Update Retrieve flag.\r
+ //\r
+ mFinishRetrieveCall = FALSE;\r
\r
//\r
// Keep current form information\r
//\r
- mCurrentHiiHandle = Selection->Handle;\r
+ mCurrentHiiHandle = Selection->Handle;\r
CopyGuid (&mCurrentFormSetGuid, &Selection->FormSetGuid);\r
- mCurrentFormId = Selection->FormId;\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
+ if (ConfigAccess != NULL) {\r
+ Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, 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
+ // IFR is updated during callback of EFI_BROWSER_ACTION_FORM_OPEN, 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
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
+ if (!mFinishRetrieveCall) {\r
+ //\r
+ // Finish call RETRIEVE callback for this form.\r
+ //\r
+ mFinishRetrieveCall = TRUE;\r
\r
- //\r
- // Displays the Header and Footer borders\r
- //\r
- DisplayPageFrame (Selection);\r
+ if (ConfigAccess != NULL) {\r
+ Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_RETRIEVE, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\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
//\r
// Display form\r
//\r
- Status = DisplayForm (Selection);\r
+ Status = DisplayForm ();\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\r
//\r
Statement = Selection->Statement;\r
if (Statement != NULL) {\r
- if ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED) {\r
- gResetRequired = TRUE;\r
- }\r
-\r
- if ((ConfigAccess != NULL) && \r
- ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \r
- (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
- Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE); \r
- if (Statement->Operand == EFI_IFR_REF_OP && Selection->Action != UI_ACTION_EXIT) {\r
+ if ((ConfigAccess != NULL) &&\r
+ ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) &&\r
+ (Statement->Operand != EFI_IFR_PASSWORD_OP))\r
+ {\r
+ Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
+ if (Statement->Operand == EFI_IFR_REF_OP) {\r
//\r
// Process dynamic update ref opcode.\r
//\r
if (!EFI_ERROR (Status)) {\r
- Status = ProcessGotoOpCode(Statement, Selection, NULL, NULL);\r
+ Status = ProcessGotoOpCode (Statement, Selection);\r
}\r
- \r
+\r
//\r
// Callback return error status or status return from process goto opcode.\r
//\r
if (EFI_ERROR (Status)) {\r
//\r
- // Cross reference will not be taken\r
+ // Cross reference will not be taken, restore all essential field\r
//\r
- Selection->FormId = Selection->Form->FormId;\r
+ Selection->Handle = mCurrentHiiHandle;\r
+ CopyMem (&Selection->FormSetGuid, &mCurrentFormSetGuid, sizeof (EFI_GUID));\r
+ Selection->FormId = mCurrentFormId;\r
Selection->QuestionId = 0;\r
+ Selection->Action = UI_ACTION_REFRESH_FORM;\r
}\r
}\r
\r
- if (!EFI_ERROR (Status) && Statement->Operand != EFI_IFR_REF_OP) {\r
- ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);\r
+ if (!EFI_ERROR (Status) &&\r
+ (Statement->Operand != EFI_IFR_REF_OP) &&\r
+ ((Statement->Storage == NULL) || ((Statement->Storage != NULL) && Statement->ValueChanged)))\r
+ {\r
+ //\r
+ // Only question value has been changed, browser will trig CHANGED callback.\r
+ //\r
+ ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGED, FALSE);\r
+ //\r
+ // check whether the question value changed compared with buffer value\r
+ // if doesn't change ,set the ValueChanged flag to FALSE ,in order not to display the "configuration changed "information on the screen\r
+ //\r
+ IsQuestionValueChanged (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithBuffer);\r
+ }\r
+ } else {\r
+ //\r
+ // Do the question validation.\r
+ //\r
+ Status = ValueChangedValidation (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement);\r
+ if (!EFI_ERROR (Status) && (Statement->Operand != EFI_IFR_PASSWORD_OP)) {\r
+ SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\r
+ //\r
+ // Verify whether question value has checked, update the ValueChanged flag in Question.\r
+ //\r
+ IsQuestionValueChanged (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithBuffer);\r
+ }\r
+ }\r
+\r
+ //\r
+ // If question has EFI_IFR_FLAG_RESET_REQUIRED/EFI_IFR_FLAG_RECONNECT_REQUIRED flag and without storage\r
+ // and process question success till here, trig the gResetFlag/gFlagReconnect.\r
+ //\r
+ if ((Status == EFI_SUCCESS) &&\r
+ (Statement->Storage == NULL))\r
+ {\r
+ if ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0) {\r
+ gResetRequiredFormLevel = TRUE;\r
+ gResetRequiredSystemLevel = TRUE;\r
+ }\r
+\r
+ if ((Statement->QuestionFlags & EFI_IFR_FLAG_RECONNECT_REQUIRED) != 0) {\r
+ gFlagReconnect = TRUE;\r
}\r
}\r
}\r
\r
+ //\r
+ // Check whether Exit flag is TRUE.\r
+ //\r
+ if (gExitRequired) {\r
+ switch (gBrowserSettingScope) {\r
+ case SystemLevel:\r
+ Selection->Action = UI_ACTION_EXIT;\r
+ break;\r
+\r
+ case FormSetLevel:\r
+ case FormLevel:\r
+ FindNextMenu (Selection, gBrowserSettingScope);\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ gExitRequired = FALSE;\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
+ 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
+ (Selection->FormId != mCurrentFormId)))\r
+ {\r
+ Status = ProcessCallBackFunction (Selection, Selection->FormSet, Selection->Form, NULL, EFI_BROWSER_ACTION_FORM_CLOSE, FALSE);\r
if (EFI_ERROR (Status)) {\r
goto Done;\r
}\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
+ if (EFI_ERROR (Status) || (Selection->Action == UI_ACTION_EXIT)) {\r
mCurrentHiiHandle = NULL;\r
CopyGuid (&mCurrentFormSetGuid, &gZeroGuid);\r
mCurrentFormId = 0;\r
// Unregister notify for Form package update\r
//\r
mHiiDatabase->UnregisterPackageNotify (\r
- mHiiDatabase,\r
- NotifyHandle\r
- );\r
+ mHiiDatabase,\r
+ NotifyHandle\r
+ );\r
return Status;\r
}\r