Commit 5210330a authored by Joel Martin's avatar Joel Martin

Refactor configuration attributes.

- Add conf_defaults which accepts an array of configuration
  attributes.
- Split out user configuration defaults from the actual configuration
  object.
- Add mode field and enforce read-only, write-once, read-write modes.
parent d890e864
......@@ -9,11 +9,11 @@
/*jslint browser: true, white: false, bitwise: false */
/*global Util, Base64, changeCursor */
function Display(conf) {
function Display(defaults) {
"use strict";
conf = conf || {}; // Configuration
var that = {}, // Public API interface
var that = {}, // Public API methods
conf = {}, // Configuration attributes
// Private Display namespace variables
c_ctx = null,
......@@ -33,38 +33,25 @@ var that = {}, // Public API interface
c_webkit_bug = false,
c_flush_timer = null;
// Configuration settings
function cdef(v, type, defval, desc) {
Util.conf_default(conf, that, v, type, defval, desc); }
function cdef_ro(v, type, defval, desc) {
Util.conf_default({}, that, v, type, defval, desc); }
// Configuration attributes
Util.conf_defaults(conf, that, defaults, [
['target', 'wo', 'dom', null, 'Canvas element for rendering'],
['context', 'ro', 'raw', null, 'Canvas 2D context for rendering (read-only)'],
['logo', 'rw', 'raw', null, 'Logo to display when cleared: {"width": width, "height": height, "data": data}'],
['true_color', 'rw', 'bool', true, 'Use true-color pixel data'],
['colourMap', 'rw', 'arr', [], 'Colour map array (when not true-color)'],
['scale', 'rw', 'float', 1.0, 'Display area scale factor 0.0 - 1.0'],
['width', 'rw', 'int', null, 'Display area width'],
['height', 'rw', 'int', null, 'Display area height'],
// Capability settings, default can be overridden
cdef('target', 'dom', null, 'Canvas element for rendering');
cdef_ro('context', 'raw', null, 'Canvas 2D context for rendering (read-only)');
cdef('logo', 'raw', null, 'Logo to display when cleared: {"width": width, "height": height, "data": data}');
cdef('true_color', 'bool', true, 'Use true-color pixel data');
cdef('colourMap', 'arr', [], 'Colour map array (when not true-color)');
cdef('scale', 'float', 1.0, 'Display area scale factor 0.0 - 1.0');
cdef_ro('width', 'int', null, 'Display area width (read-only)');
cdef_ro('height', 'int', null, 'Display area height (read-only)');
['render_mode', 'ro', 'str', '', 'Canvas rendering mode (read-only)'],
cdef_ro('render_mode', 'str', '', 'Canvas rendering mode (read-only)');
cdef('prefer_js', 'str', null, 'Prefer Javascript over canvas methods');
cdef('cursor_uri', 'raw', null, 'Can we render cursor using data URI');
['prefer_js', 'rw', 'str', null, 'Prefer Javascript over canvas methods'],
['cursor_uri', 'rw', 'raw', null, 'Can we render cursor using data URI']
]);
// Override some specific getters/setters
that.set_prefer_js = function(val) {
if (val && c_forceCanvas) {
Util.Warn("Preferring Javascript to Canvas ops is not supported");
return false;
}
conf.prefer_js = val;
return true;
};
that.set_render_mode = function () { throw("render_mode is read-only"); };
that.get_context = function () { return c_ctx; };
that.set_scale = function(scale) { rescale(scale); };
......@@ -74,8 +61,15 @@ that.get_width = function() { return c_width; };
that.set_height = function (val) { that.resize(c_width, val); };
that.get_height = function() { return c_height; };
that.set_context = function () { throw("context is read-only"); };
that.get_context = function () { return c_ctx; };
that.set_prefer_js = function(val) {
if (val && c_forceCanvas) {
Util.Warn("Preferring Javascript to Canvas ops is not supported");
return false;
}
conf.prefer_js = val;
return true;
};
//
......
......@@ -12,33 +12,28 @@
// Keyboard event handler
//
function Keyboard(conf) {
function Keyboard(defaults) {
"use strict";
conf = conf || {}; // Configuration
var that = {}, // Public API interface
var that = {}, // Public API methods
conf = {}, // Configuration attributes
keyDownList = []; // List of depressed keys
// (even if they are happy)
// Configuration attributes
Util.conf_defaults(conf, that, defaults, [
['target', 'wo', 'dom', document, 'DOM element that captures keyboard input'],
['focused', 'rw', 'bool', true, 'Capture and send key events'],
// Configuration settings
function cdef(v, type, defval, desc) {
Util.conf_default(conf, that, v, type, defval, desc); }
['onKeyPress', 'rw', 'func', null, 'Handler for key press/release']
]);
// Capability settings, default can be overridden
cdef('target', 'dom', document, 'DOM element that captures keyboard input');
cdef('focused', 'bool', true, 'Capture and send key events');
cdef('onKeyPress', 'func', null, 'Handler for key press/release');
that.set_target = function() { throw("target cannot be changed"); };
//
// Private functions
//
// From the event keyCode return the keysym value for keys that need
// to be suppressed otherwise they may trigger unintended browser
// actions
......@@ -452,26 +447,22 @@ return that; // Return the public API interface
// Mouse event handler
//
function Mouse(conf) {
function Mouse(defaults) {
"use strict";
conf = conf || {}; // Configuration
var that = {}; // Public API interface
// Configuration settings
function cdef(v, type, defval, desc) {
Util.conf_default(conf, that, v, type, defval, desc); }
var that = {}, // Public API methods
conf = {}; // Configuration attributes
// Capability settings, default can be overridden
cdef('target', 'dom', document, 'DOM element that captures mouse input');
cdef('focused', 'bool', true, 'Capture and send mouse clicks/movement');
cdef('scale', 'float', 1.0, 'Viewport scale factor 0.0 - 1.0');
// Configuration attributes
Util.conf_defaults(conf, that, defaults, [
['target', 'ro', 'dom', document, 'DOM element that captures mouse input'],
['focused', 'rw', 'bool', true, 'Capture and send mouse clicks/movement'],
['scale', 'rw', 'float', 1.0, 'Viewport scale factor 0.0 - 1.0'],
cdef('onMouseButton', 'func', null, 'Handler for mouse button click/release');
cdef('onMouseMove', 'func', null, 'Handler for mouse movement');
['onMouseButton', 'rw', 'func', null, 'Handler for mouse button click/release'],
['onMouseMove', 'rw', 'func', null, 'Handler for mouse movement']
]);
that.set_target = function() { throw("target cannot be changed"); };
//
// Private functions
......
......@@ -10,11 +10,11 @@
/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, noVNC_logo */
function RFB(conf) {
function RFB(defaults) {
"use strict";
conf = conf || {}; // Configuration
var that = {}, // Public API interface
var that = {}, // Public API methods
conf = {}, // Configuration attributes
// Pre-declare private functions used before definitions (jslint)
init_vars, updateState, fail, handle_message,
......@@ -113,56 +113,51 @@ var that = {}, // Public API interface
test_mode = false,
def_con_timeout = Websock_native ? 2 : 5,
/* Mouse state */
mouse_buttonMask = 0,
mouse_arr = [];
//
// Configuration settings
//
function cdef(v, type, defval, desc) {
Util.conf_default(conf, that, v, type, defval, desc); }
cdef('target', 'dom', null, 'VNC display rendering Canvas object');
cdef('focusContainer', 'dom', document, 'DOM element that captures keyboard input');
cdef('encrypt', 'bool', false, 'Use TLS/SSL/wss encryption');
cdef('true_color', 'bool', true, 'Request true color pixel data');
cdef('local_cursor', 'bool', false, 'Request locally rendered cursor');
cdef('shared', 'bool', true, 'Request shared mode');
if (Websock_native) {
cdef('connectTimeout', 'int', 2, 'Time (s) to wait for connection');
} else {
cdef('connectTimeout', 'int', 5, 'Time (s) to wait for connection');
}
cdef('disconnectTimeout', 'int', 3, 'Time (s) to wait for disconnection');
cdef('check_rate', 'int', 217, 'Timing (ms) of send/receive check');
cdef('fbu_req_rate', 'int', 1413, 'Timing (ms) of frameBufferUpdate requests');
// Callback functions
cdef('onUpdateState', 'func', function() { },
'onUpdateState(rfb, state, oldstate, statusMsg): RFB state update/change ');
cdef('onPasswordRequired', 'func', function() { },
'onPasswordRequired(rfb): VNC password is required ');
cdef('onClipboard', 'func', function() { },
'onClipboard(rfb, text): RFB clipboard contents received');
cdef('onBell', 'func', function() { },
'onBell(rfb): RFB Bell message received ');
cdef('onFBUReceive', 'func', function() { },
'onFBUReceive(rfb, fbu): RFB FBU received but not yet processed ');
cdef('onFBUComplete', 'func', function() { },
'onFBUComplete(rfb, fbu): RFB FBU received and processed ');
// These callback names are deprecated
cdef('updateState', 'func', function() { },
'obsolete, use onUpdateState');
cdef('clipboardReceive', 'func', function() { },
'obsolete, use onClipboard');
// Override/add some specific getters/setters
// Configuration attributes
Util.conf_defaults(conf, that, defaults, [
['target', 'wo', 'dom', null, 'VNC display rendering Canvas object'],
['focusContainer', 'wo', 'dom', document, 'DOM element that captures keyboard input'],
['encrypt', 'rw', 'bool', false, 'Use TLS/SSL/wss encryption'],
['true_color', 'rw', 'bool', true, 'Request true color pixel data'],
['local_cursor', 'rw', 'bool', false, 'Request locally rendered cursor'],
['shared', 'rw', 'bool', true, 'Request shared mode'],
['connectTimeout', 'rw', 'int', def_con_timeout, 'Time (s) to wait for connection'],
['disconnectTimeout', 'rw', 'int', 3, 'Time (s) to wait for disconnection'],
['check_rate', 'rw', 'int', 217, 'Timing (ms) of send/receive check'],
['fbu_req_rate', 'rw', 'int', 1413, 'Timing (ms) of frameBufferUpdate requests'],
// Callback functions
['onUpdateState', 'rw', 'func', function() { },
'onUpdateState(rfb, state, oldstate, statusMsg): RFB state update/change '],
['onPasswordRequired', 'rw', 'func', function() { },
'onPasswordRequired(rfb): VNC password is required '],
['onClipboard', 'rw', 'func', function() { },
'onClipboard(rfb, text): RFB clipboard contents received'],
['onBell', 'rw', 'func', function() { },
'onBell(rfb): RFB Bell message received '],
['onFBUReceive', 'rw', 'func', function() { },
'onFBUReceive(rfb, fbu): RFB FBU received but not yet processed '],
['onFBUComplete', 'rw', 'func', function() { },
'onFBUComplete(rfb, fbu): RFB FBU received and processed '],
// These callback names are deprecated
['updateState', 'rw', 'func', function() { },
'obsolete, use onUpdateState'],
['clipboardReceive', 'rw', 'func', function() { },
'obsolete, use onClipboard']
]);
// Override/add some specific configuration getters/setters
that.set_local_cursor = function(cursor) {
if ((!cursor) || (cursor in {'0':1, 'no':1, 'false':1})) {
conf.local_cursor = false;
......@@ -175,18 +170,12 @@ that.set_local_cursor = function(cursor) {
}
};
that.get_display = function() {
return display;
};
that.get_keyboard = function() {
return keyboard;
};
that.get_mouse = function() {
return mouse;
};
// These are fake configuration getters
that.get_display = function() { return display; };
that.get_keyboard = function() { return keyboard; };
that.get_mouse = function() { return mouse; };
......
......@@ -83,60 +83,83 @@ Util.get_logging = function () {
Util.init_logging();
// Set defaults for Crockford style function namespaces
Util.conf_default = function(cfg, api, v, type, defval, desc) {
// Description
api['get_' + v + '_desc'] = desc;
// Default getter
if (typeof api['get_' + v] === 'undefined') {
api['get_' + v] = function (idx) {
if ((type in {'arr':1, 'array':1}) &&
(typeof idx !== 'undefined')) {
return cfg[v][idx];
// Set configuration default for Crockford style function namespaces
Util.conf_default = function(cfg, api, defaults, v, mode, type, defval, desc) {
var getter, setter;
// Default getter function
getter = function (idx) {
if ((type in {'arr':1, 'array':1}) &&
(typeof idx !== 'undefined')) {
return cfg[v][idx];
} else {
return cfg[v];
}
};
// Default setter function
setter = function (val, idx) {
if (type in {'boolean':1, 'bool':1}) {
if ((!val) || (val in {'0':1, 'no':1, 'false':1})) {
val = false;
} else {
return cfg[v];
val = true;
}
};
} else if (type in {'integer':1, 'int':1}) {
val = parseInt(val, 10);
} else if (type === 'func') {
if (!val) {
val = function () {};
}
}
if (typeof idx !== 'undefined') {
cfg[v][idx] = val;
} else {
cfg[v] = val;
}
};
// Set the description
api[v + '_description'] = desc;
// Set the getter function
if (typeof api['get_' + v] === 'undefined') {
api['get_' + v] = getter;
}
// Default setter
// Set the setter function with extra sanity checks
if (typeof api['set_' + v] === 'undefined') {
api['set_' + v] = function (val, idx) {
if (type in {'boolean':1, 'bool':1}) {
if ((!val) || (val in {'0':1, 'no':1, 'false':1})) {
val = false;
} else {
val = true;
}
} else if (type in {'integer':1, 'int':1}) {
val = parseInt(val, 10);
} else if (type === 'func') {
if (!val) {
val = function () {};
}
}
if (typeof idx !== 'undefined') {
cfg[v][idx] = val;
} else {
cfg[v] = val;
if (mode in {'RO':1, 'ro':1}) {
throw(v + " is read-only");
} else if ((mode in {'WO':1, 'wo':1}) &&
(typeof cfg[v] !== 'undefined')) {
throw(v + " can only be set once");
}
setter(val, idx);
};
}
if (typeof cfg[v] === 'undefined') {
// Set to default
if (type in {'arr':1, 'array':1}) {
if (! (defval instanceof Array)) {
defval = [];
}
}
api['set_' + v](defval);
} else {
// Coerce existing setting to the right type
api['set_' + v](cfg[v]);
// Set the default value
if (typeof defaults[v] !== 'undefined') {
defval = defaults[v];
} else if ((type in {'arr':1, 'array':1}) &&
(! (defval instanceof Array))) {
defval = [];
}
// Coerce existing setting to the right type
//Util.Debug("v: " + v + ", defval: " + defval + ", defaults[v]: " + defaults[v]);
setter(defval);
};
// Set group of configuration defaults
Util.conf_defaults = function(cfg, api, defaults, arr) {
var i;
for (i = 0; i < arr.length; i++) {
Util.conf_default(cfg, api, defaults, arr[i][0], arr[i][1],
arr[i][2], arr[i][3], arr[i][4]);
}
}
/*
......
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