From c91004518726480a59a0abbc6f9bd55a10010e13 Mon Sep 17 00:00:00 2001 From: Dustin Howett Date: Tue, 28 May 2019 22:51:48 +0000 Subject: [PATCH] Merged PR 3315789: Migrate GitHub changes up until cfc72cee * cfc72cee (origin/dev/duhowett/ibxint, github/master) Make sure cursor blinks after opening new tab (1030) * 9ad25440 Fix #936: misuse of uninitialized objects causes AppVerifier breaks on Windows Terminal startup (1015) * 5f938a04 Update Terminal.cpp (1034) * 4c47631b Cleanup - termDispatch.hpp & adaptDispatch.hpp overrides (1004) * cc304759 add audit mode to ci (948) * 80f10796 Fix the bell sound when Alt+key is pressed. (1006) * 42e87ed3 fix build break from using `await` instead of `co_await` (1009) * 40b557a4 Update manifest to correct 1903 version, unref param fix (1008) * 0f62ec81 Eat all tap keypresses no matter what. (985) * ce0eaab9 inbox: Merge accumulated build fixes from RS_ONECORE_DEP_ACIOSS (1002) * 1c509683 add .editorconfig file (585) * efd69990 Add support for OSC 10 and 11 to set the default colors (891) Related work items: #21610659, #21838182 --- .editorconfig | 13 ++ .gitignore | 1 - build/pipelines/ci.yml | 4 + build/pipelines/release.yml | 4 + .../templates/build-console-audit-job.yml | 53 ++++++++ .../pipelines/templates/build-console-ci.yml | 4 +- .../pipelines/templates/build-console-int.yml | 4 +- .../templates/release-sign-and-bundle.yml | 16 ++- src/StaticAnalysis.ruleset | 7 + src/buffer/out/precomp.h | 1 - src/cascadia/TerminalApp/App.cpp | 6 +- src/cascadia/TerminalApp/App.h | 2 - .../CascadiaSettingsSerialization.cpp | 2 - src/cascadia/TerminalConnection/pch.h | 1 - src/cascadia/TerminalControl/TermControl.cpp | 104 +++++++++----- src/cascadia/TerminalControl/TermControl.h | 1 + src/cascadia/TerminalCore/ITerminalApi.hpp | 3 + src/cascadia/TerminalCore/Terminal.cpp | 11 +- src/cascadia/TerminalCore/Terminal.hpp | 6 +- src/cascadia/TerminalCore/TerminalApi.cpp | 33 ++++- .../TerminalCore/TerminalDispatch.cpp | 24 +++- .../TerminalCore/TerminalDispatch.hpp | 3 + src/cascadia/WindowsTerminal/IslandWindow.cpp | 9 +- .../WindowsTerminal/WindowsTerminal.manifest | 5 +- src/common.build.post.props | 5 + src/common.build.pre.props | 4 +- src/host/getset.cpp | 56 ++++++++ src/host/getset.h | 6 + src/host/outputStream.cpp | 24 ++++ src/host/outputStream.hpp | 4 + src/host/ut_host/ScreenBufferTests.cpp | 124 +++++++++++++++++ src/inc/LibraryIncludes.h | 7 +- src/propsheet/precomp.h | 5 - src/renderer/base/thread.cpp | 24 ++-- src/terminal/adapter/ITermDispatch.hpp | 3 +- src/terminal/adapter/InteractDispatch.hpp | 18 +-- src/terminal/adapter/adaptDispatch.cpp | 91 ++++++++++--- src/terminal/adapter/adaptDispatch.hpp | 127 +++++++++--------- src/terminal/adapter/conGetSet.hpp | 2 + src/terminal/adapter/termDispatch.hpp | 124 ++++++++--------- .../adapter/ut_adapter/adapterTest.cpp | 28 ++++ .../parser/OutputStateMachineEngine.cpp | 33 +++-- .../parser/OutputStateMachineEngine.hpp | 11 +- src/terminal/parser/telemetry.cpp | 2 + src/terminal/parser/telemetry.hpp | 2 + 45 files changed, 765 insertions(+), 252 deletions(-) create mode 100644 .editorconfig create mode 100644 build/pipelines/templates/build-console-audit-job.yml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..40de22df5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +trim_trailing_whitespace = true +insert_final_newline = true + +[{*.cpp,*.c,*.hpp,*.h,*.cs}] +indent_style = space +indent_size = 4 + +[*.json] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore index 2450a0de6..d41b961a4 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ x64/ x86/ ARM64/ -build/ bld/ [Bb]in/ [Oo]bj/ diff --git a/build/pipelines/ci.yml b/build/pipelines/ci.yml index 0faa383b7..0900e5241 100644 --- a/build/pipelines/ci.yml +++ b/build/pipelines/ci.yml @@ -19,6 +19,10 @@ pr: name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr) jobs: + - template: ./templates/build-console-audit-job.yml + parameters: + platform: x64 + - template: ./templates/build-console-ci.yml parameters: platform: x64 diff --git a/build/pipelines/release.yml b/build/pipelines/release.yml index 126b3dc08..31365ae66 100644 --- a/build/pipelines/release.yml +++ b/build/pipelines/release.yml @@ -16,6 +16,10 @@ variables: name: 'Terminal_$(date:yyMM).$(date:dd)$(rev:rrr)' jobs: + - template: ./templates/build-console-audit-job.yml + parameters: + platform: x64 + - template: ./templates/build-console-int.yml parameters: platform: x64 diff --git a/build/pipelines/templates/build-console-audit-job.yml b/build/pipelines/templates/build-console-audit-job.yml new file mode 100644 index 000000000..b5bb0699c --- /dev/null +++ b/build/pipelines/templates/build-console-audit-job.yml @@ -0,0 +1,53 @@ +parameters: + platform: '' + additionalBuildArguments: '' + +jobs: +- job: Build${{ parameters.platform }}AuditMode + displayName: Static Analysis Build ${{ parameters.platform }} + variables: + BuildConfiguration: AuditMode + BuildPlatform: ${{ parameters.platform }} + pool: { vmImage: vs2017-win2016 } + + steps: + - checkout: self + submodules: true + clean: true + + - task: NuGetToolInstaller@0 + displayName: Ensure NuGet 4.8.1 + inputs: + versionSpec: 4.8.1 + + # In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous. + # This should be `task: NuGetCommand@2` + - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: Restore NuGet packages + inputs: + command: restore + feedsToUse: config + configPath: NuGet.config + restoreSolution: OpenConsole.sln + restoreDirectory: '$(Build.SourcesDirectory)\packages' + + - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2 + displayName: 'NuGet restore packages for CI' + inputs: + command: restore + restoreSolution: build/.nuget/packages.config + feedsToUse: config + externalFeedCredentials: 'TAEF NuGet Feed' + nugetConfigPath: build/config/NuGet.config + restoreDirectory: '$(Build.SourcesDirectory)/packages' + + - task: VSBuild@1 + displayName: 'Build solution **\OpenConsole.sln' + inputs: + solution: '**\OpenConsole.sln' + vsVersion: 15.0 + platform: '$(BuildPlatform)' + configuration: '$(BuildConfiguration)' + msbuildArgs: ${{ parameters.additionalBuildArguments }} + clean: true + maximumCpuCount: true diff --git a/build/pipelines/templates/build-console-ci.yml b/build/pipelines/templates/build-console-ci.yml index f8de3d181..a4ac7b6d8 100644 --- a/build/pipelines/templates/build-console-ci.yml +++ b/build/pipelines/templates/build-console-ci.yml @@ -4,8 +4,8 @@ parameters: additionalBuildArguments: '' jobs: -- job: Build${{ parameters.platform }} - displayName: Build ${{ parameters.platform }} +- job: Build${{ parameters.platform }}${{ parameters.configuration }} + displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }} variables: BuildConfiguration: ${{ parameters.configuration }} BuildPlatform: ${{ parameters.platform }} diff --git a/build/pipelines/templates/build-console-int.yml b/build/pipelines/templates/build-console-int.yml index 708915f8d..bf8664d15 100644 --- a/build/pipelines/templates/build-console-int.yml +++ b/build/pipelines/templates/build-console-int.yml @@ -4,8 +4,8 @@ parameters: additionalBuildArguments: '' jobs: -- job: Build${{ parameters.platform }} - displayName: Build ${{ parameters.platform }} +- job: Build${{ parameters.platform }}${{ parameters.configuration }} + displayName: Build ${{ parameters.platform }} ${{ parameters.configuration }} variables: BuildConfiguration: ${{ parameters.configuration }} BuildPlatform: ${{ parameters.platform }} diff --git a/build/pipelines/templates/release-sign-and-bundle.yml b/build/pipelines/templates/release-sign-and-bundle.yml index 07e578a25..105b834d4 100644 --- a/build/pipelines/templates/release-sign-and-bundle.yml +++ b/build/pipelines/templates/release-sign-and-bundle.yml @@ -6,16 +6,18 @@ jobs: displayName: Sign and Deploy for ${{ parameters.configuration }} dependsOn: - - Buildx64 - - Buildx86 - - Buildarm64 + - Buildx64AuditMode + - Buildx64Release + - Buildx86Release + - Buildarm64Release condition: | and ( - in(dependencies.Buildx64.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'), - in(dependencies.Buildx86.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'), - in(dependencies.Buildarm64.result, 'Succeeded', 'SucceededWithIssues', 'Skipped') - ) + in(dependencies.Buildx64AuditMode.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'), + in(dependencies.Buildx64Release.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'), + in(dependencies.Buildx86Release.result, 'Succeeded', 'SucceededWithIssues', 'Skipped'), + in(dependencies.Buildarm64Release.result, 'Succeeded', 'SucceededWithIssues', 'Skipped') + ) variables: BuildConfiguration: ${{ parameters.configuration }} diff --git a/src/StaticAnalysis.ruleset b/src/StaticAnalysis.ruleset index 1eea1e89f..e9d2a69ed 100644 --- a/src/StaticAnalysis.ruleset +++ b/src/StaticAnalysis.ruleset @@ -1,4 +1,11 @@  + + + + + + + diff --git a/src/buffer/out/precomp.h b/src/buffer/out/precomp.h index 4c6505cc1..adb1cfb93 100644 --- a/src/buffer/out/precomp.h +++ b/src/buffer/out/precomp.h @@ -21,7 +21,6 @@ Abstract: #include "LibraryIncludes.h" #pragma warning(push) -#pragma warning(disable: ALL_CPPCORECHECK_WARNINGS) #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #endif diff --git a/src/cascadia/TerminalApp/App.cpp b/src/cascadia/TerminalApp/App.cpp index 354696302..89d9f51c5 100644 --- a/src/cascadia/TerminalApp/App.cpp +++ b/src/cascadia/TerminalApp/App.cpp @@ -211,7 +211,7 @@ namespace winrt::TerminalApp::implementation _root.Children().Append(dialog); // Display the dialog. - Controls::ContentDialogResult result = await dialog.ShowAsync(Controls::ContentDialogPlacement::Popup); + Controls::ContentDialogResult result = co_await dialog.ShowAsync(Controls::ContentDialogPlacement::Popup); // After the dialog is dismissed, the dialog lock (held by `lock`) will // be released so another can be shown. @@ -295,12 +295,12 @@ namespace winrt::TerminalApp::implementation { // enum value for ShortcutAction::NewTabProfileX; 0==NewTabProfile0 auto profileKeyChord = keyBindings.GetKeyBinding(static_cast(profileIndex + static_cast(ShortcutAction::NewTabProfile0))); - + // make sure we find one to display if (profileKeyChord) { _SetAcceleratorForMenuItem(profileMenuItem, profileKeyChord); - } + } } auto profileName = profile.GetName(); diff --git a/src/cascadia/TerminalApp/App.h b/src/cascadia/TerminalApp/App.h index 584168da3..25638d354 100644 --- a/src/cascadia/TerminalApp/App.h +++ b/src/cascadia/TerminalApp/App.h @@ -8,8 +8,6 @@ #include "App.g.h" #include "../../cascadia/inc/cppwinrt_utils.h" -#include - #include #include diff --git a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp index 28a0b955f..f8d88ad44 100644 --- a/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettingsSerialization.cpp @@ -6,8 +6,6 @@ #include "CascadiaSettings.h" #include "../../types/inc/utils.hpp" #include -#include -#include #include using namespace ::TerminalApp; diff --git a/src/cascadia/TerminalConnection/pch.h b/src/cascadia/TerminalConnection/pch.h index 832645af3..04e2abdf5 100644 --- a/src/cascadia/TerminalConnection/pch.h +++ b/src/cascadia/TerminalConnection/pch.h @@ -14,4 +14,3 @@ #include "winrt/Windows.Foundation.h" #include -#include diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index dd42f8f49..f91643989 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -158,8 +158,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - Style our UI elements based on the values in our _settings, and set up // other control-specific settings. This method will be called whenever // the settings are reloaded. - // * Sets up the background of the control with the provided BG color, - // acrylic or not, and if acrylic, then uses the opacity from _settings. + // * Calls _BackgroundColorChanged to style the background of the control // - Core settings will be passed to the terminal in _InitializeTerminal // Arguments: // - @@ -167,37 +166,8 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // - void TermControl::_ApplyUISettings() { - winrt::Windows::UI::Color bgColor{}; uint32_t bg = _settings.DefaultBackground(); - const auto R = GetRValue(bg); - const auto G = GetGValue(bg); - const auto B = GetBValue(bg); - bgColor.R = R; - bgColor.G = G; - bgColor.B = B; - bgColor.A = 255; - - if (_settings.UseAcrylic()) - { - Media::AcrylicBrush acrylic{}; - acrylic.BackgroundSource(Media::AcrylicBackgroundSource::HostBackdrop); - acrylic.FallbackColor(bgColor); - acrylic.TintColor(bgColor); - acrylic.TintOpacity(_settings.TintOpacity()); - _root.Background(acrylic); - - // If we're acrylic, we want to make sure that the default BG color - // is transparent, so we can see the acrylic effect on text with the - // default BG color. - _settings.DefaultBackground(ARGB(0, R, G, B)); - } - else - { - Media::SolidColorBrush solidColor{}; - solidColor.Color(bgColor); - _root.Background(solidColor); - _settings.DefaultBackground(RGB(R, G, B)); - } + _BackgroundColorChanged(bg); // Apply padding to the root Grid auto thickness = _ParseThicknessFromPadding(_settings.Padding()); @@ -216,6 +186,50 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _desiredFont = { _actualFont }; } + // Method Description: + // - Style the background of the control with the provided background color + // - Respects the settings for acrylic and opacity from _settings + // Arguments: + // - color: The background color to use as a uint32 (aka DWORD COLORREF) + // Return Value: + // - + void TermControl::_BackgroundColorChanged(const uint32_t color) + { + _root.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [this, color]() { + const auto R = GetRValue(color); + const auto G = GetGValue(color); + const auto B = GetBValue(color); + + winrt::Windows::UI::Color bgColor{}; + bgColor.R = R; + bgColor.G = G; + bgColor.B = B; + bgColor.A = 255; + + if (_settings.UseAcrylic()) + { + Media::AcrylicBrush acrylic{}; + acrylic.BackgroundSource(Media::AcrylicBackgroundSource::HostBackdrop); + acrylic.FallbackColor(bgColor); + acrylic.TintColor(bgColor); + acrylic.TintOpacity(_settings.TintOpacity()); + _root.Background(acrylic); + + // If we're acrylic, we want to make sure that the default BG color + // is transparent, so we can see the acrylic effect on text with the + // default BG color. + _settings.DefaultBackground(ARGB(0, R, G, B)); + } + else + { + Media::SolidColorBrush solidColor{}; + solidColor.Color(bgColor); + _root.Background(solidColor); + _settings.DefaultBackground(RGB(R, G, B)); + } + }); + } + // Method Description: // - Create a connection based on the values in our settings object. // * Gets the commandline and working directory out of the _settings and @@ -283,13 +297,19 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _terminal = std::make_unique<::Microsoft::Terminal::Core::Terminal>(); // First create the render thread. + // Then stash a local pointer to the render thread so we can initialize it and enable it + // to paint itself *after* we hand off its ownership to the renderer. + // We split up construction and initialization of the render thread object this way + // because the renderer and render thread have circular references to each other. auto renderThread = std::make_unique<::Microsoft::Console::Render::RenderThread>(); - // Stash a local pointer to the render thread, so we can enable it after - // we hand off ownership to the renderer. auto* const localPointerToThread = renderThread.get(); + + // Now create the renderer and initialize the render thread. _renderer = std::make_unique<::Microsoft::Console::Render::Renderer>(_terminal.get(), nullptr, 0, std::move(renderThread)); ::Microsoft::Console::Render::IRenderTarget& renderTarget = *_renderer; + THROW_IF_FAILED(localPointerToThread->Initialize(_renderer.get())); + // Set up the DX Engine auto dxEngine = std::make_unique<::Microsoft::Console::Render::DxEngine>(); _renderer->AddRenderEngine(dxEngine.get()); @@ -336,8 +356,6 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation auto inputFn = std::bind(&TermControl::_SendInputToConnection, this, std::placeholders::_1); _terminal->SetWriteInputCallback(inputFn); - THROW_IF_FAILED(localPointerToThread->Initialize(_renderer.get())); - auto chain = _renderEngine->GetSwapChain(); _swapChainPanel.Dispatcher().RunAsync(CoreDispatcherPriority::High, [this, chain]() { @@ -406,6 +424,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation auto pfnTitleChanged = std::bind(&TermControl::_TerminalTitleChanged, this, std::placeholders::_1); _terminal->SetTitleChangedCallback(pfnTitleChanged); + auto pfnBackgroundColorChanged = std::bind(&TermControl::_BackgroundColorChanged, this, std::placeholders::_1); + _terminal->SetBackgroundCallback(pfnBackgroundColorChanged); + auto pfnScrollPositionChanged = std::bind(&TermControl::_TerminalScrollPositionChanged, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); _terminal->SetScrollPositionChangedCallback(pfnScrollPositionChanged); @@ -417,6 +438,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _cursorTimer = std::make_optional(DispatcherTimer()); _cursorTimer.value().Interval(std::chrono::milliseconds(blinkTime)); _cursorTimer.value().Tick({ this, &TermControl::_BlinkCursor }); + _cursorTimer.value().Start(); } else { @@ -535,6 +557,14 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation } } + // Manually prevent keyboard navigation with tab. We want to send tab to + // the terminal, and we don't want to be able to escape focus of the + // control with tab. + if (e.OriginalKey() == VirtualKey::Tab) + { + handled = true; + } + e.Handled(handled); } @@ -830,7 +860,9 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation _focused = true; if (_cursorTimer.has_value()) + { _cursorTimer.value().Start(); + } } // Method Description: diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 00d566980..29bfc91b8 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -95,6 +95,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void _Create(); void _ApplyUISettings(); + void _BackgroundColorChanged(const uint32_t color); void _ApplyConnectionSettings(); void _InitializeTerminal(); void _UpdateFont(); diff --git a/src/cascadia/TerminalCore/ITerminalApi.hpp b/src/cascadia/TerminalCore/ITerminalApi.hpp index f356c8be0..9e4e2a376 100644 --- a/src/cascadia/TerminalCore/ITerminalApi.hpp +++ b/src/cascadia/TerminalCore/ITerminalApi.hpp @@ -31,5 +31,8 @@ namespace Microsoft::Terminal::Core virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) = 0; virtual bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) = 0; + + virtual bool SetDefaultForeground(const DWORD dwColor) = 0; + virtual bool SetDefaultBackground(const DWORD dwColor) = 0; }; } diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 75d4345a1..b6c7abff7 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -77,7 +77,7 @@ void Terminal::Create(COORD viewportSize, SHORT scrollbackLines, IRenderTarget& } // Method Description: -// - Initializes the Temrinal from the given set of settings. +// - Initializes the Terminal from the given set of settings. // Arguments: // - settings: the set of CoreSettings we need to use to initialize the terminal // - renderTarget: A render target the terminal can use for paint invalidation. @@ -442,6 +442,15 @@ void Terminal::SetScrollPositionChangedCallback(std::function pfn) noexcept +{ + _pfnBackgroundColorChanged = pfn; +} + // Method Description: // - Checks if selection is active // Return Value: diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 7e880962e..593321694 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -70,8 +70,10 @@ public: COORD GetCursorPosition() override; bool EraseCharacters(const unsigned int numChars) override; bool SetWindowTitle(std::wstring_view title) override; - bool SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) 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 @@ -113,6 +115,7 @@ public: 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; @@ -131,6 +134,7 @@ public: 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; diff --git a/src/cascadia/TerminalCore/TerminalApi.cpp b/src/cascadia/TerminalCore/TerminalApi.cpp index d6793bb63..745696ff9 100644 --- a/src/cascadia/TerminalCore/TerminalApi.cpp +++ b/src/cascadia/TerminalCore/TerminalApi.cpp @@ -157,7 +157,7 @@ bool Terminal::SetWindowTitle(std::wstring_view title) // - dwColor: the new COLORREF to use as that color table value. // Return Value: // - true iff we successfully updated the color table entry. -bool Terminal::SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) +bool Terminal::SetColorTableEntry(const size_t tableIndex, const COLORREF dwColor) { if (tableIndex > _colorTable.size()) { @@ -219,3 +219,34 @@ bool Terminal::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) return true; } + +// Method Description: +// - Updates the default foreground color from a COLORREF, format 0x00BBGGRR. +// Arguments: +// - dwColor: the new COLORREF to use as the default foreground color +// Return Value: +// - true +bool Terminal::SetDefaultForeground(const COLORREF dwColor) +{ + _defaultFg = dwColor; + + // Repaint everything - the colors might have changed + _buffer->GetRenderTarget().TriggerRedrawAll(); + return true; +} + +// Method Description: +// - Updates the default background color from a COLORREF, format 0x00BBGGRR. +// Arguments: +// - dwColor: the new COLORREF to use as the default background color +// Return Value: +// - true +bool Terminal::SetDefaultBackground(const COLORREF dwColor) +{ + _defaultBg = dwColor; + _pfnBackgroundColorChanged(dwColor); + + // Repaint everything - the colors might have changed + _buffer->GetRenderTarget().TriggerRedrawAll(); + return true; +} diff --git a/src/cascadia/TerminalCore/TerminalDispatch.cpp b/src/cascadia/TerminalCore/TerminalDispatch.cpp index 8b836310c..154ee53e0 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.cpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.cpp @@ -64,7 +64,7 @@ bool TerminalDispatch::SetWindowTitle(std::wstring_view title) // - tableIndex: The VT color table index // - dwColor: The new RGB color value to use. // Return Value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool TerminalDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) { @@ -75,3 +75,25 @@ bool TerminalDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorSty { return _terminalApi.SetCursorStyle(cursorStyle); } + +// Method Description: +// - Sets the default foreground color to a new value +// Arguments: +// - dwColor: The new RGB color value to use, in 0x00BBGGRR form +// Return Value: +// True if handled successfully. False otherwise. +bool TerminalDispatch::SetDefaultForeground(const DWORD dwColor) +{ + return _terminalApi.SetDefaultForeground(dwColor); +} + +// Method Description: +// - Sets the default background color to a new value +// Arguments: +// - dwColor: The new RGB color value to use, in 0x00BBGGRR form +// Return Value: +// True if handled successfully. False otherwise. +bool TerminalDispatch::SetDefaultBackground(const DWORD dwColor) +{ + return _terminalApi.SetDefaultBackground(dwColor); +} diff --git a/src/cascadia/TerminalCore/TerminalDispatch.hpp b/src/cascadia/TerminalCore/TerminalDispatch.hpp index e24a3e14e..68bfcfb52 100644 --- a/src/cascadia/TerminalCore/TerminalDispatch.hpp +++ b/src/cascadia/TerminalCore/TerminalDispatch.hpp @@ -27,6 +27,9 @@ public: bool SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) override; bool SetCursorStyle(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::CursorStyle cursorStyle) override; + bool SetDefaultForeground(const DWORD dwColor) override; + bool SetDefaultBackground(const DWORD dwColor) override; + private: ::Microsoft::Terminal::Core::ITerminalApi& _terminalApi; diff --git a/src/cascadia/WindowsTerminal/IslandWindow.cpp b/src/cascadia/WindowsTerminal/IslandWindow.cpp index 4097576e6..0d84c1f4b 100644 --- a/src/cascadia/WindowsTerminal/IslandWindow.cpp +++ b/src/cascadia/WindowsTerminal/IslandWindow.cpp @@ -162,6 +162,13 @@ LRESULT IslandWindow::MessageHandler(UINT const message, WPARAM const wparam, LP return 0; // eat the message } } + case WM_MENUCHAR: + { + // GH#891: return this LRESULT here to prevent the app from making a + // bell when alt+key is pressed. A menu is active and the user presses a + // key that does not correspond to any mnemonic or accelerator key, + return MAKELRESULT(0, MNC_CLOSE); + } } // TODO: handle messages here... @@ -173,7 +180,7 @@ LRESULT IslandWindow::MessageHandler(UINT const message, WPARAM const wparam, LP // Arguments: // - width: the new width of the window _in pixels_ // - height: the new height of the window _in pixels_ -void IslandWindow::OnResize(const UINT width, const UINT height) +void IslandWindow::OnResize(const UINT /*width*/, const UINT /*height*/) { OnSize(); } diff --git a/src/cascadia/WindowsTerminal/WindowsTerminal.manifest b/src/cascadia/WindowsTerminal/WindowsTerminal.manifest index c89d68031..0f4759ba9 100644 --- a/src/cascadia/WindowsTerminal/WindowsTerminal.manifest +++ b/src/cascadia/WindowsTerminal/WindowsTerminal.manifest @@ -2,7 +2,10 @@ - + + + + diff --git a/src/common.build.post.props b/src/common.build.post.props index 00a81388c..5539b05ee 100644 --- a/src/common.build.post.props +++ b/src/common.build.post.props @@ -25,4 +25,9 @@ + + + $(SolutionDir)\dep\;$(CAExcludePath) + diff --git a/src/common.build.pre.props b/src/common.build.pre.props index 1591634fe..d7853a892 100644 --- a/src/common.build.pre.props +++ b/src/common.build.pre.props @@ -113,8 +113,8 @@ WIN32;%(PreprocessorDefinitions) - - + + $(SolutionDir)\src\StaticAnalysis.ruleset true true diff --git a/src/host/getset.cpp b/src/host/getset.cpp index e36fab96f..d2ec5be42 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -2170,3 +2170,59 @@ HRESULT DoSrvPrivateSetColorTableEntry(const short index, const COLORREF value) CATCH_RETURN(); } + +// Method Description: +// - Sets the default foreground color to the color specified in value. +// Arguments: +// - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR. +// Return Value: +// - S_OK +[[nodiscard]] +HRESULT DoSrvPrivateSetDefaultForegroundColor(const COLORREF value) noexcept +{ + try + { + Globals& g = ServiceLocator::LocateGlobals(); + CONSOLE_INFORMATION& gci = g.getConsoleInformation(); + + gci.SetDefaultForegroundColor(value); + + // Update the screen colors if we're not a pty + // No need to force a redraw in pty mode. + if (g.pRender && !gci.IsInVtIoMode()) + { + g.pRender->TriggerRedrawAll(); + } + + return S_OK; + } + CATCH_RETURN(); +} + +// Method Description: +// - Sets the default background color to the color specified in value. +// Arguments: +// - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR. +// Return Value: +// - S_OK +[[nodiscard]] +HRESULT DoSrvPrivateSetDefaultBackgroundColor(const COLORREF value) noexcept +{ + try + { + Globals& g = ServiceLocator::LocateGlobals(); + CONSOLE_INFORMATION& gci = g.getConsoleInformation(); + + gci.SetDefaultBackgroundColor(value); + + // Update the screen colors if we're not a pty + // No need to force a redraw in pty mode. + if (g.pRender && !gci.IsInVtIoMode()) + { + g.pRender->TriggerRedrawAll(); + } + + return S_OK; + } + CATCH_RETURN(); +} diff --git a/src/host/getset.h b/src/host/getset.h index 1676c8b63..22784375e 100644 --- a/src/host/getset.h +++ b/src/host/getset.h @@ -99,3 +99,9 @@ void DoSrvPrivateMoveToBottom(SCREEN_INFORMATION& screenInfo); [[nodiscard]] HRESULT DoSrvPrivateSetColorTableEntry(const short index, const COLORREF value) noexcept; + +[[nodiscard]] +HRESULT DoSrvPrivateSetDefaultForegroundColor(const COLORREF value) noexcept; + +[[nodiscard]] +HRESULT DoSrvPrivateSetDefaultBackgroundColor(const COLORREF value) noexcept; diff --git a/src/host/outputStream.cpp b/src/host/outputStream.cpp index 1ddf0fc48..58f0bb91e 100644 --- a/src/host/outputStream.cpp +++ b/src/host/outputStream.cpp @@ -761,3 +761,27 @@ BOOL ConhostInternalGetSet::PrivateSetColorTableEntry(const short index, const C { return SUCCEEDED(DoSrvPrivateSetColorTableEntry(index, value)); } + +// Method Description: +// - Connects the PrivateSetDefaultForeground call directly into our Driver Message servicing +// call inside Conhost.exe +// Arguments: +// - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR. +// Return Value: +// - TRUE if successful (see DoSrvPrivateSetDefaultForegroundColor). FALSE otherwise. +BOOL ConhostInternalGetSet::PrivateSetDefaultForeground(const COLORREF value) const noexcept +{ + return SUCCEEDED(DoSrvPrivateSetDefaultForegroundColor(value)); +} + +// Method Description: +// - Connects the PrivateSetDefaultBackground call directly into our Driver Message servicing +// call inside Conhost.exe +// Arguments: +// - value: the new RGB value to use, as a COLORREF, format 0x00BBGGRR. +// Return Value: +// - TRUE if successful (see DoSrvPrivateSetDefaultBackgroundColor). FALSE otherwise. +BOOL ConhostInternalGetSet::PrivateSetDefaultBackground(const COLORREF value) const noexcept +{ + return SUCCEEDED(DoSrvPrivateSetDefaultBackgroundColor(value)); +} diff --git a/src/host/outputStream.hpp b/src/host/outputStream.hpp index b450edced..b87d10082 100644 --- a/src/host/outputStream.hpp +++ b/src/host/outputStream.hpp @@ -157,6 +157,10 @@ public: BOOL PrivateSetColorTableEntry(const short index, const COLORREF value) const noexcept override; + BOOL PrivateSetDefaultForeground(const COLORREF value) const noexcept override; + + BOOL PrivateSetDefaultBackground(const COLORREF value) const noexcept override; + private: Microsoft::Console::IIoProvider& _io; }; diff --git a/src/host/ut_host/ScreenBufferTests.cpp b/src/host/ut_host/ScreenBufferTests.cpp index 200059579..c77f42e54 100644 --- a/src/host/ut_host/ScreenBufferTests.cpp +++ b/src/host/ut_host/ScreenBufferTests.cpp @@ -149,6 +149,10 @@ class ScreenBufferTests TEST_METHOD(SetColorTableThreeDigits); + TEST_METHOD(SetDefaultForegroundColor); + + TEST_METHOD(SetDefaultBackgroundColor); + TEST_METHOD(DeleteCharsNearEndOfLine); TEST_METHOD(DeleteCharsNearEndOfLineSimpleFirstCase); TEST_METHOD(DeleteCharsNearEndOfLineSimpleSecondCase); @@ -2502,6 +2506,126 @@ void ScreenBufferTests::SetColorTableThreeDigits() } + +void ScreenBufferTests::SetDefaultForegroundColor() +{ + // Setting the default foreground color should work + + CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + gci.LockConsole(); // Lock must be taken to swap buffers. + auto unlock = wil::scope_exit([&] { gci.UnlockConsole(); }); + + SCREEN_INFORMATION& mainBuffer = gci.GetActiveOutputBuffer(); + VERIFY_IS_FALSE(mainBuffer._IsAltBuffer()); + WI_SetFlag(mainBuffer.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); + VERIFY_IS_TRUE(WI_IsFlagSet(mainBuffer.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING)); + + StateMachine& stateMachine = mainBuffer.GetStateMachine(); + + COLORREF originalColor = gci.GetDefaultForegroundColor(); + COLORREF newColor = gci.GetDefaultForegroundColor(); + COLORREF testColor = RGB(0x33, 0x66, 0x99); + VERIFY_ARE_NOT_EQUAL(originalColor, testColor); + + Log::Comment(L"Valid Hexadecimal Notation"); + std::wstring seq = L"\x1b]10;rgb:33/66/99\x1b\\"; + stateMachine.ProcessString(seq); + + newColor = gci.GetDefaultForegroundColor(); + VERIFY_ARE_EQUAL(testColor, newColor); + + Log::Comment(L"Valid Hexadecimal Notation"); + originalColor = newColor; + testColor = RGB(0xff, 0xff, 0xff); + seq = L"\x1b]10;rgb:ff/ff/ff\x1b\\"; + stateMachine.ProcessString(seq); + + newColor = gci.GetDefaultForegroundColor(); + VERIFY_ARE_EQUAL(testColor, newColor); + + Log::Comment(L"Invalid Decimal Notation"); + originalColor = newColor; + testColor = RGB(153, 102, 51); + seq = L"\x1b]10;rgb:153/102/51\x1b\\"; + stateMachine.ProcessString(seq); + + newColor = gci.GetDefaultForegroundColor(); + VERIFY_ARE_NOT_EQUAL(testColor, newColor); + // it will, in fact leave the color the way it was + VERIFY_ARE_EQUAL(originalColor, newColor); + + Log::Comment(L"Invalid syntax"); + testColor = RGB(153, 102, 51); + seq = L"\x1b]10;99/66/33\x1b\\"; + stateMachine.ProcessString(seq); + + newColor = gci.GetDefaultForegroundColor(); + VERIFY_ARE_NOT_EQUAL(testColor, newColor); + // it will, in fact leave the color the way it was + VERIFY_ARE_EQUAL(originalColor, newColor); +} + + +void ScreenBufferTests::SetDefaultBackgroundColor() +{ + // Setting the default Background color should work + + CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); + gci.LockConsole(); // Lock must be taken to swap buffers. + auto unlock = wil::scope_exit([&] { gci.UnlockConsole(); }); + + SCREEN_INFORMATION& mainBuffer = gci.GetActiveOutputBuffer(); + VERIFY_IS_FALSE(mainBuffer._IsAltBuffer()); + WI_SetFlag(mainBuffer.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING); + VERIFY_IS_TRUE(WI_IsFlagSet(mainBuffer.OutputMode, ENABLE_VIRTUAL_TERMINAL_PROCESSING)); + + StateMachine& stateMachine = mainBuffer.GetStateMachine(); + + COLORREF originalColor = gci.GetDefaultBackgroundColor(); + COLORREF newColor = gci.GetDefaultBackgroundColor(); + COLORREF testColor = RGB(0x33, 0x66, 0x99); + VERIFY_ARE_NOT_EQUAL(originalColor, testColor); + + Log::Comment(L"Valid Hexadecimal Notation"); + std::wstring seq = L"\x1b]11;rgb:33/66/99\x1b\\"; + stateMachine.ProcessString(seq); + + newColor = gci.GetDefaultBackgroundColor(); + VERIFY_ARE_EQUAL(testColor, newColor); + + Log::Comment(L"Valid Hexadecimal Notation"); + originalColor = newColor; + testColor = RGB(0xff, 0xff, 0xff); + seq = L"\x1b]11;rgb:ff/ff/ff\x1b\\"; + stateMachine.ProcessString(seq); + + newColor = gci.GetDefaultBackgroundColor(); + VERIFY_ARE_EQUAL(testColor, newColor); + + Log::Comment(L"Invalid Decimal Notation"); + originalColor = newColor; + testColor = RGB(153, 102, 51); + seq = L"\x1b]11;rgb:153/102/51\x1b\\"; + stateMachine.ProcessString(seq); + + newColor = gci.GetDefaultBackgroundColor(); + VERIFY_ARE_NOT_EQUAL(testColor, newColor); + // it will, in fact leave the color the way it was + VERIFY_ARE_EQUAL(originalColor, newColor); + + Log::Comment(L"Invalid Syntax"); + testColor = RGB(153, 102, 51); + seq = L"\x1b]11;99/66/33\x1b\\"; + stateMachine.ProcessString(seq); + + newColor = gci.GetDefaultBackgroundColor(); + VERIFY_ARE_NOT_EQUAL(testColor, newColor); + // it will, in fact leave the color the way it was + VERIFY_ARE_EQUAL(originalColor, newColor); +} + + + void ScreenBufferTests::DeleteCharsNearEndOfLine() { // Created for MSFT:19888564. diff --git a/src/inc/LibraryIncludes.h b/src/inc/LibraryIncludes.h index e2a01094e..705a06237 100644 --- a/src/inc/LibraryIncludes.h +++ b/src/inc/LibraryIncludes.h @@ -3,10 +3,8 @@ #pragma once -#include #pragma warning(push) -#pragma warning(disable: ALL_CPPCORECHECK_WARNINGS) // C #include @@ -44,12 +42,12 @@ #include // WIL - #include #include #include #include #include +#include // GSL // Block GSL Multi Span include because it both has C++17 deprecated iterators @@ -57,6 +55,9 @@ #define GSL_MULTI_SPAN_H #include +// CppCoreCheck +#include + // IntSafe #define ENABLE_INTSAFE_SIGNED_FUNCTIONS #include diff --git a/src/propsheet/precomp.h b/src/propsheet/precomp.h index 6c44645f4..4b053c598 100644 --- a/src/propsheet/precomp.h +++ b/src/propsheet/precomp.h @@ -48,12 +48,7 @@ #include "strid.h" #include "..\propslib\conpropsp.hpp" -// WIL #include -#include -#include -#include -#include // This is currently bubbling up the source tree to our branch #ifndef WM_DPICHANGED_BEFOREPARENT diff --git a/src/renderer/base/thread.cpp b/src/renderer/base/thread.cpp index 80a398768..4c7fc0e1b 100644 --- a/src/renderer/base/thread.cpp +++ b/src/renderer/base/thread.cpp @@ -12,42 +12,42 @@ using namespace Microsoft::Console::Render; RenderThread::RenderThread() : _pRenderer(nullptr), - _hThread(INVALID_HANDLE_VALUE), - _hEvent(INVALID_HANDLE_VALUE), - _hPaintCompletedEvent(INVALID_HANDLE_VALUE), + _hThread(nullptr), + _hEvent(nullptr), + _hPaintCompletedEvent(nullptr), _fKeepRunning(true), - _hPaintEnabledEvent(INVALID_HANDLE_VALUE) + _hPaintEnabledEvent(nullptr) { } RenderThread::~RenderThread() { - if (_hThread != INVALID_HANDLE_VALUE) + if (_hThread) { _fKeepRunning = false; // stop loop after final run SignalObjectAndWait(_hEvent, _hThread, INFINITE, FALSE); // signal final paint and wait for thread to finish. CloseHandle(_hThread); - _hThread = INVALID_HANDLE_VALUE; + _hThread = nullptr; } - if (_hEvent != INVALID_HANDLE_VALUE) + if (_hEvent) { CloseHandle(_hEvent); - _hEvent = INVALID_HANDLE_VALUE; + _hEvent = nullptr; } - if (_hPaintEnabledEvent != INVALID_HANDLE_VALUE) + if (_hPaintEnabledEvent) { CloseHandle(_hPaintEnabledEvent); - _hPaintEnabledEvent = INVALID_HANDLE_VALUE; + _hPaintEnabledEvent = nullptr; } - if (_hPaintCompletedEvent != INVALID_HANDLE_VALUE) + if (_hPaintCompletedEvent) { CloseHandle(_hPaintCompletedEvent); - _hPaintCompletedEvent = INVALID_HANDLE_VALUE; + _hPaintCompletedEvent = nullptr; } } diff --git a/src/terminal/adapter/ITermDispatch.hpp b/src/terminal/adapter/ITermDispatch.hpp index 6f4bcd9a2..fec42544b 100644 --- a/src/terminal/adapter/ITermDispatch.hpp +++ b/src/terminal/adapter/ITermDispatch.hpp @@ -65,6 +65,8 @@ public: virtual bool EnableAnyEventMouseMode(const bool fEnabled) = 0; // ?1003 virtual bool EnableAlternateScroll(const bool fEnabled) = 0; // ?1007 virtual bool SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) = 0; // OSCColorTable + virtual bool SetDefaultForeground(const DWORD dwColor) = 0; // OSCDefaultForeground + virtual bool SetDefaultBackground(const DWORD dwColor) = 0; // OSCDefaultBackground virtual bool EraseInDisplay(const DispatchTypes::EraseType eraseType) = 0; // ED virtual bool EraseInLine(const DispatchTypes::EraseType eraseType) = 0; // EL @@ -97,4 +99,3 @@ public: }; inline Microsoft::Console::VirtualTerminal::ITermDispatch::~ITermDispatch() { } - diff --git a/src/terminal/adapter/InteractDispatch.hpp b/src/terminal/adapter/InteractDispatch.hpp index a49b07eec..413bb4753 100644 --- a/src/terminal/adapter/InteractDispatch.hpp +++ b/src/terminal/adapter/InteractDispatch.hpp @@ -26,16 +26,16 @@ namespace Microsoft::Console::VirtualTerminal InteractDispatch(ConGetSet* const pConApi); - virtual ~InteractDispatch() override = default; + ~InteractDispatch() = default; - virtual bool WriteInput(_In_ std::deque>& inputEvents) override; - virtual bool WriteCtrlC() override; - virtual bool WriteString(_In_reads_(cch) const wchar_t* const pws, const size_t cch) override; - virtual bool WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const size_t cParams) override; // DTTERM_WindowManipulation - virtual bool MoveCursor(const unsigned int row, - const unsigned int col) override; + bool WriteInput(_In_ std::deque>& inputEvents) override; + bool WriteCtrlC() override; + bool WriteString(_In_reads_(cch) const wchar_t* const pws, const size_t cch) override; + bool WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, + _In_reads_(cParams) const unsigned short* const rgusParams, + const size_t cParams) override; // DTTERM_WindowManipulation + bool MoveCursor(const unsigned int row, + const unsigned int col) override; private: std::unique_ptr _pConApi; diff --git a/src/terminal/adapter/adaptDispatch.cpp b/src/terminal/adapter/adaptDispatch.cpp index 23489a102..8e1da0e32 100644 --- a/src/terminal/adapter/adaptDispatch.cpp +++ b/src/terminal/adapter/adaptDispatch.cpp @@ -1389,7 +1389,7 @@ bool AdaptDispatch::UseMainScreenBuffer() //Arguments: // - None // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::HorizontalTabSet() { return !!_conApi->PrivateHorizontalTabSet(); @@ -1403,7 +1403,7 @@ bool AdaptDispatch::HorizontalTabSet() //Arguments: // - sNumTabs - the number of tabs to perform // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::ForwardTab(const SHORT sNumTabs) { return !!_conApi->PrivateForwardTab(sNumTabs); @@ -1415,7 +1415,7 @@ bool AdaptDispatch::ForwardTab(const SHORT sNumTabs) //Arguments: // - sNumTabs - the number of tabs to perform // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::BackwardsTab(const SHORT sNumTabs) { return !!_conApi->PrivateBackwardsTab(sNumTabs); @@ -1428,7 +1428,7 @@ bool AdaptDispatch::BackwardsTab(const SHORT sNumTabs) //Arguments: // - sClearType - Whether to clear the current column, or all columns, defined in DispatchTypes::TabClearType // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::TabClear(const SHORT sClearType) { bool fSuccess = false; @@ -1453,7 +1453,7 @@ bool AdaptDispatch::TabClear(const SHORT sClearType) //Arguments: // - wchCharset - The character indicating the charset we should switch to. // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::DesignateCharset(const wchar_t wchCharset) { return _TermOutput.DesignateCharset(wchCharset); @@ -1489,7 +1489,7 @@ bool AdaptDispatch::DesignateCharset(const wchar_t wchCharset) //Arguments: // // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::SoftReset() { bool fSuccess = CursorVisibility(true); // Cursor enabled. @@ -1542,7 +1542,7 @@ bool AdaptDispatch::SoftReset() //Arguments: // // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::HardReset() { // Clears the screen - Needs to be done in two operations. @@ -1581,7 +1581,7 @@ bool AdaptDispatch::HardReset() //Arguments: // // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::_EraseScrollback() { CONSOLE_SCREEN_BUFFER_INFOEX csbiex = { 0 }; @@ -1667,7 +1667,7 @@ bool AdaptDispatch::_EraseScrollback() //Arguments: // // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::_EraseAll() { return !!_conApi->PrivateEraseAll(); @@ -1678,7 +1678,7 @@ bool AdaptDispatch::_EraseAll() //Arguments: // - fEnabled - true to enable, false to disable. // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::EnableVT200MouseMode(const bool fEnabled) { return !!_conApi->PrivateEnableVT200MouseMode(fEnabled); @@ -1690,7 +1690,7 @@ bool AdaptDispatch::EnableVT200MouseMode(const bool fEnabled) //Arguments: // - fEnabled - true to enable, false to disable. // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::EnableUTF8ExtendedMouseMode(const bool fEnabled) { return !!_conApi->PrivateEnableUTF8ExtendedMouseMode(fEnabled); @@ -1702,7 +1702,7 @@ bool AdaptDispatch::EnableUTF8ExtendedMouseMode(const bool fEnabled) //Arguments: // - fEnabled - true to enable, false to disable. // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::EnableSGRExtendedMouseMode(const bool fEnabled) { return !!_conApi->PrivateEnableSGRExtendedMouseMode(fEnabled); @@ -1713,7 +1713,7 @@ bool AdaptDispatch::EnableSGRExtendedMouseMode(const bool fEnabled) //Arguments: // - fEnabled - true to enable, false to disable. // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::EnableButtonEventMouseMode(const bool fEnabled) { return !!_conApi->PrivateEnableButtonEventMouseMode(fEnabled); @@ -1725,7 +1725,7 @@ bool AdaptDispatch::EnableButtonEventMouseMode(const bool fEnabled) //Arguments: // - fEnabled - true to enable, false to disable. // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::EnableAnyEventMouseMode(const bool fEnabled) { return !!_conApi->PrivateEnableAnyEventMouseMode(fEnabled); @@ -1737,7 +1737,7 @@ bool AdaptDispatch::EnableAnyEventMouseMode(const bool fEnabled) //Arguments: // - fEnabled - true to enable, false to disable. // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::EnableAlternateScroll(const bool fEnabled) { return !!_conApi->PrivateEnableAlternateScroll(fEnabled); @@ -1749,7 +1749,7 @@ bool AdaptDispatch::EnableAlternateScroll(const bool fEnabled) //Arguments: // - cursorStyle - The unix-like cursor style to apply to the cursor // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) { bool isPty = false; @@ -1808,7 +1808,7 @@ bool AdaptDispatch::SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) // - tableIndex: The VT color table index // - dwColor: The new RGB color value to use. // Return Value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::SetCursorColor(const COLORREF cursorColor) { bool isPty = false; @@ -1827,9 +1827,8 @@ bool AdaptDispatch::SetCursorColor(const COLORREF cursorColor) // - tableIndex: The VT color table index // - dwColor: The new RGB color value to use. // Return Value: -// True if handled successfully. False othewise. -bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, - const DWORD dwColor) +// True if handled successfully. False otherwise. +bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, const DWORD dwColor) { bool fSuccess = tableIndex < 256; @@ -1853,6 +1852,56 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, return fSuccess; } +// Method Description: +// - Sets the default foreground color to a new value +// Arguments: +// - dwColor: The new RGB color value to use, as a COLORREF, format 0x00BBGGRR. +// Return Value: +// True if handled successfully. False otherwise. +bool Microsoft::Console::VirtualTerminal::AdaptDispatch::SetDefaultForeground(const DWORD dwColor) +{ + bool fSuccess = true; + fSuccess = !!_conApi->PrivateSetDefaultForeground(dwColor); + + // If we're a conpty, always return false, so that we send the updated color + // value to the terminal. Still handle the sequence so apps that use + // the API or VT to query the values of the color table still read the + // correct color. + bool isPty = false; + _conApi->IsConsolePty(&isPty); + if (isPty) + { + return false; + } + + return fSuccess; +} + +// Method Description: +// - Sets the default background color to a new value +// Arguments: +// - dwColor: The new RGB color value to use, as a COLORREF, format 0x00BBGGRR. +// Return Value: +// True if handled successfully. False otherwise. +bool Microsoft::Console::VirtualTerminal::AdaptDispatch::SetDefaultBackground(const DWORD dwColor) +{ + bool fSuccess = true; + fSuccess = !!_conApi->PrivateSetDefaultBackground(dwColor); + + // If we're a conpty, always return false, so that we send the updated color + // value to the terminal. Still handle the sequence so apps that use + // the API or VT to query the values of the color table still read the + // correct color. + bool isPty = false; + _conApi->IsConsolePty(&isPty); + if (isPty) + { + return false; + } + + return fSuccess; +} + //Routine Description: // Window Manipulation - Performs a variety of actions relating to the window, // such as moving the window position, resizing the window, querying @@ -1864,7 +1913,7 @@ bool AdaptDispatch::SetColorTableEntry(const size_t tableIndex, // - rgusParams - Additional parameters to pass to the function // - cParams - size of rgusParams // Return value: -// True if handled successfully. False othewise. +// True if handled successfully. False otherwise. bool AdaptDispatch::WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, _In_reads_(cParams) const unsigned short* const rgusParams, const size_t cParams) diff --git a/src/terminal/adapter/adaptDispatch.hpp b/src/terminal/adapter/adaptDispatch.hpp index b40c9f976..39d05d986 100644 --- a/src/terminal/adapter/adaptDispatch.hpp +++ b/src/terminal/adapter/adaptDispatch.hpp @@ -33,74 +33,77 @@ namespace Microsoft::Console::VirtualTerminal AdaptDispatch(ConGetSet* const pConApi, AdaptDefaults* const pDefaults); - virtual void Execute(const wchar_t wchControl) + void Execute(const wchar_t wchControl) override { _pDefaults->Execute(wchControl); } - virtual void PrintString(const wchar_t* const rgwch, const size_t cch); - virtual void Print(const wchar_t wchPrintable); + void PrintString(const wchar_t* const rgwch, const size_t cch) override; + void Print(const wchar_t wchPrintable) override; - virtual bool CursorUp(_In_ unsigned int const uiDistance); // CUU - virtual bool CursorDown(_In_ unsigned int const uiDistance); // CUD - virtual bool CursorForward(_In_ unsigned int const uiDistance); // CUF - virtual bool CursorBackward(_In_ unsigned int const uiDistance); // CUB - virtual bool CursorNextLine(_In_ unsigned int const uiDistance); // CNL - virtual bool CursorPrevLine(_In_ unsigned int const uiDistance); // CPL - virtual bool CursorHorizontalPositionAbsolute(_In_ unsigned int const uiColumn); // CHA - virtual bool VerticalLinePositionAbsolute(_In_ unsigned int const uiLine); // VPA - virtual bool CursorPosition(_In_ unsigned int const uiLine, _In_ unsigned int const uiColumn); // CUP - virtual bool CursorSavePosition(); // DECSC - virtual bool CursorRestorePosition(); // DECRC - virtual bool CursorVisibility(const bool fIsVisible); // DECTCEM - virtual bool EraseInDisplay(const DispatchTypes::EraseType eraseType); // ED - virtual bool EraseInLine(const DispatchTypes::EraseType eraseType); // EL - virtual bool EraseCharacters(_In_ unsigned int const uiNumChars); // ECH - virtual bool InsertCharacter(_In_ unsigned int const uiCount); // ICH - virtual bool DeleteCharacter(_In_ unsigned int const uiCount); // DCH - virtual bool SetGraphicsRendition(_In_reads_(cOptions) const DispatchTypes::GraphicsOptions* const rgOptions, - const size_t cOptions); // SGR - virtual bool DeviceStatusReport(const DispatchTypes::AnsiStatusType statusType); // DSR - virtual bool DeviceAttributes(); // DA - virtual bool ScrollUp(_In_ unsigned int const uiDistance); // SU - virtual bool ScrollDown(_In_ unsigned int const uiDistance); // SD - virtual bool InsertLine(_In_ unsigned int const uiDistance); // IL - virtual bool DeleteLine(_In_ unsigned int const uiDistance); // DL - virtual bool SetColumns(_In_ unsigned int const uiColumns); // DECSCPP, DECCOLM - virtual bool SetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rParams, - const size_t cParams); // DECSET - virtual bool ResetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rParams, - const size_t cParams); // DECRST - virtual bool SetCursorKeysMode(const bool fApplicationMode); // DECCKM - virtual bool SetKeypadMode(const bool fApplicationMode); // DECKPAM, DECKPNM - virtual bool EnableCursorBlinking(const bool bEnable); // ATT610 - virtual bool SetTopBottomScrollingMargins(const SHORT sTopMargin, - const SHORT sBottomMargin); // DECSTBM - virtual bool ReverseLineFeed(); // RI - virtual bool SetWindowTitle(const std::wstring_view title) override; // OscWindowTitle - virtual bool UseAlternateScreenBuffer(); // ASBSET - virtual bool UseMainScreenBuffer(); // ASBRST - virtual bool HorizontalTabSet(); // HTS - virtual bool ForwardTab(const SHORT sNumTabs); // CHT - virtual bool BackwardsTab(const SHORT sNumTabs); // CBT - virtual bool TabClear(const SHORT sClearType); // TBC - virtual bool DesignateCharset(const wchar_t wchCharset); // DesignateCharset - virtual bool SoftReset(); // DECSTR - virtual bool HardReset(); // RIS - virtual bool EnableVT200MouseMode(const bool fEnabled); // ?1000 - virtual bool EnableUTF8ExtendedMouseMode(const bool fEnabled); // ?1005 - virtual bool EnableSGRExtendedMouseMode(const bool fEnabled); // ?1006 - virtual bool EnableButtonEventMouseMode(const bool fEnabled); // ?1002 - virtual bool EnableAnyEventMouseMode(const bool fEnabled); // ?1003 - virtual bool EnableAlternateScroll(const bool fEnabled); // ?1007 - virtual bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle); // DECSCUSR - virtual bool SetCursorColor(const COLORREF cursorColor); + bool CursorUp(_In_ unsigned int const uiDistance) override; // CUU + bool CursorDown(_In_ unsigned int const uiDistance) override; // CUD + bool CursorForward(_In_ unsigned int const uiDistance) override; // CUF + bool CursorBackward(_In_ unsigned int const uiDistance) override; // CUB + bool CursorNextLine(_In_ unsigned int const uiDistance) override; // CNL + bool CursorPrevLine(_In_ unsigned int const uiDistance) override; // CPL + bool CursorHorizontalPositionAbsolute(_In_ unsigned int const uiColumn) override; // CHA + bool VerticalLinePositionAbsolute(_In_ unsigned int const uiLine) override; // VPA + bool CursorPosition(_In_ unsigned int const uiLine, _In_ unsigned int const uiColumn) override; // CUP + bool CursorSavePosition() override; // DECSC + bool CursorRestorePosition() override; // DECRC + bool CursorVisibility(const bool fIsVisible) override; // DECTCEM + bool EraseInDisplay(const DispatchTypes::EraseType eraseType) override; // ED + bool EraseInLine(const DispatchTypes::EraseType eraseType) override; // EL + bool EraseCharacters(_In_ unsigned int const uiNumChars) override; // ECH + bool InsertCharacter(_In_ unsigned int const uiCount) override; // ICH + bool DeleteCharacter(_In_ unsigned int const uiCount) override; // DCH + bool SetGraphicsRendition(_In_reads_(cOptions) const DispatchTypes::GraphicsOptions* const rgOptions, + const size_t cOptions) override; // SGR + bool DeviceStatusReport(const DispatchTypes::AnsiStatusType statusType) override; // DSR + bool DeviceAttributes() override; // DA + bool ScrollUp(_In_ unsigned int const uiDistance) override; // SU + bool ScrollDown(_In_ unsigned int const uiDistance) override; // SD + bool InsertLine(_In_ unsigned int const uiDistance) override; // IL + bool DeleteLine(_In_ unsigned int const uiDistance) override; // DL + bool SetColumns(_In_ unsigned int const uiColumns) override; // DECSCPP, DECCOLM + bool SetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rParams, + const size_t cParams) override; // DECSET + bool ResetPrivateModes(_In_reads_(cParams) const DispatchTypes::PrivateModeParams* const rParams, + const size_t cParams) override; // DECRST + bool SetCursorKeysMode(const bool fApplicationMode) override; // DECCKM + bool SetKeypadMode(const bool fApplicationMode) override; // DECKPAM, DECKPNM + bool EnableCursorBlinking(const bool bEnable) override; // ATT610 + bool SetTopBottomScrollingMargins(const SHORT sTopMargin, + const SHORT sBottomMargin) override; // DECSTBM + 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 SHORT sNumTabs) override; // CHT + bool BackwardsTab(const SHORT sNumTabs) override; // CBT + bool TabClear(const SHORT sClearType) override; // TBC + bool DesignateCharset(const wchar_t wchCharset) override; // DesignateCharset + bool SoftReset() override; // DECSTR + bool HardReset() override; // RIS + bool EnableVT200MouseMode(const bool fEnabled) override; // ?1000 + bool EnableUTF8ExtendedMouseMode(const bool fEnabled) override; // ?1005 + bool EnableSGRExtendedMouseMode(const bool fEnabled) override; // ?1006 + bool EnableButtonEventMouseMode(const bool fEnabled) override; // ?1002 + bool EnableAnyEventMouseMode(const bool fEnabled) override; // ?1003 + bool EnableAlternateScroll(const bool fEnabled) override; // ?1007 + bool SetCursorStyle(const DispatchTypes::CursorStyle cursorStyle) override; // DECSCUSR + bool SetCursorColor(const COLORREF cursorColor) override; - virtual bool SetColorTableEntry(const size_t tableIndex, - const DWORD dwColor); // OscColorTable - virtual bool WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, - _In_reads_(cParams) const unsigned short* const rgusParams, - const size_t cParams); // DTTERM_WindowManipulation + bool SetColorTableEntry(const size_t tableIndex, + const DWORD dwColor) override; // OscColorTable + bool SetDefaultForeground(const DWORD dwColor) override; // OSCDefaultForeground + bool SetDefaultBackground(const DWORD dwColor) override; // OSCDefaultBackground + + bool WindowManipulation(const DispatchTypes::WindowManipulationType uiFunction, + _In_reads_(cParams) const unsigned short* const rgusParams, + const size_t cParams) override; // DTTERM_WindowManipulation private: diff --git a/src/terminal/adapter/conGetSet.hpp b/src/terminal/adapter/conGetSet.hpp index 2f2733b03..ecf7e215e 100644 --- a/src/terminal/adapter/conGetSet.hpp +++ b/src/terminal/adapter/conGetSet.hpp @@ -107,6 +107,8 @@ namespace Microsoft::Console::VirtualTerminal virtual BOOL MoveToBottom() const = 0; virtual BOOL PrivateSetColorTableEntry(const short index, const COLORREF value) const = 0; + virtual BOOL PrivateSetDefaultForeground(const COLORREF value) const = 0; + virtual BOOL PrivateSetDefaultBackground(const COLORREF value) const = 0; }; } diff --git a/src/terminal/adapter/termDispatch.hpp b/src/terminal/adapter/termDispatch.hpp index ea3f2fce1..acc3e3147 100644 --- a/src/terminal/adapter/termDispatch.hpp +++ b/src/terminal/adapter/termDispatch.hpp @@ -20,77 +20,79 @@ namespace Microsoft::Console::VirtualTerminal class Microsoft::Console::VirtualTerminal::TermDispatch : public Microsoft::Console::VirtualTerminal::ITermDispatch { public: - virtual void Execute(const wchar_t wchControl) = 0; - virtual void Print(const wchar_t wchPrintable) = 0; - virtual void PrintString(const wchar_t* const rgwch, const size_t cch) = 0; + void Execute(const wchar_t wchControl) override = 0; + void Print(const wchar_t wchPrintable) override = 0; + void PrintString(const wchar_t* const rgwch, const size_t cch) override = 0; - virtual bool CursorUp(const unsigned int /*uiDistance*/) { return false; }; // CUU - virtual bool CursorDown(const unsigned int /*uiDistance*/) { return false; } // CUD - virtual bool CursorForward(const unsigned int /*uiDistance*/) { return false; } // CUF - virtual bool CursorBackward(const unsigned int /*uiDistance*/) { return false; } // CUB - virtual bool CursorNextLine(const unsigned int /*uiDistance*/) { return false; } // CNL - virtual bool CursorPrevLine(const unsigned int /*uiDistance*/) { return false; } // CPL - virtual bool CursorHorizontalPositionAbsolute(const unsigned int /*uiColumn*/) { return false; } // CHA - virtual bool VerticalLinePositionAbsolute(const unsigned int /*uiLine*/) { return false; } // VPA - virtual bool CursorPosition(const unsigned int /*uiLine*/, const unsigned int /*uiColumn*/) { return false; } // CUP - virtual bool CursorSavePosition() { return false; } // DECSC - virtual bool CursorRestorePosition() { return false; } // DECRC - virtual bool CursorVisibility(const bool /*fIsVisible*/) { return false; } // DECTCEM - virtual bool InsertCharacter(const unsigned int /*uiCount*/) { return false; } // ICH - virtual bool DeleteCharacter(const unsigned int /*uiCount*/) { return false; } // DCH - virtual bool ScrollUp(const unsigned int /*uiDistance*/) { return false; } // SU - virtual bool ScrollDown(const unsigned int /*uiDistance*/) { return false; } // SD - virtual bool InsertLine(const unsigned int /*uiDistance*/) { return false; } // IL - virtual bool DeleteLine(const unsigned int /*uiDistance*/) { return false; } // DL - virtual bool SetColumns(const unsigned int /*uiColumns*/) { return false; } // DECSCPP, DECCOLM - virtual bool SetCursorKeysMode(const bool /*fApplicationMode*/) { return false; } // DECCKM - virtual bool SetKeypadMode(const bool /*fApplicationMode*/) { return false; } // DECKPAM, DECKPNM - virtual bool EnableCursorBlinking(const bool /*fEnable*/) { return false; } // ATT610 - virtual bool SetTopBottomScrollingMargins(const SHORT /*sTopMargin*/, const SHORT /*sBottomMargin*/) { return false; } // DECSTBM - virtual bool ReverseLineFeed() { return false; } // RI - virtual bool SetWindowTitle(std::wstring_view /*title*/) { return false; } // OscWindowTitle - virtual bool UseAlternateScreenBuffer() { return false; } // ASBSET - virtual bool UseMainScreenBuffer() { return false; } // ASBRST - virtual bool HorizontalTabSet() { return false; } // HTS - virtual bool ForwardTab(const SHORT /*sNumTabs*/) { return false; } // CHT - virtual bool BackwardsTab(const SHORT /*sNumTabs*/) { return false; } // CBT - virtual bool TabClear(const SHORT /*sClearType*/) { return false; } // TBC - virtual bool EnableVT200MouseMode(const bool /*fEnabled*/) { return false; } // ?1000 - virtual bool EnableUTF8ExtendedMouseMode(const bool /*fEnabled*/) { return false; } // ?1005 - virtual bool EnableSGRExtendedMouseMode(const bool /*fEnabled*/) { return false; } // ?1006 - virtual bool EnableButtonEventMouseMode(const bool /*fEnabled*/) { return false; } // ?1002 - virtual bool EnableAnyEventMouseMode(const bool /*fEnabled*/) { return false; } // ?1003 - virtual bool EnableAlternateScroll(const bool /*fEnabled*/) { return false; } // ?1007 - virtual bool SetColorTableEntry(const size_t /*tableIndex*/, const DWORD /*dwColor*/) { return false; } // OSCColorTable + bool CursorUp(const unsigned int /*uiDistance*/) override { return false; } // CUU + bool CursorDown(const unsigned int /*uiDistance*/) override { return false; } // CUD + bool CursorForward(const unsigned int /*uiDistance*/) override { return false; } // CUF + bool CursorBackward(const unsigned int /*uiDistance*/) override { return false; } // CUB + bool CursorNextLine(const unsigned int /*uiDistance*/) override { return false; } // CNL + bool CursorPrevLine(const unsigned int /*uiDistance*/) override { return false; } // CPL + bool CursorHorizontalPositionAbsolute(const unsigned int /*uiColumn*/) override { return false; } // CHA + bool VerticalLinePositionAbsolute(const unsigned int /*uiLine*/) override { return false; } // VPA + bool CursorPosition(const unsigned int /*uiLine*/, const unsigned int /*uiColumn*/) override { return false; } // CUP + bool CursorSavePosition() override { return false; } // DECSC + bool CursorRestorePosition() override { return false; } // DECRC + bool CursorVisibility(const bool /*fIsVisible*/) override { return false; } // DECTCEM + bool InsertCharacter(const unsigned int /*uiCount*/) override { return false; } // ICH + bool DeleteCharacter(const unsigned int /*uiCount*/) override { return false; } // DCH + bool ScrollUp(const unsigned int /*uiDistance*/) override { return false; } // SU + bool ScrollDown(const unsigned int /*uiDistance*/) override { return false; } // SD + bool InsertLine(const unsigned int /*uiDistance*/) override { return false; } // IL + bool DeleteLine(const unsigned int /*uiDistance*/) override { return false; } // DL + bool SetColumns(const unsigned int /*uiColumns*/) override { return false; } // DECSCPP, DECCOLM + bool SetCursorKeysMode(const bool /*fApplicationMode*/) override { return false; } // DECCKM + bool SetKeypadMode(const bool /*fApplicationMode*/) override { return false; } // DECKPAM, DECKPNM + bool EnableCursorBlinking(const bool /*fEnable*/) override { return false; } // ATT610 + bool SetTopBottomScrollingMargins(const SHORT /*sTopMargin*/, const SHORT /*sBottomMargin*/) override { return false; } // DECSTBM + bool ReverseLineFeed() override { return false; } // RI + bool SetWindowTitle(std::wstring_view /*title*/) override { return false; } // OscWindowTitle + bool UseAlternateScreenBuffer() override { return false; } // ASBSET + bool UseMainScreenBuffer() override { return false; } // ASBRST + bool HorizontalTabSet() override { return false; } // HTS + bool ForwardTab(const SHORT /*sNumTabs*/) override { return false; } // CHT + bool BackwardsTab(const SHORT /*sNumTabs*/) override { return false; } // CBT + bool TabClear(const SHORT /*sClearType*/) override { return false; } // TBC + bool EnableVT200MouseMode(const bool /*fEnabled*/) override { return false; } // ?1000 + bool EnableUTF8ExtendedMouseMode(const bool /*fEnabled*/) override { return false; } // ?1005 + bool EnableSGRExtendedMouseMode(const bool /*fEnabled*/) override { return false; } // ?1006 + bool EnableButtonEventMouseMode(const bool /*fEnabled*/)override { return false; } // ?1002 + bool EnableAnyEventMouseMode(const bool /*fEnabled*/) override { return false; } // ?1003 + bool EnableAlternateScroll(const bool /*fEnabled*/) override { return false; } // ?1007 + bool SetColorTableEntry(const size_t /*tableIndex*/, const DWORD /*dwColor*/) override { return false; } // OSCColorTable + bool SetDefaultForeground(const DWORD /*dwColor*/) override { return false; } // OSCDefaultForeground + bool SetDefaultBackground(const DWORD /*dwColor*/) override { return false; } // OSCDefaultBackground - virtual bool EraseInDisplay(const DispatchTypes::EraseType /* eraseType*/) { return false; } // ED - virtual bool EraseInLine(const DispatchTypes::EraseType /* eraseType*/) { return false; } // EL - virtual bool EraseCharacters(const unsigned int /*uiNumChars*/){ return false; } // ECH + bool EraseInDisplay(const DispatchTypes::EraseType /* eraseType*/) override { return false; } // ED + bool EraseInLine(const DispatchTypes::EraseType /* eraseType*/) override { return false; } // EL + bool EraseCharacters(const unsigned int /*uiNumChars*/) override { return false; } // ECH - virtual bool SetGraphicsRendition(_In_reads_(_Param_(2)) const DispatchTypes::GraphicsOptions* const /*rgOptions*/, - const size_t /*cOptions*/) { return false; } // SGR + bool SetGraphicsRendition(_In_reads_(_Param_(2)) const DispatchTypes::GraphicsOptions* const /*rgOptions*/, + const size_t /*cOptions*/) override { return false; } // SGR - virtual bool SetPrivateModes(_In_reads_(_Param_(2)) const DispatchTypes::PrivateModeParams* const /*rgParams*/, - const size_t /*cParams*/) { return false; } // DECSET + bool SetPrivateModes(_In_reads_(_Param_(2)) const DispatchTypes::PrivateModeParams* const /*rgParams*/, + const size_t /*cParams*/) override { return false; } // DECSET - virtual bool ResetPrivateModes(_In_reads_(_Param_(2)) const DispatchTypes::PrivateModeParams* const /*rgParams*/, - const size_t /*cParams*/) { return false; } // DECRST + bool ResetPrivateModes(_In_reads_(_Param_(2)) const DispatchTypes::PrivateModeParams* const /*rgParams*/, + const size_t /*cParams*/) override { return false; } // DECRST - virtual bool DeviceStatusReport(const DispatchTypes::AnsiStatusType /*statusType*/) { return false; } // DSR - virtual bool DeviceAttributes() { return false; } // DA + bool DeviceStatusReport(const DispatchTypes::AnsiStatusType /*statusType*/) override { return false; } // DSR + bool DeviceAttributes() override { return false; } // DA - virtual bool DesignateCharset(const wchar_t /*wchCharset*/){ return false; } // DesignateCharset + bool DesignateCharset(const wchar_t /*wchCharset*/) override { return false; } // DesignateCharset - virtual bool SoftReset(){ return false; } // DECSTR - virtual bool HardReset(){ return false; } // RIS - - virtual bool SetCursorStyle(const DispatchTypes::CursorStyle /*cursorStyle*/){ return false; } // DECSCUSR - virtual bool SetCursorColor(const COLORREF /*Color*/) { return false; } // OSCSetCursorColor, OSCResetCursorColor + bool SoftReset() override { return false; } // DECSTR + bool HardReset() override { return false; } // RIS + bool SetCursorStyle(const DispatchTypes::CursorStyle /*cursorStyle*/) override { return false; } // DECSCUSR + bool SetCursorColor(const COLORREF /*Color*/) override { return false; } // OSCSetCursorColor, OSCResetCursorColor + // DTTERM_WindowManipulation - virtual bool WindowManipulation(const DispatchTypes::WindowManipulationType /*uiFunction*/, - _In_reads_(_Param_(3)) const unsigned short* const /*rgusParams*/, - const size_t /*cParams*/) { return false; } + bool WindowManipulation(const DispatchTypes::WindowManipulationType /*uiFunction*/, + _In_reads_(_Param_(3)) const unsigned short* const /*rgusParams*/, + const size_t /*cParams*/) override { return false; } }; diff --git a/src/terminal/adapter/ut_adapter/adapterTest.cpp b/src/terminal/adapter/ut_adapter/adapterTest.cpp index ee83e53ff..7289d6bed 100644 --- a/src/terminal/adapter/ut_adapter/adapterTest.cpp +++ b/src/terminal/adapter/ut_adapter/adapterTest.cpp @@ -776,6 +776,28 @@ public: return _fPrivateSetColorTableEntryResult; } + BOOL PrivateSetDefaultForeground(const COLORREF value) const noexcept override + { + Log::Comment(L"PrivateSetDefaultForeground MOCK called..."); + if (_fPrivateSetDefaultForegroundResult) + { + VERIFY_ARE_EQUAL(_expectedDefaultForegroundColorValue, value); + } + + return _fPrivateSetDefaultForegroundResult; + } + + BOOL PrivateSetDefaultBackground(const COLORREF value) const noexcept override + { + Log::Comment(L"PrivateSetDefaultForeground MOCK called..."); + if (_fPrivateSetDefaultBackgroundResult) + { + VERIFY_ARE_EQUAL(_expectedDefaultBackgroundColorValue, value); + } + + return _fPrivateSetDefaultBackgroundResult; + } + void _IncrementCoordPos(_Inout_ COORD* pcoord) { pcoord->X++; @@ -1378,6 +1400,12 @@ public: short _expectedColorTableIndex = -1; COLORREF _expectedColorValue = INVALID_COLOR; + bool _fPrivateSetDefaultForegroundResult = false; + COLORREF _expectedDefaultForegroundColorValue = INVALID_COLOR; + + bool _fPrivateSetDefaultBackgroundResult = false; + COLORREF _expectedDefaultBackgroundColorValue = INVALID_COLOR; + private: HANDLE _hCon; }; diff --git a/src/terminal/parser/OutputStateMachineEngine.cpp b/src/terminal/parser/OutputStateMachineEngine.cpp index e68a8ce1e..7037975cc 100644 --- a/src/terminal/parser/OutputStateMachineEngine.cpp +++ b/src/terminal/parser/OutputStateMachineEngine.cpp @@ -697,8 +697,10 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, case OscActionCodes::SetColor: fSuccess = _GetOscSetColorTable(pwchOscStringBuffer, cchOscString, &tableIndex, &dwColor); break; + case OscActionCodes::SetForegroundColor: + case OscActionCodes::SetBackgroundColor: case OscActionCodes::SetCursorColor: - fSuccess = _GetOscSetCursorColor(pwchOscStringBuffer, cchOscString, &dwColor); + fSuccess = _GetOscSetColor(pwchOscStringBuffer, cchOscString, &dwColor); break; case OscActionCodes::ResetCursorColor: // the console uses 0xffffffff as an "invalid color" value @@ -724,6 +726,14 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/, fSuccess = _dispatch->SetColorTableEntry(tableIndex, dwColor); TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCCT); break; + case OscActionCodes::SetForegroundColor: + fSuccess = _dispatch->SetDefaultForeground(dwColor); + TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCFG); + break; + case OscActionCodes::SetBackgroundColor: + fSuccess = _dispatch->SetDefaultBackground(dwColor); + TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCBG); + break; case OscActionCodes::SetCursorColor: fSuccess = _dispatch->SetCursorColor(dwColor); TermTelemetry::Instance().Log(TermTelemetry::Codes::OSCSCC); @@ -1162,7 +1172,7 @@ bool OutputStateMachineEngine::_VerifyDeviceAttributesParams(_In_reads_(cParams) // - Null terminates, then returns, the string that we've collected as part of the OSC string. // Arguments: // - ppwchTitle - a pointer to point to the Osc String to use as a title. -// - pcchTitleLength - a pointer place the length of ppwchTitle into. +// - pcchTitle - a pointer place the length of ppwchTitle into. // Return Value: // - True if there was a title to output. (a title with length=0 is still valid) _Success_(return) @@ -1476,10 +1486,12 @@ bool OutputStateMachineEngine::s_ParseColorSpec(_In_reads_(cchBuffer) const wcha // "rgb://" // where is two hex digits // Arguments: -// - ppwchTitle - a pointer to point to the Osc String to use as a title. -// - pcchTitleLength - a pointer place the length of ppwchTitle into. +// - pwchOscStringBuffer - a pointer to the Osc String to parse +// - cchOscString - the length of the Osc String +// - pTableIndex - a pointer that recieves the table index +// - pRgb - a pointer that recieves the color that we parsed in the format: 0x00BBGGRR // Return Value: -// - True if there was a title to output. (a title with length=0 is still valid) +// - True if a table index and color was parsed successfully. False otherwise. bool OutputStateMachineEngine::_GetOscSetColorTable(_In_reads_(cchOscString) const wchar_t* const pwchOscStringBuffer, const size_t cchOscString, _Out_ size_t* const pTableIndex, @@ -1548,16 +1560,17 @@ bool OutputStateMachineEngine::_GetOscSetColorTable(_In_reads_(cchOscString) con } // Routine Description: -// - OSC 12 ; spec ST +// - OSC 10, 11, 12 ; spec ST // spec: a color in the following format: // "rgb://" // where is two hex digits // Arguments: -// - ppwchTitle - a pointer to point to the Osc String to use as a title. -// - pcchTitleLength - a pointer place the length of ppwchTitle into. +// - pwchOscStringBuffer - a pointer to the Osc String to parse +// - cchOscString - the length of the Osc String +// - pRgb - a pointer that recieves the color that we parsed in the format: 0x00BBGGRR // Return Value: -// - True if there was a title to output. (a title with length=0 is still valid) -bool OutputStateMachineEngine::_GetOscSetCursorColor(_In_reads_(cchOscString) const wchar_t* const pwchOscStringBuffer, +// - True if a table index and color was parsed successfully. False otherwise. +bool OutputStateMachineEngine::_GetOscSetColor(_In_reads_(cchOscString) const wchar_t* const pwchOscStringBuffer, const size_t cchOscString, _Out_ DWORD* const pRgb) const { diff --git a/src/terminal/parser/OutputStateMachineEngine.hpp b/src/terminal/parser/OutputStateMachineEngine.hpp index bafedc958..11ad0d8bf 100644 --- a/src/terminal/parser/OutputStateMachineEngine.hpp +++ b/src/terminal/parser/OutputStateMachineEngine.hpp @@ -131,8 +131,13 @@ namespace Microsoft::Console::VirtualTerminal SetIconAndWindowTitle = 0, SetWindowIcon = 1, SetWindowTitle = 2, + SetWindowProperty = 3, // Not implemented SetColor = 4, + SetForegroundColor = 10, + SetBackgroundColor = 11, SetCursorColor = 12, + ResetForegroundColor = 110, // Not implemented + ResetBackgroundColor = 111, // Not implemented ResetCursorColor = 112, }; @@ -251,9 +256,9 @@ namespace Microsoft::Console::VirtualTerminal const size_t cchBuffer, _Out_ DWORD* const pRgb); - bool _GetOscSetCursorColor(_In_reads_(cchOscString) const wchar_t* const pwchOscStringBuffer, - const size_t cchOscString, - _Out_ DWORD* const pRgb) const; + bool _GetOscSetColor(_In_reads_(cchOscString) const wchar_t* const pwchOscStringBuffer, + const size_t cchOscString, + _Out_ DWORD* const pRgb) const; static const DispatchTypes::CursorStyle s_defaultCursorStyle = DispatchTypes::CursorStyle::BlinkingBlockDefault; _Success_(return) diff --git a/src/terminal/parser/telemetry.cpp b/src/terminal/parser/telemetry.cpp index 2d227514e..90d81f08f 100644 --- a/src/terminal/parser/telemetry.cpp +++ b/src/terminal/parser/telemetry.cpp @@ -243,6 +243,8 @@ void TermTelemetry::WriteFinalTraceLog() const TraceLoggingUInt32(_uiTimesUsed[OSCCT], "OscColorTable"), TraceLoggingUInt32(_uiTimesUsed[OSCSCC], "OscSetCursorColor"), TraceLoggingUInt32(_uiTimesUsed[OSCRCC], "OscResetCursorColor"), + TraceLoggingUInt32(_uiTimesUsed[OSCFG], "OscForegroundColor"), + TraceLoggingUInt32(_uiTimesUsed[OSCBG], "OscBackgroundColor"), TraceLoggingUInt32(_uiTimesUsed[REP], "REP"), TraceLoggingUInt32Array(_uiTimesFailed, ARRAYSIZE(_uiTimesFailed), "Failed"), TraceLoggingUInt32(_uiTimesFailedOutsideRange, "FailedOutsideRange")); diff --git a/src/terminal/parser/telemetry.hpp b/src/terminal/parser/telemetry.hpp index e73d75de1..59c8752d3 100644 --- a/src/terminal/parser/telemetry.hpp +++ b/src/terminal/parser/telemetry.hpp @@ -83,6 +83,8 @@ namespace Microsoft::Console::VirtualTerminal OSCSCC, OSCRCC, REP, + OSCFG, + OSCBG, // Only use this last enum as a count of the number of codes. NUMBER_OF_CODES };