525be22bd8
## References * See also #8617 ## PR Checklist * [x] Supports #3075 * [x] I work here. * [x] Manual test. ## Detailed Description of the Pull Request / Additional comments ### Window Title Generation Every time the renderer checks the title, it's doing two bad things that I've fixed: 1. It's assembling the prefix to the full title doing a concatenation. No one ever gets just the prefix ever after it is set besides the concat. So instead of storing prefix and the title, I store the assembled prefix + title and the bare title. 2. A copy must be made because it was returning `std::wstring` instead of `std::wstring&`. Now it returns the ref. ### Dirty Area Return Every time the renderer checks the dirty area, which is sometimes multiple times per pass (regular text printing, again for selection, etc.), a vector is created off the heap to return the rectangles. The consumers only ever iterate this data. Now we return a span over a rectangle or rectangles that the engine must store itself. 1. For some renderers, it's always a constant 1 element. They update that 1 element when dirty is queried and return it in the span with a span size of 1. 2. For other renderers with more complex behavior, they're already holding a cached vector of rectangles. Now it's effectively giving out the ref to those in the span for iteration. ### Bitmap Runs The `til::bitmap` used a `std::optional<std::vector<til::rectangle>>` inside itself to cache its runs and would clear the optional when the runs became invalidated. Unfortunately doing `.reset()` to clear the optional will destroy the underlying vector and have it release its memory. We know it's about to get reallocated again, so we're just going to make it a `std::pmr::vector` and give it a memory pool. The alternative solution here was to use a `bool` and `std::vector<til::rectangle>` and just flag when the vector was invalid, but that was honestly more code changes and I love excuses to try out PMR now. Also, instead of returning the ref to the vector... I'm just returning a span now. Everyone just iterates it anyway, may as well not share the implementation detail. ### UTF-8 conversions When testing with Terminal and looking at the `conhost.exe`'s PTY renderer, it spends a TON of allocation time on converting all the UTF-16 stuff inside to UTF-8 before it sends it out the PTY. This was because `ConvertToA` was allocating a string inside itself and returning it just to have it freed after printing and looping back around again... as a PTY does. The change here is to use `til::u16u8` that accepts a buffer out parameter so the caller can just hold onto it. ## Validation Steps Performed - [x] `big.txt` in conhost.exe (GDI renderer) - [x] `big.txt` in Terminal (DX, PTY renderer) - [x] Ensure WDDM and BGFX build under Razzle with this change.
176 lines
6 KiB
C++
176 lines
6 KiB
C++
/*++
|
|
Copyright (c) Microsoft Corporation
|
|
Licensed under the MIT license.
|
|
|
|
Module Name:
|
|
- server.h
|
|
|
|
Abstract:
|
|
- This module contains the internal structures and definitions used by the console server.
|
|
|
|
Author:
|
|
- Therese Stowell (ThereseS) 12-Nov-1990
|
|
|
|
Revision History:
|
|
--*/
|
|
|
|
#pragma once
|
|
|
|
#include "IIoProvider.hpp"
|
|
|
|
#include "settings.hpp"
|
|
|
|
#include "conimeinfo.h"
|
|
#include "VtIo.hpp"
|
|
#include "CursorBlinker.hpp"
|
|
|
|
#include "../server/ProcessList.h"
|
|
#include "../server/WaitQueue.h"
|
|
|
|
#include "../host/RenderData.hpp"
|
|
#include "../renderer/inc/BlinkingState.hpp"
|
|
|
|
// clang-format off
|
|
// Flags flags
|
|
#define CONSOLE_IS_ICONIC 0x00000001
|
|
#define CONSOLE_OUTPUT_SUSPENDED 0x00000002
|
|
#define CONSOLE_HAS_FOCUS 0x00000004
|
|
#define CONSOLE_IGNORE_NEXT_MOUSE_INPUT 0x00000008
|
|
#define CONSOLE_SELECTING 0x00000010
|
|
#define CONSOLE_SCROLLING 0x00000020
|
|
// unused (CONSOLE_DISABLE_CLOSE) 0x00000040
|
|
// unused (CONSOLE_USE_POLY_TEXT) 0x00000080
|
|
|
|
// Removed Oct 2017 - added a headless mode, which revealed that the consumption
|
|
// of this flag was redundant.
|
|
// unused (CONSOLE_NO_WINDOW) 0x00000100
|
|
|
|
// unused (CONSOLE_VDM_REGISTERED) 0x00000200
|
|
#define CONSOLE_UPDATING_SCROLL_BARS 0x00000400
|
|
#define CONSOLE_QUICK_EDIT_MODE 0x00000800
|
|
#define CONSOLE_CONNECTED_TO_EMULATOR 0x00002000
|
|
// unused (CONSOLE_FULLSCREEN_NOPAINT) 0x00004000
|
|
#define CONSOLE_QUIT_POSTED 0x00008000
|
|
#define CONSOLE_AUTO_POSITION 0x00010000
|
|
#define CONSOLE_IGNORE_NEXT_KEYUP 0x00020000
|
|
// unused (CONSOLE_WOW_REGISTERED) 0x00040000
|
|
#define CONSOLE_HISTORY_NODUP 0x00100000
|
|
#define CONSOLE_SCROLLBAR_TRACKING 0x00200000
|
|
#define CONSOLE_SETTING_WINDOW_SIZE 0x00800000
|
|
// unused (CONSOLE_VDM_HIDDEN_WINDOW) 0x01000000
|
|
// unused (CONSOLE_OS2_REGISTERED) 0x02000000
|
|
// unused (CONSOLE_OS2_OEM_FORMAT) 0x04000000
|
|
// unused (CONSOLE_JUST_VDM_UNREGISTERED) 0x08000000
|
|
// unused (CONSOLE_FULLSCREEN_INITIALIZED) 0x10000000
|
|
#define CONSOLE_USE_PRIVATE_FLAGS 0x20000000
|
|
// unused (CONSOLE_TSF_ACTIVATED) 0x40000000
|
|
#define CONSOLE_INITIALIZED 0x80000000
|
|
|
|
#define CONSOLE_SUSPENDED (CONSOLE_OUTPUT_SUSPENDED)
|
|
// clang-format on
|
|
|
|
class COOKED_READ_DATA;
|
|
class CommandHistory;
|
|
|
|
class CONSOLE_INFORMATION :
|
|
public Settings,
|
|
public Microsoft::Console::IIoProvider
|
|
{
|
|
public:
|
|
CONSOLE_INFORMATION();
|
|
~CONSOLE_INFORMATION();
|
|
CONSOLE_INFORMATION(const CONSOLE_INFORMATION& c) = delete;
|
|
CONSOLE_INFORMATION& operator=(const CONSOLE_INFORMATION& c) = delete;
|
|
|
|
ConsoleProcessList ProcessHandleList;
|
|
InputBuffer* pInputBuffer;
|
|
|
|
SCREEN_INFORMATION* ScreenBuffers; // singly linked list
|
|
ConsoleWaitQueue OutputQueue;
|
|
|
|
DWORD Flags;
|
|
|
|
std::atomic<WORD> PopupCount;
|
|
|
|
// the following fields are used for ansi-unicode translation
|
|
UINT CP;
|
|
UINT OutputCP;
|
|
|
|
ULONG CtrlFlags; // indicates outstanding ctrl requests
|
|
ULONG LimitingProcessId;
|
|
|
|
CPINFO CPInfo;
|
|
CPINFO OutputCPInfo;
|
|
|
|
ConsoleImeInfo ConsoleIme;
|
|
|
|
void LockConsole();
|
|
bool TryLockConsole();
|
|
void UnlockConsole();
|
|
bool IsConsoleLocked() const;
|
|
ULONG GetCSRecursionCount();
|
|
|
|
Microsoft::Console::VirtualTerminal::VtIo* GetVtIo();
|
|
|
|
SCREEN_INFORMATION& GetActiveOutputBuffer() override;
|
|
const SCREEN_INFORMATION& GetActiveOutputBuffer() const override;
|
|
bool HasActiveOutputBuffer() const;
|
|
|
|
InputBuffer* const GetActiveInputBuffer() const;
|
|
|
|
bool IsInVtIoMode() const;
|
|
bool HasPendingCookedRead() const noexcept;
|
|
const COOKED_READ_DATA& CookedReadData() const noexcept;
|
|
COOKED_READ_DATA& CookedReadData() noexcept;
|
|
void SetCookedReadData(COOKED_READ_DATA* readData) noexcept;
|
|
|
|
COLORREF GetDefaultForeground() const noexcept;
|
|
COLORREF GetDefaultBackground() const noexcept;
|
|
std::pair<COLORREF, COLORREF> LookupAttributeColors(const TextAttribute& attr) const noexcept;
|
|
|
|
void SetTitle(const std::wstring_view newTitle);
|
|
void SetTitlePrefix(const std::wstring_view newTitlePrefix);
|
|
void SetOriginalTitle(const std::wstring_view originalTitle);
|
|
void SetLinkTitle(const std::wstring_view linkTitle);
|
|
const std::wstring_view GetTitle() const noexcept;
|
|
const std::wstring_view GetOriginalTitle() const noexcept;
|
|
const std::wstring_view GetLinkTitle() const noexcept;
|
|
const std::wstring_view GetTitleAndPrefix() const;
|
|
|
|
[[nodiscard]] static NTSTATUS AllocateConsole(const std::wstring_view title);
|
|
// MSFT:16886775 : get rid of friends
|
|
friend void SetActiveScreenBuffer(_Inout_ SCREEN_INFORMATION& screenInfo);
|
|
friend class SCREEN_INFORMATION;
|
|
friend class CommonState;
|
|
Microsoft::Console::CursorBlinker& GetCursorBlinker() noexcept;
|
|
Microsoft::Console::Render::BlinkingState& GetBlinkingState() const noexcept;
|
|
|
|
CHAR_INFO AsCharInfo(const OutputCellView& cell) const noexcept;
|
|
|
|
RenderData renderData;
|
|
|
|
private:
|
|
CRITICAL_SECTION _csConsoleLock; // serialize input and output using this
|
|
std::wstring _Title;
|
|
std::wstring _Prefix; // Eg Select, Mark - things that we manually prepend to the title.
|
|
std::wstring _TitleAndPrefix;
|
|
std::wstring _OriginalTitle;
|
|
std::wstring _LinkTitle; // Path to .lnk file
|
|
SCREEN_INFORMATION* pCurrentScreenBuffer;
|
|
COOKED_READ_DATA* _cookedReadData; // non-ownership pointer
|
|
|
|
Microsoft::Console::VirtualTerminal::VtIo _vtIo;
|
|
Microsoft::Console::CursorBlinker _blinker;
|
|
mutable Microsoft::Console::Render::BlinkingState _blinkingState;
|
|
};
|
|
|
|
#define ConsoleLocked() (ServiceLocator::LocateGlobals()->getConsoleInformation()->ConsoleLock.OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
|
|
|
|
#define CONSOLE_STATUS_WAIT 0xC0030001
|
|
#define CONSOLE_STATUS_READ_COMPLETE 0xC0030002
|
|
#define CONSOLE_STATUS_WAIT_NO_BLOCK 0xC0030003
|
|
|
|
#include "../server/ObjectHandle.h"
|
|
|
|
void SetActiveScreenBuffer(SCREEN_INFORMATION& screenInfo);
|