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