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
This commit is contained in:
ydong10 2011-05-31 00:59:15 +00:00
parent d490265ca6
commit b18e705046
12 changed files with 990 additions and 433 deletions

View File

@ -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.<BR>
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
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.

View File

@ -2,7 +2,7 @@
//
// Sample Setup formset.
//
// Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
// Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
// 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),

View File

@ -1,7 +1,7 @@
/** @file
Utility functions for expression evaluation.
Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
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;

View File

@ -1,7 +1,7 @@
/** @file
Parser for IFR binary encoding.
Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
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 <RequestElement> to <ConfigRequest>
//
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;

View File

@ -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;

View File

@ -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;
Status = ProcessCallBackFunction (Selection, NULL, EFI_BROWSER_ACTION_FORM_OPEN, FALSE);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// 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);
}
//
// 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);

View File

@ -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);
}
}

View File

@ -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 <ConfigResp>
//
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 <ConfigResp>.
@param Storage The Storage to be conveted.
@param Buffer The Storage to be conveted.
@param ConfigResp The returned <ConfigResp>.
@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);
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 <ConfigResp>
//
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,15 +1974,70 @@ 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;
}
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 (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
continue;
}
//
// Skip if there is no RequestElement
//
if (ConfigInfo->ElementCount == 0) {
continue;
}
//
// Prepare <ConfigResp>
//
Status = StorageToConfigResp (ConfigInfo, &ConfigResp, TRUE);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Send <ConfigResp> 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);
}
Form->NvUpdateRequired = FALSE;
} else {
//
// Submit Buffer storage or Name/Value storage
//
@ -1772,7 +2060,7 @@ SubmitForm (
//
// Prepare <ConfigResp>
//
Status = StorageToConfigResp (Storage, &ConfigResp);
Status = StorageToConfigResp (Storage, &ConfigResp, FALSE);
if (EFI_ERROR (Status)) {
return Status;
}
@ -1799,7 +2087,8 @@ SubmitForm (
SynchronizeStorage (Storage);
}
gNvUpdateRequired = FALSE;
UpdateNvInfoInForm(FormSet, 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,13 +2879,6 @@ InitializeCurrentSetting (
// Storage is not found in backup formset, request it from ConfigDriver
//
Status = LoadStorage (FormSet, Storage);
} else {
//
// Storage found in backup formset, use it
//
Status = CopyStorage (Storage, OldStorage);
}
//
// Now Edit Buffer is filled with default values(lower priority) and current
// settings(higher priority), sychronize it to shadow Buffer
@ -2638,6 +2886,12 @@ InitializeCurrentSetting (
if (!EFI_ERROR (Status)) {
SynchronizeStorage (Storage);
}
} else {
//
// Storage found in backup formset, use it
//
Status = CopyStorage (Storage, OldStorage);
}
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;

View File

@ -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; // <ConfigRequest> = <ConfigHdr> + <RequestElement>
UINTN ElementCount; // Number of <RequestElement> in the <ConfigRequest>
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 <ConfigResp>.
@param Storage The Storage to be conveted.
@param Buffer The Storage to be conveted.
@param ConfigResp The returned <ConfigResp>.
@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

View File

@ -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;
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;

View File

@ -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.<BR>
Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
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