https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Hao Wu <hao.a.wu@intel.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
		
			
				
	
	
		
			755 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			755 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
 | 
						|
Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "Edb.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Set the current coordinates of the cursor position.
 | 
						|
 | 
						|
  @param  ConOut        Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
 | 
						|
  @param  Column        The position to set the cursor to.
 | 
						|
  @param  Row           The position to set the cursor to.
 | 
						|
  @param  LineLength    Length of a line.
 | 
						|
  @param  TotalRow      Total row of a screen.
 | 
						|
  @param  Str           Point to the string.
 | 
						|
  @param  StrPos        The position of the string.
 | 
						|
  @param  Len           The length of the string.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SetCursorPosition (
 | 
						|
  IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *ConOut,
 | 
						|
  IN  UINTN                           Column,
 | 
						|
  IN  INTN                            Row,
 | 
						|
  IN  UINTN                           LineLength,
 | 
						|
  IN  UINTN                           TotalRow,
 | 
						|
  IN  CHAR16                          *Str,
 | 
						|
  IN  UINTN                           StrPos,
 | 
						|
  IN  UINTN                           Len
 | 
						|
  );
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Function waits for a given event to fire, or for an optional timeout to expire.
 | 
						|
 | 
						|
  @param  Event            - The event to wait for
 | 
						|
  @param  Timeout          - An optional timeout value in 100 ns units.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       - Event fired before Timeout expired.
 | 
						|
  @retval EFI_TIME_OUT     - Timout expired before Event fired..
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
WaitForSingleEvent (
 | 
						|
  IN EFI_EVENT                  Event,
 | 
						|
  IN UINT64                     Timeout OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINTN       Index;
 | 
						|
  EFI_EVENT   TimerEvent;
 | 
						|
  EFI_EVENT   WaitList[2];
 | 
						|
 | 
						|
  if (Timeout != 0) {
 | 
						|
    //
 | 
						|
    // Create a timer event
 | 
						|
    //
 | 
						|
    Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // Set the timer event
 | 
						|
      //
 | 
						|
      gBS->SetTimer (
 | 
						|
            TimerEvent,
 | 
						|
            TimerRelative,
 | 
						|
            Timeout
 | 
						|
            );
 | 
						|
 | 
						|
      //
 | 
						|
      // Wait for the original event or the timer
 | 
						|
      //
 | 
						|
      WaitList[0] = Event;
 | 
						|
      WaitList[1] = TimerEvent;
 | 
						|
      Status      = gBS->WaitForEvent (2, WaitList, &Index);
 | 
						|
      gBS->CloseEvent (TimerEvent);
 | 
						|
 | 
						|
      //
 | 
						|
      // If the timer expired, change the return to timed out
 | 
						|
      //
 | 
						|
      if (!EFI_ERROR (Status) && Index == 1) {
 | 
						|
        Status = EFI_TIMEOUT;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // No timeout... just wait on the event
 | 
						|
    //
 | 
						|
    Status = gBS->WaitForEvent (1, &Event, &Index);
 | 
						|
    ASSERT (!EFI_ERROR (Status));
 | 
						|
    ASSERT (Index == 0);
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Move the cursor position one character backward.
 | 
						|
 | 
						|
  @param  LineLength       Length of a line. Get it by calling QueryMode
 | 
						|
  @param  Column           Current column of the cursor position
 | 
						|
  @param  Row              Current row of the cursor position
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
ConMoveCursorBackward (
 | 
						|
  IN     UINTN                   LineLength,
 | 
						|
  IN OUT UINTN                   *Column,
 | 
						|
  IN OUT UINTN                   *Row
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (Column != NULL);
 | 
						|
  ASSERT (Row != NULL);
 | 
						|
  //
 | 
						|
  // If current column is 0, move to the last column of the previous line,
 | 
						|
  // otherwise, just decrement column.
 | 
						|
  //
 | 
						|
  if (*Column == 0) {
 | 
						|
    (*Column) = LineLength - 1;
 | 
						|
    //
 | 
						|
    //   if (*Row > 0) {
 | 
						|
    //
 | 
						|
    (*Row)--;
 | 
						|
    //
 | 
						|
    // }
 | 
						|
    //
 | 
						|
  } else {
 | 
						|
    (*Column)--;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Move the cursor position one character backward.
 | 
						|
 | 
						|
  @param  LineLength       Length of a line. Get it by calling QueryMode
 | 
						|
  @param  TotalRow         Total row of a screen, get by calling QueryMode
 | 
						|
  @param  Column           Current column of the cursor position
 | 
						|
  @param  Row              Current row of the cursor position
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
ConMoveCursorForward (
 | 
						|
  IN     UINTN                   LineLength,
 | 
						|
  IN     UINTN                   TotalRow,
 | 
						|
  IN OUT UINTN                   *Column,
 | 
						|
  IN OUT UINTN                   *Row
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (Column != NULL);
 | 
						|
  ASSERT (Row != NULL);
 | 
						|
  //
 | 
						|
  // If current column is at line end, move to the first column of the nest
 | 
						|
  // line, otherwise, just increment column.
 | 
						|
  //
 | 
						|
  (*Column)++;
 | 
						|
  if (*Column >= LineLength) {
 | 
						|
    (*Column) = 0;
 | 
						|
    if ((*Row) < TotalRow - 1) {
 | 
						|
      (*Row)++;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
CHAR16 mBackupSpace[EFI_DEBUG_INPUS_BUFFER_SIZE];
 | 
						|
CHAR16 mInputBufferHistory[EFI_DEBUG_INPUS_BUFFER_SIZE];
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  Get user input.
 | 
						|
 | 
						|
  @param  Prompt       The prompt string.
 | 
						|
  @param  InStr        Point to the input string.
 | 
						|
  @param  StrLength    The max length of string user can input.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
Input (
 | 
						|
  IN CHAR16    *Prompt OPTIONAL,
 | 
						|
  OUT CHAR16   *InStr,
 | 
						|
  IN UINTN     StrLength
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL     *ConOut;
 | 
						|
  EFI_SIMPLE_TEXT_INPUT_PROTOCOL      *ConIn;
 | 
						|
  BOOLEAN       Done;
 | 
						|
  UINTN         Column;
 | 
						|
  UINTN         Row;
 | 
						|
  UINTN         StartColumn;
 | 
						|
  UINTN         Update;
 | 
						|
  UINTN         Delete;
 | 
						|
  UINTN         Len;
 | 
						|
  UINTN         StrPos;
 | 
						|
  UINTN         Index;
 | 
						|
  UINTN         LineLength;
 | 
						|
  UINTN         TotalRow;
 | 
						|
  UINTN         SkipLength;
 | 
						|
  UINTN         OutputLength;
 | 
						|
  UINTN         TailRow;
 | 
						|
  UINTN         TailColumn;
 | 
						|
  EFI_INPUT_KEY Key;
 | 
						|
  BOOLEAN       InsertMode;
 | 
						|
  BOOLEAN       NeedAdjust;
 | 
						|
  UINTN         SubIndex;
 | 
						|
  CHAR16        *CommandStr;
 | 
						|
 | 
						|
  ConOut = gST->ConOut;
 | 
						|
  ConIn = gST->ConIn;
 | 
						|
 | 
						|
  ASSERT (ConOut != NULL);
 | 
						|
  ASSERT (ConIn != NULL);
 | 
						|
  ASSERT (InStr != NULL);
 | 
						|
 | 
						|
  if (Prompt != NULL) {
 | 
						|
    ConOut->OutputString (ConOut, Prompt);
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Read a line from the console
 | 
						|
  //
 | 
						|
  Len           = 0;
 | 
						|
  StrPos        = 0;
 | 
						|
  OutputLength  = 0;
 | 
						|
  Update        = 0;
 | 
						|
  Delete        = 0;
 | 
						|
  InsertMode    = TRUE;
 | 
						|
  NeedAdjust    = FALSE;
 | 
						|
 | 
						|
  //
 | 
						|
  // If buffer is not large enough to hold a CHAR16, do nothing.
 | 
						|
  //
 | 
						|
  if (StrLength < 1) {
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Get the screen setting and the current cursor location
 | 
						|
  //
 | 
						|
  StartColumn = ConOut->Mode->CursorColumn;
 | 
						|
  Column      = StartColumn;
 | 
						|
  Row         = ConOut->Mode->CursorRow;
 | 
						|
  ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &LineLength, &TotalRow);
 | 
						|
  if (LineLength == 0) {
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
 | 
						|
  SetMem (InStr, StrLength * sizeof (CHAR16), 0);
 | 
						|
  Done = FALSE;
 | 
						|
  do {
 | 
						|
    //
 | 
						|
    // Read a key
 | 
						|
    //
 | 
						|
    WaitForSingleEvent (ConIn->WaitForKey, 0);
 | 
						|
    ConIn->ReadKeyStroke (ConIn, &Key);
 | 
						|
 | 
						|
    switch (Key.UnicodeChar) {
 | 
						|
    case CHAR_CARRIAGE_RETURN:
 | 
						|
      //
 | 
						|
      // All done, print a newline at the end of the string
 | 
						|
      //
 | 
						|
      TailRow     = Row + (Len - StrPos + Column) / LineLength;
 | 
						|
      TailColumn  = (Len - StrPos + Column) % LineLength;
 | 
						|
      Done        = TRUE;
 | 
						|
      break;
 | 
						|
 | 
						|
    case CHAR_BACKSPACE:
 | 
						|
      if (StrPos != 0) {
 | 
						|
        //
 | 
						|
        // If not move back beyond string beginning, move all characters behind
 | 
						|
        // the current position one character forward
 | 
						|
        //
 | 
						|
        StrPos -= 1;
 | 
						|
        Update  = StrPos;
 | 
						|
        Delete  = 1;
 | 
						|
        CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos));
 | 
						|
 | 
						|
        //
 | 
						|
        // Adjust the current column and row
 | 
						|
        //
 | 
						|
        ConMoveCursorBackward (LineLength, &Column, &Row);
 | 
						|
 | 
						|
        NeedAdjust = TRUE;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      if (Key.UnicodeChar >= ' ') {
 | 
						|
        //
 | 
						|
        // If we are at the buffer's end, drop the key
 | 
						|
        //
 | 
						|
        if (Len == StrLength - 1 && (InsertMode || StrPos == Len)) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        //
 | 
						|
        // If in insert mode, move all characters behind the current position
 | 
						|
        // one character backward to make space for this character. Then store
 | 
						|
        // the character.
 | 
						|
        //
 | 
						|
        if (InsertMode) {
 | 
						|
          for (Index = Len; Index > StrPos; Index -= 1) {
 | 
						|
            InStr[Index] = InStr[Index - 1];
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        InStr[StrPos] = Key.UnicodeChar;
 | 
						|
        Update        = StrPos;
 | 
						|
 | 
						|
        StrPos += 1;
 | 
						|
        OutputLength = 1;
 | 
						|
      }
 | 
						|
      break;
 | 
						|
 | 
						|
    case 0:
 | 
						|
      switch (Key.ScanCode) {
 | 
						|
      case SCAN_DELETE:
 | 
						|
        //
 | 
						|
        // Move characters behind current position one character forward
 | 
						|
        //
 | 
						|
        if (Len != 0) {
 | 
						|
          Update  = StrPos;
 | 
						|
          Delete  = 1;
 | 
						|
          CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos));
 | 
						|
 | 
						|
          NeedAdjust = TRUE;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
      case SCAN_LEFT:
 | 
						|
        //
 | 
						|
        // Adjust current cursor position
 | 
						|
        //
 | 
						|
        if (StrPos != 0) {
 | 
						|
          StrPos -= 1;
 | 
						|
          ConMoveCursorBackward (LineLength, &Column, &Row);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
      case SCAN_RIGHT:
 | 
						|
        //
 | 
						|
        // Adjust current cursor position
 | 
						|
        //
 | 
						|
        if (StrPos < Len) {
 | 
						|
          StrPos += 1;
 | 
						|
          ConMoveCursorForward (LineLength, TotalRow, &Column, &Row);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
 | 
						|
      case SCAN_HOME:
 | 
						|
        //
 | 
						|
        // Move current cursor position to the beginning of the command line
 | 
						|
        //
 | 
						|
        Row -= (StrPos + StartColumn) / LineLength;
 | 
						|
        Column  = StartColumn;
 | 
						|
        StrPos  = 0;
 | 
						|
        break;
 | 
						|
 | 
						|
      case SCAN_END:
 | 
						|
        //
 | 
						|
        // Move current cursor position to the end of the command line
 | 
						|
        //
 | 
						|
        TailRow     = Row + (Len - StrPos + Column) / LineLength;
 | 
						|
        TailColumn  = (Len - StrPos + Column) % LineLength;
 | 
						|
        Row         = TailRow;
 | 
						|
        Column      = TailColumn;
 | 
						|
        StrPos      = Len;
 | 
						|
        break;
 | 
						|
 | 
						|
      case SCAN_ESC:
 | 
						|
        //
 | 
						|
        // Prepare to clear the current command line
 | 
						|
        //
 | 
						|
        InStr[0]  = 0;
 | 
						|
        Update    = 0;
 | 
						|
        Delete    = Len;
 | 
						|
        Row -= (StrPos + StartColumn) / LineLength;
 | 
						|
        Column        = StartColumn;
 | 
						|
        OutputLength  = 0;
 | 
						|
 | 
						|
        NeedAdjust = TRUE;
 | 
						|
        break;
 | 
						|
 | 
						|
      case SCAN_INSERT:
 | 
						|
        //
 | 
						|
        // Toggle the SEnvInsertMode flag
 | 
						|
        //
 | 
						|
        InsertMode = (BOOLEAN)!InsertMode;
 | 
						|
        break;
 | 
						|
 | 
						|
      case SCAN_UP:
 | 
						|
      case SCAN_DOWN:
 | 
						|
        //
 | 
						|
        // show history
 | 
						|
        //
 | 
						|
        CopyMem (InStr, mInputBufferHistory, StrLength * sizeof(CHAR16));
 | 
						|
        StrPos       = StrLen (mInputBufferHistory);
 | 
						|
        Update       = 0;
 | 
						|
        Delete       = 0;
 | 
						|
        OutputLength = 0;
 | 
						|
 | 
						|
        TailRow      = Row + (StrPos + StartColumn) / LineLength;
 | 
						|
        TailColumn   = (StrPos + StartColumn) % LineLength;
 | 
						|
        Row          = TailRow;
 | 
						|
        Column       = TailColumn;
 | 
						|
        NeedAdjust   = FALSE;
 | 
						|
 | 
						|
        ConOut->SetCursorPosition (ConOut, StartColumn, Row);
 | 
						|
        for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) {
 | 
						|
          mBackupSpace[SubIndex] = L' ';
 | 
						|
        }
 | 
						|
        EDBPrint (mBackupSpace);
 | 
						|
        SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN)) * sizeof(CHAR16), 0);
 | 
						|
 | 
						|
        ConOut->SetCursorPosition (ConOut, StartColumn, Row);
 | 
						|
        Len = StrPos;
 | 
						|
 | 
						|
        break;
 | 
						|
 | 
						|
      case SCAN_F1:
 | 
						|
      case SCAN_F2:
 | 
						|
      case SCAN_F3:
 | 
						|
      case SCAN_F4:
 | 
						|
      case SCAN_F5:
 | 
						|
      case SCAN_F6:
 | 
						|
      case SCAN_F7:
 | 
						|
      case SCAN_F8:
 | 
						|
      case SCAN_F9:
 | 
						|
      case SCAN_F10:
 | 
						|
      case SCAN_F11:
 | 
						|
      case SCAN_F12:
 | 
						|
        CommandStr = GetCommandNameByKey (Key);
 | 
						|
        if (CommandStr != NULL) {
 | 
						|
          StrnCpyS (InStr, StrLength, CommandStr, StrLength - 1);
 | 
						|
          return ;
 | 
						|
        }
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (Done) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // If we need to update the output do so now
 | 
						|
    //
 | 
						|
    if (Update != -1) {
 | 
						|
      if (NeedAdjust) {
 | 
						|
        ConOut->SetCursorPosition (ConOut, Column, Row);
 | 
						|
        for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) {
 | 
						|
          mBackupSpace[SubIndex] = L' ';
 | 
						|
        }
 | 
						|
        EDBPrint (mBackupSpace);
 | 
						|
        SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN)) * sizeof(CHAR16), 0);
 | 
						|
        ConOut->SetCursorPosition (ConOut, Column, Row);
 | 
						|
        NeedAdjust = FALSE;
 | 
						|
      }
 | 
						|
      EDBPrint (InStr + Update);
 | 
						|
      Len = StrLen (InStr);
 | 
						|
 | 
						|
      if (Delete != 0) {
 | 
						|
        SetMem (InStr + Len, Delete * sizeof (CHAR16), 0x00);
 | 
						|
      }
 | 
						|
 | 
						|
      if (StrPos > Len) {
 | 
						|
        StrPos = Len;
 | 
						|
      }
 | 
						|
 | 
						|
      Update = (UINTN) -1;
 | 
						|
 | 
						|
      //
 | 
						|
      // After using print to reflect newly updates, if we're not using
 | 
						|
      // BACKSPACE and DELETE, we need to move the cursor position forward,
 | 
						|
      // so adjust row and column here.
 | 
						|
      //
 | 
						|
      if (Key.UnicodeChar != CHAR_BACKSPACE && !(Key.UnicodeChar == 0 && Key.ScanCode == SCAN_DELETE)) {
 | 
						|
        //
 | 
						|
        // Calulate row and column of the tail of current string
 | 
						|
        //
 | 
						|
        TailRow     = Row + (Len - StrPos + Column + OutputLength) / LineLength;
 | 
						|
        TailColumn  = (Len - StrPos + Column + OutputLength) % LineLength;
 | 
						|
 | 
						|
        //
 | 
						|
        // If the tail of string reaches screen end, screen rolls up, so if
 | 
						|
        // Row does not equal TailRow, Row should be decremented
 | 
						|
        //
 | 
						|
        // (if we are recalling commands using UPPER and DOWN key, and if the
 | 
						|
        // old command is too long to fit the screen, TailColumn must be 79.
 | 
						|
        //
 | 
						|
        if (TailColumn == 0 && TailRow >= TotalRow && (UINTN) Row != TailRow) {
 | 
						|
          Row--;
 | 
						|
        }
 | 
						|
        //
 | 
						|
        // Calculate the cursor position after current operation. If cursor
 | 
						|
        // reaches line end, update both row and column, otherwise, only
 | 
						|
        // column will be changed.
 | 
						|
        //
 | 
						|
        if (Column + OutputLength >= LineLength) {
 | 
						|
          SkipLength = OutputLength - (LineLength - Column);
 | 
						|
 | 
						|
          Row += SkipLength / LineLength + 1;
 | 
						|
          if ((UINTN) Row > TotalRow - 1) {
 | 
						|
            Row = TotalRow - 1;
 | 
						|
          }
 | 
						|
 | 
						|
          Column = SkipLength % LineLength;
 | 
						|
        } else {
 | 
						|
          Column += OutputLength;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      Delete = 0;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Set the cursor position for this key
 | 
						|
    //
 | 
						|
    SetCursorPosition (ConOut, Column, Row, LineLength, TotalRow, InStr, StrPos, Len);
 | 
						|
  } while (!Done);
 | 
						|
 | 
						|
  CopyMem (mInputBufferHistory, InStr, StrLength * sizeof(CHAR16));
 | 
						|
 | 
						|
  //
 | 
						|
  // Return the data to the caller
 | 
						|
  //
 | 
						|
  return ;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Set the current coordinates of the cursor position.
 | 
						|
 | 
						|
  @param  ConOut        Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
 | 
						|
  @param  Column        The position to set the cursor to.
 | 
						|
  @param  Row           The position to set the cursor to.
 | 
						|
  @param  LineLength    Length of a line.
 | 
						|
  @param  TotalRow      Total row of a screen.
 | 
						|
  @param  Str           Point to the string.
 | 
						|
  @param  StrPos        The position of the string.
 | 
						|
  @param  Len           The length of the string.
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
SetCursorPosition (
 | 
						|
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut,
 | 
						|
  IN  UINTN                           Column,
 | 
						|
  IN  INTN                            Row,
 | 
						|
  IN  UINTN                           LineLength,
 | 
						|
  IN  UINTN                           TotalRow,
 | 
						|
  IN  CHAR16                          *Str,
 | 
						|
  IN  UINTN                           StrPos,
 | 
						|
  IN  UINTN                           Len
 | 
						|
  )
 | 
						|
{
 | 
						|
  CHAR16  Backup;
 | 
						|
 | 
						|
  ASSERT (ConOut != NULL);
 | 
						|
  ASSERT (Str != NULL);
 | 
						|
 | 
						|
  Backup = 0;
 | 
						|
  if (Row >= 0) {
 | 
						|
    ConOut->SetCursorPosition (ConOut, Column, Row);
 | 
						|
    return ;
 | 
						|
  }
 | 
						|
 | 
						|
  if (Len - StrPos > Column * Row) {
 | 
						|
    Backup                          = *(Str + StrPos + Column * Row);
 | 
						|
    *(Str + StrPos + Column * Row)  = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  EDBPrint (L"%s", Str + StrPos);
 | 
						|
  if (Len - StrPos > Column * Row) {
 | 
						|
    *(Str + StrPos + Column * Row) = Backup;
 | 
						|
  }
 | 
						|
 | 
						|
  ConOut->SetCursorPosition (ConOut, 0, 0);
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 | 
						|
  SetPageBreak.
 | 
						|
 | 
						|
**/
 | 
						|
BOOLEAN
 | 
						|
EFIAPI
 | 
						|
SetPageBreak (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_INPUT_KEY Key;
 | 
						|
  CHAR16        Str[3];
 | 
						|
  BOOLEAN       OmitPrint;
 | 
						|
 | 
						|
  //
 | 
						|
  // Check
 | 
						|
  //
 | 
						|
  if (!mDebuggerPrivate.EnablePageBreak) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  gST->ConOut->OutputString (gST->ConOut, L"Press ENTER to continue, 'q' to exit:");
 | 
						|
 | 
						|
  OmitPrint = FALSE;
 | 
						|
  //
 | 
						|
  // Wait for user input
 | 
						|
  //
 | 
						|
  Str[0]  = ' ';
 | 
						|
  Str[1]  = 0;
 | 
						|
  Str[2]  = 0;
 | 
						|
  for (;;) {
 | 
						|
    WaitForSingleEvent (gST->ConIn->WaitForKey, 0);
 | 
						|
    gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
 | 
						|
 | 
						|
    //
 | 
						|
    // handle control keys
 | 
						|
    //
 | 
						|
    if (Key.UnicodeChar == CHAR_NULL) {
 | 
						|
      if (Key.ScanCode == SCAN_ESC) {
 | 
						|
        gST->ConOut->OutputString (gST->ConOut, L"\r\n");
 | 
						|
        OmitPrint = TRUE;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
 | 
						|
      gST->ConOut->OutputString (gST->ConOut, L"\r\n");
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    // Echo input
 | 
						|
    //
 | 
						|
    Str[1] = Key.UnicodeChar;
 | 
						|
    if (Str[1] == CHAR_BACKSPACE) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    gST->ConOut->OutputString (gST->ConOut, Str);
 | 
						|
 | 
						|
    if ((Str[1] == L'q') || (Str[1] == L'Q')) {
 | 
						|
      OmitPrint = TRUE;
 | 
						|
    } else {
 | 
						|
      OmitPrint = FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    Str[0] = CHAR_BACKSPACE;
 | 
						|
  }
 | 
						|
 | 
						|
  return OmitPrint;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Print a Unicode string to the output device.
 | 
						|
 | 
						|
  @param  Format    A Null-terminated Unicode format string.
 | 
						|
  @param  ...       The variable argument list that contains pointers to Null-
 | 
						|
                    terminated Unicode strings to be printed
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
EDBPrint (
 | 
						|
  IN CONST CHAR16  *Format,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN   Return;
 | 
						|
  VA_LIST Marker;
 | 
						|
  CHAR16  Buffer[EFI_DEBUG_MAX_PRINT_BUFFER];
 | 
						|
 | 
						|
  VA_START (Marker, Format);
 | 
						|
  Return = UnicodeVSPrint (Buffer, sizeof (Buffer), Format, Marker);
 | 
						|
  VA_END (Marker);
 | 
						|
 | 
						|
  if (gST->ConOut != NULL) {
 | 
						|
    //
 | 
						|
    // To be extra safe make sure ConOut has been initialized
 | 
						|
    //
 | 
						|
    gST->ConOut->OutputString (gST->ConOut, Buffer);
 | 
						|
  }
 | 
						|
 | 
						|
  return Return;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Print a Unicode string to the output buffer.
 | 
						|
 | 
						|
  @param  Buffer          A pointer to the output buffer for the produced Null-terminated
 | 
						|
                          Unicode string.
 | 
						|
  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
 | 
						|
  @param  Format          A Null-terminated Unicode format string.
 | 
						|
  @param  ...             The variable argument list that contains pointers to Null-
 | 
						|
                          terminated Unicode strings to be printed
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
EDBSPrint (
 | 
						|
  OUT CHAR16        *Buffer,
 | 
						|
  IN  INTN          BufferSize,
 | 
						|
  IN  CONST CHAR16  *Format,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN   Return;
 | 
						|
  VA_LIST Marker;
 | 
						|
 | 
						|
  ASSERT (BufferSize > 0);
 | 
						|
 | 
						|
  VA_START (Marker, Format);
 | 
						|
  Return = UnicodeVSPrint (Buffer, (UINTN)BufferSize, Format, Marker);
 | 
						|
  VA_END (Marker);
 | 
						|
 | 
						|
  return Return;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Print a Unicode string to the output buffer with specified offset..
 | 
						|
 | 
						|
  @param  Buffer          A pointer to the output buffer for the produced Null-terminated
 | 
						|
                          Unicode string.
 | 
						|
  @param  BufferSize      The size, in bytes, of the output buffer specified by StartOfBuffer.
 | 
						|
  @param  Offset          The offset of the buffer.
 | 
						|
  @param  Format          A Null-terminated Unicode format string.
 | 
						|
  @param  ...             The variable argument list that contains pointers to Null-
 | 
						|
                          terminated Unicode strings to be printed
 | 
						|
 | 
						|
**/
 | 
						|
UINTN
 | 
						|
EFIAPI
 | 
						|
EDBSPrintWithOffset (
 | 
						|
  OUT CHAR16        *Buffer,
 | 
						|
  IN  INTN          BufferSize,
 | 
						|
  IN  UINTN         Offset,
 | 
						|
  IN  CONST CHAR16  *Format,
 | 
						|
  ...
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN   Return;
 | 
						|
  VA_LIST Marker;
 | 
						|
 | 
						|
  ASSERT (BufferSize - (Offset * sizeof(CHAR16)) > 0);
 | 
						|
 | 
						|
  VA_START (Marker, Format);
 | 
						|
  Return = UnicodeVSPrint (Buffer + Offset, (UINTN)(BufferSize - (Offset * sizeof(CHAR16))), Format, Marker);
 | 
						|
  VA_END (Marker);
 | 
						|
 | 
						|
  return Return;
 | 
						|
}
 |