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> 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 }