2 Framework to UEFI 2.1 Setup Browser Thunk. The file consume EFI_FORM_BROWSER2_PROTOCOL
3 to produce a EFI_FORM_BROWSER_PROTOCOL.
5 Copyright (c) 2008, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "HiiDatabase.h"
17 #include "SetupBrowser.h"
19 EFI_GUID gFrameworkBdsFrontPageFormsetGuid
= FRAMEWORK_BDS_FRONTPAGE_FORMSET_GUID
;
20 EFI_HII_HANDLE gStringPackHandle
= NULL
;
21 BOOLEAN mFrontPageDisplayed
= FALSE
;
23 // 106F3545-B788-4cb5-9D2A-CE0CDB208DF5
25 EFI_GUID gEfiHiiThunkProducerGuid
= { 0x106f3545, 0xb788, 0x4cb5, { 0x9d, 0x2a, 0xce, 0xc, 0xdb, 0x20, 0x8d, 0xf5 } };
29 Get string by string id from HII Interface
34 @retval CHAR16 * String from ID.
35 @retval NULL If error occurs.
43 return HiiGetString (gStringPackHandle
, Id
, NULL
);
48 Show progress bar with title above it. It only works in Graphics mode.
51 @param TitleForeground Foreground color for Title.
52 @param TitleBackground Background color for Title.
53 @param Title Title above progress bar.
54 @param ProgressColor Progress bar color.
55 @param Progress Progress (0-100)
56 @param PreviousValue The previous value of the progress.
58 @retval EFI_STATUS Success update the progress bar
62 PlatformBdsShowProgress (
63 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground
,
64 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground
,
66 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor
,
68 IN UINTN PreviousValue
72 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
73 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
78 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
87 return EFI_INVALID_PARAMETER
;
91 Status
= gBS
->HandleProtocol (
92 gST
->ConsoleOutHandle
,
93 &gEfiGraphicsOutputProtocolGuid
,
94 (VOID
**) &GraphicsOutput
96 if (EFI_ERROR (Status
)) {
97 GraphicsOutput
= NULL
;
99 Status
= gBS
->HandleProtocol (
100 gST
->ConsoleOutHandle
,
101 &gEfiUgaDrawProtocolGuid
,
105 if (EFI_ERROR (Status
)) {
106 return EFI_UNSUPPORTED
;
111 if (GraphicsOutput
!= NULL
) {
112 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
113 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
115 Status
= UgaDraw
->GetMode (
122 if (EFI_ERROR (Status
)) {
123 return EFI_UNSUPPORTED
;
127 BlockWidth
= SizeOfX
/ 100;
128 BlockHeight
= SizeOfY
/ 50;
133 PosY
= SizeOfY
* 48 / 50;
137 // Clear progress area
139 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
141 if (GraphicsOutput
!= NULL
) {
142 Status
= GraphicsOutput
->Blt (
149 PosY
- EFI_GLYPH_HEIGHT
- 1,
151 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
152 SizeOfX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
155 Status
= UgaDraw
->Blt (
157 (EFI_UGA_PIXEL
*) &Color
,
162 PosY
- EFI_GLYPH_HEIGHT
- 1,
164 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
165 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
170 // Show progress by drawing blocks
172 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
173 PosX
= Index
* BlockWidth
;
174 if (GraphicsOutput
!= NULL
) {
175 Status
= GraphicsOutput
->Blt (
185 (BlockWidth
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
188 Status
= UgaDraw
->Blt (
190 (EFI_UGA_PIXEL
*) &ProgressColor
,
198 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
204 (SizeOfX
- StrLen (Title
) * EFI_GLYPH_WIDTH
) / 2,
205 PosY
- EFI_GLYPH_HEIGHT
- 1,
215 Function waits for a given event to fire, or for an optional timeout to expire.
218 @param Event The event to wait for
220 @param Timeout An optional timeout value in 100 ns units.
222 @retval EFI_SUCCESS Event fired before Timeout expired.
223 @retval EFI_TIME_OUT Timout expired before Event fired..
229 IN UINT64 Timeout OPTIONAL
234 EFI_EVENT TimerEvent
;
235 EFI_EVENT WaitList
[2];
239 // Create a timer event
241 Status
= gBS
->CreateEvent (EVT_TIMER
, 0, NULL
, NULL
, &TimerEvent
);
242 if (!EFI_ERROR (Status
)) {
244 // Set the timer event
253 // Wait for the original event or the timer
256 WaitList
[1] = TimerEvent
;
257 Status
= gBS
->WaitForEvent (2, WaitList
, &Index
);
258 gBS
->CloseEvent (TimerEvent
);
261 // If the timer expired, change the return to timed out
263 if (!EFI_ERROR (Status
) && Index
== 1) {
264 Status
= EFI_TIMEOUT
;
269 // No timeout... just wait on the event
271 Status
= gBS
->WaitForEvent (1, &Event
, &Index
);
272 ASSERT (!EFI_ERROR (Status
));
280 Function show progress bar to wait for user input.
283 @param TimeoutDefault - The fault time out value before the system
286 @retval EFI_SUCCESS User pressed some key except "Enter"
287 @retval EFI_TIME_OUT Timout expired or user press "Enter"
292 IN UINT16 TimeoutDefault
297 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
298 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
299 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
301 UINT16 TimeoutRemain
;
303 if (TimeoutDefault
== 0) {
307 DEBUG ((EFI_D_INFO
, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));
309 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
310 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
311 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
314 // Clear the progress status bar first
316 TmpStr
= GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION
));
317 if (TmpStr
!= NULL
) {
318 PlatformBdsShowProgress (Foreground
, Background
, TmpStr
, Color
, 0, 0);
321 TimeoutRemain
= TimeoutDefault
;
322 while (TimeoutRemain
!= 0) {
323 DEBUG ((EFI_D_INFO
, "Showing progress bar...Remaining %d second!\n", TimeoutRemain
));
325 Status
= WaitForSingleEvent (gST
->ConIn
->WaitForKey
, ONE_SECOND
);
326 if (Status
!= EFI_TIMEOUT
) {
334 if (TmpStr
!= NULL
) {
335 PlatformBdsShowProgress (
340 ((TimeoutDefault
- TimeoutRemain
) * 100 / TimeoutDefault
),
345 gBS
->FreePool (TmpStr
);
350 if (TimeoutRemain
== 0) {
355 // User pressed some key
357 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
358 if (EFI_ERROR (Status
)) {
362 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
364 // User pressed enter, equivalent to select "continue"
373 Return the default value for system Timeout variable.
375 @return Timeout value.
384 return PcdGet16 (PcdPlatformBootTimeOut
);
389 This is the Framework Setup Browser interface which displays a FormSet.
391 @param This The EFI_FORM_BROWSER_PROTOCOL context.
392 @param UseDatabase TRUE if the FormSet is from HII database. The Thunk implementation
393 only support UseDatabase is TRUE.
394 @param Handle The Handle buffer.
395 @param HandleCount The number of Handle in the Handle Buffer. It must be 1 for this implementation.
396 @param Packet The pointer to data buffer containing IFR and String package. Not supported.
397 @param CallbackHandle Not supported.
398 @param NvMapOverride The buffer is used only when there is no NV variable to define the
399 current settings and the caller needs to provide to the browser the
400 current settings for the the "fake" NV variable. If used, no saving of
401 an NV variable is possbile. This parameter is also ignored if Handle is NULL.
403 @retval EFI_SUCCESS If the Formset is displayed correctly.
404 @retval EFI_UNSUPPORTED If UseDatabase is FALSE or HandleCount is not 1.
405 @retval EFI_INVALID_PARAMETER If the *Handle passed in is not found in the database.
411 IN EFI_FORM_BROWSER_PROTOCOL
*This
,
412 IN BOOLEAN UseDatabase
,
413 IN FRAMEWORK_EFI_HII_HANDLE
*Handle
,
414 IN UINTN HandleCount
,
415 IN FRAMEWORK_EFI_IFR_PACKET
*Packet
, OPTIONAL
416 IN EFI_HANDLE CallbackHandle
, OPTIONAL
417 IN UINT8
*NvMapOverride
, OPTIONAL
418 IN FRAMEWORK_EFI_SCREEN_DESCRIPTOR
*ScreenDimensions
, OPTIONAL
419 OUT BOOLEAN
*ResetRequired OPTIONAL
423 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
424 HII_THUNK_CONTEXT
*ThunkContext
;
425 HII_THUNK_PRIVATE_DATA
*Private
;
426 EFI_FORMBROWSER_THUNK_PRIVATE_DATA
*BrowserPrivate
;
430 // ThunkSendForm only support displays forms registered into the HII database.
432 return EFI_UNSUPPORTED
;
435 if (HandleCount
!= 1 ) {
436 return EFI_UNSUPPORTED
;
439 BrowserPrivate
= EFI_FORMBROWSER_THUNK_PRIVATE_DATA_FROM_THIS (This
);
440 Private
= BrowserPrivate
->ThunkPrivate
;
442 ThunkContext
= FwHiiHandleToThunkContext (Private
, *Handle
);
443 if (ThunkContext
== NULL
) {
444 return EFI_INVALID_PARAMETER
;
448 // Following UEFI spec to do auto booting after a time-out. This feature is implemented
449 // in Framework Setup Browser and moved to MdeModulePkg/Universal/BdsDxe. The auto booting is
450 // moved here in HII Thunk module.
452 if (CompareGuid (&gFrameworkBdsFrontPageFormsetGuid
, &ThunkContext
->FormSet
->Guid
) && !mFrontPageDisplayed
) {
454 // Send form is called before entering the
456 mFrontPageDisplayed
= TRUE
;
457 Status
= ShowProgress (GetTimeout ());
459 if (EFI_ERROR (Status
)) {
464 if (NvMapOverride
!= NULL
) {
465 ThunkContext
->NvMapOverride
= NvMapOverride
;
468 Status
= mFormBrowser2Protocol
->SendForm (
469 mFormBrowser2Protocol
,
470 &ThunkContext
->UefiHiiHandle
,
474 (EFI_SCREEN_DESCRIPTOR
*) ScreenDimensions
,
478 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
479 *ResetRequired
= TRUE
;
487 Rountine used to display a generic dialog interface and return
488 the Key or Input from user input.
490 @param LinesNumber The number of lines for the dialog box.
491 @param HotKey Defines if a single character is parsed (TRUE) and returned in KeyValue
492 or if a string is returned in StringBuffer.
493 @param MaximumStringSize The maximum size in bytes of a typed-in string.
494 @param StringBuffer On return contains the typed-in string if HotKey is FALSE.
495 @param Key The EFI_INPUT_KEY value returned if HotKey is TRUE.
496 @param FirstString The pointer to the first string in the list of strings
497 that comprise the dialog box.
498 @param ... A series of NumberOfLines text strings that will be used
499 to construct the dialog box.
500 @retval EFI_SUCCESS The dialog is created successfully and user interaction was received.
501 @retval EFI_DEVICE_ERROR The user typed in an ESC.
502 @retval EFI_INVALID_PARAMETER One of the parameters was invalid.(StringBuffer == NULL && HotKey == FALSE).
507 IN UINTN LinesNumber
,
509 IN UINTN MaximumStringSize
,
510 OUT CHAR16
*StringBuffer
,
511 OUT EFI_INPUT_KEY
*Key
,
512 IN CHAR16
*FirstString
,
517 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
518 EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode
;
531 return EFI_UNSUPPORTED
;
534 if (MaximumStringSize
== 0) {
536 // Blank strint to output
538 return EFI_INVALID_PARAMETER
;
542 // Determine the length of the longest line in the popup and the the total
543 // number of lines in the popup
545 MaxLength
= StrLen (FirstString
);
547 VA_START (Args
, FirstString
);
548 while ((String
= VA_ARG (Args
, CHAR16
*)) != NULL
) {
549 MaxLength
= MAX (MaxLength
, StrLen (String
));
555 // If the total number of lines in the popup is not same to the input NumberOfLines
556 // the parameter is not valid. Not check.
558 // if (NumberOfLines != LinesNumber) {
559 // return EFI_INVALID_PARAMETER;
563 // If the maximum length of all the strings is not same to the input MaximumStringSize
564 // the parameter is not valid. Not check.
566 // if (MaxLength != MaximumStringSize) {
567 // return EFI_INVALID_PARAMETER;
571 // Cache a pointer to the Simple Text Output Protocol in the EFI System Table
573 ConOut
= gST
->ConOut
;
576 // Save the current console cursor position and attributes
578 CopyMem (&SavedConsoleMode
, ConOut
->Mode
, sizeof (SavedConsoleMode
));
581 // Retrieve the number of columns and rows in the current console mode
583 ConOut
->QueryMode (ConOut
, SavedConsoleMode
.Mode
, &Columns
, &Rows
);
586 // Disable cursor and set the foreground and background colors specified by Attribute
588 ConOut
->EnableCursor (ConOut
, FALSE
);
589 ConOut
->SetAttribute (ConOut
, EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
);
592 // Limit NumberOfLines to height of the screen minus 3 rows for the box itself
594 NumberOfLines
= MIN (NumberOfLines
, Rows
- 3);
597 // Limit MaxLength to width of the screen minus 2 columns for the box itself
599 MaxLength
= MIN (MaxLength
, Columns
- 2);
602 // Compute the starting row and starting column for the popup
604 Row
= (Rows
- (NumberOfLines
+ 3)) / 2;
605 Column
= (Columns
- (MaxLength
+ 2)) / 2;
608 // Allocate a buffer for a single line of the popup with borders and a Null-terminator
610 Line
= AllocateZeroPool ((MaxLength
+ 3) * sizeof (CHAR16
));
611 ASSERT (Line
!= NULL
);
614 // Draw top of popup box
616 SetMem16 (Line
, (MaxLength
+ 2) * 2, BOXDRAW_HORIZONTAL
);
617 Line
[0] = BOXDRAW_DOWN_RIGHT
;
618 Line
[MaxLength
+ 1] = BOXDRAW_DOWN_LEFT
;
619 Line
[MaxLength
+ 2] = L
'\0';
620 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
621 ConOut
->OutputString (ConOut
, Line
);
624 // Draw middle of the popup with strings
626 VA_START (Args
, FirstString
);
627 String
= FirstString
;
628 while ((String
!= NULL
) && (NumberOfLines
> 0)) {
629 Length
= StrLen (String
);
630 SetMem16 (Line
, (MaxLength
+ 2) * 2, L
' ');
631 if (Length
<= MaxLength
) {
633 // Length <= MaxLength
635 CopyMem (Line
+ 1 + (MaxLength
- Length
) / 2, String
, Length
* sizeof (CHAR16
));
638 // Length > MaxLength
640 CopyMem (Line
+ 1, String
+ (Length
- MaxLength
) / 2 , MaxLength
* sizeof (CHAR16
));
642 Line
[0] = BOXDRAW_VERTICAL
;
643 Line
[MaxLength
+ 1] = BOXDRAW_VERTICAL
;
644 Line
[MaxLength
+ 2] = L
'\0';
645 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
646 ConOut
->OutputString (ConOut
, Line
);
647 String
= VA_ARG (Args
, CHAR16
*);
653 // Draw bottom of popup box
655 SetMem16 (Line
, (MaxLength
+ 2) * 2, BOXDRAW_HORIZONTAL
);
656 Line
[0] = BOXDRAW_UP_RIGHT
;
657 Line
[MaxLength
+ 1] = BOXDRAW_UP_LEFT
;
658 Line
[MaxLength
+ 2] = L
'\0';
659 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
660 ConOut
->OutputString (ConOut
, Line
);
663 // Free the allocated line buffer
668 // Restore the cursor visibility, position, and attributes
670 ConOut
->EnableCursor (ConOut
, SavedConsoleMode
.CursorVisible
);
671 ConOut
->SetCursorPosition (ConOut
, SavedConsoleMode
.CursorColumn
, SavedConsoleMode
.CursorRow
);
672 ConOut
->SetAttribute (ConOut
, SavedConsoleMode
.Attribute
);
675 // Wait for a keystroke
678 gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &EventIndex
);
679 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, Key
);
687 Initialize string packages in HII database.
691 InitSetBrowserStrings (
696 // Initialize strings to HII database
698 gStringPackHandle
= HiiAddPackages (
699 &gEfiHiiThunkProducerGuid
,
704 ASSERT (gStringPackHandle
!= NULL
);