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 CopyKey
->KeyData
= AllocateCopyPool(sizeof (EFI_INPUT_KEY
), HotKey
->KeyData
);
401 CopyKey
->HelpString
= AllocateCopyPool(StrSize (HotKey
->HelpString
), HotKey
->HelpString
);
403 InsertTailList(&gDisplayFormData
.HotKeyListHead
, &CopyKey
->Link
);
405 Link
= GetNextNode (&gBrowserHotKeyList
, Link
);
411 Get the extra question attribute from override question list.
413 @param QuestionId The question id for this request question.
415 @retval The attribute for this question or NULL if not found this
416 question in the list.
420 ProcessQuestionExtraAttr (
421 IN EFI_QUESTION_ID QuestionId
425 QUESTION_ATTRIBUTE_OVERRIDE
*QuestionDesc
;
428 // Return HII_DISPLAY_NONE if input a invalid question id.
430 if (QuestionId
== 0) {
431 return HII_DISPLAY_NONE
;
434 Link
= GetFirstNode (&mPrivateData
.FormBrowserEx2
.OverrideQestListHead
);
435 while (!IsNull (&mPrivateData
.FormBrowserEx2
.OverrideQestListHead
, Link
)) {
436 QuestionDesc
= FORM_QUESTION_ATTRIBUTE_OVERRIDE_FROM_LINK (Link
);
437 Link
= GetNextNode (&mPrivateData
.FormBrowserEx2
.OverrideQestListHead
, Link
);
439 if ((QuestionDesc
->QuestionId
== QuestionId
) &&
440 (QuestionDesc
->FormId
== gCurrentSelection
->FormId
) &&
441 (QuestionDesc
->HiiHandle
== gCurrentSelection
->Handle
) &&
442 CompareGuid (&QuestionDesc
->FormSetGuid
, &gCurrentSelection
->FormSetGuid
)) {
443 return QuestionDesc
->Attribute
;
447 return HII_DISPLAY_NONE
;
452 Enum all statement in current form, find all the statement can be display and
453 add to the display form.
457 AddStatementToDisplayForm (
463 FORM_BROWSER_STATEMENT
*Statement
;
464 FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
;
465 UINT8 MinRefreshInterval
;
466 EFI_EVENT RefreshIntervalEvent
;
467 FORM_BROWSER_REFRESH_EVENT_NODE
*EventNode
;
468 BOOLEAN FormEditable
;
469 UINT32 ExtraAttribute
;
471 MinRefreshInterval
= 0;
472 FormEditable
= FALSE
;
475 // Process the statement outside the form, these statements are not recognized
478 Link
= GetFirstNode (&gCurrentSelection
->FormSet
->StatementListOSF
);
479 while (!IsNull (&gCurrentSelection
->FormSet
->StatementListOSF
, Link
)) {
480 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
481 Link
= GetNextNode (&gCurrentSelection
->FormSet
->StatementListOSF
, Link
);
483 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
484 ASSERT (DisplayStatement
!= NULL
);
485 DisplayStatement
->Signature
= FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE
;
486 DisplayStatement
->Version
= FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1
;
487 DisplayStatement
->OpCode
= Statement
->OpCode
;
489 InitializeListHead (&DisplayStatement
->NestStatementList
);
490 InitializeListHead (&DisplayStatement
->OptionListHead
);
492 InsertTailList(&gDisplayFormData
.StatementListOSF
, &DisplayStatement
->DisplayLink
);
496 // Process the statement in this form.
498 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
499 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
500 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
501 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
504 // This statement can't be show, skip it.
506 if (EvaluateExpressionList(Statement
->Expression
, FALSE
, NULL
, NULL
) > ExpressGrayOut
) {
511 // Check the extra attribute.
513 ExtraAttribute
= ProcessQuestionExtraAttr (Statement
->QuestionId
);
514 if ((ExtraAttribute
& HII_DISPLAY_SUPPRESS
) != 0) {
518 DisplayStatement
= AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT
));
519 ASSERT (DisplayStatement
!= NULL
);
522 // Initialize this statement and add it to the display form.
524 InitializeDisplayStatement(DisplayStatement
, Statement
);
527 // Set the extra attribute.
529 DisplayStatement
->Attribute
|= ExtraAttribute
;
531 if (Statement
->Storage
!= NULL
) {
536 // Get the minimal refresh interval value for later use.
538 if ((Statement
->RefreshInterval
!= 0) &&
539 (MinRefreshInterval
== 0 || Statement
->RefreshInterval
< MinRefreshInterval
)) {
540 MinRefreshInterval
= Statement
->RefreshInterval
;
545 // Create the periodic timer for refresh interval statement.
547 if (MinRefreshInterval
!= 0) {
548 Status
= gBS
->CreateEvent (EVT_TIMER
| EVT_NOTIFY_SIGNAL
, TPL_CALLBACK
, RefreshIntervalProcess
, NULL
, &RefreshIntervalEvent
);
549 ASSERT_EFI_ERROR (Status
);
550 Status
= gBS
->SetTimer (RefreshIntervalEvent
, TimerPeriodic
, MinRefreshInterval
* ONE_SECOND
);
551 ASSERT_EFI_ERROR (Status
);
553 EventNode
= AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE
));
554 ASSERT (EventNode
!= NULL
);
555 EventNode
->RefreshEvent
= RefreshIntervalEvent
;
556 InsertTailList(&mRefreshEventList
, &EventNode
->Link
);
560 // Update hotkey list field.
562 if (gBrowserSettingScope
== SystemLevel
|| FormEditable
) {
569 Initialize the SettingChangedFlag variable in the display form.
573 UpdateDataChangedFlag (
578 FORM_BROWSER_FORMSET
*LocalFormSet
;
580 gDisplayFormData
.SettingChangedFlag
= FALSE
;
582 if (IsNvUpdateRequiredForForm (gCurrentSelection
->Form
)) {
583 gDisplayFormData
.SettingChangedFlag
= TRUE
;
588 // Base on the system level to check whether need to show the NV flag.
590 switch (gBrowserSettingScope
) {
593 // Check the maintain list to see whether there is any change.
595 Link
= GetFirstNode (&gBrowserFormSetList
);
596 while (!IsNull (&gBrowserFormSetList
, Link
)) {
597 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
598 if (IsNvUpdateRequiredForFormSet(LocalFormSet
)) {
599 gDisplayFormData
.SettingChangedFlag
= TRUE
;
602 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
607 if (IsNvUpdateRequiredForFormSet(gCurrentSelection
->FormSet
)) {
608 gDisplayFormData
.SettingChangedFlag
= TRUE
;
620 Initialize the Display form structure data.
624 InitializeDisplayFormData (
630 gDisplayFormData
.Signature
= FORM_DISPLAY_ENGINE_FORM_SIGNATURE
;
631 gDisplayFormData
.Version
= FORM_DISPLAY_ENGINE_VERSION_1
;
632 gDisplayFormData
.ImageId
= 0;
633 gDisplayFormData
.AnimationId
= 0;
635 InitializeListHead (&gDisplayFormData
.StatementListHead
);
636 InitializeListHead (&gDisplayFormData
.StatementListOSF
);
637 InitializeListHead (&gDisplayFormData
.HotKeyListHead
);
639 Status
= gBS
->CreateEvent (
642 SetupBrowserEmptyFunction
,
646 ASSERT_EFI_ERROR (Status
);
651 Free the kotkey info saved in form data.
659 BROWSER_HOT_KEY
*HotKey
;
662 while (!IsListEmpty (&gDisplayFormData
.HotKeyListHead
)) {
663 Link
= GetFirstNode (&gDisplayFormData
.HotKeyListHead
);
664 HotKey
= BROWSER_HOT_KEY_FROM_LINK (Link
);
666 RemoveEntryList (&HotKey
->Link
);
668 FreePool (HotKey
->KeyData
);
669 FreePool (HotKey
->HelpString
);
676 Update the Display form structure data.
680 UpdateDisplayFormData (
684 gDisplayFormData
.FormTitle
= gCurrentSelection
->Form
->FormTitle
;
685 gDisplayFormData
.FormId
= gCurrentSelection
->FormId
;
686 gDisplayFormData
.HiiHandle
= gCurrentSelection
->Handle
;
687 CopyGuid (&gDisplayFormData
.FormSetGuid
, &gCurrentSelection
->FormSetGuid
);
689 gDisplayFormData
.Attribute
= 0;
690 gDisplayFormData
.Attribute
|= gCurrentSelection
->Form
->ModalForm
? HII_DISPLAY_MODAL
: 0;
691 gDisplayFormData
.Attribute
|= gCurrentSelection
->Form
->Locked
? HII_DISPLAY_LOCK
: 0;
693 gDisplayFormData
.FormRefreshEvent
= NULL
;
694 gDisplayFormData
.HighLightedStatement
= NULL
;
696 UpdateDataChangedFlag ();
698 AddStatementToDisplayForm ();
703 Free the Display Statement structure data.
705 @param StatementList Point to the statement list which need to be free.
710 LIST_ENTRY
*StatementList
714 LIST_ENTRY
*OptionLink
;
715 FORM_DISPLAY_ENGINE_STATEMENT
*Statement
;
716 DISPLAY_QUESTION_OPTION
*Option
;
719 // Free Statements/Questions
721 while (!IsListEmpty (StatementList
)) {
722 Link
= GetFirstNode (StatementList
);
723 Statement
= FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link
);
728 while (!IsListEmpty (&Statement
->OptionListHead
)) {
729 OptionLink
= GetFirstNode (&Statement
->OptionListHead
);
730 Option
= DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink
);
731 RemoveEntryList (&Option
->Link
);
736 // Free nest statement List
738 if (!IsListEmpty (&Statement
->NestStatementList
)) {
739 FreeStatementData(&Statement
->NestStatementList
);
742 RemoveEntryList (&Statement
->DisplayLink
);
743 FreePool (Statement
);
749 Free the Display form structure data.
753 FreeDisplayFormData (
757 FreeStatementData (&gDisplayFormData
.StatementListHead
);
758 FreeStatementData (&gDisplayFormData
.StatementListOSF
);
767 Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
769 @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
771 @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
774 FORM_BROWSER_STATEMENT
*
775 GetBrowserStatement (
776 IN FORM_DISPLAY_ENGINE_STATEMENT
*DisplayStatement
779 FORM_BROWSER_STATEMENT
*Statement
;
782 Link
= GetFirstNode (&gCurrentSelection
->Form
->StatementListHead
);
783 while (!IsNull (&gCurrentSelection
->Form
->StatementListHead
, Link
)) {
784 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
786 if (Statement
->OpCode
== DisplayStatement
->OpCode
) {
790 Link
= GetNextNode (&gCurrentSelection
->Form
->StatementListHead
, Link
);
797 Update the ValueChanged status for questions in this form.
799 @param FormSet FormSet data structure.
800 @param Form Form data structure.
804 UpdateStatementStatusForForm (
805 IN FORM_BROWSER_FORMSET
*FormSet
,
806 IN FORM_BROWSER_FORM
*Form
810 FORM_BROWSER_STATEMENT
*Question
;
812 Link
= GetFirstNode (&Form
->StatementListHead
);
813 while (!IsNull (&Form
->StatementListHead
, Link
)) {
814 Question
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
815 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
817 IsQuestionValueChanged(FormSet
, Form
, Question
, GetSetValueWithBuffer
);
822 Update the ValueChanged status for questions in this formset.
824 @param FormSet FormSet data structure.
828 UpdateStatementStatusForFormSet (
829 IN FORM_BROWSER_FORMSET
*FormSet
833 FORM_BROWSER_FORM
*Form
;
835 Link
= GetFirstNode (&FormSet
->FormListHead
);
836 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
837 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
838 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
840 UpdateStatementStatusForForm (FormSet
, Form
);
845 Update the ValueChanged status for questions.
847 @param FormSet FormSet data structure.
848 @param Form Form data structure.
849 @param SettingScope Setting Scope for Default action.
853 UpdateStatementStatus (
854 IN FORM_BROWSER_FORMSET
*FormSet
,
855 IN FORM_BROWSER_FORM
*Form
,
856 IN BROWSER_SETTING_SCOPE SettingScope
860 FORM_BROWSER_FORMSET
*LocalFormSet
;
862 switch (SettingScope
) {
864 Link
= GetFirstNode (&gBrowserFormSetList
);
865 while (!IsNull (&gBrowserFormSetList
, Link
)) {
866 LocalFormSet
= FORM_BROWSER_FORMSET_FROM_LINK (Link
);
867 Link
= GetNextNode (&gBrowserFormSetList
, Link
);
868 if (!ValidateFormSet(LocalFormSet
)) {
872 UpdateStatementStatusForFormSet (LocalFormSet
);
877 UpdateStatementStatusForFormSet (FormSet
);
881 UpdateStatementStatusForForm (FormSet
, Form
);
891 Process the action request in user input.
893 @param Action The user input action request info.
894 @param DefaultId The user input default Id info.
896 @retval EFI_SUCESSS This function always return successfully for now.
908 // This is caused by use press ESC, and it should not combine with other action type.
910 if ((Action
& BROWSER_ACTION_FORM_EXIT
) == BROWSER_ACTION_FORM_EXIT
) {
911 FindNextMenu (gCurrentSelection
, FormLevel
);
916 // Below is normal hotkey trigged action, these action maybe combine with each other.
918 if ((Action
& BROWSER_ACTION_DISCARD
) == BROWSER_ACTION_DISCARD
) {
919 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
922 if ((Action
& BROWSER_ACTION_DEFAULT
) == BROWSER_ACTION_DEFAULT
) {
923 ExtractDefault (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, DefaultId
, gBrowserSettingScope
, GetDefaultForAll
, NULL
, FALSE
);
924 UpdateStatementStatus (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
927 if ((Action
& BROWSER_ACTION_SUBMIT
) == BROWSER_ACTION_SUBMIT
) {
928 Status
= SubmitForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
929 if (EFI_ERROR (Status
)) {
930 PopupErrorMessage(BROWSER_SUBMIT_FAIL
, NULL
, NULL
);
934 if ((Action
& BROWSER_ACTION_RESET
) == BROWSER_ACTION_RESET
) {
935 gResetRequired
= TRUE
;
938 if ((Action
& BROWSER_ACTION_EXIT
) == BROWSER_ACTION_EXIT
) {
940 // Form Exit without saving, Similar to ESC Key.
941 // FormSet Exit without saving, Exit SendForm.
942 // System Exit without saving, CallExitHandler and Exit SendForm.
944 DiscardForm (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, gBrowserSettingScope
);
945 if (gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) {
946 FindNextMenu (gCurrentSelection
, gBrowserSettingScope
);
947 } else if (gBrowserSettingScope
== SystemLevel
) {
948 if (ExitHandlerFunction
!= NULL
) {
949 ExitHandlerFunction ();
951 gCurrentSelection
->Action
= UI_ACTION_EXIT
;
959 Check whether the formset guid is in this Hii package list.
961 @param HiiHandle The HiiHandle for this HII package list.
962 @param FormSetGuid The formset guid for the request formset.
964 @retval TRUE Find the formset guid.
965 @retval FALSE Not found the formset guid.
969 GetFormsetGuidFromHiiHandle (
970 IN EFI_HII_HANDLE HiiHandle
,
971 IN EFI_GUID
*FormSetGuid
974 EFI_HII_PACKAGE_LIST_HEADER
*HiiPackageList
;
978 UINT32 PackageListLength
;
979 EFI_HII_PACKAGE_HEADER PackageHeader
;
986 HiiPackageList
= NULL
;
989 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
990 if (Status
== EFI_BUFFER_TOO_SMALL
) {
991 HiiPackageList
= AllocatePool (BufferSize
);
992 ASSERT (HiiPackageList
!= NULL
);
994 Status
= mHiiDatabase
->ExportPackageLists (mHiiDatabase
, HiiHandle
, &BufferSize
, HiiPackageList
);
996 if (EFI_ERROR (Status
) || HiiPackageList
== NULL
) {
1001 // Get Form package from this HII package List
1003 Offset
= sizeof (EFI_HII_PACKAGE_LIST_HEADER
);
1005 CopyMem (&PackageListLength
, &HiiPackageList
->PackageLength
, sizeof (UINT32
));
1007 while (Offset
< PackageListLength
) {
1008 Package
= ((UINT8
*) HiiPackageList
) + Offset
;
1009 CopyMem (&PackageHeader
, Package
, sizeof (EFI_HII_PACKAGE_HEADER
));
1010 Offset
+= PackageHeader
.Length
;
1012 if (PackageHeader
.Type
== EFI_HII_PACKAGE_FORMS
) {
1014 // Search FormSet in this Form Package
1016 Offset2
= sizeof (EFI_HII_PACKAGE_HEADER
);
1017 while (Offset2
< PackageHeader
.Length
) {
1018 OpCodeData
= Package
+ Offset2
;
1020 if (((EFI_IFR_OP_HEADER
*) OpCodeData
)->OpCode
== EFI_IFR_FORM_SET_OP
) {
1021 if (CompareGuid (FormSetGuid
, (EFI_GUID
*)(OpCodeData
+ sizeof (EFI_IFR_OP_HEADER
)))){
1027 Offset2
+= ((EFI_IFR_OP_HEADER
*) OpCodeData
)->Length
;
1035 FreePool (HiiPackageList
);
1041 Find HII Handle in the HII database associated with given Device Path.
1043 If DevicePath is NULL, then ASSERT.
1045 @param DevicePath Device Path associated with the HII package list
1047 @param FormsetGuid The formset guid for this formset.
1049 @retval Handle HII package list Handle associated with the Device
1051 @retval NULL Hii Package list handle is not found.
1055 DevicePathToHiiHandle (
1056 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
1057 IN EFI_GUID
*FormsetGuid
1061 EFI_DEVICE_PATH_PROTOCOL
*TmpDevicePath
;
1064 EFI_HANDLE DriverHandle
;
1065 EFI_HII_HANDLE
*HiiHandles
;
1066 EFI_HII_HANDLE HiiHandle
;
1068 ASSERT (DevicePath
!= NULL
);
1070 TmpDevicePath
= DevicePath
;
1072 // Locate Device Path Protocol handle buffer
1074 Status
= gBS
->LocateDevicePath (
1075 &gEfiDevicePathProtocolGuid
,
1079 if (EFI_ERROR (Status
) || !IsDevicePathEnd (TmpDevicePath
)) {
1084 // Retrieve all HII Handles from HII database
1086 HiiHandles
= HiiGetHiiHandles (NULL
);
1087 if (HiiHandles
== NULL
) {
1092 // Search Hii Handle by Driver Handle
1095 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
1096 Status
= mHiiDatabase
->GetPackageListHandle (
1101 if (!EFI_ERROR (Status
) && (Handle
== DriverHandle
)) {
1102 if (GetFormsetGuidFromHiiHandle(HiiHandles
[Index
], FormsetGuid
)) {
1103 HiiHandle
= HiiHandles
[Index
];
1107 if (HiiHandle
!= NULL
) {
1113 FreePool (HiiHandles
);
1118 Find HII Handle in the HII database associated with given form set guid.
1120 If FormSetGuid is NULL, then ASSERT.
1122 @param ComparingGuid FormSet Guid associated with the HII package list
1125 @retval Handle HII package list Handle associated with the Device
1127 @retval NULL Hii Package list handle is not found.
1131 FormSetGuidToHiiHandle (
1132 EFI_GUID
*ComparingGuid
1135 EFI_HII_HANDLE
*HiiHandles
;
1136 EFI_HII_HANDLE HiiHandle
;
1139 ASSERT (ComparingGuid
!= NULL
);
1143 // Get all the Hii handles
1145 HiiHandles
= HiiGetHiiHandles (NULL
);
1146 ASSERT (HiiHandles
!= NULL
);
1149 // Search for formset of each class type
1151 for (Index
= 0; HiiHandles
[Index
] != NULL
; Index
++) {
1152 if (GetFormsetGuidFromHiiHandle(HiiHandles
[Index
], ComparingGuid
)) {
1153 HiiHandle
= HiiHandles
[Index
];
1157 if (HiiHandle
!= NULL
) {
1162 FreePool (HiiHandles
);
1168 check how to process the changed data in current form or form set.
1170 @param Selection On input, Selection tell setup browser the information
1171 about the Selection, form and formset to be displayed.
1172 On output, Selection return the screen item that is selected
1175 @param Scope Data save or discard scope, form or formset.
1177 @retval TRUE Success process the changed data, will return to the parent form.
1178 @retval FALSE Reject to process the changed data, will stay at current form.
1181 ProcessChangedData (
1182 IN OUT UI_MENU_SELECTION
*Selection
,
1183 IN BROWSER_SETTING_SCOPE Scope
1189 switch (mFormDisplay
->ConfirmDataChange()) {
1190 case BROWSER_ACTION_DISCARD
:
1191 DiscardForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1194 case BROWSER_ACTION_SUBMIT
:
1195 SubmitForm (Selection
->FormSet
, Selection
->Form
, Scope
);
1198 case BROWSER_ACTION_NONE
:
1204 // if Invalid value return, process same as BROWSER_ACTION_NONE.
1214 Find parent formset menu(the first menu which has different formset) for current menu.
1215 If not find, just return to the first menu.
1217 @param Selection The selection info.
1222 IN OUT UI_MENU_SELECTION
*Selection
1225 FORM_ENTRY_INFO
*CurrentMenu
;
1226 FORM_ENTRY_INFO
*ParentMenu
;
1228 CurrentMenu
= Selection
->CurrentMenu
;
1229 ParentMenu
= UiFindParentMenu(CurrentMenu
);
1232 // Find a menu which has different formset guid with current.
1234 while (ParentMenu
!= NULL
&& CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1235 CurrentMenu
= ParentMenu
;
1236 ParentMenu
= UiFindParentMenu(CurrentMenu
);
1239 if (ParentMenu
!= NULL
) {
1240 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1241 Selection
->Handle
= ParentMenu
->HiiHandle
;
1242 Selection
->FormId
= ParentMenu
->FormId
;
1243 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1245 Selection
->FormId
= CurrentMenu
->FormId
;
1246 Selection
->QuestionId
= CurrentMenu
->QuestionId
;
1249 Selection
->Statement
= NULL
;
1253 Process the goto op code, update the info in the selection structure.
1255 @param Statement The statement belong to goto op code.
1256 @param Selection The selection info.
1258 @retval EFI_SUCCESS The menu process successfully.
1259 @return Other value if the process failed.
1263 IN OUT FORM_BROWSER_STATEMENT
*Statement
,
1264 IN OUT UI_MENU_SELECTION
*Selection
1268 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1269 FORM_BROWSER_FORM
*RefForm
;
1271 EFI_HII_HANDLE HiiHandle
;
1273 Status
= EFI_SUCCESS
;
1278 // Prepare the device path check, get the device path info first.
1280 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0) {
1281 StringPtr
= GetToken (Statement
->HiiValue
.Value
.ref
.DevicePath
, Selection
->FormSet
->HiiHandle
);
1285 // Check whether the device path string is a valid string.
1287 if (Statement
->HiiValue
.Value
.ref
.DevicePath
!= 0 && StringPtr
!= NULL
&& StringPtr
[0] != L
'\0') {
1288 if (Selection
->Form
->ModalForm
) {
1293 // Goto another Hii Package list
1295 if (mPathFromText
!= NULL
) {
1296 DevicePath
= mPathFromText
->ConvertTextToDevicePath(StringPtr
);
1297 if (DevicePath
!= NULL
) {
1298 HiiHandle
= DevicePathToHiiHandle (DevicePath
, &Statement
->HiiValue
.Value
.ref
.FormSetGuid
);
1299 FreePool (DevicePath
);
1301 FreePool (StringPtr
);
1304 // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
1306 PopupErrorMessage(BROWSER_PROTOCOL_NOT_FOUND
, NULL
, NULL
);
1307 FreePool (StringPtr
);
1311 if (HiiHandle
!= Selection
->Handle
) {
1313 // Goto another Formset, check for uncommitted data
1315 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1316 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1317 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1323 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1324 Selection
->Handle
= HiiHandle
;
1325 if (Selection
->Handle
== NULL
) {
1327 // If target Hii Handle not found, exit current formset.
1329 FindParentFormSet(Selection
);
1333 CopyMem (&Selection
->FormSetGuid
,&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1334 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1335 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1336 } else if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &gZeroGuid
)) {
1337 if (Selection
->Form
->ModalForm
) {
1340 if (!CompareGuid (&Statement
->HiiValue
.Value
.ref
.FormSetGuid
, &Selection
->FormSetGuid
)) {
1342 // Goto another Formset, check for uncommitted data
1344 if ((gBrowserSettingScope
== FormLevel
|| gBrowserSettingScope
== FormSetLevel
) &&
1345 IsNvUpdateRequiredForFormSet(Selection
->FormSet
)) {
1346 if (!ProcessChangedData(Selection
, FormSetLevel
)) {
1352 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1353 Selection
->Handle
= FormSetGuidToHiiHandle(&Statement
->HiiValue
.Value
.ref
.FormSetGuid
);
1354 if (Selection
->Handle
== NULL
) {
1356 // If target Hii Handle not found, exit current formset.
1358 FindParentFormSet(Selection
);
1362 CopyMem (&Selection
->FormSetGuid
, &Statement
->HiiValue
.Value
.ref
.FormSetGuid
, sizeof (EFI_GUID
));
1363 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1364 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1365 } else if (Statement
->HiiValue
.Value
.ref
.FormId
!= 0) {
1367 // Goto another Form, check for uncommitted data
1369 if (Statement
->HiiValue
.Value
.ref
.FormId
!= Selection
->FormId
) {
1370 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm(Selection
->Form
))) {
1371 if (!ProcessChangedData (Selection
, FormLevel
)) {
1377 RefForm
= IdToForm (Selection
->FormSet
, Statement
->HiiValue
.Value
.ref
.FormId
);
1378 if ((RefForm
!= NULL
) && (RefForm
->SuppressExpression
!= NULL
)) {
1379 if (EvaluateExpressionList(RefForm
->SuppressExpression
, TRUE
, Selection
->FormSet
, RefForm
) != ExpressFalse
) {
1381 // Form is suppressed.
1383 PopupErrorMessage(BROWSER_FORM_SUPPRESS
, NULL
, NULL
);
1388 Selection
->FormId
= Statement
->HiiValue
.Value
.ref
.FormId
;
1389 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1390 } else if (Statement
->HiiValue
.Value
.ref
.QuestionId
!= 0) {
1391 Selection
->QuestionId
= Statement
->HiiValue
.Value
.ref
.QuestionId
;
1399 Process Question Config.
1401 @param Selection The UI menu selection.
1402 @param Question The Question to be peocessed.
1404 @retval EFI_SUCCESS Question Config process success.
1405 @retval Other Question Config process fail.
1409 ProcessQuestionConfig (
1410 IN UI_MENU_SELECTION
*Selection
,
1411 IN FORM_BROWSER_STATEMENT
*Question
1418 if (Question
->QuestionConfig
== 0) {
1425 ConfigResp
= GetToken (Question
->QuestionConfig
, Selection
->FormSet
->HiiHandle
);
1426 if (ConfigResp
== NULL
) {
1427 return EFI_NOT_FOUND
;
1431 // Send config to Configuration Driver
1433 Status
= mHiiConfigRouting
->RouteConfig (
1444 Process the user input data.
1446 @param UserInput The user input data.
1447 @param ChangeHighlight Whether need to change the highlight statement.
1449 @retval EFI_SUCESSS This function always return successfully for now.
1454 IN USER_INPUT
*UserInput
,
1455 IN BOOLEAN ChangeHighlight
1459 FORM_BROWSER_STATEMENT
*Statement
;
1461 Status
= EFI_SUCCESS
;
1464 // When Exit from FormDisplay function, one of the below two cases must be true.
1466 ASSERT (UserInput
->Action
!= 0 || UserInput
->SelectedStatement
!= NULL
);
1469 // Remove the last highligh question id, this id will update when show next form.
1471 gCurrentSelection
->QuestionId
= 0;
1474 // First process the Action field in USER_INPUT.
1476 if (UserInput
->Action
!= 0) {
1477 Status
= ProcessAction (UserInput
->Action
, UserInput
->DefaultId
);
1478 if (EFI_ERROR (Status
)) {
1483 // Clear the highlight info.
1485 gCurrentSelection
->Statement
= NULL
;
1487 if (UserInput
->SelectedStatement
!= NULL
) {
1488 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1489 ASSERT (Statement
!= NULL
);
1491 // Save the current highlight menu in the menu history data.
1492 // which will be used when later browse back to this form.
1494 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1496 // For statement like text, actio, it not has question id.
1497 // So use FakeQuestionId to save the question.
1499 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1500 mCurFakeQestId
= Statement
->FakeQuestionId
;
1506 Statement
= GetBrowserStatement(UserInput
->SelectedStatement
);
1507 ASSERT (Statement
!= NULL
);
1509 gCurrentSelection
->Statement
= Statement
;
1511 if (ChangeHighlight
) {
1513 // This question is the current user select one,record it and later
1514 // show it as the highlight question.
1516 gCurrentSelection
->CurrentMenu
->QuestionId
= Statement
->QuestionId
;
1518 // For statement like text, actio, it not has question id.
1519 // So use FakeQuestionId to save the question.
1521 if (gCurrentSelection
->CurrentMenu
->QuestionId
== 0) {
1522 mCurFakeQestId
= Statement
->FakeQuestionId
;
1528 switch (Statement
->Operand
) {
1529 case EFI_IFR_REF_OP
:
1530 Status
= ProcessGotoOpCode(Statement
, gCurrentSelection
);
1533 case EFI_IFR_ACTION_OP
:
1535 // Process the Config string <ConfigResp>
1537 Status
= ProcessQuestionConfig (gCurrentSelection
, Statement
);
1540 case EFI_IFR_RESET_BUTTON_OP
:
1542 // Reset Question to default value specified by DefaultId
1544 Status
= ExtractDefault (gCurrentSelection
->FormSet
, NULL
, Statement
->DefaultId
, FormSetLevel
, GetDefaultForAll
, NULL
, FALSE
);
1545 UpdateStatementStatus (gCurrentSelection
->FormSet
, NULL
, FormSetLevel
);
1549 switch (Statement
->Operand
) {
1550 case EFI_IFR_STRING_OP
:
1551 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1552 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1553 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1554 FreePool (UserInput
->InputValue
.Buffer
);
1557 case EFI_IFR_PASSWORD_OP
:
1558 if (UserInput
->InputValue
.Buffer
== NULL
) {
1560 // User not input new password, just return.
1565 DeleteString(Statement
->HiiValue
.Value
.string
, gCurrentSelection
->FormSet
->HiiHandle
);
1566 Statement
->HiiValue
.Value
.string
= UserInput
->InputValue
.Value
.string
;
1567 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1568 FreePool (UserInput
->InputValue
.Buffer
);
1570 // Two password match, send it to Configuration Driver
1572 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != 0) {
1573 PasswordCheck (NULL
, UserInput
->SelectedStatement
, (CHAR16
*) Statement
->BufferValue
);
1575 // Clean the value after saved it.
1577 ZeroMem (Statement
->BufferValue
, (UINTN
) UserInput
->InputValue
.BufferLen
);
1578 HiiSetString (gCurrentSelection
->FormSet
->HiiHandle
, Statement
->HiiValue
.Value
.string
, (CHAR16
*)Statement
->BufferValue
, NULL
);
1580 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithHiiDriver
);
1584 case EFI_IFR_ORDERED_LIST_OP
:
1585 CopyMem (Statement
->BufferValue
, UserInput
->InputValue
.Buffer
, UserInput
->InputValue
.BufferLen
);
1589 CopyMem (&Statement
->HiiValue
, &UserInput
->InputValue
, sizeof (EFI_HII_VALUE
));
1601 Display form and wait for user to select one menu option, then return it.
1603 @retval EFI_SUCESSS This function always return successfully for now.
1612 USER_INPUT UserInput
;
1613 FORM_ENTRY_INFO
*CurrentMenu
;
1614 BOOLEAN ChangeHighlight
;
1616 ZeroMem (&UserInput
, sizeof (USER_INPUT
));
1619 // Update the menu history data.
1621 CurrentMenu
= UiFindMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
, gCurrentSelection
->FormId
);
1622 if (CurrentMenu
== NULL
) {
1624 // Current menu not found, add it to the menu tree
1626 CurrentMenu
= UiAddMenuList (gCurrentSelection
->Handle
, &gCurrentSelection
->FormSetGuid
,
1627 gCurrentSelection
->FormId
, gCurrentSelection
->QuestionId
);
1628 ASSERT (CurrentMenu
!= NULL
);
1630 gCurrentSelection
->CurrentMenu
= CurrentMenu
;
1633 // Find currrent highlight statement.
1635 if (gCurrentSelection
->QuestionId
== 0) {
1637 // Highlight not specified, fetch it from cached menu
1639 gCurrentSelection
->QuestionId
= CurrentMenu
->QuestionId
;
1643 // Evaluate all the Expressions in this Form
1645 Status
= EvaluateFormExpressions (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
);
1646 if (EFI_ERROR (Status
)) {
1650 UpdateDisplayFormData ();
1653 // Three possible status maybe return.
1655 // EFI_INVALID_PARAMETER: The input dimension info is not valid.
1656 // EFI_NOT_FOUND: The input value for oneof/orderedlist opcode is not valid
1657 // and an valid value has return.
1658 // EFI_SUCCESS: Success shows form and get user input in UserInput paramenter.
1660 Status
= mFormDisplay
->FormDisplay (&gDisplayFormData
, &UserInput
);
1661 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_FOUND
) {
1662 FreeDisplayFormData();
1667 // If status is EFI_SUCCESS, means user has change the highlight menu and new user input return.
1668 // in this case, browser need to change the highlight menu.
1669 // If status is EFI_NOT_FOUND, means the input DisplayFormData has error for oneof/orderedlist
1670 // opcode and new valid value has return, browser core need to adjust
1671 // value for this opcode and shows this form again.
1673 ChangeHighlight
= (Status
== EFI_SUCCESS
? TRUE
:FALSE
);
1675 Status
= ProcessUserInput (&UserInput
, ChangeHighlight
);
1677 FreeDisplayFormData();
1683 Functions which are registered to receive notification of
1684 database events have this prototype. The actual event is encoded
1685 in NotifyType. The following table describes how PackageType,
1686 PackageGuid, Handle, and Package are used for each of the
1689 @param PackageType Package type of the notification.
1691 @param PackageGuid If PackageType is
1692 EFI_HII_PACKAGE_TYPE_GUID, then this is
1693 the pointer to the GUID from the Guid
1694 field of EFI_HII_PACKAGE_GUID_HEADER.
1695 Otherwise, it must be NULL.
1697 @param Package Points to the package referred to by the
1698 notification Handle The handle of the package
1699 list which contains the specified package.
1701 @param Handle The HII handle.
1703 @param NotifyType The type of change concerning the
1705 EFI_HII_DATABASE_NOTIFY_TYPE.
1711 IN UINT8 PackageType
,
1712 IN CONST EFI_GUID
*PackageGuid
,
1713 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
1714 IN EFI_HII_HANDLE Handle
,
1715 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
1718 mHiiPackageListUpdated
= TRUE
;
1724 Update the NV flag info for this form set.
1726 @param FormSet FormSet data structure.
1730 IsNvUpdateRequiredForFormSet (
1731 IN FORM_BROWSER_FORMSET
*FormSet
1735 FORM_BROWSER_FORM
*Form
;
1739 // Not finished question initialization, return FALSE.
1741 if (!FormSet
->QuestionInited
) {
1747 Link
= GetFirstNode (&FormSet
->FormListHead
);
1748 while (!IsNull (&FormSet
->FormListHead
, Link
)) {
1749 Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
1751 RetVal
= IsNvUpdateRequiredForForm(Form
);
1756 Link
= GetNextNode (&FormSet
->FormListHead
, Link
);
1763 Update the NvUpdateRequired flag for a form.
1765 @param Form Form data structure.
1769 IsNvUpdateRequiredForForm (
1770 IN FORM_BROWSER_FORM
*Form
1774 FORM_BROWSER_STATEMENT
*Statement
;
1776 Link
= GetFirstNode (&Form
->StatementListHead
);
1777 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1778 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1780 if (Statement
->ValueChanged
) {
1784 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1791 Find menu which will show next time.
1793 @param Selection On input, Selection tell setup browser the information
1794 about the Selection, form and formset to be displayed.
1795 On output, Selection return the screen item that is selected
1797 @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.
1798 else, we need to exit current formset.
1800 @retval TRUE Exit current form.
1801 @retval FALSE User press ESC and keep in current form.
1805 IN OUT UI_MENU_SELECTION
*Selection
,
1806 IN BROWSER_SETTING_SCOPE SettingLevel
1809 FORM_ENTRY_INFO
*CurrentMenu
;
1810 FORM_ENTRY_INFO
*ParentMenu
;
1811 BROWSER_SETTING_SCOPE Scope
;
1813 CurrentMenu
= Selection
->CurrentMenu
;
1815 Scope
= FormSetLevel
;
1817 if (CurrentMenu
!= NULL
&& (ParentMenu
= UiFindParentMenu(CurrentMenu
)) != NULL
) {
1819 // we have a parent, so go to the parent menu
1821 if (CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1822 if (SettingLevel
== FormSetLevel
) {
1824 // Find a menu which has different formset guid with current.
1826 while (CompareGuid (&CurrentMenu
->FormSetGuid
, &ParentMenu
->FormSetGuid
)) {
1827 CurrentMenu
= ParentMenu
;
1828 if ((ParentMenu
= UiFindParentMenu(CurrentMenu
)) == NULL
) {
1833 if (ParentMenu
!= NULL
) {
1834 Scope
= FormSetLevel
;
1840 Scope
= FormSetLevel
;
1845 // Form Level Check whether the data is changed.
1847 if ((gBrowserSettingScope
== FormLevel
&& IsNvUpdateRequiredForForm (Selection
->Form
)) ||
1848 (gBrowserSettingScope
== FormSetLevel
&& IsNvUpdateRequiredForFormSet(Selection
->FormSet
) && Scope
== FormSetLevel
)) {
1849 if (!ProcessChangedData(Selection
, Scope
)) {
1854 if (ParentMenu
!= NULL
) {
1856 // ParentMenu is found. Then, go to it.
1858 if (Scope
== FormLevel
) {
1859 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
1861 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
1862 CopyMem (&Selection
->FormSetGuid
, &ParentMenu
->FormSetGuid
, sizeof (EFI_GUID
));
1863 Selection
->Handle
= ParentMenu
->HiiHandle
;
1866 Selection
->Statement
= NULL
;
1868 Selection
->FormId
= ParentMenu
->FormId
;
1869 Selection
->QuestionId
= ParentMenu
->QuestionId
;
1872 // Clear highlight record for this menu
1874 CurrentMenu
->QuestionId
= 0;
1879 // Current in root page, exit the SendForm
1881 Selection
->Action
= UI_ACTION_EXIT
;
1887 Call the call back function for the question and process the return action.
1889 @param Selection On input, Selection tell setup browser the information
1890 about the Selection, form and formset to be displayed.
1891 On output, Selection return the screen item that is selected
1893 @param FormSet The formset this question belong to.
1894 @param Form The form this question belong to.
1895 @param Question The Question which need to call.
1896 @param Action The action request.
1897 @param SkipSaveOrDiscard Whether skip save or discard action.
1899 @retval EFI_SUCCESS The call back function excutes successfully.
1900 @return Other value if the call back function failed to excute.
1903 ProcessCallBackFunction (
1904 IN OUT UI_MENU_SELECTION
*Selection
,
1905 IN FORM_BROWSER_FORMSET
*FormSet
,
1906 IN FORM_BROWSER_FORM
*Form
,
1907 IN FORM_BROWSER_STATEMENT
*Question
,
1908 IN EFI_BROWSER_ACTION Action
,
1909 IN BOOLEAN SkipSaveOrDiscard
1913 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
1914 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
1915 EFI_HII_VALUE
*HiiValue
;
1916 EFI_IFR_TYPE_VALUE
*TypeValue
;
1917 FORM_BROWSER_STATEMENT
*Statement
;
1918 BOOLEAN SubmitFormIsRequired
;
1919 BOOLEAN DiscardFormIsRequired
;
1922 BROWSER_SETTING_SCOPE SettingLevel
;
1923 EFI_IFR_TYPE_VALUE BackUpValue
;
1924 UINT8
*BackUpBuffer
;
1927 ConfigAccess
= FormSet
->ConfigAccess
;
1928 SubmitFormIsRequired
= FALSE
;
1929 SettingLevel
= FormSetLevel
;
1930 DiscardFormIsRequired
= FALSE
;
1932 Status
= EFI_SUCCESS
;
1933 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1934 BackUpBuffer
= NULL
;
1936 if (ConfigAccess
== NULL
) {
1940 Link
= GetFirstNode (&Form
->StatementListHead
);
1941 while (!IsNull (&Form
->StatementListHead
, Link
)) {
1942 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
1943 Link
= GetNextNode (&Form
->StatementListHead
, Link
);
1946 // if Question != NULL, only process the question. Else, process all question in this form.
1948 if ((Question
!= NULL
) && (Statement
!= Question
)) {
1952 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) {
1957 // Check whether Statement is disabled.
1959 if (Statement
->Expression
!= NULL
) {
1960 if (EvaluateExpressionList(Statement
->Expression
, TRUE
, FormSet
, Form
) == ExpressDisable
) {
1965 HiiValue
= &Statement
->HiiValue
;
1966 TypeValue
= &HiiValue
->Value
;
1967 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
1969 // For OrderedList, passing in the value buffer to Callback()
1971 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
1975 // If EFI_BROWSER_ACTION_CHANGING type, back up the new question value.
1977 if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
1978 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
1979 BackUpBuffer
= AllocateCopyPool(Statement
->StorageWidth
+ sizeof(CHAR16
), Statement
->BufferValue
);
1981 CopyMem (&BackUpValue
, &HiiValue
->Value
, sizeof (EFI_IFR_TYPE_VALUE
));
1985 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
1986 Status
= ConfigAccess
->Callback (
1989 Statement
->QuestionId
,
1994 if (!EFI_ERROR (Status
)) {
1996 // Need to sync the value between Statement->HiiValue->Value and Statement->BufferValue
1998 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
1999 NewString
= GetToken (Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
2000 ASSERT (NewString
!= NULL
);
2002 ASSERT (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
);
2003 if (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
) {
2004 CopyMem (Statement
->BufferValue
, NewString
, StrSize (NewString
));
2006 CopyMem (Statement
->BufferValue
, NewString
, Statement
->StorageWidth
);
2008 FreePool (NewString
);
2012 // Only for EFI_BROWSER_ACTION_CHANGED need to handle this ActionRequest.
2015 case EFI_BROWSER_ACTION_CHANGED
:
2016 switch (ActionRequest
) {
2017 case EFI_BROWSER_ACTION_REQUEST_RESET
:
2018 DiscardFormIsRequired
= TRUE
;
2019 gResetRequired
= TRUE
;
2023 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
2024 SubmitFormIsRequired
= TRUE
;
2028 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
2029 DiscardFormIsRequired
= TRUE
;
2033 case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT
:
2034 SubmitFormIsRequired
= TRUE
;
2035 SettingLevel
= FormLevel
;
2039 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT
:
2040 DiscardFormIsRequired
= TRUE
;
2041 SettingLevel
= FormLevel
;
2045 case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY
:
2046 SubmitFormIsRequired
= TRUE
;
2047 SettingLevel
= FormLevel
;
2050 case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD
:
2051 DiscardFormIsRequired
= TRUE
;
2052 SettingLevel
= FormLevel
;
2060 case EFI_BROWSER_ACTION_CHANGING
:
2062 // Do the question validation.
2064 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2065 if (!EFI_ERROR (Status
)) {
2067 // According the spec, return value from call back of "changing" and
2068 // "retrieve" should update to the question's temp buffer.
2070 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2074 case EFI_BROWSER_ACTION_RETRIEVE
:
2076 // According the spec, return value from call back of "changing" and
2077 // "retrieve" should update to the question's temp buffer.
2079 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2087 // If the callback returns EFI_UNSUPPORTED for EFI_BROWSER_ACTION_CHANGING,
2088 // then the browser will use the value passed to Callback() and ignore the
2089 // value returned by Callback().
2091 if (Action
== EFI_BROWSER_ACTION_CHANGING
&& Status
== EFI_UNSUPPORTED
) {
2092 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2093 CopyMem (Statement
->BufferValue
, BackUpBuffer
, Statement
->StorageWidth
+ sizeof(CHAR16
));
2095 CopyMem (&HiiValue
->Value
, &BackUpValue
, sizeof (EFI_IFR_TYPE_VALUE
));
2099 // Do the question validation.
2101 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2102 if (!EFI_ERROR (Status
)) {
2103 SetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2108 // According the spec, return fail from call back of "changing" and
2109 // "retrieve", should restore the question's value.
2111 if ((Action
== EFI_BROWSER_ACTION_CHANGING
&& Status
!= EFI_UNSUPPORTED
) ||
2112 Action
== EFI_BROWSER_ACTION_RETRIEVE
) {
2113 GetQuestionValue(FormSet
, Form
, Statement
, GetSetValueWithEditBuffer
);
2116 if (Status
== EFI_UNSUPPORTED
) {
2118 // If return EFI_UNSUPPORTED, also consider Hii driver suceess deal with it.
2120 Status
= EFI_SUCCESS
;
2124 if (BackUpBuffer
!= NULL
) {
2125 FreePool (BackUpBuffer
);
2129 if (SubmitFormIsRequired
&& !SkipSaveOrDiscard
) {
2130 SubmitForm (FormSet
, Form
, SettingLevel
);
2133 if (DiscardFormIsRequired
&& !SkipSaveOrDiscard
) {
2134 DiscardForm (FormSet
, Form
, SettingLevel
);
2138 FindNextMenu (Selection
, SettingLevel
);
2145 Call the retrieve type call back function for one question to get the initialize data.
2147 This function only used when in the initialize stage, because in this stage, the
2148 Selection->Form is not ready. For other case, use the ProcessCallBackFunction instead.
2150 @param ConfigAccess The config access protocol produced by the hii driver.
2151 @param Statement The Question which need to call.
2152 @param FormSet The formset this question belong to.
2154 @retval EFI_SUCCESS The call back function excutes successfully.
2155 @return Other value if the call back function failed to excute.
2158 ProcessRetrieveForQuestion (
2159 IN EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
,
2160 IN FORM_BROWSER_STATEMENT
*Statement
,
2161 IN FORM_BROWSER_FORMSET
*FormSet
2165 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
2166 EFI_HII_VALUE
*HiiValue
;
2167 EFI_IFR_TYPE_VALUE
*TypeValue
;
2170 Status
= EFI_SUCCESS
;
2171 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2173 if (((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) != EFI_IFR_FLAG_CALLBACK
) || ConfigAccess
== NULL
) {
2174 return EFI_UNSUPPORTED
;
2177 HiiValue
= &Statement
->HiiValue
;
2178 TypeValue
= &HiiValue
->Value
;
2179 if (HiiValue
->Type
== EFI_IFR_TYPE_BUFFER
) {
2181 // For OrderedList, passing in the value buffer to Callback()
2183 TypeValue
= (EFI_IFR_TYPE_VALUE
*) Statement
->BufferValue
;
2186 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
2187 Status
= ConfigAccess
->Callback (
2189 EFI_BROWSER_ACTION_RETRIEVE
,
2190 Statement
->QuestionId
,
2195 if (!EFI_ERROR (Status
) && HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
2196 NewString
= GetToken (Statement
->HiiValue
.Value
.string
, FormSet
->HiiHandle
);
2197 ASSERT (NewString
!= NULL
);
2199 ASSERT (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
);
2200 if (StrLen (NewString
) * sizeof (CHAR16
) <= Statement
->StorageWidth
) {
2201 CopyMem (Statement
->BufferValue
, NewString
, StrSize (NewString
));
2203 CopyMem (Statement
->BufferValue
, NewString
, Statement
->StorageWidth
);
2205 FreePool (NewString
);
2212 The worker function that send the displays to the screen. On output,
2213 the selection made by user is returned.
2215 @param Selection On input, Selection tell setup browser the information
2216 about the Selection, form and formset to be displayed.
2217 On output, Selection return the screen item that is selected
2220 @retval EFI_SUCCESS The page is displayed successfully.
2221 @return Other value if the page failed to be diplayed.
2226 IN OUT UI_MENU_SELECTION
*Selection
2231 EFI_HANDLE NotifyHandle
;
2232 FORM_BROWSER_STATEMENT
*Statement
;
2233 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
2235 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
2238 // Register notify for Form package update
2240 Status
= mHiiDatabase
->RegisterPackageNotify (
2242 EFI_HII_PACKAGE_FORMS
,
2245 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
2248 if (EFI_ERROR (Status
)) {
2253 // Initialize current settings of Questions in this FormSet
2255 InitializeCurrentSetting (Selection
->FormSet
);
2258 // Initilize Action field.
2260 Selection
->Action
= UI_ACTION_REFRESH_FORM
;
2263 // Clean the mCurFakeQestId value is formset refreshed.
2269 // IFR is updated, force to reparse the IFR binary
2271 if (mHiiPackageListUpdated
) {
2272 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2273 mHiiPackageListUpdated
= FALSE
;
2278 // Initialize Selection->Form
2280 if (Selection
->FormId
== 0) {
2282 // Zero FormId indicates display the first Form in a FormSet
2284 Link
= GetFirstNode (&Selection
->FormSet
->FormListHead
);
2286 Selection
->Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
2287 Selection
->FormId
= Selection
->Form
->FormId
;
2289 Selection
->Form
= IdToForm (Selection
->FormSet
, Selection
->FormId
);
2292 if (Selection
->Form
== NULL
) {
2294 // No Form to display
2296 Status
= EFI_NOT_FOUND
;
2301 // Check Form is suppressed.
2303 if (Selection
->Form
->SuppressExpression
!= NULL
) {
2304 if (EvaluateExpressionList(Selection
->Form
->SuppressExpression
, TRUE
, Selection
->FormSet
, Selection
->Form
) == ExpressSuppress
) {
2306 // Form is suppressed.
2308 PopupErrorMessage(BROWSER_FORM_SUPPRESS
, NULL
, NULL
);
2309 Status
= EFI_NOT_FOUND
;
2315 // Before display new form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_OPEN
2316 // for each question with callback flag.
2317 // New form may be the first form, or the different form after another form close.
2319 if (((Selection
->Handle
!= mCurrentHiiHandle
) ||
2320 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2321 (Selection
->FormId
!= mCurrentFormId
))) {
2323 // Update Retrieve flag.
2325 mFinishRetrieveCall
= FALSE
;
2328 // Keep current form information
2330 mCurrentHiiHandle
= Selection
->Handle
;
2331 CopyGuid (&mCurrentFormSetGuid
, &Selection
->FormSetGuid
);
2332 mCurrentFormId
= Selection
->FormId
;
2334 if (ConfigAccess
!= NULL
) {
2335 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_FORM_OPEN
, FALSE
);
2336 if (EFI_ERROR (Status
)) {
2341 // IFR is updated during callback of open form, force to reparse the IFR binary
2343 if (mHiiPackageListUpdated
) {
2344 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2345 mHiiPackageListUpdated
= FALSE
;
2352 // Load Questions' Value for display
2354 Status
= LoadFormSetConfig (Selection
, Selection
->FormSet
);
2355 if (EFI_ERROR (Status
)) {
2359 if (!mFinishRetrieveCall
) {
2361 // Finish call RETRIEVE callback for this form.
2363 mFinishRetrieveCall
= TRUE
;
2365 if (ConfigAccess
!= NULL
) {
2366 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_RETRIEVE
, FALSE
);
2367 if (EFI_ERROR (Status
)) {
2372 // IFR is updated during callback of open form, force to reparse the IFR binary
2374 if (mHiiPackageListUpdated
) {
2375 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
2376 mHiiPackageListUpdated
= FALSE
;
2385 Status
= DisplayForm ();
2386 if (EFI_ERROR (Status
)) {
2391 // Check Selected Statement (if press ESC, Selection->Statement will be NULL)
2393 Statement
= Selection
->Statement
;
2394 if (Statement
!= NULL
) {
2395 if ((ConfigAccess
!= NULL
) &&
2396 ((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
) &&
2397 (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
2398 Status
= ProcessCallBackFunction(Selection
, Selection
->FormSet
, Selection
->Form
, Statement
, EFI_BROWSER_ACTION_CHANGING
, FALSE
);
2399 if (Statement
->Operand
== EFI_IFR_REF_OP
) {
2401 // Process dynamic update ref opcode.
2403 if (!EFI_ERROR (Status
)) {
2404 Status
= ProcessGotoOpCode(Statement
, Selection
);
2408 // Callback return error status or status return from process goto opcode.
2410 if (EFI_ERROR (Status
)) {
2412 // Cross reference will not be taken
2414 Selection
->FormId
= Selection
->Form
->FormId
;
2415 Selection
->QuestionId
= 0;
2420 // Verify whether question value has checked, update the ValueChanged flag in Question.
2422 IsQuestionValueChanged(gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithBuffer
);
2424 if (!EFI_ERROR (Status
) && Statement
->Operand
!= EFI_IFR_REF_OP
) {
2425 ProcessCallBackFunction(Selection
, Selection
->FormSet
, Selection
->Form
, Statement
, EFI_BROWSER_ACTION_CHANGED
, FALSE
);
2429 // Do the question validation.
2431 Status
= ValueChangedValidation (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
);
2432 if (!EFI_ERROR (Status
) && (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
2433 SetQuestionValue (gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithEditBuffer
);
2435 // Verify whether question value has checked, update the ValueChanged flag in Question.
2437 IsQuestionValueChanged(gCurrentSelection
->FormSet
, gCurrentSelection
->Form
, Statement
, GetSetValueWithBuffer
);
2442 // If question has EFI_IFR_FLAG_RESET_REQUIRED flag and without storage and process question success till here,
2443 // trig the gResetFlag.
2445 if ((Status
== EFI_SUCCESS
) &&
2446 (Statement
->Storage
== NULL
) &&
2447 ((Statement
->QuestionFlags
& EFI_IFR_FLAG_RESET_REQUIRED
) != 0)) {
2448 gResetRequired
= TRUE
;
2453 // Check whether Exit flag is TRUE.
2455 if (gExitRequired
) {
2456 switch (gBrowserSettingScope
) {
2458 Selection
->Action
= UI_ACTION_EXIT
;
2463 FindNextMenu (Selection
, gBrowserSettingScope
);
2470 gExitRequired
= FALSE
;
2474 // Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE
2475 // for each question with callback flag.
2477 if ((ConfigAccess
!= NULL
) &&
2478 ((Selection
->Action
== UI_ACTION_EXIT
) ||
2479 (Selection
->Handle
!= mCurrentHiiHandle
) ||
2480 (!CompareGuid (&Selection
->FormSetGuid
, &mCurrentFormSetGuid
)) ||
2481 (Selection
->FormId
!= mCurrentFormId
))) {
2483 Status
= ProcessCallBackFunction (Selection
, Selection
->FormSet
, Selection
->Form
, NULL
, EFI_BROWSER_ACTION_FORM_CLOSE
, FALSE
);
2484 if (EFI_ERROR (Status
)) {
2488 } while (Selection
->Action
== UI_ACTION_REFRESH_FORM
);
2492 // Reset current form information to the initial setting when error happens or form exit.
2494 if (EFI_ERROR (Status
) || Selection
->Action
== UI_ACTION_EXIT
) {
2495 mCurrentHiiHandle
= NULL
;
2496 CopyGuid (&mCurrentFormSetGuid
, &gZeroGuid
);
2501 // Unregister notify for Form package update
2503 mHiiDatabase
->UnregisterPackageNotify (