72cbe59078
Implement the `XTPUSHSGR` and `XTPOPSGR` control sequences (see #1796). This change adds a new pair of methods to `ITermDispatch`: `PushGraphicsRendition` and `PopGraphicsRendition`, and then plumbs the change through `AdaptDispatch`, `TerminalDispatch`, `ITerminalApi` and `TerminalApi`. The stack logic is encapsulated in the `SgrStack` class, to allow it to be reused between the two APIs (`AdaptDispatch` and `TerminalDispatch`). Like xterm, only ten levels of nesting are supported. The stack is implemented as a "ring stack": if you push when the stack is full, the bottom of the stack will be dropped to make room. Partial pushes (see the description of `XTPUSHSGR` in Issue #1796) are implemented per xterm spec. ## Validation Steps Performed Tests added, plus manual verification of the feature. Closes #1796
139 lines
3.5 KiB
C++
139 lines
3.5 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
/*
|
|
Module Name:
|
|
- telemetry.hpp
|
|
|
|
Abstract:
|
|
- This module is used for recording all telemetry feedback from the console virtual terminal parser
|
|
*/
|
|
#pragma once
|
|
|
|
// Including TraceLogging essentials for the binary
|
|
#include <windows.h>
|
|
#include <winmeta.h>
|
|
#include <TraceLoggingProvider.h>
|
|
#include "climits"
|
|
|
|
TRACELOGGING_DECLARE_PROVIDER(g_hConsoleVirtTermParserEventTraceProvider);
|
|
|
|
namespace Microsoft::Console::VirtualTerminal
|
|
{
|
|
class TermTelemetry sealed
|
|
{
|
|
public:
|
|
// Implement this as a singleton class.
|
|
static TermTelemetry& Instance() noexcept
|
|
{
|
|
static TermTelemetry s_Instance;
|
|
return s_Instance;
|
|
}
|
|
|
|
// Names primarily from http://inwap.com/pdp10/ansicode.txt
|
|
enum Codes
|
|
{
|
|
CUU = 0,
|
|
CUD,
|
|
CUF,
|
|
CUB,
|
|
CNL,
|
|
CPL,
|
|
CHA,
|
|
CUP,
|
|
ED,
|
|
EL,
|
|
SGR,
|
|
DECSC,
|
|
DECRC,
|
|
DECSET,
|
|
DECRST,
|
|
DECKPAM,
|
|
DECKPNM,
|
|
DSR,
|
|
DA,
|
|
DA2,
|
|
DA3,
|
|
DECREQTPARM,
|
|
VPA,
|
|
HPR,
|
|
VPR,
|
|
ICH,
|
|
DCH,
|
|
SU,
|
|
SD,
|
|
ANSISYSSC,
|
|
ANSISYSRC,
|
|
IL,
|
|
DL,
|
|
DECSTBM,
|
|
NEL,
|
|
IND,
|
|
RI,
|
|
OSCWT,
|
|
HTS,
|
|
CHT,
|
|
CBT,
|
|
TBC,
|
|
ECH,
|
|
DesignateG0,
|
|
DesignateG1,
|
|
DesignateG2,
|
|
DesignateG3,
|
|
LS2,
|
|
LS3,
|
|
LS1R,
|
|
LS2R,
|
|
LS3R,
|
|
SS2,
|
|
SS3,
|
|
DOCS,
|
|
HVP,
|
|
DECSTR,
|
|
RIS,
|
|
DECSCUSR,
|
|
DTTERM_WM,
|
|
OSCCT,
|
|
OSCSCC,
|
|
OSCRCC,
|
|
REP,
|
|
OSCFG,
|
|
OSCBG,
|
|
DECALN,
|
|
OSCSCB,
|
|
XTPUSHSGR,
|
|
XTPOPSGR,
|
|
// Only use this last enum as a count of the number of codes.
|
|
NUMBER_OF_CODES
|
|
};
|
|
void Log(const Codes code) noexcept;
|
|
void LogFailed(const wchar_t wch) noexcept;
|
|
void SetShouldWriteFinalLog(const bool writeLog) noexcept;
|
|
void SetActivityId(const GUID* activityId) noexcept;
|
|
unsigned int GetAndResetTimesUsedCurrent() noexcept;
|
|
unsigned int GetAndResetTimesFailedCurrent() noexcept;
|
|
unsigned int GetAndResetTimesFailedOutsideRangeCurrent() noexcept;
|
|
|
|
private:
|
|
// Used to prevent multiple instances
|
|
TermTelemetry() noexcept;
|
|
~TermTelemetry();
|
|
TermTelemetry(TermTelemetry const&) = delete;
|
|
TermTelemetry(TermTelemetry&&) = delete;
|
|
TermTelemetry& operator=(const TermTelemetry&) = delete;
|
|
TermTelemetry& operator=(TermTelemetry&&) = delete;
|
|
|
|
void WriteFinalTraceLog() const;
|
|
|
|
unsigned int _uiTimesUsedCurrent;
|
|
unsigned int _uiTimesFailedCurrent;
|
|
unsigned int _uiTimesFailedOutsideRangeCurrent;
|
|
unsigned int _uiTimesUsed[NUMBER_OF_CODES];
|
|
unsigned int _uiTimesFailed[CHAR_MAX + 1];
|
|
unsigned int _uiTimesFailedOutsideRange;
|
|
GUID _activityId;
|
|
|
|
bool _fShouldWriteFinalLog;
|
|
};
|
|
}
|