// Copyright (c) Microsoft Corporation. // Licensed under the MIT license. #pragma once #include #include "../../buffer/out/textBuffer.hpp" #include "../../renderer/inc/IRenderData.hpp" #include "../../terminal/parser/StateMachine.hpp" #include "../../terminal/input/terminalInput.hpp" #include "../../types/inc/Viewport.hpp" #include "../../cascadia/terminalcore/ITerminalApi.hpp" #include "../../cascadia/terminalcore/ITerminalInput.hpp" // You have to forward decl the ICoreSettings here, instead of including the header. // If you include the header, there will be compilation errors with other // headers that include Terminal.hpp namespace winrt::Microsoft::Terminal::Settings { struct ICoreSettings; } namespace Microsoft::Terminal::Core { class Terminal; } class Microsoft::Terminal::Core::Terminal final : public Microsoft::Terminal::Core::ITerminalApi, public Microsoft::Terminal::Core::ITerminalInput, public Microsoft::Console::Render::IRenderData { public: Terminal(); virtual ~Terminal(){}; void Create(COORD viewportSize, SHORT scrollbackLines, Microsoft::Console::Render::IRenderTarget& renderTarget); void CreateFromSettings(winrt::Microsoft::Terminal::Settings::ICoreSettings settings, Microsoft::Console::Render::IRenderTarget& renderTarget); void UpdateSettings(winrt::Microsoft::Terminal::Settings::ICoreSettings settings); // Write goes through the parser void Write(std::wstring_view stringView); [[nodiscard]] std::shared_lock LockForReading(); [[nodiscard]] std::unique_lock LockForWriting(); short GetBufferHeight() const noexcept; #pragma region ITerminalApi // These methods are defined in TerminalApi.cpp bool PrintString(std::wstring_view stringView) override; bool ExecuteChar(wchar_t wch) override; bool SetTextToDefaults(bool foreground, bool background) override; bool SetTextForegroundIndex(BYTE colorIndex) override; bool SetTextBackgroundIndex(BYTE colorIndex) override; bool SetTextRgbColor(COLORREF color, bool foreground) override; bool BoldText(bool boldOn) override; bool UnderlineText(bool underlineOn) override; bool ReverseText(bool reversed) override; bool SetCursorPosition(short x, short y) override; COORD GetCursorPosition() override; bool EraseCharacters(const unsigned int numChars) override; bool SetWindowTitle(std::wstring_view title) override; bool SetColorTableEntry(const size_t tableIndex, const COLORREF dwColor) override; bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override; bool SetDefaultForeground(const COLORREF dwColor) override; bool SetDefaultBackground(const COLORREF dwColor) override; #pragma endregion #pragma region ITerminalInput // These methods are defined in Terminal.cpp bool SendKeyEvent(const WORD vkey, const bool ctrlPressed, const bool altPressed, const bool shiftPressed) override; [[nodiscard]] HRESULT UserResize(const COORD viewportSize) noexcept override; void UserScrollViewport(const int viewTop) override; int GetScrollOffset() override; #pragma endregion #pragma region IRenderData // These methods are defined in TerminalRenderData.cpp Microsoft::Console::Types::Viewport GetViewport() noexcept override; const TextBuffer& GetTextBuffer() noexcept override; const FontInfo& GetFontInfo() noexcept override; const TextAttribute GetDefaultBrushColors() noexcept override; const COLORREF GetForegroundColor(const TextAttribute& attr) const noexcept override; const COLORREF GetBackgroundColor(const TextAttribute& attr) const noexcept override; COORD GetCursorPosition() const noexcept override; bool IsCursorVisible() const noexcept override; bool IsCursorOn() const noexcept override; ULONG GetCursorHeight() const noexcept override; ULONG GetCursorPixelWidth() const noexcept override; CursorType GetCursorStyle() const noexcept override; COLORREF GetCursorColor() const noexcept override; bool IsCursorDoubleWidth() const noexcept override; const std::vector GetOverlays() const noexcept override; const bool IsGridLineDrawingAllowed() noexcept override; std::vector GetSelectionRects() noexcept override; const std::wstring GetConsoleTitle() const noexcept override; void LockConsole() noexcept override; void UnlockConsole() noexcept override; #pragma endregion void SetWriteInputCallback(std::function pfn) noexcept; void SetTitleChangedCallback(std::function pfn) noexcept; void SetScrollPositionChangedCallback(std::function pfn) noexcept; void SetBackgroundCallback(std::function pfn) noexcept; void SetCursorVisible(const bool isVisible) noexcept; bool IsCursorBlinkingAllowed() const noexcept; #pragma region TextSelection const bool IsSelectionActive() const noexcept; void SetSelectionAnchor(const COORD position); void SetEndSelectionPosition(const COORD position); void SetBoxSelection(const bool isEnabled) noexcept; void ClearSelection() noexcept; const std::wstring RetrieveSelectedTextFromBuffer(bool trimTrailingWhitespace) const; #pragma endregion private: std::function _pfnWriteInput; std::function _pfnTitleChanged; std::function _pfnScrollPositionChanged; std::function _pfnBackgroundColorChanged; std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine; std::unique_ptr<::Microsoft::Console::VirtualTerminal::TerminalInput> _terminalInput; std::wstring _title; std::array _colorTable; COLORREF _defaultFg; COLORREF _defaultBg; bool _snapOnInput; // Text Selection COORD _selectionAnchor; COORD _endSelectionPosition; bool _boxSelection; bool _selectionActive; SHORT _selectionAnchor_YOffset; SHORT _endSelectionPosition_YOffset; std::shared_mutex _readWriteLock; // TODO: These members are not shared by an alt-buffer. They should be // encapsulated, such that a Terminal can have both a main and alt buffer. std::unique_ptr _buffer; Microsoft::Console::Types::Viewport _mutableViewport; SHORT _scrollbackLines; // _scrollOffset is the number of lines above the viewport that are currently visible // If _scrollOffset is 0, then the visible region of the buffer is the viewport. int _scrollOffset; // TODO this might not be the value we want to store. // We might want to store the height in the scrollback that's currenty visible. // Think on this some more. // For example: While looking at the scrollback, we probably want the visible region to "stick" // to the region they scrolled to. If that were the case, then every time we move _mutableViewport, // we'd also need to update _offset. // However, if we just stored it as a _visibleTop, then that point would remain fixed - // Though if _visibleTop == _mutableViewport.Top, then we'd need to make sure to update // _visibleTop as well. // Additionally, maybe some people want to scroll into the history, then have that scroll out from // underneath them, while others would prefer to anchor it in place. // Either way, we sohould make this behavior controlled by a setting. int _ViewStartIndex() const noexcept; int _VisibleStartIndex() const noexcept; Microsoft::Console::Types::Viewport _GetMutableViewport() const noexcept; Microsoft::Console::Types::Viewport _GetVisibleViewport() const noexcept; void _InitializeColorTable(); void _WriteBuffer(const std::wstring_view& stringView); void _NotifyScrollEvent(); std::vector _GetSelectionRects() const; };