From 253616154506e17ebd02c076f240748f57e36ac2 Mon Sep 17 00:00:00 2001 From: Eric Dong Date: Mon, 12 Aug 2013 02:03:10 +0000 Subject: Rollback patch 14537 & 14538, because patch 14537 is not tested by Laszlo Ersek, but i wrote it. Signed-off-by: Eric Dong git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14539 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/DisplayEngineDxe/InputHandler.c | 1531 -------------------- 1 file changed, 1531 deletions(-) delete mode 100644 MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c (limited to 'MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c') diff --git a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c b/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c deleted file mode 100644 index a58e12f12c..0000000000 --- a/MdeModulePkg/Universal/DisplayEngineDxe/InputHandler.c +++ /dev/null @@ -1,1531 +0,0 @@ -/** @file -Implementation for handling user input from the User Interfaces. - -Copyright (c) 2004 - 2012, 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 "FormDisplay.h" - -/** - Get maximum and minimum info from this opcode. - - @param OpCode Pointer to the current input opcode. - @param Minimum The minimum size info for this opcode. - @param Maximum The maximum size info for this opcode. - -**/ -VOID -GetFieldFromOp ( - IN EFI_IFR_OP_HEADER *OpCode, - OUT UINTN *Minimum, - OUT UINTN *Maximum - ) -{ - EFI_IFR_STRING *StringOp; - EFI_IFR_PASSWORD *PasswordOp; - if (OpCode->OpCode == EFI_IFR_STRING_OP) { - StringOp = (EFI_IFR_STRING *) OpCode; - *Minimum = StringOp->MinSize; - *Maximum = StringOp->MaxSize; - } else if (OpCode->OpCode == EFI_IFR_PASSWORD_OP) { - PasswordOp = (EFI_IFR_PASSWORD *) OpCode; - *Minimum = PasswordOp->MinSize; - *Maximum = PasswordOp->MaxSize; - } else { - *Minimum = 0; - *Maximum = 0; - } -} - -/** - Get string or password input from user. - - @param MenuOption Pointer to the current input menu. - @param Prompt The prompt string shown on popup window. - @param StringPtr Old user input and destination for use input string. - - @retval EFI_SUCCESS If string input is read successfully - @retval EFI_DEVICE_ERROR If operation fails - -**/ -EFI_STATUS -ReadString ( - IN UI_MENU_OPTION *MenuOption, - IN CHAR16 *Prompt, - IN OUT CHAR16 *StringPtr - ) -{ - EFI_STATUS Status; - EFI_INPUT_KEY Key; - CHAR16 NullCharacter; - UINTN ScreenSize; - CHAR16 Space[2]; - CHAR16 KeyPad[2]; - CHAR16 *TempString; - CHAR16 *BufferedString; - UINTN Index; - UINTN Index2; - UINTN Count; - UINTN Start; - UINTN Top; - UINTN DimensionsWidth; - UINTN DimensionsHeight; - UINTN CurrentCursor; - BOOLEAN CursorVisible; - UINTN Minimum; - UINTN Maximum; - FORM_DISPLAY_ENGINE_STATEMENT *Question; - BOOLEAN IsPassword; - - DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn; - DimensionsHeight = gStatementDimensions.BottomRow - gStatementDimensions.TopRow; - - NullCharacter = CHAR_NULL; - ScreenSize = GetStringWidth (Prompt) / sizeof (CHAR16); - Space[0] = L' '; - Space[1] = CHAR_NULL; - - Question = MenuOption->ThisTag; - GetFieldFromOp(Question->OpCode, &Minimum, &Maximum); - - if (Question->OpCode->OpCode == EFI_IFR_PASSWORD_OP) { - IsPassword = TRUE; - } else { - IsPassword = FALSE; - } - - TempString = AllocateZeroPool ((Maximum + 1)* sizeof (CHAR16)); - ASSERT (TempString); - - if (ScreenSize < (Maximum + 1)) { - ScreenSize = Maximum + 1; - } - - if ((ScreenSize + 2) > DimensionsWidth) { - ScreenSize = DimensionsWidth - 2; - } - - BufferedString = AllocateZeroPool (ScreenSize * 2); - ASSERT (BufferedString); - - Start = (DimensionsWidth - ScreenSize - 2) / 2 + gStatementDimensions.LeftColumn + 1; - Top = ((DimensionsHeight - 6) / 2) + gStatementDimensions.TopRow - 1; - - // - // Display prompt for string - // - // CreateDialog (NULL, "", Prompt, Space, "", NULL); - CreateMultiStringPopUp (ScreenSize, 4, &NullCharacter, Prompt, Space, &NullCharacter); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); - - CursorVisible = gST->ConOut->Mode->CursorVisible; - gST->ConOut->EnableCursor (gST->ConOut, TRUE); - - CurrentCursor = GetStringWidth (StringPtr) / 2 - 1; - if (CurrentCursor != 0) { - // - // Show the string which has beed saved before. - // - SetUnicodeMem (BufferedString, ScreenSize - 1, L' '); - PrintStringAt (Start + 1, Top + 3, BufferedString); - - if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { - Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; - } else { - Index = 0; - } - - if (IsPassword) { - gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3); - } - - for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { - BufferedString[Count] = StringPtr[Index]; - - if (IsPassword) { - PrintCharAt ((UINTN)-1, (UINTN)-1, L'*'); - } - } - - if (!IsPassword) { - PrintStringAt (Start + 1, Top + 3, BufferedString); - } - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->SetCursorPosition (gST->ConOut, Start + GetStringWidth (StringPtr) / 2, Top + 3); - } - - do { - Status = WaitForKeyStroke (&Key); - ASSERT_EFI_ERROR (Status); - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_BLACK, EFI_LIGHTGRAY)); - switch (Key.UnicodeChar) { - case CHAR_NULL: - switch (Key.ScanCode) { - case SCAN_LEFT: - if (CurrentCursor > 0) { - CurrentCursor--; - } - break; - - case SCAN_RIGHT: - if (CurrentCursor < (GetStringWidth (StringPtr) / 2 - 1)) { - CurrentCursor++; - } - break; - - case SCAN_ESC: - FreePool (TempString); - FreePool (BufferedString); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); - return EFI_DEVICE_ERROR; - - default: - break; - } - - break; - - case CHAR_CARRIAGE_RETURN: - if (GetStringWidth (StringPtr) >= ((Minimum + 1) * sizeof (CHAR16))) { - - FreePool (TempString); - FreePool (BufferedString); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); - return EFI_SUCCESS; - } else { - // - // Simply create a popup to tell the user that they had typed in too few characters. - // To save code space, we can then treat this as an error and return back to the menu. - // - do { - CreateDialog (&Key, &NullCharacter, gMiniString, gPressEnter, &NullCharacter, NULL); - } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - - FreePool (TempString); - FreePool (BufferedString); - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->EnableCursor (gST->ConOut, CursorVisible); - return EFI_DEVICE_ERROR; - } - - break; - - case CHAR_BACKSPACE: - if (StringPtr[0] != CHAR_NULL && CurrentCursor != 0) { - for (Index = 0; Index < CurrentCursor - 1; Index++) { - TempString[Index] = StringPtr[Index]; - } - Count = GetStringWidth (StringPtr) / 2 - 1; - if (Count >= CurrentCursor) { - for (Index = CurrentCursor - 1, Index2 = CurrentCursor; Index2 < Count; Index++, Index2++) { - TempString[Index] = StringPtr[Index2]; - } - TempString[Index] = CHAR_NULL; - } - // - // Effectively truncate string by 1 character - // - StrCpy (StringPtr, TempString); - CurrentCursor --; - } - - default: - // - // If it is the beginning of the string, don't worry about checking maximum limits - // - if ((StringPtr[0] == CHAR_NULL) && (Key.UnicodeChar != CHAR_BACKSPACE)) { - StrnCpy (StringPtr, &Key.UnicodeChar, 1); - CurrentCursor++; - } else if ((GetStringWidth (StringPtr) < ((Maximum + 1) * sizeof (CHAR16))) && (Key.UnicodeChar != CHAR_BACKSPACE)) { - KeyPad[0] = Key.UnicodeChar; - KeyPad[1] = CHAR_NULL; - Count = GetStringWidth (StringPtr) / 2 - 1; - if (CurrentCursor < Count) { - for (Index = 0; Index < CurrentCursor; Index++) { - TempString[Index] = StringPtr[Index]; - } - TempString[Index] = CHAR_NULL; - StrCat (TempString, KeyPad); - StrCat (TempString, StringPtr + CurrentCursor); - StrCpy (StringPtr, TempString); - } else { - StrCat (StringPtr, KeyPad); - } - CurrentCursor++; - } - - // - // If the width of the input string is now larger than the screen, we nee to - // adjust the index to start printing portions of the string - // - SetUnicodeMem (BufferedString, ScreenSize - 1, L' '); - PrintStringAt (Start + 1, Top + 3, BufferedString); - - if ((GetStringWidth (StringPtr) / 2) > (DimensionsWidth - 2)) { - Index = (GetStringWidth (StringPtr) / 2) - DimensionsWidth + 2; - } else { - Index = 0; - } - - if (IsPassword) { - gST->ConOut->SetCursorPosition (gST->ConOut, Start + 1, Top + 3); - } - - for (Count = 0; Index + 1 < GetStringWidth (StringPtr) / 2; Index++, Count++) { - BufferedString[Count] = StringPtr[Index]; - - if (IsPassword) { - PrintCharAt ((UINTN)-1, (UINTN)-1, L'*'); - } - } - - if (!IsPassword) { - PrintStringAt (Start + 1, Top + 3, BufferedString); - } - break; - } - - gST->ConOut->SetAttribute (gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); - gST->ConOut->SetCursorPosition (gST->ConOut, Start + CurrentCursor + 1, Top + 3); - } while (TRUE); - -} - -/** - Adjust the value to the correct one. Rules follow the sample: - like: Year change: 2012.02.29 -> 2013.02.29 -> 2013.02.01 - Month change: 2013.03.29 -> 2013.02.29 -> 2013.02.28 - - @param QuestionValue Pointer to current question. - @param Sequence The sequence of the field in the question. -**/ -VOID -AdjustQuestionValue ( - IN EFI_HII_VALUE *QuestionValue, - IN UINT8 Sequence - ) -{ - UINT8 Month; - UINT16 Year; - UINT8 Maximum; - UINT8 Minimum; - - Month = QuestionValue->Value.date.Month; - Year = QuestionValue->Value.date.Year; - Minimum = 1; - - switch (Month) { - case 2: - if ((Year % 4) == 0 && ((Year % 100) != 0 || (Year % 400) == 0)) { - Maximum = 29; - } else { - Maximum = 28; - } - break; - case 4: - case 6: - case 9: - case 11: - Maximum = 30; - break; - default: - Maximum = 31; - break; - } - - // - // Change the month area. - // - if (Sequence == 0) { - if (QuestionValue->Value.date.Day > Maximum) { - QuestionValue->Value.date.Day = Maximum; - } - } - - // - // Change the Year area. - // - if (Sequence == 2) { - if (QuestionValue->Value.date.Day > Maximum) { - QuestionValue->Value.date.Day = Minimum; - } - } -} - -/** - Get field info from numeric opcode. - - @param OpCode Pointer to the current input opcode. - @param Minimum The minimum size info for this opcode. - @param Maximum The maximum size info for this opcode. - @param Step The step size info for this opcode. - @param StorageWidth The storage width info for this opcode. - -**/ -VOID -GetValueFromNum ( - IN EFI_IFR_OP_HEADER *OpCode, - OUT UINT64 *Minimum, - OUT UINT64 *Maximum, - OUT UINT64 *Step, - OUT UINT16 *StorageWidth -) -{ - EFI_IFR_NUMERIC *NumericOp; - - NumericOp = (EFI_IFR_NUMERIC *) OpCode; - - switch (NumericOp->Flags & EFI_IFR_NUMERIC_SIZE) { - case EFI_IFR_NUMERIC_SIZE_1: - *Minimum = NumericOp->data.u8.MinValue; - *Maximum = NumericOp->data.u8.MaxValue; - *Step = NumericOp->data.u8.Step; - *StorageWidth = (UINT16) sizeof (UINT8); - break; - - case EFI_IFR_NUMERIC_SIZE_2: - *Minimum = NumericOp->data.u16.MinValue; - *Maximum = NumericOp->data.u16.MaxValue; - *Step = NumericOp->data.u16.Step; - *StorageWidth = (UINT16) sizeof (UINT16); - break; - - case EFI_IFR_NUMERIC_SIZE_4: - *Minimum = NumericOp->data.u32.MinValue; - *Maximum = NumericOp->data.u32.MaxValue; - *Step = NumericOp->data.u32.Step; - *StorageWidth = (UINT16) sizeof (UINT32); - break; - - case EFI_IFR_NUMERIC_SIZE_8: - *Minimum = NumericOp->data.u64.MinValue; - *Maximum = NumericOp->data.u64.MaxValue; - *Step = NumericOp->data.u64.Step; - *StorageWidth = (UINT16) sizeof (UINT64); - break; - - default: - break; - } - - if (*Maximum == 0) { - *Maximum = (UINT64) -1; - } -} - -/** - This routine reads a numeric value from the user input. - - @param MenuOption Pointer to the current input menu. - - @retval EFI_SUCCESS If numerical input is read successfully - @retval EFI_DEVICE_ERROR If operation fails - -**/ -EFI_STATUS -GetNumericInput ( - IN UI_MENU_OPTION *MenuOption - ) -{ - EFI_STATUS Status; - UINTN Column; - UINTN Row; - CHAR16 InputText[MAX_NUMERIC_INPUT_WIDTH]; - CHAR16 FormattedNumber[MAX_NUMERIC_INPUT_WIDTH - 1]; - UINT64 PreviousNumber[MAX_NUMERIC_INPUT_WIDTH - 3]; - UINTN Count; - UINTN Loop; - BOOLEAN ManualInput; - BOOLEAN HexInput; - BOOLEAN DateOrTime; - UINTN InputWidth; - UINT64 EditValue; - UINT64 Step; - UINT64 Minimum; - UINT64 Maximum; - UINTN EraseLen; - UINT8 Digital; - EFI_INPUT_KEY Key; - EFI_HII_VALUE *QuestionValue; - FORM_DISPLAY_ENGINE_STATEMENT *Question; - EFI_IFR_NUMERIC *NumericOp; - UINT16 StorageWidth; - - Column = MenuOption->OptCol; - Row = MenuOption->Row; - PreviousNumber[0] = 0; - Count = 0; - InputWidth = 0; - Digital = 0; - StorageWidth = 0; - Minimum = 0; - Maximum = 0; - NumericOp = NULL; - - Question = MenuOption->ThisTag; - QuestionValue = &Question->CurrentValue; - - // - // Only two case, user can enter to this function: Enter and +/- case. - // In Enter case, gDirection = 0; in +/- case, gDirection = SCAN_LEFT/SCAN_WRIGHT - // - ManualInput = (BOOLEAN)(gDirection == 0 ? TRUE : FALSE); - - if ((Question->OpCode->OpCode == EFI_IFR_DATE_OP) || (Question->OpCode->OpCode == EFI_IFR_TIME_OP)) { - DateOrTime = TRUE; - } else { - DateOrTime = FALSE; - } - - // - // Prepare Value to be edit - // - EraseLen = 0; - EditValue = 0; - if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) { - Step = 1; - Minimum = 1; - - switch (MenuOption->Sequence) { - case 0: - Maximum = 12; - EraseLen = 4; - EditValue = QuestionValue->Value.date.Month; - break; - - case 1: - switch (QuestionValue->Value.date.Month) { - case 2: - if ((QuestionValue->Value.date.Year % 4) == 0 && - ((QuestionValue->Value.date.Year % 100) != 0 || - (QuestionValue->Value.date.Year % 400) == 0)) { - Maximum = 29; - } else { - Maximum = 28; - } - break; - case 4: - case 6: - case 9: - case 11: - Maximum = 30; - break; - default: - Maximum = 31; - break; - } - - EraseLen = 3; - EditValue = QuestionValue->Value.date.Day; - break; - - case 2: - Maximum = 0xffff; - EraseLen = 5; - EditValue = QuestionValue->Value.date.Year; - break; - - default: - break; - } - } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) { - Step = 1; - Minimum = 0; - - switch (MenuOption->Sequence) { - case 0: - Maximum = 23; - EraseLen = 4; - EditValue = QuestionValue->Value.time.Hour; - break; - - case 1: - Maximum = 59; - EraseLen = 3; - EditValue = QuestionValue->Value.time.Minute; - break; - - case 2: - Maximum = 59; - EraseLen = 3; - EditValue = QuestionValue->Value.time.Second; - break; - - default: - break; - } - } else { - ASSERT (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP); - NumericOp = (EFI_IFR_NUMERIC *) Question->OpCode; - GetValueFromNum(Question->OpCode, &Minimum, &Maximum, &Step, &StorageWidth); - EditValue = QuestionValue->Value.u64; - EraseLen = gOptionBlockWidth; - } - - if ((Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) && (NumericOp != NULL) && - ((NumericOp->Flags & EFI_IFR_DISPLAY) == EFI_IFR_DISPLAY_UINT_HEX)) { - HexInput = TRUE; - } else { - HexInput = FALSE; - } - - // - // Enter from "Enter" input, clear the old word showing. - // - if (ManualInput) { - if (Question->OpCode->OpCode == EFI_IFR_NUMERIC_OP) { - if (HexInput) { - InputWidth = StorageWidth * 2; - } else { - switch (StorageWidth) { - case 1: - InputWidth = 3; - break; - - case 2: - InputWidth = 5; - break; - - case 4: - InputWidth = 10; - break; - - case 8: - InputWidth = 20; - break; - - default: - InputWidth = 0; - break; - } - } - - InputText[0] = LEFT_NUMERIC_DELIMITER; - SetUnicodeMem (InputText + 1, InputWidth, L' '); - ASSERT (InputWidth + 2 < MAX_NUMERIC_INPUT_WIDTH); - InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER; - InputText[InputWidth + 2] = L'\0'; - - PrintStringAt (Column, Row, InputText); - Column++; - } - - if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) { - if (MenuOption->Sequence == 2) { - InputWidth = 4; - } else { - InputWidth = 2; - } - - if (MenuOption->Sequence == 0) { - InputText[0] = LEFT_NUMERIC_DELIMITER; - SetUnicodeMem (InputText + 1, InputWidth, L' '); - } else { - SetUnicodeMem (InputText, InputWidth, L' '); - } - - if (MenuOption->Sequence == 2) { - InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER; - } else { - InputText[InputWidth + 1] = DATE_SEPARATOR; - } - InputText[InputWidth + 2] = L'\0'; - - PrintStringAt (Column, Row, InputText); - if (MenuOption->Sequence == 0) { - Column++; - } - } - - if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) { - InputWidth = 2; - - if (MenuOption->Sequence == 0) { - InputText[0] = LEFT_NUMERIC_DELIMITER; - SetUnicodeMem (InputText + 1, InputWidth, L' '); - } else { - SetUnicodeMem (InputText, InputWidth, L' '); - } - - if (MenuOption->Sequence == 2) { - InputText[InputWidth + 1] = RIGHT_NUMERIC_DELIMITER; - } else { - InputText[InputWidth + 1] = TIME_SEPARATOR; - } - InputText[InputWidth + 2] = L'\0'; - - PrintStringAt (Column, Row, InputText); - if (MenuOption->Sequence == 0) { - Column++; - } - } - } - - // - // First time we enter this handler, we need to check to see if - // we were passed an increment or decrement directive - // - do { - Key.UnicodeChar = CHAR_NULL; - if (gDirection != 0) { - Key.ScanCode = gDirection; - gDirection = 0; - goto TheKey2; - } - - Status = WaitForKeyStroke (&Key); - -TheKey2: - switch (Key.UnicodeChar) { - - case '+': - case '-': - if (Key.UnicodeChar == '+') { - Key.ScanCode = SCAN_RIGHT; - } else { - Key.ScanCode = SCAN_LEFT; - } - Key.UnicodeChar = CHAR_NULL; - goto TheKey2; - - case CHAR_NULL: - switch (Key.ScanCode) { - case SCAN_LEFT: - case SCAN_RIGHT: - if (DateOrTime && !ManualInput) { - // - // By setting this value, we will return back to the caller. - // We need to do this since an auto-refresh will destroy the adjustment - // based on what the real-time-clock is showing. So we always commit - // upon changing the value. - // - gDirection = SCAN_DOWN; - } - - if ((Step != 0) && !ManualInput) { - if (Key.ScanCode == SCAN_LEFT) { - if (EditValue >= Minimum + Step) { - EditValue = EditValue - Step; - } else if (EditValue > Minimum){ - EditValue = Minimum; - } else { - EditValue = Maximum; - } - } else if (Key.ScanCode == SCAN_RIGHT) { - if (EditValue + Step <= Maximum) { - EditValue = EditValue + Step; - } else if (EditValue < Maximum) { - EditValue = Maximum; - } else { - EditValue = Minimum; - } - } - - ZeroMem (FormattedNumber, 21 * sizeof (CHAR16)); - if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) { - if (MenuOption->Sequence == 2) { - // - // Year - // - UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%04d", (UINT16) EditValue); - } else { - // - // Month/Day - // - UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue); - } - - if (MenuOption->Sequence == 0) { - ASSERT (EraseLen >= 2); - FormattedNumber[EraseLen - 2] = DATE_SEPARATOR; - } else if (MenuOption->Sequence == 1) { - ASSERT (EraseLen >= 1); - FormattedNumber[EraseLen - 1] = DATE_SEPARATOR; - } - } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) { - UnicodeSPrint (FormattedNumber, 21 * sizeof (CHAR16), L"%02d", (UINT8) EditValue); - - if (MenuOption->Sequence == 0) { - ASSERT (EraseLen >= 2); - FormattedNumber[EraseLen - 2] = TIME_SEPARATOR; - } else if (MenuOption->Sequence == 1) { - ASSERT (EraseLen >= 1); - FormattedNumber[EraseLen - 1] = TIME_SEPARATOR; - } - } else { - QuestionValue->Value.u64 = EditValue; - PrintFormattedNumber (Question, FormattedNumber, 21 * sizeof (CHAR16)); - } - - gST->ConOut->SetAttribute (gST->ConOut, GetFieldTextColor ()); - for (Loop = 0; Loop < EraseLen; Loop++) { - PrintStringAt (MenuOption->OptCol + Loop, MenuOption->Row, L" "); - } - gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ()); - - if (MenuOption->Sequence == 0) { - PrintCharAt (MenuOption->OptCol, Row, LEFT_NUMERIC_DELIMITER); - Column = MenuOption->OptCol + 1; - } - - PrintStringAt (Column, Row, FormattedNumber); - - if (!DateOrTime || MenuOption->Sequence == 2) { - PrintCharAt ((UINTN)-1, (UINTN)-1, RIGHT_NUMERIC_DELIMITER); - } - } - - goto EnterCarriageReturn; - break; - - case SCAN_UP: - case SCAN_DOWN: - goto EnterCarriageReturn; - - case SCAN_ESC: - return EFI_DEVICE_ERROR; - - default: - break; - } - - break; - -EnterCarriageReturn: - - case CHAR_CARRIAGE_RETURN: - // - // Validate input value with Minimum value. - // - if (EditValue < Minimum) { - UpdateStatusBar (INPUT_ERROR, TRUE); - break; - } else { - UpdateStatusBar (INPUT_ERROR, FALSE); - } - - CopyMem (&gUserInput->InputValue, &Question->CurrentValue, sizeof (EFI_HII_VALUE)); - QuestionValue = &gUserInput->InputValue; - // - // Store Edit value back to Question - // - if (Question->OpCode->OpCode == EFI_IFR_DATE_OP) { - switch (MenuOption->Sequence) { - case 0: - QuestionValue->Value.date.Month = (UINT8) EditValue; - break; - - case 1: - QuestionValue->Value.date.Day = (UINT8) EditValue; - break; - - case 2: - QuestionValue->Value.date.Year = (UINT16) EditValue; - break; - - default: - break; - } - } else if (Question->OpCode->OpCode == EFI_IFR_TIME_OP) { - switch (MenuOption->Sequence) { - case 0: - QuestionValue->Value.time.Hour = (UINT8) EditValue; - break; - - case 1: - QuestionValue->Value.time.Minute = (UINT8) EditValue; - break; - - case 2: - QuestionValue->Value.time.Second = (UINT8) EditValue; - break; - - default: - break; - } - } else { - // - // Numeric - // - QuestionValue->Value.u64 = EditValue; - } - - // - // Adjust the value to the correct one. - // Sample like: 2012.02.29 -> 2013.02.29 -> 2013.02.01 - // 2013.03.29 -> 2013.02.29 -> 2013.02.28 - // - if (Question->OpCode->OpCode == EFI_IFR_DATE_OP && - (MenuOption->Sequence == 0 || MenuOption->Sequence == 2)) { - AdjustQuestionValue (QuestionValue, (UINT8)MenuOption->Sequence); - } - - return ValidateQuestion (Question); - break; - - case CHAR_BACKSPACE: - if (ManualInput) { - if (Count == 0) { - break; - } - // - // Remove a character - // - EditValue = PreviousNumber[Count - 1]; - UpdateStatusBar (INPUT_ERROR, FALSE); - Count--; - Column--; - PrintStringAt (Column, Row, L" "); - } - break; - - default: - if (ManualInput) { - if (HexInput) { - if ((Key.UnicodeChar >= L'0') && (Key.UnicodeChar <= L'9')) { - Digital = (UINT8) (Key.UnicodeChar - L'0'); - } else if ((Key.UnicodeChar >= L'A') && (Key.UnicodeChar <= L'F')) { - Digital = (UINT8) (Key.UnicodeChar - L'A' + 0x0A); - } else if ((Key.UnicodeChar >= L'a') && (Key.UnicodeChar <= L'f')) { - Digital = (UINT8) (Key.UnicodeChar - L'a' + 0x0A); - } else { - UpdateStatusBar (INPUT_ERROR, TRUE); - break; - } - } else { - if (Key.UnicodeChar > L'9' || Key.UnicodeChar < L'0') { - UpdateStatusBar (INPUT_ERROR, TRUE); - break; - } - } - - // - // If Count exceed input width, there is no way more is valid - // - if (Count >= InputWidth) { - break; - } - // - // Someone typed something valid! - // - if (Count != 0) { - if (HexInput) { - EditValue = LShiftU64 (EditValue, 4) + Digital; - } else { - EditValue = MultU64x32 (EditValue, 10) + (Key.UnicodeChar - L'0'); - } - } else { - if (HexInput) { - EditValue = Digital; - } else { - EditValue = Key.UnicodeChar - L'0'; - } - } - - if (EditValue > Maximum) { - UpdateStatusBar (INPUT_ERROR, TRUE); - ASSERT (Count < sizeof (PreviousNumber) / sizeof (PreviousNumber[0])); - EditValue = PreviousNumber[Count]; - break; - } else { - UpdateStatusBar (INPUT_ERROR, FALSE); - } - - Count++; - ASSERT (Count < (sizeof (PreviousNumber) / sizeof (PreviousNumber[0]))); - PreviousNumber[Count] = EditValue; - - gST->ConOut->SetAttribute (gST->ConOut, GetHighlightTextColor ()); - PrintCharAt (Column, Row, Key.UnicodeChar); - Column++; - } - break; - } - } while (TRUE); -} - -/** - Adjust option order base on the question value. - - @param Question Pointer to current question. - @param PopUpMenuLines The line number of the pop up menu. - - @retval EFI_SUCCESS If Option input is processed successfully - @retval EFI_DEVICE_ERROR If operation fails - -**/ -EFI_STATUS -AdjustOptionOrder ( - IN FORM_DISPLAY_ENGINE_STATEMENT *Question, - OUT UINTN *PopUpMenuLines - ) -{ - UINTN Index; - EFI_IFR_ORDERED_LIST *OrderList; - UINT8 *ValueArray; - UINT8 ValueType; - LIST_ENTRY *Link; - DISPLAY_QUESTION_OPTION *OneOfOption; - EFI_HII_VALUE *HiiValueArray; - - Link = GetFirstNode (&Question->OptionListHead); - OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); - ValueArray = Question->CurrentValue.Buffer; - ValueType = OneOfOption->OptionOpCode->Type; - OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode; - - for (Index = 0; Index < OrderList->MaxContainers; Index++) { - if (GetArrayData (ValueArray, ValueType, Index) == 0) { - break; - } - } - - *PopUpMenuLines = Index; - - // - // Prepare HiiValue array - // - HiiValueArray = AllocateZeroPool (*PopUpMenuLines * sizeof (EFI_HII_VALUE)); - ASSERT (HiiValueArray != NULL); - - for (Index = 0; Index < *PopUpMenuLines; Index++) { - HiiValueArray[Index].Type = ValueType; - HiiValueArray[Index].Value.u64 = GetArrayData (ValueArray, ValueType, Index); - } - - for (Index = 0; Index < *PopUpMenuLines; Index++) { - OneOfOption = ValueToOption (Question, &HiiValueArray[*PopUpMenuLines - Index - 1]); - if (OneOfOption == NULL) { - return EFI_NOT_FOUND; - } - - RemoveEntryList (&OneOfOption->Link); - - // - // Insert to head. - // - InsertHeadList (&Question->OptionListHead, &OneOfOption->Link); - } - - FreePool (HiiValueArray); - - return EFI_SUCCESS; -} - -/** - Base on the type to compare the value. - - @param Value1 The first value need to compare. - @param Value2 The second value need to compare. - @param Type The value type for above two values. - - @retval TRUE The two value are same. - @retval FALSE The two value are different. - -**/ -BOOLEAN -IsValuesEqual ( - IN EFI_IFR_TYPE_VALUE *Value1, - IN EFI_IFR_TYPE_VALUE *Value2, - IN UINT8 Type - ) -{ - switch (Type) { - case EFI_IFR_TYPE_BOOLEAN: - case EFI_IFR_TYPE_NUM_SIZE_8: - return (BOOLEAN) (Value1->u8 == Value2->u8); - - case EFI_IFR_TYPE_NUM_SIZE_16: - return (BOOLEAN) (Value1->u16 == Value2->u16); - - case EFI_IFR_TYPE_NUM_SIZE_32: - return (BOOLEAN) (Value1->u32 == Value2->u32); - - case EFI_IFR_TYPE_NUM_SIZE_64: - return (BOOLEAN) (Value1->u64 == Value2->u64); - - default: - ASSERT (FALSE); - return FALSE; - } -} - -/** - Base on the type to set the value. - - @param Dest The dest value. - @param Source The source value. - @param Type The value type for above two values. - -**/ -VOID -SetValuesByType ( - OUT EFI_IFR_TYPE_VALUE *Dest, - IN EFI_IFR_TYPE_VALUE *Source, - IN UINT8 Type - ) -{ - switch (Type) { - case EFI_IFR_TYPE_BOOLEAN: - Dest->b = Source->b; - break; - - case EFI_IFR_TYPE_NUM_SIZE_8: - Dest->u8 = Source->u8; - break; - - case EFI_IFR_TYPE_NUM_SIZE_16: - Dest->u16 = Source->u16; - break; - - case EFI_IFR_TYPE_NUM_SIZE_32: - Dest->u32 = Source->u32; - break; - - case EFI_IFR_TYPE_NUM_SIZE_64: - Dest->u64 = Source->u64; - break; - - default: - ASSERT (FALSE); - break; - } -} - -/** - Get selection for OneOf and OrderedList (Left/Right will be ignored). - - @param MenuOption Pointer to the current input menu. - - @retval EFI_SUCCESS If Option input is processed successfully - @retval EFI_DEVICE_ERROR If operation fails - -**/ -EFI_STATUS -GetSelectionInputPopUp ( - IN UI_MENU_OPTION *MenuOption - ) -{ - EFI_STATUS Status; - EFI_INPUT_KEY Key; - UINTN Index; - CHAR16 *StringPtr; - CHAR16 *TempStringPtr; - UINTN Index2; - UINTN TopOptionIndex; - UINTN HighlightOptionIndex; - UINTN Start; - UINTN End; - UINTN Top; - UINTN Bottom; - UINTN PopUpMenuLines; - UINTN MenuLinesInView; - UINTN PopUpWidth; - CHAR16 Character; - INT32 SavedAttribute; - BOOLEAN ShowDownArrow; - BOOLEAN ShowUpArrow; - UINTN DimensionsWidth; - LIST_ENTRY *Link; - BOOLEAN OrderedList; - UINT8 *ValueArray; - UINT8 *ReturnValue; - UINT8 ValueType; - EFI_HII_VALUE HiiValue; - DISPLAY_QUESTION_OPTION *OneOfOption; - DISPLAY_QUESTION_OPTION *CurrentOption; - FORM_DISPLAY_ENGINE_STATEMENT *Question; - INTN Result; - EFI_IFR_ORDERED_LIST *OrderList; - - DimensionsWidth = gStatementDimensions.RightColumn - gStatementDimensions.LeftColumn; - - ValueArray = NULL; - ValueType = 0; - CurrentOption = NULL; - ShowDownArrow = FALSE; - ShowUpArrow = FALSE; - - StringPtr = AllocateZeroPool ((gOptionBlockWidth + 1) * 2); - ASSERT (StringPtr); - - ZeroMem (&HiiValue, sizeof (EFI_HII_VALUE)); - - Question = MenuOption->ThisTag; - if (Question->OpCode->OpCode == EFI_IFR_ORDERED_LIST_OP) { - Link = GetFirstNode (&Question->OptionListHead); - OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); - ValueArray = Question->CurrentValue.Buffer; - ValueType = OneOfOption->OptionOpCode->Type; - OrderedList = TRUE; - OrderList = (EFI_IFR_ORDERED_LIST *) Question->OpCode; - } else { - OrderedList = FALSE; - OrderList = NULL; - } - - // - // Calculate Option count - // - PopUpMenuLines = 0; - if (OrderedList) { - AdjustOptionOrder(Question, &PopUpMenuLines); - } else { - Link = GetFirstNode (&Question->OptionListHead); - while (!IsNull (&Question->OptionListHead, Link)) { - OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); - PopUpMenuLines++; - Link = GetNextNode (&Question->OptionListHead, Link); - } - } - - // - // Get the number of one of options present and its size - // - PopUpWidth = 0; - HighlightOptionIndex = 0; - Link = GetFirstNode (&Question->OptionListHead); - for (Index = 0; Index < PopUpMenuLines; Index++) { - OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); - - StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); - if (StrLen (StringPtr) > PopUpWidth) { - PopUpWidth = StrLen (StringPtr); - } - FreePool (StringPtr); - HiiValue.Type = OneOfOption->OptionOpCode->Type; - SetValuesByType (&HiiValue.Value, &OneOfOption->OptionOpCode->Value, HiiValue.Type); - if (!OrderedList && (CompareHiiValue (&Question->CurrentValue, &HiiValue, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) { - // - // Find current selected Option for OneOf - // - HighlightOptionIndex = Index; - } - - Link = GetNextNode (&Question->OptionListHead, Link); - } - - // - // Perform popup menu initialization. - // - PopUpWidth = PopUpWidth + POPUP_PAD_SPACE_COUNT; - - SavedAttribute = gST->ConOut->Mode->Attribute; - gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); - - if ((PopUpWidth + POPUP_FRAME_WIDTH) > DimensionsWidth) { - PopUpWidth = DimensionsWidth - POPUP_FRAME_WIDTH; - } - - Start = (DimensionsWidth - PopUpWidth - POPUP_FRAME_WIDTH) / 2 + gStatementDimensions.LeftColumn; - End = Start + PopUpWidth + POPUP_FRAME_WIDTH; - Top = gStatementDimensions.TopRow; - Bottom = gStatementDimensions.BottomRow - 1; - - MenuLinesInView = Bottom - Top - 1; - if (MenuLinesInView >= PopUpMenuLines) { - Top = Top + (MenuLinesInView - PopUpMenuLines) / 2; - Bottom = Top + PopUpMenuLines + 1; - } else { - ShowDownArrow = TRUE; - } - - if (HighlightOptionIndex > (MenuLinesInView - 1)) { - TopOptionIndex = HighlightOptionIndex - MenuLinesInView + 1; - } else { - TopOptionIndex = 0; - } - - do { - // - // Clear that portion of the screen - // - ClearLines (Start, End, Top, Bottom, GetPopupColor ()); - - // - // Draw "One of" pop-up menu - // - Character = BOXDRAW_DOWN_RIGHT; - PrintCharAt (Start, Top, Character); - for (Index = Start; Index + 2 < End; Index++) { - if ((ShowUpArrow) && ((Index + 1) == (Start + End) / 2)) { - Character = GEOMETRICSHAPE_UP_TRIANGLE; - } else { - Character = BOXDRAW_HORIZONTAL; - } - - PrintCharAt ((UINTN)-1, (UINTN)-1, Character); - } - - Character = BOXDRAW_DOWN_LEFT; - PrintCharAt ((UINTN)-1, (UINTN)-1, Character); - Character = BOXDRAW_VERTICAL; - for (Index = Top + 1; Index < Bottom; Index++) { - PrintCharAt (Start, Index, Character); - PrintCharAt (End - 1, Index, Character); - } - - // - // Move to top Option - // - Link = GetFirstNode (&Question->OptionListHead); - for (Index = 0; Index < TopOptionIndex; Index++) { - Link = GetNextNode (&Question->OptionListHead, Link); - } - - // - // Display the One of options - // - Index2 = Top + 1; - for (Index = TopOptionIndex; (Index < PopUpMenuLines) && (Index2 < Bottom); Index++) { - OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); - Link = GetNextNode (&Question->OptionListHead, Link); - - StringPtr = GetToken (OneOfOption->OptionOpCode->Option, gFormData->HiiHandle); - ASSERT (StringPtr != NULL); - // - // If the string occupies multiple lines, truncate it to fit in one line, - // and append a "..." for indication. - // - if (StrLen (StringPtr) > (PopUpWidth - 1)) { - TempStringPtr = AllocateZeroPool (sizeof (CHAR16) * (PopUpWidth - 1)); - ASSERT ( TempStringPtr != NULL ); - CopyMem (TempStringPtr, StringPtr, (sizeof (CHAR16) * (PopUpWidth - 5))); - FreePool (StringPtr); - StringPtr = TempStringPtr; - StrCat (StringPtr, L"..."); - } - - if (Index == HighlightOptionIndex) { - // - // Highlight the selected one - // - CurrentOption = OneOfOption; - - gST->ConOut->SetAttribute (gST->ConOut, GetPickListColor ()); - PrintStringAt (Start + 2, Index2, StringPtr); - gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); - } else { - gST->ConOut->SetAttribute (gST->ConOut, GetPopupColor ()); - PrintStringAt (Start + 2, Index2, StringPtr); - } - - Index2++; - FreePool (StringPtr); - } - - Character = BOXDRAW_UP_RIGHT; - PrintCharAt (Start, Bottom, Character); - for (Index = Start; Index + 2 < End; Index++) { - if ((ShowDownArrow) && ((Index + 1) == (Start + End) / 2)) { - Character = GEOMETRICSHAPE_DOWN_TRIANGLE; - } else { - Character = BOXDRAW_HORIZONTAL; - } - - PrintCharAt ((UINTN)-1, (UINTN)-1, Character); - } - - Character = BOXDRAW_UP_LEFT; - PrintCharAt ((UINTN)-1, (UINTN)-1, Character); - - // - // Get User selection - // - Key.UnicodeChar = CHAR_NULL; - if ((gDirection == SCAN_UP) || (gDirection == SCAN_DOWN)) { - Key.ScanCode = gDirection; - gDirection = 0; - goto TheKey; - } - - Status = WaitForKeyStroke (&Key); - -TheKey: - switch (Key.UnicodeChar) { - case '+': - if (OrderedList) { - if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) { - // - // Highlight reaches the top of the popup window, scroll one menu item. - // - TopOptionIndex--; - ShowDownArrow = TRUE; - } - - if (TopOptionIndex == 0) { - ShowUpArrow = FALSE; - } - - if (HighlightOptionIndex > 0) { - HighlightOptionIndex--; - - ASSERT (CurrentOption != NULL); - SwapListEntries (CurrentOption->Link.BackLink, &CurrentOption->Link); - } - } - break; - - case '-': - // - // If an ordered list op-code, we will allow for a popup of +/- keys - // to create an ordered list of items - // - if (OrderedList) { - if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) && - (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) { - // - // Highlight reaches the bottom of the popup window, scroll one menu item. - // - TopOptionIndex++; - ShowUpArrow = TRUE; - } - - if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) { - ShowDownArrow = FALSE; - } - - if (HighlightOptionIndex < (PopUpMenuLines - 1)) { - HighlightOptionIndex++; - - ASSERT (CurrentOption != NULL); - SwapListEntries (&CurrentOption->Link, CurrentOption->Link.ForwardLink); - } - } - break; - - case CHAR_NULL: - switch (Key.ScanCode) { - case SCAN_UP: - case SCAN_DOWN: - if (Key.ScanCode == SCAN_UP) { - if ((TopOptionIndex > 0) && (TopOptionIndex == HighlightOptionIndex)) { - // - // Highlight reaches the top of the popup window, scroll one menu item. - // - TopOptionIndex--; - ShowDownArrow = TRUE; - } - - if (TopOptionIndex == 0) { - ShowUpArrow = FALSE; - } - - if (HighlightOptionIndex > 0) { - HighlightOptionIndex--; - } - } else { - if (((TopOptionIndex + MenuLinesInView) < PopUpMenuLines) && - (HighlightOptionIndex == (TopOptionIndex + MenuLinesInView - 1))) { - // - // Highlight reaches the bottom of the popup window, scroll one menu item. - // - TopOptionIndex++; - ShowUpArrow = TRUE; - } - - if ((TopOptionIndex + MenuLinesInView) == PopUpMenuLines) { - ShowDownArrow = FALSE; - } - - if (HighlightOptionIndex < (PopUpMenuLines - 1)) { - HighlightOptionIndex++; - } - } - break; - - case SCAN_ESC: - gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); - - // - // Restore link list order for orderedlist - // - if (OrderedList) { - HiiValue.Type = ValueType; - HiiValue.Value.u64 = 0; - for (Index = 0; Index < OrderList->MaxContainers; Index++) { - HiiValue.Value.u64 = GetArrayData (ValueArray, ValueType, Index); - if (HiiValue.Value.u64 == 0) { - break; - } - - OneOfOption = ValueToOption (Question, &HiiValue); - if (OneOfOption == NULL) { - return EFI_NOT_FOUND; - } - - RemoveEntryList (&OneOfOption->Link); - InsertTailList (&Question->OptionListHead, &OneOfOption->Link); - } - } - - return EFI_DEVICE_ERROR; - - default: - break; - } - - break; - - case CHAR_CARRIAGE_RETURN: - // - // return the current selection - // - if (OrderedList) { - ReturnValue = AllocateZeroPool (Question->CurrentValue.BufferLen); - ASSERT (ReturnValue != NULL); - Index = 0; - Link = GetFirstNode (&Question->OptionListHead); - while (!IsNull (&Question->OptionListHead, Link)) { - OneOfOption = DISPLAY_QUESTION_OPTION_FROM_LINK (Link); - Link = GetNextNode (&Question->OptionListHead, Link); - - SetArrayData (ReturnValue, ValueType, Index, OneOfOption->OptionOpCode->Value.u64); - - Index++; - if (Index > OrderList->MaxContainers) { - break; - } - } - if (CompareMem (ReturnValue, ValueArray, Question->CurrentValue.BufferLen) == 0) { - FreePool (ReturnValue); - return EFI_DEVICE_ERROR; - } else { - gUserInput->InputValue.Buffer = ReturnValue; - gUserInput->InputValue.BufferLen = Question->CurrentValue.BufferLen; - Status = EFI_SUCCESS; - } - } else { - ASSERT (CurrentOption != NULL); - gUserInput->InputValue.Type = CurrentOption->OptionOpCode->Type; - if (IsValuesEqual (&Question->CurrentValue.Value, &CurrentOption->OptionOpCode->Value, gUserInput->InputValue.Type)) { - return EFI_DEVICE_ERROR; - } else { - SetValuesByType (&gUserInput->InputValue.Value, &CurrentOption->OptionOpCode->Value, gUserInput->InputValue.Type); - Status = EFI_SUCCESS; - } - } - - gST->ConOut->SetAttribute (gST->ConOut, SavedAttribute); - - return ValidateQuestion (Question); - - default: - break; - } - } while (TRUE); - -} - -- cgit v1.2.3