UINTN MyVarSize;\r
\r
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
- //\r
- // On FORM_OPEN event, update the form on-the-fly\r
- //\r
- PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
-\r
- //\r
- // Initialize the container for dynamic opcodes\r
- //\r
- StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
- ASSERT (StartOpCodeHandle != NULL);\r
-\r
- //\r
- // Create Hii Extend Label OpCode as the start opcode\r
- //\r
- StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
- StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
- StartLabel->Number = LABEL_UPDATE2;\r
+ if (QuestionId == 0x1234) {\r
+ //\r
+ // Sample CallBack for UEFI FORM_OPEN action:\r
+ // Add Save action into Form 3 when Form 1 is opened.\r
+ // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.\r
+ //\r
+ PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
\r
- HiiCreateActionOpCode (\r
- StartOpCodeHandle, // Container for dynamic created opcodes\r
- 0x1238, // Question ID\r
- STRING_TOKEN(STR_SAVE_TEXT), // Prompt text\r
- STRING_TOKEN(STR_SAVE_TEXT), // Help text\r
- EFI_IFR_FLAG_CALLBACK, // Question flag\r
- 0 // Action String ID\r
- );\r
+ //\r
+ // Initialize the container for dynamic opcodes\r
+ //\r
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+ ASSERT (StartOpCodeHandle != NULL);\r
\r
- HiiUpdateForm (\r
- PrivateData->HiiHandle[0], // HII handle\r
- &mFormSetGuid, // Formset GUID\r
- 0x3, // Form ID\r
- StartOpCodeHandle, // Label for where to insert opcodes\r
- NULL // Insert data\r
+ //\r
+ // Create Hii Extend Label OpCode as the start opcode\r
+ //\r
+ StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+ StartLabel->Number = LABEL_UPDATE2;\r
+\r
+ HiiCreateActionOpCode (\r
+ StartOpCodeHandle, // Container for dynamic created opcodes\r
+ 0x1238, // Question ID\r
+ STRING_TOKEN(STR_SAVE_TEXT), // Prompt text\r
+ STRING_TOKEN(STR_SAVE_TEXT), // Help text\r
+ EFI_IFR_FLAG_CALLBACK, // Question flag\r
+ 0 // Action String ID\r
);\r
\r
- HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+ HiiUpdateForm (\r
+ PrivateData->HiiHandle[0], // HII handle\r
+ &mFormSetGuid, // Formset GUID\r
+ 0x3, // Form ID\r
+ StartOpCodeHandle, // Label for where to insert opcodes\r
+ NULL // Insert data\r
+ );\r
+\r
+ HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+ }\r
return EFI_SUCCESS;\r
}\r
\r
if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {\r
- //\r
- // On FORM_CLOSE event, show up a pop-up\r
- //\r
- do {\r
- CreatePopUp (\r
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
- &Key,\r
- L"",\r
- L"You are going to leave the Form!",\r
- L"Press ESC or ENTER to continue ...",\r
- L"",\r
- NULL\r
- );\r
- } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
-\r
+ if (QuestionId == 0x5678) {\r
+ //\r
+ // Sample CallBack for UEFI FORM_CLOSE action:\r
+ // Show up a pop-up to specify Form 3 will be closed when exit Form 3.\r
+ //\r
+ do {\r
+ CreatePopUp (\r
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+ &Key,\r
+ L"",\r
+ L"You are going to leave third Form!",\r
+ L"Press ESC or ENTER to continue ...",\r
+ L"",\r
+ NULL\r
+ );\r
+ } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
+ }\r
return EFI_SUCCESS;\r
}\r
\r
NULL // Default Opcode is NULl\r
);\r
\r
+ HiiCreateTextOpCode (\r
+ StartOpCodeHandle,\r
+ STRING_TOKEN(STR_TEXT_SAMPLE_HELP),\r
+ STRING_TOKEN(STR_TEXT_SAMPLE_HELP),\r
+ STRING_TOKEN(STR_TEXT_SAMPLE_STRING)\r
+ );\r
+\r
+ HiiCreateDateOpCode (\r
+ StartOpCodeHandle,\r
+ 0x8004,\r
+ 0x0,\r
+ 0x0,\r
+ STRING_TOKEN(STR_DATE_SAMPLE_HELP),\r
+ STRING_TOKEN(STR_DATE_SAMPLE_HELP),\r
+ 0,\r
+ QF_DATE_STORAGE_TIME,\r
+ NULL\r
+ );\r
+\r
+ HiiCreateTimeOpCode (\r
+ StartOpCodeHandle,\r
+ 0x8005,\r
+ 0x0,\r
+ 0x0,\r
+ STRING_TOKEN(STR_TIME_SAMPLE_HELP),\r
+ STRING_TOKEN(STR_TIME_SAMPLE_HELP),\r
+ 0,\r
+ QF_TIME_STORAGE_TIME,\r
+ NULL\r
+ );\r
+\r
HiiCreateGotoOpCode (\r
StartOpCodeHandle, // Container for dynamic created opcodes\r
1, // Target Form ID\r
return EFI_SUCCESS;\r
}\r
\r
+BOOLEAN mFormCloseCallBack = FALSE;\r
+\r
/**\r
The worker function that send the displays to the screen. On output,\r
the selection made by user is returned.\r
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
FORM_BROWSER_FORMSET *FormSet;\r
EFI_INPUT_KEY Key;\r
+ BOOLEAN FormOpenCallBack;\r
+ BOOLEAN SubmitFormIsRequired;\r
+ EFI_GUID CurrentFormSetGuid;\r
+ EFI_HII_HANDLE CurrentHiiHandle;\r
+ UINT16 CurrentFormId;\r
\r
gMenuRefreshHead = NULL;\r
gResetRequired = FALSE;\r
FormSet = Selection->FormSet;\r
+ ConfigAccess = Selection->FormSet->ConfigAccess;\r
\r
//\r
// Register notify for Form package update\r
return Status;\r
}\r
\r
- //\r
- // Before display the formset, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN\r
- //\r
- ConfigAccess = Selection->FormSet->ConfigAccess;\r
- if ((ConfigAccess != NULL) && (Selection->Action != UI_ACTION_REFRESH_FORMSET)) {\r
- ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
- mHiiPackageListUpdated = FALSE;\r
- Status = ConfigAccess->Callback (\r
- ConfigAccess,\r
- EFI_BROWSER_ACTION_FORM_OPEN,\r
- 0,\r
- EFI_IFR_TYPE_UNDEFINED,\r
- NULL,\r
- &ActionRequest\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- switch (ActionRequest) {\r
- case EFI_BROWSER_ACTION_REQUEST_RESET:\r
- gResetRequired = TRUE;\r
- break;\r
-\r
- case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
- //\r
- // Till now there is no uncommitted data, so ignore this request\r
- //\r
- break;\r
-\r
- case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
- Selection->Action = UI_ACTION_EXIT;\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- if (mHiiPackageListUpdated) {\r
- //\r
- // IFR is updated during callback, force to reparse the IFR binary\r
- //\r
- mHiiPackageListUpdated = FALSE;\r
- Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
- goto Done;\r
- }\r
- }\r
-\r
//\r
// Initialize current settings of Questions in this FormSet\r
//\r
//\r
// Initialize Selection->Form\r
//\r
+ FormOpenCallBack = FALSE;\r
if (Selection->FormId == 0) {\r
+ //\r
+ // First Form will open.\r
+ //\r
+ FormOpenCallBack = TRUE;\r
+\r
//\r
// Zero FormId indicates display the first Form in a FormSet\r
//\r
Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
Selection->FormId = Selection->Form->FormId;\r
} else {\r
+ if (Selection->Form == NULL) {\r
+ //\r
+ // First Form will open.\r
+ //\r
+ FormOpenCallBack = TRUE;\r
+ }\r
Selection->Form = IdToForm (Selection->FormSet, Selection->FormId);\r
}\r
\r
return EFI_NOT_FOUND;\r
}\r
}\r
- \r
+\r
+ //\r
+ // Keep current form information\r
+ //\r
+ CurrentHiiHandle = Selection->Handle;\r
+ CopyGuid (&CurrentFormSetGuid, &Selection->FormSetGuid);\r
+ CurrentFormId = Selection->FormId;\r
+\r
//\r
// Reset FormPackage update flag\r
//\r
mHiiPackageListUpdated = FALSE;\r
\r
+ //\r
+ // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN\r
+ // for each question with callback flag.\r
+ // New form may be the first form, or the different form after another form close.\r
+ //\r
+ if ((FormOpenCallBack || mFormCloseCallBack) && (ConfigAccess != NULL)) {\r
+ mFormCloseCallBack = FALSE;\r
+ //\r
+ // Go through each statement in this form\r
+ //\r
+ SubmitFormIsRequired = FALSE;\r
+ Link = GetFirstNode (&Selection->Form->StatementListHead);\r
+ while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+ \r
+ if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // Check whether Statement is disabled.\r
+ //\r
+ if (Statement->DisableExpression != NULL) {\r
+ Status = EvaluateExpression (Selection->FormSet, Selection->Form, Statement->DisableExpression);\r
+ if (!EFI_ERROR (Status) && \r
+ (Statement->DisableExpression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && \r
+ (Statement->DisableExpression->Result.Value.b)) {\r
+ continue;\r
+ }\r
+ }\r
+\r
+ ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+ Status = ConfigAccess->Callback (\r
+ ConfigAccess,\r
+ EFI_BROWSER_ACTION_FORM_OPEN,\r
+ Statement->QuestionId,\r
+ EFI_IFR_TYPE_UNDEFINED,\r
+ NULL,\r
+ &ActionRequest\r
+ );\r
+\r
+ if (!EFI_ERROR (Status)) {\r
+ switch (ActionRequest) {\r
+ case EFI_BROWSER_ACTION_REQUEST_RESET:\r
+ gResetRequired = TRUE;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
+ SubmitFormIsRequired = TRUE;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+ Selection->Action = UI_ACTION_EXIT;\r
+ gNvUpdateRequired = FALSE;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (SubmitFormIsRequired) {\r
+ SubmitForm (Selection->FormSet, Selection->Form);\r
+ }\r
+ //\r
+ // EXIT requests to close form.\r
+ //\r
+ if (Selection->Action == UI_ACTION_EXIT) {\r
+ goto Done;\r
+ }\r
+ //\r
+ // IFR is updated during callback of open form, force to reparse the IFR binary\r
+ //\r
+ if (mHiiPackageListUpdated) {\r
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
+ mHiiPackageListUpdated = FALSE;\r
+ goto Done;\r
+ }\r
+ }\r
+\r
//\r
// Load Questions' Value for display\r
//\r
return Status;\r
}\r
\r
+ //\r
+ // EXIT requests to close form.\r
+ //\r
+ if (Selection->Action == UI_ACTION_EXIT) {\r
+ goto Done;\r
+ }\r
//\r
// IFR is updated during callback of read value, force to reparse the IFR binary\r
//\r
Selection->Action = UI_ACTION_REFRESH_FORMSET;\r
}\r
}\r
- } while (Selection->Action == UI_ACTION_REFRESH_FORM);\r
\r
- //\r
- // Before exit the formset, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE\r
- //\r
- if ((ConfigAccess != NULL) && (Selection->Action == UI_ACTION_EXIT)) {\r
- ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
- Status = ConfigAccess->Callback (\r
- ConfigAccess,\r
- EFI_BROWSER_ACTION_FORM_CLOSE,\r
- 0,\r
- EFI_IFR_TYPE_UNDEFINED,\r
- NULL,\r
- &ActionRequest\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- switch (ActionRequest) {\r
- case EFI_BROWSER_ACTION_REQUEST_RESET:\r
- gResetRequired = TRUE;\r
- break;\r
+ //\r
+ // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE\r
+ // for each question with callback flag.\r
+ //\r
+ mFormCloseCallBack = FALSE;\r
+ if ((ConfigAccess != NULL) && \r
+ ((Selection->Action == UI_ACTION_EXIT) || \r
+ (Selection->Handle != CurrentHiiHandle) ||\r
+ (!CompareGuid (&CurrentFormSetGuid, &Selection->FormSetGuid)) ||\r
+ (Selection->FormId != CurrentFormId))) {\r
+ //\r
+ // Go through each statement in this form\r
+ //\r
+ mFormCloseCallBack = TRUE;\r
+ SubmitFormIsRequired = FALSE;\r
+ Link = GetFirstNode (&Selection->Form->StatementListHead);\r
+ while (!IsNull (&Selection->Form->StatementListHead, Link)) {\r
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ Link = GetNextNode (&Selection->Form->StatementListHead, Link);\r
+ \r
+ if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) {\r
+ continue;\r
+ }\r
\r
- case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
- SubmitForm (Selection->FormSet, Selection->Form);\r
- break;\r
+ ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+ Status = ConfigAccess->Callback (\r
+ ConfigAccess,\r
+ EFI_BROWSER_ACTION_FORM_CLOSE,\r
+ Statement->QuestionId,\r
+ EFI_IFR_TYPE_UNDEFINED,\r
+ NULL,\r
+ &ActionRequest\r
+ );\r
\r
- case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
- gNvUpdateRequired = FALSE;\r
- break;\r
+ if (!EFI_ERROR (Status)) {\r
+ switch (ActionRequest) {\r
+ case EFI_BROWSER_ACTION_REQUEST_RESET:\r
+ gResetRequired = TRUE;\r
+ break;\r
\r
- default:\r
- break;\r
+ case EFI_BROWSER_ACTION_REQUEST_SUBMIT:\r
+ SubmitFormIsRequired = TRUE;\r
+ break;\r
+\r
+ case EFI_BROWSER_ACTION_REQUEST_EXIT:\r
+ Selection->Action = UI_ACTION_EXIT;\r
+ gNvUpdateRequired = FALSE;\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ if (SubmitFormIsRequired) {\r
+ SubmitForm (Selection->FormSet, Selection->Form);\r
}\r
}\r
- }\r
+ } while (Selection->Action == UI_ACTION_REFRESH_FORM);\r
\r
//\r
// Record the old formset\r
\r
\r
/**\r
- Perform NoSubmit check for a Form.\r
+ Perform NoSubmit check for each Form in FormSet.\r
\r
@param FormSet FormSet data structure.\r
- @param Form Form data structure.\r
\r
@retval EFI_SUCCESS Form validation pass.\r
@retval other Form validation failed.\r
**/\r
EFI_STATUS\r
NoSubmitCheck (\r
- IN FORM_BROWSER_FORMSET *FormSet,\r
- IN FORM_BROWSER_FORM *Form\r
+ IN FORM_BROWSER_FORMSET *FormSet\r
)\r
{\r
EFI_STATUS Status;\r
LIST_ENTRY *Link;\r
FORM_BROWSER_STATEMENT *Question;\r
+ FORM_BROWSER_FORM *Form;\r
+ LIST_ENTRY *LinkForm;\r
\r
- Link = GetFirstNode (&Form->StatementListHead);\r
- while (!IsNull (&Form->StatementListHead, Link)) {\r
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+ LinkForm = GetFirstNode (&FormSet->FormListHead);\r
+ while (!IsNull (&FormSet->FormListHead, LinkForm)) {\r
+ Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm);\r
\r
- Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_NO_SUBMIT_IF);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ Link = GetFirstNode (&Form->StatementListHead);\r
+ while (!IsNull (&Form->StatementListHead, Link)) {\r
+ Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
+\r
+ Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_NO_SUBMIT_IF);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Link = GetNextNode (&Form->StatementListHead, Link);\r
}\r
\r
- Link = GetNextNode (&Form->StatementListHead, Link);\r
+ LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm);\r
}\r
\r
return EFI_SUCCESS;\r
//\r
// Validate the Form by NoSubmit check\r
//\r
- Status = NoSubmitCheck (FormSet, Form);\r
+ Status = NoSubmitCheck (FormSet);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r