2019-05-03 00:29:04 +02:00
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
# include "precomp.h"
# include "settings.hpp"
2020-11-25 22:02:10 +01:00
# include "../interactivity/inc/ServiceLocator.hpp"
2020-10-15 02:29:10 +02:00
# include "../types/inc/colorTable.hpp"
2019-05-03 00:29:04 +02:00
# pragma hdrstop
2019-11-04 14:37:48 +01:00
constexpr unsigned int DEFAULT_NUMBER_OF_COMMANDS = 25 ;
constexpr unsigned int DEFAULT_NUMBER_OF_BUFFERS = 4 ;
2019-05-03 00:29:04 +02:00
2019-05-30 20:14:21 +02:00
using Microsoft : : Console : : Interactivity : : ServiceLocator ;
2019-05-03 00:29:04 +02:00
Settings : : Settings ( ) :
_dwHotKey ( 0 ) ,
_dwStartupFlags ( 0 ) ,
_wFillAttribute ( FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE ) , // White (not bright) on black by default
_wPopupFillAttribute ( FOREGROUND_RED | FOREGROUND_BLUE | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY ) , // Purple on white (bright) by default
_wShowWindow ( SW_SHOWNORMAL ) ,
_wReserved ( 0 ) ,
// dwScreenBufferSize initialized below
// dwWindowSize initialized below
// dwWindowOrigin initialized below
_nFont ( 0 ) ,
// dwFontSize initialized below
_uFontFamily ( 0 ) ,
_uFontWeight ( 0 ) ,
// FaceName initialized below
2019-11-01 18:33:09 +01:00
_uCursorSize ( Cursor : : CURSOR_SMALL_SIZE ) ,
2019-05-03 00:29:04 +02:00
_bFullScreen ( false ) ,
_bQuickEdit ( true ) ,
_bInsertMode ( true ) ,
_bAutoPosition ( true ) ,
_uHistoryBufferSize ( DEFAULT_NUMBER_OF_COMMANDS ) ,
_uNumberOfHistoryBuffers ( DEFAULT_NUMBER_OF_BUFFERS ) ,
_bHistoryNoDup ( false ) ,
// ColorTable initialized below
_uCodePage ( ServiceLocator : : LocateGlobals ( ) . uiOEMCP ) ,
_uScrollScale ( 1 ) ,
_bLineSelection ( true ) ,
_bWrapText ( true ) ,
_fCtrlKeyShortcutsDisabled ( false ) ,
_bWindowAlpha ( BYTE_MAX ) , // 255 alpha = opaque. 0 = transparent.
_fFilterOnPaste ( false ) ,
Allow FontInfo{,Base,Desired} to store a font name > 32 wch (#3107)
We now truncate the font name as it goes out to GDI APIs, in console API
servicing, and in the propsheet.
I attempted to defer truncating the font to as far up the stack as
possible, so as to make FontInfo usable for the broadest set of cases.
There were a couple questions that came up: I know that `Settings` gets
memset (memsat?) by the registry deserializer, and perhaps that's
another place for us to tackle. Right now, this pull request enables
fonts whose names are >= 32 characters _in Windows Terminal only_, but
the underpinnings are there for conhost as well. We'd need to explicitly
break at the API, or perhaps return a failure or log something to
telemetry.
* Should we log truncation at the API boundary to telemetry?
-> Later; followup filed (#3123)
* Should we fix Settings here, or later?
-> Later; followup filed (#3123)
* `TrueTypeFontList` is built out of things in winconp, the private
console header. Concern about interop structures.
-> Not used for interop, followup filed to clean it up (#3123)
* Is `unsigned int` right for codepage? For width?
-> Yes: codepage became UINT (from WORD) when we moved from Win16 to
Win32
This commit also includes a workaround for #3170. Growing
CONSOLE_INFORMATION made us lose the struct layout lottery during
release builds, and this was an expedient fix.
Closes #602.
Related to #3123.
2019-10-15 06:23:45 +02:00
_LaunchFaceName { } ,
2019-05-03 00:29:04 +02:00
_fTrimLeadingZeros ( FALSE ) ,
_fEnableColorSelection ( FALSE ) ,
_fAllowAltF4Close ( true ) ,
_dwVirtTermLevel ( 0 ) ,
_fUseWindowSizePixels ( false ) ,
_fAutoReturnOnNewline ( true ) , // the historic Windows behavior defaults this to on.
_fRenderGridWorldwide ( false ) , // historically grid lines were only rendered in DBCS codepages, so this is false by default unless otherwise specified.
Add support for the DECSCNM screen mode (#3817)
## Summary of the Pull Request
This adds support for the [`DECSCNM`](https://vt100.net/docs/vt510-rm/DECSCNM.html) private mode escape sequence, which toggles the display between normal and reverse screen modes. When reversed, the background and foreground colors are switched. Tested manually, with [Vttest](https://invisible-island.net/vttest/), and with some new unit tests.
## References
This also fixes issue #72 for the most part, although if you toggle the mode too fast, there is no discernible flash.
## PR Checklist
* [x] Closes #3773
* [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
* [ ] 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: #xxx
## Detailed Description of the Pull Request / Additional comments
I've implemented this as a new flag in the `Settings` class, along with updates to the `LookupForegroundColor` and `LookupBackgroundColor` methods, to switch the returned foreground and background colors when that flag is set.
It also required a new private API in the `ConGetSet` interface to toggle the setting. And that API is then called from the `AdaptDispatch` class when the screen mode escape sequence is received.
The last thing needed was to add a step to the `HardReset` method, to reset the mode back to normal, which is one of the `RIS` requirements.
Note that this does currently work in the Windows Terminal, but once #2661 is implemented that may no longer be the case. It might become necessary to let the mode change sequences pass through conpty, and handle the color reversing on the client side.
## Validation Steps Performed
I've added a state machine test to make sure the escape sequence is dispatched correctly, and a screen buffer test to confirm that the mode change does alter the interpretation of colors as expected.
I've also confirmed that the various "light background" tests in Vttest now display correctly, and that the `tput flash` command (in a bash shell) does actually cause the screen to flash.
2020-01-22 23:29:50 +01:00
_fScreenReversed ( false ) ,
2019-05-03 00:29:04 +02:00
// window size pixels initialized below
_fInterceptCopyPaste ( 0 ) ,
_DefaultForeground ( INVALID_COLOR ) ,
_DefaultBackground ( INVALID_COLOR ) ,
_fUseDx ( false ) ,
_fCopyColor ( false )
{
_dwScreenBufferSize . X = 80 ;
_dwScreenBufferSize . Y = 25 ;
_dwWindowSize . X = _dwScreenBufferSize . X ;
_dwWindowSize . Y = _dwScreenBufferSize . Y ;
_dwWindowSizePixels = { 0 } ;
_dwWindowOrigin . X = 0 ;
_dwWindowOrigin . Y = 0 ;
_dwFontSize . X = 0 ;
_dwFontSize . Y = 16 ;
ZeroMemory ( ( void * ) & _FaceName , sizeof ( _FaceName ) ) ;
wcscpy_s ( _FaceName , DEFAULT_TT_FONT_FACENAME ) ;
_CursorColor = Cursor : : s_InvertCursorColor ;
_CursorType = CursorType : : Legacy ;
2020-07-14 20:30:59 +02:00
gsl : : span < COLORREF > tableView = { _colorTable . data ( ) , _colorTable . size ( ) } ;
Fix SGR indexed colors to distinguish Indexed256 color (and more) (#5834)
This PR introduces a new `ColorType` to allow us to distinguish between
`SGR` indexed colors from the 16 color table, the lower half of which
can be brightened, and the ISO/ITU indexed colors from the 256 color
table, which have a fixed brightness. Retaining the distinction between
these two types will enable us to forward the correct `SGR` sequences to
conpty when addressing issue #2661.
The other benefit of retaining the color index (which we didn't
previously do for ISO/ITU colors) is that it ensures that the colors are
updated correctly when the color scheme is changed.
## References
* This is another step towards fixing the conpty narrowing bugs in issue
#2661.
* This is technically a fix for issue #5384, but that won't be apparent
until #2661 is complete.
## PR Checklist
* [x] Closes #1223
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already.
## Detailed Description of the Pull Request / Additional comments
The first part of this PR was the introduction of a new `ColorType` in
the `TextColor` class. Instead of just the one `IsIndex` type, there is
now an `IsIndex16` and an `IsIndex256`. `IsIndex16` covers the eight
original ANSI colors set with `SGR 3x` and `SGR 4x`, as well as the
brighter aixterm variants set with `SGR 9x` and `SGR 10x`. `IsIndex256`
covers the 256 ISO/ITU indexed colors set with `SGR 38;5` and `SGR
48;5`.
There are two reasons for this distinction. The first is that the ANSI
colors have the potential to be brightened by the `SGR 1` bold
attribute, while the ISO/ITO color do not. The second reason is that
when forwarding an attributes through conpty, we want to try and
preserve the original SGR sequence that generated each color (to the
extent that that is possible). By having the two separate types, we can
map the `IsIndex16` colors back to ANSI/aixterm values, and `IsIndex256`
to the ISO/ITU sequences.
In addition to the VT colors, we also have to deal with the legacy
colors set by the Windows console APIs, but we don't really need a
separate type for those. It seemed most appropriate to me to store them
as `IsIndex256` colors, since it doesn't make sense to have them
brightened by the `SGR 1` attribute (which is what would happen if they
were stored as `IsIndex16`). If a console app wanted a bright color it
would have selected one, so we shouldn't be messing with that choice.
The second part of the PR was the unification of the two color tables.
Originally we had a 16 color table for the legacy colors, and a separate
table for the 256 ISO/ITU colors. These have now been merged into one,
so color table lookups no longer need to decide which of the two tables
they should be referencing. I've also updated all the methods that took
a color table as a parameter to use a `basic_string_view` instead of
separate pointer and length variables, which I think makes them a lot
easier and safer to work with.
With this new architecture in place, I could now update the
`AdaptDispatch` SGR implementation to store the ISO/ITU indexed colors
as `IsIndex256` values, where before they were mapped to RGB values
(which prevented them reflecting any color scheme changes). I could also
update the `TerminalDispatch` implementation to differentiate between
the two index types, so that the `SGR 1` brightening would only be
applied to the ANSI colors.
I've also done a bit of code refactoring to try and minimise any direct
access to the color tables, getting rid of a lot of places that were
copying tables with `memmove` operations. I'm hoping this will make it
easier for us to update the code in the future if we want to reorder the
table entries (which is likely a requirement for unifying the
`AdaptDispatch` and `TerminalDispatch` implementations).
## Validation Steps Performed
For testing, I've just updated the existing unit tests to account for
the API changes. The `TextColorTests` required an extra parameter
specifying the index type when setting an index. And the `AdapterTest`
and `ScreenBufferTests` required the use of the new `SetIndexedXXX`
methods in order to be explicit about the index type, instead of relying
on the `TextAttribute` constructor and the old `SetForeground` and
`SetBackground` methods which didn't have a way to differentiate index
types.
I've manually tested the various console APIs
(`SetConsoleTextAttribute`, `ReadConsoleOutputAttribute`, and
`ReadConsoleOutput`), to make sure they are still setting and reading
the attributes as well as they used to. And I've tested the
`SetConsoleScreenBufferInfoEx` and `GetConsoleScreenBufferInfoEx` APIs
to make sure they can read and write the color table correctly. I've
also tested the color table in the properties dialog, made sure it was
saved and restored from the registry correctly, and similarly saved and
restored from a shortcut link.
Note that there are still a bunch of issues with the color table APIs,
but no new problems have been introduced by the changes in this PR, as
far as I could tell.
I've also done a bunch of manual tests of `OSC 4` to make sure it's
updating all the colors correctly (at least in conhost), and confirmed
that the test case in issue #1223 now works as expected.
2020-05-28 00:34:45 +02:00
: : Microsoft : : Console : : Utils : : Initialize256ColorTable ( tableView ) ;
2019-07-26 00:03:00 +02:00
: : Microsoft : : Console : : Utils : : InitializeCampbellColorTableForConhost ( tableView ) ;
2019-05-03 00:29:04 +02:00
}
// Routine Description:
// - Applies hardcoded default settings that are in line with what is defined
// in our Windows edition manifest (living in win32k-settings.man).
// - NOTE: This exists in case we cannot access the registry on desktop platforms.
// We will use this to provide better defaults than the constructor values which
// are optimized for OneCore.
// Arguments:
// - <none>
// Return Value:
// - <none> - Adjusts internal state only.
void Settings : : ApplyDesktopSpecificDefaults ( )
{
_dwFontSize . X = 0 ;
_dwFontSize . Y = 16 ;
_uFontFamily = 0 ;
_dwScreenBufferSize . X = 120 ;
_dwScreenBufferSize . Y = 9001 ;
_uCursorSize = 25 ;
_dwWindowSize . X = 120 ;
_dwWindowSize . Y = 30 ;
_wFillAttribute = 0x7 ;
_wPopupFillAttribute = 0xf5 ;
wcscpy_s ( _FaceName , L " __DefaultTTFont__ " ) ;
_uFontWeight = 0 ;
_bInsertMode = TRUE ;
_bFullScreen = FALSE ;
_fCtrlKeyShortcutsDisabled = false ;
_bWrapText = true ;
_bLineSelection = TRUE ;
_bWindowAlpha = 255 ;
_fFilterOnPaste = TRUE ;
_bQuickEdit = TRUE ;
_uHistoryBufferSize = 50 ;
_uNumberOfHistoryBuffers = 4 ;
_bHistoryNoDup = FALSE ;
2020-07-14 20:30:59 +02:00
gsl : : span < COLORREF > tableView = { _colorTable . data ( ) , _colorTable . size ( ) } ;
2019-07-26 00:03:00 +02:00
: : Microsoft : : Console : : Utils : : InitializeCampbellColorTableForConhost ( tableView ) ;
2019-05-03 00:29:04 +02:00
_fTrimLeadingZeros = false ;
_fEnableColorSelection = false ;
_uScrollScale = 1 ;
}
void Settings : : ApplyStartupInfo ( const Settings * const pStartupSettings )
{
const DWORD dwFlags = pStartupSettings - > _dwStartupFlags ;
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686331(v=vs.85).aspx
// Note: These attributes do not get sent to us if we started conhost
// directly. See minkernel/console/client/dllinit for the
// initialization of these values for cmdline applications.
if ( WI_IsFlagSet ( dwFlags , STARTF_USECOUNTCHARS ) )
{
_dwScreenBufferSize = pStartupSettings - > _dwScreenBufferSize ;
}
if ( WI_IsFlagSet ( dwFlags , STARTF_USESIZE ) )
{
// WARNING: This size is in pixels when passed in the create process call.
// It will need to be divided by the font size before use.
// All other Window Size values (from registry/shortcuts) are stored in characters.
_dwWindowSizePixels = pStartupSettings - > _dwWindowSize ;
_fUseWindowSizePixels = true ;
}
if ( WI_IsFlagSet ( dwFlags , STARTF_USEPOSITION ) )
{
_dwWindowOrigin = pStartupSettings - > _dwWindowOrigin ;
_bAutoPosition = FALSE ;
}
if ( WI_IsFlagSet ( dwFlags , STARTF_USEFILLATTRIBUTE ) )
{
_wFillAttribute = pStartupSettings - > _wFillAttribute ;
}
if ( WI_IsFlagSet ( dwFlags , STARTF_USESHOWWINDOW ) )
{
_wShowWindow = pStartupSettings - > _wShowWindow ;
}
}
// Method Description:
// - Applies settings passed on the commandline to this settings structure.
// Currently, the only settings that can be passed on the commandline are
// the initial width and height of the screenbuffer/viewport.
// Arguments:
// - consoleArgs: A reference to a parsed command-line args object.
// Return Value:
// - <none>
void Settings : : ApplyCommandlineArguments ( const ConsoleArguments & consoleArgs )
{
const short width = consoleArgs . GetWidth ( ) ;
const short height = consoleArgs . GetHeight ( ) ;
if ( width > 0 & & height > 0 )
{
_dwScreenBufferSize . X = width ;
_dwWindowSize . X = width ;
_dwScreenBufferSize . Y = height ;
_dwWindowSize . Y = height ;
}
else if ( ServiceLocator : : LocateGlobals ( ) . getConsoleInformation ( ) . IsInVtIoMode ( ) )
{
// If we're a PTY but we weren't explicitly told a size, use the window size as the buffer size.
_dwScreenBufferSize = _dwWindowSize ;
}
}
// WARNING: this function doesn't perform any validation or conversion
void Settings : : InitFromStateInfo ( _In_ PCONSOLE_STATE_INFO pStateInfo )
{
_wFillAttribute = pStateInfo - > ScreenAttributes ;
_wPopupFillAttribute = pStateInfo - > PopupAttributes ;
_dwScreenBufferSize = pStateInfo - > ScreenBufferSize ;
_dwWindowSize = pStateInfo - > WindowSize ;
_dwWindowOrigin . X = ( SHORT ) pStateInfo - > WindowPosX ;
_dwWindowOrigin . Y = ( SHORT ) pStateInfo - > WindowPosY ;
_dwFontSize = pStateInfo - > FontSize ;
_uFontFamily = pStateInfo - > FontFamily ;
_uFontWeight = pStateInfo - > FontWeight ;
StringCchCopyW ( _FaceName , ARRAYSIZE ( _FaceName ) , pStateInfo - > FaceName ) ;
_uCursorSize = pStateInfo - > CursorSize ;
_bFullScreen = pStateInfo - > FullScreen ;
_bQuickEdit = pStateInfo - > QuickEdit ;
_bAutoPosition = pStateInfo - > AutoPosition ;
_bInsertMode = pStateInfo - > InsertMode ;
_bHistoryNoDup = pStateInfo - > HistoryNoDup ;
_uHistoryBufferSize = pStateInfo - > HistoryBufferSize ;
_uNumberOfHistoryBuffers = pStateInfo - > NumberOfHistoryBuffers ;
Fix SGR indexed colors to distinguish Indexed256 color (and more) (#5834)
This PR introduces a new `ColorType` to allow us to distinguish between
`SGR` indexed colors from the 16 color table, the lower half of which
can be brightened, and the ISO/ITU indexed colors from the 256 color
table, which have a fixed brightness. Retaining the distinction between
these two types will enable us to forward the correct `SGR` sequences to
conpty when addressing issue #2661.
The other benefit of retaining the color index (which we didn't
previously do for ISO/ITU colors) is that it ensures that the colors are
updated correctly when the color scheme is changed.
## References
* This is another step towards fixing the conpty narrowing bugs in issue
#2661.
* This is technically a fix for issue #5384, but that won't be apparent
until #2661 is complete.
## PR Checklist
* [x] Closes #1223
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already.
## Detailed Description of the Pull Request / Additional comments
The first part of this PR was the introduction of a new `ColorType` in
the `TextColor` class. Instead of just the one `IsIndex` type, there is
now an `IsIndex16` and an `IsIndex256`. `IsIndex16` covers the eight
original ANSI colors set with `SGR 3x` and `SGR 4x`, as well as the
brighter aixterm variants set with `SGR 9x` and `SGR 10x`. `IsIndex256`
covers the 256 ISO/ITU indexed colors set with `SGR 38;5` and `SGR
48;5`.
There are two reasons for this distinction. The first is that the ANSI
colors have the potential to be brightened by the `SGR 1` bold
attribute, while the ISO/ITO color do not. The second reason is that
when forwarding an attributes through conpty, we want to try and
preserve the original SGR sequence that generated each color (to the
extent that that is possible). By having the two separate types, we can
map the `IsIndex16` colors back to ANSI/aixterm values, and `IsIndex256`
to the ISO/ITU sequences.
In addition to the VT colors, we also have to deal with the legacy
colors set by the Windows console APIs, but we don't really need a
separate type for those. It seemed most appropriate to me to store them
as `IsIndex256` colors, since it doesn't make sense to have them
brightened by the `SGR 1` attribute (which is what would happen if they
were stored as `IsIndex16`). If a console app wanted a bright color it
would have selected one, so we shouldn't be messing with that choice.
The second part of the PR was the unification of the two color tables.
Originally we had a 16 color table for the legacy colors, and a separate
table for the 256 ISO/ITU colors. These have now been merged into one,
so color table lookups no longer need to decide which of the two tables
they should be referencing. I've also updated all the methods that took
a color table as a parameter to use a `basic_string_view` instead of
separate pointer and length variables, which I think makes them a lot
easier and safer to work with.
With this new architecture in place, I could now update the
`AdaptDispatch` SGR implementation to store the ISO/ITU indexed colors
as `IsIndex256` values, where before they were mapped to RGB values
(which prevented them reflecting any color scheme changes). I could also
update the `TerminalDispatch` implementation to differentiate between
the two index types, so that the `SGR 1` brightening would only be
applied to the ANSI colors.
I've also done a bit of code refactoring to try and minimise any direct
access to the color tables, getting rid of a lot of places that were
copying tables with `memmove` operations. I'm hoping this will make it
easier for us to update the code in the future if we want to reorder the
table entries (which is likely a requirement for unifying the
`AdaptDispatch` and `TerminalDispatch` implementations).
## Validation Steps Performed
For testing, I've just updated the existing unit tests to account for
the API changes. The `TextColorTests` required an extra parameter
specifying the index type when setting an index. And the `AdapterTest`
and `ScreenBufferTests` required the use of the new `SetIndexedXXX`
methods in order to be explicit about the index type, instead of relying
on the `TextAttribute` constructor and the old `SetForeground` and
`SetBackground` methods which didn't have a way to differentiate index
types.
I've manually tested the various console APIs
(`SetConsoleTextAttribute`, `ReadConsoleOutputAttribute`, and
`ReadConsoleOutput`), to make sure they are still setting and reading
the attributes as well as they used to. And I've tested the
`SetConsoleScreenBufferInfoEx` and `GetConsoleScreenBufferInfoEx` APIs
to make sure they can read and write the color table correctly. I've
also tested the color table in the properties dialog, made sure it was
saved and restored from the registry correctly, and similarly saved and
restored from a shortcut link.
Note that there are still a bunch of issues with the color table APIs,
but no new problems have been introduced by the changes in this PR, as
far as I could tell.
I've also done a bunch of manual tests of `OSC 4` to make sure it's
updating all the colors correctly (at least in conhost), and confirmed
that the test case in issue #1223 now works as expected.
2020-05-28 00:34:45 +02:00
for ( size_t i = 0 ; i < std : : size ( pStateInfo - > ColorTable ) ; i + + )
{
SetColorTableEntry ( i , pStateInfo - > ColorTable [ i ] ) ;
}
2019-05-03 00:29:04 +02:00
_uCodePage = pStateInfo - > CodePage ;
_bWrapText = ! ! pStateInfo - > fWrapText ;
_fFilterOnPaste = pStateInfo - > fFilterOnPaste ;
_fCtrlKeyShortcutsDisabled = pStateInfo - > fCtrlKeyShortcutsDisabled ;
_bLineSelection = pStateInfo - > fLineSelection ;
_bWindowAlpha = pStateInfo - > bWindowTransparency ;
_CursorColor = pStateInfo - > CursorColor ;
_CursorType = static_cast < CursorType > ( pStateInfo - > CursorType ) ;
_fInterceptCopyPaste = pStateInfo - > InterceptCopyPaste ;
_DefaultForeground = pStateInfo - > DefaultForeground ;
_DefaultBackground = pStateInfo - > DefaultBackground ;
_TerminalScrolling = pStateInfo - > TerminalScrolling ;
}
// Method Description:
// - Create a CONSOLE_STATE_INFO with the current state of this settings structure.
// Arguments:
// - <none>
// Return Value:
// - a CONSOLE_STATE_INFO with the current state of this settings structure.
CONSOLE_STATE_INFO Settings : : CreateConsoleStateInfo ( ) const
{
2019-06-11 22:27:09 +02:00
CONSOLE_STATE_INFO csi = { 0 } ;
2019-05-03 00:29:04 +02:00
csi . ScreenAttributes = _wFillAttribute ;
csi . PopupAttributes = _wPopupFillAttribute ;
csi . ScreenBufferSize = _dwScreenBufferSize ;
csi . WindowSize = _dwWindowSize ;
csi . WindowPosX = ( SHORT ) _dwWindowOrigin . X ;
csi . WindowPosY = ( SHORT ) _dwWindowOrigin . Y ;
csi . FontSize = _dwFontSize ;
csi . FontFamily = _uFontFamily ;
csi . FontWeight = _uFontWeight ;
StringCchCopyW ( csi . FaceName , ARRAYSIZE ( _FaceName ) , _FaceName ) ;
csi . CursorSize = _uCursorSize ;
csi . FullScreen = _bFullScreen ;
csi . QuickEdit = _bQuickEdit ;
csi . AutoPosition = _bAutoPosition ;
csi . InsertMode = _bInsertMode ;
csi . HistoryNoDup = _bHistoryNoDup ;
csi . HistoryBufferSize = _uHistoryBufferSize ;
csi . NumberOfHistoryBuffers = _uNumberOfHistoryBuffers ;
Fix SGR indexed colors to distinguish Indexed256 color (and more) (#5834)
This PR introduces a new `ColorType` to allow us to distinguish between
`SGR` indexed colors from the 16 color table, the lower half of which
can be brightened, and the ISO/ITU indexed colors from the 256 color
table, which have a fixed brightness. Retaining the distinction between
these two types will enable us to forward the correct `SGR` sequences to
conpty when addressing issue #2661.
The other benefit of retaining the color index (which we didn't
previously do for ISO/ITU colors) is that it ensures that the colors are
updated correctly when the color scheme is changed.
## References
* This is another step towards fixing the conpty narrowing bugs in issue
#2661.
* This is technically a fix for issue #5384, but that won't be apparent
until #2661 is complete.
## PR Checklist
* [x] Closes #1223
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already.
## Detailed Description of the Pull Request / Additional comments
The first part of this PR was the introduction of a new `ColorType` in
the `TextColor` class. Instead of just the one `IsIndex` type, there is
now an `IsIndex16` and an `IsIndex256`. `IsIndex16` covers the eight
original ANSI colors set with `SGR 3x` and `SGR 4x`, as well as the
brighter aixterm variants set with `SGR 9x` and `SGR 10x`. `IsIndex256`
covers the 256 ISO/ITU indexed colors set with `SGR 38;5` and `SGR
48;5`.
There are two reasons for this distinction. The first is that the ANSI
colors have the potential to be brightened by the `SGR 1` bold
attribute, while the ISO/ITO color do not. The second reason is that
when forwarding an attributes through conpty, we want to try and
preserve the original SGR sequence that generated each color (to the
extent that that is possible). By having the two separate types, we can
map the `IsIndex16` colors back to ANSI/aixterm values, and `IsIndex256`
to the ISO/ITU sequences.
In addition to the VT colors, we also have to deal with the legacy
colors set by the Windows console APIs, but we don't really need a
separate type for those. It seemed most appropriate to me to store them
as `IsIndex256` colors, since it doesn't make sense to have them
brightened by the `SGR 1` attribute (which is what would happen if they
were stored as `IsIndex16`). If a console app wanted a bright color it
would have selected one, so we shouldn't be messing with that choice.
The second part of the PR was the unification of the two color tables.
Originally we had a 16 color table for the legacy colors, and a separate
table for the 256 ISO/ITU colors. These have now been merged into one,
so color table lookups no longer need to decide which of the two tables
they should be referencing. I've also updated all the methods that took
a color table as a parameter to use a `basic_string_view` instead of
separate pointer and length variables, which I think makes them a lot
easier and safer to work with.
With this new architecture in place, I could now update the
`AdaptDispatch` SGR implementation to store the ISO/ITU indexed colors
as `IsIndex256` values, where before they were mapped to RGB values
(which prevented them reflecting any color scheme changes). I could also
update the `TerminalDispatch` implementation to differentiate between
the two index types, so that the `SGR 1` brightening would only be
applied to the ANSI colors.
I've also done a bit of code refactoring to try and minimise any direct
access to the color tables, getting rid of a lot of places that were
copying tables with `memmove` operations. I'm hoping this will make it
easier for us to update the code in the future if we want to reorder the
table entries (which is likely a requirement for unifying the
`AdaptDispatch` and `TerminalDispatch` implementations).
## Validation Steps Performed
For testing, I've just updated the existing unit tests to account for
the API changes. The `TextColorTests` required an extra parameter
specifying the index type when setting an index. And the `AdapterTest`
and `ScreenBufferTests` required the use of the new `SetIndexedXXX`
methods in order to be explicit about the index type, instead of relying
on the `TextAttribute` constructor and the old `SetForeground` and
`SetBackground` methods which didn't have a way to differentiate index
types.
I've manually tested the various console APIs
(`SetConsoleTextAttribute`, `ReadConsoleOutputAttribute`, and
`ReadConsoleOutput`), to make sure they are still setting and reading
the attributes as well as they used to. And I've tested the
`SetConsoleScreenBufferInfoEx` and `GetConsoleScreenBufferInfoEx` APIs
to make sure they can read and write the color table correctly. I've
also tested the color table in the properties dialog, made sure it was
saved and restored from the registry correctly, and similarly saved and
restored from a shortcut link.
Note that there are still a bunch of issues with the color table APIs,
but no new problems have been introduced by the changes in this PR, as
far as I could tell.
I've also done a bunch of manual tests of `OSC 4` to make sure it's
updating all the colors correctly (at least in conhost), and confirmed
that the test case in issue #1223 now works as expected.
2020-05-28 00:34:45 +02:00
for ( size_t i = 0 ; i < std : : size ( csi . ColorTable ) ; i + + )
{
csi . ColorTable [ i ] = GetColorTableEntry ( i ) ;
}
2019-05-03 00:29:04 +02:00
csi . CodePage = _uCodePage ;
csi . fWrapText = ! ! _bWrapText ;
csi . fFilterOnPaste = _fFilterOnPaste ;
csi . fCtrlKeyShortcutsDisabled = _fCtrlKeyShortcutsDisabled ;
csi . fLineSelection = _bLineSelection ;
csi . bWindowTransparency = _bWindowAlpha ;
csi . CursorColor = _CursorColor ;
csi . CursorType = static_cast < unsigned int > ( _CursorType ) ;
csi . InterceptCopyPaste = _fInterceptCopyPaste ;
csi . DefaultForeground = _DefaultForeground ;
csi . DefaultBackground = _DefaultBackground ;
csi . TerminalScrolling = _TerminalScrolling ;
return csi ;
}
void Settings : : Validate ( )
{
// If we were explicitly given a size in pixels from the startup info, divide by the font to turn it into characters.
// See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331%28v=vs.85%29.aspx
if ( WI_IsFlagSet ( _dwStartupFlags , STARTF_USESIZE ) )
{
// TODO: FIX
//// Get the font that we're going to use to convert pixels to characters.
//DWORD const dwFontIndexWant = FindCreateFont(_uFontFamily,
// _FaceName,
// _dwFontSize,
// _uFontWeight,
// _uCodePage);
//_dwWindowSize.X /= g_pfiFontInfo[dwFontIndexWant].Size.X;
//_dwWindowSize.Y /= g_pfiFontInfo[dwFontIndexWant].Size.Y;
}
// minimum screen buffer size 1x1
_dwScreenBufferSize . X = std : : max ( _dwScreenBufferSize . X , 1 i16 ) ;
_dwScreenBufferSize . Y = std : : max ( _dwScreenBufferSize . Y , 1 i16 ) ;
// minimum window size size 1x1
_dwWindowSize . X = std : : max ( _dwWindowSize . X , 1 i16 ) ;
_dwWindowSize . Y = std : : max ( _dwWindowSize . Y , 1 i16 ) ;
// if buffer size is less than window size, increase buffer size to meet window size
_dwScreenBufferSize . X = std : : max ( _dwWindowSize . X , _dwScreenBufferSize . X ) ;
_dwScreenBufferSize . Y = std : : max ( _dwWindowSize . Y , _dwScreenBufferSize . Y ) ;
// ensure that the window alpha value is not below the minimum. (no invisible windows)
// if it's below minimum, just set it to the opaque value
if ( _bWindowAlpha < MIN_WINDOW_OPACITY )
{
_bWindowAlpha = BYTE_MAX ;
}
// If text wrapping is on, ensure that the window width is the same as the buffer width.
if ( _bWrapText )
{
_dwWindowSize . X = _dwScreenBufferSize . X ;
}
// Ensure that our fill attributes only contain colors and not any box drawing or invert attributes.
WI_ClearAllFlags ( _wFillAttribute , ~ ( FG_ATTRS | BG_ATTRS ) ) ;
WI_ClearAllFlags ( _wPopupFillAttribute , ~ ( FG_ATTRS | BG_ATTRS ) ) ;
2019-09-24 03:35:53 +02:00
// If the extended color options are set to invalid values (all the same color), reset them.
if ( _CursorColor ! = Cursor : : s_InvertCursorColor & & _CursorColor = = _DefaultBackground )
{
_CursorColor = Cursor : : s_InvertCursorColor ;
}
if ( _DefaultForeground ! = INVALID_COLOR & & _DefaultForeground = = _DefaultBackground )
{
// INVALID_COLOR is used as an "unset" sentinel in future attribute functions.
_DefaultForeground = _DefaultBackground = INVALID_COLOR ;
// If the damaged settings _further_ propagated to the default fill attribute, fix it.
if ( _wFillAttribute = = 0 )
{
// These attributes were taken from the Settings ctor and equal "gray on black"
_wFillAttribute = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE ;
}
}
Improve conpty rendering of default colors in legacy apps (#6698)
Essentially what this does is map the default legacy foreground and
background attributes (typically white on black) to the `IsDefault`
color type in the `TextColor` class. As a result, we can now initialize
the buffer for "legacy" shells (like PowerShell and cmd.exe) with
default colors, instead of white on black. This fixes the startup
rendering in conpty clients, which expect an initial default background
color. It also makes these colors update appropriately when the default
palette values change.
One complication in getting this to work, is that the console permits
users to change which color indices are designated as defaults, so we
can't assume they'll always be white on black. This means that the
legacy-to-`TextAttribute` conversion will need access to those default
values.
Unfortunately the defaults are stored in the conhost `Settings` class
(the `_wFillAttribute` field), which isn't easily accessible to all the
code that needs to construct a `TextAttribute` from a legacy value. The
`OutputCellIterator` is particularly problematic, because some iterator
types need to generate a new `TextAttribute` on every iteration.
So after trying a couple of different approaches, I decided that the
least worst option would be to add a pair of static properties for the
legacy defaults in the `TextAttribute` class itself, then refresh those
values from the `Settings` class whenever the defaults changed (this
only happens on startup, or when the conhost _Properties_ dialog is
edited).
And once the `TextAttribute` class had access to those defaults, it was
fairly easy to adapt the constructor to handle the conversion of default
values to the `IsDefault` color type. I could also then simplify the
`TextAttribute::GetLegacyAttributes` method which does the reverse
mapping, and which previously required the default values to be passed
in as a parameter
VALIDATION
I had to make one small change to the `TestRoundtripExhaustive` unit
test which assumed that all legacy attributes would convert to legacy
color types, which is no longer the case, but otherwise all the existing
tests passed as is. I added a new unit test verifying that the default
legacy attributes correctly mapped to default color types, and the
default color types were mapped back to the correct legacy attributes.
I've manually confirmed that this fixed the issue raised in #5952,
namely that the conhost screen is cleared with the correct default
colors, and also that it is correctly refreshed when changing the
palette from the properties dialog. And I've combined this PR with
#6506, and confirmed that the PowerShell and the cmd shell renderings in
Windows Terminal are at least improved, if not always perfect.
This is a prerequisite for PR #6506
Closes #5952
2020-07-01 20:08:30 +02:00
// At this point the default fill attributes are fully initialized
// so we can pass on the final colors to the TextAttribute class.
TextAttribute : : SetLegacyDefaultAttributes ( _wFillAttribute ) ;
2019-05-03 00:29:04 +02:00
FAIL_FAST_IF ( ! ( _dwWindowSize . X > 0 ) ) ;
FAIL_FAST_IF ( ! ( _dwWindowSize . Y > 0 ) ) ;
FAIL_FAST_IF ( ! ( _dwScreenBufferSize . X > 0 ) ) ;
FAIL_FAST_IF ( ! ( _dwScreenBufferSize . Y > 0 ) ) ;
}
DWORD Settings : : GetVirtTermLevel ( ) const
{
return _dwVirtTermLevel ;
}
void Settings : : SetVirtTermLevel ( const DWORD dwVirtTermLevel )
{
_dwVirtTermLevel = dwVirtTermLevel ;
}
bool Settings : : IsAltF4CloseAllowed ( ) const
{
return _fAllowAltF4Close ;
}
void Settings : : SetAltF4CloseAllowed ( const bool fAllowAltF4Close )
{
_fAllowAltF4Close = fAllowAltF4Close ;
}
bool Settings : : IsReturnOnNewlineAutomatic ( ) const
{
return _fAutoReturnOnNewline ;
}
void Settings : : SetAutomaticReturnOnNewline ( const bool fAutoReturnOnNewline )
{
_fAutoReturnOnNewline = fAutoReturnOnNewline ;
}
bool Settings : : IsGridRenderingAllowedWorldwide ( ) const
{
return _fRenderGridWorldwide ;
}
void Settings : : SetGridRenderingAllowedWorldwide ( const bool fGridRenderingAllowed )
{
// Only trigger a notification and update the status if something has changed.
if ( _fRenderGridWorldwide ! = fGridRenderingAllowed )
{
_fRenderGridWorldwide = fGridRenderingAllowed ;
if ( ServiceLocator : : LocateGlobals ( ) . pRender ! = nullptr )
{
ServiceLocator : : LocateGlobals ( ) . pRender - > TriggerRedrawAll ( ) ;
}
}
}
Add support for the DECSCNM screen mode (#3817)
## Summary of the Pull Request
This adds support for the [`DECSCNM`](https://vt100.net/docs/vt510-rm/DECSCNM.html) private mode escape sequence, which toggles the display between normal and reverse screen modes. When reversed, the background and foreground colors are switched. Tested manually, with [Vttest](https://invisible-island.net/vttest/), and with some new unit tests.
## References
This also fixes issue #72 for the most part, although if you toggle the mode too fast, there is no discernible flash.
## PR Checklist
* [x] Closes #3773
* [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
* [ ] 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: #xxx
## Detailed Description of the Pull Request / Additional comments
I've implemented this as a new flag in the `Settings` class, along with updates to the `LookupForegroundColor` and `LookupBackgroundColor` methods, to switch the returned foreground and background colors when that flag is set.
It also required a new private API in the `ConGetSet` interface to toggle the setting. And that API is then called from the `AdaptDispatch` class when the screen mode escape sequence is received.
The last thing needed was to add a step to the `HardReset` method, to reset the mode back to normal, which is one of the `RIS` requirements.
Note that this does currently work in the Windows Terminal, but once #2661 is implemented that may no longer be the case. It might become necessary to let the mode change sequences pass through conpty, and handle the color reversing on the client side.
## Validation Steps Performed
I've added a state machine test to make sure the escape sequence is dispatched correctly, and a screen buffer test to confirm that the mode change does alter the interpretation of colors as expected.
I've also confirmed that the various "light background" tests in Vttest now display correctly, and that the `tput flash` command (in a bash shell) does actually cause the screen to flash.
2020-01-22 23:29:50 +01:00
bool Settings : : IsScreenReversed ( ) const
{
return _fScreenReversed ;
}
void Settings : : SetScreenReversed ( const bool fScreenReversed )
{
_fScreenReversed = fScreenReversed ;
}
2019-05-03 00:29:04 +02:00
bool Settings : : GetFilterOnPaste ( ) const
{
return _fFilterOnPaste ;
}
void Settings : : SetFilterOnPaste ( const bool fFilterOnPaste )
{
_fFilterOnPaste = fFilterOnPaste ;
}
Allow FontInfo{,Base,Desired} to store a font name > 32 wch (#3107)
We now truncate the font name as it goes out to GDI APIs, in console API
servicing, and in the propsheet.
I attempted to defer truncating the font to as far up the stack as
possible, so as to make FontInfo usable for the broadest set of cases.
There were a couple questions that came up: I know that `Settings` gets
memset (memsat?) by the registry deserializer, and perhaps that's
another place for us to tackle. Right now, this pull request enables
fonts whose names are >= 32 characters _in Windows Terminal only_, but
the underpinnings are there for conhost as well. We'd need to explicitly
break at the API, or perhaps return a failure or log something to
telemetry.
* Should we log truncation at the API boundary to telemetry?
-> Later; followup filed (#3123)
* Should we fix Settings here, or later?
-> Later; followup filed (#3123)
* `TrueTypeFontList` is built out of things in winconp, the private
console header. Concern about interop structures.
-> Not used for interop, followup filed to clean it up (#3123)
* Is `unsigned int` right for codepage? For width?
-> Yes: codepage became UINT (from WORD) when we moved from Win16 to
Win32
This commit also includes a workaround for #3170. Growing
CONSOLE_INFORMATION made us lose the struct layout lottery during
release builds, and this was an expedient fix.
Closes #602.
Related to #3123.
2019-10-15 06:23:45 +02:00
const std : : wstring_view Settings : : GetLaunchFaceName ( ) const
2019-05-03 00:29:04 +02:00
{
return _LaunchFaceName ;
}
Allow FontInfo{,Base,Desired} to store a font name > 32 wch (#3107)
We now truncate the font name as it goes out to GDI APIs, in console API
servicing, and in the propsheet.
I attempted to defer truncating the font to as far up the stack as
possible, so as to make FontInfo usable for the broadest set of cases.
There were a couple questions that came up: I know that `Settings` gets
memset (memsat?) by the registry deserializer, and perhaps that's
another place for us to tackle. Right now, this pull request enables
fonts whose names are >= 32 characters _in Windows Terminal only_, but
the underpinnings are there for conhost as well. We'd need to explicitly
break at the API, or perhaps return a failure or log something to
telemetry.
* Should we log truncation at the API boundary to telemetry?
-> Later; followup filed (#3123)
* Should we fix Settings here, or later?
-> Later; followup filed (#3123)
* `TrueTypeFontList` is built out of things in winconp, the private
console header. Concern about interop structures.
-> Not used for interop, followup filed to clean it up (#3123)
* Is `unsigned int` right for codepage? For width?
-> Yes: codepage became UINT (from WORD) when we moved from Win16 to
Win32
This commit also includes a workaround for #3170. Growing
CONSOLE_INFORMATION made us lose the struct layout lottery during
release builds, and this was an expedient fix.
Closes #602.
Related to #3123.
2019-10-15 06:23:45 +02:00
void Settings : : SetLaunchFaceName ( const std : : wstring_view launchFaceName )
2019-05-03 00:29:04 +02:00
{
Allow FontInfo{,Base,Desired} to store a font name > 32 wch (#3107)
We now truncate the font name as it goes out to GDI APIs, in console API
servicing, and in the propsheet.
I attempted to defer truncating the font to as far up the stack as
possible, so as to make FontInfo usable for the broadest set of cases.
There were a couple questions that came up: I know that `Settings` gets
memset (memsat?) by the registry deserializer, and perhaps that's
another place for us to tackle. Right now, this pull request enables
fonts whose names are >= 32 characters _in Windows Terminal only_, but
the underpinnings are there for conhost as well. We'd need to explicitly
break at the API, or perhaps return a failure or log something to
telemetry.
* Should we log truncation at the API boundary to telemetry?
-> Later; followup filed (#3123)
* Should we fix Settings here, or later?
-> Later; followup filed (#3123)
* `TrueTypeFontList` is built out of things in winconp, the private
console header. Concern about interop structures.
-> Not used for interop, followup filed to clean it up (#3123)
* Is `unsigned int` right for codepage? For width?
-> Yes: codepage became UINT (from WORD) when we moved from Win16 to
Win32
This commit also includes a workaround for #3170. Growing
CONSOLE_INFORMATION made us lose the struct layout lottery during
release builds, and this was an expedient fix.
Closes #602.
Related to #3123.
2019-10-15 06:23:45 +02:00
_LaunchFaceName = launchFaceName ;
2019-05-03 00:29:04 +02:00
}
UINT Settings : : GetCodePage ( ) const
{
return _uCodePage ;
}
void Settings : : SetCodePage ( const UINT uCodePage )
{
_uCodePage = uCodePage ;
}
UINT Settings : : GetScrollScale ( ) const
{
return _uScrollScale ;
}
void Settings : : SetScrollScale ( const UINT uScrollScale )
{
_uScrollScale = uScrollScale ;
}
bool Settings : : GetTrimLeadingZeros ( ) const
{
return _fTrimLeadingZeros ;
}
void Settings : : SetTrimLeadingZeros ( const bool fTrimLeadingZeros )
{
_fTrimLeadingZeros = fTrimLeadingZeros ;
}
bool Settings : : GetEnableColorSelection ( ) const
{
return _fEnableColorSelection ;
}
void Settings : : SetEnableColorSelection ( const bool fEnableColorSelection )
{
_fEnableColorSelection = fEnableColorSelection ;
}
bool Settings : : GetLineSelection ( ) const
{
return _bLineSelection ;
}
void Settings : : SetLineSelection ( const bool bLineSelection )
{
_bLineSelection = bLineSelection ;
}
2019-06-11 22:27:09 +02:00
bool Settings : : GetWrapText ( ) const
2019-05-03 00:29:04 +02:00
{
return _bWrapText ;
}
2019-06-11 22:27:09 +02:00
void Settings : : SetWrapText ( const bool bWrapText )
2019-05-03 00:29:04 +02:00
{
_bWrapText = bWrapText ;
}
2019-06-11 22:27:09 +02:00
bool Settings : : GetCtrlKeyShortcutsDisabled ( ) const
2019-05-03 00:29:04 +02:00
{
return _fCtrlKeyShortcutsDisabled ;
}
2019-06-11 22:27:09 +02:00
void Settings : : SetCtrlKeyShortcutsDisabled ( const bool fCtrlKeyShortcutsDisabled )
2019-05-03 00:29:04 +02:00
{
_fCtrlKeyShortcutsDisabled = fCtrlKeyShortcutsDisabled ;
}
BYTE Settings : : GetWindowAlpha ( ) const
{
return _bWindowAlpha ;
}
void Settings : : SetWindowAlpha ( const BYTE bWindowAlpha )
{
// if we're out of bounds, set it to 100% opacity so it appears as if nothing happened.
2019-06-11 22:27:09 +02:00
_bWindowAlpha = ( bWindowAlpha < MIN_WINDOW_OPACITY ) ? BYTE_MAX : bWindowAlpha ;
2019-05-03 00:29:04 +02:00
}
DWORD Settings : : GetHotKey ( ) const
{
return _dwHotKey ;
}
void Settings : : SetHotKey ( const DWORD dwHotKey )
{
_dwHotKey = dwHotKey ;
}
DWORD Settings : : GetStartupFlags ( ) const
{
return _dwStartupFlags ;
}
void Settings : : SetStartupFlags ( const DWORD dwStartupFlags )
{
_dwStartupFlags = dwStartupFlags ;
}
WORD Settings : : GetFillAttribute ( ) const
{
return _wFillAttribute ;
}
void Settings : : SetFillAttribute ( const WORD wFillAttribute )
{
_wFillAttribute = wFillAttribute ;
// Do not allow the default fill attribute to use any attrs other than fg/bg colors.
// This prevents us from accidentally inverting everything or suddenly drawing lines
// everywhere by default.
WI_ClearAllFlags ( _wFillAttribute , ~ ( FG_ATTRS | BG_ATTRS ) ) ;
}
WORD Settings : : GetPopupFillAttribute ( ) const
{
return _wPopupFillAttribute ;
}
void Settings : : SetPopupFillAttribute ( const WORD wPopupFillAttribute )
{
_wPopupFillAttribute = wPopupFillAttribute ;
// Do not allow the default popup fill attribute to use any attrs other than fg/bg colors.
// This prevents us from accidentally inverting everything or suddenly drawing lines
2020-02-10 21:40:01 +01:00
// everywhere by default.
2019-05-03 00:29:04 +02:00
WI_ClearAllFlags ( _wPopupFillAttribute , ~ ( FG_ATTRS | BG_ATTRS ) ) ;
}
WORD Settings : : GetShowWindow ( ) const
{
return _wShowWindow ;
}
void Settings : : SetShowWindow ( const WORD wShowWindow )
{
_wShowWindow = wShowWindow ;
}
WORD Settings : : GetReserved ( ) const
{
return _wReserved ;
}
void Settings : : SetReserved ( const WORD wReserved )
{
_wReserved = wReserved ;
}
COORD Settings : : GetScreenBufferSize ( ) const
{
return _dwScreenBufferSize ;
}
void Settings : : SetScreenBufferSize ( const COORD dwScreenBufferSize )
{
_dwScreenBufferSize = dwScreenBufferSize ;
}
COORD Settings : : GetWindowSize ( ) const
{
return _dwWindowSize ;
}
void Settings : : SetWindowSize ( const COORD dwWindowSize )
{
_dwWindowSize = dwWindowSize ;
}
bool Settings : : IsWindowSizePixelsValid ( ) const
{
return _fUseWindowSizePixels ;
}
COORD Settings : : GetWindowSizePixels ( ) const
{
return _dwWindowSizePixels ;
}
void Settings : : SetWindowSizePixels ( const COORD dwWindowSizePixels )
{
_dwWindowSizePixels = dwWindowSizePixels ;
}
COORD Settings : : GetWindowOrigin ( ) const
{
return _dwWindowOrigin ;
}
void Settings : : SetWindowOrigin ( const COORD dwWindowOrigin )
{
_dwWindowOrigin = dwWindowOrigin ;
}
DWORD Settings : : GetFont ( ) const
{
return _nFont ;
}
void Settings : : SetFont ( const DWORD nFont )
{
_nFont = nFont ;
}
COORD Settings : : GetFontSize ( ) const
{
return _dwFontSize ;
}
void Settings : : SetFontSize ( const COORD dwFontSize )
{
_dwFontSize = dwFontSize ;
}
UINT Settings : : GetFontFamily ( ) const
{
return _uFontFamily ;
}
void Settings : : SetFontFamily ( const UINT uFontFamily )
{
_uFontFamily = uFontFamily ;
}
UINT Settings : : GetFontWeight ( ) const
{
return _uFontWeight ;
}
void Settings : : SetFontWeight ( const UINT uFontWeight )
{
_uFontWeight = uFontWeight ;
}
const WCHAR * const Settings : : GetFaceName ( ) const
{
return _FaceName ;
}
Allow FontInfo{,Base,Desired} to store a font name > 32 wch (#3107)
We now truncate the font name as it goes out to GDI APIs, in console API
servicing, and in the propsheet.
I attempted to defer truncating the font to as far up the stack as
possible, so as to make FontInfo usable for the broadest set of cases.
There were a couple questions that came up: I know that `Settings` gets
memset (memsat?) by the registry deserializer, and perhaps that's
another place for us to tackle. Right now, this pull request enables
fonts whose names are >= 32 characters _in Windows Terminal only_, but
the underpinnings are there for conhost as well. We'd need to explicitly
break at the API, or perhaps return a failure or log something to
telemetry.
* Should we log truncation at the API boundary to telemetry?
-> Later; followup filed (#3123)
* Should we fix Settings here, or later?
-> Later; followup filed (#3123)
* `TrueTypeFontList` is built out of things in winconp, the private
console header. Concern about interop structures.
-> Not used for interop, followup filed to clean it up (#3123)
* Is `unsigned int` right for codepage? For width?
-> Yes: codepage became UINT (from WORD) when we moved from Win16 to
Win32
This commit also includes a workaround for #3170. Growing
CONSOLE_INFORMATION made us lose the struct layout lottery during
release builds, and this was an expedient fix.
Closes #602.
Related to #3123.
2019-10-15 06:23:45 +02:00
void Settings : : SetFaceName ( const std : : wstring_view faceName )
2019-05-03 00:29:04 +02:00
{
Allow FontInfo{,Base,Desired} to store a font name > 32 wch (#3107)
We now truncate the font name as it goes out to GDI APIs, in console API
servicing, and in the propsheet.
I attempted to defer truncating the font to as far up the stack as
possible, so as to make FontInfo usable for the broadest set of cases.
There were a couple questions that came up: I know that `Settings` gets
memset (memsat?) by the registry deserializer, and perhaps that's
another place for us to tackle. Right now, this pull request enables
fonts whose names are >= 32 characters _in Windows Terminal only_, but
the underpinnings are there for conhost as well. We'd need to explicitly
break at the API, or perhaps return a failure or log something to
telemetry.
* Should we log truncation at the API boundary to telemetry?
-> Later; followup filed (#3123)
* Should we fix Settings here, or later?
-> Later; followup filed (#3123)
* `TrueTypeFontList` is built out of things in winconp, the private
console header. Concern about interop structures.
-> Not used for interop, followup filed to clean it up (#3123)
* Is `unsigned int` right for codepage? For width?
-> Yes: codepage became UINT (from WORD) when we moved from Win16 to
Win32
This commit also includes a workaround for #3170. Growing
CONSOLE_INFORMATION made us lose the struct layout lottery during
release builds, and this was an expedient fix.
Closes #602.
Related to #3123.
2019-10-15 06:23:45 +02:00
auto extent = std : : min < size_t > ( faceName . size ( ) , ARRAYSIZE ( _FaceName ) ) ;
StringCchCopyW ( _FaceName , extent , faceName . data ( ) ) ;
2019-05-03 00:29:04 +02:00
}
UINT Settings : : GetCursorSize ( ) const
{
return _uCursorSize ;
}
void Settings : : SetCursorSize ( const UINT uCursorSize )
{
_uCursorSize = uCursorSize ;
}
bool Settings : : GetFullScreen ( ) const
{
return _bFullScreen ;
}
void Settings : : SetFullScreen ( const bool bFullScreen )
{
_bFullScreen = bFullScreen ;
}
bool Settings : : GetQuickEdit ( ) const
{
return _bQuickEdit ;
}
void Settings : : SetQuickEdit ( const bool bQuickEdit )
{
_bQuickEdit = bQuickEdit ;
}
bool Settings : : GetInsertMode ( ) const
{
return _bInsertMode ;
}
void Settings : : SetInsertMode ( const bool bInsertMode )
{
_bInsertMode = bInsertMode ;
}
bool Settings : : GetAutoPosition ( ) const
{
return _bAutoPosition ;
}
void Settings : : SetAutoPosition ( const bool bAutoPosition )
{
_bAutoPosition = bAutoPosition ;
}
UINT Settings : : GetHistoryBufferSize ( ) const
{
return _uHistoryBufferSize ;
}
void Settings : : SetHistoryBufferSize ( const UINT uHistoryBufferSize )
{
_uHistoryBufferSize = uHistoryBufferSize ;
}
UINT Settings : : GetNumberOfHistoryBuffers ( ) const
{
return _uNumberOfHistoryBuffers ;
}
void Settings : : SetNumberOfHistoryBuffers ( const UINT uNumberOfHistoryBuffers )
{
_uNumberOfHistoryBuffers = uNumberOfHistoryBuffers ;
}
bool Settings : : GetHistoryNoDup ( ) const
{
return _bHistoryNoDup ;
}
void Settings : : SetHistoryNoDup ( const bool bHistoryNoDup )
{
_bHistoryNoDup = bHistoryNoDup ;
}
void Settings : : SetColorTableEntry ( const size_t index , const COLORREF ColorValue )
{
Fix SGR indexed colors to distinguish Indexed256 color (and more) (#5834)
This PR introduces a new `ColorType` to allow us to distinguish between
`SGR` indexed colors from the 16 color table, the lower half of which
can be brightened, and the ISO/ITU indexed colors from the 256 color
table, which have a fixed brightness. Retaining the distinction between
these two types will enable us to forward the correct `SGR` sequences to
conpty when addressing issue #2661.
The other benefit of retaining the color index (which we didn't
previously do for ISO/ITU colors) is that it ensures that the colors are
updated correctly when the color scheme is changed.
## References
* This is another step towards fixing the conpty narrowing bugs in issue
#2661.
* This is technically a fix for issue #5384, but that won't be apparent
until #2661 is complete.
## PR Checklist
* [x] Closes #1223
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already.
## Detailed Description of the Pull Request / Additional comments
The first part of this PR was the introduction of a new `ColorType` in
the `TextColor` class. Instead of just the one `IsIndex` type, there is
now an `IsIndex16` and an `IsIndex256`. `IsIndex16` covers the eight
original ANSI colors set with `SGR 3x` and `SGR 4x`, as well as the
brighter aixterm variants set with `SGR 9x` and `SGR 10x`. `IsIndex256`
covers the 256 ISO/ITU indexed colors set with `SGR 38;5` and `SGR
48;5`.
There are two reasons for this distinction. The first is that the ANSI
colors have the potential to be brightened by the `SGR 1` bold
attribute, while the ISO/ITO color do not. The second reason is that
when forwarding an attributes through conpty, we want to try and
preserve the original SGR sequence that generated each color (to the
extent that that is possible). By having the two separate types, we can
map the `IsIndex16` colors back to ANSI/aixterm values, and `IsIndex256`
to the ISO/ITU sequences.
In addition to the VT colors, we also have to deal with the legacy
colors set by the Windows console APIs, but we don't really need a
separate type for those. It seemed most appropriate to me to store them
as `IsIndex256` colors, since it doesn't make sense to have them
brightened by the `SGR 1` attribute (which is what would happen if they
were stored as `IsIndex16`). If a console app wanted a bright color it
would have selected one, so we shouldn't be messing with that choice.
The second part of the PR was the unification of the two color tables.
Originally we had a 16 color table for the legacy colors, and a separate
table for the 256 ISO/ITU colors. These have now been merged into one,
so color table lookups no longer need to decide which of the two tables
they should be referencing. I've also updated all the methods that took
a color table as a parameter to use a `basic_string_view` instead of
separate pointer and length variables, which I think makes them a lot
easier and safer to work with.
With this new architecture in place, I could now update the
`AdaptDispatch` SGR implementation to store the ISO/ITU indexed colors
as `IsIndex256` values, where before they were mapped to RGB values
(which prevented them reflecting any color scheme changes). I could also
update the `TerminalDispatch` implementation to differentiate between
the two index types, so that the `SGR 1` brightening would only be
applied to the ANSI colors.
I've also done a bit of code refactoring to try and minimise any direct
access to the color tables, getting rid of a lot of places that were
copying tables with `memmove` operations. I'm hoping this will make it
easier for us to update the code in the future if we want to reorder the
table entries (which is likely a requirement for unifying the
`AdaptDispatch` and `TerminalDispatch` implementations).
## Validation Steps Performed
For testing, I've just updated the existing unit tests to account for
the API changes. The `TextColorTests` required an extra parameter
specifying the index type when setting an index. And the `AdapterTest`
and `ScreenBufferTests` required the use of the new `SetIndexedXXX`
methods in order to be explicit about the index type, instead of relying
on the `TextAttribute` constructor and the old `SetForeground` and
`SetBackground` methods which didn't have a way to differentiate index
types.
I've manually tested the various console APIs
(`SetConsoleTextAttribute`, `ReadConsoleOutputAttribute`, and
`ReadConsoleOutput`), to make sure they are still setting and reading
the attributes as well as they used to. And I've tested the
`SetConsoleScreenBufferInfoEx` and `GetConsoleScreenBufferInfoEx` APIs
to make sure they can read and write the color table correctly. I've
also tested the color table in the properties dialog, made sure it was
saved and restored from the registry correctly, and similarly saved and
restored from a shortcut link.
Note that there are still a bunch of issues with the color table APIs,
but no new problems have been introduced by the changes in this PR, as
far as I could tell.
I've also done a bunch of manual tests of `OSC 4` to make sure it's
updating all the colors correctly (at least in conhost), and confirmed
that the test case in issue #1223 now works as expected.
2020-05-28 00:34:45 +02:00
_colorTable . at ( index ) = ColorValue ;
2019-05-03 00:29:04 +02:00
}
bool Settings : : IsStartupTitleIsLinkNameSet ( ) const
{
return WI_IsFlagSet ( _dwStartupFlags , STARTF_TITLEISLINKNAME ) ;
}
bool Settings : : IsFaceNameSet ( ) const
{
return GetFaceName ( ) [ 0 ] ! = ' \0 ' ;
}
void Settings : : UnsetStartupFlag ( const DWORD dwFlagToUnset )
{
_dwStartupFlags & = ~ dwFlagToUnset ;
}
COLORREF Settings : : GetColorTableEntry ( const size_t index ) const
{
Fix SGR indexed colors to distinguish Indexed256 color (and more) (#5834)
This PR introduces a new `ColorType` to allow us to distinguish between
`SGR` indexed colors from the 16 color table, the lower half of which
can be brightened, and the ISO/ITU indexed colors from the 256 color
table, which have a fixed brightness. Retaining the distinction between
these two types will enable us to forward the correct `SGR` sequences to
conpty when addressing issue #2661.
The other benefit of retaining the color index (which we didn't
previously do for ISO/ITU colors) is that it ensures that the colors are
updated correctly when the color scheme is changed.
## References
* This is another step towards fixing the conpty narrowing bugs in issue
#2661.
* This is technically a fix for issue #5384, but that won't be apparent
until #2661 is complete.
## PR Checklist
* [x] Closes #1223
* [x] CLA signed.
* [x] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already.
## Detailed Description of the Pull Request / Additional comments
The first part of this PR was the introduction of a new `ColorType` in
the `TextColor` class. Instead of just the one `IsIndex` type, there is
now an `IsIndex16` and an `IsIndex256`. `IsIndex16` covers the eight
original ANSI colors set with `SGR 3x` and `SGR 4x`, as well as the
brighter aixterm variants set with `SGR 9x` and `SGR 10x`. `IsIndex256`
covers the 256 ISO/ITU indexed colors set with `SGR 38;5` and `SGR
48;5`.
There are two reasons for this distinction. The first is that the ANSI
colors have the potential to be brightened by the `SGR 1` bold
attribute, while the ISO/ITO color do not. The second reason is that
when forwarding an attributes through conpty, we want to try and
preserve the original SGR sequence that generated each color (to the
extent that that is possible). By having the two separate types, we can
map the `IsIndex16` colors back to ANSI/aixterm values, and `IsIndex256`
to the ISO/ITU sequences.
In addition to the VT colors, we also have to deal with the legacy
colors set by the Windows console APIs, but we don't really need a
separate type for those. It seemed most appropriate to me to store them
as `IsIndex256` colors, since it doesn't make sense to have them
brightened by the `SGR 1` attribute (which is what would happen if they
were stored as `IsIndex16`). If a console app wanted a bright color it
would have selected one, so we shouldn't be messing with that choice.
The second part of the PR was the unification of the two color tables.
Originally we had a 16 color table for the legacy colors, and a separate
table for the 256 ISO/ITU colors. These have now been merged into one,
so color table lookups no longer need to decide which of the two tables
they should be referencing. I've also updated all the methods that took
a color table as a parameter to use a `basic_string_view` instead of
separate pointer and length variables, which I think makes them a lot
easier and safer to work with.
With this new architecture in place, I could now update the
`AdaptDispatch` SGR implementation to store the ISO/ITU indexed colors
as `IsIndex256` values, where before they were mapped to RGB values
(which prevented them reflecting any color scheme changes). I could also
update the `TerminalDispatch` implementation to differentiate between
the two index types, so that the `SGR 1` brightening would only be
applied to the ANSI colors.
I've also done a bit of code refactoring to try and minimise any direct
access to the color tables, getting rid of a lot of places that were
copying tables with `memmove` operations. I'm hoping this will make it
easier for us to update the code in the future if we want to reorder the
table entries (which is likely a requirement for unifying the
`AdaptDispatch` and `TerminalDispatch` implementations).
## Validation Steps Performed
For testing, I've just updated the existing unit tests to account for
the API changes. The `TextColorTests` required an extra parameter
specifying the index type when setting an index. And the `AdapterTest`
and `ScreenBufferTests` required the use of the new `SetIndexedXXX`
methods in order to be explicit about the index type, instead of relying
on the `TextAttribute` constructor and the old `SetForeground` and
`SetBackground` methods which didn't have a way to differentiate index
types.
I've manually tested the various console APIs
(`SetConsoleTextAttribute`, `ReadConsoleOutputAttribute`, and
`ReadConsoleOutput`), to make sure they are still setting and reading
the attributes as well as they used to. And I've tested the
`SetConsoleScreenBufferInfoEx` and `GetConsoleScreenBufferInfoEx` APIs
to make sure they can read and write the color table correctly. I've
also tested the color table in the properties dialog, made sure it was
saved and restored from the registry correctly, and similarly saved and
restored from a shortcut link.
Note that there are still a bunch of issues with the color table APIs,
but no new problems have been introduced by the changes in this PR, as
far as I could tell.
I've also done a bunch of manual tests of `OSC 4` to make sure it's
updating all the colors correctly (at least in conhost), and confirmed
that the test case in issue #1223 now works as expected.
2020-05-28 00:34:45 +02:00
return _colorTable . at ( index ) ;
2019-05-03 00:29:04 +02:00
}
COLORREF Settings : : GetCursorColor ( ) const noexcept
{
return _CursorColor ;
}
CursorType Settings : : GetCursorType ( ) const noexcept
{
return _CursorType ;
}
void Settings : : SetCursorColor ( const COLORREF CursorColor ) noexcept
{
_CursorColor = CursorColor ;
}
void Settings : : SetCursorType ( const CursorType cursorType ) noexcept
{
_CursorType = cursorType ;
}
bool Settings : : GetInterceptCopyPaste ( ) const noexcept
{
return _fInterceptCopyPaste ;
}
void Settings : : SetInterceptCopyPaste ( const bool interceptCopyPaste ) noexcept
{
_fInterceptCopyPaste = interceptCopyPaste ;
}
COLORREF Settings : : GetDefaultForegroundColor ( ) const noexcept
{
return _DefaultForeground ;
}
void Settings : : SetDefaultForegroundColor ( const COLORREF defaultForeground ) noexcept
{
_DefaultForeground = defaultForeground ;
}
COLORREF Settings : : GetDefaultBackgroundColor ( ) const noexcept
{
return _DefaultBackground ;
}
void Settings : : SetDefaultBackgroundColor ( const COLORREF defaultBackground ) noexcept
{
_DefaultBackground = defaultBackground ;
}
bool Settings : : IsTerminalScrolling ( ) const noexcept
{
return _TerminalScrolling ;
}
void Settings : : SetTerminalScrolling ( const bool terminalScrollingEnabled ) noexcept
{
_TerminalScrolling = terminalScrollingEnabled ;
}
// Routine Description:
// - Determines whether our primary renderer should be DirectX or GDI.
// - This is based on user preference and velocity hold back state.
// Return Value:
// - True means use DirectX renderer. False means use GDI renderer.
bool Settings : : GetUseDx ( ) const noexcept
{
return _fUseDx ;
}
bool Settings : : GetCopyColor ( ) const noexcept
{
return _fCopyColor ;
}