audk/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c

929 lines
28 KiB
C

/** @file
Copyright (c) 2004 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Presentation.c
Abstract:
Some presentation routines.
**/
#include "Setup.h"
#include "Ui.h"
BOOLEAN mHiiPackageListUpdated;
UI_MENU_SELECTION *gCurrentSelection;
/**
Clear retangle with specified text attribute.
@param LeftColumn Left column of retangle.
@param RightColumn Right column of retangle.
@param TopRow Start row of retangle.
@param BottomRow End row of retangle.
@param TextAttribute The character foreground and background.
@return None.
**/
VOID
ClearLines (
UINTN LeftColumn,
UINTN RightColumn,
UINTN TopRow,
UINTN BottomRow,
UINTN TextAttribute
)
{
CHAR16 *Buffer;
UINTN Row;
//
// For now, allocate an arbitrarily long buffer
//
Buffer = AllocateZeroPool (0x10000);
ASSERT (Buffer != NULL);
//
// Set foreground and background as defined
//
gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);
//
// Much faster to buffer the long string instead of print it a character at a time
//
SetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');
//
// Clear the desired area with the appropriate foreground/background
//
for (Row = TopRow; Row <= BottomRow; Row++) {
PrintStringAt (LeftColumn, Row, Buffer);
}
gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);
gBS->FreePool (Buffer);
return ;
}
VOID
NewStrCat (
CHAR16 *Destination,
CHAR16 *Source
)
{
UINTN Length;
for (Length = 0; Destination[Length] != 0; Length++)
;
//
// We now have the length of the original string
// We can safely assume for now that we are concatenating a narrow value to this string.
// For instance, the string is "XYZ" and cat'ing ">"
// If this assumption changes, we need to make this routine a bit more complex
//
Destination[Length] = NARROW_CHAR;
Length++;
StrCpy (Destination + Length, Source);
}
UINTN
GetStringWidth (
CHAR16 *String
)
{
UINTN Index;
UINTN Count;
UINTN IncrementValue;
Index = 0;
Count = 0;
IncrementValue = 1;
do {
//
// Advance to the null-terminator or to the first width directive
//
for (;
(String[Index] != NARROW_CHAR) && (String[Index] != WIDE_CHAR) && (String[Index] != 0);
Index++, Count = Count + IncrementValue
)
;
//
// We hit the null-terminator, we now have a count
//
if (String[Index] == 0) {
break;
}
//
// We encountered a narrow directive - strip it from the size calculation since it doesn't get printed
// and also set the flag that determines what we increment by.(if narrow, increment by 1, if wide increment by 2)
//
if (String[Index] == NARROW_CHAR) {
//
// Skip to the next character
//
Index++;
IncrementValue = 1;
} else {
//
// Skip to the next character
//
Index++;
IncrementValue = 2;
}
} while (String[Index] != 0);
//
// Increment by one to include the null-terminator in the size
//
Count++;
return Count * sizeof (CHAR16);
}
VOID
DisplayPageFrame (
VOID
)
{
UINTN Index;
UINT8 Line;
UINT8 Alignment;
CHAR16 Character;
CHAR16 *Buffer;
CHAR16 *StrFrontPageBanner;
UINTN Row;
EFI_SCREEN_DESCRIPTOR LocalScreen;
ZeroMem (&LocalScreen, sizeof (EFI_SCREEN_DESCRIPTOR));
gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &LocalScreen.RightColumn, &LocalScreen.BottomRow);
ClearLines (0, LocalScreen.RightColumn, 0, LocalScreen.BottomRow, KEYHELP_BACKGROUND);
CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
//
// For now, allocate an arbitrarily long buffer
//
Buffer = AllocateZeroPool (0x10000);
ASSERT (Buffer != NULL);
Character = BOXDRAW_HORIZONTAL;
for (Index = 0; Index + 2 < (LocalScreen.RightColumn - LocalScreen.LeftColumn); Index++) {
Buffer[Index] = Character;
}
if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {
//
// ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);
//
ClearLines (
LocalScreen.LeftColumn,
LocalScreen.RightColumn,
LocalScreen.TopRow,
FRONT_PAGE_HEADER_HEIGHT - 1 + LocalScreen.TopRow,
BANNER_TEXT | BANNER_BACKGROUND
);
//
// for (Line = 0; Line < BANNER_HEIGHT; Line++) {
//
for (Line = (UINT8) LocalScreen.TopRow; Line < BANNER_HEIGHT + (UINT8) LocalScreen.TopRow; Line++) {
//
// for (Alignment = 0; Alignment < BANNER_COLUMNS; Alignment++) {
//
for (Alignment = (UINT8) LocalScreen.LeftColumn;
Alignment < BANNER_COLUMNS + (UINT8) LocalScreen.LeftColumn;
Alignment++
) {
if (BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn] != 0x0000) {
StrFrontPageBanner = GetToken (
BannerData->Banner[Line - (UINT8) LocalScreen.TopRow][Alignment - (UINT8) LocalScreen.LeftColumn],
FrontPageHandle
);
} else {
continue;
}
switch (Alignment - LocalScreen.LeftColumn) {
case 0:
//
// Handle left column
//
PrintStringAt (LocalScreen.LeftColumn, Line, StrFrontPageBanner);
break;
case 1:
//
// Handle center column
//
PrintStringAt (
LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
Line,
StrFrontPageBanner
);
break;
case 2:
//
// Handle right column
//
PrintStringAt (
LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,
Line,
StrFrontPageBanner
);
break;
}
gBS->FreePool (StrFrontPageBanner);
}
}
}
ClearLines (
LocalScreen.LeftColumn,
LocalScreen.RightColumn,
LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT,
LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,
KEYHELP_TEXT | KEYHELP_BACKGROUND
);
if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {
ClearLines (
LocalScreen.LeftColumn,
LocalScreen.RightColumn,
LocalScreen.TopRow,
LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1,
TITLE_TEXT | TITLE_BACKGROUND
);
//
// Print Top border line
// +------------------------------------------------------------------------------+
// ? ?
// +------------------------------------------------------------------------------+
//
Character = BOXDRAW_DOWN_RIGHT;
PrintChar (Character);
PrintString (Buffer);
Character = BOXDRAW_DOWN_LEFT;
PrintChar (Character);
Character = BOXDRAW_VERTICAL;
for (Row = LocalScreen.TopRow + 1; Row <= LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 2; Row++) {
PrintCharAt (LocalScreen.LeftColumn, Row, Character);
PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
}
Character = BOXDRAW_UP_RIGHT;
PrintCharAt (LocalScreen.LeftColumn, LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);
PrintString (Buffer);
Character = BOXDRAW_UP_LEFT;
PrintChar (Character);
if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
//
// Print Bottom border line
// +------------------------------------------------------------------------------+
// ? ?
// +------------------------------------------------------------------------------+
//
Character = BOXDRAW_DOWN_RIGHT;
PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT, Character);
PrintString (Buffer);
Character = BOXDRAW_DOWN_LEFT;
PrintChar (Character);
Character = BOXDRAW_VERTICAL;
for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT + 1;
Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;
Row++
) {
PrintCharAt (LocalScreen.LeftColumn, Row, Character);
PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
}
Character = BOXDRAW_UP_RIGHT;
PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character);
PrintString (Buffer);
Character = BOXDRAW_UP_LEFT;
PrintChar (Character);
}
}
gBS->FreePool (Buffer);
}
/**
Evaluate all expressions in a Form.
@param FormSet FormSet this Form belongs to.
@param Form The Form.
@retval EFI_SUCCESS The expression evaluated successfuly
**/
EFI_STATUS
EvaluateFormExpressions (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_FORM *Form
)
{
EFI_STATUS Status;
LIST_ENTRY *Link;
FORM_EXPRESSION *Expression;
Link = GetFirstNode (&Form->ExpressionListHead);
while (!IsNull (&Form->ExpressionListHead, Link)) {
Expression = FORM_EXPRESSION_FROM_LINK (Link);
Link = GetNextNode (&Form->ExpressionListHead, Link);
if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF ||
Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {
//
// Postpone Form validation to Question editing or Form submiting
//
continue;
}
Status = EvaluateExpression (FormSet, Form, Expression);
if (EFI_ERROR (Status)) {
return Status;
}
}
return EFI_SUCCESS;
}
/*
+------------------------------------------------------------------------------+
?F2=Previous Page Setup Page ?
+------------------------------------------------------------------------------+
+------------------------------------------------------------------------------+
?F1=Scroll Help F9=Reset to Defaults F10=Save and Exit ?
| ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Discard Changes |
+------------------------------------------------------------------------------+
*/
EFI_STATUS
DisplayForm (
IN OUT UI_MENU_SELECTION *Selection
)
{
CHAR16 *StringPtr;
UINT16 MenuItemCount;
EFI_HII_HANDLE Handle;
BOOLEAN Suppress;
EFI_SCREEN_DESCRIPTOR LocalScreen;
UINT16 Width;
UINTN ArrayEntry;
CHAR16 *OutputString;
LIST_ENTRY *Link;
FORM_BROWSER_STATEMENT *Statement;
UINT16 NumberOfLines;
EFI_STATUS Status;
Handle = Selection->Handle;
MenuItemCount = 0;
ArrayEntry = 0;
OutputString = NULL;
UiInitMenu ();
CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
StringPtr = GetToken (Selection->FormSet->FormSetTitle, Handle);
if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {
gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);
PrintStringAt (
(LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,
LocalScreen.TopRow + 1,
StringPtr
);
}
if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
//
// Display the infrastructure strings
//
if (!IsListEmpty (&gMenuList)) {
PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.TopRow + 1, gFunctionTwoString);
}
PrintStringAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 4, gFunctionOneString);
PrintStringAt (
LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
LocalScreen.BottomRow - 4,
gFunctionNineString
);
PrintStringAt (
LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,
LocalScreen.BottomRow - 4,
gFunctionTenString
);
PrintAt (LocalScreen.LeftColumn + 2, LocalScreen.BottomRow - 3, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
PrintStringAt (
LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
LocalScreen.BottomRow - 3,
gEscapeString
);
}
//
// Remove Buffer allocated for StringPtr after it has been used.
//
gBS->FreePool (StringPtr);
//
// Evaluate all the Expressions in this Form
//
Status = EvaluateFormExpressions (Selection->FormSet, Selection->Form);
if (EFI_ERROR (Status)) {
return Status;
}
Link = GetFirstNode (&Selection->Form->StatementListHead);
while (!IsNull (&Selection->Form->StatementListHead, Link)) {
Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
if (Statement->SuppressExpression != NULL) {
Suppress = Statement->SuppressExpression->Result.Value.b;
} else {
Suppress = FALSE;
}
if (!Suppress) {
StringPtr = GetToken (Statement->Prompt, Handle);
Width = GetWidth (Statement, Handle);
NumberOfLines = 1;
ArrayEntry = 0;
for (; GetLineByWidth (StringPtr, Width, &ArrayEntry, &OutputString) != 0x0000;) {
//
// If there is more string to process print on the next row and increment the Skip value
//
if (StrLen (&StringPtr[ArrayEntry])) {
NumberOfLines++;
}
gBS->FreePool (OutputString);
}
//
// We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
// it in UiFreeMenu.
//
UiAddMenuOption (StringPtr, Selection->Handle, Statement, NumberOfLines, MenuItemCount);
MenuItemCount++;
}
Link = GetNextNode (&Selection->Form->StatementListHead, Link);
}
Status = UiDisplayMenu (Selection);
UiFreeMenu ();
return Status;
}
VOID
InitializeBrowserStrings (
VOID
)
{
gFunctionOneString = GetToken (STRING_TOKEN (FUNCTION_ONE_STRING), gHiiHandle);
gFunctionTwoString = GetToken (STRING_TOKEN (FUNCTION_TWO_STRING), gHiiHandle);
gFunctionNineString = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);
gFunctionTenString = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);
gEnterString = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle);
gEnterCommitString = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle);
gEscapeString = GetToken (STRING_TOKEN (ESCAPE_STRING), gHiiHandle);
gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);
gMoveHighlight = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle);
gMakeSelection = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle);
gDecNumericInput = GetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), gHiiHandle);
gHexNumericInput = GetToken (STRING_TOKEN (HEX_NUMERIC_INPUT), gHiiHandle);
gToggleCheckBox = GetToken (STRING_TOKEN (TOGGLE_CHECK_BOX), gHiiHandle);
gPromptForData = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle);
gPromptForPassword = GetToken (STRING_TOKEN (PROMPT_FOR_PASSWORD), gHiiHandle);
gPromptForNewPassword = GetToken (STRING_TOKEN (PROMPT_FOR_NEW_PASSWORD), gHiiHandle);
gConfirmPassword = GetToken (STRING_TOKEN (CONFIRM_PASSWORD), gHiiHandle);
gConfirmError = GetToken (STRING_TOKEN (CONFIRM_ERROR), gHiiHandle);
gPassowordInvalid = GetToken (STRING_TOKEN (PASSWORD_INVALID), gHiiHandle);
gPressEnter = GetToken (STRING_TOKEN (PRESS_ENTER), gHiiHandle);
gEmptyString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
gAreYouSure = GetToken (STRING_TOKEN (ARE_YOU_SURE), gHiiHandle);
gYesResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);
gNoResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);
gMiniString = GetToken (STRING_TOKEN (MINI_STRING), gHiiHandle);
gPlusString = GetToken (STRING_TOKEN (PLUS_STRING), gHiiHandle);
gMinusString = GetToken (STRING_TOKEN (MINUS_STRING), gHiiHandle);
gAdjustNumber = GetToken (STRING_TOKEN (ADJUST_NUMBER), gHiiHandle);
return ;
}
VOID
FreeBrowserStrings (
VOID
)
{
SafeFreePool (gFunctionOneString);
SafeFreePool (gFunctionTwoString);
SafeFreePool (gFunctionNineString);
SafeFreePool (gFunctionTenString);
SafeFreePool (gEnterString);
SafeFreePool (gEnterCommitString);
SafeFreePool (gEscapeString);
SafeFreePool (gMoveHighlight);
SafeFreePool (gMakeSelection);
SafeFreePool (gDecNumericInput);
SafeFreePool (gHexNumericInput);
SafeFreePool (gToggleCheckBox);
SafeFreePool (gPromptForData);
SafeFreePool (gPromptForPassword);
SafeFreePool (gPromptForNewPassword);
SafeFreePool (gConfirmPassword);
SafeFreePool (gPassowordInvalid);
SafeFreePool (gConfirmError);
SafeFreePool (gPressEnter);
SafeFreePool (gEmptyString);
SafeFreePool (gAreYouSure);
SafeFreePool (gYesResponse);
SafeFreePool (gNoResponse);
SafeFreePool (gMiniString);
SafeFreePool (gPlusString);
SafeFreePool (gMinusString);
SafeFreePool (gAdjustNumber);
return ;
}
/**
Update key's help imformation
@param MenuOption The Menu option
@param Selected Whether or not a tag be selected
@return None
**/
VOID
UpdateKeyHelp (
IN UI_MENU_OPTION *MenuOption,
IN BOOLEAN Selected
)
{
UINTN SecCol;
UINTN ThdCol;
UINTN LeftColumnOfHelp;
UINTN RightColumnOfHelp;
UINTN TopRowOfHelp;
UINTN BottomRowOfHelp;
UINTN StartColumnOfHelp;
EFI_SCREEN_DESCRIPTOR LocalScreen;
FORM_BROWSER_STATEMENT *Statement;
CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
SecCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
ThdCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3;
StartColumnOfHelp = LocalScreen.LeftColumn + 2;
LeftColumnOfHelp = LocalScreen.LeftColumn + 1;
RightColumnOfHelp = LocalScreen.RightColumn - 2;
TopRowOfHelp = LocalScreen.BottomRow - 4;
BottomRowOfHelp = LocalScreen.BottomRow - 3;
if (gClassOfVfr == EFI_GENERAL_APPLICATION_SUBCLASS) {
return ;
}
gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
Statement = MenuOption->ThisTag;
switch (Statement->Operand) {
case EFI_IFR_ORDERED_LIST_OP:
case EFI_IFR_ONE_OF_OP:
case EFI_IFR_NUMERIC_OP:
case EFI_IFR_TIME_OP:
case EFI_IFR_DATE_OP:
ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
if (!Selected) {
if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
}
if ((Statement->Operand == EFI_IFR_DATE_OP) ||
(Statement->Operand == EFI_IFR_TIME_OP) ||
(Statement->Operand == EFI_IFR_NUMERIC_OP && Statement->Step != 0)) {
PrintAt (
StartColumnOfHelp,
BottomRowOfHelp,
L"%c%c%c%c%s",
ARROW_UP,
ARROW_DOWN,
ARROW_RIGHT,
ARROW_LEFT,
gMoveHighlight
);
PrintStringAt (SecCol, BottomRowOfHelp, gAdjustNumber);
} else {
PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
}
} else {
PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString);
//
// If it is a selected numeric with manual input, display different message
//
if ((Statement->Operand == EFI_IFR_NUMERIC_OP) && (Statement->Step == 0)) {
PrintStringAt (
SecCol,
TopRowOfHelp,
(Statement->Flags & EFI_IFR_DISPLAY_UINT_HEX) ? gHexNumericInput : gDecNumericInput
);
} else if (Statement->Operand != EFI_IFR_ORDERED_LIST_OP) {
PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
}
if (Statement->Operand == EFI_IFR_ORDERED_LIST_OP) {
PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString);
PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);
}
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
}
break;
case EFI_IFR_CHECKBOX_OP:
ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
}
PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox);
break;
case EFI_IFR_REF_OP:
case EFI_IFR_PASSWORD_OP:
case EFI_IFR_STRING_OP:
case EFI_IFR_TEXT_OP:
case EFI_IFR_ACTION_OP:
case EFI_IFR_RESET_BUTTON_OP:
ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
if (!Selected) {
if (gClassOfVfr == EFI_SETUP_APPLICATION_SUBCLASS) {
PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gFunctionOneString);
PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
}
PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
if (Statement->Operand != EFI_IFR_TEXT_OP) {
PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
}
} else {
if (Statement->Operand != EFI_IFR_REF_OP) {
PrintStringAt (
(LocalScreen.RightColumn - GetStringWidth (gEnterCommitString) / 2) / 2,
BottomRowOfHelp,
gEnterCommitString
);
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
}
}
break;
default:
break;
}
}
EFI_STATUS
FormUpdateNotify (
IN UINT8 PackageType,
IN CONST EFI_GUID *PackageGuid,
IN CONST EFI_HII_PACKAGE_HEADER *Package,
IN EFI_HII_HANDLE Handle,
IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
)
{
mHiiPackageListUpdated = TRUE;
return EFI_SUCCESS;
}
EFI_STATUS
SetupBrowser (
IN OUT UI_MENU_SELECTION *Selection
)
{
EFI_STATUS Status;
LIST_ENTRY *Link;
EFI_BROWSER_ACTION_REQUEST ActionRequest;
EFI_HANDLE NotifyHandle;
EFI_HII_VALUE *HiiValue;
FORM_BROWSER_STATEMENT *Statement;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
gMenuRefreshHead = NULL;
gResetRequired = FALSE;
gNvUpdateRequired = FALSE;
UiInitMenuList ();
//
// Register notify for Form package update
//
Status = mHiiDatabase->RegisterPackageNotify (
mHiiDatabase,
EFI_HII_PACKAGE_FORM,
NULL,
FormUpdateNotify,
EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
&NotifyHandle
);
if (EFI_ERROR (Status)) {
return Status;
}
do {
//
// Displays the Header and Footer borders
//
DisplayPageFrame ();
//
// Initialize Selection->Form
//
if (Selection->FormId == 0) {
//
// Zero FormId indicates display the first Form in a FormSet
//
Link = GetFirstNode (&Selection->FormSet->FormListHead);
Selection->Form = FORM_BROWSER_FORM_FROM_LINK (Link);
Selection->FormId = Selection->Form->FormId;
} else {
Selection->Form = IdToForm (Selection->FormSet, Selection->FormId);
}
//
// Load Questions' Value for display
//
Status = LoadFormConfig (Selection->FormSet, Selection->Form);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Display form
//
Status = DisplayForm (Selection);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Check Selected Statement (if press ESC, Selection->Statement will be NULL)
//
Statement = Selection->Statement;
if (Statement != NULL) {
if (Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) {
gResetRequired = TRUE;
}
//
// Reset FormPackage update flag
//
mHiiPackageListUpdated = FALSE;
if (Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK && Statement->Operand != EFI_IFR_PASSWORD_OP) {
ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
HiiValue = &Statement->HiiValue;
if (HiiValue->Type == EFI_IFR_TYPE_STRING) {
//
// Create String in HII database for Configuration Driver to retrieve
//
HiiValue->Value.string = NewString ((CHAR16 *) Statement->BufferValue, Selection->FormSet->HiiHandle);
}
ConfigAccess = Selection->FormSet->ConfigAccess;
if (ConfigAccess == NULL) {
return EFI_UNSUPPORTED;
}
Status = ConfigAccess->Callback (
ConfigAccess,
EFI_BROWSER_ACTION_CHANGING,
Statement->QuestionId,
HiiValue->Type,
&HiiValue->Value,
&ActionRequest
);
if (HiiValue->Type == EFI_IFR_TYPE_STRING) {
//
// Clean the String in HII Database
//
DeleteString (HiiValue->Value.string, Selection->FormSet->HiiHandle);
}
if (!EFI_ERROR (Status)) {
switch (ActionRequest) {
case EFI_BROWSER_ACTION_REQUEST_RESET:
gResetRequired = TRUE;
break;
case EFI_BROWSER_ACTION_REQUEST_SUBMIT:
SubmitForm (Selection->FormSet, Selection->Form);
break;
case EFI_BROWSER_ACTION_REQUEST_EXIT:
Selection->Action = UI_ACTION_EXIT;
gNvUpdateRequired = FALSE;
break;
default:
break;
}
}
}
//
// Check whether Form Package has been updated during Callback
//
if (mHiiPackageListUpdated && (Selection->Action == UI_ACTION_REFRESH_FORM)) {
//
// Force to reparse IFR binary of target Formset
//
Selection->Action = UI_ACTION_REFRESH_FORMSET;
}
}
} while (Selection->Action == UI_ACTION_REFRESH_FORM);
//
// Unregister notify for Form package update
//
Status = mHiiDatabase->UnregisterPackageNotify (
mHiiDatabase,
NotifyHandle
);
return Status;
}