Clean up SCREEN_INFORMATION even further (#19648)

A continuation of #19645. Maintainer modifications were disabled,
unfortunately.
This commit is contained in:
Leonard Hecker 2025-12-19 23:08:03 +01:00 committed by GitHub
parent a79078924a
commit 8f418d10a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 111 additions and 180 deletions

View File

@ -23,7 +23,6 @@ SCREEN_INFORMATION::SCREEN_INFORMATION(
const TextAttribute popupAttributes,
const FontInfo fontInfo) :
_pConsoleWindowMetrics{ pMetrics },
_viewport(Viewport::Empty()),
_PopupAttributes{ popupAttributes },
_currentFont{ fontInfo },
_desiredFont{ fontInfo }

View File

@ -20,24 +20,12 @@ Revision History:
#pragma once
#include "outputStream.hpp"
#include "../buffer/out/OutputCellRect.hpp"
#include "../buffer/out/TextAttribute.hpp"
#include "../buffer/out/textBuffer.hpp"
#include "../buffer/out/textBufferCellIterator.hpp"
#include "../buffer/out/textBufferTextIterator.hpp"
#include "IIoProvider.hpp"
#include "../terminal/parser/stateMachine.hpp"
#include "../interactivity/inc/IWindowMetrics.hpp"
#include "../renderer/inc/FontInfoDesired.hpp"
#include "../server/ObjectHeader.h"
#include "../interactivity/inc/IWindowMetrics.hpp"
#include "../renderer/inc/FontInfo.hpp"
#include "../renderer/inc/FontInfoDesired.hpp"
#include "../types/inc/Viewport.hpp"
class ConversionAreaInfo; // forward decl window. circular reference
class SCREEN_INFORMATION : public ConsoleObjectHeader, public Microsoft::Console::IIoProvider
@ -62,103 +50,14 @@ public:
SCREEN_INFORMATION* self;
};
[[nodiscard]] static NTSTATUS CreateInstance(_In_ til::size coordWindowSize,
const FontInfo fontInfo,
_In_ til::size coordScreenBufferSize,
const TextAttribute defaultAttributes,
const TextAttribute popupAttributes,
const UINT uiCursorSize,
_Outptr_ SCREEN_INFORMATION** const ppScreen);
~SCREEN_INFORMATION() override;
void GetScreenBufferInformation(_Out_ til::size* pcoordSize,
_Out_ til::point* pcoordCursorPosition,
_Out_ til::inclusive_rect* psrWindow,
_Out_ PWORD pwAttributes,
_Out_ til::size* pcoordMaximumWindowSize,
_Out_ PWORD pwPopupAttributes,
_Out_writes_(COLOR_TABLE_SIZE) LPCOLORREF lpColorTable) const;
void GetRequiredConsoleSizeInPixels(_Out_ til::size* const pRequiredSize) const;
void MakeCurrentCursorVisible();
void MakeCursorVisible(til::point position);
void SnapOnInput(WORD vkey);
SnapOnScopeExit SnapOnOutput() noexcept;
void ClipToScreenBuffer(_Inout_ til::inclusive_rect* const psrClip) const;
til::size GetMinWindowSizeInCharacters(const til::size coordFontSize = { 1, 1 }) const;
til::size GetMaxWindowSizeInCharacters(const til::size coordFontSize = { 1, 1 }) const;
til::size GetLargestWindowSizeInCharacters(const til::size coordFontSize = { 1, 1 }) const;
til::size GetScrollBarSizesInCharacters() const;
Microsoft::Console::Types::Viewport GetBufferSize() const;
Microsoft::Console::Types::Viewport GetTerminalBufferSize() const;
til::size GetScreenFontSize() const;
void UpdateFont(const FontInfo* const pfiNewFont);
void RefreshFontWithRenderer();
[[nodiscard]] NTSTATUS ResizeScreenBuffer(const til::size coordNewScreenSize, const bool fDoScrollBarUpdate);
struct ScrollBarState
{
til::size maxSize;
til::rect viewport;
bool isAltBuffer = false;
};
void UpdateScrollBars();
ScrollBarState FetchScrollBarState();
bool IsMaximizedBoth() const;
bool IsMaximizedX() const;
bool IsMaximizedY() const;
const Microsoft::Console::Types::Viewport& GetViewport() const noexcept;
void SetViewport(const Microsoft::Console::Types::Viewport& newViewport, const bool updateBottom);
Microsoft::Console::Types::Viewport GetVirtualViewport() const noexcept;
Microsoft::Console::Types::Viewport GetVtPageArea() const noexcept;
void ProcessResizeWindow(const til::rect* const prcClientNew, const til::rect* const prcClientOld);
void SetViewportSize(const til::size* const pcoordSize);
// Forwarders to Window if we're the active buffer.
[[nodiscard]] NTSTATUS SetViewportOrigin(const bool fAbsolute, const til::point coordWindowOrigin, const bool updateBottom);
bool SendNotifyBeep() const;
bool PostUpdateWindowSize() const;
// TODO: MSFT 9355062 these methods should probably be a part of construction/destruction. http://osgvsowi/9355062
static void s_InsertScreenBuffer(_In_ SCREEN_INFORMATION* const pScreenInfo);
static void s_RemoveScreenBuffer(_In_ SCREEN_INFORMATION* const pScreenInfo);
TextBufferCellIterator GetCellDataAt(const til::point at) const;
TextBufferCellIterator GetCellLineDataAt(const til::point at) const;
TextBufferCellIterator GetCellDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
TextBufferTextIterator GetTextDataAt(const til::point at) const;
TextBufferTextIterator GetTextLineDataAt(const til::point at) const;
TextBufferTextIterator GetTextDataAt(const til::point at, const Microsoft::Console::Types::Viewport limit) const;
OutputCellIterator Write(const OutputCellIterator it);
OutputCellIterator Write(const OutputCellIterator it,
const til::point target,
const std::optional<bool> wrap = true);
OutputCellIterator WriteRect(const OutputCellIterator it,
const Microsoft::Console::Types::Viewport viewport);
void WriteRect(const OutputCellRect& data,
const til::point location);
void ClearTextData();
std::pair<til::point, til::point> GetWordBoundary(const til::point position) const;
TextBuffer& GetTextBuffer() noexcept;
const TextBuffer& GetTextBuffer() const noexcept;
~SCREEN_INFORMATION() override;
#pragma region IIoProvider
SCREEN_INFORMATION& GetActiveOutputBuffer() override;
@ -166,129 +65,162 @@ public:
InputBuffer* const GetActiveInputBuffer() const override;
#pragma endregion
DWORD OutputMode{ ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT };
// NOTE: If your method has 200 chars worth of parameters, and it's hard to read
// without wrapping, chance is you're doing it wrong. This is also true here.
// Should have been a default constructor + setters / builder pattern.
// GetScreenBufferInformation could return a struct. And so on.
short WheelDelta{ 0 };
short HWheelDelta{ 0 };
private:
std::unique_ptr<TextBuffer> _textBuffer{ nullptr };
public:
SCREEN_INFORMATION* Next{ nullptr };
BYTE WriteConsoleDbcsLeadByte[2]{ 0, 0 };
BYTE FillOutDbcsLeadChar{ 0 };
UINT ScrollScale{ 1u };
// Creation
[[nodiscard]] static NTSTATUS CreateInstance(til::size windowSize, FontInfo fontInfo, til::size screenBufferSize, TextAttribute defaultAttributes, TextAttribute popupAttributes, UINT cursorSize, SCREEN_INFORMATION** screen);
static void s_InsertScreenBuffer(SCREEN_INFORMATION* screenInfo);
static void s_RemoveScreenBuffer(SCREEN_INFORMATION* screenInfo);
// Buffer
TextBuffer& GetTextBuffer() noexcept;
const TextBuffer& GetTextBuffer() const noexcept;
bool IsActiveScreenBuffer() const;
const Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() const;
Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine();
void SetCursorInformation(const ULONG Size,
const bool Visible) noexcept;
void SetCursorType(const CursorType Type, const bool setMain = false) noexcept;
void SetCursorDBMode(const bool DoubleCursor);
[[nodiscard]] NTSTATUS SetCursorPosition(til::point Position);
[[nodiscard]] NTSTATUS ResizeScreenBuffer(til::size newScreenSize, bool doScrollBarUpdate);
[[nodiscard]] NTSTATUS ResizeWithReflow(til::size newScreenSize);
[[nodiscard]] NTSTATUS ResizeTraditional(til::size newScreenSize);
[[nodiscard]] NTSTATUS UseAlternateScreenBuffer(const TextAttribute& initAttributes);
void UseMainScreenBuffer();
SCREEN_INFORMATION& GetMainBuffer();
const SCREEN_INFORMATION& GetMainBuffer() const;
const SCREEN_INFORMATION* GetAltBuffer() const noexcept;
SCREEN_INFORMATION& GetActiveBuffer();
const SCREEN_INFORMATION& GetActiveBuffer() const;
const TextAttribute& GetAttributes() const noexcept;
const TextAttribute& GetPopupAttributes() const noexcept;
void SetAttributes(const TextAttribute& attributes);
void SetPopupAttributes(const TextAttribute& popupAttributes);
void SetDefaultAttributes(const TextAttribute& attributes,
const TextAttribute& popupAttributes);
void SetDefaultAttributes(const TextAttribute& attributes, const TextAttribute& popupAttributes);
void ProcessResizeWindow(const til::rect* clientNew, const til::rect* clientOld);
void UpdateBottom();
// Cursor
[[nodiscard]] NTSTATUS SetCursorPosition(til::point Position);
void MakeCurrentCursorVisible();
void MakeCursorVisible(til::point position);
void SnapOnInput(WORD vkey);
SnapOnScopeExit SnapOnOutput() noexcept;
void SetCursorInformation(ULONG size, bool visible) noexcept;
void SetCursorType(CursorType type, bool setMain = false) noexcept;
void SetCursorDBMode(bool doubleCursor);
// I/O
const Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine() const;
Microsoft::Console::VirtualTerminal::StateMachine& GetStateMachine();
TextBufferCellIterator GetCellDataAt(til::point at) const;
TextBufferCellIterator GetCellLineDataAt(til::point at) const;
TextBufferCellIterator GetCellDataAt(til::point at, Microsoft::Console::Types::Viewport limit) const;
TextBufferTextIterator GetTextDataAt(til::point at) const;
TextBufferTextIterator GetTextLineDataAt(til::point at) const;
TextBufferTextIterator GetTextDataAt(til::point at, Microsoft::Console::Types::Viewport limit) const;
OutputCellIterator Write(OutputCellIterator it);
OutputCellIterator Write(OutputCellIterator it, til::point target, std::optional<bool> wrap = true);
OutputCellIterator WriteRect(OutputCellIterator it, Microsoft::Console::Types::Viewport viewport);
void WriteRect(const OutputCellRect& data, til::point location);
void ClearTextData();
// Rendering / Viewport
FontInfo& GetCurrentFont() noexcept;
const FontInfo& GetCurrentFont() const noexcept;
FontInfoDesired& GetDesiredFont() noexcept;
const FontInfoDesired& GetDesiredFont() const noexcept;
til::size GetScreenFontSize() const;
void UpdateFont(const FontInfo* newFont);
void RefreshFontWithRenderer();
[[nodiscard]] NTSTATUS SetViewportOrigin(bool absolute, til::point coordWindowOrigin, bool updateBottom);
const Microsoft::Console::Types::Viewport& GetViewport() const noexcept;
void SetViewport(const Microsoft::Console::Types::Viewport& newViewport, bool updateBottom);
void SetViewportSize(const til::size* size);
void UpdateBottom();
Microsoft::Console::Types::Viewport GetVirtualViewport() const noexcept;
Microsoft::Console::Types::Viewport GetVtPageArea() const noexcept;
[[nodiscard]] NTSTATUS ResizeWithReflow(const til::size coordnewScreenSize);
[[nodiscard]] NTSTATUS ResizeTraditional(const til::size coordNewScreenSize);
// Windowing
til::size GetScrollBarSizesInCharacters() const;
void UpdateScrollBars();
ScrollBarState FetchScrollBarState();
bool IsMaximizedBoth() const;
bool IsMaximizedX() const;
bool IsMaximizedY() const;
bool PostUpdateWindowSize() const;
// General Information
void GetScreenBufferInformation(til::size* size, til::point* cursorPosition, til::inclusive_rect* window, PWORD attributes, til::size* maximumWindowSize, PWORD popupAttributes, LPCOLORREF colorTable) const;
void GetRequiredConsoleSizeInPixels(til::size* requiredSize) const;
til::size GetMinWindowSizeInCharacters(til::size fontSize = { 1, 1 }) const;
til::size GetMaxWindowSizeInCharacters(til::size fontSize = { 1, 1 }) const;
til::size GetLargestWindowSizeInCharacters(til::size fontSize = { 1, 1 }) const;
// Helpers
void ClipToScreenBuffer(til::inclusive_rect* clip) const;
std::pair<til::point, til::point> GetWordBoundary(til::point position) const;
Microsoft::Console::Types::Viewport GetBufferSize() const;
Microsoft::Console::Types::Viewport GetTerminalBufferSize() const;
bool SendNotifyBeep() const;
bool ConptyCursorPositionMayBeWrong() const noexcept;
void SetConptyCursorPositionMayBeWrong() noexcept;
void ResetConptyCursorPositionMayBeWrong() noexcept;
void WaitForConptyCursorPositionToBeSynchronized() noexcept;
DWORD OutputMode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
short WheelDelta = 0;
short HWheelDelta = 0;
SCREEN_INFORMATION* Next = nullptr;
BYTE WriteConsoleDbcsLeadByte[2] = { 0, 0 };
BYTE FillOutDbcsLeadChar = 0;
UINT ScrollScale = 1;
private:
SCREEN_INFORMATION(_In_ Microsoft::Console::Interactivity::IWindowMetrics* pMetrics,
const TextAttribute popupAttributes,
const FontInfo fontInfo);
Microsoft::Console::Interactivity::IWindowMetrics* _pConsoleWindowMetrics;
[[nodiscard]] HRESULT _AdjustScreenBufferHelper(const til::rect* const prcClientNew,
const til::size coordBufferOld,
_Out_ til::size* const pcoordClientNewCharacters);
[[nodiscard]] HRESULT _AdjustScreenBuffer(const til::rect* const prcClientNew);
void _CalculateViewportSize(const til::rect* const prcClientArea, _Out_ til::size* const pcoordSize);
void _AdjustViewportSize(const til::rect* const prcClientNew, const til::rect* const prcClientOld, const til::size* const pcoordSize);
void _InternalSetViewportSize(const til::size* pcoordSize, const bool fResizeFromTop, const bool fResizeFromLeft);
void _makeCursorVisible();
static void s_CalculateScrollbarVisibility(const til::rect* const prcClientArea,
const til::size* const pcoordBufferSize,
const til::size* const pcoordFontSize,
_Out_ bool* const pfIsHorizontalVisible,
_Out_ bool* const pfIsVerticalVisible);
SCREEN_INFORMATION(Microsoft::Console::Interactivity::IWindowMetrics* metrics, TextAttribute popupAttributes, FontInfo fontInfo);
// Construction
[[nodiscard]] NTSTATUS _InitializeOutputStateMachine();
void _FreeOutputStateMachine();
[[nodiscard]] NTSTATUS _CreateAltBuffer(const TextAttribute& initAttributes,
_Out_ SCREEN_INFORMATION** const ppsiNewScreenBuffer);
// Buffer
[[nodiscard]] HRESULT _AdjustScreenBufferHelper(const til::rect* clientNew, til::size bufferOld, til::size* clientNewCharacters);
[[nodiscard]] HRESULT _AdjustScreenBuffer(const til::rect* clientNew);
[[nodiscard]] NTSTATUS _CreateAltBuffer(const TextAttribute& initAttributes, SCREEN_INFORMATION** newScreenBuffer);
bool _IsAltBuffer() const;
bool _IsInPtyMode() const;
bool _IsInVTMode() const;
// Cursor
void _makeCursorVisible();
// Rendering / Viewport
void _CalculateViewportSize(const til::rect* clientArea, til::size* size);
void _AdjustViewportSize(const til::rect* clientNew, const til::rect* clientOld, const til::size* size);
void _InternalSetViewportSize(const til::size* size, bool resizeFromTop, bool resizeFromLeft);
// Windowing
static void s_CalculateScrollbarVisibility(const til::rect* clientArea, const til::size* bufferSize, const til::size* fontSize, bool* horizontalVisible, bool* verticalVisible);
static void _handleDeferredResize(SCREEN_INFORMATION& siMain);
Microsoft::Console::Interactivity::IWindowMetrics* _pConsoleWindowMetrics;
std::unique_ptr<TextBuffer> _textBuffer{ nullptr };
ConhostInternalGetSet _api{ *this };
std::shared_ptr<Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine{ nullptr };
std::shared_ptr<Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
// Specifies which coordinates of the screen buffer are visible in the
// window client (the "viewport" into the buffer)
Microsoft::Console::Types::Viewport _viewport;
SCREEN_INFORMATION* _psiAlternateBuffer{ nullptr }; // The VT "Alternate" screen buffer.
SCREEN_INFORMATION* _psiMainBuffer{ nullptr }; // A pointer to the main buffer, if this is the alternate buffer.
til::rect _rcAltSavedClientNew{};
til::rect _rcAltSavedClientOld{};
bool _fAltWindowChanged{ false };
SCREEN_INFORMATION* _psiAlternateBuffer = nullptr; // The VT "Alternate" screen buffer.
SCREEN_INFORMATION* _psiMainBuffer = nullptr; // A pointer to the main buffer, if this is the alternate buffer.
til::rect _rcAltSavedClientNew;
til::rect _rcAltSavedClientOld;
bool _fAltWindowChanged = false;
TextAttribute _PopupAttributes;
FontInfo _currentFont;
FontInfoDesired _desiredFont;
// Tracks the last virtual position the viewport was at. This is not
// affected by the user scrolling the viewport, only when API calls cause
// the viewport to move (SetBufferInfo, WriteConsole, etc)
til::CoordType _virtualBottom{ 0 };
std::optional<til::size> _deferredPtyResize{ std::nullopt };
til::CoordType _virtualBottom = 0;
std::optional<til::size> _deferredPtyResize;
std::atomic<bool> _conptyCursorPositionMayBeWrong = false;
static void _handleDeferredResize(SCREEN_INFORMATION& siMain);
#ifdef UNIT_TESTING
friend class TextBufferIteratorTests;
friend class ScreenBufferTests;