2019-05-03 00:29:04 +02:00
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
# include "precomp.h"
# include "settings.hpp"
# include "..\interactivity\inc\ServiceLocator.hpp"
# include "../types/inc/utils.hpp"
# 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.
// 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 ;
gsl : : span < COLORREF > tableView = { _ColorTable , gsl : : narrow < ptrdiff_t > ( COLOR_TABLE_SIZE ) } ;
gsl : : span < COLORREF > xtermTableView = { _XtermColorTable , gsl : : narrow < ptrdiff_t > ( XTERM_COLOR_TABLE_SIZE ) } ;
: : Microsoft : : Console : : Utils : : Initialize256ColorTable ( xtermTableView ) ;
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 ;
gsl : : span < COLORREF > tableView = { _ColorTable , gsl : : narrow < ptrdiff_t > ( COLOR_TABLE_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 ;
memmove ( _ColorTable , pStateInfo - > ColorTable , sizeof ( _ColorTable ) ) ;
_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 ;
memmove ( csi . ColorTable , _ColorTable , sizeof ( _ColorTable ) ) ;
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 ;
}
}
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 ( ) ;
}
}
}
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
// everywhere by defualt.
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 ;
}
const COLORREF * const Settings : : GetColorTable ( ) const
{
return _ColorTable ;
}
void Settings : : SetColorTable ( _In_reads_ ( cSize ) const COLORREF * const pColorTable , const size_t cSize )
{
size_t cSizeWritten = std : : min ( cSize , static_cast < size_t > ( COLOR_TABLE_SIZE ) ) ;
memmove ( _ColorTable , pColorTable , cSizeWritten * sizeof ( COLORREF ) ) ;
}
void Settings : : SetColorTableEntry ( const size_t index , const COLORREF ColorValue )
{
if ( index < ARRAYSIZE ( _ColorTable ) )
{
_ColorTable [ index ] = ColorValue ;
}
else
{
_XtermColorTable [ index ] = ColorValue ;
}
}
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 ;
}
const size_t Settings : : GetColorTableSize ( ) const
{
return ARRAYSIZE ( _ColorTable ) ;
}
COLORREF Settings : : GetColorTableEntry ( const size_t index ) const
{
if ( index < ARRAYSIZE ( _ColorTable ) )
{
return _ColorTable [ index ] ;
}
else
{
return _XtermColorTable [ index ] ;
}
}
// Routine Description:
// - Generates a legacy attribute from the given TextAttributes.
// This needs to be a method on the Settings because the generated index
// is dependent upon the particular values of the color table at the time of reading.
// Parameters:
// - attributes - The TextAttributes to generate a legacy attribute for.
// Return value:
// - A WORD representing the entry in the color table that most closely represents the given fullcolor attributes.
WORD Settings : : GenerateLegacyAttributes ( const TextAttribute attributes ) const
{
const WORD wLegacyOriginal = attributes . GetLegacyAttributes ( ) ;
if ( attributes . IsLegacy ( ) )
{
return wLegacyOriginal ;
}
// We need to construct the legacy attributes manually
// First start with whatever our default legacy attributes are
BYTE fgIndex = static_cast < BYTE > ( ( _wFillAttribute & FG_ATTRS ) ) ;
BYTE bgIndex = static_cast < BYTE > ( ( _wFillAttribute & BG_ATTRS ) > > 4 ) ;
// If the attributes have any RGB components, we need to match that RGB
// color to a color table value.
if ( attributes . IsRgb ( ) )
{
// If the attribute doesn't have a "default" colored *ground, look up
2019-05-21 08:15:44 +02:00
// the nearest color table value for its *ground.
2019-05-03 00:29:04 +02:00
const COLORREF rgbForeground = LookupForegroundColor ( attributes ) ;
fgIndex = attributes . ForegroundIsDefault ( ) ?
2019-06-11 22:27:09 +02:00
fgIndex :
static_cast < BYTE > ( FindNearestTableIndex ( rgbForeground ) ) ;
2019-05-03 00:29:04 +02:00
const COLORREF rgbBackground = LookupBackgroundColor ( attributes ) ;
bgIndex = attributes . BackgroundIsDefault ( ) ?
2019-06-11 22:27:09 +02:00
bgIndex :
static_cast < BYTE > ( FindNearestTableIndex ( rgbBackground ) ) ;
2019-05-03 00:29:04 +02:00
}
// TextAttribute::GetLegacyAttributes(BYTE, BYTE) will use the legacy value
// it has if the component is a legacy index, otherwise it will use the
// provided byte for each index. In this way, we can provide a value to
// use should it not already have one.
const WORD wCompleteAttr = attributes . GetLegacyAttributes ( fgIndex , bgIndex ) ;
return wCompleteAttr ;
}
//Routine Description:
// For a given RGB color Color, finds the nearest color from the array ColorTable, and returns the index of that match.
//Arguments:
// - Color - The RGB color to fine the nearest color to.
// - ColorTable - The array of colors to find a nearest color from.
// - cColorTable - The number of elements in ColorTable
// Return value:
// The index in ColorTable of the nearest match to Color.
WORD Settings : : FindNearestTableIndex ( const COLORREF Color ) const
{
return : : FindNearestTableIndex ( Color , _ColorTable , ARRAYSIZE ( _ColorTable ) ) ;
}
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 ;
}
TextAttribute Settings : : GetDefaultAttributes ( ) const noexcept
{
auto attrs = TextAttribute { _wFillAttribute } ;
if ( _DefaultForeground ! = INVALID_COLOR )
{
attrs . SetDefaultForeground ( ) ;
}
if ( _DefaultBackground ! = INVALID_COLOR )
{
attrs . SetDefaultBackground ( ) ;
}
return attrs ;
}
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 ;
}
// Method Description:
// - Return the default foreground color of the console. If the settings are
// configured to have a default foreground color (separate from the color
// table), this will return that value. Otherwise it will return the value
// from the colortable corresponding to our default legacy attributes.
// Arguments:
// - <none>
// Return Value:
// - the default foreground color of the console.
COLORREF Settings : : CalculateDefaultForeground ( ) const noexcept
{
const auto fg = GetDefaultForegroundColor ( ) ;
return fg ! = INVALID_COLOR ? fg : ForegroundColor ( GetFillAttribute ( ) , GetColorTable ( ) , GetColorTableSize ( ) ) ;
}
// Method Description:
// - Return the default background color of the console. If the settings are
// configured to have a default background color (separate from the color
// table), this will return that value. Otherwise it will return the value
// from the colortable corresponding to our default legacy attributes.
// Arguments:
// - <none>
// Return Value:
// - the default background color of the console.
COLORREF Settings : : CalculateDefaultBackground ( ) const noexcept
{
const auto bg = GetDefaultBackgroundColor ( ) ;
return bg ! = INVALID_COLOR ? bg : BackgroundColor ( GetFillAttribute ( ) , GetColorTable ( ) , GetColorTableSize ( ) ) ;
}
// Method Description:
// - Get the foregroud color of a particular text attribute, using our color
// table, and our configured default attributes.
// Arguments:
// - attr: the TextAttribute to retrieve the foreground color of.
// Return Value:
// - The color value of the attribute's foreground TextColor.
COLORREF Settings : : LookupForegroundColor ( const TextAttribute & attr ) const noexcept
{
const auto tableView = std : : basic_string_view < COLORREF > ( & GetColorTable ( ) [ 0 ] , GetColorTableSize ( ) ) ;
return attr . CalculateRgbForeground ( tableView , CalculateDefaultForeground ( ) , CalculateDefaultBackground ( ) ) ;
}
// Method Description:
// - Get the background color of a particular text attribute, using our color
// table, and our configured default attributes.
// Arguments:
// - attr: the TextAttribute to retrieve the background color of.
// Return Value:
// - The color value of the attribute's background TextColor.
COLORREF Settings : : LookupBackgroundColor ( const TextAttribute & attr ) const noexcept
{
const auto tableView = std : : basic_string_view < COLORREF > ( & GetColorTable ( ) [ 0 ] , GetColorTableSize ( ) ) ;
return attr . CalculateRgbBackground ( tableView , CalculateDefaultForeground ( ) , CalculateDefaultBackground ( ) ) ;
}
bool Settings : : GetCopyColor ( ) const noexcept
{
return _fCopyColor ;
}