mirror of https://github.com/acidanthera/audk.git
324 lines
7.5 KiB
C
324 lines
7.5 KiB
C
/** @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);
|
|
}
|