From 5adb8db71e333069509269f832b356adab0678c0 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Wed, 2 Jun 2010 02:05:47 +0000 Subject: 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 --- .../Universal/DriverSampleDxe/DriverSample.c | 131 +++++++---- .../Universal/DriverSampleDxe/VfrStrings.uni | Bin 47290 -> 48460 bytes .../Universal/Network/IScsiDxe/IScsiConfig.c | 7 + .../Universal/Network/Ip4ConfigDxe/Ip4ConfigNv.c | 7 + .../Network/VlanConfigDxe/VlanConfigImpl.c | 15 +- .../PlatformDriOverrideDxe/PlatDriOverrideDxe.c | 9 +- .../Universal/SetupBrowserDxe/Presentation.c | 246 ++++++++++++++------- MdeModulePkg/Universal/SetupBrowserDxe/Setup.c | 31 ++- 8 files changed, 306 insertions(+), 140 deletions(-) diff --git a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c index e490ca45d8..efd260512a 100644 --- a/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c +++ b/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c @@ -842,61 +842,67 @@ DriverCallback ( UINTN MyVarSize; if (Action == EFI_BROWSER_ACTION_FORM_OPEN) { - // - // On FORM_OPEN event, update the form on-the-fly - // - PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This); - - // - // Initialize the container for dynamic opcodes - // - StartOpCodeHandle = HiiAllocateOpCodeHandle (); - ASSERT (StartOpCodeHandle != NULL); - - // - // Create Hii Extend Label OpCode as the start opcode - // - StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); - StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; - StartLabel->Number = LABEL_UPDATE2; + if (QuestionId == 0x1234) { + // + // 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); - HiiCreateActionOpCode ( - StartOpCodeHandle, // Container for dynamic created opcodes - 0x1238, // Question ID - STRING_TOKEN(STR_SAVE_TEXT), // Prompt text - STRING_TOKEN(STR_SAVE_TEXT), // Help text - EFI_IFR_FLAG_CALLBACK, // Question flag - 0 // Action String ID - ); + // + // Initialize the container for dynamic opcodes + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + ASSERT (StartOpCodeHandle != NULL); - HiiUpdateForm ( - PrivateData->HiiHandle[0], // HII handle - &mFormSetGuid, // Formset GUID - 0x3, // Form ID - StartOpCodeHandle, // Label for where to insert opcodes - NULL // Insert data + // + // Create Hii Extend Label OpCode as the start opcode + // + StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = LABEL_UPDATE2; + + HiiCreateActionOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + 0x1238, // Question ID + STRING_TOKEN(STR_SAVE_TEXT), // Prompt text + STRING_TOKEN(STR_SAVE_TEXT), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + 0 // Action String ID ); - HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiUpdateForm ( + PrivateData->HiiHandle[0], // HII handle + &mFormSetGuid, // Formset GUID + 0x3, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + NULL // Insert data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + } return EFI_SUCCESS; } if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) { - // - // On FORM_CLOSE event, show up a pop-up - // - do { - CreatePopUp ( - EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, - &Key, - L"", - L"You are going to leave the Form!", - L"Press ESC or ENTER to continue ...", - L"", - NULL - ); - } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); - + if (QuestionId == 0x5678) { + // + // Sample CallBack for UEFI FORM_CLOSE action: + // Show up a pop-up to specify Form 3 will be closed when exit Form 3. + // + do { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"", + L"You are going to leave third Form!", + L"Press ESC or ENTER to continue ...", + L"", + NULL + ); + } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN)); + } return EFI_SUCCESS; } @@ -1028,6 +1034,37 @@ DriverCallback ( 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 ( StartOpCodeHandle, // Container for dynamic created opcodes 1, // Target Form ID diff --git a/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni b/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni index 0fc0016082..4abcfa2cd7 100644 Binary files a/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni and b/MdeModulePkg/Universal/DriverSampleDxe/VfrStrings.uni differ diff --git a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.c b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.c index 4eb76aca63..2f9806e20a 100644 --- a/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.c +++ b/MdeModulePkg/Universal/Network/IScsiDxe/IScsiConfig.c @@ -562,6 +562,13 @@ IScsiFormCallback ( EFI_STATUS Status; 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); // diff --git a/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigNv.c b/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigNv.c index d660e403ba..c0d27aac78 100644 --- a/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigNv.c +++ b/MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigNv.c @@ -670,6 +670,13 @@ Ip4FormCallback ( EFI_STATUS Status; 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); IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA)); diff --git a/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c b/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c index 82ffcf2215..57fe339129 100644 --- a/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c +++ b/MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c @@ -237,11 +237,20 @@ VlanCallback ( PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This); if (Action == EFI_BROWSER_ACTION_FORM_OPEN) { + if (QuestionId == VLAN_ADD_QUESTION_ID) { + // + // 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); + } + return EFI_SUCCESS; + } + + if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) { // - // On FORM_OPEN event, update current VLAN list + // Do nothing for UEFI FORM_CLOSE action // - VlanUpdateForm (PrivateData); - return EFI_SUCCESS; } diff --git a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c index 1e5481ef72..70f29998ba 100644 --- a/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c +++ b/MdeModulePkg/Universal/PlatformDriOverrideDxe/PlatDriOverrideDxe.c @@ -1334,7 +1334,14 @@ PlatOverMngrCallback ( EFI_STRING_ID NewStringToken; EFI_INPUT_KEY Key; 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); FakeNvData = &Private->FakeNvData; if (!HiiGetBrowserData (&mPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData)) { diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c index a89bb2f50b..e9b4df4df9 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c @@ -842,6 +842,8 @@ FormUpdateNotify ( return EFI_SUCCESS; } +BOOLEAN mFormCloseCallBack = FALSE; + /** The worker function that send the displays to the screen. On output, the selection made by user is returned. @@ -870,10 +872,16 @@ SetupBrowser ( EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess; FORM_BROWSER_FORMSET *FormSet; EFI_INPUT_KEY Key; + BOOLEAN FormOpenCallBack; + BOOLEAN SubmitFormIsRequired; + EFI_GUID CurrentFormSetGuid; + EFI_HII_HANDLE CurrentHiiHandle; + UINT16 CurrentFormId; gMenuRefreshHead = NULL; gResetRequired = FALSE; FormSet = Selection->FormSet; + ConfigAccess = Selection->FormSet->ConfigAccess; // // Register notify for Form package update @@ -890,53 +898,6 @@ SetupBrowser ( 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 // @@ -950,7 +911,13 @@ SetupBrowser ( // // Initialize Selection->Form // + FormOpenCallBack = FALSE; if (Selection->FormId == 0) { + // + // First Form will open. + // + FormOpenCallBack = TRUE; + // // Zero FormId indicates display the first Form in a FormSet // @@ -959,6 +926,12 @@ SetupBrowser ( Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link); Selection->FormId = Selection->Form->FormId; } else { + if (Selection->Form == NULL) { + // + // First Form will open. + // + FormOpenCallBack = TRUE; + } Selection->Form = IdToForm (Selection->FormSet, Selection->FormId); } @@ -989,12 +962,100 @@ SetupBrowser ( return EFI_NOT_FOUND; } } - + + // + // Keep current form information + // + CurrentHiiHandle = Selection->Handle; + CopyGuid (&CurrentFormSetGuid, &Selection->FormSetGuid); + CurrentFormId = Selection->FormId; + // // Reset FormPackage update flag // 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 // @@ -1003,6 +1064,12 @@ SetupBrowser ( 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 // @@ -1119,41 +1186,66 @@ SetupBrowser ( 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 - // - if ((ConfigAccess != NULL) && (Selection->Action == UI_ACTION_EXIT)) { - ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; - Status = ConfigAccess->Callback ( - ConfigAccess, - EFI_BROWSER_ACTION_FORM_CLOSE, - 0, - EFI_IFR_TYPE_UNDEFINED, - NULL, - &ActionRequest - ); - - if (!EFI_ERROR (Status)) { - switch (ActionRequest) { - case EFI_BROWSER_ACTION_REQUEST_RESET: - gResetRequired = TRUE; - break; + // + // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE + // for each question with callback flag. + // + 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; + } - case EFI_BROWSER_ACTION_REQUEST_SUBMIT: - SubmitForm (Selection->FormSet, Selection->Form); - break; + ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; + Status = ConfigAccess->Callback ( + ConfigAccess, + EFI_BROWSER_ACTION_FORM_CLOSE, + Statement->QuestionId, + EFI_IFR_TYPE_UNDEFINED, + NULL, + &ActionRequest + ); - case EFI_BROWSER_ACTION_REQUEST_EXIT: - gNvUpdateRequired = FALSE; - break; + if (!EFI_ERROR (Status)) { + switch (ActionRequest) { + case EFI_BROWSER_ACTION_REQUEST_RESET: + gResetRequired = TRUE; + break; - default: - 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); } } - } + } while (Selection->Action == UI_ACTION_REFRESH_FORM); // // Record the old formset diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c index d25bcdf86f..e06228d4aa 100644 --- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c +++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c @@ -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 Form Form data structure. @retval EFI_SUCCESS Form validation pass. @retval other Form validation failed. @@ -1690,24 +1689,32 @@ ValidateQuestion ( **/ EFI_STATUS NoSubmitCheck ( - IN FORM_BROWSER_FORMSET *FormSet, - IN FORM_BROWSER_FORM *Form + IN FORM_BROWSER_FORMSET *FormSet ) { EFI_STATUS Status; LIST_ENTRY *Link; FORM_BROWSER_STATEMENT *Question; + FORM_BROWSER_FORM *Form; + LIST_ENTRY *LinkForm; - Link = GetFirstNode (&Form->StatementListHead); - while (!IsNull (&Form->StatementListHead, Link)) { - Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link); + LinkForm = GetFirstNode (&FormSet->FormListHead); + while (!IsNull (&FormSet->FormListHead, LinkForm)) { + Form = FORM_BROWSER_FORM_FROM_LINK (LinkForm); - Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_NO_SUBMIT_IF); - if (EFI_ERROR (Status)) { - return Status; + Link = GetFirstNode (&Form->StatementListHead); + while (!IsNull (&Form->StatementListHead, Link)) { + Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link); + + Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_NO_SUBMIT_IF); + if (EFI_ERROR (Status)) { + return Status; + } + + Link = GetNextNode (&Form->StatementListHead, Link); } - Link = GetNextNode (&Form->StatementListHead, Link); + LinkForm = GetNextNode (&FormSet->FormListHead, LinkForm); } return EFI_SUCCESS; @@ -1738,7 +1745,7 @@ SubmitForm ( // // Validate the Form by NoSubmit check // - Status = NoSubmitCheck (FormSet, Form); + Status = NoSubmitCheck (FormSet); if (EFI_ERROR (Status)) { return Status; } -- cgit v1.2.3