// 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 tableView = { _colorTable.data(), _colorTable.size() }; ::Microsoft::Console::Utils::Initialize256ColorTable(tableView); ::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: // - // Return Value: // - - 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 tableView = { _colorTable.data(), _colorTable.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: // - 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; for (size_t i = 0; i < std::size(pStateInfo->ColorTable); i++) { SetColorTableEntry(i, pStateInfo->ColorTable[i]); } _uCodePage = pStateInfo->CodePage; _bWrapText = !!pStateInfo->fWrapText; _fFilterOnPaste = pStateInfo->fFilterOnPaste; _fCtrlKeyShortcutsDisabled = pStateInfo->fCtrlKeyShortcutsDisabled; _bLineSelection = pStateInfo->fLineSelection; _bWindowAlpha = pStateInfo->bWindowTransparency; _CursorColor = pStateInfo->CursorColor; _CursorType = static_cast(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: // - // 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; for (size_t i = 0; i < std::size(csi.ColorTable); i++) { csi.ColorTable[i] = GetColorTableEntry(i); } 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(_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; } } // 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); 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(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; } std::basic_string_view Settings::Get16ColorTable() const { return Get256ColorTable().substr(0, 16); } std::basic_string_view Settings::Get256ColorTable() const { return { _colorTable.data(), _colorTable.size() }; } void Settings::SetColorTableEntry(const size_t index, const COLORREF ColorValue) { _colorTable.at(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; } COLORREF Settings::GetColorTableEntry(const size_t index) const { return _colorTable.at(index); } 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; } // 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: // - // Return Value: // - the default foreground color of the console. COLORREF Settings::CalculateDefaultForeground() const noexcept { const auto fg = GetDefaultForegroundColor(); return fg != INVALID_COLOR ? fg : GetColorTableEntry(LOBYTE(_wFillAttribute) & FG_ATTRS); } // 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: // - // Return Value: // - the default background color of the console. COLORREF Settings::CalculateDefaultBackground() const noexcept { const auto bg = GetDefaultBackgroundColor(); return bg != INVALID_COLOR ? bg : GetColorTableEntry((LOBYTE(_wFillAttribute) & BG_ATTRS) >> 4); } // Method Description: // - Get the colors 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 values of the attribute's foreground and background. std::pair Settings::LookupAttributeColors(const TextAttribute& attr) const noexcept { return attr.CalculateRgbColors(Get256ColorTable(), CalculateDefaultForeground(), CalculateDefaultBackground(), _fScreenReversed); } bool Settings::GetCopyColor() const noexcept { return _fCopyColor; }