Added support for alternate screen buffer (1049 h/l codes)

openid
Marcin Kulik 14 years ago
parent eb9034ea15
commit 2a27089243

@ -59,17 +59,25 @@ SP.AnsiInterpreter.prototype = {
"\x1b\\[\\?([\x30-\x3f]+)([hlsr])": function(data, match) { // private standards "\x1b\\[\\?([\x30-\x3f]+)([hlsr])": function(data, match) { // private standards
// h = Sets DEC/xterm specific mode (http://ttssh2.sourceforge.jp/manual/en/about/ctrlseq.html#decmode) // h = Sets DEC/xterm specific mode (http://ttssh2.sourceforge.jp/manual/en/about/ctrlseq.html#decmode)
// l = Resets mode (http://ttssh2.sourceforge.jp/manual/en/about/ctrlseq.html#mode) // l = Resets mode (http://ttssh2.sourceforge.jp/manual/en/about/ctrlseq.html#mode)
// 1049 + h = Save cursor position, switch to alternate screen buffer, and clear screen.
// 1049 + l = Clear screen, switch to normal screen buffer, and restore cursor position.
// 1001 + s = ? // 1001 + s = ?
// 1001 + r = ? // 1001 + r = ?
if (match[1] == '1049') { if (match[1] == '1049') {
if (match[2] == 'h') { if (match[2] == 'h') {
// 1049 + h = Save cursor position, switch to alternate screen buffer, and clear screen.
this.terminal.saveCursor(); this.terminal.saveCursor();
this.terminal.switchToAlternateBuffer();
this.terminal.clearScreen();
} else if (match[2] == 'l') { } else if (match[2] == 'l') {
// 1049 + l = Clear screen, switch to normal screen buffer, and restore cursor position.
this.terminal.clearScreen();
this.terminal.switchToNormalBuffer();
this.terminal.restoreCursor(); this.terminal.restoreCursor();
} }
} else if (match[1] == '1002') {
// 2002 + h / l = mouse tracking stuff
} else if (match[1] == '1') {
// 1 + h / l = cursor keys stuff
} }
}, },

@ -28,7 +28,7 @@ SP.Player.prototype = {
var run = function() { var run = function() {
var rest = this.interpreter.feed(this.currentData); var rest = this.interpreter.feed(this.currentData);
this.terminal.updateDirtyLines(); this.terminal.renderDirtyLines();
var n = timing[1]; var n = timing[1];
if (rest.length > 0) if (rest.length > 0)

@ -3,7 +3,9 @@ SP.Terminal = function(cols, lines) {
this.lines = lines; this.lines = lines;
this.cursorLine = 0; this.cursorLine = 0;
this.cursorCol = 0; this.cursorCol = 0;
this.lineData = []; this.normalBuffer = [];
this.alternateBuffer = [];
this.lineData = this.normalBuffer;
this.fg = this.bg = undefined; this.fg = this.bg = undefined;
this.dirtyLines = []; this.dirtyLines = [];
this.initialize(); this.initialize();
@ -13,48 +15,65 @@ SP.Terminal.prototype = {
initialize: function() { initialize: function() {
var container = $(".player .term"); var container = $(".player .term");
this.element = container; this.element = container;
for (l = 0; l < this.lines; l++) { this.renderLine(0); // we only need 1 line
var row = $("<span class='line'>"); this.element.css({ height: this.element.height() * this.lines });
container.append(row); },
container.append("\n");
this.lineData[l] = []; getLine: function(n) {
this.updateLine(l); n = (typeof n != "undefined" ? n : this.cursorLine);
var line = this.lineData[n];
if (typeof line == 'undefined') {
line = this.lineData[n] = [];
this.fill(n, 0, this.cols, ' ');
} }
return line;
}, },
setSGR: function(codes) { clearScreen: function() {
if (codes.length == 0) { this.lineData.length = 0;
codes = [0]; this.cursorLine = this.cursorCol = 0;
this.element.empty();
},
switchToNormalBuffer: function() {
this.lineData = this.normalBuffer;
this.updateScreen();
},
switchToAlternateBuffer: function() {
this.lineData = this.alternateBuffer;
this.updateScreen();
},
renderLine: function(n) {
var html = this.getLine(n);
if (n == this.cursorLine) {
html = html.slice(0, this.cursorCol).concat(['<span class="cursor">' + (html[this.cursorCol] || '') + "</span>"], html.slice(this.cursorCol + 1) || []);
} }
for (var i=0; i<codes.length; i++) { var missingLines = this.lineData.length - this.element.find('.line').length;
var n = codes[i];
if (n === 0) { for (var i = 0; i < missingLines; i++) {
this.fg = this.bg = undefined; var row = $('<span class="line">');
this.bright = false; this.element.append(row);
} else if (n == 1) { this.element.append("\n");
this.bright = true; this.element.scrollTop(100000);//row.offset().top);
} else if (n >= 30 && n <= 37) {
this.fg = n - 30;
} else if (n >= 40 && n <= 47) {
this.bg = n - 40;
}
} }
},
updateLine: function(n) { this.element.find(".line:eq(" + n + ")").html(html.join(''));
n = (typeof n != "undefined" ? n : this.cursorLine);
this.dirtyLines.push(n);
}, },
updateDirtyLines: function() { renderDirtyLines: function() {
var updated = []; var updated = [];
for (var i=0; i<this.dirtyLines.length; i++) { for (var i=0; i<this.dirtyLines.length; i++) {
var n = this.dirtyLines[i]; var n = this.dirtyLines[i];
if (updated.indexOf(n) == -1) { if (updated.indexOf(n) == -1) {
this._updateLine(n); this.renderLine(n);
updated.push(n); updated.push(n);
} }
} }
@ -62,17 +81,38 @@ SP.Terminal.prototype = {
this.dirtyLines = []; this.dirtyLines = [];
}, },
_updateLine: function(n) { updateLine: function(n) {
var html; n = (typeof n != "undefined" ? n : this.cursorLine);
this.dirtyLines.push(n);
},
if (n == this.cursorLine) { updateScreen: function() {
var text = this.lineData[n]; this.dirtyLines = [];
html = text.slice(0, this.cursorCol).concat(['<span class="cursor">' + (text[this.cursorCol] || '') + "</span>"], text.slice(this.cursorCol + 1) || []);
} else { for (var l=0; l<this.lineData.length; l++) {
html = this.lineData[n]; this.dirtyLines.push(l);
} }
},
this.element.find(".line:eq(" + n + ")").html(html.join('')); setSGR: function(codes) {
if (codes.length == 0) {
codes = [0];
}
for (var i=0; i<codes.length; i++) {
var n = codes[i];
if (n === 0) {
this.fg = this.bg = undefined;
this.bright = false;
} else if (n == 1) {
this.bright = true;
} else if (n >= 30 && n <= 37) {
this.fg = n - 30;
} else if (n >= 40 && n <= 47) {
this.bg = n - 40;
}
}
}, },
setCursorPos: function(line, col) { setCursorPos: function(line, col) {
@ -101,27 +141,29 @@ SP.Terminal.prototype = {
}, },
cursorLeft: function() { cursorLeft: function() {
if (this.cursorCol > 0) if (this.cursorCol > 0) {
this.cursorCol = this.cursorCol - 1; this.cursorCol -= 1;
this.updateLine(); this.updateLine();
}
}, },
cursorRight: function() { cursorRight: function() {
if (this.cursorCol < this.cols) if (this.cursorCol < this.cols) {
this.cursorCol = this.cursorCol + 1; this.cursorCol += 1;
this.updateLine(); this.updateLine();
}
}, },
cursorUp: function() { cursorUp: function() {
if (this.cursorLine > 0) if (this.cursorLine > 0) {
this.cursorLine = this.cursorLine - 1; this.cursorLine -= 1;
this.updateLine(this.cursorLine); this.updateLine(this.cursorLine);
this.updateLine(this.cursorLine+1); this.updateLine(this.cursorLine+1);
}
}, },
cursorDown: function() { cursorDown: function() {
if (this.cursorLine < this.lines) this.cursorLine += 1;
this.cursorLine = this.cursorLine + 1;
this.updateLine(this.cursorLine); this.updateLine(this.cursorLine);
this.updateLine(this.cursorLine-1); this.updateLine(this.cursorLine-1);
}, },
@ -141,8 +183,8 @@ SP.Terminal.prototype = {
bs: function() { bs: function() {
if (this.cursorCol > 0) { if (this.cursorCol > 0) {
this.lineData[this.cursorLine][this.cursorCol - 1] = ' '; this.getLine()[this.cursorCol - 1] = ' ';
this.cursorCol = this.cursorCol - 1; this.cursorCol -= 1;
this.updateLine(); this.updateLine();
} }
}, },
@ -157,7 +199,7 @@ SP.Terminal.prototype = {
} }
this.fill(this.cursorLine, this.cursorCol, 1, text[i]); this.fill(this.cursorLine, this.cursorCol, 1, text[i]);
this.cursorCol = this.cursorCol + 1; this.cursorCol += 1;
} }
this.updateLine(); this.updateLine();
@ -165,8 +207,8 @@ SP.Terminal.prototype = {
eraseData: function(n) { eraseData: function(n) {
if (n == 0) { if (n == 0) {
this.eraseLine(n); this.eraseLine(0);
for (var l=this.cursorLine+1; l<this.lines; l++) { for (var l=this.cursorLine+1; l<this.lineData.length; l++) {
this.lineData[l] = []; this.lineData[l] = [];
this.updateLine(l); this.updateLine(l);
} }
@ -177,7 +219,7 @@ SP.Terminal.prototype = {
} }
this.eraseLine(n); this.eraseLine(n);
} else if (n == 2) { } else if (n == 2) {
for (var l=0; l<this.lines; l++) { for (var l=0; l<this.lineData.length; l++) {
this.lineData[l] = []; this.lineData[l] = [];
this.updateLine(l); this.updateLine(l);
} }
@ -189,21 +231,21 @@ SP.Terminal.prototype = {
this.fill(this.cursorLine, this.cursorCol, this.cols - this.cursorCol, ' '); this.fill(this.cursorLine, this.cursorCol, this.cols - this.cursorCol, ' ');
// this.lineData[this.cursorLine] = this.lineData[this.cursorLine].slice(0, this.cursorCol); // this.lineData[this.cursorLine] = this.lineData[this.cursorLine].slice(0, this.cursorCol);
// this.lineData[this.cursorLine] = this.lineData[this.cursorLine].slice(0, this.cursorCol) + " ".times(this.cols - this.cursorCol); // this.lineData[this.cursorLine] = this.lineData[this.cursorLine].slice(0, this.cursorCol) + " ".times(this.cols - this.cursorCol);
this.updateLine(this.cursorLine); this.updateLine();
} else if (n == 1) { } else if (n == 1) {
this.fill(this.cursorLine, 0, this.cursorCol, ' '); this.fill(this.cursorLine, 0, this.cursorCol, ' ');
// this.lineData[this.cursorLine] = " ".times(this.cursorCol).split('').concat(this.lineData[this.cursorLine].slice(this.cursorCol)); // this.lineData[this.cursorLine] = " ".times(this.cursorCol).split('').concat(this.lineData[this.cursorLine].slice(this.cursorCol));
// this.lineData[this.cursorLine] = " ".times(this.cursorCol) + this.lineData[this.cursorLine].slice(this.cursorCol); // this.lineData[this.cursorLine] = " ".times(this.cursorCol) + this.lineData[this.cursorLine].slice(this.cursorCol);
this.updateLine(this.cursorLine); this.updateLine();
} else if (n == 2) { } else if (n == 2) {
this.fill(this.cursorLine, 0, this.cols, ' '); this.fill(this.cursorLine, 0, this.cols, ' ');
// this.lineData[this.cursorLine] = [] // " ".times(this.cols); // this.lineData[this.cursorLine] = [] // " ".times(this.cols);
this.updateLine(this.cursorLine); this.updateLine();
} }
}, },
reserveCharacters: function(n) { reserveCharacters: function(n) {
var line = this.lineData[this.cursorLine]; var line = this.getLine();
this.lineData[this.cursorLine] = line.slice(0, this.cursorCol).concat(" ".times(n).split(''), line.slice(this.cursorCol, this.cols - n)); this.lineData[this.cursorLine] = line.slice(0, this.cursorCol).concat(" ".times(n).split(''), line.slice(this.cursorCol, this.cols - n));
this.updateLine(); this.updateLine();
}, },
@ -231,10 +273,11 @@ SP.Terminal.prototype = {
var char = prefix + char + postfix; var char = prefix + char + postfix;
var lineArr = this.getLine(line);
for (var i=0; i<n; i++) { for (var i=0; i<n; i++) {
this.lineData[line][col+i] = char; lineArr[col+i] = char;
} }
// this.lineData[line] = this.lineData[line].slice(0, col).concat(char, this.lineData[line].slice(col + 1));
}, },
blinkCursor: function() { blinkCursor: function() {

Loading…
Cancel
Save