2019-05-03 00:29:04 +02:00
|
|
|
// Copyright (c) Microsoft Corporation.
|
|
|
|
// Licensed under the MIT license.
|
|
|
|
|
|
|
|
#include "../../terminal/adapter/termDispatch.hpp"
|
|
|
|
#include "ITerminalApi.hpp"
|
|
|
|
|
|
|
|
class TerminalDispatch : public Microsoft::Console::VirtualTerminal::TermDispatch
|
|
|
|
{
|
|
|
|
public:
|
2020-01-03 19:44:27 +01:00
|
|
|
TerminalDispatch(::Microsoft::Terminal::Core::ITerminalApi& terminalApi) noexcept;
|
|
|
|
|
|
|
|
void Execute(const wchar_t wchControl) noexcept override;
|
|
|
|
void Print(const wchar_t wchPrintable) noexcept override;
|
|
|
|
void PrintString(const std::wstring_view string) noexcept override;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-07-15 18:40:42 +02:00
|
|
|
bool SetGraphicsRendition(const gsl::span<const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options) noexcept override;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-01-03 19:44:27 +01:00
|
|
|
bool CursorPosition(const size_t line,
|
|
|
|
const size_t column) noexcept override; // CUP
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-06-09 00:31:28 +02:00
|
|
|
bool EnableWin32InputMode(const bool win32InputMode) noexcept override; // win32-input-mode
|
|
|
|
|
2020-03-13 18:39:42 +01:00
|
|
|
bool CursorVisibility(const bool isVisible) noexcept override; // DECTCEM
|
|
|
|
bool EnableCursorBlinking(const bool enable) noexcept override; // ATT610
|
|
|
|
|
2020-01-03 15:25:21 +01:00
|
|
|
bool CursorForward(const size_t distance) noexcept override;
|
|
|
|
bool CursorBackward(const size_t distance) noexcept override;
|
|
|
|
bool CursorUp(const size_t distance) noexcept override;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
Add support for all the line feed control sequences (#3271)
## Summary of the Pull Request
This adds support for the `FF` (form feed) and `VT` (vertical tab) [control characters](https://vt100.net/docs/vt510-rm/chapter4.html#T4-1), as well as the [`NEL` (Next Line)](https://vt100.net/docs/vt510-rm/NEL.html) and [`IND` (Index)](https://vt100.net/docs/vt510-rm/IND.html) escape sequences.
## References
#976 discusses the conflict between VT100 Index sequence and the VT52 cursor back sequence.
## PR Checklist
* [x] Closes #3189
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #3189
## Detailed Description of the Pull Request / Additional comments
I've added a `LineFeed` method to the `ITermDispatch` interface, with an enum parameter specifying the required line feed type (i.e. with carriage return, without carriage return, or dependent on the [`LNM` mode](https://vt100.net/docs/vt510-rm/LNM.html)). The output state machine can then call that method to handle the various line feed control characters (parsed in the `ActionExecute` method), as well the `NEL` and `IND` escape sequences (parsed in the `ActionEscDispatch` method).
The `AdaptDispatch` implementation of `LineFeed` then forwards the call to a new `PrivateLineFeed` method in the `ConGetSet` interface, which simply takes a bool parameter specifying whether a carriage return is required or not. In the case of mode-dependent line feeds, the `AdaptDispatch` implementation determines whether the return is necessary or not, based on the existing _AutoReturnOnNewLine_ setting (which I'm obtaining via another new `PrivateGetLineFeedMode` method).
Ultimately we'll want to support changing the mode via the [`LNM` escape sequence](https://vt100.net/docs/vt510-rm/LNM.html), but there's no urgent need for that now. And using the existing _AutoReturnOnNewLine_ setting as a substitute for the mode gives us backwards compatible behaviour, since that will be true for the Windows shells (which expect a linefeed to also generate a carriage return), and false in a WSL bash shell (which won't want the carriage return by default).
As for the actual `PrivateLineFeed` implementation, that is just a simplified version of how the line feed would previously have been executed in the `WriteCharsLegacy` function. This includes setting the cursor to "On" (with `Cursor::SetIsOn`), potentially clearing the wrap property of the line being left (with `CharRow::SetWrapForced` false), and then setting the new position using `AdjustCursorPosition` with the _fKeepCursorVisible_ parameter set to false.
I'm unsure whether the `SetIsOn` call is really necessary, and I think the way the forced wrap is handled needs a rethink in general, but for now this should at least be compatible with the existing behaviour.
Finally, in order to make this all work in the _Windows Terminal_ app, I also had to add a basic implementation of the `ITermDispatch::LineFeed` method in the `TerminalDispatch` class. There is currently no need to support mode-specific line feeds here, so this simply forwards a `\n` or `\r\n` to the `Execute` method, which is ultimately handled by the `Terminal::_WriteBuffer` implementation.
## Validation Steps Performed
I've added output engine tests which confirm that the various control characters and escape sequences trigger the dispatch method correctly. Then I've added adapter tests which confirm the various dispatch options trigger the `PrivateLineFeed` API correctly. And finally I added some screen buffer tests that check the actual results of the `NEL` and `IND` sequences, which covers both forms of the `PrivateLineFeed` API (i.e. with and without a carriage return).
I've also run the _Test of cursor movements_ in the [Vttest](https://invisible-island.net/vttest/) utility, and confirmed that screens 1, 2, and 5 are now working correctly. The first two depend on `NEL` and `IND` being supported, and screen 5 requires the `VT` control character.
2020-01-15 14:41:55 +01:00
|
|
|
bool LineFeed(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::LineFeedType lineFeedType) noexcept override;
|
|
|
|
|
2020-01-03 15:25:21 +01:00
|
|
|
bool EraseCharacters(const size_t numChars) noexcept override;
|
Dispatch more C0 control characters from the VT state machine (#4171)
This commit moves the handling of the `BEL`, `BS`, `TAB`, and `CR`
controls characters into the state machine (when in VT mode), instead of
forwarding them on to the default string writer, which would otherwise
have to parse them out all over again.
This doesn't cover all the control characters, but `ESC`, `SUB`, and
`CAN` are already an integral part of the `StateMachine` itself; `NUL`
is filtered out by the `OutputStateMachineEngine`; and `LF`, `FF`, and
`VT` are due to be implemented as part of PR #3271.
Once all of these controls are handled at the state machine level, we
can strip out all the VT-specific code from the `WriteCharsLegacy`
function, which should simplify it considerably. This would also let us
simplify the `Terminal::_WriteBuffer` implementation, and the planned
replacement stream writer for issue #780.
On the conhost side, the implementation is handled as follows:
* The `BS` control is dispatched to the existing `CursorBackward`
method, with a distance of 1.
* The `TAB` control is dispatched to the existing `ForwardTab` method,
with a tab count of 1.
* The `CR` control required a new dispatch method, but the
implementation was a simple call to the new `_CursorMovePosition` method
from PR #3628.
* The `BEL` control also required a new dispatch method, as well as an
additional private API in the `ConGetSet` interface. But that's mostly
boilerplate code - ultimately it just calls the `SendNotifyBeep` method.
On the Windows Terminal side, not all dispatch methods are implemented.
* There is an existing `CursorBackward` implementation, so `BS` works
OK.
* There isn't a `ForwardTab` implementation, but `TAB` isn't currently
required by the conpty protocol.
* I had to implement the `CarriageReturn` dispatch method, but that was
a simple call to `Terminal::SetCursorPosition`.
* The `WarningBell` method I've left unimplemented, because that
functionality wasn't previously supported anyway, and there's an
existing issue for that (#4046).
## Validation Steps Performed
I've added a state machine test to confirm that the updated control
characters are now forwarded to the appropriate dispatch handlers. But
since the actual implementation is mostly relying on existing
functionality, I'm assuming that code is already adequately tested
elsewhere. That said, I have also run various manual tests of my own,
and confirmed that everything still worked as well as before.
References #3271
References #780
References #3628
References #4046
2020-01-17 02:43:21 +01:00
|
|
|
bool CarriageReturn() noexcept override;
|
2020-01-03 15:25:21 +01:00
|
|
|
bool SetWindowTitle(std::wstring_view title) noexcept override;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-01-03 15:25:21 +01:00
|
|
|
bool SetColorTableEntry(const size_t tableIndex, const DWORD color) noexcept override;
|
|
|
|
bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) noexcept override;
|
2020-07-31 00:24:59 +02:00
|
|
|
bool SetCursorColor(const DWORD color) noexcept override;
|
2019-05-03 00:29:04 +02:00
|
|
|
|
2020-06-30 03:55:40 +02:00
|
|
|
bool SetClipboard(std::wstring_view content) noexcept override;
|
|
|
|
|
2020-01-03 15:25:21 +01:00
|
|
|
bool SetDefaultForeground(const DWORD color) noexcept override;
|
|
|
|
bool SetDefaultBackground(const DWORD color) noexcept override;
|
|
|
|
bool EraseInLine(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override; // ED
|
|
|
|
bool DeleteCharacter(const size_t count) noexcept override;
|
|
|
|
bool InsertCharacter(const size_t count) noexcept override;
|
|
|
|
bool EraseInDisplay(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::EraseType eraseType) noexcept override;
|
2019-05-24 18:53:00 +02:00
|
|
|
|
2020-03-13 01:44:28 +01:00
|
|
|
bool SetCursorKeysMode(const bool applicationMode) noexcept override; // DECCKM
|
|
|
|
bool SetKeypadMode(const bool applicationMode) noexcept override; // DECKPAM, DECKPNM
|
2020-07-09 13:25:30 +02:00
|
|
|
bool SetScreenMode(const bool reverseMode) noexcept override; // DECSCNM
|
2020-03-13 01:44:28 +01:00
|
|
|
|
2020-03-16 16:32:01 +01:00
|
|
|
bool SoftReset() noexcept override; // DECSTR
|
|
|
|
bool HardReset() noexcept override; // RIS
|
|
|
|
|
2020-03-13 01:44:28 +01:00
|
|
|
bool EnableVT200MouseMode(const bool enabled) noexcept override; // ?1000
|
|
|
|
bool EnableUTF8ExtendedMouseMode(const bool enabled) noexcept override; // ?1005
|
|
|
|
bool EnableSGRExtendedMouseMode(const bool enabled) noexcept override; // ?1006
|
|
|
|
bool EnableButtonEventMouseMode(const bool enabled) noexcept override; // ?1002
|
|
|
|
bool EnableAnyEventMouseMode(const bool enabled) noexcept override; // ?1003
|
|
|
|
bool EnableAlternateScroll(const bool enabled) noexcept override; // ?1007
|
|
|
|
|
2020-07-15 18:40:42 +02:00
|
|
|
bool SetPrivateModes(const gsl::span<const ::Microsoft::Console::VirtualTerminal::DispatchTypes::PrivateModeParams> /*params*/) noexcept override; // DECSET
|
|
|
|
bool ResetPrivateModes(const gsl::span<const ::Microsoft::Console::VirtualTerminal::DispatchTypes::PrivateModeParams> /*params*/) noexcept override; // DECRST
|
2020-03-13 01:44:28 +01:00
|
|
|
|
2020-09-03 19:52:39 +02:00
|
|
|
bool AddHyperlink(const std::wstring_view uri, const std::wstring_view params) noexcept override;
|
|
|
|
bool EndHyperlink() noexcept override;
|
|
|
|
|
2019-05-03 00:29:04 +02:00
|
|
|
private:
|
|
|
|
::Microsoft::Terminal::Core::ITerminalApi& _terminalApi;
|
|
|
|
|
2020-07-15 18:40:42 +02:00
|
|
|
size_t _SetRgbColorsHelper(const gsl::span<const ::Microsoft::Console::VirtualTerminal::DispatchTypes::GraphicsOptions> options,
|
Refactor TerminalDispatch (graphics) to match AdaptDispatch (#6728)
This is essentially a rewrite of the
`TerminalDispatch::SetGraphicsRendition` method, bringing it into closer
alignment with the `AdaptDispatch` implementation, simplifying the
`ITerminalApi` interface, and making the code easier to extend. It adds
support for a number of attributes which weren't previously implemented.
REFERENCES
* This is a mirror of the `AdaptDispatch` refactoring in PR #5758.
* The closer alignment with `AdaptDispatch` is a small step towards
solving issue #3849.
* The newly supported attributes should help a little with issues #5461
(italics) and #6205 (strike-through).
DETAILS
I've literally copied and pasted the `SetGraphicsRendition`
implementation from `AdaptDispatch` into `TerminalDispatch`, with only
few minor changes:
* The `SetTextAttribute` and `GetTextAttribute` calls are slightly
different in the `TerminalDispatch` version, since they don't return a
pointless `success` value, and in the case of the getter, the
`TextAttribute` is returned directly instead of by reference.
Ultimately I'd like to move the `AdaptDispatch` code towards that way
of doing things too, but I'd like to deal with that later as part of a
wider refactoring of the `ConGetSet` interface.
* The `SetIndexedForeground256` and `SetIndexedBackground256` calls
required the color indices to be remapped in the `AdaptDispatch`
implementation, because the conhost color table is in a different
order to the XTerm standard. `TerminalDispatch` doesn't have that
problem, so doesn't require the mapping.
* The index color constants used in the 16-color `SetIndexedForeground`
and `SetIndexedBackground` calls are also slightly different for the
same reason.
VALIDATION
I cherry-picked this code on top of the #6506 and #6698 PRs, since
that's only way to really get the different color formats passed-through
to the terminal. I then ran a bunch of manual tests with various color
coverage scripts that I have, and confirmed that all the different color
formats were being rendered as expected.
Closes #6725
2020-07-01 20:13:42 +02:00
|
|
|
TextAttribute& attr,
|
|
|
|
const bool isForeground) noexcept;
|
2020-03-13 01:44:28 +01:00
|
|
|
|
2020-07-15 18:40:42 +02:00
|
|
|
bool _SetResetPrivateModes(const gsl::span<const ::Microsoft::Console::VirtualTerminal::DispatchTypes::PrivateModeParams> params, const bool enable) noexcept;
|
2020-03-13 01:44:28 +01:00
|
|
|
bool _PrivateModeParamsHelper(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::PrivateModeParams param, const bool enable) noexcept;
|
2019-05-03 00:29:04 +02:00
|
|
|
};
|