diff options
Diffstat (limited to 'third_party/websockify/include')
-rw-r--r-- | third_party/websockify/include/VT100.js | 919 | ||||
-rw-r--r-- | third_party/websockify/include/base64.js | 147 | ||||
-rw-r--r-- | third_party/websockify/include/keysym.js | 99 | ||||
-rw-r--r-- | third_party/websockify/include/util.js | 303 | ||||
-rw-r--r-- | third_party/websockify/include/web-socket-js/README.txt | 109 | ||||
-rw-r--r-- | third_party/websockify/include/web-socket-js/WebSocketMain.swf | bin | 0 -> 177114 bytes | |||
-rw-r--r-- | third_party/websockify/include/web-socket-js/swfobject.js | 4 | ||||
-rwxr-xr-x | third_party/websockify/include/web-socket-js/web_socket.js | 391 | ||||
-rw-r--r-- | third_party/websockify/include/websock.js | 427 | ||||
-rw-r--r-- | third_party/websockify/include/webutil.js | 148 | ||||
-rw-r--r-- | third_party/websockify/include/wsirc.js | 235 | ||||
-rw-r--r-- | third_party/websockify/include/wstelnet.js | 335 |
12 files changed, 3117 insertions, 0 deletions
diff --git a/third_party/websockify/include/VT100.js b/third_party/websockify/include/VT100.js new file mode 100644 index 00000000..6a325e13 --- /dev/null +++ b/third_party/websockify/include/VT100.js @@ -0,0 +1,919 @@ +// VT100.js -- a text terminal emulator in JavaScript with a ncurses-like +// interface and a POSIX-like interface. (The POSIX-like calls are +// implemented on top of the ncurses-like calls, not the other way round.) +// +// Released under the GNU LGPL v2.1, by Frank Bi <bi@zompower.tk> +// +// 2007-08-12 - refresh(): +// - factor out colour code to html_colours_() +// - fix handling of A_REVERSE | A_DIM +// - simplify initial <br /> output code +// - fix underlining colour +// - fix attron() not to turn off attributes +// - decouple A_STANDOUT and A_BOLD +// 2007-08-11 - getch() now calls refresh() +// 2007-08-06 - Safari compat fix -- turn '\r' into '\n' for onkeypress +// 2007-08-05 - Opera compat fixes for onkeypress +// 2007-07-30 - IE compat fixes: +// - change key handling code +// - add <br />...<br /> so that 1st and last lines align +// 2007-07-28 - change wrapping behaviour -- writing at the right edge no +// longer causes the cursor to immediately wrap around +// - add <b>...</b> to output to make A_STANDOUT stand out more +// - add handling of backspace, tab, return keys +// - fix doc. of VT100() constructor +// - change from GPL to LGPL +// 2007-07-09 - initial release +// +// class VT100 +// A_NORMAL, A_UNDERLINE, A_REVERSE, A_BLINK, A_DIM, A_BOLD, A_STANDOUT +// =class constants= +// Attribute constants. +// VT100(wd, ht, scr_id) =constructor= +// Creates a virtual terminal with width `wd', and +// height `ht'. The terminal will be displayed between +// <pre>...</pre> tags which have element ID `scr_id'. +// addch(ch [, attr]) +// Writes out the character `ch'. If `attr' is given, +// it specifies the attributes for the character, +// otherwise the current attributes are used. +// addstr(stuff) Writes out the string `stuff' using the current +// attributes. +// attroff(mode) Turns off any current options given in mode. +// attron(mode) Turns on any options given in mode. +// attrset(mode) Sets the current options to mode. +// bkgdset(attr) Sets the background attributes to attr. +// clear() Clears the terminal using the background attributes, +// and homes the cursor. +// clrtobol() Clears the portion of the terminal from the cursor +// to the bottom. +// clrtoeol() Clears the portion of the current line after the +// cursor. +// curs_set(vis [, grab]) +// If `vis' is 0, makes the cursor invisible; otherwise +// make it visible. If `grab' is given and true, starts +// capturing keyboard events (for `getch()'); if given +// and false, stops capturing events. +// echo() Causes key strokes to be automatically echoed on the +// terminal. +// erase() Same as `clear()'. +// getch(isr) Arranges to call `isr' when a key stroke is +// received. The received character and the terminal +// object are passed as arguments to `isr'. +// getmaxyx() Returns an associative array with the maximum row +// (`y') and column (`x') numbers for the terminal. +// getyx() Returns an associative array with the current row +// (`y') and column (`x') of the cursor. +// move(r, c) Moves the cursor to row `r', column `c'. +// noecho() Stops automatically echoing key strokes. +// refresh() Updates the display. +// scroll() Scrolls the terminal up one line. +// standend() Same as `attrset(VT100.A_NORMAL)'. +// standout() Same as `attron(VT100.A_STANDOUT)'. +// write(stuff) Writes `stuff' to the terminal and immediately +// updates the display; (some) escape sequences are +// interpreted and acted on. + +// constructor +function VT100(wd, ht, scr_id) +{ + var r; + var c; + var scr = document.getElementById(scr_id); + this.wd_ = wd; + this.ht_ = ht; + this.scrolled_ = 0; + this.bkgd_ = { + mode: VT100.A_NORMAL, + fg: VT100.COLOR_WHITE, + bg: VT100.COLOR_BLACK + }; + this.c_attr_ = { + mode: VT100.A_NORMAL, + fg: VT100.COLOR_WHITE, + bg: VT100.COLOR_BLACK + }; + this.text_ = new Array(ht); + this.attr_ = new Array(ht); + for (r = 0; r < ht; ++r) { + this.text_[r] = new Array(wd); + this.attr_[r] = new Array(wd); + } + this.scr_ = scr; + this.cursor_vis_ = true; + this.grab_events_ = false; + this.getch_isr_ = undefined; + this.key_buf_ = []; + this.echo_ = true; + this.esc_state_ = 0; + // Internal debug setting. + this.debug_ = 0; + this.clear(); + this.refresh(); +} + +// public constants -- colours and colour pairs +VT100.COLOR_BLACK = 0; +VT100.COLOR_BLUE = 1; +VT100.COLOR_GREEN = 2; +VT100.COLOR_CYAN = 3; +VT100.COLOR_RED = 4; +VT100.COLOR_MAGENTA = 5; +VT100.COLOR_YELLOW = 6; +VT100.COLOR_WHITE = 7; +VT100.COLOR_PAIRS = 256; +VT100.COLORS = 8; +// public constants -- attributes +VT100.A_NORMAL = 0; +VT100.A_UNDERLINE = 1; +VT100.A_REVERSE = 2; +VT100.A_BLINK = 4; +VT100.A_DIM = 8; +VT100.A_BOLD = 16; +VT100.A_STANDOUT = 32; +VT100.A_PROTECT = VT100.A_INVIS = 0; // ? +// other public constants +VT100.TABSIZE = 8; +// private constants +VT100.ATTR_FLAGS_ = VT100.A_UNDERLINE | VT100.A_REVERSE | VT100.A_BLINK | + VT100.A_DIM | VT100.A_BOLD | VT100.A_STANDOUT | + VT100.A_PROTECT | VT100.A_INVIS; +VT100.COLOR_SHIFT_ = 6; +VT100.browser_ie_ = (navigator.appName.indexOf("Microsoft") != -1); +VT100.browser_opera_ = (navigator.appName.indexOf("Opera") != -1); +// class variables +VT100.the_vt_ = undefined; + +// class methods + +// this is actually an event handler +VT100.handle_onkeypress_ = function VT100_handle_onkeypress(event) +{ + var vt = VT100.the_vt_, ch; + if (vt === undefined) + return true; + if (VT100.browser_ie_ || VT100.browser_opera_) { + ch = event.keyCode; + if (ch == 13) + ch = 10; + else if (ch > 255 || (ch < 32 && ch != 8)) + return true; + ch = String.fromCharCode(ch); + } else { + ch = event.charCode; + //dump("ch: " + ch + "\n"); + //dump("ctrl?: " + event.ctrlKey + "\n"); + vt.debug("onkeypress:: keyCode: " + event.keyCode + ", ch: " + event.charCode); + if (ch) { + if (ch > 255) + return true; + if (event.ctrlKey && event.shiftKey) { + // Don't send the copy/paste commands. + var charStr = String.fromCharCode(ch); + if (charStr == 'C' || charStr == 'V') { + return false; + } + } + if (event.ctrlKey) { + ch = String.fromCharCode(ch - 96); + } else { + ch = String.fromCharCode(ch); + if (ch == '\r') + ch = '\n'; + } + } else { + switch (event.keyCode) { + case event.DOM_VK_BACK_SPACE: + ch = '\b'; + break; + case event.DOM_VK_TAB: + ch = '\t'; + // Stop tab from moving to another element. + event.preventDefault(); + break; + case event.DOM_VK_RETURN: + case event.DOM_VK_ENTER: + ch = '\n'; + break; + case event.DOM_VK_UP: + ch = '\x1b[A'; + break; + case event.DOM_VK_DOWN: + ch = '\x1b[B'; + break; + case event.DOM_VK_RIGHT: + ch = '\x1b[C'; + break; + case event.DOM_VK_LEFT: + ch = '\x1b[D'; + break; + case event.DOM_VK_DELETE: + ch = '\x1b[3~'; + break; + case event.DOM_VK_HOME: + ch = '\x1b[H'; + break; + case event.DOM_VK_ESCAPE: + ch = '\x1bc'; + break; + default: + return true; + } + } + } + vt.key_buf_.push(ch); + setTimeout(VT100.go_getch_, 0); + return false; +} + +// this is actually an event handler +VT100.handle_onkeydown_ = function VT100_handle_onkeydown() +{ + var vt = VT100.the_vt_, ch; + switch (event.keyCode) { + case 8: + ch = '\b'; break; + default: + return true; + } + vt.key_buf_.push(ch); + setTimeout(VT100.go_getch_, 0); + return false; +} + +VT100.go_getch_ = function VT100_go_getch() +{ + var vt = VT100.the_vt_; + if (vt === undefined) + return; + var isr = vt.getch_isr_; + vt.getch_isr_ = undefined; + if (isr === undefined) + return; + var ch = vt.key_buf_.shift(); + if (ch === undefined) { + vt.getch_isr_ = isr; + return; + } + if (vt.echo_) + vt.addch(ch); + isr(ch, vt); +} + +// object methods + +VT100.prototype.may_scroll_ = function() +{ + var ht = this.ht_, cr = this.row_; + while (cr >= ht) { + this.scroll(); + --cr; + } + this.row_ = cr; +} + +VT100.prototype.html_colours_ = function(attr) +{ + var fg, bg, co0, co1; + fg = attr.fg; + bg = attr.bg; + switch (attr.mode & (VT100.A_REVERSE | VT100.A_DIM | VT100.A_BOLD)) { + case 0: + case VT100.A_DIM | VT100.A_BOLD: + co0 = '00'; co1 = 'c0'; + break; + case VT100.A_BOLD: + co0 = '00'; co1 = 'ff'; + break; + case VT100.A_DIM: + if (fg == VT100.COLOR_BLACK) + co0 = '40'; + else + co0 = '00'; + co1 = '40'; + break; + case VT100.A_REVERSE: + case VT100.A_REVERSE | VT100.A_DIM | VT100.A_BOLD: + co0 = 'c0'; co1 = '40'; + break; + case VT100.A_REVERSE | VT100.A_BOLD: + co0 = 'c0'; co1 = '00'; + break; + default: + if (fg == VT100.COLOR_BLACK) + co0 = '80'; + else + co0 = 'c0'; + co1 = 'c0'; + } + return { + f: '#' + (fg & 4 ? co1 : co0) + + (fg & 2 ? co1 : co0) + + (fg & 1 ? co1 : co0), + b: '#' + (bg & 4 ? co1 : co0) + + (bg & 2 ? co1 : co0) + + (bg & 1 ? co1 : co0) + }; +} + +VT100.prototype.addch = function(ch, attr) +{ + var cc = this.col_; + this.debug("addch:: ch: " + ch + ", attr: " + attr); + switch (ch) { + case '\b': + if (cc != 0) + --cc; + break; + case '\n': + ++this.row_; + cc = 0; + this.clrtoeol(); + this.may_scroll_(); + break; + case '\r': + this.may_scroll_(); + cc = 0; + break; + case '\t': + this.may_scroll_(); + cc += VT100.TABSIZE - cc % VT100.TABSIZE; + if (cc >= this.wd_) { + ++this.row_; + cc -= this.wd_; + } + break; + default: + if (attr === undefined) + attr = this._cloneAttr(this.c_attr_); + if (cc >= this.wd_) { + ++this.row_; + cc = 0; + } + this.may_scroll_(); + this.text_[this.row_][cc] = ch; + this.attr_[this.row_][cc] = attr; + ++cc; + } + this.col_ = cc; +} + +VT100.prototype.addstr = function(stuff) +{ + for (var i = 0; i < stuff.length; ++i) + this.addch(stuff.charAt(i)); +} + +VT100.prototype._cloneAttr = function VT100_cloneAttr(a) +{ + return { + mode: a.mode, + fg: a.fg, + bg: a.bg + }; +} + +VT100.prototype.attroff = function(a) +{ + //dump("attroff: " + a + "\n"); + a &= VT100.ATTR_FLAGS_; + this.c_attr_.mode &= ~a; +} + +VT100.prototype.attron = function(a) +{ + //dump("attron: " + a + "\n"); + a &= VT100.ATTR_FLAGS_; + this.c_attr_.mode |= a; +} + +VT100.prototype.attrset = function(a) +{ + //dump("attrset: " + a + "\n"); + this.c_attr_.mode = a; +} + +VT100.prototype.fgset = function(fg) +{ + //dump("fgset: " + fg + "\n"); + this.c_attr_.fg = fg; +} + +VT100.prototype.bgset = function(bg) +{ + //dump("bgset: " + bg + "\n"); + if (bg !== 0) { + this.warn("bgset: " + bg + "\n"); + } + this.c_attr_.bg = bg; +} + +VT100.prototype.bkgdset = function(a) +{ + this.bkgd_ = a; +} + +VT100.prototype.clear = function() +{ + this.debug("clear"); + this.row_ = this.col_ = 0; + this.scrolled_ = 0; + for (r = 0; r < this.ht_; ++r) { + for (c = 0; c < this.wd_; ++c) { + this.text_[r][c] = ' '; + this.attr_[r][c] = this._cloneAttr(this.bkgd_); + } + } +} + +VT100.prototype.clrtobot = function() +{ + this.debug("clrtobot, row: " + this.row_); + var ht = this.ht_; + var wd = this.wd_; + this.clrtoeol(); + for (var r = this.row_ + 1; r < ht; ++r) { + for (var c = 0; c < wd; ++c) { + this.text_[r][c] = ' '; + this.attr_[r][c] = this.bkgd_; + } + } +} + +VT100.prototype.clrtoeol = function() +{ + this.debug("clrtoeol, col: " + this.col_); + var r = this.row_; + if (r >= this.ht_) + return; + for (var c = this.col_; c < this.wd_; ++c) { + this.text_[r][c] = ' '; + this.attr_[r][c] = this.bkgd_; + } +} + +VT100.prototype.clearpos = function(row, col) +{ + this.debug("clearpos (" + row + ", " + col + ")"); + if (row < 0 || row >= this.ht_) + return; + if (col < 0 || col >= this.wd_) + return; + this.text_[row][col] = ' '; + this.attr_[row][col] = this.bkgd_; +} + +VT100.prototype.curs_set = function(vis, grab, eventist) +{ + this.debug("curs_set:: vis: " + vis + ", grab: " + grab); + 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; + VT100.the_vt_ = this; + eventist.addEventListener("keypress", VT100.handle_onkeypress_, false); + if (VT100.browser_ie_) + document.onkeydown = VT100.handle_onkeydown_; + } else { + eventist.removeEventListener("keypress", VT100.handle_onkeypress_, false); + if (VT100.browser_ie_) + document.onkeydown = VT100.handle_onkeydown_; + this.grab_events_ = false; + VT100.the_vt_ = undefined; + } + } +} + +VT100.prototype.echo = function() +{ + this.debug("echo on"); + this.echo_ = true; +} + +VT100.prototype.erase = VT100.prototype.clear; + +VT100.prototype.getch = function(isr) +{ + this.debug("getch"); + this.refresh(); + this.getch_isr_ = isr; + setTimeout(VT100.go_getch_, 0); +} + +VT100.prototype.getmaxyx = function() +{ + return { y: this.ht_ - 1, x: this.wd_ - 1 }; +} + +VT100.prototype.getyx = function() +{ + return { y: this.row_, x: this.col_ }; +} + +VT100.prototype.move = function(r, c) +{ + this.debug("move: (" + r + ", " + c + ")"); + if (r < 0) + r = 0; + else if (r >= this.ht_) + r = this.ht_ - 1; + if (c < 0) + c = 0; + else if (c >= this.wd_) + c = this.wd_ - 1; + this.row_ = r; + this.col_ = c; +} + +VT100.prototype.noecho = function() +{ + this.debug("echo off"); + this.echo_ = false; +} + +VT100.prototype.refresh = function() +{ + this.debug("refresh"); + var r, c, stuff = "", start_tag = "", end_tag = "", at = -1, n_at, ch, + pair, cr, cc, ht, wd, cv, added_end_tag; + ht = this.ht_; + wd = this.wd_; + cr = this.row_; + cc = this.col_; + cv = this.cursor_vis_; + var innerHTML = this.scr_.innerHTML; + if (cc >= wd) + cc = wd - 1; + for (r = 0; r < ht; ++r) { + if (r > 0) { + stuff += '\n'; + } + for (c = 0; c < wd; ++c) { + added_end_tag = false; + n_at = this.attr_[r][c]; + if (cv && r == cr && c == cc) { + // Draw the cursor here. + n_at = this._cloneAttr(n_at); + n_at.mode ^= VT100.A_REVERSE; + } + // If the attributes changed, make a new span. + if (n_at.mode != at.mode || n_at.fg != at.fg || n_at.bg != at.bg) { + if (c > 0) { + stuff += end_tag; + } + start_tag = ""; + end_tag = ""; + if (n_at.mode & VT100.A_BLINK) { + start_tag = "<blink>"; + end_tag = "</blink>" + end_tag; + } + if (n_at.mode & VT100.A_STANDOUT) + n_at.mode |= VT100.A_BOLD; + pair = this.html_colours_(n_at); + start_tag += '<span style="color:' + pair.f + + ';background-color:' + pair.b; + if (n_at.mode & VT100.A_UNDERLINE) + start_tag += ';text-decoration:underline'; + start_tag += ';">'; + stuff += start_tag; + end_tag = "</span>" + end_tag; + at = n_at; + added_end_tag = true; + } else if (c == 0) { + stuff += start_tag; + } + ch = this.text_[r][c]; + switch (ch) { + case '&': + stuff += '&'; break; + case '<': + stuff += '<'; break; + case '>': + stuff += '>'; break; + case ' ': + //stuff += ' '; break; + stuff += ' '; break; + default: + stuff += ch; + } + } + if (!added_end_tag) + stuff += end_tag; + } + this.scr_.innerHTML = "<b>" + stuff + "</b>\n"; +} + +VT100.prototype.scroll = function() +{ + this.scrolled_ += 1; + this.debug("scrolled: " + this.scrolled_); + var n_text = this.text_[0], n_attr = this.attr_[0], + ht = this.ht_, wd = this.wd_; + for (var r = 1; r < ht; ++r) { + this.text_[r - 1] = this.text_[r]; + this.attr_[r - 1] = this.attr_[r]; + } + this.text_[ht - 1] = n_text; + this.attr_[ht - 1] = n_attr; + for (var c = 0; c < wd; ++c) { + n_text[c] = ' '; + n_attr[c] = this.bkgd_; + } +} + +VT100.prototype.standend = function() +{ + //this.debug("standend"); + this.attrset(0); +} + +VT100.prototype.standout = function() +{ + //this.debug("standout"); + this.attron(VT100.A_STANDOUT); +} + +VT100.prototype.write = function(stuff) +{ + var ch, x, r, c, i, j, yx, myx; + for (i = 0; i < stuff.length; ++i) { + ch = stuff.charAt(i); + if (ch == '\x0D') { + this.debug("write:: ch: " + ch.charCodeAt(0) + ", '\\x0D'"); + } else { + this.debug("write:: ch: " + ch.charCodeAt(0) + ", '" + (ch == '\x1b' ? "ESC" : ch) + "'"); + } + //dump("ch: " + ch.charCodeAt(0) + ", '" + (ch == '\x1b' ? "ESC" : ch) + "'\n"); + switch (ch) { + case '\x00': + case '\x7f': + case '\x07': /* bell, ignore it */ + this.debug("write:: ignoring bell character: " + ch); + continue; + case '\a': + case '\b': + case '\t': + case '\r': + this.addch(ch); + continue; + case '\n': + case '\v': + case '\f': // what a mess + yx = this.getyx(); + myx = this.getmaxyx(); + if (yx.y >= myx.y) { + this.scroll(); + this.move(myx.y, 0); + } else + this.move(yx.y + 1, 0); + continue; + case '\x18': + case '\x1a': + this.esc_state_ = 0; + this.debug("write:: set escape state: 0"); + continue; + case '\x1b': + this.esc_state_ = 1; + this.debug("write:: set escape state: 1"); + continue; + case '\x9b': + this.esc_state_ = 2; + this.debug("write:: set escape state: 2"); + continue; + } + // not a recognized control character + switch (this.esc_state_) { + case 0: // not in escape sequence + this.addch(ch); + break; + case 1: // just saw ESC + switch (ch) { + case '[': + this.esc_state_ = 2; + this.debug("write:: set escape state: 2"); + break; + case '=': + /* Set keypade mode (ignored) */ + this.debug("write:: set keypade mode: ignored"); + this.esc_state_ = 0; + break; + case '>': + /* Reset keypade mode (ignored) */ + this.debug("write:: reset keypade mode: ignored"); + this.esc_state_ = 0; + break; + case 'H': + /* Set tab at cursor column (ignored) */ + this.debug("write:: set tab cursor column: ignored"); + this.esc_state_ = 0; + break; + } + break; + case 2: // just saw CSI + switch (ch) { + case 'K': + /* Erase in Line */ + this.esc_state_ = 0; + this.clrtoeol(); + continue; + case 'H': + /* Move to (0,0). */ + this.esc_state_ = 0; + this.move(0, 0); + continue; + case 'J': + /* Clear to the bottom. */ + this.esc_state_ = 0; + this.clrtobot(); + continue; + case '?': + /* Special VT100 mode handling. */ + this.esc_state_ = 5; + this.debug("write:: special vt100 mode"); + continue; + } + // Drop through to next case. + this.csi_parms_ = [0]; + this.debug("write:: set escape state: 3"); + this.esc_state_ = 3; + case 3: // saw CSI and parameters + switch (ch) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + x = this.csi_parms_.pop(); + this.csi_parms_.push(x * 10 + ch * 1); + this.debug("csi_parms_: " + this.csi_parms_); + continue; + case ';': + if (this.csi_parms_.length < 17) + this.csi_parms_.push(0); + continue; + } + this.esc_state_ = 0; + switch (ch) { + case 'A': + // Cursor Up <ESC>[{COUNT}A + this.move(this.row_ - Math.max(1, this.csi_parms_[0]), + this.col_); + break; + case 'B': + // Cursor Down <ESC>[{COUNT}B + this.move(this.row_ + Math.max(1, this.csi_parms_[0]), + this.col_); + break; + case 'C': + // Cursor Forward <ESC>[{COUNT}C + this.move(this.row_, + this.col_ + Math.max(1, this.csi_parms_[0])); + break; + case 'c': + this.warn("write:: got TERM query"); + break; + case 'D': + // Cursor Backward <ESC>[{COUNT}D + this.move(this.row_, + this.col_ - Math.max(1, this.csi_parms_[0])); + break; + case 'f': + case 'H': + // Cursor Home <ESC>[{ROW};{COLUMN}H + this.csi_parms_.push(0); + this.move(this.csi_parms_[0] - 1, + this.csi_parms_[1] - 1); + break; + case 'J': + switch (this.csi_parms_[0]) { + case 0: + this.clrtobot(); + break; + case 2: + this.clear(); + this.move(0, 0); + } + break; + case 'm': + for (j=0; j<this.csi_parms_.length; ++j) { + x = this.csi_parms_[j]; + switch (x) { + case 0: + this.standend(); + this.fgset(this.bkgd_.fg); + this.bgset(this.bkgd_.bg); + break; + case 1: + this.attron(VT100.A_BOLD); + break; + case 30: + this.fgset(VT100.COLOR_BLACK); + break; + case 31: + this.fgset(VT100.COLOR_RED); + break; + case 32: + this.fgset(VT100.COLOR_GREEN); + break; + case 33: + this.fgset(VT100.COLOR_YELLOW); + break; + case 34: + this.fgset(VT100.COLOR_BLUE); + break; + case 35: + this.fgset(VT100.COLOR_MAGENTA); + break; + case 36: + this.fgset(VT100.COLOR_CYAN); + break; + case 37: + this.fgset(VT100.COLOR_WHITE); + break; + case 40: + this.bgset(VT100.COLOR_BLACK); + break; + case 41: + this.bgset(VT100.COLOR_RED); + break; + case 42: + this.bgset(VT100.COLOR_GREEN); + break; + case 44: + this.bgset(VT100.COLOR_YELLOW); + break; + case 44: + this.bgset(VT100.COLOR_BLUE); + break; + case 45: + this.bgset(VT100.COLOR_MAGENTA); + break; + case 46: + this.bgset(VT100.COLOR_CYAN); + break; + case 47: + this.bgset(VT100.COLOR_WHITE); + break; + } + } + break; + case 'r': + // 1,24r - set scrolling region (ignored) + break; + case '[': + this.debug("write:: set escape state: 4"); + this.esc_state_ = 4; + break; + case 'g': + // 0g: clear tab at cursor (ignored) + // 3g: clear all tabs (ignored) + break; + default: + this.warn("write:: unknown command: " + ch); + this.csi_parms_ = []; + break; + } + break; + case 4: // saw CSI [ + this.esc_state_ = 0; // gobble char. + break; + case 5: // Special mode handling, saw <ESC>[? + // Expect a number - the reset type + this.csi_parms_ = [ch]; + this.esc_state_ = 6; + break; + case 6: // Reset mode handling, saw <ESC>[?1 + // Expect a letter - the mode target, example: + // <ESC>[?1l : cursor key mode = cursor + // <ESC>[?1h : save current screen, create new empty + // screen and position at 0,0 + // <ESC>[?5l : White on blk + // XXX: Ignored for now. + //dump("Saw reset mode: <ESC>[?" + this.csi_parms_[0] + ch + "\n"); + this.esc_state_ = 0; + this.debug("write:: set escape state: 0"); + break; + } + } + this.refresh(); +} + +VT100.prototype.debug = function(message) { + if (this.debug_) { + dump(message + "\n"); + } +} + +VT100.prototype.warn = function(message) { + dump(message + "\n"); +} diff --git a/third_party/websockify/include/base64.js b/third_party/websockify/include/base64.js new file mode 100644 index 00000000..e9b3c522 --- /dev/null +++ b/third_party/websockify/include/base64.js @@ -0,0 +1,147 @@ +/* + * Modified from: + * http://lxr.mozilla.org/mozilla/source/extensions/xml-rpc/src/nsXmlRpcClient.js#956 + */ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla XML-RPC Client component. + * + * The Initial Developer of the Original Code is + * Digital Creations 2, Inc. + * Portions created by the Initial Developer are Copyright (C) 2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Martijn Pieters <mj@digicool.com> (original author) + * Samuel Sieb <samuel@sieb.net> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/*jslint white: false, bitwise: false, plusplus: false */ +/*global console */ + +var Base64 = { + +/* Convert data (an array of integers) to a Base64 string. */ +toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', +base64Pad : '=', + +encode: function (data) { + "use strict"; + var result = '', + chrTable = Base64.toBase64Table.split(''), + pad = Base64.base64Pad, + length = data.length, + i; + // Convert every three bytes to 4 ascii characters. + for (i = 0; i < (length - 2); i += 3) { + result += chrTable[data[i] >> 2]; + result += chrTable[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; + result += chrTable[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)]; + result += chrTable[data[i+2] & 0x3f]; + } + + // Convert the remaining 1 or 2 bytes, pad out to 4 characters. + if (length%3) { + i = length - (length%3); + result += chrTable[data[i] >> 2]; + if ((length%3) === 2) { + result += chrTable[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; + result += chrTable[(data[i+1] & 0x0f) << 2]; + result += pad; + } else { + result += chrTable[(data[i] & 0x03) << 4]; + result += pad + pad; + } + } + + return result; +}, + +/* Convert Base64 data to a string */ +toBinaryTable : [ + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +], + +decode: function (data, offset) { + "use strict"; + offset = typeof(offset) !== 'undefined' ? offset : 0; + var binTable = Base64.toBinaryTable, + pad = Base64.base64Pad, + result, result_length, idx, i, c, padding, + leftbits = 0, // number of bits decoded, but yet to be appended + leftdata = 0, // bits decoded, but yet to be appended + data_length = data.indexOf('=') - offset; + + if (data_length < 0) { data_length = data.length - offset; } + + /* Every four characters is 3 resulting numbers */ + result_length = (data_length >> 2) * 3 + Math.floor((data_length%4)/1.5); + result = new Array(result_length); + + // Convert one by one. + for (idx = 0, i = offset; i < data.length; i++) { + c = binTable[data.charCodeAt(i) & 0x7f]; + padding = (data.charAt(i) === pad); + // Skip illegal characters and whitespace + if (c === -1) { + console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i); + continue; + } + + // Collect data into leftdata, update bitcount + leftdata = (leftdata << 6) | c; + leftbits += 6; + + // If we have 8 or more bits, append 8 bits to the result + if (leftbits >= 8) { + leftbits -= 8; + // Append if not padding. + if (!padding) { + result[idx++] = (leftdata >> leftbits) & 0xff; + } + leftdata &= (1 << leftbits) - 1; + } + } + + // If there are any bits left, the base64 string was corrupted + if (leftbits) { + throw {name: 'Base64-Error', + message: 'Corrupted base64 string'}; + } + + return result; +} + +}; /* End of Base64 namespace */ diff --git a/third_party/websockify/include/keysym.js b/third_party/websockify/include/keysym.js new file mode 100644 index 00000000..b24ac889 --- /dev/null +++ b/third_party/websockify/include/keysym.js @@ -0,0 +1,99 @@ +/* + * from noVNC: HTML5 VNC client + * Copyright (C) 2010 Joel Martin + * Licensed under LGPL-3 (see LICENSE.txt) + */ + +/* Translate DOM key down/up event to keysym value */ +function getKeysym(e) { + var evt, keysym; + evt = (e ? e : window.event); + + /* Remap modifier and special keys */ + switch ( evt.keyCode ) { + case 8 : keysym = 0xFF08; break; // BACKSPACE + case 9 : keysym = 0xFF09; break; // TAB + case 13 : keysym = 0xFF0D; break; // ENTER + case 27 : keysym = 0xFF1B; break; // ESCAPE |