Home | History | Annotate | Download | only in InteractiveIO
      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