summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/SetupBrowserDxe
diff options
context:
space:
mode:
authorEric Dong <eric.dong@intel.com>2013-08-09 05:26:47 +0000
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>2013-08-09 05:26:47 +0000
commitb9feb4bdf281bcd9c61d9b089c379f265664674b (patch)
tree8e0d577f3767750ce82be625bd507311d370b97c /MdeModulePkg/Universal/SetupBrowserDxe
parent301c867b27f975eda41ffb340e7a314e5f4d0ff1 (diff)
downloadedk2-platforms-b9feb4bdf281bcd9c61d9b089c379f265664674b.tar.xz
Update Browser to provide the customization possibilities.
Signed-off-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com> MdeModulePkg Patch Tested-by: Laszlo Ersek <lersek@redhat.com> OvmfPkg Patch Tested-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14537 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal/SetupBrowserDxe')
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Colors.h44
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Expression.c6
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Expression.h265
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c65
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c1418
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c2425
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Print.c272
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c1075
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.c2302
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.h821
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf26
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.unibin14784 -> 0 bytes
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Ui.c4027
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Ui.h1067
14 files changed, 3721 insertions, 10092 deletions
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Colors.h b/MdeModulePkg/Universal/SetupBrowserDxe/Colors.h
deleted file mode 100644
index 2db8b99614..0000000000
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Colors.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/** @file
-MACRO definitions for color used in Setup Browser.
-
-Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
-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.
-
-**/
-//
-// Unicode collation protocol in
-
-#ifndef _COLORS_H_
-#define _COLORS_H_
-
-//
-// Screen Color Settings
-//
-#define PICKLIST_HIGHLIGHT_TEXT EFI_WHITE
-#define PICKLIST_HIGHLIGHT_BACKGROUND EFI_BACKGROUND_CYAN
-#define TITLE_TEXT EFI_WHITE
-#define TITLE_BACKGROUND EFI_BACKGROUND_BLUE
-#define KEYHELP_TEXT EFI_LIGHTGRAY
-#define KEYHELP_BACKGROUND EFI_BACKGROUND_BLACK
-#define SUBTITLE_BACKGROUND EFI_BACKGROUND_LIGHTGRAY
-#define BANNER_TEXT EFI_BLUE
-#define BANNER_BACKGROUND EFI_BACKGROUND_LIGHTGRAY
-#define FIELD_TEXT_GRAYED EFI_DARKGRAY
-#define FIELD_BACKGROUND EFI_BACKGROUND_LIGHTGRAY
-#define POPUP_TEXT EFI_LIGHTGRAY
-#define POPUP_BACKGROUND EFI_BACKGROUND_BLUE
-#define POPUP_INVERSE_TEXT EFI_LIGHTGRAY
-#define POPUP_INVERSE_BACKGROUND EFI_BACKGROUND_BLACK
-#define HELP_TEXT EFI_BLUE
-#define ERROR_TEXT EFI_RED | EFI_BRIGHT
-#define INFO_TEXT EFI_YELLOW | EFI_BRIGHT
-#define ARROW_TEXT EFI_RED | EFI_BRIGHT
-#define ARROW_BACKGROUND EFI_BACKGROUND_LIGHTGRAY
-
-#endif
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
index cd29e29438..44dae1ba03 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
@@ -787,7 +787,7 @@ FORM_BROWSER_FORM *
IdToForm (
IN FORM_BROWSER_FORMSET *FormSet,
IN UINT16 FormId
-)
+ )
{
LIST_ENTRY *Link;
FORM_BROWSER_FORM *Form;
@@ -2105,7 +2105,7 @@ GetQuestionValueFromForm (
//
FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
ASSERT (FormSet != NULL);
- Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet, FALSE);
+ Status = InitializeFormSet(HiiHandle, FormSetGuid, FormSet);
if (EFI_ERROR (Status)) {
GetTheVal = FALSE;
goto Done;
@@ -2800,7 +2800,7 @@ EvaluateExpression (
for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) {
StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2);
}
- Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer);
+ Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer, NULL);
FreePool (NameValue);
if (!EFI_ERROR (Status)) {
Data1.Value.b = TRUE;
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Expression.h b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.h
new file mode 100644
index 0000000000..5660a997b8
--- /dev/null
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Expression.h
@@ -0,0 +1,265 @@
+/** @file
+Private structure, MACRO and function definitions for User Interface related functionalities.
+
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
+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.
+
+**/
+
+#ifndef _EXPRESSION_H_
+#define _EXPRESSION_H_
+
+/**
+ Get the expression list count.
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval >=0 The expression count
+ @retval -1 Input parameter error.
+
+**/
+INTN
+GetConditionalExpressionCount (
+ IN EXPRESS_LEVEL Level
+ );
+
+/**
+ Reset stack pointer to begin of the stack.
+
+**/
+VOID
+ResetCurrentExpressionStack (
+ VOID
+ );
+
+/**
+ Reset stack pointer to begin of the stack.
+
+**/
+VOID
+ResetMapExpressionListStack (
+ VOID
+ );
+
+/**
+ Reset stack pointer to begin of the stack.
+
+**/
+VOID
+ResetScopeStack (
+ VOID
+ );
+
+/**
+ Push an Operand onto the Stack
+
+ @param Operand Operand to push.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
+ stack.
+
+**/
+EFI_STATUS
+PushScope (
+ IN UINT8 Operand
+ );
+
+/**
+ Get the expression Buffer pointer.
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval The start pointer of the expression buffer or NULL.
+
+**/
+FORM_EXPRESSION **
+GetConditionalExpressionList (
+ IN EXPRESS_LEVEL Level
+ );
+
+/**
+ Pop an Operand from the Stack
+
+ @param Operand Operand to pop.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
+ stack.
+
+**/
+EFI_STATUS
+PopScope (
+ OUT UINT8 *Operand
+ );
+
+/**
+ Push the list of map expression onto the Stack
+
+ @param Pointer Pointer to the list of map expression to be pushed.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushMapExpressionList (
+ IN VOID *Pointer
+ );
+
+/**
+ Push current expression onto the Stack
+
+ @param Pointer Pointer to current expression.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushCurrentExpression (
+ IN VOID *Pointer
+ );
+
+/**
+ Zero extend integer/boolean/date/time to UINT64 for comparing.
+
+ @param Value HII Value to be converted.
+
+**/
+VOID
+ExtendValueToU64 (
+ IN EFI_HII_VALUE *Value
+ );
+
+/**
+ Push the expression options onto the Stack.
+
+ @param Pointer Pointer to the current expression.
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PushConditionalExpression (
+ IN FORM_EXPRESSION *Pointer,
+ IN EXPRESS_LEVEL Level
+ );
+
+/**
+ Pop the expression options from the Stack
+
+ @param Level Which type this expression belong to. Form,
+ statement or option?
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopConditionalExpression (
+ IN EXPRESS_LEVEL Level
+ );
+
+/**
+ Pop the list of map expression from the Stack
+
+ @param Pointer Pointer to the list of map expression to be pop.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopMapExpressionList (
+ OUT VOID **Pointer
+ );
+
+/**
+ Pop current expression from the Stack
+
+ @param Pointer Pointer to current expression to be pop.
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+PopCurrentExpression (
+ OUT VOID **Pointer
+ );
+
+/**
+ Evaluate the result of a HII expression.
+
+ If Expression is NULL, then ASSERT.
+
+ @param FormSet FormSet associated with this expression.
+ @param Form Form associated with this expression.
+ @param Expression Expression to be evaluated.
+
+ @retval EFI_SUCCESS The expression evaluated successfuly
+ @retval EFI_NOT_FOUND The Question which referenced by a QuestionId
+ could not be found.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
+ stack.
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
+ @retval EFI_INVALID_PARAMETER Syntax error with the Expression
+
+**/
+EFI_STATUS
+EvaluateExpression (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN FORM_BROWSER_FORM *Form,
+ IN OUT FORM_EXPRESSION *Expression
+ );
+/**
+ Return the result of the expression list. Check the expression list and
+ return the highest priority express result.
+ Priority: DisableIf > SuppressIf > GrayOutIf > FALSE
+
+ @param ExpList The input expression list.
+ @param Evaluate Whether need to evaluate the expression first.
+ @param FormSet FormSet associated with this expression.
+ @param Form Form associated with this expression.
+
+ @retval EXPRESS_RESULT Return the higher priority express result.
+ DisableIf > SuppressIf > GrayOutIf > FALSE
+
+**/
+EXPRESS_RESULT
+EvaluateExpressionList (
+ IN FORM_EXPRESSION_LIST *ExpList,
+ IN BOOLEAN Evaluate,
+ IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL
+ IN FORM_BROWSER_FORM *Form OPTIONAL
+ );
+
+/**
+ Get Form given its FormId.
+
+ @param FormSet The formset which contains this form.
+ @param FormId Id of this form.
+
+ @retval Pointer The form.
+ @retval NULL Specified Form is not found in the formset.
+
+**/
+FORM_BROWSER_FORM *
+IdToForm (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN UINT16 FormId
+ );
+
+#endif // _EXPRESSION_H
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
index 2464aebd09..1c3ab2bedc 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
@@ -16,7 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
UINT16 mStatementIndex;
UINT16 mExpressionOpCodeIndex;
-
+EFI_QUESTION_ID mUsedQuestionId;
BOOLEAN mInScopeSubtitle;
extern LIST_ENTRY gBrowserStorageList;
/**
@@ -42,9 +42,9 @@ CreateStatement (
if (Form == NULL) {
//
- // We are currently not in a Form Scope, so just skip this Statement
+ // Only guid op may out side the form level.
//
- return NULL;
+ ASSERT (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_GUID_OP);
}
Statement = &FormSet->StatementBuffer[mStatementIndex];
@@ -58,6 +58,7 @@ CreateStatement (
Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;
Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
+ Statement->OpCode = (EFI_IFR_OP_HEADER *) OpCodeData;
StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));
CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));
@@ -82,8 +83,11 @@ CreateStatement (
//
// Insert this Statement into current Form
//
- InsertTailList (&Form->StatementListHead, &Statement->Link);
-
+ if (Form == NULL) {
+ InsertTailList (&FormSet->StatementListOSF, &Statement->Link);
+ } else {
+ InsertTailList (&Form->StatementListHead, &Statement->Link);
+ }
return Statement;
}
@@ -1133,6 +1137,7 @@ ParseOpCodes (
CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);
mStatementIndex = 0;
+ mUsedQuestionId = 1;
FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));
if (FormSet->StatementBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
@@ -1144,6 +1149,7 @@ ParseOpCodes (
return EFI_OUT_OF_RESOURCES;
}
+ InitializeListHead (&FormSet->StatementListOSF);
InitializeListHead (&FormSet->StorageListHead);
InitializeListHead (&FormSet->DefaultStoreListHead);
InitializeListHead (&FormSet->FormListHead);
@@ -1502,7 +1508,6 @@ ParseOpCodes (
InitializeListHead (&CurrentForm->ConfigRequestHead);
CurrentForm->FormType = STANDARD_MAP_FORM_TYPE;
- CurrentForm->NvUpdateRequired = FALSE;
CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));
CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));
@@ -1539,7 +1544,6 @@ ParseOpCodes (
CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));
ASSERT (CurrentForm != NULL);
CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;
- CurrentForm->NvUpdateRequired = FALSE;
InitializeListHead (&CurrentForm->ExpressionListHead);
InitializeListHead (&CurrentForm->StatementListHead);
InitializeListHead (&CurrentForm->ConfigRequestHead);
@@ -1653,7 +1657,7 @@ ParseOpCodes (
ASSERT (CurrentStatement != NULL);
CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;
-
+ CurrentStatement->FakeQuestionId = mUsedQuestionId++;
if (Scope != 0) {
mInScopeSubtitle = TRUE;
}
@@ -1662,13 +1666,14 @@ ParseOpCodes (
case EFI_IFR_TEXT_OP:
CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
ASSERT (CurrentStatement != NULL);
-
+ CurrentStatement->FakeQuestionId = mUsedQuestionId++;
CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));
break;
case EFI_IFR_RESET_BUTTON_OP:
CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
ASSERT (CurrentStatement != NULL);
+ CurrentStatement->FakeQuestionId = mUsedQuestionId++;
CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));
break;
@@ -1913,6 +1918,7 @@ ParseOpCodes (
CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));
ASSERT (CurrentOption != NULL);
CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;
+ CurrentOption->OpCode = (EFI_IFR_ONE_OF_OPTION *) OpCodeData;
CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;
CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;
@@ -2270,45 +2276,8 @@ ParseOpCodes (
//
// Vendor specific
//
- case EFI_IFR_GUID_OP:
- if (CompareGuid (&gEfiIfrTianoGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
- //
- // Tiano specific GUIDed opcodes
- //
- switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {
- case EFI_IFR_EXTEND_OP_LABEL:
- //
- // just ignore label
- //
- break;
-
- case EFI_IFR_EXTEND_OP_BANNER:
- //
- // By SubClass to get Banner Data from Front Page
- //
- if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {
- CopyMem (
- &gBannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][
- ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],
- &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,
- sizeof (EFI_STRING_ID)
- );
- }
- break;
-
- case EFI_IFR_EXTEND_OP_CLASS:
- CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));
- break;
-
- case EFI_IFR_EXTEND_OP_SUBCLASS:
- CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));
- break;
-
- default:
- break;
- }
- }
-
+ case EFI_IFR_GUID_OP:
+ CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);
break;
//
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c b/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c
deleted file mode 100644
index 844590770a..0000000000
--- a/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c
+++ /dev/null
@@ -1,1418 +0,0 @@
-/** @file
-Implementation for handling user input from the User Interfaces.
-
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
-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.
-
-**/
-
-#include "Setup.h"
-
-
-/**
- Get string or password input from user.
-
- @param MenuOption Pointer to the current input menu.
- @param Prompt The prompt string shown on popup window.
- @param StringPtr Old user input and destination for use input string.
-
- @retval EFI_SUCCESS If string input is read successfully
- @retval EFI_DEVICE_ERROR If operation fails
-
-**/
-EFI_STATUS
-ReadString (
- IN UI_MENU_OPTION *MenuOption,
- IN CHAR16 *Prompt,
- IN OUT CHAR16 *StringPtr
- )
-{
- EFI_STATUS Status;
- EFI_INPUT_KEY Key;
- CHAR16 NullCharacter;
- UINTN ScreenSize;
- CHAR16 Space[2];
- CHAR16 KeyPad[2];
- CHAR16 *TempString;
- CHAR16 *BufferedString;
- UINTN Index;
- UINTN Index2;
- UINTN Count;
- UINTN Start;
- UINTN Top;
- UINTN DimensionsWidth;
- UINTN DimensionsHeight;
- UINTN CurrentCursor;
- BOOLEAN CursorVisible;
- UINTN Minimum;
- UINTN Maximum;
- FORM_BROWSER_STATEMENT *Question;
- BOOLEAN IsPassword;
-
- DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
- DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;
-
- NullCharacter = CHAR_NULL;
- ScreenSize = GetStringWidth (Prompt) / sizeof (CHAR16);
- Space[0] = L' ';
- Space[1] = CHAR_NULL;
-
- Question = MenuOption->ThisTag;
- Minimum = (UINTN) Question->Minimum;
- Maximum = (UINTN) Question->Maximum;
-
- if (Question->Operand == EFI_IFR_PASSWORD_OP) {
- IsPassword = TRUE;
- } else {
- IsPassword = FALSE;
- }
-
- TempString = AllocateZeroPool ((Maximum + 1)* sizeof (CHAR16));
- ASSERT (TempString);
-
- if (ScreenSize < (Maximum + 1)) {
- ScreenSize = Maximum + 1;
- }
-
- if ((ScreenSize + 2) > DimensionsWidth) {
- ScreenSize = DimensionsWidth - 2;
- }
-
- BufferedString = AllocateZeroPool (ScreenSize * 2);
- ASSERT (BufferedString);
-
- Start = (DimensionsWidth - ScreenSize - 2) / 2 + gScreenDimensions.LeftColumn + 1;
- Top = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1;
-
- //
- // Display prompt for string
- //
- CreateMultiStringPopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter);
-
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));
-
- CursorVisible = gST->ConOut->Mode->CursorVisible;
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
-
- CurrentCursor = GetStringWidth (StringPtr) / 2 - 1;
- if (CurrentCursor != 0) {
- //
- // Show the string which has beed saved before.
- //
- SetUnicodeMem (BufferedString, ScreenSize - 1, L' ');
- PrintStringAt (Start + 1, Top + 3, BufferedString);
-
- if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) {
- Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2;
- } else {
- Index = 0;
- }
-
- if (IsPassword) {
- gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3);
- }
-
- for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {
- BufferedString[Count] = StringPtr[Index];
-
- if (IsPassword) {
- PrintChar (L'*');
- }
- }
-
- if (!IsPassword) {
- PrintStringAt (Start + 1, Top + 3, BufferedString);
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3);
- }
-
- do {
- Status = WaitForKeyStroke (&Key);
- ASSERT_EFI_ERROR (Status);
-
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY));
- switch (Key.UnicodeChar) {
- case CHAR_NULL:
- switch (Key.ScanCode) {
- case SCAN_LEFT:
- if (CurrentCursor > 0) {
- CurrentCursor--;
- }
- break;
-
- case SCAN_RIGHT:
- if (CurrentCursor < (GetStringWidth (StringPtr) / 2 - 1)) {
- CurrentCursor++;
- }
- break;
-
- case SCAN_ESC:
- FreePool (TempString);
- FreePool (BufferedString);
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
- return EFI_DEVICE_ERROR;
-
- default:
- break;
- }
-
- break;
-
- case CHAR_CARRIAGE_RETURN:
- if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) {
-
- FreePool (TempString);
- FreePool (BufferedString);
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
- return EFI_SUCCESS;
- } else {
- //
- // Simply create a popup to tell the user that they had typed in too few characters.
- // To save code space, we can then treat this as an error and return back to the menu.
- //
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-
- FreePool (TempString);
- FreePool (BufferedString);
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- gST->ConOut->EnableCursor (gST->ConOut, CursorVisible);
- return EFI_DEVICE_ERROR;
- }
-
- break;
-
- case CHAR_BACKSPACE:
- if (StringPtr[0] != CHAR_NULL && CurrentCursor != 0) {
- for (Index = 0; Index < CurrentCursor - 1; Index++) {
- TempString[Index] = StringPtr[Index];
- }
- Count = GetStringWidth (StringPtr) / 2 - 1;
- if (Count >= CurrentCursor) {
- for (Index = CurrentCursor - 1, Index2 = CurrentCursor; Index2 < Count; Index++, Index2++) {
- TempString[Index] = StringPtr[Index2];
- }
- TempString[Index] = CHAR_NULL;
- }
- //
- // Effectively truncate string by 1 character
- //
- StrCpy (StringPtr, TempString);
- CurrentCursor --;
- }
-
- default:
- //
- // If it is the beginning of the string, don't worry about checking maximum limits
- //
- if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
- StrnCpy (StringPtr, &Key.UnicodeChar, 1);
- CurrentCursor++;
- } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
- KeyPad[0] = Key.UnicodeChar;
- KeyPad[1] = CHAR_NULL;
- Count = GetStringWidth (StringPtr) / 2 - 1;
- if (CurrentCursor < Count) {
- for (Index = 0; Index < CurrentCursor; Index++) {
- TempString[Index] = StringPtr[Index];
- }
- TempString[Index] = CHAR_NULL;
- StrCat (TempString, KeyPad);
- StrCat (TempString, StringPtr + CurrentCursor);
- StrCpy (StringPtr, TempString);
- } else {
- StrCat (StringPtr, KeyPad);
- }
- CurrentCursor++;
- }
-
- //
- // If the width of the input string is now larger than the screen, we nee to
- // adjust the index to start printing portions of the string
- //
- SetUnicodeMem (BufferedString, ScreenSize - 1, L' ');
- PrintStringAt (Start + 1, Top + 3, BufferedString);
-
- if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) {
- Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2;
- } else {
- Index = 0;
- }
-
- if (IsPassword) {
- gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3);
- }
-
- for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) {
- BufferedString[Count] = StringPtr[Index];
-
- if (IsPassword) {
- PrintChar (L'*');
- }
- }
-
- if (!IsPassword) {
- PrintStringAt (Start + 1, Top + 3, BufferedString);
- }
- break;
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- gST->ConOut->SetCursorPosition (gST->ConOut, Start + CurrentCursor + 1, Top + 3);
- } while (TRUE);
-
-}
-
-/**
- Adjust the value to the correct one. Rules follow the sample:
- like: Year change: 2012.02.29 -> 2013.02.29 -> 2013.02.01
- Month change: 2013.03.29 -> 2013.02.29 -> 2013.02.28
-
- @param Question Pointer to current question.
- @param Sequence The sequence of the field in the question.
-**/
-VOID
-AdjustQuestionValue (
- IN FORM_BROWSER_STATEMENT *Question,
- IN UINT8 Sequence
- )
-{
- UINT8 Month;
- UINT16 Year;
- UINT8 Maximum;
- UINT8 Minimum;
-
- if (Question->Operand != EFI_IFR_DATE_OP) {
- return;
- }
-
- Month = Question->HiiValue.Value.date.Month;
- Year = Question->HiiValue.Value.date.Year;
- Minimum = 1;
-
- switch (Month) {
- case 2:
- if ((Year % 4) == 0 && ((Year % 100) != 0 || (Year % 400) == 0)) {
- Maximum = 29;
- } else {
- Maximum = 28;
- }
- break;
- case 4:
- case 6:
- case 9:
- case 11:
- Maximum = 30;
- break;
- default:
- Maximum = 31;
- break;
- }
-
- //
- // Change the month area.
- //
- if (Sequence == 0) {
- if (Question->HiiValue.Value.date.Day > Maximum) {
- Question->HiiValue.Value.date.Day = Maximum;
- }
- }
-
- //
- // Change the Year area.
- //
- if (Sequence == 2) {
- if (Question->HiiValue.Value.date.Day > Maximum) {
- Question->HiiValue.Value.date.Day = Minimum;
- }
- }
-}
-
-/**
- This routine reads a numeric value from the user input.
-
- @param Selection Pointer to current selection.
- @param MenuOption Pointer to the current input menu.
-
- @retval EFI_SUCCESS If numerical input is read successfully
- @retval EFI_DEVICE_ERROR If operation fails
-
-**/
-EFI_STATUS
-GetNumericInput (
- IN UI_MENU_SELECTION *Selection,
- IN UI_MENU_OPTION *MenuOption
- )
-{
- EFI_STATUS Status;
- UINTN Column;
- UINTN Row;
- CHAR16 InputText[MAX_NUMERIC_INPUT_WIDTH];
- CHAR16 FormattedNumber[MAX_NUMERIC_INPUT_WIDTH - 1];
- UINT64 PreviousNumber[MAX_NUMERIC_INPUT_WIDTH - 3];
- UINTN Count;
- UINTN Loop;
- BOOLEAN ManualInput;
- BOOLEAN HexInput;
- BOOLEAN DateOrTime;
- UINTN InputWidth;
- UINT64 EditValue;
- UINT64 Step;
- UINT64 Minimum;
- UINT64 Maximum;
- UINTN EraseLen;
- UINT8 Digital;
- EFI_INPUT_KEY Key;
- EFI_HII_VALUE *QuestionValue;
- FORM_BROWSER_FORM *Form;
- FORM_BROWSER_FORMSET *FormSet;
- FORM_BROWSER_STATEMENT *Question;
-
- Column = MenuOption->OptCol;
- Row = MenuOption->Row;
- PreviousNumber[0] = 0;
- Count = 0;
- InputWidth = 0;
- Digital = 0;
-
- FormSet = Selection->FormSet;
- Form = Selection->Form;
- Question = MenuOption->ThisTag;
- QuestionValue = &Question->HiiValue;
- Step = Question->Step;
- Minimum = Question->Minimum;
- Maximum = Question->Maximum;
-
- //
- // Only two case, user can enter to this function: Enter and +/- case.
- // In Enter case, gDirection = 0; in +/- case, gDirection = SCAN_LEFT/SCAN_WRIGHT
- //
- ManualInput = (BOOLEAN)(gDirection == 0 ? TRUE : FALSE);
-
- if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) {
- DateOrTime = TRUE;
- } else {
- DateOrTime = FALSE;
- }
-
- //
- // Prepare Value to be edit
- //
- EraseLen = 0;
- EditValue = 0;
- if (Question->Operand == EFI_IFR_DATE_OP) {
- Step = 1;
- Minimum = 1;
-
- switch (MenuOption->Sequence) {
- case 0:
- Maximum = 12;
- EraseLen = 4;
- EditValue = QuestionValue->Value.date.Month;
- break;
-
- case 1:
- switch (QuestionValue->Value.date.Month) {
- case 2:
- if ((QuestionValue->Value.date.Year % 4) == 0 &&
- ((QuestionValue->Value.date.Year % 100) != 0 ||
- (QuestionValue->Value.date.Year % 400) == 0)) {
- Maximum = 29;
- } else {
- Maximum = 28;
- }
- break;
- case 4:
- case 6:
- case 9:
- case 11:
- Maximum = 30;
- break;
- default:
- Maximum = 31;
- break;
- }
-
- EraseLen = 3;
- EditValue = QuestionValue->Value.date.Day;
- break;
-
- case 2:
- Maximum = 0xffff;
- EraseLen = 5;
- EditValue = QuestionValue->Value.date.Year;
- break;
-
- default:
- break;
- }
- } else if (Question->Operand == EFI_IFR_TIME_OP) {
- Step = 1;
- Minimum = 0;
-
- switch (MenuOption->Sequence) {
- case 0:
- Maximum = 23;
- EraseLen = 4;
- EditValue = QuestionValue->Value.time.Hour;
- break;
-
- case 1:
- Maximum = 59;
- EraseLen = 3;
- EditValue = QuestionValue->Value.time.Minute;
- break;
-
- case 2:
- Maximum = 59;
- EraseLen = 3;
- EditValue = QuestionValue->Value.time.Second;
- break;
-
- default:
- break;
- }
- } else {
- //
- // Numeric
- //
- EraseLen = gOptionBlockWidth;
- EditValue = QuestionValue->Value.u64;
- if (Maximum == 0) {
- Maximum = (UINT64) -1;
- }
- }
-
- if ((Question->Operand == EFI_IFR_NUMERIC_OP) &&
- ((Question->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) {
- HexInput = TRUE;
- } else {
- HexInput = FALSE;
- }
-
- //
- // Enter from "Enter" input, clear the old word showing.
- //
- if (ManualInput) {
- if (Question->Operand == EFI_IFR_NUMERIC_OP) {
- if (HexInput) {
- InputWidth = Question->StorageWidth * 2;
- } else {
- switch (Question->StorageWidth) {
- case 1:
- InputWidth = 3;
- break;
-
- case 2:
- InputWidth = 5;
- break;
-
- case 4:
- InputWidth = 10;
- break;
-
- case 8:
- InputWidth = 20;
- break;
-
- default:
- InputWidth = 0;
- break;
- }
- }
-
- InputText[0] = LEFT_NUMERIC_DELIMITER;
- SetUnicodeMem (InputText + 1, InputWidth, L' ');
- ASSERT (InputWidth + 2 < MAX_NUMERIC_INPUT_WIDTH);
- InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;
- InputText[InputWidth + 2] = L'\0';
-
- PrintAt (Column, Row, InputText);
- Column++;
- }
-
- if (Question->Operand == EFI_IFR_DATE_OP) {
- if (MenuOption->Sequence == 2) {
- InputWidth = 4;
- } else {
- InputWidth = 2;
- }
-
- if (MenuOption->Sequence == 0) {
- InputText[0] = LEFT_NUMERIC_DELIMITER;
- SetUnicodeMem (InputText + 1, InputWidth, L' ');
- } else {
- SetUnicodeMem (InputText, InputWidth, L' ');
- }
-
- if (MenuOption->Sequence == 2) {
- InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;
- } else {
- InputText[InputWidth + 1] = DATE_SEPARATOR;
- }
- InputText[InputWidth + 2] = L'\0';
-
- PrintAt (Column, Row, InputText);
- if (MenuOption->Sequence == 0) {
- Column++;
- }
- }
-
- if (Question->Operand == EFI_IFR_TIME_OP) {
- InputWidth = 2;
-
- if (MenuOption->Sequence == 0) {
- InputText[0] = LEFT_NUMERIC_DELIMITER;
- SetUnicodeMem (InputText + 1, InputWidth, L' ');
- } else {
- SetUnicodeMem (InputText, InputWidth, L' ');
- }
-
- if (MenuOption->Sequence == 2) {
- InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER;
- } else {
- InputText[InputWidth + 1] = TIME_SEPARATOR;
- }
- InputText[InputWidth + 2] = L'\0';
-
- PrintAt (Column, Row, InputText);
- if (MenuOption->Sequence == 0) {
- Column++;
- }
- }
- }
-
- //
- // First time we enter this handler, we need to check to see if
- // we were passed an increment or decrement directive
- //
- do {
- Key.UnicodeChar = CHAR_NULL;
- if (gDirection != 0) {
- Key.ScanCode = gDirection;
- gDirection = 0;
- goto TheKey2;
- }
-
- Status = WaitForKeyStroke (&Key);
-
-TheKey2:
- switch (Key.UnicodeChar) {
-
- case '+':
- case '-':
- if (Key.UnicodeChar == '+') {
- Key.ScanCode = SCAN_RIGHT;
- } else {
- Key.ScanCode = SCAN_LEFT;
- }
- Key.UnicodeChar = CHAR_NULL;
- goto TheKey2;
-
- case CHAR_NULL:
- switch (Key.ScanCode) {
- case SCAN_LEFT:
- case SCAN_RIGHT:
- if (DateOrTime && !ManualInput) {
- //
- // By setting this value, we will return back to the caller.
- // We need to do this since an auto-refresh will destroy the adjustment
- // based on what the real-time-clock is showing. So we always commit
- // upon changing the value.
- //
- gDirection = SCAN_DOWN;
- }
-
- if ((Step != 0) && !ManualInput) {
- if (Key.ScanCode == SCAN_LEFT) {
- if (EditValue >= Minimum + Step) {
- EditValue = EditValue - Step;
- } else if (EditValue > Minimum){
- EditValue = Minimum;
- } else {
- EditValue = Maximum;
- }
- } else if (Key.ScanCode == SCAN_RIGHT) {
- if (EditValue + Step <= Maximum) {
- EditValue = EditValue + Step;
- } else if (EditValue < Maximum) {
- EditValue = Maximum;
- } else {
- EditValue = Minimum;
- }
- }
-
- ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
- if (Question->Operand == EFI_IFR_DATE_OP) {
- if (MenuOption->Sequence == 2) {
- //
- // Year
- //
- UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%04d", (UINT16) EditValue);
- } else {
- //
- // Month/Day
- //
- UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue);
- }
-
- if (MenuOption->Sequence == 0) {
- ASSERT (EraseLen >= 2);
- FormattedNumber[EraseLen - 2] = DATE_SEPARATOR;
- } else if (MenuOption->Sequence == 1) {
- ASSERT (EraseLen >= 1);
- FormattedNumber[EraseLen - 1] = DATE_SEPARATOR;
- }
- } else if (Question->Operand == EFI_IFR_TIME_OP) {
- UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue);
-
- if (MenuOption->Sequence == 0) {
- ASSERT (EraseLen >= 2);
- FormattedNumber[EraseLen - 2] = TIME_SEPARATOR;
- } else if (MenuOption->Sequence == 1) {
- ASSERT (EraseLen >= 1);
- FormattedNumber[EraseLen - 1] = TIME_SEPARATOR;
- }
- } else {
- QuestionValue->Value.u64 = EditValue;
- PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
- for (Loop = 0; Loop < EraseLen; Loop++) {
- PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, L" ");
- }
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor));
-
- if (MenuOption->Sequence == 0) {
- PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER);
- Column = MenuOption->OptCol + 1;
- }
-
- PrintStringAt (Column, Row, FormattedNumber);
-
- if (!DateOrTime || MenuOption->Sequence == 2) {
- PrintChar (RIGHT_NUMERIC_DELIMITER);
- }
- }
-
- goto EnterCarriageReturn;
- break;
-
- case SCAN_UP:
- case SCAN_DOWN:
- goto EnterCarriageReturn;
-
- case SCAN_ESC:
- return EFI_DEVICE_ERROR;
-
- default:
- break;
- }
-
- break;
-
-EnterCarriageReturn:
-
- case CHAR_CARRIAGE_RETURN:
- //
- // Validate input value with Minimum value.
- //
- if (EditValue < Minimum) {
- UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);
- break;
- } else {
- UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);
- }
-
- //
- // Store Edit value back to Question
- //
- if (Question->Operand == EFI_IFR_DATE_OP) {
- switch (MenuOption->Sequence) {
- case 0:
- QuestionValue->Value.date.Month = (UINT8) EditValue;
- break;
-
- case 1:
- QuestionValue->Value.date.Day = (UINT8) EditValue;
- break;
-
- case 2:
- QuestionValue->Value.date.Year = (UINT16) EditValue;
- break;
-
- default:
- break;
- }
- } else if (Question->Operand == EFI_IFR_TIME_OP) {
- switch (MenuOption->Sequence) {
- case 0:
- QuestionValue->Value.time.Hour = (UINT8) EditValue;
- break;
-
- case 1:
- QuestionValue->Value.time.Minute = (UINT8) EditValue;
- break;
-
- case 2:
- QuestionValue->Value.time.Second = (UINT8) EditValue;
- break;
-
- default:
- break;
- }
- } else {
- //
- // Numeric
- //
- QuestionValue->Value.u64 = EditValue;
- }
-
- //
- // Adjust the value to the correct one.
- // Sample like: 2012.02.29 -> 2013.02.29 -> 2013.02.01
- // 2013.03.29 -> 2013.02.29 -> 2013.02.28
- //
- if (Question->Operand == EFI_IFR_DATE_OP &&
- (MenuOption->Sequence == 0 || MenuOption->Sequence == 2)) {
- AdjustQuestionValue (Question, (UINT8)MenuOption->Sequence);
- }
-
- //
- // Check to see if the Value is something reasonable against consistency limitations.
- // If not, let's kick the error specified.
- //
- Status = ValidateQuestion (FormSet, Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
- if (EFI_ERROR (Status)) {
- //
- // Input value is not valid, restore Question Value
- //
- GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
- } else {
- SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
- if (!DateOrTime || (Question->Storage != NULL)) {
- //
- // NV flag is unnecessary for RTC type of Date/Time
- //
- UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
- }
- }
-
- return Status;
- break;
-
- case CHAR_BACKSPACE:
- if (ManualInput) {
- if (Count == 0) {
- break;
- }
- //
- // Remove a character
- //
- EditValue = PreviousNumber[Count - 1];
- UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);
- Count--;
- Column--;
- PrintAt (Column, Row, L" ");
- }
- break;
-
- default:
- if (ManualInput) {
- if (HexInput) {
- if ((Key.UnicodeChar >= L'0') && (Key.UnicodeChar <= L'9')) {
- Digital = (UINT8) (Key.UnicodeChar - L'0');
- } else if ((Key.UnicodeChar >= L'A') && (Key.UnicodeChar <= L'F')) {
- Digital = (UINT8) (Key.UnicodeChar - L'A' + 0x0A);
- } else if ((Key.UnicodeChar >= L'a') && (Key.UnicodeChar <= L'f')) {
- Digital = (UINT8) (Key.UnicodeChar - L'a' + 0x0A);
- } else {
- UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);
- break;
- }
- } else {
- if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') {
- UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);
- break;
- }
- }
-
- //
- // If Count exceed input width, there is no way more is valid
- //
- if (Count >= InputWidth) {
- break;
- }
- //
- // Someone typed something valid!
- //
- if (Count != 0) {
- if (HexInput) {
- EditValue = LShiftU64 (EditValue, 4) + Digital;
- } else {
- EditValue = MultU64x32 (EditValue, 10) + (Key.UnicodeChar - L'0');
- }
- } else {
- if (HexInput) {
- EditValue = Digital;
- } else {
- EditValue = Key.UnicodeChar - L'0';
- }
- }
-
- if (EditValue > Maximum) {
- UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, TRUE);
- ASSERT (Count < sizeof (PreviousNumber) / sizeof (PreviousNumber[0]));
- EditValue = PreviousNumber[Count];
- break;
- } else {
- UpdateStatusBar (Selection, INPUT_ERROR, Question->QuestionFlags, FALSE);
- }
-
- Count++;
- ASSERT (Count < (sizeof (PreviousNumber) / sizeof (PreviousNumber[0])));
- PreviousNumber[Count] = EditValue;
-
- PrintCharAt (Column, Row, Key.UnicodeChar);
- Column++;
- }
- break;
- }
- } while (TRUE);
-
-}
-
-
-/**
- Get selection for OneOf and OrderedList (Left/Right will be ignored).
-
- @param Selection Pointer to current selection.
- @param MenuOption Pointer to the current input menu.
-
- @retval EFI_SUCCESS If Option input is processed successfully
- @retval EFI_DEVICE_ERROR If operation fails
-
-**/
-EFI_STATUS
-GetSelectionInputPopUp (
- IN UI_MENU_SELECTION *Selection,
- IN UI_MENU_OPTION *MenuOption
- )
-{
- EFI_STATUS Status;
- EFI_INPUT_KEY Key;
- UINTN Index;
- CHAR16 *StringPtr;
- CHAR16 *TempStringPtr;
- UINTN Index2;
- UINTN TopOptionIndex;
- UINTN HighlightOptionIndex;
- UINTN Start;
- UINTN End;
- UINTN Top;
- UINTN Bottom;
- UINTN PopUpMenuLines;
- UINTN MenuLinesInView;
- UINTN PopUpWidth;
- CHAR16 Character;
- INT32 SavedAttribute;
- BOOLEAN ShowDownArrow;
- BOOLEAN ShowUpArrow;
- UINTN DimensionsWidth;
- LIST_ENTRY *Link;
- BOOLEAN OrderedList;
- UINT8 *ValueArray;
- UINT8 ValueType;
- EFI_HII_VALUE HiiValue;
- EFI_HII_VALUE *HiiValueArray;
- UINTN OptionCount;
- QUESTION_OPTION *OneOfOption;
- QUESTION_OPTION *CurrentOption;
- FORM_BROWSER_STATEMENT *Question;
- INTN Result;
-
- DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
-
- ValueArray = NULL;
- ValueType = 0;
- CurrentOption = NULL;
- ShowDownArrow = FALSE;
- ShowUpArrow = FALSE;
-
- StringPtr = AllocateZeroPool ((gOptionBlockWidth + 1) * 2);
- ASSERT (StringPtr);
-
- Question = MenuOption->ThisTag;
- if (Question->Operand == EFI_IFR_ORDERED_LIST_OP) {
- ValueArray = Question->BufferValue;
- ValueType = Question->ValueType;
- OrderedList = TRUE;
- } else {
- OrderedList = FALSE;
- }
-
- //
- // Calculate Option count
- //
- if (OrderedList) {
- for (Index = 0; Index < Question->MaxContainers; Index++) {
- if (GetArrayData (ValueArray, ValueType, Index) == 0) {
- break;
- }
- }
-
- OptionCount = Index;
- } else {
- OptionCount = 0;
- Link = GetFirstNode (&Question->OptionListHead);
- while (!IsNull (&Question->OptionListHead, Link)) {
- OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
-
- OptionCount++;
-
- Link = GetNextNode (&Question->OptionListHead, Link);
- }
- }
-
- //
- // Move valid Option to list head.
- //
- PopUpMenuLines = 0;
- if (OrderedList) {
- //
- // Prepare HiiValue array
- //
- HiiValueArray = AllocateZeroPool (OptionCount * sizeof (EFI_HII_VALUE));
- ASSERT (HiiValueArray != NULL);
- for (Index = 0; Index < OptionCount; Index++) {
- HiiValueArray[Index].Type = ValueType;
- HiiValueArray[Index].Value.u64 = GetArrayData (ValueArray, ValueType, Index);
- }
-
- for (Index = 0; Index < OptionCount; Index++) {
- OneOfOption = ValueToOption (Question, &HiiValueArray[OptionCount - Index - 1]);
- if (OneOfOption == NULL) {
- return EFI_NOT_FOUND;
- }
-
- RemoveEntryList (&OneOfOption->Link);
-
- //
- // Insert to head.
- //
- InsertHeadList (&Question->OptionListHead, &OneOfOption->Link);
-
- PopUpMenuLines++;
- }
-
- FreePool (HiiValueArray);
- } else {
- Link = GetFirstNode (&Question->OptionListHead);
- for (Index = 0; Index < OptionCount; Index++) {
- OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
- Link = GetNextNode (&Question->OptionListHead, Link);
- if ((OneOfOption->SuppressExpression != NULL) &&
- EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {
- continue;
- } else {
- PopUpMenuLines++;
- }
- }
- }
-
- //
- // Get the number of one of options present and its size
- //
- PopUpWidth = 0;
- HighlightOptionIndex = 0;
- Link = GetFirstNode (&Question->OptionListHead);
- for (Index = 0; Index < PopUpMenuLines; Index++) {
- OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
- Link = GetNextNode (&Question->OptionListHead, Link);
-
- if (!OrderedList && (OneOfOption->SuppressExpression != NULL) &&
- EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {
- Index--;
- continue;
- }
-
- StringPtr = GetToken (OneOfOption->Text, MenuOption->Handle);
- if (StrLen (StringPtr) > PopUpWidth) {
- PopUpWidth = StrLen (StringPtr);
- }
- FreePool (StringPtr);
-
- if (!OrderedList && (CompareHiiValue (&Question->HiiValue, &OneOfOption->Value, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
- //
- // Find current selected Option for OneOf
- //
- HighlightOptionIndex = Index;
- }
- }
-
- //
- // Perform popup menu initialization.
- //
- PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT;
-
- SavedAttribute = gST->ConOut->Mode->Attribute;
- gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
-
- if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) {
- PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH;
- }
-
- Start = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gScreenDimensions.LeftColumn;
- End = Start + PopUpWidth + POPUP_FRAME_WIDTH;
- Top = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT;
- Bottom = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight - 1;
-
- MenuLinesInView = Bottom - Top - 1;
- if (MenuLinesInView >= PopUpMenuLines) {
- Top = Top + (MenuLinesInView - PopUpMenuLines) / 2;
- Bottom = Top + PopUpMenuLines + 1;
- } else {
- ShowDownArrow = TRUE;
- }
-
- if (HighlightOptionIndex > (MenuLinesInView - 1)) {
- TopOptionIndex = HighlightOptionIndex - MenuLinesInView + 1;
- } else {
- TopOptionIndex = 0;
- }
-
- do {
- //
- // Clear that portion of the screen
- //
- ClearLines (Start, End, Top, Bottom, POPUP_TEXT | POPUP_BACKGROUND);
-
- //
- // Draw "One of" pop-up menu
- //
- Character = BOXDRAW_DOWN_RIGHT;
- PrintCharAt (Start, Top, Character);
- for (Index = Start; Index + 2 < End; Index++) {
- if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) {
- Character = GEOMETRICSHAPE_UP_TRIANGLE;
- } else {
- Character = BOXDRAW_HORIZONTAL;
- }
-
- PrintChar (Character);
- }
-
- Character = BOXDRAW_DOWN_LEFT;
- PrintChar (Character);
- Character = BOXDRAW_VERTICAL;
- for (Index = Top + 1; Index < Bottom; Index++) {
- PrintCharAt (Start, Index, Character);
- PrintCharAt (End - 1, Index, Character);
- }
-
- //
- // Move to top Option
- //
- Link = GetFirstNode (&Question->OptionListHead);
- for (Index = 0; Index < TopOptionIndex; Index++) {
- Link = GetNextNode (&Question->OptionListHead, Link);
-
- OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
- if (!OrderedList && (OneOfOption->SuppressExpression != NULL) &&
- EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {
- Index--;
- continue;
- }
- }
-
- //
- // Display the One of options
- //
- Index2 = Top + 1;
- for (Index = TopOptionIndex; (Index < PopUpMenuLines) && (Index2 < Bottom); Index++) {
- OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
- Link = GetNextNode (&Question->OptionListHead, Link);
-
- if (!OrderedList && (OneOfOption->SuppressExpression != NULL) &&
- EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) > ExpressFalse) {
- Index--;
- continue;
- }
-
- StringPtr = GetToken (OneOfOption->Text, MenuOption->Handle);
- ASSERT (StringPtr != NULL);
- //
- // If the string occupies multiple lines, truncate it to fit in one line,
- // and append a "..." for indication.
- //
- if (StrLen (StringPtr) > (PopUpWidth - 1)) {
- TempStringPtr = AllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1));
- ASSERT ( TempStringPtr != NULL );
- CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5)));
- FreePool (StringPtr);
- StringPtr = TempStringPtr;
- StrCat (StringPtr, L"...");
- }
-
- if (Index == HighlightOptionIndex) {
- //
- // Highlight the selected one
- //
- CurrentOption = OneOfOption;
-
- gST->ConOut->SetAttribute (gST->ConOut, PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND);
- PrintStringAt (Start + 2, Index2, StringPtr);
- gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
- PrintStringAt (Start + 2, Index2, StringPtr);
- }
-
- Index2++;
- FreePool (StringPtr);
- }
-
- Character = BOXDRAW_UP_RIGHT;
- PrintCharAt (Start, Bottom, Character);
- for (Index = Start; Index + 2 < End; Index++) {
- if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) {
- Character = GEOMETRICSHAPE_DOWN_TRIANGLE;
- } else {
- Character = BOXDRAW_HORIZONTAL;
- }
-
- PrintChar (Character);
- }
-
- Character = BOXDRAW_UP_LEFT;
- PrintChar (Character);
-
- //
- // Get User selection
- //
- Key.UnicodeChar = CHAR_NULL;
- if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) {
- Key.ScanCode = gDirection;
- gDirection = 0;
- goto TheKey;
- }
-
- Status = WaitForKeyStroke (&Key);
-
-TheKey:
- switch (Key.UnicodeChar) {
- case '+':
- if (OrderedList) {
- if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {
- //
- // Highlight reaches the top of the popup window, scroll one menu item.
- //
- TopOptionIndex--;
- ShowDownArrow = TRUE;
- }
-
- if (TopOptionIndex == 0) {
- ShowUpArrow = FALSE;
- }
-
- if (HighlightOptionIndex > 0) {
- HighlightOptionIndex--;
-
- ASSERT (CurrentOption != NULL);
- SwapListEntries (CurrentOption->Link.BackLink, &CurrentOption->Link);
- }
- }
- break;
-
- case '-':
- //
- // If an ordered list op-code, we will allow for a popup of +/- keys
- // to create an ordered list of items
- //
- if (OrderedList) {
- if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&
- (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) {
- //
- // Highlight reaches the bottom of the popup window, scroll one menu item.
- //
- TopOptionIndex++;
- ShowUpArrow = TRUE;
- }
-
- if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {
- ShowDownArrow = FALSE;
- }
-
- if (HighlightOptionIndex < (PopUpMenuLines - 1)) {
- HighlightOptionIndex++;
-
- ASSERT (CurrentOption != NULL);
- SwapListEntries (&CurrentOption->Link, CurrentOption->Link.ForwardLink);
- }
- }
- break;
-
- case CHAR_NULL:
- switch (Key.ScanCode) {
- case SCAN_UP:
- case SCAN_DOWN:
- if (Key.ScanCode == SCAN_UP) {
- if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) {
- //
- // Highlight reaches the top of the popup window, scroll one menu item.
- //
- TopOptionIndex--;
- ShowDownArrow = TRUE;
- }
-
- if (TopOptionIndex == 0) {
- ShowUpArrow = FALSE;
- }
-
- if (HighlightOptionIndex > 0) {
- HighlightOptionIndex--;
- }
- } else {
- if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) &&
- (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) {
- //
- // Highlight reaches the bottom of the popup window, scroll one menu item.
- //
- TopOptionIndex++;
- ShowUpArrow = TRUE;
- }
-
- if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) {
- ShowDownArrow = FALSE;
- }
-
- if (HighlightOptionIndex < (PopUpMenuLines - 1)) {
- HighlightOptionIndex++;
- }
- }
- break;
-
- case SCAN_ESC:
- gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
-
- //
- // Restore link list order for orderedlist
- //
- if (OrderedList) {
- HiiValue.Type = ValueType;
- HiiValue.Value.u64 = 0;
- for (Index = 0; Index < Question->MaxContainers; Index++) {
- HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
- if (HiiValue.Value.u64 == 0) {
- break;
- }
-
- OneOfOption = ValueToOption (Question, &HiiValue);
- if (OneOfOption == NULL) {
- return EFI_NOT_FOUND;
- }
-
- RemoveEntryList (&OneOfOption->Link);
- InsertTailList (&Question->OptionListHead, &OneOfOption->Link);
- }
- }
-
- return EFI_DEVICE_ERROR;
-
- default:
- break;
- }
-
- break;
-
- case CHAR_CARRIAGE_RETURN:
- //
- // return the current selection
- //
- if (OrderedList) {
- Index = 0;
- Link = GetFirstNode (&Question->OptionListHead);
- while (!IsNull (&Question->OptionListHead, Link)) {
- OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
- Link = GetNextNode (&Question->OptionListHead, Link);
-
- if ((OneOfOption->SuppressExpression != NULL) &&
- EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) != ExpressFalse) {
- continue;
- }
-
- SetArrayData (ValueArray, ValueType, Index, OneOfOption->Value.Value.u64);
-
- Index++;
- if (Index > Question->MaxContainers) {
- break;
- }
- }
- } else {
- ASSERT (CurrentOption != NULL);
- CopyMem (&Question->HiiValue, &CurrentOption->Value, sizeof (EFI_HII_VALUE));
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute);
-
- Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
- if (EFI_ERROR (Status)) {
- //
- // Input value is not valid, restore Question Value
- //
- GetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
- } else {
- SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
- UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
- }
-
- return Status;
-
- default:
- break;
- }
- } while (TRUE);
-
-}
-
-/**
- Wait for a key to be pressed by user.
-
- @param Key The key which is pressed by user.
-
- @retval EFI_SUCCESS The function always completed successfully.
-
-**/
-EFI_STATUS
-WaitForKeyStroke (
- OUT EFI_INPUT_KEY *Key
- )
-{
- EFI_STATUS Status;
-
- while (TRUE) {
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key);
- if (!EFI_ERROR (Status)) {
- break;
- }
-
- if (Status != EFI_NOT_READY) {
- continue;
- }
-
- UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0, 0);
- }
- return Status;
-}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
index 4cd71e5d44..def18fd9f9 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
@@ -19,863 +19,1658 @@ UI_MENU_SELECTION *gCurrentSelection;
EFI_HII_HANDLE mCurrentHiiHandle = NULL;
EFI_GUID mCurrentFormSetGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
UINT16 mCurrentFormId = 0;
+EFI_EVENT mValueChangedEvent = NULL;
+LIST_ENTRY mRefreshEventList = INITIALIZE_LIST_HEAD_VARIABLE (mRefreshEventList);
+UINT32 gBrowserStatus = BROWSER_SUCCESS;
+CHAR16 *gErrorInfo;
+UINT16 mCurFakeQestId;
+FORM_DISPLAY_ENGINE_FORM gDisplayFormData;
/**
- Clear retangle with specified text attribute.
+ 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 ||
+ Expression->Type == EFI_HII_EXPRESSION_WRITE ||
+ (Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) {
+ //
+ // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.
+ //
+ continue;
+ }
+
+ Status = EvaluateExpression (FormSet, Form, Expression);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Add empty function for event process function.
- @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.
+ @param Event The Event need to be process
+ @param Context The context of the event.
**/
VOID
-ClearLines (
- IN UINTN LeftColumn,
- IN UINTN RightColumn,
- IN UINTN TopRow,
- IN UINTN BottomRow,
- IN UINTN TextAttribute
+EFIAPI
+SetupBrowserEmptyFunction (
+ IN EFI_EVENT Event,
+ IN VOID *Context
)
{
- CHAR16 *Buffer;
- UINTN Row;
+}
- //
- // For now, allocate an arbitrarily long buffer
- //
- Buffer = AllocateZeroPool (0x10000);
- ASSERT (Buffer != NULL);
+/**
+ Base on the opcode buffer info to get the display statement.
- //
- // Set foreground and background as defined
- //
- gST->ConOut->SetAttribute (gST->ConOut, TextAttribute);
+ @param OpCode The input opcode buffer for this statement.
+
+ @retval Statement The statement use this opcode buffer.
+
+**/
+FORM_DISPLAY_ENGINE_STATEMENT *
+GetDisplayStatement (
+ IN EFI_IFR_OP_HEADER *OpCode
+ )
+{
+ FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement;
+ LIST_ENTRY *Link;
+
+ Link = GetFirstNode (&gDisplayFormData.StatementListHead);
+ while (!IsNull (&gDisplayFormData.StatementListHead, Link)) {
+ DisplayStatement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
+
+ if (DisplayStatement->OpCode == OpCode) {
+ return DisplayStatement;
+ }
+ Link = GetNextNode (&gDisplayFormData.StatementListHead, Link);
+ }
+
+ return NULL;
+}
+
+/**
+ Free the refresh event list.
+
+**/
+VOID
+FreeRefreshEvent (
+ VOID
+ )
+{
+ LIST_ENTRY *Link;
+ FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;
+
+ while (!IsListEmpty (&mRefreshEventList)) {
+ Link = GetFirstNode (&mRefreshEventList);
+ EventNode = FORM_BROWSER_REFRESH_EVENT_FROM_LINK (Link);
+ RemoveEntryList (&EventNode->Link);
+
+ gBS->CloseEvent (EventNode->RefreshEvent);
+
+ FreePool (EventNode);
+ }
+}
+
+/**
+ Check whether this statement value is changed. If yes, update the statement value and return TRUE;
+ else return FALSE.
+
+ @param Statement The statement need to check.
+
+**/
+VOID
+UpdateStatement (
+ IN OUT FORM_BROWSER_STATEMENT *Statement
+ )
+{
+ GetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);
//
- // Much faster to buffer the long string instead of print it a character at a time
+ // Reset FormPackage update flag
//
- SetUnicodeMem (Buffer, RightColumn - LeftColumn, L' ');
+ mHiiPackageListUpdated = FALSE;
//
- // Clear the desired area with the appropriate foreground/background
+ // Question value may be changed, need invoke its Callback()
//
- for (Row = TopRow; Row <= BottomRow; Row++) {
- PrintStringAt (LeftColumn, Row, Buffer);
+ ProcessCallBackFunction (gCurrentSelection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);
+
+ if (mHiiPackageListUpdated) {
+ //
+ // Package list is updated, force to reparse IFR binary of target Formset
+ //
+ mHiiPackageListUpdated = FALSE;
+ gCurrentSelection->Action = UI_ACTION_REFRESH_FORMSET;
}
+}
- gST->ConOut->SetCursorPosition (gST->ConOut, LeftColumn, TopRow);
+/**
+ Refresh the question which has refresh guid event attribute.
+
+ @param Event The event which has this function related.
+ @param Context The input context info related to this event or the status code return to the caller.
+**/
+VOID
+EFIAPI
+RefreshEventNotify(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ FORM_BROWSER_STATEMENT *Statement;
- FreePool (Buffer);
- return ;
+ Statement = (FORM_BROWSER_STATEMENT *)Context;
+ UpdateStatement(Statement);
+ gBS->SignalEvent (mValueChangedEvent);
}
+
/**
- Concatenate a narrow string to another string.
+ Create refresh hook event for statement which has refresh event or interval.
- @param Destination The destination string.
- @param Source The source string. The string to be concatenated.
- to the end of Destination.
+ @param Statement The statement need to check.
**/
VOID
-NewStrCat (
- IN OUT CHAR16 *Destination,
- IN CHAR16 *Source
+CreateRefreshEvent (
+ IN FORM_BROWSER_STATEMENT *Statement
)
{
- UINTN Length;
-
- for (Length = 0; Destination[Length] != 0; Length++)
- ;
+ EFI_STATUS Status;
+ EFI_EVENT RefreshEvent;
+ FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;
//
- // 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
+ // If question has refresh guid, create the notify function.
//
- Destination[Length] = NARROW_CHAR;
- Length++;
-
- StrCpy (Destination + Length, Source);
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ RefreshEventNotify,
+ Statement,
+ &Statement->RefreshGuid,
+ &RefreshEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));
+ ASSERT (EventNode != NULL);
+ EventNode->RefreshEvent = RefreshEvent;
+ InsertTailList(&mRefreshEventList, &EventNode->Link);
}
/**
- Count the storage space of a Unicode string.
+ Perform value check for a question.
+
+ @param Question The question need to do check.
+ @param ErrorInfo Return info about the error.
+
+ @retval The check result.
+**/
+UINT32
+InConsistentIfCheck (
+ IN FORM_BROWSER_STATEMENT *Question,
+ OUT STATEMENT_ERROR_INFO *ErrorInfo
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *Link;
+ FORM_EXPRESSION *Expression;
+ LIST_ENTRY *ListHead;
+ UINT32 RetVal;
- This function handles the Unicode string with NARROW_CHAR
- and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
- does not count in the resultant output. If a WIDE_CHAR is
- hit, then 2 Unicode character will consume an output storage
- space with size of CHAR16 till a NARROW_CHAR is hit.
+ RetVal = STATEMENT_VALID;
+ ListHead = &Question->InconsistentListHead;
- If String is NULL, then ASSERT ().
+ Link = GetFirstNode (ListHead);
+ while (!IsNull (ListHead, Link)) {
+ Expression = FORM_EXPRESSION_FROM_LINK (Link);
+ Link = GetNextNode (ListHead, Link);
- @param String The input string to be counted.
+ //
+ // Evaluate the expression
+ //
+ Status = EvaluateExpression (gCurrentSelection->FormSet, gCurrentSelection->Form, Expression);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ if ((Expression->Result.Type == EFI_IFR_TYPE_BOOLEAN) && Expression->Result.Value.b) {
+ ErrorInfo->StringId = Expression->Error;
+ ErrorInfo->TimeOut = 0;
+ RetVal = INCOSISTENT_IF_TRUE;
+ break;
+ }
+ }
- @return Storage space for the input string.
+ return RetVal;
+}
+/**
+ Perform value check for a question.
+
+ @param Form Form where Statement is in.
+ @param Statement Value will check for it.
+ @param InputValue New value will be checked.
+ @param ErrorInfo Return the error info for this check.
+
+ @retval TRUE Input Value is valid.
+ @retval FALSE Input Value is invalid.
**/
-UINTN
-GetStringWidth (
- IN CHAR16 *String
+UINT32
+EFIAPI
+QuestionCheck (
+ IN FORM_DISPLAY_ENGINE_FORM *Form,
+ IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
+ IN EFI_HII_VALUE *InputValue,
+ OUT STATEMENT_ERROR_INFO *ErrorInfo
)
{
- UINTN Index;
- UINTN Count;
- UINTN IncrementValue;
+ FORM_BROWSER_STATEMENT *Question;
+ EFI_HII_VALUE BackUpValue;
+ UINT8 *BackUpBuffer;
+ UINT32 RetVal;
+
+ BackUpBuffer = NULL;
+ RetVal = STATEMENT_VALID;
+
+ ASSERT (Form != NULL && Statement != NULL && InputValue != NULL && ErrorInfo != NULL);
+
+ Question = GetBrowserStatement(Statement);
+ ASSERT (Question != NULL);
+
+ //
+ // Back up the quesion value.
+ //
+ switch (Question->Operand) {
+ case EFI_IFR_ORDERED_LIST_OP:
+ BackUpBuffer = AllocateCopyPool (Question->StorageWidth, Question->BufferValue);
+ ASSERT (BackUpBuffer != NULL);
+ CopyMem (Question->BufferValue, InputValue->Buffer, Question->StorageWidth);
+ break;
- ASSERT (String != NULL);
- if (String == NULL) {
- return 0;
+ default:
+ CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));
+ CopyMem (&Question->HiiValue, InputValue, sizeof (EFI_HII_VALUE));
+ break;
}
- Index = 0;
- Count = 0;
- IncrementValue = 1;
+ //
+ // Do the inconsistentif check.
+ //
+ if (!IsListEmpty (&Question->InconsistentListHead)) {
+ RetVal = InConsistentIfCheck(Question, ErrorInfo);
+ }
- 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
- )
- ;
+ //
+ // Restore the quesion value.
+ //
+ switch (Question->Operand) {
+ case EFI_IFR_ORDERED_LIST_OP:
+ CopyMem (Question->BufferValue, BackUpBuffer, Question->StorageWidth);
+ break;
- //
- // We hit the null-terminator, we now have a count
- //
- if (String[Index] == 0) {
- break;
+ default:
+ CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));
+ break;
+ }
+
+ return RetVal;
+}
+
+/**
+
+ Initialize the Display statement structure data.
+
+ @param DisplayStatement Pointer to the display Statement data strucure.
+ @param Statement The statement need to check.
+ @param HostDisplayStatement Pointer to the display Statement data strucure which is an host statement.
+**/
+VOID
+InitializeDisplayStatement (
+ IN OUT FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement,
+ IN FORM_BROWSER_STATEMENT *Statement,
+ IN FORM_DISPLAY_ENGINE_STATEMENT *HostDisplayStatement
+ )
+{
+ LIST_ENTRY *Link;
+ QUESTION_OPTION *Option;
+ DISPLAY_QUESTION_OPTION *DisplayOption;
+
+ DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;
+ DisplayStatement->Version = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;
+ DisplayStatement->OpCode = Statement->OpCode;
+ InitializeListHead (&DisplayStatement->NestStatementList);
+ InitializeListHead (&DisplayStatement->OptionListHead);
+
+ if ((EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut) || Statement->Locked) {
+ DisplayStatement->Attribute |= HII_DISPLAY_GRAYOUT;
+ }
+ if ((Statement->ValueExpression != NULL) || ((Statement->QuestionFlags & EFI_IFR_FLAG_READ_ONLY) != 0)) {
+ DisplayStatement->Attribute |= HII_DISPLAY_READONLY;
+ }
+
+ //
+ // Initilize the option list in statement.
+ //
+ Link = GetFirstNode (&Statement->OptionListHead);
+ while (!IsNull (&Statement->OptionListHead, Link)) {
+ Option = QUESTION_OPTION_FROM_LINK (Link);
+ Link = GetNextNode (&Statement->OptionListHead, Link);
+ if ((Option->SuppressExpression != NULL) &&
+ ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {
+ continue;
}
+
+ DisplayOption = AllocateZeroPool (sizeof (DISPLAY_QUESTION_OPTION));
+ ASSERT (DisplayOption != NULL);
+
+ DisplayOption->ImageId = Option->ImageId;
+ DisplayOption->Signature = DISPLAY_QUESTION_OPTION_SIGNATURE;
+ DisplayOption->OptionOpCode = Option->OpCode;
+ InsertTailList(&DisplayStatement->OptionListHead, &DisplayOption->Link);
+ }
+
+ CopyMem (&DisplayStatement->CurrentValue, &Statement->HiiValue, sizeof (EFI_HII_VALUE));
+
+ //
+ // Some special op code need an extra buffer to save the data.
+ // Such as string, password, orderedlist...
+ //
+ if (Statement->BufferValue != NULL) {
//
- // 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)
+ // Ordered list opcode may not initilized, get default value here.
//
- if (String[Index] == NARROW_CHAR) {
- //
- // Skip to the next character
- //
- Index++;
- IncrementValue = 1;
- } else {
- //
- // Skip to the next character
- //
- Index++;
- IncrementValue = 2;
+ if (Statement->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP && GetArrayData (Statement->BufferValue, Statement->ValueType, 0) == 0) {
+ GetQuestionDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, 0);
}
- } while (String[Index] != 0);
+
+ DisplayStatement->CurrentValue.Buffer = AllocateCopyPool(Statement->StorageWidth,Statement->BufferValue);
+ DisplayStatement->CurrentValue.BufferLen = Statement->StorageWidth;
+ }
+
+ DisplayStatement->SettingChangedFlag = Statement->ValueChanged;
+
+ //
+ // Get the highlight statement for current form.
+ //
+ if (((gCurrentSelection->QuestionId != 0) && (Statement->QuestionId == gCurrentSelection->QuestionId)) ||
+ ((mCurFakeQestId != 0) && (Statement->FakeQuestionId == mCurFakeQestId))) {
+ gDisplayFormData.HighLightedStatement = DisplayStatement;
+ }
+
+ //
+ // Create the refresh event process function.
+ //
+ if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {
+ CreateRefreshEvent (Statement);
+ }
+
+ //
+ // For RTC type of date/time, set default refresh interval to be 1 second.
+ //
+ if ((Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) && Statement->Storage == NULL) {
+ Statement->RefreshInterval = 1;
+ }
+
+ //
+ // Create the refresh guid hook event.
+ // If the statement in this form has refresh event or refresh interval, browser will create this event for display engine.
+ //
+ if ((!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) || (Statement->RefreshInterval != 0)) {
+ gDisplayFormData.FormRefreshEvent = mValueChangedEvent;
+ }
//
- // Increment by one to include the null-terminator in the size
+ // Save the password check function for later use.
//
- Count++;
+ if (Statement->Operand == EFI_IFR_PASSWORD_OP) {
+ DisplayStatement->PasswordCheck = PasswordCheck;
+ }
+
+ //
+ // Save the validate check question for later use.
+ //
+ if (!IsListEmpty (&Statement->InconsistentListHead)) {
+ DisplayStatement->ValidateQuestion = QuestionCheck;
+ }
- return Count * sizeof (CHAR16);
+ //
+ // If this statement is nest in the subtitle, insert to the host statement.
+ // else insert to the form it belongs to.
+ //
+ if (Statement->InSubtitle) {
+ InsertTailList(&HostDisplayStatement->NestStatementList, &DisplayStatement->DisplayLink);
+ } else {
+ InsertTailList(&gDisplayFormData.StatementListHead, &DisplayStatement->DisplayLink);
+ }
}
/**
- This function displays the page frame.
+ Process for the refresh interval statement.
+
+ @param Event The Event need to be process
+ @param Context The context of the event.
- @param Selection Selection contains the information about
- the Selection, form and formset to be displayed.
- Selection action may be updated in retrieve callback.
**/
VOID
-DisplayPageFrame (
- IN UI_MENU_SELECTION *Selection
+EFIAPI
+RefreshIntervalProcess (
+ IN EFI_EVENT Event,
+ IN VOID *Context
)
{
- UINTN Index;
- UINT8 Line;
- UINT8 Alignment;
- CHAR16 Character;
- CHAR16 *Buffer;
- CHAR16 *StrFrontPageBanner;
- UINTN Row;
- EFI_SCREEN_DESCRIPTOR LocalScreen;
- UINT8 RowIdx;
- UINT8 ColumnIdx;
-
- 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);
-
- if (Selection->Form->ModalForm) {
- return;
+ FORM_BROWSER_STATEMENT *Statement;
+ LIST_ENTRY *Link;
+
+ Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);
+ while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
+ Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);
+
+ if (Statement->RefreshInterval == 0) {
+ continue;
+ }
+
+ UpdateStatement(Statement);
}
- CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
+ gBS->SignalEvent (mValueChangedEvent);
+}
+
+/**
+
+ Make a copy of the global hotkey info.
+
+**/
+VOID
+UpdateHotkeyList (
+ VOID
+ )
+{
+ BROWSER_HOT_KEY *HotKey;
+ BROWSER_HOT_KEY *CopyKey;
+ LIST_ENTRY *Link;
+
+ Link = GetFirstNode (&gBrowserHotKeyList);
+ while (!IsNull (&gBrowserHotKeyList, Link)) {
+ HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
+
+ CopyKey = AllocateCopyPool(sizeof (BROWSER_HOT_KEY), HotKey);
+ CopyKey->KeyData = AllocateCopyPool(sizeof (EFI_INPUT_KEY), HotKey->KeyData);
+ CopyKey->HelpString = AllocateCopyPool(StrSize (HotKey->HelpString), HotKey->HelpString);
+
+ InsertTailList(&gDisplayFormData.HotKeyListHead, &CopyKey->Link);
+
+ Link = GetNextNode (&gBrowserHotKeyList, Link);
+ }
+}
+
+/**
+
+ Enum all statement in current form, find all the statement can be display and
+ add to the display form.
+
+**/
+VOID
+AddStatementToDisplayForm (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ LIST_ENTRY *Link;
+ FORM_BROWSER_STATEMENT *Statement;
+ FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement;
+ FORM_DISPLAY_ENGINE_STATEMENT *HostDisplayStatement;
+ UINT8 MinRefreshInterval;
+ EFI_EVENT RefreshIntervalEvent;
+ FORM_BROWSER_REFRESH_EVENT_NODE *EventNode;
+ BOOLEAN FormEditable;
+
+ HostDisplayStatement = NULL;
+ MinRefreshInterval = 0;
+ FormEditable = FALSE;
//
- // For now, allocate an arbitrarily long buffer
+ // Process the statement outside the form, these statements are not recognized
+ // by browser core.
//
- Buffer = AllocateZeroPool (0x10000);
- ASSERT (Buffer != NULL);
+ Link = GetFirstNode (&gCurrentSelection->FormSet->StatementListOSF);
+ while (!IsNull (&gCurrentSelection->FormSet->StatementListOSF, Link)) {
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
+ Link = GetNextNode (&gCurrentSelection->FormSet->StatementListOSF, Link);
+
+ DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));
+ ASSERT (DisplayStatement != NULL);
+ DisplayStatement->Signature = FORM_DISPLAY_ENGINE_STATEMENT_SIGNATURE;
+ DisplayStatement->Version = FORM_DISPLAY_ENGINE_STATEMENT_VERSION_1;
+ DisplayStatement->OpCode = Statement->OpCode;
- Character = BOXDRAW_HORIZONTAL;
+ InitializeListHead (&DisplayStatement->NestStatementList);
+ InitializeListHead (&DisplayStatement->OptionListHead);
- for (Index = 0; Index + 2 < (LocalScreen.RightColumn - LocalScreen.LeftColumn); Index++) {
- Buffer[Index] = Character;
+ InsertTailList(&gDisplayFormData.StatementListOSF, &DisplayStatement->DisplayLink);
}
- if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {
+ //
+ // Process the statement in this form.
+ //
+ Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);
+ while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
+ Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);
+
//
- // ClearLines(0, LocalScreen.RightColumn, 0, BANNER_HEIGHT-1, BANNER_TEXT | BANNER_BACKGROUND);
+ // This statement can't be show, skip it.
//
- ClearLines (
- LocalScreen.LeftColumn,
- LocalScreen.RightColumn,
- LocalScreen.TopRow,
- FRONT_PAGE_HEADER_HEIGHT - 1 + LocalScreen.TopRow,
- BANNER_TEXT | BANNER_BACKGROUND
- );
+ if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) > ExpressGrayOut) {
+ continue;
+ }
+
+ DisplayStatement = AllocateZeroPool (sizeof (FORM_DISPLAY_ENGINE_STATEMENT));
+ ASSERT (DisplayStatement != NULL);
+
//
- // for (Line = 0; Line < BANNER_HEIGHT; Line++) {
+ // Initialize this statement and add it to the display form.
//
- 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++
- ) {
- RowIdx = (UINT8) (Line - (UINT8) LocalScreen.TopRow);
- ColumnIdx = (UINT8) (Alignment - (UINT8) LocalScreen.LeftColumn);
-
- ASSERT (RowIdx < BANNER_HEIGHT);
- ASSERT (ColumnIdx < BANNER_COLUMNS);
-
- if (gBannerData->Banner[RowIdx][ColumnIdx] != 0x0000) {
- StrFrontPageBanner = GetToken (
- gBannerData->Banner[RowIdx][ColumnIdx],
- gFrontPageHandle
- );
- } else {
- continue;
- }
+ InitializeDisplayStatement(DisplayStatement, Statement, HostDisplayStatement);
- switch (Alignment - LocalScreen.LeftColumn) {
- case 0:
- //
- // Handle left column
- //
- PrintStringAt (LocalScreen.LeftColumn + BANNER_LEFT_COLUMN_INDENT, Line, StrFrontPageBanner);
- break;
-
- case 1:
- //
- // Handle center column
- //
- PrintStringAt (
- LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3,
- Line,
- StrFrontPageBanner
- );
- break;
+ //
+ // Save the Host statement info.
+ // Host statement may has nest statement follow it.
+ //
+ if (!Statement->InSubtitle) {
+ HostDisplayStatement = DisplayStatement;
+ }
- case 2:
- //
- // Handle right column
- //
- PrintStringAt (
- LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 3,
- Line,
- StrFrontPageBanner
- );
- break;
- }
+ if (Statement->Storage != NULL) {
+ FormEditable = TRUE;
+ }
- FreePool (StrFrontPageBanner);
- }
+ //
+ // Get the minimal refresh interval value for later use.
+ //
+ if ((Statement->RefreshInterval != 0) &&
+ (MinRefreshInterval == 0 || Statement->RefreshInterval < MinRefreshInterval)) {
+ MinRefreshInterval = Statement->RefreshInterval;
}
}
- ClearLines (
- LocalScreen.LeftColumn,
- LocalScreen.RightColumn,
- LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight,
- LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,
- KEYHELP_TEXT | KEYHELP_BACKGROUND
- );
-
- if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {
- 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);
- }
+ //
+ // Create the periodic timer for refresh interval statement.
+ //
+ if (MinRefreshInterval != 0) {
+ Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, RefreshIntervalProcess, NULL, &RefreshIntervalEvent);
+ ASSERT_EFI_ERROR (Status);
+ Status = gBS->SetTimer (RefreshIntervalEvent, TimerPeriodic, MinRefreshInterval * ONE_SECOND);
+ ASSERT_EFI_ERROR (Status);
+
+ EventNode = AllocateZeroPool (sizeof (FORM_BROWSER_REFRESH_EVENT_NODE));
+ ASSERT (EventNode != NULL);
+ EventNode->RefreshEvent = RefreshIntervalEvent;
+ InsertTailList(&mRefreshEventList, &EventNode->Link);
+ }
- Character = BOXDRAW_UP_RIGHT;
- PrintCharAt (LocalScreen.LeftColumn, LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT - 1, Character);
- PrintString (Buffer);
+ //
+ // Update hotkey list field.
+ //
+ if (gBrowserSettingScope == SystemLevel || FormEditable) {
+ UpdateHotkeyList();
+ }
+}
- Character = BOXDRAW_UP_LEFT;
- PrintChar (Character);
+/**
- if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {
- //
- // Print Bottom border line
- // +------------------------------------------------------------------------------+
- // ? ?
- // +------------------------------------------------------------------------------+
- //
- Character = BOXDRAW_DOWN_RIGHT;
- PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight, Character);
-
- PrintString (Buffer);
-
- Character = BOXDRAW_DOWN_LEFT;
- PrintChar (Character);
- Character = BOXDRAW_VERTICAL;
- for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;
- Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;
- Row++
- ) {
- PrintCharAt (LocalScreen.LeftColumn, Row, Character);
- PrintCharAt (LocalScreen.RightColumn - 1, Row, Character);
- }
+ Initialize the SettingChangedFlag variable in the display form.
- Character = BOXDRAW_UP_RIGHT;
- PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1, Character);
+**/
+VOID
+UpdateDataChangedFlag (
+ VOID
+ )
+{
+ LIST_ENTRY *Link;
+ FORM_BROWSER_FORMSET *LocalFormSet;
- PrintString (Buffer);
+ gDisplayFormData.SettingChangedFlag = FALSE;
- Character = BOXDRAW_UP_LEFT;
- PrintChar (Character);
- }
+ if (IsNvUpdateRequiredForForm (gCurrentSelection->Form)) {
+ gDisplayFormData.SettingChangedFlag = TRUE;
+ return;
}
- FreePool (Buffer);
+ //
+ // Base on the system level to check whether need to show the NV flag.
+ //
+ switch (gBrowserSettingScope) {
+ case SystemLevel:
+ //
+ // Check the maintain list to see whether there is any change.
+ //
+ Link = GetFirstNode (&gBrowserFormSetList);
+ while (!IsNull (&gBrowserFormSetList, Link)) {
+ LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
+ if (IsNvUpdateRequiredForFormSet(LocalFormSet)) {
+ gDisplayFormData.SettingChangedFlag = TRUE;
+ return;
+ }
+ Link = GetNextNode (&gBrowserFormSetList, Link);
+ }
+ break;
+
+ case FormSetLevel:
+ if (IsNvUpdateRequiredForFormSet(gCurrentSelection->FormSet)) {
+ gDisplayFormData.SettingChangedFlag = TRUE;
+ return;
+ }
+ break;
+ default:
+ break;
+ }
}
-
/**
- Evaluate all expressions in a Form.
- @param FormSet FormSet this Form belongs to.
- @param Form The Form.
+ Initialize the Display form structure data.
- @retval EFI_SUCCESS The expression evaluated successfuly
+**/
+VOID
+InitializeDisplayFormData (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ gDisplayFormData.Signature = FORM_DISPLAY_ENGINE_FORM_SIGNATURE;
+ gDisplayFormData.Version = FORM_DISPLAY_ENGINE_VERSION_1;
+ gDisplayFormData.ImageId = 0;
+ gDisplayFormData.AnimationId = 0;
+
+ InitializeListHead (&gDisplayFormData.StatementListHead);
+ InitializeListHead (&gDisplayFormData.StatementListOSF);
+ InitializeListHead (&gDisplayFormData.HotKeyListHead);
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_CALLBACK,
+ SetupBrowserEmptyFunction,
+ NULL,
+ &mValueChangedEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+
+ Free the kotkey info saved in form data.
**/
-EFI_STATUS
-EvaluateFormExpressions (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN FORM_BROWSER_FORM *Form
+VOID
+FreeHotkeyList (
+ VOID
)
{
- EFI_STATUS Status;
+ BROWSER_HOT_KEY *HotKey;
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);
+ while (!IsListEmpty (&gDisplayFormData.HotKeyListHead)) {
+ Link = GetFirstNode (&gDisplayFormData.HotKeyListHead);
+ HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
- if (Expression->Type == EFI_HII_EXPRESSION_INCONSISTENT_IF ||
- Expression->Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF ||
- Expression->Type == EFI_HII_EXPRESSION_WRITE ||
- (Expression->Type == EFI_HII_EXPRESSION_READ && Form->FormType != STANDARD_MAP_FORM_TYPE)) {
- //
- // Postpone Form validation to Question editing or Form submitting or Question Write or Question Read for nonstandard form.
- //
- continue;
- }
+ RemoveEntryList (&HotKey->Link);
- Status = EvaluateExpression (FormSet, Form, Expression);
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ FreePool (HotKey->KeyData);
+ FreePool (HotKey->HelpString);
+ FreePool (HotKey);
}
+}
- return EFI_SUCCESS;
+/**
+
+ Update the Display form structure data.
+
+**/
+VOID
+UpdateDisplayFormData (
+ VOID
+ )
+{
+ gDisplayFormData.FormTitle = gCurrentSelection->Form->FormTitle;
+ gDisplayFormData.FormId = gCurrentSelection->FormId;
+ gDisplayFormData.HiiHandle = gCurrentSelection->Handle;
+ CopyGuid (&gDisplayFormData.FormSetGuid, &gCurrentSelection->FormSetGuid);
+
+ gDisplayFormData.Attribute = 0;
+ gDisplayFormData.Attribute |= gCurrentSelection->Form->ModalForm ? HII_DISPLAY_MODAL : 0;
+ gDisplayFormData.Attribute |= gCurrentSelection->Form->Locked ? HII_DISPLAY_LOCK : 0;
+
+ gDisplayFormData.FormRefreshEvent = NULL;
+ gDisplayFormData.HighLightedStatement = NULL;
+
+ gDisplayFormData.BrowserStatus = gBrowserStatus;
+ gDisplayFormData.ErrorString = gErrorInfo;
+
+ gBrowserStatus = BROWSER_SUCCESS;
+ gErrorInfo = NULL;
+
+ UpdateDataChangedFlag ();
+
+ AddStatementToDisplayForm ();
}
-/*
-+------------------------------------------------------------------------------+
-? Setup Page ?
-+------------------------------------------------------------------------------+
+/**
+ Free the Display Statement structure data.
+ @param StatementList Point to the statement list which need to be free.
+**/
+VOID
+FreeStatementData (
+ LIST_ENTRY *StatementList
+ )
+{
+ LIST_ENTRY *Link;
+ LIST_ENTRY *OptionLink;
+ FORM_DISPLAY_ENGINE_STATEMENT *Statement;
+ DISPLAY_QUESTION_OPTION *Option;
+ //
+ // Free Statements/Questions
+ //
+ while (!IsListEmpty (StatementList)) {
+ Link = GetFirstNode (StatementList);
+ Statement = FORM_DISPLAY_ENGINE_STATEMENT_FROM_LINK (Link);
+ //
+ // Free Options List
+ //
+ while (!IsListEmpty (&Statement->OptionListHead)) {
+ OptionLink = GetFirstNode (&Statement->OptionListHead);
+ Option = DISPLAY_QUESTION_OPTION_FROM_LINK (OptionLink);
+ RemoveEntryList (&Option->Link);
+ FreePool (Option);
+ }
+ //
+ // Free nest statement List
+ //
+ if (!IsListEmpty (&Statement->NestStatementList)) {
+ FreeStatementData(&Statement->NestStatementList);
+ }
+ RemoveEntryList (&Statement->DisplayLink);
+ FreePool (Statement);
+ }
+}
+/**
+ Free the Display form structure data.
+**/
+VOID
+FreeDisplayFormData (
+ VOID
+ )
+{
+ FreeStatementData (&gDisplayFormData.StatementListHead);
+ FreeStatementData (&gDisplayFormData.StatementListOSF);
+
+ FreeRefreshEvent();
+ FreeHotkeyList();
+}
+/**
+ Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
+ @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
+
+ @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
+
+**/
+FORM_BROWSER_STATEMENT *
+GetBrowserStatement (
+ IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement
+ )
+{
+ FORM_BROWSER_STATEMENT *Statement;
+ LIST_ENTRY *Link;
+
+ Link = GetFirstNode (&gCurrentSelection->Form->StatementListHead);
+ while (!IsNull (&gCurrentSelection->Form->StatementListHead, Link)) {
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
+ if (Statement->OpCode == DisplayStatement->OpCode) {
+ return Statement;
+ }
+ Link = GetNextNode (&gCurrentSelection->Form->StatementListHead, Link);
+ }
-+------------------------------------------------------------------------------+
-?F1=Scroll Help F9=Reset to Defaults F10=Save and Exit ?
-| ^"=Move Highlight <Spacebar> Toggles Checkbox Esc=Discard Changes |
-+------------------------------------------------------------------------------+
-*/
+ return NULL;
+}
/**
+ Process the action request in user input.
- Display form and wait for user to select one menu option, then return it.
+ @param Action The user input action request info.
+ @param DefaultId The user input default Id info.
- @param Selection On input, Selection tell setup browser the information
- about the Selection, form and formset to be displayed.
- On output, Selection return the screen item that is selected
- by user.
@retval EFI_SUCESSS This function always return successfully for now.
**/
-EFI_STATUS
-DisplayForm (
- IN OUT UI_MENU_SELECTION *Selection
+EFI_STATUS
+ProcessAction (
+ IN UINT32 Action,
+ IN UINT16 DefaultId
)
{
- CHAR16 *StringPtr;
- UINT16 MenuItemCount;
- EFI_HII_HANDLE Handle;
- EFI_SCREEN_DESCRIPTOR LocalScreen;
- UINT16 Width;
- UINTN ArrayEntry;
- CHAR16 *OutputString;
- LIST_ENTRY *Link;
- FORM_BROWSER_STATEMENT *Statement;
- UINT16 NumberOfLines;
- EFI_STATUS Status;
- UI_MENU_OPTION *MenuOption;
- UINT16 GlyphWidth;
+ EFI_STATUS Status;
+
+ //
+ // This is caused by use press ESC, and it should not combine with other action type.
+ //
+ if ((Action & BROWSER_ACTION_FORM_EXIT) == BROWSER_ACTION_FORM_EXIT) {
+ FindNextMenu (gCurrentSelection, FormLevel);
+ return EFI_SUCCESS;
+ }
- Handle = Selection->Handle;
- MenuItemCount = 0;
- ArrayEntry = 0;
- OutputString = NULL;
+ //
+ // Below is normal hotkey trigged action, these action maybe combine with each other.
+ //
+ if ((Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {
+ DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
+ }
- UiInitMenu ();
+ if ((Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
+ ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);
+ }
- CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
+ if ((Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {
+ Status = SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
+ if (EFI_ERROR (Status)) {
+ gBrowserStatus = BROWSER_SUBMIT_FAIL;
+ }
+ }
- StringPtr = GetToken (Selection->Form->FormTitle, Handle);
+ if ((Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {
+ gResetRequired = TRUE;
+ }
- if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {
- if (Selection->Form->ModalForm) {
- gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | EFI_BACKGROUND_BLACK);
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, TITLE_TEXT | TITLE_BACKGROUND);
+ if ((Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {
+ //
+ // Form Exit without saving, Similar to ESC Key.
+ // FormSet Exit without saving, Exit SendForm.
+ // System Exit without saving, CallExitHandler and Exit SendForm.
+ //
+ DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
+ if (gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) {
+ FindNextMenu (gCurrentSelection, gBrowserSettingScope);
+ } else if (gBrowserSettingScope == SystemLevel) {
+ if (ExitHandlerFunction != NULL) {
+ ExitHandlerFunction ();
+ }
+ gCurrentSelection->Action = UI_ACTION_EXIT;
}
- PrintStringAt (
- (LocalScreen.RightColumn + LocalScreen.LeftColumn - GetStringWidth (StringPtr) / 2) / 2,
- LocalScreen.TopRow + 1,
- StringPtr
- );
}
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Find HII Handle in the HII database associated with given Device Path.
+
+ If DevicePath is NULL, then ASSERT.
+
+ @param DevicePath Device Path associated with the HII package list
+ handle.
+
+ @retval Handle HII package list Handle associated with the Device
+ Path.
+ @retval NULL Hii Package list handle is not found.
+
+**/
+EFI_HII_HANDLE
+EFIAPI
+DevicePathToHiiHandle (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
+ UINTN BufferSize;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_HANDLE Handle;
+ EFI_HANDLE DriverHandle;
+ EFI_HII_HANDLE *HiiHandles;
+ EFI_HII_HANDLE HiiHandle;
+
+ ASSERT (DevicePath != NULL);
+
+ TmpDevicePath = DevicePath;
//
- // Remove Buffer allocated for StringPtr after it has been used.
+ // Locate Device Path Protocol handle buffer
//
- FreePool (StringPtr);
+ Status = gBS->LocateDevicePath (
+ &gEfiDevicePathProtocolGuid,
+ &TmpDevicePath,
+ &DriverHandle
+ );
+ if (EFI_ERROR (Status) || !IsDevicePathEnd (TmpDevicePath)) {
+ return NULL;
+ }
//
- // Evaluate all the Expressions in this Form
+ // Retrieve all HII Handles from HII database
//
- Status = EvaluateFormExpressions (Selection->FormSet, Selection->Form);
+ BufferSize = 0x1000;
+ HiiHandles = AllocatePool (BufferSize);
+ ASSERT (HiiHandles != NULL);
+ Status = mHiiDatabase->ListPackageLists (
+ mHiiDatabase,
+ EFI_HII_PACKAGE_TYPE_ALL,
+ NULL,
+ &BufferSize,
+ HiiHandles
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (HiiHandles);
+ HiiHandles = AllocatePool (BufferSize);
+ ASSERT (HiiHandles != NULL);
+
+ Status = mHiiDatabase->ListPackageLists (
+ mHiiDatabase,
+ EFI_HII_PACKAGE_TYPE_ALL,
+ NULL,
+ &BufferSize,
+ HiiHandles
+ );
+ }
+
if (EFI_ERROR (Status)) {
- return Status;
+ FreePool (HiiHandles);
+ return NULL;
}
- Selection->FormEditable = FALSE;
- Link = GetFirstNode (&Selection->Form->StatementListHead);
- while (!IsNull (&Selection->Form->StatementListHead, Link)) {
- Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
+ //
+ // Search Hii Handle by Driver Handle
+ //
+ HiiHandle = NULL;
+ HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = mHiiDatabase->GetPackageListHandle (
+ mHiiDatabase,
+ HiiHandles[Index],
+ &Handle
+ );
+ if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
+ HiiHandle = HiiHandles[Index];
+ break;
+ }
+ }
- if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) <= ExpressGrayOut) {
- StringPtr = GetToken (Statement->Prompt, Handle);
- ASSERT (StringPtr != NULL);
+ FreePool (HiiHandles);
+ return HiiHandle;
+}
- Width = GetWidth (Statement, Handle);
+/**
+ Find HII Handle in the HII database associated with given form set guid.
- NumberOfLines = 1;
- ArrayEntry = 0;
- GlyphWidth = 1;
- for (; GetLineByWidth (StringPtr, Width, &GlyphWidth,&ArrayEntry, &OutputString) != 0x0000;) {
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&StringPtr[ArrayEntry]) != 0) {
- NumberOfLines++;
- }
+ If FormSetGuid is NULL, then ASSERT.
- FreePool (OutputString);
- }
+ @param ComparingGuid FormSet Guid associated with the HII package list
+ handle.
- //
- // We are NOT!! removing this StringPtr buffer via FreePool since it is being used in the menuoptions, we will do
- // it in UiFreeMenu.
- //
- MenuOption = UiAddMenuOption (StringPtr, Selection->Handle, Selection->Form, Statement, NumberOfLines, MenuItemCount);
- MenuItemCount++;
+ @retval Handle HII package list Handle associated with the Device
+ Path.
+ @retval NULL Hii Package list handle is not found.
+
+**/
+EFI_HII_HANDLE
+FormSetGuidToHiiHandle (
+ EFI_GUID *ComparingGuid
+ )
+{
+ EFI_HII_HANDLE *HiiHandles;
+ UINTN Index;
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
+ UINTN BufferSize;
+ UINT32 Offset;
+ UINT32 Offset2;
+ UINT32 PackageListLength;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ UINT8 *Package;
+ UINT8 *OpCodeData;
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+
+ ASSERT (ComparingGuid != NULL);
+
+ HiiHandle = NULL;
+ //
+ // Get all the Hii handles
+ //
+ HiiHandles = HiiGetHiiHandles (NULL);
+ ASSERT (HiiHandles != NULL);
+
+ //
+ // Search for formset of each class type
+ //
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {
+ BufferSize = 0;
+ HiiPackageList = NULL;
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ HiiPackageList = AllocatePool (BufferSize);
+ ASSERT (HiiPackageList != NULL);
+
+ Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
+ }
+ if (EFI_ERROR (Status) || HiiPackageList == NULL) {
+ return NULL;
+ }
+
+ //
+ // Get Form package from this HII package List
+ //
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+ Offset2 = 0;
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
+
+ while (Offset < PackageListLength) {
+ Package = ((UINT8 *) HiiPackageList) + Offset;
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
- if (MenuOption->IsQuestion && !MenuOption->ReadOnly) {
+ if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
//
- // At least one item is not readonly, this Form is considered as editable
+ // Search FormSet in this Form Package
//
- Selection->FormEditable = TRUE;
+ Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
+ while (Offset2 < PackageHeader.Length) {
+ OpCodeData = Package + Offset2;
+
+ if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
+ //
+ // Try to compare against formset GUID
+ //
+ if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
+ HiiHandle = HiiHandles[Index];
+ break;
+ }
+ }
+
+ Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
+ }
+ }
+ if (HiiHandle != NULL) {
+ break;
}
+ Offset += PackageHeader.Length;
}
-
- Link = GetNextNode (&Selection->Form->StatementListHead, Link);
+
+ FreePool (HiiPackageList);
+ if (HiiHandle != NULL) {
+ break;
+ }
}
- Status = UiDisplayMenu (Selection);
-
- UiFreeMenu ();
+ FreePool (HiiHandles);
- return Status;
+ return HiiHandle;
}
/**
- Initialize the HII String Token to the correct values.
+ check how to process the changed data in current form or form set.
+
+ @param Selection On input, Selection tell setup browser the information
+ about the Selection, form and formset to be displayed.
+ On output, Selection return the screen item that is selected
+ by user.
+
+ @param Scope Data save or discard scope, form or formset.
+ @retval TRUE Success process the changed data, will return to the parent form.
+ @retval FALSE Reject to process the changed data, will stay at current form.
**/
-VOID
-InitializeBrowserStrings (
- VOID
+BOOLEAN
+ProcessChangedData (
+ IN OUT UI_MENU_SELECTION *Selection,
+ IN BROWSER_SETTING_SCOPE Scope
)
{
- gEnterString = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle);
- gEnterCommitString = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle);
- gEnterEscapeString = GetToken (STRING_TOKEN (ENTER_ESCAPE_STRING), gHiiHandle);
- gEscapeString = GetToken (STRING_TOKEN (ESCAPE_STRING), 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);
- gSaveChanges = GetToken (STRING_TOKEN (SAVE_CHANGES), gHiiHandle);
- gOptionMismatch = GetToken (STRING_TOKEN (OPTION_MISMATCH), gHiiHandle);
- gFormSuppress = GetToken (STRING_TOKEN (FORM_SUPPRESSED), gHiiHandle);
- gProtocolNotFound = GetToken (STRING_TOKEN (PROTOCOL_NOT_FOUND), gHiiHandle);
- return ;
+ BOOLEAN RetValue;
+
+ RetValue = TRUE;
+ switch (mFormDisplay->ConfirmDataChange()) {
+ case BROWSER_ACTION_DISCARD:
+ DiscardForm (Selection->FormSet, Selection->Form, Scope);
+ break;
+
+ case BROWSER_ACTION_SUBMIT:
+ SubmitForm (Selection->FormSet, Selection->Form, Scope);
+ break;
+
+ case BROWSER_ACTION_NONE:
+ RetValue = FALSE;
+ break;
+
+ default:
+ //
+ // if Invalid value return, process same as BROWSER_ACTION_NONE.
+ //
+ RetValue = FALSE;
+ break;
+ }
+
+ return RetValue;
}
/**
- Free up the resource allocated for all strings required
- by Setup Browser.
+ Find parent formset menu(the first menu which has different formset) for current menu.
+ If not find, just return to the first menu.
+
+ @param Selection The selection info.
**/
VOID
-FreeBrowserStrings (
- VOID
+FindParentFormSet (
+ IN OUT UI_MENU_SELECTION *Selection
)
{
- FreePool (gEnterString);
- FreePool (gEnterCommitString);
- FreePool (gEnterEscapeString);
- FreePool (gEscapeString);
- FreePool (gMoveHighlight);
- FreePool (gMakeSelection);
- FreePool (gDecNumericInput);
- FreePool (gHexNumericInput);
- FreePool (gToggleCheckBox);
- FreePool (gPromptForData);
- FreePool (gPromptForPassword);
- FreePool (gPromptForNewPassword);
- FreePool (gConfirmPassword);
- FreePool (gPassowordInvalid);
- FreePool (gConfirmError);
- FreePool (gPressEnter);
- FreePool (gEmptyString);
- FreePool (gAreYouSure);
- FreePool (gYesResponse);
- FreePool (gNoResponse);
- FreePool (gMiniString);
- FreePool (gPlusString);
- FreePool (gMinusString);
- FreePool (gAdjustNumber);
- FreePool (gSaveChanges);
- FreePool (gOptionMismatch);
- FreePool (gFormSuppress);
- FreePool (gProtocolNotFound);
- return ;
+ FORM_ENTRY_INFO *CurrentMenu;
+ FORM_ENTRY_INFO *ParentMenu;
+
+ CurrentMenu = Selection->CurrentMenu;
+ ParentMenu = UiFindParentMenu(CurrentMenu);
+
+ //
+ // Find a menu which has different formset guid with current.
+ //
+ while (ParentMenu != NULL && CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {
+ CurrentMenu = ParentMenu;
+ ParentMenu = UiFindParentMenu(CurrentMenu);
+ }
+
+ if (ParentMenu != NULL) {
+ CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));
+ Selection->Handle = ParentMenu->HiiHandle;
+ Selection->FormId = ParentMenu->FormId;
+ Selection->QuestionId = ParentMenu->QuestionId;
+ } else {
+ Selection->FormId = CurrentMenu->FormId;
+ Selection->QuestionId = CurrentMenu->QuestionId;
+ }
+
+ Selection->Statement = NULL;
}
/**
- Show all registered HotKey help strings on bottom Rows.
+ Process the goto op code, update the info in the selection structure.
+
+ @param Statement The statement belong to goto op code.
+ @param Selection The selection info.
+ @retval EFI_SUCCESS The menu process successfully.
+ @return Other value if the process failed.
**/
-VOID
-PrintHotKeyHelpString (
- VOID
+EFI_STATUS
+ProcessGotoOpCode (
+ IN OUT FORM_BROWSER_STATEMENT *Statement,
+ IN OUT UI_MENU_SELECTION *Selection
)
{
- UINTN CurrentCol;
- UINTN CurrentRow;
- UINTN BottomRowOfHotKeyHelp;
- UINTN ColumnWidth;
- UINTN Index;
- EFI_SCREEN_DESCRIPTOR LocalScreen;
- LIST_ENTRY *Link;
- BROWSER_HOT_KEY *HotKey;
+ CHAR16 *StringPtr;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ FORM_BROWSER_FORM *RefForm;
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+
+ Status = EFI_SUCCESS;
+ StringPtr = NULL;
+ HiiHandle = NULL;
- CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
- ColumnWidth = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
- BottomRowOfHotKeyHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3;
+ //
+ // Prepare the device path check, get the device path info first.
+ //
+ if (Statement->HiiValue.Value.ref.DevicePath != 0) {
+ StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);
+ }
//
- // Calculate total number of Register HotKeys.
+ // Check whether the device path string is a valid string.
//
- Index = 0;
- Link = GetFirstNode (&gBrowserHotKeyList);
- while (!IsNull (&gBrowserHotKeyList, Link)) {
- HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
- //
- // Help string can't exceed ColumnWidth. One Row will show three Help information.
- //
- if (StrLen (HotKey->HelpString) > ColumnWidth) {
- HotKey->HelpString[ColumnWidth] = L'\0';
+ if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL) {
+ if (Selection->Form->ModalForm) {
+ return Status;
}
+
//
- // Calculate help information Column and Row.
+ // Goto another Hii Package list
//
- if ((Index % 3) != 2) {
- CurrentCol = LocalScreen.LeftColumn + (2 - Index % 3) * ColumnWidth;
+ if (mPathFromText != NULL) {
+ DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);
+ if (DevicePath != NULL) {
+ HiiHandle = DevicePathToHiiHandle (DevicePath);
+ FreePool (DevicePath);
+ }
+ FreePool (StringPtr);
} else {
- CurrentCol = LocalScreen.LeftColumn + 2;
+ //
+ // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
+ //
+ gBrowserStatus = BROWSER_PROTOCOL_NOT_FOUND;
+ FreePool (StringPtr);
+ return Status;
+ }
+
+ if (HiiHandle != Selection->Handle) {
+ //
+ // Goto another Formset, check for uncommitted data
+ //
+ if ((gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) &&
+ IsNvUpdateRequiredForFormSet(Selection->FormSet)) {
+ if (!ProcessChangedData(Selection, FormSetLevel)) {
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;
+ Selection->Handle = HiiHandle;
+ if (Selection->Handle == NULL) {
+ //
+ // If target Hii Handle not found, exit current formset.
+ //
+ FindParentFormSet(Selection);
+ return EFI_SUCCESS;
+ }
+
+ CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
+ Selection->FormId = Statement->HiiValue.Value.ref.FormId;
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
+ } else if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {
+ if (Selection->Form->ModalForm) {
+ return Status;
+ }
+ if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &Selection->FormSetGuid)) {
+ //
+ // Goto another Formset, check for uncommitted data
+ //
+ if ((gBrowserSettingScope == FormLevel || gBrowserSettingScope == FormSetLevel) &&
+ IsNvUpdateRequiredForFormSet(Selection->FormSet)) {
+ if (!ProcessChangedData(Selection, FormSetLevel)) {
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;
+ Selection->Handle = FormSetGuidToHiiHandle(&Statement->HiiValue.Value.ref.FormSetGuid);
+ if (Selection->Handle == NULL) {
+ //
+ // If target Hii Handle not found, exit current formset.
+ //
+ FindParentFormSet(Selection);
+ return EFI_SUCCESS;
}
- CurrentRow = BottomRowOfHotKeyHelp - Index / 3;
- //
- // Print HotKey help string on bottom Row.
- //
- PrintStringAt (CurrentCol, CurrentRow, HotKey->HelpString);
+ CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
+ Selection->FormId = Statement->HiiValue.Value.ref.FormId;
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
+ } else if (Statement->HiiValue.Value.ref.FormId != 0) {
//
- // Get Next Hot Key.
+ // Goto another Form, check for uncommitted data
//
- Link = GetNextNode (&gBrowserHotKeyList, Link);
- Index ++;
+ if (Statement->HiiValue.Value.ref.FormId != Selection->FormId) {
+ if ((gBrowserSettingScope == FormLevel && IsNvUpdateRequiredForForm(Selection->Form))) {
+ if (!ProcessChangedData (Selection, FormLevel)) {
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);
+ if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {
+ if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {
+ //
+ // Form is suppressed.
+ //
+ gBrowserStatus = BROWSER_FORM_SUPPRESS;
+ return EFI_SUCCESS;
+ }
+ }
+
+ Selection->FormId = Statement->HiiValue.Value.ref.FormId;
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
+ } else if (Statement->HiiValue.Value.ref.QuestionId != 0) {
+ Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
}
-
- return;
+
+ return Status;
}
+
/**
- Update key's help imformation.
+ Process Question Config.
- @param Selection Tell setup browser the information about the Selection
- @param MenuOption The Menu option
- @param Selected Whether or not a tag be selected
+ @param Selection The UI menu selection.
+ @param Question The Question to be peocessed.
+
+ @retval EFI_SUCCESS Question Config process success.
+ @retval Other Question Config process fail.
**/
-VOID
-UpdateKeyHelp (
- IN UI_MENU_SELECTION *Selection,
- IN UI_MENU_OPTION *MenuOption,
- IN BOOLEAN Selected
+EFI_STATUS
+ProcessQuestionConfig (
+ IN UI_MENU_SELECTION *Selection,
+ IN FORM_BROWSER_STATEMENT *Question
)
{
- UINTN SecCol;
- UINTN ThdCol;
- UINTN LeftColumnOfHelp;
- UINTN RightColumnOfHelp;
- UINTN TopRowOfHelp;
- UINTN BottomRowOfHelp;
- UINTN StartColumnOfHelp;
- EFI_SCREEN_DESCRIPTOR LocalScreen;
- FORM_BROWSER_STATEMENT *Statement;
+ EFI_STATUS Status;
+ CHAR16 *ConfigResp;
+ CHAR16 *Progress;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
- gST->ConOut->SetAttribute (gST->ConOut, KEYHELP_TEXT | KEYHELP_BACKGROUND);
+ if (Question->QuestionConfig == 0) {
+ return EFI_SUCCESS;
+ }
- if (Selection->Form->ModalForm) {
- return;
+ //
+ // Get <ConfigResp>
+ //
+ ConfigResp = GetToken (Question->QuestionConfig, Selection->FormSet->HiiHandle);
+ if (ConfigResp == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Send config to Configuration Driver
+ //
+ ConfigAccess = Selection->FormSet->ConfigAccess;
+ if (ConfigAccess == NULL) {
+ return EFI_UNSUPPORTED;
}
+ Status = ConfigAccess->RouteConfig (
+ ConfigAccess,
+ ConfigResp,
+ &Progress
+ );
- CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
+ return Status;
+}
- SecCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
- ThdCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3 * 2;
+/**
- StartColumnOfHelp = LocalScreen.LeftColumn + 2;
- LeftColumnOfHelp = LocalScreen.LeftColumn + 1;
- RightColumnOfHelp = LocalScreen.RightColumn - 2;
- TopRowOfHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;
- BottomRowOfHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;
+ Process the user input data.
- 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);
+ @param UserInput The user input data.
+ @param ChangeHighlight Whether need to change the highlight statement.
+
+ @retval EFI_SUCESSS This function always return successfully for now.
+
+**/
+EFI_STATUS
+ProcessUserInput (
+ IN USER_INPUT *UserInput,
+ IN BOOLEAN ChangeHighlight
+ )
+{
+ EFI_STATUS Status;
+ FORM_BROWSER_STATEMENT *Statement;
- if (!Selected) {
+ Status = EFI_SUCCESS;
+
+ //
+ // When Exit from FormDisplay function, one of the below two cases must be true.
+ //
+ ASSERT (UserInput->Action != 0 || UserInput->SelectedStatement != NULL);
+
+ //
+ // Remove the last highligh question id, this id will update when show next form.
+ //
+ gCurrentSelection->QuestionId = 0;
+
+ //
+ // First process the Action field in USER_INPUT.
+ //
+ if (UserInput->Action != 0) {
+ Status = ProcessAction (UserInput->Action, UserInput->DefaultId);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Clear the highlight info.
+ //
+ gCurrentSelection->Statement = NULL;
+
+ if (UserInput->SelectedStatement != NULL) {
+ Statement = GetBrowserStatement(UserInput->SelectedStatement);
+ ASSERT (Statement != NULL);
+ //
+ // Save the current highlight menu in the menu history data.
+ // which will be used when later browse back to this form.
+ //
+ gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;
//
- // On system setting, HotKey will show on every form.
+ // For statement like text, actio, it not has question id.
+ // So use FakeQuestionId to save the question.
//
- if (gBrowserSettingScope == SystemLevel ||
- (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
- PrintHotKeyHelpString ();
+ if (gCurrentSelection->CurrentMenu->QuestionId == 0) {
+ mCurFakeQestId = Statement->FakeQuestionId;
+ } else {
+ mCurFakeQestId = 0;
}
+ }
+ } else {
+ Statement = GetBrowserStatement(UserInput->SelectedStatement);
+ ASSERT (Statement != NULL);
- if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {
- PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
- }
+ gCurrentSelection->Statement = Statement;
- if ((Statement->Operand == EFI_IFR_DATE_OP) ||
- (Statement->Operand == EFI_IFR_TIME_OP)) {
- PrintAt (
- StartColumnOfHelp,
- BottomRowOfHelp,
- L"%c%c%c%c%s",
- ARROW_UP,
- ARROW_DOWN,
- ARROW_RIGHT,
- ARROW_LEFT,
- gMoveHighlight
- );
- PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
- PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);
+ if (ChangeHighlight) {
+ //
+ // This question is the current user select one,record it and later
+ // show it as the highlight question.
+ //
+ gCurrentSelection->CurrentMenu->QuestionId = Statement->QuestionId;
+ //
+ // For statement like text, actio, it not has question id.
+ // So use FakeQuestionId to save the question.
+ //
+ if (gCurrentSelection->CurrentMenu->QuestionId == 0) {
+ mCurFakeQestId = Statement->FakeQuestionId;
} else {
- PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
- if (Statement->Operand == EFI_IFR_NUMERIC_OP && Statement->Step != 0) {
- PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gAdjustNumber);
- }
- PrintStringAt (SecCol, BottomRowOfHelp, gEnterString);
+ mCurFakeQestId = 0;
}
- } else {
- PrintStringAt (SecCol, BottomRowOfHelp, gEnterCommitString);
+ }
+ switch (Statement->Operand) {
+ case EFI_IFR_REF_OP:
+ Status = ProcessGotoOpCode(Statement, gCurrentSelection);
+ break;
+
+ case EFI_IFR_ACTION_OP:
//
- // If it is a selected numeric with manual input, display different message
+ // Process the Config string <ConfigResp>
//
- if ((Statement->Operand == EFI_IFR_NUMERIC_OP) ||
- (Statement->Operand == EFI_IFR_DATE_OP) ||
- (Statement->Operand == EFI_IFR_TIME_OP)) {
- PrintStringAt (
- SecCol,
- TopRowOfHelp,
- ((Statement->Flags & EFI_IFR_DISPLAY_UINT_HEX) == 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);
- }
+ Status = ProcessQuestionConfig (gCurrentSelection, Statement);
+ break;
+
+ case EFI_IFR_RESET_BUTTON_OP:
+ //
+ // Reset Question to default value specified by DefaultId
+ //
+ Status = ExtractDefault (gCurrentSelection->FormSet, NULL, Statement->DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE);
+ break;
- if (Statement->Operand == EFI_IFR_ORDERED_LIST_OP) {
- PrintStringAt (StartColumnOfHelp, TopRowOfHelp, gPlusString);
- PrintStringAt (ThdCol, TopRowOfHelp, gMinusString);
- }
+ default:
+ switch (Statement->Operand) {
+ case EFI_IFR_STRING_OP:
+ DeleteString(Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);
+ Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;
+ CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);
+ FreePool (UserInput->InputValue.Buffer);
+ break;
+
+ case EFI_IFR_PASSWORD_OP:
+ if (UserInput->InputValue.Buffer == NULL) {
+ //
+ // User not input new password, just return.
+ //
+ break;
+ }
- PrintStringAt (ThdCol, BottomRowOfHelp, gEnterEscapeString);
+ DeleteString(Statement->HiiValue.Value.string, gCurrentSelection->FormSet->HiiHandle);
+ Statement->HiiValue.Value.string = UserInput->InputValue.Value.string;
+ CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, (UINTN) UserInput->InputValue.BufferLen);
+ FreePool (UserInput->InputValue.Buffer);
+ //
+ // Two password match, send it to Configuration Driver
+ //
+ if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
+ PasswordCheck (NULL, UserInput->SelectedStatement, (CHAR16 *) Statement->BufferValue);
+ //
+ // Clean the value after saved it.
+ //
+ ZeroMem (Statement->BufferValue, (UINTN) UserInput->InputValue.BufferLen);
+ HiiSetString (gCurrentSelection->FormSet->HiiHandle, Statement->HiiValue.Value.string, (CHAR16*)Statement->BufferValue, NULL);
+ } else {
+ SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithHiiDriver);
+ }
+ break;
+
+ case EFI_IFR_ORDERED_LIST_OP:
+ CopyMem (Statement->BufferValue, UserInput->InputValue.Buffer, UserInput->InputValue.BufferLen);
+ break;
+
+ default:
+ CopyMem (&Statement->HiiValue, &UserInput->InputValue, sizeof (EFI_HII_VALUE));
+ break;
+ }
+ if (Statement->Operand != EFI_IFR_PASSWORD_OP) {
+ SetQuestionValue (gCurrentSelection->FormSet, gCurrentSelection->Form, Statement, GetSetValueWithEditBuffer);
+ }
+ break;
}
- break;
+ }
+
+ return Status;
+}
+
+/**
+
+ Display form and wait for user to select one menu option, then return it.
+
+ @retval EFI_SUCESSS This function always return successfully for now.
+
+**/
+EFI_STATUS
+DisplayForm (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ USER_INPUT UserInput;
+ FORM_ENTRY_INFO *CurrentMenu;
+ BOOLEAN ChangeHighlight;
- case EFI_IFR_CHECKBOX_OP:
- ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
+ ZeroMem (&UserInput, sizeof (USER_INPUT));
+ //
+ // Update the menu history data.
+ //
+ CurrentMenu = UiFindMenuList (gCurrentSelection->Handle, &gCurrentSelection->FormSetGuid, gCurrentSelection->FormId);
+ if (CurrentMenu == NULL) {
//
- // On system setting, HotKey will show on every form.
+ // Current menu not found, add it to the menu tree
//
- if (gBrowserSettingScope == SystemLevel ||
- (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
- PrintHotKeyHelpString ();
- }
- if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {
- PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
- }
-
- PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
- PrintStringAt (SecCol, BottomRowOfHelp, gToggleCheckBox);
- break;
+ CurrentMenu = UiAddMenuList (gCurrentSelection->Handle, &gCurrentSelection->FormSetGuid,
+ gCurrentSelection->FormId, gCurrentSelection->QuestionId);
+ ASSERT (CurrentMenu != NULL);
+ }
+ gCurrentSelection->CurrentMenu = CurrentMenu;
- 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:
- case EFI_IFR_SUBTITLE_OP:
- ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
+ //
+ // Find currrent highlight statement.
+ //
+ if (gCurrentSelection->QuestionId == 0) {
+ //
+ // Highlight not specified, fetch it from cached menu
+ //
+ gCurrentSelection->QuestionId = CurrentMenu->QuestionId;
+ }
- if (!Selected) {
- //
- // On system setting, HotKey will show on every form.
- //
- if (gBrowserSettingScope == SystemLevel ||
- (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
- PrintHotKeyHelpString ();
- }
- if ((gClassOfVfr & FORMSET_CLASS_PLATFORM_SETUP) == FORMSET_CLASS_PLATFORM_SETUP) {
- PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
- }
+ //
+ // Evaluate all the Expressions in this Form
+ //
+ Status = EvaluateFormExpressions (gCurrentSelection->FormSet, gCurrentSelection->Form);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- PrintAt (StartColumnOfHelp, BottomRowOfHelp, L"%c%c%s", ARROW_UP, ARROW_DOWN, gMoveHighlight);
- if (Statement->Operand != EFI_IFR_TEXT_OP && Statement->Operand != EFI_IFR_SUBTITLE_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, gEnterEscapeString);
- }
- }
- break;
+ UpdateDisplayFormData ();
- default:
- break;
+ //
+ // Three possible status maybe return.
+ //
+ // EFI_INVALID_PARAMETER: The input dimension info is not valid.
+ // EFI_NOT_FOUND: The input value for oneof/orderedlist opcode is not valid
+ // and an valid value has return.
+ // EFI_SUCCESS: Success shows form and get user input in UserInput paramenter.
+ //
+ Status = mFormDisplay->FormDisplay (&gDisplayFormData, &UserInput);
+ if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {
+ FreeDisplayFormData();
+ return Status;
}
+
+ //
+ // If status is EFI_SUCCESS, means user has change the highlight menu and new user input return.
+ // in this case, browser need to change the highlight menu.
+ // If status is EFI_NOT_FOUND, means the input DisplayFormData has error for oneof/orderedlist
+ // opcode and new valid value has return, browser core need to adjust
+ // value for this opcode and shows this form again.
+ //
+ ChangeHighlight = (Status == EFI_SUCCESS ? TRUE :FALSE);
+
+ Status = ProcessUserInput (&UserInput, ChangeHighlight);
+
+ FreeDisplayFormData();
+
+ return Status;
}
/**
@@ -920,60 +1715,136 @@ FormUpdateNotify (
}
/**
- check whether the formset need to update the NV.
+ Update the NV flag info for this form set.
@param FormSet FormSet data structure.
- @retval TRUE Need to update the NV.
- @retval FALSE No need to update the NV.
**/
-BOOLEAN
-IsNvUpdateRequired (
+BOOLEAN
+IsNvUpdateRequiredForFormSet (
IN FORM_BROWSER_FORMSET *FormSet
)
{
LIST_ENTRY *Link;
FORM_BROWSER_FORM *Form;
+ BOOLEAN RetVal;
+
+ //
+ // Not finished question initialization, return FALSE.
+ //
+ if (!FormSet->QuestionInited) {
+ return FALSE;
+ }
+
+ RetVal = FALSE;
Link = GetFirstNode (&FormSet->FormListHead);
while (!IsNull (&FormSet->FormListHead, Link)) {
Form = FORM_BROWSER_FORM_FROM_LINK (Link);
- if (Form->NvUpdateRequired ) {
- return TRUE;
+ RetVal = IsNvUpdateRequiredForForm(Form);
+ if (RetVal) {
+ break;
}
Link = GetNextNode (&FormSet->FormListHead, Link);
}
+ return RetVal;
+}
+
+/**
+ Update the NvUpdateRequired flag for a form.
+
+ @param Form Form data structure.
+
+**/
+BOOLEAN
+IsNvUpdateRequiredForForm (
+ IN FORM_BROWSER_FORM *Form
+ )
+{
+ LIST_ENTRY *Link;
+ FORM_BROWSER_STATEMENT *Statement;
+
+ Link = GetFirstNode (&Form->StatementListHead);
+ while (!IsNull (&Form->StatementListHead, Link)) {
+ Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
+
+ if (Statement->ValueChanged) {
+ return TRUE;
+ }
+
+ Link = GetNextNode (&Form->StatementListHead, Link);
+ }
+
return FALSE;
}
/**
- check whether the formset need to update the NV.
+ Check whether the storage data for current form set is changed.
- @param FormSet FormSet data structure.
- @param SetValue Whether set new value or clear old value.
+ @param FormSet FormSet data structure.
+ @retval TRUE Data is changed.
+ @retval FALSE Data is not changed.
**/
-VOID
-UpdateNvInfoInForm (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN BOOLEAN SetValue
+BOOLEAN
+IsStorageDataChangedForFormSet (
+ IN FORM_BROWSER_FORMSET *FormSet
)
{
LIST_ENTRY *Link;
- FORM_BROWSER_FORM *Form;
-
- Link = GetFirstNode (&FormSet->FormListHead);
- while (!IsNull (&FormSet->FormListHead, Link)) {
- Form = FORM_BROWSER_FORM_FROM_LINK (Link);
+ FORMSET_STORAGE *Storage;
+ BROWSER_STORAGE *BrowserStorage;
+ CHAR16 *ConfigRespNew;
+ CHAR16 *ConfigRespOld;
+ BOOLEAN RetVal;
- Form->NvUpdateRequired = SetValue;
+ RetVal = FALSE;
+ ConfigRespNew = NULL;
+ ConfigRespOld = NULL;
- Link = GetNextNode (&FormSet->FormListHead, Link);
+ //
+ // Request current settings from Configuration Driver
+ //
+ Link = GetFirstNode (&FormSet->StorageListHead);
+ while (!IsNull (&FormSet->StorageListHead, Link)) {
+ Storage = FORMSET_STORAGE_FROM_LINK (Link);
+ Link = GetNextNode (&FormSet->StorageListHead, Link);
+
+ BrowserStorage = Storage->BrowserStorage;
+
+ if (BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
+ continue;
+ }
+
+ if (Storage->ElementCount == 0) {
+ continue;
+ }
+
+ StorageToConfigResp (BrowserStorage, &ConfigRespNew, Storage->ConfigRequest, TRUE);
+ StorageToConfigResp (BrowserStorage, &ConfigRespOld, Storage->ConfigRequest, FALSE);
+ ASSERT (ConfigRespNew != NULL && ConfigRespOld != NULL);
+
+ if (StrCmp (ConfigRespNew, ConfigRespOld) != 0) {
+ RetVal = TRUE;
+ }
+
+ FreePool (ConfigRespNew);
+ ConfigRespNew = NULL;
+
+ FreePool (ConfigRespOld);
+ ConfigRespOld = NULL;
+
+ if (RetVal) {
+ break;
+ }
}
+
+ return RetVal;
}
+
/**
Find menu which will show next time.
@@ -981,170 +1852,92 @@ UpdateNvInfoInForm (
about the Selection, form and formset to be displayed.
On output, Selection return the screen item that is selected
by user.
- @param Repaint Whether need to repaint the menu.
- @param NewLine Whether need to show at new line.
+ @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.
+ else, we need to exit current formset.
- @retval TRUE Need return.
- @retval FALSE No need to return.
+ @retval TRUE Exit current form.
+ @retval FALSE User press ESC and keep in current form.
**/
BOOLEAN
FindNextMenu (
- IN OUT UI_MENU_SELECTION *Selection,
- IN BOOLEAN *Repaint,
- IN BOOLEAN *NewLine
+ IN OUT UI_MENU_SELECTION *Selection,
+ IN BROWSER_SETTING_SCOPE SettingLevel
)
{
- UI_MENU_LIST *CurrentMenu;
- CHAR16 YesResponse;
- CHAR16 NoResponse;
- EFI_INPUT_KEY Key;
- BROWSER_SETTING_SCOPE Scope;
+ FORM_ENTRY_INFO *CurrentMenu;
+ FORM_ENTRY_INFO *ParentMenu;
+ BROWSER_SETTING_SCOPE Scope;
CurrentMenu = Selection->CurrentMenu;
+ ParentMenu = NULL;
+ Scope = FormSetLevel;
- if (CurrentMenu != NULL && CurrentMenu->Parent != NULL) {
+ if (CurrentMenu != NULL && (ParentMenu = UiFindParentMenu(CurrentMenu)) != NULL) {
//
// we have a parent, so go to the parent menu
//
- if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) {
- //
- // The parent menu and current menu are in the same formset
- //
- Selection->Action = UI_ACTION_REFRESH_FORM;
- Scope = FormLevel;
- } else {
- Selection->Action = UI_ACTION_REFRESH_FORMSET;
- CopyMem (&Selection->FormSetGuid, &CurrentMenu->Parent->FormSetGuid, sizeof (EFI_GUID));
- Selection->Handle = CurrentMenu->Parent->HiiHandle;
- Scope = FormSetLevel;
- }
-
- //
- // Form Level Check whether the data is changed.
- //
- if ((gBrowserSettingScope == FormLevel && Selection->Form->NvUpdateRequired) ||
- (gBrowserSettingScope == FormSetLevel && IsNvUpdateRequired(Selection->FormSet) && Scope == FormSetLevel)) {
- gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
-
- YesResponse = gYesResponse[0];
- NoResponse = gNoResponse[0];
-
- //
- // If NV flag is up, prompt user
- //
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString);
- } while
- (
- (Key.ScanCode != SCAN_ESC) &&
- ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&
- ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))
- );
-
- if (Key.ScanCode == SCAN_ESC) {
+ if (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {
+ if (SettingLevel == FormSetLevel) {
//
- // User hits the ESC key, Ingore.
+ // Find a menu which has different formset guid with current.
//
- if (Repaint != NULL) {
- *Repaint = TRUE;
- }
- if (NewLine != NULL) {
- *NewLine = TRUE;
+ while (CompareGuid (&CurrentMenu->FormSetGuid, &ParentMenu->FormSetGuid)) {
+ CurrentMenu = ParentMenu;
+ if ((ParentMenu = UiFindParentMenu(CurrentMenu)) == NULL) {
+ break;
+ }
}
- Selection->Action = UI_ACTION_NONE;
- return FALSE;
- }
-
- if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {
- //
- // If the user hits the YesResponse key
- //
- SubmitForm (Selection->FormSet, Selection->Form, Scope);
+ if (ParentMenu != NULL) {
+ Scope = FormSetLevel;
+ }
} else {
- //
- // If the user hits the NoResponse key
- //
- DiscardForm (Selection->FormSet, Selection->Form, Scope);
+ Scope = FormLevel;
}
+ } else {
+ Scope = FormSetLevel;
}
-
- Selection->Statement = NULL;
-
- Selection->FormId = CurrentMenu->Parent->FormId;
- Selection->QuestionId = CurrentMenu->Parent->QuestionId;
-
- //
- // Clear highlight record for this menu
- //
- CurrentMenu->QuestionId = 0;
- return FALSE;
- }
-
- if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {
- //
- // We never exit FrontPage, so skip the ESC
- //
- Selection->Action = UI_ACTION_NONE;
- return FALSE;
}
//
- // We are going to leave current FormSet, so check uncommited data in this FormSet
+ // Form Level Check whether the data is changed.
//
- if (gBrowserSettingScope != SystemLevel && IsNvUpdateRequired(Selection->FormSet)) {
- gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
-
- YesResponse = gYesResponse[0];
- NoResponse = gNoResponse[0];
-
- //
- // If NV flag is up, prompt user
- //
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gSaveChanges, gAreYouSure, gEmptyString);
- } while
- (
- (Key.ScanCode != SCAN_ESC) &&
- ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse | UPPER_LOWER_CASE_OFFSET)) &&
- ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse | UPPER_LOWER_CASE_OFFSET))
- );
-
- if (Key.ScanCode == SCAN_ESC) {
- //
- // User hits the ESC key
- //
- if (Repaint != NULL) {
- *Repaint = TRUE;
- }
-
- if (NewLine != NULL) {
- *NewLine = TRUE;
- }
-
- Selection->Action = UI_ACTION_NONE;
+ if ((gBrowserSettingScope == FormLevel && IsNvUpdateRequiredForForm (Selection->Form)) ||
+ (gBrowserSettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet(Selection->FormSet) && Scope == FormSetLevel)) {
+ if (!ProcessChangedData(Selection, Scope)) {
return FALSE;
}
+ }
- if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {
- //
- // If the user hits the YesResponse key
- //
- SubmitForm (Selection->FormSet, Selection->Form, FormSetLevel);
+ if (ParentMenu != NULL) {
+ //
+ // ParentMenu is found. Then, go to it.
+ //
+ if (Scope == FormLevel) {
+ Selection->Action = UI_ACTION_REFRESH_FORM;
} else {
- //
- // If the user hits the NoResponse key
- //
- DiscardForm (Selection->FormSet, Selection->Form, FormSetLevel);
+ Selection->Action = UI_ACTION_REFRESH_FORMSET;
+ CopyMem (&Selection->FormSetGuid, &ParentMenu->FormSetGuid, sizeof (EFI_GUID));
+ Selection->Handle = ParentMenu->HiiHandle;
}
- }
- Selection->Statement = NULL;
- if (CurrentMenu != NULL) {
+ Selection->Statement = NULL;
+
+ Selection->FormId = ParentMenu->FormId;
+ Selection->QuestionId = ParentMenu->QuestionId;
+
+ //
+ // Clear highlight record for this menu
+ //
CurrentMenu->QuestionId = 0;
+ return FALSE;
}
+ //
+ // Current in root page, exit the SendForm
+ //
Selection->Action = UI_ACTION_EXIT;
+
return TRUE;
}
@@ -1246,17 +2039,17 @@ ProcessCallBackFunction (
case EFI_BROWSER_ACTION_REQUEST_RESET:
DiscardFormIsRequired = TRUE;
gResetRequired = TRUE;
- Selection->Action = UI_ACTION_EXIT;
+ NeedExit = TRUE;
break;
case EFI_BROWSER_ACTION_REQUEST_SUBMIT:
SubmitFormIsRequired = TRUE;
- Selection->Action = UI_ACTION_EXIT;
+ NeedExit = TRUE;
break;
case EFI_BROWSER_ACTION_REQUEST_EXIT:
DiscardFormIsRequired = TRUE;
- Selection->Action = UI_ACTION_EXIT;
+ NeedExit = TRUE;
break;
case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT:
@@ -1267,7 +2060,7 @@ ProcessCallBackFunction (
case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT:
DiscardFormIsRequired = TRUE;
- SettingLevel = FormLevel;
+ SettingLevel = FormLevel;
NeedExit = TRUE;
break;
@@ -1320,7 +2113,7 @@ ProcessCallBackFunction (
}
if (NeedExit) {
- FindNextMenu (Selection, NULL, NULL);
+ FindNextMenu (Selection, SettingLevel);
}
return Status;
@@ -1400,9 +2193,7 @@ SetupBrowser (
EFI_HANDLE NotifyHandle;
FORM_BROWSER_STATEMENT *Statement;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
- EFI_INPUT_KEY Key;
- gMenuRefreshHead = NULL;
ConfigAccess = Selection->FormSet->ConfigAccess;
//
@@ -1423,21 +2214,17 @@ SetupBrowser (
//
// Initialize current settings of Questions in this FormSet
//
- Status = InitializeCurrentSetting (Selection->FormSet);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
+ InitializeCurrentSetting (Selection->FormSet);
//
- // Update gOldFormSet on maintain back up FormSet list.
- // And, make gOldFormSet point to current FormSet.
+ // Initilize Action field.
//
- if (gOldFormSet != NULL) {
- RemoveEntryList (&gOldFormSet->Link);
- DestroyFormSet (gOldFormSet);
- }
- gOldFormSet = Selection->FormSet;
- InsertTailList (&gBrowserFormSetList, &gOldFormSet->Link);
+ Selection->Action = UI_ACTION_REFRESH_FORM;
+
+ //
+ // Clean the mCurFakeQestId value is formset refreshed.
+ //
+ mCurFakeQestId = 0;
do {
//
@@ -1480,10 +2267,7 @@ SetupBrowser (
//
// Form is suppressed.
//
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-
+ gBrowserStatus = BROWSER_FORM_SUPPRESS;
Status = EFI_NOT_FOUND;
goto Done;
}
@@ -1498,7 +2282,6 @@ SetupBrowser (
((Selection->Handle != mCurrentHiiHandle) ||
(!CompareGuid (&Selection->FormSetGuid, &mCurrentFormSetGuid)) ||
(Selection->FormId != mCurrentFormId))) {
-
//
// Keep current form information
//
@@ -1512,12 +2295,6 @@ SetupBrowser (
}
//
- // EXIT requests to close form.
- //
- if (Selection->Action == UI_ACTION_EXIT) {
- goto Done;
- }
- //
// IFR is updated during callback of open form, force to reparse the IFR binary
//
if (mHiiPackageListUpdated) {
@@ -1536,12 +2313,6 @@ SetupBrowser (
}
//
- // EXIT requests to close form.
- //
- if (Selection->Action == UI_ACTION_EXIT) {
- goto Done;
- }
- //
// IFR is updated during callback of read value, force to reparse the IFR binary
//
if (mHiiPackageListUpdated) {
@@ -1551,14 +2322,9 @@ SetupBrowser (
}
//
- // Displays the Header and Footer borders
- //
- DisplayPageFrame (Selection);
-
- //
// Display form
//
- Status = DisplayForm (Selection);
+ Status = DisplayForm ();
if (EFI_ERROR (Status)) {
goto Done;
}
@@ -1568,20 +2334,16 @@ SetupBrowser (
//
Statement = Selection->Statement;
if (Statement != NULL) {
- if ((Statement->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED) {
- gResetRequired = TRUE;
- }
-
if ((ConfigAccess != NULL) &&
((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) &&
(Statement->Operand != EFI_IFR_PASSWORD_OP)) {
- Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);
- if (Statement->Operand == EFI_IFR_REF_OP && Selection->Action != UI_ACTION_EXIT) {
+ Status = ProcessCallBackFunction(Selection, Statement, EFI_BROWSER_ACTION_CHANGING, FALSE);
+ if (Statement->Operand == EFI_IFR_REF_OP) {
//
// Process dynamic update ref opcode.
//
if (!EFI_ERROR (Status)) {
- Status = ProcessGotoOpCode(Statement, Selection, NULL, NULL);
+ Status = ProcessGotoOpCode(Statement, Selection);
}
//
@@ -1603,6 +2365,27 @@ SetupBrowser (
}
//
+ // Check whether Exit flag is TRUE.
+ //
+ if (gExitRequired) {
+ switch (gBrowserSettingScope) {
+ case SystemLevel:
+ Selection->Action = UI_ACTION_EXIT;
+ break;
+
+ case FormSetLevel:
+ case FormLevel:
+ FindNextMenu (Selection, gBrowserSettingScope);
+ break;
+
+ default:
+ break;
+ }
+
+ gExitRequired = FALSE;
+ }
+
+ //
// Before exit the form, invoke ConfigAccess.Callback() with EFI_BROWSER_ACTION_FORM_CLOSE
// for each question with callback flag.
//
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Print.c b/MdeModulePkg/Universal/SetupBrowserDxe/Print.c
deleted file mode 100644
index eeadf2494f..0000000000
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Print.c
+++ /dev/null
@@ -1,272 +0,0 @@
-/** @file
-Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very
-simple implemenation of SPrint() and Print() to support debug.
-
-You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a
-time. This makes the implementation very simple.
-
-VSPrint, Print, SPrint format specification has the follwoing form
-
-%type
-
-type:
- 'S','s' - argument is an Unicode string
- 'c' - argument is an ascii character
- '%' - Print a %
-
-
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
-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.
-
-**/
-
-#include "Setup.h"
-
-/**
- The internal function prints to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
- protocol instance.
-
- @param Column The position of the output string.
- @param Row The position of the output string.
- @param Out The EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL instance.
- @param Fmt The format string.
- @param Args The additional argument for the variables in the format string.
-
- @return Number of Unicode character printed.
-
-**/
-UINTN
-PrintInternal (
- IN UINTN Column,
- IN UINTN Row,
- IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Out,
- IN CHAR16 *Fmt,
- IN VA_LIST Args
- )
-{
- CHAR16 *Buffer;
- CHAR16 *BackupBuffer;
- UINTN Index;
- UINTN PreviousIndex;
- UINTN Count;
-
- //
- // For now, allocate an arbitrarily long buffer
- //
- Buffer = AllocateZeroPool (0x10000);
- BackupBuffer = AllocateZeroPool (0x10000);
- ASSERT (Buffer);
- ASSERT (BackupBuffer);
-
- if (Column != (UINTN) -1) {
- Out->SetCursorPosition (Out, Column, Row);
- }
-
- UnicodeVSPrint (Buffer, 0x10000, Fmt, Args);
-
- Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;
-
- Out->SetAttribute (Out, Out->Mode->Attribute);
-
- Index = 0;
- PreviousIndex = 0;
- Count = 0;
-
- do {
- for (; (Buffer[Index] != NARROW_CHAR) && (Buffer[Index] != WIDE_CHAR) && (Buffer[Index] != 0); Index++) {
- BackupBuffer[Index] = Buffer[Index];
- }
-
- if (Buffer[Index] == 0) {
- break;
- }
- //
- // Null-terminate the temporary string
- //
- BackupBuffer[Index] = 0;
-
- //
- // Print this out, we are about to switch widths
- //
- Out->OutputString (Out, &BackupBuffer[PreviousIndex]);
- Count += StrLen (&BackupBuffer[PreviousIndex]);
-
- //
- // Preserve the current index + 1, since this is where we will start printing from next
- //
- PreviousIndex = Index + 1;
-
- //
- // We are at a narrow or wide character directive. Set attributes and strip it and print it
- //
- if (Buffer[Index] == NARROW_CHAR) {
- //
- // Preserve bits 0 - 6 and zero out the rest
- //
- Out->Mode->Attribute = Out->Mode->Attribute & 0x7f;
- Out->SetAttribute (Out, Out->Mode->Attribute);
- } else {
- //
- // Must be wide, set bit 7 ON
- //
- Out->Mode->Attribute = Out->Mode->Attribute | EFI_WIDE_ATTRIBUTE;
- Out->SetAttribute (Out, Out->Mode->Attribute);
- }
-
- Index++;
-
- } while (Buffer[Index] != 0);
-
- //
- // We hit the end of the string - print it
- //
- Out->OutputString (Out, &BackupBuffer[PreviousIndex]);
- Count += StrLen (&BackupBuffer[PreviousIndex]);
-
- FreePool (Buffer);
- FreePool (BackupBuffer);
- return Count;
-}
-
-
-/**
- Prints a formatted unicode string to the default console.
-
- @param Fmt Format string
- @param ... Variable argument list for format string.
-
- @return Length of string printed to the console.
-
-**/
-UINTN
-EFIAPI
-ConsolePrint (
- IN CHAR16 *Fmt,
- ...
- )
-{
- VA_LIST Args;
- UINTN LengthOfPrinted;
-
- VA_START (Args, Fmt);
- LengthOfPrinted = PrintInternal ((UINTN) -1, (UINTN) -1, gST->ConOut, Fmt, Args);
- VA_END (Args);
- return LengthOfPrinted;
-}
-
-
-/**
- Prints a unicode string to the default console,
- using L"%s" format.
-
- @param String String pointer.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-PrintString (
- IN CHAR16 *String
- )
-{
- return ConsolePrint (L"%s", String);
-}
-
-
-/**
- Prints a chracter to the default console,
- using L"%c" format.
-
- @param Character Character to print.
-
- @return Length of string printed to the console.
-
-**/
-UINTN
-PrintChar (
- CHAR16 Character
- )
-{
- return ConsolePrint (L"%c", Character);
-}
-
-
-/**
- Prints a formatted unicode string to the default console, at
- the supplied cursor position.
-
- @param Column The cursor position to print the string at.
- @param Row The cursor position to print the string at.
- @param Fmt Format string.
- @param ... Variable argument list for format string.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-EFIAPI
-PrintAt (
- IN UINTN Column,
- IN UINTN Row,
- IN CHAR16 *Fmt,
- ...
- )
-{
- VA_LIST Args;
- UINTN LengthOfPrinted;
-
- VA_START (Args, Fmt);
- LengthOfPrinted = PrintInternal (Column, Row, gST->ConOut, Fmt, Args);
- VA_END (Args);
- return LengthOfPrinted;
-}
-
-
-/**
- Prints a unicode string to the default console, at
- the supplied cursor position, using L"%s" format.
-
- @param Column The cursor position to print the string at.
- @param Row The cursor position to print the string at
- @param String String pointer.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-PrintStringAt (
- IN UINTN Column,
- IN UINTN Row,
- IN CHAR16 *String
- )
-{
- return PrintAt (Column, Row, L"%s", String);
-}
-
-
-/**
- Prints a chracter to the default console, at
- the supplied cursor position, using L"%c" format.
-
- @param Column The cursor position to print the string at.
- @param Row The cursor position to print the string at.
- @param Character Character to print.
-
- @return Length of string printed to the console.
-
-**/
-UINTN
-PrintCharAt (
- IN UINTN Column,
- IN UINTN Row,
- CHAR16 Character
- )
-{
- return PrintAt (Column, Row, L"%c", Character);
-}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c b/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c
deleted file mode 100644
index fecb98e8bf..0000000000
--- a/MdeModulePkg/Universal/SetupBrowserDxe/ProcessOptions.c
+++ /dev/null
@@ -1,1075 +0,0 @@
-/** @file
-Implementation for handling the User Interface option processing.
-
-
-Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>
-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.
-
-**/
-
-#include "Setup.h"
-
-
-/**
- Process Question Config.
-
- @param Selection The UI menu selection.
- @param Question The Question to be peocessed.
-
- @retval EFI_SUCCESS Question Config process success.
- @retval Other Question Config process fail.
-
-**/
-EFI_STATUS
-ProcessQuestionConfig (
- IN UI_MENU_SELECTION *Selection,
- IN FORM_BROWSER_STATEMENT *Question
- )
-{
- EFI_STATUS Status;
- CHAR16 *ConfigResp;
- CHAR16 *Progress;
- EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
-
- if (Question->QuestionConfig == 0) {
- return EFI_SUCCESS;
- }
-
- //
- // Get <ConfigResp>
- //
- ConfigResp = GetToken (Question->QuestionConfig, Selection->FormSet->HiiHandle);
- if (ConfigResp == NULL) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Send config to Configuration Driver
- //
- ConfigAccess = Selection->FormSet->ConfigAccess;
- if (ConfigAccess == NULL) {
- return EFI_UNSUPPORTED;
- }
- Status = ConfigAccess->RouteConfig (
- ConfigAccess,
- ConfigResp,
- &Progress
- );
-
- return Status;
-}
-
-
-/**
- Search an Option of a Question by its value.
-
- @param Question The Question
- @param OptionValue Value for Option to be searched.
-
- @retval Pointer Pointer to the found Option.
- @retval NULL Option not found.
-
-**/
-QUESTION_OPTION *
-ValueToOption (
- IN FORM_BROWSER_STATEMENT *Question,
- IN EFI_HII_VALUE *OptionValue
- )
-{
- LIST_ENTRY *Link;
- QUESTION_OPTION *Option;
- INTN Result;
-
- Link = GetFirstNode (&Question->OptionListHead);
- while (!IsNull (&Question->OptionListHead, Link)) {
- Option = QUESTION_OPTION_FROM_LINK (Link);
-
- if ((CompareHiiValue (&Option->Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
- //
- // Check the suppressif condition, only a valid option can be return.
- //
- if ((Option->SuppressExpression == NULL) ||
- ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse))) {
- return Option;
- }
- }
-
- Link = GetNextNode (&Question->OptionListHead, Link);
- }
-
- return NULL;
-}
-
-
-/**
- Return data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
-
- @retval Value The data to be returned
-
-**/
-UINT64
-GetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index
- )
-{
- UINT64 Data;
-
- ASSERT (Array != NULL);
-
- Data = 0;
- switch (Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- Data = (UINT64) *(((UINT8 *) Array) + Index);
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_16:
- Data = (UINT64) *(((UINT16 *) Array) + Index);
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_32:
- Data = (UINT64) *(((UINT32 *) Array) + Index);
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_64:
- Data = (UINT64) *(((UINT64 *) Array) + Index);
- break;
-
- default:
- break;
- }
-
- return Data;
-}
-
-
-/**
- Set value of a data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
- @param Value The value to be set.
-
-**/
-VOID
-SetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index,
- IN UINT64 Value
- )
-{
-
- ASSERT (Array != NULL);
-
- switch (Type) {
- case EFI_IFR_TYPE_NUM_SIZE_8:
- *(((UINT8 *) Array) + Index) = (UINT8) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_16:
- *(((UINT16 *) Array) + Index) = (UINT16) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_32:
- *(((UINT32 *) Array) + Index) = (UINT32) Value;
- break;
-
- case EFI_IFR_TYPE_NUM_SIZE_64:
- *(((UINT64 *) Array) + Index) = (UINT64) Value;
- break;
-
- default:
- break;
- }
-}
-
-/**
- Check whether this value already in the array, if yes, return the index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Value The value to be find.
- @param Index The index in the array which has same value with Value.
-
- @retval TRUE Found the value in the array.
- @retval FALSE Not found the value.
-
-**/
-BOOLEAN
-FindArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINT64 Value,
- OUT UINTN *Index OPTIONAL
- )
-{
- UINTN Count;
- UINT64 TmpValue;
-
- ASSERT (Array != NULL);
-
- Count = 0;
- TmpValue = 0;
-
- while ((TmpValue = GetArrayData (Array, Type, Count)) != 0) {
- if (Value == TmpValue) {
- if (Index != NULL) {
- *Index = Count;
- }
- return TRUE;
- }
-
- Count ++;
- }
-
- return FALSE;
-}
-
-/**
- Print Question Value according to it's storage width and display attributes.
-
- @param Question The Question to be printed.
- @param FormattedNumber Buffer for output string.
- @param BufferSize The FormattedNumber buffer size in bytes.
-
- @retval EFI_SUCCESS Print success.
- @retval EFI_BUFFER_TOO_SMALL Buffer size is not enough for formatted number.
-
-**/
-EFI_STATUS
-PrintFormattedNumber (
- IN FORM_BROWSER_STATEMENT *Question,
- IN OUT CHAR16 *FormattedNumber,
- IN UINTN BufferSize
- )
-{
- INT64 Value;
- CHAR16 *Format;
- EFI_HII_VALUE *QuestionValue;
-
- if (BufferSize < (21 * sizeof (CHAR16))) {
- return EFI_BUFFER_TOO_SMALL;
- }
-
- QuestionValue = &Question->HiiValue;
-
- Value = (INT64) QuestionValue->Value.u64;
- switch (Question->Flags & EFI_IFR_DISPLAY) {
- case EFI_IFR_DISPLAY_INT_DEC:
- switch (QuestionValue->Type) {
- case EFI_IFR_NUMERIC_SIZE_1:
- Value = (INT64) ((INT8) QuestionValue->Value.u8);
- break;
-
- case EFI_IFR_NUMERIC_SIZE_2:
- Value = (INT64) ((INT16) QuestionValue->Value.u16);
- break;
-
- case EFI_IFR_NUMERIC_SIZE_4:
- Value = (INT64) ((INT32) QuestionValue->Value.u32);
- break;
-
- case EFI_IFR_NUMERIC_SIZE_8:
- default:
- break;
- }
-
- if (Value < 0) {
- Value = -Value;
- Format = L"-%ld";
- } else {
- Format = L"%ld";
- }
- break;
-
- case EFI_IFR_DISPLAY_UINT_DEC:
- Format = L"%ld";
- break;
-
- case EFI_IFR_DISPLAY_UINT_HEX:
- Format = L"%lx";
- break;
-
- default:
- return EFI_UNSUPPORTED;
- break;
- }
-
- UnicodeSPrint (FormattedNumber, BufferSize, Format, Value);
-
- return EFI_SUCCESS;
-}
-
-
-/**
- Password may be stored as encrypted by Configuration Driver. When change a
- password, user will be challenged with old password. To validate user input old
- password, we will send the clear text to Configuration Driver via Callback().
- Configuration driver is responsible to check the passed in password and return
- the validation result. If validation pass, state machine in password Callback()
- will transit from BROWSER_STATE_VALIDATE_PASSWORD to BROWSER_STATE_SET_PASSWORD.
- After user type in new password twice, Callback() will be invoked to send the
- new password to Configuration Driver.
-
- @param Selection Pointer to UI_MENU_SELECTION.
- @param MenuOption The MenuOption for this password Question.
- @param String The clear text of password.
-
- @retval EFI_NOT_AVAILABLE_YET Callback() request to terminate password input.
- @return In state of BROWSER_STATE_VALIDATE_PASSWORD:
- @retval EFI_SUCCESS Password correct, Browser will prompt for new
- password.
- @retval EFI_NOT_READY Password incorrect, Browser will show error
- message.
- @retval Other Browser will do nothing.
- @return In state of BROWSER_STATE_SET_PASSWORD:
- @retval EFI_SUCCESS Set password success.
- @retval Other Set password failed.
-
-**/
-EFI_STATUS
-PasswordCallback (
- IN UI_MENU_SELECTION *Selection,
- IN UI_MENU_OPTION *MenuOption,
- IN CHAR16 *String
- )
-{
- EFI_STATUS Status;
- EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
- EFI_BROWSER_ACTION_REQUEST ActionRequest;
- EFI_IFR_TYPE_VALUE IfrTypeValue;
-
- ConfigAccess = Selection->FormSet->ConfigAccess;
- if (ConfigAccess == NULL) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Prepare password string in HII database
- //
- if (String != NULL) {
- IfrTypeValue.string = NewString (String, Selection->FormSet->HiiHandle);
- } else {
- IfrTypeValue.string = 0;
- }
-
- //
- // Send password to Configuration Driver for validation
- //
- Status = ConfigAccess->Callback (
- ConfigAccess,
- EFI_BROWSER_ACTION_CHANGING,
- MenuOption->ThisTag->QuestionId,
- MenuOption->ThisTag->HiiValue.Type,
- &IfrTypeValue,
- &ActionRequest
- );
-
- //
- // Remove password string from HII database
- //
- if (String != NULL) {
- DeleteString (IfrTypeValue.string, Selection->FormSet->HiiHandle);
- }
-
- return Status;
-}
-
-
-/**
- Display error message for invalid password.
-
-**/
-VOID
-PasswordInvalid (
- VOID
- )
-{
- EFI_INPUT_KEY Key;
-
- //
- // Invalid password, prompt error message
- //
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gPassowordInvalid, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-}
-
-
-/**
- Process a Question's Option (whether selected or un-selected).
-
- @param Selection Pointer to UI_MENU_SELECTION.
- @param MenuOption The MenuOption for this Question.
- @param Selected TRUE: if Question is selected.
- @param OptionString Pointer of the Option String to be displayed.
-
- @retval EFI_SUCCESS Question Option process success.
- @retval Other Question Option process fail.
-
-**/
-EFI_STATUS
-ProcessOptions (
- IN UI_MENU_SELECTION *Selection,
- IN UI_MENU_OPTION *MenuOption,
- IN BOOLEAN Selected,
- OUT CHAR16 **OptionString
- )
-{
- EFI_STATUS Status;
- CHAR16 *StringPtr;
- CHAR16 *TempString;
- UINTN Index;
- FORM_BROWSER_STATEMENT *Question;
- CHAR16 FormattedNumber[21];
- UINT16 Number;
- CHAR16 Character[2];
- EFI_INPUT_KEY Key;
- UINTN BufferSize;
- QUESTION_OPTION *OneOfOption;
- LIST_ENTRY *Link;
- EFI_HII_VALUE HiiValue;
- EFI_HII_VALUE *QuestionValue;
- UINT16 Maximum;
- QUESTION_OPTION *Option;
- UINTN Index2;
- UINT8 *ValueArray;
- UINT8 ValueType;
- EFI_STRING_ID StringId;
-
- Status = EFI_SUCCESS;
-
- StringPtr = NULL;
- Character[1] = L'\0';
- *OptionString = NULL;
- StringId = 0;
-
- ZeroMem (FormattedNumber, 21 * sizeof (CHAR16));
- BufferSize = (gOptionBlockWidth + 1) * 2 * gScreenDimensions.BottomRow;
-
- Question = MenuOption->ThisTag;
- QuestionValue = &Question->HiiValue;
- Maximum = (UINT16) Question->Maximum;
-
- ValueArray = Question->BufferValue;
- ValueType = Question->ValueType;
-
- switch (Question->Operand) {
- case EFI_IFR_ORDERED_LIST_OP:
- //
- // Check whether there are Options of this OrderedList
- //
- if (IsListEmpty (&Question->OptionListHead)) {
- break;
- }
- //
- // Initialize Option value array
- //
- if (GetArrayData (ValueArray, ValueType, 0) == 0) {
- GetQuestionDefault (Selection->FormSet, Selection->Form, Question, 0);
- }
-
- if (Selected) {
- //
- // Go ask for input
- //
- Status = GetSelectionInputPopUp (Selection, MenuOption);
- } else {
- //
- // We now know how many strings we will have, so we can allocate the
- // space required for the array or strings.
- //
- *OptionString = AllocateZeroPool (Question->MaxContainers * BufferSize);
- ASSERT (*OptionString);
-
- HiiValue.Type = ValueType;
- HiiValue.Value.u64 = 0;
- for (Index = 0; Index < Question->MaxContainers; Index++) {
- HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index);
- if (HiiValue.Value.u64 == 0) {
- //
- // Values for the options in ordered lists should never be a 0
- //
- break;
- }
-
- OneOfOption = ValueToOption (Question, &HiiValue);
- if (OneOfOption == NULL) {
- //
- // Show error message
- //
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-
- //
- // The initial value of the orderedlist is invalid, force to be valid value
- //
- Link = GetFirstNode (&Question->OptionListHead);
- Index2 = 0;
- while (!IsNull (&Question->OptionListHead, Link) && Index2 < Question->MaxContainers) {
- Option = QUESTION_OPTION_FROM_LINK (Link);
- Link = GetNextNode (&Question->OptionListHead, Link);
- if ((Option->SuppressExpression != NULL) &&
- ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {
- continue;
- }
- SetArrayData (ValueArray, ValueType, Index2, Option->Value.Value.u64);
- Index2++;
- }
- SetArrayData (ValueArray, ValueType, Index2, 0);
-
- Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
- UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
-
- FreePool (*OptionString);
- *OptionString = NULL;
- return EFI_NOT_FOUND;
- }
-
- Character[0] = LEFT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
- StringPtr = GetToken (OneOfOption->Text, Selection->Handle);
- ASSERT (StringPtr != NULL);
- NewStrCat (OptionString[0], StringPtr);
- Character[0] = RIGHT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
- Character[0] = CHAR_CARRIAGE_RETURN;
- NewStrCat (OptionString[0], Character);
- FreePool (StringPtr);
- }
-
- //
- // Search the other options, try to find the one not in the container.
- //
- Link = GetFirstNode (&Question->OptionListHead);
- while (!IsNull (&Question->OptionListHead, Link)) {
- OneOfOption = QUESTION_OPTION_FROM_LINK (Link);
- Link = GetNextNode (&Question->OptionListHead, Link);
- if ((OneOfOption->SuppressExpression != NULL) &&
- ((EvaluateExpressionList(OneOfOption->SuppressExpression, FALSE, NULL, NULL) == ExpressSuppress))) {
- continue;
- }
-
- if (FindArrayData (ValueArray, ValueType, OneOfOption->Value.Value.u64, NULL)) {
- continue;
- }
-
- SetArrayData (ValueArray, ValueType, Index++, OneOfOption->Value.Value.u64);
-
- Character[0] = LEFT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
- StringPtr = GetToken (OneOfOption->Text, Selection->Handle);
- ASSERT (StringPtr != NULL);
- NewStrCat (OptionString[0], StringPtr);
- Character[0] = RIGHT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
- Character[0] = CHAR_CARRIAGE_RETURN;
- NewStrCat (OptionString[0], Character);
- FreePool (StringPtr);
- }
- }
- break;
-
- case EFI_IFR_ONE_OF_OP:
- //
- // Check whether there are Options of this OneOf
- //
- if (IsListEmpty (&Question->OptionListHead)) {
- break;
- }
- if (Selected) {
- //
- // Go ask for input
- //
- Status = GetSelectionInputPopUp (Selection, MenuOption);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- OneOfOption = ValueToOption (Question, QuestionValue);
- if (OneOfOption == NULL) {
- //
- // Show error message
- //
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gOptionMismatch, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
-
- //
- // Force the Question value to be valid
- //
- Link = GetFirstNode (&Question->OptionListHead);
- while (!IsNull (&Question->OptionListHead, Link)) {
- Option = QUESTION_OPTION_FROM_LINK (Link);
-
- if ((Option->SuppressExpression == NULL) ||
- (EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse)) {
- CopyMem (QuestionValue, &Option->Value, sizeof (EFI_HII_VALUE));
- SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
- UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
- break;
- }
-
- Link = GetNextNode (&Question->OptionListHead, Link);
- }
-
- FreePool (*OptionString);
- *OptionString = NULL;
- return EFI_NOT_FOUND;
- }
-
- Character[0] = LEFT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
- StringPtr = GetToken (OneOfOption->Text, Selection->Handle);
- ASSERT (StringPtr != NULL);
- NewStrCat (OptionString[0], StringPtr);
- Character[0] = RIGHT_ONEOF_DELIMITER;
- NewStrCat (OptionString[0], Character);
-
- FreePool (StringPtr);
- }
- break;
-
- case EFI_IFR_CHECKBOX_OP:
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- *OptionString[0] = LEFT_CHECKBOX_DELIMITER;
-
- if (Selected) {
- //
- // Since this is a BOOLEAN operation, flip it upon selection
- //
- QuestionValue->Value.b = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);
-
- //
- // Perform inconsistent check
- //
- Status = ValidateQuestion (Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
- if (EFI_ERROR (Status)) {
- //
- // Inconsistent check fail, restore Question Value
- //
- QuestionValue->Value.b = (BOOLEAN) (QuestionValue->Value.b ? FALSE : TRUE);
- FreePool (*OptionString);
- *OptionString = NULL;
- return Status;
- }
-
- //
- // Save Question value
- //
- Status = SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
- UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
- }
-
- if (QuestionValue->Value.b) {
- *(OptionString[0] + 1) = CHECK_ON;
- } else {
- *(OptionString[0] + 1) = CHECK_OFF;
- }
- *(OptionString[0] + 2) = RIGHT_CHECKBOX_DELIMITER;
- break;
-
- case EFI_IFR_NUMERIC_OP:
- if (Selected) {
- //
- // Go ask for input
- //
- Status = GetNumericInput (Selection, MenuOption);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- *OptionString[0] = LEFT_NUMERIC_DELIMITER;
-
- //
- // Formatted print
- //
- PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16));
- Number = (UINT16) GetStringWidth (FormattedNumber);
- CopyMem (OptionString[0] + 1, FormattedNumber, Number);
-
- *(OptionString[0] + Number / 2) = RIGHT_NUMERIC_DELIMITER;
- }
- break;
-
- case EFI_IFR_DATE_OP:
- if (Selected) {
- //
- // This is similar to numerics
- //
- Status = GetNumericInput (Selection, MenuOption);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- switch (MenuOption->Sequence) {
- case 0:
- *OptionString[0] = LEFT_NUMERIC_DELIMITER;
- UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Month);
- *(OptionString[0] + 3) = DATE_SEPARATOR;
- break;
-
- case 1:
- SetUnicodeMem (OptionString[0], 4, L' ');
- UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.date.Day);
- *(OptionString[0] + 6) = DATE_SEPARATOR;
- break;
-
- case 2:
- SetUnicodeMem (OptionString[0], 7, L' ');
- UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%04d", QuestionValue->Value.date.Year);
- *(OptionString[0] + 11) = RIGHT_NUMERIC_DELIMITER;
- break;
- }
- }
- break;
-
- case EFI_IFR_TIME_OP:
- if (Selected) {
- //
- // This is similar to numerics
- //
- Status = GetNumericInput (Selection, MenuOption);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- switch (MenuOption->Sequence) {
- case 0:
- *OptionString[0] = LEFT_NUMERIC_DELIMITER;
- UnicodeSPrint (OptionString[0] + 1, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Hour);
- *(OptionString[0] + 3) = TIME_SEPARATOR;
- break;
-
- case 1:
- SetUnicodeMem (OptionString[0], 4, L' ');
- UnicodeSPrint (OptionString[0] + 4, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Minute);
- *(OptionString[0] + 6) = TIME_SEPARATOR;
- break;
-
- case 2:
- SetUnicodeMem (OptionString[0], 7, L' ');
- UnicodeSPrint (OptionString[0] + 7, 21 * sizeof (CHAR16), L"%02d", QuestionValue->Value.time.Second);
- *(OptionString[0] + 9) = RIGHT_NUMERIC_DELIMITER;
- break;
- }
- }
- break;
-
- case EFI_IFR_STRING_OP:
- if (Selected) {
- StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
- ASSERT (StringPtr);
- CopyMem(StringPtr, Question->BufferValue, Maximum * sizeof (CHAR16));
-
- Status = ReadString (MenuOption, gPromptForData, StringPtr);
- if (!EFI_ERROR (Status)) {
- HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, StringPtr, NULL);
- Status = ValidateQuestion(Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
- if (EFI_ERROR (Status)) {
- HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);
- } else {
- CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));
- SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithEditBuffer);
-
- UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Question->QuestionFlags, TRUE);
- }
- }
-
- FreePool (StringPtr);
- } else {
- *OptionString = AllocateZeroPool (BufferSize);
- ASSERT (*OptionString);
-
- if (((CHAR16 *) Question->BufferValue)[0] == 0x0000) {
- *(OptionString[0]) = '_';
- } else {
- if ((Maximum * sizeof (CHAR16)) < BufferSize) {
- BufferSize = Maximum * sizeof (CHAR16);
- }
- CopyMem (OptionString[0], (CHAR16 *) Question->BufferValue, BufferSize);
- }
- }
- break;
-
- case EFI_IFR_PASSWORD_OP:
- if (Selected) {
- StringPtr = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
- ASSERT (StringPtr);
-
- //
- // For interactive passwords, old password is validated by callback
- //
- if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- //
- // Use a NULL password to test whether old password is required
- //
- *StringPtr = 0;
- Status = PasswordCallback (Selection, MenuOption, StringPtr);
- if (Status == EFI_NOT_AVAILABLE_YET || Status == EFI_UNSUPPORTED) {
- //
- // Callback is not supported, or
- // Callback request to terminate password input
- //
- FreePool (StringPtr);
- return EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- //
- // Old password exist, ask user for the old password
- //
- Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
- if (EFI_ERROR (Status)) {
- FreePool (StringPtr);
- return Status;
- }
-
- //
- // Check user input old password
- //
- Status = PasswordCallback (Selection, MenuOption, StringPtr);
- if (EFI_ERROR (Status)) {
- if (Status == EFI_NOT_READY) {
- //
- // Typed in old password incorrect
- //
- PasswordInvalid ();
- } else {
- Status = EFI_SUCCESS;
- }
-
- FreePool (StringPtr);
- return Status;
- }
- }
- } else {
- //
- // For non-interactive password, validate old password in local
- //
- if (*((CHAR16 *) Question->BufferValue) != 0) {
- //
- // There is something there! Prompt for password
- //
- Status = ReadString (MenuOption, gPromptForPassword, StringPtr);
- if (EFI_ERROR (Status)) {
- FreePool (StringPtr);
- return Status;
- }
-
- TempString = AllocateCopyPool ((Maximum + 1) * sizeof (CHAR16), Question->BufferValue);
- ASSERT (TempString != NULL);
-
- TempString[Maximum] = L'\0';
-
- if (StrCmp (StringPtr, TempString) != 0) {
- //
- // Typed in old password incorrect
- //
- PasswordInvalid ();
-
- FreePool (StringPtr);
- FreePool (TempString);
- return Status;
- }
-
- FreePool (TempString);
- }
- }
-
- //
- // Ask for new password
- //
- ZeroMem (StringPtr, (Maximum + 1) * sizeof (CHAR16));
- Status = ReadString (MenuOption, gPromptForNewPassword, StringPtr);
- if (EFI_ERROR (Status)) {
- //
- // Reset state machine for interactive password
- //
- if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- PasswordCallback (Selection, MenuOption, NULL);
- }
-
- FreePool (StringPtr);
- return Status;
- }
-
- //
- // Confirm new password
- //
- TempString = AllocateZeroPool ((Maximum + 1) * sizeof (CHAR16));
- ASSERT (TempString);
- Status = ReadString (MenuOption, gConfirmPassword, TempString);
- if (EFI_ERROR (Status)) {
- //
- // Reset state machine for interactive password
- //
- if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- PasswordCallback (Selection, MenuOption, NULL);
- }
-
- FreePool (StringPtr);
- FreePool (TempString);
- return Status;
- }
-
- //
- // Compare two typed-in new passwords
- //
- if (StrCmp (StringPtr, TempString) == 0) {
- //
- // Prepare the Question->HiiValue.Value.string for ValidateQuestion use.
- //
- if((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- StringId = Question->HiiValue.Value.string;
- Question->HiiValue.Value.string = NewString (StringPtr, Selection->FormSet->HiiHandle);
- } else {
- HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, StringPtr, NULL);
- }
-
- Status = ValidateQuestion(Selection->FormSet, Selection->Form, Question, EFI_HII_EXPRESSION_INCONSISTENT_IF);
-
- //
- // Researve the Question->HiiValue.Value.string.
- //
- if((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- DeleteString(Question->HiiValue.Value.string, Selection->FormSet->HiiHandle);
- Question->HiiValue.Value.string = StringId;
- }
-
- if (EFI_ERROR (Status)) {
- //
- // Reset state machine for interactive password
- //
- if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- PasswordCallback (Selection, MenuOption, NULL);
- } else {
- //
- // Researve the Question->HiiValue.Value.string.
- //
- HiiSetString(Selection->FormSet->HiiHandle, Question->HiiValue.Value.string, (CHAR16*)Question->BufferValue, NULL);
- }
- } else {
- //
- // Two password match, send it to Configuration Driver
- //
- if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- PasswordCallback (Selection, MenuOption, StringPtr);
- } else {
- CopyMem (Question->BufferValue, StringPtr, Maximum * sizeof (CHAR16));
- SetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithHiiDriver);
- }
- }
- } else {
- //
- // Reset state machine for interactive password
- //
- if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- PasswordCallback (Selection, MenuOption, NULL);
- }
-
- //
- // Two password mismatch, prompt error message
- //
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gConfirmError, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- }
-
- FreePool (TempString);
- FreePool (StringPtr);
- }
- break;
-
- default:
- break;
- }
-
- return Status;
-}
-
-
-/**
- Process the help string: Split StringPtr to several lines of strings stored in
- FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.
-
- @param StringPtr The entire help string.
- @param FormattedString The oupput formatted string.
- @param EachLineWidth The max string length of each line in the formatted string.
- @param RowCount TRUE: if Question is selected.
-
-**/
-UINTN
-ProcessHelpString (
- IN CHAR16 *StringPtr,
- OUT CHAR16 **FormattedString,
- OUT UINT16 *EachLineWidth,
- IN UINTN RowCount
- )
-{
- UINTN Index;
- CHAR16 *OutputString;
- UINTN TotalRowNum;
- UINTN CheckedNum;
- UINT16 GlyphWidth;
- UINT16 LineWidth;
- UINT16 MaxStringLen;
- UINT16 StringLen;
-
- TotalRowNum = 0;
- CheckedNum = 0;
- GlyphWidth = 1;
- Index = 0;
- MaxStringLen = 0;
- StringLen = 0;
-
- //
- // Set default help string width.
- //
- LineWidth = (UINT16) (gHelpBlockWidth - 1);
-
- //
- // Get row number of the String.
- //
- while ((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {
- if (StringLen > MaxStringLen) {
- MaxStringLen = StringLen;
- }
-
- TotalRowNum ++;
- FreePool (OutputString);
- }
- *EachLineWidth = MaxStringLen;
-
- *FormattedString = AllocateZeroPool (TotalRowNum * MaxStringLen * sizeof (CHAR16));
- ASSERT (*FormattedString != NULL);
-
- //
- // Generate formatted help string array.
- //
- GlyphWidth = 1;
- Index = 0;
- while((StringLen = GetLineByWidth (StringPtr, LineWidth, &GlyphWidth, &Index, &OutputString)) != 0) {
- CopyMem (*FormattedString + CheckedNum * MaxStringLen, OutputString, StringLen * sizeof (CHAR16));
- CheckedNum ++;
- FreePool (OutputString);
- }
-
- return TotalRowNum;
-}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
index ed904161b6..ba72d1220b 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
@@ -26,167 +26,281 @@ SETUP_DRIVER_PRIVATE_DATA mPrivateData = {
RegisterHotKey,
RegiserExitHandler,
SaveReminder
+ },
+ {
+ BROWSER_EXTENSION2_VERSION_1,
+ SetScope,
+ RegisterHotKey,
+ RegiserExitHandler,
+ IsBrowserDataModified,
+ ExecuteAction,
}
};
EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
-EFI_HII_STRING_PROTOCOL *mHiiString;
EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;
EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;
+EDKII_FORM_DISPLAY_ENGINE_PROTOCOL *mFormDisplay;
UINTN gBrowserContextCount = 0;
LIST_ENTRY gBrowserContextList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserContextList);
LIST_ENTRY gBrowserFormSetList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserFormSetList);
LIST_ENTRY gBrowserHotKeyList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserHotKeyList);
-LIST_ENTRY gBrowserStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);
+LIST_ENTRY gBrowserStorageList = INITIALIZE_LIST_HEAD_VARIABLE (gBrowserStorageList);
-BANNER_DATA *gBannerData;
-EFI_HII_HANDLE gFrontPageHandle;
-UINTN gClassOfVfr;
-UINTN gFunctionKeySetting;
BOOLEAN gResetRequired;
-EFI_HII_HANDLE gHiiHandle;
-UINT16 gDirection;
-EFI_SCREEN_DESCRIPTOR gScreenDimensions;
+BOOLEAN gExitRequired;
BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;
BOOLEAN mBrowserScopeFirstSet = TRUE;
EXIT_HANDLER ExitHandlerFunction = NULL;
-UINTN gFooterHeight;
//
// Browser Global Strings
//
-CHAR16 *gSaveFailed;
-CHAR16 *gDiscardFailed;
-CHAR16 *gDefaultFailed;
-CHAR16 *gEnterString;
-CHAR16 *gEnterCommitString;
-CHAR16 *gEnterEscapeString;
-CHAR16 *gEscapeString;
-CHAR16 *gMoveHighlight;
-CHAR16 *gMakeSelection;
-CHAR16 *gDecNumericInput;
-CHAR16 *gHexNumericInput;
-CHAR16 *gToggleCheckBox;
-CHAR16 *gPromptForData;
-CHAR16 *gPromptForPassword;
-CHAR16 *gPromptForNewPassword;
-CHAR16 *gConfirmPassword;
-CHAR16 *gConfirmError;
-CHAR16 *gPassowordInvalid;
-CHAR16 *gPressEnter;
CHAR16 *gEmptyString;
-CHAR16 *gAreYouSure;
-CHAR16 *gYesResponse;
-CHAR16 *gNoResponse;
-CHAR16 *gMiniString;
-CHAR16 *gPlusString;
-CHAR16 *gMinusString;
-CHAR16 *gAdjustNumber;
-CHAR16 *gSaveChanges;
-CHAR16 *gOptionMismatch;
-CHAR16 *gFormSuppress;
-CHAR16 *gProtocolNotFound;
-
CHAR16 *mUnknownString = L"!";
-CHAR16 gPromptBlockWidth;
-CHAR16 gOptionBlockWidth;
-CHAR16 gHelpBlockWidth;
-
EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
-EFI_GUID gSetupBrowserGuid = {
- 0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}
-};
-FORM_BROWSER_FORMSET *gOldFormSet = NULL;
+extern UINT32 gBrowserStatus;
+extern CHAR16 *gErrorInfo;
+extern EFI_GUID mCurrentFormSetGuid;
+extern EFI_HII_HANDLE mCurrentHiiHandle;
+extern UINT16 mCurrentFormId;
+extern FORM_DISPLAY_ENGINE_FORM gDisplayFormData;
+
+/**
+ Create a menu with specified formset GUID and form ID, and add it as a child
+ of the given parent menu.
+
+ @param HiiHandle Hii handle related to this formset.
+ @param FormSetGuid The Formset Guid of menu to be added.
+ @param FormId The Form ID of menu to be added.
+ @param QuestionId The question id of this menu to be added.
+
+ @return A pointer to the newly added menu or NULL if memory is insufficient.
+
+**/
+FORM_ENTRY_INFO *
+UiAddMenuList (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid,
+ IN UINT16 FormId,
+ IN UINT16 QuestionId
+ )
+{
+ FORM_ENTRY_INFO *MenuList;
+
+ MenuList = AllocateZeroPool (sizeof (FORM_ENTRY_INFO));
+ if (MenuList == NULL) {
+ return NULL;
+ }
+
+ MenuList->Signature = FORM_ENTRY_INFO_SIGNATURE;
+
+ MenuList->HiiHandle = HiiHandle;
+ CopyMem (&MenuList->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));
+ MenuList->FormId = FormId;
+ MenuList->QuestionId = QuestionId;
-FUNCTIION_KEY_SETTING gFunctionKeySettingTable[] = {
//
- // Boot Manager
+ // If parent is not specified, it is the root Form of a Formset
//
- {
- {
- 0x847bc3fe,
- 0xb974,
- 0x446d,
- {
- 0x94,
- 0x49,
- 0x5a,
- 0xd5,
- 0x41,
- 0x2e,
- 0x99,
- 0x3b
+ InsertTailList (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &MenuList->Link);
+
+ return MenuList;
+}
+
+/**
+ Return the form id for the input hiihandle and formset.
+
+ @param HiiHandle HiiHandle for FormSet.
+ @param FormSetGuid The Formset GUID of the menu to search.
+
+ @return First form's id for this form set.
+
+**/
+EFI_FORM_ID
+GetFirstFormId (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid
+ )
+{
+ LIST_ENTRY *Link;
+ FORM_BROWSER_FORM *Form;
+
+ Link = GetFirstNode (&gCurrentSelection->FormSet->FormListHead);
+ Form = FORM_BROWSER_FORM_FROM_LINK (Link);
+
+ return Form->FormId;
+}
+
+/**
+ Search Menu with given FormSetGuid and FormId in all cached menu list.
+
+ @param HiiHandle HiiHandle for FormSet.
+ @param FormSetGuid The Formset GUID of the menu to search.
+ @param FormId The Form ID of menu to search.
+
+ @return A pointer to menu found or NULL if not found.
+
+**/
+FORM_ENTRY_INFO *
+UiFindMenuList (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid,
+ IN UINT16 FormId
+ )
+{
+ LIST_ENTRY *Link;
+ FORM_ENTRY_INFO *MenuList;
+ FORM_ENTRY_INFO *RetMenu;
+ EFI_FORM_ID FirstFormId;
+
+ RetMenu = NULL;
+
+ Link = GetFirstNode (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);
+ while (!IsNull (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, Link)) {
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (Link);
+ Link = GetNextNode (&mPrivateData.FormBrowserEx2.FormViewHistoryHead, Link);
+
+ //
+ // If already find the menu, free the menus behind it.
+ //
+ if (RetMenu != NULL) {
+ RemoveEntryList (&MenuList->Link);
+ FreePool (MenuList);
+ continue;
+ }
+
+ //
+ // Find the same FromSet.
+ //
+ if (MenuList->HiiHandle == HiiHandle) {
+ if (CompareGuid (&MenuList->FormSetGuid, &gZeroGuid)) {
+ //
+ // FormSetGuid is not specified.
+ //
+ RetMenu = MenuList;
+ } else if (CompareGuid (&MenuList->FormSetGuid, FormSetGuid)) {
+ if (MenuList->FormId == FormId) {
+ RetMenu = MenuList;
+ } else if (FormId == 0 || MenuList->FormId == 0 ) {
+ FirstFormId = GetFirstFormId (HiiHandle, FormSetGuid);
+ if ((FormId == 0 && FirstFormId == MenuList->FormId) || (MenuList->FormId ==0 && FirstFormId == FormId)) {
+ RetMenu = MenuList;
+ }
+ }
}
- },
- NONE_FUNCTION_KEY_SETTING
- },
+ }
+ }
+
+ return RetMenu;
+}
+
+/**
+ Find parent menu for current menu.
+
+ @param CurrentMenu Current Menu
+
+ @retval The parent menu for current menu.
+**/
+FORM_ENTRY_INFO *
+UiFindParentMenu (
+ IN FORM_ENTRY_INFO *CurrentMenu
+ )
+{
+ FORM_ENTRY_INFO *ParentMenu;
+
+ ParentMenu = NULL;
+ if (CurrentMenu->Link.BackLink != &mPrivateData.FormBrowserEx2.FormViewHistoryHead) {
+ ParentMenu = FORM_ENTRY_INFO_FROM_LINK (CurrentMenu->Link.BackLink);
+ }
+
+ return ParentMenu;
+}
+
+/**
+ Free Menu list linked list.
+
+ @param MenuListHead One Menu list point in the menu list.
+
+**/
+VOID
+UiFreeMenuList (
+ LIST_ENTRY *MenuListHead
+ )
+{
+ FORM_ENTRY_INFO *MenuList;
+
+ while (!IsListEmpty (MenuListHead)) {
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (MenuListHead->ForwardLink);
+ RemoveEntryList (&MenuList->Link);
+
+ FreePool (MenuList);
+ }
+}
+
+/**
+ Load all hii formset to the browser.
+
+**/
+VOID
+LoadAllHiiFormset (
+ VOID
+ )
+{
+ FORM_BROWSER_FORMSET *LocalFormSet;
+ EFI_HII_HANDLE *HiiHandles;
+ UINTN Index;
+ EFI_GUID ZeroGuid;
+ EFI_STATUS Status;
+
//
- // Device Manager
+ // Get all the Hii handles
//
- {
- {
- 0x3ebfa8e6,
- 0x511d,
- 0x4b5b,
- {
- 0xa9,
- 0x5f,
- 0xfb,
- 0x38,
- 0x26,
- 0xf,
- 0x1c,
- 0x27
- }
- },
- NONE_FUNCTION_KEY_SETTING
- },
+ HiiHandles = HiiGetHiiHandles (NULL);
+ ASSERT (HiiHandles != NULL);
+
//
- // BMM FormSet.
+ // Search for formset of each class type
//
- {
- {
- 0x642237c7,
- 0x35d4,
- 0x472d,
- {
- 0x83,
- 0x65,
- 0x12,
- 0xe0,
- 0xcc,
- 0xf2,
- 0x7a,
- 0x22
- }
- },
- NONE_FUNCTION_KEY_SETTING
- },
+ for (Index = 0; HiiHandles[Index] != NULL; Index++) {
+ //
+ // Check HiiHandles[Index] does exist in global maintain list.
+ //
+ if (GetFormSetFromHiiHandle (HiiHandles[Index]) != NULL) {
+ continue;
+ }
+
+ //
+ // Initilize FormSet Setting
+ //
+ LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
+ ASSERT (LocalFormSet != NULL);
+ ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
+ Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet);
+ if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {
+ DestroyFormSet (LocalFormSet);
+ continue;
+ }
+ InitializeCurrentSetting (LocalFormSet);
+
+ //
+ // Initilize Questions' Value
+ //
+ Status = LoadFormSetConfig (NULL, LocalFormSet);
+ if (EFI_ERROR (Status)) {
+ DestroyFormSet (LocalFormSet);
+ continue;
+ }
+ }
+
//
- // BMM File Explorer FormSet.
+ // Free resources, and restore gOldFormSet and gClassOfVfr
//
- {
- {
- 0x1f2d63e1,
- 0xfebd,
- 0x4dc7,
- {
- 0x9c,
- 0xc5,
- 0xba,
- 0x2b,
- 0x1c,
- 0xef,
- 0x9c,
- 0x5b
- }
- },
- NONE_FUNCTION_KEY_SETTING
- },
-};
+ FreePool (HiiHandles);
+}
/**
This is the routine which an external caller uses to direct the browser
@@ -229,26 +343,14 @@ SendForm (
UI_MENU_SELECTION *Selection;
UINTN Index;
FORM_BROWSER_FORMSET *FormSet;
- LIST_ENTRY *Link;
+ FORM_ENTRY_INFO *MenuList;
//
- // Calculate total number of Register HotKeys.
+ // If EDKII_FORM_DISPLAY_ENGINE_PROTOCOL not found, return EFI_UNSUPPORTED.
//
- Index = 0;
- Link = GetFirstNode (&gBrowserHotKeyList);
- while (!IsNull (&gBrowserHotKeyList, Link)) {
- Link = GetNextNode (&gBrowserHotKeyList, Link);
- Index ++;
+ if (mFormDisplay == NULL) {
+ return EFI_UNSUPPORTED;
}
- //
- // Show three HotKeys help information on one ROW.
- //
- gFooterHeight = FOOTER_HEIGHT + (Index / 3);
-
- //
- // Clean the history menu list.
- //
- InitializeListHead (&gMenuList);
//
// Save globals used by SendForm()
@@ -256,65 +358,10 @@ SendForm (
SaveBrowserContext ();
gResetRequired = FALSE;
- Status = EFI_SUCCESS;
- ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
-
- //
- // Seed the dimensions in the global
- //
- gST->ConOut->QueryMode (
- gST->ConOut,
- gST->ConOut->Mode->Mode,
- &gScreenDimensions.RightColumn,
- &gScreenDimensions.BottomRow
- );
-
- if (ScreenDimensions != NULL) {
- //
- // Check local dimension vs. global dimension.
- //
- if ((gScreenDimensions.RightColumn < ScreenDimensions->RightColumn) ||
- (gScreenDimensions.BottomRow < ScreenDimensions->BottomRow)
- ) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- } else {
- //
- // Local dimension validation.
- //
- if ((ScreenDimensions->RightColumn > ScreenDimensions->LeftColumn) &&
- (ScreenDimensions->BottomRow > ScreenDimensions->TopRow) &&
- ((ScreenDimensions->RightColumn - ScreenDimensions->LeftColumn) > 2) &&
- (
- (ScreenDimensions->BottomRow - ScreenDimensions->TopRow) > STATUS_BAR_HEIGHT +
- SCROLL_ARROW_HEIGHT *
- 2 +
- FRONT_PAGE_HEADER_HEIGHT +
- gFooterHeight +
- 1
- )
- ) {
- CopyMem (&gScreenDimensions, (VOID *) ScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
- } else {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
- }
- }
-
- gOptionBlockWidth = (CHAR16) ((gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn) / 3);
- gPromptBlockWidth = (CHAR16) (gOptionBlockWidth + LEFT_SKIPPED_COLUMNS);
- gHelpBlockWidth = (CHAR16) (gOptionBlockWidth - LEFT_SKIPPED_COLUMNS);
-
- //
- // Initialize the strings for the browser, upon exit of the browser, the strings will be freed
- //
- InitializeBrowserStrings ();
-
- //
- // Ensure we are in Text mode
- //
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
+ gExitRequired = FALSE;
+ Status = EFI_SUCCESS;
+ gEmptyString = L"";
+ gDisplayFormData.ScreenDimensions = (EFI_SCREEN_DESCRIPTOR *) ScreenDimensions;
for (Index = 0; Index < HandleCount; Index++) {
Selection = AllocateZeroPool (sizeof (UI_MENU_SELECTION));
@@ -335,7 +382,7 @@ SendForm (
//
// Initialize internal data structures of FormSet
//
- Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet, TRUE);
+ Status = InitializeFormSet (Selection->Handle, &Selection->FormSetGuid, FormSet);
if (EFI_ERROR (Status) || IsListEmpty (&FormSet->FormListHead)) {
DestroyFormSet (FormSet);
break;
@@ -343,11 +390,6 @@ SendForm (
Selection->FormSet = FormSet;
//
- // Try to find pre FormSet in the maintain backup list.
- //
- gOldFormSet = GetFormSetFromHiiHandle (Selection->Handle);
-
- //
// Display this formset
//
gCurrentSelection = Selection;
@@ -356,27 +398,36 @@ SendForm (
gCurrentSelection = NULL;
- if (EFI_ERROR (Status)) {
- break;
- }
-
- } while (Selection->Action == UI_ACTION_REFRESH_FORMSET);
-
- if (gOldFormSet != NULL) {
//
// If no data is changed, don't need to save current FormSet into the maintain list.
//
- if (!IsNvUpdateRequired (gOldFormSet)) {
- CleanBrowserStorage(gOldFormSet);
- RemoveEntryList (&gOldFormSet->Link);
- DestroyFormSet (gOldFormSet);
+ if (!IsNvUpdateRequiredForFormSet (FormSet) && !IsStorageDataChangedForFormSet(FormSet)) {
+ CleanBrowserStorage(FormSet);
+ RemoveEntryList (&FormSet->Link);
+ DestroyFormSet (FormSet);
}
- gOldFormSet = NULL;
- }
+
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ } while (Selection->Action == UI_ACTION_REFRESH_FORMSET);
FreePool (Selection);
}
+ //
+ // Still has error info, pop up a message.
+ //
+ if (gBrowserStatus != BROWSER_SUCCESS) {
+ gDisplayFormData.BrowserStatus = gBrowserStatus;
+ gDisplayFormData.ErrorString = gErrorInfo;
+
+ gBrowserStatus = BROWSER_SUCCESS;
+ gErrorInfo = NULL;
+
+ mFormDisplay->FormDisplay (&gDisplayFormData, NULL);
+ }
+
if (ActionRequest != NULL) {
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
if (gResetRequired) {
@@ -384,13 +435,17 @@ SendForm (
}
}
- FreeBrowserStrings ();
- UiFreeMenuList(&gMenuList);
+ mFormDisplay->ExitDisplay();
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- gST->ConOut->ClearScreen (gST->ConOut);
+ //
+ // Clear the menu history data.
+ //
+ while (!IsListEmpty (&mPrivateData.FormBrowserEx2.FormViewHistoryHead)) {
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (mPrivateData.FormBrowserEx2.FormViewHistoryHead.ForwardLink);
+ RemoveEntryList (&MenuList->Link);
+ FreePool (MenuList);
+ }
-Done:
//
// Restore globals used by SendForm()
//
@@ -399,10 +454,93 @@ Done:
return Status;
}
+/**
+ Get or set data to the storage.
+
+ @param ResultsDataSize The size of the buffer associatedwith ResultsData.
+ @param ResultsData A string returned from an IFR browser or
+ equivalent. The results string will have no
+ routing information in them.
+ @param RetrieveData A BOOLEAN field which allows an agent to retrieve
+ (if RetrieveData = TRUE) data from the uncommitted
+ browser state information or set (if RetrieveData
+ = FALSE) data in the uncommitted browser state
+ information.
+ @param Storage The pointer to the storage.
+
+ @retval EFI_SUCCESS The results have been distributed or are awaiting
+ distribution.
+
+**/
+EFI_STATUS
+ProcessStorage (
+ IN OUT UINTN *ResultsDataSize,
+ IN OUT EFI_STRING *ResultsData,
+ IN BOOLEAN RetrieveData,
+ IN BROWSER_STORAGE *Storage
+ )
+{
+ CHAR16 *ConfigResp;
+ EFI_STATUS Status;
+ CHAR16 *StrPtr;
+ UINTN BufferSize;
+ UINTN TmpSize;
+
+ if (RetrieveData) {
+ //
+ // Generate <ConfigResp>
+ //
+ Status = StorageToConfigResp (Storage, &ConfigResp, Storage->ConfigRequest, TRUE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Skip <ConfigHdr> and '&' to point to <ConfigBody> when first copy the configbody.
+ // Also need to consider add "\0" at first time.
+ //
+ StrPtr = ConfigResp + StrLen (Storage->ConfigHdr) + 1;
+ BufferSize = StrSize (StrPtr);
+
+
+ //
+ // Copy the data if the input buffer is bigger enough.
+ //
+ if (*ResultsDataSize >= BufferSize) {
+ StrCpy (*ResultsData, StrPtr);
+ }
+
+ *ResultsDataSize = BufferSize;
+ FreePool (ConfigResp);
+ } else {
+ //
+ // Prepare <ConfigResp>
+ //
+ TmpSize = StrLen (*ResultsData);
+ BufferSize = (TmpSize + StrLen (Storage->ConfigHdr) + 2) * sizeof (CHAR16);
+ ConfigResp = AllocateZeroPool (BufferSize);
+ ASSERT (ConfigResp != NULL);
+
+ StrCpy (ConfigResp, Storage->ConfigHdr);
+ StrCat (ConfigResp, L"&");
+ StrCat (ConfigResp, *ResultsData);
+
+ //
+ // Update Browser uncommited data
+ //
+ Status = ConfigRespToStorage (Storage, ConfigResp);
+ FreePool (ConfigResp);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
/**
- This function is called by a callback handler to retrieve uncommitted state
- data from the browser.
+ This routine called this service in the browser to retrieve or set certain uncommitted
+ state information that resides in the open formsets.
@param This A pointer to the EFI_FORM_BROWSER2_PROTOCOL
instance.
@@ -440,60 +578,69 @@ BrowserCallback (
{
EFI_STATUS Status;
LIST_ENTRY *Link;
- FORMSET_STORAGE *Storage;
+ BROWSER_STORAGE *Storage;
+ FORMSET_STORAGE *FormsetStorage;
FORM_BROWSER_FORMSET *FormSet;
+ UINTN TotalSize;
BOOLEAN Found;
- CHAR16 *ConfigResp;
- CHAR16 *StrPtr;
- UINTN BufferSize;
- UINTN TmpSize;
if (ResultsDataSize == NULL || ResultsData == NULL) {
return EFI_INVALID_PARAMETER;
}
- if (gCurrentSelection == NULL) {
- return EFI_NOT_READY;
- }
-
- Storage = NULL;
- ConfigResp = NULL;
- FormSet = gCurrentSelection->FormSet;
+ TotalSize = *ResultsDataSize;
+ Storage = NULL;
+ Found = FALSE;
+ Status = EFI_SUCCESS;
//
- // Find target storage
+ // If set browser data, pre load all hii formset to avoid set the varstore which is not
+ // saved in browser.
//
- Link = GetFirstNode (&FormSet->StorageListHead);
- if (IsNull (&FormSet->StorageListHead, Link)) {
- return EFI_UNSUPPORTED;
+ if (!RetrieveData && (gBrowserSettingScope == SystemLevel)) {
+ LoadAllHiiFormset();
}
if (VariableGuid != NULL) {
//
- // Try to find target storage
+ // Try to find target storage in the current formset.
//
- Found = FALSE;
- while (!IsNull (&FormSet->StorageListHead, Link)) {
- Storage = FORMSET_STORAGE_FROM_LINK (Link);
- Link = GetNextNode (&FormSet->StorageListHead, Link);
+ Link = GetFirstNode (&gBrowserStorageList);
+ while (!IsNull (&gBrowserStorageList, Link)) {
+ Storage = BROWSER_STORAGE_FROM_LINK (Link);
+ Link = GetNextNode (&gBrowserStorageList, Link);
+ //
+ // Check the current storage.
+ //
+ if (!CompareGuid (&Storage->Guid, (EFI_GUID *) VariableGuid)) {
+ continue;
+ }
- if (CompareGuid (&Storage->BrowserStorage->Guid, (EFI_GUID *) VariableGuid)) {
- if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_BUFFER ||
- Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- //
- // Buffer storage require both GUID and Name
- //
- if (VariableName == NULL) {
- return EFI_NOT_FOUND;
- }
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
+ //
+ // Buffer storage require both GUID and Name
+ //
+ if (VariableName == NULL) {
+ return EFI_NOT_FOUND;
+ }
- if (StrCmp (Storage->BrowserStorage->Name, (CHAR16 *) VariableName) != 0) {
- continue;
- }
+ if (StrCmp (Storage->Name, (CHAR16 *) VariableName) != 0) {
+ continue;
}
- Found = TRUE;
- break;
}
+
+ Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, Storage);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Different formsets may have same varstore, so here just set the flag
+ // not exit the circle.
+ //
+ Found = TRUE;
+ break;
}
if (!Found) {
@@ -503,65 +650,62 @@ BrowserCallback (
//
// GUID/Name is not specified, take the first storage in FormSet
//
- Storage = FORMSET_STORAGE_FROM_LINK (Link);
- }
-
- if (RetrieveData) {
- //
- // Skip if there is no RequestElement
- //
- if (Storage->ElementCount == 0) {
- return EFI_SUCCESS;
+ if (gCurrentSelection == NULL) {
+ return EFI_NOT_READY;
}
//
// Generate <ConfigResp>
//
- Status = StorageToConfigResp (Storage->BrowserStorage, &ConfigResp, Storage->ConfigRequest);
+ FormSet = gCurrentSelection->FormSet;
+ Link = GetFirstNode (&FormSet->StorageListHead);
+ if (IsNull (&FormSet->StorageListHead, Link)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ FormsetStorage = FORMSET_STORAGE_FROM_LINK (Link);
+
+ Status = ProcessStorage (&TotalSize, &ResultsData, RetrieveData, FormsetStorage->BrowserStorage);
if (EFI_ERROR (Status)) {
return Status;
}
+ }
- //
- // Skip <ConfigHdr> and '&' to point to <ConfigBody>
- //
- StrPtr = ConfigResp + StrLen (Storage->BrowserStorage->ConfigHdr) + 1;
+ if (RetrieveData) {
+ Status = TotalSize <= *ResultsDataSize ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
+ *ResultsDataSize = TotalSize;
+ }
+
+ return Status;
- BufferSize = StrSize (StrPtr);
- if (*ResultsDataSize < BufferSize) {
- *ResultsDataSize = BufferSize;
+}
- FreePool (ConfigResp);
- return EFI_BUFFER_TOO_SMALL;
- }
- *ResultsDataSize = BufferSize;
- CopyMem (ResultsData, StrPtr, BufferSize);
+/**
+ Callback function for SimpleTextInEx protocol install events
- FreePool (ConfigResp);
- } else {
- //
- // Prepare <ConfigResp>
- //
- TmpSize = StrLen (ResultsData);
- BufferSize = (TmpSize + StrLen (Storage->BrowserStorage->ConfigHdr) + 2) * sizeof (CHAR16);
- ConfigResp = AllocateZeroPool (BufferSize);
- ASSERT (ConfigResp != NULL);
+ @param Event the event that is signaled.
+ @param Context not used here.
- StrCpy (ConfigResp, Storage->BrowserStorage->ConfigHdr);
- StrCat (ConfigResp, L"&");
- StrCat (ConfigResp, ResultsData);
+**/
+VOID
+EFIAPI
+FormDisplayCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
- //
- // Update Browser uncommited data
- //
- Status = ConfigRespToStorage (Storage->BrowserStorage, ConfigResp);
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ if (mFormDisplay != NULL) {
+ return;
}
- return EFI_SUCCESS;
+ Status = gBS->LocateProtocol (
+ &gEdkiiFormDisplayEngineProtocolGuid,
+ NULL,
+ (VOID **) &mFormDisplay
+ );
}
/**
@@ -582,8 +726,7 @@ InitializeSetup (
)
{
EFI_STATUS Status;
- EFI_INPUT_KEY DefaultHotKey;
- EFI_STRING HelpString;
+ VOID *Registration;
//
// Locate required Hii relative protocols
@@ -596,13 +739,6 @@ InitializeSetup (
ASSERT_EFI_ERROR (Status);
Status = gBS->LocateProtocol (
- &gEfiHiiStringProtocolGuid,
- NULL,
- (VOID **) &mHiiString
- );
- ASSERT_EFI_ERROR (Status);
-
- Status = gBS->LocateProtocol (
&gEfiHiiConfigRoutingProtocolGuid,
NULL,
(VOID **) &mHiiConfigRouting
@@ -616,30 +752,6 @@ InitializeSetup (
);
//
- // Publish our HII data
- //
- gHiiHandle = HiiAddPackages (
- &gSetupBrowserGuid,
- ImageHandle,
- SetupBrowserStrings,
- NULL
- );
- ASSERT (gHiiHandle != NULL);
-
- //
- // Initialize Driver private data
- //
- gBannerData = AllocateZeroPool (sizeof (BANNER_DATA));
- ASSERT (gBannerData != NULL);
-
- //
- // Initialize generic help strings.
- //
- gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);
- gDiscardFailed = GetToken (STRING_TOKEN (DISCARD_FAILED), gHiiHandle);
- gDefaultFailed = GetToken (STRING_TOKEN (DEFAULT_FAILED), gHiiHandle);
-
- //
// Install FormBrowser2 protocol
//
mPrivateData.Handle = NULL;
@@ -652,34 +764,45 @@ InitializeSetup (
ASSERT_EFI_ERROR (Status);
//
- // Install default HotKey F10 for Save
- //
- DefaultHotKey.UnicodeChar = CHAR_NULL;
- HelpString = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);
- DefaultHotKey.ScanCode = SCAN_F10;
- RegisterHotKey (&DefaultHotKey, BROWSER_ACTION_SUBMIT, 0, HelpString);
- FreePool (HelpString);
- //
- // Install default HotKey F9 for Reset To Defaults
- //
- DefaultHotKey.ScanCode = SCAN_F9;
- HelpString = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);
- RegisterHotKey (&DefaultHotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, HelpString);
- FreePool (HelpString);
-
- //
- // Install FormBrowserEx protocol
+ // Install FormBrowserEx2 protocol
//
+ InitializeListHead (&mPrivateData.FormBrowserEx2.FormViewHistoryHead);
mPrivateData.Handle = NULL;
Status = gBS->InstallProtocolInterface (
&mPrivateData.Handle,
+ &gEdkiiFormBrowserEx2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mPrivateData.FormBrowserEx2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->InstallProtocolInterface (
+ &mPrivateData.Handle,
&gEfiFormBrowserExProtocolGuid,
EFI_NATIVE_INTERFACE,
&mPrivateData.FormBrowserEx
);
ASSERT_EFI_ERROR (Status);
- return Status;
+ InitializeDisplayFormData ();
+
+ Status = gBS->LocateProtocol (
+ &gEdkiiFormDisplayEngineProtocolGuid,
+ NULL,
+ (VOID **) &mFormDisplay
+ );
+
+ if (EFI_ERROR (Status)) {
+ EfiCreateProtocolNotifyEvent (
+ &gEdkiiFormDisplayEngineProtocolGuid,
+ TPL_CALLBACK,
+ FormDisplayCallback,
+ NULL,
+ &Registration
+ );
+ }
+
+ return EFI_SUCCESS;
}
@@ -815,58 +938,6 @@ NewStringCat (
*Dest = NewString;
}
-
-/**
- Synchronize or restore Storage's Edit copy and Shadow copy.
-
- @param Storage The Storage to be synchronized.
- @param SyncOrRestore Sync the buffer to editbuffer or Restore the
- editbuffer to buffer
- if TRUE, copy the editbuffer to the buffer.
- if FALSE, copy the buffer to the editbuffer.
-
-**/
-VOID
-SynchronizeStorage (
- IN BROWSER_STORAGE *Storage,
- IN BOOLEAN SyncOrRestore
- )
-{
- LIST_ENTRY *Link;
- NAME_VALUE_NODE *Node;
-
- switch (Storage->Type) {
- case EFI_HII_VARSTORE_BUFFER:
- case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
- if (SyncOrRestore) {
- CopyMem (Storage->Buffer, Storage->EditBuffer, Storage->Size);
- } else {
- CopyMem (Storage->EditBuffer, Storage->Buffer, Storage->Size);
- }
- break;
-
- case EFI_HII_VARSTORE_NAME_VALUE:
- Link = GetFirstNode (&Storage->NameValueListHead);
- while (!IsNull (&Storage->NameValueListHead, Link)) {
- Node = NAME_VALUE_NODE_FROM_LINK (Link);
-
- if (SyncOrRestore) {
- NewStringCpy (&Node->Value, Node->EditValue);
- } else {
- NewStringCpy (&Node->EditValue, Node->Value);
- }
-
- Link = GetNextNode (&Storage->NameValueListHead, Link);
- }
- break;
-
- case EFI_HII_VARSTORE_EFI_VARIABLE:
- default:
- break;
- }
-}
-
-
/**
Get Value for given Name from a NameValue Storage.
@@ -923,6 +994,7 @@ GetValueByName (
@param Name The Name.
@param Value The Value to set.
@param SetValueTo Whether update editValue or Value.
+ @param ReturnNode The node use the input name.
@retval EFI_SUCCESS Value found for given Name.
@retval EFI_NOT_FOUND No such Name found in NameValue storage.
@@ -930,10 +1002,11 @@ GetValueByName (
**/
EFI_STATUS
SetValueByName (
- IN BROWSER_STORAGE *Storage,
- IN CHAR16 *Name,
- IN CHAR16 *Value,
- IN GET_SET_QUESTION_VALUE_WITH SetValueTo
+ IN BROWSER_STORAGE *Storage,
+ IN CHAR16 *Name,
+ IN CHAR16 *Value,
+ IN GET_SET_QUESTION_VALUE_WITH SetValueTo,
+ OUT NAME_VALUE_NODE **ReturnNode
)
{
LIST_ENTRY *Link;
@@ -964,6 +1037,11 @@ SetValueByName (
} else {
Node->Value = Buffer;
}
+
+ if (ReturnNode != NULL) {
+ *ReturnNode = Node;
+ }
+
return EFI_SUCCESS;
}
@@ -980,6 +1058,7 @@ SetValueByName (
@param Storage The Storage to be conveted.
@param ConfigResp The returned <ConfigResp>.
@param ConfigRequest The ConfigRequest string.
+ @param GetEditBuf Get the data from editbuffer or buffer.
@retval EFI_SUCCESS Convert success.
@retval EFI_INVALID_PARAMETER Incorrect storage type.
@@ -989,23 +1068,26 @@ EFI_STATUS
StorageToConfigResp (
IN BROWSER_STORAGE *Storage,
IN CHAR16 **ConfigResp,
- IN CHAR16 *ConfigRequest
+ IN CHAR16 *ConfigRequest,
+ IN BOOLEAN GetEditBuf
)
{
EFI_STATUS Status;
EFI_STRING Progress;
LIST_ENTRY *Link;
NAME_VALUE_NODE *Node;
+ UINT8 *SourceBuf;
Status = EFI_SUCCESS;
switch (Storage->Type) {
case EFI_HII_VARSTORE_BUFFER:
case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
+ SourceBuf = GetEditBuf ? Storage->EditBuffer : Storage->Buffer;
Status = mHiiConfigRouting->BlockToConfig (
mHiiConfigRouting,
ConfigRequest,
- Storage->EditBuffer,
+ SourceBuf,
Storage->Size,
ConfigResp,
&Progress
@@ -1024,7 +1106,11 @@ StorageToConfigResp (
NewStringCat (ConfigResp, L"&");
NewStringCat (ConfigResp, Node->Name);
NewStringCat (ConfigResp, L"=");
- NewStringCat (ConfigResp, Node->EditValue);
+ if (GetEditBuf) {
+ NewStringCat (ConfigResp, Node->EditValue);
+ } else {
+ NewStringCat (ConfigResp, Node->Value);
+ }
}
Link = GetNextNode (&Storage->NameValueListHead, Link);
}
@@ -1105,7 +1191,7 @@ ConfigRespToStorage (
if (StrPtr != NULL) {
*StrPtr = 0;
}
- SetValueByName (Storage, Name, Value, GetSetValueWithEditBuffer);
+ SetValueByName (Storage, Name, Value, GetSetValueWithEditBuffer, NULL);
}
break;
@@ -1531,7 +1617,7 @@ GetQuestionValue (
if (IsBufferStorage) {
CopyMem (Storage->EditBuffer + Question->VarStoreInfo.VarOffset, Dst, StorageWidth);
} else {
- SetValueByName (Storage, Question->VariableName, Value, GetSetValueWithEditBuffer);
+ SetValueByName (Storage, Question->VariableName, Value, GetSetValueWithEditBuffer, NULL);
}
if (Result != NULL) {
@@ -1581,8 +1667,10 @@ SetQuestionValue (
CHAR16 *TemName;
CHAR16 *TemString;
UINTN Index;
+ NAME_VALUE_NODE *Node;
Status = EFI_SUCCESS;
+ Node = NULL;
if (SetValueTo >= GetSetValueWithMax) {
return EFI_INVALID_PARAMETER;
@@ -1717,6 +1805,14 @@ SetQuestionValue (
//
CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);
}
+ //
+ // Check whether question value has been changed.
+ //
+ if (CompareMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Storage->EditBuffer + Question->VarStoreInfo.VarOffset, StorageWidth) != 0) {
+ Question->ValueChanged = TRUE;
+ } else {
+ Question->ValueChanged = FALSE;
+ }
} else {
if (IsString) {
//
@@ -1748,8 +1844,19 @@ SetQuestionValue (
}
}
- Status = SetValueByName (Storage, Question->VariableName, Value, SetValueTo);
+ Status = SetValueByName (Storage, Question->VariableName, Value, SetValueTo, &Node);
FreePool (Value);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Check whether question value has been changed.
+ //
+ if (StrCmp (Node->Value, Node->EditValue) != 0) {
+ Question->ValueChanged = TRUE;
+ } else {
+ Question->ValueChanged = FALSE;
+ }
}
} else if (SetValueTo == GetSetValueWithHiiDriver) {
if (Storage->Type == EFI_HII_VARSTORE_BUFFER || Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
@@ -1868,12 +1975,12 @@ SetQuestionValue (
/**
- Perform inconsistent check for a Form.
+ Perform nosubmitif check for a Form.
@param FormSet FormSet data structure.
@param Form Form data structure.
@param Question The Question to be validated.
- @param Type Validation type: InConsistent or NoSubmit
+ @param Type Validation type: NoSubmit
@retval EFI_SUCCESS Form validation pass.
@retval other Form validation failed.
@@ -1891,12 +1998,9 @@ ValidateQuestion (
LIST_ENTRY *Link;
LIST_ENTRY *ListHead;
EFI_STRING PopUp;
- EFI_INPUT_KEY Key;
FORM_EXPRESSION *Expression;
- if (Type == EFI_HII_EXPRESSION_INCONSISTENT_IF) {
- ListHead = &Question->InconsistentListHead;
- } else if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {
+ if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {
ListHead = &Question->NoSubmitListHead;
} else {
return EFI_UNSUPPORTED;
@@ -1920,10 +2024,10 @@ ValidateQuestion (
//
if (Expression->Error != 0) {
PopUp = GetToken (Expression->Error, FormSet->HiiHandle);
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, PopUp, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- FreePool (PopUp);
+ if (Type == EFI_HII_EXPRESSION_NO_SUBMIT_IF) {
+ gBrowserStatus = BROWSER_NO_SUBMIT_IF;
+ gErrorInfo = PopUp;
+ }
}
return EFI_NOT_READY;
@@ -1987,7 +2091,8 @@ NoSubmitCheck (
Fill storage's edit copy with settings requested from Configuration Driver.
@param FormSet FormSet data structure.
- @param ConfigInfo The config info related to this form.
+ @param Storage The storage which need to sync.
+ @param ConfigRequest The config request string which used to sync storage.
@param SyncOrRestore Sync the buffer to editbuffer or Restore the
editbuffer to buffer
if TRUE, copy the editbuffer to the buffer.
@@ -1997,10 +2102,11 @@ NoSubmitCheck (
**/
EFI_STATUS
-SynchronizeStorageForForm (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN FORM_BROWSER_CONFIG_REQUEST *ConfigInfo,
- IN BOOLEAN SyncOrRestore
+SynchronizeStorage (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ OUT BROWSER_STORAGE *Storage,
+ IN CHAR16 *ConfigRequest,
+ IN BOOLEAN SyncOrRestore
)
{
EFI_STATUS Status;
@@ -2014,57 +2120,52 @@ SynchronizeStorageForForm (
Status = EFI_SUCCESS;
Result = NULL;
- if (FormSet->ConfigAccess == NULL && ConfigInfo->Storage->Type != EFI_HII_VARSTORE_NAME_VALUE) {
- return EFI_NOT_FOUND;
- }
- if (ConfigInfo->ElementCount == 0) {
- //
- // Skip if there is no RequestElement
- //
- return EFI_SUCCESS;
- }
-
- if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_BUFFER ||
- (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
- BufferSize = ConfigInfo->Storage->Size;
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
+ BufferSize = Storage->Size;
if (SyncOrRestore) {
- Src = ConfigInfo->Storage->EditBuffer;
- Dst = ConfigInfo->Storage->Buffer;
+ Src = Storage->EditBuffer;
+ Dst = Storage->Buffer;
} else {
- Src = ConfigInfo->Storage->Buffer;
- Dst = ConfigInfo->Storage->EditBuffer;
+ Src = Storage->Buffer;
+ Dst = Storage->EditBuffer;
}
- Status = mHiiConfigRouting->BlockToConfig(
- mHiiConfigRouting,
- ConfigInfo->ConfigRequest,
- Src,
- BufferSize,
- &Result,
- &Progress
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ if (ConfigRequest != NULL) {
+ Status = mHiiConfigRouting->BlockToConfig(
+ mHiiConfigRouting,
+ ConfigRequest,
+ Src,
+ BufferSize,
+ &Result,
+ &Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- Status = mHiiConfigRouting->ConfigToBlock (
- mHiiConfigRouting,
- Result,
- Dst,
- &BufferSize,
- &Progress
- );
- if (Result != NULL) {
- FreePool (Result);
+ Status = mHiiConfigRouting->ConfigToBlock (
+ mHiiConfigRouting,
+ Result,
+ Dst,
+ &BufferSize,
+ &Progress
+ );
+ if (Result != NULL) {
+ FreePool (Result);
+ }
+ } else {
+ CopyMem (Dst, Src, BufferSize);
}
- } else if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
- Link = GetFirstNode (&ConfigInfo->Storage->NameValueListHead);
- while (!IsNull (&ConfigInfo->Storage->NameValueListHead, Link)) {
+ } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
+ Link = GetFirstNode (&Storage->NameValueListHead);
+ while (!IsNull (&Storage->NameValueListHead, Link)) {
Node = NAME_VALUE_NODE_FROM_LINK (Link);
- if (StrStr (ConfigInfo->ConfigRequest, Node->Name) != NULL) {
+ if ((ConfigRequest != NULL && StrStr (ConfigRequest, Node->Name) != NULL) ||
+ (ConfigRequest == NULL)) {
if (SyncOrRestore) {
NewStringCpy (&Node->Value, Node->EditValue);
} else {
@@ -2072,7 +2173,7 @@ SynchronizeStorageForForm (
}
}
- Link = GetNextNode (&ConfigInfo->Storage->NameValueListHead, Link);
+ Link = GetNextNode (&Storage->NameValueListHead, Link);
}
}
@@ -2095,20 +2196,9 @@ SendDiscardInfoToDriver (
{
LIST_ENTRY *Link;
FORM_BROWSER_STATEMENT *Question;
- EFI_STATUS Status;
- EFI_HII_VALUE HiiValue;
- UINT8 *BufferValue;
- BOOLEAN ValueChanged;
EFI_IFR_TYPE_VALUE *TypeValue;
EFI_BROWSER_ACTION_REQUEST ActionRequest;
- ValueChanged = FALSE;
- BufferValue = NULL;
-
- if(!Form->NvUpdateRequired) {
- return;
- }
-
Link = GetFirstNode (&Form->StatementListHead);
while (!IsNull (&Form->StatementListHead, Link)) {
Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
@@ -2122,45 +2212,10 @@ SendDiscardInfoToDriver (
continue;
}
- if (Question->BufferValue != NULL) {
- BufferValue = AllocateZeroPool (Question->StorageWidth);
- ASSERT (BufferValue != NULL);
- CopyMem (BufferValue, Question->BufferValue, Question->StorageWidth);
- } else {
- HiiValue.Type = Question->HiiValue.Type;
- CopyMem (&HiiValue.Value, &Question->HiiValue.Value, sizeof (EFI_IFR_TYPE_VALUE));
- }
-
- Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithBuffer);
- if (EFI_ERROR (Status)) {
- if (BufferValue != NULL) {
- FreePool (BufferValue);
- BufferValue = NULL;
- }
- continue;
- }
-
- if (Question->BufferValue != NULL) {
- if (CompareMem (BufferValue, Question->BufferValue, Question->StorageWidth)) {
- ValueChanged = TRUE;
- }
- } else {
- if (CompareMem (&HiiValue.Value, &Question->HiiValue.Value, sizeof (EFI_IFR_TYPE_VALUE))) {
- ValueChanged = TRUE;
- }
- }
-
- if (BufferValue != NULL) {
- FreePool (BufferValue);
- BufferValue = NULL;
- }
-
- if (!ValueChanged) {
+ if (!Question->ValueChanged) {
continue;
}
- ValueChanged = FALSE;
-
if (Question->HiiValue.Type == EFI_IFR_TYPE_BUFFER) {
TypeValue = (EFI_IFR_TYPE_VALUE *) Question->BufferValue;
} else {
@@ -2225,6 +2280,78 @@ ValidateFormSet (
return Find;
}
+/**
+ Check whether need to enable the reset flag in form level.
+ Also clean all ValueChanged flag in question.
+
+ @param SetFlag Whether need to set the Reset Flag.
+ @param Form Form data structure.
+
+**/
+VOID
+UpdateFlagForForm (
+ IN BOOLEAN SetFlag,
+ IN FORM_BROWSER_FORM *Form
+ )
+{
+ LIST_ENTRY *Link;
+ FORM_BROWSER_STATEMENT *Question;
+ BOOLEAN FindOne;
+
+ FindOne = FALSE;
+ Link = GetFirstNode (&Form->StatementListHead);
+ while (!IsNull (&Form->StatementListHead, Link)) {
+ Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
+
+ if (SetFlag && Question->ValueChanged && ((Question->QuestionFlags & EFI_IFR_FLAG_RESET_REQUIRED) != 0)) {
+ gResetRequired = TRUE;
+ }
+
+ if (Question->ValueChanged) {
+ Question->ValueChanged = FALSE;
+ }
+
+ Link = GetNextNode (&Form->StatementListHead, Link);
+ }
+}
+
+/**
+ Check whether need to enable the reset flag.
+ Also clean ValueChanged flag for all statements.
+
+ Form level or formset level, only one.
+
+ @param SetFlag Whether need to set the Reset Flag.
+ @param FormSet FormSet data structure.
+ @param Form Form data structure.
+
+**/
+VOID
+ValueChangeResetFlagUpdate (
+ IN BOOLEAN SetFlag,
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN FORM_BROWSER_FORM *Form
+ )
+{
+ FORM_BROWSER_FORM *CurrentForm;
+ LIST_ENTRY *Link;
+
+ //
+ // Form != NULL means only check form level.
+ //
+ if (Form != NULL) {
+ UpdateFlagForForm(SetFlag, Form);
+ return;
+ }
+
+ Link = GetFirstNode (&FormSet->FormListHead);
+ while (!IsNull (&FormSet->FormListHead, Link)) {
+ CurrentForm = FORM_BROWSER_FORM_FROM_LINK (Link);
+ Link = GetNextNode (&FormSet->FormListHead, Link);
+
+ UpdateFlagForForm(SetFlag, CurrentForm);
+ }
+}
/**
Discard data based on the input setting scope (Form, FormSet or System).
@@ -2256,7 +2383,7 @@ DiscardForm (
return EFI_UNSUPPORTED;
}
- if (SettingScope == FormLevel && Form->NvUpdateRequired) {
+ if (SettingScope == FormLevel && IsNvUpdateRequiredForForm (Form)) {
ConfigInfo = NULL;
Link = GetFirstNode (&Form->ConfigRequestHead);
while (!IsNull (&Form->ConfigRequestHead, Link)) {
@@ -2277,7 +2404,7 @@ DiscardForm (
//
// Prepare <ConfigResp>
//
- SynchronizeStorageForForm(FormSet, ConfigInfo, FALSE);
+ SynchronizeStorage(FormSet, ConfigInfo->Storage, ConfigInfo->ConfigRequest, FALSE);
//
// Call callback with Changed type to inform the driver.
@@ -2285,8 +2412,8 @@ DiscardForm (
SendDiscardInfoToDriver (FormSet, Form);
}
- Form->NvUpdateRequired = FALSE;
- } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {
+ ValueChangeResetFlagUpdate (FALSE, NULL, Form);
+ } else if (SettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet (FormSet)) {
//
// Discard Buffer storage or Name/Value storage
@@ -2307,7 +2434,7 @@ DiscardForm (
continue;
}
- SynchronizeStorage(Storage->BrowserStorage, FALSE);
+ SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigRequest, FALSE);
}
Link = GetFirstNode (&FormSet->FormListHead);
@@ -2321,7 +2448,7 @@ DiscardForm (
SendDiscardInfoToDriver (FormSet, Form);
}
- UpdateNvInfoInForm (FormSet, FALSE);
+ ValueChangeResetFlagUpdate(FALSE, FormSet, NULL);
} else if (SettingScope == SystemLevel) {
//
// System Level Discard.
@@ -2401,7 +2528,7 @@ SubmitForm (
return Status;
}
- if (SettingScope == FormLevel && Form->NvUpdateRequired) {
+ if (SettingScope == FormLevel && IsNvUpdateRequiredForForm (Form)) {
ConfigInfo = NULL;
Link = GetFirstNode (&Form->ConfigRequestHead);
while (!IsNull (&Form->ConfigRequestHead, Link)) {
@@ -2423,7 +2550,7 @@ SubmitForm (
//
// 1. Prepare <ConfigResp>
//
- Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest);
+ Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest, TRUE);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -2499,14 +2626,14 @@ SubmitForm (
//
// 3. Config success, update storage shadow Buffer, only update the data belong to this form.
//
- SynchronizeStorageForForm(FormSet, ConfigInfo, TRUE);
+ SynchronizeStorage (FormSet, ConfigInfo->Storage, ConfigInfo->ConfigRequest, TRUE);
}
//
// 4. Update the NV flag.
//
- Form->NvUpdateRequired = FALSE;
- } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {
+ ValueChangeResetFlagUpdate(TRUE, NULL, Form);
+ } else if (SettingScope == FormSetLevel && IsNvUpdateRequiredForFormSet (FormSet)) {
//
// Submit Buffer storage or Name/Value storage
//
@@ -2530,7 +2657,7 @@ SubmitForm (
//
// 1. Prepare <ConfigResp>
//
- Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest);
+ Status = StorageToConfigResp (Storage, &ConfigResp, FormSetStorage->ConfigRequest, TRUE);
if (EFI_ERROR (Status)) {
return Status;
}
@@ -2602,13 +2729,13 @@ SubmitForm (
//
// 3. Config success, update storage shadow Buffer
//
- SynchronizeStorage (Storage, TRUE);
+ SynchronizeStorage (FormSet, Storage, FormSetStorage->ConfigRequest, TRUE);
}
//
// 4. Update the NV flag.
//
- UpdateNvInfoInForm (FormSet, FALSE);
+ ValueChangeResetFlagUpdate(TRUE, FormSet, NULL);
} else if (SettingScope == SystemLevel) {
//
// System Level Save.
@@ -2864,6 +2991,138 @@ GetDefaultIdForCallBack (
}
}
+
+
+/**
+ Return data element in an Array by its Index.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+
+ @retval Value The data to be returned
+
+**/
+UINT64
+GetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index
+ )
+{
+ UINT64 Data;
+
+ ASSERT (Array != NULL);
+
+ Data = 0;
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ Data = (UINT64) *(((UINT8 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ Data = (UINT64) *(((UINT16 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ Data = (UINT64) *(((UINT32 *) Array) + Index);
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ Data = (UINT64) *(((UINT64 *) Array) + Index);
+ break;
+
+ default:
+ break;
+ }
+
+ return Data;
+}
+
+
+/**
+ Set value of a data element in an Array by its Index.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+ @param Value The value to be set.
+
+**/
+VOID
+SetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index,
+ IN UINT64 Value
+ )
+{
+
+ ASSERT (Array != NULL);
+
+ switch (Type) {
+ case EFI_IFR_TYPE_NUM_SIZE_8:
+ *(((UINT8 *) Array) + Index) = (UINT8) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_16:
+ *(((UINT16 *) Array) + Index) = (UINT16) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_32:
+ *(((UINT32 *) Array) + Index) = (UINT32) Value;
+ break;
+
+ case EFI_IFR_TYPE_NUM_SIZE_64:
+ *(((UINT64 *) Array) + Index) = (UINT64) Value;
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ Search an Option of a Question by its value.
+
+ @param Question The Question
+ @param OptionValue Value for Option to be searched.
+
+ @retval Pointer Pointer to the found Option.
+ @retval NULL Option not found.
+
+**/
+QUESTION_OPTION *
+ValueToOption (
+ IN FORM_BROWSER_STATEMENT *Question,
+ IN EFI_HII_VALUE *OptionValue
+ )
+{
+ LIST_ENTRY *Link;
+ QUESTION_OPTION *Option;
+ INTN Result;
+
+ Link = GetFirstNode (&Question->OptionListHead);
+ while (!IsNull (&Question->OptionListHead, Link)) {
+ Option = QUESTION_OPTION_FROM_LINK (Link);
+
+ if ((CompareHiiValue (&Option->Value, OptionValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
+ //
+ // Check the suppressif condition, only a valid option can be return.
+ //
+ if ((Option->SuppressExpression == NULL) ||
+ ((EvaluateExpressionList(Option->SuppressExpression, FALSE, NULL, NULL) == ExpressFalse))) {
+ return Option;
+ }
+ }
+
+ Link = GetNextNode (&Question->OptionListHead, Link);
+ }
+
+ return NULL;
+}
+
+
/**
Reset Question to its default value.
@@ -3155,11 +3414,7 @@ ExtractDefault (
LIST_ENTRY *FormLink;
LIST_ENTRY *Link;
FORM_BROWSER_STATEMENT *Question;
- FORM_BROWSER_FORMSET *BackUpFormSet;
FORM_BROWSER_FORMSET *LocalFormSet;
- EFI_HII_HANDLE *HiiHandles;
- UINTN Index;
- EFI_GUID ZeroGuid;
Status = EFI_SUCCESS;
@@ -3229,10 +3484,6 @@ ExtractDefault (
if ((Question->Storage != NULL) &&
(Question->Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE)) {
SetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
- //
- // Update Form NV flag.
- //
- Form->NvUpdateRequired = TRUE;
}
}
} else if (SettingScope == FormSetLevel) {
@@ -3244,65 +3495,9 @@ ExtractDefault (
}
} else if (SettingScope == SystemLevel) {
//
- // Open all FormSet by locate HII packages.
- // Initiliaze the maintain FormSet to store default data as back up data.
- //
- BackUpFormSet = gOldFormSet;
- gOldFormSet = NULL;
-
- //
- // Get all the Hii handles
- //
- HiiHandles = HiiGetHiiHandles (NULL);
- ASSERT (HiiHandles != NULL);
-
- //
- // Search for formset of each class type
- //
- for (Index = 0; HiiHandles[Index] != NULL; Index++) {
- //
- // Check HiiHandles[Index] does exist in global maintain list.
- //
- if (GetFormSetFromHiiHandle (HiiHandles[Index]) != NULL) {
- continue;
- }
-
- //
- // Initilize FormSet Setting
- //
- LocalFormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
- ASSERT (LocalFormSet != NULL);
- ZeroMem (&ZeroGuid, sizeof (ZeroGuid));
- Status = InitializeFormSet (HiiHandles[Index], &ZeroGuid, LocalFormSet, FALSE);
- if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {
- DestroyFormSet (LocalFormSet);
- continue;
- }
- Status = InitializeCurrentSetting (LocalFormSet);
- if (EFI_ERROR (Status)) {
- DestroyFormSet (LocalFormSet);
- continue;
- }
- //
- // Initilize Questions' Value
- //
- Status = LoadFormSetConfig (NULL, LocalFormSet);
- if (EFI_ERROR (Status)) {
- DestroyFormSet (LocalFormSet);
- continue;
- }
-
- //
- // Add FormSet into the maintain list.
- //
- InsertTailList (&gBrowserFormSetList, &LocalFormSet->Link);
- }
-
- //
- // Free resources, and restore gOldFormSet and gClassOfVfr
+ // Preload all Hii formset.
//
- FreePool (HiiHandles);
- gOldFormSet = BackUpFormSet;
+ LoadAllHiiFormset();
//
// Set Default Value for each FormSet in the maintain list.
@@ -3321,6 +3516,81 @@ ExtractDefault (
return EFI_SUCCESS;
}
+
+/**
+ Validate whether this question's value has changed.
+
+ @param FormSet FormSet data structure.
+ @param Form Form data structure.
+ @param Question Question to be initialized.
+ @param GetValueFrom Where to get value, may from editbuffer, buffer or hii driver.
+
+ @retval TRUE Question's value has changed.
+ @retval FALSE Question's value has not changed
+
+**/
+BOOLEAN
+IsQuestionValueChanged (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN FORM_BROWSER_FORM *Form,
+ IN OUT FORM_BROWSER_STATEMENT *Question,
+ IN GET_SET_QUESTION_VALUE_WITH GetValueFrom
+ )
+{
+ EFI_HII_VALUE BackUpValue;
+ CHAR8 *BackUpBuffer;
+ EFI_STATUS Status;
+ BOOLEAN ValueChanged;
+ UINTN BufferWidth;
+
+ //
+ // For quetion without storage, always mark it as data not changed.
+ //
+ if (Question->Storage == NULL && Question->Operand != EFI_IFR_TIME_OP && Question->Operand != EFI_IFR_DATE_OP) {
+ return FALSE;
+ }
+
+ BackUpBuffer = NULL;
+ ValueChanged = FALSE;
+
+ switch (Question->Operand) {
+ case EFI_IFR_ORDERED_LIST_OP:
+ BufferWidth = Question->StorageWidth;
+ BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);
+ ASSERT (BackUpBuffer != NULL);
+ break;
+
+ case EFI_IFR_STRING_OP:
+ case EFI_IFR_PASSWORD_OP:
+ BufferWidth = (UINTN) Question->Maximum * sizeof (CHAR16);
+ BackUpBuffer = AllocateCopyPool (BufferWidth, Question->BufferValue);
+ ASSERT (BackUpBuffer != NULL);
+ break;
+
+ default:
+ BufferWidth = 0;
+ break;
+ }
+ CopyMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE));
+
+ Status = GetQuestionValue (FormSet, Form, Question, GetValueFrom);
+ ASSERT_EFI_ERROR(Status);
+
+ if (CompareMem (&BackUpValue, &Question->HiiValue, sizeof (EFI_HII_VALUE)) != 0 ||
+ CompareMem (BackUpBuffer, Question->BufferValue, BufferWidth) != 0) {
+ ValueChanged = TRUE;
+ }
+
+ CopyMem (&Question->HiiValue, &BackUpValue, sizeof (EFI_HII_VALUE));
+ CopyMem (Question->BufferValue, BackUpBuffer, BufferWidth);
+
+ if (BackUpBuffer != NULL) {
+ FreePool (BackUpBuffer);
+ }
+
+ return ValueChanged;
+}
+
/**
Initialize Question's Edit copy from Storage.
@@ -3354,7 +3624,11 @@ LoadFormConfig (
//
// Initialize local copy of Value for each Question
//
- Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
+ if (Question->Operand == EFI_IFR_PASSWORD_OP && (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)== 0) {
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithHiiDriver);
+ } else {
+ Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
+ }
if (EFI_ERROR (Status)) {
return Status;
}
@@ -3394,6 +3668,11 @@ LoadFormConfig (
Status = ProcessCallBackFunction(Selection, Question, EFI_BROWSER_ACTION_RETRIEVE, TRUE);
}
+ //
+ // Update Question Value changed flag.
+ //
+ Question->ValueChanged = IsQuestionValueChanged(FormSet, Form, Question, GetSetValueWithBuffer);
+
Link = GetNextNode (&Form->StatementListHead, Link);
}
@@ -3437,6 +3716,11 @@ LoadFormSetConfig (
Link = GetNextNode (&FormSet->FormListHead, Link);
}
+ //
+ // Finished question initialization.
+ //
+ FormSet->QuestionInited = TRUE;
+
return EFI_SUCCESS;
}
@@ -3491,6 +3775,13 @@ RemoveConfigRequest (
CHAR16 *NextRequestElement;
CHAR16 *SearchKey;
+ //
+ // No request element in it, just return.
+ //
+ if (ConfigRequest == NULL) {
+ return;
+ }
+
if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
//
// "&Name1&Name2" section for EFI_HII_VARSTORE_NAME_VALUE storage
@@ -3565,6 +3856,7 @@ CleanBrowserStorage (
{
LIST_ENTRY *Link;
FORMSET_STORAGE *Storage;
+ CHAR16 *ConfigRequest;
Link = GetFirstNode (&FormSet->StorageListHead);
while (!IsNull (&FormSet->StorageListHead, Link)) {
@@ -3572,7 +3864,8 @@ CleanBrowserStorage (
Link = GetNextNode (&FormSet->StorageListHead, Link);
if ((Storage->BrowserStorage->Type != EFI_HII_VARSTORE_BUFFER) &&
- (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE)) {
+ (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_NAME_VALUE) &&
+ (Storage->BrowserStorage->Type != EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
continue;
}
@@ -3580,7 +3873,8 @@ CleanBrowserStorage (
continue;
}
- RemoveConfigRequest (Storage->BrowserStorage, Storage->ConfigRequest);
+ ConfigRequest = FormSet->QuestionInited ? Storage->ConfigRequest : Storage->ConfigElements;
+ RemoveConfigRequest (Storage->BrowserStorage, ConfigRequest);
}
}
@@ -3651,7 +3945,6 @@ AppendConfigRequest (
Adjust the config request info, remove the request elements which already in AllConfigRequest string.
@param Storage Form set Storage.
- @param ConfigRequest Return the ConfigRequest info.
@retval TRUE Has element not covered by current used elements, need to continue to call ExtractConfig
@retval FALSE All elements covered by current used elements.
@@ -3659,8 +3952,7 @@ AppendConfigRequest (
**/
BOOLEAN
ConfigRequestAdjust (
- IN FORMSET_STORAGE *Storage,
- OUT CHAR16 **ConfigRequest
+ IN FORMSET_STORAGE *Storage
)
{
CHAR16 *RequestElement;
@@ -3676,7 +3968,10 @@ ConfigRequestAdjust (
if (Storage->BrowserStorage->ConfigRequest == NULL) {
Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
- *ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
+ if (Storage->ConfigElements != NULL) {
+ FreePool (Storage->ConfigElements);
+ }
+ Storage->ConfigElements = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
return TRUE;
}
@@ -3745,7 +4040,10 @@ ConfigRequestAdjust (
}
if (RetVal) {
- *ConfigRequest = RetBuf;
+ if (Storage->ConfigElements != NULL) {
+ FreePool (Storage->ConfigElements);
+ }
+ Storage->ConfigElements = RetBuf;
} else {
FreePool (RetBuf);
}
@@ -3754,15 +4052,162 @@ ConfigRequestAdjust (
}
/**
+
+ Base on ConfigRequest info to get default value for current formset.
+
+ ConfigRequest info include the info about which questions in current formset need to
+ get default value. This function only get these questions default value.
+
+ @param FormSet FormSet data structure.
+ @param Storage Storage need to update value.
+ @param ConfigRequest The config request string.
+
+**/
+VOID
+GetDefaultForFormset (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN BROWSER_STORAGE *Storage,
+ IN CHAR16 *ConfigRequest
+ )
+{
+ UINT8 *BackUpBuf;
+ UINTN BufferSize;
+ LIST_ENTRY BackUpList;
+ NAME_VALUE_NODE *Node;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NodeLink;
+ NAME_VALUE_NODE *TmpNode;
+ EFI_STATUS Status;
+ EFI_STRING Progress;
+ EFI_STRING Result;
+
+ BackUpBuf = NULL;
+ InitializeListHead(&BackUpList);
+
+ //
+ // Back update the edit buffer.
+ //
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
+ BackUpBuf = AllocateCopyPool (Storage->Size, Storage->EditBuffer);
+ ASSERT (BackUpBuf != NULL);
+ } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
+ Link = GetFirstNode (&Storage->NameValueListHead);
+ while (!IsNull (&Storage->NameValueListHead, Link)) {
+ Node = NAME_VALUE_NODE_FROM_LINK (Link);
+ Link = GetNextNode (&Storage->NameValueListHead, Link);
+
+ //
+ // Only back Node belong to this formset.
+ //
+ if (StrStr (Storage->ConfigRequest, Node->Name) == NULL) {
+ continue;
+ }
+
+ TmpNode = AllocateCopyPool (sizeof (NAME_VALUE_NODE), Node);
+ TmpNode->Name = AllocateCopyPool (StrSize(Node->Name) * sizeof (CHAR16), Node->Name);
+ TmpNode->EditValue = AllocateCopyPool (StrSize(Node->EditValue) * sizeof (CHAR16), Node->EditValue);
+
+ InsertTailList(&BackUpList, &TmpNode->Link);
+ }
+ }
+
+ //
+ // Get default value.
+ //
+ ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage, TRUE);
+
+ //
+ // Update the question value based on the input ConfigRequest.
+ //
+ if (Storage->Type == EFI_HII_VARSTORE_BUFFER ||
+ (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
+ ASSERT (BackUpBuf != NULL);
+ BufferSize = Storage->Size;
+ Status = mHiiConfigRouting->BlockToConfig(
+ mHiiConfigRouting,
+ ConfigRequest,
+ Storage->EditBuffer,
+ BufferSize,
+ &Result,
+ &Progress
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = mHiiConfigRouting->ConfigToBlock (
+ mHiiConfigRouting,
+ Result,
+ BackUpBuf,
+ &BufferSize,
+ &Progress
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (Result != NULL) {
+ FreePool (Result);
+ }
+
+ CopyMem (Storage->EditBuffer, BackUpBuf, Storage->Size);
+ FreePool (BackUpBuf);
+ } else if (Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {
+ //
+ // Update question value, only element in ConfigReqeust will be update.
+ //
+ Link = GetFirstNode (&BackUpList);
+ while (!IsNull (&BackUpList, Link)) {
+ Node = NAME_VALUE_NODE_FROM_LINK (Link);
+ Link = GetNextNode (&BackUpList, Link);
+
+ if (StrStr (ConfigRequest, Node->Name) != NULL) {
+ continue;
+ }
+
+ NodeLink = GetFirstNode (&Storage->NameValueListHead);
+ while (!IsNull (&Storage->NameValueListHead, NodeLink)) {
+ TmpNode = NAME_VALUE_NODE_FROM_LINK (NodeLink);
+ NodeLink = GetNextNode (&Storage->NameValueListHead, NodeLink);
+
+ if (StrCmp (Node->Name, TmpNode->Name) != 0) {
+ continue;
+ }
+
+ FreePool (TmpNode->EditValue);
+ TmpNode->EditValue = AllocateCopyPool (StrSize(Node->EditValue) * sizeof (CHAR16), Node->EditValue);
+
+ RemoveEntryList (&Node->Link);
+ FreePool (Node->EditValue);
+ FreePool (Node->Name);
+ FreePool (Node);
+ }
+ }
+
+ //
+ // Restore the Name/Value node.
+ //
+ Link = GetFirstNode (&BackUpList);
+ while (!IsNull (&BackUpList, Link)) {
+ Node = NAME_VALUE_NODE_FROM_LINK (Link);
+ Link = GetNextNode (&BackUpList, Link);
+
+ //
+ // Free this node.
+ //
+ RemoveEntryList (&Node->Link);
+ FreePool (Node->EditValue);
+ FreePool (Node->Name);
+ FreePool (Node);
+ }
+ }
+}
+
+/**
Fill storage's edit copy with settings requested from Configuration Driver.
@param FormSet FormSet data structure.
@param Storage Buffer Storage.
- @retval EFI_SUCCESS The function completed successfully.
-
**/
-EFI_STATUS
+VOID
LoadStorage (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORMSET_STORAGE *Storage
@@ -3772,18 +4217,17 @@ LoadStorage (
EFI_STRING Progress;
EFI_STRING Result;
CHAR16 *StrPtr;
- CHAR16 *ConfigRequest;
- if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
- return EFI_SUCCESS;
- }
+ switch (Storage->BrowserStorage->Type) {
+ case EFI_HII_VARSTORE_EFI_VARIABLE:
+ return;
+
+ case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
+ if (Storage->BrowserStorage->ReferenceCount > 1) {
+ ConfigRequestAdjust(Storage);
+ return;
+ }
- if (Storage->BrowserStorage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER) {
- Status = EFI_SUCCESS;
- //
- // EFI varstore data all get from variable, so no need to get again.
- //
- if (Storage->BrowserStorage->ReferenceCount == 1) {
Status = gRT->GetVariable (
Storage->BrowserStorage->Name,
&Storage->BrowserStorage->Guid,
@@ -3791,55 +4235,78 @@ LoadStorage (
(UINTN*)&Storage->BrowserStorage->Size,
Storage->BrowserStorage->EditBuffer
);
- }
- return Status;
- }
+ //
+ // If get variable fail, extract default from IFR binary
+ //
+ if (EFI_ERROR (Status)) {
+ ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);
+ }
- if (FormSet->ConfigAccess == NULL) {
- return EFI_NOT_FOUND;
- }
+ Storage->BrowserStorage->ConfigRequest = AllocateCopyPool (StrSize (Storage->ConfigRequest), Storage->ConfigRequest);
+ //
+ // Input NULL for ConfigRequest field means sync all fields from editbuffer to buffer.
+ //
+ SynchronizeStorage(FormSet, Storage->BrowserStorage, NULL, TRUE);
+ break;
- if (Storage->ElementCount == 0) {
- //
- // Skip if there is no RequestElement
- //
- return EFI_SUCCESS;
- }
+ case EFI_HII_VARSTORE_BUFFER:
+ case EFI_HII_VARSTORE_NAME_VALUE:
+ //
+ // Skip if there is no RequestElement
+ //
+ if (Storage->ElementCount == 0) {
+ return;
+ }
- //
- // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig
- // will used to call ExtractConfig.
- //
- if (!ConfigRequestAdjust(Storage, &ConfigRequest)) {
- return EFI_SUCCESS;
- }
+ //
+ // Adjust the ConfigRequest string, only the field not saved in BrowserStorage->AllConfig
+ // will used to call ExtractConfig.
+ // If not elements need to udpate, return.
+ //
+ if (!ConfigRequestAdjust(Storage)) {
+ return;
+ }
+ ASSERT (Storage->ConfigElements != NULL);
- //
- // Request current settings from Configuration Driver
- //
- Status = FormSet->ConfigAccess->ExtractConfig (
- FormSet->ConfigAccess,
- ConfigRequest,
- &Progress,
- &Result
- );
- FreePool (ConfigRequest);
+ Status = EFI_NOT_FOUND;
+ if (FormSet->ConfigAccess != NULL) {
+ //
+ // Request current settings from Configuration Driver
+ //
+ Status = FormSet->ConfigAccess->ExtractConfig (
+ FormSet->ConfigAccess,
+ Storage->ConfigElements,
+ &Progress,
+ &Result
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Convert Result from <ConfigAltResp> to <ConfigResp>
+ //
+ StrPtr = StrStr (Result, L"&GUID=");
+ if (StrPtr != NULL) {
+ *StrPtr = L'\0';
+ }
+
+ Status = ConfigRespToStorage (Storage->BrowserStorage, Result);
+ FreePool (Result);
+ }
+ }
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ if (EFI_ERROR (Status)) {
+ //
+ // Base on the configRequest string to get default value.
+ //
+ GetDefaultForFormset (FormSet, Storage->BrowserStorage, Storage->ConfigElements);
+ }
- //
- // Convert Result from <ConfigAltResp> to <ConfigResp>
- //
- StrPtr = StrStr (Result, L"&GUID=");
- if (StrPtr != NULL) {
- *StrPtr = L'\0';
- }
+ SynchronizeStorage(FormSet, Storage->BrowserStorage, Storage->ConfigElements, TRUE);
+ break;
- Status = ConfigRespToStorage (Storage->BrowserStorage, Result);
- FreePool (Result);
- return Status;
+ default:
+ break;
+ }
}
/**
@@ -3847,22 +4314,15 @@ LoadStorage (
@param FormSet FormSet data structure.
- @retval EFI_SUCCESS The function completed successfully.
-
**/
-EFI_STATUS
+VOID
InitializeCurrentSetting (
IN OUT FORM_BROWSER_FORMSET *FormSet
)
{
LIST_ENTRY *Link;
- LIST_ENTRY *Link2;
FORMSET_STORAGE *Storage;
- FORMSET_STORAGE *StorageSrc;
- FORMSET_STORAGE *OldStorage;
- FORM_BROWSER_FORM *Form;
- FORM_BROWSER_FORM *Form2;
- EFI_STATUS Status;
+ FORM_BROWSER_FORMSET *OldFormSet;
//
// Extract default from IFR binary for no storage questions.
@@ -3876,77 +4336,21 @@ InitializeCurrentSetting (
while (!IsNull (&FormSet->StorageListHead, Link)) {
Storage = FORMSET_STORAGE_FROM_LINK (Link);
- OldStorage = NULL;
- if (gOldFormSet != NULL) {
- //
- // Try to find the Storage in backup formset gOldFormSet
- //
- Link2 = GetFirstNode (&gOldFormSet->StorageListHead);
- while (!IsNull (&gOldFormSet->StorageListHead, Link2)) {
- StorageSrc = FORMSET_STORAGE_FROM_LINK (Link2);
-
- if (StorageSrc->VarStoreId == Storage->VarStoreId) {
- OldStorage = StorageSrc;
- break;
- }
-
- Link2 = GetNextNode (&gOldFormSet->StorageListHead, Link2);
- }
- }
-
- //
- // Storage is not found in backup formset and current global storage not has other driver used,
- // request it from ConfigDriver
- //
- if (OldStorage == NULL) {
- Status = LoadStorage (FormSet, Storage);
-
- if (EFI_ERROR (Status)) {
- //
- // If get last time changed value failed, extract default from IFR binary
- //
- ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel, GetDefaultForStorage, Storage->BrowserStorage, TRUE);
- //
- // ExtractDefault will set the NV flag to TRUE, so need this function to clean the flag
- // in current situation.
- //
- UpdateNvInfoInForm (FormSet, FALSE);
- }
-
- //
- // Now Edit Buffer is filled with default values(lower priority) or current
- // settings(higher priority), sychronize it to shadow Buffer
- //
- SynchronizeStorage (Storage->BrowserStorage, TRUE);
- }
+ LoadStorage (FormSet, Storage);
Link = GetNextNode (&FormSet->StorageListHead, Link);
}
//
- // If has old formset, get the old nv update status.
+ // Try to find pre FormSet in the maintain backup list.
+ // If old formset != NULL, destroy this formset. Add new formset to gBrowserFormSetList.
//
- if (gOldFormSet != NULL) {
- Link = GetFirstNode (&FormSet->FormListHead);
- while (!IsNull (&FormSet->FormListHead, Link)) {
- Form = FORM_BROWSER_FORM_FROM_LINK (Link);
-
- Link2 = GetFirstNode (&gOldFormSet->FormListHead);
- while (!IsNull (&gOldFormSet->FormListHead, Link2)) {
- Form2 = FORM_BROWSER_FORM_FROM_LINK (Link2);
-
- if (Form->FormId == Form2->FormId) {
- Form->NvUpdateRequired = Form2->NvUpdateRequired;
- break;
- }
-
- Link2 = GetNextNode (&gOldFormSet->FormListHead, Link2);
- }
- Link = GetNextNode (&FormSet->FormListHead, Link);
- }
+ OldFormSet = GetFormSetFromHiiHandle (FormSet->HiiHandle);
+ if (OldFormSet != NULL) {
+ RemoveEntryList (&OldFormSet->Link);
+ DestroyFormSet (OldFormSet);
}
-
- return EFI_SUCCESS;
+ InsertTailList (&gBrowserFormSetList, &FormSet->Link);
}
@@ -4129,7 +4533,6 @@ GetIfrBinaryData (
found in package list.
On output, GUID of the formset found(if not NULL).
@param FormSet FormSet data structure.
- @param UpdateGlobalVar Whether need to update the global variable.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The specified FormSet could not be found.
@@ -4139,13 +4542,11 @@ EFI_STATUS
InitializeFormSet (
IN EFI_HII_HANDLE Handle,
IN OUT EFI_GUID *FormSetGuid,
- OUT FORM_BROWSER_FORMSET *FormSet,
- IN BOOLEAN UpdateGlobalVar
+ OUT FORM_BROWSER_FORMSET *FormSet
)
{
EFI_STATUS Status;
EFI_HANDLE DriverHandle;
- UINT16 Index;
Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);
if (EFI_ERROR (Status)) {
@@ -4155,6 +4556,7 @@ InitializeFormSet (
FormSet->Signature = FORM_BROWSER_FORMSET_SIGNATURE;
FormSet->HiiHandle = Handle;
CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));
+ FormSet->QuestionInited = FALSE;
//
// Retrieve ConfigAccess Protocol associated with this HiiPackageList
@@ -4181,55 +4583,8 @@ InitializeFormSet (
// Parse the IFR binary OpCodes
//
Status = ParseOpCodes (FormSet);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // If not need to update the global variable, just return.
- //
- if (!UpdateGlobalVar) {
- return Status;
- }
-
- //
- // Set VFR type by FormSet SubClass field
- //
- gClassOfVfr = FORMSET_CLASS_PLATFORM_SETUP;
- if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {
- gClassOfVfr = FORMSET_CLASS_FRONT_PAGE;
- }
-
- //
- // Set VFR type by FormSet class guid
- //
- for (Index = 0; Index < 3; Index ++) {
- if (CompareGuid (&FormSet->ClassGuid[Index], &gEfiHiiPlatformSetupFormsetGuid)) {
- gClassOfVfr |= FORMSET_CLASS_PLATFORM_SETUP;
- break;
- }
- }
-
- gFunctionKeySetting = ENABLE_FUNCTION_KEY_SETTING;
-
- if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {
- gFrontPageHandle = FormSet->HiiHandle;
- gFunctionKeySetting = NONE_FUNCTION_KEY_SETTING;
- }
-
- //
- // Match GUID to find out the function key setting. If match fail, use the default setting.
- //
- for (Index = 0; Index < sizeof (gFunctionKeySettingTable) / sizeof (FUNCTIION_KEY_SETTING); Index++) {
- if (CompareGuid (&FormSet->Guid, &(gFunctionKeySettingTable[Index].FormSetGuid))) {
- //
- // Update the function key setting.
- //
- gFunctionKeySetting = gFunctionKeySettingTable[Index].KeySetting;
- }
- }
-
- return EFI_SUCCESS;
+ return Status;
}
@@ -4245,6 +4600,7 @@ SaveBrowserContext (
)
{
BROWSER_CONTEXT *Context;
+ FORM_ENTRY_INFO *MenuList;
gBrowserContextCount++;
if (gBrowserContextCount == 1) {
@@ -4262,47 +4618,23 @@ SaveBrowserContext (
//
// Save FormBrowser context
//
- Context->BannerData = gBannerData;
- Context->ClassOfVfr = gClassOfVfr;
- Context->FunctionKeySetting = gFunctionKeySetting;
+ Context->Selection = gCurrentSelection;
Context->ResetRequired = gResetRequired;
- Context->Direction = gDirection;
- Context->EnterString = gEnterString;
- Context->EnterCommitString = gEnterCommitString;
- Context->EnterEscapeString = gEnterEscapeString;
- Context->EscapeString = gEscapeString;
- Context->MoveHighlight = gMoveHighlight;
- Context->MakeSelection = gMakeSelection;
- Context->DecNumericInput = gDecNumericInput;
- Context->HexNumericInput = gHexNumericInput;
- Context->ToggleCheckBox = gToggleCheckBox;
- Context->PromptForData = gPromptForData;
- Context->PromptForPassword = gPromptForPassword;
- Context->PromptForNewPassword = gPromptForNewPassword;
- Context->ConfirmPassword = gConfirmPassword;
- Context->ConfirmError = gConfirmError;
- Context->PassowordInvalid = gPassowordInvalid;
- Context->PressEnter = gPressEnter;
- Context->EmptyString = gEmptyString;
- Context->AreYouSure = gAreYouSure;
- Context->YesResponse = gYesResponse;
- Context->NoResponse = gNoResponse;
- Context->MiniString = gMiniString;
- Context->PlusString = gPlusString;
- Context->MinusString = gMinusString;
- Context->AdjustNumber = gAdjustNumber;
- Context->SaveChanges = gSaveChanges;
- Context->OptionMismatch = gOptionMismatch;
- Context->FormSuppress = gFormSuppress;
- Context->PromptBlockWidth = gPromptBlockWidth;
- Context->OptionBlockWidth = gOptionBlockWidth;
- Context->HelpBlockWidth = gHelpBlockWidth;
- Context->OldFormSet = gOldFormSet;
- Context->MenuRefreshHead = gMenuRefreshHead;
- Context->ProtocolNotFound = gProtocolNotFound;
-
- CopyMem (&Context->ScreenDimensions, &gScreenDimensions, sizeof (gScreenDimensions));
- CopyMem (&Context->MenuOption, &gMenuOption, sizeof (gMenuOption));
+ Context->ExitRequired = gExitRequired;
+ Context->HiiHandle = mCurrentHiiHandle;
+ Context->FormId = mCurrentFormId;
+ CopyGuid (&Context->FormSetGuid, &mCurrentFormSetGuid);
+
+ //
+ // Save the menu history data.
+ //
+ InitializeListHead(&Context->FormHistoryList);
+ while (!IsListEmpty (&mPrivateData.FormBrowserEx2.FormViewHistoryHead)) {
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (mPrivateData.FormBrowserEx2.FormViewHistoryHead.ForwardLink);
+ RemoveEntryList (&MenuList->Link);
+
+ InsertTailList(&Context->FormHistoryList, &MenuList->Link);
+ }
//
// Insert to FormBrowser context list
@@ -4322,6 +4654,7 @@ RestoreBrowserContext (
{
LIST_ENTRY *Link;
BROWSER_CONTEXT *Context;
+ FORM_ENTRY_INFO *MenuList;
ASSERT (gBrowserContextCount != 0);
gBrowserContextCount--;
@@ -4340,47 +4673,22 @@ RestoreBrowserContext (
//
// Restore FormBrowser context
//
- gBannerData = Context->BannerData;
- gClassOfVfr = Context->ClassOfVfr;
- gFunctionKeySetting = Context->FunctionKeySetting;
+ gCurrentSelection = Context->Selection;
gResetRequired = Context->ResetRequired;
- gDirection = Context->Direction;
- gEnterString = Context->EnterString;
- gEnterCommitString = Context->EnterCommitString;
- gEnterEscapeString = Context->EnterEscapeString;
- gEscapeString = Context->EscapeString;
- gMoveHighlight = Context->MoveHighlight;
- gMakeSelection = Context->MakeSelection;
- gDecNumericInput = Context->DecNumericInput;
- gHexNumericInput = Context->HexNumericInput;
- gToggleCheckBox = Context->ToggleCheckBox;
- gPromptForData = Context->PromptForData;
- gPromptForPassword = Context->PromptForPassword;
- gPromptForNewPassword = Context->PromptForNewPassword;
- gConfirmPassword = Context->ConfirmPassword;
- gConfirmError = Context->ConfirmError;
- gPassowordInvalid = Context->PassowordInvalid;
- gPressEnter = Context->PressEnter;
- gEmptyString = Context->EmptyString;
- gAreYouSure = Context->AreYouSure;
- gYesResponse = Context->YesResponse;
- gNoResponse = Context->NoResponse;
- gMiniString = Context->MiniString;
- gPlusString = Context->PlusString;
- gMinusString = Context->MinusString;
- gAdjustNumber = Context->AdjustNumber;
- gSaveChanges = Context->SaveChanges;
- gOptionMismatch = Context->OptionMismatch;
- gFormSuppress = Context->FormSuppress;
- gPromptBlockWidth = Context->PromptBlockWidth;
- gOptionBlockWidth = Context->OptionBlockWidth;
- gHelpBlockWidth = Context->HelpBlockWidth;
- gOldFormSet = Context->OldFormSet;
- gMenuRefreshHead = Context->MenuRefreshHead;
- gProtocolNotFound = Context->ProtocolNotFound;
-
- CopyMem (&gScreenDimensions, &Context->ScreenDimensions, sizeof (gScreenDimensions));
- CopyMem (&gMenuOption, &Context->MenuOption, sizeof (gMenuOption));
+ gExitRequired = Context->ExitRequired;
+ mCurrentHiiHandle = Context->HiiHandle;
+ mCurrentFormId = Context->FormId;
+ CopyGuid (&mCurrentFormSetGuid, &Context->FormSetGuid);
+
+ //
+ // Restore the menu history data.
+ //
+ while (!IsListEmpty (&Context->FormHistoryList)) {
+ MenuList = FORM_ENTRY_INFO_FROM_LINK (Context->FormHistoryList.ForwardLink);
+ RemoveEntryList (&MenuList->Link);
+
+ InsertTailList(&mPrivateData.FormBrowserEx2.FormViewHistoryHead, &MenuList->Link);
+ }
//
// Remove from FormBrowser context list
@@ -4440,7 +4748,7 @@ IsHiiHandleInBrowserContext (
//
// HiiHandle is Current FormSet.
//
- if ((gOldFormSet != NULL) && (gOldFormSet->HiiHandle == Handle)) {
+ if (mCurrentHiiHandle == Handle) {
return TRUE;
}
@@ -4450,7 +4758,7 @@ IsHiiHandleInBrowserContext (
Link = GetFirstNode (&gBrowserContextList);
while (!IsNull (&gBrowserContextList, Link)) {
Context = BROWSER_CONTEXT_FROM_LINK (Link);
- if (Context->OldFormSet->HiiHandle == Handle) {
+ if (Context->HiiHandle == Handle) {
//
// HiiHandle is in BrowserContext
//
@@ -4463,6 +4771,83 @@ IsHiiHandleInBrowserContext (
}
/**
+ Perform Password check.
+ Passwork may be encrypted by driver that requires the specific check.
+
+ @param Form Form where Password Statement is in.
+ @param Statement Password statement
+ @param PasswordString Password string to be checked. It may be NULL.
+ NULL means to restore password.
+ "" string can be used to checked whether old password does exist.
+
+ @return Status Status of Password check.
+**/
+EFI_STATUS
+EFIAPI
+PasswordCheck (
+ IN FORM_DISPLAY_ENGINE_FORM *Form,
+ IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
+ IN EFI_STRING PasswordString OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
+ EFI_BROWSER_ACTION_REQUEST ActionRequest;
+ EFI_IFR_TYPE_VALUE IfrTypeValue;
+ FORM_BROWSER_STATEMENT *Question;
+
+ ConfigAccess = gCurrentSelection->FormSet->ConfigAccess;
+ Question = GetBrowserStatement(Statement);
+ ASSERT (Question != NULL);
+
+ if ((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) == EFI_IFR_FLAG_CALLBACK) {
+ if (ConfigAccess == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ if (PasswordString == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ if (StrnCmp (PasswordString, (CHAR16 *) Question->BufferValue, Question->StorageWidth/sizeof (CHAR16)) == 0) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_READY;
+ }
+ }
+
+ //
+ // Prepare password string in HII database
+ //
+ if (PasswordString != NULL) {
+ IfrTypeValue.string = NewString (PasswordString, gCurrentSelection->FormSet->HiiHandle);
+ } else {
+ IfrTypeValue.string = 0;
+ }
+
+ //
+ // Send password to Configuration Driver for validation
+ //
+ Status = ConfigAccess->Callback (
+ ConfigAccess,
+ EFI_BROWSER_ACTION_CHANGING,
+ Question->QuestionId,
+ Question->HiiValue.Type,
+ &IfrTypeValue,
+ &ActionRequest
+ );
+
+ //
+ // Remove password string from HII database
+ //
+ if (PasswordString != NULL) {
+ DeleteString (IfrTypeValue.string, gCurrentSelection->FormSet->HiiHandle);
+ }
+
+ return Status;
+}
+
+/**
Find the registered HotKey based on KeyData.
@param[in] KeyData A pointer to a buffer that describes the keystroke
@@ -4512,7 +4897,7 @@ SetScope (
if (Scope >= MaxLevel) {
return EFI_INVALID_PARAMETER;
}
-
+
//
// When no hot key registered in system or on the first setting,
// Scope can be set.
@@ -4637,6 +5022,128 @@ RegiserExitHandler (
}
/**
+ Check whether the browser data has been modified.
+
+ @retval TRUE Browser data is modified.
+ @retval FALSE No browser data is modified.
+
+**/
+BOOLEAN
+EFIAPI
+IsBrowserDataModified (
+ VOID
+ )
+{
+ LIST_ENTRY *Link;
+ FORM_BROWSER_FORMSET *FormSet;
+
+ if (gCurrentSelection == NULL) {
+ return FALSE;
+ }
+
+ switch (gBrowserSettingScope) {
+ case FormLevel:
+ return IsNvUpdateRequiredForForm (gCurrentSelection->Form);
+
+ case FormSetLevel:
+ return IsNvUpdateRequiredForFormSet (gCurrentSelection->FormSet);
+
+ case SystemLevel:
+ Link = GetFirstNode (&gBrowserFormSetList);
+ while (!IsNull (&gBrowserFormSetList, Link)) {
+ FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
+ if (IsNvUpdateRequiredForFormSet (FormSet)) {
+ return TRUE;
+ }
+ Link = GetNextNode (&gBrowserFormSetList, Link);
+ }
+ return FALSE;
+
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ Execute the action requested by the Action parameter.
+
+ @param[in] Action Execute the request action.
+ @param[in] DefaultId The default Id info when need to load default value. Only used when Action is BROWSER_ACTION_DEFAULT.
+
+ @retval EFI_SUCCESS Execute the request action succss.
+ @retval EFI_INVALID_PARAMETER The input action value is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+ExecuteAction (
+ IN UINT32 Action,
+ IN UINT16 DefaultId
+ )
+{
+ EFI_STATUS Status;
+
+ if (gCurrentSelection == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Executet the discard action.
+ //
+ if ((Action & BROWSER_ACTION_DISCARD) != 0) {
+ Status = DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Executet the difault action.
+ //
+ if ((Action & BROWSER_ACTION_DEFAULT) != 0) {
+ Status = ExtractDefault (gCurrentSelection->FormSet, gCurrentSelection->Form, DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Executet the submit action.
+ //
+ if ((Action & BROWSER_ACTION_SUBMIT) != 0) {
+ Status = SubmitForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Executet the reset action.
+ //
+ if ((Action & BROWSER_ACTION_RESET) != 0) {
+ gResetRequired = TRUE;
+ }
+
+ //
+ // Executet the exit action.
+ //
+ if ((Action & BROWSER_ACTION_EXIT) != 0) {
+ DiscardForm (gCurrentSelection->FormSet, gCurrentSelection->Form, gBrowserSettingScope);
+ if (gBrowserSettingScope == SystemLevel) {
+ if (ExitHandlerFunction != NULL) {
+ ExitHandlerFunction ();
+ }
+ }
+
+ gExitRequired = TRUE;
+ }
+
+ return Status;
+}
+
+/**
Create reminder to let user to choose save or discard the changed browser data.
Caller can use it to actively check the changed browser data.
@@ -4655,12 +5162,6 @@ SaveReminder (
FORM_BROWSER_FORMSET *FormSet;
BOOLEAN IsDataChanged;
UINT32 DataSavedAction;
- CHAR16 *YesResponse;
- CHAR16 *NoResponse;
- CHAR16 *EmptyString;
- CHAR16 *ChangeReminderString;
- CHAR16 *SaveConfirmString;
- EFI_INPUT_KEY Key;
DataSavedAction = BROWSER_NO_CHANGES;
IsDataChanged = FALSE;
@@ -4671,7 +5172,7 @@ SaveReminder (
if (!ValidateFormSet(FormSet)) {
continue;
}
- if (IsNvUpdateRequired (FormSet)) {
+ if (IsNvUpdateRequiredForFormSet (FormSet)) {
IsDataChanged = TRUE;
break;
}
@@ -4685,42 +5186,19 @@ SaveReminder (
}
//
- // If data is changed, prompt user
+ // If data is changed, prompt user to save or discard it.
//
- gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
-
- YesResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_YES), gHiiHandle);
- ASSERT (YesResponse != NULL);
- NoResponse = GetToken (STRING_TOKEN (ARE_YOU_SURE_NO), gHiiHandle);
- ASSERT (NoResponse != NULL);
- EmptyString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
- ChangeReminderString = GetToken (STRING_TOKEN (CHANGE_REMINDER), gHiiHandle);
- SaveConfirmString = GetToken (STRING_TOKEN (SAVE_CONFIRM), gHiiHandle);
-
do {
- CreateDialog (4, TRUE, 0, NULL, &Key, EmptyString, ChangeReminderString, SaveConfirmString, EmptyString);
- } while
- (((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (NoResponse[0] | UPPER_LOWER_CASE_OFFSET)) &&
- ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (YesResponse[0] | UPPER_LOWER_CASE_OFFSET))
- );
+ DataSavedAction = (UINT32) mFormDisplay->ConfirmDataChange();
- //
- // If the user hits the YesResponse key
- //
- if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse[0] | UPPER_LOWER_CASE_OFFSET)) {
- SubmitForm (NULL, NULL, SystemLevel);
- DataSavedAction = BROWSER_SAVE_CHANGES;
- } else {
- DiscardForm (NULL, NULL, SystemLevel);
- DataSavedAction = BROWSER_DISCARD_CHANGES;
- gResetRequired = FALSE;
- }
-
- FreePool (YesResponse);
- FreePool (NoResponse);
- FreePool (EmptyString);
- FreePool (SaveConfirmString);
- FreePool (ChangeReminderString);
+ if (DataSavedAction == BROWSER_SAVE_CHANGES) {
+ SubmitForm (NULL, NULL, SystemLevel);
+ break;
+ } else if (DataSavedAction == BROWSER_DISCARD_CHANGES) {
+ DiscardForm (NULL, NULL, SystemLevel);
+ break;
+ }
+ } while (1);
return DataSavedAction;
}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
index 9a0c739094..030cf32eac 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
@@ -22,7 +22,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SimpleTextOut.h>
#include <Protocol/SimpleTextIn.h>
#include <Protocol/FormBrowser2.h>
-#include <Protocol/FormBrowserEx.h>
+#include <Protocol/FormBrowserEx2.h>
+#include <Protocol/DisplayProtocol.h>
#include <Protocol/DevicePath.h>
#include <Protocol/UnicodeCollation.h>
#include <Protocol/HiiConfigAccess.h>
@@ -47,106 +48,29 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/HiiLib.h>
#include <Library/PcdLib.h>
#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
-#include "Colors.h"
//
// This is the generated header file which includes whatever needs to be exported (strings + IFR)
//
-extern UINT8 SetupBrowserStrings[];
+#define UI_ACTION_NONE 0
+#define UI_ACTION_REFRESH_FORM 1
+#define UI_ACTION_REFRESH_FORMSET 2
+#define UI_ACTION_EXIT 3
//
-// Screen definitions
-//
-#define BANNER_HEIGHT 6
-#define BANNER_COLUMNS 3
-#define BANNER_LEFT_COLUMN_INDENT 1
-
-#define FRONT_PAGE_HEADER_HEIGHT 6
-#define NONE_FRONT_PAGE_HEADER_HEIGHT 3
-#define LEFT_SKIPPED_COLUMNS 3
-#define FOOTER_HEIGHT 4
-#define STATUS_BAR_HEIGHT 1
-#define SCROLL_ARROW_HEIGHT 1
-#define POPUP_PAD_SPACE_COUNT 5
-#define POPUP_FRAME_WIDTH 2
-
-//
-// Definition for function key setting
-//
-#define NONE_FUNCTION_KEY_SETTING 0
-#define ENABLE_FUNCTION_KEY_SETTING 1
-
-typedef struct {
- EFI_GUID FormSetGuid;
- UINTN KeySetting;
-} FUNCTIION_KEY_SETTING;
-
-//
-// Character definitions
-//
-#define CHAR_SPACE 0x0020
-#define UPPER_LOWER_CASE_OFFSET 0x20
-
//
// Time definitions
//
#define ONE_SECOND 10000000
-//
-// Display definitions
-//
-#define LEFT_HYPER_DELIMITER L'<'
-#define RIGHT_HYPER_DELIMITER L'>'
-
-#define LEFT_ONEOF_DELIMITER L'<'
-#define RIGHT_ONEOF_DELIMITER L'>'
-
-#define LEFT_NUMERIC_DELIMITER L'['
-#define RIGHT_NUMERIC_DELIMITER L']'
-
-#define LEFT_CHECKBOX_DELIMITER L'['
-#define RIGHT_CHECKBOX_DELIMITER L']'
-
-#define CHECK_ON L'X'
-#define CHECK_OFF L' '
-
-#define TIME_SEPARATOR L':'
-#define DATE_SEPARATOR L'/'
-
-#define YES_ANSWER L'Y'
-#define NO_ANSWER L'N'
-
-//
-// This is the Input Error Message
-//
-#define INPUT_ERROR 1
-
-//
-// This is the NV RAM update required Message
-//
-#define NV_UPDATE_REQUIRED 2
-
-//
-// Refresh the Status Bar with flags
-//
-#define REFRESH_STATUS_BAR 0xff
-
-//
// Incremental string lenght of ConfigRequest
//
#define CONFIG_REQUEST_STRING_INCREMENTAL 1024
//
-// HII value compare result
-//
-#define HII_VALUE_UNDEFINED 0
-#define HII_VALUE_EQUAL 1
-#define HII_VALUE_LESS_THAN 2
-#define HII_VALUE_GREATER_THAN 3
-
-//
// Incremental size of stack for expression
//
#define EXPRESSION_STACK_SIZE_INCREMENT 0x100
@@ -163,15 +87,12 @@ typedef struct {
//
// Produced protocol
//
- EFI_FORM_BROWSER2_PROTOCOL FormBrowser2;
-
- EFI_FORM_BROWSER_EXTENSION_PROTOCOL FormBrowserEx;
+ EFI_FORM_BROWSER2_PROTOCOL FormBrowser2;
+ EFI_FORM_BROWSER_EXTENSION_PROTOCOL FormBrowserEx;
-} SETUP_DRIVER_PRIVATE_DATA;
+ EDKII_FORM_BROWSER_EXTENSION2_PROTOCOL FormBrowserEx2;
-typedef struct {
- EFI_STRING_ID Banner[BANNER_HEIGHT][BANNER_COLUMNS];
-} BANNER_DATA;
+} SETUP_DRIVER_PRIVATE_DATA;
//
// IFR relative definition
@@ -194,16 +115,6 @@ typedef struct {
#define FORM_INCONSISTENT_VALIDATION 0
#define FORM_NO_SUBMIT_VALIDATION 1
-#define FORMSET_CLASS_PLATFORM_SETUP 0x0001
-#define FORMSET_CLASS_FRONT_PAGE 0x0002
-
-typedef struct {
- UINT8 Type;
- UINT8 *Buffer;
- UINT16 BufferLen;
- EFI_IFR_TYPE_VALUE Value;
-} EFI_HII_VALUE;
-
#define NAME_VALUE_NODE_SIGNATURE SIGNATURE_32 ('N', 'V', 'S', 'T')
typedef struct {
@@ -255,6 +166,7 @@ typedef struct {
BROWSER_STORAGE *BrowserStorage;
CHAR16 *ConfigRequest; // <ConfigRequest> = <ConfigHdr> + <RequestElement>
+ CHAR16 *ConfigElements;// Elements need to load initial data.
UINTN ElementCount; // Number of <RequestElement> in the <ConfigRequest>
UINTN SpareStrLen; // Spare length of ConfigRequest string buffer
} FORMSET_STORAGE;
@@ -344,6 +256,8 @@ typedef struct {
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
+
+ EFI_IFR_ONE_OF_OPTION *OpCode; // OneOfOption Data
EFI_STRING_ID Text;
UINT8 Flags;
@@ -376,6 +290,7 @@ typedef struct {
LIST_ENTRY Link;
UINT8 Operand; // The operand (first byte) of this Statement or Question
+ EFI_IFR_OP_HEADER *OpCode;
//
// Statement Header
@@ -385,6 +300,11 @@ typedef struct {
EFI_STRING_ID TextTwo; // For EFI_IFR_TEXT
//
+ // Fake Question Id, used for statement not has true QuestionId.
+ //
+ EFI_QUESTION_ID FakeQuestionId;
+
+ //
// Question Header
//
EFI_QUESTION_ID QuestionId; // The value of zero is reserved
@@ -417,6 +337,7 @@ typedef struct {
EFI_DEFAULT_ID DefaultId; // for EFI_IFR_RESET_BUTTON
EFI_GUID RefreshGuid; // for EFI_IFR_REFRESH_ID
BOOLEAN Locked; // Whether this statement is locked.
+ BOOLEAN ValueChanged; // Whether this statement's value is changed.
//
// Get from IFR parsing
//
@@ -467,8 +388,6 @@ typedef struct {
BOOLEAN ModalForm; // Whether this is a modal form.
BOOLEAN Locked; // Whether this form is locked.
- BOOLEAN NvUpdateRequired; // Whether this form has NV update request.
-
LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)
LIST_ENTRY StatementListHead; // List of Statements and Questions (FORM_BROWSER_STATEMENT)
LIST_ENTRY ConfigRequestHead; // List of configreques for all storage.
@@ -502,6 +421,7 @@ typedef struct {
UINTN IfrBinaryLength;
UINT8 *IfrBinaryData;
+ BOOLEAN QuestionInited; // Have finished question initilization?
EFI_GUID Guid;
EFI_STRING_ID FormSetTitle;
EFI_STRING_ID Help;
@@ -514,84 +434,82 @@ typedef struct {
FORM_BROWSER_STATEMENT *StatementBuffer; // Buffer for all Statements and Questions
EXPRESSION_OPCODE *ExpressionBuffer; // Buffer for all Expression OpCode
+ LIST_ENTRY StatementListOSF; // Statement list out side of the form.
LIST_ENTRY StorageListHead; // Storage list (FORMSET_STORAGE)
LIST_ENTRY DefaultStoreListHead; // DefaultStore list (FORMSET_DEFAULTSTORE)
LIST_ENTRY FormListHead; // Form list (FORM_BROWSER_FORM)
LIST_ENTRY ExpressionListHead; // List of Expressions (FORM_EXPRESSION)
} FORM_BROWSER_FORMSET;
-
#define FORM_BROWSER_FORMSET_FROM_LINK(a) CR (a, FORM_BROWSER_FORMSET, Link, FORM_BROWSER_FORMSET_SIGNATURE)
-#define BROWSER_CONTEXT_SIGNATURE SIGNATURE_32 ('B', 'C', 'T', 'X')
+typedef struct {
+ LIST_ENTRY Link;
+ EFI_EVENT RefreshEvent;
+} FORM_BROWSER_REFRESH_EVENT_NODE;
+
+#define FORM_BROWSER_REFRESH_EVENT_FROM_LINK(a) BASE_CR (a, FORM_BROWSER_REFRESH_EVENT_NODE, Link)
+
typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
+ EFI_HII_HANDLE Handle;
//
- // Globals defined in Setup.c
+ // Target formset/form/Question information
//
- BANNER_DATA *BannerData;
- UINTN ClassOfVfr;
- UINTN FunctionKeySetting;
- BOOLEAN ResetRequired;
- UINT16 Direction;
- EFI_SCREEN_DESCRIPTOR ScreenDimensions;
- CHAR16 *EnterString;
- CHAR16 *EnterCommitString;
- CHAR16 *EnterEscapeString;
- CHAR16 *EscapeString;
- CHAR16 *MoveHighlight;
- CHAR16 *MakeSelection;
- CHAR16 *DecNumericInput;
- CHAR16 *HexNumericInput;
- CHAR16 *ToggleCheckBox;
- CHAR16 *PromptForData;
- CHAR16 *PromptForPassword;
- CHAR16 *PromptForNewPassword;
- CHAR16 *ConfirmPassword;
- CHAR16 *ConfirmError;
- CHAR16 *PassowordInvalid;
- CHAR16 *PressEnter;
- CHAR16 *EmptyString;
- CHAR16 *AreYouSure;
- CHAR16 *YesResponse;
- CHAR16 *NoResponse;
- CHAR16 *MiniString;
- CHAR16 *PlusString;
- CHAR16 *MinusString;
- CHAR16 *AdjustNumber;
- CHAR16 *SaveChanges;
- CHAR16 *OptionMismatch;
- CHAR16 *FormSuppress;
- CHAR16 *ProtocolNotFound;
- CHAR16 PromptBlockWidth;
- CHAR16 OptionBlockWidth;
- CHAR16 HelpBlockWidth;
- FORM_BROWSER_FORMSET *OldFormSet;
+ EFI_GUID FormSetGuid;
+ UINT16 FormId;
+ UINT16 QuestionId;
+ UINTN Sequence; // used for time/date only.
+
+ UINTN TopRow;
+ UINTN BottomRow;
+ UINTN PromptCol;
+ UINTN OptionCol;
+ UINTN CurrentRow;
//
- // Globals defined in Ui.c
+ // Ation for Browser to taken:
+ // UI_ACTION_NONE - navigation inside a form
+ // UI_ACTION_REFRESH_FORM - re-evaluate expressions and repaint form
+ // UI_ACTION_REFRESH_FORMSET - re-parse formset IFR binary
//
- LIST_ENTRY MenuOption;
- VOID *MenuRefreshHead;
-} BROWSER_CONTEXT;
+ UINTN Action;
-#define BROWSER_CONTEXT_FROM_LINK(a) CR (a, BROWSER_CONTEXT, Link, BROWSER_CONTEXT_SIGNATURE)
+ //
+ // Current selected fomset/form/Question
+ //
+ FORM_BROWSER_FORMSET *FormSet;
+ FORM_BROWSER_FORM *Form;
+ FORM_BROWSER_STATEMENT *Statement;
-#define BROWSER_HOT_KEY_SIGNATURE SIGNATURE_32 ('B', 'H', 'K', 'S')
+ //
+ // Whether the Form is editable
+ //
+ BOOLEAN FormEditable;
+
+ FORM_ENTRY_INFO *CurrentMenu;
+} UI_MENU_SELECTION;
+
+#define BROWSER_CONTEXT_SIGNATURE SIGNATURE_32 ('B', 'C', 'T', 'X')
typedef struct {
UINTN Signature;
LIST_ENTRY Link;
-
- EFI_INPUT_KEY *KeyData;
- IN UINT32 Action;
- IN UINT16 DefaultId;
- IN EFI_STRING HelpString;
-} BROWSER_HOT_KEY;
-#define BROWSER_HOT_KEY_FROM_LINK(a) CR (a, BROWSER_HOT_KEY, Link, BROWSER_HOT_KEY_SIGNATURE)
+ //
+ // Globals defined in Setup.c
+ //
+ BOOLEAN ResetRequired;
+ BOOLEAN ExitRequired;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_GUID FormSetGuid;
+ EFI_FORM_ID FormId;
+ UI_MENU_SELECTION *Selection;
+
+ LIST_ENTRY FormHistoryList;
+} BROWSER_CONTEXT;
+
+#define BROWSER_CONTEXT_FROM_LINK(a) CR (a, BROWSER_CONTEXT, Link, BROWSER_CONTEXT_SIGNATURE)
//
// Scope for get defaut value. It may be GetDefaultForNoStorage, GetDefaultForStorage or GetDefaultForAll.
@@ -614,72 +532,31 @@ typedef enum {
} GET_SET_QUESTION_VALUE_WITH;
extern EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
-extern EFI_HII_STRING_PROTOCOL *mHiiString;
extern EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;
extern EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mPathFromText;
+extern EDKII_FORM_DISPLAY_ENGINE_PROTOCOL *mFormDisplay;
-extern BANNER_DATA *gBannerData;
-extern EFI_HII_HANDLE gFrontPageHandle;
-extern UINTN gClassOfVfr;
-extern UINTN gFunctionKeySetting;
extern BOOLEAN gResetRequired;
-extern EFI_HII_HANDLE gHiiHandle;
-extern UINT16 gDirection;
-extern EFI_SCREEN_DESCRIPTOR gScreenDimensions;
+extern BOOLEAN gExitRequired;
-extern FORM_BROWSER_FORMSET *gOldFormSet;
extern LIST_ENTRY gBrowserFormSetList;
extern LIST_ENTRY gBrowserHotKeyList;
extern BROWSER_SETTING_SCOPE gBrowserSettingScope;
extern EXIT_HANDLER ExitHandlerFunction;
-extern UINTN gFooterHeight;
-
+extern EFI_HII_HANDLE mCurrentHiiHandle;
//
// Browser Global Strings
//
-extern CHAR16 *gDiscardFailed;
-extern CHAR16 *gDefaultFailed;
-extern CHAR16 *gEnterString;
-extern CHAR16 *gEnterCommitString;
-extern CHAR16 *gEnterEscapeString;
-extern CHAR16 *gEscapeString;
-extern CHAR16 *gSaveFailed;
-extern CHAR16 *gMoveHighlight;
-extern CHAR16 *gMakeSelection;
-extern CHAR16 *gDecNumericInput;
-extern CHAR16 *gHexNumericInput;
-extern CHAR16 *gToggleCheckBox;
-extern CHAR16 *gPromptForData;
-extern CHAR16 *gPromptForPassword;
-extern CHAR16 *gPromptForNewPassword;
-extern CHAR16 *gConfirmPassword;
-extern CHAR16 *gConfirmError;
-extern CHAR16 *gPassowordInvalid;
-extern CHAR16 *gPressEnter;
extern CHAR16 *gEmptyString;
-extern CHAR16 *gAreYouSure;
-extern CHAR16 *gYesResponse;
-extern CHAR16 *gNoResponse;
-extern CHAR16 *gMiniString;
-extern CHAR16 *gPlusString;
-extern CHAR16 *gMinusString;
-extern CHAR16 *gAdjustNumber;
-extern CHAR16 *gSaveChanges;
-extern CHAR16 *gOptionMismatch;
-extern CHAR16 *gFormSuppress;
-extern CHAR16 *gProtocolNotFound;
-
-extern CHAR16 gPromptBlockWidth;
-extern CHAR16 gOptionBlockWidth;
-extern CHAR16 gHelpBlockWidth;
extern EFI_GUID gZeroGuid;
-extern EFI_GUID gTianoHiiIfrGuid;
-#include "Ui.h"
+extern UI_MENU_SELECTION *gCurrentSelection;
+
//
// Global Procedure Defines
//
+#include "Expression.h"
/**
Initialize the HII String Token to the correct values.
@@ -691,91 +568,6 @@ InitializeBrowserStrings (
);
/**
- Prints a unicode string to the default console,
- using L"%s" format.
-
- @param String String pointer.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-PrintString (
- IN CHAR16 *String
- );
-
-/**
- Prints a chracter to the default console,
- using L"%c" format.
-
- @param Character Character to print.
-
- @return Length of string printed to the console.
-
-**/
-UINTN
-PrintChar (
- CHAR16 Character
- );
-
-/**
- Prints a formatted unicode string to the default console, at
- the supplied cursor position.
-
- @param Column The cursor position to print the string at.
- @param Row The cursor position to print the string at
- @param Fmt Format string
- @param ... Variable argument list for formating string.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-EFIAPI
-PrintAt (
- IN UINTN Column,
- IN UINTN Row,
- IN CHAR16 *Fmt,
- ...
- );
-
-/**
- Prints a unicode string to the default console, at
- the supplied cursor position, using L"%s" format.
-
- @param Column The cursor position to print the string at.
- @param Row The cursor position to print the string at
- @param String String pointer.
-
- @return Length of string printed to the console
-
-**/
-UINTN
-PrintStringAt (
- IN UINTN Column,
- IN UINTN Row,
- IN CHAR16 *String
- );
-
-/**
- Prints a chracter to the default console, at
- the supplied cursor position, using L"%c" format.
-
- @param Column The cursor position to print the string at.
- @param Row The cursor position to print the string at.
- @param Character Character to print.
-
- @return Length of string printed to the console.
-
-**/
-UINTN
-PrintCharAt (
- IN UINTN Column,
- IN UINTN Row,
- CHAR16 Character
- );
-
-/**
Parse opcodes in the formset IFR binary.
@param FormSet Pointer of the FormSet data structure.
@@ -800,17 +592,6 @@ DestroyFormSet (
IN OUT FORM_BROWSER_FORMSET *FormSet
);
-/**
- This function displays the page frame.
-
- @param Selection Selection contains the information about
- the Selection, form and formset to be displayed.
- Selection action may be updated in retrieve callback.
-**/
-VOID
-DisplayPageFrame (
- IN UI_MENU_SELECTION *Selection
- );
/**
Create a new string in HII Package List.
@@ -860,59 +641,6 @@ GetToken (
);
/**
- Draw a pop up windows based on the dimension, number of lines and
- strings specified.
-
- @param RequestedWidth The width of the pop-up.
- @param NumberOfLines The number of lines.
- @param Marker The variable argument list for the list of string to be printed.
-
-**/
-VOID
-CreateSharedPopUp (
- IN UINTN RequestedWidth,
- IN UINTN NumberOfLines,
- IN VA_LIST Marker
- );
-
-/**
- Routine used to abstract a generic dialog interface and return the selected key or string
-
- @param NumberOfLines The number of lines for the dialog box
- @param HotKey Defines whether a single character is parsed
- (TRUE) and returned in KeyValue or a string is
- returned in StringBuffer. Two special characters
- are considered when entering a string, a SCAN_ESC
- and an CHAR_CARRIAGE_RETURN. SCAN_ESC terminates
- string input and returns
- @param MaximumStringSize The maximum size in bytes of a typed in string
- (each character is a CHAR16) and the minimum
- string returned is two bytes
- @param StringBuffer The passed in pointer to the buffer which will
- hold the typed in string if HotKey is FALSE
- @param KeyValue The EFI_KEY value returned if HotKey is TRUE..
- @param ... A series of (quantity == NumberOfLines) text
- strings which will be used to construct the dialog
- box
-
- @retval EFI_SUCCESS Displayed dialog and received user interaction
- @retval EFI_INVALID_PARAMETER One of the parameters was invalid (e.g.
- (StringBuffer == NULL) && (HotKey == FALSE))
- @retval EFI_DEVICE_ERROR User typed in an ESC character to exit the routine
-
-**/
-EFI_STATUS
-EFIAPI
-CreateDialog (
- IN UINTN NumberOfLines,
- IN BOOLEAN HotKey,
- IN UINTN MaximumStringSize,
- OUT CHAR16 *StringBuffer,
- OUT EFI_INPUT_KEY *KeyValue,
- ...
- );
-
-/**
Get Value for given Name from a NameValue Storage.
@param Storage The NameValue Storage.
@@ -939,6 +667,7 @@ GetValueByName (
@param Name The Name.
@param Value The Value to set.
@param SetValueTo Whether update editValue or Value.
+ @param ReturnNode The node use the input name.
@retval EFI_SUCCESS Value found for given Name.
@retval EFI_NOT_FOUND No such Name found in NameValue storage.
@@ -946,10 +675,31 @@ GetValueByName (
**/
EFI_STATUS
SetValueByName (
- IN BROWSER_STORAGE *Storage,
- IN CHAR16 *Name,
- IN CHAR16 *Value,
- IN GET_SET_QUESTION_VALUE_WITH SetValueTo
+ IN BROWSER_STORAGE *Storage,
+ IN CHAR16 *Name,
+ IN CHAR16 *Value,
+ IN GET_SET_QUESTION_VALUE_WITH SetValueTo,
+ OUT NAME_VALUE_NODE **ReturnNode
+ );
+
+/**
+ Validate whether this question's value has changed.
+
+ @param FormSet FormSet data structure.
+ @param Form Form data structure.
+ @param Question Question to be initialized.
+ @param GetValueFrom Where to get value, may from editbuffer, buffer or hii driver.
+
+ @retval TRUE Question's value has changed.
+ @retval FALSE Question's value has not changed
+
+**/
+BOOLEAN
+IsQuestionValueChanged (
+ IN FORM_BROWSER_FORMSET *FormSet,
+ IN FORM_BROWSER_FORM *Form,
+ IN OUT FORM_BROWSER_STATEMENT *Question,
+ IN GET_SET_QUESTION_VALUE_WITH GetValueFrom
);
/**
@@ -1071,10 +821,8 @@ GetQuestionDefault (
@param FormSet FormSet data structure.
- @retval EFI_SUCCESS The function completed successfully.
-
**/
-EFI_STATUS
+VOID
InitializeCurrentSetting (
IN OUT FORM_BROWSER_FORMSET *FormSet
);
@@ -1087,7 +835,6 @@ InitializeCurrentSetting (
GUID), take the first FormSet found in package
list.
@param FormSet FormSet data structure.
- @param UpdateGlobalVar Whether need to update the global variable.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_NOT_FOUND The specified FormSet could not be found.
@@ -1097,8 +844,7 @@ EFI_STATUS
InitializeFormSet (
IN EFI_HII_HANDLE Handle,
IN OUT EFI_GUID *FormSetGuid,
- OUT FORM_BROWSER_FORMSET *FormSet,
- IN BOOLEAN UpdateGlobalVar
+ OUT FORM_BROWSER_FORMSET *FormSet
);
/**
@@ -1176,6 +922,7 @@ LoadFormSetConfig (
@param Storage The Storage to be conveted.
@param ConfigResp The returned <ConfigResp>.
@param ConfigRequest The ConfigRequest string.
+ @param GetEditBuf Get the data from editbuffer or buffer.
@retval EFI_SUCCESS Convert success.
@retval EFI_INVALID_PARAMETER Incorrect storage type.
@@ -1185,7 +932,8 @@ EFI_STATUS
StorageToConfigResp (
IN BROWSER_STORAGE *Storage,
IN CHAR16 **ConfigResp,
- IN CHAR16 *ConfigRequest
+ IN CHAR16 *ConfigRequest,
+ IN BOOLEAN GetEditBuf
);
/**
@@ -1210,10 +958,8 @@ ConfigRespToStorage (
@param FormSet FormSet data structure.
@param Storage Buffer Storage.
- @retval EFI_SUCCESS The function completed successfully.
-
**/
-EFI_STATUS
+VOID
LoadStorage (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORMSET_STORAGE *Storage
@@ -1349,30 +1095,29 @@ BrowserCallback (
about the Selection, form and formset to be displayed.
On output, Selection return the screen item that is selected
by user.
- @param Repaint Whether need to repaint the menu.
- @param NewLine Whether need to show at new line.
+ @param SettingLevel Input Settting level, if it is FormLevel, just exit current form.
+ else, we need to exit current formset.
- @retval TRUE Need return.
- @retval FALSE No need to return.
+ @retval TRUE Exit current form.
+ @retval FALSE User press ESC and keep in current form.
**/
BOOLEAN
FindNextMenu (
- IN OUT UI_MENU_SELECTION *Selection,
- IN BOOLEAN *Repaint,
- IN BOOLEAN *NewLine
+ IN OUT UI_MENU_SELECTION *Selection,
+ IN BROWSER_SETTING_SCOPE SettingLevel
);
/**
- check whether the formset need to update the NV.
+ check whether the form need to update the NV.
- @param FormSet FormSet data structure.
- @param SetValue Whether set new value or clear old value.
+ @param Form Form data structure.
+ @retval TRUE Need to update the NV.
+ @retval FALSE No need to update the NV.
**/
-VOID
-UpdateNvInfoInForm (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN BOOLEAN SetValue
+BOOLEAN
+IsNvUpdateRequiredForForm (
+ IN FORM_BROWSER_FORM *Form
);
/**
@@ -1383,12 +1128,25 @@ UpdateNvInfoInForm (
@retval TRUE Need to update the NV.
@retval FALSE No need to update the NV.
**/
-BOOLEAN
-IsNvUpdateRequired (
+BOOLEAN
+IsNvUpdateRequiredForFormSet (
IN FORM_BROWSER_FORMSET *FormSet
);
/**
+ Check whether the storage data for current form set is changed.
+
+ @param FormSet FormSet data structure.
+
+ @retval TRUE Data is changed.
+ @retval FALSE Data is not changed.
+**/
+BOOLEAN
+IsStorageDataChangedForFormSet (
+ IN FORM_BROWSER_FORMSET *FormSet
+ );
+
+/**
Call the call back function for the question and process the return action.
@param Selection On input, Selection tell setup browser the information
@@ -1517,6 +1275,38 @@ RegiserExitHandler (
);
/**
+
+ Check whether the browser data has been modified.
+
+ @retval TRUE Browser data is changed.
+ @retval FALSE No browser data is changed.
+
+**/
+BOOLEAN
+EFIAPI
+IsBrowserDataModified (
+ VOID
+ );
+
+/**
+
+ Execute the action requested by the Action parameter.
+
+ @param[in] Action Execute the request action.
+ @param[in] DefaultId The default Id info when need to load default value.
+
+ @retval EFI_SUCCESS Execute the request action succss.
+ @retval EFI_INVALID_PARAMETER The input action value is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+ExecuteAction (
+ IN UINT32 Action,
+ IN UINT16 DefaultId
+ );
+
+/**
Create reminder to let user to choose save or discard the changed browser data.
Caller can use it to actively check the changed browser data.
@@ -1545,6 +1335,267 @@ GetHotKeyFromRegisterList (
);
/**
+
+ Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
+
+ @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
+
+ @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
+
+**/
+FORM_BROWSER_STATEMENT *
+GetBrowserStatement (
+ IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement
+ );
+
+/**
+ Password may be stored as encrypted by Configuration Driver. When change a
+ password, user will be challenged with old password. To validate user input old
+ password, we will send the clear text to Configuration Driver via Callback().
+ Configuration driver is responsible to check the passed in password and return
+ the validation result. If validation pass, state machine in password Callback()
+ will transit from BROWSER_STATE_VALIDATE_PASSWORD to BROWSER_STATE_SET_PASSWORD.
+ After user type in new password twice, Callback() will be invoked to send the
+ new password to Configuration Driver.
+
+ @param Selection Pointer to UI_MENU_SELECTION.
+ @param MenuOption The MenuOption for this password Question.
+ @param String The clear text of password.
+
+ @retval EFI_NOT_AVAILABLE_YET Callback() request to terminate password input.
+ @return In state of BROWSER_STATE_VALIDATE_PASSWORD:
+ @retval EFI_SUCCESS Password correct, Browser will prompt for new
+ password.
+ @retval EFI_NOT_READY Password incorrect, Browser will show error
+ message.
+ @retval Other Browser will do nothing.
+ @return In state of BROWSER_STATE_SET_PASSWORD:
+ @retval EFI_SUCCESS Set password success.
+ @retval Other Set password failed.
+
+**/
+EFI_STATUS
+PasswordCallback (
+ IN UI_MENU_SELECTION *Selection,
+ IN FORM_BROWSER_STATEMENT *Question,
+ IN CHAR16 *String
+ );
+
+/**
+ Display error message for invalid password.
+
+**/
+VOID
+PasswordInvalid (
+ VOID
+ );
+
+/**
+ The worker function that send the displays to the screen. On output,
+ the selection made by user is returned.
+
+ @param Selection On input, Selection tell setup browser the information
+ about the Selection, form and formset to be displayed.
+ On output, Selection return the screen item that is selected
+ by user.
+
+ @retval EFI_SUCCESS The page is displayed successfully.
+ @return Other value if the page failed to be diplayed.
+
+**/
+EFI_STATUS
+SetupBrowser (
+ IN OUT UI_MENU_SELECTION *Selection
+ );
+
+/**
+ Free up the resource allocated for all strings required
+ by Setup Browser.
+
+**/
+VOID
+FreeBrowserStrings (
+ VOID
+ );
+
+/**
+ Create a menu with specified formset GUID and form ID, and add it as a child
+ of the given parent menu.
+
+ @param HiiHandle Hii handle related to this formset.
+ @param FormSetGuid The Formset Guid of menu to be added.
+ @param FormId The Form ID of menu to be added.
+ @param QuestionId The question id of this menu to be added.
+
+ @return A pointer to the newly added menu or NULL if memory is insufficient.
+
+**/
+FORM_ENTRY_INFO *
+UiAddMenuList (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid,
+ IN UINT16 FormId,
+ IN UINT16 QuestionId
+ );
+
+/**
+ Search Menu with given FormSetGuid and FormId in all cached menu list.
+
+ @param HiiHandle HiiHandle for FormSet.
+ @param FormSetGuid The Formset GUID of the menu to search.
+ @param FormId The Form ID of menu to search.
+
+ @return A pointer to menu found or NULL if not found.
+
+**/
+FORM_ENTRY_INFO *
+UiFindMenuList (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid,
+ IN UINT16 FormId
+ );
+
+/**
+ Free Menu list linked list.
+
+ @param MenuListHead One Menu list point in the menu list.
+
+**/
+VOID
+UiFreeMenuList (
+ LIST_ENTRY *MenuListHead
+ );
+
+/**
+ Find parent menu for current menu.
+
+ @param CurrentMenu Current Menu
+
+ @retval The parent menu for current menu.
+**/
+FORM_ENTRY_INFO *
+UiFindParentMenu (
+ IN FORM_ENTRY_INFO *CurrentMenu
+ );
+
+/**
+ Search an Option of a Question by its value.
+
+ @param Question The Question
+ @param OptionValue Value for Option to be searched.
+
+ @retval Pointer Pointer to the found Option.
+ @retval NULL Option not found.
+
+**/
+QUESTION_OPTION *
+ValueToOption (
+ IN FORM_BROWSER_STATEMENT *Question,
+ IN EFI_HII_VALUE *OptionValue
+ );
+/**
+ Return data element in an Array by its Index.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+
+ @retval Value The data to be returned
+
+**/
+UINT64
+GetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index
+ );
+
+/**
+ Set value of a data element in an Array by its Index.
+
+ @param Array The data array.
+ @param Type Type of the data in this array.
+ @param Index Zero based index for data in this array.
+ @param Value The value to be set.
+
+**/
+VOID
+SetArrayData (
+ IN VOID *Array,
+ IN UINT8 Type,
+ IN UINTN Index,
+ IN UINT64 Value
+ );
+
+/**
+ Compare two Hii value.
+
+ @param Value1 Expression value to compare on left-hand.
+ @param Value2 Expression value to compare on right-hand.
+ @param Result Return value after compare.
+ retval 0 Two operators equal.
+ return Positive value if Value1 is greater than Value2.
+ retval Negative value if Value1 is less than Value2.
+ @param HiiHandle Only required for string compare.
+
+ @retval other Could not perform compare on two values.
+ @retval EFI_SUCCESS Compare the value success.
+
+**/
+EFI_STATUS
+CompareHiiValue (
+ IN EFI_HII_VALUE *Value1,
+ IN EFI_HII_VALUE *Value2,
+ OUT INTN *Result,
+ IN EFI_HII_HANDLE HiiHandle OPTIONAL
+ );
+
+/**
+ Perform Password check.
+ Passwork may be encrypted by driver that requires the specific check.
+
+ @param Form Form where Password Statement is in.
+ @param Statement Password statement
+ @param PasswordString Password string to be checked. It may be NULL.
+ NULL means to restore password.
+ "" string can be used to checked whether old password does exist.
+
+ @return Status Status of Password check.
+**/
+EFI_STATUS
+EFIAPI
+PasswordCheck (
+ IN FORM_DISPLAY_ENGINE_FORM *Form,
+ IN FORM_DISPLAY_ENGINE_STATEMENT *Statement,
+ IN EFI_STRING PasswordString OPTIONAL
+ );
+
+/**
+
+ Get FORM_BROWSER_STATEMENT from FORM_DISPLAY_ENGINE_STATEMENT based on the OpCode info.
+
+ @param DisplayStatement The input FORM_DISPLAY_ENGINE_STATEMENT.
+
+ @retval FORM_BROWSER_STATEMENT The return FORM_BROWSER_STATEMENT info.
+
+**/
+FORM_BROWSER_STATEMENT *
+GetBrowserStatement (
+ IN FORM_DISPLAY_ENGINE_STATEMENT *DisplayStatement
+ );
+
+/**
+
+ Initialize the Display form structure data.
+
+**/
+VOID
+InitializeDisplayFormData (
+ VOID
+ );
+
+
+/**
Base on the current formset info, clean the ConfigRequest string in browser storage.
@param FormSet Pointer of the FormSet
@@ -1554,5 +1605,5 @@ VOID
CleanBrowserStorage (
IN OUT FORM_BROWSER_FORMSET *FormSet
);
-
+
#endif
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
index 7e740bc099..a3f3a6fc2c 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
@@ -19,7 +19,7 @@
BASE_NAME = SetupBrowser
FILE_GUID = EBf342FE-B1D3-4EF8-957C-8048606FF671
MODULE_TYPE = DXE_DRIVER
- VERSION_STRING = 1.0
+ VERSION_STRING = 2.0
ENTRY_POINT = InitializeSetup
#
@@ -29,19 +29,12 @@
#
[Sources]
- SetupBrowserStr.uni
Setup.c
Setup.h
IfrParse.c
Expression.c
- InputHandler.c
- Print.c
Presentation.c
- ProcessOptions.c
- Ui.c
- Ui.h
- Colors.h
-
+ Expression.h
[Packages]
MdePkg/MdePkg.dec
@@ -59,34 +52,27 @@
HiiLib
DevicePathLib
PcdLib
+ UefiLib
[Guids]
- gEfiIfrTianoGuid ## CONSUMES ## GUID
gEfiIfrFrameworkGuid ## CONSUMES ## GUID
gEfiHiiPlatformSetupFormsetGuid
gEfiHiiStandardFormGuid ## SOMETIMES_CONSUMES ## GUID
[Protocols]
gEfiHiiConfigAccessProtocolGuid ## CONSUMES
- gEfiHiiStringProtocolGuid ## CONSUMES
gEfiFormBrowser2ProtocolGuid ## PRODUCES
- gEfiFormBrowserExProtocolGuid ## PRODUCES
+ gEdkiiFormBrowserEx2ProtocolGuid ## PRODUCES
gEfiHiiConfigRoutingProtocolGuid ## CONSUMES
gEfiHiiDatabaseProtocolGuid ## CONSUMES
gEfiUnicodeCollation2ProtocolGuid ## CONSUMES
gEfiUserManagerProtocolGuid ## SOMETIMES_CONSUMES
gEfiDevicePathFromTextProtocolGuid ## SOMETIMES_CONSUMES
+ gEdkiiFormDisplayEngineProtocolGuid ## PRODUCE
+ gEfiFormBrowserExProtocolGuid ## PRODUCE
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserGrayOutTextStatement ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowerGrayOutReadOnlyMenu ## CONSUMES
-
-[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserSubtitleTextColor ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextColor ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldTextHighlightColor ## CONSUMES
- gEfiMdeModulePkgTokenSpaceGuid.PcdBrowserFieldBackgroundHighlightColor ## CONSUMES
[Depex]
gEfiHiiDatabaseProtocolGuid AND gEfiHiiConfigRoutingProtocolGuid
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni
deleted file mode 100644
index bb6414d206..0000000000
--- a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni
+++ /dev/null
Binary files differ
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
deleted file mode 100644
index 7c246b60e1..0000000000
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
+++ /dev/null
@@ -1,4027 +0,0 @@
-/** @file
-Utility functions for User Interface functions.
-
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
-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.
-
-**/
-
-#include "Setup.h"
-
-LIST_ENTRY gMenuOption;
-LIST_ENTRY gMenuList;
-MENU_REFRESH_ENTRY *gMenuRefreshHead; // Menu list used for refresh timer opcode.
-MENU_REFRESH_ENTRY *gMenuEventGuidRefreshHead; // Menu list used for refresh event guid opcode.
-
-//
-// Search table for UiDisplayMenu()
-//
-SCAN_CODE_TO_SCREEN_OPERATION gScanCodeToOperation[] = {
- {
- SCAN_UP,
- UiUp,
- },
- {
- SCAN_DOWN,
- UiDown,
- },
- {
- SCAN_PAGE_UP,
- UiPageUp,
- },
- {
- SCAN_PAGE_DOWN,
- UiPageDown,
- },
- {
- SCAN_ESC,
- UiReset,
- },
- {
- SCAN_LEFT,
- UiLeft,
- },
- {
- SCAN_RIGHT,
- UiRight,
- }
-};
-
-UINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);
-
-SCREEN_OPERATION_T0_CONTROL_FLAG gScreenOperationToControlFlag[] = {
- {
- UiNoOperation,
- CfUiNoOperation,
- },
- {
- UiSelect,
- CfUiSelect,
- },
- {
- UiUp,
- CfUiUp,
- },
- {
- UiDown,
- CfUiDown,
- },
- {
- UiLeft,
- CfUiLeft,
- },
- {
- UiRight,
- CfUiRight,
- },
- {
- UiReset,
- CfUiReset,
- },
- {
- UiPageUp,
- CfUiPageUp,
- },
- {
- UiPageDown,
- CfUiPageDown
- },
- {
- UiHotKey,
- CfUiHotKey
- }
-};
-
-BOOLEAN mInputError;
-BOOLEAN GetLineByWidthFinished = FALSE;
-
-
-/**
- Set Buffer to Value for Size bytes.
-
- @param Buffer Memory to set.
- @param Size Number of bytes to set
- @param Value Value of the set operation.
-
-**/
-VOID
-SetUnicodeMem (
- IN VOID *Buffer,
- IN UINTN Size,
- IN CHAR16 Value
- )
-{
- CHAR16 *Ptr;
-
- Ptr = Buffer;
- while ((Size--) != 0) {
- *(Ptr++) = Value;
- }
-}
-
-
-/**
- Initialize Menu option list.
-
-**/
-VOID
-UiInitMenu (
- VOID
- )
-{
- InitializeListHead (&gMenuOption);
-}
-
-
-/**
- Free Menu option linked list.
-
-**/
-VOID
-UiFreeMenu (
- VOID
- )
-{
- UI_MENU_OPTION *MenuOption;
-
- while (!IsListEmpty (&gMenuOption)) {
- MenuOption = MENU_OPTION_FROM_LINK (gMenuOption.ForwardLink);
- RemoveEntryList (&MenuOption->Link);
-
- //
- // We allocated space for this description when we did a GetToken, free it here
- //
- if (MenuOption->Skip != 0) {
- //
- // For date/time, MenuOption->Description is shared by three Menu Options
- // Data format : [01/02/2004] [11:22:33]
- // Line number : 0 0 1 0 0 1
- //
- FreePool (MenuOption->Description);
- }
- FreePool (MenuOption);
- }
-}
-
-
-/**
- Create a menu with specified formset GUID and form ID, and add it as a child
- of the given parent menu.
-
- @param Parent The parent of menu to be added.
- @param HiiHandle Hii handle related to this formset.
- @param FormSetGuid The Formset Guid of menu to be added.
- @param FormId The Form ID of menu to be added.
-
- @return A pointer to the newly added menu or NULL if memory is insufficient.
-
-**/
-UI_MENU_LIST *
-UiAddMenuList (
- IN OUT UI_MENU_LIST *Parent,
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_GUID *FormSetGuid,
- IN UINT16 FormId
- )
-{
- UI_MENU_LIST *MenuList;
-
- MenuList = AllocateZeroPool (sizeof (UI_MENU_LIST));
- if (MenuList == NULL) {
- return NULL;
- }
-
- MenuList->Signature = UI_MENU_LIST_SIGNATURE;
- InitializeListHead (&MenuList->ChildListHead);
-
- MenuList->HiiHandle = HiiHandle;
- CopyMem (&MenuList->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));
- MenuList->FormId = FormId;
- MenuList->Parent = Parent;
-
- if (Parent == NULL) {
- //
- // If parent is not specified, it is the root Form of a Formset
- //
- InsertTailList (&gMenuList, &MenuList->Link);
- } else {
- InsertTailList (&Parent->ChildListHead, &MenuList->Link);
- }
-
- return MenuList;
-}
-
-
-/**
- Search Menu with given FormId, FormSetGuid and Handle in all cached menu list.
-
- @param Parent The parent of menu to search.
- @param Handle Hii handle related to this formset.
- @param FormSetGuid The Formset GUID of the menu to search.
- @param FormId The Form ID of menu to search.
-
- @return A pointer to menu found or NULL if not found.
-
-**/
-UI_MENU_LIST *
-UiFindChildMenuList (
- IN UI_MENU_LIST *Parent,
- IN EFI_HII_HANDLE Handle,
- IN EFI_GUID *FormSetGuid,
- IN UINT16 FormId
- )
-{
- LIST_ENTRY *Link;
- UI_MENU_LIST *Child;
- UI_MENU_LIST *MenuList;
-
- ASSERT (Parent != NULL);
-
- if (Parent->FormId == FormId && CompareGuid (FormSetGuid, &Parent->FormSetGuid) && Parent->HiiHandle == Handle) {
- return Parent;
- }
-
- Link = GetFirstNode (&Parent->ChildListHead);
- while (!IsNull (&Parent->ChildListHead, Link)) {
- Child = UI_MENU_LIST_FROM_LINK (Link);
-
- MenuList = UiFindChildMenuList (Child, Handle, FormSetGuid, FormId);
- if (MenuList != NULL) {
- return MenuList;
- }
-
- Link = GetNextNode (&Parent->ChildListHead, Link);
- }
-
- return NULL;
-}
-
-
-/**
- Search Menu with given Handle, FormSetGuid and FormId in all cached menu list.
-
- @param Handle Hii handle related to this formset.
- @param FormSetGuid The Formset GUID of the menu to search.
- @param FormId The Form ID of menu to search.
-
- @return A pointer to menu found or NULL if not found.
-
-**/
-UI_MENU_LIST *
-UiFindMenuList (
- IN EFI_HII_HANDLE Handle,
- IN EFI_GUID *FormSetGuid,
- IN UINT16 FormId
- )
-{
- LIST_ENTRY *Link;
- UI_MENU_LIST *MenuList;
- UI_MENU_LIST *Child;
-
- Link = GetFirstNode (&gMenuList);
- while (!IsNull (&gMenuList, Link)) {
- MenuList = UI_MENU_LIST_FROM_LINK (Link);
-
- Child = UiFindChildMenuList(MenuList, Handle, FormSetGuid, FormId);
- if (Child != NULL) {
-
- //
- // If this form already in the menu history list,
- // just free the list between old this form.
- //
- UiFreeMenuList(&Child->ChildListHead);
- return Child;
- }
-
- Link = GetNextNode (&gMenuList, Link);
- }
-
- return NULL;
-}
-
-/**
- Free Menu list linked list.
-
- @param MenuListHead One Menu list point in the menu list.
-
-**/
-VOID
-UiFreeMenuList (
- LIST_ENTRY *MenuListHead
- )
-{
- UI_MENU_LIST *MenuList;
-
- while (!IsListEmpty (MenuListHead)) {
- MenuList = UI_MENU_LIST_FROM_LINK (MenuListHead->ForwardLink);
- RemoveEntryList (&MenuList->Link);
-
- UiFreeMenuList(&MenuList->ChildListHead);
- FreePool (MenuList);
- }
-
-}
-
-/**
- Free Menu option linked list.
-
-**/
-VOID
-UiFreeRefreshList (
- VOID
- )
-{
- MENU_REFRESH_ENTRY *OldMenuRefreshEntry;
-
- while (gMenuRefreshHead != NULL) {
- OldMenuRefreshEntry = gMenuRefreshHead->Next;
- FreePool (gMenuRefreshHead);
- gMenuRefreshHead = OldMenuRefreshEntry;
- }
-
- while (gMenuEventGuidRefreshHead != NULL) {
- OldMenuRefreshEntry = gMenuEventGuidRefreshHead->Next;
- if (gMenuEventGuidRefreshHead != NULL) {
- gBS->CloseEvent(gMenuEventGuidRefreshHead->Event);
- }
- FreePool (gMenuEventGuidRefreshHead);
- gMenuEventGuidRefreshHead = OldMenuRefreshEntry;
- }
-}
-
-
-/**
- Process option string for date/time opcode.
-
- @param MenuOption Menu option point to date/time.
- @param OptionString Option string input for process.
- @param AddOptCol Whether need to update MenuOption->OptCol.
-
-**/
-VOID
-ProcessStringForDateTime (
- UI_MENU_OPTION *MenuOption,
- CHAR16 *OptionString,
- BOOLEAN AddOptCol
- )
-{
- UINTN Index;
- UINTN Count;
- FORM_BROWSER_STATEMENT *Statement;
-
- ASSERT (MenuOption != NULL && OptionString != NULL);
-
- Statement = MenuOption->ThisTag;
-
- //
- // If leading spaces on OptionString - remove the spaces
- //
- for (Index = 0; OptionString[Index] == L' '; Index++) {
- //
- // Base on the blockspace to get the option column info.
- //
- if (AddOptCol) {
- MenuOption->OptCol++;
- }
- }
-
- for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {
- OptionString[Count] = OptionString[Index];
- Count++;
- }
- OptionString[Count] = CHAR_NULL;
-
- //
- // Enable to suppress field in the opcode base on the flag.
- //
- if (Statement->Operand == EFI_IFR_DATE_OP) {
- //
- // OptionString format is: <**: **: ****>
- // |month|day|year|
- // 4 3 5
- //
- if ((Statement->Flags & EFI_QF_DATE_MONTH_SUPPRESS) && (MenuOption->Sequence == 0)) {
- //
- // At this point, only "<**:" in the optionstring.
- // Clean the day's ** field, after clean, the format is "< :"
- //
- SetUnicodeMem (&OptionString[1], 2, L' ');
- } else if ((Statement->Flags & EFI_QF_DATE_DAY_SUPPRESS) && (MenuOption->Sequence == 1)) {
- //
- // At this point, only "**:" in the optionstring.
- // Clean the month's "**" field, after clean, the format is " :"
- //
- SetUnicodeMem (&OptionString[0], 2, L' ');
- } else if ((Statement->Flags & EFI_QF_DATE_YEAR_SUPPRESS) && (MenuOption->Sequence == 2)) {
- //
- // At this point, only "****>" in the optionstring.
- // Clean the year's "****" field, after clean, the format is " >"
- //
- SetUnicodeMem (&OptionString[0], 4, L' ');
- }
- } else if (Statement->Operand == EFI_IFR_TIME_OP) {
- //
- // OptionString format is: <**: **: **>
- // |hour|minute|second|
- // 4 3 3
- //
- if ((Statement->Flags & QF_TIME_HOUR_SUPPRESS) && (MenuOption->Sequence == 0)) {
- //
- // At this point, only "<**:" in the optionstring.
- // Clean the hour's ** field, after clean, the format is "< :"
- //
- SetUnicodeMem (&OptionString[1], 2, L' ');
- } else if ((Statement->Flags & QF_TIME_MINUTE_SUPPRESS) && (MenuOption->Sequence == 1)) {
- //
- // At this point, only "**:" in the optionstring.
- // Clean the minute's "**" field, after clean, the format is " :"
- //
- SetUnicodeMem (&OptionString[0], 2, L' ');
- } else if ((Statement->Flags & QF_TIME_SECOND_SUPPRESS) && (MenuOption->Sequence == 2)) {
- //
- // At this point, only "**>" in the optionstring.
- // Clean the second's "**" field, after clean, the format is " >"
- //
- SetUnicodeMem (&OptionString[0], 2, L' ');
- }
- }
-}
-
-/**
- Refresh question.
-
- @param MenuRefreshEntry Menu refresh structure which has info about the refresh question.
-**/
-EFI_STATUS
-RefreshQuestion (
- IN MENU_REFRESH_ENTRY *MenuRefreshEntry
- )
-{
- CHAR16 *OptionString;
- EFI_STATUS Status;
- UI_MENU_SELECTION *Selection;
- FORM_BROWSER_STATEMENT *Question;
-
- Selection = MenuRefreshEntry->Selection;
- Question = MenuRefreshEntry->MenuOption->ThisTag;
-
- Status = GetQuestionValue (Selection->FormSet, Selection->Form, Question, GetSetValueWithHiiDriver);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- OptionString = NULL;
- ProcessOptions (Selection, MenuRefreshEntry->MenuOption, FALSE, &OptionString);
-
- if (OptionString != NULL) {
- //
- // If old Text is longer than new string, need to clean the old string before paint the newer.
- // This option is no need for time/date opcode, because time/data opcode has fixed string length.
- //
- if ((MenuRefreshEntry->MenuOption->ThisTag->Operand != EFI_IFR_DATE_OP) &&
- (MenuRefreshEntry->MenuOption->ThisTag->Operand != EFI_IFR_TIME_OP)) {
- ClearLines (
- MenuRefreshEntry->CurrentColumn,
- MenuRefreshEntry->CurrentColumn + gOptionBlockWidth - 1,
- MenuRefreshEntry->CurrentRow,
- MenuRefreshEntry->CurrentRow,
- PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND
- );
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, MenuRefreshEntry->CurrentAttribute);
- ProcessStringForDateTime(MenuRefreshEntry->MenuOption, OptionString, FALSE);
- PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, OptionString);
- FreePool (OptionString);
- }
-
- //
- // Question value may be changed, need invoke its Callback()
- //
- Status = ProcessCallBackFunction (Selection, Question, EFI_BROWSER_ACTION_CHANGING, FALSE);
-
- return Status;
-}
-
-/**
- Refresh the question which has refresh guid event attribute.
-
- @param Event The event which has this function related.
- @param Context The input context info related to this event or the status code return to the caller.
-**/
-VOID
-EFIAPI
-RefreshQuestionNotify(
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- MENU_REFRESH_ENTRY *MenuRefreshEntry;
- UI_MENU_SELECTION *Selection;
-
- //
- // Reset FormPackage update flag
- //
- mHiiPackageListUpdated = FALSE;
-
- MenuRefreshEntry = (MENU_REFRESH_ENTRY *)Context;
- ASSERT (MenuRefreshEntry != NULL);
- Selection = MenuRefreshEntry->Selection;
-
- RefreshQuestion (MenuRefreshEntry);
-
- if (mHiiPackageListUpdated) {
- //
- // Package list is updated, force to reparse IFR binary of target Formset
- //
- mHiiPackageListUpdated = FALSE;
- Selection->Action = UI_ACTION_REFRESH_FORMSET;
- }
-}
-
-
-/**
- Refresh screen.
-
-**/
-EFI_STATUS
-RefreshForm (
- VOID
- )
-{
- MENU_REFRESH_ENTRY *MenuRefreshEntry;
- EFI_STATUS Status;
- UI_MENU_SELECTION *Selection;
-
- if (gMenuRefreshHead != NULL) {
- //
- // call from refresh interval process.
- //
- MenuRefreshEntry = gMenuRefreshHead;
- Selection = MenuRefreshEntry->Selection;
- //
- // Reset FormPackage update flag
- //
- mHiiPackageListUpdated = FALSE;
-
- do {
- Status = RefreshQuestion (MenuRefreshEntry);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- MenuRefreshEntry = MenuRefreshEntry->Next;
-
- } while (MenuRefreshEntry != NULL);
-
- if (mHiiPackageListUpdated) {
- //
- // Package list is updated, force to reparse IFR binary of target Formset
- //
- mHiiPackageListUpdated = FALSE;
- Selection->Action = UI_ACTION_REFRESH_FORMSET;
- return EFI_SUCCESS;
- }
- }
-
- return EFI_TIMEOUT;
-}
-
-
-/**
- Wait for a given event to fire, or for an optional timeout to expire.
-
- @param Event The event to wait for
- @param Timeout An optional timeout value in 100 ns units.
- @param RefreshInterval Menu refresh interval (in seconds).
-
- @retval EFI_SUCCESS Event fired before Timeout expired.
- @retval EFI_TIME_OUT Timout expired before Event fired.
-
-**/
-EFI_STATUS
-UiWaitForSingleEvent (
- IN EFI_EVENT Event,
- IN UINT64 Timeout, OPTIONAL
- IN UINT8 RefreshInterval OPTIONAL
- )
-{
- EFI_STATUS Status;
- UINTN Index;
- EFI_EVENT TimerEvent;
- EFI_EVENT WaitList[2];
-
- if (Timeout != 0) {
- //
- // Create a timer event
- //
- Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
- if (!EFI_ERROR (Status)) {
- //
- // Set the timer event
- //
- gBS->SetTimer (
- TimerEvent,
- TimerRelative,
- Timeout
- );
-
- //
- // Wait for the original event or the timer
- //
- WaitList[0] = Event;
- WaitList[1] = TimerEvent;
- Status = gBS->WaitForEvent (2, WaitList, &Index);
- gBS->CloseEvent (TimerEvent);
-
- //
- // If the timer expired, change the return to timed out
- //
- if (!EFI_ERROR (Status) && Index == 1) {
- Status = EFI_TIMEOUT;
- }
- }
- } else {
- //
- // Update screen every second
- //
- if (RefreshInterval == 0) {
- Timeout = ONE_SECOND;
- } else {
- Timeout = RefreshInterval * ONE_SECOND;
- }
-
- do {
- Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
-
- //
- // Set the timer event
- //
- gBS->SetTimer (
- TimerEvent,
- TimerRelative,
- Timeout
- );
-
- //
- // Wait for the original event or the timer
- //
- WaitList[0] = Event;
- WaitList[1] = TimerEvent;
- Status = gBS->WaitForEvent (2, WaitList, &Index);
-
- //
- // If the timer expired, update anything that needs a refresh and keep waiting
- //
- if (!EFI_ERROR (Status) && Index == 1) {
- Status = EFI_TIMEOUT;
- if (RefreshInterval != 0) {
- Status = RefreshForm ();
- }
- }
-
- gBS->CloseEvent (TimerEvent);
- } while (Status == EFI_TIMEOUT);
- }
-
- return Status;
-}
-
-
-/**
- Add one menu option by specified description and context.
-
- @param String String description for this option.
- @param Handle Hii handle for the package list.
- @param Form The form this statement belong to.
- @param Statement Statement of this Menu Option.
- @param NumberOfLines Display lines for this Menu Option.
- @param MenuItemCount The index for this Option in the Menu.
-
- @retval Pointer Pointer to the added Menu Option.
-
-**/
-UI_MENU_OPTION *
-UiAddMenuOption (
- IN CHAR16 *String,
- IN EFI_HII_HANDLE Handle,
- IN FORM_BROWSER_FORM *Form,
- IN FORM_BROWSER_STATEMENT *Statement,
- IN UINT16 NumberOfLines,
- IN UINT16 MenuItemCount
- )
-{
- UI_MENU_OPTION *MenuOption;
- UINTN Index;
- UINTN Count;
-
- Count = 1;
- MenuOption = NULL;
-
- if (Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) {
- //
- // Add three MenuOptions for Date/Time
- // Data format : [01/02/2004] [11:22:33]
- // Line number : 0 0 1 0 0 1
- //
- NumberOfLines = 0;
- Count = 3;
-
- if (Statement->Storage == NULL) {
- //
- // For RTC type of date/time, set default refresh interval to be 1 second
- //
- if (Statement->RefreshInterval == 0) {
- Statement->RefreshInterval = 1;
- }
- }
- }
-
- for (Index = 0; Index < Count; Index++) {
- MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));
- ASSERT (MenuOption);
-
- MenuOption->Signature = UI_MENU_OPTION_SIGNATURE;
- MenuOption->Description = String;
- MenuOption->Handle = Handle;
- MenuOption->ThisTag = Statement;
- MenuOption->EntryNumber = MenuItemCount;
-
- if (Index == 2) {
- //
- // Override LineNumber for the MenuOption in Date/Time sequence
- //
- MenuOption->Skip = 1;
- } else {
- MenuOption->Skip = NumberOfLines;
- }
- MenuOption->Sequence = Index;
-
- if (EvaluateExpressionList(Statement->Expression, FALSE, NULL, NULL) == ExpressGrayOut ) {
- MenuOption->GrayOut = TRUE;
- } else {
- MenuOption->GrayOut = FALSE;
- }
-
- //
- // If the form or the question has the lock attribute, deal same as grayout.
- //
- if (Form->Locked || Statement->Locked) {
- MenuOption->GrayOut = TRUE;
- }
-
- 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:
- case EFI_IFR_CHECKBOX_OP:
- case EFI_IFR_PASSWORD_OP:
- case EFI_IFR_STRING_OP:
- //
- // User could change the value of these items
- //
- MenuOption->IsQuestion = TRUE;
- break;
-
- case EFI_IFR_TEXT_OP:
- if (FeaturePcdGet (PcdBrowserGrayOutTextStatement)) {
- //
- // Initializing GrayOut option as TRUE for Text setup options
- // so that those options will be Gray in colour and un selectable.
- //
- MenuOption->GrayOut = TRUE;
- }
- //
- // break skipped on purpose
- //
- default:
- MenuOption->IsQuestion = FALSE;
- break;
- }
-
- if ((Statement->ValueExpression != NULL) ||
- ((Statement->QuestionFlags & EFI_IFR_FLAG_READ_ONLY) != 0)) {
- MenuOption->ReadOnly = TRUE;
- if (FeaturePcdGet (PcdBrowerGrayOutReadOnlyMenu)) {
- MenuOption->GrayOut = TRUE;
- }
- }
-
- InsertTailList (&gMenuOption, &MenuOption->Link);
- }
-
- return MenuOption;
-}
-
-
-/**
- Routine used to abstract a generic dialog interface and return the selected key or string
-
- @param NumberOfLines The number of lines for the dialog box
- @param HotKey Defines whether a single character is parsed
- (TRUE) and returned in KeyValue or a string is
- returned in StringBuffer. Two special characters
- are considered when entering a string, a SCAN_ESC
- and an CHAR_CARRIAGE_RETURN. SCAN_ESC terminates
- string input and returns
- @param MaximumStringSize The maximum size in bytes of a typed in string
- (each character is a CHAR16) and the minimum
- string returned is two bytes
- @param StringBuffer The passed in pointer to the buffer which will
- hold the typed in string if HotKey is FALSE
- @param KeyValue The EFI_KEY value returned if HotKey is TRUE..
- @param ... A series of (quantity == NumberOfLines) text
- strings which will be used to construct the dialog
- box
-
- @retval EFI_SUCCESS Displayed dialog and received user interaction
- @retval EFI_INVALID_PARAMETER One of the parameters was invalid (e.g.
- (StringBuffer == NULL) && (HotKey == FALSE))
- @retval EFI_DEVICE_ERROR User typed in an ESC character to exit the routine
-
-**/
-EFI_STATUS
-EFIAPI
-CreateDialog (
- IN UINTN NumberOfLines,
- IN BOOLEAN HotKey,
- IN UINTN MaximumStringSize,
- OUT CHAR16 *StringBuffer,
- OUT EFI_INPUT_KEY *KeyValue,
- ...
- )
-{
- VA_LIST Marker;
- UINTN Count;
- EFI_INPUT_KEY Key;
- UINTN LargestString;
- CHAR16 *TempString;
- CHAR16 *BufferedString;
- CHAR16 *StackString;
- CHAR16 KeyPad[2];
- UINTN Start;
- UINTN Top;
- UINTN Index;
- EFI_STATUS Status;
- BOOLEAN SelectionComplete;
- UINTN InputOffset;
- UINTN CurrentAttribute;
- UINTN DimensionsWidth;
- UINTN DimensionsHeight;
-
- DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
- DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;
-
- SelectionComplete = FALSE;
- InputOffset = 0;
- TempString = AllocateZeroPool (MaximumStringSize * 2);
- BufferedString = AllocateZeroPool (MaximumStringSize * 2);
- CurrentAttribute = gST->ConOut->Mode->Attribute;
-
- ASSERT (TempString);
- ASSERT (BufferedString);
-
- //
- // Zero the outgoing buffer
- //
- ZeroMem (StringBuffer, MaximumStringSize);
-
- if (HotKey) {
- if (KeyValue == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- } else {
- if (StringBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- }
- //
- // Disable cursor
- //
- gST->ConOut->EnableCursor (gST->ConOut, FALSE);
-
- LargestString = 0;
-
- VA_START (Marker, KeyValue);
-
- //
- // Determine the largest string in the dialog box
- // Notice we are starting with 1 since String is the first string
- //
- for (Count = 0; Count < NumberOfLines; Count++) {
- StackString = VA_ARG (Marker, CHAR16 *);
-
- if (StackString[0] == L' ') {
- InputOffset = Count + 1;
- }
-
- if ((GetStringWidth (StackString) / 2) > LargestString) {
- //
- // Size of the string visually and subtract the width by one for the null-terminator
- //
- LargestString = (GetStringWidth (StackString) / 2);
- }
- }
- VA_END (Marker);
-
- Start = (DimensionsWidth - LargestString - 2) / 2 + gScreenDimensions.LeftColumn + 1;
- Top = ((DimensionsHeight - NumberOfLines - 2) / 2) + gScreenDimensions.TopRow - 1;
-
- Count = 0;
-
- //
- // Display the Popup
- //
- VA_START (Marker, KeyValue);
- CreateSharedPopUp (LargestString, NumberOfLines, Marker);
- VA_END (Marker);
-
- //
- // Take the first key typed and report it back?
- //
- if (HotKey) {
- Status = WaitForKeyStroke (&Key);
- ASSERT_EFI_ERROR (Status);
- CopyMem (KeyValue, &Key, sizeof (EFI_INPUT_KEY));
-
- } else {
- do {
- Status = WaitForKeyStroke (&Key);
-
- switch (Key.UnicodeChar) {
- case CHAR_NULL:
- switch (Key.ScanCode) {
- case SCAN_ESC:
- FreePool (TempString);
- FreePool (BufferedString);
- gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
- return EFI_DEVICE_ERROR;
-
- default:
- break;
- }
-
- break;
-
- case CHAR_CARRIAGE_RETURN:
- SelectionComplete = TRUE;
- FreePool (TempString);
- FreePool (BufferedString);
- gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
- return EFI_SUCCESS;
- break;
-
- case CHAR_BACKSPACE:
- if (StringBuffer[0] != CHAR_NULL) {
- for (Index = 0; StringBuffer[Index] != CHAR_NULL; Index++) {
- TempString[Index] = StringBuffer[Index];
- }
- //
- // Effectively truncate string by 1 character
- //
- TempString[Index - 1] = CHAR_NULL;
- StrCpy (StringBuffer, TempString);
- }
- //
- // break skipped on purpose
- //
-
- default:
- //
- // If it is the beginning of the string, don't worry about checking maximum limits
- //
- if ((StringBuffer[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
- StrnCpy (StringBuffer, &Key.UnicodeChar, 1);
- StrnCpy (TempString, &Key.UnicodeChar, 1);
- } else if ((GetStringWidth (StringBuffer) < MaximumStringSize) && (Key.UnicodeChar != CHAR_BACKSPACE)) {
- KeyPad[0] = Key.UnicodeChar;
- KeyPad[1] = CHAR_NULL;
- StrCat (StringBuffer, KeyPad);
- StrCat (TempString, KeyPad);
- }
- //
- // If the width of the input string is now larger than the screen, we nee to
- // adjust the index to start printing portions of the string
- //
- SetUnicodeMem (BufferedString, LargestString, L' ');
-
- PrintStringAt (Start + 1, Top + InputOffset, BufferedString);
-
- if ((GetStringWidth (StringBuffer) / 2) > (DimensionsWidth - 2)) {
- Index = (GetStringWidth (StringBuffer) / 2) - DimensionsWidth + 2;
- } else {
- Index = 0;
- }
-
- for (Count = 0; Index + 1 < GetStringWidth (StringBuffer) / 2; Index++, Count++) {
- BufferedString[Count] = StringBuffer[Index];
- }
-
- PrintStringAt (Start + 1, Top + InputOffset, BufferedString);
- break;
- }
- } while (!SelectionComplete);
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, CurrentAttribute);
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
- return EFI_SUCCESS;
-}
-
-/**
- Draw a pop up windows based on the dimension, number of lines and
- strings specified.
-
- @param RequestedWidth The width of the pop-up.
- @param NumberOfLines The number of lines.
- @param Marker The variable argument list for the list of string to be printed.
-
-**/
-VOID
-CreateSharedPopUp (
- IN UINTN RequestedWidth,
- IN UINTN NumberOfLines,
- IN VA_LIST Marker
- )
-{
- UINTN Index;
- UINTN Count;
- CHAR16 Character;
- UINTN Start;
- UINTN End;
- UINTN Top;
- UINTN Bottom;
- CHAR16 *String;
- UINTN DimensionsWidth;
- UINTN DimensionsHeight;
-
- DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn;
- DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow;
-
- gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
-
- if ((RequestedWidth + 2) > DimensionsWidth) {
- RequestedWidth = DimensionsWidth - 2;
- }
-
- //
- // Subtract the PopUp width from total Columns, allow for one space extra on
- // each end plus a border.
- //
- Start = (DimensionsWidth - RequestedWidth - 2) / 2 + gScreenDimensions.LeftColumn + 1;
- End = Start + RequestedWidth + 1;
-
- Top = ((DimensionsHeight - NumberOfLines - 2) / 2) + gScreenDimensions.TopRow - 1;
- Bottom = Top + NumberOfLines + 2;
-
- Character = BOXDRAW_DOWN_RIGHT;
- PrintCharAt (Start, Top, Character);
- Character = BOXDRAW_HORIZONTAL;
- for (Index = Start; Index + 2 < End; Index++) {
- PrintChar (Character);
- }
-
- Character = BOXDRAW_DOWN_LEFT;
- PrintChar (Character);
- Character = BOXDRAW_VERTICAL;
-
- Count = 0;
- for (Index = Top; Index + 2 < Bottom; Index++, Count++) {
- String = VA_ARG (Marker, CHAR16*);
-
- //
- // This will clear the background of the line - we never know who might have been
- // here before us. This differs from the next clear in that it used the non-reverse
- // video for normal printing.
- //
- if (GetStringWidth (String) / 2 > 1) {
- ClearLines (Start, End, Index + 1, Index + 1, POPUP_TEXT | POPUP_BACKGROUND);
- }
-
- //
- // Passing in a space results in the assumption that this is where typing will occur
- //
- if (String[0] == L' ') {
- ClearLines (Start + 1, End - 1, Index + 1, Index + 1, POPUP_INVERSE_TEXT | POPUP_INVERSE_BACKGROUND);
- }
-
- //
- // Passing in a NULL results in a blank space
- //
- if (String[0] == CHAR_NULL) {
- ClearLines (Start, End, Index + 1, Index + 1, POPUP_TEXT | POPUP_BACKGROUND);
- }
-
- PrintStringAt (
- ((DimensionsWidth - GetStringWidth (String) / 2) / 2) + gScreenDimensions.LeftColumn + 1,
- Index + 1,
- String
- );
- gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND);
- PrintCharAt (Start, Index + 1, Character);
- PrintCharAt (End - 1, Index + 1, Character);
- }
-
- Character = BOXDRAW_UP_RIGHT;
- PrintCharAt (Start, Bottom - 1, Character);
- Character = BOXDRAW_HORIZONTAL;
- for (Index = Start; Index + 2 < End; Index++) {
- PrintChar (Character);
- }
-
- Character = BOXDRAW_UP_LEFT;
- PrintChar (Character);
-}
-
-/**
- Draw a pop up windows based on the dimension, number of lines and
- strings specified.
-
- @param RequestedWidth The width of the pop-up.
- @param NumberOfLines The number of lines.
- @param ... A series of text strings that displayed in the pop-up.
-
-**/
-VOID
-EFIAPI
-CreateMultiStringPopUp (
- IN UINTN RequestedWidth,
- IN UINTN NumberOfLines,
- ...
- )
-{
- VA_LIST Marker;
-
- VA_START (Marker, NumberOfLines);
-
- CreateSharedPopUp (RequestedWidth, NumberOfLines, Marker);
-
- VA_END (Marker);
-}
-
-
-/**
- Update status bar on the bottom of menu.
-
- @param Selection Current Selction info.
- @param MessageType The type of message to be shown.
- @param Flags The flags in Question header.
- @param State Set or clear.
-
-**/
-VOID
-UpdateStatusBar (
- IN UI_MENU_SELECTION *Selection,
- IN UINTN MessageType,
- IN UINT8 Flags,
- IN BOOLEAN State
- )
-{
- UINTN Index;
- CHAR16 *NvUpdateMessage;
- CHAR16 *InputErrorMessage;
- LIST_ENTRY *Link;
- FORM_BROWSER_FORMSET *LocalFormSet;
- FORM_BROWSER_STATEMENT *Question;
-
- NvUpdateMessage = GetToken (STRING_TOKEN (NV_UPDATE_MESSAGE), gHiiHandle);
- InputErrorMessage = GetToken (STRING_TOKEN (INPUT_ERROR_MESSAGE), gHiiHandle);
-
- switch (MessageType) {
- case INPUT_ERROR:
- if (State) {
- gST->ConOut->SetAttribute (gST->ConOut, ERROR_TEXT);
- PrintStringAt (
- gScreenDimensions.LeftColumn + gPromptBlockWidth,
- gScreenDimensions.BottomRow - 1,
- InputErrorMessage
- );
- mInputError = TRUE;
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor));
- for (Index = 0; Index < (GetStringWidth (InputErrorMessage) - 2) / 2; Index++) {
- PrintAt (gScreenDimensions.LeftColumn + gPromptBlockWidth + Index, gScreenDimensions.BottomRow - 1, L" ");
- }
-
- mInputError = FALSE;
- }
- break;
-
- case NV_UPDATE_REQUIRED:
- //
- // Global setting support. Show configuration change on every form.
- //
- if (State) {
- gResetRequired = (BOOLEAN) (gResetRequired | ((Flags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED));
-
- if (Selection != NULL && Selection->Statement != NULL) {
- Question = Selection->Statement;
- if (Question->Storage != NULL || Question->Operand == EFI_IFR_DATE_OP || Question->Operand == EFI_IFR_TIME_OP) {
- //
- // Update only for Question value that need to be saved into Storage.
- //
- Selection->Form->NvUpdateRequired = TRUE;
- }
- }
-
- if (Selection == NULL || IsNvUpdateRequired (Selection->FormSet)) {
- gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT);
- PrintStringAt (
- gScreenDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth,
- gScreenDimensions.BottomRow - 1,
- NvUpdateMessage
- );
- }
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor));
- for (Index = 0; Index < (GetStringWidth (NvUpdateMessage) - 2) / 2; Index++) {
- PrintAt (
- (gScreenDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + Index),
- gScreenDimensions.BottomRow - 1,
- L" "
- );
- }
- }
- break;
-
- case REFRESH_STATUS_BAR:
- if (mInputError) {
- UpdateStatusBar (Selection, INPUT_ERROR, Flags, TRUE);
- }
-
- switch (gBrowserSettingScope) {
- case SystemLevel:
- //
- // Check the maintain list to see whether there is any change.
- //
- Link = GetFirstNode (&gBrowserFormSetList);
- while (!IsNull (&gBrowserFormSetList, Link)) {
- LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
- if (IsNvUpdateRequired(LocalFormSet)) {
- UpdateStatusBar (NULL, NV_UPDATE_REQUIRED, Flags, TRUE);
- break;
- }
- Link = GetNextNode (&gBrowserFormSetList, Link);
- }
- break;
- case FormSetLevel:
- case FormLevel:
- UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, Flags, TRUE);
- default:
- break;
- }
-
- break;
-
- default:
- break;
- }
-
- FreePool (InputErrorMessage);
- FreePool (NvUpdateMessage);
- return ;
-}
-
-
-/**
- Get the supported width for a particular op-code
-
- @param Statement The FORM_BROWSER_STATEMENT structure passed in.
- @param Handle The handle in the HII database being used
-
- @return Returns the number of CHAR16 characters that is support.
-
-**/
-UINT16
-GetWidth (
- IN FORM_BROWSER_STATEMENT *Statement,
- IN EFI_HII_HANDLE Handle
- )
-{
- CHAR16 *String;
- UINTN Size;
- UINT16 Width;
-
- Size = 0;
-
- //
- // See if the second text parameter is really NULL
- //
- if ((Statement->Operand == EFI_IFR_TEXT_OP) && (Statement->TextTwo != 0)) {
- String = GetToken (Statement->TextTwo, Handle);
- Size = StrLen (String);
- FreePool (String);
- }
-
- if ((Statement->Operand == EFI_IFR_SUBTITLE_OP) ||
- (Statement->Operand == EFI_IFR_REF_OP) ||
- (Statement->Operand == EFI_IFR_PASSWORD_OP) ||
- (Statement->Operand == EFI_IFR_ACTION_OP) ||
- (Statement->Operand == EFI_IFR_RESET_BUTTON_OP) ||
- //
- // Allow a wide display if text op-code and no secondary text op-code
- //
- ((Statement->Operand == EFI_IFR_TEXT_OP) && (Size == 0))
- ) {
- Width = (UINT16) (gPromptBlockWidth + gOptionBlockWidth);
- } else {
- Width = (UINT16) gPromptBlockWidth;
- }
-
- if (Statement->InSubtitle) {
- Width -= SUBTITLE_INDENT;
- }
-
- return (UINT16) (Width - LEFT_SKIPPED_COLUMNS);
-}
-
-/**
- Will copy LineWidth amount of a string in the OutputString buffer and return the
- number of CHAR16 characters that were copied into the OutputString buffer.
- The output string format is:
- Glyph Info + String info + '\0'.
-
- In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.
-
- @param InputString String description for this option.
- @param LineWidth Width of the desired string to extract in CHAR16
- characters
- @param GlyphWidth The glyph width of the begin of the char in the string.
- @param Index Where in InputString to start the copy process
- @param OutputString Buffer to copy the string into
-
- @return Returns the number of CHAR16 characters that were copied into the OutputString
- buffer, include extra glyph info and '\0' info.
-
-**/
-UINT16
-GetLineByWidth (
- IN CHAR16 *InputString,
- IN UINT16 LineWidth,
- IN OUT UINT16 *GlyphWidth,
- IN OUT UINTN *Index,
- OUT CHAR16 **OutputString
- )
-{
- UINT16 StrOffset;
- UINT16 GlyphOffset;
- UINT16 OriginalGlyphWidth;
- BOOLEAN ReturnFlag;
- UINT16 LastSpaceOffset;
- UINT16 LastGlyphWidth;
-
- if (InputString == NULL || Index == NULL || OutputString == NULL) {
- return 0;
- }
-
- if (LineWidth == 0 || *GlyphWidth == 0) {
- return 0;
- }
-
- //
- // Save original glyph width.
- //
- OriginalGlyphWidth = *GlyphWidth;
- LastGlyphWidth = OriginalGlyphWidth;
- ReturnFlag = FALSE;
- LastSpaceOffset = 0;
-
- //
- // NARROW_CHAR can not be printed in screen, so if a line only contain the two CHARs: 'NARROW_CHAR + CHAR_CARRIAGE_RETURN' , it is a empty line in Screen.
- // To avoid displaying this empty line in screen, just skip the two CHARs here.
- //
- if ((InputString[*Index] == NARROW_CHAR) && (InputString[*Index + 1] == CHAR_CARRIAGE_RETURN)) {
- *Index = *Index + 2;
- }
-
- //
- // Fast-forward the string and see if there is a carriage-return in the string
- //
- for (StrOffset = 0, GlyphOffset = 0; GlyphOffset <= LineWidth; StrOffset++) {
- switch (InputString[*Index + StrOffset]) {
- case NARROW_CHAR:
- *GlyphWidth = 1;
- break;
-
- case WIDE_CHAR:
- *GlyphWidth = 2;
- break;
-
- case CHAR_CARRIAGE_RETURN:
- case CHAR_LINEFEED:
- case CHAR_NULL:
- ReturnFlag = TRUE;
- break;
-
- default:
- GlyphOffset = GlyphOffset + *GlyphWidth;
-
- //
- // Record the last space info in this line. Will be used in rewind.
- //
- if ((InputString[*Index + StrOffset] == CHAR_SPACE) && (GlyphOffset <= LineWidth)) {
- LastSpaceOffset = StrOffset;
- LastGlyphWidth = *GlyphWidth;
- }
- break;
- }
-
- if (ReturnFlag) {
- break;
- }
- }
-
- //
- // Rewind the string from the maximum size until we see a space to break the line
- //
- if (GlyphOffset > LineWidth) {
- //
- // Rewind the string to last space char in this line.
- //
- if (LastSpaceOffset != 0) {
- StrOffset = LastSpaceOffset;
- *GlyphWidth = LastGlyphWidth;
- } else {
- //
- // Roll back to last char in the line width.
- //
- StrOffset--;
- }
- }
-
- //
- // The CHAR_NULL has process last time, this time just return 0 to stand for the end.
- //
- if (StrOffset == 0 && (InputString[*Index + StrOffset] == CHAR_NULL)) {
- return 0;
- }
-
- //
- // Need extra glyph info and '\0' info, so +2.
- //
- *OutputString = AllocateZeroPool (((UINTN) (StrOffset + 2) * sizeof(CHAR16)));
- if (*OutputString == NULL) {
- return 0;
- }
-
- //
- // Save the glyph info at the begin of the string, will used by Print function.
- //
- if (OriginalGlyphWidth == 1) {
- *(*OutputString) = NARROW_CHAR;
- } else {
- *(*OutputString) = WIDE_CHAR;
- }
-
- CopyMem ((*OutputString) + 1, &InputString[*Index], StrOffset * sizeof(CHAR16));
-
- if (InputString[*Index + StrOffset] == CHAR_SPACE) {
- //
- // Skip the space info at the begin of next line.
- //
- *Index = (UINT16) (*Index + StrOffset + 1);
- } else if (InputString[*Index + StrOffset] == CHAR_LINEFEED) {
- //
- // Skip the /n or /n/r info.
- //
- if (InputString[*Index + StrOffset + 1] == CHAR_CARRIAGE_RETURN) {
- *Index = (UINT16) (*Index + StrOffset + 2);
- } else {
- *Index = (UINT16) (*Index + StrOffset + 1);
- }
- } else if (InputString[*Index + StrOffset] == CHAR_CARRIAGE_RETURN) {
- //
- // Skip the /r or /r/n info.
- //
- if (InputString[*Index + StrOffset + 1] == CHAR_LINEFEED) {
- *Index = (UINT16) (*Index + StrOffset + 2);
- } else {
- *Index = (UINT16) (*Index + StrOffset + 1);
- }
- } else {
- *Index = (UINT16) (*Index + StrOffset);
- }
-
- //
- // Include extra glyph info and '\0' info, so +2.
- //
- return StrOffset + 2;
-}
-
-
-/**
- Update display lines for a Menu Option.
-
- @param Selection The user's selection.
- @param MenuOption The MenuOption to be checked.
-
-**/
-VOID
-UpdateOptionSkipLines (
- IN UI_MENU_SELECTION *Selection,
- IN UI_MENU_OPTION *MenuOption
- )
-{
- UINTN Index;
- UINT16 Width;
- UINTN Row;
- UINTN OriginalRow;
- CHAR16 *OutputString;
- CHAR16 *OptionString;
- UINT16 GlyphWidth;
-
- Row = 0;
- OptionString = NULL;
- Width = (UINT16) gOptionBlockWidth;
- OriginalRow = 0;
- GlyphWidth = 1;
-
- ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
- if (OptionString == NULL) {
- return;
- }
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- Row++;
- //
- // Since the Number of lines for this menu entry may or may not be reflected accurately
- // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
- // some testing to ensure we are keeping this in-sync.
- //
- // If the difference in rows is greater than or equal to the skip value, increase the skip value
- //
- if ((Row - OriginalRow) >= MenuOption->Skip) {
- MenuOption->Skip++;
- }
- }
-
- FreePool (OutputString);
- }
-
- if (OptionString != NULL) {
- FreePool (OptionString);
- }
-}
-
-
-/**
- Check whether this Menu Option could be highlighted.
-
- This is an internal function.
-
- @param MenuOption The MenuOption to be checked.
-
- @retval TRUE This Menu Option is selectable.
- @retval FALSE This Menu Option could not be selected.
-
-**/
-BOOLEAN
-IsSelectable (
- UI_MENU_OPTION *MenuOption
- )
-{
- if ((MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP) ||
- MenuOption->GrayOut || MenuOption->ReadOnly) {
- return FALSE;
- } else {
- return TRUE;
- }
-}
-
-
-/**
- Determine if the menu is the last menu that can be selected.
-
- This is an internal function.
-
- @param Direction The scroll direction. False is down. True is up.
- @param CurrentPos The current focus.
-
- @return FALSE -- the menu isn't the last menu that can be selected.
- @return TRUE -- the menu is the last menu that can be selected.
-
-**/
-BOOLEAN
-ValueIsScroll (
- IN BOOLEAN Direction,
- IN LIST_ENTRY *CurrentPos
- )
-{
- LIST_ENTRY *Temp;
-
- Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;
-
- if (Temp == &gMenuOption) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-/**
- Move to next selectable statement.
-
- This is an internal function.
-
- @param Selection Menu selection.
- @param GoUp The navigation direction. TRUE: up, FALSE: down.
- @param CurrentPosition Current position.
- @param GapToTop Gap position to top or bottom.
-
- @return The row distance from current MenuOption to next selectable MenuOption.
-
- @retval -1 Reach the begin of the menu, still can't find the selectable menu.
- @retval Value Find the selectable menu, maybe the truly selectable, maybe the l
- last menu showing at current form.
-
-**/
-INTN
-MoveToNextStatement (
- IN UI_MENU_SELECTION *Selection,
- IN BOOLEAN GoUp,
- IN OUT LIST_ENTRY **CurrentPosition,
- IN UINTN GapToTop
- )
-{
- INTN Distance;
- LIST_ENTRY *Pos;
- UI_MENU_OPTION *NextMenuOption;
- UI_MENU_OPTION *PreMenuOption;
-
- Distance = 0;
- Pos = *CurrentPosition;
- PreMenuOption = MENU_OPTION_FROM_LINK (Pos);
-
- while (TRUE) {
- NextMenuOption = MENU_OPTION_FROM_LINK (Pos);
- //
- // NextMenuOption->Row == 0 means this menu has not calculate
- // the NextMenuOption->Skip value yet, just calculate here.
- //
- if (NextMenuOption->Row == 0) {
- UpdateOptionSkipLines (Selection, NextMenuOption);
- }
-
- if (GoUp && (PreMenuOption != NextMenuOption)) {
- //
- // In this case, still can't find the selectable menu,
- // return the last one in the showing form.
- //
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
- NextMenuOption = PreMenuOption;
- break;
- }
-
- //
- // Current Position doesn't need to be caculated when go up.
- // Caculate distanct at first when go up
- //
- Distance += NextMenuOption->Skip;
- }
-
- if (IsSelectable (NextMenuOption)) {
- break;
- }
-
- //
- // Arrive at begin of the menu list.
- //
- if ((GoUp ? Pos->BackLink : Pos->ForwardLink) == &gMenuOption) {
- Distance = -1;
- break;
- }
-
- if (!GoUp) {
- //
- // In this case, still can't find the selectable menu,
- // return the last one in the showing form.
- //
- if ((UINTN) Distance + NextMenuOption->Skip > GapToTop) {
- NextMenuOption = PreMenuOption;
- break;
- }
-
- Distance += NextMenuOption->Skip;
- }
-
- PreMenuOption = NextMenuOption;
- Pos = (GoUp ? Pos->BackLink : Pos->ForwardLink);
- }
-
- *CurrentPosition = &NextMenuOption->Link;
- return Distance;
-}
-
-
-/**
- Adjust Data and Time position accordingly.
- Data format : [01/02/2004] [11:22:33]
- Line number : 0 0 1 0 0 1
-
- This is an internal function.
-
- @param DirectionUp the up or down direction. False is down. True is
- up.
- @param CurrentPosition Current position. On return: Point to the last
- Option (Year or Second) if up; Point to the first
- Option (Month or Hour) if down.
-
- @return Return line number to pad. It is possible that we stand on a zero-advance
- @return data or time opcode, so pad one line when we judge if we are going to scroll outside.
-
-**/
-UINTN
-AdjustDateAndTimePosition (
- IN BOOLEAN DirectionUp,
- IN OUT LIST_ENTRY **CurrentPosition
- )
-{
- UINTN Count;
- LIST_ENTRY *NewPosition;
- UI_MENU_OPTION *MenuOption;
- UINTN PadLineNumber;
-
- PadLineNumber = 0;
- NewPosition = *CurrentPosition;
- MenuOption = MENU_OPTION_FROM_LINK (NewPosition);
-
- if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) ||
- (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {
- //
- // Calculate the distance from current position to the last Date/Time MenuOption
- //
- Count = 0;
- while (MenuOption->Skip == 0) {
- Count++;
- NewPosition = NewPosition->ForwardLink;
- MenuOption = MENU_OPTION_FROM_LINK (NewPosition);
- PadLineNumber = 1;
- }
-
- NewPosition = *CurrentPosition;
- if (DirectionUp) {
- //
- // Since the behavior of hitting the up arrow on a Date/Time MenuOption is intended
- // to be one that back to the previous set of MenuOptions, we need to advance to the first
- // Date/Time MenuOption and leave the remaining logic in CfUiUp intact so the appropriate
- // checking can be done.
- //
- while (Count++ < 2) {
- NewPosition = NewPosition->BackLink;
- }
- } else {
- //
- // Since the behavior of hitting the down arrow on a Date/Time MenuOption is intended
- // to be one that progresses to the next set of MenuOptions, we need to advance to the last
- // Date/Time MenuOption and leave the remaining logic in CfUiDown intact so the appropriate
- // checking can be done.
- //
- while (Count-- > 0) {
- NewPosition = NewPosition->ForwardLink;
- }
- }
-
- *CurrentPosition = NewPosition;
- }
-
- return PadLineNumber;
-}
-
-/**
- Find HII Handle in the HII database associated with given Device Path.
-
- If DevicePath is NULL, then ASSERT.
-
- @param DevicePath Device Path associated with the HII package list
- handle.
-
- @retval Handle HII package list Handle associated with the Device
- Path.
- @retval NULL Hii Package list handle is not found.
-
-**/
-EFI_HII_HANDLE
-EFIAPI
-DevicePathToHiiHandle (
- IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
- UINTN BufferSize;
- UINTN HandleCount;
- UINTN Index;
- EFI_HANDLE Handle;
- EFI_HANDLE DriverHandle;
- EFI_HII_HANDLE *HiiHandles;
- EFI_HII_HANDLE HiiHandle;
-
- ASSERT (DevicePath != NULL);
-
- TmpDevicePath = DevicePath;
- //
- // Locate Device Path Protocol handle buffer
- //
- Status = gBS->LocateDevicePath (
- &gEfiDevicePathProtocolGuid,
- &TmpDevicePath,
- &DriverHandle
- );
- if (EFI_ERROR (Status) || !IsDevicePathEnd (TmpDevicePath)) {
- return NULL;
- }
-
- //
- // Retrieve all HII Handles from HII database
- //
- BufferSize = 0x1000;
- HiiHandles = AllocatePool (BufferSize);
- ASSERT (HiiHandles != NULL);
- Status = mHiiDatabase->ListPackageLists (
- mHiiDatabase,
- EFI_HII_PACKAGE_TYPE_ALL,
- NULL,
- &BufferSize,
- HiiHandles
- );
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FreePool (HiiHandles);
- HiiHandles = AllocatePool (BufferSize);
- ASSERT (HiiHandles != NULL);
-
- Status = mHiiDatabase->ListPackageLists (
- mHiiDatabase,
- EFI_HII_PACKAGE_TYPE_ALL,
- NULL,
- &BufferSize,
- HiiHandles
- );
- }
-
- if (EFI_ERROR (Status)) {
- FreePool (HiiHandles);
- return NULL;
- }
-
- //
- // Search Hii Handle by Driver Handle
- //
- HiiHandle = NULL;
- HandleCount = BufferSize / sizeof (EFI_HII_HANDLE);
- for (Index = 0; Index < HandleCount; Index++) {
- Status = mHiiDatabase->GetPackageListHandle (
- mHiiDatabase,
- HiiHandles[Index],
- &Handle
- );
- if (!EFI_ERROR (Status) && (Handle == DriverHandle)) {
- HiiHandle = HiiHandles[Index];
- break;
- }
- }
-
- FreePool (HiiHandles);
- return HiiHandle;
-}
-
-/**
- Find HII Handle in the HII database associated with given form set guid.
-
- If FormSetGuid is NULL, then ASSERT.
-
- @param ComparingGuid FormSet Guid associated with the HII package list
- handle.
-
- @retval Handle HII package list Handle associated with the Device
- Path.
- @retval NULL Hii Package list handle is not found.
-
-**/
-EFI_HII_HANDLE
-FormSetGuidToHiiHandle (
- EFI_GUID *ComparingGuid
- )
-{
- EFI_HII_HANDLE *HiiHandles;
- UINTN Index;
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
- UINTN BufferSize;
- UINT32 Offset;
- UINT32 Offset2;
- UINT32 PackageListLength;
- EFI_HII_PACKAGE_HEADER PackageHeader;
- UINT8 *Package;
- UINT8 *OpCodeData;
- EFI_STATUS Status;
- EFI_HII_HANDLE HiiHandle;
-
- ASSERT (ComparingGuid != NULL);
-
- HiiHandle = NULL;
- //
- // Get all the Hii handles
- //
- HiiHandles = HiiGetHiiHandles (NULL);
- ASSERT (HiiHandles != NULL);
-
- //
- // Search for formset of each class type
- //
- for (Index = 0; HiiHandles[Index] != NULL; Index++) {
- BufferSize = 0;
- HiiPackageList = NULL;
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- HiiPackageList = AllocatePool (BufferSize);
- ASSERT (HiiPackageList != NULL);
-
- Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, HiiHandles[Index], &BufferSize, HiiPackageList);
- }
- if (EFI_ERROR (Status) || HiiPackageList == NULL) {
- return NULL;
- }
-
- //
- // Get Form package from this HII package List
- //
- Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
- Offset2 = 0;
- CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
-
- while (Offset < PackageListLength) {
- Package = ((UINT8 *) HiiPackageList) + Offset;
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
-
- if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
- //
- // Search FormSet in this Form Package
- //
- Offset2 = sizeof (EFI_HII_PACKAGE_HEADER);
- while (Offset2 < PackageHeader.Length) {
- OpCodeData = Package + Offset2;
-
- if (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode == EFI_IFR_FORM_SET_OP) {
- //
- // Try to compare against formset GUID
- //
- if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
- HiiHandle = HiiHandles[Index];
- break;
- }
- }
-
- Offset2 += ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
- }
- }
- if (HiiHandle != NULL) {
- break;
- }
- Offset += PackageHeader.Length;
- }
-
- FreePool (HiiPackageList);
- if (HiiHandle != NULL) {
- break;
- }
- }
-
- FreePool (HiiHandles);
-
- return HiiHandle;
-}
-
-/**
- Process the goto op code, update the info in the selection structure.
-
- @param Statement The statement belong to goto op code.
- @param Selection The selection info.
- @param Repaint Whether need to repaint the menu.
- @param NewLine Whether need to create new line.
-
- @retval EFI_SUCCESS The menu process successfully.
- @return Other value if the process failed.
-**/
-EFI_STATUS
-ProcessGotoOpCode (
- IN OUT FORM_BROWSER_STATEMENT *Statement,
- IN OUT UI_MENU_SELECTION *Selection,
- OUT BOOLEAN *Repaint,
- OUT BOOLEAN *NewLine
- )
-{
- CHAR16 *StringPtr;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- FORM_BROWSER_FORM *RefForm;
- EFI_INPUT_KEY Key;
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
- StringPtr = NULL;
-
- //
- // Prepare the device path check, get the device path info first.
- //
- if (Statement->HiiValue.Value.ref.DevicePath != 0) {
- StringPtr = GetToken (Statement->HiiValue.Value.ref.DevicePath, Selection->FormSet->HiiHandle);
- }
-
- //
- // Check whether the device path string is a valid string.
- //
- if (Statement->HiiValue.Value.ref.DevicePath != 0 && StringPtr != NULL) {
- if (Selection->Form->ModalForm) {
- return Status;
- }
-
- //
- // Goto another Hii Package list
- //
- if (mPathFromText != NULL) {
- DevicePath = mPathFromText->ConvertTextToDevicePath(StringPtr);
- if (DevicePath != NULL) {
- Selection->Handle = DevicePathToHiiHandle (DevicePath);
- FreePool (DevicePath);
- }
- FreePool (StringPtr);
- } else {
- //
- // Not found the EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol.
- //
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gProtocolNotFound, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- if (Repaint != NULL) {
- *Repaint = TRUE;
- }
- FreePool (StringPtr);
- return Status;
- }
-
- Selection->Action = UI_ACTION_REFRESH_FORMSET;
- if (Selection->Handle == NULL) {
- //
- // If target Hii Handle not found, exit
- //
- Selection->Action = UI_ACTION_EXIT;
- Selection->Statement = NULL;
- return Status;
- }
-
- CopyMem (&Selection->FormSetGuid,&Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
- Selection->FormId = Statement->HiiValue.Value.ref.FormId;
- Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
- } else if (!CompareGuid (&Statement->HiiValue.Value.ref.FormSetGuid, &gZeroGuid)) {
- if (Selection->Form->ModalForm) {
- return Status;
- }
- //
- // Goto another Formset, check for uncommitted data
- //
- Selection->Action = UI_ACTION_REFRESH_FORMSET;
-
- Selection->Handle = FormSetGuidToHiiHandle(&Statement->HiiValue.Value.ref.FormSetGuid);
- if (Selection->Handle == NULL) {
- //
- // If target Hii Handle not found, exit
- //
- Selection->Action = UI_ACTION_EXIT;
- Selection->Statement = NULL;
- return Status;
- }
-
- CopyMem (&Selection->FormSetGuid, &Statement->HiiValue.Value.ref.FormSetGuid, sizeof (EFI_GUID));
- Selection->FormId = Statement->HiiValue.Value.ref.FormId;
- Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
- } else if (Statement->HiiValue.Value.ref.FormId != 0) {
- //
- // Check whether target From is suppressed.
- //
- RefForm = IdToForm (Selection->FormSet, Statement->HiiValue.Value.ref.FormId);
-
- if ((RefForm != NULL) && (RefForm->SuppressExpression != NULL)) {
- if (EvaluateExpressionList(RefForm->SuppressExpression, TRUE, Selection->FormSet, RefForm) != ExpressFalse) {
- //
- // Form is suppressed.
- //
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, gEmptyString, gFormSuppress, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- if (Repaint != NULL) {
- *Repaint = TRUE;
- }
- return Status;
- }
- }
-
- //
- // Goto another form inside this formset,
- //
- Selection->Action = UI_ACTION_REFRESH_FORM;
-
- Selection->FormId = Statement->HiiValue.Value.ref.FormId;
- Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
- } else if (Statement->HiiValue.Value.ref.QuestionId != 0) {
- //
- // Goto another Question
- //
- Selection->QuestionId = Statement->HiiValue.Value.ref.QuestionId;
-
- if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- Selection->Action = UI_ACTION_REFRESH_FORM;
- } else {
- if (Repaint != NULL) {
- *Repaint = TRUE;
- }
- if (NewLine != NULL) {
- *NewLine = TRUE;
- }
- }
- } else {
- if ((Statement->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != 0) {
- Selection->Action = UI_ACTION_REFRESH_FORM;
- }
- }
-
- return Status;
-}
-
-/**
- Display menu and wait for user to select one menu option, then return it.
- If AutoBoot is enabled, then if user doesn't select any option,
- after period of time, it will automatically return the first menu option.
-
- @param Selection Menu selection.
-
- @retval EFI_SUCESSS This function always return successfully for now.
-
-**/
-EFI_STATUS
-UiDisplayMenu (
- IN OUT UI_MENU_SELECTION *Selection
- )
-{
- INTN SkipValue;
- INTN Difference;
- UINTN DistanceValue;
- UINTN Row;
- UINTN Col;
- UINTN Temp;
- UINTN Temp2;
- UINTN TopRow;
- UINTN BottomRow;
- UINTN OriginalRow;
- UINTN Index;
- UINT16 Width;
- CHAR16 *StringPtr;
- CHAR16 *OptionString;
- CHAR16 *OutputString;
- CHAR16 *HelpString;
- CHAR16 *HelpHeaderString;
- CHAR16 *HelpBottomString;
- BOOLEAN NewLine;
- BOOLEAN Repaint;
- BOOLEAN SavedValue;
- BOOLEAN UpArrow;
- BOOLEAN DownArrow;
- BOOLEAN InitializedFlag;
- EFI_STATUS Status;
- EFI_INPUT_KEY Key;
- LIST_ENTRY *Link;
- LIST_ENTRY *NewPos;
- LIST_ENTRY *TopOfScreen;
- LIST_ENTRY *SavedListEntry;
- UI_MENU_OPTION *MenuOption;
- UI_MENU_OPTION *NextMenuOption;
- UI_MENU_OPTION *SavedMenuOption;
- UI_MENU_OPTION *PreviousMenuOption;
- UI_CONTROL_FLAG ControlFlag;
- EFI_SCREEN_DESCRIPTOR LocalScreen;
- MENU_REFRESH_ENTRY *MenuRefreshEntry;
- MENU_REFRESH_ENTRY *MenuUpdateEntry;
- UI_SCREEN_OPERATION ScreenOperation;
- UINT8 MinRefreshInterval;
- UINT16 DefaultId;
- FORM_BROWSER_STATEMENT *Statement;
- UI_MENU_LIST *CurrentMenu;
- UINTN ModalSkipColumn;
- BROWSER_HOT_KEY *HotKey;
- UINTN HelpPageIndex;
- UINTN HelpPageCount;
- UINTN RowCount;
- UINTN HelpLine;
- UINTN HelpHeaderLine;
- UINTN HelpBottomLine;
- BOOLEAN MultiHelpPage;
- UINT16 GlyphWidth;
- UINT16 EachLineWidth;
- UINT16 HeaderLineWidth;
- UINT16 BottomLineWidth;
-
- CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
-
- Status = EFI_SUCCESS;
- HelpString = NULL;
- HelpHeaderString = NULL;
- HelpBottomString = NULL;
- OptionString = NULL;
- ScreenOperation = UiNoOperation;
- NewLine = TRUE;
- MinRefreshInterval = 0;
- DefaultId = 0;
- HelpPageCount = 0;
- HelpLine = 0;
- RowCount = 0;
- HelpBottomLine = 0;
- HelpHeaderLine = 0;
- HelpPageIndex = 0;
- MultiHelpPage = FALSE;
- EachLineWidth = 0;
- HeaderLineWidth = 0;
- BottomLineWidth = 0;
- OutputString = NULL;
- UpArrow = FALSE;
- DownArrow = FALSE;
- SkipValue = 0;
- MenuRefreshEntry = gMenuRefreshHead;
-
- NextMenuOption = NULL;
- PreviousMenuOption = NULL;
- SavedMenuOption = NULL;
- HotKey = NULL;
- ModalSkipColumn = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 6;
-
- ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
-
- if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE){
- TopRow = LocalScreen.TopRow + FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;
- Row = LocalScreen.TopRow + FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;
- } else {
- TopRow = LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;
- Row = LocalScreen.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT + SCROLL_ARROW_HEIGHT;
- }
-
- if (Selection->Form->ModalForm) {
- Col = LocalScreen.LeftColumn + LEFT_SKIPPED_COLUMNS + ModalSkipColumn;
- } else {
- Col = LocalScreen.LeftColumn + LEFT_SKIPPED_COLUMNS;
- }
-
- BottomRow = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight - SCROLL_ARROW_HEIGHT - 1;
-
- Selection->TopRow = TopRow;
- Selection->BottomRow = BottomRow;
- Selection->PromptCol = Col;
- Selection->OptionCol = gPromptBlockWidth + 1 + LocalScreen.LeftColumn;
- Selection->Statement = NULL;
-
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
-
- //
- // Find current Menu
- //
- CurrentMenu = UiFindMenuList (Selection->Handle, &Selection->FormSetGuid, Selection->FormId);
- if (CurrentMenu == NULL) {
- //
- // Current menu not found, add it to the menu tree
- //
- CurrentMenu = UiAddMenuList (Selection->CurrentMenu, Selection->Handle, &Selection->FormSetGuid, Selection->FormId);
- }
- ASSERT (CurrentMenu != NULL);
- Selection->CurrentMenu = CurrentMenu;
-
- if (Selection->QuestionId == 0) {
- //
- // Highlight not specified, fetch it from cached menu
- //
- Selection->QuestionId = CurrentMenu->QuestionId;
- Selection->Sequence = CurrentMenu->Sequence;
- }
-
- //
- // Init option as the current user's selection
- //
- InitializedFlag = TRUE;
- NewPos = gMenuOption.ForwardLink;
-
- gST->ConOut->EnableCursor (gST->ConOut, FALSE);
- UpdateStatusBar (Selection, REFRESH_STATUS_BAR, (UINT8) 0, TRUE);
-
- ControlFlag = CfInitialization;
- Selection->Action = UI_ACTION_NONE;
- while (TRUE) {
- switch (ControlFlag) {
- case CfInitialization:
- if (IsListEmpty (&gMenuOption)) {
- ControlFlag = CfReadKey;
- } else {
- ControlFlag = CfCheckSelection;
- }
- break;
-
- case CfCheckSelection:
- if (Selection->Action != UI_ACTION_NONE) {
- ControlFlag = CfExit;
- } else {
- ControlFlag = CfRepaint;
- }
- break;
-
- case CfRepaint:
- ControlFlag = CfRefreshHighLight;
-
- if (Repaint) {
- //
- // Display menu
- //
- DownArrow = FALSE;
- UpArrow = FALSE;
- Row = TopRow;
-
- Temp = (UINTN) SkipValue;
- Temp2 = (UINTN) SkipValue;
-
- //
- // 1. Clear the screen.
- //
- if (Selection->Form->ModalForm) {
- ClearLines (
- LocalScreen.LeftColumn + ModalSkipColumn,
- LocalScreen.LeftColumn + ModalSkipColumn + gPromptBlockWidth + gOptionBlockWidth,
- TopRow - SCROLL_ARROW_HEIGHT,
- BottomRow + SCROLL_ARROW_HEIGHT,
- PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND
- );
- } else {
- ClearLines (
- LocalScreen.LeftColumn,
- LocalScreen.RightColumn,
- TopRow - SCROLL_ARROW_HEIGHT,
- BottomRow + SCROLL_ARROW_HEIGHT,
- PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND
- );
- }
- UiFreeRefreshList ();
- MinRefreshInterval = 0;
-
- //
- // 2.Paint the menu.
- //
- for (Link = TopOfScreen; Link != &gMenuOption; Link = Link->ForwardLink) {
- MenuOption = MENU_OPTION_FROM_LINK (Link);
- MenuOption->Row = Row;
- MenuOption->Col = Col;
- if (Selection->Form->ModalForm) {
- MenuOption->OptCol = gPromptBlockWidth + 1 + LocalScreen.LeftColumn + ModalSkipColumn;
- } else {
- MenuOption->OptCol = gPromptBlockWidth + 1 + LocalScreen.LeftColumn;
- }
-
- Statement = MenuOption->ThisTag;
- if (Statement->InSubtitle) {
- MenuOption->Col += SUBTITLE_INDENT;
- }
-
- if (MenuOption->GrayOut) {
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | FIELD_BACKGROUND);
- } else {
- if (Statement->Operand == EFI_IFR_SUBTITLE_OP) {
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserSubtitleTextColor) | FIELD_BACKGROUND);
- }
- }
-
- Width = GetWidth (Statement, MenuOption->Handle);
- OriginalRow = Row;
- GlyphWidth = 1;
-
- if (Statement->Operand == EFI_IFR_REF_OP && MenuOption->Col >= 2) {
- //
- // Print Arrow for Goto button.
- //
- PrintAt (
- MenuOption->Col - 2,
- Row,
- L"%c",
- GEOMETRICSHAPE_RIGHT_TRIANGLE
- );
- }
-
- //
- // 2.1. Paint the description.
- //
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- //
- // Temp means need to skip how many lines from the start.
- //
- if ((Temp == 0) && (Row <= BottomRow)) {
- PrintStringAt (MenuOption->Col, Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp == 0) {
- Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- Temp = 0;
- Row = OriginalRow;
-
- //
- // 2.2. Paint the option string.
- //
- Status = ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
- if (EFI_ERROR (Status)) {
- //
- // Repaint to clear possible error prompt pop-up
- //
- Repaint = TRUE;
- NewLine = TRUE;
- ControlFlag = CfRepaint;
- break;
- }
-
- if (OptionString != NULL) {
- if (Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) {
- ProcessStringForDateTime(MenuOption, OptionString, TRUE);
- }
-
- Width = (UINT16) gOptionBlockWidth;
- OriginalRow = Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (Row <= BottomRow)) {
- PrintStringAt (MenuOption->OptCol, Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp2 == 0) {
- Row++;
- //
- // Since the Number of lines for this menu entry may or may not be reflected accurately
- // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
- // some testing to ensure we are keeping this in-sync.
- //
- // If the difference in rows is greater than or equal to the skip value, increase the skip value
- //
- if ((Row - OriginalRow) >= MenuOption->Skip) {
- MenuOption->Skip++;
- }
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- Temp2 = 0;
- Row = OriginalRow;
-
- FreePool (OptionString);
- }
-
- //
- // 2.4 Special process for Test opcode with test two.
- //
- if (!CompareGuid (&Statement->RefreshGuid, &gZeroGuid)) {
- if (gMenuEventGuidRefreshHead == NULL) {
- MenuUpdateEntry = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));
- gMenuEventGuidRefreshHead = MenuUpdateEntry;
- } else {
- MenuUpdateEntry = gMenuEventGuidRefreshHead;
- while (MenuUpdateEntry->Next != NULL) {
- MenuUpdateEntry = MenuUpdateEntry->Next;
- }
- MenuUpdateEntry->Next = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));
- MenuUpdateEntry = MenuUpdateEntry->Next;
- }
- ASSERT (MenuUpdateEntry != NULL);
- Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, RefreshQuestionNotify, MenuUpdateEntry, &Statement->RefreshGuid, &MenuUpdateEntry->Event);
- ASSERT (!EFI_ERROR (Status));
- MenuUpdateEntry->MenuOption = MenuOption;
- MenuUpdateEntry->Selection = Selection;
- MenuUpdateEntry->CurrentColumn = MenuOption->OptCol;
- MenuUpdateEntry->CurrentRow = MenuOption->Row;
- if (MenuOption->GrayOut) {
- MenuUpdateEntry->CurrentAttribute = FIELD_TEXT_GRAYED | FIELD_BACKGROUND;
- } else {
- MenuUpdateEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;
- }
- }
-
- //
- // If Question request refresh, register the op-code
- //
- if (Statement->RefreshInterval != 0) {
- //
- // Menu will be refreshed at minimal interval of all Questions
- // which have refresh request
- //
- if (MinRefreshInterval == 0 || Statement->RefreshInterval < MinRefreshInterval) {
- MinRefreshInterval = Statement->RefreshInterval;
- }
-
- if (gMenuRefreshHead == NULL) {
- MenuRefreshEntry = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));
- gMenuRefreshHead = MenuRefreshEntry;
- } else {
- MenuRefreshEntry = gMenuRefreshHead;
- while (MenuRefreshEntry->Next != NULL) {
- MenuRefreshEntry = MenuRefreshEntry->Next;
- }
- MenuRefreshEntry->Next = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));
- MenuRefreshEntry = MenuRefreshEntry->Next;
- }
- ASSERT (MenuRefreshEntry != NULL);
- MenuRefreshEntry->MenuOption = MenuOption;
- MenuRefreshEntry->Selection = Selection;
- MenuRefreshEntry->CurrentColumn = MenuOption->OptCol;
- MenuRefreshEntry->CurrentRow = MenuOption->Row;
- if (MenuOption->GrayOut) {
- MenuRefreshEntry->CurrentAttribute = FIELD_TEXT_GRAYED | FIELD_BACKGROUND;
- } else {
- MenuRefreshEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;
- }
- }
-
- //
- // If this is a text op with secondary text information
- //
- if ((Statement->Operand == EFI_IFR_TEXT_OP) && (Statement->TextTwo != 0)) {
- StringPtr = GetToken (Statement->TextTwo, MenuOption->Handle);
-
- Width = (UINT16) gOptionBlockWidth;
- OriginalRow = Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (StringPtr, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (Row <= BottomRow)) {
- PrintStringAt (MenuOption->OptCol, Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&StringPtr[Index]) != 0) {
- if (Temp2 == 0) {
- Row++;
- //
- // Since the Number of lines for this menu entry may or may not be reflected accurately
- // since the prompt might be 1 lines and option might be many, and vice versa, we need to do
- // some testing to ensure we are keeping this in-sync.
- //
- // If the difference in rows is greater than or equal to the skip value, increase the skip value
- //
- if ((Row - OriginalRow) >= MenuOption->Skip) {
- MenuOption->Skip++;
- }
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- Row = OriginalRow;
- FreePool (StringPtr);
- }
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
-
- //
- // 3. Update the row info which will be used by next menu.
- //
- if (Link == TopOfScreen) {
- Row += MenuOption->Skip - SkipValue;
- } else {
- Row += MenuOption->Skip;
- }
-
- if (Row > BottomRow) {
- if (!ValueIsScroll (FALSE, Link)) {
- DownArrow = TRUE;
- }
-
- Row = BottomRow + 1;
- break;
- }
- }
-
- if (!ValueIsScroll (TRUE, TopOfScreen)) {
- UpArrow = TRUE;
- }
-
- if (UpArrow) {
- gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);
- PrintAt (
- LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
- TopRow - SCROLL_ARROW_HEIGHT,
- L"%c",
- ARROW_UP
- );
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
- }
-
- if (DownArrow) {
- gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);
- PrintAt (
- LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
- BottomRow + SCROLL_ARROW_HEIGHT,
- L"%c",
- ARROW_DOWN
- );
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
- }
-
- MenuOption = NULL;
- }
- break;
-
- case CfRefreshHighLight:
- //
- // MenuOption: Last menu option that need to remove hilight
- // MenuOption is set to NULL in Repaint
- // NewPos: Current menu option that need to hilight
- //
- ControlFlag = CfUpdateHelpString;
- if (TopOfScreen == &MenuOption->Link) {
- Temp = SkipValue;
- } else {
- Temp = 0;
- }
- if (NewPos == TopOfScreen) {
- Temp2 = SkipValue;
- } else {
- Temp2 = 0;
- }
- if (InitializedFlag) {
- InitializedFlag = FALSE;
- MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
- }
-
- //
- // Repaint flag is normally reset when finish processing CfUpdateHelpString. Temporarily
- // reset Repaint flag because we may break halfway and skip CfUpdateHelpString processing.
- //
- SavedValue = Repaint;
- Repaint = FALSE;
-
- if (Selection->QuestionId != 0) {
- NewPos = gMenuOption.ForwardLink;
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
-
- while ((SavedMenuOption->ThisTag->QuestionId != Selection->QuestionId ||
- SavedMenuOption->Sequence != Selection->Sequence) &&
- NewPos->ForwardLink != &gMenuOption) {
- NewPos = NewPos->ForwardLink;
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- }
- if (SavedMenuOption->ThisTag->QuestionId == Selection->QuestionId) {
- //
- // Target Question found, find its MenuOption
- //
- Link = TopOfScreen;
-
- for (Index = TopRow; Index <= BottomRow && Link != NewPos;) {
- SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
- Index += SavedMenuOption->Skip;
- if (Link == TopOfScreen) {
- Index -= SkipValue;
- }
- Link = Link->ForwardLink;
- }
- if (NewPos == Link) {
- SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
- }
-
- //
- // Not find the selected menu in current show page.
- // Have two case to enter this if:
- // 1. Not find the menu at current page.
- // 2. Find the menu in current page, but the menu shows at the bottom and not all info shows.
- // For case 2, has an exception: The menu can show more than one pages and now only this menu shows.
- //
- // Base on the selected menu will show at the bottom of the page,
- // select the menu which will show at the top of the page.
- //
- if (Link != NewPos || Index > BottomRow ||
- (Link == NewPos && (SavedMenuOption->Row + SavedMenuOption->Skip - 1 > BottomRow) && (Link != TopOfScreen))) {
- //
- // Find the MenuOption which has the skip value for Date/Time opcode.
- //
- AdjustDateAndTimePosition(FALSE, &NewPos);
- //
- // NewPos is not in the current page, simply scroll page so that NewPos is in the end of the page
- //
- SavedMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- //
- // SavedMenuOption->Row == 0 means the menu not show yet.
- //
- if (SavedMenuOption->Row == 0) {
- UpdateOptionSkipLines (Selection, SavedMenuOption);
- }
-
- //
- // Base on the selected menu will show at the bottome of next page,
- // select the menu show at the top of the next page.
- //
- Link = NewPos;
- for (Index = TopRow + SavedMenuOption->Skip; Index <= BottomRow + 1; ) {
- Link = Link->BackLink;
- SavedMenuOption = MENU_OPTION_FROM_LINK (Link);
- if (SavedMenuOption->Row == 0) {
- UpdateOptionSkipLines (Selection, SavedMenuOption);
- }
- Index += SavedMenuOption->Skip;
- }
-
- //
- // Found the menu which will show at the top of the page.
- //
- if (Link == NewPos) {
- //
- // The menu can show more than one pages, just show the menu at the top of the page.
- //
- SkipValue = 0;
- TopOfScreen = Link;
- } else {
- //
- // Check whether need to skip some line for menu shows at the top of the page.
- //
- SkipValue = Index - BottomRow - 1;
- if (SkipValue > 0 && SkipValue < (INTN) SavedMenuOption->Skip) {
- TopOfScreen = Link;
- } else {
- SkipValue = 0;
- TopOfScreen = Link->ForwardLink;
- }
- }
-
- Repaint = TRUE;
- NewLine = TRUE;
- ControlFlag = CfRepaint;
- break;
- }
- } else {
- //
- // Target Question not found, highlight the default menu option
- //
- NewPos = TopOfScreen;
- }
-
- Selection->QuestionId = 0;
- }
-
- if (NewPos != NULL && (MenuOption == NULL || NewPos != &MenuOption->Link)) {
- if (MenuOption != NULL) {
- //
- // Remove highlight on last Menu Option
- //
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
- ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
- if (OptionString != NULL) {
- if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) ||
- (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)
- ) {
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);
- }
-
- Width = (UINT16) gOptionBlockWidth;
- OriginalRow = MenuOption->Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- FreePool (OptionString);
- } else {
- if (NewLine) {
- if (MenuOption->GrayOut) {
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | FIELD_BACKGROUND);
- } else if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP) {
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserSubtitleTextColor) | FIELD_BACKGROUND);
- }
-
- OriginalRow = MenuOption->Row;
- Width = GetWidth (MenuOption->ThisTag, MenuOption->Handle);
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow)) {
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- MenuOption->Row = OriginalRow;
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
- }
- }
- }
-
- //
- // This is the current selected statement
- //
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- Statement = MenuOption->ThisTag;
- Selection->Statement = Statement;
- if (!IsSelectable (MenuOption)) {
- Repaint = SavedValue;
- UpdateKeyHelp (Selection, MenuOption, FALSE);
- break;
- }
-
- //
- // Record highlight for current menu
- //
- CurrentMenu->QuestionId = Statement->QuestionId;
- CurrentMenu->Sequence = MenuOption->Sequence;
-
- //
- // Set reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor));
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
-
- //
- // Assuming that we have a refresh linked-list created, lets annotate the
- // appropriate entry that we are highlighting with its new attribute. Just prior to this
- // lets reset all of the entries' attribute so we do not get multiple highlights in he refresh
- //
- if (gMenuRefreshHead != NULL) {
- for (MenuRefreshEntry = gMenuRefreshHead; MenuRefreshEntry != NULL; MenuRefreshEntry = MenuRefreshEntry->Next) {
- if (MenuRefreshEntry->MenuOption->GrayOut) {
- MenuRefreshEntry->CurrentAttribute = FIELD_TEXT_GRAYED | FIELD_BACKGROUND;
- } else {
- MenuRefreshEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND;
- }
- if (MenuRefreshEntry->MenuOption == MenuOption) {
- MenuRefreshEntry->CurrentAttribute = PcdGet8 (PcdBrowserFieldTextHighlightColor) | PcdGet8 (PcdBrowserFieldBackgroundHighlightColor);
- }
- }
- }
-
- ProcessOptions (Selection, MenuOption, FALSE, &OptionString);
- if (OptionString != NULL) {
- if (Statement->Operand == EFI_IFR_DATE_OP || Statement->Operand == EFI_IFR_TIME_OP) {
- ProcessStringForDateTime(MenuOption, OptionString, FALSE);
- }
- Width = (UINT16) gOptionBlockWidth;
-
- OriginalRow = MenuOption->Row;
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
- PrintStringAt (MenuOption->OptCol, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index]) != 0) {
- if (Temp2 == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- FreePool (OptionString);
- } else {
- if (NewLine) {
- OriginalRow = MenuOption->Row;
-
- Width = GetWidth (Statement, MenuOption->Handle);
- GlyphWidth = 1;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &GlyphWidth, &Index, &OutputString) != 0x0000;) {
- if ((Temp2 == 0) && (MenuOption->Row >= TopRow) && (MenuOption->Row <= BottomRow) ) {
- PrintStringAt (MenuOption->Col, MenuOption->Row, OutputString);
- }
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&MenuOption->Description[Index]) != 0) {
- if (Temp2 == 0) {
- MenuOption->Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp2 != 0) {
- Temp2--;
- }
- }
-
- MenuOption->Row = OriginalRow;
-
- }
- }
-
- UpdateKeyHelp (Selection, MenuOption, FALSE);
-
- //
- // Clear reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND);
- }
- //
- // Repaint flag will be used when process CfUpdateHelpString, so restore its value
- // if we didn't break halfway when process CfRefreshHighLight.
- //
- Repaint = SavedValue;
- break;
-
- case CfUpdateHelpString:
- ControlFlag = CfPrepareToReadKey;
- if (Selection->Form->ModalForm) {
- break;
- }
-
- if (Repaint || NewLine) {
- //
- // Don't print anything if it is a NULL help token
- //
- ASSERT(MenuOption != NULL);
- if (MenuOption->ThisTag->Help == 0 || !IsSelectable (MenuOption)) {
- StringPtr = L"\0";
- } else {
- StringPtr = GetToken (MenuOption->ThisTag->Help, MenuOption->Handle);
- }
-
- RowCount = BottomRow - TopRow;
- HelpPageIndex = 0;
- //
- // 1.Calculate how many line the help string need to print.
- //
- if (HelpString != NULL) {
- FreePool (HelpString);
- }
- HelpLine = ProcessHelpString (StringPtr, &HelpString, &EachLineWidth, RowCount);
- if (HelpLine > RowCount) {
- MultiHelpPage = TRUE;
- StringPtr = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_UP), gHiiHandle);
- if (HelpHeaderString != NULL) {
- FreePool (HelpHeaderString);
- }
- HelpHeaderLine = ProcessHelpString (StringPtr, &HelpHeaderString, &HeaderLineWidth, RowCount);
- StringPtr = GetToken (STRING_TOKEN(ADJUST_HELP_PAGE_DOWN), gHiiHandle);
- if (HelpBottomString != NULL) {
- FreePool (HelpBottomString);
- }
- HelpBottomLine = ProcessHelpString (StringPtr, &HelpBottomString, &BottomLineWidth, RowCount);
- //
- // Calculate the help page count.
- //
- if (HelpLine > 2 * RowCount - 2) {
- HelpPageCount = (HelpLine - RowCount + 1) / (RowCount - 2) + 1;
- if ((HelpLine - RowCount + 1) % (RowCount - 2) > 1) {
- HelpPageCount += 1;
- }
- } else {
- HelpPageCount = 2;
- }
- } else {
- MultiHelpPage = FALSE;
- }
- }
-
- //
- // Clean the help field first.
- //
- ClearLines (
- LocalScreen.RightColumn - gHelpBlockWidth,
- LocalScreen.RightColumn,
- TopRow,
- BottomRow,
- PcdGet8 (PcdBrowserFieldTextColor) | FIELD_BACKGROUND
- );
-
- //
- // Check whether need to show the 'More(U/u)' at the begin.
- // Base on current direct info, here shows aligned to the right side of the column.
- // If the direction is multi line and aligned to right side may have problem, so
- // add ASSERT code here.
- //
- if (HelpPageIndex > 0) {
- gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT | FIELD_BACKGROUND);
- for (Index = 0; Index < HelpHeaderLine; Index++) {
- ASSERT (HelpHeaderLine == 1);
- ASSERT (GetStringWidth (HelpHeaderString) / 2 < (UINTN) (gHelpBlockWidth - 1));
- PrintStringAt (
- LocalScreen.RightColumn - GetStringWidth (HelpHeaderString) / 2 - 1,
- Index + TopRow,
- &HelpHeaderString[Index * HeaderLineWidth]
- );
- }
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, HELP_TEXT | FIELD_BACKGROUND);
- //
- // Print the help string info.
- //
- if (!MultiHelpPage) {
- for (Index = 0; Index < HelpLine; Index++) {
- PrintStringAt (
- LocalScreen.RightColumn - gHelpBlockWidth,
- Index + TopRow,
- &HelpString[Index * EachLineWidth]
- );
- }
- gST->ConOut->SetCursorPosition(gST->ConOut, LocalScreen.RightColumn-1, BottomRow);
- } else {
- if (HelpPageIndex == 0) {
- for (Index = 0; Index < RowCount - HelpBottomLine; Index++) {
- PrintStringAt (
- LocalScreen.RightColumn - gHelpBlockWidth,
- Index + TopRow,
- &HelpString[Index * EachLineWidth]
- );
- }
- } else {
- for (Index = 0; (Index < RowCount - HelpBottomLine - HelpHeaderLine) &&
- (Index + HelpPageIndex * (RowCount - 2) + 1 < HelpLine); Index++) {
- PrintStringAt (
- LocalScreen.RightColumn - gHelpBlockWidth,
- Index + TopRow + HelpHeaderLine,
- &HelpString[(Index + HelpPageIndex * (RowCount - 2) + 1)* EachLineWidth]
- );
- }
- if (HelpPageIndex == HelpPageCount - 1) {
- gST->ConOut->SetCursorPosition(gST->ConOut, LocalScreen.RightColumn-1, BottomRow);
- }
- }
- }
-
- //
- // Check whether need to print the 'More(D/d)' at the bottom.
- // Base on current direct info, here shows aligned to the right side of the column.
- // If the direction is multi line and aligned to right side may have problem, so
- // add ASSERT code here.
- //
- if (HelpPageIndex < HelpPageCount - 1 && MultiHelpPage) {
- gST->ConOut->SetAttribute (gST->ConOut, INFO_TEXT | FIELD_BACKGROUND);
- for (Index = 0; Index < HelpBottomLine; Index++) {
- ASSERT (HelpBottomLine == 1);
- ASSERT (GetStringWidth (HelpBottomString) / 2 < (UINTN) (gHelpBlockWidth - 1));
- PrintStringAt (
- LocalScreen.RightColumn - GetStringWidth (HelpBottomString) / 2 - 1,
- Index + BottomRow - HelpBottomLine,
- &HelpBottomString[Index * BottomLineWidth]
- );
- }
- }
- //
- // Reset this flag every time we finish using it.
- //
- Repaint = FALSE;
- NewLine = FALSE;
- break;
-
- case CfPrepareToReadKey:
- ControlFlag = CfReadKey;
- ScreenOperation = UiNoOperation;
- break;
-
- case CfReadKey:
- ControlFlag = CfScreenOperation;
-
- //
- // Wait for user's selection
- //
- while (TRUE) {
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
- if (!EFI_ERROR (Status)) {
- break;
- }
-
- //
- // If we encounter error, continue to read another key in.
- //
- if (Status != EFI_NOT_READY) {
- continue;
- }
-
- Status = UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0, MinRefreshInterval);
- ASSERT_EFI_ERROR (Status);
-
- if (Selection->Action == UI_ACTION_REFRESH_FORMSET) {
- //
- // IFR is updated in Callback of refresh opcode, re-parse it
- //
- ControlFlag = CfCheckSelection;
- Selection->Statement = NULL;
- break;
- }
- }
-
- if (ControlFlag == CfCheckSelection) {
- break;
- }
-
- switch (Key.UnicodeChar) {
- case CHAR_CARRIAGE_RETURN:
- if(MenuOption->GrayOut || MenuOption->ReadOnly) {
- ControlFlag = CfReadKey;
- break;
- }
-
- ScreenOperation = UiSelect;
- gDirection = 0;
- break;
-
- //
- // We will push the adjustment of these numeric values directly to the input handler
- // NOTE: we won't handle manual input numeric
- //
- case '+':
- case '-':
- //
- // If the screen has no menu items, and the user didn't select UiReset
- // ignore the selection and go back to reading keys.
- //
- if(IsListEmpty (&gMenuOption) || MenuOption->GrayOut || MenuOption->ReadOnly) {
- ControlFlag = CfReadKey;
- break;
- }
-
- ASSERT(MenuOption != NULL);
- Statement = MenuOption->ThisTag;
- if ((Statement->Operand == EFI_IFR_DATE_OP)
- || (Statement->Operand == EFI_IFR_TIME_OP)
- || ((Statement->Operand == EFI_IFR_NUMERIC_OP) && (Statement->Step != 0))
- ){
- if (Key.UnicodeChar == '+') {
- gDirection = SCAN_RIGHT;
- } else {
- gDirection = SCAN_LEFT;
- }
- Status = ProcessOptions (Selection, MenuOption, TRUE, &OptionString);
- if (EFI_ERROR (Status)) {
- //
- // Repaint to clear possible error prompt pop-up
- //
- Repaint = TRUE;
- NewLine = TRUE;
- } else {
- Selection->Action = UI_ACTION_REFRESH_FORM;
- }
- if (OptionString != NULL) {
- FreePool (OptionString);
- }
- }
- break;
-
- case '^':
- ScreenOperation = UiUp;
- break;
-
- case 'V':
- case 'v':
- ScreenOperation = UiDown;
- break;
-
- case ' ':
- if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {
- //
- // If the screen has no menu items, and the user didn't select UiReset
- // ignore the selection and go back to reading keys.
- //
- if(IsListEmpty (&gMenuOption)) {
- ControlFlag = CfReadKey;
- break;
- }
-
- ASSERT(MenuOption != NULL);
- if (MenuOption->ThisTag->Operand == EFI_IFR_CHECKBOX_OP && !MenuOption->GrayOut && !MenuOption->ReadOnly) {
- ScreenOperation = UiSelect;
- }
- }
- break;
-
- case 'D':
- case 'd':
- if (!MultiHelpPage) {
- ControlFlag = CfReadKey;
- break;
- }
- ControlFlag = CfUpdateHelpString;
- HelpPageIndex = HelpPageIndex < HelpPageCount - 1 ? HelpPageIndex + 1 : HelpPageCount - 1;
- break;
-
- case 'U':
- case 'u':
- if (!MultiHelpPage) {
- ControlFlag = CfReadKey;
- break;
- }
- ControlFlag = CfUpdateHelpString;
- HelpPageIndex = HelpPageIndex > 0 ? HelpPageIndex - 1 : 0;
- break;
-
- case CHAR_NULL:
- for (Index = 0; Index < mScanCodeNumber; Index++) {
- if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {
- ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;
- break;
- }
- }
-
- if (Selection->Form->ModalForm && (Key.ScanCode == SCAN_ESC || Index == mScanCodeNumber)) {
- //
- // ModalForm has no ESC key and Hot Key.
- //
- ControlFlag = CfReadKey;
- } else if (Index == mScanCodeNumber) {
- //
- // Check whether Key matches the registered hot key.
- //
- HotKey = NULL;
- if ((gBrowserSettingScope == SystemLevel) ||
- (Selection->FormEditable && gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
- HotKey = GetHotKeyFromRegisterList (&Key);
- }
- if (HotKey != NULL) {
- ScreenOperation = UiHotKey;
- }
- }
- break;
- }
- break;
-
- case CfScreenOperation:
- if (ScreenOperation != UiReset) {
- //
- // If the screen has no menu items, and the user didn't select UiReset
- // ignore the selection and go back to reading keys.
- //
- if (IsListEmpty (&gMenuOption)) {
- ControlFlag = CfReadKey;
- break;
- }
- }
-
- for (Index = 0;
- Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);
- Index++
- ) {
- if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {
- ControlFlag = gScreenOperationToControlFlag[Index].ControlFlag;
- break;
- }
- }
- break;
-
- case CfUiSelect:
- ControlFlag = CfCheckSelection;
-
- ASSERT(MenuOption != NULL);
- Statement = MenuOption->ThisTag;
- if (Statement->Operand == EFI_IFR_TEXT_OP) {
- break;
- }
-
- //
- // Keep highlight on current MenuOption
- //
- Selection->QuestionId = Statement->QuestionId;
-
- switch (Statement->Operand) {
- case EFI_IFR_REF_OP:
- ProcessGotoOpCode(Statement, Selection, &Repaint, &NewLine);
- break;
-
- case EFI_IFR_ACTION_OP:
- //
- // Process the Config string <ConfigResp>
- //
- Status = ProcessQuestionConfig (Selection, Statement);
-
- if (EFI_ERROR (Status)) {
- break;
- }
-
- //
- // The action button may change some Question value, so refresh the form
- //
- Selection->Action = UI_ACTION_REFRESH_FORM;
- break;
-
- case EFI_IFR_RESET_BUTTON_OP:
- //
- // Reset Question to default value specified by DefaultId
- //
- ControlFlag = CfUiDefault;
- DefaultId = Statement->DefaultId;
- break;
-
- default:
- //
- // Editable Questions: oneof, ordered list, checkbox, numeric, string, password
- //
- UpdateKeyHelp (Selection, MenuOption, TRUE);
- Status = ProcessOptions (Selection, MenuOption, TRUE, &OptionString);
-
- if (EFI_ERROR (Status)) {
- Repaint = TRUE;
- NewLine = TRUE;
- UpdateKeyHelp (Selection, MenuOption, FALSE);
- } else {
- Selection->Action = UI_ACTION_REFRESH_FORM;
- }
-
- if (OptionString != NULL) {
- FreePool (OptionString);
- }
- break;
- }
- break;
-
- case CfUiReset:
- //
- // We come here when someone press ESC
- //
- ControlFlag = CfCheckSelection;
- FindNextMenu (Selection, &Repaint, &NewLine);
- break;
-
- case CfUiLeft:
- ControlFlag = CfCheckSelection;
- ASSERT(MenuOption != NULL);
- if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {
- if (MenuOption->Sequence != 0) {
- //
- // In the middle or tail of the Date/Time op-code set, go left.
- //
- ASSERT(NewPos != NULL);
- NewPos = NewPos->BackLink;
- }
- }
- break;
-
- case CfUiRight:
- ControlFlag = CfCheckSelection;
- ASSERT(MenuOption != NULL);
- if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {
- if (MenuOption->Sequence != 2) {
- //
- // In the middle or tail of the Date/Time op-code set, go left.
- //
- ASSERT(NewPos != NULL);
- NewPos = NewPos->ForwardLink;
- }
- }
- break;
-
- case CfUiUp:
- ControlFlag = CfCheckSelection;
-
- SavedListEntry = NewPos;
-
- ASSERT(NewPos != NULL);
- //
- // Adjust Date/Time position before we advance forward.
- //
- AdjustDateAndTimePosition (TRUE, &NewPos);
- if (NewPos->BackLink != &gMenuOption) {
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- ASSERT (MenuOption != NULL);
- NewLine = TRUE;
- NewPos = NewPos->BackLink;
-
- PreviousMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (PreviousMenuOption->Row == 0) {
- UpdateOptionSkipLines (Selection, PreviousMenuOption);
- }
- DistanceValue = PreviousMenuOption->Skip;
- Difference = 0;
- if (MenuOption->Row >= DistanceValue + TopRow) {
- Difference = MoveToNextStatement (Selection, TRUE, &NewPos, MenuOption->Row - TopRow - DistanceValue);
- }
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
-
- if (Difference < 0) {
- //
- // We hit the begining MenuOption that can be focused
- // so we simply scroll to the top.
- //
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- } else {
- //
- // Scroll up to the last page when we have arrived at top page.
- //
- NewPos = &gMenuOption;
- TopOfScreen = &gMenuOption;
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- ScreenOperation = UiPageUp;
- ControlFlag = CfScreenOperation;
- break;
- }
- } else if (MenuOption->Row < TopRow + DistanceValue + Difference) {
- //
- // Previous focus MenuOption is above the TopOfScreen, so we need to scroll
- //
- TopOfScreen = NewPos;
- Repaint = TRUE;
- SkipValue = 0;
- } else if (!IsSelectable (NextMenuOption)) {
- //
- // Continue to go up until scroll to next page or the selectable option is found.
- //
- ScreenOperation = UiUp;
- ControlFlag = CfScreenOperation;
- }
-
- //
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);
- } else {
- //
- // Scroll up to the last page.
- //
- NewPos = &gMenuOption;
- TopOfScreen = &gMenuOption;
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- ScreenOperation = UiPageUp;
- ControlFlag = CfScreenOperation;
- }
- break;
-
- case CfUiPageUp:
- //
- // SkipValue means lines is skipped when show the top menu option.
- //
- ControlFlag = CfCheckSelection;
-
- ASSERT(NewPos != NULL);
- //
- // Already at the first menu option, so do nothing.
- //
- if (NewPos->BackLink == &gMenuOption) {
- NewLine = FALSE;
- Repaint = FALSE;
- break;
- }
-
- NewLine = TRUE;
- Repaint = TRUE;
-
- //
- // SkipValue > (BottomRow - TopRow + 1) means current menu has more than one
- // form of options to be show, so just update the SkipValue to show the next
- // parts of options.
- //
- if (SkipValue > (INTN) (BottomRow - TopRow + 1)) {
- SkipValue -= BottomRow - TopRow + 1;
- break;
- }
-
- Link = TopOfScreen;
- //
- // First minus the menu of the top screen, it's value is SkipValue.
- //
- Index = (BottomRow + 1) - SkipValue;
- while ((Index >= TopRow) && (Link->BackLink != &gMenuOption)) {
- Link = Link->BackLink;
- PreviousMenuOption = MENU_OPTION_FROM_LINK (Link);
- if (PreviousMenuOption->Row == 0) {
- UpdateOptionSkipLines (Selection, PreviousMenuOption);
- }
- if (Index < PreviousMenuOption->Skip) {
- break;
- }
- Index = Index - PreviousMenuOption->Skip;
- }
-
- if ((Link->BackLink == &gMenuOption) && (Index >= TopRow)) {
- SkipValue = 0;
- if (TopOfScreen == &gMenuOption) {
- TopOfScreen = gMenuOption.ForwardLink;
- NewPos = gMenuOption.BackLink;
- MoveToNextStatement (Selection, TRUE, &NewPos, BottomRow - TopRow);
- Repaint = FALSE;
- } else if (TopOfScreen != Link) {
- TopOfScreen = Link;
- NewPos = Link;
- MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
- } else {
- //
- // Finally we know that NewPos is the last MenuOption can be focused.
- //
- Repaint = FALSE;
- NewPos = Link;
- MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
- }
- } else {
- if (Index >= TopRow) {
- //
- // At here, only case "Index < PreviousMenuOption->Skip" can reach here.
- //
- SkipValue = PreviousMenuOption->Skip - (Index - TopRow);
- } else {
- SkipValue = PreviousMenuOption->Skip - (TopRow - Index);
- Link = Link->ForwardLink;
- }
-
- //
- // Move to the option in Next page.
- //
- if (TopOfScreen == &gMenuOption) {
- NewPos = gMenuOption.BackLink;
- MoveToNextStatement (Selection, TRUE, &NewPos, BottomRow - TopRow);
- } else {
- NewPos = Link;
- MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
- }
-
- //
- // There are more MenuOption needing scrolling up.
- //
- TopOfScreen = Link;
- MenuOption = NULL;
- }
-
- //
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
- // Don't do this when we are already in the first page.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
-
- case CfUiPageDown:
- //
- // SkipValue means lines is skipped when show the top menu option.
- //
- ControlFlag = CfCheckSelection;
-
- ASSERT (NewPos != NULL);
- if (NewPos->ForwardLink == &gMenuOption) {
- NewLine = FALSE;
- Repaint = FALSE;
- break;
- }
-
- NewLine = TRUE;
- Repaint = TRUE;
- Link = TopOfScreen;
- NextMenuOption = MENU_OPTION_FROM_LINK (Link);
- Index = TopRow + NextMenuOption->Skip - SkipValue;
- //
- // Count to the menu option which will show at the top of the next form.
- //
- while ((Index <= BottomRow + 1) && (Link->ForwardLink != &gMenuOption)) {
- Link = Link->ForwardLink;
- NextMenuOption = MENU_OPTION_FROM_LINK (Link);
- Index = Index + NextMenuOption->Skip;
- }
-
- if ((Link->ForwardLink == &gMenuOption) && (Index <= BottomRow + 1)) {
- //
- // Finally we know that NewPos is the last MenuOption can be focused.
- //
- Repaint = FALSE;
- MoveToNextStatement (Selection, TRUE, &Link, Index - TopRow);
- SkipValue = 0;
- } else {
- //
- // Calculate the skip line for top of screen menu.
- //
- if (Link == TopOfScreen) {
- //
- // The top of screen menu option occupies the entire form.
- //
- SkipValue += BottomRow - TopRow + 1;
- } else {
- SkipValue = NextMenuOption->Skip - (Index - (BottomRow + 1));
- }
-
- TopOfScreen = Link;
- MenuOption = NULL;
- //
- // Move to the Next selectable menu.
- //
- MoveToNextStatement (Selection, FALSE, &Link, BottomRow - TopRow);
- }
-
- //
- // Save the menu as the next highlight menu.
- //
- NewPos = Link;
-
- //
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
- // Don't do this when we are already in the last page.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
-
- case CfUiDown:
- //
- // SkipValue means lines is skipped when show the top menu option.
- // NewPos points to the menu which is highlighted now.
- //
- ControlFlag = CfCheckSelection;
- //
- // Since the behavior of hitting the down arrow on a Date/Time op-code is intended
- // to be one that progresses to the next set of op-codes, we need to advance to the last
- // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate
- // checking can be done. The only other logic we need to introduce is that if a Date/Time
- // op-code is the last entry in the menu, we need to rewind back to the first op-code of
- // the Date/Time op-code.
- //
- SavedListEntry = NewPos;
- AdjustDateAndTimePosition (FALSE, &NewPos);
-
- if (NewPos->ForwardLink != &gMenuOption) {
- MenuOption = MENU_OPTION_FROM_LINK (NewPos);
- NewLine = TRUE;
- NewPos = NewPos->ForwardLink;
-
- Difference = 0;
- //
- // Current menu not at the bottom of the form.
- //
- if (BottomRow >= MenuOption->Row + MenuOption->Skip) {
- //
- // Find the next selectable menu.
- //
- Difference = MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - MenuOption->Row - MenuOption->Skip);
- //
- // We hit the end of MenuOption that can be focused
- // so we simply scroll to the first page.
- //
- if (Difference < 0) {
- //
- // Scroll to the first page.
- //
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
- } else {
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- }
- NewPos = gMenuOption.ForwardLink;
- MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
-
- SkipValue = 0;
- //
- // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
- }
- }
- NextMenuOption = MENU_OPTION_FROM_LINK (NewPos);
- if (NextMenuOption->Row == 0) {
- UpdateOptionSkipLines (Selection, NextMenuOption);
- }
- DistanceValue = Difference + NextMenuOption->Skip;
-
- Temp = MenuOption->Row + MenuOption->Skip + DistanceValue - 1;
- if ((MenuOption->Row + MenuOption->Skip == BottomRow + 1) &&
- (NextMenuOption->ThisTag->Operand == EFI_IFR_DATE_OP ||
- NextMenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)
- ) {
- Temp ++;
- }
-
- //
- // If we are going to scroll, update TopOfScreen
- //
- if (Temp > BottomRow) {
- do {
- //
- // Is the current top of screen a zero-advance op-code?
- // If so, keep moving forward till we hit a >0 advance op-code
- //
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
-
- //
- // If bottom op-code is more than one line or top op-code is more than one line
- //
- if ((DistanceValue > 1) || (SavedMenuOption->Skip > 1)) {
- //
- // Is the bottom op-code greater than or equal in size to the top op-code?
- //
- if ((Temp - BottomRow) >= (SavedMenuOption->Skip - SkipValue)) {
- //
- // Skip the top op-code
- //
- TopOfScreen = TopOfScreen->ForwardLink;
- Difference = (Temp - BottomRow) - (SavedMenuOption->Skip - SkipValue);
-
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
-
- //
- // If we have a remainder, skip that many more op-codes until we drain the remainder
- //
- while (Difference >= (INTN) SavedMenuOption->Skip) {
- //
- // Since the Difference is greater than or equal to this op-code's skip value, skip it
- //
- Difference = Difference - (INTN) SavedMenuOption->Skip;
- TopOfScreen = TopOfScreen->ForwardLink;
- SavedMenuOption = MENU_OPTION_FROM_LINK (TopOfScreen);
- }
- //
- // Since we will act on this op-code in the next routine, and increment the
- // SkipValue, set the skips to one less than what is required.
- //
- SkipValue = Difference - 1;
- } else {
- //
- // Since we will act on this op-code in the next routine, and increment the
- // SkipValue, set the skips to one less than what is required.
- //
- SkipValue += (Temp - BottomRow) - 1;
- }
- } else {
- if ((SkipValue + 1) == (INTN) SavedMenuOption->Skip) {
- TopOfScreen = TopOfScreen->ForwardLink;
- break;
- }
- }
- //
- // If the op-code at the top of the screen is more than one line, let's not skip it yet
- // Let's set a skip flag to smoothly scroll the top of the screen.
- //
- if (SavedMenuOption->Skip > 1) {
- if (SavedMenuOption == NextMenuOption) {
- SkipValue = 0;
- } else {
- SkipValue++;
- }
- } else if (SavedMenuOption->Skip == 1) {
- SkipValue = 0;
- } else {
- SkipValue = 0;
- TopOfScreen = TopOfScreen->ForwardLink;
- }
- } while (SavedMenuOption->Skip == 0);
-
- Repaint = TRUE;
- } else if (!IsSelectable (NextMenuOption)) {
- //
- // Continue to go down until scroll to next page or the selectable option is found.
- //
- ScreenOperation = UiDown;
- ControlFlag = CfScreenOperation;
- }
-
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
-
- UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);
-
- } else {
- //
- // Scroll to the first page.
- //
- if (TopOfScreen != gMenuOption.ForwardLink) {
- TopOfScreen = gMenuOption.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
- } else {
- //
- // Need to remove the current highlight menu.
- // MenuOption saved the last highlight menu info.
- //
- MenuOption = MENU_OPTION_FROM_LINK (SavedListEntry);
- }
-
- SkipValue = 0;
- NewLine = TRUE;
- //
- // Get the next highlight menu.
- //
- NewPos = gMenuOption.ForwardLink;
- MoveToNextStatement (Selection, FALSE, &NewPos, BottomRow - TopRow);
- }
-
- //
- // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- break;
-
- case CfUiHotKey:
- ControlFlag = CfCheckSelection;
-
- Status = EFI_SUCCESS;
- //
- // Discard changes. After it, no NV flag is showed.
- //
- if ((HotKey->Action & BROWSER_ACTION_DISCARD) == BROWSER_ACTION_DISCARD) {
- Status = DiscardForm (Selection->FormSet, Selection->Form, gBrowserSettingScope);
- if (!EFI_ERROR (Status)) {
- Selection->Action = UI_ACTION_REFRESH_FORM;
- Selection->Statement = NULL;
- gResetRequired = FALSE;
- } else {
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, HotKey->HelpString, gDiscardFailed, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- //
- // Still show current page.
- //
- Selection->Action = UI_ACTION_NONE;
- Repaint = TRUE;
- NewLine = TRUE;
- break;
- }
- }
-
- //
- // Reterieve default setting. After it. NV flag will be showed.
- //
- if ((HotKey->Action & BROWSER_ACTION_DEFAULT) == BROWSER_ACTION_DEFAULT) {
- Status = ExtractDefault (Selection->FormSet, Selection->Form, HotKey->DefaultId, gBrowserSettingScope, GetDefaultForAll, NULL, FALSE);
- if (!EFI_ERROR (Status)) {
- Selection->Action = UI_ACTION_REFRESH_FORM;
- Selection->Statement = NULL;
- gResetRequired = TRUE;
- } else {
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, HotKey->HelpString, gDefaultFailed, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- //
- // Still show current page.
- //
- Selection->Action = UI_ACTION_NONE;
- Repaint = TRUE;
- NewLine = TRUE;
- break;
- }
- }
-
- //
- // Save changes. After it, no NV flag is showed.
- //
- if ((HotKey->Action & BROWSER_ACTION_SUBMIT) == BROWSER_ACTION_SUBMIT) {
- Status = SubmitForm (Selection->FormSet, Selection->Form, gBrowserSettingScope);
- if (!EFI_ERROR (Status)) {
- ASSERT(MenuOption != NULL);
- UpdateStatusBar (Selection, INPUT_ERROR, MenuOption->ThisTag->QuestionFlags, FALSE);
- UpdateStatusBar (Selection, NV_UPDATE_REQUIRED, MenuOption->ThisTag->QuestionFlags, FALSE);
- } else {
- do {
- CreateDialog (4, TRUE, 0, NULL, &Key, HotKey->HelpString, gSaveFailed, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- //
- // Still show current page.
- //
- Selection->Action = UI_ACTION_NONE;
- Repaint = TRUE;
- NewLine = TRUE;
- break;
- }
- }
-
- //
- // Set Reset required Flag
- //
- if ((HotKey->Action & BROWSER_ACTION_RESET) == BROWSER_ACTION_RESET) {
- gResetRequired = TRUE;
- }
-
- //
- // Exit Action
- //
- if ((HotKey->Action & BROWSER_ACTION_EXIT) == BROWSER_ACTION_EXIT) {
- //
- // Form Exit without saving, Similar to ESC Key.
- // FormSet Exit without saving, Exit SendForm.
- // System Exit without saving, CallExitHandler and Exit SendForm.
- //
- DiscardForm (Selection->FormSet, Selection->Form, gBrowserSettingScope);
- if (gBrowserSettingScope == FormLevel) {
- ControlFlag = CfUiReset;
- } else if (gBrowserSettingScope == FormSetLevel) {
- Selection->Action = UI_ACTION_EXIT;
- } else if (gBrowserSettingScope == SystemLevel) {
- if (ExitHandlerFunction != NULL) {
- ExitHandlerFunction ();
- }
- Selection->Action = UI_ACTION_EXIT;
- }
- Selection->Statement = NULL;
- }
- break;
-
- case CfUiDefault:
- ControlFlag = CfCheckSelection;
- //
- // Reset to default value for all forms in the whole system.
- //
- Status = ExtractDefault (Selection->FormSet, NULL, DefaultId, FormSetLevel, GetDefaultForAll, NULL, FALSE);
-
- if (!EFI_ERROR (Status)) {
- Selection->Action = UI_ACTION_REFRESH_FORM;
- Selection->Statement = NULL;
- gResetRequired = TRUE;
- }
- break;
-
- case CfUiNoOperation:
- ControlFlag = CfCheckSelection;
- break;
-
- case CfExit:
- UiFreeRefreshList ();
-
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- gST->ConOut->SetCursorPosition (gST->ConOut, 0, Row + 4);
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
- gST->ConOut->OutputString (gST->ConOut, L"\n");
- if (HelpString != NULL) {
- FreePool (HelpString);
- }
- if (HelpHeaderString != NULL) {
- FreePool (HelpHeaderString);
- }
- if (HelpBottomString != NULL) {
- FreePool (HelpBottomString);
- }
-
- return EFI_SUCCESS;
-
- default:
- break;
- }
- }
-}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h
deleted file mode 100644
index 03cb0cd753..0000000000
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h
+++ /dev/null
@@ -1,1067 +0,0 @@
-/** @file
-Private structure, MACRO and function definitions for User Interface related functionalities.
-
-Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
-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.
-
-**/
-
-#ifndef _UI_H_
-#define _UI_H_
-
-//
-// Globals
-//
-#define REGULAR_NUMERIC 0
-#define TIME_NUMERIC 1
-#define DATE_NUMERIC 2
-
-#define SUBTITLE_INDENT 2
-
-
-//
-// It take 23 characters including the NULL to print a 64 bits number with "[" and "]".
-// pow(2, 64) = [18446744073709551616]
-//
-#define MAX_NUMERIC_INPUT_WIDTH 23
-
-typedef enum {
- UiNoOperation,
- UiSelect,
- UiUp,
- UiDown,
- UiLeft,
- UiRight,
- UiReset,
- UiPrevious,
- UiPageUp,
- UiPageDown,
- UiHotKey,
- UiMaxOperation
-} UI_SCREEN_OPERATION;
-
-typedef enum {
- CfInitialization,
- CfCheckSelection,
- CfRepaint,
- CfRefreshHighLight,
- CfUpdateHelpString,
- CfPrepareToReadKey,
- CfReadKey,
- CfScreenOperation,
- CfUiSelect,
- CfUiReset,
- CfUiLeft,
- CfUiRight,
- CfUiUp,
- CfUiPageUp,
- CfUiPageDown,
- CfUiDown,
- CfUiDefault,
- CfUiNoOperation,
- CfExit,
- CfUiHotKey,
- CfMaxControlFlag
-} UI_CONTROL_FLAG;
-
-#define UI_ACTION_NONE 0
-#define UI_ACTION_REFRESH_FORM 1
-#define UI_ACTION_REFRESH_FORMSET 2
-#define UI_ACTION_EXIT 3
-
-typedef struct _UI_MENU_LIST UI_MENU_LIST;
-
-typedef struct {
- EFI_HII_HANDLE Handle;
-
- //
- // Target formset/form/Question information
- //
- EFI_GUID FormSetGuid;
- UINT16 FormId;
- UINT16 QuestionId;
- UINTN Sequence; // used for time/date only.
-
- UINTN TopRow;
- UINTN BottomRow;
- UINTN PromptCol;
- UINTN OptionCol;
- UINTN CurrentRow;
-
- //
- // Ation for Browser to taken:
- // UI_ACTION_NONE - navigation inside a form
- // UI_ACTION_REFRESH_FORM - re-evaluate expressions and repaint form
- // UI_ACTION_REFRESH_FORMSET - re-parse formset IFR binary
- //
- UINTN Action;
-
- //
- // Current selected fomset/form/Question
- //
- FORM_BROWSER_FORMSET *FormSet;
- FORM_BROWSER_FORM *Form;
- FORM_BROWSER_STATEMENT *Statement;
-
- //
- // Whether the Form is editable
- //
- BOOLEAN FormEditable;
-
- UI_MENU_LIST *CurrentMenu;
-} UI_MENU_SELECTION;
-
-#define UI_MENU_OPTION_SIGNATURE SIGNATURE_32 ('u', 'i', 'm', 'm')
-#define UI_MENU_LIST_SIGNATURE SIGNATURE_32 ('u', 'i', 'm', 'l')
-
-typedef struct {
- UINTN Signature;
- LIST_ENTRY Link;
-
- EFI_HII_HANDLE Handle;
- FORM_BROWSER_STATEMENT *ThisTag;
- UINT16 EntryNumber;
-
- UINTN Row;
- UINTN Col;
- UINTN OptCol;
- CHAR16 *Description;
- UINTN Skip; // Number of lines
-
- //
- // Display item sequence for date/time
- // Date: Month/Day/Year
- // Sequence: 0 1 2
- //
- // Time: Hour : Minute : Second
- // Sequence: 0 1 2
- //
- //
- UINTN Sequence;
-
- BOOLEAN GrayOut;
- BOOLEAN ReadOnly;
-
- //
- // Whether user could change value of this item
- //
- BOOLEAN IsQuestion;
-} UI_MENU_OPTION;
-
-#define MENU_OPTION_FROM_LINK(a) CR (a, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE)
-
-struct _UI_MENU_LIST {
- UINTN Signature;
- LIST_ENTRY Link;
-
- EFI_HII_HANDLE HiiHandle;
- EFI_GUID FormSetGuid;
- UINT16 FormId;
- UINT16 QuestionId;
- UINTN Sequence; // used for time/date only.
-
- UI_MENU_LIST *Parent;
- LIST_ENTRY ChildListHead;
-};
-
-#define UI_MENU_LIST_FROM_LINK(a) CR (a, UI_MENU_LIST, Link, UI_MENU_LIST_SIGNATURE)
-
-typedef struct _MENU_REFRESH_ENTRY MENU_REFRESH_ENTRY;
-struct _MENU_REFRESH_ENTRY {
- MENU_REFRESH_ENTRY *Next;
- UI_MENU_OPTION *MenuOption; // Describes the entry needing an update
- UI_MENU_SELECTION *Selection;
- UINTN CurrentColumn;
- UINTN CurrentRow;
- UINTN CurrentAttribute;
- EFI_EVENT Event;
-};
-
-typedef struct {
- UINT16 ScanCode;
- UI_SCREEN_OPERATION ScreenOperation;
-} SCAN_CODE_TO_SCREEN_OPERATION;
-
-typedef struct {
- UI_SCREEN_OPERATION ScreenOperation;
- UI_CONTROL_FLAG ControlFlag;
-} SCREEN_OPERATION_T0_CONTROL_FLAG;
-
-
-extern LIST_ENTRY gMenuOption;
-extern LIST_ENTRY gMenuList;
-extern MENU_REFRESH_ENTRY *gMenuRefreshHead;
-extern UI_MENU_SELECTION *gCurrentSelection;
-extern BOOLEAN mHiiPackageListUpdated;
-
-//
-// Global Functions
-//
-/**
- Initialize Menu option list.
-
-**/
-VOID
-UiInitMenu (
- VOID
- );
-
-/**
- Initialize Menu option list.
-
-**/
-VOID
-UiInitMenuList (
- VOID
- );
-
-/**
- Free Menu option linked list.
-
-**/
-VOID
-UiFreeMenu (
- VOID
- );
-
-/**
- Create a menu with specified formset GUID and form ID, and add it as a child
- of the given parent menu.
-
- @param Parent The parent of menu to be added.
- @param HiiHandle Hii handle related to this formset.
- @param FormSetGuid The Formset Guid of menu to be added.
- @param FormId The Form ID of menu to be added.
-
- @return A pointer to the newly added menu or NULL if memory is insufficient.
-
-**/
-UI_MENU_LIST *
-UiAddMenuList (
- IN OUT UI_MENU_LIST *Parent,
- IN EFI_HII_HANDLE HiiHandle,
- IN EFI_GUID *FormSetGuid,
- IN UINT16 FormId
- );
-
-/**
- Search Menu with given FormId, FormSetGuid and Handle in all cached menu list.
-
- @param Parent The parent of menu to search.
- @param Handle Hii handle related to this formset.
- @param FormSetGuid The Formset GUID of the menu to search.
- @param FormId The Form ID of menu to search.
-
- @return A pointer to menu found or NULL if not found.
-
-**/
-UI_MENU_LIST *
-UiFindChildMenuList (
- IN UI_MENU_LIST *Parent,
- IN EFI_HII_HANDLE Handle,
- IN EFI_GUID *FormSetGuid,
- IN UINT16 FormId
- );
-
-/**
- Search Menu with given Handle, FormSetGuid and FormId in all cached menu list.
-
- @param Handle Hii handle related to this formset.
- @param FormSetGuid The Formset GUID of the menu to search.
- @param FormId The Form ID of menu to search.
-
- @return A pointer to menu found or NULL if not found.
-
-**/
-UI_MENU_LIST *
-UiFindMenuList (
- IN EFI_HII_HANDLE Handle,
- IN EFI_GUID *FormSetGuid,
- IN UINT16 FormId
- );
-
-/**
- Free Menu list linked list.
-
- @param MenuListHead One Menu list point in the menu list.
-
-**/
-VOID
-UiFreeMenuList (
- LIST_ENTRY *MenuListHead
- );
-
-/**
- Free Menu option linked list.
-
-**/
-VOID
-UiFreeRefreshList (
- VOID
- );
-
-/**
- Add one menu option by specified description and context.
-
- @param String String description for this option.
- @param Handle Hii handle for the package list.
- @param Form The form this statement belong to.
- @param Statement Statement of this Menu Option.
- @param NumberOfLines Display lines for this Menu Option.
- @param MenuItemCount The index for this Option in the Menu.
-
- @retval Pointer Pointer to the added Menu Option.
-
-**/
-UI_MENU_OPTION *
-UiAddMenuOption (
- IN CHAR16 *String,
- IN EFI_HII_HANDLE Handle,
- IN FORM_BROWSER_FORM *Form,
- IN FORM_BROWSER_STATEMENT *Statement,
- IN UINT16 NumberOfLines,
- IN UINT16 MenuItemCount
- );
-
-/**
- Display menu and wait for user to select one menu option, then return it.
- If AutoBoot is enabled, then if user doesn't select any option,
- after period of time, it will automatically return the first menu option.
-
- @param Selection Menu selection.
-
- @return Return the pointer of the menu which selected,
- @return otherwise return NULL.
-
-**/
-EFI_STATUS
-UiDisplayMenu (
- IN OUT UI_MENU_SELECTION *Selection
- );
-
-/**
- Free up the resource allocated for all strings required
- by Setup Browser.
-
-**/
-VOID
-FreeBrowserStrings (
- VOID
- );
-
-/**
- Process the goto op code, update the info in the selection structure.
-
- @param Statement The statement belong to goto op code.
- @param Selection The selection info.
- @param Repaint Whether need to repaint the menu.
- @param NewLine Whether need to create new line.
-
- @retval EFI_SUCCESS The menu process successfully.
- @return Other value if the process failed.
-**/
-EFI_STATUS
-ProcessGotoOpCode (
- IN OUT FORM_BROWSER_STATEMENT *Statement,
- IN OUT UI_MENU_SELECTION *Selection,
- OUT BOOLEAN *Repaint,
- OUT BOOLEAN *NewLine
- );
-
-
-/**
- The worker function that send the displays to the screen. On output,
- the selection made by user is returned.
-
- @param Selection On input, Selection tell setup browser the information
- about the Selection, form and formset to be displayed.
- On output, Selection return the screen item that is selected
- by user.
-
- @retval EFI_SUCCESS The page is displayed successfully.
- @return Other value if the page failed to be diplayed.
-
-**/
-EFI_STATUS
-SetupBrowser (
- IN OUT UI_MENU_SELECTION *Selection
- );
-
-/**
- Set Buffer to Value for Size bytes.
-
- @param Buffer Memory to set.
- @param Size Number of bytes to set
- @param Value Value of the set operation.
-
-**/
-VOID
-SetUnicodeMem (
- IN VOID *Buffer,
- IN UINTN Size,
- IN CHAR16 Value
- );
-
-/**
- Wait for a given event to fire, or for an optional timeout to expire.
-
- @param Event The event to wait for
- @param Timeout An optional timeout value in 100 ns units.
- @param RefreshInterval Menu refresh interval (in seconds).
-
- @retval EFI_SUCCESS Event fired before Timeout expired.
- @retval EFI_TIME_OUT Timout expired before Event fired.
-
-**/
-EFI_STATUS
-UiWaitForSingleEvent (
- IN EFI_EVENT Event,
- IN UINT64 Timeout, OPTIONAL
- IN UINT8 RefreshInterval OPTIONAL
- );
-
-/**
- Draw a pop up windows based on the dimension, number of lines and
- strings specified.
-
- @param ScreenWidth The width of the pop-up.
- @param NumberOfLines The number of lines.
- @param ... A series of text strings that displayed in the pop-up.
-
-**/
-VOID
-EFIAPI
-CreateMultiStringPopUp (
- IN UINTN ScreenWidth,
- IN UINTN NumberOfLines,
- ...
- );
-
-/**
- Get string or password input from user.
-
- @param MenuOption Pointer to the current input menu.
- @param Prompt The prompt string shown on popup window.
- @param StringPtr Old user input and destination for use input string.
-
- @retval EFI_SUCCESS If string input is read successfully
- @retval EFI_DEVICE_ERROR If operation fails
-
-**/
-EFI_STATUS
-ReadString (
- IN UI_MENU_OPTION *MenuOption,
- IN CHAR16 *Prompt,
- IN OUT CHAR16 *StringPtr
- );
-
-/**
- Get selection for OneOf and OrderedList (Left/Right will be ignored).
-
- @param Selection Pointer to current selection.
- @param MenuOption Pointer to the current input menu.
-
- @retval EFI_SUCCESS If Option input is processed successfully
- @retval EFI_DEVICE_ERROR If operation fails
-
-**/
-EFI_STATUS
-GetSelectionInputPopUp (
- IN UI_MENU_SELECTION *Selection,
- IN UI_MENU_OPTION *MenuOption
- );
-
-/**
- This routine reads a numeric value from the user input.
-
- @param Selection Pointer to current selection.
- @param MenuOption Pointer to the current input menu.
-
- @retval EFI_SUCCESS If numerical input is read successfully
- @retval EFI_DEVICE_ERROR If operation fails
-
-**/
-EFI_STATUS
-GetNumericInput (
- IN UI_MENU_SELECTION *Selection,
- IN UI_MENU_OPTION *MenuOption
- );
-
-/**
- Update status bar on the bottom of menu.
-
- @param Selection Current selection info.
- @param MessageType The type of message to be shown.
- @param Flags The flags in Question header.
- @param State Set or clear.
-
-**/
-VOID
-UpdateStatusBar (
- IN UI_MENU_SELECTION *Selection,
- IN UINTN MessageType,
- IN UINT8 Flags,
- IN BOOLEAN State
- );
-
-/**
- Process Question Config.
-
- @param Selection The UI menu selection.
- @param Question The Question to be peocessed.
-
- @retval EFI_SUCCESS Question Config process success.
- @retval Other Question Config process fail.
-
-**/
-EFI_STATUS
-ProcessQuestionConfig (
- IN UI_MENU_SELECTION *Selection,
- IN FORM_BROWSER_STATEMENT *Question
- );
-
-/**
- Print Question Value according to it's storage width and display attributes.
-
- @param Question The Question to be printed.
- @param FormattedNumber Buffer for output string.
- @param BufferSize The FormattedNumber buffer size in bytes.
-
- @retval EFI_SUCCESS Print success.
- @retval EFI_BUFFER_TOO_SMALL Buffer size is not enough for formatted number.
-
-**/
-EFI_STATUS
-PrintFormattedNumber (
- IN FORM_BROWSER_STATEMENT *Question,
- IN OUT CHAR16 *FormattedNumber,
- IN UINTN BufferSize
- );
-
-/**
- Search an Option of a Question by its value.
-
- @param Question The Question
- @param OptionValue Value for Option to be searched.
-
- @retval Pointer Pointer to the found Option.
- @retval NULL Option not found.
-
-**/
-QUESTION_OPTION *
-ValueToOption (
- IN FORM_BROWSER_STATEMENT *Question,
- IN EFI_HII_VALUE *OptionValue
- );
-
-/**
- Return data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
-
- @retval Value The data to be returned
-
-**/
-UINT64
-GetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index
- );
-
-/**
- Set value of a data element in an Array by its Index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Index Zero based index for data in this array.
- @param Value The value to be set.
-
-**/
-VOID
-SetArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINTN Index,
- IN UINT64 Value
- );
-
-/**
- Check whether this value already in the array, if yes, return the index.
-
- @param Array The data array.
- @param Type Type of the data in this array.
- @param Value The value to be find.
- @param Index The index in the array which has same value with Value.
-
- @retval TRUE Found the value in the array.
- @retval FALSE Not found the value.
-
-**/
-BOOLEAN
-FindArrayData (
- IN VOID *Array,
- IN UINT8 Type,
- IN UINT64 Value,
- OUT UINTN *Index OPTIONAL
- );
-
-/**
- Process a Question's Option (whether selected or un-selected).
-
- @param Selection Pointer to UI_MENU_SELECTION.
- @param MenuOption The MenuOption for this Question.
- @param Selected TRUE: if Question is selected.
- @param OptionString Pointer of the Option String to be displayed.
-
- @retval EFI_SUCCESS Question Option process success.
- @retval Other Question Option process fail.
-
-**/
-EFI_STATUS
-ProcessOptions (
- IN UI_MENU_SELECTION *Selection,
- IN UI_MENU_OPTION *MenuOption,
- IN BOOLEAN Selected,
- OUT CHAR16 **OptionString
- );
-
-/**
- Process the help string: Split StringPtr to several lines of strings stored in
- FormattedString and the glyph width of each line cannot exceed gHelpBlockWidth.
-
- @param StringPtr The entire help string.
- @param FormattedString The oupput formatted string.
- @param EachLineWidth The string length of each line in the formatted string.
- @param RowCount TRUE: if Question is selected.
-
-**/
-UINTN
-ProcessHelpString (
- IN CHAR16 *StringPtr,
- OUT CHAR16 **FormattedString,
- OUT UINT16 *EachLineWidth,
- IN UINTN RowCount
- );
-
-/**
- Update key's help imformation.
-
- @param Selection Tell setup browser the information about the Selection
- @param MenuOption The Menu option
- @param Selected Whether or not a tag be selected
-
-**/
-VOID
-UpdateKeyHelp (
- IN UI_MENU_SELECTION *Selection,
- IN UI_MENU_OPTION *MenuOption,
- IN BOOLEAN Selected
- );
-
-/**
- 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.
-
-**/
-VOID
-ClearLines (
- IN UINTN LeftColumn,
- IN UINTN RightColumn,
- IN UINTN TopRow,
- IN UINTN BottomRow,
- IN UINTN TextAttribute
- );
-
-/**
- Count the storage space of a Unicode string.
-
- This function handles the Unicode string with NARROW_CHAR
- and WIDE_CHAR control characters. NARROW_HCAR and WIDE_CHAR
- does not count in the resultant output. If a WIDE_CHAR is
- hit, then 2 Unicode character will consume an output storage
- space with size of CHAR16 till a NARROW_CHAR is hit.
-
- If String is NULL, then ASSERT ().
-
- @param String The input string to be counted.
-
- @return Storage space for the input string.
-
-**/
-UINTN
-GetStringWidth (
- IN CHAR16 *String
- );
-
-/**
- Will copy LineWidth amount of a string in the OutputString buffer and return the
- number of CHAR16 characters that were copied into the OutputString buffer.
- In the code, it deals \r,\n,\r\n same as \n\r, also it not process the \r or \g.
-
- @param InputString String description for this option.
- @param LineWidth Width of the desired string to extract in CHAR16
- characters
- @param GlyphWidth The glyph width of the beging char in the string.
- @param Index Where in InputString to start the copy process
- @param OutputString Buffer to copy the string into
-
- @return Returns the number of CHAR16 characters that were copied into the OutputString buffer.
-
-**/
-UINT16
-GetLineByWidth (
- IN CHAR16 *InputString,
- IN UINT16 LineWidth,
- IN OUT UINT16 *GlyphWidth,
- IN OUT UINTN *Index,
- OUT CHAR16 **OutputString
- );
-
-/**
- Get the supported width for a particular op-code
-
- @param Statement The FORM_BROWSER_STATEMENT structure passed in.
- @param Handle The handle in the HII database being used
-
- @return Returns the number of CHAR16 characters that is support.
-
-**/
-UINT16
-GetWidth (
- IN FORM_BROWSER_STATEMENT *Statement,
- IN EFI_HII_HANDLE Handle
- );
-
-/**
- Concatenate a narrow string to another string.
-
- @param Destination The destination string.
- @param Source The source string. The string to be concatenated.
- to the end of Destination.
-
-**/
-VOID
-NewStrCat (
- IN OUT CHAR16 *Destination,
- IN CHAR16 *Source
- );
-
-/**
- Wait for a key to be pressed by user.
-
- @param Key The key which is pressed by user.
-
- @retval EFI_SUCCESS The function always completed successfully.
-
-**/
-EFI_STATUS
-WaitForKeyStroke (
- OUT EFI_INPUT_KEY *Key
- );
-
-/**
- Reset stack pointer to begin of the stack.
-
-**/
-VOID
-ResetScopeStack (
- VOID
- );
-
-/**
- Push the expression options onto the Stack.
-
- @param Pointer Pointer to the current expression.
- @param Level Which type this expression belong to. Form,
- statement or option?
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PushConditionalExpression (
- IN FORM_EXPRESSION *Pointer,
- IN EXPRESS_LEVEL Level
- );
-
-/**
- Pop the expression options from the Stack
-
- @param Level Which type this expression belong to. Form,
- statement or option?
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PopConditionalExpression (
- IN EXPRESS_LEVEL Level
- );
-
-/**
- Get the expression Buffer pointer.
-
- @param Level Which type this expression belong to. Form,
- statement or option?
-
- @retval The start pointer of the expression buffer or NULL.
-
-**/
-FORM_EXPRESSION **
-GetConditionalExpressionList (
- IN EXPRESS_LEVEL Level
- );
-
-/**
- Get the expression list count.
-
- @param Level Which type this expression belong to. Form,
- statement or option?
-
- @retval >=0 The expression count
- @retval -1 Input parameter error.
-
-**/
-INTN
-GetConditionalExpressionCount (
- IN EXPRESS_LEVEL Level
- );
-
-/**
- Push an Operand onto the Stack
-
- @param Operand Operand to push.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
- stack.
-
-**/
-EFI_STATUS
-PushScope (
- IN UINT8 Operand
- );
-
-/**
- Pop an Operand from the Stack
-
- @param Operand Operand to pop.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
- stack.
-
-**/
-EFI_STATUS
-PopScope (
- OUT UINT8 *Operand
- );
-
-/**
- Reset stack pointer to begin of the stack.
-
-**/
-VOID
-ResetCurrentExpressionStack (
- VOID
- );
-
-/**
- Push current expression onto the Stack
-
- @param Pointer Pointer to current expression.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PushCurrentExpression (
- IN VOID *Pointer
- );
-
-/**
- Pop current expression from the Stack
-
- @param Pointer Pointer to current expression to be pop.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PopCurrentExpression (
- OUT VOID **Pointer
- );
-
-/**
- Reset stack pointer to begin of the stack.
-
-**/
-VOID
-ResetMapExpressionListStack (
- VOID
- );
-
-/**
- Push the list of map expression onto the Stack
-
- @param Pointer Pointer to the list of map expression to be pushed.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PushMapExpressionList (
- IN VOID *Pointer
- );
-
-/**
- Pop the list of map expression from the Stack
-
- @param Pointer Pointer to the list of map expression to be pop.
-
- @retval EFI_SUCCESS The value was pushed onto the stack.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
-
-**/
-EFI_STATUS
-PopMapExpressionList (
- OUT VOID **Pointer
- );
-
-/**
- Get Form given its FormId.
-
- @param FormSet The formset which contains this form.
- @param FormId Id of this form.
-
- @retval Pointer The form.
- @retval NULL Specified Form is not found in the formset.
-
-**/
-FORM_BROWSER_FORM *
-IdToForm (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN UINT16 FormId
- );
-
-/**
- Search a Question in Formset scope using its QuestionId.
-
- @param FormSet The formset which contains this form.
- @param Form The form which contains this Question.
- @param QuestionId Id of this Question.
-
- @retval Pointer The Question.
- @retval NULL Specified Question not found in the form.
-
-**/
-FORM_BROWSER_STATEMENT *
-IdToQuestion (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN FORM_BROWSER_FORM *Form,
- IN UINT16 QuestionId
- );
-
-/**
- Zero extend integer/boolean/date/time to UINT64 for comparing.
-
- @param Value HII Value to be converted.
-
-**/
-VOID
-ExtendValueToU64 (
- IN EFI_HII_VALUE *Value
- );
-
-/**
- Compare two Hii value.
-
- @param Value1 Expression value to compare on left-hand.
- @param Value2 Expression value to compare on right-hand.
- @param Result Return value after compare.
- retval 0 Two operators equal.
- return Positive value if Value1 is greater than Value2.
- retval Negative value if Value1 is less than Value2.
- @param HiiHandle Only required for string compare.
-
- @retval other Could not perform compare on two values.
- @retval EFI_SUCCESS Compare the value success.
-
-**/
-EFI_STATUS
-CompareHiiValue (
- IN EFI_HII_VALUE *Value1,
- IN EFI_HII_VALUE *Value2,
- OUT INTN *Result,
- IN EFI_HII_HANDLE HiiHandle OPTIONAL
- );
-
-/**
- Evaluate the result of a HII expression
-
- If Expression is NULL, then ASSERT.
-
- @param FormSet FormSet associated with this expression.
- @param Form Form associated with this expression.
- @param Expression Expression to be evaluated.
-
- @retval EFI_SUCCESS The expression evaluated successfuly
- @retval EFI_NOT_FOUND The Question which referenced by a QuestionId
- could not be found.
- @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the
- stack.
- @retval EFI_ACCESS_DENIED The pop operation underflowed the stack
- @retval EFI_INVALID_PARAMETER Syntax error with the Expression
-
-**/
-EFI_STATUS
-EvaluateExpression (
- IN FORM_BROWSER_FORMSET *FormSet,
- IN FORM_BROWSER_FORM *Form,
- IN OUT FORM_EXPRESSION *Expression
- );
-
-/**
- Return the result of the expression list. Check the expression list and
- return the highest priority express result.
- Priority: DisableIf > SuppressIf > GrayOutIf > FALSE
-
- @param ExpList The input expression list.
- @param Evaluate Whether need to evaluate the expression first.
- @param FormSet FormSet associated with this expression. Only
- needed when Evaluate is TRUE
- @param Form Form associated with this expression. Only
- needed when Evaluate is TRUE
-
- @retval EXPRESS_RESULT Return the higher priority express result.
- DisableIf > SuppressIf > GrayOutIf > FALSE
-
-**/
-EXPRESS_RESULT
-EvaluateExpressionList (
- IN FORM_EXPRESSION_LIST *ExpList,
- IN BOOLEAN Evaluate,
- IN FORM_BROWSER_FORMSET *FormSet, OPTIONAL
- IN FORM_BROWSER_FORM *Form OPTIONAL
- );
-
-#endif // _UI_H