diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c new file mode 100644 index 00000000..ff683e45 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/ShellPkg/Library/UefiShellDebug1CommandsLib/EditInputBar.c @@ -0,0 +1,324 @@ +/** @file + Implements inputbar interface functions. + + Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved. <BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "EditInputBar.h" +#include "UefiShellDebug1CommandsLib.h" + +CHAR16 *mPrompt; // Input bar mPrompt string. +CHAR16 *mReturnString; // The returned string. +UINTN StringSize; // Size of mReturnString space size. +EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *mTextInEx; + +/** + Initialize the input bar. + + @param[in] TextInEx Pointer to SimpleTextInEx instance in System Table. +**/ +VOID +InputBarInit ( + IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TextInEx + ) +{ + mPrompt = NULL; + mReturnString = NULL; + StringSize = 0; + mTextInEx = TextInEx; +} + +/** + Cleanup function for input bar. +**/ +VOID +InputBarCleanup ( + VOID + ) +{ + // + // free input bar's prompt and input string + // + SHELL_FREE_NON_NULL (mPrompt); + SHELL_FREE_NON_NULL (mReturnString); + mPrompt = NULL; + mReturnString = NULL; +} + +/** + Display the prompt. + Do the requesting of input. + + @param[in] LastColumn The last printable column. + @param[in] LastRow The last printable row. +**/ +VOID +InputBarPrintInput ( + IN UINTN LastColumn, + IN UINTN LastRow + ) +{ + UINTN Limit; + UINTN Size; + CHAR16 *Buffer; + UINTN Index; + UINTN mPromptLen; + + mPromptLen = StrLen (mPrompt); + Limit = LastColumn - mPromptLen - 1; + Size = StrLen (mReturnString); + + // + // check whether the mPrompt length and input length will + // exceed limit + // + if (Size <= Limit) { + Buffer = mReturnString; + } else { + Buffer = mReturnString + Size - Limit; + } + + gST->ConOut->EnableCursor (gST->ConOut, FALSE); + + ShellPrintEx (((INT32)mPromptLen), ((INT32)LastRow) - 1, L"%s", Buffer); + Size = StrLen (Buffer); + + // + // print " " after mPrompt + // + for (Index = Size; Index < Limit; Index++) { + ShellPrintEx ((INT32)(mPromptLen + Size), ((INT32)LastRow) - 1, L" "); + } + + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + gST->ConOut->SetCursorPosition (gST->ConOut, Size + mPromptLen, LastRow - 1); +} + +typedef struct { + UINT32 Foreground : 4; + UINT32 Background : 3; +} INPUT_BAR_COLOR_ATTRIBUTES; + +typedef union { + INPUT_BAR_COLOR_ATTRIBUTES Colors; + UINTN Data; +} INPUT_BAR_COLOR_UNION; + + +/** + The refresh function for InputBar, it will wait for user input + + @param[in] LastRow The last printable row. + @param[in] LastColumn The last printable column. + + @retval EFI_SUCCESS The operation was successful. +**/ +EFI_STATUS +InputBarRefresh ( + UINTN LastRow, + UINTN LastColumn + ) +{ + INPUT_BAR_COLOR_UNION Orig; + INPUT_BAR_COLOR_UNION New; + EFI_KEY_DATA KeyData; + UINTN Size; + EFI_STATUS Status; + BOOLEAN NoDisplay; + UINTN EventIndex; + UINTN CursorRow; + UINTN CursorCol; + + // + // variable initialization + // + Size = 0; + Status = EFI_SUCCESS; + + // + // back up the old screen attributes + // + CursorCol = gST->ConOut->Mode->CursorColumn; + CursorRow = gST->ConOut->Mode->CursorRow; + Orig.Data = gST->ConOut->Mode->Attribute; + New.Data = 0; + New.Colors.Foreground = Orig.Colors.Background & 0xF; + New.Colors.Background = Orig.Colors.Foreground & 0x7; + + gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F); + + // + // clear input bar + // + EditorClearLine (LastRow , LastColumn, LastRow); + + gST->ConOut->SetCursorPosition (gST->ConOut, 0, LastRow - 1); + ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN(STR_EDIT_LIBINPUTBAR_MAININPUTBAR), gShellDebug1HiiHandle, mPrompt); + + // + // this is a selection mPrompt, cursor will stay in edit area + // actually this is for search , search/replace + // + if (StrStr (mPrompt, L"Yes/No")) { + NoDisplay = TRUE; + gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow); + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + } else { + NoDisplay = FALSE; + } + // + // wait for user input + // + for (;;) { + Status = gBS->WaitForEvent (1, &mTextInEx->WaitForKeyEx, &EventIndex); + if (EFI_ERROR (Status) || (EventIndex != 0)) { + continue; + } + Status = mTextInEx->ReadKeyStrokeEx (mTextInEx, &KeyData); + if (EFI_ERROR (Status)) { + continue; + } + if (((KeyData.KeyState.KeyShiftState & EFI_SHIFT_STATE_VALID) != 0) && + (KeyData.KeyState.KeyShiftState != EFI_SHIFT_STATE_VALID)) { + // + // Shift key pressed. + // + continue; + } + // + // pressed ESC + // + if (KeyData.Key.ScanCode == SCAN_ESC) { + Size = 0; + Status = EFI_NOT_READY; + break; + } + // + // return pressed + // + if (KeyData.Key.UnicodeChar == CHAR_LINEFEED || KeyData.Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { + break; + } else if (KeyData.Key.UnicodeChar == CHAR_BACKSPACE) { + // + // backspace + // + if (Size > 0) { + Size--; + mReturnString[Size] = CHAR_NULL; + if (!NoDisplay) { + + InputBarPrintInput (LastColumn, LastRow); + + } + } + } else if (KeyData.Key.UnicodeChar <= 127 && KeyData.Key.UnicodeChar >= 32) { + // + // VALID ASCII char pressed + // + mReturnString[Size] = KeyData.Key.UnicodeChar; + + // + // should be less than specified length + // + if (Size >= StringSize) { + continue; + } + + Size++; + + mReturnString[Size] = CHAR_NULL; + + if (!NoDisplay) { + + InputBarPrintInput (LastColumn, LastRow); + + } else { + // + // if just choose yes/no + // + break; + } + + } + } + + mReturnString[Size] = CHAR_NULL; + + + // + // restore screen attributes + // + gST->ConOut->SetCursorPosition (gST->ConOut, CursorCol, CursorRow); + gST->ConOut->SetAttribute (gST->ConOut, Orig.Data); + + return Status; +} + +/** + SetPrompt and wait for input. + + @param[in] Str The prompt string. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +InputBarSetPrompt ( + IN CONST CHAR16 *Str + ) +{ + // + // FREE the old mPrompt string + // + SHELL_FREE_NON_NULL (mPrompt); + + mPrompt = CatSPrint (NULL, L"%s ", Str); + if (mPrompt == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Set the size of the string in characters. + + @param[in] Size The max number of characters to accept. + + @retval EFI_SUCCESS The operation was successful. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. +**/ +EFI_STATUS +InputBarSetStringSize ( + UINTN Size + ) +{ + // + // free the old ReturnStirng + // + SHELL_FREE_NON_NULL (mReturnString); + + StringSize = Size; + mReturnString = AllocateZeroPool ((StringSize + 1) * sizeof(mReturnString[0])); + if (mReturnString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Function to retrieve the input from the user. + + @retval NULL No input has been received. + @return The string that was input. +**/ +CONST CHAR16* +InputBarGetString ( + VOID + ) +{ + return (mReturnString); +} |