1 /** @file 2 Echo characters to an Interactive I/O Output device. 3 4 The functions assume that isatty() is TRUE at the time they are called. 5 Since the UEFI console is a WIDE character device, these functions do all 6 processing using wide characters. 7 8 It is the responsibility of the caller, or higher level function, to perform 9 any necessary translation between wide and narrow characters. 10 11 Copyright (c) 2012, Intel Corporation. All rights reserved.<BR> 12 This program and the accompanying materials are licensed and made available 13 under the terms and conditions of the BSD License which accompanies this 14 distribution. The full text of the license may be found at 15 http://opensource.org/licenses/bsd-license.php. 16 17 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 18 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 19 **/ 20 #include <Uefi.h> 21 22 #include <LibConfig.h> 23 24 #include <assert.h> 25 #include <errno.h> 26 #include <sys/termios.h> 27 #include <Device/IIO.h> 28 #include "IIOutilities.h" 29 #include "IIOechoCtrl.h" 30 31 /** Echo one character to an IIO file. 32 33 If character InCh is a special "echo control" character, process it and output 34 the resultant character(s), if any. Otherwise pass the character on to the 35 IIO_WriteOne() function which performs generic output processing, if needed. 36 37 @param[in] filp Pointer to an open IIO file's file descriptor structure. 38 @param[in] InCh The wide character to be echoed. 39 @param[in] EchoIsOK A flag indicating whether echoing is appropriate for this 40 device or not. 41 42 @retval -1 The filp argument does not refer to an IIO device. 43 Global value errno is set to EINVAL. 44 @retval >=0 The number of characters actually output. 45 46 @sa IIO_WriteOne 47 **/ 48 ssize_t 49 IIO_EchoOne ( 50 struct __filedes *filp, 51 wchar_t InCh, 52 BOOLEAN EchoIsOK 53 ) 54 { 55 cIIO *This; 56 cFIFO *OutBuf; 57 cFIFO *InBuf; 58 UINT8 *AttrBuf; 59 ssize_t NumEcho; 60 tcflag_t LFlags; 61 UINT32 AttrDex; 62 int i; 63 64 NumEcho = -1; 65 This = filp->devdata; 66 67 if(This != NULL) { 68 LFlags = This->Termio.c_lflag; 69 OutBuf = This->OutBuf; 70 InBuf = This->InBuf; 71 AttrBuf = This->AttrBuf; 72 AttrDex = InBuf->GetWDex(InBuf); 73 74 switch(InCh) { 75 case IIO_ECHO_DISCARD: 76 // Do not buffer or otherwise process 77 NumEcho = 0; 78 break; 79 80 case IIO_ECHO_ERASE: 81 // Delete last character from InBuf 82 if(!InBuf->IsEmpty(InBuf)) { 83 (void)InBuf->Truncate(InBuf); 84 85 // Erase screen character(s) based on Attrib value 86 if(LFlags & ECHO) { 87 AttrDex = (UINT32)ModuloDecrement(AttrDex, InBuf->NumElements); 88 NumEcho = AttrBuf[AttrDex]; 89 for(i = 0; i < NumEcho; ++i) { 90 (void)IIO_WriteOne(filp, OutBuf, CHAR_BACKSPACE); 91 } 92 if(LFlags & ECHOE) { 93 for(i = 0; i < NumEcho; ++i) { 94 (void)IIO_WriteOne(filp, OutBuf, L' '); 95 } 96 for(i = 0; i < NumEcho; ++i) { 97 (void)IIO_WriteOne(filp, OutBuf, CHAR_BACKSPACE); 98 } 99 } 100 } 101 else { 102 NumEcho = 0; 103 } 104 } 105 break; 106 107 case IIO_ECHO_KILL: 108 // Flush contents of InBuf and OutBuf 109 InBuf->Flush(InBuf, (size_t)-1); 110 OutBuf->Flush(OutBuf, (size_t)-1); 111 112 // Erase characters from screen. 113 if(LFlags & ECHOE) { 114 NumEcho = IIO_CursorDelta(This, &This->InitialXY, &This->CurrentXY); 115 for(i = 0; i < NumEcho; ++i) { 116 (void)IIO_WriteOne(filp, OutBuf, L' '); 117 } 118 } 119 break; 120 121 default: 122 // Add character to input buffer 123 (void)InBuf->Write(InBuf, &InCh, 1); 124 125 NumEcho = 0; // In case echoing is not enabled or OK 126 // If echoing is OK and enabled, "echo" character using IIO_WriteOne 127 if( EchoIsOK && 128 ( (LFlags & ECHO) || 129 ((LFlags & ECHONL) && (InCh == CHAR_LINEFEED)))) 130 { 131 NumEcho = IIO_WriteOne(filp, OutBuf, InCh); 132 } 133 AttrBuf[AttrDex] = (UINT8)NumEcho; 134 break; 135 } 136 } 137 else { 138 errno = EINVAL; 139 } 140 return NumEcho; 141 } 142