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