From 2608db272899410a22c944cdd842e036ff121b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 4 Sep 2022 11:04:07 +0200 Subject: [PATCH] unit tests, fix DECRQSS report --- src/common/InputHandler.test.ts | 44 ++++++++++++++++++++++++++++++ src/common/InputHandler.ts | 20 ++++++++------ src/common/Types.d.ts | 1 + src/common/buffer/AttributeData.ts | 1 + 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index 2fa4ac2f..f86006eb 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -2146,6 +2146,50 @@ describe('InputHandler', () => { }); }); }); + + describe('DECSCA and DECSED/DECSEL', () => { + it('default is unprotected', async () => { + await inputHandler.parseP('some text'); + await inputHandler.parseP('\x1b[?2K'); + assert.deepEqual(getLines(bufferService, 2), ['', '']); + await inputHandler.parseP('some text'); + await inputHandler.parseP('\x1b[?2J'); + assert.deepEqual(getLines(bufferService, 2), ['', '']); + }); + it('DECSCA 1 with DECSEL', async () => { + await inputHandler.parseP('###\x1b[1"qlineerase\x1b[0"q***'); + await inputHandler.parseP('\x1b[?2K'); + assert.deepEqual(getLines(bufferService, 2), [' lineerase', '']); + // normal EL works as before + await inputHandler.parseP('\x1b[2K'); + assert.deepEqual(getLines(bufferService, 2), ['', '']); + }); + it('DECSCA 1 with DECSED', async () => { + await inputHandler.parseP('###\x1b[1"qdisplayerase\x1b[0"q***'); + await inputHandler.parseP('\x1b[?2J'); + assert.deepEqual(getLines(bufferService, 2), [' displayerase', '']); + // normal ED works as before + await inputHandler.parseP('\x1b[2J'); + assert.deepEqual(getLines(bufferService, 2), ['', '']); + }); + it('DECRQSS reports correct DECSCA state', async () => { + const sendStack: string[] = []; + coreService.onData(d => sendStack.push(d)); + // DCS $ q " q ST + await inputHandler.parseP('\x1bP$q"q\x1b\\'); + console.log(sendStack); + // default - DECSCA unset (0 or 2) + assert.deepEqual(sendStack.pop(), '\x1bP1$r0"q\x1b\\'); + // DECSCA 1 - protected set + await inputHandler.parseP('###\x1b[1"q'); + await inputHandler.parseP('\x1bP$q"q\x1b\\'); + assert.deepEqual(sendStack.pop(), '\x1bP1$r1"q\x1b\\'); + // DECSCA 2 - protected reset (same as 0) + await inputHandler.parseP('###\x1b[2"q'); + await inputHandler.parseP('\x1bP$q"q\x1b\\'); + assert.deepEqual(sendStack.pop(), '\x1bP1$r0"q\x1b\\'); // reported as DECSCA 0 + }); + }); }); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index bf74446e..886bb7e3 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -123,13 +123,12 @@ const SLOW_ASYNC_LIMIT = 5000; * | Graphic Rendition (SGR) | `DCS $ q m ST` | always reporting `0m` (currently broken) | * | Top and Bottom Margins (DECSTBM) | `DCS $ q r ST` | `Ps ; Ps r` | * | Cursor Style (DECSCUSR) | `DCS $ q SP q ST` | `Ps SP q` | - * | Protection Attribute (DECSCA) | `DCS $ q " q ST` | always reporting `0 " q` (DECSCA is unsupported) | + * | Protection Attribute (DECSCA) | `DCS $ q " q ST` | `Ps " q` (DECSCA 2 is reported as 0) | * | Conformance Level (DECSCL) | `DCS $ q " p ST` | always reporting `61 ; 1 " p` (DECSCL is unsupported) | * * * TODO: * - fix SGR report - * - either implement DECSCA or remove the report * - either check which conformance is better suited or remove the report completely * --> we are currently a mixture of all up to VT400 but dont follow anyone strictly */ @@ -137,10 +136,11 @@ class DECRQSS implements IDcsHandler { private _data: Uint32Array = new Uint32Array(0); constructor( - private _bufferService: IBufferService, - private _coreService: ICoreService, - private _logService: ILogService, - private _optionsService: IOptionsService + private readonly _ih: InputHandler, + private readonly _bufferService: IBufferService, + private readonly _coreService: ICoreService, + private readonly _logService: ILogService, + private readonly _optionsService: IOptionsService ) { } public hook(params: IParams): void { @@ -161,7 +161,8 @@ class DECRQSS implements IDcsHandler { switch (data) { // valid: DCS 1 $ r Pt ST (xterm) case '"q': // DECSCA - this._coreService.triggerDataEvent(`${C0.ESC}P1$r0"q${C0.ESC}\\`); + const prot = this._ih.getAttrData().isProtected() ? 1 : 0; + this._coreService.triggerDataEvent(`${C0.ESC}P1$r${prot}"q${C0.ESC}\\`); break; case '"p': // DECSCL this._coreService.triggerDataEvent(`${C0.ESC}P1$r61;1"p${C0.ESC}\\`); @@ -172,7 +173,7 @@ class DECRQSS implements IDcsHandler { this._coreService.triggerDataEvent(`${C0.ESC}P1$r${pt}${C0.ESC}\\`); break; case 'm': // SGR - // TODO: report real settings instead of 0m + // FIXME: report real settings instead of 0m this._coreService.triggerDataEvent(`${C0.ESC}P1$r0m${C0.ESC}\\`); break; case ' q': // DECSCUSR @@ -233,6 +234,7 @@ export class InputHandler extends Disposable implements IInputHandler { protected _iconNameStack: string[] = []; private _curAttrData: IAttributeData = DEFAULT_ATTR_DATA.clone(); + public getAttrData(): IAttributeData { return this._curAttrData; } private _eraseAttrDataInternal: IAttributeData = DEFAULT_ATTR_DATA.clone(); private _activeBuffer: IBuffer; @@ -482,7 +484,7 @@ export class InputHandler extends Disposable implements IInputHandler { /** * DCS handler */ - this._parser.registerDcsHandler({ intermediates: '$', final: 'q' }, new DECRQSS(this._bufferService, this._coreService, this._logService, this._optionsService)); + this._parser.registerDcsHandler({ intermediates: '$', final: 'q' }, new DECRQSS(this, this._bufferService, this._coreService, this._logService, this._optionsService)); } public dispose(): void { diff --git a/src/common/Types.d.ts b/src/common/Types.d.ts index 31399116..f559719e 100644 --- a/src/common/Types.d.ts +++ b/src/common/Types.d.ts @@ -150,6 +150,7 @@ export interface IAttributeData { isItalic(): number; isDim(): number; isStrikethrough(): number; + isProtected(): number; // color modes getFgColorMode(): number; diff --git a/src/common/buffer/AttributeData.ts b/src/common/buffer/AttributeData.ts index 3af3d293..c9f4cd61 100644 --- a/src/common/buffer/AttributeData.ts +++ b/src/common/buffer/AttributeData.ts @@ -46,6 +46,7 @@ export class AttributeData implements IAttributeData { public isItalic(): number { return this.bg & BgFlags.ITALIC; } public isDim(): number { return this.bg & BgFlags.DIM; } public isStrikethrough(): number { return this.fg & FgFlags.STRIKETHROUGH; } + public isProtected(): number { return this.bg & BgFlags.PROTECTED; } // color modes public getFgColorMode(): number { return this.fg & Attributes.CM_MASK; }