From a1a4cac113289000f6cd3a2e0bcfa4f1140ec616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Wed, 2 May 2018 00:22:35 +0200 Subject: [PATCH] dcs handler implementations --- src/InputHandler.ts | 91 ++++++++++++++++++++++++++++++++++++++++++++- src/Types.ts | 2 + 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/InputHandler.ts b/src/InputHandler.ts index 59b98cf8..6dfdd1bc 100644 --- a/src/InputHandler.ts +++ b/src/InputHandler.ts @@ -4,7 +4,7 @@ * @license MIT */ -import { CharData, IInputHandler } from './Types'; +import { CharData, IInputHandler, IDcsHandler } from './Types'; import { C0, C1 } from './EscapeSequences'; import { CHARSETS, DEFAULT_CHARSET } from './Charsets'; import { CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from './Buffer'; @@ -17,6 +17,89 @@ import { EscapeSequenceParser } from './EscapeSequenceParser'; */ const GLEVEL = {'(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2}; + +/** + * DCS subparser implementations + */ + + /** + * DCS + q Pt ST (xterm) + * Request Terminfo String + * not supported + */ +class RequestTerminfo implements IDcsHandler { + private _data: string; + constructor(private _terminal: any) { } + hook(collect: string, params: number[], flag: number): void { + this._data = ''; + } + put(data: string, start: number, end: number): void { + this._data += data.substring(start, end); + } + unhook(): void { + // invalid: DCS 0 + r Pt ST + this._terminal.send(C0.ESC + 'P0' + '+r' + this._data + C0.ESC + '\\'); + } +} + +/** + * DCS $ q Pt ST + * DECRQSS (https://vt100.net/docs/vt510-rm/DECRQSS.html) + * Request Status String (DECRQSS), VT420 and up. + * Response: DECRPSS (https://vt100.net/docs/vt510-rm/DECRPSS.html) + * FIXME: xterm and DEC flip P0 and P1 to indicate valid requests - which one to go with? + */ +class DECRQSS implements IDcsHandler { + private _data: string; + constructor(private _terminal: any) { } + hook(collect: string, params: number[], flag: number): void { + // reset data + this._data = ''; + } + put(data: string, start: number, end: number): void { + this._data += data.substring(start, end); + } + unhook(): void { + switch (this._data) { + // valid: DCS 1 $ r Pt ST (xterm) + case '"q': // DECSCA + return this._terminal.send(C0.ESC + 'P1' + '$r' + '0"q' + C0.ESC + '\\'); + case '"p': // DECSCL + return this._terminal.send(C0.ESC + 'P1' + '$r' + '61"p' + C0.ESC + '\\'); + case 'r': // DECSTBM + let pt = '' + (this._terminal.buffer.scrollTop + 1) + + ';' + (this._terminal.buffer.scrollBottom + 1) + 'r'; + return this._terminal.send(C0.ESC + 'P1' + '$r' + pt + C0.ESC + '\\'); + case 'm': // SGR + // FIXME: report real settings instead of 0m + return this._terminal.send(C0.ESC + 'P1' + '$r' + '0m' + C0.ESC + '\\'); + case ' q': // DECSCUSR + const STYLES = {'block': 2, 'underline': 4, 'bar': 6}; + let style = STYLES[this._terminal.getOption('cursorStyle')]; + style -= this._terminal.getOption('cursorBlink'); + return this._terminal.send(C0.ESC + 'P1' + '$r' + style + ' q' + C0.ESC + '\\'); + default: + // invalid: DCS 0 $ r Pt ST (xterm) + this._terminal.error('Unknown DCS $q %s', this._data); + this._terminal.send(C0.ESC + 'P0' + '$r' + this._data + C0.ESC + '\\'); + } + } +} + +/** + * DCS Ps; Ps| Pt ST + * DECUDK (https://vt100.net/docs/vt510-rm/DECUDK.html) + * not supported + */ + + /** + * DCS + p Pt ST (xterm) + * Set Terminfo Data + * not supported + */ + + + /** * The terminal's standard implementation of IInputHandler, this handles all * input from the Parser. @@ -191,6 +274,12 @@ export class InputHandler implements IInputHandler { this._terminal.error('Parsing error: ', state); return state; }); + + /** + * DCS handler + */ + this._parser.setDcsHandler('$q', new DECRQSS(this._terminal)); + this._parser.setDcsHandler('+q', new RequestTerminfo(this._terminal)); } public parse(data: string): void { diff --git a/src/Types.ts b/src/Types.ts index bbe98475..5a46cbca 100644 --- a/src/Types.ts +++ b/src/Types.ts @@ -454,6 +454,8 @@ export interface IParsingState { * EscapeSequenceParser handles DCS commands via separate * subparsers that get hook/unhooked and can handle * arbitrary amount of print data. +* NOTE: EscapeSequenceParser might call `put` several times, +* therefore you have to collect `data` until unhook is called. */ export interface IDcsHandler { hook(collect: string, params: number[], flag: number): void;