Various cross-browser fixes.
Now working under Arora 0.5. But not Konqueror 4.2.2 (WebSockets never connects). IE support with excanvas still pending.
This commit is contained in:
parent
11bb7a4ae4
commit
d93d3e09ab
11
README.md
11
README.md
|
@ -84,11 +84,16 @@ Browser Support
|
||||||
|
|
||||||
I only currently test under Linux. Here are the current results:
|
I only currently test under Linux. Here are the current results:
|
||||||
|
|
||||||
* Chrome 5.0.* beta: Works great. Native WebSockets support. Very fast.
|
* Chrome 5.0.375.29 beta: Works great. Native WebSockets support. Very
|
||||||
|
fast.
|
||||||
* firefox 3.5, 3.7: Works. Uses flash WebSockets emulator. Large
|
* firefox 3.5, 3.7: Works. Uses flash WebSockets emulator. Large
|
||||||
desktops with full-color image backgrounds are slow.
|
full-color images are slow.
|
||||||
|
* Arora 0.50: Works. Broken putImageData so large full-color images
|
||||||
|
are slow.
|
||||||
|
|
||||||
* Opera 10.10: Unusable: drops web-socket-js events.
|
* Opera 10.10: Unusable: drops web-socket-js events.
|
||||||
* Opera 10.60: Unusable: throws "WRONG_ARGUMENTS_ERR" on connect.
|
* Opera 10.60: Broken: throws "WRONG_ARGUMENTS_ERR" on connect.
|
||||||
|
* Konqueror 4.2.2: Broken: flash WebSockets emulator never connects.
|
||||||
|
|
||||||
|
|
||||||
Integration
|
Integration
|
||||||
|
|
|
@ -49,7 +49,7 @@ base64Pad : '=',
|
||||||
|
|
||||||
encode: function (data) {
|
encode: function (data) {
|
||||||
var result = '';
|
var result = '';
|
||||||
var chrTable = Base64.toBase64Table;
|
var chrTable = Base64.toBase64Table.split('');
|
||||||
var pad = Base64.base64Pad;
|
var pad = Base64.base64Pad;
|
||||||
var length = data.length;
|
var length = data.length;
|
||||||
var i;
|
var i;
|
||||||
|
@ -107,11 +107,11 @@ decode: function (data, offset) {
|
||||||
// Convert one by one.
|
// Convert one by one.
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
for (var i = offset; i < data.length; i++) {
|
for (var i = offset; i < data.length; i++) {
|
||||||
var c = binTable[data[i].charCodeAt(0) & 0x7f];
|
var c = binTable[data.charCodeAt(i) & 0x7f];
|
||||||
var padding = (data[i] == pad);
|
var padding = (data.charAt(i) == pad);
|
||||||
// Skip illegal characters and whitespace
|
// Skip illegal characters and whitespace
|
||||||
if (c == -1) {
|
if (c == -1) {
|
||||||
console.log("Illegal character '" + data[i].charCodeAt(0) + "'");
|
console.log("Illegal character '" + data.charCodeAt(i) + "'");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,20 @@
|
||||||
/*jslint white: false, bitwise: false */
|
/*jslint white: false, bitwise: false */
|
||||||
/*global window, console, $, Util */
|
/*global window, console, $, Util */
|
||||||
|
|
||||||
|
var Canvas, Canvas_native;
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
var pre, extra = "", start, end;
|
||||||
|
if (document.createElement('canvas').getContext) {
|
||||||
|
Canvas_native = true;
|
||||||
|
} else {
|
||||||
|
Canvas_native = false;
|
||||||
|
document.write("<script src='excanvas'><\/script>");
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
|
||||||
// Everything namespaced inside Canvas
|
// Everything namespaced inside Canvas
|
||||||
var Canvas = {
|
Canvas = {
|
||||||
|
|
||||||
prefer_js : false,
|
prefer_js : false,
|
||||||
|
|
||||||
|
@ -93,7 +105,7 @@ onKeyDown: function (e) {
|
||||||
},
|
},
|
||||||
|
|
||||||
onKeyUp : function (e) {
|
onKeyUp : function (e) {
|
||||||
//console.log("keyup: " + e.key + "(" + e.code + ")");
|
//console.log("keyup: " + Canvas.getKeysym(e));
|
||||||
if (! Canvas.focused) {
|
if (! Canvas.focused) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -122,17 +134,86 @@ onMouseDisable: function (e) {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
init: function (id, width, height, true_color, keyPress,
|
init: function (id) {
|
||||||
mouseButton, mouseMove) {
|
var c, imgTest, arora;
|
||||||
console.log(">> Canvas.init");
|
console.log(">> Canvas.init");
|
||||||
|
|
||||||
Canvas.id = id;
|
Canvas.id = id;
|
||||||
|
c = $(Canvas.id);
|
||||||
|
|
||||||
|
if (Canvas_native) {
|
||||||
|
console.log("Using native canvas");
|
||||||
|
// Use default Canvas functions
|
||||||
|
} else {
|
||||||
|
console.warn("Using excanvas canvas emulation");
|
||||||
|
G_vmlCanvasManager.initElement(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! c.getContext) { throw("No getContext method"); }
|
||||||
|
Canvas.ctx = c.getContext('2d');
|
||||||
|
|
||||||
|
Canvas.clear();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine browser feature support and most optimal rendering
|
||||||
|
* methods
|
||||||
|
*/
|
||||||
|
tval = 0;
|
||||||
|
try {
|
||||||
|
imgTest = Canvas.ctx.getImageData(0, 0, 1,1);
|
||||||
|
imgTest.data[0] = 123;
|
||||||
|
imgTest.data[3] = 255;
|
||||||
|
Canvas.ctx.putImageData(imgTest, 0, 0);
|
||||||
|
tval = Canvas.ctx.getImageData(0, 0, 1, 1).data[0];
|
||||||
|
} catch (exc) {
|
||||||
|
}
|
||||||
|
if (tval === 123) {
|
||||||
|
Canvas._rgbxImage = Canvas._rgbxImageData;
|
||||||
|
Canvas._cmapImage = Canvas._cmapImageData;
|
||||||
|
if (Canvas.ctx.createImageData) {
|
||||||
|
// If it's there, it's faster
|
||||||
|
console.log("Using Canvas createImageData");
|
||||||
|
Canvas._imageData = Canvas._imageDataCreate;
|
||||||
|
} else if (Canvas.ctx.getImageData) {
|
||||||
|
console.log("Using Canvas getImageData");
|
||||||
|
Canvas._imageData = Canvas._imageDataGet;
|
||||||
|
} else {
|
||||||
|
console.log("No imageData support");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Util.Engine.webkit) {
|
||||||
|
console.log("Prefering javascript operations");
|
||||||
|
Canvas.prefer_js = true;
|
||||||
|
} else {
|
||||||
|
console.log("Prefering Canvas operations");
|
||||||
|
Canvas.prefer_js = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("No imageData, using fillRect (slow)");
|
||||||
|
Canvas._rgbxImage = Canvas._rgbxImageFill;
|
||||||
|
Canvas._cmapImage = Canvas._cmapImageFill;
|
||||||
|
Canvas.prefer_js = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Canvas.colourMap = [];
|
||||||
|
Canvas.prevStyle = "";
|
||||||
|
Canvas.focused = true;
|
||||||
|
|
||||||
|
//console.log("<< Canvas.init");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
start: function (keyPress, mouseButton, mouseMove) {
|
||||||
|
var c;
|
||||||
|
console.log(">> Canvas.start");
|
||||||
|
|
||||||
|
c = $(Canvas.id);
|
||||||
Canvas.keyPress = keyPress || null;
|
Canvas.keyPress = keyPress || null;
|
||||||
Canvas.mouseButton = mouseButton || null;
|
Canvas.mouseButton = mouseButton || null;
|
||||||
Canvas.mouseMove = mouseMove || null;
|
Canvas.mouseMove = mouseMove || null;
|
||||||
|
|
||||||
var c = $(Canvas.id);
|
|
||||||
Util.addEvent(document, 'keydown', Canvas.onKeyDown);
|
Util.addEvent(document, 'keydown', Canvas.onKeyDown);
|
||||||
Util.addEvent(document, 'keyup', Canvas.onKeyUp);
|
Util.addEvent(document, 'keyup', Canvas.onKeyUp);
|
||||||
Util.addEvent(c, 'mousedown', Canvas.onMouseDown);
|
Util.addEvent(c, 'mousedown', Canvas.onMouseDown);
|
||||||
|
@ -145,34 +226,26 @@ init: function (id, width, height, true_color, keyPress,
|
||||||
Util.addEvent(document, 'click', Canvas.onMouseDisable);
|
Util.addEvent(document, 'click', Canvas.onMouseDisable);
|
||||||
Util.addEvent(document.body, 'contextmenu', Canvas.onMouseDisable);
|
Util.addEvent(document.body, 'contextmenu', Canvas.onMouseDisable);
|
||||||
|
|
||||||
Canvas.resize(width, height);
|
//console.log("<< Canvas.start");
|
||||||
Canvas.c_wx = c.offsetWidth;
|
|
||||||
Canvas.c_wy = c.offsetHeight;
|
|
||||||
Canvas.true_color = true_color;
|
|
||||||
Canvas.colourMap = [];
|
|
||||||
|
|
||||||
if (! c.getContext) { return; }
|
|
||||||
Canvas.ctx = c.getContext('2d');
|
|
||||||
|
|
||||||
Canvas.prevStyle = "";
|
|
||||||
Canvas.focused = true;
|
|
||||||
|
|
||||||
if (Util.Engine.webkit) {
|
|
||||||
Canvas.prefer_js = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//console.log("<< Canvas.init");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
clear: function () {
|
clear: function () {
|
||||||
Canvas.ctx.clearRect(0, 0, Canvas.c_wx, Canvas.c_wy);
|
|
||||||
Canvas.resize(640, 20);
|
Canvas.resize(640, 20);
|
||||||
|
Canvas.ctx.clearRect(0, 0, Canvas.c_wx, Canvas.c_wy);
|
||||||
},
|
},
|
||||||
|
|
||||||
resize: function (width, height) {
|
resize: function (width, height, true_color) {
|
||||||
var c = $(Canvas.id);
|
var c = $(Canvas.id);
|
||||||
|
|
||||||
|
if (typeof true_color !== "undefined") {
|
||||||
|
Canvas.true_color = true_color;
|
||||||
|
}
|
||||||
|
|
||||||
c.width = width;
|
c.width = width;
|
||||||
c.height = height;
|
c.height = height;
|
||||||
|
|
||||||
|
Canvas.c_wx = c.offsetWidth;
|
||||||
|
Canvas.c_wy = c.offsetHeight;
|
||||||
},
|
},
|
||||||
|
|
||||||
stop: function () {
|
stop: function () {
|
||||||
|
@ -226,7 +299,7 @@ getTile: function(x, y, width, height, color) {
|
||||||
return img;
|
return img;
|
||||||
},
|
},
|
||||||
|
|
||||||
setTile: function(img, x, y, w, h, color) {
|
setSubTile: function(img, x, y, w, h, color) {
|
||||||
var data, p, rgb, red, green, blue, width, j, i;
|
var data, p, rgb, red, green, blue, width, j, i;
|
||||||
if (Canvas.prefer_js) {
|
if (Canvas.prefer_js) {
|
||||||
data = img.data;
|
data = img.data;
|
||||||
|
@ -255,19 +328,25 @@ setTile: function(img, x, y, w, h, color) {
|
||||||
|
|
||||||
putTile: function(img) {
|
putTile: function(img) {
|
||||||
if (Canvas.prefer_js) {
|
if (Canvas.prefer_js) {
|
||||||
Canvas.rgbxImage(img.x, img.y, img.width, img.height, img.data, 0);
|
Canvas._rgbxImage(img.x, img.y, img.width, img.height, img.data, 0);
|
||||||
//Canvas.ctx.putImageData(img, img.x, img.y);
|
|
||||||
} else {
|
} else {
|
||||||
// No-op, under gecko already done by setTile
|
// No-op, under gecko already done by setSubTile
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_imageDataGet: function(width, height) {
|
||||||
|
return Canvas.ctx.getImageData(0, 0, width, height);
|
||||||
|
},
|
||||||
|
_imageDataCreate: function(width, height) {
|
||||||
|
return Canvas.ctx.createImageData(width, height);
|
||||||
|
},
|
||||||
|
_imageDataRaw: function(width, height) {
|
||||||
|
return {'data': [], 'width': width, 'height': height};
|
||||||
|
},
|
||||||
|
|
||||||
rgbxImage: function(x, y, width, height, arr, offset) {
|
_rgbxImageData: function(x, y, width, height, arr, offset) {
|
||||||
var img, i, j, data;
|
var img, i, j, data;
|
||||||
//console.log("rfbxImage: img: " + img + " x: " + x + " y: " + y + " width: " + width + " height: " + height);
|
img = Canvas._imageData(width, height);
|
||||||
/* Old firefox and Opera don't support createImageData */
|
|
||||||
img = Canvas.ctx.getImageData(0, 0, width, height);
|
|
||||||
data = img.data;
|
data = img.data;
|
||||||
for (i=0, j=offset; i < (width * height * 4); i=i+4, j=j+4) {
|
for (i=0, j=offset; i < (width * height * 4); i=i+4, j=j+4) {
|
||||||
data[i + 0] = arr[j + 0];
|
data[i + 0] = arr[j + 0];
|
||||||
|
@ -278,13 +357,25 @@ rgbxImage: function(x, y, width, height, arr, offset) {
|
||||||
Canvas.ctx.putImageData(img, x, y);
|
Canvas.ctx.putImageData(img, x, y);
|
||||||
},
|
},
|
||||||
|
|
||||||
cmapImage: function(x, y, width, height, arr, offset) {
|
// really slow fallback if we don't have imageData
|
||||||
|
_rgbxImageFill: function(x, y, width, height, arr, offset) {
|
||||||
|
var sx = 0, sy = 0;
|
||||||
|
for (i=0, j=offset; i < (width * height); i+=1, j+=4) {
|
||||||
|
Canvas.fillRect(x+sx, y+sy, 1, 1, [arr[j+0], arr[j+1], arr[j+2]]);
|
||||||
|
sx += 1;
|
||||||
|
if ((sx % width) === 0) {
|
||||||
|
sx = 0;
|
||||||
|
sy += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_cmapImageData: function(x, y, width, height, arr, offset) {
|
||||||
var img, i, j, data, rgb, cmap;
|
var img, i, j, data, rgb, cmap;
|
||||||
img = Canvas.ctx.getImageData(0, 0, width, height);
|
img = Canvas._imageData(width, height);
|
||||||
data = img.data;
|
data = img.data;
|
||||||
cmap = Canvas.colourMap;
|
cmap = Canvas.colourMap;
|
||||||
//console.log("cmapImage x: " + x + ", y: " + y + "arr.slice(0,20): " + arr.slice(0,20));
|
for (i=0, j=offset; i < (width * height * 4); i+=4, j+=1) {
|
||||||
for (i=0, j=offset; i < (width * height * 4); i=i+4, j += 1) {
|
|
||||||
rgb = cmap[arr[j]];
|
rgb = cmap[arr[j]];
|
||||||
data[i + 0] = rgb[0];
|
data[i + 0] = rgb[0];
|
||||||
data[i + 1] = rgb[1];
|
data[i + 1] = rgb[1];
|
||||||
|
@ -294,15 +385,36 @@ cmapImage: function(x, y, width, height, arr, offset) {
|
||||||
Canvas.ctx.putImageData(img, x, y);
|
Canvas.ctx.putImageData(img, x, y);
|
||||||
},
|
},
|
||||||
|
|
||||||
blitImage: function(x, y, width, height, arr, offset) {
|
_cmapImageFill: function(x, y, width, height, arr, offset) {
|
||||||
if (Canvas.true_color) {
|
var sx = 0, sy = 0;
|
||||||
Canvas.rgbxImage(x, y, width, height, arr, offset);
|
cmap = Canvas.colourMap;
|
||||||
} else {
|
console.log("here1: arr[2]: " + arr[2] + ", cmap[arr[2]]: " + cmap[arr[2]]);
|
||||||
Canvas.cmapImage(x, y, width, height, arr, offset);
|
for (i=0, j=offset; i < (width * height); i+=1, j+=1) {
|
||||||
|
Canvas.fillRect(x+sx, y+sy, 1, 1, [arr[j]]);
|
||||||
|
sx += 1;
|
||||||
|
if ((sx % width) === 0) {
|
||||||
|
sx = 0;
|
||||||
|
sy += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
fillRect: function(x, y, width, height, color) {
|
|
||||||
|
blitImage: function(x, y, width, height, arr, offset) {
|
||||||
|
if (Canvas.true_color) {
|
||||||
|
Canvas._rgbxImage(x, y, width, height, arr, offset);
|
||||||
|
} else {
|
||||||
|
Canvas._cmapImage(x, y, width, height, arr, offset);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
blitStringImage: function(str, x, y) {
|
||||||
|
var img = new Image();
|
||||||
|
img.onload = function () { Canvas.ctx.drawImage(img, x, y); };
|
||||||
|
img.src = str;
|
||||||
|
},
|
||||||
|
|
||||||
|
setFillColor: function(color) {
|
||||||
var rgb, newStyle;
|
var rgb, newStyle;
|
||||||
if (Canvas.true_color) {
|
if (Canvas.true_color) {
|
||||||
rgb = color;
|
rgb = color;
|
||||||
|
@ -314,6 +426,10 @@ fillRect: function(x, y, width, height, color) {
|
||||||
Canvas.ctx.fillStyle = newStyle;
|
Canvas.ctx.fillStyle = newStyle;
|
||||||
Canvas.prevStyle = newStyle;
|
Canvas.prevStyle = newStyle;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
fillRect: function(x, y, width, height, color) {
|
||||||
|
Canvas.setFillColor(color);
|
||||||
Canvas.ctx.fillRect(x, y, width, height);
|
Canvas.ctx.fillRect(x, y, width, height);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -171,24 +171,24 @@ Util.getEventPosition = function (e, obj) {
|
||||||
|
|
||||||
// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events
|
// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events
|
||||||
Util.addEvent = function (obj, evType, fn){
|
Util.addEvent = function (obj, evType, fn){
|
||||||
if (obj.addEventListener){
|
if (obj.attachEvent){
|
||||||
obj.addEventListener(evType, fn, false);
|
|
||||||
return true;
|
|
||||||
} else if (obj.attachEvent){
|
|
||||||
var r = obj.attachEvent("on"+evType, fn);
|
var r = obj.attachEvent("on"+evType, fn);
|
||||||
return r;
|
return r;
|
||||||
|
} else if (obj.addEventListener){
|
||||||
|
obj.addEventListener(evType, fn, false);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
throw("Handler could not be attached");
|
throw("Handler could not be attached");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Util.removeEvent = function(obj, evType, fn){
|
Util.removeEvent = function(obj, evType, fn){
|
||||||
if (obj.removeEventListener){
|
if (obj.detachEvent){
|
||||||
obj.removeEventListener(evType, fn, false);
|
|
||||||
return true;
|
|
||||||
} else if (obj.detachEvent){
|
|
||||||
var r = obj.detachEvent("on"+evType, fn);
|
var r = obj.detachEvent("on"+evType, fn);
|
||||||
return r;
|
return r;
|
||||||
|
} else if (obj.removeEventListener){
|
||||||
|
obj.removeEventListener(evType, fn, false);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
throw("Handler could not be removed");
|
throw("Handler could not be removed");
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ true_color : false,
|
||||||
|
|
||||||
b64encode : true, // false means UTF-8 on the wire
|
b64encode : true, // false means UTF-8 on the wire
|
||||||
//b64encode : false, // false means UTF-8 on the wire
|
//b64encode : false, // false means UTF-8 on the wire
|
||||||
connectTimeout : 1000, // time to wait for connection
|
connectTimeout : 3000, // time to wait for connection
|
||||||
|
|
||||||
|
|
||||||
// In preference order
|
// In preference order
|
||||||
|
@ -140,6 +140,9 @@ load: function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize canvas/fxcanvas
|
||||||
|
Canvas.init(RFB.canvasID);
|
||||||
|
|
||||||
// Populate encoding lookup tables
|
// Populate encoding lookup tables
|
||||||
RFB.encHandlers = {};
|
RFB.encHandlers = {};
|
||||||
RFB.encNames = {};
|
RFB.encNames = {};
|
||||||
|
@ -466,8 +469,8 @@ init_msg: function () {
|
||||||
name_length = RQ.shift32();
|
name_length = RQ.shift32();
|
||||||
RFB.fb_name = RQ.shiftStr(name_length);
|
RFB.fb_name = RQ.shiftStr(name_length);
|
||||||
|
|
||||||
Canvas.init(RFB.canvasID, RFB.fb_width, RFB.fb_height, RFB.true_color,
|
Canvas.resize(RFB.fb_width, RFB.fb_height, RFB.true_color);
|
||||||
RFB.keyPress, RFB.mouseButton, RFB.mouseMove);
|
Canvas.start(RFB.keyPress, RFB.mouseButton, RFB.mouseMove);
|
||||||
|
|
||||||
if (RFB.true_color) {
|
if (RFB.true_color) {
|
||||||
RFB.fb_Bpp = 4;
|
RFB.fb_Bpp = 4;
|
||||||
|
@ -873,7 +876,7 @@ display_hextile: function() {
|
||||||
sw = (wh >> 4) + 1;
|
sw = (wh >> 4) + 1;
|
||||||
sh = (wh & 0x0f) + 1;
|
sh = (wh & 0x0f) + 1;
|
||||||
|
|
||||||
Canvas.setTile(tile, sx, sy, sw, sh, color);
|
Canvas.setSubTile(tile, sx, sy, sw, sh, color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Canvas.putTile(tile);
|
Canvas.putTile(tile);
|
||||||
|
@ -1191,7 +1194,7 @@ recv_message_reorder: function(e) {
|
||||||
} else {
|
} else {
|
||||||
console.warn("sequence number mismatch: expected " +
|
console.warn("sequence number mismatch: expected " +
|
||||||
RFB.RQ_seq_num + ", got " + seq_num);
|
RFB.RQ_seq_num + ", got " + seq_num);
|
||||||
if (RFB.RQ_reorder.length > 20) {
|
if (RFB.RQ_reorder.length > 40) {
|
||||||
RFB.updateState('failed', "Re-order queue too long");
|
RFB.updateState('failed', "Re-order queue too long");
|
||||||
} else {
|
} else {
|
||||||
RFB.RQ_reorder = RFB.RQ_reorder.concat(e.data.substr(0));
|
RFB.RQ_reorder = RFB.RQ_reorder.concat(e.data.substr(0));
|
||||||
|
|
|
@ -3,13 +3,16 @@
|
||||||
<body>
|
<body>
|
||||||
Iterations: <input id='iterations' style='width:50' value="100">
|
Iterations: <input id='iterations' style='width:50' value="100">
|
||||||
|
|
||||||
<input id='startButton' type='button' value='Start' style='width:100px'
|
Width: <input id='width' style='width:50' value="640">
|
||||||
onclick="start();">
|
Height: <input id='height' style='width:50' value="480">
|
||||||
|
|
||||||
|
<input id='startButton' type='button' value='Do Performance Test'
|
||||||
|
style='width:150px' onclick="begin();">
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
Canvas:<br>
|
<b>Canvas</b> (should see three squares and two happy faces):<br>
|
||||||
<canvas id="canvas" width="640" height="20"
|
<canvas id="canvas" width="200" height="100"
|
||||||
style="border-style: dotted; border-width: 1px;">
|
style="border-style: dotted; border-width: 1px;">
|
||||||
Canvas not supported.
|
Canvas not supported.
|
||||||
</canvas>
|
</canvas>
|
||||||
|
@ -23,14 +26,12 @@
|
||||||
<script type='text/javascript'
|
<script type='text/javascript'
|
||||||
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<script src="include/mootools.js"></script>
|
|
||||||
<script src="include/util.js"></script>
|
<script src="include/util.js"></script>
|
||||||
<script src="include/canvas.js"></script>
|
<script src="include/canvas.js"></script>
|
||||||
|
<script src="face.png.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var msg_cnt = 0;
|
var msg_cnt = 0;
|
||||||
var width = 800, height = 600;
|
var start_width = 300, start_height = 100;
|
||||||
var iterations;
|
var iterations;
|
||||||
|
|
||||||
function message(str) {
|
function message(str) {
|
||||||
|
@ -40,35 +41,39 @@
|
||||||
cell.scrollTop = cell.scrollHeight;
|
cell.scrollTop = cell.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw () {
|
function test_functions () {
|
||||||
var img, x, y;
|
var img, x, y;
|
||||||
/* Border */
|
Canvas.fillRect(0, 0, Canvas.c_wx, Canvas.c_wy, [240,240,240]);
|
||||||
Canvas.ctx.stroke();
|
|
||||||
Canvas.ctx.rect(0, 0, Canvas.c_wx, Canvas.c_wy);
|
Canvas.blitStringImage("data:image/png;base64," + face64, 150, 40);
|
||||||
Canvas.ctx.stroke();
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Does not work in firefox
|
|
||||||
var himg = new Image();
|
var himg = new Image();
|
||||||
himg.src = "head_ani2.gif"
|
himg.onload = function () {
|
||||||
Canvas.ctx.drawImage(himg, 10, 10);
|
Canvas.ctx.drawImage(himg, 200, 10); };
|
||||||
*/
|
himg.src = "face.png";
|
||||||
|
|
||||||
/* Test array image data */
|
/* Test array image data */
|
||||||
//img = Canvas.ctx.createImageData(50, 50);
|
data = [];
|
||||||
img = Canvas.ctx.getImageData(0, 0, 50, 50);
|
|
||||||
for (y=0; y< 50; y++) {
|
for (y=0; y< 50; y++) {
|
||||||
for (x=0; x< 50; x++) {
|
for (x=0; x< 50; x++) {
|
||||||
img.data[(y*50 + x)*4 + 0] = 255 - parseInt((255 / 50) * y, 10);
|
data[(y*50 + x)*4 + 0] = 255 - parseInt((255 / 50) * y, 10);
|
||||||
img.data[(y*50 + x)*4 + 1] = parseInt((255 / 50) * y, 10);
|
data[(y*50 + x)*4 + 1] = parseInt((255 / 50) * y, 10);
|
||||||
img.data[(y*50 + x)*4 + 2] = parseInt((255 / 50) * x, 10);
|
data[(y*50 + x)*4 + 2] = parseInt((255 / 50) * x, 10);
|
||||||
img.data[(y*50 + x)*4 + 3] = 255;
|
data[(y*50 + x)*4 + 3] = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Canvas.ctx.putImageData(img, 100, 100);
|
Canvas.blitImage(30, 10, 50, 50, data, 0);
|
||||||
|
|
||||||
|
//Canvas.prefer_js = false;
|
||||||
|
img = Canvas.getTile(5,5,16,16,[0,128,128]);
|
||||||
|
Canvas.putTile(img);
|
||||||
|
|
||||||
|
img = Canvas.getTile(90,15,16,16,[0,0,0]);
|
||||||
|
Canvas.setSubTile(img, 0,0,16,16,[128,128,0]);
|
||||||
|
Canvas.putTile(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
function start () {
|
function begin () {
|
||||||
$('startButton').value = "Running";
|
$('startButton').value = "Running";
|
||||||
$('startButton').disabled = true;
|
$('startButton').disabled = true;
|
||||||
setTimeout(start_delayed, 250);
|
setTimeout(start_delayed, 250);
|
||||||
|
@ -89,18 +94,26 @@
|
||||||
message("prefer Canvas ops: " + time2 + "ms total, " +
|
message("prefer Canvas ops: " + time2 + "ms total, " +
|
||||||
(time2 / iterations) + "ms per frame");
|
(time2 / iterations) + "ms per frame");
|
||||||
|
|
||||||
|
Canvas.resize(start_width, start_height, true);
|
||||||
|
test_functions();
|
||||||
$('startButton').disabled = false;
|
$('startButton').disabled = false;
|
||||||
$('startButton').value = "Start";
|
$('startButton').value = "Start";
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_test () {
|
function run_test () {
|
||||||
var color, start_time = (new Date()).getTime();
|
var width, height;
|
||||||
|
width = $('width').value;
|
||||||
|
height = $('height').value;
|
||||||
|
Canvas.resize(width, height);
|
||||||
|
var color, start_time = (new Date()).getTime(), w, h;
|
||||||
for (var i=0; i < iterations; i++) {
|
for (var i=0; i < iterations; i++) {
|
||||||
color = [128, 128, (255 / iterations) * i, 0];
|
color = [128, 128, (255 / iterations) * i, 0];
|
||||||
for (var x=0; x < width; x = x + 16) {
|
for (var x=0; x < width; x = x + 16) {
|
||||||
for (var y=0; y < width; y = y + 16) {
|
for (var y=0; y < height; y = y + 16) {
|
||||||
var tile = Canvas.getTile(x, y, 16, 16, color);
|
w = Math.min(16, width - x);
|
||||||
Canvas.setTile(tile, 0, 0, 16, 16, color);
|
h = Math.min(16, height - y);
|
||||||
|
var tile = Canvas.getTile(x, y, w, h, color);
|
||||||
|
Canvas.setSubTile(tile, 0, 0, w, h, color);
|
||||||
Canvas.putTile(tile);
|
Canvas.putTile(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,11 +123,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
Canvas.init('canvas', width, height);
|
|
||||||
Canvas.stop(); // Shut-off event interception
|
|
||||||
$('iterations').value = 10;
|
$('iterations').value = 10;
|
||||||
draw();
|
Canvas.init('canvas');
|
||||||
|
Canvas.resize(start_width, start_height, true);
|
||||||
message("Canvas initialized");
|
message("Canvas initialized");
|
||||||
|
test_functions();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
var face64 = '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';
|
|
@ -18,14 +18,11 @@
|
||||||
<script type='text/javascript'
|
<script type='text/javascript'
|
||||||
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<script src="include/mootools.js"></script>
|
|
||||||
<script src="include/util.js"></script>
|
<script src="include/util.js"></script>
|
||||||
<script src="include/canvas.js"></script>
|
<script src="include/canvas.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var msg_cnt = 0;
|
var msg_cnt = 0;
|
||||||
var width = 1280, height = 600;
|
var width = 400, height = 200;
|
||||||
var iterations;
|
var iterations;
|
||||||
|
|
||||||
function message(str) {
|
function message(str) {
|
||||||
|
@ -54,8 +51,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
Canvas.init('canvas', width, height, true, keyPress,
|
Canvas.init('canvas');
|
||||||
mouseButton, mouseMove);
|
Canvas.resize(width, height);
|
||||||
|
Canvas.start(keyPress, mouseButton, mouseMove);
|
||||||
message("Canvas initialized");
|
message("Canvas initialized");
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
4
vnc.html
4
vnc.html
|
@ -11,6 +11,10 @@ noVNC example: simple example using default controls
|
||||||
<div id='vnc'>Loading</div>
|
<div id='vnc'>Loading</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<script type='text/javascript'
|
||||||
|
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
||||||
|
-->
|
||||||
<script src="include/vnc.js"></script>
|
<script src="include/vnc.js"></script>
|
||||||
<script src="include/default_controls.js"></script>
|
<script src="include/default_controls.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
Loading…
Reference in New Issue