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

openid
Marcin Kulik 13 years ago
parent eb9034ea15
commit 2a27089243

@ -59,17 +59,25 @@ SP.AnsiInterpreter.prototype = {
"\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)
// 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 + r = ?
if (match[1] == '1049') {
if (match[2] == 'h') {
// 1049 + h = Save cursor position, switch to alternate screen buffer, and clear screen.
this.terminal.saveCursor();
this.terminal.switchToAlternateBuffer();
this.terminal.clearScreen();
} 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();
}
} 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 rest = this.interpreter.feed(this.currentData);
this.terminal.updateDirtyLines();
this.terminal.renderDirtyLines();
var n = timing[1];
if (rest.length > 0)

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

Loading…
Cancel
Save