/** @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
-\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
+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
**/\r
\r
UINT16 mCurrentFormId = 0;\r
EFI_EVENT mValueChangedEvent = NULL;\r
LIST_ENTRY mRefreshEventList = INITIALIZE_LIST_HEAD_VARIABLE (mRefreshEventList);\r
-UINT32 gBrowserStatus = BROWSER_SUCCESS;\r
-CHAR16 *gErrorInfo;\r
UINT16 mCurFakeQestId;\r
FORM_DISPLAY_ENGINE_FORM gDisplayFormData;\r
+BOOLEAN mFinishRetrieveCall = FALSE;\r
\r
/**\r
Evaluate all expressions in a Form.\r
return EFI_SUCCESS;\r
}\r
\r
-/**\r
- Add empty function for event process function.\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
-SetupBrowserEmptyFunction (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\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
+\r
@retval Statement The statement use this opcode buffer.\r
\r
**/\r
Free the refresh event list.\r
\r
**/\r
-VOID \r
+VOID\r
FreeRefreshEvent (\r
VOID\r
)\r
}\r
\r
/**\r
- Check whether this statement value is changed. If yes, update the statement value and return TRUE; \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
// 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
+\r
if (mHiiPackageListUpdated) {\r
//\r
// Package list is updated, force to reparse IFR binary of target Formset\r
\r
/**\r
Refresh the question which has refresh guid event attribute.\r
- \r
- @param Event The event which has this function related. \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
-RefreshEventNotify(\r
+RefreshEventNotifyForStatement(\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
)\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
**/\r
VOID\r
-CreateRefreshEvent (\r
+CreateRefreshEventForStatement (\r
IN FORM_BROWSER_STATEMENT *Statement\r
)\r
{\r
Status = gBS->CreateEventEx (\r
EVT_NOTIFY_SIGNAL,\r
TPL_CALLBACK,\r
- RefreshEventNotify,\r
+ RefreshEventNotifyForStatement,\r
Statement,\r
&Statement->RefreshGuid,\r
&RefreshEvent);\r
}\r
\r
/**\r
- Perform value check for a question.\r
- \r
- @param Question The question need to do check.\r
- @param Type Condition type need to check.\r
- @param ErrorInfo Return info about the error.\r
- \r
- @retval The check result.\r
-**/\r
-UINT32\r
-ConditionCheck (\r
- IN FORM_BROWSER_STATEMENT *Question,\r
- IN UINT8 Type,\r
- OUT STATEMENT_ERROR_INFO *ErrorInfo\r
- )\r
-{\r
- EFI_STATUS Status;\r
- LIST_ENTRY *Link;\r
- FORM_EXPRESSION *Expression;\r
- LIST_ENTRY *ListHead;\r
- UINT32 RetVal;\r
-\r
- RetVal = STATEMENT_VALID;\r
- ListHead = NULL;\r
-\r
- switch (Type) {\r
- case EFI_HII_EXPRESSION_INCONSISTENT_IF:\r
- ListHead = &Question->InconsistentListHead;\r
- break;\r
-\r
- case EFI_HII_EXPRESSION_WARNING_IF:\r
- ListHead = &Question->WarningListHead;\r
- break;\r
-\r
- default:\r
- ASSERT (FALSE);\r
- return RetVal;\r
- }\r
-\r
- ASSERT (ListHead != NULL);\r
- Link = GetFirstNode (ListHead);\r
- while (!IsNull (ListHead, Link)) {\r
- Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
- Link = GetNextNode (ListHead, Link);\r
-\r
- //\r
- // Evaluate the expression\r
- //\r
- Status = EvaluateExpression (gCurrentSelection->FormSet, gCurrentSelection->Form, Expression);\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
+ Create refresh hook event for form which has refresh event or interval.\r
\r
- if ((Expression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && Expression->Result.Value.b) {\r
- ErrorInfo->StringId = Expression->Error;\r
- switch (Type) {\r
- case EFI_HII_EXPRESSION_INCONSISTENT_IF:\r
- ErrorInfo->TimeOut = 0;\r
- RetVal = INCOSISTENT_IF_TRUE;\r
- break;\r
+ @param Form The form need to check.\r
\r
- case EFI_HII_EXPRESSION_WARNING_IF:\r
- ErrorInfo->TimeOut = Expression->TimeOut;\r
- RetVal = WARNING_IF_TRUE;\r
- break;\r
-\r
- default:\r
- ASSERT (FALSE);\r
- break;\r
- }\r
- break;\r
- }\r
- }\r
-\r
- return RetVal;\r
-}\r
-\r
-/**\r
- Perform value check for a question.\r
- \r
- @param Form Form where Statement is in.\r
- @param Statement Value will check for it.\r
- @param InputValue New value will be checked.\r
- @param ErrorInfo Return the error info for this check.\r
- \r
- @retval TRUE Input Value is valid.\r
- @retval FALSE Input Value is invalid.\r
**/\r
-UINT32\r
-EFIAPI\r
-QuestionCheck (\r
- IN FORM_DISPLAY_ENGINE_FORM *Form,\r
- IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,\r
- IN EFI_HII_VALUE *InputValue,\r
- OUT STATEMENT_ERROR_INFO *ErrorInfo\r
+VOID\r
+CreateRefreshEventForForm (\r
+ IN FORM_BROWSER_FORM *Form\r
)\r
{\r
- FORM_BROWSER_STATEMENT *Question;\r
- EFI_HII_VALUE BackUpValue;\r
- UINT8 *BackUpBuffer;\r
- UINT32 RetVal;\r
-\r
- BackUpBuffer = NULL;\r
- RetVal = STATEMENT_VALID;\r
-\r
- ASSERT (Form != NULL && Statement != NULL && InputValue != NULL && ErrorInfo != NULL);\r
-\r
- Question = GetBrowserStatement(Statement);\r
- ASSERT (Question != NULL);\r
-\r
- //\r
- // Back up the quesion value.\r
- //\r
- switch (Question->Operand) {\r
- case EFI_IFR_ORDERED_LIST_OP:\r
- BackUpBuffer = AllocateCopyPool (Question->StorageWidth, Question->BufferValue);\r
- ASSERT (BackUpBuffer != NULL);\r
- CopyMem (Question->BufferValue, InputValue->Buffer, Question->StorageWidth);\r
- break;\r
-\r
- default:\r
- CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));\r
- CopyMem (&Question->HiiValue, InputValue, sizeof (EFI_HII_VALUE));\r
- break;\r
- }\r
-\r
- //\r
- // Do the inconsistentif check.\r
- //\r
- if (!IsListEmpty (&Question->InconsistentListHead)) {\r
- RetVal = ConditionCheck(Question, EFI_HII_EXPRESSION_INCONSISTENT_IF, ErrorInfo);\r
- }\r
-\r
- //\r
- // Do the warningif check.\r
- //\r
- if (RetVal == STATEMENT_VALID && !IsListEmpty (&Question->WarningListHead)) {\r
- RetVal = ConditionCheck(Question, EFI_HII_EXPRESSION_WARNING_IF, ErrorInfo);\r
- }\r
+ EFI_STATUS Status;\r
+ EFI_EVENT RefreshEvent;\r
+ FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;\r
\r
//\r
- // Restore the quesion value.\r
+ // If question has refresh guid, create the notify function.\r
//\r
- switch (Question->Operand) {\r
- case EFI_IFR_ORDERED_LIST_OP:\r
- CopyMem (Question->BufferValue, BackUpBuffer, Question->StorageWidth);\r
- break;\r
-\r
- default:\r
- CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));\r
- break;\r
- }\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_CALLBACK,\r
+ RefreshEventNotifyForForm,\r
+ Form,\r
+ &Form->RefreshGuid,\r
+ &RefreshEvent);\r
+ ASSERT_EFI_ERROR (Status);\r
\r
- return RetVal;\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
// Create the refresh event process function.\r
//\r
- if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {\r
- CreateRefreshEvent (Statement);\r
+ if (!IsZeroGuid (&Statement->RefreshGuid)) {\r
+ CreateRefreshEventForStatement (Statement);\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 ((!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) || (Statement->RefreshInterval != 0)) {\r
+ if ((!IsZeroGuid (&Statement->RefreshGuid)) || (Statement->RefreshInterval != 0)) {\r
gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
}\r
\r
DisplayStatement->PasswordCheck = PasswordCheck;\r
}\r
\r
- //\r
- // Save the validate check question for later use.\r
- //\r
- if (!IsListEmpty (&Statement->InconsistentListHead) || !IsListEmpty (&Statement->WarningListHead)) {\r
- DisplayStatement->ValidateQuestion = QuestionCheck;\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
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
\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
+ @retval The attribute for this question or NULL if not found this\r
question in the list.\r
\r
**/\r
-UINT32 \r
+UINT32\r
ProcessQuestionExtraAttr (\r
IN EFI_QUESTION_ID QuestionId\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
//\r
// Get the minimal refresh interval value for later use.\r
//\r
- if ((Statement->RefreshInterval != 0) && \r
+ if ((Statement->RefreshInterval != 0) &&\r
(MinRefreshInterval == 0 || Statement->RefreshInterval < MinRefreshInterval)) {\r
MinRefreshInterval = Statement->RefreshInterval;\r
}\r
InsertTailList(&mRefreshEventList, &EventNode->Link);\r
}\r
\r
+ //\r
+ // Create the refresh event process function for Form.\r
+ //\r
+ if (!IsZeroGuid (&gCurrentSelection->Form->RefreshGuid)) {\r
+ CreateRefreshEventForForm (gCurrentSelection->Form);\r
+ if (gDisplayFormData.FormRefreshEvent == NULL) {\r
+ gDisplayFormData.FormRefreshEvent = mValueChangedEvent;\r
+ }\r
+ }\r
+\r
//\r
// Update hotkey list field.\r
//\r
\r
//\r
// Base on the system level to check whether need to show the NV flag.\r
- // \r
+ //\r
switch (gBrowserSettingScope) {\r
case SystemLevel:\r
//\r
InitializeListHead (&gDisplayFormData.HotKeyListHead);\r
\r
Status = gBS->CreateEvent (\r
- EVT_NOTIFY_WAIT, \r
+ EVT_NOTIFY_WAIT,\r
TPL_CALLBACK,\r
- SetupBrowserEmptyFunction,\r
+ EfiEventEmptyFunction,\r
NULL,\r
&mValueChangedEvent\r
);\r
- ASSERT_EFI_ERROR (Status); \r
+ ASSERT_EFI_ERROR (Status);\r
}\r
\r
/**\r
gDisplayFormData.FormRefreshEvent = NULL;\r
gDisplayFormData.HighLightedStatement = NULL;\r
\r
- gDisplayFormData.BrowserStatus = gBrowserStatus;\r
- gDisplayFormData.ErrorString = gErrorInfo;\r
-\r
- gBrowserStatus = BROWSER_SUCCESS;\r
- gErrorInfo = NULL;\r
-\r
UpdateDataChangedFlag ();\r
\r
AddStatementToDisplayForm ();\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
+ // For password opcode, not set the the value changed flag.\r
+ //\r
+ if (Question->Operand == EFI_IFR_PASSWORD_OP) {\r
+ continue;\r
+ }\r
+\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
+ UpdateStatementStatusForForm (FormSet, Form);\r
+ }\r
+}\r
+\r
+/**\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
+**/\r
+VOID\r
+UpdateStatementStatus (\r
+ IN FORM_BROWSER_FORMSET *FormSet,\r
+ IN FORM_BROWSER_FORM *Form,\r
+ IN BROWSER_SETTING_SCOPE SettingScope\r
+ )\r
+{\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
+ 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
@retval EFI_SUCESSS This function always return successfully for now.\r
\r
**/\r
-EFI_STATUS \r
+EFI_STATUS\r
ProcessAction (\r
IN UINT32 Action,\r
IN UINT16 DefaultId\r
)\r
{\r
- EFI_STATUS Status;\r
-\r
//\r
// This is caused by use press ESC, and it should not combine with other action type.\r
//\r
}\r
\r
if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {\r
- ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);\r
+ ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE, FALSE);\r
+ UpdateStatementStatus (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
}\r
\r
if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {\r
- Status = SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
- if (EFI_ERROR (Status)) {\r
- gBrowserStatus = BROWSER_SUBMIT_FAIL;\r
- }\r
+ SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);\r
}\r
\r
if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {\r
- gResetRequired = TRUE;\r
+ gResetRequiredFormLevel = TRUE;\r
+ gResetRequiredSystemLevel = TRUE;\r
}\r
\r
if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {\r
BufferSize = 0;\r
HiiPackageList = NULL;\r
FindGuid = FALSE;\r
- \r
+\r
Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);\r
if (Status == EFI_BUFFER_TOO_SMALL) {\r
HiiPackageList = AllocatePool (BufferSize);\r
//\r
Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
Offset2 = 0;\r
- CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32)); \r
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
\r
while (Offset < PackageListLength) {\r
Package = ((UINT8 *) HiiPackageList) + Offset;\r
IN BROWSER_SETTING_SCOPE Scope\r
)\r
{\r
- BOOLEAN RetValue;\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
+\r
case BROWSER_ACTION_SUBMIT:\r
- SubmitForm (Selection->FormSet, Selection->Form, Scope);\r
+ Status = SubmitForm (Selection->FormSet, Selection->Form, Scope);\r
+ if (EFI_ERROR (Status)) {\r
+ RetValue = FALSE;\r
+ }\r
break;\r
\r
case BROWSER_ACTION_NONE:\r
FORM_ENTRY_INFO *ParentMenu;\r
\r
CurrentMenu = Selection->CurrentMenu;\r
- ParentMenu = UiFindParentMenu(CurrentMenu);\r
-\r
- //\r
- // Find a menu which has different formset guid with current.\r
- //\r
- while (ParentMenu != NULL && CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
- CurrentMenu = ParentMenu;\r
- ParentMenu = UiFindParentMenu(CurrentMenu);\r
- }\r
+ ParentMenu = UiFindParentMenu(CurrentMenu, FormSetLevel);\r
\r
if (ParentMenu != NULL) {\r
CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));\r
FORM_BROWSER_FORM *RefForm;\r
EFI_STATUS Status;\r
EFI_HII_HANDLE HiiHandle;\r
- \r
+\r
Status = EFI_SUCCESS;\r
StringPtr = NULL;\r
HiiHandle = NULL;\r
//\r
// Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.\r
//\r
- gBrowserStatus = BROWSER_PROTOCOL_NOT_FOUND;\r
+ PopupErrorMessage(BROWSER_PROTOCOL_NOT_FOUND, NULL, NULL, NULL);\r
FreePool (StringPtr);\r
return Status;\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 (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {\r
+ } else if (!IsZeroGuid (&Statement->HiiValue.Value.ref.FormSetGuid)) {\r
if (Selection->Form->ModalForm) {\r
return Status;\r
}\r
if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {\r
if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {\r
//\r
- // Form is suppressed. \r
+ // Form is suppressed.\r
//\r
- gBrowserStatus = BROWSER_FORM_SUPPRESS;\r
+ PopupErrorMessage(BROWSER_FORM_SUPPRESS, NULL, NULL, NULL);\r
return EFI_SUCCESS;\r
}\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
Process the user input data.\r
\r
@param UserInput The user input data.\r
- @param ChangeHighlight Whether need to change the highlight statement. \r
\r
@retval EFI_SUCESSS This function always return successfully for now.\r
\r
**/\r
EFI_STATUS\r
ProcessUserInput (\r
- IN USER_INPUT *UserInput,\r
- IN BOOLEAN ChangeHighlight\r
+ IN USER_INPUT *UserInput\r
)\r
{\r
EFI_STATUS Status;\r
FORM_BROWSER_STATEMENT *Statement;\r
\r
- Status = EFI_SUCCESS;\r
+ Status = EFI_SUCCESS;\r
+ Statement = NULL;\r
\r
//\r
// When Exit from FormDisplay function, one of the below two cases must be true.\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
+ // This question is the current user select one,record it and later\r
+ // show it as the highlight question.\r
+ //\r
+ gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;\r
+ //\r
+ // For statement like text, actio, it not has question id.\r
+ // So use FakeQuestionId to save the question.\r
+ //\r
+ if (gCurrentSelection->CurrentMenu->QuestionId == 0) {\r
+ mCurFakeQestId = Statement->FakeQuestionId;\r
+ } else {\r
+ mCurFakeQestId = 0;\r
+ }\r
+ }\r
\r
//\r
// First process the Action field in USER_INPUT.\r
//\r
if (UserInput->Action != 0) {\r
Status = ProcessAction (UserInput->Action, UserInput->DefaultId);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- //\r
- // Clear the highlight info.\r
- //\r
gCurrentSelection->Statement = NULL;\r
-\r
- if (UserInput->SelectedStatement != NULL) {\r
- Statement = GetBrowserStatement(UserInput->SelectedStatement);\r
- ASSERT (Statement != NULL);\r
- //\r
- // Save the current highlight menu in the menu history data.\r
- // which will be used when later browse back to this form.\r
- //\r
- gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;\r
- //\r
- // For statement like text, actio, it not has question id.\r
- // So use FakeQuestionId to save the question.\r
- //\r
- if (gCurrentSelection->CurrentMenu->QuestionId == 0) {\r
- mCurFakeQestId = Statement->FakeQuestionId;\r
- } else {\r
- mCurFakeQestId = 0;\r
- }\r
- }\r
} else {\r
- Statement = GetBrowserStatement(UserInput->SelectedStatement);\r
ASSERT (Statement != NULL);\r
-\r
gCurrentSelection->Statement = Statement;\r
-\r
- if (ChangeHighlight) {\r
- //\r
- // This question is the current user select one,record it and later\r
- // show it as the highlight question.\r
- //\r
- gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;\r
- //\r
- // For statement like text, actio, it not has question id.\r
- // So use FakeQuestionId to save the question.\r
- //\r
- if (gCurrentSelection->CurrentMenu->QuestionId == 0) {\r
- mCurFakeQestId = Statement->FakeQuestionId;\r
- } else {\r
- mCurFakeQestId = 0;\r
- }\r
- }\r
-\r
switch (Statement->Operand) {\r
case EFI_IFR_REF_OP:\r
Status = ProcessGotoOpCode(Statement, gCurrentSelection);\r
break;\r
- \r
+\r
case EFI_IFR_ACTION_OP:\r
//\r
// Process the Config string <ConfigResp>\r
//\r
Status = ProcessQuestionConfig (gCurrentSelection, Statement);\r
break;\r
- \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);\r
+ Status = ExtractDefault (gCurrentSelection->FormSet, NULL, Statement->DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE, FALSE);\r
+ UpdateStatementStatus (gCurrentSelection->FormSet, NULL, FormSetLevel);\r
break;\r
\r
default:\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
EFI_STATUS Status;\r
USER_INPUT UserInput;\r
FORM_ENTRY_INFO *CurrentMenu;\r
- BOOLEAN ChangeHighlight;\r
\r
ZeroMem (&UserInput, sizeof (USER_INPUT));\r
\r
gCurrentSelection->FormId, gCurrentSelection->QuestionId);\r
ASSERT (CurrentMenu != NULL);\r
}\r
- gCurrentSelection->CurrentMenu = CurrentMenu;\r
\r
//\r
- // Find currrent highlight statement.\r
+ // Back up the form view history data for this form.\r
//\r
+ UiCopyMenuList(&gCurrentSelection->Form->FormViewListHead, &mPrivateData.FormBrowserEx2.FormViewHistoryHead);\r
+\r
+ gCurrentSelection->CurrentMenu = CurrentMenu;\r
+\r
if (gCurrentSelection->QuestionId == 0) {\r
//\r
// Highlight not specified, fetch it from cached menu\r
gCurrentSelection->QuestionId = CurrentMenu->QuestionId;\r
}\r
\r
- //\r
- // Evaluate all the Expressions in this Form\r
- //\r
Status = EvaluateFormExpressions (gCurrentSelection->FormSet, gCurrentSelection->Form);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
\r
UpdateDisplayFormData ();\r
\r
- //\r
- // Three possible status maybe return.\r
- //\r
- // EFI_INVALID_PARAMETER: The input dimension info is not valid.\r
- // EFI_NOT_FOUND: The input value for oneof/orderedlist opcode is not valid\r
- // and an valid value has return.\r
- // EFI_SUCCESS: Success shows form and get user input in UserInput paramenter.\r
- //\r
+ ASSERT (gDisplayFormData.BrowserStatus == BROWSER_SUCCESS);\r
Status = mFormDisplay->FormDisplay (&gDisplayFormData, &UserInput);\r
- if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {\r
+ if (EFI_ERROR (Status)) {\r
FreeDisplayFormData();\r
return Status;\r
}\r
\r
- //\r
- // If status is EFI_SUCCESS, means user has change the highlight menu and new user input return.\r
- // in this case, browser need to change the highlight menu.\r
- // If status is EFI_NOT_FOUND, means the input DisplayFormData has error for oneof/orderedlist \r
- // opcode and new valid value has return, browser core need to adjust\r
- // value for this opcode and shows this form again.\r
- //\r
- ChangeHighlight = (Status == EFI_SUCCESS ? TRUE :FALSE);\r
-\r
- Status = ProcessUserInput (&UserInput, ChangeHighlight);\r
-\r
+ Status = ProcessUserInput (&UserInput);\r
FreeDisplayFormData();\r
-\r
return Status;\r
}\r
\r
return FALSE;\r
}\r
\r
-/**\r
- Check whether the storage data for current form set is changed.\r
-\r
- @param FormSet FormSet data structure.\r
-\r
- @retval TRUE Data is changed.\r
- @retval FALSE Data is not changed.\r
-**/\r
-BOOLEAN \r
-IsStorageDataChangedForFormSet (\r
- IN FORM_BROWSER_FORMSET *FormSet\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- FORMSET_STORAGE *Storage;\r
- BROWSER_STORAGE *BrowserStorage;\r
- CHAR16 *ConfigRespNew;\r
- CHAR16 *ConfigRespOld;\r
- BOOLEAN RetVal;\r
-\r
- RetVal = FALSE;\r
- ConfigRespNew = NULL;\r
- ConfigRespOld = NULL;\r
-\r
- //\r
- // Request current settings from Configuration Driver\r
- //\r
- Link = GetFirstNode (&FormSet->StorageListHead);\r
- while (!IsNull (&FormSet->StorageListHead, Link)) {\r
- Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
- Link = GetNextNode (&FormSet->StorageListHead, Link);\r
-\r
- BrowserStorage = Storage->BrowserStorage;\r
-\r
- if (BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
- continue;\r
- }\r
-\r
- if (Storage->ElementCount == 0) {\r
- continue;\r
- }\r
-\r
- StorageToConfigResp (BrowserStorage, &ConfigRespNew, Storage->ConfigRequest, TRUE);\r
- StorageToConfigResp (BrowserStorage, &ConfigRespOld, Storage->ConfigRequest, FALSE);\r
- ASSERT (ConfigRespNew != NULL && ConfigRespOld != NULL);\r
-\r
- if (StrCmp (ConfigRespNew, ConfigRespOld) != 0) {\r
- RetVal = TRUE;\r
- }\r
-\r
- FreePool (ConfigRespNew);\r
- ConfigRespNew = NULL;\r
-\r
- FreePool (ConfigRespOld);\r
- ConfigRespOld = NULL;\r
-\r
- if (RetVal) {\r
- break;\r
- }\r
- }\r
-\r
- return RetVal;\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 SettingLevel Input Settting level, if it is FormLevel, just exit current form. \r
+ @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.\r
else, we need to exit current formset.\r
- \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 BROWSER_SETTING_SCOPE SettingLevel\r
+ IN BROWSER_SETTING_SCOPE SettingLevel\r
)\r
{\r
FORM_ENTRY_INFO *CurrentMenu;\r
FORM_ENTRY_INFO *ParentMenu;\r
BROWSER_SETTING_SCOPE Scope;\r
- \r
+\r
CurrentMenu = Selection->CurrentMenu;\r
- ParentMenu = NULL;\r
Scope = FormSetLevel;\r
\r
- if (CurrentMenu != NULL && (ParentMenu = UiFindParentMenu(CurrentMenu)) != NULL) {\r
- //\r
- // we have a parent, so go to the parent menu\r
- //\r
- if (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
- if (SettingLevel == FormSetLevel) {\r
- //\r
- // Find a menu which has different formset guid with current.\r
- //\r
- while (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
- CurrentMenu = ParentMenu;\r
- if ((ParentMenu = UiFindParentMenu(CurrentMenu)) == NULL) {\r
- break;\r
- }\r
- }\r
+ ParentMenu = UiFindParentMenu(CurrentMenu, SettingLevel);\r
+ while (ParentMenu != NULL && !ValidateHiiHandle(ParentMenu->HiiHandle)) {\r
+ ParentMenu = UiFindParentMenu(ParentMenu, SettingLevel);\r
+ }\r
\r
- if (ParentMenu != NULL) {\r
- Scope = FormSetLevel;\r
- }\r
- } else {\r
- Scope = FormLevel;\r
- }\r
+ if (ParentMenu != NULL) {\r
+ if (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {\r
+ Scope = FormLevel;\r
} else {\r
Scope = FormSetLevel;\r
}\r
//\r
if ((gBrowserSettingScope == FormLevel && IsNvUpdateRequiredForForm (Selection->Form)) ||\r
(gBrowserSettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet(Selection->FormSet) && Scope == FormSetLevel)) {\r
- if (!ProcessChangedData(Selection, Scope)) {\r
+ if (!ProcessChangedData(Selection, gBrowserSettingScope)) {\r
return FALSE;\r
}\r
}\r
return TRUE;\r
}\r
\r
+/**\r
+ Reconnect the controller.\r
+\r
+ @param DriverHandle The controller handle which need to be reconnect.\r
+\r
+ @retval TRUE do the reconnect behavior success.\r
+ @retval FALSE do the reconnect behavior failed.\r
+\r
+**/\r
+BOOLEAN\r
+ReconnectController (\r
+ IN EFI_HANDLE DriverHandle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->DisconnectController(DriverHandle, NULL, NULL);\r
+ if (!EFI_ERROR (Status)) {\r
+ Status = gBS->ConnectController(DriverHandle, NULL, NULL, TRUE);\r
+ }\r
+\r
+ return Status == EFI_SUCCESS;\r
+}\r
+\r
/**\r
Call the call back function for the question and process the return action.\r
\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_FORMSET *FormSet,\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
BROWSER_SETTING_SCOPE SettingLevel;\r
EFI_IFR_TYPE_VALUE BackUpValue;\r
UINT8 *BackUpBuffer;\r
+ CHAR16 *NewString;\r
\r
ConfigAccess = FormSet->ConfigAccess;\r
SubmitFormIsRequired = FALSE;\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
//\r
if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
- BackUpBuffer = AllocateCopyPool(Statement->StorageWidth + sizeof(CHAR16), Statement->BufferValue);\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
&ActionRequest\r
);\r
if (!EFI_ERROR (Status)) {\r
+ //\r
+ // Need to sync the value between Statement->HiiValue->Value and Statement->BufferValue\r
+ //\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
+ FreePool (NewString);\r
+ }\r
+\r
//\r
// Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.\r
//\r
- if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+ switch (Action) {\r
+ case EFI_BROWSER_ACTION_CHANGED:\r
switch (ActionRequest) {\r
case EFI_BROWSER_ACTION_REQUEST_RESET:\r
DiscardFormIsRequired = TRUE;\r
- gResetRequired = TRUE;\r
+ gResetRequiredFormLevel = TRUE;\r
+ gResetRequiredSystemLevel = TRUE;\r
NeedExit = TRUE;\r
break;\r
\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
+ break;\r
\r
- //\r
- // According the spec, return value from call back of "changing" and \r
- // "retrieve" should update to the question's temp buffer.\r
- //\r
- if (Action == EFI_BROWSER_ACTION_CHANGING || Action == EFI_BROWSER_ACTION_RETRIEVE) {\r
+ 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
+ break;\r
+\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
} else {\r
//\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
+ // 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 && Status == EFI_UNSUPPORTED) {\r
if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) {\r
- CopyMem (Statement->BufferValue, BackUpBuffer, Statement->StorageWidth + sizeof(CHAR16));\r
+ CopyMem (Statement->BufferValue, BackUpBuffer, Statement->StorageWidth);\r
} else {\r
CopyMem (&HiiValue->Value, &BackUpValue, sizeof (EFI_IFR_TYPE_VALUE));\r
}\r
\r
- SetQuestionValue(FormSet, Form, Statement, GetSetValueWithEditBuffer);\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
\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 && Status != EFI_UNSUPPORTED) || \r
- Action == EFI_BROWSER_ACTION_RETRIEVE) {\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 (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
\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
+ 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
+\r
+ if (((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) || ConfigAccess == NULL) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
//\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
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
+ FreePool (NewString);\r
+ }\r
+\r
return Status;\r
}\r
\r
return Status;\r
}\r
\r
- if ((Selection->Handle != mCurrentHiiHandle) ||\r
- (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid))) {\r
- gFinishRetrieveCall = FALSE;\r
- }\r
-\r
//\r
// Initialize current settings of Questions in this FormSet\r
//\r
mCurFakeQestId = 0;\r
\r
do {\r
+\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
if (Selection->Form->SuppressExpression != NULL) {\r
if (EvaluateExpressionList(Selection->Form->SuppressExpression, TRUE, Selection->FormSet, Selection->Form) == ExpressSuppress) {\r
//\r
- // Form is suppressed. \r
+ // Form is suppressed.\r
//\r
- gBrowserStatus = BROWSER_FORM_SUPPRESS;\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
+ if (((Selection->Handle != mCurrentHiiHandle) ||\r
(!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||\r
(Selection->FormId != mCurrentFormId))) {\r
+ //\r
+ // Update Retrieve flag.\r
+ //\r
+ mFinishRetrieveCall = FALSE;\r
+\r
//\r
// Keep current form information\r
//\r
CopyGuid (&mCurrentFormSetGuid, &Selection->FormSetGuid);\r
mCurrentFormId = Selection->FormId;\r
\r
- Status = ProcessCallBackFunction (Selection, gCurrentSelection->FormSet, Selection->Form, 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
- // 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
- // Finish call RETRIEVE callback for this formset.\r
- //\r
- gFinishRetrieveCall = TRUE;\r
+ if (!mFinishRetrieveCall) {\r
+ //\r
+ // Finish call RETRIEVE callback for this form.\r
+ //\r
+ mFinishRetrieveCall = TRUE;\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
+ 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
//\r
Statement = Selection->Statement;\r
if (Statement != NULL) {\r
- if ((ConfigAccess != NULL) && \r
- ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && \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, Selection->FormSet, Selection->Form, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);\r
if (Statement->Operand == EFI_IFR_REF_OP) {\r
if (!EFI_ERROR (Status)) {\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
+\r
+ if (!EFI_ERROR (Status) &&\r
+ (Statement->Operand != EFI_IFR_REF_OP) &&\r
+ ((Statement->Storage == NULL) || (Statement->Storage != NULL && Statement->ValueChanged))) {\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
+ 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
- } else if (Statement->Operand != EFI_IFR_PASSWORD_OP) {\r
- SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);\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