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;
 | |
| }
 |