7b7dea009c
Instead of having a separate method for setting each mouse and keyboard mode, this PR consolidates them all into a single method which takes a mode parameter, and stores the modes in a `til::enumset` rather than having a separate `bool` for each mode. This enables us to get rid of a lot of boilerplate code, and makes the code easier to extend when we want to introduce additional modes in the future. It'll also makes it easier to read back the state of the various modes when implementing the `DECRQM` query. Most of the complication is in the `TerminalInput` class, which had to be adjusted to work with an `enumset` in place of all the `bool` fields. For the rest, it was largely a matter of replacing calls to all the old mode setting methods with the new `SetInputMode` method, and deleting a bunch of unused code. One thing worth mentioning is that the `AdaptDispatch` implementation used to have a `_ShouldPassThroughInputModeChange` method that was called after every mode change. This code has now been moved up into the `SetInputMode` implementation in `ConhostInternalGetSet` so it's just handled in one place. Keeping this out of the dispatch class will also be beneficial for sharing the implementation with `TerminalDispatch`. ## Validation The updated interface necessitated some adjustments to the tests in `AdapterTest` and `MouseInputTest`, but the essential structure of the tests remains unchanged, and everything still passes. I've also tested the keyboard and mouse modes in Vttest and confirmed they still work at least as well as they did before (both conhost and Windows Terminal), and I tested the alternate scroll mode manually (conhost only). Simplifying the `ConGetSet` and `ITerminalApi` is also part of the plan to de-duplicate the `AdaptDispatch` and `TerminalDispatch` implementation (#3849).
227 lines
11 KiB
C++
227 lines
11 KiB
C++
/*++
|
|
Copyright (c) Microsoft Corporation
|
|
Licensed under the MIT license.
|
|
|
|
Module Name:
|
|
- adaptDispatch.hpp
|
|
|
|
Abstract:
|
|
- This serves as the Windows Console API-specific implementation of the callbacks from our generic Virtual Terminal parser.
|
|
|
|
Author(s):
|
|
- Michael Niksa (MiNiksa) 30-July-2015
|
|
--*/
|
|
|
|
#pragma once
|
|
|
|
#include "termDispatch.hpp"
|
|
#include "DispatchCommon.hpp"
|
|
#include "conGetSet.hpp"
|
|
#include "adaptDefaults.hpp"
|
|
#include "FontBuffer.hpp"
|
|
#include "terminalOutput.hpp"
|
|
#include "..\..\types\inc\sgrStack.hpp"
|
|
|
|
namespace Microsoft::Console::VirtualTerminal
|
|
{
|
|
class AdaptDispatch : public ITermDispatch
|
|
{
|
|
public:
|
|
AdaptDispatch(std::unique_ptr<ConGetSet> pConApi,
|
|
std::unique_ptr<AdaptDefaults> pDefaults);
|
|
|
|
void Execute(const wchar_t wchControl) override
|
|
{
|
|
_pDefaults->Execute(wchControl);
|
|
}
|
|
|
|
void PrintString(const std::wstring_view string) override;
|
|
void Print(const wchar_t wchPrintable) override;
|
|
|
|
bool CursorUp(const size_t distance) override; // CUU
|
|
bool CursorDown(const size_t distance) override; // CUD
|
|
bool CursorForward(const size_t distance) override; // CUF
|
|
bool CursorBackward(const size_t distance) override; // CUB, BS
|
|
bool CursorNextLine(const size_t distance) override; // CNL
|
|
bool CursorPrevLine(const size_t distance) override; // CPL
|
|
bool CursorHorizontalPositionAbsolute(const size_t column) override; // HPA, CHA
|
|
bool VerticalLinePositionAbsolute(const size_t line) override; // VPA
|
|
bool HorizontalPositionRelative(const size_t distance) override; // HPR
|
|
bool VerticalPositionRelative(const size_t distance) override; // VPR
|
|
bool CursorPosition(const size_t line, const size_t column) override; // CUP, HVP
|
|
bool CursorSaveState() override; // DECSC
|
|
bool CursorRestoreState() override; // DECRC
|
|
bool CursorVisibility(const bool isVisible) override; // DECTCEM
|
|
bool EraseInDisplay(const DispatchTypes::EraseType eraseType) override; // ED
|
|
bool EraseInLine(const DispatchTypes::EraseType eraseType) override; // EL
|
|
bool EraseCharacters(const size_t numChars) override; // ECH
|
|
bool InsertCharacter(const size_t count) override; // ICH
|
|
bool DeleteCharacter(const size_t count) override; // DCH
|
|
bool SetGraphicsRendition(const VTParameters options) override; // SGR
|
|
bool SetLineRendition(const LineRendition rendition) override; // DECSWL, DECDWL, DECDHL
|
|
bool PushGraphicsRendition(const VTParameters options) override; // XTPUSHSGR
|
|
bool PopGraphicsRendition() override; // XTPOPSGR
|
|
bool DeviceStatusReport(const DispatchTypes::AnsiStatusType statusType) override; // DSR, DSR-OS, DSR-CPR
|
|
bool DeviceAttributes() override; // DA1
|
|
bool SecondaryDeviceAttributes() override; // DA2
|
|
bool TertiaryDeviceAttributes() override; // DA3
|
|
bool Vt52DeviceAttributes() override; // VT52 Identify
|
|
bool RequestTerminalParameters(const DispatchTypes::ReportingPermission permission) override; // DECREQTPARM
|
|
bool ScrollUp(const size_t distance) override; // SU
|
|
bool ScrollDown(const size_t distance) override; // SD
|
|
bool InsertLine(const size_t distance) override; // IL
|
|
bool DeleteLine(const size_t distance) override; // DL
|
|
bool SetColumns(const size_t columns) override; // DECCOLM
|
|
bool SetMode(const DispatchTypes::ModeParams param) override; // DECSET
|
|
bool ResetMode(const DispatchTypes::ModeParams param) override; // DECRST
|
|
bool SetCursorKeysMode(const bool applicationMode) override; // DECCKM
|
|
bool SetKeypadMode(const bool applicationMode) override; // DECKPAM, DECKPNM
|
|
bool EnableWin32InputMode(const bool win32InputMode) override; // win32-input-mode
|
|
bool EnableCursorBlinking(const bool enable) override; // ATT610
|
|
bool SetAnsiMode(const bool ansiMode) override; // DECANM
|
|
bool SetScreenMode(const bool reverseMode) override; // DECSCNM
|
|
bool SetOriginMode(const bool relativeMode) noexcept override; // DECOM
|
|
bool SetAutoWrapMode(const bool wrapAtEOL) override; // DECAWM
|
|
bool SetTopBottomScrollingMargins(const size_t topMargin,
|
|
const size_t bottomMargin) override; // DECSTBM
|
|
bool WarningBell() override; // BEL
|
|
bool CarriageReturn() override; // CR
|
|
bool LineFeed(const DispatchTypes::LineFeedType lineFeedType) override; // IND, NEL, LF, FF, VT
|
|
bool ReverseLineFeed() override; // RI
|
|
bool SetWindowTitle(const std::wstring_view title) override; // OSCWindowTitle
|
|
bool UseAlternateScreenBuffer() override; // ASBSET
|
|
bool UseMainScreenBuffer() override; // ASBRST
|
|
bool HorizontalTabSet() override; // HTS
|
|
bool ForwardTab(const size_t numTabs) override; // CHT, HT
|
|
bool BackwardsTab(const size_t numTabs) override; // CBT
|
|
bool TabClear(const DispatchTypes::TabClearType clearType) override; // TBC
|
|
bool DesignateCodingSystem(const VTID codingSystem) override; // DOCS
|
|
bool Designate94Charset(const size_t gsetNumber, const VTID charset) override; // SCS
|
|
bool Designate96Charset(const size_t gsetNumber, const VTID charset) override; // SCS
|
|
bool LockingShift(const size_t gsetNumber) override; // LS0, LS1, LS2, LS3
|
|
bool LockingShiftRight(const size_t gsetNumber) override; // LS1R, LS2R, LS3R
|
|
bool SingleShift(const size_t gsetNumber) override; // SS2, SS3
|
|
bool SoftReset() override; // DECSTR
|
|
bool HardReset() override; // RIS
|
|
bool ScreenAlignmentPattern() override; // DECALN
|
|
bool EnableDECCOLMSupport(const bool enabled) noexcept override; // ?40
|
|
bool EnableVT200MouseMode(const bool enabled) override; // ?1000
|
|
bool EnableUTF8ExtendedMouseMode(const bool enabled) override; // ?1005
|
|
bool EnableSGRExtendedMouseMode(const bool enabled) override; // ?1006
|
|
bool EnableButtonEventMouseMode(const bool enabled) override; // ?1002
|
|
bool EnableAnyEventMouseMode(const bool enabled) override; // ?1003
|
|
bool EnableAlternateScroll(const bool enabled) override; // ?1007
|
|
bool EnableXtermBracketedPasteMode(const bool enabled) noexcept override; // ?2004
|
|
bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) override; // DECSCUSR
|
|
bool SetCursorColor(const COLORREF cursorColor) override;
|
|
|
|
bool SetClipboard(const std::wstring_view content) noexcept override; // OSCSetClipboard
|
|
|
|
bool SetColorTableEntry(const size_t tableIndex,
|
|
const DWORD color) override; // OSCColorTable
|
|
bool SetDefaultForeground(const DWORD color) override; // OSCDefaultForeground
|
|
bool SetDefaultBackground(const DWORD color) override; // OSCDefaultBackground
|
|
|
|
bool WindowManipulation(const DispatchTypes::WindowManipulationType function,
|
|
const VTParameter parameter1,
|
|
const VTParameter parameter2) override; // DTTERM_WindowManipulation
|
|
|
|
bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) override;
|
|
bool EndHyperlink() override;
|
|
|
|
bool DoConEmuAction(const std::wstring_view string) noexcept override;
|
|
|
|
StringHandler DownloadDRCS(const size_t fontNumber,
|
|
const VTParameter startChar,
|
|
const DispatchTypes::DrcsEraseControl eraseControl,
|
|
const DispatchTypes::DrcsCellMatrix cellMatrix,
|
|
const DispatchTypes::DrcsFontSet fontSet,
|
|
const DispatchTypes::DrcsFontUsage fontUsage,
|
|
const VTParameter cellHeight,
|
|
const DispatchTypes::DrcsCharsetSize charsetSize) override; // DECDLD
|
|
|
|
StringHandler RequestSetting() override; // DECRQSS
|
|
|
|
private:
|
|
enum class ScrollDirection
|
|
{
|
|
Up,
|
|
Down
|
|
};
|
|
struct CursorState
|
|
{
|
|
unsigned int Row = 1;
|
|
unsigned int Column = 1;
|
|
bool IsOriginModeRelative = false;
|
|
TextAttribute Attributes = {};
|
|
TerminalOutput TermOutput = {};
|
|
unsigned int CodePage = 0;
|
|
};
|
|
struct Offset
|
|
{
|
|
int Value;
|
|
bool IsAbsolute;
|
|
// VT origin is at 1,1 so we need to subtract 1 from absolute positions.
|
|
static constexpr Offset Absolute(const size_t value) { return { gsl::narrow_cast<int>(value) - 1, true }; };
|
|
static constexpr Offset Forward(const size_t value) { return { gsl::narrow_cast<int>(value), false }; };
|
|
static constexpr Offset Backward(const size_t value) { return { -gsl::narrow_cast<int>(value), false }; };
|
|
static constexpr Offset Unchanged() { return Forward(0); };
|
|
};
|
|
|
|
bool _CursorMovePosition(const Offset rowOffset, const Offset colOffset, const bool clampInMargins) const;
|
|
bool _EraseSingleLineHelper(const CONSOLE_SCREEN_BUFFER_INFOEX& csbiex,
|
|
const DispatchTypes::EraseType eraseType,
|
|
const size_t lineId) const;
|
|
bool _EraseScrollback();
|
|
bool _EraseAll();
|
|
bool _InsertDeleteHelper(const size_t count, const bool isInsert) const;
|
|
bool _ScrollMovement(const ScrollDirection dir, const size_t distance) const;
|
|
|
|
bool _DoSetTopBottomScrollingMargins(const size_t topMargin,
|
|
const size_t bottomMargin);
|
|
bool _OperatingStatus() const;
|
|
bool _CursorPositionReport() const;
|
|
|
|
bool _WriteResponse(const std::wstring_view reply) const;
|
|
bool _ModeParamsHelper(const DispatchTypes::ModeParams param, const bool enable);
|
|
bool _DoDECCOLMHelper(const size_t columns);
|
|
|
|
bool _ClearSingleTabStop();
|
|
bool _ClearAllTabStops() noexcept;
|
|
void _ResetTabStops() noexcept;
|
|
void _InitTabStopsForWidth(const size_t width);
|
|
|
|
void _ReportSGRSetting() const;
|
|
void _ReportDECSTBMSetting() const;
|
|
|
|
std::vector<bool> _tabStopColumns;
|
|
bool _initDefaultTabStops = true;
|
|
|
|
std::unique_ptr<ConGetSet> _pConApi;
|
|
std::unique_ptr<AdaptDefaults> _pDefaults;
|
|
TerminalOutput _termOutput;
|
|
std::unique_ptr<FontBuffer> _fontBuffer;
|
|
std::optional<unsigned int> _initialCodePage;
|
|
|
|
// We have two instances of the saved cursor state, because we need
|
|
// one for the main buffer (at index 0), and another for the alt buffer
|
|
// (at index 1). The _usingAltBuffer property keeps tracks of which
|
|
// buffer is active, so can be used as an index into this array to
|
|
// obtain the saved state that should be currently active.
|
|
std::array<CursorState, 2> _savedCursorState;
|
|
bool _usingAltBuffer;
|
|
|
|
SMALL_RECT _scrollMargins;
|
|
|
|
bool _isOriginModeRelative;
|
|
|
|
bool _isDECCOLMAllowed;
|
|
|
|
SgrStack _sgrStack;
|
|
|
|
size_t _SetRgbColorsHelper(const VTParameters options,
|
|
TextAttribute& attr,
|
|
const bool isForeground) noexcept;
|
|
};
|
|
}
|