Per UEFI spec, FORM_OPEN/FORM_CLOSE Callback function should be called for each question in the form when this form opens or closes.

Update SetupBrowser driver to call Callback function (FORM_OPEN/FORM_CLOSE) based on UEFI spec, and update all EDKII HII drivers to correctly handle FORM_OPEN and FORM_CLOSE call back. 


git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10560 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
lgao4 2010-06-02 02:05:47 +00:00
parent 2bd78c92c6
commit 5adb8db71e
8 changed files with 306 additions and 140 deletions

View File

@ -842,8 +842,11 @@ DriverCallback (
UINTN MyVarSize; UINTN MyVarSize;
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) { if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
if (QuestionId == 0x1234) {
// //
// On FORM_OPEN event, update the form on-the-fly // Sample CallBack for UEFI FORM_OPEN action:
// Add Save action into Form 3 when Form 1 is opened.
// This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
// //
PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This); PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
@ -878,25 +881,28 @@ DriverCallback (
); );
HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle (StartOpCodeHandle);
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }
if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) { if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
if (QuestionId == 0x5678) {
// //
// On FORM_CLOSE event, show up a pop-up // Sample CallBack for UEFI FORM_CLOSE action:
// Show up a pop-up to specify Form 3 will be closed when exit Form 3.
// //
do { do {
CreatePopUp ( CreatePopUp (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key, &Key,
L"", L"",
L"You are going to leave the Form!", L"You are going to leave third Form!",
L"Press ESC or ENTER to continue ...", L"Press ESC or ENTER to continue ...",
L"", L"",
NULL NULL
); );
} while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -1028,6 +1034,37 @@ DriverCallback (
NULL // Default Opcode is NULl NULL // Default Opcode is NULl
); );
HiiCreateTextOpCode (
StartOpCodeHandle,
STRING_TOKEN(STR_TEXT_SAMPLE_HELP),
STRING_TOKEN(STR_TEXT_SAMPLE_HELP),
STRING_TOKEN(STR_TEXT_SAMPLE_STRING)
);
HiiCreateDateOpCode (
StartOpCodeHandle,
0x8004,
0x0,
0x0,
STRING_TOKEN(STR_DATE_SAMPLE_HELP),
STRING_TOKEN(STR_DATE_SAMPLE_HELP),
0,
QF_DATE_STORAGE_TIME,
NULL
);
HiiCreateTimeOpCode (
StartOpCodeHandle,
0x8005,
0x0,
0x0,
STRING_TOKEN(STR_TIME_SAMPLE_HELP),
STRING_TOKEN(STR_TIME_SAMPLE_HELP),
0,
QF_TIME_STORAGE_TIME,
NULL
);
HiiCreateGotoOpCode ( HiiCreateGotoOpCode (
StartOpCodeHandle, // Container for dynamic created opcodes StartOpCodeHandle, // Container for dynamic created opcodes
1, // Target Form ID 1, // Target Form ID

View File

@ -562,6 +562,13 @@ IScsiFormCallback (
EFI_STATUS Status; EFI_STATUS Status;
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
//
// Do nothing for UEFI OPEN/CLOSE Action
//
return EFI_SUCCESS;
}
Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This); Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);
// //

View File

@ -670,6 +670,13 @@ Ip4FormCallback (
EFI_STATUS Status; EFI_STATUS Status;
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
//
// Do nothing for UEFI OPEN/CLOSE Action
//
return EFI_SUCCESS;
}
Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This); Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);
IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA)); IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA));

View File

@ -237,11 +237,20 @@ VlanCallback (
PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This); PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) { if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
if (QuestionId == VLAN_ADD_QUESTION_ID) {
// //
// On FORM_OPEN event, update current VLAN list // Update current VLAN list into Form when Form is opened.
// This will be done only in FORM_OPEN CallBack of question with VLAN_ADD_QUESTION_ID.
// //
VlanUpdateForm (PrivateData); VlanUpdateForm (PrivateData);
}
return EFI_SUCCESS;
}
if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {
//
// Do nothing for UEFI FORM_CLOSE action
//
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@ -1335,6 +1335,13 @@ PlatOverMngrCallback (
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
PLAT_OVER_MNGR_DATA *FakeNvData; PLAT_OVER_MNGR_DATA *FakeNvData;
if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
//
// Do nothing for UEFI OPEN/CLOSE Action
//
return EFI_SUCCESS;
}
Private = EFI_CALLBACK_INFO_FROM_THIS (This); Private = EFI_CALLBACK_INFO_FROM_THIS (This);
FakeNvData = &Private->FakeNvData; FakeNvData = &Private->FakeNvData;
if (!HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData)) { if (!HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData)) {

View File

@ -842,6 +842,8 @@ FormUpdateNotify (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
BOOLEAN mFormCloseCallBack = FALSE;
/** /**
The worker function that send the displays to the screen. On output, The worker function that send the displays to the screen. On output,
the selection made by user is returned. the selection made by user is returned.
@ -870,10 +872,16 @@ SetupBrowser (
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
FORM_BROWSER_FORMSET *FormSet; FORM_BROWSER_FORMSET *FormSet;
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
BOOLEAN FormOpenCallBack;
BOOLEAN SubmitFormIsRequired;
EFI_GUID CurrentFormSetGuid;
EFI_HII_HANDLE CurrentHiiHandle;
UINT16 CurrentFormId;
gMenuRefreshHead = NULL; gMenuRefreshHead = NULL;
gResetRequired = FALSE; gResetRequired = FALSE;
FormSet = Selection->FormSet; FormSet = Selection->FormSet;
ConfigAccess = Selection->FormSet->ConfigAccess;
// //
// Register notify for Form package update // Register notify for Form package update
@ -890,53 +898,6 @@ SetupBrowser (
return Status; return Status;
} }
//
// Before display the formset, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN
//
ConfigAccess = Selection->FormSet->ConfigAccess;
if ((ConfigAccess != NULL) && (Selection->Action != UI_ACTION_REFRESH_FORMSET)) {
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
mHiiPackageListUpdated = FALSE;
Status = ConfigAccess->Callback (
ConfigAccess,
EFI_BROWSER_ACTION_FORM_OPEN,
0,
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:
//
// 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;
}
}
if (mHiiPackageListUpdated) {
//
// IFR is updated during callback, force to reparse the IFR binary
//
mHiiPackageListUpdated = FALSE;
Selection->Action = UI_ACTION_REFRESH_FORMSET;
goto Done;
}
}
// //
// Initialize current settings of Questions in this FormSet // Initialize current settings of Questions in this FormSet
// //
@ -950,7 +911,13 @@ SetupBrowser (
// //
// Initialize Selection->Form // Initialize Selection->Form
// //
FormOpenCallBack = FALSE;
if (Selection->FormId == 0) { if (Selection->FormId == 0) {
//
// First Form will open.
//
FormOpenCallBack = TRUE;
// //
// Zero FormId indicates display the first Form in a FormSet // Zero FormId indicates display the first Form in a FormSet
// //
@ -959,6 +926,12 @@ SetupBrowser (
Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link); Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link);
Selection->FormId = Selection->Form->FormId; Selection->FormId = Selection->Form->FormId;
} else { } else {
if (Selection->Form == NULL) {
//
// First Form will open.
//
FormOpenCallBack = TRUE;
}
Selection->Form = IdToForm (Selection->FormSet, Selection->FormId); Selection->Form = IdToForm (Selection->FormSet, Selection->FormId);
} }
@ -990,11 +963,99 @@ SetupBrowser (
} }
} }
//
// Keep current form information
//
CurrentHiiHandle = Selection->Handle;
CopyGuid (&CurrentFormSetGuid, &Selection->FormSetGuid);
CurrentFormId = Selection->FormId;
// //
// Reset FormPackage update flag // Reset FormPackage update flag
// //
mHiiPackageListUpdated = FALSE; mHiiPackageListUpdated = FALSE;
//
// Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN
// for each question with callback flag.
// New form may be the first form, or the different form after another form close.
//
if ((FormOpenCallBack || mFormCloseCallBack) && (ConfigAccess != NULL)) {
mFormCloseCallBack = FALSE;
//
// 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;
}
}
}
if (SubmitFormIsRequired) {
SubmitForm (Selection->FormSet, Selection->Form);
}
//
// EXIT requests to close form.
//
if (Selection->Action == UI_ACTION_EXIT) {
goto Done;
}
//
// IFR is updated during callback of open form, force to reparse the IFR binary
//
if (mHiiPackageListUpdated) {
Selection->Action = UI_ACTION_REFRESH_FORMSET;
mHiiPackageListUpdated = FALSE;
goto Done;
}
}
// //
// Load Questions' Value for display // Load Questions' Value for display
// //
@ -1003,6 +1064,12 @@ SetupBrowser (
return Status; return Status;
} }
//
// EXIT requests to close form.
//
if (Selection->Action == UI_ACTION_EXIT) {
goto Done;
}
// //
// IFR is updated during callback of read value, force to reparse the IFR binary // IFR is updated during callback of read value, force to reparse the IFR binary
// //
@ -1119,17 +1186,36 @@ SetupBrowser (
Selection->Action = UI_ACTION_REFRESH_FORMSET; Selection->Action = UI_ACTION_REFRESH_FORMSET;
} }
} }
} while (Selection->Action == UI_ACTION_REFRESH_FORM);
// //
// Before exit the formset, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE
// for each question with callback flag.
// //
if ((ConfigAccess != NULL) && (Selection->Action == UI_ACTION_EXIT)) { mFormCloseCallBack = FALSE;
if ((ConfigAccess != NULL) &&
((Selection->Action == UI_ACTION_EXIT) ||
(Selection->Handle != CurrentHiiHandle) ||
(!CompareGuid (&CurrentFormSetGuid, &Selection->FormSetGuid)) ||
(Selection->FormId != CurrentFormId))) {
//
// Go through each statement in this form
//
mFormCloseCallBack = TRUE;
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; ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
Status = ConfigAccess->Callback ( Status = ConfigAccess->Callback (
ConfigAccess, ConfigAccess,
EFI_BROWSER_ACTION_FORM_CLOSE, EFI_BROWSER_ACTION_FORM_CLOSE,
0, Statement->QuestionId,
EFI_IFR_TYPE_UNDEFINED, EFI_IFR_TYPE_UNDEFINED,
NULL, NULL,
&ActionRequest &ActionRequest
@ -1142,10 +1228,11 @@ SetupBrowser (
break; break;
case EFI_BROWSER_ACTION_REQUEST_SUBMIT: case EFI_BROWSER_ACTION_REQUEST_SUBMIT:
SubmitForm (Selection->FormSet, Selection->Form); SubmitFormIsRequired = TRUE;
break; break;
case EFI_BROWSER_ACTION_REQUEST_EXIT: case EFI_BROWSER_ACTION_REQUEST_EXIT:
Selection->Action = UI_ACTION_EXIT;
gNvUpdateRequired = FALSE; gNvUpdateRequired = FALSE;
break; break;
@ -1154,6 +1241,11 @@ SetupBrowser (
} }
} }
} }
if (SubmitFormIsRequired) {
SubmitForm (Selection->FormSet, Selection->Form);
}
}
} while (Selection->Action == UI_ACTION_REFRESH_FORM);
// //
// Record the old formset // Record the old formset

View File

@ -1679,10 +1679,9 @@ ValidateQuestion (
/** /**
Perform NoSubmit check for a Form. Perform NoSubmit check for each Form in FormSet.
@param FormSet FormSet data structure. @param FormSet FormSet data structure.
@param Form Form data structure.
@retval EFI_SUCCESS Form validation pass. @retval EFI_SUCCESS Form validation pass.
@retval other Form validation failed. @retval other Form validation failed.
@ -1690,13 +1689,18 @@ ValidateQuestion (
**/ **/
EFI_STATUS EFI_STATUS
NoSubmitCheck ( NoSubmitCheck (
IN FORM_BROWSER_FORMSET *FormSet, IN FORM_BROWSER_FORMSET *FormSet
IN FORM_BROWSER_FORM *Form
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
LIST_ENTRY *Link; LIST_ENTRY *Link;
FORM_BROWSER_STATEMENT *Question; FORM_BROWSER_STATEMENT *Question;
FORM_BROWSER_FORM *Form;
LIST_ENTRY *LinkForm;
LinkForm = GetFirstNode (&FormSet->FormListHead);
while (!IsNull (&FormSet->FormListHead, LinkForm)) {
Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm);
Link = GetFirstNode (&Form->StatementListHead); Link = GetFirstNode (&Form->StatementListHead);
while (!IsNull (&Form->StatementListHead, Link)) { while (!IsNull (&Form->StatementListHead, Link)) {
@ -1710,6 +1714,9 @@ NoSubmitCheck (
Link = GetNextNode (&Form->StatementListHead, Link); Link = GetNextNode (&Form->StatementListHead, Link);
} }
LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);
}
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -1738,7 +1745,7 @@ SubmitForm (
// //
// Validate the Form by NoSubmit check // Validate the Form by NoSubmit check
// //
Status = NoSubmitCheck (FormSet, Form); Status = NoSubmitCheck (FormSet);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }