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
);
820 IsQuestionValueChanged(FormSet
, Form
, Question
, GetSetValueWithBuffer
);
825 Update the ValueChanged status for questions in this formset.
827 @param FormSet FormSet data structure.
831 UpdateStatementStatusForFormSet (
832 IN FORM_BROWSER_FORMSET
*FormSet
836 FORM_BROWSER_FORM
*Form
;
838 Link
= GetFirstNode (&FormSet
->FormListHead
);
839 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
840 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
841 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
843 UpdateStatementStatusForForm (FormSet
, Form
);
848 Update the ValueChanged status for questions.
850 @param FormSet FormSet data structure.
851 @param Form Form data structure.
852 @param SettingScope Setting Scope for Default action.
856 UpdateStatementStatus (
857 IN FORM_BROWSER_FORMSET
*FormSet
,
858 IN FORM_BROWSER_FORM
*Form
,
859 IN BROWSER_SETTING_SCOPE SettingScope
863 FORM_BROWSER_FORMSET
*LocalFormSet
;
865 switch (SettingScope
) {
867 Link
= GetFirstNode (&gBrowserFormSetList
);
868 while (!IsNull (&gBrowserFormSetList
, Link
)) {
869 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
870 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
871 if (!ValidateFormSet(LocalFormSet
)) {
875 UpdateStatementStatusForFormSet (LocalFormSet
);
880 UpdateStatementStatusForFormSet (FormSet
);
884 UpdateStatementStatusForForm (FormSet
, Form
);
894 Process the action request in user input.
896 @param Action The user input action request info.
897 @param DefaultId The user input default Id info.
899 @retval EFI_SUCESSS This function always return successfully for now.
911 // This is caused by use press ESC, and it should not combine with other action type.
913 if ((Action
& BROWSER_ACTION_FORM_EXIT
) == BROWSER_ACTION_FORM_EXIT
) {
914 FindNextMenu (gCurrentSelection
, FormLevel
);
919 // Below is normal hotkey trigged action, these action maybe combine with each other.
921 if ((Action
& BROWSER_ACTION_DISCARD
) == BROWSER_ACTION_DISCARD
) {
922 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
925 if ((Action
& BROWSER_ACTION_DEFAULT
) == BROWSER_ACTION_DEFAULT
) {
926 ExtractDefault (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, DefaultId
, gBrowserSettingScope
, GetDefaultForAll
, NULL
, FALSE
);
927 UpdateStatementStatus (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
930 if ((Action
& BROWSER_ACTION_SUBMIT
) == BROWSER_ACTION_SUBMIT
) {
931 Status
= SubmitForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
932 if (EFI_ERROR (Status
)) {
933 PopupErrorMessage(BROWSER_SUBMIT_FAIL
, NULL
, NULL
);
937 if ((Action
& BROWSER_ACTION_RESET
) == BROWSER_ACTION_RESET
) {
938 gResetRequired
= TRUE
;
941 if ((Action
& BROWSER_ACTION_EXIT
) == BROWSER_ACTION_EXIT
) {
943 // Form Exit without saving, Similar to ESC Key.
944 // FormSet Exit without saving, Exit SendForm.
945 // System Exit without saving, CallExitHandler and Exit SendForm.
947 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
948 if (gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) {
949 FindNextMenu (gCurrentSelection
, gBrowserSettingScope
);
950 } else if (gBrowserSettingScope
== SystemLevel
) {
951 if (ExitHandlerFunction
!= NULL
) {
952 ExitHandlerFunction ();
954 gCurrentSelection
->Action
= UI_ACTION_EXIT
;
962 Check whether the formset guid is in this Hii package list.
964 @param HiiHandle The HiiHandle for this HII package list.
965 @param FormSetGuid The formset guid for the request formset.
967 @retval TRUE Find the formset guid.
968 @retval FALSE Not found the formset guid.
972 GetFormsetGuidFromHiiHandle (
973 IN EFI_HII_HANDLE HiiHandle
,
974 IN EFI_GUID
*FormSetGuid
977 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
981 UINT32 PackageListLength
;
982 EFI_HII_PACKAGE_HEADER PackageHeader
;
989 HiiPackageList
= NULL
;
992 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
993 if (Status
== EFI_BUFFER_TOO_SMALL
) {
994 HiiPackageList
= AllocatePool (BufferSize
);
995 ASSERT (HiiPackageList
!= NULL
);
997 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
999 if (EFI_ERROR (Status
) || HiiPackageList
== NULL
) {
1004 // Get Form package from this HII package List
1006 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
1008 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
1010 while (Offset
< PackageListLength
) {
1011 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
1012 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
1013 Offset
+= PackageHeader
.Length
;
1015 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
1017 // Search FormSet in this Form Package
1019 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
1020 while (Offset2
< PackageHeader
.Length
) {
1021 OpCodeData
= Package
+ Offset2
;
1023 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
1024 if (CompareGuid (FormSetGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))){
1030 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1038 FreePool (HiiPackageList
);
1044 Find HII Handle in the HII database associated with given Device Path.
1046 If DevicePath is NULL, then ASSERT.
1048 @param DevicePath Device Path associated with the HII package list
1050 @param FormsetGuid The formset guid for this formset.
1052 @retval Handle HII package list Handle associated with the Device
1054 @retval NULL Hii Package list handle is not found.
1058 DevicePathToHiiHandle (
1059 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
1060 IN EFI_GUID
*FormsetGuid
1064 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
1067 EFI_HANDLE DriverHandle
;
1068 EFI_HII_HANDLE
*HiiHandles
;
1069 EFI_HII_HANDLE HiiHandle
;
1071 ASSERT (DevicePath
!= NULL
);
1073 TmpDevicePath
= DevicePath
;
1075 // Locate Device Path Protocol handle buffer
1077 Status
= gBS
->LocateDevicePath (
1078 &gEfiDevicePathProtocolGuid
,
1082 if (EFI_ERROR (Status
) || !IsDevicePathEnd (TmpDevicePath
)) {
1087 // Retrieve all HII Handles from HII database
1089 HiiHandles
= HiiGetHiiHandles (NULL
);
1090 if (HiiHandles
== NULL
) {
1095 // Search Hii Handle by Driver Handle
1098 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
1099 Status
= mHiiDatabase
->GetPackageListHandle (
1104 if (!EFI_ERROR (Status
) && (Handle
== DriverHandle
)) {
1105 if (GetFormsetGuidFromHiiHandle(HiiHandles
[Index
], FormsetGuid
)) {
1106 HiiHandle
= HiiHandles
[Index
];
1110 if (HiiHandle
!= NULL
) {
1116 FreePool (HiiHandles
);
1121 Find HII Handle in the HII database associated with given form set guid.
1123 If FormSetGuid is NULL, then ASSERT.
1125 @param ComparingGuid FormSet Guid associated with the HII package list
1128 @retval Handle HII package list Handle associated with the Device
1130 @retval NULL Hii Package list handle is not found.
1134 FormSetGuidToHiiHandle (
1135 EFI_GUID
*ComparingGuid
1138 EFI_HII_HANDLE
*HiiHandles
;
1139 EFI_HII_HANDLE HiiHandle
;
1142 ASSERT (ComparingGuid
!= NULL
);
1146 // Get all the Hii handles
1148 HiiHandles
= HiiGetHiiHandles (NULL
);
1149 ASSERT (HiiHandles
!= NULL
);
1152 // Search for formset of each class type
1154 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
1155 if (GetFormsetGuidFromHiiHandle(HiiHandles
[Index
], ComparingGuid
)) {
1156 HiiHandle
= HiiHandles
[Index
];
1160 if (HiiHandle
!= NULL
) {
1165 FreePool (HiiHandles
);
1171 check how to process the changed data in current form or form set.
1173 @param Selection On input, Selection tell setup browser the information
1174 about the Selection, form and formset to be displayed.
1175 On output, Selection return the screen item that is selected
1178 @param Scope Data save or discard scope, form or formset.
1180 @retval TRUE Success process the changed data, will return to the parent form.
1181 @retval FALSE Reject to process the changed data, will stay at current form.
1184 ProcessChangedData (
1185 IN OUT UI_MENU_SELECTION
*Selection
,
1186 IN BROWSER_SETTING_SCOPE Scope
1192 switch (mFormDisplay
->ConfirmDataChange()) {
1193 case BROWSER_ACTION_DISCARD
:
1194 DiscardForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1197 case BROWSER_ACTION_SUBMIT
:
1198 SubmitForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1201 case BROWSER_ACTION_NONE
:
1207 // if Invalid value return, process same as BROWSER_ACTION_NONE.
1217 Find parent formset menu(the first menu which has different formset) for current menu.
1218 If not find, just return to the first menu.
1220 @param Selection The selection info.
1225 IN OUT UI_MENU_SELECTION
*Selection
1228 FORM_ENTRY_INFO
*CurrentMenu
;
1229 FORM_ENTRY_INFO
*ParentMenu
;
1231 CurrentMenu
= Selection
->CurrentMenu
;
1232 ParentMenu
= UiFindParentMenu(CurrentMenu
);
1235 // Find a menu which has different formset guid with current.
1237 while (ParentMenu
!= NULL
&& CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1238 CurrentMenu
= ParentMenu
;
1239 ParentMenu
= UiFindParentMenu(CurrentMenu
);
1242 if (ParentMenu
!= NULL
) {
1243 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1244 Selection
->Handle
= ParentMenu
->HiiHandle
;
1245 Selection
->FormId
= ParentMenu
->FormId
;
1246 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1248 Selection
->FormId
= CurrentMenu
->FormId
;
1249 Selection
->QuestionId
= CurrentMenu
->QuestionId
;
1252 Selection
->Statement
= NULL
;
1256 Process the goto op code, update the info in the selection structure.
1258 @param Statement The statement belong to goto op code.
1259 @param Selection The selection info.
1261 @retval EFI_SUCCESS The menu process successfully.
1262 @return Other value if the process failed.
1266 IN OUT FORM_BROWSER_STATEMENT
*Statement
,
1267 IN OUT UI_MENU_SELECTION
*Selection
1271 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1272 FORM_BROWSER_FORM
*RefForm
;
1274 EFI_HII_HANDLE HiiHandle
;
1276 Status
= EFI_SUCCESS
;
1281 // Prepare the device path check, get the device path info first.
1283 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0) {
1284 StringPtr
= GetToken (Statement
->HiiValue
.Value
.ref
.DevicePath
, Selection
->FormSet
->HiiHandle
);
1288 // Check whether the device path string is a valid string.
1290 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0 && StringPtr
!= NULL
&& StringPtr
[0] != L
'\0') {
1291 if (Selection
->Form
->ModalForm
) {
1296 // Goto another Hii Package list
1298 if (mPathFromText
!= NULL
) {
1299 DevicePath
= mPathFromText
->ConvertTextToDevicePath(StringPtr
);
1300 if (DevicePath
!= NULL
) {
1301 HiiHandle
= DevicePathToHiiHandle (DevicePath
, &Statement
->HiiValue
.Value
.ref
.FormSetGuid
);
1302 FreePool (DevicePath
);
1304 FreePool (StringPtr
);
1307 // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
1309 PopupErrorMessage(BROWSER_PROTOCOL_NOT_FOUND
, NULL
, NULL
);
1310 FreePool (StringPtr
);
1314 if (HiiHandle
!= Selection
->Handle
) {
1316 // Goto another Formset, check for uncommitted data
1318 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1319 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1320 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1326 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1327 Selection
->Handle
= HiiHandle
;
1328 if (Selection
->Handle
== NULL
) {
1330 // If target Hii Handle not found, exit current formset.
1332 FindParentFormSet(Selection
);
1336 CopyMem (&Selection
->FormSetGuid
,&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1337 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1338 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1339 } else if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &gZeroGuid
)) {
1340 if (Selection
->Form
->ModalForm
) {
1343 if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &Selection
->FormSetGuid
)) {
1345 // Goto another Formset, check for uncommitted data
1347 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1348 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1349 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1355 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1356 Selection
->Handle
= FormSetGuidToHiiHandle(&Statement
->HiiValue
.Value
.ref
.FormSetGuid
);
1357 if (Selection
->Handle
== NULL
) {
1359 // If target Hii Handle not found, exit current formset.
1361 FindParentFormSet(Selection
);
1365 CopyMem (&Selection
->FormSetGuid
, &Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1366 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1367 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1368 } else if (Statement
->HiiValue
.Value
.ref
.FormId
!= 0) {
1370 // Goto another Form, check for uncommitted data
1372 if (Statement
->HiiValue
.Value
.ref
.FormId
!= Selection
->FormId
) {
1373 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm(Selection
->Form
))) {
1374 if (!ProcessChangedData (Selection
, FormLevel
)) {
1380 RefForm
= IdToForm (Selection
->FormSet
, Statement
->HiiValue
.Value
.ref
.FormId
);
1381 if ((RefForm
!= NULL
) && (RefForm
->SuppressExpression
!= NULL
)) {
1382 if (EvaluateExpressionList(RefForm
->SuppressExpression
, TRUE
, Selection
->FormSet
, RefForm
) != ExpressFalse
) {
1384 // Form is suppressed.
1386 PopupErrorMessage(BROWSER_FORM_SUPPRESS
, NULL
, NULL
);
1391 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1392 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1393 } else if (Statement
->HiiValue
.Value
.ref
.QuestionId
!= 0) {
1394 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1402 Process Question Config.
1404 @param Selection The UI menu selection.
1405 @param Question The Question to be peocessed.
1407 @retval EFI_SUCCESS Question Config process success.
1408 @retval Other Question Config process fail.
1412 ProcessQuestionConfig (
1413 IN UI_MENU_SELECTION
*Selection
,
1414 IN FORM_BROWSER_STATEMENT
*Question
1421 if (Question
->QuestionConfig
== 0) {
1428 ConfigResp
= GetToken (Question
->QuestionConfig
, Selection
->FormSet
->HiiHandle
);
1429 if (ConfigResp
== NULL
) {
1430 return EFI_NOT_FOUND
;
1434 // Send config to Configuration Driver
1436 Status
= mHiiConfigRouting
->RouteConfig (
1447 Process the user input data.
1449 @param UserInput The user input data.
1450 @param ChangeHighlight Whether need to change the highlight statement.
1452 @retval EFI_SUCESSS This function always return successfully for now.
1457 IN USER_INPUT
*UserInput
,
1458 IN BOOLEAN ChangeHighlight
1462 FORM_BROWSER_STATEMENT
*Statement
;
1464 Status
= EFI_SUCCESS
;
1467 // When Exit from FormDisplay function, one of the below two cases must be true.
1469 ASSERT (UserInput
->Action
!= 0 || UserInput
->SelectedStatement
!= NULL
);
1472 // Remove the last highligh question id, this id will update when show next form.
1474 gCurrentSelection
->QuestionId
= 0;
1477 // First process the Action field in USER_INPUT.
1479 if (UserInput
->Action
!= 0) {
1480 Status
= ProcessAction (UserInput
->Action
, UserInput
->DefaultId
);
1481 if (EFI_ERROR (Status
)) {
1486 // Clear the highlight info.
1488 gCurrentSelection
->Statement
= NULL
;
1490 if (UserInput
->SelectedStatement
!= NULL
) {
1491 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1492 ASSERT (Statement
!= NULL
);
1494 // Save the current highlight menu in the menu history data.
1495 // which will be used when later browse back to this form.
1497 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1499 // For statement like text, actio, it not has question id.
1500 // So use FakeQuestionId to save the question.
1502 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1503 mCurFakeQestId
= Statement
->FakeQuestionId
;
1509 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1510 ASSERT (Statement
!= NULL
);
1512 gCurrentSelection
->Statement
= Statement
;
1514 if (ChangeHighlight
) {
1516 // This question is the current user select one,record it and later
1517 // show it as the highlight question.
1519 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1521 // For statement like text, actio, it not has question id.
1522 // So use FakeQuestionId to save the question.
1524 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1525 mCurFakeQestId
= Statement
->FakeQuestionId
;
1531 switch (Statement
->Operand
) {
1532 case EFI_IFR_REF_OP
:
1533 Status
= ProcessGotoOpCode(Statement
, gCurrentSelection
);
1536 case EFI_IFR_ACTION_OP
:
1538 // Process the Config string <ConfigResp>
1540 Status
= ProcessQuestionConfig (gCurrentSelection
, Statement
);
1543 case EFI_IFR_RESET_BUTTON_OP
:
1545 // Reset Question to default value specified by DefaultId
1547 Status
= ExtractDefault (gCurrentSelection
->FormSet
, NULL
, Statement
->DefaultId
, FormSetLevel
, GetDefaultForAll
, NULL
, FALSE
);
1548 UpdateStatementStatus (gCurrentSelection
->FormSet
, NULL
, FormSetLevel
);
1552 switch (Statement
->Operand
) {
1553 case EFI_IFR_STRING_OP
:
1554 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1555 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1556 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1557 FreePool (UserInput
->InputValue
.Buffer
);
1560 case EFI_IFR_PASSWORD_OP
:
1561 if (UserInput
->InputValue
.Buffer
== NULL
) {
1563 // User not input new password, just return.
1568 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1569 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1570 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1571 FreePool (UserInput
->InputValue
.Buffer
);
1573 // Two password match, send it to Configuration Driver
1575 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
1576 PasswordCheck (NULL
, UserInput
->SelectedStatement
, (CHAR16
*) Statement
->BufferValue
);
1578 // Clean the value after saved it.
1580 ZeroMem (Statement
->BufferValue
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1581 HiiSetString (gCurrentSelection
->FormSet
->HiiHandle
, Statement
->HiiValue
.Value
.string
, (CHAR16
*)Statement
->BufferValue
, NULL
);
1583 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithHiiDriver
);
1587 case EFI_IFR_ORDERED_LIST_OP
:
1588 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, UserInput
->InputValue
.BufferLen
);
1592 CopyMem (&Statement
->HiiValue
, &UserInput
->InputValue
, sizeof (EFI_HII_VALUE
));
1604 Display form and wait for user to select one menu option, then return it.
1606 @retval EFI_SUCESSS This function always return successfully for now.
1615 USER_INPUT UserInput
;
1616 FORM_ENTRY_INFO
*CurrentMenu
;
1617 BOOLEAN ChangeHighlight
;
1619 ZeroMem (&UserInput
, sizeof (USER_INPUT
));
1622 // Update the menu history data.
1624 CurrentMenu
= UiFindMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
, gCurrentSelection
->FormId
);
1625 if (CurrentMenu
== NULL
) {
1627 // Current menu not found, add it to the menu tree
1629 CurrentMenu
= UiAddMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
,
1630 gCurrentSelection
->FormId
, gCurrentSelection
->QuestionId
);
1631 ASSERT (CurrentMenu
!= NULL
);
1633 gCurrentSelection
->CurrentMenu
= CurrentMenu
;
1636 // Find currrent highlight statement.
1638 if (gCurrentSelection
->QuestionId
== 0) {
1640 // Highlight not specified, fetch it from cached menu
1642 gCurrentSelection
->QuestionId
= CurrentMenu
->QuestionId
;
1646 // Evaluate all the Expressions in this Form
1648 Status
= EvaluateFormExpressions (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
);
1649 if (EFI_ERROR (Status
)) {
1653 UpdateDisplayFormData ();
1656 // Three possible status maybe return.
1658 // EFI_INVALID_PARAMETER: The input dimension info is not valid.
1659 // EFI_NOT_FOUND: The input value for oneof/orderedlist opcode is not valid
1660 // and an valid value has return.
1661 // EFI_SUCCESS: Success shows form and get user input in UserInput paramenter.
1663 Status
= mFormDisplay
->FormDisplay (&gDisplayFormData
, &UserInput
);
1664 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_FOUND
) {
1665 FreeDisplayFormData();
1670 // If status is EFI_SUCCESS, means user has change the highlight menu and new user input return.
1671 // in this case, browser need to change the highlight menu.
1672 // If status is EFI_NOT_FOUND, means the input DisplayFormData has error for oneof/orderedlist
1673 // opcode and new valid value has return, browser core need to adjust
1674 // value for this opcode and shows this form again.
1676 ChangeHighlight
= (Status
== EFI_SUCCESS
? TRUE
:FALSE
);
1678 Status
= ProcessUserInput (&UserInput
, ChangeHighlight
);
1680 FreeDisplayFormData();
1686 Functions which are registered to receive notification of
1687 database events have this prototype. The actual event is encoded
1688 in NotifyType. The following table describes how PackageType,
1689 PackageGuid, Handle, and Package are used for each of the
1692 @param PackageType Package type of the notification.
1694 @param PackageGuid If PackageType is
1695 EFI_HII_PACKAGE_TYPE_GUID, then this is
1696 the pointer to the GUID from the Guid
1697 field of EFI_HII_PACKAGE_GUID_HEADER.
1698 Otherwise, it must be NULL.
1700 @param Package Points to the package referred to by the
1701 notification Handle The handle of the package
1702 list which contains the specified package.
1704 @param Handle The HII handle.
1706 @param NotifyType The type of change concerning the
1708 EFI_HII_DATABASE_NOTIFY_TYPE.
1714 IN UINT8 PackageType
,
1715 IN CONST EFI_GUID
*PackageGuid
,
1716 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
1717 IN EFI_HII_HANDLE Handle
,
1718 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
1721 mHiiPackageListUpdated
= TRUE
;
1727 Update the NV flag info for this form set.
1729 @param FormSet FormSet data structure.
1733 IsNvUpdateRequiredForFormSet (
1734 IN FORM_BROWSER_FORMSET
*FormSet
1738 FORM_BROWSER_FORM
*Form
;
1742 // Not finished question initialization, return FALSE.
1744 if (!FormSet
->QuestionInited
) {
1750 Link
= GetFirstNode (&FormSet
->FormListHead
);
1751 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
1752 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
1754 RetVal
= IsNvUpdateRequiredForForm(Form
);
1759 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
1766 Update the NvUpdateRequired flag for a form.
1768 @param Form Form data structure.
1772 IsNvUpdateRequiredForForm (
1773 IN FORM_BROWSER_FORM
*Form
1777 FORM_BROWSER_STATEMENT
*Statement
;
1779 Link
= GetFirstNode (&Form
->StatementListHead
);
1780 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1781 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1783 if (Statement
->ValueChanged
) {
1787 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1794 Find menu which will show next time.
1796 @param Selection On input, Selection tell setup browser the information
1797 about the Selection, form and formset to be displayed.
1798 On output, Selection return the screen item that is selected
1800 @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.
1801 else, we need to exit current formset.
1803 @retval TRUE Exit current form.
1804 @retval FALSE User press ESC and keep in current form.
1808 IN OUT UI_MENU_SELECTION
*Selection
,
1809 IN BROWSER_SETTING_SCOPE SettingLevel
1812 FORM_ENTRY_INFO
*CurrentMenu
;
1813 FORM_ENTRY_INFO
*ParentMenu
;
1814 BROWSER_SETTING_SCOPE Scope
;
1816 CurrentMenu
= Selection
->CurrentMenu
;
1818 Scope
= FormSetLevel
;
1820 if (CurrentMenu
!= NULL
&& (ParentMenu
= UiFindParentMenu(CurrentMenu
)) != NULL
) {
1822 // we have a parent, so go to the parent menu
1824 if (CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1825 if (SettingLevel
== FormSetLevel
) {
1827 // Find a menu which has different formset guid with current.
1829 while (CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1830 CurrentMenu
= ParentMenu
;
1831 if ((ParentMenu
= UiFindParentMenu(CurrentMenu
)) == NULL
) {
1836 if (ParentMenu
!= NULL
) {
1837 Scope
= FormSetLevel
;
1843 Scope
= FormSetLevel
;
1848 // Form Level Check whether the data is changed.
1850 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm (Selection
->Form
)) ||
1851 (gBrowserSettingScope
== FormSetLevel
&& IsNvUpdateRequiredForFormSet(Selection
->FormSet
) && Scope
== FormSetLevel
)) {
1852 if (!ProcessChangedData(Selection
, Scope
)) {
1857 if (ParentMenu
!= NULL
) {
1859 // ParentMenu is found. Then, go to it.
1861 if (Scope
== FormLevel
) {
1862 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
1864 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1865 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1866 Selection
->Handle
= ParentMenu
->HiiHandle
;
1869 Selection
->Statement
= NULL
;
1871 Selection
->FormId
= ParentMenu
->FormId
;
1872 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1875 // Clear highlight record for this menu
1877 CurrentMenu
->QuestionId
= 0;
1882 // Current in root page, exit the SendForm
1884 Selection
->Action
= UI_ACTION_EXIT
;
1890 Call the call back function for the question and process the return action.
1892 @param Selection On input, Selection tell setup browser the information
1893 about the Selection, form and formset to be displayed.
1894 On output, Selection return the screen item that is selected
1896 @param FormSet The formset this question belong to.
1897 @param Form The form this question belong to.
1898 @param Question The Question which need to call.
1899 @param Action The action request.
1900 @param SkipSaveOrDiscard Whether skip save or discard action.
1902 @retval EFI_SUCCESS The call back function excutes successfully.
1903 @return Other value if the call back function failed to excute.
1906 ProcessCallBackFunction (
1907 IN OUT UI_MENU_SELECTION
*Selection
,
1908 IN FORM_BROWSER_FORMSET
*FormSet
,
1909 IN FORM_BROWSER_FORM
*Form
,
1910 IN FORM_BROWSER_STATEMENT
*Question
,
1911 IN EFI_BROWSER_ACTION Action
,
1912 IN BOOLEAN SkipSaveOrDiscard
1916 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
1917 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1918 EFI_HII_VALUE
*HiiValue
;
1919 EFI_IFR_TYPE_VALUE
*TypeValue
;
1920 FORM_BROWSER_STATEMENT
*Statement
;
1921 BOOLEAN SubmitFormIsRequired
;
1922 BOOLEAN DiscardFormIsRequired
;
1925 BROWSER_SETTING_SCOPE SettingLevel
;
1926 EFI_IFR_TYPE_VALUE BackUpValue
;
1927 UINT8
*BackUpBuffer
;
1930 ConfigAccess
= FormSet
->ConfigAccess
;
1931 SubmitFormIsRequired
= FALSE
;
1932 SettingLevel
= FormSetLevel
;
1933 DiscardFormIsRequired
= FALSE
;
1935 Status
= EFI_SUCCESS
;
1936 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1937 BackUpBuffer
= NULL
;
1939 if (ConfigAccess
== NULL
) {
1943 Link
= GetFirstNode (&Form
->StatementListHead
);
1944 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1945 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1946 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1949 // if Question != NULL, only process the question. Else, process all question in this form.
1951 if ((Question
!= NULL
) && (Statement
!= Question
)) {
1955 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) {
1960 // Check whether Statement is disabled.
1962 if (Statement
->Expression
!= NULL
) {
1963 if (EvaluateExpressionList(Statement
->Expression
, TRUE
, FormSet
, Form
) == ExpressDisable
) {
1968 HiiValue
= &Statement
->HiiValue
;
1969 TypeValue
= &HiiValue
->Value
;
1970 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
1972 // For OrderedList, passing in the value buffer to Callback()
1974 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
1978 // If EFI_BROWSER_ACTION_CHANGING type, back up the new question value.
1980 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1981 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
1982 BackUpBuffer
= AllocateCopyPool(Statement
->StorageWidth
+ sizeof(CHAR16
), Statement
->BufferValue
);
1983 ASSERT (BackUpBuffer
!= NULL
);
1985 CopyMem (&BackUpValue
, &HiiValue
->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1989 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1990 Status
= ConfigAccess
->Callback (
1993 Statement
->QuestionId
,
1998 if (!EFI_ERROR (Status
)) {
2000 // Need to sync the value between Statement->HiiValue->Value and Statement->BufferValue
2002 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2003 NewString
= GetToken (Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
2004 ASSERT (NewString
!= NULL
);
2006 ASSERT (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
);
2007 if (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
) {
2008 CopyMem (Statement
->BufferValue
, NewString
, StrSize (NewString
));
2010 CopyMem (Statement
->BufferValue
, NewString
, Statement
->StorageWidth
);
2012 FreePool (NewString
);
2016 // Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.
2019 case EFI_BROWSER_ACTION_CHANGED
:
2020 switch (ActionRequest
) {
2021 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2022 DiscardFormIsRequired
= TRUE
;
2023 gResetRequired
= TRUE
;
2027 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2028 SubmitFormIsRequired
= TRUE
;
2032 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2033 DiscardFormIsRequired
= TRUE
;
2037 case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
:
2038 SubmitFormIsRequired
= TRUE
;
2039 SettingLevel
= FormLevel
;
2043 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
:
2044 DiscardFormIsRequired
= TRUE
;
2045 SettingLevel
= FormLevel
;
2049 case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
:
2050 SubmitFormIsRequired
= TRUE
;
2051 SettingLevel
= FormLevel
;
2054 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
:
2055 DiscardFormIsRequired
= TRUE
;
2056 SettingLevel
= FormLevel
;
2064 case EFI_BROWSER_ACTION_CHANGING
:
2066 // Do the question validation.
2068 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2069 if (!EFI_ERROR (Status
)) {
2071 // According the spec, return value from call back of "changing" and
2072 // "retrieve" should update to the question's temp buffer.
2074 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2078 case EFI_BROWSER_ACTION_RETRIEVE
:
2080 // According the spec, return value from call back of "changing" and
2081 // "retrieve" should update to the question's temp buffer.
2083 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2091 // If the callback returns EFI_UNSUPPORTED for EFI_BROWSER_ACTION_CHANGING,
2092 // then the browser will use the value passed to Callback() and ignore the
2093 // value returned by Callback().
2095 if (Action
== EFI_BROWSER_ACTION_CHANGING
&& Status
== EFI_UNSUPPORTED
) {
2096 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2097 CopyMem (Statement
->BufferValue
, BackUpBuffer
, Statement
->StorageWidth
+ sizeof(CHAR16
));
2099 CopyMem (&HiiValue
->Value
, &BackUpValue
, sizeof (EFI_IFR_TYPE_VALUE
));
2103 // Do the question validation.
2105 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2106 if (!EFI_ERROR (Status
)) {
2107 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2112 // According the spec, return fail from call back of "changing" and
2113 // "retrieve", should restore the question's value.
2115 if ((Action
== EFI_BROWSER_ACTION_CHANGING
&& Status
!= EFI_UNSUPPORTED
) ||
2116 Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
2117 GetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2120 if (Status
== EFI_UNSUPPORTED
) {
2122 // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.
2124 Status
= EFI_SUCCESS
;
2128 if (BackUpBuffer
!= NULL
) {
2129 FreePool (BackUpBuffer
);
2133 if (SubmitFormIsRequired
&& !SkipSaveOrDiscard
) {
2134 SubmitForm (FormSet
, Form
, SettingLevel
);
2137 if (DiscardFormIsRequired
&& !SkipSaveOrDiscard
) {
2138 DiscardForm (FormSet
, Form
, SettingLevel
);
2142 FindNextMenu (Selection
, SettingLevel
);
2149 Call the retrieve type call back function for one question to get the initialize data.
2151 This function only used when in the initialize stage, because in this stage, the
2152 Selection->Form is not ready. For other case, use the ProcessCallBackFunction instead.
2154 @param ConfigAccess The config access protocol produced by the hii driver.
2155 @param Statement The Question which need to call.
2156 @param FormSet The formset this question belong to.
2158 @retval EFI_SUCCESS The call back function excutes successfully.
2159 @return Other value if the call back function failed to excute.
2162 ProcessRetrieveForQuestion (
2163 IN EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
,
2164 IN FORM_BROWSER_STATEMENT
*Statement
,
2165 IN FORM_BROWSER_FORMSET
*FormSet
2169 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2170 EFI_HII_VALUE
*HiiValue
;
2171 EFI_IFR_TYPE_VALUE
*TypeValue
;
2174 Status
= EFI_SUCCESS
;
2175 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2177 if (((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) || ConfigAccess
== NULL
) {
2178 return EFI_UNSUPPORTED
;
2181 HiiValue
= &Statement
->HiiValue
;
2182 TypeValue
= &HiiValue
->Value
;
2183 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2185 // For OrderedList, passing in the value buffer to Callback()
2187 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
2190 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2191 Status
= ConfigAccess
->Callback (
2193 EFI_BROWSER_ACTION_RETRIEVE
,
2194 Statement
->QuestionId
,
2199 if (!EFI_ERROR (Status
) && HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2200 NewString
= GetToken (Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
2201 ASSERT (NewString
!= NULL
);
2203 ASSERT (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
);
2204 if (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
) {
2205 CopyMem (Statement
->BufferValue
, NewString
, StrSize (NewString
));
2207 CopyMem (Statement
->BufferValue
, NewString
, Statement
->StorageWidth
);
2209 FreePool (NewString
);
2216 The worker function that send the displays to the screen. On output,
2217 the selection made by user is returned.
2219 @param Selection On input, Selection tell setup browser the information
2220 about the Selection, form and formset to be displayed.
2221 On output, Selection return the screen item that is selected
2224 @retval EFI_SUCCESS The page is displayed successfully.
2225 @return Other value if the page failed to be diplayed.
2230 IN OUT UI_MENU_SELECTION
*Selection
2235 EFI_HANDLE NotifyHandle
;
2236 FORM_BROWSER_STATEMENT
*Statement
;
2237 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
2239 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
2242 // Register notify for Form package update
2244 Status
= mHiiDatabase
->RegisterPackageNotify (
2246 EFI_HII_PACKAGE_FORMS
,
2249 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2252 if (EFI_ERROR (Status
)) {
2257 // Initialize current settings of Questions in this FormSet
2259 InitializeCurrentSetting (Selection
->FormSet
);
2262 // Initilize Action field.
2264 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
2267 // Clean the mCurFakeQestId value is formset refreshed.
2273 // IFR is updated, force to reparse the IFR binary
2275 if (mHiiPackageListUpdated
) {
2276 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2277 mHiiPackageListUpdated
= FALSE
;
2282 // Initialize Selection->Form
2284 if (Selection
->FormId
== 0) {
2286 // Zero FormId indicates display the first Form in a FormSet
2288 Link
= GetFirstNode (&Selection
->FormSet
->FormListHead
);
2290 Selection
->Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2291 Selection
->FormId
= Selection
->Form
->FormId
;
2293 Selection
->Form
= IdToForm (Selection
->FormSet
, Selection
->FormId
);
2296 if (Selection
->Form
== NULL
) {
2298 // No Form to display
2300 Status
= EFI_NOT_FOUND
;
2305 // Check Form is suppressed.
2307 if (Selection
->Form
->SuppressExpression
!= NULL
) {
2308 if (EvaluateExpressionList(Selection
->Form
->SuppressExpression
, TRUE
, Selection
->FormSet
, Selection
->Form
) == ExpressSuppress
) {
2310 // Form is suppressed.
2312 PopupErrorMessage(BROWSER_FORM_SUPPRESS
, NULL
, NULL
);
2313 Status
= EFI_NOT_FOUND
;
2319 // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN
2320 // for each question with callback flag.
2321 // New form may be the first form, or the different form after another form close.
2323 if (((Selection
->Handle
!= mCurrentHiiHandle
) ||
2324 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2325 (Selection
->FormId
!= mCurrentFormId
))) {
2327 // Update Retrieve flag.
2329 mFinishRetrieveCall
= FALSE
;
2332 // Keep current form information
2334 mCurrentHiiHandle
= Selection
->Handle
;
2335 CopyGuid (&mCurrentFormSetGuid
, &Selection
->FormSetGuid
);
2336 mCurrentFormId
= Selection
->FormId
;
2338 if (ConfigAccess
!= NULL
) {
2339 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_FORM_OPEN
, FALSE
);
2340 if (EFI_ERROR (Status
)) {
2345 // IFR is updated during callback of open form, force to reparse the IFR binary
2347 if (mHiiPackageListUpdated
) {
2348 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2349 mHiiPackageListUpdated
= FALSE
;
2356 // Load Questions' Value for display
2358 Status
= LoadFormSetConfig (Selection
, Selection
->FormSet
);
2359 if (EFI_ERROR (Status
)) {
2363 if (!mFinishRetrieveCall
) {
2365 // Finish call RETRIEVE callback for this form.
2367 mFinishRetrieveCall
= TRUE
;
2369 if (ConfigAccess
!= NULL
) {
2370 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_RETRIEVE
, FALSE
);
2371 if (EFI_ERROR (Status
)) {
2376 // IFR is updated during callback of open form, force to reparse the IFR binary
2378 if (mHiiPackageListUpdated
) {
2379 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2380 mHiiPackageListUpdated
= FALSE
;
2389 Status
= DisplayForm ();
2390 if (EFI_ERROR (Status
)) {
2395 // Check Selected Statement (if press ESC, Selection->Statement will be NULL)
2397 Statement
= Selection
->Statement
;
2398 if (Statement
!= NULL
) {
2399 if ((ConfigAccess
!= NULL
) &&
2400 ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
) &&
2401 (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
2402 Status
= ProcessCallBackFunction(Selection
, Selection
->FormSet
, Selection
->Form
, Statement
, EFI_BROWSER_ACTION_CHANGING
, FALSE
);
2403 if (Statement
->Operand
== EFI_IFR_REF_OP
) {
2405 // Process dynamic update ref opcode.
2407 if (!EFI_ERROR (Status
)) {
2408 Status
= ProcessGotoOpCode(Statement
, Selection
);
2412 // Callback return error status or status return from process goto opcode.
2414 if (EFI_ERROR (Status
)) {
2416 // Cross reference will not be taken
2418 Selection
->FormId
= Selection
->Form
->FormId
;
2419 Selection
->QuestionId
= 0;
2424 // Verify whether question value has checked, update the ValueChanged flag in Question.
2426 IsQuestionValueChanged(gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithBuffer
);
2428 if (!EFI_ERROR (Status
) && Statement
->Operand
!= EFI_IFR_REF_OP
) {
2429 ProcessCallBackFunction(Selection
, Selection
->FormSet
, Selection
->Form
, Statement
, EFI_BROWSER_ACTION_CHANGED
, FALSE
);
2433 // Do the question validation.
2435 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2436 if (!EFI_ERROR (Status
) && (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
2437 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2439 // Verify whether question value has checked, update the ValueChanged flag in Question.
2441 IsQuestionValueChanged(gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithBuffer
);
2446 // If question has EFI_IFR_FLAG_RESET_REQUIRED flag and without storage and process question success till here,
2447 // trig the gResetFlag.
2449 if ((Status
== EFI_SUCCESS
) &&
2450 (Statement
->Storage
== NULL
) &&
2451 ((Statement
->QuestionFlags
& EFI_IFR_FLAG_RESET_REQUIRED
) != 0)) {
2452 gResetRequired
= TRUE
;
2457 // Check whether Exit flag is TRUE.
2459 if (gExitRequired
) {
2460 switch (gBrowserSettingScope
) {
2462 Selection
->Action
= UI_ACTION_EXIT
;
2467 FindNextMenu (Selection
, gBrowserSettingScope
);
2474 gExitRequired
= FALSE
;
2478 // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE
2479 // for each question with callback flag.
2481 if ((ConfigAccess
!= NULL
) &&
2482 ((Selection
->Action
== UI_ACTION_EXIT
) ||
2483 (Selection
->Handle
!= mCurrentHiiHandle
) ||
2484 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2485 (Selection
->FormId
!= mCurrentFormId
))) {
2487 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_FORM_CLOSE
, FALSE
);
2488 if (EFI_ERROR (Status
)) {
2492 } while (Selection
->Action
== UI_ACTION_REFRESH_FORM
);
2496 // Reset current form information to the initial setting when error happens or form exit.
2498 if (EFI_ERROR (Status
) || Selection
->Action
== UI_ACTION_EXIT
) {
2499 mCurrentHiiHandle
= NULL
;
2500 CopyGuid (&mCurrentFormSetGuid
, &gZeroGuid
);
2505 // Unregister notify for Form package update
2507 mHiiDatabase
->UnregisterPackageNotify (