4 Copyright (c) 2006, Intel Corporation
5 All rights reserved. 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.
32 // For now, allocate an arbitrarily long buffer
34 Buffer
= AllocateZeroPool (0x10000);
35 ASSERT (Buffer
!= NULL
);
38 // Set foreground and background as defined
40 gST
->ConOut
->SetAttribute (gST
->ConOut
, TextAttribute
);
43 // Much faster to buffer the long string instead of print it a character at a time
45 SetUnicodeMem (Buffer
, RightColumn
- LeftColumn
, L
' ');
48 // Clear the desired area with the appropriate foreground/background
50 for (Row
= TopRow
; Row
<= BottomRow
; Row
++) {
51 PrintStringAt (LeftColumn
, Row
, Buffer
);
54 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, LeftColumn
, TopRow
);
68 for (Length
= 0; Destination
[Length
] != 0; Length
++)
72 // We now have the length of the original string
73 // We can safely assume for now that we are concatenating a narrow value to this string.
74 // For instance, the string is "XYZ" and cat'ing ">"
75 // If this assumption changes, we need to make this routine a bit more complex
77 Destination
[Length
] = (CHAR16
) NARROW_CHAR
;
80 StrCpy (Destination
+ Length
, Source
);
98 // Advance to the null-terminator or to the first width directive
101 (String
[Index
] != NARROW_CHAR
) && (String
[Index
] != WIDE_CHAR
) && (String
[Index
] != 0);
102 Index
++, Count
= Count
+ IncrementValue
107 // We hit the null-terminator, we now have a count
109 if (String
[Index
] == 0) {
113 // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
114 // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
116 if (String
[Index
] == NARROW_CHAR
) {
118 // Skip to the next character
124 // Skip to the next character
129 } while (String
[Index
] != 0);
132 // Increment by one to include the null-terminator in the size
136 return Count
* sizeof (CHAR16
);
149 CHAR16
*StrFrontPageBanner
;
150 EFI_SCREEN_DESCRIPTOR LocalScreen
;
153 ZeroMem (&LocalScreen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
154 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &LocalScreen
.RightColumn
, &LocalScreen
.BottomRow
);
155 ClearLines (0, LocalScreen
.RightColumn
, 0, LocalScreen
.BottomRow
, KEYHELP_BACKGROUND
);
157 CopyMem (&LocalScreen
, &gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
160 // For now, allocate an arbitrarily long buffer
162 Buffer
= AllocateZeroPool (0x10000);
163 ASSERT (Buffer
!= NULL
);
165 Character
= (CHAR16
) BOXDRAW_HORIZONTAL
;
167 for (Index
= 0; Index
+ 2 < (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
); Index
++) {
168 Buffer
[Index
] = Character
;
171 if (gClassOfVfr
== EFI_FRONT_PAGE_SUBCLASS
) {
173 // ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);
176 LocalScreen
.LeftColumn
,
177 LocalScreen
.RightColumn
,
179 FRONT_PAGE_HEADER_HEIGHT
- 1 + LocalScreen
.TopRow
,
180 BANNER_TEXT
| BANNER_BACKGROUND
183 // for (Line = 0; Line < BANNER_HEIGHT; Line++) {
185 for (Line
= (UINT8
) LocalScreen
.TopRow
; Line
< BANNER_HEIGHT
+ (UINT8
) LocalScreen
.TopRow
; Line
++) {
187 // for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {
189 for (Alignment
= (UINT8
) LocalScreen
.LeftColumn
;
190 Alignment
< BANNER_COLUMNS
+ (UINT8
) LocalScreen
.LeftColumn
;
193 if (BannerData
->Banner
[Line
- (UINT8
) LocalScreen
.TopRow
][Alignment
- (UINT8
) LocalScreen
.LeftColumn
] != 0x0000) {
194 StrFrontPageBanner
= GetToken (
195 BannerData
->Banner
[Line
- (UINT8
) LocalScreen
.TopRow
][Alignment
- (UINT8
) LocalScreen
.LeftColumn
],
202 switch (Alignment
- LocalScreen
.LeftColumn
) {
205 // Handle left column
207 PrintStringAt (LocalScreen
.LeftColumn
, Line
, StrFrontPageBanner
);
212 // Handle center column
215 LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) / 3,
223 // Handle right column
226 LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) * 2 / 3,
233 FreePool (StrFrontPageBanner
);
239 LocalScreen
.LeftColumn
,
240 LocalScreen
.RightColumn
,
241 LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- FOOTER_HEIGHT
,
242 LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- 1,
243 KEYHELP_TEXT
| KEYHELP_BACKGROUND
246 if (gClassOfVfr
!= EFI_FRONT_PAGE_SUBCLASS
) {
248 LocalScreen
.LeftColumn
,
249 LocalScreen
.RightColumn
,
251 LocalScreen
.TopRow
+ NONE_FRONT_PAGE_HEADER_HEIGHT
- 1,
252 TITLE_TEXT
| TITLE_BACKGROUND
255 // Print Top border line
256 // +------------------------------------------------------------------------------+
258 // +------------------------------------------------------------------------------+
260 Character
= (CHAR16
) BOXDRAW_DOWN_RIGHT
;
262 PrintChar (Character
);
263 PrintString (Buffer
);
265 Character
= (CHAR16
) BOXDRAW_DOWN_LEFT
;
266 PrintChar (Character
);
268 Character
= (CHAR16
) BOXDRAW_VERTICAL
;
269 for (Row
= LocalScreen
.TopRow
+ 1; Row
<= LocalScreen
.TopRow
+ NONE_FRONT_PAGE_HEADER_HEIGHT
- 2; Row
++) {
270 PrintCharAt (LocalScreen
.LeftColumn
, Row
, Character
);
271 PrintCharAt (LocalScreen
.RightColumn
- 1, Row
, Character
);
274 Character
= (CHAR16
) BOXDRAW_UP_RIGHT
;
275 PrintCharAt (LocalScreen
.LeftColumn
, LocalScreen
.TopRow
+ NONE_FRONT_PAGE_HEADER_HEIGHT
- 1, Character
);
276 PrintString (Buffer
);
278 Character
= (CHAR16
) BOXDRAW_UP_LEFT
;
279 PrintChar (Character
);
281 if (gClassOfVfr
== EFI_SETUP_APPLICATION_SUBCLASS
) {
283 // Print Bottom border line
284 // +------------------------------------------------------------------------------+
286 // +------------------------------------------------------------------------------+
288 Character
= (CHAR16
) BOXDRAW_DOWN_RIGHT
;
289 PrintCharAt (LocalScreen
.LeftColumn
, LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- FOOTER_HEIGHT
, Character
);
291 PrintString (Buffer
);
293 Character
= (CHAR16
) BOXDRAW_DOWN_LEFT
;
294 PrintChar (Character
);
295 Character
= (CHAR16
) BOXDRAW_VERTICAL
;
296 for (Row
= LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- FOOTER_HEIGHT
+ 1;
297 Row
<= LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- 2;
300 PrintCharAt (LocalScreen
.LeftColumn
, Row
, Character
);
301 PrintCharAt (LocalScreen
.RightColumn
- 1, Row
, Character
);
304 Character
= (CHAR16
) BOXDRAW_UP_RIGHT
;
305 PrintCharAt (LocalScreen
.LeftColumn
, LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- 1, Character
);
307 PrintString (Buffer
);
309 Character
= (CHAR16
) BOXDRAW_UP_LEFT
;
310 PrintChar (Character
);
319 +------------------------------------------------------------------------------+
320 ?F2=Previous Page Setup Page ?
321 +------------------------------------------------------------------------------+
339 +------------------------------------------------------------------------------+
340 ?F1=Scroll Help F9=Reset to Defaults F10=Save and Exit ?
341 | ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Discard Changes |
342 +------------------------------------------------------------------------------+
347 OUT UI_MENU_OPTION
*Selection
,
348 IN UINT16 FormHandle
,
349 IN UINT16 TitleToken
,
350 IN EFI_FORM_TAGS FormTags
,
351 IN EFI_FILE_FORM_TAGS
*FileFormTagsHead
,
352 IN UINT8
*CallbackData
358 UINT16 MenuItemCount
;
359 FRAMEWORK_EFI_HII_HANDLE Handle
;
362 EFI_FILE_FORM_TAGS
*FileFormTags
;
367 EFI_SCREEN_DESCRIPTOR LocalScreen
;
370 CHAR16
*OutputString
;
372 Handle
= Selection
->Handle
;
379 CopyMem (&LocalScreen
, &gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
382 // If we hit a F2 (previous) we already nuked the menu and are simply carrying around what information we need
384 if (Selection
->Previous
) {
385 Selection
->Previous
= FALSE
;
391 StringPtr
= GetToken (TitleToken
, Handle
);
393 if (gClassOfVfr
!= EFI_FRONT_PAGE_SUBCLASS
) {
394 gST
->ConOut
->SetAttribute (gST
->ConOut
, TITLE_TEXT
| TITLE_BACKGROUND
);
396 (LocalScreen
.RightColumn
+ LocalScreen
.LeftColumn
- GetStringWidth (StringPtr
) / 2) / 2,
397 LocalScreen
.TopRow
+ 1,
402 if (gClassOfVfr
== EFI_SETUP_APPLICATION_SUBCLASS
) {
403 gST
->ConOut
->SetAttribute (gST
->ConOut
, KEYHELP_TEXT
| KEYHELP_BACKGROUND
);
406 // Display the infrastructure strings
408 if (!IsListEmpty (&gMenuList
)) {
409 PrintStringAt (LocalScreen
.LeftColumn
+ 2, LocalScreen
.TopRow
+ 1, gFunctionTwoString
);
412 PrintStringAt (LocalScreen
.LeftColumn
+ 2, LocalScreen
.BottomRow
- 4, gFunctionOneString
);
414 LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) / 3,
415 LocalScreen
.BottomRow
- 4,
419 LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) * 2 / 3,
420 LocalScreen
.BottomRow
- 4,
423 PrintAt (LocalScreen
.LeftColumn
+ 2, LocalScreen
.BottomRow
- 3, (CHAR16
*) L
"%c%c%s", ARROW_UP
, ARROW_DOWN
, gMoveHighlight
);
425 LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) / 3,
426 LocalScreen
.BottomRow
- 3,
431 // Remove Buffer allocated for StringPtr after it has been used.
433 FreePool (StringPtr
);
435 for (Index
= 0; FormTags
.Tags
[Index
].Operand
!= FRAMEWORK_EFI_IFR_END_FORM_OP
; Index
++) {
440 FileFormTags
= FileFormTagsHead
;
442 if (FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_FORM_OP
) {
443 FormId
= FormTags
.Tags
[Index
].Id
;
446 // This gives us visibility to the FileFormTags->NvRamMap to check things
447 // ActiveIfr is a global maintained by the menuing code to ensure that we
448 // are pointing to the correct formset's file data.
450 for (Count
= 0; Count
< gActiveIfr
; Count
++) {
451 FileFormTags
= FileFormTags
->NextFile
;
454 // GrayoutIf [SuppressIf]
459 // SuppressIf [GrayoutIf]
467 switch (FormTags
.Tags
[Index
].Operand
) {
468 case FRAMEWORK_EFI_IFR_SUPPRESS_IF_OP
:
471 case FRAMEWORK_EFI_IFR_GRAYOUT_IF_OP
:
476 // Advance to the next op-code
481 // We are now pointing to the beginning of the consistency checking. Let's fast forward
482 // through the AND/OR/NOT data to come up with some meaningful ID data.
485 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_AND_OP
||
486 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_OR_OP
||
487 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_GT_OP
||
488 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_GE_OP
||
489 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_NOT_OP
;
495 // We need to walk through the consistency checks until we hit the end of the consistency
496 // FALSE means evaluate this single expression
497 // The ConsistencyId refers to which expression in the Consistency database to use
500 Suppress
= ValueIsNotValid (
502 FormTags
.Tags
[Index
].ConsistencyId
,
503 &FormTags
.Tags
[Index
],
509 GrayOut
= ValueIsNotValid (
511 FormTags
.Tags
[Index
].ConsistencyId
,
512 &FormTags
.Tags
[Index
],
518 // Advance to the end of the expression (Will land us at a grayoutif/suppressif or the op-code being affected)
521 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_EQ_ID_VAL_OP
||
522 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_EQ_VAR_VAL_OP
||
523 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_EQ_ID_ID_OP
||
524 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_EQ_ID_LIST_OP
||
525 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_NOT_OP
||
526 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_AND_OP
||
527 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_OR_OP
||
528 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_TRUE_OP
||
529 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_FALSE_OP
||
530 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_GT_OP
||
531 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_GE_OP
||
532 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_LABEL_OP
;
542 // Do this two times (at most will see a suppress and grayout combination
550 FormTags
.Tags
[Index
].GrayOut
= TRUE
;
552 FormTags
.Tags
[Index
].GrayOut
= FALSE
;
554 if (Suppress
&& FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
) {
556 // Only need .Suppress field when the tag is a one_of_option. For other cases, omit them directly.
558 FormTags
.Tags
[Index
].Suppress
= TRUE
;
560 FormTags
.Tags
[Index
].Suppress
= FALSE
;
564 FormTags
.Tags
[Index
].NumberOfLines
> 0 ||
565 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_DATE_OP
||
566 FormTags
.Tags
[Index
].Operand
== FRAMEWORK_EFI_IFR_TIME_OP
571 StringPtr
= GetToken (FormTags
.Tags
[Index
].Text
, Handle
);
573 Width
= GetWidth (&FormTags
.Tags
[Index
], Handle
);
576 // This data can be retrieved over and over again. Therefore, reset to original values
577 // before processing otherwise things will start growing linearly
579 if (FormTags
.Tags
[Index
].NumberOfLines
> 1) {
580 FormTags
.Tags
[Index
].NumberOfLines
= 1;
583 for (Count
= 0; GetLineByWidth (StringPtr
, Width
, &ArrayEntry
, &OutputString
) != 0x0000;) {
585 // If there is more string to process print on the next row and increment the Skip value
587 if (StrLen (&StringPtr
[ArrayEntry
])) {
588 FormTags
.Tags
[Index
].NumberOfLines
++;
591 FreePool (OutputString
);
597 // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
600 UiAddSubMenuOption (StringPtr
, Handle
, FormTags
.Tags
, Index
, FormId
, MenuItemCount
);
604 // Keep processing menu entries based on the resultant suppress/grayout results until we hit an end-if
607 } while (FormTags
.Tags
[Index
].Operand
!= FRAMEWORK_EFI_IFR_END_IF_OP
&& Conditional
);
610 // We advanced the index for the above conditional, rewind it to keep harmony with the for loop logic
615 Selection
= UiDisplayMenu (TRUE
, FileFormTagsHead
, (FRAMEWORK_EFI_IFR_DATA_ARRAY
*) CallbackData
);
621 InitializeBrowserStrings (
625 gFunctionOneString
= GetToken (STRING_TOKEN (FUNCTION_ONE_STRING
), gHiiHandle
);
626 gFunctionTwoString
= GetToken (STRING_TOKEN (FUNCTION_TWO_STRING
), gHiiHandle
);
627 gFunctionNineString
= GetToken (STRING_TOKEN (FUNCTION_NINE_STRING
), gHiiHandle
);
628 gFunctionTenString
= GetToken (STRING_TOKEN (FUNCTION_TEN_STRING
), gHiiHandle
);
629 gEnterString
= GetToken (STRING_TOKEN (ENTER_STRING
), gHiiHandle
);
630 gEnterCommitString
= GetToken (STRING_TOKEN (ENTER_COMMIT_STRING
), gHiiHandle
);
631 gEscapeString
= GetToken (STRING_TOKEN (ESCAPE_STRING
), gHiiHandle
);
632 gMoveHighlight
= GetToken (STRING_TOKEN (MOVE_HIGHLIGHT
), gHiiHandle
);
633 gMakeSelection
= GetToken (STRING_TOKEN (MAKE_SELECTION
), gHiiHandle
);
634 gNumericInput
= GetToken (STRING_TOKEN (NUMERIC_INPUT
), gHiiHandle
);
635 gToggleCheckBox
= GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX
), gHiiHandle
);
636 gPromptForPassword
= GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD
), gHiiHandle
);
637 gPromptForNewPassword
= GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD
), gHiiHandle
);
638 gConfirmPassword
= GetToken (STRING_TOKEN (CONFIRM_PASSWORD
), gHiiHandle
);
639 gConfirmError
= GetToken (STRING_TOKEN (CONFIRM_ERROR
), gHiiHandle
);
640 gPressEnter
= GetToken (STRING_TOKEN (PRESS_ENTER
), gHiiHandle
);
641 gEmptyString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
642 gAreYouSure
= GetToken (STRING_TOKEN (ARE_YOU_SURE
), gHiiHandle
);
643 gYesResponse
= GetToken (STRING_TOKEN (ARE_YOU_SURE_YES
), gHiiHandle
);
644 gNoResponse
= GetToken (STRING_TOKEN (ARE_YOU_SURE_NO
), gHiiHandle
);
645 gMiniString
= GetToken (STRING_TOKEN (MINI_STRING
), gHiiHandle
);
646 gPlusString
= GetToken (STRING_TOKEN (PLUS_STRING
), gHiiHandle
);
647 gMinusString
= GetToken (STRING_TOKEN (MINUS_STRING
), gHiiHandle
);
648 gAdjustNumber
= GetToken (STRING_TOKEN (ADJUST_NUMBER
), gHiiHandle
);
654 IN UI_MENU_OPTION
*Selection
,
659 Update key's help imformation
662 Selection C The form that current display
663 Selected C Whether or not a tag be selected
671 UINTN LeftColumnOfHelp
;
672 UINTN RightColumnOfHelp
;
674 UINTN BottomRowOfHelp
;
675 UINTN StartColumnOfHelp
;
676 EFI_SCREEN_DESCRIPTOR LocalScreen
;
678 CopyMem (&LocalScreen
, &gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
680 SecCol
= LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) / 3;
681 ThdCol
= LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) * 2 / 3;
683 StartColumnOfHelp
= LocalScreen
.LeftColumn
+ 2;
684 LeftColumnOfHelp
= LocalScreen
.LeftColumn
+ 1;
685 RightColumnOfHelp
= LocalScreen
.RightColumn
- 2;
686 TopRowOfHelp
= LocalScreen
.BottomRow
- 4;
687 BottomRowOfHelp
= LocalScreen
.BottomRow
- 3;
689 if (gClassOfVfr
== EFI_GENERAL_APPLICATION_SUBCLASS
) {
693 gST
->ConOut
->SetAttribute (gST
->ConOut
, KEYHELP_TEXT
| KEYHELP_BACKGROUND
);
695 switch (Selection
->ThisTag
->Operand
) {
696 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
:
697 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
698 case FRAMEWORK_EFI_IFR_NUMERIC_OP
:
699 case FRAMEWORK_EFI_IFR_TIME_OP
:
700 case FRAMEWORK_EFI_IFR_DATE_OP
:
701 ClearLines (LeftColumnOfHelp
, RightColumnOfHelp
, TopRowOfHelp
, BottomRowOfHelp
, KEYHELP_TEXT
| KEYHELP_BACKGROUND
);
704 if (gClassOfVfr
== EFI_SETUP_APPLICATION_SUBCLASS
) {
705 PrintStringAt (StartColumnOfHelp
, TopRowOfHelp
, gFunctionOneString
);
706 PrintStringAt (SecCol
, TopRowOfHelp
, gFunctionNineString
);
707 PrintStringAt (ThdCol
, TopRowOfHelp
, gFunctionTenString
);
708 PrintStringAt (ThdCol
, BottomRowOfHelp
, gEscapeString
);
712 if ((Selection
->ThisTag
->Operand
== FRAMEWORK_EFI_IFR_DATE_OP
) || (Selection
->ThisTag
->Operand
== FRAMEWORK_EFI_IFR_TIME_OP
)) {
716 (CHAR16
*) L
"%c%c%c%c%s",
723 PrintStringAt (SecCol
, BottomRowOfHelp
, gAdjustNumber
);
725 PrintAt (StartColumnOfHelp
, BottomRowOfHelp
, (CHAR16
*) L
"%c%c%s", ARROW_UP
, ARROW_DOWN
, gMoveHighlight
);
726 PrintStringAt (SecCol
, BottomRowOfHelp
, gEnterString
);
729 PrintStringAt (SecCol
, BottomRowOfHelp
, gEnterCommitString
);
732 // If it is a selected numeric with manual input, display different message
734 if ((Selection
->ThisTag
->Operand
== FRAMEWORK_EFI_IFR_NUMERIC_OP
) && (Selection
->ThisTag
->Step
== 0)) {
735 PrintStringAt (SecCol
, TopRowOfHelp
, gNumericInput
);
736 } else if (Selection
->ThisTag
->Operand
!= FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
) {
737 PrintAt (StartColumnOfHelp
, BottomRowOfHelp
, L
"%c%c%s", ARROW_UP
, ARROW_DOWN
, gMoveHighlight
);
740 if (Selection
->ThisTag
->Operand
== FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
) {
741 PrintStringAt (StartColumnOfHelp
, TopRowOfHelp
, gPlusString
);
742 PrintStringAt (ThdCol
, TopRowOfHelp
, gMinusString
);
745 PrintStringAt (ThdCol
, BottomRowOfHelp
, gEscapeString
);
749 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
750 ClearLines (LeftColumnOfHelp
, RightColumnOfHelp
, TopRowOfHelp
, BottomRowOfHelp
, KEYHELP_TEXT
| KEYHELP_BACKGROUND
);
752 if (gClassOfVfr
== EFI_SETUP_APPLICATION_SUBCLASS
) {
753 PrintStringAt (StartColumnOfHelp
, TopRowOfHelp
, gFunctionOneString
);
754 PrintStringAt (SecCol
, TopRowOfHelp
, gFunctionNineString
);
755 PrintStringAt (ThdCol
, TopRowOfHelp
, gFunctionTenString
);
756 PrintStringAt (ThdCol
, BottomRowOfHelp
, gEscapeString
);
759 PrintAt (StartColumnOfHelp
, BottomRowOfHelp
, (CHAR16
*) L
"%c%c%s", ARROW_UP
, ARROW_DOWN
, gMoveHighlight
);
760 PrintStringAt (SecCol
, BottomRowOfHelp
, gToggleCheckBox
);
763 case FRAMEWORK_EFI_IFR_REF_OP
:
764 case FRAMEWORK_EFI_IFR_PASSWORD_OP
:
765 case FRAMEWORK_EFI_IFR_STRING_OP
:
766 ClearLines (LeftColumnOfHelp
, RightColumnOfHelp
, TopRowOfHelp
, BottomRowOfHelp
, KEYHELP_TEXT
| KEYHELP_BACKGROUND
);
769 if (gClassOfVfr
== EFI_SETUP_APPLICATION_SUBCLASS
) {
770 PrintStringAt (StartColumnOfHelp
, TopRowOfHelp
, gFunctionOneString
);
771 PrintStringAt (SecCol
, TopRowOfHelp
, gFunctionNineString
);
772 PrintStringAt (ThdCol
, TopRowOfHelp
, gFunctionTenString
);
773 PrintStringAt (ThdCol
, BottomRowOfHelp
, gEscapeString
);
776 PrintAt (StartColumnOfHelp
, BottomRowOfHelp
, (CHAR16
*) L
"%c%c%s", ARROW_UP
, ARROW_DOWN
, gMoveHighlight
);
777 PrintStringAt (SecCol
, BottomRowOfHelp
, gEnterString
);
779 if (Selection
->ThisTag
->Operand
!= FRAMEWORK_EFI_IFR_REF_OP
) {
781 (LocalScreen
.RightColumn
- GetStringWidth (gEnterCommitString
) / 2) / 2,
785 PrintStringAt (ThdCol
, BottomRowOfHelp
, gEscapeString
);
796 IN UI_MENU_OPTION
*Selection
,
797 IN EFI_FILE_FORM_TAGS
*FileFormTagsHead
,
799 OUT UINT16
*FormHandle
,
800 OUT UINT16
*TitleToken
,
801 OUT EFI_FORM_TAGS
*FormTags
805 EFI_FILE_FORM_TAGS
*FileFormTags
;
806 EFI_FORM_TAGS LocalTags
;
808 FileFormTags
= FileFormTagsHead
;
811 // Advance FileFormTags to the correct file's tag information.
812 // For instance, if Selection->IfrNumber is 3, that means the 4th
813 // file (0-based) in the FileFormTags linked-list contains the tag
816 for (Index
= 0; Index
< Selection
->IfrNumber
; Index
++) {
817 FileFormTags
= FileFormTags
->NextFile
;
820 LocalTags
= FileFormTags
->FormTags
;
824 // Advance Index to the first FormOp tag information
826 for (Index
= 0; FileFormTags
->FormTags
.Tags
[Index
].Operand
!= FRAMEWORK_EFI_IFR_FORM_OP
; Index
++)
830 // Advance Index to the FormOp with the correct ID value
832 for (; LocalTags
.Next
!= NULL
; LocalTags
= *LocalTags
.Next
) {
833 for (Index
= 0; LocalTags
.Tags
[Index
].Operand
!= FRAMEWORK_EFI_IFR_FORM_OP
; Index
++)
835 if (LocalTags
.Tags
[Index
].Id
== IdValue
) {
841 // return the Form Id, Text, and the File's FormTags structure
843 *FormHandle
= LocalTags
.Tags
[Index
].Id
;
844 *TitleToken
= LocalTags
.Tags
[Index
].Text
;
845 *FormTags
= LocalTags
;
853 IN UINT16 ConsistencyId
,
854 IN UINT16 CurrentVariable
,
855 IN EFI_FORM_TAGS
*FormTags
,
856 OUT EFI_FILE_FORM_TAGS
*FileFormTags
861 UINT16 QuestionIndex
;
869 // Initialize some Index variable and Status
875 Status
= EFI_SUCCESS
;
879 // Determine the number of tags for the first form
881 GetTagCount (&FormData
[Index
], &NumberOfTags
);
884 // Allocate memory for our tags on the first form
886 FormTags
->Tags
= AllocateZeroPool (NumberOfTags
* sizeof (EFI_TAG
));
887 ASSERT (FormTags
->Tags
!= NULL
);
889 for (CurrTag
= 0; FormData
[Index
] != FRAMEWORK_EFI_IFR_END_FORM_SET_OP
; CurrTag
++) {
891 // Operand = IFR OpCode
893 FormTags
->Tags
[CurrTag
].Operand
= FormData
[Index
];
896 // Assume for now 0 lines occupied by this OpCode
898 FormTags
->Tags
[CurrTag
].NumberOfLines
= 0;
901 // Determine the length of the Tag so we can later skip to the next tag in the form
906 TagLength
= FormData
[Index
+ 1];
908 // Operate on the Found OpCode
910 switch (FormData
[Index
]) {
912 case FRAMEWORK_EFI_IFR_FORM_OP
:
913 case FRAMEWORK_EFI_IFR_SUBTITLE_OP
:
914 case FRAMEWORK_EFI_IFR_TEXT_OP
:
915 case FRAMEWORK_EFI_IFR_REF_OP
:
916 IfrToFormTag (FormData
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &FormData
[Index
], NULL
);
919 case FRAMEWORK_EFI_IFR_VARSTORE_SELECT_OP
:
920 IfrToFormTag (FormData
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &FormData
[Index
], NULL
);
921 CopyMem (&CurrentVariable
, &((FRAMEWORK_EFI_IFR_VARSTORE_SELECT
*) &FormData
[Index
])->VarId
, sizeof (UINT16
));
924 case FRAMEWORK_EFI_IFR_END_FORM_OP
:
925 FormTags
->Tags
[CurrTag
].Operand
= FormData
[Index
];
926 FormTags
->Tags
[CurrTag
].NumberOfLines
= 0;
931 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
:
932 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
933 GetQuestionHeader (&FormTags
->Tags
[CurrTag
], FormData
, Index
, FileFormTags
, CurrentVariable
);
936 // Store away the CurrTag since what follows will be the answer that we
937 // need to place into the appropriate location in the tag array
940 // record for setting default later
942 QuestionIndex
= (UINT16
) CurrTag
;
945 case FRAMEWORK_EFI_IFR_ONE_OF_OPTION_OP
:
946 IfrToFormTag (FormData
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &FormData
[Index
], NULL
);
947 FormTags
->Tags
[QuestionIndex
].Key
= ((FRAMEWORK_EFI_IFR_ONE_OF_OPTION
*) &FormData
[Index
])->Key
;
948 FormTags
->Tags
[QuestionIndex
].ResetRequired
= (BOOLEAN
) (FormTags
->Tags
[QuestionIndex
].Flags
& FRAMEWORK_EFI_IFR_FLAG_RESET_REQUIRED
);
951 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
952 GetQuestionHeader (&FormTags
->Tags
[CurrTag
], FormData
, Index
, FileFormTags
, CurrentVariable
);
953 IfrToFormTag (FormData
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &FormData
[Index
], NULL
);
956 case FRAMEWORK_EFI_IFR_NUMERIC_OP
:
957 GetNumericHeader (&FormTags
->Tags
[CurrTag
], FormData
, Index
, (UINT16
) 1, FileFormTags
, CurrentVariable
);
958 IfrToFormTag (FormData
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &FormData
[Index
], NULL
);
961 case FRAMEWORK_EFI_IFR_DATE_OP
:
963 // Date elements come in as a Year, Month, Day. We need to process them as a country-based
964 // Order. It is much easier to do it here than anywhere else.
966 // For US standards - we want Month/Day/Year, thus we advance "i" +1, +2, +0 while CurrTag is +0, +1, +2
969 &FormTags
->Tags
[CurrTag
],
971 (UINT16
) (Index
+ TagLength
),
978 // The current language selected + the Date operand
980 FormTags
->Tags
[CurrTag
+ 1].Operand
= FormData
[Index
];
982 &FormTags
->Tags
[CurrTag
+ 1],
984 (UINT16
) (Index
+ TagLength
+ FormData
[Index
+ TagLength
+ 1]),
991 // The current language selected + the Date operand
993 FormTags
->Tags
[CurrTag
+ 2].Operand
= FormData
[Index
];
994 GetNumericHeader (&FormTags
->Tags
[CurrTag
+ 2], FormData
, Index
, (UINT16
) 1, FileFormTags
, CurrentVariable
);
996 CurrTag
= (INT16
) (CurrTag
+ 2);
998 Index
= (UINT16
) (Index
+ TagLength
);
1002 TagLength
= FormData
[Index
+ 1];
1003 Index
= (UINT16
) (Index
+ TagLength
);
1007 TagLength
= FormData
[Index
+ 1];
1010 case FRAMEWORK_EFI_IFR_TIME_OP
:
1011 GetNumericHeader (&FormTags
->Tags
[CurrTag
], FormData
, Index
, (UINT16
) 0, FileFormTags
, CurrentVariable
);
1015 // Override the GetQuestionHeader information - date/time are treated very differently
1017 FormTags
->Tags
[CurrTag
].NumberOfLines
= 1;
1021 // The premise is that every date/time op-code have 3 elements, the first 2 have 0 lines
1022 // associated with them, and the third has 1 line to allow to space beyond the choice.
1028 case FRAMEWORK_EFI_IFR_PASSWORD_OP
:
1029 case FRAMEWORK_EFI_IFR_STRING_OP
:
1030 GetQuestionHeader (&FormTags
->Tags
[CurrTag
], FormData
, Index
, FileFormTags
, CurrentVariable
);
1031 IfrToFormTag (FormData
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &FormData
[Index
], NULL
);
1034 case FRAMEWORK_EFI_IFR_INCONSISTENT_IF_OP
:
1035 case FRAMEWORK_EFI_IFR_SUPPRESS_IF_OP
:
1036 case FRAMEWORK_EFI_IFR_GRAYOUT_IF_OP
:
1040 case FRAMEWORK_EFI_IFR_EQ_ID_VAL_OP
:
1041 IfrToFormTag (FormData
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &FormData
[Index
], NULL
);
1042 FormTags
->Tags
[CurrTag
].ConsistencyId
= ConsistencyId
;
1045 case FRAMEWORK_EFI_IFR_EQ_VAR_VAL_OP
:
1046 IfrToFormTag (FormData
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &FormData
[Index
], NULL
);
1047 FormTags
->Tags
[CurrTag
].ConsistencyId
= ConsistencyId
;
1050 case FRAMEWORK_EFI_IFR_EQ_ID_ID_OP
:
1051 IfrToFormTag (FormData
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &FormData
[Index
], NULL
);
1052 FormTags
->Tags
[CurrTag
].ConsistencyId
= ConsistencyId
;
1055 case FRAMEWORK_EFI_IFR_AND_OP
:
1056 case FRAMEWORK_EFI_IFR_OR_OP
:
1057 case FRAMEWORK_EFI_IFR_NOT_OP
:
1058 case FRAMEWORK_EFI_IFR_TRUE_OP
:
1059 case FRAMEWORK_EFI_IFR_FALSE_OP
:
1060 case FRAMEWORK_EFI_IFR_GT_OP
:
1061 case FRAMEWORK_EFI_IFR_GE_OP
:
1062 FormTags
->Tags
[CurrTag
].ConsistencyId
= ConsistencyId
;
1065 case FRAMEWORK_EFI_IFR_EQ_ID_LIST_OP
:
1066 IfrToFormTag (FormData
[Index
], &FormTags
->Tags
[CurrTag
], (VOID
*) &FormData
[Index
], NULL
);
1068 FormTags
->Tags
[CurrTag
].ConsistencyId
= ConsistencyId
;
1081 // Per spec., we ignore ops that we don't know how to deal with. Skip to next tag
1083 Index
= (UINT16
) (Index
+ TagLength
);
1093 ExtractDynamicFormHandle (
1094 IN UI_MENU_OPTION
*Selection
,
1095 IN UINT8
*CallbackData
,
1096 IN EFI_FILE_FORM_TAGS
*FileFormTagsHead
,
1098 OUT UINT16
*FormHandle
,
1099 OUT UINT16
*TitleToken
,
1100 OUT EFI_FORM_TAGS
*FormTags
1104 Routine Description:
1106 The function does the most of the works when the EFI_TAG that
1107 user selects on is FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE or FRAMEWORK_EFI_IFR_PASSWORD_OP:
1108 invoke CallBack, update the new form data.
1112 Selection - The current selection of the form.
1113 CallbackData - The pointer to host the data passed back by the callback function.
1114 FileFormTagsHead - Prompt string token of the one-of box
1115 IdValue - The current page number.
1116 FormHandle - Output the the handle of the form.
1117 TitleToken - Output the TitleToken of the new page.
1118 FormTags - Output the FormFags of the new page.
1127 EFI_FILE_FORM_TAGS
*FileFormTags
;
1128 EFI_FORM_TAGS
*LocalTags
;
1129 EFI_FORM_CALLBACK_PROTOCOL
*FormCallback
;
1133 EFI_PHYSICAL_ADDRESS CallbackHandle
;
1136 EFI_HII_CALLBACK_PACKET
*Packet
;
1138 CHAR16 NullCharacter
;
1140 UINT16 ConsistencyId
;
1141 UINT16 CurrentVariable
;
1142 EFI_VARIABLE_DEFINITION
*VariableDefinition
;
1143 FRAMEWORK_EFI_IFR_DATA_ENTRY
*DataEntry
;
1145 VariableDefinition
= NULL
;
1146 NullCharacter
= CHAR_NULL
;
1148 CurrentVariable
= 0;
1149 FileFormTags
= FileFormTagsHead
;
1152 TargetPage
= (UINT16
) IdValue
;
1157 // Advance FileFormTags to the correct file's tag information.
1158 // For instance, if Selection->IfrNumber is 3, that means the 4th
1159 // file (0-based) in the FileFormTags linked-list contains the tag
1162 for (Index
= 0; Index
< Selection
->IfrNumber
; Index
++) {
1163 FileFormTags
= FileFormTags
->NextFile
;
1166 LocalTags
= &FileFormTags
->FormTags
;
1169 // Advance Index to the FormOp with the correct ID value
1171 for (; LocalTags
->Next
!= NULL
; LocalTags
= LocalTags
->Next
) {
1172 if ((LocalTags
->Tags
[0].CallbackHandle
!= 0) && (CallbackHandle
== 0)) {
1173 CallbackHandle
= LocalTags
->Tags
[0].CallbackHandle
;
1174 CopyMem (&TagGuid
, &LocalTags
->Tags
[0].GuidValue
, sizeof (EFI_GUID
));
1177 for (Index
= 0; LocalTags
->Tags
[Index
].Operand
!= FRAMEWORK_EFI_IFR_FORM_OP
; Index
++)
1179 if (LocalTags
->Tags
[Index
].Id
== IdValue
) {
1184 // If we are going to callback on a non-goto opcode, make sure we don't change pages
1186 if (Selection
->ThisTag
->Operand
!= FRAMEWORK_EFI_IFR_REF_OP
) {
1187 TargetPage
= Selection
->FormId
;
1190 // The first tag below should be the form op-code. We need to store away the
1191 // current variable setting to ensure if we have to reload the page, that we
1192 // can correctly restore the values for the active variable
1194 CurrentVariable
= Selection
->Tags
[0].VariableNumber
;
1197 // Remember that dynamic pages in an environment where all pages are not
1198 // dynamic require us to call back to the user to give them an opportunity
1199 // to register fresh information in the HII database so that we can extract it.
1201 Status
= gBS
->HandleProtocol (
1202 (VOID
*) (UINTN
) CallbackHandle
,
1203 &gEfiFormCallbackProtocolGuid
,
1204 (VOID
**) &FormCallback
1207 if (EFI_ERROR (Status
)) {
1208 FreePool (LocalTags
->Tags
);
1212 ExtractRequestedNvMap (FileFormTags
, CurrentVariable
, &VariableDefinition
);
1214 if (Selection
->ThisTag
->Flags
& (FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
| FRAMEWORK_EFI_IFR_FLAG_NV_ACCESS
)) {
1215 ((FRAMEWORK_EFI_IFR_DATA_ARRAY
*) CallbackData
)->NvRamMap
= VariableDefinition
->NvRamMap
;
1217 ((FRAMEWORK_EFI_IFR_DATA_ARRAY
*) CallbackData
)->NvRamMap
= NULL
;
1220 if ((FormCallback
!= NULL
) && (FormCallback
->Callback
!= NULL
)) {
1221 Status
= FormCallback
->Callback (
1223 Selection
->ThisTag
->Key
,
1224 (FRAMEWORK_EFI_IFR_DATA_ARRAY
*) CallbackData
,
1229 if (EFI_ERROR (Status
)) {
1231 // Restore Previous Value
1234 &VariableDefinition
->NvRamMap
[Selection
->ThisTag
->StorageStart
],
1236 Selection
->ThisTag
->StorageWidth
1239 if (Packet
!= NULL
&& Packet
->String
!= NULL
) {
1241 // Upon error, we will likely receive a string to print out
1243 ScreenSize
= GetStringWidth (Packet
->String
) / 2;
1246 // Display error popup
1248 CreatePopUp (ScreenSize
, 3, &NullCharacter
, Packet
->String
, &NullCharacter
);
1251 Status
= WaitForKeyStroke (&Key
);
1252 } while (Key
.UnicodeChar
!= CHAR_CARRIAGE_RETURN
);
1254 UpdateStatusBar (INPUT_ERROR
, (UINT8
) 0, TRUE
);
1258 if (Packet
!= NULL
) {
1260 // We need to on a non-error, look in the outbound Packet for information and update the NVRAM
1261 // location associated with the op-code specified there. This is used on single op-code instances
1262 // and not for when a hyperlink sent us a whole page of data.
1264 DataEntry
= (FRAMEWORK_EFI_IFR_DATA_ENTRY
*) (&Packet
->DataArray
+ 1);
1265 if (Packet
->DataArray
.EntryCount
== 1) {
1266 switch (DataEntry
->OpCode
) {
1267 case FRAMEWORK_EFI_IFR_STRING_OP
:
1268 case FRAMEWORK_EFI_IFR_NUMERIC_OP
:
1269 case FRAMEWORK_EFI_IFR_ORDERED_LIST_OP
:
1270 case FRAMEWORK_EFI_IFR_ONE_OF_OP
:
1271 case FRAMEWORK_EFI_IFR_CHECKBOX_OP
:
1273 &VariableDefinition
->NvRamMap
[Selection
->ThisTag
->StorageStart
],
1275 Selection
->ThisTag
->StorageWidth
1279 case FRAMEWORK_EFI_IFR_NV_ACCESS_COMMAND
:
1281 &VariableDefinition
->NvRamMap
[((FRAMEWORK_EFI_IFR_NV_DATA
*) Packet
)->QuestionId
],
1282 ((FRAMEWORK_EFI_IFR_NV_DATA
*) Packet
) + 1,
1283 ((FRAMEWORK_EFI_IFR_NV_DATA
*) Packet
)->StorageWidth
1289 if (DataEntry
->Flags
& RESET_REQUIRED
) {
1290 gResetRequired
= TRUE
;
1293 if (DataEntry
->Flags
& EXIT_REQUIRED
) {
1294 gExitRequired
= TRUE
;
1297 if (DataEntry
->Flags
& SAVE_REQUIRED
) {
1298 gSaveRequired
= TRUE
;
1301 if (DataEntry
->Flags
& NV_CHANGED
) {
1302 gNvUpdateRequired
= TRUE
;
1305 if (DataEntry
->Flags
& NV_NOT_CHANGED
) {
1306 gNvUpdateRequired
= FALSE
;
1312 if (Packet
!= NULL
) {
1316 for (BackupIndex
= 0; LocalTags
->Tags
[BackupIndex
].Operand
!= FRAMEWORK_EFI_IFR_END_FORM_OP
; BackupIndex
++) {
1317 switch (LocalTags
->Tags
[BackupIndex
].Operand
) {
1318 case FRAMEWORK_EFI_IFR_EQ_VAR_VAL_OP
:
1319 case FRAMEWORK_EFI_IFR_EQ_ID_VAL_OP
:
1320 case FRAMEWORK_EFI_IFR_EQ_ID_ID_OP
:
1321 case FRAMEWORK_EFI_IFR_AND_OP
:
1322 case FRAMEWORK_EFI_IFR_OR_OP
:
1323 case FRAMEWORK_EFI_IFR_NOT_OP
:
1324 case FRAMEWORK_EFI_IFR_TRUE_OP
:
1325 case FRAMEWORK_EFI_IFR_FALSE_OP
:
1326 case FRAMEWORK_EFI_IFR_GT_OP
:
1327 case FRAMEWORK_EFI_IFR_GE_OP
:
1328 case FRAMEWORK_EFI_IFR_EQ_ID_LIST_OP
:
1330 // If we encountered a ConsistencyId value, on this page they will be incremental
1331 // So register the first value we encounter. We will pass this in when we re-create this page
1333 if ((LocalTags
->Tags
[BackupIndex
].ConsistencyId
!= 0) && (ConsistencyId
== 0)) {
1334 ConsistencyId
= (UINT16
) (LocalTags
->Tags
[BackupIndex
].ConsistencyId
- 1);
1340 // Delete the buffer associated with previous dynamic page
1341 // We will re-allocate a buffer....
1343 FreePool (LocalTags
->Tags
);
1346 Buffer
= AllocateZeroPool (Length
);
1347 ASSERT (Buffer
!= NULL
);
1350 // Get the form that was updated by the callback
1361 // Ok, we have the new page.....now we must purge the old page and re-allocate
1362 // the tag page with the new data
1373 // return the Form Id, Text, and the File's FormTags structure
1375 *FormHandle
= LocalTags
->Tags
[0].Id
;
1376 *TitleToken
= LocalTags
->Tags
[0].Text
;
1377 *FormTags
= *LocalTags
;
1379 FormTags
->Tags
[0].CallbackHandle
= CallbackHandle
;
1380 CopyMem (&FormTags
->Tags
[0].GuidValue
, &TagGuid
, sizeof (EFI_GUID
));
1387 IN UI_MENU_OPTION
*Selection
,
1388 IN BOOLEAN Callback
,
1389 IN EFI_FILE_FORM_TAGS
*FileFormTagsHead
,
1390 IN UINT8
*CallbackData
1395 EFI_FORM_TAGS FormTags
;
1400 // Displays the Header and Footer borders
1402 DisplayPageFrame ();
1405 // Id of 0 yields the getting of the top form whatever the ID is. Usually the first form in the IFR
1407 ExtractFormHandle (Selection
, FileFormTagsHead
, 0, &FormHandle
, &TitleToken
, &FormTags
);
1409 Selection
= DisplayForm (Selection
, FormHandle
, TitleToken
, FormTags
, FileFormTagsHead
, CallbackData
);
1412 // If selection is null use the former selection
1414 if (Selection
== NULL
) {
1422 while (Selection
->Tags
!= NULL
) {
1423 if (Selection
->Previous
) {
1424 ExtractFormHandle (Selection
, FileFormTagsHead
, Selection
->FormId
, &FormHandle
, &TitleToken
, &FormTags
);
1427 // True if a hyperlink/jump is selected
1429 if (Selection
->ThisTag
->Operand
== FRAMEWORK_EFI_IFR_REF_OP
&& Selection
->ThisTag
->Id
!= 0x0000) {
1430 if (Selection
->ThisTag
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) {
1431 ExtractDynamicFormHandle (
1435 Selection
->ThisTag
->Id
,
1442 ExtractFormHandle (Selection
, FileFormTagsHead
, Selection
->ThisTag
->Id
, &FormHandle
, &TitleToken
, &FormTags
);
1447 if ((Selection
->ThisTag
->Flags
& FRAMEWORK_EFI_IFR_FLAG_INTERACTIVE
) &&
1448 (Selection
->ThisTag
->Operand
!= FRAMEWORK_EFI_IFR_PASSWORD_OP
)
1450 ExtractDynamicFormHandle (
1460 ExtractFormHandle (Selection
, FileFormTagsHead
, Selection
->FormId
, &FormHandle
, &TitleToken
, &FormTags
);
1466 // Displays the Header and Footer borders
1468 DisplayPageFrame ();
1470 Selection
= DisplayForm (Selection
, FormHandle
, TitleToken
, FormTags
, FileFormTagsHead
, CallbackData
);
1472 if (Selection
== NULL
) {