/** @file
  Implementation for EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL protocol.

Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.<BR>
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (C) 2016 Silicon Graphics, Inc. All rights reserved.<BR>
Copyright (c) 2025, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Terminal.h"

//
// This list is used to define the valid extend chars.
// It also provides a mapping from Unicode to PCANSI or
// ASCII. The ASCII mapping we just made up.
//
//
UNICODE_TO_CHAR  UnicodeToPcAnsiOrAscii[] = {
  { BOXDRAW_HORIZONTAL,                 0xc4, L'-'  },
  { BOXDRAW_VERTICAL,                   0xb3, L'|'  },
  { BOXDRAW_DOWN_RIGHT,                 0xda, L'/'  },
  { BOXDRAW_DOWN_LEFT,                  0xbf, L'\\' },
  { BOXDRAW_UP_RIGHT,                   0xc0, L'\\' },
  { BOXDRAW_UP_LEFT,                    0xd9, L'/'  },
  { BOXDRAW_VERTICAL_RIGHT,             0xc3, L'|'  },
  { BOXDRAW_VERTICAL_LEFT,              0xb4, L'|'  },
  { BOXDRAW_DOWN_HORIZONTAL,            0xc2, L'+'  },
  { BOXDRAW_UP_HORIZONTAL,              0xc1, L'+'  },
  { BOXDRAW_VERTICAL_HORIZONTAL,        0xc5, L'+'  },
  { BOXDRAW_DOUBLE_HORIZONTAL,          0xcd, L'-'  },
  { BOXDRAW_DOUBLE_VERTICAL,            0xba, L'|'  },
  { BOXDRAW_DOWN_RIGHT_DOUBLE,          0xd5, L'/'  },
  { BOXDRAW_DOWN_DOUBLE_RIGHT,          0xd6, L'/'  },
  { BOXDRAW_DOUBLE_DOWN_RIGHT,          0xc9, L'/'  },
  { BOXDRAW_DOWN_LEFT_DOUBLE,           0xb8, L'\\' },
  { BOXDRAW_DOWN_DOUBLE_LEFT,           0xb7, L'\\' },
  { BOXDRAW_DOUBLE_DOWN_LEFT,           0xbb, L'\\' },
  { BOXDRAW_UP_RIGHT_DOUBLE,            0xd4, L'\\' },
  { BOXDRAW_UP_DOUBLE_RIGHT,            0xd3, L'\\' },
  { BOXDRAW_DOUBLE_UP_RIGHT,            0xc8, L'\\' },
  { BOXDRAW_UP_LEFT_DOUBLE,             0xbe, L'/'  },
  { BOXDRAW_UP_DOUBLE_LEFT,             0xbd, L'/'  },
  { BOXDRAW_DOUBLE_UP_LEFT,             0xbc, L'/'  },
  { BOXDRAW_VERTICAL_RIGHT_DOUBLE,      0xc6, L'|'  },
  { BOXDRAW_VERTICAL_DOUBLE_RIGHT,      0xc7, L'|'  },
  { BOXDRAW_DOUBLE_VERTICAL_RIGHT,      0xcc, L'|'  },
  { BOXDRAW_VERTICAL_LEFT_DOUBLE,       0xb5, L'|'  },
  { BOXDRAW_VERTICAL_DOUBLE_LEFT,       0xb6, L'|'  },
  { BOXDRAW_DOUBLE_VERTICAL_LEFT,       0xb9, L'|'  },
  { BOXDRAW_DOWN_HORIZONTAL_DOUBLE,     0xd1, L'+'  },
  { BOXDRAW_DOWN_DOUBLE_HORIZONTAL,     0xd2, L'+'  },
  { BOXDRAW_DOUBLE_DOWN_HORIZONTAL,     0xcb, L'+'  },
  { BOXDRAW_UP_HORIZONTAL_DOUBLE,       0xcf, L'+'  },
  { BOXDRAW_UP_DOUBLE_HORIZONTAL,       0xd0, L'+'  },
  { BOXDRAW_DOUBLE_UP_HORIZONTAL,       0xca, L'+'  },
  { BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE, 0xd8, L'+'  },
  { BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL, 0xd7, L'+'  },
  { BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL, 0xce, L'+'  },

  { BLOCKELEMENT_FULL_BLOCK,            0xdb, L'*'  },
  { BLOCKELEMENT_LIGHT_SHADE,           0xb0, L'+'  },

  { GEOMETRICSHAPE_UP_TRIANGLE,         '^',  L'^'  },
  { GEOMETRICSHAPE_RIGHT_TRIANGLE,      '>',  L'>'  },
  { GEOMETRICSHAPE_DOWN_TRIANGLE,       'v',  L'v'  },
  { GEOMETRICSHAPE_LEFT_TRIANGLE,       '<',  L'<'  },

  { ARROW_LEFT,                         '<',  L'<'  },
  { ARROW_UP,                           '^',  L'^'  },
  { ARROW_RIGHT,                        '>',  L'>'  },
  { ARROW_DOWN,                         'v',  L'v'  },

  { 0x0000,                             0x00, L'\0' }
};

CHAR16  mSetModeString[]           = { ESC, '[', '=', '3', 'h', 0 };
CHAR16  mSetModeStringResize[]     = { ESC, '[', '8', ';', '0', '0', '0', ';', '0', '0', '0', 't', 0 };
CHAR16  mSetAttributeString[]      = { ESC, '[', '0', 'm', ESC, '[', '4', '0', 'm', ESC, '[', '4', '0', 'm', 0 };
CHAR16  mClearScreenString[]       = { ESC, '[', '2', 'J', 0 };
CHAR16  mSetCursorPositionString[] = { ESC, '[', '0', '0', '0', ';', '0', '0', '0', 'H', 0 };
CHAR16  mCursorForwardString[]     = { ESC, '[', '0', '0', '0', 'C', 0 };
CHAR16  mCursorBackwardString[]    = { ESC, '[', '0', '0', '0', 'D', 0 };

//
// Body of the ConOut functions
//

/**
  Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.Reset().

  If ExtendeVerification is TRUE, then perform dependent serial device reset,
  and set display mode to mode 0.
  If ExtendedVerification is FALSE, only set display mode to mode 0.

  @param  This                  Indicates the calling context.
  @param  ExtendedVerification  Indicates that the driver may perform a more
                                exhaustive verification operation of the device
                                during reset.

  @retval EFI_SUCCESS           The reset operation succeeds.
  @retval EFI_DEVICE_ERROR      The terminal is not functioning correctly or the serial port reset fails.

**/
EFI_STATUS
EFIAPI
TerminalConOutReset (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  BOOLEAN                          ExtendedVerification
  )
{
  EFI_STATUS    Status;
  TERMINAL_DEV  *TerminalDevice;

  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

  //
  // Perform a more exhaustive reset by resetting the serial port.
  //
  if (ExtendedVerification) {
    //
    // Report progress code here
    //
    REPORT_STATUS_CODE_WITH_DEVICE_PATH (
      EFI_PROGRESS_CODE,
      (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_PC_RESET),
      TerminalDevice->DevicePath
      );

    Status = TerminalDevice->SerialIo->Reset (TerminalDevice->SerialIo);
    if (EFI_ERROR (Status)) {
      //
      // Report error code here
      //
      REPORT_STATUS_CODE_WITH_DEVICE_PATH (
        EFI_ERROR_CODE | EFI_ERROR_MINOR,
        (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR),
        TerminalDevice->DevicePath
        );

      return Status;
    }
  }

  This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BLACK));

  Status = This->SetMode (This, 0);

  return Status;
}

/**
  Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.OutputString().

  The Unicode string will be converted to terminal expressible data stream
  and send to terminal via serial port.

  @param  This                    Indicates the calling context.
  @param  WString                 The Null-terminated Unicode string to be displayed
                                  on the terminal screen.

  @retval EFI_SUCCESS             The string is output successfully.
  @retval EFI_DEVICE_ERROR        The serial port fails to send the string out.
  @retval EFI_WARN_UNKNOWN_GLYPH  Indicates that some of the characters in the Unicode string could not
                                  be rendered and are skipped.
  @retval EFI_UNSUPPORTED         If current display mode is out of range.

**/
EFI_STATUS
EFIAPI
TerminalConOutOutputString (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  CHAR16                           *WString
  )
{
  TERMINAL_DEV                 *TerminalDevice;
  EFI_SIMPLE_TEXT_OUTPUT_MODE  *Mode;
  UINTN                        MaxColumn;
  UINTN                        MaxRow;
  UINTN                        Length;
  UTF8_CHAR                    Utf8Char;
  CHAR8                        GraphicChar;
  CHAR8                        AsciiChar;
  EFI_STATUS                   Status;
  UINT8                        ValidBytes;
  CHAR8                        CrLfStr[2];
  //
  //  flag used to indicate whether condition happens which will cause
  //  return EFI_WARN_UNKNOWN_GLYPH
  //
  BOOLEAN  Warning;

  ValidBytes = 0;
  Warning    = FALSE;
  AsciiChar  = 0;

  //
  //  get Terminal device data structure pointer.
  //
  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

  //
  //  Get current display mode
  //
  Mode = This->Mode;

  if (Mode->Mode >= Mode->MaxMode) {
    return EFI_UNSUPPORTED;
  }

  This->QueryMode (
          This,
          Mode->Mode,
          &MaxColumn,
          &MaxRow
          );

  for ( ; *WString != CHAR_NULL; WString++) {
    //
    // Skip WIDE_CHAR/NARROW_CHAR, because they are not displayable.
    //
    if ((*WString == WIDE_CHAR) || (*WString == NARROW_CHAR)) {
      continue;
    }

    switch (TerminalDevice->TerminalType) {
      case TerminalTypePcAnsi:
      case TerminalTypeVt100:
      case TerminalTypeVt100Plus:
      case TerminalTypeTtyTerm:
      case TerminalTypeLinux:
      case TerminalTypeXtermR6:
      case TerminalTypeVt400:
      case TerminalTypeSCO:

        if (!TerminalIsValidTextGraphics (*WString, &GraphicChar, &AsciiChar)) {
          //
          // If it's not a graphic character convert Unicode to ASCII.
          //
          GraphicChar = (CHAR8)*WString;

          if (!(TerminalIsValidAscii (GraphicChar) || TerminalIsValidEfiCntlChar (GraphicChar))) {
            //
            // when this driver use the OutputString to output control string,
            // TerminalDevice->OutputEscChar is set to let the Esc char
            // to be output to the terminal emulation software.
            //
            if ((GraphicChar == 27) && TerminalDevice->OutputEscChar) {
              GraphicChar = 27;
            } else {
              GraphicChar = '?';
              Warning     = TRUE;
            }
          }

          AsciiChar = GraphicChar;
        }

        if (TerminalDevice->TerminalType != TerminalTypePcAnsi) {
          GraphicChar = AsciiChar;
        }

        Length = 1;

        Status = TerminalDevice->SerialIo->Write (
                                             TerminalDevice->SerialIo,
                                             &Length,
                                             &GraphicChar
                                             );

        if (EFI_ERROR (Status)) {
          goto OutputError;
        }

        break;

      case TerminalTypeVtUtf8:
        UnicodeToUtf8 (*WString, &Utf8Char, &ValidBytes);
        Length = ValidBytes;
        Status = TerminalDevice->SerialIo->Write (
                                             TerminalDevice->SerialIo,
                                             &Length,
                                             (UINT8 *)&Utf8Char
                                             );
        if (EFI_ERROR (Status)) {
          goto OutputError;
        }

        break;
    }

    //
    //  Update cursor position.
    //
    switch (*WString) {
      case CHAR_BACKSPACE:
        if (Mode->CursorColumn > 0) {
          Mode->CursorColumn--;
        }

        break;

      case CHAR_LINEFEED:
        if (Mode->CursorRow < (INT32)(MaxRow - 1)) {
          Mode->CursorRow++;
        }

        break;

      case CHAR_CARRIAGE_RETURN:
        Mode->CursorColumn = 0;
        break;

      default:
        if (Mode->CursorColumn < (INT32)(MaxColumn - 1)) {
          Mode->CursorColumn++;
        } else {
          Mode->CursorColumn = 0;
          if (Mode->CursorRow < (INT32)(MaxRow - 1)) {
            Mode->CursorRow++;
          }

          if ((TerminalDevice->TerminalType == TerminalTypeTtyTerm) &&
              !TerminalDevice->OutputEscChar)
          {
            //
            // We've written the last character on the line.  The
            // terminal doesn't actually wrap its cursor until we print
            // the next character, but the driver thinks it has wrapped
            // already.  Print CR LF to synchronize the terminal with
            // the driver, but only if we're not in the middle of
            // printing an escape sequence.
            //
            CrLfStr[0] = '\r';
            CrLfStr[1] = '\n';

            Length = sizeof (CrLfStr);

            Status = TerminalDevice->SerialIo->Write (
                                                 TerminalDevice->SerialIo,
                                                 &Length,
                                                 CrLfStr
                                                 );

            if (EFI_ERROR (Status)) {
              goto OutputError;
            }
          }
        }

        break;
    }
  }

  if (Warning) {
    return EFI_WARN_UNKNOWN_GLYPH;
  }

  return EFI_SUCCESS;

OutputError:
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_ERROR_CODE | EFI_ERROR_MINOR,
    (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_OUTPUT_ERROR),
    TerminalDevice->DevicePath
    );

  return EFI_DEVICE_ERROR;
}

/**
  Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.TestString().

  If one of the characters in the *Wstring is
  neither valid Unicode drawing characters,
  not ASCII code, then this function will return
  EFI_UNSUPPORTED.

  @param  This              Indicates the calling context.
  @param  WString           The Null-terminated Unicode string to be tested.

  @retval EFI_SUCCESS       The terminal is capable of rendering the output string.
  @retval EFI_UNSUPPORTED   Some of the characters in the Unicode string cannot be rendered.

**/
EFI_STATUS
EFIAPI
TerminalConOutTestString (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  CHAR16                           *WString
  )
{
  TERMINAL_DEV  *TerminalDevice;
  EFI_STATUS    Status;

  //
  //  get Terminal device data structure pointer.
  //
  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

  switch (TerminalDevice->TerminalType) {
    case TerminalTypePcAnsi:
    case TerminalTypeVt100:
    case TerminalTypeVt100Plus:
    case TerminalTypeTtyTerm:
    case TerminalTypeLinux:
    case TerminalTypeXtermR6:
    case TerminalTypeVt400:
    case TerminalTypeSCO:
      Status = AnsiTestString (TerminalDevice, WString);
      break;

    case TerminalTypeVtUtf8:
      Status = VTUTF8TestString (TerminalDevice, WString);
      break;

    default:
      Status = EFI_UNSUPPORTED;
      break;
  }

  return Status;
}

/**
  Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.QueryMode().

  It returns information for an available text mode
  that the terminal supports.

  @param This        Indicates the calling context.
  @param ModeNumber  The mode number to return information on.
  @param Columns     The returned columns of the requested mode.
  @param Rows        The returned rows of the requested mode.

  @retval EFI_SUCCESS       The requested mode information is returned.
  @retval EFI_UNSUPPORTED   The mode number is not valid.

**/
EFI_STATUS
EFIAPI
TerminalConOutQueryMode (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  UINTN                            ModeNumber,
  OUT UINTN                            *Columns,
  OUT UINTN                            *Rows
  )
{
  TERMINAL_DEV  *TerminalDevice;

  if (ModeNumber >= (UINTN)This->Mode->MaxMode) {
    return EFI_UNSUPPORTED;
  }

  //
  // Get Terminal device data structure pointer.
  //
  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);
  *Columns       = TerminalDevice->TerminalConsoleModeData[ModeNumber].Columns;
  *Rows          = TerminalDevice->TerminalConsoleModeData[ModeNumber].Rows;

  return EFI_SUCCESS;
}

/**
  Implements EFI_SIMPLE_TEXT_OUT.SetMode().

  Set the terminal to a specified display mode.

  @param This          Indicates the calling context.
  @param ModeNumber    The text mode to set.

  @retval EFI_SUCCESS       The requested text mode is set.
  @retval EFI_DEVICE_ERROR  The requested text mode cannot be set
                            because of serial device error.
  @retval EFI_UNSUPPORTED   The text mode number is not valid.

**/
EFI_STATUS
EFIAPI
TerminalConOutSetMode (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  UINTN                            ModeNumber
  )
{
  EFI_STATUS    Status;
  TERMINAL_DEV  *TerminalDevice;
  CHAR16        *String;
  UINTN         Columns;
  UINTN         Rows;

  //
  // Get Terminal device data structure pointer.
  //
  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

  if (ModeNumber >= (UINTN)This->Mode->MaxMode) {
    return EFI_UNSUPPORTED;
  }

  //
  // Configure terminal string for the text mode to set.
  //
  if (ModeNumber == 0) {
    String = mSetModeString;
  } else {
    Columns = TerminalDevice->TerminalConsoleModeData[ModeNumber].Columns;
    Rows    = TerminalDevice->TerminalConsoleModeData[ModeNumber].Rows;

    mSetModeStringResize[RESIZE_ROW_OFFSET + 0]    = (CHAR16)('0' + (Rows / 100));
    mSetModeStringResize[RESIZE_ROW_OFFSET + 1]    = (CHAR16)('0' + ((Rows % 100) / 10));
    mSetModeStringResize[RESIZE_ROW_OFFSET + 2]    = (CHAR16)('0' + (Rows % 10));
    mSetModeStringResize[RESIZE_COLUMN_OFFSET + 0] = (CHAR16)('0' + (Columns / 100));
    mSetModeStringResize[RESIZE_COLUMN_OFFSET + 1] = (CHAR16)('0' + ((Columns % 100) / 10));
    mSetModeStringResize[RESIZE_COLUMN_OFFSET + 2] = (CHAR16)('0' + (Columns % 10));

    String = mSetModeStringResize;
  }

  //
  // Set the current mode
  //
  This->Mode->Mode = (INT32)ModeNumber;

  This->ClearScreen (This);

  TerminalDevice->OutputEscChar = TRUE;
  Status                        = This->OutputString (This, String);
  TerminalDevice->OutputEscChar = FALSE;

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  This->Mode->Mode = (INT32)ModeNumber;

  Status = This->ClearScreen (This);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetAttribute().

  @param This        Indicates the calling context.
  @param Attribute   The attribute to set. Only bit0..6 are valid, all other bits
                     are undefined and must be zero.

  @retval EFI_SUCCESS        The requested attribute is set.
  @retval EFI_DEVICE_ERROR   The requested attribute cannot be set due to serial port error.
  @retval EFI_UNSUPPORTED    The attribute requested is not defined by EFI spec.

**/
EFI_STATUS
EFIAPI
TerminalConOutSetAttribute (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  UINTN                            Attribute
  )
{
  UINT8         ForegroundControl;
  UINT8         BackgroundControl;
  UINT8         BrightControl;
  INT32         SavedColumn;
  INT32         SavedRow;
  EFI_STATUS    Status;
  TERMINAL_DEV  *TerminalDevice;

  SavedColumn = 0;
  SavedRow    = 0;

  //
  //  get Terminal device data structure pointer.
  //
  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

  //
  //  only the bit0..6 of the Attribute is valid
  //
  if ((Attribute | 0x7f) != 0x7f) {
    return EFI_UNSUPPORTED;
  }

  //
  // Skip outputting the command string for the same attribute
  // It improves the terminal performance significantly
  //
  if (This->Mode->Attribute == (INT32)Attribute) {
    return EFI_SUCCESS;
  }

  //
  //  convert Attribute value to terminal emulator
  //  understandable foreground color
  //
  switch (Attribute & 0x07) {
    case EFI_BLACK:
      ForegroundControl = 30;
      break;

    case EFI_BLUE:
      ForegroundControl = 34;
      break;

    case EFI_GREEN:
      ForegroundControl = 32;
      break;

    case EFI_CYAN:
      ForegroundControl = 36;
      break;

    case EFI_RED:
      ForegroundControl = 31;
      break;

    case EFI_MAGENTA:
      ForegroundControl = 35;
      break;

    case EFI_BROWN:
      ForegroundControl = 33;
      break;

    default:

    case EFI_LIGHTGRAY:
      ForegroundControl = 37;
      break;
  }

  //
  //  bit4 of the Attribute indicates bright control
  //  of terminal emulator.
  //
  BrightControl = (UINT8)((Attribute >> 3) & 1);

  //
  //  convert Attribute value to terminal emulator
  //  understandable background color.
  //
  switch ((Attribute >> 4) & 0x07) {
    case EFI_BLACK:
      BackgroundControl = 40;
      break;

    case EFI_BLUE:
      BackgroundControl = 44;
      break;

    case EFI_GREEN:
      BackgroundControl = 42;
      break;

    case EFI_CYAN:
      BackgroundControl = 46;
      break;

    case EFI_RED:
      BackgroundControl = 41;
      break;

    case EFI_MAGENTA:
      BackgroundControl = 45;
      break;

    case EFI_BROWN:
      BackgroundControl = 43;
      break;

    default:

    case EFI_LIGHTGRAY:
      BackgroundControl = 47;
      break;
  }

  //
  // terminal emulator's control sequence to set attributes
  //
  mSetAttributeString[BRIGHT_CONTROL_OFFSET]         = (CHAR16)('0' + BrightControl);
  mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 0] = (CHAR16)('0' + (ForegroundControl / 10));
  mSetAttributeString[FOREGROUND_CONTROL_OFFSET + 1] = (CHAR16)('0' + (ForegroundControl % 10));
  mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 0] = (CHAR16)('0' + (BackgroundControl / 10));
  mSetAttributeString[BACKGROUND_CONTROL_OFFSET + 1] = (CHAR16)('0' + (BackgroundControl % 10));

  //
  // save current column and row
  // for future scrolling back use.
  //
  SavedColumn = This->Mode->CursorColumn;
  SavedRow    = This->Mode->CursorRow;

  TerminalDevice->OutputEscChar = TRUE;
  Status                        = This->OutputString (This, mSetAttributeString);
  TerminalDevice->OutputEscChar = FALSE;

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  //
  //  scroll back to saved cursor position.
  //
  This->Mode->CursorColumn = SavedColumn;
  This->Mode->CursorRow    = SavedRow;

  This->Mode->Attribute = (INT32)Attribute;

  return EFI_SUCCESS;
}

/**
  Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.ClearScreen().
  It clears the ANSI terminal's display to the
  currently selected background color.

  @param This     Indicates the calling context.

  @retval EFI_SUCCESS       The operation completed successfully.
  @retval EFI_DEVICE_ERROR  The terminal screen cannot be cleared due to serial port error.
  @retval EFI_UNSUPPORTED   The terminal is not in a valid display mode.

**/
EFI_STATUS
EFIAPI
TerminalConOutClearScreen (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This
  )
{
  EFI_STATUS    Status;
  TERMINAL_DEV  *TerminalDevice;

  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

  //
  //  control sequence for clear screen request
  //
  TerminalDevice->OutputEscChar = TRUE;
  Status                        = This->OutputString (This, mClearScreenString);
  TerminalDevice->OutputEscChar = FALSE;

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  Status = This->SetCursorPosition (This, 0, 0);

  return Status;
}

/**
  Implements EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.SetCursorPosition().

  @param This      Indicates the calling context.
  @param Column    The row to set cursor to.
  @param Row       The column to set cursor to.

  @retval EFI_SUCCESS       The operation completed successfully.
  @retval EFI_DEVICE_ERROR  The request fails due to serial port error.
  @retval EFI_UNSUPPORTED   The terminal is not in a valid text mode, or the cursor position
                            is invalid for current mode.

**/
EFI_STATUS
EFIAPI
TerminalConOutSetCursorPosition (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  UINTN                            Column,
  IN  UINTN                            Row
  )
{
  EFI_SIMPLE_TEXT_OUTPUT_MODE  *Mode;
  UINTN                        MaxColumn;
  UINTN                        MaxRow;
  EFI_STATUS                   Status;
  TERMINAL_DEV                 *TerminalDevice;
  CHAR16                       *String;

  TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (This);

  //
  //  get current mode
  //
  Mode = This->Mode;

  //
  //  get geometry of current mode
  //
  Status = This->QueryMode (
                   This,
                   Mode->Mode,
                   &MaxColumn,
                   &MaxRow
                   );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  if ((Column >= MaxColumn) || (Row >= MaxRow)) {
    return EFI_UNSUPPORTED;
  }

  //
  // control sequence to move the cursor
  //
  // Optimize cursor motion control sequences for TtyTerm.  Move
  // within the current line if possible, and don't output anyting if
  // it isn't necessary.
  //
  if ((TerminalDevice->TerminalType == TerminalTypeTtyTerm) &&
      ((UINTN)Mode->CursorRow == Row))
  {
    if ((UINTN)Mode->CursorColumn > Column) {
      mCursorBackwardString[FW_BACK_OFFSET + 0] = (CHAR16)('0' + ((Mode->CursorColumn - Column) / 100));
      mCursorBackwardString[FW_BACK_OFFSET + 1] = (CHAR16)('0' + (((Mode->CursorColumn - Column) % 100) / 10));
      mCursorBackwardString[FW_BACK_OFFSET + 2] = (CHAR16)('0' + ((Mode->CursorColumn - Column) % 10));
      String                                    = mCursorBackwardString;
    } else if (Column > (UINTN)Mode->CursorColumn) {
      mCursorForwardString[FW_BACK_OFFSET + 0] = (CHAR16)('0' + ((Column - Mode->CursorColumn) / 100));
      mCursorForwardString[FW_BACK_OFFSET + 1] = (CHAR16)('0' + (((Column - Mode->CursorColumn) % 100) / 10));
      mCursorForwardString[FW_BACK_OFFSET + 2] = (CHAR16)('0' + ((Column - Mode->CursorColumn) % 10));
      String                                   = mCursorForwardString;
    } else {
      String = L"";  // No cursor motion necessary
    }
  } else {
    mSetCursorPositionString[ROW_OFFSET + 0]    = (CHAR16)('0' + ((Row + 1) / 100));
    mSetCursorPositionString[ROW_OFFSET + 1]    = (CHAR16)('0' + (((Row + 1) % 100) / 10));
    mSetCursorPositionString[ROW_OFFSET + 2]    = (CHAR16)('0' + ((Row + 1) % 10));
    mSetCursorPositionString[COLUMN_OFFSET + 0] = (CHAR16)('0' + ((Column + 1) / 100));
    mSetCursorPositionString[COLUMN_OFFSET + 1] = (CHAR16)('0' + (((Column + 1) % 100) / 10));
    mSetCursorPositionString[COLUMN_OFFSET + 2] = (CHAR16)('0' + ((Column + 1) % 10));
    String                                      = mSetCursorPositionString;
  }

  TerminalDevice->OutputEscChar = TRUE;
  Status                        = This->OutputString (This, String);
  TerminalDevice->OutputEscChar = FALSE;

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  //
  //  update current cursor position
  //  in the Mode data structure.
  //
  Mode->CursorColumn = (INT32)Column;
  Mode->CursorRow    = (INT32)Row;

  return EFI_SUCCESS;
}

/**
  Implements SIMPLE_TEXT_OUTPUT.EnableCursor().

  In this driver, the cursor cannot be hidden.

  @param This      Indicates the calling context.
  @param Visible   If TRUE, the cursor is set to be visible,
                   If FALSE, the cursor is set to be invisible.

  @retval EFI_SUCCESS      The request is valid.
  @retval EFI_UNSUPPORTED  The terminal does not support cursor hidden.

**/
EFI_STATUS
EFIAPI
TerminalConOutEnableCursor (
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *This,
  IN  BOOLEAN                          Visible
  )
{
  if (!Visible) {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Detects if a Unicode char is for Box Drawing text graphics.

  @param  Graphic      Unicode char to test.
  @param  PcAnsi       Optional pointer to return PCANSI equivalent of
                       Graphic.
  @param  Ascii        Optional pointer to return ASCII equivalent of
                       Graphic.

  @retval TRUE         If Graphic is a supported Unicode Box Drawing character.

**/
BOOLEAN
TerminalIsValidTextGraphics (
  IN  CHAR16  Graphic,
  OUT CHAR8   *PcAnsi  OPTIONAL,
  OUT CHAR8   *Ascii OPTIONAL
  )
{
  UNICODE_TO_CHAR  *Table;

  if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
    //
    // Unicode drawing code charts are all in the 0x25xx range,
    //  arrows are 0x21xx
    //
    return FALSE;
  }

  for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
    if (Graphic == Table->Unicode) {
      if (PcAnsi != NULL) {
        *PcAnsi = Table->PcAnsi;
      }

      if (Ascii != NULL) {
        *Ascii = Table->Ascii;
      }

      return TRUE;
    }
  }

  return FALSE;
}

/**
  Detects if a valid ASCII char.

  @param  Ascii        An ASCII character.

  @retval TRUE         If it is a valid ASCII character.
  @retval FALSE        If it is not a valid ASCII character.

**/
BOOLEAN
TerminalIsValidAscii (
  IN  CHAR16  Ascii
  )
{
  //
  // valid ascii code lies in the extent of 0x20 ~ 0x7f
  //
  if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
    return TRUE;
  }

  return FALSE;
}

/**
  Detects if a valid EFI control character.

  @param  CharC        An input EFI Control character.

  @retval TRUE         If it is a valid EFI control character.
  @retval FALSE        If it is not a valid EFI control character.

**/
BOOLEAN
TerminalIsValidEfiCntlChar (
  IN  CHAR16  CharC
  )
{
  //
  // only support four control characters.
  //
  if ((CharC == CHAR_NULL) ||
      (CharC == CHAR_BACKSPACE) ||
      (CharC == CHAR_LINEFEED) ||
      (CharC == CHAR_CARRIAGE_RETURN) ||
      (CharC == CHAR_TAB)
      )
  {
    return TRUE;
  }

  return FALSE;
}
