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

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