TianoCore EDK2 master
Loading...
Searching...
No Matches
Popup.c
Go to the documentation of this file.
1
9#include "FormDisplay.h"
10
11EFI_SCREEN_DESCRIPTOR gPopupDimensions;
12LIST_ENTRY gUserSelectableOptions;
13EFI_STRING gMessageString;
14UINTN gMesStrLineNum;
15UINTN gMaxRowWidth;
16
23VOID
25 LIST_ENTRY *OptionList
26 )
27{
28 LIST_ENTRY *Link;
29 USER_SELECTABLE_OPTION *SelectableOption;
30
31 while (!IsListEmpty (OptionList)) {
32 Link = GetFirstNode (OptionList);
33 SelectableOption = SELECTABLE_OPTION_FROM_LINK (Link);
34 RemoveEntryList (&SelectableOption->Link);
35 FreePool (SelectableOption);
36 }
37}
38
46VOID
48 IN USER_SELECTABLE_OPTION *SelectableOption,
49 IN BOOLEAN Highlight
50 )
51{
52 if (Highlight) {
53 gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ());
54 }
55
56 PrintStringAt (SelectableOption->OptionCol, SelectableOption->OptionRow, SelectableOption->OptionString);
57 gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ());
58}
59
75 IN EFI_HII_POPUP_TYPE PopupType,
76 IN EFI_HII_POPUP_SELECTION OptionType,
77 IN CHAR16 *OptionString,
78 IN UINTN OptionCol,
79 IN UINTN OptionRow
80 )
81{
82 USER_SELECTABLE_OPTION *UserSelectableOption;
83
84 UserSelectableOption = AllocateZeroPool (sizeof (USER_SELECTABLE_OPTION));
85 if (UserSelectableOption == NULL) {
86 return EFI_OUT_OF_RESOURCES;
87 }
88
89 //
90 // Initialize the user selectable option based on the PopupType and OptionType.
91 // And then add the option to the option list gUserSelectableOptions.
92 //
93 UserSelectableOption->Signature = USER_SELECTABLE_OPTION_SIGNATURE;
94 UserSelectableOption->OptionString = OptionString;
95 UserSelectableOption->OptionType = OptionType;
96 UserSelectableOption->OptionCol = OptionCol;
97 UserSelectableOption->OptionRow = OptionRow;
98 UserSelectableOption->MinSequence = 0;
99
100 switch (PopupType) {
101 case EfiHiiPopupTypeOk:
102 UserSelectableOption->MaxSequence = 0;
103 UserSelectableOption->Sequence = 0;
104 break;
105 case EfiHiiPopupTypeOkCancel:
106 UserSelectableOption->MaxSequence = 1;
107 if (OptionType == EfiHiiPopupSelectionOk) {
108 UserSelectableOption->Sequence = 0;
109 } else {
110 UserSelectableOption->Sequence = 1;
111 }
112
113 break;
114 case EfiHiiPopupTypeYesNo:
115 UserSelectableOption->MaxSequence = 1;
116 if (OptionType == EfiHiiPopupSelectionYes) {
117 UserSelectableOption->Sequence = 0;
118 } else {
119 UserSelectableOption->Sequence = 1;
120 }
121
122 break;
123 case EfiHiiPopupTypeYesNoCancel:
124 UserSelectableOption->MaxSequence = 2;
125 if (OptionType == EfiHiiPopupSelectionYes) {
126 UserSelectableOption->Sequence = 0;
127 } else if (OptionType == EfiHiiPopupSelectionNo) {
128 UserSelectableOption->Sequence = 1;
129 } else {
130 UserSelectableOption->Sequence = 2;
131 }
132
133 break;
134 default:
135 break;
136 }
137
138 InsertTailList (&gUserSelectableOptions, &UserSelectableOption->Link);
139
140 return EFI_SUCCESS;
141}
142
154 IN EFI_HII_POPUP_TYPE PopupType
155 )
156{
157 EFI_STATUS Status;
158 UINTN EndCol;
159 UINTN StartCol;
160 UINTN OptionCol;
161 UINTN OptionRow;
162 UINTN ColDimension;
163
164 Status = EFI_SUCCESS;
165 EndCol = gPopupDimensions.RightColumn;
166 StartCol = gPopupDimensions.LeftColumn;
167 OptionRow = gPopupDimensions.BottomRow - POPUP_BORDER;
168 ColDimension = EndCol - StartCol + 1;
169
170 InitializeListHead (&gUserSelectableOptions);
171
172 switch (PopupType) {
173 case EfiHiiPopupTypeOk:
174 //
175 // Add [Ok] option to the option list.
176 //
177 OptionCol = StartCol + (ColDimension - USER_SELECTABLE_OPTION_OK_WIDTH) / 2;
178 Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionOk, gOkOption, OptionCol, OptionRow);
179 break;
180 case EfiHiiPopupTypeOkCancel:
181 //
182 // Add [Ok] and [Cancel] options to the option list.
183 //
184 OptionCol = StartCol + (ColDimension - USER_SELECTABLE_OPTION_OK_CAL_WIDTH) / 3;
185 Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionOk, gOkOption, OptionCol, OptionRow);
186 OptionCol = EndCol - (ColDimension - USER_SELECTABLE_OPTION_OK_CAL_WIDTH) / 3 - (GetStringWidth (gCancelOption) -2) / 2 + 1;
187 Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionCancel, gCancelOption, OptionCol, OptionRow);
188 break;
189 case EfiHiiPopupTypeYesNo:
190 //
191 // Add [Yes] and [No] options to the option list.
192 //
193 OptionCol = StartCol + (ColDimension - USER_SELECTABLE_OPTION_YES_NO_WIDTH) / 3;
194 Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionYes, gYesOption, OptionCol, OptionRow);
195 OptionCol = EndCol - (ColDimension - USER_SELECTABLE_OPTION_YES_NO_WIDTH) / 3 - (GetStringWidth (gNoOption)- 2) / 2 + 1;
196 Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionNo, gNoOption, OptionCol, OptionRow);
197 break;
198 case EfiHiiPopupTypeYesNoCancel:
199 //
200 // Add [Yes], [No] and [Cancel] options to the option list.
201 //
202 OptionCol = StartCol + (ColDimension - USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH) / 4;
203 Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionYes, gYesOption, OptionCol, OptionRow);
204 OptionCol = StartCol + (ColDimension - (GetStringWidth (gNoOption) -2) / 2) / 2;
205 Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionNo, gNoOption, OptionCol, OptionRow);
206 OptionCol = EndCol - (ColDimension - USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH) / 4 - (GetStringWidth (gCancelOption) - 2) / 2 + 1;
207 Status = AddOneSelectableOption (PopupType, EfiHiiPopupSelectionCancel, gCancelOption, OptionCol, OptionRow);
208 break;
209 default:
210 break;
211 }
212
213 return Status;
214}
215
223VOID
225 IN EFI_HII_POPUP_TYPE PopupType,
226 OUT EFI_HII_POPUP_SELECTION *UserSelection
227 )
228{
229 LIST_ENTRY *HighlightPos;
230 LIST_ENTRY *Link;
231 USER_SELECTABLE_OPTION *SelectableOption;
232 USER_SELECTABLE_OPTION *HighlightOption;
233 EFI_INPUT_KEY KeyValue;
234 EFI_STATUS Status;
235
236 //
237 // Display user selectable options in gUserSelectableOptions and get the option which user selects.
238 //
239 HighlightPos = gUserSelectableOptions.ForwardLink;
240 do {
241 for (Link = gUserSelectableOptions.ForwardLink; Link != &gUserSelectableOptions; Link = Link->ForwardLink) {
242 SelectableOption = SELECTABLE_OPTION_FROM_LINK (Link);
243 DisplayOneSelectableOption (SelectableOption, (BOOLEAN)(Link == HighlightPos));
244 }
245
246 //
247 // If UserSelection is NULL, there is no need to handle the key user input, just return.
248 //
249 if (UserSelection == NULL) {
250 return;
251 }
252
253 Status = WaitForKeyStroke (&KeyValue);
254 ASSERT_EFI_ERROR (Status);
255
256 HighlightOption = SELECTABLE_OPTION_FROM_LINK (HighlightPos);
257 switch (KeyValue.UnicodeChar) {
258 case CHAR_NULL:
259 switch (KeyValue.ScanCode) {
260 case SCAN_RIGHT:
261 if (HighlightOption->Sequence < HighlightOption->MaxSequence) {
262 HighlightPos = HighlightPos->ForwardLink;
263 } else {
264 HighlightPos = gUserSelectableOptions.ForwardLink;
265 }
266
267 break;
268 case SCAN_LEFT:
269 if (HighlightOption->Sequence > HighlightOption->MinSequence) {
270 HighlightPos = HighlightPos->BackLink;
271 } else {
272 HighlightPos = gUserSelectableOptions.BackLink;
273 }
274
275 break;
276 default:
277 break;
278 }
279
280 break;
281
282 case CHAR_CARRIAGE_RETURN:
283 *UserSelection = HighlightOption->OptionType;
284 return;
285 default:
286 if (((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (*gConfirmOptYes | UPPER_LOWER_CASE_OFFSET)) &&
287 ((PopupType == EfiHiiPopupTypeYesNo) || (PopupType == EfiHiiPopupTypeYesNoCancel)))
288 {
289 *UserSelection = EfiHiiPopupSelectionYes;
290 return;
291 } else if (((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (*gConfirmOptNo| UPPER_LOWER_CASE_OFFSET)) &&
292 ((PopupType == EfiHiiPopupTypeYesNo) || (PopupType == EfiHiiPopupTypeYesNoCancel)))
293 {
294 *UserSelection = EfiHiiPopupSelectionNo;
295 return;
296 } else if (((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (*gConfirmOptOk | UPPER_LOWER_CASE_OFFSET)) &&
297 ((PopupType == EfiHiiPopupTypeOk) || (PopupType == EfiHiiPopupTypeOkCancel)))
298 {
299 *UserSelection = EfiHiiPopupSelectionOk;
300 return;
301 } else if (((KeyValue.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (*gConfirmOptCancel| UPPER_LOWER_CASE_OFFSET)) &&
302 ((PopupType == EfiHiiPopupTypeOkCancel) || (PopupType == EfiHiiPopupTypeYesNoCancel)))
303 {
304 *UserSelection = EfiHiiPopupSelectionCancel;
305 return;
306 }
307
308 break;
309 }
310 } while (TRUE);
311}
312
324VOID
326 IN CHAR16 *String,
327 IN UINTN MaxWidth,
328 OUT UINTN *Offset
329 )
330{
331 UINTN StringWidth;
332 UINTN CharWidth;
333 UINTN StrOffset;
334
335 StringWidth = 0;
336 CharWidth = 1;
337
338 for (StrOffset = 0; String[StrOffset] != CHAR_NULL; StrOffset++) {
339 switch (String[StrOffset]) {
340 case NARROW_CHAR:
341 CharWidth = 1;
342 break;
343 case WIDE_CHAR:
344 CharWidth = 2;
345 break;
346 default:
347 StringWidth += CharWidth;
348 if (StringWidth >= MaxWidth) {
349 *Offset = StrOffset;
350 return;
351 }
352 }
353 }
354
355 *Offset = StrOffset;
356}
357
373UINTN
375 IN CHAR16 *InputString,
376 OUT CHAR16 **OutputString,
377 OUT UINTN *OutputStrWidth,
378 IN OUT UINTN *Index
379 )
380{
381 UINTN StrOffset;
382
383 if ((InputString == NULL) || (Index == NULL) || (OutputString == NULL)) {
384 return 0;
385 }
386
387 *OutputStrWidth = 0;
388
389 //
390 // Check the string to see if there are line break characters in the string
391 //
392 for (StrOffset = 0;
393 InputString[*Index + StrOffset] != CHAR_CARRIAGE_RETURN && InputString[*Index + StrOffset] != CHAR_LINEFEED && InputString[*Index + StrOffset] != CHAR_NULL;
394 StrOffset++
395 )
396 {
397 }
398
399 //
400 // The CHAR_NULL has process last time, this time just return 0 to stand for finishing parsing the InputString.
401 //
402 if ((StrOffset == 0) && (InputString[*Index + StrOffset] == CHAR_NULL)) {
403 return 0;
404 }
405
406 //
407 // Copy the string to OutputString buffer and calculate the width of OutputString.
408 //
409 *OutputString = AllocateZeroPool ((StrOffset + 1) * sizeof (CHAR16));
410 if (*OutputString == NULL) {
411 return 0;
412 }
413
414 CopyMem ((*OutputString), &InputString[*Index], StrOffset * sizeof (CHAR16));
415 *OutputStrWidth = (GetStringWidth (*OutputString) -2) / 2;
416
417 //
418 // Update the value of Index, can be used for marking where to check the input string for next call.
419 //
420 if (InputString[*Index + StrOffset] == CHAR_LINEFEED) {
421 //
422 // Skip the /n or /n/r info.
423 //
424 if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {
425 *Index = (*Index + StrOffset + 2);
426 } else {
427 *Index = (*Index + StrOffset + 1);
428 }
429 } else if (InputString[*Index + StrOffset] == CHAR_CARRIAGE_RETURN) {
430 //
431 // Skip the /r or /r/n info.
432 //
433 if (InputString[*Index + StrOffset + 1] == CHAR_LINEFEED) {
434 *Index = (*Index + StrOffset + 2);
435 } else {
436 *Index = (*Index + StrOffset + 1);
437 }
438 } else {
439 *Index = (*Index + StrOffset);
440 }
441
442 return StrOffset + 1;
443}
444
452VOID
454 IN EFI_HII_POPUP_TYPE PopupType,
455 OUT EFI_SCREEN_DESCRIPTOR *ScreenForPopup
456 )
457{
458 CHAR16 *OutputString;
459 UINTN StringIndex;
460 UINTN OutputStrWidth;
461 UINTN OptionRowWidth;
462 UINTN Columns;
463 UINTN Rows;
464
465 OptionRowWidth = 0;
466
467 //
468 // Calculate the row number which is needed to show the message string and the max width of the string in one row.
469 //
470 for (StringIndex = 0; ParseMessageString (gMessageString, &OutputString, &OutputStrWidth, &StringIndex) != 0;) {
471 gMesStrLineNum++;
472 if (gMaxRowWidth < OutputStrWidth) {
473 gMaxRowWidth = OutputStrWidth;
474 }
475
476 FreePool (OutputString);
477 }
478
479 //
480 // Calculate the row width for the selectable options.(OptionRowWidth = Number * SkipWidth + OptionWidth)
481 //
482 if (PopupType == EfiHiiPopupTypeOk) {
483 OptionRowWidth = USER_SELECTABLE_OPTION_SKIP_WIDTH *2 + USER_SELECTABLE_OPTION_OK_WIDTH;
484 } else if (PopupType == EfiHiiPopupTypeOkCancel) {
485 OptionRowWidth = USER_SELECTABLE_OPTION_SKIP_WIDTH *3 + USER_SELECTABLE_OPTION_OK_CAL_WIDTH;
486 } else if (PopupType == EfiHiiPopupTypeYesNo) {
487 OptionRowWidth = USER_SELECTABLE_OPTION_SKIP_WIDTH *3 + USER_SELECTABLE_OPTION_YES_NO_WIDTH;
488 } else if (PopupType == EfiHiiPopupTypeYesNoCancel) {
489 OptionRowWidth = USER_SELECTABLE_OPTION_SKIP_WIDTH *4 + USER_SELECTABLE_OPTION_YES_NO_CAL_WIDTH;
490 }
491
492 if (OptionRowWidth > gMaxRowWidth) {
493 gMaxRowWidth = OptionRowWidth;
494 }
495
496 //
497 // Avialble row width for message string = screen width - left popup border width - right popup border width.
498 // Avialble line number for message string = screen height - 1 - popup header height - popup footer height.
499 // (Notice: screen height - 1 because in current UI page, the bottom row of srceen is usded to show Status Bar,not for form itself.
500 // 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.)
501 //
502 // Select the smaller one between actual dimension of message string and the avialble dimension for message string.
503 //
504 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Columns, &Rows);
505 gMaxRowWidth = MIN (gMaxRowWidth, Columns - 2 * POPUP_BORDER);
506 gMesStrLineNum = MIN (gMesStrLineNum, Rows -1 - POPUP_FOOTER_HEIGHT - POPUP_HEADER_HEIGHT);
507
508 //
509 // Calculate the start column, end column, top row and bottom row for the popup.
510 //
511 ScreenForPopup->LeftColumn = (Columns -2 * POPUP_BORDER - gMaxRowWidth) / 2;
512 ScreenForPopup->RightColumn = ScreenForPopup->LeftColumn + gMaxRowWidth + 2 * POPUP_BORDER - 1;
513 ScreenForPopup->TopRow = (Rows - 1 - POPUP_FOOTER_HEIGHT - POPUP_HEADER_HEIGHT - gMesStrLineNum) / 2;
514 ScreenForPopup->BottomRow = ScreenForPopup->TopRow + gMesStrLineNum + POPUP_FOOTER_HEIGHT + POPUP_HEADER_HEIGHT - 1;
515}
516
532 IN EFI_HII_POPUP_STYLE PopupStyle
533 )
534{
535 UINTN Index;
536 UINTN Length;
537 UINTN EndCol;
538 UINTN TopRow;
539 UINTN StartCol;
540 UINTN BottomRow;
541 CHAR16 Character;
542 UINTN DisplayRow;
543 UINTN StringIndex;
544 CHAR16 *TempString;
545 CHAR16 *OutputString;
546 UINTN ColDimension;
547 UINTN OutputStrWidth;
548 UINTN DrawMesStrRowNum;
549
550 EndCol = gPopupDimensions.RightColumn;
551 TopRow = gPopupDimensions.TopRow;
552 StartCol = gPopupDimensions.LeftColumn;
553 BottomRow = gPopupDimensions.BottomRow;
554 ColDimension = EndCol - StartCol + 1;
555 DrawMesStrRowNum = 0;
556
557 //
558 // 1. Draw the top of the message box.
559 //
560 Character = BOXDRAW_DOWN_RIGHT;
561 PrintCharAt (StartCol, TopRow, Character);
562 Character = BOXDRAW_HORIZONTAL;
563 for (Index = StartCol; Index + 1 < EndCol; Index++) {
564 PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
565 }
566
567 Character = BOXDRAW_DOWN_LEFT;
568 PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
569
570 //
571 // 2. Draw the prompt string for different popup styles.
572 //
573 Character = BOXDRAW_VERTICAL;
574 DisplayRow = TopRow + POPUP_BORDER;
575 ClearLines (StartCol, EndCol, DisplayRow, DisplayRow, GetPopupColor ());
576 PrintCharAt (StartCol, DisplayRow, Character);
577 PrintCharAt (EndCol, DisplayRow, Character);
578 if (PopupStyle == EfiHiiPopupStyleError) {
579 PrintStringAt ((ColDimension - (GetStringWidth (gErrorPopup) - 2) / 2) / 2 + StartCol, DisplayRow, gErrorPopup);
580 } else if (PopupStyle == EfiHiiPopupStyleWarning) {
581 PrintStringAt ((ColDimension - (GetStringWidth (gWarningPopup) - 2) / 2) / 2 + StartCol, DisplayRow, gWarningPopup);
582 } else {
583 PrintStringAt ((ColDimension - (GetStringWidth (gInfoPopup) - 2) / 2) / 2 + StartCol, DisplayRow, gInfoPopup);
584 }
585
586 //
587 // 3. Draw the horizontal line below the prompt string for different popup styles.
588 //
589 DisplayRow = TopRow + POPUP_BORDER + POPUP_STYLE_STRING_HEIGHT;
590 ClearLines (StartCol, EndCol, DisplayRow, DisplayRow, GetPopupColor ());
591 Character = BOXDRAW_HORIZONTAL;
592 for (Index = StartCol + 1; Index < EndCol; Index++) {
593 PrintCharAt (Index, DisplayRow, Character);
594 }
595
596 Character = BOXDRAW_VERTICAL;
597 PrintCharAt (StartCol, DisplayRow, Character);
598 PrintCharAt (EndCol, DisplayRow, Character);
599
600 //
601 // 4. Draw the mesage string.
602 //
603 DisplayRow = TopRow + POPUP_HEADER_HEIGHT;
604 for (Index = DisplayRow, StringIndex = 0; ParseMessageString (gMessageString, &OutputString, &OutputStrWidth, &StringIndex) != 0 && DrawMesStrRowNum < gMesStrLineNum;) {
605 ClearLines (StartCol, EndCol, Index, Index, GetPopupColor ());
606 PrintCharAt (StartCol, Index, Character);
607 PrintCharAt (EndCol, Index, Character);
608 if (OutputStrWidth > gMaxRowWidth) {
609 //
610 // OutputStrWidth > MaxMesStrWidth, cut off the string and print print ... instead.
611 //
612 GetStringOffsetWithWidth (OutputString, gMaxRowWidth, &Length);
613 TempString = AllocateZeroPool ((Length + 1) * sizeof (CHAR16));
614 if (TempString == NULL) {
615 FreePool (OutputString);
616 return EFI_OUT_OF_RESOURCES;
617 }
618
619 StrnCpyS (TempString, Length + 1, OutputString, Length - 3);
620 StrCatS (TempString, Length + 1, L"...");
621 PrintStringAt ((ColDimension - gMaxRowWidth) / 2 + StartCol, Index, TempString);
622 FreePool (TempString);
623 } else {
624 PrintStringAt ((ColDimension - OutputStrWidth) / 2 + StartCol, Index, OutputString);
625 }
626
627 Index++;
628 DrawMesStrRowNum++;
629 FreePool (OutputString);
630 }
631
632 //
633 // 5. Draw an empty line after message string.
634 //
635 ClearLines (StartCol, EndCol, Index, Index, GetPopupColor ());
636 PrintCharAt (StartCol, Index, Character);
637 PrintCharAt (EndCol, Index, Character);
638 //
639 // Check whether the actual string row number beyond the MesStrRowNum, if yes, print the ...... in the row.
640 //
641 if ((OutputStrWidth > 0) && (DrawMesStrRowNum >= gMesStrLineNum)) {
642 PrintStringAt ((ColDimension - StrLen (L"......")) / 2 + StartCol, Index, L"......");
643 }
644
645 //
646 // 6. Draw an empty line which is used to show user selectable options, will draw concrete option strings in function GetUserSelection().
647 //
648 Character = BOXDRAW_VERTICAL;
649 DisplayRow = BottomRow - POPUP_BORDER;
650 ClearLines (StartCol, EndCol, DisplayRow, DisplayRow, GetPopupColor ());
651 PrintCharAt (StartCol, DisplayRow, Character);
652 PrintCharAt (EndCol, DisplayRow, Character);
653
654 //
655 // 7. Draw the bottom of the message box.
656 //
657 Character = BOXDRAW_UP_RIGHT;
658 PrintCharAt (StartCol, BottomRow, Character);
659 Character = BOXDRAW_HORIZONTAL;
660 for (Index = StartCol; Index + 1 < EndCol; Index++) {
661 PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
662 }
663
664 Character = BOXDRAW_UP_LEFT;
665 PrintCharAt ((UINTN)-1, (UINTN)-1, Character);
666
667 return EFI_SUCCESS;
668}
669
687EFIAPI
690 IN EFI_HII_POPUP_STYLE PopupStyle,
691 IN EFI_HII_POPUP_TYPE PopupType,
692 IN EFI_HII_HANDLE HiiHandle,
693 IN EFI_STRING_ID Message,
694 OUT EFI_HII_POPUP_SELECTION *UserSelection OPTIONAL
695 )
696{
698 EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode;
699 EFI_STATUS Status;
700
701 if ((PopupType < EfiHiiPopupTypeOk) || (PopupType > EfiHiiPopupTypeYesNoCancel)) {
702 return EFI_INVALID_PARAMETER;
703 }
704
705 if ((HiiHandle == NULL) || (Message == 0)) {
706 return EFI_INVALID_PARAMETER;
707 }
708
709 gMessageString = HiiGetString (HiiHandle, Message, NULL);
710 if (gMessageString == NULL) {
711 return EFI_INVALID_PARAMETER;
712 }
713
714 ConOut = gST->ConOut;
715 gMaxRowWidth = 0;
716 gMesStrLineNum = 0;
717
718 CopyMem (&SavedConsoleMode, ConOut->Mode, sizeof (SavedConsoleMode));
719 ConOut->EnableCursor (ConOut, FALSE);
720 ConOut->SetAttribute (ConOut, GetPopupColor ());
721
722 CalculatePopupPosition (PopupType, &gPopupDimensions);
723
724 Status = DrawMessageBox (PopupStyle);
725 if (EFI_ERROR (Status)) {
726 goto Done;
727 }
728
729 //
730 // Add user selectable options to option list: gUserSelectableOptions
731 //
732 Status = AddUserSelectableOptions (PopupType);
733 if (EFI_ERROR (Status)) {
734 goto Done;
735 }
736
737 GetUserSelection (PopupType, UserSelection);
738
739Done:
740 //
741 // Restore Conout attributes and free the resources allocate before.
742 //
743 ConOut->EnableCursor (ConOut, SavedConsoleMode.CursorVisible);
744 ConOut->SetCursorPosition (ConOut, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);
745 ConOut->SetAttribute (ConOut, SavedConsoleMode.Attribute);
746 FreeSelectableOptions (&gUserSelectableOptions);
747 FreePool (gMessageString);
748
749 return Status;
750}
UINT64 UINTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
RETURN_STATUS EFIAPI StrCatS(IN OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:405
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
RETURN_STATUS EFIAPI StrnCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source, IN UINTN Length)
Definition: SafeString.c:310
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
UINTN PrintCharAt(IN UINTN Column, IN UINTN Row, CHAR16 Character)
UINTN PrintStringAt(IN UINTN Column, IN UINTN Row, IN CHAR16 *String)
UINT8 EFIAPI GetPopupColor(VOID)
VOID EFIAPI ClearLines(IN UINTN LeftColumn, IN UINTN RightColumn, IN UINTN TopRow, IN UINTN BottomRow, IN UINTN TextAttribute)
UINT8 EFIAPI GetHighlightTextColor(VOID)
EFI_STATUS WaitForKeyStroke(OUT EFI_INPUT_KEY *Key)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINTN GetStringWidth(IN CHAR16 *String)
Definition: FormDisplay.c:830
EFI_STRING EFIAPI HiiGetString(IN EFI_HII_HANDLE HiiHandle, IN EFI_STRING_ID StringId, IN CONST CHAR8 *Language OPTIONAL)
Definition: HiiString.c:211
#define NULL
Definition: Base.h:319
#define MIN(a, b)
Definition: Base.h:1007
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
UINTN ParseMessageString(IN CHAR16 *InputString, OUT CHAR16 **OutputString, OUT UINTN *OutputStrWidth, IN OUT UINTN *Index)
Definition: Popup.c:374
VOID FreeSelectableOptions(LIST_ENTRY *OptionList)
Definition: Popup.c:24
EFI_STATUS AddUserSelectableOptions(IN EFI_HII_POPUP_TYPE PopupType)
Definition: Popup.c:153
EFI_STATUS DrawMessageBox(IN EFI_HII_POPUP_STYLE PopupStyle)
Definition: Popup.c:531
EFI_STATUS EFIAPI CreatePopup(IN EFI_HII_POPUP_PROTOCOL *This, IN EFI_HII_POPUP_STYLE PopupStyle, IN EFI_HII_POPUP_TYPE PopupType, IN EFI_HII_HANDLE HiiHandle, IN EFI_STRING_ID Message, OUT EFI_HII_POPUP_SELECTION *UserSelection OPTIONAL)
Definition: Popup.c:688
VOID CalculatePopupPosition(IN EFI_HII_POPUP_TYPE PopupType, OUT EFI_SCREEN_DESCRIPTOR *ScreenForPopup)
Definition: Popup.c:453
VOID DisplayOneSelectableOption(IN USER_SELECTABLE_OPTION *SelectableOption, IN BOOLEAN Highlight)
Definition: Popup.c:47
VOID GetStringOffsetWithWidth(IN CHAR16 *String, IN UINTN MaxWidth, OUT UINTN *Offset)
Definition: Popup.c:325
EFI_STATUS AddOneSelectableOption(IN EFI_HII_POPUP_TYPE PopupType, IN EFI_HII_POPUP_SELECTION OptionType, IN CHAR16 *OptionString, IN UINTN OptionCol, IN UINTN OptionRow)
Definition: Popup.c:74
VOID GetUserSelection(IN EFI_HII_POPUP_TYPE PopupType, OUT EFI_HII_POPUP_SELECTION *UserSelection)
Definition: Popup.c:224
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_SYSTEM_TABLE * gST
VOID * EFI_HII_HANDLE
EFI_SIMPLE_TEXT_OUTPUT_MODE * Mode
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL * ConOut
Definition: UefiSpec.h:2064