From b18e7050464b0809e0c8366219447e87c9124551 Mon Sep 17 00:00:00 2001 From: ydong10 Date: Tue, 31 May 2011 00:59:15 +0000 Subject: [PATCH] Add new call back return value; also add some sample code to use it. Signed-off-by: ydong10 Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11713 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/DriverSampleDxe/DriverSample.c | 32 +- .../Universal/DriverSampleDxe/Vfr.vfr | 29 +- .../Universal/DriverSampleDxe/VfrStrings.uni | Bin 51254 -> 52710 bytes .../Universal/SetupBrowserDxe/Expression.c | 4 +- .../Universal/SetupBrowserDxe/IfrParse.c | 87 +++- .../Universal/SetupBrowserDxe/InputHandler.c | 14 +- .../Universal/SetupBrowserDxe/Presentation.c | 489 ++++++++++++------ .../SetupBrowserDxe/ProcessOptions.c | 10 +- .../Universal/SetupBrowserDxe/Setup.c | 478 +++++++++++++---- .../Universal/SetupBrowserDxe/Setup.h | 120 ++++- MdeModulePkg/Universal/SetupBrowserDxe/Ui.c | 150 +----- MdeModulePkg/Universal/SetupBrowserDxe/Ui.h | 10 +- 12 files changed, 990 insertions(+), 433 deletions(-) diff --git a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c index 9751242fd2..9f78db2854 100644 --- a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c +++ b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c @@ -2,7 +2,7 @@ This is an example of how a driver might export data to the HII protocol to be later utilized by the Setup Protocol -Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -587,7 +587,7 @@ AppendAltCfgString ( StringPtr += StrLen (L"&VALUE="); // - // Get Width + // Get Value // Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length); if (EFI_ERROR (Status)) { @@ -1501,6 +1501,34 @@ DriverCallback ( *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; break; + case 0x1241: + // + // User press "Submit current form and Exit now", request Browser to submit current form and exit + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT; + break; + + case 0x1242: + // + // User press "Discard current form now", request Browser to discard the uncommitted data. + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD; + break; + + case 0x1243: + // + // User press "Submit current form now", request Browser to save the uncommitted data. + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; + break; + + case 0x1244: + // + // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit. + // + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT; + break; + case 0x2000: // // Only used to update the state. diff --git a/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr b/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr index fce22fef2f..26d29e3813 100644 --- a/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr +++ b/MdeModulePkg/Universal/DriverSampleDxe/Vfr.vfr @@ -2,7 +2,7 @@ // // Sample Setup formset. // -// Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+// Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
// This program and the accompanying materials // are licensed and made available under the terms and conditions of the BSD License // which accompanies this distribution. The full text of the license may be found at @@ -141,6 +141,19 @@ formset flags = INTERACTIVE, key = 0x1238; + text + help = STRING_TOKEN(STR_SAVE_CURRENT), + text = STRING_TOKEN(STR_SAVE_CURRENT), + text = STRING_TOKEN(STR_SAVE_CURRENT), + flags = INTERACTIVE, + key = 0x1243; + + text + help = STRING_TOKEN(STR_DISCARD_CURRENT_AND_EXIT), + text = STRING_TOKEN(STR_DISCARD_CURRENT_AND_EXIT), + text = STRING_TOKEN(STR_DISCARD_CURRENT_AND_EXIT), + flags = INTERACTIVE, + key = 0x1244; // // Define oneof (EFI_IFR_ONE_OF) // @@ -530,6 +543,20 @@ formset enddate; + text + help = STRING_TOKEN(STR_SAVE_CURRENT_AND_EXIT), + text = STRING_TOKEN(STR_SAVE_CURRENT_AND_EXIT), + text = STRING_TOKEN(STR_SAVE_CURRENT_AND_EXIT), + flags = INTERACTIVE, + key = 0x1241; + + text + help = STRING_TOKEN(STR_DISCARD_CURRENT), + text = STRING_TOKEN(STR_DISCARD_CURRENT), + text = STRING_TOKEN(STR_DISCARD_CURRENT), + flags = INTERACTIVE, + key = 0x1242; + time hour varid = Time.Hours, // Note that it is a member of NULL, so the RTC will be the system resource to retrieve and save from prompt = STRING_TOKEN(STR_TIME_PROMPT), help = STRING_TOKEN(STR_TIME_HELP), diff --git a/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni b/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni index 1901fd8d2e010d9d43e4c7a31b59b9f261503551..8bd34469a204012b5510150d72d7cfb6facff7f4 100644 GIT binary patch delta 530 zcmdlsf%(~N<_#;_q+J+18G;#{85|jc7+e_Qfvivf`YjLkQ5HjtqWa|GF|n07D>Ta-o2xF_HcR`Zy8jb5Ka6 yPCnhz4)U`l8G0EifZ +Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -2138,7 +2138,7 @@ EvaluateExpression ( for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) { StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2); } - Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue); + Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, TRUE); FreePool (NameValue); if (!EFI_ERROR (Status)) { Data1.Value.b = TRUE; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c index ef862e4e98..564a246a1b 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c @@ -1,7 +1,7 @@ /** @file Parser for IFR binary encoding. -Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -357,6 +357,7 @@ InitializeConfigHdr ( @param FormSet Pointer of the current FormSet. @param Question The Question to be initialized. + @param Form Pointer of the current form. @retval EFI_SUCCESS Function success. @retval EFI_INVALID_PARAMETER No storage associated with the Question. @@ -365,7 +366,8 @@ InitializeConfigHdr ( EFI_STATUS InitializeRequestElement ( IN OUT FORM_BROWSER_FORMSET *FormSet, - IN OUT FORM_BROWSER_STATEMENT *Question + IN OUT FORM_BROWSER_STATEMENT *Question, + IN OUT FORM_BROWSER_FORM *Form ) { FORMSET_STORAGE *Storage; @@ -373,6 +375,9 @@ InitializeRequestElement ( UINTN StringSize; CHAR16 *NewStr; CHAR16 RequestElement[30]; + LIST_ENTRY *Link; + BOOLEAN Find; + FORM_BROWSER_CONFIG_REQUEST *ConfigInfo; Storage = Question->Storage; if (Storage == NULL) { @@ -433,6 +438,53 @@ InitializeRequestElement ( Storage->ElementCount++; Storage->SpareStrLen -= StrLen; + // + // Update the Config Request info saved in the form. + // + ConfigInfo = NULL; + Find = FALSE; + Link = GetFirstNode (&Form->ConfigRequestHead); + while (!IsNull (&Form->ConfigRequestHead, Link)) { + ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link); + + if (ConfigInfo != NULL && ConfigInfo->Storage->VarStoreId == Storage->VarStoreId) { + Find = TRUE; + break; + } + + Link = GetNextNode (&Form->ConfigRequestHead, Link); + } + + if (!Find) { + ConfigInfo = AllocateZeroPool(sizeof (FORM_BROWSER_CONFIG_REQUEST)); + ConfigInfo->Signature = FORM_BROWSER_CONFIG_REQUEST_SIGNATURE; + ConfigInfo->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigHdr), Storage->ConfigHdr); + ConfigInfo->SpareStrLen = 0; + ConfigInfo->Storage = Storage; + InsertTailList(&Form->ConfigRequestHead, &ConfigInfo->Link); + } + + // + // Append to + // + if (StrLen > ConfigInfo->SpareStrLen) { + // + // Old String buffer is not sufficient for RequestElement, allocate a new one + // + StringSize = (ConfigInfo->ConfigRequest != NULL) ? StrSize (ConfigInfo->ConfigRequest) : sizeof (CHAR16); + NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16)); + ASSERT (NewStr != NULL); + if (ConfigInfo->ConfigRequest != NULL) { + CopyMem (NewStr, ConfigInfo->ConfigRequest, StringSize); + FreePool (ConfigInfo->ConfigRequest); + } + ConfigInfo->ConfigRequest = NewStr; + ConfigInfo->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL; + } + + StrCat (ConfigInfo->ConfigRequest, RequestElement); + ConfigInfo->ElementCount++; + ConfigInfo->SpareStrLen -= StrLen; return EFI_SUCCESS; } @@ -632,6 +684,7 @@ DestroyForm ( LIST_ENTRY *Link; FORM_EXPRESSION *Expression; FORM_BROWSER_STATEMENT *Statement; + FORM_BROWSER_CONFIG_REQUEST *ConfigInfo; // // Free Form Expressions @@ -655,6 +708,18 @@ DestroyForm ( DestroyStatement (FormSet, Statement); } + // + // Free ConfigRequest string. + // + while (!IsListEmpty (&Form->ConfigRequestHead)) { + Link = GetFirstNode (&Form->ConfigRequestHead); + ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link); + RemoveEntryList (&ConfigInfo->Link); + + FreePool (ConfigInfo->ConfigRequest); + FreePool (ConfigInfo); + } + // // Free this Form // @@ -1273,8 +1338,10 @@ ParseOpCodes ( CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE; InitializeListHead (&CurrentForm->ExpressionListHead); InitializeListHead (&CurrentForm->StatementListHead); + InitializeListHead (&CurrentForm->ConfigRequestHead); CurrentForm->FormType = STANDARD_MAP_FORM_TYPE; + CurrentForm->NvUpdateRequired = FALSE; CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16)); CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID)); @@ -1305,8 +1372,10 @@ ParseOpCodes ( CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM)); ASSERT (CurrentForm != NULL); CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE; + CurrentForm->NvUpdateRequired = FALSE; InitializeListHead (&CurrentForm->ExpressionListHead); InitializeListHead (&CurrentForm->StatementListHead); + InitializeListHead (&CurrentForm->ConfigRequestHead); CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16)); MapMethod = (EFI_IFR_FORM_MAP_METHOD *) (OpCodeData + sizeof (EFI_IFR_FORM_MAP)); @@ -1538,7 +1607,7 @@ ParseOpCodes ( break; } - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); if ((Operand == EFI_IFR_ONE_OF_OP) && Scope != 0) { SuppressForOption = TRUE; @@ -1568,7 +1637,7 @@ ParseOpCodes ( CurrentStatement->StorageWidth = (UINT16) sizeof (BOOLEAN); CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN; - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); break; @@ -1589,7 +1658,7 @@ ParseOpCodes ( CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth + sizeof (CHAR16)); CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle); - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); break; case EFI_IFR_PASSWORD_OP: @@ -1608,7 +1677,7 @@ ParseOpCodes ( CurrentStatement->BufferValue = AllocateZeroPool ((CurrentStatement->StorageWidth + sizeof (CHAR16))); CurrentStatement->HiiValue.Value.string = NewString ((CHAR16*) CurrentStatement->BufferValue, FormSet->HiiHandle); - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); break; case EFI_IFR_DATE_OP: @@ -1621,7 +1690,7 @@ ParseOpCodes ( if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) { CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_DATE); - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); } else { // // Don't assign storage for RTC type of date/time @@ -1641,7 +1710,7 @@ ParseOpCodes ( if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) { CurrentStatement->StorageWidth = (UINT16) sizeof (EFI_HII_TIME); - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); } else { // // Don't assign storage for RTC type of date/time @@ -1740,7 +1809,7 @@ ParseOpCodes ( CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth); CurrentStatement->ValueType = CurrentOption->Value.Type; - InitializeRequestElement (FormSet, CurrentStatement); + InitializeRequestElement (FormSet, CurrentStatement, CurrentForm); } break; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c b/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c index 360a6d75ec..eee8eed244 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c @@ -637,7 +637,7 @@ EnterCarriageReturn: // // NV flag is unnecessary for RTC type of Date/Time // - UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); + UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); } } @@ -653,7 +653,7 @@ EnterCarriageReturn: // Remove a character // EditValue = PreviousNumber[Count - 1]; - UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, FALSE); + UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE); Count--; Column--; PrintAt (Column, Row, L" "); @@ -670,12 +670,12 @@ EnterCarriageReturn: } else if ((Key.UnicodeChar >= L'a') && (Key.UnicodeChar <= L'f')) { Digital = (UINT8) (Key.UnicodeChar - L'a' + 0x0A); } else { - UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE); + UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE); break; } } else { if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') { - UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE); + UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE); break; } } @@ -704,12 +704,12 @@ EnterCarriageReturn: } if (EditValue > Maximum) { - UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, TRUE); + UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE); ASSERT (Count < sizeof (PreviousNumber) / sizeof (PreviousNumber[0])); EditValue = PreviousNumber[Count]; break; } else { - UpdateStatusBar (INPUT_ERROR, Question->QuestionFlags, FALSE); + UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE); } Count++; @@ -1183,7 +1183,7 @@ TheKey: GetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); } else { SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); - UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); + UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); } return Status; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c index 8dc1651950..94ba239950 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c @@ -847,6 +847,327 @@ FormUpdateNotify ( return EFI_SUCCESS; } +/** + check whether the formset need to update the NV. + + @param FormSet FormSet data structure. + + @retval TRUE Need to update the NV. + @retval FALSE No need to update the NV. +**/ +BOOLEAN +IsNvUpdateRequired ( + IN FORM_BROWSER_FORMSET *FormSet + ) +{ + LIST_ENTRY *Link; + FORM_BROWSER_FORM *Form; + + Link = GetFirstNode (&FormSet->FormListHead); + while (!IsNull (&FormSet->FormListHead, Link)) { + Form = FORM_BROWSER_FORM_FROM_LINK (Link); + + if (Form->NvUpdateRequired ) { + return TRUE; + } + + Link = GetNextNode (&FormSet->FormListHead, Link); + } + + return FALSE; +} + +/** + check whether the formset need to update the NV. + + @param FormSet FormSet data structure. + @param SetValue Whether set new value or clear old value. + +**/ +VOID +UpdateNvInfoInForm ( + IN FORM_BROWSER_FORMSET *FormSet, + IN BOOLEAN SetValue + ) +{ + LIST_ENTRY *Link; + FORM_BROWSER_FORM *Form; + + Link = GetFirstNode (&FormSet->FormListHead); + while (!IsNull (&FormSet->FormListHead, Link)) { + Form = FORM_BROWSER_FORM_FROM_LINK (Link); + + Form->NvUpdateRequired = SetValue; + + Link = GetNextNode (&FormSet->FormListHead, Link); + } +} +/** + Find menu which will show next time. + + @param Selection On input, Selection tell setup browser the information + about the Selection, form and formset to be displayed. + On output, Selection return the screen item that is selected + by user. + @param Repaint Whether need to repaint the menu. + @param NewLine Whether need to show at new line. + + @retval TRUE Need return. + @retval FALSE No need to return. +**/ +BOOLEAN +FindNextMenu ( + IN OUT UI_MENU_SELECTION *Selection, + IN BOOLEAN *Repaint, + IN BOOLEAN *NewLine + ) +{ + UI_MENU_LIST *CurrentMenu; + CHAR16 YesResponse; + CHAR16 NoResponse; + EFI_INPUT_KEY Key; + EFI_STATUS Status; + + CurrentMenu = Selection->CurrentMenu; + + if (CurrentMenu != NULL && CurrentMenu->Parent != NULL) { + // + // we have a parent, so go to the parent menu + // + if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) { + // + // The parent menu and current menu are in the same formset + // + Selection->Action = UI_ACTION_REFRESH_FORM; + } else { + Selection->Action = UI_ACTION_REFRESH_FORMSET; + } + Selection->Statement = NULL; + + Selection->FormId = CurrentMenu->Parent->FormId; + Selection->QuestionId = CurrentMenu->Parent->QuestionId; + + // + // Clear highlight record for this menu + // + CurrentMenu->QuestionId = 0; + return FALSE; + } + + if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) { + // + // We never exit FrontPage, so skip the ESC + // + Selection->Action = UI_ACTION_NONE; + return FALSE; + } + + // + // We are going to leave current FormSet, so check uncommited data in this FormSet + // + if (IsNvUpdateRequired(Selection->FormSet)) { + Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); + + YesResponse = gYesResponse[0]; + NoResponse = gNoResponse[0]; + + // + // If NV flag is up, prompt user + // + do { + CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString); + } while + ( + (Key.ScanCode != SCAN_ESC) && + ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) && + ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET)) + ); + + if (Key.ScanCode == SCAN_ESC) { + // + // User hits the ESC key + // + if (Repaint != NULL) { + *Repaint = TRUE; + } + + if (NewLine != NULL) { + *NewLine = TRUE; + } + + Selection->Action = UI_ACTION_NONE; + return FALSE; + } + + // + // If the user hits the YesResponse key + // + if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) { + Status = SubmitForm (Selection->FormSet, Selection->Form, FALSE); + } + } + + Selection->Statement = NULL; + CurrentMenu->QuestionId = 0; + + Selection->Action = UI_ACTION_EXIT; + return TRUE; +} + +/** + Call the call back function for the question and process the return action. + + @param Selection On input, Selection tell setup browser the information + about the Selection, form and formset to be displayed. + On output, Selection return the screen item that is selected + by user. + @param Question The Question which need to call. + @param Action The action request. + @param SkipSaveOrDiscard Whether skip save or discard action. + + @retval EFI_SUCCESS The call back function excutes successfully. + @return Other value if the call back function failed to excute. +**/ +EFI_STATUS +ProcessCallBackFunction ( + IN OUT UI_MENU_SELECTION *Selection, + IN FORM_BROWSER_STATEMENT *Question, + IN EFI_BROWSER_ACTION Action, + IN BOOLEAN SkipSaveOrDiscard + ) +{ + EFI_STATUS Status; + EFI_BROWSER_ACTION_REQUEST ActionRequest; + EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; + EFI_HII_VALUE *HiiValue; + EFI_IFR_TYPE_VALUE *TypeValue; + FORM_BROWSER_STATEMENT *Statement; + BOOLEAN SubmitFormIsRequired; + BOOLEAN SingleForm; + BOOLEAN DiscardFormIsRequired; + BOOLEAN NeedExit; + LIST_ENTRY *Link; + + ConfigAccess = Selection->FormSet->ConfigAccess; + SubmitFormIsRequired = FALSE; + SingleForm = FALSE; + DiscardFormIsRequired = FALSE; + NeedExit = FALSE; + Status = EFI_SUCCESS; + ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; + + if (ConfigAccess == NULL) { + return EFI_SUCCESS; + } + + Link = GetFirstNode (&Selection->Form->StatementListHead); + while (!IsNull (&Selection->Form->StatementListHead, Link)) { + Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link); + Link = GetNextNode (&Selection->Form->StatementListHead, Link); + + // + // if Question != NULL, only process the question. Else, process all question in this form. + // + if ((Question != NULL) && (Statement != Question)) { + continue; + } + + if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) { + continue; + } + + // + // Check whether Statement is disabled. + // + if (Statement->DisableExpression != NULL) { + Status = EvaluateExpression (Selection->FormSet, Selection->Form, Statement->DisableExpression); + if (!EFI_ERROR (Status) && + (Statement->DisableExpression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && + (Statement->DisableExpression->Result.Value.b)) { + continue; + } + } + + HiiValue = &Statement->HiiValue; + TypeValue = &HiiValue->Value; + if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) { + // + // For OrderedList, passing in the value buffer to Callback() + // + TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue; + } + + ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; + Status = ConfigAccess->Callback ( + ConfigAccess, + Action, + Statement->QuestionId, + HiiValue->Type, + TypeValue, + &ActionRequest + ); + if (!EFI_ERROR (Status)) { + switch (ActionRequest) { + case EFI_BROWSER_ACTION_REQUEST_RESET: + gResetRequired = TRUE; + break; + + case EFI_BROWSER_ACTION_REQUEST_SUBMIT: + SubmitFormIsRequired = TRUE; + break; + + case EFI_BROWSER_ACTION_REQUEST_EXIT: + Selection->Action = UI_ACTION_EXIT; + break; + + case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT: + SubmitFormIsRequired = TRUE; + SingleForm = TRUE; + NeedExit = TRUE; + break; + + case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT: + DiscardFormIsRequired = TRUE; + SingleForm = TRUE; + NeedExit = TRUE; + break; + + case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY: + SubmitFormIsRequired = TRUE; + SingleForm = TRUE; + break; + + case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD: + DiscardFormIsRequired = TRUE; + SingleForm = TRUE; + break; + + default: + break; + } + } else if (Status == EFI_UNSUPPORTED) { + // + // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it. + // + Status = EFI_SUCCESS; + } + } + + if (SubmitFormIsRequired && !SkipSaveOrDiscard) { + SubmitForm (Selection->FormSet, Selection->Form, SingleForm); + } + + if (DiscardFormIsRequired && !SkipSaveOrDiscard) { + DiscardForm (Selection->FormSet, Selection->Form, SingleForm); + } + + if (NeedExit) { + FindNextMenu (Selection, NULL, NULL); + } + + return Status; +} + /** The worker function that send the displays to the screen. On output, the selection made by user is returned. @@ -867,15 +1188,11 @@ SetupBrowser ( { EFI_STATUS Status; LIST_ENTRY *Link; - EFI_BROWSER_ACTION_REQUEST ActionRequest; EFI_HANDLE NotifyHandle; - EFI_HII_VALUE *HiiValue; - EFI_IFR_TYPE_VALUE *TypeValue; FORM_BROWSER_STATEMENT *Statement; EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; FORM_BROWSER_FORMSET *FormSet; EFI_INPUT_KEY Key; - BOOLEAN SubmitFormIsRequired; gMenuRefreshHead = NULL; gResetRequired = FALSE; @@ -974,69 +1291,11 @@ SetupBrowser ( CopyGuid (&mCurrentFormSetGuid, &Selection->FormSetGuid); mCurrentFormId = Selection->FormId; - // - // Go through each statement in this form - // - SubmitFormIsRequired = FALSE; - Link = GetFirstNode (&Selection->Form->StatementListHead); - while (!IsNull (&Selection->Form->StatementListHead, Link)) { - Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link); - Link = GetNextNode (&Selection->Form->StatementListHead, Link); - - if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) { - continue; - } - - // - // Check whether Statement is disabled. - // - if (Statement->DisableExpression != NULL) { - Status = EvaluateExpression (Selection->FormSet, Selection->Form, Statement->DisableExpression); - if (!EFI_ERROR (Status) && - (Statement->DisableExpression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && - (Statement->DisableExpression->Result.Value.b)) { - continue; - } - } - - ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; - Status = ConfigAccess->Callback ( - ConfigAccess, - EFI_BROWSER_ACTION_FORM_OPEN, - Statement->QuestionId, - EFI_IFR_TYPE_UNDEFINED, - NULL, - &ActionRequest - ); - - if (!EFI_ERROR (Status)) { - switch (ActionRequest) { - case EFI_BROWSER_ACTION_REQUEST_RESET: - gResetRequired = TRUE; - break; - - case EFI_BROWSER_ACTION_REQUEST_SUBMIT: - SubmitFormIsRequired = TRUE; - break; - - case EFI_BROWSER_ACTION_REQUEST_EXIT: - Selection->Action = UI_ACTION_EXIT; - gNvUpdateRequired = FALSE; - break; - - default: - break; - } - } else if (Status == EFI_UNSUPPORTED) { - // - // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it. - // - Status = EFI_SUCCESS; - } - } - if (SubmitFormIsRequired) { - SubmitForm (Selection->FormSet, Selection->Form); + Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_OPEN, FALSE); + if (EFI_ERROR (Status)) { + goto Done; } + // // EXIT requests to close form. // @@ -1107,45 +1366,8 @@ SetupBrowser ( ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) && (Statement->Operand != EFI_IFR_PASSWORD_OP)) { - ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; - - HiiValue = &Statement->HiiValue; - TypeValue = &HiiValue->Value; - if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) { - // - // For OrderedList, passing in the value buffer to Callback() - // - TypeValue = (EFI_IFR_TYPE_VALUE *) Statement->BufferValue; - } - - Status = ConfigAccess->Callback ( - ConfigAccess, - EFI_BROWSER_ACTION_CHANGING, - Statement->QuestionId, - HiiValue->Type, - TypeValue, - &ActionRequest - ); - - if (!EFI_ERROR (Status)) { - switch (ActionRequest) { - case EFI_BROWSER_ACTION_REQUEST_RESET: - gResetRequired = TRUE; - break; - - case EFI_BROWSER_ACTION_REQUEST_SUBMIT: - SubmitForm (Selection->FormSet, Selection->Form); - break; - - case EFI_BROWSER_ACTION_REQUEST_EXIT: - Selection->Action = UI_ACTION_EXIT; - gNvUpdateRequired = FALSE; - break; - - default: - break; - } - } else if (Status != EFI_UNSUPPORTED) { + Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE); + if ((EFI_ERROR (Status)) && (Status != EFI_UNSUPPORTED)) { // // Callback return error status other than EFI_UNSUPPORTED // @@ -1156,11 +1378,6 @@ SetupBrowser ( Selection->FormId = Selection->Form->FormId; Selection->QuestionId = 0; } - } else { - // - // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it. - // - Status = EFI_SUCCESS; } } @@ -1185,56 +1402,10 @@ SetupBrowser ( (Selection->Handle != mCurrentHiiHandle) || (!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) || (Selection->FormId != mCurrentFormId))) { - // - // Go through each statement in this form - // - SubmitFormIsRequired = FALSE; - Link = GetFirstNode (&Selection->Form->StatementListHead); - while (!IsNull (&Selection->Form->StatementListHead, Link)) { - Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link); - Link = GetNextNode (&Selection->Form->StatementListHead, Link); - - if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) { - continue; - } - ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; - Status = ConfigAccess->Callback ( - ConfigAccess, - EFI_BROWSER_ACTION_FORM_CLOSE, - Statement->QuestionId, - EFI_IFR_TYPE_UNDEFINED, - NULL, - &ActionRequest - ); - - if (!EFI_ERROR (Status)) { - switch (ActionRequest) { - case EFI_BROWSER_ACTION_REQUEST_RESET: - gResetRequired = TRUE; - break; - - case EFI_BROWSER_ACTION_REQUEST_SUBMIT: - SubmitFormIsRequired = TRUE; - break; - - case EFI_BROWSER_ACTION_REQUEST_EXIT: - Selection->Action = UI_ACTION_EXIT; - gNvUpdateRequired = FALSE; - break; - - default: - break; - } - } else if (Status == EFI_UNSUPPORTED) { - // - // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it. - // - Status = EFI_SUCCESS; - } - } - if (SubmitFormIsRequired) { - SubmitForm (Selection->FormSet, Selection->Form); + Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_CLOSE, FALSE); + if (EFI_ERROR (Status)) { + goto Done; } } } while (Selection->Action == UI_ACTION_REFRESH_FORM); diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c b/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c index 2e77522ca1..aa57fe437c 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c @@ -482,7 +482,7 @@ ProcessOptions ( SetArrayData (ValueArray, ValueType, Index2, 0); Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); - UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); + UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); FreePool (*OptionString); *OptionString = NULL; @@ -550,7 +550,7 @@ ProcessOptions ( !Option->SuppressExpression->Result.Value.b) { CopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE)); SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); - UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); + UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); break; } @@ -586,7 +586,7 @@ ProcessOptions ( Suppress = FALSE; CopyMem (QuestionValue, &OneOfOption->Value, sizeof (EFI_HII_VALUE)); SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); - UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); + UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND); break; } @@ -638,7 +638,7 @@ ProcessOptions ( // Save Question value // Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); - UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); + UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); } if (QuestionValue->Value.b) { @@ -751,7 +751,7 @@ ProcessOptions ( CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16)); SetQuestionValue (Selection->FormSet, Selection->Form, Question, TRUE); - UpdateStatusBar (NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); + UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE); } } diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c index 67a4aeb7ec..0eaa78321f 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c @@ -35,7 +35,6 @@ EFI_HII_HANDLE gFrontPageHandle; UINTN gClassOfVfr; UINTN gFunctionKeySetting; BOOLEAN gResetRequired; -BOOLEAN gNvUpdateRequired; EFI_HII_HANDLE gHiiHandle; UINT16 gDirection; EFI_SCREEN_DESCRIPTOR gScreenDimensions; @@ -294,7 +293,6 @@ SendForm ( } gOldFormSet = NULL; - gNvUpdateRequired = FALSE; do { FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET)); @@ -471,7 +469,7 @@ BrowserCallback ( // // Generate // - Status = StorageToConfigResp (Storage, &ConfigResp); + Status = StorageToConfigResp (Storage, &ConfigResp, FALSE); if (EFI_ERROR (Status)) { return Status; } @@ -810,6 +808,7 @@ GetValueByName ( @param Storage The NameValue Storage. @param Name The Name. @param Value The Value to set. + @param Edit Whether update editValue or Value. @retval EFI_SUCCESS Value found for given Name. @retval EFI_NOT_FOUND No such Name found in NameValue storage. @@ -819,22 +818,34 @@ EFI_STATUS SetValueByName ( IN FORMSET_STORAGE *Storage, IN CHAR16 *Name, - IN CHAR16 *Value + IN CHAR16 *Value, + IN BOOLEAN Edit ) { LIST_ENTRY *Link; NAME_VALUE_NODE *Node; + CHAR16 *Buffer; Link = GetFirstNode (&Storage->NameValueListHead); while (!IsNull (&Storage->NameValueListHead, Link)) { Node = NAME_VALUE_NODE_FROM_LINK (Link); if (StrCmp (Name, Node->Name) == 0) { - if (Node->EditValue != NULL) { - FreePool (Node->EditValue); + if (Edit) { + Buffer = Node->EditValue; + } else { + Buffer = Node->Value; + } + if (Buffer != NULL) { + FreePool (Buffer); + } + Buffer = AllocateCopyPool (StrSize (Value), Value); + ASSERT (Buffer != NULL); + if (Edit) { + Node->EditValue = Buffer; + } else { + Node->Value = Buffer; } - Node->EditValue = AllocateCopyPool (StrSize (Value), Value); - ASSERT (Node->EditValue != NULL); return EFI_SUCCESS; } @@ -848,8 +859,9 @@ SetValueByName ( /** Convert setting of Buffer Storage or NameValue Storage to . - @param Storage The Storage to be conveted. + @param Buffer The Storage to be conveted. @param ConfigResp The returned . + @param SingleForm Whether update data for single form or formset level. @retval EFI_SUCCESS Convert success. @retval EFI_INVALID_PARAMETER Incorrect storage type. @@ -857,22 +869,34 @@ SetValueByName ( **/ EFI_STATUS StorageToConfigResp ( - IN FORMSET_STORAGE *Storage, - IN CHAR16 **ConfigResp + IN VOID *Buffer, + IN CHAR16 **ConfigResp, + IN BOOLEAN SingleForm ) { EFI_STATUS Status; EFI_STRING Progress; LIST_ENTRY *Link; NAME_VALUE_NODE *Node; + CHAR16 *ConfigRequest; + FORMSET_STORAGE *Storage; + FORM_BROWSER_CONFIG_REQUEST *ConfigInfo; Status = EFI_SUCCESS; + if (SingleForm) { + ConfigInfo = (FORM_BROWSER_CONFIG_REQUEST *) Buffer; + Storage = ConfigInfo->Storage; + ConfigRequest = ConfigInfo->ConfigRequest; + } else { + Storage = (FORMSET_STORAGE *) Buffer; + ConfigRequest = Storage->ConfigRequest; + } switch (Storage->Type) { case EFI_HII_VARSTORE_BUFFER: Status = mHiiConfigRouting->BlockToConfig ( mHiiConfigRouting, - Storage->ConfigRequest, + ConfigRequest, Storage->EditBuffer, Storage->Size, ConfigResp, @@ -888,11 +912,12 @@ StorageToConfigResp ( while (!IsNull (&Storage->NameValueListHead, Link)) { Node = NAME_VALUE_NODE_FROM_LINK (Link); - NewStringCat (ConfigResp, L"&"); - NewStringCat (ConfigResp, Node->Name); - NewStringCat (ConfigResp, L"="); - NewStringCat (ConfigResp, Node->EditValue); - + if (StrStr (ConfigRequest, Node->Name) != NULL) { + NewStringCat (ConfigResp, L"&"); + NewStringCat (ConfigResp, Node->Name); + NewStringCat (ConfigResp, L"="); + NewStringCat (ConfigResp, Node->EditValue); + } Link = GetNextNode (&Storage->NameValueListHead, Link); } break; @@ -971,7 +996,7 @@ ConfigRespToStorage ( if (StrPtr != NULL) { *StrPtr = 0; } - SetValueByName (Storage, Name, Value); + SetValueByName (Storage, Name, Value, TRUE); } break; @@ -1322,7 +1347,7 @@ GetQuestionValue ( if (IsBufferStorage) { CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth); } else { - SetValueByName (Storage, Question->VariableName, Value); + SetValueByName (Storage, Question->VariableName, Value, TRUE); } FreePool (Result); @@ -1520,7 +1545,7 @@ SetQuestionValue ( } } - Status = SetValueByName (Storage, Question->VariableName, Value); + Status = SetValueByName (Storage, Question->VariableName, Value, TRUE); FreePool (Value); } @@ -1682,6 +1707,7 @@ ValidateQuestion ( Perform NoSubmit check for each Form in FormSet. @param FormSet FormSet data structure. + @param CurrentForm Current input form data structure. @retval EFI_SUCCESS Form validation pass. @retval other Form validation failed. @@ -1689,7 +1715,8 @@ ValidateQuestion ( **/ EFI_STATUS NoSubmitCheck ( - IN FORM_BROWSER_FORMSET *FormSet + IN FORM_BROWSER_FORMSET *FormSet, + IN FORM_BROWSER_FORM *CurrentForm ) { EFI_STATUS Status; @@ -1701,6 +1728,11 @@ NoSubmitCheck ( LinkForm = GetFirstNode (&FormSet->FormListHead); while (!IsNull (&FormSet->FormListHead, LinkForm)) { Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm); + LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm); + + if (CurrentForm != NULL && CurrentForm != Form) { + continue; + } Link = GetFirstNode (&Form->StatementListHead); while (!IsNull (&Form->StatementListHead, Link)) { @@ -1713,19 +1745,219 @@ NoSubmitCheck ( Link = GetNextNode (&Form->StatementListHead, Link); } - - LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm); } return EFI_SUCCESS; } +/** + Restore Storage's Edit copy to Shadow copy. + + @param Storage The Storage to be synchronized. + +**/ +VOID +RestoreStorage ( + IN FORMSET_STORAGE *Storage + ) +{ + LIST_ENTRY *Link; + NAME_VALUE_NODE *Node; + + switch (Storage->Type) { + case EFI_HII_VARSTORE_BUFFER: + CopyMem (Storage->EditBuffer, Storage->Buffer, Storage->Size); + break; + + case EFI_HII_VARSTORE_NAME_VALUE: + Link = GetFirstNode (&Storage->NameValueListHead); + while (!IsNull (&Storage->NameValueListHead, Link)) { + Node = NAME_VALUE_NODE_FROM_LINK (Link); + + if (Node->EditValue != NULL) { + FreePool (Node->EditValue); + } + Node->EditValue = AllocateCopyPool (StrSize (Node->Value), Node->Value); + ASSERT (Node->EditValue != NULL); + Link = GetNextNode (&Storage->NameValueListHead, Link); + } + break; + + case EFI_HII_VARSTORE_EFI_VARIABLE: + default: + break; + } +} /** - Submit a Form. + Fill storage's edit copy with settings requested from Configuration Driver. + + @param FormSet FormSet data structure. + @param ConfigInfo The config info related to this form. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +EFI_STATUS +FormRestoreStorage ( + IN FORM_BROWSER_FORMSET *FormSet, + IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo + ) +{ + EFI_STATUS Status; + EFI_STRING Progress; + EFI_STRING Result; + UINTN BufferSize; + LIST_ENTRY *Link; + NAME_VALUE_NODE *Node; + + Status = EFI_SUCCESS; + Result = NULL; + if (FormSet->ConfigAccess == NULL) { + return EFI_NOT_FOUND; + } + + if (ConfigInfo->ElementCount == 0) { + // + // Skip if there is no RequestElement + // + return EFI_SUCCESS; + } + + if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_BUFFER) { + BufferSize = ConfigInfo->Storage->Size; + Status = mHiiConfigRouting->BlockToConfig( + mHiiConfigRouting, + ConfigInfo->ConfigRequest, + ConfigInfo->Storage->Buffer, + BufferSize, + &Result, + &Progress + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = mHiiConfigRouting->ConfigToBlock ( + mHiiConfigRouting, + Result, + ConfigInfo->Storage->EditBuffer, + &BufferSize, + &Progress + ); + if (Result != NULL) { + FreePool (Result); + } + + if (EFI_ERROR (Status)) { + return Status; + } + } else if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) { + Link = GetFirstNode (&ConfigInfo->Storage->NameValueListHead); + while (!IsNull (&ConfigInfo->Storage->NameValueListHead, Link)) { + Node = NAME_VALUE_NODE_FROM_LINK (Link); + + if (StrStr (ConfigInfo->ConfigRequest, Node->Name) != NULL) { + if (Node->EditValue != NULL) { + FreePool (Node->EditValue); + } + Node->EditValue = AllocateCopyPool (StrSize (Node->Value), Node->Value); + ASSERT (Node->EditValue != NULL); + } + + Link = GetNextNode (&ConfigInfo->Storage->NameValueListHead, Link); + } + } + + return Status; +} + + +/** + Discard data for form level or formset level. @param FormSet FormSet data structure. @param Form Form data structure. + @param SingleForm Only discard single form or formset. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +EFI_STATUS +DiscardForm ( + IN FORM_BROWSER_FORMSET *FormSet, + IN FORM_BROWSER_FORM *Form, + IN BOOLEAN SingleForm + ) +{ + LIST_ENTRY *Link; + FORMSET_STORAGE *Storage; + FORM_BROWSER_CONFIG_REQUEST *ConfigInfo; + + if (SingleForm) { + if (Form->NvUpdateRequired) { + ConfigInfo = NULL; + Link = GetFirstNode (&Form->ConfigRequestHead); + while (!IsNull (&Form->ConfigRequestHead, Link)) { + ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link); + Link = GetNextNode (&Form->ConfigRequestHead, Link); + + if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) { + continue; + } + + // + // Skip if there is no RequestElement + // + if (ConfigInfo->ElementCount == 0) { + continue; + } + + // + // Prepare + // + FormRestoreStorage(FormSet, ConfigInfo); + } + + Form->NvUpdateRequired = FALSE; + } + } else { + if (IsNvUpdateRequired(FormSet)) { + // + // Discard Buffer storage or Name/Value storage + // + Link = GetFirstNode (&FormSet->StorageListHead); + while (!IsNull (&FormSet->StorageListHead, Link)) { + Storage = FORMSET_STORAGE_FROM_LINK (Link); + Link = GetNextNode (&FormSet->StorageListHead, Link); + + if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) { + continue; + } + + // + // Skip if there is no RequestElement + // + if (Storage->ElementCount == 0) { + continue; + } + + RestoreStorage(Storage); + } + + UpdateNvInfoInForm(FormSet, FALSE); + } + } + + return EFI_SUCCESS; +} + +/** + Submit data for form level or formset level. + + @param FormSet FormSet data structure. + @param Form Form data structure. + @param SingleForm whether submit for the single form or all form set. @retval EFI_SUCCESS The function completed successfully. @@ -1733,7 +1965,8 @@ NoSubmitCheck ( EFI_STATUS SubmitForm ( IN FORM_BROWSER_FORMSET *FormSet, - IN FORM_BROWSER_FORM *Form + IN FORM_BROWSER_FORM *Form, + IN BOOLEAN SingleForm ) { EFI_STATUS Status; @@ -1741,66 +1974,122 @@ SubmitForm ( EFI_STRING ConfigResp; EFI_STRING Progress; FORMSET_STORAGE *Storage; + FORM_BROWSER_CONFIG_REQUEST *ConfigInfo; // // Validate the Form by NoSubmit check // - Status = NoSubmitCheck (FormSet); + if (SingleForm) { + Status = NoSubmitCheck (FormSet, Form); + } else { + Status = NoSubmitCheck (FormSet, NULL); + } if (EFI_ERROR (Status)) { return Status; } - // - // Submit Buffer storage or Name/Value storage - // - Link = GetFirstNode (&FormSet->StorageListHead); - while (!IsNull (&FormSet->StorageListHead, Link)) { - Storage = FORMSET_STORAGE_FROM_LINK (Link); - Link = GetNextNode (&FormSet->StorageListHead, Link); + if (SingleForm) { + ConfigInfo = NULL; + Link = GetFirstNode (&Form->ConfigRequestHead); + while (!IsNull (&Form->ConfigRequestHead, Link)) { + ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link); + Link = GetNextNode (&Form->ConfigRequestHead, Link); - if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) { - continue; - } + if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) { + continue; + } - // - // Skip if there is no RequestElement - // - if (Storage->ElementCount == 0) { - continue; - } + // + // Skip if there is no RequestElement + // + if (ConfigInfo->ElementCount == 0) { + continue; + } - // - // Prepare - // - Status = StorageToConfigResp (Storage, &ConfigResp); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Send to Configuration Driver - // - if (FormSet->ConfigAccess != NULL) { - Status = FormSet->ConfigAccess->RouteConfig ( - FormSet->ConfigAccess, - ConfigResp, - &Progress - ); + // + // Prepare + // + Status = StorageToConfigResp (ConfigInfo, &ConfigResp, TRUE); if (EFI_ERROR (Status)) { - FreePool (ConfigResp); return Status; } + + // + // Send to Configuration Driver + // + if (FormSet->ConfigAccess != NULL) { + Status = FormSet->ConfigAccess->RouteConfig ( + FormSet->ConfigAccess, + ConfigResp, + &Progress + ); + if (EFI_ERROR (Status)) { + FreePool (ConfigResp); + return Status; + } + } + FreePool (ConfigResp); + + // + // Config success, update storage shadow Buffer + // + SynchronizeStorage (ConfigInfo->Storage); } - FreePool (ConfigResp); + Form->NvUpdateRequired = FALSE; + } else { // - // Config success, update storage shadow Buffer + // Submit Buffer storage or Name/Value storage // - SynchronizeStorage (Storage); + Link = GetFirstNode (&FormSet->StorageListHead); + while (!IsNull (&FormSet->StorageListHead, Link)) { + Storage = FORMSET_STORAGE_FROM_LINK (Link); + Link = GetNextNode (&FormSet->StorageListHead, Link); + + if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) { + continue; + } + + // + // Skip if there is no RequestElement + // + if (Storage->ElementCount == 0) { + continue; + } + + // + // Prepare + // + Status = StorageToConfigResp (Storage, &ConfigResp, FALSE); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Send to Configuration Driver + // + if (FormSet->ConfigAccess != NULL) { + Status = FormSet->ConfigAccess->RouteConfig ( + FormSet->ConfigAccess, + ConfigResp, + &Progress + ); + if (EFI_ERROR (Status)) { + FreePool (ConfigResp); + return Status; + } + } + FreePool (ConfigResp); + + // + // Config success, update storage shadow Buffer + // + SynchronizeStorage (Storage); + } + + UpdateNvInfoInForm(FormSet, FALSE); } - gNvUpdateRequired = FALSE; - return EFI_SUCCESS; } @@ -2321,8 +2610,6 @@ LoadFormConfig ( FORM_BROWSER_STATEMENT *Question; UINT8 *BufferValue; UINTN StorageWidth; - EFI_HII_VALUE *HiiValue; - EFI_BROWSER_ACTION_REQUEST ActionRequest; Link = GetFirstNode (&Form->StatementListHead); while (!IsNull (&Form->StatementListHead, Link)) { @@ -2368,41 +2655,7 @@ LoadFormConfig ( ); if (!EFI_ERROR (Status)) { - ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; - HiiValue = &Question->HiiValue; - BufferValue = (UINT8 *) &Question->HiiValue.Value; - if (HiiValue->Type == EFI_IFR_TYPE_BUFFER) { - BufferValue = Question->BufferValue; - } - - Status = FormSet->ConfigAccess->Callback ( - FormSet->ConfigAccess, - EFI_BROWSER_ACTION_RETRIEVE, - Question->QuestionId, - HiiValue->Type, - (EFI_IFR_TYPE_VALUE *) BufferValue, - &ActionRequest - ); - if (!EFI_ERROR (Status)) { - switch (ActionRequest) { - case EFI_BROWSER_ACTION_REQUEST_RESET: - gResetRequired = TRUE; - break; - - case EFI_BROWSER_ACTION_REQUEST_SUBMIT: - // - // Till now there is no uncommitted data, so ignore this request - // - break; - - case EFI_BROWSER_ACTION_REQUEST_EXIT: - Selection->Action = UI_ACTION_EXIT; - break; - - default: - break; - } - } + Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE); } } @@ -2539,6 +2792,7 @@ CopyStorage ( switch (Src->Type) { case EFI_HII_VARSTORE_BUFFER: CopyMem (Dst->EditBuffer, Src->EditBuffer, Src->Size); + CopyMem (Dst->Buffer, Src->Buffer, Src->Size); break; case EFI_HII_VARSTORE_NAME_VALUE: @@ -2546,7 +2800,8 @@ CopyStorage ( while (!IsNull (&Src->NameValueListHead, Link)) { Node = NAME_VALUE_NODE_FROM_LINK (Link); - SetValueByName (Dst, Node->Name, Node->EditValue); + SetValueByName (Dst, Node->Name, Node->EditValue, TRUE); + SetValueByName (Dst, Node->Name, Node->Value, FALSE); Link = GetNextNode (&Src->NameValueListHead, Link); } @@ -2624,6 +2879,13 @@ InitializeCurrentSetting ( // Storage is not found in backup formset, request it from ConfigDriver // Status = LoadStorage (FormSet, Storage); + // + // Now Edit Buffer is filled with default values(lower priority) and current + // settings(higher priority), sychronize it to shadow Buffer + // + if (!EFI_ERROR (Status)) { + SynchronizeStorage (Storage); + } } else { // // Storage found in backup formset, use it @@ -2631,14 +2893,6 @@ InitializeCurrentSetting ( Status = CopyStorage (Storage, OldStorage); } - // - // Now Edit Buffer is filled with default values(lower priority) and current - // settings(higher priority), sychronize it to shadow Buffer - // - if (!EFI_ERROR (Status)) { - SynchronizeStorage (Storage); - } - Link = GetNextNode (&FormSet->StorageListHead, Link); } @@ -2958,7 +3212,6 @@ SaveBrowserContext ( Context->ClassOfVfr = gClassOfVfr; Context->FunctionKeySetting = gFunctionKeySetting; Context->ResetRequired = gResetRequired; - Context->NvUpdateRequired = gNvUpdateRequired; Context->Direction = gDirection; Context->FunctionNineString = gFunctionNineString; Context->FunctionTenString = gFunctionTenString; @@ -3039,7 +3292,6 @@ RestoreBrowserContext ( gClassOfVfr = Context->ClassOfVfr; gFunctionKeySetting = Context->FunctionKeySetting; gResetRequired = Context->ResetRequired; - gNvUpdateRequired = Context->NvUpdateRequired; gDirection = Context->Direction; gFunctionNineString = Context->FunctionNineString; gFunctionTenString = Context->FunctionTenString; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h index f000c7b767..d76569e8ec 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h @@ -400,6 +400,19 @@ typedef struct { #define FORM_BROWSER_STATEMENT_FROM_LINK(a) CR (a, FORM_BROWSER_STATEMENT, Link, FORM_BROWSER_STATEMENT_SIGNATURE) +#define FORM_BROWSER_CONFIG_REQUEST_SIGNATURE SIGNATURE_32 ('F', 'C', 'R', 'S') +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + CHAR16 *ConfigRequest; // = + + UINTN ElementCount; // Number of in the + UINTN SpareStrLen; + + FORMSET_STORAGE *Storage; +} FORM_BROWSER_CONFIG_REQUEST; +#define FORM_BROWSER_CONFIG_REQUEST_FROM_LINK(a) CR (a, FORM_BROWSER_CONFIG_REQUEST, Link, FORM_BROWSER_CONFIG_REQUEST_SIGNATURE) + #define FORM_BROWSER_FORM_SIGNATURE SIGNATURE_32 ('F', 'F', 'R', 'M') #define STANDARD_MAP_FORM_TYPE 0x01 @@ -413,8 +426,11 @@ typedef struct { EFI_IMAGE_ID ImageId; + BOOLEAN NvUpdateRequired; // Whether this form has NV update request. + LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION) LIST_ENTRY StatementListHead; // List of Statements and Questions (FORM_BROWSER_STATEMENT) + LIST_ENTRY ConfigRequestHead; // List of configreques for all storage. FORM_EXPRESSION *SuppressExpression; // nesting inside of SuppressIf } FORM_BROWSER_FORM; @@ -472,7 +488,6 @@ typedef struct { UINTN ClassOfVfr; UINTN FunctionKeySetting; BOOLEAN ResetRequired; - BOOLEAN NvUpdateRequired; UINT16 Direction; EFI_SCREEN_DESCRIPTOR ScreenDimensions; CHAR16 *FunctionNineString; @@ -528,7 +543,6 @@ extern EFI_HII_HANDLE gFrontPageHandle; extern UINTN gClassOfVfr; extern UINTN gFunctionKeySetting; extern BOOLEAN gResetRequired; -extern BOOLEAN gNvUpdateRequired; extern EFI_HII_HANDLE gHiiHandle; extern UINT16 gDirection; extern EFI_SCREEN_DESCRIPTOR gScreenDimensions; @@ -833,6 +847,7 @@ GetValueByName ( @param Storage The NameValue Storage. @param Name The Name. @param Value The Value to set. + @param Edit Whether update editValue or Value. @retval EFI_SUCCESS Value found for given Name. @retval EFI_NOT_FOUND No such Name found in NameValue storage. @@ -842,7 +857,8 @@ EFI_STATUS SetValueByName ( IN FORMSET_STORAGE *Storage, IN CHAR16 *Name, - IN CHAR16 *Value + IN CHAR16 *Value, + IN BOOLEAN Edit ); /** @@ -906,10 +922,28 @@ ValidateQuestion ( ); /** - Submit a Form. + Discard data for form level or formset level. @param FormSet FormSet data structure. @param Form Form data structure. + @param SingleForm whether submit single form or formset. + + @retval EFI_SUCCESS The function completed successfully. + +**/ +EFI_STATUS +DiscardForm ( + IN FORM_BROWSER_FORMSET *FormSet, + IN FORM_BROWSER_FORM *Form, + IN BOOLEAN SingleForm + ); + +/** + Submit data for form level or formset level. + + @param FormSet FormSet data structure. + @param Form Form data structure. + @param SingleForm whether submit single form or formset. @retval EFI_SUCCESS The function completed successfully. @@ -917,7 +951,8 @@ ValidateQuestion ( EFI_STATUS SubmitForm ( IN FORM_BROWSER_FORMSET *FormSet, - IN FORM_BROWSER_FORM *Form + IN FORM_BROWSER_FORM *Form, + IN BOOLEAN SingleForm ); /** @@ -1028,8 +1063,9 @@ LoadFormSetConfig ( /** Convert setting of Buffer Storage or NameValue Storage to . - @param Storage The Storage to be conveted. + @param Buffer The Storage to be conveted. @param ConfigResp The returned . + @param SingleForm Whether update data for single form or formset level. @retval EFI_SUCCESS Convert success. @retval EFI_INVALID_PARAMETER Incorrect storage type. @@ -1037,8 +1073,9 @@ LoadFormSetConfig ( **/ EFI_STATUS StorageToConfigResp ( - IN FORMSET_STORAGE *Storage, - IN CHAR16 **ConfigResp + IN VOID *Buffer, + IN CHAR16 **ConfigResp, + IN BOOLEAN SingleForm ); /** @@ -1195,4 +1232,71 @@ BrowserCallback ( IN CONST CHAR16 *VariableName OPTIONAL ); +/** + Find menu which will show next time. + + @param Selection On input, Selection tell setup browser the information + about the Selection, form and formset to be displayed. + On output, Selection return the screen item that is selected + by user. + @param Repaint Whether need to repaint the menu. + @param NewLine Whether need to show at new line. + + @retval TRUE Need return. + @retval FALSE No need to return. +**/ +BOOLEAN +FindNextMenu ( + IN OUT UI_MENU_SELECTION *Selection, + IN BOOLEAN *Repaint, + IN BOOLEAN *NewLine + ); + +/** + check whether the formset need to update the NV. + + @param FormSet FormSet data structure. + @param SetValue Whether set new value or clear old value. + +**/ +VOID +UpdateNvInfoInForm ( + IN FORM_BROWSER_FORMSET *FormSet, + IN BOOLEAN SetValue + ); + +/** + check whether the formset need to update the NV. + + @param FormSet FormSet data structure. + + @retval TRUE Need to update the NV. + @retval FALSE No need to update the NV. +**/ +BOOLEAN +IsNvUpdateRequired ( + IN FORM_BROWSER_FORMSET *FormSet + ); + +/** + Call the call back function for the question and process the return action. + + @param Selection On input, Selection tell setup browser the information + about the Selection, form and formset to be displayed. + On output, Selection return the screen item that is selected + by user. + @param Statement The Question which need to call. + @param Action The action request. + @param SkipSaveOrDiscard Whether skip save or discard action. + + @retval EFI_SUCCESS The call back function excutes successfully. + @return Other value if the call back function failed to excute. +**/ +EFI_STATUS +ProcessCallBackFunction ( + IN OUT UI_MENU_SELECTION *Selection, + IN FORM_BROWSER_STATEMENT *Question, + IN EFI_BROWSER_ACTION Action, + IN BOOLEAN SkipSaveOrDiscard + ); #endif diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c index 3ab63be2d6..d5f726b0ce 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c @@ -340,8 +340,6 @@ RefreshForm ( EFI_STATUS Status; UI_MENU_SELECTION *Selection; FORM_BROWSER_STATEMENT *Question; - EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; - EFI_BROWSER_ACTION_REQUEST ActionRequest; if (gMenuRefreshHead != NULL) { @@ -394,36 +392,9 @@ RefreshForm ( // // Question value may be changed, need invoke its Callback() // - ConfigAccess = Selection->FormSet->ConfigAccess; - if (((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) && (ConfigAccess != NULL)) { - ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; - Status = ConfigAccess->Callback ( - ConfigAccess, - EFI_BROWSER_ACTION_CHANGING, - Question->QuestionId, - Question->HiiValue.Type, - &Question->HiiValue.Value, - &ActionRequest - ); - if (!EFI_ERROR (Status)) { - switch (ActionRequest) { - case EFI_BROWSER_ACTION_REQUEST_RESET: - gResetRequired = TRUE; - break; - - case EFI_BROWSER_ACTION_REQUEST_SUBMIT: - SubmitForm (Selection->FormSet, Selection->Form); - break; - - case EFI_BROWSER_ACTION_REQUEST_EXIT: - Selection->Action = UI_ACTION_EXIT; - gNvUpdateRequired = FALSE; - break; - - default: - break; - } - } + Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_CHANGING, FALSE); + if (EFI_ERROR (Status)) { + return Status; } MenuRefreshEntry = MenuRefreshEntry->Next; @@ -1004,6 +975,7 @@ CreateMultiStringPopUp ( /** Update status bar on the bottom of menu. + @param Selection Current Selction info. @param MessageType The type of message to be shown. @param Flags The flags in Question header. @param State Set or clear. @@ -1011,6 +983,7 @@ CreateMultiStringPopUp ( **/ VOID UpdateStatusBar ( + IN UI_MENU_SELECTION *Selection, IN UINTN MessageType, IN UINT8 Flags, IN BOOLEAN State @@ -1054,7 +1027,9 @@ UpdateStatusBar ( ); gResetRequired = (BOOLEAN) (gResetRequired | ((Flags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED)); - gNvUpdateRequired = TRUE; + if (Selection != NULL) { + Selection->Form->NvUpdateRequired = TRUE; + } } else { gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor)); for (Index = 0; Index < (GetStringWidth (NvUpdateMessage) - 2) / 2; Index++) { @@ -1065,18 +1040,20 @@ UpdateStatusBar ( ); } - gNvUpdateRequired = FALSE; + if (Selection != NULL) { + Selection->Form->NvUpdateRequired = FALSE; + } } } break; case REFRESH_STATUS_BAR: if (mInputError) { - UpdateStatusBar (INPUT_ERROR, Flags, TRUE); + UpdateStatusBar (Selection, INPUT_ERROR, Flags, TRUE); } - if (gNvUpdateRequired) { - UpdateStatusBar (NV_UPDATE_REQUIRED, Flags, TRUE); + if (IsNvUpdateRequired(Selection->FormSet)) { + UpdateStatusBar (NULL, NV_UPDATE_REQUIRED, Flags, TRUE); } break; @@ -1640,8 +1617,6 @@ UiDisplayMenu ( CHAR16 *OptionString; CHAR16 *OutputString; CHAR16 *FormattedString; - CHAR16 YesResponse; - CHAR16 NoResponse; BOOLEAN NewLine; BOOLEAN Repaint; BOOLEAN SavedValue; @@ -1730,6 +1705,7 @@ UiDisplayMenu ( CurrentMenu = UiAddMenuList (NULL, &Selection->FormSetGuid, Selection->FormId); } ASSERT (CurrentMenu != NULL); + Selection->CurrentMenu = CurrentMenu; if (Selection->QuestionId == 0) { // @@ -1745,7 +1721,7 @@ UiDisplayMenu ( NewPos = gMenuOption.ForwardLink; gST->ConOut->EnableCursor (gST->ConOut, FALSE); - UpdateStatusBar (REFRESH_STATUS_BAR, (UINT8) 0, TRUE); + UpdateStatusBar (Selection, REFRESH_STATUS_BAR, (UINT8) 0, TRUE); ControlFlag = CfInitialization; Selection->Action = UI_ACTION_NONE; @@ -2697,84 +2673,10 @@ UiDisplayMenu ( // We come here when someone press ESC // ControlFlag = CfCheckSelection; - - if (CurrentMenu->Parent != NULL) { - // - // we have a parent, so go to the parent menu - // - if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) { - // - // The parent menu and current menu are in the same formset - // - Selection->Action = UI_ACTION_REFRESH_FORM; - } else { - Selection->Action = UI_ACTION_REFRESH_FORMSET; - } - Selection->Statement = NULL; - - Selection->FormId = CurrentMenu->Parent->FormId; - Selection->QuestionId = CurrentMenu->Parent->QuestionId; - - // - // Clear highlight record for this menu - // - CurrentMenu->QuestionId = 0; - break; - } - - if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) { - // - // We never exit FrontPage, so skip the ESC - // - Selection->Action = UI_ACTION_NONE; - break; - } - - // - // We are going to leave current FormSet, so check uncommited data in this FormSet - // - if (gNvUpdateRequired) { - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); - - YesResponse = gYesResponse[0]; - NoResponse = gNoResponse[0]; - - // - // If NV flag is up, prompt user - // - do { - CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString); - } while - ( - (Key.ScanCode != SCAN_ESC) && - ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) && - ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET)) - ); - - if (Key.ScanCode == SCAN_ESC) { - // - // User hits the ESC key - // - Repaint = TRUE; - NewLine = TRUE; - - Selection->Action = UI_ACTION_NONE; - break; - } - - // - // If the user hits the YesResponse key - // - if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) { - Status = SubmitForm (Selection->FormSet, Selection->Form); - } - } - - Selection->Action = UI_ACTION_EXIT; - Selection->Statement = NULL; - CurrentMenu->QuestionId = 0; - - return EFI_SUCCESS; + if (FindNextMenu (Selection, &Repaint, &NewLine)) { + return EFI_SUCCESS; + } + break; case CfUiLeft: ControlFlag = CfCheckSelection; @@ -2869,7 +2771,7 @@ UiDisplayMenu ( AdjustDateAndTimePosition (TRUE, &TopOfScreen); AdjustDateAndTimePosition (TRUE, &NewPos); MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry); - UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE); + UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE); } else { // // Scroll up to the last page. @@ -3166,7 +3068,7 @@ UiDisplayMenu ( MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry); - UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE); + UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE); } else { // @@ -3197,12 +3099,12 @@ UiDisplayMenu ( // // Submit the form // - Status = SubmitForm (Selection->FormSet, Selection->Form); + Status = SubmitForm (Selection->FormSet, Selection->Form, FALSE); if (!EFI_ERROR (Status)) { ASSERT(MenuOption != NULL); - UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE); - UpdateStatusBar (NV_UPDATE_REQUIRED, MenuOption->ThisTag->QuestionFlags, FALSE); + UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE); + UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, MenuOption->ThisTag->QuestionFlags, FALSE); } else { do { CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveFailed, gPressEnter, gEmptyString); @@ -3231,7 +3133,7 @@ UiDisplayMenu ( // // Show NV update flag on status bar // - gNvUpdateRequired = TRUE; + UpdateNvInfoInForm(Selection->FormSet, TRUE); gResetRequired = TRUE; } break; diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h index 362f8e7d60..a9f679b3d2 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h @@ -1,7 +1,7 @@ /** @file Private structure, MACRO and function definitions for User Interface related functionalities. -Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -76,6 +76,8 @@ typedef enum { #define UI_ACTION_REFRESH_FORMSET 2 #define UI_ACTION_EXIT 3 +typedef struct _UI_MENU_LIST UI_MENU_LIST; + typedef struct { EFI_HII_HANDLE Handle; @@ -111,6 +113,8 @@ typedef struct { // Whether the Form is editable // BOOLEAN FormEditable; + + UI_MENU_LIST *CurrentMenu; } UI_MENU_SELECTION; #define UI_MENU_OPTION_SIGNATURE SIGNATURE_32 ('u', 'i', 'm', 'm') @@ -152,8 +156,6 @@ typedef struct { #define MENU_OPTION_FROM_LINK(a) CR (a, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE) -typedef struct _UI_MENU_LIST UI_MENU_LIST; - struct _UI_MENU_LIST { UINTN Signature; LIST_ENTRY Link; @@ -449,6 +451,7 @@ GetNumericInput ( /** Update status bar on the bottom of menu. + @param Selection Current selection info. @param MessageType The type of message to be shown. @param Flags The flags in Question header. @param State Set or clear. @@ -456,6 +459,7 @@ GetNumericInput ( **/ VOID UpdateStatusBar ( + IN UI_MENU_SELECTION *Selection, IN UINTN MessageType, IN UINT8 Flags, IN BOOLEAN State