text: // Copyright (c) Microsoft Corporation.
  // Licensed under the MIT license.
  
  #include "precomp.h"
  #include "Xterm256Engine.hpp"
  #pragma hdrstop
  using namespace Microsoft::Console;
  using namespace Microsoft::Console::Render;
  using namespace Microsoft::Console::Types;
  
  Xterm256Engine::Xterm256Engine(_In_ wil::unique_hfile hPipe,
                                 const Viewport initialViewport) :
      XtermEngine(std::move(hPipe), initialViewport, false)
  {
  }
  
  // Routine Description:
  // - Write a VT sequence to change the current colors of text. Writes true RGB
  //      color sequences.
  // Arguments:
  // - textAttributes - Text attributes to use for the colors and character rendition
  // - pData - The interface to console data structures required for rendering
  // - isSettingDefaultBrushes: indicates if we should change the background color of
  //      the window. Unused for VT
  // Return Value:
  // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
  [[nodiscard]] HRESULT Xterm256Engine::UpdateDrawingBrushes(const TextAttribute& textAttributes,
                                                             const gsl::not_null<IRenderData*> /*pData*/,
                                                             const bool /*isSettingDefaultBrushes*/) noexcept
  {
      RETURN_IF_FAILED(VtEngine::_RgbUpdateDrawingBrushes(textAttributes));
      // Only do extended attributes in xterm-256color, as to not break telnet.exe.
      return _UpdateExtendedAttrs(textAttributes);
  }
  
  // Routine Description:
  // - Write a VT sequence to update the character rendition attributes.
  // Arguments:
  // - textAttributes - text attributes (bold, italic, underline, etc.) to use.
  // Return Value:
  // - S_OK if we succeeded, else an appropriate HRESULT for failing to allocate or write.
  [[nodiscard]] HRESULT Xterm256Engine::_UpdateExtendedAttrs(const TextAttribute& textAttributes) noexcept
  {
      // Turning off Bold and Faint must be handled at the same time,
      // since there is only one sequence that resets both of them.
      const auto boldTurnedOff = !textAttributes.IsBold() && _lastTextAttributes.IsBold();
      const auto faintTurnedOff = !textAttributes.IsFaint() && _lastTextAttributes.IsFaint();
      if (boldTurnedOff || faintTurnedOff)
      {
          RETURN_IF_FAILED(_SetBold(false));
          _lastTextAttributes.SetBold(false);
          _lastTextAttributes.SetFaint(false);
      }
  
      // Once we've handled the cases where they need to be turned off,
      // we can then check if either should be turned back on again.
      if (textAttributes.IsBold() && !_lastTextAttributes.IsBold())
      {
          RETURN_IF_FAILED(_SetBold(true));
          _lastTextAttributes.SetBold(true);
      }
      if (textAttributes.IsFaint() && !_lastTextAttributes.IsFaint())
      {
          RETURN_IF_FAILED(_SetFaint(true));
          _lastTextAttributes.SetFaint(true);
      }
  
      if (textAttributes.IsUnderlined() != _lastTextAttributes.IsUnderlined())
      {
          RETURN_IF_FAILED(_SetUnderline(textAttributes.IsUnderlined()));
          _lastTextAttributes.SetUnderline(textAttributes.IsUnderlined());
      }
  
      if (textAttributes.IsOverlined() != _lastTextAttributes.IsOverlined())
      {
          RETURN_IF_FAILED(_SetOverline(textAttributes.IsOverlined()));
          _lastTextAttributes.SetOverline(textAttributes.IsOverlined());
      }
  
      if (textAttributes.IsItalic() != _lastTextAttributes.IsItalic())
      {
          RETURN_IF_FAILED(_SetItalics(textAttributes.IsItalic()));
          _lastTextAttributes.SetItalics(textAttributes.IsItalic());
      }
  
      if (textAttributes.IsBlinking() != _lastTextAttributes.IsBlinking())
      {
          RETURN_IF_FAILED(_SetBlinking(textAttributes.IsBlinking()));
          _lastTextAttributes.SetBlinking(textAttributes.IsBlinking());
      }
  
      if (textAttributes.IsInvisible() != _lastTextAttributes.IsInvisible())
      {
          RETURN_IF_FAILED(_SetInvisible(textAttributes.IsInvisible()));
          _lastTextAttributes.SetInvisible(textAttributes.IsInvisible());
      }
  
      if (textAttributes.IsCrossedOut() != _lastTextAttributes.IsCrossedOut())
      {
          RETURN_IF_FAILED(_SetCrossedOut(textAttributes.IsCrossedOut()));
          _lastTextAttributes.SetCrossedOut(textAttributes.IsCrossedOut());
      }
  
      if (textAttributes.IsReverseVideo() != _lastTextAttributes.IsReverseVideo())
      {
          RETURN_IF_FAILED(_SetReverseVideo(textAttributes.IsReverseVideo()));
          _lastTextAttributes.SetReverseVideo(textAttributes.IsReverseVideo());
      }
  
      return S_OK;
  }
  
  // Method Description:
  // - Manually emit a "Erase Scrollback" sequence to the connected terminal. We
  //   need to do this in certain cases that we've identified where we believe the
  //   client wanted the entire terminal buffer cleared, not just the viewport.
  //   For more information, see GH#3126.
  // Arguments:
  // - <none>
  // Return Value:
  // - S_OK if we wrote the sequences successfully, otherwise an appropriate HRESULT
  [[nodiscard]] HRESULT Xterm256Engine::ManuallyClearScrollback() noexcept
  {
      return _ClearScrollback();
  }
  