|
Home - Old Man Programmer
| Displaying webapps/vt100/script//vt100-fb.js
module.exports = {
terminal : {
FGMASK : 15,
BGMASK : 240,
BOLD : 256,
UNDERLINE : 512,
REVERSE : 1024,
BLINK : 2048,
sc : null,
m : null, row : null,
// m: { char : " ", fg : this.fg, bg: this.bg, flags: x };
rows : 0, cols : 0,
homeRow: 0, homeCol : 0,
tmargin: 0, bmargin: 0,
cx : 0, cy : 0,
cq : "", cqlen : 0,
// Attributes:
fg : 7, bg : 0,
bold: false, underline: false, blink: false, reverse: false,
mode : 0,
// 0 = normal, 1 = escape encountered:
// 2 = [ encountered, 3 = [? encountered,
// 4 = ) encountered, 5 = ( encountered
newrow : function(oldline) {
var m = [];
for(var c = 0; c < this.cols; c ++) {
if (oldline != undefined) {
m[c] = { char : " ", fg : oldline[c].fg, bg: oldline[c].bg, flags : 0};
} else {
m[c] = { char : " ", fg : this.fg, bg: this.bg, flags: 0 };
}
this.setColor(m[c], m[c].fg, m[c].bg);
}
return m;
},
scrollup : function() {
for(var r = this.tmargin; r < this.bmargin; r++) {
this.m[r] = this.m[r+1];
}
this.m[this.bmargin] = this.newrow();
},
scrolldown : function() {
for(var r = this.bmargin; r > this.tmargin; r--) {
this.m[r] = this.m[r-1];
}
this.m[this.tmargin] = this.newrow();
},
tab : function() {
this.cx = Math.min(this.cols-1, (8*Math.floor((this.cx+8)/8)));
},
cr : function() {
this.cx = 0;
},
down : function(lines, scroll) {
do {
if (this.cy == this.bmargin) {
if (scroll) this.scrollup();
} else this.cy++;
} while (--lines > 0);
},
up : function(lines, scroll) {
do {
if (this.cy == this.tmargin) {
if (scroll) this.scrolldown();
} else this.cy--;
} while (--lines > 0);
},
left : function(cols) {
this.cx = Math.max(0, this.cx-(cols?cols:1));
},
right : function(cols) {
this.cx = Math.min(this.cols-1, this.cx + (cols? cols : 1));
},
move : function(y, x) {
this.cy = Math.max(Math.min(this.rows-1,y-1), 0);
this.cx = Math.max(Math.min(this.cols-1,x-1), 0);
},
clrline : function(r, s, e) {
var m = this.m[r];
for(var c = s; c <= e; c++) {
m[c].char = " ";
this.setColor(m[c], this.fg, this.bg);
}
},
eid : function(n) {
switch(n) {
case 0: // erase cursor to eos
this.clrline(this.cy, this.cx, this.cols-1);
for(var r = this.cy+1; r < this.rows; r++)
this.clrline(r, 0, this.cols-1);
break;
case 1: // start of screen to cursor
for(var r = 0; r < this.cy; r++)
this.clrline(r, 0, this.cols-1);
this.clrline(this.cy, 0, this.cx);
break;
case 2: // clear screen
for(var r = 0; r < this.rows; r++)
this.clrline(r, 0, this.cols-1);
}
},
eil : function(n) {
switch(n) {
case 0: // erase cursor to eol
return this.clrline(this.cy, this.cx, this.cols-1);
case 1: // erase from bol to cursor
return this.clrline(this.cy, 0, this.cx);
case 2: // erase entire line
return this.clrline(this.cy, 0, this.cols-1);
}
},
setMargins : function(t, b) {
t = Math.min(Math.max(0, t-1), this.rows-2);
b = Math.min(Math.max(0, b-1), this.rows-1);
if (t == 0 && b == 0) b = this.rows-1;
if (t >= b) return;
this.tmargin = t;
this.bmargin = b;
this.move(this.homeRow, this.homeCol);
return;
},
setAttrs : function(pn) {
var v, l = Math.max(this.cqlen, 1);
if (this.cqlen == 0) pn[0] = 0;
while (l-- > 0) {
switch(v = pn[0]) {
case 0:
this.fg = 7; this.bg = 0;
this.bold = this.underline = this.blink = this.reverse = false;
break;
case 1:
this.bold = true;
break;
case 4:
this.underline = true;
break;
case 5:
this.blink = true;
break;
case 7:
this.reverse = true;
break;
case 8:
this.fg = this.bg;
break;
case 21:
this.bold = false;
break;
case 24:
this.underline = false;
break;
case 27:
this.reverse = false;
break;
case 28:
this.fg = 0;
break;
default:
if (v >= 30 && v <= 37) this.fg = v-30;
else if (v >= 40 && v <= 47) this.bg = v-40;
else if (v >= 90 && v <= 97) this.fg = (v-90)+8;
else if (v >= 100 && v <= 107) this.bg = (v-100)+8;
break;
}
pn.shift();
}
},
normal : function(ch) {
switch(ch) {
case '\033':
this.mode = 1;
return;
case '\007': return;
case '\b': return this.left(1);
case '\t': return this.tab();
case '\n':
case '\v':
case '\f': return this.down(1,true);
case '\r': return this.cr();
default:
if (ch < ' ' || ch == 127) return;
}
var m = this.m[this.cy][this.cx];
m.char = ch;
if (this.reverse) this.setColor(m,this.colorInverse(this.fg), this.colorInverse(this.bg));
else this.setColor(m, this.fg, this.bg);
m.flags = 0;
if (this.underline) m.flags |= this.UNDERLINE;
if (this.bold) m.flags |= this.BOLD;
this.cx++;
if (this.cx >= this.cols) {
this.cx = 0;
if (this.cy+1 >= this.rows) this.scrollup();
else this.cy++;
}
},
parsecq : function() {
if (this.cq.length == 0) return [ 0, 0 ];
var a = [0, 0], s = this.cq.split(";");
for(var i = 0; i < s.length; i++) {
a[i] = parseInt(s[i]);
}
this.cqlen = s.length;
this.cq = "";
return a;
},
qmode : function(ch) {
if (ch >= '0' && ch <='9' || ch == ';') this.cq += ch;
else {
this.mode = 0;
var pn = this.parsecq();
switch(ch) {
case 'l':
break;
case 'h':
break;
}
}
},
brac: function(ch) {
if (ch >= '0' && ch <='9' || ch == ';') this.cq += ch;
else {
this.mode = 0;
var pn = this.parsecq();
switch(ch) {
case 'A': // up
return this.up(pn[0], false);
case 'B': // down
return this.down(pn[0], false);
case 'C': // right
return this.right(pn[0]);
case 'D': // left
return this.left(pn[0]);
case 'f':
case 'H':
return this.move(pn[0], pn[1]);
case 'J':
return this.eid(pn[0]);
case 'K':
return this.eil(pn[0]);
case 'r':
return this.setMargins(pn[0], pn[1]);
case 'm':
return this.setAttrs(pn);
case '?':
if (this.cqlen == 0) this.mode = 3;
return;
default:
}
}
},
escape : function(ch) {
this.mode = 0;
switch(ch) {
case '[': return this.cq = "", this.mode = 2;
case '(': return this.cq = "", this.mode = 3;
case ')': return this.cq = "", this.mode = 4;
case 'c': return this.reset();
case 'D': return this.down(1,true);
case 'M': return this.up(1,true);
case 'E':
this.cr();
this.down(1, true);
return;
case '7':
this.sc = { cy : this.cy, cx : this.cx, cset : null };
return;
case '8':
this.cx = this.sc.cx; this.cy = this.sc.cy;
return;
default:
}
},
addch : function(ch) {
switch(this.mode) {
case 3: return this.qmode(ch);
case 2: return this.brac(ch);
case 1: return this.escape(ch);
case 0:
default:
this.normal(ch);
}
},
addstr : function(s) {
for(var i = 0; i < s.length; i++) {
this.addch(s[i]);
}
},
reset : function() {
this.homeRow = this.homeCol = this.cx = this.cy = this.mode = 0;
this.sc = { cy : 0, cx: 0, charset: null };
this.tmargin = 0; this.bmargin = this.rows-1;
this.fg = 7; this.bg = 0;
this.bold = this.underline = this.blink = this.reverse = false;
this.m = [];
for(var r = 0; r < this.rows; r++) {
this.m[r] = this.newrow();
}
},
dumpstate: function() {
var rows = [];
for(var r = 0; r < this.rows; r++) {
var cdata = "";
var adata = [];
for(var c = 0; c < this.cols; c++) {
var m = this.m[r][c];
cdata += m.char;
adata.push(m.fg | m.bg <<4 | m.flags);
}
rows.push({c:cdata, a: adata});
}
return {
cx: this.cx, cy: this.cy, sc: this.sc, mode : this.mode, cq: this.cq,
tmargin: this.tmargin, bmargin: this.bmargin,
fg: this.fg, bg: this.bg, bold: this.bold, underline: this.underline,
blink: this.blink, reverse: this.reverse,
m: rows
};
},
init: function(w, h) {
this.rows = h;
this.cols = w;
this.reset();
},
colorInverse : function(color) {
if (color < 8) return 7-color;
return 15-color;
},
setColor : function(m, f, b) {
m.fg = f;
m.bg = b;
},
}
};
|