Removed variables that had no effect on code behavior. Fifo.c::FIFO_Dequeue: Replaced instances of "Self->ElementSize" with preexisting variable "SizeOfElement". IIOutilities.c::IIO_GetInChar: Fixed variable of wrong, but compatible, type and made updating of housekeeping variables dependent upon successful completion of reading from the buffer. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <olivier.martin@arm.com> Reviewed by: Daryl McDaniel <daryl.mcdaniel@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16276 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			291 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			291 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Utilities for Interactive I/O Functions.
 | 
						|
 | 
						|
  The functions assume that isatty() is TRUE at the time they are called.
 | 
						|
 | 
						|
  Copyright (c) 2012 - 2014, 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  <Protocol/SimpleTextOut.h>
 | 
						|
 | 
						|
#include  <LibConfig.h>
 | 
						|
 | 
						|
#include  <assert.h>
 | 
						|
#include  <errno.h>
 | 
						|
#include  <sys/syslimits.h>
 | 
						|
#include  <sys/termios.h>
 | 
						|
#include  <Device/IIO.h>
 | 
						|
#include  <MainData.h>
 | 
						|
#include  "IIOutilities.h"
 | 
						|
 | 
						|
/** Get the low-level UEFI protocol associated with an open file.
 | 
						|
 | 
						|
    @param[in]    fd    File descriptor for an open file.
 | 
						|
    @param[out]   filp  NULL, or a pointer to where a pointer to the file's
 | 
						|
                        file descriptor structure is to be stored.
 | 
						|
 | 
						|
    @return   Returns NULL if fd is not a valid file descriptor, otherwise
 | 
						|
              a pointer to the file's associated UEFI protocol is returned.
 | 
						|
**/
 | 
						|
void *
 | 
						|
EFIAPI
 | 
						|
IIO_GetDeviceProto (
 | 
						|
  int                 fd,
 | 
						|
  struct __filedes  **filp
 | 
						|
  )
 | 
						|
{
 | 
						|
  void               *Proto;
 | 
						|
  ConInstance        *Stream;
 | 
						|
  struct __filedes   *pfil;
 | 
						|
 | 
						|
  Proto = NULL;
 | 
						|
  if(ValidateFD( fd, VALID_OPEN)) {
 | 
						|
    pfil = &gMD->fdarray[fd];
 | 
						|
    Stream = BASE_CR(pfil->f_ops, ConInstance, Abstraction);
 | 
						|
    Proto = (void *)Stream->Dev;
 | 
						|
    if(filp != NULL) {
 | 
						|
      *filp = pfil;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return Proto;
 | 
						|
}
 | 
						|
 | 
						|
/** Get a character either from the input buffer or from hardware.
 | 
						|
 | 
						|
    @param[in]    filp      Pointer to a file descriptor structure.
 | 
						|
    @param[in]    First     Set to TRUE to identify the initial read.
 | 
						|
 | 
						|
    @return   Returns a character read from either the input buffer
 | 
						|
              or from the open file (device) identified by filp.
 | 
						|
              A return value of WEOF indicates an error has occurred.
 | 
						|
**/
 | 
						|
wint_t
 | 
						|
EFIAPI
 | 
						|
IIO_GetInChar (
 | 
						|
  struct __filedes *filp,
 | 
						|
  BOOLEAN           First
 | 
						|
)
 | 
						|
{
 | 
						|
  cIIO             *This;
 | 
						|
  cFIFO            *InBuf;
 | 
						|
  size_t            Status;
 | 
						|
  ssize_t           NumRead;
 | 
						|
  wint_t            RetVal;
 | 
						|
  wchar_t           InChar;
 | 
						|
 | 
						|
  static size_t     BufCnt;
 | 
						|
 | 
						|
  This      = filp->devdata;
 | 
						|
  InBuf     = This->InBuf;
 | 
						|
 | 
						|
  NumRead = -1;
 | 
						|
  InChar  =  0;
 | 
						|
  if(First) {
 | 
						|
    BufCnt = InBuf->Count(InBuf, AsElements);
 | 
						|
  }
 | 
						|
  if(BufCnt > 0) {
 | 
						|
    Status = InBuf->Read(InBuf, &InChar, 1);
 | 
						|
    if (Status > 0) {
 | 
						|
      --BufCnt;
 | 
						|
      NumRead = 1;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    NumRead = filp->f_ops->fo_read(filp, &filp->f_offset, sizeof(wchar_t), &InChar);
 | 
						|
  }
 | 
						|
  if(NumRead <= 0) {
 | 
						|
    RetVal = WEOF;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    RetVal = (wint_t)InChar;
 | 
						|
  }
 | 
						|
  return RetVal;
 | 
						|
}
 | 
						|
 | 
						|
/** Get the current cursor position.
 | 
						|
 | 
						|
    @param[in]      fd      File descriptor for an open file.
 | 
						|
    @param[out]     Column  Pointer to where the current cursor column is to be stored.
 | 
						|
    @param[out]     Row     Pointer to where the current cursor row is to be stored.
 | 
						|
 | 
						|
    @retval   -1    fd is not an IIO output device.
 | 
						|
    @retval    0    Cursor position retrieved, Cursor is Not Visible.
 | 
						|
    @retval    1    Cursor position retrieved, Cursor is Visible.
 | 
						|
**/
 | 
						|
int
 | 
						|
EFIAPI
 | 
						|
IIO_GetCursorPosition (
 | 
						|
  int       fd,
 | 
						|
  UINT32   *Column,
 | 
						|
  UINT32   *Row
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *Proto;
 | 
						|
  struct __filedes                   *pStdOut;
 | 
						|
  int                                 RetVal;
 | 
						|
 | 
						|
  RetVal    = -1;
 | 
						|
 | 
						|
  Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)IIO_GetDeviceProto(fd, &pStdOut);
 | 
						|
  if(Proto != NULL) {
 | 
						|
    if(((pStdOut->f_iflags & _S_ITTY) != 0) &&    // file is a TTY
 | 
						|
       ((pStdOut->Oflags & O_ACCMODE) != 0))      // and it is open for output
 | 
						|
    {
 | 
						|
      // fd is for a TTY or "Interactive IO" device
 | 
						|
      *Column  = Proto->Mode->CursorColumn;
 | 
						|
      *Row     = Proto->Mode->CursorRow;
 | 
						|
      if(Proto->Mode->CursorVisible) {
 | 
						|
        RetVal = 1;
 | 
						|
      }
 | 
						|
      else {
 | 
						|
        RetVal = 0;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return RetVal;
 | 
						|
}
 | 
						|
 | 
						|
/** Set the cursor position.
 | 
						|
 | 
						|
    @param[in]    filp    Pointer to the output device's file descriptor structure.
 | 
						|
    @param[in]    StartXY Pointer to a cursor coordinate (XY) structure indicating
 | 
						|
                          the desired coordinate to move the cursor to.
 | 
						|
 | 
						|
    @retval   -1    fd is not an IIO output device
 | 
						|
    @retval    0    Cursor position set successfully.
 | 
						|
**/
 | 
						|
int
 | 
						|
EFIAPI
 | 
						|
IIO_SetCursorPosition (
 | 
						|
  struct __filedes *filp,
 | 
						|
  CURSOR_XY        *CursorXY
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *Proto;
 | 
						|
  cIIO                               *This;
 | 
						|
  EFI_STATUS                          Status;
 | 
						|
  int                                 RetVal;
 | 
						|
 | 
						|
  RetVal    = -1;
 | 
						|
 | 
						|
  This = filp->devdata;
 | 
						|
  Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)IIO_GetDeviceProto(filp->MyFD, NULL);
 | 
						|
  if(Proto != NULL) {
 | 
						|
    if(((filp->f_iflags & _S_ITTY) != 0) &&    // file is a TTY
 | 
						|
       ((filp->Oflags & O_ACCMODE) != 0))      // and it is open for output
 | 
						|
    {
 | 
						|
      // fd is for a TTY or "Interactive IO" device
 | 
						|
      Status = Proto->SetCursorPosition(Proto, CursorXY->Column, CursorXY->Row);
 | 
						|
      if(Status == EFI_SUCCESS) {
 | 
						|
        This->CurrentXY.Column  = CursorXY->Column;
 | 
						|
        This->CurrentXY.Row     = CursorXY->Row;
 | 
						|
        RetVal = 0;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return RetVal;
 | 
						|
}
 | 
						|
 | 
						|
/** Get Output screen size and mode.
 | 
						|
 | 
						|
    @param[in]    fd    File descriptor of the output device.
 | 
						|
    @param[out]   Col   Pointer to where to store the MAX Column, or NULL.
 | 
						|
    @param[out]   Row   Pointer to where to store the MAX Row, or NULL.
 | 
						|
 | 
						|
    @retval   <0    An error occurred.  The reason is in errno and EFIerrno.
 | 
						|
                      * EIO     UEFI QueryMode failed
 | 
						|
                      * ENOTTY  fd does not refer to an interactive output device
 | 
						|
    @retval   >=0   Current output mode
 | 
						|
**/
 | 
						|
int
 | 
						|
EFIAPI
 | 
						|
IIO_GetOutputSize (
 | 
						|
  int       fd,
 | 
						|
  UINTN    *Col,
 | 
						|
  UINTN    *Row
 | 
						|
)
 | 
						|
{
 | 
						|
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL    *Proto;
 | 
						|
  struct __filedes                   *pStdOut;
 | 
						|
  EFI_STATUS                          Status;
 | 
						|
  UINTN                               TempCol;
 | 
						|
  UINTN                               TempRow;
 | 
						|
  UINTN                               TempMode;
 | 
						|
  int                                 RetVal;
 | 
						|
 | 
						|
  RetVal    = -1;
 | 
						|
 | 
						|
  Proto = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)IIO_GetDeviceProto(fd, &pStdOut);
 | 
						|
  if(Proto != NULL) {
 | 
						|
    if(((pStdOut->f_iflags & _S_ITTY) != 0)   &&    // file is a TTY
 | 
						|
        ((pStdOut->Oflags & O_ACCMODE) != 0))       // and it is open for output
 | 
						|
    {
 | 
						|
      // fd is for a TTY or "Interactive IO" device
 | 
						|
      TempMode = Proto->Mode->Mode;
 | 
						|
      Status = Proto->QueryMode(Proto, TempMode, &TempCol, &TempRow);
 | 
						|
      if(EFI_ERROR(Status)) {
 | 
						|
        EFIerrno  = Status;
 | 
						|
        errno     = EIO;
 | 
						|
      }
 | 
						|
      else {
 | 
						|
        *Col    = TempCol;
 | 
						|
        *Row    = TempRow;
 | 
						|
        RetVal  = (int)TempMode;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      errno = ENOTTY;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return RetVal;
 | 
						|
}
 | 
						|
 | 
						|
/** Calculate the number of character positions between two X/Y coordinate pairs.
 | 
						|
 | 
						|
    Using the current output device characteristics, calculate the number of
 | 
						|
    characters between two coordinates.  It is assumed that EndXY points to
 | 
						|
    an output location that occurs after StartXY.
 | 
						|
 | 
						|
    RowDelta is the computed difference between the ending and starting rows.
 | 
						|
    If RowDelta < 0, then EndXY is NOT after StartXY, so assert.
 | 
						|
 | 
						|
    ColumnDelta is the computed number of character positions (columns) between
 | 
						|
    the starting position and the ending position.  If ColumnDelta is < 0,
 | 
						|
    then EndXY is NOT after StartXY, so assert.
 | 
						|
 | 
						|
    @param[in]      This      Pointer to the IIO instance to be examined.
 | 
						|
    @param[in]      StartXY   Pointer to the starting coordinate pair.
 | 
						|
    @param[in]      EndXY     Pointer to the ending coordinate pair.
 | 
						|
 | 
						|
    @return   Returns the difference between the starting and ending coordinates.
 | 
						|
              The return value is positive if the coordinates contained in EndXY
 | 
						|
              are larger than StartXY, otherwise the return value is negative.
 | 
						|
**/
 | 
						|
int
 | 
						|
EFIAPI
 | 
						|
IIO_CursorDelta (
 | 
						|
  cIIO         *This,
 | 
						|
  CURSOR_XY    *StartXY,
 | 
						|
  CURSOR_XY    *EndXY
 | 
						|
)
 | 
						|
{
 | 
						|
  int    ColumnDelta;
 | 
						|
  int    RowDelta;
 | 
						|
 | 
						|
  RowDelta = (int)EndXY->Row - (int)StartXY->Row;
 | 
						|
 | 
						|
  assert(RowDelta >= 0);    // assert if EndXY is NOT after StartXY
 | 
						|
 | 
						|
  ColumnDelta = (int)((This->MaxColumn * RowDelta) + EndXY->Column);
 | 
						|
  ColumnDelta -= (int)StartXY->Column;
 | 
						|
 | 
						|
  return ColumnDelta;
 | 
						|
}
 |