StdLib: Add terminal type line editing (Interactive IO) for console devices.
Adds a subset of the terminal I/O capabilities described in the Single Unix Specification, V4. Supports: Erase previous character. Default is Backspace or ^H Erase line. Default is ^U TAB characters are supported and, by default, are rendered as 8 spaces. They will still be read as a single TAB character. Both Canonical and Non-Canonical modes are supported. If a terminal device is opened with O_TTY_INIT in the mode, the device will be initialized to "sane" values for interactive use. It will be in Canonical mode, Enter will be translated to NewLine and on output, a NewLine is translated to CRLF. Echoing will be on, control characters are output as ^X, and TABs are expanded. See the new <sys/termios.h> file for more information. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: daryl.mcdaniel@intel.com Reviewed-by: erik.c.bjorge@intel.com Reviewed-by: leroy.p.leahy@intel.com Reviewed-by: lee.g.rosenbaum@intel.com Reviewed-by: jaben.carsey@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13989 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
141
StdLib/LibC/Uefi/InteractiveIO/IIOecho.c
Normal file
141
StdLib/LibC/Uefi/InteractiveIO/IIOecho.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/** @file
|
||||
Echo characters to an Interactive I/O Output device.
|
||||
|
||||
The functions assume that isatty() is TRUE at the time they are called.
|
||||
Since the UEFI console is a WIDE character device, these functions do all
|
||||
processing using wide characters.
|
||||
|
||||
It is the responsibility of the caller, or higher level function, to perform
|
||||
any necessary translation between wide and narrow characters.
|
||||
|
||||
Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
|
||||
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 <Uefi.h>
|
||||
|
||||
#include <LibConfig.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/termios.h>
|
||||
#include <Device/IIO.h>
|
||||
#include "IIOutilities.h"
|
||||
#include "IIOechoCtrl.h"
|
||||
|
||||
/** Echo one character to an IIO file.
|
||||
|
||||
If character InCh is a special "echo control" character, process it and output
|
||||
the resultant character(s), if any. Otherwise pass the character on to the
|
||||
IIO_WriteOne() function which performs generic output processing, if needed.
|
||||
|
||||
@param[in] filp Pointer to an open IIO file's file descriptor structure.
|
||||
@param[in] InCh The wide character to be echoed.
|
||||
@param[in] EchoIsOK A flag indicating whether echoing is appropriate for this
|
||||
device or not.
|
||||
|
||||
@retval -1 The filp argument does not refer to an IIO device.
|
||||
Global value errno is set to EINVAL.
|
||||
@retval >=0 The number of characters actually output.
|
||||
|
||||
@sa IIO_WriteOne
|
||||
**/
|
||||
ssize_t
|
||||
IIO_EchoOne (
|
||||
struct __filedes *filp,
|
||||
wchar_t InCh,
|
||||
BOOLEAN EchoIsOK
|
||||
)
|
||||
{
|
||||
cIIO *This;
|
||||
cFIFO *OutBuf;
|
||||
cFIFO *InBuf;
|
||||
UINT8 *AttrBuf;
|
||||
ssize_t NumEcho;
|
||||
tcflag_t LFlags;
|
||||
UINT32 AttrDex;
|
||||
int i;
|
||||
|
||||
NumEcho = -1;
|
||||
This = filp->devdata;
|
||||
|
||||
if(This != NULL) {
|
||||
LFlags = This->Termio.c_lflag;
|
||||
OutBuf = This->OutBuf;
|
||||
InBuf = This->InBuf;
|
||||
AttrBuf = This->AttrBuf;
|
||||
AttrDex = InBuf->GetWDex(InBuf);
|
||||
|
||||
switch(InCh) {
|
||||
case IIO_ECHO_DISCARD:
|
||||
// Do not buffer or otherwise process
|
||||
NumEcho = 0;
|
||||
break;
|
||||
|
||||
case IIO_ECHO_ERASE:
|
||||
// Delete last character from InBuf
|
||||
if(!InBuf->IsEmpty(InBuf)) {
|
||||
(void)InBuf->Truncate(InBuf);
|
||||
|
||||
// Erase screen character(s) based on Attrib value
|
||||
if(LFlags & ECHO) {
|
||||
AttrDex = (UINT32)ModuloDecrement(AttrDex, InBuf->NumElements);
|
||||
NumEcho = AttrBuf[AttrDex];
|
||||
for(i = 0; i < NumEcho; ++i) {
|
||||
(void)IIO_WriteOne(filp, OutBuf, CHAR_BACKSPACE);
|
||||
}
|
||||
if(LFlags & ECHOE) {
|
||||
for(i = 0; i < NumEcho; ++i) {
|
||||
(void)IIO_WriteOne(filp, OutBuf, L' ');
|
||||
}
|
||||
for(i = 0; i < NumEcho; ++i) {
|
||||
(void)IIO_WriteOne(filp, OutBuf, CHAR_BACKSPACE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
NumEcho = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IIO_ECHO_KILL:
|
||||
// Flush contents of InBuf and OutBuf
|
||||
InBuf->Flush(InBuf, (size_t)-1);
|
||||
OutBuf->Flush(OutBuf, (size_t)-1);
|
||||
|
||||
// Erase characters from screen.
|
||||
if(LFlags & ECHOE) {
|
||||
NumEcho = IIO_CursorDelta(This, &This->InitialXY, &This->CurrentXY);
|
||||
for(i = 0; i < NumEcho; ++i) {
|
||||
(void)IIO_WriteOne(filp, OutBuf, L' ');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Add character to input buffer
|
||||
(void)InBuf->Write(InBuf, &InCh, 1);
|
||||
|
||||
NumEcho = 0; // In case echoing is not enabled or OK
|
||||
// If echoing is OK and enabled, "echo" character using IIO_WriteOne
|
||||
if( EchoIsOK &&
|
||||
( (LFlags & ECHO) ||
|
||||
((LFlags & ECHONL) && (InCh == CHAR_LINEFEED))))
|
||||
{
|
||||
NumEcho = IIO_WriteOne(filp, OutBuf, InCh);
|
||||
}
|
||||
AttrBuf[AttrDex] = (UINT8)NumEcho;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errno = EINVAL;
|
||||
}
|
||||
return NumEcho;
|
||||
}
|
Reference in New Issue
Block a user