summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/InputHandler.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/InputHandler.c')
-rw-r--r--EdkModulePkg/Universal/UserInterface/SetupBrowser/Dxe/InputHandler.c1570
1 files changed, 0 insertions, 1570 deletions
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;
-}