From ebcf44d55a9487e91357a6f09fa06f177fb6fa47 Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Wed, 14 Sep 2016 13:45:08 -0400 Subject: Move input-related files into core/input This commit moves all the input-related files from `core/` to `core/input/`, and renames a couple as relevant (input.js --> input/devices.js, keyboard.js --> input/util.js). --- LICENSE.txt | 6 +- app/ui.js | 8 +- core/input.js | 402 --------------------------- core/input/devices.js | 402 +++++++++++++++++++++++++++ core/input/keysym.js | 382 ++++++++++++++++++++++++++ core/input/keysymdef.js | 18 ++ core/input/util.js | 682 ++++++++++++++++++++++++++++++++++++++++++++++ core/input/xtscancodes.js | 149 ++++++++++ core/keyboard.js | 682 ---------------------------------------------- core/keysym.js | 382 -------------------------- core/keysymdef.js | 18 -- core/rfb.js | 6 +- core/xtscancodes.js | 149 ---------- karma.conf.js | 10 +- tests/input.html | 10 +- tests/test.helper.js | 2 +- tests/test.keyboard.js | 2 +- tests/test.rfb.js | 2 +- tests/vnc_perf.html | 6 +- tests/vnc_playback.html | 6 +- utils/use_require.js | 3 +- vnc_auto.html | 6 +- 22 files changed, 1667 insertions(+), 1666 deletions(-) delete mode 100644 core/input.js create mode 100644 core/input/devices.js create mode 100644 core/input/keysym.js create mode 100644 core/input/keysymdef.js create mode 100644 core/input/util.js create mode 100644 core/input/xtscancodes.js delete mode 100644 core/keyboard.js delete mode 100644 core/keysym.js delete mode 100644 core/keysymdef.js delete mode 100644 core/xtscancodes.js diff --git a/LICENSE.txt b/LICENSE.txt index 41b45bb..7b5de59 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -8,8 +8,8 @@ is not limited to): core/base64.js core/des.js core/display.js - core/input.js - core/keysym.js + core/input/devices.js + core/input/keysym.js core/logo.js core/playback.js core/rfb.js @@ -17,7 +17,7 @@ is not limited to): core/util.js core/websock.js app/webutil.js - core/xtscancodes.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 diff --git a/app/ui.js b/app/ui.js index cb0cc9e..78d397d 100644 --- a/app/ui.js +++ b/app/ui.js @@ -12,7 +12,7 @@ /* [module] * import Util from "../core/util"; - * import KeyTable from "../core/keysym"; + * import KeyTable from "../core/input/keysym"; * import RFB from "../core/rfb"; * import Display from "../core/display"; * import WebUtil from "./webutil"; @@ -26,9 +26,9 @@ var UI; /* [begin skip-as-module] */ // Load supporting scripts WebUtil.load_scripts( - {'core': ["base64.js", "websock.js", "des.js", "keysymdef.js", - "xtscancodes.js", "keyboard.js", "input.js", "display.js", - "inflator.js", "rfb.js", "keysym.js"]}); + {'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(); }; /* [end skip-as-module] */ diff --git a/core/input.js b/core/input.js deleted file mode 100644 index e1fff1c..0000000 --- a/core/input.js +++ /dev/null @@ -1,402 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2012 Joel Martin - * Copyright (C) 2013 Samuel Mannehed for Cendio AB - * Licensed under MPL 2.0 or any later version (see LICENSE.txt) - */ - -/*jslint browser: true, white: false */ -/*global window, Util */ - -/* [module] - * import Util from "./util"; - * import KeyboardUtil from "./keyboard"; - */ - -/* [module] export */ var Keyboard; - -(function () { - "use strict"; - - // - // Keyboard event handler - // - - Keyboard = function (defaults) { - this._keyDownList = []; // List of depressed keys - // (even if they are happy) - - Util.set_defaults(this, defaults, { - 'target': document, - 'focused': true - }); - - // create the keyboard handler - this._handler = new KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), - KeyboardUtil.VerifyCharModifier( /* jshint newcap: false */ - KeyboardUtil.TrackKeyState( - KeyboardUtil.EscapeModifiers(this._handleRfbEvent.bind(this)) - ) - ) - ); /* jshint newcap: true */ - - // keep these here so we can refer to them later - this._eventHandlers = { - 'keyup': this._handleKeyUp.bind(this), - 'keydown': this._handleKeyDown.bind(this), - 'keypress': this._handleKeyPress.bind(this), - 'blur': this._allKeysUp.bind(this) - }; - }; - - Keyboard.prototype = { - // private methods - - _handleRfbEvent: function (e) { - if (this._onKeyPress) { - Util.Debug("onKeyPress " + (e.type == 'keydown' ? "down" : "up") + - ", keysym: " + e.keysym.keysym + "(" + e.keysym.keyname + ")"); - this._onKeyPress(e); - } - }, - - setQEMUVNCKeyboardHandler: function () { - this._handler = new KeyboardUtil.QEMUKeyEventDecoder(KeyboardUtil.ModifierSync(), - KeyboardUtil.TrackQEMUKeyState( - this._handleRfbEvent.bind(this) - ) - ); - }, - - _handleKeyDown: function (e) { - if (!this._focused) { return true; } - - if (this._handler.keydown(e)) { - // Suppress bubbling/default actions - Util.stopEvent(e); - return false; - } else { - // Allow the event to bubble and become a keyPress event which - // will have the character code translated - return true; - } - }, - - _handleKeyPress: function (e) { - if (!this._focused) { return true; } - - if (this._handler.keypress(e)) { - // Suppress bubbling/default actions - Util.stopEvent(e); - return false; - } else { - // Allow the event to bubble and become a keyPress event which - // will have the character code translated - return true; - } - }, - - _handleKeyUp: function (e) { - if (!this._focused) { return true; } - - if (this._handler.keyup(e)) { - // Suppress bubbling/default actions - Util.stopEvent(e); - return false; - } else { - // Allow the event to bubble and become a keyPress event which - // will have the character code translated - return true; - } - }, - - _allKeysUp: function () { - Util.Debug(">> Keyboard.allKeysUp"); - this._handler.releaseAll(); - Util.Debug("<< Keyboard.allKeysUp"); - }, - - // Public methods - - grab: function () { - //Util.Debug(">> Keyboard.grab"); - var c = this._target; - - 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 - window.addEventListener('blur', this._eventHandlers.blur); - - //Util.Debug("<< Keyboard.grab"); - }, - - ungrab: function () { - //Util.Debug(">> Keyboard.ungrab"); - var c = this._target; - - 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(); - - //Util.Debug(">> Keyboard.ungrab"); - }, - - sync: function (e) { - this._handler.syncModifiers(e); - } - }; - - Util.make_properties(Keyboard, [ - ['target', 'wo', 'dom'], // DOM element that captures keyboard input - ['focused', 'rw', 'bool'], // Capture and send key events - - ['onKeyPress', 'rw', 'func'] // Handler for key press/release - ]); -})(); - -/* [module] export */ var Mouse; - -(function () { - Mouse = function (defaults) { - this._mouseCaptured = false; - - this._doubleClickTimer = null; - this._lastTouchPos = null; - - // Configuration attributes - Util.set_defaults(this, defaults, { - 'target': document, - 'focused': true, - 'scale': 1.0, - 'touchButton': 1 - }); - - this._eventHandlers = { - 'mousedown': this._handleMouseDown.bind(this), - 'mouseup': this._handleMouseUp.bind(this), - 'mousemove': this._handleMouseMove.bind(this), - 'mousewheel': this._handleMouseWheel.bind(this), - 'mousedisable': this._handleMouseDisable.bind(this) - }; - }; - - Mouse.prototype = { - // private methods - _captureMouse: function () { - // capturing the mouse ensures we get the mouseup event - if (this._target.setCapture) { - this._target.setCapture(); - } - - // some browsers give us mouseup events regardless, - // so if we never captured the mouse, we can disregard the event - this._mouseCaptured = true; - }, - - _releaseMouse: function () { - if (this._target.releaseCapture) { - this._target.releaseCapture(); - } - this._mouseCaptured = false; - }, - - _resetDoubleClickTimer: function () { - this._doubleClickTimer = null; - }, - - _handleMouseButton: function (e, down) { - if (!this._focused) { return true; } - - if (this._notify) { - this._notify(e); - } - - var evt = (e ? e : window.event); - var pos = Util.getEventPosition(e, this._target, this._scale); - - var bmask; - if (e.touches || e.changedTouches) { - // Touch device - - // When two touches occur within 500 ms of each other and are - // close enough together a double click is triggered. - if (down == 1) { - if (this._doubleClickTimer === null) { - this._lastTouchPos = pos; - } else { - clearTimeout(this._doubleClickTimer); - - // When the distance between the two touches is small enough - // force the position of the latter touch to the position of - // the first. - - var xs = this._lastTouchPos.x - pos.x; - var ys = this._lastTouchPos.y - pos.y; - var d = Math.sqrt((xs * xs) + (ys * ys)); - - // The goal is to trigger on a certain physical width, the - // devicePixelRatio brings us a bit closer but is not optimal. - var threshold = 20 * (window.devicePixelRatio || 1); - if (d < threshold) { - pos = this._lastTouchPos; - } - } - this._doubleClickTimer = setTimeout(this._resetDoubleClickTimer.bind(this), 500); - } - bmask = this._touchButton; - // If bmask is set - } else if (evt.which) { - /* everything except IE */ - bmask = 1 << evt.button; - } else { - /* IE including 9 */ - bmask = (evt.button & 0x1) + // Left - (evt.button & 0x2) * 2 + // Right - (evt.button & 0x4) / 2; // Middle - } - - if (this._onMouseButton) { - Util.Debug("onMouseButton " + (down ? "down" : "up") + - ", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask); - this._onMouseButton(pos.x, pos.y, down, bmask); - } - Util.stopEvent(e); - return false; - }, - - _handleMouseDown: function (e) { - this._captureMouse(); - this._handleMouseButton(e, 1); - }, - - _handleMouseUp: function (e) { - if (!this._mouseCaptured) { return; } - - this._handleMouseButton(e, 0); - this._releaseMouse(); - }, - - _handleMouseWheel: function (e) { - if (!this._focused) { return true; } - - if (this._notify) { - this._notify(e); - } - - var evt = (e ? e : window.event); - var pos = Util.getEventPosition(e, this._target, this._scale); - var wheelData = evt.detail ? evt.detail * -1 : evt.wheelDelta / 40; - var bmask; - if (wheelData > 0) { - bmask = 1 << 3; - } else { - bmask = 1 << 4; - } - - if (this._onMouseButton) { - this._onMouseButton(pos.x, pos.y, 1, bmask); - this._onMouseButton(pos.x, pos.y, 0, bmask); - } - Util.stopEvent(e); - return false; - }, - - _handleMouseMove: function (e) { - if (! this._focused) { return true; } - - if (this._notify) { - this._notify(e); - } - - var evt = (e ? e : window.event); - var pos = Util.getEventPosition(e, this._target, this._scale); - if (this._onMouseMove) { - this._onMouseMove(pos.x, pos.y); - } - Util.stopEvent(e); - return false; - }, - - _handleMouseDisable: function (e) { - if (!this._focused) { return true; } - - var evt = (e ? e : window.event); - var pos = Util.getEventPosition(e, this._target, this._scale); - - /* Stop propagation if inside canvas area */ - if ((pos.realx >= 0) && (pos.realy >= 0) && - (pos.realx < this._target.offsetWidth) && - (pos.realy < this._target.offsetHeight)) { - //Util.Debug("mouse event disabled"); - Util.stopEvent(e); - return false; - } - - return true; - }, - - - // Public methods - grab: function () { - var c = this._target; - - if ('ontouchstart' in document.documentElement) { - 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 { - 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 */ - document.addEventListener('click', this._eventHandlers.mousedisable); - document.body.addEventListener('contextmenu', this._eventHandlers.mousedisable); - }, - - ungrab: function () { - var c = this._target; - - if ('ontouchstart' in document.documentElement) { - 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 { - 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 */ - document.removeEventListener('click', this._eventHandlers.mousedisable); - document.body.removeEventListener('contextmenu', this._eventHandlers.mousedisable); - - } - }; - - Util.make_properties(Mouse, [ - ['target', 'ro', 'dom'], // DOM element that captures mouse input - ['notify', 'ro', 'func'], // Function to call to notify whenever a mouse event is received - ['focused', 'rw', 'bool'], // Capture and send mouse clicks/movement - ['scale', 'rw', 'float'], // Viewport scale factor 0.0 - 1.0 - - ['onMouseButton', 'rw', 'func'], // Handler for mouse button click/release - ['onMouseMove', 'rw', 'func'], // Handler for mouse movement - ['touchButton', 'rw', 'int'] // Button mask (1, 2, 4) for touch devices (0 means ignore clicks) - ]); -})(); diff --git a/core/input/devices.js b/core/input/devices.js new file mode 100644 index 0000000..d283fc4 --- /dev/null +++ b/core/input/devices.js @@ -0,0 +1,402 @@ +/* + * noVNC: HTML5 VNC client + * Copyright (C) 2012 Joel Martin + * Copyright (C) 2013 Samuel Mannehed for Cendio AB + * Licensed under MPL 2.0 or any later version (see LICENSE.txt) + */ + +/*jslint browser: true, white: false */ +/*global window, Util */ + +/* [module] + * import Util from "../util"; + * import KeyboardUtil from "./util"; + */ + +/* [module] export */ var Keyboard; + +(function () { + "use strict"; + + // + // Keyboard event handler + // + + Keyboard = function (defaults) { + this._keyDownList = []; // List of depressed keys + // (even if they are happy) + + Util.set_defaults(this, defaults, { + 'target': document, + 'focused': true + }); + + // create the keyboard handler + this._handler = new KeyboardUtil.KeyEventDecoder(KeyboardUtil.ModifierSync(), + KeyboardUtil.VerifyCharModifier( /* jshint newcap: false */ + KeyboardUtil.TrackKeyState( + KeyboardUtil.EscapeModifiers(this._handleRfbEvent.bind(this)) + ) + ) + ); /* jshint newcap: true */ + + // keep these here so we can refer to them later + this._eventHandlers = { + 'keyup': this._handleKeyUp.bind(this), + 'keydown': this._handleKeyDown.bind(this), + 'keypress': this._handleKeyPress.bind(this), + 'blur': this._allKeysUp.bind(this) + }; + }; + + Keyboard.prototype = { + // private methods + + _handleRfbEvent: function (e) { + if (this._onKeyPress) { + Util.Debug("onKeyPress " + (e.type == 'keydown' ? "down" : "up") + + ", keysym: " + e.keysym.keysym + "(" + e.keysym.keyname + ")"); + this._onKeyPress(e); + } + }, + + setQEMUVNCKeyboardHandler: function () { + this._handler = new KeyboardUtil.QEMUKeyEventDecoder(KeyboardUtil.ModifierSync(), + KeyboardUtil.TrackQEMUKeyState( + this._handleRfbEvent.bind(this) + ) + ); + }, + + _handleKeyDown: function (e) { + if (!this._focused) { return true; } + + if (this._handler.keydown(e)) { + // Suppress bubbling/default actions + Util.stopEvent(e); + return false; + } else { + // Allow the event to bubble and become a keyPress event which + // will have the character code translated + return true; + } + }, + + _handleKeyPress: function (e) { + if (!this._focused) { return true; } + + if (this._handler.keypress(e)) { + // Suppress bubbling/default actions + Util.stopEvent(e); + return false; + } else { + // Allow the event to bubble and become a keyPress event which + // will have the character code translated + return true; + } + }, + + _handleKeyUp: function (e) { + if (!this._focused) { return true; } + + if (this._handler.keyup(e)) { + // Suppress bubbling/default actions + Util.stopEvent(e); + return false; + } else { + // Allow the event to bubble and become a keyPress event which + // will have the character code translated + return true; + } + }, + + _allKeysUp: function () { + Util.Debug(">> Keyboard.allKeysUp"); + this._handler.releaseAll(); + Util.Debug("<< Keyboard.allKeysUp"); + }, + + // Public methods + + grab: function () { + //Util.Debug(">> Keyboard.grab"); + var c = this._target; + + 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 + window.addEventListener('blur', this._eventHandlers.blur); + + //Util.Debug("<< Keyboard.grab"); + }, + + ungrab: function () { + //Util.Debug(">> Keyboard.ungrab"); + var c = this._target; + + 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(); + + //Util.Debug(">> Keyboard.ungrab"); + }, + + sync: function (e) { + this._handler.syncModifiers(e); + } + }; + + Util.make_properties(Keyboard, [ + ['target', 'wo', 'dom'], // DOM element that captures keyboard input + ['focused', 'rw', 'bool'], // Capture and send key events + + ['onKeyPress', 'rw', 'func'] // Handler for key press/release + ]); +})(); + +/* [module] export */ var Mouse; + +(function () { + Mouse = function (defaults) { + this._mouseCaptured = false; + + this._doubleClickTimer = null; + this._lastTouchPos = null; + + // Configuration attributes + Util.set_defaults(this, defaults, { + 'target': document, + 'focused': true, + 'scale': 1.0, + 'touchButton': 1 + }); + + this._eventHandlers = { + 'mousedown': this._handleMouseDown.bind(this), + 'mouseup': this._handleMouseUp.bind(this), + 'mousemove': this._handleMouseMove.bind(this), + 'mousewheel': this._handleMouseWheel.bind(this), + 'mousedisable': this._handleMouseDisable.bind(this) + }; + }; + + Mouse.prototype = { + // private methods + _captureMouse: function () { + // capturing the mouse ensures we get the mouseup event + if (this._target.setCapture) { + this._target.setCapture(); + } + + // some browsers give us mouseup events regardless, + // so if we never captured the mouse, we can disregard the event + this._mouseCaptured = true; + }, + + _releaseMouse: function () { + if (this._target.releaseCapture) { + this._target.releaseCapture(); + } + this._mouseCaptured = false; + }, + + _resetDoubleClickTimer: function () { + this._doubleClickTimer = null; + }, + + _handleMouseButton: function (e, down) { + if (!this._focused) { return true; } + + if (this._notify) { + this._notify(e); + } + + var evt = (e ? e : window.event); + var pos = Util.getEventPosition(e, this._target, this._scale); + + var bmask; + if (e.touches || e.changedTouches) { + // Touch device + + // When two touches occur within 500 ms of each other and are + // close enough together a double click is triggered. + if (down == 1) { + if (this._doubleClickTimer === null) { + this._lastTouchPos = pos; + } else { + clearTimeout(this._doubleClickTimer); + + // When the distance between the two touches is small enough + // force the position of the latter touch to the position of + // the first. + + var xs = this._lastTouchPos.x - pos.x; + var ys = this._lastTouchPos.y - pos.y; + var d = Math.sqrt((xs * xs) + (ys * ys)); + + // The goal is to trigger on a certain physical width, the + // devicePixelRatio brings us a bit closer but is not optimal. + var threshold = 20 * (window.devicePixelRatio || 1); + if (d < threshold) { + pos = this._lastTouchPos; + } + } + this._doubleClickTimer = setTimeout(this._resetDoubleClickTimer.bind(this), 500); + } + bmask = this._touchButton; + // If bmask is set + } else if (evt.which) { + /* everything except IE */ + bmask = 1 << evt.button; + } else { + /* IE including 9 */ + bmask = (evt.button & 0x1) + // Left + (evt.button & 0x2) * 2 + // Right + (evt.button & 0x4) / 2; // Middle + } + + if (this._onMouseButton) { + Util.Debug("onMouseButton " + (down ? "down" : "up") + + ", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask); + this._onMouseButton(pos.x, pos.y, down, bmask); + } + Util.stopEvent(e); + return false; + }, + + _handleMouseDown: function (e) { + this._captureMouse(); + this._handleMouseButton(e, 1); + }, + + _handleMouseUp: function (e) { + if (!this._mouseCaptured) { return; } + + this._handleMouseButton(e, 0); + this._releaseMouse(); + }, + + _handleMouseWheel: function (e) { + if (!this._focused) { return true; } + + if (this._notify) { + this._notify(e); + } + + var evt = (e ? e : window.event); + var pos = Util.getEventPosition(e, this._target, this._scale); + var wheelData = evt.detail ? evt.detail * -1 : evt.wheelDelta / 40; + var bmask; + if (wheelData > 0) { + bmask = 1 << 3; + } else { + bmask = 1 << 4; + } + + if (this._onMouseButton) { + this._onMouseButton(pos.x, pos.y, 1, bmask); + this._onMouseButton(pos.x, pos.y, 0, bmask); + } + Util.stopEvent(e); + return false; + }, + + _handleMouseMove: function (e) { + if (! this._focused) { return true; } + + if (this._notify) { + this._notify(e); + } + + var evt = (e ? e : window.event); + var pos = Util.getEventPosition(e, this._target, this._scale); + if (this._onMouseMove) { + this._onMouseMove(pos.x, pos.y); + } + Util.stopEvent(e); + return false; + }, + + _handleMouseDisable: function (e) { + if (!this._focused) { return true; } + + var evt = (e ? e : window.event); + var pos = Util.getEventPosition(e, this._target, this._scale); + + /* Stop propagation if inside canvas area */ + if ((pos.realx >= 0) && (pos.realy >= 0) && + (pos.realx < this._target.offsetWidth) && + (pos.realy < this._target.offsetHeight)) { + //Util.Debug("mouse event disabled"); + Util.stopEvent(e); + return false; + } + + return true; + }, + + + // Public methods + grab: function () { + var c = this._target; + + if ('ontouchstart' in document.documentElement) { + 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 { + 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 */ + document.addEventListener('click', this._eventHandlers.mousedisable); + document.body.addEventListener('contextmenu', this._eventHandlers.mousedisable); + }, + + ungrab: function () { + var c = this._target; + + if ('ontouchstart' in document.documentElement) { + 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 { + 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 */ + document.removeEventListener('click', this._eventHandlers.mousedisable); + document.body.removeEventListener('contextmenu', this._eventHandlers.mousedisable); + + } + }; + + Util.make_properties(Mouse, [ + ['target', 'ro', 'dom'], // DOM element that captures mouse input + ['notify', 'ro', 'func'], // Function to call to notify whenever a mouse event is received + ['focused', 'rw', 'bool'], // Capture and send mouse clicks/movement + ['scale', 'rw', 'float'], // Viewport scale factor 0.0 - 1.0 + + ['onMouseButton', 'rw', 'func'], // Handler for mouse button click/release + ['onMouseMove', 'rw', 'func'], // Handler for mouse movement + ['touchButton', 'rw', 'int'] // Button mask (1, 2, 4) for touch devices (0 means ignore clicks) + ]); +})(); diff --git a/core/input/keysym.js b/core/input/keysym.js new file mode 100644 index 0000000..5983c38 --- /dev/null +++ b/core/input/keysym.js @@ -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; */ diff --git a/core/input/keysymdef.js b/core/input/keysymdef.js new file mode 100644 index 0000000..f45d9d9 --- /dev/null +++ b/core/input/keysymdef.js @@ -0,0 +1,18 @@ +// This file describes mappings from Unicode codepoints to the keysym values +// (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; + var codepoints = {"32":32,"33":33,"34":34,"35":35,"36":36,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42,"43":43,"44":44,"45":45,"46":46,"47":47,"48":48,"49":49,"50":50,"51":51,"52":52,"53":53,"54":54,"55":55,"56":56,"57":57,"58":58,"59":59,"60":60,"61":61,"62":62,"63":63,"64":64,"65":65,"66":66,"67":67,"68":68,"69":69,"70":70,"71":71,"72":72,"73":73,"74":74,"75":75,"76":76,"77":77,"78":78,"79":79,"80":80,"81":81,"82":82,"83":83,"84":84,"85":85,"86":86,"87":87,"88":88,"89":89,"90":90,"91":91,"92":92,"93":93,"94":94,"95":95,"96":96,"97":97,"98":98,"99":99,"100":100,"101":101,"102":102,"103":103,"104":104,"105":105,"106":106,"107":107,"108":108,"109":109,"110":110,"111":111,"112":112,"113":113,"114":114,"115":115,"116":116,"117":117,"118":118,"119":119,"120":120,"121":121,"122":122,"123":123,"124":124,"125":125,"126":126,"160":160,"161":161,"162":162,"163":163,"164":164,"165":165,"166":166,"167":167,"168":168,"169":169,"170":170,"171":171,"172":172,"173":173,"174":174,"175":175,"176":176,"177":177,"178":178,"179":179,"180":180,"181":181,"182":182,"183":183,"184":184,"185":185,"186":186,"187":187,"188":188,"189":189,"190":190,"191":191,"192":192,"193":193,"194":194,"195":195,"196":196,"197":197,"198":198,"199":199,"200":200,"201":201,"202":202,"203":203,"204":204,"205":205,"206":206,"207":207,"208":208,"209":209,"210":210,"211":211,"212":212,"213":213,"214":214,"215":215,"216":216,"217":217,"218":218,"219":219,"220":220,"221":221,"222":222,"223":223,"224":224,"225":225,"226":226,"227":227,"228":228,"229":229,"230":230,"231":231,"232":232,"233":233,"234":234,"235":235,"236":236,"237":237,"238":238,"239":239,"240":240,"241":241,"242":242,"243":243,"244":244,"245":245,"246":246,"247":247,"248":248,"249":249,"250":250,"251":251,"252":252,"253":253,"254":254,"255":255,"256":960,"257":992,"258":451,"259":483,"260":417,"261":433,"262":454,"263":486,"264":710,"265":742,"266":709,"267":741,"268":456,"269":488,"270":463,"271":495,"272":464,"273":496,"274":938,"275":954,"278":972,"279":1004,"280":458,"281":490,"282":460,"283":492,"284":728,"285":760,"286":683,"287":699,"288":725,"289":757,"290":939,"291":955,"292":678,"293":694,"294":673,"295":689,"296":933,"297":949,"298":975,"299":1007,"300":16777516,"301":16777517,"302":967,"303":999,"304":681,"305":697,"308":684,"309":700,"310":979,"311":1011,"312":930,"313":453,"314":485,"315":934,"316":950,"317":421,"318":437,"321":419,"322":435,"323":465,"324":497,"325":977,"326":1009,"327":466,"328":498,"330":957,"331":959,"332":978,"333":1010,"336":469,"337":501,"338":5052,"339":5053,"340":448,"341":480,"342":931,"343":947,"344":472,"345":504,"346":422,"347":438,"348":734,"349":766,"350":426,"351":442,"352":425,"353":441,"354":478,"355":510,"356":427,"357":443,"358":940,"359":956,"360":989,"361":1021,"362":990,"363":1022,"364":733,"365":765,"366":473,"367":505,"368":475,"369":507,"370":985,"371":1017,"372":16777588,"373":16777589,"374":16777590,"375":16777591,"376":5054,"377":428,"378":444,"379":431,"380":447,"381":430,"382":446,"399":16777615,"402":2294,"415":16777631,"416":16777632,"417":16777633,"431":16777647,"432":16777648,"437":16777653,"438":16777654,"439":16777655,"466":16777681,"486":16777702,"487":16777703,"601":16777817,"629":16777845,"658":16777874,"711":439,"728":418,"729":511,"731":434,"733":445,"901":1966,"902":1953,"904":1954,"905":1955,"906":1956,"908":1959,"910":1960,"911":1963,"912":1974,"913":1985,"914":1986,"915":1987,"916":1988,"917":1989,"918":1990,"919":1991,"920":1992,"921":1993,"922":1994,"923":1995,"924":1996,"925":1997,"926":1998,"927":1999,"928":2000,"929":2001,"931":2002,"932":2004,"933":2005,"934":2006,"935":2007,"936":2008,"937":2009,"938":1957,"939":1961,"940":1969,"941":1970,"942":1971,"943":1972,"944":1978,"945":2017,"946":2018,"947":2019,"948":2020,"949":2021,"950":2022,"951":2023,"952":2024,"953":2025,"954":2026,"955":2027,"956":2028,"957":2029,"958":2030,"959":2031,"960":2032,"961":2033,"962":2035,"963":2034,"964":2036,"965":2037,"966":2038,"967":2039,"968":2040,"969":2041,"970":1973,"971":1977,"972":1975,"973":1976,"974":1979,"1025":1715,"1026":1713,"1027":1714,"1028":1716,"1029":1717,"1030":1718,"1031":1719,"1032":1720,"1033":1721,"1034":1722,"1035":1723,"1036":1724,"1038":1726,"1039":1727,"1040":1761,"1041":1762,"1042":1783,"1043":1767,"1044":1764,"1045":1765,"1046":1782,"1047":1786,"1048":1769,"1049":1770,"1050":1771,"1051":1772,"1052":1773,"1053":1774,"1054":1775,"1055":1776,"1056":1778,"1057":1779,"1058":1780,"1059":1781,"1060":1766,"1061":1768,"1062":1763,"1063":1790,"1064":1787,"1065":1789,"1066":1791,"1067":1785,"1068":1784,"1069":1788,"1070":1760,"1071":1777,"1072":1729,"1073":1730,"1074":1751,"1075":1735,"1076":1732,"1077":1733,"1078":1750,"1079":1754,"1080":1737,"1081":1738,"1082":1739,"1083":1740,"1084":1741,"1085":1742,"1086":1743,"1087":1744,"1088":1746,"1089":1747,"1090":1748,"1091":1749,"1092":1734,"1093":1736,"1094":1731,"1095":1758,"1096":1755,"1097":1757,"1098":1759,"1099":1753,"1100":1752,"1101":1756,"1102":1728,"1103":1745,"1105":1699,"1106":1697,"1107":1698,"1108":1700,"1109":1701,"1110":1702,"1111":1703,"1112":1704,"1113":1705,"1114":1706,"1115":1707,"1116":1708,"1118":1710,"1119":1711,"1168":1725,"1169":1709,"1170":16778386,"1171":16778387,"1174":16778390,"1175":16778391,"1178":16778394,"1179":16778395,"1180":16778396,"1181":16778397,"1186":16778402,"1187":16778403,"1198":16778414,"1199":16778415,"1200":16778416,"1201":16778417,"1202":16778418,"1203":16778419,"1206":16778422,"1207":16778423,"1208":16778424,"1209":16778425,"1210":16778426,"1211":16778427,"1240":16778456,"1241":16778457,"1250":16778466,"1251":16778467,"1256":16778472,"1257":16778473,"1262":16778478,"1263":16778479,"1329":16778545,"1330":16778546,"1331":16778547,"1332":16778548,"1333":16778549,"1334":16778550,"1335":16778551,"1336":16778552,"1337":16778553,"1338":16778554,"1339":16778555,"1340":16778556,"1341":16778557,"1342":16778558,"1343":16778559,"1344":16778560,"1345":16778561,"1346":16778562,"1347":16778563,"1348":16778564,"1349":16778565,"1350":16778566,"1351":16778567,"1352":16778568,"1353":16778569,"1354":16778570,"1355":16778571,"1356":16778572,"1357":16778573,"1358":16778574,"1359":16778575,"1360":16778576,"1361":16778577,"1362":16778578,"1363":16778579,"1364":16778580,"1365":16778581,"1366":16778582,"1370":16778586,"1371":16778587,"1372":16778588,"1373":16778589,"1374":16778590,"1377":16778593,"1378":16778594,"1379":16778595,"1380":16778596,"1381":16778597,"1382":16778598,"1383":16778599,"1384":16778600,"1385":16778601,"1386":16778602,"1387":16778603,"1388":16778604,"1389":16778605,"1390":16778606,"1391":16778607,"1392":16778608,"1393":16778609,"1394":16778610,"1395":16778611,"1396":16778612,"1397":16778613,"1398":16778614,"1399":16778615,"1400":16778616,"1401":16778617,"1402":16778618,"1403":16778619,"1404":16778620,"1405":16778621,"1406":16778622,"1407":16778623,"1408":16778624,"1409":16778625,"1410":16778626,"1411":16778627,"1412":16778628,"1413":16778629,"1414":16778630,"1415":16778631,"1417":16778633,"1418":16778634,"1488":3296,"1489":3297,"1490":3298,"1491":3299,"1492":3300,"1493":3301,"1494":3302,"1495":3303,"1496":3304,"1497":3305,"1498":3306,"1499":3307,"1500":3308,"1501":3309,"1502":3310,"1503":3311,"1504":3312,"1505":3313,"1506":3314,"1507":3315,"1508":3316,"1509":3317,"1510":3318,"1511":3319,"1512":3320,"1513":3321,"1514":3322,"1548":1452,"1563":1467,"1567":1471,"1569":1473,"1570":1474,"1571":1475,"1572":1476,"1573":1477,"1574":1478,"1575":1479,"1576":1480,"1577":1481,"1578":1482,"1579":1483,"1580":1484,"1581":1485,"1582":1486,"1583":1487,"1584":1488,"1585":1489,"1586":1490,"1587":1491,"1588":1492,"1589":1493,"1590":1494,"1591":1495,"1592":1496,"1593":1497,"1594":1498,"1600":1504,"1601":1505,"1602":1506,"1603":1507,"1604":1508,"1605":1509,"1606":1510,"1607":1511,"1608":1512,"1609":1513,"1610":1514,"1611":1515,"1612":1516,"1613":1517,"1614":1518,"1615":1519,"1616":1520,"1617":1521,"1618":1522,"1619":16778835,"1620":16778836,"1621":16778837,"1632":16778848,"1633":16778849,"1634":16778850,"1635":16778851,"1636":16778852,"1637":16778853,"1638":16778854,"1639":16778855,"1640":16778856,"1641":16778857,"1642":16778858,"1648":16778864,"1657":16778873,"1662":16778878,"1670":16778886,"1672":16778888,"1681":16778897,"1688":16778904,"1700":16778916,"1705":16778921,"1711":16778927,"1722":16778938,"1726":16778942,"1729":16778945,"1740":16778956,"1746":16778962,"1748":16778964,"1776":16778992,"1777":16778993,"1778":16778994,"1779":16778995,"1780":16778996,"1781":16778997,"1782":16778998,"1783":16778999,"1784":16779000,"1785":16779001,"3458":16780674,"3459":16780675,"3461":16780677,"3462":16780678,"3463":16780679,"3464":16780680,"3465":16780681,"3466":16780682,"3467":16780683,"3468":16780684,"3469":16780685,"3470":16780686,"3471":16780687,"3472":16780688,"3473":16780689,"3474":16780690,"3475":16780691,"3476":16780692,"3477":16780693,"3478":16780694,"3482":16780698,"3483":16780699,"3484":16780700,"3485":16780701,"3486":16780702,"3487":16780703,"3488":16780704,"3489":16780705,"3490":16780706,"3491":16780707,"3492":16780708,"3493":16780709,"3494":16780710,"3495":16780711,"3496":16780712,"3497":16780713,"3498":16780714,"3499":16780715,"3500":16780716,"3501":16780717,"3502":16780718,"3503":16780719,"3504":16780720,"3505":16780721,"3507":16780723,"3508":16780724,"3509":16780725,"3510":16780726,"3511":16780727,"3512":16780728,"3513":16780729,"3514":16780730,"3515":16780731,"3517":16780733,"3520":16780736,"3521":16780737,"3522":16780738,"3523":16780739,"3524":16780740,"3525":16780741,"3526":16780742,"3530":16780746,"3535":16780751,"3536":16780752,"3537":16780753,"3538":16780754,"3539":16780755,"3540":16780756,"3542":16780758,"3544":16780760,"3545":16780761,"3546":16780762,"3547":16780763,"3548":16780764,"3549":16780765,"3550":16780766,"3551":16780767,"3570":16780786,"3571":16780787,"3572":16780788,"3585":3489,"3586":3490,"3587":3491,"3588":3492,"3589":3493,"3590":3494,"3591":3495,"3592":3496,"3593":3497,"3594":3498,"3595":3499,"3596":3500,"3597":3501,"3598":3502,"3599":3503,"3600":3504,"3601":3505,"3602":3506,"3603":3507,"3604":3508,"3605":3509,"3606":3510,"3607":3511,"3608":3512,"3609":3513,"3610":3514,"3611":3515,"3612":3516,"3613":3517,"3614":3518,"3615":3519,"3616":3520,"3617":3521,"3618":3522,"3619":3523,"3620":3524,"3621":3525,"3622":3526,"3623":3527,"3624":3528,"3625":3529,"3626":3530,"3627":3531,"3628":3532,"3629":3533,"3630":3534,"3631":3535,"3632":3536,"3633":3537,"3634":3538,"3635":3539,"3636":3540,"3637":3541,"3638":3542,"3639":3543,"3640":3544,"3641":3545,"3642":3546,"3647":3551,"3648":3552,"3649":3553,"3650":3554,"3651":3555,"3652":3556,"3653":3557,"3654":3558,"3655":3559,"3656":3560,"3657":3561,"3658":3562,"3659":3563,"3660":3564,"3661":3565,"3664":3568,"3665":3569,"3666":3570,"3667":3571,"3668":3572,"3669":3573,"3670":3574,"3671":3575,"3672":3576,"3673":3577,"4304":16781520,"4305":16781521,"4306":16781522,"4307":16781523,"4308":16781524,"4309":16781525,"4310":16781526,"4311":16781527,"4312":16781528,"4313":16781529,"4314":16781530,"4315":16781531,"4316":16781532,"4317":16781533,"4318":16781534,"4319":16781535,"4320":16781536,"4321":16781537,"4322":16781538,"4323":16781539,"4324":16781540,"4325":16781541,"4326":16781542,"4327":16781543,"4328":16781544,"4329":16781545,"4330":16781546,"4331":16781547,"4332":16781548,"4333":16781549,"4334":16781550,"4335":16781551,"4336":16781552,"4337":16781553,"4338":16781554,"4339":16781555,"4340":16781556,"4341":16781557,"4342":16781558,"7682":16784898,"7683":16784899,"7690":16784906,"7691":16784907,"7710":16784926,"7711":16784927,"7734":16784950,"7735":16784951,"7744":16784960,"7745":16784961,"7766":16784982,"7767":16784983,"7776":16784992,"7777":16784993,"7786":16785002,"7787":16785003,"7808":16785024,"7809":16785025,"7810":16785026,"7811":16785027,"7812":16785028,"7813":16785029,"7818":16785034,"7819":16785035,"7840":16785056,"7841":16785057,"7842":16785058,"7843":16785059,"7844":16785060,"7845":16785061,"7846":16785062,"7847":16785063,"7848":16785064,"7849":16785065,"7850":16785066,"7851":16785067,"7852":16785068,"7853":16785069,"7854":16785070,"7855":16785071,"7856":16785072,"7857":16785073,"7858":16785074,"7859":16785075,"7860":16785076,"7861":16785077,"7862":16785078,"7863":16785079,"7864":16785080,"7865":16785081,"7866":16785082,"7867":16785083,"7868":16785084,"7869":16785085,"7870":16785086,"7871":16785087,"7872":16785088,"7873":16785089,"7874":16785090,"7875":16785091,"7876":16785092,"7877":16785093,"7878":16785094,"7879":16785095,"7880":16785096,"7881":16785097,"7882":16785098,"7883":16785099,"7884":16785100,"7885":16785101,"7886":16785102,"7887":16785103,"7888":16785104,"7889":16785105,"7890":16785106,"7891":16785107,"7892":16785108,"7893":16785109,"7894":16785110,"7895":16785111,"7896":16785112,"7897":16785113,"7898":16785114,"7899":16785115,"7900":16785116,"7901":16785117,"7902":16785118,"7903":16785119,"7904":16785120,"7905":16785121,"7906":16785122,"7907":16785123,"7908":16785124,"7909":16785125,"7910":16785126,"7911":16785127,"7912":16785128,"7913":16785129,"7914":16785130,"7915":16785131,"7916":16785132,"7917":16785133,"7918":16785134,"7919":16785135,"7920":16785136,"7921":16785137,"7922":16785138,"7923":16785139,"7924":16785140,"7925":16785141,"7926":16785142,"7927":16785143,"7928":16785144,"7929":16785145,"8194":2722,"8195":2721,"8196":2723,"8197":2724,"8199":2725,"8200":2726,"8201":2727,"8202":2728,"8210":2747,"8211":2730,"8212":2729,"8213":1967,"8215":3295,"8216":2768,"8217":2769,"8218":2813,"8220":2770,"8221":2771,"8222":2814,"8224":2801,"8225":2802,"8226":2790,"8229":2735,"8230":2734,"8240":2773,"8242":2774,"8243":2775,"8248":2812,"8254":1150,"8304":16785520,"8308":16785524,"8309":16785525,"8310":16785526,"8311":16785527,"8312":16785528,"8313":16785529,"8320":16785536,"8321":16785537,"8322":16785538,"8323":16785539,"8324":16785540,"8325":16785541,"8326":16785542,"8327":16785543,"8328":16785544,"8329":16785545,"8352":16785568,"8353":16785569,"8354":16785570,"8355":16785571,"8356":16785572,"8357":16785573,"8358":16785574,"8359":16785575,"8360":16785576,"8361":3839,"8362":16785578,"8363":16785579,"8364":8364,"8453":2744,"8470":1712,"8471":2811,"8478":2772,"8482":2761,"8531":2736,"8532":2737,"8533":2738,"8534":2739,"8535":2740,"8536":2741,"8537":2742,"8538":2743,"8539":2755,"8540":2756,"8541":2757,"8542":2758,"8592":2299,"8593":2300,"8594":2301,"8595":2302,"8658":2254,"8660":2253,"8706":2287,"8709":16785925,"8711":2245,"8712":16785928,"8713":16785929,"8715":16785931,"8728":3018,"8730":2262,"8731":16785947,"8732":16785948,"8733":2241,"8734":2242,"8743":2270,"8744":2271,"8745":2268,"8746":2269,"8747":2239,"8748":16785964,"8749":16785965,"8756":2240,"8757":16785973,"8764":2248,"8771":2249,"8773":16785992,"8775":16785991,"8800":2237,"8801":2255,"8802":16786018,"8803":16786019,"8804":2236,"8805":2238,"8834":2266,"8835":2267,"8866":3068,"8867":3036,"8868":3010,"8869":3022,"8968":3027,"8970":3012,"8981":2810,"8992":2212,"8993":2213,"9109":3020,"9115":2219,"9117":2220,"9118":2221,"9120":2222,"9121":2215,"9123":2216,"9124":2217,"9126":2218,"9128":2223,"9132":2224,"9143":2209,"9146":2543,"9147":2544,"9148":2546,"9149":2547,"9225":2530,"9226":2533,"9227":2537,"9228":2531,"9229":2532,"9251":2732,"9252":2536,"9472":2211,"9474":2214,"9484":2210,"9488":2539,"9492":2541,"9496":2538,"9500":2548,"9508":2549,"9516":2551,"9524":2550,"9532":2542,"9618":2529,"9642":2791,"9643":2785,"9644":2779,"9645":2786,"9646":2783,"9647":2767,"9650":2792,"9651":2787,"9654":2781,"9655":2765,"9660":2793,"9661":2788,"9664":2780,"9665":2764,"9670":2528,"9675":2766,"9679":2782,"9702":2784,"9734":2789,"9742":2809,"9747":2762,"9756":2794,"9758":2795,"9792":2808,"9794":2807,"9827":2796,"9829":2798,"9830":2797,"9837":2806,"9839":2805,"10003":2803,"10007":2804,"10013":2777,"10016":2800,"10216":2748,"10217":2750,"10240":16787456,"10241":16787457,"10242":16787458,"10243":16787459,"10244":16787460,"10245":16787461,"10246":16787462,"10247":16787463,"10248":16787464,"10249":16787465,"10250":16787466,"10251":16787467,"10252":16787468,"10253":16787469,"10254":16787470,"10255":16787471,"10256":16787472,"10257":16787473,"10258":16787474,"10259":16787475,"10260":16787476,"10261":16787477,"10262":16787478,"10263":16787479,"10264":16787480,"10265":16787481,"10266":16787482,"10267":16787483,"10268":16787484,"10269":16787485,"10270":16787486,"10271":16787487,"10272":16787488,"10273":16787489,"10274":16787490,"10275":16787491,"10276":16787492,"10277":16787493,"10278":16787494,"10279":16787495,"10280":16787496,"10281":16787497,"10282":16787498,"10283":16787499,"10284":16787500,"10285":16787501,"10286":16787502,"10287":16787503,"10288":16787504,"10289":16787505,"10290":16787506,"10291":16787507,"10292":16787508,"10293":16787509,"10294":16787510,"10295":16787511,"10296":16787512,"10297":16787513,"10298":16787514,"10299":16787515,"10300":16787516,"10301":16787517,"10302":16787518,"10303":16787519,"10304":16787520,"10305":16787521,"10306":16787522,"10307":16787523,"10308":16787524,"10309":16787525,"10310":16787526,"10311":16787527,"10312":16787528,"10313":16787529,"10314":16787530,"10315":16787531,"10316":16787532,"10317":16787533,"10318":16787534,"10319":16787535,"10320":16787536,"10321":16787537,"10322":16787538,"10323":16787539,"10324":16787540,"10325":16787541,"10326":16787542,"10327":16787543,"10328":16787544,"10329":16787545,"10330":16787546,"10331":16787547,"10332":16787548,"10333":16787549,"10334":16787550,"10335":16787551,"10336":16787552,"10337":16787553,"10338":16787554,"10339":16787555,"10340":16787556,"10341":16787557,"10342":16787558,"10343":16787559,"10344":16787560,"10345":16787561,"10346":16787562,"10347":16787563,"10348":16787564,"10349":16787565,"10350":16787566,"10351":16787567,"10352":16787568,"10353":16787569,"10354":16787570,"10355":16787571,"10356":16787572,"10357":16787573,"10358":16787574,"10359":16787575,"10360":16787576,"10361":16787577,"10362":16787578,"10363":16787579,"10364":16787580,"10365":16787581,"10366":16787582,"10367":16787583,"10368":16787584,"10369":16787585,"10370":16787586,"10371":16787587,"10372":16787588,"10373":16787589,"10374":16787590,"10375":16787591,"10376":16787592,"10377":16787593,"10378":16787594,"10379":16787595,"10380":16787596,"10381":16787597,"10382":16787598,"10383":16787599,"10384":16787600,"10385":16787601,"10386":16787602,"10387":16787603,"10388":16787604,"10389":16787605,"10390":16787606,"10391":16787607,"10392":16787608,"10393":16787609,"10394":16787610,"10395":16787611,"10396":16787612,"10397":16787613,"10398":16787614,"10399":16787615,"10400":16787616,"10401":16787617,"10402":16787618,"10403":16787619,"10404":16787620,"10405":16787621,"10406":16787622,"10407":16787623,"10408":16787624,"10409":16787625,"10410":16787626,"10411":16787627,"10412":16787628,"10413":16787629,"10414":16787630,"10415":16787631,"10416":16787632,"10417":16787633,"10418":16787634,"10419":16787635,"10420":16787636,"10421":16787637,"10422":16787638,"10423":16787639,"10424":16787640,"10425":16787641,"10426":16787642,"10427":16787643,"10428":16787644,"10429":16787645,"10430":16787646,"10431":16787647,"10432":16787648,"10433":16787649,"10434":16787650,"10435":16787651,"10436":16787652,"10437":16787653,"10438":16787654,"10439":16787655,"10440":16787656,"10441":16787657,"10442":16787658,"10443":16787659,"10444":16787660,"10445":16787661,"10446":16787662,"10447":16787663,"10448":16787664,"10449":16787665,"10450":16787666,"10451":16787667,"10452":16787668,"10453":16787669,"10454":16787670,"10455":16787671,"10456":16787672,"10457":16787673,"10458":16787674,"10459":16787675,"10460":16787676,"10461":16787677,"10462":16787678,"10463":16787679,"10464":16787680,"10465":16787681,"10466":16787682,"10467":16787683,"10468":16787684,"10469":16787685,"10470":16787686,"10471":16787687,"10472":16787688,"10473":16787689,"10474":16787690,"10475":16787691,"10476":16787692,"10477":16787693,"10478":16787694,"10479":16787695,"10480":16787696,"10481":16787697,"10482":16787698,"10483":16787699,"10484":16787700,"10485":16787701,"10486":16787702,"10487":16787703,"10488":16787704,"10489":16787705,"10490":16787706,"10491":16787707,"10492":16787708,"10493":16787709,"10494":16787710,"10495":16787711,"12289":1188,"12290":1185,"12300":1186,"12301":1187,"12443":1246,"12444":1247,"12449":1191,"12450":1201,"12451":1192,"12452":1202,"12453":1193,"12454":1203,"12455":1194,"12456":1204,"12457":1195,"12458":1205,"12459":1206,"12461":1207,"12463":1208,"12465":1209,"12467":1210,"12469":1211,"12471":1212,"12473":1213,"12475":1214,"12477":1215,"12479":1216,"12481":1217,"12483":1199,"12484":1218,"12486":1219,"12488":1220,"12490":1221,"12491":1222,"12492":1223,"12493":1224,"12494":1225,"12495":1226,"12498":1227,"12501":1228,"12504":1229,"12507":1230,"12510":1231,"12511":1232,"12512":1233,"12513":1234,"12514":1235,"12515":1196,"12516":1236,"12517":1197,"12518":1237,"12519":1198,"12520":1238,"12521":1239,"12522":1240,"12523":1241,"12524":1242,"12525":1243,"12527":1244,"12530":1190,"12531":1245,"12539":1189,"12540":1200}; + + function lookup(k) { return k ? {keysym: k, keyname: keynames ? keynames[k] : k} : undefined; } + return { + fromUnicode : function(u) { return lookup(codepoints[u]); }, + lookup : lookup + }; +})(); + +/* [module] export default keysyms */ diff --git a/core/input/util.js b/core/input/util.js new file mode 100644 index 0000000..efdcced --- /dev/null +++ b/core/input/util.js @@ -0,0 +1,682 @@ +/* [module] + * import KeyTable from "./keysym"; + * import keysyms from "./keysymdef"; + */ + +var KeyboardUtil = {}; + +(function() { + "use strict"; + + function substituteCodepoint(cp) { + // Any Unicode code points which do not have corresponding keysym entries + // can be swapped out for another code point by adding them to this table + var substitutions = { + // {S,s} with comma below -> {S,s} with cedilla + 0x218 : 0x15e, + 0x219 : 0x15f, + // {T,t} with comma below -> {T,t} with cedilla + 0x21a : 0x162, + 0x21b : 0x163 + }; + + var sub = substitutions[cp]; + return sub ? sub : cp; + } + + function isMac() { + return navigator && !!(/mac/i).exec(navigator.platform); + } + function isWindows() { + return navigator && !!(/win/i).exec(navigator.platform); + } + function isLinux() { + return navigator && !!(/linux/i).exec(navigator.platform); + } + + // Return true if a modifier which is not the specified char modifier (and is not shift) is down + function hasShortcutModifier(charModifier, currentModifiers) { + var mods = {}; + for (var key in currentModifiers) { + if (parseInt(key) !== KeyTable.XK_Shift_L) { + mods[key] = currentModifiers[key]; + } + } + + var sum = 0; + for (var k in currentModifiers) { + if (mods[k]) { + ++sum; + } + } + if (hasCharModifier(charModifier, mods)) { + return sum > charModifier.length; + } + else { + return sum > 0; + } + } + + // Return true if the specified char modifier is currently down + function hasCharModifier(charModifier, currentModifiers) { + if (charModifier.length === 0) { return false; } + + for (var i = 0; i < charModifier.length; ++i) { + if (!currentModifiers[charModifier[i]]) { + return false; + } + } + return true; + } + + // Helper object tracking modifier key state + // and generates fake key events to compensate if it gets out of sync + function ModifierSync(charModifier) { + if (!charModifier) { + if (isMac()) { + // on Mac, Option (AKA Alt) is used as a char modifier + charModifier = [KeyTable.XK_Alt_L]; + } + else if (isWindows()) { + // on Windows, Ctrl+Alt is used as a char modifier + 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 = [KeyTable.XK_ISO_Level3_Shift]; + } + else { + charModifier = []; + } + } + + var state = {}; + 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 = []; + function syncKey(keysym) { + return {keysym: keysyms.lookup(keysym), type: state[keysym] ? 'keydown' : 'keyup'}; + } + + if (evt.ctrlKey !== undefined && + 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[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[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[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[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; + } + function syncKeyEvent(evt, down) { + var obj = getKeysym(evt); + var keysym = obj ? obj.keysym : null; + + // first, apply the event itself, if relevant + if (keysym !== null && state[keysym] !== undefined) { + state[keysym] = down; + } + return sync(evt, keysym); + } + + return { + // sync on the appropriate keyboard event + keydown: function(evt) { return syncKeyEvent(evt, true);}, + keyup: function(evt) { return syncKeyEvent(evt, false);}, + // Call this with a non-keyboard event (such as mouse events) to use its modifier state to synchronize anyway + syncAny: function(evt) { return sync(evt);}, + + // is a shortcut modifier down? + hasShortcutModifier: function() { return hasShortcutModifier(charModifier, state); }, + // if a char modifier is down, return the keys it consists of, otherwise return null + activeCharModifier: function() { return hasCharModifier(charModifier, state) ? charModifier : null; } + }; + } + + // Get a key ID from a keyboard event + // May be a string or an integer depending on the available properties + function getKey(evt){ + if ('keyCode' in evt && 'key' in evt) { + return evt.key + ':' + evt.keyCode; + } + else if ('keyCode' in evt) { + return evt.keyCode; + } + else { + return evt.key; + } + } + + // Get the most reliable keysym value we can get from a key event + // if char/charCode is available, prefer those, otherwise fall back to key/keyCode/which + function getKeysym(evt){ + var codepoint; + if (evt.char && evt.char.length === 1) { + codepoint = evt.char.charCodeAt(); + } + else if (evt.charCode) { + codepoint = evt.charCode; + } + else if (evt.keyCode && evt.type === 'keypress') { + // IE10 stores the char code as keyCode, and has no other useful properties + codepoint = evt.keyCode; + } + if (codepoint) { + var res = keysyms.fromUnicode(substituteCodepoint(codepoint)); + if (res) { + return res; + } + } + // we could check evt.key here. + // Legal values are defined in http://www.w3.org/TR/DOM-Level-3-Events/#key-values-list, + // so we "just" need to map them to keysym, but AFAIK this is only available in IE10, which also provides evt.key + // so we don't *need* it yet + if (evt.keyCode) { + return keysyms.lookup(keysymFromKeyCode(evt.keyCode, evt.shiftKey)); + } + if (evt.which) { + return keysyms.lookup(keysymFromKeyCode(evt.which, evt.shiftKey)); + } + return null; + } + + // Given a keycode, try to predict which keysym it might be. + // If the keycode is unknown, null is returned. + function keysymFromKeyCode(keycode, shiftPressed) { + if (typeof(keycode) !== 'number') { + return null; + } + // won't be accurate for azerty + if (keycode >= 0x30 && keycode <= 0x39) { + return keycode; // digit + } + if (keycode >= 0x41 && keycode <= 0x5a) { + // remap to lowercase unless shift is down + return shiftPressed ? keycode : keycode + 32; // A-Z + } + if (keycode >= 0x60 && keycode <= 0x69) { + return KeyTable.XK_KP_0 + (keycode - 0x60); // numpad 0-9 + } + + switch(keycode) { + 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}); + } + + // if the key is a known non-character key (any key which doesn't generate character data) + // return its keysym value. Otherwise return null + function nonCharacterKey(evt) { + // evt.key not implemented yet + if (!evt.keyCode) { return null; } + var keycode = evt.keyCode; + + if (keycode >= 0x70 && keycode <= 0x87) { + return KeyTable.XK_F1 + keycode - 0x70; // F1-F24 + } + switch (keycode) { + + case 8 : return KeyTable.XK_BackSpace; + case 13 : return KeyTable.XK_Return; + + case 9 : return KeyTable.XK_Tab; + + case 27 : return KeyTable.XK_Escape; + case 46 : return KeyTable.XK_Delete; + + 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 KeyTable.XK_Left; + case 38 : return KeyTable.XK_Up; + case 39 : return KeyTable.XK_Right; + case 40 : return KeyTable.XK_Down; + + 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 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; + } + } + + KeyboardUtil.hasShortcutModifier = hasShortcutModifier; + KeyboardUtil.hasCharModifier = hasCharModifier; + KeyboardUtil.ModifierSync = ModifierSync; + KeyboardUtil.getKey = getKey; + KeyboardUtil.getKeysym = getKeysym; + KeyboardUtil.keysymFromKeyCode = keysymFromKeyCode; + KeyboardUtil.nonCharacterKey = nonCharacterKey; + KeyboardUtil.substituteCodepoint = substituteCodepoint; +})(); + +KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) { + "use strict"; + + function sendAll(evts) { + for (var i = 0; i < evts.length; ++i) { + next(evts[i]); + } + } + + var numPadCodes = ["Numpad0", "Numpad1", "Numpad2", + "Numpad3", "Numpad4", "Numpad5", "Numpad6", + "Numpad7", "Numpad8", "Numpad9", "NumpadDecimal"]; + + var numLockOnKeySyms = { + "Numpad0": 0xffb0, "Numpad1": 0xffb1, "Numpad2": 0xffb2, + "Numpad3": 0xffb3, "Numpad4": 0xffb4, "Numpad5": 0xffb5, + "Numpad6": 0xffb6, "Numpad7": 0xffb7, "Numpad8": 0xffb8, + "Numpad9": 0xffb9, "NumpadDecimal": 0xffac + }; + + var numLockOnKeyCodes = [96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 108, 110]; + + function isNumPadMultiKey(evt) { + return (numPadCodes.indexOf(evt.code) !== -1); + } + + function getNumPadKeySym(evt) { + if (numLockOnKeyCodes.indexOf(evt.keyCode) !== -1) { + return numLockOnKeySyms[evt.code]; + } + return 0; + } + + function process(evt, type) { + var result = {type: type}; + result.code = evt.code; + result.keysym = 0; + + if (isNumPadMultiKey(evt)) { + result.keysym = getNumPadKeySym(evt); + } + + var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier(); + var isShift = evt.keyCode === 0x10 || evt.key === 'Shift'; + + var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!KeyboardUtil.nonCharacterKey(evt)); + + next(result); + return suppress; + } + return { + keydown: function(evt) { + sendAll(modifierState.keydown(evt)); + return process(evt, 'keydown'); + }, + keypress: function(evt) { + return true; + }, + keyup: function(evt) { + sendAll(modifierState.keyup(evt)); + return process(evt, 'keyup'); + }, + syncModifiers: function(evt) { + sendAll(modifierState.syncAny(evt)); + }, + releaseAll: function() { next({type: 'releaseall'}); } + }; +}; + +KeyboardUtil.TrackQEMUKeyState = function(next) { + "use strict"; + var state = []; + + return function (evt) { + var last = state.length !== 0 ? state[state.length-1] : null; + + switch (evt.type) { + case 'keydown': + + if (!last || last.code !== evt.code) { + last = {code: evt.code}; + + if (state.length > 0 && state[state.length-1].code == 'ControlLeft') { + if (evt.code !== 'AltRight') { + next({code: 'ControlLeft', type: 'keydown', keysym: 0}); + } else { + state.pop(); + } + } + state.push(last); + } + if (evt.code !== 'ControlLeft') { + next(evt); + } + break; + + case 'keyup': + if (state.length === 0) { + return; + } + var idx = null; + // do we have a matching key tracked as being down? + for (var i = 0; i !== state.length; ++i) { + if (state[i].code === evt.code) { + idx = i; + break; + } + } + // if we couldn't find a match (it happens), assume it was the last key pressed + if (idx === null) { + if (evt.code === 'ControlLeft') { + return; + } + idx = state.length - 1; + } + + state.splice(idx, 1); + next(evt); + break; + case 'releaseall': + /* jshint shadow: true */ + for (var i = 0; i < state.length; ++i) { + next({code: state[i].code, keysym: 0, type: 'keyup'}); + } + /* jshint shadow: false */ + state = []; + } + }; +}; + +// Takes a DOM keyboard event and: +// - determines which keysym it represents +// - determines a keyId identifying the key that was pressed (corresponding to the key/keyCode properties on the DOM event) +// - synthesizes events to synchronize modifier key state between which modifiers are actually down, and which we thought were down +// - 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) +KeyboardUtil.KeyEventDecoder = function(modifierState, next) { + "use strict"; + function sendAll(evts) { + for (var i = 0; i < evts.length; ++i) { + next(evts[i]); + } + } + function process(evt, type) { + var result = {type: type}; + var keyId = KeyboardUtil.getKey(evt); + if (keyId) { + result.keyId = keyId; + } + + 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' || KeyboardUtil.nonCharacterKey(evt) || hasModifier)) { + result.keysym = keysym; + } + + var isShift = evt.keyCode === 0x10 || evt.key === 'Shift'; + + // 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() || !!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() && !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(); + + // If we have a char modifier down, and we're able to determine a keysym reliably + // then (a) we know to treat the modifier as a char modifier, + // and (b) we'll have to "escape" the modifier to undo the modifier when sending the char. + if (active && keysym) { + var isCharModifier = false; + for (var i = 0; i < active.length; ++i) { + if (active[i] === keysym.keysym) { + isCharModifier = true; + } + } + if (type === 'keypress' && !isCharModifier) { + result.escape = modifierState.activeCharModifier(); + } + } + + if (stall) { + // insert a fake "stall" event + next({type: 'stall'}); + } + next(result); + + return suppress; + } + + return { + keydown: function(evt) { + sendAll(modifierState.keydown(evt)); + return process(evt, 'keydown'); + }, + keypress: function(evt) { + return process(evt, 'keypress'); + }, + keyup: function(evt) { + sendAll(modifierState.keyup(evt)); + return process(evt, 'keyup'); + }, + syncModifiers: function(evt) { + sendAll(modifierState.syncAny(evt)); + }, + 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. +// For example, on Windows, AltGr is synonymous with Ctrl-Alt. On a Danish keyboard layout, AltGr-2 yields a @, but Ctrl-Alt-D does nothing +// 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 +KeyboardUtil.VerifyCharModifier = function(next) { + "use strict"; + var queue = []; + var timer = null; + function process() { + if (timer) { + return; + } + + var delayProcess = function () { + clearTimeout(timer); + timer = null; + process(); + }; + + while (queue.length !== 0) { + var cur = queue[0]; + queue = queue.splice(1); + switch (cur.type) { + case 'stall': + // insert a delay before processing available events. + /* jshint loopfunc: true */ + timer = setTimeout(delayProcess, 5); + /* jshint loopfunc: false */ + return; + case 'keydown': + // is the next element a keypress? Then we should merge the two + if (queue.length !== 0 && queue[0].type === 'keypress') { + // Firefox sends keypress even when no char is generated. + // so, if keypress keysym is the same as we'd have guessed from keydown, + // the modifier didn't have any effect, and should not be escaped + if (queue[0].escape && (!cur.keysym || cur.keysym.keysym !== queue[0].keysym.keysym)) { + cur.escape = queue[0].escape; + } + cur.keysym = queue[0].keysym; + queue = queue.splice(1); + } + break; + } + + // swallow stall events, and pass all others to the next stage + if (cur.type !== 'stall') { + next(cur); + } + } + } + return function(evt) { + 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 +KeyboardUtil.TrackKeyState = function(next) { + "use strict"; + var state = []; + + return function (evt) { + var last = state.length !== 0 ? state[state.length-1] : null; + + switch (evt.type) { + case 'keydown': + // insert a new entry if last seen key was different. + if (!last || !evt.keyId || last.keyId !== evt.keyId) { + last = {keyId: evt.keyId, keysyms: {}}; + state.push(last); + } + if (evt.keysym) { + // make sure last event contains this keysym (a single "logical" keyevent + // can cause multiple key events to be sent to the VNC server) + last.keysyms[evt.keysym.keysym] = evt.keysym; + last.ignoreKeyPress = true; + next(evt); + } + break; + case 'keypress': + if (!last) { + last = {keyId: evt.keyId, keysyms: {}}; + state.push(last); + } + if (!evt.keysym) { + console.log('keypress with no keysym:', evt); + } + + // If we didn't expect a keypress, and already sent a keydown to the VNC server + // based on the keydown, make sure to skip this event. + if (evt.keysym && !last.ignoreKeyPress) { + last.keysyms[evt.keysym.keysym] = evt.keysym; + evt.type = 'keydown'; + next(evt); + } + break; + case 'keyup': + if (state.length === 0) { + return; + } + var idx = null; + // do we have a matching key tracked as being down? + for (var i = 0; i !== state.length; ++i) { + if (state[i].keyId === evt.keyId) { + idx = i; + break; + } + } + // if we couldn't find a match (it happens), assume it was the last key pressed + if (idx === null) { + idx = state.length - 1; + } + + var item = state.splice(idx, 1)[0]; + // for each keysym tracked by this key entry, clone the current event and override the keysym + var clone = (function(){ + function Clone(){} + return function (obj) { Clone.prototype=obj; return new Clone(); }; + }()); + for (var key in item.keysyms) { + var out = clone(evt); + out.keysym = item.keysyms[key]; + next(out); + } + break; + case 'releaseall': + /* jshint shadow: true */ + for (var i = 0; i < state.length; ++i) { + for (var key in state[i].keysyms) { + var keysym = state[i].keysyms[key]; + next({keyId: 0, keysym: keysym, type: 'keyup'}); + } + } + /* jshint shadow: false */ + 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. +KeyboardUtil.EscapeModifiers = function(next) { + "use strict"; + return function(evt) { + if (evt.type !== 'keydown' || evt.escape === undefined) { + next(evt); + return; + } + // undo modifiers + for (var i = 0; i < evt.escape.length; ++i) { + next({type: 'keyup', keyId: 0, keysym: keysyms.lookup(evt.escape[i])}); + } + // send the character event + next(evt); + // redo modifiers + /* jshint shadow: true */ + for (var i = 0; i < evt.escape.length; ++i) { + next({type: 'keydown', keyId: 0, keysym: keysyms.lookup(evt.escape[i])}); + } + /* jshint shadow: false */ + }; +}; + +/* [module] export default KeyboardUtil; */ diff --git a/core/input/xtscancodes.js b/core/input/xtscancodes.js new file mode 100644 index 0000000..89d824c --- /dev/null +++ b/core/input/xtscancodes.js @@ -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 */ diff --git a/core/keyboard.js b/core/keyboard.js deleted file mode 100644 index efdcced..0000000 --- a/core/keyboard.js +++ /dev/null @@ -1,682 +0,0 @@ -/* [module] - * import KeyTable from "./keysym"; - * import keysyms from "./keysymdef"; - */ - -var KeyboardUtil = {}; - -(function() { - "use strict"; - - function substituteCodepoint(cp) { - // Any Unicode code points which do not have corresponding keysym entries - // can be swapped out for another code point by adding them to this table - var substitutions = { - // {S,s} with comma below -> {S,s} with cedilla - 0x218 : 0x15e, - 0x219 : 0x15f, - // {T,t} with comma below -> {T,t} with cedilla - 0x21a : 0x162, - 0x21b : 0x163 - }; - - var sub = substitutions[cp]; - return sub ? sub : cp; - } - - function isMac() { - return navigator && !!(/mac/i).exec(navigator.platform); - } - function isWindows() { - return navigator && !!(/win/i).exec(navigator.platform); - } - function isLinux() { - return navigator && !!(/linux/i).exec(navigator.platform); - } - - // Return true if a modifier which is not the specified char modifier (and is not shift) is down - function hasShortcutModifier(charModifier, currentModifiers) { - var mods = {}; - for (var key in currentModifiers) { - if (parseInt(key) !== KeyTable.XK_Shift_L) { - mods[key] = currentModifiers[key]; - } - } - - var sum = 0; - for (var k in currentModifiers) { - if (mods[k]) { - ++sum; - } - } - if (hasCharModifier(charModifier, mods)) { - return sum > charModifier.length; - } - else { - return sum > 0; - } - } - - // Return true if the specified char modifier is currently down - function hasCharModifier(charModifier, currentModifiers) { - if (charModifier.length === 0) { return false; } - - for (var i = 0; i < charModifier.length; ++i) { - if (!currentModifiers[charModifier[i]]) { - return false; - } - } - return true; - } - - // Helper object tracking modifier key state - // and generates fake key events to compensate if it gets out of sync - function ModifierSync(charModifier) { - if (!charModifier) { - if (isMac()) { - // on Mac, Option (AKA Alt) is used as a char modifier - charModifier = [KeyTable.XK_Alt_L]; - } - else if (isWindows()) { - // on Windows, Ctrl+Alt is used as a char modifier - 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 = [KeyTable.XK_ISO_Level3_Shift]; - } - else { - charModifier = []; - } - } - - var state = {}; - 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 = []; - function syncKey(keysym) { - return {keysym: keysyms.lookup(keysym), type: state[keysym] ? 'keydown' : 'keyup'}; - } - - if (evt.ctrlKey !== undefined && - 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[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[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[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[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; - } - function syncKeyEvent(evt, down) { - var obj = getKeysym(evt); - var keysym = obj ? obj.keysym : null; - - // first, apply the event itself, if relevant - if (keysym !== null && state[keysym] !== undefined) { - state[keysym] = down; - } - return sync(evt, keysym); - } - - return { - // sync on the appropriate keyboard event - keydown: function(evt) { return syncKeyEvent(evt, true);}, - keyup: function(evt) { return syncKeyEvent(evt, false);}, - // Call this with a non-keyboard event (such as mouse events) to use its modifier state to synchronize anyway - syncAny: function(evt) { return sync(evt);}, - - // is a shortcut modifier down? - hasShortcutModifier: function() { return hasShortcutModifier(charModifier, state); }, - // if a char modifier is down, return the keys it consists of, otherwise return null - activeCharModifier: function() { return hasCharModifier(charModifier, state) ? charModifier : null; } - }; - } - - // Get a key ID from a keyboard event - // May be a string or an integer depending on the available properties - function getKey(evt){ - if ('keyCode' in evt && 'key' in evt) { - return evt.key + ':' + evt.keyCode; - } - else if ('keyCode' in evt) { - return evt.keyCode; - } - else { - return evt.key; - } - } - - // Get the most reliable keysym value we can get from a key event - // if char/charCode is available, prefer those, otherwise fall back to key/keyCode/which - function getKeysym(evt){ - var codepoint; - if (evt.char && evt.char.length === 1) { - codepoint = evt.char.charCodeAt(); - } - else if (evt.charCode) { - codepoint = evt.charCode; - } - else if (evt.keyCode && evt.type === 'keypress') { - // IE10 stores the char code as keyCode, and has no other useful properties - codepoint = evt.keyCode; - } - if (codepoint) { - var res = keysyms.fromUnicode(substituteCodepoint(codepoint)); - if (res) { - return res; - } - } - // we could check evt.key here. - // Legal values are defined in http://www.w3.org/TR/DOM-Level-3-Events/#key-values-list, - // so we "just" need to map them to keysym, but AFAIK this is only available in IE10, which also provides evt.key - // so we don't *need* it yet - if (evt.keyCode) { - return keysyms.lookup(keysymFromKeyCode(evt.keyCode, evt.shiftKey)); - } - if (evt.which) { - return keysyms.lookup(keysymFromKeyCode(evt.which, evt.shiftKey)); - } - return null; - } - - // Given a keycode, try to predict which keysym it might be. - // If the keycode is unknown, null is returned. - function keysymFromKeyCode(keycode, shiftPressed) { - if (typeof(keycode) !== 'number') { - return null; - } - // won't be accurate for azerty - if (keycode >= 0x30 && keycode <= 0x39) { - return keycode; // digit - } - if (keycode >= 0x41 && keycode <= 0x5a) { - // remap to lowercase unless shift is down - return shiftPressed ? keycode : keycode + 32; // A-Z - } - if (keycode >= 0x60 && keycode <= 0x69) { - return KeyTable.XK_KP_0 + (keycode - 0x60); // numpad 0-9 - } - - switch(keycode) { - 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}); - } - - // if the key is a known non-character key (any key which doesn't generate character data) - // return its keysym value. Otherwise return null - function nonCharacterKey(evt) { - // evt.key not implemented yet - if (!evt.keyCode) { return null; } - var keycode = evt.keyCode; - - if (keycode >= 0x70 && keycode <= 0x87) { - return KeyTable.XK_F1 + keycode - 0x70; // F1-F24 - } - switch (keycode) { - - case 8 : return KeyTable.XK_BackSpace; - case 13 : return KeyTable.XK_Return; - - case 9 : return KeyTable.XK_Tab; - - case 27 : return KeyTable.XK_Escape; - case 46 : return KeyTable.XK_Delete; - - 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 KeyTable.XK_Left; - case 38 : return KeyTable.XK_Up; - case 39 : return KeyTable.XK_Right; - case 40 : return KeyTable.XK_Down; - - 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 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; - } - } - - KeyboardUtil.hasShortcutModifier = hasShortcutModifier; - KeyboardUtil.hasCharModifier = hasCharModifier; - KeyboardUtil.ModifierSync = ModifierSync; - KeyboardUtil.getKey = getKey; - KeyboardUtil.getKeysym = getKeysym; - KeyboardUtil.keysymFromKeyCode = keysymFromKeyCode; - KeyboardUtil.nonCharacterKey = nonCharacterKey; - KeyboardUtil.substituteCodepoint = substituteCodepoint; -})(); - -KeyboardUtil.QEMUKeyEventDecoder = function(modifierState, next) { - "use strict"; - - function sendAll(evts) { - for (var i = 0; i < evts.length; ++i) { - next(evts[i]); - } - } - - var numPadCodes = ["Numpad0", "Numpad1", "Numpad2", - "Numpad3", "Numpad4", "Numpad5", "Numpad6", - "Numpad7", "Numpad8", "Numpad9", "NumpadDecimal"]; - - var numLockOnKeySyms = { - "Numpad0": 0xffb0, "Numpad1": 0xffb1, "Numpad2": 0xffb2, - "Numpad3": 0xffb3, "Numpad4": 0xffb4, "Numpad5": 0xffb5, - "Numpad6": 0xffb6, "Numpad7": 0xffb7, "Numpad8": 0xffb8, - "Numpad9": 0xffb9, "NumpadDecimal": 0xffac - }; - - var numLockOnKeyCodes = [96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 108, 110]; - - function isNumPadMultiKey(evt) { - return (numPadCodes.indexOf(evt.code) !== -1); - } - - function getNumPadKeySym(evt) { - if (numLockOnKeyCodes.indexOf(evt.keyCode) !== -1) { - return numLockOnKeySyms[evt.code]; - } - return 0; - } - - function process(evt, type) { - var result = {type: type}; - result.code = evt.code; - result.keysym = 0; - - if (isNumPadMultiKey(evt)) { - result.keysym = getNumPadKeySym(evt); - } - - var hasModifier = modifierState.hasShortcutModifier() || !!modifierState.activeCharModifier(); - var isShift = evt.keyCode === 0x10 || evt.key === 'Shift'; - - var suppress = !isShift && (type !== 'keydown' || modifierState.hasShortcutModifier() || !!KeyboardUtil.nonCharacterKey(evt)); - - next(result); - return suppress; - } - return { - keydown: function(evt) { - sendAll(modifierState.keydown(evt)); - return process(evt, 'keydown'); - }, - keypress: function(evt) { - return true; - }, - keyup: function(evt) { - sendAll(modifierState.keyup(evt)); - return process(evt, 'keyup'); - }, - syncModifiers: function(evt) { - sendAll(modifierState.syncAny(evt)); - }, - releaseAll: function() { next({type: 'releaseall'}); } - }; -}; - -KeyboardUtil.TrackQEMUKeyState = function(next) { - "use strict"; - var state = []; - - return function (evt) { - var last = state.length !== 0 ? state[state.length-1] : null; - - switch (evt.type) { - case 'keydown': - - if (!last || last.code !== evt.code) { - last = {code: evt.code}; - - if (state.length > 0 && state[state.length-1].code == 'ControlLeft') { - if (evt.code !== 'AltRight') { - next({code: 'ControlLeft', type: 'keydown', keysym: 0}); - } else { - state.pop(); - } - } - state.push(last); - } - if (evt.code !== 'ControlLeft') { - next(evt); - } - break; - - case 'keyup': - if (state.length === 0) { - return; - } - var idx = null; - // do we have a matching key tracked as being down? - for (var i = 0; i !== state.length; ++i) { - if (state[i].code === evt.code) { - idx = i; - break; - } - } - // if we couldn't find a match (it happens), assume it was the last key pressed - if (idx === null) { - if (evt.code === 'ControlLeft') { - return; - } - idx = state.length - 1; - } - - state.splice(idx, 1); - next(evt); - break; - case 'releaseall': - /* jshint shadow: true */ - for (var i = 0; i < state.length; ++i) { - next({code: state[i].code, keysym: 0, type: 'keyup'}); - } - /* jshint shadow: false */ - state = []; - } - }; -}; - -// Takes a DOM keyboard event and: -// - determines which keysym it represents -// - determines a keyId identifying the key that was pressed (corresponding to the key/keyCode properties on the DOM event) -// - synthesizes events to synchronize modifier key state between which modifiers are actually down, and which we thought were down -// - 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) -KeyboardUtil.KeyEventDecoder = function(modifierState, next) { - "use strict"; - function sendAll(evts) { - for (var i = 0; i < evts.length; ++i) { - next(evts[i]); - } - } - function process(evt, type) { - var result = {type: type}; - var keyId = KeyboardUtil.getKey(evt); - if (keyId) { - result.keyId = keyId; - } - - 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' || KeyboardUtil.nonCharacterKey(evt) || hasModifier)) { - result.keysym = keysym; - } - - var isShift = evt.keyCode === 0x10 || evt.key === 'Shift'; - - // 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() || !!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() && !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(); - - // If we have a char modifier down, and we're able to determine a keysym reliably - // then (a) we know to treat the modifier as a char modifier, - // and (b) we'll have to "escape" the modifier to undo the modifier when sending the char. - if (active && keysym) { - var isCharModifier = false; - for (var i = 0; i < active.length; ++i) { - if (active[i] === keysym.keysym) { - isCharModifier = true; - } - } - if (type === 'keypress' && !isCharModifier) { - result.escape = modifierState.activeCharModifier(); - } - } - - if (stall) { - // insert a fake "stall" event - next({type: 'stall'}); - } - next(result); - - return suppress; - } - - return { - keydown: function(evt) { - sendAll(modifierState.keydown(evt)); - return process(evt, 'keydown'); - }, - keypress: function(evt) { - return process(evt, 'keypress'); - }, - keyup: function(evt) { - sendAll(modifierState.keyup(evt)); - return process(evt, 'keyup'); - }, - syncModifiers: function(evt) { - sendAll(modifierState.syncAny(evt)); - }, - 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. -// For example, on Windows, AltGr is synonymous with Ctrl-Alt. On a Danish keyboard layout, AltGr-2 yields a @, but Ctrl-Alt-D does nothing -// 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 -KeyboardUtil.VerifyCharModifier = function(next) { - "use strict"; - var queue = []; - var timer = null; - function process() { - if (timer) { - return; - } - - var delayProcess = function () { - clearTimeout(timer); - timer = null; - process(); - }; - - while (queue.length !== 0) { - var cur = queue[0]; - queue = queue.splice(1); - switch (cur.type) { - case 'stall': - // insert a delay before processing available events. - /* jshint loopfunc: true */ - timer = setTimeout(delayProcess, 5); - /* jshint loopfunc: false */ - return; - case 'keydown': - // is the next element a keypress? Then we should merge the two - if (queue.length !== 0 && queue[0].type === 'keypress') { - // Firefox sends keypress even when no char is generated. - // so, if keypress keysym is the same as we'd have guessed from keydown, - // the modifier didn't have any effect, and should not be escaped - if (queue[0].escape && (!cur.keysym || cur.keysym.keysym !== queue[0].keysym.keysym)) { - cur.escape = queue[0].escape; - } - cur.keysym = queue[0].keysym; - queue = queue.splice(1); - } - break; - } - - // swallow stall events, and pass all others to the next stage - if (cur.type !== 'stall') { - next(cur); - } - } - } - return function(evt) { - 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 -KeyboardUtil.TrackKeyState = function(next) { - "use strict"; - var state = []; - - return function (evt) { - var last = state.length !== 0 ? state[state.length-1] : null; - - switch (evt.type) { - case 'keydown': - // insert a new entry if last seen key was different. - if (!last || !evt.keyId || last.keyId !== evt.keyId) { - last = {keyId: evt.keyId, keysyms: {}}; - state.push(last); - } - if (evt.keysym) { - // make sure last event contains this keysym (a single "logical" keyevent - // can cause multiple key events to be sent to the VNC server) - last.keysyms[evt.keysym.keysym] = evt.keysym; - last.ignoreKeyPress = true; - next(evt); - } - break; - case 'keypress': - if (!last) { - last = {keyId: evt.keyId, keysyms: {}}; - state.push(last); - } - if (!evt.keysym) { - console.log('keypress with no keysym:', evt); - } - - // If we didn't expect a keypress, and already sent a keydown to the VNC server - // based on the keydown, make sure to skip this event. - if (evt.keysym && !last.ignoreKeyPress) { - last.keysyms[evt.keysym.keysym] = evt.keysym; - evt.type = 'keydown'; - next(evt); - } - break; - case 'keyup': - if (state.length === 0) { - return; - } - var idx = null; - // do we have a matching key tracked as being down? - for (var i = 0; i !== state.length; ++i) { - if (state[i].keyId === evt.keyId) { - idx = i; - break; - } - } - // if we couldn't find a match (it happens), assume it was the last key pressed - if (idx === null) { - idx = state.length - 1; - } - - var item = state.splice(idx, 1)[0]; - // for each keysym tracked by this key entry, clone the current event and override the keysym - var clone = (function(){ - function Clone(){} - return function (obj) { Clone.prototype=obj; return new Clone(); }; - }()); - for (var key in item.keysyms) { - var out = clone(evt); - out.keysym = item.keysyms[key]; - next(out); - } - break; - case 'releaseall': - /* jshint shadow: true */ - for (var i = 0; i < state.length; ++i) { - for (var key in state[i].keysyms) { - var keysym = state[i].keysyms[key]; - next({keyId: 0, keysym: keysym, type: 'keyup'}); - } - } - /* jshint shadow: false */ - 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. -KeyboardUtil.EscapeModifiers = function(next) { - "use strict"; - return function(evt) { - if (evt.type !== 'keydown' || evt.escape === undefined) { - next(evt); - return; - } - // undo modifiers - for (var i = 0; i < evt.escape.length; ++i) { - next({type: 'keyup', keyId: 0, keysym: keysyms.lookup(evt.escape[i])}); - } - // send the character event - next(evt); - // redo modifiers - /* jshint shadow: true */ - for (var i = 0; i < evt.escape.length; ++i) { - next({type: 'keydown', keyId: 0, keysym: keysyms.lookup(evt.escape[i])}); - } - /* jshint shadow: false */ - }; -}; - -/* [module] export default KeyboardUtil; */ diff --git a/core/keysym.js b/core/keysym.js deleted file mode 100644 index 5983c38..0000000 --- a/core/keysym.js +++ /dev/null @@ -1,382 +0,0 @@ -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; */ diff --git a/core/keysymdef.js b/core/keysymdef.js deleted file mode 100644 index f45d9d9..0000000 --- a/core/keysymdef.js +++ /dev/null @@ -1,18 +0,0 @@ -// This file describes mappings from Unicode codepoints to the keysym values -// (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; - var codepoints = {"32":32,"33":33,"34":34,"35":35,"36":36,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42,"43":43,"44":44,"45":45,"46":46,"47":47,"48":48,"49":49,"50":50,"51":51,"52":52,"53":53,"54":54,"55":55,"56":56,"57":57,"58":58,"59":59,"60":60,"61":61,"62":62,"63":63,"64":64,"65":65,"66":66,"67":67,"68":68,"69":69,"70":70,"71":71,"72":72,"73":73,"74":74,"75":75,"76":76,"77":77,"78":78,"79":79,"80":80,"81":81,"82":82,"83":83,"84":84,"85":85,"86":86,"87":87,"88":88,"89":89,"90":90,"91":91,"92":92,"93":93,"94":94,"95":95,"96":96,"97":97,"98":98,"99":99,"100":100,"101":101,"102":102,"103":103,"104":104,"105":105,"106":106,"107":107,"108":108,"109":109,"110":110,"111":111,"112":112,"113":113,"114":114,"115":115,"116":116,"117":117,"118":118,"119":119,"120":120,"121":121,"122":122,"123":123,"124":124,"125":125,"126":126,"160":160,"161":161,"162":162,"163":163,"164":164,"165":165,"166":166,"167":167,"168":168,"169":169,"170":170,"171":171,"172":172,"173":173,"174":174,"175":175,"176":176,"177":177,"178":178,"179":179,"180":180,"181":181,"182":182,"183":183,"184":184,"185":185,"186":186,"187":187,"188":188,"189":189,"190":190,"191":191,"192":192,"193":193,"194":194,"195":195,"196":196,"197":197,"198":198,"199":199,"200":200,"201":201,"202":202,"203":203,"204":204,"205":205,"206":206,"207":207,"208":208,"209":209,"210":210,"211":211,"212":212,"213":213,"214":214,"215":215,"216":216,"217":217,"218":218,"219":219,"220":220,"221":221,"222":222,"223":223,"224":224,"225":225,"226":226,"227":227,"228":228,"229":229,"230":230,"231":231,"232":232,"233":233,"234":234,"235":235,"236":236,"237":237,"238":238,"239":239,"240":240,"241":241,"242":242,"243":243,"244":244,"245":245,"246":246,"247":247,"248":248,"249":249,"250":250,"251":251,"252":252,"253":253,"254":254,"255":255,"256":960,"257":992,"258":451,"259":483,"260":417,"261":433,"262":454,"263":486,"264":710,"265":742,"266":709,"267":741,"268":456,"269":488,"270":463,"271":495,"272":464,"273":496,"274":938,"275":954,"278":972,"279":1004,"280":458,"281":490,"282":460,"283":492,"284":728,"285":760,"286":683,"287":699,"288":725,"289":757,"290":939,"291":955,"292":678,"293":694,"294":673,"295":689,"296":933,"297":949,"298":975,"299":1007,"300":16777516,"301":16777517,"302":967,"303":999,"304":681,"305":697,"308":684,"309":700,"310":979,"311":1011,"312":930,"313":453,"314":485,"315":934,"316":950,"317":421,"318":437,"321":419,"322":435,"323":465,"324":497,"325":977,"326":1009,"327":466,"328":498,"330":957,"331":959,"332":978,"333":1010,"336":469,"337":501,"338":5052,"339":5053,"340":448,"341":480,"342":931,"343":947,"344":472,"345":504,"346":422,"347":438,"348":734,"349":766,"350":426,"351":442,"352":425,"353":441,"354":478,"355":510,"356":427,"357":443,"358":940,"359":956,"360":989,"361":1021,"362":990,"363":1022,"364":733,"365":765,"366":473,"367":505,"368":475,"369":507,"370":985,"371":1017,"372":16777588,"373":16777589,"374":16777590,"375":16777591,"376":5054,"377":428,"378":444,"379":431,"380":447,"381":430,"382":446,"399":16777615,"402":2294,"415":16777631,"416":16777632,"417":16777633,"431":16777647,"432":16777648,"437":16777653,"438":16777654,"439":16777655,"466":16777681,"486":16777702,"487":16777703,"601":16777817,"629":16777845,"658":16777874,"711":439,"728":418,"729":511,"731":434,"733":445,"901":1966,"902":1953,"904":1954,"905":1955,"906":1956,"908":1959,"910":1960,"911":1963,"912":1974,"913":1985,"914":1986,"915":1987,"916":1988,"917":1989,"918":1990,"919":1991,"920":1992,"921":1993,"922":1994,"923":1995,"924":1996,"925":1997,"926":1998,"927":1999,"928":2000,"929":2001,"931":2002,"932":2004,"933":2005,"934":2006,"935":2007,"936":2008,"937":2009,"938":1957,"939":1961,"940":1969,"941":1970,"942":1971,"943":1972,"944":1978,"945":2017,"946":2018,"947":2019,"948":2020,"949":2021,"950":2022,"951":2023,"952":2024,"953":2025,"954":2026,"955":2027,"956":2028,"957":2029,"958":2030,"959":2031,"960":2032,"961":2033,"962":2035,"963":2034,"964":2036,"965":2037,"966":2038,"967":2039,"968":2040,"969":2041,"970":1973,"971":1977,"972":1975,"973":1976,"974":1979,"1025":1715,"1026":1713,"1027":1714,"1028":1716,"1029":1717,"1030":1718,"1031":1719,"1032":1720,"1033":1721,"1034":1722,"1035":1723,"1036":1724,"1038":1726,"1039":1727,"1040":1761,"1041":1762,"1042":1783,"1043":1767,"1044":1764,"1045":1765,"1046":1782,"1047":1786,"1048":1769,"1049":1770,"1050":1771,"1051":1772,"1052":1773,"1053":1774,"1054":1775,"1055":1776,"1056":1778,"1057":1779,"1058":1780,"1059":1781,"1060":1766,"1061":1768,"1062":1763,"1063":1790,"1064":1787,"1065":1789,"1066":1791,"1067":1785,"1068":1784,"1069":1788,"1070":1760,"1071":1777,"1072":1729,"1073":1730,"1074":1751,"1075":1735,"1076":1732,"1077":1733,"1078":1750,"1079":1754,"1080":1737,"1081":1738,"1082":1739,"1083":1740,"1084":1741,"1085":1742,"1086":1743,"1087":1744,"1088":1746,"1089":1747,"1090":1748,"1091":1749,"1092":1734,"1093":1736,"1094":1731,"1095":1758,"1096":1755,"1097":1757,"1098":1759,"1099":1753,"1100":1752,"1101":1756,"1102":1728,"1103":1745,"1105":1699,"1106":1697,"1107":1698,"1108":1700,"1109":1701,"1110":1702,"1111":1703,"1112":1704,"1113":1705,"1114":1706,"1115":1707,"1116":1708,"1118":1710,"1119":1711,"1168":1725,"1169":1709,"1170":16778386,"1171":16778387,"1174":16778390,"1175":16778391,"1178":16778394,"1179":16778395,"1180":16778396,"1181":16778397,"1186":16778402,"1187":16778403,"1198":16778414,"1199":16778415,"1200":16778416,"1201":16778417,"1202":16778418,"1203":16778419,"1206":16778422,"1207":16778423,"1208":16778424,"1209":16778425,"1210":16778426,"1211":16778427,"1240":16778456,"1241":16778457,"1250":16778466,"1251":16778467,"1256":16778472,"1257":16778473,"1262":16778478,"1263":16778479,"1329":16778545,"1330":16778546,"1331":16778547,"1332":16778548,"1333":16778549,"1334":16778550,"1335":16778551,"1336":16778552,"1337":16778553,"1338":16778554,"1339":16778555,"1340":16778556,"1341":16778557,"1342":16778558,"1343":16778559,"1344":16778560,"1345":16778561,"1346":16778562,"1347":16778563,"1348":16778564,"1349":16778565,"1350":16778566,"1351":16778567,"1352":16778568,"1353":16778569,"1354":16778570,"1355":16778571,"1356":16778572,"1357":16778573,"1358":16778574,"1359":16778575,"1360":16778576,"1361":16778577,"1362":16778578,"1363":16778579,"1364":16778580,"1365":16778581,"1366":16778582,"1370":16778586,"1371":16778587,"1372":16778588,"1373":16778589,"1374":16778590,"1377":16778593,"1378":16778594,"1379":16778595,"1380":16778596,"1381":16778597,"1382":16778598,"1383":16778599,"1384":16778600,"1385":16778601,"1386":16778602,"1387":16778603,"1388":16778604,"1389":16778605,"1390":16778606,"1391":16778607,"1392":16778608,"1393":16778609,"1394":16778610,"1395":16778611,"1396":16778612,"1397":16778613,"1398":16778614,"1399":16778615,"1400":16778616,"1401":16778617,"1402":16778618,"1403":16778619,"1404":16778620,"1405":16778621,"1406":16778622,"1407":16778623,"1408":16778624,"1409":16778625,"1410":16778626,"1411":16778627,"1412":16778628,"1413":16778629,"1414":16778630,"1415":16778631,"1417":16778633,"1418":16778634,"1488":3296,"1489":3297,"1490":3298,"1491":3299,"1492":3300,"1493":3301,"1494":3302,"1495":3303,"1496":3304,"1497":3305,"1498":3306,"1499":3307,"1500":3308,"1501":3309,"1502":3310,"1503":3311,"1504":3312,"1505":3313,"1506":3314,"1507":3315,"1508":3316,"1509":3317,"1510":3318,"1511":3319,"1512":3320,"1513":3321,"1514":3322,"1548":1452,"1563":1467,"1567":1471,"1569":1473,"1570":1474,"1571":1475,"1572":1476,"1573":1477,"1574":1478,"1575":1479,"1576":1480,"1577":1481,"1578":1482,"1579":1483,"1580":1484,"1581":1485,"1582":1486,"1583":1487,"1584":1488,"1585":1489,"1586":1490,"1587":1491,"1588":1492,"1589":1493,"1590":1494,"1591":1495,"1592":1496,"1593":1497,"1594":1498,"1600":1504,"1601":1505,"1602":1506,"1603":1507,"1604":1508,"1605":1509,"1606":1510,"1607":1511,"1608":1512,"1609":1513,"1610":1514,"1611":1515,"1612":1516,"1613":1517,"1614":1518,"1615":1519,"1616":1520,"1617":1521,"1618":1522,"1619":16778835,"1620":16778836,"1621":16778837,"1632":16778848,"1633":16778849,"1634":16778850,"1635":16778851,"1636":16778852,"1637":16778853,"1638":16778854,"1639":16778855,"1640":16778856,"1641":16778857,"1642":16778858,"1648":16778864,"1657":16778873,"1662":16778878,"1670":16778886,"1672":16778888,"1681":16778897,"1688":16778904,"1700":16778916,"1705":16778921,"1711":16778927,"1722":16778938,"1726":16778942,"1729":16778945,"1740":16778956,"1746":16778962,"1748":16778964,"1776":16778992,"1777":16778993,"1778":16778994,"1779":16778995,"1780":16778996,"1781":16778997,"1782":16778998,"1783":16778999,"1784":16779000,"1785":16779001,"3458":16780674,"3459":16780675,"3461":16780677,"3462":16780678,"3463":16780679,"3464":16780680,"3465":16780681,"3466":16780682,"3467":16780683,"3468":16780684,"3469":16780685,"3470":16780686,"3471":16780687,"3472":16780688,"3473":16780689,"3474":16780690,"3475":16780691,"3476":16780692,"3477":16780693,"3478":16780694,"3482":16780698,"3483":16780699,"3484":16780700,"3485":16780701,"3486":16780702,"3487":16780703,"3488":16780704,"3489":16780705,"3490":16780706,"3491":16780707,"3492":16780708,"3493":16780709,"3494":16780710,"3495":16780711,"3496":16780712,"3497":16780713,"3498":16780714,"3499":16780715,"3500":16780716,"3501":16780717,"3502":16780718,"3503":16780719,"3504":16780720,"3505":16780721,"3507":16780723,"3508":16780724,"3509":16780725,"3510":16780726,"3511":16780727,"3512":16780728,"3513":16780729,"3514":16780730,"3515":16780731,"3517":16780733,"3520":16780736,"3521":16780737,"3522":16780738,"3523":16780739,"3524":16780740,"3525":16780741,"3526":16780742,"3530":16780746,"3535":16780751,"3536":16780752,"3537":16780753,"3538":16780754,"3539":16780755,"3540":16780756,"3542":16780758,"3544":16780760,"3545":16780761,"3546":16780762,"3547":16780763,"3548":16780764,"3549":16780765,"3550":16780766,"3551":16780767,"3570":16780786,"3571":16780787,"3572":16780788,"3585":3489,"3586":3490,"3587":3491,"3588":3492,"3589":3493,"3590":3494,"3591":3495,"3592":3496,"3593":3497,"3594":3498,"3595":3499,"3596":3500,"3597":3501,"3598":3502,"3599":3503,"3600":3504,"3601":3505,"3602":3506,"3603":3507,"3604":3508,"3605":3509,"3606":3510,"3607":3511,"3608":3512,"3609":3513,"3610":3514,"3611":3515,"3612":3516,"3613":3517,"3614":3518,"3615":3519,"3616":3520,"3617":3521,"3618":3522,"3619":3523,"3620":3524,"3621":3525,"3622":3526,"3623":3527,"3624":3528,"3625":3529,"3626":3530,"3627":3531,"3628":3532,"3629":3533,"3630":3534,"3631":3535,"3632":3536,"3633":3537,"3634":3538,"3635":3539,"3636":3540,"3637":3541,"3638":3542,"3639":3543,"3640":3544,"3641":3545,"3642":3546,"3647":3551,"3648":3552,"3649":3553,"3650":3554,"3651":3555,"3652":3556,"3653":3557,"3654":3558,"3655":3559,"3656":3560,"3657":3561,"3658":3562,"3659":3563,"3660":3564,"3661":3565,"3664":3568,"3665":3569,"3666":3570,"3667":3571,"3668":3572,"3669":3573,"3670":3574,"3671":3575,"3672":3576,"3673":3577,"4304":16781520,"4305":16781521,"4306":16781522,"4307":16781523,"4308":16781524,"4309":16781525,"4310":16781526,"4311":16781527,"4312":16781528,"4313":16781529,"4314":16781530,"4315":16781531,"4316":16781532,"4317":16781533,"4318":16781534,"4319":16781535,"4320":16781536,"4321":16781537,"4322":16781538,"4323":16781539,"4324":16781540,"4325":16781541,"4326":16781542,"4327":16781543,"4328":16781544,"4329":16781545,"4330":16781546,"4331":16781547,"4332":16781548,"4333":16781549,"4334":16781550,"4335":16781551,"4336":16781552,"4337":16781553,"4338":16781554,"4339":16781555,"4340":16781556,"4341":16781557,"4342":16781558,"7682":16784898,"7683":16784899,"7690":16784906,"7691":16784907,"7710":16784926,"7711":16784927,"7734":16784950,"7735":16784951,"7744":16784960,"7745":16784961,"7766":16784982,"7767":16784983,"7776":16784992,"7777":16784993,"7786":16785002,"7787":16785003,"7808":16785024,"7809":16785025,"7810":16785026,"7811":16785027,"7812":16785028,"7813":16785029,"7818":16785034,"7819":16785035,"7840":16785056,"7841":16785057,"7842":16785058,"7843":16785059,"7844":16785060,"7845":16785061,"7846":16785062,"7847":16785063,"7848":16785064,"7849":16785065,"7850":16785066,"7851":16785067,"7852":16785068,"7853":16785069,"7854":16785070,"7855":16785071,"7856":16785072,"7857":16785073,"7858":16785074,"7859":16785075,"7860":16785076,"7861":16785077,"7862":16785078,"7863":16785079,"7864":16785080,"7865":16785081,"7866":16785082,"7867":16785083,"7868":16785084,"7869":16785085,"7870":16785086,"7871":16785087,"7872":16785088,"7873":16785089,"7874":16785090,"7875":16785091,"7876":16785092,"7877":16785093,"7878":16785094,"7879":16785095,"7880":16785096,"7881":16785097,"7882":16785098,"7883":16785099,"7884":16785100,"7885":16785101,"7886":16785102,"7887":16785103,"7888":16785104,"7889":16785105,"7890":16785106,"7891":16785107,"7892":16785108,"7893":16785109,"7894":16785110,"7895":16785111,"7896":16785112,"7897":16785113,"7898":16785114,"7899":16785115,"7900":16785116,"7901":16785117,"7902":16785118,"7903":16785119,"7904":16785120,"7905":16785121,"7906":16785122,"7907":16785123,"7908":16785124,"7909":16785125,"7910":16785126,"7911":16785127,"7912":16785128,"7913":16785129,"7914":16785130,"7915":16785131,"7916":16785132,"7917":16785133,"7918":16785134,"7919":16785135,"7920":16785136,"7921":16785137,"7922":16785138,"7923":16785139,"7924":16785140,"7925":16785141,"7926":16785142,"7927":16785143,"7928":16785144,"7929":16785145,"8194":2722,"8195":2721,"8196":2723,"8197":2724,"8199":2725,"8200":2726,"8201":2727,"8202":2728,"8210":2747,"8211":2730,"8212":2729,"8213":1967,"8215":3295,"8216":2768,"8217":2769,"8218":2813,"8220":2770,"8221":2771,"8222":2814,"8224":2801,"8225":2802,"8226":2790,"8229":2735,"8230":2734,"8240":2773,"8242":2774,"8243":2775,"8248":2812,"8254":1150,"8304":16785520,"8308":16785524,"8309":16785525,"8310":16785526,"8311":16785527,"8312":16785528,"8313":16785529,"8320":16785536,"8321":16785537,"8322":16785538,"8323":16785539,"8324":16785540,"8325":16785541,"8326":16785542,"8327":16785543,"8328":16785544,"8329":16785545,"8352":16785568,"8353":16785569,"8354":16785570,"8355":16785571,"8356":16785572,"8357":16785573,"8358":16785574,"8359":16785575,"8360":16785576,"8361":3839,"8362":16785578,"8363":16785579,"8364":8364,"8453":2744,"8470":1712,"8471":2811,"8478":2772,"8482":2761,"8531":2736,"8532":2737,"8533":2738,"8534":2739,"8535":2740,"8536":2741,"8537":2742,"8538":2743,"8539":2755,"8540":2756,"8541":2757,"8542":2758,"8592":2299,"8593":2300,"8594":2301,"8595":2302,"8658":2254,"8660":2253,"8706":2287,"8709":16785925,"8711":2245,"8712":16785928,"8713":16785929,"8715":16785931,"8728":3018,"8730":2262,"8731":16785947,"8732":16785948,"8733":2241,"8734":2242,"8743":2270,"8744":2271,"8745":2268,"8746":2269,"8747":2239,"8748":16785964,"8749":16785965,"8756":2240,"8757":16785973,"8764":2248,"8771":2249,"8773":16785992,"8775":16785991,"8800":2237,"8801":2255,"8802":16786018,"8803":16786019,"8804":2236,"8805":2238,"8834":2266,"8835":2267,"8866":3068,"8867":3036,"8868":3010,"8869":3022,"8968":3027,"8970":3012,"8981":2810,"8992":2212,"8993":2213,"9109":3020,"9115":2219,"9117":2220,"9118":2221,"9120":2222,"9121":2215,"9123":2216,"9124":2217,"9126":2218,"9128":2223,"9132":2224,"9143":2209,"9146":2543,"9147":2544,"9148":2546,"9149":2547,"9225":2530,"9226":2533,"9227":2537,"9228":2531,"9229":2532,"9251":2732,"9252":2536,"9472":2211,"9474":2214,"9484":2210,"9488":2539,"9492":2541,"9496":2538,"9500":2548,"9508":2549,"9516":2551,"9524":2550,"9532":2542,"9618":2529,"9642":2791,"9643":2785,"9644":2779,"9645":2786,"9646":2783,"9647":2767,"9650":2792,"9651":2787,"9654":2781,"9655":2765,"9660":2793,"9661":2788,"9664":2780,"9665":2764,"9670":2528,"9675":2766,"9679":2782,"9702":2784,"9734":2789,"9742":2809,"9747":2762,"9756":2794,"9758":2795,"9792":2808,"9794":2807,"9827":2796,"9829":2798,"9830":2797,"9837":2806,"9839":2805,"10003":2803,"10007":2804,"10013":2777,"10016":2800,"10216":2748,"10217":2750,"10240":16787456,"10241":16787457,"10242":16787458,"10243":16787459,"10244":16787460,"10245":16787461,"10246":16787462,"10247":16787463,"10248":16787464,"10249":16787465,"10250":16787466,"10251":16787467,"10252":16787468,"10253":16787469,"10254":16787470,"10255":16787471,"10256":16787472,"10257":16787473,"10258":16787474,"10259":16787475,"10260":16787476,"10261":16787477,"10262":16787478,"10263":16787479,"10264":16787480,"10265":16787481,"10266":16787482,"10267":16787483,"10268":16787484,"10269":16787485,"10270":16787486,"10271":16787487,"10272":16787488,"10273":16787489,"10274":16787490,"10275":16787491,"10276":16787492,"10277":16787493,"10278":16787494,"10279":16787495,"10280":16787496,"10281":16787497,"10282":16787498,"10283":16787499,"10284":16787500,"10285":16787501,"10286":16787502,"10287":16787503,"10288":16787504,"10289":16787505,"10290":16787506,"10291":16787507,"10292":16787508,"10293":16787509,"10294":16787510,"10295":16787511,"10296":16787512,"10297":16787513,"10298":16787514,"10299":16787515,"10300":16787516,"10301":16787517,"10302":16787518,"10303":16787519,"10304":16787520,"10305":16787521,"10306":16787522,"10307":16787523,"10308":16787524,"10309":16787525,"10310":16787526,"10311":16787527,"10312":16787528,"10313":16787529,"10314":16787530,"10315":16787531,"10316":16787532,"10317":16787533,"10318":16787534,"10319":16787535,"10320":16787536,"10321":16787537,"10322":16787538,"10323":16787539,"10324":16787540,"10325":16787541,"10326":16787542,"10327":16787543,"10328":16787544,"10329":16787545,"10330":16787546,"10331":16787547,"10332":16787548,"10333":16787549,"10334":16787550,"10335":16787551,"10336":16787552,"10337":16787553,"10338":16787554,"10339":16787555,"10340":16787556,"10341":16787557,"10342":16787558,"10343":16787559,"10344":16787560,"10345":16787561,"10346":16787562,"10347":16787563,"10348":16787564,"10349":16787565,"10350":16787566,"10351":16787567,"10352":16787568,"10353":16787569,"10354":16787570,"10355":16787571,"10356":16787572,"10357":16787573,"10358":16787574,"10359":16787575,"10360":16787576,"10361":16787577,"10362":16787578,"10363":16787579,"10364":16787580,"10365":16787581,"10366":16787582,"10367":16787583,"10368":16787584,"10369":16787585,"10370":16787586,"10371":16787587,"10372":16787588,"10373":16787589,"10374":16787590,"10375":16787591,"10376":16787592,"10377":16787593,"10378":16787594,"10379":16787595,"10380":16787596,"10381":16787597,"10382":16787598,"10383":16787599,"10384":16787600,"10385":16787601,"10386":16787602,"10387":16787603,"10388":16787604,"10389":16787605,"10390":16787606,"10391":16787607,"10392":16787608,"10393":16787609,"10394":16787610,"10395":16787611,"10396":16787612,"10397":16787613,"10398":16787614,"10399":16787615,"10400":16787616,"10401":16787617,"10402":16787618,"10403":16787619,"10404":16787620,"10405":16787621,"10406":16787622,"10407":16787623,"10408":16787624,"10409":16787625,"10410":16787626,"10411":16787627,"10412":16787628,"10413":16787629,"10414":16787630,"10415":16787631,"10416":16787632,"10417":16787633,"10418":16787634,"10419":16787635,"10420":16787636,"10421":16787637,"10422":16787638,"10423":16787639,"10424":16787640,"10425":16787641,"10426":16787642,"10427":16787643,"10428":16787644,"10429":16787645,"10430":16787646,"10431":16787647,"10432":16787648,"10433":16787649,"10434":16787650,"10435":16787651,"10436":16787652,"10437":16787653,"10438":16787654,"10439":16787655,"10440":16787656,"10441":16787657,"10442":16787658,"10443":16787659,"10444":16787660,"10445":16787661,"10446":16787662,"10447":16787663,"10448":16787664,"10449":16787665,"10450":16787666,"10451":16787667,"10452":16787668,"10453":16787669,"10454":16787670,"10455":16787671,"10456":16787672,"10457":16787673,"10458":16787674,"10459":16787675,"10460":16787676,"10461":16787677,"10462":16787678,"10463":16787679,"10464":16787680,"10465":16787681,"10466":16787682,"10467":16787683,"10468":16787684,"10469":16787685,"10470":16787686,"10471":16787687,"10472":16787688,"10473":16787689,"10474":16787690,"10475":16787691,"10476":16787692,"10477":16787693,"10478":16787694,"10479":16787695,"10480":16787696,"10481":16787697,"10482":16787698,"10483":16787699,"10484":16787700,"10485":16787701,"10486":16787702,"10487":16787703,"10488":16787704,"10489":16787705,"10490":16787706,"10491":16787707,"10492":16787708,"10493":16787709,"10494":16787710,"10495":16787711,"12289":1188,"12290":1185,"12300":1186,"12301":1187,"12443":1246,"12444":1247,"12449":1191,"12450":1201,"12451":1192,"12452":1202,"12453":1193,"12454":1203,"12455":1194,"12456":1204,"12457":1195,"12458":1205,"12459":1206,"12461":1207,"12463":1208,"12465":1209,"12467":1210,"12469":1211,"12471":1212,"12473":1213,"12475":1214,"12477":1215,"12479":1216,"12481":1217,"12483":1199,"12484":1218,"12486":1219,"12488":1220,"12490":1221,"12491":1222,"12492":1223,"12493":1224,"12494":1225,"12495":1226,"12498":1227,"12501":1228,"12504":1229,"12507":1230,"12510":1231,"12511":1232,"12512":1233,"12513":1234,"12514":1235,"12515":1196,"12516":1236,"12517":1197,"12518":1237,"12519":1198,"12520":1238,"12521":1239,"12522":1240,"12523":1241,"12524":1242,"12525":1243,"12527":1244,"12530":1190,"12531":1245,"12539":1189,"12540":1200}; - - function lookup(k) { return k ? {keysym: k, keyname: keynames ? keynames[k] : k} : undefined; } - return { - fromUnicode : function(u) { return lookup(codepoints[u]); }, - lookup : lookup - }; -})(); - -/* [module] export default keysyms */ diff --git a/core/rfb.js b/core/rfb.js index 0ae96bd..135d3a7 100644 --- a/core/rfb.js +++ b/core/rfb.js @@ -13,12 +13,12 @@ /* [module] * import Util from "./util"; * import Display from "./display"; - * import { Keyboard, Mouse } from "./input" + * import { Keyboard, Mouse } from "./input/devices" * import Websock from "./websock" * import Base64 from "./base64"; * import DES from "./des"; - * import KeyTable from "./keysym"; - * import XtScancode from "./xtscancodes"; + * import KeyTable from "./input/keysym"; + * import XtScancode from "./input/xtscancodes"; * import Inflator from "./inflator.mod"; */ /*jslint white: false, browser: true */ diff --git a/core/xtscancodes.js b/core/xtscancodes.js deleted file mode 100644 index 89d824c..0000000 --- a/core/xtscancodes.js +++ /dev/null @@ -1,149 +0,0 @@ -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 */ diff --git a/karma.conf.js b/karma.conf.js index f14dc42..5f3c20b 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -113,11 +113,11 @@ module.exports = function(config) { 'core/util.js', // load first to avoid issues, since methods are called immediately //'../core/*.js', 'core/base64.js', - 'core/keysym.js', - 'core/keysymdef.js', - 'core/xtscancodes.js', - 'core/keyboard.js', - 'core/input.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', diff --git a/tests/input.html b/tests/input.html index a513645..a261924 100644 --- a/tests/input.html +++ b/tests/input.html @@ -26,11 +26,11 @@ - - - - - + + + + +