123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- /*
- * noVNC: HTML5 VNC client
- * Copyright (C) 2011 Joel Martin
- * Licensed under LGPL-3 (see LICENSE.txt)
- */
- /*jslint browser: true, white: false, bitwise: false */
- /*global window, Util */
- //
- // Keyboard event handler
- //
- function Keyboard(conf) {
- "use strict";
- conf = conf || {}; // Configuration
- var that = {}; // Public API interface
- // Configuration settings
- function cdef(v, type, defval, desc) {
- Util.conf_default(conf, that, v, type, defval, desc); }
- // Capability settings, default can be overridden
- cdef('target', 'dom', document, 'DOM element that grabs keyboard input');
- cdef('focused', 'bool', true, 'Capture and send key strokes');
- cdef('keyPress', 'func', null, 'Handler for key press/release');
- that.set_target = function () { throw("target cannot be changed"); }
- //
- // Private functions
- //
- function onKeyDown(e) {
- //Util.Debug("keydown: " + that.getKeysym(e));
- if (! conf.focused) {
- return true;
- }
- if (conf.keyPress) {
- conf.keyPress(that.getKeysym(e), 1, e.ctrlKey, e.shiftKey, e.altKey);
- }
- Util.stopEvent(e);
- return false;
- }
- function onKeyUp(e) {
- //Util.Debug("keyup: " + that.getKeysym(e));
- if (! conf.focused) {
- return true;
- }
- if (conf.keyPress) {
- conf.keyPress(that.getKeysym(e), 0, e.ctrlKey, e.shiftKey, e.altKey);
- }
- Util.stopEvent(e);
- return false;
- }
- function onKeyPress(e) {
- //Util.Debug("keypress: " + e.charCode);
- if (! conf.focused) {
- return true;
- }
- // Stop keypress events. Necessary for Opera because stopping
- // keydown and keyup events still results in a keypress event.
- Util.stopEvent(e);
- return false;
- }
- //
- // Public API interface functions
- //
- /* Translate DOM key down/up event to keysym value */
- that.getKeysym = function getKeysym(e) {
- var evt, keysym;
- evt = (e ? e : window.event);
- /*
- Util.Debug(">> getKeysym - keyCode: " + evt.keyCode + ", which: " + evt.which +
- ", charCode: " + evt.charCode + ", keyIdentifier: " + evt.keyIdentifier +
- ", altKey: " + evt.altKey + ", ctrlKey: " + evt.ctrlKey +
- ", shiftKey: " + evt.shiftKey + ", metaKey: " + evt.metaKey +
- ", type: " + evt.type + ", keyLocation: " + evt.keyLocation);
- */
- /* Remap modifier and special keys */
- switch ( evt.keyCode ) {
- case 8 : keysym = 0xFF08; break; // BACKSPACE
- case 9 : keysym = 0xFF09; break; // TAB
- case 13 : keysym = 0xFF0D; break; // ENTER
- case 27 : keysym = 0xFF1B; break; // ESCAPE
- case 45 : keysym = 0xFF63; break; // INSERT
- case 46 : keysym = 0xFFFF; break; // DELETE
- case 36 : keysym = 0xFF50; break; // HOME
- case 35 : keysym = 0xFF57; break; // END
- case 33 : keysym = 0xFF55; break; // PAGE_UP
- case 34 : keysym = 0xFF56; break; // PAGE_DOWN
- case 37 : keysym = 0xFF51; break; // LEFT
- case 38 : keysym = 0xFF52; break; // UP
- case 39 : keysym = 0xFF53; break; // RIGHT
- case 40 : keysym = 0xFF54; break; // DOWN
- case 112 : keysym = 0xFFBE; break; // F1
- case 113 : keysym = 0xFFBF; break; // F2
- case 114 : keysym = 0xFFC0; break; // F3
- case 115 : keysym = 0xFFC1; break; // F4
- case 116 : keysym = 0xFFC2; break; // F5
- case 117 : keysym = 0xFFC3; break; // F6
- case 118 : keysym = 0xFFC4; break; // F7
- case 119 : keysym = 0xFFC5; break; // F8
- case 120 : keysym = 0xFFC6; break; // F9
- case 121 : keysym = 0xFFC7; break; // F10
- case 122 : keysym = 0xFFC8; break; // F11
- case 123 : keysym = 0xFFC9; break; // F12
- case 16 : keysym = 0xFFE1; break; // SHIFT
- case 17 : keysym = 0xFFE3; break; // CONTROL
- //case 18 : keysym = 0xFFE7; break; // Left Meta (Mac Option)
- case 18 : keysym = 0xFFE9; break; // Left ALT (Mac Command)
- default : keysym = evt.keyCode; break;
- }
- /* Remap symbols */
- switch (keysym) {
- case 186 : keysym = 59; break; // ; (IE)
- case 187 : keysym = 61; break; // = (IE)
- case 188 : keysym = 44; break; // , (Mozilla, IE)
- case 109 : // - (Mozilla, Opera)
- if (Util.Engine.gecko || Util.Engine.presto) {
- keysym = 45; }
- break;
- case 189 : keysym = 45; break; // - (IE)
- case 190 : keysym = 46; break; // . (Mozilla, IE)
- case 191 : keysym = 47; break; // / (Mozilla, IE)
- case 192 : keysym = 96; break; // ` (Mozilla, IE)
- case 219 : keysym = 91; break; // [ (Mozilla, IE)
- case 220 : keysym = 92; break; // \ (Mozilla, IE)
- case 221 : keysym = 93; break; // ] (Mozilla, IE)
- case 222 : keysym = 39; break; // ' (Mozilla, IE)
- }
-
- /* Remap shifted and unshifted keys */
- if (!!evt.shiftKey) {
- switch (keysym) {
- case 48 : keysym = 41 ; break; // ) (shifted 0)
- case 49 : keysym = 33 ; break; // ! (shifted 1)
- case 50 : keysym = 64 ; break; // @ (shifted 2)
- case 51 : keysym = 35 ; break; // # (shifted 3)
- case 52 : keysym = 36 ; break; // $ (shifted 4)
- case 53 : keysym = 37 ; break; // % (shifted 5)
- case 54 : keysym = 94 ; break; // ^ (shifted 6)
- case 55 : keysym = 38 ; break; // & (shifted 7)
- case 56 : keysym = 42 ; break; // * (shifted 8)
- case 57 : keysym = 40 ; break; // ( (shifted 9)
- case 59 : keysym = 58 ; break; // : (shifted `)
- case 61 : keysym = 43 ; break; // + (shifted ;)
- case 44 : keysym = 60 ; break; // < (shifted ,)
- case 45 : keysym = 95 ; break; // _ (shifted -)
- case 46 : keysym = 62 ; break; // > (shifted .)
- case 47 : keysym = 63 ; break; // ? (shifted /)
- case 96 : keysym = 126; break; // ~ (shifted `)
- case 91 : keysym = 123; break; // { (shifted [)
- case 92 : keysym = 124; break; // | (shifted \)
- case 93 : keysym = 125; break; // } (shifted ])
- case 39 : keysym = 34 ; break; // " (shifted ')
- }
- } else if ((keysym >= 65) && (keysym <=90)) {
- /* Remap unshifted A-Z */
- keysym += 32;
- } else if (evt.keyLocation === 3) {
- // numpad keys
- switch (keysym) {
- case 96 : keysym = 48; break; // 0
- case 97 : keysym = 49; break; // 1
- case 98 : keysym = 50; break; // 2
- case 99 : keysym = 51; break; // 3
- case 100: keysym = 52; break; // 4
- case 101: keysym = 53; break; // 5
- case 102: keysym = 54; break; // 6
- case 103: keysym = 55; break; // 7
- case 104: keysym = 56; break; // 8
- case 105: keysym = 57; break; // 9
- case 109: keysym = 45; break; // -
- case 110: keysym = 46; break; // .
- case 111: keysym = 47; break; // /
- }
- }
- return keysym;
- };
- that.grab = function() {
- //Util.Debug(">> Keyboard.grab");
- var c = conf.target;
- Util.addEvent(c, 'keydown', onKeyDown);
- Util.addEvent(c, 'keyup', onKeyUp);
- Util.addEvent(c, 'keypress', onKeyPress);
- //Util.Debug("<< Keyboard.grab");
- };
- that.ungrab = function() {
- //Util.Debug(">> Keyboard.ungrab");
- var c = conf.target;
- Util.removeEvent(c, 'keydown', onKeyDown);
- Util.removeEvent(c, 'keyup', onKeyUp);
- Util.removeEvent(c, 'keypress', onKeyPress);
- //Util.Debug(">> Keyboard.ungrab");
- };
- return that; // Return the public API interface
- } // End of Keyboard()
- //
- // Mouse event handler
- //
- function Mouse(conf) {
- "use strict";
- conf = conf || {}; // Configuration
- var that = {}; // Public API interface
- // Configuration settings
- function cdef(v, type, defval, desc) {
- Util.conf_default(conf, that, v, type, defval, desc); }
- // Capability settings, default can be overridden
- cdef('target', 'dom', document, 'DOM element that grabs mouse input');
- cdef('focused', 'bool', true, 'Capture and send mouse clicks/movement');
- cdef('mouseButton', 'func', null, 'Handler for mouse button click/release');
- cdef('mouseMove', 'func', null, 'Handler for mouse movement');
- that.set_target = function () { throw("target cannot be changed"); }
- //
- // Private functions
- //
- function onMouseButton(e, down) {
- var evt, pos, bmask;
- if (! conf.focused) {
- return true;
- }
- evt = (e ? e : window.event);
- pos = Util.getEventPosition(e, conf.target, conf.scale);
- 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
- }
- //Util.Debug("mouse " + pos.x + "," + pos.y + " down: " + down +
- // " bmask: " + bmask + "(evt.button: " + evt.button + ")");
- if (conf.mouseButton) {
- conf.mouseButton(pos.x, pos.y, down, bmask);
- }
- Util.stopEvent(e);
- return false;
- }
- function onMouseDown(e) {
- onMouseButton(e, 1);
- }
- function onMouseUp(e) {
- onMouseButton(e, 0);
- }
- function onMouseWheel(e) {
- var evt, pos, bmask, wheelData;
- if (! conf.focused) {
- return true;
- }
- evt = (e ? e : window.event);
- pos = Util.getEventPosition(e, conf.target, conf.scale);
- wheelData = evt.detail ? evt.detail * -1 : evt.wheelDelta / 40;
- if (wheelData > 0) {
- bmask = 1 << 3;
- } else {
- bmask = 1 << 4;
- }
- //Util.Debug('mouse scroll by ' + wheelData + ':' + pos.x + "," + pos.y);
- if (conf.mouseButton) {
- conf.mouseButton(pos.x, pos.y, 1, bmask);
- conf.mouseButton(pos.x, pos.y, 0, bmask);
- }
- Util.stopEvent(e);
- return false;
- }
- function onMouseMove(e) {
- var evt, pos;
- if (! conf.focused) {
- return true;
- }
- evt = (e ? e : window.event);
- pos = Util.getEventPosition(e, conf.target, conf.scale);
- //Util.Debug('mouse ' + evt.which + '/' + evt.button + ' up:' + pos.x + "," + pos.y);
- if (conf.mouseMove) {
- conf.mouseMove(pos.x, pos.y);
- }
- }
- function onMouseDisable(e) {
- var evt, pos;
- if (! conf.focused) {
- return true;
- }
- evt = (e ? e : window.event);
- pos = Util.getEventPosition(e, conf.target, conf.scale);
- /* Stop propagation if inside canvas area */
- if ((pos.x >= 0) && (pos.y >= 0) &&
- (pos.x < conf.target.offsetWidth) &&
- (pos.y < conf.target.offsetHeight)) {
- //Util.Debug("mouse event disabled");
- Util.stopEvent(e);
- return false;
- }
- //Util.Debug("mouse event not disabled");
- return true;
- }
- //
- // Public API interface functions
- //
- that.grab = function() {
- //Util.Debug(">> Mouse.grab");
- var c = conf.target;
- Util.addEvent(c, 'mousedown', onMouseDown);
- Util.addEvent(c, 'mouseup', onMouseUp);
- Util.addEvent(c, 'mousemove', onMouseMove);
- Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel',
- onMouseWheel);
- /* Work around right and middle click browser behaviors */
- Util.addEvent(document, 'click', onMouseDisable);
- Util.addEvent(document.body, 'contextmenu', onMouseDisable);
- //Util.Debug("<< Mouse.grab");
- };
- that.ungrab = function() {
- //Util.Debug(">> Mouse.ungrab");
- var c = conf.target;
- Util.removeEvent(c, 'mousedown', onMouseDown);
- Util.removeEvent(c, 'mouseup', onMouseUp);
- Util.removeEvent(c, 'mousemove', onMouseMove);
- Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel',
- onMouseWheel);
- /* Work around right and middle click browser behaviors */
- Util.removeEvent(document, 'click', onMouseDisable);
- Util.removeEvent(document.body, 'contextmenu', onMouseDisable);
- //Util.Debug(">> Mouse.ungrab");
- };
- return that; // Return the public API interface
- } // End of Mouse()
|