sbbs/themes/hueman/source/js/viewdata/wsvdata.js

271 lines
5.1 KiB
JavaScript

if (! window.$D) {
window.$D = function (id) {
return document.getElementById(id);
};
}
function Telnet(target, connect_callback, disconnect_callback, initscr) {
var that = {}, // Public API interface
vd, ws, sQ = [];
termType = "Viewdata";
Array.prototype.pushStr = function (str) {
var n = str.length;
for (var i=0; i<n; i++) {
this.push(str.charCodeAt(i));
}
}
function do_send() {
Log.Debug('>> do_send');
if (sQ.length > 0) {
ws.send(sQ);
sQ = [];
}
}
function do_recv() {
Log.Debug('>> do_recv');
vd.write(ws.rQshiftStr(ws.rQlen()));
}
that.addEvent = function(obj, evType, fn) {
if (obj.attachEvent) {
var r = obj.attachEvent("on"+evType, fn);
return r;
} else if (obj.addEventListener){
obj.addEventListener(evType, fn, false);
return true;
} else {
throw("Handler could not be attached");
}
};
that.removeEvent = function(obj, evType, fn){
if (obj.detachEvent) {
var r = obj.detachEvent("on"+evType, fn);
return r;
} else if (obj.removeEventListener) {
obj.removeEventListener(evType, fn, false);
return true;
} else {
throw("Handler could not be removed");
}
};
that.stopEvent = function(e) {
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
};
that.connect = function(host, port, encrypt, url) {
Log.Debug('>> connect');
var host = host,
port = port,
scheme = "ws://", uri;
if ((!host) || (!port)) {
console.log("must set host and port");
return;
}
if (ws) {
ws.close();
}
if (encrypt) {
scheme = "wss://";
}
uri = scheme + host + ":" + port + url;
ws.open(uri);
//vd.write("\x1e\x11Connecting, hang tight...");
vd.write("\x0c"+vd.txthash('#0:QIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECBAgQIECA0XboW7V61ete7Fuh1oWr1q3QoECBAgQIECBAgQIECBAgQIDRfqw6tWrVq16sOrDUgatWvVqwYMGCBAgQIECBAgQIECBAg')+' '.repeat(40));
}
that.disconnect = function() {
if (ws) {
ws.close();
}
disconnect_callback();
}
function constructor() {
/* Initialize Websock object */
ws = new Websock();
ws.on('message', do_recv);
ws.on('open', function(e) {
vd.curs_set(true, true);
connect_callback();
});
ws.on('close', function(e) {
that.disconnect();
});
ws.on('error', function(e) {
that.disconnect();
});
/* Initialize the terminal emulator/renderer */
vd = new VD(40,24,target,initscr);
// Override VD I/O routines
// Set handler for sending characters
vd.getch(
function send_chr(chr, vt) {
var i;
for (i = 0; i < chr.length; i++) {
sQ.push(chr.charCodeAt(i));
}
do_send();
vd.getch(send_chr);
}
);
vd.curs_set = function(vis, grab, eventist) {
if (vis !== undefined)
this.cursor_vis_ = (vis > 0);
if (eventist === undefined)
eventist = window;
if (grab === true || grab === false) {
if (grab === this.grab_events_)
return;
if (grab) {
this.grab_events_ = true;
VD.the_vt_ = this;
that.addEvent(eventist, 'keydown', vd.key_down);
that.addEvent(eventist, 'keyup', vd.key_up);
} else {
that.removeEvent(eventist, 'keydown', vd.key_down);
that.removeEvent(eventist, 'keyup', vd.key_up);
this.grab_events_ = false;
VD.the_vt_ = undefined;
}
}
}
vd.key_down = function(e) {
var vt = VD.the_vt_, keysym, ch, str = '';
if (vt === undefined)
return true;
keysym = getKeysym(e);
if (keysym < 128) {
if (e.ctrlKey) {
if (keysym == 64) {
// control 0
ch = 0;
} else if ((keysym >= 97) && (keysym <= 122)) {
// control codes 1-26
ch = keysym - 96;
} else if ((keysym >= 91) && (keysym <= 95)) {
// control codes 27-31
ch = keysym - 64;
}
} else {
ch = keysym;
switch (ch) {
case 34:
ch = 126; break;
case 126:
ch = 0x40; break;
case 64:
ch = 0x22; break;
case 39:
ch = 0x5f; break;
case 95:
ch = 0x23; break;
case 96:
ch = 0x27; break;
}
}
str = String.fromCharCode(ch);
} else {
switch (keysym) {
case 65505: // Shift, do not send directly
break;
case 65507: // Ctrl, do not send directly
break;
case 65293: // Carriage return, line feed
str = '_'; break;
case 65288: // Backspace
str = '\b'; break;
case 65307: // Escape
str = '\x1b'; break;
case 65361: // Left arrow
str = '\x08'; break;
case 65362: // Up arrow
str = '\x0b'; break;
case 65363: // Right arrow
str = '\x09'; break;
case 65364: // Down arrow
str = '\x0a'; break;
case 0xffc0: // f3
vd.reveal_ ^= 1;
vd.refresh();
break;
case 0xffc4: // f7
str = '\x1b'; break
}
}
if (str) {
vt.key_buf_.push(str);
setTimeout(VD.go_getch_,0);
}
that.stopEvent(e);
return false;
}
vd.key_up = function(e) {
var vt = VD.the_vt_;
if (vt === undefined)
return true;
that.stopEvent(e);
return false;
}
return that;
}
return constructor(); // Return the public API interface
}