<head>
<title>Remote Terminal Viewer</title>
<script src="/jquery.js"></script>
+ <script src="/terminal.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
$(function() {
+ var term = null;
// 8-14 are bolded versions
var palette = [
'2e3436',
index += 8;
}
return 'color: #' + palette[index] + '; ';
- }
+ };
var bg_color_to_css = function(i) {
return 'background-' + color_to_css((i&0x10000) | ((i&0xff00) >> 8));
- }
+ };
var stylize = function (txt, style) {
if (txt.length == 0 || style == 0) {
return txt
}
css = ''
- if(style & 0x10000) css += 'font-weight: bold; ';
- if(style & 0x20000) css += 'text-decoration: underline; ';
- if(style & 0x40000) css += 'text-decoration: underline; '; // blink
- if(style & 0x80000) css += 'text-decoration: line-through; '; // invisible
- if(style & 0x000ff) css += color_to_css(style);
- if(style & 0x0ff00) css += bg_color_to_css(style);
+ if (style & 0x10000) css += 'font-weight: bold; ';
+ if (style & 0x20000) css += 'text-decoration: underline; ';
+ if (style & 0x40000) css += 'text-decoration: underline; '; // blink
+ if (style & 0x80000) css += 'text-decoration: line-through; '; // invisible
+ if (style & 0x000ff) css += color_to_css(style);
+ if (style & 0x0ff00) css += bg_color_to_css(style);
return $('<span style="'+css+'"></span>').text(txt);
- }
- socket.on('init', function (v) {
+ };
+ var redraw_wait = false;
+ var redraw_again = false;
+ var redraw_now = function () {
$body.children().remove();
- for(i in v.text) {
+ for (i in term.text) {
div = $('<div>');
txt = ''
a = 0;
- for(j in v.text[i]) {
- if(v.attributes[i][j] != a) {
- if(txt.length) {
+ for (j in term.text[i]) {
+ if (term.attributes[i][j] != a) {
+ if (txt.length) {
div.append(stylize(txt, a));
txt = ''
}
- a = v.attributes[i][j]
+ a = term.attributes[i][j]
}
- txt += v.text[i][j]
+ txt += term.text[i][j]
}
if(txt.length) {
div.append(stylize(txt, a));
}
$body.append(div);
}
+ }
+ // limit to 50fps
+ var redraw = function () {
+ if (redraw_wait) {
+ redraw_again = true;
+ } else {
+ redraw_now()
+ redraw_wait = true;
+ redraw_again = false;
+ setTimeout(function () {
+ redraw_wait = false;
+ if(redraw_again) {
+ redraw_again = false;
+ redraw();
+ }
+ }, 20);
+ }
+ }
+ var update = function (data) {
+ if (term) {
+ term.update(data);
+ redraw();
+ }
+ };
+
+ socket.on('data', function (data) {
+ update(data);
+ });
+ socket.on('init', function (v) {
+ term = terminal.new(v.width, v.height);
+ term.x = v.x;
+ term.y = v.y;
+ term.a = v.a;
+ term.text = v.text;
+ term.attributes = v.attributes;
+ redraw();
});
});
</script>
handler = (req, res) ->
- err = (req, res) ->
- res.writeHead(404, 'Content-Type': 'text/plain')
- return res.end("Error loading #{req.url}")
+ reply_err = (req, res, msg) ->
+ res.writeHead(200, 'Content-Type': 'text/plain')
+ return res.end("Error loading #{req.url} \"#{msg}\"")
switch req.url
when '/', '/index.html'
filename = __dirname + '/index.html'
when '/jquery.js'
filename = '/usr/share/javascript/jquery/jquery.min.js'
type = 'text/javascript'
+ when '/terminal.js'
+ filename = __dirname + '/terminal.coffee'
+ type = 'text/javascript'
else
- return err req, res
- fs.readFile filename, (err, data) ->
- return err req, res if err
+ return reply_err req, res
+ fs.readFile filename, 'utf8', (err, data) ->
+ return reply_err req, res, err if err
+
+ if filename.substr(filename.length - 7) is '.coffee'
+ try
+ data = coffee.compile data
+ catch e
+ return reply_err req, res, "server faild to compile #{filename}: #{JSON.stringify(e)}"
res.writeHead(200, 'Content-Type': type)
res.end(data)
+coffee = require 'coffee-script'
app = require('http').createServer(handler)
io = require('socket.io').listen(app)
fs = require('fs')
process.stdin.on 'data', (data) ->
term.update data
- # FIXME send data, and have client parse it
for s in sockets
- s.emit 'init', width: term.width, height: term.height, x: term.x, y: term.y, a: term.a, text: term.text, attributes: term.attributes
+ s.emit 'data', data
process.stdin.on 'end', -> process.exit()