Cleanup of files and vnc.js namespace.

- Trim unused code in base64.js
This commit is contained in:
Joel Martin 2010-04-06 16:44:45 -05:00
parent d9cbdc7d85
commit cc0410a39b
5 changed files with 187 additions and 304 deletions

80
include/base64.js Normal file
View File

@ -0,0 +1,80 @@
/**
*
* Base64 encode / decode with array versions
*
* Based on Base64 from:
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding an array to a string
encode_array : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
while (i < input.length) {
chr1 = input[i++];
chr2 = input[i++];
chr3 = input[i++];
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding a string to an array
decode_array : function (input) {
var output = [];
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output.push(chr1);
if (enc3 != 64) {
output.push(chr2);
}
if (enc4 != 64) {
output.push(chr3);
}
}
return output;
}
}

View File

@ -1,206 +0,0 @@
/**
*
* Base64 encode / decode with array versions
*
* Based on Base64 from:
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding to a string
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
},
// public method for encoding an array
encode_array : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
while (i < input.length) {
chr1 = input[i++];
chr2 = input[i++];
chr3 = input[i++];
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding to an array
decode_array : function (input) {
var output = [];
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output.push(chr1);
if (enc3 != 64) {
output.push(chr2);
}
if (enc4 != 64) {
output.push(chr3);
}
}
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}

View File

@ -24,8 +24,8 @@
<script src="include/mootools.js"></script> <script src="include/mootools.js"></script>
<script src="include/mootools-more.js"></script> <script src="include/mootools-more.js"></script>
<script src="include/base64a.js"></script> <script src="include/base64.js"></script>
<script src="include/des3.js"></script> <script src="include/des.js"></script>
<script src="canvas.js"></script> <script src="canvas.js"></script>
<script src="vnc.js"></script> <script src="vnc.js"></script>

201
vnc.js
View File

@ -1,22 +1,3 @@
var ws = null;
var vnc_host = '';
var vnc_port = 5900;
var vnc_password = '';
var fbu = {
rects : 0,
bytes : 0,
x : 0,
y : 0,
width : 0,
height : 0,
encoding : 0,
arr : null};
var fb_width = 0;
var fb_height = 0;
var fb_name = "";
var fb_Bpp = 4;
Array.prototype.shift8 = function () { Array.prototype.shift8 = function () {
return this.shift(); return this.shift();
} }
@ -57,37 +38,66 @@ Array.prototype.shiftBytes = function (len) {
return this.splice(0, len); return this.splice(0, len);
} }
/*
* Pending frame buffer update data
*/
var FBU = {
rects : 0,
bytes : 0,
x : 0,
y : 0,
width : 0,
height : 0,
encoding : 0,
arr : null};
/*
* RFB namespace
*/
RFB = {
ws : null, // Web Socket object
version : "RFB 003.003\n",
state : 'ProtocolVersion',
shared : 1,
poll_rate : 3000,
host : '',
port : 5900,
password : '',
fb_width : 0,
fb_height : 0,
fb_name : "",
fb_Bpp : 4,
/* /*
* Server message handlers * Server message handlers
*/ */
RFB = {
state : 'ProtocolVersion',
shared : 1,
poll_rate : 3000,
/* RFB/VNC initialisation */ /* RFB/VNC initialisation */
init_msg: function (data) { init_msg: function (data) {
debug(">> init_msg"); debug(">> init_msg: " + RFB.state);
switch (RFB.state) { switch (RFB.state) {
case 'ProtocolVersion' : case 'ProtocolVersion' :
debug("ProtocolVersion:")
if (data.length != 12) { if (data.length != 12) {
debug("Invalid protocol version from server"); debug("Invalid protocol version from server");
RFB.state = 'reset'; RFB.state = 'reset';
return; return;
} }
debug("Server ProtocolVersion: " + data.shiftStr(11)) debug("Server ProtocolVersion: " + data.shiftStr(11));
RFB.send_string("RFB 003.003\n"); debug("Sending ProtocolVersion: " + RFB.version.substr(0,11));
RFB.send_string(RFB.version);
RFB.state = 'Authentication'; RFB.state = 'Authentication';
break; break;
case 'Authentication' : case 'Authentication' :
debug("Authentication")
if (data.length < 4) { if (data.length < 4) {
debug("Invalid auth frame"); debug("Invalid auth frame");
RFB.state = 'reset'; RFB.state = 'reset';
@ -108,13 +118,12 @@ init_msg: function (data) {
break; break;
case 2: // VNC authentication case 2: // VNC authentication
var challenge = data.shiftBytes(16); var challenge = data.shiftBytes(16);
debug("vnc_password: " + vnc_password); debug("Password: " + RFB.password);
debug("challenge: " + challenge + "(" + challenge.length + ")"); debug("Challenge: " + challenge + "(" + challenge.length + ")");
//passwd = [194, 242, 234, 194, 242, 234]; // 'COWCOW' bit mirrored passwd = RFB.passwdTwiddle(RFB.password);
passwd = RFB.passwdTwiddle(vnc_password); //debug("passwd: " + passwd + "(" + passwd.length + ")");
debug("passwd: " + passwd + "(" + passwd.length + ")");
response = des(passwd, challenge, 1) response = des(passwd, challenge, 1)
debug("reponse: " + response + "(" + response.length + ")"); //debug("reponse: " + response + "(" + response.length + ")");
RFB.send_array(response); RFB.send_array(response);
RFB.state = "SecurityResult"; RFB.state = "SecurityResult";
@ -123,7 +132,6 @@ init_msg: function (data) {
break; break;
case 'SecurityResult' : case 'SecurityResult' :
debug("SecurityResult")
if (data.length != 4) { if (data.length != 4) {
debug("Invalid server auth response"); debug("Invalid server auth response");
RFB.state = 'reset'; RFB.state = 'reset';
@ -148,7 +156,6 @@ init_msg: function (data) {
break; break;
case 'ServerInitialisation' : case 'ServerInitialisation' :
debug("ServerInitialisation")
if (data.length < 24) { if (data.length < 24) {
debug("Invalid server initialisation"); debug("Invalid server initialisation");
RFB.state = 'reset'; RFB.state = 'reset';
@ -157,10 +164,10 @@ init_msg: function (data) {
/* Screen size */ /* Screen size */
//debug("data: " + data); //debug("data: " + data);
fb_width = data.shift16(); RFB.fb_width = data.shift16();
fb_height = data.shift16(); RFB.fb_height = data.shift16();
debug("Screen size: " + fb_width + "x" + fb_height); debug("Screen size: " + RFB.fb_width + "x" + RFB.fb_height);
/* PIXEL_FORMAT */ /* PIXEL_FORMAT */
var bpp = data.shift8(); var bpp = data.shift8();
@ -176,89 +183,89 @@ init_msg: function (data) {
/* Connection name/title */ /* Connection name/title */
data.shiftStr(12); data.shiftStr(12);
var name_length = data.shift32(); var name_length = data.shift32();
fb_name = data.shiftStr(name_length); RFB.fb_name = data.shiftStr(name_length);
debug("Name: " + fb_name); debug("Name: " + RFB.fb_name);
$('status').innerHTML = "Connected to: " + fb_name; $('status').innerHTML = "Connected to: " + RFB.fb_name;
Canvas.init('vnc', fb_width, fb_height, RFB.keyDown, RFB.keyUp); Canvas.init('vnc', RFB.fb_width, RFB.fb_height, RFB.keyDown, RFB.keyUp);
RFB.setEncodings(); RFB.setEncodings();
RFB.setPixelFormat(); RFB.setPixelFormat();
RFB.fbUpdateRequest(0, 0, 0, fb_width, fb_height); RFB.fbUpdateRequest(0, 0, 0, RFB.fb_width, RFB.fb_height);
RFB.state = 'normal'; RFB.state = 'normal';
break; break;
} }
debug("<< init_msg"); debug("<< init_msg (" + RFB.state + ")");
}, },
/* Normal RFB/VNC messages */ /* Normal RFB/VNC messages */
normal_msg: function (data) { normal_msg: function (data) {
//debug(">> normal_msg"); //debug(">> normal_msg");
if ((fbu.rects > 0) || (fbu.bytes > 0)) { if ((FBU.rects > 0) || (FBU.bytes > 0)) {
var msg_type = 0; var msg_type = 0;
} else { } else {
var msg_type = data.shift8(); var msg_type = data.shift8();
} }
switch (msg_type) { switch (msg_type) {
case 0: // FramebufferUpdate case 0: // FramebufferUpdate
if (fbu.rects == 0) { if (FBU.rects == 0) {
data.shift8(); data.shift8();
fbu.rects = data.shift16(); FBU.rects = data.shift16();
debug("FramebufferUpdate, " + fbu.rects + " rects"); debug("FramebufferUpdate, " + FBU.rects + " rects");
fbu.bytes = 0; FBU.bytes = 0;
fbu.arr = []; FBU.arr = [];
} else { } else {
//debug("FramebufferUpdate continuation"); //debug("FramebufferUpdate continuation");
} }
while (data.length > 0) { while (data.length > 0) {
//debug("data.length: " + data.length); //debug("data.length: " + data.length);
if (fbu.bytes == 0) { if (FBU.bytes == 0) {
fbu.x = data.shift16(); FBU.x = data.shift16();
fbu.y = data.shift16(); FBU.y = data.shift16();
fbu.width = data.shift16(); FBU.width = data.shift16();
fbu.height = data.shift16(); FBU.height = data.shift16();
fbu.encoding = data.shift32(); FBU.encoding = data.shift32();
//debug('New rect: ' + fbu.x + "," + fbu.y + " -> " + (fbu.x + fbu.width) + "," + (fbu.y + fbu.height)); //debug('New rect: ' + FBU.x + "," + FBU.y + " -> " + (FBU.x + FBU.width) + "," + (FBU.y + FBU.height));
switch (fbu.encoding) { switch (FBU.encoding) {
case 0: // Raw case 0: // Raw
fbu.bytes = fbu.width * fbu.height * fb_Bpp; FBU.bytes = FBU.width * FBU.height * RFB.fb_Bpp;
break; break;
case 1: // Copy-Rect case 1: // Copy-Rect
fbu_bytes = 4; fbu_bytes = 4;
break; break;
} }
} else { } else {
if (data.length >= fbu.bytes) { if (data.length >= FBU.bytes) {
//debug('Done rect: ' + fbu.x + "," + fbu.y + " -> " + (fbu.x + fbu.width) + "," + (fbu.y + fbu.height)); //debug('Done rect: ' + FBU.x + "," + FBU.y + " -> " + (FBU.x + FBU.width) + "," + (FBU.y + FBU.height));
fbu.arr = fbu.arr.concat(data.shiftBytes(fbu.bytes)) FBU.arr = FBU.arr.concat(data.shiftBytes(FBU.bytes))
fbu.bytes = 0; FBU.bytes = 0;
switch (fbu.encoding) { switch (FBU.encoding) {
case 0: // Raw case 0: // Raw
debug('Raw-Rect: ' + fbu.x + "," + fbu.y + " -> " + (fbu.x + fbu.width) + "," + (fbu.y + fbu.height)); debug('Raw-Rect: ' + FBU.x + "," + FBU.y + " -> " + (FBU.x + FBU.width) + "," + (FBU.y + FBU.height));
Canvas.rfbImage(fbu.x, fbu.y, fbu.width, fbu.height, fbu.arr); Canvas.rfbImage(FBU.x, FBU.y, FBU.width, FBU.height, FBU.arr);
break; break;
case 1: // Copy-Rect case 1: // Copy-Rect
debug('Copy-Rect: ' + fbu.x + "," + fbu.y + " -> " + (fbu.x + fbu.width) + "," + (fbu.y + fbu.height)); debug('Copy-Rect: ' + FBU.x + "," + FBU.y + " -> " + (FBU.x + FBU.width) + "," + (FBU.y + FBU.height));
var new_x = fbu.arr.shift16(); var new_x = FBU.arr.shift16();
var new_y = fbu.arr.shift16(); var new_y = FBU.arr.shift16();
Canvas.ctx.drawImage(Canvas.c, fbu.x, fbu.y, fbu.width, fbu.height, new_x, new_y, fbu.width, fbu.height); Canvas.ctx.drawImage(Canvas.c, FBU.x, FBU.y, FBU.width, FBU.height, new_x, new_y, FBU.width, FBU.height);
break; break;
} }
fbu.arr = []; FBU.arr = [];
fbu.rects --; FBU.rects --;
} else { } else {
//debug('Part rect: ' + fbu.x + "," + fbu.y + " -> " + (fbu.x + fbu.width) + "," + (fbu.y + fbu.height)); //debug('Part rect: ' + FBU.x + "," + FBU.y + " -> " + (FBU.x + FBU.width) + "," + (FBU.y + FBU.height));
fbu.bytes = fbu.bytes - data.length; FBU.bytes = FBU.bytes - data.length;
fbu.arr = fbu.arr.concat(data.shiftBytes(data.length)) FBU.arr = FBU.arr.concat(data.shiftBytes(data.length))
} }
} }
//debug("Bytes remaining: " + fbu.bytes); //debug("Bytes remaining: " + FBU.bytes);
} }
//debug("Finished frame buffer update"); //debug("Finished frame buffer update");
break; break;
@ -289,7 +296,7 @@ setPixelFormat: function () {
arr.push8(0); // padding arr.push8(0); // padding
arr.push8(0); // padding arr.push8(0); // padding
arr.push8(fb_Bpp * 8); // bits-per-pixel arr.push8(RFB.fb_Bpp * 8); // bits-per-pixel
arr.push8(24); // depth arr.push8(24); // depth
arr.push8(0); // little-endian arr.push8(0); // little-endian
arr.push8(1); // true-color arr.push8(1); // true-color
@ -342,7 +349,7 @@ keyEvent: function (keysym, down) {
arr.push32(keysym); arr.push32(keysym);
//debug("keyEvent array: " + arr); //debug("keyEvent array: " + arr);
RFB.send_array(arr); RFB.send_array(arr);
RFB.fbUpdateRequest(1, 0, 0, fb_width, fb_height); RFB.fbUpdateRequest(1, 0, 0, RFB.fb_width, RFB.fb_height);
//debug("<< keyEvent"); //debug("<< keyEvent");
}, },
@ -359,12 +366,14 @@ clientCutText: function () {
send_string: function (str) { send_string: function (str) {
//debug(">> send_string: " + str); //debug(">> send_string: " + str);
ws.send(Base64.encode(str)); var arr = str.split('').map(function (chr) {
return chr.charCodeAt(0) } );
RFB.send_array(arr);
}, },
send_array: function (arr) { send_array: function (arr) {
//debug(">> send_array: " + Base64.encode_array(arr)); //debug(">> send_array: " + Base64.encode_array(arr));
ws.send(Base64.encode_array(arr)); RFB.ws.send(Base64.encode_array(arr));
}, },
/* Mirror bits of each character and return as array */ /* Mirror bits of each character and return as array */
@ -386,7 +395,7 @@ passwdTwiddle: function (passwd) {
poller: function () { poller: function () {
if (RFB.state == 'normal') { if (RFB.state == 'normal') {
RFB.fbUpdateRequest(1, 0, 0, fb_width, fb_height); RFB.fbUpdateRequest(1, 0, 0, RFB.fb_width, RFB.fb_height);
RFB.poller.delay(RFB.poll_rate); RFB.poller.delay(RFB.poll_rate);
} }
}, },
@ -410,10 +419,10 @@ keyUp: function (e) {
init_ws: function () { init_ws: function () {
debug(">> init_ws"); debug(">> init_ws");
var uri = "ws://" + vnc_host + ":" + vnc_port; var uri = "ws://" + RFB.host + ":" + RFB.port;
debug("connecting to " + uri); debug("connecting to " + uri);
ws = new WebSocket(uri); RFB.ws = new WebSocket(uri);
ws.onmessage = function(e) { RFB.ws.onmessage = function(e) {
//debug(">> onmessage"); //debug(">> onmessage");
var data = Base64.decode_array(e.data); var data = Base64.decode_array(e.data);
//debug("decoded array: " + data); //debug("decoded array: " + data);
@ -432,12 +441,12 @@ init_ws: function () {
} }
//debug("<< onmessage"); //debug("<< onmessage");
}; };
ws.onopen = function(e) { RFB.ws.onopen = function(e) {
debug(">> onopen"); debug(">> onopen");
RFB.state = "ProtocolVersion"; RFB.state = "ProtocolVersion";
debug("<< onopen"); debug("<< onopen");
}; };
ws.onclose = function(e) { RFB.ws.onclose = function(e) {
debug(">> onclose"); debug(">> onclose");
RFB.state = "closed"; RFB.state = "closed";
debug("<< onclose"); debug("<< onclose");
@ -449,15 +458,15 @@ init_ws: function () {
connect: function () { connect: function () {
debug(">> connect"); debug(">> connect");
vnc_host = $('host').value; RFB.host = $('host').value;
vnc_port = $('port').value; RFB.port = $('port').value;
vnc_password = $('password').value; RFB.password = $('password').value;
if ((!host) || (!port)) { if ((!host) || (!port)) {
debug("must set host and port"); debug("must set host and port");
return; return;
} }
if (ws) { if (RFB.ws) {
ws.close(); RFB.ws.close();
} }
RFB.init_ws(); RFB.init_ws();
$('connectButton').value = "Disconnect"; $('connectButton').value = "Disconnect";
@ -468,8 +477,8 @@ connect: function () {
disconnect: function () { disconnect: function () {
debug(">> disconnect"); debug(">> disconnect");
if (ws) { if (RFB.ws) {
ws.close(); RFB.ws.close();
} }
if (Canvas.ctx) { if (Canvas.ctx) {
Canvas.clear(); Canvas.clear();