2 Utility functions for UI presentation.
4 Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 BOOLEAN mHiiPackageListUpdated
;
18 UI_MENU_SELECTION
*gCurrentSelection
;
19 EFI_HII_HANDLE mCurrentHiiHandle
= NULL
;
20 EFI_GUID mCurrentFormSetGuid
= {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
21 UINT16 mCurrentFormId
= 0;
22 EFI_EVENT mValueChangedEvent
= NULL
;
23 LIST_ENTRY mRefreshEventList
= INITIALIZE_LIST_HEAD_VARIABLE (mRefreshEventList
);
24 UINT16 mCurFakeQestId
;
25 FORM_DISPLAY_ENGINE_FORM gDisplayFormData
;
26 BOOLEAN mFinishRetrieveCall
= FALSE
;
29 Evaluate all expressions in a Form.
31 @param FormSet FormSet this Form belongs to.
34 @retval EFI_SUCCESS The expression evaluated successfuly
38 EvaluateFormExpressions (
39 IN FORM_BROWSER_FORMSET
*FormSet
,
40 IN FORM_BROWSER_FORM
*Form
45 FORM_EXPRESSION
*Expression
;
47 Link
= GetFirstNode (&Form
->ExpressionListHead
);
48 while (!IsNull (&Form
->ExpressionListHead
, Link
)) {
49 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
50 Link
= GetNextNode (&Form
->ExpressionListHead
, Link
);
52 if (Expression
->Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
||
53 Expression
->Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
||
54 Expression
->Type
== EFI_HII_EXPRESSION_WARNING_IF
||
55 Expression
->Type
== EFI_HII_EXPRESSION_WRITE
||
56 (Expression
->Type
== EFI_HII_EXPRESSION_READ
&& Form
->FormType
!= STANDARD_MAP_FORM_TYPE
)) {
58 // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.
63 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
64 if (EFI_ERROR (Status
)) {
73 Add empty function for event process function.
75 @param Event The Event need to be process
76 @param Context The context of the event.
81 SetupBrowserEmptyFunction (
89 Base on the opcode buffer info to get the display statement.
91 @param OpCode The input opcode buffer for this statement.
93 @retval Statement The statement use this opcode buffer.
96 FORM_DISPLAY_ENGINE_STATEMENT
*
98 IN EFI_IFR_OP_HEADER
*OpCode
101 FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
;
104 Link
= GetFirstNode (&gDisplayFormData
.StatementListHead
);
105 while (!IsNull (&gDisplayFormData
.StatementListHead
, Link
)) {
106 DisplayStatement
= FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link
);
108 if (DisplayStatement
->OpCode
== OpCode
) {
109 return DisplayStatement
;
111 Link
= GetNextNode (&gDisplayFormData
.StatementListHead
, Link
);
118 Free the refresh event list.
127 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
129 while (!IsListEmpty (&mRefreshEventList
)) {
130 Link
= GetFirstNode (&mRefreshEventList
);
131 EventNode
= FORM_BROWSER_REFRESH_EVENT_FROM_LINK (Link
);
132 RemoveEntryList (&EventNode
->Link
);
134 gBS
->CloseEvent (EventNode
->RefreshEvent
);
136 FreePool (EventNode
);
141 Check whether this statement value is changed. If yes, update the statement value and return TRUE;
144 @param Statement The statement need to check.
149 IN OUT FORM_BROWSER_STATEMENT
*Statement
152 GetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithHiiDriver
);
155 // Reset FormPackage update flag
157 mHiiPackageListUpdated
= FALSE
;
160 // Question value may be changed, need invoke its Callback()
162 ProcessCallBackFunction (gCurrentSelection
, gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, EFI_BROWSER_ACTION_RETRIEVE
, FALSE
);
164 if (mHiiPackageListUpdated
) {
166 // Package list is updated, force to reparse IFR binary of target Formset
168 mHiiPackageListUpdated
= FALSE
;
169 gCurrentSelection
->Action
= UI_ACTION_REFRESH_FORMSET
;
174 Refresh the question which has refresh guid event attribute.
176 @param Event The event which has this function related.
177 @param Context The input context info related to this event or the status code return to the caller.
186 FORM_BROWSER_STATEMENT
*Statement
;
188 Statement
= (FORM_BROWSER_STATEMENT
*)Context
;
189 UpdateStatement(Statement
);
190 gBS
->SignalEvent (mValueChangedEvent
);
195 Create refresh hook event for statement which has refresh event or interval.
197 @param Statement The statement need to check.
202 IN FORM_BROWSER_STATEMENT
*Statement
206 EFI_EVENT RefreshEvent
;
207 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
210 // If question has refresh guid, create the notify function.
212 Status
= gBS
->CreateEventEx (
217 &Statement
->RefreshGuid
,
219 ASSERT_EFI_ERROR (Status
);
221 EventNode
= AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE
));
222 ASSERT (EventNode
!= NULL
);
223 EventNode
->RefreshEvent
= RefreshEvent
;
224 InsertTailList(&mRefreshEventList
, &EventNode
->Link
);
229 Initialize the Display statement structure data.
231 @param DisplayStatement Pointer to the display Statement data strucure.
232 @param Statement The statement need to check.
235 InitializeDisplayStatement (
236 IN OUT FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
,
237 IN FORM_BROWSER_STATEMENT
*Statement
241 QUESTION_OPTION
*Option
;
242 DISPLAY_QUESTION_OPTION
*DisplayOption
;
243 FORM_DISPLAY_ENGINE_STATEMENT
*ParentStatement
;
245 DisplayStatement
->Signature
= FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE
;
246 DisplayStatement
->Version
= FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1
;
247 DisplayStatement
->OpCode
= Statement
->OpCode
;
248 InitializeListHead (&DisplayStatement
->NestStatementList
);
249 InitializeListHead (&DisplayStatement
->OptionListHead
);
251 if ((EvaluateExpressionList(Statement
->Expression
, FALSE
, NULL
, NULL
) == ExpressGrayOut
) || Statement
->Locked
) {
252 DisplayStatement
->Attribute
|= HII_DISPLAY_GRAYOUT
;
254 if ((Statement
->ValueExpression
!= NULL
) || ((Statement
->QuestionFlags
& EFI_IFR_FLAG_READ_ONLY
) != 0)) {
255 DisplayStatement
->Attribute
|= HII_DISPLAY_READONLY
;
259 // Initilize the option list in statement.
261 Link
= GetFirstNode (&Statement
->OptionListHead
);
262 while (!IsNull (&Statement
->OptionListHead
, Link
)) {
263 Option
= QUESTION_OPTION_FROM_LINK (Link
);
264 Link
= GetNextNode (&Statement
->OptionListHead
, Link
);
265 if ((Option
->SuppressExpression
!= NULL
) &&
266 ((EvaluateExpressionList(Option
->SuppressExpression
, FALSE
, NULL
, NULL
) == ExpressSuppress
))) {
270 DisplayOption
= AllocateZeroPool (sizeof (DISPLAY_QUESTION_OPTION
));
271 ASSERT (DisplayOption
!= NULL
);
273 DisplayOption
->ImageId
= Option
->ImageId
;
274 DisplayOption
->Signature
= DISPLAY_QUESTION_OPTION_SIGNATURE
;
275 DisplayOption
->OptionOpCode
= Option
->OpCode
;
276 InsertTailList(&DisplayStatement
->OptionListHead
, &DisplayOption
->Link
);
279 CopyMem (&DisplayStatement
->CurrentValue
, &Statement
->HiiValue
, sizeof (EFI_HII_VALUE
));
282 // Some special op code need an extra buffer to save the data.
283 // Such as string, password, orderedlist...
285 if (Statement
->BufferValue
!= NULL
) {
287 // Ordered list opcode may not initilized, get default value here.
289 if (Statement
->OpCode
->OpCode
== EFI_IFR_ORDERED_LIST_OP
&& GetArrayData (Statement
->BufferValue
, Statement
->ValueType
, 0) == 0) {
290 GetQuestionDefault (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, 0);
293 DisplayStatement
->CurrentValue
.Buffer
= AllocateCopyPool(Statement
->StorageWidth
,Statement
->BufferValue
);
294 DisplayStatement
->CurrentValue
.BufferLen
= Statement
->StorageWidth
;
297 DisplayStatement
->SettingChangedFlag
= Statement
->ValueChanged
;
300 // Get the highlight statement for current form.
302 if (((gCurrentSelection
->QuestionId
!= 0) && (Statement
->QuestionId
== gCurrentSelection
->QuestionId
)) ||
303 ((mCurFakeQestId
!= 0) && (Statement
->FakeQuestionId
== mCurFakeQestId
))) {
304 gDisplayFormData
.HighLightedStatement
= DisplayStatement
;
308 // Create the refresh event process function.
310 if (!CompareGuid (&Statement
->RefreshGuid
, &gZeroGuid
)) {
311 CreateRefreshEvent (Statement
);
315 // For RTC type of date/time, set default refresh interval to be 1 second.
317 if ((Statement
->Operand
== EFI_IFR_DATE_OP
|| Statement
->Operand
== EFI_IFR_TIME_OP
) && Statement
->Storage
== NULL
) {
318 Statement
->RefreshInterval
= 1;
322 // Create the refresh guid hook event.
323 // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.
325 if ((!CompareGuid (&Statement
->RefreshGuid
, &gZeroGuid
)) || (Statement
->RefreshInterval
!= 0)) {
326 gDisplayFormData
.FormRefreshEvent
= mValueChangedEvent
;
330 // Save the password check function for later use.
332 if (Statement
->Operand
== EFI_IFR_PASSWORD_OP
) {
333 DisplayStatement
->PasswordCheck
= PasswordCheck
;
337 // If this statement is nest in the subtitle, insert to the host statement.
338 // else insert to the form it belongs to.
340 if (Statement
->ParentStatement
!= NULL
) {
341 ParentStatement
= GetDisplayStatement(Statement
->ParentStatement
->OpCode
);
342 ASSERT (ParentStatement
!= NULL
);
343 InsertTailList(&ParentStatement
->NestStatementList
, &DisplayStatement
->DisplayLink
);
345 InsertTailList(&gDisplayFormData
.StatementListHead
, &DisplayStatement
->DisplayLink
);
350 Process for the refresh interval statement.
352 @param Event The Event need to be process
353 @param Context The context of the event.
358 RefreshIntervalProcess (
363 FORM_BROWSER_STATEMENT
*Statement
;
366 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
367 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
368 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
369 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
371 if (Statement
->RefreshInterval
== 0) {
375 UpdateStatement(Statement
);
378 gBS
->SignalEvent (mValueChangedEvent
);
383 Make a copy of the global hotkey info.
391 BROWSER_HOT_KEY
*HotKey
;
392 BROWSER_HOT_KEY
*CopyKey
;
395 Link
= GetFirstNode (&gBrowserHotKeyList
);
396 while (!IsNull (&gBrowserHotKeyList
, Link
)) {
397 HotKey
= BROWSER_HOT_KEY_FROM_LINK (Link
);
399 CopyKey
= AllocateCopyPool(sizeof (BROWSER_HOT_KEY
), HotKey
);
400 ASSERT (CopyKey
!= NULL
);
401 CopyKey
->KeyData
= AllocateCopyPool(sizeof (EFI_INPUT_KEY
), HotKey
->KeyData
);
402 ASSERT (CopyKey
->KeyData
!= NULL
);
403 CopyKey
->HelpString
= AllocateCopyPool(StrSize (HotKey
->HelpString
), HotKey
->HelpString
);
404 ASSERT (CopyKey
->HelpString
!= NULL
);
406 InsertTailList(&gDisplayFormData
.HotKeyListHead
, &CopyKey
->Link
);
408 Link
= GetNextNode (&gBrowserHotKeyList
, Link
);
414 Get the extra question attribute from override question list.
416 @param QuestionId The question id for this request question.
418 @retval The attribute for this question or NULL if not found this
419 question in the list.
423 ProcessQuestionExtraAttr (
424 IN EFI_QUESTION_ID QuestionId
428 QUESTION_ATTRIBUTE_OVERRIDE
*QuestionDesc
;
431 // Return HII_DISPLAY_NONE if input a invalid question id.
433 if (QuestionId
== 0) {
434 return HII_DISPLAY_NONE
;
437 Link
= GetFirstNode (&mPrivateData
.FormBrowserEx2
.OverrideQestListHead
);
438 while (!IsNull (&mPrivateData
.FormBrowserEx2
.OverrideQestListHead
, Link
)) {
439 QuestionDesc
= FORM_QUESTION_ATTRIBUTE_OVERRIDE_FROM_LINK (Link
);
440 Link
= GetNextNode (&mPrivateData
.FormBrowserEx2
.OverrideQestListHead
, Link
);
442 if ((QuestionDesc
->QuestionId
== QuestionId
) &&
443 (QuestionDesc
->FormId
== gCurrentSelection
->FormId
) &&
444 (QuestionDesc
->HiiHandle
== gCurrentSelection
->Handle
) &&
445 CompareGuid (&QuestionDesc
->FormSetGuid
, &gCurrentSelection
->FormSetGuid
)) {
446 return QuestionDesc
->Attribute
;
450 return HII_DISPLAY_NONE
;
455 Enum all statement in current form, find all the statement can be display and
456 add to the display form.
460 AddStatementToDisplayForm (
466 FORM_BROWSER_STATEMENT
*Statement
;
467 FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
;
468 UINT8 MinRefreshInterval
;
469 EFI_EVENT RefreshIntervalEvent
;
470 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
471 BOOLEAN FormEditable
;
472 UINT32 ExtraAttribute
;
474 MinRefreshInterval
= 0;
475 FormEditable
= FALSE
;
478 // Process the statement outside the form, these statements are not recognized
481 Link
= GetFirstNode (&gCurrentSelection
->FormSet
->StatementListOSF
);
482 while (!IsNull (&gCurrentSelection
->FormSet
->StatementListOSF
, Link
)) {
483 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
484 Link
= GetNextNode (&gCurrentSelection
->FormSet
->StatementListOSF
, Link
);
486 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
487 ASSERT (DisplayStatement
!= NULL
);
488 DisplayStatement
->Signature
= FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE
;
489 DisplayStatement
->Version
= FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1
;
490 DisplayStatement
->OpCode
= Statement
->OpCode
;
492 InitializeListHead (&DisplayStatement
->NestStatementList
);
493 InitializeListHead (&DisplayStatement
->OptionListHead
);
495 InsertTailList(&gDisplayFormData
.StatementListOSF
, &DisplayStatement
->DisplayLink
);
499 // Process the statement in this form.
501 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
502 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
503 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
504 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
507 // This statement can't be show, skip it.
509 if (EvaluateExpressionList(Statement
->Expression
, FALSE
, NULL
, NULL
) > ExpressGrayOut
) {
514 // Check the extra attribute.
516 ExtraAttribute
= ProcessQuestionExtraAttr (Statement
->QuestionId
);
517 if ((ExtraAttribute
& HII_DISPLAY_SUPPRESS
) != 0) {
521 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
522 ASSERT (DisplayStatement
!= NULL
);
525 // Initialize this statement and add it to the display form.
527 InitializeDisplayStatement(DisplayStatement
, Statement
);
530 // Set the extra attribute.
532 DisplayStatement
->Attribute
|= ExtraAttribute
;
534 if (Statement
->Storage
!= NULL
) {
539 // Get the minimal refresh interval value for later use.
541 if ((Statement
->RefreshInterval
!= 0) &&
542 (MinRefreshInterval
== 0 || Statement
->RefreshInterval
< MinRefreshInterval
)) {
543 MinRefreshInterval
= Statement
->RefreshInterval
;
548 // Create the periodic timer for refresh interval statement.
550 if (MinRefreshInterval
!= 0) {
551 Status
= gBS
->CreateEvent (EVT_TIMER
| EVT_NOTIFY_SIGNAL
, TPL_CALLBACK
, RefreshIntervalProcess
, NULL
, &RefreshIntervalEvent
);
552 ASSERT_EFI_ERROR (Status
);
553 Status
= gBS
->SetTimer (RefreshIntervalEvent
, TimerPeriodic
, MinRefreshInterval
* ONE_SECOND
);
554 ASSERT_EFI_ERROR (Status
);
556 EventNode
= AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE
));
557 ASSERT (EventNode
!= NULL
);
558 EventNode
->RefreshEvent
= RefreshIntervalEvent
;
559 InsertTailList(&mRefreshEventList
, &EventNode
->Link
);
563 // Update hotkey list field.
565 if (gBrowserSettingScope
== SystemLevel
|| FormEditable
) {
572 Initialize the SettingChangedFlag variable in the display form.
576 UpdateDataChangedFlag (
581 FORM_BROWSER_FORMSET
*LocalFormSet
;
583 gDisplayFormData
.SettingChangedFlag
= FALSE
;
585 if (IsNvUpdateRequiredForForm (gCurrentSelection
->Form
)) {
586 gDisplayFormData
.SettingChangedFlag
= TRUE
;
591 // Base on the system level to check whether need to show the NV flag.
593 switch (gBrowserSettingScope
) {
596 // Check the maintain list to see whether there is any change.
598 Link
= GetFirstNode (&gBrowserFormSetList
);
599 while (!IsNull (&gBrowserFormSetList
, Link
)) {
600 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
601 if (IsNvUpdateRequiredForFormSet(LocalFormSet
)) {
602 gDisplayFormData
.SettingChangedFlag
= TRUE
;
605 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
610 if (IsNvUpdateRequiredForFormSet(gCurrentSelection
->FormSet
)) {
611 gDisplayFormData
.SettingChangedFlag
= TRUE
;
623 Initialize the Display form structure data.
627 InitializeDisplayFormData (
633 gDisplayFormData
.Signature
= FORM_DISPLAY_ENGINE_FORM_SIGNATURE
;
634 gDisplayFormData
.Version
= FORM_DISPLAY_ENGINE_VERSION_1
;
635 gDisplayFormData
.ImageId
= 0;
636 gDisplayFormData
.AnimationId
= 0;
638 InitializeListHead (&gDisplayFormData
.StatementListHead
);
639 InitializeListHead (&gDisplayFormData
.StatementListOSF
);
640 InitializeListHead (&gDisplayFormData
.HotKeyListHead
);
642 Status
= gBS
->CreateEvent (
645 SetupBrowserEmptyFunction
,
649 ASSERT_EFI_ERROR (Status
);
654 Free the kotkey info saved in form data.
662 BROWSER_HOT_KEY
*HotKey
;
665 while (!IsListEmpty (&gDisplayFormData
.HotKeyListHead
)) {
666 Link
= GetFirstNode (&gDisplayFormData
.HotKeyListHead
);
667 HotKey
= BROWSER_HOT_KEY_FROM_LINK (Link
);
669 RemoveEntryList (&HotKey
->Link
);
671 FreePool (HotKey
->KeyData
);
672 FreePool (HotKey
->HelpString
);
679 Update the Display form structure data.
683 UpdateDisplayFormData (
687 gDisplayFormData
.FormTitle
= gCurrentSelection
->Form
->FormTitle
;
688 gDisplayFormData
.FormId
= gCurrentSelection
->FormId
;
689 gDisplayFormData
.HiiHandle
= gCurrentSelection
->Handle
;
690 CopyGuid (&gDisplayFormData
.FormSetGuid
, &gCurrentSelection
->FormSetGuid
);
692 gDisplayFormData
.Attribute
= 0;
693 gDisplayFormData
.Attribute
|= gCurrentSelection
->Form
->ModalForm
? HII_DISPLAY_MODAL
: 0;
694 gDisplayFormData
.Attribute
|= gCurrentSelection
->Form
->Locked
? HII_DISPLAY_LOCK
: 0;
696 gDisplayFormData
.FormRefreshEvent
= NULL
;
697 gDisplayFormData
.HighLightedStatement
= NULL
;
699 UpdateDataChangedFlag ();
701 AddStatementToDisplayForm ();
706 Free the Display Statement structure data.
708 @param StatementList Point to the statement list which need to be free.
713 LIST_ENTRY
*StatementList
717 LIST_ENTRY
*OptionLink
;
718 FORM_DISPLAY_ENGINE_STATEMENT
*Statement
;
719 DISPLAY_QUESTION_OPTION
*Option
;
722 // Free Statements/Questions
724 while (!IsListEmpty (StatementList
)) {
725 Link
= GetFirstNode (StatementList
);
726 Statement
= FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link
);
731 while (!IsListEmpty (&Statement
->OptionListHead
)) {
732 OptionLink
= GetFirstNode (&Statement
->OptionListHead
);
733 Option
= DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink
);
734 RemoveEntryList (&Option
->Link
);
739 // Free nest statement List
741 if (!IsListEmpty (&Statement
->NestStatementList
)) {
742 FreeStatementData(&Statement
->NestStatementList
);
745 RemoveEntryList (&Statement
->DisplayLink
);
746 FreePool (Statement
);
752 Free the Display form structure data.
756 FreeDisplayFormData (
760 FreeStatementData (&gDisplayFormData
.StatementListHead
);
761 FreeStatementData (&gDisplayFormData
.StatementListOSF
);
770 Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
772 @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
774 @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
777 FORM_BROWSER_STATEMENT
*
778 GetBrowserStatement (
779 IN FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
782 FORM_BROWSER_STATEMENT
*Statement
;
785 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
786 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
787 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
789 if (Statement
->OpCode
== DisplayStatement
->OpCode
) {
793 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
800 Update the ValueChanged status for questions in this form.
802 @param FormSet FormSet data structure.
803 @param Form Form data structure.
807 UpdateStatementStatusForForm (
808 IN FORM_BROWSER_FORMSET
*FormSet
,
809 IN FORM_BROWSER_FORM
*Form
813 FORM_BROWSER_STATEMENT
*Question
;
815 Link
= GetFirstNode (&Form
->StatementListHead
);
816 while (!IsNull (&Form
->StatementListHead
, Link
)) {
817 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
818 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
821 // For password opcode, not set the the value changed flag.
823 if (Question
->Operand
== EFI_IFR_PASSWORD_OP
) {
827 IsQuestionValueChanged(FormSet
, Form
, Question
, GetSetValueWithBuffer
);
832 Update the ValueChanged status for questions in this formset.
834 @param FormSet FormSet data structure.
838 UpdateStatementStatusForFormSet (
839 IN FORM_BROWSER_FORMSET
*FormSet
843 FORM_BROWSER_FORM
*Form
;
845 Link
= GetFirstNode (&FormSet
->FormListHead
);
846 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
847 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
848 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
850 UpdateStatementStatusForForm (FormSet
, Form
);
855 Update the ValueChanged status for questions.
857 @param FormSet FormSet data structure.
858 @param Form Form data structure.
859 @param SettingScope Setting Scope for Default action.
863 UpdateStatementStatus (
864 IN FORM_BROWSER_FORMSET
*FormSet
,
865 IN FORM_BROWSER_FORM
*Form
,
866 IN BROWSER_SETTING_SCOPE SettingScope
870 FORM_BROWSER_FORMSET
*LocalFormSet
;
872 switch (SettingScope
) {
874 Link
= GetFirstNode (&gBrowserFormSetList
);
875 while (!IsNull (&gBrowserFormSetList
, Link
)) {
876 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
877 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
878 if (!ValidateFormSet(LocalFormSet
)) {
882 UpdateStatementStatusForFormSet (LocalFormSet
);
887 UpdateStatementStatusForFormSet (FormSet
);
891 UpdateStatementStatusForForm (FormSet
, Form
);
901 Process the action request in user input.
903 @param Action The user input action request info.
904 @param DefaultId The user input default Id info.
906 @retval EFI_SUCESSS This function always return successfully for now.
916 // This is caused by use press ESC, and it should not combine with other action type.
918 if ((Action
& BROWSER_ACTION_FORM_EXIT
) == BROWSER_ACTION_FORM_EXIT
) {
919 FindNextMenu (gCurrentSelection
, FormLevel
);
924 // Below is normal hotkey trigged action, these action maybe combine with each other.
926 if ((Action
& BROWSER_ACTION_DISCARD
) == BROWSER_ACTION_DISCARD
) {
927 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
930 if ((Action
& BROWSER_ACTION_DEFAULT
) == BROWSER_ACTION_DEFAULT
) {
931 ExtractDefault (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, DefaultId
, gBrowserSettingScope
, GetDefaultForAll
, NULL
, FALSE
);
932 UpdateStatementStatus (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
935 if ((Action
& BROWSER_ACTION_SUBMIT
) == BROWSER_ACTION_SUBMIT
) {
936 SubmitForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
939 if ((Action
& BROWSER_ACTION_RESET
) == BROWSER_ACTION_RESET
) {
940 gResetRequired
= TRUE
;
943 if ((Action
& BROWSER_ACTION_EXIT
) == BROWSER_ACTION_EXIT
) {
945 // Form Exit without saving, Similar to ESC Key.
946 // FormSet Exit without saving, Exit SendForm.
947 // System Exit without saving, CallExitHandler and Exit SendForm.
949 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
950 if (gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) {
951 FindNextMenu (gCurrentSelection
, gBrowserSettingScope
);
952 } else if (gBrowserSettingScope
== SystemLevel
) {
953 if (ExitHandlerFunction
!= NULL
) {
954 ExitHandlerFunction ();
956 gCurrentSelection
->Action
= UI_ACTION_EXIT
;
964 Check whether the formset guid is in this Hii package list.
966 @param HiiHandle The HiiHandle for this HII package list.
967 @param FormSetGuid The formset guid for the request formset.
969 @retval TRUE Find the formset guid.
970 @retval FALSE Not found the formset guid.
974 GetFormsetGuidFromHiiHandle (
975 IN EFI_HII_HANDLE HiiHandle
,
976 IN EFI_GUID
*FormSetGuid
979 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
983 UINT32 PackageListLength
;
984 EFI_HII_PACKAGE_HEADER PackageHeader
;
991 HiiPackageList
= NULL
;
994 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
995 if (Status
== EFI_BUFFER_TOO_SMALL
) {
996 HiiPackageList
= AllocatePool (BufferSize
);
997 ASSERT (HiiPackageList
!= NULL
);
999 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
1001 if (EFI_ERROR (Status
) || HiiPackageList
== NULL
) {
1006 // Get Form package from this HII package List
1008 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
1010 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
1012 while (Offset
< PackageListLength
) {
1013 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
1014 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
1015 Offset
+= PackageHeader
.Length
;
1017 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
1019 // Search FormSet in this Form Package
1021 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
1022 while (Offset2
< PackageHeader
.Length
) {
1023 OpCodeData
= Package
+ Offset2
;
1025 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
1026 if (CompareGuid (FormSetGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))){
1032 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1040 FreePool (HiiPackageList
);
1046 Find HII Handle in the HII database associated with given Device Path.
1048 If DevicePath is NULL, then ASSERT.
1050 @param DevicePath Device Path associated with the HII package list
1052 @param FormsetGuid The formset guid for this formset.
1054 @retval Handle HII package list Handle associated with the Device
1056 @retval NULL Hii Package list handle is not found.
1060 DevicePathToHiiHandle (
1061 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
1062 IN EFI_GUID
*FormsetGuid
1066 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
1069 EFI_HANDLE DriverHandle
;
1070 EFI_HII_HANDLE
*HiiHandles
;
1071 EFI_HII_HANDLE HiiHandle
;
1073 ASSERT (DevicePath
!= NULL
);
1075 TmpDevicePath
= DevicePath
;
1077 // Locate Device Path Protocol handle buffer
1079 Status
= gBS
->LocateDevicePath (
1080 &gEfiDevicePathProtocolGuid
,
1084 if (EFI_ERROR (Status
) || !IsDevicePathEnd (TmpDevicePath
)) {
1089 // Retrieve all HII Handles from HII database
1091 HiiHandles
= HiiGetHiiHandles (NULL
);
1092 if (HiiHandles
== NULL
) {
1097 // Search Hii Handle by Driver Handle
1100 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
1101 Status
= mHiiDatabase
->GetPackageListHandle (
1106 if (!EFI_ERROR (Status
) && (Handle
== DriverHandle
)) {
1107 if (GetFormsetGuidFromHiiHandle(HiiHandles
[Index
], FormsetGuid
)) {
1108 HiiHandle
= HiiHandles
[Index
];
1112 if (HiiHandle
!= NULL
) {
1118 FreePool (HiiHandles
);
1123 Find HII Handle in the HII database associated with given form set guid.
1125 If FormSetGuid is NULL, then ASSERT.
1127 @param ComparingGuid FormSet Guid associated with the HII package list
1130 @retval Handle HII package list Handle associated with the Device
1132 @retval NULL Hii Package list handle is not found.
1136 FormSetGuidToHiiHandle (
1137 EFI_GUID
*ComparingGuid
1140 EFI_HII_HANDLE
*HiiHandles
;
1141 EFI_HII_HANDLE HiiHandle
;
1144 ASSERT (ComparingGuid
!= NULL
);
1148 // Get all the Hii handles
1150 HiiHandles
= HiiGetHiiHandles (NULL
);
1151 ASSERT (HiiHandles
!= NULL
);
1154 // Search for formset of each class type
1156 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
1157 if (GetFormsetGuidFromHiiHandle(HiiHandles
[Index
], ComparingGuid
)) {
1158 HiiHandle
= HiiHandles
[Index
];
1162 if (HiiHandle
!= NULL
) {
1167 FreePool (HiiHandles
);
1173 check how to process the changed data in current form or form set.
1175 @param Selection On input, Selection tell setup browser the information
1176 about the Selection, form and formset to be displayed.
1177 On output, Selection return the screen item that is selected
1180 @param Scope Data save or discard scope, form or formset.
1182 @retval TRUE Success process the changed data, will return to the parent form.
1183 @retval FALSE Reject to process the changed data, will stay at current form.
1186 ProcessChangedData (
1187 IN OUT UI_MENU_SELECTION
*Selection
,
1188 IN BROWSER_SETTING_SCOPE Scope
1195 switch (mFormDisplay
->ConfirmDataChange()) {
1196 case BROWSER_ACTION_DISCARD
:
1197 DiscardForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1200 case BROWSER_ACTION_SUBMIT
:
1201 Status
= SubmitForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1202 if (EFI_ERROR (Status
)) {
1207 case BROWSER_ACTION_NONE
:
1213 // if Invalid value return, process same as BROWSER_ACTION_NONE.
1223 Find parent formset menu(the first menu which has different formset) for current menu.
1224 If not find, just return to the first menu.
1226 @param Selection The selection info.
1231 IN OUT UI_MENU_SELECTION
*Selection
1234 FORM_ENTRY_INFO
*CurrentMenu
;
1235 FORM_ENTRY_INFO
*ParentMenu
;
1237 CurrentMenu
= Selection
->CurrentMenu
;
1238 ParentMenu
= UiFindParentMenu(CurrentMenu
, FormSetLevel
);
1240 if (ParentMenu
!= NULL
) {
1241 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1242 Selection
->Handle
= ParentMenu
->HiiHandle
;
1243 Selection
->FormId
= ParentMenu
->FormId
;
1244 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1246 Selection
->FormId
= CurrentMenu
->FormId
;
1247 Selection
->QuestionId
= CurrentMenu
->QuestionId
;
1250 Selection
->Statement
= NULL
;
1254 Process the goto op code, update the info in the selection structure.
1256 @param Statement The statement belong to goto op code.
1257 @param Selection The selection info.
1259 @retval EFI_SUCCESS The menu process successfully.
1260 @return Other value if the process failed.
1264 IN OUT FORM_BROWSER_STATEMENT
*Statement
,
1265 IN OUT UI_MENU_SELECTION
*Selection
1269 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1270 FORM_BROWSER_FORM
*RefForm
;
1272 EFI_HII_HANDLE HiiHandle
;
1274 Status
= EFI_SUCCESS
;
1279 // Prepare the device path check, get the device path info first.
1281 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0) {
1282 StringPtr
= GetToken (Statement
->HiiValue
.Value
.ref
.DevicePath
, Selection
->FormSet
->HiiHandle
);
1286 // Check whether the device path string is a valid string.
1288 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0 && StringPtr
!= NULL
&& StringPtr
[0] != L
'\0') {
1289 if (Selection
->Form
->ModalForm
) {
1294 // Goto another Hii Package list
1296 if (mPathFromText
!= NULL
) {
1297 DevicePath
= mPathFromText
->ConvertTextToDevicePath(StringPtr
);
1298 if (DevicePath
!= NULL
) {
1299 HiiHandle
= DevicePathToHiiHandle (DevicePath
, &Statement
->HiiValue
.Value
.ref
.FormSetGuid
);
1300 FreePool (DevicePath
);
1302 FreePool (StringPtr
);
1305 // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
1307 PopupErrorMessage(BROWSER_PROTOCOL_NOT_FOUND
, NULL
, NULL
, NULL
);
1308 FreePool (StringPtr
);
1312 if (HiiHandle
!= Selection
->Handle
) {
1314 // Goto another Formset, check for uncommitted data
1316 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1317 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1318 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1324 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1325 Selection
->Handle
= HiiHandle
;
1326 if (Selection
->Handle
== NULL
) {
1328 // If target Hii Handle not found, exit current formset.
1330 FindParentFormSet(Selection
);
1334 CopyMem (&Selection
->FormSetGuid
,&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1335 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1336 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1337 } else if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &gZeroGuid
)) {
1338 if (Selection
->Form
->ModalForm
) {
1341 if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &Selection
->FormSetGuid
)) {
1343 // Goto another Formset, check for uncommitted data
1345 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1346 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1347 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1353 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1354 Selection
->Handle
= FormSetGuidToHiiHandle(&Statement
->HiiValue
.Value
.ref
.FormSetGuid
);
1355 if (Selection
->Handle
== NULL
) {
1357 // If target Hii Handle not found, exit current formset.
1359 FindParentFormSet(Selection
);
1363 CopyMem (&Selection
->FormSetGuid
, &Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1364 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1365 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1366 } else if (Statement
->HiiValue
.Value
.ref
.FormId
!= 0) {
1368 // Goto another Form, check for uncommitted data
1370 if (Statement
->HiiValue
.Value
.ref
.FormId
!= Selection
->FormId
) {
1371 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm(Selection
->Form
))) {
1372 if (!ProcessChangedData (Selection
, FormLevel
)) {
1378 RefForm
= IdToForm (Selection
->FormSet
, Statement
->HiiValue
.Value
.ref
.FormId
);
1379 if ((RefForm
!= NULL
) && (RefForm
->SuppressExpression
!= NULL
)) {
1380 if (EvaluateExpressionList(RefForm
->SuppressExpression
, TRUE
, Selection
->FormSet
, RefForm
) != ExpressFalse
) {
1382 // Form is suppressed.
1384 PopupErrorMessage(BROWSER_FORM_SUPPRESS
, NULL
, NULL
, NULL
);
1389 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1390 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1391 } else if (Statement
->HiiValue
.Value
.ref
.QuestionId
!= 0) {
1392 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1400 Process Question Config.
1402 @param Selection The UI menu selection.
1403 @param Question The Question to be peocessed.
1405 @retval EFI_SUCCESS Question Config process success.
1406 @retval Other Question Config process fail.
1410 ProcessQuestionConfig (
1411 IN UI_MENU_SELECTION
*Selection
,
1412 IN FORM_BROWSER_STATEMENT
*Question
1419 if (Question
->QuestionConfig
== 0) {
1426 ConfigResp
= GetToken (Question
->QuestionConfig
, Selection
->FormSet
->HiiHandle
);
1427 if (ConfigResp
== NULL
) {
1428 return EFI_NOT_FOUND
;
1432 // Send config to Configuration Driver
1434 Status
= mHiiConfigRouting
->RouteConfig (
1445 Process the user input data.
1447 @param UserInput The user input data.
1448 @param ChangeHighlight Whether need to change the highlight statement.
1450 @retval EFI_SUCESSS This function always return successfully for now.
1455 IN USER_INPUT
*UserInput
,
1456 IN BOOLEAN ChangeHighlight
1460 FORM_BROWSER_STATEMENT
*Statement
;
1462 Status
= EFI_SUCCESS
;
1465 // When Exit from FormDisplay function, one of the below two cases must be true.
1467 ASSERT (UserInput
->Action
!= 0 || UserInput
->SelectedStatement
!= NULL
);
1470 // Remove the last highligh question id, this id will update when show next form.
1472 gCurrentSelection
->QuestionId
= 0;
1475 // First process the Action field in USER_INPUT.
1477 if (UserInput
->Action
!= 0) {
1478 Status
= ProcessAction (UserInput
->Action
, UserInput
->DefaultId
);
1479 if (EFI_ERROR (Status
)) {
1484 // Clear the highlight info.
1486 gCurrentSelection
->Statement
= NULL
;
1488 if (UserInput
->SelectedStatement
!= NULL
) {
1489 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1490 ASSERT (Statement
!= NULL
);
1492 // Save the current highlight menu in the menu history data.
1493 // which will be used when later browse back to this form.
1495 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1497 // For statement like text, actio, it not has question id.
1498 // So use FakeQuestionId to save the question.
1500 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1501 mCurFakeQestId
= Statement
->FakeQuestionId
;
1507 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1508 ASSERT (Statement
!= NULL
);
1510 gCurrentSelection
->Statement
= Statement
;
1512 if (ChangeHighlight
) {
1514 // This question is the current user select one,record it and later
1515 // show it as the highlight question.
1517 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1519 // For statement like text, actio, it not has question id.
1520 // So use FakeQuestionId to save the question.
1522 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1523 mCurFakeQestId
= Statement
->FakeQuestionId
;
1529 switch (Statement
->Operand
) {
1530 case EFI_IFR_REF_OP
:
1531 Status
= ProcessGotoOpCode(Statement
, gCurrentSelection
);
1534 case EFI_IFR_ACTION_OP
:
1536 // Process the Config string <ConfigResp>
1538 Status
= ProcessQuestionConfig (gCurrentSelection
, Statement
);
1541 case EFI_IFR_RESET_BUTTON_OP
:
1543 // Reset Question to default value specified by DefaultId
1545 Status
= ExtractDefault (gCurrentSelection
->FormSet
, NULL
, Statement
->DefaultId
, FormSetLevel
, GetDefaultForAll
, NULL
, FALSE
);
1546 UpdateStatementStatus (gCurrentSelection
->FormSet
, NULL
, FormSetLevel
);
1550 switch (Statement
->Operand
) {
1551 case EFI_IFR_STRING_OP
:
1552 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1553 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1554 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1555 FreePool (UserInput
->InputValue
.Buffer
);
1558 case EFI_IFR_PASSWORD_OP
:
1559 if (UserInput
->InputValue
.Buffer
== NULL
) {
1561 // User not input new password, just return.
1566 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1567 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1568 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1569 FreePool (UserInput
->InputValue
.Buffer
);
1571 // Two password match, send it to Configuration Driver
1573 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
1574 PasswordCheck (NULL
, UserInput
->SelectedStatement
, (CHAR16
*) Statement
->BufferValue
);
1576 // Clean the value after saved it.
1578 ZeroMem (Statement
->BufferValue
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1579 HiiSetString (gCurrentSelection
->FormSet
->HiiHandle
, Statement
->HiiValue
.Value
.string
, (CHAR16
*)Statement
->BufferValue
, NULL
);
1581 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithHiiDriver
);
1585 case EFI_IFR_ORDERED_LIST_OP
:
1586 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, UserInput
->InputValue
.BufferLen
);
1590 CopyMem (&Statement
->HiiValue
, &UserInput
->InputValue
, sizeof (EFI_HII_VALUE
));
1602 Display form and wait for user to select one menu option, then return it.
1604 @retval EFI_SUCESSS This function always return successfully for now.
1613 USER_INPUT UserInput
;
1614 FORM_ENTRY_INFO
*CurrentMenu
;
1615 BOOLEAN ChangeHighlight
;
1617 ZeroMem (&UserInput
, sizeof (USER_INPUT
));
1620 // Update the menu history data.
1622 CurrentMenu
= UiFindMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
, gCurrentSelection
->FormId
);
1623 if (CurrentMenu
== NULL
) {
1625 // Current menu not found, add it to the menu tree
1627 CurrentMenu
= UiAddMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
,
1628 gCurrentSelection
->FormId
, gCurrentSelection
->QuestionId
);
1629 ASSERT (CurrentMenu
!= NULL
);
1633 // Back up the form view history data for this form.
1635 UiCopyMenuList(&gCurrentSelection
->Form
->FormViewListHead
, &mPrivateData
.FormBrowserEx2
.FormViewHistoryHead
);
1637 gCurrentSelection
->CurrentMenu
= CurrentMenu
;
1640 // Find currrent highlight statement.
1642 if (gCurrentSelection
->QuestionId
== 0) {
1644 // Highlight not specified, fetch it from cached menu
1646 gCurrentSelection
->QuestionId
= CurrentMenu
->QuestionId
;
1650 // Evaluate all the Expressions in this Form
1652 Status
= EvaluateFormExpressions (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
);
1653 if (EFI_ERROR (Status
)) {
1657 UpdateDisplayFormData ();
1660 // Three possible status maybe return.
1662 // EFI_INVALID_PARAMETER: The input dimension info is not valid.
1663 // EFI_NOT_FOUND: The input value for oneof/orderedlist opcode is not valid
1664 // and an valid value has return.
1665 // EFI_SUCCESS: Success shows form and get user input in UserInput paramenter.
1667 ASSERT (gDisplayFormData
.BrowserStatus
== BROWSER_SUCCESS
);
1668 Status
= mFormDisplay
->FormDisplay (&gDisplayFormData
, &UserInput
);
1669 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_FOUND
) {
1670 FreeDisplayFormData();
1675 // If status is EFI_SUCCESS, means user has change the highlight menu and new user input return.
1676 // in this case, browser need to change the highlight menu.
1677 // If status is EFI_NOT_FOUND, means the input DisplayFormData has error for oneof/orderedlist
1678 // opcode and new valid value has return, browser core need to adjust
1679 // value for this opcode and shows this form again.
1681 ChangeHighlight
= (Status
== EFI_SUCCESS
? TRUE
:FALSE
);
1683 Status
= ProcessUserInput (&UserInput
, ChangeHighlight
);
1685 FreeDisplayFormData();
1691 Functions which are registered to receive notification of
1692 database events have this prototype. The actual event is encoded
1693 in NotifyType. The following table describes how PackageType,
1694 PackageGuid, Handle, and Package are used for each of the
1697 @param PackageType Package type of the notification.
1699 @param PackageGuid If PackageType is
1700 EFI_HII_PACKAGE_TYPE_GUID, then this is
1701 the pointer to the GUID from the Guid
1702 field of EFI_HII_PACKAGE_GUID_HEADER.
1703 Otherwise, it must be NULL.
1705 @param Package Points to the package referred to by the
1706 notification Handle The handle of the package
1707 list which contains the specified package.
1709 @param Handle The HII handle.
1711 @param NotifyType The type of change concerning the
1713 EFI_HII_DATABASE_NOTIFY_TYPE.
1719 IN UINT8 PackageType
,
1720 IN CONST EFI_GUID
*PackageGuid
,
1721 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
1722 IN EFI_HII_HANDLE Handle
,
1723 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
1726 mHiiPackageListUpdated
= TRUE
;
1732 Update the NV flag info for this form set.
1734 @param FormSet FormSet data structure.
1738 IsNvUpdateRequiredForFormSet (
1739 IN FORM_BROWSER_FORMSET
*FormSet
1743 FORM_BROWSER_FORM
*Form
;
1747 // Not finished question initialization, return FALSE.
1749 if (!FormSet
->QuestionInited
) {
1755 Link
= GetFirstNode (&FormSet
->FormListHead
);
1756 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
1757 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
1759 RetVal
= IsNvUpdateRequiredForForm(Form
);
1764 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
1771 Update the NvUpdateRequired flag for a form.
1773 @param Form Form data structure.
1777 IsNvUpdateRequiredForForm (
1778 IN FORM_BROWSER_FORM
*Form
1782 FORM_BROWSER_STATEMENT
*Statement
;
1784 Link
= GetFirstNode (&Form
->StatementListHead
);
1785 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1786 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1788 if (Statement
->ValueChanged
) {
1792 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1799 Find menu which will show next time.
1801 @param Selection On input, Selection tell setup browser the information
1802 about the Selection, form and formset to be displayed.
1803 On output, Selection return the screen item that is selected
1805 @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.
1806 else, we need to exit current formset.
1808 @retval TRUE Exit current form.
1809 @retval FALSE User press ESC and keep in current form.
1813 IN OUT UI_MENU_SELECTION
*Selection
,
1814 IN BROWSER_SETTING_SCOPE SettingLevel
1817 FORM_ENTRY_INFO
*CurrentMenu
;
1818 FORM_ENTRY_INFO
*ParentMenu
;
1819 BROWSER_SETTING_SCOPE Scope
;
1821 CurrentMenu
= Selection
->CurrentMenu
;
1822 Scope
= FormSetLevel
;
1824 ParentMenu
= UiFindParentMenu(CurrentMenu
, SettingLevel
);
1825 while (ParentMenu
!= NULL
&& !ValidateHiiHandle(ParentMenu
->HiiHandle
)) {
1826 ParentMenu
= UiFindParentMenu(ParentMenu
, SettingLevel
);
1829 if (ParentMenu
!= NULL
) {
1830 if (CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1833 Scope
= FormSetLevel
;
1838 // Form Level Check whether the data is changed.
1840 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm (Selection
->Form
)) ||
1841 (gBrowserSettingScope
== FormSetLevel
&& IsNvUpdateRequiredForFormSet(Selection
->FormSet
) && Scope
== FormSetLevel
)) {
1842 if (!ProcessChangedData(Selection
, gBrowserSettingScope
)) {
1847 if (ParentMenu
!= NULL
) {
1849 // ParentMenu is found. Then, go to it.
1851 if (Scope
== FormLevel
) {
1852 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
1854 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1855 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1856 Selection
->Handle
= ParentMenu
->HiiHandle
;
1859 Selection
->Statement
= NULL
;
1861 Selection
->FormId
= ParentMenu
->FormId
;
1862 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1865 // Clear highlight record for this menu
1867 CurrentMenu
->QuestionId
= 0;
1872 // Current in root page, exit the SendForm
1874 Selection
->Action
= UI_ACTION_EXIT
;
1880 Call the call back function for the question and process the return action.
1882 @param Selection On input, Selection tell setup browser the information
1883 about the Selection, form and formset to be displayed.
1884 On output, Selection return the screen item that is selected
1886 @param FormSet The formset this question belong to.
1887 @param Form The form this question belong to.
1888 @param Question The Question which need to call.
1889 @param Action The action request.
1890 @param SkipSaveOrDiscard Whether skip save or discard action.
1892 @retval EFI_SUCCESS The call back function excutes successfully.
1893 @return Other value if the call back function failed to excute.
1896 ProcessCallBackFunction (
1897 IN OUT UI_MENU_SELECTION
*Selection
,
1898 IN FORM_BROWSER_FORMSET
*FormSet
,
1899 IN FORM_BROWSER_FORM
*Form
,
1900 IN FORM_BROWSER_STATEMENT
*Question
,
1901 IN EFI_BROWSER_ACTION Action
,
1902 IN BOOLEAN SkipSaveOrDiscard
1906 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
1907 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1908 EFI_HII_VALUE
*HiiValue
;
1909 EFI_IFR_TYPE_VALUE
*TypeValue
;
1910 FORM_BROWSER_STATEMENT
*Statement
;
1911 BOOLEAN SubmitFormIsRequired
;
1912 BOOLEAN DiscardFormIsRequired
;
1915 BROWSER_SETTING_SCOPE SettingLevel
;
1916 EFI_IFR_TYPE_VALUE BackUpValue
;
1917 UINT8
*BackUpBuffer
;
1920 ConfigAccess
= FormSet
->ConfigAccess
;
1921 SubmitFormIsRequired
= FALSE
;
1922 SettingLevel
= FormSetLevel
;
1923 DiscardFormIsRequired
= FALSE
;
1925 Status
= EFI_SUCCESS
;
1926 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1927 BackUpBuffer
= NULL
;
1929 if (ConfigAccess
== NULL
) {
1933 Link
= GetFirstNode (&Form
->StatementListHead
);
1934 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1935 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1936 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1939 // if Question != NULL, only process the question. Else, process all question in this form.
1941 if ((Question
!= NULL
) && (Statement
!= Question
)) {
1945 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) {
1950 // Check whether Statement is disabled.
1952 if (Statement
->Expression
!= NULL
) {
1953 if (EvaluateExpressionList(Statement
->Expression
, TRUE
, FormSet
, Form
) == ExpressDisable
) {
1958 HiiValue
= &Statement
->HiiValue
;
1959 TypeValue
= &HiiValue
->Value
;
1960 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
1962 // For OrderedList, passing in the value buffer to Callback()
1964 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
1968 // If EFI_BROWSER_ACTION_CHANGING type, back up the new question value.
1970 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1971 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
1972 BackUpBuffer
= AllocateCopyPool(Statement
->StorageWidth
+ sizeof(CHAR16
), Statement
->BufferValue
);
1973 ASSERT (BackUpBuffer
!= NULL
);
1975 CopyMem (&BackUpValue
, &HiiValue
->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1979 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1980 Status
= ConfigAccess
->Callback (
1983 Statement
->QuestionId
,
1989 // IFR is updated, force to reparse the IFR binary
1991 if (mHiiPackageListUpdated
) {
1992 if (BackUpBuffer
!= NULL
) {
1993 FreePool (BackUpBuffer
);
1999 if (!EFI_ERROR (Status
)) {
2001 // Need to sync the value between Statement->HiiValue->Value and Statement->BufferValue
2003 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2004 NewString
= GetToken (Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
2005 ASSERT (NewString
!= NULL
);
2007 ASSERT (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
);
2008 if (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
) {
2009 CopyMem (Statement
->BufferValue
, NewString
, StrSize (NewString
));
2011 CopyMem (Statement
->BufferValue
, NewString
, Statement
->StorageWidth
);
2013 FreePool (NewString
);
2017 // Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.
2020 case EFI_BROWSER_ACTION_CHANGED
:
2021 switch (ActionRequest
) {
2022 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2023 DiscardFormIsRequired
= TRUE
;
2024 gResetRequired
= TRUE
;
2028 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2029 SubmitFormIsRequired
= TRUE
;
2033 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2034 DiscardFormIsRequired
= TRUE
;
2038 case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
:
2039 SubmitFormIsRequired
= TRUE
;
2040 SettingLevel
= FormLevel
;
2044 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
:
2045 DiscardFormIsRequired
= TRUE
;
2046 SettingLevel
= FormLevel
;
2050 case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
:
2051 SubmitFormIsRequired
= TRUE
;
2052 SettingLevel
= FormLevel
;
2055 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
:
2056 DiscardFormIsRequired
= TRUE
;
2057 SettingLevel
= FormLevel
;
2065 case EFI_BROWSER_ACTION_CHANGING
:
2067 // Do the question validation.
2069 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2070 if (!EFI_ERROR (Status
)) {
2072 // According the spec, return value from call back of "changing" and
2073 // "retrieve" should update to the question's temp buffer.
2075 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2079 case EFI_BROWSER_ACTION_RETRIEVE
:
2081 // According the spec, return value from call back of "changing" and
2082 // "retrieve" should update to the question's temp buffer.
2084 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2092 // If the callback returns EFI_UNSUPPORTED for EFI_BROWSER_ACTION_CHANGING,
2093 // then the browser will use the value passed to Callback() and ignore the
2094 // value returned by Callback().
2096 if (Action
== EFI_BROWSER_ACTION_CHANGING
&& Status
== EFI_UNSUPPORTED
) {
2097 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2098 CopyMem (Statement
->BufferValue
, BackUpBuffer
, Statement
->StorageWidth
+ sizeof(CHAR16
));
2100 CopyMem (&HiiValue
->Value
, &BackUpValue
, sizeof (EFI_IFR_TYPE_VALUE
));
2104 // Do the question validation.
2106 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2107 if (!EFI_ERROR (Status
)) {
2108 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2113 // According the spec, return fail from call back of "changing" and
2114 // "retrieve", should restore the question's value.
2116 if ((Action
== EFI_BROWSER_ACTION_CHANGING
&& Status
!= EFI_UNSUPPORTED
) ||
2117 Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
2118 GetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2121 if (Status
== EFI_UNSUPPORTED
) {
2123 // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.
2125 Status
= EFI_SUCCESS
;
2129 if (BackUpBuffer
!= NULL
) {
2130 FreePool (BackUpBuffer
);
2134 // If Question != NULL, means just process one question
2135 // and if code reach here means this question has finished
2136 // processing, so just break.
2138 if (Question
!= NULL
) {
2143 if (SubmitFormIsRequired
&& !SkipSaveOrDiscard
) {
2144 SubmitForm (FormSet
, Form
, SettingLevel
);
2147 if (DiscardFormIsRequired
&& !SkipSaveOrDiscard
) {
2148 DiscardForm (FormSet
, Form
, SettingLevel
);
2152 FindNextMenu (Selection
, SettingLevel
);
2159 Call the retrieve type call back function for one question to get the initialize data.
2161 This function only used when in the initialize stage, because in this stage, the
2162 Selection->Form is not ready. For other case, use the ProcessCallBackFunction instead.
2164 @param ConfigAccess The config access protocol produced by the hii driver.
2165 @param Statement The Question which need to call.
2166 @param FormSet The formset this question belong to.
2168 @retval EFI_SUCCESS The call back function excutes successfully.
2169 @return Other value if the call back function failed to excute.
2172 ProcessRetrieveForQuestion (
2173 IN EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
,
2174 IN FORM_BROWSER_STATEMENT
*Statement
,
2175 IN FORM_BROWSER_FORMSET
*FormSet
2179 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2180 EFI_HII_VALUE
*HiiValue
;
2181 EFI_IFR_TYPE_VALUE
*TypeValue
;
2184 Status
= EFI_SUCCESS
;
2185 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2187 if (((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) || ConfigAccess
== NULL
) {
2188 return EFI_UNSUPPORTED
;
2191 HiiValue
= &Statement
->HiiValue
;
2192 TypeValue
= &HiiValue
->Value
;
2193 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2195 // For OrderedList, passing in the value buffer to Callback()
2197 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
2200 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2201 Status
= ConfigAccess
->Callback (
2203 EFI_BROWSER_ACTION_RETRIEVE
,
2204 Statement
->QuestionId
,
2209 if (!EFI_ERROR (Status
) && HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2210 NewString
= GetToken (Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
2211 ASSERT (NewString
!= NULL
);
2213 ASSERT (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
);
2214 if (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
) {
2215 CopyMem (Statement
->BufferValue
, NewString
, StrSize (NewString
));
2217 CopyMem (Statement
->BufferValue
, NewString
, Statement
->StorageWidth
);
2219 FreePool (NewString
);
2226 The worker function that send the displays to the screen. On output,
2227 the selection made by user is returned.
2229 @param Selection On input, Selection tell setup browser the information
2230 about the Selection, form and formset to be displayed.
2231 On output, Selection return the screen item that is selected
2234 @retval EFI_SUCCESS The page is displayed successfully.
2235 @return Other value if the page failed to be diplayed.
2240 IN OUT UI_MENU_SELECTION
*Selection
2245 EFI_HANDLE NotifyHandle
;
2246 FORM_BROWSER_STATEMENT
*Statement
;
2247 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
2249 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
2252 // Register notify for Form package update
2254 Status
= mHiiDatabase
->RegisterPackageNotify (
2256 EFI_HII_PACKAGE_FORMS
,
2259 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2262 if (EFI_ERROR (Status
)) {
2267 // Initialize current settings of Questions in this FormSet
2269 InitializeCurrentSetting (Selection
->FormSet
);
2272 // Initilize Action field.
2274 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
2277 // Clean the mCurFakeQestId value is formset refreshed.
2283 // IFR is updated, force to reparse the IFR binary
2284 // This check is shared by EFI_BROWSER_ACTION_FORM_CLOSE and
2285 // EFI_BROWSER_ACTION_RETRIEVE, so code place here.
2287 if (mHiiPackageListUpdated
) {
2288 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2289 mHiiPackageListUpdated
= FALSE
;
2294 // Initialize Selection->Form
2296 if (Selection
->FormId
== 0) {
2298 // Zero FormId indicates display the first Form in a FormSet
2300 Link
= GetFirstNode (&Selection
->FormSet
->FormListHead
);
2302 Selection
->Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2303 Selection
->FormId
= Selection
->Form
->FormId
;
2305 Selection
->Form
= IdToForm (Selection
->FormSet
, Selection
->FormId
);
2308 if (Selection
->Form
== NULL
) {
2310 // No Form to display
2312 Status
= EFI_NOT_FOUND
;
2317 // Check Form is suppressed.
2319 if (Selection
->Form
->SuppressExpression
!= NULL
) {
2320 if (EvaluateExpressionList(Selection
->Form
->SuppressExpression
, TRUE
, Selection
->FormSet
, Selection
->Form
) == ExpressSuppress
) {
2322 // Form is suppressed.
2324 PopupErrorMessage(BROWSER_FORM_SUPPRESS
, NULL
, NULL
, NULL
);
2325 Status
= EFI_NOT_FOUND
;
2331 // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN
2332 // for each question with callback flag.
2333 // New form may be the first form, or the different form after another form close.
2335 if (((Selection
->Handle
!= mCurrentHiiHandle
) ||
2336 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2337 (Selection
->FormId
!= mCurrentFormId
))) {
2339 // Update Retrieve flag.
2341 mFinishRetrieveCall
= FALSE
;
2344 // Keep current form information
2346 mCurrentHiiHandle
= Selection
->Handle
;
2347 CopyGuid (&mCurrentFormSetGuid
, &Selection
->FormSetGuid
);
2348 mCurrentFormId
= Selection
->FormId
;
2350 if (ConfigAccess
!= NULL
) {
2351 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_FORM_OPEN
, FALSE
);
2352 if (EFI_ERROR (Status
)) {
2357 // IFR is updated during callback of EFI_BROWSER_ACTION_FORM_OPEN, force to reparse the IFR binary
2359 if (mHiiPackageListUpdated
) {
2360 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2361 mHiiPackageListUpdated
= FALSE
;
2368 // Load Questions' Value for display
2370 Status
= LoadFormSetConfig (Selection
, Selection
->FormSet
);
2371 if (EFI_ERROR (Status
)) {
2375 if (!mFinishRetrieveCall
) {
2377 // Finish call RETRIEVE callback for this form.
2379 mFinishRetrieveCall
= TRUE
;
2381 if (ConfigAccess
!= NULL
) {
2382 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_RETRIEVE
, FALSE
);
2383 if (EFI_ERROR (Status
)) {
2388 // IFR is updated during callback of open form, force to reparse the IFR binary
2390 if (mHiiPackageListUpdated
) {
2391 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2392 mHiiPackageListUpdated
= FALSE
;
2401 Status
= DisplayForm ();
2402 if (EFI_ERROR (Status
)) {
2407 // Check Selected Statement (if press ESC, Selection->Statement will be NULL)
2409 Statement
= Selection
->Statement
;
2410 if (Statement
!= NULL
) {
2411 if ((ConfigAccess
!= NULL
) &&
2412 ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
) &&
2413 (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
2414 Status
= ProcessCallBackFunction(Selection
, Selection
->FormSet
, Selection
->Form
, Statement
, EFI_BROWSER_ACTION_CHANGING
, FALSE
);
2416 // IFR is updated during callback of EFI_BROWSER_ACTION_CHANGING, force to reparse the IFR binary
2418 if (mHiiPackageListUpdated
) {
2419 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2420 mHiiPackageListUpdated
= FALSE
;
2424 if (Statement
->Operand
== EFI_IFR_REF_OP
) {
2426 // Process dynamic update ref opcode.
2428 if (!EFI_ERROR (Status
)) {
2429 Status
= ProcessGotoOpCode(Statement
, Selection
);
2433 // Callback return error status or status return from process goto opcode.
2435 if (EFI_ERROR (Status
)) {
2437 // Cross reference will not be taken
2439 Selection
->FormId
= Selection
->Form
->FormId
;
2440 Selection
->QuestionId
= 0;
2445 // Verify whether question value has checked, update the ValueChanged flag in Question.
2447 IsQuestionValueChanged(gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithBuffer
);
2449 if (!EFI_ERROR (Status
) && Statement
->Operand
!= EFI_IFR_REF_OP
) {
2450 ProcessCallBackFunction(Selection
, Selection
->FormSet
, Selection
->Form
, Statement
, EFI_BROWSER_ACTION_CHANGED
, FALSE
);
2452 // IFR is updated during callback of EFI_BROWSER_ACTION_CHANGED, force to reparse the IFR binary
2454 if (mHiiPackageListUpdated
) {
2455 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2456 mHiiPackageListUpdated
= FALSE
;
2462 // Do the question validation.
2464 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2465 if (!EFI_ERROR (Status
) && (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
2466 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2468 // Verify whether question value has checked, update the ValueChanged flag in Question.
2470 IsQuestionValueChanged(gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithBuffer
);
2475 // If question has EFI_IFR_FLAG_RESET_REQUIRED flag and without storage and process question success till here,
2476 // trig the gResetFlag.
2478 if ((Status
== EFI_SUCCESS
) &&
2479 (Statement
->Storage
== NULL
) &&
2480 ((Statement
->QuestionFlags
& EFI_IFR_FLAG_RESET_REQUIRED
) != 0)) {
2481 gResetRequired
= TRUE
;
2486 // Check whether Exit flag is TRUE.
2488 if (gExitRequired
) {
2489 switch (gBrowserSettingScope
) {
2491 Selection
->Action
= UI_ACTION_EXIT
;
2496 FindNextMenu (Selection
, gBrowserSettingScope
);
2503 gExitRequired
= FALSE
;
2507 // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE
2508 // for each question with callback flag.
2510 if ((ConfigAccess
!= NULL
) &&
2511 ((Selection
->Action
== UI_ACTION_EXIT
) ||
2512 (Selection
->Handle
!= mCurrentHiiHandle
) ||
2513 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2514 (Selection
->FormId
!= mCurrentFormId
))) {
2516 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_FORM_CLOSE
, FALSE
);
2517 if (EFI_ERROR (Status
)) {
2521 } while (Selection
->Action
== UI_ACTION_REFRESH_FORM
);
2525 // Reset current form information to the initial setting when error happens or form exit.
2527 if (EFI_ERROR (Status
) || Selection
->Action
== UI_ACTION_EXIT
) {
2528 mCurrentHiiHandle
= NULL
;
2529 CopyGuid (&mCurrentFormSetGuid
, &gZeroGuid
);
2534 // Unregister notify for Form package update
2536 mHiiDatabase
->UnregisterPackageNotify (