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 - 2011, Intel Corporation. All rights reserved.<BR>
6 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_HII_HANDLE gStringPackHandle
= NULL
;
20 BOOLEAN mFrontPageDisplayed
= FALSE
;
22 // 106F3545-B788-4cb5-9D2A-CE0CDB208DF5
24 EFI_GUID gEfiHiiThunkProducerGuid
= { 0x106f3545, 0xb788, 0x4cb5, { 0x9d, 0x2a, 0xce, 0xc, 0xdb, 0x20, 0x8d, 0xf5 } };
28 Get string by string id from HII Interface
33 @retval CHAR16 * String from ID.
34 @retval NULL If error occurs.
42 return HiiGetString (gStringPackHandle
, Id
, NULL
);
47 Show progress bar with title above it. It only works in Graphics mode.
50 @param TitleForeground Foreground color for Title.
51 @param TitleBackground Background color for Title.
52 @param Title Title above progress bar.
53 @param ProgressColor Progress bar color.
54 @param Progress Progress (0-100)
55 @param PreviousValue The previous value of the progress.
57 @retval EFI_STATUS Success update the progress bar
61 PlatformBdsShowProgress (
62 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground
,
63 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground
,
65 IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor
,
67 IN UINTN PreviousValue
71 EFI_GRAPHICS_OUTPUT_PROTOCOL
*GraphicsOutput
;
72 EFI_UGA_DRAW_PROTOCOL
*UgaDraw
;
77 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
86 return EFI_INVALID_PARAMETER
;
90 Status
= gBS
->HandleProtocol (
91 gST
->ConsoleOutHandle
,
92 &gEfiGraphicsOutputProtocolGuid
,
93 (VOID
**) &GraphicsOutput
95 if (EFI_ERROR (Status
)) {
96 GraphicsOutput
= NULL
;
98 Status
= gBS
->HandleProtocol (
99 gST
->ConsoleOutHandle
,
100 &gEfiUgaDrawProtocolGuid
,
104 if (EFI_ERROR (Status
) || (GraphicsOutput
== NULL
&& UgaDraw
== NULL
)) {
105 return EFI_UNSUPPORTED
;
110 if (GraphicsOutput
!= NULL
) {
111 SizeOfX
= GraphicsOutput
->Mode
->Info
->HorizontalResolution
;
112 SizeOfY
= GraphicsOutput
->Mode
->Info
->VerticalResolution
;
114 Status
= UgaDraw
->GetMode (
121 if (EFI_ERROR (Status
)) {
122 return EFI_UNSUPPORTED
;
126 BlockWidth
= SizeOfX
/ 100;
127 BlockHeight
= SizeOfY
/ 50;
132 PosY
= SizeOfY
* 48 / 50;
136 // Clear progress area
138 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
140 if (GraphicsOutput
!= NULL
) {
141 Status
= GraphicsOutput
->Blt (
148 PosY
- EFI_GLYPH_HEIGHT
- 1,
150 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
151 SizeOfX
* sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
154 Status
= UgaDraw
->Blt (
156 (EFI_UGA_PIXEL
*) &Color
,
161 PosY
- EFI_GLYPH_HEIGHT
- 1,
163 SizeOfY
- (PosY
- EFI_GLYPH_HEIGHT
- 1),
164 SizeOfX
* sizeof (EFI_UGA_PIXEL
)
169 // Show progress by drawing blocks
171 for (Index
= PreviousValue
; Index
< BlockNum
; Index
++) {
172 PosX
= Index
* BlockWidth
;
173 if (GraphicsOutput
!= NULL
) {
174 Status
= GraphicsOutput
->Blt (
184 (BlockWidth
) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
)
187 Status
= UgaDraw
->Blt (
189 (EFI_UGA_PIXEL
*) &ProgressColor
,
197 (BlockWidth
) * sizeof (EFI_UGA_PIXEL
)
203 (SizeOfX
- StrLen (Title
) * EFI_GLYPH_WIDTH
) / 2,
204 PosY
- EFI_GLYPH_HEIGHT
- 1,
214 Function waits for a given event to fire, or for an optional timeout to expire.
217 @param Event The event to wait for
219 @param Timeout An optional timeout value in 100 ns units.
221 @retval EFI_SUCCESS Event fired before Timeout expired.
222 @retval EFI_TIME_OUT Timout expired before Event fired..
228 IN UINT64 Timeout OPTIONAL
233 EFI_EVENT TimerEvent
;
234 EFI_EVENT WaitList
[2];
238 // Create a timer event
240 Status
= gBS
->CreateEvent (EVT_TIMER
, 0, NULL
, NULL
, &TimerEvent
);
241 if (!EFI_ERROR (Status
)) {
243 // Set the timer event
252 // Wait for the original event or the timer
255 WaitList
[1] = TimerEvent
;
256 Status
= gBS
->WaitForEvent (2, WaitList
, &Index
);
257 gBS
->CloseEvent (TimerEvent
);
260 // If the timer expired, change the return to timed out
262 if (!EFI_ERROR (Status
) && Index
== 1) {
263 Status
= EFI_TIMEOUT
;
268 // No timeout... just wait on the event
270 Status
= gBS
->WaitForEvent (1, &Event
, &Index
);
271 ASSERT (!EFI_ERROR (Status
));
279 Function show progress bar to wait for user input.
282 @param TimeoutDefault - The fault time out value before the system
285 @retval EFI_SUCCESS User pressed some key except "Enter"
286 @retval EFI_TIME_OUT Timout expired or user press "Enter"
291 IN UINT16 TimeoutDefault
296 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground
;
297 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background
;
298 EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color
;
300 UINT16 TimeoutRemain
;
302 if (TimeoutDefault
== 0) {
306 DEBUG ((EFI_D_INFO
, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));
308 SetMem (&Foreground
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
309 SetMem (&Background
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0x0);
310 SetMem (&Color
, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL
), 0xff);
313 // Clear the progress status bar first
315 TmpStr
= GetStringById (STRING_TOKEN (STR_START_BOOT_OPTION
));
316 if (TmpStr
!= NULL
) {
317 PlatformBdsShowProgress (Foreground
, Background
, TmpStr
, Color
, 0, 0);
320 TimeoutRemain
= TimeoutDefault
;
321 while (TimeoutRemain
!= 0) {
322 DEBUG ((EFI_D_INFO
, "Showing progress bar...Remaining %d second!\n", TimeoutRemain
));
324 Status
= WaitForSingleEvent (gST
->ConIn
->WaitForKey
, ONE_SECOND
);
325 if (Status
!= EFI_TIMEOUT
) {
333 if (TmpStr
!= NULL
) {
334 PlatformBdsShowProgress (
339 ((TimeoutDefault
- TimeoutRemain
) * 100 / TimeoutDefault
),
344 gBS
->FreePool (TmpStr
);
349 if (TimeoutRemain
== 0) {
354 // User pressed some key
356 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
357 if (EFI_ERROR (Status
)) {
361 if (Key
.UnicodeChar
== CHAR_CARRIAGE_RETURN
) {
363 // User pressed enter, equivalent to select "continue"
372 Return the default value for system Timeout variable.
374 @return Timeout value.
383 return PcdGet16 (PcdPlatformBootTimeOut
);
388 This is the Framework Setup Browser interface which displays a FormSet.
390 @param This The EFI_FORM_BROWSER_PROTOCOL context.
391 @param UseDatabase TRUE if the FormSet is from HII database. The Thunk implementation
392 only support UseDatabase is TRUE.
393 @param Handle The Handle buffer.
394 @param HandleCount The number of Handle in the Handle Buffer. It must be 1 for this implementation.
395 @param Packet The pointer to data buffer containing IFR and String package. Not supported.
396 @param CallbackHandle Not supported.
397 @param NvMapOverride The buffer is used only when there is no NV variable to define the
398 current settings and the caller needs to provide to the browser the
399 current settings for the the "fake" NV variable. If used, no saving of
400 an NV variable is possbile. This parameter is also ignored if Handle is NULL.
401 @param ScreenDimensions
402 Allows the browser to be called so that it occupies a portion of the physical
403 screen instead of dynamically determining the screen dimensions.
404 @param ResetRequired This BOOLEAN value denotes whether a reset is required based on the data that
405 might have been changed. The ResetRequired parameter is primarily applicable
406 for configuration applications, and is an optional parameter.
408 @retval EFI_SUCCESS If the Formset is displayed correctly.
409 @retval EFI_UNSUPPORTED If UseDatabase is FALSE or HandleCount is not 1.
410 @retval EFI_INVALID_PARAMETER If the *Handle passed in is not found in the database.
415 IN EFI_FORM_BROWSER_PROTOCOL
*This
,
416 IN BOOLEAN UseDatabase
,
417 IN FRAMEWORK_EFI_HII_HANDLE
*Handle
,
418 IN UINTN HandleCount
,
419 IN EFI_IFR_PACKET
*Packet
, OPTIONAL
420 IN EFI_HANDLE CallbackHandle
, OPTIONAL
421 IN UINT8
*NvMapOverride
, OPTIONAL
422 IN FRAMEWORK_EFI_SCREEN_DESCRIPTOR
*ScreenDimensions
, OPTIONAL
423 OUT BOOLEAN
*ResetRequired OPTIONAL
427 EFI_BROWSER_ACTION_REQUEST ActionRequest
;
428 HII_THUNK_CONTEXT
*ThunkContext
;
429 HII_THUNK_PRIVATE_DATA
*Private
;
430 EFI_FORMBROWSER_THUNK_PRIVATE_DATA
*BrowserPrivate
;
434 // ThunkSendForm only support displays forms registered into the HII database.
436 return EFI_UNSUPPORTED
;
439 if (HandleCount
!= 1 ) {
440 return EFI_UNSUPPORTED
;
443 BrowserPrivate
= EFI_FORMBROWSER_THUNK_PRIVATE_DATA_FROM_THIS (This
);
444 Private
= BrowserPrivate
->ThunkPrivate
;
446 ThunkContext
= FwHiiHandleToThunkContext (Private
, *Handle
);
447 if (ThunkContext
== NULL
) {
448 return EFI_INVALID_PARAMETER
;
452 // Following UEFI spec to do auto booting after a time-out. This feature is implemented
453 // in Framework Setup Browser and moved to MdeModulePkg/Universal/BdsDxe. The auto booting is
454 // moved here in HII Thunk module.
456 if (CompareGuid (&gFrameworkBdsFrontPageFormsetGuid
, &ThunkContext
->FormSet
->Guid
) && !mFrontPageDisplayed
) {
458 // Send form is called before entering the
460 mFrontPageDisplayed
= TRUE
;
461 Status
= ShowProgress (GetTimeout ());
463 if (EFI_ERROR (Status
)) {
468 if (NvMapOverride
!= NULL
) {
469 ThunkContext
->NvMapOverride
= NvMapOverride
;
472 Status
= mFormBrowser2Protocol
->SendForm (
473 mFormBrowser2Protocol
,
474 &ThunkContext
->UefiHiiHandle
,
478 (EFI_SCREEN_DESCRIPTOR
*) ScreenDimensions
,
482 if (ActionRequest
== EFI_BROWSER_ACTION_REQUEST_RESET
) {
483 *ResetRequired
= TRUE
;
491 Rountine used to display a generic dialog interface and return
492 the Key or Input from user input.
494 @param LinesNumber The number of lines for the dialog box.
495 @param HotKey Defines if a single character is parsed (TRUE) and returned in KeyValue
496 or if a string is returned in StringBuffer.
497 @param MaximumStringSize The maximum size in bytes of a typed-in string.
498 @param StringBuffer On return contains the typed-in string if HotKey is FALSE.
499 @param Key The EFI_INPUT_KEY value returned if HotKey is TRUE.
500 @param FirstString The pointer to the first string in the list of strings
501 that comprise the dialog box.
502 @param ... A series of NumberOfLines text strings that will be used
503 to construct the dialog box.
504 @retval EFI_SUCCESS The dialog is created successfully and user interaction was received.
505 @retval EFI_DEVICE_ERROR The user typed in an ESC.
506 @retval EFI_INVALID_PARAMETER One of the parameters was invalid.(StringBuffer == NULL && HotKey == FALSE).
511 IN UINTN LinesNumber
,
513 IN UINTN MaximumStringSize
,
514 OUT CHAR16
*StringBuffer
,
515 OUT EFI_INPUT_KEY
*Key
,
516 IN CHAR16
*FirstString
,
521 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*ConOut
;
522 EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode
;
535 return EFI_UNSUPPORTED
;
538 if (MaximumStringSize
== 0) {
540 // Blank strint to output
542 return EFI_INVALID_PARAMETER
;
546 // Determine the length of the longest line in the popup and the the total
547 // number of lines in the popup
549 MaxLength
= StrLen (FirstString
);
551 VA_START (Args
, FirstString
);
552 while ((String
= VA_ARG (Args
, CHAR16
*)) != NULL
) {
553 MaxLength
= MAX (MaxLength
, StrLen (String
));
559 // If the total number of lines in the popup is not same to the input NumberOfLines
560 // the parameter is not valid. Not check.
562 // if (NumberOfLines != LinesNumber) {
563 // return EFI_INVALID_PARAMETER;
567 // If the maximum length of all the strings is not same to the input MaximumStringSize
568 // the parameter is not valid. Not check.
570 // if (MaxLength != MaximumStringSize) {
571 // return EFI_INVALID_PARAMETER;
575 // Cache a pointer to the Simple Text Output Protocol in the EFI System Table
577 ConOut
= gST
->ConOut
;
580 // Save the current console cursor position and attributes
582 CopyMem (&SavedConsoleMode
, ConOut
->Mode
, sizeof (SavedConsoleMode
));
585 // Retrieve the number of columns and rows in the current console mode
587 ConOut
->QueryMode (ConOut
, SavedConsoleMode
.Mode
, &Columns
, &Rows
);
590 // Disable cursor and set the foreground and background colors specified by Attribute
592 ConOut
->EnableCursor (ConOut
, FALSE
);
593 ConOut
->SetAttribute (ConOut
, EFI_LIGHTGRAY
| EFI_BACKGROUND_BLUE
);
596 // Limit NumberOfLines to height of the screen minus 3 rows for the box itself
598 NumberOfLines
= MIN (NumberOfLines
, Rows
- 3);
601 // Limit MaxLength to width of the screen minus 2 columns for the box itself
603 MaxLength
= MIN (MaxLength
, Columns
- 2);
606 // Compute the starting row and starting column for the popup
608 Row
= (Rows
- (NumberOfLines
+ 3)) / 2;
609 Column
= (Columns
- (MaxLength
+ 2)) / 2;
612 // Allocate a buffer for a single line of the popup with borders and a Null-terminator
614 Line
= AllocateZeroPool ((MaxLength
+ 3) * sizeof (CHAR16
));
615 ASSERT (Line
!= NULL
);
618 // Draw top of popup box
620 SetMem16 (Line
, (MaxLength
+ 2) * 2, BOXDRAW_HORIZONTAL
);
621 Line
[0] = BOXDRAW_DOWN_RIGHT
;
622 Line
[MaxLength
+ 1] = BOXDRAW_DOWN_LEFT
;
623 Line
[MaxLength
+ 2] = L
'\0';
624 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
625 ConOut
->OutputString (ConOut
, Line
);
628 // Draw middle of the popup with strings
630 VA_START (Args
, FirstString
);
631 String
= FirstString
;
632 while ((String
!= NULL
) && (NumberOfLines
> 0)) {
633 Length
= StrLen (String
);
634 SetMem16 (Line
, (MaxLength
+ 2) * 2, L
' ');
635 if (Length
<= MaxLength
) {
637 // Length <= MaxLength
639 CopyMem (Line
+ 1 + (MaxLength
- Length
) / 2, String
, Length
* sizeof (CHAR16
));
642 // Length > MaxLength
644 CopyMem (Line
+ 1, String
+ (Length
- MaxLength
) / 2 , MaxLength
* sizeof (CHAR16
));
646 Line
[0] = BOXDRAW_VERTICAL
;
647 Line
[MaxLength
+ 1] = BOXDRAW_VERTICAL
;
648 Line
[MaxLength
+ 2] = L
'\0';
649 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
650 ConOut
->OutputString (ConOut
, Line
);
651 String
= VA_ARG (Args
, CHAR16
*);
657 // Draw bottom of popup box
659 SetMem16 (Line
, (MaxLength
+ 2) * 2, BOXDRAW_HORIZONTAL
);
660 Line
[0] = BOXDRAW_UP_RIGHT
;
661 Line
[MaxLength
+ 1] = BOXDRAW_UP_LEFT
;
662 Line
[MaxLength
+ 2] = L
'\0';
663 ConOut
->SetCursorPosition (ConOut
, Column
, Row
++);
664 ConOut
->OutputString (ConOut
, Line
);
667 // Free the allocated line buffer
672 // Restore the cursor visibility, position, and attributes
674 ConOut
->EnableCursor (ConOut
, SavedConsoleMode
.CursorVisible
);
675 ConOut
->SetCursorPosition (ConOut
, SavedConsoleMode
.CursorColumn
, SavedConsoleMode
.CursorRow
);
676 ConOut
->SetAttribute (ConOut
, SavedConsoleMode
.Attribute
);
679 // Wait for a keystroke
682 gBS
->WaitForEvent (1, &gST
->ConIn
->WaitForKey
, &EventIndex
);
683 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, Key
);
691 Initialize string packages in HII database.
695 InitSetBrowserStrings (
700 // Initialize strings to HII database
702 gStringPackHandle
= HiiAddPackages (
703 &gEfiHiiThunkProducerGuid
,
708 ASSERT (gStringPackHandle
!= NULL
);