Commit da6dd893 authored by Joel Martin's avatar Joel Martin

API changes. Client cursor and settings menu.

The following API changes may affect integrators:

    - Settings have been moved out of the RFB.connect() call. Each
      setting now has it's own setter function: setEncrypt, setBase64,
      setTrueColor, setCursor.

    - Encrypt and cursor settings now default to on.

    - CSS changes:
        - VNC_status_bar for input buttons switched to a element class.

        - VNC_buttons split into VNC_buttons_right and
          VNC_buttons_left

        - New id styles for VNC_settings_menu and VNC_setting

Note: the encrypt, true_color and cursor, logging setting can all be
  set on load using query string variables (in addition to host, port
  and password).

Client cursor (cursor pseudo-encoding) support has been polished and
activated.

The RFB settings are now presented as radio button list items in
a drop-down "Settings" menu when using the default controls.

Also, in the settings menu is the ability to select between alternate
style-sheets.

Cookie and stylesheet selection support added to util.js.
parent f55b6b41
...@@ -14,6 +14,9 @@ Short Term: ...@@ -14,6 +14,9 @@ Short Term:
http://excanvas.sourceforge.net/ http://excanvas.sourceforge.net/
http://code.google.com/p/fxcanvas/ http://code.google.com/p/fxcanvas/
- Fix cursor URI detection in Arora:
- allows data URI, but doesn't actually work
Medium Term: Medium Term:
......
body { body {
background: #ddd;
margin: 0; margin: 0;
font-size: 13px; font-size: 13px;
color: #111; color: #111;
...@@ -56,7 +55,7 @@ body { ...@@ -56,7 +55,7 @@ body {
margin: 0px; margin: 0px;
padding: 1em; padding: 1em;
} }
#VNC_status_bar input { .VNC_status_button {
font-size: 10px; font-size: 10px;
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
...@@ -64,24 +63,46 @@ body { ...@@ -64,24 +63,46 @@ body {
#VNC_status { #VNC_status {
text-align: center; text-align: center;
} }
#VNC_buttons { #VNC_settings_menu {
text-align: right; display: none;
position: absolute;
width: 12em;
border: 1px solid #888;
background-color: #f0f2f6;
padding: 5px; margin: 3px;
z-index: 100; opacity: 1;
text-align: left; white-space: normal;
}
#VNC_settings_menu ul {
list-style: none;
margin: 0;
padding: 0;
} }
.VNC_buttons_right {
text-align: right;
}
.VNC_buttons_left {
text-align: left;
}
.VNC_status_normal { .VNC_status_normal {
background: #111;
color: #fff; color: #fff;
} }
.VNC_status_error { .VNC_status_error {
background: #111;
color: #f44; color: #f44;
} }
.VNC_status_warn { .VNC_status_warn {
background: #111;
color: #ff4; color: #ff4;
} }
#VNC_screen { #VNC_screen {
-webkit-border-radius: 10px; -webkit-border-radius: 10px;
-moz-border-radius: 10px; -moz-border-radius: 10px;
border-radius: 10px; border-radius: 10px;
background: #000; background: #111;
padding: 20px; padding: 20px;
margin: 0 auto; margin: 0 auto;
color: #FFF; color: #FFF;
...@@ -93,6 +114,7 @@ body { ...@@ -93,6 +114,7 @@ body {
table-layout: auto; table-layout: auto;
} }
#VNC_canvas { #VNC_canvas {
background: #111;
margin: 0 auto; margin: 0 auto;
} }
#VNC_clipboard { #VNC_clipboard {
......
...@@ -29,7 +29,7 @@ Canvas = { ...@@ -29,7 +29,7 @@ Canvas = {
prefer_js : false, // make private prefer_js : false, // make private
force_canvas : false, // make private force_canvas : false, // make private
cursor_uri : true, // make private, create getter cursor_uri : true, // make private
true_color : false, true_color : false,
colourMap : [], colourMap : [],
...@@ -47,6 +47,9 @@ mouseMove : null, ...@@ -47,6 +47,9 @@ mouseMove : null,
onMouseButton: function(e, down) { onMouseButton: function(e, down) {
var evt, pos, bmask; var evt, pos, bmask;
if (! Canvas.focused) {
return true;
}
evt = (e ? e : window.event); evt = (e ? e : window.event);
pos = Util.getEventPosition(e, $(Canvas.id)); pos = Util.getEventPosition(e, $(Canvas.id));
bmask = 1 << evt.button; bmask = 1 << evt.button;
...@@ -122,6 +125,9 @@ onKeyUp : function (e) { ...@@ -122,6 +125,9 @@ onKeyUp : function (e) {
onMouseDisable: function (e) { onMouseDisable: function (e) {
var evt, pos; var evt, pos;
if (! Canvas.focused) {
return true;
}
evt = (e ? e : window.event); evt = (e ? e : window.event);
pos = Util.getPosition($(Canvas.id)); pos = Util.getPosition($(Canvas.id));
/* Stop propagation if inside canvas area */ /* Stop propagation if inside canvas area */
...@@ -208,7 +214,7 @@ init: function (id) { ...@@ -208,7 +214,7 @@ init: function (id) {
curDat.push(255); curDat.push(255);
} }
curSave = c.style.cursor; curSave = c.style.cursor;
Canvas.setCursor(curDat, curDat, 2, 2, 8, 8); Canvas.changeCursor(curDat, curDat, 2, 2, 8, 8);
if (c.style.cursor) { if (c.style.cursor) {
Util.Info("Data URI scheme cursor supported"); Util.Info("Data URI scheme cursor supported");
} else { } else {
...@@ -561,13 +567,12 @@ getKeysym: function(e) { ...@@ -561,13 +567,12 @@ getKeysym: function(e) {
isCursor: function() { isCursor: function() {
return Canvas.cursor_uri; return Canvas.cursor_uri;
}, },
changeCursor: function(pixels, mask, hotx, hoty, w, h) {
setCursor: function(pixels, mask, hotx, hoty, w, h) {
var cur = [], cmap, IHDRsz, ANDsz, XORsz, url, idx, x, y; var cur = [], cmap, IHDRsz, ANDsz, XORsz, url, idx, x, y;
//Util.Debug(">> setCursor, x: " + hotx + ", y: " + hoty + ", w: " + w + ", h: " + h); //Util.Debug(">> changeCursor, x: " + hotx + ", y: " + hoty + ", w: " + w + ", h: " + h);
if (!Canvas.cursor_uri) { if (!Canvas.cursor_uri) {
Util.Warn("setCursor called but no cursor data URI support"); Util.Warn("changeCursor called but no cursor data URI support");
return; return;
} }
...@@ -636,7 +641,7 @@ setCursor: function(pixels, mask, hotx, hoty, w, h) { ...@@ -636,7 +641,7 @@ setCursor: function(pixels, mask, hotx, hoty, w, h) {
url = "data:image/x-icon;base64," + Base64.encode(cur); url = "data:image/x-icon;base64," + Base64.encode(cur);
$(Canvas.id).style.cursor = "url(" + url + ") " + hotx + " " + hoty + ", default"; $(Canvas.id).style.cursor = "url(" + url + ") " + hotx + " " + hoty + ", default";
//Util.Debug("<< setCursor, cur.length: " + cur.length); //Util.Debug("<< changeCursor, cur.length: " + cur.length);
} }
}; };
......
This diff is collapsed.
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
} }
#VNC_status_bar input { .VNC_status_button {
font-size: 10px; font-size: 10px;
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
...@@ -44,10 +44,28 @@ ...@@ -44,10 +44,28 @@
#VNC_status { #VNC_status {
text-align: center; text-align: center;
} }
#VNC_buttons { #VNC_settings_menu {
text-align: right; display: none;
position: absolute;
width: 12em;
border: 1px solid #888;
background-color: #f0f2f6;
padding: 5px; margin: 3px;
z-index: 100; opacity: 1;
text-align: left; white-space: normal;
}
#VNC_settings_menu ul {
list-style: none;
margin: 0;
padding: 0;
} }
.VNC_buttons_right {
text-align: right;
}
.VNC_buttons_left {
text-align: left;
}
.VNC_status_normal { .VNC_status_normal {
background: #eee; background: #eee;
} }
......
...@@ -14,37 +14,44 @@ ...@@ -14,37 +14,44 @@
var Util = {}, $; var Util = {}, $;
// Logging/debug routines /*
if (typeof window.console === "undefined") { * Logging/debug routines
if (typeof window.opera !== "undefined") { */
window.console = {
'log' : window.opera.postError, Util.init_logging = function (level) {
'warn' : window.opera.postError, if (typeof window.console === "undefined") {
'error': window.opera.postError }; if (typeof window.opera !== "undefined") {
} else { window.console = {
window.console = { 'log' : window.opera.postError,
'log' : function(m) {}, 'warn' : window.opera.postError,
'warn' : function(m) {}, 'error': window.opera.postError };
'error': function(m) {}}; } else {
window.console = {
'log' : function(m) {},
'warn' : function(m) {},
'error': function(m) {}};
}
} }
}
Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {}; Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {};
switch (level) {
Util.logging = (document.location.href.match( case 'debug': Util.Debug = function (msg) { console.log(msg); };
/logging=([A-Za-z0-9\._\-]*)/) || ['', 'warn'])[1]; case 'info': Util.Info = function (msg) { console.log(msg); };
switch (Util.logging) { case 'warn': Util.Warn = function (msg) { console.warn(msg); };
case 'debug': Util.Debug = function (msg) { console.log(msg); }; case 'error': Util.Error = function (msg) { console.error(msg); };
case 'info': Util.Info = function (msg) { console.log(msg); }; break;
case 'warn': Util.Warn = function (msg) { console.warn(msg); }; default:
case 'error': Util.Error = function (msg) { console.error(msg); }; throw("invalid logging type '" + level + "'");
break; }
default:
throw("invalid logging type '" + Util.logging + "'");
} }
// Initialize logging level
Util.init_logging( (document.location.href.match(
/logging=([A-Za-z0-9\._\-]*)/) ||
['', 'warn'])[1] );
/*
// Simple DOM selector by ID * Simple DOM selector by ID
*/
if (!window.$) { if (!window.$) {
$ = function (id) { $ = function (id) {
if (document.getElementById) { if (document.getElementById) {
...@@ -254,3 +261,69 @@ Util.Flash = (function(){ ...@@ -254,3 +261,69 @@ Util.Flash = (function(){
return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
}()); }());
/*
* Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
*/
// No days means only for this browser session
Util.createCookie = function(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
};
Util.readCookie = function(name, defaultValue) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return (typeof defaultValue !== 'undefined') ? defaultValue : null;
};
Util.eraseCookie = function(name) {
createCookie(name,"",-1);
};
/*
* Alternate stylesheet selection
*/
Util.getStylesheets = function() { var i, links, sheets = [];
links = document.getElementsByTagName("link")
for (i = 0; i < links.length; i++) {
if (links[i].title &&
links[i].rel.toUpperCase().indexOf("STYLESHEET") > -1) {
sheets.push(links[i]);
}
}
return sheets;
};
// No sheet means try and use value from cookie, null sheet used to
// clear all alternates.
Util.selectStylesheet = function(sheet) {
var i, link, sheets = Util.getStylesheets();
if (typeof sheet === 'undefined') {
sheet = 'default';
}
for (i=0; i < sheets.length; i++) {
link = sheets[i];
if (link.title === sheet) {
Util.Debug("Using stylesheet " + sheet);
link.disabled = false;
} else {
Util.Debug("Skipping stylesheet " + link.title);
link.disabled = true;
}
}
return sheet;
};
// call once to disable alternates and get around webkit bug
Util.selectStylesheet(null);
...@@ -61,11 +61,11 @@ RFB = { ...@@ -61,11 +61,11 @@ RFB = {
host : '', host : '',
port : 5900, port : 5900,
password : '', password : '',
encrypt : true, encrypt : true,
true_color : false, 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 local_cursor : true,
connectTimeout : 2000, // time to wait for connection connectTimeout : 2000, // time to wait for connection
...@@ -77,6 +77,7 @@ encodings : [ ...@@ -77,6 +77,7 @@ encodings : [
['RRE', 0x02, 'display_rre'], ['RRE', 0x02, 'display_rre'],
['RAW', 0x00, 'display_raw'], ['RAW', 0x00, 'display_raw'],
['DesktopSize', -223, 'set_desktopsize'], ['DesktopSize', -223, 'set_desktopsize'],
['Cursor', -239, 'set_cursor'],
// Psuedo-encoding settings // Psuedo-encoding settings
['JPEG_quality_lo', -32, 'set_jpeg_quality'], ['JPEG_quality_lo', -32, 'set_jpeg_quality'],
...@@ -85,9 +86,6 @@ encodings : [ ...@@ -85,9 +86,6 @@ encodings : [
// ['compress_hi', -247, 'set_compress_level'] // ['compress_hi', -247, 'set_compress_level']
], ],
encodingCursor :
['Cursor', -239, 'set_cursor'],
setUpdateState: function(externalUpdateState) { setUpdateState: function(externalUpdateState) {
RFB.externalUpdateState = externalUpdateState; RFB.externalUpdateState = externalUpdateState;
...@@ -101,6 +99,43 @@ setCanvasID: function(canvasID) { ...@@ -101,6 +99,43 @@ setCanvasID: function(canvasID) {
RFB.canvasID = canvasID; RFB.canvasID = canvasID;
}, },
setEncrypt: function(encrypt) {
if ((!encrypt) || (encrypt in {'0':1, 'no':1, 'false':1})) {
RFB.encrypt = false;
} else {
RFB.encrypt = true;
}
},
setBase64: function(b64) {
if ((!b64) || (b64 in {'0':1, 'no':1, 'false':1})) {
RFB.b64encode = false;
} else {
RFB.b64encode = true;
}
Util.Debug("Set b64encode to: " + RFB.b64encode);
},
setTrueColor: function(trueColor) {
if ((!trueColor) || (trueColor in {'0':1, 'no':1, 'false':1})) {
RFB.true_color = false;
} else {
RFB.true_color = true;
}
},
setCursor: function(cursor) {
if ((!cursor) || (cursor in {'0':1, 'no':1, 'false':1})) {
RFB.local_cursor = false;
} else {
if (Canvas.isCursor()) {
RFB.local_cursor = true;
} else {
Util.Warn("Browser does not support local cursor");
}
}
},
sendPassword: function(passwd) { sendPassword: function(passwd) {
RFB.password = passwd; RFB.password = passwd;
RFB.state = "Authentication"; RFB.state = "Authentication";
...@@ -149,14 +184,6 @@ load: function () { ...@@ -149,14 +184,6 @@ load: function () {
RFB.updateState('fatal', "No working Canvas"); RFB.updateState('fatal', "No working Canvas");
} }
// Add Cursor pseudo-encoding if supported
/*
if (Canvas.isCursor()) {
Util.Debug("Adding Cursor pseudo-encoding to encoding list");
RFB.encodings.push(RFB.encodingCursor);
}
*/
// Populate encoding lookup tables // Populate encoding lookup tables
RFB.encHandlers = {}; RFB.encHandlers = {};
RFB.encNames = {}; RFB.encNames = {};
...@@ -167,24 +194,12 @@ load: function () { ...@@ -167,24 +194,12 @@ load: function () {
//Util.Debug("<< load"); //Util.Debug("<< load");
}, },
connect: function (host, port, password, encrypt, true_color) { connect: function (host, port, password) {
//Util.Debug(">> connect"); //Util.Debug(">> connect");
RFB.host = host; RFB.host = host;
RFB.port = port; RFB.port = port;
RFB.password = (password !== undefined) ? password : ""; RFB.password = (password !== undefined) ? password : "";
RFB.encrypt = (encrypt !== undefined) ? encrypt : true;
if ((RFB.encrypt === "0") ||
(RFB.encrypt === "no") ||
(RFB.encrypt === "false")) {
RFB.encrypt = false;
}
RFB.true_color = (true_color !== undefined) ? true_color: true;
if ((RFB.true_color === "0") ||
(RFB.true_color === "no") ||
(RFB.true_color === "false")) {
RFB.true_color = false;
}
if ((!RFB.host) || (!RFB.port)) { if ((!RFB.host) || (!RFB.port)) {
RFB.updateState('failed', "Must set host and port"); RFB.updateState('failed', "Must set host and port");
...@@ -501,7 +516,11 @@ init_msg: function () { ...@@ -501,7 +516,11 @@ init_msg: function () {
RFB.timing.history_start = (new Date()).getTime(); RFB.timing.history_start = (new Date()).getTime();
setTimeout(RFB.update_timings, 1000); setTimeout(RFB.update_timings, 1000);
RFB.updateState('normal', "Connected to: " + RFB.fb_name); if (RFB.encrypt) {
RFB.updateState('normal', "Connected (encrypted) to: " + RFB.fb_name);
} else {
RFB.updateState('normal', "Connected (unencrypted) to: " + RFB.fb_name);
}
break; break;
} }
//Util.Debug("<< init_msg"); //Util.Debug("<< init_msg");
...@@ -1051,9 +1070,9 @@ set_cursor: function () { ...@@ -1051,9 +1070,9 @@ set_cursor: function () {
//Util.Debug(" set_cursor, x: " + x + ", y: " + y + ", w: " + w + ", h: " + h); //Util.Debug(" set_cursor, x: " + x + ", y: " + y + ", w: " + w + ", h: " + h);
Canvas.setCursor(RFB.RQ.shiftBytes(pixelslength), Canvas.changeCursor(RFB.RQ.shiftBytes(pixelslength),
RFB.RQ.shiftBytes(masklength), RFB.RQ.shiftBytes(masklength),
x, y, w, h); x, y, w, h);
RFB.FBU.bytes = 0; RFB.FBU.bytes = 0;
RFB.FBU.rects -= 1; RFB.FBU.rects -= 1;
...@@ -1104,14 +1123,24 @@ fixColourMapEntries: function () { ...@@ -1104,14 +1123,24 @@ fixColourMapEntries: function () {
clientEncodings: function () { clientEncodings: function () {
//Util.Debug(">> clientEncodings"); //Util.Debug(">> clientEncodings");
var arr, i; var arr, i, encList = [];
for (i=0; i<RFB.encodings.length; i += 1) {
if ((RFB.encodings[i][0] === "Cursor") &&
(! RFB.local_cursor)) {
Util.Debug("Skipping Cursor pseudo-encoding");
} else {
//Util.Debug("Adding encoding: " + RFB.encodings[i][0]);
encList.push(RFB.encodings[i][1]);
}
}
arr = [2]; // msg-type arr = [2]; // msg-type
arr.push8(0); // padding arr.push8(0); // padding
arr.push16(RFB.encodings.length); // encoding count arr.push16(encList.length); // encoding count
for (i=0; i < encList.length; i += 1) {
for (i=0; i<RFB.encodings.length; i += 1) { arr.push32(encList[i]);
arr.push32(RFB.encodings[i][1]);
} }
//Util.Debug("<< clientEncodings: " + arr); //Util.Debug("<< clientEncodings: " + arr);
return arr; return arr;
......
<html> <html>
<head><title>Canvas Performance Test</title></head> <head>
<title>Canvas Performance Test</title>
<meta http-equiv="X-UA-Compatible" content="IE=8,chrome=1">
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
<script src="include/util.js"></script>
<script src="include/base64.js"></script>
<script src="include/canvas.js"></script>
<script src="face.png.js"></script>
</head>
<body> <body>
Iterations: <input id='iterations' style='width:50' value="100">&nbsp; Iterations: <input id='iterations' style='width:50' value="100">&nbsp;
...@@ -22,13 +31,6 @@ ...@@ -22,13 +31,6 @@
<textarea id="messages" style="font-size: 9;" cols=80 rows=25></textarea> <textarea id="messages" style="font-size: 9;" cols=80 rows=25></textarea>
</body> </body>
<!--
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
<script src="include/util.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 start_width = 300, start_height = 100; var start_width = 300, start_height = 100;
...@@ -39,17 +41,18 @@ ...@@ -39,17 +41,18 @@
cell = $('messages'); cell = $('messages');
cell.innerHTML += msg_cnt + ": " + str + "\n"; cell.innerHTML += msg_cnt + ": " + str + "\n";
cell.scrollTop = cell.scrollHeight; cell.scrollTop = cell.scrollHeight;
msg_cnt += 1;
} }
function test_functions () { function test_functions () {
var img, x, y; var img, x, y;
Canvas.fillRect(0, 0, Canvas.c_wx, Canvas.c_wy, [240,240,240]); Canvas.fillRect(0, 0, Canvas.c_wx, Canvas.c_wy, [240,240,240]);
Canvas.blitStringImage("data:image/png;base64," + face64, 150, 40); Canvas.blitStringImage("data:image/png;base64," + face64, 150, 10);
var himg = new Image(); var himg = new Image();
himg.onload = function () { himg.onload = function () {
Canvas.ctx.drawImage(himg, 200, 10); }; Canvas.ctx.drawImage(himg, 200, 40); };
himg.src = "face.png"; himg.src = "face.png";
/* Test array image data */ /* Test array image data */
...@@ -123,6 +126,7 @@ ...@@ -123,6 +126,7 @@
} }
window.onload = function() { window.onload = function() {
message("in onload");
$('iterations').value = 10; $('iterations').value = 10;
Canvas.init('canvas'); Canvas.init('canvas');
Canvas.resize(start_width, start_height, true); Canvas.resize(start_width, start_height, true);
......
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Cursor Change test</title>
<meta charset="UTF-8">
<!--
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
<script src="include/util.js"></script>
<script src="include/base64.js"></script>
<script src="include/canvas.js"></script>
</head>
<body>
<h1>Roll over the buttons to test cursors</h1>
<br>
<input id=button1 type="button" value="Cursor from file (smiley face)">
<input id=button2 type="button" value="Data URI cursor (crosshair)">
<br>
<br>
<br>
Debug:<br>
<textarea id="debug" style="font-size: 9px;" cols=80 rows=25></textarea>
<br>
<br>
<canvas id="testcanvas" width="100px" height="20px">
Canvas not supported.
</canvas>
</body>
<script>
function debug(str) {
console.log(str);
cell = $('debug');
cell.innerHTML += str + "\n";
cell.scrollTop = cell.scrollHeight;
}
function makeCursor() {
var arr = [], x, y, w = 32, h = 32, hx = 16, hy = 16;
var IHDRsz = 40;
var ANDsz = w * h * 4;
var XORsz = Math.ceil( (w * h) / 8.0 );
// Main header
arr.push16le(0); // Reserved
arr.push16le(2); // .CUR type
arr.push16le(1); // Number of images, 1 for non-animated arr
// Cursor #1
arr.push(w); // width
arr.push(h); // height
arr.push(0); // colors, 0 -> true-color
arr.push(0); // reserved
arr.push16le(hx); // hotspot x coordinate
arr.push16le(hy); // hotspot y coordinate
arr.push32le(IHDRsz + XORsz + ANDsz); // cursor data byte size
arr.push32le(22); // offset of cursor data in the file
// Infoheader for Cursor #1
arr.push32le(IHDRsz); // Infoheader size
arr.push32le(w); // Cursor width
arr.push32le(h*2); // XOR+AND height
arr.push16le(1); // number of planes
arr.push16le(32); // bits per pixel
arr.push32le(0); // type of compression
arr.push32le(XORsz + ANDsz); // Size of Image
arr.push32le(0);
arr.push32le(0);
arr.push32le(0);
arr.push32le(0);
// XOR/color data
for (y = h-1; y >= 0; y--) {
for (x = 0; x < w; x++) {
//if ((x === hx) || (y === (h-hy-1))) {
if ((x === hx) || (y === hy)) {
arr.push(0xe0); // blue
arr.push(0x00); // green
arr.push(0x00); // red
arr.push(0xff); // alpha
} else {
arr.push(0x05); // blue
arr.push(0xe6); // green
arr.push(0x00); // red
arr.push(0x80); // alpha
}
}
}
// AND/bitmask data (seems to be ignored)
for (y = 0; y < h; y++) {
for (x = 0; x < Math.ceil(w / 8); x++) {
arr.push(0x00);
}
}
debug("cursor generated");
return arr;
}
window.onload = function() {
debug("onload");
var cross, cursor, cursor64;
Canvas.init("testcanvas");
debug("Canvas.init() indicates Data URI cursor support is: " + Canvas.isCursor());
$('button1').style.cursor="url(face.png), default";
cursor = makeCursor();
cursor64 = Base64.encode(cursor);
//debug("cursor: " + cursor.slice(0,100) + " (" + cursor.length + ")");
//debug("cursor64: " + cursor64.slice(0,100) + " (" + cursor64.length + ")");
$('button2').style.cursor="url(data:image/x-icon;base64," + cursor64 + "), default";
debug("onload complete");
}
</script>
...@@ -4,8 +4,8 @@ noVNC example: simple example using default controls ...@@ -4,8 +4,8 @@ noVNC example: simple example using default controls
<html> <html>
<head> <head>
<title>VNC Client</title> <title>VNC Client</title>
<link rel="stylesheet" href="include/plain.css" TITLE="plain"> <link rel="stylesheet" href="include/plain.css">
<link rel="Alternate StyleSheet" href="include/black.css" TITLE="Black"> <link rel="alternate stylesheet" href="include/black.css" TITLE="Black">
<!-- <!--
<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>
......
...@@ -21,7 +21,7 @@ Connect parameters are provided in query string: ...@@ -21,7 +21,7 @@ Connect parameters are provided in query string:
<div id="VNC_status_bar" class="VNC_status_bar" style="margin-top: 0px;"> <div id="VNC_status_bar" class="VNC_status_bar" style="margin-top: 0px;">
<table border=0 width=100%><tr> <table border=0 width=100%><tr>
<td><div id="VNC_status">Loading</div></td> <td><div id="VNC_status">Loading</div></td>
<td width=10%><div id="VNC_buttons"> <td width=1%><div id="VNC_buttons">
<input type=button value="Send CtrlAltDel" <input type=button value="Send CtrlAltDel"
id="sendCtrlAltDelButton" id="sendCtrlAltDelButton"
onclick="sendCtrlAltDel();"></div></td> onclick="sendCtrlAltDel();"></div></td>
...@@ -79,23 +79,26 @@ Connect parameters are provided in query string: ...@@ -79,23 +79,26 @@ Connect parameters are provided in query string:
} }
window.onload = function () { window.onload = function () {
var host, port, password, encrypt; var host, port, password;
url = document.location.href; url = document.location.href;
host = (url.match(/host=([A-Za-z0-9.\-]*)/) || ['',''])[1]; host = (url.match(/host=([A-Za-z0-9.\-]*)/) || ['',''])[1];
port = (url.match(/port=([0-9]*)/) || ['',''])[1]; port = (url.match(/port=([0-9]*)/) || ['',''])[1];
password = (url.match(/password=([^&#]*)/) || ['',''])[1]; password = (url.match(/password=([^&#]*)/) || ['',''])[1];
encrypt = (url.match(/encrypt=([A-Za-z0-9]*)/) || ['',1])[1];
true_color = (url.match(/true_color=([A-Za-z0-9]*)/) || ['',1])[1];
if ((!host) || (!port)) { if ((!host) || (!port)) {
updateState('failed', updateState('failed',
"Must specify host and port in URL"); "Must specify host and port in URL");
return; return;
} }
RFB.setEncrypt((url.match(/encrypt=([A-Za-z0-9]*)/) || ['',1])[1]);
RFB.setBase64((url.match(/base64=([A-Za-z0-9]*)/) || ['',1])[1]);
RFB.setTrueColor((url.match(/true_color=([A-Za-z0-9]*)/) || ['',1])[1]);
RFB.setCursor((url.match(/cursor=([A-Za-z0-9]*)/) || ['',true])[1]);
RFB.setUpdateState(updateState); RFB.setUpdateState(updateState);
RFB.load(); RFB.load();
RFB.connect(host, port, password, encrypt, true_color); RFB.connect(host, port, password);
} }
</script> </script>
</html> </html>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment