summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2011-09-13 09:32:54 +0000
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2011-09-13 09:32:54 +0000
commit48a9d5f7781e430c54cfc2964243580c56384310 (patch)
tree74fe71f79e97700d87c51b0f509e86b73c44260b
parent3e710183d118ba84c32c46027bbc548c8766549d (diff)
downloadedk2-48a9d5f7781e430c54cfc2964243580c56384310.tar.gz
edk2-48a9d5f7781e430c54cfc2964243580c56384310.tar.bz2
edk2-48a9d5f7781e430c54cfc2964243580c56384310.zip
Enhance EDKII Browser to support flexible HotKey setting.
Signed-off-by: lgao4 Reviewed-by: ydong10 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12336 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--MdeModulePkg/Include/Protocol/FormBrowserEx.h147
-rw-r--r--MdeModulePkg/MdeModulePkg.dec5
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c3
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c2
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c211
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.c826
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Setup.h187
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf1
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.unibin12148 -> 13732 bytes
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Ui.c268
-rw-r--r--MdeModulePkg/Universal/SetupBrowserDxe/Ui.h5
11 files changed, 1389 insertions, 266 deletions
diff --git a/MdeModulePkg/Include/Protocol/FormBrowserEx.h b/MdeModulePkg/Include/Protocol/FormBrowserEx.h
new file mode 100644
index 0000000000..a42039871d
--- /dev/null
+++ b/MdeModulePkg/Include/Protocol/FormBrowserEx.h
@@ -0,0 +1,147 @@
+/** @file
+ Extension Form Browser Protocol provides the services that can be used to
+ register the different hot keys for the standard Browser actions described in UEFI specification.
+
+Copyright (c) 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 that 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 __FORM_BROWSER_EXTENSION_H__
+#define __FORM_BROWSER_EXTENSION_H__
+
+#define FORM_BROWSER_EXTENSION_PROTOCOL_GUID \
+ { 0x1f73b18d, 0x4630, 0x43c1, { 0xa1, 0xde, 0x6f, 0x80, 0x85, 0x5d, 0x7d, 0xa4 } }
+
+typedef struct _EFI_FORM_BROWSER_EXTENSION_PROTOCOL EFI_FORM_BROWSER_EXTENSION_PROTOCOL;
+
+//
+// Return value of EXIT_REMINDER() that describes whether the changed data is saved or discarded.
+//
+#define BROWSER_NO_CHANGES 0
+#define BROWSER_SAVE_CHANGES 1
+#define BROWSER_DISCARD_CHANGES 2
+
+//
+// Browser actions. They can be cominbed together.
+// If more than one actions are specified, the action with low bit will be executed first.
+//
+#define BROWSER_ACTION_UNREGISTER 0
+#define BROWSER_ACTION_DISCARD BIT0
+#define BROWSER_ACTION_DEFAULT BIT1
+#define BROWSER_ACTION_SUBMIT BIT2
+#define BROWSER_ACTION_RESET BIT3
+#define BROWSER_ACTION_EXIT BIT4
+
+//
+// Scope for Browser action. It may be Form, FormSet or System level.
+//
+typedef enum {
+ FormLevel,
+ FormSetLevel,
+ SystemLevel,
+ MaxLevel
+} BROWSER_SETTING_SCOPE;
+
+/**
+ Configure what scope the hot key will impact.
+ All hot keys have the same scope. The mixed hot keys with the different level are not supported.
+ If no scope is set, the default scope will be FormSet level.
+ After all registered hot keys are removed, previous Scope can reset to another level.
+
+ @param[in] Scope Scope level to be set.
+
+ @retval EFI_SUCCESS Scope is set correctly.
+ @retval EFI_INVALID_PARAMETER Scope is not the valid value specified in BROWSER_SETTING_SCOPE.
+ @retval EFI_UNSPPORTED Scope level is different from current one that the registered hot keys have.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *SET_SCOPE) (
+ IN BROWSER_SETTING_SCOPE Scope
+ );
+
+/**
+ Register the hot key with its browser action, or unregistered the hot key.
+ If the action value is zero, the hot key will be unregistered if it has been registered.
+ If the same hot key has been registered, the new action and help string will override the previous ones.
+
+ @param[in] KeyData A pointer to a buffer that describes the keystroke
+ information for the hot key. Its type is EFI_INPUT_KEY to
+ be supported by all ConsoleIn devices.
+ @param[in] Action Action value that describes what action will be trigged when the hot key is pressed.
+ @param[in] DefaultId Specifies the type of defaults to retrieve, which is only for DEFAULT action.
+ @param[in] HelpString Help string that describes the hot key information.
+ Its value may be NULL for the unregistered hot key.
+
+ @retval EFI_SUCCESS Hot key is registered or unregistered.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REGISTER_HOT_KEY) (
+ IN EFI_INPUT_KEY *KeyData,
+ IN UINT32 Action,
+ IN UINT16 DefaultId,
+ IN EFI_STRING HelpString OPTIONAL
+ );
+
+/**
+ This handler is responsbile for the left things on normal boot after all UI forms are closed.
+ For example, it can continue to boot the first boot option.
+
+ It will be used only when EXIT action is trigged as system level.
+**/
+typedef
+VOID
+(EFIAPI *EXIT_HANDLER) (
+ VOID
+ );
+
+/**
+ Register Exit handler function.
+ When more than one handler function is registered, the latter one will override the previous one.
+ When NULL handler is specified, the previous Exit handler will be unregistered.
+
+ @param[in] Handler Pointer to handler function.
+
+**/
+typedef
+VOID
+(EFIAPI *REGISTER_EXIT_HANDLER) (
+ IN EXIT_HANDLER Handler
+ );
+
+/**
+ 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.
+
+ @retval BROWSER_NO_CHANGES No browser data is changed.
+ @retval BROWSER_SAVE_CHANGES The changed browser data is saved.
+ @retval BROWSER_DISCARD_CHANGES The changed browser data is discard.
+
+**/
+typedef
+UINT32
+(EFIAPI *SAVE_REMINDER)(
+ VOID
+ );
+
+struct _EFI_FORM_BROWSER_EXTENSION_PROTOCOL {
+ SET_SCOPE SetScope;
+ REGISTER_HOT_KEY RegisterHotKey;
+ REGISTER_EXIT_HANDLER RegiserExitHandler;
+ SAVE_REMINDER SaveReminder;
+};
+
+extern EFI_GUID gEfiFormBrowserExProtocolGuid;
+
+#endif
+
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 8837cac700..4c6d6b166e 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -202,6 +202,9 @@
gEfiBootScriptExecutorVariableGuid = { 0x3079818c, 0x46d4, 0x4a73, { 0xae, 0xf3, 0xe3, 0xe4, 0x6c, 0xf1, 0xee, 0xdb }}
gEfiBootScriptExecutorContextGuid = { 0x79cb58c4, 0xac51, 0x442f, { 0xaf, 0xd7, 0x98, 0xe4, 0x7d, 0x2e, 0x99, 0x8 }}
+ ## Include/Guid/UsbKeyBoardLayout.h
+ gUsbKeyboardLayoutPackageGuid = { 0xc0f3b43, 0x44de, 0x4907, { 0xb4, 0x78, 0x22, 0x5f, 0x6f, 0x62, 0x89, 0xdc }}
+ gUsbKeyboardLayoutKeyGuid = { 0x3a4d7a7c, 0x18a, 0x4b42, { 0x81, 0xb3, 0xdc, 0x10, 0xe3, 0xb5, 0x91, 0xbd }}
[Ppis]
## Include/Ppi/AtaController.h
gPeiAtaControllerPpiGuid = { 0xa45e60d1, 0xc719, 0x44aa, { 0xb0, 0x7a, 0xaa, 0x77, 0x7f, 0x85, 0x90, 0x6d }}
@@ -285,6 +288,8 @@
## Include/Protocol/LockBox.h
gEfiLockBoxProtocolGuid = { 0xbd445d79, 0xb7ad, 0x4f04, { 0x9a, 0xd8, 0x29, 0xbd, 0x20, 0x40, 0xeb, 0x3c }}
+ gEfiFormBrowserExProtocolGuid = { 0x1f73b18d, 0x4630, 0x43c1, { 0xa1, 0xde, 0x6f, 0x80, 0x85, 0x5d, 0x7d, 0xa4 } }
+
[PcdsFeatureFlag]
## Indicate whether platform can support update capsule across a system reset
gEfiMdeModulePkgTokenSpaceGuid.PcdSupportUpdateCapsuleReset|FALSE|BOOLEAN|0x0001001d
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
index d8fb8c963e..50ae87d92e 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/IfrParse.c
@@ -992,6 +992,7 @@ ParseOpCodes (
InitializeListHead (&FormSet->StorageListHead);
InitializeListHead (&FormSet->DefaultStoreListHead);
InitializeListHead (&FormSet->FormListHead);
+ InitializeListHead (&FormSet->ExpressionListHead);
ResetCurrentExpressionStack ();
ResetMapExpressionListStack ();
@@ -1332,8 +1333,6 @@ ParseOpCodes (
FormSet->NumberOfClassGuid = (UINT8) (((EFI_IFR_FORM_SET *) OpCodeData)->Flags & 0x3);
CopyMem (FormSet->ClassGuid, OpCodeData + sizeof (EFI_IFR_FORM_SET), FormSet->NumberOfClassGuid * sizeof (EFI_GUID));
}
-
- InitializeListHead (&FormSet->ExpressionListHead);
break;
case EFI_IFR_FORM_OP:
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c b/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c
index 1e4d20237c..c42a18e3b0 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/InputHandler.c
@@ -1060,7 +1060,7 @@ GetSelectionInputPopUp (
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 - FOOTER_HEIGHT - 1;
+ Bottom = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight - 1;
MenuLinesInView = Bottom - Top - 1;
if (MenuLinesInView >= PopUpMenuLines) {
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
index 863097d005..bff79570db 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Presentation.c
@@ -300,7 +300,7 @@ DisplayPageFrame (
ClearLines (
LocalScreen.LeftColumn,
LocalScreen.RightColumn,
- LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT,
+ LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight,
LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 1,
KEYHELP_TEXT | KEYHELP_BACKGROUND
);
@@ -348,14 +348,14 @@ DisplayPageFrame (
// +------------------------------------------------------------------------------+
//
Character = BOXDRAW_DOWN_RIGHT;
- PrintCharAt (LocalScreen.LeftColumn, LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT, Character);
+ 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 - FOOTER_HEIGHT + 1;
+ for (Row = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;
Row <= LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;
Row++
) {
@@ -583,13 +583,10 @@ InitializeBrowserStrings (
VOID
)
{
- gFunctionNineString = GetToken (STRING_TOKEN (FUNCTION_NINE_STRING), gHiiHandle);
- gFunctionTenString = GetToken (STRING_TOKEN (FUNCTION_TEN_STRING), gHiiHandle);
gEnterString = GetToken (STRING_TOKEN (ENTER_STRING), gHiiHandle);
gEnterCommitString = GetToken (STRING_TOKEN (ENTER_COMMIT_STRING), gHiiHandle);
gEnterEscapeString = GetToken (STRING_TOKEN (ENTER_ESCAPE_STRING), gHiiHandle);
gEscapeString = GetToken (STRING_TOKEN (ESCAPE_STRING), gHiiHandle);
- gSaveFailed = GetToken (STRING_TOKEN (SAVE_FAILED), gHiiHandle);
gMoveHighlight = GetToken (STRING_TOKEN (MOVE_HIGHLIGHT), gHiiHandle);
gMakeSelection = GetToken (STRING_TOKEN (MAKE_SELECTION), gHiiHandle);
gDecNumericInput = GetToken (STRING_TOKEN (DEC_NUMERIC_INPUT), gHiiHandle);
@@ -626,8 +623,6 @@ FreeBrowserStrings (
VOID
)
{
- FreePool (gFunctionNineString);
- FreePool (gFunctionTenString);
FreePool (gEnterString);
FreePool (gEnterCommitString);
FreePool (gEnterEscapeString);
@@ -658,6 +653,64 @@ FreeBrowserStrings (
return ;
}
+/**
+ Show all registered HotKey help strings on bottom Rows.
+
+**/
+VOID
+PrintHotKeyHelpString (
+ VOID
+ )
+{
+ UINTN CurrentCol;
+ UINTN CurrentRow;
+ UINTN BottomRowOfHotKeyHelp;
+ UINTN ColumnWidth;
+ UINTN Index;
+ EFI_SCREEN_DESCRIPTOR LocalScreen;
+ LIST_ENTRY *Link;
+ BROWSER_HOT_KEY *HotKey;
+
+ CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
+ ColumnWidth = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
+ BottomRowOfHotKeyHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 3;
+
+ //
+ // Calculate total number of Register HotKeys.
+ //
+ 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';
+ }
+ //
+ // Calculate help information Column and Row.
+ //
+ if ((Index % 3) != 2) {
+ CurrentCol = LocalScreen.LeftColumn + (2 - Index % 3) * ColumnWidth;
+ } else {
+ CurrentCol = LocalScreen.LeftColumn + 2;
+ }
+ CurrentRow = BottomRowOfHotKeyHelp - Index / 3;
+ //
+ // Print HotKey help string on bottom Row.
+ //
+ PrintStringAt (CurrentCol, CurrentRow, HotKey->HelpString);
+
+ //
+ // Get Next Hot Key.
+ //
+ Link = GetNextNode (&gBrowserHotKeyList, Link);
+ Index ++;
+ }
+
+ return;
+}
/**
Update key's help imformation.
@@ -693,13 +746,13 @@ UpdateKeyHelp (
CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
SecCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 3;
- ThdCol = LocalScreen.LeftColumn + (LocalScreen.RightColumn - LocalScreen.LeftColumn) * 2 / 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 - 4;
- BottomRowOfHelp = LocalScreen.BottomRow - 3;
+ TopRowOfHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight + 1;
+ BottomRowOfHelp = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - 2;
Statement = MenuOption->ThisTag;
switch (Statement->Operand) {
@@ -711,11 +764,15 @@ UpdateKeyHelp (
ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
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) {
- if (Selection->FormEditable) {
- PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
- PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
- }
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
}
@@ -770,11 +827,14 @@ UpdateKeyHelp (
case EFI_IFR_CHECKBOX_OP:
ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
+ //
+ // 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) {
- if (Selection->FormEditable) {
- PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
- PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
- }
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
}
@@ -792,11 +852,14 @@ UpdateKeyHelp (
ClearLines (LeftColumnOfHelp, RightColumnOfHelp, TopRowOfHelp, BottomRowOfHelp, KEYHELP_TEXT | KEYHELP_BACKGROUND);
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) {
- if (Selection->FormEditable) {
- PrintStringAt (SecCol, TopRowOfHelp, gFunctionNineString);
- PrintStringAt (ThdCol, TopRowOfHelp, gFunctionTenString);
- }
PrintStringAt (ThdCol, BottomRowOfHelp, gEscapeString);
}
@@ -947,6 +1010,55 @@ FindNextMenu (
if (CurrentMenu != NULL && CurrentMenu->Parent != NULL) {
//
+ // Form Level Check whether the data is changed.
+ //
+ if (gBrowserSettingScope == FormLevel && Selection->Form->NvUpdateRequired) {
+ Status = 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, Ingore.
+ //
+ if (Repaint != NULL) {
+ *Repaint = TRUE;
+ }
+ if (NewLine != NULL) {
+ *NewLine = TRUE;
+ }
+
+ 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
+ //
+ Status = SubmitForm (Selection->FormSet, Selection->Form, FormLevel);
+ } else {
+ //
+ // If the user hits the NoResponse key
+ //
+ Status = DiscardForm (Selection->FormSet, Selection->Form, FormLevel);
+ }
+ }
+
+ //
// we have a parent, so go to the parent menu
//
if (CompareGuid (&CurrentMenu->FormSetGuid, &CurrentMenu->Parent->FormSetGuid)) {
@@ -980,7 +1092,7 @@ FindNextMenu (
//
// We are going to leave current FormSet, so check uncommited data in this FormSet
//
- if (IsNvUpdateRequired(Selection->FormSet)) {
+ if (gBrowserSettingScope != SystemLevel && IsNvUpdateRequired(Selection->FormSet)) {
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
YesResponse = gYesResponse[0];
@@ -1014,11 +1126,16 @@ FindNextMenu (
return FALSE;
}
- //
- // If the user hits the YesResponse key
- //
if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {
- Status = SubmitForm (Selection->FormSet, Selection->Form, FALSE);
+ //
+ // If the user hits the YesResponse key
+ //
+ Status = SubmitForm (Selection->FormSet, Selection->Form, FormSetLevel);
+ } else {
+ //
+ // If the user hits the NoResponse key
+ //
+ Status = DiscardForm (Selection->FormSet, Selection->Form, FormSetLevel);
}
}
@@ -1060,14 +1177,14 @@ ProcessCallBackFunction (
EFI_IFR_TYPE_VALUE *TypeValue;
FORM_BROWSER_STATEMENT *Statement;
BOOLEAN SubmitFormIsRequired;
- BOOLEAN SingleForm;
BOOLEAN DiscardFormIsRequired;
BOOLEAN NeedExit;
LIST_ENTRY *Link;
+ BROWSER_SETTING_SCOPE SettingLevel;
ConfigAccess = Selection->FormSet->ConfigAccess;
SubmitFormIsRequired = FALSE;
- SingleForm = FALSE;
+ SettingLevel = FormSetLevel;
DiscardFormIsRequired = FALSE;
NeedExit = FALSE;
Status = EFI_SUCCESS;
@@ -1139,24 +1256,24 @@ ProcessCallBackFunction (
case EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT:
SubmitFormIsRequired = TRUE;
- SingleForm = TRUE;
+ SettingLevel = FormLevel;
NeedExit = TRUE;
break;
case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT:
DiscardFormIsRequired = TRUE;
- SingleForm = TRUE;
+ SettingLevel = FormLevel;
NeedExit = TRUE;
break;
case EFI_BROWSER_ACTION_REQUEST_FORM_APPLY:
SubmitFormIsRequired = TRUE;
- SingleForm = TRUE;
+ SettingLevel = FormLevel;
break;
case EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD:
DiscardFormIsRequired = TRUE;
- SingleForm = TRUE;
+ SettingLevel = FormLevel;
break;
default:
@@ -1179,11 +1296,11 @@ ProcessCallBackFunction (
}
if (SubmitFormIsRequired && !SkipSaveOrDiscard) {
- SubmitForm (Selection->FormSet, Selection->Form, SingleForm);
+ SubmitForm (Selection->FormSet, Selection->Form, SettingLevel);
}
if (DiscardFormIsRequired && !SkipSaveOrDiscard) {
- DiscardForm (Selection->FormSet, Selection->Form, SingleForm);
+ DiscardForm (Selection->FormSet, Selection->Form, SettingLevel);
}
if (NeedExit) {
@@ -1216,12 +1333,9 @@ SetupBrowser (
EFI_HANDLE NotifyHandle;
FORM_BROWSER_STATEMENT *Statement;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
- FORM_BROWSER_FORMSET *FormSet;
EFI_INPUT_KEY Key;
gMenuRefreshHead = NULL;
- gResetRequired = FALSE;
- FormSet = Selection->FormSet;
ConfigAccess = Selection->FormSet->ConfigAccess;
//
@@ -1247,6 +1361,17 @@ SetupBrowser (
goto Done;
}
+ //
+ // Update gOldFormSet on maintain back up FormSet list.
+ // And, make gOldFormSet point to current FormSet.
+ //
+ if (gOldFormSet != NULL) {
+ RemoveEntryList (&gOldFormSet->Link);
+ DestroyFormSet (gOldFormSet);
+ }
+ gOldFormSet = Selection->FormSet;
+ InsertTailList (&gBrowserFormSetList, &gOldFormSet->Link);
+
do {
//
// Initialize Selection->Form
@@ -1442,14 +1567,6 @@ SetupBrowser (
}
} while (Selection->Action == UI_ACTION_REFRESH_FORM);
- //
- // Record the old formset
- //
- if (gOldFormSet != NULL) {
- DestroyFormSet (gOldFormSet);
- }
- gOldFormSet = FormSet;
-
Done:
//
// Reset current form information to the initial setting when error happens or form exit.
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
index 0b526d0a02..88f965059f 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.c
@@ -20,6 +20,12 @@ SETUP_DRIVER_PRIVATE_DATA mPrivateData = {
{
SendForm,
BrowserCallback
+ },
+ {
+ SetScope,
+ RegisterHotKey,
+ RegiserExitHandler,
+ SaveReminder
}
};
@@ -29,6 +35,8 @@ EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;
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);
BANNER_DATA *gBannerData;
EFI_HII_HANDLE gFrontPageHandle;
@@ -38,17 +46,21 @@ BOOLEAN gResetRequired;
EFI_HII_HANDLE gHiiHandle;
UINT16 gDirection;
EFI_SCREEN_DESCRIPTOR gScreenDimensions;
+BROWSER_SETTING_SCOPE gBrowserSettingScope = FormSetLevel;
+BOOLEAN mBrowserScopeFirstSet = TRUE;
+EXIT_HANDLER ExitHandlerFunction = NULL;
+UINTN gFooterHeight;
//
// Browser Global Strings
//
-CHAR16 *gFunctionNineString;
-CHAR16 *gFunctionTenString;
+CHAR16 *gSaveFailed;
+CHAR16 *gDiscardFailed;
+CHAR16 *gDefaultFailed;
CHAR16 *gEnterString;
CHAR16 *gEnterCommitString;
CHAR16 *gEnterEscapeString;
CHAR16 *gEscapeString;
-CHAR16 *gSaveFailed;
CHAR16 *gMoveHighlight;
CHAR16 *gMakeSelection;
CHAR16 *gDecNumericInput;
@@ -84,7 +96,7 @@ EFI_GUID gSetupBrowserGuid = {
0xab368524, 0xb60c, 0x495b, {0xa0, 0x9, 0x12, 0xe8, 0x5b, 0x1a, 0xea, 0x32}
};
-FORM_BROWSER_FORMSET *gOldFormSet;
+FORM_BROWSER_FORMSET *gOldFormSet = NULL;
FUNCTIION_KEY_SETTING gFunctionKeySettingTable[] = {
//
@@ -214,12 +226,28 @@ SendForm (
UI_MENU_SELECTION *Selection;
UINTN Index;
FORM_BROWSER_FORMSET *FormSet;
+ LIST_ENTRY *Link;
+
+ //
+ // Calculate total number of Register HotKeys.
+ //
+ Index = 0;
+ Link = GetFirstNode (&gBrowserHotKeyList);
+ while (!IsNull (&gBrowserHotKeyList, Link)) {
+ Link = GetNextNode (&gBrowserHotKeyList, Link);
+ Index ++;
+ }
+ //
+ // Show three HotKeys help information on one ROW.
+ //
+ gFooterHeight = FOOTER_HEIGHT + (Index / 3);
//
// Save globals used by SendForm()
//
SaveBrowserContext ();
+ gResetRequired = FALSE;
Status = EFI_SUCCESS;
ZeroMem (&gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
@@ -254,7 +282,7 @@ SendForm (
SCROLL_ARROW_HEIGHT *
2 +
FRONT_PAGE_HEADER_HEIGHT +
- FOOTER_HEIGHT +
+ gFooterHeight +
1
)
) {
@@ -275,7 +303,7 @@ SendForm (
//
InitializeBrowserStrings ();
- gFunctionKeySetting = DEFAULT_FUNCTION_KEY_SETTING;
+ gFunctionKeySetting = ENABLE_FUNCTION_KEY_SETTING;
//
// Ensure we are in Text mode
@@ -290,9 +318,14 @@ SendForm (
if (FormSetGuid != NULL) {
CopyMem (&Selection->FormSetGuid, FormSetGuid, sizeof (EFI_GUID));
Selection->FormId = FormId;
+ } else {
+ CopyMem (&Selection->FormSetGuid, &gEfiHiiPlatformSetupFormsetGuid, sizeof (EFI_GUID));
}
- gOldFormSet = NULL;
+ //
+ // Try to find pre FormSet in the maintain backup list.
+ //
+ gOldFormSet = GetFormSetFromHiiHandle (Selection->Handle);
do {
FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
@@ -324,7 +357,13 @@ SendForm (
} while (Selection->Action == UI_ACTION_REFRESH_FORMSET);
if (gOldFormSet != NULL) {
- DestroyFormSet (gOldFormSet);
+ //
+ // If no data is changed, don't need to save current FormSet into the maintain list.
+ //
+ if (!IsNvUpdateRequired (gOldFormSet)) {
+ RemoveEntryList (&gOldFormSet->Link);
+ DestroyFormSet (gOldFormSet);
+ }
gOldFormSet = NULL;
}
@@ -517,6 +556,65 @@ BrowserCallback (
return EFI_SUCCESS;
}
+/**
+ Notify function will remove the formset in the maintain list
+ once this formset is removed.
+
+ Functions which are registered to receive notification of
+ database events have this prototype. The actual event is encoded
+ in NotifyType. The following table describes how PackageType,
+ PackageGuid, Handle, and Package are used for each of the
+ notification types.
+
+ @param PackageType Package type of the notification.
+
+ @param PackageGuid If PackageType is
+ EFI_HII_PACKAGE_TYPE_GUID, then this is
+ the pointer to the GUID from the Guid
+ field of EFI_HII_PACKAGE_GUID_HEADER.
+ Otherwise, it must be NULL.
+
+ @param Package Points to the package referred to by the
+ notification Handle The handle of the package
+ list which contains the specified package.
+
+ @param Handle The HII handle.
+
+ @param NotifyType The type of change concerning the
+ database. See
+ EFI_HII_DATABASE_NOTIFY_TYPE.
+
+**/
+EFI_STATUS
+EFIAPI
+FormsetRemoveNotify (
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN CONST EFI_HII_PACKAGE_HEADER *Package,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
+ )
+{
+ FORM_BROWSER_FORMSET *FormSet;
+
+ //
+ // Ignore the update for current using formset, which is handled by another notify function.
+ //
+ if (IsHiiHandleInBrowserContext (Handle)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Remove the backup FormSet data when the Form Package is removed.
+ //
+ FormSet = GetFormSetFromHiiHandle (Handle);
+ if (FormSet != NULL) {
+ RemoveEntryList (&FormSet->Link);
+ DestroyFormSet (FormSet);
+ }
+
+ return EFI_SUCCESS;
+}
/**
Initialize Setup Browser driver.
@@ -536,6 +634,9 @@ InitializeSetup (
)
{
EFI_STATUS Status;
+ EFI_HANDLE NotifyHandle;
+ EFI_INPUT_KEY DefaultHotKey;
+ EFI_STRING HelpString;
//
// Locate required Hii relative protocols
@@ -577,6 +678,13 @@ InitializeSetup (
//
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
@@ -590,6 +698,47 @@ 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
+ //
+ mPrivateData.Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &mPrivateData.Handle,
+ &gEfiFormBrowserExProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mPrivateData.FormBrowserEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register notify for Form package remove
+ //
+ Status = mHiiDatabase->RegisterPackageNotify (
+ mHiiDatabase,
+ EFI_HII_PACKAGE_FORMS,
+ NULL,
+ FormsetRemoveNotify,
+ EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,
+ &NotifyHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
return Status;
}
@@ -1932,78 +2081,104 @@ SynchronizeStorageForForm (
/**
- Discard data for form level or formset level.
+ Discard data based on the input setting scope (Form, FormSet or System).
@param FormSet FormSet data structure.
@param Form Form data structure.
- @param SingleForm Only discard single form or formset.
+ @param SettingScope Setting Scope for Discard action.
@retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.
**/
EFI_STATUS
DiscardForm (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_FORM *Form,
- IN BOOLEAN SingleForm
+ IN BROWSER_SETTING_SCOPE SettingScope
)
{
- LIST_ENTRY *Link;
- FORMSET_STORAGE *Storage;
+ LIST_ENTRY *Link;
+ FORMSET_STORAGE *Storage;
FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
+ FORM_BROWSER_FORMSET *LocalFormSet;
- if (SingleForm) {
- if (Form->NvUpdateRequired) {
- ConfigInfo = NULL;
- Link = GetFirstNode (&Form->ConfigRequestHead);
- while (!IsNull (&Form->ConfigRequestHead, Link)) {
- ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
- Link = GetNextNode (&Form->ConfigRequestHead, Link);
-
- if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
- continue;
- }
+ //
+ // Check the supported setting level.
+ //
+ if (SettingScope >= MaxLevel) {
+ return EFI_UNSUPPORTED;
+ }
- //
- // Skip if there is no RequestElement
- //
- if (ConfigInfo->ElementCount == 0) {
- continue;
- }
+ if (SettingScope == FormLevel && Form->NvUpdateRequired) {
+ ConfigInfo = NULL;
+ Link = GetFirstNode (&Form->ConfigRequestHead);
+ while (!IsNull (&Form->ConfigRequestHead, Link)) {
+ ConfigInfo = FORM_BROWSER_CONFIG_REQUEST_FROM_LINK (Link);
+ Link = GetNextNode (&Form->ConfigRequestHead, Link);
- //
- // Prepare <ConfigResp>
- //
- SynchronizeStorageForForm(FormSet, ConfigInfo, FALSE);
+ if (ConfigInfo->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
+ continue;
+ }
+
+ //
+ // Skip if there is no RequestElement
+ //
+ if (ConfigInfo->ElementCount == 0) {
+ continue;
}
- Form->NvUpdateRequired = FALSE;
+ //
+ // Prepare <ConfigResp>
+ //
+ SynchronizeStorageForForm(FormSet, ConfigInfo, FALSE);
}
- } else {
- if (IsNvUpdateRequired(FormSet)) {
+
+ Form->NvUpdateRequired = FALSE;
+ } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {
+ //
+ // Discard Buffer storage or Name/Value storage
+ //
+ Link = GetFirstNode (&FormSet->StorageListHead);
+ while (!IsNull (&FormSet->StorageListHead, Link)) {
+ Storage = FORMSET_STORAGE_FROM_LINK (Link);
+ Link = GetNextNode (&FormSet->StorageListHead, Link);
+
+ if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
+ continue;
+ }
+
//
- // Discard Buffer storage or Name/Value storage
+ // Skip if there is no RequestElement
//
- Link = GetFirstNode (&FormSet->StorageListHead);
- while (!IsNull (&FormSet->StorageListHead, Link)) {
- Storage = FORMSET_STORAGE_FROM_LINK (Link);
- Link = GetNextNode (&FormSet->StorageListHead, Link);
+ if (Storage->ElementCount == 0) {
+ continue;
+ }
- if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
- continue;
- }
+ SynchronizeStorage(Storage, FALSE);
+ }
+ UpdateNvInfoInForm (FormSet, FALSE);
+ } else if (SettingScope == SystemLevel) {
+ //
+ // System Level Discard.
+ //
+
+ //
+ // Discard changed value for each FormSet in the maintain list.
+ //
+ Link = GetFirstNode (&gBrowserFormSetList);
+ while (!IsNull (&gBrowserFormSetList, Link)) {
+ LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
+ DiscardForm (LocalFormSet, NULL, FormSetLevel);
+ Link = GetNextNode (&gBrowserFormSetList, Link);
+ if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {
//
- // Skip if there is no RequestElement
+ // Remove maintain backup list after discard except for the current using FormSet.
//
- if (Storage->ElementCount == 0) {
- continue;
- }
-
- SynchronizeStorage(Storage, FALSE);
+ RemoveEntryList (&LocalFormSet->Link);
+ DestroyFormSet (LocalFormSet);
}
-
- UpdateNvInfoInForm(FormSet, FALSE);
}
}
@@ -2011,20 +2186,21 @@ DiscardForm (
}
/**
- Submit data for form level or formset level.
+ Submit data based on the input Setting level (Form, FormSet or System).
@param FormSet FormSet data structure.
@param Form Form data structure.
- @param SingleForm whether submit for the single form or all form set.
+ @param SettingScope Setting Scope for Submit action.
@retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.
**/
EFI_STATUS
SubmitForm (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_FORM *Form,
- IN BOOLEAN SingleForm
+ IN BROWSER_SETTING_SCOPE SettingScope
)
{
EFI_STATUS Status;
@@ -2033,22 +2209,31 @@ SubmitForm (
EFI_STRING Progress;
FORMSET_STORAGE *Storage;
UINTN BufferSize;
- UINT8 *TmpBuf;
+ UINT8 *TmpBuf;
+ FORM_BROWSER_FORMSET *LocalFormSet;
FORM_BROWSER_CONFIG_REQUEST *ConfigInfo;
//
+ // Check the supported setting level.
+ //
+ if (SettingScope >= MaxLevel) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
// Validate the Form by NoSubmit check
//
- if (SingleForm) {
+ Status = EFI_SUCCESS;
+ if (SettingScope == FormLevel) {
Status = NoSubmitCheck (FormSet, Form);
- } else {
+ } else if (SettingScope == FormSetLevel) {
Status = NoSubmitCheck (FormSet, NULL);
}
if (EFI_ERROR (Status)) {
return Status;
}
- if (SingleForm) {
+ if (SettingScope == FormLevel && Form->NvUpdateRequired) {
ConfigInfo = NULL;
Link = GetFirstNode (&Form->ConfigRequestHead);
while (!IsNull (&Form->ConfigRequestHead, Link)) {
@@ -2153,7 +2338,7 @@ SubmitForm (
// 4. Update the NV flag.
//
Form->NvUpdateRequired = FALSE;
- } else {
+ } else if (SettingScope == FormSetLevel && IsNvUpdateRequired(FormSet)) {
//
// Submit Buffer storage or Name/Value storage
//
@@ -2254,7 +2439,28 @@ SubmitForm (
//
// 4. Update the NV flag.
//
- UpdateNvInfoInForm(FormSet, FALSE);
+ UpdateNvInfoInForm (FormSet, FALSE);
+ } else if (SettingScope == SystemLevel) {
+ //
+ // System Level Save.
+ //
+
+ //
+ // Save changed value for each FormSet in the maintain list.
+ //
+ Link = GetFirstNode (&gBrowserFormSetList);
+ while (!IsNull (&gBrowserFormSetList, Link)) {
+ LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
+ SubmitForm (LocalFormSet, NULL, FormSetLevel);
+ Link = GetNextNode (&gBrowserFormSetList, Link);
+ if (!IsHiiHandleInBrowserContext (LocalFormSet->HiiHandle)) {
+ //
+ // Remove maintain backup list after save except for the current using FormSet.
+ //
+ RemoveEntryList (&LocalFormSet->Link);
+ DestroyFormSet (LocalFormSet);
+ }
+ }
}
return EFI_SUCCESS;
@@ -2515,7 +2721,7 @@ GetQuestionDefault (
EFI_BROWSER_ACTION_REQUEST ActionRequest;
INTN Action;
- Status = EFI_SUCCESS;
+ Status = EFI_NOT_FOUND;
StrValue = NULL;
//
@@ -2658,6 +2864,7 @@ GetQuestionDefault (
//
// For Questions without default
//
+ Status = EFI_NOT_FOUND;
switch (Question->Operand) {
case EFI_IFR_NUMERIC_OP:
//
@@ -2665,6 +2872,7 @@ GetQuestionDefault (
//
if ((HiiValue->Value.u64 < Question->Minimum) || (HiiValue->Value.u64 > Question->Maximum)) {
HiiValue->Value.u64 = Question->Minimum;
+ Status = EFI_SUCCESS;
}
break;
@@ -2677,6 +2885,7 @@ GetQuestionDefault (
if (!IsNull (&Question->OptionListHead, Link)) {
Option = QUESTION_OPTION_FROM_LINK (Link);
CopyMem (HiiValue, &Option->Value, sizeof (EFI_HII_VALUE));
+ Status = EFI_SUCCESS;
}
}
break;
@@ -2688,6 +2897,7 @@ GetQuestionDefault (
Index = 0;
Link = GetFirstNode (&Question->OptionListHead);
while (!IsNull (&Question->OptionListHead, Link)) {
+ Status = EFI_SUCCESS;
Option = QUESTION_OPTION_FROM_LINK (Link);
SetArrayData (Question->BufferValue, Question->ValueType, Index, Option->Value.Value.u64);
@@ -2702,7 +2912,6 @@ GetQuestionDefault (
break;
default:
- Status = EFI_NOT_FOUND;
break;
}
@@ -2711,38 +2920,52 @@ GetQuestionDefault (
/**
- Reset Questions in a Formset to their default value.
+ Reset Questions to their default value in a Form, Formset or System.
@param FormSet FormSet data structure.
+ @param Form Form data structure.
@param DefaultId The Class of the default.
+ @param SettingScope Setting Scope for Default action.
@retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.
**/
EFI_STATUS
-ExtractFormSetDefault (
+ExtractDefault (
IN FORM_BROWSER_FORMSET *FormSet,
- IN UINT16 DefaultId
+ IN FORM_BROWSER_FORM *Form,
+ IN UINT16 DefaultId,
+ IN BROWSER_SETTING_SCOPE SettingScope
)
{
EFI_STATUS Status;
LIST_ENTRY *FormLink;
- LIST_ENTRY *StatementLink;
+ LIST_ENTRY *Link;
FORM_BROWSER_STATEMENT *Question;
- FORM_BROWSER_FORM *Form;
+ FORM_BROWSER_FORMSET *BackUpFormSet;
+ FORM_BROWSER_FORMSET *LocalFormSet;
+ EFI_HII_HANDLE *HiiHandles;
+ UINTN Index;
+ EFI_GUID ZeroGuid;
+ UINTN BackUpClassOfVfr;
- FormLink = GetFirstNode (&FormSet->FormListHead);
- while (!IsNull (&FormSet->FormListHead, FormLink)) {
- Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);
-
+ //
+ // Check the supported setting level.
+ //
+ if (SettingScope >= MaxLevel) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (SettingScope == FormLevel) {
//
// Extract Form default
//
- StatementLink = GetFirstNode (&Form->StatementListHead);
- while (!IsNull (&Form->StatementListHead, StatementLink)) {
- Question = FORM_BROWSER_STATEMENT_FROM_LINK (StatementLink);
- StatementLink = GetNextNode (&Form->StatementListHead, StatementLink);
-
+ Link = GetFirstNode (&Form->StatementListHead);
+ while (!IsNull (&Form->StatementListHead, Link)) {
+ Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
+ Link = GetNextNode (&Form->StatementListHead, Link);
+
//
// If Question is disabled, don't reset it to default
//
@@ -2752,7 +2975,7 @@ ExtractFormSetDefault (
continue;
}
}
-
+
//
// Reset Question to its default value
//
@@ -2760,16 +2983,91 @@ ExtractFormSetDefault (
if (EFI_ERROR (Status)) {
continue;
}
-
+
//
// Synchronize Buffer storage's Edit buffer
//
if ((Question->Storage != NULL) &&
(Question->Storage->Type != EFI_HII_VARSTORE_EFI_VARIABLE)) {
SetQuestionValue (FormSet, Form, Question, TRUE);
+ //
+ // Update Form NV flag.
+ //
+ Form->NvUpdateRequired = TRUE;
+ }
+ }
+ } else if (SettingScope == FormSetLevel) {
+ FormLink = GetFirstNode (&FormSet->FormListHead);
+ while (!IsNull (&FormSet->FormListHead, FormLink)) {
+ Form = FORM_BROWSER_FORM_FROM_LINK (FormLink);
+ ExtractDefault (FormSet, Form, DefaultId, FormLevel);
+ FormLink = GetNextNode (&FormSet->FormListHead, FormLink);
+ }
+ } else if (SettingScope == SystemLevel) {
+ //
+ // Open all FormSet by locate HII packages.
+ // Initiliaze the maintain FormSet to store default data as back up data.
+ //
+ BackUpClassOfVfr = gClassOfVfr;
+ 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);
+ if (EFI_ERROR (Status) || IsListEmpty (&LocalFormSet->FormListHead)) {
+ DestroyFormSet (LocalFormSet);
+ continue;
+ }
+ Status = InitializeCurrentSetting (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
+ //
+ FreePool (HiiHandles);
+ gOldFormSet = BackUpFormSet;
+ gClassOfVfr = BackUpClassOfVfr;
+
+ //
+ // Set Default Value for each FormSet in the maintain list.
+ //
+ Link = GetFirstNode (&gBrowserFormSetList);
+ while (!IsNull (&gBrowserFormSetList, Link)) {
+ LocalFormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
+ ExtractDefault (LocalFormSet, NULL, DefaultId, FormSetLevel);
+ Link = GetNextNode (&gBrowserFormSetList, Link);
}
- FormLink = GetNextNode (&FormSet->FormListHead, FormLink);
}
return EFI_SUCCESS;
@@ -3052,10 +3350,8 @@ InitializeCurrentSetting (
//
// Extract default from IFR binary
//
- Status = ExtractFormSetDefault (FormSet, EFI_HII_DEFAULT_CLASS_STANDARD);
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ ExtractDefault (FormSet, NULL, EFI_HII_DEFAULT_CLASS_STANDARD, FormSetLevel);
+ UpdateNvInfoInForm (FormSet, FALSE);
//
// Request current settings from Configuration Driver
@@ -3180,8 +3476,8 @@ GetIfrBinaryData (
//
// if FormSetGuid is NULL or zero GUID, return first Setup FormSet in the package list
//
- if (FormSetGuid == NULL || CompareGuid (FormSetGuid, &gZeroGuid)) {
- ComparingGuid = &gEfiHiiPlatformSetupFormsetGuid;
+ if (FormSetGuid == NULL) {
+ ComparingGuid = &gZeroGuid;
} else {
ComparingGuid = FormSetGuid;
}
@@ -3227,7 +3523,8 @@ GetIfrBinaryData (
//
// Try to compare against formset GUID
//
- if (CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
+ if (CompareGuid (FormSetGuid, &gZeroGuid) ||
+ CompareGuid (ComparingGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {
break;
}
@@ -3274,7 +3571,7 @@ GetIfrBinaryData (
return EFI_NOT_FOUND;
}
- if (ClassGuidMatch && (FormSetGuid != NULL)) {
+ if (FormSetGuid != NULL) {
//
// Return the FormSet GUID
//
@@ -3330,6 +3627,7 @@ InitializeFormSet (
return Status;
}
+ FormSet->Signature = FORM_BROWSER_FORMSET_SIGNATURE;
FormSet->HiiHandle = Handle;
CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));
@@ -3382,6 +3680,7 @@ InitializeFormSet (
if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) == FORMSET_CLASS_FRONT_PAGE) {
gFrontPageHandle = FormSet->HiiHandle;
+ gFunctionKeySetting = NONE_FUNCTION_KEY_SETTING;
}
//
@@ -3393,20 +3692,10 @@ InitializeFormSet (
// Update the function key setting.
//
gFunctionKeySetting = gFunctionKeySettingTable[Index].KeySetting;
- //
- // Function key prompt can not be displayed if the function key has been disabled.
- //
- if ((gFunctionKeySetting & FUNCTION_NINE) != FUNCTION_NINE) {
- gFunctionNineString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
- }
-
- if ((gFunctionKeySetting & FUNCTION_TEN) != FUNCTION_TEN) {
- gFunctionTenString = GetToken (STRING_TOKEN (EMPTY_STRING), gHiiHandle);
- }
}
}
- return Status;
+ return EFI_SUCCESS;
}
@@ -3444,13 +3733,10 @@ SaveBrowserContext (
Context->FunctionKeySetting = gFunctionKeySetting;
Context->ResetRequired = gResetRequired;
Context->Direction = gDirection;
- Context->FunctionNineString = gFunctionNineString;
- Context->FunctionTenString = gFunctionTenString;
Context->EnterString = gEnterString;
Context->EnterCommitString = gEnterCommitString;
Context->EnterEscapeString = gEnterEscapeString;
Context->EscapeString = gEscapeString;
- Context->SaveFailed = gSaveFailed;
Context->MoveHighlight = gMoveHighlight;
Context->MakeSelection = gMakeSelection;
Context->DecNumericInput = gDecNumericInput;
@@ -3524,13 +3810,10 @@ RestoreBrowserContext (
gFunctionKeySetting = Context->FunctionKeySetting;
gResetRequired = Context->ResetRequired;
gDirection = Context->Direction;
- gFunctionNineString = Context->FunctionNineString;
- gFunctionTenString = Context->FunctionTenString;
gEnterString = Context->EnterString;
gEnterCommitString = Context->EnterCommitString;
gEnterEscapeString = Context->EnterEscapeString;
gEscapeString = Context->EscapeString;
- gSaveFailed = Context->SaveFailed;
gMoveHighlight = Context->MoveHighlight;
gMakeSelection = Context->MakeSelection;
gDecNumericInput = Context->DecNumericInput;
@@ -3569,3 +3852,334 @@ RestoreBrowserContext (
RemoveEntryList (&Context->Link);
gBS->FreePool (Context);
}
+
+/**
+ Find the matched FormSet context in the backup maintain list based on HiiHandle.
+
+ @param Handle The Hii Handle.
+
+ @return the found FormSet context. If no found, NULL will return.
+
+**/
+FORM_BROWSER_FORMSET *
+GetFormSetFromHiiHandle (
+ EFI_HII_HANDLE Handle
+ )
+{
+ LIST_ENTRY *Link;
+ FORM_BROWSER_FORMSET *FormSet;
+
+ Link = GetFirstNode (&gBrowserFormSetList);
+ while (!IsNull (&gBrowserFormSetList, Link)) {
+ FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
+ if (FormSet->HiiHandle == Handle) {
+ return FormSet;
+ }
+ Link = GetNextNode (&gBrowserFormSetList, Link);
+ }
+
+ return NULL;
+}
+
+/**
+ Check whether the input HII handle is the FormSet that is being used.
+
+ @param Handle The Hii Handle.
+
+ @retval TRUE HII handle is being used.
+ @retval FALSE HII handle is not being used.
+
+**/
+BOOLEAN
+IsHiiHandleInBrowserContext (
+ EFI_HII_HANDLE Handle
+ )
+{
+ LIST_ENTRY *Link;
+ BROWSER_CONTEXT *Context;
+
+ //
+ // HiiHandle is Current FormSet.
+ //
+ if ((gOldFormSet != NULL) && (gOldFormSet->HiiHandle == Handle)) {
+ return TRUE;
+ }
+
+ //
+ // Check whether HiiHandle is in BrowserContext.
+ //
+ Link = GetFirstNode (&gBrowserContextList);
+ while (!IsNull (&gBrowserContextList, Link)) {
+ Context = BROWSER_CONTEXT_FROM_LINK (Link);
+ if (Context->OldFormSet->HiiHandle == Handle) {
+ //
+ // HiiHandle is in BrowserContext
+ //
+ return TRUE;
+ }
+ Link = GetNextNode (&gBrowserContextList, Link);
+ }
+
+ return FALSE;
+}
+
+/**
+ Find the registered HotKey based on KeyData.
+
+ @param[in] KeyData A pointer to a buffer that describes the keystroke
+ information for the hot key.
+
+ @return The registered HotKey context. If no found, NULL will return.
+**/
+BROWSER_HOT_KEY *
+GetHotKeyFromRegisterList (
+ IN EFI_INPUT_KEY *KeyData
+ )
+{
+ LIST_ENTRY *Link;
+ BROWSER_HOT_KEY *HotKey;
+
+ Link = GetFirstNode (&gBrowserHotKeyList);
+ while (!IsNull (&gBrowserHotKeyList, Link)) {
+ HotKey = BROWSER_HOT_KEY_FROM_LINK (Link);
+ if (HotKey->KeyData->ScanCode == KeyData->ScanCode) {
+ return HotKey;
+ }
+ Link = GetNextNode (&gBrowserHotKeyList, Link);
+ }
+
+ return NULL;
+}
+
+/**
+ Configure what scope the hot key will impact.
+ All hot keys have the same scope. The mixed hot keys with the different level are not supported.
+ If no scope is set, the default scope will be FormSet level.
+ After all registered hot keys are removed, previous Scope can reset to another level.
+
+ @param[in] Scope Scope level to be set.
+
+ @retval EFI_SUCCESS Scope is set correctly.
+ @retval EFI_INVALID_PARAMETER Scope is not the valid value specified in BROWSER_SETTING_SCOPE.
+ @retval EFI_UNSPPORTED Scope level is different from current one that the registered hot keys have.
+
+**/
+EFI_STATUS
+EFIAPI
+SetScope (
+ IN BROWSER_SETTING_SCOPE Scope
+ )
+{
+ if (Scope >= MaxLevel) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // When no hot key registered in system or on the first setting,
+ // Scope can be set.
+ //
+ if (mBrowserScopeFirstSet || IsListEmpty (&gBrowserHotKeyList)) {
+ gBrowserSettingScope = Scope;
+ mBrowserScopeFirstSet = FALSE;
+ } else if (Scope != gBrowserSettingScope) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Register the hot key with its browser action, or unregistered the hot key.
+ Only support hot key that is not printable character (control key, function key, etc.).
+ If the action value is zero, the hot key will be unregistered if it has been registered.
+ If the same hot key has been registered, the new action and help string will override the previous ones.
+
+ @param[in] KeyData A pointer to a buffer that describes the keystroke
+ information for the hot key. Its type is EFI_INPUT_KEY to
+ be supported by all ConsoleIn devices.
+ @param[in] Action Action value that describes what action will be trigged when the hot key is pressed.
+ @param[in] DefaultId Specifies the type of defaults to retrieve, which is only for DEFAULT action.
+ @param[in] HelpString Help string that describes the hot key information.
+ Its value may be NULL for the unregistered hot key.
+
+ @retval EFI_SUCCESS Hot key is registered or unregistered.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL or HelpString is NULL on register.
+ @retval EFI_NOT_FOUND KeyData is not found to be unregistered.
+ @retval EFI_UNSUPPORTED Key represents a printable character. It is conflicted with Browser.
+**/
+EFI_STATUS
+EFIAPI
+RegisterHotKey (
+ IN EFI_INPUT_KEY *KeyData,
+ IN UINT32 Action,
+ IN UINT16 DefaultId,
+ IN EFI_STRING HelpString OPTIONAL
+ )
+{
+ BROWSER_HOT_KEY *HotKey;
+
+ //
+ // Check input parameters.
+ //
+ if (KeyData == NULL || KeyData->UnicodeChar != CHAR_NULL ||
+ (Action != BROWSER_ACTION_UNREGISTER && HelpString == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check whether the input KeyData is in BrowserHotKeyList.
+ //
+ HotKey = GetHotKeyFromRegisterList (KeyData);
+
+ //
+ // Unregister HotKey
+ //
+ if (Action == BROWSER_ACTION_UNREGISTER) {
+ if (HotKey != NULL) {
+ //
+ // The registered HotKey is found.
+ // Remove it from List, and free its resource.
+ //
+ RemoveEntryList (&HotKey->Link);
+ FreePool (HotKey->KeyData);
+ FreePool (HotKey->HelpString);
+ return EFI_SUCCESS;
+ } else {
+ //
+ // The registered HotKey is not found.
+ //
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ //
+ // Register HotKey into List.
+ //
+ if (HotKey == NULL) {
+ //
+ // Create new Key, and add it into List.
+ //
+ HotKey = AllocateZeroPool (sizeof (BROWSER_HOT_KEY));
+ ASSERT (HotKey != NULL);
+ HotKey->Signature = BROWSER_HOT_KEY_SIGNATURE;
+ HotKey->KeyData = AllocateCopyPool (sizeof (EFI_INPUT_KEY), KeyData);
+ InsertTailList (&gBrowserHotKeyList, &HotKey->Link);
+ }
+
+ //
+ // Fill HotKey information.
+ //
+ HotKey->Action = Action;
+ HotKey->DefaultId = DefaultId;
+ if (HotKey->HelpString != NULL) {
+ FreePool (HotKey->HelpString);
+ }
+ HotKey->HelpString = AllocateCopyPool (StrSize (HelpString), HelpString);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Register Exit handler function.
+ When more than one handler function is registered, the latter one will override the previous one.
+ When NULL handler is specified, the previous Exit handler will be unregistered.
+
+ @param[in] Handler Pointer to handler function.
+
+**/
+VOID
+EFIAPI
+RegiserExitHandler (
+ IN EXIT_HANDLER Handler
+ )
+{
+ ExitHandlerFunction = Handler;
+ return;
+}
+
+/**
+ 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.
+
+ @retval BROWSER_NO_CHANGES No browser data is changed.
+ @retval BROWSER_SAVE_CHANGES The changed browser data is saved.
+ @retval BROWSER_DISCARD_CHANGES The changed browser data is discard.
+
+**/
+UINT32
+EFIAPI
+SaveReminder (
+ VOID
+ )
+{
+ LIST_ENTRY *Link;
+ FORM_BROWSER_FORMSET *FormSet;
+ BOOLEAN IsDataChanged;
+ UINT32 DataSavedAction;
+ CHAR16 *YesResponse;
+ CHAR16 *NoResponse;
+ CHAR16 *EmptyString;
+ CHAR16 *ChangeReminderString;
+ CHAR16 *SaveConfirmString;
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+
+ DataSavedAction = BROWSER_NO_CHANGES;
+ IsDataChanged = FALSE;
+ Link = GetFirstNode (&gBrowserFormSetList);
+ while (!IsNull (&gBrowserFormSetList, Link)) {
+ FormSet = FORM_BROWSER_FORMSET_FROM_LINK (Link);
+ if (IsNvUpdateRequired (FormSet)) {
+ IsDataChanged = TRUE;
+ break;
+ }
+ Link = GetNextNode (&gBrowserFormSetList, Link);
+ }
+
+ //
+ // No data is changed. No save is required.
+ //
+ if (!IsDataChanged) {
+ return DataSavedAction;
+ }
+
+ //
+ // If data is changed, prompt user
+ //
+ Status = 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))
+ );
+
+ //
+ // 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);
+
+ return DataSavedAction;
+}
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
index 27a1ad1c3c..8f71e7cc38 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Setup.h
@@ -22,6 +22,7 @@ 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/DevicePath.h>
#include <Protocol/UnicodeCollation.h>
#include <Protocol/HiiConfigAccess.h>
@@ -74,10 +75,7 @@ extern UINT8 SetupBrowserStrings[];
// Definition for function key setting
//
#define NONE_FUNCTION_KEY_SETTING 0
-#define DEFAULT_FUNCTION_KEY_SETTING (FUNCTION_NINE | FUNCTION_TEN)
-
-#define FUNCTION_NINE (1 << 2)
-#define FUNCTION_TEN (1 << 3)
+#define ENABLE_FUNCTION_KEY_SETTING 1
typedef struct {
EFI_GUID FormSetGuid;
@@ -164,7 +162,9 @@ typedef struct {
//
// Produced protocol
//
- EFI_FORM_BROWSER2_PROTOCOL FormBrowser2;
+ EFI_FORM_BROWSER2_PROTOCOL FormBrowser2;
+
+ EFI_FORM_BROWSER_EXTENSION_PROTOCOL FormBrowserEx;
} SETUP_DRIVER_PRIVATE_DATA;
@@ -448,8 +448,12 @@ typedef struct {
#define FORMSET_DEFAULTSTORE_FROM_LINK(a) CR (a, FORMSET_DEFAULTSTORE, Link, FORMSET_DEFAULTSTORE_SIGNATURE)
+#define FORM_BROWSER_FORMSET_SIGNATURE SIGNATURE_32 ('F', 'B', 'F', 'S')
+
typedef struct {
- EFI_HII_HANDLE HiiHandle;
+ UINTN Signature;
+ LIST_ENTRY Link;
+ EFI_HII_HANDLE HiiHandle; // unique id for formset.
EFI_HANDLE DriverHandle;
EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
@@ -475,6 +479,8 @@ typedef struct {
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 {
@@ -490,13 +496,10 @@ typedef struct {
BOOLEAN ResetRequired;
UINT16 Direction;
EFI_SCREEN_DESCRIPTOR ScreenDimensions;
- CHAR16 *FunctionNineString;
- CHAR16 *FunctionTenString;
CHAR16 *EnterString;
CHAR16 *EnterCommitString;
CHAR16 *EnterEscapeString;
CHAR16 *EscapeString;
- CHAR16 *SaveFailed;
CHAR16 *MoveHighlight;
CHAR16 *MakeSelection;
CHAR16 *DecNumericInput;
@@ -534,6 +537,20 @@ typedef struct {
#define BROWSER_CONTEXT_FROM_LINK(a) CR (a, BROWSER_CONTEXT, Link, BROWSER_CONTEXT_SIGNATURE)
+#define BROWSER_HOT_KEY_SIGNATURE SIGNATURE_32 ('B', 'H', 'K', 'S')
+
+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)
+
extern EFI_HII_DATABASE_PROTOCOL *mHiiDatabase;
extern EFI_HII_STRING_PROTOCOL *mHiiString;
extern EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting;
@@ -548,12 +565,17 @@ extern UINT16 gDirection;
extern EFI_SCREEN_DESCRIPTOR gScreenDimensions;
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;
//
// Browser Global Strings
//
-extern CHAR16 *gFunctionNineString;
-extern CHAR16 *gFunctionTenString;
+extern CHAR16 *gDiscardFailed;
+extern CHAR16 *gDefaultFailed;
extern CHAR16 *gEnterString;
extern CHAR16 *gEnterCommitString;
extern CHAR16 *gEnterEscapeString;
@@ -924,38 +946,41 @@ ValidateQuestion (
IN UINTN Type
);
+
/**
- Discard data for form level or formset level.
+ Discard data based on the input setting scope (Form, FormSet or System).
@param FormSet FormSet data structure.
@param Form Form data structure.
- @param SingleForm whether submit single form or formset.
+ @param SettingScope Setting Scope for Discard action.
@retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.
**/
EFI_STATUS
DiscardForm (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_FORM *Form,
- IN BOOLEAN SingleForm
+ IN BROWSER_SETTING_SCOPE SettingScope
);
/**
- Submit data for form level or formset level.
+ Submit data based on the input Setting level (Form, FormSet or System).
@param FormSet FormSet data structure.
@param Form Form data structure.
- @param SingleForm whether submit single form or formset.
+ @param SettingScope Setting Scope for Submit action.
@retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.
**/
EFI_STATUS
SubmitForm (
IN FORM_BROWSER_FORMSET *FormSet,
IN FORM_BROWSER_FORM *Form,
- IN BOOLEAN SingleForm
+ IN BROWSER_SETTING_SCOPE SettingScope
);
/**
@@ -1011,18 +1036,23 @@ InitializeFormSet (
);
/**
- Reset Questions in a Formset to their default value.
+ Reset Questions to their default value in a Form, Formset or System.
@param FormSet FormSet data structure.
+ @param Form Form data structure.
@param DefaultId The Class of the default.
+ @param SettingScope Setting Scope for Default action.
@retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_UNSUPPORTED Unsupport SettingScope.
**/
EFI_STATUS
-ExtractFormSetDefault (
+ExtractDefault (
IN FORM_BROWSER_FORMSET *FormSet,
- IN UINT16 DefaultId
+ IN FORM_BROWSER_FORM *Form,
+ IN UINT16 DefaultId,
+ IN BROWSER_SETTING_SCOPE SettingScope
);
/**
@@ -1300,4 +1330,121 @@ ProcessCallBackFunction (
IN EFI_BROWSER_ACTION Action,
IN BOOLEAN SkipSaveOrDiscard
);
+
+/**
+ Find the matched FormSet context in the backup maintain list based on HiiHandle.
+
+ @param Handle The Hii Handle.
+
+ @return the found FormSet context. If no found, NULL will return.
+
+**/
+FORM_BROWSER_FORMSET *
+GetFormSetFromHiiHandle (
+ EFI_HII_HANDLE Handle
+ );
+
+/**
+ Check whether the input HII handle is the FormSet that is being used.
+
+ @param Handle The Hii Handle.
+
+ @retval TRUE HII handle is being used.
+ @retval FALSE HII handle is not being used.
+
+**/
+BOOLEAN
+IsHiiHandleInBrowserContext (
+ EFI_HII_HANDLE Handle
+ );
+
+/**
+ Configure what scope the hot key will impact.
+ All hot keys have the same scope. The mixed hot keys with the different level are not supported.
+ If no scope is set, the default scope will be FormSet level.
+ After all registered hot keys are removed, previous Scope can reset to another level.
+
+ @param[in] Scope Scope level to be set.
+
+ @retval EFI_SUCCESS Scope is set correctly.
+ @retval EFI_INVALID_PARAMETER Scope is not the valid value specified in BROWSER_SETTING_SCOPE.
+ @retval EFI_UNSPPORTED Scope level is different from current one that the registered hot keys have.
+
+**/
+EFI_STATUS
+EFIAPI
+SetScope (
+ IN BROWSER_SETTING_SCOPE Scope
+ );
+
+/**
+ Register the hot key with its browser action, or unregistered the hot key.
+ Only support hot key that is not printable character (control key, function key, etc.).
+ If the action value is zero, the hot key will be unregistered if it has been registered.
+ If the same hot key has been registered, the new action and help string will override the previous ones.
+
+ @param[in] KeyData A pointer to a buffer that describes the keystroke
+ information for the hot key. Its type is EFI_INPUT_KEY to
+ be supported by all ConsoleIn devices.
+ @param[in] Action Action value that describes what action will be trigged when the hot key is pressed.
+ @param[in] DefaultId Specifies the type of defaults to retrieve, which is only for DEFAULT action.
+ @param[in] HelpString Help string that describes the hot key information.
+ Its value may be NULL for the unregistered hot key.
+
+ @retval EFI_SUCCESS Hot key is registered or unregistered.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+ @retval EFI_NOT_FOUND KeyData is not found to be unregistered.
+ @retval EFI_UNSUPPORTED Key represents a printable character. It is conflicted with Browser.
+**/
+EFI_STATUS
+EFIAPI
+RegisterHotKey (
+ IN EFI_INPUT_KEY *KeyData,
+ IN UINT32 Action,
+ IN UINT16 DefaultId,
+ IN EFI_STRING HelpString OPTIONAL
+ );
+
+/**
+ Register Exit handler function.
+ When more than one handler function is registered, the latter one will override the previous one.
+ When NULL handler is specified, the previous Exit handler will be unregistered.
+
+ @param[in] Handler Pointer to handler function.
+
+**/
+VOID
+EFIAPI
+RegiserExitHandler (
+ IN EXIT_HANDLER Handler
+ );
+
+/**
+ 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.
+
+ @retval BROWSER_NO_CHANGES No browser data is changed.
+ @retval BROWSER_SAVE_CHANGES The changed browser data is saved.
+ @retval BROWSER_DISCARD_CHANGES The changed browser data is discard.
+
+**/
+UINT32
+EFIAPI
+SaveReminder (
+ VOID
+ );
+
+/**
+ Find the registered HotKey based on KeyData.
+
+ @param[in] KeyData A pointer to a buffer that describes the keystroke
+ information for the hot key.
+
+ @return The registered HotKey context. If no found, NULL will return.
+**/
+BROWSER_HOT_KEY *
+GetHotKeyFromRegisterList (
+ IN EFI_INPUT_KEY *KeyData
+ );
+
#endif
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
index 0cba75189e..6c7820c664 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
@@ -69,6 +69,7 @@
gEfiHiiConfigAccessProtocolGuid ## CONSUMES
gEfiHiiStringProtocolGuid ## CONSUMES
gEfiFormBrowser2ProtocolGuid ## PRODUCES
+ gEfiFormBrowserExProtocolGuid ## PRODUCES
gEfiHiiConfigRoutingProtocolGuid ## CONSUMES
gEfiHiiDatabaseProtocolGuid ## CONSUMES
gEfiUnicodeCollation2ProtocolGuid ## CONSUMES
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni
index b09269141b..fdecbe85a1 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserStr.uni
Binary files differ
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
index 44b4d774b7..c2340ab80a 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.c
@@ -50,27 +50,17 @@ SCAN_CODE_TO_SCREEN_OPERATION gScanCodeToOperation[] = {
{
SCAN_RIGHT,
UiRight,
- },
- {
- SCAN_F9,
- UiDefault,
- },
- {
- SCAN_F10,
- UiSave
}
};
+UINTN mScanCodeNumber = sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]);
+
SCREEN_OPERATION_T0_CONTROL_FLAG gScreenOperationToControlFlag[] = {
{
UiNoOperation,
CfUiNoOperation,
},
{
- UiDefault,
- CfUiDefault,
- },
- {
UiSelect,
CfUiSelect,
},
@@ -95,16 +85,16 @@ SCREEN_OPERATION_T0_CONTROL_FLAG gScreenOperationToControlFlag[] = {
CfUiReset,
},
{
- UiSave,
- CfUiSave,
- },
- {
UiPageUp,
CfUiPageUp,
},
{
UiPageDown,
CfUiPageDown
+ },
+ {
+ UiHotKey,
+ CfUiHotKey
}
};
@@ -1057,7 +1047,10 @@ UpdateStatusBar (
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);
@@ -1082,32 +1075,38 @@ UpdateStatusBar (
break;
case NV_UPDATE_REQUIRED:
- if ((gClassOfVfr & FORMSET_CLASS_FRONT_PAGE) != FORMSET_CLASS_FRONT_PAGE) {
- if (State) {
+ //
+ // 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
);
- gResetRequired = (BOOLEAN) (gResetRequired | ((Flags & EFI_IFR_FLAG_RESET_REQUIRED) == EFI_IFR_FLAG_RESET_REQUIRED));
-
- if (Selection != NULL) {
- Selection->Form->NvUpdateRequired = TRUE;
- }
- } 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" "
- );
- }
-
- if (Selection != NULL) {
- Selection->Form->NvUpdateRequired = FALSE;
- }
+ }
+ } 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;
@@ -1117,9 +1116,28 @@ UpdateStatusBar (
UpdateStatusBar (Selection, INPUT_ERROR, Flags, TRUE);
}
- if (IsNvUpdateRequired(Selection->FormSet)) {
- UpdateStatusBar (NULL, NV_UPDATE_REQUIRED, 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:
@@ -1877,6 +1895,7 @@ UiDisplayMenu (
FORM_BROWSER_STATEMENT *Statement;
UI_MENU_LIST *CurrentMenu;
UINTN ModalSkipColumn;
+ BROWSER_HOT_KEY *HotKey;
CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
@@ -1898,6 +1917,7 @@ UiDisplayMenu (
NextMenuOption = NULL;
PreviousMenuOption = NULL;
SavedMenuOption = NULL;
+ HotKey = NULL;
ModalSkipColumn = (LocalScreen.RightColumn - LocalScreen.LeftColumn) / 6;
ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
@@ -1916,7 +1936,7 @@ UiDisplayMenu (
Col = LocalScreen.LeftColumn + LEFT_SKIPPED_COLUMNS;
}
- BottomRow = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT - SCROLL_ARROW_HEIGHT - 1;
+ BottomRow = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - gFooterHeight - SCROLL_ARROW_HEIGHT - 1;
Selection->TopRow = TopRow;
Selection->BottomRow = BottomRow;
@@ -2620,8 +2640,9 @@ UiDisplayMenu (
//
// IFR is updated in Callback of refresh opcode, re-parse it
//
+ ControlFlag = CfCheckSelection;
Selection->Statement = NULL;
- return EFI_SUCCESS;
+ break;
}
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
@@ -2709,30 +2730,28 @@ UiDisplayMenu (
break;
case CHAR_NULL:
- if (((Key.ScanCode == SCAN_F9) && ((gFunctionKeySetting & FUNCTION_NINE) != FUNCTION_NINE)) ||
- ((Key.ScanCode == SCAN_F10) && ((gFunctionKeySetting & FUNCTION_TEN) != FUNCTION_TEN))
- ) {
+ 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)) {
//
- // If the function key has been disabled, just ignore the key.
+ // ModalForm has no ESC key and Hot Key.
//
- } else {
- for (Index = 0; Index < sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]); Index++) {
- if (Selection->Form->ModalForm &&
- (Key.ScanCode == SCAN_F9 || Key.ScanCode == SCAN_F10 || Key.ScanCode == SCAN_ESC)) {
- ControlFlag = CfReadKey;
- break;
- }
-
- if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {
- if (Key.ScanCode == SCAN_F9) {
- //
- // Reset to standard default
- //
- DefaultId = EFI_HII_DEFAULT_CLASS_STANDARD;
- }
- ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;
- break;
- }
+ ControlFlag = CfReadKey;
+ } else if (Index == mScanCodeNumber) {
+ //
+ // Check whether Key matches the registered hot key.
+ //
+ HotKey = NULL;
+ if ((gBrowserSettingScope == SystemLevel) || (gFunctionKeySetting != NONE_FUNCTION_KEY_SETTING)) {
+ HotKey = GetHotKeyFromRegisterList (&Key);
+ }
+ if (HotKey != NULL) {
+ ScreenOperation = UiHotKey;
}
}
break;
@@ -2832,9 +2851,7 @@ UiDisplayMenu (
// We come here when someone press ESC
//
ControlFlag = CfCheckSelection;
- if (FindNextMenu (Selection, &Repaint, &NewLine)) {
- return EFI_SUCCESS;
- }
+ FindNextMenu (Selection, &Repaint, &NewLine);
break;
case CfUiLeft:
@@ -3252,43 +3269,120 @@ UiDisplayMenu (
AdjustDateAndTimePosition (TRUE, &NewPos);
break;
- case CfUiSave:
+ case CfUiHotKey:
ControlFlag = CfCheckSelection;
-
+
+ Status = EFI_SUCCESS;
//
- // Submit the form
+ // Discard changes. After it, no NV flag is showed.
//
- Status = SubmitForm (Selection->FormSet, Selection->Form, FALSE);
+ 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;
+ }
+ }
- 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, gEmptyString, gSaveFailed, gPressEnter, gEmptyString);
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
+ //
+ // 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);
+ 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;
+ }
+ }
- Repaint = TRUE;
- NewLine = TRUE;
+ //
+ // 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 values for the whole formset
+ // Reset to default value for all forms in the whole system.
//
- Status = ExtractFormSetDefault (Selection->FormSet, DefaultId);
+ Status = ExtractDefault (Selection->FormSet, NULL, DefaultId, FormSetLevel);
if (!EFI_ERROR (Status)) {
Selection->Action = UI_ACTION_REFRESH_FORM;
Selection->Statement = NULL;
-
- //
- // Show NV update flag on status bar
- //
- UpdateNvInfoInForm(Selection->FormSet, TRUE);
gResetRequired = TRUE;
}
break;
diff --git a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h
index cec7dcd0c1..df5a22fe71 100644
--- a/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h
+++ b/MdeModulePkg/Universal/SetupBrowserDxe/Ui.h
@@ -33,17 +33,16 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
typedef enum {
UiNoOperation,
- UiDefault,
UiSelect,
UiUp,
UiDown,
UiLeft,
UiRight,
UiReset,
- UiSave,
UiPrevious,
UiPageUp,
UiPageDown,
+ UiHotKey,
UiMaxOperation
} UI_SCREEN_OPERATION;
@@ -64,10 +63,10 @@ typedef enum {
CfUiPageUp,
CfUiPageDown,
CfUiDown,
- CfUiSave,
CfUiDefault,
CfUiNoOperation,
CfExit,
+ CfUiHotKey,
CfMaxControlFlag
} UI_CONTROL_FLAG;