2 Implementation for Hii Popup Protocol.
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "FormDisplay.h"
11 EFI_SCREEN_DESCRIPTOR gPopupDimensions
;
12 LIST_ENTRY gUserSelectableOptions
;
13 EFI_STRING gMessageString
;
18 Free the user selectable option structure data.
20 @param OptionList Point to the selectable option list which need to be freed.
24 FreeSelectableOptions(
25 LIST_ENTRY
*OptionList
29 USER_SELECTABLE_OPTION
*SelectableOption
;
31 while (!IsListEmpty (OptionList
)) {
32 Link
= GetFirstNode (OptionList
);
33 SelectableOption
= SELECTABLE_OPTION_FROM_LINK (Link
);
34 RemoveEntryList (&SelectableOption
->Link
);
35 FreePool (SelectableOption
);
40 Display one selectable option.
42 @param SelectableOption The selectable option need to be drew.
43 @param Highlight Whether the option need to be highlighted.
47 DisplayOneSelectableOption(
48 IN USER_SELECTABLE_OPTION
*SelectableOption
,
53 gST
->ConOut
->SetAttribute (gST
->ConOut
, GetHighlightTextColor ());
55 PrintStringAt (SelectableOption
->OptionCol
, SelectableOption
->OptionRow
, SelectableOption
->OptionString
);
56 gST
->ConOut
->SetAttribute (gST
->ConOut
, GetPopupColor ());
60 Add one selectable option to option list. This is the work function for AddUserSelectableOptions.
62 @param PopupType The option need to be drew.
63 @param OptionType The type of this selection option.
64 @param OptionString Point to the option string that to be shown.
65 @param OptionCol The column that the option need to be drew at.
66 @param OptionRow The row that the option need to be drew at.
68 @retval EFI_SUCCESS This function implement successfully.
69 @retval EFI_OUT_OF_RESOURCES There are not enough resources available.
73 AddOneSelectableOption (
74 IN EFI_HII_POPUP_TYPE PopupType
,
75 IN EFI_HII_POPUP_SELECTION OptionType
,
76 IN CHAR16
*OptionString
,
81 USER_SELECTABLE_OPTION
*UserSelectableOption
;
83 UserSelectableOption
= AllocateZeroPool (sizeof (USER_SELECTABLE_OPTION
));
84 if (UserSelectableOption
== NULL
) {
85 return EFI_OUT_OF_RESOURCES
;
88 // Initialize the user selectable option based on the PopupType and OptionType.
89 // And then add the option to the option list gUserSelectableOptions.
91 UserSelectableOption
->Signature
= USER_SELECTABLE_OPTION_SIGNATURE
;
92 UserSelectableOption
->OptionString
= OptionString
;
93 UserSelectableOption
->OptionType
= OptionType
;
94 UserSelectableOption
->OptionCol
= OptionCol
;
95 UserSelectableOption
->OptionRow
= OptionRow
;
96 UserSelectableOption
->MinSequence
= 0;
99 case EfiHiiPopupTypeOk
:
100 UserSelectableOption
->MaxSequence
= 0;
101 UserSelectableOption
->Sequence
= 0;
103 case EfiHiiPopupTypeOkCancel
:
104 UserSelectableOption
->MaxSequence
= 1;
105 if (OptionType
== EfiHiiPopupSelectionOk
) {
106 UserSelectableOption
->Sequence
= 0;
108 UserSelectableOption
->Sequence
= 1;
111 case EfiHiiPopupTypeYesNo
:
112 UserSelectableOption
->MaxSequence
= 1;
113 if (OptionType
== EfiHiiPopupSelectionYes
) {
114 UserSelectableOption
->Sequence
= 0;
116 UserSelectableOption
->Sequence
= 1;
119 case EfiHiiPopupTypeYesNoCancel
:
120 UserSelectableOption
->MaxSequence
= 2;
121 if (OptionType
== EfiHiiPopupSelectionYes
) {
122 UserSelectableOption
->Sequence
= 0;
123 } else if (OptionType
== EfiHiiPopupSelectionNo
){
124 UserSelectableOption
->Sequence
= 1;
126 UserSelectableOption
->Sequence
= 2;
132 InsertTailList (&gUserSelectableOptions
, &UserSelectableOption
->Link
);
138 Add user selectable options to option list for different types of Popup.
140 @param PopupType Type of the popup to display.
142 @retval EFI_SUCCESS This function implement successfully.
143 @retval EFI_OUT_OF_RESOURCES There are not enough resources available.
147 AddUserSelectableOptions (
148 IN EFI_HII_POPUP_TYPE PopupType
158 Status
= EFI_SUCCESS
;
159 EndCol
= gPopupDimensions
.RightColumn
;
160 StartCol
= gPopupDimensions
.LeftColumn
;
161 OptionRow
= gPopupDimensions
.BottomRow
- POPUP_BORDER
;
162 ColDimension
= EndCol
- StartCol
+ 1;
164 InitializeListHead (&gUserSelectableOptions
);
167 case EfiHiiPopupTypeOk
:
169 // Add [Ok] option to the option list.
171 OptionCol
= StartCol
+ (ColDimension
- USER_SELECTABLE_OPTION_OK_WIDTH
) / 2;
172 Status
= AddOneSelectableOption (PopupType
, EfiHiiPopupSelectionOk
, gOkOption
, OptionCol
, OptionRow
);
174 case EfiHiiPopupTypeOkCancel
:
176 // Add [Ok] and [Cancel] options to the option list.
178 OptionCol
= StartCol
+ (ColDimension
- USER_SELECTABLE_OPTION_OK_CAL_WIDTH
) / 3;
179 Status
= AddOneSelectableOption (PopupType
, EfiHiiPopupSelectionOk
, gOkOption
, OptionCol
, OptionRow
);
180 OptionCol
= EndCol
- (ColDimension
- USER_SELECTABLE_OPTION_OK_CAL_WIDTH
) / 3 - (GetStringWidth (gCancelOption
) -2) / 2 + 1;
181 Status
= AddOneSelectableOption (PopupType
, EfiHiiPopupSelectionCancel
, gCancelOption
, OptionCol
, OptionRow
);
183 case EfiHiiPopupTypeYesNo
:
185 // Add [Yes] and [No] options to the option list.
187 OptionCol
= StartCol
+ (ColDimension
- USER_SELECTABLE_OPTION_YES_NO_WIDTH
) / 3;
188 Status
= AddOneSelectableOption (PopupType
, EfiHiiPopupSelectionYes
, gYesOption
, OptionCol
, OptionRow
);
189 OptionCol
= EndCol
- (ColDimension
- USER_SELECTABLE_OPTION_YES_NO_WIDTH
) / 3 - (GetStringWidth (gNoOption
)- 2) / 2 + 1;
190 Status
= AddOneSelectableOption (PopupType
, EfiHiiPopupSelectionNo
, gNoOption
, OptionCol
, OptionRow
);
192 case EfiHiiPopupTypeYesNoCancel
:
194 // Add [Yes], [No] and [Cancel] options to the option list.
196 OptionCol
= StartCol
+ (ColDimension
- USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH
) / 4;
197 Status
= AddOneSelectableOption (PopupType
, EfiHiiPopupSelectionYes
, gYesOption
, OptionCol
, OptionRow
);
198 OptionCol
= StartCol
+ (ColDimension
- (GetStringWidth (gNoOption
) -2) / 2) / 2;
199 Status
= AddOneSelectableOption (PopupType
, EfiHiiPopupSelectionNo
, gNoOption
, OptionCol
, OptionRow
);
200 OptionCol
= EndCol
- (ColDimension
- USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH
) / 4 - (GetStringWidth (gCancelOption
) - 2) / 2 + 1;
201 Status
= AddOneSelectableOption (PopupType
, EfiHiiPopupSelectionCancel
, gCancelOption
, OptionCol
, OptionRow
);
210 Show selectable options to user and get the one that user select.
212 @param PopupType Type of the popup to display.
213 @param UserSelection User selection.
218 IN EFI_HII_POPUP_TYPE PopupType
,
219 OUT EFI_HII_POPUP_SELECTION
*UserSelection
222 LIST_ENTRY
*HighlightPos
;
224 USER_SELECTABLE_OPTION
*SelectableOption
;
225 USER_SELECTABLE_OPTION
*HighlightOption
;
226 EFI_INPUT_KEY KeyValue
;
230 // Display user selectable options in gUserSelectableOptions and get the option which user selects.
232 HighlightPos
= gUserSelectableOptions
.ForwardLink
;
234 for (Link
= gUserSelectableOptions
.ForwardLink
; Link
!= &gUserSelectableOptions
; Link
= Link
->ForwardLink
) {
235 SelectableOption
= SELECTABLE_OPTION_FROM_LINK (Link
);
236 DisplayOneSelectableOption (SelectableOption
, (BOOLEAN
)(Link
== HighlightPos
));
239 //If UserSelection is NULL, there is no need to handle the key user input, just return.
241 if (UserSelection
== NULL
) {
245 Status
= WaitForKeyStroke (&KeyValue
);
246 ASSERT_EFI_ERROR (Status
);
248 HighlightOption
= SELECTABLE_OPTION_FROM_LINK (HighlightPos
);
249 switch (KeyValue
.UnicodeChar
) {
251 switch (KeyValue
.ScanCode
) {
253 if (HighlightOption
->Sequence
< HighlightOption
->MaxSequence
) {
254 HighlightPos
= HighlightPos
->ForwardLink
;
256 HighlightPos
= gUserSelectableOptions
.ForwardLink
;
260 if (HighlightOption
->Sequence
> HighlightOption
->MinSequence
) {
261 HighlightPos
= HighlightPos
->BackLink
;
263 HighlightPos
= gUserSelectableOptions
.BackLink
;
271 case CHAR_CARRIAGE_RETURN
:
272 *UserSelection
= HighlightOption
->OptionType
;
275 if (((KeyValue
.UnicodeChar
| UPPER_LOWER_CASE_OFFSET
) == (*gConfirmOptYes
| UPPER_LOWER_CASE_OFFSET
)) &&
276 (PopupType
== EfiHiiPopupTypeYesNo
|| PopupType
== EfiHiiPopupTypeYesNoCancel
)) {
277 *UserSelection
= EfiHiiPopupSelectionYes
;
279 } else if ((KeyValue
.UnicodeChar
| UPPER_LOWER_CASE_OFFSET
) == (*gConfirmOptNo
| UPPER_LOWER_CASE_OFFSET
) &&
280 (PopupType
== EfiHiiPopupTypeYesNo
|| PopupType
== EfiHiiPopupTypeYesNoCancel
)){
281 *UserSelection
= EfiHiiPopupSelectionNo
;
283 } else if ((KeyValue
.UnicodeChar
| UPPER_LOWER_CASE_OFFSET
) == (*gConfirmOptOk
| UPPER_LOWER_CASE_OFFSET
) &&
284 (PopupType
== EfiHiiPopupTypeOk
|| PopupType
== EfiHiiPopupTypeOkCancel
)){
285 *UserSelection
= EfiHiiPopupSelectionOk
;
287 } else if ((KeyValue
.UnicodeChar
| UPPER_LOWER_CASE_OFFSET
) == (*gConfirmOptCancel
| UPPER_LOWER_CASE_OFFSET
) &&
288 (PopupType
== EfiHiiPopupTypeOkCancel
|| PopupType
== EfiHiiPopupTypeYesNoCancel
)){
289 *UserSelection
= EfiHiiPopupSelectionCancel
;
298 Get the offset in the input string when the width reaches to a fixed one.
300 The input string may contain NARROW_CHAR and WIDE_CHAR.
301 Notice: the input string doesn't contain line break characters.
303 @param String The input string to be counted.
304 @param MaxWidth The max length this function supported.
305 @param Offset The max index of the string can be show out. If string's width less than MaxWidth, offset will point to the "\0" of the string.
309 GetStringOffsetWithWidth (
322 for (StrOffset
= 0; String
[StrOffset
] != CHAR_NULL
; StrOffset
++) {
323 switch (String
[StrOffset
]) {
331 StringWidth
+= CharWidth
;
332 if (StringWidth
>= MaxWidth
) {
342 Parse the message to check if it contains line break characters.
343 For once call, caller can get the string for one line and the width of the string.
344 This function call be called recursively to parse the whole InputString.
346 (Notice: current implementation, it only checks \r, \n characters, it deals \r,\n,\n\r same as \r\n.)
348 @param InputString String description for this option.
349 @param OutputString Buffer to copy the string into, caller is responsible for freeing the buffer.
350 @param OutputStrWidth The width of OutputString.
351 @param Index Where in InputString to start the copy process
353 @return Returns the number of CHAR16 characters that were copied into the OutputString buffer, include the '\0' info.
358 IN CHAR16
*InputString
,
359 OUT CHAR16
**OutputString
,
360 OUT UINTN
*OutputStrWidth
,
366 if (InputString
== NULL
|| Index
== NULL
|| OutputString
== NULL
) {
373 //Check the string to see if there are line break characters in the string
376 InputString
[*Index
+ StrOffset
] != CHAR_CARRIAGE_RETURN
&& InputString
[*Index
+ StrOffset
] != CHAR_LINEFEED
&& InputString
[*Index
+ StrOffset
] != CHAR_NULL
;
381 // The CHAR_NULL has process last time, this time just return 0 to stand for finishing parsing the InputString.
383 if (StrOffset
== 0 && (InputString
[*Index
+ StrOffset
] == CHAR_NULL
)) {
388 // Copy the string to OutputString buffer and calculate the width of OutputString.
390 *OutputString
= AllocateZeroPool ((StrOffset
+ 1) * sizeof(CHAR16
));
391 if (*OutputString
== NULL
) {
394 CopyMem ((*OutputString
), &InputString
[*Index
], StrOffset
* sizeof(CHAR16
));
395 *OutputStrWidth
= (GetStringWidth (*OutputString
) -2) / 2;
398 // Update the value of Index, can be used for marking where to check the input string for next call.
400 if (InputString
[*Index
+ StrOffset
] == CHAR_LINEFEED
) {
402 // Skip the /n or /n/r info.
404 if (InputString
[*Index
+ StrOffset
+ 1] == CHAR_CARRIAGE_RETURN
) {
405 *Index
= (*Index
+ StrOffset
+ 2);
407 *Index
= (*Index
+ StrOffset
+ 1);
409 } else if (InputString
[*Index
+ StrOffset
] == CHAR_CARRIAGE_RETURN
) {
411 // Skip the /r or /r/n info.
413 if (InputString
[*Index
+ StrOffset
+ 1] == CHAR_LINEFEED
) {
414 *Index
= (*Index
+ StrOffset
+ 2);
416 *Index
= (*Index
+ StrOffset
+ 1);
419 *Index
= (*Index
+ StrOffset
);
422 return StrOffset
+ 1;
426 Calculate the position of the popup.
428 @param PopupType Type of the popup to display.
429 @param ScreenForPopup The screen dimensions for the popup.
433 CalculatePopupPosition (
434 IN EFI_HII_POPUP_TYPE PopupType
,
435 OUT EFI_SCREEN_DESCRIPTOR
*ScreenForPopup
438 CHAR16
*OutputString
;
440 UINTN OutputStrWidth
;
441 UINTN OptionRowWidth
;
448 // Calculate the row number which is needed to show the message string and the max width of the string in one row.
450 for (StringIndex
= 0; ParseMessageString (gMessageString
, &OutputString
, &OutputStrWidth
, &StringIndex
) != 0;) {
452 if (gMaxRowWidth
< OutputStrWidth
) {
453 gMaxRowWidth
= OutputStrWidth
;
455 FreePool (OutputString
);
459 // Calculate the row width for the selectable options.(OptionRowWidth = Number * SkipWidth + OptionWidth)
461 if (PopupType
== EfiHiiPopupTypeOk
) {
462 OptionRowWidth
= USER_SELECTABLE_OPTION_SKIP_WIDTH
*2 + USER_SELECTABLE_OPTION_OK_WIDTH
;
463 } else if (PopupType
== EfiHiiPopupTypeOkCancel
) {
464 OptionRowWidth
= USER_SELECTABLE_OPTION_SKIP_WIDTH
*3 + USER_SELECTABLE_OPTION_OK_CAL_WIDTH
;
465 } else if (PopupType
== EfiHiiPopupTypeYesNo
) {
466 OptionRowWidth
= USER_SELECTABLE_OPTION_SKIP_WIDTH
*3 + USER_SELECTABLE_OPTION_YES_NO_WIDTH
;
467 } else if (PopupType
== EfiHiiPopupTypeYesNoCancel
) {
468 OptionRowWidth
= USER_SELECTABLE_OPTION_SKIP_WIDTH
*4 + USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH
;
470 if (OptionRowWidth
> gMaxRowWidth
) {
471 gMaxRowWidth
= OptionRowWidth
;
475 // Avialble row width for message string = screen width - left popup border width - right popup border width.
476 // Avialble line number for message string = screen height - 1 - popup header height - popup footer height.
477 // (Notice: screen height - 1 because in current UI page, the bottom row of srceen is usded to show Status Bar,not for form itself.
478 // So we don't use the bottom row for popup either. If macro STATUS_BAR_HEIGHT changed, we also need to update the height here.)
480 // Select the smaller one between actual dimension of message string and the avialble dimension for message string.
482 gST
->ConOut
->QueryMode (gST
->ConOut
, gST
->ConOut
->Mode
->Mode
, &Columns
, &Rows
);
483 gMaxRowWidth
= MIN (gMaxRowWidth
, Columns
- 2 * POPUP_BORDER
);
484 gMesStrLineNum
= MIN (gMesStrLineNum
, Rows
-1 - POPUP_FOOTER_HEIGHT
- POPUP_HEADER_HEIGHT
);
487 // Calculate the start column, end column, top row and bottom row for the popup.
489 ScreenForPopup
->LeftColumn
= (Columns
-2 * POPUP_BORDER
- gMaxRowWidth
) / 2;
490 ScreenForPopup
->RightColumn
= ScreenForPopup
->LeftColumn
+ gMaxRowWidth
+ 2 * POPUP_BORDER
- 1;
491 ScreenForPopup
->TopRow
= (Rows
- 1 - POPUP_FOOTER_HEIGHT
- POPUP_HEADER_HEIGHT
- gMesStrLineNum
) / 2;
492 ScreenForPopup
->BottomRow
= ScreenForPopup
->TopRow
+ gMesStrLineNum
+ POPUP_FOOTER_HEIGHT
+ POPUP_HEADER_HEIGHT
- 1;
496 Draw the Message box.
497 +-------------------------------------------+
498 | ERROR/WARNING/INFO |
499 |-------------------------------------------|
502 | user selectable options |
503 +-------------------------------------------+
505 @param PopupStyle Popup style to use.
510 IN EFI_HII_POPUP_STYLE PopupStyle
523 CHAR16
*OutputString
;
525 UINTN OutputStrWidth
;
526 UINTN DrawMesStrRowNum
;
528 EndCol
= gPopupDimensions
.RightColumn
;
529 TopRow
= gPopupDimensions
.TopRow
;
530 StartCol
= gPopupDimensions
.LeftColumn
;
531 BottomRow
= gPopupDimensions
.BottomRow
;
532 ColDimension
= EndCol
- StartCol
+ 1;
533 DrawMesStrRowNum
= 0;
536 // 1. Draw the top of the message box.
538 Character
= BOXDRAW_DOWN_RIGHT
;
539 PrintCharAt (StartCol
, TopRow
, Character
);
540 Character
= BOXDRAW_HORIZONTAL
;
541 for (Index
= StartCol
; Index
+ 1 < EndCol
; Index
++) {
542 PrintCharAt ((UINTN
)-1, (UINTN
)-1, Character
);
544 Character
= BOXDRAW_DOWN_LEFT
;
545 PrintCharAt ((UINTN
)-1, (UINTN
)-1, Character
);
548 // 2. Draw the prompt string for different popup styles.
550 Character
= BOXDRAW_VERTICAL
;
551 DisplayRow
= TopRow
+ POPUP_BORDER
;
552 ClearLines (StartCol
, EndCol
, DisplayRow
, DisplayRow
, GetPopupColor ());
553 PrintCharAt (StartCol
, DisplayRow
, Character
);
554 PrintCharAt (EndCol
, DisplayRow
, Character
);
555 if (PopupStyle
== EfiHiiPopupStyleError
) {
556 PrintStringAt ((ColDimension
- (GetStringWidth (gErrorPopup
) - 2) / 2) / 2 + StartCol
, DisplayRow
, gErrorPopup
);
557 } else if (PopupStyle
== EfiHiiPopupStyleWarning
) {
558 PrintStringAt ((ColDimension
- (GetStringWidth (gWarningPopup
) - 2) / 2) / 2 + StartCol
, DisplayRow
, gWarningPopup
);
560 PrintStringAt ((ColDimension
- (GetStringWidth (gInfoPopup
) - 2) / 2) / 2 + StartCol
, DisplayRow
, gInfoPopup
);
564 // 3. Draw the horizontal line below the prompt string for different popup styles.
566 DisplayRow
= TopRow
+ POPUP_BORDER
+ POPUP_STYLE_STRING_HEIGHT
;
567 ClearLines (StartCol
, EndCol
, DisplayRow
, DisplayRow
, GetPopupColor ());
568 Character
= BOXDRAW_HORIZONTAL
;
569 for (Index
= StartCol
+ 1; Index
< EndCol
; Index
++) {
570 PrintCharAt (Index
, DisplayRow
, Character
);
572 Character
= BOXDRAW_VERTICAL
;
573 PrintCharAt (StartCol
, DisplayRow
, Character
);
574 PrintCharAt (EndCol
, DisplayRow
, Character
);
577 // 4. Draw the mesage string.
579 DisplayRow
= TopRow
+ POPUP_HEADER_HEIGHT
;
580 for (Index
= DisplayRow
,StringIndex
= 0; ParseMessageString (gMessageString
, &OutputString
, &OutputStrWidth
, &StringIndex
) != 0 && DrawMesStrRowNum
< gMesStrLineNum
;) {
581 ClearLines (StartCol
, EndCol
, Index
, Index
, GetPopupColor ());
582 PrintCharAt (StartCol
, Index
, Character
);
583 PrintCharAt (EndCol
, Index
, Character
);
584 if (OutputStrWidth
> gMaxRowWidth
) {
586 //OutputStrWidth > MaxMesStrWidth, cut off the string and print print ... instead.
588 GetStringOffsetWithWidth (OutputString
, gMaxRowWidth
, &Length
);
589 TempString
= AllocateZeroPool ((Length
+ 1) * sizeof (CHAR16
));
590 if (TempString
== NULL
) {
591 FreePool (OutputString
);
592 return EFI_OUT_OF_RESOURCES
;
594 StrnCpyS (TempString
, Length
+ 1, OutputString
, Length
- 3);
595 StrCatS (TempString
, Length
+ 1, L
"...");
596 PrintStringAt ((ColDimension
- gMaxRowWidth
) / 2 + StartCol
, Index
, TempString
);
597 FreePool (TempString
);
599 PrintStringAt ((ColDimension
- OutputStrWidth
) / 2 + StartCol
, Index
, OutputString
);
603 FreePool (OutputString
);
607 // 5. Draw an empty line after message string.
609 ClearLines (StartCol
, EndCol
, Index
, Index
, GetPopupColor ());
610 PrintCharAt (StartCol
, Index
, Character
);
611 PrintCharAt (EndCol
, Index
, Character
);
613 // Check whether the actual string row number beyond the MesStrRowNum, if yes, print the ...... in the row.
615 if (OutputStrWidth
> 0 && DrawMesStrRowNum
>= gMesStrLineNum
) {
616 PrintStringAt ((ColDimension
- StrLen (L
"......")) / 2 + StartCol
, Index
, L
"......");
620 // 6. Draw an empty line which is used to show user selectable options, will draw concrete option strings in function GetUserSelection().
622 Character
= BOXDRAW_VERTICAL
;
623 DisplayRow
= BottomRow
- POPUP_BORDER
;
624 ClearLines (StartCol
, EndCol
, DisplayRow
, DisplayRow
, GetPopupColor ());
625 PrintCharAt (StartCol
, DisplayRow
, Character
);
626 PrintCharAt (EndCol
, DisplayRow
, Character
);
629 // 7. Draw the bottom of the message box.
631 Character
= BOXDRAW_UP_RIGHT
;
632 PrintCharAt (StartCol
, BottomRow
, Character
);
633 Character
= BOXDRAW_HORIZONTAL
;
634 for (Index
= StartCol
; Index
+ 1 < EndCol
; Index
++) {
635 PrintCharAt ((UINTN
)-1, (UINTN
) -1, Character
);
637 Character
= BOXDRAW_UP_LEFT
;
638 PrintCharAt ((UINTN
)-1, (UINTN
) -1, Character
);
644 Displays a popup window.
646 @param This A pointer to the EFI_HII_POPUP_PROTOCOL instance.
647 @param PopupStyle Popup style to use.
648 @param PopupType Type of the popup to display.
649 @param HiiHandle HII handle of the string pack containing Message
650 @param Message A message to display in the popup box.
651 @param UserSelection User selection.
653 @retval EFI_SUCCESS The popup box was successfully displayed.
654 @retval EFI_INVALID_PARAMETER HiiHandle and Message do not define a valid HII string.
655 @retval EFI_INVALID_PARAMETER PopupType is not one of the values defined by this specification.
656 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to display the popup box.
662 IN EFI_HII_POPUP_PROTOCOL
*This
,
663 IN EFI_HII_POPUP_STYLE PopupStyle
,
664 IN EFI_HII_POPUP_TYPE PopupType
,
665 IN EFI_HII_HANDLE HiiHandle
,
666 IN EFI_STRING_ID Message
,
667 OUT EFI_HII_POPUP_SELECTION
*UserSelection OPTIONAL
670 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
671 EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode
;
674 if ((PopupType
< EfiHiiPopupTypeOk
) || (PopupType
> EfiHiiPopupTypeYesNoCancel
)) {
675 return EFI_INVALID_PARAMETER
;
678 if((HiiHandle
== NULL
) || (Message
== 0)) {
679 return EFI_INVALID_PARAMETER
;
682 gMessageString
= HiiGetString (HiiHandle
, Message
, NULL
);
683 if(gMessageString
== NULL
) {
684 return EFI_INVALID_PARAMETER
;
687 ConOut
= gST
->ConOut
;
691 CopyMem (&SavedConsoleMode
, ConOut
->Mode
, sizeof (SavedConsoleMode
));
692 ConOut
->EnableCursor (ConOut
, FALSE
);
693 ConOut
->SetAttribute (ConOut
, GetPopupColor ());
695 CalculatePopupPosition (PopupType
, &gPopupDimensions
);
697 Status
= DrawMessageBox (PopupStyle
);
698 if (EFI_ERROR (Status
)) {
703 // Add user selectable options to option list: gUserSelectableOptions
705 Status
= AddUserSelectableOptions (PopupType
);
706 if (EFI_ERROR (Status
)) {
710 GetUserSelection (PopupType
, UserSelection
);
714 // Restore Conout attributes and free the resources allocate before.
716 ConOut
->EnableCursor (ConOut
, SavedConsoleMode
.CursorVisible
);
717 ConOut
->SetCursorPosition (ConOut
, SavedConsoleMode
.CursorColumn
, SavedConsoleMode
.CursorRow
);
718 ConOut
->SetAttribute (ConOut
, SavedConsoleMode
.Attribute
);
719 FreeSelectableOptions (&gUserSelectableOptions
);
720 FreePool (gMessageString
);