summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.c')
-rw-r--r--EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.c3150
1 files changed, 0 insertions, 3150 deletions
diff --git a/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.c b/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.c
deleted file mode 100644
index 3d30c1bd2d..0000000000
--- a/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/Ui.c
+++ /dev/null
@@ -1,3150 +0,0 @@
-/**@file
- Implementation for UI.
-
-Copyright (c) 2006 - 2007, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "Setup.h"
-#include "Ui.h"
-#include "Colors.h"
-
-//
-// Implementation
-//
-VOID
-SetUnicodeMem (
- IN VOID *Buffer,
- IN UINTN Size,
- IN CHAR16 Value
- )
-/*++
-
-Routine Description:
-
- Set Buffer to Value for Size bytes.
-
-Arguments:
-
- Buffer - Memory to set.
-
- Size - Number of bytes to set
-
- Value - Value of the set operation.
-
-Returns:
-
- None
-
---*/
-{
- CHAR16 *Ptr;
-
- Ptr = Buffer;
- while (Size--) {
- *(Ptr++) = Value;
- }
-}
-
-VOID
-UiInitMenu (
- VOID
- )
-/*++
-
-Routine Description:
- Initialize Menu option list.
-
-Arguments:
-
-Returns:
-
---*/
-{
- InitializeListHead (&Menu);
-}
-
-VOID
-UiInitMenuList (
- VOID
- )
-/*++
-
-Routine Description:
- Initialize Menu option list.
-
-Arguments:
-
-Returns:
-
---*/
-{
- InitializeListHead (&gMenuList);
-}
-
-VOID
-UiRemoveMenuListEntry (
- IN UI_MENU_OPTION *Selection,
- OUT UI_MENU_OPTION **PreviousSelection
- )
-/*++
-
-Routine Description:
- Remove Menu option list.
-
-Arguments:
-
-Returns:
-
---*/
-{
- UI_MENU_LIST *UiMenuList;
-
- *PreviousSelection = AllocateZeroPool (sizeof (UI_MENU_OPTION));
- ASSERT (*PreviousSelection != NULL);
-
- if (!IsListEmpty (&gMenuList)) {
- UiMenuList = CR (gMenuList.ForwardLink, UI_MENU_LIST, MenuLink, UI_MENU_LIST_SIGNATURE);
- (*PreviousSelection)->IfrNumber = UiMenuList->Selection.IfrNumber;
- (*PreviousSelection)->FormId = UiMenuList->Selection.FormId;
- (*PreviousSelection)->Tags = UiMenuList->Selection.Tags;
- (*PreviousSelection)->ThisTag = UiMenuList->Selection.ThisTag;
- (*PreviousSelection)->Handle = UiMenuList->Selection.Handle;
- gEntryNumber = UiMenuList->FormerEntryNumber;
- RemoveEntryList (&UiMenuList->MenuLink);
- FreePool (UiMenuList);
- }
-}
-
-VOID
-UiFreeMenuList (
- VOID
- )
-/*++
-
-Routine Description:
- Free Menu option linked list.
-
-Arguments:
-
-Returns:
-
---*/
-{
- UI_MENU_LIST *UiMenuList;
-
- while (!IsListEmpty (&gMenuList)) {
- UiMenuList = CR (gMenuList.ForwardLink, UI_MENU_LIST, MenuLink, UI_MENU_LIST_SIGNATURE);
- RemoveEntryList (&UiMenuList->MenuLink);
- FreePool (UiMenuList);
- }
-}
-
-VOID
-UiAddMenuListEntry (
- IN UI_MENU_OPTION *Selection
- )
-/*++
-
-Routine Description:
- Add one menu entry to the linked lst
-
-Arguments:
-
-Returns:
-
---*/
-{
- UI_MENU_LIST *UiMenuList;
-
- UiMenuList = AllocateZeroPool (sizeof (UI_MENU_LIST));
- ASSERT (UiMenuList != NULL);
-
- UiMenuList->Signature = UI_MENU_LIST_SIGNATURE;
- CopyMem (&UiMenuList->Selection, Selection, sizeof (UI_MENU_OPTION));
-
- InsertHeadList (&gMenuList, &UiMenuList->MenuLink);
-}
-
-VOID
-UiFreeMenu (
- VOID
- )
-/*++
-
-Routine Description:
- Free Menu option linked list.
-
-Arguments:
-
-Returns:
-
---*/
-{
- UI_MENU_OPTION *MenuOption;
-
- while (!IsListEmpty (&Menu)) {
- MenuOption = CR (Menu.ForwardLink, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- RemoveEntryList (&MenuOption->Link);
-
- //
- // We allocated space for this description when we did a GetToken, free it here
- //
- FreePool (MenuOption->Description);
- FreePool (MenuOption);
- }
-}
-
-STATIC
-VOID
-UpdateDateAndTime (
- VOID
- )
-/*++
-
-Routine Description:
- Refresh screen with current date and/or time based on screen context
-
-Arguments:
-
-Returns:
-
---*/
-{
- CHAR16 *OptionString;
- MENU_REFRESH_ENTRY *MenuRefreshEntry;
- UINTN Index;
- UINTN Loop;
-
- OptionString = NULL;
-
- if (gMenuRefreshHead != NULL) {
-
- MenuRefreshEntry = gMenuRefreshHead;
-
- do {
- gST->ConOut->SetAttribute (gST->ConOut, MenuRefreshEntry->CurrentAttribute);
- ProcessOptions (MenuRefreshEntry->MenuOption, FALSE, MenuRefreshEntry->FileFormTagsHead, NULL, &OptionString);
-
- if (OptionString != NULL) {
- //
- // If leading spaces on OptionString - remove the spaces
- //
- for (Index = 0; OptionString[Index] == L' '; Index++)
- ;
-
- for (Loop = 0; OptionString[Index] != CHAR_NULL; Index++) {
- OptionString[Loop] = OptionString[Index];
- Loop++;
- }
-
- OptionString[Loop] = CHAR_NULL;
-
- PrintStringAt (MenuRefreshEntry->CurrentColumn, MenuRefreshEntry->CurrentRow, OptionString);
- }
-
- MenuRefreshEntry = MenuRefreshEntry->Next;
-
- } while (MenuRefreshEntry != NULL);
- }
-
- if (OptionString != NULL) {
- FreePool (OptionString);
- }
-}
-
-EFI_STATUS
-UiWaitForSingleEvent (
- IN EFI_EVENT Event,
- IN UINT64 Timeout OPTIONAL
- )
-/*++
-
-Routine Description:
- Wait for a given event to fire, or for an optional timeout to expire.
-
-Arguments:
- Event - The event to wait for
-
- Timeout - An optional timeout value in 100 ns units.
-
-Returns:
-
- EFI_SUCCESS - Event fired before Timeout expired.
- EFI_TIME_OUT - Timout expired before Event fired.
-
---*/
-{
- EFI_STATUS Status;
- UINTN Index;
- EFI_EVENT TimerEvent;
- EFI_EVENT WaitList[2];
-
- if (Timeout) {
- //
- // 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
- //
- Timeout = 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;
- UpdateDateAndTime ();
- }
-
- gBS->CloseEvent (TimerEvent);
- } while (Status == EFI_TIMEOUT);
- }
-
- return Status;
-}
-
-VOID
-UiAddMenuOption (
- IN CHAR16 *String,
- IN EFI_HII_HANDLE Handle,
- IN EFI_TAG *Tags,
- IN VOID *FormBinary,
- IN UINTN IfrNumber
- )
-/*++
-
-Routine Description:
- Add one menu option by specified description and context.
-
-Arguments:
- String - String description for this option.
- Context - Context data for entry.
-
-Returns:
-
---*/
-{
- UI_MENU_OPTION *MenuOption;
-
- MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));
- ASSERT (MenuOption);
-
- MenuOption->Signature = UI_MENU_OPTION_SIGNATURE;
- MenuOption->Description = String;
- MenuOption->Handle = Handle;
- MenuOption->FormBinary = FormBinary;
- MenuOption->IfrNumber = IfrNumber;
- MenuOption->Skip = 1;
- MenuOption->Tags = Tags;
- MenuOption->TagIndex = 0;
- MenuOption->ThisTag = &(MenuOption->Tags[MenuOption->TagIndex]);
- MenuOption->EntryNumber = (UINT16) IfrNumber;
-
- InsertTailList (&Menu, &MenuOption->Link);
-}
-
-VOID
-UiAddSubMenuOption (
- IN CHAR16 *String,
- IN EFI_HII_HANDLE Handle,
- IN EFI_TAG *Tags,
- IN UINTN TagIndex,
- IN UINT16 FormId,
- IN UINT16 MenuItemCount
- )
-/*++
-
-Routine Description:
- Add one menu option by specified description and context.
-
-Arguments:
- String - String description for this option.
- Context - Context data for entry.
-
-Returns:
-
---*/
-{
- UI_MENU_OPTION *MenuOption;
-
- MenuOption = AllocateZeroPool (sizeof (UI_MENU_OPTION));
- ASSERT (MenuOption);
-
- MenuOption->Signature = UI_MENU_OPTION_SIGNATURE;
- MenuOption->Description = String;
- MenuOption->Handle = Handle;
- MenuOption->Skip = Tags[TagIndex].NumberOfLines;
- MenuOption->IfrNumber = gActiveIfr;
- MenuOption->Tags = Tags;
- MenuOption->TagIndex = TagIndex;
- MenuOption->ThisTag = &(MenuOption->Tags[MenuOption->TagIndex]);
- MenuOption->Consistency = Tags[TagIndex].Consistency;
- MenuOption->FormId = FormId;
- MenuOption->GrayOut = Tags[TagIndex].GrayOut;
- MenuOption->EntryNumber = MenuItemCount;
-
- InsertTailList (&Menu, &MenuOption->Link);
-}
-
-EFI_STATUS
-CreateDialog (
- IN UINTN NumberOfLines,
- IN BOOLEAN HotKey,
- IN UINTN MaximumStringSize,
- OUT CHAR16 *StringBuffer,
- OUT EFI_INPUT_KEY *KeyValue,
- IN CHAR16 *String,
- ...
- )
-/*++
-
-Routine Description:
- Routine used to abstract a generic dialog interface and return the selected key or string
-
-Arguments:
- NumberOfLines - The number of lines for the dialog box
- 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
- MaximumStringSize - The maximum size in bytes of a typed in string (each character is a CHAR16) and the minimum string returned is two bytes
- StringBuffer - The passed in pointer to the buffer which will hold the typed in string if HotKey is FALSE
- KeyValue - The EFI_KEY value returned if HotKey is TRUE..
- String - Pointer to the first string in the list
- ... - A series of (quantity == NumberOfLines) text strings which will be used to construct the dialog box
-
-Returns:
- EFI_SUCCESS - Displayed dialog and received user interaction
- EFI_INVALID_PARAMETER - One of the parameters was invalid (e.g. (StringBuffer == NULL) && (HotKey == FALSE))
- EFI_DEVICE_ERROR - User typed in an ESC character to exit the routine
-
---*/
-{
- 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;
- 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);
-
- VA_START (Marker, String);
-
- //
- // 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 = (GetStringWidth (String) / 2);
-
- if (LargestString == L' ') {
- InputOffset = 1;
- }
- //
- // Determine the largest string in the dialog box
- // Notice we are starting with 1 since String is the first string
- //
- for (Count = 1; 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);
- }
- }
-
- Start = (DimensionsWidth - LargestString - 2) / 2 + gScreenDimensions.LeftColumn + 1;
- Top = ((DimensionsHeight - NumberOfLines - 2) / 2) + gScreenDimensions.TopRow - 1;
-
- Count = 0;
-
- //
- // Display the Popup
- //
- CreateSharedPopUp (LargestString, NumberOfLines, &String);
-
- //
- // Take the first key typed and report it back?
- //
- if (HotKey) {
- WaitForKeyStroke (&Key);
- CopyMem (KeyValue, &Key, sizeof (EFI_INPUT_KEY));
-
- } else {
- do {
- 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);
- }
-
- 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;
-}
-
-VOID
-CreateSharedPopUp (
- IN UINTN RequestedWidth,
- IN UINTN NumberOfLines,
- IN CHAR16 **ArrayOfStrings
- )
-{
- 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;
-
- Count = 0;
-
- 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 = (CHAR16) BOXDRAW_DOWN_RIGHT;
- PrintCharAt (Start, Top, Character);
- Character = (CHAR16) BOXDRAW_HORIZONTAL;
- for (Index = Start; Index + 2 < End; Index++) {
- PrintChar (Character);
- }
-
- Character = (CHAR16) BOXDRAW_DOWN_LEFT;
- PrintChar (Character);
- Character = (CHAR16) BOXDRAW_VERTICAL;
- for (Index = Top; Index + 2 < Bottom; Index++) {
- String = ArrayOfStrings[Count];
- Count++;
-
- //
- // 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 = (CHAR16) BOXDRAW_UP_RIGHT;
- PrintCharAt (Start, Bottom - 1, Character);
- Character = (CHAR16) BOXDRAW_HORIZONTAL;
- for (Index = Start; Index + 2 < End; Index++) {
- PrintChar (Character);
- }
-
- Character = (CHAR16) BOXDRAW_UP_LEFT;
- PrintChar (Character);
-}
-
-VOID
-CreatePopUp (
- IN UINTN RequestedWidth,
- IN UINTN NumberOfLines,
- IN CHAR16 *ArrayOfStrings,
- ...
- )
-{
- CreateSharedPopUp (RequestedWidth, NumberOfLines, &ArrayOfStrings);
-}
-
-VOID
-UpdateStatusBar (
- IN UINTN MessageType,
- IN UINT8 Flags,
- IN BOOLEAN State
- )
-{
- UINTN Index;
- STATIC BOOLEAN InputError;
- CHAR16 *NvUpdateMessage;
- CHAR16 *InputErrorMessage;
-
- 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
- );
- InputError = TRUE;
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT);
- for (Index = 0; Index < (GetStringWidth (InputErrorMessage) - 2) / 2; Index++) {
- PrintAt (gScreenDimensions.LeftColumn + gPromptBlockWidth + Index, gScreenDimensions.BottomRow - 1, (CHAR16 *) L" ");
- }
-
- InputError = FALSE;
- }
- break;
-
- case NV_UPDATE_REQUIRED:
- if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {
- if (State) {
- 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));
-
- gNvUpdateRequired = TRUE;
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT);
- for (Index = 0; Index < (GetStringWidth (NvUpdateMessage) - 2) / 2; Index++) {
- PrintAt (
- (gScreenDimensions.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + Index),
- gScreenDimensions.BottomRow - 1,
- (CHAR16 *) L" "
- );
- }
-
- gNvUpdateRequired = FALSE;
- }
- }
- break;
-
- case REFRESH_STATUS_BAR:
- if (InputError) {
- UpdateStatusBar (INPUT_ERROR, Flags, TRUE);
- }
-
- if (gNvUpdateRequired) {
- UpdateStatusBar (NV_UPDATE_REQUIRED, Flags, TRUE);
- }
- break;
-
- default:
- break;
- }
-
- FreePool (InputErrorMessage);
- FreePool (NvUpdateMessage);
- return ;
-}
-
-VOID
-FreeData (
- IN EFI_FILE_FORM_TAGS *FileFormTagsHead,
- IN CHAR16 *FormattedString,
- IN CHAR16 *OptionString
- )
-/*++
-
-Routine Description:
-
- Used to remove the allocated data instances
-
-Arguments:
-
-Returns:
-
---*/
-{
- EFI_FILE_FORM_TAGS *FileForm;
- EFI_FILE_FORM_TAGS *PreviousFileForm;
- EFI_FORM_TAGS *FormTags;
- EFI_FORM_TAGS *PreviousFormTags;
- EFI_IFR_BINARY *IfrBinary;
- EFI_IFR_BINARY *PreviousIfrBinary;
- EFI_INCONSISTENCY_DATA *Inconsistent;
- EFI_VARIABLE_DEFINITION *VariableDefinition;
- EFI_VARIABLE_DEFINITION *PreviousVariableDefinition;
- VOID *Buffer;
- UINTN Index;
-
- FileForm = FileFormTagsHead;
-
- if (FormattedString != NULL) {
- FreePool (FormattedString);
- }
-
- if (OptionString != NULL) {
- FreePool (OptionString);
- }
-
- for (; FileForm != NULL;) {
- PreviousFileForm = NULL;
-
- //
- // Advance FileForm to the last entry
- //
- for (; FileForm->NextFile != NULL; FileForm = FileForm->NextFile) {
- PreviousFileForm = FileForm;
- }
-
- FormTags = &FileForm->FormTags;
-
- for (; FormTags != NULL;) {
- FormTags = &FileForm->FormTags;
- PreviousFormTags = NULL;
-
- //
- // Advance FormTags to the last entry
- //
- for (; FormTags->Next != NULL; FormTags = FormTags->Next) {
- PreviousFormTags = FormTags;
- }
- //
- // Walk through each of the tags and free the IntList allocation
- //
- for (Index = 0; FormTags->Tags[Index].Operand != EFI_IFR_END_FORM_OP; Index++) {
- //
- // It is more than likely that the very last page will contain an end formset
- //
- if (FormTags->Tags[Index].Operand == EFI_IFR_END_FORM_SET_OP) {
- break;
- }
-
- if (FormTags->Tags[Index].IntList != NULL) {
- FreePool (FormTags->Tags[Index].IntList);
- }
- }
-
- if (PreviousFormTags != NULL) {
- FreePool (FormTags->Tags);
- FormTags = PreviousFormTags;
- FreePool (FormTags->Next);
- FormTags->Next = NULL;
- } else {
- FreePool (FormTags->Tags);
- FormTags = NULL;
- }
- }
- //
- // Last FileForm entry's Inconsistent database
- //
- Inconsistent = FileForm->InconsistentTags;
-
- //
- // Advance Inconsistent to the last entry
- //
- for (; Inconsistent->Next != NULL; Inconsistent = Inconsistent->Next)
- ;
-
- for (; Inconsistent != NULL;) {
- //
- // Preserve the Previous pointer
- //
- Buffer = (VOID *) Inconsistent->Previous;
-
- //
- // Free the current entry
- //
- FreePool (Inconsistent);
-
- //
- // Restore the Previous pointer
- //
- Inconsistent = (EFI_INCONSISTENCY_DATA *) Buffer;
- }
-
- VariableDefinition = FileForm->VariableDefinitions;
-
- for (; VariableDefinition != NULL;) {
- VariableDefinition = FileForm->VariableDefinitions;
- PreviousVariableDefinition = NULL;
-
- //
- // Advance VariableDefinitions to the last entry
- //
- for (; VariableDefinition->Next != NULL; VariableDefinition = VariableDefinition->Next) {
- PreviousVariableDefinition = VariableDefinition;
- }
-
- FreePool (VariableDefinition->VariableName);
-
- if (VariableDefinition->NvRamMap != NULL) {
- FreePool (VariableDefinition->NvRamMap);
- }
-
- if (VariableDefinition->FakeNvRamMap != NULL) {
- FreePool (VariableDefinition->FakeNvRamMap);
- }
-
- if (PreviousVariableDefinition != NULL) {
- VariableDefinition = PreviousVariableDefinition;
- FreePool (VariableDefinition->Next);
- VariableDefinition->Next = NULL;
- } else {
- FreePool (VariableDefinition);
- VariableDefinition = NULL;
- }
- }
-
- if (PreviousFileForm != NULL) {
- FileForm = PreviousFileForm;
- FreePool (FileForm->NextFile);
- FileForm->NextFile = NULL;
- } else {
- FreePool (FileForm);
- FileForm = NULL;
- }
- }
-
- IfrBinary = gBinaryDataHead;
-
- for (; IfrBinary != NULL;) {
- IfrBinary = gBinaryDataHead;
- PreviousIfrBinary = NULL;
-
- //
- // Advance IfrBinary to the last entry
- //
- for (; IfrBinary->Next != NULL; IfrBinary = IfrBinary->Next) {
- PreviousIfrBinary = IfrBinary;
- }
-
- FreePool (IfrBinary->IfrPackage);
-
- if (PreviousIfrBinary != NULL) {
- IfrBinary = PreviousIfrBinary;
- FreePool (IfrBinary->Next);
- IfrBinary->Next = NULL;
- } else {
- FreePool (IfrBinary);
- IfrBinary = NULL;
- }
- }
-
- FreePool (gPreviousValue);
- gPreviousValue = NULL;
-
- //
- // Free Browser Strings
- //
- FreePool (gPressEnter);
- FreePool (gConfirmError);
- FreePool (gConfirmPassword);
- FreePool (gPromptForNewPassword);
- FreePool (gPromptForPassword);
- FreePool (gToggleCheckBox);
- FreePool (gNumericInput);
- FreePool (gMakeSelection);
- FreePool (gMoveHighlight);
- FreePool (gEscapeString);
- FreePool (gEnterCommitString);
- FreePool (gEnterString);
- FreePool (gFunctionOneString);
- FreePool (gFunctionTwoString);
- FreePool (gFunctionNineString);
- FreePool (gFunctionTenString);
- return ;
-}
-
-STATIC
-BOOLEAN
-SelectionsAreValid (
- IN UI_MENU_OPTION *MenuOption,
- IN EFI_FILE_FORM_TAGS *FileFormTagsHead
- )
-/*++
-
-Routine Description:
- Initiate late consistency checks against the current page.
-
-Arguments:
- None
-
-Returns:
-
---*/
-{
- LIST_ENTRY *Link;
- EFI_TAG *Tag;
- EFI_FILE_FORM_TAGS *FileFormTags;
- CHAR16 *StringPtr;
- CHAR16 NullCharacter;
- UINTN Index;
- UINT16 *NvRamMap;
- STRING_REF PopUp;
- EFI_INPUT_KEY Key;
- EFI_VARIABLE_DEFINITION *VariableDefinition;
-
- StringPtr = (CHAR16 *) L"\0";
- NullCharacter = CHAR_NULL;
-
- FileFormTags = FileFormTagsHead;
-
- for (Index = 0; Index < MenuOption->IfrNumber; Index++) {
- FileFormTags = FileFormTags->NextFile;
- }
-
- for (Link = Menu.ForwardLink; Link != &Menu; Link = Link->ForwardLink) {
- MenuOption = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
-
- Tag = MenuOption->ThisTag;
-
- ExtractRequestedNvMap (FileFormTags, Tag->VariableNumber, &VariableDefinition);
- NvRamMap = (UINT16 *) &VariableDefinition->NvRamMap[Tag->StorageStart];
-
- //
- // If the op-code has a late check, ensure consistency checks are now applied
- //
- if (Tag->Flags & EFI_IFR_FLAG_LATE_CHECK) {
- if (ValueIsNotValid (TRUE, 0, Tag, FileFormTags, &PopUp)) {
- if (PopUp != 0x0000) {
- StringPtr = GetToken (PopUp, MenuOption->Handle);
-
- CreatePopUp (GetStringWidth (StringPtr) / 2, 3, &NullCharacter, StringPtr, &NullCharacter);
-
- do {
- WaitForKeyStroke (&Key);
-
- switch (Key.UnicodeChar) {
-
- case CHAR_CARRIAGE_RETURN:
- //
- // Since the value can be one byte long or two bytes long, do a CopyMem based on StorageWidth
- //
- CopyMem (NvRamMap, &Tag->OldValue, Tag->StorageWidth);
- FreePool (StringPtr);
- break;
-
- default:
- break;
- }
- } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- }
-
- return FALSE;
- }
- }
- }
-
- return TRUE;
-}
-
-UINT16
-GetWidth (
- IN EFI_TAG *Tag,
- IN EFI_HII_HANDLE Handle
- )
-/*++
-
-Routine Description:
- Get the supported width for a particular op-code
-
-Arguments:
- Tag - The Tag structure passed in.
- Handle - The handle in the HII database being used
-
-Returns:
- Returns the number of CHAR16 characters that is support.
-
-
---*/
-{
- CHAR16 *String;
- UINTN Size;
-
- Size = 0x00;
-
- //
- // See if the second text parameter is really NULL
- //
- if ((Tag->Operand == EFI_IFR_TEXT_OP) && (Tag->TextTwo != 0)) {
- String = GetToken (Tag->TextTwo, Handle);
- Size = StrLen (String);
- FreePool (String);
- }
-
- if ((Tag->Operand == EFI_IFR_SUBTITLE_OP) ||
- (Tag->Operand == EFI_IFR_REF_OP) ||
- (Tag->Operand == EFI_IFR_PASSWORD_OP) ||
- (Tag->Operand == EFI_IFR_STRING_OP) ||
- (Tag->Operand == EFI_IFR_INVENTORY_OP) ||
- //
- // Allow a wide display if text op-code and no secondary text op-code
- //
- ((Tag->Operand == EFI_IFR_TEXT_OP) && (Size == 0x0000))
- ) {
- return (UINT16) (gPromptBlockWidth + gOptionBlockWidth);
- } else {
- return (UINT16) gPromptBlockWidth;
- }
-}
-
-UINT16
-GetLineByWidth (
- IN CHAR16 *InputString,
- IN UINT16 LineWidth,
- IN OUT UINTN *Index,
- OUT CHAR16 **OutputString
- )
-/*++
-
-Routine Description:
- 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.
-
-Arguments:
- InputString - String description for this option.
- LineWidth - Width of the desired string to extract in CHAR16 characters
- Index - Where in InputString to start the copy process
- OutputString - Buffer to copy the string into
-
-Returns:
- Returns the number of CHAR16 characters that were copied into the OutputString buffer.
-
-
---*/
-{
- static BOOLEAN Finished;
- UINT16 Count;
- UINT16 Count2;
-
- if (Finished) {
- Finished = FALSE;
- return (UINT16) 0;
- }
-
- Count = LineWidth;
- Count2 = 0;
-
- *OutputString = AllocateZeroPool (((UINTN) (LineWidth + 1) * 2));
-
- //
- // Ensure we have got a valid buffer
- //
- if (*OutputString != NULL) {
-
- //
- //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 (; (InputString[*Index + Count2] != CHAR_CARRIAGE_RETURN) && (Count2 != LineWidth); Count2++)
- ;
-
- //
- // Copy the desired LineWidth of data to the output buffer.
- // Also make sure that we don't copy more than the string.
- // Also make sure that if there are linefeeds, we account for them.
- //
- if ((StrSize (&InputString[*Index]) <= ((UINTN) (LineWidth + 1) * 2)) &&
- (StrSize (&InputString[*Index]) <= ((UINTN) (Count2 + 1) * 2))
- ) {
- //
- // Convert to CHAR16 value and show that we are done with this operation
- //
- LineWidth = (UINT16) ((StrSize (&InputString[*Index]) - 2) / 2);
- if (LineWidth != 0) {
- Finished = TRUE;
- }
- } else {
- if (Count2 == LineWidth) {
- //
- // Rewind the string from the maximum size until we see a space to break the line
- //
- for (; (InputString[*Index + LineWidth] != CHAR_SPACE) && (LineWidth != 0); LineWidth--)
- ;
- if (LineWidth == 0) {
- LineWidth = Count;
- }
- } else {
- LineWidth = Count2;
- }
- }
-
- CopyMem (*OutputString, &InputString[*Index], LineWidth * 2);
-
- //
- // If currently pointing to a space, increment the index to the first non-space character
- //
- for (;
- (InputString[*Index + LineWidth] == CHAR_SPACE) || (InputString[*Index + LineWidth] == CHAR_CARRIAGE_RETURN);
- (*Index)++
- )
- ;
- *Index = (UINT16) (*Index + LineWidth);
- return LineWidth;
- } else {
- return (UINT16) 0;
- }
-}
-
-STATIC
-VOID
-UpdateOptionSkipLines (
- IN EFI_IFR_DATA_ARRAY *PageData,
- IN UI_MENU_OPTION *MenuOption,
- IN EFI_FILE_FORM_TAGS *FileFormTagsHead,
- IN CHAR16 **OptionalString,
- IN UINTN SkipValue
- )
-{
- UINTN Index;
- UINT16 Width;
- UINTN Row;
- UINTN OriginalRow;
- CHAR16 *OutputString;
- CHAR16 *OptionString;
-
- Row = 0;
- OptionString = *OptionalString;
- OutputString = NULL;
-
- ProcessOptions (MenuOption, FALSE, FileFormTagsHead, PageData, &OptionString);
-
- if (OptionString != NULL) {
- Width = (UINT16) gOptionBlockWidth;
-
- OriginalRow = Row;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {
- //
- // If there is more string to process print on the next row and increment the Skip value
- //
- if (StrLen (&OptionString[Index])) {
- if (SkipValue == 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 (SkipValue != 0) {
- SkipValue--;
- }
- }
-
- Row = OriginalRow;
- }
-
- *OptionalString = OptionString;
-}
-//
-// 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_F2, UiPrevious},
- { SCAN_LEFT, UiLeft },
- { SCAN_RIGHT, UiRight },
- { SCAN_F9, UiDefault},
- { SCAN_F10, UiSave }
-};
-
-SCREEN_OPERATION_T0_CONTROL_FLAG gScreenOperationToControlFlag[] = {
- { UiNoOperation, CfUiNoOperation },
- { UiDefault, CfUiDefault },
- { UiSelect, CfUiSelect },
- { UiUp, CfUiUp},
- { UiDown, CfUiDown },
- { UiLeft, CfUiLeft },
- { UiRight, CfUiRight },
- { UiReset, CfUiReset },
- { UiSave, CfUiSave },
- { UiPrevious, CfUiPrevious },
- { UiPageUp, CfUiPageUp },
- { UiPageDown, CfUiPageDown }
-};
-
-UI_MENU_OPTION *
-UiDisplayMenu (
- IN BOOLEAN SubMenu,
- IN EFI_FILE_FORM_TAGS *FileFormTagsHead,
- OUT EFI_IFR_DATA_ARRAY *PageData
- )
-/*++
-
-Routine Description:
- 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.
-
-Arguments:
- SubMenu - Indicate is sub menu.
- FileFormTagsHead - A pointer to the EFI_FILE_FORM_TAGS structure.
- PageData - A pointer to the EFI_IFR_DATA_ARRAY.
-
-Returns:
- Return the pointer of the menu which selected,
- otherwise return NULL.
-
---*/
-{
- INTN SkipValue;
- INTN Difference;
- INTN OldSkipValue;
- UINTN Row;
- UINTN Col;
- UINTN Temp;
- UINTN Temp2;
- UINTN TopRow;
- UINTN BottomRow;
- UINTN OriginalRow;
- UINTN Index;
- UINTN DataAndTimeLineNumberPad;
- UINT32 Count;
- INT16 OriginalTimeOut;
- UINT8 *Location;
- UINT16 Width;
- CHAR16 *StringPtr;
- CHAR16 *OptionString;
- CHAR16 *OutputString;
- CHAR16 *FormattedString;
- CHAR16 YesResponse;
- CHAR16 NoResponse;
- BOOLEAN NewLine;
- BOOLEAN Repaint;
- BOOLEAN SavedValue;
- EFI_STATUS Status;
- UI_MENU_LIST *UiMenuList;
- EFI_INPUT_KEY Key;
- LIST_ENTRY *Link;
- LIST_ENTRY *NewPos;
- LIST_ENTRY *TopOfScreen;
- LIST_ENTRY *SavedListEntry;
- UI_MENU_OPTION *Selection;
- UI_MENU_OPTION *MenuOption;
- UI_MENU_OPTION *NextMenuOption;
- UI_MENU_OPTION *SavedMenuOption;
- UI_MENU_OPTION *PreviousMenuOption;
- EFI_IFR_BINARY *IfrBinary;
- UI_CONTROL_FLAG ControlFlag;
- EFI_SCREEN_DESCRIPTOR LocalScreen;
- EFI_FILE_FORM_TAGS *FileFormTags;
- MENU_REFRESH_ENTRY *MenuRefreshEntry;
- MENU_REFRESH_ENTRY *OldMenuRefreshEntry;
- UI_SCREEN_OPERATION ScreenOperation;
- EFI_VARIABLE_DEFINITION *VariableDefinition;
- EFI_FORM_CALLBACK_PROTOCOL *FormCallback;
- EFI_HII_VARIABLE_PACK_LIST *NvMapListHead;
- EFI_HII_VARIABLE_PACK_LIST *NvMapListNode;
- VOID *NvMap;
- UINTN NvMapSize;
-
- CopyMem (&LocalScreen, &gScreenDimensions, sizeof (EFI_SCREEN_DESCRIPTOR));
-
- VariableDefinition = NULL;
- Status = EFI_SUCCESS;
- FormattedString = NULL;
- OptionString = NULL;
- ScreenOperation = UiNoOperation;
- NewLine = TRUE;
- FormCallback = NULL;
- FileFormTags = NULL;
- OutputString = NULL;
- gUpArrow = FALSE;
- gDownArrow = FALSE;
- SkipValue = 0;
- OldSkipValue = 0;
- MenuRefreshEntry = gMenuRefreshHead;
- OldMenuRefreshEntry = gMenuRefreshHead;
- NextMenuOption = NULL;
- PreviousMenuOption = NULL;
- SavedMenuOption = NULL;
- IfrBinary = NULL;
- NvMap = NULL;
- NvMapSize = 0;
-
- ZeroMem (&Key, sizeof (EFI_INPUT_KEY));
-
- if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {
- 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 (SubMenu) {
- Col = LocalScreen.LeftColumn;
- } else {
- Col = LocalScreen.LeftColumn + LEFT_SKIPPED_COLUMNS;
- }
-
- BottomRow = LocalScreen.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT - SCROLL_ARROW_HEIGHT - 1;
-
- TopOfScreen = Menu.ForwardLink;
- Repaint = TRUE;
- MenuOption = NULL;
-
- //
- // Get user's selection
- //
- Selection = NULL;
- NewPos = Menu.ForwardLink;
- gST->ConOut->EnableCursor (gST->ConOut, FALSE);
-
- UpdateStatusBar (REFRESH_STATUS_BAR, (UINT8) 0, TRUE);
-
- ControlFlag = CfInitialization;
-
- while (TRUE) {
- switch (ControlFlag) {
- case CfInitialization:
- ControlFlag = CfCheckSelection;
- if (gExitRequired) {
- ScreenOperation = UiReset;
- ControlFlag = CfScreenOperation;
- } else if (gSaveRequired) {
- ScreenOperation = UiSave;
- ControlFlag = CfScreenOperation;
- } else if (IsListEmpty (&Menu)) {
- ControlFlag = CfReadKey;
- }
- break;
-
- case CfCheckSelection:
- if (Selection != NULL) {
- ControlFlag = CfExit;
- } else {
- ControlFlag = CfRepaint;
- }
-
- FileFormTags = FileFormTagsHead;
- break;
-
- case CfRepaint:
- ControlFlag = CfRefreshHighLight;
-
- if (Repaint) {
- //
- // Display menu
- //
- SavedMenuOption = MenuOption;
- gDownArrow = FALSE;
- gUpArrow = FALSE;
- Row = TopRow;
-
- Temp = SkipValue;
- Temp2 = SkipValue;
-
- ClearLines (
- LocalScreen.LeftColumn,
- LocalScreen.RightColumn,
- TopRow - SCROLL_ARROW_HEIGHT,
- BottomRow + SCROLL_ARROW_HEIGHT,
- FIELD_TEXT | FIELD_BACKGROUND
- );
-
- while (gMenuRefreshHead != NULL) {
- OldMenuRefreshEntry = gMenuRefreshHead->Next;
-
- FreePool (gMenuRefreshHead);
-
- gMenuRefreshHead = OldMenuRefreshEntry;
- }
-
- for (Link = TopOfScreen; Link != &Menu; Link = Link->ForwardLink) {
- MenuOption = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- MenuOption->Row = Row;
- OriginalRow = Row;
- MenuOption->Col = Col;
- MenuOption->OptCol = gPromptBlockWidth + 1 + LocalScreen.LeftColumn;
-
- if (SubMenu) {
- if (MenuOption->ThisTag->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, SUBTITLE_TEXT | FIELD_BACKGROUND);
- }
- }
-
- Width = GetWidth (MenuOption->ThisTag, MenuOption->Handle);
-
- OriginalRow = Row;
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &Index, &OutputString) != 0x0000;) {
- if ((Temp == 0) && (Row <= BottomRow)) {
- PrintStringAt (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])) {
- if (Temp == 0) {
- Row++;
- }
- }
-
- FreePool (OutputString);
- if (Temp != 0) {
- Temp--;
- }
- }
-
- Temp = 0;
-
- Row = OriginalRow;
-
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
- ProcessOptions (MenuOption, FALSE, FileFormTagsHead, PageData, &OptionString);
-
- if (OptionString != NULL) {
- if (MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP ||
- MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP
- ) {
- //
- // If leading spaces on OptionString - remove the spaces
- //
- for (Index = 0; OptionString[Index] == L' '; Index++) {
- MenuOption->OptCol++;
- }
-
- for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {
- OptionString[Count] = OptionString[Index];
- Count++;
- }
-
- OptionString[Count] = CHAR_NULL;
- }
-
- //
- // If this is a date or time op-code and is used to reflect an RTC, register the op-code
- //
- if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP ||
- MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP) &&
- (MenuOption->ThisTag->StorageStart >= FileFormTags->FormTags.Tags[0].NvDataSize)) {
-
- if (gMenuRefreshHead == NULL) {
- MenuRefreshEntry = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));
- ASSERT (MenuRefreshEntry != NULL);
- MenuRefreshEntry->MenuOption = MenuOption;
- MenuRefreshEntry->FileFormTagsHead = FileFormTagsHead;
- MenuRefreshEntry->CurrentColumn = MenuOption->OptCol;
- MenuRefreshEntry->CurrentRow = MenuOption->Row;
- MenuRefreshEntry->CurrentAttribute = FIELD_TEXT | FIELD_BACKGROUND;
- gMenuRefreshHead = MenuRefreshEntry;
- } else {
- //
- // Advance to the last entry
- //
- for (MenuRefreshEntry = gMenuRefreshHead;
- MenuRefreshEntry->Next != NULL;
- MenuRefreshEntry = MenuRefreshEntry->Next
- )
- ;
- MenuRefreshEntry->Next = AllocateZeroPool (sizeof (MENU_REFRESH_ENTRY));
- ASSERT (MenuRefreshEntry->Next != NULL);
- MenuRefreshEntry = MenuRefreshEntry->Next;
- MenuRefreshEntry->MenuOption = MenuOption;
- MenuRefreshEntry->FileFormTagsHead = FileFormTagsHead;
- MenuRefreshEntry->CurrentColumn = MenuOption->OptCol;
- MenuRefreshEntry->CurrentRow = MenuOption->Row;
- MenuRefreshEntry->CurrentAttribute = FIELD_TEXT | FIELD_BACKGROUND;
- }
- }
-
- Width = (UINT16) gOptionBlockWidth;
-
- OriginalRow = Row;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &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])) {
- 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;
- }
- //
- // If this is a text op with secondary text information
- //
- if ((MenuOption->ThisTag->Operand == EFI_IFR_TEXT_OP) && (MenuOption->ThisTag->TextTwo != 0)) {
- StringPtr = GetToken (MenuOption->ThisTag->TextTwo, MenuOption->Handle);
-
- Width = (UINT16) gOptionBlockWidth;
-
- OriginalRow = Row;
-
- for (Index = 0; GetLineByWidth (StringPtr, Width, &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])) {
- 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);
- }
- } else {
- //
- // For now, assume left-justified 72 width max setup entries
- //
- PrintStringAt (Col, Row, MenuOption->Description);
- }
- //
- // Tracker 6210 - need to handle the bottom of the display
- //
- if (MenuOption->Skip > 1) {
- Row += MenuOption->Skip - SkipValue;
- SkipValue = 0;
- } else {
- Row += MenuOption->Skip;
- }
-
- if (Row > BottomRow) {
- if (!ValueIsScroll (FALSE, Link)) {
- gDownArrow = TRUE;
- }
-
- Row = BottomRow + 1;
- break;
- }
- }
-
- if (!ValueIsScroll (TRUE, TopOfScreen)) {
- gUpArrow = TRUE;
- }
-
- if (gUpArrow) {
- gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);
- PrintAt (
- LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
- TopRow - SCROLL_ARROW_HEIGHT,
- (CHAR16 *) L"%c",
- ARROW_UP
- );
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
- }
-
- if (gDownArrow) {
- gST->ConOut->SetAttribute (gST->ConOut, ARROW_TEXT | ARROW_BACKGROUND);
- PrintAt (
- LocalScreen.LeftColumn + gPromptBlockWidth + gOptionBlockWidth + 1,
- BottomRow + SCROLL_ARROW_HEIGHT,
- (CHAR16 *) L"%c",
- ARROW_DOWN
- );
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
- }
-
- if (SavedMenuOption != NULL) {
- MenuOption = SavedMenuOption;
- }
- }
- break;
-
- case CfRefreshHighLight:
- ControlFlag = CfUpdateHelpString;
- //
- // 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 (NewPos != NULL) {
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
- if (SubMenu) {
- if (gLastOpr && (gEntryNumber != -1)) {
- MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- if (gEntryNumber != MenuOption->EntryNumber) {
- ScreenOperation = UiDown;
- ControlFlag = CfScreenOperation;
- break;
- } else {
- gLastOpr = FALSE;
- }
- }
-
- ProcessOptions (MenuOption, FALSE, FileFormTagsHead, PageData, &OptionString);
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
- if (OptionString != NULL) {
- if (MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP ||
- MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP
- ) {
- //
- // If leading spaces on OptionString - remove the spaces
- //
- for (Index = 0; OptionString[Index] == L' '; Index++)
- ;
-
- for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {
- OptionString[Count] = OptionString[Index];
- Count++;
- }
-
- OptionString[Count] = CHAR_NULL;
- }
-
- Width = (UINT16) gOptionBlockWidth;
-
- OriginalRow = MenuOption->Row;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {
- if (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])) {
- MenuOption->Row++;
- }
-
- FreePool (OutputString);
- }
-
- MenuOption->Row = OriginalRow;
- } else {
- if (NewLine) {
- if (MenuOption->ThisTag->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, SUBTITLE_TEXT | FIELD_BACKGROUND);
- }
- }
-
- OriginalRow = MenuOption->Row;
- Width = GetWidth (MenuOption->ThisTag, MenuOption->Handle);
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &Index, &OutputString) != 0x0000;) {
- if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {
- PrintStringAt (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])) {
- MenuOption->Row++;
- }
-
- FreePool (OutputString);
- }
-
- MenuOption->Row = OriginalRow;
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
- }
- }
- } else {
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND);
- gST->ConOut->OutputString (gST->ConOut, MenuOption->Description);
- }
-
- MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
-
- if ((gPriorMenuEntry != 0) && (MenuOption->EntryNumber != gPriorMenuEntry) && (NewPos->ForwardLink != &Menu)) {
- ScreenOperation = UiDown;
- ControlFlag = CfScreenOperation;
- break;
- } else {
- gPriorMenuEntry = 0;
- }
- //
- // This is only possible if we entered this page and the first menu option is
- // a "non-menu" item. In that case, force it UiDown
- //
- if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || MenuOption->ThisTag->GrayOut) {
- //
- // If we previously hit an UP command and we are still sitting on a text operation
- // we must continue going up
- //
- if (ScreenOperation == UiUp) {
- ControlFlag = CfScreenOperation;
- break;
- } else {
- ScreenOperation = UiDown;
- ControlFlag = CfScreenOperation;
- break;
- }
- }
- //
- // Set reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT | FIELD_BACKGROUND_HIGHLIGHT);
- 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) {
- MenuRefreshEntry->CurrentAttribute = FIELD_TEXT | FIELD_BACKGROUND;
- if (MenuRefreshEntry->MenuOption == MenuOption) {
- MenuRefreshEntry->CurrentAttribute = FIELD_TEXT_HIGHLIGHT | FIELD_BACKGROUND_HIGHLIGHT;
- }
- }
- }
-
- if (SubMenu) {
- ProcessOptions (MenuOption, FALSE, FileFormTagsHead, PageData, &OptionString);
- if (OptionString != NULL) {
- if (MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP ||
- MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP
- ) {
- //
- // If leading spaces on OptionString - remove the spaces
- //
- for (Index = 0; OptionString[Index] == L' '; Index++)
- ;
-
- for (Count = 0; OptionString[Index] != CHAR_NULL; Index++) {
- OptionString[Count] = OptionString[Index];
- Count++;
- }
-
- OptionString[Count] = CHAR_NULL;
- }
- Width = (UINT16) gOptionBlockWidth;
-
- OriginalRow = MenuOption->Row;
-
- for (Index = 0; GetLineByWidth (OptionString, Width, &Index, &OutputString) != 0x0000;) {
- if (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])) {
- MenuOption->Row++;
- }
-
- FreePool (OutputString);
- }
-
- MenuOption->Row = OriginalRow;
- } else {
- if (NewLine) {
- OriginalRow = MenuOption->Row;
-
- Width = GetWidth (MenuOption->ThisTag, MenuOption->Handle);
-
- for (Index = 0; GetLineByWidth (MenuOption->Description, Width, &Index, &OutputString) != 0x0000;) {
- if (MenuOption->Row >= TopRow && MenuOption->Row <= BottomRow) {
- PrintStringAt (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])) {
- MenuOption->Row++;
- }
-
- FreePool (OutputString);
- }
-
- MenuOption->Row = OriginalRow;
-
- }
- }
-
- if (((NewPos->ForwardLink != &Menu) && (ScreenOperation == UiDown)) ||
- ((NewPos->BackLink != &Menu) && (ScreenOperation == UiUp)) ||
- (ScreenOperation == UiNoOperation)
- ) {
- UpdateKeyHelp (MenuOption, FALSE);
- }
- } else {
- gST->ConOut->OutputString (gST->ConOut, MenuOption->Description);
- }
- //
- // Clear reverse attribute
- //
- gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | 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 (SubMenu &&
- (Repaint || NewLine ||
- (MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) ||
- (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) &&
- !(gClassOfVfr == EFI_GENERAL_APPLICATION_SUBCLASS)) {
- //
- // Don't print anything if it is a NULL help token
- //
- if (MenuOption->ThisTag->Help == 0x00000000) {
- StringPtr = (CHAR16 *) L"\0";
- } else {
- StringPtr = GetToken (MenuOption->ThisTag->Help, MenuOption->Handle);
- }
-
- ProcessHelpString (StringPtr, &FormattedString, BottomRow - TopRow);
-
- gST->ConOut->SetAttribute (gST->ConOut, HELP_TEXT | FIELD_BACKGROUND);
-
- for (Index = 0; Index < BottomRow - TopRow; Index++) {
- //
- // Pad String with spaces to simulate a clearing of the previous line
- //
- for (; GetStringWidth (&FormattedString[Index * gHelpBlockWidth * 2]) / 2 < gHelpBlockWidth;) {
- StrCat (&FormattedString[Index * gHelpBlockWidth * 2], (CHAR16 *) L" ");
- }
-
- PrintStringAt (
- LocalScreen.RightColumn - gHelpBlockWidth,
- Index + TopRow,
- &FormattedString[Index * gHelpBlockWidth * 2]
- );
- }
- }
- //
- // Reset this flag every time we finish using it.
- //
- Repaint = FALSE;
- NewLine = FALSE;
- break;
-
- case CfPrepareToReadKey:
- ControlFlag = CfReadKey;
-
- for (Index = 0; Index < MenuOption->IfrNumber; Index++) {
- FileFormTags = FileFormTags->NextFile;
- }
-
- ScreenOperation = UiNoOperation;
-
- Status = gBS->HandleProtocol (
- (VOID *) (UINTN) FileFormTags->FormTags.Tags[0].CallbackHandle,
- &gEfiFormCallbackProtocolGuid,
- (VOID **) &FormCallback
- );
-
- break;
-
- case CfReadKey:
- ControlFlag = CfScreenOperation;
-
- OriginalTimeOut = FrontPageTimeOutValue;
- do {
- if (FrontPageTimeOutValue >= 0 && (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) && FrontPageTimeOutValue != (INT16) -1) {
- //
- // Remember that if set to 0, must immediately boot an option
- //
- if (FrontPageTimeOutValue == 0) {
- FrontPageTimeOutValue = 0xFFFF;
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
- if (EFI_ERROR (Status)) {
- Status = EFI_TIMEOUT;
- }
- break;
- }
-
- Status = UiWaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND);
- if (Status == EFI_TIMEOUT) {
- EFI_IFR_DATA_ENTRY *DataEntry;
-
- DataEntry = (EFI_IFR_DATA_ENTRY *) (PageData + 1);
-
- PageData->EntryCount = 1;
- Count = (UINT32) ((OriginalTimeOut - FrontPageTimeOutValue) * 100 / OriginalTimeOut);
- CopyMem (&DataEntry->Data, &Count, sizeof (UINT32));
-
- if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {
- FormCallback->Callback (
- FormCallback,
- 0xFFFF,
- (EFI_IFR_DATA_ARRAY *) PageData,
- NULL
- );
- }
- //
- // Count down 1 second
- //
- FrontPageTimeOutValue--;
-
- } else {
- ASSERT (!EFI_ERROR (Status));
- PageData->EntryCount = 0;
- if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) {
- FormCallback->Callback (
- FormCallback,
- 0xFFFE,
- (EFI_IFR_DATA_ARRAY *) PageData,
- NULL
- );
- }
-
- FrontPageTimeOutValue = 0xFFFF;
- }
- } else {
- //
- // Wait for user's selection, no auto boot
- //
- Status = UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0);
- }
- } while (Status == EFI_TIMEOUT);
-
- if (gFirstIn) {
- gFirstIn = FALSE;
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- DisableQuietBoot ();
- }
-
- if (Status == EFI_TIMEOUT) {
- Key.UnicodeChar = CHAR_CARRIAGE_RETURN;
- } else {
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
- //
- // if we encounter error, continue to read another key in.
- //
- if (EFI_ERROR (Status)) {
- ControlFlag = CfReadKey;
- continue;
- }
- }
-
- switch (Key.UnicodeChar) {
- case CHAR_CARRIAGE_RETURN:
- Selection = MenuOption;
- ScreenOperation = UiSelect;
- gDirection = 0;
- break;
-
- //
- // We will push the adjustment of these numeric values directly to the input handler
- //
- case '+':
- case '-':
- if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {
-
- if (Key.UnicodeChar == '+') {
- gDirection = SCAN_RIGHT;
- } else {
- gDirection = SCAN_LEFT;
- }
-
- Status = ProcessOptions (MenuOption, TRUE, FileFormTagsHead, NULL, &OptionString);
- }
- break;
-
- case '^':
- ScreenOperation = UiUp;
- break;
-
- case 'V':
- case 'v':
- ScreenOperation = UiDown;
- break;
-
- case ' ':
- if (gClassOfVfr != EFI_FRONT_PAGE_SUBCLASS) {
- if (SubMenu) {
- if (MenuOption->ThisTag->Operand == EFI_IFR_CHECKBOX_OP && !(MenuOption->ThisTag->GrayOut)) {
- gST->ConOut->SetCursorPosition (gST->ConOut, MenuOption->Col, MenuOption->Row);
- gST->ConOut->OutputString (gST->ConOut, MenuOption->Description);
- Selection = MenuOption;
- ScreenOperation = UiSelect;
- }
- }
- }
- break;
-
- case CHAR_NULL:
- if (((Key.ScanCode == SCAN_F1) && ((gFunctionKeySetting & FUNCTION_ONE) != FUNCTION_ONE)) ||
- ((Key.ScanCode == SCAN_F2) && ((gFunctionKeySetting & FUNCTION_TWO) != FUNCTION_TWO)) ||
- ((Key.ScanCode == SCAN_F9) && ((gFunctionKeySetting & FUNCTION_NINE) != FUNCTION_NINE)) ||
- ((Key.ScanCode == SCAN_F10) && ((gFunctionKeySetting & FUNCTION_TEN) != FUNCTION_TEN))
- ) {
- //
- // If the function key has been disabled, just ignore the key.
- //
- } else {
- for (Index = 0; Index < sizeof (gScanCodeToOperation) / sizeof (gScanCodeToOperation[0]); Index++) {
- if (Key.ScanCode == gScanCodeToOperation[Index].ScanCode) {
- if ((Key.ScanCode == SCAN_F9) || (Key.ScanCode == SCAN_F10)) {
- if (SubMenu) {
- ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;
- }
- } else {
- ScreenOperation = gScanCodeToOperation[Index].ScreenOperation;
- }
- }
- }
- }
- break;
- }
- break;
-
- case CfScreenOperation:
- IfrBinary = gBinaryDataHead;
-
- //
- // Advance to the Ifr we are using
- //
- for (Index = 0; Index < gActiveIfr; Index++) {
- IfrBinary = IfrBinary->Next;
- }
-
- if (ScreenOperation != UiPrevious && ScreenOperation != UiReset) {
- //
- // If the screen has no menu items, and the user didn't select UiPrevious, or UiReset
- // ignore the selection and go back to reading keys.
- //
- if (IsListEmpty (&Menu)) {
- ControlFlag = CfReadKey;
- break;
- }
- //
- // if there is nothing logical to place a cursor on, just move on to wait for a key.
- //
- for (Link = Menu.ForwardLink; Link != &Menu; Link = Link->ForwardLink) {
- NextMenuOption = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- if (!(NextMenuOption->ThisTag->GrayOut) && (NextMenuOption->ThisTag->Operand != EFI_IFR_SUBTITLE_OP)) {
- break;
- }
- }
-
- if (Link == &Menu) {
- ControlFlag = CfPrepareToReadKey;
- break;
- }
- }
-
- for (Index = 0;
- Index < sizeof (gScreenOperationToControlFlag) / sizeof (gScreenOperationToControlFlag[0]);
- Index++
- ) {
- if (ScreenOperation == gScreenOperationToControlFlag[Index].ScreenOperation) {
- ControlFlag = gScreenOperationToControlFlag[Index].ControlFlag;
- }
- }
-
- break;
-
- case CfUiPrevious:
- ControlFlag = CfCheckSelection;
- //
- // Check for tags that might have LATE_CHECK enabled. If they do, we can't switch pages or save NV data.
- //
- if (MenuOption != NULL) {
- if (!SelectionsAreValid (MenuOption, FileFormTagsHead)) {
- Selection = NULL;
- Repaint = TRUE;
- break;
- }
- }
-
- if (IsListEmpty (&gMenuList)) {
- Selection = NULL;
- if (IsListEmpty (&Menu)) {
- ControlFlag = CfReadKey;
- }
- break;
- }
-
- gLastOpr = TRUE;
-
- while (gMenuRefreshHead != NULL) {
- OldMenuRefreshEntry = gMenuRefreshHead->Next;
-
- FreePool (gMenuRefreshHead);
-
- gMenuRefreshHead = OldMenuRefreshEntry;
- }
- //
- // Remove the Cached page entry, free and init the menus, flag Selection as jumping to previous page and a valid Tag
- //
- if (SubMenu) {
- UiRemoveMenuListEntry (MenuOption, &Selection);
- Selection->Previous = TRUE;
- UiFreeMenu ();
- UiInitMenu ();
- }
-
- gActiveIfr = Selection->IfrNumber;
- return Selection;
-
- case CfUiSelect:
- ControlFlag = CfCheckSelection;
-
- ExtractRequestedNvMap (FileFormTags, MenuOption->ThisTag->VariableNumber, &VariableDefinition);
-
- if (SubMenu) {
- if ((MenuOption->ThisTag->Operand == EFI_IFR_TEXT_OP &&
- !(MenuOption->ThisTag->Flags & EFI_IFR_FLAG_INTERACTIVE)) ||
- (MenuOption->ThisTag->GrayOut) ||
- (MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) ||
- (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {
- Selection = NULL;
- break;
- }
-
- NewLine = TRUE;
- UpdateKeyHelp (MenuOption, TRUE);
- Status = ProcessOptions (MenuOption, TRUE, FileFormTagsHead, PageData, &OptionString);
-
- if (EFI_ERROR (Status)) {
- Selection = NULL;
- Repaint = TRUE;
- break;
- }
-
- if (OptionString != NULL) {
- PrintStringAt (LocalScreen.LeftColumn + gPromptBlockWidth + 1, MenuOption->Row, OptionString);
- }
-
- if (MenuOption->ThisTag->Flags & EFI_IFR_FLAG_INTERACTIVE) {
- Selection = MenuOption;
- }
-
- if (Selection == NULL) {
- break;
- }
-
- Location = (UINT8 *) &PageData->EntryCount;
-
- //
- // If not a goto, dump single piece of data, otherwise dump everything
- //
- if (Selection->ThisTag->Operand == EFI_IFR_REF_OP) {
- //
- // Check for tags that might have LATE_CHECK enabled. If they do, we can't switch pages or save NV data.
- //
- if (!SelectionsAreValid (MenuOption, FileFormTagsHead)) {
- Selection = NULL;
- Repaint = TRUE;
- break;
- }
-
- UiAddMenuListEntry (Selection);
- gPriorMenuEntry = 0;
-
- //
- // Now that we added a menu entry specific to a goto, we can always go back when someone hits the UiPrevious
- //
- UiMenuList = CR (gMenuList.ForwardLink, UI_MENU_LIST, MenuLink, UI_MENU_LIST_SIGNATURE);
- UiMenuList->FormerEntryNumber = MenuOption->EntryNumber;
-
- gLastOpr = FALSE;
-
- //
- // Rewind to the beginning of the menu
- //
- for (; NewPos->BackLink != &Menu; NewPos = NewPos->BackLink)
- ;
-
- //
- // Get Total Count of Menu entries
- //
- for (Count = 1; NewPos->ForwardLink != &Menu; NewPos = NewPos->ForwardLink) {
- Count++;
- }
- //
- // Rewind to the beginning of the menu
- //
- for (; NewPos->BackLink != &Menu; NewPos = NewPos->BackLink)
- ;
-
- //
- // Copy the number of entries being described to the PageData location
- //
- CopyMem (&Location[0], &Count, sizeof (UINT32));
-
- for (Index = 4; NewPos->ForwardLink != &Menu; Index = Index + MenuOption->ThisTag->StorageWidth + 2) {
-
- MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- Location[Index] = MenuOption->ThisTag->Operand;
- Location[Index + 1] = (UINT8) (MenuOption->ThisTag->StorageWidth + 4);
- CopyMem (
- &Location[Index + 4],
- &VariableDefinition->NvRamMap[MenuOption->ThisTag->StorageStart],
- MenuOption->ThisTag->StorageWidth
- );
- NewPos = NewPos->ForwardLink;
- }
- } else {
-
- gPriorMenuEntry = MenuOption->EntryNumber;
-
- Count = 1;
-
- //
- // Copy the number of entries being described to the PageData location
- //
- CopyMem (&Location[0], &Count, sizeof (UINT32));
-
- //
- // Start at PageData[4] since the EntryCount is a UINT32
- //
- Index = 4;
-
- //
- // Copy data to destination
- //
- Location[Index] = MenuOption->ThisTag->Operand;
- Location[Index + 1] = (UINT8) (MenuOption->ThisTag->StorageWidth + 4);
- CopyMem (
- &Location[Index + 4],
- &VariableDefinition->NvRamMap[MenuOption->ThisTag->StorageStart],
- MenuOption->ThisTag->StorageWidth
- );
- }
- }
- break;
-
- case CfUiReset:
- ControlFlag = CfCheckSelection;
- gLastOpr = FALSE;
- if (gClassOfVfr == EFI_FRONT_PAGE_SUBCLASS) {
- break;
- }
- //
- // If NV flag is up, prompt user
- //
- if (gNvUpdateRequired) {
- Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
-
- YesResponse = gYesResponse[0];
- NoResponse = gNoResponse[0];
-
- do {
- CreateDialog (3, TRUE, 0, NULL, &Key, gEmptyString, 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 the user hits the YesResponse key
- //
- if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (YesResponse | UPPER_LOWER_CASE_OFFSET)) {
- } else {
- Repaint = TRUE;
- NewLine = TRUE;
- break;
- }
- }
- //
- // Check for tags that might have LATE_CHECK enabled. If they do, we can't switch pages or save NV data.
- //
- if (MenuOption != NULL) {
- if (!SelectionsAreValid (MenuOption, FileFormTagsHead)) {
- Selection = NULL;
- Repaint = TRUE;
- NewLine = TRUE;
- break;
- }
- }
-
- gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK));
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
-
- if (SubMenu) {
- UiFreeMenuList ();
- gST->ConOut->ClearScreen (gST->ConOut);
- return NULL;
- }
-
- UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->Flags, FALSE);
- UpdateStatusBar (NV_UPDATE_REQUIRED, MenuOption->ThisTag->Flags, FALSE);
-
- if (IfrBinary->UnRegisterOnExit) {
- Hii->RemovePack (Hii, MenuOption->Handle);
- }
-
- UiFreeMenu ();
-
- //
- // Clean up the allocated data buffers
- //
- FreeData (FileFormTagsHead, FormattedString, OptionString);
-
- gST->ConOut->ClearScreen (gST->ConOut);
- return NULL;
-
- case CfUiLeft:
- ControlFlag = CfCheckSelection;
- if ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP)) {
- if (MenuOption->Skip == 1) {
- //
- // In the tail of the Date/Time op-code set, go left.
- //
- NewPos = NewPos->BackLink;
- } else {
- //
- // In the middle of the Data/Time op-code set, go left.
- //
- NextMenuOption = CR (NewPos->ForwardLink, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- if (NextMenuOption->Skip == 1) {
- NewPos = NewPos->BackLink;
- }
- }
- }
- break;
-
- case CfUiRight:
- ControlFlag = CfCheckSelection;
- if ((MenuOption->Skip == 0) &&
- ((MenuOption->ThisTag->Operand == EFI_IFR_DATE_OP) || (MenuOption->ThisTag->Operand == EFI_IFR_TIME_OP))
- ) {
- //
- // We are in the head or middle of the Date/Time op-code set, advance right.
- //
- NewPos = NewPos->ForwardLink;
- }
- break;
-
- case CfUiUp:
- ControlFlag = CfCheckSelection;
-
- if (NewPos->BackLink != &Menu) {
- NewLine = TRUE;
- //
- // Adjust Date/Time position before we advance forward.
- //
- AdjustDateAndTimePosition (TRUE, &NewPos);
-
- //
- // Caution that we have already rewind to the top, don't go backward in this situation.
- //
- if (NewPos->BackLink != &Menu) {
- NewPos = NewPos->BackLink;
- }
-
- PreviousMenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
-
- //
- // Since the behavior of hitting the up arrow on a Date/Time op-code is intended
- // to be one that back to the previous set of op-codes, we need to advance to the sencond
- // Date/Time op-code and leave the remaining logic in UiDown intact so the appropriate
- // checking can be done.
- //
- DataAndTimeLineNumberPad = AdjustDateAndTimePosition (TRUE, &NewPos);
-
- if (SubMenu) {
- //
- // If the previous MenuOption contains a display-only op-code, skip to the next one
- //
- if (PreviousMenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || PreviousMenuOption->ThisTag->GrayOut) {
- //
- // This is ok as long as not at the end of the list
- //
- if (NewPos->BackLink == &Menu) {
- //
- // If we are at the start of the list, then this list must start with a display only
- // piece of data, so do not allow the backward motion
- //
- ScreenOperation = UiDown;
-
- if (PreviousMenuOption->Row <= TopRow) {
- if (TopOfScreen->BackLink != &Menu) {
- TopOfScreen = TopOfScreen->BackLink;
- Repaint = TRUE;
- }
- }
-
- UpdateStatusBar (INPUT_ERROR, PreviousMenuOption->ThisTag->Flags, FALSE);
- break;
- }
- }
- }
- //
- // Check the previous menu entry to see if it was a zero-length advance. If it was,
- // don't worry about a redraw.
- //
- if ((MenuOption->Row - PreviousMenuOption->Skip - DataAndTimeLineNumberPad < TopRow) ||
- (PreviousMenuOption->Skip > MenuOption->Row)
- ) {
- do {
- if (TopOfScreen->BackLink == &Menu) {
- break;
- }
-
- Repaint = TRUE;
-
- //
- // 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 = CR (TopOfScreen->BackLink, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- TopOfScreen = TopOfScreen->BackLink;
- } while (SavedMenuOption->Skip == 0);
- //
- // If we encounter a Date/Time op-code set, rewind to the first op-code of the set.
- //
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- }
-
- UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->Flags, FALSE);
- } else {
- if (SubMenu) {
- SavedMenuOption = MenuOption;
- MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || MenuOption->ThisTag->GrayOut) {
- //
- // If we are at the end of the list and sitting on a text op, we need to more forward
- //
- ScreenOperation = UiDown;
- ControlFlag = CfScreenOperation;
- break;
- }
-
- MenuOption = SavedMenuOption;
- }
- }
- break;
-
- case CfUiPageUp:
- ControlFlag = CfCheckSelection;
-
- SavedListEntry = NewPos;
- Link = TopOfScreen;
- for (Index = BottomRow; Index >= TopRow + 1; Index -= MenuOption->Skip) {
- if (Link->BackLink == &Menu) {
- TopOfScreen = Link;
- Link = SavedListEntry;
- MenuOption = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- break;
- }
-
- NewLine = TRUE;
- Repaint = TRUE;
- Link = Link->BackLink;
- MenuOption = CR (Link, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- TopOfScreen = Link;
- SavedListEntry = Link;
- }
-
- 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 first page.
- //
- if (Repaint) {
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- }
- break;
-
- case CfUiPageDown:
- ControlFlag = CfCheckSelection;
-
- SavedListEntry = NewPos;
- Link = TopOfScreen;
- NewPos = TopOfScreen;
- for (Index = TopRow; Index <= BottomRow - 1; Index += MenuOption->Skip) {
- if (NewPos->ForwardLink == &Menu) {
- NewPos = SavedListEntry;
- MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- Link = TopOfScreen;
- NewLine = FALSE;
- Repaint = FALSE;
- break;
- }
-
- NewLine = TRUE;
- Repaint = TRUE;
- MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- NewPos = NewPos->ForwardLink;
- Link = NewPos;
- }
-
- TopOfScreen = 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.
- //
- if (Repaint) {
- AdjustDateAndTimePosition (TRUE, &TopOfScreen);
- AdjustDateAndTimePosition (TRUE, &NewPos);
- MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- }
- break;
-
- case CfUiDown:
- 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.
- //
- DataAndTimeLineNumberPad = AdjustDateAndTimePosition (FALSE, &NewPos);
-
- if (NewPos->ForwardLink != &Menu) {
- NewLine = TRUE;
- NewPos = NewPos->ForwardLink;
- NextMenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
-
- if (SubMenu) {
- //
- // If the next MenuOption contains a display-only op-code, skip to the next one
- // Also if the next MenuOption is date or time,
- //
- if (NextMenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || NextMenuOption->ThisTag->GrayOut) {
- //
- // This is ok as long as not at the end of the list
- //
- if (NewPos == &Menu) {
- //
- // If we are at the end of the list, then this list must end with a display only
- // piece of data, so do not allow the forward motion
- //
- UpdateStatusBar (INPUT_ERROR, NextMenuOption->ThisTag->Flags, FALSE);
- NewPos = NewPos->BackLink;
- ScreenOperation = UiUp;
- break;
- }
- }
- }
- //
- // An option might be multi-line, so we need to reflect that data in the overall skip value
- //
- UpdateOptionSkipLines (PageData, NextMenuOption, FileFormTagsHead, &OptionString, SkipValue);
-
- if (NextMenuOption->Skip > 1) {
- Temp = MenuOption->Row + MenuOption->Skip + NextMenuOption->Skip - 1;
- } else {
- Temp = MenuOption->Row + MenuOption->Skip + DataAndTimeLineNumberPad;
- }
- //
- // If we are going to scroll
- //
- 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 = CR (TopOfScreen, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
-
- //
- // If bottom op-code is more than one line or top op-code is more than one line
- //
- if ((NextMenuOption->Skip > 1) || (MenuOption->Skip > 1)) {
- //
- // Is the bottom op-code greater than or equal in size to the top op-code?
- //
- if ((Temp - BottomRow) >= (SavedMenuOption->Skip - OldSkipValue)) {
- //
- // Skip the top op-code
- //
- TopOfScreen = TopOfScreen->ForwardLink;
- Difference = (Temp - BottomRow) - (SavedMenuOption->Skip - OldSkipValue);
-
- OldSkipValue = Difference;
-
- SavedMenuOption = CR (TopOfScreen, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
-
- //
- // If we have a remainder, skip that many more op-codes until we drain the remainder
- //
- for (;
- Difference >= (INTN) SavedMenuOption->Skip;
- Difference = Difference - (INTN) SavedMenuOption->Skip
- ) {
- //
- // Since the Difference is greater than or equal to this op-code's skip value, skip it
- //
- TopOfScreen = TopOfScreen->ForwardLink;
- SavedMenuOption = CR (TopOfScreen, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- if (Difference < (INTN) SavedMenuOption->Skip) {
- Difference = SavedMenuOption->Skip - Difference - 1;
- break;
- } else {
- if (Difference == (INTN) SavedMenuOption->Skip) {
- TopOfScreen = TopOfScreen->ForwardLink;
- SavedMenuOption = CR (TopOfScreen, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- Difference = SavedMenuOption->Skip - Difference;
- break;
- }
- }
- }
- //
- // 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 = OldSkipValue + (Temp - BottomRow) - 1;
- }
- } else {
- if ((OldSkipValue + 1) == (INTN) SavedMenuOption->Skip) {
- TopOfScreen = TopOfScreen->ForwardLink;
- break;
- } else {
- SkipValue = OldSkipValue;
- }
- }
- //
- // 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 {
- SkipValue = 0;
- TopOfScreen = TopOfScreen->ForwardLink;
- }
- } while (SavedMenuOption->Skip == 0);
-
- Repaint = TRUE;
- OldSkipValue = SkipValue;
- }
-
- UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->Flags, FALSE);
-
- } else {
- if (SubMenu) {
- SavedMenuOption = MenuOption;
- MenuOption = CR (NewPos, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- if (MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || MenuOption->ThisTag->GrayOut) {
- //
- // If we are at the end of the list and sitting on a text op, we need to more forward
- //
- ScreenOperation = UiUp;
- ControlFlag = CfScreenOperation;
- break;
- }
-
- MenuOption = SavedMenuOption;
- //
- // If we are at the end of the list and sitting on a Date/Time op, rewind to the head.
- //
- AdjustDateAndTimePosition (TRUE, &NewPos);
- }
- }
- break;
-
- case CfUiSave:
- ControlFlag = CfCheckSelection;
- //
- // Check for tags that might have LATE_CHECK enabled. If they do, we can't switch pages or save NV data.
- //
- if (MenuOption != NULL) {
- if (!SelectionsAreValid (MenuOption, FileFormTagsHead)) {
- Selection = NULL;
- Repaint = TRUE;
- break;
- }
- }
- //
- // If callbacks are active, and the callback has a Write method, try to use it
- //
- if (FileFormTags->VariableDefinitions->VariableName == NULL) {
- if ((FormCallback != NULL) && (FormCallback->NvWrite != NULL)) {
- Status = FormCallback->NvWrite (
- FormCallback,
- (CHAR16 *) L"Setup",
- &FileFormTags->FormTags.Tags[0].GuidValue,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- VariableDefinition->VariableSize,
- (VOID *) VariableDefinition->NvRamMap,
- &gResetRequired
- );
-
- } else {
- Status = gRT->SetVariable (
- (CHAR16 *) L"Setup",
- &FileFormTags->FormTags.Tags[0].GuidValue,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- VariableDefinition->VariableSize,
- (VOID *) VariableDefinition->NvRamMap
- );
- }
- } else {
- VariableDefinition = FileFormTags->VariableDefinitions;
-
- for (; VariableDefinition != NULL; VariableDefinition = VariableDefinition->Next) {
- if ((FormCallback != NULL) && (FormCallback->NvWrite != NULL)) {
- Status = FormCallback->NvWrite (
- FormCallback,
- VariableDefinition->VariableName,
- &VariableDefinition->Guid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- VariableDefinition->VariableSize,
- (VOID *) VariableDefinition->NvRamMap,
- &gResetRequired
- );
-
- } else {
- Status = gRT->SetVariable (
- VariableDefinition->VariableName,
- &VariableDefinition->Guid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- VariableDefinition->VariableSize,
- (VOID *) VariableDefinition->NvRamMap
- );
- }
- }
- }
-
- UpdateStatusBar (INPUT_ERROR, MenuOption->ThisTag->Flags, FALSE);
- UpdateStatusBar (NV_UPDATE_REQUIRED, MenuOption->ThisTag->Flags, FALSE);
- break;
-
- case CfUiDefault:
- ControlFlag = CfCheckSelection;
-
- NvMapListHead = NULL;
-
- Status = Hii->GetDefaultImage (Hii, MenuOption->Handle, EFI_IFR_FLAG_DEFAULT, &NvMapListHead);
-
- if (!EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (NULL != NvMapListHead);
-
- NvMapListNode = NvMapListHead;
-
- while (NULL != NvMapListNode) {
- if (FileFormTags->VariableDefinitions->VariableId == NvMapListNode->VariablePack->VariableId) {
- NvMap = (VOID *) ((CHAR8 *) NvMapListNode->VariablePack + sizeof (EFI_HII_VARIABLE_PACK) + NvMapListNode->VariablePack->VariableNameLength);
- NvMapSize = NvMapListNode->VariablePack->Header.Length - sizeof (EFI_HII_VARIABLE_PACK) - NvMapListNode->VariablePack->VariableNameLength;
- break;
- }
- NvMapListNode = NvMapListNode->NextVariablePack;
- }
-
- //
- // Free the buffer that was allocated.
- //
- FreePool (FileFormTags->VariableDefinitions->NvRamMap);
- FreePool (FileFormTags->VariableDefinitions->FakeNvRamMap);
-
- //
- // Allocate, copy the NvRamMap.
- //
- FileFormTags->VariableDefinitions->VariableFakeSize = (UINT16) (FileFormTags->VariableDefinitions->VariableFakeSize - FileFormTags->VariableDefinitions->VariableSize);
- FileFormTags->VariableDefinitions->VariableSize = (UINT16) NvMapSize;
- FileFormTags->VariableDefinitions->VariableFakeSize = (UINT16) (FileFormTags->VariableDefinitions->VariableFakeSize + FileFormTags->VariableDefinitions->VariableSize);
-
- FileFormTags->VariableDefinitions->NvRamMap = AllocateZeroPool (FileFormTags->VariableDefinitions->VariableSize);
- ASSERT (FileFormTags->VariableDefinitions->NvRamMap != NULL);
-
- FileFormTags->VariableDefinitions->FakeNvRamMap = AllocateZeroPool (NvMapSize + FileFormTags->VariableDefinitions->VariableFakeSize);
- ASSERT (FileFormTags->VariableDefinitions->FakeNvRamMap != NULL);
-
- CopyMem (FileFormTags->VariableDefinitions->NvRamMap, NvMap, NvMapSize);
- FreePool (NvMapListHead);
- }
-
- UpdateStatusBar (NV_UPDATE_REQUIRED, MenuOption->ThisTag->Flags, TRUE);
- Repaint = TRUE;
- //
- // After the repaint operation, we should refresh the highlight.
- //
- NewLine = TRUE;
- break;
-
- case CfUiNoOperation:
- ControlFlag = CfCheckSelection;
- break;
-
- case CfExit:
- while (gMenuRefreshHead != NULL) {
- OldMenuRefreshEntry = gMenuRefreshHead->Next;
-
- FreePool (gMenuRefreshHead);
-
- gMenuRefreshHead = OldMenuRefreshEntry;
- }
-
- gST->ConOut->SetCursorPosition (gST->ConOut, 0, Row + 4);
- gST->ConOut->EnableCursor (gST->ConOut, TRUE);
- gST->ConOut->OutputString (gST->ConOut, (CHAR16 *) L"\n");
-
- gActiveIfr = MenuOption->IfrNumber;
- return Selection;
-
- default:
- break;
- }
- }
-}
-
-BOOLEAN
-ValueIsScroll (
- IN BOOLEAN Direction,
- IN LIST_ENTRY *CurrentPos
- )
-/*++
-
-Routine Description:
- Determine if the menu is the last menu that can be selected.
-
-Arguments:
- Direction - the scroll direction. False is down. True is up.
-
-Returns:
- FALSE -- the menu isn't the last menu that can be selected.
- TRUE -- the menu is the last menu that can be selected.
---*/
-{
- LIST_ENTRY *Temp;
- UI_MENU_OPTION *MenuOption;
- MenuOption = NULL;
-
- Temp = Direction ? CurrentPos->BackLink : CurrentPos->ForwardLink;
-
- if (Temp == &Menu) {
- return TRUE;
- }
-
- for (; Temp != &Menu; Temp = Direction ? Temp->BackLink : Temp->ForwardLink) {
- MenuOption = CR (Temp, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- if (!(MenuOption->ThisTag->Operand == EFI_IFR_SUBTITLE_OP || MenuOption->ThisTag->GrayOut)) {
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-UINTN
-AdjustDateAndTimePosition (
- IN BOOLEAN DirectionUp,
- IN LIST_ENTRY **CurrentPosition
- )
-/*++
-Routine Description:
- Adjust Data and Time tag position accordingly.
- Data format : [01/02/2004] [11:22:33]
- Line number : 0 0 1 0 0 1
-
-Arguments:
- Direction - the up or down direction. False is down. True is up.
- CurrentPos - Current position.
-
-Returns:
- Return line number to pad. It is possible that we stand on a zero-advance
- data or time opcode, so pad one line when we judge if we are going to scroll outside.
---*/
-{
- UINTN Count;
- LIST_ENTRY *NewPosition;
- UI_MENU_OPTION *MenuOption;
- UINTN PadLineNumber;
-
- PadLineNumber = 0;
- NewPosition = *CurrentPosition;
- MenuOption = CR (NewPosition, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
-
- 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 op-code.
- //
- Count = 0;
- while (MenuOption->ThisTag->NumberOfLines == 0) {
- Count++;
- NewPosition = NewPosition->ForwardLink;
- MenuOption = CR (NewPosition, UI_MENU_OPTION, Link, UI_MENU_OPTION_SIGNATURE);
- PadLineNumber = 1;
- }
-
- NewPosition = *CurrentPosition;
- if (DirectionUp) {
- //
- // Since the behavior of hitting the up arrow on a Date/Time op-code is intended
- // to be one that back to the previous set of op-codes, we need to advance to the first
- // Date/Time op-code 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 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 CfUiDown intact so the appropriate
- // checking can be done.
- //
- while (Count-- > 0) {
- NewPosition = NewPosition->ForwardLink;
- }
- }
-
- *CurrentPosition = NewPosition;
- }
-
- return PadLineNumber;
-}