Make the emulator screen resizable.
This commit is contained in:
parent
5b0be4c820
commit
02cc454ad1
4 changed files with 95 additions and 12 deletions
|
|
@ -405,7 +405,7 @@ function textsize(larger) {
|
||||||
nsize = 48;
|
nsize = 48;
|
||||||
}
|
}
|
||||||
document.getElementById("term").style.fontSize = nsize.toString() + "px";
|
document.getElementById("term").style.fontSize = nsize.toString() + "px";
|
||||||
termemu.resize();
|
termemu.fixsize();
|
||||||
debug(1, "Changing font size to " + nsize.toString());
|
debug(1, "Changing font size to " + nsize.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
shterm.js
10
shterm.js
|
|
@ -270,7 +270,7 @@ function vkey(c) {
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
keyHexCodes.init();
|
keyHexCodes.init();
|
||||||
termemu.init("termwrap", 25, 80);
|
termemu.init("termwrap", 24, 80);
|
||||||
setTitle("Not connected.");
|
setTitle("Not connected.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -295,7 +295,7 @@ function togglectrl() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function login() {
|
function login(h, w) {
|
||||||
if (termemu.alive)
|
if (termemu.alive)
|
||||||
return;
|
return;
|
||||||
var req = new XMLHttpRequest();
|
var req = new XMLHttpRequest();
|
||||||
|
|
@ -304,6 +304,8 @@ function login() {
|
||||||
var datalines = req.responseText.split("\n");
|
var datalines = req.responseText.split("\n");
|
||||||
if (datalines[0] == 'l1') {
|
if (datalines[0] == 'l1') {
|
||||||
/* Success */
|
/* Success */
|
||||||
|
// FIXME extract the size from the response instead of hardcoding
|
||||||
|
termemu.resize(25, 80);
|
||||||
termemu.alive = true;
|
termemu.alive = true;
|
||||||
setTitle("Logged in");
|
setTitle("Logged in");
|
||||||
debug(1, "Logged in with id " + datalines[1]);
|
debug(1, "Logged in with id " + datalines[1]);
|
||||||
|
|
@ -314,7 +316,7 @@ function login() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
req.open('POST', '/login', true);
|
req.open('POST', '/login', true);
|
||||||
req.send("login=login");
|
req.send("login=login&h=" + String(h) + "&w=" + String(w));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,7 +390,7 @@ function textsize(larger) {
|
||||||
nsize = 48;
|
nsize = 48;
|
||||||
}
|
}
|
||||||
document.getElementById("term").style.fontSize = nsize.toString() + "px";
|
document.getElementById("term").style.fontSize = nsize.toString() + "px";
|
||||||
termemu.resize();
|
termemu.fixsize();
|
||||||
debug(1, "Changing font size to " + nsize.toString());
|
debug(1, "Changing font size to " + nsize.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
62
termemu.js
62
termemu.js
|
|
@ -54,6 +54,7 @@ function Cursor(src) {
|
||||||
// An object representing the terminal emulator.
|
// An object representing the terminal emulator.
|
||||||
var termemu = {
|
var termemu = {
|
||||||
sessid: null, // Session key assigned by the server
|
sessid: null, // Session key assigned by the server
|
||||||
|
alive: false,
|
||||||
/* Some elements of the page. */
|
/* Some elements of the page. */
|
||||||
inwrap: null, // A non-table div wrapping the screen
|
inwrap: null, // A non-table div wrapping the screen
|
||||||
view: null, // The div holding the terminal screen
|
view: null, // The div holding the terminal screen
|
||||||
|
|
@ -192,14 +193,67 @@ var termemu = {
|
||||||
/* Attach them. */
|
/* Attach them. */
|
||||||
this.view = termdiv;
|
this.view = termdiv;
|
||||||
this.screen = this.normbuf;
|
this.screen = this.normbuf;
|
||||||
this.resize();
|
this.fixsize();
|
||||||
this.cmove(0, 0);
|
this.cmove(0, 0);
|
||||||
},
|
},
|
||||||
|
resize: function (h, w) {
|
||||||
|
if (this.screen == null)
|
||||||
|
return;
|
||||||
|
if (!(h > 0 && h < 256))
|
||||||
|
h = this.h;
|
||||||
|
if (!(w > 0 && w < 256))
|
||||||
|
w = this.w;
|
||||||
|
/* First give all the rows the right number of cells. */
|
||||||
|
var allrows = Array().concat(this.histbuf.childNodes,
|
||||||
|
this.normbuf.childNodes,
|
||||||
|
this.altbuf.childNodes);
|
||||||
|
for (var i = 0; i < allrows.length; i++) {
|
||||||
|
var row = allrows[i];
|
||||||
|
for (var j = Math.min(w, this.w); j < Math.max(w, this.w); j++) {
|
||||||
|
if (w < this.w)
|
||||||
|
row.removeChild(row.childNodes.lastChild);
|
||||||
|
else
|
||||||
|
row.appendChild(this.makeCell(' '));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.w = w;
|
||||||
|
/* Now the rows. */
|
||||||
|
/* Resizing altbuf isn't always necessary. */
|
||||||
|
/* TODO resize and scrolling region interact in complicated ways that I
|
||||||
|
* don't want to reverse-engineer. For the moment, just don't do that.
|
||||||
|
*/
|
||||||
|
if (h > this.h) {
|
||||||
|
for (var i = this.h; i < h; i++) {
|
||||||
|
this.normbuf.appendChild(this.makeRow());
|
||||||
|
this.altbuf.appendChild(this.makeRow());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (h < this.h) {
|
||||||
|
for (var i = h; i < this.h; i++) {
|
||||||
|
this.histbuf.appendChild(this.normbuf.firstChild);
|
||||||
|
if (this.altbuf.firstChild)
|
||||||
|
this.altbuf.removeChild(this.altbuf.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Keep it on the bottom */
|
||||||
|
if (this.scrB == this.h - 1)
|
||||||
|
this.scrB = h - 1;
|
||||||
|
else if (this.scrB >= h)
|
||||||
|
this.scrB = h - 1;
|
||||||
|
if (this.scrT >= h - 1)
|
||||||
|
this.scrT = 0;
|
||||||
|
this.h = h;
|
||||||
|
this.fixsize();
|
||||||
|
/* If the cursor is now offscreen, cmove()'s sanity checks will fix it. */
|
||||||
|
this.cmove(null, null);
|
||||||
|
debug(1, "Size is now " + this.w + "x" + this.h);
|
||||||
|
return;
|
||||||
|
},
|
||||||
valign: function () {
|
valign: function () {
|
||||||
if (this.screen == this.normbuf)
|
if (this.screen == this.normbuf)
|
||||||
this.inwrap.scrollTop = this.histbuf.clientHeight;
|
this.inwrap.scrollTop = this.histbuf.clientHeight;
|
||||||
},
|
},
|
||||||
resize: function () {
|
fixsize: function () {
|
||||||
var owrap = document.getElementById("termwrap");
|
var owrap = document.getElementById("termwrap");
|
||||||
/* Set the height up properly. */
|
/* Set the height up properly. */
|
||||||
this.inwrap.style.height = this.screen.scrollHeight.toString() + "px";
|
this.inwrap.style.height = this.screen.scrollHeight.toString() + "px";
|
||||||
|
|
@ -215,7 +269,9 @@ var termemu = {
|
||||||
flipCursor: function () {
|
flipCursor: function () {
|
||||||
/* Swaps the text and background colors of the active location. */
|
/* Swaps the text and background colors of the active location. */
|
||||||
/* This will change when other cursor styles are supported. */
|
/* This will change when other cursor styles are supported. */
|
||||||
if (this.c.x != null && this.c.y != null) {
|
/* Check: the cursor might be offscreen if it was resized. */
|
||||||
|
if (this.c.x != null && this.c.y != null && this.c.x >= 0 &&
|
||||||
|
this.c.x < this.w && this.c.y >= 0 && this.c.y < this.h) {
|
||||||
var oldcell = this.screen.childNodes[this.c.y].childNodes[this.c.x];
|
var oldcell = this.screen.childNodes[this.c.y].childNodes[this.c.x];
|
||||||
var tempswap = oldcell.style.color;
|
var tempswap = oldcell.style.color;
|
||||||
oldcell.style.color = oldcell.style.backgroundColor;
|
oldcell.style.color = oldcell.style.backgroundColor;
|
||||||
|
|
|
||||||
33
webtty.js
33
webtty.js
|
|
@ -14,13 +14,23 @@ var env_dontuse = {"TMUX": true, "TMUX_PANE": true};
|
||||||
/* Constructor for TermSessions. Note that it opens the terminal and
|
/* Constructor for TermSessions. Note that it opens the terminal and
|
||||||
* adds itself to the sessions dict.
|
* adds itself to the sessions dict.
|
||||||
*/
|
*/
|
||||||
function TermSession(sessid) {
|
function TermSession(sessid, h, w) {
|
||||||
|
/* Set up the sizes. */
|
||||||
|
w = Math.floor(Number(w));
|
||||||
|
if (!(w > 0 && w < 256))
|
||||||
|
w = 80;
|
||||||
|
this.w = w;
|
||||||
|
h = Math.floor(Number(h));
|
||||||
|
if (!(h > 0 && h < 256))
|
||||||
|
h = 25;
|
||||||
|
this.h = h;
|
||||||
|
/* Customize the environment. */
|
||||||
var childenv = {};
|
var childenv = {};
|
||||||
for (var key in process.env) {
|
for (var key in process.env) {
|
||||||
if (!(key in env_dontuse))
|
if (!(key in env_dontuse))
|
||||||
childenv[key] = process.env[key];
|
childenv[key] = process.env[key];
|
||||||
}
|
}
|
||||||
childenv["PTYHELPER"] = "25x80";
|
childenv["PTYHELPER"] = String(this.h) + "x" + String(this.w);
|
||||||
// Should setsid get set?
|
// Should setsid get set?
|
||||||
var spawnopts = {"env": childenv, "cwd": process.env["HOME"]};
|
var spawnopts = {"env": childenv, "cwd": process.env["HOME"]};
|
||||||
this.child = child_process.spawn(ptyhelp, ["bash"], spawnopts);
|
this.child = child_process.spawn(ptyhelp, ["bash"], spawnopts);
|
||||||
|
|
@ -154,10 +164,25 @@ function getFormValues(formtext) {
|
||||||
function login(req, res, formdata) {
|
function login(req, res, formdata) {
|
||||||
var resheaders = {'Content-Type': 'text/plain'};
|
var resheaders = {'Content-Type': 'text/plain'};
|
||||||
var sessid = randkey();
|
var sessid = randkey();
|
||||||
var nsession = new TermSession(sessid);
|
/* The TermSession constructor will check these thoroughly too, but
|
||||||
|
* you can't be too suspicious of client-supplied data. */
|
||||||
|
var w = 80;
|
||||||
|
var h = 25;
|
||||||
|
var t;
|
||||||
|
if ("w" in formdata) {
|
||||||
|
t = Math.floor(Number(formdata["w"]));
|
||||||
|
if (t > 0 && t < 256)
|
||||||
|
w = t;
|
||||||
|
}
|
||||||
|
if ("h" in formdata) {
|
||||||
|
t = Math.floor(Number(formdata["h"]));
|
||||||
|
if (t > 0 && t < 256)
|
||||||
|
h = t;
|
||||||
|
}
|
||||||
|
var nsession = new TermSession(sessid, h, w);
|
||||||
resheaders["Set-Cookie"] = "ID=" + sessid;
|
resheaders["Set-Cookie"] = "ID=" + sessid;
|
||||||
res.writeHead(200, resheaders);
|
res.writeHead(200, resheaders);
|
||||||
res.write("l1\n" + sessid + "\n");
|
res.write("l1\n" + sessid + "\n" + String(h) + "x" + String(w) + "\n");
|
||||||
res.end();
|
res.end();
|
||||||
console.log("Started new session with key " + sessid + ", pid " + nsession.child.pid);
|
console.log("Started new session with key " + sessid + ", pid " + nsession.child.pid);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue