X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=EdkModulePkg%2FUniversal%2FUserInterface%2FSetupBrowser%2FDxe%2FInputHandler.c;fp=EdkModulePkg%2FUniversal%2FUserInterface%2FSetupBrowser%2FDxe%2FInputHandler.c;h=0000000000000000000000000000000000000000;hp=85e1a0cf984fc5b16b760fafd05182d35930c57d;hb=808def96aa4589fba9c2d0ea55837754a3b7a4f7;hpb=9216450d1143056a50a5f916984a2d7faf590488 diff --git a/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/InputHandler.c b/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/InputHandler.c deleted file mode 100644 index 85e1a0cf98..0000000000 --- a/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/InputHandler.c +++ /dev/null @@ -1,1570 +0,0 @@ -/*++ - -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. - -Module Name: - - InputHandler.C - -Abstract: - - Implementation for handling user input from the User Interface - -Revision History - ---*/ - -#include "Setup.h" -#include "Ui.h" -#include "Colors.h" - -#define EFI_MAX(_a, _b) ((_a) > (_b) ? (_a) : (_b)) - -EFI_STATUS -ReadString( - IN UI_MENU_OPTION *MenuOption, - OUT CHAR16 *StringPtr - ) -{ - EFI_STATUS Status; - EFI_INPUT_KEY Key; - CHAR16 NullCharacter; - UINTN ScreenSize; - EFI_TAG *Tag; - CHAR16 Space[2]; - CHAR16 KeyPad[2]; - BOOLEAN SelectionComplete; - CHAR16 *TempString; - CHAR16 *BufferedString; - UINTN Index; - UINTN Count; - UINTN Start; - UINTN Top; - CHAR16 *PromptForDataString; - UINTN DimensionsWidth; - UINTN DimensionsHeight; - BOOLEAN CursorVisible; - - DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn; - DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow; - - PromptForDataString = GetToken (STRING_TOKEN (PROMPT_FOR_DATA), gHiiHandle); - - NullCharacter = CHAR_NULL; - ScreenSize = GetStringWidth (PromptForDataString) / 2; - Tag = MenuOption->ThisTag; - Space[0] = L' '; - Space[1] = CHAR_NULL; - SelectionComplete = FALSE; - - TempString = AllocateZeroPool (MenuOption->ThisTag->Maximum * 2); - ASSERT (TempString); - - if (ScreenSize < (Tag->Maximum / (UINTN) 2)) { - ScreenSize = Tag->Maximum / 2; - } - - if ((ScreenSize + 2) > DimensionsWidth) { - ScreenSize = DimensionsWidth - 2; - } - - BufferedString = AllocateZeroPool (ScreenSize * 2); - ASSERT (BufferedString); - - Start = (DimensionsWidth - ScreenSize - 2) / 2 + gScreenDimensions.LeftColumn + 1; - Top = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1; - - // - // Display prompt for string - // - CreatePopUp (ScreenSize, 4, &NullCharacter, PromptForDataString, Space, &NullCharacter); - - FreePool (PromptForDataString); - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); - - CursorVisible = gST->ConOut->Mode->CursorVisible; - gST->ConOut->EnableCursor (gST->ConOut, TRUE); - - do { - Status = WaitForKeyStroke (&Key); - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); - switch (Key.UnicodeChar) { - case CHAR_NULL: - switch (Key.ScanCode) { - case SCAN_LEFT: - break; - - case SCAN_RIGHT: - break; - - case SCAN_ESC: - FreePool (TempString); - FreePool (BufferedString); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); - return EFI_DEVICE_ERROR; - - default: - break; - } - - break; - - case CHAR_CARRIAGE_RETURN: - if (GetStringWidth (StringPtr) >= MenuOption->ThisTag->Minimum) { - SelectionComplete = TRUE; - FreePool (TempString); - FreePool (BufferedString); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); - return EFI_SUCCESS; - } else { - ScreenSize = GetStringWidth (gMiniString) / 2; - CreatePopUp (ScreenSize, 4, &NullCharacter, gMiniString, gPressEnter, &NullCharacter); - // - // Simply create a popup to tell the user that they had typed in too few characters. - // To save code space, we can then treat this as an error and return back to the menu. - // - do { - Status = WaitForKeyStroke (&Key); - } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - FreePool (TempString); - FreePool (BufferedString); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); - return EFI_DEVICE_ERROR; - } - - break; - - case CHAR_BACKSPACE: - if (StringPtr[0] != CHAR_NULL) { - for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) { - TempString[Index] = StringPtr[Index]; - } - // - // Effectively truncate string by 1 character - // - TempString[Index - 1] = CHAR_NULL; - StrCpy (StringPtr, TempString); - } - - default: - // - // If it is the beginning of the string, don't worry about checking maximum limits - // - if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) { - StrnCpy (StringPtr, &Key.UnicodeChar, 1); - StrnCpy (TempString, &Key.UnicodeChar, 1); - } else if ((GetStringWidth (StringPtr) < MenuOption->ThisTag->Maximum) && (Key.UnicodeChar != CHAR_BACKSPACE)) { - KeyPad[0] = Key.UnicodeChar; - KeyPad[1] = CHAR_NULL; - StrCat (StringPtr, 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, ScreenSize - 1, L' '); - - PrintStringAt (Start + 1, Top + 3, BufferedString); - - if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { - Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; - } else { - Index = 0; - } - - for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { - BufferedString[Count] = StringPtr[Index]; - } - - PrintStringAt (Start + 1, Top + 3, BufferedString); - break; - } - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3); - } while (!SelectionComplete); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); - return Status; -} - -EFI_STATUS -ReadPassword ( - IN UI_MENU_OPTION *MenuOption, - IN BOOLEAN PromptForPassword, - IN EFI_TAG *Tag, - IN EFI_IFR_DATA_ARRAY *PageData, - IN BOOLEAN SecondEntry, - IN EFI_FILE_FORM_TAGS *FileFormTags, - OUT CHAR16 *StringPtr - ) -{ - EFI_STATUS Status; - UINTN ScreenSize; - CHAR16 NullCharacter; - CHAR16 Space[2]; - EFI_INPUT_KEY Key; - CHAR16 KeyPad[2]; - UINTN Index; - UINTN Start; - UINTN Top; - CHAR16 *TempString; - CHAR16 *TempString2; - BOOLEAN Confirmation; - BOOLEAN ConfirmationComplete; - EFI_HII_CALLBACK_PACKET *Packet; - EFI_FORM_CALLBACK_PROTOCOL *FormCallback; - EFI_VARIABLE_DEFINITION *VariableDefinition; - UINTN DimensionsWidth; - UINTN DimensionsHeight; - EFI_IFR_DATA_ENTRY *DataEntry; - UINTN WidthOfString; - - DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn; - DimensionsHeight = gScreenDimensions.BottomRow - gScreenDimensions.TopRow; - - VariableDefinition = NULL; - NullCharacter = CHAR_NULL; - Space[0] = L' '; - Space[1] = CHAR_NULL; - Confirmation = FALSE; - ConfirmationComplete = FALSE; - Status = EFI_SUCCESS; - FormCallback = NULL; - Packet = NULL; - - // - // Remember that dynamic pages in an environment where all pages are not - // dynamic require us to call back to the user to give them an opportunity - // to register fresh information in the HII database so that we can extract it. - // - Status = gBS->HandleProtocol ( - (VOID *) (UINTN) MenuOption->Tags[0].CallbackHandle, - &gEfiFormCallbackProtocolGuid, - (VOID **) &FormCallback - ); - - TempString = AllocateZeroPool (MenuOption->ThisTag->Maximum * 2); - TempString2 = AllocateZeroPool (MenuOption->ThisTag->Maximum * 2); - - ASSERT (TempString); - ASSERT (TempString2); - - if (Tag->Flags & EFI_IFR_FLAG_INTERACTIVE) { - // - // Password requires a callback to determine if a password exists - // - DataEntry = (EFI_IFR_DATA_ENTRY *) (PageData + 1); - DataEntry->OpCode = EFI_IFR_PASSWORD_OP; - DataEntry->Length = 3; - - ExtractRequestedNvMap (FileFormTags, Tag->VariableNumber, &VariableDefinition); - - // - // The user is about to be prompted with a password field, Data = 0 (Return Status determines the type of prompt) - // - DataEntry->Data = (VOID *) (UINTN) (UINT8) (0 + SecondEntry * 2); - PageData->NvRamMap = VariableDefinition->NvRamMap; - - if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) { - Status = FormCallback->Callback ( - FormCallback, - Tag->Key, - PageData, - &Packet - ); - } - // - // If error on return, continue with the reading of a typed in password to verify user knows password - // If no error, there is no password set, so prompt for new password - // if the previous callback was to verify the user knew password, and user typed it correctly - should return no error - // - if (!EFI_ERROR (Status)) { - PromptForPassword = FALSE; - - // - // Simulate this as the second entry into this routine for an interactive behavior - // - SecondEntry = TRUE; - } else if (Status == EFI_NOT_READY) { -Error: - if (Packet != NULL) { - // - // Upon error, we will likely receive a string to print out - // Display error popup - // - WidthOfString = GetStringWidth (Packet->String); - ScreenSize = EFI_MAX(WidthOfString, GetStringWidth (gPressEnter)) / 2; - CreatePopUp (ScreenSize, 4, &NullCharacter, Packet->String, gPressEnter, &NullCharacter); - FreePool (Packet); - - do { - Status = WaitForKeyStroke (&Key); - } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - } - - Status = EFI_NOT_READY; - goto Done; - } - } - - do { - // - // Display PopUp Screen - // - ScreenSize = GetStringWidth (gPromptForNewPassword) / 2; - if (GetStringWidth (gConfirmPassword) / 2 > ScreenSize) { - ScreenSize = GetStringWidth (gConfirmPassword) / 2; - } - - Start = (DimensionsWidth - ScreenSize - 4) / 2 + gScreenDimensions.LeftColumn + 2; - Top = ((DimensionsHeight - 6) / 2) + gScreenDimensions.TopRow - 1; - - if (!Confirmation) { - if (PromptForPassword) { - CreatePopUp (ScreenSize, 4, &NullCharacter, gPromptForPassword, Space, &NullCharacter); - } else { - CreatePopUp (ScreenSize, 4, &NullCharacter, gPromptForNewPassword, Space, &NullCharacter); - } - } else { - CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmPassword, Space, &NullCharacter); - StringPtr[0] = CHAR_NULL; - } - - do { - Status = WaitForKeyStroke (&Key); - - switch (Key.UnicodeChar) { - case CHAR_NULL: - if (Key.ScanCode == SCAN_ESC) { - return EFI_NOT_READY; - } - - ConfirmationComplete = FALSE; - break; - - case CHAR_CARRIAGE_RETURN: - if (Tag->Flags & EFI_IFR_FLAG_INTERACTIVE) { - // - // User just typed a string in - // - DataEntry = (EFI_IFR_DATA_ENTRY *) (PageData + 1); - DataEntry->OpCode = EFI_IFR_PASSWORD_OP; - - // - // If the user just typed in a password, Data = 1 - // If the user just typed in a password to confirm the previous password, Data = 2 - // - if (!Confirmation) { - DataEntry->Length = 3; - DataEntry->Data = (VOID *) (UINTN) (UINT8) (1 + SecondEntry * 2); - - if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) { - Status = FormCallback->Callback ( - FormCallback, - Tag->Key, - PageData, - &Packet - ); - } - - DataEntry->Length = sizeof (EFI_IFR_DATA_ENTRY); - DataEntry->Data = (VOID *) TempString; - } else { - DataEntry->Length = 3; - DataEntry->Data = (VOID *) (UINTN) (UINT8) (2 + SecondEntry * 2); - - if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) { - Status = FormCallback->Callback ( - FormCallback, - Tag->Key, - PageData, - &Packet - ); - } - - DataEntry->Length = sizeof (EFI_IFR_DATA_ENTRY); - DataEntry->Data = (VOID *) TempString2; - } - - if ((FormCallback != NULL) && (FormCallback->Callback != NULL)) { - Status = FormCallback->Callback ( - FormCallback, - Tag->Key, - PageData, - &Packet - ); - } - // - // If this was the confirmation round of callbacks - // and an error comes back, display an error - // - if (Confirmation) { - if (EFI_ERROR (Status)) { - if (Packet->String == NULL) { - WidthOfString = GetStringWidth (gConfirmError); - ScreenSize = EFI_MAX (WidthOfString, GetStringWidth (gPressEnter)) / 2; - CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmError, gPressEnter, &NullCharacter); - } else { - WidthOfString = GetStringWidth (Packet->String); - ScreenSize = EFI_MAX (WidthOfString, GetStringWidth (gPressEnter)) / 2; - CreatePopUp (ScreenSize, 4, &NullCharacter, Packet->String, gPressEnter, &NullCharacter); - FreePool (Packet); - } - - StringPtr[0] = CHAR_NULL; - do { - Status = WaitForKeyStroke (&Key); - - if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { - Status = EFI_NOT_READY; - goto Done; - } - } while (1); - } else { - Status = EFI_NOT_READY; - goto Done; - } - } else { - // - // User typed a string in and it wasn't valid somehow from the callback - // For instance, callback may have said that some invalid characters were contained in the string - // - if (Status == EFI_NOT_READY) { - goto Error; - } - - if (PromptForPassword && EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; - goto Done; - } - } - } - - if (Confirmation) { - // - // Compare tempstring and tempstring2, if the same, return with StringPtr success - // Otherwise, kick and error box, and return an error - // - if (StrCmp (TempString, TempString2) == 0) { - Status = EFI_SUCCESS; - goto Done; - } else { - WidthOfString = GetStringWidth (gConfirmError); - ScreenSize = EFI_MAX (WidthOfString, GetStringWidth (gPressEnter)) / 2; - CreatePopUp (ScreenSize, 4, &NullCharacter, gConfirmError, gPressEnter, &NullCharacter); - StringPtr[0] = CHAR_NULL; - do { - Status = WaitForKeyStroke (&Key); - if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { - Status = EFI_DEVICE_ERROR; - goto Done; - } - } while (1); - } - } - - if (PromptForPassword) { - // - // I was asked for a password, return it back in StringPtr - // - Status = EFI_SUCCESS; - goto Done; - } else { - // - // If the two passwords were not the same kick an error popup - // - Confirmation = TRUE; - ConfirmationComplete = TRUE; - break; - } - - case CHAR_BACKSPACE: - if (StringPtr[0] != CHAR_NULL) { - if (!Confirmation) { - for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) { - TempString[Index] = StringPtr[Index]; - } - // - // Effectively truncate string by 1 character - // - TempString[Index - 1] = CHAR_NULL; - StrCpy (StringPtr, TempString); - } else { - for (Index = 0; StringPtr[Index] != CHAR_NULL; Index++) { - TempString2[Index] = StringPtr[Index]; - } - // - // Effectively truncate string by 1 character - // - TempString2[Index - 1] = CHAR_NULL; - StrCpy (StringPtr, TempString2); - } - - ConfirmationComplete = FALSE; - } else { - ConfirmationComplete = FALSE; - } - - // - // Must be a character we are interested in! - // - default: - if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) { - if (!Confirmation) { - StrnCpy (StringPtr, &Key.UnicodeChar, 1); - StrnCpy (TempString, &Key.UnicodeChar, 1); - } else { - StrnCpy (StringPtr, &Key.UnicodeChar, 1); - StrnCpy (TempString2, &Key.UnicodeChar, 1); - ConfirmationComplete = FALSE; - } - } else if ((GetStringWidth (StringPtr) / 2 <= (UINTN) (MenuOption->ThisTag->Maximum - 1) / 2) && - (Key.UnicodeChar != CHAR_BACKSPACE) - ) { - KeyPad[0] = Key.UnicodeChar; - KeyPad[1] = CHAR_NULL; - if (!Confirmation) { - StrCat (StringPtr, KeyPad); - StrCat (TempString, KeyPad); - } else { - StrCat (StringPtr, KeyPad); - StrCat (TempString2, KeyPad); - } - } - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); - for (Index = 1; Index < ScreenSize; Index++) { - PrintCharAt (Start + Index, Top + 3, L' '); - } - - gST->ConOut->SetCursorPosition ( - gST->ConOut, - (DimensionsWidth - GetStringWidth (StringPtr) / 2) / 2 + gScreenDimensions.LeftColumn, - Top + 3 - ); - for (Index = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++) { - PrintChar (L'*'); - } - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - break; - } - // - // end switch - // - } while (!ConfirmationComplete); - - } while (1); - -Done: - FreePool (TempString); - FreePool (TempString2); - return Status; -} - -VOID -EncodePassword ( - IN CHAR16 *Password, - IN UINT8 MaxSize - ) -{ - UINTN Index; - UINTN Loop; - CHAR16 *Buffer; - CHAR16 *Key; - - Key = (CHAR16 *) L"MAR10648567"; - Buffer = AllocateZeroPool (MaxSize); - - ASSERT (Buffer); - - for (Index = 0; Key[Index] != 0; Index++) { - for (Loop = 0; Loop < (UINT8) (MaxSize / 2); Loop++) { - Buffer[Loop] = (CHAR16) (Password[Loop] ^ Key[Index]); - } - } - - CopyMem (Password, Buffer, MaxSize); - - FreePool (Buffer); - return ; -} - -EFI_STATUS -GetNumericInput ( - IN UI_MENU_OPTION *MenuOption, - IN EFI_FILE_FORM_TAGS *FileFormTagsHead, - IN BOOLEAN ManualInput, - IN EFI_TAG *Tag, - IN UINTN NumericType, - OUT UINT16 *Value - ) -/*++ - -Routine Description: - - This routine reads a numeric value from the user input. - -Arguments: - - MenuOption - Pointer to the current input menu. - - FileFormTagsHead - Pointer to the root of formset. - - ManualInput - If the input is manual or not. - - Tag - Pointer to all the attributes and values associated with a tag. - - Value - Pointer to the numeric value that is going to be read. - -Returns: - - EFI_SUCCESS - If numerical input is read successfully - EFI_DEVICE_ERROR - If operation fails - ---*/ -{ - EFI_INPUT_KEY Key; - BOOLEAN SelectionComplete; - UINTN Column; - UINTN Row; - CHAR16 FormattedNumber[6]; - UINTN PreviousNumber[6]; - INTN Number; - UINTN Count; - UINT16 BackupValue; - STRING_REF PopUp; - CHAR16 NullCharacter; - CHAR16 *StringPtr; - EFI_FILE_FORM_TAGS *FileFormTags; - EFI_VARIABLE_DEFINITION *VariableDefinition; - UINTN Loop; - - NullCharacter = CHAR_NULL; - StringPtr = NULL; - Column = MenuOption->OptCol; - Row = MenuOption->Row; - Number = 0; - PreviousNumber[0] = 0; - Count = 0; - SelectionComplete = FALSE; - BackupValue = Tag->Value; - FileFormTags = FileFormTagsHead; - - if (ManualInput) { - PrintAt (Column, Row, (CHAR16 *) L"[ ]"); - Column++; - if (Tag->Operand != EFI_IFR_TIME_OP) { - *Value = BackupValue; - } - } - // - // First time we enter this handler, we need to check to see if - // we were passed an increment or decrement directive - // - do { - Key.UnicodeChar = CHAR_NULL; - if (gDirection != 0) { - Key.ScanCode = gDirection; - gDirection = 0; - goto TheKey2; - } - - WaitForKeyStroke (&Key); - -TheKey2: - switch (Key.UnicodeChar) { - case '+': - case '-': - if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) { - Key.UnicodeChar = CHAR_NULL; - if (Key.UnicodeChar == '+') { - Key.ScanCode = SCAN_RIGHT; - } else { - Key.ScanCode = SCAN_LEFT; - } - - goto TheKey2; - } - break; - - case CHAR_NULL: - switch (Key.ScanCode) { - case SCAN_LEFT: - case SCAN_RIGHT: - if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) { - // - // By setting this value, we will return back to the caller. - // We need to do this since an auto-refresh will destroy the adjustment - // based on what the real-time-clock is showing. So we always commit - // upon changing the value. - // - gDirection = SCAN_DOWN; - } - - if (!ManualInput) { - Tag->Value = *Value; - if (Key.ScanCode == SCAN_LEFT) { - Number = *Value - Tag->Step; - if (Number < Tag->Minimum) { - Number = Tag->Minimum; - } - } else if (Key.ScanCode == SCAN_RIGHT) { - Number = *Value + Tag->Step; - if (Number > Tag->Maximum) { - Number = Tag->Maximum; - } - } - - Tag->Value = (UINT16) Number; - *Value = (UINT16) Number; - UnicodeValueToString ( - FormattedNumber, - FALSE, - (UINTN) Number, - (sizeof (FormattedNumber) / sizeof (FormattedNumber[0])) - ); - Number = (UINT16) GetStringWidth (FormattedNumber); - - gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT | FIELD_BACKGROUND); - if ((Tag->Operand == EFI_IFR_DATE_OP) || (Tag->Operand == EFI_IFR_TIME_OP)) { - for (Loop = 0; Loop < (UINTN) ((Number >= 8) ? 4 : 2); Loop++) { - PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, (CHAR16 *) L" "); - } - } else { - for (Loop = 0; Loop < gOptionBlockWidth; Loop++) { - PrintAt (MenuOption->OptCol + Loop, MenuOption->Row, (CHAR16 *) L" "); - } - } - - gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_HIGHLIGHT | FIELD_BACKGROUND_HIGHLIGHT); - - if ((MenuOption->Col + gPromptBlockWidth + 1) == MenuOption->OptCol) { - PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER); - Column = MenuOption->OptCol + 1; - } - // - // If Number looks like "3", convert it to "03/" - // - if (Number == 4 && (NumericType == DATE_NUMERIC)) { - FormattedNumber[3] = FormattedNumber[1]; - FormattedNumber[2] = DATE_SEPARATOR; - FormattedNumber[1] = FormattedNumber[0]; - FormattedNumber[0] = L'0'; - Number = 8; - } - // - // If Number looks like "13", convert it to "13/" - // - if (Number == 6 && (NumericType == DATE_NUMERIC)) { - FormattedNumber[3] = FormattedNumber[2]; - FormattedNumber[2] = DATE_SEPARATOR; - Number = 8; - } - - if (Number == 4 && - (NumericType == TIME_NUMERIC) && - (MenuOption->Col + gPromptBlockWidth + 8) != MenuOption->OptCol - ) { - FormattedNumber[3] = FormattedNumber[1]; - FormattedNumber[2] = TIME_SEPARATOR; - FormattedNumber[1] = FormattedNumber[0]; - FormattedNumber[0] = L'0'; - Number = 8; - } - - if (Number == 4 && - (NumericType == TIME_NUMERIC) && - (MenuOption->Col + gPromptBlockWidth + 8) == MenuOption->OptCol - ) { - FormattedNumber[3] = FormattedNumber[1]; - FormattedNumber[2] = RIGHT_NUMERIC_DELIMITER; - FormattedNumber[1] = FormattedNumber[0]; - FormattedNumber[0] = L'0'; - Number = 8; - } - - PrintStringAt (Column, Row, FormattedNumber); - if (Number == 10 && (NumericType == DATE_NUMERIC)) { - PrintChar (RIGHT_NUMERIC_DELIMITER); - } - - if (NumericType == REGULAR_NUMERIC) { - PrintChar (RIGHT_NUMERIC_DELIMITER); - } - } - break; - - case SCAN_UP: - case SCAN_DOWN: - goto EnterCarriageReturn; - - case SCAN_ESC: - return EFI_DEVICE_ERROR; - - default: - break; - } - - break; - -EnterCarriageReturn: - - case CHAR_CARRIAGE_RETURN: - // - // Check to see if the Value is something reasonable against consistency limitations. - // If not, let's kick the error specified. - // - // - // This gives us visibility to the FileFormTags->NvRamMap to check things - // ActiveIfr is a global maintained by the menuing code to ensure that we - // are pointing to the correct formset's file data. - // - for (Count = 0; Count < gActiveIfr; Count++) { - FileFormTags = FileFormTags->NextFile; - } - - ExtractRequestedNvMap (FileFormTags, Tag->VariableNumber, &VariableDefinition); - - CopyMem (&VariableDefinition->NvRamMap[Tag->StorageStart], &Tag->Value, Tag->StorageWidth); - - // - // Data associated with a NULL device (in the fake NV storage) - // - if (Tag->StorageWidth == (UINT16) 0) { - CopyMem (&VariableDefinition->FakeNvRamMap[Tag->StorageStart], &Tag->Value, 2); - } - // - // If a late check is required save off the information. This is used when consistency checks - // are required, but certain values might be bound by an impossible consistency check such as - // if two questions are bound by consistency checks and each only has two possible choices, there - // would be no way for a user to switch the values. Thus we require late checking. - // - if (Tag->Flags & EFI_IFR_FLAG_LATE_CHECK) { - CopyMem (&Tag->OldValue, &BackupValue, Tag->StorageWidth); - } else { - // - // In theory, passing the value and the Id are sufficient to determine what needs - // to be done. The Id is the key to look for the entry needed in the Inconsistency - // database. That will yields operand and ID data - and since the ID's correspond - // to the NV storage, we can determine the values for other IDs there. - // - if (ValueIsNotValid (TRUE, 0, Tag, FileFormTags, &PopUp)) { - if (PopUp == 0x0000) { - SelectionComplete = TRUE; - break; - } - - StringPtr = GetToken (PopUp, MenuOption->Handle); - - CreatePopUp (GetStringWidth (StringPtr) / 2, 3, &NullCharacter, StringPtr, &NullCharacter); - - do { - WaitForKeyStroke (&Key); - - switch (Key.UnicodeChar) { - - case CHAR_CARRIAGE_RETURN: - SelectionComplete = TRUE; - FreePool (StringPtr); - break; - - default: - break; - } - } while (!SelectionComplete); - - Tag->Value = BackupValue; - *Value = BackupValue; - - CopyMem (&VariableDefinition->NvRamMap[Tag->StorageStart], &Tag->Value, Tag->StorageWidth); - - // - // Data associated with a NULL device (in the fake NV storage) - // - if (Tag->StorageWidth == (UINT16) 0) { - CopyMem (&VariableDefinition->FakeNvRamMap[Tag->StorageStart], &Tag->Value, 2); - } - - return EFI_DEVICE_ERROR; - } - } - - return EFI_SUCCESS; - break; - - case CHAR_BACKSPACE: - if (ManualInput) { - if (Count == 0) { - break; - } - // - // Remove a character - // - Number = PreviousNumber[Count - 1]; - *Value = (UINT16) Number; - UpdateStatusBar (INPUT_ERROR, Tag->Flags, FALSE); - Count--; - Column--; - PrintAt (Column, Row, (CHAR16 *) L" "); - } - break; - - default: - if (ManualInput) { - if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') { - UpdateStatusBar (INPUT_ERROR, Tag->Flags, TRUE); - break; - } - // - // If Count 0-4 is complete, there is no way more is valid - // - if (Count > 4) { - break; - } - // - // Someone typed something valid! - // - if (Count != 0) { - Number = Number * 10 + (Key.UnicodeChar - L'0'); - } else { - Number = Key.UnicodeChar - L'0'; - } - - if (Number > Tag->Maximum) { - UpdateStatusBar (INPUT_ERROR, Tag->Flags, TRUE); - Number = PreviousNumber[Count]; - break; - } else { - UpdateStatusBar (INPUT_ERROR, Tag->Flags, FALSE); - } - - Count++; - - PreviousNumber[Count] = Number; - *Value = (UINT16) Number; - Tag->Value = (UINT16) Number; - - PrintCharAt (Column, Row, Key.UnicodeChar); - Column++; - } - break; - } - } while (!SelectionComplete); - return EFI_SUCCESS; -} -// -// Notice that this is at least needed for the ordered list manipulation. -// Left/Right doesn't make sense for this op-code -// -EFI_STATUS -GetSelectionInputPopUp ( - IN UI_MENU_OPTION *MenuOption, - IN EFI_TAG *Tag, - IN UINTN ValueCount, - OUT UINT16 *Value, - OUT UINT16 *KeyValue - ) -{ - EFI_INPUT_KEY Key; - UINTN Index; - UINTN TempIndex; - CHAR16 *StringPtr; - CHAR16 *TempStringPtr; - UINT16 Token; - UINTN Index2; - UINTN TopOptionIndex; - UINTN HighlightPosition; - UINTN Start; - UINTN End; - UINTN Top; - UINTN Bottom; - UINT16 TempValue; - UINTN Count; - UINTN PopUpMenuLines; - UINTN MenuLinesInView; - UINTN PopUpWidth; - CHAR16 Character; - BOOLEAN FirstOptionFoundFlag; - INT32 SavedAttribute; - EFI_TAG TagBackup; - UINT8 *ValueArray; - UINT8 *ValueArrayBackup; - UINT8 ValueBackup; - BOOLEAN Initialized; - BOOLEAN KeyInitialized; - BOOLEAN ShowDownArrow; - BOOLEAN ShowUpArrow; - UINTN DimensionsWidth; - - DimensionsWidth = gScreenDimensions.RightColumn - gScreenDimensions.LeftColumn; - - TempValue = 0; - TempIndex = 0; - ValueArray = (UINT8 *) Value; - ValueArrayBackup = NULL; - Initialized = FALSE; - KeyInitialized = FALSE; - ShowDownArrow = FALSE; - ShowUpArrow = FALSE; - - if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) { - ValueArrayBackup = AllocateZeroPool (Tag->StorageWidth); - ASSERT (ValueArrayBackup != NULL); - CopyMem (ValueArrayBackup, ValueArray, ValueCount); - TempValue = *(UINT8 *) (ValueArray); - if (ValueArray[0] != 0x00) { - Initialized = TRUE; - } - - for (Index = 0; ValueArray[Index] != 0x00; Index++) - ; - ValueCount = Index; - } else { - TempValue = *Value; - } - - Count = 0; - PopUpWidth = 0; - - FirstOptionFoundFlag = FALSE; - - StringPtr = AllocateZeroPool ((gOptionBlockWidth + 1) * 2); - ASSERT (StringPtr); - - // - // Initialization for "One of" pop-up menu - // - // - // Get the number of one of options present and its size - // - for (Index = MenuOption->TagIndex; MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP; Index++) { - if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP && - !MenuOption->Tags[Index].Suppress) { - if (!FirstOptionFoundFlag) { - FirstOptionFoundFlag = TRUE; - } - - Count++; - Token = MenuOption->Tags[Index].Text; - - // - // If this is an ordered list that is initialized - // - if (Initialized) { - for (ValueBackup = (UINT8) MenuOption->TagIndex; - MenuOption->Tags[ValueBackup].Operand != EFI_IFR_END_OP; - ValueBackup++ - ) { - if (MenuOption->Tags[ValueBackup].Value == ((UINT8 *) ValueArrayBackup)[Index - MenuOption->TagIndex - 1]) { - StringPtr = GetToken (MenuOption->Tags[ValueBackup].Text, MenuOption->Handle); - break; - } - } - } else { - StringPtr = GetToken (Token, MenuOption->Handle); - } - - if (StrLen (StringPtr) > PopUpWidth) { - PopUpWidth = StrLen (StringPtr); - } - - FreePool (StringPtr); - } - } - // - // Perform popup menu initialization. - // - PopUpMenuLines = Count; - PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT; - - SavedAttribute = gST->ConOut->Mode->Attribute; - gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND); - - if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) { - PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH; - } - - Start = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gScreenDimensions.LeftColumn; - End = Start + PopUpWidth + POPUP_FRAME_WIDTH; - Top = gScreenDimensions.TopRow + NONE_FRONT_PAGE_HEADER_HEIGHT; - Bottom = gScreenDimensions.BottomRow - STATUS_BAR_HEIGHT - FOOTER_HEIGHT; - - MenuLinesInView = Bottom - Top - 1; - if (MenuLinesInView >= PopUpMenuLines) { - Top = Top + (MenuLinesInView - PopUpMenuLines) / 2; - Bottom = Top + PopUpMenuLines + 1; - } else { - TempValue = MenuOption->Tags[MenuOption->TagIndex + 1].Value; - ShowDownArrow = TRUE; - } - - TopOptionIndex = 1; - HighlightPosition = 0; - do { - if (Initialized) { - for (Index = MenuOption->TagIndex, Index2 = 0; Index2 < ValueCount; Index++, Index2++) { - // - // Set the value for the item we are looking for - // - Count = ValueArrayBackup[Index2]; - - // - // If we hit the end of the Array, we are complete - // - if (Count == 0) { - break; - } - - if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) { - for (ValueBackup = (UINT8) MenuOption->TagIndex; - MenuOption->Tags[ValueBackup].Operand != EFI_IFR_END_ONE_OF_OP; - ValueBackup++ - ) { - // - // We just found what we are looking for - // - if (MenuOption->Tags[ValueBackup].Value == Count) { - // - // As long as the two indexes aren't the same, we have - // two different op-codes we need to swap internally - // - if (Index != ValueBackup) { - // - // Backup destination tag, then copy source to destination, then copy backup to source location - // - CopyMem (&TagBackup, &MenuOption->Tags[Index], sizeof (EFI_TAG)); - CopyMem (&MenuOption->Tags[Index], &MenuOption->Tags[ValueBackup], sizeof (EFI_TAG)); - CopyMem (&MenuOption->Tags[ValueBackup], &TagBackup, sizeof (EFI_TAG)); - } else { - // - // If the indexes are the same, then the op-code is where he belongs - // - } - } - } - } else { - // - // Since this wasn't an option op-code (likely the ordered list op-code) decerement Index2 - // - Index2--; - } - } - } - // - // Clear that portion of the screen - // - ClearLines (Start, End, Top, Bottom, POPUP_TEXT | POPUP_BACKGROUND); - - // - // Draw "One of" pop-up menu - // - Character = (CHAR16) BOXDRAW_DOWN_RIGHT; - PrintCharAt (Start, Top, Character); - for (Index = Start; Index + 2 < End; Index++) { - if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) { - Character = (CHAR16) GEOMETRICSHAPE_UP_TRIANGLE; - } else { - Character = (CHAR16) BOXDRAW_HORIZONTAL; - } - - PrintChar (Character); - } - - Character = (CHAR16) BOXDRAW_DOWN_LEFT; - PrintChar (Character); - Character = (CHAR16) BOXDRAW_VERTICAL; - for (Index = Top + 1; Index < Bottom; Index++) { - PrintCharAt (Start, Index, Character); - PrintCharAt (End - 1, Index, Character); - } - // - // Display the One of options - // - Index2 = Top + 1; - for (Index = MenuOption->TagIndex + TopOptionIndex; - (MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP) && (Index2 < Bottom); - Index++ - ) { - if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) { - Token = MenuOption->Tags[Index].Text; - if (Initialized) { - for (ValueBackup = (UINT8) MenuOption->TagIndex; - MenuOption->Tags[ValueBackup].Operand != EFI_IFR_END_ONE_OF_OP; - ValueBackup++ - ) { - if (MenuOption->Tags[ValueBackup].Value == ((UINT8 *) ValueArrayBackup)[Index - MenuOption->TagIndex - 1]) { - StringPtr = GetToken (MenuOption->Tags[ValueBackup].Text, MenuOption->Handle); - break; - } - } - } else { - ValueBackup = (UINT8) Index; - StringPtr = GetToken (Token, MenuOption->Handle); - } - // - // If the string occupies multiple lines, truncate it to fit in one line, - // and append a "..." for indication. - // - if (StrLen (StringPtr) > (PopUpWidth - 1)) { - TempStringPtr = AllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1)); - ASSERT (TempStringPtr != NULL); - CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5))); - FreePool (StringPtr); - StringPtr = TempStringPtr; - StrCat (StringPtr, (CHAR16 *) L"..."); - } - // - // Code to display the text should go here. Follwed by the [*] - // - if (MenuOption->Tags[ValueBackup].Suppress == TRUE) { - // - // Don't show the one, so decrease the Index2 for balance - // - Index2--; - } else if (MenuOption->Tags[ValueBackup].GrayOut == TRUE) { - // - // Gray Out the one - // - gST->ConOut->SetAttribute (gST->ConOut, FIELD_TEXT_GRAYED | POPUP_BACKGROUND); - PrintStringAt (Start + 2, Index2, StringPtr); - gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND); - } else if (MenuOption->Tags[ValueBackup].Value == TempValue) { - // - // Highlight the selected one - // - gST->ConOut->SetAttribute (gST->ConOut, PICKLIST_HIGHLIGHT_TEXT | PICKLIST_HIGHLIGHT_BACKGROUND); - PrintStringAt (Start + 2, Index2, StringPtr); - gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND); - HighlightPosition = Index2; - } else { - gST->ConOut->SetAttribute (gST->ConOut, POPUP_TEXT | POPUP_BACKGROUND); - PrintStringAt (Start + 2, Index2, StringPtr); - } - - FreePool (StringPtr); - Index2 = Index2 + 1; - } - } - - Character = (CHAR16) BOXDRAW_UP_RIGHT; - PrintCharAt (Start, Bottom, Character); - for (Index = Start; Index + 2 < End; Index++) { - if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) { - Character = (CHAR16) GEOMETRICSHAPE_DOWN_TRIANGLE; - } else { - Character = (CHAR16) BOXDRAW_HORIZONTAL; - } - - PrintChar (Character); - } - - Character = (CHAR16) BOXDRAW_UP_LEFT; - PrintChar (Character); - // - // Get User selection and change TempValue if necessary - // - // - // Stop: One of pop-up menu - // - Key.UnicodeChar = CHAR_NULL; - if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) { - Key.ScanCode = gDirection; - gDirection = 0; - goto TheKey; - } - - if (!KeyInitialized) { - if (MenuOption->ThisTag->Operand == EFI_IFR_ONE_OF_OP) { - *KeyValue = MenuOption->Tags[MenuOption->TagIndex + 1].Key; - } else { - *KeyValue = MenuOption->ThisTag->Key; - } - - KeyInitialized = TRUE; - } - - WaitForKeyStroke (&Key); - -TheKey: - switch (Key.UnicodeChar) { - case '+': - case '-': - // - // If an ordered list op-code, we will allow for a popup of +/- keys - // to create an ordered list of items - // - if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) { - if (Key.UnicodeChar == '+') { - if ((TopOptionIndex > 1) && (HighlightPosition == (Top + 1))) { - // - // Highlight reaches the top of the popup window, scroll one menu item. - // - TopOptionIndex--; - ShowDownArrow = TRUE; - } - - if (TopOptionIndex == 1) { - ShowUpArrow = FALSE; - } - } else { - if (((TopOptionIndex + MenuLinesInView) <= PopUpMenuLines) && (HighlightPosition == (Bottom - 1))) { - // - // Highlight reaches the bottom of the popup window, scroll one menu item. - // - TopOptionIndex++; - ShowUpArrow = TRUE; - } - - if ((TopOptionIndex + MenuLinesInView) == (PopUpMenuLines + 1)) { - ShowDownArrow = FALSE; - } - } - - for (Index = MenuOption->TagIndex + TopOptionIndex; - MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP; - Index++ - ) { - if (MenuOption->Tags[Index].Operand == EFI_IFR_ORDERED_LIST_OP) { - continue; - } - - if (Key.UnicodeChar == '+') { - TempIndex = Index - 1; - } else { - TempIndex = Index + 1; - } - // - // Is this the current tag we are on? - // - if (MenuOption->Tags[Index].Value == TempValue) { - // - // Is this prior tag a valid choice? If not, bail out - // - if (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP) { - // - // Copy the destination tag to the local variable - // - CopyMem (&TagBackup, &MenuOption->Tags[TempIndex], sizeof (EFI_TAG)); - // - // Copy the current tag to the tag location before us - // - CopyMem (&MenuOption->Tags[TempIndex], &MenuOption->Tags[Index], sizeof (EFI_TAG)); - // - // Copy the backed up tag to the current location - // - CopyMem (&MenuOption->Tags[Index], &TagBackup, sizeof (EFI_TAG)); - - // - // Adjust the array of values - // - for (Index = 0; Index < ValueCount; Index++) { - if (ValueArrayBackup[Index] == (UINT8) TempValue) { - if (Key.UnicodeChar == '+') { - if (Index == 0) { - // - // It is the top of the array already - // - break; - } - - TempIndex = Index - 1; - } else { - if ((Index + 1) == ValueCount) { - // - // It is the bottom of the array already - // - break; - } - - TempIndex = Index + 1; - } - - ValueBackup = ValueArrayBackup[TempIndex]; - ValueArrayBackup[TempIndex] = ValueArrayBackup[Index]; - ValueArrayBackup[Index] = ValueBackup; - Initialized = TRUE; - break; - } - } - break; - } else { - break; - } - } - } - } - break; - - case CHAR_NULL: - switch (Key.ScanCode) { - case SCAN_UP: - case SCAN_DOWN: - if (Key.ScanCode == SCAN_UP) { - if ((TopOptionIndex > 1) && (HighlightPosition == (Top + 1))) { - // - // Highlight reaches the top of the popup window, scroll one menu item. - // - TopOptionIndex--; - ShowDownArrow = TRUE; - } - - if (TopOptionIndex == 1) { - ShowUpArrow = FALSE; - } - } else { - if (((TopOptionIndex + MenuLinesInView) <= PopUpMenuLines) && (HighlightPosition == (Bottom - 1))) { - // - // Highlight reaches the bottom of the popup window, scroll one menu item. - // - TopOptionIndex++; - ShowUpArrow = TRUE; - } - - if ((TopOptionIndex + MenuLinesInView) == (PopUpMenuLines + 1)) { - ShowDownArrow = FALSE; - } - } - - for (Index = MenuOption->TagIndex + TopOptionIndex; - MenuOption->Tags[Index].Operand != EFI_IFR_END_ONE_OF_OP; - Index++ - ) { - if (MenuOption->Tags[Index].Operand == EFI_IFR_ONE_OF_OPTION_OP) { - if (Initialized) { - for (Index = 0; (ValueArrayBackup[Index] != TempValue) && (Index < ValueCount); Index++) - ; - - // - // Did we hit the end of the array? Either get the first TempValue or the next one - // - if (Key.ScanCode == SCAN_UP) { - if (Index == 0) { - TempValue = ValueArrayBackup[0]; - } else { - TempValue = ValueArrayBackup[Index - 1]; - } - } else { - if ((Index + 1) == ValueCount) { - TempValue = ValueArrayBackup[Index]; - } else { - TempValue = ValueArrayBackup[Index + 1]; - } - } - break; - } else { - if (Key.ScanCode == SCAN_UP) { - TempIndex = Index - 1; - - // - // Keep going until meets meaningful tag. - // - while ((MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OPTION_OP && - MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OP && - MenuOption->Tags[TempIndex].Operand != EFI_IFR_END_ONE_OF_OP) - || - (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP && - (MenuOption->Tags[TempIndex].Suppress || MenuOption->Tags[TempIndex].GrayOut))) { - TempIndex--; - } - } else { - TempIndex = Index + 1; - - // - // Keep going until meets meaningful tag. - // - while ((MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OPTION_OP && - MenuOption->Tags[TempIndex].Operand != EFI_IFR_ONE_OF_OP && - MenuOption->Tags[TempIndex].Operand != EFI_IFR_END_ONE_OF_OP) - || - (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP && - (MenuOption->Tags[TempIndex].Suppress || MenuOption->Tags[TempIndex].GrayOut))) { - TempIndex++; - } - } - // - // The option value is the same as what is stored in NV store. This is where we take action - // - if (MenuOption->Tags[Index].Value == TempValue) { - // - // Only if the previous op-code is an option can we select it, otherwise we are at the left-most option - // - if (MenuOption->Tags[TempIndex].Operand == EFI_IFR_ONE_OF_OPTION_OP) { - TempValue = MenuOption->Tags[TempIndex].Value; - *KeyValue = MenuOption->Tags[TempIndex].Key; - } else { - TempValue = MenuOption->Tags[Index].Value; - *KeyValue = MenuOption->Tags[Index].Key; - } - break; - } - } - } - } - break; - - case SCAN_ESC: - gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); - if (ValueArrayBackup != NULL) { - FreePool (ValueArrayBackup); - } - - return EFI_DEVICE_ERROR; - - default: - break; - } - - break; - - case CHAR_CARRIAGE_RETURN: - // - // return the current selection - // - if (Tag->Operand == EFI_IFR_ORDERED_LIST_OP) { - CopyMem (ValueArray, ValueArrayBackup, ValueCount); - FreePool (ValueArrayBackup); - } else { - *Value = TempValue; - } - - goto Done; - - default: - break; - } - } while (1); - -Done: - gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); - return EFI_SUCCESS; -} - -EFI_STATUS -WaitForKeyStroke ( - OUT EFI_INPUT_KEY *Key - ) -{ - EFI_STATUS Status; - - do { - UiWaitForSingleEvent (gST->ConIn->WaitForKey, 0); - Status = gST->ConIn->ReadKeyStroke (gST->ConIn, Key); - } while (EFI_ERROR(Status)); - - return Status; -}