Enable switching between 80 and 132 column mode, if the browser supports

CSS transforms.


git-svn-id: https://shellinabox.googlecode.com/svn/trunk@190 0da03de8-d603-11dd-86c2-0f8696b7b6f9
This commit is contained in:
zodiac@gmail.com 2009-11-25 23:56:56 +00:00
parent 99169cff6a
commit 7862fb99be
8 changed files with 407 additions and 126 deletions

View file

@ -1,3 +1,8 @@
2009-11-25 Markus Gutschke <markus@shellinabox.com>
* On browsers that support CSS transforms, enable switching between
80 and 132 column mode.
2009-11-21 Markus Gutschke <markus@shellinabox.com>
* Updated manual page documenting --user-css

View file

@ -138,7 +138,7 @@
#define STDC_HEADERS 1
/* Most recent revision number in the version control system */
#define VCS_REVISION "189"
#define VCS_REVISION "190"
/* Version number of package */
#define VERSION "2.10"

2
configure vendored
View file

@ -2319,7 +2319,7 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
VCS_REVISION=189
VCS_REVISION=190
cat >>confdefs.h <<_ACEOF

View file

@ -2,7 +2,7 @@ AC_PREREQ(2.57)
dnl This is the one location where the authoritative version number is stored
AC_INIT(shellinabox, 2.10, markus@shellinabox.com)
VCS_REVISION=189
VCS_REVISION=190
AC_SUBST(VCS_REVISION)
AC_DEFINE_UNQUOTED(VCS_REVISION, "${VCS_REVISION}",
[Most recent revision number in the version control system])

View file

@ -220,7 +220,7 @@ VT100.prototype.reset = function(clearHistory) {
this.GMap = [ this.Latin1Map,
this.VT100GraphicsMap,
this.CodePage437Map,
this.DirectToFontMap ];
this.DirectToFontMap];
this.translate = this.GMap[this.useGMap];
this.top = 0;
this.bottom = this.terminalHeight;
@ -236,6 +236,31 @@ VT100.prototype.reset = function(clearHistory) {
}
this.enableAlternateScreen(false);
var wasCompressed = false;
var styles = [ 'transform',
'WebkitTransform',
'MozTransform',
'filter' ];
for (var i = 0; i < styles.length; ++i) {
if (typeof this.console[0].style[styles[i]] != 'undefined') {
for (var j = 0; j < 1; ++j) {
wasCompressed |= this.console[j].style[styles[i]] != '';
this.console[j].style[styles[i]] = '';
}
this.cursor.style[styles[i]] = '';
this.space.style[styles[i]] = '';
if (styles[i] == 'filter') {
this.console[this.currentScreen].style.width = '';
}
break;
}
}
this.scale = 1.0;
if (wasCompressed) {
this.resizer();
}
this.gotoXY(0, 0);
this.showCursor();
this.isInverted = false;
@ -658,6 +683,7 @@ VT100.prototype.initializeElements = function(container) {
this.numScrollbackLines = 0;
this.top = 0;
this.bottom = 0x7FFFFFFF;
this.scale = 1.0;
this.resizer();
this.focusCursor();
this.input.focus();
@ -833,7 +859,8 @@ VT100.prototype.resizer = function() {
}
// Reposition the reconnect button
this.reconnectBtn.style.left = (this.terminalWidth*this.cursorWidth -
this.reconnectBtn.style.left = (this.terminalWidth*this.cursorWidth/
this.scale -
this.reconnectBtn.clientWidth)/2 + 'px';
this.reconnectBtn.style.top = (this.terminalHeight*this.cursorHeight-
this.reconnectBtn.clientHeight)/2 + 'px';
@ -849,7 +876,8 @@ VT100.prototype.showCurrentSize = function() {
this.curSizeBox.innerHTML = '' + this.terminalWidth + 'x' +
this.terminalHeight;
this.curSizeBox.style.left =
(this.terminalWidth*this.cursorWidth -
(this.terminalWidth*this.cursorWidth/
this.scale -
this.curSizeBox.clientWidth)/2 + 'px';
this.curSizeBox.style.top =
(this.terminalHeight*this.cursorHeight -
@ -1119,7 +1147,7 @@ VT100.prototype.insertBlankLine = function(y, color, style) {
VT100.prototype.updateWidth = function() {
this.terminalWidth = Math.floor(this.console[this.currentScreen].offsetWidth/
this.cursorWidth);
this.cursorWidth*this.scale);
return this.terminalWidth;
};
@ -1415,11 +1443,12 @@ VT100.prototype.putString = function(x, y, text, color, style) {
}
}
if (pixelX >= 0) {
this.cursor.style.left = (pixelX + (this.isIE ? 1 : 0)) + 'px';
this.cursor.style.left = (pixelX + (this.isIE ? 1 : 0))/
this.scale + 'px';
} else {
this.setTextContent(this.space, this.spaces(this.cursorX));
this.cursor.style.left = this.space.offsetWidth +
console.offsetLeft + 'px';
this.cursor.style.left = (this.space.offsetWidth +
console.offsetLeft)/this.scale + 'px';
}
this.cursorY = yIdx - this.numScrollbackLines;
if (pixelY >= 0) {
@ -1532,6 +1561,31 @@ VT100.prototype.enableAlternateScreen = function(state) {
this.currentScreen = state ? 1 : 0;
this.console[1-this.currentScreen].style.display = 'none';
this.console[this.currentScreen].style.display = '';
// Select appropriate character pitch.
var styles = [ 'transform',
'WebkitTransform',
'MozTransform',
'filter' ];
for (var i = 0; i < styles.length; ++i) {
if (typeof this.console[0].style[styles[i]] != 'undefined') {
if (state) {
// Upon enabling the alternate screen, we switch to 80 column mode. But
// upon returning to the regular screen, we restore the mode that was
// in effect previously.
this.console[1].style[styles[i]] = '';
}
var style =
this.console[this.currentScreen].style[styles[i]];
this.cursor.style[styles[i]] = style;
this.space.style[styles[i]] = style;
this.scale = style == '' ? 1.0:1.65;
if (styles[i] == 'filter') {
this.console[this.currentScreen].style.width = style == '' ? '165%':'';
}
break;
}
}
this.resizer();
// If we switched to the alternate screen, reset it completely. Otherwise,
@ -1901,7 +1955,7 @@ VT100.prototype.toggleBell = function() {
};
VT100.prototype.about = function() {
alert("VT100 Terminal Emulator " + "2.10 (revision 189)" +
alert("VT100 Terminal Emulator " + "2.10 (revision 190)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com");
};
@ -2814,12 +2868,50 @@ VT100.prototype.restoreCursor = function() {
this.savedY[this.currentScreen]);
};
VT100.prototype.set80_132Mode = function(state) {
var transform = undefined;
var styles = [ 'transform',
'WebkitTransform',
'MozTransform',
'filter'
];
for (var i = 0; i < styles.length; ++i) {
if (typeof this.console[0].style[styles[i]] != 'undefined') {
transform = styles[i];
break;
}
}
if (transform) {
if ((this.console[this.currentScreen].style[transform] != '') == state) {
return;
}
var style =
state ? transform == 'filter'
? 'progid:DXImageTransform.Microsoft.Matrix(' +
'M11=0.606060606060606060606,M12=0,M21=0,M22=1,' +
"sizingMethod='auto expand')"
: 'translateX(-50%) ' +
'scaleX(0.606060606060606060606) ' +
'translateX(50%)'
: '';
this.console[this.currentScreen].style[transform] = style;
this.cursor.style[transform] = style;
this.space.style[transform] = style;
this.scale = state ? 1.65 : 1.0;
if (transform == 'filter') {
this.console[this.currentScreen].style.width = state ? '165%' : '';
}
this.resizer();
}
};
VT100.prototype.setMode = function(state) {
for (var i = 0; i <= this.npar; i++) {
if (this.isQuestionMark) {
switch (this.par[i]) {
case 1: this.cursorKeyMode = state; break;
case 3: /* Toggling between 80/132 mode is not implemented */ break;
case 3: this.set80_132Mode(state); break;
case 5: this.isInverted = state; this.refreshInvertedState(); break;
case 6: this.offsetMode = state; break;
case 7: this.autoWrapMode = state; break;

View file

@ -358,7 +358,7 @@ ShellInABox.prototype.extendContextMenu = function(entries, actions) {
};
ShellInABox.prototype.about = function() {
alert("Shell In A Box version " + "2.10 (revision 189)" +
alert("Shell In A Box version " + "2.10 (revision 190)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com" +
(typeof serverSupportsSSL != 'undefined' && serverSupportsSSL ?

View file

@ -220,7 +220,7 @@ VT100.prototype.reset = function(clearHistory) {
this.GMap = [ this.Latin1Map,
this.VT100GraphicsMap,
this.CodePage437Map,
this.DirectToFontMap ];
this.DirectToFontMap];
this.translate = this.GMap[this.useGMap];
this.top = 0;
this.bottom = this.terminalHeight;
@ -236,6 +236,31 @@ VT100.prototype.reset = function(clearHistory) {
}
this.enableAlternateScreen(false);
var wasCompressed = false;
var styles = [ 'transform',
'WebkitTransform',
'MozTransform',
'filter' ];
for (var i = 0; i < styles.length; ++i) {
if (typeof this.console[0].style[styles[i]] != 'undefined') {
for (var j = 0; j < 1; ++j) {
wasCompressed |= this.console[j].style[styles[i]] != '';
this.console[j].style[styles[i]] = '';
}
this.cursor.style[styles[i]] = '';
this.space.style[styles[i]] = '';
if (styles[i] == 'filter') {
this.console[this.currentScreen].style.width = '';
}
break;
}
}
this.scale = 1.0;
if (wasCompressed) {
this.resizer();
}
this.gotoXY(0, 0);
this.showCursor();
this.isInverted = false;
@ -658,6 +683,7 @@ VT100.prototype.initializeElements = function(container) {
this.numScrollbackLines = 0;
this.top = 0;
this.bottom = 0x7FFFFFFF;
this.scale = 1.0;
this.resizer();
this.focusCursor();
this.input.focus();
@ -833,7 +859,8 @@ VT100.prototype.resizer = function() {
}
// Reposition the reconnect button
this.reconnectBtn.style.left = (this.terminalWidth*this.cursorWidth -
this.reconnectBtn.style.left = (this.terminalWidth*this.cursorWidth/
this.scale -
this.reconnectBtn.clientWidth)/2 + 'px';
this.reconnectBtn.style.top = (this.terminalHeight*this.cursorHeight-
this.reconnectBtn.clientHeight)/2 + 'px';
@ -849,7 +876,8 @@ VT100.prototype.showCurrentSize = function() {
this.curSizeBox.innerHTML = '' + this.terminalWidth + 'x' +
this.terminalHeight;
this.curSizeBox.style.left =
(this.terminalWidth*this.cursorWidth -
(this.terminalWidth*this.cursorWidth/
this.scale -
this.curSizeBox.clientWidth)/2 + 'px';
this.curSizeBox.style.top =
(this.terminalHeight*this.cursorHeight -
@ -1119,7 +1147,7 @@ VT100.prototype.insertBlankLine = function(y, color, style) {
VT100.prototype.updateWidth = function() {
this.terminalWidth = Math.floor(this.console[this.currentScreen].offsetWidth/
this.cursorWidth);
this.cursorWidth*this.scale);
return this.terminalWidth;
};
@ -1415,11 +1443,12 @@ VT100.prototype.putString = function(x, y, text, color, style) {
}
}
if (pixelX >= 0) {
this.cursor.style.left = (pixelX + (this.isIE ? 1 : 0)) + 'px';
this.cursor.style.left = (pixelX + (this.isIE ? 1 : 0))/
this.scale + 'px';
} else {
this.setTextContent(this.space, this.spaces(this.cursorX));
this.cursor.style.left = this.space.offsetWidth +
console.offsetLeft + 'px';
this.cursor.style.left = (this.space.offsetWidth +
console.offsetLeft)/this.scale + 'px';
}
this.cursorY = yIdx - this.numScrollbackLines;
if (pixelY >= 0) {
@ -1532,6 +1561,31 @@ VT100.prototype.enableAlternateScreen = function(state) {
this.currentScreen = state ? 1 : 0;
this.console[1-this.currentScreen].style.display = 'none';
this.console[this.currentScreen].style.display = '';
// Select appropriate character pitch.
var styles = [ 'transform',
'WebkitTransform',
'MozTransform',
'filter' ];
for (var i = 0; i < styles.length; ++i) {
if (typeof this.console[0].style[styles[i]] != 'undefined') {
if (state) {
// Upon enabling the alternate screen, we switch to 80 column mode. But
// upon returning to the regular screen, we restore the mode that was
// in effect previously.
this.console[1].style[styles[i]] = '';
}
var style =
this.console[this.currentScreen].style[styles[i]];
this.cursor.style[styles[i]] = style;
this.space.style[styles[i]] = style;
this.scale = style == '' ? 1.0:1.65;
if (styles[i] == 'filter') {
this.console[this.currentScreen].style.width = style == '' ? '165%':'';
}
break;
}
}
this.resizer();
// If we switched to the alternate screen, reset it completely. Otherwise,
@ -1901,7 +1955,7 @@ VT100.prototype.toggleBell = function() {
};
VT100.prototype.about = function() {
alert("VT100 Terminal Emulator " + "2.10 (revision 189)" +
alert("VT100 Terminal Emulator " + "2.10 (revision 190)" +
"\nCopyright 2008-2009 by Markus Gutschke\n" +
"For more information check http://shellinabox.com");
};
@ -2814,12 +2868,50 @@ VT100.prototype.restoreCursor = function() {
this.savedY[this.currentScreen]);
};
VT100.prototype.set80_132Mode = function(state) {
var transform = undefined;
var styles = [ 'transform',
'WebkitTransform',
'MozTransform',
'filter'
];
for (var i = 0; i < styles.length; ++i) {
if (typeof this.console[0].style[styles[i]] != 'undefined') {
transform = styles[i];
break;
}
}
if (transform) {
if ((this.console[this.currentScreen].style[transform] != '') == state) {
return;
}
var style =
state ? transform == 'filter'
? 'progid:DXImageTransform.Microsoft.Matrix(' +
'M11=0.606060606060606060606,M12=0,M21=0,M22=1,' +
"sizingMethod='auto expand')"
: 'translateX(-50%) ' +
'scaleX(0.606060606060606060606) ' +
'translateX(50%)'
: '';
this.console[this.currentScreen].style[transform] = style;
this.cursor.style[transform] = style;
this.space.style[transform] = style;
this.scale = state ? 1.65 : 1.0;
if (transform == 'filter') {
this.console[this.currentScreen].style.width = state ? '165%' : '';
}
this.resizer();
}
};
VT100.prototype.setMode = function(state) {
for (var i = 0; i <= this.npar; i++) {
if (this.isQuestionMark) {
switch (this.par[i]) {
case 1: this.cursorKeyMode = state; break;
case 3: /* Toggling between 80/132 mode is not implemented */ break;
case 3: this.set80_132Mode(state); break;
case 5: this.isInverted = state; this.refreshInvertedState(); break;
case 6: this.offsetMode = state; break;
case 7: this.autoWrapMode = state; break;

View file

@ -220,7 +220,7 @@ VT100.prototype.reset = function(clearHistory) {
this.GMap = [ this.Latin1Map,
this.VT100GraphicsMap,
this.CodePage437Map,
this.DirectToFontMap ];
this.DirectToFontMap];
this.translate = this.GMap[this.useGMap];
this.top = 0;
this.bottom = this.terminalHeight;
@ -236,6 +236,31 @@ VT100.prototype.reset = function(clearHistory) {
}
this.enableAlternateScreen(false);
var wasCompressed = false;
var styles = [ 'transform',
'WebkitTransform',
'MozTransform',
'filter' ];
for (var i = 0; i < styles.length; ++i) {
if (typeof this.console[0].style[styles[i]] != 'undefined') {
for (var j = 0; j < 1; ++j) {
wasCompressed |= this.console[j].style[styles[i]] != '';
this.console[j].style[styles[i]] = '';
}
this.cursor.style[styles[i]] = '';
this.space.style[styles[i]] = '';
if (styles[i] == 'filter') {
this.console[this.currentScreen].style.width = '';
}
break;
}
}
this.scale = 1.0;
if (wasCompressed) {
this.resizer();
}
this.gotoXY(0, 0);
this.showCursor();
this.isInverted = false;
@ -658,6 +683,7 @@ VT100.prototype.initializeElements = function(container) {
this.numScrollbackLines = 0;
this.top = 0;
this.bottom = 0x7FFFFFFF;
this.scale = 1.0;
this.resizer();
this.focusCursor();
this.input.focus();
@ -833,7 +859,8 @@ VT100.prototype.resizer = function() {
}
// Reposition the reconnect button
this.reconnectBtn.style.left = (this.terminalWidth*this.cursorWidth -
this.reconnectBtn.style.left = (this.terminalWidth*this.cursorWidth/
this.scale -
this.reconnectBtn.clientWidth)/2 + 'px';
this.reconnectBtn.style.top = (this.terminalHeight*this.cursorHeight-
this.reconnectBtn.clientHeight)/2 + 'px';
@ -849,7 +876,8 @@ VT100.prototype.showCurrentSize = function() {
this.curSizeBox.innerHTML = '' + this.terminalWidth + 'x' +
this.terminalHeight;
this.curSizeBox.style.left =
(this.terminalWidth*this.cursorWidth -
(this.terminalWidth*this.cursorWidth/
this.scale -
this.curSizeBox.clientWidth)/2 + 'px';
this.curSizeBox.style.top =
(this.terminalHeight*this.cursorHeight -
@ -1119,7 +1147,7 @@ VT100.prototype.insertBlankLine = function(y, color, style) {
VT100.prototype.updateWidth = function() {
this.terminalWidth = Math.floor(this.console[this.currentScreen].offsetWidth/
this.cursorWidth);
this.cursorWidth*this.scale);
return this.terminalWidth;
};
@ -1415,11 +1443,12 @@ VT100.prototype.putString = function(x, y, text, color, style) {
}
}
if (pixelX >= 0) {
this.cursor.style.left = (pixelX + (this.isIE ? 1 : 0)) + 'px';
this.cursor.style.left = (pixelX + (this.isIE ? 1 : 0))/
this.scale + 'px';
} else {
this.setTextContent(this.space, this.spaces(this.cursorX));
this.cursor.style.left = this.space.offsetWidth +
console.offsetLeft + 'px';
this.cursor.style.left = (this.space.offsetWidth +
console.offsetLeft)/this.scale + 'px';
}
this.cursorY = yIdx - this.numScrollbackLines;
if (pixelY >= 0) {
@ -1532,6 +1561,31 @@ VT100.prototype.enableAlternateScreen = function(state) {
this.currentScreen = state ? 1 : 0;
this.console[1-this.currentScreen].style.display = 'none';
this.console[this.currentScreen].style.display = '';
// Select appropriate character pitch.
var styles = [ 'transform',
'WebkitTransform',
'MozTransform',
'filter' ];
for (var i = 0; i < styles.length; ++i) {
if (typeof this.console[0].style[styles[i]] != 'undefined') {
if (state) {
// Upon enabling the alternate screen, we switch to 80 column mode. But
// upon returning to the regular screen, we restore the mode that was
// in effect previously.
this.console[1].style[styles[i]] = '';
}
var style =
this.console[this.currentScreen].style[styles[i]];
this.cursor.style[styles[i]] = style;
this.space.style[styles[i]] = style;
this.scale = style == '' ? 1.0:1.65;
if (styles[i] == 'filter') {
this.console[this.currentScreen].style.width = style == '' ? '165%':'';
}
break;
}
}
this.resizer();
// If we switched to the alternate screen, reset it completely. Otherwise,
@ -2814,12 +2868,50 @@ VT100.prototype.restoreCursor = function() {
this.savedY[this.currentScreen]);
};
VT100.prototype.set80_132Mode = function(state) {
var transform = undefined;
var styles = [ 'transform',
'WebkitTransform',
'MozTransform',
'filter'
];
for (var i = 0; i < styles.length; ++i) {
if (typeof this.console[0].style[styles[i]] != 'undefined') {
transform = styles[i];
break;
}
}
if (transform) {
if ((this.console[this.currentScreen].style[transform] != '') == state) {
return;
}
var style =
state ? transform == 'filter'
? 'progid:DXImageTransform.Microsoft.Matrix(' +
'M11=0.606060606060606060606,M12=0,M21=0,M22=1,' +
"sizingMethod='auto expand')"
: 'translateX(-50%) ' +
'scaleX(0.606060606060606060606) ' +
'translateX(50%)'
: '';
this.console[this.currentScreen].style[transform] = style;
this.cursor.style[transform] = style;
this.space.style[transform] = style;
this.scale = state ? 1.65 : 1.0;
if (transform == 'filter') {
this.console[this.currentScreen].style.width = state ? '165%' : '';
}
this.resizer();
}
};
VT100.prototype.setMode = function(state) {
for (var i = 0; i <= this.npar; i++) {
if (this.isQuestionMark) {
switch (this.par[i]) {
case 1: this.cursorKeyMode = state; break;
case 3: /* Toggling between 80/132 mode is not implemented */ break;
case 3: this.set80_132Mode(state); break;
case 5: this.isInverted = state; this.refreshInvertedState(); break;
case 6: this.offsetMode = state; break;
case 7: this.autoWrapMode = state; break;