* conflict resolution

This commit is contained in:
primalmotion
2010-07-22 14:28:37 +02:00
14 changed files with 764 additions and 110 deletions
+27 -5
View File
@@ -1,5 +1,4 @@
body {
background: #ddd;
margin: 0;
font-size: 13px;
color: #111;
@@ -56,7 +55,7 @@ body {
margin: 0px;
padding: 1em;
}
#VNC_status_bar input {
.VNC_status_button {
font-size: 10px;
margin: 0px;
padding: 0px;
@@ -64,24 +63,46 @@ body {
#VNC_status {
text-align: center;
}
#VNC_buttons {
text-align: right;
#VNC_settings_menu {
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 {
background: #111;
color: #fff;
}
.VNC_status_error {
background: #111;
color: #f44;
}
.VNC_status_warn {
background: #111;
color: #ff4;
}
#VNC_screen {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
background: #000;
background: #111;
padding: 20px;
margin: 0 auto;
color: #FFF;
@@ -93,6 +114,7 @@ body {
table-layout: auto;
}
#VNC_canvas {
background: #111;
margin: 0 auto;
}
#VNC_clipboard {
+115 -4
View File
@@ -16,8 +16,9 @@ Canvas_native = true;
// Everything namespaced inside Canvas
Canvas = {
prefer_js : false,
force_canvas : false,
prefer_js : false, // make private
force_canvas : false, // make private
cursor_uri : true, // make private
true_color : false,
colourMap : [],
@@ -49,6 +50,9 @@ loadExtra : function () {
onMouseButton: function(e, down) {
var evt, pos, bmask;
if (! Canvas.focused) {
return true;
}
evt = (e ? e : window.event);
pos = Util.getEventPosition(e, $(Canvas.id), Canvas.scale);
bmask = 1 << evt.button;
@@ -124,6 +128,9 @@ onKeyUp : function (e) {
onMouseDisable: function (e) {
var evt, pos;
if (! Canvas.focused) {
return true;
}
evt = (e ? e : window.event);
pos = Util.getPosition($(Canvas.id));
/* Stop propagation if inside canvas area */
@@ -141,7 +148,7 @@ onMouseDisable: function (e) {
init: function (id) {
var c, imgTest, arora;
var c, imgTest, tval, i, curTest, curSave;
Util.Debug(">> Canvas.init");
Canvas.id = id;
@@ -201,6 +208,25 @@ init: function (id) {
Canvas._cmapImage = Canvas._cmapImageFill;
}
/*
* Determine browser support for setting the cursor via data URI
* scheme
*/
curDat = [];
for (i=0; i < 8 * 8 * 4; i++) {
curDat.push(255);
}
curSave = c.style.cursor;
Canvas.changeCursor(curDat, curDat, 2, 2, 8, 8);
if (c.style.cursor) {
Util.Info("Data URI scheme cursor supported");
} else {
Canvas.cursor_uri = false;
Util.Warn("Data URI scheme cursor not supported");
}
c.style.cursor = curSave;
Canvas.colourMap = [];
Canvas.prevStyle = "";
Canvas.focused = true;
@@ -319,6 +345,11 @@ stop: function () {
/* Work around right and middle click browser behaviors */
Util.removeEvent(document, 'click', Canvas.onMouseDisable);
Util.removeEvent(document.body, 'contextmenu', Canvas.onMouseDisable);
// Turn off cursor rendering
if (Canvas.cursor_uri) {
c.style.cursor = "default";
}
},
/*
@@ -586,8 +617,88 @@ getKeysym: function(e) {
}
return keysym;
}
},
isCursor: function() {
return Canvas.cursor_uri;
},
changeCursor: function(pixels, mask, hotx, hoty, w, h) {
var cur = [], cmap, IHDRsz, ANDsz, XORsz, url, idx, x, y;
//Util.Debug(">> changeCursor, x: " + hotx + ", y: " + hoty + ", w: " + w + ", h: " + h);
if (!Canvas.cursor_uri) {
Util.Warn("changeCursor called but no cursor data URI support");
return;
}
cmap = Canvas.colourMap;
IHDRsz = 40;
ANDsz = w * h * 4;
XORsz = Math.ceil( (w * h) / 8.0 );
// Main header
cur.push16le(0); // Reserved
cur.push16le(2); // .CUR type
cur.push16le(1); // Number of images, 1 for non-animated ico
// Cursor #1 header
cur.push(w); // width
cur.push(h); // height
cur.push(0); // colors, 0 -> true-color
cur.push(0); // reserved
cur.push16le(hotx); // hotspot x coordinate
cur.push16le(hoty); // hotspot y coordinate
cur.push32le(IHDRsz + XORsz + ANDsz); // cursor data byte size
cur.push32le(22); // offset of cursor data in the file
// Cursor #1 InfoHeader
cur.push32le(IHDRsz); // Infoheader size
cur.push32le(w); // Cursor width
cur.push32le(h*2); // XOR+AND height
cur.push16le(1); // number of planes
cur.push16le(32); // bits per pixel
cur.push32le(0); // Type of compression
cur.push32le(XORsz + ANDsz); // Size of Image
cur.push32le(0);
cur.push32le(0);
cur.push32le(0);
cur.push32le(0);
// XOR/color data
for (y = h-1; y >= 0; y--) {
for (x = 0; x < w; x++) {
idx = y * Math.ceil(w / 8) + Math.floor(x/8);
alpha = (mask[idx] << (x % 8)) & 0x80 ? 255 : 0;
if (Canvas.true_color) {
idx = ((w * y) + x) * 4;
cur.push(pixels[idx + 2]); // blue
cur.push(pixels[idx + 1]); // green
cur.push(pixels[idx + 0]); // red
cur.push(alpha); // red
} else {
idx = (w * y) + x;
rgb = cmap[pixels[idx]];
cur.push(rgb[2]); // blue
cur.push(rgb[1]); // green
cur.push(rgb[0]); // red
cur.push(alpha); // alpha
}
}
}
// AND/bitmask data (ignored, just needs to be right size)
for (y = 0; y < h; y++) {
for (x = 0; x < Math.ceil(w / 8); x++) {
cur.push(0x00);
}
}
url = "data:image/x-icon;base64," + Base64.encode(cur);
$(Canvas.id).style.cursor = "url(" + url + ") " + hotx + " " + hoty + ", default";
//Util.Debug("<< changeCursor, cur.length: " + cur.length);
}
};
+232 -26
View File
@@ -10,12 +10,16 @@
var DefaultControls = {
settingsOpen : false,
// Render default controls and initialize settings menu
load: function(target) {
var url, html;
var url, html, encrypt, cursor, base64, i, sheet, sheets,
DC = DefaultControls;
/* Handle state updates */
RFB.setUpdateState(DefaultControls.updateState);
RFB.setClipboardReceive(DefaultControls.clipReceive);
RFB.setUpdateState(DC.updateState);
RFB.setClipboardReceive(DC.clipReceive);
/* Populate the 'target' DOM element with default controls */
if (!target) { target = 'vnc'; }
@@ -27,10 +31,6 @@ load: function(target) {
html += ' <li>Port: <input id="VNC_port"></li>';
html += ' <li>Password: <input id="VNC_password"';
html += ' type="password"></li>';
html += ' <li>Encrypt: <input id="VNC_encrypt"';
html += ' type="checkbox"></li>';
html += ' <li>True Color: <input id="VNC_true_color"';
html += ' type="checkbox" checked></li>';
html += ' <li><input id="VNC_connect_button" type="button"';
html += ' value="Loading" disabled></li>';
html += ' </ul>';
@@ -39,8 +39,49 @@ load: function(target) {
html += ' <div id="VNC_status_bar" class="VNC_status_bar" style="margin-top: 0px;">';
html += ' <table border=0 width=100%><tr>';
html += ' <td><div id="VNC_status">Loading</div></td>';
html += ' <td width=10%><div id="VNC_buttons">';
html += ' <input type=button value="Send CtrlAltDel"';
html += ' <td width=1%><div class="VNC_buttons_right">';
html += ' <input type=button class="VNC_status_button" value="Settings"';
html += ' id="menuButton"';
html += ' onclick="DefaultControls.clickSettingsMenu();">';
html += ' <span id="VNC_settings_menu"';
html += ' onmouseover="DefaultControls.canvasBlur();"';
html += ' onmouseout="DefaultControls.canvasFocus();">';
html += ' <ul>';
html += ' <li><input id="VNC_encrypt"';
html += ' type="checkbox" checked> Encrypt</li>';
html += ' <li><input id="VNC_base64"';
html += ' type="checkbox" checked> Base64 Encode</li>';
html += ' <li><input id="VNC_true_color"';
html += ' type="checkbox" checked> True Color</li>';
html += ' <li><input id="VNC_cursor"';
html += ' type="checkbox" checked> Local Cursor</li>';
html += ' <hr>';
// Stylesheet selection dropdown
html += ' <li><select id="VNC_stylesheet" name="vncStyle">';
html += ' <option value="default">default</option>';
sheet = Util.selectStylesheet();
sheets = Util.getStylesheets();
for (i = 0; i < sheets.length; i++) {
html += '<option value="' + sheets[i].title + '">' + sheets[i].title + '</option>';
}
html += ' </select> Style</li>';
// Logging selection dropdown
html += ' <li><select id="VNC_logging" name="vncLogging">';
llevels = ['error', 'warn', 'info', 'debug'];
for (i = 0; i < llevels.length; i++) {
html += '<option value="' + llevels[i] + '">' + llevels[i] + '</option>';
}
html += ' </select> Logging</li>';
html += ' <hr>';
html += ' <li><input type="button" id="VNC_apply" value="Apply"';
html += ' onclick="DefaultControls.settingsApply()"></li>';
html += ' </ul>';
html += ' </span></div></td>';
html += ' <td width=1%><div class="VNC_buttons_right">';
html += ' <input type=button class="VNC_status_button" value="Send CtrlAltDel"';
html += ' id="sendCtrlAltDelButton"';
html += ' onclick="DefaultControls.sendCtrlAltDel();"></div></td>';
html += ' </tr></table>';
@@ -57,8 +98,8 @@ load: function(target) {
html += ' onclick="DefaultControls.clipClear();">';
html += ' <br>';
html += ' <textarea id="VNC_clipboard_text" cols=80 rows=5';
html += ' onfocus="DefaultControls.clipFocus();"';
html += ' onblur="DefaultControls.clipBlur();"';
html += ' onfocus="DefaultControls.canvasBlur();"';
html += ' onblur="DefaultControls.canvasFocus();"';
html += ' onchange="DefaultControls.clipSend();"></textarea>';
html += ' <br>';
html += ' <input id="VNC_scale" type="text"';
@@ -70,16 +111,20 @@ load: function(target) {
html += '</div>';
$(target).innerHTML = html;
// Settings with immediate effects
DC.initSetting('logging', 'default');
Util.init_logging(DC.getSetting('logging'));
DC.initSetting('stylesheet', 'default');
Util.selectStylesheet(DC.getSetting('stylesheet'));
/* Populate the controls if defaults are provided in the URL */
url = document.location.href;
$('VNC_host').value = (url.match(/host=([A-Za-z0-9.\-]*)/) ||
['',''])[1];
$('VNC_port').value = (url.match(/port=([0-9]*)/) ||
['',''])[1];
$('VNC_password').value = (url.match(/password=([^&#]*)/) ||
['',''])[1];
$('VNC_encrypt').checked = (url.match(/encrypt=([A-Za-z0-9]*)/) ||
['',''])[1];
DC.initSetting('host', '');
DC.initSetting('port', '');
DC.initSetting('password', '');
DC.initSetting('encrypt', true);
DC.initSetting('base64', true);
DC.initSetting('true_color', true);
DC.initSetting('cursor', true);
$('VNC_screen').onmousemove = function () {
// Unfocus clipboard when over the VNC area
@@ -89,6 +134,154 @@ load: function(target) {
};
},
// Read a query string variable
getQueryVar: function(name) {
var re = new RegExp('[\?].*' + name + '=([^\&\#]*)');
return (document.location.href.match(re) || ['',null])[1];
},
// Read form control compatible setting from cookie
getSetting: function(name) {
var val, ctrl = $('VNC_' + name);
val = Util.readCookie(name);
if (ctrl.type === 'checkbox') {
if (val.toLowerCase() in {'0':1, 'no':1, 'false':1}) {
val = false;
} else {
val = true;
}
}
return val;
},
// Update cookie and form control setting. If value is not set, then
// updates from control to current cookie setting.
updateSetting: function(name, value) {
var i, ctrl = $('VNC_' + name);
// Save the cookie for this session
if (typeof value !== 'undefined') {
Util.createCookie(name, value);
}
// Update the settings control
value = DefaultControls.getSetting(name);
if (ctrl.type === 'checkbox') {
ctrl.checked = value;
} else if (typeof ctrl.options !== 'undefined') {
for (i = 0; i < ctrl.options.length; i++) {
if (ctrl.options[i].value === value) {
ctrl.selectedIndex = i;
break;
}
}
} else {
ctrl.value = value;
}
},
// Save control setting to cookie
saveSetting: function(name) {
var val, ctrl = $('VNC_' + name);
if (ctrl.type === 'checkbox') {
val = ctrl.checked;
} else if (typeof ctrl.options !== 'undefined') {
val = ctrl.options[ctrl.selectedIndex].value;
} else {
val = ctrl.value;
}
Util.createCookie(name, val);
Util.Debug("Setting saved '" + name + "=" + val + "'");
return val;
},
// Initial page load read/initialization of settings
initSetting: function(name, defVal) {
var val, ctrl = $('VNC_' + name), DC = DefaultControls;
// Check Query string followed by cookie
val = DC.getQueryVar(name);
if (val === null) {
val = Util.readCookie(name, defVal);
}
DC.updateSetting(name, val);
Util.Debug("Setting '" + name + "' initialized to '" + val + "'");
return val;
},
// Toggle the settings menu:
// On open, settings are refreshed from saved cookies.
// On close, settings are applied
clickSettingsMenu: function() {
var DC = DefaultControls;
if (DefaultControls.settingsOpen) {
DC.settingsApply();
DC.closeSettingsMenu();
} else {
DC.updateSetting('encrypt');
DC.updateSetting('base64');
DC.updateSetting('true_color');
if (Canvas.isCursor()) {
DC.updateSetting('cursor');
} else {
DC.updateSettings('cursor', false);
$('VNC_cursor').disabled = true;
}
DC.updateSetting('stylesheet');
DC.updateSetting('logging');
DC.openSettingsMenu();
}
},
// Open menu
openSettingsMenu: function() {
$('VNC_settings_menu').style.display = "block";
DefaultControls.settingsOpen = true;
},
// Close menu (without applying settings)
closeSettingsMenu: function() {
$('VNC_settings_menu').style.display = "none";
DefaultControls.settingsOpen = false;
},
// Disable/enable controls depending on connection state
settingsDisabled: function(disabled) {
$('VNC_encrypt').disabled = disabled;
$('VNC_base64').disabled = disabled;
$('VNC_true_color').disabled = disabled;
if (Canvas.isCursor()) {
$('VNC_cursor').disabled = disabled;
} else {
DefaultControls.updateSettings('cursor', false);
$('VNC_cursor').disabled = true;
}
},
// Save/apply settings when 'Apply' button is pressed
settingsApply: function() {
Util.Debug(">> settingsApply");
var curSS, newSS, DC = DefaultControls;
DC.saveSetting('encrypt');
DC.saveSetting('base64');
DC.saveSetting('true_color');
if (Canvas.isCursor()) {
DC.saveSetting('cursor');
}
DC.saveSetting('stylesheet');
DC.saveSetting('logging');
// Settings with immediate (non-connected related) effect
Util.selectStylesheet(DC.getSetting('stylesheet'));
Util.init_logging(DC.getSetting('logging'));
Util.Debug("<< settingsApply");
},
setPassword: function() {
console.log("setPassword");
RFB.sendPassword($('VNC_password').value);
@@ -113,6 +306,7 @@ updateState: function(state, msg) {
case 'fatal':
c.disabled = true;
cad.disabled = true;
DefaultControls.settingsDisabled(true);
klass = "VNC_status_error";
break;
case 'normal':
@@ -121,6 +315,7 @@ updateState: function(state, msg) {
zb.onclick = DefaultControls.setScale;
c.disabled = false;
cad.disabled = false;
DefaultControls.settingsDisabled(true);
klass = "VNC_status_normal";
break;
@@ -131,6 +326,7 @@ updateState: function(state, msg) {
c.disabled = false;
cad.disabled = true;
DefaultControls.settingsDisabled(false);
klass = "VNC_status_normal";
break;
case 'password':
@@ -139,11 +335,13 @@ updateState: function(state, msg) {
c.disabled = false;
cad.disabled = true;
DefaultControls.settingsDisabled(true);
klass = "VNC_status_warn";
break;
default:
c.disabled = true;
cad.disabled = true;
DefaultControls.settingsDisabled(true);
klass = "VNC_status_warn";
break;
}
@@ -157,28 +355,36 @@ updateState: function(state, msg) {
},
connect: function() {
var host, port, password, encrypt, true_color;
var host, port, password, DC = DefaultControls;
DC.closeSettingsMenu();
host = $('VNC_host').value;
port = $('VNC_port').value;
password = $('VNC_password').value;
encrypt = $('VNC_encrypt').checked;
true_color = $('VNC_true_color').checked;
if ((!host) || (!port)) {
throw("Must set host and port");
}
RFB.connect(host, port, password, encrypt, true_color);
RFB.setEncrypt(DC.getSetting('encrypt'));
RFB.setBase64(DC.getSetting('base64'));
RFB.setTrueColor(DC.getSetting('true_color'));
RFB.setCursor(DC.getSetting('cursor'));
RFB.connect(host, port, password);
},
disconnect: function() {
DefaultControls.closeSettingsMenu();
RFB.disconnect();
},
clipFocus: function() {
canvasBlur: function() {
Canvas.focused = false;
},
clipBlur: function() {
canvasFocus: function() {
Canvas.focused = true;
},
+21 -3
View File
@@ -36,7 +36,7 @@
margin: 0px;
padding: 0px;
}
#VNC_status_bar input {
.VNC_status_button {
font-size: 10px;
margin: 0px;
padding: 0px;
@@ -44,10 +44,28 @@
#VNC_status {
text-align: center;
}
#VNC_buttons {
text-align: right;
#VNC_settings_menu {
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 {
background: #eee;
}
+113 -28
View File
@@ -14,37 +14,44 @@
Util = {};
// Logging/debug routines
if (typeof window.console === "undefined") {
if (typeof window.opera !== "undefined") {
window.console = {
'log' : window.opera.postError,
'warn' : window.opera.postError,
'error': window.opera.postError };
} else {
window.console = {
'log' : function(m) {},
'warn' : function(m) {},
'error': function(m) {}};
/*
* Logging/debug routines
*/
Util.init_logging = function (level) {
if (typeof window.console === "undefined") {
if (typeof window.opera !== "undefined") {
window.console = {
'log' : window.opera.postError,
'warn' : window.opera.postError,
'error': window.opera.postError };
} else {
window.console = {
'log' : function(m) {},
'warn' : function(m) {},
'error': function(m) {}};
}
}
Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {};
switch (level) {
case 'debug': Util.Debug = function (msg) { console.log(msg); };
case 'info': Util.Info = function (msg) { console.log(msg); };
case 'warn': Util.Warn = function (msg) { console.warn(msg); };
case 'error': Util.Error = function (msg) { console.error(msg); };
break;
default:
throw("invalid logging type '" + level + "'");
}
}
// Initialize logging level
Util.init_logging( (document.location.href.match(
/logging=([A-Za-z0-9\._\-]*)/) ||
['', 'warn'])[1] );
Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {};
Util.logging = (document.location.href.match(
/logging=([A-Za-z0-9\._\-]*)/) || ['', 'warn'])[1];
switch (Util.logging) {
case 'debug': Util.Debug = function (msg) { console.log(msg); };
case 'info': Util.Info = function (msg) { console.log(msg); };
case 'warn': Util.Warn = function (msg) { console.warn(msg); };
case 'error': Util.Error = function (msg) { console.error(msg); };
break;
default:
throw("invalid logging type '" + Util.logging + "'");
}
// Simple DOM selector by ID
/*
* Simple DOM selector by ID
*/
if (!window.$) {
$ = function (id) {
if (document.getElementById) {
@@ -77,6 +84,10 @@ Array.prototype.push16 = function (num) {
this.push((num >> 8) & 0xFF,
(num ) & 0xFF );
};
Array.prototype.push16le = function (num) {
this.push((num ) & 0xFF,
(num >> 8) & 0xFF );
};
Array.prototype.shift32 = function () {
@@ -97,6 +108,13 @@ Array.prototype.push32 = function (num) {
(num >> 8) & 0xFF,
(num ) & 0xFF );
};
Array.prototype.push32le = function (num) {
this.push((num ) & 0xFF,
(num >> 8) & 0xFF,
(num >> 16) & 0xFF,
(num >> 24) & 0xFF );
};
Array.prototype.shiftStr = function (len) {
var arr = this.splice(0, len);
@@ -245,3 +263,70 @@ Util.Flash = (function(){
version = v.match(/\d+/g);
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);
+95 -22
View File
@@ -58,11 +58,11 @@ loadExtras: function () {
host : '',
port : 5900,
password : '',
encrypt : true,
true_color : false,
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
@@ -74,6 +74,7 @@ encodings : [
['RRE', 0x02, 'display_rre'],
['RAW', 0x00, 'display_raw'],
['DesktopSize', -223, 'set_desktopsize'],
['Cursor', -239, 'set_cursor'],
// Psuedo-encoding settings
['JPEG_quality_lo', -32, 'set_jpeg_quality'],
@@ -82,6 +83,7 @@ encodings : [
// ['compress_hi', -247, 'set_compress_level']
],
setUpdateState: function(externalUpdateState) {
RFB.externalUpdateState = externalUpdateState;
},
@@ -94,6 +96,43 @@ setCanvasID: function(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) {
RFB.password = passwd;
RFB.state = "Authentication";
@@ -151,24 +190,12 @@ load: function () {
//Util.Debug("<< load");
},
connect: function (host, port, password, encrypt, true_color) {
connect: function (host, port, password) {
//Util.Debug(">> connect");
RFB.host = host;
RFB.port = port;
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)) {
RFB.updateState('failed', "Must set host and port");
@@ -486,7 +513,11 @@ init_msg: function () {
RFB.timing.history_start = (new Date()).getTime();
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;
}
//Util.Debug("<< init_msg");
@@ -1010,10 +1041,40 @@ set_desktopsize : function () {
RFB.timing.fbu_rt_start = (new Date()).getTime();
// Send a new non-incremental request
RFB.send_array(RFB.fbUpdateRequest(0));
Util.Debug("<< set_desktopsize");
RFB.FBU.bytes = 0;
RFB.FBU.rects -= 1;
Util.Debug("<< set_desktopsize");
},
set_cursor: function () {
var x, y, w, h, pixelslength, masklength;
//Util.Debug(">> set_cursor");
x = RFB.FBU.x; // hotspot-x
y = RFB.FBU.y; // hotspot-y
w = RFB.FBU.width;
h = RFB.FBU.height;
pixelslength = w * h * RFB.fb_Bpp;
masklength = Math.floor((w + 7) / 8) * h;
if (RFB.RQ.length < (pixelslength + masklength)) {
//Util.Debug("waiting for cursor encoding bytes");
RFB.FBU.bytes = pixelslength + masklength;
return false;
}
//Util.Debug(" set_cursor, x: " + x + ", y: " + y + ", w: " + w + ", h: " + h);
Canvas.changeCursor(RFB.RQ.shiftBytes(pixelslength),
RFB.RQ.shiftBytes(masklength),
x, y, w, h);
RFB.FBU.bytes = 0;
RFB.FBU.rects -= 1;
//Util.Debug("<< set_cursor");
},
set_jpeg_quality : function () {
@@ -1059,14 +1120,24 @@ fixColourMapEntries: function () {
clientEncodings: function () {
//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.push8(0); // padding
arr.push16(RFB.encodings.length); // encoding count
for (i=0; i<RFB.encodings.length; i += 1) {
arr.push32(RFB.encodings[i][1]);
arr.push16(encList.length); // encoding count
for (i=0; i < encList.length; i += 1) {
arr.push32(encList[i]);
}
//Util.Debug("<< clientEncodings: " + arr);
return arr;
@@ -1533,6 +1604,8 @@ init_ws: function () {
Util.Debug(">> WebSocket.onclose");
if (RFB.state === 'normal') {
RFB.updateState('failed', 'Server disconnected');
} else if (RFB.state === 'ProtocolVersion') {
RFB.updateState('failed', 'Failed to connect to server');
} else {
RFB.updateState('disconnected', 'VNC disconnected');
}