blob: 0b25965427806de71047d7dcdb3755c0a40dbc04 [file] [log] [blame]
/** @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);
}