Merge pull request #496 from kanaka/refactor/modularized

Enable noVNC to become Browserifiable
This commit is contained in:
Solly Ross 2016-09-16 16:16:09 -04:00 committed by GitHub
commit 386db8f54f
82 changed files with 1970 additions and 3534 deletions

3
.gitignore vendored
View File

@ -4,3 +4,6 @@ tests/data_*.js
utils/rebind.so
utils/websockify
node_modules
build
lib
recordings

21
.npmignore Normal file
View File

@ -0,0 +1,21 @@
app
core
favicon.ico
.gitmodules
node_modules
.*
*~
*.swp
*.swo
tests
.travis.yml
utils
docs/notes
docs/links
docs/release.txt
docs/rfb_notes
docs/*.pdf
vnc.html
vnc_auto.html
karma.conf.js
docs/flash_policy.txt

View File

@ -5,19 +5,19 @@ Public License 2.0). The noVNC core library is composed of the
Javascript code necessary for full noVNC operation. This includes (but
is not limited to):
include/base64.js
include/des.js
include/display.js
include/input.js
include/keysym.js
include/logo.js
include/playback.js
include/rfb.js
include/ui.js
include/util.js
include/websock.js
include/webutil.js
include/xtscancodes.js
core/base64.js
core/des.js
core/display.js
core/input/devices.js
core/input/keysym.js
core/logo.js
core/playback.js
core/rfb.js
app/ui.js
core/util.js
core/websock.js
app/webutil.js
core/input/xtscancodes.js
The HTML, CSS, font and images files that included with the noVNC
source distibution (or repository) are not considered part of the
@ -29,12 +29,12 @@ The HTML, CSS, font and image files are licensed as follows:
*.html : 2-Clause BSD license
include/*.css : 2-Clause BSD license
app/styles/*.css : 2-Clause BSD license
include/Orbitron* : SIL Open Font License 1.1
app/styles/Orbitron* : SIL Open Font License 1.1
(Copyright 2009 Matt McInerney)
images/ : Creative Commons Attribution-ShareAlike
app/images/ : Creative Commons Attribution-ShareAlike
http://creativecommons.org/licenses/by-sa/3.0/
Some portions of noVNC are copyright to their individual authors.
@ -45,18 +45,12 @@ The are several files and projects that have been incorporated into
the noVNC core library. Here is a list of those files and the original
licenses (all MPL 2.0 compatible):
include/base64.js : MPL 2.0
core/base64.js : MPL 2.0
include/des.js : Various BSD style licenses
core/des.js : Various BSD style licenses
include/chrome-app/tcp-stream.js
: Apache 2.0 license
utils/websockify
utils/websocket.py : LGPL 3
utils/inflator.partial.js
include/inflator.js : MIT (for pako)
utils/inflator.mod.js
include/inflator.js : MIT (for pako)
Any other files not mentioned above are typically marked with
a copyright/license header at the top of the file. The default noVNC

View File

Before

Width:  |  Height:  |  Size: 339 B

After

Width:  |  Height:  |  Size: 339 B

View File

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 501 B

View File

Before

Width:  |  Height:  |  Size: 404 B

After

Width:  |  Height:  |  Size: 404 B

View File

Before

Width:  |  Height:  |  Size: 354 B

After

Width:  |  Height:  |  Size: 354 B

View File

Before

Width:  |  Height:  |  Size: 317 B

After

Width:  |  Height:  |  Size: 317 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 963 B

After

Width:  |  Height:  |  Size: 963 B

View File

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 453 B

View File

Before

Width:  |  Height:  |  Size: 851 B

After

Width:  |  Height:  |  Size: 851 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 511 B

After

Width:  |  Height:  |  Size: 511 B

View File

Before

Width:  |  Height:  |  Size: 517 B

After

Width:  |  Height:  |  Size: 517 B

View File

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 497 B

View File

Before

Width:  |  Height:  |  Size: 513 B

After

Width:  |  Height:  |  Size: 513 B

View File

Before

Width:  |  Height:  |  Size: 390 B

After

Width:  |  Height:  |  Size: 390 B

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 387 B

View File

Before

Width:  |  Height:  |  Size: 735 B

After

Width:  |  Height:  |  Size: 735 B

View File

@ -280,7 +280,7 @@ html {
/* Control bar */
#noVNC_control_bar {
position:fixed;
display:block;
height:36px;
left:0;

View File

@ -8,19 +8,30 @@
*/
/* jslint white: false, browser: true */
/* global window, $D, Util, WebUtil, RFB, Display */
/* global window, document.getElementById, Util, WebUtil, RFB, Display */
/* [module]
* import Util from "../core/util";
* import KeyTable from "../core/input/keysym";
* import RFB from "../core/rfb";
* import Display from "../core/display";
* import WebUtil from "./webutil";
*/
var UI;
(function () {
"use strict";
/* [begin skip-as-module] */
// Load supporting scripts
WebUtil.load_scripts(
{'core': ["base64.js", "websock.js", "des.js", "input/keysymdef.js",
"input/xtscancodes.js", "input/util.js", "input/devices.js",
"display.js", "inflator.js", "rfb.js", "input/keysym.js"]});
window.onscriptsload = function () { UI.load(); };
Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
"keysymdef.js", "xtscancodes.js", "keyboard.js",
"input.js", "display.js", "rfb.js", "keysym.js",
"inflator.js"]);
/* [end skip-as-module] */
UI = {
@ -60,13 +71,13 @@ var UI;
var sheets = WebUtil.getStylesheets();
var i;
for (i = 0; i < sheets.length; i += 1) {
UI.addOption($D('noVNC_setting_stylesheet'),sheets[i].title, sheets[i].title);
UI.addOption(document.getElementById('noVNC_setting_stylesheet'),sheets[i].title, sheets[i].title);
}
// Logging selection dropdown
var llevels = ['error', 'warn', 'info', 'debug'];
for (i = 0; i < llevels.length; i += 1) {
UI.addOption($D('noVNC_setting_logging'),llevels[i], llevels[i]);
UI.addOption(document.getElementById('noVNC_setting_logging'),llevels[i], llevels[i]);
}
// Settings with immediate effects
@ -114,12 +125,12 @@ var UI;
UI.updateVisualState();
$D('noVNC_setting_host').focus();
document.getElementById('noVNC_setting_host').focus();
// Show mouse selector buttons on touch screen devices
if (UI.isTouchDevice) {
// Show mobile buttons
$D('noVNC_mobile_buttons').style.display = "inline";
document.getElementById('noVNC_mobile_buttons').style.display = "inline";
UI.setMouseButton();
// Remove the address bar
setTimeout(function() { window.scrollTo(0, 1); }, 100);
@ -131,7 +142,7 @@ var UI;
UI.setViewClip();
UI.setBarPosition();
Util.addEvent(window, 'resize', function () {
window.addEventListener('resize', function () {
UI.applyResizeMode();
UI.setViewClip();
UI.updateViewDrag();
@ -148,18 +159,18 @@ var UI;
document.documentElement.mozRequestFullScreen ||
document.documentElement.webkitRequestFullscreen ||
document.body.msRequestFullscreen)) {
$D('noVNC_fullscreen_button').style.display = "inline";
Util.addEvent(window, 'fullscreenchange', UI.updateFullscreenButton);
Util.addEvent(window, 'mozfullscreenchange', UI.updateFullscreenButton);
Util.addEvent(window, 'webkitfullscreenchange', UI.updateFullscreenButton);
Util.addEvent(window, 'msfullscreenchange', UI.updateFullscreenButton);
document.getElementById('noVNC_fullscreen_button').style.display = "inline";
window.addEventListener('fullscreenchange', UI.updateFullscreenButton);
window.addEventListener('mozfullscreenchange', UI.updateFullscreenButton);
window.addEventListener('webkitfullscreenchange', UI.updateFullscreenButton);
window.addEventListener('msfullscreenchange', UI.updateFullscreenButton);
}
Util.addEvent(window, 'load', UI.keyboardinputReset);
window.addEventListener('load', UI.keyboardinputReset);
// While connected we want to display a confirmation dialogue
// if the user tries to leave the page
Util.addEvent(window, 'beforeunload', function (e) {
window.addEventListener('beforeunload', function (e) {
if (UI.rfb && UI.rfb_state === 'normal') {
var msg = "You are currently connected.";
e.returnValue = msg;
@ -172,7 +183,7 @@ var UI;
// Show description by default when hosted at for kanaka.github.com
if (location.host === "kanaka.github.io") {
// Open the description dialog
$D('noVNC_description').style.display = "block";
document.getElementById('noVNC_description').style.display = "block";
} else {
// Show the connect panel on first load unless autoconnecting
if (autoconnect === UI.connSettingsOpen) {
@ -190,7 +201,7 @@ var UI;
initRFB: function() {
try {
UI.rfb = new RFB({'target': $D('noVNC_canvas'),
UI.rfb = new RFB({'target': document.getElementById('noVNC_canvas'),
'onUpdateState': UI.updateState,
'onXvpInit': UI.updateXvpButton,
'onClipboard': UI.clipboardReceive,
@ -206,49 +217,49 @@ var UI;
addMouseHandlers: function() {
// Setup interface handlers that can't be inline
$D("noVNC_view_drag_button").onclick = UI.toggleViewDrag;
$D("noVNC_mouse_button0").onclick = function () { UI.setMouseButton(1); };
$D("noVNC_mouse_button1").onclick = function () { UI.setMouseButton(2); };
$D("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); };
$D("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); };
$D("noVNC_keyboard_button").onclick = UI.showKeyboard;
document.getElementById("noVNC_view_drag_button").onclick = UI.toggleViewDrag;
document.getElementById("noVNC_mouse_button0").onclick = function () { UI.setMouseButton(1); };
document.getElementById("noVNC_mouse_button1").onclick = function () { UI.setMouseButton(2); };
document.getElementById("noVNC_mouse_button2").onclick = function () { UI.setMouseButton(4); };
document.getElementById("noVNC_mouse_button4").onclick = function () { UI.setMouseButton(0); };
document.getElementById("noVNC_keyboard_button").onclick = UI.showKeyboard;
$D("noVNC_keyboardinput").oninput = UI.keyInput;
$D("noVNC_keyboardinput").onblur = UI.hideKeyboard;
$D("noVNC_keyboardinput").onsubmit = function () { return false; };
document.getElementById("noVNC_keyboardinput").oninput = UI.keyInput;
document.getElementById("noVNC_keyboardinput").onblur = UI.hideKeyboard;
document.getElementById("noVNC_keyboardinput").onsubmit = function () { return false; };
$D("noVNC_toggleExtraKeys_button").onclick = UI.toggleExtraKeys;
$D("noVNC_toggleCtrl_button").onclick = UI.toggleCtrl;
$D("noVNC_toggleAlt_button").onclick = UI.toggleAlt;
$D("noVNC_sendTab_button").onclick = UI.sendTab;
$D("noVNC_sendEsc_button").onclick = UI.sendEsc;
document.getElementById("noVNC_toggleExtraKeys_button").onclick = UI.toggleExtraKeys;
document.getElementById("noVNC_toggleCtrl_button").onclick = UI.toggleCtrl;
document.getElementById("noVNC_toggleAlt_button").onclick = UI.toggleAlt;
document.getElementById("noVNC_sendTab_button").onclick = UI.sendTab;
document.getElementById("noVNC_sendEsc_button").onclick = UI.sendEsc;
$D("noVNC_sendCtrlAltDel_button").onclick = UI.sendCtrlAltDel;
$D("noVNC_xvpShutdown_button").onclick = function() { UI.rfb.xvpShutdown(); },
$D("noVNC_xvpReboot_button").onclick = function() { UI.rfb.xvpReboot(); },
$D("noVNC_xvpReset_button").onclick = function() { UI.rfb.xvpReset(); },
$D("noVNC_status").onclick = UI.popupStatus;
$D("noVNC_popup_status").onclick = UI.closePopup;
$D("noVNC_toggleXvp_button").onclick = UI.toggleXvpPanel;
$D("noVNC_clipboard_button").onclick = UI.toggleClipboardPanel;
$D("noVNC_fullscreen_button").onclick = UI.toggleFullscreen;
$D("noVNC_settings_button").onclick = UI.toggleSettingsPanel;
$D("noVNC_connectPanel_button").onclick = UI.toggleConnectPanel;
$D("noVNC_disconnect_button").onclick = UI.disconnect;
$D("noVNC_description_button").onclick = UI.toggleConnectPanel;
document.getElementById("noVNC_sendCtrlAltDel_button").onclick = UI.sendCtrlAltDel;
document.getElementById("noVNC_xvpShutdown_button").onclick = function() { UI.rfb.xvpShutdown(); },
document.getElementById("noVNC_xvpReboot_button").onclick = function() { UI.rfb.xvpReboot(); },
document.getElementById("noVNC_xvpReset_button").onclick = function() { UI.rfb.xvpReset(); },
document.getElementById("noVNC_status").onclick = UI.popupStatus;
document.getElementById("noVNC_popup_status").onclick = UI.closePopup;
document.getElementById("noVNC_toggleXvp_button").onclick = UI.toggleXvpPanel;
document.getElementById("noVNC_clipboard_button").onclick = UI.toggleClipboardPanel;
document.getElementById("noVNC_fullscreen_button").onclick = UI.toggleFullscreen;
document.getElementById("noVNC_settings_button").onclick = UI.toggleSettingsPanel;
document.getElementById("noVNC_connectPanel_button").onclick = UI.toggleConnectPanel;
document.getElementById("noVNC_disconnect_button").onclick = UI.disconnect;
document.getElementById("noVNC_description_button").onclick = UI.toggleConnectPanel;
$D("noVNC_clipboard_text").onfocus = UI.displayBlur;
$D("noVNC_clipboard_text").onblur = UI.displayFocus;
$D("noVNC_clipboard_text").onchange = UI.clipboardSend;
$D("noVNC_clipboard_clear_button").onclick = UI.clipboardClear;
document.getElementById("noVNC_clipboard_text").onfocus = UI.displayBlur;
document.getElementById("noVNC_clipboard_text").onblur = UI.displayFocus;
document.getElementById("noVNC_clipboard_text").onchange = UI.clipboardSend;
document.getElementById("noVNC_clipboard_clear_button").onclick = UI.clipboardClear;
$D("noVNC_settings_menu").onmouseover = UI.displayBlur;
$D("noVNC_settings_menu").onmouseover = UI.displayFocus;
$D("noVNC_settings_apply").onclick = UI.settingsApply;
document.getElementById("noVNC_settings_menu").onmouseover = UI.displayBlur;
document.getElementById("noVNC_settings_menu").onmouseover = UI.displayFocus;
document.getElementById("noVNC_settings_apply").onclick = UI.settingsApply;
$D("noVNC_connect_button").onclick = UI.connect;
document.getElementById("noVNC_connect_button").onclick = UI.connect;
$D("noVNC_setting_resize").onchange = UI.enableDisableViewClip;
document.getElementById("noVNC_setting_resize").onchange = UI.enableDisableViewClip;
},
/* ------^-------
@ -269,8 +280,8 @@ var UI;
klass = "noVNC_status_normal";
break;
case 'disconnected':
$D('noVNC_logo').style.display = "block";
$D('noVNC_screen').style.display = "none";
document.getElementById('noVNC_logo').style.display = "block";
document.getElementById('noVNC_screen').style.display = "none";
/* falls through */
case 'loaded':
klass = "noVNC_status_normal";
@ -278,9 +289,9 @@ var UI;
case 'password':
UI.toggleConnectPanel();
$D('noVNC_connect_button').value = "Send Password";
$D('noVNC_connect_button').onclick = UI.setPassword;
$D('noVNC_setting_password').focus();
document.getElementById('noVNC_connect_button').value = "Send Password";
document.getElementById('noVNC_connect_button').onclick = UI.setPassword;
document.getElementById('noVNC_setting_password').focus();
klass = "noVNC_status_warn";
break;
@ -290,8 +301,8 @@ var UI;
}
if (typeof(msg) !== 'undefined') {
$D('noVNC_control_bar').setAttribute("class", klass);
$D('noVNC_status').innerHTML = msg;
document.getElementById('noVNC_control_bar').setAttribute("class", klass);
document.getElementById('noVNC_status').innerHTML = msg;
}
UI.updateVisualState();
@ -302,35 +313,35 @@ var UI;
var connected = UI.rfb && UI.rfb_state === 'normal';
//Util.Debug(">> updateVisualState");
$D('noVNC_setting_encrypt').disabled = connected;
$D('noVNC_setting_true_color').disabled = connected;
document.getElementById('noVNC_setting_encrypt').disabled = connected;
document.getElementById('noVNC_setting_true_color').disabled = connected;
if (Util.browserSupportsCursorURIs()) {
$D('noVNC_setting_cursor').disabled = connected;
document.getElementById('noVNC_setting_cursor').disabled = connected;
} else {
UI.updateSetting('cursor', !UI.isTouchDevice);
$D('noVNC_setting_cursor').disabled = true;
document.getElementById('noVNC_setting_cursor').disabled = true;
}
UI.enableDisableViewClip();
$D('noVNC_setting_resize').disabled = connected;
$D('noVNC_setting_shared').disabled = connected;
$D('noVNC_setting_view_only').disabled = connected;
$D('noVNC_setting_path').disabled = connected;
$D('noVNC_setting_repeaterID').disabled = connected;
document.getElementById('noVNC_setting_resize').disabled = connected;
document.getElementById('noVNC_setting_shared').disabled = connected;
document.getElementById('noVNC_setting_view_only').disabled = connected;
document.getElementById('noVNC_setting_path').disabled = connected;
document.getElementById('noVNC_setting_repeaterID').disabled = connected;
if (connected) {
UI.setViewClip();
UI.setMouseButton(1);
$D('noVNC_clipboard_button').style.display = "inline";
$D('noVNC_keyboard_button').style.display = "inline";
$D('noVNC_extra_keys').style.display = "";
$D('noVNC_sendCtrlAltDel_button').style.display = "inline";
document.getElementById('noVNC_clipboard_button').style.display = "inline";
document.getElementById('noVNC_keyboard_button').style.display = "inline";
document.getElementById('noVNC_extra_keys').style.display = "";
document.getElementById('noVNC_sendCtrlAltDel_button').style.display = "inline";
} else {
UI.setMouseButton();
$D('noVNC_clipboard_button').style.display = "none";
$D('noVNC_keyboard_button').style.display = "none";
$D('noVNC_extra_keys').style.display = "none";
$D('noVNC_sendCtrlAltDel_button').style.display = "none";
document.getElementById('noVNC_clipboard_button').style.display = "none";
document.getElementById('noVNC_keyboard_button').style.display = "none";
document.getElementById('noVNC_extra_keys').style.display = "none";
document.getElementById('noVNC_sendCtrlAltDel_button').style.display = "none";
UI.updateXvpButton(0);
}
@ -342,18 +353,18 @@ var UI;
case 'fatal':
case 'failed':
case 'disconnected':
$D('noVNC_connectPanel_button').style.display = "";
$D('noVNC_disconnect_button').style.display = "none";
document.getElementById('noVNC_connectPanel_button').style.display = "";
document.getElementById('noVNC_disconnect_button').style.display = "none";
UI.connSettingsOpen = false;
UI.toggleConnectPanel();
break;
case 'loaded':
$D('noVNC_connectPanel_button').style.display = "";
$D('noVNC_disconnect_button').style.display = "none";
document.getElementById('noVNC_connectPanel_button').style.display = "";
document.getElementById('noVNC_disconnect_button').style.display = "none";
break;
default:
$D('noVNC_connectPanel_button').style.display = "none";
$D('noVNC_disconnect_button').style.display = "";
document.getElementById('noVNC_connectPanel_button').style.display = "none";
document.getElementById('noVNC_disconnect_button').style.display = "";
break;
}
@ -361,14 +372,14 @@ var UI;
},
popupStatus: function(text) {
var psp = $D('noVNC_popup_status');
var psp = document.getElementById('noVNC_popup_status');
clearTimeout(UI.popupStatusTimeout);
if (typeof text === 'string') {
psp.innerHTML = text;
} else {
psp.innerHTML = $D('noVNC_status').innerHTML;
psp.innerHTML = document.getElementById('noVNC_status').innerHTML;
}
psp.style.display = "block";
psp.style.left = window.innerWidth/2 -
@ -380,7 +391,7 @@ var UI;
closePopup: function() {
clearTimeout(UI.popupStatusTimeout);
$D('noVNC_popup_status').style.display = "none";
document.getElementById('noVNC_popup_status').style.display = "none";
},
/* ------^-------
@ -412,7 +423,7 @@ var UI;
// Update the settings control
value = UI.getSetting(name);
var ctrl = $D('noVNC_setting_' + name);
var ctrl = document.getElementById('noVNC_setting_' + name);
if (ctrl.type === 'checkbox') {
ctrl.checked = value;
@ -435,7 +446,7 @@ var UI;
// Save control setting to cookie
saveSetting: function(name) {
var val, ctrl = $D('noVNC_setting_' + name);
var val, ctrl = document.getElementById('noVNC_setting_' + name);
if (ctrl.type === 'checkbox') {
val = ctrl.checked;
} else if (typeof ctrl.options !== 'undefined') {
@ -456,7 +467,7 @@ var UI;
// Read form control compatible setting from cookie
getSetting: function(name) {
var ctrl = $D('noVNC_setting_' + name);
var ctrl = document.getElementById('noVNC_setting_' + name);
var val = WebUtil.readSetting(name);
if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') {
if (val.toString().toLowerCase() in {'0':1, 'no':1, 'false':1}) {
@ -502,7 +513,7 @@ var UI;
// Open menu
openSettingsMenu: function() {
// Close the description panel
$D('noVNC_description').style.display = "none";
document.getElementById('noVNC_description').style.display = "none";
// Close clipboard panel if open
if (UI.clipboardOpen === true) {
UI.toggleClipboardPanel();
@ -515,15 +526,15 @@ var UI;
if (UI.xvpOpen === true) {
UI.toggleXvpPanel();
}
$D('noVNC_settings').style.display = "block";
$D('noVNC_settings_button').className = "noVNC_status_button_selected";
document.getElementById('noVNC_settings').style.display = "block";
document.getElementById('noVNC_settings_button').className = "noVNC_status_button_selected";
UI.settingsOpen = true;
},
// Close menu (without applying settings)
closeSettingsMenu: function() {
$D('noVNC_settings').style.display = "none";
$D('noVNC_settings_button').className = "noVNC_status_button";
document.getElementById('noVNC_settings').style.display = "none";
document.getElementById('noVNC_settings_button').className = "noVNC_status_button";
UI.settingsOpen = false;
},
@ -532,7 +543,7 @@ var UI;
// On close, settings are applied
toggleSettingsPanel: function() {
// Close the description panel
$D('noVNC_description').style.display = "none";
document.getElementById('noVNC_description').style.display = "none";
if (UI.settingsOpen) {
UI.settingsApply();
UI.closeSettingsMenu();
@ -543,7 +554,7 @@ var UI;
UI.updateSetting('cursor');
} else {
UI.updateSetting('cursor', !UI.isTouchDevice);
$D('noVNC_setting_cursor').disabled = true;
document.getElementById('noVNC_setting_cursor').disabled = true;
}
UI.updateSetting('clip');
UI.updateSetting('resize');
@ -567,7 +578,7 @@ var UI;
// Show the XVP panel
toggleXvpPanel: function() {
// Close the description panel
$D('noVNC_description').style.display = "none";
document.getElementById('noVNC_description').style.display = "none";
// Close settings if open
if (UI.settingsOpen === true) {
UI.settingsApply();
@ -583,12 +594,12 @@ var UI;
}
// Toggle XVP panel
if (UI.xvpOpen === true) {
$D('noVNC_xvp').style.display = "none";
$D('noVNC_toggleXvp_button').className = "noVNC_status_button";
document.getElementById('noVNC_xvp').style.display = "none";
document.getElementById('noVNC_toggleXvp_button').className = "noVNC_status_button";
UI.xvpOpen = false;
} else {
$D('noVNC_xvp').style.display = "block";
$D('noVNC_toggleXvp_button').className = "noVNC_status_button_selected";
document.getElementById('noVNC_xvp').style.display = "block";
document.getElementById('noVNC_toggleXvp_button').className = "noVNC_status_button_selected";
UI.xvpOpen = true;
}
},
@ -596,9 +607,9 @@ var UI;
// Disable/enable XVP button
updateXvpButton: function(ver) {
if (ver >= 1) {
$D('noVNC_toggleXvp_button').style.display = 'inline';
document.getElementById('noVNC_toggleXvp_button').style.display = 'inline';
} else {
$D('noVNC_toggleXvp_button').style.display = 'none';
document.getElementById('noVNC_toggleXvp_button').style.display = 'none';
// Close XVP panel if open
if (UI.xvpOpen === true) {
UI.toggleXvpPanel();
@ -615,7 +626,7 @@ var UI;
// Show the clipboard panel
toggleClipboardPanel: function() {
// Close the description panel
$D('noVNC_description').style.display = "none";
document.getElementById('noVNC_description').style.display = "none";
// Close settings if open
if (UI.settingsOpen === true) {
UI.settingsApply();
@ -631,29 +642,29 @@ var UI;
}
// Toggle Clipboard Panel
if (UI.clipboardOpen === true) {
$D('noVNC_clipboard').style.display = "none";
$D('noVNC_clipboard_button').className = "noVNC_status_button";
document.getElementById('noVNC_clipboard').style.display = "none";
document.getElementById('noVNC_clipboard_button').className = "noVNC_status_button";
UI.clipboardOpen = false;
} else {
$D('noVNC_clipboard').style.display = "block";
$D('noVNC_clipboard_button').className = "noVNC_status_button_selected";
document.getElementById('noVNC_clipboard').style.display = "block";
document.getElementById('noVNC_clipboard_button').className = "noVNC_status_button_selected";
UI.clipboardOpen = true;
}
},
clipboardReceive: function(rfb, text) {
Util.Debug(">> UI.clipboardReceive: " + text.substr(0,40) + "...");
$D('noVNC_clipboard_text').value = text;
document.getElementById('noVNC_clipboard_text').value = text;
Util.Debug("<< UI.clipboardReceive");
},
clipboardClear: function() {
$D('noVNC_clipboard_text').value = "";
document.getElementById('noVNC_clipboard_text').value = "";
UI.rfb.clipboardPasteFrom("");
},
clipboardSend: function() {
var text = $D('noVNC_clipboard_text').value;
var text = document.getElementById('noVNC_clipboard_text').value;
Util.Debug(">> UI.clipboardSend: " + text.substr(0,40) + "...");
UI.rfb.clipboardPasteFrom(text);
Util.Debug("<< UI.clipboardSend");
@ -668,12 +679,12 @@ var UI;
// Show the connection settings panel/menu
toggleConnectPanel: function() {
// Close the description panel
$D('noVNC_description').style.display = "none";
document.getElementById('noVNC_description').style.display = "none";
// Close connection settings if open
if (UI.settingsOpen === true) {
UI.settingsApply();
UI.closeSettingsMenu();
$D('noVNC_connectPanel_button').className = "noVNC_status_button";
document.getElementById('noVNC_connectPanel_button').className = "noVNC_status_button";
}
// Close clipboard panel if open
if (UI.clipboardOpen === true) {
@ -686,18 +697,18 @@ var UI;
// Toggle Connection Panel
if (UI.connSettingsOpen === true) {
$D('noVNC_controls').style.display = "none";
$D('noVNC_connectPanel_button').className = "noVNC_status_button";
document.getElementById('noVNC_controls').style.display = "none";
document.getElementById('noVNC_connectPanel_button').className = "noVNC_status_button";
UI.connSettingsOpen = false;
UI.saveSetting('host');
UI.saveSetting('port');
UI.saveSetting('token');
//UI.saveSetting('password');
} else {
$D('noVNC_controls').style.display = "block";
$D('noVNC_connectPanel_button').className = "noVNC_status_button_selected";
document.getElementById('noVNC_controls').style.display = "block";
document.getElementById('noVNC_connectPanel_button').className = "noVNC_status_button_selected";
UI.connSettingsOpen = true;
$D('noVNC_setting_host').focus();
document.getElementById('noVNC_setting_host').focus();
}
},
@ -705,11 +716,11 @@ var UI;
UI.closeSettingsMenu();
UI.toggleConnectPanel();
var host = $D('noVNC_setting_host').value;
var port = $D('noVNC_setting_port').value;
var password = $D('noVNC_setting_password').value;
var token = $D('noVNC_setting_token').value;
var path = $D('noVNC_setting_path').value;
var host = document.getElementById('noVNC_setting_host').value;
var port = document.getElementById('noVNC_setting_port').value;
var password = document.getElementById('noVNC_setting_password').value;
var token = document.getElementById('noVNC_setting_token').value;
var path = document.getElementById('noVNC_setting_path').value;
//if token is in path then ignore the new token variable
if (token) {
@ -733,8 +744,8 @@ var UI;
//Close dialog.
setTimeout(UI.setBarPosition, 100);
$D('noVNC_logo').style.display = "none";
$D('noVNC_screen').style.display = "inline";
document.getElementById('noVNC_logo').style.display = "none";
document.getElementById('noVNC_screen').style.display = "inline";
},
disconnect: function() {
@ -744,17 +755,17 @@ var UI;
// Restore the callback used for initial resize
UI.rfb.set_onFBUComplete(UI.initialResize);
$D('noVNC_logo').style.display = "block";
$D('noVNC_screen').style.display = "none";
document.getElementById('noVNC_logo').style.display = "block";
document.getElementById('noVNC_screen').style.display = "none";
// Don't display the connection settings until we're actually disconnected
},
setPassword: function() {
UI.rfb.sendPassword($D('noVNC_setting_password').value);
UI.rfb.sendPassword(document.getElementById('noVNC_setting_password').value);
//Reset connect button.
$D('noVNC_connect_button').value = "Connect";
$D('noVNC_connect_button').onclick = UI.connect;
document.getElementById('noVNC_connect_button').value = "Connect";
document.getElementById('noVNC_connect_button').onclick = UI.connect;
//Hide connection panel.
UI.toggleConnectPanel();
return false;
@ -800,9 +811,9 @@ var UI;
document.mozFullScreenElement || // currently working methods
document.webkitFullscreenElement ||
document.msFullscreenElement ) {
$D('noVNC_fullscreen_button').className = "noVNC_status_button_selected";
document.getElementById('noVNC_fullscreen_button').className = "noVNC_status_button_selected";
} else {
$D('noVNC_fullscreen_button').className = "noVNC_status_button";
document.getElementById('noVNC_fullscreen_button').className = "noVNC_status_button";
}
},
@ -856,7 +867,7 @@ var UI;
// The screen is always the same size as the available viewport
// in the browser window minus the height of the control bar
screenSize: function() {
var screen = $D('noVNC_screen');
var screen = document.getElementById('noVNC_screen');
// Hide the scrollbars until the size is calculated
screen.style.overflow = "hidden";
@ -931,13 +942,13 @@ var UI;
display.set_maxHeight(size.h);
// Hide potential scrollbars that can skew the position
$D('noVNC_screen').style.overflow = "hidden";
document.getElementById('noVNC_screen').style.overflow = "hidden";
// The x position marks the left margin of the canvas,
// remove the margin from both sides to keep it centered
var new_w = size.w - (2 * Util.getPosition($D('noVNC_canvas')).x);
var new_w = size.w - (2 * Util.getPosition(document.getElementById('noVNC_canvas')).x);
$D('noVNC_screen').style.overflow = "visible";
document.getElementById('noVNC_screen').style.overflow = "visible";
display.viewportChangeSize(new_w, size.h);
}
@ -946,18 +957,18 @@ var UI;
// Handle special cases where clipping is forced on/off or locked
enableDisableViewClip: function() {
var resizeSetting = $D('noVNC_setting_resize');
var resizeSetting = document.getElementById('noVNC_setting_resize');
var connected = UI.rfb && UI.rfb_state === 'normal';
if (UI.isSafari) {
// Safari auto-hides the scrollbars which makes them
// impossible to use in most cases
UI.setViewClip(true);
$D('noVNC_setting_clip').disabled = true;
document.getElementById('noVNC_setting_clip').disabled = true;
} else if (resizeSetting.value === 'downscale' || resizeSetting.value === 'scale') {
// Disable clipping if we are scaling
UI.setViewClip(false);
$D('noVNC_setting_clip').disabled = true;
document.getElementById('noVNC_setting_clip').disabled = true;
} else if (document.msFullscreenElement) {
// The browser is IE and we are in fullscreen mode.
// - We need to force clipping while in fullscreen since
@ -965,13 +976,13 @@ var UI;
UI.popupStatus("Forcing clipping mode since scrollbars aren't supported by IE in fullscreen");
UI.rememberedClipSetting = UI.getSetting('clip');
UI.setViewClip(true);
$D('noVNC_setting_clip').disabled = true;
document.getElementById('noVNC_setting_clip').disabled = true;
} else if (document.body.msRequestFullscreen && UI.rememberedClip !== null) {
// Restore view clip to what it was before fullscreen on IE
UI.setViewClip(UI.rememberedClipSetting);
$D('noVNC_setting_clip').disabled = connected || UI.isTouchDevice;
document.getElementById('noVNC_setting_clip').disabled = connected || UI.isTouchDevice;
} else {
$D('noVNC_setting_clip').disabled = connected || UI.isTouchDevice;
document.getElementById('noVNC_setting_clip').disabled = connected || UI.isTouchDevice;
if (UI.isTouchDevice) {
UI.setViewClip(true);
}
@ -988,7 +999,7 @@ var UI;
updateViewDrag: function(drag) {
if (!UI.rfb) return;
var viewDragButton = $D('noVNC_view_drag_button');
var viewDragButton = document.getElementById('noVNC_view_drag_button');
// Check if viewport drag is possible. It is only possible
// if the remote display is clipping the client display.
@ -1033,7 +1044,7 @@ var UI;
toggleViewDrag: function() {
if (!UI.rfb) return;
var viewDragButton = $D('noVNC_view_drag_button');
var viewDragButton = document.getElementById('noVNC_view_drag_button');
if (UI.rfb.get_viewportDrag()) {
viewDragButton.className = "noVNC_status_button";
UI.rfb.set_viewportDrag(false);
@ -1051,8 +1062,8 @@ var UI;
// On touch devices, show the OS keyboard
showKeyboard: function() {
var kbi = $D('noVNC_keyboardinput');
var skb = $D('noVNC_keyboard_button');
var kbi = document.getElementById('noVNC_keyboardinput');
var skb = document.getElementById('noVNC_keyboard_button');
var l = kbi.value.length;
if(UI.keyboardVisible === false) {
kbi.focus();
@ -1068,7 +1079,7 @@ var UI;
},
hideKeyboard: function() {
$D('noVNC_keyboard_button').className = "noVNC_status_button";
document.getElementById('noVNC_keyboard_button').className = "noVNC_status_button";
//Weird bug in iOS if you change keyboardVisible
//here it does not actually occur so next time
//you click keyboard icon it doesnt work.
@ -1080,16 +1091,16 @@ var UI;
keepKeyboard: function() {
clearTimeout(UI.hideKeyboardTimeout);
if(UI.keyboardVisible === true) {
$D('noVNC_keyboardinput').focus();
$D('noVNC_keyboard_button').className = "noVNC_status_button_selected";
document.getElementById('noVNC_keyboardinput').focus();
document.getElementById('noVNC_keyboard_button').className = "noVNC_status_button_selected";
} else if(UI.keyboardVisible === false) {
$D('noVNC_keyboardinput').blur();
$D('noVNC_keyboard_button').className = "noVNC_status_button";
document.getElementById('noVNC_keyboardinput').blur();
document.getElementById('noVNC_keyboard_button').className = "noVNC_status_button";
}
},
keyboardinputReset: function() {
var kbi = $D('noVNC_keyboardinput');
var kbi = document.getElementById('noVNC_keyboardinput');
kbi.value = new Array(UI.defaultKeyboardinputLen).join("_");
UI.lastKeyboardinput = kbi.value;
},
@ -1141,7 +1152,7 @@ var UI;
// Send the key events
for (i = 0; i < backspaces; i++) {
UI.rfb.sendKey(XK_BackSpace);
UI.rfb.sendKey(KeyTable.XK_BackSpace);
}
for (i = newLen - inputs; i < newLen; i++) {
UI.rfb.sendKey(newValue.charCodeAt(i));
@ -1168,41 +1179,41 @@ var UI;
toggleExtraKeys: function() {
UI.keepKeyboard();
if(UI.extraKeysVisible === false) {
$D('noVNC_toggleCtrl_button').style.display = "inline";
$D('noVNC_toggleAlt_button').style.display = "inline";
$D('noVNC_sendTab_button').style.display = "inline";
$D('noVNC_sendEsc_button').style.display = "inline";
$D('noVNC_toggleExtraKeys_button').className = "noVNC_status_button_selected";
document.getElementById('noVNC_toggleCtrl_button').style.display = "inline";
document.getElementById('noVNC_toggleAlt_button').style.display = "inline";
document.getElementById('noVNC_sendTab_button').style.display = "inline";
document.getElementById('noVNC_sendEsc_button').style.display = "inline";
document.getElementById('noVNC_toggleExtraKeys_button').className = "noVNC_status_button_selected";
UI.extraKeysVisible = true;
} else if(UI.extraKeysVisible === true) {
$D('noVNC_toggleCtrl_button').style.display = "";
$D('noVNC_toggleAlt_button').style.display = "";
$D('noVNC_sendTab_button').style.display = "";
$D('noVNC_sendEsc_button').style.display = "";
$D('noVNC_toggleExtraKeys_button').className = "noVNC_status_button";
document.getElementById('noVNC_toggleCtrl_button').style.display = "";
document.getElementById('noVNC_toggleAlt_button').style.display = "";
document.getElementById('noVNC_sendTab_button').style.display = "";
document.getElementById('noVNC_sendEsc_button').style.display = "";
document.getElementById('noVNC_toggleExtraKeys_button').className = "noVNC_status_button";
UI.extraKeysVisible = false;
}
},
sendEsc: function() {
UI.keepKeyboard();
UI.rfb.sendKey(XK_Escape);
UI.rfb.sendKey(KeyTable.XK_Escape);
},
sendTab: function() {
UI.keepKeyboard();
UI.rfb.sendKey(XK_Tab);
UI.rfb.sendKey(KeyTable.XK_Tab);
},
toggleCtrl: function() {
UI.keepKeyboard();
if(UI.ctrlOn === false) {
UI.rfb.sendKey(XK_Control_L, true);
$D('noVNC_toggleCtrl_button').className = "noVNC_status_button_selected";
UI.rfb.sendKey(KeyTable.XK_Control_L, true);
document.getElementById('noVNC_toggleCtrl_button').className = "noVNC_status_button_selected";
UI.ctrlOn = true;
} else if(UI.ctrlOn === true) {
UI.rfb.sendKey(XK_Control_L, false);
$D('noVNC_toggleCtrl_button').className = "noVNC_status_button";
UI.rfb.sendKey(KeyTable.XK_Control_L, false);
document.getElementById('noVNC_toggleCtrl_button').className = "noVNC_status_button";
UI.ctrlOn = false;
}
},
@ -1210,12 +1221,12 @@ var UI;
toggleAlt: function() {
UI.keepKeyboard();
if(UI.altOn === false) {
UI.rfb.sendKey(XK_Alt_L, true);
$D('noVNC_toggleAlt_button').className = "noVNC_status_button_selected";
UI.rfb.sendKey(KeyTable.XK_Alt_L, true);
document.getElementById('noVNC_toggleAlt_button').className = "noVNC_status_button_selected";
UI.altOn = true;
} else if(UI.altOn === true) {
UI.rfb.sendKey(XK_Alt_L, false);
$D('noVNC_toggleAlt_button').className = "noVNC_status_button";
UI.rfb.sendKey(KeyTable.XK_Alt_L, false);
document.getElementById('noVNC_toggleAlt_button').className = "noVNC_status_button";
UI.altOn = false;
}
},
@ -1241,7 +1252,7 @@ var UI;
var blist = [0, 1,2,4];
for (var b = 0; b < blist.length; b++) {
var button = $D('noVNC_mouse_button' + blist[b]);
var button = document.getElementById('noVNC_mouse_button' + blist[b]);
if (blist[b] === num) {
button.style.display = "";
} else {
@ -1278,11 +1289,11 @@ var UI;
},
setBarPosition: function() {
$D('noVNC_control_bar').style.top = (window.pageYOffset) + 'px';
$D('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px';
document.getElementById('noVNC_control_bar').style.top = (window.pageYOffset) + 'px';
document.getElementById('noVNC_mobile_buttons').style.left = (window.pageXOffset) + 'px';
var vncwidth = $D('noVNC_container').style.offsetWidth;
$D('noVNC_control_bar').style.width = vncwidth + 'px';
var vncwidth = document.getElementById('noVNC_container').style.offsetWidth;
document.getElementById('noVNC_control_bar').style.width = vncwidth + 'px';
}
/* ------^-------
@ -1290,4 +1301,8 @@ var UI;
* ==============
*/
};
/* [module] UI.load(); */
})();
/* [module] export default UI; */

View File

@ -10,25 +10,12 @@
/*jslint bitwise: false, white: false, browser: true, devel: true */
/*global Util, window, document */
// Globals defined here
var WebUtil = {}, $D;
/*
* Simple DOM selector by ID
/* [module]
* import Util from "../core/util";
*/
if (!window.$D) {
window.$D = function (id) {
if (document.getElementById) {
return document.getElementById(id);
} else if (document.all) {
return document.all[id];
} else if (document.layers) {
return document.layers[id];
}
return undefined;
};
}
// Globals defined here
var WebUtil = {};
/*
* ------------------------------------------------------
@ -290,3 +277,74 @@ WebUtil.injectParamIfMissing = function (path, param, value) {
return elem.pathname + elem.search + elem.hash;
}
};
// Dynamically load scripts without using document.write()
// Reference: http://unixpapa.com/js/dyna.html
//
// Handles the case where load_scripts is invoked from a script that
// itself is loaded via load_scripts. Once all scripts are loaded the
// window.onscriptsloaded handler is called (if set).
WebUtil.get_include_uri = function (root_dir) {
return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI + root_dir + '/' : root_dir + '/';
};
WebUtil._loading_scripts = [];
WebUtil._pending_scripts = [];
WebUtil.load_scripts = function (files_by_dir) {
"use strict";
var head = document.getElementsByTagName('head')[0], script,
ls = WebUtil._loading_scripts, ps = WebUtil._pending_scripts;
var loadFunc = function (e) {
while (ls.length > 0 && (ls[0].readyState === 'loaded' ||
ls[0].readyState === 'complete')) {
// For IE, append the script to trigger execution
var s = ls.shift();
//console.log("loaded script: " + s.src);
head.appendChild(s);
}
if (!this.readyState ||
(Util.Engine.presto && this.readyState === 'loaded') ||
this.readyState === 'complete') {
if (ps.indexOf(this) >= 0) {
this.onload = this.onreadystatechange = null;
//console.log("completed script: " + this.src);
ps.splice(ps.indexOf(this), 1);
// Call window.onscriptsload after last script loads
if (ps.length === 0 && window.onscriptsload) {
window.onscriptsload();
}
}
}
};
var root_dirs = Object.keys(files_by_dir);
for (var d = 0; d < root_dirs.length; d++) {
var root_dir = root_dirs[d];
var files = files_by_dir[root_dir];
for (var f = 0; f < files.length; f++) {
script = document.createElement('script');
script.type = 'text/javascript';
script.src = WebUtil.get_include_uri(root_dir) + files[f];
//console.log("loading script: " + script.src);
script.onload = script.onreadystatechange = loadFunc;
// In-order script execution tricks
if (Util.Engine.trident) {
// For IE wait until readyState is 'loaded' before
// appending it which will trigger execution
// http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
ls.push(script);
} else {
// For webkit and firefox set async=false and append now
// https://developer.mozilla.org/en-US/docs/HTML/Element/script
script.async = false;
head.appendChild(script);
}
ps.push(script);
}
}
};
/* [module] export default WebUtil; */

View File

@ -85,7 +85,7 @@ var Base64 = {
console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i);
continue;
}
// Collect data into leftdata, update bitcount
leftdata = (leftdata << 6) | c;
leftbits += 6;
@ -111,3 +111,5 @@ var Base64 = {
return result;
}
}; /* End of Base64 namespace */
/* [module] export default Base64; */

View File

@ -25,16 +25,16 @@
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
* without fee is hereby granted, provided that this copyright notice is kept
* intact.
*
* without fee is hereby granted, provided that this copyright notice is kept
* intact.
*
* WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
*
* THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
* CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
* PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
@ -77,7 +77,7 @@
/* jslint white: false */
function DES(passwd) {
/* [module] export default */ function DES(passwd) {
"use strict";
// Tables, permutations, S-boxes, etc.
@ -273,4 +273,4 @@ function DES(passwd) {
setKeys(passwd); // Setup keys
return {'encrypt': encrypt}; // Public interface
} // function DES
}; // function DES

View File

@ -10,7 +10,89 @@
/*jslint browser: true, white: false */
/*global Util, Base64, changeCursor */
var Display;
/* [module]
* import Util from "./util";
* import Base64 from "./base64";
*/
/* [module] export default */ function Display(defaults) {
this._drawCtx = null;
this._c_forceCanvas = false;
this._renderQ = []; // queue drawing actions for in-oder rendering
// the full frame buffer (logical canvas) size
this._fb_width = 0;
this._fb_height = 0;
// the size limit of the viewport (start disabled)
this._maxWidth = 0;
this._maxHeight = 0;
// the visible "physical canvas" viewport
this._viewportLoc = { 'x': 0, 'y': 0, 'w': 0, 'h': 0 };
this._cleanRect = { 'x1': 0, 'y1': 0, 'x2': -1, 'y2': -1 };
this._prevDrawStyle = "";
this._tile = null;
this._tile16x16 = null;
this._tile_x = 0;
this._tile_y = 0;
Util.set_defaults(this, defaults, {
'true_color': true,
'colourMap': [],
'scale': 1.0,
'viewport': false,
'render_mode': ''
});
Util.Debug(">> Display.constructor");
if (!this._target) {
throw new Error("Target must be set");
}
if (typeof this._target === 'string') {
throw new Error('target must be a DOM element');
}
if (!this._target.getContext) {
throw new Error("no getContext method");
}
if (!this._drawCtx) {
this._drawCtx = this._target.getContext('2d');
}
Util.Debug("User Agent: " + navigator.userAgent);
if (Util.Engine.gecko) { Util.Debug("Browser: gecko " + Util.Engine.gecko); }
if (Util.Engine.webkit) { Util.Debug("Browser: webkit " + Util.Engine.webkit); }
if (Util.Engine.trident) { Util.Debug("Browser: trident " + Util.Engine.trident); }
if (Util.Engine.presto) { Util.Debug("Browser: presto " + Util.Engine.presto); }
this.clear();
// Check canvas features
if ('createImageData' in this._drawCtx) {
this._render_mode = 'canvas rendering';
} else {
throw new Error("Canvas does not support createImageData");
}
if (this._prefer_js === null) {
Util.Info("Prefering javascript operations");
this._prefer_js = true;
}
// Determine browser support for setting the cursor via data URI scheme
if (this._cursor_uri || this._cursor_uri === null ||
this._cursor_uri === undefined) {
this._cursor_uri = Util.browserSupportsCursorURIs();
}
Util.Debug("<< Display.constructor");
};
(function () {
"use strict";
@ -23,84 +105,6 @@ var Display;
// ignore failure
}
Display = function (defaults) {
this._drawCtx = null;
this._c_forceCanvas = false;
this._renderQ = []; // queue drawing actions for in-oder rendering
// the full frame buffer (logical canvas) size
this._fb_width = 0;
this._fb_height = 0;
// the size limit of the viewport (start disabled)
this._maxWidth = 0;
this._maxHeight = 0;
// the visible "physical canvas" viewport
this._viewportLoc = { 'x': 0, 'y': 0, 'w': 0, 'h': 0 };
this._cleanRect = { 'x1': 0, 'y1': 0, 'x2': -1, 'y2': -1 };
this._prevDrawStyle = "";
this._tile = null;
this._tile16x16 = null;
this._tile_x = 0;
this._tile_y = 0;
Util.set_defaults(this, defaults, {
'true_color': true,
'colourMap': [],
'scale': 1.0,
'viewport': false,
'render_mode': ''
});
Util.Debug(">> Display.constructor");
if (!this._target) {
throw new Error("Target must be set");
}
if (typeof this._target === 'string') {
throw new Error('target must be a DOM element');
}
if (!this._target.getContext) {
throw new Error("no getContext method");
}
if (!this._drawCtx) {
this._drawCtx = this._target.getContext('2d');
}
Util.Debug("User Agent: " + navigator.userAgent);
if (Util.Engine.gecko) { Util.Debug("Browser: gecko " + Util.Engine.gecko); }
if (Util.Engine.webkit) { Util.Debug("Browser: webkit " + Util.Engine.webkit); }
if (Util.Engine.trident) { Util.Debug("Browser: trident " + Util.Engine.trident); }
if (Util.Engine.presto) { Util.Debug("Browser: presto " + Util.Engine.presto); }
this.clear();
// Check canvas features
if ('createImageData' in this._drawCtx) {
this._render_mode = 'canvas rendering';
} else {
throw new Error("Canvas does not support createImageData");
}
if (this._prefer_js === null) {
Util.Info("Prefering javascript operations");
this._prefer_js = true;
}
// Determine browser support for setting the cursor via data URI scheme
if (this._cursor_uri || this._cursor_uri === null ||
this._cursor_uri === undefined) {
this._cursor_uri = Util.browserSupportsCursorURIs();
}
Util.Debug("<< Display.constructor");
};
Display.prototype = {
// Public methods
@ -774,7 +778,7 @@ var Display;
}
if (this._renderQ.length > 0) {
requestAnimFrame(this._scan_renderQ.bind(this));
requestAnimationFrame(this._scan_renderQ.bind(this));
}
},
};

View File

@ -1,4 +1,46 @@
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.inflator = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Inflator = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var zlib = require('pako/lib/zlib/inflate.js');
var ZStream = require('pako/lib/zlib/zstream.js');
function Inflate() {
this.strm = new ZStream();
this.chunkSize = 1024 * 10 * 10;
this.strm.output = new Uint8Array(this.chunkSize);
this.windowBits = 5;
zlib.inflateInit(this.strm, this.windowBits);
};
Inflate.prototype = {
inflate: function (data, flush, expected) {
this.strm.input = data;
this.strm.avail_in = this.strm.input.length;
this.strm.next_in = 0;
this.strm.next_out = 0;
// resize our output buffer if it's too small
// (we could just use multiple chunks, but that would cause an extra
// allocation each time to flatten the chunks)
if (expected > this.chunkSize) {
this.chunkSize = expected;
this.strm.output = new Uint8Array(this.chunkSize);
}
this.strm.avail_out = this.chunkSize;
zlib.inflate(this.strm, flush);
return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
},
reset: function () {
zlib.inflateReset(this.strm);
}
};
module.exports = { Inflate: Inflate };
},{"pako/lib/zlib/inflate.js":6,"pako/lib/zlib/zstream.js":8}],2:[function(require,module,exports){
'use strict';
@ -40,28 +82,28 @@ exports.shrinkBuf = function (buf, size) {
var fnTyped = {
arraySet: function (dest, src, src_offs, len, dest_offs) {
if (src.subarray && dest.subarray) {
dest.set(src.subarray(src_offs, src_offs+len), dest_offs);
dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
return;
}
// Fallback to ordinary array
for (var i=0; i<len; i++) {
for (var i = 0; i < len; i++) {
dest[dest_offs + i] = src[src_offs + i];
}
},
// Join array of chunks to single array.
flattenChunks: function(chunks) {
flattenChunks: function (chunks) {
var i, l, len, pos, chunk, result;
// calculate data length
len = 0;
for (i=0, l=chunks.length; i<l; i++) {
for (i = 0, l = chunks.length; i < l; i++) {
len += chunks[i].length;
}
// join chunks
result = new Uint8Array(len);
pos = 0;
for (i=0, l=chunks.length; i<l; i++) {
for (i = 0, l = chunks.length; i < l; i++) {
chunk = chunks[i];
result.set(chunk, pos);
pos += chunk.length;
@ -73,12 +115,12 @@ var fnTyped = {
var fnUntyped = {
arraySet: function (dest, src, src_offs, len, dest_offs) {
for (var i=0; i<len; i++) {
for (var i = 0; i < len; i++) {
dest[dest_offs + i] = src[src_offs + i];
}
},
// Join array of chunks to single array.
flattenChunks: function(chunks) {
flattenChunks: function (chunks) {
return [].concat.apply([], chunks);
}
};
@ -102,7 +144,7 @@ exports.setTyped = function (on) {
exports.setTyped(TYPED_OK);
},{}],2:[function(require,module,exports){
},{}],3:[function(require,module,exports){
'use strict';
// Note: adler32 takes 12% for level 0 and 2% for level 6.
@ -136,7 +178,7 @@ function adler32(adler, buf, len, pos) {
module.exports = adler32;
},{}],3:[function(require,module,exports){
},{}],4:[function(require,module,exports){
'use strict';
// Note: we can't get significant speed boost here.
@ -148,10 +190,10 @@ module.exports = adler32;
function makeTable() {
var c, table = [];
for (var n =0; n < 256; n++) {
for (var n = 0; n < 256; n++) {
c = n;
for (var k =0; k < 8; k++) {
c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
for (var k = 0; k < 8; k++) {
c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
}
table[n] = c;
}
@ -167,7 +209,7 @@ function crc32(crc, buf, len, pos) {
var t = crcTable,
end = pos + len;
crc = crc ^ (-1);
crc ^= -1;
for (var i = pos; i < end; i++) {
crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];
@ -179,7 +221,7 @@ function crc32(crc, buf, len, pos) {
module.exports = crc32;
},{}],4:[function(require,module,exports){
},{}],5:[function(require,module,exports){
'use strict';
// See state defs from inflate.js
@ -507,14 +549,14 @@ module.exports = function inflate_fast(strm, start) {
return;
};
},{}],5:[function(require,module,exports){
},{}],6:[function(require,module,exports){
'use strict';
var utils = require('../utils/common');
var adler32 = require('./adler32');
var crc32 = require('./crc32');
var inflate_fast = require('./inffast');
var utils = require('../utils/common');
var adler32 = require('./adler32');
var crc32 = require('./crc32');
var inflate_fast = require('./inffast');
var inflate_table = require('./inftrees');
var CODES = 0;
@ -602,7 +644,7 @@ var MAX_WBITS = 15;
var DEF_WBITS = MAX_WBITS;
function ZSWAP32(q) {
function zswap32(q) {
return (((q >>> 24) & 0xff) +
((q >>> 8) & 0xff00) +
((q & 0xff00) << 8) +
@ -795,13 +837,13 @@ function fixedtables(state) {
while (sym < 280) { state.lens[sym++] = 7; }
while (sym < 288) { state.lens[sym++] = 8; }
inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, {bits: 9});
inflate_table(LENS, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 });
/* distance table */
sym = 0;
while (sym < 32) { state.lens[sym++] = 5; }
inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, {bits: 5});
inflate_table(DISTS, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 });
/* do this just once */
virgin = false;
@ -843,7 +885,7 @@ function updatewindow(strm, src, end, copy) {
/* copy state->wsize or less output bytes into the circular window */
if (copy >= state.wsize) {
utils.arraySet(state.window,src, end - state.wsize, state.wsize, 0);
utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);
state.wnext = 0;
state.whave = state.wsize;
}
@ -853,11 +895,11 @@ function updatewindow(strm, src, end, copy) {
dist = copy;
}
//zmemcpy(state->window + state->wnext, end - copy, dist);
utils.arraySet(state.window,src, end - copy, dist, state.wnext);
utils.arraySet(state.window, src, end - copy, dist, state.wnext);
copy -= dist;
if (copy) {
//zmemcpy(state->window, end - copy, copy);
utils.arraySet(state.window,src, end - copy, copy, 0);
utils.arraySet(state.window, src, end - copy, copy, 0);
state.wnext = copy;
state.whave = state.wsize;
}
@ -894,7 +936,7 @@ function inflate(strm, flush) {
var n; // temporary var for NEED_BITS
var order = /* permutation of code lengths */
[16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
[ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
if (!strm || !strm.state || !strm.output ||
@ -1221,7 +1263,7 @@ function inflate(strm, flush) {
state.head.hcrc = ((state.flags >> 9) & 1);
state.head.done = true;
}
strm.adler = state.check = 0 /*crc32(0L, Z_NULL, 0)*/;
strm.adler = state.check = 0;
state.mode = TYPE;
break;
case DICTID:
@ -1233,7 +1275,7 @@ function inflate(strm, flush) {
bits += 8;
}
//===//
strm.adler = state.check = ZSWAP32(hold);
strm.adler = state.check = zswap32(hold);
//=== INITBITS();
hold = 0;
bits = 0;
@ -1425,7 +1467,7 @@ function inflate(strm, flush) {
state.lencode = state.lendyn;
state.lenbits = 7;
opts = {bits: state.lenbits};
opts = { bits: state.lenbits };
ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
state.lenbits = opts.bits;
@ -1556,7 +1598,7 @@ function inflate(strm, flush) {
concerning the ENOUGH constants, which depend on those values */
state.lenbits = 9;
opts = {bits: state.lenbits};
opts = { bits: state.lenbits };
ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
// We have separate tables & no pointers. 2 commented lines below not needed.
// state.next_index = opts.table_index;
@ -1573,7 +1615,7 @@ function inflate(strm, flush) {
//state.distcode.copy(state.codes);
// Switch to use dynamic table
state.distcode = state.distdyn;
opts = {bits: state.distbits};
opts = { bits: state.distbits };
ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
// We have separate tables & no pointers. 2 commented lines below not needed.
// state.next_index = opts.table_index;
@ -1621,7 +1663,7 @@ function inflate(strm, flush) {
}
state.back = 0;
for (;;) {
here = state.lencode[hold & ((1 << state.lenbits) -1)]; /*BITS(state.lenbits)*/
here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/
here_bits = here >>> 24;
here_op = (here >>> 16) & 0xff;
here_val = here & 0xffff;
@ -1640,7 +1682,7 @@ function inflate(strm, flush) {
last_val = here_val;
for (;;) {
here = state.lencode[last_val +
((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)];
((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
here_bits = here >>> 24;
here_op = (here >>> 16) & 0xff;
here_val = here & 0xffff;
@ -1697,7 +1739,7 @@ function inflate(strm, flush) {
bits += 8;
}
//===//
state.length += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/;
state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
//--- DROPBITS(state.extra) ---//
hold >>>= state.extra;
bits -= state.extra;
@ -1710,7 +1752,7 @@ function inflate(strm, flush) {
/* falls through */
case DIST:
for (;;) {
here = state.distcode[hold & ((1 << state.distbits) -1)];/*BITS(state.distbits)*/
here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/
here_bits = here >>> 24;
here_op = (here >>> 16) & 0xff;
here_val = here & 0xffff;
@ -1729,7 +1771,7 @@ function inflate(strm, flush) {
last_val = here_val;
for (;;) {
here = state.distcode[last_val +
((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)];
((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
here_bits = here >>> 24;
here_op = (here >>> 16) & 0xff;
here_val = here & 0xffff;
@ -1773,7 +1815,7 @@ function inflate(strm, flush) {
bits += 8;
}
//===//
state.offset += hold & ((1 << state.extra) -1)/*BITS(state.extra)*/;
state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
//--- DROPBITS(state.extra) ---//
hold >>>= state.extra;
bits -= state.extra;
@ -1867,8 +1909,8 @@ function inflate(strm, flush) {
}
_out = left;
// NB: crc32 stored as signed 32-bit int, ZSWAP32 returns signed too
if ((state.flags ? hold : ZSWAP32(hold)) !== state.check) {
// NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
if ((state.flags ? hold : zswap32(hold)) !== state.check) {
strm.msg = 'incorrect data check';
state.mode = BAD;
break;
@ -1990,6 +2032,41 @@ function inflateGetHeader(strm, head) {
return Z_OK;
}
function inflateSetDictionary(strm, dictionary) {
var dictLength = dictionary.length;
var state;
var dictid;
var ret;
/* check state */
if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }
state = strm.state;
if (state.wrap !== 0 && state.mode !== DICT) {
return Z_STREAM_ERROR;
}
/* check for correct dictionary identifier */
if (state.mode === DICT) {
dictid = 1; /* adler32(0, null, 0)*/
/* dictid = adler32(dictid, dictionary, dictLength); */
dictid = adler32(dictid, dictionary, dictLength, 0);
if (dictid !== state.check) {
return Z_DATA_ERROR;
}
}
/* copy dictionary to window using updatewindow(), which will amend the
existing dictionary if appropriate */
ret = updatewindow(strm, dictionary, dictLength, dictLength);
if (ret) {
state.mode = MEM;
return Z_MEM_ERROR;
}
state.havedict = 1;
// Tracev((stderr, "inflate: dictionary set\n"));
return Z_OK;
}
exports.inflateReset = inflateReset;
exports.inflateReset2 = inflateReset2;
@ -1999,6 +2076,7 @@ exports.inflateInit2 = inflateInit2;
exports.inflate = inflate;
exports.inflateEnd = inflateEnd;
exports.inflateGetHeader = inflateGetHeader;
exports.inflateSetDictionary = inflateSetDictionary;
exports.inflateInfo = 'pako inflate (from Nodeca project)';
/* Not implemented
@ -2006,13 +2084,12 @@ exports.inflateCopy = inflateCopy;
exports.inflateGetDictionary = inflateGetDictionary;
exports.inflateMark = inflateMark;
exports.inflatePrime = inflatePrime;
exports.inflateSetDictionary = inflateSetDictionary;
exports.inflateSync = inflateSync;
exports.inflateSyncPoint = inflateSyncPoint;
exports.inflateUndermine = inflateUndermine;
*/
},{"../utils/common":1,"./adler32":2,"./crc32":3,"./inffast":4,"./inftrees":6}],6:[function(require,module,exports){
},{"../utils/common":2,"./adler32":3,"./crc32":4,"./inffast":5,"./inftrees":7}],7:[function(require,module,exports){
'use strict';
@ -2072,8 +2149,8 @@ module.exports = function inflate_table(type, lens, lens_index, codes, table, ta
var base_index = 0;
// var shoextra; /* extra bits table to use */
var end; /* use base and extra for symbol > end */
var count = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* number of codes of each length */
var offs = new utils.Buf16(MAXBITS+1); //[MAXBITS+1]; /* offsets in table for each length */
var count = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */
var offs = new utils.Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */
var extra = null;
var extra_index = 0;
@ -2242,7 +2319,7 @@ module.exports = function inflate_table(type, lens, lens_index, codes, table, ta
return 1;
}
var i=0;
var i = 0;
/* process all codes and make table entries */
for (;;) {
i++;
@ -2341,7 +2418,7 @@ module.exports = function inflate_table(type, lens, lens_index, codes, table, ta
return 0;
};
},{"../utils/common":1}],7:[function(require,module,exports){
},{"../utils/common":2}],8:[function(require,module,exports){
'use strict';
@ -2372,47 +2449,5 @@ function ZStream() {
module.exports = ZStream;
},{}],8:[function(require,module,exports){
var zlib = require('../node_modules/pako/lib/zlib/inflate.js');
var ZStream = require('../node_modules/pako/lib/zlib/zstream.js');
var Inflate = function () {
this.strm = new ZStream();
this.chunkSize = 1024 * 10 * 10;
this.strm.output = new Uint8Array(this.chunkSize);
this.windowBits = 5;
zlib.inflateInit(this.strm, this.windowBits);
};
Inflate.prototype = {
inflate: function (data, flush, expected) {
this.strm.input = data;
this.strm.avail_in = this.strm.input.length;
this.strm.next_in = 0;
this.strm.next_out = 0;
// resize our output buffer if it's too small
// (we could just use multiple chunks, but that would cause an extra
// allocation each time to flatten the chunks)
if (expected > this.chunkSize) {
this.chunkSize = expected;
this.strm.output = new Uint8Array(this.chunkSize);
}
this.strm.avail_out = this.chunkSize;
zlib.inflate(this.strm, flush);
return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out);
},
reset: function () {
zlib.inflateReset(this.strm);
}
};
module.exports = {Inflate: Inflate};
},{"../node_modules/pako/lib/zlib/inflate.js":5,"../node_modules/pako/lib/zlib/zstream.js":7}]},{},[8])(8)
},{}]},{},[1])(1)
});

View File

@ -1,7 +1,7 @@
var zlib = require('../node_modules/pako/lib/zlib/inflate.js');
var ZStream = require('../node_modules/pako/lib/zlib/zstream.js');
var zlib = require('pako/lib/zlib/inflate.js');
var ZStream = require('pako/lib/zlib/zstream.js');
var Inflate = function () {
function Inflate() {
this.strm = new ZStream();
this.chunkSize = 1024 * 10 * 10;
this.strm.output = new Uint8Array(this.chunkSize);
@ -37,4 +37,4 @@ Inflate.prototype = {
}
};
module.exports = {Inflate: Inflate};
module.exports = { Inflate: Inflate };

View File

@ -8,7 +8,12 @@
/*jslint browser: true, white: false */
/*global window, Util */
var Keyboard, Mouse;
/* [module]
* import Util from "../util";
* import KeyboardUtil from "./util";
*/
/* [module] export */ var Keyboard;
(function () {
"use strict";
@ -27,10 +32,10 @@ var Keyboard, Mouse;
});
// create the keyboard handler
this._handler = new KeyEventDecoder(kbdUtil.ModifierSync(),
VerifyCharModifier( /* jshint newcap: false */
TrackKeyState(
EscapeModifiers(this._handleRfbEvent.bind(this))
this._handler = new KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(),
KeyboardUtil.VerifyCharModifier( /* jshint newcap: false */
KeyboardUtil.TrackKeyState(
KeyboardUtil.EscapeModifiers(this._handleRfbEvent.bind(this))
)
)
); /* jshint newcap: true */
@ -56,8 +61,8 @@ var Keyboard, Mouse;
},
setQEMUVNCKeyboardHandler: function () {
this._handler = new QEMUKeyEventDecoder(kbdUtil.ModifierSync(),
TrackQEMUKeyState(
this._handler = new KeyboardUtil.QEMUKeyEventDecoder(KeyboardUtil.ModifierSync(),
KeyboardUtil.TrackQEMUKeyState(
this._handleRfbEvent.bind(this)
)
);
@ -117,12 +122,12 @@ var Keyboard, Mouse;
//Util.Debug(">> Keyboard.grab");
var c = this._target;
Util.addEvent(c, 'keydown', this._eventHandlers.keydown);
Util.addEvent(c, 'keyup', this._eventHandlers.keyup);
Util.addEvent(c, 'keypress', this._eventHandlers.keypress);
c.addEventListener('keydown', this._eventHandlers.keydown);
c.addEventListener('keyup', this._eventHandlers.keyup);
c.addEventListener('keypress', this._eventHandlers.keypress);
// Release (key up) if window loses focus
Util.addEvent(window, 'blur', this._eventHandlers.blur);
window.addEventListener('blur', this._eventHandlers.blur);
//Util.Debug("<< Keyboard.grab");
},
@ -131,10 +136,10 @@ var Keyboard, Mouse;
//Util.Debug(">> Keyboard.ungrab");
var c = this._target;
Util.removeEvent(c, 'keydown', this._eventHandlers.keydown);
Util.removeEvent(c, 'keyup', this._eventHandlers.keyup);
Util.removeEvent(c, 'keypress', this._eventHandlers.keypress);
Util.removeEvent(window, 'blur', this._eventHandlers.blur);
c.removeEventListener('keydown', this._eventHandlers.keydown);
c.removeEventListener('keyup', this._eventHandlers.keyup);
c.removeEventListener('keypress', this._eventHandlers.keypress);
window.removeEventListener('blur', this._eventHandlers.blur);
// Release (key up) all keys that are in a down state
this._allKeysUp();
@ -153,11 +158,11 @@ var Keyboard, Mouse;
['onKeyPress', 'rw', 'func'] // Handler for key press/release
]);
})();
//
// Mouse event handler
//
/* [module] export */ var Mouse;
(function () {
Mouse = function (defaults) {
this._mouseCaptured = false;
@ -342,44 +347,44 @@ var Keyboard, Mouse;
var c = this._target;
if ('ontouchstart' in document.documentElement) {
Util.addEvent(c, 'touchstart', this._eventHandlers.mousedown);
Util.addEvent(window, 'touchend', this._eventHandlers.mouseup);
Util.addEvent(c, 'touchend', this._eventHandlers.mouseup);
Util.addEvent(c, 'touchmove', this._eventHandlers.mousemove);
c.addEventListener('touchstart', this._eventHandlers.mousedown);
window.addEventListener('touchend', this._eventHandlers.mouseup);
c.addEventListener('touchend', this._eventHandlers.mouseup);
c.addEventListener('touchmove', this._eventHandlers.mousemove);
} else {
Util.addEvent(c, 'mousedown', this._eventHandlers.mousedown);
Util.addEvent(window, 'mouseup', this._eventHandlers.mouseup);
Util.addEvent(c, 'mouseup', this._eventHandlers.mouseup);
Util.addEvent(c, 'mousemove', this._eventHandlers.mousemove);
Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel',
c.addEventListener('mousedown', this._eventHandlers.mousedown);
window.addEventListener('mouseup', this._eventHandlers.mouseup);
c.addEventListener('mouseup', this._eventHandlers.mouseup);
c.addEventListener('mousemove', this._eventHandlers.mousemove);
c.addEventListener((Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel',
this._eventHandlers.mousewheel);
}
/* Work around right and middle click browser behaviors */
Util.addEvent(document, 'click', this._eventHandlers.mousedisable);
Util.addEvent(document.body, 'contextmenu', this._eventHandlers.mousedisable);
document.addEventListener('click', this._eventHandlers.mousedisable);
document.body.addEventListener('contextmenu', this._eventHandlers.mousedisable);
},
ungrab: function () {
var c = this._target;
if ('ontouchstart' in document.documentElement) {
Util.removeEvent(c, 'touchstart', this._eventHandlers.mousedown);
Util.removeEvent(window, 'touchend', this._eventHandlers.mouseup);
Util.removeEvent(c, 'touchend', this._eventHandlers.mouseup);
Util.removeEvent(c, 'touchmove', this._eventHandlers.mousemove);
c.removeEventListener('touchstart', this._eventHandlers.mousedown);
window.removeEventListener('touchend', this._eventHandlers.mouseup);
c.removeEventListener('touchend', this._eventHandlers.mouseup);
c.removeEventListener('touchmove', this._eventHandlers.mousemove);
} else {
Util.removeEvent(c, 'mousedown', this._eventHandlers.mousedown);
Util.removeEvent(window, 'mouseup', this._eventHandlers.mouseup);
Util.removeEvent(c, 'mouseup', this._eventHandlers.mouseup);
Util.removeEvent(c, 'mousemove', this._eventHandlers.mousemove);
Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel',
c.removeEventListener('mousedown', this._eventHandlers.mousedown);
window.removeEventListener('mouseup', this._eventHandlers.mouseup);
c.removeEventListener('mouseup', this._eventHandlers.mouseup);
c.removeEventListener('mousemove', this._eventHandlers.mousemove);
c.removeEventListener((Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel',
this._eventHandlers.mousewheel);
}
/* Work around right and middle click browser behaviors */
Util.removeEvent(document, 'click', this._eventHandlers.mousedisable);
Util.removeEvent(document.body, 'contextmenu', this._eventHandlers.mousedisable);
document.removeEventListener('click', this._eventHandlers.mousedisable);
document.body.removeEventListener('contextmenu', this._eventHandlers.mousedisable);
}
};

382
core/input/keysym.js Normal file
View File

@ -0,0 +1,382 @@
var KeyTable = {
XK_VoidSymbol: 0xffffff, /* Void symbol */
XK_BackSpace: 0xff08, /* Back space, back char */
XK_Tab: 0xff09,
XK_Linefeed: 0xff0a, /* Linefeed, LF */
XK_Clear: 0xff0b,
XK_Return: 0xff0d, /* Return, enter */
XK_Pause: 0xff13, /* Pause, hold */
XK_Scroll_Lock: 0xff14,
XK_Sys_Req: 0xff15,
XK_Escape: 0xff1b,
XK_Delete: 0xffff, /* Delete, rubout */
/* Cursor control & motion */
XK_Home: 0xff50,
XK_Left: 0xff51, /* Move left, left arrow */
XK_Up: 0xff52, /* Move up, up arrow */
XK_Right: 0xff53, /* Move right, right arrow */
XK_Down: 0xff54, /* Move down, down arrow */
XK_Prior: 0xff55, /* Prior, previous */
XK_Page_Up: 0xff55,
XK_Next: 0xff56, /* Next */
XK_Page_Down: 0xff56,
XK_End: 0xff57, /* EOL */
XK_Begin: 0xff58, /* BOL */
/* Misc functions */
XK_Select: 0xff60, /* Select, mark */
XK_Print: 0xff61,
XK_Execute: 0xff62, /* Execute, run, do */
XK_Insert: 0xff63, /* Insert, insert here */
XK_Undo: 0xff65,
XK_Redo: 0xff66, /* Redo, again */
XK_Menu: 0xff67,
XK_Find: 0xff68, /* Find, search */
XK_Cancel: 0xff69, /* Cancel, stop, abort, exit */
XK_Help: 0xff6a, /* Help */
XK_Break: 0xff6b,
XK_Mode_switch: 0xff7e, /* Character set switch */
XK_script_switch: 0xff7e, /* Alias for mode_switch */
XK_Num_Lock: 0xff7f,
/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */
XK_KP_Space: 0xff80, /* Space */
XK_KP_Tab: 0xff89,
XK_KP_Enter: 0xff8d, /* Enter */
XK_KP_F1: 0xff91, /* PF1, KP_A, ... */
XK_KP_F2: 0xff92,
XK_KP_F3: 0xff93,
XK_KP_F4: 0xff94,
XK_KP_Home: 0xff95,
XK_KP_Left: 0xff96,
XK_KP_Up: 0xff97,
XK_KP_Right: 0xff98,
XK_KP_Down: 0xff99,
XK_KP_Prior: 0xff9a,
XK_KP_Page_Up: 0xff9a,
XK_KP_Next: 0xff9b,
XK_KP_Page_Down: 0xff9b,
XK_KP_End: 0xff9c,
XK_KP_Begin: 0xff9d,
XK_KP_Insert: 0xff9e,
XK_KP_Delete: 0xff9f,
XK_KP_Equal: 0xffbd, /* Equals */
XK_KP_Multiply: 0xffaa,
XK_KP_Add: 0xffab,
XK_KP_Separator: 0xffac, /* Separator, often comma */
XK_KP_Subtract: 0xffad,
XK_KP_Decimal: 0xffae,
XK_KP_Divide: 0xffaf,
XK_KP_0: 0xffb0,
XK_KP_1: 0xffb1,
XK_KP_2: 0xffb2,
XK_KP_3: 0xffb3,
XK_KP_4: 0xffb4,
XK_KP_5: 0xffb5,
XK_KP_6: 0xffb6,
XK_KP_7: 0xffb7,
XK_KP_8: 0xffb8,
XK_KP_9: 0xffb9,
/*
* Auxiliary functions; note the duplicate definitions for left and right
* function keys; Sun keyboards and a few other manufacturers have such
* function key groups on the left and/or right sides of the keyboard.
* We've not found a keyboard with more than 35 function keys total.
*/
XK_F1: 0xffbe,
XK_F2: 0xffbf,
XK_F3: 0xffc0,
XK_F4: 0xffc1,
XK_F5: 0xffc2,
XK_F6: 0xffc3,
XK_F7: 0xffc4,
XK_F8: 0xffc5,
XK_F9: 0xffc6,
XK_F10: 0xffc7,
XK_F11: 0xffc8,
XK_L1: 0xffc8,
XK_F12: 0xffc9,
XK_L2: 0xffc9,
XK_F13: 0xffca,
XK_L3: 0xffca,
XK_F14: 0xffcb,
XK_L4: 0xffcb,
XK_F15: 0xffcc,
XK_L5: 0xffcc,
XK_F16: 0xffcd,
XK_L6: 0xffcd,
XK_F17: 0xffce,
XK_L7: 0xffce,
XK_F18: 0xffcf,
XK_L8: 0xffcf,
XK_F19: 0xffd0,
XK_L9: 0xffd0,
XK_F20: 0xffd1,
XK_L10: 0xffd1,
XK_F21: 0xffd2,
XK_R1: 0xffd2,
XK_F22: 0xffd3,
XK_R2: 0xffd3,
XK_F23: 0xffd4,
XK_R3: 0xffd4,
XK_F24: 0xffd5,
XK_R4: 0xffd5,
XK_F25: 0xffd6,
XK_R5: 0xffd6,
XK_F26: 0xffd7,
XK_R6: 0xffd7,
XK_F27: 0xffd8,
XK_R7: 0xffd8,
XK_F28: 0xffd9,
XK_R8: 0xffd9,
XK_F29: 0xffda,
XK_R9: 0xffda,
XK_F30: 0xffdb,
XK_R10: 0xffdb,
XK_F31: 0xffdc,
XK_R11: 0xffdc,
XK_F32: 0xffdd,
XK_R12: 0xffdd,
XK_F33: 0xffde,
XK_R13: 0xffde,
XK_F34: 0xffdf,
XK_R14: 0xffdf,
XK_F35: 0xffe0,
XK_R15: 0xffe0,
/* Modifiers */
XK_Shift_L: 0xffe1, /* Left shift */
XK_Shift_R: 0xffe2, /* Right shift */
XK_Control_L: 0xffe3, /* Left control */
XK_Control_R: 0xffe4, /* Right control */
XK_Caps_Lock: 0xffe5, /* Caps lock */
XK_Shift_Lock: 0xffe6, /* Shift lock */
XK_Meta_L: 0xffe7, /* Left meta */
XK_Meta_R: 0xffe8, /* Right meta */
XK_Alt_L: 0xffe9, /* Left alt */
XK_Alt_R: 0xffea, /* Right alt */
XK_Super_L: 0xffeb, /* Left super */
XK_Super_R: 0xffec, /* Right super */
XK_Hyper_L: 0xffed, /* Left hyper */
XK_Hyper_R: 0xffee, /* Right hyper */
XK_ISO_Level3_Shift: 0xfe03, /* AltGr */
/*
* Latin 1
* (ISO/IEC 8859-1: Unicode U+0020..U+00FF)
* Byte 3: 0
*/
XK_space: 0x0020, /* U+0020 SPACE */
XK_exclam: 0x0021, /* U+0021 EXCLAMATION MARK */
XK_quotedbl: 0x0022, /* U+0022 QUOTATION MARK */
XK_numbersign: 0x0023, /* U+0023 NUMBER SIGN */
XK_dollar: 0x0024, /* U+0024 DOLLAR SIGN */
XK_percent: 0x0025, /* U+0025 PERCENT SIGN */
XK_ampersand: 0x0026, /* U+0026 AMPERSAND */
XK_apostrophe: 0x0027, /* U+0027 APOSTROPHE */
XK_quoteright: 0x0027, /* deprecated */
XK_parenleft: 0x0028, /* U+0028 LEFT PARENTHESIS */
XK_parenright: 0x0029, /* U+0029 RIGHT PARENTHESIS */
XK_asterisk: 0x002a, /* U+002A ASTERISK */
XK_plus: 0x002b, /* U+002B PLUS SIGN */
XK_comma: 0x002c, /* U+002C COMMA */
XK_minus: 0x002d, /* U+002D HYPHEN-MINUS */
XK_period: 0x002e, /* U+002E FULL STOP */
XK_slash: 0x002f, /* U+002F SOLIDUS */
XK_0: 0x0030, /* U+0030 DIGIT ZERO */
XK_1: 0x0031, /* U+0031 DIGIT ONE */
XK_2: 0x0032, /* U+0032 DIGIT TWO */
XK_3: 0x0033, /* U+0033 DIGIT THREE */
XK_4: 0x0034, /* U+0034 DIGIT FOUR */
XK_5: 0x0035, /* U+0035 DIGIT FIVE */
XK_6: 0x0036, /* U+0036 DIGIT SIX */
XK_7: 0x0037, /* U+0037 DIGIT SEVEN */
XK_8: 0x0038, /* U+0038 DIGIT EIGHT */
XK_9: 0x0039, /* U+0039 DIGIT NINE */
XK_colon: 0x003a, /* U+003A COLON */
XK_semicolon: 0x003b, /* U+003B SEMICOLON */
XK_less: 0x003c, /* U+003C LESS-THAN SIGN */
XK_equal: 0x003d, /* U+003D EQUALS SIGN */
XK_greater: 0x003e, /* U+003E GREATER-THAN SIGN */
XK_question: 0x003f, /* U+003F QUESTION MARK */
XK_at: 0x0040, /* U+0040 COMMERCIAL AT */
XK_A: 0x0041, /* U+0041 LATIN CAPITAL LETTER A */
XK_B: 0x0042, /* U+0042 LATIN CAPITAL LETTER B */
XK_C: 0x0043, /* U+0043 LATIN CAPITAL LETTER C */
XK_D: 0x0044, /* U+0044 LATIN CAPITAL LETTER D */
XK_E: 0x0045, /* U+0045 LATIN CAPITAL LETTER E */
XK_F: 0x0046, /* U+0046 LATIN CAPITAL LETTER F */
XK_G: 0x0047, /* U+0047 LATIN CAPITAL LETTER G */
XK_H: 0x0048, /* U+0048 LATIN CAPITAL LETTER H */
XK_I: 0x0049, /* U+0049 LATIN CAPITAL LETTER I */
XK_J: 0x004a, /* U+004A LATIN CAPITAL LETTER J */
XK_K: 0x004b, /* U+004B LATIN CAPITAL LETTER K */
XK_L: 0x004c, /* U+004C LATIN CAPITAL LETTER L */
XK_M: 0x004d, /* U+004D LATIN CAPITAL LETTER M */
XK_N: 0x004e, /* U+004E LATIN CAPITAL LETTER N */
XK_O: 0x004f, /* U+004F LATIN CAPITAL LETTER O */
XK_P: 0x0050, /* U+0050 LATIN CAPITAL LETTER P */
XK_Q: 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */
XK_R: 0x0052, /* U+0052 LATIN CAPITAL LETTER R */
XK_S: 0x0053, /* U+0053 LATIN CAPITAL LETTER S */
XK_T: 0x0054, /* U+0054 LATIN CAPITAL LETTER T */
XK_U: 0x0055, /* U+0055 LATIN CAPITAL LETTER U */
XK_V: 0x0056, /* U+0056 LATIN CAPITAL LETTER V */
XK_W: 0x0057, /* U+0057 LATIN CAPITAL LETTER W */
XK_X: 0x0058, /* U+0058 LATIN CAPITAL LETTER X */
XK_Y: 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */
XK_Z: 0x005a, /* U+005A LATIN CAPITAL LETTER Z */
XK_bracketleft: 0x005b, /* U+005B LEFT SQUARE BRACKET */
XK_backslash: 0x005c, /* U+005C REVERSE SOLIDUS */
XK_bracketright: 0x005d, /* U+005D RIGHT SQUARE BRACKET */
XK_asciicircum: 0x005e, /* U+005E CIRCUMFLEX ACCENT */
XK_underscore: 0x005f, /* U+005F LOW LINE */
XK_grave: 0x0060, /* U+0060 GRAVE ACCENT */
XK_quoteleft: 0x0060, /* deprecated */
XK_a: 0x0061, /* U+0061 LATIN SMALL LETTER A */
XK_b: 0x0062, /* U+0062 LATIN SMALL LETTER B */
XK_c: 0x0063, /* U+0063 LATIN SMALL LETTER C */
XK_d: 0x0064, /* U+0064 LATIN SMALL LETTER D */
XK_e: 0x0065, /* U+0065 LATIN SMALL LETTER E */
XK_f: 0x0066, /* U+0066 LATIN SMALL LETTER F */
XK_g: 0x0067, /* U+0067 LATIN SMALL LETTER G */
XK_h: 0x0068, /* U+0068 LATIN SMALL LETTER H */
XK_i: 0x0069, /* U+0069 LATIN SMALL LETTER I */
XK_j: 0x006a, /* U+006A LATIN SMALL LETTER J */
XK_k: 0x006b, /* U+006B LATIN SMALL LETTER K */
XK_l: 0x006c, /* U+006C LATIN SMALL LETTER L */
XK_m: 0x006d, /* U+006D LATIN SMALL LETTER M */
XK_n: 0x006e, /* U+006E LATIN SMALL LETTER N */
XK_o: 0x006f, /* U+006F LATIN SMALL LETTER O */
XK_p: 0x0070, /* U+0070 LATIN SMALL LETTER P */
XK_q: 0x0071, /* U+0071 LATIN SMALL LETTER Q */
XK_r: 0x0072, /* U+0072 LATIN SMALL LETTER R */
XK_s: 0x0073, /* U+0073 LATIN SMALL LETTER S */
XK_t: 0x0074, /* U+0074 LATIN SMALL LETTER T */
XK_u: 0x0075, /* U+0075 LATIN SMALL LETTER U */
XK_v: 0x0076, /* U+0076 LATIN SMALL LETTER V */
XK_w: 0x0077, /* U+0077 LATIN SMALL LETTER W */
XK_x: 0x0078, /* U+0078 LATIN SMALL LETTER X */
XK_y: 0x0079, /* U+0079 LATIN SMALL LETTER Y */
XK_z: 0x007a, /* U+007A LATIN SMALL LETTER Z */
XK_braceleft: 0x007b, /* U+007B LEFT CURLY BRACKET */
XK_bar: 0x007c, /* U+007C VERTICAL LINE */
XK_braceright: 0x007d, /* U+007D RIGHT CURLY BRACKET */
XK_asciitilde: 0x007e, /* U+007E TILDE */
XK_nobreakspace: 0x00a0, /* U+00A0 NO-BREAK SPACE */
XK_exclamdown: 0x00a1, /* U+00A1 INVERTED EXCLAMATION MARK */
XK_cent: 0x00a2, /* U+00A2 CENT SIGN */
XK_sterling: 0x00a3, /* U+00A3 POUND SIGN */
XK_currency: 0x00a4, /* U+00A4 CURRENCY SIGN */
XK_yen: 0x00a5, /* U+00A5 YEN SIGN */
XK_brokenbar: 0x00a6, /* U+00A6 BROKEN BAR */
XK_section: 0x00a7, /* U+00A7 SECTION SIGN */
XK_diaeresis: 0x00a8, /* U+00A8 DIAERESIS */
XK_copyright: 0x00a9, /* U+00A9 COPYRIGHT SIGN */
XK_ordfeminine: 0x00aa, /* U+00AA FEMININE ORDINAL INDICATOR */
XK_guillemotleft: 0x00ab, /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
XK_notsign: 0x00ac, /* U+00AC NOT SIGN */
XK_hyphen: 0x00ad, /* U+00AD SOFT HYPHEN */
XK_registered: 0x00ae, /* U+00AE REGISTERED SIGN */
XK_macron: 0x00af, /* U+00AF MACRON */
XK_degree: 0x00b0, /* U+00B0 DEGREE SIGN */
XK_plusminus: 0x00b1, /* U+00B1 PLUS-MINUS SIGN */
XK_twosuperior: 0x00b2, /* U+00B2 SUPERSCRIPT TWO */
XK_threesuperior: 0x00b3, /* U+00B3 SUPERSCRIPT THREE */
XK_acute: 0x00b4, /* U+00B4 ACUTE ACCENT */
XK_mu: 0x00b5, /* U+00B5 MICRO SIGN */
XK_paragraph: 0x00b6, /* U+00B6 PILCROW SIGN */
XK_periodcentered: 0x00b7, /* U+00B7 MIDDLE DOT */
XK_cedilla: 0x00b8, /* U+00B8 CEDILLA */
XK_onesuperior: 0x00b9, /* U+00B9 SUPERSCRIPT ONE */
XK_masculine: 0x00ba, /* U+00BA MASCULINE ORDINAL INDICATOR */
XK_guillemotright: 0x00bb, /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
XK_onequarter: 0x00bc, /* U+00BC VULGAR FRACTION ONE QUARTER */
XK_onehalf: 0x00bd, /* U+00BD VULGAR FRACTION ONE HALF */
XK_threequarters: 0x00be, /* U+00BE VULGAR FRACTION THREE QUARTERS */
XK_questiondown: 0x00bf, /* U+00BF INVERTED QUESTION MARK */
XK_Agrave: 0x00c0, /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
XK_Aacute: 0x00c1, /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
XK_Acircumflex: 0x00c2, /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
XK_Atilde: 0x00c3, /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */
XK_Adiaeresis: 0x00c4, /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */
XK_Aring: 0x00c5, /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */
XK_AE: 0x00c6, /* U+00C6 LATIN CAPITAL LETTER AE */
XK_Ccedilla: 0x00c7, /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */
XK_Egrave: 0x00c8, /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */
XK_Eacute: 0x00c9, /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
XK_Ecircumflex: 0x00ca, /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
XK_Ediaeresis: 0x00cb, /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */
XK_Igrave: 0x00cc, /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */
XK_Iacute: 0x00cd, /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */
XK_Icircumflex: 0x00ce, /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
XK_Idiaeresis: 0x00cf, /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */
XK_ETH: 0x00d0, /* U+00D0 LATIN CAPITAL LETTER ETH */
XK_Eth: 0x00d0, /* deprecated */
XK_Ntilde: 0x00d1, /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */
XK_Ograve: 0x00d2, /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */
XK_Oacute: 0x00d3, /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */
XK_Ocircumflex: 0x00d4, /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
XK_Otilde: 0x00d5, /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */
XK_Odiaeresis: 0x00d6, /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */
XK_multiply: 0x00d7, /* U+00D7 MULTIPLICATION SIGN */
XK_Oslash: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
XK_Ooblique: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
XK_Ugrave: 0x00d9, /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */
XK_Uacute: 0x00da, /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */
XK_Ucircumflex: 0x00db, /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
XK_Udiaeresis: 0x00dc, /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */
XK_Yacute: 0x00dd, /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */
XK_THORN: 0x00de, /* U+00DE LATIN CAPITAL LETTER THORN */
XK_Thorn: 0x00de, /* deprecated */
XK_ssharp: 0x00df, /* U+00DF LATIN SMALL LETTER SHARP S */
XK_agrave: 0x00e0, /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */
XK_aacute: 0x00e1, /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */
XK_acircumflex: 0x00e2, /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */
XK_atilde: 0x00e3, /* U+00E3 LATIN SMALL LETTER A WITH TILDE */
XK_adiaeresis: 0x00e4, /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */
XK_aring: 0x00e5, /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */
XK_ae: 0x00e6, /* U+00E6 LATIN SMALL LETTER AE */
XK_ccedilla: 0x00e7, /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */
XK_egrave: 0x00e8, /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */
XK_eacute: 0x00e9, /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
XK_ecircumflex: 0x00ea, /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */
XK_ediaeresis: 0x00eb, /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */
XK_igrave: 0x00ec, /* U+00EC LATIN SMALL LETTER I WITH GRAVE */
XK_iacute: 0x00ed, /* U+00ED LATIN SMALL LETTER I WITH ACUTE */
XK_icircumflex: 0x00ee, /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */
XK_idiaeresis: 0x00ef, /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */
XK_eth: 0x00f0, /* U+00F0 LATIN SMALL LETTER ETH */
XK_ntilde: 0x00f1, /* U+00F1 LATIN SMALL LETTER N WITH TILDE */
XK_ograve: 0x00f2, /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */
XK_oacute: 0x00f3, /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */
XK_ocircumflex: 0x00f4, /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */
XK_otilde: 0x00f5, /* U+00F5 LATIN SMALL LETTER O WITH TILDE */
XK_odiaeresis: 0x00f6, /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */
XK_division: 0x00f7, /* U+00F7 DIVISION SIGN */
XK_oslash: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
XK_ooblique: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
XK_ugrave: 0x00f9, /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */
XK_uacute: 0x00fa, /* U+00FA LATIN SMALL LETTER U WITH ACUTE */
XK_ucircumflex: 0x00fb, /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */
XK_udiaeresis: 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */
XK_yacute: 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
XK_thorn: 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */
XK_ydiaeresis: 0x00ff, /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
};
/* [module] export default KeyTable; */

View File

@ -2,6 +2,7 @@
// (and optionally, key names) expected by the RFB protocol
// How this file was generated:
// node /Users/jalf/dev/mi/novnc/utils/parse.js /opt/X11/include/X11/keysymdef.h
var keysyms = (function(){
"use strict";
var keynames = null;
@ -13,3 +14,5 @@ var keysyms = (function(){
lookup : lookup
};
})();
/* [module] export default keysyms */

View File

@ -1,4 +1,11 @@
var kbdUtil = (function() {
/* [module]
* import KeyTable from "./keysym";
* import keysyms from "./keysymdef";
*/
var KeyboardUtil = {};
(function() {
"use strict";
function substituteCodepoint(cp) {
@ -31,7 +38,7 @@ var kbdUtil = (function() {
function hasShortcutModifier(charModifier, currentModifiers) {
var mods = {};
for (var key in currentModifiers) {
if (parseInt(key) !== XK_Shift_L) {
if (parseInt(key) !== KeyTable.XK_Shift_L) {
mods[key] = currentModifiers[key];
}
}
@ -68,15 +75,15 @@ var kbdUtil = (function() {
if (!charModifier) {
if (isMac()) {
// on Mac, Option (AKA Alt) is used as a char modifier
charModifier = [XK_Alt_L];
charModifier = [KeyTable.XK_Alt_L];
}
else if (isWindows()) {
// on Windows, Ctrl+Alt is used as a char modifier
charModifier = [XK_Alt_L, XK_Control_L];
charModifier = [KeyTable.XK_Alt_L, KeyTable.XK_Control_L];
}
else if (isLinux()) {
// on Linux, ISO Level 3 Shift (AltGr) is used as a char modifier
charModifier = [XK_ISO_Level3_Shift];
charModifier = [KeyTable.XK_ISO_Level3_Shift];
}
else {
charModifier = [];
@ -84,11 +91,11 @@ var kbdUtil = (function() {
}
var state = {};
state[XK_Control_L] = false;
state[XK_Alt_L] = false;
state[XK_ISO_Level3_Shift] = false;
state[XK_Shift_L] = false;
state[XK_Meta_L] = false;
state[KeyTable.XK_Control_L] = false;
state[KeyTable.XK_Alt_L] = false;
state[KeyTable.XK_ISO_Level3_Shift] = false;
state[KeyTable.XK_Shift_L] = false;
state[KeyTable.XK_Meta_L] = false;
function sync(evt, keysym) {
var result = [];
@ -97,29 +104,29 @@ var kbdUtil = (function() {
}
if (evt.ctrlKey !== undefined &&
evt.ctrlKey !== state[XK_Control_L] && keysym !== XK_Control_L) {
state[XK_Control_L] = evt.ctrlKey;
result.push(syncKey(XK_Control_L));
evt.ctrlKey !== state[KeyTable.XK_Control_L] && keysym !== KeyTable.XK_Control_L) {
state[KeyTable.XK_Control_L] = evt.ctrlKey;
result.push(syncKey(KeyTable.XK_Control_L));
}
if (evt.altKey !== undefined &&
evt.altKey !== state[XK_Alt_L] && keysym !== XK_Alt_L) {
state[XK_Alt_L] = evt.altKey;
result.push(syncKey(XK_Alt_L));
evt.altKey !== state[KeyTable.XK_Alt_L] && keysym !== KeyTable.XK_Alt_L) {
state[KeyTable.XK_Alt_L] = evt.altKey;
result.push(syncKey(KeyTable.XK_Alt_L));
}
if (evt.altGraphKey !== undefined &&
evt.altGraphKey !== state[XK_ISO_Level3_Shift] && keysym !== XK_ISO_Level3_Shift) {
state[XK_ISO_Level3_Shift] = evt.altGraphKey;
result.push(syncKey(XK_ISO_Level3_Shift));
evt.altGraphKey !== state[KeyTable.XK_ISO_Level3_Shift] && keysym !== KeyTable.XK_ISO_Level3_Shift) {
state[KeyTable.XK_ISO_Level3_Shift] = evt.altGraphKey;
result.push(syncKey(KeyTable.XK_ISO_Level3_Shift));
}
if (evt.shiftKey !== undefined &&
evt.shiftKey !== state[XK_Shift_L] && keysym !== XK_Shift_L) {
state[XK_Shift_L] = evt.shiftKey;
result.push(syncKey(XK_Shift_L));
evt.shiftKey !== state[KeyTable.XK_Shift_L] && keysym !== KeyTable.XK_Shift_L) {
state[KeyTable.XK_Shift_L] = evt.shiftKey;
result.push(syncKey(KeyTable.XK_Shift_L));
}
if (evt.metaKey !== undefined &&
evt.metaKey !== state[XK_Meta_L] && keysym !== XK_Meta_L) {
state[XK_Meta_L] = evt.metaKey;
result.push(syncKey(XK_Meta_L));
evt.metaKey !== state[KeyTable.XK_Meta_L] && keysym !== KeyTable.XK_Meta_L) {
state[KeyTable.XK_Meta_L] = evt.metaKey;
result.push(syncKey(KeyTable.XK_Meta_L));
}
return result;
}
@ -210,21 +217,21 @@ var kbdUtil = (function() {
return shiftPressed ? keycode : keycode + 32; // A-Z
}
if (keycode >= 0x60 && keycode <= 0x69) {
return XK_KP_0 + (keycode - 0x60); // numpad 0-9
return KeyTable.XK_KP_0 + (keycode - 0x60); // numpad 0-9
}
switch(keycode) {
case 0x20: return XK_space;
case 0x6a: return XK_KP_Multiply;
case 0x6b: return XK_KP_Add;
case 0x6c: return XK_KP_Separator;
case 0x6d: return XK_KP_Subtract;
case 0x6e: return XK_KP_Decimal;
case 0x6f: return XK_KP_Divide;
case 0xbb: return XK_plus;
case 0xbc: return XK_comma;
case 0xbd: return XK_minus;
case 0xbe: return XK_period;
case 0x20: return KeyTable.XK_space;
case 0x6a: return KeyTable.XK_KP_Multiply;
case 0x6b: return KeyTable.XK_KP_Add;
case 0x6c: return KeyTable.XK_KP_Separator;
case 0x6d: return KeyTable.XK_KP_Subtract;
case 0x6e: return KeyTable.XK_KP_Decimal;
case 0x6f: return KeyTable.XK_KP_Divide;
case 0xbb: return KeyTable.XK_plus;
case 0xbc: return KeyTable.XK_comma;
case 0xbd: return KeyTable.XK_minus;
case 0xbe: return KeyTable.XK_period;
}
return nonCharacterKey({keyCode: keycode});
@ -238,54 +245,53 @@ var kbdUtil = (function() {
var keycode = evt.keyCode;
if (keycode >= 0x70 && keycode <= 0x87) {
return XK_F1 + keycode - 0x70; // F1-F24
return KeyTable.XK_F1 + keycode - 0x70; // F1-F24
}
switch (keycode) {
case 8 : return XK_BackSpace;
case 13 : return XK_Return;
case 8 : return KeyTable.XK_BackSpace;
case 13 : return KeyTable.XK_Return;
case 9 : return XK_Tab;
case 9 : return KeyTable.XK_Tab;
case 27 : return XK_Escape;
case 46 : return XK_Delete;
case 27 : return KeyTable.XK_Escape;
case 46 : return KeyTable.XK_Delete;
case 36 : return XK_Home;
case 35 : return XK_End;
case 33 : return XK_Page_Up;
case 34 : return XK_Page_Down;
case 45 : return XK_Insert;
case 36 : return KeyTable.XK_Home;
case 35 : return KeyTable.XK_End;
case 33 : return KeyTable.XK_Page_Up;
case 34 : return KeyTable.XK_Page_Down;
case 45 : return KeyTable.XK_Insert;
case 37 : return XK_Left;
case 38 : return XK_Up;
case 39 : return XK_Right;
case 40 : return XK_Down;
case 37 : return KeyTable.XK_Left;
case 38 : return KeyTable.XK_Up;
case 39 : return KeyTable.XK_Right;
case 40 : return KeyTable.XK_Down;
case 16 : return XK_Shift_L;
case 17 : return XK_Control_L;
case 18 : return XK_Alt_L; // also: Option-key on Mac
case 16 : return KeyTable.XK_Shift_L;
case 17 : return KeyTable.XK_Control_L;
case 18 : return KeyTable.XK_Alt_L; // also: Option-key on Mac
case 224 : return XK_Meta_L;
case 225 : return XK_ISO_Level3_Shift; // AltGr
case 91 : return XK_Super_L; // also: Windows-key
case 92 : return XK_Super_R; // also: Windows-key
case 93 : return XK_Menu; // also: Windows-Menu, Command on Mac
case 224 : return KeyTable.XK_Meta_L;
case 225 : return KeyTable.XK_ISO_Level3_Shift; // AltGr
case 91 : return KeyTable.XK_Super_L; // also: Windows-key
case 92 : return KeyTable.XK_Super_R; // also: Windows-key
case 93 : return KeyTable.XK_Menu; // also: Windows-Menu, Command on Mac
default: return null;
}
}
return {
hasShortcutModifier : hasShortcutModifier,
hasCharModifier : hasCharModifier,
ModifierSync : ModifierSync,
getKey : getKey,
getKeysym : getKeysym,
keysymFromKeyCode : keysymFromKeyCode,
nonCharacterKey : nonCharacterKey,
substituteCodepoint : substituteCodepoint
};
KeyboardUtil.hasShortcutModifier = hasShortcutModifier;
KeyboardUtil.hasCharModifier = hasCharModifier;
KeyboardUtil.ModifierSync = ModifierSync;
KeyboardUtil.getKey = getKey;
KeyboardUtil.getKeysym = getKeysym;
KeyboardUtil.keysymFromKeyCode = keysymFromKeyCode;
KeyboardUtil.nonCharacterKey = nonCharacterKey;
KeyboardUtil.substituteCodepoint = substituteCodepoint;
})();
function QEMUKeyEventDecoder(modifierState, next) {
KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) {
"use strict";
function sendAll(evts) {
@ -331,7 +337,7 @@ function QEMUKeyEventDecoder(modifierState, next) {
var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier();
var isShift = evt.keyCode === 0x10 || evt.key === 'Shift';
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!kbdUtil.nonCharacterKey(evt));
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!KeyboardUtil.nonCharacterKey(evt));
next(result);
return suppress;
@ -353,9 +359,9 @@ function QEMUKeyEventDecoder(modifierState, next) {
},
releaseAll: function() { next({type: 'releaseall'}); }
};
}
};
function TrackQEMUKeyState(next) {
KeyboardUtil.TrackQEMUKeyState = function(next) {
"use strict";
var state = [];
@ -414,7 +420,7 @@ function TrackQEMUKeyState(next) {
state = [];
}
};
}
};
// Takes a DOM keyboard event and:
// - determines which keysym it represents
@ -423,7 +429,7 @@ function TrackQEMUKeyState(next) {
// - marks each event with an 'escape' property if a modifier was down which should be "escaped"
// - generates a "stall" event in cases where it might be necessary to wait and see if a keypress event follows a keydown
// This information is collected into an object which is passed to the next() function. (one call per event)
function KeyEventDecoder(modifierState, next) {
KeyboardUtil.KeyEventDecoder = function(modifierState, next) {
"use strict";
function sendAll(evts) {
for (var i = 0; i < evts.length; ++i) {
@ -432,18 +438,18 @@ function KeyEventDecoder(modifierState, next) {
}
function process(evt, type) {
var result = {type: type};
var keyId = kbdUtil.getKey(evt);
var keyId = KeyboardUtil.getKey(evt);
if (keyId) {
result.keyId = keyId;
}
var keysym = kbdUtil.getKeysym(evt);
var keysym = KeyboardUtil.getKeysym(evt);
var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier();
// Is this a case where we have to decide on the keysym right away, rather than waiting for the keypress?
// "special" keys like enter, tab or backspace don't send keypress events,
// and some browsers don't send keypresses at all if a modifier is down
if (keysym && (type !== 'keydown' || kbdUtil.nonCharacterKey(evt) || hasModifier)) {
if (keysym && (type !== 'keydown' || KeyboardUtil.nonCharacterKey(evt) || hasModifier)) {
result.keysym = keysym;
}
@ -452,11 +458,11 @@ function KeyEventDecoder(modifierState, next) {
// Should we prevent the browser from handling the event?
// Doing so on a keydown (in most browsers) prevents keypress from being generated
// so only do that if we have to.
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!kbdUtil.nonCharacterKey(evt));
var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!KeyboardUtil.nonCharacterKey(evt));
// If a char modifier is down on a keydown, we need to insert a stall,
// so VerifyCharModifier knows to wait and see if a keypress is comnig
var stall = type === 'keydown' && modifierState.activeCharModifier() && !kbdUtil.nonCharacterKey(evt);
var stall = type === 'keydown' && modifierState.activeCharModifier() && !KeyboardUtil.nonCharacterKey(evt);
// if a char modifier is pressed, get the keys it consists of (on Windows, AltGr is equivalent to Ctrl+Alt)
var active = modifierState.activeCharModifier();
@ -502,7 +508,7 @@ function KeyEventDecoder(modifierState, next) {
},
releaseAll: function() { next({type: 'releaseall'}); }
};
}
};
// Combines keydown and keypress events where necessary to handle char modifiers.
// On some OS'es, a char modifier is sometimes used as a shortcut modifier.
@ -510,7 +516,7 @@ function KeyEventDecoder(modifierState, next) {
// so when used with the '2' key, Ctrl-Alt counts as a char modifier (and should be escaped), but when used with 'D', it does not.
// The only way we can distinguish these cases is to wait and see if a keypress event arrives
// When we receive a "stall" event, wait a few ms before processing the next keydown. If a keypress has also arrived, merge the two
function VerifyCharModifier(next) {
KeyboardUtil.VerifyCharModifier = function(next) {
"use strict";
var queue = [];
var timer = null;
@ -560,14 +566,14 @@ function VerifyCharModifier(next) {
queue.push(evt);
process();
};
}
};
// Keeps track of which keys we (and the server) believe are down
// When a keyup is received, match it against this list, to determine the corresponding keysym(s)
// in some cases, a single key may produce multiple keysyms, so the corresponding keyup event must release all of these chars
// key repeat events should be merged into a single entry.
// Because we can't always identify which entry a keydown or keyup event corresponds to, we sometimes have to guess
function TrackKeyState(next) {
KeyboardUtil.TrackKeyState = function(next) {
"use strict";
var state = [];
@ -647,11 +653,11 @@ function TrackKeyState(next) {
state = [];
}
};
}
};
// Handles "escaping" of modifiers: if a char modifier is used to produce a keysym (such as AltGr-2 to generate an @),
// then the modifier must be "undone" before sending the @, and "redone" afterwards.
function EscapeModifiers(next) {
KeyboardUtil.EscapeModifiers = function(next) {
"use strict";
return function(evt) {
if (evt.type !== 'keydown' || evt.escape === undefined) {
@ -671,4 +677,6 @@ function EscapeModifiers(next) {
}
/* jshint shadow: false */
};
}
};
/* [module] export default KeyboardUtil; */

149
core/input/xtscancodes.js Normal file
View File

@ -0,0 +1,149 @@
var XtScancode = {
"Escape": 0x0001,
"Digit1": 0x0002,
"Digit2": 0x0003,
"Digit3": 0x0004,
"Digit4": 0x0005,
"Digit5": 0x0006,
"Digit6": 0x0007,
"Digit7": 0x0008,
"Digit8": 0x0009,
"Digit9": 0x000A,
"Digit0": 0x000B,
"Minus": 0x000C,
"Equal": 0x000D,
"Backspace": 0x000E,
"Tab": 0x000F,
"KeyQ": 0x0010,
"KeyW": 0x0011,
"KeyE": 0x0012,
"KeyR": 0x0013,
"KeyT": 0x0014,
"KeyY": 0x0015,
"KeyU": 0x0016,
"KeyI": 0x0017,
"KeyO": 0x0018,
"KeyP": 0x0019,
"BracketLeft": 0x001A,
"BracketRight": 0x001B,
"Enter": 0x001C,
"ControlLeft": 0x001D,
"KeyA": 0x001E,
"KeyS": 0x001F,
"KeyD": 0x0020,
"KeyF": 0x0021,
"KeyG": 0x0022,
"KeyH": 0x0023,
"KeyJ": 0x0024,
"KeyK": 0x0025,
"KeyL": 0x0026,
"Semicolon": 0x0027,
"Quote": 0x0028,
"Backquote": 0x0029,
"ShiftLeft": 0x002A,
"Backslash": 0x002B,
"KeyZ": 0x002C,
"KeyX": 0x002D,
"KeyC": 0x002E,
"KeyV": 0x002F,
"KeyB": 0x0030,
"KeyN": 0x0031,
"KeyM": 0x0032,
"Comma": 0x0033,
"Period": 0x0034,
"Slash": 0x0035,
"ShiftRight": 0x0036,
"NumpadMultiply": 0x0037,
"AltLeft": 0x0038,
"Space": 0x0039,
"CapsLock": 0x003A,
"F1": 0x003B,
"F2": 0x003C,
"F3": 0x003D,
"F4": 0x003E,
"F5": 0x003F,
"F6": 0x0040,
"F7": 0x0041,
"F8": 0x0042,
"F9": 0x0043,
"F10": 0x0044,
"Pause": 0xE045,
"ScrollLock": 0x0046,
"Numpad7": 0x0047,
"Numpad8": 0x0048,
"Numpad9": 0x0049,
"NumpadSubtract": 0x004A,
"Numpad4": 0x004B,
"Numpad5": 0x004C,
"Numpad6": 0x004D,
"NumpadAdd": 0x004E,
"Numpad1": 0x004F,
"Numpad2": 0x0050,
"Numpad3": 0x0051,
"Numpad0": 0x0052,
"NumpadDecimal": 0x0053,
"IntlBackslash": 0x0056,
"F11": 0x0057,
"F12": 0x0058,
"IntlYen": 0x007D,
"MediaTrackPrevious": 0xE010,
"MediaTrackNext": 0xE019,
"NumpadEnter": 0xE01C,
"ControlRight": 0xE01D,
"VolumeMute": 0xE020,
"MediaPlayPause": 0xE022,
"MediaStop": 0xE024,
"VolumeDown": 0xE02E,
"VolumeUp": 0xE030,
"BrowserHome": 0xE032,
"NumpadDivide": 0xE035,
"PrintScreen": 0xE037,
"AltRight": 0xE038,
"NumLock": 0x0045,
"Home": 0xE047,
"ArrowUp": 0xE048,
"PageUp": 0xE049,
"ArrowLeft": 0xE04B,
"ArrowRight": 0xE04D,
"End": 0xE04F,
"ArrowDown": 0xE050,
"PageDown": 0xE051,
"Insert": 0xE052,
"Delete": 0xE053,
"OSLeft": 0xE05B,
"OSRight": 0xE05C,
"ContextMenu": 0xE05D,
"BrowserSearch": 0xE065,
"BrowserFavorites": 0xE066,
"BrowserRefresh": 0xE067,
"BrowserStop": 0xE068,
"BrowserForward": 0xE069,
"BrowserBack": 0xE06A,
"NumpadComma": 0x007E,
"NumpadEqual": 0x0059,
"F13": 0x0064,
"F14": 0x0065,
"F15": 0x0066,
"F16": 0x0067,
"F17": 0x0068,
"F18": 0x0069,
"F19": 0x006A,
"F20": 0x006B,
"F21": 0x006C,
"F22": 0x006D,
"F23": 0x006E,
"F24": 0x0076,
"KanaMode": 0x0070,
"Lang2": 0x0071,
"Lang1": 0x0072,
"IntlRo": 0x0073,
"Convert": 0x0079,
"NonConvert": 0x007B,
"LaunchApp2": 0xE021,
"Power": 0xE05E,
"LaunchApp1": 0xE06B,
"LaunchMail": 0xE06C,
"MediaSelect": 0xE06D,
};
/* [module] export default XtScancode */

View File

@ -10,236 +10,240 @@
* (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca)
*/
/* [module]
* import Util from "./util";
* import Display from "./display";
* import { Keyboard, Mouse } from "./input/devices"
* import Websock from "./websock"
* import Base64 from "./base64";
* import DES from "./des";
* import KeyTable from "./input/keysym";
* import XtScancode from "./input/xtscancodes";
* import Inflator from "./inflator.mod";
*/
/*jslint white: false, browser: true */
/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES */
/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, KeyTable, Inflator, XtScancode */
var RFB;
(function () {
/* [module] export default */ function RFB(defaults) {
"use strict";
RFB = function (defaults) {
if (!defaults) {
defaults = {};
}
if (!defaults) {
defaults = {};
}
this._rfb_host = '';
this._rfb_port = 5900;
this._rfb_password = '';
this._rfb_path = '';
this._rfb_host = '';
this._rfb_port = 5900;
this._rfb_password = '';
this._rfb_path = '';
this._rfb_state = 'disconnected';
this._rfb_version = 0;
this._rfb_max_version = 3.8;
this._rfb_auth_scheme = '';
this._rfb_state = 'disconnected';
this._rfb_version = 0;
this._rfb_max_version = 3.8;
this._rfb_auth_scheme = '';
this._rfb_tightvnc = false;
this._rfb_xvp_ver = 0;
this._rfb_tightvnc = false;
this._rfb_xvp_ver = 0;
// In preference order
this._encodings = [
['COPYRECT', 0x01 ],
['TIGHT', 0x07 ],
['TIGHT_PNG', -260 ],
['HEXTILE', 0x05 ],
['RRE', 0x02 ],
['RAW', 0x00 ],
// In preference order
this._encodings = [
['COPYRECT', 0x01 ],
['TIGHT', 0x07 ],
['TIGHT_PNG', -260 ],
['HEXTILE', 0x05 ],
['RRE', 0x02 ],
['RAW', 0x00 ],
// Psuedo-encoding settings
// Psuedo-encoding settings
//['JPEG_quality_lo', -32 ],
['JPEG_quality_med', -26 ],
//['JPEG_quality_hi', -23 ],
//['compress_lo', -255 ],
['compress_hi', -247 ],
//['JPEG_quality_lo', -32 ],
['JPEG_quality_med', -26 ],
//['JPEG_quality_hi', -23 ],
//['compress_lo', -255 ],
['compress_hi', -247 ],
['DesktopSize', -223 ],
['last_rect', -224 ],
['Cursor', -239 ],
['QEMUExtendedKeyEvent', -258 ],
['ExtendedDesktopSize', -308 ],
['xvp', -309 ],
['Fence', -312 ],
['ContinuousUpdates', -313 ]
];
['DesktopSize', -223 ],
['last_rect', -224 ],
['Cursor', -239 ],
['QEMUExtendedKeyEvent', -258 ],
['ExtendedDesktopSize', -308 ],
['xvp', -309 ],
['Fence', -312 ],
['ContinuousUpdates', -313 ]
];
this._encHandlers = {};
this._encNames = {};
this._encStats = {};
this._encHandlers = {};
this._encNames = {};
this._encStats = {};
this._sock = null; // Websock object
this._display = null; // Display object
this._keyboard = null; // Keyboard input handler object
this._mouse = null; // Mouse input handler object
this._disconnTimer = null; // disconnection timer
this._msgTimer = null; // queued handle_msg timer
this._sock = null; // Websock object
this._display = null; // Display object
this._keyboard = null; // Keyboard input handler object
this._mouse = null; // Mouse input handler object
this._disconnTimer = null; // disconnection timer
this._msgTimer = null; // queued handle_msg timer
this._supportsFence = false;
this._supportsFence = false;
this._supportsContinuousUpdates = false;
this._enabledContinuousUpdates = false;
this._supportsContinuousUpdates = false;
this._enabledContinuousUpdates = false;
// Frame buffer update state
this._FBU = {
rects: 0,
subrects: 0, // RRE
lines: 0, // RAW
tiles: 0, // HEXTILE
bytes: 0,
x: 0,
y: 0,
width: 0,
height: 0,
encoding: 0,
subencoding: -1,
background: null,
zlib: [] // TIGHT zlib streams
};
this._fb_Bpp = 4;
this._fb_depth = 3;
this._fb_width = 0;
this._fb_height = 0;
this._fb_name = "";
this._destBuff = null;
this._paletteBuff = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel)
this._rre_chunk_sz = 100;
this._timing = {
last_fbu: 0,
fbu_total: 0,
fbu_total_cnt: 0,
full_fbu_total: 0,
full_fbu_cnt: 0,
fbu_rt_start: 0,
fbu_rt_total: 0,
fbu_rt_cnt: 0,
pixels: 0
};
this._supportsSetDesktopSize = false;
this._screen_id = 0;
this._screen_flags = 0;
// Mouse state
this._mouse_buttonMask = 0;
this._mouse_arr = [];
this._viewportDragging = false;
this._viewportDragPos = {};
this._viewportHasMoved = false;
// QEMU Extended Key Event support - default to false
this._qemuExtKeyEventSupported = false;
// set the default value on user-facing properties
Util.set_defaults(this, defaults, {
'target': 'null', // VNC display rendering Canvas object
'focusContainer': document, // DOM element that captures keyboard input
'encrypt': false, // Use TLS/SSL/wss encryption
'true_color': true, // Request true color pixel data
'local_cursor': false, // Request locally rendered cursor
'shared': true, // Request shared mode
'view_only': false, // Disable client mouse/keyboard
'xvp_password_sep': '@', // Separator for XVP password fields
'disconnectTimeout': 3, // Time (s) to wait for disconnection
'wsProtocols': ['binary'], // Protocols to use in the WebSocket connection
'repeaterID': '', // [UltraVNC] RepeaterID to connect to
'viewportDrag': false, // Move the viewport on mouse drags
// Callback functions
'onUpdateState': function () { }, // onUpdateState(rfb, state, oldstate, statusMsg): state update/change
'onPasswordRequired': function () { }, // onPasswordRequired(rfb): VNC password is required
'onClipboard': function () { }, // onClipboard(rfb, text): RFB clipboard contents received
'onBell': function () { }, // onBell(rfb): RFB Bell message received
'onFBUReceive': function () { }, // onFBUReceive(rfb, fbu): RFB FBU received but not yet processed
'onFBUComplete': function () { }, // onFBUComplete(rfb, fbu): RFB FBU received and processed
'onFBResize': function () { }, // onFBResize(rfb, width, height): frame buffer resized
'onDesktopName': function () { }, // onDesktopName(rfb, name): desktop name received
'onXvpInit': function () { } // onXvpInit(version): XVP extensions active for this connection
});
// main setup
Util.Debug(">> RFB.constructor");
// populate encHandlers with bound versions
Object.keys(RFB.encodingHandlers).forEach(function (encName) {
this._encHandlers[encName] = RFB.encodingHandlers[encName].bind(this);
}.bind(this));
// Create lookup tables based on encoding number
for (var i = 0; i < this._encodings.length; i++) {
this._encHandlers[this._encodings[i][1]] = this._encHandlers[this._encodings[i][0]];
this._encNames[this._encodings[i][1]] = this._encodings[i][0];
this._encStats[this._encodings[i][1]] = [0, 0];
}
// NB: nothing that needs explicit teardown should be done
// before this point, since this can throw an exception
try {
this._display = new Display({target: this._target});
} catch (exc) {
Util.Error("Display exception: " + exc);
throw exc;
}
this._keyboard = new Keyboard({target: this._focusContainer,
onKeyPress: this._handleKeyPress.bind(this)});
this._mouse = new Mouse({target: this._target,
onMouseButton: this._handleMouseButton.bind(this),
onMouseMove: this._handleMouseMove.bind(this),
notify: this._keyboard.sync.bind(this._keyboard)});
this._sock = new Websock();
this._sock.on('message', this._handle_message.bind(this));
this._sock.on('open', function () {
if (this._rfb_state === 'connect') {
this._updateState('ProtocolVersion', "Starting VNC handshake");
} else {
this._fail("Got unexpected WebSocket connection");
}
}.bind(this));
this._sock.on('close', function (e) {
Util.Warn("WebSocket on-close event");
var msg = "";
if (e.code) {
msg = " (code: " + e.code;
if (e.reason) {
msg += ", reason: " + e.reason;
}
msg += ")";
}
if (this._rfb_state === 'disconnect') {
this._updateState('disconnected', 'VNC disconnected' + msg);
} else if (this._rfb_state === 'ProtocolVersion') {
this._fail('Failed to connect to server' + msg);
} else if (this._rfb_state in {'failed': 1, 'disconnected': 1}) {
Util.Error("Received onclose while disconnected" + msg);
} else {
this._fail("Server disconnected" + msg);
}
this._sock.off('close');
}.bind(this));
this._sock.on('error', function (e) {
Util.Warn("WebSocket on-error event");
});
this._init_vars();
var rmode = this._display.get_render_mode();
if (Websock_native) {
Util.Info("Using native WebSockets");
this._updateState('loaded', 'noVNC ready: native WebSockets, ' + rmode);
} else {
this._cleanupSocket('fatal');
throw new Error("WebSocket support is required to use noVNC");
}
Util.Debug("<< RFB.constructor");
// Frame buffer update state
this._FBU = {
rects: 0,
subrects: 0, // RRE
lines: 0, // RAW
tiles: 0, // HEXTILE
bytes: 0,
x: 0,
y: 0,
width: 0,
height: 0,
encoding: 0,
subencoding: -1,
background: null,
zlib: [] // TIGHT zlib streams
};
this._fb_Bpp = 4;
this._fb_depth = 3;
this._fb_width = 0;
this._fb_height = 0;
this._fb_name = "";
this._destBuff = null;
this._paletteBuff = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel)
this._rre_chunk_sz = 100;
this._timing = {
last_fbu: 0,
fbu_total: 0,
fbu_total_cnt: 0,
full_fbu_total: 0,
full_fbu_cnt: 0,
fbu_rt_start: 0,
fbu_rt_total: 0,
fbu_rt_cnt: 0,
pixels: 0
};
this._supportsSetDesktopSize = false;
this._screen_id = 0;
this._screen_flags = 0;
// Mouse state
this._mouse_buttonMask = 0;
this._mouse_arr = [];
this._viewportDragging = false;
this._viewportDragPos = {};
this._viewportHasMoved = false;
// QEMU Extended Key Event support - default to false
this._qemuExtKeyEventSupported = false;
// set the default value on user-facing properties
Util.set_defaults(this, defaults, {
'target': 'null', // VNC display rendering Canvas object
'focusContainer': document, // DOM element that captures keyboard input
'encrypt': false, // Use TLS/SSL/wss encryption
'true_color': true, // Request true color pixel data
'local_cursor': false, // Request locally rendered cursor
'shared': true, // Request shared mode
'view_only': false, // Disable client mouse/keyboard
'xvp_password_sep': '@', // Separator for XVP password fields
'disconnectTimeout': 3, // Time (s) to wait for disconnection
'wsProtocols': ['binary'], // Protocols to use in the WebSocket connection
'repeaterID': '', // [UltraVNC] RepeaterID to connect to
'viewportDrag': false, // Move the viewport on mouse drags
// Callback functions
'onUpdateState': function () { }, // onUpdateState(rfb, state, oldstate, statusMsg): state update/change
'onPasswordRequired': function () { }, // onPasswordRequired(rfb): VNC password is required
'onClipboard': function () { }, // onClipboard(rfb, text): RFB clipboard contents received
'onBell': function () { }, // onBell(rfb): RFB Bell message received
'onFBUReceive': function () { }, // onFBUReceive(rfb, fbu): RFB FBU received but not yet processed
'onFBUComplete': function () { }, // onFBUComplete(rfb, fbu): RFB FBU received and processed
'onFBResize': function () { }, // onFBResize(rfb, width, height): frame buffer resized
'onDesktopName': function () { }, // onDesktopName(rfb, name): desktop name received
'onXvpInit': function () { } // onXvpInit(version): XVP extensions active for this connection
});
// main setup
Util.Debug(">> RFB.constructor");
// populate encHandlers with bound versions
Object.keys(RFB.encodingHandlers).forEach(function (encName) {
this._encHandlers[encName] = RFB.encodingHandlers[encName].bind(this);
}.bind(this));
// Create lookup tables based on encoding number
for (var i = 0; i < this._encodings.length; i++) {
this._encHandlers[this._encodings[i][1]] = this._encHandlers[this._encodings[i][0]];
this._encNames[this._encodings[i][1]] = this._encodings[i][0];
this._encStats[this._encodings[i][1]] = [0, 0];
}
// NB: nothing that needs explicit teardown should be done
// before this point, since this can throw an exception
try {
this._display = new Display({target: this._target});
} catch (exc) {
Util.Error("Display exception: " + exc);
throw exc;
}
this._keyboard = new Keyboard({target: this._focusContainer,
onKeyPress: this._handleKeyPress.bind(this)});
this._mouse = new Mouse({target: this._target,
onMouseButton: this._handleMouseButton.bind(this),
onMouseMove: this._handleMouseMove.bind(this),
notify: this._keyboard.sync.bind(this._keyboard)});
this._sock = new Websock();
this._sock.on('message', this._handle_message.bind(this));
this._sock.on('open', function () {
if (this._rfb_state === 'connect') {
this._updateState('ProtocolVersion', "Starting VNC handshake");
} else {
this._fail("Got unexpected WebSocket connection");
}
}.bind(this));
this._sock.on('close', function (e) {
Util.Warn("WebSocket on-close event");
var msg = "";
if (e.code) {
msg = " (code: " + e.code;
if (e.reason) {
msg += ", reason: " + e.reason;
}
msg += ")";
}
if (this._rfb_state === 'disconnect') {
this._updateState('disconnected', 'VNC disconnected' + msg);
} else if (this._rfb_state === 'ProtocolVersion') {
this._fail('Failed to connect to server' + msg);
} else if (this._rfb_state in {'failed': 1, 'disconnected': 1}) {
Util.Error("Received onclose while disconnected" + msg);
} else {
this._fail("Server disconnected" + msg);
}
this._sock.off('close');
}.bind(this));
this._sock.on('error', function (e) {
Util.Warn("WebSocket on-error event");
});
this._init_vars();
var rmode = this._display.get_render_mode();
Util.Info("Using native WebSockets");
this._updateState('loaded', 'noVNC ready: native WebSockets, ' + rmode);
Util.Debug("<< RFB.constructor");
};
(function() {
RFB.prototype = {
// Public methods
connect: function (host, port, password, path) {
@ -273,12 +277,12 @@ var RFB;
if (this._rfb_state !== 'normal' || this._view_only) { return false; }
Util.Info("Sending Ctrl-Alt-Del");
RFB.messages.keyEvent(this._sock, XK_Control_L, 1);
RFB.messages.keyEvent(this._sock, XK_Alt_L, 1);
RFB.messages.keyEvent(this._sock, XK_Delete, 1);
RFB.messages.keyEvent(this._sock, XK_Delete, 0);
RFB.messages.keyEvent(this._sock, XK_Alt_L, 0);
RFB.messages.keyEvent(this._sock, XK_Control_L, 0);
RFB.messages.keyEvent(this._sock, KeyTable.XK_Control_L, 1);
RFB.messages.keyEvent(this._sock, KeyTable.XK_Alt_L, 1);
RFB.messages.keyEvent(this._sock, KeyTable.XK_Delete, 1);
RFB.messages.keyEvent(this._sock, KeyTable.XK_Delete, 0);
RFB.messages.keyEvent(this._sock, KeyTable.XK_Alt_L, 0);
RFB.messages.keyEvent(this._sock, KeyTable.XK_Control_L, 0);
return true;
},
@ -372,7 +376,7 @@ var RFB;
}
for (i = 0; i < 4; i++) {
this._FBU.zlibs[i] = new inflator.Inflate();
this._FBU.zlibs[i] = new Inflator.Inflate();
}
},

View File

@ -9,170 +9,8 @@
/* jshint white: false, nonstandard: true */
/*global window, console, document, navigator, ActiveXObject, INCLUDE_URI */
// Globals defined here
var Util = {};
/*
* Make arrays quack
*/
var addFunc = function (cl, name, func) {
if (!cl.prototype[name]) {
Object.defineProperty(cl.prototype, name, { enumerable: false, value: func });
}
};
addFunc(Array, 'push8', function (num) {
"use strict";
this.push(num & 0xFF);
});
addFunc(Array, 'push16', function (num) {
"use strict";
this.push((num >> 8) & 0xFF,
num & 0xFF);
});
addFunc(Array, 'push32', function (num) {
"use strict";
this.push((num >> 24) & 0xFF,
(num >> 16) & 0xFF,
(num >> 8) & 0xFF,
num & 0xFF);
});
// IE does not support map (even in IE9)
//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
addFunc(Array, 'map', function (fun /*, thisp*/) {
"use strict";
var len = this.length;
if (typeof fun != "function") {
throw new TypeError();
}
var res = new Array(len);
var thisp = arguments[1];
for (var i = 0; i < len; i++) {
if (i in this) {
res[i] = fun.call(thisp, this[i], i, this);
}
}
return res;
});
// IE <9 does not support indexOf
//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
addFunc(Array, 'indexOf', function (elt /*, from*/) {
"use strict";
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0) ? Math.ceil(from) : Math.floor(from);
if (from < 0) {
from += len;
}
for (; from < len; from++) {
if (from in this &&
this[from] === elt) {
return from;
}
}
return -1;
});
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
if (!Object.keys) {
Object.keys = (function () {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function (obj) {
if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
})();
}
// PhantomJS 1.x doesn't support bind,
// so leave this in until PhantomJS 2.0 is released
//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license
addFunc(Function, 'bind', function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError("Function.prototype.bind - " +
"what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis ? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
});
//
// requestAnimationFrame shim with setTimeout fallback
//
window.requestAnimFrame = (function () {
"use strict";
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
/*
* ------------------------------------------------------
* Namespaced in Util
@ -191,39 +29,26 @@ Util.init_logging = function (level) {
} else {
Util._log_level = 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) {};
/* jshint -W086 */
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); };
case 'none':
break;
default:
throw new Error("invalid logging type '" + level + "'");
if (typeof window.console !== "undefined") {
/* jshint -W086 */
switch (level) {
case 'debug':
Util.Debug = function (msg) { console.log(msg); };
case 'info':
Util.Info = function (msg) { console.info(msg); };
case 'warn':
Util.Warn = function (msg) { console.warn(msg); };
case 'error':
Util.Error = function (msg) { console.error(msg); };
case 'none':
break;
default:
throw new Error("invalid logging type '" + level + "'");
}
/* jshint +W086 */
}
/* jshint +W086 */
};
Util.get_logging = function () {
return Util._log_level;
@ -369,70 +194,6 @@ Util.decodeUTF8 = function (utf8string) {
* Cross-browser routines
*/
// Dynamically load scripts without using document.write()
// Reference: http://unixpapa.com/js/dyna.html
//
// Handles the case where load_scripts is invoked from a script that
// itself is loaded via load_scripts. Once all scripts are loaded the
// window.onscriptsloaded handler is called (if set).
Util.get_include_uri = function () {
return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI : "include/";
};
Util._loading_scripts = [];
Util._pending_scripts = [];
Util.load_scripts = function (files) {
"use strict";
var head = document.getElementsByTagName('head')[0], script,
ls = Util._loading_scripts, ps = Util._pending_scripts;
var loadFunc = function (e) {
while (ls.length > 0 && (ls[0].readyState === 'loaded' ||
ls[0].readyState === 'complete')) {
// For IE, append the script to trigger execution
var s = ls.shift();
//console.log("loaded script: " + s.src);
head.appendChild(s);
}
if (!this.readyState ||
(Util.Engine.presto && this.readyState === 'loaded') ||
this.readyState === 'complete') {
if (ps.indexOf(this) >= 0) {
this.onload = this.onreadystatechange = null;
//console.log("completed script: " + this.src);
ps.splice(ps.indexOf(this), 1);
// Call window.onscriptsload after last script loads
if (ps.length === 0 && window.onscriptsload) {
window.onscriptsload();
}
}
}
};
for (var f = 0; f < files.length; f++) {
script = document.createElement('script');
script.type = 'text/javascript';
script.src = Util.get_include_uri() + files[f];
//console.log("loading script: " + script.src);
script.onload = script.onreadystatechange = loadFunc;
// In-order script execution tricks
if (Util.Engine.trident) {
// For IE wait until readyState is 'loaded' before
// appending it which will trigger execution
// http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
ls.push(script);
} else {
// For webkit and firefox set async=false and append now
// https://developer.mozilla.org/en-US/docs/HTML/Element/script
script.async = false;
head.appendChild(script);
}
ps.push(script);
}
};
Util.getPosition = function(obj) {
"use strict";
// NB(sross): the Mozilla developer reference seems to indicate that
@ -471,41 +232,9 @@ Util.getEventPosition = function (e, obj, scale) {
return {'x': x / scale, 'y': y / scale, 'realx': realx / scale, 'realy': realy / scale};
};
// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events
Util.addEvent = function (obj, evType, fn) {
"use strict";
if (obj.attachEvent) {
var r = obj.attachEvent("on" + evType, fn);
return r;
} else if (obj.addEventListener) {
obj.addEventListener(evType, fn, false);
return true;
} else {
throw new Error("Handler could not be attached");
}
};
Util.removeEvent = function (obj, evType, fn) {
"use strict";
if (obj.detachEvent) {
var r = obj.detachEvent("on" + evType, fn);
return r;
} else if (obj.removeEventListener) {
obj.removeEventListener(evType, fn, false);
return true;
} else {
throw new Error("Handler could not be removed");
}
};
Util.stopEvent = function (e) {
"use strict";
if (e.stopPropagation) { e.stopPropagation(); }
else { e.cancelBubble = true; }
if (e.preventDefault) { e.preventDefault(); }
else { e.returnValue = false; }
e.stopPropagation();
e.preventDefault();
};
Util._cursor_uris_supported = null;
@ -620,3 +349,5 @@ Util.Flash = (function () {
version = v.match(/\d+/g);
return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
}());
/* [module] export default Util; */

View File

@ -14,29 +14,15 @@
* read binary data off of the receive queue.
*/
/* [module]
* import Util from "./util";
* import Base64 from "./base64";
*/
/*jslint browser: true, bitwise: true */
/*global Util*/
// Load Flash WebSocket emulator if needed
// To force WebSocket emulator even when native WebSocket available
//window.WEB_SOCKET_FORCE_FLASH = true;
// To enable WebSocket emulator debug:
//window.WEB_SOCKET_DEBUG=1;
if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) {
Websock_native = true;
} else if (window.MozWebSocket && !window.WEB_SOCKET_FORCE_FLASH) {
Websock_native = true;
window.WebSocket = window.MozWebSocket;
} else {
/* no builtin WebSocket so load web_socket.js */
Websock_native = false;
}
function Websock() {
/* [module] export default */ function Websock() {
"use strict";
this._websocket = null; // WebSocket object
@ -62,7 +48,7 @@ function Websock() {
'close': function () {},
'error': function () {}
};
}
};
(function () {
"use strict";

View File

@ -2,4 +2,4 @@ Rebuilding inflator.js
- Download pako from npm
- Install browserify using npm
- browserify utils/inflator.partial.js -o include/inflator.js -s inflator
- browserify core/inflator.mod.js -o core/inflator.js -s Inflator

View File

@ -1 +1 @@
images/favicon.ico
app/images/favicon.ico

View File

@ -1,321 +0,0 @@
/*
Copyright 2012 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Author: Boris Smus (smus@chromium.org)
*/
(function(exports) {
// Define some local variables here.
var socket = chrome.socket || chrome.experimental.socket;
var dns = chrome.experimental.dns;
/**
* Creates an instance of the client
*
* @param {String} host The remote host to connect to
* @param {Number} port The port to connect to at the remote host
*/
function TcpClient(host, port, pollInterval) {
this.host = host;
this.port = port;
this.pollInterval = pollInterval || 15;
// Callback functions.
this.callbacks = {
connect: null, // Called when socket is connected.
disconnect: null, // Called when socket is disconnected.
recvBuffer: null, // Called (as ArrayBuffer) when client receives data from server.
recvString: null, // Called (as string) when client receives data from server.
sent: null // Called when client sends data to server.
};
// Socket.
this.socketId = null;
this.isConnected = false;
log('initialized tcp client');
}
/**
* Connects to the TCP socket, and creates an open socket.
*
* @see http://developer.chrome.com/trunk/apps/socket.html#method-create
* @param {Function} callback The function to call on connection
*/
TcpClient.prototype.connect = function(callback) {
// First resolve the hostname to an IP.
dns.resolve(this.host, function(result) {
this.addr = result.address;
socket.create('tcp', {}, this._onCreate.bind(this));
// Register connect callback.
this.callbacks.connect = callback;
}.bind(this));
};
/**
* Sends an arraybuffer/view down the wire to the remote side
*
* @see http://developer.chrome.com/trunk/apps/socket.html#method-write
* @param {String} msg The arraybuffer/view to send
* @param {Function} callback The function to call when the message has sent
*/
TcpClient.prototype.sendBuffer = function(buf, callback) {
if (buf.buffer) {
buf = buf.buffer;
}
/*
// Debug
var bytes = [], u8 = new Uint8Array(buf);
for (var i = 0; i < u8.length; i++) {
bytes.push(u8[i]);
}
log("sending bytes: " + (bytes.join(',')));
*/
socket.write(this.socketId, buf, this._onWriteComplete.bind(this));
// Register sent callback.
this.callbacks.sent = callback;
};
/**
* Sends a string down the wire to the remote side
*
* @see http://developer.chrome.com/trunk/apps/socket.html#method-write
* @param {String} msg The string to send
* @param {Function} callback The function to call when the message has sent
*/
TcpClient.prototype.sendString = function(msg, callback) {
/*
// Debug
log("sending string: " + msg);
*/
this._stringToArrayBuffer(msg, function(arrayBuffer) {
socket.write(this.socketId, arrayBuffer, this._onWriteComplete.bind(this));
}.bind(this));
// Register sent callback.
this.callbacks.sent = callback;
};
/**
* Sets the callback for when a message is received
*
* @param {Function} callback The function to call when a message has arrived
* @param {String} type The callback argument type: "arraybuffer" or "string"
*/
TcpClient.prototype.addResponseListener = function(callback, type) {
if (typeof type === "undefined") {
type = "arraybuffer";
}
// Register received callback.
if (type === "string") {
this.callbacks.recvString = callback;
} else {
this.callbacks.recvBuffer = callback;
}
};
/**
* Sets the callback for when the socket disconnects
*
* @param {Function} callback The function to call when the socket disconnects
* @param {String} type The callback argument type: "arraybuffer" or "string"
*/
TcpClient.prototype.addDisconnectListener = function(callback) {
// Register disconnect callback.
this.callbacks.disconnect = callback;
};
/**
* Disconnects from the remote side
*
* @see http://developer.chrome.com/trunk/apps/socket.html#method-disconnect
*/
TcpClient.prototype.disconnect = function() {
if (this.isConnected) {
this.isConnected = false;
socket.disconnect(this.socketId);
if (this.callbacks.disconnect) {
this.callbacks.disconnect();
}
log('socket disconnected');
}
};
/**
* The callback function used for when we attempt to have Chrome
* create a socket. If the socket is successfully created
* we go ahead and connect to the remote side.
*
* @private
* @see http://developer.chrome.com/trunk/apps/socket.html#method-connect
* @param {Object} createInfo The socket details
*/
TcpClient.prototype._onCreate = function(createInfo) {
this.socketId = createInfo.socketId;
if (this.socketId > 0) {
socket.connect(this.socketId, this.addr, this.port, this._onConnectComplete.bind(this));
} else {
error('Unable to create socket');
}
};
/**
* The callback function used for when we attempt to have Chrome
* connect to the remote side. If a successful connection is
* made then polling starts to check for data to read
*
* @private
* @param {Number} resultCode Indicates whether the connection was successful
*/
TcpClient.prototype._onConnectComplete = function(resultCode) {
// Start polling for reads.
this.isConnected = true;
setTimeout(this._periodicallyRead.bind(this), this.pollInterval);
if (this.callbacks.connect) {
log('connect complete');
this.callbacks.connect();
}
log('onConnectComplete');
};
/**
* Checks for new data to read from the socket
*
* @see http://developer.chrome.com/trunk/apps/socket.html#method-read
*/
TcpClient.prototype._periodicallyRead = function() {
var that = this;
socket.getInfo(this.socketId, function (info) {
if (info.connected) {
setTimeout(that._periodicallyRead.bind(that), that.pollInterval);
socket.read(that.socketId, null, that._onDataRead.bind(that));
} else if (that.isConnected) {
log('socket disconnect detected');
that.disconnect();
}
});
};
/**
* Callback function for when data has been read from the socket.
* Converts the array buffer that is read in to a string
* and sends it on for further processing by passing it to
* the previously assigned callback function.
*
* @private
* @see TcpClient.prototype.addResponseListener
* @param {Object} readInfo The incoming message
*/
TcpClient.prototype._onDataRead = function(readInfo) {
// Call received callback if there's data in the response.
if (readInfo.resultCode > 0) {
log('onDataRead');
/*
// Debug
var bytes = [], u8 = new Uint8Array(readInfo.data);
for (var i = 0; i < u8.length; i++) {
bytes.push(u8[i]);
}
log("received bytes: " + (bytes.join(',')));
*/
if (this.callbacks.recvBuffer) {
// Return raw ArrayBuffer directly.
this.callbacks.recvBuffer(readInfo.data);
}
if (this.callbacks.recvString) {
// Convert ArrayBuffer to string.
this._arrayBufferToString(readInfo.data, function(str) {
this.callbacks.recvString(str);
}.bind(this));
}
// Trigger another read right away
setTimeout(this._periodicallyRead.bind(this), 0);
}
};
/**
* Callback for when data has been successfully
* written to the socket.
*
* @private
* @param {Object} writeInfo The outgoing message
*/
TcpClient.prototype._onWriteComplete = function(writeInfo) {
log('onWriteComplete');
// Call sent callback.
if (this.callbacks.sent) {
this.callbacks.sent(writeInfo);
}
};
/**
* Converts an array buffer to a string
*
* @private
* @param {ArrayBuffer} buf The buffer to convert
* @param {Function} callback The function to call when conversion is complete
*/
TcpClient.prototype._arrayBufferToString = function(buf, callback) {
var bb = new Blob([new Uint8Array(buf)]);
var f = new FileReader();
f.onload = function(e) {
callback(e.target.result);
};
f.readAsText(bb);
};
/**
* Converts a string to an array buffer
*
* @private
* @param {String} str The string to convert
* @param {Function} callback The function to call when conversion is complete
*/
TcpClient.prototype._stringToArrayBuffer = function(str, callback) {
var bb = new Blob([str]);
var f = new FileReader();
f.onload = function(e) {
callback(e.target.result);
};
f.readAsArrayBuffer(bb);
};
/**
* Wrapper function for logging
*/
function log(msg) {
console.log(msg);
}
/**
* Wrapper function for error logging
*/
function error(msg) {
console.error(msg);
}
exports.TcpClient = TcpClient;
})(window);

View File

@ -1,378 +0,0 @@
var XK_VoidSymbol = 0xffffff, /* Void symbol */
XK_BackSpace = 0xff08, /* Back space, back char */
XK_Tab = 0xff09,
XK_Linefeed = 0xff0a, /* Linefeed, LF */
XK_Clear = 0xff0b,
XK_Return = 0xff0d, /* Return, enter */
XK_Pause = 0xff13, /* Pause, hold */
XK_Scroll_Lock = 0xff14,
XK_Sys_Req = 0xff15,
XK_Escape = 0xff1b,
XK_Delete = 0xffff, /* Delete, rubout */
/* Cursor control & motion */
XK_Home = 0xff50,
XK_Left = 0xff51, /* Move left, left arrow */
XK_Up = 0xff52, /* Move up, up arrow */
XK_Right = 0xff53, /* Move right, right arrow */
XK_Down = 0xff54, /* Move down, down arrow */
XK_Prior = 0xff55, /* Prior, previous */
XK_Page_Up = 0xff55,
XK_Next = 0xff56, /* Next */
XK_Page_Down = 0xff56,
XK_End = 0xff57, /* EOL */
XK_Begin = 0xff58, /* BOL */
/* Misc functions */
XK_Select = 0xff60, /* Select, mark */
XK_Print = 0xff61,
XK_Execute = 0xff62, /* Execute, run, do */
XK_Insert = 0xff63, /* Insert, insert here */
XK_Undo = 0xff65,
XK_Redo = 0xff66, /* Redo, again */
XK_Menu = 0xff67,
XK_Find = 0xff68, /* Find, search */
XK_Cancel = 0xff69, /* Cancel, stop, abort, exit */
XK_Help = 0xff6a, /* Help */
XK_Break = 0xff6b,
XK_Mode_switch = 0xff7e, /* Character set switch */
XK_script_switch = 0xff7e, /* Alias for mode_switch */
XK_Num_Lock = 0xff7f,
/* Keypad functions, keypad numbers cleverly chosen to map to ASCII */
XK_KP_Space = 0xff80, /* Space */
XK_KP_Tab = 0xff89,
XK_KP_Enter = 0xff8d, /* Enter */
XK_KP_F1 = 0xff91, /* PF1, KP_A, ... */
XK_KP_F2 = 0xff92,
XK_KP_F3 = 0xff93,
XK_KP_F4 = 0xff94,
XK_KP_Home = 0xff95,
XK_KP_Left = 0xff96,
XK_KP_Up = 0xff97,
XK_KP_Right = 0xff98,
XK_KP_Down = 0xff99,
XK_KP_Prior = 0xff9a,
XK_KP_Page_Up = 0xff9a,
XK_KP_Next = 0xff9b,
XK_KP_Page_Down = 0xff9b,
XK_KP_End = 0xff9c,
XK_KP_Begin = 0xff9d,
XK_KP_Insert = 0xff9e,
XK_KP_Delete = 0xff9f,
XK_KP_Equal = 0xffbd, /* Equals */
XK_KP_Multiply = 0xffaa,
XK_KP_Add = 0xffab,
XK_KP_Separator = 0xffac, /* Separator, often comma */
XK_KP_Subtract = 0xffad,
XK_KP_Decimal = 0xffae,
XK_KP_Divide = 0xffaf,
XK_KP_0 = 0xffb0,
XK_KP_1 = 0xffb1,
XK_KP_2 = 0xffb2,
XK_KP_3 = 0xffb3,
XK_KP_4 = 0xffb4,
XK_KP_5 = 0xffb5,
XK_KP_6 = 0xffb6,
XK_KP_7 = 0xffb7,
XK_KP_8 = 0xffb8,
XK_KP_9 = 0xffb9,
/*
* Auxiliary functions; note the duplicate definitions for left and right
* function keys; Sun keyboards and a few other manufacturers have such
* function key groups on the left and/or right sides of the keyboard.
* We've not found a keyboard with more than 35 function keys total.
*/
XK_F1 = 0xffbe,
XK_F2 = 0xffbf,
XK_F3 = 0xffc0,
XK_F4 = 0xffc1,
XK_F5 = 0xffc2,
XK_F6 = 0xffc3,
XK_F7 = 0xffc4,
XK_F8 = 0xffc5,
XK_F9 = 0xffc6,
XK_F10 = 0xffc7,
XK_F11 = 0xffc8,
XK_L1 = 0xffc8,
XK_F12 = 0xffc9,
XK_L2 = 0xffc9,
XK_F13 = 0xffca,
XK_L3 = 0xffca,
XK_F14 = 0xffcb,
XK_L4 = 0xffcb,
XK_F15 = 0xffcc,
XK_L5 = 0xffcc,
XK_F16 = 0xffcd,
XK_L6 = 0xffcd,
XK_F17 = 0xffce,
XK_L7 = 0xffce,
XK_F18 = 0xffcf,
XK_L8 = 0xffcf,
XK_F19 = 0xffd0,
XK_L9 = 0xffd0,
XK_F20 = 0xffd1,
XK_L10 = 0xffd1,
XK_F21 = 0xffd2,
XK_R1 = 0xffd2,
XK_F22 = 0xffd3,
XK_R2 = 0xffd3,
XK_F23 = 0xffd4,
XK_R3 = 0xffd4,
XK_F24 = 0xffd5,
XK_R4 = 0xffd5,
XK_F25 = 0xffd6,
XK_R5 = 0xffd6,
XK_F26 = 0xffd7,
XK_R6 = 0xffd7,
XK_F27 = 0xffd8,
XK_R7 = 0xffd8,
XK_F28 = 0xffd9,
XK_R8 = 0xffd9,
XK_F29 = 0xffda,
XK_R9 = 0xffda,
XK_F30 = 0xffdb,
XK_R10 = 0xffdb,
XK_F31 = 0xffdc,
XK_R11 = 0xffdc,
XK_F32 = 0xffdd,
XK_R12 = 0xffdd,
XK_F33 = 0xffde,
XK_R13 = 0xffde,
XK_F34 = 0xffdf,
XK_R14 = 0xffdf,
XK_F35 = 0xffe0,
XK_R15 = 0xffe0,
/* Modifiers */
XK_Shift_L = 0xffe1, /* Left shift */
XK_Shift_R = 0xffe2, /* Right shift */
XK_Control_L = 0xffe3, /* Left control */
XK_Control_R = 0xffe4, /* Right control */
XK_Caps_Lock = 0xffe5, /* Caps lock */
XK_Shift_Lock = 0xffe6, /* Shift lock */
XK_Meta_L = 0xffe7, /* Left meta */
XK_Meta_R = 0xffe8, /* Right meta */
XK_Alt_L = 0xffe9, /* Left alt */
XK_Alt_R = 0xffea, /* Right alt */
XK_Super_L = 0xffeb, /* Left super */
XK_Super_R = 0xffec, /* Right super */
XK_Hyper_L = 0xffed, /* Left hyper */
XK_Hyper_R = 0xffee, /* Right hyper */
XK_ISO_Level3_Shift = 0xfe03, /* AltGr */
/*
* Latin 1
* (ISO/IEC 8859-1 = Unicode U+0020..U+00FF)
* Byte 3 = 0
*/
XK_space = 0x0020, /* U+0020 SPACE */
XK_exclam = 0x0021, /* U+0021 EXCLAMATION MARK */
XK_quotedbl = 0x0022, /* U+0022 QUOTATION MARK */
XK_numbersign = 0x0023, /* U+0023 NUMBER SIGN */
XK_dollar = 0x0024, /* U+0024 DOLLAR SIGN */
XK_percent = 0x0025, /* U+0025 PERCENT SIGN */
XK_ampersand = 0x0026, /* U+0026 AMPERSAND */
XK_apostrophe = 0x0027, /* U+0027 APOSTROPHE */
XK_quoteright = 0x0027, /* deprecated */
XK_parenleft = 0x0028, /* U+0028 LEFT PARENTHESIS */
XK_parenright = 0x0029, /* U+0029 RIGHT PARENTHESIS */
XK_asterisk = 0x002a, /* U+002A ASTERISK */
XK_plus = 0x002b, /* U+002B PLUS SIGN */
XK_comma = 0x002c, /* U+002C COMMA */
XK_minus = 0x002d, /* U+002D HYPHEN-MINUS */
XK_period = 0x002e, /* U+002E FULL STOP */
XK_slash = 0x002f, /* U+002F SOLIDUS */
XK_0 = 0x0030, /* U+0030 DIGIT ZERO */
XK_1 = 0x0031, /* U+0031 DIGIT ONE */
XK_2 = 0x0032, /* U+0032 DIGIT TWO */
XK_3 = 0x0033, /* U+0033 DIGIT THREE */
XK_4 = 0x0034, /* U+0034 DIGIT FOUR */
XK_5 = 0x0035, /* U+0035 DIGIT FIVE */
XK_6 = 0x0036, /* U+0036 DIGIT SIX */
XK_7 = 0x0037, /* U+0037 DIGIT SEVEN */
XK_8 = 0x0038, /* U+0038 DIGIT EIGHT */
XK_9 = 0x0039, /* U+0039 DIGIT NINE */
XK_colon = 0x003a, /* U+003A COLON */
XK_semicolon = 0x003b, /* U+003B SEMICOLON */
XK_less = 0x003c, /* U+003C LESS-THAN SIGN */
XK_equal = 0x003d, /* U+003D EQUALS SIGN */
XK_greater = 0x003e, /* U+003E GREATER-THAN SIGN */
XK_question = 0x003f, /* U+003F QUESTION MARK */
XK_at = 0x0040, /* U+0040 COMMERCIAL AT */
XK_A = 0x0041, /* U+0041 LATIN CAPITAL LETTER A */
XK_B = 0x0042, /* U+0042 LATIN CAPITAL LETTER B */
XK_C = 0x0043, /* U+0043 LATIN CAPITAL LETTER C */
XK_D = 0x0044, /* U+0044 LATIN CAPITAL LETTER D */
XK_E = 0x0045, /* U+0045 LATIN CAPITAL LETTER E */
XK_F = 0x0046, /* U+0046 LATIN CAPITAL LETTER F */
XK_G = 0x0047, /* U+0047 LATIN CAPITAL LETTER G */
XK_H = 0x0048, /* U+0048 LATIN CAPITAL LETTER H */
XK_I = 0x0049, /* U+0049 LATIN CAPITAL LETTER I */
XK_J = 0x004a, /* U+004A LATIN CAPITAL LETTER J */
XK_K = 0x004b, /* U+004B LATIN CAPITAL LETTER K */
XK_L = 0x004c, /* U+004C LATIN CAPITAL LETTER L */
XK_M = 0x004d, /* U+004D LATIN CAPITAL LETTER M */
XK_N = 0x004e, /* U+004E LATIN CAPITAL LETTER N */
XK_O = 0x004f, /* U+004F LATIN CAPITAL LETTER O */
XK_P = 0x0050, /* U+0050 LATIN CAPITAL LETTER P */
XK_Q = 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */
XK_R = 0x0052, /* U+0052 LATIN CAPITAL LETTER R */
XK_S = 0x0053, /* U+0053 LATIN CAPITAL LETTER S */
XK_T = 0x0054, /* U+0054 LATIN CAPITAL LETTER T */
XK_U = 0x0055, /* U+0055 LATIN CAPITAL LETTER U */
XK_V = 0x0056, /* U+0056 LATIN CAPITAL LETTER V */
XK_W = 0x0057, /* U+0057 LATIN CAPITAL LETTER W */
XK_X = 0x0058, /* U+0058 LATIN CAPITAL LETTER X */
XK_Y = 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */
XK_Z = 0x005a, /* U+005A LATIN CAPITAL LETTER Z */
XK_bracketleft = 0x005b, /* U+005B LEFT SQUARE BRACKET */
XK_backslash = 0x005c, /* U+005C REVERSE SOLIDUS */
XK_bracketright = 0x005d, /* U+005D RIGHT SQUARE BRACKET */
XK_asciicircum = 0x005e, /* U+005E CIRCUMFLEX ACCENT */
XK_underscore = 0x005f, /* U+005F LOW LINE */
XK_grave = 0x0060, /* U+0060 GRAVE ACCENT */
XK_quoteleft = 0x0060, /* deprecated */
XK_a = 0x0061, /* U+0061 LATIN SMALL LETTER A */
XK_b = 0x0062, /* U+0062 LATIN SMALL LETTER B */
XK_c = 0x0063, /* U+0063 LATIN SMALL LETTER C */
XK_d = 0x0064, /* U+0064 LATIN SMALL LETTER D */
XK_e = 0x0065, /* U+0065 LATIN SMALL LETTER E */
XK_f = 0x0066, /* U+0066 LATIN SMALL LETTER F */
XK_g = 0x0067, /* U+0067 LATIN SMALL LETTER G */
XK_h = 0x0068, /* U+0068 LATIN SMALL LETTER H */
XK_i = 0x0069, /* U+0069 LATIN SMALL LETTER I */
XK_j = 0x006a, /* U+006A LATIN SMALL LETTER J */
XK_k = 0x006b, /* U+006B LATIN SMALL LETTER K */
XK_l = 0x006c, /* U+006C LATIN SMALL LETTER L */
XK_m = 0x006d, /* U+006D LATIN SMALL LETTER M */
XK_n = 0x006e, /* U+006E LATIN SMALL LETTER N */
XK_o = 0x006f, /* U+006F LATIN SMALL LETTER O */
XK_p = 0x0070, /* U+0070 LATIN SMALL LETTER P */
XK_q = 0x0071, /* U+0071 LATIN SMALL LETTER Q */
XK_r = 0x0072, /* U+0072 LATIN SMALL LETTER R */
XK_s = 0x0073, /* U+0073 LATIN SMALL LETTER S */
XK_t = 0x0074, /* U+0074 LATIN SMALL LETTER T */
XK_u = 0x0075, /* U+0075 LATIN SMALL LETTER U */
XK_v = 0x0076, /* U+0076 LATIN SMALL LETTER V */
XK_w = 0x0077, /* U+0077 LATIN SMALL LETTER W */
XK_x = 0x0078, /* U+0078 LATIN SMALL LETTER X */
XK_y = 0x0079, /* U+0079 LATIN SMALL LETTER Y */
XK_z = 0x007a, /* U+007A LATIN SMALL LETTER Z */
XK_braceleft = 0x007b, /* U+007B LEFT CURLY BRACKET */
XK_bar = 0x007c, /* U+007C VERTICAL LINE */
XK_braceright = 0x007d, /* U+007D RIGHT CURLY BRACKET */
XK_asciitilde = 0x007e, /* U+007E TILDE */
XK_nobreakspace = 0x00a0, /* U+00A0 NO-BREAK SPACE */
XK_exclamdown = 0x00a1, /* U+00A1 INVERTED EXCLAMATION MARK */
XK_cent = 0x00a2, /* U+00A2 CENT SIGN */
XK_sterling = 0x00a3, /* U+00A3 POUND SIGN */
XK_currency = 0x00a4, /* U+00A4 CURRENCY SIGN */
XK_yen = 0x00a5, /* U+00A5 YEN SIGN */
XK_brokenbar = 0x00a6, /* U+00A6 BROKEN BAR */
XK_section = 0x00a7, /* U+00A7 SECTION SIGN */
XK_diaeresis = 0x00a8, /* U+00A8 DIAERESIS */
XK_copyright = 0x00a9, /* U+00A9 COPYRIGHT SIGN */
XK_ordfeminine = 0x00aa, /* U+00AA FEMININE ORDINAL INDICATOR */
XK_guillemotleft = 0x00ab, /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */
XK_notsign = 0x00ac, /* U+00AC NOT SIGN */
XK_hyphen = 0x00ad, /* U+00AD SOFT HYPHEN */
XK_registered = 0x00ae, /* U+00AE REGISTERED SIGN */
XK_macron = 0x00af, /* U+00AF MACRON */
XK_degree = 0x00b0, /* U+00B0 DEGREE SIGN */
XK_plusminus = 0x00b1, /* U+00B1 PLUS-MINUS SIGN */
XK_twosuperior = 0x00b2, /* U+00B2 SUPERSCRIPT TWO */
XK_threesuperior = 0x00b3, /* U+00B3 SUPERSCRIPT THREE */
XK_acute = 0x00b4, /* U+00B4 ACUTE ACCENT */
XK_mu = 0x00b5, /* U+00B5 MICRO SIGN */
XK_paragraph = 0x00b6, /* U+00B6 PILCROW SIGN */
XK_periodcentered = 0x00b7, /* U+00B7 MIDDLE DOT */
XK_cedilla = 0x00b8, /* U+00B8 CEDILLA */
XK_onesuperior = 0x00b9, /* U+00B9 SUPERSCRIPT ONE */
XK_masculine = 0x00ba, /* U+00BA MASCULINE ORDINAL INDICATOR */
XK_guillemotright = 0x00bb, /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */
XK_onequarter = 0x00bc, /* U+00BC VULGAR FRACTION ONE QUARTER */
XK_onehalf = 0x00bd, /* U+00BD VULGAR FRACTION ONE HALF */
XK_threequarters = 0x00be, /* U+00BE VULGAR FRACTION THREE QUARTERS */
XK_questiondown = 0x00bf, /* U+00BF INVERTED QUESTION MARK */
XK_Agrave = 0x00c0, /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */
XK_Aacute = 0x00c1, /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */
XK_Acircumflex = 0x00c2, /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */
XK_Atilde = 0x00c3, /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */
XK_Adiaeresis = 0x00c4, /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */
XK_Aring = 0x00c5, /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */
XK_AE = 0x00c6, /* U+00C6 LATIN CAPITAL LETTER AE */
XK_Ccedilla = 0x00c7, /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */
XK_Egrave = 0x00c8, /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */
XK_Eacute = 0x00c9, /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */
XK_Ecircumflex = 0x00ca, /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */
XK_Ediaeresis = 0x00cb, /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */
XK_Igrave = 0x00cc, /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */
XK_Iacute = 0x00cd, /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */
XK_Icircumflex = 0x00ce, /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */
XK_Idiaeresis = 0x00cf, /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */
XK_ETH = 0x00d0, /* U+00D0 LATIN CAPITAL LETTER ETH */
XK_Eth = 0x00d0, /* deprecated */
XK_Ntilde = 0x00d1, /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */
XK_Ograve = 0x00d2, /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */
XK_Oacute = 0x00d3, /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */
XK_Ocircumflex = 0x00d4, /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */
XK_Otilde = 0x00d5, /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */
XK_Odiaeresis = 0x00d6, /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */
XK_multiply = 0x00d7, /* U+00D7 MULTIPLICATION SIGN */
XK_Oslash = 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
XK_Ooblique = 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */
XK_Ugrave = 0x00d9, /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */
XK_Uacute = 0x00da, /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */
XK_Ucircumflex = 0x00db, /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */
XK_Udiaeresis = 0x00dc, /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */
XK_Yacute = 0x00dd, /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */
XK_THORN = 0x00de, /* U+00DE LATIN CAPITAL LETTER THORN */
XK_Thorn = 0x00de, /* deprecated */
XK_ssharp = 0x00df, /* U+00DF LATIN SMALL LETTER SHARP S */
XK_agrave = 0x00e0, /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */
XK_aacute = 0x00e1, /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */
XK_acircumflex = 0x00e2, /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */
XK_atilde = 0x00e3, /* U+00E3 LATIN SMALL LETTER A WITH TILDE */
XK_adiaeresis = 0x00e4, /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */
XK_aring = 0x00e5, /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */
XK_ae = 0x00e6, /* U+00E6 LATIN SMALL LETTER AE */
XK_ccedilla = 0x00e7, /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */
XK_egrave = 0x00e8, /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */
XK_eacute = 0x00e9, /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */
XK_ecircumflex = 0x00ea, /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */
XK_ediaeresis = 0x00eb, /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */
XK_igrave = 0x00ec, /* U+00EC LATIN SMALL LETTER I WITH GRAVE */
XK_iacute = 0x00ed, /* U+00ED LATIN SMALL LETTER I WITH ACUTE */
XK_icircumflex = 0x00ee, /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */
XK_idiaeresis = 0x00ef, /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */
XK_eth = 0x00f0, /* U+00F0 LATIN SMALL LETTER ETH */
XK_ntilde = 0x00f1, /* U+00F1 LATIN SMALL LETTER N WITH TILDE */
XK_ograve = 0x00f2, /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */
XK_oacute = 0x00f3, /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */
XK_ocircumflex = 0x00f4, /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */
XK_otilde = 0x00f5, /* U+00F5 LATIN SMALL LETTER O WITH TILDE */
XK_odiaeresis = 0x00f6, /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */
XK_division = 0x00f7, /* U+00F7 DIVISION SIGN */
XK_oslash = 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
XK_ooblique = 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */
XK_ugrave = 0x00f9, /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */
XK_uacute = 0x00fa, /* U+00FA LATIN SMALL LETTER U WITH ACUTE */
XK_ucircumflex = 0x00fb, /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */
XK_udiaeresis = 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */
XK_yacute = 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
XK_thorn = 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */
XK_ydiaeresis = 0x00ff; /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */

File diff suppressed because one or more lines are too long

View File

@ -1,146 +0,0 @@
var XtScancode = {};
XtScancode["Escape"] = 0x0001;
XtScancode["Digit1"] = 0x0002;
XtScancode["Digit2"] = 0x0003;
XtScancode["Digit3"] = 0x0004;
XtScancode["Digit4"] = 0x0005;
XtScancode["Digit5"] = 0x0006;
XtScancode["Digit6"] = 0x0007;
XtScancode["Digit7"] = 0x0008;
XtScancode["Digit8"] = 0x0009;
XtScancode["Digit9"] = 0x000A;
XtScancode["Digit0"] = 0x000B;
XtScancode["Minus"] = 0x000C;
XtScancode["Equal"] = 0x000D;
XtScancode["Backspace"] = 0x000E;
XtScancode["Tab"] = 0x000F;
XtScancode["KeyQ"] = 0x0010;
XtScancode["KeyW"] = 0x0011;
XtScancode["KeyE"] = 0x0012;
XtScancode["KeyR"] = 0x0013;
XtScancode["KeyT"] = 0x0014;
XtScancode["KeyY"] = 0x0015;
XtScancode["KeyU"] = 0x0016;
XtScancode["KeyI"] = 0x0017;
XtScancode["KeyO"] = 0x0018;
XtScancode["KeyP"] = 0x0019;
XtScancode["BracketLeft"] = 0x001A;
XtScancode["BracketRight"] = 0x001B;
XtScancode["Enter"] = 0x001C;
XtScancode["ControlLeft"] = 0x001D;
XtScancode["KeyA"] = 0x001E;
XtScancode["KeyS"] = 0x001F;
XtScancode["KeyD"] = 0x0020;
XtScancode["KeyF"] = 0x0021;
XtScancode["KeyG"] = 0x0022;
XtScancode["KeyH"] = 0x0023;
XtScancode["KeyJ"] = 0x0024;
XtScancode["KeyK"] = 0x0025;
XtScancode["KeyL"] = 0x0026;
XtScancode["Semicolon"] = 0x0027;
XtScancode["Quote"] = 0x0028;
XtScancode["Backquote"] = 0x0029;
XtScancode["ShiftLeft"] = 0x002A;
XtScancode["Backslash"] = 0x002B;
XtScancode["KeyZ"] = 0x002C;
XtScancode["KeyX"] = 0x002D;
XtScancode["KeyC"] = 0x002E;
XtScancode["KeyV"] = 0x002F;
XtScancode["KeyB"] = 0x0030;
XtScancode["KeyN"] = 0x0031;
XtScancode["KeyM"] = 0x0032;
XtScancode["Comma"] = 0x0033;
XtScancode["Period"] = 0x0034;
XtScancode["Slash"] = 0x0035;
XtScancode["ShiftRight"] = 0x0036;
XtScancode["NumpadMultiply"] = 0x0037;
XtScancode["AltLeft"] = 0x0038;
XtScancode["Space"] = 0x0039;
XtScancode["CapsLock"] = 0x003A;
XtScancode["F1"] = 0x003B;
XtScancode["F2"] = 0x003C;
XtScancode["F3"] = 0x003D;
XtScancode["F4"] = 0x003E;
XtScancode["F5"] = 0x003F;
XtScancode["F6"] = 0x0040;
XtScancode["F7"] = 0x0041;
XtScancode["F8"] = 0x0042;
XtScancode["F9"] = 0x0043;
XtScancode["F10"] = 0x0044;
XtScancode["Pause"] = 0xE045;
XtScancode["ScrollLock"] = 0x0046;
XtScancode["Numpad7"] = 0x0047;
XtScancode["Numpad8"] = 0x0048;
XtScancode["Numpad9"] = 0x0049;
XtScancode["NumpadSubtract"] = 0x004A;
XtScancode["Numpad4"] = 0x004B;
XtScancode["Numpad5"] = 0x004C;
XtScancode["Numpad6"] = 0x004D;
XtScancode["NumpadAdd"] = 0x004E;
XtScancode["Numpad1"] = 0x004F;
XtScancode["Numpad2"] = 0x0050;
XtScancode["Numpad3"] = 0x0051;
XtScancode["Numpad0"] = 0x0052;
XtScancode["NumpadDecimal"] = 0x0053;
XtScancode["IntlBackslash"] = 0x0056;
XtScancode["F11"] = 0x0057;
XtScancode["F12"] = 0x0058;
XtScancode["IntlYen"] = 0x007D;
XtScancode["MediaTrackPrevious"] = 0xE010;
XtScancode["MediaTrackNext"] = 0xE019;
XtScancode["NumpadEnter"] = 0xE01C;
XtScancode["ControlRight"] = 0xE01D;
XtScancode["VolumeMute"] = 0xE020;
XtScancode["MediaPlayPause"] = 0xE022;
XtScancode["MediaStop"] = 0xE024;
XtScancode["VolumeDown"] = 0xE02E;
XtScancode["VolumeUp"] = 0xE030;
XtScancode["BrowserHome"] = 0xE032;
XtScancode["NumpadDivide"] = 0xE035;
XtScancode["PrintScreen"] = 0xE037;
XtScancode["AltRight"] = 0xE038;
XtScancode["NumLock"] = 0x0045;
XtScancode["Home"] = 0xE047;
XtScancode["ArrowUp"] = 0xE048;
XtScancode["PageUp"] = 0xE049;
XtScancode["ArrowLeft"] = 0xE04B;
XtScancode["ArrowRight"] = 0xE04D;
XtScancode["End"] = 0xE04F;
XtScancode["ArrowDown"] = 0xE050;
XtScancode["PageDown"] = 0xE051;
XtScancode["Insert"] = 0xE052;
XtScancode["Delete"] = 0xE053;
XtScancode["OSLeft"] = 0xE05B;
XtScancode["OSRight"] = 0xE05C;
XtScancode["ContextMenu"] = 0xE05D;
XtScancode["BrowserSearch"] = 0xE065;
XtScancode["BrowserFavorites"] = 0xE066;
XtScancode["BrowserRefresh"] = 0xE067;
XtScancode["BrowserStop"] = 0xE068;
XtScancode["BrowserForward"] = 0xE069;
XtScancode["BrowserBack"] = 0xE06A;
XtScancode["NumpadComma"] = 0x007E;
XtScancode["NumpadEqual"] = 0x0059;
XtScancode["F13"] = 0x0064;
XtScancode["F14"] = 0x0065;
XtScancode["F15"] = 0x0066;
XtScancode["F16"] = 0x0067;
XtScancode["F17"] = 0x0068;
XtScancode["F18"] = 0x0069;
XtScancode["F19"] = 0x006A;
XtScancode["F20"] = 0x006B;
XtScancode["F21"] = 0x006C;
XtScancode["F22"] = 0x006D;
XtScancode["F23"] = 0x006E;
XtScancode["F24"] = 0x0076;
XtScancode["KanaMode"] = 0x0070;
XtScancode["Lang2"] = 0x0071;
XtScancode["Lang1"] = 0x0072;
XtScancode["IntlRo"] = 0x0073;
XtScancode["Convert"] = 0x0079;
XtScancode["NonConvert"] = 0x007B;
XtScancode["LaunchApp2"] = 0xE021;
XtScancode["Power"] = 0xE05E;
XtScancode["LaunchApp1"] = 0xE06B;
XtScancode["LaunchMail"] = 0xE06C;
XtScancode["MediaSelect"] = 0xE06D;

View File

@ -110,19 +110,19 @@ module.exports = function(config) {
files: [
'tests/fake.*.js',
'tests/assertions.js',
'include/util.js', // load first to avoid issues, since methods are called immediately
//'../include/*.js',
'include/base64.js',
'include/keysym.js',
'include/keysymdef.js',
'include/xtscancodes.js',
'include/keyboard.js',
'include/input.js',
'include/websock.js',
'include/rfb.js',
'include/des.js',
'include/display.js',
'include/inflator.js',
'core/util.js', // load first to avoid issues, since methods are called immediately
//'../core/*.js',
'core/base64.js',
'core/input/keysym.js',
'core/input/keysymdef.js',
'core/input/xtscancodes.js',
'core/input/util.js',
'core/input/devices.js',
'core/websock.js',
'core/rfb.js',
'core/des.js',
'core/display.js',
'core/inflator.js',
'tests/test.*.js'
],
@ -134,8 +134,8 @@ module.exports = function(config) {
// list of files to exclude
exclude: [
'../include/playback.js',
'../include/ui.js'
'../tests/playback.js',
'../app/ui.js'
],
customLaunchers: customLaunchers,

View File

@ -8,7 +8,9 @@
"test": "tests"
},
"scripts": {
"test": "PATH=$PATH:node_modules/karma/bin karma start karma.conf.js"
"test": "PATH=$PATH:node_modules/karma/bin karma start karma.conf.js",
"prepublish": "node ./utils/use_require.js --as-require",
"build-es6": "node ./utils/use_require.js"
},
"repository": {
"type": "git",
@ -27,24 +29,32 @@
"homepage": "https://github.com/kanaka/noVNC",
"devDependencies": {
"ansi": "^0.3.0",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-es2015-modules-commonjs": "^6.14.0",
"babelify": "^7.3.0",
"browserify": "^13.1.0",
"casperjs": "^1.1.0-beta3",
"chai": "^2.1.0",
"commander": "^2.6.0",
"commander": "^2.8.1",
"fs-extra": "^0.30.0",
"karma": "^0.12.31",
"karma-chai": "^0.1.0",
"karma-mocha": "^0.1.10",
"karma-mocha-reporter": "^1.0.0",
"karma-phantomjs-launcher": "^0.1.4",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sauce-launcher": "^0.2.10",
"karma-sinon": "^1.0.4",
"karma-sinon-chai-latest": "^0.1.0",
"mocha": "^2.1.0",
"open": "^0.0.5",
"phantom": "^0.7.2",
"phantomjs": "^1.9.15",
"phantomjs-prebuilt": "^2.1.4",
"sinon": "^1.12.2",
"sinon-chai": "^2.7.0",
"spooky": "^0.2.5",
"temp": "^0.8.1"
"temp": "^0.8.1",
"through2": "^2.0.1"
},
"dependencies": {
"pako": "^1.0.3"
}
}

View File

@ -1,39 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Javascript Arrays Performance Test</title>
<!--
<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/webutil.js"></script>
<script src="browser.js"></script>
<script src="stats.js"></script>
<script src="arrays.js"></script>
</head>
<body>
<h3>Javascript Arrays Performance Test</h3>
Iterations: <input id='iterations' style='width:50'>&nbsp;
Array Size: <input id='arraySize' style='width:40'>*1024&nbsp;
<input id='startButton' type='button' value='Run Tests'
onclick="begin();">&nbsp;
<br><br>
Results:<br>
<textarea id="messages" style="font-size: 9;" cols=80 rows=50></textarea>
</br>
<canvas id="canvas" style="display: none;"></canvas>
</body>
<script>
var verbose = true;
window.onload = function() {
vmessage("in onload");
init();
}
</script>
</html>

View File

@ -1,375 +0,0 @@
/*
* Javascript binary array performance tests
* Copyright (C) 2012 Joel Martin
* Licensed under MPL 2.0 (see LICENSE.txt)
*/
var ctx, i, j, randlist,
new_normal, new_imageData, new_arrayBuffer,
browser = Browser.browser + " " +
Browser.version + " on " +
Browser.OS,
do_imageData = false,
do_arrayBuffer = false,
conf = {
'create_cnt' : 2000,
'read_cnt' : 5000000,
'write_cnt' : 5000000,
'iterations' : 0,
'order_l1' : [browser],
'order_l2' : ['normal',
'imageData',
'arrayBuffer'],
'order_l3' : ['create',
'sequentialRead',
'randomRead',
'sequentialWrite']
},
stats = {},
testFunc = {},
iteration, arraySize;
var newline = "\n";
if (Util.Engine.trident) {
var newline = "<br>\n";
}
function message(str) {
//console.log(str);
cell = $D('messages');
cell.innerHTML += str + newline;
cell.scrollTop = cell.scrollHeight;
}
function vmessage(str) {
if (verbose) {
message(str);
} else {
console.log(str);
}
}
new_normal = function() {
var arr = [], i;
for (i = 0; i < arraySize; i++) {
arr[i] = 0;
}
return arr;
}
/* Will be overridden with real function */
new_imageData = function() {
throw("imageData not supported");
};
new_imageData_createImageData = function() {
var imageData = ctx.createImageData(1024/4, arraySize / 1024);
return imageData.data;
};
new_imageData_getImageData = function() {
var imageData = ctx.getImageData(0, 0, 1024/4, arraySize / 1024),
arr = imageData.data;
for (i = 0; i < arraySize; i++) {
arr[i] = 0;
}
return arr;
};
new_arrayBuffer = function() {
var arr = new ArrayBuffer(arraySize);
return new Uint8Array(arr);
}
function init_randlist() {
randlist = [];
for (var i=0; i < arraySize; i++) {
randlist[i] = parseInt(Math.random() * 256, 10);
}
}
function copy_randlist(arr) {
for (var i=0; i < arraySize; i++) {
arr[i] = randlist[i];
}
}
function begin() {
var i, j;
conf.iterations = parseInt($D('iterations').value, 10);
arraySize = parseInt($D('arraySize').value, 10) * 1024;
init_randlist();
// TODO: randomize test_list
stats = {};
for (i = 0; i < conf.order_l2.length; i++) {
stats[conf.order_l2[i]] = {};
for (j = 0; j < conf.order_l3.length; j++) {
stats[conf.order_l2[i]][conf.order_l3[j]] = [];
}
}
$D('startButton').value = "Running";
$D('startButton').disabled = true;
message("running " + conf.iterations + " test iterations");
iteration = 1;
setTimeout(run_next_iteration, 250);
}
function finish() {
var totalTime, arrayType, testType, times;
message("tests finished");
for (j = 0; j < conf.order_l3.length; j++) {
testType = conf.order_l3[j];
message("Test '" + testType + "'");
for (i = 0; i < conf.order_l2.length; i++) {
arrayType = conf.order_l2[i];
message(" Array Type '" + arrayType);
times = stats[arrayType][testType];
message(" Average : " + times.mean() + "ms" +
" (Total: " + times.sum() + "ms)");
message(" Min/Max : " + times.min() + "ms/" +
times.max() + "ms");
message(" StdDev : " + times.stdDev() + "ms");
}
}
vmessage("array_chart.py JSON data:");
chart_data = {'conf' : conf, 'stats' : { } };
chart_data.stats[browser] = stats;
chart_data.stats['next_browser'] = {};
vmessage(JSON.stringify(chart_data, null, 2));
$D('startButton').disabled = false;
$D('startButton').value = "Run Tests";
}
function run_next_iteration() {
var arrayType, testType, deltaTime;
for (i = 0; i < conf.order_l2.length; i++) {
arrayType = conf.order_l2[i];
if (arrayType === 'imageData' && (!do_imageData)) {
continue;
}
if (arrayType === 'arrayBuffer' && (!do_arrayBuffer)) {
continue;
}
for (j = 0; j < conf.order_l3.length; j++) {
testType = conf.order_l3[j];
deltaTime = testFunc[arrayType + "_" + testType]();
stats[arrayType][testType].push(deltaTime);
vmessage("test " + (arrayType + "_" + testType) +
" time: " + (deltaTime) + "ms");
}
}
message("finished test iteration " + iteration);
if (iteration >= conf.iterations) {
setTimeout(finish, 1);
return;
}
iteration++;
setTimeout(run_next_iteration, 1);
}
/*
* Test functions
*/
testFunc["normal_create"] = function() {
var cnt, arrNormal, startTime, endTime;
vmessage("create normal array " + conf.create_cnt + "x, initialized to 0");
startTime = (new Date()).getTime();
for (cnt = 0; cnt < conf.create_cnt; cnt++) {
arrNormal = new_normal();
}
endTime = (new Date()).getTime();
return endTime - startTime;
};
testFunc["imageData_create"] = function() {
var cnt, arrImage, startTime, endTime;
vmessage("create imageData array " + conf.create_cnt + "x, initialized to 0");
startTime = (new Date()).getTime();
for (cnt = 0; cnt < conf.create_cnt; cnt++) {
arrImage = new_imageData();
}
endTime = (new Date()).getTime();
if (arrImage[103] !== 0) {
message("Initialization failed, arrImage[103] is: " + arrImage[103]);
throw("Initialization failed, arrImage[103] is: " + arrImage[103]);
}
return endTime - startTime;
};
testFunc["arrayBuffer_create"] = function() {
var cnt, arrBuffer, startTime, endTime;
vmessage("create arrayBuffer array " + conf.create_cnt + "x, initialized to 0");
startTime = (new Date()).getTime();
for (cnt = 0; cnt < conf.create_cnt; cnt++) {
arrBuffer = new_arrayBuffer();
}
endTime = (new Date()).getTime();
if (arrBuffer[103] !== 0) {
message("Initialization failed, arrBuffer[103] is: " + arrBuffer[103]);
throw("Initialization failed, arrBuffer[103] is: " + arrBuffer[103]);
}
return endTime - startTime;
};
function test_sequentialRead(arr) {
var i, j, cnt, startTime, endTime;
/* Initialize the array */
copy_randlist(arr);
startTime = (new Date()).getTime();
i = 0;
j = 0;
for (cnt = 0; cnt < conf.read_cnt; cnt++) {
j = arr[i];
i++;
if (i >= arraySize) {
i = 0;
}
}
endTime = (new Date()).getTime();
return endTime - startTime;
}
function test_randomRead(arr) {
var i, cnt, startTime, endTime;
/* Initialize the array */
copy_randlist(arr); // used as jumplist
startTime = (new Date()).getTime();
i = 0;
for (cnt = 0; cnt < conf.read_cnt; cnt++) {
i = (arr[i] + cnt) % arraySize;
}
endTime = (new Date()).getTime();
return endTime - startTime;
}
function test_sequentialWrite(arr) {
var i, cnt, startTime, endTime;
/* Initialize the array */
copy_randlist(arr);
startTime = (new Date()).getTime();
i = 0;
for (cnt = 0; cnt < conf.write_cnt; cnt++) {
arr[i] = (cnt % 256);
i++;
if (i >= arraySize) {
i = 0;
}
}
endTime = (new Date()).getTime();
return endTime - startTime;
}
/* Sequential Read Tests */
testFunc["normal_sequentialRead"] = function() {
vmessage("read normal array " + conf.read_cnt + "x");
return test_sequentialRead(new_normal());
};
testFunc["imageData_sequentialRead"] = function() {
vmessage("read imageData array " + conf.read_cnt + "x");
return test_sequentialRead(new_imageData());
};
testFunc["arrayBuffer_sequentialRead"] = function() {
vmessage("read arrayBuffer array " + conf.read_cnt + "x");
return test_sequentialRead(new_arrayBuffer());
};
/* Random Read Tests */
testFunc["normal_randomRead"] = function() {
vmessage("read normal array " + conf.read_cnt + "x");
return test_randomRead(new_normal());
};
testFunc["imageData_randomRead"] = function() {
vmessage("read imageData array " + conf.read_cnt + "x");
return test_randomRead(new_imageData());
};
testFunc["arrayBuffer_randomRead"] = function() {
vmessage("read arrayBuffer array " + conf.read_cnt + "x");
return test_randomRead(new_arrayBuffer());
};
/* Sequential Write Tests */
testFunc["normal_sequentialWrite"] = function() {
vmessage("write normal array " + conf.write_cnt + "x");
return test_sequentialWrite(new_normal());
};
testFunc["imageData_sequentialWrite"] = function() {
vmessage("write imageData array " + conf.write_cnt + "x");
return test_sequentialWrite(new_imageData());
};
testFunc["arrayBuffer_sequentialWrite"] = function() {
vmessage("write arrayBuffer array " + conf.write_cnt + "x");
return test_sequentialWrite(new_arrayBuffer());
};
init = function() {
vmessage(">> init");
$D('iterations').value = 10;
$D('arraySize').value = 10;
arraySize = parseInt($D('arraySize').value, 10) * 1024;
message("Browser: " + browser);
/* Determine browser binary array support */
try {
ctx = $D('canvas').getContext('2d');
new_imageData = new_imageData_createImageData;
new_imageData();
do_imageData = true;
} catch (exc) {
vmessage("createImageData not supported: " + exc);
try {
ctx = $D('canvas').getContext('2d');
new_imageData = new_imageData_getImageData;
blah = new_imageData();
do_imageData = true;
} catch (exc) {
vmessage("getImageData not supported: " + exc);
}
}
if (! do_imageData) {
message("imageData arrays not supported");
}
try {
new_arrayBuffer();
do_arrayBuffer = true;
} catch (exc) {
vmessage("Typed Arrays not supported: " + exc);
}
if (! do_arrayBuffer) {
message("Typed Arrays (ArrayBuffers) not suppoted");
}
vmessage("<< init");
}

View File

@ -1,91 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Native Base64 Tests</title>
<script src="../include/util.js"></script>
<script src="../include/webutil.js"></script>
<script src="../include/base64.js"></script>
</head>
<body>
<h1>Native Base64 Tests</h1>
<br>
Messages:<br>
<textarea id="debug" style="font-size: 9px;" cols=80 rows=25></textarea>
<br>
</body>
<script>
function debug(str) {
console.log(str);
cell = $D('debug');
cell.innerHTML += str + "\n";
cell.scrollTop = cell.scrollHeight;
}
function assertRun(code, result) {
try {
var actual = eval(code);
} catch (exc) {
debug("FAIL: '" + code + "' threw an exception");
fail += 1;
return false;
}
if (actual !== result) {
debug("FAIL: '" + code + "' returned '" + actual + "', expected '" + result + "'");
fail += 1;
return false;
}
debug("PASS: '" + code + "' returned expected '" + result +"'");
pass += 1;
return true;
}
function Base64_decode(data) {
var arr = Base64.decode (data);
return arr.map(function (num) {
return String.fromCharCode(num); } ).join('');
}
window.onload = function() {
var str;
debug('onload');
fail = 0;
pass = 0;
assertRun('window.btoa("hello world")', 'aGVsbG8gd29ybGQ=');
assertRun('window.btoa("a")', 'YQ==');
assertRun('window.btoa("ab")', 'YWI=');
assertRun('window.btoa("abc")', 'YWJj');
assertRun('window.btoa("abcd")', 'YWJjZA==');
assertRun('window.btoa("abcde")', 'YWJjZGU=');
assertRun('window.btoa("abcdef")', 'YWJjZGVm');
assertRun('window.btoa("abcdefg")', 'YWJjZGVmZw==');
assertRun('window.btoa("abcdefgh")', 'YWJjZGVmZ2g=');
assertRun('window.atob("aGVsbG8gd29ybGQ=")', 'hello world');
assertRun('Base64_decode("aGVsbG8gd29ybGQ=")', 'hello world');
assertRun('window.atob("YQ==")', 'a');
assertRun('Base64_decode("YQ==")', 'a');
assertRun('window.atob("YWI=")', 'ab');
assertRun('Base64_decode("YWI=")', 'ab');
assertRun('window.atob("YWJj")', 'abc');
assertRun('Base64_decode("YWJj")', 'abc');
assertRun('window.atob("YWJjZA==")', 'abcd');
assertRun('Base64_decode("YWJjZA==")', 'abcd');
assertRun('window.atob("YWJjZGU=")', 'abcde');
assertRun('Base64_decode("YWJjZGU=")', 'abcde');
assertRun('window.atob("YWJjZGVm")', 'abcdef');
assertRun('Base64_decode("YWJjZGVm")', 'abcdef');
assertRun('typeof window.btoa', 'function');
assertRun('window.btoa("")', '');
assertRun('window.btoa(null)', '');
assertRun('window.atob(window.btoa(window))', window.toString()); // "[object DOMWindow]"
assertRun('window.btoa("\\u0080\\u0081")', 'gIE=');
debug("Tests failed: " + fail);
debug("Tests passed: " + pass);
}
</script>

View File

@ -1,12 +0,0 @@
// The following results in 'hello [MANGLED]'
//
// Filed as https://github.com/ry/node/issues/issue/402
var sys = require("sys"),
buf = new Buffer(1024), len,
str1 = "aGVsbG8g", // 'hello '
str2 = "d29ybGQ=", // 'world'
len = buf.write(str1, 0, 'base64');
len += buf.write(str2, len, 'base64');
sys.log("decoded result: " + buf.toString('binary', 0, len));

View File

@ -1,134 +0,0 @@
/*
* From:
* http://www.quirksmode.org/js/detect.html
*/
var Browser = {
init: function () {
this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
this.version = this.searchVersion(navigator.userAgent)
|| this.searchVersion(navigator.appVersion)
|| "an unknown version";
this.majorVersion = this.searchMajorVersion(navigator.userAgent)
|| this.searchMajorVersion(navigator.appVersion)
|| "an unknown version";
this.fullVersion = this.searchFullVersion(navigator.userAgent)
|| this.searchFullVersion(navigator.appVersion)
|| "an unknown version";
this.OS = this.searchString(this.dataOS) || "an unknown OS";
},
searchString: function (data) {
for (var i=0;i<data.length;i++) {
var dataString = data[i].string;
var dataProp = data[i].prop;
this.versionSearchString = data[i].versionSearch || data[i].identity;
if (dataString) {
if (dataString.indexOf(data[i].subString) != -1)
return data[i].identity;
}
else if (dataProp)
return data[i].identity;
}
},
searchFullVersion: function (dataString) {
var index = dataString.indexOf(this.versionSearchString);
if (index == -1) return;
return dataString.substring(index+this.versionSearchString.length+1);
},
searchVersion: function (dataString) {
return this.searchFullVersion(dataString).split(" ")[0];
},
searchMajorVersion: function (dataString) {
return parseFloat(this.searchFullVersion(dataString).split(".")[0]);
},
dataBrowser: [
{
string: navigator.userAgent,
subString: "Chrome",
identity: "Chrome"
},
{ string: navigator.userAgent,
subString: "OmniWeb",
versionSearch: "OmniWeb/",
identity: "OmniWeb"
},
{
string: navigator.vendor,
subString: "Apple",
identity: "Safari",
versionSearch: "Version"
},
{
prop: window.opera,
identity: "Opera",
versionSearch: "Version"
},
{
string: navigator.vendor,
subString: "iCab",
identity: "iCab"
},
{
string: navigator.vendor,
subString: "KDE",
identity: "Konqueror"
},
{
string: navigator.userAgent,
subString: "Firefox",
identity: "Firefox"
},
{
string: navigator.vendor,
subString: "Camino",
identity: "Camino"
},
{ // for newer Netscapes (6+)
string: navigator.userAgent,
subString: "Netscape",
identity: "Netscape"
},
{
string: navigator.userAgent,
subString: "MSIE",
identity: "Explorer",
versionSearch: "MSIE"
},
{
string: navigator.userAgent,
subString: "Gecko",
identity: "Mozilla",
versionSearch: "rv"
},
{ // for older Netscapes (4-)
string: navigator.userAgent,
subString: "Mozilla",
identity: "Netscape",
versionSearch: "Mozilla"
}
],
dataOS : [
{
string: navigator.platform,
subString: "Win",
identity: "Windows"
},
{
string: navigator.platform,
subString: "Mac",
identity: "Mac"
},
{
string: navigator.userAgent,
subString: "iPhone",
identity: "iPhone/iPod"
},
{
string: navigator.platform,
subString: "Linux",
identity: "Linux"
}
]
};
Browser.init();

View File

@ -1,148 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Canvas Performance Test</title>
<!--
<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/webutil.js"></script>
<script src="../include/base64.js"></script>
<script src="../include/display.js"></script>
<script src="face.png.js"></script>
</head>
<body>
Iterations: <input id='iterations' style='width:50' value="100">&nbsp;
Width: <input id='width' style='width:50' value="640">&nbsp;
Height: <input id='height' style='width:50' value="480">&nbsp;
<input id='startButton' type='button' value='Do Performance Test'
style='width:150px' onclick="begin();">&nbsp;
<br><br>
<b>Canvas</b> (should see three squares and two happy faces):<br>
<canvas id="canvas" width="200" height="100"
style="border-style: dotted; border-width: 1px;">
Canvas not supported.
</canvas>
<br>
Results:<br>
<textarea id="messages" style="font-size: 9;" cols=80 rows=25></textarea>
</body>
<script>
var msg_cnt = 0;
var display, start_width = 300, start_height = 100;
var iterations;
function message(str) {
console.log(str);
cell = $D('messages');
cell.innerHTML += msg_cnt + ": " + str + "\n";
cell.scrollTop = cell.scrollHeight;
msg_cnt += 1;
}
function test_functions () {
var img, x, y, w, h, ctx = display.get_context();
w = display.get_width();
h = display.get_height();
display.fillRect(0, 0, w, h, [240,240,240]);
display.blitStringImage("data:image/png;base64," + face64, 150, 10);
var himg = new Image();
himg.onload = function () {
ctx.drawImage(himg, 200, 40); };
himg.src = "face.png";
/* Test array image data */
data = [];
for (y=0; y< 50; y++) {
for (x=0; x< 50; x++) {
data[(y*50 + x)*4 + 0] = 255 - parseInt((255 / 50) * y, 10);
data[(y*50 + x)*4 + 1] = parseInt((255 / 50) * y, 10);
data[(y*50 + x)*4 + 2] = parseInt((255 / 50) * x, 10);
data[(y*50 + x)*4 + 3] = 255;
}
}
display.blitImage(30, 10, 50, 50, data, 0);
img = display.getTile(5,5,16,16,[0,128,128]);
display.putTile(img);
img = display.getTile(90,15,16,16,[0,0,0]);
display.setSubTile(img, 0,0,16,16,[128,128,0]);
display.putTile(img);
}
function begin () {
$D('startButton').value = "Running";
$D('startButton').disabled = true;
setTimeout(start_delayed, 250);
iterations = $D('iterations').value;
}
function start_delayed () {
var ret;
ret = display.set_prefer_js(true);
if (ret) {
message("Running test: prefer Javascript ops");
var time1 = run_test();
message("prefer Javascript ops: " + time1 + "ms total, " +
(time1 / iterations) + "ms per frame");
} else {
message("Could not run: prefer Javascript ops");
}
display.set_prefer_js(false);
message("Running test: prefer Canvas ops");
var time2 = run_test();
message("prefer Canvas ops: " + time2 + "ms total, " +
(time2 / iterations) + "ms per frame");
if (Util.get_logging() !== 'debug') {
display.resize(start_width, start_height, true);
test_functions();
}
$D('startButton').disabled = false;
$D('startButton').value = "Do Performance Test";
}
function run_test () {
var width, height;
width = $D('width').value;
height = $D('height').value;
display.resize(width, height);
var color, start_time = (new Date()).getTime(), w, h;
for (var i=0; i < iterations; i++) {
color = [128, 128, (255 / iterations) * i, 0];
for (var x=0; x < width; x = x + 16) {
for (var y=0; y < height; y = y + 16) {
w = Math.min(16, width - x);
h = Math.min(16, height - y);
var tile = display.getTile(x, y, w, h, color);
display.setSubTile(tile, 0, 0, w, h, color);
display.putTile(tile);
}
}
}
var end_time = (new Date()).getTime();
return (end_time - start_time);
}
window.onload = function() {
message("in onload");
$D('iterations').value = 10;
display = new Display({'target' : $D('canvas')});
display.resize(start_width, start_height, true);
message("Canvas initialized");
test_functions();
}
</script>
</html>

View File

@ -1,135 +0,0 @@
<!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/webutil.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 = $D('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 );
// Push multi-byte little-endian values
arr.push16le = function (num) {
this.push((num ) & 0xFF,
(num >> 8) & 0xFF );
};
arr.push32le = function (num) {
this.push((num ) & 0xFF,
(num >> 8) & 0xFF,
(num >> 16) & 0xFF,
(num >> 24) & 0xFF );
};
// 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 canvas, cross, cursor, cursor64;
canvas = new Canvas({'target' : $D("testcanvas")});
debug("canvas indicates Data URI cursor support is: " + canvas.get_cursor_uri());
$D('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 + ")");
$D('button2').style.cursor="url(data:image/x-icon;base64," + cursor64 + "), default";
debug("onload complete");
}
</script>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1 +0,0 @@
var face64 = 'iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAIAAACRuyQOAAAAA3NCSVQICAjb4U/gAAAAGXRFWHRTb2Z0d2FyZQBnbm9tZS1zY3JlZW5zaG907wO/PgAACJJJREFUSIm1lltsXMUdxr8558zZq9d3OxebJDYhJLhNIAmUWyFKIBUtVaGqSgtUlIJKeahoEahgIZU+VC0oQiVVC60obckDgVIp3KRCQkmhhIhA4oY4wjg2ufmS9drec/bc5vbvw9prJwq85dP/YWfP7Pfb/8w3s8v6339l2fkrbMvGuZQ2mkUTA0bpc4qpyjrX3dTkAATQ5z0WUrqcAwjL/eXirmBqj0yKSTTBwNxMM0+15JuurG/dlClcOH/yWcVEaVBKUR3Eidizr2946Nhr/9q5b//BsudZzDLG5DK4sDt3443XrFm34bkX9x4ZPimkWNBa/+MfrB84+O7rbxz4+JPQD8liljY6n8t9uWfld2/++vp1F3ct6cikU2eSnvr7P7e99OqC9vaTJ0ccMtl8loyJ4igKwzAIK0GglersWv7sM08VCrk4joY/O/rLXz3mTYzmcnnXdZXWcRzHURwEQRCEHUuXdS/vnp4qP/CT2zdvuAKAQwCB4kRse+m1LY//Wojkscd/57opKUQUJ8wyzFaOq7OGGGPcdZ/f/sKbu3YT0YZrr3JT7pq1l3qeH4SBqgRETBljDKXSqXyh/i9PP/W/Q31btz59zVXrUpxb1dYsixUK+c7Fi59/YUdz2yInnbXcLHfTtpu23ZRlu4ZZiRBTp8Z37HjlhW1/evnFZ9/a+VZdLsecFOMpx83ydJanc24q67iuFOr48NC1G6+fKBY7zutIElFNBAC4nN99602XXLzutjvvETqAlcqktVQin0QiLsRxEAUBaRVUfBh1QfcigmzIuw0NTe2LOjNlL07iOArDwA88z0unGWNTk5P1dfkf3XH3BT2r9b23zZKIAHxr81f/uGpF/8G+Fau+VPbKp8ZHpqdKSRiEYWiMMVopJSuVyl+f3UpIQKL34btvvf2BxuZWN5Umo7TWFiNDDHCampob6utLpRKz7Hvv+E5jfR5ELCkNShFXOytOTH7vjrsOfXJ0wcLFF63sXr1mfXtbS6FQB4BZyGYzX7l0TWtrvWVpUGxUMFEa2bv3Q9+bNCaECX2/NFEc3bd/4r19/tR0uLC98c+/3/LVy9fWzhNq56m1pfEPvabnut2OI8EvBMAYAxhgAWz3u3tuvuWeRx/56aYNa0Hy3fc/euiRZx596IZvbF5Dpgw9CdMI0waqaMrEScPgvtdWXH5JzdzC7NElIPQH3GyTk+4ABCgCEpAkMgRGcLb/49WGxqYtTzwNaJDa/tJ7DU1tW558GaYCEwESYGAWwEidTOcWM8tElcGauTP/ivDGd7V3fxv6JGCBIpBDjIMxgIM5B/YfjMJwfGwEMIA40DcQhcn46DGAzX7p6gIwBhj5WUvH8vLYG+nu8+d6qimY2lPXup70GFEEE9baAhRIj5w8cfz4MSESkJw3FLOfnrvSCETqs3xTd2Vyd+1Na/4MmRRt3gBTgfGJKkQhTAQTwgQgv2tpR8X3Vq5YCiiC7lrSXPG9lRe0AmZ2hQxo5jXpspNqEElxPmlOIi5ZThYUgBKYKRgPxgMFMAGM/+D9P2xuLPQ+dBcoAYkHf/bN5sZM74M3gHS1acBUi0gZ4zk8J5NyzdzBGSIJkoANCqsrwgBAg+zN1605Mfw6IIkiUHL9xouODzwBE4ACkKrGBNBkBEgSKSIz39gxRkuRVAduulHLCZtZoARkzybTAFU2m7GjBBSDkmoRJYCc3U5lSBgjAFeJae4Wauan9WSnWlU0aqdtUAXElAicVDNIgfHZaJkZU0pAESgmCJAACUCApJIBKCITg+VVMuWm2+btEwFE1coVLvOKe2HVE8UwUd/OXi0nQZXZ8kH+7HIFoIgoqvKqzWkV9L2zy5jQ6Ig5nX5pOFd/Vc3cmv9zW9eyYfzITmY1giKiMJNtCiYPw1RgPBh/psiHqcAEZAJQBFMlxaDEnyqmc3mjY2NCiy+bHB3Kt2w8I+UzxTPLlAzjygCz6kFBx6qNg/ue84p9M7AZRoWoQhSAqumfacsrnRg6uH9Rd4/RFWafl1RGjLJ5ZknNnIXjh+PQB0BEQkqv9L4sb1t59cMU74GVKxcnhg5sdzN1jQtX5grtqVyj46ZtywIJrUOZeCKYCLxTU+PHkzhZ2vO1XH5MRIfcwvcHP9qRafp5XfN6l3PGGIA5ktJaJEJINXnkvmWrNza0rSBxEFYbnE6veGRq9IPQO54Ep5QItRYAs22Hu1k315QtdDYsuCzf1KHDt0XlbTu3ySuVRo6MNnc/6XLHTbmObc+QotAHIJUSQiSJTKLR4Nh9Pdc+kM44JA+D5RhfBud8ZjeD5WHVMVYHqwAYmGkyUyRPqPDfMnhTxcNW+jKpGj/94NX8eVtTmYWpFHddlzsOABaOzZGkkImQUsrI/1iVfrPq6vszuSyJD0EasGEVmN0KlgXLgYGMT6qkkwEthrQuG53Y2U0icT79YIfb2pup6+Gcp1zOXV4j9VdJxhghpJBSSCmEjL0+XXqsa+0tTYvWQ/aTHJrZW9JEkowwJjYmMjo0OmR8uZ1eNz12+Nih/zgtv0gXVrsur1Jcl1uWNUsK/GoQldZSSCGllEpIGYcndOm36Vyqa/VNmboFRh4ldZR02ZhpMhJwCGnmLGZ8SewXj/bvTkLDW3pT2UUu55w7Lufc5dVNAsCCsf4o8Gqpr8KkUlIqpZRUKim/Y/y/pVLZ1s5V+Zbl3C3Ybp5Iq2RKxhP+xFBxZFAmwi7cmaq/kjuO4zicO9xx5mPOQqrGvYZRWmulldYqGlLBf3X8EfQkSR8A43WMN1nuWid3hZPpcmzbdmzHtmuwarjnkw5FldNIczyljDZKa62NNpoM1QSA1WQx27Jt23Js27It7pzJmLthz/7/nzHOOThcImPoNBIIAMNpJMtiNcBZDZ3PfVIjgtkWsy3riyZ9AaFGMlozhuqCnDsxxv4PC7uS+QV5eeoAAAAASUVORK5CYII=';

View File

@ -23,15 +23,15 @@
<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/webutil.js"></script>
<script src="../include/base64.js"></script>
<script src="../include/keysym.js"></script>
<script src="../include/keysymdef.js"></script>
<script src="../include/xtscancodes.js"></script>
<script src="../include/keyboard.js"></script>
<script src="../include/input.js"></script>
<script src="../include/display.js"></script>
<script src="../core/util.js"></script>
<script src="../app/webutil.js"></script>
<script src="../core/base64.js"></script>
<script src="../core/input/keysym.js"></script>
<script src="../core/input/keysymdef.js"></script>
<script src="../core/input/xtscancodes.js"></script>
<script src="../core/input/util.js"></script>
<script src="../core/input/devices.js"></script>
<script src="../core/display.js"></script>
<script>
var msg_cnt = 0, iterations,
width = 400, height = 200,
@ -44,7 +44,7 @@
function message(str) {
console.log(str);
cell = $D('messages');
cell = document.getElementById('messages');
cell.innerHTML += msg_cnt + ": " + str + newline;
cell.scrollTop = cell.scrollHeight;
msg_cnt++;
@ -94,23 +94,23 @@
for (b = 0; b < blist.length; b++) {
if (blist[b] === num) {
$D('button' + blist[b]).style.backgroundColor = "black";
$D('button' + blist[b]).style.color = "lightgray";
document.getElementById('button' + blist[b]).style.backgroundColor = "black";
document.getElementById('button' + blist[b]).style.color = "lightgray";
} else {
$D('button' + blist[b]).style.backgroundColor = "";
$D('button' + blist[b]).style.color = "";
document.getElementById('button' + blist[b]).style.backgroundColor = "";
document.getElementById('button' + blist[b]).style.color = "";
}
}
}
window.onload = function() {
canvas = new Display({'target' : $D('canvas')});
canvas = new Display({'target' : document.getElementById('canvas')});
keyboard = new Keyboard({'target': document,
'onKeyPress': rfbKeyPress});
Util.addEvent(document, 'keypress', rawKey);
Util.addEvent(document, 'keydown', rawKey);
Util.addEvent(document, 'keyup', rawKey);
mouse = new Mouse({'target': $D('canvas'),
document.addEventListener('keypress', rawKey);
document.addEventListener('keydown', rawKey);
document.addEventListener('keyup', rawKey);
mouse = new Mouse({'target': document.getElementById('canvas'),
'onMouseButton': mouseButton,
'onMouseMove': mouseMove});
@ -121,10 +121,10 @@
if ('ontouchstart' in document.documentElement) {
message("Touch device detected");
$D('button-selection').style.display = "inline";
$D('button1').onclick = function(){ selectButton(1) };
$D('button2').onclick = function(){ selectButton(2) };
$D('button4').onclick = function(){ selectButton(4) };
document.getElementById('button-selection').style.display = "inline";
document.getElementById('button1').onclick = function(){ selectButton(1) };
document.getElementById('button2').onclick = function(){ selectButton(2) };
document.getElementById('button4').onclick = function(){ selectButton(4) };
selectButton();
}

View File

@ -1,29 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link rel="stylesheet" href="node_modules/mocha/mocha.css" />
</head>
<body>
<!--
To run tests
cd .../noVNC/tests
npm install chai mocha
open keyboard-tests.html in a browser
-->
<div id="mocha"></div>
<script src="node_modules/chai/chai.js"></script>
<script src="node_modules/mocha/mocha.js"></script>
<script>mocha.setup('bdd')</script>
<script src="../include/keysymdef.js"></script>
<script src="../include/keyboard.js"></script>
<script src="test.keyboard.js"></script>
<script src="test.helper.js"></script>
<script>
mocha.checkLeaks();
mocha.globals(['navigator']);
mocha.run();
</script>
</body>
</html>

View File

@ -36,7 +36,7 @@ enable_test_mode = function () {
};
next_iteration = function () {
rfb = new RFB({'target': $D('VNC_canvas'),
rfb = new RFB({'target': document.getElementById('VNC_canvas'),
'onUpdateState': updateState});
enable_test_mode();

View File

@ -1,7 +1,7 @@
var Spooky = require('spooky');
var path = require('path');
var phantom_path = require('phantomjs').path;
var phantom_path = require('phantomjs-prebuilt').path;
var casper_path = path.resolve(__dirname, '../node_modules/casperjs/bin/casperjs');
process.env.PHANTOMJS_EXECUTABLE = phantom_path;
var casper_opts = {

View File

@ -67,7 +67,7 @@ if (all_js && !program.autoInject) {
var eol = content.indexOf('\n', ind);
var modules = content.slice(ind, eol).split(/,\s*/);
modules.forEach(function (mod) {
all_modules[get_path('include/', mod) + '.js'] = 1;
all_modules[get_path('core/', mod) + '.js'] = 1;
});
}
@ -92,7 +92,7 @@ if (program.autoInject) {
var template = {
header: "<html>\n<head>\n<meta charset='utf-8' />\n<link rel='stylesheet' href='" + get_path('node_modules/mocha/mocha.css') + "'/>\n</head>\n<body><div id='mocha'></div>",
script_tag: function(p) { return "<script src='" + p + "'></script>"; },
footer: "<script>\nmocha.checkLeaks();\nmocha.globals(['navigator', 'create', 'ClientUtils', '__utils__']);\nmocha.run(function () { window.__mocha_done = true; });\n</script>\n</body>\n</html>"
footer: "<script>\nmocha.checkLeaks();\nmocha.globals(['navigator', 'create', 'ClientUtils', '__utils__', 'requestAnimationFrame', 'WebSocket']);\nmocha.run(function () { window.__mocha_done = true; });\n</script>\n</body>\n</html>"
};
template.header += "\n" + template.script_tag(get_path('node_modules/chai/chai.js'));

View File

@ -1,53 +0,0 @@
/*
* Define some useful statistical functions on arrays of numbers
*/
Array.prototype.sum = function() {
var i, sum = 0;
for (i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
}
Array.prototype.max = function() {
return Math.max.apply(null, this);
}
Array.prototype.min = function() {
return Math.min.apply(null, this);
}
Array.prototype.mean = function() {
return this.sum() / this.length;
}
Array.prototype.average = Array.prototype.mean;
Array.prototype.median = function() {
var sorted = this.sort( function(a,b) { return a-b; }),
len = sorted.length;
if (len % 2) {
return sorted[Math.floor(len / 2)]; // Odd
} else {
return (sorted[len/2 - 1] + sorted[len/2]) / 2; // Even
}
}
Array.prototype.stdDev = function(sample) {
var i, sumSqr = 0, mean = this.mean(), N;
if (sample) {
// Population correction if this is a sample
N = this.length - 1;
} else {
// Standard deviation of just the array
N = this.length;
}
for (i = 0; i < this.length; i++) {
sumSqr += Math.pow(this[i] - mean, 2);
}
return Math.sqrt(sumSqr / N);
}

View File

@ -384,15 +384,15 @@ describe('Display/Canvas Helper', function () {
display = new Display({ target: document.createElement('canvas'), prefer_js: false });
display.resize(4, 4);
sinon.spy(display, '_scan_renderQ');
this.old_requestAnimFrame = window.requestAnimFrame;
window.requestAnimFrame = function (cb) {
this.old_requestAnimationFrame = window.requestAnimationFrame;
window.requestAnimationFrame = function (cb) {
this.next_frame_cb = cb;
}.bind(this);
this.next_frame = function () { this.next_frame_cb(); };
});
afterEach(function () {
window.requestAnimFrame = this.old_requestAnimFrame;
window.requestAnimationFrame = this.old_requestAnimationFrame;
});
it('should try to process an item when it is pushed on, if nothing else is on the queue', function () {

View File

@ -1,4 +1,4 @@
// requires local modules: keysym, keysymdef, keyboard
// requires local modules: input/keysym, input/keysymdef, input/util
var assert = chai.assert;
var expect = chai.expect;
@ -7,18 +7,18 @@ describe('Helpers', function() {
"use strict";
describe('keysymFromKeyCode', function() {
it('should map known keycodes to keysyms', function() {
expect(kbdUtil.keysymFromKeyCode(0x41, false), 'a').to.be.equal(0x61);
expect(kbdUtil.keysymFromKeyCode(0x41, true), 'A').to.be.equal(0x41);
expect(kbdUtil.keysymFromKeyCode(0xd, false), 'enter').to.be.equal(0xFF0D);
expect(kbdUtil.keysymFromKeyCode(0x11, false), 'ctrl').to.be.equal(0xFFE3);
expect(kbdUtil.keysymFromKeyCode(0x12, false), 'alt').to.be.equal(0xFFE9);
expect(kbdUtil.keysymFromKeyCode(0xe1, false), 'altgr').to.be.equal(0xFE03);
expect(kbdUtil.keysymFromKeyCode(0x1b, false), 'esc').to.be.equal(0xFF1B);
expect(kbdUtil.keysymFromKeyCode(0x26, false), 'up').to.be.equal(0xFF52);
expect(KeyboardUtil.keysymFromKeyCode(0x41, false), 'a').to.be.equal(0x61);
expect(KeyboardUtil.keysymFromKeyCode(0x41, true), 'A').to.be.equal(0x41);
expect(KeyboardUtil.keysymFromKeyCode(0xd, false), 'enter').to.be.equal(0xFF0D);
expect(KeyboardUtil.keysymFromKeyCode(0x11, false), 'ctrl').to.be.equal(0xFFE3);
expect(KeyboardUtil.keysymFromKeyCode(0x12, false), 'alt').to.be.equal(0xFFE9);
expect(KeyboardUtil.keysymFromKeyCode(0xe1, false), 'altgr').to.be.equal(0xFE03);
expect(KeyboardUtil.keysymFromKeyCode(0x1b, false), 'esc').to.be.equal(0xFF1B);
expect(KeyboardUtil.keysymFromKeyCode(0x26, false), 'up').to.be.equal(0xFF52);
});
it('should return null for unknown keycodes', function() {
expect(kbdUtil.keysymFromKeyCode(0xc0, false), 'DK æ').to.be.null;
expect(kbdUtil.keysymFromKeyCode(0xde, false), 'DK ø').to.be.null;
expect(KeyboardUtil.keysymFromKeyCode(0xc0, false), 'DK æ').to.be.null;
expect(KeyboardUtil.keysymFromKeyCode(0xde, false), 'DK ø').to.be.null;
});
});
@ -46,59 +46,59 @@ describe('Helpers', function() {
describe('substituteCodepoint', function() {
it('should replace characters which don\'t have a keysym', function() {
expect(kbdUtil.substituteCodepoint('Ș'.charCodeAt())).to.equal('Ş'.charCodeAt());
expect(kbdUtil.substituteCodepoint('ș'.charCodeAt())).to.equal('ş'.charCodeAt());
expect(kbdUtil.substituteCodepoint('Ț'.charCodeAt())).to.equal('Ţ'.charCodeAt());
expect(kbdUtil.substituteCodepoint('ț'.charCodeAt())).to.equal('ţ'.charCodeAt());
expect(KeyboardUtil.substituteCodepoint('Ș'.charCodeAt())).to.equal('Ş'.charCodeAt());
expect(KeyboardUtil.substituteCodepoint('ș'.charCodeAt())).to.equal('ş'.charCodeAt());
expect(KeyboardUtil.substituteCodepoint('Ț'.charCodeAt())).to.equal('Ţ'.charCodeAt());
expect(KeyboardUtil.substituteCodepoint('ț'.charCodeAt())).to.equal('ţ'.charCodeAt());
});
it('should pass other characters through unchanged', function() {
expect(kbdUtil.substituteCodepoint('T'.charCodeAt())).to.equal('T'.charCodeAt());
expect(KeyboardUtil.substituteCodepoint('T'.charCodeAt())).to.equal('T'.charCodeAt());
});
});
describe('nonCharacterKey', function() {
it('should recognize the right keys', function() {
expect(kbdUtil.nonCharacterKey({keyCode: 0xd}), 'enter').to.be.defined;
expect(kbdUtil.nonCharacterKey({keyCode: 0x08}), 'backspace').to.be.defined;
expect(kbdUtil.nonCharacterKey({keyCode: 0x09}), 'tab').to.be.defined;
expect(kbdUtil.nonCharacterKey({keyCode: 0x10}), 'shift').to.be.defined;
expect(kbdUtil.nonCharacterKey({keyCode: 0x11}), 'ctrl').to.be.defined;
expect(kbdUtil.nonCharacterKey({keyCode: 0x12}), 'alt').to.be.defined;
expect(kbdUtil.nonCharacterKey({keyCode: 0xe0}), 'meta').to.be.defined;
expect(KeyboardUtil.nonCharacterKey({keyCode: 0xd}), 'enter').to.be.defined;
expect(KeyboardUtil.nonCharacterKey({keyCode: 0x08}), 'backspace').to.be.defined;
expect(KeyboardUtil.nonCharacterKey({keyCode: 0x09}), 'tab').to.be.defined;
expect(KeyboardUtil.nonCharacterKey({keyCode: 0x10}), 'shift').to.be.defined;
expect(KeyboardUtil.nonCharacterKey({keyCode: 0x11}), 'ctrl').to.be.defined;
expect(KeyboardUtil.nonCharacterKey({keyCode: 0x12}), 'alt').to.be.defined;
expect(KeyboardUtil.nonCharacterKey({keyCode: 0xe0}), 'meta').to.be.defined;
});
it('should not recognize character keys', function() {
expect(kbdUtil.nonCharacterKey({keyCode: 'A'}), 'A').to.be.null;
expect(kbdUtil.nonCharacterKey({keyCode: '1'}), '1').to.be.null;
expect(kbdUtil.nonCharacterKey({keyCode: '.'}), '.').to.be.null;
expect(kbdUtil.nonCharacterKey({keyCode: ' '}), 'space').to.be.null;
expect(KeyboardUtil.nonCharacterKey({keyCode: 'A'}), 'A').to.be.null;
expect(KeyboardUtil.nonCharacterKey({keyCode: '1'}), '1').to.be.null;
expect(KeyboardUtil.nonCharacterKey({keyCode: '.'}), '.').to.be.null;
expect(KeyboardUtil.nonCharacterKey({keyCode: ' '}), 'space').to.be.null;
});
});
describe('getKeysym', function() {
it('should prefer char', function() {
expect(kbdUtil.getKeysym({char : 'a', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x61);
expect(KeyboardUtil.getKeysym({char : 'a', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x61);
});
it('should use charCode if no char', function() {
expect(kbdUtil.getKeysym({char : '', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x01a9);
expect(kbdUtil.getKeysym({charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x01a9);
expect(kbdUtil.getKeysym({char : 'hello', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x01a9);
expect(KeyboardUtil.getKeysym({char : '', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x01a9);
expect(KeyboardUtil.getKeysym({charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x01a9);
expect(KeyboardUtil.getKeysym({char : 'hello', charCode: 'Š'.charCodeAt(), keyCode: 0x42, which: 0x43})).to.have.property('keysym', 0x01a9);
});
it('should use keyCode if no charCode', function() {
expect(kbdUtil.getKeysym({keyCode: 0x42, which: 0x43, shiftKey: false})).to.have.property('keysym', 0x62);
expect(kbdUtil.getKeysym({keyCode: 0x42, which: 0x43, shiftKey: true})).to.have.property('keysym', 0x42);
expect(KeyboardUtil.getKeysym({keyCode: 0x42, which: 0x43, shiftKey: false})).to.have.property('keysym', 0x62);
expect(KeyboardUtil.getKeysym({keyCode: 0x42, which: 0x43, shiftKey: true})).to.have.property('keysym', 0x42);
});
it('should use which if no keyCode', function() {
expect(kbdUtil.getKeysym({which: 0x43, shiftKey: false})).to.have.property('keysym', 0x63);
expect(kbdUtil.getKeysym({which: 0x43, shiftKey: true})).to.have.property('keysym', 0x43);
expect(KeyboardUtil.getKeysym({which: 0x43, shiftKey: false})).to.have.property('keysym', 0x63);
expect(KeyboardUtil.getKeysym({which: 0x43, shiftKey: true})).to.have.property('keysym', 0x43);
});
it('should substitute where applicable', function() {
expect(kbdUtil.getKeysym({char : 'Ș'})).to.have.property('keysym', 0x1aa);
expect(KeyboardUtil.getKeysym({char : 'Ș'})).to.have.property('keysym', 0x1aa);
});
});
describe('Modifier Sync', function() { // return a list of fake events necessary to fix modifier state
describe('Toggle all modifiers', function() {
var sync = kbdUtil.ModifierSync();
var sync = KeyboardUtil.ModifierSync();
it ('should do nothing if all modifiers are up as expected', function() {
expect(sync.keydown({
keyCode: 0x41,
@ -141,7 +141,7 @@ describe('Helpers', function() {
});
});
describe('Toggle Ctrl', function() {
var sync = kbdUtil.ModifierSync();
var sync = KeyboardUtil.ModifierSync();
it('should sync if modifier is suddenly down', function() {
expect(sync.keydown({
keyCode: 0x41,
@ -156,7 +156,7 @@ describe('Helpers', function() {
});
});
describe('Toggle Alt', function() {
var sync = kbdUtil.ModifierSync();
var sync = KeyboardUtil.ModifierSync();
it('should sync if modifier is suddenly down', function() {
expect(sync.keydown({
keyCode: 0x41,
@ -171,7 +171,7 @@ describe('Helpers', function() {
});
});
describe('Toggle AltGr', function() {
var sync = kbdUtil.ModifierSync();
var sync = KeyboardUtil.ModifierSync();
it('should sync if modifier is suddenly down', function() {
expect(sync.keydown({
keyCode: 0x41,
@ -186,7 +186,7 @@ describe('Helpers', function() {
});
});
describe('Toggle Shift', function() {
var sync = kbdUtil.ModifierSync();
var sync = KeyboardUtil.ModifierSync();
it('should sync if modifier is suddenly down', function() {
expect(sync.keydown({
keyCode: 0x41,
@ -201,7 +201,7 @@ describe('Helpers', function() {
});
});
describe('Toggle Meta', function() {
var sync = kbdUtil.ModifierSync();
var sync = KeyboardUtil.ModifierSync();
it('should sync if modifier is suddenly down', function() {
expect(sync.keydown({
keyCode: 0x41,
@ -217,17 +217,17 @@ describe('Helpers', function() {
});
describe('Modifier keyevents', function() {
it('should not sync a modifier on its own events', function() {
expect(kbdUtil.ModifierSync().keydown({
expect(KeyboardUtil.ModifierSync().keydown({
keyCode: 0x11,
ctrlKey: false
})).to.be.deep.equal([]);
expect(kbdUtil.ModifierSync().keydown({
expect(KeyboardUtil.ModifierSync().keydown({
keyCode: 0x11,
ctrlKey: true
}), 'B').to.be.deep.equal([]);
})
it('should update state on modifier keyevents', function() {
var sync = kbdUtil.ModifierSync();
var sync = KeyboardUtil.ModifierSync();
sync.keydown({
keyCode: 0x11,
});
@ -237,7 +237,7 @@ describe('Helpers', function() {
})).to.be.deep.equal([]);
});
it('should sync other modifiers on ctrl events', function() {
expect(kbdUtil.ModifierSync().keydown({
expect(KeyboardUtil.ModifierSync().keydown({
keyCode: 0x11,
altKey: true
})).to.be.deep.equal([{keysym: keysyms.lookup(0xffe9), type: 'keydown'}]);
@ -245,17 +245,17 @@ describe('Helpers', function() {
});
describe('sync modifiers on non-key events', function() {
it('should generate sync events when receiving non-keyboard events', function() {
expect(kbdUtil.ModifierSync().syncAny({
expect(KeyboardUtil.ModifierSync().syncAny({
altKey: true
})).to.be.deep.equal([{keysym: keysyms.lookup(0xffe9), type: 'keydown'}]);
});
});
describe('do not treat shift as a modifier key', function() {
it('should not treat shift as a shortcut modifier', function() {
expect(kbdUtil.hasShortcutModifier([], {0xffe1 : true})).to.be.false;
expect(KeyboardUtil.hasShortcutModifier([], {0xffe1 : true})).to.be.false;
});
it('should not treat shift as a char modifier', function() {
expect(kbdUtil.hasCharModifier([], {0xffe1 : true})).to.be.false;
expect(KeyboardUtil.hasCharModifier([], {0xffe1 : true})).to.be.false;
});
});
});

View File

@ -1,4 +1,4 @@
// requires local modules: input, keyboard, keysymdef
// requires local modules: input/devices, input/util, input/keysymdef, input/keysym
var assert = chai.assert;
var expect = chai.expect;
@ -7,19 +7,19 @@ describe('Key Event Pipeline Stages', function() {
"use strict";
describe('Decode Keyboard Events', function() {
it('should pass events to the next stage', function(done) {
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt).to.be.an.object;
done();
}).keydown({keyCode: 0x41});
});
it('should pass the right keysym through', function(done) {
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt.keysym).to.be.deep.equal(keysyms.lookup(0x61));
done();
}).keypress({keyCode: 0x41});
});
it('should pass the right keyid through', function(done) {
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt).to.have.property('keyId', 0x41);
done();
}).keydown({keyCode: 0x41});
@ -27,14 +27,14 @@ describe('Key Event Pipeline Stages', function() {
it('should not sync modifiers on a keypress', function() {
// Firefox provides unreliable modifier state on keypress events
var count = 0;
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
++count;
}).keypress({keyCode: 0x41, ctrlKey: true});
expect(count).to.be.equal(1);
});
it('should sync modifiers if necessary', function(done) {
var count = 0;
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
switch (count) {
case 0: // fake a ctrl keydown
expect(evt).to.be.deep.equal({keysym: keysyms.lookup(0xffe3), type: 'keydown'});
@ -48,26 +48,26 @@ describe('Key Event Pipeline Stages', function() {
}).keydown({keyCode: 0x41, ctrlKey: true});
});
it('should forward keydown events with the right type', function(done) {
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt).to.be.deep.equal({keyId: 0x41, type: 'keydown'});
done();
}).keydown({keyCode: 0x41});
});
it('should forward keyup events with the right type', function(done) {
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keyup'});
done();
}).keyup({keyCode: 0x41});
});
it('should forward keypress events with the right type', function(done) {
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keypress'});
done();
}).keypress({keyCode: 0x41});
});
it('should generate stalls if a char modifier is down while a key is pressed', function(done) {
var count = 0;
KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
switch (count) {
case 0: // fake altgr
expect(evt).to.be.deep.equal({keysym: keysyms.lookup(0xfe03), type: 'keydown'});
@ -92,7 +92,7 @@ describe('Key Event Pipeline Stages', function() {
});
describe('suppress the right events at the right time', function() {
it('should suppress anything while a shortcut modifier is down', function() {
var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {});
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {});
obj.keydown({keyCode: 0x11}); // press ctrl
expect(obj.keydown({keyCode: 'A'.charCodeAt()})).to.be.true;
@ -102,7 +102,7 @@ describe('Key Event Pipeline Stages', function() {
expect(obj.keydown({keyCode: 0xde})).to.be.true; // Ø key on DK
});
it('should suppress non-character keys', function() {
var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {});
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {});
expect(obj.keydown({keyCode: 0x08}), 'a').to.be.true;
expect(obj.keydown({keyCode: 0x09}), 'b').to.be.true;
@ -110,20 +110,20 @@ describe('Key Event Pipeline Stages', function() {
expect(obj.keydown({keyCode: 0x12}), 'e').to.be.true;
});
it('should not suppress shift', function() {
var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {});
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {});
expect(obj.keydown({keyCode: 0x10}), 'd').to.be.false;
});
it('should generate event for shift keydown', function() {
var called = false;
var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt).to.have.property('keysym');
called = true;
}).keydown({keyCode: 0x10});
expect(called).to.be.true;
});
it('should not suppress character keys', function() {
var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {});
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {});
expect(obj.keydown({keyCode: 'A'.charCodeAt()})).to.be.false;
expect(obj.keydown({keyCode: ' '.charCodeAt()})).to.be.false;
@ -132,7 +132,7 @@ describe('Key Event Pipeline Stages', function() {
expect(obj.keydown({keyCode: 0xde})).to.be.false; // Ø key on DK
});
it('should not suppress if a char modifier is down', function() {
var obj = KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {});
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {});
obj.keydown({keyCode: 0xe1}); // press altgr
expect(obj.keydown({keyCode: 'A'.charCodeAt()})).to.be.false;
@ -144,7 +144,7 @@ describe('Key Event Pipeline Stages', function() {
});
describe('Keypress and keyup events', function() {
it('should always suppress event propagation', function() {
var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {});
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {});
expect(obj.keypress({keyCode: 'A'.charCodeAt()})).to.be.true;
expect(obj.keypress({keyCode: 0x3c})).to.be.true; // < key on DK Windows
@ -155,7 +155,7 @@ describe('Key Event Pipeline Stages', function() {
expect(obj.keyup({keyCode: 0x11})).to.be.true;
});
it('should never generate stalls', function() {
var obj = KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt.type).to.not.be.equal('stall');
});
@ -171,7 +171,7 @@ describe('Key Event Pipeline Stages', function() {
describe('mark events if a char modifier is down', function() {
it('should not mark modifiers on a keydown event', function() {
var times_called = 0;
var obj = KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
switch (times_called++) {
case 0: //altgr
break;
@ -187,7 +187,7 @@ describe('Key Event Pipeline Stages', function() {
it('should indicate on events if a single-key char modifier is down', function(done) {
var times_called = 0;
var obj = KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
switch (times_called++) {
case 0: //altgr
break;
@ -208,7 +208,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should indicate on events if a multi-key char modifier is down', function(done) {
var times_called = 0;
var obj = KeyEventDecoder(kbdUtil.ModifierSync([0xffe9, 0xffe3]), function(evt) {
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xffe9, 0xffe3]), function(evt) {
switch (times_called++) {
case 0: //ctrl
break;
@ -231,7 +231,7 @@ describe('Key Event Pipeline Stages', function() {
obj.keypress({keyCode: 'A'.charCodeAt()});
});
it('should not consider a char modifier to be down on the modifier key itself', function() {
var obj = KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {
var obj = KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
expect(evt).to.not.have.property('escape');
});
@ -241,13 +241,13 @@ describe('Key Event Pipeline Stages', function() {
});
describe('add/remove keysym', function() {
it('should remove keysym from keydown if a char key and no modifier', function() {
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt).to.be.deep.equal({keyId: 0x41, type: 'keydown'});
}).keydown({keyCode: 0x41});
});
it('should not remove keysym from keydown if a shortcut modifier is down', function() {
var times_called = 0;
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
switch (times_called++) {
case 1:
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keydown'});
@ -258,7 +258,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should not remove keysym from keydown if a char modifier is down', function() {
var times_called = 0;
KeyEventDecoder(kbdUtil.ModifierSync([0xfe03]), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync([0xfe03]), function(evt) {
switch (times_called++) {
case 2:
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keydown'});
@ -268,21 +268,21 @@ describe('Key Event Pipeline Stages', function() {
expect(times_called).to.be.equal(3);
});
it('should not remove keysym from keydown if key is noncharacter', function() {
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt, 'bacobjpace').to.be.deep.equal({keyId: 0x09, keysym: keysyms.lookup(0xff09), type: 'keydown'});
}).keydown({keyCode: 0x09});
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt, 'ctrl').to.be.deep.equal({keyId: 0x11, keysym: keysyms.lookup(0xffe3), type: 'keydown'});
}).keydown({keyCode: 0x11});
});
it('should never remove keysym from keypress', function() {
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keypress'});
}).keypress({keyCode: 0x41});
});
it('should never remove keysym from keyup', function() {
KeyEventDecoder(kbdUtil.ModifierSync(), function(evt) {
KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), function(evt) {
expect(evt).to.be.deep.equal({keyId: 0x41, keysym: keysyms.lookup(0x61), type: 'keyup'});
}).keyup({keyCode: 0x41});
});
@ -293,25 +293,25 @@ describe('Key Event Pipeline Stages', function() {
describe('Verify that char modifiers are active', function() {
it('should pass keydown events through if there is no stall', function(done) {
var obj = VerifyCharModifier(function(evt){
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x41)});
done();
})({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x41)});
});
it('should pass keyup events through if there is no stall', function(done) {
var obj = VerifyCharModifier(function(evt){
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
expect(evt).to.deep.equal({type: 'keyup', keyId: 0x41, keysym: keysyms.lookup(0x41)});
done();
})({type: 'keyup', keyId: 0x41, keysym: keysyms.lookup(0x41)});
});
it('should pass keypress events through if there is no stall', function(done) {
var obj = VerifyCharModifier(function(evt){
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
expect(evt).to.deep.equal({type: 'keypress', keyId: 0x41, keysym: keysyms.lookup(0x41)});
done();
})({type: 'keypress', keyId: 0x41, keysym: keysyms.lookup(0x41)});
});
it('should not pass stall events through', function(done){
var obj = VerifyCharModifier(function(evt){
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
// should only be called once, for the keydown
expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x41)});
done();
@ -322,7 +322,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should merge keydown and keypress events if they come after a stall', function(done) {
var next_called = false;
var obj = VerifyCharModifier(function(evt){
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
// should only be called once, for the keydown
expect(next_called).to.be.false;
next_called = true;
@ -337,7 +337,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should preserve modifier attribute when merging if keysyms differ', function(done) {
var next_called = false;
var obj = VerifyCharModifier(function(evt){
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
// should only be called once, for the keydown
expect(next_called).to.be.false;
next_called = true;
@ -351,7 +351,7 @@ describe('Key Event Pipeline Stages', function() {
expect(next_called).to.be.false;
});
it('should not preserve modifier attribute when merging if keysyms are the same', function() {
var obj = VerifyCharModifier(function(evt){
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
expect(evt).to.not.have.property('escape');
});
@ -361,7 +361,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should not merge keydown and keypress events if there is no stall', function(done) {
var times_called = 0;
var obj = VerifyCharModifier(function(evt){
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
switch(times_called) {
case 0:
expect(evt).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
@ -380,7 +380,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should not merge keydown and keypress events if separated by another event', function(done) {
var times_called = 0;
var obj = VerifyCharModifier(function(evt){
var obj = KeyboardUtil.VerifyCharModifier(function(evt){
switch(times_called) {
case 0:
expect(evt,1).to.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
@ -406,7 +406,7 @@ describe('Key Event Pipeline Stages', function() {
describe('Track Key State', function() {
it('should do nothing on keyup events if no keys are down', function() {
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
expect(true).to.be.false;
});
obj({type: 'keyup', keyId: 0x41});
@ -415,7 +415,7 @@ describe('Key Event Pipeline Stages', function() {
var times_called = 0;
var elem = null;
var keysymsdown = {};
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
++times_called;
if (elem.type == 'keyup') {
expect(evt).to.have.property('keysym');
@ -443,7 +443,7 @@ describe('Key Event Pipeline Stages', function() {
var times_called = 0;
var elem = null;
var keysymsdown = {};
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
++times_called;
if (elem.type == 'keyup') {
expect(evt).to.have.property('keysym');
@ -472,7 +472,7 @@ describe('Key Event Pipeline Stages', function() {
var times_called = 0;
var elem = null;
var keysymsdown = {};
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
++times_called;
if (elem.type == 'keyup') {
expect(evt).to.have.property('keysym');
@ -504,7 +504,7 @@ describe('Key Event Pipeline Stages', function() {
var times_called = 0;
var elem = null;
var keysymsdown = {};
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
++times_called;
if (elem.type == 'keyup') {
expect(evt).to.have.property('keysym');
@ -540,7 +540,7 @@ describe('Key Event Pipeline Stages', function() {
var times_called = 0;
var elem = null;
var keysymsdown = {};
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
++times_called;
if (elem.type == 'keyup') {
expect(evt).to.have.property('keysym');
@ -573,7 +573,7 @@ describe('Key Event Pipeline Stages', function() {
var times_called = 0;
var elem = null;
var keysymsdown = {};
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
++times_called;
if (elem.type == 'keyup') {
expect(evt).to.have.property('keysym');
@ -608,7 +608,7 @@ describe('Key Event Pipeline Stages', function() {
var times_called = 0;
var elem = null;
var keysymsdown = {};
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
++times_called;
if (elem.type == 'keyup') {
expect(evt).to.have.property('keysym');
@ -644,7 +644,7 @@ describe('Key Event Pipeline Stages', function() {
var times_called = 0;
var elem = null;
var keysymsdown = {};
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
++times_called;
if (elem.type == 'keyup') {
expect(evt).to.have.property('keysym');
@ -676,7 +676,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should pop matching key event on keyup', function() {
var times_called = 0;
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
switch (times_called++) {
case 0:
case 1:
@ -697,7 +697,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should pop the first zero keyevent on keyup with zero keyId', function() {
var times_called = 0;
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
switch (times_called++) {
case 0:
case 1:
@ -718,7 +718,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should pop the last keyevents keysym if no match is found for keyId', function() {
var times_called = 0;
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
switch (times_called++) {
case 0:
case 1:
@ -740,7 +740,7 @@ describe('Key Event Pipeline Stages', function() {
describe('Firefox sends keypress even when keydown is suppressed', function() {
it('should discard the keypress', function() {
var times_called = 0;
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
expect(times_called).to.be.equal(0);
++times_called;
});
@ -753,7 +753,7 @@ describe('Key Event Pipeline Stages', function() {
describe('releaseAll', function() {
it('should do nothing if no keys have been pressed', function() {
var times_called = 0;
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
++times_called;
});
obj({type: 'releaseall'});
@ -761,7 +761,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should release the keys that have been pressed', function() {
var times_called = 0;
var obj = TrackKeyState(function(evt) {
var obj = KeyboardUtil.TrackKeyState(function(evt) {
switch (times_called++) {
case 2:
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: keysyms.lookup(0x41)});
@ -787,7 +787,7 @@ describe('Key Event Pipeline Stages', function() {
describe('Keydown', function() {
it('should pass through when a char modifier is not down', function() {
var times_called = 0;
EscapeModifiers(function(evt) {
KeyboardUtil.EscapeModifiers(function(evt) {
expect(times_called).to.be.equal(0);
++times_called;
expect(evt).to.be.deep.equal({type: 'keydown', keyId: 0x41, keysym: keysyms.lookup(0x42)});
@ -796,7 +796,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should generate fake undo/redo events when a char modifier is down', function() {
var times_called = 0;
EscapeModifiers(function(evt) {
KeyboardUtil.EscapeModifiers(function(evt) {
switch(times_called++) {
case 0:
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0, keysym: keysyms.lookup(0xffe9)});
@ -821,7 +821,7 @@ describe('Key Event Pipeline Stages', function() {
describe('Keyup', function() {
it('should pass through when a char modifier is down', function() {
var times_called = 0;
EscapeModifiers(function(evt) {
KeyboardUtil.EscapeModifiers(function(evt) {
expect(times_called).to.be.equal(0);
++times_called;
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0x41, keysym: keysyms.lookup(0x42), escape: [0xfe03]});
@ -830,7 +830,7 @@ describe('Key Event Pipeline Stages', function() {
});
it('should pass through when a char modifier is not down', function() {
var times_called = 0;
EscapeModifiers(function(evt) {
KeyboardUtil.EscapeModifiers(function(evt) {
expect(times_called).to.be.equal(0);
++times_called;
expect(evt).to.be.deep.equal({type: 'keyup', keyId: 0x41, keysym: keysyms.lookup(0x42)});

View File

@ -1,4 +1,4 @@
// requires local modules: util, websock, rfb, keyboard, keysym, keysymdef, input, inflator, des, display
// requires local modules: util, websock, rfb, input/util, input/keysym, input/keysymdef, input/devices, inflator, des, display
// requires test modules: fake.websocket, assertions
/* jshint expr: true */
var assert = chai.assert;
@ -13,6 +13,25 @@ function make_rfb (extra_opts) {
return new RFB(extra_opts);
}
var push8 = function (arr, num) {
"use strict";
arr.push(num & 0xFF);
};
var push16 = function (arr, num) {
"use strict";
arr.push((num >> 8) & 0xFF,
num & 0xFF);
};
var push32 = function (arr, num) {
"use strict";
arr.push((num >> 24) & 0xFF,
(num >> 16) & 0xFF,
(num >> 8) & 0xFF,
num & 0xFF);
};
describe('Remote Frame Buffer Protocol Client', function() {
"use strict";
before(FakeWebSocket.replace);
@ -232,17 +251,17 @@ describe('Remote Frame Buffer Protocol Client', function() {
it('should send the request with the given width and height', function () {
var expected = [251];
expected.push8(0); // padding
expected.push16(1); // width
expected.push16(2); // height
expected.push8(1); // number-of-screens
expected.push8(0); // padding before screen array
expected.push32(0); // id
expected.push16(0); // x-position
expected.push16(0); // y-position
expected.push16(1); // width
expected.push16(2); // height
expected.push32(0); // flags
push8(expected, 0); // padding
push16(expected, 1); // width
push16(expected, 2); // height
push8(expected, 1); // number-of-screens
push8(expected, 0); // padding before screen array
push32(expected, 0); // id
push16(expected, 0); // x-position
push16(expected, 0); // y-position
push16(expected, 1); // width
push16(expected, 2); // height
push32(expected, 0); // flags
client.requestDesktopSize(1, 2);
expect(client._sock).to.have.sent(new Uint8Array(expected));
@ -662,7 +681,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
var err_msg = "Whoopsies";
var data = [0, 0, 0, 0];
var err_len = err_msg.length;
data.push32(err_len);
push32(data, err_len);
for (var i = 0; i < err_len; i++) {
data.push(err_msg.charCodeAt(i));
}
@ -796,10 +815,10 @@ describe('Remote Frame Buffer Protocol Client', function() {
function send_num_str_pairs(pairs, client) {
var pairs_len = pairs.length;
var data = [];
data.push32(pairs_len);
push32(data, pairs_len);
for (var i = 0; i < pairs_len; i++) {
data.push32(pairs[i][0]);
push32(data, pairs[i][0]);
var j;
for (j = 0; j < 4; j++) {
data.push(pairs[i][1].charCodeAt(j));
@ -948,30 +967,30 @@ describe('Remote Frame Buffer Protocol Client', function() {
}
var data = [];
data.push16(full_opts.width);
data.push16(full_opts.height);
push16(data, full_opts.width);
push16(data, full_opts.height);
data.push(full_opts.bpp);
data.push(full_opts.depth);
data.push(full_opts.big_endian);
data.push(full_opts.true_color);
data.push16(full_opts.red_max);
data.push16(full_opts.green_max);
data.push16(full_opts.blue_max);
data.push8(full_opts.red_shift);
data.push8(full_opts.green_shift);
data.push8(full_opts.blue_shift);
push16(data, full_opts.red_max);
push16(data, full_opts.green_max);
push16(data, full_opts.blue_max);
push8(data, full_opts.red_shift);
push8(data, full_opts.green_shift);
push8(data, full_opts.blue_shift);
// padding
data.push8(0);
data.push8(0);
data.push8(0);
push8(data, 0);
push8(data, 0);
push8(data, 0);
client._sock._websocket._receive_data(new Uint8Array(data));
var name_data = [];
name_data.push32(full_opts.name.length);
push32(name_data, full_opts.name.length);
for (var i = 0; i < full_opts.name.length; i++) {
name_data.push(full_opts.name.charCodeAt(i));
}
@ -1003,10 +1022,10 @@ describe('Remote Frame Buffer Protocol Client', function() {
send_server_init({}, client);
var tight_data = [];
tight_data.push16(1);
tight_data.push16(2);
tight_data.push16(3);
tight_data.push16(0);
push16(tight_data, 1);
push16(tight_data, 2);
push16(tight_data, 3);
push16(tight_data, 0);
for (var i = 0; i < 16 + 32 + 48; i++) {
tight_data.push(i);
}
@ -1136,16 +1155,16 @@ describe('Remote Frame Buffer Protocol Client', function() {
// header
data.push(0); // msg type
data.push(0); // padding
data.push16(rect_cnt || rect_data.length);
push16(data, rect_cnt || rect_data.length);
}
for (var i = 0; i < rect_data.length; i++) {
if (rect_info[i]) {
data.push16(rect_info[i].x);
data.push16(rect_info[i].y);
data.push16(rect_info[i].width);
data.push16(rect_info[i].height);
data.push32(rect_info[i].encoding);
push16(data, rect_info[i].x);
push16(data, rect_info[i].y);
push16(data, rect_info[i].width);
push16(data, rect_info[i].height);
push32(data, rect_info[i].encoding);
}
data = data.concat(rect_data[i]);
}
@ -1339,24 +1358,24 @@ describe('Remote Frame Buffer Protocol Client', function() {
it('should handle the RRE encoding', function () {
var info = [{ x: 0, y: 0, width: 4, height: 4, encoding: 0x02 }];
var rect = [];
rect.push32(2); // 2 subrects
rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
push32(rect, 2); // 2 subrects
push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
rect.push(0xff); // becomes ff0000ff --> #0000FF color
rect.push(0x00);
rect.push(0x00);
rect.push(0xff);
rect.push16(0); // x: 0
rect.push16(0); // y: 0
rect.push16(2); // width: 2
rect.push16(2); // height: 2
push16(rect, 0); // x: 0
push16(rect, 0); // y: 0
push16(rect, 2); // width: 2
push16(rect, 2); // height: 2
rect.push(0xff); // becomes ff0000ff --> #0000FF color
rect.push(0x00);
rect.push(0x00);
rect.push(0xff);
rect.push16(2); // x: 2
rect.push16(2); // y: 2
rect.push16(2); // width: 2
rect.push16(2); // height: 2
push16(rect, 2); // x: 2
push16(rect, 2); // y: 2
push16(rect, 2); // width: 2
push16(rect, 2); // height: 2
send_fbu_msg(info, [rect], client);
expect(client._display).to.have.displayed(target_data_check);
@ -1384,7 +1403,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
var info = [{ x: 0, y: 0, width: 4, height: 4, encoding: 0x05 }];
var rect = [];
rect.push(0x02 | 0x04 | 0x08); // bg spec, fg spec, anysubrects
rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
rect.push(0xff); // becomes ff0000ff --> #0000FF fg color
rect.push(0x00);
rect.push(0x00);
@ -1416,11 +1435,11 @@ describe('Remote Frame Buffer Protocol Client', function() {
var info = [{ x: 0, y: 0, width: 4, height: 4, encoding: 0x05 }];
var rect = [];
rect.push(0x02);
rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
send_fbu_msg(info, [rect], client);
var expected = [];
for (var i = 0; i < 16; i++) { expected.push32(0xff00ff); }
for (var i = 0; i < 16; i++) { push32(expected, 0xff00ff); }
expect(client._display).to.have.displayed(new Uint8Array(expected));
});
@ -1436,7 +1455,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
// send a bg frame
rect.push(0x02);
rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
// send an empty frame
rect.push(0x00);
@ -1445,8 +1464,8 @@ describe('Remote Frame Buffer Protocol Client', function() {
var expected = [];
var i;
for (i = 0; i < 16; i++) { expected.push32(0xff00ff); } // rect 1: solid
for (i = 0; i < 16; i++) { expected.push32(0xff00ff); } // rect 2: same bkground color
for (i = 0; i < 16; i++) { push32(expected, 0xff00ff); } // rect 1: solid
for (i = 0; i < 16; i++) { push32(expected, 0xff00ff); } // rect 2: same bkground color
expect(client._display).to.have.displayed(new Uint8Array(expected));
});
@ -1454,7 +1473,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
var info = [{ x: 0, y: 0, width: 4, height: 4, encoding: 0x05 }];
var rect = [];
rect.push(0x02 | 0x08 | 0x10); // bg spec, anysubrects, colouredsubrects
rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
rect.push(2); // 2 subrects
rect.push(0xff); // becomes ff0000ff --> #0000FF fg color
rect.push(0x00);
@ -1480,7 +1499,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
var info = [{ x: 0, y: 0, width: 4, height: 17, encoding: 0x05}];
var rect = [];
rect.push(0x02 | 0x04 | 0x08); // bg spec, fg spec, anysubrects
rect.push32(0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
push32(rect, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
rect.push(0xff); // becomes ff0000ff --> #0000FF fg color
rect.push(0x00);
rect.push(0x00);
@ -1561,16 +1580,16 @@ describe('Remote Frame Buffer Protocol Client', function() {
function make_screen_data (nr_of_screens) {
var data = [];
data.push8(nr_of_screens); // number-of-screens
data.push8(0); // padding
data.push16(0); // padding
push8(data, nr_of_screens); // number-of-screens
push8(data, 0); // padding
push16(data, 0); // padding
for (var i=0; i<nr_of_screens; i += 1) {
data.push32(0); // id
data.push16(0); // x-position
data.push16(0); // y-position
data.push16(20); // width
data.push16(50); // height
data.push32(0); // flags
push32(data, 0); // id
push16(data, 0); // x-position
push16(data, 0); // y-position
push16(data, 20); // width
push16(data, 50); // height
push32(data, 0); // flags
}
return data;
}
@ -1672,9 +1691,9 @@ describe('Remote Frame Buffer Protocol Client', function() {
var i;
for (i = 0; i < 4; i++) {
expected_cm[i + 1] = [i * 10, i * 10 + 1, i * 10 + 2];
data.push16(expected_cm[i + 1][2] << 8);
data.push16(expected_cm[i + 1][1] << 8);
data.push16(expected_cm[i + 1][0] << 8);
push16(data, expected_cm[i + 1][2] << 8);
push16(data, expected_cm[i + 1][1] << 8);
push16(data, expected_cm[i + 1][0] << 8);
}
client._sock._websocket._receive_data(new Uint8Array(data));
@ -1716,7 +1735,7 @@ describe('Remote Frame Buffer Protocol Client', function() {
it('should fire the clipboard callback with the retrieved text on ServerCutText', function () {
var expected_str = 'cheese!';
var data = [3, 0, 0, 0];
data.push32(expected_str.length);
push32(data, expected_str.length);
for (var i = 0; i < expected_str.length; i++) { data.push(expected_str.charCodeAt(i)); }
client.set_onClipboard(sinon.spy());

View File

@ -7,61 +7,19 @@ var expect = chai.expect;
describe('Utils', function() {
"use strict";
describe('Array instance methods', function () {
describe('push8', function () {
it('should push a byte on to the array', function () {
var arr = [1];
arr.push8(128);
expect(arr).to.deep.equal([1, 128]);
});
it('should only use the least significant byte of any number passed in', function () {
var arr = [1];
arr.push8(0xABCD);
expect(arr).to.deep.equal([1, 0xCD]);
});
});
describe('push16', function () {
it('should push two bytes on to the array', function () {
var arr = [1];
arr.push16(0xABCD);
expect(arr).to.deep.equal([1, 0xAB, 0xCD]);
});
it('should only use the two least significant bytes of any number passed in', function () {
var arr = [1];
arr.push16(0xABCDEF);
expect(arr).to.deep.equal([1, 0xCD, 0xEF]);
});
});
describe('push32', function () {
it('should push four bytes on to the array', function () {
var arr = [1];
arr.push32(0xABCDEF12);
expect(arr).to.deep.equal([1, 0xAB, 0xCD, 0xEF, 0x12]);
});
it('should only use the four least significant bytes of any number passed in', function () {
var arr = [1];
arr.push32(0xABCDEF1234);
expect(arr).to.deep.equal([1, 0xCD, 0xEF, 0x12, 0x34]);
});
});
});
describe('logging functions', function () {
beforeEach(function () {
sinon.spy(console, 'log');
sinon.spy(console, 'warn');
sinon.spy(console, 'error');
sinon.spy(console, 'info');
});
afterEach(function () {
console.log.restore();
console.warn.restore();
console.error.restore();
console.info.restore();
});
it('should use noop for levels lower than the min level', function () {
@ -71,12 +29,16 @@ describe('Utils', function() {
expect(console.log).to.not.have.been.called;
});
it('should use console.log for Debug and Info', function () {
it('should use console.log for Debug', function () {
Util.init_logging('debug');
Util.Debug('dbg');
Util.Info('inf');
expect(console.log).to.have.been.calledWith('dbg');
expect(console.log).to.have.been.calledWith('inf');
});
it('should use console.info for Info', function () {
Util.init_logging('debug');
Util.Info('inf');
expect(console.info).to.have.been.calledWith('inf');
});
it('should use console.warn for Warn', function () {
@ -101,5 +63,4 @@ describe('Utils', function() {
// TODO(directxman12): figure out how to test the browser detection functions properly
// (we can't really test them against the browsers, except for Gecko
// via PhantomJS, the default test driver)
// TODO(directxman12): figure out how to test Util.Flash
});

View File

@ -1,43 +0,0 @@
html,body {
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
}
.flex-layout {
width: 100%;
height: 100%;
display: box;
display: -webkit-box;
display: -moz-box;
display: -ms-box;
box-orient: vertical;
-webkit-box-orient: vertical;
-moz-box-orient: vertical;
-ms-box-orient: vertical;
box-align: stretch;
-webkit-box-align: stretch;
-moz-box-align: stretch;
-ms-box-align: stretch;
}
.flex-box {
box-flex: 1;
-webkit-box-flex: 1;
-moz-box-flex: 1;
-ms-box-flex: 1;
}
.container {
margin: 0px;
padding: 0px;
}
.canvas {
position: absolute;
border-style: dotted;
border-width: 1px;
}

View File

@ -1,203 +0,0 @@
<!DOCTYPE html>
<html>
<head><title>Viewport Test</title>
<link rel="stylesheet" href="viewport.css">
<!--
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
-->
<meta name=viewport content="width=device-width, initial-scale=1.0, user-scalable=no">
</head>
<body>
<div class="flex-layout">
<div>
Canvas:
<input id="move-selector" type="button" value="Move"
onclick="toggleMove();">
<br>
</div>
<div class="container flex-box">
<canvas id="canvas" class="canvas">
Canvas not supported.
</canvas>
<br>
</div>
<div>
<br>
Results:<br>
<textarea id="messages" style="font-size: 9;" cols=80 rows=8></textarea>
</div>
</div>
</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/webutil.js"></script>
<script src="../include/base64.js"></script>
<script src="../include/keysymdef.js"></script>
<script src="../include/keyboard.js"></script>
<script src="../include/input.js"></script>
<script src="../include/display.js"></script>
<script>
var msg_cnt = 0, iterations,
penDown = false, doMove = false,
inMove = false, lastPos = {},
padW = 0, padH = 0,
display, ctx, keyboard, mouse;
var newline = "\n";
if (Util.Engine.trident) {
var newline = "<br>\n";
}
function message(str) {
console.log(str);
cell = $D('messages');
cell.innerHTML += msg_cnt + ": " + str + newline;
cell.scrollTop = cell.scrollHeight;
msg_cnt++;
}
function mouseButton(x, y, down, bmask) {
//msg = 'mouse x,y: ' + x + ',' + y + ' down: ' + down;
//msg += ' bmask: ' + bmask;
//message(msg);
if (doMove) {
if (down && !inMove) {
inMove = true;
lastPos = {'x': x, 'y': y};
} else if (!down && inMove) {
inMove = false;
//dirtyRedraw();
}
return;
}
if (down && ! penDown) {
penDown = true;
ctx.beginPath();
ctx.moveTo(x, y);
} else if (!down && penDown) {
penDown = false;
ctx.closePath();
}
}
function mouseMove(x, y) {
var deltaX, deltaY;
if (inMove) {
//deltaX = x - lastPos.x; // drag viewport
deltaX = lastPos.x - x; // drag frame buffer
//deltaY = y - lastPos.y; // drag viewport
deltaY = lastPos.y - y; // drag frame buffer
lastPos = {'x': x, 'y': y};
display.viewportChangePos(deltaX, deltaY);
return;
}
if (penDown) {
ctx.lineTo(x, y);
ctx.stroke();
}
}
function dirtyRedraw() {
if (inMove) {
// Wait for user to stop moving viewport
return;
}
var d = display.getCleanDirtyReset();
for (i = 0; i < d.dirtyBoxes.length; i++) {
//showBox(d.dirtyBoxes[i], "dirty[" + i + "]: ");
drawArea(d.dirtyBoxes[i]);
}
}
function drawArea(b) {
var data = [], pixel, x, y;
//message("draw "+b.x+","+b.y+" ("+b.w+","+b.h+")");
for (var i = 0; i < b.w; i++) {
x = b.x + i;
for (var j = 0; j < b.h; j++) {
y = b.y + j;
pixel = (j * b.w * 4 + i * 4);
data[pixel + 0] = ((x * y) / 13) % 256;
data[pixel + 1] = ((x * y) + 392) % 256;
data[pixel + 2] = ((x + y) + 256) % 256;
data[pixel + 3] = 255;
}
}
//message("i: " + i + ", j: " + j + ", pixel: " + pixel);
display.blitImage(b.x, b.y, b.w, b.h, data, 0);
}
function toggleMove() {
if (doMove) {
doMove = false;
$D('move-selector').style.backgroundColor = "";
$D('move-selector').style.color = "";
} else {
doMove = true;
$D('move-selector').style.backgroundColor = "black";
$D('move-selector').style.color = "lightgray";
}
}
function detectPad() {
var c = $D('canvas'), p = c.parentNode;
c.width = 10;
c.height = 10;
padW = c.offsetWidth - 10;
padH = c.offsetHeight - 10;
message("padW: " + padW + ", padH: " + padH);
}
function doResize() {
var p = $D('canvas').parentNode;
message("doResize1: [" + (p.offsetWidth - padW) +
"," + (p.offsetHeight - padH) + "]");
display.viewportChangeSize(p.offsetWidth - padW, p.offsetHeight - padH);
/*
var pos, new_w, new_h;pos
pos = Util.getPosition($D('canvas').parentNode);
new_w = window.innerWidth - pos.x;
new_h = window.innerHeight - pos.y;
display.viewportChangeSize(new_w, new_h);
*/
}
window.onload = function() {
detectPad();
display = new Display({'target': $D('canvas')});
display.resize(1600, 1024);
display.set_viewport(true);
ctx = display.get_context();
mouse = new Mouse({'target': $D('canvas'),
'onMouseButton': mouseButton,
'onMouseMove': mouseMove});
mouse.grab();
Util.addEvent(window, 'resize', doResize);
// Shrink viewport for first resize call so that the
// scrollbars are disabled
display.viewportChangeSize(10, 10);
setTimeout(doResize, 1);
setInterval(dirtyRedraw, 50);
message("Display initialized");
};
</script>
</html>

View File

@ -31,17 +31,17 @@
</body>
<!--
<script type='text/javascript'
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
<script type="text/javascript">
var INCLUDE_URI= "../include/";
var INCLUDE_URI= "../";
// TODO: Data file should override
var VNC_frame_encoding = "binary";
</script>
<script src="../include/util.js"></script>
<script src="../include/webutil.js"></script>
<script src="../core/util.js"></script>
<script src="../app/webutil.js"></script>
<script>
var fname = WebUtil.getQueryVar('data', null);
@ -49,10 +49,12 @@
msg("Loading " + fname);
// Load supporting scripts
Util.load_scripts(["base64.js", "websock.js", "des.js", "keysym.js",
"keysymdef.js", "xtscancodes.js", "keyboard.js",
"input.js", "display.js", "rfb.js", "playback.js",
"inflator.js", fname]);
WebUtil.load_scripts({
'core': ["base64.js", "websock.js", "des.js", "input/keysym.js",
"input/keysymdef.js", "input/xtscancodes.js", "input/util.js",
"input/devices.js", "display.js", "rfb.js", "inflator.js"],
'tests': ["playback.js"],
'recordings': [fname]});
} else {
msg("Must specifiy data=FOO.js in query string.");
}
@ -64,7 +66,7 @@
function msg(str) {
console.log(str);
var cell = $D('messages');
var cell = document.getElementById('messages');
cell.innerHTML += str + "\n";
cell.scrollTop = cell.scrollHeight;
}
@ -85,20 +87,20 @@
test_state = 'failed';
break;
case 'loaded':
$D('startButton').disabled = false;
document.getElementById('startButton').disabled = false;
break;
}
if (typeof mesg !== 'undefined') {
$D('VNC_status').innerHTML = mesg;
document.getElementById('VNC_status').innerHTML = mesg;
}
}
function do_test() {
$D('startButton').value = "Running";
$D('startButton').disabled = true;
document.getElementById('startButton').value = "Running";
document.getElementById('startButton').disabled = true;
mode = 'perftest'; // full-speed
passes = $D('passes').value;
passes = document.getElementById('passes').value;
pass = 1;
encIdx = 0;
@ -142,8 +144,8 @@
// Shut-off event interception
rfb.get_mouse().ungrab();
rfb.get_keyboard().ungrab();
$D('startButton').disabled = false;
$D('startButton').value = "Start";
document.getElementById('startButton').disabled = false;
document.getElementById('startButton').value = "Start";
finish_passes();
return; // We are finished, terminate
}
@ -190,7 +192,7 @@
enc = encOrder[i];
avg = (encTot[i] / passes).toFixed(1);
msg(" " + enc + ": " + encTot[i] + " ms, " +
encMin[i] + "/" + avg + "/" + encMax[i] +
encMin[i] + "/" + avg + "/" + encMax[i] +
" (min/avg/max)");
}
@ -208,7 +210,7 @@
enc = encOrder[i];
dbgmsg(" " + enc + ": " + VNC_frame_data_multi[enc].length);
}
$D('startButton').disabled = false;
document.getElementById('startButton').disabled = false;
}
</script>
</html>

View File

@ -33,24 +33,24 @@
</body>
<!--
<script type='text/javascript'
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
<script type="text/javascript">
var INCLUDE_URI= "../include/";
var INCLUDE_URI= "../";
// TODO: Data file should override
var VNC_frame_encoding = "binary";
</script>
<script src="../include/util.js"></script>
<script src="../include/webutil.js"></script>
<script src="../core/util.js"></script>
<script src="../app/webutil.js"></script>
<script>
var fname, start_time;
function message(str) {
console.log(str);
var cell = $D('messages');
var cell = document.getElementById('messages');
cell.innerHTML += str + "\n";
cell.scrollTop = cell.scrollHeight;
}
@ -59,10 +59,12 @@
if (fname) {
message("Loading " + fname);
// Load supporting scripts
Util.load_scripts(["base64.js", "websock.js", "des.js", "keysym.js",
"keysymdef.js", "xtscancodes.js", "keyboard.js",
"input.js", "display.js", "rfb.js", "playback.js",
"inflator.js", fname]);
WebUtil.load_scripts({
'core': ["base64.js", "websock.js", "des.js", "input/keysym.js",
"input/keysymdef.js", "input/xtscancodes.js", "input/util.js",
"input/devices.js", "display.js", "rfb.js", "inflator.js"],
'tests': ["playback.js"],
'recordings': [fname]});
} else {
message("Must specify data=FOO in query string.");
@ -79,19 +81,19 @@
break;
}
if (typeof msg !== 'undefined') {
$D('VNC_status').innerHTML = msg;
document.getElementById('VNC_status').innerHTML = msg;
}
}
function start() {
$D('startButton').value = "Running";
$D('startButton').disabled = true;
document.getElementById('startButton').value = "Running";
document.getElementById('startButton').disabled = true;
iterations = $D('iterations').value;
iterations = document.getElementById('iterations').value;
iteration = 0;
start_time = (new Date()).getTime();
if ($D('mode1').checked) {
if (document.getElementById('mode1').checked) {
message("Starting performance playback (fullspeed) [" + iterations + " iteration(s)]");
mode = 'perftest';
} else {
@ -115,24 +117,24 @@
// Shut-off event interception
rfb.get_mouse().ungrab();
rfb.get_keyboard().ungrab();
$D('startButton').disabled = false;
$D('startButton').value = "Start";
document.getElementById('startButton').disabled = false;
document.getElementById('startButton').value = "Start";
}
window.onscriptsload = function () {
iterations = WebUtil.getQueryVar('iterations', 3);
$D('iterations').value = iterations;
document.getElementById('iterations').value = iterations;
mode = WebUtil.getQueryVar('mode', 3);
if (mode === 'realtime') {
$D('mode2').checked = true;
document.getElementById('mode2').checked = true;
} else {
$D('mode1').checked = true;
document.getElementById('mode1').checked = true;
}
if (fname) {
message("VNC_frame_data.length: " + VNC_frame_data.length);
}
$D('startButton').disabled = false;
document.getElementById('startButton').disabled = false;
}
</script>
</html>

View File

@ -0,0 +1,25 @@
var through = require('through2');
var singleLineRe = /\/\* \[module\] ((.(?!\*\/))+) \*\//g;
var multiLineRe = /\/\* \[module\]\n(( * .+\n)+) \*\//g;
var skipAsModule = /\/\* \[begin skip-as-module\] \*\/(.|\n)+\/\* \[end skip-as-module\] \*\//g;
module.exports = function (file) {
var stream = through(function (buf, enc, next) {
var bufStr = buf.toString('utf8');
bufStr = bufStr.replace(singleLineRe, "$1");
bufStr = bufStr.replace(multiLineRe, function (match, mainLines) {
return mainLines.split(" * ").join("");
});
bufStr = bufStr.replace(skipAsModule, "");
this.push(bufStr);
next();
});
stream._is_make_module = true;
return stream;
};

121
utils/use_require.js Executable file
View File

@ -0,0 +1,121 @@
#!/usr/bin/env node
var path = require('path');
var program = require('commander');
var fs = require('fs');
var fse = require('fs-extra');
var browserify = require('browserify');
var make_modules_transform = require('./make-module-transform');
var babelify = require("babelify");
program
.option('-b, --browserify', 'create a browserify bundled app')
.option('--as-require', 'output files using "require" instead of ES6 import and export')
.parse(process.argv);
// the various important paths
var core_path = path.resolve(__dirname, '..', 'core');
var app_path = path.resolve(__dirname, '..', 'app');
var out_dir_base = path.resolve(__dirname, '..', 'build');
var lib_dir_base = path.resolve(__dirname, '..', 'lib');
var make_browserify = function (src_files, opts) {
// change to the root noVNC directory
process.chdir(path.resolve(__dirname, '..'));
var b = browserify(src_files, opts);
// register the transforms
b.transform(make_modules_transform);
b.transform(babelify,
{ plugins: ["add-module-exports", "transform-es2015-modules-commonjs"] });
return b;
};
var make_full_app = function () {
// make sure the output directory exists
fse.ensureDir(out_dir_base);
// actually bundle the files into a browserified bundled
var ui_file = path.join(app_path, 'ui.js');
var b = make_browserify(ui_file, {});
var app_file = path.join(out_dir_base, 'app.js');
b.bundle().pipe(fs.createWriteStream(app_file));
// copy over app-related resources (images, styles, etc)
var src_dir_app = path.join(__dirname, '..', 'app');
fs.readdir(src_dir_app, function (err, files) {
if (err) { throw err; }
files.forEach(function (src_file) {
var src_file_path = path.resolve(src_dir_app, src_file);
var out_file_path = path.resolve(out_dir_base, src_file);
var ext = path.extname(src_file);
if (ext === '.js' || ext === '.html') return;
fse.copy(src_file_path, out_file_path, function (err) {
if (err) { throw err; }
console.log("Copied file(s) from " + src_file_path + " to " + out_file_path);
});
});
});
// write out the modified vnc.html file that works with the bundle
var src_html_path = path.resolve(__dirname, '..', 'vnc.html');
var out_html_path = path.resolve(out_dir_base, 'vnc.html');
fs.readFile(src_html_path, function (err, contents_raw) {
if (err) { throw err; }
var contents = contents_raw.toString();
contents = contents.replace(/="app\//g, '="');
var start_marker = '<!-- begin scripts -->\n';
var end_marker = '<!-- end scripts -->';
var start_ind = contents.indexOf(start_marker) + start_marker.length;
var end_ind = contents.indexOf(end_marker, start_ind);
contents = contents.slice(0, start_ind) + '<script src="app.js"></script>\n' + contents.slice(end_ind);
fs.writeFile(out_html_path, contents, function (err) {
if (err) { throw err; }
console.log("Wrote " + out_html_path);
});
});
};
var make_lib_files = function (use_require) {
// make sure the output directory exists
fse.ensureDir(lib_dir_base);
var through = require('through2');
var deps = {};
var rfb_file = path.join(core_path, 'rfb.js');
var b = make_browserify(rfb_file, {});
b.on('transform', function (tr, file) {
if (tr._is_make_module) {
var new_path = path.join(lib_dir_base, path.relative(core_path, file));
fse.ensureDir(path.dirname(new_path));
console.log("Writing " + new_path)
var fileStream = fs.createWriteStream(new_path);
if (use_require) {
var babelificate = babelify(file,
{ plugins: ["add-module-exports", "transform-es2015-modules-commonjs"] });
tr.pipe(babelificate);
tr = babelificate;
}
tr.pipe(fileStream);
}
});
b.bundle();
};
if (program.browserify) {
make_full_app();
} else {
make_lib_files(program.asRequire);
}

View File

@ -27,18 +27,18 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<!-- App Start Icon -->
<link rel="apple-touch-startup-image" href="images/screen_320x460.png" />
<link rel="apple-touch-startup-image" href="app/images/screen_320x460.png" />
<!-- For iOS devices set the icon to use if user bookmarks app on their homescreen -->
<link rel="apple-touch-icon" href="images/screen_57x57.png" />
<link rel="apple-touch-icon" href="app/images/screen_57x57.png" />
<!--
<link rel="apple-touch-icon-precomposed" href="images/screen_57x57.png" />
<link rel="apple-touch-icon-precomposed" href="app/images/screen_57x57.png" />
-->
<!-- Stylesheets -->
<link rel="stylesheet" href="include/base.css" />
<link rel="alternate stylesheet" href="include/black.css" TITLE="Black" />
<link rel="alternate stylesheet" href="include/blue.css" TITLE="Blue" />
<link rel="stylesheet" href="app/styles/base.css" />
<link rel="alternate stylesheet" href="app/styles/black.css" TITLE="Black" />
<link rel="alternate stylesheet" href="app/styles/blue.css" TITLE="Blue" />
<!--
<script type='text/javascript'
@ -51,19 +51,19 @@
<div id="noVNC_control_bar" class="noVNC_status_normal">
<!--noVNC Mobile Device only Buttons-->
<div class="noVNC_buttons_left">
<input type="image" alt="viewport drag" src="images/drag.png"
<input type="image" alt="viewport drag" src="app/images/drag.png"
id="noVNC_view_drag_button" class="noVNC_status_button"
title="Move/Drag Viewport" />
<div id="noVNC_mobile_buttons">
<input type="image" alt="No mousebutton" src="images/mouse_none.png"
<input type="image" alt="No mousebutton" src="app/images/mouse_none.png"
id="noVNC_mouse_button0" class="noVNC_status_button" />
<input type="image" alt="Left mousebutton" src="images/mouse_left.png"
<input type="image" alt="Left mousebutton" src="app/images/mouse_left.png"
id="noVNC_mouse_button1" class="noVNC_status_button" />
<input type="image" alt="Middle mousebutton" src="images/mouse_middle.png"
<input type="image" alt="Middle mousebutton" src="app/images/mouse_middle.png"
id="noVNC_mouse_button2" class="noVNC_status_button" />
<input type="image" alt="Right mousebutton" src="images/mouse_right.png"
<input type="image" alt="Right mousebutton" src="app/images/mouse_right.png"
id="noVNC_mouse_button4" class="noVNC_status_button" />
<input type="image" alt="Keyboard" src="images/keyboard.png"
<input type="image" alt="Keyboard" src="app/images/keyboard.png"
id="noVNC_keyboard_button" class="noVNC_status_button"
value="Keyboard" title="Show Keyboard" />
<!-- Note that Google Chrome on Android doesn't respect any of these,
@ -74,15 +74,15 @@
autocorrect="off" autocomplete="off" spellcheck="false"
mozactionhint="Enter"></textarea>
<div id="noVNC_extra_keys">
<input type="image" alt="Extra keys" src="images/toggleextrakeys.png"
<input type="image" alt="Extra keys" src="app/images/toggleextrakeys.png"
id="noVNC_toggleExtraKeys_button" class="noVNC_status_button" />
<input type="image" alt="Ctrl" src="images/ctrl.png"
<input type="image" alt="Ctrl" src="app/images/ctrl.png"
id="noVNC_toggleCtrl_button" class="noVNC_status_button" />
<input type="image" alt="Alt" src="images/alt.png"
<input type="image" alt="Alt" src="app/images/alt.png"
id="noVNC_toggleAlt_button" class="noVNC_status_button" />
<input type="image" alt="Tab" src="images/tab.png"
<input type="image" alt="Tab" src="app/images/tab.png"
id="noVNC_sendTab_button" class="noVNC_status_button" />
<input type="image" alt="Esc" src="images/esc.png"
<input type="image" alt="Esc" src="app/images/esc.png"
id="noVNC_sendEsc_button" class="noVNC_status_button" />
</div>
</div>
@ -92,25 +92,25 @@
<!--noVNC Buttons-->
<div class="noVNC_buttons_right">
<input type="image" alt="Ctrl+Alt+Del" src="images/ctrlaltdel.png"
<input type="image" alt="Ctrl+Alt+Del" src="app/images/ctrlaltdel.png"
id="noVNC_sendCtrlAltDel_button" class="noVNC_status_button"
title="Send Ctrl-Alt-Del" />
<input type="image" alt="Shutdown/Reboot" src="images/power.png"
<input type="image" alt="Shutdown/Reboot" src="app/images/power.png"
id="noVNC_toggleXvp_button" class="noVNC_status_button"
title="Shutdown/Reboot..." />
<input type="image" alt="Clipboard" src="images/clipboard.png"
<input type="image" alt="Clipboard" src="app/images/clipboard.png"
id="noVNC_clipboard_button" class="noVNC_status_button"
title="Clipboard" />
<input type="image" alt="Fullscreen" src="images/fullscreen.png"
<input type="image" alt="Fullscreen" src="app/images/fullscreen.png"
id="noVNC_fullscreen_button" class="noVNC_status_button"
title="Fullscreen" />
<input type="image" alt="Settings" src="images/settings.png"
<input type="image" alt="Settings" src="app/images/settings.png"
id="noVNC_settings_button" class="noVNC_status_button"
title="Settings" />
<input type="image" alt="Connect" src="images/connect.png"
<input type="image" alt="Connect" src="app/images/connect.png"
id="noVNC_connectPanel_button" class="noVNC_status_button"
title="Connect" />
<input type="image" alt="Disconnect" src="images/disconnect.png"
<input type="image" alt="Disconnect" src="app/images/disconnect.png"
id="noVNC_disconnect_button" class="noVNC_status_button"
title="Disconnect" />
</div>
@ -218,8 +218,11 @@
</div>
</div>
<script src="include/util.js"></script>
<script src="include/ui.js"></script>
<!-- begin scripts -->
<script src="core/util.js"></script>
<script src="app/webutil.js"></script>
<script src="app/ui.js"></script>
<!-- end scripts -->
</body>
</html>

View File

@ -27,22 +27,23 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<!-- App Start Icon -->
<link rel="apple-touch-startup-image" href="images/screen_320x460.png" />
<link rel="apple-touch-startup-image" href="app/images/screen_320x460.png" />
<!-- For iOS devices set the icon to use if user bookmarks app on their homescreen -->
<link rel="apple-touch-icon" href="images/screen_57x57.png">
<link rel="apple-touch-icon" href="app/images/screen_57x57.png">
<!--
<link rel="apple-touch-icon-precomposed" href="images/screen_57x57.png" />
<link rel="apple-touch-icon-precomposed" href="app/images/screen_57x57.png" />
-->
<!-- Stylesheets -->
<link rel="stylesheet" href="include/base.css" title="plain">
<link rel="stylesheet" href="app/styles/base.css" title="plain">
<!--
<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="core/util.js"></script>
<script src="app/webutil.js"></script>
</head>
<body style="margin: 0px;">
@ -77,10 +78,11 @@
"use strict";
// Load supporting scripts
Util.load_scripts(["webutil.js", "base64.js", "websock.js", "des.js",
"keysymdef.js", "xtscancodes.js", "keyboard.js",
"input.js", "display.js", "inflator.js", "rfb.js",
"keysym.js"]);
WebUtil.load_scripts({
'core': ["base64.js", "websock.js", "des.js", "input/keysymdef.js",
"input/xtscancodes.js", "input/util.js", "input/devices.js",
"display.js", "inflator.js", "rfb.js", "input/keysym.js"],
'app': ["webutil.js"]});
var rfb;
var resizeTimeout;
@ -90,7 +92,7 @@
if (WebUtil.getConfigVar('resize', false)) {
var innerW = window.innerWidth;
var innerH = window.innerHeight;
var controlbarH = $D('noVNC_status_bar').offsetHeight;
var controlbarH = document.getElementById('noVNC_status_bar').offsetHeight;
var padding = 5;
if (innerW !== undefined && innerH !== undefined)
rfb.requestDesktopSize(innerW, innerH - controlbarH - padding);
@ -107,11 +109,11 @@
msg += 'Password Required: ';
msg += '<input type=password size=10 id="password_input" class="noVNC_status">';
msg += '<\/form>';
$D('noVNC_status_bar').setAttribute("class", "noVNC_status_warn");
$D('noVNC_status').innerHTML = msg;
document.getElementById('noVNC_status_bar').setAttribute("class", "noVNC_status_warn");
document.getElementById('noVNC_status').innerHTML = msg;
}
function setPassword() {
rfb.sendPassword($D('password_input').value);
rfb.sendPassword(document.getElementById('password_input').value);
return false;
}
function sendCtrlAltDel() {
@ -132,9 +134,9 @@
}
function updateState(rfb, state, oldstate, msg) {
var s, sb, cad, level;
s = $D('noVNC_status');
sb = $D('noVNC_status_bar');
cad = $D('sendCtrlAltDelButton');
s = document.getElementById('noVNC_status');
sb = document.getElementById('noVNC_status_bar');
cad = document.getElementById('sendCtrlAltDelButton');
switch (state) {
case 'failed': level = "error"; break;
case 'fatal': level = "error"; break;
@ -169,7 +171,7 @@
function xvpInit(ver) {
var xvpbuttons;
xvpbuttons = $D('noVNC_xvp_buttons');
xvpbuttons = document.getElementById('noVNC_xvp_buttons');
if (ver >= 1) {
xvpbuttons.style.display = 'inline';
} else {
@ -180,11 +182,11 @@
window.onscriptsload = function () {
var host, port, password, path, token;
$D('sendCtrlAltDelButton').style.display = "inline";
$D('sendCtrlAltDelButton').onclick = sendCtrlAltDel;
$D('xvpShutdownButton').onclick = xvpShutdown;
$D('xvpRebootButton').onclick = xvpReboot;
$D('xvpResetButton').onclick = xvpReset;
document.getElementById('sendCtrlAltDelButton').style.display = "inline";
document.getElementById('sendCtrlAltDelButton').onclick = sendCtrlAltDel;
document.getElementById('xvpShutdownButton').onclick = xvpShutdown;
document.getElementById('xvpRebootButton').onclick = xvpReboot;
document.getElementById('xvpResetButton').onclick = xvpReset;
WebUtil.init_logging(WebUtil.getConfigVar('logging', 'warn'));
document.title = unescape(WebUtil.getConfigVar('title', 'noVNC'));
@ -223,7 +225,7 @@
}
try {
rfb = new RFB({'target': $D('noVNC_canvas'),
rfb = new RFB({'target': document.getElementById('noVNC_canvas'),
'encrypt': WebUtil.getConfigVar('encrypt',
(window.location.protocol === "https:")),
'repeaterID': WebUtil.getConfigVar('repeaterID', ''),