2 Utility functions for UI presentation.
4 Copyright (c) 2004 - 2008, 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.
18 BOOLEAN mHiiPackageListUpdated
;
19 UI_MENU_SELECTION
*gCurrentSelection
;
23 Clear retangle with specified text attribute.
25 @param LeftColumn Left column of retangle.
26 @param RightColumn Right column of retangle.
27 @param TopRow Start row of retangle.
28 @param BottomRow End row of retangle.
29 @param TextAttribute The character foreground and background.
45 // For now, allocate an arbitrarily long buffer
47 Buffer
= AllocateZeroPool (0x10000);
48 ASSERT (Buffer
!= NULL
);
51 // Set foreground and background as defined
53 gST
->ConOut
->SetAttribute (gST
->ConOut
, TextAttribute
);
56 // Much faster to buffer the long string instead of print it a character at a time
58 SetUnicodeMem (Buffer
, RightColumn
- LeftColumn
, L
' ');
61 // Clear the desired area with the appropriate foreground/background
63 for (Row
= TopRow
; Row
<= BottomRow
; Row
++) {
64 PrintStringAt (LeftColumn
, Row
, Buffer
);
67 gST
->ConOut
->SetCursorPosition (gST
->ConOut
, LeftColumn
, TopRow
);
74 Concatenate a narrow string to another string.
76 @param Destination The destination string.
77 @param Source The source string. The string to be concatenated.
78 to the end of Destination.
89 for (Length
= 0; Destination
[Length
] != 0; Length
++)
93 // We now have the length of the original string
94 // We can safely assume for now that we are concatenating a narrow value to this string.
95 // For instance, the string is "XYZ" and cat'ing ">"
96 // If this assumption changes, we need to make this routine a bit more complex
98 Destination
[Length
] = NARROW_CHAR
;
101 StrCpy (Destination
+ Length
, Source
);
105 Count the storage space of a Unicode string.
107 This function handles the Unicode string with NARROW_CHAR
108 and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
109 does not count in the resultant output. If a WIDE_CHAR is
110 hit, then 2 Unicode character will consume an output storage
111 space with size of CHAR16 till a NARROW_CHAR is hit.
113 @param String The input string to be counted.
115 @return Storage space for the input string.
125 UINTN IncrementValue
;
133 // Advance to the null-terminator or to the first width directive
136 (String
[Index
] != NARROW_CHAR
) && (String
[Index
] != WIDE_CHAR
) && (String
[Index
] != 0);
137 Index
++, Count
= Count
+ IncrementValue
142 // We hit the null-terminator, we now have a count
144 if (String
[Index
] == 0) {
148 // We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
149 // and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
151 if (String
[Index
] == NARROW_CHAR
) {
153 // Skip to the next character
159 // Skip to the next character
164 } while (String
[Index
] != 0);
167 // Increment by one to include the null-terminator in the size
171 return Count
* sizeof (CHAR16
);
175 This function displays the page frame.
188 CHAR16
*StrFrontPageBanner
;
190 EFI_SCREEN_DESCRIPTOR LocalScreen
;
192 ZeroMem (&LocalScreen
, sizeof (EFI_SCREEN_DESCRIPTOR
));
193 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &LocalScreen
.RightColumn
, &LocalScreen
.BottomRow
);
194 ClearLines (0, LocalScreen
.RightColumn
, 0, LocalScreen
.BottomRow
, KEYHELP_BACKGROUND
);
196 CopyMem (&LocalScreen
, &gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
199 // For now, allocate an arbitrarily long buffer
201 Buffer
= AllocateZeroPool (0x10000);
202 ASSERT (Buffer
!= NULL
);
204 Character
= BOXDRAW_HORIZONTAL
;
206 for (Index
= 0; Index
+ 2 < (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
); Index
++) {
207 Buffer
[Index
] = Character
;
210 if (gClassOfVfr
== EFI_FRONT_PAGE_SUBCLASS
) {
212 // ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);
215 LocalScreen
.LeftColumn
,
216 LocalScreen
.RightColumn
,
218 FRONT_PAGE_HEADER_HEIGHT
- 1 + LocalScreen
.TopRow
,
219 BANNER_TEXT
| BANNER_BACKGROUND
222 // for (Line = 0; Line < BANNER_HEIGHT; Line++) {
224 for (Line
= (UINT8
) LocalScreen
.TopRow
; Line
< BANNER_HEIGHT
+ (UINT8
) LocalScreen
.TopRow
; Line
++) {
226 // for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {
228 for (Alignment
= (UINT8
) LocalScreen
.LeftColumn
;
229 Alignment
< BANNER_COLUMNS
+ (UINT8
) LocalScreen
.LeftColumn
;
232 if (BannerData
->Banner
[Line
- (UINT8
) LocalScreen
.TopRow
][Alignment
- (UINT8
) LocalScreen
.LeftColumn
] != 0x0000) {
233 StrFrontPageBanner
= GetToken (
234 BannerData
->Banner
[Line
- (UINT8
) LocalScreen
.TopRow
][Alignment
- (UINT8
) LocalScreen
.LeftColumn
],
241 switch (Alignment
- LocalScreen
.LeftColumn
) {
244 // Handle left column
246 PrintStringAt (LocalScreen
.LeftColumn
, Line
, StrFrontPageBanner
);
251 // Handle center column
254 LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) / 3,
262 // Handle right column
265 LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) * 2 / 3,
272 FreePool (StrFrontPageBanner
);
278 LocalScreen
.LeftColumn
,
279 LocalScreen
.RightColumn
,
280 LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- FOOTER_HEIGHT
,
281 LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- 1,
282 KEYHELP_TEXT
| KEYHELP_BACKGROUND
285 if (gClassOfVfr
!= EFI_FRONT_PAGE_SUBCLASS
) {
287 LocalScreen
.LeftColumn
,
288 LocalScreen
.RightColumn
,
290 LocalScreen
.TopRow
+ NONE_FRONT_PAGE_HEADER_HEIGHT
- 1,
291 TITLE_TEXT
| TITLE_BACKGROUND
294 // Print Top border line
295 // +------------------------------------------------------------------------------+
297 // +------------------------------------------------------------------------------+
299 Character
= BOXDRAW_DOWN_RIGHT
;
301 PrintChar (Character
);
302 PrintString (Buffer
);
304 Character
= BOXDRAW_DOWN_LEFT
;
305 PrintChar (Character
);
307 Character
= BOXDRAW_VERTICAL
;
308 for (Row
= LocalScreen
.TopRow
+ 1; Row
<= LocalScreen
.TopRow
+ NONE_FRONT_PAGE_HEADER_HEIGHT
- 2; Row
++) {
309 PrintCharAt (LocalScreen
.LeftColumn
, Row
, Character
);
310 PrintCharAt (LocalScreen
.RightColumn
- 1, Row
, Character
);
313 Character
= BOXDRAW_UP_RIGHT
;
314 PrintCharAt (LocalScreen
.LeftColumn
, LocalScreen
.TopRow
+ NONE_FRONT_PAGE_HEADER_HEIGHT
- 1, Character
);
315 PrintString (Buffer
);
317 Character
= BOXDRAW_UP_LEFT
;
318 PrintChar (Character
);
320 if (gClassOfVfr
== EFI_SETUP_APPLICATION_SUBCLASS
) {
322 // Print Bottom border line
323 // +------------------------------------------------------------------------------+
325 // +------------------------------------------------------------------------------+
327 Character
= BOXDRAW_DOWN_RIGHT
;
328 PrintCharAt (LocalScreen
.LeftColumn
, LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- FOOTER_HEIGHT
, Character
);
330 PrintString (Buffer
);
332 Character
= BOXDRAW_DOWN_LEFT
;
333 PrintChar (Character
);
334 Character
= BOXDRAW_VERTICAL
;
335 for (Row
= LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- FOOTER_HEIGHT
+ 1;
336 Row
<= LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- 2;
339 PrintCharAt (LocalScreen
.LeftColumn
, Row
, Character
);
340 PrintCharAt (LocalScreen
.RightColumn
- 1, Row
, Character
);
343 Character
= BOXDRAW_UP_RIGHT
;
344 PrintCharAt (LocalScreen
.LeftColumn
, LocalScreen
.BottomRow
- STATUS_BAR_HEIGHT
- 1, Character
);
346 PrintString (Buffer
);
348 Character
= BOXDRAW_UP_LEFT
;
349 PrintChar (Character
);
359 Evaluate all expressions in a Form.
361 @param FormSet FormSet this Form belongs to.
362 @param Form The Form.
364 @retval EFI_SUCCESS The expression evaluated successfuly
368 EvaluateFormExpressions (
369 IN FORM_BROWSER_FORMSET
*FormSet
,
370 IN FORM_BROWSER_FORM
*Form
375 FORM_EXPRESSION
*Expression
;
377 Link
= GetFirstNode (&Form
->ExpressionListHead
);
378 while (!IsNull (&Form
->ExpressionListHead
, Link
)) {
379 Expression
= FORM_EXPRESSION_FROM_LINK (Link
);
380 Link
= GetNextNode (&Form
->ExpressionListHead
, Link
);
382 if (Expression
->Type
== EFI_HII_EXPRESSION_INCONSISTENT_IF
||
383 Expression
->Type
== EFI_HII_EXPRESSION_NO_SUBMIT_IF
) {
385 // Postpone Form validation to Question editing or Form submiting
390 Status
= EvaluateExpression (FormSet
, Form
, Expression
);
391 if (EFI_ERROR (Status
)) {
400 +------------------------------------------------------------------------------+
401 ?F2=Previous Page Setup Page ?
402 +------------------------------------------------------------------------------+
420 +------------------------------------------------------------------------------+
421 ?F1=Scroll Help F9=Reset to Defaults F10=Save and Exit ?
422 | ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Discard Changes |
423 +------------------------------------------------------------------------------+
429 Display form and wait for user to select one menu option, then return it.
431 @param Selection On input, Selection tell setup browser the information
432 about the Selection, form and formset to be displayed.
433 On output, Selection return the screen item that is selected
435 @retval EFI_SUCESSS This function always return successfully for now.
440 IN OUT UI_MENU_SELECTION
*Selection
444 UINT16 MenuItemCount
;
445 EFI_HII_HANDLE Handle
;
447 EFI_SCREEN_DESCRIPTOR LocalScreen
;
450 CHAR16
*OutputString
;
452 FORM_BROWSER_STATEMENT
*Statement
;
453 UINT16 NumberOfLines
;
456 Handle
= Selection
->Handle
;
463 CopyMem (&LocalScreen
, &gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
465 StringPtr
= GetToken (Selection
->Form
->FormTitle
, Handle
);
467 if (gClassOfVfr
!= EFI_FRONT_PAGE_SUBCLASS
) {
468 gST
->ConOut
->SetAttribute (gST
->ConOut
, TITLE_TEXT
| TITLE_BACKGROUND
);
470 (LocalScreen
.RightColumn
+ LocalScreen
.LeftColumn
- GetStringWidth (StringPtr
) / 2) / 2,
471 LocalScreen
.TopRow
+ 1,
476 if (gClassOfVfr
== EFI_SETUP_APPLICATION_SUBCLASS
) {
477 gST
->ConOut
->SetAttribute (gST
->ConOut
, KEYHELP_TEXT
| KEYHELP_BACKGROUND
);
480 // Display the infrastructure strings
482 if (!IsListEmpty (&gMenuList
)) {
483 PrintStringAt (LocalScreen
.LeftColumn
+ 2, LocalScreen
.TopRow
+ 1, gFunctionTwoString
);
487 // Remove Buffer allocated for StringPtr after it has been used.
489 FreePool (StringPtr
);
492 // Evaluate all the Expressions in this Form
494 Status
= EvaluateFormExpressions (Selection
->FormSet
, Selection
->Form
);
495 if (EFI_ERROR (Status
)) {
499 Link
= GetFirstNode (&Selection
->Form
->StatementListHead
);
500 while (!IsNull (&Selection
->Form
->StatementListHead
, Link
)) {
501 Statement
= FORM_BROWSER_STATEMENT_FROM_LINK (Link
);
503 if (Statement
->SuppressExpression
!= NULL
) {
504 Suppress
= Statement
->SuppressExpression
->Result
.Value
.b
;
510 StringPtr
= GetToken (Statement
->Prompt
, Handle
);
512 Width
= GetWidth (Statement
, Handle
);
516 for (; GetLineByWidth (StringPtr
, Width
, &ArrayEntry
, &OutputString
) != 0x0000;) {
518 // If there is more string to process print on the next row and increment the Skip value
520 if (StrLen (&StringPtr
[ArrayEntry
])) {
524 FreePool (OutputString
);
528 // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
531 UiAddMenuOption (StringPtr
, Selection
->Handle
, Statement
, NumberOfLines
, MenuItemCount
);
535 Link
= GetNextNode (&Selection
->Form
->StatementListHead
, Link
);
538 Status
= UiDisplayMenu (Selection
);
546 Initialize the HII String Token to the correct values.
550 InitializeBrowserStrings (
554 gFunctionOneString
= GetToken (STRING_TOKEN (FUNCTION_ONE_STRING
), gHiiHandle
);
555 gFunctionTwoString
= GetToken (STRING_TOKEN (FUNCTION_TWO_STRING
), gHiiHandle
);
556 gFunctionNineString
= GetToken (STRING_TOKEN (FUNCTION_NINE_STRING
), gHiiHandle
);
557 gFunctionTenString
= GetToken (STRING_TOKEN (FUNCTION_TEN_STRING
), gHiiHandle
);
558 gEnterString
= GetToken (STRING_TOKEN (ENTER_STRING
), gHiiHandle
);
559 gEnterCommitString
= GetToken (STRING_TOKEN (ENTER_COMMIT_STRING
), gHiiHandle
);
560 gEnterEscapeString
= GetToken (STRING_TOKEN (ENTER_ESCAPE_STRING
), gHiiHandle
);
561 gEscapeString
= GetToken (STRING_TOKEN (ESCAPE_STRING
), gHiiHandle
);
562 gSaveFailed
= GetToken (STRING_TOKEN (SAVE_FAILED
), gHiiHandle
);
563 gMoveHighlight
= GetToken (STRING_TOKEN (MOVE_HIGHLIGHT
), gHiiHandle
);
564 gMakeSelection
= GetToken (STRING_TOKEN (MAKE_SELECTION
), gHiiHandle
);
565 gDecNumericInput
= GetToken (STRING_TOKEN (DEC_NUMERIC_INPUT
), gHiiHandle
);
566 gHexNumericInput
= GetToken (STRING_TOKEN (HEX_NUMERIC_INPUT
), gHiiHandle
);
567 gToggleCheckBox
= GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX
), gHiiHandle
);
568 gPromptForData
= GetToken (STRING_TOKEN (PROMPT_FOR_DATA
), gHiiHandle
);
569 gPromptForPassword
= GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD
), gHiiHandle
);
570 gPromptForNewPassword
= GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD
), gHiiHandle
);
571 gConfirmPassword
= GetToken (STRING_TOKEN (CONFIRM_PASSWORD
), gHiiHandle
);
572 gConfirmError
= GetToken (STRING_TOKEN (CONFIRM_ERROR
), gHiiHandle
);
573 gPassowordInvalid
= GetToken (STRING_TOKEN (PASSWORD_INVALID
), gHiiHandle
);
574 gPressEnter
= GetToken (STRING_TOKEN (PRESS_ENTER
), gHiiHandle
);
575 gEmptyString
= GetToken (STRING_TOKEN (EMPTY_STRING
), gHiiHandle
);
576 gAreYouSure
= GetToken (STRING_TOKEN (ARE_YOU_SURE
), gHiiHandle
);
577 gYesResponse
= GetToken (STRING_TOKEN (ARE_YOU_SURE_YES
), gHiiHandle
);
578 gNoResponse
= GetToken (STRING_TOKEN (ARE_YOU_SURE_NO
), gHiiHandle
);
579 gMiniString
= GetToken (STRING_TOKEN (MINI_STRING
), gHiiHandle
);
580 gPlusString
= GetToken (STRING_TOKEN (PLUS_STRING
), gHiiHandle
);
581 gMinusString
= GetToken (STRING_TOKEN (MINUS_STRING
), gHiiHandle
);
582 gAdjustNumber
= GetToken (STRING_TOKEN (ADJUST_NUMBER
), gHiiHandle
);
583 gSaveChanges
= GetToken (STRING_TOKEN (SAVE_CHANGES
), gHiiHandle
);
584 gOptionMismatch
= GetToken (STRING_TOKEN (OPTION_MISMATCH
), gHiiHandle
);
589 Free up the resource allocated for all strings required
598 FreePool (gFunctionOneString
);
599 FreePool (gFunctionTwoString
);
600 FreePool (gFunctionNineString
);
601 FreePool (gFunctionTenString
);
602 FreePool (gEnterString
);
603 FreePool (gEnterCommitString
);
604 FreePool (gEnterEscapeString
);
605 FreePool (gEscapeString
);
606 FreePool (gMoveHighlight
);
607 FreePool (gMakeSelection
);
608 FreePool (gDecNumericInput
);
609 FreePool (gHexNumericInput
);
610 FreePool (gToggleCheckBox
);
611 FreePool (gPromptForData
);
612 FreePool (gPromptForPassword
);
613 FreePool (gPromptForNewPassword
);
614 FreePool (gConfirmPassword
);
615 FreePool (gPassowordInvalid
);
616 FreePool (gConfirmError
);
617 FreePool (gPressEnter
);
618 FreePool (gEmptyString
);
619 FreePool (gAreYouSure
);
620 FreePool (gYesResponse
);
621 FreePool (gNoResponse
);
622 FreePool (gMiniString
);
623 FreePool (gPlusString
);
624 FreePool (gMinusString
);
625 FreePool (gAdjustNumber
);
626 FreePool (gSaveChanges
);
627 FreePool (gOptionMismatch
);
633 Update key's help imformation.
635 @param MenuOption The Menu option
636 @param Selected Whether or not a tag be selected
641 IN UI_MENU_OPTION
*MenuOption
,
647 UINTN LeftColumnOfHelp
;
648 UINTN RightColumnOfHelp
;
650 UINTN BottomRowOfHelp
;
651 UINTN StartColumnOfHelp
;
652 EFI_SCREEN_DESCRIPTOR LocalScreen
;
653 FORM_BROWSER_STATEMENT
*Statement
;
655 CopyMem (&LocalScreen
, &gScreenDimensions
, sizeof (EFI_SCREEN_DESCRIPTOR
));
657 SecCol
= LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) / 3;
658 ThdCol
= LocalScreen
.LeftColumn
+ (LocalScreen
.RightColumn
- LocalScreen
.LeftColumn
) * 2 / 3;
660 StartColumnOfHelp
= LocalScreen
.LeftColumn
+ 2;
661 LeftColumnOfHelp
= LocalScreen
.LeftColumn
+ 1;
662 RightColumnOfHelp
= LocalScreen
.RightColumn
- 2;
663 TopRowOfHelp
= LocalScreen
.BottomRow
- 4;
664 BottomRowOfHelp
= LocalScreen
.BottomRow
- 3;
666 if (gClassOfVfr
== EFI_GENERAL_APPLICATION_SUBCLASS
) {
670 gST
->ConOut
->SetAttribute (gST
->ConOut
, KEYHELP_TEXT
| KEYHELP_BACKGROUND
);
672 Statement
= MenuOption
->ThisTag
;
673 switch (Statement
->Operand
) {
674 case EFI_IFR_ORDERED_LIST_OP
:
675 case EFI_IFR_ONE_OF_OP
:
676 case EFI_IFR_NUMERIC_OP
:
677 case EFI_IFR_TIME_OP
:
678 case EFI_IFR_DATE_OP
:
679 ClearLines (LeftColumnOfHelp
, RightColumnOfHelp
, TopRowOfHelp
, BottomRowOfHelp
, KEYHELP_TEXT
| KEYHELP_BACKGROUND
);
682 if (gClassOfVfr
== EFI_SETUP_APPLICATION_SUBCLASS
) {
683 PrintStringAt (StartColumnOfHelp
, TopRowOfHelp
, gFunctionOneString
);
684 PrintStringAt (SecCol
, TopRowOfHelp
, gFunctionNineString
);
685 PrintStringAt (ThdCol
, TopRowOfHelp
, gFunctionTenString
);
686 PrintStringAt (ThdCol
, BottomRowOfHelp
, gEscapeString
);
689 if ((Statement
->Operand
== EFI_IFR_DATE_OP
) ||
690 (Statement
->Operand
== EFI_IFR_TIME_OP
)) {
701 PrintStringAt (SecCol
, BottomRowOfHelp
, gAdjustNumber
);
703 PrintAt (StartColumnOfHelp
, BottomRowOfHelp
, L
"%c%c%s", ARROW_UP
, ARROW_DOWN
, gMoveHighlight
);
704 if (Statement
->Operand
== EFI_IFR_NUMERIC_OP
&& Statement
->Step
!= 0) {
705 PrintStringAt (SecCol
, BottomRowOfHelp
, gAdjustNumber
);
707 PrintStringAt (SecCol
, BottomRowOfHelp
, gEnterString
);
711 PrintStringAt (SecCol
, BottomRowOfHelp
, gEnterCommitString
);
714 // If it is a selected numeric with manual input, display different message
716 if ((Statement
->Operand
== EFI_IFR_NUMERIC_OP
) && (Statement
->Step
== 0)) {
720 ((Statement
->Flags
& EFI_IFR_DISPLAY_UINT_HEX
) == EFI_IFR_DISPLAY_UINT_HEX
) ? gHexNumericInput
: gDecNumericInput
722 } else if (Statement
->Operand
!= EFI_IFR_ORDERED_LIST_OP
) {
723 PrintAt (StartColumnOfHelp
, BottomRowOfHelp
, L
"%c%c%s", ARROW_UP
, ARROW_DOWN
, gMoveHighlight
);
726 if (Statement
->Operand
== EFI_IFR_ORDERED_LIST_OP
) {
727 PrintStringAt (StartColumnOfHelp
, TopRowOfHelp
, gPlusString
);
728 PrintStringAt (ThdCol
, TopRowOfHelp
, gMinusString
);
731 PrintStringAt (ThdCol
, BottomRowOfHelp
, gEnterEscapeString
);
735 case EFI_IFR_CHECKBOX_OP
:
736 ClearLines (LeftColumnOfHelp
, RightColumnOfHelp
, TopRowOfHelp
, BottomRowOfHelp
, KEYHELP_TEXT
| KEYHELP_BACKGROUND
);
738 if (gClassOfVfr
== EFI_SETUP_APPLICATION_SUBCLASS
) {
739 PrintStringAt (StartColumnOfHelp
, TopRowOfHelp
, gFunctionOneString
);
740 PrintStringAt (SecCol
, TopRowOfHelp
, gFunctionNineString
);
741 PrintStringAt (ThdCol
, TopRowOfHelp
, gFunctionTenString
);
742 PrintStringAt (ThdCol
, BottomRowOfHelp
, gEscapeString
);
745 PrintAt (StartColumnOfHelp
, BottomRowOfHelp
, L
"%c%c%s", ARROW_UP
, ARROW_DOWN
, gMoveHighlight
);
746 PrintStringAt (SecCol
, BottomRowOfHelp
, gToggleCheckBox
);
750 case EFI_IFR_PASSWORD_OP
:
751 case EFI_IFR_STRING_OP
:
752 case EFI_IFR_TEXT_OP
:
753 case EFI_IFR_ACTION_OP
:
754 case EFI_IFR_RESET_BUTTON_OP
:
755 ClearLines (LeftColumnOfHelp
, RightColumnOfHelp
, TopRowOfHelp
, BottomRowOfHelp
, KEYHELP_TEXT
| KEYHELP_BACKGROUND
);
758 if (gClassOfVfr
== EFI_SETUP_APPLICATION_SUBCLASS
) {
759 PrintStringAt (StartColumnOfHelp
, TopRowOfHelp
, gFunctionOneString
);
760 PrintStringAt (SecCol
, TopRowOfHelp
, gFunctionNineString
);
761 PrintStringAt (ThdCol
, TopRowOfHelp
, gFunctionTenString
);
762 PrintStringAt (ThdCol
, BottomRowOfHelp
, gEscapeString
);
765 PrintAt (StartColumnOfHelp
, BottomRowOfHelp
, L
"%c%c%s", ARROW_UP
, ARROW_DOWN
, gMoveHighlight
);
766 if (Statement
->Operand
!= EFI_IFR_TEXT_OP
) {
767 PrintStringAt (SecCol
, BottomRowOfHelp
, gEnterString
);
770 if (Statement
->Operand
!= EFI_IFR_REF_OP
) {
772 (LocalScreen
.RightColumn
- GetStringWidth (gEnterCommitString
) / 2) / 2,
776 PrintStringAt (ThdCol
, BottomRowOfHelp
, gEnterEscapeString
);
787 Functions which are registered to receive notification of
788 database events have this prototype. The actual event is encoded
789 in NotifyType. The following table describes how PackageType,
790 PackageGuid, Handle, and Package are used for each of the
793 @param PackageType Package type of the notification.
795 @param PackageGuid If PackageType is
796 EFI_HII_PACKAGE_TYPE_GUID, then this is
797 the pointer to the GUID from the Guid
798 field of EFI_HII_PACKAGE_GUID_HEADER.
799 Otherwise, it must be NULL.
801 @param Package Points to the package referred to by the
802 notification Handle The handle of the package
803 list which contains the specified package.
805 @param Handle The HII handle.
807 @param NotifyType The type of change concerning the
809 EFI_HII_DATABASE_NOTIFY_TYPE.
814 IN UINT8 PackageType
,
815 IN CONST EFI_GUID
*PackageGuid
,
816 IN CONST EFI_HII_PACKAGE_HEADER
*Package
,
817 IN EFI_HII_HANDLE Handle
,
818 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
821 mHiiPackageListUpdated
= TRUE
;
827 The worker function that send the displays to the screen. On output,
828 the selection made by user is returned.
830 @param Selection On input, Selection tell setup browser the information
831 about the Selection, form and formset to be displayed.
832 On output, Selection return the screen item that is selected
835 @retval EFI_SUCCESS The page is displayed successfully.
836 @return Other value if the page failed to be diplayed.
841 IN OUT UI_MENU_SELECTION
*Selection
846 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
847 EFI_HANDLE NotifyHandle
;
848 EFI_HII_VALUE
*HiiValue
;
849 FORM_BROWSER_STATEMENT
*Statement
;
850 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
855 gMenuRefreshHead
= NULL
;
856 gResetRequired
= FALSE
;
857 gNvUpdateRequired
= FALSE
;
862 // Register notify for Form package update
864 Status
= mHiiDatabase
->RegisterPackageNotify (
866 EFI_HII_PACKAGE_FORMS
,
869 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK
,
872 if (EFI_ERROR (Status
)) {
878 // Displays the Header and Footer borders
883 // Initialize Selection->Form
885 if (Selection
->FormId
== 0) {
887 // Zero FormId indicates display the first Form in a FormSet
889 Link
= GetFirstNode (&Selection
->FormSet
->FormListHead
);
891 Selection
->Form
= FORM_BROWSER_FORM_FROM_LINK (Link
);
892 Selection
->FormId
= Selection
->Form
->FormId
;
894 Selection
->Form
= IdToForm (Selection
->FormSet
, Selection
->FormId
);
898 // Load Questions' Value for display
900 Status
= LoadFormConfig (Selection
->FormSet
, Selection
->Form
);
901 if (EFI_ERROR (Status
)) {
908 Status
= DisplayForm (Selection
);
909 if (EFI_ERROR (Status
)) {
914 // Check Selected Statement (if press ESC, Selection->Statement will be NULL)
916 Statement
= Selection
->Statement
;
917 if (Statement
!= NULL
) {
918 if ((Statement
->QuestionFlags
& EFI_IFR_FLAG_RESET_REQUIRED
) == EFI_IFR_FLAG_RESET_REQUIRED
) {
919 gResetRequired
= TRUE
;
923 // Reset FormPackage update flag
925 mHiiPackageListUpdated
= FALSE
;
927 if (((Statement
->QuestionFlags
& EFI_IFR_FLAG_CALLBACK
) == EFI_IFR_FLAG_CALLBACK
) && (Statement
->Operand
!= EFI_IFR_PASSWORD_OP
)) {
928 ActionRequest
= EFI_BROWSER_ACTION_REQUEST_NONE
;
930 HiiValue
= &Statement
->HiiValue
;
931 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
933 // Create String in HII database for Configuration Driver to retrieve
935 HiiValue
->Value
.string
= NewString ((CHAR16
*) Statement
->BufferValue
, Selection
->FormSet
->HiiHandle
);
938 ConfigAccess
= Selection
->FormSet
->ConfigAccess
;
939 if (ConfigAccess
== NULL
) {
940 return EFI_UNSUPPORTED
;
942 Status
= ConfigAccess
->Callback (
944 EFI_BROWSER_ACTION_CHANGING
,
945 Statement
->QuestionId
,
951 if (HiiValue
->Type
== EFI_IFR_TYPE_STRING
) {
953 // Clean the String in HII Database
955 DeleteString (HiiValue
->Value
.string
, Selection
->FormSet
->HiiHandle
);
958 if (!EFI_ERROR (Status
)) {
959 switch (ActionRequest
) {
960 case EFI_BROWSER_ACTION_REQUEST_RESET
:
961 gResetRequired
= TRUE
;
964 case EFI_BROWSER_ACTION_REQUEST_SUBMIT
:
965 SubmitForm (Selection
->FormSet
, Selection
->Form
);
968 case EFI_BROWSER_ACTION_REQUEST_EXIT
:
969 Selection
->Action
= UI_ACTION_EXIT
;
970 gNvUpdateRequired
= FALSE
;
980 // Check whether Form Package has been updated during Callback
982 if (mHiiPackageListUpdated
&& (Selection
->Action
== UI_ACTION_REFRESH_FORM
)) {
984 // Force to reparse IFR binary of target Formset
986 Selection
->Action
= UI_ACTION_REFRESH_FORMSET
;
989 // Uncommitted data will be lost after IFR binary re-pasing, so confirm on whether to save
991 if (gNvUpdateRequired
) {
992 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
994 YesResponse
= gYesResponse
[0];
995 NoResponse
= gNoResponse
[0];
998 CreateDialog (3, TRUE
, 0, NULL
, &Key
, gEmptyString
, gSaveChanges
, gEmptyString
);
1001 (Key
.ScanCode
!= SCAN_ESC
) &&
1002 ((Key
.UnicodeChar
| UPPER_LOWER_CASE_OFFSET
) != (NoResponse
| UPPER_LOWER_CASE_OFFSET
)) &&
1003 ((Key
.UnicodeChar
| UPPER_LOWER_CASE_OFFSET
) != (YesResponse
| UPPER_LOWER_CASE_OFFSET
))
1006 if ((Key
.UnicodeChar
| UPPER_LOWER_CASE_OFFSET
) == (YesResponse
| UPPER_LOWER_CASE_OFFSET
)) {
1008 // If the user hits the YesResponse key
1010 SubmitForm (Selection
->FormSet
, Selection
->Form
);
1015 } while (Selection
->Action
== UI_ACTION_REFRESH_FORM
);
1018 // Unregister notify for Form package update
1020 Status
= mHiiDatabase
->UnregisterPackageNotify (