darylm503 6c6c850ad6 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
2012-12-11 21:19:14 +00:00

142 lines
4.4 KiB
C

/** @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;
}