989 lines
30 KiB
C++
989 lines
30 KiB
C++
// 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
|
|
|
|
constexpr unsigned int DEFAULT_NUMBER_OF_COMMANDS = 25;
|
|
constexpr unsigned int DEFAULT_NUMBER_OF_BUFFERS = 4;
|
|
|
|
using Microsoft::Console::Interactivity::ServiceLocator;
|
|
|
|
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
|
|
_uCursorSize(Cursor::CURSOR_SMALL_SIZE),
|
|
_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),
|
|
_LaunchFaceName{},
|
|
_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.
|
|
_fScreenReversed(false),
|
|
// 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);
|
|
::Microsoft::Console::Utils::InitializeCampbellColorTableForConhost(tableView);
|
|
}
|
|
|
|
// 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) };
|
|
::Microsoft::Console::Utils::InitializeCampbellColorTableForConhost(tableView);
|
|
|
|
_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
|
|
{
|
|
CONSOLE_STATE_INFO csi = { 0 };
|
|
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, 1i16);
|
|
_dwScreenBufferSize.Y = std::max(_dwScreenBufferSize.Y, 1i16);
|
|
|
|
// minimum window size size 1x1
|
|
_dwWindowSize.X = std::max(_dwWindowSize.X, 1i16);
|
|
_dwWindowSize.Y = std::max(_dwWindowSize.Y, 1i16);
|
|
|
|
// 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));
|
|
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
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::IsScreenReversed() const
|
|
{
|
|
return _fScreenReversed;
|
|
}
|
|
void Settings::SetScreenReversed(const bool fScreenReversed)
|
|
{
|
|
_fScreenReversed = fScreenReversed;
|
|
}
|
|
|
|
bool Settings::GetFilterOnPaste() const
|
|
{
|
|
return _fFilterOnPaste;
|
|
}
|
|
void Settings::SetFilterOnPaste(const bool fFilterOnPaste)
|
|
{
|
|
_fFilterOnPaste = fFilterOnPaste;
|
|
}
|
|
|
|
const std::wstring_view Settings::GetLaunchFaceName() const
|
|
{
|
|
return _LaunchFaceName;
|
|
}
|
|
void Settings::SetLaunchFaceName(const std::wstring_view launchFaceName)
|
|
{
|
|
_LaunchFaceName = launchFaceName;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
bool Settings::GetWrapText() const
|
|
{
|
|
return _bWrapText;
|
|
}
|
|
void Settings::SetWrapText(const bool bWrapText)
|
|
{
|
|
_bWrapText = bWrapText;
|
|
}
|
|
|
|
bool Settings::GetCtrlKeyShortcutsDisabled() const
|
|
{
|
|
return _fCtrlKeyShortcutsDisabled;
|
|
}
|
|
void Settings::SetCtrlKeyShortcutsDisabled(const bool fCtrlKeyShortcutsDisabled)
|
|
{
|
|
_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.
|
|
_bWindowAlpha = (bWindowAlpha < MIN_WINDOW_OPACITY) ? BYTE_MAX : bWindowAlpha;
|
|
}
|
|
|
|
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 default.
|
|
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;
|
|
}
|
|
void Settings::SetFaceName(const std::wstring_view faceName)
|
|
{
|
|
auto extent = std::min<size_t>(faceName.size(), ARRAYSIZE(_FaceName));
|
|
StringCchCopyW(_FaceName, extent, faceName.data());
|
|
}
|
|
|
|
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
|
|
// the nearest color table value for its *ground.
|
|
const COLORREF rgbForeground = LookupForegroundColor(attributes);
|
|
fgIndex = attributes.ForegroundIsDefault() ?
|
|
fgIndex :
|
|
static_cast<BYTE>(FindNearestTableIndex(rgbForeground));
|
|
|
|
const COLORREF rgbBackground = LookupBackgroundColor(attributes);
|
|
bgIndex = attributes.BackgroundIsDefault() ?
|
|
bgIndex :
|
|
static_cast<BYTE>(FindNearestTableIndex(rgbBackground));
|
|
}
|
|
|
|
// 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 foreground 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());
|
|
if (_fScreenReversed)
|
|
{
|
|
return attr.CalculateRgbBackground(tableView, CalculateDefaultForeground(), CalculateDefaultBackground());
|
|
}
|
|
else
|
|
{
|
|
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());
|
|
if (_fScreenReversed)
|
|
{
|
|
return attr.CalculateRgbForeground(tableView, CalculateDefaultForeground(), CalculateDefaultBackground());
|
|
}
|
|
else
|
|
{
|
|
return attr.CalculateRgbBackground(tableView, CalculateDefaultForeground(), CalculateDefaultBackground());
|
|
}
|
|
}
|
|
|
|
bool Settings::GetCopyColor() const noexcept
|
|
{
|
|
return _fCopyColor;
|
|
}
|