Fix noVNC: utiliser la version ESM (core/) au lieu du CommonJS lib/ (erreur can find variable export)
76 changed files +11,181 −8,814
modified
public/app.js
+1 −1
@@ -80,7 +80,7 @@ | ||
| 80 | 80 | statusEl.textContent = 'connexion…'; |
| 81 | 81 | try { |
| 82 | 82 | const pw = await (await fetch('/api/social/vncpw')).json(); |
| 83 | − const { default: RFB } = await import('/vendor/novnc/rfb.js'); | |
| 83 | + const { default: RFB } = await import('/vendor/novnc/core/rfb.js'); | |
| 84 | 84 | const url = (location.protocol === 'https:' ? 'wss://' : 'ws://') + location.host + '/vncws'; |
| 85 | 85 | panel.style.display = 'block'; |
| 86 | 86 | _rfb = new RFB(panel, url, { credentials: { password: pw.password } }); |
deleted
public/vendor/novnc/base64.js
+0 −100
@@ -1,100 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 4 | −Object.defineProperty(exports, "__esModule", { | |
| 5 | − value: true | |
| 6 | −}); | |
| 7 | −exports["default"] = void 0; | |
| 8 | −var Log = _interopRequireWildcard(require("./util/logging.js")); | |
| 9 | −function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } | |
| 10 | −function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } | |
| 11 | −/* This Source Code Form is subject to the terms of the Mozilla Public | |
| 12 | − * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 13 | − * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 14 | −// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js | |
| 15 | −var _default = exports["default"] = { | |
| 16 | − /* Convert data (an array of integers) to a Base64 string. */ | |
| 17 | − toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''), | |
| 18 | − base64Pad: '=', | |
| 19 | − encode: function encode(data) { | |
| 20 | − "use strict"; | |
| 21 | − | |
| 22 | − var result = ''; | |
| 23 | − var length = data.length; | |
| 24 | − var lengthpad = length % 3; | |
| 25 | − // Convert every three bytes to 4 ascii characters. | |
| 26 | − | |
| 27 | − for (var i = 0; i < length - 2; i += 3) { | |
| 28 | − result += this.toBase64Table[data[i] >> 2]; | |
| 29 | − result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)]; | |
| 30 | − result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)]; | |
| 31 | − result += this.toBase64Table[data[i + 2] & 0x3f]; | |
| 32 | − } | |
| 33 | − | |
| 34 | − // Convert the remaining 1 or 2 bytes, pad out to 4 characters. | |
| 35 | − var j = length - lengthpad; | |
| 36 | − if (lengthpad === 2) { | |
| 37 | − result += this.toBase64Table[data[j] >> 2]; | |
| 38 | − result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)]; | |
| 39 | − result += this.toBase64Table[(data[j + 1] & 0x0f) << 2]; | |
| 40 | − result += this.toBase64Table[64]; | |
| 41 | − } else if (lengthpad === 1) { | |
| 42 | − result += this.toBase64Table[data[j] >> 2]; | |
| 43 | − result += this.toBase64Table[(data[j] & 0x03) << 4]; | |
| 44 | − result += this.toBase64Table[64]; | |
| 45 | − result += this.toBase64Table[64]; | |
| 46 | − } | |
| 47 | − return result; | |
| 48 | − }, | |
| 49 | − /* Convert Base64 data to a string */ | |
| 50 | − /* eslint-disable comma-spacing */ | |
| 51 | − toBinaryTable: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 0, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1], | |
| 52 | − /* eslint-enable comma-spacing */decode: function decode(data) { | |
| 53 | − var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | |
| 54 | − var dataLength = data.indexOf('=') - offset; | |
| 55 | − if (dataLength < 0) { | |
| 56 | − dataLength = data.length - offset; | |
| 57 | − } | |
| 58 | − | |
| 59 | − /* Every four characters is 3 resulting numbers */ | |
| 60 | − var resultLength = (dataLength >> 2) * 3 + Math.floor(dataLength % 4 / 1.5); | |
| 61 | − var result = new Array(resultLength); | |
| 62 | − | |
| 63 | − // Convert one by one. | |
| 64 | − | |
| 65 | − var leftbits = 0; // number of bits decoded, but yet to be appended | |
| 66 | − var leftdata = 0; // bits decoded, but yet to be appended | |
| 67 | − for (var idx = 0, i = offset; i < data.length; i++) { | |
| 68 | − var c = this.toBinaryTable[data.charCodeAt(i) & 0x7f]; | |
| 69 | − var padding = data.charAt(i) === this.base64Pad; | |
| 70 | − // Skip illegal characters and whitespace | |
| 71 | − if (c === -1) { | |
| 72 | − Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i); | |
| 73 | − continue; | |
| 74 | − } | |
| 75 | − | |
| 76 | − // Collect data into leftdata, update bitcount | |
| 77 | − leftdata = leftdata << 6 | c; | |
| 78 | − leftbits += 6; | |
| 79 | − | |
| 80 | − // If we have 8 or more bits, append 8 bits to the result | |
| 81 | − if (leftbits >= 8) { | |
| 82 | − leftbits -= 8; | |
| 83 | − // Append if not padding. | |
| 84 | − if (!padding) { | |
| 85 | − result[idx++] = leftdata >> leftbits & 0xff; | |
| 86 | − } | |
| 87 | − leftdata &= (1 << leftbits) - 1; | |
| 88 | − } | |
| 89 | − } | |
| 90 | − | |
| 91 | − // If there are any bits left, the base64 string was corrupted | |
| 92 | − if (leftbits) { | |
| 93 | − var err = new Error('Corrupted base64 string'); | |
| 94 | − err.name = 'Base64-Error'; | |
| 95 | − throw err; | |
| 96 | − } | |
| 97 | − return result; | |
| 98 | − } | |
| 99 | −}; | |
| 100 | −/* End of Base64 namespace */ | |
| \ No newline at end of file | ||
added
public/vendor/novnc/core/base64.js
+104 −0
@@ -0,0 +1,104 @@ | ||
| 1 | +/* This Source Code Form is subject to the terms of the Mozilla Public | |
| 2 | + * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 3 | + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 4 | + | |
| 5 | +// From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js | |
| 6 | + | |
| 7 | +import * as Log from './util/logging.js'; | |
| 8 | + | |
| 9 | +export default { | |
| 10 | + /* Convert data (an array of integers) to a Base64 string. */ | |
| 11 | + toBase64Table: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''), | |
| 12 | + base64Pad: '=', | |
| 13 | + | |
| 14 | + encode(data) { | |
| 15 | + "use strict"; | |
| 16 | + let result = ''; | |
| 17 | + const length = data.length; | |
| 18 | + const lengthpad = (length % 3); | |
| 19 | + // Convert every three bytes to 4 ascii characters. | |
| 20 | + | |
| 21 | + for (let i = 0; i < (length - 2); i += 3) { | |
| 22 | + result += this.toBase64Table[data[i] >> 2]; | |
| 23 | + result += this.toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)]; | |
| 24 | + result += this.toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)]; | |
| 25 | + result += this.toBase64Table[data[i + 2] & 0x3f]; | |
| 26 | + } | |
| 27 | + | |
| 28 | + // Convert the remaining 1 or 2 bytes, pad out to 4 characters. | |
| 29 | + const j = length - lengthpad; | |
| 30 | + if (lengthpad === 2) { | |
| 31 | + result += this.toBase64Table[data[j] >> 2]; | |
| 32 | + result += this.toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)]; | |
| 33 | + result += this.toBase64Table[(data[j + 1] & 0x0f) << 2]; | |
| 34 | + result += this.toBase64Table[64]; | |
| 35 | + } else if (lengthpad === 1) { | |
| 36 | + result += this.toBase64Table[data[j] >> 2]; | |
| 37 | + result += this.toBase64Table[(data[j] & 0x03) << 4]; | |
| 38 | + result += this.toBase64Table[64]; | |
| 39 | + result += this.toBase64Table[64]; | |
| 40 | + } | |
| 41 | + | |
| 42 | + return result; | |
| 43 | + }, | |
| 44 | + | |
| 45 | + /* Convert Base64 data to a string */ | |
| 46 | + /* eslint-disable comma-spacing */ | |
| 47 | + toBinaryTable: [ | |
| 48 | + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, | |
| 49 | + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, | |
| 50 | + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, | |
| 51 | + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, | |
| 52 | + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, | |
| 53 | + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, | |
| 54 | + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, | |
| 55 | + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 | |
| 56 | + ], | |
| 57 | + /* eslint-enable comma-spacing */ | |
| 58 | + | |
| 59 | + decode(data, offset = 0) { | |
| 60 | + let dataLength = data.indexOf('=') - offset; | |
| 61 | + if (dataLength < 0) { dataLength = data.length - offset; } | |
| 62 | + | |
| 63 | + /* Every four characters is 3 resulting numbers */ | |
| 64 | + const resultLength = (dataLength >> 2) * 3 + Math.floor((dataLength % 4) / 1.5); | |
| 65 | + const result = new Array(resultLength); | |
| 66 | + | |
| 67 | + // Convert one by one. | |
| 68 | + | |
| 69 | + let leftbits = 0; // number of bits decoded, but yet to be appended | |
| 70 | + let leftdata = 0; // bits decoded, but yet to be appended | |
| 71 | + for (let idx = 0, i = offset; i < data.length; i++) { | |
| 72 | + const c = this.toBinaryTable[data.charCodeAt(i) & 0x7f]; | |
| 73 | + const padding = (data.charAt(i) === this.base64Pad); | |
| 74 | + // Skip illegal characters and whitespace | |
| 75 | + if (c === -1) { | |
| 76 | + Log.Error("Illegal character code " + data.charCodeAt(i) + " at position " + i); | |
| 77 | + continue; | |
| 78 | + } | |
| 79 | + | |
| 80 | + // Collect data into leftdata, update bitcount | |
| 81 | + leftdata = (leftdata << 6) | c; | |
| 82 | + leftbits += 6; | |
| 83 | + | |
| 84 | + // If we have 8 or more bits, append 8 bits to the result | |
| 85 | + if (leftbits >= 8) { | |
| 86 | + leftbits -= 8; | |
| 87 | + // Append if not padding. | |
| 88 | + if (!padding) { | |
| 89 | + result[idx++] = (leftdata >> leftbits) & 0xff; | |
| 90 | + } | |
| 91 | + leftdata &= (1 << leftbits) - 1; | |
| 92 | + } | |
| 93 | + } | |
| 94 | + | |
| 95 | + // If there are any bits left, the base64 string was corrupted | |
| 96 | + if (leftbits) { | |
| 97 | + const err = new Error('Corrupted base64 string'); | |
| 98 | + err.name = 'Base64-Error'; | |
| 99 | + throw err; | |
| 100 | + } | |
| 101 | + | |
| 102 | + return result; | |
| 103 | + } | |
| 104 | +}; /* End of Base64 namespace */ | |
added
public/vendor/novnc/core/crypto/aes.js
+178 −0
@@ -0,0 +1,178 @@ | ||
| 1 | +export class AESECBCipher { | |
| 2 | + constructor() { | |
| 3 | + this._key = null; | |
| 4 | + } | |
| 5 | + | |
| 6 | + get algorithm() { | |
| 7 | + return { name: "AES-ECB" }; | |
| 8 | + } | |
| 9 | + | |
| 10 | + static async importKey(key, _algorithm, extractable, keyUsages) { | |
| 11 | + const cipher = new AESECBCipher; | |
| 12 | + await cipher._importKey(key, extractable, keyUsages); | |
| 13 | + return cipher; | |
| 14 | + } | |
| 15 | + | |
| 16 | + async _importKey(key, extractable, keyUsages) { | |
| 17 | + this._key = await window.crypto.subtle.importKey( | |
| 18 | + "raw", key, {name: "AES-CBC"}, extractable, keyUsages); | |
| 19 | + } | |
| 20 | + | |
| 21 | + async encrypt(_algorithm, plaintext) { | |
| 22 | + const x = new Uint8Array(plaintext); | |
| 23 | + if (x.length % 16 !== 0 || this._key === null) { | |
| 24 | + return null; | |
| 25 | + } | |
| 26 | + const n = x.length / 16; | |
| 27 | + for (let i = 0; i < n; i++) { | |
| 28 | + const y = new Uint8Array(await window.crypto.subtle.encrypt({ | |
| 29 | + name: "AES-CBC", | |
| 30 | + iv: new Uint8Array(16), | |
| 31 | + }, this._key, x.slice(i * 16, i * 16 + 16))).slice(0, 16); | |
| 32 | + x.set(y, i * 16); | |
| 33 | + } | |
| 34 | + return x; | |
| 35 | + } | |
| 36 | +} | |
| 37 | + | |
| 38 | +export class AESEAXCipher { | |
| 39 | + constructor() { | |
| 40 | + this._rawKey = null; | |
| 41 | + this._ctrKey = null; | |
| 42 | + this._cbcKey = null; | |
| 43 | + this._zeroBlock = new Uint8Array(16); | |
| 44 | + this._prefixBlock0 = this._zeroBlock; | |
| 45 | + this._prefixBlock1 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); | |
| 46 | + this._prefixBlock2 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]); | |
| 47 | + } | |
| 48 | + | |
| 49 | + get algorithm() { | |
| 50 | + return { name: "AES-EAX" }; | |
| 51 | + } | |
| 52 | + | |
| 53 | + async _encryptBlock(block) { | |
| 54 | + const encrypted = await window.crypto.subtle.encrypt({ | |
| 55 | + name: "AES-CBC", | |
| 56 | + iv: this._zeroBlock, | |
| 57 | + }, this._cbcKey, block); | |
| 58 | + return new Uint8Array(encrypted).slice(0, 16); | |
| 59 | + } | |
| 60 | + | |
| 61 | + async _initCMAC() { | |
| 62 | + const k1 = await this._encryptBlock(this._zeroBlock); | |
| 63 | + const k2 = new Uint8Array(16); | |
| 64 | + const v = k1[0] >>> 6; | |
| 65 | + for (let i = 0; i < 15; i++) { | |
| 66 | + k2[i] = (k1[i + 1] >> 6) | (k1[i] << 2); | |
| 67 | + k1[i] = (k1[i + 1] >> 7) | (k1[i] << 1); | |
| 68 | + } | |
| 69 | + const lut = [0x0, 0x87, 0x0e, 0x89]; | |
| 70 | + k2[14] ^= v >>> 1; | |
| 71 | + k2[15] = (k1[15] << 2) ^ lut[v]; | |
| 72 | + k1[15] = (k1[15] << 1) ^ lut[v >> 1]; | |
| 73 | + this._k1 = k1; | |
| 74 | + this._k2 = k2; | |
| 75 | + } | |
| 76 | + | |
| 77 | + async _encryptCTR(data, counter) { | |
| 78 | + const encrypted = await window.crypto.subtle.encrypt({ | |
| 79 | + name: "AES-CTR", | |
| 80 | + counter: counter, | |
| 81 | + length: 128 | |
| 82 | + }, this._ctrKey, data); | |
| 83 | + return new Uint8Array(encrypted); | |
| 84 | + } | |
| 85 | + | |
| 86 | + async _decryptCTR(data, counter) { | |
| 87 | + const decrypted = await window.crypto.subtle.decrypt({ | |
| 88 | + name: "AES-CTR", | |
| 89 | + counter: counter, | |
| 90 | + length: 128 | |
| 91 | + }, this._ctrKey, data); | |
| 92 | + return new Uint8Array(decrypted); | |
| 93 | + } | |
| 94 | + | |
| 95 | + async _computeCMAC(data, prefixBlock) { | |
| 96 | + if (prefixBlock.length !== 16) { | |
| 97 | + return null; | |
| 98 | + } | |
| 99 | + const n = Math.floor(data.length / 16); | |
| 100 | + const m = Math.ceil(data.length / 16); | |
| 101 | + const r = data.length - n * 16; | |
| 102 | + const cbcData = new Uint8Array((m + 1) * 16); | |
| 103 | + cbcData.set(prefixBlock); | |
| 104 | + cbcData.set(data, 16); | |
| 105 | + if (r === 0) { | |
| 106 | + for (let i = 0; i < 16; i++) { | |
| 107 | + cbcData[n * 16 + i] ^= this._k1[i]; | |
| 108 | + } | |
| 109 | + } else { | |
| 110 | + cbcData[(n + 1) * 16 + r] = 0x80; | |
| 111 | + for (let i = 0; i < 16; i++) { | |
| 112 | + cbcData[(n + 1) * 16 + i] ^= this._k2[i]; | |
| 113 | + } | |
| 114 | + } | |
| 115 | + let cbcEncrypted = await window.crypto.subtle.encrypt({ | |
| 116 | + name: "AES-CBC", | |
| 117 | + iv: this._zeroBlock, | |
| 118 | + }, this._cbcKey, cbcData); | |
| 119 | + | |
| 120 | + cbcEncrypted = new Uint8Array(cbcEncrypted); | |
| 121 | + const mac = cbcEncrypted.slice(cbcEncrypted.length - 32, cbcEncrypted.length - 16); | |
| 122 | + return mac; | |
| 123 | + } | |
| 124 | + | |
| 125 | + static async importKey(key, _algorithm, _extractable, _keyUsages) { | |
| 126 | + const cipher = new AESEAXCipher; | |
| 127 | + await cipher._importKey(key); | |
| 128 | + return cipher; | |
| 129 | + } | |
| 130 | + | |
| 131 | + async _importKey(key) { | |
| 132 | + this._rawKey = key; | |
| 133 | + this._ctrKey = await window.crypto.subtle.importKey( | |
| 134 | + "raw", key, {name: "AES-CTR"}, false, ["encrypt", "decrypt"]); | |
| 135 | + this._cbcKey = await window.crypto.subtle.importKey( | |
| 136 | + "raw", key, {name: "AES-CBC"}, false, ["encrypt"]); | |
| 137 | + await this._initCMAC(); | |
| 138 | + } | |
| 139 | + | |
| 140 | + async encrypt(algorithm, message) { | |
| 141 | + const ad = algorithm.additionalData; | |
| 142 | + const nonce = algorithm.iv; | |
| 143 | + const nCMAC = await this._computeCMAC(nonce, this._prefixBlock0); | |
| 144 | + const encrypted = await this._encryptCTR(message, nCMAC); | |
| 145 | + const adCMAC = await this._computeCMAC(ad, this._prefixBlock1); | |
| 146 | + const mac = await this._computeCMAC(encrypted, this._prefixBlock2); | |
| 147 | + for (let i = 0; i < 16; i++) { | |
| 148 | + mac[i] ^= nCMAC[i] ^ adCMAC[i]; | |
| 149 | + } | |
| 150 | + const res = new Uint8Array(16 + encrypted.length); | |
| 151 | + res.set(encrypted); | |
| 152 | + res.set(mac, encrypted.length); | |
| 153 | + return res; | |
| 154 | + } | |
| 155 | + | |
| 156 | + async decrypt(algorithm, data) { | |
| 157 | + const encrypted = data.slice(0, data.length - 16); | |
| 158 | + const ad = algorithm.additionalData; | |
| 159 | + const nonce = algorithm.iv; | |
| 160 | + const mac = data.slice(data.length - 16); | |
| 161 | + const nCMAC = await this._computeCMAC(nonce, this._prefixBlock0); | |
| 162 | + const adCMAC = await this._computeCMAC(ad, this._prefixBlock1); | |
| 163 | + const computedMac = await this._computeCMAC(encrypted, this._prefixBlock2); | |
| 164 | + for (let i = 0; i < 16; i++) { | |
| 165 | + computedMac[i] ^= nCMAC[i] ^ adCMAC[i]; | |
| 166 | + } | |
| 167 | + if (computedMac.length !== mac.length) { | |
| 168 | + return null; | |
| 169 | + } | |
| 170 | + for (let i = 0; i < mac.length; i++) { | |
| 171 | + if (computedMac[i] !== mac[i]) { | |
| 172 | + return null; | |
| 173 | + } | |
| 174 | + } | |
| 175 | + const res = await this._decryptCTR(encrypted, nCMAC); | |
| 176 | + return res; | |
| 177 | + } | |
| 178 | +} | |
added
public/vendor/novnc/core/crypto/bigint.js
+34 −0
@@ -0,0 +1,34 @@ | ||
| 1 | +export function modPow(b, e, m) { | |
| 2 | + let r = 1n; | |
| 3 | + b = b % m; | |
| 4 | + while (e > 0n) { | |
| 5 | + if ((e & 1n) === 1n) { | |
| 6 | + r = (r * b) % m; | |
| 7 | + } | |
| 8 | + e = e >> 1n; | |
| 9 | + b = (b * b) % m; | |
| 10 | + } | |
| 11 | + return r; | |
| 12 | +} | |
| 13 | + | |
| 14 | +export function bigIntToU8Array(bigint, padLength=0) { | |
| 15 | + let hex = bigint.toString(16); | |
| 16 | + if (padLength === 0) { | |
| 17 | + padLength = Math.ceil(hex.length / 2); | |
| 18 | + } | |
| 19 | + hex = hex.padStart(padLength * 2, '0'); | |
| 20 | + const length = hex.length / 2; | |
| 21 | + const arr = new Uint8Array(length); | |
| 22 | + for (let i = 0; i < length; i++) { | |
| 23 | + arr[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16); | |
| 24 | + } | |
| 25 | + return arr; | |
| 26 | +} | |
| 27 | + | |
| 28 | +export function u8ArrayToBigInt(arr) { | |
| 29 | + let hex = '0x'; | |
| 30 | + for (let i = 0; i < arr.length; i++) { | |
| 31 | + hex += arr[i].toString(16).padStart(2, '0'); | |
| 32 | + } | |
| 33 | + return BigInt(hex); | |
| 34 | +} | |
added
public/vendor/novnc/core/crypto/crypto.js
+90 −0
@@ -0,0 +1,90 @@ | ||
| 1 | +import { AESECBCipher, AESEAXCipher } from "./aes.js"; | |
| 2 | +import { DESCBCCipher, DESECBCipher } from "./des.js"; | |
| 3 | +import { RSACipher } from "./rsa.js"; | |
| 4 | +import { DHCipher } from "./dh.js"; | |
| 5 | +import { MD5 } from "./md5.js"; | |
| 6 | + | |
| 7 | +// A single interface for the cryptographic algorithms not supported by SubtleCrypto. | |
| 8 | +// Both synchronous and asynchronous implmentations are allowed. | |
| 9 | +class LegacyCrypto { | |
| 10 | + constructor() { | |
| 11 | + this._algorithms = { | |
| 12 | + "AES-ECB": AESECBCipher, | |
| 13 | + "AES-EAX": AESEAXCipher, | |
| 14 | + "DES-ECB": DESECBCipher, | |
| 15 | + "DES-CBC": DESCBCCipher, | |
| 16 | + "RSA-PKCS1-v1_5": RSACipher, | |
| 17 | + "DH": DHCipher, | |
| 18 | + "MD5": MD5, | |
| 19 | + }; | |
| 20 | + } | |
| 21 | + | |
| 22 | + encrypt(algorithm, key, data) { | |
| 23 | + if (key.algorithm.name !== algorithm.name) { | |
| 24 | + throw new Error("algorithm does not match"); | |
| 25 | + } | |
| 26 | + if (typeof key.encrypt !== "function") { | |
| 27 | + throw new Error("key does not support encryption"); | |
| 28 | + } | |
| 29 | + return key.encrypt(algorithm, data); | |
| 30 | + } | |
| 31 | + | |
| 32 | + decrypt(algorithm, key, data) { | |
| 33 | + if (key.algorithm.name !== algorithm.name) { | |
| 34 | + throw new Error("algorithm does not match"); | |
| 35 | + } | |
| 36 | + if (typeof key.decrypt !== "function") { | |
| 37 | + throw new Error("key does not support encryption"); | |
| 38 | + } | |
| 39 | + return key.decrypt(algorithm, data); | |
| 40 | + } | |
| 41 | + | |
| 42 | + importKey(format, keyData, algorithm, extractable, keyUsages) { | |
| 43 | + if (format !== "raw") { | |
| 44 | + throw new Error("key format is not supported"); | |
| 45 | + } | |
| 46 | + const alg = this._algorithms[algorithm.name]; | |
| 47 | + if (typeof alg === "undefined" || typeof alg.importKey !== "function") { | |
| 48 | + throw new Error("algorithm is not supported"); | |
| 49 | + } | |
| 50 | + return alg.importKey(keyData, algorithm, extractable, keyUsages); | |
| 51 | + } | |
| 52 | + | |
| 53 | + generateKey(algorithm, extractable, keyUsages) { | |
| 54 | + const alg = this._algorithms[algorithm.name]; | |
| 55 | + if (typeof alg === "undefined" || typeof alg.generateKey !== "function") { | |
| 56 | + throw new Error("algorithm is not supported"); | |
| 57 | + } | |
| 58 | + return alg.generateKey(algorithm, extractable, keyUsages); | |
| 59 | + } | |
| 60 | + | |
| 61 | + exportKey(format, key) { | |
| 62 | + if (format !== "raw") { | |
| 63 | + throw new Error("key format is not supported"); | |
| 64 | + } | |
| 65 | + if (typeof key.exportKey !== "function") { | |
| 66 | + throw new Error("key does not support exportKey"); | |
| 67 | + } | |
| 68 | + return key.exportKey(); | |
| 69 | + } | |
| 70 | + | |
| 71 | + digest(algorithm, data) { | |
| 72 | + const alg = this._algorithms[algorithm]; | |
| 73 | + if (typeof alg !== "function") { | |
| 74 | + throw new Error("algorithm is not supported"); | |
| 75 | + } | |
| 76 | + return alg(data); | |
| 77 | + } | |
| 78 | + | |
| 79 | + deriveBits(algorithm, key, length) { | |
| 80 | + if (key.algorithm.name !== algorithm.name) { | |
| 81 | + throw new Error("algorithm does not match"); | |
| 82 | + } | |
| 83 | + if (typeof key.deriveBits !== "function") { | |
| 84 | + throw new Error("key does not support deriveBits"); | |
| 85 | + } | |
| 86 | + return key.deriveBits(algorithm, length); | |
| 87 | + } | |
| 88 | +} | |
| 89 | + | |
| 90 | +export default new LegacyCrypto; | |
added
public/vendor/novnc/core/crypto/des.js
+330 −0
@@ -0,0 +1,330 @@ | ||
| 1 | +/* | |
| 2 | + * Ported from Flashlight VNC ActionScript implementation: | |
| 3 | + * http://www.wizhelp.com/flashlight-vnc/ | |
| 4 | + * | |
| 5 | + * Full attribution follows: | |
| 6 | + * | |
| 7 | + * ------------------------------------------------------------------------- | |
| 8 | + * | |
| 9 | + * This DES class has been extracted from package Acme.Crypto for use in VNC. | |
| 10 | + * The unnecessary odd parity code has been removed. | |
| 11 | + * | |
| 12 | + * These changes are: | |
| 13 | + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. | |
| 14 | + * | |
| 15 | + * This software is distributed in the hope that it will be useful, | |
| 16 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 17 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
| 18 | + * | |
| 19 | + | |
| 20 | + * DesCipher - the DES encryption method | |
| 21 | + * | |
| 22 | + * The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is: | |
| 23 | + * | |
| 24 | + * Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. | |
| 25 | + * | |
| 26 | + * Permission to use, copy, modify, and distribute this software | |
| 27 | + * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and | |
| 28 | + * without fee is hereby granted, provided that this copyright notice is kept | |
| 29 | + * intact. | |
| 30 | + * | |
| 31 | + * WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY | |
| 32 | + * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED | |
| 33 | + * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |
| 34 | + * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE | |
| 35 | + * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
| 36 | + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. | |
| 37 | + * | |
| 38 | + * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE | |
| 39 | + * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE | |
| 40 | + * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT | |
| 41 | + * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE | |
| 42 | + * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE | |
| 43 | + * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE | |
| 44 | + * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP | |
| 45 | + * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR | |
| 46 | + * HIGH RISK ACTIVITIES. | |
| 47 | + * | |
| 48 | + * | |
| 49 | + * The rest is: | |
| 50 | + * | |
| 51 | + * Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved. | |
| 52 | + * | |
| 53 | + * Redistribution and use in source and binary forms, with or without | |
| 54 | + * modification, are permitted provided that the following conditions | |
| 55 | + * are met: | |
| 56 | + * 1. Redistributions of source code must retain the above copyright | |
| 57 | + * notice, this list of conditions and the following disclaimer. | |
| 58 | + * 2. Redistributions in binary form must reproduce the above copyright | |
| 59 | + * notice, this list of conditions and the following disclaimer in the | |
| 60 | + * documentation and/or other materials provided with the distribution. | |
| 61 | + * | |
| 62 | + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
| 63 | + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 64 | + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 65 | + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
| 66 | + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 67 | + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 68 | + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 69 | + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 70 | + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 71 | + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 72 | + * SUCH DAMAGE. | |
| 73 | + * | |
| 74 | + * Visit the ACME Labs Java page for up-to-date versions of this and other | |
| 75 | + * fine Java utilities: http://www.acme.com/java/ | |
| 76 | + */ | |
| 77 | + | |
| 78 | +/* eslint-disable comma-spacing */ | |
| 79 | + | |
| 80 | +// Tables, permutations, S-boxes, etc. | |
| 81 | +const PC2 = [13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3, | |
| 82 | + 25, 7,15, 6,26,19,12, 1,40,51,30,36,46,54,29,39, | |
| 83 | + 50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31 ], | |
| 84 | + totrot = [ 1, 2, 4, 6, 8,10,12,14,15,17,19,21,23,25,27,28]; | |
| 85 | + | |
| 86 | +const z = 0x0; | |
| 87 | +let a,b,c,d,e,f; | |
| 88 | +a=1<<16; b=1<<24; c=a|b; d=1<<2; e=1<<10; f=d|e; | |
| 89 | +const SP1 = [c|e,z|z,a|z,c|f,c|d,a|f,z|d,a|z,z|e,c|e,c|f,z|e,b|f,c|d,b|z,z|d, | |
| 90 | + z|f,b|e,b|e,a|e,a|e,c|z,c|z,b|f,a|d,b|d,b|d,a|d,z|z,z|f,a|f,b|z, | |
| 91 | + a|z,c|f,z|d,c|z,c|e,b|z,b|z,z|e,c|d,a|z,a|e,b|d,z|e,z|d,b|f,a|f, | |
| 92 | + c|f,a|d,c|z,b|f,b|d,z|f,a|f,c|e,z|f,b|e,b|e,z|z,a|d,a|e,z|z,c|d]; | |
| 93 | +a=1<<20; b=1<<31; c=a|b; d=1<<5; e=1<<15; f=d|e; | |
| 94 | +const SP2 = [c|f,b|e,z|e,a|f,a|z,z|d,c|d,b|f,b|d,c|f,c|e,b|z,b|e,a|z,z|d,c|d, | |
| 95 | + a|e,a|d,b|f,z|z,b|z,z|e,a|f,c|z,a|d,b|d,z|z,a|e,z|f,c|e,c|z,z|f, | |
| 96 | + z|z,a|f,c|d,a|z,b|f,c|z,c|e,z|e,c|z,b|e,z|d,c|f,a|f,z|d,z|e,b|z, | |
| 97 | + z|f,c|e,a|z,b|d,a|d,b|f,b|d,a|d,a|e,z|z,b|e,z|f,b|z,c|d,c|f,a|e]; | |
| 98 | +a=1<<17; b=1<<27; c=a|b; d=1<<3; e=1<<9; f=d|e; | |
| 99 | +const SP3 = [z|f,c|e,z|z,c|d,b|e,z|z,a|f,b|e,a|d,b|d,b|d,a|z,c|f,a|d,c|z,z|f, | |
| 100 | + b|z,z|d,c|e,z|e,a|e,c|z,c|d,a|f,b|f,a|e,a|z,b|f,z|d,c|f,z|e,b|z, | |
| 101 | + c|e,b|z,a|d,z|f,a|z,c|e,b|e,z|z,z|e,a|d,c|f,b|e,b|d,z|e,z|z,c|d, | |
| 102 | + b|f,a|z,b|z,c|f,z|d,a|f,a|e,b|d,c|z,b|f,z|f,c|z,a|f,z|d,c|d,a|e]; | |
| 103 | +a=1<<13; b=1<<23; c=a|b; d=1<<0; e=1<<7; f=d|e; | |
| 104 | +const SP4 = [c|d,a|f,a|f,z|e,c|e,b|f,b|d,a|d,z|z,c|z,c|z,c|f,z|f,z|z,b|e,b|d, | |
| 105 | + z|d,a|z,b|z,c|d,z|e,b|z,a|d,a|e,b|f,z|d,a|e,b|e,a|z,c|e,c|f,z|f, | |
| 106 | + b|e,b|d,c|z,c|f,z|f,z|z,z|z,c|z,a|e,b|e,b|f,z|d,c|d,a|f,a|f,z|e, | |
| 107 | + c|f,z|f,z|d,a|z,b|d,a|d,c|e,b|f,a|d,a|e,b|z,c|d,z|e,b|z,a|z,c|e]; | |
| 108 | +a=1<<25; b=1<<30; c=a|b; d=1<<8; e=1<<19; f=d|e; | |
| 109 | +const SP5 = [z|d,a|f,a|e,c|d,z|e,z|d,b|z,a|e,b|f,z|e,a|d,b|f,c|d,c|e,z|f,b|z, | |
| 110 | + a|z,b|e,b|e,z|z,b|d,c|f,c|f,a|d,c|e,b|d,z|z,c|z,a|f,a|z,c|z,z|f, | |
| 111 | + z|e,c|d,z|d,a|z,b|z,a|e,c|d,b|f,a|d,b|z,c|e,a|f,b|f,z|d,a|z,c|e, | |
| 112 | + c|f,z|f,c|z,c|f,a|e,z|z,b|e,c|z,z|f,a|d,b|d,z|e,z|z,b|e,a|f,b|d]; | |
| 113 | +a=1<<22; b=1<<29; c=a|b; d=1<<4; e=1<<14; f=d|e; | |
| 114 | +const SP6 = [b|d,c|z,z|e,c|f,c|z,z|d,c|f,a|z,b|e,a|f,a|z,b|d,a|d,b|e,b|z,z|f, | |
| 115 | + z|z,a|d,b|f,z|e,a|e,b|f,z|d,c|d,c|d,z|z,a|f,c|e,z|f,a|e,c|e,b|z, | |
| 116 | + b|e,z|d,c|d,a|e,c|f,a|z,z|f,b|d,a|z,b|e,b|z,z|f,b|d,c|f,a|e,c|z, | |
| 117 | + a|f,c|e,z|z,c|d,z|d,z|e,c|z,a|f,z|e,a|d,b|f,z|z,c|e,b|z,a|d,b|f]; | |
| 118 | +a=1<<21; b=1<<26; c=a|b; d=1<<1; e=1<<11; f=d|e; | |
| 119 | +const SP7 = [a|z,c|d,b|f,z|z,z|e,b|f,a|f,c|e,c|f,a|z,z|z,b|d,z|d,b|z,c|d,z|f, | |
| 120 | + b|e,a|f,a|d,b|e,b|d,c|z,c|e,a|d,c|z,z|e,z|f,c|f,a|e,z|d,b|z,a|e, | |
| 121 | + b|z,a|e,a|z,b|f,b|f,c|d,c|d,z|d,a|d,b|z,b|e,a|z,c|e,z|f,a|f,c|e, | |
| 122 | + z|f,b|d,c|f,c|z,a|e,z|z,z|d,c|f,z|z,a|f,c|z,z|e,b|d,b|e,z|e,a|d]; | |
| 123 | +a=1<<18; b=1<<28; c=a|b; d=1<<6; e=1<<12; f=d|e; | |
| 124 | +const SP8 = [b|f,z|e,a|z,c|f,b|z,b|f,z|d,b|z,a|d,c|z,c|f,a|e,c|e,a|f,z|e,z|d, | |
| 125 | + c|z,b|d,b|e,z|f,a|e,a|d,c|d,c|e,z|f,z|z,z|z,c|d,b|d,b|e,a|f,a|z, | |
| 126 | + a|f,a|z,c|e,z|e,z|d,c|d,z|e,a|f,b|e,z|d,b|d,c|z,c|d,b|z,a|z,b|f, | |
| 127 | + z|z,c|f,a|d,b|d,c|z,b|e,b|f,z|z,c|f,a|e,a|e,z|f,z|f,a|d,b|z,c|e]; | |
| 128 | + | |
| 129 | +/* eslint-enable comma-spacing */ | |
| 130 | + | |
| 131 | +class DES { | |
| 132 | + constructor(password) { | |
| 133 | + this.keys = []; | |
| 134 | + | |
| 135 | + // Set the key. | |
| 136 | + const pc1m = [], pcr = [], kn = []; | |
| 137 | + | |
| 138 | + for (let j = 0, l = 56; j < 56; ++j, l -= 8) { | |
| 139 | + l += l < -5 ? 65 : l < -3 ? 31 : l < -1 ? 63 : l === 27 ? 35 : 0; // PC1 | |
| 140 | + const m = l & 0x7; | |
| 141 | + pc1m[j] = ((password[l >>> 3] & (1<<m)) !== 0) ? 1: 0; | |
| 142 | + } | |
| 143 | + | |
| 144 | + for (let i = 0; i < 16; ++i) { | |
| 145 | + const m = i << 1; | |
| 146 | + const n = m + 1; | |
| 147 | + kn[m] = kn[n] = 0; | |
| 148 | + for (let o = 28; o < 59; o += 28) { | |
| 149 | + for (let j = o - 28; j < o; ++j) { | |
| 150 | + const l = j + totrot[i]; | |
| 151 | + pcr[j] = l < o ? pc1m[l] : pc1m[l - 28]; | |
| 152 | + } | |
| 153 | + } | |
| 154 | + for (let j = 0; j < 24; ++j) { | |
| 155 | + if (pcr[PC2[j]] !== 0) { | |
| 156 | + kn[m] |= 1 << (23 - j); | |
| 157 | + } | |
| 158 | + if (pcr[PC2[j + 24]] !== 0) { | |
| 159 | + kn[n] |= 1 << (23 - j); | |
| 160 | + } | |
| 161 | + } | |
| 162 | + } | |
| 163 | + | |
| 164 | + // cookey | |
| 165 | + for (let i = 0, rawi = 0, KnLi = 0; i < 16; ++i) { | |
| 166 | + const raw0 = kn[rawi++]; | |
| 167 | + const raw1 = kn[rawi++]; | |
| 168 | + this.keys[KnLi] = (raw0 & 0x00fc0000) << 6; | |
| 169 | + this.keys[KnLi] |= (raw0 & 0x00000fc0) << 10; | |
| 170 | + this.keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10; | |
| 171 | + this.keys[KnLi] |= (raw1 & 0x00000fc0) >>> 6; | |
| 172 | + ++KnLi; | |
| 173 | + this.keys[KnLi] = (raw0 & 0x0003f000) << 12; | |
| 174 | + this.keys[KnLi] |= (raw0 & 0x0000003f) << 16; | |
| 175 | + this.keys[KnLi] |= (raw1 & 0x0003f000) >>> 4; | |
| 176 | + this.keys[KnLi] |= (raw1 & 0x0000003f); | |
| 177 | + ++KnLi; | |
| 178 | + } | |
| 179 | + } | |
| 180 | + | |
| 181 | + // Encrypt 8 bytes of text | |
| 182 | + enc8(text) { | |
| 183 | + const b = text.slice(); | |
| 184 | + let i = 0, l, r, x; // left, right, accumulator | |
| 185 | + | |
| 186 | + // Squash 8 bytes to 2 ints | |
| 187 | + l = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++]; | |
| 188 | + r = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++]; | |
| 189 | + | |
| 190 | + x = ((l >>> 4) ^ r) & 0x0f0f0f0f; | |
| 191 | + r ^= x; | |
| 192 | + l ^= (x << 4); | |
| 193 | + x = ((l >>> 16) ^ r) & 0x0000ffff; | |
| 194 | + r ^= x; | |
| 195 | + l ^= (x << 16); | |
| 196 | + x = ((r >>> 2) ^ l) & 0x33333333; | |
| 197 | + l ^= x; | |
| 198 | + r ^= (x << 2); | |
| 199 | + x = ((r >>> 8) ^ l) & 0x00ff00ff; | |
| 200 | + l ^= x; | |
| 201 | + r ^= (x << 8); | |
| 202 | + r = (r << 1) | ((r >>> 31) & 1); | |
| 203 | + x = (l ^ r) & 0xaaaaaaaa; | |
| 204 | + l ^= x; | |
| 205 | + r ^= x; | |
| 206 | + l = (l << 1) | ((l >>> 31) & 1); | |
| 207 | + | |
| 208 | + for (let i = 0, keysi = 0; i < 8; ++i) { | |
| 209 | + x = (r << 28) | (r >>> 4); | |
| 210 | + x ^= this.keys[keysi++]; | |
| 211 | + let fval = SP7[x & 0x3f]; | |
| 212 | + fval |= SP5[(x >>> 8) & 0x3f]; | |
| 213 | + fval |= SP3[(x >>> 16) & 0x3f]; | |
| 214 | + fval |= SP1[(x >>> 24) & 0x3f]; | |
| 215 | + x = r ^ this.keys[keysi++]; | |
| 216 | + fval |= SP8[x & 0x3f]; | |
| 217 | + fval |= SP6[(x >>> 8) & 0x3f]; | |
| 218 | + fval |= SP4[(x >>> 16) & 0x3f]; | |
| 219 | + fval |= SP2[(x >>> 24) & 0x3f]; | |
| 220 | + l ^= fval; | |
| 221 | + x = (l << 28) | (l >>> 4); | |
| 222 | + x ^= this.keys[keysi++]; | |
| 223 | + fval = SP7[x & 0x3f]; | |
| 224 | + fval |= SP5[(x >>> 8) & 0x3f]; | |
| 225 | + fval |= SP3[(x >>> 16) & 0x3f]; | |
| 226 | + fval |= SP1[(x >>> 24) & 0x3f]; | |
| 227 | + x = l ^ this.keys[keysi++]; | |
| 228 | + fval |= SP8[x & 0x0000003f]; | |
| 229 | + fval |= SP6[(x >>> 8) & 0x3f]; | |
| 230 | + fval |= SP4[(x >>> 16) & 0x3f]; | |
| 231 | + fval |= SP2[(x >>> 24) & 0x3f]; | |
| 232 | + r ^= fval; | |
| 233 | + } | |
| 234 | + | |
| 235 | + r = (r << 31) | (r >>> 1); | |
| 236 | + x = (l ^ r) & 0xaaaaaaaa; | |
| 237 | + l ^= x; | |
| 238 | + r ^= x; | |
| 239 | + l = (l << 31) | (l >>> 1); | |
| 240 | + x = ((l >>> 8) ^ r) & 0x00ff00ff; | |
| 241 | + r ^= x; | |
| 242 | + l ^= (x << 8); | |
| 243 | + x = ((l >>> 2) ^ r) & 0x33333333; | |
| 244 | + r ^= x; | |
| 245 | + l ^= (x << 2); | |
| 246 | + x = ((r >>> 16) ^ l) & 0x0000ffff; | |
| 247 | + l ^= x; | |
| 248 | + r ^= (x << 16); | |
| 249 | + x = ((r >>> 4) ^ l) & 0x0f0f0f0f; | |
| 250 | + l ^= x; | |
| 251 | + r ^= (x << 4); | |
| 252 | + | |
| 253 | + // Spread ints to bytes | |
| 254 | + x = [r, l]; | |
| 255 | + for (i = 0; i < 8; i++) { | |
| 256 | + b[i] = (x[i>>>2] >>> (8 * (3 - (i % 4)))) % 256; | |
| 257 | + if (b[i] < 0) { b[i] += 256; } // unsigned | |
| 258 | + } | |
| 259 | + return b; | |
| 260 | + } | |
| 261 | +} | |
| 262 | + | |
| 263 | +export class DESECBCipher { | |
| 264 | + constructor() { | |
| 265 | + this._cipher = null; | |
| 266 | + } | |
| 267 | + | |
| 268 | + get algorithm() { | |
| 269 | + return { name: "DES-ECB" }; | |
| 270 | + } | |
| 271 | + | |
| 272 | + static importKey(key, _algorithm, _extractable, _keyUsages) { | |
| 273 | + const cipher = new DESECBCipher; | |
| 274 | + cipher._importKey(key); | |
| 275 | + return cipher; | |
| 276 | + } | |
| 277 | + | |
| 278 | + _importKey(key, _extractable, _keyUsages) { | |
| 279 | + this._cipher = new DES(key); | |
| 280 | + } | |
| 281 | + | |
| 282 | + encrypt(_algorithm, plaintext) { | |
| 283 | + const x = new Uint8Array(plaintext); | |
| 284 | + if (x.length % 8 !== 0 || this._cipher === null) { | |
| 285 | + return null; | |
| 286 | + } | |
| 287 | + const n = x.length / 8; | |
| 288 | + for (let i = 0; i < n; i++) { | |
| 289 | + x.set(this._cipher.enc8(x.slice(i * 8, i * 8 + 8)), i * 8); | |
| 290 | + } | |
| 291 | + return x; | |
| 292 | + } | |
| 293 | +} | |
| 294 | + | |
| 295 | +export class DESCBCCipher { | |
| 296 | + constructor() { | |
| 297 | + this._cipher = null; | |
| 298 | + } | |
| 299 | + | |
| 300 | + get algorithm() { | |
| 301 | + return { name: "DES-CBC" }; | |
| 302 | + } | |
| 303 | + | |
| 304 | + static importKey(key, _algorithm, _extractable, _keyUsages) { | |
| 305 | + const cipher = new DESCBCCipher; | |
| 306 | + cipher._importKey(key); | |
| 307 | + return cipher; | |
| 308 | + } | |
| 309 | + | |
| 310 | + _importKey(key) { | |
| 311 | + this._cipher = new DES(key); | |
| 312 | + } | |
| 313 | + | |
| 314 | + encrypt(algorithm, plaintext) { | |
| 315 | + const x = new Uint8Array(plaintext); | |
| 316 | + let y = new Uint8Array(algorithm.iv); | |
| 317 | + if (x.length % 8 !== 0 || this._cipher === null) { | |
| 318 | + return null; | |
| 319 | + } | |
| 320 | + const n = x.length / 8; | |
| 321 | + for (let i = 0; i < n; i++) { | |
| 322 | + for (let j = 0; j < 8; j++) { | |
| 323 | + y[j] ^= plaintext[i * 8 + j]; | |
| 324 | + } | |
| 325 | + y = this._cipher.enc8(y); | |
| 326 | + x.set(y, i * 8); | |
| 327 | + } | |
| 328 | + return x; | |
| 329 | + } | |
| 330 | +} | |
added
public/vendor/novnc/core/crypto/dh.js
+55 −0
@@ -0,0 +1,55 @@ | ||
| 1 | +import { modPow, bigIntToU8Array, u8ArrayToBigInt } from "./bigint.js"; | |
| 2 | + | |
| 3 | +class DHPublicKey { | |
| 4 | + constructor(key) { | |
| 5 | + this._key = key; | |
| 6 | + } | |
| 7 | + | |
| 8 | + get algorithm() { | |
| 9 | + return { name: "DH" }; | |
| 10 | + } | |
| 11 | + | |
| 12 | + exportKey() { | |
| 13 | + return this._key; | |
| 14 | + } | |
| 15 | +} | |
| 16 | + | |
| 17 | +export class DHCipher { | |
| 18 | + constructor() { | |
| 19 | + this._g = null; | |
| 20 | + this._p = null; | |
| 21 | + this._gBigInt = null; | |
| 22 | + this._pBigInt = null; | |
| 23 | + this._privateKey = null; | |
| 24 | + } | |
| 25 | + | |
| 26 | + get algorithm() { | |
| 27 | + return { name: "DH" }; | |
| 28 | + } | |
| 29 | + | |
| 30 | + static generateKey(algorithm, _extractable) { | |
| 31 | + const cipher = new DHCipher; | |
| 32 | + cipher._generateKey(algorithm); | |
| 33 | + return { privateKey: cipher, publicKey: new DHPublicKey(cipher._publicKey) }; | |
| 34 | + } | |
| 35 | + | |
| 36 | + _generateKey(algorithm) { | |
| 37 | + const g = algorithm.g; | |
| 38 | + const p = algorithm.p; | |
| 39 | + this._keyBytes = p.length; | |
| 40 | + this._gBigInt = u8ArrayToBigInt(g); | |
| 41 | + this._pBigInt = u8ArrayToBigInt(p); | |
| 42 | + this._privateKey = window.crypto.getRandomValues(new Uint8Array(this._keyBytes)); | |
| 43 | + this._privateKeyBigInt = u8ArrayToBigInt(this._privateKey); | |
| 44 | + this._publicKey = bigIntToU8Array(modPow( | |
| 45 | + this._gBigInt, this._privateKeyBigInt, this._pBigInt), this._keyBytes); | |
| 46 | + } | |
| 47 | + | |
| 48 | + deriveBits(algorithm, length) { | |
| 49 | + const bytes = Math.ceil(length / 8); | |
| 50 | + const pkey = new Uint8Array(algorithm.public); | |
| 51 | + const len = bytes > this._keyBytes ? bytes : this._keyBytes; | |
| 52 | + const secret = modPow(u8ArrayToBigInt(pkey), this._privateKeyBigInt, this._pBigInt); | |
| 53 | + return bigIntToU8Array(secret, len).slice(0, len); | |
| 54 | + } | |
| 55 | +} | |
added
public/vendor/novnc/core/crypto/md5.js
+82 −0
@@ -0,0 +1,82 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2021 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * Performs MD5 hashing on an array of bytes, returns an array of bytes | |
| 11 | + */ | |
| 12 | + | |
| 13 | +export async function MD5(d) { | |
| 14 | + let s = ""; | |
| 15 | + for (let i = 0; i < d.length; i++) { | |
| 16 | + s += String.fromCharCode(d[i]); | |
| 17 | + } | |
| 18 | + return M(V(Y(X(s), 8 * s.length))); | |
| 19 | +} | |
| 20 | + | |
| 21 | +function M(d) { | |
| 22 | + let f = new Uint8Array(d.length); | |
| 23 | + for (let i=0;i<d.length;i++) { | |
| 24 | + f[i] = d.charCodeAt(i); | |
| 25 | + } | |
| 26 | + return f; | |
| 27 | +} | |
| 28 | + | |
| 29 | +function X(d) { | |
| 30 | + let r = Array(d.length >> 2); | |
| 31 | + for (let m = 0; m < r.length; m++) r[m] = 0; | |
| 32 | + for (let m = 0; m < 8 * d.length; m += 8) r[m >> 5] |= (255 & d.charCodeAt(m / 8)) << m % 32; | |
| 33 | + return r; | |
| 34 | +} | |
| 35 | + | |
| 36 | +function V(d) { | |
| 37 | + let r = ""; | |
| 38 | + for (let m = 0; m < 32 * d.length; m += 8) r += String.fromCharCode(d[m >> 5] >>> m % 32 & 255); | |
| 39 | + return r; | |
| 40 | +} | |
| 41 | + | |
| 42 | +function Y(d, g) { | |
| 43 | + d[g >> 5] |= 128 << g % 32, d[14 + (g + 64 >>> 9 << 4)] = g; | |
| 44 | + let m = 1732584193, f = -271733879, r = -1732584194, i = 271733878; | |
| 45 | + for (let n = 0; n < d.length; n += 16) { | |
| 46 | + let h = m, | |
| 47 | + t = f, | |
| 48 | + g = r, | |
| 49 | + e = i; | |
| 50 | + f = ii(f = ii(f = ii(f = ii(f = hh(f = hh(f = hh(f = hh(f = gg(f = gg(f = gg(f = gg(f = ff(f = ff(f = ff(f = ff(f, r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 0], 7, -680876936), f, r, d[n + 1], 12, -389564586), m, f, d[n + 2], 17, 606105819), i, m, d[n + 3], 22, -1044525330), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 4], 7, -176418897), f, r, d[n + 5], 12, 1200080426), m, f, d[n + 6], 17, -1473231341), i, m, d[n + 7], 22, -45705983), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 8], 7, 1770035416), f, r, d[n + 9], 12, -1958414417), m, f, d[n + 10], 17, -42063), i, m, d[n + 11], 22, -1990404162), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 12], 7, 1804603682), f, r, d[n + 13], 12, -40341101), m, f, d[n + 14], 17, -1502002290), i, m, d[n + 15], 22, 1236535329), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 1], 5, -165796510), f, r, d[n + 6], 9, -1069501632), m, f, d[n + 11], 14, 643717713), i, m, d[n + 0], 20, -373897302), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 5], 5, -701558691), f, r, d[n + 10], 9, 38016083), m, f, d[n + 15], 14, -660478335), i, m, d[n + 4], 20, -405537848), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 9], 5, 568446438), f, r, d[n + 14], 9, -1019803690), m, f, d[n + 3], 14, -187363961), i, m, d[n + 8], 20, 1163531501), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 13], 5, -1444681467), f, r, d[n + 2], 9, -51403784), m, f, d[n + 7], 14, 1735328473), i, m, d[n + 12], 20, -1926607734), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 5], 4, -378558), f, r, d[n + 8], 11, -2022574463), m, f, d[n + 11], 16, 1839030562), i, m, d[n + 14], 23, -35309556), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 1], 4, -1530992060), f, r, d[n + 4], 11, 1272893353), m, f, d[n + 7], 16, -155497632), i, m, d[n + 10], 23, -1094730640), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 13], 4, 681279174), f, r, d[n + 0], 11, -358537222), m, f, d[n + 3], 16, -722521979), i, m, d[n + 6], 23, 76029189), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 9], 4, -640364487), f, r, d[n + 12], 11, -421815835), m, f, d[n + 15], 16, 530742520), i, m, d[n + 2], 23, -995338651), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 0], 6, -198630844), f, r, d[n + 7], 10, 1126891415), m, f, d[n + 14], 15, -1416354905), i, m, d[n + 5], 21, -57434055), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 12], 6, 1700485571), f, r, d[n + 3], 10, -1894986606), m, f, d[n + 10], 15, -1051523), i, m, d[n + 1], 21, -2054922799), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 8], 6, 1873313359), f, r, d[n + 15], 10, -30611744), m, f, d[n + 6], 15, -1560198380), i, m, d[n + 13], 21, 1309151649), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 4], 6, -145523070), f, r, d[n + 11], 10, -1120210379), m, f, d[n + 2], 15, 718787259), i, m, d[n + 9], 21, -343485551), m = add(m, h), f = add(f, t), r = add(r, g), i = add(i, e); | |
| 51 | + } | |
| 52 | + return Array(m, f, r, i); | |
| 53 | +} | |
| 54 | + | |
| 55 | +function cmn(d, g, m, f, r, i) { | |
| 56 | + return add(rol(add(add(g, d), add(f, i)), r), m); | |
| 57 | +} | |
| 58 | + | |
| 59 | +function ff(d, g, m, f, r, i, n) { | |
| 60 | + return cmn(g & m | ~g & f, d, g, r, i, n); | |
| 61 | +} | |
| 62 | + | |
| 63 | +function gg(d, g, m, f, r, i, n) { | |
| 64 | + return cmn(g & f | m & ~f, d, g, r, i, n); | |
| 65 | +} | |
| 66 | + | |
| 67 | +function hh(d, g, m, f, r, i, n) { | |
| 68 | + return cmn(g ^ m ^ f, d, g, r, i, n); | |
| 69 | +} | |
| 70 | + | |
| 71 | +function ii(d, g, m, f, r, i, n) { | |
| 72 | + return cmn(m ^ (g | ~f), d, g, r, i, n); | |
| 73 | +} | |
| 74 | + | |
| 75 | +function add(d, g) { | |
| 76 | + let m = (65535 & d) + (65535 & g); | |
| 77 | + return (d >> 16) + (g >> 16) + (m >> 16) << 16 | 65535 & m; | |
| 78 | +} | |
| 79 | + | |
| 80 | +function rol(d, g) { | |
| 81 | + return d << g | d >>> 32 - g; | |
| 82 | +} | |
added
public/vendor/novnc/core/crypto/rsa.js
+132 −0
@@ -0,0 +1,132 @@ | ||
| 1 | +import Base64 from "../base64.js"; | |
| 2 | +import { modPow, bigIntToU8Array, u8ArrayToBigInt } from "./bigint.js"; | |
| 3 | + | |
| 4 | +export class RSACipher { | |
| 5 | + constructor() { | |
| 6 | + this._keyLength = 0; | |
| 7 | + this._keyBytes = 0; | |
| 8 | + this._n = null; | |
| 9 | + this._e = null; | |
| 10 | + this._d = null; | |
| 11 | + this._nBigInt = null; | |
| 12 | + this._eBigInt = null; | |
| 13 | + this._dBigInt = null; | |
| 14 | + this._extractable = false; | |
| 15 | + } | |
| 16 | + | |
| 17 | + get algorithm() { | |
| 18 | + return { name: "RSA-PKCS1-v1_5" }; | |
| 19 | + } | |
| 20 | + | |
| 21 | + _base64urlDecode(data) { | |
| 22 | + data = data.replace(/-/g, "+").replace(/_/g, "/"); | |
| 23 | + data = data.padEnd(Math.ceil(data.length / 4) * 4, "="); | |
| 24 | + return Base64.decode(data); | |
| 25 | + } | |
| 26 | + | |
| 27 | + _padArray(arr, length) { | |
| 28 | + const res = new Uint8Array(length); | |
| 29 | + res.set(arr, length - arr.length); | |
| 30 | + return res; | |
| 31 | + } | |
| 32 | + | |
| 33 | + static async generateKey(algorithm, extractable, _keyUsages) { | |
| 34 | + const cipher = new RSACipher; | |
| 35 | + await cipher._generateKey(algorithm, extractable); | |
| 36 | + return { privateKey: cipher }; | |
| 37 | + } | |
| 38 | + | |
| 39 | + async _generateKey(algorithm, extractable) { | |
| 40 | + this._keyLength = algorithm.modulusLength; | |
| 41 | + this._keyBytes = Math.ceil(this._keyLength / 8); | |
| 42 | + const key = await window.crypto.subtle.generateKey( | |
| 43 | + { | |
| 44 | + name: "RSA-OAEP", | |
| 45 | + modulusLength: algorithm.modulusLength, | |
| 46 | + publicExponent: algorithm.publicExponent, | |
| 47 | + hash: {name: "SHA-256"}, | |
| 48 | + }, | |
| 49 | + true, ["encrypt", "decrypt"]); | |
| 50 | + const privateKey = await window.crypto.subtle.exportKey("jwk", key.privateKey); | |
| 51 | + this._n = this._padArray(this._base64urlDecode(privateKey.n), this._keyBytes); | |
| 52 | + this._nBigInt = u8ArrayToBigInt(this._n); | |
| 53 | + this._e = this._padArray(this._base64urlDecode(privateKey.e), this._keyBytes); | |
| 54 | + this._eBigInt = u8ArrayToBigInt(this._e); | |
| 55 | + this._d = this._padArray(this._base64urlDecode(privateKey.d), this._keyBytes); | |
| 56 | + this._dBigInt = u8ArrayToBigInt(this._d); | |
| 57 | + this._extractable = extractable; | |
| 58 | + } | |
| 59 | + | |
| 60 | + static async importKey(key, _algorithm, extractable, keyUsages) { | |
| 61 | + if (keyUsages.length !== 1 || keyUsages[0] !== "encrypt") { | |
| 62 | + throw new Error("only support importing RSA public key"); | |
| 63 | + } | |
| 64 | + const cipher = new RSACipher; | |
| 65 | + await cipher._importKey(key, extractable); | |
| 66 | + return cipher; | |
| 67 | + } | |
| 68 | + | |
| 69 | + async _importKey(key, extractable) { | |
| 70 | + const n = key.n; | |
| 71 | + const e = key.e; | |
| 72 | + if (n.length !== e.length) { | |
| 73 | + throw new Error("the sizes of modulus and public exponent do not match"); | |
| 74 | + } | |
| 75 | + this._keyBytes = n.length; | |
| 76 | + this._keyLength = this._keyBytes * 8; | |
| 77 | + this._n = new Uint8Array(this._keyBytes); | |
| 78 | + this._e = new Uint8Array(this._keyBytes); | |
| 79 | + this._n.set(n); | |
| 80 | + this._e.set(e); | |
| 81 | + this._nBigInt = u8ArrayToBigInt(this._n); | |
| 82 | + this._eBigInt = u8ArrayToBigInt(this._e); | |
| 83 | + this._extractable = extractable; | |
| 84 | + } | |
| 85 | + | |
| 86 | + async encrypt(_algorithm, message) { | |
| 87 | + if (message.length > this._keyBytes - 11) { | |
| 88 | + return null; | |
| 89 | + } | |
| 90 | + const ps = new Uint8Array(this._keyBytes - message.length - 3); | |
| 91 | + window.crypto.getRandomValues(ps); | |
| 92 | + for (let i = 0; i < ps.length; i++) { | |
| 93 | + ps[i] = Math.floor(ps[i] * 254 / 255 + 1); | |
| 94 | + } | |
| 95 | + const em = new Uint8Array(this._keyBytes); | |
| 96 | + em[1] = 0x02; | |
| 97 | + em.set(ps, 2); | |
| 98 | + em.set(message, ps.length + 3); | |
| 99 | + const emBigInt = u8ArrayToBigInt(em); | |
| 100 | + const c = modPow(emBigInt, this._eBigInt, this._nBigInt); | |
| 101 | + return bigIntToU8Array(c, this._keyBytes); | |
| 102 | + } | |
| 103 | + | |
| 104 | + async decrypt(_algorithm, message) { | |
| 105 | + if (message.length !== this._keyBytes) { | |
| 106 | + return null; | |
| 107 | + } | |
| 108 | + const msgBigInt = u8ArrayToBigInt(message); | |
| 109 | + const emBigInt = modPow(msgBigInt, this._dBigInt, this._nBigInt); | |
| 110 | + const em = bigIntToU8Array(emBigInt, this._keyBytes); | |
| 111 | + if (em[0] !== 0x00 || em[1] !== 0x02) { | |
| 112 | + return null; | |
| 113 | + } | |
| 114 | + let i = 2; | |
| 115 | + for (; i < em.length; i++) { | |
| 116 | + if (em[i] === 0x00) { | |
| 117 | + break; | |
| 118 | + } | |
| 119 | + } | |
| 120 | + if (i === em.length) { | |
| 121 | + return null; | |
| 122 | + } | |
| 123 | + return em.slice(i + 1, em.length); | |
| 124 | + } | |
| 125 | + | |
| 126 | + async exportKey() { | |
| 127 | + if (!this._extractable) { | |
| 128 | + throw new Error("key is not extractable"); | |
| 129 | + } | |
| 130 | + return { n: this._n, e: this._e, d: this._d }; | |
| 131 | + } | |
| 132 | +} | |
added
public/vendor/novnc/core/decoders/copyrect.js
+27 −0
@@ -0,0 +1,27 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +export default class CopyRectDecoder { | |
| 11 | + decodeRect(x, y, width, height, sock, display, depth) { | |
| 12 | + if (sock.rQwait("COPYRECT", 4)) { | |
| 13 | + return false; | |
| 14 | + } | |
| 15 | + | |
| 16 | + let deltaX = sock.rQshift16(); | |
| 17 | + let deltaY = sock.rQshift16(); | |
| 18 | + | |
| 19 | + if ((width === 0) || (height === 0)) { | |
| 20 | + return true; | |
| 21 | + } | |
| 22 | + | |
| 23 | + display.copyImage(deltaX, deltaY, x, y, width, height); | |
| 24 | + | |
| 25 | + return true; | |
| 26 | + } | |
| 27 | +} | |
added
public/vendor/novnc/core/decoders/h264.js
+321 −0
@@ -0,0 +1,321 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2024 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +import * as Log from '../util/logging.js'; | |
| 11 | + | |
| 12 | +export class H264Parser { | |
| 13 | + constructor(data) { | |
| 14 | + this._data = data; | |
| 15 | + this._index = 0; | |
| 16 | + this.profileIdc = null; | |
| 17 | + this.constraintSet = null; | |
| 18 | + this.levelIdc = null; | |
| 19 | + } | |
| 20 | + | |
| 21 | + _getStartSequenceLen(index) { | |
| 22 | + let data = this._data; | |
| 23 | + if (data[index + 0] == 0 && data[index + 1] == 0 && data[index + 2] == 0 && data[index + 3] == 1) { | |
| 24 | + return 4; | |
| 25 | + } | |
| 26 | + if (data[index + 0] == 0 && data[index + 1] == 0 && data[index + 2] == 1) { | |
| 27 | + return 3; | |
| 28 | + } | |
| 29 | + return 0; | |
| 30 | + } | |
| 31 | + | |
| 32 | + _indexOfNextNalUnit(index) { | |
| 33 | + let data = this._data; | |
| 34 | + for (let i = index; i < data.length; ++i) { | |
| 35 | + if (this._getStartSequenceLen(i) != 0) { | |
| 36 | + return i; | |
| 37 | + } | |
| 38 | + } | |
| 39 | + return -1; | |
| 40 | + } | |
| 41 | + | |
| 42 | + _parseSps(index) { | |
| 43 | + this.profileIdc = this._data[index]; | |
| 44 | + this.constraintSet = this._data[index + 1]; | |
| 45 | + this.levelIdc = this._data[index + 2]; | |
| 46 | + } | |
| 47 | + | |
| 48 | + _parseNalUnit(index) { | |
| 49 | + const firstByte = this._data[index]; | |
| 50 | + if (firstByte & 0x80) { | |
| 51 | + throw new Error('H264 parsing sanity check failed, forbidden zero bit is set'); | |
| 52 | + } | |
| 53 | + const unitType = firstByte & 0x1f; | |
| 54 | + | |
| 55 | + switch (unitType) { | |
| 56 | + case 1: // coded slice, non-idr | |
| 57 | + return { slice: true }; | |
| 58 | + case 5: // coded slice, idr | |
| 59 | + return { slice: true, key: true }; | |
| 60 | + case 6: // sei | |
| 61 | + return {}; | |
| 62 | + case 7: // sps | |
| 63 | + this._parseSps(index + 1); | |
| 64 | + return {}; | |
| 65 | + case 8: // pps | |
| 66 | + return {}; | |
| 67 | + default: | |
| 68 | + Log.Warn("Unhandled unit type: ", unitType); | |
| 69 | + break; | |
| 70 | + } | |
| 71 | + return {}; | |
| 72 | + } | |
| 73 | + | |
| 74 | + parse() { | |
| 75 | + const startIndex = this._index; | |
| 76 | + let isKey = false; | |
| 77 | + | |
| 78 | + while (this._index < this._data.length) { | |
| 79 | + const startSequenceLen = this._getStartSequenceLen(this._index); | |
| 80 | + if (startSequenceLen == 0) { | |
| 81 | + throw new Error('Invalid start sequence in bit stream'); | |
| 82 | + } | |
| 83 | + | |
| 84 | + const { slice, key } = this._parseNalUnit(this._index + startSequenceLen); | |
| 85 | + | |
| 86 | + let nextIndex = this._indexOfNextNalUnit(this._index + startSequenceLen); | |
| 87 | + if (nextIndex == -1) { | |
| 88 | + this._index = this._data.length; | |
| 89 | + } else { | |
| 90 | + this._index = nextIndex; | |
| 91 | + } | |
| 92 | + | |
| 93 | + if (key) { | |
| 94 | + isKey = true; | |
| 95 | + } | |
| 96 | + if (slice) { | |
| 97 | + break; | |
| 98 | + } | |
| 99 | + } | |
| 100 | + | |
| 101 | + if (startIndex === this._index) { | |
| 102 | + return null; | |
| 103 | + } | |
| 104 | + | |
| 105 | + return { | |
| 106 | + frame: this._data.subarray(startIndex, this._index), | |
| 107 | + key: isKey, | |
| 108 | + }; | |
| 109 | + } | |
| 110 | +} | |
| 111 | + | |
| 112 | +export class H264Context { | |
| 113 | + constructor(width, height) { | |
| 114 | + this.lastUsed = 0; | |
| 115 | + this._width = width; | |
| 116 | + this._height = height; | |
| 117 | + this._profileIdc = null; | |
| 118 | + this._constraintSet = null; | |
| 119 | + this._levelIdc = null; | |
| 120 | + this._decoder = null; | |
| 121 | + this._pendingFrames = []; | |
| 122 | + } | |
| 123 | + | |
| 124 | + _handleFrame(frame) { | |
| 125 | + let pending = this._pendingFrames.shift(); | |
| 126 | + if (pending === undefined) { | |
| 127 | + throw new Error("Pending frame queue empty when receiving frame from decoder"); | |
| 128 | + } | |
| 129 | + | |
| 130 | + if (pending.timestamp != frame.timestamp) { | |
| 131 | + throw new Error("Video frame timestamp mismatch. Expected " + | |
| 132 | + frame.timestamp + " but but got " + pending.timestamp); | |
| 133 | + } | |
| 134 | + | |
| 135 | + pending.frame = frame; | |
| 136 | + pending.ready = true; | |
| 137 | + pending.resolve(); | |
| 138 | + | |
| 139 | + if (!pending.keep) { | |
| 140 | + frame.close(); | |
| 141 | + } | |
| 142 | + } | |
| 143 | + | |
| 144 | + _handleError(e) { | |
| 145 | + throw new Error("Failed to decode frame: " + e.message); | |
| 146 | + } | |
| 147 | + | |
| 148 | + _configureDecoder(profileIdc, constraintSet, levelIdc) { | |
| 149 | + if (this._decoder === null || this._decoder.state === 'closed') { | |
| 150 | + this._decoder = new VideoDecoder({ | |
| 151 | + output: frame => this._handleFrame(frame), | |
| 152 | + error: e => this._handleError(e), | |
| 153 | + }); | |
| 154 | + } | |
| 155 | + const codec = 'avc1.' + | |
| 156 | + profileIdc.toString(16).padStart(2, '0') + | |
| 157 | + constraintSet.toString(16).padStart(2, '0') + | |
| 158 | + levelIdc.toString(16).padStart(2, '0'); | |
| 159 | + this._decoder.configure({ | |
| 160 | + codec: codec, | |
| 161 | + codedWidth: this._width, | |
| 162 | + codedHeight: this._height, | |
| 163 | + optimizeForLatency: true, | |
| 164 | + }); | |
| 165 | + } | |
| 166 | + | |
| 167 | + _preparePendingFrame(timestamp) { | |
| 168 | + let pending = { | |
| 169 | + timestamp: timestamp, | |
| 170 | + promise: null, | |
| 171 | + resolve: null, | |
| 172 | + frame: null, | |
| 173 | + ready: false, | |
| 174 | + keep: false, | |
| 175 | + }; | |
| 176 | + pending.promise = new Promise((resolve) => { | |
| 177 | + pending.resolve = resolve; | |
| 178 | + }); | |
| 179 | + this._pendingFrames.push(pending); | |
| 180 | + | |
| 181 | + return pending; | |
| 182 | + } | |
| 183 | + | |
| 184 | + decode(payload) { | |
| 185 | + let parser = new H264Parser(payload); | |
| 186 | + let result = null; | |
| 187 | + | |
| 188 | + // Ideally, this timestamp should come from the server, but we'll just | |
| 189 | + // approximate it instead. | |
| 190 | + let timestamp = Math.round(window.performance.now() * 1e3); | |
| 191 | + | |
| 192 | + while (true) { | |
| 193 | + let encodedFrame = parser.parse(); | |
| 194 | + if (encodedFrame === null) { | |
| 195 | + break; | |
| 196 | + } | |
| 197 | + | |
| 198 | + if (parser.profileIdc !== null) { | |
| 199 | + self._profileIdc = parser.profileIdc; | |
| 200 | + self._constraintSet = parser.constraintSet; | |
| 201 | + self._levelIdc = parser.levelIdc; | |
| 202 | + } | |
| 203 | + | |
| 204 | + if (this._decoder === null || this._decoder.state !== 'configured') { | |
| 205 | + if (!encodedFrame.key) { | |
| 206 | + Log.Warn("Missing key frame. Can't decode until one arrives"); | |
| 207 | + continue; | |
| 208 | + } | |
| 209 | + if (self._profileIdc === null) { | |
| 210 | + Log.Warn('Cannot config decoder. Have not received SPS and PPS yet.'); | |
| 211 | + continue; | |
| 212 | + } | |
| 213 | + this._configureDecoder(self._profileIdc, self._constraintSet, | |
| 214 | + self._levelIdc); | |
| 215 | + } | |
| 216 | + | |
| 217 | + result = this._preparePendingFrame(timestamp); | |
| 218 | + | |
| 219 | + const chunk = new EncodedVideoChunk({ | |
| 220 | + timestamp: timestamp, | |
| 221 | + type: encodedFrame.key ? 'key' : 'delta', | |
| 222 | + data: encodedFrame.frame, | |
| 223 | + }); | |
| 224 | + | |
| 225 | + try { | |
| 226 | + this._decoder.decode(chunk); | |
| 227 | + } catch (e) { | |
| 228 | + Log.Warn("Failed to decode:", e); | |
| 229 | + } | |
| 230 | + } | |
| 231 | + | |
| 232 | + // We only keep last frame of each payload | |
| 233 | + if (result !== null) { | |
| 234 | + result.keep = true; | |
| 235 | + } | |
| 236 | + | |
| 237 | + return result; | |
| 238 | + } | |
| 239 | +} | |
| 240 | + | |
| 241 | +export default class H264Decoder { | |
| 242 | + constructor() { | |
| 243 | + this._tick = 0; | |
| 244 | + this._contexts = {}; | |
| 245 | + } | |
| 246 | + | |
| 247 | + _contextId(x, y, width, height) { | |
| 248 | + return [x, y, width, height].join(','); | |
| 249 | + } | |
| 250 | + | |
| 251 | + _findOldestContextId() { | |
| 252 | + let oldestTick = Number.MAX_VALUE; | |
| 253 | + let oldestKey = undefined; | |
| 254 | + for (const [key, value] of Object.entries(this._contexts)) { | |
| 255 | + if (value.lastUsed < oldestTick) { | |
| 256 | + oldestTick = value.lastUsed; | |
| 257 | + oldestKey = key; | |
| 258 | + } | |
| 259 | + } | |
| 260 | + return oldestKey; | |
| 261 | + } | |
| 262 | + | |
| 263 | + _createContext(x, y, width, height) { | |
| 264 | + const maxContexts = 64; | |
| 265 | + if (Object.keys(this._contexts).length >= maxContexts) { | |
| 266 | + let oldestContextId = this._findOldestContextId(); | |
| 267 | + delete this._contexts[oldestContextId]; | |
| 268 | + } | |
| 269 | + let context = new H264Context(width, height); | |
| 270 | + this._contexts[this._contextId(x, y, width, height)] = context; | |
| 271 | + return context; | |
| 272 | + } | |
| 273 | + | |
| 274 | + _getContext(x, y, width, height) { | |
| 275 | + let context = this._contexts[this._contextId(x, y, width, height)]; | |
| 276 | + return context !== undefined ? context : this._createContext(x, y, width, height); | |
| 277 | + } | |
| 278 | + | |
| 279 | + _resetContext(x, y, width, height) { | |
| 280 | + delete this._contexts[this._contextId(x, y, width, height)]; | |
| 281 | + } | |
| 282 | + | |
| 283 | + _resetAllContexts() { | |
| 284 | + this._contexts = {}; | |
| 285 | + } | |
| 286 | + | |
| 287 | + decodeRect(x, y, width, height, sock, display, depth) { | |
| 288 | + const resetContextFlag = 1; | |
| 289 | + const resetAllContextsFlag = 2; | |
| 290 | + | |
| 291 | + if (sock.rQwait("h264 header", 8)) { | |
| 292 | + return false; | |
| 293 | + } | |
| 294 | + | |
| 295 | + const length = sock.rQshift32(); | |
| 296 | + const flags = sock.rQshift32(); | |
| 297 | + | |
| 298 | + if (sock.rQwait("h264 payload", length, 8)) { | |
| 299 | + return false; | |
| 300 | + } | |
| 301 | + | |
| 302 | + if (flags & resetAllContextsFlag) { | |
| 303 | + this._resetAllContexts(); | |
| 304 | + } else if (flags & resetContextFlag) { | |
| 305 | + this._resetContext(x, y, width, height); | |
| 306 | + } | |
| 307 | + | |
| 308 | + let context = this._getContext(x, y, width, height); | |
| 309 | + context.lastUsed = this._tick++; | |
| 310 | + | |
| 311 | + if (length !== 0) { | |
| 312 | + let payload = sock.rQshiftBytes(length, false); | |
| 313 | + let frame = context.decode(payload); | |
| 314 | + if (frame !== null) { | |
| 315 | + display.videoFrame(x, y, width, height, frame); | |
| 316 | + } | |
| 317 | + } | |
| 318 | + | |
| 319 | + return true; | |
| 320 | + } | |
| 321 | +} | |
added
public/vendor/novnc/core/decoders/hextile.js
+181 −0
@@ -0,0 +1,181 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +import * as Log from '../util/logging.js'; | |
| 11 | + | |
| 12 | +export default class HextileDecoder { | |
| 13 | + constructor() { | |
| 14 | + this._tiles = 0; | |
| 15 | + this._lastsubencoding = 0; | |
| 16 | + this._tileBuffer = new Uint8Array(16 * 16 * 4); | |
| 17 | + } | |
| 18 | + | |
| 19 | + decodeRect(x, y, width, height, sock, display, depth) { | |
| 20 | + if (this._tiles === 0) { | |
| 21 | + this._tilesX = Math.ceil(width / 16); | |
| 22 | + this._tilesY = Math.ceil(height / 16); | |
| 23 | + this._totalTiles = this._tilesX * this._tilesY; | |
| 24 | + this._tiles = this._totalTiles; | |
| 25 | + } | |
| 26 | + | |
| 27 | + while (this._tiles > 0) { | |
| 28 | + let bytes = 1; | |
| 29 | + | |
| 30 | + if (sock.rQwait("HEXTILE", bytes)) { | |
| 31 | + return false; | |
| 32 | + } | |
| 33 | + | |
| 34 | + let subencoding = sock.rQpeek8(); | |
| 35 | + if (subencoding > 30) { // Raw | |
| 36 | + throw new Error("Illegal hextile subencoding (subencoding: " + | |
| 37 | + subencoding + ")"); | |
| 38 | + } | |
| 39 | + | |
| 40 | + const currTile = this._totalTiles - this._tiles; | |
| 41 | + const tileX = currTile % this._tilesX; | |
| 42 | + const tileY = Math.floor(currTile / this._tilesX); | |
| 43 | + const tx = x + tileX * 16; | |
| 44 | + const ty = y + tileY * 16; | |
| 45 | + const tw = Math.min(16, (x + width) - tx); | |
| 46 | + const th = Math.min(16, (y + height) - ty); | |
| 47 | + | |
| 48 | + // Figure out how much we are expecting | |
| 49 | + if (subencoding & 0x01) { // Raw | |
| 50 | + bytes += tw * th * 4; | |
| 51 | + } else { | |
| 52 | + if (subencoding & 0x02) { // Background | |
| 53 | + bytes += 4; | |
| 54 | + } | |
| 55 | + if (subencoding & 0x04) { // Foreground | |
| 56 | + bytes += 4; | |
| 57 | + } | |
| 58 | + if (subencoding & 0x08) { // AnySubrects | |
| 59 | + bytes++; // Since we aren't shifting it off | |
| 60 | + | |
| 61 | + if (sock.rQwait("HEXTILE", bytes)) { | |
| 62 | + return false; | |
| 63 | + } | |
| 64 | + | |
| 65 | + let subrects = sock.rQpeekBytes(bytes).at(-1); | |
| 66 | + if (subencoding & 0x10) { // SubrectsColoured | |
| 67 | + bytes += subrects * (4 + 2); | |
| 68 | + } else { | |
| 69 | + bytes += subrects * 2; | |
| 70 | + } | |
| 71 | + } | |
| 72 | + } | |
| 73 | + | |
| 74 | + if (sock.rQwait("HEXTILE", bytes)) { | |
| 75 | + return false; | |
| 76 | + } | |
| 77 | + | |
| 78 | + // We know the encoding and have a whole tile | |
| 79 | + sock.rQshift8(); | |
| 80 | + if (subencoding === 0) { | |
| 81 | + if (this._lastsubencoding & 0x01) { | |
| 82 | + // Weird: ignore blanks are RAW | |
| 83 | + Log.Debug(" Ignoring blank after RAW"); | |
| 84 | + } else { | |
| 85 | + display.fillRect(tx, ty, tw, th, this._background); | |
| 86 | + } | |
| 87 | + } else if (subencoding & 0x01) { // Raw | |
| 88 | + let pixels = tw * th; | |
| 89 | + let data = sock.rQshiftBytes(pixels * 4, false); | |
| 90 | + // Max sure the image is fully opaque | |
| 91 | + for (let i = 0;i < pixels;i++) { | |
| 92 | + data[i * 4 + 3] = 255; | |
| 93 | + } | |
| 94 | + display.blitImage(tx, ty, tw, th, data, 0); | |
| 95 | + } else { | |
| 96 | + if (subencoding & 0x02) { // Background | |
| 97 | + this._background = new Uint8Array(sock.rQshiftBytes(4)); | |
| 98 | + } | |
| 99 | + if (subencoding & 0x04) { // Foreground | |
| 100 | + this._foreground = new Uint8Array(sock.rQshiftBytes(4)); | |
| 101 | + } | |
| 102 | + | |
| 103 | + this._startTile(tx, ty, tw, th, this._background); | |
| 104 | + if (subencoding & 0x08) { // AnySubrects | |
| 105 | + let subrects = sock.rQshift8(); | |
| 106 | + | |
| 107 | + for (let s = 0; s < subrects; s++) { | |
| 108 | + let color; | |
| 109 | + if (subencoding & 0x10) { // SubrectsColoured | |
| 110 | + color = sock.rQshiftBytes(4); | |
| 111 | + } else { | |
| 112 | + color = this._foreground; | |
| 113 | + } | |
| 114 | + const xy = sock.rQshift8(); | |
| 115 | + const sx = (xy >> 4); | |
| 116 | + const sy = (xy & 0x0f); | |
| 117 | + | |
| 118 | + const wh = sock.rQshift8(); | |
| 119 | + const sw = (wh >> 4) + 1; | |
| 120 | + const sh = (wh & 0x0f) + 1; | |
| 121 | + | |
| 122 | + this._subTile(sx, sy, sw, sh, color); | |
| 123 | + } | |
| 124 | + } | |
| 125 | + this._finishTile(display); | |
| 126 | + } | |
| 127 | + this._lastsubencoding = subencoding; | |
| 128 | + this._tiles--; | |
| 129 | + } | |
| 130 | + | |
| 131 | + return true; | |
| 132 | + } | |
| 133 | + | |
| 134 | + // start updating a tile | |
| 135 | + _startTile(x, y, width, height, color) { | |
| 136 | + this._tileX = x; | |
| 137 | + this._tileY = y; | |
| 138 | + this._tileW = width; | |
| 139 | + this._tileH = height; | |
| 140 | + | |
| 141 | + const red = color[0]; | |
| 142 | + const green = color[1]; | |
| 143 | + const blue = color[2]; | |
| 144 | + | |
| 145 | + const data = this._tileBuffer; | |
| 146 | + for (let i = 0; i < width * height * 4; i += 4) { | |
| 147 | + data[i] = red; | |
| 148 | + data[i + 1] = green; | |
| 149 | + data[i + 2] = blue; | |
| 150 | + data[i + 3] = 255; | |
| 151 | + } | |
| 152 | + } | |
| 153 | + | |
| 154 | + // update sub-rectangle of the current tile | |
| 155 | + _subTile(x, y, w, h, color) { | |
| 156 | + const red = color[0]; | |
| 157 | + const green = color[1]; | |
| 158 | + const blue = color[2]; | |
| 159 | + const xend = x + w; | |
| 160 | + const yend = y + h; | |
| 161 | + | |
| 162 | + const data = this._tileBuffer; | |
| 163 | + const width = this._tileW; | |
| 164 | + for (let j = y; j < yend; j++) { | |
| 165 | + for (let i = x; i < xend; i++) { | |
| 166 | + const p = (i + (j * width)) * 4; | |
| 167 | + data[p] = red; | |
| 168 | + data[p + 1] = green; | |
| 169 | + data[p + 2] = blue; | |
| 170 | + data[p + 3] = 255; | |
| 171 | + } | |
| 172 | + } | |
| 173 | + } | |
| 174 | + | |
| 175 | + // draw the current tile to the screen | |
| 176 | + _finishTile(display) { | |
| 177 | + display.blitImage(this._tileX, this._tileY, | |
| 178 | + this._tileW, this._tileH, | |
| 179 | + this._tileBuffer, 0); | |
| 180 | + } | |
| 181 | +} | |
added
public/vendor/novnc/core/decoders/jpeg.js
+146 −0
@@ -0,0 +1,146 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +export default class JPEGDecoder { | |
| 11 | + constructor() { | |
| 12 | + // RealVNC will reuse the quantization tables | |
| 13 | + // and Huffman tables, so we need to cache them. | |
| 14 | + this._cachedQuantTables = []; | |
| 15 | + this._cachedHuffmanTables = []; | |
| 16 | + | |
| 17 | + this._segments = []; | |
| 18 | + } | |
| 19 | + | |
| 20 | + decodeRect(x, y, width, height, sock, display, depth) { | |
| 21 | + // A rect of JPEG encodings is simply a JPEG file | |
| 22 | + while (true) { | |
| 23 | + let segment = this._readSegment(sock); | |
| 24 | + if (segment === null) { | |
| 25 | + return false; | |
| 26 | + } | |
| 27 | + this._segments.push(segment); | |
| 28 | + // End of image? | |
| 29 | + if (segment[1] === 0xD9) { | |
| 30 | + break; | |
| 31 | + } | |
| 32 | + } | |
| 33 | + | |
| 34 | + let huffmanTables = []; | |
| 35 | + let quantTables = []; | |
| 36 | + for (let segment of this._segments) { | |
| 37 | + let type = segment[1]; | |
| 38 | + if (type === 0xC4) { | |
| 39 | + // Huffman tables | |
| 40 | + huffmanTables.push(segment); | |
| 41 | + } else if (type === 0xDB) { | |
| 42 | + // Quantization tables | |
| 43 | + quantTables.push(segment); | |
| 44 | + } | |
| 45 | + } | |
| 46 | + | |
| 47 | + const sofIndex = this._segments.findIndex( | |
| 48 | + x => x[1] == 0xC0 || x[1] == 0xC2 | |
| 49 | + ); | |
| 50 | + if (sofIndex == -1) { | |
| 51 | + throw new Error("Illegal JPEG image without SOF"); | |
| 52 | + } | |
| 53 | + | |
| 54 | + if (quantTables.length === 0) { | |
| 55 | + this._segments.splice(sofIndex+1, 0, | |
| 56 | + ...this._cachedQuantTables); | |
| 57 | + } | |
| 58 | + if (huffmanTables.length === 0) { | |
| 59 | + this._segments.splice(sofIndex+1, 0, | |
| 60 | + ...this._cachedHuffmanTables); | |
| 61 | + } | |
| 62 | + | |
| 63 | + let length = 0; | |
| 64 | + for (let segment of this._segments) { | |
| 65 | + length += segment.length; | |
| 66 | + } | |
| 67 | + | |
| 68 | + let data = new Uint8Array(length); | |
| 69 | + length = 0; | |
| 70 | + for (let segment of this._segments) { | |
| 71 | + data.set(segment, length); | |
| 72 | + length += segment.length; | |
| 73 | + } | |
| 74 | + | |
| 75 | + display.imageRect(x, y, width, height, "image/jpeg", data); | |
| 76 | + | |
| 77 | + if (huffmanTables.length !== 0) { | |
| 78 | + this._cachedHuffmanTables = huffmanTables; | |
| 79 | + } | |
| 80 | + if (quantTables.length !== 0) { | |
| 81 | + this._cachedQuantTables = quantTables; | |
| 82 | + } | |
| 83 | + | |
| 84 | + this._segments = []; | |
| 85 | + | |
| 86 | + return true; | |
| 87 | + } | |
| 88 | + | |
| 89 | + _readSegment(sock) { | |
| 90 | + if (sock.rQwait("JPEG", 2)) { | |
| 91 | + return null; | |
| 92 | + } | |
| 93 | + | |
| 94 | + let marker = sock.rQshift8(); | |
| 95 | + if (marker != 0xFF) { | |
| 96 | + throw new Error("Illegal JPEG marker received (byte: " + | |
| 97 | + marker + ")"); | |
| 98 | + } | |
| 99 | + let type = sock.rQshift8(); | |
| 100 | + if (type >= 0xD0 && type <= 0xD9 || type == 0x01) { | |
| 101 | + // No length after marker | |
| 102 | + return new Uint8Array([marker, type]); | |
| 103 | + } | |
| 104 | + | |
| 105 | + if (sock.rQwait("JPEG", 2, 2)) { | |
| 106 | + return null; | |
| 107 | + } | |
| 108 | + | |
| 109 | + let length = sock.rQshift16(); | |
| 110 | + if (length < 2) { | |
| 111 | + throw new Error("Illegal JPEG length received (length: " + | |
| 112 | + length + ")"); | |
| 113 | + } | |
| 114 | + | |
| 115 | + if (sock.rQwait("JPEG", length-2, 4)) { | |
| 116 | + return null; | |
| 117 | + } | |
| 118 | + | |
| 119 | + let extra = 0; | |
| 120 | + if (type === 0xDA) { | |
| 121 | + // start of scan | |
| 122 | + extra += 2; | |
| 123 | + while (true) { | |
| 124 | + if (sock.rQwait("JPEG", length-2+extra, 4)) { | |
| 125 | + return null; | |
| 126 | + } | |
| 127 | + let data = sock.rQpeekBytes(length-2+extra, false); | |
| 128 | + if (data.at(-2) === 0xFF && data.at(-1) !== 0x00 && | |
| 129 | + !(data.at(-1) >= 0xD0 && data.at(-1) <= 0xD7)) { | |
| 130 | + extra -= 2; | |
| 131 | + break; | |
| 132 | + } | |
| 133 | + extra++; | |
| 134 | + } | |
| 135 | + } | |
| 136 | + | |
| 137 | + let segment = new Uint8Array(2 + length + extra); | |
| 138 | + segment[0] = marker; | |
| 139 | + segment[1] = type; | |
| 140 | + segment[2] = length >> 8; | |
| 141 | + segment[3] = length; | |
| 142 | + segment.set(sock.rQshiftBytes(length-2+extra, false), 4); | |
| 143 | + | |
| 144 | + return segment; | |
| 145 | + } | |
| 146 | +} | |
added
public/vendor/novnc/core/decoders/raw.js
+59 −0
@@ -0,0 +1,59 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +export default class RawDecoder { | |
| 11 | + constructor() { | |
| 12 | + this._lines = 0; | |
| 13 | + } | |
| 14 | + | |
| 15 | + decodeRect(x, y, width, height, sock, display, depth) { | |
| 16 | + if ((width === 0) || (height === 0)) { | |
| 17 | + return true; | |
| 18 | + } | |
| 19 | + | |
| 20 | + if (this._lines === 0) { | |
| 21 | + this._lines = height; | |
| 22 | + } | |
| 23 | + | |
| 24 | + const pixelSize = depth == 8 ? 1 : 4; | |
| 25 | + const bytesPerLine = width * pixelSize; | |
| 26 | + | |
| 27 | + while (this._lines > 0) { | |
| 28 | + if (sock.rQwait("RAW", bytesPerLine)) { | |
| 29 | + return false; | |
| 30 | + } | |
| 31 | + | |
| 32 | + const curY = y + (height - this._lines); | |
| 33 | + | |
| 34 | + let data = sock.rQshiftBytes(bytesPerLine, false); | |
| 35 | + | |
| 36 | + // Convert data if needed | |
| 37 | + if (depth == 8) { | |
| 38 | + const newdata = new Uint8Array(width * 4); | |
| 39 | + for (let i = 0; i < width; i++) { | |
| 40 | + newdata[i * 4 + 0] = ((data[i] >> 0) & 0x3) * 255 / 3; | |
| 41 | + newdata[i * 4 + 1] = ((data[i] >> 2) & 0x3) * 255 / 3; | |
| 42 | + newdata[i * 4 + 2] = ((data[i] >> 4) & 0x3) * 255 / 3; | |
| 43 | + newdata[i * 4 + 3] = 255; | |
| 44 | + } | |
| 45 | + data = newdata; | |
| 46 | + } | |
| 47 | + | |
| 48 | + // Max sure the image is fully opaque | |
| 49 | + for (let i = 0; i < width; i++) { | |
| 50 | + data[i * 4 + 3] = 255; | |
| 51 | + } | |
| 52 | + | |
| 53 | + display.blitImage(x, curY, width, 1, data, 0); | |
| 54 | + this._lines--; | |
| 55 | + } | |
| 56 | + | |
| 57 | + return true; | |
| 58 | + } | |
| 59 | +} | |
added
public/vendor/novnc/core/decoders/rre.js
+44 −0
@@ -0,0 +1,44 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +export default class RREDecoder { | |
| 11 | + constructor() { | |
| 12 | + this._subrects = 0; | |
| 13 | + } | |
| 14 | + | |
| 15 | + decodeRect(x, y, width, height, sock, display, depth) { | |
| 16 | + if (this._subrects === 0) { | |
| 17 | + if (sock.rQwait("RRE", 4 + 4)) { | |
| 18 | + return false; | |
| 19 | + } | |
| 20 | + | |
| 21 | + this._subrects = sock.rQshift32(); | |
| 22 | + | |
| 23 | + let color = sock.rQshiftBytes(4); // Background | |
| 24 | + display.fillRect(x, y, width, height, color); | |
| 25 | + } | |
| 26 | + | |
| 27 | + while (this._subrects > 0) { | |
| 28 | + if (sock.rQwait("RRE", 4 + 8)) { | |
| 29 | + return false; | |
| 30 | + } | |
| 31 | + | |
| 32 | + let color = sock.rQshiftBytes(4); | |
| 33 | + let sx = sock.rQshift16(); | |
| 34 | + let sy = sock.rQshift16(); | |
| 35 | + let swidth = sock.rQshift16(); | |
| 36 | + let sheight = sock.rQshift16(); | |
| 37 | + display.fillRect(x + sx, y + sy, swidth, sheight, color); | |
| 38 | + | |
| 39 | + this._subrects--; | |
| 40 | + } | |
| 41 | + | |
| 42 | + return true; | |
| 43 | + } | |
| 44 | +} | |
added
public/vendor/novnc/core/decoders/tight.js
+393 −0
@@ -0,0 +1,393 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca) | |
| 5 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 6 | + * | |
| 7 | + * See README.md for usage and integration instructions. | |
| 8 | + * | |
| 9 | + */ | |
| 10 | + | |
| 11 | +import * as Log from '../util/logging.js'; | |
| 12 | +import Inflator from "../inflator.js"; | |
| 13 | + | |
| 14 | +export default class TightDecoder { | |
| 15 | + constructor() { | |
| 16 | + this._ctl = null; | |
| 17 | + this._filter = null; | |
| 18 | + this._numColors = 0; | |
| 19 | + this._palette = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel) | |
| 20 | + this._len = 0; | |
| 21 | + | |
| 22 | + this._zlibs = []; | |
| 23 | + for (let i = 0; i < 4; i++) { | |
| 24 | + this._zlibs[i] = new Inflator(); | |
| 25 | + } | |
| 26 | + } | |
| 27 | + | |
| 28 | + decodeRect(x, y, width, height, sock, display, depth) { | |
| 29 | + if (this._ctl === null) { | |
| 30 | + if (sock.rQwait("TIGHT compression-control", 1)) { | |
| 31 | + return false; | |
| 32 | + } | |
| 33 | + | |
| 34 | + this._ctl = sock.rQshift8(); | |
| 35 | + | |
| 36 | + // Reset streams if the server requests it | |
| 37 | + for (let i = 0; i < 4; i++) { | |
| 38 | + if ((this._ctl >> i) & 1) { | |
| 39 | + this._zlibs[i].reset(); | |
| 40 | + Log.Info("Reset zlib stream " + i); | |
| 41 | + } | |
| 42 | + } | |
| 43 | + | |
| 44 | + // Figure out filter | |
| 45 | + this._ctl = this._ctl >> 4; | |
| 46 | + } | |
| 47 | + | |
| 48 | + let ret; | |
| 49 | + | |
| 50 | + if (this._ctl === 0x08) { | |
| 51 | + ret = this._fillRect(x, y, width, height, | |
| 52 | + sock, display, depth); | |
| 53 | + } else if (this._ctl === 0x09) { | |
| 54 | + ret = this._jpegRect(x, y, width, height, | |
| 55 | + sock, display, depth); | |
| 56 | + } else if (this._ctl === 0x0A) { | |
| 57 | + ret = this._pngRect(x, y, width, height, | |
| 58 | + sock, display, depth); | |
| 59 | + } else if ((this._ctl & 0x08) == 0) { | |
| 60 | + ret = this._basicRect(this._ctl, x, y, width, height, | |
| 61 | + sock, display, depth); | |
| 62 | + } else { | |
| 63 | + throw new Error("Illegal tight compression received (ctl: " + | |
| 64 | + this._ctl + ")"); | |
| 65 | + } | |
| 66 | + | |
| 67 | + if (ret) { | |
| 68 | + this._ctl = null; | |
| 69 | + } | |
| 70 | + | |
| 71 | + return ret; | |
| 72 | + } | |
| 73 | + | |
| 74 | + _fillRect(x, y, width, height, sock, display, depth) { | |
| 75 | + if (sock.rQwait("TIGHT", 3)) { | |
| 76 | + return false; | |
| 77 | + } | |
| 78 | + | |
| 79 | + let pixel = sock.rQshiftBytes(3); | |
| 80 | + display.fillRect(x, y, width, height, pixel, false); | |
| 81 | + | |
| 82 | + return true; | |
| 83 | + } | |
| 84 | + | |
| 85 | + _jpegRect(x, y, width, height, sock, display, depth) { | |
| 86 | + let data = this._readData(sock); | |
| 87 | + if (data === null) { | |
| 88 | + return false; | |
| 89 | + } | |
| 90 | + | |
| 91 | + display.imageRect(x, y, width, height, "image/jpeg", data); | |
| 92 | + | |
| 93 | + return true; | |
| 94 | + } | |
| 95 | + | |
| 96 | + _pngRect(x, y, width, height, sock, display, depth) { | |
| 97 | + throw new Error("PNG received in standard Tight rect"); | |
| 98 | + } | |
| 99 | + | |
| 100 | + _basicRect(ctl, x, y, width, height, sock, display, depth) { | |
| 101 | + if (this._filter === null) { | |
| 102 | + if (ctl & 0x4) { | |
| 103 | + if (sock.rQwait("TIGHT", 1)) { | |
| 104 | + return false; | |
| 105 | + } | |
| 106 | + | |
| 107 | + this._filter = sock.rQshift8(); | |
| 108 | + } else { | |
| 109 | + // Implicit CopyFilter | |
| 110 | + this._filter = 0; | |
| 111 | + } | |
| 112 | + } | |
| 113 | + | |
| 114 | + let streamId = ctl & 0x3; | |
| 115 | + | |
| 116 | + let ret; | |
| 117 | + | |
| 118 | + switch (this._filter) { | |
| 119 | + case 0: // CopyFilter | |
| 120 | + ret = this._copyFilter(streamId, x, y, width, height, | |
| 121 | + sock, display, depth); | |
| 122 | + break; | |
| 123 | + case 1: // PaletteFilter | |
| 124 | + ret = this._paletteFilter(streamId, x, y, width, height, | |
| 125 | + sock, display, depth); | |
| 126 | + break; | |
| 127 | + case 2: // GradientFilter | |
| 128 | + ret = this._gradientFilter(streamId, x, y, width, height, | |
| 129 | + sock, display, depth); | |
| 130 | + break; | |
| 131 | + default: | |
| 132 | + throw new Error("Illegal tight filter received (ctl: " + | |
| 133 | + this._filter + ")"); | |
| 134 | + } | |
| 135 | + | |
| 136 | + if (ret) { | |
| 137 | + this._filter = null; | |
| 138 | + } | |
| 139 | + | |
| 140 | + return ret; | |
| 141 | + } | |
| 142 | + | |
| 143 | + _copyFilter(streamId, x, y, width, height, sock, display, depth) { | |
| 144 | + const uncompressedSize = width * height * 3; | |
| 145 | + let data; | |
| 146 | + | |
| 147 | + if (uncompressedSize === 0) { | |
| 148 | + return true; | |
| 149 | + } | |
| 150 | + | |
| 151 | + if (uncompressedSize < 12) { | |
| 152 | + if (sock.rQwait("TIGHT", uncompressedSize)) { | |
| 153 | + return false; | |
| 154 | + } | |
| 155 | + | |
| 156 | + data = sock.rQshiftBytes(uncompressedSize); | |
| 157 | + } else { | |
| 158 | + data = this._readData(sock); | |
| 159 | + if (data === null) { | |
| 160 | + return false; | |
| 161 | + } | |
| 162 | + | |
| 163 | + this._zlibs[streamId].setInput(data); | |
| 164 | + data = this._zlibs[streamId].inflate(uncompressedSize); | |
| 165 | + this._zlibs[streamId].setInput(null); | |
| 166 | + } | |
| 167 | + | |
| 168 | + let rgbx = new Uint8Array(width * height * 4); | |
| 169 | + for (let i = 0, j = 0; i < width * height * 4; i += 4, j += 3) { | |
| 170 | + rgbx[i] = data[j]; | |
| 171 | + rgbx[i + 1] = data[j + 1]; | |
| 172 | + rgbx[i + 2] = data[j + 2]; | |
| 173 | + rgbx[i + 3] = 255; // Alpha | |
| 174 | + } | |
| 175 | + | |
| 176 | + display.blitImage(x, y, width, height, rgbx, 0, false); | |
| 177 | + | |
| 178 | + return true; | |
| 179 | + } | |
| 180 | + | |
| 181 | + _paletteFilter(streamId, x, y, width, height, sock, display, depth) { | |
| 182 | + if (this._numColors === 0) { | |
| 183 | + if (sock.rQwait("TIGHT palette", 1)) { | |
| 184 | + return false; | |
| 185 | + } | |
| 186 | + | |
| 187 | + const numColors = sock.rQpeek8() + 1; | |
| 188 | + const paletteSize = numColors * 3; | |
| 189 | + | |
| 190 | + if (sock.rQwait("TIGHT palette", 1 + paletteSize)) { | |
| 191 | + return false; | |
| 192 | + } | |
| 193 | + | |
| 194 | + this._numColors = numColors; | |
| 195 | + sock.rQskipBytes(1); | |
| 196 | + | |
| 197 | + sock.rQshiftTo(this._palette, paletteSize); | |
| 198 | + } | |
| 199 | + | |
| 200 | + const bpp = (this._numColors <= 2) ? 1 : 8; | |
| 201 | + const rowSize = Math.floor((width * bpp + 7) / 8); | |
| 202 | + const uncompressedSize = rowSize * height; | |
| 203 | + | |
| 204 | + let data; | |
| 205 | + | |
| 206 | + if (uncompressedSize === 0) { | |
| 207 | + return true; | |
| 208 | + } | |
| 209 | + | |
| 210 | + if (uncompressedSize < 12) { | |
| 211 | + if (sock.rQwait("TIGHT", uncompressedSize)) { | |
| 212 | + return false; | |
| 213 | + } | |
| 214 | + | |
| 215 | + data = sock.rQshiftBytes(uncompressedSize); | |
| 216 | + } else { | |
| 217 | + data = this._readData(sock); | |
| 218 | + if (data === null) { | |
| 219 | + return false; | |
| 220 | + } | |
| 221 | + | |
| 222 | + this._zlibs[streamId].setInput(data); | |
| 223 | + data = this._zlibs[streamId].inflate(uncompressedSize); | |
| 224 | + this._zlibs[streamId].setInput(null); | |
| 225 | + } | |
| 226 | + | |
| 227 | + // Convert indexed (palette based) image data to RGB | |
| 228 | + if (this._numColors == 2) { | |
| 229 | + this._monoRect(x, y, width, height, data, this._palette, display); | |
| 230 | + } else { | |
| 231 | + this._paletteRect(x, y, width, height, data, this._palette, display); | |
| 232 | + } | |
| 233 | + | |
| 234 | + this._numColors = 0; | |
| 235 | + | |
| 236 | + return true; | |
| 237 | + } | |
| 238 | + | |
| 239 | + _monoRect(x, y, width, height, data, palette, display) { | |
| 240 | + // Convert indexed (palette based) image data to RGB | |
| 241 | + // TODO: reduce number of calculations inside loop | |
| 242 | + const dest = this._getScratchBuffer(width * height * 4); | |
| 243 | + const w = Math.floor((width + 7) / 8); | |
| 244 | + const w1 = Math.floor(width / 8); | |
| 245 | + | |
| 246 | + for (let y = 0; y < height; y++) { | |
| 247 | + let dp, sp, x; | |
| 248 | + for (x = 0; x < w1; x++) { | |
| 249 | + for (let b = 7; b >= 0; b--) { | |
| 250 | + dp = (y * width + x * 8 + 7 - b) * 4; | |
| 251 | + sp = (data[y * w + x] >> b & 1) * 3; | |
| 252 | + dest[dp] = palette[sp]; | |
| 253 | + dest[dp + 1] = palette[sp + 1]; | |
| 254 | + dest[dp + 2] = palette[sp + 2]; | |
| 255 | + dest[dp + 3] = 255; | |
| 256 | + } | |
| 257 | + } | |
| 258 | + | |
| 259 | + for (let b = 7; b >= 8 - width % 8; b--) { | |
| 260 | + dp = (y * width + x * 8 + 7 - b) * 4; | |
| 261 | + sp = (data[y * w + x] >> b & 1) * 3; | |
| 262 | + dest[dp] = palette[sp]; | |
| 263 | + dest[dp + 1] = palette[sp + 1]; | |
| 264 | + dest[dp + 2] = palette[sp + 2]; | |
| 265 | + dest[dp + 3] = 255; | |
| 266 | + } | |
| 267 | + } | |
| 268 | + | |
| 269 | + display.blitImage(x, y, width, height, dest, 0, false); | |
| 270 | + } | |
| 271 | + | |
| 272 | + _paletteRect(x, y, width, height, data, palette, display) { | |
| 273 | + // Convert indexed (palette based) image data to RGB | |
| 274 | + const dest = this._getScratchBuffer(width * height * 4); | |
| 275 | + const total = width * height * 4; | |
| 276 | + for (let i = 0, j = 0; i < total; i += 4, j++) { | |
| 277 | + const sp = data[j] * 3; | |
| 278 | + dest[i] = palette[sp]; | |
| 279 | + dest[i + 1] = palette[sp + 1]; | |
| 280 | + dest[i + 2] = palette[sp + 2]; | |
| 281 | + dest[i + 3] = 255; | |
| 282 | + } | |
| 283 | + | |
| 284 | + display.blitImage(x, y, width, height, dest, 0, false); | |
| 285 | + } | |
| 286 | + | |
| 287 | + _gradientFilter(streamId, x, y, width, height, sock, display, depth) { | |
| 288 | + // assume the TPIXEL is 3 bytes long | |
| 289 | + const uncompressedSize = width * height * 3; | |
| 290 | + let data; | |
| 291 | + | |
| 292 | + if (uncompressedSize === 0) { | |
| 293 | + return true; | |
| 294 | + } | |
| 295 | + | |
| 296 | + if (uncompressedSize < 12) { | |
| 297 | + if (sock.rQwait("TIGHT", uncompressedSize)) { | |
| 298 | + return false; | |
| 299 | + } | |
| 300 | + | |
| 301 | + data = sock.rQshiftBytes(uncompressedSize); | |
| 302 | + } else { | |
| 303 | + data = this._readData(sock); | |
| 304 | + if (data === null) { | |
| 305 | + return false; | |
| 306 | + } | |
| 307 | + | |
| 308 | + this._zlibs[streamId].setInput(data); | |
| 309 | + data = this._zlibs[streamId].inflate(uncompressedSize); | |
| 310 | + this._zlibs[streamId].setInput(null); | |
| 311 | + } | |
| 312 | + | |
| 313 | + let rgbx = new Uint8Array(4 * width * height); | |
| 314 | + | |
| 315 | + let rgbxIndex = 0, dataIndex = 0; | |
| 316 | + let left = new Uint8Array(3); | |
| 317 | + for (let x = 0; x < width; x++) { | |
| 318 | + for (let c = 0; c < 3; c++) { | |
| 319 | + const prediction = left[c]; | |
| 320 | + const value = data[dataIndex++] + prediction; | |
| 321 | + rgbx[rgbxIndex++] = value; | |
| 322 | + left[c] = value; | |
| 323 | + } | |
| 324 | + rgbx[rgbxIndex++] = 255; | |
| 325 | + } | |
| 326 | + | |
| 327 | + let upperIndex = 0; | |
| 328 | + let upper = new Uint8Array(3), | |
| 329 | + upperleft = new Uint8Array(3); | |
| 330 | + for (let y = 1; y < height; y++) { | |
| 331 | + left.fill(0); | |
| 332 | + upperleft.fill(0); | |
| 333 | + for (let x = 0; x < width; x++) { | |
| 334 | + for (let c = 0; c < 3; c++) { | |
| 335 | + upper[c] = rgbx[upperIndex++]; | |
| 336 | + let prediction = left[c] + upper[c] - upperleft[c]; | |
| 337 | + if (prediction < 0) { | |
| 338 | + prediction = 0; | |
| 339 | + } else if (prediction > 255) { | |
| 340 | + prediction = 255; | |
| 341 | + } | |
| 342 | + const value = data[dataIndex++] + prediction; | |
| 343 | + rgbx[rgbxIndex++] = value; | |
| 344 | + upperleft[c] = upper[c]; | |
| 345 | + left[c] = value; | |
| 346 | + } | |
| 347 | + rgbx[rgbxIndex++] = 255; | |
| 348 | + upperIndex++; | |
| 349 | + } | |
| 350 | + } | |
| 351 | + | |
| 352 | + display.blitImage(x, y, width, height, rgbx, 0, false); | |
| 353 | + | |
| 354 | + return true; | |
| 355 | + } | |
| 356 | + | |
| 357 | + _readData(sock) { | |
| 358 | + if (this._len === 0) { | |
| 359 | + if (sock.rQwait("TIGHT", 3)) { | |
| 360 | + return null; | |
| 361 | + } | |
| 362 | + | |
| 363 | + let byte; | |
| 364 | + | |
| 365 | + byte = sock.rQshift8(); | |
| 366 | + this._len = byte & 0x7f; | |
| 367 | + if (byte & 0x80) { | |
| 368 | + byte = sock.rQshift8(); | |
| 369 | + this._len |= (byte & 0x7f) << 7; | |
| 370 | + if (byte & 0x80) { | |
| 371 | + byte = sock.rQshift8(); | |
| 372 | + this._len |= byte << 14; | |
| 373 | + } | |
| 374 | + } | |
| 375 | + } | |
| 376 | + | |
| 377 | + if (sock.rQwait("TIGHT", this._len)) { | |
| 378 | + return null; | |
| 379 | + } | |
| 380 | + | |
| 381 | + let data = sock.rQshiftBytes(this._len, false); | |
| 382 | + this._len = 0; | |
| 383 | + | |
| 384 | + return data; | |
| 385 | + } | |
| 386 | + | |
| 387 | + _getScratchBuffer(size) { | |
| 388 | + if (!this._scratchBuffer || (this._scratchBuffer.length < size)) { | |
| 389 | + this._scratchBuffer = new Uint8Array(size); | |
| 390 | + } | |
| 391 | + return this._scratchBuffer; | |
| 392 | + } | |
| 393 | +} | |
added
public/vendor/novnc/core/decoders/tightpng.js
+27 −0
@@ -0,0 +1,27 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +import TightDecoder from './tight.js'; | |
| 11 | + | |
| 12 | +export default class TightPNGDecoder extends TightDecoder { | |
| 13 | + _pngRect(x, y, width, height, sock, display, depth) { | |
| 14 | + let data = this._readData(sock); | |
| 15 | + if (data === null) { | |
| 16 | + return false; | |
| 17 | + } | |
| 18 | + | |
| 19 | + display.imageRect(x, y, width, height, "image/png", data); | |
| 20 | + | |
| 21 | + return true; | |
| 22 | + } | |
| 23 | + | |
| 24 | + _basicRect(ctl, x, y, width, height, sock, display, depth) { | |
| 25 | + throw new Error("BasicCompression received in TightPNG rect"); | |
| 26 | + } | |
| 27 | +} | |
added
public/vendor/novnc/core/decoders/zlib.js
+51 −0
@@ -0,0 +1,51 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2024 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +import Inflator from "../inflator.js"; | |
| 11 | + | |
| 12 | +export default class ZlibDecoder { | |
| 13 | + constructor() { | |
| 14 | + this._zlib = new Inflator(); | |
| 15 | + this._length = 0; | |
| 16 | + } | |
| 17 | + | |
| 18 | + decodeRect(x, y, width, height, sock, display, depth) { | |
| 19 | + if ((width === 0) || (height === 0)) { | |
| 20 | + return true; | |
| 21 | + } | |
| 22 | + | |
| 23 | + if (this._length === 0) { | |
| 24 | + if (sock.rQwait("ZLIB", 4)) { | |
| 25 | + return false; | |
| 26 | + } | |
| 27 | + | |
| 28 | + this._length = sock.rQshift32(); | |
| 29 | + } | |
| 30 | + | |
| 31 | + if (sock.rQwait("ZLIB", this._length)) { | |
| 32 | + return false; | |
| 33 | + } | |
| 34 | + | |
| 35 | + let data = new Uint8Array(sock.rQshiftBytes(this._length, false)); | |
| 36 | + this._length = 0; | |
| 37 | + | |
| 38 | + this._zlib.setInput(data); | |
| 39 | + data = this._zlib.inflate(width * height * 4); | |
| 40 | + this._zlib.setInput(null); | |
| 41 | + | |
| 42 | + // Max sure the image is fully opaque | |
| 43 | + for (let i = 0; i < width * height; i++) { | |
| 44 | + data[i * 4 + 3] = 255; | |
| 45 | + } | |
| 46 | + | |
| 47 | + display.blitImage(x, y, width, height, data, 0); | |
| 48 | + | |
| 49 | + return true; | |
| 50 | + } | |
| 51 | +} | |
added
public/vendor/novnc/core/decoders/zrle.js
+185 −0
@@ -0,0 +1,185 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2021 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +import Inflate from "../inflator.js"; | |
| 11 | + | |
| 12 | +const ZRLE_TILE_WIDTH = 64; | |
| 13 | +const ZRLE_TILE_HEIGHT = 64; | |
| 14 | + | |
| 15 | +export default class ZRLEDecoder { | |
| 16 | + constructor() { | |
| 17 | + this._length = 0; | |
| 18 | + this._inflator = new Inflate(); | |
| 19 | + | |
| 20 | + this._pixelBuffer = new Uint8Array(ZRLE_TILE_WIDTH * ZRLE_TILE_HEIGHT * 4); | |
| 21 | + this._tileBuffer = new Uint8Array(ZRLE_TILE_WIDTH * ZRLE_TILE_HEIGHT * 4); | |
| 22 | + } | |
| 23 | + | |
| 24 | + decodeRect(x, y, width, height, sock, display, depth) { | |
| 25 | + if (this._length === 0) { | |
| 26 | + if (sock.rQwait("ZLib data length", 4)) { | |
| 27 | + return false; | |
| 28 | + } | |
| 29 | + this._length = sock.rQshift32(); | |
| 30 | + } | |
| 31 | + if (sock.rQwait("Zlib data", this._length)) { | |
| 32 | + return false; | |
| 33 | + } | |
| 34 | + | |
| 35 | + const data = sock.rQshiftBytes(this._length, false); | |
| 36 | + | |
| 37 | + this._inflator.setInput(data); | |
| 38 | + | |
| 39 | + for (let ty = y; ty < y + height; ty += ZRLE_TILE_HEIGHT) { | |
| 40 | + let th = Math.min(ZRLE_TILE_HEIGHT, y + height - ty); | |
| 41 | + | |
| 42 | + for (let tx = x; tx < x + width; tx += ZRLE_TILE_WIDTH) { | |
| 43 | + let tw = Math.min(ZRLE_TILE_WIDTH, x + width - tx); | |
| 44 | + | |
| 45 | + const tileSize = tw * th; | |
| 46 | + const subencoding = this._inflator.inflate(1)[0]; | |
| 47 | + if (subencoding === 0) { | |
| 48 | + // raw data | |
| 49 | + const data = this._readPixels(tileSize); | |
| 50 | + display.blitImage(tx, ty, tw, th, data, 0, false); | |
| 51 | + } else if (subencoding === 1) { | |
| 52 | + // solid | |
| 53 | + const background = this._readPixels(1); | |
| 54 | + display.fillRect(tx, ty, tw, th, [background[0], background[1], background[2]]); | |
| 55 | + } else if (subencoding >= 2 && subencoding <= 16) { | |
| 56 | + const data = this._decodePaletteTile(subencoding, tileSize, tw, th); | |
| 57 | + display.blitImage(tx, ty, tw, th, data, 0, false); | |
| 58 | + } else if (subencoding === 128) { | |
| 59 | + const data = this._decodeRLETile(tileSize); | |
| 60 | + display.blitImage(tx, ty, tw, th, data, 0, false); | |
| 61 | + } else if (subencoding >= 130 && subencoding <= 255) { | |
| 62 | + const data = this._decodeRLEPaletteTile(subencoding - 128, tileSize); | |
| 63 | + display.blitImage(tx, ty, tw, th, data, 0, false); | |
| 64 | + } else { | |
| 65 | + throw new Error('Unknown subencoding: ' + subencoding); | |
| 66 | + } | |
| 67 | + } | |
| 68 | + } | |
| 69 | + this._length = 0; | |
| 70 | + return true; | |
| 71 | + } | |
| 72 | + | |
| 73 | + _getBitsPerPixelInPalette(paletteSize) { | |
| 74 | + if (paletteSize <= 2) { | |
| 75 | + return 1; | |
| 76 | + } else if (paletteSize <= 4) { | |
| 77 | + return 2; | |
| 78 | + } else if (paletteSize <= 16) { | |
| 79 | + return 4; | |
| 80 | + } | |
| 81 | + } | |
| 82 | + | |
| 83 | + _readPixels(pixels) { | |
| 84 | + let data = this._pixelBuffer; | |
| 85 | + const buffer = this._inflator.inflate(3*pixels); | |
| 86 | + for (let i = 0, j = 0; i < pixels*4; i += 4, j += 3) { | |
| 87 | + data[i] = buffer[j]; | |
| 88 | + data[i + 1] = buffer[j + 1]; | |
| 89 | + data[i + 2] = buffer[j + 2]; | |
| 90 | + data[i + 3] = 255; // Add the Alpha | |
| 91 | + } | |
| 92 | + return data; | |
| 93 | + } | |
| 94 | + | |
| 95 | + _decodePaletteTile(paletteSize, tileSize, tilew, tileh) { | |
| 96 | + const data = this._tileBuffer; | |
| 97 | + const palette = this._readPixels(paletteSize); | |
| 98 | + const bitsPerPixel = this._getBitsPerPixelInPalette(paletteSize); | |
| 99 | + const mask = (1 << bitsPerPixel) - 1; | |
| 100 | + | |
| 101 | + let offset = 0; | |
| 102 | + let encoded = this._inflator.inflate(1)[0]; | |
| 103 | + | |
| 104 | + for (let y=0; y<tileh; y++) { | |
| 105 | + let shift = 8-bitsPerPixel; | |
| 106 | + for (let x=0; x<tilew; x++) { | |
| 107 | + if (shift<0) { | |
| 108 | + shift=8-bitsPerPixel; | |
| 109 | + encoded = this._inflator.inflate(1)[0]; | |
| 110 | + } | |
| 111 | + let indexInPalette = (encoded>>shift) & mask; | |
| 112 | + | |
| 113 | + data[offset] = palette[indexInPalette * 4]; | |
| 114 | + data[offset + 1] = palette[indexInPalette * 4 + 1]; | |
| 115 | + data[offset + 2] = palette[indexInPalette * 4 + 2]; | |
| 116 | + data[offset + 3] = palette[indexInPalette * 4 + 3]; | |
| 117 | + offset += 4; | |
| 118 | + shift-=bitsPerPixel; | |
| 119 | + } | |
| 120 | + if (shift<8-bitsPerPixel && y<tileh-1) { | |
| 121 | + encoded = this._inflator.inflate(1)[0]; | |
| 122 | + } | |
| 123 | + } | |
| 124 | + return data; | |
| 125 | + } | |
| 126 | + | |
| 127 | + _decodeRLETile(tileSize) { | |
| 128 | + const data = this._tileBuffer; | |
| 129 | + let i = 0; | |
| 130 | + while (i < tileSize) { | |
| 131 | + const pixel = this._readPixels(1); | |
| 132 | + const length = this._readRLELength(); | |
| 133 | + for (let j = 0; j < length; j++) { | |
| 134 | + data[i * 4] = pixel[0]; | |
| 135 | + data[i * 4 + 1] = pixel[1]; | |
| 136 | + data[i * 4 + 2] = pixel[2]; | |
| 137 | + data[i * 4 + 3] = pixel[3]; | |
| 138 | + i++; | |
| 139 | + } | |
| 140 | + } | |
| 141 | + return data; | |
| 142 | + } | |
| 143 | + | |
| 144 | + _decodeRLEPaletteTile(paletteSize, tileSize) { | |
| 145 | + const data = this._tileBuffer; | |
| 146 | + | |
| 147 | + // palette | |
| 148 | + const palette = this._readPixels(paletteSize); | |
| 149 | + | |
| 150 | + let offset = 0; | |
| 151 | + while (offset < tileSize) { | |
| 152 | + let indexInPalette = this._inflator.inflate(1)[0]; | |
| 153 | + let length = 1; | |
| 154 | + if (indexInPalette >= 128) { | |
| 155 | + indexInPalette -= 128; | |
| 156 | + length = this._readRLELength(); | |
| 157 | + } | |
| 158 | + if (indexInPalette > paletteSize) { | |
| 159 | + throw new Error('Too big index in palette: ' + indexInPalette + ', palette size: ' + paletteSize); | |
| 160 | + } | |
| 161 | + if (offset + length > tileSize) { | |
| 162 | + throw new Error('Too big rle length in palette mode: ' + length + ', allowed length is: ' + (tileSize - offset)); | |
| 163 | + } | |
| 164 | + | |
| 165 | + for (let j = 0; j < length; j++) { | |
| 166 | + data[offset * 4] = palette[indexInPalette * 4]; | |
| 167 | + data[offset * 4 + 1] = palette[indexInPalette * 4 + 1]; | |
| 168 | + data[offset * 4 + 2] = palette[indexInPalette * 4 + 2]; | |
| 169 | + data[offset * 4 + 3] = palette[indexInPalette * 4 + 3]; | |
| 170 | + offset++; | |
| 171 | + } | |
| 172 | + } | |
| 173 | + return data; | |
| 174 | + } | |
| 175 | + | |
| 176 | + _readRLELength() { | |
| 177 | + let length = 0; | |
| 178 | + let current = 0; | |
| 179 | + do { | |
| 180 | + current = this._inflator.inflate(1)[0]; | |
| 181 | + length += current; | |
| 182 | + } while (current === 255); | |
| 183 | + return length + 1; | |
| 184 | + } | |
| 185 | +} | |
added
public/vendor/novnc/core/deflator.js
+84 −0
@@ -0,0 +1,84 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2020 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +import { deflateInit, deflate } from "../vendor/pako/lib/zlib/deflate.js"; | |
| 10 | +import { Z_FULL_FLUSH, Z_DEFAULT_COMPRESSION } from "../vendor/pako/lib/zlib/deflate.js"; | |
| 11 | +import ZStream from "../vendor/pako/lib/zlib/zstream.js"; | |
| 12 | + | |
| 13 | +export default class Deflator { | |
| 14 | + constructor() { | |
| 15 | + this.strm = new ZStream(); | |
| 16 | + this.chunkSize = 1024 * 10 * 10; | |
| 17 | + this.outputBuffer = new Uint8Array(this.chunkSize); | |
| 18 | + | |
| 19 | + deflateInit(this.strm, Z_DEFAULT_COMPRESSION); | |
| 20 | + } | |
| 21 | + | |
| 22 | + deflate(inData) { | |
| 23 | + /* eslint-disable camelcase */ | |
| 24 | + this.strm.input = inData; | |
| 25 | + this.strm.avail_in = this.strm.input.length; | |
| 26 | + this.strm.next_in = 0; | |
| 27 | + this.strm.output = this.outputBuffer; | |
| 28 | + this.strm.avail_out = this.chunkSize; | |
| 29 | + this.strm.next_out = 0; | |
| 30 | + /* eslint-enable camelcase */ | |
| 31 | + | |
| 32 | + let lastRet = deflate(this.strm, Z_FULL_FLUSH); | |
| 33 | + let outData = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); | |
| 34 | + | |
| 35 | + if (lastRet < 0) { | |
| 36 | + throw new Error("zlib deflate failed"); | |
| 37 | + } | |
| 38 | + | |
| 39 | + if (this.strm.avail_in > 0) { | |
| 40 | + // Read chunks until done | |
| 41 | + | |
| 42 | + let chunks = [outData]; | |
| 43 | + let totalLen = outData.length; | |
| 44 | + do { | |
| 45 | + /* eslint-disable camelcase */ | |
| 46 | + this.strm.output = new Uint8Array(this.chunkSize); | |
| 47 | + this.strm.next_out = 0; | |
| 48 | + this.strm.avail_out = this.chunkSize; | |
| 49 | + /* eslint-enable camelcase */ | |
| 50 | + | |
| 51 | + lastRet = deflate(this.strm, Z_FULL_FLUSH); | |
| 52 | + | |
| 53 | + if (lastRet < 0) { | |
| 54 | + throw new Error("zlib deflate failed"); | |
| 55 | + } | |
| 56 | + | |
| 57 | + let chunk = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); | |
| 58 | + totalLen += chunk.length; | |
| 59 | + chunks.push(chunk); | |
| 60 | + } while (this.strm.avail_in > 0); | |
| 61 | + | |
| 62 | + // Combine chunks into a single data | |
| 63 | + | |
| 64 | + let newData = new Uint8Array(totalLen); | |
| 65 | + let offset = 0; | |
| 66 | + | |
| 67 | + for (let i = 0; i < chunks.length; i++) { | |
| 68 | + newData.set(chunks[i], offset); | |
| 69 | + offset += chunks[i].length; | |
| 70 | + } | |
| 71 | + | |
| 72 | + outData = newData; | |
| 73 | + } | |
| 74 | + | |
| 75 | + /* eslint-disable camelcase */ | |
| 76 | + this.strm.input = null; | |
| 77 | + this.strm.avail_in = 0; | |
| 78 | + this.strm.next_in = 0; | |
| 79 | + /* eslint-enable camelcase */ | |
| 80 | + | |
| 81 | + return outData; | |
| 82 | + } | |
| 83 | + | |
| 84 | +} | |
added
public/vendor/novnc/core/display.js
+575 −0
@@ -0,0 +1,575 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +import * as Log from './util/logging.js'; | |
| 10 | +import Base64 from "./base64.js"; | |
| 11 | +import { toSigned32bit } from './util/int.js'; | |
| 12 | + | |
| 13 | +export default class Display { | |
| 14 | + constructor(target) { | |
| 15 | + this._drawCtx = null; | |
| 16 | + | |
| 17 | + this._renderQ = []; // queue drawing actions for in-oder rendering | |
| 18 | + this._flushPromise = null; | |
| 19 | + | |
| 20 | + // the full frame buffer (logical canvas) size | |
| 21 | + this._fbWidth = 0; | |
| 22 | + this._fbHeight = 0; | |
| 23 | + | |
| 24 | + this._prevDrawStyle = ""; | |
| 25 | + | |
| 26 | + Log.Debug(">> Display.constructor"); | |
| 27 | + | |
| 28 | + // The visible canvas | |
| 29 | + this._target = target; | |
| 30 | + | |
| 31 | + if (!this._target) { | |
| 32 | + throw new Error("Target must be set"); | |
| 33 | + } | |
| 34 | + | |
| 35 | + if (typeof this._target === 'string') { | |
| 36 | + throw new Error('target must be a DOM element'); | |
| 37 | + } | |
| 38 | + | |
| 39 | + if (!this._target.getContext) { | |
| 40 | + throw new Error("no getContext method"); | |
| 41 | + } | |
| 42 | + | |
| 43 | + this._targetCtx = this._target.getContext('2d'); | |
| 44 | + | |
| 45 | + // the visible canvas viewport (i.e. what actually gets seen) | |
| 46 | + this._viewportLoc = { 'x': 0, 'y': 0, 'w': this._target.width, 'h': this._target.height }; | |
| 47 | + | |
| 48 | + // The hidden canvas, where we do the actual rendering | |
| 49 | + this._backbuffer = document.createElement('canvas'); | |
| 50 | + this._drawCtx = this._backbuffer.getContext('2d'); | |
| 51 | + | |
| 52 | + this._damageBounds = { left: 0, top: 0, | |
| 53 | + right: this._backbuffer.width, | |
| 54 | + bottom: this._backbuffer.height }; | |
| 55 | + | |
| 56 | + Log.Debug("User Agent: " + navigator.userAgent); | |
| 57 | + | |
| 58 | + Log.Debug("<< Display.constructor"); | |
| 59 | + | |
| 60 | + // ===== PROPERTIES ===== | |
| 61 | + | |
| 62 | + this._scale = 1.0; | |
| 63 | + this._clipViewport = false; | |
| 64 | + } | |
| 65 | + | |
| 66 | + // ===== PROPERTIES ===== | |
| 67 | + | |
| 68 | + get scale() { return this._scale; } | |
| 69 | + set scale(scale) { | |
| 70 | + this._rescale(scale); | |
| 71 | + } | |
| 72 | + | |
| 73 | + get clipViewport() { return this._clipViewport; } | |
| 74 | + set clipViewport(viewport) { | |
| 75 | + this._clipViewport = viewport; | |
| 76 | + // May need to readjust the viewport dimensions | |
| 77 | + const vp = this._viewportLoc; | |
| 78 | + this.viewportChangeSize(vp.w, vp.h); | |
| 79 | + this.viewportChangePos(0, 0); | |
| 80 | + } | |
| 81 | + | |
| 82 | + get width() { | |
| 83 | + return this._fbWidth; | |
| 84 | + } | |
| 85 | + | |
| 86 | + get height() { | |
| 87 | + return this._fbHeight; | |
| 88 | + } | |
| 89 | + | |
| 90 | + // ===== PUBLIC METHODS ===== | |
| 91 | + | |
| 92 | + viewportChangePos(deltaX, deltaY) { | |
| 93 | + const vp = this._viewportLoc; | |
| 94 | + deltaX = Math.floor(deltaX); | |
| 95 | + deltaY = Math.floor(deltaY); | |
| 96 | + | |
| 97 | + if (!this._clipViewport) { | |
| 98 | + deltaX = -vp.w; // clamped later of out of bounds | |
| 99 | + deltaY = -vp.h; | |
| 100 | + } | |
| 101 | + | |
| 102 | + const vx2 = vp.x + vp.w - 1; | |
| 103 | + const vy2 = vp.y + vp.h - 1; | |
| 104 | + | |
| 105 | + // Position change | |
| 106 | + | |
| 107 | + if (deltaX < 0 && vp.x + deltaX < 0) { | |
| 108 | + deltaX = -vp.x; | |
| 109 | + } | |
| 110 | + if (vx2 + deltaX >= this._fbWidth) { | |
| 111 | + deltaX -= vx2 + deltaX - this._fbWidth + 1; | |
| 112 | + } | |
| 113 | + | |
| 114 | + if (vp.y + deltaY < 0) { | |
| 115 | + deltaY = -vp.y; | |
| 116 | + } | |
| 117 | + if (vy2 + deltaY >= this._fbHeight) { | |
| 118 | + deltaY -= (vy2 + deltaY - this._fbHeight + 1); | |
| 119 | + } | |
| 120 | + | |
| 121 | + if (deltaX === 0 && deltaY === 0) { | |
| 122 | + return; | |
| 123 | + } | |
| 124 | + Log.Debug("viewportChange deltaX: " + deltaX + ", deltaY: " + deltaY); | |
| 125 | + | |
| 126 | + vp.x += deltaX; | |
| 127 | + vp.y += deltaY; | |
| 128 | + | |
| 129 | + this._damage(vp.x, vp.y, vp.w, vp.h); | |
| 130 | + | |
| 131 | + this.flip(); | |
| 132 | + } | |
| 133 | + | |
| 134 | + viewportChangeSize(width, height) { | |
| 135 | + | |
| 136 | + if (!this._clipViewport || | |
| 137 | + typeof(width) === "undefined" || | |
| 138 | + typeof(height) === "undefined") { | |
| 139 | + | |
| 140 | + Log.Debug("Setting viewport to full display region"); | |
| 141 | + width = this._fbWidth; | |
| 142 | + height = this._fbHeight; | |
| 143 | + } | |
| 144 | + | |
| 145 | + width = Math.floor(width); | |
| 146 | + height = Math.floor(height); | |
| 147 | + | |
| 148 | + if (width > this._fbWidth) { | |
| 149 | + width = this._fbWidth; | |
| 150 | + } | |
| 151 | + if (height > this._fbHeight) { | |
| 152 | + height = this._fbHeight; | |
| 153 | + } | |
| 154 | + | |
| 155 | + const vp = this._viewportLoc; | |
| 156 | + if (vp.w !== width || vp.h !== height) { | |
| 157 | + vp.w = width; | |
| 158 | + vp.h = height; | |
| 159 | + | |
| 160 | + const canvas = this._target; | |
| 161 | + canvas.width = width; | |
| 162 | + canvas.height = height; | |
| 163 | + | |
| 164 | + // The position might need to be updated if we've grown | |
| 165 | + this.viewportChangePos(0, 0); | |
| 166 | + | |
| 167 | + this._damage(vp.x, vp.y, vp.w, vp.h); | |
| 168 | + this.flip(); | |
| 169 | + | |
| 170 | + // Update the visible size of the target canvas | |
| 171 | + this._rescale(this._scale); | |
| 172 | + } | |
| 173 | + } | |
| 174 | + | |
| 175 | + absX(x) { | |
| 176 | + if (this._scale === 0) { | |
| 177 | + return 0; | |
| 178 | + } | |
| 179 | + return toSigned32bit(x / this._scale + this._viewportLoc.x); | |
| 180 | + } | |
| 181 | + | |
| 182 | + absY(y) { | |
| 183 | + if (this._scale === 0) { | |
| 184 | + return 0; | |
| 185 | + } | |
| 186 | + return toSigned32bit(y / this._scale + this._viewportLoc.y); | |
| 187 | + } | |
| 188 | + | |
| 189 | + resize(width, height) { | |
| 190 | + this._prevDrawStyle = ""; | |
| 191 | + | |
| 192 | + this._fbWidth = width; | |
| 193 | + this._fbHeight = height; | |
| 194 | + | |
| 195 | + const canvas = this._backbuffer; | |
| 196 | + if (canvas.width !== width || canvas.height !== height) { | |
| 197 | + | |
| 198 | + // We have to save the canvas data since changing the size will clear it | |
| 199 | + let saveImg = null; | |
| 200 | + if (canvas.width > 0 && canvas.height > 0) { | |
| 201 | + saveImg = this._drawCtx.getImageData(0, 0, canvas.width, canvas.height); | |
| 202 | + } | |
| 203 | + | |
| 204 | + if (canvas.width !== width) { | |
| 205 | + canvas.width = width; | |
| 206 | + } | |
| 207 | + if (canvas.height !== height) { | |
| 208 | + canvas.height = height; | |
| 209 | + } | |
| 210 | + | |
| 211 | + if (saveImg) { | |
| 212 | + this._drawCtx.putImageData(saveImg, 0, 0); | |
| 213 | + } | |
| 214 | + } | |
| 215 | + | |
| 216 | + // Readjust the viewport as it may be incorrectly sized | |
| 217 | + // and positioned | |
| 218 | + const vp = this._viewportLoc; | |
| 219 | + this.viewportChangeSize(vp.w, vp.h); | |
| 220 | + this.viewportChangePos(0, 0); | |
| 221 | + } | |
| 222 | + | |
| 223 | + getImageData() { | |
| 224 | + return this._drawCtx.getImageData(0, 0, this.width, this.height); | |
| 225 | + } | |
| 226 | + | |
| 227 | + toDataURL(type, encoderOptions) { | |
| 228 | + return this._backbuffer.toDataURL(type, encoderOptions); | |
| 229 | + } | |
| 230 | + | |
| 231 | + toBlob(callback, type, quality) { | |
| 232 | + return this._backbuffer.toBlob(callback, type, quality); | |
| 233 | + } | |
| 234 | + | |
| 235 | + // Track what parts of the visible canvas that need updating | |
| 236 | + _damage(x, y, w, h) { | |
| 237 | + if (x < this._damageBounds.left) { | |
| 238 | + this._damageBounds.left = x; | |
| 239 | + } | |
| 240 | + if (y < this._damageBounds.top) { | |
| 241 | + this._damageBounds.top = y; | |
| 242 | + } | |
| 243 | + if ((x + w) > this._damageBounds.right) { | |
| 244 | + this._damageBounds.right = x + w; | |
| 245 | + } | |
| 246 | + if ((y + h) > this._damageBounds.bottom) { | |
| 247 | + this._damageBounds.bottom = y + h; | |
| 248 | + } | |
| 249 | + } | |
| 250 | + | |
| 251 | + // Update the visible canvas with the contents of the | |
| 252 | + // rendering canvas | |
| 253 | + flip(fromQueue) { | |
| 254 | + if (this._renderQ.length !== 0 && !fromQueue) { | |
| 255 | + this._renderQPush({ | |
| 256 | + 'type': 'flip' | |
| 257 | + }); | |
| 258 | + } else { | |
| 259 | + let x = this._damageBounds.left; | |
| 260 | + let y = this._damageBounds.top; | |
| 261 | + let w = this._damageBounds.right - x; | |
| 262 | + let h = this._damageBounds.bottom - y; | |
| 263 | + | |
| 264 | + let vx = x - this._viewportLoc.x; | |
| 265 | + let vy = y - this._viewportLoc.y; | |
| 266 | + | |
| 267 | + if (vx < 0) { | |
| 268 | + w += vx; | |
| 269 | + x -= vx; | |
| 270 | + vx = 0; | |
| 271 | + } | |
| 272 | + if (vy < 0) { | |
| 273 | + h += vy; | |
| 274 | + y -= vy; | |
| 275 | + vy = 0; | |
| 276 | + } | |
| 277 | + | |
| 278 | + if ((vx + w) > this._viewportLoc.w) { | |
| 279 | + w = this._viewportLoc.w - vx; | |
| 280 | + } | |
| 281 | + if ((vy + h) > this._viewportLoc.h) { | |
| 282 | + h = this._viewportLoc.h - vy; | |
| 283 | + } | |
| 284 | + | |
| 285 | + if ((w > 0) && (h > 0)) { | |
| 286 | + // FIXME: We may need to disable image smoothing here | |
| 287 | + // as well (see copyImage()), but we haven't | |
| 288 | + // noticed any problem yet. | |
| 289 | + this._targetCtx.drawImage(this._backbuffer, | |
| 290 | + x, y, w, h, | |
| 291 | + vx, vy, w, h); | |
| 292 | + } | |
| 293 | + | |
| 294 | + this._damageBounds.left = this._damageBounds.top = 65535; | |
| 295 | + this._damageBounds.right = this._damageBounds.bottom = 0; | |
| 296 | + } | |
| 297 | + } | |
| 298 | + | |
| 299 | + pending() { | |
| 300 | + return this._renderQ.length > 0; | |
| 301 | + } | |
| 302 | + | |
| 303 | + flush() { | |
| 304 | + if (this._renderQ.length === 0) { | |
| 305 | + return Promise.resolve(); | |
| 306 | + } else { | |
| 307 | + if (this._flushPromise === null) { | |
| 308 | + this._flushPromise = new Promise((resolve) => { | |
| 309 | + this._flushResolve = resolve; | |
| 310 | + }); | |
| 311 | + } | |
| 312 | + return this._flushPromise; | |
| 313 | + } | |
| 314 | + } | |
| 315 | + | |
| 316 | + fillRect(x, y, width, height, color, fromQueue) { | |
| 317 | + if (this._renderQ.length !== 0 && !fromQueue) { | |
| 318 | + this._renderQPush({ | |
| 319 | + 'type': 'fill', | |
| 320 | + 'x': x, | |
| 321 | + 'y': y, | |
| 322 | + 'width': width, | |
| 323 | + 'height': height, | |
| 324 | + 'color': color | |
| 325 | + }); | |
| 326 | + } else { | |
| 327 | + this._setFillColor(color); | |
| 328 | + this._drawCtx.fillRect(x, y, width, height); | |
| 329 | + this._damage(x, y, width, height); | |
| 330 | + } | |
| 331 | + } | |
| 332 | + | |
| 333 | + copyImage(oldX, oldY, newX, newY, w, h, fromQueue) { | |
| 334 | + if (this._renderQ.length !== 0 && !fromQueue) { | |
| 335 | + this._renderQPush({ | |
| 336 | + 'type': 'copy', | |
| 337 | + 'oldX': oldX, | |
| 338 | + 'oldY': oldY, | |
| 339 | + 'x': newX, | |
| 340 | + 'y': newY, | |
| 341 | + 'width': w, | |
| 342 | + 'height': h, | |
| 343 | + }); | |
| 344 | + } else { | |
| 345 | + // Due to this bug among others [1] we need to disable the image-smoothing to | |
| 346 | + // avoid getting a blur effect when copying data. | |
| 347 | + // | |
| 348 | + // 1. https://bugzilla.mozilla.org/show_bug.cgi?id=1194719 | |
| 349 | + // | |
| 350 | + // We need to set these every time since all properties are reset | |
| 351 | + // when the the size is changed | |
| 352 | + this._drawCtx.mozImageSmoothingEnabled = false; | |
| 353 | + this._drawCtx.webkitImageSmoothingEnabled = false; | |
| 354 | + this._drawCtx.msImageSmoothingEnabled = false; | |
| 355 | + this._drawCtx.imageSmoothingEnabled = false; | |
| 356 | + | |
| 357 | + this._drawCtx.drawImage(this._backbuffer, | |
| 358 | + oldX, oldY, w, h, | |
| 359 | + newX, newY, w, h); | |
| 360 | + this._damage(newX, newY, w, h); | |
| 361 | + } | |
| 362 | + } | |
| 363 | + | |
| 364 | + imageRect(x, y, width, height, mime, arr) { | |
| 365 | + /* The internal logic cannot handle empty images, so bail early */ | |
| 366 | + if ((width === 0) || (height === 0)) { | |
| 367 | + return; | |
| 368 | + } | |
| 369 | + | |
| 370 | + const img = new Image(); | |
| 371 | + img.src = "data: " + mime + ";base64," + Base64.encode(arr); | |
| 372 | + | |
| 373 | + this._renderQPush({ | |
| 374 | + 'type': 'img', | |
| 375 | + 'img': img, | |
| 376 | + 'x': x, | |
| 377 | + 'y': y, | |
| 378 | + 'width': width, | |
| 379 | + 'height': height | |
| 380 | + }); | |
| 381 | + } | |
| 382 | + | |
| 383 | + videoFrame(x, y, width, height, frame) { | |
| 384 | + this._renderQPush({ | |
| 385 | + 'type': 'frame', | |
| 386 | + 'frame': frame, | |
| 387 | + 'x': x, | |
| 388 | + 'y': y, | |
| 389 | + 'width': width, | |
| 390 | + 'height': height | |
| 391 | + }); | |
| 392 | + } | |
| 393 | + | |
| 394 | + blitImage(x, y, width, height, arr, offset, fromQueue) { | |
| 395 | + if (this._renderQ.length !== 0 && !fromQueue) { | |
| 396 | + // NB(directxman12): it's technically more performant here to use preallocated arrays, | |
| 397 | + // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue, | |
| 398 | + // this probably isn't getting called *nearly* as much | |
| 399 | + const newArr = new Uint8Array(width * height * 4); | |
| 400 | + newArr.set(new Uint8Array(arr.buffer, 0, newArr.length)); | |
| 401 | + this._renderQPush({ | |
| 402 | + 'type': 'blit', | |
| 403 | + 'data': newArr, | |
| 404 | + 'x': x, | |
| 405 | + 'y': y, | |
| 406 | + 'width': width, | |
| 407 | + 'height': height, | |
| 408 | + }); | |
| 409 | + } else { | |
| 410 | + // NB(directxman12): arr must be an Type Array view | |
| 411 | + let data = new Uint8ClampedArray(arr.buffer, | |
| 412 | + arr.byteOffset + offset, | |
| 413 | + width * height * 4); | |
| 414 | + let img = new ImageData(data, width, height); | |
| 415 | + this._drawCtx.putImageData(img, x, y); | |
| 416 | + this._damage(x, y, width, height); | |
| 417 | + } | |
| 418 | + } | |
| 419 | + | |
| 420 | + drawImage(img, ...args) { | |
| 421 | + this._drawCtx.drawImage(img, ...args); | |
| 422 | + | |
| 423 | + if (args.length <= 4) { | |
| 424 | + const [x, y] = args; | |
| 425 | + this._damage(x, y, img.width, img.height); | |
| 426 | + } else { | |
| 427 | + const [,, sw, sh, dx, dy] = args; | |
| 428 | + this._damage(dx, dy, sw, sh); | |
| 429 | + } | |
| 430 | + } | |
| 431 | + | |
| 432 | + autoscale(containerWidth, containerHeight) { | |
| 433 | + let scaleRatio; | |
| 434 | + | |
| 435 | + if (containerWidth === 0 || containerHeight === 0) { | |
| 436 | + scaleRatio = 0; | |
| 437 | + | |
| 438 | + } else { | |
| 439 | + | |
| 440 | + const vp = this._viewportLoc; | |
| 441 | + const targetAspectRatio = containerWidth / containerHeight; | |
| 442 | + const fbAspectRatio = vp.w / vp.h; | |
| 443 | + | |
| 444 | + if (fbAspectRatio >= targetAspectRatio) { | |
| 445 | + scaleRatio = containerWidth / vp.w; | |
| 446 | + } else { | |
| 447 | + scaleRatio = containerHeight / vp.h; | |
| 448 | + } | |
| 449 | + } | |
| 450 | + | |
| 451 | + this._rescale(scaleRatio); | |
| 452 | + } | |
| 453 | + | |
| 454 | + // ===== PRIVATE METHODS ===== | |
| 455 | + | |
| 456 | + _rescale(factor) { | |
| 457 | + this._scale = factor; | |
| 458 | + const vp = this._viewportLoc; | |
| 459 | + | |
| 460 | + // NB(directxman12): If you set the width directly, or set the | |
| 461 | + // style width to a number, the canvas is cleared. | |
| 462 | + // However, if you set the style width to a string | |
| 463 | + // ('NNNpx'), the canvas is scaled without clearing. | |
| 464 | + const width = factor * vp.w + 'px'; | |
| 465 | + const height = factor * vp.h + 'px'; | |
| 466 | + | |
| 467 | + if ((this._target.style.width !== width) || | |
| 468 | + (this._target.style.height !== height)) { | |
| 469 | + this._target.style.width = width; | |
| 470 | + this._target.style.height = height; | |
| 471 | + } | |
| 472 | + } | |
| 473 | + | |
| 474 | + _setFillColor(color) { | |
| 475 | + const newStyle = 'rgb(' + color[0] + ',' + color[1] + ',' + color[2] + ')'; | |
| 476 | + if (newStyle !== this._prevDrawStyle) { | |
| 477 | + this._drawCtx.fillStyle = newStyle; | |
| 478 | + this._prevDrawStyle = newStyle; | |
| 479 | + } | |
| 480 | + } | |
| 481 | + | |
| 482 | + _renderQPush(action) { | |
| 483 | + this._renderQ.push(action); | |
| 484 | + if (this._renderQ.length === 1) { | |
| 485 | + // If this can be rendered immediately it will be, otherwise | |
| 486 | + // the scanner will wait for the relevant event | |
| 487 | + this._scanRenderQ(); | |
| 488 | + } | |
| 489 | + } | |
| 490 | + | |
| 491 | + _resumeRenderQ() { | |
| 492 | + // "this" is the object that is ready, not the | |
| 493 | + // display object | |
| 494 | + this.removeEventListener('load', this._noVNCDisplay._resumeRenderQ); | |
| 495 | + this._noVNCDisplay._scanRenderQ(); | |
| 496 | + } | |
| 497 | + | |
| 498 | + _scanRenderQ() { | |
| 499 | + let ready = true; | |
| 500 | + while (ready && this._renderQ.length > 0) { | |
| 501 | + const a = this._renderQ[0]; | |
| 502 | + switch (a.type) { | |
| 503 | + case 'flip': | |
| 504 | + this.flip(true); | |
| 505 | + break; | |
| 506 | + case 'copy': | |
| 507 | + this.copyImage(a.oldX, a.oldY, a.x, a.y, a.width, a.height, true); | |
| 508 | + break; | |
| 509 | + case 'fill': | |
| 510 | + this.fillRect(a.x, a.y, a.width, a.height, a.color, true); | |
| 511 | + break; | |
| 512 | + case 'blit': | |
| 513 | + this.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true); | |
| 514 | + break; | |
| 515 | + case 'img': | |
| 516 | + if (a.img.complete) { | |
| 517 | + if (a.img.width !== a.width || a.img.height !== a.height) { | |
| 518 | + Log.Error("Decoded image has incorrect dimensions. Got " + | |
| 519 | + a.img.width + "x" + a.img.height + ". Expected " + | |
| 520 | + a.width + "x" + a.height + "."); | |
| 521 | + return; | |
| 522 | + } | |
| 523 | + this.drawImage(a.img, a.x, a.y); | |
| 524 | + } else { | |
| 525 | + a.img._noVNCDisplay = this; | |
| 526 | + a.img.addEventListener('load', this._resumeRenderQ); | |
| 527 | + // We need to wait for this image to 'load' | |
| 528 | + // to keep things in-order | |
| 529 | + ready = false; | |
| 530 | + } | |
| 531 | + break; | |
| 532 | + case 'frame': | |
| 533 | + if (a.frame.ready) { | |
| 534 | + // The encoded frame may be larger than the rect due to | |
| 535 | + // limitations of the encoder, so we need to crop the | |
| 536 | + // frame. | |
| 537 | + let frame = a.frame.frame; | |
| 538 | + if (frame.codedWidth < a.width || frame.codedHeight < a.height) { | |
| 539 | + Log.Warn("Decoded video frame does not cover its full rectangle area. Expecting at least " + | |
| 540 | + a.width + "x" + a.height + " but got " + | |
| 541 | + frame.codedWidth + "x" + frame.codedHeight); | |
| 542 | + } | |
| 543 | + const sx = 0; | |
| 544 | + const sy = 0; | |
| 545 | + const sw = a.width; | |
| 546 | + const sh = a.height; | |
| 547 | + const dx = a.x; | |
| 548 | + const dy = a.y; | |
| 549 | + const dw = sw; | |
| 550 | + const dh = sh; | |
| 551 | + this.drawImage(frame, sx, sy, sw, sh, dx, dy, dw, dh); | |
| 552 | + frame.close(); | |
| 553 | + } else { | |
| 554 | + let display = this; | |
| 555 | + a.frame.promise.then(() => { | |
| 556 | + display._scanRenderQ(); | |
| 557 | + }); | |
| 558 | + ready = false; | |
| 559 | + } | |
| 560 | + break; | |
| 561 | + } | |
| 562 | + | |
| 563 | + if (ready) { | |
| 564 | + this._renderQ.shift(); | |
| 565 | + } | |
| 566 | + } | |
| 567 | + | |
| 568 | + if (this._renderQ.length === 0 && | |
| 569 | + this._flushPromise !== null) { | |
| 570 | + this._flushResolve(); | |
| 571 | + this._flushPromise = null; | |
| 572 | + this._flushResolve = null; | |
| 573 | + } | |
| 574 | + } | |
| 575 | +} | |
added
public/vendor/novnc/core/encodings.js
+54 −0
@@ -0,0 +1,54 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +export const encodings = { | |
| 10 | + encodingRaw: 0, | |
| 11 | + encodingCopyRect: 1, | |
| 12 | + encodingRRE: 2, | |
| 13 | + encodingHextile: 5, | |
| 14 | + encodingZlib: 6, | |
| 15 | + encodingTight: 7, | |
| 16 | + encodingZRLE: 16, | |
| 17 | + encodingTightPNG: -260, | |
| 18 | + encodingJPEG: 21, | |
| 19 | + encodingH264: 50, | |
| 20 | + | |
| 21 | + pseudoEncodingQualityLevel9: -23, | |
| 22 | + pseudoEncodingQualityLevel0: -32, | |
| 23 | + pseudoEncodingDesktopSize: -223, | |
| 24 | + pseudoEncodingLastRect: -224, | |
| 25 | + pseudoEncodingCursor: -239, | |
| 26 | + pseudoEncodingQEMUExtendedKeyEvent: -258, | |
| 27 | + pseudoEncodingQEMULedEvent: -261, | |
| 28 | + pseudoEncodingDesktopName: -307, | |
| 29 | + pseudoEncodingExtendedDesktopSize: -308, | |
| 30 | + pseudoEncodingXvp: -309, | |
| 31 | + pseudoEncodingFence: -312, | |
| 32 | + pseudoEncodingContinuousUpdates: -313, | |
| 33 | + pseudoEncodingExtendedMouseButtons: -316, | |
| 34 | + pseudoEncodingCompressLevel9: -247, | |
| 35 | + pseudoEncodingCompressLevel0: -256, | |
| 36 | + pseudoEncodingVMwareCursor: 0x574d5664, | |
| 37 | + pseudoEncodingExtendedClipboard: 0xc0a1e5ce | |
| 38 | +}; | |
| 39 | + | |
| 40 | +export function encodingName(num) { | |
| 41 | + switch (num) { | |
| 42 | + case encodings.encodingRaw: return "Raw"; | |
| 43 | + case encodings.encodingCopyRect: return "CopyRect"; | |
| 44 | + case encodings.encodingRRE: return "RRE"; | |
| 45 | + case encodings.encodingHextile: return "Hextile"; | |
| 46 | + case encodings.encodingZlib: return "Zlib"; | |
| 47 | + case encodings.encodingTight: return "Tight"; | |
| 48 | + case encodings.encodingZRLE: return "ZRLE"; | |
| 49 | + case encodings.encodingTightPNG: return "TightPNG"; | |
| 50 | + case encodings.encodingJPEG: return "JPEG"; | |
| 51 | + case encodings.encodingH264: return "H.264"; | |
| 52 | + default: return "[unknown encoding " + num + "]"; | |
| 53 | + } | |
| 54 | +} | |
added
public/vendor/novnc/core/inflator.js
+65 −0
@@ -0,0 +1,65 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2020 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +import { inflateInit, inflate, inflateReset } from "../vendor/pako/lib/zlib/inflate.js"; | |
| 10 | +import ZStream from "../vendor/pako/lib/zlib/zstream.js"; | |
| 11 | + | |
| 12 | +export default class Inflate { | |
| 13 | + constructor() { | |
| 14 | + this.strm = new ZStream(); | |
| 15 | + this.chunkSize = 1024 * 10 * 10; | |
| 16 | + this.strm.output = new Uint8Array(this.chunkSize); | |
| 17 | + | |
| 18 | + inflateInit(this.strm); | |
| 19 | + } | |
| 20 | + | |
| 21 | + setInput(data) { | |
| 22 | + if (!data) { | |
| 23 | + //FIXME: flush remaining data. | |
| 24 | + /* eslint-disable camelcase */ | |
| 25 | + this.strm.input = null; | |
| 26 | + this.strm.avail_in = 0; | |
| 27 | + this.strm.next_in = 0; | |
| 28 | + } else { | |
| 29 | + this.strm.input = data; | |
| 30 | + this.strm.avail_in = this.strm.input.length; | |
| 31 | + this.strm.next_in = 0; | |
| 32 | + /* eslint-enable camelcase */ | |
| 33 | + } | |
| 34 | + } | |
| 35 | + | |
| 36 | + inflate(expected) { | |
| 37 | + // resize our output buffer if it's too small | |
| 38 | + // (we could just use multiple chunks, but that would cause an extra | |
| 39 | + // allocation each time to flatten the chunks) | |
| 40 | + if (expected > this.chunkSize) { | |
| 41 | + this.chunkSize = expected; | |
| 42 | + this.strm.output = new Uint8Array(this.chunkSize); | |
| 43 | + } | |
| 44 | + | |
| 45 | + /* eslint-disable camelcase */ | |
| 46 | + this.strm.next_out = 0; | |
| 47 | + this.strm.avail_out = expected; | |
| 48 | + /* eslint-enable camelcase */ | |
| 49 | + | |
| 50 | + let ret = inflate(this.strm, 0); // Flush argument not used. | |
| 51 | + if (ret < 0) { | |
| 52 | + throw new Error("zlib inflate failed"); | |
| 53 | + } | |
| 54 | + | |
| 55 | + if (this.strm.next_out != expected) { | |
| 56 | + throw new Error("Incomplete zlib block"); | |
| 57 | + } | |
| 58 | + | |
| 59 | + return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); | |
| 60 | + } | |
| 61 | + | |
| 62 | + reset() { | |
| 63 | + inflateReset(this.strm); | |
| 64 | + } | |
| 65 | +} | |
added
public/vendor/novnc/core/input/domkeytable.js
+311 −0
@@ -0,0 +1,311 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2018 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | |
| 5 | + */ | |
| 6 | + | |
| 7 | +import KeyTable from "./keysym.js"; | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * Mapping between HTML key values and VNC/X11 keysyms for "special" | |
| 11 | + * keys that cannot be handled via their Unicode codepoint. | |
| 12 | + * | |
| 13 | + * See https://www.w3.org/TR/uievents-key/ for possible values. | |
| 14 | + */ | |
| 15 | + | |
| 16 | +const DOMKeyTable = {}; | |
| 17 | + | |
| 18 | +function addStandard(key, standard) { | |
| 19 | + if (standard === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | |
| 20 | + if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\""); | |
| 21 | + DOMKeyTable[key] = [standard, standard, standard, standard]; | |
| 22 | +} | |
| 23 | + | |
| 24 | +function addLeftRight(key, left, right) { | |
| 25 | + if (left === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | |
| 26 | + if (right === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | |
| 27 | + if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\""); | |
| 28 | + DOMKeyTable[key] = [left, left, right, left]; | |
| 29 | +} | |
| 30 | + | |
| 31 | +function addNumpad(key, standard, numpad) { | |
| 32 | + if (standard === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | |
| 33 | + if (numpad === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | |
| 34 | + if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\""); | |
| 35 | + DOMKeyTable[key] = [standard, standard, standard, numpad]; | |
| 36 | +} | |
| 37 | + | |
| 38 | +// 3.2. Modifier Keys | |
| 39 | + | |
| 40 | +addLeftRight("Alt", KeyTable.XK_Alt_L, KeyTable.XK_Alt_R); | |
| 41 | +addStandard("AltGraph", KeyTable.XK_ISO_Level3_Shift); | |
| 42 | +addStandard("CapsLock", KeyTable.XK_Caps_Lock); | |
| 43 | +addLeftRight("Control", KeyTable.XK_Control_L, KeyTable.XK_Control_R); | |
| 44 | +// - Fn | |
| 45 | +// - FnLock | |
| 46 | +addLeftRight("Meta", KeyTable.XK_Super_L, KeyTable.XK_Super_R); | |
| 47 | +addStandard("NumLock", KeyTable.XK_Num_Lock); | |
| 48 | +addStandard("ScrollLock", KeyTable.XK_Scroll_Lock); | |
| 49 | +addLeftRight("Shift", KeyTable.XK_Shift_L, KeyTable.XK_Shift_R); | |
| 50 | +// - Symbol | |
| 51 | +// - SymbolLock | |
| 52 | +// - Hyper | |
| 53 | +// - Super | |
| 54 | + | |
| 55 | +// 3.3. Whitespace Keys | |
| 56 | + | |
| 57 | +addNumpad("Enter", KeyTable.XK_Return, KeyTable.XK_KP_Enter); | |
| 58 | +addStandard("Tab", KeyTable.XK_Tab); | |
| 59 | +addNumpad(" ", KeyTable.XK_space, KeyTable.XK_KP_Space); | |
| 60 | + | |
| 61 | +// 3.4. Navigation Keys | |
| 62 | + | |
| 63 | +addNumpad("ArrowDown", KeyTable.XK_Down, KeyTable.XK_KP_Down); | |
| 64 | +addNumpad("ArrowLeft", KeyTable.XK_Left, KeyTable.XK_KP_Left); | |
| 65 | +addNumpad("ArrowRight", KeyTable.XK_Right, KeyTable.XK_KP_Right); | |
| 66 | +addNumpad("ArrowUp", KeyTable.XK_Up, KeyTable.XK_KP_Up); | |
| 67 | +addNumpad("End", KeyTable.XK_End, KeyTable.XK_KP_End); | |
| 68 | +addNumpad("Home", KeyTable.XK_Home, KeyTable.XK_KP_Home); | |
| 69 | +addNumpad("PageDown", KeyTable.XK_Next, KeyTable.XK_KP_Next); | |
| 70 | +addNumpad("PageUp", KeyTable.XK_Prior, KeyTable.XK_KP_Prior); | |
| 71 | + | |
| 72 | +// 3.5. Editing Keys | |
| 73 | + | |
| 74 | +addStandard("Backspace", KeyTable.XK_BackSpace); | |
| 75 | +// Browsers send "Clear" for the numpad 5 without NumLock because | |
| 76 | +// Windows uses VK_Clear for that key. But Unix expects KP_Begin for | |
| 77 | +// that scenario. | |
| 78 | +addNumpad("Clear", KeyTable.XK_Clear, KeyTable.XK_KP_Begin); | |
| 79 | +addStandard("Copy", KeyTable.XF86XK_Copy); | |
| 80 | +// - CrSel | |
| 81 | +addStandard("Cut", KeyTable.XF86XK_Cut); | |
| 82 | +addNumpad("Delete", KeyTable.XK_Delete, KeyTable.XK_KP_Delete); | |
| 83 | +// - EraseEof | |
| 84 | +// - ExSel | |
| 85 | +addNumpad("Insert", KeyTable.XK_Insert, KeyTable.XK_KP_Insert); | |
| 86 | +addStandard("Paste", KeyTable.XF86XK_Paste); | |
| 87 | +addStandard("Redo", KeyTable.XK_Redo); | |
| 88 | +addStandard("Undo", KeyTable.XK_Undo); | |
| 89 | + | |
| 90 | +// 3.6. UI Keys | |
| 91 | + | |
| 92 | +// - Accept | |
| 93 | +// - Again (could just be XK_Redo) | |
| 94 | +// - Attn | |
| 95 | +addStandard("Cancel", KeyTable.XK_Cancel); | |
| 96 | +addStandard("ContextMenu", KeyTable.XK_Menu); | |
| 97 | +addStandard("Escape", KeyTable.XK_Escape); | |
| 98 | +addStandard("Execute", KeyTable.XK_Execute); | |
| 99 | +addStandard("Find", KeyTable.XK_Find); | |
| 100 | +addStandard("Help", KeyTable.XK_Help); | |
| 101 | +addStandard("Pause", KeyTable.XK_Pause); | |
| 102 | +// - Play | |
| 103 | +// - Props | |
| 104 | +addStandard("Select", KeyTable.XK_Select); | |
| 105 | +addStandard("ZoomIn", KeyTable.XF86XK_ZoomIn); | |
| 106 | +addStandard("ZoomOut", KeyTable.XF86XK_ZoomOut); | |
| 107 | + | |
| 108 | +// 3.7. Device Keys | |
| 109 | + | |
| 110 | +addStandard("BrightnessDown", KeyTable.XF86XK_MonBrightnessDown); | |
| 111 | +addStandard("BrightnessUp", KeyTable.XF86XK_MonBrightnessUp); | |
| 112 | +addStandard("Eject", KeyTable.XF86XK_Eject); | |
| 113 | +addStandard("LogOff", KeyTable.XF86XK_LogOff); | |
| 114 | +addStandard("Power", KeyTable.XF86XK_PowerOff); | |
| 115 | +addStandard("PowerOff", KeyTable.XF86XK_PowerDown); | |
| 116 | +addStandard("PrintScreen", KeyTable.XK_Print); | |
| 117 | +addStandard("Hibernate", KeyTable.XF86XK_Hibernate); | |
| 118 | +addStandard("Standby", KeyTable.XF86XK_Standby); | |
| 119 | +addStandard("WakeUp", KeyTable.XF86XK_WakeUp); | |
| 120 | + | |
| 121 | +// 3.8. IME and Composition Keys | |
| 122 | + | |
| 123 | +addStandard("AllCandidates", KeyTable.XK_MultipleCandidate); | |
| 124 | +addStandard("Alphanumeric", KeyTable.XK_Eisu_toggle); | |
| 125 | +addStandard("CodeInput", KeyTable.XK_Codeinput); | |
| 126 | +addStandard("Compose", KeyTable.XK_Multi_key); | |
| 127 | +addStandard("Convert", KeyTable.XK_Henkan); | |
| 128 | +// - Dead | |
| 129 | +// - FinalMode | |
| 130 | +addStandard("GroupFirst", KeyTable.XK_ISO_First_Group); | |
| 131 | +addStandard("GroupLast", KeyTable.XK_ISO_Last_Group); | |
| 132 | +addStandard("GroupNext", KeyTable.XK_ISO_Next_Group); | |
| 133 | +addStandard("GroupPrevious", KeyTable.XK_ISO_Prev_Group); | |
| 134 | +// - ModeChange (XK_Mode_switch is often used for AltGr) | |
| 135 | +// - NextCandidate | |
| 136 | +addStandard("NonConvert", KeyTable.XK_Muhenkan); | |
| 137 | +addStandard("PreviousCandidate", KeyTable.XK_PreviousCandidate); | |
| 138 | +// - Process | |
| 139 | +addStandard("SingleCandidate", KeyTable.XK_SingleCandidate); | |
| 140 | +addStandard("HangulMode", KeyTable.XK_Hangul); | |
| 141 | +addStandard("HanjaMode", KeyTable.XK_Hangul_Hanja); | |
| 142 | +addStandard("JunjaMode", KeyTable.XK_Hangul_Jeonja); | |
| 143 | +addStandard("Eisu", KeyTable.XK_Eisu_toggle); | |
| 144 | +addStandard("Hankaku", KeyTable.XK_Hankaku); | |
| 145 | +addStandard("Hiragana", KeyTable.XK_Hiragana); | |
| 146 | +addStandard("HiraganaKatakana", KeyTable.XK_Hiragana_Katakana); | |
| 147 | +addStandard("KanaMode", KeyTable.XK_Kana_Shift); // could also be _Kana_Lock | |
| 148 | +addStandard("KanjiMode", KeyTable.XK_Kanji); | |
| 149 | +addStandard("Katakana", KeyTable.XK_Katakana); | |
| 150 | +addStandard("Romaji", KeyTable.XK_Romaji); | |
| 151 | +addStandard("Zenkaku", KeyTable.XK_Zenkaku); | |
| 152 | +addStandard("ZenkakuHankaku", KeyTable.XK_Zenkaku_Hankaku); | |
| 153 | + | |
| 154 | +// 3.9. General-Purpose Function Keys | |
| 155 | + | |
| 156 | +addStandard("F1", KeyTable.XK_F1); | |
| 157 | +addStandard("F2", KeyTable.XK_F2); | |
| 158 | +addStandard("F3", KeyTable.XK_F3); | |
| 159 | +addStandard("F4", KeyTable.XK_F4); | |
| 160 | +addStandard("F5", KeyTable.XK_F5); | |
| 161 | +addStandard("F6", KeyTable.XK_F6); | |
| 162 | +addStandard("F7", KeyTable.XK_F7); | |
| 163 | +addStandard("F8", KeyTable.XK_F8); | |
| 164 | +addStandard("F9", KeyTable.XK_F9); | |
| 165 | +addStandard("F10", KeyTable.XK_F10); | |
| 166 | +addStandard("F11", KeyTable.XK_F11); | |
| 167 | +addStandard("F12", KeyTable.XK_F12); | |
| 168 | +addStandard("F13", KeyTable.XK_F13); | |
| 169 | +addStandard("F14", KeyTable.XK_F14); | |
| 170 | +addStandard("F15", KeyTable.XK_F15); | |
| 171 | +addStandard("F16", KeyTable.XK_F16); | |
| 172 | +addStandard("F17", KeyTable.XK_F17); | |
| 173 | +addStandard("F18", KeyTable.XK_F18); | |
| 174 | +addStandard("F19", KeyTable.XK_F19); | |
| 175 | +addStandard("F20", KeyTable.XK_F20); | |
| 176 | +addStandard("F21", KeyTable.XK_F21); | |
| 177 | +addStandard("F22", KeyTable.XK_F22); | |
| 178 | +addStandard("F23", KeyTable.XK_F23); | |
| 179 | +addStandard("F24", KeyTable.XK_F24); | |
| 180 | +addStandard("F25", KeyTable.XK_F25); | |
| 181 | +addStandard("F26", KeyTable.XK_F26); | |
| 182 | +addStandard("F27", KeyTable.XK_F27); | |
| 183 | +addStandard("F28", KeyTable.XK_F28); | |
| 184 | +addStandard("F29", KeyTable.XK_F29); | |
| 185 | +addStandard("F30", KeyTable.XK_F30); | |
| 186 | +addStandard("F31", KeyTable.XK_F31); | |
| 187 | +addStandard("F32", KeyTable.XK_F32); | |
| 188 | +addStandard("F33", KeyTable.XK_F33); | |
| 189 | +addStandard("F34", KeyTable.XK_F34); | |
| 190 | +addStandard("F35", KeyTable.XK_F35); | |
| 191 | +// - Soft1... | |
| 192 | + | |
| 193 | +// 3.10. Multimedia Keys | |
| 194 | + | |
| 195 | +// - ChannelDown | |
| 196 | +// - ChannelUp | |
| 197 | +addStandard("Close", KeyTable.XF86XK_Close); | |
| 198 | +addStandard("MailForward", KeyTable.XF86XK_MailForward); | |
| 199 | +addStandard("MailReply", KeyTable.XF86XK_Reply); | |
| 200 | +addStandard("MailSend", KeyTable.XF86XK_Send); | |
| 201 | +// - MediaClose | |
| 202 | +addStandard("MediaFastForward", KeyTable.XF86XK_AudioForward); | |
| 203 | +addStandard("MediaPause", KeyTable.XF86XK_AudioPause); | |
| 204 | +addStandard("MediaPlay", KeyTable.XF86XK_AudioPlay); | |
| 205 | +// - MediaPlayPause | |
| 206 | +addStandard("MediaRecord", KeyTable.XF86XK_AudioRecord); | |
| 207 | +addStandard("MediaRewind", KeyTable.XF86XK_AudioRewind); | |
| 208 | +addStandard("MediaStop", KeyTable.XF86XK_AudioStop); | |
| 209 | +addStandard("MediaTrackNext", KeyTable.XF86XK_AudioNext); | |
| 210 | +addStandard("MediaTrackPrevious", KeyTable.XF86XK_AudioPrev); | |
| 211 | +addStandard("New", KeyTable.XF86XK_New); | |
| 212 | +addStandard("Open", KeyTable.XF86XK_Open); | |
| 213 | +addStandard("Print", KeyTable.XK_Print); | |
| 214 | +addStandard("Save", KeyTable.XF86XK_Save); | |
| 215 | +addStandard("SpellCheck", KeyTable.XF86XK_Spell); | |
| 216 | + | |
| 217 | +// 3.11. Multimedia Numpad Keys | |
| 218 | + | |
| 219 | +// - Key11 | |
| 220 | +// - Key12 | |
| 221 | + | |
| 222 | +// 3.12. Audio Keys | |
| 223 | + | |
| 224 | +// - AudioBalanceLeft | |
| 225 | +// - AudioBalanceRight | |
| 226 | +// - AudioBassBoostDown | |
| 227 | +// - AudioBassBoostToggle | |
| 228 | +// - AudioBassBoostUp | |
| 229 | +// - AudioFaderFront | |
| 230 | +// - AudioFaderRear | |
| 231 | +// - AudioSurroundModeNext | |
| 232 | +// - AudioTrebleDown | |
| 233 | +// - AudioTrebleUp | |
| 234 | +addStandard("AudioVolumeDown", KeyTable.XF86XK_AudioLowerVolume); | |
| 235 | +addStandard("AudioVolumeUp", KeyTable.XF86XK_AudioRaiseVolume); | |
| 236 | +addStandard("AudioVolumeMute", KeyTable.XF86XK_AudioMute); | |
| 237 | +// - MicrophoneToggle | |
| 238 | +// - MicrophoneVolumeDown | |
| 239 | +// - MicrophoneVolumeUp | |
| 240 | +addStandard("MicrophoneVolumeMute", KeyTable.XF86XK_AudioMicMute); | |
| 241 | + | |
| 242 | +// 3.13. Speech Keys | |
| 243 | + | |
| 244 | +// - SpeechCorrectionList | |
| 245 | +// - SpeechInputToggle | |
| 246 | + | |
| 247 | +// 3.14. Application Keys | |
| 248 | + | |
| 249 | +addStandard("LaunchApplication1", KeyTable.XF86XK_MyComputer); | |
| 250 | +addStandard("LaunchApplication2", KeyTable.XF86XK_Calculator); | |
| 251 | +addStandard("LaunchCalendar", KeyTable.XF86XK_Calendar); | |
| 252 | +// - LaunchContacts | |
| 253 | +addStandard("LaunchMail", KeyTable.XF86XK_Mail); | |
| 254 | +addStandard("LaunchMediaPlayer", KeyTable.XF86XK_AudioMedia); | |
| 255 | +addStandard("LaunchMusicPlayer", KeyTable.XF86XK_Music); | |
| 256 | +addStandard("LaunchPhone", KeyTable.XF86XK_Phone); | |
| 257 | +addStandard("LaunchScreenSaver", KeyTable.XF86XK_ScreenSaver); | |
| 258 | +addStandard("LaunchSpreadsheet", KeyTable.XF86XK_Excel); | |
| 259 | +addStandard("LaunchWebBrowser", KeyTable.XF86XK_WWW); | |
| 260 | +addStandard("LaunchWebCam", KeyTable.XF86XK_WebCam); | |
| 261 | +addStandard("LaunchWordProcessor", KeyTable.XF86XK_Word); | |
| 262 | + | |
| 263 | +// 3.15. Browser Keys | |
| 264 | + | |
| 265 | +addStandard("BrowserBack", KeyTable.XF86XK_Back); | |
| 266 | +addStandard("BrowserFavorites", KeyTable.XF86XK_Favorites); | |
| 267 | +addStandard("BrowserForward", KeyTable.XF86XK_Forward); | |
| 268 | +addStandard("BrowserHome", KeyTable.XF86XK_HomePage); | |
| 269 | +addStandard("BrowserRefresh", KeyTable.XF86XK_Refresh); | |
| 270 | +addStandard("BrowserSearch", KeyTable.XF86XK_Search); | |
| 271 | +addStandard("BrowserStop", KeyTable.XF86XK_Stop); | |
| 272 | + | |
| 273 | +// 3.16. Mobile Phone Keys | |
| 274 | + | |
| 275 | +// - A whole bunch... | |
| 276 | + | |
| 277 | +// 3.17. TV Keys | |
| 278 | + | |
| 279 | +// - A whole bunch... | |
| 280 | + | |
| 281 | +// 3.18. Media Controller Keys | |
| 282 | + | |
| 283 | +// - A whole bunch... | |
| 284 | +addStandard("Dimmer", KeyTable.XF86XK_BrightnessAdjust); | |
| 285 | +addStandard("MediaAudioTrack", KeyTable.XF86XK_AudioCycleTrack); | |
| 286 | +addStandard("RandomToggle", KeyTable.XF86XK_AudioRandomPlay); | |
| 287 | +addStandard("SplitScreenToggle", KeyTable.XF86XK_SplitScreen); | |
| 288 | +addStandard("Subtitle", KeyTable.XF86XK_Subtitle); | |
| 289 | +addStandard("VideoModeNext", KeyTable.XF86XK_Next_VMode); | |
| 290 | + | |
| 291 | +// Extra: Numpad | |
| 292 | + | |
| 293 | +addNumpad("=", KeyTable.XK_equal, KeyTable.XK_KP_Equal); | |
| 294 | +addNumpad("+", KeyTable.XK_plus, KeyTable.XK_KP_Add); | |
| 295 | +addNumpad("-", KeyTable.XK_minus, KeyTable.XK_KP_Subtract); | |
| 296 | +addNumpad("*", KeyTable.XK_asterisk, KeyTable.XK_KP_Multiply); | |
| 297 | +addNumpad("/", KeyTable.XK_slash, KeyTable.XK_KP_Divide); | |
| 298 | +addNumpad(".", KeyTable.XK_period, KeyTable.XK_KP_Decimal); | |
| 299 | +addNumpad(",", KeyTable.XK_comma, KeyTable.XK_KP_Separator); | |
| 300 | +addNumpad("0", KeyTable.XK_0, KeyTable.XK_KP_0); | |
| 301 | +addNumpad("1", KeyTable.XK_1, KeyTable.XK_KP_1); | |
| 302 | +addNumpad("2", KeyTable.XK_2, KeyTable.XK_KP_2); | |
| 303 | +addNumpad("3", KeyTable.XK_3, KeyTable.XK_KP_3); | |
| 304 | +addNumpad("4", KeyTable.XK_4, KeyTable.XK_KP_4); | |
| 305 | +addNumpad("5", KeyTable.XK_5, KeyTable.XK_KP_5); | |
| 306 | +addNumpad("6", KeyTable.XK_6, KeyTable.XK_KP_6); | |
| 307 | +addNumpad("7", KeyTable.XK_7, KeyTable.XK_KP_7); | |
| 308 | +addNumpad("8", KeyTable.XK_8, KeyTable.XK_KP_8); | |
| 309 | +addNumpad("9", KeyTable.XK_9, KeyTable.XK_KP_9); | |
| 310 | + | |
| 311 | +export default DOMKeyTable; | |
added
public/vendor/novnc/core/input/fixedkeys.js
+129 −0
@@ -0,0 +1,129 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2018 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | |
| 5 | + */ | |
| 6 | + | |
| 7 | +/* | |
| 8 | + * Fallback mapping between HTML key codes (physical keys) and | |
| 9 | + * HTML key values. This only works for keys that don't vary | |
| 10 | + * between layouts. We also omit those who manage fine by mapping the | |
| 11 | + * Unicode representation. | |
| 12 | + * | |
| 13 | + * See https://www.w3.org/TR/uievents-code/ for possible codes. | |
| 14 | + * See https://www.w3.org/TR/uievents-key/ for possible values. | |
| 15 | + */ | |
| 16 | + | |
| 17 | +/* eslint-disable key-spacing */ | |
| 18 | + | |
| 19 | +export default { | |
| 20 | + | |
| 21 | +// 3.1.1.1. Writing System Keys | |
| 22 | + | |
| 23 | + 'Backspace': 'Backspace', | |
| 24 | + | |
| 25 | +// 3.1.1.2. Functional Keys | |
| 26 | + | |
| 27 | + 'AltLeft': 'Alt', | |
| 28 | + 'AltRight': 'Alt', // This could also be 'AltGraph' | |
| 29 | + 'CapsLock': 'CapsLock', | |
| 30 | + 'ContextMenu': 'ContextMenu', | |
| 31 | + 'ControlLeft': 'Control', | |
| 32 | + 'ControlRight': 'Control', | |
| 33 | + 'Enter': 'Enter', | |
| 34 | + 'MetaLeft': 'Meta', | |
| 35 | + 'MetaRight': 'Meta', | |
| 36 | + 'ShiftLeft': 'Shift', | |
| 37 | + 'ShiftRight': 'Shift', | |
| 38 | + 'Tab': 'Tab', | |
| 39 | + // FIXME: Japanese/Korean keys | |
| 40 | + | |
| 41 | +// 3.1.2. Control Pad Section | |
| 42 | + | |
| 43 | + 'Delete': 'Delete', | |
| 44 | + 'End': 'End', | |
| 45 | + 'Help': 'Help', | |
| 46 | + 'Home': 'Home', | |
| 47 | + 'Insert': 'Insert', | |
| 48 | + 'PageDown': 'PageDown', | |
| 49 | + 'PageUp': 'PageUp', | |
| 50 | + | |
| 51 | +// 3.1.3. Arrow Pad Section | |
| 52 | + | |
| 53 | + 'ArrowDown': 'ArrowDown', | |
| 54 | + 'ArrowLeft': 'ArrowLeft', | |
| 55 | + 'ArrowRight': 'ArrowRight', | |
| 56 | + 'ArrowUp': 'ArrowUp', | |
| 57 | + | |
| 58 | +// 3.1.4. Numpad Section | |
| 59 | + | |
| 60 | + 'NumLock': 'NumLock', | |
| 61 | + 'NumpadBackspace': 'Backspace', | |
| 62 | + 'NumpadClear': 'Clear', | |
| 63 | + | |
| 64 | +// 3.1.5. Function Section | |
| 65 | + | |
| 66 | + 'Escape': 'Escape', | |
| 67 | + 'F1': 'F1', | |
| 68 | + 'F2': 'F2', | |
| 69 | + 'F3': 'F3', | |
| 70 | + 'F4': 'F4', | |
| 71 | + 'F5': 'F5', | |
| 72 | + 'F6': 'F6', | |
| 73 | + 'F7': 'F7', | |
| 74 | + 'F8': 'F8', | |
| 75 | + 'F9': 'F9', | |
| 76 | + 'F10': 'F10', | |
| 77 | + 'F11': 'F11', | |
| 78 | + 'F12': 'F12', | |
| 79 | + 'F13': 'F13', | |
| 80 | + 'F14': 'F14', | |
| 81 | + 'F15': 'F15', | |
| 82 | + 'F16': 'F16', | |
| 83 | + 'F17': 'F17', | |
| 84 | + 'F18': 'F18', | |
| 85 | + 'F19': 'F19', | |
| 86 | + 'F20': 'F20', | |
| 87 | + 'F21': 'F21', | |
| 88 | + 'F22': 'F22', | |
| 89 | + 'F23': 'F23', | |
| 90 | + 'F24': 'F24', | |
| 91 | + 'F25': 'F25', | |
| 92 | + 'F26': 'F26', | |
| 93 | + 'F27': 'F27', | |
| 94 | + 'F28': 'F28', | |
| 95 | + 'F29': 'F29', | |
| 96 | + 'F30': 'F30', | |
| 97 | + 'F31': 'F31', | |
| 98 | + 'F32': 'F32', | |
| 99 | + 'F33': 'F33', | |
| 100 | + 'F34': 'F34', | |
| 101 | + 'F35': 'F35', | |
| 102 | + 'PrintScreen': 'PrintScreen', | |
| 103 | + 'ScrollLock': 'ScrollLock', | |
| 104 | + 'Pause': 'Pause', | |
| 105 | + | |
| 106 | +// 3.1.6. Media Keys | |
| 107 | + | |
| 108 | + 'BrowserBack': 'BrowserBack', | |
| 109 | + 'BrowserFavorites': 'BrowserFavorites', | |
| 110 | + 'BrowserForward': 'BrowserForward', | |
| 111 | + 'BrowserHome': 'BrowserHome', | |
| 112 | + 'BrowserRefresh': 'BrowserRefresh', | |
| 113 | + 'BrowserSearch': 'BrowserSearch', | |
| 114 | + 'BrowserStop': 'BrowserStop', | |
| 115 | + 'Eject': 'Eject', | |
| 116 | + 'LaunchApp1': 'LaunchMyComputer', | |
| 117 | + 'LaunchApp2': 'LaunchCalendar', | |
| 118 | + 'LaunchMail': 'LaunchMail', | |
| 119 | + 'MediaPlayPause': 'MediaPlay', | |
| 120 | + 'MediaStop': 'MediaStop', | |
| 121 | + 'MediaTrackNext': 'MediaTrackNext', | |
| 122 | + 'MediaTrackPrevious': 'MediaTrackPrevious', | |
| 123 | + 'Power': 'Power', | |
| 124 | + 'Sleep': 'Sleep', | |
| 125 | + 'AudioVolumeDown': 'AudioVolumeDown', | |
| 126 | + 'AudioVolumeMute': 'AudioVolumeMute', | |
| 127 | + 'AudioVolumeUp': 'AudioVolumeUp', | |
| 128 | + 'WakeUp': 'WakeUp', | |
| 129 | +}; | |
added
public/vendor/novnc/core/input/gesturehandler.js
+567 −0
@@ -0,0 +1,567 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2020 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +const GH_NOGESTURE = 0; | |
| 11 | +const GH_ONETAP = 1; | |
| 12 | +const GH_TWOTAP = 2; | |
| 13 | +const GH_THREETAP = 4; | |
| 14 | +const GH_DRAG = 8; | |
| 15 | +const GH_LONGPRESS = 16; | |
| 16 | +const GH_TWODRAG = 32; | |
| 17 | +const GH_PINCH = 64; | |
| 18 | + | |
| 19 | +const GH_INITSTATE = 127; | |
| 20 | + | |
| 21 | +const GH_MOVE_THRESHOLD = 50; | |
| 22 | +const GH_ANGLE_THRESHOLD = 90; // Degrees | |
| 23 | + | |
| 24 | +// Timeout when waiting for gestures (ms) | |
| 25 | +const GH_MULTITOUCH_TIMEOUT = 250; | |
| 26 | + | |
| 27 | +// Maximum time between press and release for a tap (ms) | |
| 28 | +const GH_TAP_TIMEOUT = 1000; | |
| 29 | + | |
| 30 | +// Timeout when waiting for longpress (ms) | |
| 31 | +const GH_LONGPRESS_TIMEOUT = 1000; | |
| 32 | + | |
| 33 | +// Timeout when waiting to decide between PINCH and TWODRAG (ms) | |
| 34 | +const GH_TWOTOUCH_TIMEOUT = 50; | |
| 35 | + | |
| 36 | +export default class GestureHandler { | |
| 37 | + constructor() { | |
| 38 | + this._target = null; | |
| 39 | + | |
| 40 | + this._state = GH_INITSTATE; | |
| 41 | + | |
| 42 | + this._tracked = []; | |
| 43 | + this._ignored = []; | |
| 44 | + | |
| 45 | + this._waitingRelease = false; | |
| 46 | + this._releaseStart = 0.0; | |
| 47 | + | |
| 48 | + this._longpressTimeoutId = null; | |
| 49 | + this._twoTouchTimeoutId = null; | |
| 50 | + | |
| 51 | + this._boundEventHandler = this._eventHandler.bind(this); | |
| 52 | + } | |
| 53 | + | |
| 54 | + attach(target) { | |
| 55 | + this.detach(); | |
| 56 | + | |
| 57 | + this._target = target; | |
| 58 | + this._target.addEventListener('touchstart', | |
| 59 | + this._boundEventHandler); | |
| 60 | + this._target.addEventListener('touchmove', | |
| 61 | + this._boundEventHandler); | |
| 62 | + this._target.addEventListener('touchend', | |
| 63 | + this._boundEventHandler); | |
| 64 | + this._target.addEventListener('touchcancel', | |
| 65 | + this._boundEventHandler); | |
| 66 | + } | |
| 67 | + | |
| 68 | + detach() { | |
| 69 | + if (!this._target) { | |
| 70 | + return; | |
| 71 | + } | |
| 72 | + | |
| 73 | + this._stopLongpressTimeout(); | |
| 74 | + this._stopTwoTouchTimeout(); | |
| 75 | + | |
| 76 | + this._target.removeEventListener('touchstart', | |
| 77 | + this._boundEventHandler); | |
| 78 | + this._target.removeEventListener('touchmove', | |
| 79 | + this._boundEventHandler); | |
| 80 | + this._target.removeEventListener('touchend', | |
| 81 | + this._boundEventHandler); | |
| 82 | + this._target.removeEventListener('touchcancel', | |
| 83 | + this._boundEventHandler); | |
| 84 | + this._target = null; | |
| 85 | + } | |
| 86 | + | |
| 87 | + _eventHandler(e) { | |
| 88 | + let fn; | |
| 89 | + | |
| 90 | + e.stopPropagation(); | |
| 91 | + e.preventDefault(); | |
| 92 | + | |
| 93 | + switch (e.type) { | |
| 94 | + case 'touchstart': | |
| 95 | + fn = this._touchStart; | |
| 96 | + break; | |
| 97 | + case 'touchmove': | |
| 98 | + fn = this._touchMove; | |
| 99 | + break; | |
| 100 | + case 'touchend': | |
| 101 | + case 'touchcancel': | |
| 102 | + fn = this._touchEnd; | |
| 103 | + break; | |
| 104 | + } | |
| 105 | + | |
| 106 | + for (let i = 0; i < e.changedTouches.length; i++) { | |
| 107 | + let touch = e.changedTouches[i]; | |
| 108 | + fn.call(this, touch.identifier, touch.clientX, touch.clientY); | |
| 109 | + } | |
| 110 | + } | |
| 111 | + | |
| 112 | + _touchStart(id, x, y) { | |
| 113 | + // Ignore any new touches if there is already an active gesture, | |
| 114 | + // or we're in a cleanup state | |
| 115 | + if (this._hasDetectedGesture() || (this._state === GH_NOGESTURE)) { | |
| 116 | + this._ignored.push(id); | |
| 117 | + return; | |
| 118 | + } | |
| 119 | + | |
| 120 | + // Did it take too long between touches that we should no longer | |
| 121 | + // consider this a single gesture? | |
| 122 | + if ((this._tracked.length > 0) && | |
| 123 | + ((Date.now() - this._tracked[0].started) > GH_MULTITOUCH_TIMEOUT)) { | |
| 124 | + this._state = GH_NOGESTURE; | |
| 125 | + this._ignored.push(id); | |
| 126 | + return; | |
| 127 | + } | |
| 128 | + | |
| 129 | + // If we're waiting for fingers to release then we should no longer | |
| 130 | + // recognize new touches | |
| 131 | + if (this._waitingRelease) { | |
| 132 | + this._state = GH_NOGESTURE; | |
| 133 | + this._ignored.push(id); | |
| 134 | + return; | |
| 135 | + } | |
| 136 | + | |
| 137 | + this._tracked.push({ | |
| 138 | + id: id, | |
| 139 | + started: Date.now(), | |
| 140 | + active: true, | |
| 141 | + firstX: x, | |
| 142 | + firstY: y, | |
| 143 | + lastX: x, | |
| 144 | + lastY: y, | |
| 145 | + angle: 0 | |
| 146 | + }); | |
| 147 | + | |
| 148 | + switch (this._tracked.length) { | |
| 149 | + case 1: | |
| 150 | + this._startLongpressTimeout(); | |
| 151 | + break; | |
| 152 | + | |
| 153 | + case 2: | |
| 154 | + this._state &= ~(GH_ONETAP | GH_DRAG | GH_LONGPRESS); | |
| 155 | + this._stopLongpressTimeout(); | |
| 156 | + break; | |
| 157 | + | |
| 158 | + case 3: | |
| 159 | + this._state &= ~(GH_TWOTAP | GH_TWODRAG | GH_PINCH); | |
| 160 | + break; | |
| 161 | + | |
| 162 | + default: | |
| 163 | + this._state = GH_NOGESTURE; | |
| 164 | + } | |
| 165 | + } | |
| 166 | + | |
| 167 | + _touchMove(id, x, y) { | |
| 168 | + let touch = this._tracked.find(t => t.id === id); | |
| 169 | + | |
| 170 | + // If this is an update for a touch we're not tracking, ignore it | |
| 171 | + if (touch === undefined) { | |
| 172 | + return; | |
| 173 | + } | |
| 174 | + | |
| 175 | + // Update the touches last position with the event coordinates | |
| 176 | + touch.lastX = x; | |
| 177 | + touch.lastY = y; | |
| 178 | + | |
| 179 | + let deltaX = x - touch.firstX; | |
| 180 | + let deltaY = y - touch.firstY; | |
| 181 | + | |
| 182 | + // Update angle when the touch has moved | |
| 183 | + if ((touch.firstX !== touch.lastX) || | |
| 184 | + (touch.firstY !== touch.lastY)) { | |
| 185 | + touch.angle = Math.atan2(deltaY, deltaX) * 180 / Math.PI; | |
| 186 | + } | |
| 187 | + | |
| 188 | + if (!this._hasDetectedGesture()) { | |
| 189 | + // Ignore moves smaller than the minimum threshold | |
| 190 | + if (Math.hypot(deltaX, deltaY) < GH_MOVE_THRESHOLD) { | |
| 191 | + return; | |
| 192 | + } | |
| 193 | + | |
| 194 | + // Can't be a tap or long press as we've seen movement | |
| 195 | + this._state &= ~(GH_ONETAP | GH_TWOTAP | GH_THREETAP | GH_LONGPRESS); | |
| 196 | + this._stopLongpressTimeout(); | |
| 197 | + | |
| 198 | + if (this._tracked.length !== 1) { | |
| 199 | + this._state &= ~(GH_DRAG); | |
| 200 | + } | |
| 201 | + if (this._tracked.length !== 2) { | |
| 202 | + this._state &= ~(GH_TWODRAG | GH_PINCH); | |
| 203 | + } | |
| 204 | + | |
| 205 | + // We need to figure out which of our different two touch gestures | |
| 206 | + // this might be | |
| 207 | + if (this._tracked.length === 2) { | |
| 208 | + | |
| 209 | + // The other touch is the one where the id doesn't match | |
| 210 | + let prevTouch = this._tracked.find(t => t.id !== id); | |
| 211 | + | |
| 212 | + // How far the previous touch point has moved since start | |
| 213 | + let prevDeltaMove = Math.hypot(prevTouch.firstX - prevTouch.lastX, | |
| 214 | + prevTouch.firstY - prevTouch.lastY); | |
| 215 | + | |
| 216 | + // We know that the current touch moved far enough, | |
| 217 | + // but unless both touches moved further than their | |
| 218 | + // threshold we don't want to disqualify any gestures | |
| 219 | + if (prevDeltaMove > GH_MOVE_THRESHOLD) { | |
| 220 | + | |
| 221 | + // The angle difference between the direction of the touch points | |
| 222 | + let deltaAngle = Math.abs(touch.angle - prevTouch.angle); | |
| 223 | + deltaAngle = Math.abs(((deltaAngle + 180) % 360) - 180); | |
| 224 | + | |
| 225 | + // PINCH or TWODRAG can be eliminated depending on the angle | |
| 226 | + if (deltaAngle > GH_ANGLE_THRESHOLD) { | |
| 227 | + this._state &= ~GH_TWODRAG; | |
| 228 | + } else { | |
| 229 | + this._state &= ~GH_PINCH; | |
| 230 | + } | |
| 231 | + | |
| 232 | + if (this._isTwoTouchTimeoutRunning()) { | |
| 233 | + this._stopTwoTouchTimeout(); | |
| 234 | + } | |
| 235 | + } else if (!this._isTwoTouchTimeoutRunning()) { | |
| 236 | + // We can't determine the gesture right now, let's | |
| 237 | + // wait and see if more events are on their way | |
| 238 | + this._startTwoTouchTimeout(); | |
| 239 | + } | |
| 240 | + } | |
| 241 | + | |
| 242 | + if (!this._hasDetectedGesture()) { | |
| 243 | + return; | |
| 244 | + } | |
| 245 | + | |
| 246 | + this._pushEvent('gesturestart'); | |
| 247 | + } | |
| 248 | + | |
| 249 | + this._pushEvent('gesturemove'); | |
| 250 | + } | |
| 251 | + | |
| 252 | + _touchEnd(id, x, y) { | |
| 253 | + // Check if this is an ignored touch | |
| 254 | + if (this._ignored.indexOf(id) !== -1) { | |
| 255 | + // Remove this touch from ignored | |
| 256 | + this._ignored.splice(this._ignored.indexOf(id), 1); | |
| 257 | + | |
| 258 | + // And reset the state if there are no more touches | |
| 259 | + if ((this._ignored.length === 0) && | |
| 260 | + (this._tracked.length === 0)) { | |
| 261 | + this._state = GH_INITSTATE; | |
| 262 | + this._waitingRelease = false; | |
| 263 | + } | |
| 264 | + return; | |
| 265 | + } | |
| 266 | + | |
| 267 | + // We got a touchend before the timer triggered, | |
| 268 | + // this cannot result in a gesture anymore. | |
| 269 | + if (!this._hasDetectedGesture() && | |
| 270 | + this._isTwoTouchTimeoutRunning()) { | |
| 271 | + this._stopTwoTouchTimeout(); | |
| 272 | + this._state = GH_NOGESTURE; | |
| 273 | + } | |
| 274 | + | |
| 275 | + // Some gestures don't trigger until a touch is released | |
| 276 | + if (!this._hasDetectedGesture()) { | |
| 277 | + // Can't be a gesture that relies on movement | |
| 278 | + this._state &= ~(GH_DRAG | GH_TWODRAG | GH_PINCH); | |
| 279 | + // Or something that relies on more time | |
| 280 | + this._state &= ~GH_LONGPRESS; | |
| 281 | + this._stopLongpressTimeout(); | |
| 282 | + | |
| 283 | + if (!this._waitingRelease) { | |
| 284 | + this._releaseStart = Date.now(); | |
| 285 | + this._waitingRelease = true; | |
| 286 | + | |
| 287 | + // Can't be a tap that requires more touches than we current have | |
| 288 | + switch (this._tracked.length) { | |
| 289 | + case 1: | |
| 290 | + this._state &= ~(GH_TWOTAP | GH_THREETAP); | |
| 291 | + break; | |
| 292 | + | |
| 293 | + case 2: | |
| 294 | + this._state &= ~(GH_ONETAP | GH_THREETAP); | |
| 295 | + break; | |
| 296 | + } | |
| 297 | + } | |
| 298 | + } | |
| 299 | + | |
| 300 | + // Waiting for all touches to release? (i.e. some tap) | |
| 301 | + if (this._waitingRelease) { | |
| 302 | + // Were all touches released at roughly the same time? | |
| 303 | + if ((Date.now() - this._releaseStart) > GH_MULTITOUCH_TIMEOUT) { | |
| 304 | + this._state = GH_NOGESTURE; | |
| 305 | + } | |
| 306 | + | |
| 307 | + // Did too long time pass between press and release? | |
| 308 | + if (this._tracked.some(t => (Date.now() - t.started) > GH_TAP_TIMEOUT)) { | |
| 309 | + this._state = GH_NOGESTURE; | |
| 310 | + } | |
| 311 | + | |
| 312 | + let touch = this._tracked.find(t => t.id === id); | |
| 313 | + touch.active = false; | |
| 314 | + | |
| 315 | + // Are we still waiting for more releases? | |
| 316 | + if (this._hasDetectedGesture()) { | |
| 317 | + this._pushEvent('gesturestart'); | |
| 318 | + } else { | |
| 319 | + // Have we reached a dead end? | |
| 320 | + if (this._state !== GH_NOGESTURE) { | |
| 321 | + return; | |
| 322 | + } | |
| 323 | + } | |
| 324 | + } | |
| 325 | + | |
| 326 | + if (this._hasDetectedGesture()) { | |
| 327 | + this._pushEvent('gestureend'); | |
| 328 | + } | |
| 329 | + | |
| 330 | + // Ignore any remaining touches until they are ended | |
| 331 | + for (let i = 0; i < this._tracked.length; i++) { | |
| 332 | + if (this._tracked[i].active) { | |
| 333 | + this._ignored.push(this._tracked[i].id); | |
| 334 | + } | |
| 335 | + } | |
| 336 | + this._tracked = []; | |
| 337 | + | |
| 338 | + this._state = GH_NOGESTURE; | |
| 339 | + | |
| 340 | + // Remove this touch from ignored if it's in there | |
| 341 | + if (this._ignored.indexOf(id) !== -1) { | |
| 342 | + this._ignored.splice(this._ignored.indexOf(id), 1); | |
| 343 | + } | |
| 344 | + | |
| 345 | + // We reset the state if ignored is empty | |
| 346 | + if ((this._ignored.length === 0)) { | |
| 347 | + this._state = GH_INITSTATE; | |
| 348 | + this._waitingRelease = false; | |
| 349 | + } | |
| 350 | + } | |
| 351 | + | |
| 352 | + _hasDetectedGesture() { | |
| 353 | + if (this._state === GH_NOGESTURE) { | |
| 354 | + return false; | |
| 355 | + } | |
| 356 | + // Check to see if the bitmask value is a power of 2 | |
| 357 | + // (i.e. only one bit set). If it is, we have a state. | |
| 358 | + if (this._state & (this._state - 1)) { | |
| 359 | + return false; | |
| 360 | + } | |
| 361 | + | |
| 362 | + // For taps we also need to have all touches released | |
| 363 | + // before we've fully detected the gesture | |
| 364 | + if (this._state & (GH_ONETAP | GH_TWOTAP | GH_THREETAP)) { | |
| 365 | + if (this._tracked.some(t => t.active)) { | |
| 366 | + return false; | |
| 367 | + } | |
| 368 | + } | |
| 369 | + | |
| 370 | + return true; | |
| 371 | + } | |
| 372 | + | |
| 373 | + _startLongpressTimeout() { | |
| 374 | + this._stopLongpressTimeout(); | |
| 375 | + this._longpressTimeoutId = setTimeout(() => this._longpressTimeout(), | |
| 376 | + GH_LONGPRESS_TIMEOUT); | |
| 377 | + } | |
| 378 | + | |
| 379 | + _stopLongpressTimeout() { | |
| 380 | + clearTimeout(this._longpressTimeoutId); | |
| 381 | + this._longpressTimeoutId = null; | |
| 382 | + } | |
| 383 | + | |
| 384 | + _longpressTimeout() { | |
| 385 | + if (this._hasDetectedGesture()) { | |
| 386 | + throw new Error("A longpress gesture failed, conflict with a different gesture"); | |
| 387 | + } | |
| 388 | + | |
| 389 | + this._state = GH_LONGPRESS; | |
| 390 | + this._pushEvent('gesturestart'); | |
| 391 | + } | |
| 392 | + | |
| 393 | + _startTwoTouchTimeout() { | |
| 394 | + this._stopTwoTouchTimeout(); | |
| 395 | + this._twoTouchTimeoutId = setTimeout(() => this._twoTouchTimeout(), | |
| 396 | + GH_TWOTOUCH_TIMEOUT); | |
| 397 | + } | |
| 398 | + | |
| 399 | + _stopTwoTouchTimeout() { | |
| 400 | + clearTimeout(this._twoTouchTimeoutId); | |
| 401 | + this._twoTouchTimeoutId = null; | |
| 402 | + } | |
| 403 | + | |
| 404 | + _isTwoTouchTimeoutRunning() { | |
| 405 | + return this._twoTouchTimeoutId !== null; | |
| 406 | + } | |
| 407 | + | |
| 408 | + _twoTouchTimeout() { | |
| 409 | + if (this._tracked.length === 0) { | |
| 410 | + throw new Error("A pinch or two drag gesture failed, no tracked touches"); | |
| 411 | + } | |
| 412 | + | |
| 413 | + // How far each touch point has moved since start | |
| 414 | + let avgM = this._getAverageMovement(); | |
| 415 | + let avgMoveH = Math.abs(avgM.x); | |
| 416 | + let avgMoveV = Math.abs(avgM.y); | |
| 417 | + | |
| 418 | + // The difference in the distance between where | |
| 419 | + // the touch points started and where they are now | |
| 420 | + let avgD = this._getAverageDistance(); | |
| 421 | + let deltaTouchDistance = Math.abs(Math.hypot(avgD.first.x, avgD.first.y) - | |
| 422 | + Math.hypot(avgD.last.x, avgD.last.y)); | |
| 423 | + | |
| 424 | + if ((avgMoveV < deltaTouchDistance) && | |
| 425 | + (avgMoveH < deltaTouchDistance)) { | |
| 426 | + this._state = GH_PINCH; | |
| 427 | + } else { | |
| 428 | + this._state = GH_TWODRAG; | |
| 429 | + } | |
| 430 | + | |
| 431 | + this._pushEvent('gesturestart'); | |
| 432 | + this._pushEvent('gesturemove'); | |
| 433 | + } | |
| 434 | + | |
| 435 | + _pushEvent(type) { | |
| 436 | + let detail = { type: this._stateToGesture(this._state) }; | |
| 437 | + | |
| 438 | + // For most gesture events the current (average) position is the | |
| 439 | + // most useful | |
| 440 | + let avg = this._getPosition(); | |
| 441 | + let pos = avg.last; | |
| 442 | + | |
| 443 | + // However we have a slight distance to detect gestures, so for the | |
| 444 | + // first gesture event we want to use the first positions we saw | |
| 445 | + if (type === 'gesturestart') { | |
| 446 | + pos = avg.first; | |
| 447 | + } | |
| 448 | + | |
| 449 | + // For these gestures, we always want the event coordinates | |
| 450 | + // to be where the gesture began, not the current touch location. | |
| 451 | + switch (this._state) { | |
| 452 | + case GH_TWODRAG: | |
| 453 | + case GH_PINCH: | |
| 454 | + pos = avg.first; | |
| 455 | + break; | |
| 456 | + } | |
| 457 | + | |
| 458 | + detail['clientX'] = pos.x; | |
| 459 | + detail['clientY'] = pos.y; | |
| 460 | + | |
| 461 | + // FIXME: other coordinates? | |
| 462 | + | |
| 463 | + // Some gestures also have a magnitude | |
| 464 | + if (this._state === GH_PINCH) { | |
| 465 | + let distance = this._getAverageDistance(); | |
| 466 | + if (type === 'gesturestart') { | |
| 467 | + detail['magnitudeX'] = distance.first.x; | |
| 468 | + detail['magnitudeY'] = distance.first.y; | |
| 469 | + } else { | |
| 470 | + detail['magnitudeX'] = distance.last.x; | |
| 471 | + detail['magnitudeY'] = distance.last.y; | |
| 472 | + } | |
| 473 | + } else if (this._state === GH_TWODRAG) { | |
| 474 | + if (type === 'gesturestart') { | |
| 475 | + detail['magnitudeX'] = 0.0; | |
| 476 | + detail['magnitudeY'] = 0.0; | |
| 477 | + } else { | |
| 478 | + let movement = this._getAverageMovement(); | |
| 479 | + detail['magnitudeX'] = movement.x; | |
| 480 | + detail['magnitudeY'] = movement.y; | |
| 481 | + } | |
| 482 | + } | |
| 483 | + | |
| 484 | + let gev = new CustomEvent(type, { detail: detail }); | |
| 485 | + this._target.dispatchEvent(gev); | |
| 486 | + } | |
| 487 | + | |
| 488 | + _stateToGesture(state) { | |
| 489 | + switch (state) { | |
| 490 | + case GH_ONETAP: | |
| 491 | + return 'onetap'; | |
| 492 | + case GH_TWOTAP: | |
| 493 | + return 'twotap'; | |
| 494 | + case GH_THREETAP: | |
| 495 | + return 'threetap'; | |
| 496 | + case GH_DRAG: | |
| 497 | + return 'drag'; | |
| 498 | + case GH_LONGPRESS: | |
| 499 | + return 'longpress'; | |
| 500 | + case GH_TWODRAG: | |
| 501 | + return 'twodrag'; | |
| 502 | + case GH_PINCH: | |
| 503 | + return 'pinch'; | |
| 504 | + } | |
| 505 | + | |
| 506 | + throw new Error("Unknown gesture state: " + state); | |
| 507 | + } | |
| 508 | + | |
| 509 | + _getPosition() { | |
| 510 | + if (this._tracked.length === 0) { | |
| 511 | + throw new Error("Failed to get gesture position, no tracked touches"); | |
| 512 | + } | |
| 513 | + | |
| 514 | + let size = this._tracked.length; | |
| 515 | + let fx = 0, fy = 0, lx = 0, ly = 0; | |
| 516 | + | |
| 517 | + for (let i = 0; i < this._tracked.length; i++) { | |
| 518 | + fx += this._tracked[i].firstX; | |
| 519 | + fy += this._tracked[i].firstY; | |
| 520 | + lx += this._tracked[i].lastX; | |
| 521 | + ly += this._tracked[i].lastY; | |
| 522 | + } | |
| 523 | + | |
| 524 | + return { first: { x: fx / size, | |
| 525 | + y: fy / size }, | |
| 526 | + last: { x: lx / size, | |
| 527 | + y: ly / size } }; | |
| 528 | + } | |
| 529 | + | |
| 530 | + _getAverageMovement() { | |
| 531 | + if (this._tracked.length === 0) { | |
| 532 | + throw new Error("Failed to get gesture movement, no tracked touches"); | |
| 533 | + } | |
| 534 | + | |
| 535 | + let totalH, totalV; | |
| 536 | + totalH = totalV = 0; | |
| 537 | + let size = this._tracked.length; | |
| 538 | + | |
| 539 | + for (let i = 0; i < this._tracked.length; i++) { | |
| 540 | + totalH += this._tracked[i].lastX - this._tracked[i].firstX; | |
| 541 | + totalV += this._tracked[i].lastY - this._tracked[i].firstY; | |
| 542 | + } | |
| 543 | + | |
| 544 | + return { x: totalH / size, | |
| 545 | + y: totalV / size }; | |
| 546 | + } | |
| 547 | + | |
| 548 | + _getAverageDistance() { | |
| 549 | + if (this._tracked.length === 0) { | |
| 550 | + throw new Error("Failed to get gesture distance, no tracked touches"); | |
| 551 | + } | |
| 552 | + | |
| 553 | + // Distance between the first and last tracked touches | |
| 554 | + | |
| 555 | + let first = this._tracked[0]; | |
| 556 | + let last = this._tracked[this._tracked.length - 1]; | |
| 557 | + | |
| 558 | + let fdx = Math.abs(last.firstX - first.firstX); | |
| 559 | + let fdy = Math.abs(last.firstY - first.firstY); | |
| 560 | + | |
| 561 | + let ldx = Math.abs(last.lastX - first.lastX); | |
| 562 | + let ldy = Math.abs(last.lastY - first.lastY); | |
| 563 | + | |
| 564 | + return { first: { x: fdx, y: fdy }, | |
| 565 | + last: { x: ldx, y: ldy } }; | |
| 566 | + } | |
| 567 | +} | |
added
public/vendor/novnc/core/input/keyboard.js
+294 −0
@@ -0,0 +1,294 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | |
| 5 | + */ | |
| 6 | + | |
| 7 | +import * as Log from '../util/logging.js'; | |
| 8 | +import { stopEvent } from '../util/events.js'; | |
| 9 | +import * as KeyboardUtil from "./util.js"; | |
| 10 | +import KeyTable from "./keysym.js"; | |
| 11 | +import * as browser from "../util/browser.js"; | |
| 12 | + | |
| 13 | +// | |
| 14 | +// Keyboard event handler | |
| 15 | +// | |
| 16 | + | |
| 17 | +export default class Keyboard { | |
| 18 | + constructor(target) { | |
| 19 | + this._target = target || null; | |
| 20 | + | |
| 21 | + this._keyDownList = {}; // List of depressed keys | |
| 22 | + // (even if they are happy) | |
| 23 | + this._altGrArmed = false; // Windows AltGr detection | |
| 24 | + | |
| 25 | + // keep these here so we can refer to them later | |
| 26 | + this._eventHandlers = { | |
| 27 | + 'keyup': this._handleKeyUp.bind(this), | |
| 28 | + 'keydown': this._handleKeyDown.bind(this), | |
| 29 | + 'blur': this._allKeysUp.bind(this), | |
| 30 | + }; | |
| 31 | + | |
| 32 | + // ===== EVENT HANDLERS ===== | |
| 33 | + | |
| 34 | + this.onkeyevent = () => {}; // Handler for key press/release | |
| 35 | + } | |
| 36 | + | |
| 37 | + // ===== PRIVATE METHODS ===== | |
| 38 | + | |
| 39 | + _sendKeyEvent(keysym, code, down, numlock = null, capslock = null) { | |
| 40 | + if (down) { | |
| 41 | + this._keyDownList[code] = keysym; | |
| 42 | + } else { | |
| 43 | + // Do we really think this key is down? | |
| 44 | + if (!(code in this._keyDownList)) { | |
| 45 | + return; | |
| 46 | + } | |
| 47 | + delete this._keyDownList[code]; | |
| 48 | + } | |
| 49 | + | |
| 50 | + Log.Debug("onkeyevent " + (down ? "down" : "up") + | |
| 51 | + ", keysym: " + keysym, ", code: " + code + | |
| 52 | + ", numlock: " + numlock + ", capslock: " + capslock); | |
| 53 | + this.onkeyevent(keysym, code, down, numlock, capslock); | |
| 54 | + } | |
| 55 | + | |
| 56 | + _getKeyCode(e) { | |
| 57 | + const code = KeyboardUtil.getKeycode(e); | |
| 58 | + if (code !== 'Unidentified') { | |
| 59 | + return code; | |
| 60 | + } | |
| 61 | + | |
| 62 | + // Unstable, but we don't have anything else to go on | |
| 63 | + if (e.keyCode) { | |
| 64 | + // 229 is used for composition events | |
| 65 | + if (e.keyCode !== 229) { | |
| 66 | + return 'Platform' + e.keyCode; | |
| 67 | + } | |
| 68 | + } | |
| 69 | + | |
| 70 | + // A precursor to the final DOM3 standard. Unfortunately it | |
| 71 | + // is not layout independent, so it is as bad as using keyCode | |
| 72 | + if (e.keyIdentifier) { | |
| 73 | + // Non-character key? | |
| 74 | + if (e.keyIdentifier.substr(0, 2) !== 'U+') { | |
| 75 | + return e.keyIdentifier; | |
| 76 | + } | |
| 77 | + | |
| 78 | + const codepoint = parseInt(e.keyIdentifier.substr(2), 16); | |
| 79 | + const char = String.fromCharCode(codepoint).toUpperCase(); | |
| 80 | + | |
| 81 | + return 'Platform' + char.charCodeAt(); | |
| 82 | + } | |
| 83 | + | |
| 84 | + return 'Unidentified'; | |
| 85 | + } | |
| 86 | + | |
| 87 | + _handleKeyDown(e) { | |
| 88 | + const code = this._getKeyCode(e); | |
| 89 | + let keysym = KeyboardUtil.getKeysym(e); | |
| 90 | + let numlock = e.getModifierState('NumLock'); | |
| 91 | + let capslock = e.getModifierState('CapsLock'); | |
| 92 | + | |
| 93 | + // getModifierState for NumLock is not supported on mac and ios and always returns false. | |
| 94 | + // Set to null to indicate unknown/unsupported instead. | |
| 95 | + if (browser.isMac() || browser.isIOS()) { | |
| 96 | + numlock = null; | |
| 97 | + } | |
| 98 | + | |
| 99 | + // Windows doesn't have a proper AltGr, but handles it using | |
| 100 | + // fake Ctrl+Alt. However the remote end might not be Windows, | |
| 101 | + // so we need to merge those in to a single AltGr event. We | |
| 102 | + // detect this case by seeing the two key events directly after | |
| 103 | + // each other with a very short time between them (<50ms). | |
| 104 | + if (this._altGrArmed) { | |
| 105 | + this._altGrArmed = false; | |
| 106 | + clearTimeout(this._altGrTimeout); | |
| 107 | + | |
| 108 | + if ((code === "AltRight") && | |
| 109 | + ((e.timeStamp - this._altGrCtrlTime) < 50)) { | |
| 110 | + // FIXME: We fail to detect this if either Ctrl key is | |
| 111 | + // first manually pressed as Windows then no | |
| 112 | + // longer sends the fake Ctrl down event. It | |
| 113 | + // does however happily send real Ctrl events | |
| 114 | + // even when AltGr is already down. Some | |
| 115 | + // browsers detect this for us though and set the | |
| 116 | + // key to "AltGraph". | |
| 117 | + keysym = KeyTable.XK_ISO_Level3_Shift; | |
| 118 | + } else { | |
| 119 | + this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true, numlock, capslock); | |
| 120 | + } | |
| 121 | + } | |
| 122 | + | |
| 123 | + // We cannot handle keys we cannot track, but we also need | |
| 124 | + // to deal with virtual keyboards which omit key info | |
| 125 | + if (code === 'Unidentified') { | |
| 126 | + if (keysym) { | |
| 127 | + // If it's a virtual keyboard then it should be | |
| 128 | + // sufficient to just send press and release right | |
| 129 | + // after each other | |
| 130 | + this._sendKeyEvent(keysym, code, true, numlock, capslock); | |
| 131 | + this._sendKeyEvent(keysym, code, false, numlock, capslock); | |
| 132 | + } | |
| 133 | + | |
| 134 | + stopEvent(e); | |
| 135 | + return; | |
| 136 | + } | |
| 137 | + | |
| 138 | + // Alt behaves more like AltGraph on macOS, so shuffle the | |
| 139 | + // keys around a bit to make things more sane for the remote | |
| 140 | + // server. This method is used by RealVNC and TigerVNC (and | |
| 141 | + // possibly others). | |
| 142 | + if (browser.isMac() || browser.isIOS()) { | |
| 143 | + switch (keysym) { | |
| 144 | + case KeyTable.XK_Super_L: | |
| 145 | + keysym = KeyTable.XK_Alt_L; | |
| 146 | + break; | |
| 147 | + case KeyTable.XK_Super_R: | |
| 148 | + keysym = KeyTable.XK_Super_L; | |
| 149 | + break; | |
| 150 | + case KeyTable.XK_Alt_L: | |
| 151 | + keysym = KeyTable.XK_Mode_switch; | |
| 152 | + break; | |
| 153 | + case KeyTable.XK_Alt_R: | |
| 154 | + keysym = KeyTable.XK_ISO_Level3_Shift; | |
| 155 | + break; | |
| 156 | + } | |
| 157 | + } | |
| 158 | + | |
| 159 | + // Is this key already pressed? If so, then we must use the | |
| 160 | + // same keysym or we'll confuse the server | |
| 161 | + if (code in this._keyDownList) { | |
| 162 | + keysym = this._keyDownList[code]; | |
| 163 | + } | |
| 164 | + | |
| 165 | + // macOS doesn't send proper key releases if a key is pressed | |
| 166 | + // while meta is held down | |
| 167 | + if ((browser.isMac() || browser.isIOS()) && | |
| 168 | + (e.metaKey && code !== 'MetaLeft' && code !== 'MetaRight')) { | |
| 169 | + this._sendKeyEvent(keysym, code, true, numlock, capslock); | |
| 170 | + this._sendKeyEvent(keysym, code, false, numlock, capslock); | |
| 171 | + stopEvent(e); | |
| 172 | + return; | |
| 173 | + } | |
| 174 | + | |
| 175 | + // macOS doesn't send proper key events for modifiers, only | |
| 176 | + // state change events. That gets extra confusing for CapsLock | |
| 177 | + // which toggles on each press, but not on release. So pretend | |
| 178 | + // it was a quick press and release of the button. | |
| 179 | + if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) { | |
| 180 | + this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true, numlock, capslock); | |
| 181 | + this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false, numlock, capslock); | |
| 182 | + stopEvent(e); | |
| 183 | + return; | |
| 184 | + } | |
| 185 | + | |
| 186 | + // Windows doesn't send proper key releases for a bunch of | |
| 187 | + // Japanese IM keys so we have to fake the release right away | |
| 188 | + const jpBadKeys = [ KeyTable.XK_Zenkaku_Hankaku, | |
| 189 | + KeyTable.XK_Eisu_toggle, | |
| 190 | + KeyTable.XK_Katakana, | |
| 191 | + KeyTable.XK_Hiragana, | |
| 192 | + KeyTable.XK_Romaji ]; | |
| 193 | + if (browser.isWindows() && jpBadKeys.includes(keysym)) { | |
| 194 | + this._sendKeyEvent(keysym, code, true, numlock, capslock); | |
| 195 | + this._sendKeyEvent(keysym, code, false, numlock, capslock); | |
| 196 | + stopEvent(e); | |
| 197 | + return; | |
| 198 | + } | |
| 199 | + | |
| 200 | + stopEvent(e); | |
| 201 | + | |
| 202 | + // Possible start of AltGr sequence? (see above) | |
| 203 | + if ((code === "ControlLeft") && browser.isWindows() && | |
| 204 | + !("ControlLeft" in this._keyDownList)) { | |
| 205 | + this._altGrArmed = true; | |
| 206 | + this._altGrTimeout = setTimeout(this._interruptAltGrSequence.bind(this), 100); | |
| 207 | + this._altGrCtrlTime = e.timeStamp; | |
| 208 | + return; | |
| 209 | + } | |
| 210 | + | |
| 211 | + this._sendKeyEvent(keysym, code, true, numlock, capslock); | |
| 212 | + } | |
| 213 | + | |
| 214 | + _handleKeyUp(e) { | |
| 215 | + stopEvent(e); | |
| 216 | + | |
| 217 | + const code = this._getKeyCode(e); | |
| 218 | + | |
| 219 | + // We can't get a release in the middle of an AltGr sequence, so | |
| 220 | + // abort that detection | |
| 221 | + this._interruptAltGrSequence(); | |
| 222 | + | |
| 223 | + // See comment in _handleKeyDown() | |
| 224 | + if ((browser.isMac() || browser.isIOS()) && (code === 'CapsLock')) { | |
| 225 | + this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', true); | |
| 226 | + this._sendKeyEvent(KeyTable.XK_Caps_Lock, 'CapsLock', false); | |
| 227 | + return; | |
| 228 | + } | |
| 229 | + | |
| 230 | + this._sendKeyEvent(this._keyDownList[code], code, false); | |
| 231 | + | |
| 232 | + // Windows has a rather nasty bug where it won't send key | |
| 233 | + // release events for a Shift button if the other Shift is still | |
| 234 | + // pressed | |
| 235 | + if (browser.isWindows() && ((code === 'ShiftLeft') || | |
| 236 | + (code === 'ShiftRight'))) { | |
| 237 | + if ('ShiftRight' in this._keyDownList) { | |
| 238 | + this._sendKeyEvent(this._keyDownList['ShiftRight'], | |
| 239 | + 'ShiftRight', false); | |
| 240 | + } | |
| 241 | + if ('ShiftLeft' in this._keyDownList) { | |
| 242 | + this._sendKeyEvent(this._keyDownList['ShiftLeft'], | |
| 243 | + 'ShiftLeft', false); | |
| 244 | + } | |
| 245 | + } | |
| 246 | + } | |
| 247 | + | |
| 248 | + _interruptAltGrSequence() { | |
| 249 | + if (this._altGrArmed) { | |
| 250 | + this._altGrArmed = false; | |
| 251 | + clearTimeout(this._altGrTimeout); | |
| 252 | + this._sendKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true); | |
| 253 | + } | |
| 254 | + } | |
| 255 | + | |
| 256 | + _allKeysUp() { | |
| 257 | + Log.Debug(">> Keyboard.allKeysUp"); | |
| 258 | + | |
| 259 | + // Prevent control key being processed after losing focus. | |
| 260 | + this._interruptAltGrSequence(); | |
| 261 | + | |
| 262 | + for (let code in this._keyDownList) { | |
| 263 | + this._sendKeyEvent(this._keyDownList[code], code, false); | |
| 264 | + } | |
| 265 | + Log.Debug("<< Keyboard.allKeysUp"); | |
| 266 | + } | |
| 267 | + | |
| 268 | + // ===== PUBLIC METHODS ===== | |
| 269 | + | |
| 270 | + grab() { | |
| 271 | + //Log.Debug(">> Keyboard.grab"); | |
| 272 | + | |
| 273 | + this._target.addEventListener('keydown', this._eventHandlers.keydown); | |
| 274 | + this._target.addEventListener('keyup', this._eventHandlers.keyup); | |
| 275 | + | |
| 276 | + // Release (key up) if window loses focus | |
| 277 | + window.addEventListener('blur', this._eventHandlers.blur); | |
| 278 | + | |
| 279 | + //Log.Debug("<< Keyboard.grab"); | |
| 280 | + } | |
| 281 | + | |
| 282 | + ungrab() { | |
| 283 | + //Log.Debug(">> Keyboard.ungrab"); | |
| 284 | + | |
| 285 | + this._target.removeEventListener('keydown', this._eventHandlers.keydown); | |
| 286 | + this._target.removeEventListener('keyup', this._eventHandlers.keyup); | |
| 287 | + window.removeEventListener('blur', this._eventHandlers.blur); | |
| 288 | + | |
| 289 | + // Release (key up) all keys that are in a down state | |
| 290 | + this._allKeysUp(); | |
| 291 | + | |
| 292 | + //Log.Debug(">> Keyboard.ungrab"); | |
| 293 | + } | |
| 294 | +} | |
added
public/vendor/novnc/core/input/keysym.js
+616 −0
@@ -0,0 +1,616 @@ | ||
| 1 | +/* eslint-disable key-spacing */ | |
| 2 | + | |
| 3 | +export default { | |
| 4 | + XK_VoidSymbol: 0xffffff, /* Void symbol */ | |
| 5 | + | |
| 6 | + XK_BackSpace: 0xff08, /* Back space, back char */ | |
| 7 | + XK_Tab: 0xff09, | |
| 8 | + XK_Linefeed: 0xff0a, /* Linefeed, LF */ | |
| 9 | + XK_Clear: 0xff0b, | |
| 10 | + XK_Return: 0xff0d, /* Return, enter */ | |
| 11 | + XK_Pause: 0xff13, /* Pause, hold */ | |
| 12 | + XK_Scroll_Lock: 0xff14, | |
| 13 | + XK_Sys_Req: 0xff15, | |
| 14 | + XK_Escape: 0xff1b, | |
| 15 | + XK_Delete: 0xffff, /* Delete, rubout */ | |
| 16 | + | |
| 17 | + /* International & multi-key character composition */ | |
| 18 | + | |
| 19 | + XK_Multi_key: 0xff20, /* Multi-key character compose */ | |
| 20 | + XK_Codeinput: 0xff37, | |
| 21 | + XK_SingleCandidate: 0xff3c, | |
| 22 | + XK_MultipleCandidate: 0xff3d, | |
| 23 | + XK_PreviousCandidate: 0xff3e, | |
| 24 | + | |
| 25 | + /* Japanese keyboard support */ | |
| 26 | + | |
| 27 | + XK_Kanji: 0xff21, /* Kanji, Kanji convert */ | |
| 28 | + XK_Muhenkan: 0xff22, /* Cancel Conversion */ | |
| 29 | + XK_Henkan_Mode: 0xff23, /* Start/Stop Conversion */ | |
| 30 | + XK_Henkan: 0xff23, /* Alias for Henkan_Mode */ | |
| 31 | + XK_Romaji: 0xff24, /* to Romaji */ | |
| 32 | + XK_Hiragana: 0xff25, /* to Hiragana */ | |
| 33 | + XK_Katakana: 0xff26, /* to Katakana */ | |
| 34 | + XK_Hiragana_Katakana: 0xff27, /* Hiragana/Katakana toggle */ | |
| 35 | + XK_Zenkaku: 0xff28, /* to Zenkaku */ | |
| 36 | + XK_Hankaku: 0xff29, /* to Hankaku */ | |
| 37 | + XK_Zenkaku_Hankaku: 0xff2a, /* Zenkaku/Hankaku toggle */ | |
| 38 | + XK_Touroku: 0xff2b, /* Add to Dictionary */ | |
| 39 | + XK_Massyo: 0xff2c, /* Delete from Dictionary */ | |
| 40 | + XK_Kana_Lock: 0xff2d, /* Kana Lock */ | |
| 41 | + XK_Kana_Shift: 0xff2e, /* Kana Shift */ | |
| 42 | + XK_Eisu_Shift: 0xff2f, /* Alphanumeric Shift */ | |
| 43 | + XK_Eisu_toggle: 0xff30, /* Alphanumeric toggle */ | |
| 44 | + XK_Kanji_Bangou: 0xff37, /* Codeinput */ | |
| 45 | + XK_Zen_Koho: 0xff3d, /* Multiple/All Candidate(s) */ | |
| 46 | + XK_Mae_Koho: 0xff3e, /* Previous Candidate */ | |
| 47 | + | |
| 48 | + /* Cursor control & motion */ | |
| 49 | + | |
| 50 | + XK_Home: 0xff50, | |
| 51 | + XK_Left: 0xff51, /* Move left, left arrow */ | |
| 52 | + XK_Up: 0xff52, /* Move up, up arrow */ | |
| 53 | + XK_Right: 0xff53, /* Move right, right arrow */ | |
| 54 | + XK_Down: 0xff54, /* Move down, down arrow */ | |
| 55 | + XK_Prior: 0xff55, /* Prior, previous */ | |
| 56 | + XK_Page_Up: 0xff55, | |
| 57 | + XK_Next: 0xff56, /* Next */ | |
| 58 | + XK_Page_Down: 0xff56, | |
| 59 | + XK_End: 0xff57, /* EOL */ | |
| 60 | + XK_Begin: 0xff58, /* BOL */ | |
| 61 | + | |
| 62 | + | |
| 63 | + /* Misc functions */ | |
| 64 | + | |
| 65 | + XK_Select: 0xff60, /* Select, mark */ | |
| 66 | + XK_Print: 0xff61, | |
| 67 | + XK_Execute: 0xff62, /* Execute, run, do */ | |
| 68 | + XK_Insert: 0xff63, /* Insert, insert here */ | |
| 69 | + XK_Undo: 0xff65, | |
| 70 | + XK_Redo: 0xff66, /* Redo, again */ | |
| 71 | + XK_Menu: 0xff67, | |
| 72 | + XK_Find: 0xff68, /* Find, search */ | |
| 73 | + XK_Cancel: 0xff69, /* Cancel, stop, abort, exit */ | |
| 74 | + XK_Help: 0xff6a, /* Help */ | |
| 75 | + XK_Break: 0xff6b, | |
| 76 | + XK_Mode_switch: 0xff7e, /* Character set switch */ | |
| 77 | + XK_script_switch: 0xff7e, /* Alias for mode_switch */ | |
| 78 | + XK_Num_Lock: 0xff7f, | |
| 79 | + | |
| 80 | + /* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ | |
| 81 | + | |
| 82 | + XK_KP_Space: 0xff80, /* Space */ | |
| 83 | + XK_KP_Tab: 0xff89, | |
| 84 | + XK_KP_Enter: 0xff8d, /* Enter */ | |
| 85 | + XK_KP_F1: 0xff91, /* PF1, KP_A, ... */ | |
| 86 | + XK_KP_F2: 0xff92, | |
| 87 | + XK_KP_F3: 0xff93, | |
| 88 | + XK_KP_F4: 0xff94, | |
| 89 | + XK_KP_Home: 0xff95, | |
| 90 | + XK_KP_Left: 0xff96, | |
| 91 | + XK_KP_Up: 0xff97, | |
| 92 | + XK_KP_Right: 0xff98, | |
| 93 | + XK_KP_Down: 0xff99, | |
| 94 | + XK_KP_Prior: 0xff9a, | |
| 95 | + XK_KP_Page_Up: 0xff9a, | |
| 96 | + XK_KP_Next: 0xff9b, | |
| 97 | + XK_KP_Page_Down: 0xff9b, | |
| 98 | + XK_KP_End: 0xff9c, | |
| 99 | + XK_KP_Begin: 0xff9d, | |
| 100 | + XK_KP_Insert: 0xff9e, | |
| 101 | + XK_KP_Delete: 0xff9f, | |
| 102 | + XK_KP_Equal: 0xffbd, /* Equals */ | |
| 103 | + XK_KP_Multiply: 0xffaa, | |
| 104 | + XK_KP_Add: 0xffab, | |
| 105 | + XK_KP_Separator: 0xffac, /* Separator, often comma */ | |
| 106 | + XK_KP_Subtract: 0xffad, | |
| 107 | + XK_KP_Decimal: 0xffae, | |
| 108 | + XK_KP_Divide: 0xffaf, | |
| 109 | + | |
| 110 | + XK_KP_0: 0xffb0, | |
| 111 | + XK_KP_1: 0xffb1, | |
| 112 | + XK_KP_2: 0xffb2, | |
| 113 | + XK_KP_3: 0xffb3, | |
| 114 | + XK_KP_4: 0xffb4, | |
| 115 | + XK_KP_5: 0xffb5, | |
| 116 | + XK_KP_6: 0xffb6, | |
| 117 | + XK_KP_7: 0xffb7, | |
| 118 | + XK_KP_8: 0xffb8, | |
| 119 | + XK_KP_9: 0xffb9, | |
| 120 | + | |
| 121 | + /* | |
| 122 | + * Auxiliary functions; note the duplicate definitions for left and right | |
| 123 | + * function keys; Sun keyboards and a few other manufacturers have such | |
| 124 | + * function key groups on the left and/or right sides of the keyboard. | |
| 125 | + * We've not found a keyboard with more than 35 function keys total. | |
| 126 | + */ | |
| 127 | + | |
| 128 | + XK_F1: 0xffbe, | |
| 129 | + XK_F2: 0xffbf, | |
| 130 | + XK_F3: 0xffc0, | |
| 131 | + XK_F4: 0xffc1, | |
| 132 | + XK_F5: 0xffc2, | |
| 133 | + XK_F6: 0xffc3, | |
| 134 | + XK_F7: 0xffc4, | |
| 135 | + XK_F8: 0xffc5, | |
| 136 | + XK_F9: 0xffc6, | |
| 137 | + XK_F10: 0xffc7, | |
| 138 | + XK_F11: 0xffc8, | |
| 139 | + XK_L1: 0xffc8, | |
| 140 | + XK_F12: 0xffc9, | |
| 141 | + XK_L2: 0xffc9, | |
| 142 | + XK_F13: 0xffca, | |
| 143 | + XK_L3: 0xffca, | |
| 144 | + XK_F14: 0xffcb, | |
| 145 | + XK_L4: 0xffcb, | |
| 146 | + XK_F15: 0xffcc, | |
| 147 | + XK_L5: 0xffcc, | |
| 148 | + XK_F16: 0xffcd, | |
| 149 | + XK_L6: 0xffcd, | |
| 150 | + XK_F17: 0xffce, | |
| 151 | + XK_L7: 0xffce, | |
| 152 | + XK_F18: 0xffcf, | |
| 153 | + XK_L8: 0xffcf, | |
| 154 | + XK_F19: 0xffd0, | |
| 155 | + XK_L9: 0xffd0, | |
| 156 | + XK_F20: 0xffd1, | |
| 157 | + XK_L10: 0xffd1, | |
| 158 | + XK_F21: 0xffd2, | |
| 159 | + XK_R1: 0xffd2, | |
| 160 | + XK_F22: 0xffd3, | |
| 161 | + XK_R2: 0xffd3, | |
| 162 | + XK_F23: 0xffd4, | |
| 163 | + XK_R3: 0xffd4, | |
| 164 | + XK_F24: 0xffd5, | |
| 165 | + XK_R4: 0xffd5, | |
| 166 | + XK_F25: 0xffd6, | |
| 167 | + XK_R5: 0xffd6, | |
| 168 | + XK_F26: 0xffd7, | |
| 169 | + XK_R6: 0xffd7, | |
| 170 | + XK_F27: 0xffd8, | |
| 171 | + XK_R7: 0xffd8, | |
| 172 | + XK_F28: 0xffd9, | |
| 173 | + XK_R8: 0xffd9, | |
| 174 | + XK_F29: 0xffda, | |
| 175 | + XK_R9: 0xffda, | |
| 176 | + XK_F30: 0xffdb, | |
| 177 | + XK_R10: 0xffdb, | |
| 178 | + XK_F31: 0xffdc, | |
| 179 | + XK_R11: 0xffdc, | |
| 180 | + XK_F32: 0xffdd, | |
| 181 | + XK_R12: 0xffdd, | |
| 182 | + XK_F33: 0xffde, | |
| 183 | + XK_R13: 0xffde, | |
| 184 | + XK_F34: 0xffdf, | |
| 185 | + XK_R14: 0xffdf, | |
| 186 | + XK_F35: 0xffe0, | |
| 187 | + XK_R15: 0xffe0, | |
| 188 | + | |
| 189 | + /* Modifiers */ | |
| 190 | + | |
| 191 | + XK_Shift_L: 0xffe1, /* Left shift */ | |
| 192 | + XK_Shift_R: 0xffe2, /* Right shift */ | |
| 193 | + XK_Control_L: 0xffe3, /* Left control */ | |
| 194 | + XK_Control_R: 0xffe4, /* Right control */ | |
| 195 | + XK_Caps_Lock: 0xffe5, /* Caps lock */ | |
| 196 | + XK_Shift_Lock: 0xffe6, /* Shift lock */ | |
| 197 | + | |
| 198 | + XK_Meta_L: 0xffe7, /* Left meta */ | |
| 199 | + XK_Meta_R: 0xffe8, /* Right meta */ | |
| 200 | + XK_Alt_L: 0xffe9, /* Left alt */ | |
| 201 | + XK_Alt_R: 0xffea, /* Right alt */ | |
| 202 | + XK_Super_L: 0xffeb, /* Left super */ | |
| 203 | + XK_Super_R: 0xffec, /* Right super */ | |
| 204 | + XK_Hyper_L: 0xffed, /* Left hyper */ | |
| 205 | + XK_Hyper_R: 0xffee, /* Right hyper */ | |
| 206 | + | |
| 207 | + /* | |
| 208 | + * Keyboard (XKB) Extension function and modifier keys | |
| 209 | + * (from Appendix C of "The X Keyboard Extension: Protocol Specification") | |
| 210 | + * Byte 3 = 0xfe | |
| 211 | + */ | |
| 212 | + | |
| 213 | + XK_ISO_Level3_Shift: 0xfe03, /* AltGr */ | |
| 214 | + XK_ISO_Next_Group: 0xfe08, | |
| 215 | + XK_ISO_Prev_Group: 0xfe0a, | |
| 216 | + XK_ISO_First_Group: 0xfe0c, | |
| 217 | + XK_ISO_Last_Group: 0xfe0e, | |
| 218 | + | |
| 219 | + /* | |
| 220 | + * Latin 1 | |
| 221 | + * (ISO/IEC 8859-1: Unicode U+0020..U+00FF) | |
| 222 | + * Byte 3: 0 | |
| 223 | + */ | |
| 224 | + | |
| 225 | + XK_space: 0x0020, /* U+0020 SPACE */ | |
| 226 | + XK_exclam: 0x0021, /* U+0021 EXCLAMATION MARK */ | |
| 227 | + XK_quotedbl: 0x0022, /* U+0022 QUOTATION MARK */ | |
| 228 | + XK_numbersign: 0x0023, /* U+0023 NUMBER SIGN */ | |
| 229 | + XK_dollar: 0x0024, /* U+0024 DOLLAR SIGN */ | |
| 230 | + XK_percent: 0x0025, /* U+0025 PERCENT SIGN */ | |
| 231 | + XK_ampersand: 0x0026, /* U+0026 AMPERSAND */ | |
| 232 | + XK_apostrophe: 0x0027, /* U+0027 APOSTROPHE */ | |
| 233 | + XK_quoteright: 0x0027, /* deprecated */ | |
| 234 | + XK_parenleft: 0x0028, /* U+0028 LEFT PARENTHESIS */ | |
| 235 | + XK_parenright: 0x0029, /* U+0029 RIGHT PARENTHESIS */ | |
| 236 | + XK_asterisk: 0x002a, /* U+002A ASTERISK */ | |
| 237 | + XK_plus: 0x002b, /* U+002B PLUS SIGN */ | |
| 238 | + XK_comma: 0x002c, /* U+002C COMMA */ | |
| 239 | + XK_minus: 0x002d, /* U+002D HYPHEN-MINUS */ | |
| 240 | + XK_period: 0x002e, /* U+002E FULL STOP */ | |
| 241 | + XK_slash: 0x002f, /* U+002F SOLIDUS */ | |
| 242 | + XK_0: 0x0030, /* U+0030 DIGIT ZERO */ | |
| 243 | + XK_1: 0x0031, /* U+0031 DIGIT ONE */ | |
| 244 | + XK_2: 0x0032, /* U+0032 DIGIT TWO */ | |
| 245 | + XK_3: 0x0033, /* U+0033 DIGIT THREE */ | |
| 246 | + XK_4: 0x0034, /* U+0034 DIGIT FOUR */ | |
| 247 | + XK_5: 0x0035, /* U+0035 DIGIT FIVE */ | |
| 248 | + XK_6: 0x0036, /* U+0036 DIGIT SIX */ | |
| 249 | + XK_7: 0x0037, /* U+0037 DIGIT SEVEN */ | |
| 250 | + XK_8: 0x0038, /* U+0038 DIGIT EIGHT */ | |
| 251 | + XK_9: 0x0039, /* U+0039 DIGIT NINE */ | |
| 252 | + XK_colon: 0x003a, /* U+003A COLON */ | |
| 253 | + XK_semicolon: 0x003b, /* U+003B SEMICOLON */ | |
| 254 | + XK_less: 0x003c, /* U+003C LESS-THAN SIGN */ | |
| 255 | + XK_equal: 0x003d, /* U+003D EQUALS SIGN */ | |
| 256 | + XK_greater: 0x003e, /* U+003E GREATER-THAN SIGN */ | |
| 257 | + XK_question: 0x003f, /* U+003F QUESTION MARK */ | |
| 258 | + XK_at: 0x0040, /* U+0040 COMMERCIAL AT */ | |
| 259 | + XK_A: 0x0041, /* U+0041 LATIN CAPITAL LETTER A */ | |
| 260 | + XK_B: 0x0042, /* U+0042 LATIN CAPITAL LETTER B */ | |
| 261 | + XK_C: 0x0043, /* U+0043 LATIN CAPITAL LETTER C */ | |
| 262 | + XK_D: 0x0044, /* U+0044 LATIN CAPITAL LETTER D */ | |
| 263 | + XK_E: 0x0045, /* U+0045 LATIN CAPITAL LETTER E */ | |
| 264 | + XK_F: 0x0046, /* U+0046 LATIN CAPITAL LETTER F */ | |
| 265 | + XK_G: 0x0047, /* U+0047 LATIN CAPITAL LETTER G */ | |
| 266 | + XK_H: 0x0048, /* U+0048 LATIN CAPITAL LETTER H */ | |
| 267 | + XK_I: 0x0049, /* U+0049 LATIN CAPITAL LETTER I */ | |
| 268 | + XK_J: 0x004a, /* U+004A LATIN CAPITAL LETTER J */ | |
| 269 | + XK_K: 0x004b, /* U+004B LATIN CAPITAL LETTER K */ | |
| 270 | + XK_L: 0x004c, /* U+004C LATIN CAPITAL LETTER L */ | |
| 271 | + XK_M: 0x004d, /* U+004D LATIN CAPITAL LETTER M */ | |
| 272 | + XK_N: 0x004e, /* U+004E LATIN CAPITAL LETTER N */ | |
| 273 | + XK_O: 0x004f, /* U+004F LATIN CAPITAL LETTER O */ | |
| 274 | + XK_P: 0x0050, /* U+0050 LATIN CAPITAL LETTER P */ | |
| 275 | + XK_Q: 0x0051, /* U+0051 LATIN CAPITAL LETTER Q */ | |
| 276 | + XK_R: 0x0052, /* U+0052 LATIN CAPITAL LETTER R */ | |
| 277 | + XK_S: 0x0053, /* U+0053 LATIN CAPITAL LETTER S */ | |
| 278 | + XK_T: 0x0054, /* U+0054 LATIN CAPITAL LETTER T */ | |
| 279 | + XK_U: 0x0055, /* U+0055 LATIN CAPITAL LETTER U */ | |
| 280 | + XK_V: 0x0056, /* U+0056 LATIN CAPITAL LETTER V */ | |
| 281 | + XK_W: 0x0057, /* U+0057 LATIN CAPITAL LETTER W */ | |
| 282 | + XK_X: 0x0058, /* U+0058 LATIN CAPITAL LETTER X */ | |
| 283 | + XK_Y: 0x0059, /* U+0059 LATIN CAPITAL LETTER Y */ | |
| 284 | + XK_Z: 0x005a, /* U+005A LATIN CAPITAL LETTER Z */ | |
| 285 | + XK_bracketleft: 0x005b, /* U+005B LEFT SQUARE BRACKET */ | |
| 286 | + XK_backslash: 0x005c, /* U+005C REVERSE SOLIDUS */ | |
| 287 | + XK_bracketright: 0x005d, /* U+005D RIGHT SQUARE BRACKET */ | |
| 288 | + XK_asciicircum: 0x005e, /* U+005E CIRCUMFLEX ACCENT */ | |
| 289 | + XK_underscore: 0x005f, /* U+005F LOW LINE */ | |
| 290 | + XK_grave: 0x0060, /* U+0060 GRAVE ACCENT */ | |
| 291 | + XK_quoteleft: 0x0060, /* deprecated */ | |
| 292 | + XK_a: 0x0061, /* U+0061 LATIN SMALL LETTER A */ | |
| 293 | + XK_b: 0x0062, /* U+0062 LATIN SMALL LETTER B */ | |
| 294 | + XK_c: 0x0063, /* U+0063 LATIN SMALL LETTER C */ | |
| 295 | + XK_d: 0x0064, /* U+0064 LATIN SMALL LETTER D */ | |
| 296 | + XK_e: 0x0065, /* U+0065 LATIN SMALL LETTER E */ | |
| 297 | + XK_f: 0x0066, /* U+0066 LATIN SMALL LETTER F */ | |
| 298 | + XK_g: 0x0067, /* U+0067 LATIN SMALL LETTER G */ | |
| 299 | + XK_h: 0x0068, /* U+0068 LATIN SMALL LETTER H */ | |
| 300 | + XK_i: 0x0069, /* U+0069 LATIN SMALL LETTER I */ | |
| 301 | + XK_j: 0x006a, /* U+006A LATIN SMALL LETTER J */ | |
| 302 | + XK_k: 0x006b, /* U+006B LATIN SMALL LETTER K */ | |
| 303 | + XK_l: 0x006c, /* U+006C LATIN SMALL LETTER L */ | |
| 304 | + XK_m: 0x006d, /* U+006D LATIN SMALL LETTER M */ | |
| 305 | + XK_n: 0x006e, /* U+006E LATIN SMALL LETTER N */ | |
| 306 | + XK_o: 0x006f, /* U+006F LATIN SMALL LETTER O */ | |
| 307 | + XK_p: 0x0070, /* U+0070 LATIN SMALL LETTER P */ | |
| 308 | + XK_q: 0x0071, /* U+0071 LATIN SMALL LETTER Q */ | |
| 309 | + XK_r: 0x0072, /* U+0072 LATIN SMALL LETTER R */ | |
| 310 | + XK_s: 0x0073, /* U+0073 LATIN SMALL LETTER S */ | |
| 311 | + XK_t: 0x0074, /* U+0074 LATIN SMALL LETTER T */ | |
| 312 | + XK_u: 0x0075, /* U+0075 LATIN SMALL LETTER U */ | |
| 313 | + XK_v: 0x0076, /* U+0076 LATIN SMALL LETTER V */ | |
| 314 | + XK_w: 0x0077, /* U+0077 LATIN SMALL LETTER W */ | |
| 315 | + XK_x: 0x0078, /* U+0078 LATIN SMALL LETTER X */ | |
| 316 | + XK_y: 0x0079, /* U+0079 LATIN SMALL LETTER Y */ | |
| 317 | + XK_z: 0x007a, /* U+007A LATIN SMALL LETTER Z */ | |
| 318 | + XK_braceleft: 0x007b, /* U+007B LEFT CURLY BRACKET */ | |
| 319 | + XK_bar: 0x007c, /* U+007C VERTICAL LINE */ | |
| 320 | + XK_braceright: 0x007d, /* U+007D RIGHT CURLY BRACKET */ | |
| 321 | + XK_asciitilde: 0x007e, /* U+007E TILDE */ | |
| 322 | + | |
| 323 | + XK_nobreakspace: 0x00a0, /* U+00A0 NO-BREAK SPACE */ | |
| 324 | + XK_exclamdown: 0x00a1, /* U+00A1 INVERTED EXCLAMATION MARK */ | |
| 325 | + XK_cent: 0x00a2, /* U+00A2 CENT SIGN */ | |
| 326 | + XK_sterling: 0x00a3, /* U+00A3 POUND SIGN */ | |
| 327 | + XK_currency: 0x00a4, /* U+00A4 CURRENCY SIGN */ | |
| 328 | + XK_yen: 0x00a5, /* U+00A5 YEN SIGN */ | |
| 329 | + XK_brokenbar: 0x00a6, /* U+00A6 BROKEN BAR */ | |
| 330 | + XK_section: 0x00a7, /* U+00A7 SECTION SIGN */ | |
| 331 | + XK_diaeresis: 0x00a8, /* U+00A8 DIAERESIS */ | |
| 332 | + XK_copyright: 0x00a9, /* U+00A9 COPYRIGHT SIGN */ | |
| 333 | + XK_ordfeminine: 0x00aa, /* U+00AA FEMININE ORDINAL INDICATOR */ | |
| 334 | + XK_guillemotleft: 0x00ab, /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ | |
| 335 | + XK_notsign: 0x00ac, /* U+00AC NOT SIGN */ | |
| 336 | + XK_hyphen: 0x00ad, /* U+00AD SOFT HYPHEN */ | |
| 337 | + XK_registered: 0x00ae, /* U+00AE REGISTERED SIGN */ | |
| 338 | + XK_macron: 0x00af, /* U+00AF MACRON */ | |
| 339 | + XK_degree: 0x00b0, /* U+00B0 DEGREE SIGN */ | |
| 340 | + XK_plusminus: 0x00b1, /* U+00B1 PLUS-MINUS SIGN */ | |
| 341 | + XK_twosuperior: 0x00b2, /* U+00B2 SUPERSCRIPT TWO */ | |
| 342 | + XK_threesuperior: 0x00b3, /* U+00B3 SUPERSCRIPT THREE */ | |
| 343 | + XK_acute: 0x00b4, /* U+00B4 ACUTE ACCENT */ | |
| 344 | + XK_mu: 0x00b5, /* U+00B5 MICRO SIGN */ | |
| 345 | + XK_paragraph: 0x00b6, /* U+00B6 PILCROW SIGN */ | |
| 346 | + XK_periodcentered: 0x00b7, /* U+00B7 MIDDLE DOT */ | |
| 347 | + XK_cedilla: 0x00b8, /* U+00B8 CEDILLA */ | |
| 348 | + XK_onesuperior: 0x00b9, /* U+00B9 SUPERSCRIPT ONE */ | |
| 349 | + XK_masculine: 0x00ba, /* U+00BA MASCULINE ORDINAL INDICATOR */ | |
| 350 | + XK_guillemotright: 0x00bb, /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ | |
| 351 | + XK_onequarter: 0x00bc, /* U+00BC VULGAR FRACTION ONE QUARTER */ | |
| 352 | + XK_onehalf: 0x00bd, /* U+00BD VULGAR FRACTION ONE HALF */ | |
| 353 | + XK_threequarters: 0x00be, /* U+00BE VULGAR FRACTION THREE QUARTERS */ | |
| 354 | + XK_questiondown: 0x00bf, /* U+00BF INVERTED QUESTION MARK */ | |
| 355 | + XK_Agrave: 0x00c0, /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ | |
| 356 | + XK_Aacute: 0x00c1, /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ | |
| 357 | + XK_Acircumflex: 0x00c2, /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ | |
| 358 | + XK_Atilde: 0x00c3, /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ | |
| 359 | + XK_Adiaeresis: 0x00c4, /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ | |
| 360 | + XK_Aring: 0x00c5, /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ | |
| 361 | + XK_AE: 0x00c6, /* U+00C6 LATIN CAPITAL LETTER AE */ | |
| 362 | + XK_Ccedilla: 0x00c7, /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ | |
| 363 | + XK_Egrave: 0x00c8, /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ | |
| 364 | + XK_Eacute: 0x00c9, /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ | |
| 365 | + XK_Ecircumflex: 0x00ca, /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ | |
| 366 | + XK_Ediaeresis: 0x00cb, /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ | |
| 367 | + XK_Igrave: 0x00cc, /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ | |
| 368 | + XK_Iacute: 0x00cd, /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ | |
| 369 | + XK_Icircumflex: 0x00ce, /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ | |
| 370 | + XK_Idiaeresis: 0x00cf, /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ | |
| 371 | + XK_ETH: 0x00d0, /* U+00D0 LATIN CAPITAL LETTER ETH */ | |
| 372 | + XK_Eth: 0x00d0, /* deprecated */ | |
| 373 | + XK_Ntilde: 0x00d1, /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ | |
| 374 | + XK_Ograve: 0x00d2, /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ | |
| 375 | + XK_Oacute: 0x00d3, /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ | |
| 376 | + XK_Ocircumflex: 0x00d4, /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ | |
| 377 | + XK_Otilde: 0x00d5, /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ | |
| 378 | + XK_Odiaeresis: 0x00d6, /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ | |
| 379 | + XK_multiply: 0x00d7, /* U+00D7 MULTIPLICATION SIGN */ | |
| 380 | + XK_Oslash: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ | |
| 381 | + XK_Ooblique: 0x00d8, /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ | |
| 382 | + XK_Ugrave: 0x00d9, /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ | |
| 383 | + XK_Uacute: 0x00da, /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ | |
| 384 | + XK_Ucircumflex: 0x00db, /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ | |
| 385 | + XK_Udiaeresis: 0x00dc, /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ | |
| 386 | + XK_Yacute: 0x00dd, /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ | |
| 387 | + XK_THORN: 0x00de, /* U+00DE LATIN CAPITAL LETTER THORN */ | |
| 388 | + XK_Thorn: 0x00de, /* deprecated */ | |
| 389 | + XK_ssharp: 0x00df, /* U+00DF LATIN SMALL LETTER SHARP S */ | |
| 390 | + XK_agrave: 0x00e0, /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ | |
| 391 | + XK_aacute: 0x00e1, /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ | |
| 392 | + XK_acircumflex: 0x00e2, /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ | |
| 393 | + XK_atilde: 0x00e3, /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ | |
| 394 | + XK_adiaeresis: 0x00e4, /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ | |
| 395 | + XK_aring: 0x00e5, /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ | |
| 396 | + XK_ae: 0x00e6, /* U+00E6 LATIN SMALL LETTER AE */ | |
| 397 | + XK_ccedilla: 0x00e7, /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ | |
| 398 | + XK_egrave: 0x00e8, /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ | |
| 399 | + XK_eacute: 0x00e9, /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ | |
| 400 | + XK_ecircumflex: 0x00ea, /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ | |
| 401 | + XK_ediaeresis: 0x00eb, /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ | |
| 402 | + XK_igrave: 0x00ec, /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ | |
| 403 | + XK_iacute: 0x00ed, /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ | |
| 404 | + XK_icircumflex: 0x00ee, /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ | |
| 405 | + XK_idiaeresis: 0x00ef, /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ | |
| 406 | + XK_eth: 0x00f0, /* U+00F0 LATIN SMALL LETTER ETH */ | |
| 407 | + XK_ntilde: 0x00f1, /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ | |
| 408 | + XK_ograve: 0x00f2, /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ | |
| 409 | + XK_oacute: 0x00f3, /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ | |
| 410 | + XK_ocircumflex: 0x00f4, /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ | |
| 411 | + XK_otilde: 0x00f5, /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ | |
| 412 | + XK_odiaeresis: 0x00f6, /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ | |
| 413 | + XK_division: 0x00f7, /* U+00F7 DIVISION SIGN */ | |
| 414 | + XK_oslash: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ | |
| 415 | + XK_ooblique: 0x00f8, /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ | |
| 416 | + XK_ugrave: 0x00f9, /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ | |
| 417 | + XK_uacute: 0x00fa, /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ | |
| 418 | + XK_ucircumflex: 0x00fb, /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ | |
| 419 | + XK_udiaeresis: 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ | |
| 420 | + XK_yacute: 0x00fd, /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ | |
| 421 | + XK_thorn: 0x00fe, /* U+00FE LATIN SMALL LETTER THORN */ | |
| 422 | + XK_ydiaeresis: 0x00ff, /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ | |
| 423 | + | |
| 424 | + /* | |
| 425 | + * Korean | |
| 426 | + * Byte 3 = 0x0e | |
| 427 | + */ | |
| 428 | + | |
| 429 | + XK_Hangul: 0xff31, /* Hangul start/stop(toggle) */ | |
| 430 | + XK_Hangul_Hanja: 0xff34, /* Start Hangul->Hanja Conversion */ | |
| 431 | + XK_Hangul_Jeonja: 0xff38, /* Jeonja mode */ | |
| 432 | + | |
| 433 | + /* | |
| 434 | + * XFree86 vendor specific keysyms. | |
| 435 | + * | |
| 436 | + * The XFree86 keysym range is 0x10080001 - 0x1008FFFF. | |
| 437 | + */ | |
| 438 | + | |
| 439 | + XF86XK_ModeLock: 0x1008FF01, | |
| 440 | + XF86XK_MonBrightnessUp: 0x1008FF02, | |
| 441 | + XF86XK_MonBrightnessDown: 0x1008FF03, | |
| 442 | + XF86XK_KbdLightOnOff: 0x1008FF04, | |
| 443 | + XF86XK_KbdBrightnessUp: 0x1008FF05, | |
| 444 | + XF86XK_KbdBrightnessDown: 0x1008FF06, | |
| 445 | + XF86XK_Standby: 0x1008FF10, | |
| 446 | + XF86XK_AudioLowerVolume: 0x1008FF11, | |
| 447 | + XF86XK_AudioMute: 0x1008FF12, | |
| 448 | + XF86XK_AudioRaiseVolume: 0x1008FF13, | |
| 449 | + XF86XK_AudioPlay: 0x1008FF14, | |
| 450 | + XF86XK_AudioStop: 0x1008FF15, | |
| 451 | + XF86XK_AudioPrev: 0x1008FF16, | |
| 452 | + XF86XK_AudioNext: 0x1008FF17, | |
| 453 | + XF86XK_HomePage: 0x1008FF18, | |
| 454 | + XF86XK_Mail: 0x1008FF19, | |
| 455 | + XF86XK_Start: 0x1008FF1A, | |
| 456 | + XF86XK_Search: 0x1008FF1B, | |
| 457 | + XF86XK_AudioRecord: 0x1008FF1C, | |
| 458 | + XF86XK_Calculator: 0x1008FF1D, | |
| 459 | + XF86XK_Memo: 0x1008FF1E, | |
| 460 | + XF86XK_ToDoList: 0x1008FF1F, | |
| 461 | + XF86XK_Calendar: 0x1008FF20, | |
| 462 | + XF86XK_PowerDown: 0x1008FF21, | |
| 463 | + XF86XK_ContrastAdjust: 0x1008FF22, | |
| 464 | + XF86XK_RockerUp: 0x1008FF23, | |
| 465 | + XF86XK_RockerDown: 0x1008FF24, | |
| 466 | + XF86XK_RockerEnter: 0x1008FF25, | |
| 467 | + XF86XK_Back: 0x1008FF26, | |
| 468 | + XF86XK_Forward: 0x1008FF27, | |
| 469 | + XF86XK_Stop: 0x1008FF28, | |
| 470 | + XF86XK_Refresh: 0x1008FF29, | |
| 471 | + XF86XK_PowerOff: 0x1008FF2A, | |
| 472 | + XF86XK_WakeUp: 0x1008FF2B, | |
| 473 | + XF86XK_Eject: 0x1008FF2C, | |
| 474 | + XF86XK_ScreenSaver: 0x1008FF2D, | |
| 475 | + XF86XK_WWW: 0x1008FF2E, | |
| 476 | + XF86XK_Sleep: 0x1008FF2F, | |
| 477 | + XF86XK_Favorites: 0x1008FF30, | |
| 478 | + XF86XK_AudioPause: 0x1008FF31, | |
| 479 | + XF86XK_AudioMedia: 0x1008FF32, | |
| 480 | + XF86XK_MyComputer: 0x1008FF33, | |
| 481 | + XF86XK_VendorHome: 0x1008FF34, | |
| 482 | + XF86XK_LightBulb: 0x1008FF35, | |
| 483 | + XF86XK_Shop: 0x1008FF36, | |
| 484 | + XF86XK_History: 0x1008FF37, | |
| 485 | + XF86XK_OpenURL: 0x1008FF38, | |
| 486 | + XF86XK_AddFavorite: 0x1008FF39, | |
| 487 | + XF86XK_HotLinks: 0x1008FF3A, | |
| 488 | + XF86XK_BrightnessAdjust: 0x1008FF3B, | |
| 489 | + XF86XK_Finance: 0x1008FF3C, | |
| 490 | + XF86XK_Community: 0x1008FF3D, | |
| 491 | + XF86XK_AudioRewind: 0x1008FF3E, | |
| 492 | + XF86XK_BackForward: 0x1008FF3F, | |
| 493 | + XF86XK_Launch0: 0x1008FF40, | |
| 494 | + XF86XK_Launch1: 0x1008FF41, | |
| 495 | + XF86XK_Launch2: 0x1008FF42, | |
| 496 | + XF86XK_Launch3: 0x1008FF43, | |
| 497 | + XF86XK_Launch4: 0x1008FF44, | |
| 498 | + XF86XK_Launch5: 0x1008FF45, | |
| 499 | + XF86XK_Launch6: 0x1008FF46, | |
| 500 | + XF86XK_Launch7: 0x1008FF47, | |
| 501 | + XF86XK_Launch8: 0x1008FF48, | |
| 502 | + XF86XK_Launch9: 0x1008FF49, | |
| 503 | + XF86XK_LaunchA: 0x1008FF4A, | |
| 504 | + XF86XK_LaunchB: 0x1008FF4B, | |
| 505 | + XF86XK_LaunchC: 0x1008FF4C, | |
| 506 | + XF86XK_LaunchD: 0x1008FF4D, | |
| 507 | + XF86XK_LaunchE: 0x1008FF4E, | |
| 508 | + XF86XK_LaunchF: 0x1008FF4F, | |
| 509 | + XF86XK_ApplicationLeft: 0x1008FF50, | |
| 510 | + XF86XK_ApplicationRight: 0x1008FF51, | |
| 511 | + XF86XK_Book: 0x1008FF52, | |
| 512 | + XF86XK_CD: 0x1008FF53, | |
| 513 | + XF86XK_Calculater: 0x1008FF54, | |
| 514 | + XF86XK_Clear: 0x1008FF55, | |
| 515 | + XF86XK_Close: 0x1008FF56, | |
| 516 | + XF86XK_Copy: 0x1008FF57, | |
| 517 | + XF86XK_Cut: 0x1008FF58, | |
| 518 | + XF86XK_Display: 0x1008FF59, | |
| 519 | + XF86XK_DOS: 0x1008FF5A, | |
| 520 | + XF86XK_Documents: 0x1008FF5B, | |
| 521 | + XF86XK_Excel: 0x1008FF5C, | |
| 522 | + XF86XK_Explorer: 0x1008FF5D, | |
| 523 | + XF86XK_Game: 0x1008FF5E, | |
| 524 | + XF86XK_Go: 0x1008FF5F, | |
| 525 | + XF86XK_iTouch: 0x1008FF60, | |
| 526 | + XF86XK_LogOff: 0x1008FF61, | |
| 527 | + XF86XK_Market: 0x1008FF62, | |
| 528 | + XF86XK_Meeting: 0x1008FF63, | |
| 529 | + XF86XK_MenuKB: 0x1008FF65, | |
| 530 | + XF86XK_MenuPB: 0x1008FF66, | |
| 531 | + XF86XK_MySites: 0x1008FF67, | |
| 532 | + XF86XK_New: 0x1008FF68, | |
| 533 | + XF86XK_News: 0x1008FF69, | |
| 534 | + XF86XK_OfficeHome: 0x1008FF6A, | |
| 535 | + XF86XK_Open: 0x1008FF6B, | |
| 536 | + XF86XK_Option: 0x1008FF6C, | |
| 537 | + XF86XK_Paste: 0x1008FF6D, | |
| 538 | + XF86XK_Phone: 0x1008FF6E, | |
| 539 | + XF86XK_Q: 0x1008FF70, | |
| 540 | + XF86XK_Reply: 0x1008FF72, | |
| 541 | + XF86XK_Reload: 0x1008FF73, | |
| 542 | + XF86XK_RotateWindows: 0x1008FF74, | |
| 543 | + XF86XK_RotationPB: 0x1008FF75, | |
| 544 | + XF86XK_RotationKB: 0x1008FF76, | |
| 545 | + XF86XK_Save: 0x1008FF77, | |
| 546 | + XF86XK_ScrollUp: 0x1008FF78, | |
| 547 | + XF86XK_ScrollDown: 0x1008FF79, | |
| 548 | + XF86XK_ScrollClick: 0x1008FF7A, | |
| 549 | + XF86XK_Send: 0x1008FF7B, | |
| 550 | + XF86XK_Spell: 0x1008FF7C, | |
| 551 | + XF86XK_SplitScreen: 0x1008FF7D, | |
| 552 | + XF86XK_Support: 0x1008FF7E, | |
| 553 | + XF86XK_TaskPane: 0x1008FF7F, | |
| 554 | + XF86XK_Terminal: 0x1008FF80, | |
| 555 | + XF86XK_Tools: 0x1008FF81, | |
| 556 | + XF86XK_Travel: 0x1008FF82, | |
| 557 | + XF86XK_UserPB: 0x1008FF84, | |
| 558 | + XF86XK_User1KB: 0x1008FF85, | |
| 559 | + XF86XK_User2KB: 0x1008FF86, | |
| 560 | + XF86XK_Video: 0x1008FF87, | |
| 561 | + XF86XK_WheelButton: 0x1008FF88, | |
| 562 | + XF86XK_Word: 0x1008FF89, | |
| 563 | + XF86XK_Xfer: 0x1008FF8A, | |
| 564 | + XF86XK_ZoomIn: 0x1008FF8B, | |
| 565 | + XF86XK_ZoomOut: 0x1008FF8C, | |
| 566 | + XF86XK_Away: 0x1008FF8D, | |
| 567 | + XF86XK_Messenger: 0x1008FF8E, | |
| 568 | + XF86XK_WebCam: 0x1008FF8F, | |
| 569 | + XF86XK_MailForward: 0x1008FF90, | |
| 570 | + XF86XK_Pictures: 0x1008FF91, | |
| 571 | + XF86XK_Music: 0x1008FF92, | |
| 572 | + XF86XK_Battery: 0x1008FF93, | |
| 573 | + XF86XK_Bluetooth: 0x1008FF94, | |
| 574 | + XF86XK_WLAN: 0x1008FF95, | |
| 575 | + XF86XK_UWB: 0x1008FF96, | |
| 576 | + XF86XK_AudioForward: 0x1008FF97, | |
| 577 | + XF86XK_AudioRepeat: 0x1008FF98, | |
| 578 | + XF86XK_AudioRandomPlay: 0x1008FF99, | |
| 579 | + XF86XK_Subtitle: 0x1008FF9A, | |
| 580 | + XF86XK_AudioCycleTrack: 0x1008FF9B, | |
| 581 | + XF86XK_CycleAngle: 0x1008FF9C, | |
| 582 | + XF86XK_FrameBack: 0x1008FF9D, | |
| 583 | + XF86XK_FrameForward: 0x1008FF9E, | |
| 584 | + XF86XK_Time: 0x1008FF9F, | |
| 585 | + XF86XK_Select: 0x1008FFA0, | |
| 586 | + XF86XK_View: 0x1008FFA1, | |
| 587 | + XF86XK_TopMenu: 0x1008FFA2, | |
| 588 | + XF86XK_Red: 0x1008FFA3, | |
| 589 | + XF86XK_Green: 0x1008FFA4, | |
| 590 | + XF86XK_Yellow: 0x1008FFA5, | |
| 591 | + XF86XK_Blue: 0x1008FFA6, | |
| 592 | + XF86XK_Suspend: 0x1008FFA7, | |
| 593 | + XF86XK_Hibernate: 0x1008FFA8, | |
| 594 | + XF86XK_TouchpadToggle: 0x1008FFA9, | |
| 595 | + XF86XK_TouchpadOn: 0x1008FFB0, | |
| 596 | + XF86XK_TouchpadOff: 0x1008FFB1, | |
| 597 | + XF86XK_AudioMicMute: 0x1008FFB2, | |
| 598 | + XF86XK_Switch_VT_1: 0x1008FE01, | |
| 599 | + XF86XK_Switch_VT_2: 0x1008FE02, | |
| 600 | + XF86XK_Switch_VT_3: 0x1008FE03, | |
| 601 | + XF86XK_Switch_VT_4: 0x1008FE04, | |
| 602 | + XF86XK_Switch_VT_5: 0x1008FE05, | |
| 603 | + XF86XK_Switch_VT_6: 0x1008FE06, | |
| 604 | + XF86XK_Switch_VT_7: 0x1008FE07, | |
| 605 | + XF86XK_Switch_VT_8: 0x1008FE08, | |
| 606 | + XF86XK_Switch_VT_9: 0x1008FE09, | |
| 607 | + XF86XK_Switch_VT_10: 0x1008FE0A, | |
| 608 | + XF86XK_Switch_VT_11: 0x1008FE0B, | |
| 609 | + XF86XK_Switch_VT_12: 0x1008FE0C, | |
| 610 | + XF86XK_Ungrab: 0x1008FE20, | |
| 611 | + XF86XK_ClearGrab: 0x1008FE21, | |
| 612 | + XF86XK_Next_VMode: 0x1008FE22, | |
| 613 | + XF86XK_Prev_VMode: 0x1008FE23, | |
| 614 | + XF86XK_LogWindowTree: 0x1008FE24, | |
| 615 | + XF86XK_LogGrabInfo: 0x1008FE25, | |
| 616 | +}; | |
added
public/vendor/novnc/core/input/keysymdef.js
+688 −0
@@ -0,0 +1,688 @@ | ||
| 1 | +/* | |
| 2 | + * Mapping from Unicode codepoints to X11/RFB keysyms | |
| 3 | + * | |
| 4 | + * This file was automatically generated from keysymdef.h | |
| 5 | + * DO NOT EDIT! | |
| 6 | + */ | |
| 7 | + | |
| 8 | +/* Functions at the bottom */ | |
| 9 | + | |
| 10 | +const codepoints = { | |
| 11 | + 0x0100: 0x03c0, // XK_Amacron | |
| 12 | + 0x0101: 0x03e0, // XK_amacron | |
| 13 | + 0x0102: 0x01c3, // XK_Abreve | |
| 14 | + 0x0103: 0x01e3, // XK_abreve | |
| 15 | + 0x0104: 0x01a1, // XK_Aogonek | |
| 16 | + 0x0105: 0x01b1, // XK_aogonek | |
| 17 | + 0x0106: 0x01c6, // XK_Cacute | |
| 18 | + 0x0107: 0x01e6, // XK_cacute | |
| 19 | + 0x0108: 0x02c6, // XK_Ccircumflex | |
| 20 | + 0x0109: 0x02e6, // XK_ccircumflex | |
| 21 | + 0x010a: 0x02c5, // XK_Cabovedot | |
| 22 | + 0x010b: 0x02e5, // XK_cabovedot | |
| 23 | + 0x010c: 0x01c8, // XK_Ccaron | |
| 24 | + 0x010d: 0x01e8, // XK_ccaron | |
| 25 | + 0x010e: 0x01cf, // XK_Dcaron | |
| 26 | + 0x010f: 0x01ef, // XK_dcaron | |
| 27 | + 0x0110: 0x01d0, // XK_Dstroke | |
| 28 | + 0x0111: 0x01f0, // XK_dstroke | |
| 29 | + 0x0112: 0x03aa, // XK_Emacron | |
| 30 | + 0x0113: 0x03ba, // XK_emacron | |
| 31 | + 0x0116: 0x03cc, // XK_Eabovedot | |
| 32 | + 0x0117: 0x03ec, // XK_eabovedot | |
| 33 | + 0x0118: 0x01ca, // XK_Eogonek | |
| 34 | + 0x0119: 0x01ea, // XK_eogonek | |
| 35 | + 0x011a: 0x01cc, // XK_Ecaron | |
| 36 | + 0x011b: 0x01ec, // XK_ecaron | |
| 37 | + 0x011c: 0x02d8, // XK_Gcircumflex | |
| 38 | + 0x011d: 0x02f8, // XK_gcircumflex | |
| 39 | + 0x011e: 0x02ab, // XK_Gbreve | |
| 40 | + 0x011f: 0x02bb, // XK_gbreve | |
| 41 | + 0x0120: 0x02d5, // XK_Gabovedot | |
| 42 | + 0x0121: 0x02f5, // XK_gabovedot | |
| 43 | + 0x0122: 0x03ab, // XK_Gcedilla | |
| 44 | + 0x0123: 0x03bb, // XK_gcedilla | |
| 45 | + 0x0124: 0x02a6, // XK_Hcircumflex | |
| 46 | + 0x0125: 0x02b6, // XK_hcircumflex | |
| 47 | + 0x0126: 0x02a1, // XK_Hstroke | |
| 48 | + 0x0127: 0x02b1, // XK_hstroke | |
| 49 | + 0x0128: 0x03a5, // XK_Itilde | |
| 50 | + 0x0129: 0x03b5, // XK_itilde | |
| 51 | + 0x012a: 0x03cf, // XK_Imacron | |
| 52 | + 0x012b: 0x03ef, // XK_imacron | |
| 53 | + 0x012e: 0x03c7, // XK_Iogonek | |
| 54 | + 0x012f: 0x03e7, // XK_iogonek | |
| 55 | + 0x0130: 0x02a9, // XK_Iabovedot | |
| 56 | + 0x0131: 0x02b9, // XK_idotless | |
| 57 | + 0x0134: 0x02ac, // XK_Jcircumflex | |
| 58 | + 0x0135: 0x02bc, // XK_jcircumflex | |
| 59 | + 0x0136: 0x03d3, // XK_Kcedilla | |
| 60 | + 0x0137: 0x03f3, // XK_kcedilla | |
| 61 | + 0x0138: 0x03a2, // XK_kra | |
| 62 | + 0x0139: 0x01c5, // XK_Lacute | |
| 63 | + 0x013a: 0x01e5, // XK_lacute | |
| 64 | + 0x013b: 0x03a6, // XK_Lcedilla | |
| 65 | + 0x013c: 0x03b6, // XK_lcedilla | |
| 66 | + 0x013d: 0x01a5, // XK_Lcaron | |
| 67 | + 0x013e: 0x01b5, // XK_lcaron | |
| 68 | + 0x0141: 0x01a3, // XK_Lstroke | |
| 69 | + 0x0142: 0x01b3, // XK_lstroke | |
| 70 | + 0x0143: 0x01d1, // XK_Nacute | |
| 71 | + 0x0144: 0x01f1, // XK_nacute | |
| 72 | + 0x0145: 0x03d1, // XK_Ncedilla | |
| 73 | + 0x0146: 0x03f1, // XK_ncedilla | |
| 74 | + 0x0147: 0x01d2, // XK_Ncaron | |
| 75 | + 0x0148: 0x01f2, // XK_ncaron | |
| 76 | + 0x014a: 0x03bd, // XK_ENG | |
| 77 | + 0x014b: 0x03bf, // XK_eng | |
| 78 | + 0x014c: 0x03d2, // XK_Omacron | |
| 79 | + 0x014d: 0x03f2, // XK_omacron | |
| 80 | + 0x0150: 0x01d5, // XK_Odoubleacute | |
| 81 | + 0x0151: 0x01f5, // XK_odoubleacute | |
| 82 | + 0x0152: 0x13bc, // XK_OE | |
| 83 | + 0x0153: 0x13bd, // XK_oe | |
| 84 | + 0x0154: 0x01c0, // XK_Racute | |
| 85 | + 0x0155: 0x01e0, // XK_racute | |
| 86 | + 0x0156: 0x03a3, // XK_Rcedilla | |
| 87 | + 0x0157: 0x03b3, // XK_rcedilla | |
| 88 | + 0x0158: 0x01d8, // XK_Rcaron | |
| 89 | + 0x0159: 0x01f8, // XK_rcaron | |
| 90 | + 0x015a: 0x01a6, // XK_Sacute | |
| 91 | + 0x015b: 0x01b6, // XK_sacute | |
| 92 | + 0x015c: 0x02de, // XK_Scircumflex | |
| 93 | + 0x015d: 0x02fe, // XK_scircumflex | |
| 94 | + 0x015e: 0x01aa, // XK_Scedilla | |
| 95 | + 0x015f: 0x01ba, // XK_scedilla | |
| 96 | + 0x0160: 0x01a9, // XK_Scaron | |
| 97 | + 0x0161: 0x01b9, // XK_scaron | |
| 98 | + 0x0162: 0x01de, // XK_Tcedilla | |
| 99 | + 0x0163: 0x01fe, // XK_tcedilla | |
| 100 | + 0x0164: 0x01ab, // XK_Tcaron | |
| 101 | + 0x0165: 0x01bb, // XK_tcaron | |
| 102 | + 0x0166: 0x03ac, // XK_Tslash | |
| 103 | + 0x0167: 0x03bc, // XK_tslash | |
| 104 | + 0x0168: 0x03dd, // XK_Utilde | |
| 105 | + 0x0169: 0x03fd, // XK_utilde | |
| 106 | + 0x016a: 0x03de, // XK_Umacron | |
| 107 | + 0x016b: 0x03fe, // XK_umacron | |
| 108 | + 0x016c: 0x02dd, // XK_Ubreve | |
| 109 | + 0x016d: 0x02fd, // XK_ubreve | |
| 110 | + 0x016e: 0x01d9, // XK_Uring | |
| 111 | + 0x016f: 0x01f9, // XK_uring | |
| 112 | + 0x0170: 0x01db, // XK_Udoubleacute | |
| 113 | + 0x0171: 0x01fb, // XK_udoubleacute | |
| 114 | + 0x0172: 0x03d9, // XK_Uogonek | |
| 115 | + 0x0173: 0x03f9, // XK_uogonek | |
| 116 | + 0x0178: 0x13be, // XK_Ydiaeresis | |
| 117 | + 0x0179: 0x01ac, // XK_Zacute | |
| 118 | + 0x017a: 0x01bc, // XK_zacute | |
| 119 | + 0x017b: 0x01af, // XK_Zabovedot | |
| 120 | + 0x017c: 0x01bf, // XK_zabovedot | |
| 121 | + 0x017d: 0x01ae, // XK_Zcaron | |
| 122 | + 0x017e: 0x01be, // XK_zcaron | |
| 123 | + 0x0192: 0x08f6, // XK_function | |
| 124 | + 0x01d2: 0x10001d1, // XK_Ocaron | |
| 125 | + 0x02c7: 0x01b7, // XK_caron | |
| 126 | + 0x02d8: 0x01a2, // XK_breve | |
| 127 | + 0x02d9: 0x01ff, // XK_abovedot | |
| 128 | + 0x02db: 0x01b2, // XK_ogonek | |
| 129 | + 0x02dd: 0x01bd, // XK_doubleacute | |
| 130 | + 0x0385: 0x07ae, // XK_Greek_accentdieresis | |
| 131 | + 0x0386: 0x07a1, // XK_Greek_ALPHAaccent | |
| 132 | + 0x0388: 0x07a2, // XK_Greek_EPSILONaccent | |
| 133 | + 0x0389: 0x07a3, // XK_Greek_ETAaccent | |
| 134 | + 0x038a: 0x07a4, // XK_Greek_IOTAaccent | |
| 135 | + 0x038c: 0x07a7, // XK_Greek_OMICRONaccent | |
| 136 | + 0x038e: 0x07a8, // XK_Greek_UPSILONaccent | |
| 137 | + 0x038f: 0x07ab, // XK_Greek_OMEGAaccent | |
| 138 | + 0x0390: 0x07b6, // XK_Greek_iotaaccentdieresis | |
| 139 | + 0x0391: 0x07c1, // XK_Greek_ALPHA | |
| 140 | + 0x0392: 0x07c2, // XK_Greek_BETA | |
| 141 | + 0x0393: 0x07c3, // XK_Greek_GAMMA | |
| 142 | + 0x0394: 0x07c4, // XK_Greek_DELTA | |
| 143 | + 0x0395: 0x07c5, // XK_Greek_EPSILON | |
| 144 | + 0x0396: 0x07c6, // XK_Greek_ZETA | |
| 145 | + 0x0397: 0x07c7, // XK_Greek_ETA | |
| 146 | + 0x0398: 0x07c8, // XK_Greek_THETA | |
| 147 | + 0x0399: 0x07c9, // XK_Greek_IOTA | |
| 148 | + 0x039a: 0x07ca, // XK_Greek_KAPPA | |
| 149 | + 0x039b: 0x07cb, // XK_Greek_LAMDA | |
| 150 | + 0x039c: 0x07cc, // XK_Greek_MU | |
| 151 | + 0x039d: 0x07cd, // XK_Greek_NU | |
| 152 | + 0x039e: 0x07ce, // XK_Greek_XI | |
| 153 | + 0x039f: 0x07cf, // XK_Greek_OMICRON | |
| 154 | + 0x03a0: 0x07d0, // XK_Greek_PI | |
| 155 | + 0x03a1: 0x07d1, // XK_Greek_RHO | |
| 156 | + 0x03a3: 0x07d2, // XK_Greek_SIGMA | |
| 157 | + 0x03a4: 0x07d4, // XK_Greek_TAU | |
| 158 | + 0x03a5: 0x07d5, // XK_Greek_UPSILON | |
| 159 | + 0x03a6: 0x07d6, // XK_Greek_PHI | |
| 160 | + 0x03a7: 0x07d7, // XK_Greek_CHI | |
| 161 | + 0x03a8: 0x07d8, // XK_Greek_PSI | |
| 162 | + 0x03a9: 0x07d9, // XK_Greek_OMEGA | |
| 163 | + 0x03aa: 0x07a5, // XK_Greek_IOTAdieresis | |
| 164 | + 0x03ab: 0x07a9, // XK_Greek_UPSILONdieresis | |
| 165 | + 0x03ac: 0x07b1, // XK_Greek_alphaaccent | |
| 166 | + 0x03ad: 0x07b2, // XK_Greek_epsilonaccent | |
| 167 | + 0x03ae: 0x07b3, // XK_Greek_etaaccent | |
| 168 | + 0x03af: 0x07b4, // XK_Greek_iotaaccent | |
| 169 | + 0x03b0: 0x07ba, // XK_Greek_upsilonaccentdieresis | |
| 170 | + 0x03b1: 0x07e1, // XK_Greek_alpha | |
| 171 | + 0x03b2: 0x07e2, // XK_Greek_beta | |
| 172 | + 0x03b3: 0x07e3, // XK_Greek_gamma | |
| 173 | + 0x03b4: 0x07e4, // XK_Greek_delta | |
| 174 | + 0x03b5: 0x07e5, // XK_Greek_epsilon | |
| 175 | + 0x03b6: 0x07e6, // XK_Greek_zeta | |
| 176 | + 0x03b7: 0x07e7, // XK_Greek_eta | |
| 177 | + 0x03b8: 0x07e8, // XK_Greek_theta | |
| 178 | + 0x03b9: 0x07e9, // XK_Greek_iota | |
| 179 | + 0x03ba: 0x07ea, // XK_Greek_kappa | |
| 180 | + 0x03bb: 0x07eb, // XK_Greek_lamda | |
| 181 | + 0x03bc: 0x07ec, // XK_Greek_mu | |
| 182 | + 0x03bd: 0x07ed, // XK_Greek_nu | |
| 183 | + 0x03be: 0x07ee, // XK_Greek_xi | |
| 184 | + 0x03bf: 0x07ef, // XK_Greek_omicron | |
| 185 | + 0x03c0: 0x07f0, // XK_Greek_pi | |
| 186 | + 0x03c1: 0x07f1, // XK_Greek_rho | |
| 187 | + 0x03c2: 0x07f3, // XK_Greek_finalsmallsigma | |
| 188 | + 0x03c3: 0x07f2, // XK_Greek_sigma | |
| 189 | + 0x03c4: 0x07f4, // XK_Greek_tau | |
| 190 | + 0x03c5: 0x07f5, // XK_Greek_upsilon | |
| 191 | + 0x03c6: 0x07f6, // XK_Greek_phi | |
| 192 | + 0x03c7: 0x07f7, // XK_Greek_chi | |
| 193 | + 0x03c8: 0x07f8, // XK_Greek_psi | |
| 194 | + 0x03c9: 0x07f9, // XK_Greek_omega | |
| 195 | + 0x03ca: 0x07b5, // XK_Greek_iotadieresis | |
| 196 | + 0x03cb: 0x07b9, // XK_Greek_upsilondieresis | |
| 197 | + 0x03cc: 0x07b7, // XK_Greek_omicronaccent | |
| 198 | + 0x03cd: 0x07b8, // XK_Greek_upsilonaccent | |
| 199 | + 0x03ce: 0x07bb, // XK_Greek_omegaaccent | |
| 200 | + 0x0401: 0x06b3, // XK_Cyrillic_IO | |
| 201 | + 0x0402: 0x06b1, // XK_Serbian_DJE | |
| 202 | + 0x0403: 0x06b2, // XK_Macedonia_GJE | |
| 203 | + 0x0404: 0x06b4, // XK_Ukrainian_IE | |
| 204 | + 0x0405: 0x06b5, // XK_Macedonia_DSE | |
| 205 | + 0x0406: 0x06b6, // XK_Ukrainian_I | |
| 206 | + 0x0407: 0x06b7, // XK_Ukrainian_YI | |
| 207 | + 0x0408: 0x06b8, // XK_Cyrillic_JE | |
| 208 | + 0x0409: 0x06b9, // XK_Cyrillic_LJE | |
| 209 | + 0x040a: 0x06ba, // XK_Cyrillic_NJE | |
| 210 | + 0x040b: 0x06bb, // XK_Serbian_TSHE | |
| 211 | + 0x040c: 0x06bc, // XK_Macedonia_KJE | |
| 212 | + 0x040e: 0x06be, // XK_Byelorussian_SHORTU | |
| 213 | + 0x040f: 0x06bf, // XK_Cyrillic_DZHE | |
| 214 | + 0x0410: 0x06e1, // XK_Cyrillic_A | |
| 215 | + 0x0411: 0x06e2, // XK_Cyrillic_BE | |
| 216 | + 0x0412: 0x06f7, // XK_Cyrillic_VE | |
| 217 | + 0x0413: 0x06e7, // XK_Cyrillic_GHE | |
| 218 | + 0x0414: 0x06e4, // XK_Cyrillic_DE | |
| 219 | + 0x0415: 0x06e5, // XK_Cyrillic_IE | |
| 220 | + 0x0416: 0x06f6, // XK_Cyrillic_ZHE | |
| 221 | + 0x0417: 0x06fa, // XK_Cyrillic_ZE | |
| 222 | + 0x0418: 0x06e9, // XK_Cyrillic_I | |
| 223 | + 0x0419: 0x06ea, // XK_Cyrillic_SHORTI | |
| 224 | + 0x041a: 0x06eb, // XK_Cyrillic_KA | |
| 225 | + 0x041b: 0x06ec, // XK_Cyrillic_EL | |
| 226 | + 0x041c: 0x06ed, // XK_Cyrillic_EM | |
| 227 | + 0x041d: 0x06ee, // XK_Cyrillic_EN | |
| 228 | + 0x041e: 0x06ef, // XK_Cyrillic_O | |
| 229 | + 0x041f: 0x06f0, // XK_Cyrillic_PE | |
| 230 | + 0x0420: 0x06f2, // XK_Cyrillic_ER | |
| 231 | + 0x0421: 0x06f3, // XK_Cyrillic_ES | |
| 232 | + 0x0422: 0x06f4, // XK_Cyrillic_TE | |
| 233 | + 0x0423: 0x06f5, // XK_Cyrillic_U | |
| 234 | + 0x0424: 0x06e6, // XK_Cyrillic_EF | |
| 235 | + 0x0425: 0x06e8, // XK_Cyrillic_HA | |
| 236 | + 0x0426: 0x06e3, // XK_Cyrillic_TSE | |
| 237 | + 0x0427: 0x06fe, // XK_Cyrillic_CHE | |
| 238 | + 0x0428: 0x06fb, // XK_Cyrillic_SHA | |
| 239 | + 0x0429: 0x06fd, // XK_Cyrillic_SHCHA | |
| 240 | + 0x042a: 0x06ff, // XK_Cyrillic_HARDSIGN | |
| 241 | + 0x042b: 0x06f9, // XK_Cyrillic_YERU | |
| 242 | + 0x042c: 0x06f8, // XK_Cyrillic_SOFTSIGN | |
| 243 | + 0x042d: 0x06fc, // XK_Cyrillic_E | |
| 244 | + 0x042e: 0x06e0, // XK_Cyrillic_YU | |
| 245 | + 0x042f: 0x06f1, // XK_Cyrillic_YA | |
| 246 | + 0x0430: 0x06c1, // XK_Cyrillic_a | |
| 247 | + 0x0431: 0x06c2, // XK_Cyrillic_be | |
| 248 | + 0x0432: 0x06d7, // XK_Cyrillic_ve | |
| 249 | + 0x0433: 0x06c7, // XK_Cyrillic_ghe | |
| 250 | + 0x0434: 0x06c4, // XK_Cyrillic_de | |
| 251 | + 0x0435: 0x06c5, // XK_Cyrillic_ie | |
| 252 | + 0x0436: 0x06d6, // XK_Cyrillic_zhe | |
| 253 | + 0x0437: 0x06da, // XK_Cyrillic_ze | |
| 254 | + 0x0438: 0x06c9, // XK_Cyrillic_i | |
| 255 | + 0x0439: 0x06ca, // XK_Cyrillic_shorti | |
| 256 | + 0x043a: 0x06cb, // XK_Cyrillic_ka | |
| 257 | + 0x043b: 0x06cc, // XK_Cyrillic_el | |
| 258 | + 0x043c: 0x06cd, // XK_Cyrillic_em | |
| 259 | + 0x043d: 0x06ce, // XK_Cyrillic_en | |
| 260 | + 0x043e: 0x06cf, // XK_Cyrillic_o | |
| 261 | + 0x043f: 0x06d0, // XK_Cyrillic_pe | |
| 262 | + 0x0440: 0x06d2, // XK_Cyrillic_er | |
| 263 | + 0x0441: 0x06d3, // XK_Cyrillic_es | |
| 264 | + 0x0442: 0x06d4, // XK_Cyrillic_te | |
| 265 | + 0x0443: 0x06d5, // XK_Cyrillic_u | |
| 266 | + 0x0444: 0x06c6, // XK_Cyrillic_ef | |
| 267 | + 0x0445: 0x06c8, // XK_Cyrillic_ha | |
| 268 | + 0x0446: 0x06c3, // XK_Cyrillic_tse | |
| 269 | + 0x0447: 0x06de, // XK_Cyrillic_che | |
| 270 | + 0x0448: 0x06db, // XK_Cyrillic_sha | |
| 271 | + 0x0449: 0x06dd, // XK_Cyrillic_shcha | |
| 272 | + 0x044a: 0x06df, // XK_Cyrillic_hardsign | |
| 273 | + 0x044b: 0x06d9, // XK_Cyrillic_yeru | |
| 274 | + 0x044c: 0x06d8, // XK_Cyrillic_softsign | |
| 275 | + 0x044d: 0x06dc, // XK_Cyrillic_e | |
| 276 | + 0x044e: 0x06c0, // XK_Cyrillic_yu | |
| 277 | + 0x044f: 0x06d1, // XK_Cyrillic_ya | |
| 278 | + 0x0451: 0x06a3, // XK_Cyrillic_io | |
| 279 | + 0x0452: 0x06a1, // XK_Serbian_dje | |
| 280 | + 0x0453: 0x06a2, // XK_Macedonia_gje | |
| 281 | + 0x0454: 0x06a4, // XK_Ukrainian_ie | |
| 282 | + 0x0455: 0x06a5, // XK_Macedonia_dse | |
| 283 | + 0x0456: 0x06a6, // XK_Ukrainian_i | |
| 284 | + 0x0457: 0x06a7, // XK_Ukrainian_yi | |
| 285 | + 0x0458: 0x06a8, // XK_Cyrillic_je | |
| 286 | + 0x0459: 0x06a9, // XK_Cyrillic_lje | |
| 287 | + 0x045a: 0x06aa, // XK_Cyrillic_nje | |
| 288 | + 0x045b: 0x06ab, // XK_Serbian_tshe | |
| 289 | + 0x045c: 0x06ac, // XK_Macedonia_kje | |
| 290 | + 0x045e: 0x06ae, // XK_Byelorussian_shortu | |
| 291 | + 0x045f: 0x06af, // XK_Cyrillic_dzhe | |
| 292 | + 0x0490: 0x06bd, // XK_Ukrainian_GHE_WITH_UPTURN | |
| 293 | + 0x0491: 0x06ad, // XK_Ukrainian_ghe_with_upturn | |
| 294 | + 0x05d0: 0x0ce0, // XK_hebrew_aleph | |
| 295 | + 0x05d1: 0x0ce1, // XK_hebrew_bet | |
| 296 | + 0x05d2: 0x0ce2, // XK_hebrew_gimel | |
| 297 | + 0x05d3: 0x0ce3, // XK_hebrew_dalet | |
| 298 | + 0x05d4: 0x0ce4, // XK_hebrew_he | |
| 299 | + 0x05d5: 0x0ce5, // XK_hebrew_waw | |
| 300 | + 0x05d6: 0x0ce6, // XK_hebrew_zain | |
| 301 | + 0x05d7: 0x0ce7, // XK_hebrew_chet | |
| 302 | + 0x05d8: 0x0ce8, // XK_hebrew_tet | |
| 303 | + 0x05d9: 0x0ce9, // XK_hebrew_yod | |
| 304 | + 0x05da: 0x0cea, // XK_hebrew_finalkaph | |
| 305 | + 0x05db: 0x0ceb, // XK_hebrew_kaph | |
| 306 | + 0x05dc: 0x0cec, // XK_hebrew_lamed | |
| 307 | + 0x05dd: 0x0ced, // XK_hebrew_finalmem | |
| 308 | + 0x05de: 0x0cee, // XK_hebrew_mem | |
| 309 | + 0x05df: 0x0cef, // XK_hebrew_finalnun | |
| 310 | + 0x05e0: 0x0cf0, // XK_hebrew_nun | |
| 311 | + 0x05e1: 0x0cf1, // XK_hebrew_samech | |
| 312 | + 0x05e2: 0x0cf2, // XK_hebrew_ayin | |
| 313 | + 0x05e3: 0x0cf3, // XK_hebrew_finalpe | |
| 314 | + 0x05e4: 0x0cf4, // XK_hebrew_pe | |
| 315 | + 0x05e5: 0x0cf5, // XK_hebrew_finalzade | |
| 316 | + 0x05e6: 0x0cf6, // XK_hebrew_zade | |
| 317 | + 0x05e7: 0x0cf7, // XK_hebrew_qoph | |
| 318 | + 0x05e8: 0x0cf8, // XK_hebrew_resh | |
| 319 | + 0x05e9: 0x0cf9, // XK_hebrew_shin | |
| 320 | + 0x05ea: 0x0cfa, // XK_hebrew_taw | |
| 321 | + 0x060c: 0x05ac, // XK_Arabic_comma | |
| 322 | + 0x061b: 0x05bb, // XK_Arabic_semicolon | |
| 323 | + 0x061f: 0x05bf, // XK_Arabic_question_mark | |
| 324 | + 0x0621: 0x05c1, // XK_Arabic_hamza | |
| 325 | + 0x0622: 0x05c2, // XK_Arabic_maddaonalef | |
| 326 | + 0x0623: 0x05c3, // XK_Arabic_hamzaonalef | |
| 327 | + 0x0624: 0x05c4, // XK_Arabic_hamzaonwaw | |
| 328 | + 0x0625: 0x05c5, // XK_Arabic_hamzaunderalef | |
| 329 | + 0x0626: 0x05c6, // XK_Arabic_hamzaonyeh | |
| 330 | + 0x0627: 0x05c7, // XK_Arabic_alef | |
| 331 | + 0x0628: 0x05c8, // XK_Arabic_beh | |
| 332 | + 0x0629: 0x05c9, // XK_Arabic_tehmarbuta | |
| 333 | + 0x062a: 0x05ca, // XK_Arabic_teh | |
| 334 | + 0x062b: 0x05cb, // XK_Arabic_theh | |
| 335 | + 0x062c: 0x05cc, // XK_Arabic_jeem | |
| 336 | + 0x062d: 0x05cd, // XK_Arabic_hah | |
| 337 | + 0x062e: 0x05ce, // XK_Arabic_khah | |
| 338 | + 0x062f: 0x05cf, // XK_Arabic_dal | |
| 339 | + 0x0630: 0x05d0, // XK_Arabic_thal | |
| 340 | + 0x0631: 0x05d1, // XK_Arabic_ra | |
| 341 | + 0x0632: 0x05d2, // XK_Arabic_zain | |
| 342 | + 0x0633: 0x05d3, // XK_Arabic_seen | |
| 343 | + 0x0634: 0x05d4, // XK_Arabic_sheen | |
| 344 | + 0x0635: 0x05d5, // XK_Arabic_sad | |
| 345 | + 0x0636: 0x05d6, // XK_Arabic_dad | |
| 346 | + 0x0637: 0x05d7, // XK_Arabic_tah | |
| 347 | + 0x0638: 0x05d8, // XK_Arabic_zah | |
| 348 | + 0x0639: 0x05d9, // XK_Arabic_ain | |
| 349 | + 0x063a: 0x05da, // XK_Arabic_ghain | |
| 350 | + 0x0640: 0x05e0, // XK_Arabic_tatweel | |
| 351 | + 0x0641: 0x05e1, // XK_Arabic_feh | |
| 352 | + 0x0642: 0x05e2, // XK_Arabic_qaf | |
| 353 | + 0x0643: 0x05e3, // XK_Arabic_kaf | |
| 354 | + 0x0644: 0x05e4, // XK_Arabic_lam | |
| 355 | + 0x0645: 0x05e5, // XK_Arabic_meem | |
| 356 | + 0x0646: 0x05e6, // XK_Arabic_noon | |
| 357 | + 0x0647: 0x05e7, // XK_Arabic_ha | |
| 358 | + 0x0648: 0x05e8, // XK_Arabic_waw | |
| 359 | + 0x0649: 0x05e9, // XK_Arabic_alefmaksura | |
| 360 | + 0x064a: 0x05ea, // XK_Arabic_yeh | |
| 361 | + 0x064b: 0x05eb, // XK_Arabic_fathatan | |
| 362 | + 0x064c: 0x05ec, // XK_Arabic_dammatan | |
| 363 | + 0x064d: 0x05ed, // XK_Arabic_kasratan | |
| 364 | + 0x064e: 0x05ee, // XK_Arabic_fatha | |
| 365 | + 0x064f: 0x05ef, // XK_Arabic_damma | |
| 366 | + 0x0650: 0x05f0, // XK_Arabic_kasra | |
| 367 | + 0x0651: 0x05f1, // XK_Arabic_shadda | |
| 368 | + 0x0652: 0x05f2, // XK_Arabic_sukun | |
| 369 | + 0x0e01: 0x0da1, // XK_Thai_kokai | |
| 370 | + 0x0e02: 0x0da2, // XK_Thai_khokhai | |
| 371 | + 0x0e03: 0x0da3, // XK_Thai_khokhuat | |
| 372 | + 0x0e04: 0x0da4, // XK_Thai_khokhwai | |
| 373 | + 0x0e05: 0x0da5, // XK_Thai_khokhon | |
| 374 | + 0x0e06: 0x0da6, // XK_Thai_khorakhang | |
| 375 | + 0x0e07: 0x0da7, // XK_Thai_ngongu | |
| 376 | + 0x0e08: 0x0da8, // XK_Thai_chochan | |
| 377 | + 0x0e09: 0x0da9, // XK_Thai_choching | |
| 378 | + 0x0e0a: 0x0daa, // XK_Thai_chochang | |
| 379 | + 0x0e0b: 0x0dab, // XK_Thai_soso | |
| 380 | + 0x0e0c: 0x0dac, // XK_Thai_chochoe | |
| 381 | + 0x0e0d: 0x0dad, // XK_Thai_yoying | |
| 382 | + 0x0e0e: 0x0dae, // XK_Thai_dochada | |
| 383 | + 0x0e0f: 0x0daf, // XK_Thai_topatak | |
| 384 | + 0x0e10: 0x0db0, // XK_Thai_thothan | |
| 385 | + 0x0e11: 0x0db1, // XK_Thai_thonangmontho | |
| 386 | + 0x0e12: 0x0db2, // XK_Thai_thophuthao | |
| 387 | + 0x0e13: 0x0db3, // XK_Thai_nonen | |
| 388 | + 0x0e14: 0x0db4, // XK_Thai_dodek | |
| 389 | + 0x0e15: 0x0db5, // XK_Thai_totao | |
| 390 | + 0x0e16: 0x0db6, // XK_Thai_thothung | |
| 391 | + 0x0e17: 0x0db7, // XK_Thai_thothahan | |
| 392 | + 0x0e18: 0x0db8, // XK_Thai_thothong | |
| 393 | + 0x0e19: 0x0db9, // XK_Thai_nonu | |
| 394 | + 0x0e1a: 0x0dba, // XK_Thai_bobaimai | |
| 395 | + 0x0e1b: 0x0dbb, // XK_Thai_popla | |
| 396 | + 0x0e1c: 0x0dbc, // XK_Thai_phophung | |
| 397 | + 0x0e1d: 0x0dbd, // XK_Thai_fofa | |
| 398 | + 0x0e1e: 0x0dbe, // XK_Thai_phophan | |
| 399 | + 0x0e1f: 0x0dbf, // XK_Thai_fofan | |
| 400 | + 0x0e20: 0x0dc0, // XK_Thai_phosamphao | |
| 401 | + 0x0e21: 0x0dc1, // XK_Thai_moma | |
| 402 | + 0x0e22: 0x0dc2, // XK_Thai_yoyak | |
| 403 | + 0x0e23: 0x0dc3, // XK_Thai_rorua | |
| 404 | + 0x0e24: 0x0dc4, // XK_Thai_ru | |
| 405 | + 0x0e25: 0x0dc5, // XK_Thai_loling | |
| 406 | + 0x0e26: 0x0dc6, // XK_Thai_lu | |
| 407 | + 0x0e27: 0x0dc7, // XK_Thai_wowaen | |
| 408 | + 0x0e28: 0x0dc8, // XK_Thai_sosala | |
| 409 | + 0x0e29: 0x0dc9, // XK_Thai_sorusi | |
| 410 | + 0x0e2a: 0x0dca, // XK_Thai_sosua | |
| 411 | + 0x0e2b: 0x0dcb, // XK_Thai_hohip | |
| 412 | + 0x0e2c: 0x0dcc, // XK_Thai_lochula | |
| 413 | + 0x0e2d: 0x0dcd, // XK_Thai_oang | |
| 414 | + 0x0e2e: 0x0dce, // XK_Thai_honokhuk | |
| 415 | + 0x0e2f: 0x0dcf, // XK_Thai_paiyannoi | |
| 416 | + 0x0e30: 0x0dd0, // XK_Thai_saraa | |
| 417 | + 0x0e31: 0x0dd1, // XK_Thai_maihanakat | |
| 418 | + 0x0e32: 0x0dd2, // XK_Thai_saraaa | |
| 419 | + 0x0e33: 0x0dd3, // XK_Thai_saraam | |
| 420 | + 0x0e34: 0x0dd4, // XK_Thai_sarai | |
| 421 | + 0x0e35: 0x0dd5, // XK_Thai_saraii | |
| 422 | + 0x0e36: 0x0dd6, // XK_Thai_saraue | |
| 423 | + 0x0e37: 0x0dd7, // XK_Thai_sarauee | |
| 424 | + 0x0e38: 0x0dd8, // XK_Thai_sarau | |
| 425 | + 0x0e39: 0x0dd9, // XK_Thai_sarauu | |
| 426 | + 0x0e3a: 0x0dda, // XK_Thai_phinthu | |
| 427 | + 0x0e3f: 0x0ddf, // XK_Thai_baht | |
| 428 | + 0x0e40: 0x0de0, // XK_Thai_sarae | |
| 429 | + 0x0e41: 0x0de1, // XK_Thai_saraae | |
| 430 | + 0x0e42: 0x0de2, // XK_Thai_sarao | |
| 431 | + 0x0e43: 0x0de3, // XK_Thai_saraaimaimuan | |
| 432 | + 0x0e44: 0x0de4, // XK_Thai_saraaimaimalai | |
| 433 | + 0x0e45: 0x0de5, // XK_Thai_lakkhangyao | |
| 434 | + 0x0e46: 0x0de6, // XK_Thai_maiyamok | |
| 435 | + 0x0e47: 0x0de7, // XK_Thai_maitaikhu | |
| 436 | + 0x0e48: 0x0de8, // XK_Thai_maiek | |
| 437 | + 0x0e49: 0x0de9, // XK_Thai_maitho | |
| 438 | + 0x0e4a: 0x0dea, // XK_Thai_maitri | |
| 439 | + 0x0e4b: 0x0deb, // XK_Thai_maichattawa | |
| 440 | + 0x0e4c: 0x0dec, // XK_Thai_thanthakhat | |
| 441 | + 0x0e4d: 0x0ded, // XK_Thai_nikhahit | |
| 442 | + 0x0e50: 0x0df0, // XK_Thai_leksun | |
| 443 | + 0x0e51: 0x0df1, // XK_Thai_leknung | |
| 444 | + 0x0e52: 0x0df2, // XK_Thai_leksong | |
| 445 | + 0x0e53: 0x0df3, // XK_Thai_leksam | |
| 446 | + 0x0e54: 0x0df4, // XK_Thai_leksi | |
| 447 | + 0x0e55: 0x0df5, // XK_Thai_lekha | |
| 448 | + 0x0e56: 0x0df6, // XK_Thai_lekhok | |
| 449 | + 0x0e57: 0x0df7, // XK_Thai_lekchet | |
| 450 | + 0x0e58: 0x0df8, // XK_Thai_lekpaet | |
| 451 | + 0x0e59: 0x0df9, // XK_Thai_lekkao | |
| 452 | + 0x2002: 0x0aa2, // XK_enspace | |
| 453 | + 0x2003: 0x0aa1, // XK_emspace | |
| 454 | + 0x2004: 0x0aa3, // XK_em3space | |
| 455 | + 0x2005: 0x0aa4, // XK_em4space | |
| 456 | + 0x2007: 0x0aa5, // XK_digitspace | |
| 457 | + 0x2008: 0x0aa6, // XK_punctspace | |
| 458 | + 0x2009: 0x0aa7, // XK_thinspace | |
| 459 | + 0x200a: 0x0aa8, // XK_hairspace | |
| 460 | + 0x2012: 0x0abb, // XK_figdash | |
| 461 | + 0x2013: 0x0aaa, // XK_endash | |
| 462 | + 0x2014: 0x0aa9, // XK_emdash | |
| 463 | + 0x2015: 0x07af, // XK_Greek_horizbar | |
| 464 | + 0x2017: 0x0cdf, // XK_hebrew_doublelowline | |
| 465 | + 0x2018: 0x0ad0, // XK_leftsinglequotemark | |
| 466 | + 0x2019: 0x0ad1, // XK_rightsinglequotemark | |
| 467 | + 0x201a: 0x0afd, // XK_singlelowquotemark | |
| 468 | + 0x201c: 0x0ad2, // XK_leftdoublequotemark | |
| 469 | + 0x201d: 0x0ad3, // XK_rightdoublequotemark | |
| 470 | + 0x201e: 0x0afe, // XK_doublelowquotemark | |
| 471 | + 0x2020: 0x0af1, // XK_dagger | |
| 472 | + 0x2021: 0x0af2, // XK_doubledagger | |
| 473 | + 0x2022: 0x0ae6, // XK_enfilledcircbullet | |
| 474 | + 0x2025: 0x0aaf, // XK_doubbaselinedot | |
| 475 | + 0x2026: 0x0aae, // XK_ellipsis | |
| 476 | + 0x2030: 0x0ad5, // XK_permille | |
| 477 | + 0x2032: 0x0ad6, // XK_minutes | |
| 478 | + 0x2033: 0x0ad7, // XK_seconds | |
| 479 | + 0x2038: 0x0afc, // XK_caret | |
| 480 | + 0x203e: 0x047e, // XK_overline | |
| 481 | + 0x20a9: 0x0eff, // XK_Korean_Won | |
| 482 | + 0x20ac: 0x20ac, // XK_EuroSign | |
| 483 | + 0x2105: 0x0ab8, // XK_careof | |
| 484 | + 0x2116: 0x06b0, // XK_numerosign | |
| 485 | + 0x2117: 0x0afb, // XK_phonographcopyright | |
| 486 | + 0x211e: 0x0ad4, // XK_prescription | |
| 487 | + 0x2122: 0x0ac9, // XK_trademark | |
| 488 | + 0x2153: 0x0ab0, // XK_onethird | |
| 489 | + 0x2154: 0x0ab1, // XK_twothirds | |
| 490 | + 0x2155: 0x0ab2, // XK_onefifth | |
| 491 | + 0x2156: 0x0ab3, // XK_twofifths | |
| 492 | + 0x2157: 0x0ab4, // XK_threefifths | |
| 493 | + 0x2158: 0x0ab5, // XK_fourfifths | |
| 494 | + 0x2159: 0x0ab6, // XK_onesixth | |
| 495 | + 0x215a: 0x0ab7, // XK_fivesixths | |
| 496 | + 0x215b: 0x0ac3, // XK_oneeighth | |
| 497 | + 0x215c: 0x0ac4, // XK_threeeighths | |
| 498 | + 0x215d: 0x0ac5, // XK_fiveeighths | |
| 499 | + 0x215e: 0x0ac6, // XK_seveneighths | |
| 500 | + 0x2190: 0x08fb, // XK_leftarrow | |
| 501 | + 0x2191: 0x08fc, // XK_uparrow | |
| 502 | + 0x2192: 0x08fd, // XK_rightarrow | |
| 503 | + 0x2193: 0x08fe, // XK_downarrow | |
| 504 | + 0x21d2: 0x08ce, // XK_implies | |
| 505 | + 0x21d4: 0x08cd, // XK_ifonlyif | |
| 506 | + 0x2202: 0x08ef, // XK_partialderivative | |
| 507 | + 0x2207: 0x08c5, // XK_nabla | |
| 508 | + 0x2218: 0x0bca, // XK_jot | |
| 509 | + 0x221a: 0x08d6, // XK_radical | |
| 510 | + 0x221d: 0x08c1, // XK_variation | |
| 511 | + 0x221e: 0x08c2, // XK_infinity | |
| 512 | + 0x2227: 0x08de, // XK_logicaland | |
| 513 | + 0x2228: 0x08df, // XK_logicalor | |
| 514 | + 0x2229: 0x08dc, // XK_intersection | |
| 515 | + 0x222a: 0x08dd, // XK_union | |
| 516 | + 0x222b: 0x08bf, // XK_integral | |
| 517 | + 0x2234: 0x08c0, // XK_therefore | |
| 518 | + 0x223c: 0x08c8, // XK_approximate | |
| 519 | + 0x2243: 0x08c9, // XK_similarequal | |
| 520 | + 0x2245: 0x1002248, // XK_approxeq | |
| 521 | + 0x2260: 0x08bd, // XK_notequal | |
| 522 | + 0x2261: 0x08cf, // XK_identical | |
| 523 | + 0x2264: 0x08bc, // XK_lessthanequal | |
| 524 | + 0x2265: 0x08be, // XK_greaterthanequal | |
| 525 | + 0x2282: 0x08da, // XK_includedin | |
| 526 | + 0x2283: 0x08db, // XK_includes | |
| 527 | + 0x22a2: 0x0bfc, // XK_righttack | |
| 528 | + 0x22a3: 0x0bdc, // XK_lefttack | |
| 529 | + 0x22a4: 0x0bc2, // XK_downtack | |
| 530 | + 0x22a5: 0x0bce, // XK_uptack | |
| 531 | + 0x2308: 0x0bd3, // XK_upstile | |
| 532 | + 0x230a: 0x0bc4, // XK_downstile | |
| 533 | + 0x2315: 0x0afa, // XK_telephonerecorder | |
| 534 | + 0x2320: 0x08a4, // XK_topintegral | |
| 535 | + 0x2321: 0x08a5, // XK_botintegral | |
| 536 | + 0x2395: 0x0bcc, // XK_quad | |
| 537 | + 0x239b: 0x08ab, // XK_topleftparens | |
| 538 | + 0x239d: 0x08ac, // XK_botleftparens | |
| 539 | + 0x239e: 0x08ad, // XK_toprightparens | |
| 540 | + 0x23a0: 0x08ae, // XK_botrightparens | |
| 541 | + 0x23a1: 0x08a7, // XK_topleftsqbracket | |
| 542 | + 0x23a3: 0x08a8, // XK_botleftsqbracket | |
| 543 | + 0x23a4: 0x08a9, // XK_toprightsqbracket | |
| 544 | + 0x23a6: 0x08aa, // XK_botrightsqbracket | |
| 545 | + 0x23a8: 0x08af, // XK_leftmiddlecurlybrace | |
| 546 | + 0x23ac: 0x08b0, // XK_rightmiddlecurlybrace | |
| 547 | + 0x23b7: 0x08a1, // XK_leftradical | |
| 548 | + 0x23ba: 0x09ef, // XK_horizlinescan1 | |
| 549 | + 0x23bb: 0x09f0, // XK_horizlinescan3 | |
| 550 | + 0x23bc: 0x09f2, // XK_horizlinescan7 | |
| 551 | + 0x23bd: 0x09f3, // XK_horizlinescan9 | |
| 552 | + 0x2409: 0x09e2, // XK_ht | |
| 553 | + 0x240a: 0x09e5, // XK_lf | |
| 554 | + 0x240b: 0x09e9, // XK_vt | |
| 555 | + 0x240c: 0x09e3, // XK_ff | |
| 556 | + 0x240d: 0x09e4, // XK_cr | |
| 557 | + 0x2423: 0x0aac, // XK_signifblank | |
| 558 | + 0x2424: 0x09e8, // XK_nl | |
| 559 | + 0x2500: 0x08a3, // XK_horizconnector | |
| 560 | + 0x2502: 0x08a6, // XK_vertconnector | |
| 561 | + 0x250c: 0x08a2, // XK_topleftradical | |
| 562 | + 0x2510: 0x09eb, // XK_uprightcorner | |
| 563 | + 0x2514: 0x09ed, // XK_lowleftcorner | |
| 564 | + 0x2518: 0x09ea, // XK_lowrightcorner | |
| 565 | + 0x251c: 0x09f4, // XK_leftt | |
| 566 | + 0x2524: 0x09f5, // XK_rightt | |
| 567 | + 0x252c: 0x09f7, // XK_topt | |
| 568 | + 0x2534: 0x09f6, // XK_bott | |
| 569 | + 0x253c: 0x09ee, // XK_crossinglines | |
| 570 | + 0x2592: 0x09e1, // XK_checkerboard | |
| 571 | + 0x25aa: 0x0ae7, // XK_enfilledsqbullet | |
| 572 | + 0x25ab: 0x0ae1, // XK_enopensquarebullet | |
| 573 | + 0x25ac: 0x0adb, // XK_filledrectbullet | |
| 574 | + 0x25ad: 0x0ae2, // XK_openrectbullet | |
| 575 | + 0x25ae: 0x0adf, // XK_emfilledrect | |
| 576 | + 0x25af: 0x0acf, // XK_emopenrectangle | |
| 577 | + 0x25b2: 0x0ae8, // XK_filledtribulletup | |
| 578 | + 0x25b3: 0x0ae3, // XK_opentribulletup | |
| 579 | + 0x25b6: 0x0add, // XK_filledrighttribullet | |
| 580 | + 0x25b7: 0x0acd, // XK_rightopentriangle | |
| 581 | + 0x25bc: 0x0ae9, // XK_filledtribulletdown | |
| 582 | + 0x25bd: 0x0ae4, // XK_opentribulletdown | |
| 583 | + 0x25c0: 0x0adc, // XK_filledlefttribullet | |
| 584 | + 0x25c1: 0x0acc, // XK_leftopentriangle | |
| 585 | + 0x25c6: 0x09e0, // XK_soliddiamond | |
| 586 | + 0x25cb: 0x0ace, // XK_emopencircle | |
| 587 | + 0x25cf: 0x0ade, // XK_emfilledcircle | |
| 588 | + 0x25e6: 0x0ae0, // XK_enopencircbullet | |
| 589 | + 0x2606: 0x0ae5, // XK_openstar | |
| 590 | + 0x260e: 0x0af9, // XK_telephone | |
| 591 | + 0x2613: 0x0aca, // XK_signaturemark | |
| 592 | + 0x261c: 0x0aea, // XK_leftpointer | |
| 593 | + 0x261e: 0x0aeb, // XK_rightpointer | |
| 594 | + 0x2640: 0x0af8, // XK_femalesymbol | |
| 595 | + 0x2642: 0x0af7, // XK_malesymbol | |
| 596 | + 0x2663: 0x0aec, // XK_club | |
| 597 | + 0x2665: 0x0aee, // XK_heart | |
| 598 | + 0x2666: 0x0aed, // XK_diamond | |
| 599 | + 0x266d: 0x0af6, // XK_musicalflat | |
| 600 | + 0x266f: 0x0af5, // XK_musicalsharp | |
| 601 | + 0x2713: 0x0af3, // XK_checkmark | |
| 602 | + 0x2717: 0x0af4, // XK_ballotcross | |
| 603 | + 0x271d: 0x0ad9, // XK_latincross | |
| 604 | + 0x2720: 0x0af0, // XK_maltesecross | |
| 605 | + 0x27e8: 0x0abc, // XK_leftanglebracket | |
| 606 | + 0x27e9: 0x0abe, // XK_rightanglebracket | |
| 607 | + 0x3001: 0x04a4, // XK_kana_comma | |
| 608 | + 0x3002: 0x04a1, // XK_kana_fullstop | |
| 609 | + 0x300c: 0x04a2, // XK_kana_openingbracket | |
| 610 | + 0x300d: 0x04a3, // XK_kana_closingbracket | |
| 611 | + 0x309b: 0x04de, // XK_voicedsound | |
| 612 | + 0x309c: 0x04df, // XK_semivoicedsound | |
| 613 | + 0x30a1: 0x04a7, // XK_kana_a | |
| 614 | + 0x30a2: 0x04b1, // XK_kana_A | |
| 615 | + 0x30a3: 0x04a8, // XK_kana_i | |
| 616 | + 0x30a4: 0x04b2, // XK_kana_I | |
| 617 | + 0x30a5: 0x04a9, // XK_kana_u | |
| 618 | + 0x30a6: 0x04b3, // XK_kana_U | |
| 619 | + 0x30a7: 0x04aa, // XK_kana_e | |
| 620 | + 0x30a8: 0x04b4, // XK_kana_E | |
| 621 | + 0x30a9: 0x04ab, // XK_kana_o | |
| 622 | + 0x30aa: 0x04b5, // XK_kana_O | |
| 623 | + 0x30ab: 0x04b6, // XK_kana_KA | |
| 624 | + 0x30ad: 0x04b7, // XK_kana_KI | |
| 625 | + 0x30af: 0x04b8, // XK_kana_KU | |
| 626 | + 0x30b1: 0x04b9, // XK_kana_KE | |
| 627 | + 0x30b3: 0x04ba, // XK_kana_KO | |
| 628 | + 0x30b5: 0x04bb, // XK_kana_SA | |
| 629 | + 0x30b7: 0x04bc, // XK_kana_SHI | |
| 630 | + 0x30b9: 0x04bd, // XK_kana_SU | |
| 631 | + 0x30bb: 0x04be, // XK_kana_SE | |
| 632 | + 0x30bd: 0x04bf, // XK_kana_SO | |
| 633 | + 0x30bf: 0x04c0, // XK_kana_TA | |
| 634 | + 0x30c1: 0x04c1, // XK_kana_CHI | |
| 635 | + 0x30c3: 0x04af, // XK_kana_tsu | |
| 636 | + 0x30c4: 0x04c2, // XK_kana_TSU | |
| 637 | + 0x30c6: 0x04c3, // XK_kana_TE | |
| 638 | + 0x30c8: 0x04c4, // XK_kana_TO | |
| 639 | + 0x30ca: 0x04c5, // XK_kana_NA | |
| 640 | + 0x30cb: 0x04c6, // XK_kana_NI | |
| 641 | + 0x30cc: 0x04c7, // XK_kana_NU | |
| 642 | + 0x30cd: 0x04c8, // XK_kana_NE | |
| 643 | + 0x30ce: 0x04c9, // XK_kana_NO | |
| 644 | + 0x30cf: 0x04ca, // XK_kana_HA | |
| 645 | + 0x30d2: 0x04cb, // XK_kana_HI | |
| 646 | + 0x30d5: 0x04cc, // XK_kana_FU | |
| 647 | + 0x30d8: 0x04cd, // XK_kana_HE | |
| 648 | + 0x30db: 0x04ce, // XK_kana_HO | |
| 649 | + 0x30de: 0x04cf, // XK_kana_MA | |
| 650 | + 0x30df: 0x04d0, // XK_kana_MI | |
| 651 | + 0x30e0: 0x04d1, // XK_kana_MU | |
| 652 | + 0x30e1: 0x04d2, // XK_kana_ME | |
| 653 | + 0x30e2: 0x04d3, // XK_kana_MO | |
| 654 | + 0x30e3: 0x04ac, // XK_kana_ya | |
| 655 | + 0x30e4: 0x04d4, // XK_kana_YA | |
| 656 | + 0x30e5: 0x04ad, // XK_kana_yu | |
| 657 | + 0x30e6: 0x04d5, // XK_kana_YU | |
| 658 | + 0x30e7: 0x04ae, // XK_kana_yo | |
| 659 | + 0x30e8: 0x04d6, // XK_kana_YO | |
| 660 | + 0x30e9: 0x04d7, // XK_kana_RA | |
| 661 | + 0x30ea: 0x04d8, // XK_kana_RI | |
| 662 | + 0x30eb: 0x04d9, // XK_kana_RU | |
| 663 | + 0x30ec: 0x04da, // XK_kana_RE | |
| 664 | + 0x30ed: 0x04db, // XK_kana_RO | |
| 665 | + 0x30ef: 0x04dc, // XK_kana_WA | |
| 666 | + 0x30f2: 0x04a6, // XK_kana_WO | |
| 667 | + 0x30f3: 0x04dd, // XK_kana_N | |
| 668 | + 0x30fb: 0x04a5, // XK_kana_conjunctive | |
| 669 | + 0x30fc: 0x04b0, // XK_prolongedsound | |
| 670 | +}; | |
| 671 | + | |
| 672 | +export default { | |
| 673 | + lookup(u) { | |
| 674 | + // Latin-1 is one-to-one mapping | |
| 675 | + if ((u >= 0x20) && (u <= 0xff)) { | |
| 676 | + return u; | |
| 677 | + } | |
| 678 | + | |
| 679 | + // Lookup table (fairly random) | |
| 680 | + const keysym = codepoints[u]; | |
| 681 | + if (keysym !== undefined) { | |
| 682 | + return keysym; | |
| 683 | + } | |
| 684 | + | |
| 685 | + // General mapping as final fallback | |
| 686 | + return 0x01000000 | u; | |
| 687 | + }, | |
| 688 | +}; | |
added
public/vendor/novnc/core/input/util.js
+191 −0
@@ -0,0 +1,191 @@ | ||
| 1 | +import KeyTable from "./keysym.js"; | |
| 2 | +import keysyms from "./keysymdef.js"; | |
| 3 | +import vkeys from "./vkeys.js"; | |
| 4 | +import fixedkeys from "./fixedkeys.js"; | |
| 5 | +import DOMKeyTable from "./domkeytable.js"; | |
| 6 | +import * as browser from "../util/browser.js"; | |
| 7 | + | |
| 8 | +// Get 'KeyboardEvent.code', handling legacy browsers | |
| 9 | +export function getKeycode(evt) { | |
| 10 | + // Are we getting proper key identifiers? | |
| 11 | + // (unfortunately Firefox and Chrome are crappy here and gives | |
| 12 | + // us an empty string on some platforms, rather than leaving it | |
| 13 | + // undefined) | |
| 14 | + if (evt.code) { | |
| 15 | + // Mozilla isn't fully in sync with the spec yet | |
| 16 | + switch (evt.code) { | |
| 17 | + case 'OSLeft': return 'MetaLeft'; | |
| 18 | + case 'OSRight': return 'MetaRight'; | |
| 19 | + } | |
| 20 | + | |
| 21 | + return evt.code; | |
| 22 | + } | |
| 23 | + | |
| 24 | + // The de-facto standard is to use Windows Virtual-Key codes | |
| 25 | + // in the 'keyCode' field for non-printable characters | |
| 26 | + if (evt.keyCode in vkeys) { | |
| 27 | + let code = vkeys[evt.keyCode]; | |
| 28 | + | |
| 29 | + // macOS has messed up this code for some reason | |
| 30 | + if (browser.isMac() && (code === 'ContextMenu')) { | |
| 31 | + code = 'MetaRight'; | |
| 32 | + } | |
| 33 | + | |
| 34 | + // The keyCode doesn't distinguish between left and right | |
| 35 | + // for the standard modifiers | |
| 36 | + if (evt.location === 2) { | |
| 37 | + switch (code) { | |
| 38 | + case 'ShiftLeft': return 'ShiftRight'; | |
| 39 | + case 'ControlLeft': return 'ControlRight'; | |
| 40 | + case 'AltLeft': return 'AltRight'; | |
| 41 | + } | |
| 42 | + } | |
| 43 | + | |
| 44 | + // Nor a bunch of the numpad keys | |
| 45 | + if (evt.location === 3) { | |
| 46 | + switch (code) { | |
| 47 | + case 'Delete': return 'NumpadDecimal'; | |
| 48 | + case 'Insert': return 'Numpad0'; | |
| 49 | + case 'End': return 'Numpad1'; | |
| 50 | + case 'ArrowDown': return 'Numpad2'; | |
| 51 | + case 'PageDown': return 'Numpad3'; | |
| 52 | + case 'ArrowLeft': return 'Numpad4'; | |
| 53 | + case 'ArrowRight': return 'Numpad6'; | |
| 54 | + case 'Home': return 'Numpad7'; | |
| 55 | + case 'ArrowUp': return 'Numpad8'; | |
| 56 | + case 'PageUp': return 'Numpad9'; | |
| 57 | + case 'Enter': return 'NumpadEnter'; | |
| 58 | + } | |
| 59 | + } | |
| 60 | + | |
| 61 | + return code; | |
| 62 | + } | |
| 63 | + | |
| 64 | + return 'Unidentified'; | |
| 65 | +} | |
| 66 | + | |
| 67 | +// Get 'KeyboardEvent.key', handling legacy browsers | |
| 68 | +export function getKey(evt) { | |
| 69 | + // Are we getting a proper key value? | |
| 70 | + if ((evt.key !== undefined) && (evt.key !== 'Unidentified')) { | |
| 71 | + // Mozilla isn't fully in sync with the spec yet | |
| 72 | + switch (evt.key) { | |
| 73 | + case 'OS': return 'Meta'; | |
| 74 | + case 'LaunchMyComputer': return 'LaunchApplication1'; | |
| 75 | + case 'LaunchCalculator': return 'LaunchApplication2'; | |
| 76 | + } | |
| 77 | + | |
| 78 | + // iOS leaks some OS names | |
| 79 | + switch (evt.key) { | |
| 80 | + case 'UIKeyInputUpArrow': return 'ArrowUp'; | |
| 81 | + case 'UIKeyInputDownArrow': return 'ArrowDown'; | |
| 82 | + case 'UIKeyInputLeftArrow': return 'ArrowLeft'; | |
| 83 | + case 'UIKeyInputRightArrow': return 'ArrowRight'; | |
| 84 | + case 'UIKeyInputEscape': return 'Escape'; | |
| 85 | + } | |
| 86 | + | |
| 87 | + // Broken behaviour in Chrome | |
| 88 | + if ((evt.key === '\x00') && (evt.code === 'NumpadDecimal')) { | |
| 89 | + return 'Delete'; | |
| 90 | + } | |
| 91 | + | |
| 92 | + return evt.key; | |
| 93 | + } | |
| 94 | + | |
| 95 | + // Try to deduce it based on the physical key | |
| 96 | + const code = getKeycode(evt); | |
| 97 | + if (code in fixedkeys) { | |
| 98 | + return fixedkeys[code]; | |
| 99 | + } | |
| 100 | + | |
| 101 | + // If that failed, then see if we have a printable character | |
| 102 | + if (evt.charCode) { | |
| 103 | + return String.fromCharCode(evt.charCode); | |
| 104 | + } | |
| 105 | + | |
| 106 | + // At this point we have nothing left to go on | |
| 107 | + return 'Unidentified'; | |
| 108 | +} | |
| 109 | + | |
| 110 | +// Get the most reliable keysym value we can get from a key event | |
| 111 | +export function getKeysym(evt) { | |
| 112 | + const key = getKey(evt); | |
| 113 | + | |
| 114 | + if (key === 'Unidentified') { | |
| 115 | + return null; | |
| 116 | + } | |
| 117 | + | |
| 118 | + // First look up special keys | |
| 119 | + if (key in DOMKeyTable) { | |
| 120 | + let location = evt.location; | |
| 121 | + | |
| 122 | + // Safari screws up location for the right cmd key | |
| 123 | + if ((key === 'Meta') && (location === 0)) { | |
| 124 | + location = 2; | |
| 125 | + } | |
| 126 | + | |
| 127 | + // And for Clear | |
| 128 | + if ((key === 'Clear') && (location === 3)) { | |
| 129 | + let code = getKeycode(evt); | |
| 130 | + if (code === 'NumLock') { | |
| 131 | + location = 0; | |
| 132 | + } | |
| 133 | + } | |
| 134 | + | |
| 135 | + if ((location === undefined) || (location > 3)) { | |
| 136 | + location = 0; | |
| 137 | + } | |
| 138 | + | |
| 139 | + // The original Meta key now gets confused with the Windows key | |
| 140 | + // https://bugs.chromium.org/p/chromium/issues/detail?id=1020141 | |
| 141 | + // https://bugzilla.mozilla.org/show_bug.cgi?id=1232918 | |
| 142 | + if (key === 'Meta') { | |
| 143 | + let code = getKeycode(evt); | |
| 144 | + if (code === 'AltLeft') { | |
| 145 | + return KeyTable.XK_Meta_L; | |
| 146 | + } else if (code === 'AltRight') { | |
| 147 | + return KeyTable.XK_Meta_R; | |
| 148 | + } | |
| 149 | + } | |
| 150 | + | |
| 151 | + // macOS has Clear instead of NumLock, but the remote system is | |
| 152 | + // probably not macOS, so lying here is probably best... | |
| 153 | + if (key === 'Clear') { | |
| 154 | + let code = getKeycode(evt); | |
| 155 | + if (code === 'NumLock') { | |
| 156 | + return KeyTable.XK_Num_Lock; | |
| 157 | + } | |
| 158 | + } | |
| 159 | + | |
| 160 | + // Windows sends alternating symbols for some keys when using a | |
| 161 | + // Japanese layout. We have no way of synchronising with the IM | |
| 162 | + // running on the remote system, so we send some combined keysym | |
| 163 | + // instead and hope for the best. | |
| 164 | + if (browser.isWindows()) { | |
| 165 | + switch (key) { | |
| 166 | + case 'Zenkaku': | |
| 167 | + case 'Hankaku': | |
| 168 | + return KeyTable.XK_Zenkaku_Hankaku; | |
| 169 | + case 'Romaji': | |
| 170 | + case 'KanaMode': | |
| 171 | + return KeyTable.XK_Romaji; | |
| 172 | + } | |
| 173 | + } | |
| 174 | + | |
| 175 | + return DOMKeyTable[key][location]; | |
| 176 | + } | |
| 177 | + | |
| 178 | + // Now we need to look at the Unicode symbol instead | |
| 179 | + | |
| 180 | + // Special key? (FIXME: Should have been caught earlier) | |
| 181 | + if (key.length !== 1) { | |
| 182 | + return null; | |
| 183 | + } | |
| 184 | + | |
| 185 | + const codepoint = key.charCodeAt(); | |
| 186 | + if (codepoint) { | |
| 187 | + return keysyms.lookup(codepoint); | |
| 188 | + } | |
| 189 | + | |
| 190 | + return null; | |
| 191 | +} | |
added
public/vendor/novnc/core/input/vkeys.js
+116 −0
@@ -0,0 +1,116 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2018 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | |
| 5 | + */ | |
| 6 | + | |
| 7 | +/* | |
| 8 | + * Mapping between Microsoft® Windows® Virtual-Key codes and | |
| 9 | + * HTML key codes. | |
| 10 | + */ | |
| 11 | + | |
| 12 | +export default { | |
| 13 | + 0x08: 'Backspace', | |
| 14 | + 0x09: 'Tab', | |
| 15 | + 0x0a: 'NumpadClear', | |
| 16 | + 0x0d: 'Enter', | |
| 17 | + 0x10: 'ShiftLeft', | |
| 18 | + 0x11: 'ControlLeft', | |
| 19 | + 0x12: 'AltLeft', | |
| 20 | + 0x13: 'Pause', | |
| 21 | + 0x14: 'CapsLock', | |
| 22 | + 0x15: 'Lang1', | |
| 23 | + 0x19: 'Lang2', | |
| 24 | + 0x1b: 'Escape', | |
| 25 | + 0x1c: 'Convert', | |
| 26 | + 0x1d: 'NonConvert', | |
| 27 | + 0x20: 'Space', | |
| 28 | + 0x21: 'PageUp', | |
| 29 | + 0x22: 'PageDown', | |
| 30 | + 0x23: 'End', | |
| 31 | + 0x24: 'Home', | |
| 32 | + 0x25: 'ArrowLeft', | |
| 33 | + 0x26: 'ArrowUp', | |
| 34 | + 0x27: 'ArrowRight', | |
| 35 | + 0x28: 'ArrowDown', | |
| 36 | + 0x29: 'Select', | |
| 37 | + 0x2c: 'PrintScreen', | |
| 38 | + 0x2d: 'Insert', | |
| 39 | + 0x2e: 'Delete', | |
| 40 | + 0x2f: 'Help', | |
| 41 | + 0x30: 'Digit0', | |
| 42 | + 0x31: 'Digit1', | |
| 43 | + 0x32: 'Digit2', | |
| 44 | + 0x33: 'Digit3', | |
| 45 | + 0x34: 'Digit4', | |
| 46 | + 0x35: 'Digit5', | |
| 47 | + 0x36: 'Digit6', | |
| 48 | + 0x37: 'Digit7', | |
| 49 | + 0x38: 'Digit8', | |
| 50 | + 0x39: 'Digit9', | |
| 51 | + 0x5b: 'MetaLeft', | |
| 52 | + 0x5c: 'MetaRight', | |
| 53 | + 0x5d: 'ContextMenu', | |
| 54 | + 0x5f: 'Sleep', | |
| 55 | + 0x60: 'Numpad0', | |
| 56 | + 0x61: 'Numpad1', | |
| 57 | + 0x62: 'Numpad2', | |
| 58 | + 0x63: 'Numpad3', | |
| 59 | + 0x64: 'Numpad4', | |
| 60 | + 0x65: 'Numpad5', | |
| 61 | + 0x66: 'Numpad6', | |
| 62 | + 0x67: 'Numpad7', | |
| 63 | + 0x68: 'Numpad8', | |
| 64 | + 0x69: 'Numpad9', | |
| 65 | + 0x6a: 'NumpadMultiply', | |
| 66 | + 0x6b: 'NumpadAdd', | |
| 67 | + 0x6c: 'NumpadDecimal', | |
| 68 | + 0x6d: 'NumpadSubtract', | |
| 69 | + 0x6e: 'NumpadDecimal', // Duplicate, because buggy on Windows | |
| 70 | + 0x6f: 'NumpadDivide', | |
| 71 | + 0x70: 'F1', | |
| 72 | + 0x71: 'F2', | |
| 73 | + 0x72: 'F3', | |
| 74 | + 0x73: 'F4', | |
| 75 | + 0x74: 'F5', | |
| 76 | + 0x75: 'F6', | |
| 77 | + 0x76: 'F7', | |
| 78 | + 0x77: 'F8', | |
| 79 | + 0x78: 'F9', | |
| 80 | + 0x79: 'F10', | |
| 81 | + 0x7a: 'F11', | |
| 82 | + 0x7b: 'F12', | |
| 83 | + 0x7c: 'F13', | |
| 84 | + 0x7d: 'F14', | |
| 85 | + 0x7e: 'F15', | |
| 86 | + 0x7f: 'F16', | |
| 87 | + 0x80: 'F17', | |
| 88 | + 0x81: 'F18', | |
| 89 | + 0x82: 'F19', | |
| 90 | + 0x83: 'F20', | |
| 91 | + 0x84: 'F21', | |
| 92 | + 0x85: 'F22', | |
| 93 | + 0x86: 'F23', | |
| 94 | + 0x87: 'F24', | |
| 95 | + 0x90: 'NumLock', | |
| 96 | + 0x91: 'ScrollLock', | |
| 97 | + 0xa6: 'BrowserBack', | |
| 98 | + 0xa7: 'BrowserForward', | |
| 99 | + 0xa8: 'BrowserRefresh', | |
| 100 | + 0xa9: 'BrowserStop', | |
| 101 | + 0xaa: 'BrowserSearch', | |
| 102 | + 0xab: 'BrowserFavorites', | |
| 103 | + 0xac: 'BrowserHome', | |
| 104 | + 0xad: 'AudioVolumeMute', | |
| 105 | + 0xae: 'AudioVolumeDown', | |
| 106 | + 0xaf: 'AudioVolumeUp', | |
| 107 | + 0xb0: 'MediaTrackNext', | |
| 108 | + 0xb1: 'MediaTrackPrevious', | |
| 109 | + 0xb2: 'MediaStop', | |
| 110 | + 0xb3: 'MediaPlayPause', | |
| 111 | + 0xb4: 'LaunchMail', | |
| 112 | + 0xb5: 'MediaSelect', | |
| 113 | + 0xb6: 'LaunchApp1', | |
| 114 | + 0xb7: 'LaunchApp2', | |
| 115 | + 0xe1: 'AltRight', // Only when it is AltGraph | |
| 116 | +}; | |
added
public/vendor/novnc/core/input/xtscancodes.js
+173 −0
@@ -0,0 +1,173 @@ | ||
| 1 | +/* | |
| 2 | + * This file is auto-generated from keymaps.csv | |
| 3 | + * Database checksum sha256(76d68c10e97d37fe2ea459e210125ae41796253fb217e900bf2983ade13a7920) | |
| 4 | + * To re-generate, run: | |
| 5 | + * keymap-gen code-map --lang=js keymaps.csv html atset1 | |
| 6 | +*/ | |
| 7 | +export default { | |
| 8 | + "Again": 0xe005, /* html:Again (Again) -> linux:129 (KEY_AGAIN) -> atset1:57349 */ | |
| 9 | + "AltLeft": 0x38, /* html:AltLeft (AltLeft) -> linux:56 (KEY_LEFTALT) -> atset1:56 */ | |
| 10 | + "AltRight": 0xe038, /* html:AltRight (AltRight) -> linux:100 (KEY_RIGHTALT) -> atset1:57400 */ | |
| 11 | + "ArrowDown": 0xe050, /* html:ArrowDown (ArrowDown) -> linux:108 (KEY_DOWN) -> atset1:57424 */ | |
| 12 | + "ArrowLeft": 0xe04b, /* html:ArrowLeft (ArrowLeft) -> linux:105 (KEY_LEFT) -> atset1:57419 */ | |
| 13 | + "ArrowRight": 0xe04d, /* html:ArrowRight (ArrowRight) -> linux:106 (KEY_RIGHT) -> atset1:57421 */ | |
| 14 | + "ArrowUp": 0xe048, /* html:ArrowUp (ArrowUp) -> linux:103 (KEY_UP) -> atset1:57416 */ | |
| 15 | + "AudioVolumeDown": 0xe02e, /* html:AudioVolumeDown (AudioVolumeDown) -> linux:114 (KEY_VOLUMEDOWN) -> atset1:57390 */ | |
| 16 | + "AudioVolumeMute": 0xe020, /* html:AudioVolumeMute (AudioVolumeMute) -> linux:113 (KEY_MUTE) -> atset1:57376 */ | |
| 17 | + "AudioVolumeUp": 0xe030, /* html:AudioVolumeUp (AudioVolumeUp) -> linux:115 (KEY_VOLUMEUP) -> atset1:57392 */ | |
| 18 | + "Backquote": 0x29, /* html:Backquote (Backquote) -> linux:41 (KEY_GRAVE) -> atset1:41 */ | |
| 19 | + "Backslash": 0x2b, /* html:Backslash (Backslash) -> linux:43 (KEY_BACKSLASH) -> atset1:43 */ | |
| 20 | + "Backspace": 0xe, /* html:Backspace (Backspace) -> linux:14 (KEY_BACKSPACE) -> atset1:14 */ | |
| 21 | + "BracketLeft": 0x1a, /* html:BracketLeft (BracketLeft) -> linux:26 (KEY_LEFTBRACE) -> atset1:26 */ | |
| 22 | + "BracketRight": 0x1b, /* html:BracketRight (BracketRight) -> linux:27 (KEY_RIGHTBRACE) -> atset1:27 */ | |
| 23 | + "BrowserBack": 0xe06a, /* html:BrowserBack (BrowserBack) -> linux:158 (KEY_BACK) -> atset1:57450 */ | |
| 24 | + "BrowserFavorites": 0xe066, /* html:BrowserFavorites (BrowserFavorites) -> linux:156 (KEY_BOOKMARKS) -> atset1:57446 */ | |
| 25 | + "BrowserForward": 0xe069, /* html:BrowserForward (BrowserForward) -> linux:159 (KEY_FORWARD) -> atset1:57449 */ | |
| 26 | + "BrowserHome": 0xe032, /* html:BrowserHome (BrowserHome) -> linux:172 (KEY_HOMEPAGE) -> atset1:57394 */ | |
| 27 | + "BrowserRefresh": 0xe067, /* html:BrowserRefresh (BrowserRefresh) -> linux:173 (KEY_REFRESH) -> atset1:57447 */ | |
| 28 | + "BrowserSearch": 0xe065, /* html:BrowserSearch (BrowserSearch) -> linux:217 (KEY_SEARCH) -> atset1:57445 */ | |
| 29 | + "BrowserStop": 0xe068, /* html:BrowserStop (BrowserStop) -> linux:128 (KEY_STOP) -> atset1:57448 */ | |
| 30 | + "CapsLock": 0x3a, /* html:CapsLock (CapsLock) -> linux:58 (KEY_CAPSLOCK) -> atset1:58 */ | |
| 31 | + "Comma": 0x33, /* html:Comma (Comma) -> linux:51 (KEY_COMMA) -> atset1:51 */ | |
| 32 | + "ContextMenu": 0xe05d, /* html:ContextMenu (ContextMenu) -> linux:127 (KEY_COMPOSE) -> atset1:57437 */ | |
| 33 | + "ControlLeft": 0x1d, /* html:ControlLeft (ControlLeft) -> linux:29 (KEY_LEFTCTRL) -> atset1:29 */ | |
| 34 | + "ControlRight": 0xe01d, /* html:ControlRight (ControlRight) -> linux:97 (KEY_RIGHTCTRL) -> atset1:57373 */ | |
| 35 | + "Convert": 0x79, /* html:Convert (Convert) -> linux:92 (KEY_HENKAN) -> atset1:121 */ | |
| 36 | + "Copy": 0xe078, /* html:Copy (Copy) -> linux:133 (KEY_COPY) -> atset1:57464 */ | |
| 37 | + "Cut": 0xe03c, /* html:Cut (Cut) -> linux:137 (KEY_CUT) -> atset1:57404 */ | |
| 38 | + "Delete": 0xe053, /* html:Delete (Delete) -> linux:111 (KEY_DELETE) -> atset1:57427 */ | |
| 39 | + "Digit0": 0xb, /* html:Digit0 (Digit0) -> linux:11 (KEY_0) -> atset1:11 */ | |
| 40 | + "Digit1": 0x2, /* html:Digit1 (Digit1) -> linux:2 (KEY_1) -> atset1:2 */ | |
| 41 | + "Digit2": 0x3, /* html:Digit2 (Digit2) -> linux:3 (KEY_2) -> atset1:3 */ | |
| 42 | + "Digit3": 0x4, /* html:Digit3 (Digit3) -> linux:4 (KEY_3) -> atset1:4 */ | |
| 43 | + "Digit4": 0x5, /* html:Digit4 (Digit4) -> linux:5 (KEY_4) -> atset1:5 */ | |
| 44 | + "Digit5": 0x6, /* html:Digit5 (Digit5) -> linux:6 (KEY_5) -> atset1:6 */ | |
| 45 | + "Digit6": 0x7, /* html:Digit6 (Digit6) -> linux:7 (KEY_6) -> atset1:7 */ | |
| 46 | + "Digit7": 0x8, /* html:Digit7 (Digit7) -> linux:8 (KEY_7) -> atset1:8 */ | |
| 47 | + "Digit8": 0x9, /* html:Digit8 (Digit8) -> linux:9 (KEY_8) -> atset1:9 */ | |
| 48 | + "Digit9": 0xa, /* html:Digit9 (Digit9) -> linux:10 (KEY_9) -> atset1:10 */ | |
| 49 | + "Eject": 0xe07d, /* html:Eject (Eject) -> linux:162 (KEY_EJECTCLOSECD) -> atset1:57469 */ | |
| 50 | + "End": 0xe04f, /* html:End (End) -> linux:107 (KEY_END) -> atset1:57423 */ | |
| 51 | + "Enter": 0x1c, /* html:Enter (Enter) -> linux:28 (KEY_ENTER) -> atset1:28 */ | |
| 52 | + "Equal": 0xd, /* html:Equal (Equal) -> linux:13 (KEY_EQUAL) -> atset1:13 */ | |
| 53 | + "Escape": 0x1, /* html:Escape (Escape) -> linux:1 (KEY_ESC) -> atset1:1 */ | |
| 54 | + "F1": 0x3b, /* html:F1 (F1) -> linux:59 (KEY_F1) -> atset1:59 */ | |
| 55 | + "F10": 0x44, /* html:F10 (F10) -> linux:68 (KEY_F10) -> atset1:68 */ | |
| 56 | + "F11": 0x57, /* html:F11 (F11) -> linux:87 (KEY_F11) -> atset1:87 */ | |
| 57 | + "F12": 0x58, /* html:F12 (F12) -> linux:88 (KEY_F12) -> atset1:88 */ | |
| 58 | + "F13": 0x5d, /* html:F13 (F13) -> linux:183 (KEY_F13) -> atset1:93 */ | |
| 59 | + "F14": 0x5e, /* html:F14 (F14) -> linux:184 (KEY_F14) -> atset1:94 */ | |
| 60 | + "F15": 0x5f, /* html:F15 (F15) -> linux:185 (KEY_F15) -> atset1:95 */ | |
| 61 | + "F16": 0x55, /* html:F16 (F16) -> linux:186 (KEY_F16) -> atset1:85 */ | |
| 62 | + "F17": 0xe003, /* html:F17 (F17) -> linux:187 (KEY_F17) -> atset1:57347 */ | |
| 63 | + "F18": 0xe077, /* html:F18 (F18) -> linux:188 (KEY_F18) -> atset1:57463 */ | |
| 64 | + "F19": 0xe004, /* html:F19 (F19) -> linux:189 (KEY_F19) -> atset1:57348 */ | |
| 65 | + "F2": 0x3c, /* html:F2 (F2) -> linux:60 (KEY_F2) -> atset1:60 */ | |
| 66 | + "F20": 0x5a, /* html:F20 (F20) -> linux:190 (KEY_F20) -> atset1:90 */ | |
| 67 | + "F21": 0x74, /* html:F21 (F21) -> linux:191 (KEY_F21) -> atset1:116 */ | |
| 68 | + "F22": 0xe079, /* html:F22 (F22) -> linux:192 (KEY_F22) -> atset1:57465 */ | |
| 69 | + "F23": 0x6d, /* html:F23 (F23) -> linux:193 (KEY_F23) -> atset1:109 */ | |
| 70 | + "F24": 0x6f, /* html:F24 (F24) -> linux:194 (KEY_F24) -> atset1:111 */ | |
| 71 | + "F3": 0x3d, /* html:F3 (F3) -> linux:61 (KEY_F3) -> atset1:61 */ | |
| 72 | + "F4": 0x3e, /* html:F4 (F4) -> linux:62 (KEY_F4) -> atset1:62 */ | |
| 73 | + "F5": 0x3f, /* html:F5 (F5) -> linux:63 (KEY_F5) -> atset1:63 */ | |
| 74 | + "F6": 0x40, /* html:F6 (F6) -> linux:64 (KEY_F6) -> atset1:64 */ | |
| 75 | + "F7": 0x41, /* html:F7 (F7) -> linux:65 (KEY_F7) -> atset1:65 */ | |
| 76 | + "F8": 0x42, /* html:F8 (F8) -> linux:66 (KEY_F8) -> atset1:66 */ | |
| 77 | + "F9": 0x43, /* html:F9 (F9) -> linux:67 (KEY_F9) -> atset1:67 */ | |
| 78 | + "Find": 0xe041, /* html:Find (Find) -> linux:136 (KEY_FIND) -> atset1:57409 */ | |
| 79 | + "Help": 0xe075, /* html:Help (Help) -> linux:138 (KEY_HELP) -> atset1:57461 */ | |
| 80 | + "Hiragana": 0x77, /* html:Hiragana (Lang4) -> linux:91 (KEY_HIRAGANA) -> atset1:119 */ | |
| 81 | + "Home": 0xe047, /* html:Home (Home) -> linux:102 (KEY_HOME) -> atset1:57415 */ | |
| 82 | + "Insert": 0xe052, /* html:Insert (Insert) -> linux:110 (KEY_INSERT) -> atset1:57426 */ | |
| 83 | + "IntlBackslash": 0x56, /* html:IntlBackslash (IntlBackslash) -> linux:86 (KEY_102ND) -> atset1:86 */ | |
| 84 | + "IntlRo": 0x73, /* html:IntlRo (IntlRo) -> linux:89 (KEY_RO) -> atset1:115 */ | |
| 85 | + "IntlYen": 0x7d, /* html:IntlYen (IntlYen) -> linux:124 (KEY_YEN) -> atset1:125 */ | |
| 86 | + "KanaMode": 0x70, /* html:KanaMode (KanaMode) -> linux:93 (KEY_KATAKANAHIRAGANA) -> atset1:112 */ | |
| 87 | + "Katakana": 0x78, /* html:Katakana (Lang3) -> linux:90 (KEY_KATAKANA) -> atset1:120 */ | |
| 88 | + "KeyA": 0x1e, /* html:KeyA (KeyA) -> linux:30 (KEY_A) -> atset1:30 */ | |
| 89 | + "KeyB": 0x30, /* html:KeyB (KeyB) -> linux:48 (KEY_B) -> atset1:48 */ | |
| 90 | + "KeyC": 0x2e, /* html:KeyC (KeyC) -> linux:46 (KEY_C) -> atset1:46 */ | |
| 91 | + "KeyD": 0x20, /* html:KeyD (KeyD) -> linux:32 (KEY_D) -> atset1:32 */ | |
| 92 | + "KeyE": 0x12, /* html:KeyE (KeyE) -> linux:18 (KEY_E) -> atset1:18 */ | |
| 93 | + "KeyF": 0x21, /* html:KeyF (KeyF) -> linux:33 (KEY_F) -> atset1:33 */ | |
| 94 | + "KeyG": 0x22, /* html:KeyG (KeyG) -> linux:34 (KEY_G) -> atset1:34 */ | |
| 95 | + "KeyH": 0x23, /* html:KeyH (KeyH) -> linux:35 (KEY_H) -> atset1:35 */ | |
| 96 | + "KeyI": 0x17, /* html:KeyI (KeyI) -> linux:23 (KEY_I) -> atset1:23 */ | |
| 97 | + "KeyJ": 0x24, /* html:KeyJ (KeyJ) -> linux:36 (KEY_J) -> atset1:36 */ | |
| 98 | + "KeyK": 0x25, /* html:KeyK (KeyK) -> linux:37 (KEY_K) -> atset1:37 */ | |
| 99 | + "KeyL": 0x26, /* html:KeyL (KeyL) -> linux:38 (KEY_L) -> atset1:38 */ | |
| 100 | + "KeyM": 0x32, /* html:KeyM (KeyM) -> linux:50 (KEY_M) -> atset1:50 */ | |
| 101 | + "KeyN": 0x31, /* html:KeyN (KeyN) -> linux:49 (KEY_N) -> atset1:49 */ | |
| 102 | + "KeyO": 0x18, /* html:KeyO (KeyO) -> linux:24 (KEY_O) -> atset1:24 */ | |
| 103 | + "KeyP": 0x19, /* html:KeyP (KeyP) -> linux:25 (KEY_P) -> atset1:25 */ | |
| 104 | + "KeyQ": 0x10, /* html:KeyQ (KeyQ) -> linux:16 (KEY_Q) -> atset1:16 */ | |
| 105 | + "KeyR": 0x13, /* html:KeyR (KeyR) -> linux:19 (KEY_R) -> atset1:19 */ | |
| 106 | + "KeyS": 0x1f, /* html:KeyS (KeyS) -> linux:31 (KEY_S) -> atset1:31 */ | |
| 107 | + "KeyT": 0x14, /* html:KeyT (KeyT) -> linux:20 (KEY_T) -> atset1:20 */ | |
| 108 | + "KeyU": 0x16, /* html:KeyU (KeyU) -> linux:22 (KEY_U) -> atset1:22 */ | |
| 109 | + "KeyV": 0x2f, /* html:KeyV (KeyV) -> linux:47 (KEY_V) -> atset1:47 */ | |
| 110 | + "KeyW": 0x11, /* html:KeyW (KeyW) -> linux:17 (KEY_W) -> atset1:17 */ | |
| 111 | + "KeyX": 0x2d, /* html:KeyX (KeyX) -> linux:45 (KEY_X) -> atset1:45 */ | |
| 112 | + "KeyY": 0x15, /* html:KeyY (KeyY) -> linux:21 (KEY_Y) -> atset1:21 */ | |
| 113 | + "KeyZ": 0x2c, /* html:KeyZ (KeyZ) -> linux:44 (KEY_Z) -> atset1:44 */ | |
| 114 | + "Lang1": 0x72, /* html:Lang1 (Lang1) -> linux:122 (KEY_HANGEUL) -> atset1:114 */ | |
| 115 | + "Lang2": 0x71, /* html:Lang2 (Lang2) -> linux:123 (KEY_HANJA) -> atset1:113 */ | |
| 116 | + "Lang3": 0x78, /* html:Lang3 (Lang3) -> linux:90 (KEY_KATAKANA) -> atset1:120 */ | |
| 117 | + "Lang4": 0x77, /* html:Lang4 (Lang4) -> linux:91 (KEY_HIRAGANA) -> atset1:119 */ | |
| 118 | + "Lang5": 0x76, /* html:Lang5 (Lang5) -> linux:85 (KEY_ZENKAKUHANKAKU) -> atset1:118 */ | |
| 119 | + "LaunchApp1": 0xe06b, /* html:LaunchApp1 (LaunchApp1) -> linux:157 (KEY_COMPUTER) -> atset1:57451 */ | |
| 120 | + "LaunchApp2": 0xe021, /* html:LaunchApp2 (LaunchApp2) -> linux:140 (KEY_CALC) -> atset1:57377 */ | |
| 121 | + "LaunchMail": 0xe06c, /* html:LaunchMail (LaunchMail) -> linux:155 (KEY_MAIL) -> atset1:57452 */ | |
| 122 | + "MediaPlayPause": 0xe022, /* html:MediaPlayPause (MediaPlayPause) -> linux:164 (KEY_PLAYPAUSE) -> atset1:57378 */ | |
| 123 | + "MediaSelect": 0xe06d, /* html:MediaSelect (MediaSelect) -> linux:226 (KEY_MEDIA) -> atset1:57453 */ | |
| 124 | + "MediaStop": 0xe024, /* html:MediaStop (MediaStop) -> linux:166 (KEY_STOPCD) -> atset1:57380 */ | |
| 125 | + "MediaTrackNext": 0xe019, /* html:MediaTrackNext (MediaTrackNext) -> linux:163 (KEY_NEXTSONG) -> atset1:57369 */ | |
| 126 | + "MediaTrackPrevious": 0xe010, /* html:MediaTrackPrevious (MediaTrackPrevious) -> linux:165 (KEY_PREVIOUSSONG) -> atset1:57360 */ | |
| 127 | + "MetaLeft": 0xe05b, /* html:MetaLeft (MetaLeft) -> linux:125 (KEY_LEFTMETA) -> atset1:57435 */ | |
| 128 | + "MetaRight": 0xe05c, /* html:MetaRight (MetaRight) -> linux:126 (KEY_RIGHTMETA) -> atset1:57436 */ | |
| 129 | + "Minus": 0xc, /* html:Minus (Minus) -> linux:12 (KEY_MINUS) -> atset1:12 */ | |
| 130 | + "NonConvert": 0x7b, /* html:NonConvert (NonConvert) -> linux:94 (KEY_MUHENKAN) -> atset1:123 */ | |
| 131 | + "NumLock": 0x45, /* html:NumLock (NumLock) -> linux:69 (KEY_NUMLOCK) -> atset1:69 */ | |
| 132 | + "Numpad0": 0x52, /* html:Numpad0 (Numpad0) -> linux:82 (KEY_KP0) -> atset1:82 */ | |
| 133 | + "Numpad1": 0x4f, /* html:Numpad1 (Numpad1) -> linux:79 (KEY_KP1) -> atset1:79 */ | |
| 134 | + "Numpad2": 0x50, /* html:Numpad2 (Numpad2) -> linux:80 (KEY_KP2) -> atset1:80 */ | |
| 135 | + "Numpad3": 0x51, /* html:Numpad3 (Numpad3) -> linux:81 (KEY_KP3) -> atset1:81 */ | |
| 136 | + "Numpad4": 0x4b, /* html:Numpad4 (Numpad4) -> linux:75 (KEY_KP4) -> atset1:75 */ | |
| 137 | + "Numpad5": 0x4c, /* html:Numpad5 (Numpad5) -> linux:76 (KEY_KP5) -> atset1:76 */ | |
| 138 | + "Numpad6": 0x4d, /* html:Numpad6 (Numpad6) -> linux:77 (KEY_KP6) -> atset1:77 */ | |
| 139 | + "Numpad7": 0x47, /* html:Numpad7 (Numpad7) -> linux:71 (KEY_KP7) -> atset1:71 */ | |
| 140 | + "Numpad8": 0x48, /* html:Numpad8 (Numpad8) -> linux:72 (KEY_KP8) -> atset1:72 */ | |
| 141 | + "Numpad9": 0x49, /* html:Numpad9 (Numpad9) -> linux:73 (KEY_KP9) -> atset1:73 */ | |
| 142 | + "NumpadAdd": 0x4e, /* html:NumpadAdd (NumpadAdd) -> linux:78 (KEY_KPPLUS) -> atset1:78 */ | |
| 143 | + "NumpadComma": 0x7e, /* html:NumpadComma (NumpadComma) -> linux:121 (KEY_KPCOMMA) -> atset1:126 */ | |
| 144 | + "NumpadDecimal": 0x53, /* html:NumpadDecimal (NumpadDecimal) -> linux:83 (KEY_KPDOT) -> atset1:83 */ | |
| 145 | + "NumpadDivide": 0xe035, /* html:NumpadDivide (NumpadDivide) -> linux:98 (KEY_KPSLASH) -> atset1:57397 */ | |
| 146 | + "NumpadEnter": 0xe01c, /* html:NumpadEnter (NumpadEnter) -> linux:96 (KEY_KPENTER) -> atset1:57372 */ | |
| 147 | + "NumpadEqual": 0x59, /* html:NumpadEqual (NumpadEqual) -> linux:117 (KEY_KPEQUAL) -> atset1:89 */ | |
| 148 | + "NumpadMultiply": 0x37, /* html:NumpadMultiply (NumpadMultiply) -> linux:55 (KEY_KPASTERISK) -> atset1:55 */ | |
| 149 | + "NumpadParenLeft": 0xe076, /* html:NumpadParenLeft (NumpadParenLeft) -> linux:179 (KEY_KPLEFTPAREN) -> atset1:57462 */ | |
| 150 | + "NumpadParenRight": 0xe07b, /* html:NumpadParenRight (NumpadParenRight) -> linux:180 (KEY_KPRIGHTPAREN) -> atset1:57467 */ | |
| 151 | + "NumpadSubtract": 0x4a, /* html:NumpadSubtract (NumpadSubtract) -> linux:74 (KEY_KPMINUS) -> atset1:74 */ | |
| 152 | + "Open": 0x64, /* html:Open (Open) -> linux:134 (KEY_OPEN) -> atset1:100 */ | |
| 153 | + "PageDown": 0xe051, /* html:PageDown (PageDown) -> linux:109 (KEY_PAGEDOWN) -> atset1:57425 */ | |
| 154 | + "PageUp": 0xe049, /* html:PageUp (PageUp) -> linux:104 (KEY_PAGEUP) -> atset1:57417 */ | |
| 155 | + "Paste": 0x65, /* html:Paste (Paste) -> linux:135 (KEY_PASTE) -> atset1:101 */ | |
| 156 | + "Pause": 0xe046, /* html:Pause (Pause) -> linux:119 (KEY_PAUSE) -> atset1:57414 */ | |
| 157 | + "Period": 0x34, /* html:Period (Period) -> linux:52 (KEY_DOT) -> atset1:52 */ | |
| 158 | + "Power": 0xe05e, /* html:Power (Power) -> linux:116 (KEY_POWER) -> atset1:57438 */ | |
| 159 | + "PrintScreen": 0x54, /* html:PrintScreen (PrintScreen) -> linux:99 (KEY_SYSRQ) -> atset1:84 */ | |
| 160 | + "Props": 0xe006, /* html:Props (Props) -> linux:130 (KEY_PROPS) -> atset1:57350 */ | |
| 161 | + "Quote": 0x28, /* html:Quote (Quote) -> linux:40 (KEY_APOSTROPHE) -> atset1:40 */ | |
| 162 | + "ScrollLock": 0x46, /* html:ScrollLock (ScrollLock) -> linux:70 (KEY_SCROLLLOCK) -> atset1:70 */ | |
| 163 | + "Semicolon": 0x27, /* html:Semicolon (Semicolon) -> linux:39 (KEY_SEMICOLON) -> atset1:39 */ | |
| 164 | + "ShiftLeft": 0x2a, /* html:ShiftLeft (ShiftLeft) -> linux:42 (KEY_LEFTSHIFT) -> atset1:42 */ | |
| 165 | + "ShiftRight": 0x36, /* html:ShiftRight (ShiftRight) -> linux:54 (KEY_RIGHTSHIFT) -> atset1:54 */ | |
| 166 | + "Slash": 0x35, /* html:Slash (Slash) -> linux:53 (KEY_SLASH) -> atset1:53 */ | |
| 167 | + "Sleep": 0xe05f, /* html:Sleep (Sleep) -> linux:142 (KEY_SLEEP) -> atset1:57439 */ | |
| 168 | + "Space": 0x39, /* html:Space (Space) -> linux:57 (KEY_SPACE) -> atset1:57 */ | |
| 169 | + "Suspend": 0xe025, /* html:Suspend (Suspend) -> linux:205 (KEY_SUSPEND) -> atset1:57381 */ | |
| 170 | + "Tab": 0xf, /* html:Tab (Tab) -> linux:15 (KEY_TAB) -> atset1:15 */ | |
| 171 | + "Undo": 0xe007, /* html:Undo (Undo) -> linux:131 (KEY_UNDO) -> atset1:57351 */ | |
| 172 | + "WakeUp": 0xe063, /* html:WakeUp (WakeUp) -> linux:143 (KEY_WAKEUP) -> atset1:57443 */ | |
| 173 | +}; | |
added
public/vendor/novnc/core/ra2.js
+312 −0
@@ -0,0 +1,312 @@ | ||
| 1 | +import { encodeUTF8 } from './util/strings.js'; | |
| 2 | +import EventTargetMixin from './util/eventtarget.js'; | |
| 3 | +import legacyCrypto from './crypto/crypto.js'; | |
| 4 | + | |
| 5 | +class RA2Cipher { | |
| 6 | + constructor() { | |
| 7 | + this._cipher = null; | |
| 8 | + this._counter = new Uint8Array(16); | |
| 9 | + } | |
| 10 | + | |
| 11 | + async setKey(key) { | |
| 12 | + this._cipher = await legacyCrypto.importKey( | |
| 13 | + "raw", key, { name: "AES-EAX" }, false, ["encrypt, decrypt"]); | |
| 14 | + } | |
| 15 | + | |
| 16 | + async makeMessage(message) { | |
| 17 | + const ad = new Uint8Array([(message.length & 0xff00) >>> 8, message.length & 0xff]); | |
| 18 | + const encrypted = await legacyCrypto.encrypt({ | |
| 19 | + name: "AES-EAX", | |
| 20 | + iv: this._counter, | |
| 21 | + additionalData: ad, | |
| 22 | + }, this._cipher, message); | |
| 23 | + for (let i = 0; i < 16 && this._counter[i]++ === 255; i++); | |
| 24 | + const res = new Uint8Array(message.length + 2 + 16); | |
| 25 | + res.set(ad); | |
| 26 | + res.set(encrypted, 2); | |
| 27 | + return res; | |
| 28 | + } | |
| 29 | + | |
| 30 | + async receiveMessage(length, encrypted) { | |
| 31 | + const ad = new Uint8Array([(length & 0xff00) >>> 8, length & 0xff]); | |
| 32 | + const res = await legacyCrypto.decrypt({ | |
| 33 | + name: "AES-EAX", | |
| 34 | + iv: this._counter, | |
| 35 | + additionalData: ad, | |
| 36 | + }, this._cipher, encrypted); | |
| 37 | + for (let i = 0; i < 16 && this._counter[i]++ === 255; i++); | |
| 38 | + return res; | |
| 39 | + } | |
| 40 | +} | |
| 41 | + | |
| 42 | +export default class RSAAESAuthenticationState extends EventTargetMixin { | |
| 43 | + constructor(sock, getCredentials) { | |
| 44 | + super(); | |
| 45 | + this._hasStarted = false; | |
| 46 | + this._checkSock = null; | |
| 47 | + this._checkCredentials = null; | |
| 48 | + this._approveServerResolve = null; | |
| 49 | + this._sockReject = null; | |
| 50 | + this._credentialsReject = null; | |
| 51 | + this._approveServerReject = null; | |
| 52 | + this._sock = sock; | |
| 53 | + this._getCredentials = getCredentials; | |
| 54 | + } | |
| 55 | + | |
| 56 | + _waitSockAsync(len) { | |
| 57 | + return new Promise((resolve, reject) => { | |
| 58 | + const hasData = () => !this._sock.rQwait('RA2', len); | |
| 59 | + if (hasData()) { | |
| 60 | + resolve(); | |
| 61 | + } else { | |
| 62 | + this._checkSock = () => { | |
| 63 | + if (hasData()) { | |
| 64 | + resolve(); | |
| 65 | + this._checkSock = null; | |
| 66 | + this._sockReject = null; | |
| 67 | + } | |
| 68 | + }; | |
| 69 | + this._sockReject = reject; | |
| 70 | + } | |
| 71 | + }); | |
| 72 | + } | |
| 73 | + | |
| 74 | + _waitApproveKeyAsync() { | |
| 75 | + return new Promise((resolve, reject) => { | |
| 76 | + this._approveServerResolve = resolve; | |
| 77 | + this._approveServerReject = reject; | |
| 78 | + }); | |
| 79 | + } | |
| 80 | + | |
| 81 | + _waitCredentialsAsync(subtype) { | |
| 82 | + const hasCredentials = () => { | |
| 83 | + if (subtype === 1 && this._getCredentials().username !== undefined && | |
| 84 | + this._getCredentials().password !== undefined) { | |
| 85 | + return true; | |
| 86 | + } else if (subtype === 2 && this._getCredentials().password !== undefined) { | |
| 87 | + return true; | |
| 88 | + } | |
| 89 | + return false; | |
| 90 | + }; | |
| 91 | + return new Promise((resolve, reject) => { | |
| 92 | + if (hasCredentials()) { | |
| 93 | + resolve(); | |
| 94 | + } else { | |
| 95 | + this._checkCredentials = () => { | |
| 96 | + if (hasCredentials()) { | |
| 97 | + resolve(); | |
| 98 | + this._checkCredentials = null; | |
| 99 | + this._credentialsReject = null; | |
| 100 | + } | |
| 101 | + }; | |
| 102 | + this._credentialsReject = reject; | |
| 103 | + } | |
| 104 | + }); | |
| 105 | + } | |
| 106 | + | |
| 107 | + checkInternalEvents() { | |
| 108 | + if (this._checkSock !== null) { | |
| 109 | + this._checkSock(); | |
| 110 | + } | |
| 111 | + if (this._checkCredentials !== null) { | |
| 112 | + this._checkCredentials(); | |
| 113 | + } | |
| 114 | + } | |
| 115 | + | |
| 116 | + approveServer() { | |
| 117 | + if (this._approveServerResolve !== null) { | |
| 118 | + this._approveServerResolve(); | |
| 119 | + this._approveServerResolve = null; | |
| 120 | + } | |
| 121 | + } | |
| 122 | + | |
| 123 | + disconnect() { | |
| 124 | + if (this._sockReject !== null) { | |
| 125 | + this._sockReject(new Error("disconnect normally")); | |
| 126 | + this._sockReject = null; | |
| 127 | + } | |
| 128 | + if (this._credentialsReject !== null) { | |
| 129 | + this._credentialsReject(new Error("disconnect normally")); | |
| 130 | + this._credentialsReject = null; | |
| 131 | + } | |
| 132 | + if (this._approveServerReject !== null) { | |
| 133 | + this._approveServerReject(new Error("disconnect normally")); | |
| 134 | + this._approveServerReject = null; | |
| 135 | + } | |
| 136 | + } | |
| 137 | + | |
| 138 | + async negotiateRA2neAuthAsync() { | |
| 139 | + this._hasStarted = true; | |
| 140 | + // 1: Receive server public key | |
| 141 | + await this._waitSockAsync(4); | |
| 142 | + const serverKeyLengthBuffer = this._sock.rQpeekBytes(4); | |
| 143 | + const serverKeyLength = this._sock.rQshift32(); | |
| 144 | + if (serverKeyLength < 1024) { | |
| 145 | + throw new Error("RA2: server public key is too short: " + serverKeyLength); | |
| 146 | + } else if (serverKeyLength > 8192) { | |
| 147 | + throw new Error("RA2: server public key is too long: " + serverKeyLength); | |
| 148 | + } | |
| 149 | + const serverKeyBytes = Math.ceil(serverKeyLength / 8); | |
| 150 | + await this._waitSockAsync(serverKeyBytes * 2); | |
| 151 | + const serverN = this._sock.rQshiftBytes(serverKeyBytes); | |
| 152 | + const serverE = this._sock.rQshiftBytes(serverKeyBytes); | |
| 153 | + const serverRSACipher = await legacyCrypto.importKey( | |
| 154 | + "raw", { n: serverN, e: serverE }, { name: "RSA-PKCS1-v1_5" }, false, ["encrypt"]); | |
| 155 | + const serverPublickey = new Uint8Array(4 + serverKeyBytes * 2); | |
| 156 | + serverPublickey.set(serverKeyLengthBuffer); | |
| 157 | + serverPublickey.set(serverN, 4); | |
| 158 | + serverPublickey.set(serverE, 4 + serverKeyBytes); | |
| 159 | + | |
| 160 | + // verify server public key | |
| 161 | + let approveKey = this._waitApproveKeyAsync(); | |
| 162 | + this.dispatchEvent(new CustomEvent("serververification", { | |
| 163 | + detail: { type: "RSA", publickey: serverPublickey } | |
| 164 | + })); | |
| 165 | + await approveKey; | |
| 166 | + | |
| 167 | + // 2: Send client public key | |
| 168 | + const clientKeyLength = 2048; | |
| 169 | + const clientKeyBytes = Math.ceil(clientKeyLength / 8); | |
| 170 | + const clientRSACipher = (await legacyCrypto.generateKey({ | |
| 171 | + name: "RSA-PKCS1-v1_5", | |
| 172 | + modulusLength: clientKeyLength, | |
| 173 | + publicExponent: new Uint8Array([1, 0, 1]), | |
| 174 | + }, true, ["encrypt"])).privateKey; | |
| 175 | + const clientExportedRSAKey = await legacyCrypto.exportKey("raw", clientRSACipher); | |
| 176 | + const clientN = clientExportedRSAKey.n; | |
| 177 | + const clientE = clientExportedRSAKey.e; | |
| 178 | + const clientPublicKey = new Uint8Array(4 + clientKeyBytes * 2); | |
| 179 | + clientPublicKey[0] = (clientKeyLength & 0xff000000) >>> 24; | |
| 180 | + clientPublicKey[1] = (clientKeyLength & 0xff0000) >>> 16; | |
| 181 | + clientPublicKey[2] = (clientKeyLength & 0xff00) >>> 8; | |
| 182 | + clientPublicKey[3] = clientKeyLength & 0xff; | |
| 183 | + clientPublicKey.set(clientN, 4); | |
| 184 | + clientPublicKey.set(clientE, 4 + clientKeyBytes); | |
| 185 | + this._sock.sQpushBytes(clientPublicKey); | |
| 186 | + this._sock.flush(); | |
| 187 | + | |
| 188 | + // 3: Send client random | |
| 189 | + const clientRandom = new Uint8Array(16); | |
| 190 | + window.crypto.getRandomValues(clientRandom); | |
| 191 | + const clientEncryptedRandom = await legacyCrypto.encrypt( | |
| 192 | + { name: "RSA-PKCS1-v1_5" }, serverRSACipher, clientRandom); | |
| 193 | + const clientRandomMessage = new Uint8Array(2 + serverKeyBytes); | |
| 194 | + clientRandomMessage[0] = (serverKeyBytes & 0xff00) >>> 8; | |
| 195 | + clientRandomMessage[1] = serverKeyBytes & 0xff; | |
| 196 | + clientRandomMessage.set(clientEncryptedRandom, 2); | |
| 197 | + this._sock.sQpushBytes(clientRandomMessage); | |
| 198 | + this._sock.flush(); | |
| 199 | + | |
| 200 | + // 4: Receive server random | |
| 201 | + await this._waitSockAsync(2); | |
| 202 | + if (this._sock.rQshift16() !== clientKeyBytes) { | |
| 203 | + throw new Error("RA2: wrong encrypted message length"); | |
| 204 | + } | |
| 205 | + const serverEncryptedRandom = this._sock.rQshiftBytes(clientKeyBytes); | |
| 206 | + const serverRandom = await legacyCrypto.decrypt( | |
| 207 | + { name: "RSA-PKCS1-v1_5" }, clientRSACipher, serverEncryptedRandom); | |
| 208 | + if (serverRandom === null || serverRandom.length !== 16) { | |
| 209 | + throw new Error("RA2: corrupted server encrypted random"); | |
| 210 | + } | |
| 211 | + | |
| 212 | + // 5: Compute session keys and set ciphers | |
| 213 | + let clientSessionKey = new Uint8Array(32); | |
| 214 | + let serverSessionKey = new Uint8Array(32); | |
| 215 | + clientSessionKey.set(serverRandom); | |
| 216 | + clientSessionKey.set(clientRandom, 16); | |
| 217 | + serverSessionKey.set(clientRandom); | |
| 218 | + serverSessionKey.set(serverRandom, 16); | |
| 219 | + clientSessionKey = await window.crypto.subtle.digest("SHA-1", clientSessionKey); | |
| 220 | + clientSessionKey = new Uint8Array(clientSessionKey).slice(0, 16); | |
| 221 | + serverSessionKey = await window.crypto.subtle.digest("SHA-1", serverSessionKey); | |
| 222 | + serverSessionKey = new Uint8Array(serverSessionKey).slice(0, 16); | |
| 223 | + const clientCipher = new RA2Cipher(); | |
| 224 | + await clientCipher.setKey(clientSessionKey); | |
| 225 | + const serverCipher = new RA2Cipher(); | |
| 226 | + await serverCipher.setKey(serverSessionKey); | |
| 227 | + | |
| 228 | + // 6: Compute and exchange hashes | |
| 229 | + let serverHash = new Uint8Array(8 + serverKeyBytes * 2 + clientKeyBytes * 2); | |
| 230 | + let clientHash = new Uint8Array(8 + serverKeyBytes * 2 + clientKeyBytes * 2); | |
| 231 | + serverHash.set(serverPublickey); | |
| 232 | + serverHash.set(clientPublicKey, 4 + serverKeyBytes * 2); | |
| 233 | + clientHash.set(clientPublicKey); | |
| 234 | + clientHash.set(serverPublickey, 4 + clientKeyBytes * 2); | |
| 235 | + serverHash = await window.crypto.subtle.digest("SHA-1", serverHash); | |
| 236 | + clientHash = await window.crypto.subtle.digest("SHA-1", clientHash); | |
| 237 | + serverHash = new Uint8Array(serverHash); | |
| 238 | + clientHash = new Uint8Array(clientHash); | |
| 239 | + this._sock.sQpushBytes(await clientCipher.makeMessage(clientHash)); | |
| 240 | + this._sock.flush(); | |
| 241 | + await this._waitSockAsync(2 + 20 + 16); | |
| 242 | + if (this._sock.rQshift16() !== 20) { | |
| 243 | + throw new Error("RA2: wrong server hash"); | |
| 244 | + } | |
| 245 | + const serverHashReceived = await serverCipher.receiveMessage( | |
| 246 | + 20, this._sock.rQshiftBytes(20 + 16)); | |
| 247 | + if (serverHashReceived === null) { | |
| 248 | + throw new Error("RA2: failed to authenticate the message"); | |
| 249 | + } | |
| 250 | + for (let i = 0; i < 20; i++) { | |
| 251 | + if (serverHashReceived[i] !== serverHash[i]) { | |
| 252 | + throw new Error("RA2: wrong server hash"); | |
| 253 | + } | |
| 254 | + } | |
| 255 | + | |
| 256 | + // 7: Receive subtype | |
| 257 | + await this._waitSockAsync(2 + 1 + 16); | |
| 258 | + if (this._sock.rQshift16() !== 1) { | |
| 259 | + throw new Error("RA2: wrong subtype"); | |
| 260 | + } | |
| 261 | + let subtype = (await serverCipher.receiveMessage( | |
| 262 | + 1, this._sock.rQshiftBytes(1 + 16))); | |
| 263 | + if (subtype === null) { | |
| 264 | + throw new Error("RA2: failed to authenticate the message"); | |
| 265 | + } | |
| 266 | + subtype = subtype[0]; | |
| 267 | + let waitCredentials = this._waitCredentialsAsync(subtype); | |
| 268 | + if (subtype === 1) { | |
| 269 | + if (this._getCredentials().username === undefined || | |
| 270 | + this._getCredentials().password === undefined) { | |
| 271 | + this.dispatchEvent(new CustomEvent( | |
| 272 | + "credentialsrequired", | |
| 273 | + { detail: { types: ["username", "password"] } })); | |
| 274 | + } | |
| 275 | + } else if (subtype === 2) { | |
| 276 | + if (this._getCredentials().password === undefined) { | |
| 277 | + this.dispatchEvent(new CustomEvent( | |
| 278 | + "credentialsrequired", | |
| 279 | + { detail: { types: ["password"] } })); | |
| 280 | + } | |
| 281 | + } else { | |
| 282 | + throw new Error("RA2: wrong subtype"); | |
| 283 | + } | |
| 284 | + await waitCredentials; | |
| 285 | + let username; | |
| 286 | + if (subtype === 1) { | |
| 287 | + username = encodeUTF8(this._getCredentials().username).slice(0, 255); | |
| 288 | + } else { | |
| 289 | + username = ""; | |
| 290 | + } | |
| 291 | + const password = encodeUTF8(this._getCredentials().password).slice(0, 255); | |
| 292 | + const credentials = new Uint8Array(username.length + password.length + 2); | |
| 293 | + credentials[0] = username.length; | |
| 294 | + credentials[username.length + 1] = password.length; | |
| 295 | + for (let i = 0; i < username.length; i++) { | |
| 296 | + credentials[i + 1] = username.charCodeAt(i); | |
| 297 | + } | |
| 298 | + for (let i = 0; i < password.length; i++) { | |
| 299 | + credentials[username.length + 2 + i] = password.charCodeAt(i); | |
| 300 | + } | |
| 301 | + this._sock.sQpushBytes(await clientCipher.makeMessage(credentials)); | |
| 302 | + this._sock.flush(); | |
| 303 | + } | |
| 304 | + | |
| 305 | + get hasStarted() { | |
| 306 | + return this._hasStarted; | |
| 307 | + } | |
| 308 | + | |
| 309 | + set hasStarted(s) { | |
| 310 | + this._hasStarted = s; | |
| 311 | + } | |
| 312 | +} | |
added
public/vendor/novnc/core/rfb.js
+3415 −0
@@ -0,0 +1,3415 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2020 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + */ | |
| 9 | + | |
| 10 | +import { toUnsigned32bit, toSigned32bit } from './util/int.js'; | |
| 11 | +import * as Log from './util/logging.js'; | |
| 12 | +import { encodeUTF8, decodeUTF8 } from './util/strings.js'; | |
| 13 | +import { dragThreshold, supportsWebCodecsH264Decode } from './util/browser.js'; | |
| 14 | +import { clientToElement } from './util/element.js'; | |
| 15 | +import { setCapture } from './util/events.js'; | |
| 16 | +import EventTargetMixin from './util/eventtarget.js'; | |
| 17 | +import Display from "./display.js"; | |
| 18 | +import Inflator from "./inflator.js"; | |
| 19 | +import Deflator from "./deflator.js"; | |
| 20 | +import Keyboard from "./input/keyboard.js"; | |
| 21 | +import GestureHandler from "./input/gesturehandler.js"; | |
| 22 | +import Cursor from "./util/cursor.js"; | |
| 23 | +import Websock from "./websock.js"; | |
| 24 | +import KeyTable from "./input/keysym.js"; | |
| 25 | +import XtScancode from "./input/xtscancodes.js"; | |
| 26 | +import { encodings } from "./encodings.js"; | |
| 27 | +import RSAAESAuthenticationState from "./ra2.js"; | |
| 28 | +import legacyCrypto from "./crypto/crypto.js"; | |
| 29 | + | |
| 30 | +import RawDecoder from "./decoders/raw.js"; | |
| 31 | +import CopyRectDecoder from "./decoders/copyrect.js"; | |
| 32 | +import RREDecoder from "./decoders/rre.js"; | |
| 33 | +import HextileDecoder from "./decoders/hextile.js"; | |
| 34 | +import ZlibDecoder from './decoders/zlib.js'; | |
| 35 | +import TightDecoder from "./decoders/tight.js"; | |
| 36 | +import TightPNGDecoder from "./decoders/tightpng.js"; | |
| 37 | +import ZRLEDecoder from "./decoders/zrle.js"; | |
| 38 | +import JPEGDecoder from "./decoders/jpeg.js"; | |
| 39 | +import H264Decoder from "./decoders/h264.js"; | |
| 40 | + | |
| 41 | +// How many seconds to wait for a disconnect to finish | |
| 42 | +const DISCONNECT_TIMEOUT = 3; | |
| 43 | +const DEFAULT_BACKGROUND = 'rgb(40, 40, 40)'; | |
| 44 | + | |
| 45 | +// Minimum wait (ms) between two mouse moves | |
| 46 | +const MOUSE_MOVE_DELAY = 17; | |
| 47 | + | |
| 48 | +// Wheel thresholds | |
| 49 | +const WHEEL_STEP = 50; // Pixels needed for one step | |
| 50 | +const WHEEL_LINE_HEIGHT = 19; // Assumed pixels for one line step | |
| 51 | + | |
| 52 | +// Gesture thresholds | |
| 53 | +const GESTURE_ZOOMSENS = 75; | |
| 54 | +const GESTURE_SCRLSENS = 50; | |
| 55 | +const DOUBLE_TAP_TIMEOUT = 1000; | |
| 56 | +const DOUBLE_TAP_THRESHOLD = 50; | |
| 57 | + | |
| 58 | +// Security types | |
| 59 | +const securityTypeNone = 1; | |
| 60 | +const securityTypeVNCAuth = 2; | |
| 61 | +const securityTypeRA2ne = 6; | |
| 62 | +const securityTypeTight = 16; | |
| 63 | +const securityTypeVeNCrypt = 19; | |
| 64 | +const securityTypeXVP = 22; | |
| 65 | +const securityTypeARD = 30; | |
| 66 | +const securityTypeMSLogonII = 113; | |
| 67 | + | |
| 68 | +// Special Tight security types | |
| 69 | +const securityTypeUnixLogon = 129; | |
| 70 | + | |
| 71 | +// VeNCrypt security types | |
| 72 | +const securityTypePlain = 256; | |
| 73 | + | |
| 74 | +// Extended clipboard pseudo-encoding formats | |
| 75 | +const extendedClipboardFormatText = 1; | |
| 76 | +/*eslint-disable no-unused-vars */ | |
| 77 | +const extendedClipboardFormatRtf = 1 << 1; | |
| 78 | +const extendedClipboardFormatHtml = 1 << 2; | |
| 79 | +const extendedClipboardFormatDib = 1 << 3; | |
| 80 | +const extendedClipboardFormatFiles = 1 << 4; | |
| 81 | +/*eslint-enable */ | |
| 82 | + | |
| 83 | +// Extended clipboard pseudo-encoding actions | |
| 84 | +const extendedClipboardActionCaps = 1 << 24; | |
| 85 | +const extendedClipboardActionRequest = 1 << 25; | |
| 86 | +const extendedClipboardActionPeek = 1 << 26; | |
| 87 | +const extendedClipboardActionNotify = 1 << 27; | |
| 88 | +const extendedClipboardActionProvide = 1 << 28; | |
| 89 | + | |
| 90 | +export default class RFB extends EventTargetMixin { | |
| 91 | + constructor(target, urlOrChannel, options) { | |
| 92 | + if (!target) { | |
| 93 | + throw new Error("Must specify target"); | |
| 94 | + } | |
| 95 | + if (!urlOrChannel) { | |
| 96 | + throw new Error("Must specify URL, WebSocket or RTCDataChannel"); | |
| 97 | + } | |
| 98 | + | |
| 99 | + // We rely on modern APIs which might not be available in an | |
| 100 | + // insecure context | |
| 101 | + if (!window.isSecureContext) { | |
| 102 | + Log.Error("noVNC requires a secure context (TLS). Expect crashes!"); | |
| 103 | + } | |
| 104 | + | |
| 105 | + super(); | |
| 106 | + | |
| 107 | + this._target = target; | |
| 108 | + | |
| 109 | + if (typeof urlOrChannel === "string") { | |
| 110 | + this._url = urlOrChannel; | |
| 111 | + } else { | |
| 112 | + this._url = null; | |
| 113 | + this._rawChannel = urlOrChannel; | |
| 114 | + } | |
| 115 | + | |
| 116 | + // Connection details | |
| 117 | + options = options || {}; | |
| 118 | + this._rfbCredentials = options.credentials || {}; | |
| 119 | + this._shared = 'shared' in options ? !!options.shared : true; | |
| 120 | + this._repeaterID = options.repeaterID || ''; | |
| 121 | + this._wsProtocols = options.wsProtocols || []; | |
| 122 | + | |
| 123 | + // Internal state | |
| 124 | + this._rfbConnectionState = ''; | |
| 125 | + this._rfbInitState = ''; | |
| 126 | + this._rfbAuthScheme = -1; | |
| 127 | + this._rfbCleanDisconnect = true; | |
| 128 | + this._rfbRSAAESAuthenticationState = null; | |
| 129 | + | |
| 130 | + // Server capabilities | |
| 131 | + this._rfbVersion = 0; | |
| 132 | + this._rfbMaxVersion = 3.8; | |
| 133 | + this._rfbTightVNC = false; | |
| 134 | + this._rfbVeNCryptState = 0; | |
| 135 | + this._rfbXvpVer = 0; | |
| 136 | + | |
| 137 | + this._fbWidth = 0; | |
| 138 | + this._fbHeight = 0; | |
| 139 | + | |
| 140 | + this._fbName = ""; | |
| 141 | + | |
| 142 | + this._capabilities = { power: false }; | |
| 143 | + | |
| 144 | + this._supportsFence = false; | |
| 145 | + | |
| 146 | + this._supportsContinuousUpdates = false; | |
| 147 | + this._enabledContinuousUpdates = false; | |
| 148 | + | |
| 149 | + this._supportsSetDesktopSize = false; | |
| 150 | + this._screenID = 0; | |
| 151 | + this._screenFlags = 0; | |
| 152 | + this._pendingRemoteResize = false; | |
| 153 | + this._lastResize = 0; | |
| 154 | + | |
| 155 | + this._qemuExtKeyEventSupported = false; | |
| 156 | + | |
| 157 | + this._extendedPointerEventSupported = false; | |
| 158 | + | |
| 159 | + this._clipboardText = null; | |
| 160 | + this._clipboardServerCapabilitiesActions = {}; | |
| 161 | + this._clipboardServerCapabilitiesFormats = {}; | |
| 162 | + | |
| 163 | + // Internal objects | |
| 164 | + this._sock = null; // Websock object | |
| 165 | + this._display = null; // Display object | |
| 166 | + this._flushing = false; // Display flushing state | |
| 167 | + this._keyboard = null; // Keyboard input handler object | |
| 168 | + this._gestures = null; // Gesture input handler object | |
| 169 | + this._resizeObserver = null; // Resize observer object | |
| 170 | + | |
| 171 | + // Timers | |
| 172 | + this._disconnTimer = null; // disconnection timer | |
| 173 | + this._resizeTimeout = null; // resize rate limiting | |
| 174 | + this._mouseMoveTimer = null; | |
| 175 | + | |
| 176 | + // Decoder states | |
| 177 | + this._decoders = {}; | |
| 178 | + | |
| 179 | + this._FBU = { | |
| 180 | + rects: 0, | |
| 181 | + x: 0, | |
| 182 | + y: 0, | |
| 183 | + width: 0, | |
| 184 | + height: 0, | |
| 185 | + encoding: null, | |
| 186 | + }; | |
| 187 | + | |
| 188 | + // Mouse state | |
| 189 | + this._mousePos = {}; | |
| 190 | + this._mouseButtonMask = 0; | |
| 191 | + this._mouseLastMoveTime = 0; | |
| 192 | + this._viewportDragging = false; | |
| 193 | + this._viewportDragPos = {}; | |
| 194 | + this._viewportHasMoved = false; | |
| 195 | + this._accumulatedWheelDeltaX = 0; | |
| 196 | + this._accumulatedWheelDeltaY = 0; | |
| 197 | + | |
| 198 | + // Gesture state | |
| 199 | + this._gestureLastTapTime = null; | |
| 200 | + this._gestureFirstDoubleTapEv = null; | |
| 201 | + this._gestureLastMagnitudeX = 0; | |
| 202 | + this._gestureLastMagnitudeY = 0; | |
| 203 | + | |
| 204 | + // Bound event handlers | |
| 205 | + this._eventHandlers = { | |
| 206 | + focusCanvas: this._focusCanvas.bind(this), | |
| 207 | + handleResize: this._handleResize.bind(this), | |
| 208 | + handleMouse: this._handleMouse.bind(this), | |
| 209 | + handleWheel: this._handleWheel.bind(this), | |
| 210 | + handleGesture: this._handleGesture.bind(this), | |
| 211 | + handleRSAAESCredentialsRequired: this._handleRSAAESCredentialsRequired.bind(this), | |
| 212 | + handleRSAAESServerVerification: this._handleRSAAESServerVerification.bind(this), | |
| 213 | + }; | |
| 214 | + | |
| 215 | + // main setup | |
| 216 | + Log.Debug(">> RFB.constructor"); | |
| 217 | + | |
| 218 | + // Create DOM elements | |
| 219 | + this._screen = document.createElement('div'); | |
| 220 | + this._screen.style.display = 'flex'; | |
| 221 | + this._screen.style.width = '100%'; | |
| 222 | + this._screen.style.height = '100%'; | |
| 223 | + this._screen.style.overflow = 'auto'; | |
| 224 | + this._screen.style.background = DEFAULT_BACKGROUND; | |
| 225 | + this._canvas = document.createElement('canvas'); | |
| 226 | + this._canvas.style.margin = 'auto'; | |
| 227 | + // Some browsers add an outline on focus | |
| 228 | + this._canvas.style.outline = 'none'; | |
| 229 | + this._canvas.width = 0; | |
| 230 | + this._canvas.height = 0; | |
| 231 | + this._canvas.tabIndex = -1; | |
| 232 | + this._screen.appendChild(this._canvas); | |
| 233 | + | |
| 234 | + // Cursor | |
| 235 | + this._cursor = new Cursor(); | |
| 236 | + | |
| 237 | + // XXX: TightVNC 2.8.11 sends no cursor at all until Windows changes | |
| 238 | + // it. Result: no cursor at all until a window border or an edit field | |
| 239 | + // is hit blindly. But there are also VNC servers that draw the cursor | |
| 240 | + // in the framebuffer and don't send the empty local cursor. There is | |
| 241 | + // no way to satisfy both sides. | |
| 242 | + // | |
| 243 | + // The spec is unclear on this "initial cursor" issue. Many other | |
| 244 | + // viewers (TigerVNC, RealVNC, Remmina) display an arrow as the | |
| 245 | + // initial cursor instead. | |
| 246 | + this._cursorImage = RFB.cursors.none; | |
| 247 | + | |
| 248 | + // populate decoder array with objects | |
| 249 | + this._decoders[encodings.encodingRaw] = new RawDecoder(); | |
| 250 | + this._decoders[encodings.encodingCopyRect] = new CopyRectDecoder(); | |
| 251 | + this._decoders[encodings.encodingRRE] = new RREDecoder(); | |
| 252 | + this._decoders[encodings.encodingHextile] = new HextileDecoder(); | |
| 253 | + this._decoders[encodings.encodingZlib] = new ZlibDecoder(); | |
| 254 | + this._decoders[encodings.encodingTight] = new TightDecoder(); | |
| 255 | + this._decoders[encodings.encodingTightPNG] = new TightPNGDecoder(); | |
| 256 | + this._decoders[encodings.encodingZRLE] = new ZRLEDecoder(); | |
| 257 | + this._decoders[encodings.encodingJPEG] = new JPEGDecoder(); | |
| 258 | + this._decoders[encodings.encodingH264] = new H264Decoder(); | |
| 259 | + | |
| 260 | + // NB: nothing that needs explicit teardown should be done | |
| 261 | + // before this point, since this can throw an exception | |
| 262 | + try { | |
| 263 | + this._display = new Display(this._canvas); | |
| 264 | + } catch (exc) { | |
| 265 | + Log.Error("Display exception: " + exc); | |
| 266 | + throw exc; | |
| 267 | + } | |
| 268 | + | |
| 269 | + this._keyboard = new Keyboard(this._canvas); | |
| 270 | + this._keyboard.onkeyevent = this._handleKeyEvent.bind(this); | |
| 271 | + this._remoteCapsLock = null; // Null indicates unknown or irrelevant | |
| 272 | + this._remoteNumLock = null; | |
| 273 | + | |
| 274 | + this._gestures = new GestureHandler(); | |
| 275 | + | |
| 276 | + this._sock = new Websock(); | |
| 277 | + this._sock.on('open', this._socketOpen.bind(this)); | |
| 278 | + this._sock.on('close', this._socketClose.bind(this)); | |
| 279 | + this._sock.on('message', this._handleMessage.bind(this)); | |
| 280 | + this._sock.on('error', this._socketError.bind(this)); | |
| 281 | + | |
| 282 | + this._expectedClientWidth = null; | |
| 283 | + this._expectedClientHeight = null; | |
| 284 | + this._resizeObserver = new ResizeObserver(this._eventHandlers.handleResize); | |
| 285 | + | |
| 286 | + // All prepared, kick off the connection | |
| 287 | + this._updateConnectionState('connecting'); | |
| 288 | + | |
| 289 | + Log.Debug("<< RFB.constructor"); | |
| 290 | + | |
| 291 | + // ===== PROPERTIES ===== | |
| 292 | + | |
| 293 | + this.dragViewport = false; | |
| 294 | + this.focusOnClick = true; | |
| 295 | + | |
| 296 | + this._viewOnly = false; | |
| 297 | + this._clipViewport = false; | |
| 298 | + this._clippingViewport = false; | |
| 299 | + this._scaleViewport = false; | |
| 300 | + this._resizeSession = false; | |
| 301 | + | |
| 302 | + this._showDotCursor = false; | |
| 303 | + if (options.showDotCursor !== undefined) { | |
| 304 | + Log.Warn("Specifying showDotCursor as a RFB constructor argument is deprecated"); | |
| 305 | + this._showDotCursor = options.showDotCursor; | |
| 306 | + } | |
| 307 | + | |
| 308 | + this._qualityLevel = 6; | |
| 309 | + this._compressionLevel = 2; | |
| 310 | + } | |
| 311 | + | |
| 312 | + // ===== PROPERTIES ===== | |
| 313 | + | |
| 314 | + get viewOnly() { return this._viewOnly; } | |
| 315 | + set viewOnly(viewOnly) { | |
| 316 | + this._viewOnly = viewOnly; | |
| 317 | + | |
| 318 | + if (this._rfbConnectionState === "connecting" || | |
| 319 | + this._rfbConnectionState === "connected") { | |
| 320 | + if (viewOnly) { | |
| 321 | + this._keyboard.ungrab(); | |
| 322 | + } else { | |
| 323 | + this._keyboard.grab(); | |
| 324 | + } | |
| 325 | + } | |
| 326 | + } | |
| 327 | + | |
| 328 | + get capabilities() { return this._capabilities; } | |
| 329 | + | |
| 330 | + get clippingViewport() { return this._clippingViewport; } | |
| 331 | + _setClippingViewport(on) { | |
| 332 | + if (on === this._clippingViewport) { | |
| 333 | + return; | |
| 334 | + } | |
| 335 | + this._clippingViewport = on; | |
| 336 | + this.dispatchEvent(new CustomEvent("clippingviewport", | |
| 337 | + { detail: this._clippingViewport })); | |
| 338 | + } | |
| 339 | + | |
| 340 | + get touchButton() { return 0; } | |
| 341 | + set touchButton(button) { Log.Warn("Using old API!"); } | |
| 342 | + | |
| 343 | + get clipViewport() { return this._clipViewport; } | |
| 344 | + set clipViewport(viewport) { | |
| 345 | + this._clipViewport = viewport; | |
| 346 | + this._updateClip(); | |
| 347 | + } | |
| 348 | + | |
| 349 | + get scaleViewport() { return this._scaleViewport; } | |
| 350 | + set scaleViewport(scale) { | |
| 351 | + this._scaleViewport = scale; | |
| 352 | + // Scaling trumps clipping, so we may need to adjust | |
| 353 | + // clipping when enabling or disabling scaling | |
| 354 | + if (scale && this._clipViewport) { | |
| 355 | + this._updateClip(); | |
| 356 | + } | |
| 357 | + this._updateScale(); | |
| 358 | + if (!scale && this._clipViewport) { | |
| 359 | + this._updateClip(); | |
| 360 | + } | |
| 361 | + } | |
| 362 | + | |
| 363 | + get resizeSession() { return this._resizeSession; } | |
| 364 | + set resizeSession(resize) { | |
| 365 | + this._resizeSession = resize; | |
| 366 | + if (resize) { | |
| 367 | + this._requestRemoteResize(); | |
| 368 | + } | |
| 369 | + } | |
| 370 | + | |
| 371 | + get showDotCursor() { return this._showDotCursor; } | |
| 372 | + set showDotCursor(show) { | |
| 373 | + this._showDotCursor = show; | |
| 374 | + this._refreshCursor(); | |
| 375 | + } | |
| 376 | + | |
| 377 | + get background() { return this._screen.style.background; } | |
| 378 | + set background(cssValue) { this._screen.style.background = cssValue; } | |
| 379 | + | |
| 380 | + get qualityLevel() { | |
| 381 | + return this._qualityLevel; | |
| 382 | + } | |
| 383 | + set qualityLevel(qualityLevel) { | |
| 384 | + if (!Number.isInteger(qualityLevel) || qualityLevel < 0 || qualityLevel > 9) { | |
| 385 | + Log.Error("qualityLevel must be an integer between 0 and 9"); | |
| 386 | + return; | |
| 387 | + } | |
| 388 | + | |
| 389 | + if (this._qualityLevel === qualityLevel) { | |
| 390 | + return; | |
| 391 | + } | |
| 392 | + | |
| 393 | + this._qualityLevel = qualityLevel; | |
| 394 | + | |
| 395 | + if (this._rfbConnectionState === 'connected') { | |
| 396 | + this._sendEncodings(); | |
| 397 | + } | |
| 398 | + } | |
| 399 | + | |
| 400 | + get compressionLevel() { | |
| 401 | + return this._compressionLevel; | |
| 402 | + } | |
| 403 | + set compressionLevel(compressionLevel) { | |
| 404 | + if (!Number.isInteger(compressionLevel) || compressionLevel < 0 || compressionLevel > 9) { | |
| 405 | + Log.Error("compressionLevel must be an integer between 0 and 9"); | |
| 406 | + return; | |
| 407 | + } | |
| 408 | + | |
| 409 | + if (this._compressionLevel === compressionLevel) { | |
| 410 | + return; | |
| 411 | + } | |
| 412 | + | |
| 413 | + this._compressionLevel = compressionLevel; | |
| 414 | + | |
| 415 | + if (this._rfbConnectionState === 'connected') { | |
| 416 | + this._sendEncodings(); | |
| 417 | + } | |
| 418 | + } | |
| 419 | + | |
| 420 | + // ===== PUBLIC METHODS ===== | |
| 421 | + | |
| 422 | + disconnect() { | |
| 423 | + this._updateConnectionState('disconnecting'); | |
| 424 | + this._sock.off('error'); | |
| 425 | + this._sock.off('message'); | |
| 426 | + this._sock.off('open'); | |
| 427 | + if (this._rfbRSAAESAuthenticationState !== null) { | |
| 428 | + this._rfbRSAAESAuthenticationState.disconnect(); | |
| 429 | + } | |
| 430 | + } | |
| 431 | + | |
| 432 | + approveServer() { | |
| 433 | + if (this._rfbRSAAESAuthenticationState !== null) { | |
| 434 | + this._rfbRSAAESAuthenticationState.approveServer(); | |
| 435 | + } | |
| 436 | + } | |
| 437 | + | |
| 438 | + sendCredentials(creds) { | |
| 439 | + this._rfbCredentials = creds; | |
| 440 | + this._resumeAuthentication(); | |
| 441 | + } | |
| 442 | + | |
| 443 | + sendCtrlAltDel() { | |
| 444 | + if (this._rfbConnectionState !== 'connected' || this._viewOnly) { return; } | |
| 445 | + Log.Info("Sending Ctrl-Alt-Del"); | |
| 446 | + | |
| 447 | + this.sendKey(KeyTable.XK_Control_L, "ControlLeft", true); | |
| 448 | + this.sendKey(KeyTable.XK_Alt_L, "AltLeft", true); | |
| 449 | + this.sendKey(KeyTable.XK_Delete, "Delete", true); | |
| 450 | + this.sendKey(KeyTable.XK_Delete, "Delete", false); | |
| 451 | + this.sendKey(KeyTable.XK_Alt_L, "AltLeft", false); | |
| 452 | + this.sendKey(KeyTable.XK_Control_L, "ControlLeft", false); | |
| 453 | + } | |
| 454 | + | |
| 455 | + machineShutdown() { | |
| 456 | + this._xvpOp(1, 2); | |
| 457 | + } | |
| 458 | + | |
| 459 | + machineReboot() { | |
| 460 | + this._xvpOp(1, 3); | |
| 461 | + } | |
| 462 | + | |
| 463 | + machineReset() { | |
| 464 | + this._xvpOp(1, 4); | |
| 465 | + } | |
| 466 | + | |
| 467 | + // Send a key press. If 'down' is not specified then send a down key | |
| 468 | + // followed by an up key. | |
| 469 | + sendKey(keysym, code, down) { | |
| 470 | + if (this._rfbConnectionState !== 'connected' || this._viewOnly) { return; } | |
| 471 | + | |
| 472 | + if (down === undefined) { | |
| 473 | + this.sendKey(keysym, code, true); | |
| 474 | + this.sendKey(keysym, code, false); | |
| 475 | + return; | |
| 476 | + } | |
| 477 | + | |
| 478 | + const scancode = XtScancode[code]; | |
| 479 | + | |
| 480 | + if (this._qemuExtKeyEventSupported && scancode) { | |
| 481 | + // 0 is NoSymbol | |
| 482 | + keysym = keysym || 0; | |
| 483 | + | |
| 484 | + Log.Info("Sending key (" + (down ? "down" : "up") + "): keysym " + keysym + ", scancode " + scancode); | |
| 485 | + | |
| 486 | + RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode); | |
| 487 | + } else { | |
| 488 | + if (!keysym) { | |
| 489 | + return; | |
| 490 | + } | |
| 491 | + Log.Info("Sending keysym (" + (down ? "down" : "up") + "): " + keysym); | |
| 492 | + RFB.messages.keyEvent(this._sock, keysym, down ? 1 : 0); | |
| 493 | + } | |
| 494 | + } | |
| 495 | + | |
| 496 | + focus(options) { | |
| 497 | + this._canvas.focus(options); | |
| 498 | + } | |
| 499 | + | |
| 500 | + blur() { | |
| 501 | + this._canvas.blur(); | |
| 502 | + } | |
| 503 | + | |
| 504 | + clipboardPasteFrom(text) { | |
| 505 | + if (this._rfbConnectionState !== 'connected' || this._viewOnly) { return; } | |
| 506 | + | |
| 507 | + if (this._clipboardServerCapabilitiesFormats[extendedClipboardFormatText] && | |
| 508 | + this._clipboardServerCapabilitiesActions[extendedClipboardActionNotify]) { | |
| 509 | + | |
| 510 | + this._clipboardText = text; | |
| 511 | + RFB.messages.extendedClipboardNotify(this._sock, [extendedClipboardFormatText]); | |
| 512 | + } else { | |
| 513 | + let length, i; | |
| 514 | + let data; | |
| 515 | + | |
| 516 | + length = 0; | |
| 517 | + // eslint-disable-next-line no-unused-vars | |
| 518 | + for (let codePoint of text) { | |
| 519 | + length++; | |
| 520 | + } | |
| 521 | + | |
| 522 | + data = new Uint8Array(length); | |
| 523 | + | |
| 524 | + i = 0; | |
| 525 | + for (let codePoint of text) { | |
| 526 | + let code = codePoint.codePointAt(0); | |
| 527 | + | |
| 528 | + /* Only ISO 8859-1 is supported */ | |
| 529 | + if (code > 0xff) { | |
| 530 | + code = 0x3f; // '?' | |
| 531 | + } | |
| 532 | + | |
| 533 | + data[i++] = code; | |
| 534 | + } | |
| 535 | + | |
| 536 | + RFB.messages.clientCutText(this._sock, data); | |
| 537 | + } | |
| 538 | + } | |
| 539 | + | |
| 540 | + getImageData() { | |
| 541 | + return this._display.getImageData(); | |
| 542 | + } | |
| 543 | + | |
| 544 | + toDataURL(type, encoderOptions) { | |
| 545 | + return this._display.toDataURL(type, encoderOptions); | |
| 546 | + } | |
| 547 | + | |
| 548 | + toBlob(callback, type, quality) { | |
| 549 | + return this._display.toBlob(callback, type, quality); | |
| 550 | + } | |
| 551 | + | |
| 552 | + // ===== PRIVATE METHODS ===== | |
| 553 | + | |
| 554 | + _connect() { | |
| 555 | + Log.Debug(">> RFB.connect"); | |
| 556 | + | |
| 557 | + if (this._url) { | |
| 558 | + Log.Info(`connecting to ${this._url}`); | |
| 559 | + this._sock.open(this._url, this._wsProtocols); | |
| 560 | + } else { | |
| 561 | + Log.Info(`attaching ${this._rawChannel} to Websock`); | |
| 562 | + this._sock.attach(this._rawChannel); | |
| 563 | + | |
| 564 | + if (this._sock.readyState === 'closed') { | |
| 565 | + throw Error("Cannot use already closed WebSocket/RTCDataChannel"); | |
| 566 | + } | |
| 567 | + | |
| 568 | + if (this._sock.readyState === 'open') { | |
| 569 | + // FIXME: _socketOpen() can in theory call _fail(), which | |
| 570 | + // isn't allowed this early, but I'm not sure that can | |
| 571 | + // happen without a bug messing up our state variables | |
| 572 | + this._socketOpen(); | |
| 573 | + } | |
| 574 | + } | |
| 575 | + | |
| 576 | + // Make our elements part of the page | |
| 577 | + this._target.appendChild(this._screen); | |
| 578 | + | |
| 579 | + this._gestures.attach(this._canvas); | |
| 580 | + | |
| 581 | + this._cursor.attach(this._canvas); | |
| 582 | + this._refreshCursor(); | |
| 583 | + | |
| 584 | + // Monitor size changes of the screen element | |
| 585 | + this._resizeObserver.observe(this._screen); | |
| 586 | + | |
| 587 | + // Always grab focus on some kind of click event | |
| 588 | + this._canvas.addEventListener("mousedown", this._eventHandlers.focusCanvas); | |
| 589 | + this._canvas.addEventListener("touchstart", this._eventHandlers.focusCanvas); | |
| 590 | + | |
| 591 | + // Mouse events | |
| 592 | + this._canvas.addEventListener('mousedown', this._eventHandlers.handleMouse); | |
| 593 | + this._canvas.addEventListener('mouseup', this._eventHandlers.handleMouse); | |
| 594 | + this._canvas.addEventListener('mousemove', this._eventHandlers.handleMouse); | |
| 595 | + // Prevent middle-click pasting (see handler for why we bind to document) | |
| 596 | + this._canvas.addEventListener('click', this._eventHandlers.handleMouse); | |
| 597 | + // preventDefault() on mousedown doesn't stop this event for some | |
| 598 | + // reason so we have to explicitly block it | |
| 599 | + this._canvas.addEventListener('contextmenu', this._eventHandlers.handleMouse); | |
| 600 | + | |
| 601 | + // Wheel events | |
| 602 | + this._canvas.addEventListener("wheel", this._eventHandlers.handleWheel); | |
| 603 | + | |
| 604 | + // Gesture events | |
| 605 | + this._canvas.addEventListener("gesturestart", this._eventHandlers.handleGesture); | |
| 606 | + this._canvas.addEventListener("gesturemove", this._eventHandlers.handleGesture); | |
| 607 | + this._canvas.addEventListener("gestureend", this._eventHandlers.handleGesture); | |
| 608 | + | |
| 609 | + Log.Debug("<< RFB.connect"); | |
| 610 | + } | |
| 611 | + | |
| 612 | + _disconnect() { | |
| 613 | + Log.Debug(">> RFB.disconnect"); | |
| 614 | + this._cursor.detach(); | |
| 615 | + this._canvas.removeEventListener("gesturestart", this._eventHandlers.handleGesture); | |
| 616 | + this._canvas.removeEventListener("gesturemove", this._eventHandlers.handleGesture); | |
| 617 | + this._canvas.removeEventListener("gestureend", this._eventHandlers.handleGesture); | |
| 618 | + this._canvas.removeEventListener("wheel", this._eventHandlers.handleWheel); | |
| 619 | + this._canvas.removeEventListener('mousedown', this._eventHandlers.handleMouse); | |
| 620 | + this._canvas.removeEventListener('mouseup', this._eventHandlers.handleMouse); | |
| 621 | + this._canvas.removeEventListener('mousemove', this._eventHandlers.handleMouse); | |
| 622 | + this._canvas.removeEventListener('click', this._eventHandlers.handleMouse); | |
| 623 | + this._canvas.removeEventListener('contextmenu', this._eventHandlers.handleMouse); | |
| 624 | + this._canvas.removeEventListener("mousedown", this._eventHandlers.focusCanvas); | |
| 625 | + this._canvas.removeEventListener("touchstart", this._eventHandlers.focusCanvas); | |
| 626 | + this._resizeObserver.disconnect(); | |
| 627 | + this._keyboard.ungrab(); | |
| 628 | + this._gestures.detach(); | |
| 629 | + this._sock.close(); | |
| 630 | + try { | |
| 631 | + this._target.removeChild(this._screen); | |
| 632 | + } catch (e) { | |
| 633 | + if (e.name === 'NotFoundError') { | |
| 634 | + // Some cases where the initial connection fails | |
| 635 | + // can disconnect before the _screen is created | |
| 636 | + } else { | |
| 637 | + throw e; | |
| 638 | + } | |
| 639 | + } | |
| 640 | + clearTimeout(this._resizeTimeout); | |
| 641 | + clearTimeout(this._mouseMoveTimer); | |
| 642 | + Log.Debug("<< RFB.disconnect"); | |
| 643 | + } | |
| 644 | + | |
| 645 | + _socketOpen() { | |
| 646 | + if ((this._rfbConnectionState === 'connecting') && | |
| 647 | + (this._rfbInitState === '')) { | |
| 648 | + this._rfbInitState = 'ProtocolVersion'; | |
| 649 | + Log.Debug("Starting VNC handshake"); | |
| 650 | + } else { | |
| 651 | + this._fail("Unexpected server connection while " + | |
| 652 | + this._rfbConnectionState); | |
| 653 | + } | |
| 654 | + } | |
| 655 | + | |
| 656 | + _socketClose(e) { | |
| 657 | + Log.Debug("WebSocket on-close event"); | |
| 658 | + let msg = ""; | |
| 659 | + if (e.code) { | |
| 660 | + msg = "(code: " + e.code; | |
| 661 | + if (e.reason) { | |
| 662 | + msg += ", reason: " + e.reason; | |
| 663 | + } | |
| 664 | + msg += ")"; | |
| 665 | + } | |
| 666 | + switch (this._rfbConnectionState) { | |
| 667 | + case 'connecting': | |
| 668 | + this._fail("Connection closed " + msg); | |
| 669 | + break; | |
| 670 | + case 'connected': | |
| 671 | + // Handle disconnects that were initiated server-side | |
| 672 | + this._updateConnectionState('disconnecting'); | |
| 673 | + this._updateConnectionState('disconnected'); | |
| 674 | + break; | |
| 675 | + case 'disconnecting': | |
| 676 | + // Normal disconnection path | |
| 677 | + this._updateConnectionState('disconnected'); | |
| 678 | + break; | |
| 679 | + case 'disconnected': | |
| 680 | + this._fail("Unexpected server disconnect " + | |
| 681 | + "when already disconnected " + msg); | |
| 682 | + break; | |
| 683 | + default: | |
| 684 | + this._fail("Unexpected server disconnect before connecting " + | |
| 685 | + msg); | |
| 686 | + break; | |
| 687 | + } | |
| 688 | + this._sock.off('close'); | |
| 689 | + // Delete reference to raw channel to allow cleanup. | |
| 690 | + this._rawChannel = null; | |
| 691 | + } | |
| 692 | + | |
| 693 | + _socketError(e) { | |
| 694 | + Log.Warn("WebSocket on-error event"); | |
| 695 | + } | |
| 696 | + | |
| 697 | + _focusCanvas(event) { | |
| 698 | + if (!this.focusOnClick) { | |
| 699 | + return; | |
| 700 | + } | |
| 701 | + | |
| 702 | + this.focus({ preventScroll: true }); | |
| 703 | + } | |
| 704 | + | |
| 705 | + _setDesktopName(name) { | |
| 706 | + this._fbName = name; | |
| 707 | + this.dispatchEvent(new CustomEvent( | |
| 708 | + "desktopname", | |
| 709 | + { detail: { name: this._fbName } })); | |
| 710 | + } | |
| 711 | + | |
| 712 | + _saveExpectedClientSize() { | |
| 713 | + this._expectedClientWidth = this._screen.clientWidth; | |
| 714 | + this._expectedClientHeight = this._screen.clientHeight; | |
| 715 | + } | |
| 716 | + | |
| 717 | + _currentClientSize() { | |
| 718 | + return [this._screen.clientWidth, this._screen.clientHeight]; | |
| 719 | + } | |
| 720 | + | |
| 721 | + _clientHasExpectedSize() { | |
| 722 | + const [currentWidth, currentHeight] = this._currentClientSize(); | |
| 723 | + return currentWidth == this._expectedClientWidth && | |
| 724 | + currentHeight == this._expectedClientHeight; | |
| 725 | + } | |
| 726 | + | |
| 727 | + // Handle browser window resizes | |
| 728 | + _handleResize() { | |
| 729 | + // Don't change anything if the client size is already as expected | |
| 730 | + if (this._clientHasExpectedSize()) { | |
| 731 | + return; | |
| 732 | + } | |
| 733 | + // If the window resized then our screen element might have | |
| 734 | + // as well. Update the viewport dimensions. | |
| 735 | + window.requestAnimationFrame(() => { | |
| 736 | + this._updateClip(); | |
| 737 | + this._updateScale(); | |
| 738 | + this._saveExpectedClientSize(); | |
| 739 | + }); | |
| 740 | + | |
| 741 | + // Request changing the resolution of the remote display to | |
| 742 | + // the size of the local browser viewport. | |
| 743 | + this._requestRemoteResize(); | |
| 744 | + } | |
| 745 | + | |
| 746 | + // Update state of clipping in Display object, and make sure the | |
| 747 | + // configured viewport matches the current screen size | |
| 748 | + _updateClip() { | |
| 749 | + const curClip = this._display.clipViewport; | |
| 750 | + let newClip = this._clipViewport; | |
| 751 | + | |
| 752 | + if (this._scaleViewport) { | |
| 753 | + // Disable viewport clipping if we are scaling | |
| 754 | + newClip = false; | |
| 755 | + } | |
| 756 | + | |
| 757 | + if (curClip !== newClip) { | |
| 758 | + this._display.clipViewport = newClip; | |
| 759 | + } | |
| 760 | + | |
| 761 | + if (newClip) { | |
| 762 | + // When clipping is enabled, the screen is limited to | |
| 763 | + // the size of the container. | |
| 764 | + const size = this._screenSize(); | |
| 765 | + this._display.viewportChangeSize(size.w, size.h); | |
| 766 | + this._fixScrollbars(); | |
| 767 | + this._setClippingViewport(size.w < this._display.width || | |
| 768 | + size.h < this._display.height); | |
| 769 | + } else { | |
| 770 | + this._setClippingViewport(false); | |
| 771 | + } | |
| 772 | + | |
| 773 | + // When changing clipping we might show or hide scrollbars. | |
| 774 | + // This causes the expected client dimensions to change. | |
| 775 | + if (curClip !== newClip) { | |
| 776 | + this._saveExpectedClientSize(); | |
| 777 | + } | |
| 778 | + } | |
| 779 | + | |
| 780 | + _updateScale() { | |
| 781 | + if (!this._scaleViewport) { | |
| 782 | + this._display.scale = 1.0; | |
| 783 | + } else { | |
| 784 | + const size = this._screenSize(); | |
| 785 | + this._display.autoscale(size.w, size.h); | |
| 786 | + } | |
| 787 | + this._fixScrollbars(); | |
| 788 | + } | |
| 789 | + | |
| 790 | + // Requests a change of remote desktop size. This message is an extension | |
| 791 | + // and may only be sent if we have received an ExtendedDesktopSize message | |
| 792 | + _requestRemoteResize() { | |
| 793 | + if (!this._resizeSession) { | |
| 794 | + return; | |
| 795 | + } | |
| 796 | + if (this._viewOnly) { | |
| 797 | + return; | |
| 798 | + } | |
| 799 | + if (!this._supportsSetDesktopSize) { | |
| 800 | + return; | |
| 801 | + } | |
| 802 | + | |
| 803 | + // Rate limit to one pending resize at a time | |
| 804 | + if (this._pendingRemoteResize) { | |
| 805 | + return; | |
| 806 | + } | |
| 807 | + | |
| 808 | + // And no more than once every 100ms | |
| 809 | + if ((Date.now() - this._lastResize) < 100) { | |
| 810 | + clearTimeout(this._resizeTimeout); | |
| 811 | + this._resizeTimeout = setTimeout(this._requestRemoteResize.bind(this), | |
| 812 | + 100 - (Date.now() - this._lastResize)); | |
| 813 | + return; | |
| 814 | + } | |
| 815 | + this._resizeTimeout = null; | |
| 816 | + | |
| 817 | + const size = this._screenSize(); | |
| 818 | + | |
| 819 | + // Do we actually change anything? | |
| 820 | + if (size.w === this._fbWidth && size.h === this._fbHeight) { | |
| 821 | + return; | |
| 822 | + } | |
| 823 | + | |
| 824 | + this._pendingRemoteResize = true; | |
| 825 | + this._lastResize = Date.now(); | |
| 826 | + RFB.messages.setDesktopSize(this._sock, | |
| 827 | + Math.floor(size.w), Math.floor(size.h), | |
| 828 | + this._screenID, this._screenFlags); | |
| 829 | + | |
| 830 | + Log.Debug('Requested new desktop size: ' + | |
| 831 | + size.w + 'x' + size.h); | |
| 832 | + } | |
| 833 | + | |
| 834 | + // Gets the the size of the available screen | |
| 835 | + _screenSize() { | |
| 836 | + let r = this._screen.getBoundingClientRect(); | |
| 837 | + return { w: r.width, h: r.height }; | |
| 838 | + } | |
| 839 | + | |
| 840 | + _fixScrollbars() { | |
| 841 | + // This is a hack because Safari on macOS screws up the calculation | |
| 842 | + // for when scrollbars are needed. We get scrollbars when making the | |
| 843 | + // browser smaller, despite remote resize being enabled. So to fix it | |
| 844 | + // we temporarily toggle them off and on. | |
| 845 | + const orig = this._screen.style.overflow; | |
| 846 | + this._screen.style.overflow = 'hidden'; | |
| 847 | + // Force Safari to recalculate the layout by asking for | |
| 848 | + // an element's dimensions | |
| 849 | + this._screen.getBoundingClientRect(); | |
| 850 | + this._screen.style.overflow = orig; | |
| 851 | + } | |
| 852 | + | |
| 853 | + /* | |
| 854 | + * Connection states: | |
| 855 | + * connecting | |
| 856 | + * connected | |
| 857 | + * disconnecting | |
| 858 | + * disconnected - permanent state | |
| 859 | + */ | |
| 860 | + _updateConnectionState(state) { | |
| 861 | + const oldstate = this._rfbConnectionState; | |
| 862 | + | |
| 863 | + if (state === oldstate) { | |
| 864 | + Log.Debug("Already in state '" + state + "', ignoring"); | |
| 865 | + return; | |
| 866 | + } | |
| 867 | + | |
| 868 | + // The 'disconnected' state is permanent for each RFB object | |
| 869 | + if (oldstate === 'disconnected') { | |
| 870 | + Log.Error("Tried changing state of a disconnected RFB object"); | |
| 871 | + return; | |
| 872 | + } | |
| 873 | + | |
| 874 | + // Ensure proper transitions before doing anything | |
| 875 | + switch (state) { | |
| 876 | + case 'connected': | |
| 877 | + if (oldstate !== 'connecting') { | |
| 878 | + Log.Error("Bad transition to connected state, " + | |
| 879 | + "previous connection state: " + oldstate); | |
| 880 | + return; | |
| 881 | + } | |
| 882 | + break; | |
| 883 | + | |
| 884 | + case 'disconnected': | |
| 885 | + if (oldstate !== 'disconnecting') { | |
| 886 | + Log.Error("Bad transition to disconnected state, " + | |
| 887 | + "previous connection state: " + oldstate); | |
| 888 | + return; | |
| 889 | + } | |
| 890 | + break; | |
| 891 | + | |
| 892 | + case 'connecting': | |
| 893 | + if (oldstate !== '') { | |
| 894 | + Log.Error("Bad transition to connecting state, " + | |
| 895 | + "previous connection state: " + oldstate); | |
| 896 | + return; | |
| 897 | + } | |
| 898 | + break; | |
| 899 | + | |
| 900 | + case 'disconnecting': | |
| 901 | + if (oldstate !== 'connected' && oldstate !== 'connecting') { | |
| 902 | + Log.Error("Bad transition to disconnecting state, " + | |
| 903 | + "previous connection state: " + oldstate); | |
| 904 | + return; | |
| 905 | + } | |
| 906 | + break; | |
| 907 | + | |
| 908 | + default: | |
| 909 | + Log.Error("Unknown connection state: " + state); | |
| 910 | + return; | |
| 911 | + } | |
| 912 | + | |
| 913 | + // State change actions | |
| 914 | + | |
| 915 | + this._rfbConnectionState = state; | |
| 916 | + | |
| 917 | + Log.Debug("New state '" + state + "', was '" + oldstate + "'."); | |
| 918 | + | |
| 919 | + if (this._disconnTimer && state !== 'disconnecting') { | |
| 920 | + Log.Debug("Clearing disconnect timer"); | |
| 921 | + clearTimeout(this._disconnTimer); | |
| 922 | + this._disconnTimer = null; | |
| 923 | + | |
| 924 | + // make sure we don't get a double event | |
| 925 | + this._sock.off('close'); | |
| 926 | + } | |
| 927 | + | |
| 928 | + switch (state) { | |
| 929 | + case 'connecting': | |
| 930 | + this._connect(); | |
| 931 | + break; | |
| 932 | + | |
| 933 | + case 'connected': | |
| 934 | + this.dispatchEvent(new CustomEvent("connect", { detail: {} })); | |
| 935 | + break; | |
| 936 | + | |
| 937 | + case 'disconnecting': | |
| 938 | + this._disconnect(); | |
| 939 | + | |
| 940 | + this._disconnTimer = setTimeout(() => { | |
| 941 | + Log.Error("Disconnection timed out."); | |
| 942 | + this._updateConnectionState('disconnected'); | |
| 943 | + }, DISCONNECT_TIMEOUT * 1000); | |
| 944 | + break; | |
| 945 | + | |
| 946 | + case 'disconnected': | |
| 947 | + this.dispatchEvent(new CustomEvent( | |
| 948 | + "disconnect", { detail: | |
| 949 | + { clean: this._rfbCleanDisconnect } })); | |
| 950 | + break; | |
| 951 | + } | |
| 952 | + } | |
| 953 | + | |
| 954 | + /* Print errors and disconnect | |
| 955 | + * | |
| 956 | + * The parameter 'details' is used for information that | |
| 957 | + * should be logged but not sent to the user interface. | |
| 958 | + */ | |
| 959 | + _fail(details) { | |
| 960 | + switch (this._rfbConnectionState) { | |
| 961 | + case 'disconnecting': | |
| 962 | + Log.Error("Failed when disconnecting: " + details); | |
| 963 | + break; | |
| 964 | + case 'connected': | |
| 965 | + Log.Error("Failed while connected: " + details); | |
| 966 | + break; | |
| 967 | + case 'connecting': | |
| 968 | + Log.Error("Failed when connecting: " + details); | |
| 969 | + break; | |
| 970 | + default: | |
| 971 | + Log.Error("RFB failure: " + details); | |
| 972 | + break; | |
| 973 | + } | |
| 974 | + this._rfbCleanDisconnect = false; //This is sent to the UI | |
| 975 | + | |
| 976 | + // Transition to disconnected without waiting for socket to close | |
| 977 | + this._updateConnectionState('disconnecting'); | |
| 978 | + this._updateConnectionState('disconnected'); | |
| 979 | + | |
| 980 | + return false; | |
| 981 | + } | |
| 982 | + | |
| 983 | + _setCapability(cap, val) { | |
| 984 | + this._capabilities[cap] = val; | |
| 985 | + this.dispatchEvent(new CustomEvent("capabilities", | |
| 986 | + { detail: { capabilities: this._capabilities } })); | |
| 987 | + } | |
| 988 | + | |
| 989 | + _handleMessage() { | |
| 990 | + if (this._sock.rQwait("message", 1)) { | |
| 991 | + Log.Warn("handleMessage called on an empty receive queue"); | |
| 992 | + return; | |
| 993 | + } | |
| 994 | + | |
| 995 | + switch (this._rfbConnectionState) { | |
| 996 | + case 'disconnected': | |
| 997 | + Log.Error("Got data while disconnected"); | |
| 998 | + break; | |
| 999 | + case 'connected': | |
| 1000 | + while (true) { | |
| 1001 | + if (this._flushing) { | |
| 1002 | + break; | |
| 1003 | + } | |
| 1004 | + if (!this._normalMsg()) { | |
| 1005 | + break; | |
| 1006 | + } | |
| 1007 | + if (this._sock.rQwait("message", 1)) { | |
| 1008 | + break; | |
| 1009 | + } | |
| 1010 | + } | |
| 1011 | + break; | |
| 1012 | + case 'connecting': | |
| 1013 | + while (this._rfbConnectionState === 'connecting') { | |
| 1014 | + if (!this._initMsg()) { | |
| 1015 | + break; | |
| 1016 | + } | |
| 1017 | + } | |
| 1018 | + break; | |
| 1019 | + default: | |
| 1020 | + Log.Error("Got data while in an invalid state"); | |
| 1021 | + break; | |
| 1022 | + } | |
| 1023 | + } | |
| 1024 | + | |
| 1025 | + _handleKeyEvent(keysym, code, down, numlock, capslock) { | |
| 1026 | + // If remote state of capslock is known, and it doesn't match the local led state of | |
| 1027 | + // the keyboard, we send a capslock keypress first to bring it into sync. | |
| 1028 | + // If we just pressed CapsLock, or we toggled it remotely due to it being out of sync | |
| 1029 | + // we clear the remote state so that we don't send duplicate or spurious fixes, | |
| 1030 | + // since it may take some time to receive the new remote CapsLock state. | |
| 1031 | + if (code == 'CapsLock' && down) { | |
| 1032 | + this._remoteCapsLock = null; | |
| 1033 | + } | |
| 1034 | + if (this._remoteCapsLock !== null && capslock !== null && this._remoteCapsLock !== capslock && down) { | |
| 1035 | + Log.Debug("Fixing remote caps lock"); | |
| 1036 | + | |
| 1037 | + this.sendKey(KeyTable.XK_Caps_Lock, 'CapsLock', true); | |
| 1038 | + this.sendKey(KeyTable.XK_Caps_Lock, 'CapsLock', false); | |
| 1039 | + // We clear the remote capsLock state when we do this to prevent issues with doing this twice | |
| 1040 | + // before we receive an update of the the remote state. | |
| 1041 | + this._remoteCapsLock = null; | |
| 1042 | + } | |
| 1043 | + | |
| 1044 | + // Logic for numlock is exactly the same. | |
| 1045 | + if (code == 'NumLock' && down) { | |
| 1046 | + this._remoteNumLock = null; | |
| 1047 | + } | |
| 1048 | + if (this._remoteNumLock !== null && numlock !== null && this._remoteNumLock !== numlock && down) { | |
| 1049 | + Log.Debug("Fixing remote num lock"); | |
| 1050 | + this.sendKey(KeyTable.XK_Num_Lock, 'NumLock', true); | |
| 1051 | + this.sendKey(KeyTable.XK_Num_Lock, 'NumLock', false); | |
| 1052 | + this._remoteNumLock = null; | |
| 1053 | + } | |
| 1054 | + this.sendKey(keysym, code, down); | |
| 1055 | + } | |
| 1056 | + | |
| 1057 | + static _convertButtonMask(buttons) { | |
| 1058 | + /* The bits in MouseEvent.buttons property correspond | |
| 1059 | + * to the following mouse buttons: | |
| 1060 | + * 0: Left | |
| 1061 | + * 1: Right | |
| 1062 | + * 2: Middle | |
| 1063 | + * 3: Back | |
| 1064 | + * 4: Forward | |
| 1065 | + * | |
| 1066 | + * These bits needs to be converted to what they are defined as | |
| 1067 | + * in the RFB protocol. | |
| 1068 | + */ | |
| 1069 | + | |
| 1070 | + const buttonMaskMap = { | |
| 1071 | + 0: 1 << 0, // Left | |
| 1072 | + 1: 1 << 2, // Right | |
| 1073 | + 2: 1 << 1, // Middle | |
| 1074 | + 3: 1 << 7, // Back | |
| 1075 | + 4: 1 << 8, // Forward | |
| 1076 | + }; | |
| 1077 | + | |
| 1078 | + let bmask = 0; | |
| 1079 | + for (let i = 0; i < 5; i++) { | |
| 1080 | + if (buttons & (1 << i)) { | |
| 1081 | + bmask |= buttonMaskMap[i]; | |
| 1082 | + } | |
| 1083 | + } | |
| 1084 | + return bmask; | |
| 1085 | + } | |
| 1086 | + | |
| 1087 | + _handleMouse(ev) { | |
| 1088 | + /* | |
| 1089 | + * We don't check connection status or viewOnly here as the | |
| 1090 | + * mouse events might be used to control the viewport | |
| 1091 | + */ | |
| 1092 | + | |
| 1093 | + if (ev.type === 'click') { | |
| 1094 | + /* | |
| 1095 | + * Note: This is only needed for the 'click' event as it fails | |
| 1096 | + * to fire properly for the target element so we have | |
| 1097 | + * to listen on the document element instead. | |
| 1098 | + */ | |
| 1099 | + if (ev.target !== this._canvas) { | |
| 1100 | + return; | |
| 1101 | + } | |
| 1102 | + } | |
| 1103 | + | |
| 1104 | + // FIXME: if we're in view-only and not dragging, | |
| 1105 | + // should we stop events? | |
| 1106 | + ev.stopPropagation(); | |
| 1107 | + ev.preventDefault(); | |
| 1108 | + | |
| 1109 | + if ((ev.type === 'click') || (ev.type === 'contextmenu')) { | |
| 1110 | + return; | |
| 1111 | + } | |
| 1112 | + | |
| 1113 | + let pos = clientToElement(ev.clientX, ev.clientY, | |
| 1114 | + this._canvas); | |
| 1115 | + | |
| 1116 | + let bmask = RFB._convertButtonMask(ev.buttons); | |
| 1117 | + | |
| 1118 | + let down = ev.type == 'mousedown'; | |
| 1119 | + switch (ev.type) { | |
| 1120 | + case 'mousedown': | |
| 1121 | + case 'mouseup': | |
| 1122 | + if (this.dragViewport) { | |
| 1123 | + if (down && !this._viewportDragging) { | |
| 1124 | + this._viewportDragging = true; | |
| 1125 | + this._viewportDragPos = {'x': pos.x, 'y': pos.y}; | |
| 1126 | + this._viewportHasMoved = false; | |
| 1127 | + | |
| 1128 | + this._flushMouseMoveTimer(pos.x, pos.y); | |
| 1129 | + | |
| 1130 | + // Skip sending mouse events, instead save the current | |
| 1131 | + // mouse mask so we can send it later. | |
| 1132 | + this._mouseButtonMask = bmask; | |
| 1133 | + break; | |
| 1134 | + } else { | |
| 1135 | + this._viewportDragging = false; | |
| 1136 | + | |
| 1137 | + // If we actually performed a drag then we are done | |
| 1138 | + // here and should not send any mouse events | |
| 1139 | + if (this._viewportHasMoved) { | |
| 1140 | + this._mouseButtonMask = bmask; | |
| 1141 | + break; | |
| 1142 | + } | |
| 1143 | + // Otherwise we treat this as a mouse click event. | |
| 1144 | + // Send the previously saved button mask, followed | |
| 1145 | + // by the current button mask at the end of this | |
| 1146 | + // function. | |
| 1147 | + this._sendMouse(pos.x, pos.y, this._mouseButtonMask); | |
| 1148 | + } | |
| 1149 | + } | |
| 1150 | + if (down) { | |
| 1151 | + setCapture(this._canvas); | |
| 1152 | + } | |
| 1153 | + this._handleMouseButton(pos.x, pos.y, bmask); | |
| 1154 | + break; | |
| 1155 | + case 'mousemove': | |
| 1156 | + if (this._viewportDragging) { | |
| 1157 | + const deltaX = this._viewportDragPos.x - pos.x; | |
| 1158 | + const deltaY = this._viewportDragPos.y - pos.y; | |
| 1159 | + | |
| 1160 | + if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold || | |
| 1161 | + Math.abs(deltaY) > dragThreshold)) { | |
| 1162 | + this._viewportHasMoved = true; | |
| 1163 | + | |
| 1164 | + this._viewportDragPos = {'x': pos.x, 'y': pos.y}; | |
| 1165 | + this._display.viewportChangePos(deltaX, deltaY); | |
| 1166 | + } | |
| 1167 | + | |
| 1168 | + // Skip sending mouse events | |
| 1169 | + break; | |
| 1170 | + } | |
| 1171 | + this._handleMouseMove(pos.x, pos.y); | |
| 1172 | + break; | |
| 1173 | + } | |
| 1174 | + } | |
| 1175 | + | |
| 1176 | + _handleMouseButton(x, y, bmask) { | |
| 1177 | + // Flush waiting move event first | |
| 1178 | + this._flushMouseMoveTimer(x, y); | |
| 1179 | + | |
| 1180 | + this._mouseButtonMask = bmask; | |
| 1181 | + this._sendMouse(x, y, this._mouseButtonMask); | |
| 1182 | + } | |
| 1183 | + | |
| 1184 | + _handleMouseMove(x, y) { | |
| 1185 | + this._mousePos = { 'x': x, 'y': y }; | |
| 1186 | + | |
| 1187 | + // Limit many mouse move events to one every MOUSE_MOVE_DELAY ms | |
| 1188 | + if (this._mouseMoveTimer == null) { | |
| 1189 | + | |
| 1190 | + const timeSinceLastMove = Date.now() - this._mouseLastMoveTime; | |
| 1191 | + if (timeSinceLastMove > MOUSE_MOVE_DELAY) { | |
| 1192 | + this._sendMouse(x, y, this._mouseButtonMask); | |
| 1193 | + this._mouseLastMoveTime = Date.now(); | |
| 1194 | + } else { | |
| 1195 | + // Too soon since the latest move, wait the remaining time | |
| 1196 | + this._mouseMoveTimer = setTimeout(() => { | |
| 1197 | + this._handleDelayedMouseMove(); | |
| 1198 | + }, MOUSE_MOVE_DELAY - timeSinceLastMove); | |
| 1199 | + } | |
| 1200 | + } | |
| 1201 | + } | |
| 1202 | + | |
| 1203 | + _handleDelayedMouseMove() { | |
| 1204 | + this._mouseMoveTimer = null; | |
| 1205 | + this._sendMouse(this._mousePos.x, this._mousePos.y, | |
| 1206 | + this._mouseButtonMask); | |
| 1207 | + this._mouseLastMoveTime = Date.now(); | |
| 1208 | + } | |
| 1209 | + | |
| 1210 | + _sendMouse(x, y, mask) { | |
| 1211 | + if (this._rfbConnectionState !== 'connected') { return; } | |
| 1212 | + if (this._viewOnly) { return; } // View only, skip mouse events | |
| 1213 | + | |
| 1214 | + // Highest bit in mask is never sent to the server | |
| 1215 | + if (mask & 0x8000) { | |
| 1216 | + throw new Error("Illegal mouse button mask (mask: " + mask + ")"); | |
| 1217 | + } | |
| 1218 | + | |
| 1219 | + let extendedMouseButtons = mask & 0x7f80; | |
| 1220 | + | |
| 1221 | + if (this._extendedPointerEventSupported && extendedMouseButtons) { | |
| 1222 | + RFB.messages.extendedPointerEvent(this._sock, this._display.absX(x), | |
| 1223 | + this._display.absY(y), mask); | |
| 1224 | + } else { | |
| 1225 | + RFB.messages.pointerEvent(this._sock, this._display.absX(x), | |
| 1226 | + this._display.absY(y), mask); | |
| 1227 | + } | |
| 1228 | + } | |
| 1229 | + | |
| 1230 | + _handleWheel(ev) { | |
| 1231 | + if (this._rfbConnectionState !== 'connected') { return; } | |
| 1232 | + if (this._viewOnly) { return; } // View only, skip mouse events | |
| 1233 | + | |
| 1234 | + ev.stopPropagation(); | |
| 1235 | + ev.preventDefault(); | |
| 1236 | + | |
| 1237 | + let pos = clientToElement(ev.clientX, ev.clientY, | |
| 1238 | + this._canvas); | |
| 1239 | + | |
| 1240 | + let bmask = RFB._convertButtonMask(ev.buttons); | |
| 1241 | + let dX = ev.deltaX; | |
| 1242 | + let dY = ev.deltaY; | |
| 1243 | + | |
| 1244 | + // Pixel units unless it's non-zero. | |
| 1245 | + // Note that if deltamode is line or page won't matter since we aren't | |
| 1246 | + // sending the mouse wheel delta to the server anyway. | |
| 1247 | + // The difference between pixel and line can be important however since | |
| 1248 | + // we have a threshold that can be smaller than the line height. | |
| 1249 | + if (ev.deltaMode !== 0) { | |
| 1250 | + dX *= WHEEL_LINE_HEIGHT; | |
| 1251 | + dY *= WHEEL_LINE_HEIGHT; | |
| 1252 | + } | |
| 1253 | + | |
| 1254 | + // Mouse wheel events are sent in steps over VNC. This means that the VNC | |
| 1255 | + // protocol can't handle a wheel event with specific distance or speed. | |
| 1256 | + // Therefor, if we get a lot of small mouse wheel events we combine them. | |
| 1257 | + this._accumulatedWheelDeltaX += dX; | |
| 1258 | + this._accumulatedWheelDeltaY += dY; | |
| 1259 | + | |
| 1260 | + | |
| 1261 | + // Generate a mouse wheel step event when the accumulated delta | |
| 1262 | + // for one of the axes is large enough. | |
| 1263 | + if (Math.abs(this._accumulatedWheelDeltaX) >= WHEEL_STEP) { | |
| 1264 | + if (this._accumulatedWheelDeltaX < 0) { | |
| 1265 | + this._handleMouseButton(pos.x, pos.y, bmask | 1 << 5); | |
| 1266 | + this._handleMouseButton(pos.x, pos.y, bmask); | |
| 1267 | + } else if (this._accumulatedWheelDeltaX > 0) { | |
| 1268 | + this._handleMouseButton(pos.x, pos.y, bmask | 1 << 6); | |
| 1269 | + this._handleMouseButton(pos.x, pos.y, bmask); | |
| 1270 | + } | |
| 1271 | + | |
| 1272 | + this._accumulatedWheelDeltaX = 0; | |
| 1273 | + } | |
| 1274 | + if (Math.abs(this._accumulatedWheelDeltaY) >= WHEEL_STEP) { | |
| 1275 | + if (this._accumulatedWheelDeltaY < 0) { | |
| 1276 | + this._handleMouseButton(pos.x, pos.y, bmask | 1 << 3); | |
| 1277 | + this._handleMouseButton(pos.x, pos.y, bmask); | |
| 1278 | + } else if (this._accumulatedWheelDeltaY > 0) { | |
| 1279 | + this._handleMouseButton(pos.x, pos.y, bmask | 1 << 4); | |
| 1280 | + this._handleMouseButton(pos.x, pos.y, bmask); | |
| 1281 | + } | |
| 1282 | + | |
| 1283 | + this._accumulatedWheelDeltaY = 0; | |
| 1284 | + } | |
| 1285 | + } | |
| 1286 | + | |
| 1287 | + _fakeMouseMove(ev, elementX, elementY) { | |
| 1288 | + this._handleMouseMove(elementX, elementY); | |
| 1289 | + this._cursor.move(ev.detail.clientX, ev.detail.clientY); | |
| 1290 | + } | |
| 1291 | + | |
| 1292 | + _handleTapEvent(ev, bmask) { | |
| 1293 | + let pos = clientToElement(ev.detail.clientX, ev.detail.clientY, | |
| 1294 | + this._canvas); | |
| 1295 | + | |
| 1296 | + // If the user quickly taps multiple times we assume they meant to | |
| 1297 | + // hit the same spot, so slightly adjust coordinates | |
| 1298 | + | |
| 1299 | + if ((this._gestureLastTapTime !== null) && | |
| 1300 | + ((Date.now() - this._gestureLastTapTime) < DOUBLE_TAP_TIMEOUT) && | |
| 1301 | + (this._gestureFirstDoubleTapEv.detail.type === ev.detail.type)) { | |
| 1302 | + let dx = this._gestureFirstDoubleTapEv.detail.clientX - ev.detail.clientX; | |
| 1303 | + let dy = this._gestureFirstDoubleTapEv.detail.clientY - ev.detail.clientY; | |
| 1304 | + let distance = Math.hypot(dx, dy); | |
| 1305 | + | |
| 1306 | + if (distance < DOUBLE_TAP_THRESHOLD) { | |
| 1307 | + pos = clientToElement(this._gestureFirstDoubleTapEv.detail.clientX, | |
| 1308 | + this._gestureFirstDoubleTapEv.detail.clientY, | |
| 1309 | + this._canvas); | |
| 1310 | + } else { | |
| 1311 | + this._gestureFirstDoubleTapEv = ev; | |
| 1312 | + } | |
| 1313 | + } else { | |
| 1314 | + this._gestureFirstDoubleTapEv = ev; | |
| 1315 | + } | |
| 1316 | + this._gestureLastTapTime = Date.now(); | |
| 1317 | + | |
| 1318 | + this._fakeMouseMove(this._gestureFirstDoubleTapEv, pos.x, pos.y); | |
| 1319 | + this._handleMouseButton(pos.x, pos.y, bmask); | |
| 1320 | + this._handleMouseButton(pos.x, pos.y, 0x0); | |
| 1321 | + } | |
| 1322 | + | |
| 1323 | + _handleGesture(ev) { | |
| 1324 | + let magnitude; | |
| 1325 | + | |
| 1326 | + let pos = clientToElement(ev.detail.clientX, ev.detail.clientY, | |
| 1327 | + this._canvas); | |
| 1328 | + switch (ev.type) { | |
| 1329 | + case 'gesturestart': | |
| 1330 | + switch (ev.detail.type) { | |
| 1331 | + case 'onetap': | |
| 1332 | + this._handleTapEvent(ev, 0x1); | |
| 1333 | + break; | |
| 1334 | + case 'twotap': | |
| 1335 | + this._handleTapEvent(ev, 0x4); | |
| 1336 | + break; | |
| 1337 | + case 'threetap': | |
| 1338 | + this._handleTapEvent(ev, 0x2); | |
| 1339 | + break; | |
| 1340 | + case 'drag': | |
| 1341 | + if (this.dragViewport) { | |
| 1342 | + this._viewportHasMoved = false; | |
| 1343 | + this._viewportDragging = true; | |
| 1344 | + this._viewportDragPos = {'x': pos.x, 'y': pos.y}; | |
| 1345 | + } else { | |
| 1346 | + this._fakeMouseMove(ev, pos.x, pos.y); | |
| 1347 | + this._handleMouseButton(pos.x, pos.y, 0x1); | |
| 1348 | + } | |
| 1349 | + break; | |
| 1350 | + case 'longpress': | |
| 1351 | + if (this.dragViewport) { | |
| 1352 | + // If dragViewport is true, we need to wait to see | |
| 1353 | + // if we have dragged outside the threshold before | |
| 1354 | + // sending any events to the server. | |
| 1355 | + this._viewportHasMoved = false; | |
| 1356 | + this._viewportDragPos = {'x': pos.x, 'y': pos.y}; | |
| 1357 | + } else { | |
| 1358 | + this._fakeMouseMove(ev, pos.x, pos.y); | |
| 1359 | + this._handleMouseButton(pos.x, pos.y, 0x4); | |
| 1360 | + } | |
| 1361 | + break; | |
| 1362 | + case 'twodrag': | |
| 1363 | + this._gestureLastMagnitudeX = ev.detail.magnitudeX; | |
| 1364 | + this._gestureLastMagnitudeY = ev.detail.magnitudeY; | |
| 1365 | + this._fakeMouseMove(ev, pos.x, pos.y); | |
| 1366 | + break; | |
| 1367 | + case 'pinch': | |
| 1368 | + this._gestureLastMagnitudeX = Math.hypot(ev.detail.magnitudeX, | |
| 1369 | + ev.detail.magnitudeY); | |
| 1370 | + this._fakeMouseMove(ev, pos.x, pos.y); | |
| 1371 | + break; | |
| 1372 | + } | |
| 1373 | + break; | |
| 1374 | + | |
| 1375 | + case 'gesturemove': | |
| 1376 | + switch (ev.detail.type) { | |
| 1377 | + case 'onetap': | |
| 1378 | + case 'twotap': | |
| 1379 | + case 'threetap': | |
| 1380 | + break; | |
| 1381 | + case 'drag': | |
| 1382 | + case 'longpress': | |
| 1383 | + if (this.dragViewport) { | |
| 1384 | + this._viewportDragging = true; | |
| 1385 | + const deltaX = this._viewportDragPos.x - pos.x; | |
| 1386 | + const deltaY = this._viewportDragPos.y - pos.y; | |
| 1387 | + | |
| 1388 | + if (this._viewportHasMoved || (Math.abs(deltaX) > dragThreshold || | |
| 1389 | + Math.abs(deltaY) > dragThreshold)) { | |
| 1390 | + this._viewportHasMoved = true; | |
| 1391 | + | |
| 1392 | + this._viewportDragPos = {'x': pos.x, 'y': pos.y}; | |
| 1393 | + this._display.viewportChangePos(deltaX, deltaY); | |
| 1394 | + } | |
| 1395 | + } else { | |
| 1396 | + this._fakeMouseMove(ev, pos.x, pos.y); | |
| 1397 | + } | |
| 1398 | + break; | |
| 1399 | + case 'twodrag': | |
| 1400 | + // Always scroll in the same position. | |
| 1401 | + // We don't know if the mouse was moved so we need to move it | |
| 1402 | + // every update. | |
| 1403 | + this._fakeMouseMove(ev, pos.x, pos.y); | |
| 1404 | + while ((ev.detail.magnitudeY - this._gestureLastMagnitudeY) > GESTURE_SCRLSENS) { | |
| 1405 | + this._handleMouseButton(pos.x, pos.y, 0x8); | |
| 1406 | + this._handleMouseButton(pos.x, pos.y, 0x0); | |
| 1407 | + this._gestureLastMagnitudeY += GESTURE_SCRLSENS; | |
| 1408 | + } | |
| 1409 | + while ((ev.detail.magnitudeY - this._gestureLastMagnitudeY) < -GESTURE_SCRLSENS) { | |
| 1410 | + this._handleMouseButton(pos.x, pos.y, 0x10); | |
| 1411 | + this._handleMouseButton(pos.x, pos.y, 0x0); | |
| 1412 | + this._gestureLastMagnitudeY -= GESTURE_SCRLSENS; | |
| 1413 | + } | |
| 1414 | + while ((ev.detail.magnitudeX - this._gestureLastMagnitudeX) > GESTURE_SCRLSENS) { | |
| 1415 | + this._handleMouseButton(pos.x, pos.y, 0x20); | |
| 1416 | + this._handleMouseButton(pos.x, pos.y, 0x0); | |
| 1417 | + this._gestureLastMagnitudeX += GESTURE_SCRLSENS; | |
| 1418 | + } | |
| 1419 | + while ((ev.detail.magnitudeX - this._gestureLastMagnitudeX) < -GESTURE_SCRLSENS) { | |
| 1420 | + this._handleMouseButton(pos.x, pos.y, 0x40); | |
| 1421 | + this._handleMouseButton(pos.x, pos.y, 0x0); | |
| 1422 | + this._gestureLastMagnitudeX -= GESTURE_SCRLSENS; | |
| 1423 | + } | |
| 1424 | + break; | |
| 1425 | + case 'pinch': | |
| 1426 | + // Always scroll in the same position. | |
| 1427 | + // We don't know if the mouse was moved so we need to move it | |
| 1428 | + // every update. | |
| 1429 | + this._fakeMouseMove(ev, pos.x, pos.y); | |
| 1430 | + magnitude = Math.hypot(ev.detail.magnitudeX, ev.detail.magnitudeY); | |
| 1431 | + if (Math.abs(magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) { | |
| 1432 | + this._handleKeyEvent(KeyTable.XK_Control_L, "ControlLeft", true); | |
| 1433 | + while ((magnitude - this._gestureLastMagnitudeX) > GESTURE_ZOOMSENS) { | |
| 1434 | + this._handleMouseButton(pos.x, pos.y, 0x8); | |
| 1435 | + this._handleMouseButton(pos.x, pos.y, 0x0); | |
| 1436 | + this._gestureLastMagnitudeX += GESTURE_ZOOMSENS; | |
| 1437 | + } | |
| 1438 | + while ((magnitude - this._gestureLastMagnitudeX) < -GESTURE_ZOOMSENS) { | |
| 1439 | + this._handleMouseButton(pos.x, pos.y, 0x10); | |
| 1440 | + this._handleMouseButton(pos.x, pos.y, 0x0); | |
| 1441 | + this._gestureLastMagnitudeX -= GESTURE_ZOOMSENS; | |
| 1442 | + } | |
| 1443 | + } | |
| 1444 | + this._handleKeyEvent(KeyTable.XK_Control_L, "ControlLeft", false); | |
| 1445 | + break; | |
| 1446 | + } | |
| 1447 | + break; | |
| 1448 | + | |
| 1449 | + case 'gestureend': | |
| 1450 | + switch (ev.detail.type) { | |
| 1451 | + case 'onetap': | |
| 1452 | + case 'twotap': | |
| 1453 | + case 'threetap': | |
| 1454 | + case 'pinch': | |
| 1455 | + case 'twodrag': | |
| 1456 | + break; | |
| 1457 | + case 'drag': | |
| 1458 | + if (this.dragViewport) { | |
| 1459 | + this._viewportDragging = false; | |
| 1460 | + } else { | |
| 1461 | + this._fakeMouseMove(ev, pos.x, pos.y); | |
| 1462 | + this._handleMouseButton(pos.x, pos.y, 0x0); | |
| 1463 | + } | |
| 1464 | + break; | |
| 1465 | + case 'longpress': | |
| 1466 | + if (this._viewportHasMoved) { | |
| 1467 | + // We don't want to send any events if we have moved | |
| 1468 | + // our viewport | |
| 1469 | + break; | |
| 1470 | + } | |
| 1471 | + | |
| 1472 | + if (this.dragViewport && !this._viewportHasMoved) { | |
| 1473 | + this._fakeMouseMove(ev, pos.x, pos.y); | |
| 1474 | + // If dragViewport is true, we need to wait to see | |
| 1475 | + // if we have dragged outside the threshold before | |
| 1476 | + // sending any events to the server. | |
| 1477 | + this._handleMouseButton(pos.x, pos.y, 0x4); | |
| 1478 | + this._handleMouseButton(pos.x, pos.y, 0x0); | |
| 1479 | + this._viewportDragging = false; | |
| 1480 | + } else { | |
| 1481 | + this._fakeMouseMove(ev, pos.x, pos.y); | |
| 1482 | + this._handleMouseButton(pos.x, pos.y, 0x0); | |
| 1483 | + } | |
| 1484 | + break; | |
| 1485 | + } | |
| 1486 | + break; | |
| 1487 | + } | |
| 1488 | + } | |
| 1489 | + | |
| 1490 | + _flushMouseMoveTimer(x, y) { | |
| 1491 | + if (this._mouseMoveTimer !== null) { | |
| 1492 | + clearTimeout(this._mouseMoveTimer); | |
| 1493 | + this._mouseMoveTimer = null; | |
| 1494 | + this._sendMouse(x, y, this._mouseButtonMask); | |
| 1495 | + } | |
| 1496 | + } | |
| 1497 | + | |
| 1498 | + // Message handlers | |
| 1499 | + | |
| 1500 | + _negotiateProtocolVersion() { | |
| 1501 | + if (this._sock.rQwait("version", 12)) { | |
| 1502 | + return false; | |
| 1503 | + } | |
| 1504 | + | |
| 1505 | + const sversion = this._sock.rQshiftStr(12).substr(4, 7); | |
| 1506 | + Log.Info("Server ProtocolVersion: " + sversion); | |
| 1507 | + let isRepeater = 0; | |
| 1508 | + switch (sversion) { | |
| 1509 | + case "000.000": // UltraVNC repeater | |
| 1510 | + isRepeater = 1; | |
| 1511 | + break; | |
| 1512 | + case "003.003": | |
| 1513 | + case "003.006": // UltraVNC | |
| 1514 | + this._rfbVersion = 3.3; | |
| 1515 | + break; | |
| 1516 | + case "003.007": | |
| 1517 | + this._rfbVersion = 3.7; | |
| 1518 | + break; | |
| 1519 | + case "003.008": | |
| 1520 | + case "003.889": // Apple Remote Desktop | |
| 1521 | + case "004.000": // Intel AMT KVM | |
| 1522 | + case "004.001": // RealVNC 4.6 | |
| 1523 | + case "005.000": // RealVNC 5.3 | |
| 1524 | + this._rfbVersion = 3.8; | |
| 1525 | + break; | |
| 1526 | + default: | |
| 1527 | + return this._fail("Invalid server version " + sversion); | |
| 1528 | + } | |
| 1529 | + | |
| 1530 | + if (isRepeater) { | |
| 1531 | + let repeaterID = "ID:" + this._repeaterID; | |
| 1532 | + while (repeaterID.length < 250) { | |
| 1533 | + repeaterID += "\0"; | |
| 1534 | + } | |
| 1535 | + this._sock.sQpushString(repeaterID); | |
| 1536 | + this._sock.flush(); | |
| 1537 | + return true; | |
| 1538 | + } | |
| 1539 | + | |
| 1540 | + if (this._rfbVersion > this._rfbMaxVersion) { | |
| 1541 | + this._rfbVersion = this._rfbMaxVersion; | |
| 1542 | + } | |
| 1543 | + | |
| 1544 | + const cversion = "00" + parseInt(this._rfbVersion, 10) + | |
| 1545 | + ".00" + ((this._rfbVersion * 10) % 10); | |
| 1546 | + this._sock.sQpushString("RFB " + cversion + "\n"); | |
| 1547 | + this._sock.flush(); | |
| 1548 | + Log.Debug('Sent ProtocolVersion: ' + cversion); | |
| 1549 | + | |
| 1550 | + this._rfbInitState = 'Security'; | |
| 1551 | + } | |
| 1552 | + | |
| 1553 | + _isSupportedSecurityType(type) { | |
| 1554 | + const clientTypes = [ | |
| 1555 | + securityTypeNone, | |
| 1556 | + securityTypeVNCAuth, | |
| 1557 | + securityTypeRA2ne, | |
| 1558 | + securityTypeTight, | |
| 1559 | + securityTypeVeNCrypt, | |
| 1560 | + securityTypeXVP, | |
| 1561 | + securityTypeARD, | |
| 1562 | + securityTypeMSLogonII, | |
| 1563 | + securityTypePlain, | |
| 1564 | + ]; | |
| 1565 | + | |
| 1566 | + return clientTypes.includes(type); | |
| 1567 | + } | |
| 1568 | + | |
| 1569 | + _negotiateSecurity() { | |
| 1570 | + if (this._rfbVersion >= 3.7) { | |
| 1571 | + // Server sends supported list, client decides | |
| 1572 | + const numTypes = this._sock.rQshift8(); | |
| 1573 | + if (this._sock.rQwait("security type", numTypes, 1)) { return false; } | |
| 1574 | + | |
| 1575 | + if (numTypes === 0) { | |
| 1576 | + this._rfbInitState = "SecurityReason"; | |
| 1577 | + this._securityContext = "no security types"; | |
| 1578 | + this._securityStatus = 1; | |
| 1579 | + return true; | |
| 1580 | + } | |
| 1581 | + | |
| 1582 | + const types = this._sock.rQshiftBytes(numTypes); | |
| 1583 | + Log.Debug("Server security types: " + types); | |
| 1584 | + | |
| 1585 | + // Look for a matching security type in the order that the | |
| 1586 | + // server prefers | |
| 1587 | + this._rfbAuthScheme = -1; | |
| 1588 | + for (let type of types) { | |
| 1589 | + if (this._isSupportedSecurityType(type)) { | |
| 1590 | + this._rfbAuthScheme = type; | |
| 1591 | + break; | |
| 1592 | + } | |
| 1593 | + } | |
| 1594 | + | |
| 1595 | + if (this._rfbAuthScheme === -1) { | |
| 1596 | + return this._fail("Unsupported security types (types: " + types + ")"); | |
| 1597 | + } | |
| 1598 | + | |
| 1599 | + this._sock.sQpush8(this._rfbAuthScheme); | |
| 1600 | + this._sock.flush(); | |
| 1601 | + } else { | |
| 1602 | + // Server decides | |
| 1603 | + if (this._sock.rQwait("security scheme", 4)) { return false; } | |
| 1604 | + this._rfbAuthScheme = this._sock.rQshift32(); | |
| 1605 | + | |
| 1606 | + if (this._rfbAuthScheme == 0) { | |
| 1607 | + this._rfbInitState = "SecurityReason"; | |
| 1608 | + this._securityContext = "authentication scheme"; | |
| 1609 | + this._securityStatus = 1; | |
| 1610 | + return true; | |
| 1611 | + } | |
| 1612 | + } | |
| 1613 | + | |
| 1614 | + this._rfbInitState = 'Authentication'; | |
| 1615 | + Log.Debug('Authenticating using scheme: ' + this._rfbAuthScheme); | |
| 1616 | + | |
| 1617 | + return true; | |
| 1618 | + } | |
| 1619 | + | |
| 1620 | + _handleSecurityReason() { | |
| 1621 | + if (this._sock.rQwait("reason length", 4)) { | |
| 1622 | + return false; | |
| 1623 | + } | |
| 1624 | + const strlen = this._sock.rQshift32(); | |
| 1625 | + let reason = ""; | |
| 1626 | + | |
| 1627 | + if (strlen > 0) { | |
| 1628 | + if (this._sock.rQwait("reason", strlen, 4)) { return false; } | |
| 1629 | + reason = this._sock.rQshiftStr(strlen); | |
| 1630 | + } | |
| 1631 | + | |
| 1632 | + if (reason !== "") { | |
| 1633 | + this.dispatchEvent(new CustomEvent( | |
| 1634 | + "securityfailure", | |
| 1635 | + { detail: { status: this._securityStatus, | |
| 1636 | + reason: reason } })); | |
| 1637 | + | |
| 1638 | + return this._fail("Security negotiation failed on " + | |
| 1639 | + this._securityContext + | |
| 1640 | + " (reason: " + reason + ")"); | |
| 1641 | + } else { | |
| 1642 | + this.dispatchEvent(new CustomEvent( | |
| 1643 | + "securityfailure", | |
| 1644 | + { detail: { status: this._securityStatus } })); | |
| 1645 | + | |
| 1646 | + return this._fail("Security negotiation failed on " + | |
| 1647 | + this._securityContext); | |
| 1648 | + } | |
| 1649 | + } | |
| 1650 | + | |
| 1651 | + // authentication | |
| 1652 | + _negotiateXvpAuth() { | |
| 1653 | + if (this._rfbCredentials.username === undefined || | |
| 1654 | + this._rfbCredentials.password === undefined || | |
| 1655 | + this._rfbCredentials.target === undefined) { | |
| 1656 | + this.dispatchEvent(new CustomEvent( | |
| 1657 | + "credentialsrequired", | |
| 1658 | + { detail: { types: ["username", "password", "target"] } })); | |
| 1659 | + return false; | |
| 1660 | + } | |
| 1661 | + | |
| 1662 | + this._sock.sQpush8(this._rfbCredentials.username.length); | |
| 1663 | + this._sock.sQpush8(this._rfbCredentials.target.length); | |
| 1664 | + this._sock.sQpushString(this._rfbCredentials.username); | |
| 1665 | + this._sock.sQpushString(this._rfbCredentials.target); | |
| 1666 | + | |
| 1667 | + this._sock.flush(); | |
| 1668 | + | |
| 1669 | + this._rfbAuthScheme = securityTypeVNCAuth; | |
| 1670 | + | |
| 1671 | + return this._negotiateAuthentication(); | |
| 1672 | + } | |
| 1673 | + | |
| 1674 | + // VeNCrypt authentication, currently only supports version 0.2 and only Plain subtype | |
| 1675 | + _negotiateVeNCryptAuth() { | |
| 1676 | + | |
| 1677 | + // waiting for VeNCrypt version | |
| 1678 | + if (this._rfbVeNCryptState == 0) { | |
| 1679 | + if (this._sock.rQwait("vencrypt version", 2)) { return false; } | |
| 1680 | + | |
| 1681 | + const major = this._sock.rQshift8(); | |
| 1682 | + const minor = this._sock.rQshift8(); | |
| 1683 | + | |
| 1684 | + if (!(major == 0 && minor == 2)) { | |
| 1685 | + return this._fail("Unsupported VeNCrypt version " + major + "." + minor); | |
| 1686 | + } | |
| 1687 | + | |
| 1688 | + this._sock.sQpush8(0); | |
| 1689 | + this._sock.sQpush8(2); | |
| 1690 | + this._sock.flush(); | |
| 1691 | + this._rfbVeNCryptState = 1; | |
| 1692 | + } | |
| 1693 | + | |
| 1694 | + // waiting for ACK | |
| 1695 | + if (this._rfbVeNCryptState == 1) { | |
| 1696 | + if (this._sock.rQwait("vencrypt ack", 1)) { return false; } | |
| 1697 | + | |
| 1698 | + const res = this._sock.rQshift8(); | |
| 1699 | + | |
| 1700 | + if (res != 0) { | |
| 1701 | + return this._fail("VeNCrypt failure " + res); | |
| 1702 | + } | |
| 1703 | + | |
| 1704 | + this._rfbVeNCryptState = 2; | |
| 1705 | + } | |
| 1706 | + // must fall through here (i.e. no "else if"), beacause we may have already received | |
| 1707 | + // the subtypes length and won't be called again | |
| 1708 | + | |
| 1709 | + if (this._rfbVeNCryptState == 2) { // waiting for subtypes length | |
| 1710 | + if (this._sock.rQwait("vencrypt subtypes length", 1)) { return false; } | |
| 1711 | + | |
| 1712 | + const subtypesLength = this._sock.rQshift8(); | |
| 1713 | + if (subtypesLength < 1) { | |
| 1714 | + return this._fail("VeNCrypt subtypes empty"); | |
| 1715 | + } | |
| 1716 | + | |
| 1717 | + this._rfbVeNCryptSubtypesLength = subtypesLength; | |
| 1718 | + this._rfbVeNCryptState = 3; | |
| 1719 | + } | |
| 1720 | + | |
| 1721 | + // waiting for subtypes list | |
| 1722 | + if (this._rfbVeNCryptState == 3) { | |
| 1723 | + if (this._sock.rQwait("vencrypt subtypes", 4 * this._rfbVeNCryptSubtypesLength)) { return false; } | |
| 1724 | + | |
| 1725 | + const subtypes = []; | |
| 1726 | + for (let i = 0; i < this._rfbVeNCryptSubtypesLength; i++) { | |
| 1727 | + subtypes.push(this._sock.rQshift32()); | |
| 1728 | + } | |
| 1729 | + | |
| 1730 | + // Look for a matching security type in the order that the | |
| 1731 | + // server prefers | |
| 1732 | + this._rfbAuthScheme = -1; | |
| 1733 | + for (let type of subtypes) { | |
| 1734 | + // Avoid getting in to a loop | |
| 1735 | + if (type === securityTypeVeNCrypt) { | |
| 1736 | + continue; | |
| 1737 | + } | |
| 1738 | + | |
| 1739 | + if (this._isSupportedSecurityType(type)) { | |
| 1740 | + this._rfbAuthScheme = type; | |
| 1741 | + break; | |
| 1742 | + } | |
| 1743 | + } | |
| 1744 | + | |
| 1745 | + if (this._rfbAuthScheme === -1) { | |
| 1746 | + return this._fail("Unsupported security types (types: " + subtypes + ")"); | |
| 1747 | + } | |
| 1748 | + | |
| 1749 | + this._sock.sQpush32(this._rfbAuthScheme); | |
| 1750 | + this._sock.flush(); | |
| 1751 | + | |
| 1752 | + this._rfbVeNCryptState = 4; | |
| 1753 | + return true; | |
| 1754 | + } | |
| 1755 | + } | |
| 1756 | + | |
| 1757 | + _negotiatePlainAuth() { | |
| 1758 | + if (this._rfbCredentials.username === undefined || | |
| 1759 | + this._rfbCredentials.password === undefined) { | |
| 1760 | + this.dispatchEvent(new CustomEvent( | |
| 1761 | + "credentialsrequired", | |
| 1762 | + { detail: { types: ["username", "password"] } })); | |
| 1763 | + return false; | |
| 1764 | + } | |
| 1765 | + | |
| 1766 | + const user = encodeUTF8(this._rfbCredentials.username); | |
| 1767 | + const pass = encodeUTF8(this._rfbCredentials.password); | |
| 1768 | + | |
| 1769 | + this._sock.sQpush32(user.length); | |
| 1770 | + this._sock.sQpush32(pass.length); | |
| 1771 | + this._sock.sQpushString(user); | |
| 1772 | + this._sock.sQpushString(pass); | |
| 1773 | + this._sock.flush(); | |
| 1774 | + | |
| 1775 | + this._rfbInitState = "SecurityResult"; | |
| 1776 | + return true; | |
| 1777 | + } | |
| 1778 | + | |
| 1779 | + _negotiateStdVNCAuth() { | |
| 1780 | + if (this._sock.rQwait("auth challenge", 16)) { return false; } | |
| 1781 | + | |
| 1782 | + if (this._rfbCredentials.password === undefined) { | |
| 1783 | + this.dispatchEvent(new CustomEvent( | |
| 1784 | + "credentialsrequired", | |
| 1785 | + { detail: { types: ["password"] } })); | |
| 1786 | + return false; | |
| 1787 | + } | |
| 1788 | + | |
| 1789 | + // TODO(directxman12): make genDES not require an Array | |
| 1790 | + const challenge = Array.prototype.slice.call(this._sock.rQshiftBytes(16)); | |
| 1791 | + const response = RFB.genDES(this._rfbCredentials.password, challenge); | |
| 1792 | + this._sock.sQpushBytes(response); | |
| 1793 | + this._sock.flush(); | |
| 1794 | + this._rfbInitState = "SecurityResult"; | |
| 1795 | + return true; | |
| 1796 | + } | |
| 1797 | + | |
| 1798 | + _negotiateARDAuth() { | |
| 1799 | + | |
| 1800 | + if (this._rfbCredentials.username === undefined || | |
| 1801 | + this._rfbCredentials.password === undefined) { | |
| 1802 | + this.dispatchEvent(new CustomEvent( | |
| 1803 | + "credentialsrequired", | |
| 1804 | + { detail: { types: ["username", "password"] } })); | |
| 1805 | + return false; | |
| 1806 | + } | |
| 1807 | + | |
| 1808 | + if (this._rfbCredentials.ardPublicKey != undefined && | |
| 1809 | + this._rfbCredentials.ardCredentials != undefined) { | |
| 1810 | + // if the async web crypto is done return the results | |
| 1811 | + this._sock.sQpushBytes(this._rfbCredentials.ardCredentials); | |
| 1812 | + this._sock.sQpushBytes(this._rfbCredentials.ardPublicKey); | |
| 1813 | + this._sock.flush(); | |
| 1814 | + this._rfbCredentials.ardCredentials = null; | |
| 1815 | + this._rfbCredentials.ardPublicKey = null; | |
| 1816 | + this._rfbInitState = "SecurityResult"; | |
| 1817 | + return true; | |
| 1818 | + } | |
| 1819 | + | |
| 1820 | + if (this._sock.rQwait("read ard", 4)) { return false; } | |
| 1821 | + | |
| 1822 | + let generator = this._sock.rQshiftBytes(2); // DH base generator value | |
| 1823 | + | |
| 1824 | + let keyLength = this._sock.rQshift16(); | |
| 1825 | + | |
| 1826 | + if (this._sock.rQwait("read ard keylength", keyLength*2, 4)) { return false; } | |
| 1827 | + | |
| 1828 | + // read the server values | |
| 1829 | + let prime = this._sock.rQshiftBytes(keyLength); // predetermined prime modulus | |
| 1830 | + let serverPublicKey = this._sock.rQshiftBytes(keyLength); // other party's public key | |
| 1831 | + | |
| 1832 | + let clientKey = legacyCrypto.generateKey( | |
| 1833 | + { name: "DH", g: generator, p: prime }, false, ["deriveBits"]); | |
| 1834 | + this._negotiateARDAuthAsync(keyLength, serverPublicKey, clientKey); | |
| 1835 | + | |
| 1836 | + return false; | |
| 1837 | + } | |
| 1838 | + | |
| 1839 | + async _negotiateARDAuthAsync(keyLength, serverPublicKey, clientKey) { | |
| 1840 | + const clientPublicKey = legacyCrypto.exportKey("raw", clientKey.publicKey); | |
| 1841 | + const sharedKey = legacyCrypto.deriveBits( | |
| 1842 | + { name: "DH", public: serverPublicKey }, clientKey.privateKey, keyLength * 8); | |
| 1843 | + | |
| 1844 | + const username = encodeUTF8(this._rfbCredentials.username).substring(0, 63); | |
| 1845 | + const password = encodeUTF8(this._rfbCredentials.password).substring(0, 63); | |
| 1846 | + | |
| 1847 | + const credentials = window.crypto.getRandomValues(new Uint8Array(128)); | |
| 1848 | + for (let i = 0; i < username.length; i++) { | |
| 1849 | + credentials[i] = username.charCodeAt(i); | |
| 1850 | + } | |
| 1851 | + credentials[username.length] = 0; | |
| 1852 | + for (let i = 0; i < password.length; i++) { | |
| 1853 | + credentials[64 + i] = password.charCodeAt(i); | |
| 1854 | + } | |
| 1855 | + credentials[64 + password.length] = 0; | |
| 1856 | + | |
| 1857 | + const key = await legacyCrypto.digest("MD5", sharedKey); | |
| 1858 | + const cipher = await legacyCrypto.importKey( | |
| 1859 | + "raw", key, { name: "AES-ECB" }, false, ["encrypt"]); | |
| 1860 | + const encrypted = await legacyCrypto.encrypt({ name: "AES-ECB" }, cipher, credentials); | |
| 1861 | + | |
| 1862 | + this._rfbCredentials.ardCredentials = encrypted; | |
| 1863 | + this._rfbCredentials.ardPublicKey = clientPublicKey; | |
| 1864 | + | |
| 1865 | + this._resumeAuthentication(); | |
| 1866 | + } | |
| 1867 | + | |
| 1868 | + _negotiateTightUnixAuth() { | |
| 1869 | + if (this._rfbCredentials.username === undefined || | |
| 1870 | + this._rfbCredentials.password === undefined) { | |
| 1871 | + this.dispatchEvent(new CustomEvent( | |
| 1872 | + "credentialsrequired", | |
| 1873 | + { detail: { types: ["username", "password"] } })); | |
| 1874 | + return false; | |
| 1875 | + } | |
| 1876 | + | |
| 1877 | + this._sock.sQpush32(this._rfbCredentials.username.length); | |
| 1878 | + this._sock.sQpush32(this._rfbCredentials.password.length); | |
| 1879 | + this._sock.sQpushString(this._rfbCredentials.username); | |
| 1880 | + this._sock.sQpushString(this._rfbCredentials.password); | |
| 1881 | + this._sock.flush(); | |
| 1882 | + | |
| 1883 | + this._rfbInitState = "SecurityResult"; | |
| 1884 | + return true; | |
| 1885 | + } | |
| 1886 | + | |
| 1887 | + _negotiateTightTunnels(numTunnels) { | |
| 1888 | + const clientSupportedTunnelTypes = { | |
| 1889 | + 0: { vendor: 'TGHT', signature: 'NOTUNNEL' } | |
| 1890 | + }; | |
| 1891 | + const serverSupportedTunnelTypes = {}; | |
| 1892 | + // receive tunnel capabilities | |
| 1893 | + for (let i = 0; i < numTunnels; i++) { | |
| 1894 | + const capCode = this._sock.rQshift32(); | |
| 1895 | + const capVendor = this._sock.rQshiftStr(4); | |
| 1896 | + const capSignature = this._sock.rQshiftStr(8); | |
| 1897 | + serverSupportedTunnelTypes[capCode] = { vendor: capVendor, signature: capSignature }; | |
| 1898 | + } | |
| 1899 | + | |
| 1900 | + Log.Debug("Server Tight tunnel types: " + serverSupportedTunnelTypes); | |
| 1901 | + | |
| 1902 | + // Siemens touch panels have a VNC server that supports NOTUNNEL, | |
| 1903 | + // but forgets to advertise it. Try to detect such servers by | |
| 1904 | + // looking for their custom tunnel type. | |
| 1905 | + if (serverSupportedTunnelTypes[1] && | |
| 1906 | + (serverSupportedTunnelTypes[1].vendor === "SICR") && | |
| 1907 | + (serverSupportedTunnelTypes[1].signature === "SCHANNEL")) { | |
| 1908 | + Log.Debug("Detected Siemens server. Assuming NOTUNNEL support."); | |
| 1909 | + serverSupportedTunnelTypes[0] = { vendor: 'TGHT', signature: 'NOTUNNEL' }; | |
| 1910 | + } | |
| 1911 | + | |
| 1912 | + // choose the notunnel type | |
| 1913 | + if (serverSupportedTunnelTypes[0]) { | |
| 1914 | + if (serverSupportedTunnelTypes[0].vendor != clientSupportedTunnelTypes[0].vendor || | |
| 1915 | + serverSupportedTunnelTypes[0].signature != clientSupportedTunnelTypes[0].signature) { | |
| 1916 | + return this._fail("Client's tunnel type had the incorrect " + | |
| 1917 | + "vendor or signature"); | |
| 1918 | + } | |
| 1919 | + Log.Debug("Selected tunnel type: " + clientSupportedTunnelTypes[0]); | |
| 1920 | + this._sock.sQpush32(0); // use NOTUNNEL | |
| 1921 | + this._sock.flush(); | |
| 1922 | + return false; // wait until we receive the sub auth count to continue | |
| 1923 | + } else { | |
| 1924 | + return this._fail("Server wanted tunnels, but doesn't support " + | |
| 1925 | + "the notunnel type"); | |
| 1926 | + } | |
| 1927 | + } | |
| 1928 | + | |
| 1929 | + _negotiateTightAuth() { | |
| 1930 | + if (!this._rfbTightVNC) { // first pass, do the tunnel negotiation | |
| 1931 | + if (this._sock.rQwait("num tunnels", 4)) { return false; } | |
| 1932 | + const numTunnels = this._sock.rQshift32(); | |
| 1933 | + if (numTunnels > 0 && this._sock.rQwait("tunnel capabilities", 16 * numTunnels, 4)) { return false; } | |
| 1934 | + | |
| 1935 | + this._rfbTightVNC = true; | |
| 1936 | + | |
| 1937 | + if (numTunnels > 0) { | |
| 1938 | + this._negotiateTightTunnels(numTunnels); | |
| 1939 | + return false; // wait until we receive the sub auth to continue | |
| 1940 | + } | |
| 1941 | + } | |
| 1942 | + | |
| 1943 | + // second pass, do the sub-auth negotiation | |
| 1944 | + if (this._sock.rQwait("sub auth count", 4)) { return false; } | |
| 1945 | + const subAuthCount = this._sock.rQshift32(); | |
| 1946 | + if (subAuthCount === 0) { // empty sub-auth list received means 'no auth' subtype selected | |
| 1947 | + this._rfbInitState = 'SecurityResult'; | |
| 1948 | + return true; | |
| 1949 | + } | |
| 1950 | + | |
| 1951 | + if (this._sock.rQwait("sub auth capabilities", 16 * subAuthCount, 4)) { return false; } | |
| 1952 | + | |
| 1953 | + const clientSupportedTypes = { | |
| 1954 | + 'STDVNOAUTH__': 1, | |
| 1955 | + 'STDVVNCAUTH_': 2, | |
| 1956 | + 'TGHTULGNAUTH': 129 | |
| 1957 | + }; | |
| 1958 | + | |
| 1959 | + const serverSupportedTypes = []; | |
| 1960 | + | |
| 1961 | + for (let i = 0; i < subAuthCount; i++) { | |
| 1962 | + this._sock.rQshift32(); // capNum | |
| 1963 | + const capabilities = this._sock.rQshiftStr(12); | |
| 1964 | + serverSupportedTypes.push(capabilities); | |
| 1965 | + } | |
| 1966 | + | |
| 1967 | + Log.Debug("Server Tight authentication types: " + serverSupportedTypes); | |
| 1968 | + | |
| 1969 | + for (let authType in clientSupportedTypes) { | |
| 1970 | + if (serverSupportedTypes.indexOf(authType) != -1) { | |
| 1971 | + this._sock.sQpush32(clientSupportedTypes[authType]); | |
| 1972 | + this._sock.flush(); | |
| 1973 | + Log.Debug("Selected authentication type: " + authType); | |
| 1974 | + | |
| 1975 | + switch (authType) { | |
| 1976 | + case 'STDVNOAUTH__': // no auth | |
| 1977 | + this._rfbInitState = 'SecurityResult'; | |
| 1978 | + return true; | |
| 1979 | + case 'STDVVNCAUTH_': | |
| 1980 | + this._rfbAuthScheme = securityTypeVNCAuth; | |
| 1981 | + return true; | |
| 1982 | + case 'TGHTULGNAUTH': | |
| 1983 | + this._rfbAuthScheme = securityTypeUnixLogon; | |
| 1984 | + return true; | |
| 1985 | + default: | |
| 1986 | + return this._fail("Unsupported tiny auth scheme " + | |
| 1987 | + "(scheme: " + authType + ")"); | |
| 1988 | + } | |
| 1989 | + } | |
| 1990 | + } | |
| 1991 | + | |
| 1992 | + return this._fail("No supported sub-auth types!"); | |
| 1993 | + } | |
| 1994 | + | |
| 1995 | + _handleRSAAESCredentialsRequired(event) { | |
| 1996 | + this.dispatchEvent(event); | |
| 1997 | + } | |
| 1998 | + | |
| 1999 | + _handleRSAAESServerVerification(event) { | |
| 2000 | + this.dispatchEvent(event); | |
| 2001 | + } | |
| 2002 | + | |
| 2003 | + _negotiateRA2neAuth() { | |
| 2004 | + if (this._rfbRSAAESAuthenticationState === null) { | |
| 2005 | + this._rfbRSAAESAuthenticationState = new RSAAESAuthenticationState(this._sock, () => this._rfbCredentials); | |
| 2006 | + this._rfbRSAAESAuthenticationState.addEventListener( | |
| 2007 | + "serververification", this._eventHandlers.handleRSAAESServerVerification); | |
| 2008 | + this._rfbRSAAESAuthenticationState.addEventListener( | |
| 2009 | + "credentialsrequired", this._eventHandlers.handleRSAAESCredentialsRequired); | |
| 2010 | + } | |
| 2011 | + this._rfbRSAAESAuthenticationState.checkInternalEvents(); | |
| 2012 | + if (!this._rfbRSAAESAuthenticationState.hasStarted) { | |
| 2013 | + this._rfbRSAAESAuthenticationState.negotiateRA2neAuthAsync() | |
| 2014 | + .catch((e) => { | |
| 2015 | + if (e.message !== "disconnect normally") { | |
| 2016 | + this._fail(e.message); | |
| 2017 | + } | |
| 2018 | + }) | |
| 2019 | + .then(() => { | |
| 2020 | + this._rfbInitState = "SecurityResult"; | |
| 2021 | + return true; | |
| 2022 | + }).finally(() => { | |
| 2023 | + this._rfbRSAAESAuthenticationState.removeEventListener( | |
| 2024 | + "serververification", this._eventHandlers.handleRSAAESServerVerification); | |
| 2025 | + this._rfbRSAAESAuthenticationState.removeEventListener( | |
| 2026 | + "credentialsrequired", this._eventHandlers.handleRSAAESCredentialsRequired); | |
| 2027 | + this._rfbRSAAESAuthenticationState = null; | |
| 2028 | + }); | |
| 2029 | + } | |
| 2030 | + return false; | |
| 2031 | + } | |
| 2032 | + | |
| 2033 | + _negotiateMSLogonIIAuth() { | |
| 2034 | + if (this._sock.rQwait("mslogonii dh param", 24)) { return false; } | |
| 2035 | + | |
| 2036 | + if (this._rfbCredentials.username === undefined || | |
| 2037 | + this._rfbCredentials.password === undefined) { | |
| 2038 | + this.dispatchEvent(new CustomEvent( | |
| 2039 | + "credentialsrequired", | |
| 2040 | + { detail: { types: ["username", "password"] } })); | |
| 2041 | + return false; | |
| 2042 | + } | |
| 2043 | + | |
| 2044 | + const g = this._sock.rQshiftBytes(8); | |
| 2045 | + const p = this._sock.rQshiftBytes(8); | |
| 2046 | + const A = this._sock.rQshiftBytes(8); | |
| 2047 | + const dhKey = legacyCrypto.generateKey({ name: "DH", g: g, p: p }, true, ["deriveBits"]); | |
| 2048 | + const B = legacyCrypto.exportKey("raw", dhKey.publicKey); | |
| 2049 | + const secret = legacyCrypto.deriveBits({ name: "DH", public: A }, dhKey.privateKey, 64); | |
| 2050 | + | |
| 2051 | + const key = legacyCrypto.importKey("raw", secret, { name: "DES-CBC" }, false, ["encrypt"]); | |
| 2052 | + const username = encodeUTF8(this._rfbCredentials.username).substring(0, 255); | |
| 2053 | + const password = encodeUTF8(this._rfbCredentials.password).substring(0, 63); | |
| 2054 | + let usernameBytes = new Uint8Array(256); | |
| 2055 | + let passwordBytes = new Uint8Array(64); | |
| 2056 | + window.crypto.getRandomValues(usernameBytes); | |
| 2057 | + window.crypto.getRandomValues(passwordBytes); | |
| 2058 | + for (let i = 0; i < username.length; i++) { | |
| 2059 | + usernameBytes[i] = username.charCodeAt(i); | |
| 2060 | + } | |
| 2061 | + usernameBytes[username.length] = 0; | |
| 2062 | + for (let i = 0; i < password.length; i++) { | |
| 2063 | + passwordBytes[i] = password.charCodeAt(i); | |
| 2064 | + } | |
| 2065 | + passwordBytes[password.length] = 0; | |
| 2066 | + usernameBytes = legacyCrypto.encrypt({ name: "DES-CBC", iv: secret }, key, usernameBytes); | |
| 2067 | + passwordBytes = legacyCrypto.encrypt({ name: "DES-CBC", iv: secret }, key, passwordBytes); | |
| 2068 | + this._sock.sQpushBytes(B); | |
| 2069 | + this._sock.sQpushBytes(usernameBytes); | |
| 2070 | + this._sock.sQpushBytes(passwordBytes); | |
| 2071 | + this._sock.flush(); | |
| 2072 | + this._rfbInitState = "SecurityResult"; | |
| 2073 | + return true; | |
| 2074 | + } | |
| 2075 | + | |
| 2076 | + _negotiateAuthentication() { | |
| 2077 | + switch (this._rfbAuthScheme) { | |
| 2078 | + case securityTypeNone: | |
| 2079 | + if (this._rfbVersion >= 3.8) { | |
| 2080 | + this._rfbInitState = 'SecurityResult'; | |
| 2081 | + } else { | |
| 2082 | + this._rfbInitState = 'ClientInitialisation'; | |
| 2083 | + } | |
| 2084 | + return true; | |
| 2085 | + | |
| 2086 | + case securityTypeXVP: | |
| 2087 | + return this._negotiateXvpAuth(); | |
| 2088 | + | |
| 2089 | + case securityTypeARD: | |
| 2090 | + return this._negotiateARDAuth(); | |
| 2091 | + | |
| 2092 | + case securityTypeVNCAuth: | |
| 2093 | + return this._negotiateStdVNCAuth(); | |
| 2094 | + | |
| 2095 | + case securityTypeTight: | |
| 2096 | + return this._negotiateTightAuth(); | |
| 2097 | + | |
| 2098 | + case securityTypeVeNCrypt: | |
| 2099 | + return this._negotiateVeNCryptAuth(); | |
| 2100 | + | |
| 2101 | + case securityTypePlain: | |
| 2102 | + return this._negotiatePlainAuth(); | |
| 2103 | + | |
| 2104 | + case securityTypeUnixLogon: | |
| 2105 | + return this._negotiateTightUnixAuth(); | |
| 2106 | + | |
| 2107 | + case securityTypeRA2ne: | |
| 2108 | + return this._negotiateRA2neAuth(); | |
| 2109 | + | |
| 2110 | + case securityTypeMSLogonII: | |
| 2111 | + return this._negotiateMSLogonIIAuth(); | |
| 2112 | + | |
| 2113 | + default: | |
| 2114 | + return this._fail("Unsupported auth scheme (scheme: " + | |
| 2115 | + this._rfbAuthScheme + ")"); | |
| 2116 | + } | |
| 2117 | + } | |
| 2118 | + | |
| 2119 | + _handleSecurityResult() { | |
| 2120 | + if (this._sock.rQwait('VNC auth response ', 4)) { return false; } | |
| 2121 | + | |
| 2122 | + const status = this._sock.rQshift32(); | |
| 2123 | + | |
| 2124 | + if (status === 0) { // OK | |
| 2125 | + this._rfbInitState = 'ClientInitialisation'; | |
| 2126 | + Log.Debug('Authentication OK'); | |
| 2127 | + return true; | |
| 2128 | + } else { | |
| 2129 | + if (this._rfbVersion >= 3.8) { | |
| 2130 | + this._rfbInitState = "SecurityReason"; | |
| 2131 | + this._securityContext = "security result"; | |
| 2132 | + this._securityStatus = status; | |
| 2133 | + return true; | |
| 2134 | + } else { | |
| 2135 | + this.dispatchEvent(new CustomEvent( | |
| 2136 | + "securityfailure", | |
| 2137 | + { detail: { status: status } })); | |
| 2138 | + | |
| 2139 | + return this._fail("Security handshake failed"); | |
| 2140 | + } | |
| 2141 | + } | |
| 2142 | + } | |
| 2143 | + | |
| 2144 | + _negotiateServerInit() { | |
| 2145 | + if (this._sock.rQwait("server initialization", 24)) { return false; } | |
| 2146 | + | |
| 2147 | + /* Screen size */ | |
| 2148 | + const width = this._sock.rQshift16(); | |
| 2149 | + const height = this._sock.rQshift16(); | |
| 2150 | + | |
| 2151 | + /* PIXEL_FORMAT */ | |
| 2152 | + const bpp = this._sock.rQshift8(); | |
| 2153 | + const depth = this._sock.rQshift8(); | |
| 2154 | + const bigEndian = this._sock.rQshift8(); | |
| 2155 | + const trueColor = this._sock.rQshift8(); | |
| 2156 | + | |
| 2157 | + const redMax = this._sock.rQshift16(); | |
| 2158 | + const greenMax = this._sock.rQshift16(); | |
| 2159 | + const blueMax = this._sock.rQshift16(); | |
| 2160 | + const redShift = this._sock.rQshift8(); | |
| 2161 | + const greenShift = this._sock.rQshift8(); | |
| 2162 | + const blueShift = this._sock.rQshift8(); | |
| 2163 | + this._sock.rQskipBytes(3); // padding | |
| 2164 | + | |
| 2165 | + // NB(directxman12): we don't want to call any callbacks or print messages until | |
| 2166 | + // *after* we're past the point where we could backtrack | |
| 2167 | + | |
| 2168 | + /* Connection name/title */ | |
| 2169 | + const nameLength = this._sock.rQshift32(); | |
| 2170 | + if (this._sock.rQwait('server init name', nameLength, 24)) { return false; } | |
| 2171 | + let name = this._sock.rQshiftStr(nameLength); | |
| 2172 | + name = decodeUTF8(name, true); | |
| 2173 | + | |
| 2174 | + if (this._rfbTightVNC) { | |
| 2175 | + if (this._sock.rQwait('TightVNC extended server init header', 8, 24 + nameLength)) { return false; } | |
| 2176 | + // In TightVNC mode, ServerInit message is extended | |
| 2177 | + const numServerMessages = this._sock.rQshift16(); | |
| 2178 | + const numClientMessages = this._sock.rQshift16(); | |
| 2179 | + const numEncodings = this._sock.rQshift16(); | |
| 2180 | + this._sock.rQskipBytes(2); // padding | |
| 2181 | + | |
| 2182 | + const totalMessagesLength = (numServerMessages + numClientMessages + numEncodings) * 16; | |
| 2183 | + if (this._sock.rQwait('TightVNC extended server init header', totalMessagesLength, 32 + nameLength)) { return false; } | |
| 2184 | + | |
| 2185 | + // we don't actually do anything with the capability information that TIGHT sends, | |
| 2186 | + // so we just skip the all of this. | |
| 2187 | + | |
| 2188 | + // TIGHT server message capabilities | |
| 2189 | + this._sock.rQskipBytes(16 * numServerMessages); | |
| 2190 | + | |
| 2191 | + // TIGHT client message capabilities | |
| 2192 | + this._sock.rQskipBytes(16 * numClientMessages); | |
| 2193 | + | |
| 2194 | + // TIGHT encoding capabilities | |
| 2195 | + this._sock.rQskipBytes(16 * numEncodings); | |
| 2196 | + } | |
| 2197 | + | |
| 2198 | + // NB(directxman12): these are down here so that we don't run them multiple times | |
| 2199 | + // if we backtrack | |
| 2200 | + Log.Info("Screen: " + width + "x" + height + | |
| 2201 | + ", bpp: " + bpp + ", depth: " + depth + | |
| 2202 | + ", bigEndian: " + bigEndian + | |
| 2203 | + ", trueColor: " + trueColor + | |
| 2204 | + ", redMax: " + redMax + | |
| 2205 | + ", greenMax: " + greenMax + | |
| 2206 | + ", blueMax: " + blueMax + | |
| 2207 | + ", redShift: " + redShift + | |
| 2208 | + ", greenShift: " + greenShift + | |
| 2209 | + ", blueShift: " + blueShift); | |
| 2210 | + | |
| 2211 | + // we're past the point where we could backtrack, so it's safe to call this | |
| 2212 | + this._setDesktopName(name); | |
| 2213 | + this._resize(width, height); | |
| 2214 | + | |
| 2215 | + if (!this._viewOnly) { this._keyboard.grab(); } | |
| 2216 | + | |
| 2217 | + this._fbDepth = 24; | |
| 2218 | + | |
| 2219 | + if (this._fbName === "Intel(r) AMT KVM") { | |
| 2220 | + Log.Warn("Intel AMT KVM only supports 8/16 bit depths. Using low color mode."); | |
| 2221 | + this._fbDepth = 8; | |
| 2222 | + } | |
| 2223 | + | |
| 2224 | + RFB.messages.pixelFormat(this._sock, this._fbDepth, true); | |
| 2225 | + this._sendEncodings(); | |
| 2226 | + RFB.messages.fbUpdateRequest(this._sock, false, 0, 0, this._fbWidth, this._fbHeight); | |
| 2227 | + | |
| 2228 | + this._updateConnectionState('connected'); | |
| 2229 | + return true; | |
| 2230 | + } | |
| 2231 | + | |
| 2232 | + _sendEncodings() { | |
| 2233 | + const encs = []; | |
| 2234 | + | |
| 2235 | + // In preference order | |
| 2236 | + encs.push(encodings.encodingCopyRect); | |
| 2237 | + // Only supported with full depth support | |
| 2238 | + if (this._fbDepth == 24) { | |
| 2239 | + if (supportsWebCodecsH264Decode) { | |
| 2240 | + encs.push(encodings.encodingH264); | |
| 2241 | + } | |
| 2242 | + encs.push(encodings.encodingTight); | |
| 2243 | + encs.push(encodings.encodingTightPNG); | |
| 2244 | + encs.push(encodings.encodingZRLE); | |
| 2245 | + encs.push(encodings.encodingJPEG); | |
| 2246 | + encs.push(encodings.encodingHextile); | |
| 2247 | + encs.push(encodings.encodingRRE); | |
| 2248 | + encs.push(encodings.encodingZlib); | |
| 2249 | + } | |
| 2250 | + encs.push(encodings.encodingRaw); | |
| 2251 | + | |
| 2252 | + // Psuedo-encoding settings | |
| 2253 | + encs.push(encodings.pseudoEncodingQualityLevel0 + this._qualityLevel); | |
| 2254 | + encs.push(encodings.pseudoEncodingCompressLevel0 + this._compressionLevel); | |
| 2255 | + | |
| 2256 | + encs.push(encodings.pseudoEncodingDesktopSize); | |
| 2257 | + encs.push(encodings.pseudoEncodingLastRect); | |
| 2258 | + encs.push(encodings.pseudoEncodingQEMUExtendedKeyEvent); | |
| 2259 | + encs.push(encodings.pseudoEncodingQEMULedEvent); | |
| 2260 | + encs.push(encodings.pseudoEncodingExtendedDesktopSize); | |
| 2261 | + encs.push(encodings.pseudoEncodingXvp); | |
| 2262 | + encs.push(encodings.pseudoEncodingFence); | |
| 2263 | + encs.push(encodings.pseudoEncodingContinuousUpdates); | |
| 2264 | + encs.push(encodings.pseudoEncodingDesktopName); | |
| 2265 | + encs.push(encodings.pseudoEncodingExtendedClipboard); | |
| 2266 | + encs.push(encodings.pseudoEncodingExtendedMouseButtons); | |
| 2267 | + | |
| 2268 | + if (this._fbDepth == 24) { | |
| 2269 | + encs.push(encodings.pseudoEncodingVMwareCursor); | |
| 2270 | + encs.push(encodings.pseudoEncodingCursor); | |
| 2271 | + } | |
| 2272 | + | |
| 2273 | + RFB.messages.clientEncodings(this._sock, encs); | |
| 2274 | + } | |
| 2275 | + | |
| 2276 | + /* RFB protocol initialization states: | |
| 2277 | + * ProtocolVersion | |
| 2278 | + * Security | |
| 2279 | + * Authentication | |
| 2280 | + * SecurityResult | |
| 2281 | + * ClientInitialization - not triggered by server message | |
| 2282 | + * ServerInitialization | |
| 2283 | + */ | |
| 2284 | + _initMsg() { | |
| 2285 | + switch (this._rfbInitState) { | |
| 2286 | + case 'ProtocolVersion': | |
| 2287 | + return this._negotiateProtocolVersion(); | |
| 2288 | + | |
| 2289 | + case 'Security': | |
| 2290 | + return this._negotiateSecurity(); | |
| 2291 | + | |
| 2292 | + case 'Authentication': | |
| 2293 | + return this._negotiateAuthentication(); | |
| 2294 | + | |
| 2295 | + case 'SecurityResult': | |
| 2296 | + return this._handleSecurityResult(); | |
| 2297 | + | |
| 2298 | + case 'SecurityReason': | |
| 2299 | + return this._handleSecurityReason(); | |
| 2300 | + | |
| 2301 | + case 'ClientInitialisation': | |
| 2302 | + this._sock.sQpush8(this._shared ? 1 : 0); // ClientInitialisation | |
| 2303 | + this._sock.flush(); | |
| 2304 | + this._rfbInitState = 'ServerInitialisation'; | |
| 2305 | + return true; | |
| 2306 | + | |
| 2307 | + case 'ServerInitialisation': | |
| 2308 | + return this._negotiateServerInit(); | |
| 2309 | + | |
| 2310 | + default: | |
| 2311 | + return this._fail("Unknown init state (state: " + | |
| 2312 | + this._rfbInitState + ")"); | |
| 2313 | + } | |
| 2314 | + } | |
| 2315 | + | |
| 2316 | + // Resume authentication handshake after it was paused for some | |
| 2317 | + // reason, e.g. waiting for a password from the user | |
| 2318 | + _resumeAuthentication() { | |
| 2319 | + // We use setTimeout() so it's run in its own context, just like | |
| 2320 | + // it originally did via the WebSocket's event handler | |
| 2321 | + setTimeout(this._initMsg.bind(this), 0); | |
| 2322 | + } | |
| 2323 | + | |
| 2324 | + _handleSetColourMapMsg() { | |
| 2325 | + Log.Debug("SetColorMapEntries"); | |
| 2326 | + | |
| 2327 | + return this._fail("Unexpected SetColorMapEntries message"); | |
| 2328 | + } | |
| 2329 | + | |
| 2330 | + _handleServerCutText() { | |
| 2331 | + Log.Debug("ServerCutText"); | |
| 2332 | + | |
| 2333 | + if (this._sock.rQwait("ServerCutText header", 7, 1)) { return false; } | |
| 2334 | + | |
| 2335 | + this._sock.rQskipBytes(3); // Padding | |
| 2336 | + | |
| 2337 | + let length = this._sock.rQshift32(); | |
| 2338 | + length = toSigned32bit(length); | |
| 2339 | + | |
| 2340 | + if (this._sock.rQwait("ServerCutText content", Math.abs(length), 8)) { return false; } | |
| 2341 | + | |
| 2342 | + if (length >= 0) { | |
| 2343 | + //Standard msg | |
| 2344 | + const text = this._sock.rQshiftStr(length); | |
| 2345 | + if (this._viewOnly) { | |
| 2346 | + return true; | |
| 2347 | + } | |
| 2348 | + | |
| 2349 | + this.dispatchEvent(new CustomEvent( | |
| 2350 | + "clipboard", | |
| 2351 | + { detail: { text: text } })); | |
| 2352 | + | |
| 2353 | + } else { | |
| 2354 | + //Extended msg. | |
| 2355 | + length = Math.abs(length); | |
| 2356 | + const flags = this._sock.rQshift32(); | |
| 2357 | + let formats = flags & 0x0000FFFF; | |
| 2358 | + let actions = flags & 0xFF000000; | |
| 2359 | + | |
| 2360 | + let isCaps = (!!(actions & extendedClipboardActionCaps)); | |
| 2361 | + if (isCaps) { | |
| 2362 | + this._clipboardServerCapabilitiesFormats = {}; | |
| 2363 | + this._clipboardServerCapabilitiesActions = {}; | |
| 2364 | + | |
| 2365 | + // Update our server capabilities for Formats | |
| 2366 | + for (let i = 0; i <= 15; i++) { | |
| 2367 | + let index = 1 << i; | |
| 2368 | + | |
| 2369 | + // Check if format flag is set. | |
| 2370 | + if ((formats & index)) { | |
| 2371 | + this._clipboardServerCapabilitiesFormats[index] = true; | |
| 2372 | + // We don't send unsolicited clipboard, so we | |
| 2373 | + // ignore the size | |
| 2374 | + this._sock.rQshift32(); | |
| 2375 | + } | |
| 2376 | + } | |
| 2377 | + | |
| 2378 | + // Update our server capabilities for Actions | |
| 2379 | + for (let i = 24; i <= 31; i++) { | |
| 2380 | + let index = 1 << i; | |
| 2381 | + this._clipboardServerCapabilitiesActions[index] = !!(actions & index); | |
| 2382 | + } | |
| 2383 | + | |
| 2384 | + /* Caps handling done, send caps with the clients | |
| 2385 | + capabilities set as a response */ | |
| 2386 | + let clientActions = [ | |
| 2387 | + extendedClipboardActionCaps, | |
| 2388 | + extendedClipboardActionRequest, | |
| 2389 | + extendedClipboardActionPeek, | |
| 2390 | + extendedClipboardActionNotify, | |
| 2391 | + extendedClipboardActionProvide | |
| 2392 | + ]; | |
| 2393 | + RFB.messages.extendedClipboardCaps(this._sock, clientActions, {extendedClipboardFormatText: 0}); | |
| 2394 | + | |
| 2395 | + } else if (actions === extendedClipboardActionRequest) { | |
| 2396 | + if (this._viewOnly) { | |
| 2397 | + return true; | |
| 2398 | + } | |
| 2399 | + | |
| 2400 | + // Check if server has told us it can handle Provide and there is clipboard data to send. | |
| 2401 | + if (this._clipboardText != null && | |
| 2402 | + this._clipboardServerCapabilitiesActions[extendedClipboardActionProvide]) { | |
| 2403 | + | |
| 2404 | + if (formats & extendedClipboardFormatText) { | |
| 2405 | + RFB.messages.extendedClipboardProvide(this._sock, [extendedClipboardFormatText], [this._clipboardText]); | |
| 2406 | + } | |
| 2407 | + } | |
| 2408 | + | |
| 2409 | + } else if (actions === extendedClipboardActionPeek) { | |
| 2410 | + if (this._viewOnly) { | |
| 2411 | + return true; | |
| 2412 | + } | |
| 2413 | + | |
| 2414 | + if (this._clipboardServerCapabilitiesActions[extendedClipboardActionNotify]) { | |
| 2415 | + | |
| 2416 | + if (this._clipboardText != null) { | |
| 2417 | + RFB.messages.extendedClipboardNotify(this._sock, [extendedClipboardFormatText]); | |
| 2418 | + } else { | |
| 2419 | + RFB.messages.extendedClipboardNotify(this._sock, []); | |
| 2420 | + } | |
| 2421 | + } | |
| 2422 | + | |
| 2423 | + } else if (actions === extendedClipboardActionNotify) { | |
| 2424 | + if (this._viewOnly) { | |
| 2425 | + return true; | |
| 2426 | + } | |
| 2427 | + | |
| 2428 | + if (this._clipboardServerCapabilitiesActions[extendedClipboardActionRequest]) { | |
| 2429 | + | |
| 2430 | + if (formats & extendedClipboardFormatText) { | |
| 2431 | + RFB.messages.extendedClipboardRequest(this._sock, [extendedClipboardFormatText]); | |
| 2432 | + } | |
| 2433 | + } | |
| 2434 | + | |
| 2435 | + } else if (actions === extendedClipboardActionProvide) { | |
| 2436 | + if (this._viewOnly) { | |
| 2437 | + return true; | |
| 2438 | + } | |
| 2439 | + | |
| 2440 | + if (!(formats & extendedClipboardFormatText)) { | |
| 2441 | + return true; | |
| 2442 | + } | |
| 2443 | + // Ignore what we had in our clipboard client side. | |
| 2444 | + this._clipboardText = null; | |
| 2445 | + | |
| 2446 | + // FIXME: Should probably verify that this data was actually requested | |
| 2447 | + let zlibStream = this._sock.rQshiftBytes(length - 4); | |
| 2448 | + let streamInflator = new Inflator(); | |
| 2449 | + let textData = null; | |
| 2450 | + | |
| 2451 | + streamInflator.setInput(zlibStream); | |
| 2452 | + for (let i = 0; i <= 15; i++) { | |
| 2453 | + let format = 1 << i; | |
| 2454 | + | |
| 2455 | + if (formats & format) { | |
| 2456 | + | |
| 2457 | + let size = 0x00; | |
| 2458 | + let sizeArray = streamInflator.inflate(4); | |
| 2459 | + | |
| 2460 | + size |= (sizeArray[0] << 24); | |
| 2461 | + size |= (sizeArray[1] << 16); | |
| 2462 | + size |= (sizeArray[2] << 8); | |
| 2463 | + size |= (sizeArray[3]); | |
| 2464 | + let chunk = streamInflator.inflate(size); | |
| 2465 | + | |
| 2466 | + if (format === extendedClipboardFormatText) { | |
| 2467 | + textData = chunk; | |
| 2468 | + } | |
| 2469 | + } | |
| 2470 | + } | |
| 2471 | + streamInflator.setInput(null); | |
| 2472 | + | |
| 2473 | + if (textData !== null) { | |
| 2474 | + let tmpText = ""; | |
| 2475 | + for (let i = 0; i < textData.length; i++) { | |
| 2476 | + tmpText += String.fromCharCode(textData[i]); | |
| 2477 | + } | |
| 2478 | + textData = tmpText; | |
| 2479 | + | |
| 2480 | + textData = decodeUTF8(textData); | |
| 2481 | + if ((textData.length > 0) && "\0" === textData.charAt(textData.length - 1)) { | |
| 2482 | + textData = textData.slice(0, -1); | |
| 2483 | + } | |
| 2484 | + | |
| 2485 | + textData = textData.replaceAll("\r\n", "\n"); | |
| 2486 | + | |
| 2487 | + this.dispatchEvent(new CustomEvent( | |
| 2488 | + "clipboard", | |
| 2489 | + { detail: { text: textData } })); | |
| 2490 | + } | |
| 2491 | + } else { | |
| 2492 | + return this._fail("Unexpected action in extended clipboard message: " + actions); | |
| 2493 | + } | |
| 2494 | + } | |
| 2495 | + return true; | |
| 2496 | + } | |
| 2497 | + | |
| 2498 | + _handleServerFenceMsg() { | |
| 2499 | + if (this._sock.rQwait("ServerFence header", 8, 1)) { return false; } | |
| 2500 | + this._sock.rQskipBytes(3); // Padding | |
| 2501 | + let flags = this._sock.rQshift32(); | |
| 2502 | + let length = this._sock.rQshift8(); | |
| 2503 | + | |
| 2504 | + if (this._sock.rQwait("ServerFence payload", length, 9)) { return false; } | |
| 2505 | + | |
| 2506 | + if (length > 64) { | |
| 2507 | + Log.Warn("Bad payload length (" + length + ") in fence response"); | |
| 2508 | + length = 64; | |
| 2509 | + } | |
| 2510 | + | |
| 2511 | + const payload = this._sock.rQshiftStr(length); | |
| 2512 | + | |
| 2513 | + this._supportsFence = true; | |
| 2514 | + | |
| 2515 | + /* | |
| 2516 | + * Fence flags | |
| 2517 | + * | |
| 2518 | + * (1<<0) - BlockBefore | |
| 2519 | + * (1<<1) - BlockAfter | |
| 2520 | + * (1<<2) - SyncNext | |
| 2521 | + * (1<<31) - Request | |
| 2522 | + */ | |
| 2523 | + | |
| 2524 | + if (!(flags & (1<<31))) { | |
| 2525 | + return this._fail("Unexpected fence response"); | |
| 2526 | + } | |
| 2527 | + | |
| 2528 | + // Filter out unsupported flags | |
| 2529 | + // FIXME: support syncNext | |
| 2530 | + flags &= (1<<0) | (1<<1); | |
| 2531 | + | |
| 2532 | + // BlockBefore and BlockAfter are automatically handled by | |
| 2533 | + // the fact that we process each incoming message | |
| 2534 | + // synchronuosly. | |
| 2535 | + RFB.messages.clientFence(this._sock, flags, payload); | |
| 2536 | + | |
| 2537 | + return true; | |
| 2538 | + } | |
| 2539 | + | |
| 2540 | + _handleXvpMsg() { | |
| 2541 | + if (this._sock.rQwait("XVP version and message", 3, 1)) { return false; } | |
| 2542 | + this._sock.rQskipBytes(1); // Padding | |
| 2543 | + const xvpVer = this._sock.rQshift8(); | |
| 2544 | + const xvpMsg = this._sock.rQshift8(); | |
| 2545 | + | |
| 2546 | + switch (xvpMsg) { | |
| 2547 | + case 0: // XVP_FAIL | |
| 2548 | + Log.Error("XVP operation failed"); | |
| 2549 | + break; | |
| 2550 | + case 1: // XVP_INIT | |
| 2551 | + this._rfbXvpVer = xvpVer; | |
| 2552 | + Log.Info("XVP extensions enabled (version " + this._rfbXvpVer + ")"); | |
| 2553 | + this._setCapability("power", true); | |
| 2554 | + break; | |
| 2555 | + default: | |
| 2556 | + this._fail("Illegal server XVP message (msg: " + xvpMsg + ")"); | |
| 2557 | + break; | |
| 2558 | + } | |
| 2559 | + | |
| 2560 | + return true; | |
| 2561 | + } | |
| 2562 | + | |
| 2563 | + _normalMsg() { | |
| 2564 | + let msgType; | |
| 2565 | + if (this._FBU.rects > 0) { | |
| 2566 | + msgType = 0; | |
| 2567 | + } else { | |
| 2568 | + msgType = this._sock.rQshift8(); | |
| 2569 | + } | |
| 2570 | + | |
| 2571 | + let first, ret; | |
| 2572 | + switch (msgType) { | |
| 2573 | + case 0: // FramebufferUpdate | |
| 2574 | + ret = this._framebufferUpdate(); | |
| 2575 | + if (ret && !this._enabledContinuousUpdates) { | |
| 2576 | + RFB.messages.fbUpdateRequest(this._sock, true, 0, 0, | |
| 2577 | + this._fbWidth, this._fbHeight); | |
| 2578 | + } | |
| 2579 | + return ret; | |
| 2580 | + | |
| 2581 | + case 1: // SetColorMapEntries | |
| 2582 | + return this._handleSetColourMapMsg(); | |
| 2583 | + | |
| 2584 | + case 2: // Bell | |
| 2585 | + Log.Debug("Bell"); | |
| 2586 | + this.dispatchEvent(new CustomEvent( | |
| 2587 | + "bell", | |
| 2588 | + { detail: {} })); | |
| 2589 | + return true; | |
| 2590 | + | |
| 2591 | + case 3: // ServerCutText | |
| 2592 | + return this._handleServerCutText(); | |
| 2593 | + | |
| 2594 | + case 150: // EndOfContinuousUpdates | |
| 2595 | + first = !this._supportsContinuousUpdates; | |
| 2596 | + this._supportsContinuousUpdates = true; | |
| 2597 | + this._enabledContinuousUpdates = false; | |
| 2598 | + if (first) { | |
| 2599 | + this._enabledContinuousUpdates = true; | |
| 2600 | + this._updateContinuousUpdates(); | |
| 2601 | + Log.Info("Enabling continuous updates."); | |
| 2602 | + } else { | |
| 2603 | + // FIXME: We need to send a framebufferupdaterequest here | |
| 2604 | + // if we add support for turning off continuous updates | |
| 2605 | + } | |
| 2606 | + return true; | |
| 2607 | + | |
| 2608 | + case 248: // ServerFence | |
| 2609 | + return this._handleServerFenceMsg(); | |
| 2610 | + | |
| 2611 | + case 250: // XVP | |
| 2612 | + return this._handleXvpMsg(); | |
| 2613 | + | |
| 2614 | + default: | |
| 2615 | + this._fail("Unexpected server message (type " + msgType + ")"); | |
| 2616 | + Log.Debug("sock.rQpeekBytes(30): " + this._sock.rQpeekBytes(30)); | |
| 2617 | + return true; | |
| 2618 | + } | |
| 2619 | + } | |
| 2620 | + | |
| 2621 | + _framebufferUpdate() { | |
| 2622 | + if (this._FBU.rects === 0) { | |
| 2623 | + if (this._sock.rQwait("FBU header", 3, 1)) { return false; } | |
| 2624 | + this._sock.rQskipBytes(1); // Padding | |
| 2625 | + this._FBU.rects = this._sock.rQshift16(); | |
| 2626 | + | |
| 2627 | + // Make sure the previous frame is fully rendered first | |
| 2628 | + // to avoid building up an excessive queue | |
| 2629 | + if (this._display.pending()) { | |
| 2630 | + this._flushing = true; | |
| 2631 | + this._display.flush() | |
| 2632 | + .then(() => { | |
| 2633 | + this._flushing = false; | |
| 2634 | + // Resume processing | |
| 2635 | + if (!this._sock.rQwait("message", 1)) { | |
| 2636 | + this._handleMessage(); | |
| 2637 | + } | |
| 2638 | + }); | |
| 2639 | + return false; | |
| 2640 | + } | |
| 2641 | + } | |
| 2642 | + | |
| 2643 | + while (this._FBU.rects > 0) { | |
| 2644 | + if (this._FBU.encoding === null) { | |
| 2645 | + if (this._sock.rQwait("rect header", 12)) { return false; } | |
| 2646 | + /* New FramebufferUpdate */ | |
| 2647 | + | |
| 2648 | + this._FBU.x = this._sock.rQshift16(); | |
| 2649 | + this._FBU.y = this._sock.rQshift16(); | |
| 2650 | + this._FBU.width = this._sock.rQshift16(); | |
| 2651 | + this._FBU.height = this._sock.rQshift16(); | |
| 2652 | + this._FBU.encoding = this._sock.rQshift32(); | |
| 2653 | + /* Encodings are signed */ | |
| 2654 | + this._FBU.encoding >>= 0; | |
| 2655 | + } | |
| 2656 | + | |
| 2657 | + if (!this._handleRect()) { | |
| 2658 | + return false; | |
| 2659 | + } | |
| 2660 | + | |
| 2661 | + this._FBU.rects--; | |
| 2662 | + this._FBU.encoding = null; | |
| 2663 | + } | |
| 2664 | + | |
| 2665 | + this._display.flip(); | |
| 2666 | + | |
| 2667 | + return true; // We finished this FBU | |
| 2668 | + } | |
| 2669 | + | |
| 2670 | + _handleRect() { | |
| 2671 | + switch (this._FBU.encoding) { | |
| 2672 | + case encodings.pseudoEncodingLastRect: | |
| 2673 | + this._FBU.rects = 1; // Will be decreased when we return | |
| 2674 | + return true; | |
| 2675 | + | |
| 2676 | + case encodings.pseudoEncodingVMwareCursor: | |
| 2677 | + return this._handleVMwareCursor(); | |
| 2678 | + | |
| 2679 | + case encodings.pseudoEncodingCursor: | |
| 2680 | + return this._handleCursor(); | |
| 2681 | + | |
| 2682 | + case encodings.pseudoEncodingQEMUExtendedKeyEvent: | |
| 2683 | + this._qemuExtKeyEventSupported = true; | |
| 2684 | + return true; | |
| 2685 | + | |
| 2686 | + case encodings.pseudoEncodingDesktopName: | |
| 2687 | + return this._handleDesktopName(); | |
| 2688 | + | |
| 2689 | + case encodings.pseudoEncodingDesktopSize: | |
| 2690 | + this._resize(this._FBU.width, this._FBU.height); | |
| 2691 | + return true; | |
| 2692 | + | |
| 2693 | + case encodings.pseudoEncodingExtendedDesktopSize: | |
| 2694 | + return this._handleExtendedDesktopSize(); | |
| 2695 | + | |
| 2696 | + case encodings.pseudoEncodingExtendedMouseButtons: | |
| 2697 | + this._extendedPointerEventSupported = true; | |
| 2698 | + return true; | |
| 2699 | + | |
| 2700 | + case encodings.pseudoEncodingQEMULedEvent: | |
| 2701 | + return this._handleLedEvent(); | |
| 2702 | + | |
| 2703 | + default: | |
| 2704 | + return this._handleDataRect(); | |
| 2705 | + } | |
| 2706 | + } | |
| 2707 | + | |
| 2708 | + _handleVMwareCursor() { | |
| 2709 | + const hotx = this._FBU.x; // hotspot-x | |
| 2710 | + const hoty = this._FBU.y; // hotspot-y | |
| 2711 | + const w = this._FBU.width; | |
| 2712 | + const h = this._FBU.height; | |
| 2713 | + if (this._sock.rQwait("VMware cursor encoding", 1)) { | |
| 2714 | + return false; | |
| 2715 | + } | |
| 2716 | + | |
| 2717 | + const cursorType = this._sock.rQshift8(); | |
| 2718 | + | |
| 2719 | + this._sock.rQshift8(); //Padding | |
| 2720 | + | |
| 2721 | + let rgba; | |
| 2722 | + const bytesPerPixel = 4; | |
| 2723 | + | |
| 2724 | + //Classic cursor | |
| 2725 | + if (cursorType == 0) { | |
| 2726 | + //Used to filter away unimportant bits. | |
| 2727 | + //OR is used for correct conversion in js. | |
| 2728 | + const PIXEL_MASK = 0xffffff00 | 0; | |
| 2729 | + rgba = new Array(w * h * bytesPerPixel); | |
| 2730 | + | |
| 2731 | + if (this._sock.rQwait("VMware cursor classic encoding", | |
| 2732 | + (w * h * bytesPerPixel) * 2, 2)) { | |
| 2733 | + return false; | |
| 2734 | + } | |
| 2735 | + | |
| 2736 | + let andMask = new Array(w * h); | |
| 2737 | + for (let pixel = 0; pixel < (w * h); pixel++) { | |
| 2738 | + andMask[pixel] = this._sock.rQshift32(); | |
| 2739 | + } | |
| 2740 | + | |
| 2741 | + let xorMask = new Array(w * h); | |
| 2742 | + for (let pixel = 0; pixel < (w * h); pixel++) { | |
| 2743 | + xorMask[pixel] = this._sock.rQshift32(); | |
| 2744 | + } | |
| 2745 | + | |
| 2746 | + for (let pixel = 0; pixel < (w * h); pixel++) { | |
| 2747 | + if (andMask[pixel] == 0) { | |
| 2748 | + //Fully opaque pixel | |
| 2749 | + let bgr = xorMask[pixel]; | |
| 2750 | + let r = bgr >> 8 & 0xff; | |
| 2751 | + let g = bgr >> 16 & 0xff; | |
| 2752 | + let b = bgr >> 24 & 0xff; | |
| 2753 | + | |
| 2754 | + rgba[(pixel * bytesPerPixel) ] = r; //r | |
| 2755 | + rgba[(pixel * bytesPerPixel) + 1 ] = g; //g | |
| 2756 | + rgba[(pixel * bytesPerPixel) + 2 ] = b; //b | |
| 2757 | + rgba[(pixel * bytesPerPixel) + 3 ] = 0xff; //a | |
| 2758 | + | |
| 2759 | + } else if ((andMask[pixel] & PIXEL_MASK) == | |
| 2760 | + PIXEL_MASK) { | |
| 2761 | + //Only screen value matters, no mouse colouring | |
| 2762 | + if (xorMask[pixel] == 0) { | |
| 2763 | + //Transparent pixel | |
| 2764 | + rgba[(pixel * bytesPerPixel) ] = 0x00; | |
| 2765 | + rgba[(pixel * bytesPerPixel) + 1 ] = 0x00; | |
| 2766 | + rgba[(pixel * bytesPerPixel) + 2 ] = 0x00; | |
| 2767 | + rgba[(pixel * bytesPerPixel) + 3 ] = 0x00; | |
| 2768 | + | |
| 2769 | + } else if ((xorMask[pixel] & PIXEL_MASK) == | |
| 2770 | + PIXEL_MASK) { | |
| 2771 | + //Inverted pixel, not supported in browsers. | |
| 2772 | + //Fully opaque instead. | |
| 2773 | + rgba[(pixel * bytesPerPixel) ] = 0x00; | |
| 2774 | + rgba[(pixel * bytesPerPixel) + 1 ] = 0x00; | |
| 2775 | + rgba[(pixel * bytesPerPixel) + 2 ] = 0x00; | |
| 2776 | + rgba[(pixel * bytesPerPixel) + 3 ] = 0xff; | |
| 2777 | + | |
| 2778 | + } else { | |
| 2779 | + //Unhandled xorMask | |
| 2780 | + rgba[(pixel * bytesPerPixel) ] = 0x00; | |
| 2781 | + rgba[(pixel * bytesPerPixel) + 1 ] = 0x00; | |
| 2782 | + rgba[(pixel * bytesPerPixel) + 2 ] = 0x00; | |
| 2783 | + rgba[(pixel * bytesPerPixel) + 3 ] = 0xff; | |
| 2784 | + } | |
| 2785 | + | |
| 2786 | + } else { | |
| 2787 | + //Unhandled andMask | |
| 2788 | + rgba[(pixel * bytesPerPixel) ] = 0x00; | |
| 2789 | + rgba[(pixel * bytesPerPixel) + 1 ] = 0x00; | |
| 2790 | + rgba[(pixel * bytesPerPixel) + 2 ] = 0x00; | |
| 2791 | + rgba[(pixel * bytesPerPixel) + 3 ] = 0xff; | |
| 2792 | + } | |
| 2793 | + } | |
| 2794 | + | |
| 2795 | + //Alpha cursor. | |
| 2796 | + } else if (cursorType == 1) { | |
| 2797 | + if (this._sock.rQwait("VMware cursor alpha encoding", | |
| 2798 | + (w * h * 4), 2)) { | |
| 2799 | + return false; | |
| 2800 | + } | |
| 2801 | + | |
| 2802 | + rgba = new Array(w * h * bytesPerPixel); | |
| 2803 | + | |
| 2804 | + for (let pixel = 0; pixel < (w * h); pixel++) { | |
| 2805 | + let data = this._sock.rQshift32(); | |
| 2806 | + | |
| 2807 | + rgba[(pixel * 4) ] = data >> 24 & 0xff; //r | |
| 2808 | + rgba[(pixel * 4) + 1 ] = data >> 16 & 0xff; //g | |
| 2809 | + rgba[(pixel * 4) + 2 ] = data >> 8 & 0xff; //b | |
| 2810 | + rgba[(pixel * 4) + 3 ] = data & 0xff; //a | |
| 2811 | + } | |
| 2812 | + | |
| 2813 | + } else { | |
| 2814 | + Log.Warn("The given cursor type is not supported: " | |
| 2815 | + + cursorType + " given."); | |
| 2816 | + return false; | |
| 2817 | + } | |
| 2818 | + | |
| 2819 | + this._updateCursor(rgba, hotx, hoty, w, h); | |
| 2820 | + | |
| 2821 | + return true; | |
| 2822 | + } | |
| 2823 | + | |
| 2824 | + _handleCursor() { | |
| 2825 | + const hotx = this._FBU.x; // hotspot-x | |
| 2826 | + const hoty = this._FBU.y; // hotspot-y | |
| 2827 | + const w = this._FBU.width; | |
| 2828 | + const h = this._FBU.height; | |
| 2829 | + | |
| 2830 | + const pixelslength = w * h * 4; | |
| 2831 | + const masklength = Math.ceil(w / 8) * h; | |
| 2832 | + | |
| 2833 | + let bytes = pixelslength + masklength; | |
| 2834 | + if (this._sock.rQwait("cursor encoding", bytes)) { | |
| 2835 | + return false; | |
| 2836 | + } | |
| 2837 | + | |
| 2838 | + // Decode from BGRX pixels + bit mask to RGBA | |
| 2839 | + const pixels = this._sock.rQshiftBytes(pixelslength); | |
| 2840 | + const mask = this._sock.rQshiftBytes(masklength); | |
| 2841 | + let rgba = new Uint8Array(w * h * 4); | |
| 2842 | + | |
| 2843 | + let pixIdx = 0; | |
| 2844 | + for (let y = 0; y < h; y++) { | |
| 2845 | + for (let x = 0; x < w; x++) { | |
| 2846 | + let maskIdx = y * Math.ceil(w / 8) + Math.floor(x / 8); | |
| 2847 | + let alpha = (mask[maskIdx] << (x % 8)) & 0x80 ? 255 : 0; | |
| 2848 | + rgba[pixIdx ] = pixels[pixIdx + 2]; | |
| 2849 | + rgba[pixIdx + 1] = pixels[pixIdx + 1]; | |
| 2850 | + rgba[pixIdx + 2] = pixels[pixIdx]; | |
| 2851 | + rgba[pixIdx + 3] = alpha; | |
| 2852 | + pixIdx += 4; | |
| 2853 | + } | |
| 2854 | + } | |
| 2855 | + | |
| 2856 | + this._updateCursor(rgba, hotx, hoty, w, h); | |
| 2857 | + | |
| 2858 | + return true; | |
| 2859 | + } | |
| 2860 | + | |
| 2861 | + _handleDesktopName() { | |
| 2862 | + if (this._sock.rQwait("DesktopName", 4)) { | |
| 2863 | + return false; | |
| 2864 | + } | |
| 2865 | + | |
| 2866 | + let length = this._sock.rQshift32(); | |
| 2867 | + | |
| 2868 | + if (this._sock.rQwait("DesktopName", length, 4)) { | |
| 2869 | + return false; | |
| 2870 | + } | |
| 2871 | + | |
| 2872 | + let name = this._sock.rQshiftStr(length); | |
| 2873 | + name = decodeUTF8(name, true); | |
| 2874 | + | |
| 2875 | + this._setDesktopName(name); | |
| 2876 | + | |
| 2877 | + return true; | |
| 2878 | + } | |
| 2879 | + | |
| 2880 | + _handleLedEvent() { | |
| 2881 | + if (this._sock.rQwait("LED status", 1)) { | |
| 2882 | + return false; | |
| 2883 | + } | |
| 2884 | + | |
| 2885 | + let data = this._sock.rQshift8(); | |
| 2886 | + // ScrollLock state can be retrieved with data & 1. This is currently not needed. | |
| 2887 | + let numLock = data & 2 ? true : false; | |
| 2888 | + let capsLock = data & 4 ? true : false; | |
| 2889 | + this._remoteCapsLock = capsLock; | |
| 2890 | + this._remoteNumLock = numLock; | |
| 2891 | + | |
| 2892 | + return true; | |
| 2893 | + } | |
| 2894 | + | |
| 2895 | + _handleExtendedDesktopSize() { | |
| 2896 | + if (this._sock.rQwait("ExtendedDesktopSize", 4)) { | |
| 2897 | + return false; | |
| 2898 | + } | |
| 2899 | + | |
| 2900 | + const numberOfScreens = this._sock.rQpeek8(); | |
| 2901 | + | |
| 2902 | + let bytes = 4 + (numberOfScreens * 16); | |
| 2903 | + if (this._sock.rQwait("ExtendedDesktopSize", bytes)) { | |
| 2904 | + return false; | |
| 2905 | + } | |
| 2906 | + | |
| 2907 | + const firstUpdate = !this._supportsSetDesktopSize; | |
| 2908 | + this._supportsSetDesktopSize = true; | |
| 2909 | + | |
| 2910 | + this._sock.rQskipBytes(1); // number-of-screens | |
| 2911 | + this._sock.rQskipBytes(3); // padding | |
| 2912 | + | |
| 2913 | + for (let i = 0; i < numberOfScreens; i += 1) { | |
| 2914 | + // Save the id and flags of the first screen | |
| 2915 | + if (i === 0) { | |
| 2916 | + this._screenID = this._sock.rQshift32(); // id | |
| 2917 | + this._sock.rQskipBytes(2); // x-position | |
| 2918 | + this._sock.rQskipBytes(2); // y-position | |
| 2919 | + this._sock.rQskipBytes(2); // width | |
| 2920 | + this._sock.rQskipBytes(2); // height | |
| 2921 | + this._screenFlags = this._sock.rQshift32(); // flags | |
| 2922 | + } else { | |
| 2923 | + this._sock.rQskipBytes(16); | |
| 2924 | + } | |
| 2925 | + } | |
| 2926 | + | |
| 2927 | + /* | |
| 2928 | + * The x-position indicates the reason for the change: | |
| 2929 | + * | |
| 2930 | + * 0 - server resized on its own | |
| 2931 | + * 1 - this client requested the resize | |
| 2932 | + * 2 - another client requested the resize | |
| 2933 | + */ | |
| 2934 | + | |
| 2935 | + if (this._FBU.x === 1) { | |
| 2936 | + this._pendingRemoteResize = false; | |
| 2937 | + } | |
| 2938 | + | |
| 2939 | + // We need to handle errors when we requested the resize. | |
| 2940 | + if (this._FBU.x === 1 && this._FBU.y !== 0) { | |
| 2941 | + let msg = ""; | |
| 2942 | + // The y-position indicates the status code from the server | |
| 2943 | + switch (this._FBU.y) { | |
| 2944 | + case 1: | |
| 2945 | + msg = "Resize is administratively prohibited"; | |
| 2946 | + break; | |
| 2947 | + case 2: | |
| 2948 | + msg = "Out of resources"; | |
| 2949 | + break; | |
| 2950 | + case 3: | |
| 2951 | + msg = "Invalid screen layout"; | |
| 2952 | + break; | |
| 2953 | + default: | |
| 2954 | + msg = "Unknown reason"; | |
| 2955 | + break; | |
| 2956 | + } | |
| 2957 | + Log.Warn("Server did not accept the resize request: " | |
| 2958 | + + msg); | |
| 2959 | + } else { | |
| 2960 | + this._resize(this._FBU.width, this._FBU.height); | |
| 2961 | + } | |
| 2962 | + | |
| 2963 | + // Normally we only apply the current resize mode after a | |
| 2964 | + // window resize event. However there is no such trigger on the | |
| 2965 | + // initial connect. And we don't know if the server supports | |
| 2966 | + // resizing until we've gotten here. | |
| 2967 | + if (firstUpdate) { | |
| 2968 | + this._requestRemoteResize(); | |
| 2969 | + } | |
| 2970 | + | |
| 2971 | + if (this._FBU.x === 1 && this._FBU.y === 0) { | |
| 2972 | + // We might have resized again whilst waiting for the | |
| 2973 | + // previous request, so check if we are in sync | |
| 2974 | + this._requestRemoteResize(); | |
| 2975 | + } | |
| 2976 | + | |
| 2977 | + return true; | |
| 2978 | + } | |
| 2979 | + | |
| 2980 | + _handleDataRect() { | |
| 2981 | + let decoder = this._decoders[this._FBU.encoding]; | |
| 2982 | + if (!decoder) { | |
| 2983 | + this._fail("Unsupported encoding (encoding: " + | |
| 2984 | + this._FBU.encoding + ")"); | |
| 2985 | + return false; | |
| 2986 | + } | |
| 2987 | + | |
| 2988 | + try { | |
| 2989 | + return decoder.decodeRect(this._FBU.x, this._FBU.y, | |
| 2990 | + this._FBU.width, this._FBU.height, | |
| 2991 | + this._sock, this._display, | |
| 2992 | + this._fbDepth); | |
| 2993 | + } catch (err) { | |
| 2994 | + this._fail("Error decoding rect: " + err); | |
| 2995 | + return false; | |
| 2996 | + } | |
| 2997 | + } | |
| 2998 | + | |
| 2999 | + _updateContinuousUpdates() { | |
| 3000 | + if (!this._enabledContinuousUpdates) { return; } | |
| 3001 | + | |
| 3002 | + RFB.messages.enableContinuousUpdates(this._sock, true, 0, 0, | |
| 3003 | + this._fbWidth, this._fbHeight); | |
| 3004 | + } | |
| 3005 | + | |
| 3006 | + // Handle resize-messages from the server | |
| 3007 | + _resize(width, height) { | |
| 3008 | + this._fbWidth = width; | |
| 3009 | + this._fbHeight = height; | |
| 3010 | + | |
| 3011 | + this._display.resize(this._fbWidth, this._fbHeight); | |
| 3012 | + | |
| 3013 | + // Adjust the visible viewport based on the new dimensions | |
| 3014 | + this._updateClip(); | |
| 3015 | + this._updateScale(); | |
| 3016 | + | |
| 3017 | + this._updateContinuousUpdates(); | |
| 3018 | + | |
| 3019 | + // Keep this size until browser client size changes | |
| 3020 | + this._saveExpectedClientSize(); | |
| 3021 | + } | |
| 3022 | + | |
| 3023 | + _xvpOp(ver, op) { | |
| 3024 | + if (this._rfbXvpVer < ver) { return; } | |
| 3025 | + Log.Info("Sending XVP operation " + op + " (version " + ver + ")"); | |
| 3026 | + RFB.messages.xvpOp(this._sock, ver, op); | |
| 3027 | + } | |
| 3028 | + | |
| 3029 | + _updateCursor(rgba, hotx, hoty, w, h) { | |
| 3030 | + this._cursorImage = { | |
| 3031 | + rgbaPixels: rgba, | |
| 3032 | + hotx: hotx, hoty: hoty, w: w, h: h, | |
| 3033 | + }; | |
| 3034 | + this._refreshCursor(); | |
| 3035 | + } | |
| 3036 | + | |
| 3037 | + _shouldShowDotCursor() { | |
| 3038 | + // Called when this._cursorImage is updated | |
| 3039 | + if (!this._showDotCursor) { | |
| 3040 | + // User does not want to see the dot, so... | |
| 3041 | + return false; | |
| 3042 | + } | |
| 3043 | + | |
| 3044 | + // The dot should not be shown if the cursor is already visible, | |
| 3045 | + // i.e. contains at least one not-fully-transparent pixel. | |
| 3046 | + // So iterate through all alpha bytes in rgba and stop at the | |
| 3047 | + // first non-zero. | |
| 3048 | + for (let i = 3; i < this._cursorImage.rgbaPixels.length; i += 4) { | |
| 3049 | + if (this._cursorImage.rgbaPixels[i]) { | |
| 3050 | + return false; | |
| 3051 | + } | |
| 3052 | + } | |
| 3053 | + | |
| 3054 | + // At this point, we know that the cursor is fully transparent, and | |
| 3055 | + // the user wants to see the dot instead of this. | |
| 3056 | + return true; | |
| 3057 | + } | |
| 3058 | + | |
| 3059 | + _refreshCursor() { | |
| 3060 | + if (this._rfbConnectionState !== "connecting" && | |
| 3061 | + this._rfbConnectionState !== "connected") { | |
| 3062 | + return; | |
| 3063 | + } | |
| 3064 | + const image = this._shouldShowDotCursor() ? RFB.cursors.dot : this._cursorImage; | |
| 3065 | + this._cursor.change(image.rgbaPixels, | |
| 3066 | + image.hotx, image.hoty, | |
| 3067 | + image.w, image.h | |
| 3068 | + ); | |
| 3069 | + } | |
| 3070 | + | |
| 3071 | + static genDES(password, challenge) { | |
| 3072 | + const passwordChars = password.split('').map(c => c.charCodeAt(0)); | |
| 3073 | + const key = legacyCrypto.importKey( | |
| 3074 | + "raw", passwordChars, { name: "DES-ECB" }, false, ["encrypt"]); | |
| 3075 | + return legacyCrypto.encrypt({ name: "DES-ECB" }, key, challenge); | |
| 3076 | + } | |
| 3077 | +} | |
| 3078 | + | |
| 3079 | +// Class Methods | |
| 3080 | +RFB.messages = { | |
| 3081 | + keyEvent(sock, keysym, down) { | |
| 3082 | + sock.sQpush8(4); // msg-type | |
| 3083 | + sock.sQpush8(down); | |
| 3084 | + | |
| 3085 | + sock.sQpush16(0); | |
| 3086 | + | |
| 3087 | + sock.sQpush32(keysym); | |
| 3088 | + | |
| 3089 | + sock.flush(); | |
| 3090 | + }, | |
| 3091 | + | |
| 3092 | + QEMUExtendedKeyEvent(sock, keysym, down, keycode) { | |
| 3093 | + function getRFBkeycode(xtScanCode) { | |
| 3094 | + const upperByte = (keycode >> 8); | |
| 3095 | + const lowerByte = (keycode & 0x00ff); | |
| 3096 | + if (upperByte === 0xe0 && lowerByte < 0x7f) { | |
| 3097 | + return lowerByte | 0x80; | |
| 3098 | + } | |
| 3099 | + return xtScanCode; | |
| 3100 | + } | |
| 3101 | + | |
| 3102 | + sock.sQpush8(255); // msg-type | |
| 3103 | + sock.sQpush8(0); // sub msg-type | |
| 3104 | + | |
| 3105 | + sock.sQpush16(down); | |
| 3106 | + | |
| 3107 | + sock.sQpush32(keysym); | |
| 3108 | + | |
| 3109 | + const RFBkeycode = getRFBkeycode(keycode); | |
| 3110 | + | |
| 3111 | + sock.sQpush32(RFBkeycode); | |
| 3112 | + | |
| 3113 | + sock.flush(); | |
| 3114 | + }, | |
| 3115 | + | |
| 3116 | + pointerEvent(sock, x, y, mask) { | |
| 3117 | + sock.sQpush8(5); // msg-type | |
| 3118 | + | |
| 3119 | + // Marker bit must be set to 0, otherwise the server might | |
| 3120 | + // confuse the marker bit with the highest bit in a normal | |
| 3121 | + // PointerEvent message. | |
| 3122 | + mask = mask & 0x7f; | |
| 3123 | + sock.sQpush8(mask); | |
| 3124 | + | |
| 3125 | + sock.sQpush16(x); | |
| 3126 | + sock.sQpush16(y); | |
| 3127 | + | |
| 3128 | + sock.flush(); | |
| 3129 | + }, | |
| 3130 | + | |
| 3131 | + extendedPointerEvent(sock, x, y, mask) { | |
| 3132 | + sock.sQpush8(5); // msg-type | |
| 3133 | + | |
| 3134 | + let higherBits = (mask >> 7) & 0xff; | |
| 3135 | + | |
| 3136 | + // Bits 2-7 are reserved | |
| 3137 | + if (higherBits & 0xfc) { | |
| 3138 | + throw new Error("Invalid mouse button mask: " + mask); | |
| 3139 | + } | |
| 3140 | + | |
| 3141 | + let lowerBits = mask & 0x7f; | |
| 3142 | + lowerBits |= 0x80; // Set marker bit to 1 | |
| 3143 | + | |
| 3144 | + sock.sQpush8(lowerBits); | |
| 3145 | + sock.sQpush16(x); | |
| 3146 | + sock.sQpush16(y); | |
| 3147 | + sock.sQpush8(higherBits); | |
| 3148 | + | |
| 3149 | + sock.flush(); | |
| 3150 | + }, | |
| 3151 | + | |
| 3152 | + // Used to build Notify and Request data. | |
| 3153 | + _buildExtendedClipboardFlags(actions, formats) { | |
| 3154 | + let data = new Uint8Array(4); | |
| 3155 | + let formatFlag = 0x00000000; | |
| 3156 | + let actionFlag = 0x00000000; | |
| 3157 | + | |
| 3158 | + for (let i = 0; i < actions.length; i++) { | |
| 3159 | + actionFlag |= actions[i]; | |
| 3160 | + } | |
| 3161 | + | |
| 3162 | + for (let i = 0; i < formats.length; i++) { | |
| 3163 | + formatFlag |= formats[i]; | |
| 3164 | + } | |
| 3165 | + | |
| 3166 | + data[0] = actionFlag >> 24; // Actions | |
| 3167 | + data[1] = 0x00; // Reserved | |
| 3168 | + data[2] = 0x00; // Reserved | |
| 3169 | + data[3] = formatFlag; // Formats | |
| 3170 | + | |
| 3171 | + return data; | |
| 3172 | + }, | |
| 3173 | + | |
| 3174 | + extendedClipboardProvide(sock, formats, inData) { | |
| 3175 | + // Deflate incomming data and their sizes | |
| 3176 | + let deflator = new Deflator(); | |
| 3177 | + let dataToDeflate = []; | |
| 3178 | + | |
| 3179 | + for (let i = 0; i < formats.length; i++) { | |
| 3180 | + // We only support the format Text at this time | |
| 3181 | + if (formats[i] != extendedClipboardFormatText) { | |
| 3182 | + throw new Error("Unsupported extended clipboard format for Provide message."); | |
| 3183 | + } | |
| 3184 | + | |
| 3185 | + // Change lone \r or \n into \r\n as defined in rfbproto | |
| 3186 | + inData[i] = inData[i].replace(/\r\n|\r|\n/gm, "\r\n"); | |
| 3187 | + | |
| 3188 | + // Check if it already has \0 | |
| 3189 | + let text = encodeUTF8(inData[i] + "\0"); | |
| 3190 | + | |
| 3191 | + dataToDeflate.push( (text.length >> 24) & 0xFF, | |
| 3192 | + (text.length >> 16) & 0xFF, | |
| 3193 | + (text.length >> 8) & 0xFF, | |
| 3194 | + (text.length & 0xFF)); | |
| 3195 | + | |
| 3196 | + for (let j = 0; j < text.length; j++) { | |
| 3197 | + dataToDeflate.push(text.charCodeAt(j)); | |
| 3198 | + } | |
| 3199 | + } | |
| 3200 | + | |
| 3201 | + let deflatedData = deflator.deflate(new Uint8Array(dataToDeflate)); | |
| 3202 | + | |
| 3203 | + // Build data to send | |
| 3204 | + let data = new Uint8Array(4 + deflatedData.length); | |
| 3205 | + data.set(RFB.messages._buildExtendedClipboardFlags([extendedClipboardActionProvide], | |
| 3206 | + formats)); | |
| 3207 | + data.set(deflatedData, 4); | |
| 3208 | + | |
| 3209 | + RFB.messages.clientCutText(sock, data, true); | |
| 3210 | + }, | |
| 3211 | + | |
| 3212 | + extendedClipboardNotify(sock, formats) { | |
| 3213 | + let flags = RFB.messages._buildExtendedClipboardFlags([extendedClipboardActionNotify], | |
| 3214 | + formats); | |
| 3215 | + RFB.messages.clientCutText(sock, flags, true); | |
| 3216 | + }, | |
| 3217 | + | |
| 3218 | + extendedClipboardRequest(sock, formats) { | |
| 3219 | + let flags = RFB.messages._buildExtendedClipboardFlags([extendedClipboardActionRequest], | |
| 3220 | + formats); | |
| 3221 | + RFB.messages.clientCutText(sock, flags, true); | |
| 3222 | + }, | |
| 3223 | + | |
| 3224 | + extendedClipboardCaps(sock, actions, formats) { | |
| 3225 | + let formatKeys = Object.keys(formats); | |
| 3226 | + let data = new Uint8Array(4 + (4 * formatKeys.length)); | |
| 3227 | + | |
| 3228 | + formatKeys.map(x => parseInt(x)); | |
| 3229 | + formatKeys.sort((a, b) => a - b); | |
| 3230 | + | |
| 3231 | + data.set(RFB.messages._buildExtendedClipboardFlags(actions, [])); | |
| 3232 | + | |
| 3233 | + let loopOffset = 4; | |
| 3234 | + for (let i = 0; i < formatKeys.length; i++) { | |
| 3235 | + data[loopOffset] = formats[formatKeys[i]] >> 24; | |
| 3236 | + data[loopOffset + 1] = formats[formatKeys[i]] >> 16; | |
| 3237 | + data[loopOffset + 2] = formats[formatKeys[i]] >> 8; | |
| 3238 | + data[loopOffset + 3] = formats[formatKeys[i]] >> 0; | |
| 3239 | + | |
| 3240 | + loopOffset += 4; | |
| 3241 | + data[3] |= (1 << formatKeys[i]); // Update our format flags | |
| 3242 | + } | |
| 3243 | + | |
| 3244 | + RFB.messages.clientCutText(sock, data, true); | |
| 3245 | + }, | |
| 3246 | + | |
| 3247 | + clientCutText(sock, data, extended = false) { | |
| 3248 | + sock.sQpush8(6); // msg-type | |
| 3249 | + | |
| 3250 | + sock.sQpush8(0); // padding | |
| 3251 | + sock.sQpush8(0); // padding | |
| 3252 | + sock.sQpush8(0); // padding | |
| 3253 | + | |
| 3254 | + let length; | |
| 3255 | + if (extended) { | |
| 3256 | + length = toUnsigned32bit(-data.length); | |
| 3257 | + } else { | |
| 3258 | + length = data.length; | |
| 3259 | + } | |
| 3260 | + | |
| 3261 | + sock.sQpush32(length); | |
| 3262 | + sock.sQpushBytes(data); | |
| 3263 | + sock.flush(); | |
| 3264 | + }, | |
| 3265 | + | |
| 3266 | + setDesktopSize(sock, width, height, id, flags) { | |
| 3267 | + sock.sQpush8(251); // msg-type | |
| 3268 | + | |
| 3269 | + sock.sQpush8(0); // padding | |
| 3270 | + | |
| 3271 | + sock.sQpush16(width); | |
| 3272 | + sock.sQpush16(height); | |
| 3273 | + | |
| 3274 | + sock.sQpush8(1); // number-of-screens | |
| 3275 | + | |
| 3276 | + sock.sQpush8(0); // padding | |
| 3277 | + | |
| 3278 | + // screen array | |
| 3279 | + sock.sQpush32(id); | |
| 3280 | + sock.sQpush16(0); // x-position | |
| 3281 | + sock.sQpush16(0); // y-position | |
| 3282 | + sock.sQpush16(width); | |
| 3283 | + sock.sQpush16(height); | |
| 3284 | + sock.sQpush32(flags); | |
| 3285 | + | |
| 3286 | + sock.flush(); | |
| 3287 | + }, | |
| 3288 | + | |
| 3289 | + clientFence(sock, flags, payload) { | |
| 3290 | + sock.sQpush8(248); // msg-type | |
| 3291 | + | |
| 3292 | + sock.sQpush8(0); // padding | |
| 3293 | + sock.sQpush8(0); // padding | |
| 3294 | + sock.sQpush8(0); // padding | |
| 3295 | + | |
| 3296 | + sock.sQpush32(flags); | |
| 3297 | + | |
| 3298 | + sock.sQpush8(payload.length); | |
| 3299 | + sock.sQpushString(payload); | |
| 3300 | + | |
| 3301 | + sock.flush(); | |
| 3302 | + }, | |
| 3303 | + | |
| 3304 | + enableContinuousUpdates(sock, enable, x, y, width, height) { | |
| 3305 | + sock.sQpush8(150); // msg-type | |
| 3306 | + | |
| 3307 | + sock.sQpush8(enable); | |
| 3308 | + | |
| 3309 | + sock.sQpush16(x); | |
| 3310 | + sock.sQpush16(y); | |
| 3311 | + sock.sQpush16(width); | |
| 3312 | + sock.sQpush16(height); | |
| 3313 | + | |
| 3314 | + sock.flush(); | |
| 3315 | + }, | |
| 3316 | + | |
| 3317 | + pixelFormat(sock, depth, trueColor) { | |
| 3318 | + let bpp; | |
| 3319 | + | |
| 3320 | + if (depth > 16) { | |
| 3321 | + bpp = 32; | |
| 3322 | + } else if (depth > 8) { | |
| 3323 | + bpp = 16; | |
| 3324 | + } else { | |
| 3325 | + bpp = 8; | |
| 3326 | + } | |
| 3327 | + | |
| 3328 | + const bits = Math.floor(depth/3); | |
| 3329 | + | |
| 3330 | + sock.sQpush8(0); // msg-type | |
| 3331 | + | |
| 3332 | + sock.sQpush8(0); // padding | |
| 3333 | + sock.sQpush8(0); // padding | |
| 3334 | + sock.sQpush8(0); // padding | |
| 3335 | + | |
| 3336 | + sock.sQpush8(bpp); | |
| 3337 | + sock.sQpush8(depth); | |
| 3338 | + sock.sQpush8(0); // little-endian | |
| 3339 | + sock.sQpush8(trueColor ? 1 : 0); | |
| 3340 | + | |
| 3341 | + sock.sQpush16((1 << bits) - 1); // red-max | |
| 3342 | + sock.sQpush16((1 << bits) - 1); // green-max | |
| 3343 | + sock.sQpush16((1 << bits) - 1); // blue-max | |
| 3344 | + | |
| 3345 | + sock.sQpush8(bits * 0); // red-shift | |
| 3346 | + sock.sQpush8(bits * 1); // green-shift | |
| 3347 | + sock.sQpush8(bits * 2); // blue-shift | |
| 3348 | + | |
| 3349 | + sock.sQpush8(0); // padding | |
| 3350 | + sock.sQpush8(0); // padding | |
| 3351 | + sock.sQpush8(0); // padding | |
| 3352 | + | |
| 3353 | + sock.flush(); | |
| 3354 | + }, | |
| 3355 | + | |
| 3356 | + clientEncodings(sock, encodings) { | |
| 3357 | + sock.sQpush8(2); // msg-type | |
| 3358 | + | |
| 3359 | + sock.sQpush8(0); // padding | |
| 3360 | + | |
| 3361 | + sock.sQpush16(encodings.length); | |
| 3362 | + for (let i = 0; i < encodings.length; i++) { | |
| 3363 | + sock.sQpush32(encodings[i]); | |
| 3364 | + } | |
| 3365 | + | |
| 3366 | + sock.flush(); | |
| 3367 | + }, | |
| 3368 | + | |
| 3369 | + fbUpdateRequest(sock, incremental, x, y, w, h) { | |
| 3370 | + if (typeof(x) === "undefined") { x = 0; } | |
| 3371 | + if (typeof(y) === "undefined") { y = 0; } | |
| 3372 | + | |
| 3373 | + sock.sQpush8(3); // msg-type | |
| 3374 | + | |
| 3375 | + sock.sQpush8(incremental ? 1 : 0); | |
| 3376 | + | |
| 3377 | + sock.sQpush16(x); | |
| 3378 | + sock.sQpush16(y); | |
| 3379 | + sock.sQpush16(w); | |
| 3380 | + sock.sQpush16(h); | |
| 3381 | + | |
| 3382 | + sock.flush(); | |
| 3383 | + }, | |
| 3384 | + | |
| 3385 | + xvpOp(sock, ver, op) { | |
| 3386 | + sock.sQpush8(250); // msg-type | |
| 3387 | + | |
| 3388 | + sock.sQpush8(0); // padding | |
| 3389 | + | |
| 3390 | + sock.sQpush8(ver); | |
| 3391 | + sock.sQpush8(op); | |
| 3392 | + | |
| 3393 | + sock.flush(); | |
| 3394 | + } | |
| 3395 | +}; | |
| 3396 | + | |
| 3397 | +RFB.cursors = { | |
| 3398 | + none: { | |
| 3399 | + rgbaPixels: new Uint8Array(), | |
| 3400 | + w: 0, h: 0, | |
| 3401 | + hotx: 0, hoty: 0, | |
| 3402 | + }, | |
| 3403 | + | |
| 3404 | + dot: { | |
| 3405 | + /* eslint-disable indent */ | |
| 3406 | + rgbaPixels: new Uint8Array([ | |
| 3407 | + 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, | |
| 3408 | + 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, | |
| 3409 | + 255, 255, 255, 255, 0, 0, 0, 255, 255, 255, 255, 255, | |
| 3410 | + ]), | |
| 3411 | + /* eslint-enable indent */ | |
| 3412 | + w: 3, h: 3, | |
| 3413 | + hotx: 1, hoty: 1, | |
| 3414 | + } | |
| 3415 | +}; | |
added
public/vendor/novnc/core/util/browser.js
+233 −0
@@ -0,0 +1,233 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + * | |
| 8 | + * Browser feature support detection | |
| 9 | + */ | |
| 10 | + | |
| 11 | +import * as Log from './logging.js'; | |
| 12 | +import Base64 from '../base64.js'; | |
| 13 | + | |
| 14 | +// Touch detection | |
| 15 | +export let isTouchDevice = ('ontouchstart' in document.documentElement) || | |
| 16 | + // required for Chrome debugger | |
| 17 | + (document.ontouchstart !== undefined) || | |
| 18 | + // required for MS Surface | |
| 19 | + (navigator.maxTouchPoints > 0) || | |
| 20 | + (navigator.msMaxTouchPoints > 0); | |
| 21 | +window.addEventListener('touchstart', function onFirstTouch() { | |
| 22 | + isTouchDevice = true; | |
| 23 | + window.removeEventListener('touchstart', onFirstTouch, false); | |
| 24 | +}, false); | |
| 25 | + | |
| 26 | + | |
| 27 | +// The goal is to find a certain physical width, the devicePixelRatio | |
| 28 | +// brings us a bit closer but is not optimal. | |
| 29 | +export let dragThreshold = 10 * (window.devicePixelRatio || 1); | |
| 30 | + | |
| 31 | +let _supportsCursorURIs = false; | |
| 32 | + | |
| 33 | +try { | |
| 34 | + const target = document.createElement('canvas'); | |
| 35 | + target.style.cursor = 'url("data:image/x-icon;base64,AAACAAEACAgAAAIAAgA4AQAAFgAAACgAAAAIAAAAEAAAAAEAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAAAAAAAAAAAAAAAAAAAA==") 2 2, default'; | |
| 36 | + | |
| 37 | + if (target.style.cursor.indexOf("url") === 0) { | |
| 38 | + Log.Info("Data URI scheme cursor supported"); | |
| 39 | + _supportsCursorURIs = true; | |
| 40 | + } else { | |
| 41 | + Log.Warn("Data URI scheme cursor not supported"); | |
| 42 | + } | |
| 43 | +} catch (exc) { | |
| 44 | + Log.Error("Data URI scheme cursor test exception: " + exc); | |
| 45 | +} | |
| 46 | + | |
| 47 | +export const supportsCursorURIs = _supportsCursorURIs; | |
| 48 | + | |
| 49 | +let _hasScrollbarGutter = true; | |
| 50 | +try { | |
| 51 | + // Create invisible container | |
| 52 | + const container = document.createElement('div'); | |
| 53 | + container.style.visibility = 'hidden'; | |
| 54 | + container.style.overflow = 'scroll'; // forcing scrollbars | |
| 55 | + document.body.appendChild(container); | |
| 56 | + | |
| 57 | + // Create a div and place it in the container | |
| 58 | + const child = document.createElement('div'); | |
| 59 | + container.appendChild(child); | |
| 60 | + | |
| 61 | + // Calculate the difference between the container's full width | |
| 62 | + // and the child's width - the difference is the scrollbars | |
| 63 | + const scrollbarWidth = (container.offsetWidth - child.offsetWidth); | |
| 64 | + | |
| 65 | + // Clean up | |
| 66 | + container.parentNode.removeChild(container); | |
| 67 | + | |
| 68 | + _hasScrollbarGutter = scrollbarWidth != 0; | |
| 69 | +} catch (exc) { | |
| 70 | + Log.Error("Scrollbar test exception: " + exc); | |
| 71 | +} | |
| 72 | +export const hasScrollbarGutter = _hasScrollbarGutter; | |
| 73 | + | |
| 74 | +export let supportsWebCodecsH264Decode = false; | |
| 75 | + | |
| 76 | +async function _checkWebCodecsH264DecodeSupport() { | |
| 77 | + if (!('VideoDecoder' in window)) { | |
| 78 | + return false; | |
| 79 | + } | |
| 80 | + | |
| 81 | + // We'll need to make do with some placeholders here | |
| 82 | + const config = { | |
| 83 | + codec: 'avc1.42401f', | |
| 84 | + codedWidth: 1920, | |
| 85 | + codedHeight: 1080, | |
| 86 | + optimizeForLatency: true, | |
| 87 | + }; | |
| 88 | + | |
| 89 | + let support = await VideoDecoder.isConfigSupported(config); | |
| 90 | + if (!support.supported) { | |
| 91 | + return false; | |
| 92 | + } | |
| 93 | + | |
| 94 | + // Firefox incorrectly reports supports for H.264 under some | |
| 95 | + // circumstances, so we need to actually test a real frame | |
| 96 | + // https://bugzilla.mozilla.org/show_bug.cgi?id=1932392 | |
| 97 | + | |
| 98 | + const data = new Uint8Array(Base64.decode( | |
| 99 | + 'AAAAAWdCwBTZnpuAgICgAAADACAAAAZB4oVNAAAAAWjJYyyAAAABBgX//4Hc' + | |
| 100 | + 'Rem95tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTY0IHIzMTA4IDMxZTE5Zjkg' + | |
| 101 | + 'LSBILjI2NC9NUEVHLTQgQVZDIGNvZGVjIC0gQ29weWxlZnQgMjAwMy0yMDIz' + | |
| 102 | + 'IC0gaHR0cDovL3d3dy52aWRlb2xhbi5vcmcveDI2NC5odG1sIC0gb3B0aW9u' + | |
| 103 | + 'czogY2FiYWM9MCByZWY9NSBkZWJsb2NrPTE6MDowIGFuYWx5c2U9MHgxOjB4' + | |
| 104 | + 'MTExIG1lPWhleCBzdWJtZT04IHBzeT0xIHBzeV9yZD0xLjAwOjAuMDAgbWl4' + | |
| 105 | + 'ZWRfcmVmPTEgbWVfcmFuZ2U9MTYgY2hyb21hX21lPTEgdHJlbGxpcz0yIDh4' + | |
| 106 | + 'OGRjdD0wIGNxbT0wIGRlYWR6b25lPTIxLDExIGZhc3RfcHNraXA9MSBjaHJv' + | |
| 107 | + 'bWFfcXBfb2Zmc2V0PS0yIHRocmVhZHM9MSBsb29rYWhlYWRfdGhyZWFkcz0x' + | |
| 108 | + 'IHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9' + | |
| 109 | + 'MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVz' + | |
| 110 | + 'PTAgd2VpZ2h0cD0wIGtleWludD1pbmZpbml0ZSBrZXlpbnRfbWluPTI1IHNj' + | |
| 111 | + 'ZW5lY3V0PTQwIGludHJhX3JlZnJlc2g9MCByY19sb29rYWhlYWQ9NTAgcmM9' + | |
| 112 | + 'YWJyIG1idHJlZT0xIGJpdHJhdGU9NDAwIHJhdGV0b2w9MS4wIHFjb21wPTAu' + | |
| 113 | + 'NjAgcXBtaW49MCBxcG1heD02OSBxcHN0ZXA9NCBpcF9yYXRpbz0xLjQwIGFx' + | |
| 114 | + 'PTE6MS4wMACAAAABZYiEBrxmKAAPVccAAS044AA5DRJMnkycJk4TPw==')); | |
| 115 | + | |
| 116 | + let gotframe = false; | |
| 117 | + let error = null; | |
| 118 | + | |
| 119 | + let decoder = new VideoDecoder({ | |
| 120 | + output: (frame) => { gotframe = true; }, | |
| 121 | + error: (e) => { error = e; }, | |
| 122 | + }); | |
| 123 | + let chunk = new EncodedVideoChunk({ | |
| 124 | + timestamp: 0, | |
| 125 | + type: 'key', | |
| 126 | + data: data, | |
| 127 | + }); | |
| 128 | + | |
| 129 | + decoder.configure(config); | |
| 130 | + decoder.decode(chunk); | |
| 131 | + try { | |
| 132 | + await decoder.flush(); | |
| 133 | + } catch (e) { | |
| 134 | + // Firefox incorrectly throws an exception here | |
| 135 | + // https://bugzilla.mozilla.org/show_bug.cgi?id=1932566 | |
| 136 | + error = e; | |
| 137 | + } | |
| 138 | + | |
| 139 | + // Firefox fails to deliver the error on Windows, so we need to | |
| 140 | + // check if we got a frame instead | |
| 141 | + // https://bugzilla.mozilla.org/show_bug.cgi?id=1932579 | |
| 142 | + if (!gotframe) { | |
| 143 | + return false; | |
| 144 | + } | |
| 145 | + | |
| 146 | + if (error !== null) { | |
| 147 | + return false; | |
| 148 | + } | |
| 149 | + | |
| 150 | + return true; | |
| 151 | +} | |
| 152 | +supportsWebCodecsH264Decode = await _checkWebCodecsH264DecodeSupport(); | |
| 153 | + | |
| 154 | +/* | |
| 155 | + * The functions for detection of platforms and browsers below are exported | |
| 156 | + * but the use of these should be minimized as much as possible. | |
| 157 | + * | |
| 158 | + * It's better to use feature detection than platform detection. | |
| 159 | + */ | |
| 160 | + | |
| 161 | +/* OS */ | |
| 162 | + | |
| 163 | +export function isMac() { | |
| 164 | + return !!(/mac/i).exec(navigator.platform); | |
| 165 | +} | |
| 166 | + | |
| 167 | +export function isWindows() { | |
| 168 | + return !!(/win/i).exec(navigator.platform); | |
| 169 | +} | |
| 170 | + | |
| 171 | +export function isIOS() { | |
| 172 | + return (!!(/ipad/i).exec(navigator.platform) || | |
| 173 | + !!(/iphone/i).exec(navigator.platform) || | |
| 174 | + !!(/ipod/i).exec(navigator.platform)); | |
| 175 | +} | |
| 176 | + | |
| 177 | +export function isAndroid() { | |
| 178 | + /* Android sets navigator.platform to Linux :/ */ | |
| 179 | + return !!navigator.userAgent.match('Android '); | |
| 180 | +} | |
| 181 | + | |
| 182 | +export function isChromeOS() { | |
| 183 | + /* ChromeOS sets navigator.platform to Linux :/ */ | |
| 184 | + return !!navigator.userAgent.match(' CrOS '); | |
| 185 | +} | |
| 186 | + | |
| 187 | +/* Browser */ | |
| 188 | + | |
| 189 | +export function isSafari() { | |
| 190 | + return !!navigator.userAgent.match('Safari/...') && | |
| 191 | + !navigator.userAgent.match('Chrome/...') && | |
| 192 | + !navigator.userAgent.match('Chromium/...') && | |
| 193 | + !navigator.userAgent.match('Epiphany/...'); | |
| 194 | +} | |
| 195 | + | |
| 196 | +export function isFirefox() { | |
| 197 | + return !!navigator.userAgent.match('Firefox/...') && | |
| 198 | + !navigator.userAgent.match('Seamonkey/...'); | |
| 199 | +} | |
| 200 | + | |
| 201 | +export function isChrome() { | |
| 202 | + return !!navigator.userAgent.match('Chrome/...') && | |
| 203 | + !navigator.userAgent.match('Chromium/...') && | |
| 204 | + !navigator.userAgent.match('Edg/...') && | |
| 205 | + !navigator.userAgent.match('OPR/...'); | |
| 206 | +} | |
| 207 | + | |
| 208 | +export function isChromium() { | |
| 209 | + return !!navigator.userAgent.match('Chromium/...'); | |
| 210 | +} | |
| 211 | + | |
| 212 | +export function isOpera() { | |
| 213 | + return !!navigator.userAgent.match('OPR/...'); | |
| 214 | +} | |
| 215 | + | |
| 216 | +export function isEdge() { | |
| 217 | + return !!navigator.userAgent.match('Edg/...'); | |
| 218 | +} | |
| 219 | + | |
| 220 | +/* Engine */ | |
| 221 | + | |
| 222 | +export function isGecko() { | |
| 223 | + return !!navigator.userAgent.match('Gecko/...'); | |
| 224 | +} | |
| 225 | + | |
| 226 | +export function isWebKit() { | |
| 227 | + return !!navigator.userAgent.match('AppleWebKit/...') && | |
| 228 | + !navigator.userAgent.match('Chrome/...'); | |
| 229 | +} | |
| 230 | + | |
| 231 | +export function isBlink() { | |
| 232 | + return !!navigator.userAgent.match('Chrome/...'); | |
| 233 | +} | |
added
public/vendor/novnc/core/util/cursor.js
+249 −0
@@ -0,0 +1,249 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | |
| 5 | + */ | |
| 6 | + | |
| 7 | +import { supportsCursorURIs, isTouchDevice } from './browser.js'; | |
| 8 | + | |
| 9 | +const useFallback = !supportsCursorURIs || isTouchDevice; | |
| 10 | + | |
| 11 | +export default class Cursor { | |
| 12 | + constructor() { | |
| 13 | + this._target = null; | |
| 14 | + | |
| 15 | + this._canvas = document.createElement('canvas'); | |
| 16 | + | |
| 17 | + if (useFallback) { | |
| 18 | + this._canvas.style.position = 'fixed'; | |
| 19 | + this._canvas.style.zIndex = '65535'; | |
| 20 | + this._canvas.style.pointerEvents = 'none'; | |
| 21 | + // Safari on iOS can select the cursor image | |
| 22 | + // https://bugs.webkit.org/show_bug.cgi?id=249223 | |
| 23 | + this._canvas.style.userSelect = 'none'; | |
| 24 | + this._canvas.style.WebkitUserSelect = 'none'; | |
| 25 | + // Can't use "display" because of Firefox bug #1445997 | |
| 26 | + this._canvas.style.visibility = 'hidden'; | |
| 27 | + } | |
| 28 | + | |
| 29 | + this._position = { x: 0, y: 0 }; | |
| 30 | + this._hotSpot = { x: 0, y: 0 }; | |
| 31 | + | |
| 32 | + this._eventHandlers = { | |
| 33 | + 'mouseover': this._handleMouseOver.bind(this), | |
| 34 | + 'mouseleave': this._handleMouseLeave.bind(this), | |
| 35 | + 'mousemove': this._handleMouseMove.bind(this), | |
| 36 | + 'mouseup': this._handleMouseUp.bind(this), | |
| 37 | + }; | |
| 38 | + } | |
| 39 | + | |
| 40 | + attach(target) { | |
| 41 | + if (this._target) { | |
| 42 | + this.detach(); | |
| 43 | + } | |
| 44 | + | |
| 45 | + this._target = target; | |
| 46 | + | |
| 47 | + if (useFallback) { | |
| 48 | + document.body.appendChild(this._canvas); | |
| 49 | + | |
| 50 | + const options = { capture: true, passive: true }; | |
| 51 | + this._target.addEventListener('mouseover', this._eventHandlers.mouseover, options); | |
| 52 | + this._target.addEventListener('mouseleave', this._eventHandlers.mouseleave, options); | |
| 53 | + this._target.addEventListener('mousemove', this._eventHandlers.mousemove, options); | |
| 54 | + this._target.addEventListener('mouseup', this._eventHandlers.mouseup, options); | |
| 55 | + } | |
| 56 | + | |
| 57 | + this.clear(); | |
| 58 | + } | |
| 59 | + | |
| 60 | + detach() { | |
| 61 | + if (!this._target) { | |
| 62 | + return; | |
| 63 | + } | |
| 64 | + | |
| 65 | + if (useFallback) { | |
| 66 | + const options = { capture: true, passive: true }; | |
| 67 | + this._target.removeEventListener('mouseover', this._eventHandlers.mouseover, options); | |
| 68 | + this._target.removeEventListener('mouseleave', this._eventHandlers.mouseleave, options); | |
| 69 | + this._target.removeEventListener('mousemove', this._eventHandlers.mousemove, options); | |
| 70 | + this._target.removeEventListener('mouseup', this._eventHandlers.mouseup, options); | |
| 71 | + | |
| 72 | + if (document.contains(this._canvas)) { | |
| 73 | + document.body.removeChild(this._canvas); | |
| 74 | + } | |
| 75 | + } | |
| 76 | + | |
| 77 | + this._target = null; | |
| 78 | + } | |
| 79 | + | |
| 80 | + change(rgba, hotx, hoty, w, h) { | |
| 81 | + if ((w === 0) || (h === 0)) { | |
| 82 | + this.clear(); | |
| 83 | + return; | |
| 84 | + } | |
| 85 | + | |
| 86 | + this._position.x = this._position.x + this._hotSpot.x - hotx; | |
| 87 | + this._position.y = this._position.y + this._hotSpot.y - hoty; | |
| 88 | + this._hotSpot.x = hotx; | |
| 89 | + this._hotSpot.y = hoty; | |
| 90 | + | |
| 91 | + let ctx = this._canvas.getContext('2d'); | |
| 92 | + | |
| 93 | + this._canvas.width = w; | |
| 94 | + this._canvas.height = h; | |
| 95 | + | |
| 96 | + let img = new ImageData(new Uint8ClampedArray(rgba), w, h); | |
| 97 | + ctx.clearRect(0, 0, w, h); | |
| 98 | + ctx.putImageData(img, 0, 0); | |
| 99 | + | |
| 100 | + if (useFallback) { | |
| 101 | + this._updatePosition(); | |
| 102 | + } else { | |
| 103 | + let url = this._canvas.toDataURL(); | |
| 104 | + this._target.style.cursor = 'url(' + url + ')' + hotx + ' ' + hoty + ', default'; | |
| 105 | + } | |
| 106 | + } | |
| 107 | + | |
| 108 | + clear() { | |
| 109 | + this._target.style.cursor = 'none'; | |
| 110 | + this._canvas.width = 0; | |
| 111 | + this._canvas.height = 0; | |
| 112 | + this._position.x = this._position.x + this._hotSpot.x; | |
| 113 | + this._position.y = this._position.y + this._hotSpot.y; | |
| 114 | + this._hotSpot.x = 0; | |
| 115 | + this._hotSpot.y = 0; | |
| 116 | + } | |
| 117 | + | |
| 118 | + // Mouse events might be emulated, this allows | |
| 119 | + // moving the cursor in such cases | |
| 120 | + move(clientX, clientY) { | |
| 121 | + if (!useFallback) { | |
| 122 | + return; | |
| 123 | + } | |
| 124 | + // clientX/clientY are relative the _visual viewport_, | |
| 125 | + // but our position is relative the _layout viewport_, | |
| 126 | + // so try to compensate when we can | |
| 127 | + if (window.visualViewport) { | |
| 128 | + this._position.x = clientX + window.visualViewport.offsetLeft; | |
| 129 | + this._position.y = clientY + window.visualViewport.offsetTop; | |
| 130 | + } else { | |
| 131 | + this._position.x = clientX; | |
| 132 | + this._position.y = clientY; | |
| 133 | + } | |
| 134 | + this._updatePosition(); | |
| 135 | + let target = document.elementFromPoint(clientX, clientY); | |
| 136 | + this._updateVisibility(target); | |
| 137 | + } | |
| 138 | + | |
| 139 | + _handleMouseOver(event) { | |
| 140 | + // This event could be because we're entering the target, or | |
| 141 | + // moving around amongst its sub elements. Let the move handler | |
| 142 | + // sort things out. | |
| 143 | + this._handleMouseMove(event); | |
| 144 | + } | |
| 145 | + | |
| 146 | + _handleMouseLeave(event) { | |
| 147 | + // Check if we should show the cursor on the element we are leaving to | |
| 148 | + this._updateVisibility(event.relatedTarget); | |
| 149 | + } | |
| 150 | + | |
| 151 | + _handleMouseMove(event) { | |
| 152 | + this._updateVisibility(event.target); | |
| 153 | + | |
| 154 | + this._position.x = event.clientX - this._hotSpot.x; | |
| 155 | + this._position.y = event.clientY - this._hotSpot.y; | |
| 156 | + | |
| 157 | + this._updatePosition(); | |
| 158 | + } | |
| 159 | + | |
| 160 | + _handleMouseUp(event) { | |
| 161 | + // We might get this event because of a drag operation that | |
| 162 | + // moved outside of the target. Check what's under the cursor | |
| 163 | + // now and adjust visibility based on that. | |
| 164 | + let target = document.elementFromPoint(event.clientX, event.clientY); | |
| 165 | + this._updateVisibility(target); | |
| 166 | + | |
| 167 | + // Captures end with a mouseup but we can't know the event order of | |
| 168 | + // mouseup vs releaseCapture. | |
| 169 | + // | |
| 170 | + // In the cases when releaseCapture comes first, the code above is | |
| 171 | + // enough. | |
| 172 | + // | |
| 173 | + // In the cases when the mouseup comes first, we need wait for the | |
| 174 | + // browser to flush all events and then check again if the cursor | |
| 175 | + // should be visible. | |
| 176 | + if (this._captureIsActive()) { | |
| 177 | + window.setTimeout(() => { | |
| 178 | + // We might have detached at this point | |
| 179 | + if (!this._target) { | |
| 180 | + return; | |
| 181 | + } | |
| 182 | + // Refresh the target from elementFromPoint since queued events | |
| 183 | + // might have altered the DOM | |
| 184 | + target = document.elementFromPoint(event.clientX, | |
| 185 | + event.clientY); | |
| 186 | + this._updateVisibility(target); | |
| 187 | + }, 0); | |
| 188 | + } | |
| 189 | + } | |
| 190 | + | |
| 191 | + _showCursor() { | |
| 192 | + if (this._canvas.style.visibility === 'hidden') { | |
| 193 | + this._canvas.style.visibility = ''; | |
| 194 | + } | |
| 195 | + } | |
| 196 | + | |
| 197 | + _hideCursor() { | |
| 198 | + if (this._canvas.style.visibility !== 'hidden') { | |
| 199 | + this._canvas.style.visibility = 'hidden'; | |
| 200 | + } | |
| 201 | + } | |
| 202 | + | |
| 203 | + // Should we currently display the cursor? | |
| 204 | + // (i.e. are we over the target, or a child of the target without a | |
| 205 | + // different cursor set) | |
| 206 | + _shouldShowCursor(target) { | |
| 207 | + if (!target) { | |
| 208 | + return false; | |
| 209 | + } | |
| 210 | + // Easy case | |
| 211 | + if (target === this._target) { | |
| 212 | + return true; | |
| 213 | + } | |
| 214 | + // Other part of the DOM? | |
| 215 | + if (!this._target.contains(target)) { | |
| 216 | + return false; | |
| 217 | + } | |
| 218 | + // Has the child its own cursor? | |
| 219 | + // FIXME: How can we tell that a sub element has an | |
| 220 | + // explicit "cursor: none;"? | |
| 221 | + if (window.getComputedStyle(target).cursor !== 'none') { | |
| 222 | + return false; | |
| 223 | + } | |
| 224 | + return true; | |
| 225 | + } | |
| 226 | + | |
| 227 | + _updateVisibility(target) { | |
| 228 | + // When the cursor target has capture we want to show the cursor. | |
| 229 | + // So, if a capture is active - look at the captured element instead. | |
| 230 | + if (this._captureIsActive()) { | |
| 231 | + target = document.captureElement; | |
| 232 | + } | |
| 233 | + if (this._shouldShowCursor(target)) { | |
| 234 | + this._showCursor(); | |
| 235 | + } else { | |
| 236 | + this._hideCursor(); | |
| 237 | + } | |
| 238 | + } | |
| 239 | + | |
| 240 | + _updatePosition() { | |
| 241 | + this._canvas.style.left = this._position.x + "px"; | |
| 242 | + this._canvas.style.top = this._position.y + "px"; | |
| 243 | + } | |
| 244 | + | |
| 245 | + _captureIsActive() { | |
| 246 | + return document.captureElement && | |
| 247 | + document.documentElement.contains(document.captureElement); | |
| 248 | + } | |
| 249 | +} | |
added
public/vendor/novnc/core/util/element.js
+32 −0
@@ -0,0 +1,32 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2020 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * HTML element utility functions | |
| 11 | + */ | |
| 12 | + | |
| 13 | +export function clientToElement(x, y, elem) { | |
| 14 | + const bounds = elem.getBoundingClientRect(); | |
| 15 | + let pos = { x: 0, y: 0 }; | |
| 16 | + // Clip to target bounds | |
| 17 | + if (x < bounds.left) { | |
| 18 | + pos.x = 0; | |
| 19 | + } else if (x >= bounds.right) { | |
| 20 | + pos.x = bounds.width - 1; | |
| 21 | + } else { | |
| 22 | + pos.x = x - bounds.left; | |
| 23 | + } | |
| 24 | + if (y < bounds.top) { | |
| 25 | + pos.y = 0; | |
| 26 | + } else if (y >= bounds.bottom) { | |
| 27 | + pos.y = bounds.height - 1; | |
| 28 | + } else { | |
| 29 | + pos.y = y - bounds.top; | |
| 30 | + } | |
| 31 | + return pos; | |
| 32 | +} | |
added
public/vendor/novnc/core/util/events.js
+138 −0
@@ -0,0 +1,138 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2018 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * Cross-browser event and position routines | |
| 11 | + */ | |
| 12 | + | |
| 13 | +export function getPointerEvent(e) { | |
| 14 | + return e.changedTouches ? e.changedTouches[0] : e.touches ? e.touches[0] : e; | |
| 15 | +} | |
| 16 | + | |
| 17 | +export function stopEvent(e) { | |
| 18 | + e.stopPropagation(); | |
| 19 | + e.preventDefault(); | |
| 20 | +} | |
| 21 | + | |
| 22 | +// Emulate Element.setCapture() when not supported | |
| 23 | +let _captureRecursion = false; | |
| 24 | +let _elementForUnflushedEvents = null; | |
| 25 | +document.captureElement = null; | |
| 26 | +function _captureProxy(e) { | |
| 27 | + // Recursion protection as we'll see our own event | |
| 28 | + if (_captureRecursion) return; | |
| 29 | + | |
| 30 | + // Clone the event as we cannot dispatch an already dispatched event | |
| 31 | + const newEv = new e.constructor(e.type, e); | |
| 32 | + | |
| 33 | + _captureRecursion = true; | |
| 34 | + if (document.captureElement) { | |
| 35 | + document.captureElement.dispatchEvent(newEv); | |
| 36 | + } else { | |
| 37 | + _elementForUnflushedEvents.dispatchEvent(newEv); | |
| 38 | + } | |
| 39 | + _captureRecursion = false; | |
| 40 | + | |
| 41 | + // Avoid double events | |
| 42 | + e.stopPropagation(); | |
| 43 | + | |
| 44 | + // Respect the wishes of the redirected event handlers | |
| 45 | + if (newEv.defaultPrevented) { | |
| 46 | + e.preventDefault(); | |
| 47 | + } | |
| 48 | + | |
| 49 | + // Implicitly release the capture on button release | |
| 50 | + if (e.type === "mouseup") { | |
| 51 | + releaseCapture(); | |
| 52 | + } | |
| 53 | +} | |
| 54 | + | |
| 55 | +// Follow cursor style of target element | |
| 56 | +function _capturedElemChanged() { | |
| 57 | + const proxyElem = document.getElementById("noVNC_mouse_capture_elem"); | |
| 58 | + proxyElem.style.cursor = window.getComputedStyle(document.captureElement).cursor; | |
| 59 | +} | |
| 60 | + | |
| 61 | +const _captureObserver = new MutationObserver(_capturedElemChanged); | |
| 62 | + | |
| 63 | +export function setCapture(target) { | |
| 64 | + if (target.setCapture) { | |
| 65 | + | |
| 66 | + target.setCapture(); | |
| 67 | + document.captureElement = target; | |
| 68 | + } else { | |
| 69 | + // Release any existing capture in case this method is | |
| 70 | + // called multiple times without coordination | |
| 71 | + releaseCapture(); | |
| 72 | + | |
| 73 | + let proxyElem = document.getElementById("noVNC_mouse_capture_elem"); | |
| 74 | + | |
| 75 | + if (proxyElem === null) { | |
| 76 | + proxyElem = document.createElement("div"); | |
| 77 | + proxyElem.id = "noVNC_mouse_capture_elem"; | |
| 78 | + proxyElem.style.position = "fixed"; | |
| 79 | + proxyElem.style.top = "0px"; | |
| 80 | + proxyElem.style.left = "0px"; | |
| 81 | + proxyElem.style.width = "100%"; | |
| 82 | + proxyElem.style.height = "100%"; | |
| 83 | + proxyElem.style.zIndex = 10000; | |
| 84 | + proxyElem.style.display = "none"; | |
| 85 | + document.body.appendChild(proxyElem); | |
| 86 | + | |
| 87 | + // This is to make sure callers don't get confused by having | |
| 88 | + // our blocking element as the target | |
| 89 | + proxyElem.addEventListener('contextmenu', _captureProxy); | |
| 90 | + | |
| 91 | + proxyElem.addEventListener('mousemove', _captureProxy); | |
| 92 | + proxyElem.addEventListener('mouseup', _captureProxy); | |
| 93 | + } | |
| 94 | + | |
| 95 | + document.captureElement = target; | |
| 96 | + | |
| 97 | + // Track cursor and get initial cursor | |
| 98 | + _captureObserver.observe(target, {attributes: true}); | |
| 99 | + _capturedElemChanged(); | |
| 100 | + | |
| 101 | + proxyElem.style.display = ""; | |
| 102 | + | |
| 103 | + // We listen to events on window in order to keep tracking if it | |
| 104 | + // happens to leave the viewport | |
| 105 | + window.addEventListener('mousemove', _captureProxy); | |
| 106 | + window.addEventListener('mouseup', _captureProxy); | |
| 107 | + } | |
| 108 | +} | |
| 109 | + | |
| 110 | +export function releaseCapture() { | |
| 111 | + if (document.releaseCapture) { | |
| 112 | + | |
| 113 | + document.releaseCapture(); | |
| 114 | + document.captureElement = null; | |
| 115 | + | |
| 116 | + } else { | |
| 117 | + if (!document.captureElement) { | |
| 118 | + return; | |
| 119 | + } | |
| 120 | + | |
| 121 | + // There might be events already queued. The event proxy needs | |
| 122 | + // access to the captured element for these queued events. | |
| 123 | + // E.g. contextmenu (right-click) in Microsoft Edge | |
| 124 | + // | |
| 125 | + // Before removing the capturedElem pointer we save it to a | |
| 126 | + // temporary variable that the unflushed events can use. | |
| 127 | + _elementForUnflushedEvents = document.captureElement; | |
| 128 | + document.captureElement = null; | |
| 129 | + | |
| 130 | + _captureObserver.disconnect(); | |
| 131 | + | |
| 132 | + const proxyElem = document.getElementById("noVNC_mouse_capture_elem"); | |
| 133 | + proxyElem.style.display = "none"; | |
| 134 | + | |
| 135 | + window.removeEventListener('mousemove', _captureProxy); | |
| 136 | + window.removeEventListener('mouseup', _captureProxy); | |
| 137 | + } | |
| 138 | +} | |
added
public/vendor/novnc/core/util/eventtarget.js
+35 −0
@@ -0,0 +1,35 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +export default class EventTargetMixin { | |
| 10 | + constructor() { | |
| 11 | + this._listeners = new Map(); | |
| 12 | + } | |
| 13 | + | |
| 14 | + addEventListener(type, callback) { | |
| 15 | + if (!this._listeners.has(type)) { | |
| 16 | + this._listeners.set(type, new Set()); | |
| 17 | + } | |
| 18 | + this._listeners.get(type).add(callback); | |
| 19 | + } | |
| 20 | + | |
| 21 | + removeEventListener(type, callback) { | |
| 22 | + if (this._listeners.has(type)) { | |
| 23 | + this._listeners.get(type).delete(callback); | |
| 24 | + } | |
| 25 | + } | |
| 26 | + | |
| 27 | + dispatchEvent(event) { | |
| 28 | + if (!this._listeners.has(event.type)) { | |
| 29 | + return true; | |
| 30 | + } | |
| 31 | + this._listeners.get(event.type) | |
| 32 | + .forEach(callback => callback.call(this, event)); | |
| 33 | + return !event.defaultPrevented; | |
| 34 | + } | |
| 35 | +} | |
added
public/vendor/novnc/core/util/int.js
+15 −0
@@ -0,0 +1,15 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2020 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +export function toUnsigned32bit(toConvert) { | |
| 10 | + return toConvert >>> 0; | |
| 11 | +} | |
| 12 | + | |
| 13 | +export function toSigned32bit(toConvert) { | |
| 14 | + return toConvert | 0; | |
| 15 | +} | |
added
public/vendor/novnc/core/util/logging.js
+56 −0
@@ -0,0 +1,56 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +/* | |
| 10 | + * Logging/debug routines | |
| 11 | + */ | |
| 12 | + | |
| 13 | +let _logLevel = 'warn'; | |
| 14 | + | |
| 15 | +let Debug = () => {}; | |
| 16 | +let Info = () => {}; | |
| 17 | +let Warn = () => {}; | |
| 18 | +let Error = () => {}; | |
| 19 | + | |
| 20 | +export function initLogging(level) { | |
| 21 | + if (typeof level === 'undefined') { | |
| 22 | + level = _logLevel; | |
| 23 | + } else { | |
| 24 | + _logLevel = level; | |
| 25 | + } | |
| 26 | + | |
| 27 | + Debug = Info = Warn = Error = () => {}; | |
| 28 | + | |
| 29 | + if (typeof window.console !== "undefined") { | |
| 30 | + /* eslint-disable no-console, no-fallthrough */ | |
| 31 | + switch (level) { | |
| 32 | + case 'debug': | |
| 33 | + Debug = console.debug.bind(window.console); | |
| 34 | + case 'info': | |
| 35 | + Info = console.info.bind(window.console); | |
| 36 | + case 'warn': | |
| 37 | + Warn = console.warn.bind(window.console); | |
| 38 | + case 'error': | |
| 39 | + Error = console.error.bind(window.console); | |
| 40 | + case 'none': | |
| 41 | + break; | |
| 42 | + default: | |
| 43 | + throw new window.Error("invalid logging type '" + level + "'"); | |
| 44 | + } | |
| 45 | + /* eslint-enable no-console, no-fallthrough */ | |
| 46 | + } | |
| 47 | +} | |
| 48 | + | |
| 49 | +export function getLogging() { | |
| 50 | + return _logLevel; | |
| 51 | +} | |
| 52 | + | |
| 53 | +export { Debug, Info, Warn, Error }; | |
| 54 | + | |
| 55 | +// Initialize logging level | |
| 56 | +initLogging(); | |
added
public/vendor/novnc/core/util/strings.js
+28 −0
@@ -0,0 +1,28 @@ | ||
| 1 | +/* | |
| 2 | + * noVNC: HTML5 VNC client | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * See README.md for usage and integration instructions. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +// Decode from UTF-8 | |
| 10 | +export function decodeUTF8(utf8string, allowLatin1=false) { | |
| 11 | + try { | |
| 12 | + return decodeURIComponent(escape(utf8string)); | |
| 13 | + } catch (e) { | |
| 14 | + if (e instanceof URIError) { | |
| 15 | + if (allowLatin1) { | |
| 16 | + // If we allow Latin1 we can ignore any decoding fails | |
| 17 | + // and in these cases return the original string | |
| 18 | + return utf8string; | |
| 19 | + } | |
| 20 | + } | |
| 21 | + throw e; | |
| 22 | + } | |
| 23 | +} | |
| 24 | + | |
| 25 | +// Encode to UTF-8 | |
| 26 | +export function encodeUTF8(DOMString) { | |
| 27 | + return unescape(encodeURIComponent(DOMString)); | |
| 28 | +} | |
added
public/vendor/novnc/core/websock.js
+365 −0
@@ -0,0 +1,365 @@ | ||
| 1 | +/* | |
| 2 | + * Websock: high-performance buffering wrapper | |
| 3 | + * Copyright (C) 2019 The noVNC authors | |
| 4 | + * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 5 | + * | |
| 6 | + * Websock is similar to the standard WebSocket / RTCDataChannel object | |
| 7 | + * but with extra buffer handling. | |
| 8 | + * | |
| 9 | + * Websock has built-in receive queue buffering; the message event | |
| 10 | + * does not contain actual data but is simply a notification that | |
| 11 | + * there is new data available. Several rQ* methods are available to | |
| 12 | + * read binary data off of the receive queue. | |
| 13 | + */ | |
| 14 | + | |
| 15 | +import * as Log from './util/logging.js'; | |
| 16 | + | |
| 17 | +// this has performance issues in some versions Chromium, and | |
| 18 | +// doesn't gain a tremendous amount of performance increase in Firefox | |
| 19 | +// at the moment. It may be valuable to turn it on in the future. | |
| 20 | +const MAX_RQ_GROW_SIZE = 40 * 1024 * 1024; // 40 MiB | |
| 21 | + | |
| 22 | +// Constants pulled from RTCDataChannelState enum | |
| 23 | +// https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/readyState#RTCDataChannelState_enum | |
| 24 | +const DataChannel = { | |
| 25 | + CONNECTING: "connecting", | |
| 26 | + OPEN: "open", | |
| 27 | + CLOSING: "closing", | |
| 28 | + CLOSED: "closed" | |
| 29 | +}; | |
| 30 | + | |
| 31 | +const ReadyStates = { | |
| 32 | + CONNECTING: [WebSocket.CONNECTING, DataChannel.CONNECTING], | |
| 33 | + OPEN: [WebSocket.OPEN, DataChannel.OPEN], | |
| 34 | + CLOSING: [WebSocket.CLOSING, DataChannel.CLOSING], | |
| 35 | + CLOSED: [WebSocket.CLOSED, DataChannel.CLOSED], | |
| 36 | +}; | |
| 37 | + | |
| 38 | +// Properties a raw channel must have, WebSocket and RTCDataChannel are two examples | |
| 39 | +const rawChannelProps = [ | |
| 40 | + "send", | |
| 41 | + "close", | |
| 42 | + "binaryType", | |
| 43 | + "onerror", | |
| 44 | + "onmessage", | |
| 45 | + "onopen", | |
| 46 | + "protocol", | |
| 47 | + "readyState", | |
| 48 | +]; | |
| 49 | + | |
| 50 | +export default class Websock { | |
| 51 | + constructor() { | |
| 52 | + this._websocket = null; // WebSocket or RTCDataChannel object | |
| 53 | + | |
| 54 | + this._rQi = 0; // Receive queue index | |
| 55 | + this._rQlen = 0; // Next write position in the receive queue | |
| 56 | + this._rQbufferSize = 1024 * 1024 * 4; // Receive queue buffer size (4 MiB) | |
| 57 | + // called in init: this._rQ = new Uint8Array(this._rQbufferSize); | |
| 58 | + this._rQ = null; // Receive queue | |
| 59 | + | |
| 60 | + this._sQbufferSize = 1024 * 10; // 10 KiB | |
| 61 | + // called in init: this._sQ = new Uint8Array(this._sQbufferSize); | |
| 62 | + this._sQlen = 0; | |
| 63 | + this._sQ = null; // Send queue | |
| 64 | + | |
| 65 | + this._eventHandlers = { | |
| 66 | + message: () => {}, | |
| 67 | + open: () => {}, | |
| 68 | + close: () => {}, | |
| 69 | + error: () => {} | |
| 70 | + }; | |
| 71 | + } | |
| 72 | + | |
| 73 | + // Getters and setters | |
| 74 | + | |
| 75 | + get readyState() { | |
| 76 | + let subState; | |
| 77 | + | |
| 78 | + if (this._websocket === null) { | |
| 79 | + return "unused"; | |
| 80 | + } | |
| 81 | + | |
| 82 | + subState = this._websocket.readyState; | |
| 83 | + | |
| 84 | + if (ReadyStates.CONNECTING.includes(subState)) { | |
| 85 | + return "connecting"; | |
| 86 | + } else if (ReadyStates.OPEN.includes(subState)) { | |
| 87 | + return "open"; | |
| 88 | + } else if (ReadyStates.CLOSING.includes(subState)) { | |
| 89 | + return "closing"; | |
| 90 | + } else if (ReadyStates.CLOSED.includes(subState)) { | |
| 91 | + return "closed"; | |
| 92 | + } | |
| 93 | + | |
| 94 | + return "unknown"; | |
| 95 | + } | |
| 96 | + | |
| 97 | + // Receive queue | |
| 98 | + rQpeek8() { | |
| 99 | + return this._rQ[this._rQi]; | |
| 100 | + } | |
| 101 | + | |
| 102 | + rQskipBytes(bytes) { | |
| 103 | + this._rQi += bytes; | |
| 104 | + } | |
| 105 | + | |
| 106 | + rQshift8() { | |
| 107 | + return this._rQshift(1); | |
| 108 | + } | |
| 109 | + | |
| 110 | + rQshift16() { | |
| 111 | + return this._rQshift(2); | |
| 112 | + } | |
| 113 | + | |
| 114 | + rQshift32() { | |
| 115 | + return this._rQshift(4); | |
| 116 | + } | |
| 117 | + | |
| 118 | + // TODO(directxman12): test performance with these vs a DataView | |
| 119 | + _rQshift(bytes) { | |
| 120 | + let res = 0; | |
| 121 | + for (let byte = bytes - 1; byte >= 0; byte--) { | |
| 122 | + res += this._rQ[this._rQi++] << (byte * 8); | |
| 123 | + } | |
| 124 | + return res >>> 0; | |
| 125 | + } | |
| 126 | + | |
| 127 | + rQshiftStr(len) { | |
| 128 | + let str = ""; | |
| 129 | + // Handle large arrays in steps to avoid long strings on the stack | |
| 130 | + for (let i = 0; i < len; i += 4096) { | |
| 131 | + let part = this.rQshiftBytes(Math.min(4096, len - i), false); | |
| 132 | + str += String.fromCharCode.apply(null, part); | |
| 133 | + } | |
| 134 | + return str; | |
| 135 | + } | |
| 136 | + | |
| 137 | + rQshiftBytes(len, copy=true) { | |
| 138 | + this._rQi += len; | |
| 139 | + if (copy) { | |
| 140 | + return this._rQ.slice(this._rQi - len, this._rQi); | |
| 141 | + } else { | |
| 142 | + return this._rQ.subarray(this._rQi - len, this._rQi); | |
| 143 | + } | |
| 144 | + } | |
| 145 | + | |
| 146 | + rQshiftTo(target, len) { | |
| 147 | + // TODO: make this just use set with views when using a ArrayBuffer to store the rQ | |
| 148 | + target.set(new Uint8Array(this._rQ.buffer, this._rQi, len)); | |
| 149 | + this._rQi += len; | |
| 150 | + } | |
| 151 | + | |
| 152 | + rQpeekBytes(len, copy=true) { | |
| 153 | + if (copy) { | |
| 154 | + return this._rQ.slice(this._rQi, this._rQi + len); | |
| 155 | + } else { | |
| 156 | + return this._rQ.subarray(this._rQi, this._rQi + len); | |
| 157 | + } | |
| 158 | + } | |
| 159 | + | |
| 160 | + // Check to see if we must wait for 'num' bytes (default to FBU.bytes) | |
| 161 | + // to be available in the receive queue. Return true if we need to | |
| 162 | + // wait (and possibly print a debug message), otherwise false. | |
| 163 | + rQwait(msg, num, goback) { | |
| 164 | + if (this._rQlen - this._rQi < num) { | |
| 165 | + if (goback) { | |
| 166 | + if (this._rQi < goback) { | |
| 167 | + throw new Error("rQwait cannot backup " + goback + " bytes"); | |
| 168 | + } | |
| 169 | + this._rQi -= goback; | |
| 170 | + } | |
| 171 | + return true; // true means need more data | |
| 172 | + } | |
| 173 | + return false; | |
| 174 | + } | |
| 175 | + | |
| 176 | + // Send queue | |
| 177 | + | |
| 178 | + sQpush8(num) { | |
| 179 | + this._sQensureSpace(1); | |
| 180 | + this._sQ[this._sQlen++] = num; | |
| 181 | + } | |
| 182 | + | |
| 183 | + sQpush16(num) { | |
| 184 | + this._sQensureSpace(2); | |
| 185 | + this._sQ[this._sQlen++] = (num >> 8) & 0xff; | |
| 186 | + this._sQ[this._sQlen++] = (num >> 0) & 0xff; | |
| 187 | + } | |
| 188 | + | |
| 189 | + sQpush32(num) { | |
| 190 | + this._sQensureSpace(4); | |
| 191 | + this._sQ[this._sQlen++] = (num >> 24) & 0xff; | |
| 192 | + this._sQ[this._sQlen++] = (num >> 16) & 0xff; | |
| 193 | + this._sQ[this._sQlen++] = (num >> 8) & 0xff; | |
| 194 | + this._sQ[this._sQlen++] = (num >> 0) & 0xff; | |
| 195 | + } | |
| 196 | + | |
| 197 | + sQpushString(str) { | |
| 198 | + let bytes = str.split('').map(chr => chr.charCodeAt(0)); | |
| 199 | + this.sQpushBytes(new Uint8Array(bytes)); | |
| 200 | + } | |
| 201 | + | |
| 202 | + sQpushBytes(bytes) { | |
| 203 | + for (let offset = 0;offset < bytes.length;) { | |
| 204 | + this._sQensureSpace(1); | |
| 205 | + | |
| 206 | + let chunkSize = this._sQbufferSize - this._sQlen; | |
| 207 | + if (chunkSize > bytes.length - offset) { | |
| 208 | + chunkSize = bytes.length - offset; | |
| 209 | + } | |
| 210 | + | |
| 211 | + this._sQ.set(bytes.subarray(offset, offset + chunkSize), this._sQlen); | |
| 212 | + this._sQlen += chunkSize; | |
| 213 | + offset += chunkSize; | |
| 214 | + } | |
| 215 | + } | |
| 216 | + | |
| 217 | + flush() { | |
| 218 | + if (this._sQlen > 0 && this.readyState === 'open') { | |
| 219 | + this._websocket.send(new Uint8Array(this._sQ.buffer, 0, this._sQlen)); | |
| 220 | + this._sQlen = 0; | |
| 221 | + } | |
| 222 | + } | |
| 223 | + | |
| 224 | + _sQensureSpace(bytes) { | |
| 225 | + if (this._sQbufferSize - this._sQlen < bytes) { | |
| 226 | + this.flush(); | |
| 227 | + } | |
| 228 | + } | |
| 229 | + | |
| 230 | + // Event handlers | |
| 231 | + off(evt) { | |
| 232 | + this._eventHandlers[evt] = () => {}; | |
| 233 | + } | |
| 234 | + | |
| 235 | + on(evt, handler) { | |
| 236 | + this._eventHandlers[evt] = handler; | |
| 237 | + } | |
| 238 | + | |
| 239 | + _allocateBuffers() { | |
| 240 | + this._rQ = new Uint8Array(this._rQbufferSize); | |
| 241 | + this._sQ = new Uint8Array(this._sQbufferSize); | |
| 242 | + } | |
| 243 | + | |
| 244 | + init() { | |
| 245 | + this._allocateBuffers(); | |
| 246 | + this._rQi = 0; | |
| 247 | + this._websocket = null; | |
| 248 | + } | |
| 249 | + | |
| 250 | + open(uri, protocols) { | |
| 251 | + this.attach(new WebSocket(uri, protocols)); | |
| 252 | + } | |
| 253 | + | |
| 254 | + attach(rawChannel) { | |
| 255 | + this.init(); | |
| 256 | + | |
| 257 | + // Must get object and class methods to be compatible with the tests. | |
| 258 | + const channelProps = [...Object.keys(rawChannel), ...Object.getOwnPropertyNames(Object.getPrototypeOf(rawChannel))]; | |
| 259 | + for (let i = 0; i < rawChannelProps.length; i++) { | |
| 260 | + const prop = rawChannelProps[i]; | |
| 261 | + if (channelProps.indexOf(prop) < 0) { | |
| 262 | + throw new Error('Raw channel missing property: ' + prop); | |
| 263 | + } | |
| 264 | + } | |
| 265 | + | |
| 266 | + this._websocket = rawChannel; | |
| 267 | + this._websocket.binaryType = "arraybuffer"; | |
| 268 | + this._websocket.onmessage = this._recvMessage.bind(this); | |
| 269 | + | |
| 270 | + this._websocket.onopen = () => { | |
| 271 | + Log.Debug('>> WebSock.onopen'); | |
| 272 | + if (this._websocket.protocol) { | |
| 273 | + Log.Info("Server choose sub-protocol: " + this._websocket.protocol); | |
| 274 | + } | |
| 275 | + | |
| 276 | + this._eventHandlers.open(); | |
| 277 | + Log.Debug("<< WebSock.onopen"); | |
| 278 | + }; | |
| 279 | + | |
| 280 | + this._websocket.onclose = (e) => { | |
| 281 | + Log.Debug(">> WebSock.onclose"); | |
| 282 | + this._eventHandlers.close(e); | |
| 283 | + Log.Debug("<< WebSock.onclose"); | |
| 284 | + }; | |
| 285 | + | |
| 286 | + this._websocket.onerror = (e) => { | |
| 287 | + Log.Debug(">> WebSock.onerror: " + e); | |
| 288 | + this._eventHandlers.error(e); | |
| 289 | + Log.Debug("<< WebSock.onerror: " + e); | |
| 290 | + }; | |
| 291 | + } | |
| 292 | + | |
| 293 | + close() { | |
| 294 | + if (this._websocket) { | |
| 295 | + if (this.readyState === 'connecting' || | |
| 296 | + this.readyState === 'open') { | |
| 297 | + Log.Info("Closing WebSocket connection"); | |
| 298 | + this._websocket.close(); | |
| 299 | + } | |
| 300 | + | |
| 301 | + this._websocket.onmessage = () => {}; | |
| 302 | + } | |
| 303 | + } | |
| 304 | + | |
| 305 | + // private methods | |
| 306 | + | |
| 307 | + // We want to move all the unread data to the start of the queue, | |
| 308 | + // e.g. compacting. | |
| 309 | + // The function also expands the receive que if needed, and for | |
| 310 | + // performance reasons we combine these two actions to avoid | |
| 311 | + // unnecessary copying. | |
| 312 | + _expandCompactRQ(minFit) { | |
| 313 | + // if we're using less than 1/8th of the buffer even with the incoming bytes, compact in place | |
| 314 | + // instead of resizing | |
| 315 | + const requiredBufferSize = (this._rQlen - this._rQi + minFit) * 8; | |
| 316 | + const resizeNeeded = this._rQbufferSize < requiredBufferSize; | |
| 317 | + | |
| 318 | + if (resizeNeeded) { | |
| 319 | + // Make sure we always *at least* double the buffer size, and have at least space for 8x | |
| 320 | + // the current amount of data | |
| 321 | + this._rQbufferSize = Math.max(this._rQbufferSize * 2, requiredBufferSize); | |
| 322 | + } | |
| 323 | + | |
| 324 | + // we don't want to grow unboundedly | |
| 325 | + if (this._rQbufferSize > MAX_RQ_GROW_SIZE) { | |
| 326 | + this._rQbufferSize = MAX_RQ_GROW_SIZE; | |
| 327 | + if (this._rQbufferSize - (this._rQlen - this._rQi) < minFit) { | |
| 328 | + throw new Error("Receive queue buffer exceeded " + MAX_RQ_GROW_SIZE + " bytes, and the new message could not fit"); | |
| 329 | + } | |
| 330 | + } | |
| 331 | + | |
| 332 | + if (resizeNeeded) { | |
| 333 | + const oldRQbuffer = this._rQ.buffer; | |
| 334 | + this._rQ = new Uint8Array(this._rQbufferSize); | |
| 335 | + this._rQ.set(new Uint8Array(oldRQbuffer, this._rQi, this._rQlen - this._rQi)); | |
| 336 | + } else { | |
| 337 | + this._rQ.copyWithin(0, this._rQi, this._rQlen); | |
| 338 | + } | |
| 339 | + | |
| 340 | + this._rQlen = this._rQlen - this._rQi; | |
| 341 | + this._rQi = 0; | |
| 342 | + } | |
| 343 | + | |
| 344 | + // push arraybuffer values onto the end of the receive que | |
| 345 | + _recvMessage(e) { | |
| 346 | + if (this._rQlen == this._rQi) { | |
| 347 | + // All data has now been processed, this means we | |
| 348 | + // can reset the receive queue. | |
| 349 | + this._rQlen = 0; | |
| 350 | + this._rQi = 0; | |
| 351 | + } | |
| 352 | + const u8 = new Uint8Array(e.data); | |
| 353 | + if (u8.length > this._rQbufferSize - this._rQlen) { | |
| 354 | + this._expandCompactRQ(u8.length); | |
| 355 | + } | |
| 356 | + this._rQ.set(u8, this._rQlen); | |
| 357 | + this._rQlen += u8.length; | |
| 358 | + | |
| 359 | + if (this._rQlen - this._rQi > 0) { | |
| 360 | + this._eventHandlers.message(); | |
| 361 | + } else { | |
| 362 | + Log.Debug("Ignoring empty message"); | |
| 363 | + } | |
| 364 | + } | |
| 365 | +} | |
deleted
public/vendor/novnc/crypto/aes.js
+0 −481
@@ -1,481 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports.AESECBCipher = exports.AESEAXCipher = void 0; | |
| 7 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 8 | −function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } | |
| 9 | −function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } | |
| 10 | −function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } | |
| 11 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 12 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 13 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 14 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 15 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 16 | −var AESECBCipher = exports.AESECBCipher = /*#__PURE__*/function () { | |
| 17 | − function AESECBCipher() { | |
| 18 | − _classCallCheck(this, AESECBCipher); | |
| 19 | − this._key = null; | |
| 20 | − } | |
| 21 | − return _createClass(AESECBCipher, [{ | |
| 22 | − key: "algorithm", | |
| 23 | − get: function get() { | |
| 24 | − return { | |
| 25 | − name: "AES-ECB" | |
| 26 | − }; | |
| 27 | − } | |
| 28 | − }, { | |
| 29 | − key: "_importKey", | |
| 30 | − value: function () { | |
| 31 | − var _importKey2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(key, extractable, keyUsages) { | |
| 32 | − return _regeneratorRuntime().wrap(function _callee$(_context) { | |
| 33 | − while (1) switch (_context.prev = _context.next) { | |
| 34 | − case 0: | |
| 35 | − _context.next = 2; | |
| 36 | − return window.crypto.subtle.importKey("raw", key, { | |
| 37 | − name: "AES-CBC" | |
| 38 | − }, extractable, keyUsages); | |
| 39 | − case 2: | |
| 40 | − this._key = _context.sent; | |
| 41 | − case 3: | |
| 42 | − case "end": | |
| 43 | − return _context.stop(); | |
| 44 | − } | |
| 45 | − }, _callee, this); | |
| 46 | − })); | |
| 47 | − function _importKey(_x, _x2, _x3) { | |
| 48 | − return _importKey2.apply(this, arguments); | |
| 49 | − } | |
| 50 | − return _importKey; | |
| 51 | − }() | |
| 52 | − }, { | |
| 53 | − key: "encrypt", | |
| 54 | − value: function () { | |
| 55 | − var _encrypt = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(_algorithm, plaintext) { | |
| 56 | − var x, n, i, y; | |
| 57 | − return _regeneratorRuntime().wrap(function _callee2$(_context2) { | |
| 58 | − while (1) switch (_context2.prev = _context2.next) { | |
| 59 | − case 0: | |
| 60 | − x = new Uint8Array(plaintext); | |
| 61 | − if (!(x.length % 16 !== 0 || this._key === null)) { | |
| 62 | − _context2.next = 3; | |
| 63 | − break; | |
| 64 | − } | |
| 65 | − return _context2.abrupt("return", null); | |
| 66 | − case 3: | |
| 67 | − n = x.length / 16; | |
| 68 | − i = 0; | |
| 69 | − case 5: | |
| 70 | − if (!(i < n)) { | |
| 71 | − _context2.next = 15; | |
| 72 | − break; | |
| 73 | − } | |
| 74 | − _context2.t0 = Uint8Array; | |
| 75 | − _context2.next = 9; | |
| 76 | − return window.crypto.subtle.encrypt({ | |
| 77 | − name: "AES-CBC", | |
| 78 | − iv: new Uint8Array(16) | |
| 79 | − }, this._key, x.slice(i * 16, i * 16 + 16)); | |
| 80 | − case 9: | |
| 81 | − _context2.t1 = _context2.sent; | |
| 82 | − y = new _context2.t0(_context2.t1).slice(0, 16); | |
| 83 | − x.set(y, i * 16); | |
| 84 | − case 12: | |
| 85 | − i++; | |
| 86 | − _context2.next = 5; | |
| 87 | − break; | |
| 88 | − case 15: | |
| 89 | − return _context2.abrupt("return", x); | |
| 90 | − case 16: | |
| 91 | − case "end": | |
| 92 | − return _context2.stop(); | |
| 93 | − } | |
| 94 | − }, _callee2, this); | |
| 95 | − })); | |
| 96 | − function encrypt(_x4, _x5) { | |
| 97 | − return _encrypt.apply(this, arguments); | |
| 98 | − } | |
| 99 | − return encrypt; | |
| 100 | − }() | |
| 101 | − }], [{ | |
| 102 | − key: "importKey", | |
| 103 | − value: function () { | |
| 104 | − var _importKey3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(key, _algorithm, extractable, keyUsages) { | |
| 105 | − var cipher; | |
| 106 | − return _regeneratorRuntime().wrap(function _callee3$(_context3) { | |
| 107 | − while (1) switch (_context3.prev = _context3.next) { | |
| 108 | − case 0: | |
| 109 | − cipher = new AESECBCipher(); | |
| 110 | − _context3.next = 3; | |
| 111 | − return cipher._importKey(key, extractable, keyUsages); | |
| 112 | − case 3: | |
| 113 | − return _context3.abrupt("return", cipher); | |
| 114 | − case 4: | |
| 115 | − case "end": | |
| 116 | − return _context3.stop(); | |
| 117 | − } | |
| 118 | − }, _callee3); | |
| 119 | − })); | |
| 120 | − function importKey(_x6, _x7, _x8, _x9) { | |
| 121 | − return _importKey3.apply(this, arguments); | |
| 122 | − } | |
| 123 | − return importKey; | |
| 124 | − }() | |
| 125 | − }]); | |
| 126 | −}(); | |
| 127 | −var AESEAXCipher = exports.AESEAXCipher = /*#__PURE__*/function () { | |
| 128 | − function AESEAXCipher() { | |
| 129 | − _classCallCheck(this, AESEAXCipher); | |
| 130 | − this._rawKey = null; | |
| 131 | − this._ctrKey = null; | |
| 132 | − this._cbcKey = null; | |
| 133 | − this._zeroBlock = new Uint8Array(16); | |
| 134 | − this._prefixBlock0 = this._zeroBlock; | |
| 135 | − this._prefixBlock1 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); | |
| 136 | − this._prefixBlock2 = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2]); | |
| 137 | − } | |
| 138 | − return _createClass(AESEAXCipher, [{ | |
| 139 | − key: "algorithm", | |
| 140 | − get: function get() { | |
| 141 | − return { | |
| 142 | − name: "AES-EAX" | |
| 143 | − }; | |
| 144 | − } | |
| 145 | − }, { | |
| 146 | − key: "_encryptBlock", | |
| 147 | − value: function () { | |
| 148 | − var _encryptBlock2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4(block) { | |
| 149 | − var encrypted; | |
| 150 | − return _regeneratorRuntime().wrap(function _callee4$(_context4) { | |
| 151 | − while (1) switch (_context4.prev = _context4.next) { | |
| 152 | − case 0: | |
| 153 | − _context4.next = 2; | |
| 154 | − return window.crypto.subtle.encrypt({ | |
| 155 | − name: "AES-CBC", | |
| 156 | − iv: this._zeroBlock | |
| 157 | − }, this._cbcKey, block); | |
| 158 | − case 2: | |
| 159 | − encrypted = _context4.sent; | |
| 160 | − return _context4.abrupt("return", new Uint8Array(encrypted).slice(0, 16)); | |
| 161 | − case 4: | |
| 162 | − case "end": | |
| 163 | − return _context4.stop(); | |
| 164 | − } | |
| 165 | − }, _callee4, this); | |
| 166 | − })); | |
| 167 | − function _encryptBlock(_x10) { | |
| 168 | − return _encryptBlock2.apply(this, arguments); | |
| 169 | − } | |
| 170 | − return _encryptBlock; | |
| 171 | − }() | |
| 172 | − }, { | |
| 173 | − key: "_initCMAC", | |
| 174 | − value: function () { | |
| 175 | − var _initCMAC2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee5() { | |
| 176 | − var k1, k2, v, i, lut; | |
| 177 | − return _regeneratorRuntime().wrap(function _callee5$(_context5) { | |
| 178 | − while (1) switch (_context5.prev = _context5.next) { | |
| 179 | − case 0: | |
| 180 | − _context5.next = 2; | |
| 181 | − return this._encryptBlock(this._zeroBlock); | |
| 182 | − case 2: | |
| 183 | − k1 = _context5.sent; | |
| 184 | − k2 = new Uint8Array(16); | |
| 185 | − v = k1[0] >>> 6; | |
| 186 | − for (i = 0; i < 15; i++) { | |
| 187 | − k2[i] = k1[i + 1] >> 6 | k1[i] << 2; | |
| 188 | − k1[i] = k1[i + 1] >> 7 | k1[i] << 1; | |
| 189 | − } | |
| 190 | − lut = [0x0, 0x87, 0x0e, 0x89]; | |
| 191 | − k2[14] ^= v >>> 1; | |
| 192 | − k2[15] = k1[15] << 2 ^ lut[v]; | |
| 193 | − k1[15] = k1[15] << 1 ^ lut[v >> 1]; | |
| 194 | − this._k1 = k1; | |
| 195 | − this._k2 = k2; | |
| 196 | − case 12: | |
| 197 | − case "end": | |
| 198 | − return _context5.stop(); | |
| 199 | − } | |
| 200 | − }, _callee5, this); | |
| 201 | − })); | |
| 202 | − function _initCMAC() { | |
| 203 | − return _initCMAC2.apply(this, arguments); | |
| 204 | − } | |
| 205 | − return _initCMAC; | |
| 206 | − }() | |
| 207 | − }, { | |
| 208 | − key: "_encryptCTR", | |
| 209 | − value: function () { | |
| 210 | − var _encryptCTR2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee6(data, counter) { | |
| 211 | − var encrypted; | |
| 212 | − return _regeneratorRuntime().wrap(function _callee6$(_context6) { | |
| 213 | − while (1) switch (_context6.prev = _context6.next) { | |
| 214 | − case 0: | |
| 215 | − _context6.next = 2; | |
| 216 | − return window.crypto.subtle.encrypt({ | |
| 217 | − name: "AES-CTR", | |
| 218 | − counter: counter, | |
| 219 | − length: 128 | |
| 220 | − }, this._ctrKey, data); | |
| 221 | − case 2: | |
| 222 | − encrypted = _context6.sent; | |
| 223 | − return _context6.abrupt("return", new Uint8Array(encrypted)); | |
| 224 | − case 4: | |
| 225 | − case "end": | |
| 226 | − return _context6.stop(); | |
| 227 | − } | |
| 228 | − }, _callee6, this); | |
| 229 | − })); | |
| 230 | − function _encryptCTR(_x11, _x12) { | |
| 231 | − return _encryptCTR2.apply(this, arguments); | |
| 232 | − } | |
| 233 | − return _encryptCTR; | |
| 234 | − }() | |
| 235 | − }, { | |
| 236 | − key: "_decryptCTR", | |
| 237 | − value: function () { | |
| 238 | − var _decryptCTR2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee7(data, counter) { | |
| 239 | − var decrypted; | |
| 240 | − return _regeneratorRuntime().wrap(function _callee7$(_context7) { | |
| 241 | − while (1) switch (_context7.prev = _context7.next) { | |
| 242 | − case 0: | |
| 243 | − _context7.next = 2; | |
| 244 | − return window.crypto.subtle.decrypt({ | |
| 245 | − name: "AES-CTR", | |
| 246 | − counter: counter, | |
| 247 | − length: 128 | |
| 248 | − }, this._ctrKey, data); | |
| 249 | − case 2: | |
| 250 | − decrypted = _context7.sent; | |
| 251 | − return _context7.abrupt("return", new Uint8Array(decrypted)); | |
| 252 | − case 4: | |
| 253 | − case "end": | |
| 254 | − return _context7.stop(); | |
| 255 | − } | |
| 256 | − }, _callee7, this); | |
| 257 | − })); | |
| 258 | − function _decryptCTR(_x13, _x14) { | |
| 259 | − return _decryptCTR2.apply(this, arguments); | |
| 260 | − } | |
| 261 | − return _decryptCTR; | |
| 262 | − }() | |
| 263 | − }, { | |
| 264 | − key: "_computeCMAC", | |
| 265 | − value: function () { | |
| 266 | − var _computeCMAC2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee8(data, prefixBlock) { | |
| 267 | − var n, m, r, cbcData, i, _i, cbcEncrypted, mac; | |
| 268 | − return _regeneratorRuntime().wrap(function _callee8$(_context8) { | |
| 269 | − while (1) switch (_context8.prev = _context8.next) { | |
| 270 | − case 0: | |
| 271 | − if (!(prefixBlock.length !== 16)) { | |
| 272 | − _context8.next = 2; | |
| 273 | − break; | |
| 274 | − } | |
| 275 | − return _context8.abrupt("return", null); | |
| 276 | − case 2: | |
| 277 | − n = Math.floor(data.length / 16); | |
| 278 | − m = Math.ceil(data.length / 16); | |
| 279 | − r = data.length - n * 16; | |
| 280 | − cbcData = new Uint8Array((m + 1) * 16); | |
| 281 | − cbcData.set(prefixBlock); | |
| 282 | − cbcData.set(data, 16); | |
| 283 | − if (r === 0) { | |
| 284 | − for (i = 0; i < 16; i++) { | |
| 285 | − cbcData[n * 16 + i] ^= this._k1[i]; | |
| 286 | − } | |
| 287 | − } else { | |
| 288 | − cbcData[(n + 1) * 16 + r] = 0x80; | |
| 289 | − for (_i = 0; _i < 16; _i++) { | |
| 290 | − cbcData[(n + 1) * 16 + _i] ^= this._k2[_i]; | |
| 291 | − } | |
| 292 | − } | |
| 293 | − _context8.next = 11; | |
| 294 | − return window.crypto.subtle.encrypt({ | |
| 295 | − name: "AES-CBC", | |
| 296 | − iv: this._zeroBlock | |
| 297 | − }, this._cbcKey, cbcData); | |
| 298 | − case 11: | |
| 299 | − cbcEncrypted = _context8.sent; | |
| 300 | − cbcEncrypted = new Uint8Array(cbcEncrypted); | |
| 301 | − mac = cbcEncrypted.slice(cbcEncrypted.length - 32, cbcEncrypted.length - 16); | |
| 302 | − return _context8.abrupt("return", mac); | |
| 303 | − case 15: | |
| 304 | − case "end": | |
| 305 | − return _context8.stop(); | |
| 306 | − } | |
| 307 | − }, _callee8, this); | |
| 308 | − })); | |
| 309 | − function _computeCMAC(_x15, _x16) { | |
| 310 | − return _computeCMAC2.apply(this, arguments); | |
| 311 | − } | |
| 312 | − return _computeCMAC; | |
| 313 | − }() | |
| 314 | − }, { | |
| 315 | − key: "_importKey", | |
| 316 | − value: function () { | |
| 317 | − var _importKey4 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee9(key) { | |
| 318 | − return _regeneratorRuntime().wrap(function _callee9$(_context9) { | |
| 319 | − while (1) switch (_context9.prev = _context9.next) { | |
| 320 | − case 0: | |
| 321 | − this._rawKey = key; | |
| 322 | − _context9.next = 3; | |
| 323 | − return window.crypto.subtle.importKey("raw", key, { | |
| 324 | − name: "AES-CTR" | |
| 325 | − }, false, ["encrypt", "decrypt"]); | |
| 326 | − case 3: | |
| 327 | − this._ctrKey = _context9.sent; | |
| 328 | − _context9.next = 6; | |
| 329 | − return window.crypto.subtle.importKey("raw", key, { | |
| 330 | − name: "AES-CBC" | |
| 331 | − }, false, ["encrypt"]); | |
| 332 | − case 6: | |
| 333 | − this._cbcKey = _context9.sent; | |
| 334 | − _context9.next = 9; | |
| 335 | − return this._initCMAC(); | |
| 336 | − case 9: | |
| 337 | − case "end": | |
| 338 | − return _context9.stop(); | |
| 339 | − } | |
| 340 | − }, _callee9, this); | |
| 341 | − })); | |
| 342 | − function _importKey(_x17) { | |
| 343 | − return _importKey4.apply(this, arguments); | |
| 344 | − } | |
| 345 | − return _importKey; | |
| 346 | − }() | |
| 347 | − }, { | |
| 348 | − key: "encrypt", | |
| 349 | − value: function () { | |
| 350 | − var _encrypt2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee10(algorithm, message) { | |
| 351 | − var ad, nonce, nCMAC, encrypted, adCMAC, mac, i, res; | |
| 352 | − return _regeneratorRuntime().wrap(function _callee10$(_context10) { | |
| 353 | − while (1) switch (_context10.prev = _context10.next) { | |
| 354 | − case 0: | |
| 355 | − ad = algorithm.additionalData; | |
| 356 | − nonce = algorithm.iv; | |
| 357 | − _context10.next = 4; | |
| 358 | − return this._computeCMAC(nonce, this._prefixBlock0); | |
| 359 | − case 4: | |
| 360 | − nCMAC = _context10.sent; | |
| 361 | − _context10.next = 7; | |
| 362 | − return this._encryptCTR(message, nCMAC); | |
| 363 | − case 7: | |
| 364 | − encrypted = _context10.sent; | |
| 365 | − _context10.next = 10; | |
| 366 | − return this._computeCMAC(ad, this._prefixBlock1); | |
| 367 | − case 10: | |
| 368 | − adCMAC = _context10.sent; | |
| 369 | − _context10.next = 13; | |
| 370 | − return this._computeCMAC(encrypted, this._prefixBlock2); | |
| 371 | − case 13: | |
| 372 | − mac = _context10.sent; | |
| 373 | − for (i = 0; i < 16; i++) { | |
| 374 | − mac[i] ^= nCMAC[i] ^ adCMAC[i]; | |
| 375 | − } | |
| 376 | − res = new Uint8Array(16 + encrypted.length); | |
| 377 | − res.set(encrypted); | |
| 378 | − res.set(mac, encrypted.length); | |
| 379 | − return _context10.abrupt("return", res); | |
| 380 | − case 19: | |
| 381 | − case "end": | |
| 382 | − return _context10.stop(); | |
| 383 | − } | |
| 384 | − }, _callee10, this); | |
| 385 | − })); | |
| 386 | − function encrypt(_x18, _x19) { | |
| 387 | − return _encrypt2.apply(this, arguments); | |
| 388 | − } | |
| 389 | − return encrypt; | |
| 390 | − }() | |
| 391 | − }, { | |
| 392 | − key: "decrypt", | |
| 393 | − value: function () { | |
| 394 | − var _decrypt = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee11(algorithm, data) { | |
| 395 | − var encrypted, ad, nonce, mac, nCMAC, adCMAC, computedMac, i, _i2, res; | |
| 396 | − return _regeneratorRuntime().wrap(function _callee11$(_context11) { | |
| 397 | − while (1) switch (_context11.prev = _context11.next) { | |
| 398 | − case 0: | |
| 399 | − encrypted = data.slice(0, data.length - 16); | |
| 400 | − ad = algorithm.additionalData; | |
| 401 | − nonce = algorithm.iv; | |
| 402 | − mac = data.slice(data.length - 16); | |
| 403 | − _context11.next = 6; | |
| 404 | − return this._computeCMAC(nonce, this._prefixBlock0); | |
| 405 | − case 6: | |
| 406 | − nCMAC = _context11.sent; | |
| 407 | − _context11.next = 9; | |
| 408 | − return this._computeCMAC(ad, this._prefixBlock1); | |
| 409 | − case 9: | |
| 410 | − adCMAC = _context11.sent; | |
| 411 | − _context11.next = 12; | |
| 412 | − return this._computeCMAC(encrypted, this._prefixBlock2); | |
| 413 | − case 12: | |
| 414 | − computedMac = _context11.sent; | |
| 415 | − for (i = 0; i < 16; i++) { | |
| 416 | − computedMac[i] ^= nCMAC[i] ^ adCMAC[i]; | |
| 417 | − } | |
| 418 | − if (!(computedMac.length !== mac.length)) { | |
| 419 | − _context11.next = 16; | |
| 420 | − break; | |
| 421 | − } | |
| 422 | − return _context11.abrupt("return", null); | |
| 423 | − case 16: | |
| 424 | − _i2 = 0; | |
| 425 | − case 17: | |
| 426 | − if (!(_i2 < mac.length)) { | |
| 427 | − _context11.next = 23; | |
| 428 | − break; | |
| 429 | − } | |
| 430 | − if (!(computedMac[_i2] !== mac[_i2])) { | |
| 431 | − _context11.next = 20; | |
| 432 | − break; | |
| 433 | − } | |
| 434 | − return _context11.abrupt("return", null); | |
| 435 | − case 20: | |
| 436 | − _i2++; | |
| 437 | − _context11.next = 17; | |
| 438 | − break; | |
| 439 | − case 23: | |
| 440 | − _context11.next = 25; | |
| 441 | − return this._decryptCTR(encrypted, nCMAC); | |
| 442 | − case 25: | |
| 443 | − res = _context11.sent; | |
| 444 | − return _context11.abrupt("return", res); | |
| 445 | − case 27: | |
| 446 | − case "end": | |
| 447 | − return _context11.stop(); | |
| 448 | − } | |
| 449 | − }, _callee11, this); | |
| 450 | − })); | |
| 451 | − function decrypt(_x20, _x21) { | |
| 452 | − return _decrypt.apply(this, arguments); | |
| 453 | − } | |
| 454 | − return decrypt; | |
| 455 | − }() | |
| 456 | − }], [{ | |
| 457 | − key: "importKey", | |
| 458 | − value: function () { | |
| 459 | − var _importKey5 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee12(key, _algorithm, _extractable, _keyUsages) { | |
| 460 | − var cipher; | |
| 461 | − return _regeneratorRuntime().wrap(function _callee12$(_context12) { | |
| 462 | − while (1) switch (_context12.prev = _context12.next) { | |
| 463 | − case 0: | |
| 464 | − cipher = new AESEAXCipher(); | |
| 465 | − _context12.next = 3; | |
| 466 | − return cipher._importKey(key); | |
| 467 | − case 3: | |
| 468 | − return _context12.abrupt("return", cipher); | |
| 469 | − case 4: | |
| 470 | − case "end": | |
| 471 | − return _context12.stop(); | |
| 472 | − } | |
| 473 | − }, _callee12); | |
| 474 | − })); | |
| 475 | − function importKey(_x22, _x23, _x24, _x25) { | |
| 476 | − return _importKey5.apply(this, arguments); | |
| 477 | − } | |
| 478 | − return importKey; | |
| 479 | − }() | |
| 480 | − }]); | |
| 481 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/crypto/bigint.js
+0 −41
@@ -1,41 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports.bigIntToU8Array = bigIntToU8Array; | |
| 7 | −exports.modPow = modPow; | |
| 8 | −exports.u8ArrayToBigInt = u8ArrayToBigInt; | |
| 9 | −function modPow(b, e, m) { | |
| 10 | − var r = 1n; | |
| 11 | − b = b % m; | |
| 12 | − while (e > 0n) { | |
| 13 | − if ((e & 1n) === 1n) { | |
| 14 | − r = r * b % m; | |
| 15 | − } | |
| 16 | − e = e >> 1n; | |
| 17 | − b = b * b % m; | |
| 18 | − } | |
| 19 | − return r; | |
| 20 | −} | |
| 21 | −function bigIntToU8Array(bigint) { | |
| 22 | − var padLength = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | |
| 23 | − var hex = bigint.toString(16); | |
| 24 | − if (padLength === 0) { | |
| 25 | − padLength = Math.ceil(hex.length / 2); | |
| 26 | − } | |
| 27 | − hex = hex.padStart(padLength * 2, '0'); | |
| 28 | − var length = hex.length / 2; | |
| 29 | − var arr = new Uint8Array(length); | |
| 30 | − for (var i = 0; i < length; i++) { | |
| 31 | − arr[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16); | |
| 32 | − } | |
| 33 | − return arr; | |
| 34 | −} | |
| 35 | −function u8ArrayToBigInt(arr) { | |
| 36 | − var hex = '0x'; | |
| 37 | − for (var i = 0; i < arr.length; i++) { | |
| 38 | − hex += arr[i].toString(16).padStart(2, '0'); | |
| 39 | − } | |
| 40 | − return BigInt(hex); | |
| 41 | −} | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/crypto/crypto.js
+0 −109
@@ -1,109 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var _aes = require("./aes.js"); | |
| 8 | −var _des = require("./des.js"); | |
| 9 | −var _rsa = require("./rsa.js"); | |
| 10 | −var _dh = require("./dh.js"); | |
| 11 | −var _md = require("./md5.js"); | |
| 12 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 13 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 14 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 15 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 16 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 17 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 18 | −// A single interface for the cryptographic algorithms not supported by SubtleCrypto. | |
| 19 | −// Both synchronous and asynchronous implmentations are allowed. | |
| 20 | −var LegacyCrypto = /*#__PURE__*/function () { | |
| 21 | − function LegacyCrypto() { | |
| 22 | − _classCallCheck(this, LegacyCrypto); | |
| 23 | − this._algorithms = { | |
| 24 | − "AES-ECB": _aes.AESECBCipher, | |
| 25 | − "AES-EAX": _aes.AESEAXCipher, | |
| 26 | − "DES-ECB": _des.DESECBCipher, | |
| 27 | − "DES-CBC": _des.DESCBCCipher, | |
| 28 | − "RSA-PKCS1-v1_5": _rsa.RSACipher, | |
| 29 | − "DH": _dh.DHCipher, | |
| 30 | − "MD5": _md.MD5 | |
| 31 | − }; | |
| 32 | − } | |
| 33 | − return _createClass(LegacyCrypto, [{ | |
| 34 | − key: "encrypt", | |
| 35 | − value: function encrypt(algorithm, key, data) { | |
| 36 | − if (key.algorithm.name !== algorithm.name) { | |
| 37 | − throw new Error("algorithm does not match"); | |
| 38 | − } | |
| 39 | − if (typeof key.encrypt !== "function") { | |
| 40 | − throw new Error("key does not support encryption"); | |
| 41 | − } | |
| 42 | − return key.encrypt(algorithm, data); | |
| 43 | − } | |
| 44 | − }, { | |
| 45 | − key: "decrypt", | |
| 46 | − value: function decrypt(algorithm, key, data) { | |
| 47 | − if (key.algorithm.name !== algorithm.name) { | |
| 48 | − throw new Error("algorithm does not match"); | |
| 49 | − } | |
| 50 | − if (typeof key.decrypt !== "function") { | |
| 51 | − throw new Error("key does not support encryption"); | |
| 52 | − } | |
| 53 | − return key.decrypt(algorithm, data); | |
| 54 | − } | |
| 55 | − }, { | |
| 56 | − key: "importKey", | |
| 57 | − value: function importKey(format, keyData, algorithm, extractable, keyUsages) { | |
| 58 | − if (format !== "raw") { | |
| 59 | − throw new Error("key format is not supported"); | |
| 60 | − } | |
| 61 | − var alg = this._algorithms[algorithm.name]; | |
| 62 | − if (typeof alg === "undefined" || typeof alg.importKey !== "function") { | |
| 63 | − throw new Error("algorithm is not supported"); | |
| 64 | − } | |
| 65 | − return alg.importKey(keyData, algorithm, extractable, keyUsages); | |
| 66 | − } | |
| 67 | − }, { | |
| 68 | − key: "generateKey", | |
| 69 | − value: function generateKey(algorithm, extractable, keyUsages) { | |
| 70 | − var alg = this._algorithms[algorithm.name]; | |
| 71 | − if (typeof alg === "undefined" || typeof alg.generateKey !== "function") { | |
| 72 | − throw new Error("algorithm is not supported"); | |
| 73 | − } | |
| 74 | − return alg.generateKey(algorithm, extractable, keyUsages); | |
| 75 | − } | |
| 76 | − }, { | |
| 77 | − key: "exportKey", | |
| 78 | − value: function exportKey(format, key) { | |
| 79 | − if (format !== "raw") { | |
| 80 | − throw new Error("key format is not supported"); | |
| 81 | − } | |
| 82 | − if (typeof key.exportKey !== "function") { | |
| 83 | − throw new Error("key does not support exportKey"); | |
| 84 | − } | |
| 85 | − return key.exportKey(); | |
| 86 | − } | |
| 87 | − }, { | |
| 88 | − key: "digest", | |
| 89 | − value: function digest(algorithm, data) { | |
| 90 | − var alg = this._algorithms[algorithm]; | |
| 91 | − if (typeof alg !== "function") { | |
| 92 | − throw new Error("algorithm is not supported"); | |
| 93 | − } | |
| 94 | − return alg(data); | |
| 95 | − } | |
| 96 | − }, { | |
| 97 | − key: "deriveBits", | |
| 98 | − value: function deriveBits(algorithm, key, length) { | |
| 99 | − if (key.algorithm.name !== algorithm.name) { | |
| 100 | − throw new Error("algorithm does not match"); | |
| 101 | − } | |
| 102 | − if (typeof key.deriveBits !== "function") { | |
| 103 | − throw new Error("key does not support deriveBits"); | |
| 104 | − } | |
| 105 | − return key.deriveBits(algorithm, length); | |
| 106 | − } | |
| 107 | − }]); | |
| 108 | −}(); | |
| 109 | −var _default = exports["default"] = new LegacyCrypto(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/crypto/des.js
+0 −374
@@ -1,374 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports.DESECBCipher = exports.DESCBCCipher = void 0; | |
| 7 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 8 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 9 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 10 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 11 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 12 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 13 | −/* | |
| 14 | − * Ported from Flashlight VNC ActionScript implementation: | |
| 15 | − * http://www.wizhelp.com/flashlight-vnc/ | |
| 16 | − * | |
| 17 | − * Full attribution follows: | |
| 18 | − * | |
| 19 | − * ------------------------------------------------------------------------- | |
| 20 | − * | |
| 21 | − * This DES class has been extracted from package Acme.Crypto for use in VNC. | |
| 22 | − * The unnecessary odd parity code has been removed. | |
| 23 | − * | |
| 24 | − * These changes are: | |
| 25 | − * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. | |
| 26 | − * | |
| 27 | − * This software is distributed in the hope that it will be useful, | |
| 28 | − * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 29 | − * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
| 30 | − * | |
| 31 | − | |
| 32 | − * DesCipher - the DES encryption method | |
| 33 | − * | |
| 34 | − * The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is: | |
| 35 | − * | |
| 36 | − * Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. | |
| 37 | − * | |
| 38 | − * Permission to use, copy, modify, and distribute this software | |
| 39 | − * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and | |
| 40 | − * without fee is hereby granted, provided that this copyright notice is kept | |
| 41 | − * intact. | |
| 42 | − * | |
| 43 | − * WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY | |
| 44 | − * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED | |
| 45 | − * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A | |
| 46 | − * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE | |
| 47 | − * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
| 48 | − * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. | |
| 49 | − * | |
| 50 | − * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE | |
| 51 | − * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE | |
| 52 | − * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT | |
| 53 | − * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE | |
| 54 | − * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE | |
| 55 | − * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE | |
| 56 | − * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP | |
| 57 | − * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR | |
| 58 | − * HIGH RISK ACTIVITIES. | |
| 59 | − * | |
| 60 | − * | |
| 61 | − * The rest is: | |
| 62 | − * | |
| 63 | − * Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved. | |
| 64 | − * | |
| 65 | − * Redistribution and use in source and binary forms, with or without | |
| 66 | − * modification, are permitted provided that the following conditions | |
| 67 | − * are met: | |
| 68 | − * 1. Redistributions of source code must retain the above copyright | |
| 69 | − * notice, this list of conditions and the following disclaimer. | |
| 70 | − * 2. Redistributions in binary form must reproduce the above copyright | |
| 71 | − * notice, this list of conditions and the following disclaimer in the | |
| 72 | − * documentation and/or other materials provided with the distribution. | |
| 73 | − * | |
| 74 | − * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
| 75 | − * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 76 | − * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 77 | − * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |
| 78 | − * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| 79 | − * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
| 80 | − * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
| 81 | − * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 82 | − * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
| 83 | − * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
| 84 | − * SUCH DAMAGE. | |
| 85 | − * | |
| 86 | − * Visit the ACME Labs Java page for up-to-date versions of this and other | |
| 87 | − * fine Java utilities: http://www.acme.com/java/ | |
| 88 | − */ | |
| 89 | − | |
| 90 | −/* eslint-disable comma-spacing */ | |
| 91 | − | |
| 92 | −// Tables, permutations, S-boxes, etc. | |
| 93 | −var PC2 = [13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31], | |
| 94 | − totrot = [1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28]; | |
| 95 | −var z = 0x0; | |
| 96 | −var a, b, c, d, e, f; | |
| 97 | −a = 1 << 16; | |
| 98 | −b = 1 << 24; | |
| 99 | −c = a | b; | |
| 100 | −d = 1 << 2; | |
| 101 | −e = 1 << 10; | |
| 102 | −f = d | e; | |
| 103 | −var SP1 = [c | e, z | z, a | z, c | f, c | d, a | f, z | d, a | z, z | e, c | e, c | f, z | e, b | f, c | d, b | z, z | d, z | f, b | e, b | e, a | e, a | e, c | z, c | z, b | f, a | d, b | d, b | d, a | d, z | z, z | f, a | f, b | z, a | z, c | f, z | d, c | z, c | e, b | z, b | z, z | e, c | d, a | z, a | e, b | d, z | e, z | d, b | f, a | f, c | f, a | d, c | z, b | f, b | d, z | f, a | f, c | e, z | f, b | e, b | e, z | z, a | d, a | e, z | z, c | d]; | |
| 104 | −a = 1 << 20; | |
| 105 | −b = 1 << 31; | |
| 106 | −c = a | b; | |
| 107 | −d = 1 << 5; | |
| 108 | −e = 1 << 15; | |
| 109 | −f = d | e; | |
| 110 | −var SP2 = [c | f, b | e, z | e, a | f, a | z, z | d, c | d, b | f, b | d, c | f, c | e, b | z, b | e, a | z, z | d, c | d, a | e, a | d, b | f, z | z, b | z, z | e, a | f, c | z, a | d, b | d, z | z, a | e, z | f, c | e, c | z, z | f, z | z, a | f, c | d, a | z, b | f, c | z, c | e, z | e, c | z, b | e, z | d, c | f, a | f, z | d, z | e, b | z, z | f, c | e, a | z, b | d, a | d, b | f, b | d, a | d, a | e, z | z, b | e, z | f, b | z, c | d, c | f, a | e]; | |
| 111 | −a = 1 << 17; | |
| 112 | −b = 1 << 27; | |
| 113 | −c = a | b; | |
| 114 | −d = 1 << 3; | |
| 115 | −e = 1 << 9; | |
| 116 | −f = d | e; | |
| 117 | −var SP3 = [z | f, c | e, z | z, c | d, b | e, z | z, a | f, b | e, a | d, b | d, b | d, a | z, c | f, a | d, c | z, z | f, b | z, z | d, c | e, z | e, a | e, c | z, c | d, a | f, b | f, a | e, a | z, b | f, z | d, c | f, z | e, b | z, c | e, b | z, a | d, z | f, a | z, c | e, b | e, z | z, z | e, a | d, c | f, b | e, b | d, z | e, z | z, c | d, b | f, a | z, b | z, c | f, z | d, a | f, a | e, b | d, c | z, b | f, z | f, c | z, a | f, z | d, c | d, a | e]; | |
| 118 | −a = 1 << 13; | |
| 119 | −b = 1 << 23; | |
| 120 | −c = a | b; | |
| 121 | −d = 1 << 0; | |
| 122 | −e = 1 << 7; | |
| 123 | −f = d | e; | |
| 124 | −var SP4 = [c | d, a | f, a | f, z | e, c | e, b | f, b | d, a | d, z | z, c | z, c | z, c | f, z | f, z | z, b | e, b | d, z | d, a | z, b | z, c | d, z | e, b | z, a | d, a | e, b | f, z | d, a | e, b | e, a | z, c | e, c | f, z | f, b | e, b | d, c | z, c | f, z | f, z | z, z | z, c | z, a | e, b | e, b | f, z | d, c | d, a | f, a | f, z | e, c | f, z | f, z | d, a | z, b | d, a | d, c | e, b | f, a | d, a | e, b | z, c | d, z | e, b | z, a | z, c | e]; | |
| 125 | −a = 1 << 25; | |
| 126 | −b = 1 << 30; | |
| 127 | −c = a | b; | |
| 128 | −d = 1 << 8; | |
| 129 | −e = 1 << 19; | |
| 130 | −f = d | e; | |
| 131 | −var SP5 = [z | d, a | f, a | e, c | d, z | e, z | d, b | z, a | e, b | f, z | e, a | d, b | f, c | d, c | e, z | f, b | z, a | z, b | e, b | e, z | z, b | d, c | f, c | f, a | d, c | e, b | d, z | z, c | z, a | f, a | z, c | z, z | f, z | e, c | d, z | d, a | z, b | z, a | e, c | d, b | f, a | d, b | z, c | e, a | f, b | f, z | d, a | z, c | e, c | f, z | f, c | z, c | f, a | e, z | z, b | e, c | z, z | f, a | d, b | d, z | e, z | z, b | e, a | f, b | d]; | |
| 132 | −a = 1 << 22; | |
| 133 | −b = 1 << 29; | |
| 134 | −c = a | b; | |
| 135 | −d = 1 << 4; | |
| 136 | −e = 1 << 14; | |
| 137 | −f = d | e; | |
| 138 | −var SP6 = [b | d, c | z, z | e, c | f, c | z, z | d, c | f, a | z, b | e, a | f, a | z, b | d, a | d, b | e, b | z, z | f, z | z, a | d, b | f, z | e, a | e, b | f, z | d, c | d, c | d, z | z, a | f, c | e, z | f, a | e, c | e, b | z, b | e, z | d, c | d, a | e, c | f, a | z, z | f, b | d, a | z, b | e, b | z, z | f, b | d, c | f, a | e, c | z, a | f, c | e, z | z, c | d, z | d, z | e, c | z, a | f, z | e, a | d, b | f, z | z, c | e, b | z, a | d, b | f]; | |
| 139 | −a = 1 << 21; | |
| 140 | −b = 1 << 26; | |
| 141 | −c = a | b; | |
| 142 | −d = 1 << 1; | |
| 143 | −e = 1 << 11; | |
| 144 | −f = d | e; | |
| 145 | −var SP7 = [a | z, c | d, b | f, z | z, z | e, b | f, a | f, c | e, c | f, a | z, z | z, b | d, z | d, b | z, c | d, z | f, b | e, a | f, a | d, b | e, b | d, c | z, c | e, a | d, c | z, z | e, z | f, c | f, a | e, z | d, b | z, a | e, b | z, a | e, a | z, b | f, b | f, c | d, c | d, z | d, a | d, b | z, b | e, a | z, c | e, z | f, a | f, c | e, z | f, b | d, c | f, c | z, a | e, z | z, z | d, c | f, z | z, a | f, c | z, z | e, b | d, b | e, z | e, a | d]; | |
| 146 | −a = 1 << 18; | |
| 147 | −b = 1 << 28; | |
| 148 | −c = a | b; | |
| 149 | −d = 1 << 6; | |
| 150 | −e = 1 << 12; | |
| 151 | −f = d | e; | |
| 152 | −var SP8 = [b | f, z | e, a | z, c | f, b | z, b | f, z | d, b | z, a | d, c | z, c | f, a | e, c | e, a | f, z | e, z | d, c | z, b | d, b | e, z | f, a | e, a | d, c | d, c | e, z | f, z | z, z | z, c | d, b | d, b | e, a | f, a | z, a | f, a | z, c | e, z | e, z | d, c | d, z | e, a | f, b | e, z | d, b | d, c | z, c | d, b | z, a | z, b | f, z | z, c | f, a | d, b | d, c | z, b | e, b | f, z | z, c | f, a | e, a | e, z | f, z | f, a | d, b | z, c | e]; | |
| 153 | − | |
| 154 | −/* eslint-enable comma-spacing */ | |
| 155 | −var DES = /*#__PURE__*/function () { | |
| 156 | − function DES(password) { | |
| 157 | − _classCallCheck(this, DES); | |
| 158 | − this.keys = []; | |
| 159 | − | |
| 160 | − // Set the key. | |
| 161 | − var pc1m = [], | |
| 162 | − pcr = [], | |
| 163 | − kn = []; | |
| 164 | − for (var j = 0, l = 56; j < 56; ++j, l -= 8) { | |
| 165 | − l += l < -5 ? 65 : l < -3 ? 31 : l < -1 ? 63 : l === 27 ? 35 : 0; // PC1 | |
| 166 | − var m = l & 0x7; | |
| 167 | − pc1m[j] = (password[l >>> 3] & 1 << m) !== 0 ? 1 : 0; | |
| 168 | − } | |
| 169 | − for (var i = 0; i < 16; ++i) { | |
| 170 | − var _m = i << 1; | |
| 171 | − var n = _m + 1; | |
| 172 | − kn[_m] = kn[n] = 0; | |
| 173 | − for (var o = 28; o < 59; o += 28) { | |
| 174 | − for (var _j = o - 28; _j < o; ++_j) { | |
| 175 | − var _l = _j + totrot[i]; | |
| 176 | − pcr[_j] = _l < o ? pc1m[_l] : pc1m[_l - 28]; | |
| 177 | − } | |
| 178 | − } | |
| 179 | − for (var _j2 = 0; _j2 < 24; ++_j2) { | |
| 180 | − if (pcr[PC2[_j2]] !== 0) { | |
| 181 | − kn[_m] |= 1 << 23 - _j2; | |
| 182 | − } | |
| 183 | − if (pcr[PC2[_j2 + 24]] !== 0) { | |
| 184 | − kn[n] |= 1 << 23 - _j2; | |
| 185 | − } | |
| 186 | − } | |
| 187 | − } | |
| 188 | − | |
| 189 | − // cookey | |
| 190 | − for (var _i = 0, rawi = 0, KnLi = 0; _i < 16; ++_i) { | |
| 191 | − var raw0 = kn[rawi++]; | |
| 192 | − var raw1 = kn[rawi++]; | |
| 193 | − this.keys[KnLi] = (raw0 & 0x00fc0000) << 6; | |
| 194 | − this.keys[KnLi] |= (raw0 & 0x00000fc0) << 10; | |
| 195 | − this.keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10; | |
| 196 | − this.keys[KnLi] |= (raw1 & 0x00000fc0) >>> 6; | |
| 197 | − ++KnLi; | |
| 198 | − this.keys[KnLi] = (raw0 & 0x0003f000) << 12; | |
| 199 | − this.keys[KnLi] |= (raw0 & 0x0000003f) << 16; | |
| 200 | − this.keys[KnLi] |= (raw1 & 0x0003f000) >>> 4; | |
| 201 | − this.keys[KnLi] |= raw1 & 0x0000003f; | |
| 202 | − ++KnLi; | |
| 203 | − } | |
| 204 | − } | |
| 205 | − | |
| 206 | − // Encrypt 8 bytes of text | |
| 207 | − return _createClass(DES, [{ | |
| 208 | − key: "enc8", | |
| 209 | − value: function enc8(text) { | |
| 210 | − var b = text.slice(); | |
| 211 | − var i = 0, | |
| 212 | − l, | |
| 213 | − r, | |
| 214 | − x; // left, right, accumulator | |
| 215 | − | |
| 216 | − // Squash 8 bytes to 2 ints | |
| 217 | − l = b[i++] << 24 | b[i++] << 16 | b[i++] << 8 | b[i++]; | |
| 218 | − r = b[i++] << 24 | b[i++] << 16 | b[i++] << 8 | b[i++]; | |
| 219 | − x = (l >>> 4 ^ r) & 0x0f0f0f0f; | |
| 220 | − r ^= x; | |
| 221 | − l ^= x << 4; | |
| 222 | − x = (l >>> 16 ^ r) & 0x0000ffff; | |
| 223 | − r ^= x; | |
| 224 | − l ^= x << 16; | |
| 225 | − x = (r >>> 2 ^ l) & 0x33333333; | |
| 226 | − l ^= x; | |
| 227 | − r ^= x << 2; | |
| 228 | − x = (r >>> 8 ^ l) & 0x00ff00ff; | |
| 229 | − l ^= x; | |
| 230 | − r ^= x << 8; | |
| 231 | − r = r << 1 | r >>> 31 & 1; | |
| 232 | − x = (l ^ r) & 0xaaaaaaaa; | |
| 233 | − l ^= x; | |
| 234 | − r ^= x; | |
| 235 | − l = l << 1 | l >>> 31 & 1; | |
| 236 | − for (var _i2 = 0, keysi = 0; _i2 < 8; ++_i2) { | |
| 237 | − x = r << 28 | r >>> 4; | |
| 238 | − x ^= this.keys[keysi++]; | |
| 239 | − var fval = SP7[x & 0x3f]; | |
| 240 | − fval |= SP5[x >>> 8 & 0x3f]; | |
| 241 | − fval |= SP3[x >>> 16 & 0x3f]; | |
| 242 | − fval |= SP1[x >>> 24 & 0x3f]; | |
| 243 | − x = r ^ this.keys[keysi++]; | |
| 244 | − fval |= SP8[x & 0x3f]; | |
| 245 | − fval |= SP6[x >>> 8 & 0x3f]; | |
| 246 | − fval |= SP4[x >>> 16 & 0x3f]; | |
| 247 | − fval |= SP2[x >>> 24 & 0x3f]; | |
| 248 | − l ^= fval; | |
| 249 | − x = l << 28 | l >>> 4; | |
| 250 | − x ^= this.keys[keysi++]; | |
| 251 | − fval = SP7[x & 0x3f]; | |
| 252 | − fval |= SP5[x >>> 8 & 0x3f]; | |
| 253 | − fval |= SP3[x >>> 16 & 0x3f]; | |
| 254 | − fval |= SP1[x >>> 24 & 0x3f]; | |
| 255 | − x = l ^ this.keys[keysi++]; | |
| 256 | − fval |= SP8[x & 0x0000003f]; | |
| 257 | − fval |= SP6[x >>> 8 & 0x3f]; | |
| 258 | − fval |= SP4[x >>> 16 & 0x3f]; | |
| 259 | − fval |= SP2[x >>> 24 & 0x3f]; | |
| 260 | − r ^= fval; | |
| 261 | − } | |
| 262 | − r = r << 31 | r >>> 1; | |
| 263 | − x = (l ^ r) & 0xaaaaaaaa; | |
| 264 | − l ^= x; | |
| 265 | − r ^= x; | |
| 266 | − l = l << 31 | l >>> 1; | |
| 267 | − x = (l >>> 8 ^ r) & 0x00ff00ff; | |
| 268 | − r ^= x; | |
| 269 | − l ^= x << 8; | |
| 270 | − x = (l >>> 2 ^ r) & 0x33333333; | |
| 271 | − r ^= x; | |
| 272 | − l ^= x << 2; | |
| 273 | − x = (r >>> 16 ^ l) & 0x0000ffff; | |
| 274 | − l ^= x; | |
| 275 | − r ^= x << 16; | |
| 276 | − x = (r >>> 4 ^ l) & 0x0f0f0f0f; | |
| 277 | − l ^= x; | |
| 278 | − r ^= x << 4; | |
| 279 | − | |
| 280 | − // Spread ints to bytes | |
| 281 | − x = [r, l]; | |
| 282 | − for (i = 0; i < 8; i++) { | |
| 283 | − b[i] = (x[i >>> 2] >>> 8 * (3 - i % 4)) % 256; | |
| 284 | − if (b[i] < 0) { | |
| 285 | − b[i] += 256; | |
| 286 | − } // unsigned | |
| 287 | − } | |
| 288 | − return b; | |
| 289 | − } | |
| 290 | − }]); | |
| 291 | −}(); | |
| 292 | −var DESECBCipher = exports.DESECBCipher = /*#__PURE__*/function () { | |
| 293 | − function DESECBCipher() { | |
| 294 | − _classCallCheck(this, DESECBCipher); | |
| 295 | − this._cipher = null; | |
| 296 | − } | |
| 297 | − return _createClass(DESECBCipher, [{ | |
| 298 | − key: "algorithm", | |
| 299 | − get: function get() { | |
| 300 | − return { | |
| 301 | − name: "DES-ECB" | |
| 302 | − }; | |
| 303 | − } | |
| 304 | − }, { | |
| 305 | − key: "_importKey", | |
| 306 | − value: function _importKey(key, _extractable, _keyUsages) { | |
| 307 | − this._cipher = new DES(key); | |
| 308 | − } | |
| 309 | − }, { | |
| 310 | − key: "encrypt", | |
| 311 | − value: function encrypt(_algorithm, plaintext) { | |
| 312 | − var x = new Uint8Array(plaintext); | |
| 313 | − if (x.length % 8 !== 0 || this._cipher === null) { | |
| 314 | − return null; | |
| 315 | − } | |
| 316 | − var n = x.length / 8; | |
| 317 | − for (var i = 0; i < n; i++) { | |
| 318 | − x.set(this._cipher.enc8(x.slice(i * 8, i * 8 + 8)), i * 8); | |
| 319 | − } | |
| 320 | − return x; | |
| 321 | − } | |
| 322 | − }], [{ | |
| 323 | − key: "importKey", | |
| 324 | − value: function importKey(key, _algorithm, _extractable, _keyUsages) { | |
| 325 | − var cipher = new DESECBCipher(); | |
| 326 | − cipher._importKey(key); | |
| 327 | − return cipher; | |
| 328 | − } | |
| 329 | − }]); | |
| 330 | −}(); | |
| 331 | −var DESCBCCipher = exports.DESCBCCipher = /*#__PURE__*/function () { | |
| 332 | − function DESCBCCipher() { | |
| 333 | − _classCallCheck(this, DESCBCCipher); | |
| 334 | − this._cipher = null; | |
| 335 | − } | |
| 336 | − return _createClass(DESCBCCipher, [{ | |
| 337 | − key: "algorithm", | |
| 338 | − get: function get() { | |
| 339 | − return { | |
| 340 | − name: "DES-CBC" | |
| 341 | − }; | |
| 342 | − } | |
| 343 | − }, { | |
| 344 | − key: "_importKey", | |
| 345 | − value: function _importKey(key) { | |
| 346 | − this._cipher = new DES(key); | |
| 347 | − } | |
| 348 | − }, { | |
| 349 | − key: "encrypt", | |
| 350 | − value: function encrypt(algorithm, plaintext) { | |
| 351 | − var x = new Uint8Array(plaintext); | |
| 352 | − var y = new Uint8Array(algorithm.iv); | |
| 353 | − if (x.length % 8 !== 0 || this._cipher === null) { | |
| 354 | − return null; | |
| 355 | − } | |
| 356 | − var n = x.length / 8; | |
| 357 | − for (var i = 0; i < n; i++) { | |
| 358 | − for (var j = 0; j < 8; j++) { | |
| 359 | − y[j] ^= plaintext[i * 8 + j]; | |
| 360 | − } | |
| 361 | − y = this._cipher.enc8(y); | |
| 362 | − x.set(y, i * 8); | |
| 363 | − } | |
| 364 | − return x; | |
| 365 | − } | |
| 366 | − }], [{ | |
| 367 | − key: "importKey", | |
| 368 | − value: function importKey(key, _algorithm, _extractable, _keyUsages) { | |
| 369 | − var cipher = new DESCBCCipher(); | |
| 370 | − cipher._importKey(key); | |
| 371 | − return cipher; | |
| 372 | − } | |
| 373 | − }]); | |
| 374 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/crypto/dh.js
+0 −81
@@ -1,81 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports.DHCipher = void 0; | |
| 7 | −var _bigint = require("./bigint.js"); | |
| 8 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 9 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 10 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 11 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 12 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 13 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 14 | −var DHPublicKey = /*#__PURE__*/function () { | |
| 15 | − function DHPublicKey(key) { | |
| 16 | − _classCallCheck(this, DHPublicKey); | |
| 17 | − this._key = key; | |
| 18 | − } | |
| 19 | − return _createClass(DHPublicKey, [{ | |
| 20 | − key: "algorithm", | |
| 21 | − get: function get() { | |
| 22 | − return { | |
| 23 | − name: "DH" | |
| 24 | − }; | |
| 25 | − } | |
| 26 | − }, { | |
| 27 | − key: "exportKey", | |
| 28 | − value: function exportKey() { | |
| 29 | − return this._key; | |
| 30 | − } | |
| 31 | − }]); | |
| 32 | −}(); | |
| 33 | −var DHCipher = exports.DHCipher = /*#__PURE__*/function () { | |
| 34 | − function DHCipher() { | |
| 35 | − _classCallCheck(this, DHCipher); | |
| 36 | − this._g = null; | |
| 37 | − this._p = null; | |
| 38 | − this._gBigInt = null; | |
| 39 | − this._pBigInt = null; | |
| 40 | − this._privateKey = null; | |
| 41 | − } | |
| 42 | − return _createClass(DHCipher, [{ | |
| 43 | − key: "algorithm", | |
| 44 | − get: function get() { | |
| 45 | − return { | |
| 46 | − name: "DH" | |
| 47 | − }; | |
| 48 | − } | |
| 49 | − }, { | |
| 50 | − key: "_generateKey", | |
| 51 | − value: function _generateKey(algorithm) { | |
| 52 | − var g = algorithm.g; | |
| 53 | − var p = algorithm.p; | |
| 54 | − this._keyBytes = p.length; | |
| 55 | − this._gBigInt = (0, _bigint.u8ArrayToBigInt)(g); | |
| 56 | − this._pBigInt = (0, _bigint.u8ArrayToBigInt)(p); | |
| 57 | − this._privateKey = window.crypto.getRandomValues(new Uint8Array(this._keyBytes)); | |
| 58 | − this._privateKeyBigInt = (0, _bigint.u8ArrayToBigInt)(this._privateKey); | |
| 59 | − this._publicKey = (0, _bigint.bigIntToU8Array)((0, _bigint.modPow)(this._gBigInt, this._privateKeyBigInt, this._pBigInt), this._keyBytes); | |
| 60 | − } | |
| 61 | − }, { | |
| 62 | − key: "deriveBits", | |
| 63 | − value: function deriveBits(algorithm, length) { | |
| 64 | − var bytes = Math.ceil(length / 8); | |
| 65 | − var pkey = new Uint8Array(algorithm["public"]); | |
| 66 | − var len = bytes > this._keyBytes ? bytes : this._keyBytes; | |
| 67 | − var secret = (0, _bigint.modPow)((0, _bigint.u8ArrayToBigInt)(pkey), this._privateKeyBigInt, this._pBigInt); | |
| 68 | − return (0, _bigint.bigIntToU8Array)(secret, len).slice(0, len); | |
| 69 | − } | |
| 70 | − }], [{ | |
| 71 | − key: "generateKey", | |
| 72 | − value: function generateKey(algorithm, _extractable) { | |
| 73 | − var cipher = new DHCipher(); | |
| 74 | − cipher._generateKey(algorithm); | |
| 75 | − return { | |
| 76 | − privateKey: cipher, | |
| 77 | − publicKey: new DHPublicKey(cipher._publicKey) | |
| 78 | − }; | |
| 79 | − } | |
| 80 | − }]); | |
| 81 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/crypto/md5.js
+0 −97
@@ -1,97 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports.MD5 = MD5; | |
| 7 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 8 | −function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } | |
| 9 | −function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } | |
| 10 | −function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } | |
| 11 | −/* | |
| 12 | − * noVNC: HTML5 VNC client | |
| 13 | − * Copyright (C) 2021 The noVNC authors | |
| 14 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 15 | − * | |
| 16 | − * See README.md for usage and integration instructions. | |
| 17 | − */ | |
| 18 | −/* | |
| 19 | − * Performs MD5 hashing on an array of bytes, returns an array of bytes | |
| 20 | − */ | |
| 21 | −function MD5(_x) { | |
| 22 | − return _MD.apply(this, arguments); | |
| 23 | −} | |
| 24 | −function _MD() { | |
| 25 | − _MD = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(d) { | |
| 26 | − var s, i; | |
| 27 | − return _regeneratorRuntime().wrap(function _callee$(_context) { | |
| 28 | − while (1) switch (_context.prev = _context.next) { | |
| 29 | − case 0: | |
| 30 | − s = ""; | |
| 31 | − for (i = 0; i < d.length; i++) { | |
| 32 | − s += String.fromCharCode(d[i]); | |
| 33 | − } | |
| 34 | − return _context.abrupt("return", M(V(Y(X(s), 8 * s.length)))); | |
| 35 | − case 3: | |
| 36 | − case "end": | |
| 37 | − return _context.stop(); | |
| 38 | − } | |
| 39 | − }, _callee); | |
| 40 | − })); | |
| 41 | − return _MD.apply(this, arguments); | |
| 42 | −} | |
| 43 | −function M(d) { | |
| 44 | − var f = new Uint8Array(d.length); | |
| 45 | − for (var i = 0; i < d.length; i++) { | |
| 46 | − f[i] = d.charCodeAt(i); | |
| 47 | − } | |
| 48 | − return f; | |
| 49 | −} | |
| 50 | −function X(d) { | |
| 51 | − var r = Array(d.length >> 2); | |
| 52 | − for (var m = 0; m < r.length; m++) r[m] = 0; | |
| 53 | − for (var _m = 0; _m < 8 * d.length; _m += 8) r[_m >> 5] |= (255 & d.charCodeAt(_m / 8)) << _m % 32; | |
| 54 | − return r; | |
| 55 | −} | |
| 56 | −function V(d) { | |
| 57 | − var r = ""; | |
| 58 | − for (var m = 0; m < 32 * d.length; m += 8) r += String.fromCharCode(d[m >> 5] >>> m % 32 & 255); | |
| 59 | − return r; | |
| 60 | −} | |
| 61 | −function Y(d, g) { | |
| 62 | − d[g >> 5] |= 128 << g % 32, d[14 + (g + 64 >>> 9 << 4)] = g; | |
| 63 | − var m = 1732584193, | |
| 64 | − f = -271733879, | |
| 65 | − r = -1732584194, | |
| 66 | − i = 271733878; | |
| 67 | − for (var n = 0; n < d.length; n += 16) { | |
| 68 | − var h = m, | |
| 69 | − t = f, | |
| 70 | − _g = r, | |
| 71 | − e = i; | |
| 72 | − f = ii(f = ii(f = ii(f = ii(f = hh(f = hh(f = hh(f = hh(f = gg(f = gg(f = gg(f = gg(f = ff(f = ff(f = ff(f = ff(f, r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 0], 7, -680876936), f, r, d[n + 1], 12, -389564586), m, f, d[n + 2], 17, 606105819), i, m, d[n + 3], 22, -1044525330), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 4], 7, -176418897), f, r, d[n + 5], 12, 1200080426), m, f, d[n + 6], 17, -1473231341), i, m, d[n + 7], 22, -45705983), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 8], 7, 1770035416), f, r, d[n + 9], 12, -1958414417), m, f, d[n + 10], 17, -42063), i, m, d[n + 11], 22, -1990404162), r = ff(r, i = ff(i, m = ff(m, f, r, i, d[n + 12], 7, 1804603682), f, r, d[n + 13], 12, -40341101), m, f, d[n + 14], 17, -1502002290), i, m, d[n + 15], 22, 1236535329), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 1], 5, -165796510), f, r, d[n + 6], 9, -1069501632), m, f, d[n + 11], 14, 643717713), i, m, d[n + 0], 20, -373897302), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 5], 5, -701558691), f, r, d[n + 10], 9, 38016083), m, f, d[n + 15], 14, -660478335), i, m, d[n + 4], 20, -405537848), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 9], 5, 568446438), f, r, d[n + 14], 9, -1019803690), m, f, d[n + 3], 14, -187363961), i, m, d[n + 8], 20, 1163531501), r = gg(r, i = gg(i, m = gg(m, f, r, i, d[n + 13], 5, -1444681467), f, r, d[n + 2], 9, -51403784), m, f, d[n + 7], 14, 1735328473), i, m, d[n + 12], 20, -1926607734), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 5], 4, -378558), f, r, d[n + 8], 11, -2022574463), m, f, d[n + 11], 16, 1839030562), i, m, d[n + 14], 23, -35309556), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 1], 4, -1530992060), f, r, d[n + 4], 11, 1272893353), m, f, d[n + 7], 16, -155497632), i, m, d[n + 10], 23, -1094730640), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 13], 4, 681279174), f, r, d[n + 0], 11, -358537222), m, f, d[n + 3], 16, -722521979), i, m, d[n + 6], 23, 76029189), r = hh(r, i = hh(i, m = hh(m, f, r, i, d[n + 9], 4, -640364487), f, r, d[n + 12], 11, -421815835), m, f, d[n + 15], 16, 530742520), i, m, d[n + 2], 23, -995338651), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 0], 6, -198630844), f, r, d[n + 7], 10, 1126891415), m, f, d[n + 14], 15, -1416354905), i, m, d[n + 5], 21, -57434055), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 12], 6, 1700485571), f, r, d[n + 3], 10, -1894986606), m, f, d[n + 10], 15, -1051523), i, m, d[n + 1], 21, -2054922799), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 8], 6, 1873313359), f, r, d[n + 15], 10, -30611744), m, f, d[n + 6], 15, -1560198380), i, m, d[n + 13], 21, 1309151649), r = ii(r, i = ii(i, m = ii(m, f, r, i, d[n + 4], 6, -145523070), f, r, d[n + 11], 10, -1120210379), m, f, d[n + 2], 15, 718787259), i, m, d[n + 9], 21, -343485551), m = add(m, h), f = add(f, t), r = add(r, _g), i = add(i, e); | |
| 73 | − } | |
| 74 | − return Array(m, f, r, i); | |
| 75 | −} | |
| 76 | −function cmn(d, g, m, f, r, i) { | |
| 77 | − return add(rol(add(add(g, d), add(f, i)), r), m); | |
| 78 | −} | |
| 79 | −function ff(d, g, m, f, r, i, n) { | |
| 80 | − return cmn(g & m | ~g & f, d, g, r, i, n); | |
| 81 | −} | |
| 82 | −function gg(d, g, m, f, r, i, n) { | |
| 83 | − return cmn(g & f | m & ~f, d, g, r, i, n); | |
| 84 | −} | |
| 85 | −function hh(d, g, m, f, r, i, n) { | |
| 86 | − return cmn(g ^ m ^ f, d, g, r, i, n); | |
| 87 | −} | |
| 88 | −function ii(d, g, m, f, r, i, n) { | |
| 89 | − return cmn(m ^ (g | ~f), d, g, r, i, n); | |
| 90 | −} | |
| 91 | −function add(d, g) { | |
| 92 | − var m = (65535 & d) + (65535 & g); | |
| 93 | − return (d >> 16) + (g >> 16) + (m >> 16) << 16 | 65535 & m; | |
| 94 | −} | |
| 95 | −function rol(d, g) { | |
| 96 | − return d << g | d >>> 32 - g; | |
| 97 | −} | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/crypto/rsa.js
+0 −312
@@ -1,312 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports.RSACipher = void 0; | |
| 7 | −var _base = _interopRequireDefault(require("../base64.js")); | |
| 8 | −var _bigint = require("./bigint.js"); | |
| 9 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 10 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 11 | −function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } | |
| 12 | −function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } | |
| 13 | −function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } | |
| 14 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 15 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 16 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 17 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 18 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 19 | −var RSACipher = exports.RSACipher = /*#__PURE__*/function () { | |
| 20 | − function RSACipher() { | |
| 21 | − _classCallCheck(this, RSACipher); | |
| 22 | − this._keyLength = 0; | |
| 23 | − this._keyBytes = 0; | |
| 24 | − this._n = null; | |
| 25 | − this._e = null; | |
| 26 | − this._d = null; | |
| 27 | − this._nBigInt = null; | |
| 28 | − this._eBigInt = null; | |
| 29 | − this._dBigInt = null; | |
| 30 | − this._extractable = false; | |
| 31 | − } | |
| 32 | − return _createClass(RSACipher, [{ | |
| 33 | − key: "algorithm", | |
| 34 | − get: function get() { | |
| 35 | − return { | |
| 36 | − name: "RSA-PKCS1-v1_5" | |
| 37 | − }; | |
| 38 | − } | |
| 39 | − }, { | |
| 40 | − key: "_base64urlDecode", | |
| 41 | − value: function _base64urlDecode(data) { | |
| 42 | − data = data.replace(/-/g, "+").replace(/_/g, "/"); | |
| 43 | − data = data.padEnd(Math.ceil(data.length / 4) * 4, "="); | |
| 44 | − return _base["default"].decode(data); | |
| 45 | − } | |
| 46 | − }, { | |
| 47 | − key: "_padArray", | |
| 48 | − value: function _padArray(arr, length) { | |
| 49 | − var res = new Uint8Array(length); | |
| 50 | − res.set(arr, length - arr.length); | |
| 51 | − return res; | |
| 52 | − } | |
| 53 | − }, { | |
| 54 | − key: "_generateKey", | |
| 55 | − value: function () { | |
| 56 | − var _generateKey2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(algorithm, extractable) { | |
| 57 | − var key, privateKey; | |
| 58 | − return _regeneratorRuntime().wrap(function _callee$(_context) { | |
| 59 | − while (1) switch (_context.prev = _context.next) { | |
| 60 | − case 0: | |
| 61 | − this._keyLength = algorithm.modulusLength; | |
| 62 | − this._keyBytes = Math.ceil(this._keyLength / 8); | |
| 63 | − _context.next = 4; | |
| 64 | − return window.crypto.subtle.generateKey({ | |
| 65 | − name: "RSA-OAEP", | |
| 66 | − modulusLength: algorithm.modulusLength, | |
| 67 | − publicExponent: algorithm.publicExponent, | |
| 68 | − hash: { | |
| 69 | − name: "SHA-256" | |
| 70 | − } | |
| 71 | − }, true, ["encrypt", "decrypt"]); | |
| 72 | − case 4: | |
| 73 | − key = _context.sent; | |
| 74 | − _context.next = 7; | |
| 75 | − return window.crypto.subtle.exportKey("jwk", key.privateKey); | |
| 76 | − case 7: | |
| 77 | − privateKey = _context.sent; | |
| 78 | − this._n = this._padArray(this._base64urlDecode(privateKey.n), this._keyBytes); | |
| 79 | − this._nBigInt = (0, _bigint.u8ArrayToBigInt)(this._n); | |
| 80 | − this._e = this._padArray(this._base64urlDecode(privateKey.e), this._keyBytes); | |
| 81 | − this._eBigInt = (0, _bigint.u8ArrayToBigInt)(this._e); | |
| 82 | − this._d = this._padArray(this._base64urlDecode(privateKey.d), this._keyBytes); | |
| 83 | − this._dBigInt = (0, _bigint.u8ArrayToBigInt)(this._d); | |
| 84 | − this._extractable = extractable; | |
| 85 | − case 15: | |
| 86 | − case "end": | |
| 87 | − return _context.stop(); | |
| 88 | − } | |
| 89 | − }, _callee, this); | |
| 90 | − })); | |
| 91 | − function _generateKey(_x, _x2) { | |
| 92 | − return _generateKey2.apply(this, arguments); | |
| 93 | − } | |
| 94 | − return _generateKey; | |
| 95 | − }() | |
| 96 | − }, { | |
| 97 | − key: "_importKey", | |
| 98 | − value: function () { | |
| 99 | − var _importKey2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(key, extractable) { | |
| 100 | − var n, e; | |
| 101 | − return _regeneratorRuntime().wrap(function _callee2$(_context2) { | |
| 102 | − while (1) switch (_context2.prev = _context2.next) { | |
| 103 | − case 0: | |
| 104 | − n = key.n; | |
| 105 | − e = key.e; | |
| 106 | − if (!(n.length !== e.length)) { | |
| 107 | − _context2.next = 4; | |
| 108 | − break; | |
| 109 | − } | |
| 110 | − throw new Error("the sizes of modulus and public exponent do not match"); | |
| 111 | − case 4: | |
| 112 | − this._keyBytes = n.length; | |
| 113 | − this._keyLength = this._keyBytes * 8; | |
| 114 | − this._n = new Uint8Array(this._keyBytes); | |
| 115 | − this._e = new Uint8Array(this._keyBytes); | |
| 116 | − this._n.set(n); | |
| 117 | − this._e.set(e); | |
| 118 | − this._nBigInt = (0, _bigint.u8ArrayToBigInt)(this._n); | |
| 119 | − this._eBigInt = (0, _bigint.u8ArrayToBigInt)(this._e); | |
| 120 | − this._extractable = extractable; | |
| 121 | − case 13: | |
| 122 | − case "end": | |
| 123 | − return _context2.stop(); | |
| 124 | − } | |
| 125 | − }, _callee2, this); | |
| 126 | − })); | |
| 127 | − function _importKey(_x3, _x4) { | |
| 128 | − return _importKey2.apply(this, arguments); | |
| 129 | − } | |
| 130 | − return _importKey; | |
| 131 | − }() | |
| 132 | − }, { | |
| 133 | − key: "encrypt", | |
| 134 | − value: function () { | |
| 135 | − var _encrypt = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(_algorithm, message) { | |
| 136 | − var ps, i, em, emBigInt, c; | |
| 137 | − return _regeneratorRuntime().wrap(function _callee3$(_context3) { | |
| 138 | − while (1) switch (_context3.prev = _context3.next) { | |
| 139 | − case 0: | |
| 140 | − if (!(message.length > this._keyBytes - 11)) { | |
| 141 | − _context3.next = 2; | |
| 142 | − break; | |
| 143 | − } | |
| 144 | − return _context3.abrupt("return", null); | |
| 145 | − case 2: | |
| 146 | − ps = new Uint8Array(this._keyBytes - message.length - 3); | |
| 147 | − window.crypto.getRandomValues(ps); | |
| 148 | − for (i = 0; i < ps.length; i++) { | |
| 149 | − ps[i] = Math.floor(ps[i] * 254 / 255 + 1); | |
| 150 | − } | |
| 151 | − em = new Uint8Array(this._keyBytes); | |
| 152 | − em[1] = 0x02; | |
| 153 | − em.set(ps, 2); | |
| 154 | − em.set(message, ps.length + 3); | |
| 155 | − emBigInt = (0, _bigint.u8ArrayToBigInt)(em); | |
| 156 | − c = (0, _bigint.modPow)(emBigInt, this._eBigInt, this._nBigInt); | |
| 157 | − return _context3.abrupt("return", (0, _bigint.bigIntToU8Array)(c, this._keyBytes)); | |
| 158 | − case 12: | |
| 159 | − case "end": | |
| 160 | − return _context3.stop(); | |
| 161 | − } | |
| 162 | − }, _callee3, this); | |
| 163 | − })); | |
| 164 | − function encrypt(_x5, _x6) { | |
| 165 | − return _encrypt.apply(this, arguments); | |
| 166 | − } | |
| 167 | − return encrypt; | |
| 168 | − }() | |
| 169 | − }, { | |
| 170 | − key: "decrypt", | |
| 171 | − value: function () { | |
| 172 | − var _decrypt = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4(_algorithm, message) { | |
| 173 | − var msgBigInt, emBigInt, em, i; | |
| 174 | − return _regeneratorRuntime().wrap(function _callee4$(_context4) { | |
| 175 | − while (1) switch (_context4.prev = _context4.next) { | |
| 176 | − case 0: | |
| 177 | − if (!(message.length !== this._keyBytes)) { | |
| 178 | − _context4.next = 2; | |
| 179 | − break; | |
| 180 | − } | |
| 181 | − return _context4.abrupt("return", null); | |
| 182 | − case 2: | |
| 183 | − msgBigInt = (0, _bigint.u8ArrayToBigInt)(message); | |
| 184 | − emBigInt = (0, _bigint.modPow)(msgBigInt, this._dBigInt, this._nBigInt); | |
| 185 | − em = (0, _bigint.bigIntToU8Array)(emBigInt, this._keyBytes); | |
| 186 | − if (!(em[0] !== 0x00 || em[1] !== 0x02)) { | |
| 187 | − _context4.next = 7; | |
| 188 | − break; | |
| 189 | − } | |
| 190 | − return _context4.abrupt("return", null); | |
| 191 | − case 7: | |
| 192 | − i = 2; | |
| 193 | − case 8: | |
| 194 | − if (!(i < em.length)) { | |
| 195 | − _context4.next = 14; | |
| 196 | − break; | |
| 197 | − } | |
| 198 | − if (!(em[i] === 0x00)) { | |
| 199 | − _context4.next = 11; | |
| 200 | − break; | |
| 201 | − } | |
| 202 | − return _context4.abrupt("break", 14); | |
| 203 | − case 11: | |
| 204 | − i++; | |
| 205 | − _context4.next = 8; | |
| 206 | − break; | |
| 207 | − case 14: | |
| 208 | − if (!(i === em.length)) { | |
| 209 | − _context4.next = 16; | |
| 210 | − break; | |
| 211 | − } | |
| 212 | − return _context4.abrupt("return", null); | |
| 213 | − case 16: | |
| 214 | − return _context4.abrupt("return", em.slice(i + 1, em.length)); | |
| 215 | − case 17: | |
| 216 | − case "end": | |
| 217 | − return _context4.stop(); | |
| 218 | − } | |
| 219 | − }, _callee4, this); | |
| 220 | − })); | |
| 221 | − function decrypt(_x7, _x8) { | |
| 222 | − return _decrypt.apply(this, arguments); | |
| 223 | − } | |
| 224 | − return decrypt; | |
| 225 | − }() | |
| 226 | − }, { | |
| 227 | − key: "exportKey", | |
| 228 | − value: function () { | |
| 229 | − var _exportKey = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee5() { | |
| 230 | − return _regeneratorRuntime().wrap(function _callee5$(_context5) { | |
| 231 | − while (1) switch (_context5.prev = _context5.next) { | |
| 232 | − case 0: | |
| 233 | − if (this._extractable) { | |
| 234 | − _context5.next = 2; | |
| 235 | − break; | |
| 236 | − } | |
| 237 | − throw new Error("key is not extractable"); | |
| 238 | − case 2: | |
| 239 | − return _context5.abrupt("return", { | |
| 240 | − n: this._n, | |
| 241 | − e: this._e, | |
| 242 | − d: this._d | |
| 243 | − }); | |
| 244 | − case 3: | |
| 245 | − case "end": | |
| 246 | − return _context5.stop(); | |
| 247 | − } | |
| 248 | − }, _callee5, this); | |
| 249 | − })); | |
| 250 | − function exportKey() { | |
| 251 | − return _exportKey.apply(this, arguments); | |
| 252 | − } | |
| 253 | − return exportKey; | |
| 254 | − }() | |
| 255 | − }], [{ | |
| 256 | − key: "generateKey", | |
| 257 | − value: function () { | |
| 258 | − var _generateKey3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee6(algorithm, extractable, _keyUsages) { | |
| 259 | − var cipher; | |
| 260 | − return _regeneratorRuntime().wrap(function _callee6$(_context6) { | |
| 261 | − while (1) switch (_context6.prev = _context6.next) { | |
| 262 | − case 0: | |
| 263 | − cipher = new RSACipher(); | |
| 264 | − _context6.next = 3; | |
| 265 | − return cipher._generateKey(algorithm, extractable); | |
| 266 | − case 3: | |
| 267 | − return _context6.abrupt("return", { | |
| 268 | − privateKey: cipher | |
| 269 | − }); | |
| 270 | − case 4: | |
| 271 | − case "end": | |
| 272 | − return _context6.stop(); | |
| 273 | − } | |
| 274 | − }, _callee6); | |
| 275 | − })); | |
| 276 | − function generateKey(_x9, _x10, _x11) { | |
| 277 | − return _generateKey3.apply(this, arguments); | |
| 278 | − } | |
| 279 | − return generateKey; | |
| 280 | − }() | |
| 281 | − }, { | |
| 282 | − key: "importKey", | |
| 283 | − value: function () { | |
| 284 | − var _importKey3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee7(key, _algorithm, extractable, keyUsages) { | |
| 285 | − var cipher; | |
| 286 | − return _regeneratorRuntime().wrap(function _callee7$(_context7) { | |
| 287 | − while (1) switch (_context7.prev = _context7.next) { | |
| 288 | − case 0: | |
| 289 | − if (!(keyUsages.length !== 1 || keyUsages[0] !== "encrypt")) { | |
| 290 | − _context7.next = 2; | |
| 291 | − break; | |
| 292 | − } | |
| 293 | − throw new Error("only support importing RSA public key"); | |
| 294 | − case 2: | |
| 295 | − cipher = new RSACipher(); | |
| 296 | − _context7.next = 5; | |
| 297 | − return cipher._importKey(key, extractable); | |
| 298 | − case 5: | |
| 299 | − return _context7.abrupt("return", cipher); | |
| 300 | − case 6: | |
| 301 | − case "end": | |
| 302 | − return _context7.stop(); | |
| 303 | − } | |
| 304 | − }, _callee7); | |
| 305 | − })); | |
| 306 | − function importKey(_x12, _x13, _x14, _x15) { | |
| 307 | − return _importKey3.apply(this, arguments); | |
| 308 | − } | |
| 309 | − return importKey; | |
| 310 | − }() | |
| 311 | − }]); | |
| 312 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/decoders/copyrect.js
+0 −40
@@ -1,40 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 8 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 9 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 10 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 11 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 12 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 13 | −/* | |
| 14 | − * noVNC: HTML5 VNC client | |
| 15 | − * Copyright (C) 2019 The noVNC authors | |
| 16 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 17 | − * | |
| 18 | − * See README.md for usage and integration instructions. | |
| 19 | − * | |
| 20 | − */ | |
| 21 | −var CopyRectDecoder = exports["default"] = /*#__PURE__*/function () { | |
| 22 | − function CopyRectDecoder() { | |
| 23 | − _classCallCheck(this, CopyRectDecoder); | |
| 24 | − } | |
| 25 | − return _createClass(CopyRectDecoder, [{ | |
| 26 | − key: "decodeRect", | |
| 27 | − value: function decodeRect(x, y, width, height, sock, display, depth) { | |
| 28 | − if (sock.rQwait("COPYRECT", 4)) { | |
| 29 | − return false; | |
| 30 | − } | |
| 31 | − var deltaX = sock.rQshift16(); | |
| 32 | − var deltaY = sock.rQshift16(); | |
| 33 | − if (width === 0 || height === 0) { | |
| 34 | − return true; | |
| 35 | − } | |
| 36 | − display.copyImage(deltaX, deltaY, x, y, width, height); | |
| 37 | − return true; | |
| 38 | − } | |
| 39 | − }]); | |
| 40 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/decoders/h264.js
+0 −349
@@ -1,349 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = exports.H264Parser = exports.H264Context = void 0; | |
| 7 | −var Log = _interopRequireWildcard(require("../util/logging.js")); | |
| 8 | −function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } | |
| 9 | −function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } | |
| 10 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 11 | −function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } | |
| 12 | −function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } | |
| 13 | −function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } | |
| 14 | −function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } | |
| 15 | −function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } | |
| 16 | −function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } | |
| 17 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 18 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 19 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 20 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 21 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /* | |
| 22 | − * noVNC: HTML5 VNC client | |
| 23 | − * Copyright (C) 2024 The noVNC authors | |
| 24 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 25 | − * | |
| 26 | − * See README.md for usage and integration instructions. | |
| 27 | − * | |
| 28 | − */ | |
| 29 | −var H264Parser = exports.H264Parser = /*#__PURE__*/function () { | |
| 30 | − function H264Parser(data) { | |
| 31 | − _classCallCheck(this, H264Parser); | |
| 32 | − this._data = data; | |
| 33 | − this._index = 0; | |
| 34 | − this.profileIdc = null; | |
| 35 | − this.constraintSet = null; | |
| 36 | − this.levelIdc = null; | |
| 37 | − } | |
| 38 | − return _createClass(H264Parser, [{ | |
| 39 | − key: "_getStartSequenceLen", | |
| 40 | − value: function _getStartSequenceLen(index) { | |
| 41 | − var data = this._data; | |
| 42 | − if (data[index + 0] == 0 && data[index + 1] == 0 && data[index + 2] == 0 && data[index + 3] == 1) { | |
| 43 | − return 4; | |
| 44 | − } | |
| 45 | − if (data[index + 0] == 0 && data[index + 1] == 0 && data[index + 2] == 1) { | |
| 46 | − return 3; | |
| 47 | − } | |
| 48 | − return 0; | |
| 49 | − } | |
| 50 | − }, { | |
| 51 | − key: "_indexOfNextNalUnit", | |
| 52 | − value: function _indexOfNextNalUnit(index) { | |
| 53 | − var data = this._data; | |
| 54 | − for (var i = index; i < data.length; ++i) { | |
| 55 | − if (this._getStartSequenceLen(i) != 0) { | |
| 56 | − return i; | |
| 57 | − } | |
| 58 | − } | |
| 59 | − return -1; | |
| 60 | − } | |
| 61 | − }, { | |
| 62 | − key: "_parseSps", | |
| 63 | − value: function _parseSps(index) { | |
| 64 | − this.profileIdc = this._data[index]; | |
| 65 | − this.constraintSet = this._data[index + 1]; | |
| 66 | − this.levelIdc = this._data[index + 2]; | |
| 67 | − } | |
| 68 | − }, { | |
| 69 | − key: "_parseNalUnit", | |
| 70 | − value: function _parseNalUnit(index) { | |
| 71 | − var firstByte = this._data[index]; | |
| 72 | − if (firstByte & 0x80) { | |
| 73 | − throw new Error('H264 parsing sanity check failed, forbidden zero bit is set'); | |
| 74 | − } | |
| 75 | − var unitType = firstByte & 0x1f; | |
| 76 | − switch (unitType) { | |
| 77 | − case 1: | |
| 78 | − // coded slice, non-idr | |
| 79 | − return { | |
| 80 | − slice: true | |
| 81 | − }; | |
| 82 | − case 5: | |
| 83 | − // coded slice, idr | |
| 84 | − return { | |
| 85 | − slice: true, | |
| 86 | − key: true | |
| 87 | − }; | |
| 88 | − case 6: | |
| 89 | − // sei | |
| 90 | − return {}; | |
| 91 | − case 7: | |
| 92 | − // sps | |
| 93 | − this._parseSps(index + 1); | |
| 94 | − return {}; | |
| 95 | − case 8: | |
| 96 | − // pps | |
| 97 | − return {}; | |
| 98 | − default: | |
| 99 | − Log.Warn("Unhandled unit type: ", unitType); | |
| 100 | − break; | |
| 101 | − } | |
| 102 | − return {}; | |
| 103 | − } | |
| 104 | − }, { | |
| 105 | − key: "parse", | |
| 106 | − value: function parse() { | |
| 107 | − var startIndex = this._index; | |
| 108 | − var isKey = false; | |
| 109 | − while (this._index < this._data.length) { | |
| 110 | − var startSequenceLen = this._getStartSequenceLen(this._index); | |
| 111 | − if (startSequenceLen == 0) { | |
| 112 | − throw new Error('Invalid start sequence in bit stream'); | |
| 113 | − } | |
| 114 | − var _this$_parseNalUnit = this._parseNalUnit(this._index + startSequenceLen), | |
| 115 | − slice = _this$_parseNalUnit.slice, | |
| 116 | − key = _this$_parseNalUnit.key; | |
| 117 | − var nextIndex = this._indexOfNextNalUnit(this._index + startSequenceLen); | |
| 118 | − if (nextIndex == -1) { | |
| 119 | − this._index = this._data.length; | |
| 120 | − } else { | |
| 121 | − this._index = nextIndex; | |
| 122 | − } | |
| 123 | − if (key) { | |
| 124 | − isKey = true; | |
| 125 | − } | |
| 126 | − if (slice) { | |
| 127 | − break; | |
| 128 | − } | |
| 129 | − } | |
| 130 | − if (startIndex === this._index) { | |
| 131 | − return null; | |
| 132 | − } | |
| 133 | − return { | |
| 134 | − frame: this._data.subarray(startIndex, this._index), | |
| 135 | − key: isKey | |
| 136 | − }; | |
| 137 | − } | |
| 138 | − }]); | |
| 139 | −}(); | |
| 140 | −var H264Context = exports.H264Context = /*#__PURE__*/function () { | |
| 141 | − function H264Context(width, height) { | |
| 142 | − _classCallCheck(this, H264Context); | |
| 143 | − this.lastUsed = 0; | |
| 144 | − this._width = width; | |
| 145 | − this._height = height; | |
| 146 | − this._profileIdc = null; | |
| 147 | − this._constraintSet = null; | |
| 148 | − this._levelIdc = null; | |
| 149 | − this._decoder = null; | |
| 150 | − this._pendingFrames = []; | |
| 151 | − } | |
| 152 | − return _createClass(H264Context, [{ | |
| 153 | − key: "_handleFrame", | |
| 154 | − value: function _handleFrame(frame) { | |
| 155 | − var pending = this._pendingFrames.shift(); | |
| 156 | − if (pending === undefined) { | |
| 157 | − throw new Error("Pending frame queue empty when receiving frame from decoder"); | |
| 158 | − } | |
| 159 | − if (pending.timestamp != frame.timestamp) { | |
| 160 | − throw new Error("Video frame timestamp mismatch. Expected " + frame.timestamp + " but but got " + pending.timestamp); | |
| 161 | − } | |
| 162 | − pending.frame = frame; | |
| 163 | − pending.ready = true; | |
| 164 | − pending.resolve(); | |
| 165 | − if (!pending.keep) { | |
| 166 | − frame.close(); | |
| 167 | − } | |
| 168 | − } | |
| 169 | − }, { | |
| 170 | − key: "_handleError", | |
| 171 | − value: function _handleError(e) { | |
| 172 | − throw new Error("Failed to decode frame: " + e.message); | |
| 173 | − } | |
| 174 | − }, { | |
| 175 | − key: "_configureDecoder", | |
| 176 | − value: function _configureDecoder(profileIdc, constraintSet, levelIdc) { | |
| 177 | − var _this = this; | |
| 178 | − if (this._decoder === null || this._decoder.state === 'closed') { | |
| 179 | − this._decoder = new VideoDecoder({ | |
| 180 | − output: function output(frame) { | |
| 181 | − return _this._handleFrame(frame); | |
| 182 | − }, | |
| 183 | − error: function error(e) { | |
| 184 | − return _this._handleError(e); | |
| 185 | − } | |
| 186 | − }); | |
| 187 | − } | |
| 188 | − var codec = 'avc1.' + profileIdc.toString(16).padStart(2, '0') + constraintSet.toString(16).padStart(2, '0') + levelIdc.toString(16).padStart(2, '0'); | |
| 189 | − this._decoder.configure({ | |
| 190 | − codec: codec, | |
| 191 | − codedWidth: this._width, | |
| 192 | − codedHeight: this._height, | |
| 193 | − optimizeForLatency: true | |
| 194 | − }); | |
| 195 | − } | |
| 196 | − }, { | |
| 197 | − key: "_preparePendingFrame", | |
| 198 | − value: function _preparePendingFrame(timestamp) { | |
| 199 | − var pending = { | |
| 200 | − timestamp: timestamp, | |
| 201 | − promise: null, | |
| 202 | − resolve: null, | |
| 203 | − frame: null, | |
| 204 | − ready: false, | |
| 205 | − keep: false | |
| 206 | − }; | |
| 207 | − pending.promise = new Promise(function (resolve) { | |
| 208 | − pending.resolve = resolve; | |
| 209 | − }); | |
| 210 | − this._pendingFrames.push(pending); | |
| 211 | − return pending; | |
| 212 | − } | |
| 213 | − }, { | |
| 214 | − key: "decode", | |
| 215 | − value: function decode(payload) { | |
| 216 | − var parser = new H264Parser(payload); | |
| 217 | − var result = null; | |
| 218 | − | |
| 219 | − // Ideally, this timestamp should come from the server, but we'll just | |
| 220 | − // approximate it instead. | |
| 221 | − var timestamp = Math.round(window.performance.now() * 1e3); | |
| 222 | − while (true) { | |
| 223 | − var encodedFrame = parser.parse(); | |
| 224 | − if (encodedFrame === null) { | |
| 225 | − break; | |
| 226 | − } | |
| 227 | − if (parser.profileIdc !== null) { | |
| 228 | − self._profileIdc = parser.profileIdc; | |
| 229 | − self._constraintSet = parser.constraintSet; | |
| 230 | − self._levelIdc = parser.levelIdc; | |
| 231 | − } | |
| 232 | − if (this._decoder === null || this._decoder.state !== 'configured') { | |
| 233 | − if (!encodedFrame.key) { | |
| 234 | − Log.Warn("Missing key frame. Can't decode until one arrives"); | |
| 235 | − continue; | |
| 236 | − } | |
| 237 | − if (self._profileIdc === null) { | |
| 238 | − Log.Warn('Cannot config decoder. Have not received SPS and PPS yet.'); | |
| 239 | − continue; | |
| 240 | − } | |
| 241 | − this._configureDecoder(self._profileIdc, self._constraintSet, self._levelIdc); | |
| 242 | − } | |
| 243 | − result = this._preparePendingFrame(timestamp); | |
| 244 | − var chunk = new EncodedVideoChunk({ | |
| 245 | − timestamp: timestamp, | |
| 246 | − type: encodedFrame.key ? 'key' : 'delta', | |
| 247 | − data: encodedFrame.frame | |
| 248 | − }); | |
| 249 | − try { | |
| 250 | − this._decoder.decode(chunk); | |
| 251 | − } catch (e) { | |
| 252 | − Log.Warn("Failed to decode:", e); | |
| 253 | − } | |
| 254 | − } | |
| 255 | − | |
| 256 | − // We only keep last frame of each payload | |
| 257 | − if (result !== null) { | |
| 258 | − result.keep = true; | |
| 259 | − } | |
| 260 | − return result; | |
| 261 | − } | |
| 262 | − }]); | |
| 263 | −}(); | |
| 264 | −var H264Decoder = exports["default"] = /*#__PURE__*/function () { | |
| 265 | − function H264Decoder() { | |
| 266 | − _classCallCheck(this, H264Decoder); | |
| 267 | − this._tick = 0; | |
| 268 | − this._contexts = {}; | |
| 269 | − } | |
| 270 | − return _createClass(H264Decoder, [{ | |
| 271 | − key: "_contextId", | |
| 272 | − value: function _contextId(x, y, width, height) { | |
| 273 | − return [x, y, width, height].join(','); | |
| 274 | − } | |
| 275 | − }, { | |
| 276 | − key: "_findOldestContextId", | |
| 277 | − value: function _findOldestContextId() { | |
| 278 | − var oldestTick = Number.MAX_VALUE; | |
| 279 | − var oldestKey = undefined; | |
| 280 | − for (var _i = 0, _Object$entries = Object.entries(this._contexts); _i < _Object$entries.length; _i++) { | |
| 281 | − var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), | |
| 282 | − key = _Object$entries$_i[0], | |
| 283 | − value = _Object$entries$_i[1]; | |
| 284 | − if (value.lastUsed < oldestTick) { | |
| 285 | − oldestTick = value.lastUsed; | |
| 286 | − oldestKey = key; | |
| 287 | − } | |
| 288 | − } | |
| 289 | − return oldestKey; | |
| 290 | − } | |
| 291 | − }, { | |
| 292 | − key: "_createContext", | |
| 293 | − value: function _createContext(x, y, width, height) { | |
| 294 | − var maxContexts = 64; | |
| 295 | − if (Object.keys(this._contexts).length >= maxContexts) { | |
| 296 | − var oldestContextId = this._findOldestContextId(); | |
| 297 | − delete this._contexts[oldestContextId]; | |
| 298 | − } | |
| 299 | − var context = new H264Context(width, height); | |
| 300 | − this._contexts[this._contextId(x, y, width, height)] = context; | |
| 301 | − return context; | |
| 302 | − } | |
| 303 | − }, { | |
| 304 | − key: "_getContext", | |
| 305 | − value: function _getContext(x, y, width, height) { | |
| 306 | − var context = this._contexts[this._contextId(x, y, width, height)]; | |
| 307 | − return context !== undefined ? context : this._createContext(x, y, width, height); | |
| 308 | − } | |
| 309 | − }, { | |
| 310 | − key: "_resetContext", | |
| 311 | − value: function _resetContext(x, y, width, height) { | |
| 312 | − delete this._contexts[this._contextId(x, y, width, height)]; | |
| 313 | − } | |
| 314 | − }, { | |
| 315 | − key: "_resetAllContexts", | |
| 316 | − value: function _resetAllContexts() { | |
| 317 | − this._contexts = {}; | |
| 318 | − } | |
| 319 | − }, { | |
| 320 | − key: "decodeRect", | |
| 321 | − value: function decodeRect(x, y, width, height, sock, display, depth) { | |
| 322 | − var resetContextFlag = 1; | |
| 323 | − var resetAllContextsFlag = 2; | |
| 324 | − if (sock.rQwait("h264 header", 8)) { | |
| 325 | − return false; | |
| 326 | − } | |
| 327 | − var length = sock.rQshift32(); | |
| 328 | − var flags = sock.rQshift32(); | |
| 329 | − if (sock.rQwait("h264 payload", length, 8)) { | |
| 330 | − return false; | |
| 331 | − } | |
| 332 | − if (flags & resetAllContextsFlag) { | |
| 333 | − this._resetAllContexts(); | |
| 334 | − } else if (flags & resetContextFlag) { | |
| 335 | − this._resetContext(x, y, width, height); | |
| 336 | − } | |
| 337 | − var context = this._getContext(x, y, width, height); | |
| 338 | − context.lastUsed = this._tick++; | |
| 339 | − if (length !== 0) { | |
| 340 | − var payload = sock.rQshiftBytes(length, false); | |
| 341 | − var frame = context.decode(payload); | |
| 342 | − if (frame !== null) { | |
| 343 | − display.videoFrame(x, y, width, height, frame); | |
| 344 | − } | |
| 345 | − } | |
| 346 | − return true; | |
| 347 | − } | |
| 348 | − }]); | |
| 349 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/decoders/hextile.js
+0 −195
@@ -1,195 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var Log = _interopRequireWildcard(require("../util/logging.js")); | |
| 8 | −function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } | |
| 9 | −function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } | |
| 10 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 11 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 12 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 13 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 14 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 15 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /* | |
| 16 | − * noVNC: HTML5 VNC client | |
| 17 | − * Copyright (C) 2019 The noVNC authors | |
| 18 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 19 | − * | |
| 20 | − * See README.md for usage and integration instructions. | |
| 21 | − * | |
| 22 | − */ | |
| 23 | −var HextileDecoder = exports["default"] = /*#__PURE__*/function () { | |
| 24 | − function HextileDecoder() { | |
| 25 | − _classCallCheck(this, HextileDecoder); | |
| 26 | − this._tiles = 0; | |
| 27 | − this._lastsubencoding = 0; | |
| 28 | − this._tileBuffer = new Uint8Array(16 * 16 * 4); | |
| 29 | − } | |
| 30 | − return _createClass(HextileDecoder, [{ | |
| 31 | − key: "decodeRect", | |
| 32 | − value: function decodeRect(x, y, width, height, sock, display, depth) { | |
| 33 | − if (this._tiles === 0) { | |
| 34 | − this._tilesX = Math.ceil(width / 16); | |
| 35 | − this._tilesY = Math.ceil(height / 16); | |
| 36 | − this._totalTiles = this._tilesX * this._tilesY; | |
| 37 | − this._tiles = this._totalTiles; | |
| 38 | − } | |
| 39 | − while (this._tiles > 0) { | |
| 40 | − var bytes = 1; | |
| 41 | − if (sock.rQwait("HEXTILE", bytes)) { | |
| 42 | − return false; | |
| 43 | − } | |
| 44 | − var subencoding = sock.rQpeek8(); | |
| 45 | − if (subencoding > 30) { | |
| 46 | − // Raw | |
| 47 | − throw new Error("Illegal hextile subencoding (subencoding: " + subencoding + ")"); | |
| 48 | − } | |
| 49 | − var currTile = this._totalTiles - this._tiles; | |
| 50 | − var tileX = currTile % this._tilesX; | |
| 51 | − var tileY = Math.floor(currTile / this._tilesX); | |
| 52 | − var tx = x + tileX * 16; | |
| 53 | − var ty = y + tileY * 16; | |
| 54 | − var tw = Math.min(16, x + width - tx); | |
| 55 | − var th = Math.min(16, y + height - ty); | |
| 56 | − | |
| 57 | − // Figure out how much we are expecting | |
| 58 | − if (subencoding & 0x01) { | |
| 59 | − // Raw | |
| 60 | − bytes += tw * th * 4; | |
| 61 | − } else { | |
| 62 | − if (subencoding & 0x02) { | |
| 63 | − // Background | |
| 64 | − bytes += 4; | |
| 65 | − } | |
| 66 | − if (subencoding & 0x04) { | |
| 67 | − // Foreground | |
| 68 | − bytes += 4; | |
| 69 | − } | |
| 70 | − if (subencoding & 0x08) { | |
| 71 | − // AnySubrects | |
| 72 | − bytes++; // Since we aren't shifting it off | |
| 73 | − | |
| 74 | − if (sock.rQwait("HEXTILE", bytes)) { | |
| 75 | − return false; | |
| 76 | − } | |
| 77 | − var subrects = sock.rQpeekBytes(bytes).at(-1); | |
| 78 | − if (subencoding & 0x10) { | |
| 79 | − // SubrectsColoured | |
| 80 | − bytes += subrects * (4 + 2); | |
| 81 | − } else { | |
| 82 | − bytes += subrects * 2; | |
| 83 | − } | |
| 84 | − } | |
| 85 | − } | |
| 86 | − if (sock.rQwait("HEXTILE", bytes)) { | |
| 87 | − return false; | |
| 88 | − } | |
| 89 | − | |
| 90 | − // We know the encoding and have a whole tile | |
| 91 | − sock.rQshift8(); | |
| 92 | − if (subencoding === 0) { | |
| 93 | − if (this._lastsubencoding & 0x01) { | |
| 94 | − // Weird: ignore blanks are RAW | |
| 95 | − Log.Debug(" Ignoring blank after RAW"); | |
| 96 | − } else { | |
| 97 | − display.fillRect(tx, ty, tw, th, this._background); | |
| 98 | − } | |
| 99 | − } else if (subencoding & 0x01) { | |
| 100 | − // Raw | |
| 101 | − var pixels = tw * th; | |
| 102 | − var data = sock.rQshiftBytes(pixels * 4, false); | |
| 103 | − // Max sure the image is fully opaque | |
| 104 | − for (var i = 0; i < pixels; i++) { | |
| 105 | − data[i * 4 + 3] = 255; | |
| 106 | − } | |
| 107 | − display.blitImage(tx, ty, tw, th, data, 0); | |
| 108 | − } else { | |
| 109 | − if (subencoding & 0x02) { | |
| 110 | − // Background | |
| 111 | − this._background = new Uint8Array(sock.rQshiftBytes(4)); | |
| 112 | − } | |
| 113 | − if (subencoding & 0x04) { | |
| 114 | − // Foreground | |
| 115 | − this._foreground = new Uint8Array(sock.rQshiftBytes(4)); | |
| 116 | − } | |
| 117 | − this._startTile(tx, ty, tw, th, this._background); | |
| 118 | − if (subencoding & 0x08) { | |
| 119 | − // AnySubrects | |
| 120 | − var _subrects = sock.rQshift8(); | |
| 121 | − for (var s = 0; s < _subrects; s++) { | |
| 122 | − var color = void 0; | |
| 123 | − if (subencoding & 0x10) { | |
| 124 | − // SubrectsColoured | |
| 125 | − color = sock.rQshiftBytes(4); | |
| 126 | − } else { | |
| 127 | − color = this._foreground; | |
| 128 | − } | |
| 129 | − var xy = sock.rQshift8(); | |
| 130 | − var sx = xy >> 4; | |
| 131 | − var sy = xy & 0x0f; | |
| 132 | − var wh = sock.rQshift8(); | |
| 133 | − var sw = (wh >> 4) + 1; | |
| 134 | − var sh = (wh & 0x0f) + 1; | |
| 135 | − this._subTile(sx, sy, sw, sh, color); | |
| 136 | − } | |
| 137 | − } | |
| 138 | − this._finishTile(display); | |
| 139 | − } | |
| 140 | − this._lastsubencoding = subencoding; | |
| 141 | − this._tiles--; | |
| 142 | − } | |
| 143 | − return true; | |
| 144 | − } | |
| 145 | − | |
| 146 | − // start updating a tile | |
| 147 | − }, { | |
| 148 | − key: "_startTile", | |
| 149 | − value: function _startTile(x, y, width, height, color) { | |
| 150 | − this._tileX = x; | |
| 151 | − this._tileY = y; | |
| 152 | − this._tileW = width; | |
| 153 | − this._tileH = height; | |
| 154 | − var red = color[0]; | |
| 155 | − var green = color[1]; | |
| 156 | − var blue = color[2]; | |
| 157 | − var data = this._tileBuffer; | |
| 158 | − for (var i = 0; i < width * height * 4; i += 4) { | |
| 159 | − data[i] = red; | |
| 160 | − data[i + 1] = green; | |
| 161 | − data[i + 2] = blue; | |
| 162 | − data[i + 3] = 255; | |
| 163 | − } | |
| 164 | − } | |
| 165 | − | |
| 166 | − // update sub-rectangle of the current tile | |
| 167 | − }, { | |
| 168 | − key: "_subTile", | |
| 169 | − value: function _subTile(x, y, w, h, color) { | |
| 170 | − var red = color[0]; | |
| 171 | − var green = color[1]; | |
| 172 | − var blue = color[2]; | |
| 173 | − var xend = x + w; | |
| 174 | − var yend = y + h; | |
| 175 | − var data = this._tileBuffer; | |
| 176 | − var width = this._tileW; | |
| 177 | − for (var j = y; j < yend; j++) { | |
| 178 | − for (var i = x; i < xend; i++) { | |
| 179 | − var p = (i + j * width) * 4; | |
| 180 | − data[p] = red; | |
| 181 | − data[p + 1] = green; | |
| 182 | − data[p + 2] = blue; | |
| 183 | − data[p + 3] = 255; | |
| 184 | − } | |
| 185 | − } | |
| 186 | − } | |
| 187 | − | |
| 188 | − // draw the current tile to the screen | |
| 189 | − }, { | |
| 190 | − key: "_finishTile", | |
| 191 | − value: function _finishTile(display) { | |
| 192 | − display.blitImage(this._tileX, this._tileY, this._tileW, this._tileH, this._tileBuffer, 0); | |
| 193 | − } | |
| 194 | − }]); | |
| 195 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/decoders/jpeg.js
+0 −175
@@ -1,175 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 8 | −function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } | |
| 9 | −function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } | |
| 10 | −function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } | |
| 11 | −function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } | |
| 12 | −function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } | |
| 13 | −function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } | |
| 14 | −function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } | |
| 15 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 16 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 17 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 18 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 19 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 20 | −/* | |
| 21 | − * noVNC: HTML5 VNC client | |
| 22 | − * Copyright (C) 2019 The noVNC authors | |
| 23 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 24 | − * | |
| 25 | − * See README.md for usage and integration instructions. | |
| 26 | − * | |
| 27 | − */ | |
| 28 | −var JPEGDecoder = exports["default"] = /*#__PURE__*/function () { | |
| 29 | − function JPEGDecoder() { | |
| 30 | − _classCallCheck(this, JPEGDecoder); | |
| 31 | − // RealVNC will reuse the quantization tables | |
| 32 | − // and Huffman tables, so we need to cache them. | |
| 33 | − this._cachedQuantTables = []; | |
| 34 | − this._cachedHuffmanTables = []; | |
| 35 | − this._segments = []; | |
| 36 | − } | |
| 37 | − return _createClass(JPEGDecoder, [{ | |
| 38 | − key: "decodeRect", | |
| 39 | − value: function decodeRect(x, y, width, height, sock, display, depth) { | |
| 40 | − // A rect of JPEG encodings is simply a JPEG file | |
| 41 | − while (true) { | |
| 42 | − var segment = this._readSegment(sock); | |
| 43 | − if (segment === null) { | |
| 44 | − return false; | |
| 45 | − } | |
| 46 | − this._segments.push(segment); | |
| 47 | − // End of image? | |
| 48 | − if (segment[1] === 0xD9) { | |
| 49 | − break; | |
| 50 | − } | |
| 51 | − } | |
| 52 | − var huffmanTables = []; | |
| 53 | − var quantTables = []; | |
| 54 | − var _iterator = _createForOfIteratorHelper(this._segments), | |
| 55 | − _step; | |
| 56 | − try { | |
| 57 | − for (_iterator.s(); !(_step = _iterator.n()).done;) { | |
| 58 | − var _segment = _step.value; | |
| 59 | − var type = _segment[1]; | |
| 60 | − if (type === 0xC4) { | |
| 61 | − // Huffman tables | |
| 62 | − huffmanTables.push(_segment); | |
| 63 | − } else if (type === 0xDB) { | |
| 64 | − // Quantization tables | |
| 65 | − quantTables.push(_segment); | |
| 66 | − } | |
| 67 | − } | |
| 68 | − } catch (err) { | |
| 69 | − _iterator.e(err); | |
| 70 | − } finally { | |
| 71 | − _iterator.f(); | |
| 72 | − } | |
| 73 | − var sofIndex = this._segments.findIndex(function (x) { | |
| 74 | − return x[1] == 0xC0 || x[1] == 0xC2; | |
| 75 | − }); | |
| 76 | − if (sofIndex == -1) { | |
| 77 | − throw new Error("Illegal JPEG image without SOF"); | |
| 78 | − } | |
| 79 | − if (quantTables.length === 0) { | |
| 80 | − var _this$_segments; | |
| 81 | − (_this$_segments = this._segments).splice.apply(_this$_segments, [sofIndex + 1, 0].concat(_toConsumableArray(this._cachedQuantTables))); | |
| 82 | − } | |
| 83 | − if (huffmanTables.length === 0) { | |
| 84 | − var _this$_segments2; | |
| 85 | − (_this$_segments2 = this._segments).splice.apply(_this$_segments2, [sofIndex + 1, 0].concat(_toConsumableArray(this._cachedHuffmanTables))); | |
| 86 | − } | |
| 87 | − var length = 0; | |
| 88 | − var _iterator2 = _createForOfIteratorHelper(this._segments), | |
| 89 | − _step2; | |
| 90 | − try { | |
| 91 | − for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { | |
| 92 | − var _segment2 = _step2.value; | |
| 93 | − length += _segment2.length; | |
| 94 | − } | |
| 95 | − } catch (err) { | |
| 96 | − _iterator2.e(err); | |
| 97 | − } finally { | |
| 98 | − _iterator2.f(); | |
| 99 | − } | |
| 100 | − var data = new Uint8Array(length); | |
| 101 | − length = 0; | |
| 102 | − var _iterator3 = _createForOfIteratorHelper(this._segments), | |
| 103 | − _step3; | |
| 104 | − try { | |
| 105 | − for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { | |
| 106 | − var _segment3 = _step3.value; | |
| 107 | − data.set(_segment3, length); | |
| 108 | − length += _segment3.length; | |
| 109 | − } | |
| 110 | − } catch (err) { | |
| 111 | − _iterator3.e(err); | |
| 112 | − } finally { | |
| 113 | − _iterator3.f(); | |
| 114 | − } | |
| 115 | − display.imageRect(x, y, width, height, "image/jpeg", data); | |
| 116 | − if (huffmanTables.length !== 0) { | |
| 117 | − this._cachedHuffmanTables = huffmanTables; | |
| 118 | − } | |
| 119 | − if (quantTables.length !== 0) { | |
| 120 | − this._cachedQuantTables = quantTables; | |
| 121 | − } | |
| 122 | − this._segments = []; | |
| 123 | − return true; | |
| 124 | − } | |
| 125 | − }, { | |
| 126 | − key: "_readSegment", | |
| 127 | − value: function _readSegment(sock) { | |
| 128 | − if (sock.rQwait("JPEG", 2)) { | |
| 129 | − return null; | |
| 130 | − } | |
| 131 | − var marker = sock.rQshift8(); | |
| 132 | − if (marker != 0xFF) { | |
| 133 | − throw new Error("Illegal JPEG marker received (byte: " + marker + ")"); | |
| 134 | − } | |
| 135 | − var type = sock.rQshift8(); | |
| 136 | − if (type >= 0xD0 && type <= 0xD9 || type == 0x01) { | |
| 137 | − // No length after marker | |
| 138 | − return new Uint8Array([marker, type]); | |
| 139 | − } | |
| 140 | − if (sock.rQwait("JPEG", 2, 2)) { | |
| 141 | − return null; | |
| 142 | − } | |
| 143 | − var length = sock.rQshift16(); | |
| 144 | − if (length < 2) { | |
| 145 | − throw new Error("Illegal JPEG length received (length: " + length + ")"); | |
| 146 | − } | |
| 147 | − if (sock.rQwait("JPEG", length - 2, 4)) { | |
| 148 | − return null; | |
| 149 | − } | |
| 150 | − var extra = 0; | |
| 151 | − if (type === 0xDA) { | |
| 152 | − // start of scan | |
| 153 | − extra += 2; | |
| 154 | − while (true) { | |
| 155 | − if (sock.rQwait("JPEG", length - 2 + extra, 4)) { | |
| 156 | − return null; | |
| 157 | − } | |
| 158 | − var data = sock.rQpeekBytes(length - 2 + extra, false); | |
| 159 | − if (data.at(-2) === 0xFF && data.at(-1) !== 0x00 && !(data.at(-1) >= 0xD0 && data.at(-1) <= 0xD7)) { | |
| 160 | − extra -= 2; | |
| 161 | − break; | |
| 162 | − } | |
| 163 | − extra++; | |
| 164 | − } | |
| 165 | − } | |
| 166 | − var segment = new Uint8Array(2 + length + extra); | |
| 167 | − segment[0] = marker; | |
| 168 | − segment[1] = type; | |
| 169 | − segment[2] = length >> 8; | |
| 170 | − segment[3] = length; | |
| 171 | − segment.set(sock.rQshiftBytes(length - 2 + extra, false), 4); | |
| 172 | − return segment; | |
| 173 | − } | |
| 174 | − }]); | |
| 175 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/decoders/raw.js
+0 −66
@@ -1,66 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 8 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 9 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 10 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 11 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 12 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 13 | −/* | |
| 14 | − * noVNC: HTML5 VNC client | |
| 15 | − * Copyright (C) 2019 The noVNC authors | |
| 16 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 17 | − * | |
| 18 | − * See README.md for usage and integration instructions. | |
| 19 | − * | |
| 20 | − */ | |
| 21 | −var RawDecoder = exports["default"] = /*#__PURE__*/function () { | |
| 22 | − function RawDecoder() { | |
| 23 | − _classCallCheck(this, RawDecoder); | |
| 24 | − this._lines = 0; | |
| 25 | − } | |
| 26 | − return _createClass(RawDecoder, [{ | |
| 27 | − key: "decodeRect", | |
| 28 | − value: function decodeRect(x, y, width, height, sock, display, depth) { | |
| 29 | − if (width === 0 || height === 0) { | |
| 30 | − return true; | |
| 31 | − } | |
| 32 | − if (this._lines === 0) { | |
| 33 | − this._lines = height; | |
| 34 | − } | |
| 35 | − var pixelSize = depth == 8 ? 1 : 4; | |
| 36 | − var bytesPerLine = width * pixelSize; | |
| 37 | − while (this._lines > 0) { | |
| 38 | − if (sock.rQwait("RAW", bytesPerLine)) { | |
| 39 | − return false; | |
| 40 | − } | |
| 41 | − var curY = y + (height - this._lines); | |
| 42 | − var data = sock.rQshiftBytes(bytesPerLine, false); | |
| 43 | − | |
| 44 | − // Convert data if needed | |
| 45 | − if (depth == 8) { | |
| 46 | − var newdata = new Uint8Array(width * 4); | |
| 47 | − for (var i = 0; i < width; i++) { | |
| 48 | − newdata[i * 4 + 0] = (data[i] >> 0 & 0x3) * 255 / 3; | |
| 49 | − newdata[i * 4 + 1] = (data[i] >> 2 & 0x3) * 255 / 3; | |
| 50 | − newdata[i * 4 + 2] = (data[i] >> 4 & 0x3) * 255 / 3; | |
| 51 | − newdata[i * 4 + 3] = 255; | |
| 52 | − } | |
| 53 | − data = newdata; | |
| 54 | − } | |
| 55 | − | |
| 56 | − // Max sure the image is fully opaque | |
| 57 | − for (var _i = 0; _i < width; _i++) { | |
| 58 | − data[_i * 4 + 3] = 255; | |
| 59 | − } | |
| 60 | − display.blitImage(x, curY, width, 1, data, 0); | |
| 61 | − this._lines--; | |
| 62 | − } | |
| 63 | − return true; | |
| 64 | − } | |
| 65 | − }]); | |
| 66 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/decoders/rre.js
+0 −52
@@ -1,52 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 8 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 9 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 10 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 11 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 12 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 13 | −/* | |
| 14 | − * noVNC: HTML5 VNC client | |
| 15 | − * Copyright (C) 2019 The noVNC authors | |
| 16 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 17 | − * | |
| 18 | − * See README.md for usage and integration instructions. | |
| 19 | − * | |
| 20 | − */ | |
| 21 | −var RREDecoder = exports["default"] = /*#__PURE__*/function () { | |
| 22 | − function RREDecoder() { | |
| 23 | − _classCallCheck(this, RREDecoder); | |
| 24 | − this._subrects = 0; | |
| 25 | − } | |
| 26 | − return _createClass(RREDecoder, [{ | |
| 27 | − key: "decodeRect", | |
| 28 | − value: function decodeRect(x, y, width, height, sock, display, depth) { | |
| 29 | − if (this._subrects === 0) { | |
| 30 | − if (sock.rQwait("RRE", 4 + 4)) { | |
| 31 | − return false; | |
| 32 | − } | |
| 33 | − this._subrects = sock.rQshift32(); | |
| 34 | − var color = sock.rQshiftBytes(4); // Background | |
| 35 | − display.fillRect(x, y, width, height, color); | |
| 36 | − } | |
| 37 | − while (this._subrects > 0) { | |
| 38 | − if (sock.rQwait("RRE", 4 + 8)) { | |
| 39 | − return false; | |
| 40 | − } | |
| 41 | − var _color = sock.rQshiftBytes(4); | |
| 42 | − var sx = sock.rQshift16(); | |
| 43 | − var sy = sock.rQshift16(); | |
| 44 | − var swidth = sock.rQshift16(); | |
| 45 | − var sheight = sock.rQshift16(); | |
| 46 | − display.fillRect(x + sx, y + sy, swidth, sheight, _color); | |
| 47 | − this._subrects--; | |
| 48 | − } | |
| 49 | − return true; | |
| 50 | − } | |
| 51 | − }]); | |
| 52 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/decoders/tight.js
+0 −363
@@ -1,363 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var Log = _interopRequireWildcard(require("../util/logging.js")); | |
| 8 | −var _inflator = _interopRequireDefault(require("../inflator.js")); | |
| 9 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 10 | −function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } | |
| 11 | −function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } | |
| 12 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 13 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 14 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 15 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 16 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 17 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /* | |
| 18 | − * noVNC: HTML5 VNC client | |
| 19 | − * Copyright (C) 2019 The noVNC authors | |
| 20 | − * (c) 2012 Michael Tinglof, Joe Balaz, Les Piech (Mercuri.ca) | |
| 21 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 22 | − * | |
| 23 | − * See README.md for usage and integration instructions. | |
| 24 | − * | |
| 25 | − */ | |
| 26 | −var TightDecoder = exports["default"] = /*#__PURE__*/function () { | |
| 27 | − function TightDecoder() { | |
| 28 | − _classCallCheck(this, TightDecoder); | |
| 29 | − this._ctl = null; | |
| 30 | − this._filter = null; | |
| 31 | − this._numColors = 0; | |
| 32 | − this._palette = new Uint8Array(1024); // 256 * 4 (max palette size * max bytes-per-pixel) | |
| 33 | − this._len = 0; | |
| 34 | − this._zlibs = []; | |
| 35 | − for (var i = 0; i < 4; i++) { | |
| 36 | − this._zlibs[i] = new _inflator["default"](); | |
| 37 | − } | |
| 38 | − } | |
| 39 | − return _createClass(TightDecoder, [{ | |
| 40 | − key: "decodeRect", | |
| 41 | − value: function decodeRect(x, y, width, height, sock, display, depth) { | |
| 42 | − if (this._ctl === null) { | |
| 43 | − if (sock.rQwait("TIGHT compression-control", 1)) { | |
| 44 | − return false; | |
| 45 | − } | |
| 46 | − this._ctl = sock.rQshift8(); | |
| 47 | − | |
| 48 | − // Reset streams if the server requests it | |
| 49 | − for (var i = 0; i < 4; i++) { | |
| 50 | − if (this._ctl >> i & 1) { | |
| 51 | − this._zlibs[i].reset(); | |
| 52 | − Log.Info("Reset zlib stream " + i); | |
| 53 | − } | |
| 54 | − } | |
| 55 | − | |
| 56 | − // Figure out filter | |
| 57 | − this._ctl = this._ctl >> 4; | |
| 58 | − } | |
| 59 | − var ret; | |
| 60 | − if (this._ctl === 0x08) { | |
| 61 | − ret = this._fillRect(x, y, width, height, sock, display, depth); | |
| 62 | − } else if (this._ctl === 0x09) { | |
| 63 | − ret = this._jpegRect(x, y, width, height, sock, display, depth); | |
| 64 | − } else if (this._ctl === 0x0A) { | |
| 65 | − ret = this._pngRect(x, y, width, height, sock, display, depth); | |
| 66 | − } else if ((this._ctl & 0x08) == 0) { | |
| 67 | − ret = this._basicRect(this._ctl, x, y, width, height, sock, display, depth); | |
| 68 | − } else { | |
| 69 | − throw new Error("Illegal tight compression received (ctl: " + this._ctl + ")"); | |
| 70 | − } | |
| 71 | − if (ret) { | |
| 72 | − this._ctl = null; | |
| 73 | − } | |
| 74 | − return ret; | |
| 75 | − } | |
| 76 | − }, { | |
| 77 | − key: "_fillRect", | |
| 78 | − value: function _fillRect(x, y, width, height, sock, display, depth) { | |
| 79 | − if (sock.rQwait("TIGHT", 3)) { | |
| 80 | − return false; | |
| 81 | − } | |
| 82 | − var pixel = sock.rQshiftBytes(3); | |
| 83 | − display.fillRect(x, y, width, height, pixel, false); | |
| 84 | − return true; | |
| 85 | − } | |
| 86 | − }, { | |
| 87 | − key: "_jpegRect", | |
| 88 | − value: function _jpegRect(x, y, width, height, sock, display, depth) { | |
| 89 | − var data = this._readData(sock); | |
| 90 | − if (data === null) { | |
| 91 | − return false; | |
| 92 | − } | |
| 93 | − display.imageRect(x, y, width, height, "image/jpeg", data); | |
| 94 | − return true; | |
| 95 | − } | |
| 96 | − }, { | |
| 97 | − key: "_pngRect", | |
| 98 | − value: function _pngRect(x, y, width, height, sock, display, depth) { | |
| 99 | − throw new Error("PNG received in standard Tight rect"); | |
| 100 | − } | |
| 101 | − }, { | |
| 102 | − key: "_basicRect", | |
| 103 | − value: function _basicRect(ctl, x, y, width, height, sock, display, depth) { | |
| 104 | − if (this._filter === null) { | |
| 105 | − if (ctl & 0x4) { | |
| 106 | − if (sock.rQwait("TIGHT", 1)) { | |
| 107 | − return false; | |
| 108 | − } | |
| 109 | − this._filter = sock.rQshift8(); | |
| 110 | − } else { | |
| 111 | − // Implicit CopyFilter | |
| 112 | − this._filter = 0; | |
| 113 | − } | |
| 114 | − } | |
| 115 | − var streamId = ctl & 0x3; | |
| 116 | − var ret; | |
| 117 | − switch (this._filter) { | |
| 118 | − case 0: | |
| 119 | − // CopyFilter | |
| 120 | − ret = this._copyFilter(streamId, x, y, width, height, sock, display, depth); | |
| 121 | − break; | |
| 122 | − case 1: | |
| 123 | − // PaletteFilter | |
| 124 | − ret = this._paletteFilter(streamId, x, y, width, height, sock, display, depth); | |
| 125 | − break; | |
| 126 | − case 2: | |
| 127 | − // GradientFilter | |
| 128 | − ret = this._gradientFilter(streamId, x, y, width, height, sock, display, depth); | |
| 129 | − break; | |
| 130 | − default: | |
| 131 | − throw new Error("Illegal tight filter received (ctl: " + this._filter + ")"); | |
| 132 | − } | |
| 133 | − if (ret) { | |
| 134 | − this._filter = null; | |
| 135 | − } | |
| 136 | − return ret; | |
| 137 | − } | |
| 138 | − }, { | |
| 139 | − key: "_copyFilter", | |
| 140 | − value: function _copyFilter(streamId, x, y, width, height, sock, display, depth) { | |
| 141 | − var uncompressedSize = width * height * 3; | |
| 142 | − var data; | |
| 143 | − if (uncompressedSize === 0) { | |
| 144 | − return true; | |
| 145 | − } | |
| 146 | − if (uncompressedSize < 12) { | |
| 147 | − if (sock.rQwait("TIGHT", uncompressedSize)) { | |
| 148 | − return false; | |
| 149 | − } | |
| 150 | − data = sock.rQshiftBytes(uncompressedSize); | |
| 151 | − } else { | |
| 152 | − data = this._readData(sock); | |
| 153 | − if (data === null) { | |
| 154 | − return false; | |
| 155 | − } | |
| 156 | − this._zlibs[streamId].setInput(data); | |
| 157 | − data = this._zlibs[streamId].inflate(uncompressedSize); | |
| 158 | − this._zlibs[streamId].setInput(null); | |
| 159 | − } | |
| 160 | − var rgbx = new Uint8Array(width * height * 4); | |
| 161 | − for (var i = 0, j = 0; i < width * height * 4; i += 4, j += 3) { | |
| 162 | − rgbx[i] = data[j]; | |
| 163 | − rgbx[i + 1] = data[j + 1]; | |
| 164 | − rgbx[i + 2] = data[j + 2]; | |
| 165 | − rgbx[i + 3] = 255; // Alpha | |
| 166 | − } | |
| 167 | − display.blitImage(x, y, width, height, rgbx, 0, false); | |
| 168 | − return true; | |
| 169 | − } | |
| 170 | − }, { | |
| 171 | − key: "_paletteFilter", | |
| 172 | − value: function _paletteFilter(streamId, x, y, width, height, sock, display, depth) { | |
| 173 | − if (this._numColors === 0) { | |
| 174 | − if (sock.rQwait("TIGHT palette", 1)) { | |
| 175 | − return false; | |
| 176 | − } | |
| 177 | − var numColors = sock.rQpeek8() + 1; | |
| 178 | − var paletteSize = numColors * 3; | |
| 179 | − if (sock.rQwait("TIGHT palette", 1 + paletteSize)) { | |
| 180 | − return false; | |
| 181 | − } | |
| 182 | − this._numColors = numColors; | |
| 183 | − sock.rQskipBytes(1); | |
| 184 | − sock.rQshiftTo(this._palette, paletteSize); | |
| 185 | − } | |
| 186 | − var bpp = this._numColors <= 2 ? 1 : 8; | |
| 187 | − var rowSize = Math.floor((width * bpp + 7) / 8); | |
| 188 | − var uncompressedSize = rowSize * height; | |
| 189 | − var data; | |
| 190 | − if (uncompressedSize === 0) { | |
| 191 | − return true; | |
| 192 | − } | |
| 193 | − if (uncompressedSize < 12) { | |
| 194 | − if (sock.rQwait("TIGHT", uncompressedSize)) { | |
| 195 | − return false; | |
| 196 | − } | |
| 197 | − data = sock.rQshiftBytes(uncompressedSize); | |
| 198 | − } else { | |
| 199 | − data = this._readData(sock); | |
| 200 | − if (data === null) { | |
| 201 | − return false; | |
| 202 | − } | |
| 203 | − this._zlibs[streamId].setInput(data); | |
| 204 | − data = this._zlibs[streamId].inflate(uncompressedSize); | |
| 205 | − this._zlibs[streamId].setInput(null); | |
| 206 | − } | |
| 207 | − | |
| 208 | − // Convert indexed (palette based) image data to RGB | |
| 209 | − if (this._numColors == 2) { | |
| 210 | − this._monoRect(x, y, width, height, data, this._palette, display); | |
| 211 | − } else { | |
| 212 | − this._paletteRect(x, y, width, height, data, this._palette, display); | |
| 213 | − } | |
| 214 | − this._numColors = 0; | |
| 215 | − return true; | |
| 216 | − } | |
| 217 | − }, { | |
| 218 | − key: "_monoRect", | |
| 219 | − value: function _monoRect(x, y, width, height, data, palette, display) { | |
| 220 | − // Convert indexed (palette based) image data to RGB | |
| 221 | − // TODO: reduce number of calculations inside loop | |
| 222 | − var dest = this._getScratchBuffer(width * height * 4); | |
| 223 | − var w = Math.floor((width + 7) / 8); | |
| 224 | − var w1 = Math.floor(width / 8); | |
| 225 | − for (var _y = 0; _y < height; _y++) { | |
| 226 | − var dp = void 0, | |
| 227 | − sp = void 0, | |
| 228 | − _x = void 0; | |
| 229 | − for (_x = 0; _x < w1; _x++) { | |
| 230 | − for (var b = 7; b >= 0; b--) { | |
| 231 | − dp = (_y * width + _x * 8 + 7 - b) * 4; | |
| 232 | − sp = (data[_y * w + _x] >> b & 1) * 3; | |
| 233 | − dest[dp] = palette[sp]; | |
| 234 | − dest[dp + 1] = palette[sp + 1]; | |
| 235 | − dest[dp + 2] = palette[sp + 2]; | |
| 236 | − dest[dp + 3] = 255; | |
| 237 | − } | |
| 238 | − } | |
| 239 | − for (var _b = 7; _b >= 8 - width % 8; _b--) { | |
| 240 | − dp = (_y * width + _x * 8 + 7 - _b) * 4; | |
| 241 | − sp = (data[_y * w + _x] >> _b & 1) * 3; | |
| 242 | − dest[dp] = palette[sp]; | |
| 243 | − dest[dp + 1] = palette[sp + 1]; | |
| 244 | − dest[dp + 2] = palette[sp + 2]; | |
| 245 | − dest[dp + 3] = 255; | |
| 246 | − } | |
| 247 | − } | |
| 248 | − display.blitImage(x, y, width, height, dest, 0, false); | |
| 249 | − } | |
| 250 | − }, { | |
| 251 | − key: "_paletteRect", | |
| 252 | − value: function _paletteRect(x, y, width, height, data, palette, display) { | |
| 253 | − // Convert indexed (palette based) image data to RGB | |
| 254 | − var dest = this._getScratchBuffer(width * height * 4); | |
| 255 | − var total = width * height * 4; | |
| 256 | − for (var i = 0, j = 0; i < total; i += 4, j++) { | |
| 257 | − var sp = data[j] * 3; | |
| 258 | − dest[i] = palette[sp]; | |
| 259 | − dest[i + 1] = palette[sp + 1]; | |
| 260 | − dest[i + 2] = palette[sp + 2]; | |
| 261 | − dest[i + 3] = 255; | |
| 262 | − } | |
| 263 | − display.blitImage(x, y, width, height, dest, 0, false); | |
| 264 | − } | |
| 265 | − }, { | |
| 266 | − key: "_gradientFilter", | |
| 267 | − value: function _gradientFilter(streamId, x, y, width, height, sock, display, depth) { | |
| 268 | − // assume the TPIXEL is 3 bytes long | |
| 269 | − var uncompressedSize = width * height * 3; | |
| 270 | − var data; | |
| 271 | − if (uncompressedSize === 0) { | |
| 272 | − return true; | |
| 273 | − } | |
| 274 | − if (uncompressedSize < 12) { | |
| 275 | − if (sock.rQwait("TIGHT", uncompressedSize)) { | |
| 276 | − return false; | |
| 277 | − } | |
| 278 | − data = sock.rQshiftBytes(uncompressedSize); | |
| 279 | − } else { | |
| 280 | − data = this._readData(sock); | |
| 281 | − if (data === null) { | |
| 282 | − return false; | |
| 283 | − } | |
| 284 | − this._zlibs[streamId].setInput(data); | |
| 285 | − data = this._zlibs[streamId].inflate(uncompressedSize); | |
| 286 | − this._zlibs[streamId].setInput(null); | |
| 287 | − } | |
| 288 | − var rgbx = new Uint8Array(4 * width * height); | |
| 289 | − var rgbxIndex = 0, | |
| 290 | − dataIndex = 0; | |
| 291 | − var left = new Uint8Array(3); | |
| 292 | − for (var _x2 = 0; _x2 < width; _x2++) { | |
| 293 | − for (var c = 0; c < 3; c++) { | |
| 294 | − var prediction = left[c]; | |
| 295 | − var value = data[dataIndex++] + prediction; | |
| 296 | − rgbx[rgbxIndex++] = value; | |
| 297 | − left[c] = value; | |
| 298 | − } | |
| 299 | − rgbx[rgbxIndex++] = 255; | |
| 300 | − } | |
| 301 | − var upperIndex = 0; | |
| 302 | − var upper = new Uint8Array(3), | |
| 303 | − upperleft = new Uint8Array(3); | |
| 304 | − for (var _y2 = 1; _y2 < height; _y2++) { | |
| 305 | − left.fill(0); | |
| 306 | − upperleft.fill(0); | |
| 307 | − for (var _x3 = 0; _x3 < width; _x3++) { | |
| 308 | − for (var _c = 0; _c < 3; _c++) { | |
| 309 | − upper[_c] = rgbx[upperIndex++]; | |
| 310 | − var _prediction = left[_c] + upper[_c] - upperleft[_c]; | |
| 311 | − if (_prediction < 0) { | |
| 312 | − _prediction = 0; | |
| 313 | − } else if (_prediction > 255) { | |
| 314 | − _prediction = 255; | |
| 315 | − } | |
| 316 | − var _value = data[dataIndex++] + _prediction; | |
| 317 | − rgbx[rgbxIndex++] = _value; | |
| 318 | − upperleft[_c] = upper[_c]; | |
| 319 | − left[_c] = _value; | |
| 320 | − } | |
| 321 | − rgbx[rgbxIndex++] = 255; | |
| 322 | − upperIndex++; | |
| 323 | − } | |
| 324 | − } | |
| 325 | − display.blitImage(x, y, width, height, rgbx, 0, false); | |
| 326 | − return true; | |
| 327 | − } | |
| 328 | − }, { | |
| 329 | − key: "_readData", | |
| 330 | − value: function _readData(sock) { | |
| 331 | − if (this._len === 0) { | |
| 332 | − if (sock.rQwait("TIGHT", 3)) { | |
| 333 | − return null; | |
| 334 | − } | |
| 335 | − var _byte; | |
| 336 | − _byte = sock.rQshift8(); | |
| 337 | − this._len = _byte & 0x7f; | |
| 338 | − if (_byte & 0x80) { | |
| 339 | − _byte = sock.rQshift8(); | |
| 340 | − this._len |= (_byte & 0x7f) << 7; | |
| 341 | − if (_byte & 0x80) { | |
| 342 | − _byte = sock.rQshift8(); | |
| 343 | − this._len |= _byte << 14; | |
| 344 | − } | |
| 345 | − } | |
| 346 | − } | |
| 347 | − if (sock.rQwait("TIGHT", this._len)) { | |
| 348 | − return null; | |
| 349 | − } | |
| 350 | − var data = sock.rQshiftBytes(this._len, false); | |
| 351 | − this._len = 0; | |
| 352 | − return data; | |
| 353 | − } | |
| 354 | − }, { | |
| 355 | − key: "_getScratchBuffer", | |
| 356 | − value: function _getScratchBuffer(size) { | |
| 357 | − if (!this._scratchBuffer || this._scratchBuffer.length < size) { | |
| 358 | − this._scratchBuffer = new Uint8Array(size); | |
| 359 | − } | |
| 360 | − return this._scratchBuffer; | |
| 361 | − } | |
| 362 | − }]); | |
| 363 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/decoders/tightpng.js
+0 −51
@@ -1,51 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 4 | −Object.defineProperty(exports, "__esModule", { | |
| 5 | − value: true | |
| 6 | −}); | |
| 7 | −exports["default"] = void 0; | |
| 8 | −var _tight = _interopRequireDefault(require("./tight.js")); | |
| 9 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 10 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 11 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 12 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 13 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 14 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 15 | −function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } | |
| 16 | −function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); } | |
| 17 | −function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } | |
| 18 | −function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } | |
| 19 | −function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } | |
| 20 | −function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); } | |
| 21 | −function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } /* | |
| 22 | − * noVNC: HTML5 VNC client | |
| 23 | − * Copyright (C) 2019 The noVNC authors | |
| 24 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 25 | − * | |
| 26 | − * See README.md for usage and integration instructions. | |
| 27 | − * | |
| 28 | − */ | |
| 29 | −var TightPNGDecoder = exports["default"] = /*#__PURE__*/function (_TightDecoder) { | |
| 30 | − function TightPNGDecoder() { | |
| 31 | − _classCallCheck(this, TightPNGDecoder); | |
| 32 | − return _callSuper(this, TightPNGDecoder, arguments); | |
| 33 | − } | |
| 34 | − _inherits(TightPNGDecoder, _TightDecoder); | |
| 35 | − return _createClass(TightPNGDecoder, [{ | |
| 36 | − key: "_pngRect", | |
| 37 | − value: function _pngRect(x, y, width, height, sock, display, depth) { | |
| 38 | − var data = this._readData(sock); | |
| 39 | − if (data === null) { | |
| 40 | − return false; | |
| 41 | − } | |
| 42 | − display.imageRect(x, y, width, height, "image/png", data); | |
| 43 | − return true; | |
| 44 | − } | |
| 45 | − }, { | |
| 46 | − key: "_basicRect", | |
| 47 | − value: function _basicRect(ctl, x, y, width, height, sock, display, depth) { | |
| 48 | − throw new Error("BasicCompression received in TightPNG rect"); | |
| 49 | − } | |
| 50 | − }]); | |
| 51 | −}(_tight["default"]); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/decoders/zlib.js
+0 −57
@@ -1,57 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var _inflator = _interopRequireDefault(require("../inflator.js")); | |
| 8 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 9 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 10 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 11 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 12 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 13 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 14 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /* | |
| 15 | − * noVNC: HTML5 VNC client | |
| 16 | − * Copyright (C) 2024 The noVNC authors | |
| 17 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 18 | − * | |
| 19 | − * See README.md for usage and integration instructions. | |
| 20 | − * | |
| 21 | − */ | |
| 22 | −var ZlibDecoder = exports["default"] = /*#__PURE__*/function () { | |
| 23 | − function ZlibDecoder() { | |
| 24 | − _classCallCheck(this, ZlibDecoder); | |
| 25 | − this._zlib = new _inflator["default"](); | |
| 26 | − this._length = 0; | |
| 27 | − } | |
| 28 | − return _createClass(ZlibDecoder, [{ | |
| 29 | − key: "decodeRect", | |
| 30 | − value: function decodeRect(x, y, width, height, sock, display, depth) { | |
| 31 | − if (width === 0 || height === 0) { | |
| 32 | − return true; | |
| 33 | − } | |
| 34 | − if (this._length === 0) { | |
| 35 | − if (sock.rQwait("ZLIB", 4)) { | |
| 36 | − return false; | |
| 37 | − } | |
| 38 | − this._length = sock.rQshift32(); | |
| 39 | − } | |
| 40 | − if (sock.rQwait("ZLIB", this._length)) { | |
| 41 | − return false; | |
| 42 | − } | |
| 43 | − var data = new Uint8Array(sock.rQshiftBytes(this._length, false)); | |
| 44 | − this._length = 0; | |
| 45 | − this._zlib.setInput(data); | |
| 46 | − data = this._zlib.inflate(width * height * 4); | |
| 47 | − this._zlib.setInput(null); | |
| 48 | − | |
| 49 | − // Max sure the image is fully opaque | |
| 50 | − for (var i = 0; i < width * height; i++) { | |
| 51 | − data[i * 4 + 3] = 255; | |
| 52 | − } | |
| 53 | − display.blitImage(x, y, width, height, data, 0); | |
| 54 | − return true; | |
| 55 | − } | |
| 56 | − }]); | |
| 57 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/decoders/zrle.js
+0 −192
@@ -1,192 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var _inflator = _interopRequireDefault(require("../inflator.js")); | |
| 8 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 9 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 10 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 11 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 12 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 13 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 14 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /* | |
| 15 | − * noVNC: HTML5 VNC client | |
| 16 | − * Copyright (C) 2021 The noVNC authors | |
| 17 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 18 | − * | |
| 19 | − * See README.md for usage and integration instructions. | |
| 20 | − * | |
| 21 | − */ | |
| 22 | −var ZRLE_TILE_WIDTH = 64; | |
| 23 | −var ZRLE_TILE_HEIGHT = 64; | |
| 24 | −var ZRLEDecoder = exports["default"] = /*#__PURE__*/function () { | |
| 25 | − function ZRLEDecoder() { | |
| 26 | − _classCallCheck(this, ZRLEDecoder); | |
| 27 | − this._length = 0; | |
| 28 | − this._inflator = new _inflator["default"](); | |
| 29 | − this._pixelBuffer = new Uint8Array(ZRLE_TILE_WIDTH * ZRLE_TILE_HEIGHT * 4); | |
| 30 | − this._tileBuffer = new Uint8Array(ZRLE_TILE_WIDTH * ZRLE_TILE_HEIGHT * 4); | |
| 31 | − } | |
| 32 | − return _createClass(ZRLEDecoder, [{ | |
| 33 | − key: "decodeRect", | |
| 34 | − value: function decodeRect(x, y, width, height, sock, display, depth) { | |
| 35 | − if (this._length === 0) { | |
| 36 | − if (sock.rQwait("ZLib data length", 4)) { | |
| 37 | − return false; | |
| 38 | − } | |
| 39 | − this._length = sock.rQshift32(); | |
| 40 | − } | |
| 41 | − if (sock.rQwait("Zlib data", this._length)) { | |
| 42 | − return false; | |
| 43 | − } | |
| 44 | − var data = sock.rQshiftBytes(this._length, false); | |
| 45 | − this._inflator.setInput(data); | |
| 46 | − for (var ty = y; ty < y + height; ty += ZRLE_TILE_HEIGHT) { | |
| 47 | − var th = Math.min(ZRLE_TILE_HEIGHT, y + height - ty); | |
| 48 | − for (var tx = x; tx < x + width; tx += ZRLE_TILE_WIDTH) { | |
| 49 | − var tw = Math.min(ZRLE_TILE_WIDTH, x + width - tx); | |
| 50 | − var tileSize = tw * th; | |
| 51 | − var subencoding = this._inflator.inflate(1)[0]; | |
| 52 | − if (subencoding === 0) { | |
| 53 | − // raw data | |
| 54 | − var _data = this._readPixels(tileSize); | |
| 55 | − display.blitImage(tx, ty, tw, th, _data, 0, false); | |
| 56 | − } else if (subencoding === 1) { | |
| 57 | − // solid | |
| 58 | − var background = this._readPixels(1); | |
| 59 | − display.fillRect(tx, ty, tw, th, [background[0], background[1], background[2]]); | |
| 60 | − } else if (subencoding >= 2 && subencoding <= 16) { | |
| 61 | − var _data2 = this._decodePaletteTile(subencoding, tileSize, tw, th); | |
| 62 | − display.blitImage(tx, ty, tw, th, _data2, 0, false); | |
| 63 | − } else if (subencoding === 128) { | |
| 64 | − var _data3 = this._decodeRLETile(tileSize); | |
| 65 | − display.blitImage(tx, ty, tw, th, _data3, 0, false); | |
| 66 | − } else if (subencoding >= 130 && subencoding <= 255) { | |
| 67 | − var _data4 = this._decodeRLEPaletteTile(subencoding - 128, tileSize); | |
| 68 | − display.blitImage(tx, ty, tw, th, _data4, 0, false); | |
| 69 | − } else { | |
| 70 | − throw new Error('Unknown subencoding: ' + subencoding); | |
| 71 | − } | |
| 72 | − } | |
| 73 | − } | |
| 74 | − this._length = 0; | |
| 75 | − return true; | |
| 76 | − } | |
| 77 | − }, { | |
| 78 | − key: "_getBitsPerPixelInPalette", | |
| 79 | − value: function _getBitsPerPixelInPalette(paletteSize) { | |
| 80 | − if (paletteSize <= 2) { | |
| 81 | − return 1; | |
| 82 | − } else if (paletteSize <= 4) { | |
| 83 | − return 2; | |
| 84 | − } else if (paletteSize <= 16) { | |
| 85 | − return 4; | |
| 86 | − } | |
| 87 | − } | |
| 88 | − }, { | |
| 89 | − key: "_readPixels", | |
| 90 | − value: function _readPixels(pixels) { | |
| 91 | − var data = this._pixelBuffer; | |
| 92 | − var buffer = this._inflator.inflate(3 * pixels); | |
| 93 | − for (var i = 0, j = 0; i < pixels * 4; i += 4, j += 3) { | |
| 94 | − data[i] = buffer[j]; | |
| 95 | − data[i + 1] = buffer[j + 1]; | |
| 96 | − data[i + 2] = buffer[j + 2]; | |
| 97 | − data[i + 3] = 255; // Add the Alpha | |
| 98 | − } | |
| 99 | − return data; | |
| 100 | − } | |
| 101 | − }, { | |
| 102 | − key: "_decodePaletteTile", | |
| 103 | − value: function _decodePaletteTile(paletteSize, tileSize, tilew, tileh) { | |
| 104 | − var data = this._tileBuffer; | |
| 105 | − var palette = this._readPixels(paletteSize); | |
| 106 | − var bitsPerPixel = this._getBitsPerPixelInPalette(paletteSize); | |
| 107 | − var mask = (1 << bitsPerPixel) - 1; | |
| 108 | − var offset = 0; | |
| 109 | − var encoded = this._inflator.inflate(1)[0]; | |
| 110 | − for (var y = 0; y < tileh; y++) { | |
| 111 | − var shift = 8 - bitsPerPixel; | |
| 112 | − for (var x = 0; x < tilew; x++) { | |
| 113 | − if (shift < 0) { | |
| 114 | − shift = 8 - bitsPerPixel; | |
| 115 | − encoded = this._inflator.inflate(1)[0]; | |
| 116 | − } | |
| 117 | − var indexInPalette = encoded >> shift & mask; | |
| 118 | − data[offset] = palette[indexInPalette * 4]; | |
| 119 | − data[offset + 1] = palette[indexInPalette * 4 + 1]; | |
| 120 | − data[offset + 2] = palette[indexInPalette * 4 + 2]; | |
| 121 | − data[offset + 3] = palette[indexInPalette * 4 + 3]; | |
| 122 | − offset += 4; | |
| 123 | − shift -= bitsPerPixel; | |
| 124 | − } | |
| 125 | − if (shift < 8 - bitsPerPixel && y < tileh - 1) { | |
| 126 | − encoded = this._inflator.inflate(1)[0]; | |
| 127 | − } | |
| 128 | − } | |
| 129 | − return data; | |
| 130 | − } | |
| 131 | − }, { | |
| 132 | − key: "_decodeRLETile", | |
| 133 | − value: function _decodeRLETile(tileSize) { | |
| 134 | − var data = this._tileBuffer; | |
| 135 | − var i = 0; | |
| 136 | − while (i < tileSize) { | |
| 137 | − var pixel = this._readPixels(1); | |
| 138 | − var length = this._readRLELength(); | |
| 139 | − for (var j = 0; j < length; j++) { | |
| 140 | − data[i * 4] = pixel[0]; | |
| 141 | − data[i * 4 + 1] = pixel[1]; | |
| 142 | − data[i * 4 + 2] = pixel[2]; | |
| 143 | − data[i * 4 + 3] = pixel[3]; | |
| 144 | − i++; | |
| 145 | − } | |
| 146 | − } | |
| 147 | − return data; | |
| 148 | − } | |
| 149 | − }, { | |
| 150 | − key: "_decodeRLEPaletteTile", | |
| 151 | − value: function _decodeRLEPaletteTile(paletteSize, tileSize) { | |
| 152 | − var data = this._tileBuffer; | |
| 153 | − | |
| 154 | − // palette | |
| 155 | − var palette = this._readPixels(paletteSize); | |
| 156 | − var offset = 0; | |
| 157 | − while (offset < tileSize) { | |
| 158 | − var indexInPalette = this._inflator.inflate(1)[0]; | |
| 159 | − var length = 1; | |
| 160 | − if (indexInPalette >= 128) { | |
| 161 | − indexInPalette -= 128; | |
| 162 | − length = this._readRLELength(); | |
| 163 | − } | |
| 164 | − if (indexInPalette > paletteSize) { | |
| 165 | − throw new Error('Too big index in palette: ' + indexInPalette + ', palette size: ' + paletteSize); | |
| 166 | − } | |
| 167 | − if (offset + length > tileSize) { | |
| 168 | − throw new Error('Too big rle length in palette mode: ' + length + ', allowed length is: ' + (tileSize - offset)); | |
| 169 | − } | |
| 170 | − for (var j = 0; j < length; j++) { | |
| 171 | − data[offset * 4] = palette[indexInPalette * 4]; | |
| 172 | − data[offset * 4 + 1] = palette[indexInPalette * 4 + 1]; | |
| 173 | − data[offset * 4 + 2] = palette[indexInPalette * 4 + 2]; | |
| 174 | − data[offset * 4 + 3] = palette[indexInPalette * 4 + 3]; | |
| 175 | − offset++; | |
| 176 | − } | |
| 177 | − } | |
| 178 | − return data; | |
| 179 | − } | |
| 180 | − }, { | |
| 181 | − key: "_readRLELength", | |
| 182 | − value: function _readRLELength() { | |
| 183 | − var length = 0; | |
| 184 | − var current = 0; | |
| 185 | − do { | |
| 186 | − current = this._inflator.inflate(1)[0]; | |
| 187 | − length += current; | |
| 188 | − } while (current === 255); | |
| 189 | − return length + 1; | |
| 190 | − } | |
| 191 | − }]); | |
| 192 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/deflator.js
+0 −88
@@ -1,88 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var _deflate2 = require("../lib/vendor/pako/lib/zlib/deflate.js"); | |
| 8 | −var _zstream = _interopRequireDefault(require("../lib/vendor/pako/lib/zlib/zstream.js")); | |
| 9 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 10 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 11 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 12 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 13 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 14 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 15 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /* | |
| 16 | − * noVNC: HTML5 VNC client | |
| 17 | − * Copyright (C) 2020 The noVNC authors | |
| 18 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 19 | − * | |
| 20 | − * See README.md for usage and integration instructions. | |
| 21 | − */ | |
| 22 | −var Deflator = exports["default"] = /*#__PURE__*/function () { | |
| 23 | − function Deflator() { | |
| 24 | − _classCallCheck(this, Deflator); | |
| 25 | − this.strm = new _zstream["default"](); | |
| 26 | − this.chunkSize = 1024 * 10 * 10; | |
| 27 | − this.outputBuffer = new Uint8Array(this.chunkSize); | |
| 28 | − (0, _deflate2.deflateInit)(this.strm, _deflate2.Z_DEFAULT_COMPRESSION); | |
| 29 | − } | |
| 30 | − return _createClass(Deflator, [{ | |
| 31 | − key: "deflate", | |
| 32 | − value: function deflate(inData) { | |
| 33 | − /* eslint-disable camelcase */ | |
| 34 | − this.strm.input = inData; | |
| 35 | − this.strm.avail_in = this.strm.input.length; | |
| 36 | − this.strm.next_in = 0; | |
| 37 | − this.strm.output = this.outputBuffer; | |
| 38 | − this.strm.avail_out = this.chunkSize; | |
| 39 | − this.strm.next_out = 0; | |
| 40 | − /* eslint-enable camelcase */ | |
| 41 | − | |
| 42 | − var lastRet = (0, _deflate2.deflate)(this.strm, _deflate2.Z_FULL_FLUSH); | |
| 43 | − var outData = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); | |
| 44 | − if (lastRet < 0) { | |
| 45 | − throw new Error("zlib deflate failed"); | |
| 46 | − } | |
| 47 | − if (this.strm.avail_in > 0) { | |
| 48 | − // Read chunks until done | |
| 49 | − | |
| 50 | − var chunks = [outData]; | |
| 51 | − var totalLen = outData.length; | |
| 52 | − do { | |
| 53 | − /* eslint-disable camelcase */ | |
| 54 | − this.strm.output = new Uint8Array(this.chunkSize); | |
| 55 | − this.strm.next_out = 0; | |
| 56 | − this.strm.avail_out = this.chunkSize; | |
| 57 | − /* eslint-enable camelcase */ | |
| 58 | − | |
| 59 | − lastRet = (0, _deflate2.deflate)(this.strm, _deflate2.Z_FULL_FLUSH); | |
| 60 | − if (lastRet < 0) { | |
| 61 | − throw new Error("zlib deflate failed"); | |
| 62 | − } | |
| 63 | − var chunk = new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); | |
| 64 | − totalLen += chunk.length; | |
| 65 | − chunks.push(chunk); | |
| 66 | − } while (this.strm.avail_in > 0); | |
| 67 | − | |
| 68 | − // Combine chunks into a single data | |
| 69 | − | |
| 70 | − var newData = new Uint8Array(totalLen); | |
| 71 | − var offset = 0; | |
| 72 | − for (var i = 0; i < chunks.length; i++) { | |
| 73 | − newData.set(chunks[i], offset); | |
| 74 | − offset += chunks[i].length; | |
| 75 | − } | |
| 76 | − outData = newData; | |
| 77 | − } | |
| 78 | − | |
| 79 | − /* eslint-disable camelcase */ | |
| 80 | − this.strm.input = null; | |
| 81 | − this.strm.avail_in = 0; | |
| 82 | − this.strm.next_in = 0; | |
| 83 | − /* eslint-enable camelcase */ | |
| 84 | − | |
| 85 | − return outData; | |
| 86 | − } | |
| 87 | − }]); | |
| 88 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/display.js
+0 −588
@@ -1,588 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var Log = _interopRequireWildcard(require("./util/logging.js")); | |
| 8 | −var _base = _interopRequireDefault(require("./base64.js")); | |
| 9 | −var _int = require("./util/int.js"); | |
| 10 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 11 | −function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } | |
| 12 | −function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } | |
| 13 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 14 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 15 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 16 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 17 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 18 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /* | |
| 19 | − * noVNC: HTML5 VNC client | |
| 20 | − * Copyright (C) 2019 The noVNC authors | |
| 21 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 22 | − * | |
| 23 | − * See README.md for usage and integration instructions. | |
| 24 | − */ | |
| 25 | −var Display = exports["default"] = /*#__PURE__*/function () { | |
| 26 | − function Display(target) { | |
| 27 | − _classCallCheck(this, Display); | |
| 28 | − this._drawCtx = null; | |
| 29 | − this._renderQ = []; // queue drawing actions for in-oder rendering | |
| 30 | − this._flushPromise = null; | |
| 31 | − | |
| 32 | − // the full frame buffer (logical canvas) size | |
| 33 | − this._fbWidth = 0; | |
| 34 | − this._fbHeight = 0; | |
| 35 | − this._prevDrawStyle = ""; | |
| 36 | − Log.Debug(">> Display.constructor"); | |
| 37 | − | |
| 38 | − // The visible canvas | |
| 39 | − this._target = target; | |
| 40 | − if (!this._target) { | |
| 41 | − throw new Error("Target must be set"); | |
| 42 | − } | |
| 43 | − if (typeof this._target === 'string') { | |
| 44 | − throw new Error('target must be a DOM element'); | |
| 45 | − } | |
| 46 | − if (!this._target.getContext) { | |
| 47 | − throw new Error("no getContext method"); | |
| 48 | − } | |
| 49 | − this._targetCtx = this._target.getContext('2d'); | |
| 50 | − | |
| 51 | − // the visible canvas viewport (i.e. what actually gets seen) | |
| 52 | − this._viewportLoc = { | |
| 53 | − 'x': 0, | |
| 54 | − 'y': 0, | |
| 55 | − 'w': this._target.width, | |
| 56 | − 'h': this._target.height | |
| 57 | − }; | |
| 58 | − | |
| 59 | − // The hidden canvas, where we do the actual rendering | |
| 60 | − this._backbuffer = document.createElement('canvas'); | |
| 61 | − this._drawCtx = this._backbuffer.getContext('2d'); | |
| 62 | − this._damageBounds = { | |
| 63 | − left: 0, | |
| 64 | − top: 0, | |
| 65 | − right: this._backbuffer.width, | |
| 66 | − bottom: this._backbuffer.height | |
| 67 | − }; | |
| 68 | − Log.Debug("User Agent: " + navigator.userAgent); | |
| 69 | − Log.Debug("<< Display.constructor"); | |
| 70 | − | |
| 71 | − // ===== PROPERTIES ===== | |
| 72 | − | |
| 73 | − this._scale = 1.0; | |
| 74 | − this._clipViewport = false; | |
| 75 | − } | |
| 76 | − | |
| 77 | − // ===== PROPERTIES ===== | |
| 78 | − return _createClass(Display, [{ | |
| 79 | − key: "scale", | |
| 80 | − get: function get() { | |
| 81 | − return this._scale; | |
| 82 | − }, | |
| 83 | − set: function set(scale) { | |
| 84 | − this._rescale(scale); | |
| 85 | − } | |
| 86 | − }, { | |
| 87 | − key: "clipViewport", | |
| 88 | − get: function get() { | |
| 89 | − return this._clipViewport; | |
| 90 | − }, | |
| 91 | − set: function set(viewport) { | |
| 92 | − this._clipViewport = viewport; | |
| 93 | − // May need to readjust the viewport dimensions | |
| 94 | − var vp = this._viewportLoc; | |
| 95 | − this.viewportChangeSize(vp.w, vp.h); | |
| 96 | − this.viewportChangePos(0, 0); | |
| 97 | − } | |
| 98 | − }, { | |
| 99 | − key: "width", | |
| 100 | − get: function get() { | |
| 101 | − return this._fbWidth; | |
| 102 | − } | |
| 103 | − }, { | |
| 104 | − key: "height", | |
| 105 | − get: function get() { | |
| 106 | − return this._fbHeight; | |
| 107 | − } | |
| 108 | − | |
| 109 | − // ===== PUBLIC METHODS ===== | |
| 110 | − }, { | |
| 111 | − key: "viewportChangePos", | |
| 112 | − value: function viewportChangePos(deltaX, deltaY) { | |
| 113 | − var vp = this._viewportLoc; | |
| 114 | − deltaX = Math.floor(deltaX); | |
| 115 | − deltaY = Math.floor(deltaY); | |
| 116 | − if (!this._clipViewport) { | |
| 117 | − deltaX = -vp.w; // clamped later of out of bounds | |
| 118 | − deltaY = -vp.h; | |
| 119 | − } | |
| 120 | − var vx2 = vp.x + vp.w - 1; | |
| 121 | − var vy2 = vp.y + vp.h - 1; | |
| 122 | − | |
| 123 | − // Position change | |
| 124 | − | |
| 125 | − if (deltaX < 0 && vp.x + deltaX < 0) { | |
| 126 | − deltaX = -vp.x; | |
| 127 | − } | |
| 128 | − if (vx2 + deltaX >= this._fbWidth) { | |
| 129 | − deltaX -= vx2 + deltaX - this._fbWidth + 1; | |
| 130 | − } | |
| 131 | − if (vp.y + deltaY < 0) { | |
| 132 | − deltaY = -vp.y; | |
| 133 | − } | |
| 134 | − if (vy2 + deltaY >= this._fbHeight) { | |
| 135 | − deltaY -= vy2 + deltaY - this._fbHeight + 1; | |
| 136 | − } | |
| 137 | − if (deltaX === 0 && deltaY === 0) { | |
| 138 | − return; | |
| 139 | − } | |
| 140 | − Log.Debug("viewportChange deltaX: " + deltaX + ", deltaY: " + deltaY); | |
| 141 | − vp.x += deltaX; | |
| 142 | − vp.y += deltaY; | |
| 143 | − this._damage(vp.x, vp.y, vp.w, vp.h); | |
| 144 | − this.flip(); | |
| 145 | − } | |
| 146 | − }, { | |
| 147 | − key: "viewportChangeSize", | |
| 148 | − value: function viewportChangeSize(width, height) { | |
| 149 | − if (!this._clipViewport || typeof width === "undefined" || typeof height === "undefined") { | |
| 150 | − Log.Debug("Setting viewport to full display region"); | |
| 151 | − width = this._fbWidth; | |
| 152 | − height = this._fbHeight; | |
| 153 | − } | |
| 154 | − width = Math.floor(width); | |
| 155 | − height = Math.floor(height); | |
| 156 | − if (width > this._fbWidth) { | |
| 157 | − width = this._fbWidth; | |
| 158 | − } | |
| 159 | − if (height > this._fbHeight) { | |
| 160 | − height = this._fbHeight; | |
| 161 | − } | |
| 162 | − var vp = this._viewportLoc; | |
| 163 | − if (vp.w !== width || vp.h !== height) { | |
| 164 | − vp.w = width; | |
| 165 | − vp.h = height; | |
| 166 | − var canvas = this._target; | |
| 167 | − canvas.width = width; | |
| 168 | − canvas.height = height; | |
| 169 | − | |
| 170 | − // The position might need to be updated if we've grown | |
| 171 | − this.viewportChangePos(0, 0); | |
| 172 | − this._damage(vp.x, vp.y, vp.w, vp.h); | |
| 173 | − this.flip(); | |
| 174 | − | |
| 175 | − // Update the visible size of the target canvas | |
| 176 | − this._rescale(this._scale); | |
| 177 | − } | |
| 178 | − } | |
| 179 | − }, { | |
| 180 | − key: "absX", | |
| 181 | − value: function absX(x) { | |
| 182 | − if (this._scale === 0) { | |
| 183 | − return 0; | |
| 184 | − } | |
| 185 | − return (0, _int.toSigned32bit)(x / this._scale + this._viewportLoc.x); | |
| 186 | − } | |
| 187 | − }, { | |
| 188 | − key: "absY", | |
| 189 | − value: function absY(y) { | |
| 190 | − if (this._scale === 0) { | |
| 191 | − return 0; | |
| 192 | − } | |
| 193 | − return (0, _int.toSigned32bit)(y / this._scale + this._viewportLoc.y); | |
| 194 | − } | |
| 195 | − }, { | |
| 196 | − key: "resize", | |
| 197 | − value: function resize(width, height) { | |
| 198 | − this._prevDrawStyle = ""; | |
| 199 | − this._fbWidth = width; | |
| 200 | − this._fbHeight = height; | |
| 201 | − var canvas = this._backbuffer; | |
| 202 | − if (canvas.width !== width || canvas.height !== height) { | |
| 203 | − // We have to save the canvas data since changing the size will clear it | |
| 204 | − var saveImg = null; | |
| 205 | − if (canvas.width > 0 && canvas.height > 0) { | |
| 206 | − saveImg = this._drawCtx.getImageData(0, 0, canvas.width, canvas.height); | |
| 207 | − } | |
| 208 | − if (canvas.width !== width) { | |
| 209 | − canvas.width = width; | |
| 210 | − } | |
| 211 | − if (canvas.height !== height) { | |
| 212 | − canvas.height = height; | |
| 213 | − } | |
| 214 | − if (saveImg) { | |
| 215 | − this._drawCtx.putImageData(saveImg, 0, 0); | |
| 216 | − } | |
| 217 | − } | |
| 218 | − | |
| 219 | − // Readjust the viewport as it may be incorrectly sized | |
| 220 | − // and positioned | |
| 221 | − var vp = this._viewportLoc; | |
| 222 | − this.viewportChangeSize(vp.w, vp.h); | |
| 223 | − this.viewportChangePos(0, 0); | |
| 224 | − } | |
| 225 | − }, { | |
| 226 | − key: "getImageData", | |
| 227 | − value: function getImageData() { | |
| 228 | − return this._drawCtx.getImageData(0, 0, this.width, this.height); | |
| 229 | − } | |
| 230 | − }, { | |
| 231 | − key: "toDataURL", | |
| 232 | − value: function toDataURL(type, encoderOptions) { | |
| 233 | − return this._backbuffer.toDataURL(type, encoderOptions); | |
| 234 | − } | |
| 235 | − }, { | |
| 236 | − key: "toBlob", | |
| 237 | − value: function toBlob(callback, type, quality) { | |
| 238 | − return this._backbuffer.toBlob(callback, type, quality); | |
| 239 | − } | |
| 240 | − | |
| 241 | − // Track what parts of the visible canvas that need updating | |
| 242 | − }, { | |
| 243 | − key: "_damage", | |
| 244 | − value: function _damage(x, y, w, h) { | |
| 245 | − if (x < this._damageBounds.left) { | |
| 246 | − this._damageBounds.left = x; | |
| 247 | − } | |
| 248 | − if (y < this._damageBounds.top) { | |
| 249 | − this._damageBounds.top = y; | |
| 250 | − } | |
| 251 | − if (x + w > this._damageBounds.right) { | |
| 252 | − this._damageBounds.right = x + w; | |
| 253 | − } | |
| 254 | − if (y + h > this._damageBounds.bottom) { | |
| 255 | − this._damageBounds.bottom = y + h; | |
| 256 | − } | |
| 257 | − } | |
| 258 | − | |
| 259 | − // Update the visible canvas with the contents of the | |
| 260 | − // rendering canvas | |
| 261 | − }, { | |
| 262 | − key: "flip", | |
| 263 | − value: function flip(fromQueue) { | |
| 264 | − if (this._renderQ.length !== 0 && !fromQueue) { | |
| 265 | − this._renderQPush({ | |
| 266 | − 'type': 'flip' | |
| 267 | − }); | |
| 268 | − } else { | |
| 269 | − var x = this._damageBounds.left; | |
| 270 | − var y = this._damageBounds.top; | |
| 271 | − var w = this._damageBounds.right - x; | |
| 272 | − var h = this._damageBounds.bottom - y; | |
| 273 | − var vx = x - this._viewportLoc.x; | |
| 274 | − var vy = y - this._viewportLoc.y; | |
| 275 | − if (vx < 0) { | |
| 276 | − w += vx; | |
| 277 | − x -= vx; | |
| 278 | − vx = 0; | |
| 279 | − } | |
| 280 | − if (vy < 0) { | |
| 281 | − h += vy; | |
| 282 | − y -= vy; | |
| 283 | − vy = 0; | |
| 284 | − } | |
| 285 | − if (vx + w > this._viewportLoc.w) { | |
| 286 | − w = this._viewportLoc.w - vx; | |
| 287 | − } | |
| 288 | − if (vy + h > this._viewportLoc.h) { | |
| 289 | − h = this._viewportLoc.h - vy; | |
| 290 | − } | |
| 291 | − if (w > 0 && h > 0) { | |
| 292 | − // FIXME: We may need to disable image smoothing here | |
| 293 | − // as well (see copyImage()), but we haven't | |
| 294 | − // noticed any problem yet. | |
| 295 | − this._targetCtx.drawImage(this._backbuffer, x, y, w, h, vx, vy, w, h); | |
| 296 | − } | |
| 297 | − this._damageBounds.left = this._damageBounds.top = 65535; | |
| 298 | − this._damageBounds.right = this._damageBounds.bottom = 0; | |
| 299 | − } | |
| 300 | − } | |
| 301 | − }, { | |
| 302 | − key: "pending", | |
| 303 | − value: function pending() { | |
| 304 | − return this._renderQ.length > 0; | |
| 305 | − } | |
| 306 | − }, { | |
| 307 | − key: "flush", | |
| 308 | − value: function flush() { | |
| 309 | − var _this = this; | |
| 310 | − if (this._renderQ.length === 0) { | |
| 311 | − return Promise.resolve(); | |
| 312 | − } else { | |
| 313 | − if (this._flushPromise === null) { | |
| 314 | − this._flushPromise = new Promise(function (resolve) { | |
| 315 | − _this._flushResolve = resolve; | |
| 316 | − }); | |
| 317 | − } | |
| 318 | − return this._flushPromise; | |
| 319 | − } | |
| 320 | − } | |
| 321 | − }, { | |
| 322 | − key: "fillRect", | |
| 323 | − value: function fillRect(x, y, width, height, color, fromQueue) { | |
| 324 | − if (this._renderQ.length !== 0 && !fromQueue) { | |
| 325 | − this._renderQPush({ | |
| 326 | − 'type': 'fill', | |
| 327 | − 'x': x, | |
| 328 | − 'y': y, | |
| 329 | − 'width': width, | |
| 330 | − 'height': height, | |
| 331 | − 'color': color | |
| 332 | − }); | |
| 333 | − } else { | |
| 334 | − this._setFillColor(color); | |
| 335 | − this._drawCtx.fillRect(x, y, width, height); | |
| 336 | − this._damage(x, y, width, height); | |
| 337 | − } | |
| 338 | − } | |
| 339 | − }, { | |
| 340 | − key: "copyImage", | |
| 341 | − value: function copyImage(oldX, oldY, newX, newY, w, h, fromQueue) { | |
| 342 | − if (this._renderQ.length !== 0 && !fromQueue) { | |
| 343 | − this._renderQPush({ | |
| 344 | − 'type': 'copy', | |
| 345 | − 'oldX': oldX, | |
| 346 | − 'oldY': oldY, | |
| 347 | − 'x': newX, | |
| 348 | − 'y': newY, | |
| 349 | − 'width': w, | |
| 350 | − 'height': h | |
| 351 | − }); | |
| 352 | − } else { | |
| 353 | − // Due to this bug among others [1] we need to disable the image-smoothing to | |
| 354 | − // avoid getting a blur effect when copying data. | |
| 355 | − // | |
| 356 | − // 1. https://bugzilla.mozilla.org/show_bug.cgi?id=1194719 | |
| 357 | − // | |
| 358 | − // We need to set these every time since all properties are reset | |
| 359 | − // when the the size is changed | |
| 360 | − this._drawCtx.mozImageSmoothingEnabled = false; | |
| 361 | − this._drawCtx.webkitImageSmoothingEnabled = false; | |
| 362 | − this._drawCtx.msImageSmoothingEnabled = false; | |
| 363 | − this._drawCtx.imageSmoothingEnabled = false; | |
| 364 | − this._drawCtx.drawImage(this._backbuffer, oldX, oldY, w, h, newX, newY, w, h); | |
| 365 | − this._damage(newX, newY, w, h); | |
| 366 | − } | |
| 367 | − } | |
| 368 | − }, { | |
| 369 | − key: "imageRect", | |
| 370 | − value: function imageRect(x, y, width, height, mime, arr) { | |
| 371 | − /* The internal logic cannot handle empty images, so bail early */ | |
| 372 | − if (width === 0 || height === 0) { | |
| 373 | − return; | |
| 374 | − } | |
| 375 | − var img = new Image(); | |
| 376 | − img.src = "data: " + mime + ";base64," + _base["default"].encode(arr); | |
| 377 | − this._renderQPush({ | |
| 378 | − 'type': 'img', | |
| 379 | − 'img': img, | |
| 380 | − 'x': x, | |
| 381 | − 'y': y, | |
| 382 | − 'width': width, | |
| 383 | − 'height': height | |
| 384 | − }); | |
| 385 | − } | |
| 386 | − }, { | |
| 387 | − key: "videoFrame", | |
| 388 | − value: function videoFrame(x, y, width, height, frame) { | |
| 389 | − this._renderQPush({ | |
| 390 | − 'type': 'frame', | |
| 391 | − 'frame': frame, | |
| 392 | − 'x': x, | |
| 393 | − 'y': y, | |
| 394 | − 'width': width, | |
| 395 | − 'height': height | |
| 396 | − }); | |
| 397 | − } | |
| 398 | − }, { | |
| 399 | − key: "blitImage", | |
| 400 | − value: function blitImage(x, y, width, height, arr, offset, fromQueue) { | |
| 401 | − if (this._renderQ.length !== 0 && !fromQueue) { | |
| 402 | − // NB(directxman12): it's technically more performant here to use preallocated arrays, | |
| 403 | − // but it's a lot of extra work for not a lot of payoff -- if we're using the render queue, | |
| 404 | − // this probably isn't getting called *nearly* as much | |
| 405 | − var newArr = new Uint8Array(width * height * 4); | |
| 406 | − newArr.set(new Uint8Array(arr.buffer, 0, newArr.length)); | |
| 407 | − this._renderQPush({ | |
| 408 | − 'type': 'blit', | |
| 409 | − 'data': newArr, | |
| 410 | − 'x': x, | |
| 411 | − 'y': y, | |
| 412 | − 'width': width, | |
| 413 | − 'height': height | |
| 414 | − }); | |
| 415 | − } else { | |
| 416 | − // NB(directxman12): arr must be an Type Array view | |
| 417 | − var data = new Uint8ClampedArray(arr.buffer, arr.byteOffset + offset, width * height * 4); | |
| 418 | − var img = new ImageData(data, width, height); | |
| 419 | − this._drawCtx.putImageData(img, x, y); | |
| 420 | − this._damage(x, y, width, height); | |
| 421 | − } | |
| 422 | − } | |
| 423 | − }, { | |
| 424 | − key: "drawImage", | |
| 425 | − value: function drawImage(img) { | |
| 426 | − var _this$_drawCtx; | |
| 427 | − for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | |
| 428 | − args[_key - 1] = arguments[_key]; | |
| 429 | − } | |
| 430 | − (_this$_drawCtx = this._drawCtx).drawImage.apply(_this$_drawCtx, [img].concat(args)); | |
| 431 | − if (args.length <= 4) { | |
| 432 | − var x = args[0], | |
| 433 | − y = args[1]; | |
| 434 | − this._damage(x, y, img.width, img.height); | |
| 435 | − } else { | |
| 436 | − var sw = args[2], | |
| 437 | − sh = args[3], | |
| 438 | − dx = args[4], | |
| 439 | − dy = args[5]; | |
| 440 | − this._damage(dx, dy, sw, sh); | |
| 441 | − } | |
| 442 | − } | |
| 443 | − }, { | |
| 444 | − key: "autoscale", | |
| 445 | − value: function autoscale(containerWidth, containerHeight) { | |
| 446 | − var scaleRatio; | |
| 447 | − if (containerWidth === 0 || containerHeight === 0) { | |
| 448 | − scaleRatio = 0; | |
| 449 | − } else { | |
| 450 | − var vp = this._viewportLoc; | |
| 451 | − var targetAspectRatio = containerWidth / containerHeight; | |
| 452 | − var fbAspectRatio = vp.w / vp.h; | |
| 453 | − if (fbAspectRatio >= targetAspectRatio) { | |
| 454 | − scaleRatio = containerWidth / vp.w; | |
| 455 | − } else { | |
| 456 | − scaleRatio = containerHeight / vp.h; | |
| 457 | − } | |
| 458 | − } | |
| 459 | − this._rescale(scaleRatio); | |
| 460 | − } | |
| 461 | − | |
| 462 | − // ===== PRIVATE METHODS ===== | |
| 463 | − }, { | |
| 464 | − key: "_rescale", | |
| 465 | − value: function _rescale(factor) { | |
| 466 | − this._scale = factor; | |
| 467 | − var vp = this._viewportLoc; | |
| 468 | − | |
| 469 | − // NB(directxman12): If you set the width directly, or set the | |
| 470 | − // style width to a number, the canvas is cleared. | |
| 471 | − // However, if you set the style width to a string | |
| 472 | − // ('NNNpx'), the canvas is scaled without clearing. | |
| 473 | − var width = factor * vp.w + 'px'; | |
| 474 | − var height = factor * vp.h + 'px'; | |
| 475 | − if (this._target.style.width !== width || this._target.style.height !== height) { | |
| 476 | − this._target.style.width = width; | |
| 477 | − this._target.style.height = height; | |
| 478 | − } | |
| 479 | − } | |
| 480 | − }, { | |
| 481 | − key: "_setFillColor", | |
| 482 | − value: function _setFillColor(color) { | |
| 483 | − var newStyle = 'rgb(' + color[0] + ',' + color[1] + ',' + color[2] + ')'; | |
| 484 | − if (newStyle !== this._prevDrawStyle) { | |
| 485 | − this._drawCtx.fillStyle = newStyle; | |
| 486 | − this._prevDrawStyle = newStyle; | |
| 487 | − } | |
| 488 | − } | |
| 489 | − }, { | |
| 490 | − key: "_renderQPush", | |
| 491 | − value: function _renderQPush(action) { | |
| 492 | − this._renderQ.push(action); | |
| 493 | − if (this._renderQ.length === 1) { | |
| 494 | − // If this can be rendered immediately it will be, otherwise | |
| 495 | − // the scanner will wait for the relevant event | |
| 496 | − this._scanRenderQ(); | |
| 497 | − } | |
| 498 | − } | |
| 499 | − }, { | |
| 500 | − key: "_resumeRenderQ", | |
| 501 | − value: function _resumeRenderQ() { | |
| 502 | − // "this" is the object that is ready, not the | |
| 503 | − // display object | |
| 504 | − this.removeEventListener('load', this._noVNCDisplay._resumeRenderQ); | |
| 505 | − this._noVNCDisplay._scanRenderQ(); | |
| 506 | − } | |
| 507 | − }, { | |
| 508 | − key: "_scanRenderQ", | |
| 509 | − value: function _scanRenderQ() { | |
| 510 | − var _this2 = this; | |
| 511 | − var ready = true; | |
| 512 | − var _loop = function _loop() { | |
| 513 | − var a = _this2._renderQ[0]; | |
| 514 | − switch (a.type) { | |
| 515 | − case 'flip': | |
| 516 | − _this2.flip(true); | |
| 517 | − break; | |
| 518 | − case 'copy': | |
| 519 | − _this2.copyImage(a.oldX, a.oldY, a.x, a.y, a.width, a.height, true); | |
| 520 | − break; | |
| 521 | − case 'fill': | |
| 522 | − _this2.fillRect(a.x, a.y, a.width, a.height, a.color, true); | |
| 523 | − break; | |
| 524 | − case 'blit': | |
| 525 | − _this2.blitImage(a.x, a.y, a.width, a.height, a.data, 0, true); | |
| 526 | − break; | |
| 527 | − case 'img': | |
| 528 | − if (a.img.complete) { | |
| 529 | − if (a.img.width !== a.width || a.img.height !== a.height) { | |
| 530 | − Log.Error("Decoded image has incorrect dimensions. Got " + a.img.width + "x" + a.img.height + ". Expected " + a.width + "x" + a.height + "."); | |
| 531 | − return { | |
| 532 | − v: void 0 | |
| 533 | − }; | |
| 534 | − } | |
| 535 | − _this2.drawImage(a.img, a.x, a.y); | |
| 536 | − } else { | |
| 537 | − a.img._noVNCDisplay = _this2; | |
| 538 | − a.img.addEventListener('load', _this2._resumeRenderQ); | |
| 539 | − // We need to wait for this image to 'load' | |
| 540 | − // to keep things in-order | |
| 541 | − ready = false; | |
| 542 | − } | |
| 543 | − break; | |
| 544 | − case 'frame': | |
| 545 | − if (a.frame.ready) { | |
| 546 | − // The encoded frame may be larger than the rect due to | |
| 547 | − // limitations of the encoder, so we need to crop the | |
| 548 | − // frame. | |
| 549 | − var frame = a.frame.frame; | |
| 550 | − if (frame.codedWidth < a.width || frame.codedHeight < a.height) { | |
| 551 | − Log.Warn("Decoded video frame does not cover its full rectangle area. Expecting at least " + a.width + "x" + a.height + " but got " + frame.codedWidth + "x" + frame.codedHeight); | |
| 552 | − } | |
| 553 | − var sx = 0; | |
| 554 | − var sy = 0; | |
| 555 | − var sw = a.width; | |
| 556 | − var sh = a.height; | |
| 557 | − var dx = a.x; | |
| 558 | − var dy = a.y; | |
| 559 | − var dw = sw; | |
| 560 | − var dh = sh; | |
| 561 | − _this2.drawImage(frame, sx, sy, sw, sh, dx, dy, dw, dh); | |
| 562 | − frame.close(); | |
| 563 | − } else { | |
| 564 | − var display = _this2; | |
| 565 | − a.frame.promise.then(function () { | |
| 566 | − display._scanRenderQ(); | |
| 567 | − }); | |
| 568 | − ready = false; | |
| 569 | − } | |
| 570 | − break; | |
| 571 | − } | |
| 572 | − if (ready) { | |
| 573 | − _this2._renderQ.shift(); | |
| 574 | − } | |
| 575 | − }, | |
| 576 | − _ret; | |
| 577 | − while (ready && this._renderQ.length > 0) { | |
| 578 | − _ret = _loop(); | |
| 579 | − if (_ret) return _ret.v; | |
| 580 | − } | |
| 581 | − if (this._renderQ.length === 0 && this._flushPromise !== null) { | |
| 582 | − this._flushResolve(); | |
| 583 | − this._flushPromise = null; | |
| 584 | − this._flushResolve = null; | |
| 585 | − } | |
| 586 | − } | |
| 587 | − }]); | |
| 588 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/encodings.js
+0 −70
@@ -1,70 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports.encodingName = encodingName; | |
| 7 | −exports.encodings = void 0; | |
| 8 | −/* | |
| 9 | − * noVNC: HTML5 VNC client | |
| 10 | − * Copyright (C) 2019 The noVNC authors | |
| 11 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 12 | − * | |
| 13 | − * See README.md for usage and integration instructions. | |
| 14 | − */ | |
| 15 | − | |
| 16 | −var encodings = exports.encodings = { | |
| 17 | − encodingRaw: 0, | |
| 18 | − encodingCopyRect: 1, | |
| 19 | − encodingRRE: 2, | |
| 20 | − encodingHextile: 5, | |
| 21 | − encodingZlib: 6, | |
| 22 | − encodingTight: 7, | |
| 23 | − encodingZRLE: 16, | |
| 24 | − encodingTightPNG: -260, | |
| 25 | − encodingJPEG: 21, | |
| 26 | − encodingH264: 50, | |
| 27 | − pseudoEncodingQualityLevel9: -23, | |
| 28 | − pseudoEncodingQualityLevel0: -32, | |
| 29 | − pseudoEncodingDesktopSize: -223, | |
| 30 | − pseudoEncodingLastRect: -224, | |
| 31 | − pseudoEncodingCursor: -239, | |
| 32 | − pseudoEncodingQEMUExtendedKeyEvent: -258, | |
| 33 | − pseudoEncodingQEMULedEvent: -261, | |
| 34 | − pseudoEncodingDesktopName: -307, | |
| 35 | − pseudoEncodingExtendedDesktopSize: -308, | |
| 36 | − pseudoEncodingXvp: -309, | |
| 37 | − pseudoEncodingFence: -312, | |
| 38 | − pseudoEncodingContinuousUpdates: -313, | |
| 39 | − pseudoEncodingExtendedMouseButtons: -316, | |
| 40 | − pseudoEncodingCompressLevel9: -247, | |
| 41 | − pseudoEncodingCompressLevel0: -256, | |
| 42 | − pseudoEncodingVMwareCursor: 0x574d5664, | |
| 43 | − pseudoEncodingExtendedClipboard: 0xc0a1e5ce | |
| 44 | −}; | |
| 45 | −function encodingName(num) { | |
| 46 | − switch (num) { | |
| 47 | − case encodings.encodingRaw: | |
| 48 | − return "Raw"; | |
| 49 | − case encodings.encodingCopyRect: | |
| 50 | − return "CopyRect"; | |
| 51 | − case encodings.encodingRRE: | |
| 52 | − return "RRE"; | |
| 53 | − case encodings.encodingHextile: | |
| 54 | − return "Hextile"; | |
| 55 | − case encodings.encodingZlib: | |
| 56 | − return "Zlib"; | |
| 57 | − case encodings.encodingTight: | |
| 58 | − return "Tight"; | |
| 59 | − case encodings.encodingZRLE: | |
| 60 | − return "ZRLE"; | |
| 61 | − case encodings.encodingTightPNG: | |
| 62 | − return "TightPNG"; | |
| 63 | − case encodings.encodingJPEG: | |
| 64 | − return "JPEG"; | |
| 65 | − case encodings.encodingH264: | |
| 66 | − return "H.264"; | |
| 67 | − default: | |
| 68 | − return "[unknown encoding " + num + "]"; | |
| 69 | − } | |
| 70 | −} | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/inflator.js
+0 −77
@@ -1,77 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var _inflate2 = require("../lib/vendor/pako/lib/zlib/inflate.js"); | |
| 8 | −var _zstream = _interopRequireDefault(require("../lib/vendor/pako/lib/zlib/zstream.js")); | |
| 9 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 10 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 11 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 12 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 13 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 14 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 15 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /* | |
| 16 | − * noVNC: HTML5 VNC client | |
| 17 | − * Copyright (C) 2020 The noVNC authors | |
| 18 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 19 | − * | |
| 20 | − * See README.md for usage and integration instructions. | |
| 21 | − */ | |
| 22 | −var Inflate = exports["default"] = /*#__PURE__*/function () { | |
| 23 | − function Inflate() { | |
| 24 | − _classCallCheck(this, Inflate); | |
| 25 | − this.strm = new _zstream["default"](); | |
| 26 | − this.chunkSize = 1024 * 10 * 10; | |
| 27 | − this.strm.output = new Uint8Array(this.chunkSize); | |
| 28 | − (0, _inflate2.inflateInit)(this.strm); | |
| 29 | − } | |
| 30 | − return _createClass(Inflate, [{ | |
| 31 | − key: "setInput", | |
| 32 | − value: function setInput(data) { | |
| 33 | − if (!data) { | |
| 34 | − //FIXME: flush remaining data. | |
| 35 | − /* eslint-disable camelcase */ | |
| 36 | − this.strm.input = null; | |
| 37 | − this.strm.avail_in = 0; | |
| 38 | − this.strm.next_in = 0; | |
| 39 | − } else { | |
| 40 | − this.strm.input = data; | |
| 41 | − this.strm.avail_in = this.strm.input.length; | |
| 42 | − this.strm.next_in = 0; | |
| 43 | − /* eslint-enable camelcase */ | |
| 44 | − } | |
| 45 | − } | |
| 46 | − }, { | |
| 47 | − key: "inflate", | |
| 48 | − value: function inflate(expected) { | |
| 49 | − // resize our output buffer if it's too small | |
| 50 | − // (we could just use multiple chunks, but that would cause an extra | |
| 51 | − // allocation each time to flatten the chunks) | |
| 52 | − if (expected > this.chunkSize) { | |
| 53 | − this.chunkSize = expected; | |
| 54 | − this.strm.output = new Uint8Array(this.chunkSize); | |
| 55 | − } | |
| 56 | − | |
| 57 | − /* eslint-disable camelcase */ | |
| 58 | − this.strm.next_out = 0; | |
| 59 | − this.strm.avail_out = expected; | |
| 60 | − /* eslint-enable camelcase */ | |
| 61 | − | |
| 62 | − var ret = (0, _inflate2.inflate)(this.strm, 0); // Flush argument not used. | |
| 63 | − if (ret < 0) { | |
| 64 | − throw new Error("zlib inflate failed"); | |
| 65 | − } | |
| 66 | − if (this.strm.next_out != expected) { | |
| 67 | − throw new Error("Incomplete zlib block"); | |
| 68 | − } | |
| 69 | − return new Uint8Array(this.strm.output.buffer, 0, this.strm.next_out); | |
| 70 | − } | |
| 71 | − }, { | |
| 72 | − key: "reset", | |
| 73 | − value: function reset() { | |
| 74 | − (0, _inflate2.inflateReset)(this.strm); | |
| 75 | − } | |
| 76 | − }]); | |
| 77 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/input/domkeytable.js
+0 −313
@@ -1,313 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var _keysym = _interopRequireDefault(require("./keysym.js")); | |
| 8 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 9 | −/* | |
| 10 | − * noVNC: HTML5 VNC client | |
| 11 | − * Copyright (C) 2018 The noVNC authors | |
| 12 | − * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | |
| 13 | − */ | |
| 14 | − | |
| 15 | −/* | |
| 16 | − * Mapping between HTML key values and VNC/X11 keysyms for "special" | |
| 17 | − * keys that cannot be handled via their Unicode codepoint. | |
| 18 | − * | |
| 19 | − * See https://www.w3.org/TR/uievents-key/ for possible values. | |
| 20 | − */ | |
| 21 | − | |
| 22 | −var DOMKeyTable = {}; | |
| 23 | −function addStandard(key, standard) { | |
| 24 | − if (standard === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | |
| 25 | − if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\""); | |
| 26 | − DOMKeyTable[key] = [standard, standard, standard, standard]; | |
| 27 | −} | |
| 28 | −function addLeftRight(key, left, right) { | |
| 29 | − if (left === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | |
| 30 | − if (right === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | |
| 31 | − if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\""); | |
| 32 | − DOMKeyTable[key] = [left, left, right, left]; | |
| 33 | −} | |
| 34 | −function addNumpad(key, standard, numpad) { | |
| 35 | − if (standard === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | |
| 36 | − if (numpad === undefined) throw new Error("Undefined keysym for key \"" + key + "\""); | |
| 37 | − if (key in DOMKeyTable) throw new Error("Duplicate entry for key \"" + key + "\""); | |
| 38 | − DOMKeyTable[key] = [standard, standard, standard, numpad]; | |
| 39 | −} | |
| 40 | − | |
| 41 | −// 3.2. Modifier Keys | |
| 42 | − | |
| 43 | −addLeftRight("Alt", _keysym["default"].XK_Alt_L, _keysym["default"].XK_Alt_R); | |
| 44 | −addStandard("AltGraph", _keysym["default"].XK_ISO_Level3_Shift); | |
| 45 | −addStandard("CapsLock", _keysym["default"].XK_Caps_Lock); | |
| 46 | −addLeftRight("Control", _keysym["default"].XK_Control_L, _keysym["default"].XK_Control_R); | |
| 47 | −// - Fn | |
| 48 | −// - FnLock | |
| 49 | −addLeftRight("Meta", _keysym["default"].XK_Super_L, _keysym["default"].XK_Super_R); | |
| 50 | −addStandard("NumLock", _keysym["default"].XK_Num_Lock); | |
| 51 | −addStandard("ScrollLock", _keysym["default"].XK_Scroll_Lock); | |
| 52 | −addLeftRight("Shift", _keysym["default"].XK_Shift_L, _keysym["default"].XK_Shift_R); | |
| 53 | −// - Symbol | |
| 54 | −// - SymbolLock | |
| 55 | −// - Hyper | |
| 56 | −// - Super | |
| 57 | − | |
| 58 | −// 3.3. Whitespace Keys | |
| 59 | − | |
| 60 | −addNumpad("Enter", _keysym["default"].XK_Return, _keysym["default"].XK_KP_Enter); | |
| 61 | −addStandard("Tab", _keysym["default"].XK_Tab); | |
| 62 | −addNumpad(" ", _keysym["default"].XK_space, _keysym["default"].XK_KP_Space); | |
| 63 | − | |
| 64 | −// 3.4. Navigation Keys | |
| 65 | − | |
| 66 | −addNumpad("ArrowDown", _keysym["default"].XK_Down, _keysym["default"].XK_KP_Down); | |
| 67 | −addNumpad("ArrowLeft", _keysym["default"].XK_Left, _keysym["default"].XK_KP_Left); | |
| 68 | −addNumpad("ArrowRight", _keysym["default"].XK_Right, _keysym["default"].XK_KP_Right); | |
| 69 | −addNumpad("ArrowUp", _keysym["default"].XK_Up, _keysym["default"].XK_KP_Up); | |
| 70 | −addNumpad("End", _keysym["default"].XK_End, _keysym["default"].XK_KP_End); | |
| 71 | −addNumpad("Home", _keysym["default"].XK_Home, _keysym["default"].XK_KP_Home); | |
| 72 | −addNumpad("PageDown", _keysym["default"].XK_Next, _keysym["default"].XK_KP_Next); | |
| 73 | −addNumpad("PageUp", _keysym["default"].XK_Prior, _keysym["default"].XK_KP_Prior); | |
| 74 | − | |
| 75 | −// 3.5. Editing Keys | |
| 76 | − | |
| 77 | −addStandard("Backspace", _keysym["default"].XK_BackSpace); | |
| 78 | −// Browsers send "Clear" for the numpad 5 without NumLock because | |
| 79 | −// Windows uses VK_Clear for that key. But Unix expects KP_Begin for | |
| 80 | −// that scenario. | |
| 81 | −addNumpad("Clear", _keysym["default"].XK_Clear, _keysym["default"].XK_KP_Begin); | |
| 82 | −addStandard("Copy", _keysym["default"].XF86XK_Copy); | |
| 83 | −// - CrSel | |
| 84 | −addStandard("Cut", _keysym["default"].XF86XK_Cut); | |
| 85 | −addNumpad("Delete", _keysym["default"].XK_Delete, _keysym["default"].XK_KP_Delete); | |
| 86 | −// - EraseEof | |
| 87 | −// - ExSel | |
| 88 | −addNumpad("Insert", _keysym["default"].XK_Insert, _keysym["default"].XK_KP_Insert); | |
| 89 | −addStandard("Paste", _keysym["default"].XF86XK_Paste); | |
| 90 | −addStandard("Redo", _keysym["default"].XK_Redo); | |
| 91 | −addStandard("Undo", _keysym["default"].XK_Undo); | |
| 92 | − | |
| 93 | −// 3.6. UI Keys | |
| 94 | − | |
| 95 | −// - Accept | |
| 96 | −// - Again (could just be XK_Redo) | |
| 97 | −// - Attn | |
| 98 | −addStandard("Cancel", _keysym["default"].XK_Cancel); | |
| 99 | −addStandard("ContextMenu", _keysym["default"].XK_Menu); | |
| 100 | −addStandard("Escape", _keysym["default"].XK_Escape); | |
| 101 | −addStandard("Execute", _keysym["default"].XK_Execute); | |
| 102 | −addStandard("Find", _keysym["default"].XK_Find); | |
| 103 | −addStandard("Help", _keysym["default"].XK_Help); | |
| 104 | −addStandard("Pause", _keysym["default"].XK_Pause); | |
| 105 | −// - Play | |
| 106 | −// - Props | |
| 107 | −addStandard("Select", _keysym["default"].XK_Select); | |
| 108 | −addStandard("ZoomIn", _keysym["default"].XF86XK_ZoomIn); | |
| 109 | −addStandard("ZoomOut", _keysym["default"].XF86XK_ZoomOut); | |
| 110 | − | |
| 111 | −// 3.7. Device Keys | |
| 112 | − | |
| 113 | −addStandard("BrightnessDown", _keysym["default"].XF86XK_MonBrightnessDown); | |
| 114 | −addStandard("BrightnessUp", _keysym["default"].XF86XK_MonBrightnessUp); | |
| 115 | −addStandard("Eject", _keysym["default"].XF86XK_Eject); | |
| 116 | −addStandard("LogOff", _keysym["default"].XF86XK_LogOff); | |
| 117 | −addStandard("Power", _keysym["default"].XF86XK_PowerOff); | |
| 118 | −addStandard("PowerOff", _keysym["default"].XF86XK_PowerDown); | |
| 119 | −addStandard("PrintScreen", _keysym["default"].XK_Print); | |
| 120 | −addStandard("Hibernate", _keysym["default"].XF86XK_Hibernate); | |
| 121 | −addStandard("Standby", _keysym["default"].XF86XK_Standby); | |
| 122 | −addStandard("WakeUp", _keysym["default"].XF86XK_WakeUp); | |
| 123 | − | |
| 124 | −// 3.8. IME and Composition Keys | |
| 125 | − | |
| 126 | −addStandard("AllCandidates", _keysym["default"].XK_MultipleCandidate); | |
| 127 | −addStandard("Alphanumeric", _keysym["default"].XK_Eisu_toggle); | |
| 128 | −addStandard("CodeInput", _keysym["default"].XK_Codeinput); | |
| 129 | −addStandard("Compose", _keysym["default"].XK_Multi_key); | |
| 130 | −addStandard("Convert", _keysym["default"].XK_Henkan); | |
| 131 | −// - Dead | |
| 132 | −// - FinalMode | |
| 133 | −addStandard("GroupFirst", _keysym["default"].XK_ISO_First_Group); | |
| 134 | −addStandard("GroupLast", _keysym["default"].XK_ISO_Last_Group); | |
| 135 | −addStandard("GroupNext", _keysym["default"].XK_ISO_Next_Group); | |
| 136 | −addStandard("GroupPrevious", _keysym["default"].XK_ISO_Prev_Group); | |
| 137 | −// - ModeChange (XK_Mode_switch is often used for AltGr) | |
| 138 | −// - NextCandidate | |
| 139 | −addStandard("NonConvert", _keysym["default"].XK_Muhenkan); | |
| 140 | −addStandard("PreviousCandidate", _keysym["default"].XK_PreviousCandidate); | |
| 141 | −// - Process | |
| 142 | −addStandard("SingleCandidate", _keysym["default"].XK_SingleCandidate); | |
| 143 | −addStandard("HangulMode", _keysym["default"].XK_Hangul); | |
| 144 | −addStandard("HanjaMode", _keysym["default"].XK_Hangul_Hanja); | |
| 145 | −addStandard("JunjaMode", _keysym["default"].XK_Hangul_Jeonja); | |
| 146 | −addStandard("Eisu", _keysym["default"].XK_Eisu_toggle); | |
| 147 | −addStandard("Hankaku", _keysym["default"].XK_Hankaku); | |
| 148 | −addStandard("Hiragana", _keysym["default"].XK_Hiragana); | |
| 149 | −addStandard("HiraganaKatakana", _keysym["default"].XK_Hiragana_Katakana); | |
| 150 | −addStandard("KanaMode", _keysym["default"].XK_Kana_Shift); // could also be _Kana_Lock | |
| 151 | −addStandard("KanjiMode", _keysym["default"].XK_Kanji); | |
| 152 | −addStandard("Katakana", _keysym["default"].XK_Katakana); | |
| 153 | −addStandard("Romaji", _keysym["default"].XK_Romaji); | |
| 154 | −addStandard("Zenkaku", _keysym["default"].XK_Zenkaku); | |
| 155 | −addStandard("ZenkakuHankaku", _keysym["default"].XK_Zenkaku_Hankaku); | |
| 156 | − | |
| 157 | −// 3.9. General-Purpose Function Keys | |
| 158 | − | |
| 159 | −addStandard("F1", _keysym["default"].XK_F1); | |
| 160 | −addStandard("F2", _keysym["default"].XK_F2); | |
| 161 | −addStandard("F3", _keysym["default"].XK_F3); | |
| 162 | −addStandard("F4", _keysym["default"].XK_F4); | |
| 163 | −addStandard("F5", _keysym["default"].XK_F5); | |
| 164 | −addStandard("F6", _keysym["default"].XK_F6); | |
| 165 | −addStandard("F7", _keysym["default"].XK_F7); | |
| 166 | −addStandard("F8", _keysym["default"].XK_F8); | |
| 167 | −addStandard("F9", _keysym["default"].XK_F9); | |
| 168 | −addStandard("F10", _keysym["default"].XK_F10); | |
| 169 | −addStandard("F11", _keysym["default"].XK_F11); | |
| 170 | −addStandard("F12", _keysym["default"].XK_F12); | |
| 171 | −addStandard("F13", _keysym["default"].XK_F13); | |
| 172 | −addStandard("F14", _keysym["default"].XK_F14); | |
| 173 | −addStandard("F15", _keysym["default"].XK_F15); | |
| 174 | −addStandard("F16", _keysym["default"].XK_F16); | |
| 175 | −addStandard("F17", _keysym["default"].XK_F17); | |
| 176 | −addStandard("F18", _keysym["default"].XK_F18); | |
| 177 | −addStandard("F19", _keysym["default"].XK_F19); | |
| 178 | −addStandard("F20", _keysym["default"].XK_F20); | |
| 179 | −addStandard("F21", _keysym["default"].XK_F21); | |
| 180 | −addStandard("F22", _keysym["default"].XK_F22); | |
| 181 | −addStandard("F23", _keysym["default"].XK_F23); | |
| 182 | −addStandard("F24", _keysym["default"].XK_F24); | |
| 183 | −addStandard("F25", _keysym["default"].XK_F25); | |
| 184 | −addStandard("F26", _keysym["default"].XK_F26); | |
| 185 | −addStandard("F27", _keysym["default"].XK_F27); | |
| 186 | −addStandard("F28", _keysym["default"].XK_F28); | |
| 187 | −addStandard("F29", _keysym["default"].XK_F29); | |
| 188 | −addStandard("F30", _keysym["default"].XK_F30); | |
| 189 | −addStandard("F31", _keysym["default"].XK_F31); | |
| 190 | −addStandard("F32", _keysym["default"].XK_F32); | |
| 191 | −addStandard("F33", _keysym["default"].XK_F33); | |
| 192 | −addStandard("F34", _keysym["default"].XK_F34); | |
| 193 | −addStandard("F35", _keysym["default"].XK_F35); | |
| 194 | −// - Soft1... | |
| 195 | − | |
| 196 | −// 3.10. Multimedia Keys | |
| 197 | − | |
| 198 | −// - ChannelDown | |
| 199 | −// - ChannelUp | |
| 200 | −addStandard("Close", _keysym["default"].XF86XK_Close); | |
| 201 | −addStandard("MailForward", _keysym["default"].XF86XK_MailForward); | |
| 202 | −addStandard("MailReply", _keysym["default"].XF86XK_Reply); | |
| 203 | −addStandard("MailSend", _keysym["default"].XF86XK_Send); | |
| 204 | −// - MediaClose | |
| 205 | −addStandard("MediaFastForward", _keysym["default"].XF86XK_AudioForward); | |
| 206 | −addStandard("MediaPause", _keysym["default"].XF86XK_AudioPause); | |
| 207 | −addStandard("MediaPlay", _keysym["default"].XF86XK_AudioPlay); | |
| 208 | −// - MediaPlayPause | |
| 209 | −addStandard("MediaRecord", _keysym["default"].XF86XK_AudioRecord); | |
| 210 | −addStandard("MediaRewind", _keysym["default"].XF86XK_AudioRewind); | |
| 211 | −addStandard("MediaStop", _keysym["default"].XF86XK_AudioStop); | |
| 212 | −addStandard("MediaTrackNext", _keysym["default"].XF86XK_AudioNext); | |
| 213 | −addStandard("MediaTrackPrevious", _keysym["default"].XF86XK_AudioPrev); | |
| 214 | −addStandard("New", _keysym["default"].XF86XK_New); | |
| 215 | −addStandard("Open", _keysym["default"].XF86XK_Open); | |
| 216 | −addStandard("Print", _keysym["default"].XK_Print); | |
| 217 | −addStandard("Save", _keysym["default"].XF86XK_Save); | |
| 218 | −addStandard("SpellCheck", _keysym["default"].XF86XK_Spell); | |
| 219 | − | |
| 220 | −// 3.11. Multimedia Numpad Keys | |
| 221 | − | |
| 222 | −// - Key11 | |
| 223 | −// - Key12 | |
| 224 | − | |
| 225 | −// 3.12. Audio Keys | |
| 226 | − | |
| 227 | −// - AudioBalanceLeft | |
| 228 | −// - AudioBalanceRight | |
| 229 | −// - AudioBassBoostDown | |
| 230 | −// - AudioBassBoostToggle | |
| 231 | −// - AudioBassBoostUp | |
| 232 | −// - AudioFaderFront | |
| 233 | −// - AudioFaderRear | |
| 234 | −// - AudioSurroundModeNext | |
| 235 | −// - AudioTrebleDown | |
| 236 | −// - AudioTrebleUp | |
| 237 | −addStandard("AudioVolumeDown", _keysym["default"].XF86XK_AudioLowerVolume); | |
| 238 | −addStandard("AudioVolumeUp", _keysym["default"].XF86XK_AudioRaiseVolume); | |
| 239 | −addStandard("AudioVolumeMute", _keysym["default"].XF86XK_AudioMute); | |
| 240 | −// - MicrophoneToggle | |
| 241 | −// - MicrophoneVolumeDown | |
| 242 | −// - MicrophoneVolumeUp | |
| 243 | −addStandard("MicrophoneVolumeMute", _keysym["default"].XF86XK_AudioMicMute); | |
| 244 | − | |
| 245 | −// 3.13. Speech Keys | |
| 246 | − | |
| 247 | −// - SpeechCorrectionList | |
| 248 | −// - SpeechInputToggle | |
| 249 | − | |
| 250 | −// 3.14. Application Keys | |
| 251 | − | |
| 252 | −addStandard("LaunchApplication1", _keysym["default"].XF86XK_MyComputer); | |
| 253 | −addStandard("LaunchApplication2", _keysym["default"].XF86XK_Calculator); | |
| 254 | −addStandard("LaunchCalendar", _keysym["default"].XF86XK_Calendar); | |
| 255 | −// - LaunchContacts | |
| 256 | −addStandard("LaunchMail", _keysym["default"].XF86XK_Mail); | |
| 257 | −addStandard("LaunchMediaPlayer", _keysym["default"].XF86XK_AudioMedia); | |
| 258 | −addStandard("LaunchMusicPlayer", _keysym["default"].XF86XK_Music); | |
| 259 | −addStandard("LaunchPhone", _keysym["default"].XF86XK_Phone); | |
| 260 | −addStandard("LaunchScreenSaver", _keysym["default"].XF86XK_ScreenSaver); | |
| 261 | −addStandard("LaunchSpreadsheet", _keysym["default"].XF86XK_Excel); | |
| 262 | −addStandard("LaunchWebBrowser", _keysym["default"].XF86XK_WWW); | |
| 263 | −addStandard("LaunchWebCam", _keysym["default"].XF86XK_WebCam); | |
| 264 | −addStandard("LaunchWordProcessor", _keysym["default"].XF86XK_Word); | |
| 265 | − | |
| 266 | −// 3.15. Browser Keys | |
| 267 | − | |
| 268 | −addStandard("BrowserBack", _keysym["default"].XF86XK_Back); | |
| 269 | −addStandard("BrowserFavorites", _keysym["default"].XF86XK_Favorites); | |
| 270 | −addStandard("BrowserForward", _keysym["default"].XF86XK_Forward); | |
| 271 | −addStandard("BrowserHome", _keysym["default"].XF86XK_HomePage); | |
| 272 | −addStandard("BrowserRefresh", _keysym["default"].XF86XK_Refresh); | |
| 273 | −addStandard("BrowserSearch", _keysym["default"].XF86XK_Search); | |
| 274 | −addStandard("BrowserStop", _keysym["default"].XF86XK_Stop); | |
| 275 | − | |
| 276 | −// 3.16. Mobile Phone Keys | |
| 277 | − | |
| 278 | −// - A whole bunch... | |
| 279 | − | |
| 280 | −// 3.17. TV Keys | |
| 281 | − | |
| 282 | −// - A whole bunch... | |
| 283 | − | |
| 284 | −// 3.18. Media Controller Keys | |
| 285 | − | |
| 286 | −// - A whole bunch... | |
| 287 | −addStandard("Dimmer", _keysym["default"].XF86XK_BrightnessAdjust); | |
| 288 | −addStandard("MediaAudioTrack", _keysym["default"].XF86XK_AudioCycleTrack); | |
| 289 | −addStandard("RandomToggle", _keysym["default"].XF86XK_AudioRandomPlay); | |
| 290 | −addStandard("SplitScreenToggle", _keysym["default"].XF86XK_SplitScreen); | |
| 291 | −addStandard("Subtitle", _keysym["default"].XF86XK_Subtitle); | |
| 292 | −addStandard("VideoModeNext", _keysym["default"].XF86XK_Next_VMode); | |
| 293 | − | |
| 294 | −// Extra: Numpad | |
| 295 | − | |
| 296 | −addNumpad("=", _keysym["default"].XK_equal, _keysym["default"].XK_KP_Equal); | |
| 297 | −addNumpad("+", _keysym["default"].XK_plus, _keysym["default"].XK_KP_Add); | |
| 298 | −addNumpad("-", _keysym["default"].XK_minus, _keysym["default"].XK_KP_Subtract); | |
| 299 | −addNumpad("*", _keysym["default"].XK_asterisk, _keysym["default"].XK_KP_Multiply); | |
| 300 | −addNumpad("/", _keysym["default"].XK_slash, _keysym["default"].XK_KP_Divide); | |
| 301 | −addNumpad(".", _keysym["default"].XK_period, _keysym["default"].XK_KP_Decimal); | |
| 302 | −addNumpad(",", _keysym["default"].XK_comma, _keysym["default"].XK_KP_Separator); | |
| 303 | −addNumpad("0", _keysym["default"].XK_0, _keysym["default"].XK_KP_0); | |
| 304 | −addNumpad("1", _keysym["default"].XK_1, _keysym["default"].XK_KP_1); | |
| 305 | −addNumpad("2", _keysym["default"].XK_2, _keysym["default"].XK_KP_2); | |
| 306 | −addNumpad("3", _keysym["default"].XK_3, _keysym["default"].XK_KP_3); | |
| 307 | −addNumpad("4", _keysym["default"].XK_4, _keysym["default"].XK_KP_4); | |
| 308 | −addNumpad("5", _keysym["default"].XK_5, _keysym["default"].XK_KP_5); | |
| 309 | −addNumpad("6", _keysym["default"].XK_6, _keysym["default"].XK_KP_6); | |
| 310 | −addNumpad("7", _keysym["default"].XK_7, _keysym["default"].XK_KP_7); | |
| 311 | −addNumpad("8", _keysym["default"].XK_8, _keysym["default"].XK_KP_8); | |
| 312 | −addNumpad("9", _keysym["default"].XK_9, _keysym["default"].XK_KP_9); | |
| 313 | −var _default = exports["default"] = DOMKeyTable; | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/input/fixedkeys.js
+0 −127
@@ -1,127 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −/* | |
| 8 | − * noVNC: HTML5 VNC client | |
| 9 | − * Copyright (C) 2018 The noVNC authors | |
| 10 | − * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | |
| 11 | − */ | |
| 12 | −/* | |
| 13 | − * Fallback mapping between HTML key codes (physical keys) and | |
| 14 | − * HTML key values. This only works for keys that don't vary | |
| 15 | − * between layouts. We also omit those who manage fine by mapping the | |
| 16 | − * Unicode representation. | |
| 17 | − * | |
| 18 | − * See https://www.w3.org/TR/uievents-code/ for possible codes. | |
| 19 | − * See https://www.w3.org/TR/uievents-key/ for possible values. | |
| 20 | − */ | |
| 21 | −/* eslint-disable key-spacing */ | |
| 22 | −var _default = exports["default"] = { | |
| 23 | − // 3.1.1.1. Writing System Keys | |
| 24 | − | |
| 25 | − 'Backspace': 'Backspace', | |
| 26 | − // 3.1.1.2. Functional Keys | |
| 27 | − | |
| 28 | − 'AltLeft': 'Alt', | |
| 29 | − 'AltRight': 'Alt', | |
| 30 | − // This could also be 'AltGraph' | |
| 31 | − 'CapsLock': 'CapsLock', | |
| 32 | − 'ContextMenu': 'ContextMenu', | |
| 33 | − 'ControlLeft': 'Control', | |
| 34 | − 'ControlRight': 'Control', | |
| 35 | − 'Enter': 'Enter', | |
| 36 | − 'MetaLeft': 'Meta', | |
| 37 | − 'MetaRight': 'Meta', | |
| 38 | − 'ShiftLeft': 'Shift', | |
| 39 | − 'ShiftRight': 'Shift', | |
| 40 | − 'Tab': 'Tab', | |
| 41 | − // FIXME: Japanese/Korean keys | |
| 42 | − | |
| 43 | − // 3.1.2. Control Pad Section | |
| 44 | − | |
| 45 | − 'Delete': 'Delete', | |
| 46 | − 'End': 'End', | |
| 47 | − 'Help': 'Help', | |
| 48 | − 'Home': 'Home', | |
| 49 | − 'Insert': 'Insert', | |
| 50 | − 'PageDown': 'PageDown', | |
| 51 | − 'PageUp': 'PageUp', | |
| 52 | − // 3.1.3. Arrow Pad Section | |
| 53 | − | |
| 54 | − 'ArrowDown': 'ArrowDown', | |
| 55 | − 'ArrowLeft': 'ArrowLeft', | |
| 56 | − 'ArrowRight': 'ArrowRight', | |
| 57 | − 'ArrowUp': 'ArrowUp', | |
| 58 | − // 3.1.4. Numpad Section | |
| 59 | − | |
| 60 | − 'NumLock': 'NumLock', | |
| 61 | − 'NumpadBackspace': 'Backspace', | |
| 62 | − 'NumpadClear': 'Clear', | |
| 63 | − // 3.1.5. Function Section | |
| 64 | − | |
| 65 | − 'Escape': 'Escape', | |
| 66 | − 'F1': 'F1', | |
| 67 | − 'F2': 'F2', | |
| 68 | − 'F3': 'F3', | |
| 69 | − 'F4': 'F4', | |
| 70 | − 'F5': 'F5', | |
| 71 | − 'F6': 'F6', | |
| 72 | − 'F7': 'F7', | |
| 73 | − 'F8': 'F8', | |
| 74 | − 'F9': 'F9', | |
| 75 | − 'F10': 'F10', | |
| 76 | − 'F11': 'F11', | |
| 77 | − 'F12': 'F12', | |
| 78 | − 'F13': 'F13', | |
| 79 | − 'F14': 'F14', | |
| 80 | − 'F15': 'F15', | |
| 81 | − 'F16': 'F16', | |
| 82 | − 'F17': 'F17', | |
| 83 | − 'F18': 'F18', | |
| 84 | − 'F19': 'F19', | |
| 85 | − 'F20': 'F20', | |
| 86 | − 'F21': 'F21', | |
| 87 | − 'F22': 'F22', | |
| 88 | − 'F23': 'F23', | |
| 89 | − 'F24': 'F24', | |
| 90 | − 'F25': 'F25', | |
| 91 | − 'F26': 'F26', | |
| 92 | − 'F27': 'F27', | |
| 93 | − 'F28': 'F28', | |
| 94 | − 'F29': 'F29', | |
| 95 | − 'F30': 'F30', | |
| 96 | − 'F31': 'F31', | |
| 97 | − 'F32': 'F32', | |
| 98 | − 'F33': 'F33', | |
| 99 | − 'F34': 'F34', | |
| 100 | − 'F35': 'F35', | |
| 101 | − 'PrintScreen': 'PrintScreen', | |
| 102 | − 'ScrollLock': 'ScrollLock', | |
| 103 | − 'Pause': 'Pause', | |
| 104 | − // 3.1.6. Media Keys | |
| 105 | − | |
| 106 | − 'BrowserBack': 'BrowserBack', | |
| 107 | − 'BrowserFavorites': 'BrowserFavorites', | |
| 108 | − 'BrowserForward': 'BrowserForward', | |
| 109 | − 'BrowserHome': 'BrowserHome', | |
| 110 | − 'BrowserRefresh': 'BrowserRefresh', | |
| 111 | − 'BrowserSearch': 'BrowserSearch', | |
| 112 | − 'BrowserStop': 'BrowserStop', | |
| 113 | − 'Eject': 'Eject', | |
| 114 | − 'LaunchApp1': 'LaunchMyComputer', | |
| 115 | − 'LaunchApp2': 'LaunchCalendar', | |
| 116 | − 'LaunchMail': 'LaunchMail', | |
| 117 | − 'MediaPlayPause': 'MediaPlay', | |
| 118 | − 'MediaStop': 'MediaStop', | |
| 119 | − 'MediaTrackNext': 'MediaTrackNext', | |
| 120 | − 'MediaTrackPrevious': 'MediaTrackPrevious', | |
| 121 | − 'Power': 'Power', | |
| 122 | − 'Sleep': 'Sleep', | |
| 123 | − 'AudioVolumeDown': 'AudioVolumeDown', | |
| 124 | − 'AudioVolumeMute': 'AudioVolumeMute', | |
| 125 | − 'AudioVolumeUp': 'AudioVolumeUp', | |
| 126 | − 'WakeUp': 'WakeUp' | |
| 127 | −}; | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/input/gesturehandler.js
+0 −573
@@ -1,573 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 8 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 9 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 10 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 11 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 12 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 13 | −/* | |
| 14 | − * noVNC: HTML5 VNC client | |
| 15 | − * Copyright (C) 2020 The noVNC authors | |
| 16 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 17 | − * | |
| 18 | − * See README.md for usage and integration instructions. | |
| 19 | − * | |
| 20 | − */ | |
| 21 | − | |
| 22 | −var GH_NOGESTURE = 0; | |
| 23 | −var GH_ONETAP = 1; | |
| 24 | −var GH_TWOTAP = 2; | |
| 25 | −var GH_THREETAP = 4; | |
| 26 | −var GH_DRAG = 8; | |
| 27 | −var GH_LONGPRESS = 16; | |
| 28 | −var GH_TWODRAG = 32; | |
| 29 | −var GH_PINCH = 64; | |
| 30 | −var GH_INITSTATE = 127; | |
| 31 | −var GH_MOVE_THRESHOLD = 50; | |
| 32 | −var GH_ANGLE_THRESHOLD = 90; // Degrees | |
| 33 | − | |
| 34 | −// Timeout when waiting for gestures (ms) | |
| 35 | −var GH_MULTITOUCH_TIMEOUT = 250; | |
| 36 | − | |
| 37 | −// Maximum time between press and release for a tap (ms) | |
| 38 | −var GH_TAP_TIMEOUT = 1000; | |
| 39 | − | |
| 40 | −// Timeout when waiting for longpress (ms) | |
| 41 | −var GH_LONGPRESS_TIMEOUT = 1000; | |
| 42 | − | |
| 43 | −// Timeout when waiting to decide between PINCH and TWODRAG (ms) | |
| 44 | −var GH_TWOTOUCH_TIMEOUT = 50; | |
| 45 | −var GestureHandler = exports["default"] = /*#__PURE__*/function () { | |
| 46 | − function GestureHandler() { | |
| 47 | − _classCallCheck(this, GestureHandler); | |
| 48 | − this._target = null; | |
| 49 | − this._state = GH_INITSTATE; | |
| 50 | − this._tracked = []; | |
| 51 | − this._ignored = []; | |
| 52 | − this._waitingRelease = false; | |
| 53 | − this._releaseStart = 0.0; | |
| 54 | − this._longpressTimeoutId = null; | |
| 55 | − this._twoTouchTimeoutId = null; | |
| 56 | − this._boundEventHandler = this._eventHandler.bind(this); | |
| 57 | − } | |
| 58 | − return _createClass(GestureHandler, [{ | |
| 59 | − key: "attach", | |
| 60 | − value: function attach(target) { | |
| 61 | − this.detach(); | |
| 62 | − this._target = target; | |
| 63 | − this._target.addEventListener('touchstart', this._boundEventHandler); | |
| 64 | − this._target.addEventListener('touchmove', this._boundEventHandler); | |
| 65 | − this._target.addEventListener('touchend', this._boundEventHandler); | |
| 66 | − this._target.addEventListener('touchcancel', this._boundEventHandler); | |
| 67 | − } | |
| 68 | − }, { | |
| 69 | − key: "detach", | |
| 70 | − value: function detach() { | |
| 71 | − if (!this._target) { | |
| 72 | − return; | |
| 73 | − } | |
| 74 | − this._stopLongpressTimeout(); | |
| 75 | − this._stopTwoTouchTimeout(); | |
| 76 | − this._target.removeEventListener('touchstart', this._boundEventHandler); | |
| 77 | − this._target.removeEventListener('touchmove', this._boundEventHandler); | |
| 78 | − this._target.removeEventListener('touchend', this._boundEventHandler); | |
| 79 | − this._target.removeEventListener('touchcancel', this._boundEventHandler); | |
| 80 | − this._target = null; | |
| 81 | − } | |
| 82 | − }, { | |
| 83 | − key: "_eventHandler", | |
| 84 | − value: function _eventHandler(e) { | |
| 85 | − var fn; | |
| 86 | − e.stopPropagation(); | |
| 87 | − e.preventDefault(); | |
| 88 | − switch (e.type) { | |
| 89 | − case 'touchstart': | |
| 90 | − fn = this._touchStart; | |
| 91 | − break; | |
| 92 | − case 'touchmove': | |
| 93 | − fn = this._touchMove; | |
| 94 | − break; | |
| 95 | − case 'touchend': | |
| 96 | − case 'touchcancel': | |
| 97 | − fn = this._touchEnd; | |
| 98 | − break; | |
| 99 | − } | |
| 100 | − for (var i = 0; i < e.changedTouches.length; i++) { | |
| 101 | − var touch = e.changedTouches[i]; | |
| 102 | − fn.call(this, touch.identifier, touch.clientX, touch.clientY); | |
| 103 | − } | |
| 104 | − } | |
| 105 | − }, { | |
| 106 | − key: "_touchStart", | |
| 107 | − value: function _touchStart(id, x, y) { | |
| 108 | − // Ignore any new touches if there is already an active gesture, | |
| 109 | − // or we're in a cleanup state | |
| 110 | − if (this._hasDetectedGesture() || this._state === GH_NOGESTURE) { | |
| 111 | − this._ignored.push(id); | |
| 112 | − return; | |
| 113 | − } | |
| 114 | − | |
| 115 | − // Did it take too long between touches that we should no longer | |
| 116 | − // consider this a single gesture? | |
| 117 | − if (this._tracked.length > 0 && Date.now() - this._tracked[0].started > GH_MULTITOUCH_TIMEOUT) { | |
| 118 | − this._state = GH_NOGESTURE; | |
| 119 | − this._ignored.push(id); | |
| 120 | − return; | |
| 121 | − } | |
| 122 | − | |
| 123 | − // If we're waiting for fingers to release then we should no longer | |
| 124 | − // recognize new touches | |
| 125 | − if (this._waitingRelease) { | |
| 126 | − this._state = GH_NOGESTURE; | |
| 127 | − this._ignored.push(id); | |
| 128 | − return; | |
| 129 | − } | |
| 130 | − this._tracked.push({ | |
| 131 | − id: id, | |
| 132 | − started: Date.now(), | |
| 133 | − active: true, | |
| 134 | − firstX: x, | |
| 135 | − firstY: y, | |
| 136 | − lastX: x, | |
| 137 | − lastY: y, | |
| 138 | − angle: 0 | |
| 139 | − }); | |
| 140 | − switch (this._tracked.length) { | |
| 141 | − case 1: | |
| 142 | − this._startLongpressTimeout(); | |
| 143 | − break; | |
| 144 | − case 2: | |
| 145 | − this._state &= ~(GH_ONETAP | GH_DRAG | GH_LONGPRESS); | |
| 146 | − this._stopLongpressTimeout(); | |
| 147 | − break; | |
| 148 | − case 3: | |
| 149 | − this._state &= ~(GH_TWOTAP | GH_TWODRAG | GH_PINCH); | |
| 150 | − break; | |
| 151 | − default: | |
| 152 | − this._state = GH_NOGESTURE; | |
| 153 | − } | |
| 154 | − } | |
| 155 | − }, { | |
| 156 | − key: "_touchMove", | |
| 157 | − value: function _touchMove(id, x, y) { | |
| 158 | − var touch = this._tracked.find(function (t) { | |
| 159 | − return t.id === id; | |
| 160 | − }); | |
| 161 | − | |
| 162 | − // If this is an update for a touch we're not tracking, ignore it | |
| 163 | − if (touch === undefined) { | |
| 164 | − return; | |
| 165 | − } | |
| 166 | − | |
| 167 | − // Update the touches last position with the event coordinates | |
| 168 | − touch.lastX = x; | |
| 169 | − touch.lastY = y; | |
| 170 | − var deltaX = x - touch.firstX; | |
| 171 | − var deltaY = y - touch.firstY; | |
| 172 | − | |
| 173 | − // Update angle when the touch has moved | |
| 174 | − if (touch.firstX !== touch.lastX || touch.firstY !== touch.lastY) { | |
| 175 | − touch.angle = Math.atan2(deltaY, deltaX) * 180 / Math.PI; | |
| 176 | − } | |
| 177 | − if (!this._hasDetectedGesture()) { | |
| 178 | − // Ignore moves smaller than the minimum threshold | |
| 179 | − if (Math.hypot(deltaX, deltaY) < GH_MOVE_THRESHOLD) { | |
| 180 | − return; | |
| 181 | − } | |
| 182 | − | |
| 183 | − // Can't be a tap or long press as we've seen movement | |
| 184 | − this._state &= ~(GH_ONETAP | GH_TWOTAP | GH_THREETAP | GH_LONGPRESS); | |
| 185 | − this._stopLongpressTimeout(); | |
| 186 | − if (this._tracked.length !== 1) { | |
| 187 | − this._state &= ~GH_DRAG; | |
| 188 | − } | |
| 189 | − if (this._tracked.length !== 2) { | |
| 190 | − this._state &= ~(GH_TWODRAG | GH_PINCH); | |
| 191 | − } | |
| 192 | − | |
| 193 | − // We need to figure out which of our different two touch gestures | |
| 194 | − // this might be | |
| 195 | − if (this._tracked.length === 2) { | |
| 196 | − // The other touch is the one where the id doesn't match | |
| 197 | − var prevTouch = this._tracked.find(function (t) { | |
| 198 | − return t.id !== id; | |
| 199 | − }); | |
| 200 | − | |
| 201 | − // How far the previous touch point has moved since start | |
| 202 | − var prevDeltaMove = Math.hypot(prevTouch.firstX - prevTouch.lastX, prevTouch.firstY - prevTouch.lastY); | |
| 203 | − | |
| 204 | − // We know that the current touch moved far enough, | |
| 205 | − // but unless both touches moved further than their | |
| 206 | − // threshold we don't want to disqualify any gestures | |
| 207 | − if (prevDeltaMove > GH_MOVE_THRESHOLD) { | |
| 208 | − // The angle difference between the direction of the touch points | |
| 209 | − var deltaAngle = Math.abs(touch.angle - prevTouch.angle); | |
| 210 | − deltaAngle = Math.abs((deltaAngle + 180) % 360 - 180); | |
| 211 | − | |
| 212 | − // PINCH or TWODRAG can be eliminated depending on the angle | |
| 213 | − if (deltaAngle > GH_ANGLE_THRESHOLD) { | |
| 214 | − this._state &= ~GH_TWODRAG; | |
| 215 | − } else { | |
| 216 | − this._state &= ~GH_PINCH; | |
| 217 | − } | |
| 218 | − if (this._isTwoTouchTimeoutRunning()) { | |
| 219 | − this._stopTwoTouchTimeout(); | |
| 220 | − } | |
| 221 | − } else if (!this._isTwoTouchTimeoutRunning()) { | |
| 222 | − // We can't determine the gesture right now, let's | |
| 223 | − // wait and see if more events are on their way | |
| 224 | − this._startTwoTouchTimeout(); | |
| 225 | − } | |
| 226 | − } | |
| 227 | − if (!this._hasDetectedGesture()) { | |
| 228 | − return; | |
| 229 | − } | |
| 230 | − this._pushEvent('gesturestart'); | |
| 231 | − } | |
| 232 | − this._pushEvent('gesturemove'); | |
| 233 | − } | |
| 234 | − }, { | |
| 235 | − key: "_touchEnd", | |
| 236 | − value: function _touchEnd(id, x, y) { | |
| 237 | − // Check if this is an ignored touch | |
| 238 | − if (this._ignored.indexOf(id) !== -1) { | |
| 239 | − // Remove this touch from ignored | |
| 240 | − this._ignored.splice(this._ignored.indexOf(id), 1); | |
| 241 | − | |
| 242 | − // And reset the state if there are no more touches | |
| 243 | − if (this._ignored.length === 0 && this._tracked.length === 0) { | |
| 244 | − this._state = GH_INITSTATE; | |
| 245 | − this._waitingRelease = false; | |
| 246 | − } | |
| 247 | − return; | |
| 248 | − } | |
| 249 | − | |
| 250 | − // We got a touchend before the timer triggered, | |
| 251 | − // this cannot result in a gesture anymore. | |
| 252 | − if (!this._hasDetectedGesture() && this._isTwoTouchTimeoutRunning()) { | |
| 253 | − this._stopTwoTouchTimeout(); | |
| 254 | − this._state = GH_NOGESTURE; | |
| 255 | − } | |
| 256 | − | |
| 257 | − // Some gestures don't trigger until a touch is released | |
| 258 | − if (!this._hasDetectedGesture()) { | |
| 259 | − // Can't be a gesture that relies on movement | |
| 260 | − this._state &= ~(GH_DRAG | GH_TWODRAG | GH_PINCH); | |
| 261 | − // Or something that relies on more time | |
| 262 | − this._state &= ~GH_LONGPRESS; | |
| 263 | − this._stopLongpressTimeout(); | |
| 264 | − if (!this._waitingRelease) { | |
| 265 | − this._releaseStart = Date.now(); | |
| 266 | − this._waitingRelease = true; | |
| 267 | − | |
| 268 | − // Can't be a tap that requires more touches than we current have | |
| 269 | − switch (this._tracked.length) { | |
| 270 | − case 1: | |
| 271 | − this._state &= ~(GH_TWOTAP | GH_THREETAP); | |
| 272 | − break; | |
| 273 | − case 2: | |
| 274 | − this._state &= ~(GH_ONETAP | GH_THREETAP); | |
| 275 | − break; | |
| 276 | − } | |
| 277 | − } | |
| 278 | − } | |
| 279 | − | |
| 280 | − // Waiting for all touches to release? (i.e. some tap) | |
| 281 | − if (this._waitingRelease) { | |
| 282 | − // Were all touches released at roughly the same time? | |
| 283 | − if (Date.now() - this._releaseStart > GH_MULTITOUCH_TIMEOUT) { | |
| 284 | − this._state = GH_NOGESTURE; | |
| 285 | − } | |
| 286 | − | |
| 287 | − // Did too long time pass between press and release? | |
| 288 | − if (this._tracked.some(function (t) { | |
| 289 | − return Date.now() - t.started > GH_TAP_TIMEOUT; | |
| 290 | − })) { | |
| 291 | − this._state = GH_NOGESTURE; | |
| 292 | − } | |
| 293 | − var touch = this._tracked.find(function (t) { | |
| 294 | − return t.id === id; | |
| 295 | − }); | |
| 296 | − touch.active = false; | |
| 297 | − | |
| 298 | − // Are we still waiting for more releases? | |
| 299 | − if (this._hasDetectedGesture()) { | |
| 300 | − this._pushEvent('gesturestart'); | |
| 301 | − } else { | |
| 302 | − // Have we reached a dead end? | |
| 303 | − if (this._state !== GH_NOGESTURE) { | |
| 304 | − return; | |
| 305 | − } | |
| 306 | − } | |
| 307 | − } | |
| 308 | − if (this._hasDetectedGesture()) { | |
| 309 | − this._pushEvent('gestureend'); | |
| 310 | − } | |
| 311 | − | |
| 312 | − // Ignore any remaining touches until they are ended | |
| 313 | − for (var i = 0; i < this._tracked.length; i++) { | |
| 314 | − if (this._tracked[i].active) { | |
| 315 | − this._ignored.push(this._tracked[i].id); | |
| 316 | − } | |
| 317 | − } | |
| 318 | − this._tracked = []; | |
| 319 | − this._state = GH_NOGESTURE; | |
| 320 | − | |
| 321 | − // Remove this touch from ignored if it's in there | |
| 322 | − if (this._ignored.indexOf(id) !== -1) { | |
| 323 | − this._ignored.splice(this._ignored.indexOf(id), 1); | |
| 324 | − } | |
| 325 | − | |
| 326 | − // We reset the state if ignored is empty | |
| 327 | − if (this._ignored.length === 0) { | |
| 328 | − this._state = GH_INITSTATE; | |
| 329 | − this._waitingRelease = false; | |
| 330 | − } | |
| 331 | − } | |
| 332 | − }, { | |
| 333 | − key: "_hasDetectedGesture", | |
| 334 | − value: function _hasDetectedGesture() { | |
| 335 | − if (this._state === GH_NOGESTURE) { | |
| 336 | − return false; | |
| 337 | − } | |
| 338 | − // Check to see if the bitmask value is a power of 2 | |
| 339 | − // (i.e. only one bit set). If it is, we have a state. | |
| 340 | − if (this._state & this._state - 1) { | |
| 341 | − return false; | |
| 342 | − } | |
| 343 | − | |
| 344 | − // For taps we also need to have all touches released | |
| 345 | − // before we've fully detected the gesture | |
| 346 | − if (this._state & (GH_ONETAP | GH_TWOTAP | GH_THREETAP)) { | |
| 347 | − if (this._tracked.some(function (t) { | |
| 348 | − return t.active; | |
| 349 | − })) { | |
| 350 | − return false; | |
| 351 | − } | |
| 352 | − } | |
| 353 | − return true; | |
| 354 | − } | |
| 355 | − }, { | |
| 356 | − key: "_startLongpressTimeout", | |
| 357 | − value: function _startLongpressTimeout() { | |
| 358 | − var _this = this; | |
| 359 | − this._stopLongpressTimeout(); | |
| 360 | − this._longpressTimeoutId = setTimeout(function () { | |
| 361 | − return _this._longpressTimeout(); | |
| 362 | − }, GH_LONGPRESS_TIMEOUT); | |
| 363 | − } | |
| 364 | − }, { | |
| 365 | − key: "_stopLongpressTimeout", | |
| 366 | − value: function _stopLongpressTimeout() { | |
| 367 | − clearTimeout(this._longpressTimeoutId); | |
| 368 | − this._longpressTimeoutId = null; | |
| 369 | − } | |
| 370 | − }, { | |
| 371 | − key: "_longpressTimeout", | |
| 372 | − value: function _longpressTimeout() { | |
| 373 | − if (this._hasDetectedGesture()) { | |
| 374 | − throw new Error("A longpress gesture failed, conflict with a different gesture"); | |
| 375 | − } | |
| 376 | − this._state = GH_LONGPRESS; | |
| 377 | − this._pushEvent('gesturestart'); | |
| 378 | − } | |
| 379 | − }, { | |
| 380 | − key: "_startTwoTouchTimeout", | |
| 381 | − value: function _startTwoTouchTimeout() { | |
| 382 | − var _this2 = this; | |
| 383 | − this._stopTwoTouchTimeout(); | |
| 384 | − this._twoTouchTimeoutId = setTimeout(function () { | |
| 385 | − return _this2._twoTouchTimeout(); | |
| 386 | − }, GH_TWOTOUCH_TIMEOUT); | |
| 387 | − } | |
| 388 | − }, { | |
| 389 | − key: "_stopTwoTouchTimeout", | |
| 390 | − value: function _stopTwoTouchTimeout() { | |
| 391 | − clearTimeout(this._twoTouchTimeoutId); | |
| 392 | − this._twoTouchTimeoutId = null; | |
| 393 | − } | |
| 394 | − }, { | |
| 395 | − key: "_isTwoTouchTimeoutRunning", | |
| 396 | − value: function _isTwoTouchTimeoutRunning() { | |
| 397 | − return this._twoTouchTimeoutId !== null; | |
| 398 | − } | |
| 399 | − }, { | |
| 400 | − key: "_twoTouchTimeout", | |
| 401 | − value: function _twoTouchTimeout() { | |
| 402 | − if (this._tracked.length === 0) { | |
| 403 | − throw new Error("A pinch or two drag gesture failed, no tracked touches"); | |
| 404 | − } | |
| 405 | − | |
| 406 | − // How far each touch point has moved since start | |
| 407 | − var avgM = this._getAverageMovement(); | |
| 408 | − var avgMoveH = Math.abs(avgM.x); | |
| 409 | − var avgMoveV = Math.abs(avgM.y); | |
| 410 | − | |
| 411 | − // The difference in the distance between where | |
| 412 | − // the touch points started and where they are now | |
| 413 | − var avgD = this._getAverageDistance(); | |
| 414 | − var deltaTouchDistance = Math.abs(Math.hypot(avgD.first.x, avgD.first.y) - Math.hypot(avgD.last.x, avgD.last.y)); | |
| 415 | − if (avgMoveV < deltaTouchDistance && avgMoveH < deltaTouchDistance) { | |
| 416 | − this._state = GH_PINCH; | |
| 417 | − } else { | |
| 418 | − this._state = GH_TWODRAG; | |
| 419 | − } | |
| 420 | − this._pushEvent('gesturestart'); | |
| 421 | − this._pushEvent('gesturemove'); | |
| 422 | − } | |
| 423 | − }, { | |
| 424 | − key: "_pushEvent", | |
| 425 | − value: function _pushEvent(type) { | |
| 426 | − var detail = { | |
| 427 | − type: this._stateToGesture(this._state) | |
| 428 | − }; | |
| 429 | − | |
| 430 | − // For most gesture events the current (average) position is the | |
| 431 | − // most useful | |
| 432 | − var avg = this._getPosition(); | |
| 433 | − var pos = avg.last; | |
| 434 | − | |
| 435 | − // However we have a slight distance to detect gestures, so for the | |
| 436 | − // first gesture event we want to use the first positions we saw | |
| 437 | − if (type === 'gesturestart') { | |
| 438 | − pos = avg.first; | |
| 439 | − } | |
| 440 | − | |
| 441 | − // For these gestures, we always want the event coordinates | |
| 442 | − // to be where the gesture began, not the current touch location. | |
| 443 | − switch (this._state) { | |
| 444 | − case GH_TWODRAG: | |
| 445 | − case GH_PINCH: | |
| 446 | − pos = avg.first; | |
| 447 | − break; | |
| 448 | − } | |
| 449 | − detail['clientX'] = pos.x; | |
| 450 | − detail['clientY'] = pos.y; | |
| 451 | − | |
| 452 | − // FIXME: other coordinates? | |
| 453 | − | |
| 454 | − // Some gestures also have a magnitude | |
| 455 | − if (this._state === GH_PINCH) { | |
| 456 | − var distance = this._getAverageDistance(); | |
| 457 | − if (type === 'gesturestart') { | |
| 458 | − detail['magnitudeX'] = distance.first.x; | |
| 459 | − detail['magnitudeY'] = distance.first.y; | |
| 460 | − } else { | |
| 461 | − detail['magnitudeX'] = distance.last.x; | |
| 462 | − detail['magnitudeY'] = distance.last.y; | |
| 463 | − } | |
| 464 | − } else if (this._state === GH_TWODRAG) { | |
| 465 | − if (type === 'gesturestart') { | |
| 466 | − detail['magnitudeX'] = 0.0; | |
| 467 | − detail['magnitudeY'] = 0.0; | |
| 468 | − } else { | |
| 469 | − var movement = this._getAverageMovement(); | |
| 470 | − detail['magnitudeX'] = movement.x; | |
| 471 | − detail['magnitudeY'] = movement.y; | |
| 472 | − } | |
| 473 | − } | |
| 474 | − var gev = new CustomEvent(type, { | |
| 475 | − detail: detail | |
| 476 | − }); | |
| 477 | − this._target.dispatchEvent(gev); | |
| 478 | − } | |
| 479 | − }, { | |
| 480 | − key: "_stateToGesture", | |
| 481 | − value: function _stateToGesture(state) { | |
| 482 | − switch (state) { | |
| 483 | − case GH_ONETAP: | |
| 484 | − return 'onetap'; | |
| 485 | − case GH_TWOTAP: | |
| 486 | − return 'twotap'; | |
| 487 | − case GH_THREETAP: | |
| 488 | − return 'threetap'; | |
| 489 | − case GH_DRAG: | |
| 490 | − return 'drag'; | |
| 491 | − case GH_LONGPRESS: | |
| 492 | − return 'longpress'; | |
| 493 | − case GH_TWODRAG: | |
| 494 | − return 'twodrag'; | |
| 495 | − case GH_PINCH: | |
| 496 | − return 'pinch'; | |
| 497 | − } | |
| 498 | − throw new Error("Unknown gesture state: " + state); | |
| 499 | − } | |
| 500 | − }, { | |
| 501 | − key: "_getPosition", | |
| 502 | − value: function _getPosition() { | |
| 503 | − if (this._tracked.length === 0) { | |
| 504 | − throw new Error("Failed to get gesture position, no tracked touches"); | |
| 505 | − } | |
| 506 | − var size = this._tracked.length; | |
| 507 | − var fx = 0, | |
| 508 | − fy = 0, | |
| 509 | − lx = 0, | |
| 510 | − ly = 0; | |
| 511 | − for (var i = 0; i < this._tracked.length; i++) { | |
| 512 | − fx += this._tracked[i].firstX; | |
| 513 | − fy += this._tracked[i].firstY; | |
| 514 | − lx += this._tracked[i].lastX; | |
| 515 | − ly += this._tracked[i].lastY; | |
| 516 | − } | |
| 517 | − return { | |
| 518 | − first: { | |
| 519 | − x: fx / size, | |
| 520 | − y: fy / size | |
| 521 | − }, | |
| 522 | − last: { | |
| 523 | − x: lx / size, | |
| 524 | − y: ly / size | |
| 525 | − } | |
| 526 | − }; | |
| 527 | − } | |
| 528 | − }, { | |
| 529 | − key: "_getAverageMovement", | |
| 530 | − value: function _getAverageMovement() { | |
| 531 | − if (this._tracked.length === 0) { | |
| 532 | − throw new Error("Failed to get gesture movement, no tracked touches"); | |
| 533 | − } | |
| 534 | − var totalH, totalV; | |
| 535 | − totalH = totalV = 0; | |
| 536 | − var size = this._tracked.length; | |
| 537 | − for (var i = 0; i < this._tracked.length; i++) { | |
| 538 | − totalH += this._tracked[i].lastX - this._tracked[i].firstX; | |
| 539 | − totalV += this._tracked[i].lastY - this._tracked[i].firstY; | |
| 540 | − } | |
| 541 | − return { | |
| 542 | − x: totalH / size, | |
| 543 | − y: totalV / size | |
| 544 | − }; | |
| 545 | − } | |
| 546 | − }, { | |
| 547 | − key: "_getAverageDistance", | |
| 548 | − value: function _getAverageDistance() { | |
| 549 | − if (this._tracked.length === 0) { | |
| 550 | − throw new Error("Failed to get gesture distance, no tracked touches"); | |
| 551 | − } | |
| 552 | − | |
| 553 | − // Distance between the first and last tracked touches | |
| 554 | − | |
| 555 | − var first = this._tracked[0]; | |
| 556 | − var last = this._tracked[this._tracked.length - 1]; | |
| 557 | − var fdx = Math.abs(last.firstX - first.firstX); | |
| 558 | − var fdy = Math.abs(last.firstY - first.firstY); | |
| 559 | − var ldx = Math.abs(last.lastX - first.lastX); | |
| 560 | − var ldy = Math.abs(last.lastY - first.lastY); | |
| 561 | − return { | |
| 562 | − first: { | |
| 563 | − x: fdx, | |
| 564 | − y: fdy | |
| 565 | − }, | |
| 566 | − last: { | |
| 567 | − x: ldx, | |
| 568 | − y: ldy | |
| 569 | − } | |
| 570 | − }; | |
| 571 | − } | |
| 572 | − }]); | |
| 573 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/input/keyboard.js
+0 −293
@@ -1,293 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var Log = _interopRequireWildcard(require("../util/logging.js")); | |
| 8 | −var _events = require("../util/events.js"); | |
| 9 | −var KeyboardUtil = _interopRequireWildcard(require("./util.js")); | |
| 10 | −var _keysym = _interopRequireDefault(require("./keysym.js")); | |
| 11 | −var browser = _interopRequireWildcard(require("../util/browser.js")); | |
| 12 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 13 | −function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } | |
| 14 | −function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } | |
| 15 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 16 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 17 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 18 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 19 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 20 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /* | |
| 21 | − * noVNC: HTML5 VNC client | |
| 22 | − * Copyright (C) 2019 The noVNC authors | |
| 23 | − * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | |
| 24 | − */ | |
| 25 | −// | |
| 26 | −// Keyboard event handler | |
| 27 | −// | |
| 28 | −var Keyboard = exports["default"] = /*#__PURE__*/function () { | |
| 29 | − function Keyboard(target) { | |
| 30 | − _classCallCheck(this, Keyboard); | |
| 31 | − this._target = target || null; | |
| 32 | − this._keyDownList = {}; // List of depressed keys | |
| 33 | − // (even if they are happy) | |
| 34 | − this._altGrArmed = false; // Windows AltGr detection | |
| 35 | − | |
| 36 | − // keep these here so we can refer to them later | |
| 37 | − this._eventHandlers = { | |
| 38 | − 'keyup': this._handleKeyUp.bind(this), | |
| 39 | − 'keydown': this._handleKeyDown.bind(this), | |
| 40 | − 'blur': this._allKeysUp.bind(this) | |
| 41 | − }; | |
| 42 | − | |
| 43 | − // ===== EVENT HANDLERS ===== | |
| 44 | − | |
| 45 | − this.onkeyevent = function () {}; // Handler for key press/release | |
| 46 | − } | |
| 47 | − | |
| 48 | − // ===== PRIVATE METHODS ===== | |
| 49 | − return _createClass(Keyboard, [{ | |
| 50 | − key: "_sendKeyEvent", | |
| 51 | − value: function _sendKeyEvent(keysym, code, down) { | |
| 52 | − var numlock = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; | |
| 53 | − var capslock = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; | |
| 54 | − if (down) { | |
| 55 | − this._keyDownList[code] = keysym; | |
| 56 | − } else { | |
| 57 | − // Do we really think this key is down? | |
| 58 | − if (!(code in this._keyDownList)) { | |
| 59 | − return; | |
| 60 | − } | |
| 61 | − delete this._keyDownList[code]; | |
| 62 | − } | |
| 63 | − Log.Debug("onkeyevent " + (down ? "down" : "up") + ", keysym: " + keysym, ", code: " + code + ", numlock: " + numlock + ", capslock: " + capslock); | |
| 64 | − this.onkeyevent(keysym, code, down, numlock, capslock); | |
| 65 | − } | |
| 66 | − }, { | |
| 67 | − key: "_getKeyCode", | |
| 68 | − value: function _getKeyCode(e) { | |
| 69 | − var code = KeyboardUtil.getKeycode(e); | |
| 70 | − if (code !== 'Unidentified') { | |
| 71 | − return code; | |
| 72 | − } | |
| 73 | − | |
| 74 | − // Unstable, but we don't have anything else to go on | |
| 75 | − if (e.keyCode) { | |
| 76 | − // 229 is used for composition events | |
| 77 | − if (e.keyCode !== 229) { | |
| 78 | − return 'Platform' + e.keyCode; | |
| 79 | − } | |
| 80 | − } | |
| 81 | − | |
| 82 | − // A precursor to the final DOM3 standard. Unfortunately it | |
| 83 | − // is not layout independent, so it is as bad as using keyCode | |
| 84 | − if (e.keyIdentifier) { | |
| 85 | − // Non-character key? | |
| 86 | − if (e.keyIdentifier.substr(0, 2) !== 'U+') { | |
| 87 | − return e.keyIdentifier; | |
| 88 | − } | |
| 89 | − var codepoint = parseInt(e.keyIdentifier.substr(2), 16); | |
| 90 | − var _char = String.fromCharCode(codepoint).toUpperCase(); | |
| 91 | − return 'Platform' + _char.charCodeAt(); | |
| 92 | − } | |
| 93 | − return 'Unidentified'; | |
| 94 | − } | |
| 95 | − }, { | |
| 96 | − key: "_handleKeyDown", | |
| 97 | − value: function _handleKeyDown(e) { | |
| 98 | − var code = this._getKeyCode(e); | |
| 99 | − var keysym = KeyboardUtil.getKeysym(e); | |
| 100 | − var numlock = e.getModifierState('NumLock'); | |
| 101 | − var capslock = e.getModifierState('CapsLock'); | |
| 102 | − | |
| 103 | − // getModifierState for NumLock is not supported on mac and ios and always returns false. | |
| 104 | − // Set to null to indicate unknown/unsupported instead. | |
| 105 | − if (browser.isMac() || browser.isIOS()) { | |
| 106 | − numlock = null; | |
| 107 | − } | |
| 108 | − | |
| 109 | − // Windows doesn't have a proper AltGr, but handles it using | |
| 110 | − // fake Ctrl+Alt. However the remote end might not be Windows, | |
| 111 | − // so we need to merge those in to a single AltGr event. We | |
| 112 | − // detect this case by seeing the two key events directly after | |
| 113 | − // each other with a very short time between them (<50ms). | |
| 114 | − if (this._altGrArmed) { | |
| 115 | − this._altGrArmed = false; | |
| 116 | − clearTimeout(this._altGrTimeout); | |
| 117 | − if (code === "AltRight" && e.timeStamp - this._altGrCtrlTime < 50) { | |
| 118 | − // FIXME: We fail to detect this if either Ctrl key is | |
| 119 | − // first manually pressed as Windows then no | |
| 120 | − // longer sends the fake Ctrl down event. It | |
| 121 | − // does however happily send real Ctrl events | |
| 122 | − // even when AltGr is already down. Some | |
| 123 | − // browsers detect this for us though and set the | |
| 124 | − // key to "AltGraph". | |
| 125 | − keysym = _keysym["default"].XK_ISO_Level3_Shift; | |
| 126 | − } else { | |
| 127 | − this._sendKeyEvent(_keysym["default"].XK_Control_L, "ControlLeft", true, numlock, capslock); | |
| 128 | − } | |
| 129 | − } | |
| 130 | − | |
| 131 | − // We cannot handle keys we cannot track, but we also need | |
| 132 | − // to deal with virtual keyboards which omit key info | |
| 133 | − if (code === 'Unidentified') { | |
| 134 | − if (keysym) { | |
| 135 | − // If it's a virtual keyboard then it should be | |
| 136 | − // sufficient to just send press and release right | |
| 137 | − // after each other | |
| 138 | − this._sendKeyEvent(keysym, code, true, numlock, capslock); | |
| 139 | − this._sendKeyEvent(keysym, code, false, numlock, capslock); | |
| 140 | − } | |
| 141 | − (0, _events.stopEvent)(e); | |
| 142 | − return; | |
| 143 | − } | |
| 144 | − | |
| 145 | − // Alt behaves more like AltGraph on macOS, so shuffle the | |
| 146 | − // keys around a bit to make things more sane for the remote | |
| 147 | − // server. This method is used by RealVNC and TigerVNC (and | |
| 148 | − // possibly others). | |
| 149 | − if (browser.isMac() || browser.isIOS()) { | |
| 150 | − switch (keysym) { | |
| 151 | − case _keysym["default"].XK_Super_L: | |
| 152 | − keysym = _keysym["default"].XK_Alt_L; | |
| 153 | − break; | |
| 154 | − case _keysym["default"].XK_Super_R: | |
| 155 | − keysym = _keysym["default"].XK_Super_L; | |
| 156 | − break; | |
| 157 | − case _keysym["default"].XK_Alt_L: | |
| 158 | − keysym = _keysym["default"].XK_Mode_switch; | |
| 159 | − break; | |
| 160 | − case _keysym["default"].XK_Alt_R: | |
| 161 | − keysym = _keysym["default"].XK_ISO_Level3_Shift; | |
| 162 | − break; | |
| 163 | − } | |
| 164 | − } | |
| 165 | − | |
| 166 | − // Is this key already pressed? If so, then we must use the | |
| 167 | − // same keysym or we'll confuse the server | |
| 168 | − if (code in this._keyDownList) { | |
| 169 | − keysym = this._keyDownList[code]; | |
| 170 | − } | |
| 171 | − | |
| 172 | − // macOS doesn't send proper key releases if a key is pressed | |
| 173 | − // while meta is held down | |
| 174 | − if ((browser.isMac() || browser.isIOS()) && e.metaKey && code !== 'MetaLeft' && code !== 'MetaRight') { | |
| 175 | − this._sendKeyEvent(keysym, code, true, numlock, capslock); | |
| 176 | − this._sendKeyEvent(keysym, code, false, numlock, capslock); | |
| 177 | − (0, _events.stopEvent)(e); | |
| 178 | − return; | |
| 179 | − } | |
| 180 | − | |
| 181 | − // macOS doesn't send proper key events for modifiers, only | |
| 182 | − // state change events. That gets extra confusing for CapsLock | |
| 183 | − // which toggles on each press, but not on release. So pretend | |
| 184 | − // it was a quick press and release of the button. | |
| 185 | − if ((browser.isMac() || browser.isIOS()) && code === 'CapsLock') { | |
| 186 | − this._sendKeyEvent(_keysym["default"].XK_Caps_Lock, 'CapsLock', true, numlock, capslock); | |
| 187 | − this._sendKeyEvent(_keysym["default"].XK_Caps_Lock, 'CapsLock', false, numlock, capslock); | |
| 188 | − (0, _events.stopEvent)(e); | |
| 189 | − return; | |
| 190 | − } | |
| 191 | − | |
| 192 | − // Windows doesn't send proper key releases for a bunch of | |
| 193 | − // Japanese IM keys so we have to fake the release right away | |
| 194 | − var jpBadKeys = [_keysym["default"].XK_Zenkaku_Hankaku, _keysym["default"].XK_Eisu_toggle, _keysym["default"].XK_Katakana, _keysym["default"].XK_Hiragana, _keysym["default"].XK_Romaji]; | |
| 195 | − if (browser.isWindows() && jpBadKeys.includes(keysym)) { | |
| 196 | − this._sendKeyEvent(keysym, code, true, numlock, capslock); | |
| 197 | − this._sendKeyEvent(keysym, code, false, numlock, capslock); | |
| 198 | − (0, _events.stopEvent)(e); | |
| 199 | − return; | |
| 200 | − } | |
| 201 | − (0, _events.stopEvent)(e); | |
| 202 | − | |
| 203 | − // Possible start of AltGr sequence? (see above) | |
| 204 | − if (code === "ControlLeft" && browser.isWindows() && !("ControlLeft" in this._keyDownList)) { | |
| 205 | − this._altGrArmed = true; | |
| 206 | − this._altGrTimeout = setTimeout(this._interruptAltGrSequence.bind(this), 100); | |
| 207 | − this._altGrCtrlTime = e.timeStamp; | |
| 208 | − return; | |
| 209 | − } | |
| 210 | − this._sendKeyEvent(keysym, code, true, numlock, capslock); | |
| 211 | − } | |
| 212 | − }, { | |
| 213 | − key: "_handleKeyUp", | |
| 214 | − value: function _handleKeyUp(e) { | |
| 215 | − (0, _events.stopEvent)(e); | |
| 216 | − var code = this._getKeyCode(e); | |
| 217 | − | |
| 218 | − // We can't get a release in the middle of an AltGr sequence, so | |
| 219 | − // abort that detection | |
| 220 | − this._interruptAltGrSequence(); | |
| 221 | − | |
| 222 | − // See comment in _handleKeyDown() | |
| 223 | − if ((browser.isMac() || browser.isIOS()) && code === 'CapsLock') { | |
| 224 | − this._sendKeyEvent(_keysym["default"].XK_Caps_Lock, 'CapsLock', true); | |
| 225 | − this._sendKeyEvent(_keysym["default"].XK_Caps_Lock, 'CapsLock', false); | |
| 226 | − return; | |
| 227 | − } | |
| 228 | − this._sendKeyEvent(this._keyDownList[code], code, false); | |
| 229 | − | |
| 230 | − // Windows has a rather nasty bug where it won't send key | |
| 231 | − // release events for a Shift button if the other Shift is still | |
| 232 | − // pressed | |
| 233 | − if (browser.isWindows() && (code === 'ShiftLeft' || code === 'ShiftRight')) { | |
| 234 | − if ('ShiftRight' in this._keyDownList) { | |
| 235 | − this._sendKeyEvent(this._keyDownList['ShiftRight'], 'ShiftRight', false); | |
| 236 | − } | |
| 237 | − if ('ShiftLeft' in this._keyDownList) { | |
| 238 | − this._sendKeyEvent(this._keyDownList['ShiftLeft'], 'ShiftLeft', false); | |
| 239 | − } | |
| 240 | − } | |
| 241 | − } | |
| 242 | − }, { | |
| 243 | − key: "_interruptAltGrSequence", | |
| 244 | − value: function _interruptAltGrSequence() { | |
| 245 | − if (this._altGrArmed) { | |
| 246 | − this._altGrArmed = false; | |
| 247 | − clearTimeout(this._altGrTimeout); | |
| 248 | − this._sendKeyEvent(_keysym["default"].XK_Control_L, "ControlLeft", true); | |
| 249 | − } | |
| 250 | − } | |
| 251 | − }, { | |
| 252 | − key: "_allKeysUp", | |
| 253 | − value: function _allKeysUp() { | |
| 254 | − Log.Debug(">> Keyboard.allKeysUp"); | |
| 255 | − | |
| 256 | − // Prevent control key being processed after losing focus. | |
| 257 | − this._interruptAltGrSequence(); | |
| 258 | − for (var code in this._keyDownList) { | |
| 259 | − this._sendKeyEvent(this._keyDownList[code], code, false); | |
| 260 | − } | |
| 261 | − Log.Debug("<< Keyboard.allKeysUp"); | |
| 262 | − } | |
| 263 | − | |
| 264 | − // ===== PUBLIC METHODS ===== | |
| 265 | − }, { | |
| 266 | − key: "grab", | |
| 267 | − value: function grab() { | |
| 268 | − //Log.Debug(">> Keyboard.grab"); | |
| 269 | − | |
| 270 | − this._target.addEventListener('keydown', this._eventHandlers.keydown); | |
| 271 | − this._target.addEventListener('keyup', this._eventHandlers.keyup); | |
| 272 | − | |
| 273 | − // Release (key up) if window loses focus | |
| 274 | − window.addEventListener('blur', this._eventHandlers.blur); | |
| 275 | − | |
| 276 | − //Log.Debug("<< Keyboard.grab"); | |
| 277 | − } | |
| 278 | − }, { | |
| 279 | − key: "ungrab", | |
| 280 | − value: function ungrab() { | |
| 281 | − //Log.Debug(">> Keyboard.ungrab"); | |
| 282 | − | |
| 283 | − this._target.removeEventListener('keydown', this._eventHandlers.keydown); | |
| 284 | − this._target.removeEventListener('keyup', this._eventHandlers.keyup); | |
| 285 | − window.removeEventListener('blur', this._eventHandlers.blur); | |
| 286 | − | |
| 287 | − // Release (key up) all keys that are in a down state | |
| 288 | − this._allKeysUp(); | |
| 289 | − | |
| 290 | − //Log.Debug(">> Keyboard.ungrab"); | |
| 291 | − } | |
| 292 | − }]); | |
| 293 | −}(); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/input/keysym.js
+0 −878
@@ -1,878 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −/* eslint-disable key-spacing */ | |
| 8 | −var _default = exports["default"] = { | |
| 9 | − XK_VoidSymbol: 0xffffff, | |
| 10 | − /* Void symbol */ | |
| 11 | − | |
| 12 | − XK_BackSpace: 0xff08, | |
| 13 | − /* Back space, back char */ | |
| 14 | − XK_Tab: 0xff09, | |
| 15 | − XK_Linefeed: 0xff0a, | |
| 16 | − /* Linefeed, LF */ | |
| 17 | − XK_Clear: 0xff0b, | |
| 18 | − XK_Return: 0xff0d, | |
| 19 | − /* Return, enter */ | |
| 20 | − XK_Pause: 0xff13, | |
| 21 | − /* Pause, hold */ | |
| 22 | − XK_Scroll_Lock: 0xff14, | |
| 23 | − XK_Sys_Req: 0xff15, | |
| 24 | − XK_Escape: 0xff1b, | |
| 25 | − XK_Delete: 0xffff, | |
| 26 | − /* Delete, rubout */ | |
| 27 | − | |
| 28 | − /* International & multi-key character composition */ | |
| 29 | − | |
| 30 | − XK_Multi_key: 0xff20, | |
| 31 | − /* Multi-key character compose */ | |
| 32 | − XK_Codeinput: 0xff37, | |
| 33 | − XK_SingleCandidate: 0xff3c, | |
| 34 | − XK_MultipleCandidate: 0xff3d, | |
| 35 | − XK_PreviousCandidate: 0xff3e, | |
| 36 | − /* Japanese keyboard support */ | |
| 37 | − | |
| 38 | − XK_Kanji: 0xff21, | |
| 39 | − /* Kanji, Kanji convert */ | |
| 40 | − XK_Muhenkan: 0xff22, | |
| 41 | − /* Cancel Conversion */ | |
| 42 | − XK_Henkan_Mode: 0xff23, | |
| 43 | − /* Start/Stop Conversion */ | |
| 44 | − XK_Henkan: 0xff23, | |
| 45 | − /* Alias for Henkan_Mode */ | |
| 46 | − XK_Romaji: 0xff24, | |
| 47 | − /* to Romaji */ | |
| 48 | − XK_Hiragana: 0xff25, | |
| 49 | − /* to Hiragana */ | |
| 50 | − XK_Katakana: 0xff26, | |
| 51 | − /* to Katakana */ | |
| 52 | − XK_Hiragana_Katakana: 0xff27, | |
| 53 | − /* Hiragana/Katakana toggle */ | |
| 54 | − XK_Zenkaku: 0xff28, | |
| 55 | − /* to Zenkaku */ | |
| 56 | − XK_Hankaku: 0xff29, | |
| 57 | − /* to Hankaku */ | |
| 58 | − XK_Zenkaku_Hankaku: 0xff2a, | |
| 59 | − /* Zenkaku/Hankaku toggle */ | |
| 60 | − XK_Touroku: 0xff2b, | |
| 61 | − /* Add to Dictionary */ | |
| 62 | − XK_Massyo: 0xff2c, | |
| 63 | − /* Delete from Dictionary */ | |
| 64 | − XK_Kana_Lock: 0xff2d, | |
| 65 | − /* Kana Lock */ | |
| 66 | − XK_Kana_Shift: 0xff2e, | |
| 67 | − /* Kana Shift */ | |
| 68 | − XK_Eisu_Shift: 0xff2f, | |
| 69 | − /* Alphanumeric Shift */ | |
| 70 | − XK_Eisu_toggle: 0xff30, | |
| 71 | − /* Alphanumeric toggle */ | |
| 72 | − XK_Kanji_Bangou: 0xff37, | |
| 73 | − /* Codeinput */ | |
| 74 | − XK_Zen_Koho: 0xff3d, | |
| 75 | − /* Multiple/All Candidate(s) */ | |
| 76 | − XK_Mae_Koho: 0xff3e, | |
| 77 | − /* Previous Candidate */ | |
| 78 | − | |
| 79 | − /* Cursor control & motion */ | |
| 80 | − | |
| 81 | − XK_Home: 0xff50, | |
| 82 | − XK_Left: 0xff51, | |
| 83 | − /* Move left, left arrow */ | |
| 84 | − XK_Up: 0xff52, | |
| 85 | − /* Move up, up arrow */ | |
| 86 | − XK_Right: 0xff53, | |
| 87 | − /* Move right, right arrow */ | |
| 88 | − XK_Down: 0xff54, | |
| 89 | − /* Move down, down arrow */ | |
| 90 | − XK_Prior: 0xff55, | |
| 91 | − /* Prior, previous */ | |
| 92 | − XK_Page_Up: 0xff55, | |
| 93 | − XK_Next: 0xff56, | |
| 94 | − /* Next */ | |
| 95 | − XK_Page_Down: 0xff56, | |
| 96 | − XK_End: 0xff57, | |
| 97 | − /* EOL */ | |
| 98 | − XK_Begin: 0xff58, | |
| 99 | − /* BOL */ | |
| 100 | − | |
| 101 | − /* Misc functions */ | |
| 102 | − | |
| 103 | − XK_Select: 0xff60, | |
| 104 | − /* Select, mark */ | |
| 105 | − XK_Print: 0xff61, | |
| 106 | − XK_Execute: 0xff62, | |
| 107 | − /* Execute, run, do */ | |
| 108 | − XK_Insert: 0xff63, | |
| 109 | − /* Insert, insert here */ | |
| 110 | − XK_Undo: 0xff65, | |
| 111 | − XK_Redo: 0xff66, | |
| 112 | − /* Redo, again */ | |
| 113 | − XK_Menu: 0xff67, | |
| 114 | − XK_Find: 0xff68, | |
| 115 | − /* Find, search */ | |
| 116 | − XK_Cancel: 0xff69, | |
| 117 | − /* Cancel, stop, abort, exit */ | |
| 118 | − XK_Help: 0xff6a, | |
| 119 | − /* Help */ | |
| 120 | − XK_Break: 0xff6b, | |
| 121 | − XK_Mode_switch: 0xff7e, | |
| 122 | − /* Character set switch */ | |
| 123 | − XK_script_switch: 0xff7e, | |
| 124 | − /* Alias for mode_switch */ | |
| 125 | − XK_Num_Lock: 0xff7f, | |
| 126 | − /* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ | |
| 127 | − | |
| 128 | − XK_KP_Space: 0xff80, | |
| 129 | − /* Space */ | |
| 130 | − XK_KP_Tab: 0xff89, | |
| 131 | − XK_KP_Enter: 0xff8d, | |
| 132 | − /* Enter */ | |
| 133 | − XK_KP_F1: 0xff91, | |
| 134 | − /* PF1, KP_A, ... */ | |
| 135 | − XK_KP_F2: 0xff92, | |
| 136 | − XK_KP_F3: 0xff93, | |
| 137 | − XK_KP_F4: 0xff94, | |
| 138 | − XK_KP_Home: 0xff95, | |
| 139 | − XK_KP_Left: 0xff96, | |
| 140 | − XK_KP_Up: 0xff97, | |
| 141 | − XK_KP_Right: 0xff98, | |
| 142 | − XK_KP_Down: 0xff99, | |
| 143 | − XK_KP_Prior: 0xff9a, | |
| 144 | − XK_KP_Page_Up: 0xff9a, | |
| 145 | − XK_KP_Next: 0xff9b, | |
| 146 | − XK_KP_Page_Down: 0xff9b, | |
| 147 | − XK_KP_End: 0xff9c, | |
| 148 | − XK_KP_Begin: 0xff9d, | |
| 149 | − XK_KP_Insert: 0xff9e, | |
| 150 | − XK_KP_Delete: 0xff9f, | |
| 151 | − XK_KP_Equal: 0xffbd, | |
| 152 | − /* Equals */ | |
| 153 | − XK_KP_Multiply: 0xffaa, | |
| 154 | − XK_KP_Add: 0xffab, | |
| 155 | − XK_KP_Separator: 0xffac, | |
| 156 | − /* Separator, often comma */ | |
| 157 | − XK_KP_Subtract: 0xffad, | |
| 158 | − XK_KP_Decimal: 0xffae, | |
| 159 | − XK_KP_Divide: 0xffaf, | |
| 160 | − XK_KP_0: 0xffb0, | |
| 161 | − XK_KP_1: 0xffb1, | |
| 162 | − XK_KP_2: 0xffb2, | |
| 163 | − XK_KP_3: 0xffb3, | |
| 164 | − XK_KP_4: 0xffb4, | |
| 165 | − XK_KP_5: 0xffb5, | |
| 166 | − XK_KP_6: 0xffb6, | |
| 167 | − XK_KP_7: 0xffb7, | |
| 168 | − XK_KP_8: 0xffb8, | |
| 169 | − XK_KP_9: 0xffb9, | |
| 170 | − /* | |
| 171 | − * Auxiliary functions; note the duplicate definitions for left and right | |
| 172 | − * function keys; Sun keyboards and a few other manufacturers have such | |
| 173 | − * function key groups on the left and/or right sides of the keyboard. | |
| 174 | − * We've not found a keyboard with more than 35 function keys total. | |
| 175 | − */ | |
| 176 | − | |
| 177 | − XK_F1: 0xffbe, | |
| 178 | − XK_F2: 0xffbf, | |
| 179 | − XK_F3: 0xffc0, | |
| 180 | − XK_F4: 0xffc1, | |
| 181 | − XK_F5: 0xffc2, | |
| 182 | − XK_F6: 0xffc3, | |
| 183 | − XK_F7: 0xffc4, | |
| 184 | − XK_F8: 0xffc5, | |
| 185 | − XK_F9: 0xffc6, | |
| 186 | − XK_F10: 0xffc7, | |
| 187 | − XK_F11: 0xffc8, | |
| 188 | − XK_L1: 0xffc8, | |
| 189 | − XK_F12: 0xffc9, | |
| 190 | − XK_L2: 0xffc9, | |
| 191 | − XK_F13: 0xffca, | |
| 192 | − XK_L3: 0xffca, | |
| 193 | − XK_F14: 0xffcb, | |
| 194 | − XK_L4: 0xffcb, | |
| 195 | − XK_F15: 0xffcc, | |
| 196 | − XK_L5: 0xffcc, | |
| 197 | − XK_F16: 0xffcd, | |
| 198 | − XK_L6: 0xffcd, | |
| 199 | − XK_F17: 0xffce, | |
| 200 | − XK_L7: 0xffce, | |
| 201 | − XK_F18: 0xffcf, | |
| 202 | − XK_L8: 0xffcf, | |
| 203 | − XK_F19: 0xffd0, | |
| 204 | − XK_L9: 0xffd0, | |
| 205 | − XK_F20: 0xffd1, | |
| 206 | − XK_L10: 0xffd1, | |
| 207 | − XK_F21: 0xffd2, | |
| 208 | − XK_R1: 0xffd2, | |
| 209 | − XK_F22: 0xffd3, | |
| 210 | − XK_R2: 0xffd3, | |
| 211 | − XK_F23: 0xffd4, | |
| 212 | − XK_R3: 0xffd4, | |
| 213 | − XK_F24: 0xffd5, | |
| 214 | − XK_R4: 0xffd5, | |
| 215 | − XK_F25: 0xffd6, | |
| 216 | − XK_R5: 0xffd6, | |
| 217 | − XK_F26: 0xffd7, | |
| 218 | − XK_R6: 0xffd7, | |
| 219 | − XK_F27: 0xffd8, | |
| 220 | − XK_R7: 0xffd8, | |
| 221 | − XK_F28: 0xffd9, | |
| 222 | − XK_R8: 0xffd9, | |
| 223 | − XK_F29: 0xffda, | |
| 224 | − XK_R9: 0xffda, | |
| 225 | − XK_F30: 0xffdb, | |
| 226 | − XK_R10: 0xffdb, | |
| 227 | − XK_F31: 0xffdc, | |
| 228 | − XK_R11: 0xffdc, | |
| 229 | − XK_F32: 0xffdd, | |
| 230 | − XK_R12: 0xffdd, | |
| 231 | − XK_F33: 0xffde, | |
| 232 | − XK_R13: 0xffde, | |
| 233 | − XK_F34: 0xffdf, | |
| 234 | − XK_R14: 0xffdf, | |
| 235 | − XK_F35: 0xffe0, | |
| 236 | − XK_R15: 0xffe0, | |
| 237 | − /* Modifiers */ | |
| 238 | − | |
| 239 | − XK_Shift_L: 0xffe1, | |
| 240 | − /* Left shift */ | |
| 241 | − XK_Shift_R: 0xffe2, | |
| 242 | − /* Right shift */ | |
| 243 | − XK_Control_L: 0xffe3, | |
| 244 | − /* Left control */ | |
| 245 | − XK_Control_R: 0xffe4, | |
| 246 | − /* Right control */ | |
| 247 | − XK_Caps_Lock: 0xffe5, | |
| 248 | − /* Caps lock */ | |
| 249 | − XK_Shift_Lock: 0xffe6, | |
| 250 | − /* Shift lock */ | |
| 251 | − | |
| 252 | − XK_Meta_L: 0xffe7, | |
| 253 | − /* Left meta */ | |
| 254 | − XK_Meta_R: 0xffe8, | |
| 255 | − /* Right meta */ | |
| 256 | − XK_Alt_L: 0xffe9, | |
| 257 | − /* Left alt */ | |
| 258 | − XK_Alt_R: 0xffea, | |
| 259 | − /* Right alt */ | |
| 260 | − XK_Super_L: 0xffeb, | |
| 261 | − /* Left super */ | |
| 262 | − XK_Super_R: 0xffec, | |
| 263 | − /* Right super */ | |
| 264 | − XK_Hyper_L: 0xffed, | |
| 265 | − /* Left hyper */ | |
| 266 | − XK_Hyper_R: 0xffee, | |
| 267 | − /* Right hyper */ | |
| 268 | − | |
| 269 | − /* | |
| 270 | − * Keyboard (XKB) Extension function and modifier keys | |
| 271 | − * (from Appendix C of "The X Keyboard Extension: Protocol Specification") | |
| 272 | − * Byte 3 = 0xfe | |
| 273 | − */ | |
| 274 | − | |
| 275 | − XK_ISO_Level3_Shift: 0xfe03, | |
| 276 | − /* AltGr */ | |
| 277 | − XK_ISO_Next_Group: 0xfe08, | |
| 278 | − XK_ISO_Prev_Group: 0xfe0a, | |
| 279 | − XK_ISO_First_Group: 0xfe0c, | |
| 280 | − XK_ISO_Last_Group: 0xfe0e, | |
| 281 | − /* | |
| 282 | − * Latin 1 | |
| 283 | − * (ISO/IEC 8859-1: Unicode U+0020..U+00FF) | |
| 284 | − * Byte 3: 0 | |
| 285 | − */ | |
| 286 | − | |
| 287 | − XK_space: 0x0020, | |
| 288 | − /* U+0020 SPACE */ | |
| 289 | − XK_exclam: 0x0021, | |
| 290 | − /* U+0021 EXCLAMATION MARK */ | |
| 291 | − XK_quotedbl: 0x0022, | |
| 292 | − /* U+0022 QUOTATION MARK */ | |
| 293 | − XK_numbersign: 0x0023, | |
| 294 | − /* U+0023 NUMBER SIGN */ | |
| 295 | − XK_dollar: 0x0024, | |
| 296 | − /* U+0024 DOLLAR SIGN */ | |
| 297 | − XK_percent: 0x0025, | |
| 298 | − /* U+0025 PERCENT SIGN */ | |
| 299 | − XK_ampersand: 0x0026, | |
| 300 | − /* U+0026 AMPERSAND */ | |
| 301 | − XK_apostrophe: 0x0027, | |
| 302 | − /* U+0027 APOSTROPHE */ | |
| 303 | − XK_quoteright: 0x0027, | |
| 304 | − /* deprecated */ | |
| 305 | − XK_parenleft: 0x0028, | |
| 306 | − /* U+0028 LEFT PARENTHESIS */ | |
| 307 | − XK_parenright: 0x0029, | |
| 308 | − /* U+0029 RIGHT PARENTHESIS */ | |
| 309 | − XK_asterisk: 0x002a, | |
| 310 | − /* U+002A ASTERISK */ | |
| 311 | − XK_plus: 0x002b, | |
| 312 | − /* U+002B PLUS SIGN */ | |
| 313 | − XK_comma: 0x002c, | |
| 314 | − /* U+002C COMMA */ | |
| 315 | − XK_minus: 0x002d, | |
| 316 | − /* U+002D HYPHEN-MINUS */ | |
| 317 | − XK_period: 0x002e, | |
| 318 | − /* U+002E FULL STOP */ | |
| 319 | − XK_slash: 0x002f, | |
| 320 | − /* U+002F SOLIDUS */ | |
| 321 | − XK_0: 0x0030, | |
| 322 | − /* U+0030 DIGIT ZERO */ | |
| 323 | − XK_1: 0x0031, | |
| 324 | − /* U+0031 DIGIT ONE */ | |
| 325 | − XK_2: 0x0032, | |
| 326 | − /* U+0032 DIGIT TWO */ | |
| 327 | − XK_3: 0x0033, | |
| 328 | − /* U+0033 DIGIT THREE */ | |
| 329 | − XK_4: 0x0034, | |
| 330 | − /* U+0034 DIGIT FOUR */ | |
| 331 | − XK_5: 0x0035, | |
| 332 | − /* U+0035 DIGIT FIVE */ | |
| 333 | − XK_6: 0x0036, | |
| 334 | − /* U+0036 DIGIT SIX */ | |
| 335 | − XK_7: 0x0037, | |
| 336 | − /* U+0037 DIGIT SEVEN */ | |
| 337 | − XK_8: 0x0038, | |
| 338 | − /* U+0038 DIGIT EIGHT */ | |
| 339 | − XK_9: 0x0039, | |
| 340 | − /* U+0039 DIGIT NINE */ | |
| 341 | − XK_colon: 0x003a, | |
| 342 | − /* U+003A COLON */ | |
| 343 | − XK_semicolon: 0x003b, | |
| 344 | − /* U+003B SEMICOLON */ | |
| 345 | − XK_less: 0x003c, | |
| 346 | − /* U+003C LESS-THAN SIGN */ | |
| 347 | − XK_equal: 0x003d, | |
| 348 | − /* U+003D EQUALS SIGN */ | |
| 349 | − XK_greater: 0x003e, | |
| 350 | − /* U+003E GREATER-THAN SIGN */ | |
| 351 | − XK_question: 0x003f, | |
| 352 | − /* U+003F QUESTION MARK */ | |
| 353 | − XK_at: 0x0040, | |
| 354 | − /* U+0040 COMMERCIAL AT */ | |
| 355 | − XK_A: 0x0041, | |
| 356 | − /* U+0041 LATIN CAPITAL LETTER A */ | |
| 357 | − XK_B: 0x0042, | |
| 358 | − /* U+0042 LATIN CAPITAL LETTER B */ | |
| 359 | − XK_C: 0x0043, | |
| 360 | − /* U+0043 LATIN CAPITAL LETTER C */ | |
| 361 | − XK_D: 0x0044, | |
| 362 | − /* U+0044 LATIN CAPITAL LETTER D */ | |
| 363 | − XK_E: 0x0045, | |
| 364 | − /* U+0045 LATIN CAPITAL LETTER E */ | |
| 365 | − XK_F: 0x0046, | |
| 366 | − /* U+0046 LATIN CAPITAL LETTER F */ | |
| 367 | − XK_G: 0x0047, | |
| 368 | − /* U+0047 LATIN CAPITAL LETTER G */ | |
| 369 | − XK_H: 0x0048, | |
| 370 | − /* U+0048 LATIN CAPITAL LETTER H */ | |
| 371 | − XK_I: 0x0049, | |
| 372 | − /* U+0049 LATIN CAPITAL LETTER I */ | |
| 373 | − XK_J: 0x004a, | |
| 374 | − /* U+004A LATIN CAPITAL LETTER J */ | |
| 375 | − XK_K: 0x004b, | |
| 376 | − /* U+004B LATIN CAPITAL LETTER K */ | |
| 377 | − XK_L: 0x004c, | |
| 378 | − /* U+004C LATIN CAPITAL LETTER L */ | |
| 379 | − XK_M: 0x004d, | |
| 380 | − /* U+004D LATIN CAPITAL LETTER M */ | |
| 381 | − XK_N: 0x004e, | |
| 382 | − /* U+004E LATIN CAPITAL LETTER N */ | |
| 383 | − XK_O: 0x004f, | |
| 384 | − /* U+004F LATIN CAPITAL LETTER O */ | |
| 385 | − XK_P: 0x0050, | |
| 386 | − /* U+0050 LATIN CAPITAL LETTER P */ | |
| 387 | − XK_Q: 0x0051, | |
| 388 | − /* U+0051 LATIN CAPITAL LETTER Q */ | |
| 389 | − XK_R: 0x0052, | |
| 390 | − /* U+0052 LATIN CAPITAL LETTER R */ | |
| 391 | − XK_S: 0x0053, | |
| 392 | − /* U+0053 LATIN CAPITAL LETTER S */ | |
| 393 | − XK_T: 0x0054, | |
| 394 | − /* U+0054 LATIN CAPITAL LETTER T */ | |
| 395 | − XK_U: 0x0055, | |
| 396 | − /* U+0055 LATIN CAPITAL LETTER U */ | |
| 397 | − XK_V: 0x0056, | |
| 398 | − /* U+0056 LATIN CAPITAL LETTER V */ | |
| 399 | − XK_W: 0x0057, | |
| 400 | − /* U+0057 LATIN CAPITAL LETTER W */ | |
| 401 | − XK_X: 0x0058, | |
| 402 | − /* U+0058 LATIN CAPITAL LETTER X */ | |
| 403 | − XK_Y: 0x0059, | |
| 404 | − /* U+0059 LATIN CAPITAL LETTER Y */ | |
| 405 | − XK_Z: 0x005a, | |
| 406 | − /* U+005A LATIN CAPITAL LETTER Z */ | |
| 407 | − XK_bracketleft: 0x005b, | |
| 408 | − /* U+005B LEFT SQUARE BRACKET */ | |
| 409 | − XK_backslash: 0x005c, | |
| 410 | − /* U+005C REVERSE SOLIDUS */ | |
| 411 | − XK_bracketright: 0x005d, | |
| 412 | − /* U+005D RIGHT SQUARE BRACKET */ | |
| 413 | − XK_asciicircum: 0x005e, | |
| 414 | − /* U+005E CIRCUMFLEX ACCENT */ | |
| 415 | − XK_underscore: 0x005f, | |
| 416 | − /* U+005F LOW LINE */ | |
| 417 | − XK_grave: 0x0060, | |
| 418 | − /* U+0060 GRAVE ACCENT */ | |
| 419 | − XK_quoteleft: 0x0060, | |
| 420 | − /* deprecated */ | |
| 421 | − XK_a: 0x0061, | |
| 422 | − /* U+0061 LATIN SMALL LETTER A */ | |
| 423 | − XK_b: 0x0062, | |
| 424 | − /* U+0062 LATIN SMALL LETTER B */ | |
| 425 | − XK_c: 0x0063, | |
| 426 | − /* U+0063 LATIN SMALL LETTER C */ | |
| 427 | − XK_d: 0x0064, | |
| 428 | − /* U+0064 LATIN SMALL LETTER D */ | |
| 429 | − XK_e: 0x0065, | |
| 430 | − /* U+0065 LATIN SMALL LETTER E */ | |
| 431 | − XK_f: 0x0066, | |
| 432 | − /* U+0066 LATIN SMALL LETTER F */ | |
| 433 | − XK_g: 0x0067, | |
| 434 | − /* U+0067 LATIN SMALL LETTER G */ | |
| 435 | − XK_h: 0x0068, | |
| 436 | − /* U+0068 LATIN SMALL LETTER H */ | |
| 437 | − XK_i: 0x0069, | |
| 438 | − /* U+0069 LATIN SMALL LETTER I */ | |
| 439 | − XK_j: 0x006a, | |
| 440 | − /* U+006A LATIN SMALL LETTER J */ | |
| 441 | − XK_k: 0x006b, | |
| 442 | − /* U+006B LATIN SMALL LETTER K */ | |
| 443 | − XK_l: 0x006c, | |
| 444 | − /* U+006C LATIN SMALL LETTER L */ | |
| 445 | − XK_m: 0x006d, | |
| 446 | − /* U+006D LATIN SMALL LETTER M */ | |
| 447 | − XK_n: 0x006e, | |
| 448 | − /* U+006E LATIN SMALL LETTER N */ | |
| 449 | − XK_o: 0x006f, | |
| 450 | − /* U+006F LATIN SMALL LETTER O */ | |
| 451 | − XK_p: 0x0070, | |
| 452 | − /* U+0070 LATIN SMALL LETTER P */ | |
| 453 | − XK_q: 0x0071, | |
| 454 | − /* U+0071 LATIN SMALL LETTER Q */ | |
| 455 | − XK_r: 0x0072, | |
| 456 | − /* U+0072 LATIN SMALL LETTER R */ | |
| 457 | − XK_s: 0x0073, | |
| 458 | − /* U+0073 LATIN SMALL LETTER S */ | |
| 459 | − XK_t: 0x0074, | |
| 460 | − /* U+0074 LATIN SMALL LETTER T */ | |
| 461 | − XK_u: 0x0075, | |
| 462 | − /* U+0075 LATIN SMALL LETTER U */ | |
| 463 | − XK_v: 0x0076, | |
| 464 | − /* U+0076 LATIN SMALL LETTER V */ | |
| 465 | − XK_w: 0x0077, | |
| 466 | − /* U+0077 LATIN SMALL LETTER W */ | |
| 467 | − XK_x: 0x0078, | |
| 468 | − /* U+0078 LATIN SMALL LETTER X */ | |
| 469 | − XK_y: 0x0079, | |
| 470 | − /* U+0079 LATIN SMALL LETTER Y */ | |
| 471 | − XK_z: 0x007a, | |
| 472 | − /* U+007A LATIN SMALL LETTER Z */ | |
| 473 | − XK_braceleft: 0x007b, | |
| 474 | − /* U+007B LEFT CURLY BRACKET */ | |
| 475 | − XK_bar: 0x007c, | |
| 476 | − /* U+007C VERTICAL LINE */ | |
| 477 | − XK_braceright: 0x007d, | |
| 478 | − /* U+007D RIGHT CURLY BRACKET */ | |
| 479 | − XK_asciitilde: 0x007e, | |
| 480 | − /* U+007E TILDE */ | |
| 481 | − | |
| 482 | − XK_nobreakspace: 0x00a0, | |
| 483 | − /* U+00A0 NO-BREAK SPACE */ | |
| 484 | − XK_exclamdown: 0x00a1, | |
| 485 | − /* U+00A1 INVERTED EXCLAMATION MARK */ | |
| 486 | − XK_cent: 0x00a2, | |
| 487 | − /* U+00A2 CENT SIGN */ | |
| 488 | − XK_sterling: 0x00a3, | |
| 489 | − /* U+00A3 POUND SIGN */ | |
| 490 | − XK_currency: 0x00a4, | |
| 491 | − /* U+00A4 CURRENCY SIGN */ | |
| 492 | − XK_yen: 0x00a5, | |
| 493 | − /* U+00A5 YEN SIGN */ | |
| 494 | − XK_brokenbar: 0x00a6, | |
| 495 | − /* U+00A6 BROKEN BAR */ | |
| 496 | − XK_section: 0x00a7, | |
| 497 | − /* U+00A7 SECTION SIGN */ | |
| 498 | − XK_diaeresis: 0x00a8, | |
| 499 | − /* U+00A8 DIAERESIS */ | |
| 500 | − XK_copyright: 0x00a9, | |
| 501 | − /* U+00A9 COPYRIGHT SIGN */ | |
| 502 | − XK_ordfeminine: 0x00aa, | |
| 503 | − /* U+00AA FEMININE ORDINAL INDICATOR */ | |
| 504 | − XK_guillemotleft: 0x00ab, | |
| 505 | − /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ | |
| 506 | − XK_notsign: 0x00ac, | |
| 507 | − /* U+00AC NOT SIGN */ | |
| 508 | − XK_hyphen: 0x00ad, | |
| 509 | − /* U+00AD SOFT HYPHEN */ | |
| 510 | − XK_registered: 0x00ae, | |
| 511 | − /* U+00AE REGISTERED SIGN */ | |
| 512 | − XK_macron: 0x00af, | |
| 513 | − /* U+00AF MACRON */ | |
| 514 | − XK_degree: 0x00b0, | |
| 515 | − /* U+00B0 DEGREE SIGN */ | |
| 516 | − XK_plusminus: 0x00b1, | |
| 517 | − /* U+00B1 PLUS-MINUS SIGN */ | |
| 518 | − XK_twosuperior: 0x00b2, | |
| 519 | − /* U+00B2 SUPERSCRIPT TWO */ | |
| 520 | − XK_threesuperior: 0x00b3, | |
| 521 | − /* U+00B3 SUPERSCRIPT THREE */ | |
| 522 | − XK_acute: 0x00b4, | |
| 523 | − /* U+00B4 ACUTE ACCENT */ | |
| 524 | − XK_mu: 0x00b5, | |
| 525 | − /* U+00B5 MICRO SIGN */ | |
| 526 | − XK_paragraph: 0x00b6, | |
| 527 | − /* U+00B6 PILCROW SIGN */ | |
| 528 | − XK_periodcentered: 0x00b7, | |
| 529 | − /* U+00B7 MIDDLE DOT */ | |
| 530 | − XK_cedilla: 0x00b8, | |
| 531 | − /* U+00B8 CEDILLA */ | |
| 532 | − XK_onesuperior: 0x00b9, | |
| 533 | − /* U+00B9 SUPERSCRIPT ONE */ | |
| 534 | − XK_masculine: 0x00ba, | |
| 535 | − /* U+00BA MASCULINE ORDINAL INDICATOR */ | |
| 536 | − XK_guillemotright: 0x00bb, | |
| 537 | − /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ | |
| 538 | − XK_onequarter: 0x00bc, | |
| 539 | − /* U+00BC VULGAR FRACTION ONE QUARTER */ | |
| 540 | − XK_onehalf: 0x00bd, | |
| 541 | − /* U+00BD VULGAR FRACTION ONE HALF */ | |
| 542 | − XK_threequarters: 0x00be, | |
| 543 | − /* U+00BE VULGAR FRACTION THREE QUARTERS */ | |
| 544 | − XK_questiondown: 0x00bf, | |
| 545 | − /* U+00BF INVERTED QUESTION MARK */ | |
| 546 | − XK_Agrave: 0x00c0, | |
| 547 | − /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ | |
| 548 | − XK_Aacute: 0x00c1, | |
| 549 | − /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ | |
| 550 | − XK_Acircumflex: 0x00c2, | |
| 551 | − /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ | |
| 552 | − XK_Atilde: 0x00c3, | |
| 553 | − /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ | |
| 554 | − XK_Adiaeresis: 0x00c4, | |
| 555 | − /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ | |
| 556 | − XK_Aring: 0x00c5, | |
| 557 | − /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ | |
| 558 | − XK_AE: 0x00c6, | |
| 559 | − /* U+00C6 LATIN CAPITAL LETTER AE */ | |
| 560 | − XK_Ccedilla: 0x00c7, | |
| 561 | − /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ | |
| 562 | − XK_Egrave: 0x00c8, | |
| 563 | − /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ | |
| 564 | − XK_Eacute: 0x00c9, | |
| 565 | − /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ | |
| 566 | − XK_Ecircumflex: 0x00ca, | |
| 567 | − /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ | |
| 568 | − XK_Ediaeresis: 0x00cb, | |
| 569 | − /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ | |
| 570 | − XK_Igrave: 0x00cc, | |
| 571 | − /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ | |
| 572 | − XK_Iacute: 0x00cd, | |
| 573 | − /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ | |
| 574 | − XK_Icircumflex: 0x00ce, | |
| 575 | − /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ | |
| 576 | − XK_Idiaeresis: 0x00cf, | |
| 577 | − /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ | |
| 578 | − XK_ETH: 0x00d0, | |
| 579 | − /* U+00D0 LATIN CAPITAL LETTER ETH */ | |
| 580 | − XK_Eth: 0x00d0, | |
| 581 | − /* deprecated */ | |
| 582 | − XK_Ntilde: 0x00d1, | |
| 583 | − /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ | |
| 584 | − XK_Ograve: 0x00d2, | |
| 585 | − /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ | |
| 586 | − XK_Oacute: 0x00d3, | |
| 587 | − /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ | |
| 588 | − XK_Ocircumflex: 0x00d4, | |
| 589 | − /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ | |
| 590 | − XK_Otilde: 0x00d5, | |
| 591 | − /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ | |
| 592 | − XK_Odiaeresis: 0x00d6, | |
| 593 | − /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ | |
| 594 | − XK_multiply: 0x00d7, | |
| 595 | − /* U+00D7 MULTIPLICATION SIGN */ | |
| 596 | − XK_Oslash: 0x00d8, | |
| 597 | − /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ | |
| 598 | − XK_Ooblique: 0x00d8, | |
| 599 | − /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ | |
| 600 | − XK_Ugrave: 0x00d9, | |
| 601 | − /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ | |
| 602 | − XK_Uacute: 0x00da, | |
| 603 | − /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ | |
| 604 | − XK_Ucircumflex: 0x00db, | |
| 605 | − /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ | |
| 606 | − XK_Udiaeresis: 0x00dc, | |
| 607 | − /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ | |
| 608 | − XK_Yacute: 0x00dd, | |
| 609 | − /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ | |
| 610 | − XK_THORN: 0x00de, | |
| 611 | − /* U+00DE LATIN CAPITAL LETTER THORN */ | |
| 612 | − XK_Thorn: 0x00de, | |
| 613 | − /* deprecated */ | |
| 614 | − XK_ssharp: 0x00df, | |
| 615 | − /* U+00DF LATIN SMALL LETTER SHARP S */ | |
| 616 | − XK_agrave: 0x00e0, | |
| 617 | − /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ | |
| 618 | − XK_aacute: 0x00e1, | |
| 619 | − /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ | |
| 620 | − XK_acircumflex: 0x00e2, | |
| 621 | − /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ | |
| 622 | − XK_atilde: 0x00e3, | |
| 623 | − /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ | |
| 624 | − XK_adiaeresis: 0x00e4, | |
| 625 | − /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ | |
| 626 | − XK_aring: 0x00e5, | |
| 627 | − /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ | |
| 628 | − XK_ae: 0x00e6, | |
| 629 | − /* U+00E6 LATIN SMALL LETTER AE */ | |
| 630 | − XK_ccedilla: 0x00e7, | |
| 631 | − /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ | |
| 632 | − XK_egrave: 0x00e8, | |
| 633 | − /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ | |
| 634 | − XK_eacute: 0x00e9, | |
| 635 | − /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ | |
| 636 | − XK_ecircumflex: 0x00ea, | |
| 637 | − /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ | |
| 638 | − XK_ediaeresis: 0x00eb, | |
| 639 | − /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ | |
| 640 | − XK_igrave: 0x00ec, | |
| 641 | − /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ | |
| 642 | − XK_iacute: 0x00ed, | |
| 643 | − /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ | |
| 644 | − XK_icircumflex: 0x00ee, | |
| 645 | − /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ | |
| 646 | − XK_idiaeresis: 0x00ef, | |
| 647 | − /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ | |
| 648 | − XK_eth: 0x00f0, | |
| 649 | − /* U+00F0 LATIN SMALL LETTER ETH */ | |
| 650 | − XK_ntilde: 0x00f1, | |
| 651 | − /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ | |
| 652 | − XK_ograve: 0x00f2, | |
| 653 | − /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ | |
| 654 | − XK_oacute: 0x00f3, | |
| 655 | − /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ | |
| 656 | − XK_ocircumflex: 0x00f4, | |
| 657 | − /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ | |
| 658 | − XK_otilde: 0x00f5, | |
| 659 | − /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ | |
| 660 | − XK_odiaeresis: 0x00f6, | |
| 661 | − /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ | |
| 662 | − XK_division: 0x00f7, | |
| 663 | − /* U+00F7 DIVISION SIGN */ | |
| 664 | − XK_oslash: 0x00f8, | |
| 665 | − /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ | |
| 666 | − XK_ooblique: 0x00f8, | |
| 667 | − /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ | |
| 668 | − XK_ugrave: 0x00f9, | |
| 669 | − /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ | |
| 670 | − XK_uacute: 0x00fa, | |
| 671 | − /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ | |
| 672 | − XK_ucircumflex: 0x00fb, | |
| 673 | − /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ | |
| 674 | − XK_udiaeresis: 0x00fc, | |
| 675 | − /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ | |
| 676 | − XK_yacute: 0x00fd, | |
| 677 | − /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ | |
| 678 | − XK_thorn: 0x00fe, | |
| 679 | − /* U+00FE LATIN SMALL LETTER THORN */ | |
| 680 | − XK_ydiaeresis: 0x00ff, | |
| 681 | − /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ | |
| 682 | − | |
| 683 | − /* | |
| 684 | − * Korean | |
| 685 | − * Byte 3 = 0x0e | |
| 686 | − */ | |
| 687 | − | |
| 688 | − XK_Hangul: 0xff31, | |
| 689 | − /* Hangul start/stop(toggle) */ | |
| 690 | − XK_Hangul_Hanja: 0xff34, | |
| 691 | − /* Start Hangul->Hanja Conversion */ | |
| 692 | − XK_Hangul_Jeonja: 0xff38, | |
| 693 | − /* Jeonja mode */ | |
| 694 | − | |
| 695 | − /* | |
| 696 | − * XFree86 vendor specific keysyms. | |
| 697 | − * | |
| 698 | − * The XFree86 keysym range is 0x10080001 - 0x1008FFFF. | |
| 699 | − */ | |
| 700 | − | |
| 701 | − XF86XK_ModeLock: 0x1008FF01, | |
| 702 | − XF86XK_MonBrightnessUp: 0x1008FF02, | |
| 703 | − XF86XK_MonBrightnessDown: 0x1008FF03, | |
| 704 | − XF86XK_KbdLightOnOff: 0x1008FF04, | |
| 705 | − XF86XK_KbdBrightnessUp: 0x1008FF05, | |
| 706 | − XF86XK_KbdBrightnessDown: 0x1008FF06, | |
| 707 | − XF86XK_Standby: 0x1008FF10, | |
| 708 | − XF86XK_AudioLowerVolume: 0x1008FF11, | |
| 709 | − XF86XK_AudioMute: 0x1008FF12, | |
| 710 | − XF86XK_AudioRaiseVolume: 0x1008FF13, | |
| 711 | − XF86XK_AudioPlay: 0x1008FF14, | |
| 712 | − XF86XK_AudioStop: 0x1008FF15, | |
| 713 | − XF86XK_AudioPrev: 0x1008FF16, | |
| 714 | − XF86XK_AudioNext: 0x1008FF17, | |
| 715 | − XF86XK_HomePage: 0x1008FF18, | |
| 716 | − XF86XK_Mail: 0x1008FF19, | |
| 717 | − XF86XK_Start: 0x1008FF1A, | |
| 718 | − XF86XK_Search: 0x1008FF1B, | |
| 719 | − XF86XK_AudioRecord: 0x1008FF1C, | |
| 720 | − XF86XK_Calculator: 0x1008FF1D, | |
| 721 | − XF86XK_Memo: 0x1008FF1E, | |
| 722 | − XF86XK_ToDoList: 0x1008FF1F, | |
| 723 | − XF86XK_Calendar: 0x1008FF20, | |
| 724 | − XF86XK_PowerDown: 0x1008FF21, | |
| 725 | − XF86XK_ContrastAdjust: 0x1008FF22, | |
| 726 | − XF86XK_RockerUp: 0x1008FF23, | |
| 727 | − XF86XK_RockerDown: 0x1008FF24, | |
| 728 | − XF86XK_RockerEnter: 0x1008FF25, | |
| 729 | − XF86XK_Back: 0x1008FF26, | |
| 730 | − XF86XK_Forward: 0x1008FF27, | |
| 731 | − XF86XK_Stop: 0x1008FF28, | |
| 732 | − XF86XK_Refresh: 0x1008FF29, | |
| 733 | − XF86XK_PowerOff: 0x1008FF2A, | |
| 734 | − XF86XK_WakeUp: 0x1008FF2B, | |
| 735 | − XF86XK_Eject: 0x1008FF2C, | |
| 736 | − XF86XK_ScreenSaver: 0x1008FF2D, | |
| 737 | − XF86XK_WWW: 0x1008FF2E, | |
| 738 | − XF86XK_Sleep: 0x1008FF2F, | |
| 739 | − XF86XK_Favorites: 0x1008FF30, | |
| 740 | − XF86XK_AudioPause: 0x1008FF31, | |
| 741 | − XF86XK_AudioMedia: 0x1008FF32, | |
| 742 | − XF86XK_MyComputer: 0x1008FF33, | |
| 743 | − XF86XK_VendorHome: 0x1008FF34, | |
| 744 | − XF86XK_LightBulb: 0x1008FF35, | |
| 745 | − XF86XK_Shop: 0x1008FF36, | |
| 746 | − XF86XK_History: 0x1008FF37, | |
| 747 | − XF86XK_OpenURL: 0x1008FF38, | |
| 748 | − XF86XK_AddFavorite: 0x1008FF39, | |
| 749 | − XF86XK_HotLinks: 0x1008FF3A, | |
| 750 | − XF86XK_BrightnessAdjust: 0x1008FF3B, | |
| 751 | − XF86XK_Finance: 0x1008FF3C, | |
| 752 | − XF86XK_Community: 0x1008FF3D, | |
| 753 | − XF86XK_AudioRewind: 0x1008FF3E, | |
| 754 | − XF86XK_BackForward: 0x1008FF3F, | |
| 755 | − XF86XK_Launch0: 0x1008FF40, | |
| 756 | − XF86XK_Launch1: 0x1008FF41, | |
| 757 | − XF86XK_Launch2: 0x1008FF42, | |
| 758 | − XF86XK_Launch3: 0x1008FF43, | |
| 759 | − XF86XK_Launch4: 0x1008FF44, | |
| 760 | − XF86XK_Launch5: 0x1008FF45, | |
| 761 | − XF86XK_Launch6: 0x1008FF46, | |
| 762 | − XF86XK_Launch7: 0x1008FF47, | |
| 763 | − XF86XK_Launch8: 0x1008FF48, | |
| 764 | − XF86XK_Launch9: 0x1008FF49, | |
| 765 | − XF86XK_LaunchA: 0x1008FF4A, | |
| 766 | − XF86XK_LaunchB: 0x1008FF4B, | |
| 767 | − XF86XK_LaunchC: 0x1008FF4C, | |
| 768 | − XF86XK_LaunchD: 0x1008FF4D, | |
| 769 | − XF86XK_LaunchE: 0x1008FF4E, | |
| 770 | − XF86XK_LaunchF: 0x1008FF4F, | |
| 771 | − XF86XK_ApplicationLeft: 0x1008FF50, | |
| 772 | − XF86XK_ApplicationRight: 0x1008FF51, | |
| 773 | − XF86XK_Book: 0x1008FF52, | |
| 774 | − XF86XK_CD: 0x1008FF53, | |
| 775 | − XF86XK_Calculater: 0x1008FF54, | |
| 776 | − XF86XK_Clear: 0x1008FF55, | |
| 777 | − XF86XK_Close: 0x1008FF56, | |
| 778 | − XF86XK_Copy: 0x1008FF57, | |
| 779 | − XF86XK_Cut: 0x1008FF58, | |
| 780 | − XF86XK_Display: 0x1008FF59, | |
| 781 | − XF86XK_DOS: 0x1008FF5A, | |
| 782 | − XF86XK_Documents: 0x1008FF5B, | |
| 783 | − XF86XK_Excel: 0x1008FF5C, | |
| 784 | − XF86XK_Explorer: 0x1008FF5D, | |
| 785 | − XF86XK_Game: 0x1008FF5E, | |
| 786 | − XF86XK_Go: 0x1008FF5F, | |
| 787 | − XF86XK_iTouch: 0x1008FF60, | |
| 788 | − XF86XK_LogOff: 0x1008FF61, | |
| 789 | − XF86XK_Market: 0x1008FF62, | |
| 790 | − XF86XK_Meeting: 0x1008FF63, | |
| 791 | − XF86XK_MenuKB: 0x1008FF65, | |
| 792 | − XF86XK_MenuPB: 0x1008FF66, | |
| 793 | − XF86XK_MySites: 0x1008FF67, | |
| 794 | − XF86XK_New: 0x1008FF68, | |
| 795 | − XF86XK_News: 0x1008FF69, | |
| 796 | − XF86XK_OfficeHome: 0x1008FF6A, | |
| 797 | − XF86XK_Open: 0x1008FF6B, | |
| 798 | − XF86XK_Option: 0x1008FF6C, | |
| 799 | − XF86XK_Paste: 0x1008FF6D, | |
| 800 | − XF86XK_Phone: 0x1008FF6E, | |
| 801 | − XF86XK_Q: 0x1008FF70, | |
| 802 | − XF86XK_Reply: 0x1008FF72, | |
| 803 | − XF86XK_Reload: 0x1008FF73, | |
| 804 | − XF86XK_RotateWindows: 0x1008FF74, | |
| 805 | − XF86XK_RotationPB: 0x1008FF75, | |
| 806 | − XF86XK_RotationKB: 0x1008FF76, | |
| 807 | − XF86XK_Save: 0x1008FF77, | |
| 808 | − XF86XK_ScrollUp: 0x1008FF78, | |
| 809 | − XF86XK_ScrollDown: 0x1008FF79, | |
| 810 | − XF86XK_ScrollClick: 0x1008FF7A, | |
| 811 | − XF86XK_Send: 0x1008FF7B, | |
| 812 | − XF86XK_Spell: 0x1008FF7C, | |
| 813 | − XF86XK_SplitScreen: 0x1008FF7D, | |
| 814 | − XF86XK_Support: 0x1008FF7E, | |
| 815 | − XF86XK_TaskPane: 0x1008FF7F, | |
| 816 | − XF86XK_Terminal: 0x1008FF80, | |
| 817 | − XF86XK_Tools: 0x1008FF81, | |
| 818 | − XF86XK_Travel: 0x1008FF82, | |
| 819 | − XF86XK_UserPB: 0x1008FF84, | |
| 820 | − XF86XK_User1KB: 0x1008FF85, | |
| 821 | − XF86XK_User2KB: 0x1008FF86, | |
| 822 | − XF86XK_Video: 0x1008FF87, | |
| 823 | − XF86XK_WheelButton: 0x1008FF88, | |
| 824 | − XF86XK_Word: 0x1008FF89, | |
| 825 | − XF86XK_Xfer: 0x1008FF8A, | |
| 826 | − XF86XK_ZoomIn: 0x1008FF8B, | |
| 827 | − XF86XK_ZoomOut: 0x1008FF8C, | |
| 828 | − XF86XK_Away: 0x1008FF8D, | |
| 829 | − XF86XK_Messenger: 0x1008FF8E, | |
| 830 | − XF86XK_WebCam: 0x1008FF8F, | |
| 831 | − XF86XK_MailForward: 0x1008FF90, | |
| 832 | − XF86XK_Pictures: 0x1008FF91, | |
| 833 | − XF86XK_Music: 0x1008FF92, | |
| 834 | − XF86XK_Battery: 0x1008FF93, | |
| 835 | − XF86XK_Bluetooth: 0x1008FF94, | |
| 836 | − XF86XK_WLAN: 0x1008FF95, | |
| 837 | − XF86XK_UWB: 0x1008FF96, | |
| 838 | − XF86XK_AudioForward: 0x1008FF97, | |
| 839 | − XF86XK_AudioRepeat: 0x1008FF98, | |
| 840 | − XF86XK_AudioRandomPlay: 0x1008FF99, | |
| 841 | − XF86XK_Subtitle: 0x1008FF9A, | |
| 842 | − XF86XK_AudioCycleTrack: 0x1008FF9B, | |
| 843 | − XF86XK_CycleAngle: 0x1008FF9C, | |
| 844 | − XF86XK_FrameBack: 0x1008FF9D, | |
| 845 | − XF86XK_FrameForward: 0x1008FF9E, | |
| 846 | − XF86XK_Time: 0x1008FF9F, | |
| 847 | − XF86XK_Select: 0x1008FFA0, | |
| 848 | − XF86XK_View: 0x1008FFA1, | |
| 849 | − XF86XK_TopMenu: 0x1008FFA2, | |
| 850 | − XF86XK_Red: 0x1008FFA3, | |
| 851 | − XF86XK_Green: 0x1008FFA4, | |
| 852 | − XF86XK_Yellow: 0x1008FFA5, | |
| 853 | − XF86XK_Blue: 0x1008FFA6, | |
| 854 | − XF86XK_Suspend: 0x1008FFA7, | |
| 855 | − XF86XK_Hibernate: 0x1008FFA8, | |
| 856 | − XF86XK_TouchpadToggle: 0x1008FFA9, | |
| 857 | − XF86XK_TouchpadOn: 0x1008FFB0, | |
| 858 | − XF86XK_TouchpadOff: 0x1008FFB1, | |
| 859 | − XF86XK_AudioMicMute: 0x1008FFB2, | |
| 860 | − XF86XK_Switch_VT_1: 0x1008FE01, | |
| 861 | − XF86XK_Switch_VT_2: 0x1008FE02, | |
| 862 | − XF86XK_Switch_VT_3: 0x1008FE03, | |
| 863 | − XF86XK_Switch_VT_4: 0x1008FE04, | |
| 864 | − XF86XK_Switch_VT_5: 0x1008FE05, | |
| 865 | − XF86XK_Switch_VT_6: 0x1008FE06, | |
| 866 | − XF86XK_Switch_VT_7: 0x1008FE07, | |
| 867 | − XF86XK_Switch_VT_8: 0x1008FE08, | |
| 868 | − XF86XK_Switch_VT_9: 0x1008FE09, | |
| 869 | − XF86XK_Switch_VT_10: 0x1008FE0A, | |
| 870 | − XF86XK_Switch_VT_11: 0x1008FE0B, | |
| 871 | − XF86XK_Switch_VT_12: 0x1008FE0C, | |
| 872 | − XF86XK_Ungrab: 0x1008FE20, | |
| 873 | − XF86XK_ClearGrab: 0x1008FE21, | |
| 874 | − XF86XK_Next_VMode: 0x1008FE22, | |
| 875 | − XF86XK_Prev_VMode: 0x1008FE23, | |
| 876 | − XF86XK_LogWindowTree: 0x1008FE24, | |
| 877 | − XF86XK_LogGrabInfo: 0x1008FE25 | |
| 878 | −}; | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/input/keysymdef.js
+0 −1351
@@ -1,1351 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −/* | |
| 8 | − * Mapping from Unicode codepoints to X11/RFB keysyms | |
| 9 | − * | |
| 10 | − * This file was automatically generated from keysymdef.h | |
| 11 | − * DO NOT EDIT! | |
| 12 | − */ | |
| 13 | − | |
| 14 | −/* Functions at the bottom */ | |
| 15 | − | |
| 16 | −var codepoints = { | |
| 17 | − 0x0100: 0x03c0, | |
| 18 | − // XK_Amacron | |
| 19 | − 0x0101: 0x03e0, | |
| 20 | − // XK_amacron | |
| 21 | − 0x0102: 0x01c3, | |
| 22 | − // XK_Abreve | |
| 23 | − 0x0103: 0x01e3, | |
| 24 | − // XK_abreve | |
| 25 | − 0x0104: 0x01a1, | |
| 26 | − // XK_Aogonek | |
| 27 | − 0x0105: 0x01b1, | |
| 28 | − // XK_aogonek | |
| 29 | − 0x0106: 0x01c6, | |
| 30 | − // XK_Cacute | |
| 31 | − 0x0107: 0x01e6, | |
| 32 | − // XK_cacute | |
| 33 | − 0x0108: 0x02c6, | |
| 34 | − // XK_Ccircumflex | |
| 35 | − 0x0109: 0x02e6, | |
| 36 | − // XK_ccircumflex | |
| 37 | − 0x010a: 0x02c5, | |
| 38 | − // XK_Cabovedot | |
| 39 | − 0x010b: 0x02e5, | |
| 40 | − // XK_cabovedot | |
| 41 | − 0x010c: 0x01c8, | |
| 42 | − // XK_Ccaron | |
| 43 | − 0x010d: 0x01e8, | |
| 44 | − // XK_ccaron | |
| 45 | − 0x010e: 0x01cf, | |
| 46 | − // XK_Dcaron | |
| 47 | − 0x010f: 0x01ef, | |
| 48 | − // XK_dcaron | |
| 49 | − 0x0110: 0x01d0, | |
| 50 | − // XK_Dstroke | |
| 51 | − 0x0111: 0x01f0, | |
| 52 | − // XK_dstroke | |
| 53 | − 0x0112: 0x03aa, | |
| 54 | − // XK_Emacron | |
| 55 | − 0x0113: 0x03ba, | |
| 56 | − // XK_emacron | |
| 57 | − 0x0116: 0x03cc, | |
| 58 | − // XK_Eabovedot | |
| 59 | − 0x0117: 0x03ec, | |
| 60 | − // XK_eabovedot | |
| 61 | − 0x0118: 0x01ca, | |
| 62 | − // XK_Eogonek | |
| 63 | − 0x0119: 0x01ea, | |
| 64 | − // XK_eogonek | |
| 65 | − 0x011a: 0x01cc, | |
| 66 | − // XK_Ecaron | |
| 67 | − 0x011b: 0x01ec, | |
| 68 | − // XK_ecaron | |
| 69 | − 0x011c: 0x02d8, | |
| 70 | − // XK_Gcircumflex | |
| 71 | − 0x011d: 0x02f8, | |
| 72 | − // XK_gcircumflex | |
| 73 | − 0x011e: 0x02ab, | |
| 74 | − // XK_Gbreve | |
| 75 | − 0x011f: 0x02bb, | |
| 76 | − // XK_gbreve | |
| 77 | − 0x0120: 0x02d5, | |
| 78 | − // XK_Gabovedot | |
| 79 | − 0x0121: 0x02f5, | |
| 80 | − // XK_gabovedot | |
| 81 | − 0x0122: 0x03ab, | |
| 82 | − // XK_Gcedilla | |
| 83 | − 0x0123: 0x03bb, | |
| 84 | − // XK_gcedilla | |
| 85 | − 0x0124: 0x02a6, | |
| 86 | − // XK_Hcircumflex | |
| 87 | − 0x0125: 0x02b6, | |
| 88 | − // XK_hcircumflex | |
| 89 | − 0x0126: 0x02a1, | |
| 90 | − // XK_Hstroke | |
| 91 | − 0x0127: 0x02b1, | |
| 92 | − // XK_hstroke | |
| 93 | − 0x0128: 0x03a5, | |
| 94 | − // XK_Itilde | |
| 95 | − 0x0129: 0x03b5, | |
| 96 | − // XK_itilde | |
| 97 | − 0x012a: 0x03cf, | |
| 98 | − // XK_Imacron | |
| 99 | − 0x012b: 0x03ef, | |
| 100 | − // XK_imacron | |
| 101 | − 0x012e: 0x03c7, | |
| 102 | − // XK_Iogonek | |
| 103 | − 0x012f: 0x03e7, | |
| 104 | − // XK_iogonek | |
| 105 | − 0x0130: 0x02a9, | |
| 106 | − // XK_Iabovedot | |
| 107 | − 0x0131: 0x02b9, | |
| 108 | − // XK_idotless | |
| 109 | − 0x0134: 0x02ac, | |
| 110 | − // XK_Jcircumflex | |
| 111 | − 0x0135: 0x02bc, | |
| 112 | − // XK_jcircumflex | |
| 113 | − 0x0136: 0x03d3, | |
| 114 | − // XK_Kcedilla | |
| 115 | − 0x0137: 0x03f3, | |
| 116 | − // XK_kcedilla | |
| 117 | − 0x0138: 0x03a2, | |
| 118 | − // XK_kra | |
| 119 | − 0x0139: 0x01c5, | |
| 120 | − // XK_Lacute | |
| 121 | − 0x013a: 0x01e5, | |
| 122 | − // XK_lacute | |
| 123 | − 0x013b: 0x03a6, | |
| 124 | − // XK_Lcedilla | |
| 125 | − 0x013c: 0x03b6, | |
| 126 | − // XK_lcedilla | |
| 127 | − 0x013d: 0x01a5, | |
| 128 | − // XK_Lcaron | |
| 129 | − 0x013e: 0x01b5, | |
| 130 | − // XK_lcaron | |
| 131 | − 0x0141: 0x01a3, | |
| 132 | − // XK_Lstroke | |
| 133 | − 0x0142: 0x01b3, | |
| 134 | − // XK_lstroke | |
| 135 | − 0x0143: 0x01d1, | |
| 136 | − // XK_Nacute | |
| 137 | − 0x0144: 0x01f1, | |
| 138 | − // XK_nacute | |
| 139 | − 0x0145: 0x03d1, | |
| 140 | − // XK_Ncedilla | |
| 141 | − 0x0146: 0x03f1, | |
| 142 | − // XK_ncedilla | |
| 143 | − 0x0147: 0x01d2, | |
| 144 | − // XK_Ncaron | |
| 145 | − 0x0148: 0x01f2, | |
| 146 | − // XK_ncaron | |
| 147 | − 0x014a: 0x03bd, | |
| 148 | − // XK_ENG | |
| 149 | − 0x014b: 0x03bf, | |
| 150 | − // XK_eng | |
| 151 | − 0x014c: 0x03d2, | |
| 152 | − // XK_Omacron | |
| 153 | − 0x014d: 0x03f2, | |
| 154 | − // XK_omacron | |
| 155 | − 0x0150: 0x01d5, | |
| 156 | − // XK_Odoubleacute | |
| 157 | − 0x0151: 0x01f5, | |
| 158 | − // XK_odoubleacute | |
| 159 | − 0x0152: 0x13bc, | |
| 160 | − // XK_OE | |
| 161 | − 0x0153: 0x13bd, | |
| 162 | − // XK_oe | |
| 163 | − 0x0154: 0x01c0, | |
| 164 | − // XK_Racute | |
| 165 | − 0x0155: 0x01e0, | |
| 166 | − // XK_racute | |
| 167 | − 0x0156: 0x03a3, | |
| 168 | − // XK_Rcedilla | |
| 169 | − 0x0157: 0x03b3, | |
| 170 | − // XK_rcedilla | |
| 171 | − 0x0158: 0x01d8, | |
| 172 | − // XK_Rcaron | |
| 173 | − 0x0159: 0x01f8, | |
| 174 | − // XK_rcaron | |
| 175 | − 0x015a: 0x01a6, | |
| 176 | − // XK_Sacute | |
| 177 | − 0x015b: 0x01b6, | |
| 178 | − // XK_sacute | |
| 179 | − 0x015c: 0x02de, | |
| 180 | − // XK_Scircumflex | |
| 181 | − 0x015d: 0x02fe, | |
| 182 | − // XK_scircumflex | |
| 183 | − 0x015e: 0x01aa, | |
| 184 | − // XK_Scedilla | |
| 185 | − 0x015f: 0x01ba, | |
| 186 | − // XK_scedilla | |
| 187 | − 0x0160: 0x01a9, | |
| 188 | − // XK_Scaron | |
| 189 | − 0x0161: 0x01b9, | |
| 190 | − // XK_scaron | |
| 191 | − 0x0162: 0x01de, | |
| 192 | − // XK_Tcedilla | |
| 193 | − 0x0163: 0x01fe, | |
| 194 | − // XK_tcedilla | |
| 195 | − 0x0164: 0x01ab, | |
| 196 | − // XK_Tcaron | |
| 197 | − 0x0165: 0x01bb, | |
| 198 | − // XK_tcaron | |
| 199 | − 0x0166: 0x03ac, | |
| 200 | − // XK_Tslash | |
| 201 | − 0x0167: 0x03bc, | |
| 202 | − // XK_tslash | |
| 203 | − 0x0168: 0x03dd, | |
| 204 | − // XK_Utilde | |
| 205 | − 0x0169: 0x03fd, | |
| 206 | − // XK_utilde | |
| 207 | − 0x016a: 0x03de, | |
| 208 | − // XK_Umacron | |
| 209 | − 0x016b: 0x03fe, | |
| 210 | − // XK_umacron | |
| 211 | − 0x016c: 0x02dd, | |
| 212 | − // XK_Ubreve | |
| 213 | − 0x016d: 0x02fd, | |
| 214 | − // XK_ubreve | |
| 215 | − 0x016e: 0x01d9, | |
| 216 | − // XK_Uring | |
| 217 | − 0x016f: 0x01f9, | |
| 218 | − // XK_uring | |
| 219 | − 0x0170: 0x01db, | |
| 220 | − // XK_Udoubleacute | |
| 221 | − 0x0171: 0x01fb, | |
| 222 | − // XK_udoubleacute | |
| 223 | − 0x0172: 0x03d9, | |
| 224 | − // XK_Uogonek | |
| 225 | − 0x0173: 0x03f9, | |
| 226 | − // XK_uogonek | |
| 227 | − 0x0178: 0x13be, | |
| 228 | − // XK_Ydiaeresis | |
| 229 | − 0x0179: 0x01ac, | |
| 230 | − // XK_Zacute | |
| 231 | − 0x017a: 0x01bc, | |
| 232 | − // XK_zacute | |
| 233 | − 0x017b: 0x01af, | |
| 234 | − // XK_Zabovedot | |
| 235 | − 0x017c: 0x01bf, | |
| 236 | − // XK_zabovedot | |
| 237 | − 0x017d: 0x01ae, | |
| 238 | − // XK_Zcaron | |
| 239 | − 0x017e: 0x01be, | |
| 240 | − // XK_zcaron | |
| 241 | − 0x0192: 0x08f6, | |
| 242 | − // XK_function | |
| 243 | − 0x01d2: 0x10001d1, | |
| 244 | − // XK_Ocaron | |
| 245 | − 0x02c7: 0x01b7, | |
| 246 | − // XK_caron | |
| 247 | − 0x02d8: 0x01a2, | |
| 248 | − // XK_breve | |
| 249 | − 0x02d9: 0x01ff, | |
| 250 | − // XK_abovedot | |
| 251 | − 0x02db: 0x01b2, | |
| 252 | − // XK_ogonek | |
| 253 | − 0x02dd: 0x01bd, | |
| 254 | − // XK_doubleacute | |
| 255 | − 0x0385: 0x07ae, | |
| 256 | − // XK_Greek_accentdieresis | |
| 257 | − 0x0386: 0x07a1, | |
| 258 | − // XK_Greek_ALPHAaccent | |
| 259 | − 0x0388: 0x07a2, | |
| 260 | − // XK_Greek_EPSILONaccent | |
| 261 | − 0x0389: 0x07a3, | |
| 262 | − // XK_Greek_ETAaccent | |
| 263 | − 0x038a: 0x07a4, | |
| 264 | − // XK_Greek_IOTAaccent | |
| 265 | − 0x038c: 0x07a7, | |
| 266 | − // XK_Greek_OMICRONaccent | |
| 267 | − 0x038e: 0x07a8, | |
| 268 | − // XK_Greek_UPSILONaccent | |
| 269 | − 0x038f: 0x07ab, | |
| 270 | − // XK_Greek_OMEGAaccent | |
| 271 | − 0x0390: 0x07b6, | |
| 272 | − // XK_Greek_iotaaccentdieresis | |
| 273 | − 0x0391: 0x07c1, | |
| 274 | − // XK_Greek_ALPHA | |
| 275 | − 0x0392: 0x07c2, | |
| 276 | − // XK_Greek_BETA | |
| 277 | − 0x0393: 0x07c3, | |
| 278 | − // XK_Greek_GAMMA | |
| 279 | − 0x0394: 0x07c4, | |
| 280 | − // XK_Greek_DELTA | |
| 281 | − 0x0395: 0x07c5, | |
| 282 | − // XK_Greek_EPSILON | |
| 283 | − 0x0396: 0x07c6, | |
| 284 | − // XK_Greek_ZETA | |
| 285 | − 0x0397: 0x07c7, | |
| 286 | − // XK_Greek_ETA | |
| 287 | − 0x0398: 0x07c8, | |
| 288 | − // XK_Greek_THETA | |
| 289 | − 0x0399: 0x07c9, | |
| 290 | − // XK_Greek_IOTA | |
| 291 | − 0x039a: 0x07ca, | |
| 292 | − // XK_Greek_KAPPA | |
| 293 | − 0x039b: 0x07cb, | |
| 294 | − // XK_Greek_LAMDA | |
| 295 | − 0x039c: 0x07cc, | |
| 296 | − // XK_Greek_MU | |
| 297 | − 0x039d: 0x07cd, | |
| 298 | − // XK_Greek_NU | |
| 299 | − 0x039e: 0x07ce, | |
| 300 | − // XK_Greek_XI | |
| 301 | − 0x039f: 0x07cf, | |
| 302 | − // XK_Greek_OMICRON | |
| 303 | − 0x03a0: 0x07d0, | |
| 304 | − // XK_Greek_PI | |
| 305 | − 0x03a1: 0x07d1, | |
| 306 | − // XK_Greek_RHO | |
| 307 | − 0x03a3: 0x07d2, | |
| 308 | − // XK_Greek_SIGMA | |
| 309 | − 0x03a4: 0x07d4, | |
| 310 | − // XK_Greek_TAU | |
| 311 | − 0x03a5: 0x07d5, | |
| 312 | − // XK_Greek_UPSILON | |
| 313 | − 0x03a6: 0x07d6, | |
| 314 | − // XK_Greek_PHI | |
| 315 | − 0x03a7: 0x07d7, | |
| 316 | − // XK_Greek_CHI | |
| 317 | − 0x03a8: 0x07d8, | |
| 318 | − // XK_Greek_PSI | |
| 319 | − 0x03a9: 0x07d9, | |
| 320 | − // XK_Greek_OMEGA | |
| 321 | − 0x03aa: 0x07a5, | |
| 322 | − // XK_Greek_IOTAdieresis | |
| 323 | − 0x03ab: 0x07a9, | |
| 324 | − // XK_Greek_UPSILONdieresis | |
| 325 | − 0x03ac: 0x07b1, | |
| 326 | − // XK_Greek_alphaaccent | |
| 327 | − 0x03ad: 0x07b2, | |
| 328 | − // XK_Greek_epsilonaccent | |
| 329 | − 0x03ae: 0x07b3, | |
| 330 | − // XK_Greek_etaaccent | |
| 331 | − 0x03af: 0x07b4, | |
| 332 | − // XK_Greek_iotaaccent | |
| 333 | − 0x03b0: 0x07ba, | |
| 334 | − // XK_Greek_upsilonaccentdieresis | |
| 335 | − 0x03b1: 0x07e1, | |
| 336 | − // XK_Greek_alpha | |
| 337 | − 0x03b2: 0x07e2, | |
| 338 | − // XK_Greek_beta | |
| 339 | − 0x03b3: 0x07e3, | |
| 340 | − // XK_Greek_gamma | |
| 341 | − 0x03b4: 0x07e4, | |
| 342 | − // XK_Greek_delta | |
| 343 | − 0x03b5: 0x07e5, | |
| 344 | − // XK_Greek_epsilon | |
| 345 | − 0x03b6: 0x07e6, | |
| 346 | − // XK_Greek_zeta | |
| 347 | − 0x03b7: 0x07e7, | |
| 348 | − // XK_Greek_eta | |
| 349 | − 0x03b8: 0x07e8, | |
| 350 | − // XK_Greek_theta | |
| 351 | − 0x03b9: 0x07e9, | |
| 352 | − // XK_Greek_iota | |
| 353 | − 0x03ba: 0x07ea, | |
| 354 | − // XK_Greek_kappa | |
| 355 | − 0x03bb: 0x07eb, | |
| 356 | − // XK_Greek_lamda | |
| 357 | − 0x03bc: 0x07ec, | |
| 358 | − // XK_Greek_mu | |
| 359 | − 0x03bd: 0x07ed, | |
| 360 | − // XK_Greek_nu | |
| 361 | − 0x03be: 0x07ee, | |
| 362 | − // XK_Greek_xi | |
| 363 | − 0x03bf: 0x07ef, | |
| 364 | − // XK_Greek_omicron | |
| 365 | − 0x03c0: 0x07f0, | |
| 366 | − // XK_Greek_pi | |
| 367 | − 0x03c1: 0x07f1, | |
| 368 | − // XK_Greek_rho | |
| 369 | − 0x03c2: 0x07f3, | |
| 370 | − // XK_Greek_finalsmallsigma | |
| 371 | − 0x03c3: 0x07f2, | |
| 372 | − // XK_Greek_sigma | |
| 373 | − 0x03c4: 0x07f4, | |
| 374 | − // XK_Greek_tau | |
| 375 | − 0x03c5: 0x07f5, | |
| 376 | − // XK_Greek_upsilon | |
| 377 | − 0x03c6: 0x07f6, | |
| 378 | − // XK_Greek_phi | |
| 379 | − 0x03c7: 0x07f7, | |
| 380 | − // XK_Greek_chi | |
| 381 | − 0x03c8: 0x07f8, | |
| 382 | − // XK_Greek_psi | |
| 383 | − 0x03c9: 0x07f9, | |
| 384 | − // XK_Greek_omega | |
| 385 | − 0x03ca: 0x07b5, | |
| 386 | − // XK_Greek_iotadieresis | |
| 387 | − 0x03cb: 0x07b9, | |
| 388 | − // XK_Greek_upsilondieresis | |
| 389 | − 0x03cc: 0x07b7, | |
| 390 | − // XK_Greek_omicronaccent | |
| 391 | − 0x03cd: 0x07b8, | |
| 392 | − // XK_Greek_upsilonaccent | |
| 393 | − 0x03ce: 0x07bb, | |
| 394 | − // XK_Greek_omegaaccent | |
| 395 | − 0x0401: 0x06b3, | |
| 396 | − // XK_Cyrillic_IO | |
| 397 | − 0x0402: 0x06b1, | |
| 398 | − // XK_Serbian_DJE | |
| 399 | − 0x0403: 0x06b2, | |
| 400 | − // XK_Macedonia_GJE | |
| 401 | − 0x0404: 0x06b4, | |
| 402 | − // XK_Ukrainian_IE | |
| 403 | − 0x0405: 0x06b5, | |
| 404 | − // XK_Macedonia_DSE | |
| 405 | − 0x0406: 0x06b6, | |
| 406 | − // XK_Ukrainian_I | |
| 407 | − 0x0407: 0x06b7, | |
| 408 | − // XK_Ukrainian_YI | |
| 409 | − 0x0408: 0x06b8, | |
| 410 | − // XK_Cyrillic_JE | |
| 411 | − 0x0409: 0x06b9, | |
| 412 | − // XK_Cyrillic_LJE | |
| 413 | − 0x040a: 0x06ba, | |
| 414 | − // XK_Cyrillic_NJE | |
| 415 | − 0x040b: 0x06bb, | |
| 416 | − // XK_Serbian_TSHE | |
| 417 | − 0x040c: 0x06bc, | |
| 418 | − // XK_Macedonia_KJE | |
| 419 | − 0x040e: 0x06be, | |
| 420 | − // XK_Byelorussian_SHORTU | |
| 421 | − 0x040f: 0x06bf, | |
| 422 | − // XK_Cyrillic_DZHE | |
| 423 | − 0x0410: 0x06e1, | |
| 424 | − // XK_Cyrillic_A | |
| 425 | − 0x0411: 0x06e2, | |
| 426 | − // XK_Cyrillic_BE | |
| 427 | − 0x0412: 0x06f7, | |
| 428 | − // XK_Cyrillic_VE | |
| 429 | − 0x0413: 0x06e7, | |
| 430 | − // XK_Cyrillic_GHE | |
| 431 | − 0x0414: 0x06e4, | |
| 432 | − // XK_Cyrillic_DE | |
| 433 | − 0x0415: 0x06e5, | |
| 434 | − // XK_Cyrillic_IE | |
| 435 | − 0x0416: 0x06f6, | |
| 436 | − // XK_Cyrillic_ZHE | |
| 437 | − 0x0417: 0x06fa, | |
| 438 | − // XK_Cyrillic_ZE | |
| 439 | − 0x0418: 0x06e9, | |
| 440 | − // XK_Cyrillic_I | |
| 441 | − 0x0419: 0x06ea, | |
| 442 | − // XK_Cyrillic_SHORTI | |
| 443 | − 0x041a: 0x06eb, | |
| 444 | − // XK_Cyrillic_KA | |
| 445 | − 0x041b: 0x06ec, | |
| 446 | − // XK_Cyrillic_EL | |
| 447 | − 0x041c: 0x06ed, | |
| 448 | − // XK_Cyrillic_EM | |
| 449 | − 0x041d: 0x06ee, | |
| 450 | − // XK_Cyrillic_EN | |
| 451 | − 0x041e: 0x06ef, | |
| 452 | − // XK_Cyrillic_O | |
| 453 | − 0x041f: 0x06f0, | |
| 454 | − // XK_Cyrillic_PE | |
| 455 | − 0x0420: 0x06f2, | |
| 456 | − // XK_Cyrillic_ER | |
| 457 | − 0x0421: 0x06f3, | |
| 458 | − // XK_Cyrillic_ES | |
| 459 | − 0x0422: 0x06f4, | |
| 460 | − // XK_Cyrillic_TE | |
| 461 | − 0x0423: 0x06f5, | |
| 462 | − // XK_Cyrillic_U | |
| 463 | − 0x0424: 0x06e6, | |
| 464 | − // XK_Cyrillic_EF | |
| 465 | − 0x0425: 0x06e8, | |
| 466 | − // XK_Cyrillic_HA | |
| 467 | − 0x0426: 0x06e3, | |
| 468 | − // XK_Cyrillic_TSE | |
| 469 | − 0x0427: 0x06fe, | |
| 470 | − // XK_Cyrillic_CHE | |
| 471 | − 0x0428: 0x06fb, | |
| 472 | − // XK_Cyrillic_SHA | |
| 473 | − 0x0429: 0x06fd, | |
| 474 | − // XK_Cyrillic_SHCHA | |
| 475 | − 0x042a: 0x06ff, | |
| 476 | − // XK_Cyrillic_HARDSIGN | |
| 477 | − 0x042b: 0x06f9, | |
| 478 | − // XK_Cyrillic_YERU | |
| 479 | − 0x042c: 0x06f8, | |
| 480 | − // XK_Cyrillic_SOFTSIGN | |
| 481 | − 0x042d: 0x06fc, | |
| 482 | − // XK_Cyrillic_E | |
| 483 | − 0x042e: 0x06e0, | |
| 484 | − // XK_Cyrillic_YU | |
| 485 | − 0x042f: 0x06f1, | |
| 486 | − // XK_Cyrillic_YA | |
| 487 | − 0x0430: 0x06c1, | |
| 488 | − // XK_Cyrillic_a | |
| 489 | − 0x0431: 0x06c2, | |
| 490 | − // XK_Cyrillic_be | |
| 491 | − 0x0432: 0x06d7, | |
| 492 | − // XK_Cyrillic_ve | |
| 493 | − 0x0433: 0x06c7, | |
| 494 | − // XK_Cyrillic_ghe | |
| 495 | − 0x0434: 0x06c4, | |
| 496 | − // XK_Cyrillic_de | |
| 497 | − 0x0435: 0x06c5, | |
| 498 | − // XK_Cyrillic_ie | |
| 499 | − 0x0436: 0x06d6, | |
| 500 | − // XK_Cyrillic_zhe | |
| 501 | − 0x0437: 0x06da, | |
| 502 | − // XK_Cyrillic_ze | |
| 503 | − 0x0438: 0x06c9, | |
| 504 | − // XK_Cyrillic_i | |
| 505 | − 0x0439: 0x06ca, | |
| 506 | − // XK_Cyrillic_shorti | |
| 507 | − 0x043a: 0x06cb, | |
| 508 | − // XK_Cyrillic_ka | |
| 509 | − 0x043b: 0x06cc, | |
| 510 | − // XK_Cyrillic_el | |
| 511 | − 0x043c: 0x06cd, | |
| 512 | − // XK_Cyrillic_em | |
| 513 | − 0x043d: 0x06ce, | |
| 514 | − // XK_Cyrillic_en | |
| 515 | − 0x043e: 0x06cf, | |
| 516 | − // XK_Cyrillic_o | |
| 517 | − 0x043f: 0x06d0, | |
| 518 | − // XK_Cyrillic_pe | |
| 519 | − 0x0440: 0x06d2, | |
| 520 | − // XK_Cyrillic_er | |
| 521 | − 0x0441: 0x06d3, | |
| 522 | − // XK_Cyrillic_es | |
| 523 | − 0x0442: 0x06d4, | |
| 524 | − // XK_Cyrillic_te | |
| 525 | − 0x0443: 0x06d5, | |
| 526 | − // XK_Cyrillic_u | |
| 527 | − 0x0444: 0x06c6, | |
| 528 | − // XK_Cyrillic_ef | |
| 529 | − 0x0445: 0x06c8, | |
| 530 | − // XK_Cyrillic_ha | |
| 531 | − 0x0446: 0x06c3, | |
| 532 | − // XK_Cyrillic_tse | |
| 533 | − 0x0447: 0x06de, | |
| 534 | − // XK_Cyrillic_che | |
| 535 | − 0x0448: 0x06db, | |
| 536 | − // XK_Cyrillic_sha | |
| 537 | − 0x0449: 0x06dd, | |
| 538 | − // XK_Cyrillic_shcha | |
| 539 | − 0x044a: 0x06df, | |
| 540 | − // XK_Cyrillic_hardsign | |
| 541 | − 0x044b: 0x06d9, | |
| 542 | − // XK_Cyrillic_yeru | |
| 543 | − 0x044c: 0x06d8, | |
| 544 | − // XK_Cyrillic_softsign | |
| 545 | − 0x044d: 0x06dc, | |
| 546 | − // XK_Cyrillic_e | |
| 547 | − 0x044e: 0x06c0, | |
| 548 | − // XK_Cyrillic_yu | |
| 549 | − 0x044f: 0x06d1, | |
| 550 | − // XK_Cyrillic_ya | |
| 551 | − 0x0451: 0x06a3, | |
| 552 | − // XK_Cyrillic_io | |
| 553 | − 0x0452: 0x06a1, | |
| 554 | − // XK_Serbian_dje | |
| 555 | − 0x0453: 0x06a2, | |
| 556 | − // XK_Macedonia_gje | |
| 557 | − 0x0454: 0x06a4, | |
| 558 | − // XK_Ukrainian_ie | |
| 559 | − 0x0455: 0x06a5, | |
| 560 | − // XK_Macedonia_dse | |
| 561 | − 0x0456: 0x06a6, | |
| 562 | − // XK_Ukrainian_i | |
| 563 | − 0x0457: 0x06a7, | |
| 564 | − // XK_Ukrainian_yi | |
| 565 | − 0x0458: 0x06a8, | |
| 566 | − // XK_Cyrillic_je | |
| 567 | − 0x0459: 0x06a9, | |
| 568 | − // XK_Cyrillic_lje | |
| 569 | − 0x045a: 0x06aa, | |
| 570 | − // XK_Cyrillic_nje | |
| 571 | − 0x045b: 0x06ab, | |
| 572 | − // XK_Serbian_tshe | |
| 573 | − 0x045c: 0x06ac, | |
| 574 | − // XK_Macedonia_kje | |
| 575 | − 0x045e: 0x06ae, | |
| 576 | − // XK_Byelorussian_shortu | |
| 577 | − 0x045f: 0x06af, | |
| 578 | − // XK_Cyrillic_dzhe | |
| 579 | − 0x0490: 0x06bd, | |
| 580 | − // XK_Ukrainian_GHE_WITH_UPTURN | |
| 581 | − 0x0491: 0x06ad, | |
| 582 | − // XK_Ukrainian_ghe_with_upturn | |
| 583 | − 0x05d0: 0x0ce0, | |
| 584 | − // XK_hebrew_aleph | |
| 585 | − 0x05d1: 0x0ce1, | |
| 586 | − // XK_hebrew_bet | |
| 587 | − 0x05d2: 0x0ce2, | |
| 588 | − // XK_hebrew_gimel | |
| 589 | − 0x05d3: 0x0ce3, | |
| 590 | − // XK_hebrew_dalet | |
| 591 | − 0x05d4: 0x0ce4, | |
| 592 | − // XK_hebrew_he | |
| 593 | − 0x05d5: 0x0ce5, | |
| 594 | − // XK_hebrew_waw | |
| 595 | − 0x05d6: 0x0ce6, | |
| 596 | − // XK_hebrew_zain | |
| 597 | − 0x05d7: 0x0ce7, | |
| 598 | − // XK_hebrew_chet | |
| 599 | − 0x05d8: 0x0ce8, | |
| 600 | − // XK_hebrew_tet | |
| 601 | − 0x05d9: 0x0ce9, | |
| 602 | − // XK_hebrew_yod | |
| 603 | − 0x05da: 0x0cea, | |
| 604 | − // XK_hebrew_finalkaph | |
| 605 | − 0x05db: 0x0ceb, | |
| 606 | − // XK_hebrew_kaph | |
| 607 | − 0x05dc: 0x0cec, | |
| 608 | − // XK_hebrew_lamed | |
| 609 | − 0x05dd: 0x0ced, | |
| 610 | − // XK_hebrew_finalmem | |
| 611 | − 0x05de: 0x0cee, | |
| 612 | − // XK_hebrew_mem | |
| 613 | − 0x05df: 0x0cef, | |
| 614 | − // XK_hebrew_finalnun | |
| 615 | − 0x05e0: 0x0cf0, | |
| 616 | − // XK_hebrew_nun | |
| 617 | − 0x05e1: 0x0cf1, | |
| 618 | − // XK_hebrew_samech | |
| 619 | − 0x05e2: 0x0cf2, | |
| 620 | − // XK_hebrew_ayin | |
| 621 | − 0x05e3: 0x0cf3, | |
| 622 | − // XK_hebrew_finalpe | |
| 623 | − 0x05e4: 0x0cf4, | |
| 624 | − // XK_hebrew_pe | |
| 625 | − 0x05e5: 0x0cf5, | |
| 626 | − // XK_hebrew_finalzade | |
| 627 | − 0x05e6: 0x0cf6, | |
| 628 | − // XK_hebrew_zade | |
| 629 | − 0x05e7: 0x0cf7, | |
| 630 | − // XK_hebrew_qoph | |
| 631 | − 0x05e8: 0x0cf8, | |
| 632 | − // XK_hebrew_resh | |
| 633 | − 0x05e9: 0x0cf9, | |
| 634 | − // XK_hebrew_shin | |
| 635 | − 0x05ea: 0x0cfa, | |
| 636 | − // XK_hebrew_taw | |
| 637 | − 0x060c: 0x05ac, | |
| 638 | − // XK_Arabic_comma | |
| 639 | − 0x061b: 0x05bb, | |
| 640 | − // XK_Arabic_semicolon | |
| 641 | − 0x061f: 0x05bf, | |
| 642 | − // XK_Arabic_question_mark | |
| 643 | − 0x0621: 0x05c1, | |
| 644 | − // XK_Arabic_hamza | |
| 645 | − 0x0622: 0x05c2, | |
| 646 | − // XK_Arabic_maddaonalef | |
| 647 | − 0x0623: 0x05c3, | |
| 648 | − // XK_Arabic_hamzaonalef | |
| 649 | − 0x0624: 0x05c4, | |
| 650 | − // XK_Arabic_hamzaonwaw | |
| 651 | − 0x0625: 0x05c5, | |
| 652 | − // XK_Arabic_hamzaunderalef | |
| 653 | − 0x0626: 0x05c6, | |
| 654 | − // XK_Arabic_hamzaonyeh | |
| 655 | − 0x0627: 0x05c7, | |
| 656 | − // XK_Arabic_alef | |
| 657 | − 0x0628: 0x05c8, | |
| 658 | − // XK_Arabic_beh | |
| 659 | − 0x0629: 0x05c9, | |
| 660 | − // XK_Arabic_tehmarbuta | |
| 661 | − 0x062a: 0x05ca, | |
| 662 | − // XK_Arabic_teh | |
| 663 | − 0x062b: 0x05cb, | |
| 664 | − // XK_Arabic_theh | |
| 665 | − 0x062c: 0x05cc, | |
| 666 | − // XK_Arabic_jeem | |
| 667 | − 0x062d: 0x05cd, | |
| 668 | − // XK_Arabic_hah | |
| 669 | − 0x062e: 0x05ce, | |
| 670 | − // XK_Arabic_khah | |
| 671 | − 0x062f: 0x05cf, | |
| 672 | − // XK_Arabic_dal | |
| 673 | − 0x0630: 0x05d0, | |
| 674 | − // XK_Arabic_thal | |
| 675 | − 0x0631: 0x05d1, | |
| 676 | − // XK_Arabic_ra | |
| 677 | − 0x0632: 0x05d2, | |
| 678 | − // XK_Arabic_zain | |
| 679 | − 0x0633: 0x05d3, | |
| 680 | − // XK_Arabic_seen | |
| 681 | − 0x0634: 0x05d4, | |
| 682 | − // XK_Arabic_sheen | |
| 683 | − 0x0635: 0x05d5, | |
| 684 | − // XK_Arabic_sad | |
| 685 | − 0x0636: 0x05d6, | |
| 686 | − // XK_Arabic_dad | |
| 687 | − 0x0637: 0x05d7, | |
| 688 | − // XK_Arabic_tah | |
| 689 | − 0x0638: 0x05d8, | |
| 690 | − // XK_Arabic_zah | |
| 691 | − 0x0639: 0x05d9, | |
| 692 | − // XK_Arabic_ain | |
| 693 | − 0x063a: 0x05da, | |
| 694 | − // XK_Arabic_ghain | |
| 695 | − 0x0640: 0x05e0, | |
| 696 | − // XK_Arabic_tatweel | |
| 697 | − 0x0641: 0x05e1, | |
| 698 | − // XK_Arabic_feh | |
| 699 | − 0x0642: 0x05e2, | |
| 700 | − // XK_Arabic_qaf | |
| 701 | − 0x0643: 0x05e3, | |
| 702 | − // XK_Arabic_kaf | |
| 703 | − 0x0644: 0x05e4, | |
| 704 | − // XK_Arabic_lam | |
| 705 | − 0x0645: 0x05e5, | |
| 706 | − // XK_Arabic_meem | |
| 707 | − 0x0646: 0x05e6, | |
| 708 | − // XK_Arabic_noon | |
| 709 | − 0x0647: 0x05e7, | |
| 710 | − // XK_Arabic_ha | |
| 711 | − 0x0648: 0x05e8, | |
| 712 | − // XK_Arabic_waw | |
| 713 | − 0x0649: 0x05e9, | |
| 714 | − // XK_Arabic_alefmaksura | |
| 715 | − 0x064a: 0x05ea, | |
| 716 | − // XK_Arabic_yeh | |
| 717 | − 0x064b: 0x05eb, | |
| 718 | − // XK_Arabic_fathatan | |
| 719 | − 0x064c: 0x05ec, | |
| 720 | − // XK_Arabic_dammatan | |
| 721 | − 0x064d: 0x05ed, | |
| 722 | − // XK_Arabic_kasratan | |
| 723 | − 0x064e: 0x05ee, | |
| 724 | − // XK_Arabic_fatha | |
| 725 | − 0x064f: 0x05ef, | |
| 726 | − // XK_Arabic_damma | |
| 727 | − 0x0650: 0x05f0, | |
| 728 | − // XK_Arabic_kasra | |
| 729 | − 0x0651: 0x05f1, | |
| 730 | − // XK_Arabic_shadda | |
| 731 | − 0x0652: 0x05f2, | |
| 732 | − // XK_Arabic_sukun | |
| 733 | − 0x0e01: 0x0da1, | |
| 734 | − // XK_Thai_kokai | |
| 735 | − 0x0e02: 0x0da2, | |
| 736 | − // XK_Thai_khokhai | |
| 737 | − 0x0e03: 0x0da3, | |
| 738 | − // XK_Thai_khokhuat | |
| 739 | − 0x0e04: 0x0da4, | |
| 740 | − // XK_Thai_khokhwai | |
| 741 | − 0x0e05: 0x0da5, | |
| 742 | − // XK_Thai_khokhon | |
| 743 | − 0x0e06: 0x0da6, | |
| 744 | − // XK_Thai_khorakhang | |
| 745 | − 0x0e07: 0x0da7, | |
| 746 | − // XK_Thai_ngongu | |
| 747 | − 0x0e08: 0x0da8, | |
| 748 | − // XK_Thai_chochan | |
| 749 | − 0x0e09: 0x0da9, | |
| 750 | − // XK_Thai_choching | |
| 751 | − 0x0e0a: 0x0daa, | |
| 752 | − // XK_Thai_chochang | |
| 753 | − 0x0e0b: 0x0dab, | |
| 754 | − // XK_Thai_soso | |
| 755 | − 0x0e0c: 0x0dac, | |
| 756 | − // XK_Thai_chochoe | |
| 757 | − 0x0e0d: 0x0dad, | |
| 758 | − // XK_Thai_yoying | |
| 759 | − 0x0e0e: 0x0dae, | |
| 760 | − // XK_Thai_dochada | |
| 761 | − 0x0e0f: 0x0daf, | |
| 762 | − // XK_Thai_topatak | |
| 763 | − 0x0e10: 0x0db0, | |
| 764 | − // XK_Thai_thothan | |
| 765 | − 0x0e11: 0x0db1, | |
| 766 | − // XK_Thai_thonangmontho | |
| 767 | − 0x0e12: 0x0db2, | |
| 768 | − // XK_Thai_thophuthao | |
| 769 | − 0x0e13: 0x0db3, | |
| 770 | − // XK_Thai_nonen | |
| 771 | − 0x0e14: 0x0db4, | |
| 772 | − // XK_Thai_dodek | |
| 773 | − 0x0e15: 0x0db5, | |
| 774 | − // XK_Thai_totao | |
| 775 | − 0x0e16: 0x0db6, | |
| 776 | − // XK_Thai_thothung | |
| 777 | − 0x0e17: 0x0db7, | |
| 778 | − // XK_Thai_thothahan | |
| 779 | − 0x0e18: 0x0db8, | |
| 780 | − // XK_Thai_thothong | |
| 781 | − 0x0e19: 0x0db9, | |
| 782 | − // XK_Thai_nonu | |
| 783 | − 0x0e1a: 0x0dba, | |
| 784 | − // XK_Thai_bobaimai | |
| 785 | − 0x0e1b: 0x0dbb, | |
| 786 | − // XK_Thai_popla | |
| 787 | − 0x0e1c: 0x0dbc, | |
| 788 | − // XK_Thai_phophung | |
| 789 | − 0x0e1d: 0x0dbd, | |
| 790 | − // XK_Thai_fofa | |
| 791 | − 0x0e1e: 0x0dbe, | |
| 792 | − // XK_Thai_phophan | |
| 793 | − 0x0e1f: 0x0dbf, | |
| 794 | − // XK_Thai_fofan | |
| 795 | − 0x0e20: 0x0dc0, | |
| 796 | − // XK_Thai_phosamphao | |
| 797 | − 0x0e21: 0x0dc1, | |
| 798 | − // XK_Thai_moma | |
| 799 | − 0x0e22: 0x0dc2, | |
| 800 | − // XK_Thai_yoyak | |
| 801 | − 0x0e23: 0x0dc3, | |
| 802 | − // XK_Thai_rorua | |
| 803 | − 0x0e24: 0x0dc4, | |
| 804 | − // XK_Thai_ru | |
| 805 | − 0x0e25: 0x0dc5, | |
| 806 | − // XK_Thai_loling | |
| 807 | − 0x0e26: 0x0dc6, | |
| 808 | − // XK_Thai_lu | |
| 809 | − 0x0e27: 0x0dc7, | |
| 810 | − // XK_Thai_wowaen | |
| 811 | − 0x0e28: 0x0dc8, | |
| 812 | − // XK_Thai_sosala | |
| 813 | − 0x0e29: 0x0dc9, | |
| 814 | − // XK_Thai_sorusi | |
| 815 | − 0x0e2a: 0x0dca, | |
| 816 | − // XK_Thai_sosua | |
| 817 | − 0x0e2b: 0x0dcb, | |
| 818 | − // XK_Thai_hohip | |
| 819 | − 0x0e2c: 0x0dcc, | |
| 820 | − // XK_Thai_lochula | |
| 821 | − 0x0e2d: 0x0dcd, | |
| 822 | − // XK_Thai_oang | |
| 823 | − 0x0e2e: 0x0dce, | |
| 824 | − // XK_Thai_honokhuk | |
| 825 | − 0x0e2f: 0x0dcf, | |
| 826 | − // XK_Thai_paiyannoi | |
| 827 | − 0x0e30: 0x0dd0, | |
| 828 | − // XK_Thai_saraa | |
| 829 | − 0x0e31: 0x0dd1, | |
| 830 | − // XK_Thai_maihanakat | |
| 831 | − 0x0e32: 0x0dd2, | |
| 832 | − // XK_Thai_saraaa | |
| 833 | − 0x0e33: 0x0dd3, | |
| 834 | − // XK_Thai_saraam | |
| 835 | − 0x0e34: 0x0dd4, | |
| 836 | − // XK_Thai_sarai | |
| 837 | − 0x0e35: 0x0dd5, | |
| 838 | − // XK_Thai_saraii | |
| 839 | − 0x0e36: 0x0dd6, | |
| 840 | − // XK_Thai_saraue | |
| 841 | − 0x0e37: 0x0dd7, | |
| 842 | − // XK_Thai_sarauee | |
| 843 | − 0x0e38: 0x0dd8, | |
| 844 | − // XK_Thai_sarau | |
| 845 | − 0x0e39: 0x0dd9, | |
| 846 | − // XK_Thai_sarauu | |
| 847 | − 0x0e3a: 0x0dda, | |
| 848 | − // XK_Thai_phinthu | |
| 849 | − 0x0e3f: 0x0ddf, | |
| 850 | − // XK_Thai_baht | |
| 851 | − 0x0e40: 0x0de0, | |
| 852 | − // XK_Thai_sarae | |
| 853 | − 0x0e41: 0x0de1, | |
| 854 | − // XK_Thai_saraae | |
| 855 | − 0x0e42: 0x0de2, | |
| 856 | − // XK_Thai_sarao | |
| 857 | − 0x0e43: 0x0de3, | |
| 858 | − // XK_Thai_saraaimaimuan | |
| 859 | − 0x0e44: 0x0de4, | |
| 860 | − // XK_Thai_saraaimaimalai | |
| 861 | − 0x0e45: 0x0de5, | |
| 862 | − // XK_Thai_lakkhangyao | |
| 863 | − 0x0e46: 0x0de6, | |
| 864 | − // XK_Thai_maiyamok | |
| 865 | − 0x0e47: 0x0de7, | |
| 866 | − // XK_Thai_maitaikhu | |
| 867 | − 0x0e48: 0x0de8, | |
| 868 | − // XK_Thai_maiek | |
| 869 | − 0x0e49: 0x0de9, | |
| 870 | − // XK_Thai_maitho | |
| 871 | − 0x0e4a: 0x0dea, | |
| 872 | − // XK_Thai_maitri | |
| 873 | − 0x0e4b: 0x0deb, | |
| 874 | − // XK_Thai_maichattawa | |
| 875 | − 0x0e4c: 0x0dec, | |
| 876 | − // XK_Thai_thanthakhat | |
| 877 | − 0x0e4d: 0x0ded, | |
| 878 | − // XK_Thai_nikhahit | |
| 879 | − 0x0e50: 0x0df0, | |
| 880 | − // XK_Thai_leksun | |
| 881 | − 0x0e51: 0x0df1, | |
| 882 | − // XK_Thai_leknung | |
| 883 | − 0x0e52: 0x0df2, | |
| 884 | − // XK_Thai_leksong | |
| 885 | − 0x0e53: 0x0df3, | |
| 886 | − // XK_Thai_leksam | |
| 887 | − 0x0e54: 0x0df4, | |
| 888 | − // XK_Thai_leksi | |
| 889 | − 0x0e55: 0x0df5, | |
| 890 | − // XK_Thai_lekha | |
| 891 | − 0x0e56: 0x0df6, | |
| 892 | − // XK_Thai_lekhok | |
| 893 | − 0x0e57: 0x0df7, | |
| 894 | − // XK_Thai_lekchet | |
| 895 | − 0x0e58: 0x0df8, | |
| 896 | − // XK_Thai_lekpaet | |
| 897 | − 0x0e59: 0x0df9, | |
| 898 | − // XK_Thai_lekkao | |
| 899 | − 0x2002: 0x0aa2, | |
| 900 | − // XK_enspace | |
| 901 | − 0x2003: 0x0aa1, | |
| 902 | − // XK_emspace | |
| 903 | − 0x2004: 0x0aa3, | |
| 904 | − // XK_em3space | |
| 905 | − 0x2005: 0x0aa4, | |
| 906 | − // XK_em4space | |
| 907 | − 0x2007: 0x0aa5, | |
| 908 | − // XK_digitspace | |
| 909 | − 0x2008: 0x0aa6, | |
| 910 | − // XK_punctspace | |
| 911 | − 0x2009: 0x0aa7, | |
| 912 | − // XK_thinspace | |
| 913 | − 0x200a: 0x0aa8, | |
| 914 | − // XK_hairspace | |
| 915 | − 0x2012: 0x0abb, | |
| 916 | − // XK_figdash | |
| 917 | − 0x2013: 0x0aaa, | |
| 918 | − // XK_endash | |
| 919 | − 0x2014: 0x0aa9, | |
| 920 | − // XK_emdash | |
| 921 | − 0x2015: 0x07af, | |
| 922 | − // XK_Greek_horizbar | |
| 923 | − 0x2017: 0x0cdf, | |
| 924 | − // XK_hebrew_doublelowline | |
| 925 | − 0x2018: 0x0ad0, | |
| 926 | − // XK_leftsinglequotemark | |
| 927 | − 0x2019: 0x0ad1, | |
| 928 | − // XK_rightsinglequotemark | |
| 929 | − 0x201a: 0x0afd, | |
| 930 | − // XK_singlelowquotemark | |
| 931 | − 0x201c: 0x0ad2, | |
| 932 | − // XK_leftdoublequotemark | |
| 933 | − 0x201d: 0x0ad3, | |
| 934 | − // XK_rightdoublequotemark | |
| 935 | − 0x201e: 0x0afe, | |
| 936 | − // XK_doublelowquotemark | |
| 937 | − 0x2020: 0x0af1, | |
| 938 | − // XK_dagger | |
| 939 | − 0x2021: 0x0af2, | |
| 940 | − // XK_doubledagger | |
| 941 | − 0x2022: 0x0ae6, | |
| 942 | − // XK_enfilledcircbullet | |
| 943 | − 0x2025: 0x0aaf, | |
| 944 | − // XK_doubbaselinedot | |
| 945 | − 0x2026: 0x0aae, | |
| 946 | − // XK_ellipsis | |
| 947 | − 0x2030: 0x0ad5, | |
| 948 | − // XK_permille | |
| 949 | − 0x2032: 0x0ad6, | |
| 950 | − // XK_minutes | |
| 951 | − 0x2033: 0x0ad7, | |
| 952 | − // XK_seconds | |
| 953 | − 0x2038: 0x0afc, | |
| 954 | − // XK_caret | |
| 955 | − 0x203e: 0x047e, | |
| 956 | − // XK_overline | |
| 957 | − 0x20a9: 0x0eff, | |
| 958 | − // XK_Korean_Won | |
| 959 | − 0x20ac: 0x20ac, | |
| 960 | − // XK_EuroSign | |
| 961 | − 0x2105: 0x0ab8, | |
| 962 | − // XK_careof | |
| 963 | − 0x2116: 0x06b0, | |
| 964 | − // XK_numerosign | |
| 965 | − 0x2117: 0x0afb, | |
| 966 | − // XK_phonographcopyright | |
| 967 | − 0x211e: 0x0ad4, | |
| 968 | − // XK_prescription | |
| 969 | − 0x2122: 0x0ac9, | |
| 970 | − // XK_trademark | |
| 971 | − 0x2153: 0x0ab0, | |
| 972 | − // XK_onethird | |
| 973 | − 0x2154: 0x0ab1, | |
| 974 | − // XK_twothirds | |
| 975 | − 0x2155: 0x0ab2, | |
| 976 | − // XK_onefifth | |
| 977 | − 0x2156: 0x0ab3, | |
| 978 | − // XK_twofifths | |
| 979 | − 0x2157: 0x0ab4, | |
| 980 | − // XK_threefifths | |
| 981 | − 0x2158: 0x0ab5, | |
| 982 | − // XK_fourfifths | |
| 983 | − 0x2159: 0x0ab6, | |
| 984 | − // XK_onesixth | |
| 985 | − 0x215a: 0x0ab7, | |
| 986 | − // XK_fivesixths | |
| 987 | − 0x215b: 0x0ac3, | |
| 988 | − // XK_oneeighth | |
| 989 | − 0x215c: 0x0ac4, | |
| 990 | − // XK_threeeighths | |
| 991 | − 0x215d: 0x0ac5, | |
| 992 | − // XK_fiveeighths | |
| 993 | − 0x215e: 0x0ac6, | |
| 994 | − // XK_seveneighths | |
| 995 | − 0x2190: 0x08fb, | |
| 996 | − // XK_leftarrow | |
| 997 | − 0x2191: 0x08fc, | |
| 998 | − // XK_uparrow | |
| 999 | − 0x2192: 0x08fd, | |
| 1000 | − // XK_rightarrow | |
| 1001 | − 0x2193: 0x08fe, | |
| 1002 | − // XK_downarrow | |
| 1003 | − 0x21d2: 0x08ce, | |
| 1004 | − // XK_implies | |
| 1005 | − 0x21d4: 0x08cd, | |
| 1006 | − // XK_ifonlyif | |
| 1007 | − 0x2202: 0x08ef, | |
| 1008 | − // XK_partialderivative | |
| 1009 | − 0x2207: 0x08c5, | |
| 1010 | − // XK_nabla | |
| 1011 | − 0x2218: 0x0bca, | |
| 1012 | − // XK_jot | |
| 1013 | − 0x221a: 0x08d6, | |
| 1014 | − // XK_radical | |
| 1015 | − 0x221d: 0x08c1, | |
| 1016 | − // XK_variation | |
| 1017 | − 0x221e: 0x08c2, | |
| 1018 | − // XK_infinity | |
| 1019 | − 0x2227: 0x08de, | |
| 1020 | − // XK_logicaland | |
| 1021 | − 0x2228: 0x08df, | |
| 1022 | − // XK_logicalor | |
| 1023 | − 0x2229: 0x08dc, | |
| 1024 | − // XK_intersection | |
| 1025 | − 0x222a: 0x08dd, | |
| 1026 | − // XK_union | |
| 1027 | − 0x222b: 0x08bf, | |
| 1028 | − // XK_integral | |
| 1029 | − 0x2234: 0x08c0, | |
| 1030 | − // XK_therefore | |
| 1031 | − 0x223c: 0x08c8, | |
| 1032 | − // XK_approximate | |
| 1033 | − 0x2243: 0x08c9, | |
| 1034 | − // XK_similarequal | |
| 1035 | − 0x2245: 0x1002248, | |
| 1036 | − // XK_approxeq | |
| 1037 | − 0x2260: 0x08bd, | |
| 1038 | − // XK_notequal | |
| 1039 | − 0x2261: 0x08cf, | |
| 1040 | − // XK_identical | |
| 1041 | − 0x2264: 0x08bc, | |
| 1042 | − // XK_lessthanequal | |
| 1043 | − 0x2265: 0x08be, | |
| 1044 | − // XK_greaterthanequal | |
| 1045 | − 0x2282: 0x08da, | |
| 1046 | − // XK_includedin | |
| 1047 | − 0x2283: 0x08db, | |
| 1048 | − // XK_includes | |
| 1049 | − 0x22a2: 0x0bfc, | |
| 1050 | − // XK_righttack | |
| 1051 | − 0x22a3: 0x0bdc, | |
| 1052 | − // XK_lefttack | |
| 1053 | − 0x22a4: 0x0bc2, | |
| 1054 | − // XK_downtack | |
| 1055 | − 0x22a5: 0x0bce, | |
| 1056 | − // XK_uptack | |
| 1057 | − 0x2308: 0x0bd3, | |
| 1058 | − // XK_upstile | |
| 1059 | − 0x230a: 0x0bc4, | |
| 1060 | − // XK_downstile | |
| 1061 | − 0x2315: 0x0afa, | |
| 1062 | − // XK_telephonerecorder | |
| 1063 | − 0x2320: 0x08a4, | |
| 1064 | − // XK_topintegral | |
| 1065 | − 0x2321: 0x08a5, | |
| 1066 | − // XK_botintegral | |
| 1067 | − 0x2395: 0x0bcc, | |
| 1068 | − // XK_quad | |
| 1069 | − 0x239b: 0x08ab, | |
| 1070 | − // XK_topleftparens | |
| 1071 | − 0x239d: 0x08ac, | |
| 1072 | − // XK_botleftparens | |
| 1073 | − 0x239e: 0x08ad, | |
| 1074 | − // XK_toprightparens | |
| 1075 | − 0x23a0: 0x08ae, | |
| 1076 | − // XK_botrightparens | |
| 1077 | − 0x23a1: 0x08a7, | |
| 1078 | − // XK_topleftsqbracket | |
| 1079 | − 0x23a3: 0x08a8, | |
| 1080 | − // XK_botleftsqbracket | |
| 1081 | − 0x23a4: 0x08a9, | |
| 1082 | − // XK_toprightsqbracket | |
| 1083 | − 0x23a6: 0x08aa, | |
| 1084 | − // XK_botrightsqbracket | |
| 1085 | − 0x23a8: 0x08af, | |
| 1086 | − // XK_leftmiddlecurlybrace | |
| 1087 | − 0x23ac: 0x08b0, | |
| 1088 | − // XK_rightmiddlecurlybrace | |
| 1089 | − 0x23b7: 0x08a1, | |
| 1090 | − // XK_leftradical | |
| 1091 | − 0x23ba: 0x09ef, | |
| 1092 | − // XK_horizlinescan1 | |
| 1093 | − 0x23bb: 0x09f0, | |
| 1094 | − // XK_horizlinescan3 | |
| 1095 | − 0x23bc: 0x09f2, | |
| 1096 | − // XK_horizlinescan7 | |
| 1097 | − 0x23bd: 0x09f3, | |
| 1098 | − // XK_horizlinescan9 | |
| 1099 | − 0x2409: 0x09e2, | |
| 1100 | − // XK_ht | |
| 1101 | − 0x240a: 0x09e5, | |
| 1102 | − // XK_lf | |
| 1103 | − 0x240b: 0x09e9, | |
| 1104 | − // XK_vt | |
| 1105 | − 0x240c: 0x09e3, | |
| 1106 | − // XK_ff | |
| 1107 | − 0x240d: 0x09e4, | |
| 1108 | − // XK_cr | |
| 1109 | − 0x2423: 0x0aac, | |
| 1110 | − // XK_signifblank | |
| 1111 | − 0x2424: 0x09e8, | |
| 1112 | − // XK_nl | |
| 1113 | − 0x2500: 0x08a3, | |
| 1114 | − // XK_horizconnector | |
| 1115 | − 0x2502: 0x08a6, | |
| 1116 | − // XK_vertconnector | |
| 1117 | − 0x250c: 0x08a2, | |
| 1118 | − // XK_topleftradical | |
| 1119 | − 0x2510: 0x09eb, | |
| 1120 | − // XK_uprightcorner | |
| 1121 | − 0x2514: 0x09ed, | |
| 1122 | − // XK_lowleftcorner | |
| 1123 | − 0x2518: 0x09ea, | |
| 1124 | − // XK_lowrightcorner | |
| 1125 | − 0x251c: 0x09f4, | |
| 1126 | − // XK_leftt | |
| 1127 | − 0x2524: 0x09f5, | |
| 1128 | − // XK_rightt | |
| 1129 | − 0x252c: 0x09f7, | |
| 1130 | − // XK_topt | |
| 1131 | − 0x2534: 0x09f6, | |
| 1132 | − // XK_bott | |
| 1133 | − 0x253c: 0x09ee, | |
| 1134 | − // XK_crossinglines | |
| 1135 | − 0x2592: 0x09e1, | |
| 1136 | − // XK_checkerboard | |
| 1137 | − 0x25aa: 0x0ae7, | |
| 1138 | − // XK_enfilledsqbullet | |
| 1139 | − 0x25ab: 0x0ae1, | |
| 1140 | − // XK_enopensquarebullet | |
| 1141 | − 0x25ac: 0x0adb, | |
| 1142 | − // XK_filledrectbullet | |
| 1143 | − 0x25ad: 0x0ae2, | |
| 1144 | − // XK_openrectbullet | |
| 1145 | − 0x25ae: 0x0adf, | |
| 1146 | − // XK_emfilledrect | |
| 1147 | − 0x25af: 0x0acf, | |
| 1148 | − // XK_emopenrectangle | |
| 1149 | − 0x25b2: 0x0ae8, | |
| 1150 | − // XK_filledtribulletup | |
| 1151 | − 0x25b3: 0x0ae3, | |
| 1152 | − // XK_opentribulletup | |
| 1153 | − 0x25b6: 0x0add, | |
| 1154 | − // XK_filledrighttribullet | |
| 1155 | − 0x25b7: 0x0acd, | |
| 1156 | − // XK_rightopentriangle | |
| 1157 | − 0x25bc: 0x0ae9, | |
| 1158 | − // XK_filledtribulletdown | |
| 1159 | − 0x25bd: 0x0ae4, | |
| 1160 | − // XK_opentribulletdown | |
| 1161 | − 0x25c0: 0x0adc, | |
| 1162 | − // XK_filledlefttribullet | |
| 1163 | − 0x25c1: 0x0acc, | |
| 1164 | − // XK_leftopentriangle | |
| 1165 | − 0x25c6: 0x09e0, | |
| 1166 | − // XK_soliddiamond | |
| 1167 | − 0x25cb: 0x0ace, | |
| 1168 | − // XK_emopencircle | |
| 1169 | − 0x25cf: 0x0ade, | |
| 1170 | − // XK_emfilledcircle | |
| 1171 | − 0x25e6: 0x0ae0, | |
| 1172 | − // XK_enopencircbullet | |
| 1173 | − 0x2606: 0x0ae5, | |
| 1174 | − // XK_openstar | |
| 1175 | − 0x260e: 0x0af9, | |
| 1176 | − // XK_telephone | |
| 1177 | − 0x2613: 0x0aca, | |
| 1178 | − // XK_signaturemark | |
| 1179 | − 0x261c: 0x0aea, | |
| 1180 | − // XK_leftpointer | |
| 1181 | − 0x261e: 0x0aeb, | |
| 1182 | − // XK_rightpointer | |
| 1183 | − 0x2640: 0x0af8, | |
| 1184 | − // XK_femalesymbol | |
| 1185 | − 0x2642: 0x0af7, | |
| 1186 | − // XK_malesymbol | |
| 1187 | − 0x2663: 0x0aec, | |
| 1188 | − // XK_club | |
| 1189 | − 0x2665: 0x0aee, | |
| 1190 | − // XK_heart | |
| 1191 | − 0x2666: 0x0aed, | |
| 1192 | − // XK_diamond | |
| 1193 | − 0x266d: 0x0af6, | |
| 1194 | − // XK_musicalflat | |
| 1195 | − 0x266f: 0x0af5, | |
| 1196 | − // XK_musicalsharp | |
| 1197 | − 0x2713: 0x0af3, | |
| 1198 | − // XK_checkmark | |
| 1199 | − 0x2717: 0x0af4, | |
| 1200 | − // XK_ballotcross | |
| 1201 | − 0x271d: 0x0ad9, | |
| 1202 | − // XK_latincross | |
| 1203 | − 0x2720: 0x0af0, | |
| 1204 | − // XK_maltesecross | |
| 1205 | − 0x27e8: 0x0abc, | |
| 1206 | − // XK_leftanglebracket | |
| 1207 | − 0x27e9: 0x0abe, | |
| 1208 | − // XK_rightanglebracket | |
| 1209 | − 0x3001: 0x04a4, | |
| 1210 | − // XK_kana_comma | |
| 1211 | − 0x3002: 0x04a1, | |
| 1212 | − // XK_kana_fullstop | |
| 1213 | − 0x300c: 0x04a2, | |
| 1214 | − // XK_kana_openingbracket | |
| 1215 | − 0x300d: 0x04a3, | |
| 1216 | − // XK_kana_closingbracket | |
| 1217 | − 0x309b: 0x04de, | |
| 1218 | − // XK_voicedsound | |
| 1219 | − 0x309c: 0x04df, | |
| 1220 | − // XK_semivoicedsound | |
| 1221 | − 0x30a1: 0x04a7, | |
| 1222 | − // XK_kana_a | |
| 1223 | − 0x30a2: 0x04b1, | |
| 1224 | − // XK_kana_A | |
| 1225 | − 0x30a3: 0x04a8, | |
| 1226 | − // XK_kana_i | |
| 1227 | − 0x30a4: 0x04b2, | |
| 1228 | − // XK_kana_I | |
| 1229 | − 0x30a5: 0x04a9, | |
| 1230 | − // XK_kana_u | |
| 1231 | − 0x30a6: 0x04b3, | |
| 1232 | − // XK_kana_U | |
| 1233 | − 0x30a7: 0x04aa, | |
| 1234 | − // XK_kana_e | |
| 1235 | − 0x30a8: 0x04b4, | |
| 1236 | − // XK_kana_E | |
| 1237 | − 0x30a9: 0x04ab, | |
| 1238 | − // XK_kana_o | |
| 1239 | − 0x30aa: 0x04b5, | |
| 1240 | − // XK_kana_O | |
| 1241 | − 0x30ab: 0x04b6, | |
| 1242 | − // XK_kana_KA | |
| 1243 | − 0x30ad: 0x04b7, | |
| 1244 | − // XK_kana_KI | |
| 1245 | − 0x30af: 0x04b8, | |
| 1246 | − // XK_kana_KU | |
| 1247 | − 0x30b1: 0x04b9, | |
| 1248 | − // XK_kana_KE | |
| 1249 | − 0x30b3: 0x04ba, | |
| 1250 | − // XK_kana_KO | |
| 1251 | − 0x30b5: 0x04bb, | |
| 1252 | − // XK_kana_SA | |
| 1253 | − 0x30b7: 0x04bc, | |
| 1254 | − // XK_kana_SHI | |
| 1255 | − 0x30b9: 0x04bd, | |
| 1256 | − // XK_kana_SU | |
| 1257 | − 0x30bb: 0x04be, | |
| 1258 | − // XK_kana_SE | |
| 1259 | − 0x30bd: 0x04bf, | |
| 1260 | − // XK_kana_SO | |
| 1261 | − 0x30bf: 0x04c0, | |
| 1262 | − // XK_kana_TA | |
| 1263 | − 0x30c1: 0x04c1, | |
| 1264 | − // XK_kana_CHI | |
| 1265 | − 0x30c3: 0x04af, | |
| 1266 | − // XK_kana_tsu | |
| 1267 | − 0x30c4: 0x04c2, | |
| 1268 | − // XK_kana_TSU | |
| 1269 | − 0x30c6: 0x04c3, | |
| 1270 | − // XK_kana_TE | |
| 1271 | − 0x30c8: 0x04c4, | |
| 1272 | − // XK_kana_TO | |
| 1273 | − 0x30ca: 0x04c5, | |
| 1274 | − // XK_kana_NA | |
| 1275 | − 0x30cb: 0x04c6, | |
| 1276 | − // XK_kana_NI | |
| 1277 | − 0x30cc: 0x04c7, | |
| 1278 | − // XK_kana_NU | |
| 1279 | − 0x30cd: 0x04c8, | |
| 1280 | − // XK_kana_NE | |
| 1281 | − 0x30ce: 0x04c9, | |
| 1282 | − // XK_kana_NO | |
| 1283 | − 0x30cf: 0x04ca, | |
| 1284 | − // XK_kana_HA | |
| 1285 | − 0x30d2: 0x04cb, | |
| 1286 | − // XK_kana_HI | |
| 1287 | − 0x30d5: 0x04cc, | |
| 1288 | − // XK_kana_FU | |
| 1289 | − 0x30d8: 0x04cd, | |
| 1290 | − // XK_kana_HE | |
| 1291 | − 0x30db: 0x04ce, | |
| 1292 | − // XK_kana_HO | |
| 1293 | − 0x30de: 0x04cf, | |
| 1294 | − // XK_kana_MA | |
| 1295 | − 0x30df: 0x04d0, | |
| 1296 | − // XK_kana_MI | |
| 1297 | − 0x30e0: 0x04d1, | |
| 1298 | − // XK_kana_MU | |
| 1299 | − 0x30e1: 0x04d2, | |
| 1300 | − // XK_kana_ME | |
| 1301 | − 0x30e2: 0x04d3, | |
| 1302 | − // XK_kana_MO | |
| 1303 | − 0x30e3: 0x04ac, | |
| 1304 | − // XK_kana_ya | |
| 1305 | − 0x30e4: 0x04d4, | |
| 1306 | − // XK_kana_YA | |
| 1307 | − 0x30e5: 0x04ad, | |
| 1308 | − // XK_kana_yu | |
| 1309 | − 0x30e6: 0x04d5, | |
| 1310 | − // XK_kana_YU | |
| 1311 | − 0x30e7: 0x04ae, | |
| 1312 | − // XK_kana_yo | |
| 1313 | − 0x30e8: 0x04d6, | |
| 1314 | − // XK_kana_YO | |
| 1315 | − 0x30e9: 0x04d7, | |
| 1316 | − // XK_kana_RA | |
| 1317 | − 0x30ea: 0x04d8, | |
| 1318 | − // XK_kana_RI | |
| 1319 | − 0x30eb: 0x04d9, | |
| 1320 | − // XK_kana_RU | |
| 1321 | − 0x30ec: 0x04da, | |
| 1322 | − // XK_kana_RE | |
| 1323 | − 0x30ed: 0x04db, | |
| 1324 | − // XK_kana_RO | |
| 1325 | − 0x30ef: 0x04dc, | |
| 1326 | − // XK_kana_WA | |
| 1327 | − 0x30f2: 0x04a6, | |
| 1328 | − // XK_kana_WO | |
| 1329 | − 0x30f3: 0x04dd, | |
| 1330 | − // XK_kana_N | |
| 1331 | − 0x30fb: 0x04a5, | |
| 1332 | − // XK_kana_conjunctive | |
| 1333 | − 0x30fc: 0x04b0 // XK_prolongedsound | |
| 1334 | −}; | |
| 1335 | −var _default = exports["default"] = { | |
| 1336 | − lookup: function lookup(u) { | |
| 1337 | − // Latin-1 is one-to-one mapping | |
| 1338 | − if (u >= 0x20 && u <= 0xff) { | |
| 1339 | − return u; | |
| 1340 | − } | |
| 1341 | − | |
| 1342 | − // Lookup table (fairly random) | |
| 1343 | − var keysym = codepoints[u]; | |
| 1344 | − if (keysym !== undefined) { | |
| 1345 | − return keysym; | |
| 1346 | − } | |
| 1347 | − | |
| 1348 | − // General mapping as final fallback | |
| 1349 | − return 0x01000000 | u; | |
| 1350 | − } | |
| 1351 | −}; | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/input/util.js
+0 −217
@@ -1,217 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 4 | −Object.defineProperty(exports, "__esModule", { | |
| 5 | − value: true | |
| 6 | −}); | |
| 7 | −exports.getKey = getKey; | |
| 8 | −exports.getKeycode = getKeycode; | |
| 9 | −exports.getKeysym = getKeysym; | |
| 10 | −var _keysym = _interopRequireDefault(require("./keysym.js")); | |
| 11 | −var _keysymdef = _interopRequireDefault(require("./keysymdef.js")); | |
| 12 | −var _vkeys = _interopRequireDefault(require("./vkeys.js")); | |
| 13 | −var _fixedkeys = _interopRequireDefault(require("./fixedkeys.js")); | |
| 14 | −var _domkeytable = _interopRequireDefault(require("./domkeytable.js")); | |
| 15 | −var browser = _interopRequireWildcard(require("../util/browser.js")); | |
| 16 | −function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } | |
| 17 | −function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } | |
| 18 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 19 | −// Get 'KeyboardEvent.code', handling legacy browsers | |
| 20 | −function getKeycode(evt) { | |
| 21 | − // Are we getting proper key identifiers? | |
| 22 | − // (unfortunately Firefox and Chrome are crappy here and gives | |
| 23 | − // us an empty string on some platforms, rather than leaving it | |
| 24 | − // undefined) | |
| 25 | − if (evt.code) { | |
| 26 | − // Mozilla isn't fully in sync with the spec yet | |
| 27 | − switch (evt.code) { | |
| 28 | − case 'OSLeft': | |
| 29 | − return 'MetaLeft'; | |
| 30 | − case 'OSRight': | |
| 31 | − return 'MetaRight'; | |
| 32 | − } | |
| 33 | − return evt.code; | |
| 34 | − } | |
| 35 | − | |
| 36 | − // The de-facto standard is to use Windows Virtual-Key codes | |
| 37 | − // in the 'keyCode' field for non-printable characters | |
| 38 | − if (evt.keyCode in _vkeys["default"]) { | |
| 39 | − var code = _vkeys["default"][evt.keyCode]; | |
| 40 | − | |
| 41 | − // macOS has messed up this code for some reason | |
| 42 | − if (browser.isMac() && code === 'ContextMenu') { | |
| 43 | − code = 'MetaRight'; | |
| 44 | − } | |
| 45 | − | |
| 46 | − // The keyCode doesn't distinguish between left and right | |
| 47 | − // for the standard modifiers | |
| 48 | − if (evt.location === 2) { | |
| 49 | − switch (code) { | |
| 50 | − case 'ShiftLeft': | |
| 51 | − return 'ShiftRight'; | |
| 52 | − case 'ControlLeft': | |
| 53 | − return 'ControlRight'; | |
| 54 | − case 'AltLeft': | |
| 55 | − return 'AltRight'; | |
| 56 | − } | |
| 57 | − } | |
| 58 | − | |
| 59 | − // Nor a bunch of the numpad keys | |
| 60 | − if (evt.location === 3) { | |
| 61 | − switch (code) { | |
| 62 | − case 'Delete': | |
| 63 | − return 'NumpadDecimal'; | |
| 64 | − case 'Insert': | |
| 65 | − return 'Numpad0'; | |
| 66 | − case 'End': | |
| 67 | − return 'Numpad1'; | |
| 68 | − case 'ArrowDown': | |
| 69 | − return 'Numpad2'; | |
| 70 | − case 'PageDown': | |
| 71 | − return 'Numpad3'; | |
| 72 | − case 'ArrowLeft': | |
| 73 | − return 'Numpad4'; | |
| 74 | − case 'ArrowRight': | |
| 75 | − return 'Numpad6'; | |
| 76 | − case 'Home': | |
| 77 | − return 'Numpad7'; | |
| 78 | − case 'ArrowUp': | |
| 79 | − return 'Numpad8'; | |
| 80 | − case 'PageUp': | |
| 81 | − return 'Numpad9'; | |
| 82 | − case 'Enter': | |
| 83 | − return 'NumpadEnter'; | |
| 84 | − } | |
| 85 | − } | |
| 86 | − return code; | |
| 87 | − } | |
| 88 | − return 'Unidentified'; | |
| 89 | −} | |
| 90 | − | |
| 91 | −// Get 'KeyboardEvent.key', handling legacy browsers | |
| 92 | −function getKey(evt) { | |
| 93 | − // Are we getting a proper key value? | |
| 94 | − if (evt.key !== undefined && evt.key !== 'Unidentified') { | |
| 95 | − // Mozilla isn't fully in sync with the spec yet | |
| 96 | − switch (evt.key) { | |
| 97 | − case 'OS': | |
| 98 | − return 'Meta'; | |
| 99 | − case 'LaunchMyComputer': | |
| 100 | − return 'LaunchApplication1'; | |
| 101 | − case 'LaunchCalculator': | |
| 102 | − return 'LaunchApplication2'; | |
| 103 | − } | |
| 104 | − | |
| 105 | − // iOS leaks some OS names | |
| 106 | − switch (evt.key) { | |
| 107 | − case 'UIKeyInputUpArrow': | |
| 108 | − return 'ArrowUp'; | |
| 109 | − case 'UIKeyInputDownArrow': | |
| 110 | − return 'ArrowDown'; | |
| 111 | − case 'UIKeyInputLeftArrow': | |
| 112 | − return 'ArrowLeft'; | |
| 113 | − case 'UIKeyInputRightArrow': | |
| 114 | − return 'ArrowRight'; | |
| 115 | − case 'UIKeyInputEscape': | |
| 116 | − return 'Escape'; | |
| 117 | − } | |
| 118 | − | |
| 119 | − // Broken behaviour in Chrome | |
| 120 | − if (evt.key === '\x00' && evt.code === 'NumpadDecimal') { | |
| 121 | − return 'Delete'; | |
| 122 | − } | |
| 123 | − return evt.key; | |
| 124 | − } | |
| 125 | − | |
| 126 | − // Try to deduce it based on the physical key | |
| 127 | − var code = getKeycode(evt); | |
| 128 | − if (code in _fixedkeys["default"]) { | |
| 129 | − return _fixedkeys["default"][code]; | |
| 130 | − } | |
| 131 | − | |
| 132 | − // If that failed, then see if we have a printable character | |
| 133 | − if (evt.charCode) { | |
| 134 | − return String.fromCharCode(evt.charCode); | |
| 135 | − } | |
| 136 | − | |
| 137 | − // At this point we have nothing left to go on | |
| 138 | − return 'Unidentified'; | |
| 139 | −} | |
| 140 | − | |
| 141 | −// Get the most reliable keysym value we can get from a key event | |
| 142 | −function getKeysym(evt) { | |
| 143 | − var key = getKey(evt); | |
| 144 | − if (key === 'Unidentified') { | |
| 145 | − return null; | |
| 146 | − } | |
| 147 | − | |
| 148 | − // First look up special keys | |
| 149 | − if (key in _domkeytable["default"]) { | |
| 150 | − var location = evt.location; | |
| 151 | − | |
| 152 | − // Safari screws up location for the right cmd key | |
| 153 | − if (key === 'Meta' && location === 0) { | |
| 154 | − location = 2; | |
| 155 | − } | |
| 156 | − | |
| 157 | − // And for Clear | |
| 158 | − if (key === 'Clear' && location === 3) { | |
| 159 | − var code = getKeycode(evt); | |
| 160 | − if (code === 'NumLock') { | |
| 161 | − location = 0; | |
| 162 | − } | |
| 163 | − } | |
| 164 | − if (location === undefined || location > 3) { | |
| 165 | − location = 0; | |
| 166 | − } | |
| 167 | − | |
| 168 | − // The original Meta key now gets confused with the Windows key | |
| 169 | − // https://bugs.chromium.org/p/chromium/issues/detail?id=1020141 | |
| 170 | − // https://bugzilla.mozilla.org/show_bug.cgi?id=1232918 | |
| 171 | − if (key === 'Meta') { | |
| 172 | − var _code = getKeycode(evt); | |
| 173 | − if (_code === 'AltLeft') { | |
| 174 | − return _keysym["default"].XK_Meta_L; | |
| 175 | − } else if (_code === 'AltRight') { | |
| 176 | − return _keysym["default"].XK_Meta_R; | |
| 177 | − } | |
| 178 | − } | |
| 179 | − | |
| 180 | − // macOS has Clear instead of NumLock, but the remote system is | |
| 181 | − // probably not macOS, so lying here is probably best... | |
| 182 | − if (key === 'Clear') { | |
| 183 | − var _code2 = getKeycode(evt); | |
| 184 | − if (_code2 === 'NumLock') { | |
| 185 | − return _keysym["default"].XK_Num_Lock; | |
| 186 | − } | |
| 187 | − } | |
| 188 | − | |
| 189 | − // Windows sends alternating symbols for some keys when using a | |
| 190 | − // Japanese layout. We have no way of synchronising with the IM | |
| 191 | − // running on the remote system, so we send some combined keysym | |
| 192 | − // instead and hope for the best. | |
| 193 | − if (browser.isWindows()) { | |
| 194 | − switch (key) { | |
| 195 | − case 'Zenkaku': | |
| 196 | − case 'Hankaku': | |
| 197 | − return _keysym["default"].XK_Zenkaku_Hankaku; | |
| 198 | − case 'Romaji': | |
| 199 | − case 'KanaMode': | |
| 200 | − return _keysym["default"].XK_Romaji; | |
| 201 | − } | |
| 202 | − } | |
| 203 | − return _domkeytable["default"][key][location]; | |
| 204 | − } | |
| 205 | − | |
| 206 | − // Now we need to look at the Unicode symbol instead | |
| 207 | − | |
| 208 | − // Special key? (FIXME: Should have been caught earlier) | |
| 209 | − if (key.length !== 1) { | |
| 210 | − return null; | |
| 211 | − } | |
| 212 | − var codepoint = key.charCodeAt(); | |
| 213 | − if (codepoint) { | |
| 214 | − return _keysymdef["default"].lookup(codepoint); | |
| 215 | − } | |
| 216 | − return null; | |
| 217 | −} | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/input/vkeys.js
+0 −121
@@ -1,121 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −/* | |
| 8 | − * noVNC: HTML5 VNC client | |
| 9 | − * Copyright (C) 2018 The noVNC authors | |
| 10 | − * Licensed under MPL 2.0 or any later version (see LICENSE.txt) | |
| 11 | − */ | |
| 12 | −/* | |
| 13 | − * Mapping between Microsoft® Windows® Virtual-Key codes and | |
| 14 | − * HTML key codes. | |
| 15 | − */ | |
| 16 | −var _default = exports["default"] = { | |
| 17 | − 0x08: 'Backspace', | |
| 18 | − 0x09: 'Tab', | |
| 19 | − 0x0a: 'NumpadClear', | |
| 20 | − 0x0d: 'Enter', | |
| 21 | − 0x10: 'ShiftLeft', | |
| 22 | − 0x11: 'ControlLeft', | |
| 23 | − 0x12: 'AltLeft', | |
| 24 | − 0x13: 'Pause', | |
| 25 | − 0x14: 'CapsLock', | |
| 26 | − 0x15: 'Lang1', | |
| 27 | − 0x19: 'Lang2', | |
| 28 | − 0x1b: 'Escape', | |
| 29 | − 0x1c: 'Convert', | |
| 30 | − 0x1d: 'NonConvert', | |
| 31 | − 0x20: 'Space', | |
| 32 | − 0x21: 'PageUp', | |
| 33 | − 0x22: 'PageDown', | |
| 34 | − 0x23: 'End', | |
| 35 | − 0x24: 'Home', | |
| 36 | − 0x25: 'ArrowLeft', | |
| 37 | − 0x26: 'ArrowUp', | |
| 38 | − 0x27: 'ArrowRight', | |
| 39 | − 0x28: 'ArrowDown', | |
| 40 | − 0x29: 'Select', | |
| 41 | − 0x2c: 'PrintScreen', | |
| 42 | − 0x2d: 'Insert', | |
| 43 | − 0x2e: 'Delete', | |
| 44 | − 0x2f: 'Help', | |
| 45 | − 0x30: 'Digit0', | |
| 46 | − 0x31: 'Digit1', | |
| 47 | − 0x32: 'Digit2', | |
| 48 | − 0x33: 'Digit3', | |
| 49 | − 0x34: 'Digit4', | |
| 50 | − 0x35: 'Digit5', | |
| 51 | − 0x36: 'Digit6', | |
| 52 | − 0x37: 'Digit7', | |
| 53 | − 0x38: 'Digit8', | |
| 54 | − 0x39: 'Digit9', | |
| 55 | − 0x5b: 'MetaLeft', | |
| 56 | − 0x5c: 'MetaRight', | |
| 57 | − 0x5d: 'ContextMenu', | |
| 58 | − 0x5f: 'Sleep', | |
| 59 | − 0x60: 'Numpad0', | |
| 60 | − 0x61: 'Numpad1', | |
| 61 | − 0x62: 'Numpad2', | |
| 62 | − 0x63: 'Numpad3', | |
| 63 | − 0x64: 'Numpad4', | |
| 64 | − 0x65: 'Numpad5', | |
| 65 | − 0x66: 'Numpad6', | |
| 66 | − 0x67: 'Numpad7', | |
| 67 | − 0x68: 'Numpad8', | |
| 68 | − 0x69: 'Numpad9', | |
| 69 | − 0x6a: 'NumpadMultiply', | |
| 70 | − 0x6b: 'NumpadAdd', | |
| 71 | − 0x6c: 'NumpadDecimal', | |
| 72 | − 0x6d: 'NumpadSubtract', | |
| 73 | − 0x6e: 'NumpadDecimal', | |
| 74 | − // Duplicate, because buggy on Windows | |
| 75 | − 0x6f: 'NumpadDivide', | |
| 76 | − 0x70: 'F1', | |
| 77 | − 0x71: 'F2', | |
| 78 | − 0x72: 'F3', | |
| 79 | − 0x73: 'F4', | |
| 80 | − 0x74: 'F5', | |
| 81 | − 0x75: 'F6', | |
| 82 | − 0x76: 'F7', | |
| 83 | − 0x77: 'F8', | |
| 84 | − 0x78: 'F9', | |
| 85 | − 0x79: 'F10', | |
| 86 | − 0x7a: 'F11', | |
| 87 | − 0x7b: 'F12', | |
| 88 | − 0x7c: 'F13', | |
| 89 | − 0x7d: 'F14', | |
| 90 | − 0x7e: 'F15', | |
| 91 | − 0x7f: 'F16', | |
| 92 | − 0x80: 'F17', | |
| 93 | − 0x81: 'F18', | |
| 94 | − 0x82: 'F19', | |
| 95 | − 0x83: 'F20', | |
| 96 | − 0x84: 'F21', | |
| 97 | − 0x85: 'F22', | |
| 98 | − 0x86: 'F23', | |
| 99 | − 0x87: 'F24', | |
| 100 | − 0x90: 'NumLock', | |
| 101 | − 0x91: 'ScrollLock', | |
| 102 | − 0xa6: 'BrowserBack', | |
| 103 | − 0xa7: 'BrowserForward', | |
| 104 | − 0xa8: 'BrowserRefresh', | |
| 105 | − 0xa9: 'BrowserStop', | |
| 106 | − 0xaa: 'BrowserSearch', | |
| 107 | − 0xab: 'BrowserFavorites', | |
| 108 | − 0xac: 'BrowserHome', | |
| 109 | − 0xad: 'AudioVolumeMute', | |
| 110 | − 0xae: 'AudioVolumeDown', | |
| 111 | − 0xaf: 'AudioVolumeUp', | |
| 112 | − 0xb0: 'MediaTrackNext', | |
| 113 | − 0xb1: 'MediaTrackPrevious', | |
| 114 | − 0xb2: 'MediaStop', | |
| 115 | − 0xb3: 'MediaPlayPause', | |
| 116 | − 0xb4: 'LaunchMail', | |
| 117 | − 0xb5: 'MediaSelect', | |
| 118 | − 0xb6: 'LaunchApp1', | |
| 119 | − 0xb7: 'LaunchApp2', | |
| 120 | − 0xe1: 'AltRight' // Only when it is AltGraph | |
| 121 | −}; | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/input/xtscancodes.js
+0 −343
@@ -1,343 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −/* | |
| 8 | − * This file is auto-generated from keymaps.csv | |
| 9 | − * Database checksum sha256(76d68c10e97d37fe2ea459e210125ae41796253fb217e900bf2983ade13a7920) | |
| 10 | − * To re-generate, run: | |
| 11 | − * keymap-gen code-map --lang=js keymaps.csv html atset1 | |
| 12 | −*/ | |
| 13 | −var _default = exports["default"] = { | |
| 14 | − "Again": 0xe005, | |
| 15 | − /* html:Again (Again) -> linux:129 (KEY_AGAIN) -> atset1:57349 */ | |
| 16 | − "AltLeft": 0x38, | |
| 17 | − /* html:AltLeft (AltLeft) -> linux:56 (KEY_LEFTALT) -> atset1:56 */ | |
| 18 | − "AltRight": 0xe038, | |
| 19 | − /* html:AltRight (AltRight) -> linux:100 (KEY_RIGHTALT) -> atset1:57400 */ | |
| 20 | − "ArrowDown": 0xe050, | |
| 21 | − /* html:ArrowDown (ArrowDown) -> linux:108 (KEY_DOWN) -> atset1:57424 */ | |
| 22 | − "ArrowLeft": 0xe04b, | |
| 23 | − /* html:ArrowLeft (ArrowLeft) -> linux:105 (KEY_LEFT) -> atset1:57419 */ | |
| 24 | − "ArrowRight": 0xe04d, | |
| 25 | − /* html:ArrowRight (ArrowRight) -> linux:106 (KEY_RIGHT) -> atset1:57421 */ | |
| 26 | − "ArrowUp": 0xe048, | |
| 27 | − /* html:ArrowUp (ArrowUp) -> linux:103 (KEY_UP) -> atset1:57416 */ | |
| 28 | − "AudioVolumeDown": 0xe02e, | |
| 29 | − /* html:AudioVolumeDown (AudioVolumeDown) -> linux:114 (KEY_VOLUMEDOWN) -> atset1:57390 */ | |
| 30 | − "AudioVolumeMute": 0xe020, | |
| 31 | − /* html:AudioVolumeMute (AudioVolumeMute) -> linux:113 (KEY_MUTE) -> atset1:57376 */ | |
| 32 | − "AudioVolumeUp": 0xe030, | |
| 33 | − /* html:AudioVolumeUp (AudioVolumeUp) -> linux:115 (KEY_VOLUMEUP) -> atset1:57392 */ | |
| 34 | − "Backquote": 0x29, | |
| 35 | − /* html:Backquote (Backquote) -> linux:41 (KEY_GRAVE) -> atset1:41 */ | |
| 36 | − "Backslash": 0x2b, | |
| 37 | − /* html:Backslash (Backslash) -> linux:43 (KEY_BACKSLASH) -> atset1:43 */ | |
| 38 | − "Backspace": 0xe, | |
| 39 | − /* html:Backspace (Backspace) -> linux:14 (KEY_BACKSPACE) -> atset1:14 */ | |
| 40 | − "BracketLeft": 0x1a, | |
| 41 | − /* html:BracketLeft (BracketLeft) -> linux:26 (KEY_LEFTBRACE) -> atset1:26 */ | |
| 42 | − "BracketRight": 0x1b, | |
| 43 | − /* html:BracketRight (BracketRight) -> linux:27 (KEY_RIGHTBRACE) -> atset1:27 */ | |
| 44 | − "BrowserBack": 0xe06a, | |
| 45 | − /* html:BrowserBack (BrowserBack) -> linux:158 (KEY_BACK) -> atset1:57450 */ | |
| 46 | − "BrowserFavorites": 0xe066, | |
| 47 | − /* html:BrowserFavorites (BrowserFavorites) -> linux:156 (KEY_BOOKMARKS) -> atset1:57446 */ | |
| 48 | − "BrowserForward": 0xe069, | |
| 49 | − /* html:BrowserForward (BrowserForward) -> linux:159 (KEY_FORWARD) -> atset1:57449 */ | |
| 50 | − "BrowserHome": 0xe032, | |
| 51 | − /* html:BrowserHome (BrowserHome) -> linux:172 (KEY_HOMEPAGE) -> atset1:57394 */ | |
| 52 | − "BrowserRefresh": 0xe067, | |
| 53 | − /* html:BrowserRefresh (BrowserRefresh) -> linux:173 (KEY_REFRESH) -> atset1:57447 */ | |
| 54 | − "BrowserSearch": 0xe065, | |
| 55 | − /* html:BrowserSearch (BrowserSearch) -> linux:217 (KEY_SEARCH) -> atset1:57445 */ | |
| 56 | − "BrowserStop": 0xe068, | |
| 57 | − /* html:BrowserStop (BrowserStop) -> linux:128 (KEY_STOP) -> atset1:57448 */ | |
| 58 | − "CapsLock": 0x3a, | |
| 59 | − /* html:CapsLock (CapsLock) -> linux:58 (KEY_CAPSLOCK) -> atset1:58 */ | |
| 60 | − "Comma": 0x33, | |
| 61 | − /* html:Comma (Comma) -> linux:51 (KEY_COMMA) -> atset1:51 */ | |
| 62 | − "ContextMenu": 0xe05d, | |
| 63 | − /* html:ContextMenu (ContextMenu) -> linux:127 (KEY_COMPOSE) -> atset1:57437 */ | |
| 64 | − "ControlLeft": 0x1d, | |
| 65 | − /* html:ControlLeft (ControlLeft) -> linux:29 (KEY_LEFTCTRL) -> atset1:29 */ | |
| 66 | − "ControlRight": 0xe01d, | |
| 67 | − /* html:ControlRight (ControlRight) -> linux:97 (KEY_RIGHTCTRL) -> atset1:57373 */ | |
| 68 | − "Convert": 0x79, | |
| 69 | − /* html:Convert (Convert) -> linux:92 (KEY_HENKAN) -> atset1:121 */ | |
| 70 | − "Copy": 0xe078, | |
| 71 | − /* html:Copy (Copy) -> linux:133 (KEY_COPY) -> atset1:57464 */ | |
| 72 | − "Cut": 0xe03c, | |
| 73 | − /* html:Cut (Cut) -> linux:137 (KEY_CUT) -> atset1:57404 */ | |
| 74 | − "Delete": 0xe053, | |
| 75 | − /* html:Delete (Delete) -> linux:111 (KEY_DELETE) -> atset1:57427 */ | |
| 76 | − "Digit0": 0xb, | |
| 77 | − /* html:Digit0 (Digit0) -> linux:11 (KEY_0) -> atset1:11 */ | |
| 78 | − "Digit1": 0x2, | |
| 79 | − /* html:Digit1 (Digit1) -> linux:2 (KEY_1) -> atset1:2 */ | |
| 80 | − "Digit2": 0x3, | |
| 81 | − /* html:Digit2 (Digit2) -> linux:3 (KEY_2) -> atset1:3 */ | |
| 82 | − "Digit3": 0x4, | |
| 83 | − /* html:Digit3 (Digit3) -> linux:4 (KEY_3) -> atset1:4 */ | |
| 84 | − "Digit4": 0x5, | |
| 85 | − /* html:Digit4 (Digit4) -> linux:5 (KEY_4) -> atset1:5 */ | |
| 86 | − "Digit5": 0x6, | |
| 87 | − /* html:Digit5 (Digit5) -> linux:6 (KEY_5) -> atset1:6 */ | |
| 88 | − "Digit6": 0x7, | |
| 89 | − /* html:Digit6 (Digit6) -> linux:7 (KEY_6) -> atset1:7 */ | |
| 90 | − "Digit7": 0x8, | |
| 91 | − /* html:Digit7 (Digit7) -> linux:8 (KEY_7) -> atset1:8 */ | |
| 92 | − "Digit8": 0x9, | |
| 93 | − /* html:Digit8 (Digit8) -> linux:9 (KEY_8) -> atset1:9 */ | |
| 94 | − "Digit9": 0xa, | |
| 95 | − /* html:Digit9 (Digit9) -> linux:10 (KEY_9) -> atset1:10 */ | |
| 96 | − "Eject": 0xe07d, | |
| 97 | − /* html:Eject (Eject) -> linux:162 (KEY_EJECTCLOSECD) -> atset1:57469 */ | |
| 98 | − "End": 0xe04f, | |
| 99 | − /* html:End (End) -> linux:107 (KEY_END) -> atset1:57423 */ | |
| 100 | − "Enter": 0x1c, | |
| 101 | − /* html:Enter (Enter) -> linux:28 (KEY_ENTER) -> atset1:28 */ | |
| 102 | − "Equal": 0xd, | |
| 103 | − /* html:Equal (Equal) -> linux:13 (KEY_EQUAL) -> atset1:13 */ | |
| 104 | − "Escape": 0x1, | |
| 105 | − /* html:Escape (Escape) -> linux:1 (KEY_ESC) -> atset1:1 */ | |
| 106 | − "F1": 0x3b, | |
| 107 | − /* html:F1 (F1) -> linux:59 (KEY_F1) -> atset1:59 */ | |
| 108 | − "F10": 0x44, | |
| 109 | − /* html:F10 (F10) -> linux:68 (KEY_F10) -> atset1:68 */ | |
| 110 | − "F11": 0x57, | |
| 111 | − /* html:F11 (F11) -> linux:87 (KEY_F11) -> atset1:87 */ | |
| 112 | − "F12": 0x58, | |
| 113 | − /* html:F12 (F12) -> linux:88 (KEY_F12) -> atset1:88 */ | |
| 114 | − "F13": 0x5d, | |
| 115 | − /* html:F13 (F13) -> linux:183 (KEY_F13) -> atset1:93 */ | |
| 116 | − "F14": 0x5e, | |
| 117 | − /* html:F14 (F14) -> linux:184 (KEY_F14) -> atset1:94 */ | |
| 118 | − "F15": 0x5f, | |
| 119 | − /* html:F15 (F15) -> linux:185 (KEY_F15) -> atset1:95 */ | |
| 120 | − "F16": 0x55, | |
| 121 | − /* html:F16 (F16) -> linux:186 (KEY_F16) -> atset1:85 */ | |
| 122 | − "F17": 0xe003, | |
| 123 | − /* html:F17 (F17) -> linux:187 (KEY_F17) -> atset1:57347 */ | |
| 124 | − "F18": 0xe077, | |
| 125 | − /* html:F18 (F18) -> linux:188 (KEY_F18) -> atset1:57463 */ | |
| 126 | − "F19": 0xe004, | |
| 127 | − /* html:F19 (F19) -> linux:189 (KEY_F19) -> atset1:57348 */ | |
| 128 | − "F2": 0x3c, | |
| 129 | − /* html:F2 (F2) -> linux:60 (KEY_F2) -> atset1:60 */ | |
| 130 | − "F20": 0x5a, | |
| 131 | − /* html:F20 (F20) -> linux:190 (KEY_F20) -> atset1:90 */ | |
| 132 | − "F21": 0x74, | |
| 133 | − /* html:F21 (F21) -> linux:191 (KEY_F21) -> atset1:116 */ | |
| 134 | − "F22": 0xe079, | |
| 135 | − /* html:F22 (F22) -> linux:192 (KEY_F22) -> atset1:57465 */ | |
| 136 | − "F23": 0x6d, | |
| 137 | − /* html:F23 (F23) -> linux:193 (KEY_F23) -> atset1:109 */ | |
| 138 | − "F24": 0x6f, | |
| 139 | − /* html:F24 (F24) -> linux:194 (KEY_F24) -> atset1:111 */ | |
| 140 | − "F3": 0x3d, | |
| 141 | − /* html:F3 (F3) -> linux:61 (KEY_F3) -> atset1:61 */ | |
| 142 | − "F4": 0x3e, | |
| 143 | − /* html:F4 (F4) -> linux:62 (KEY_F4) -> atset1:62 */ | |
| 144 | − "F5": 0x3f, | |
| 145 | − /* html:F5 (F5) -> linux:63 (KEY_F5) -> atset1:63 */ | |
| 146 | − "F6": 0x40, | |
| 147 | − /* html:F6 (F6) -> linux:64 (KEY_F6) -> atset1:64 */ | |
| 148 | − "F7": 0x41, | |
| 149 | − /* html:F7 (F7) -> linux:65 (KEY_F7) -> atset1:65 */ | |
| 150 | − "F8": 0x42, | |
| 151 | − /* html:F8 (F8) -> linux:66 (KEY_F8) -> atset1:66 */ | |
| 152 | − "F9": 0x43, | |
| 153 | − /* html:F9 (F9) -> linux:67 (KEY_F9) -> atset1:67 */ | |
| 154 | − "Find": 0xe041, | |
| 155 | − /* html:Find (Find) -> linux:136 (KEY_FIND) -> atset1:57409 */ | |
| 156 | − "Help": 0xe075, | |
| 157 | − /* html:Help (Help) -> linux:138 (KEY_HELP) -> atset1:57461 */ | |
| 158 | − "Hiragana": 0x77, | |
| 159 | − /* html:Hiragana (Lang4) -> linux:91 (KEY_HIRAGANA) -> atset1:119 */ | |
| 160 | − "Home": 0xe047, | |
| 161 | − /* html:Home (Home) -> linux:102 (KEY_HOME) -> atset1:57415 */ | |
| 162 | − "Insert": 0xe052, | |
| 163 | − /* html:Insert (Insert) -> linux:110 (KEY_INSERT) -> atset1:57426 */ | |
| 164 | − "IntlBackslash": 0x56, | |
| 165 | − /* html:IntlBackslash (IntlBackslash) -> linux:86 (KEY_102ND) -> atset1:86 */ | |
| 166 | − "IntlRo": 0x73, | |
| 167 | − /* html:IntlRo (IntlRo) -> linux:89 (KEY_RO) -> atset1:115 */ | |
| 168 | − "IntlYen": 0x7d, | |
| 169 | − /* html:IntlYen (IntlYen) -> linux:124 (KEY_YEN) -> atset1:125 */ | |
| 170 | − "KanaMode": 0x70, | |
| 171 | − /* html:KanaMode (KanaMode) -> linux:93 (KEY_KATAKANAHIRAGANA) -> atset1:112 */ | |
| 172 | − "Katakana": 0x78, | |
| 173 | − /* html:Katakana (Lang3) -> linux:90 (KEY_KATAKANA) -> atset1:120 */ | |
| 174 | − "KeyA": 0x1e, | |
| 175 | − /* html:KeyA (KeyA) -> linux:30 (KEY_A) -> atset1:30 */ | |
| 176 | − "KeyB": 0x30, | |
| 177 | − /* html:KeyB (KeyB) -> linux:48 (KEY_B) -> atset1:48 */ | |
| 178 | − "KeyC": 0x2e, | |
| 179 | − /* html:KeyC (KeyC) -> linux:46 (KEY_C) -> atset1:46 */ | |
| 180 | − "KeyD": 0x20, | |
| 181 | − /* html:KeyD (KeyD) -> linux:32 (KEY_D) -> atset1:32 */ | |
| 182 | − "KeyE": 0x12, | |
| 183 | − /* html:KeyE (KeyE) -> linux:18 (KEY_E) -> atset1:18 */ | |
| 184 | − "KeyF": 0x21, | |
| 185 | − /* html:KeyF (KeyF) -> linux:33 (KEY_F) -> atset1:33 */ | |
| 186 | − "KeyG": 0x22, | |
| 187 | − /* html:KeyG (KeyG) -> linux:34 (KEY_G) -> atset1:34 */ | |
| 188 | − "KeyH": 0x23, | |
| 189 | − /* html:KeyH (KeyH) -> linux:35 (KEY_H) -> atset1:35 */ | |
| 190 | − "KeyI": 0x17, | |
| 191 | − /* html:KeyI (KeyI) -> linux:23 (KEY_I) -> atset1:23 */ | |
| 192 | − "KeyJ": 0x24, | |
| 193 | − /* html:KeyJ (KeyJ) -> linux:36 (KEY_J) -> atset1:36 */ | |
| 194 | − "KeyK": 0x25, | |
| 195 | − /* html:KeyK (KeyK) -> linux:37 (KEY_K) -> atset1:37 */ | |
| 196 | − "KeyL": 0x26, | |
| 197 | − /* html:KeyL (KeyL) -> linux:38 (KEY_L) -> atset1:38 */ | |
| 198 | − "KeyM": 0x32, | |
| 199 | − /* html:KeyM (KeyM) -> linux:50 (KEY_M) -> atset1:50 */ | |
| 200 | − "KeyN": 0x31, | |
| 201 | − /* html:KeyN (KeyN) -> linux:49 (KEY_N) -> atset1:49 */ | |
| 202 | − "KeyO": 0x18, | |
| 203 | − /* html:KeyO (KeyO) -> linux:24 (KEY_O) -> atset1:24 */ | |
| 204 | − "KeyP": 0x19, | |
| 205 | − /* html:KeyP (KeyP) -> linux:25 (KEY_P) -> atset1:25 */ | |
| 206 | − "KeyQ": 0x10, | |
| 207 | − /* html:KeyQ (KeyQ) -> linux:16 (KEY_Q) -> atset1:16 */ | |
| 208 | − "KeyR": 0x13, | |
| 209 | − /* html:KeyR (KeyR) -> linux:19 (KEY_R) -> atset1:19 */ | |
| 210 | − "KeyS": 0x1f, | |
| 211 | − /* html:KeyS (KeyS) -> linux:31 (KEY_S) -> atset1:31 */ | |
| 212 | − "KeyT": 0x14, | |
| 213 | − /* html:KeyT (KeyT) -> linux:20 (KEY_T) -> atset1:20 */ | |
| 214 | − "KeyU": 0x16, | |
| 215 | − /* html:KeyU (KeyU) -> linux:22 (KEY_U) -> atset1:22 */ | |
| 216 | − "KeyV": 0x2f, | |
| 217 | − /* html:KeyV (KeyV) -> linux:47 (KEY_V) -> atset1:47 */ | |
| 218 | − "KeyW": 0x11, | |
| 219 | − /* html:KeyW (KeyW) -> linux:17 (KEY_W) -> atset1:17 */ | |
| 220 | − "KeyX": 0x2d, | |
| 221 | − /* html:KeyX (KeyX) -> linux:45 (KEY_X) -> atset1:45 */ | |
| 222 | − "KeyY": 0x15, | |
| 223 | − /* html:KeyY (KeyY) -> linux:21 (KEY_Y) -> atset1:21 */ | |
| 224 | − "KeyZ": 0x2c, | |
| 225 | − /* html:KeyZ (KeyZ) -> linux:44 (KEY_Z) -> atset1:44 */ | |
| 226 | − "Lang1": 0x72, | |
| 227 | − /* html:Lang1 (Lang1) -> linux:122 (KEY_HANGEUL) -> atset1:114 */ | |
| 228 | − "Lang2": 0x71, | |
| 229 | − /* html:Lang2 (Lang2) -> linux:123 (KEY_HANJA) -> atset1:113 */ | |
| 230 | − "Lang3": 0x78, | |
| 231 | − /* html:Lang3 (Lang3) -> linux:90 (KEY_KATAKANA) -> atset1:120 */ | |
| 232 | − "Lang4": 0x77, | |
| 233 | − /* html:Lang4 (Lang4) -> linux:91 (KEY_HIRAGANA) -> atset1:119 */ | |
| 234 | − "Lang5": 0x76, | |
| 235 | − /* html:Lang5 (Lang5) -> linux:85 (KEY_ZENKAKUHANKAKU) -> atset1:118 */ | |
| 236 | − "LaunchApp1": 0xe06b, | |
| 237 | − /* html:LaunchApp1 (LaunchApp1) -> linux:157 (KEY_COMPUTER) -> atset1:57451 */ | |
| 238 | − "LaunchApp2": 0xe021, | |
| 239 | − /* html:LaunchApp2 (LaunchApp2) -> linux:140 (KEY_CALC) -> atset1:57377 */ | |
| 240 | − "LaunchMail": 0xe06c, | |
| 241 | − /* html:LaunchMail (LaunchMail) -> linux:155 (KEY_MAIL) -> atset1:57452 */ | |
| 242 | − "MediaPlayPause": 0xe022, | |
| 243 | − /* html:MediaPlayPause (MediaPlayPause) -> linux:164 (KEY_PLAYPAUSE) -> atset1:57378 */ | |
| 244 | − "MediaSelect": 0xe06d, | |
| 245 | − /* html:MediaSelect (MediaSelect) -> linux:226 (KEY_MEDIA) -> atset1:57453 */ | |
| 246 | − "MediaStop": 0xe024, | |
| 247 | − /* html:MediaStop (MediaStop) -> linux:166 (KEY_STOPCD) -> atset1:57380 */ | |
| 248 | − "MediaTrackNext": 0xe019, | |
| 249 | − /* html:MediaTrackNext (MediaTrackNext) -> linux:163 (KEY_NEXTSONG) -> atset1:57369 */ | |
| 250 | − "MediaTrackPrevious": 0xe010, | |
| 251 | − /* html:MediaTrackPrevious (MediaTrackPrevious) -> linux:165 (KEY_PREVIOUSSONG) -> atset1:57360 */ | |
| 252 | − "MetaLeft": 0xe05b, | |
| 253 | − /* html:MetaLeft (MetaLeft) -> linux:125 (KEY_LEFTMETA) -> atset1:57435 */ | |
| 254 | − "MetaRight": 0xe05c, | |
| 255 | − /* html:MetaRight (MetaRight) -> linux:126 (KEY_RIGHTMETA) -> atset1:57436 */ | |
| 256 | − "Minus": 0xc, | |
| 257 | − /* html:Minus (Minus) -> linux:12 (KEY_MINUS) -> atset1:12 */ | |
| 258 | − "NonConvert": 0x7b, | |
| 259 | − /* html:NonConvert (NonConvert) -> linux:94 (KEY_MUHENKAN) -> atset1:123 */ | |
| 260 | − "NumLock": 0x45, | |
| 261 | − /* html:NumLock (NumLock) -> linux:69 (KEY_NUMLOCK) -> atset1:69 */ | |
| 262 | − "Numpad0": 0x52, | |
| 263 | − /* html:Numpad0 (Numpad0) -> linux:82 (KEY_KP0) -> atset1:82 */ | |
| 264 | − "Numpad1": 0x4f, | |
| 265 | − /* html:Numpad1 (Numpad1) -> linux:79 (KEY_KP1) -> atset1:79 */ | |
| 266 | − "Numpad2": 0x50, | |
| 267 | − /* html:Numpad2 (Numpad2) -> linux:80 (KEY_KP2) -> atset1:80 */ | |
| 268 | − "Numpad3": 0x51, | |
| 269 | − /* html:Numpad3 (Numpad3) -> linux:81 (KEY_KP3) -> atset1:81 */ | |
| 270 | − "Numpad4": 0x4b, | |
| 271 | − /* html:Numpad4 (Numpad4) -> linux:75 (KEY_KP4) -> atset1:75 */ | |
| 272 | − "Numpad5": 0x4c, | |
| 273 | − /* html:Numpad5 (Numpad5) -> linux:76 (KEY_KP5) -> atset1:76 */ | |
| 274 | − "Numpad6": 0x4d, | |
| 275 | − /* html:Numpad6 (Numpad6) -> linux:77 (KEY_KP6) -> atset1:77 */ | |
| 276 | − "Numpad7": 0x47, | |
| 277 | − /* html:Numpad7 (Numpad7) -> linux:71 (KEY_KP7) -> atset1:71 */ | |
| 278 | − "Numpad8": 0x48, | |
| 279 | − /* html:Numpad8 (Numpad8) -> linux:72 (KEY_KP8) -> atset1:72 */ | |
| 280 | − "Numpad9": 0x49, | |
| 281 | − /* html:Numpad9 (Numpad9) -> linux:73 (KEY_KP9) -> atset1:73 */ | |
| 282 | − "NumpadAdd": 0x4e, | |
| 283 | − /* html:NumpadAdd (NumpadAdd) -> linux:78 (KEY_KPPLUS) -> atset1:78 */ | |
| 284 | − "NumpadComma": 0x7e, | |
| 285 | − /* html:NumpadComma (NumpadComma) -> linux:121 (KEY_KPCOMMA) -> atset1:126 */ | |
| 286 | − "NumpadDecimal": 0x53, | |
| 287 | − /* html:NumpadDecimal (NumpadDecimal) -> linux:83 (KEY_KPDOT) -> atset1:83 */ | |
| 288 | − "NumpadDivide": 0xe035, | |
| 289 | − /* html:NumpadDivide (NumpadDivide) -> linux:98 (KEY_KPSLASH) -> atset1:57397 */ | |
| 290 | − "NumpadEnter": 0xe01c, | |
| 291 | − /* html:NumpadEnter (NumpadEnter) -> linux:96 (KEY_KPENTER) -> atset1:57372 */ | |
| 292 | − "NumpadEqual": 0x59, | |
| 293 | − /* html:NumpadEqual (NumpadEqual) -> linux:117 (KEY_KPEQUAL) -> atset1:89 */ | |
| 294 | − "NumpadMultiply": 0x37, | |
| 295 | − /* html:NumpadMultiply (NumpadMultiply) -> linux:55 (KEY_KPASTERISK) -> atset1:55 */ | |
| 296 | − "NumpadParenLeft": 0xe076, | |
| 297 | − /* html:NumpadParenLeft (NumpadParenLeft) -> linux:179 (KEY_KPLEFTPAREN) -> atset1:57462 */ | |
| 298 | − "NumpadParenRight": 0xe07b, | |
| 299 | − /* html:NumpadParenRight (NumpadParenRight) -> linux:180 (KEY_KPRIGHTPAREN) -> atset1:57467 */ | |
| 300 | − "NumpadSubtract": 0x4a, | |
| 301 | − /* html:NumpadSubtract (NumpadSubtract) -> linux:74 (KEY_KPMINUS) -> atset1:74 */ | |
| 302 | − "Open": 0x64, | |
| 303 | − /* html:Open (Open) -> linux:134 (KEY_OPEN) -> atset1:100 */ | |
| 304 | − "PageDown": 0xe051, | |
| 305 | − /* html:PageDown (PageDown) -> linux:109 (KEY_PAGEDOWN) -> atset1:57425 */ | |
| 306 | − "PageUp": 0xe049, | |
| 307 | − /* html:PageUp (PageUp) -> linux:104 (KEY_PAGEUP) -> atset1:57417 */ | |
| 308 | − "Paste": 0x65, | |
| 309 | − /* html:Paste (Paste) -> linux:135 (KEY_PASTE) -> atset1:101 */ | |
| 310 | − "Pause": 0xe046, | |
| 311 | − /* html:Pause (Pause) -> linux:119 (KEY_PAUSE) -> atset1:57414 */ | |
| 312 | − "Period": 0x34, | |
| 313 | − /* html:Period (Period) -> linux:52 (KEY_DOT) -> atset1:52 */ | |
| 314 | − "Power": 0xe05e, | |
| 315 | − /* html:Power (Power) -> linux:116 (KEY_POWER) -> atset1:57438 */ | |
| 316 | − "PrintScreen": 0x54, | |
| 317 | − /* html:PrintScreen (PrintScreen) -> linux:99 (KEY_SYSRQ) -> atset1:84 */ | |
| 318 | − "Props": 0xe006, | |
| 319 | − /* html:Props (Props) -> linux:130 (KEY_PROPS) -> atset1:57350 */ | |
| 320 | − "Quote": 0x28, | |
| 321 | − /* html:Quote (Quote) -> linux:40 (KEY_APOSTROPHE) -> atset1:40 */ | |
| 322 | − "ScrollLock": 0x46, | |
| 323 | − /* html:ScrollLock (ScrollLock) -> linux:70 (KEY_SCROLLLOCK) -> atset1:70 */ | |
| 324 | − "Semicolon": 0x27, | |
| 325 | − /* html:Semicolon (Semicolon) -> linux:39 (KEY_SEMICOLON) -> atset1:39 */ | |
| 326 | − "ShiftLeft": 0x2a, | |
| 327 | − /* html:ShiftLeft (ShiftLeft) -> linux:42 (KEY_LEFTSHIFT) -> atset1:42 */ | |
| 328 | − "ShiftRight": 0x36, | |
| 329 | − /* html:ShiftRight (ShiftRight) -> linux:54 (KEY_RIGHTSHIFT) -> atset1:54 */ | |
| 330 | − "Slash": 0x35, | |
| 331 | − /* html:Slash (Slash) -> linux:53 (KEY_SLASH) -> atset1:53 */ | |
| 332 | − "Sleep": 0xe05f, | |
| 333 | − /* html:Sleep (Sleep) -> linux:142 (KEY_SLEEP) -> atset1:57439 */ | |
| 334 | − "Space": 0x39, | |
| 335 | − /* html:Space (Space) -> linux:57 (KEY_SPACE) -> atset1:57 */ | |
| 336 | − "Suspend": 0xe025, | |
| 337 | − /* html:Suspend (Suspend) -> linux:205 (KEY_SUSPEND) -> atset1:57381 */ | |
| 338 | − "Tab": 0xf, | |
| 339 | − /* html:Tab (Tab) -> linux:15 (KEY_TAB) -> atset1:15 */ | |
| 340 | − "Undo": 0xe007, | |
| 341 | − /* html:Undo (Undo) -> linux:131 (KEY_UNDO) -> atset1:57351 */ | |
| 342 | − "WakeUp": 0xe063 /* html:WakeUp (WakeUp) -> linux:143 (KEY_WAKEUP) -> atset1:57443 */ | |
| 343 | −}; | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/ra2.js
+0 −535
@@ -1,535 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −Object.defineProperty(exports, "__esModule", { | |
| 4 | − value: true | |
| 5 | −}); | |
| 6 | −exports["default"] = void 0; | |
| 7 | −var _strings = require("./util/strings.js"); | |
| 8 | −var _eventtarget = _interopRequireDefault(require("./util/eventtarget.js")); | |
| 9 | −var _crypto = _interopRequireDefault(require("./crypto/crypto.js")); | |
| 10 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 11 | −function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } | |
| 12 | −function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); } | |
| 13 | −function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } | |
| 14 | −function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } | |
| 15 | −function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } | |
| 16 | −function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); } | |
| 17 | −function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } | |
| 18 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 19 | −function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } | |
| 20 | −function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } | |
| 21 | −function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } | |
| 22 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 23 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 24 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 25 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 26 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 27 | −var RA2Cipher = /*#__PURE__*/function () { | |
| 28 | − function RA2Cipher() { | |
| 29 | − _classCallCheck(this, RA2Cipher); | |
| 30 | − this._cipher = null; | |
| 31 | − this._counter = new Uint8Array(16); | |
| 32 | − } | |
| 33 | − return _createClass(RA2Cipher, [{ | |
| 34 | − key: "setKey", | |
| 35 | − value: function () { | |
| 36 | − var _setKey = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(key) { | |
| 37 | − return _regeneratorRuntime().wrap(function _callee$(_context) { | |
| 38 | − while (1) switch (_context.prev = _context.next) { | |
| 39 | − case 0: | |
| 40 | − _context.next = 2; | |
| 41 | − return _crypto["default"].importKey("raw", key, { | |
| 42 | − name: "AES-EAX" | |
| 43 | − }, false, ["encrypt, decrypt"]); | |
| 44 | − case 2: | |
| 45 | − this._cipher = _context.sent; | |
| 46 | − case 3: | |
| 47 | − case "end": | |
| 48 | − return _context.stop(); | |
| 49 | − } | |
| 50 | − }, _callee, this); | |
| 51 | − })); | |
| 52 | − function setKey(_x) { | |
| 53 | − return _setKey.apply(this, arguments); | |
| 54 | − } | |
| 55 | − return setKey; | |
| 56 | − }() | |
| 57 | − }, { | |
| 58 | − key: "makeMessage", | |
| 59 | − value: function () { | |
| 60 | − var _makeMessage = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(message) { | |
| 61 | − var ad, encrypted, i, res; | |
| 62 | − return _regeneratorRuntime().wrap(function _callee2$(_context2) { | |
| 63 | − while (1) switch (_context2.prev = _context2.next) { | |
| 64 | − case 0: | |
| 65 | − ad = new Uint8Array([(message.length & 0xff00) >>> 8, message.length & 0xff]); | |
| 66 | − _context2.next = 3; | |
| 67 | − return _crypto["default"].encrypt({ | |
| 68 | − name: "AES-EAX", | |
| 69 | − iv: this._counter, | |
| 70 | − additionalData: ad | |
| 71 | − }, this._cipher, message); | |
| 72 | − case 3: | |
| 73 | − encrypted = _context2.sent; | |
| 74 | − for (i = 0; i < 16 && this._counter[i]++ === 255; i++); | |
| 75 | − res = new Uint8Array(message.length + 2 + 16); | |
| 76 | − res.set(ad); | |
| 77 | − res.set(encrypted, 2); | |
| 78 | − return _context2.abrupt("return", res); | |
| 79 | − case 9: | |
| 80 | − case "end": | |
| 81 | − return _context2.stop(); | |
| 82 | − } | |
| 83 | − }, _callee2, this); | |
| 84 | − })); | |
| 85 | − function makeMessage(_x2) { | |
| 86 | − return _makeMessage.apply(this, arguments); | |
| 87 | − } | |
| 88 | − return makeMessage; | |
| 89 | − }() | |
| 90 | − }, { | |
| 91 | − key: "receiveMessage", | |
| 92 | − value: function () { | |
| 93 | − var _receiveMessage = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(length, encrypted) { | |
| 94 | − var ad, res, i; | |
| 95 | − return _regeneratorRuntime().wrap(function _callee3$(_context3) { | |
| 96 | − while (1) switch (_context3.prev = _context3.next) { | |
| 97 | − case 0: | |
| 98 | − ad = new Uint8Array([(length & 0xff00) >>> 8, length & 0xff]); | |
| 99 | − _context3.next = 3; | |
| 100 | − return _crypto["default"].decrypt({ | |
| 101 | − name: "AES-EAX", | |
| 102 | − iv: this._counter, | |
| 103 | − additionalData: ad | |
| 104 | − }, this._cipher, encrypted); | |
| 105 | − case 3: | |
| 106 | − res = _context3.sent; | |
| 107 | − for (i = 0; i < 16 && this._counter[i]++ === 255; i++); | |
| 108 | − return _context3.abrupt("return", res); | |
| 109 | − case 6: | |
| 110 | − case "end": | |
| 111 | − return _context3.stop(); | |
| 112 | − } | |
| 113 | − }, _callee3, this); | |
| 114 | − })); | |
| 115 | − function receiveMessage(_x3, _x4) { | |
| 116 | − return _receiveMessage.apply(this, arguments); | |
| 117 | − } | |
| 118 | − return receiveMessage; | |
| 119 | − }() | |
| 120 | − }]); | |
| 121 | −}(); | |
| 122 | −var RSAAESAuthenticationState = exports["default"] = /*#__PURE__*/function (_EventTargetMixin) { | |
| 123 | − function RSAAESAuthenticationState(sock, getCredentials) { | |
| 124 | − var _this; | |
| 125 | − _classCallCheck(this, RSAAESAuthenticationState); | |
| 126 | − _this = _callSuper(this, RSAAESAuthenticationState); | |
| 127 | − _this._hasStarted = false; | |
| 128 | − _this._checkSock = null; | |
| 129 | − _this._checkCredentials = null; | |
| 130 | − _this._approveServerResolve = null; | |
| 131 | − _this._sockReject = null; | |
| 132 | − _this._credentialsReject = null; | |
| 133 | − _this._approveServerReject = null; | |
| 134 | − _this._sock = sock; | |
| 135 | − _this._getCredentials = getCredentials; | |
| 136 | − return _this; | |
| 137 | − } | |
| 138 | − _inherits(RSAAESAuthenticationState, _EventTargetMixin); | |
| 139 | − return _createClass(RSAAESAuthenticationState, [{ | |
| 140 | − key: "_waitSockAsync", | |
| 141 | − value: function _waitSockAsync(len) { | |
| 142 | − var _this2 = this; | |
| 143 | − return new Promise(function (resolve, reject) { | |
| 144 | − var hasData = function hasData() { | |
| 145 | − return !_this2._sock.rQwait('RA2', len); | |
| 146 | − }; | |
| 147 | − if (hasData()) { | |
| 148 | − resolve(); | |
| 149 | − } else { | |
| 150 | − _this2._checkSock = function () { | |
| 151 | − if (hasData()) { | |
| 152 | − resolve(); | |
| 153 | − _this2._checkSock = null; | |
| 154 | − _this2._sockReject = null; | |
| 155 | − } | |
| 156 | − }; | |
| 157 | − _this2._sockReject = reject; | |
| 158 | − } | |
| 159 | − }); | |
| 160 | − } | |
| 161 | − }, { | |
| 162 | − key: "_waitApproveKeyAsync", | |
| 163 | − value: function _waitApproveKeyAsync() { | |
| 164 | − var _this3 = this; | |
| 165 | − return new Promise(function (resolve, reject) { | |
| 166 | − _this3._approveServerResolve = resolve; | |
| 167 | − _this3._approveServerReject = reject; | |
| 168 | − }); | |
| 169 | − } | |
| 170 | − }, { | |
| 171 | − key: "_waitCredentialsAsync", | |
| 172 | − value: function _waitCredentialsAsync(subtype) { | |
| 173 | − var _this4 = this; | |
| 174 | − var hasCredentials = function hasCredentials() { | |
| 175 | − if (subtype === 1 && _this4._getCredentials().username !== undefined && _this4._getCredentials().password !== undefined) { | |
| 176 | − return true; | |
| 177 | − } else if (subtype === 2 && _this4._getCredentials().password !== undefined) { | |
| 178 | − return true; | |
| 179 | − } | |
| 180 | − return false; | |
| 181 | − }; | |
| 182 | − return new Promise(function (resolve, reject) { | |
| 183 | − if (hasCredentials()) { | |
| 184 | − resolve(); | |
| 185 | − } else { | |
| 186 | − _this4._checkCredentials = function () { | |
| 187 | − if (hasCredentials()) { | |
| 188 | − resolve(); | |
| 189 | − _this4._checkCredentials = null; | |
| 190 | − _this4._credentialsReject = null; | |
| 191 | − } | |
| 192 | − }; | |
| 193 | − _this4._credentialsReject = reject; | |
| 194 | − } | |
| 195 | − }); | |
| 196 | − } | |
| 197 | − }, { | |
| 198 | − key: "checkInternalEvents", | |
| 199 | − value: function checkInternalEvents() { | |
| 200 | − if (this._checkSock !== null) { | |
| 201 | − this._checkSock(); | |
| 202 | − } | |
| 203 | − if (this._checkCredentials !== null) { | |
| 204 | − this._checkCredentials(); | |
| 205 | − } | |
| 206 | − } | |
| 207 | − }, { | |
| 208 | − key: "approveServer", | |
| 209 | − value: function approveServer() { | |
| 210 | − if (this._approveServerResolve !== null) { | |
| 211 | − this._approveServerResolve(); | |
| 212 | − this._approveServerResolve = null; | |
| 213 | − } | |
| 214 | − } | |
| 215 | − }, { | |
| 216 | − key: "disconnect", | |
| 217 | − value: function disconnect() { | |
| 218 | − if (this._sockReject !== null) { | |
| 219 | − this._sockReject(new Error("disconnect normally")); | |
| 220 | − this._sockReject = null; | |
| 221 | − } | |
| 222 | − if (this._credentialsReject !== null) { | |
| 223 | − this._credentialsReject(new Error("disconnect normally")); | |
| 224 | − this._credentialsReject = null; | |
| 225 | − } | |
| 226 | − if (this._approveServerReject !== null) { | |
| 227 | − this._approveServerReject(new Error("disconnect normally")); | |
| 228 | − this._approveServerReject = null; | |
| 229 | − } | |
| 230 | − } | |
| 231 | − }, { | |
| 232 | − key: "negotiateRA2neAuthAsync", | |
| 233 | − value: function () { | |
| 234 | − var _negotiateRA2neAuthAsync = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4() { | |
| 235 | − var serverKeyLengthBuffer, serverKeyLength, serverKeyBytes, serverN, serverE, serverRSACipher, serverPublickey, approveKey, clientKeyLength, clientKeyBytes, clientRSACipher, clientExportedRSAKey, clientN, clientE, clientPublicKey, clientRandom, clientEncryptedRandom, clientRandomMessage, serverEncryptedRandom, serverRandom, clientSessionKey, serverSessionKey, clientCipher, serverCipher, serverHash, clientHash, serverHashReceived, i, subtype, waitCredentials, username, password, credentials, _i, _i2; | |
| 236 | − return _regeneratorRuntime().wrap(function _callee4$(_context4) { | |
| 237 | − while (1) switch (_context4.prev = _context4.next) { | |
| 238 | − case 0: | |
| 239 | − this._hasStarted = true; | |
| 240 | − // 1: Receive server public key | |
| 241 | − _context4.next = 3; | |
| 242 | − return this._waitSockAsync(4); | |
| 243 | − case 3: | |
| 244 | − serverKeyLengthBuffer = this._sock.rQpeekBytes(4); | |
| 245 | − serverKeyLength = this._sock.rQshift32(); | |
| 246 | − if (!(serverKeyLength < 1024)) { | |
| 247 | − _context4.next = 9; | |
| 248 | − break; | |
| 249 | − } | |
| 250 | − throw new Error("RA2: server public key is too short: " + serverKeyLength); | |
| 251 | − case 9: | |
| 252 | − if (!(serverKeyLength > 8192)) { | |
| 253 | − _context4.next = 11; | |
| 254 | − break; | |
| 255 | − } | |
| 256 | − throw new Error("RA2: server public key is too long: " + serverKeyLength); | |
| 257 | − case 11: | |
| 258 | − serverKeyBytes = Math.ceil(serverKeyLength / 8); | |
| 259 | − _context4.next = 14; | |
| 260 | − return this._waitSockAsync(serverKeyBytes * 2); | |
| 261 | − case 14: | |
| 262 | − serverN = this._sock.rQshiftBytes(serverKeyBytes); | |
| 263 | − serverE = this._sock.rQshiftBytes(serverKeyBytes); | |
| 264 | − _context4.next = 18; | |
| 265 | − return _crypto["default"].importKey("raw", { | |
| 266 | − n: serverN, | |
| 267 | − e: serverE | |
| 268 | − }, { | |
| 269 | − name: "RSA-PKCS1-v1_5" | |
| 270 | − }, false, ["encrypt"]); | |
| 271 | − case 18: | |
| 272 | − serverRSACipher = _context4.sent; | |
| 273 | − serverPublickey = new Uint8Array(4 + serverKeyBytes * 2); | |
| 274 | − serverPublickey.set(serverKeyLengthBuffer); | |
| 275 | − serverPublickey.set(serverN, 4); | |
| 276 | − serverPublickey.set(serverE, 4 + serverKeyBytes); | |
| 277 | − | |
| 278 | − // verify server public key | |
| 279 | − approveKey = this._waitApproveKeyAsync(); | |
| 280 | − this.dispatchEvent(new CustomEvent("serververification", { | |
| 281 | − detail: { | |
| 282 | − type: "RSA", | |
| 283 | − publickey: serverPublickey | |
| 284 | − } | |
| 285 | − })); | |
| 286 | − _context4.next = 27; | |
| 287 | − return approveKey; | |
| 288 | − case 27: | |
| 289 | − // 2: Send client public key | |
| 290 | − clientKeyLength = 2048; | |
| 291 | − clientKeyBytes = Math.ceil(clientKeyLength / 8); | |
| 292 | − _context4.next = 31; | |
| 293 | − return _crypto["default"].generateKey({ | |
| 294 | − name: "RSA-PKCS1-v1_5", | |
| 295 | − modulusLength: clientKeyLength, | |
| 296 | − publicExponent: new Uint8Array([1, 0, 1]) | |
| 297 | − }, true, ["encrypt"]); | |
| 298 | − case 31: | |
| 299 | − clientRSACipher = _context4.sent.privateKey; | |
| 300 | − _context4.next = 34; | |
| 301 | − return _crypto["default"].exportKey("raw", clientRSACipher); | |
| 302 | − case 34: | |
| 303 | − clientExportedRSAKey = _context4.sent; | |
| 304 | − clientN = clientExportedRSAKey.n; | |
| 305 | − clientE = clientExportedRSAKey.e; | |
| 306 | − clientPublicKey = new Uint8Array(4 + clientKeyBytes * 2); | |
| 307 | − clientPublicKey[0] = (clientKeyLength & 0xff000000) >>> 24; | |
| 308 | − clientPublicKey[1] = (clientKeyLength & 0xff0000) >>> 16; | |
| 309 | − clientPublicKey[2] = (clientKeyLength & 0xff00) >>> 8; | |
| 310 | − clientPublicKey[3] = clientKeyLength & 0xff; | |
| 311 | − clientPublicKey.set(clientN, 4); | |
| 312 | − clientPublicKey.set(clientE, 4 + clientKeyBytes); | |
| 313 | − this._sock.sQpushBytes(clientPublicKey); | |
| 314 | − this._sock.flush(); | |
| 315 | − | |
| 316 | − // 3: Send client random | |
| 317 | − clientRandom = new Uint8Array(16); | |
| 318 | − window.crypto.getRandomValues(clientRandom); | |
| 319 | − _context4.next = 50; | |
| 320 | − return _crypto["default"].encrypt({ | |
| 321 | − name: "RSA-PKCS1-v1_5" | |
| 322 | − }, serverRSACipher, clientRandom); | |
| 323 | − case 50: | |
| 324 | − clientEncryptedRandom = _context4.sent; | |
| 325 | − clientRandomMessage = new Uint8Array(2 + serverKeyBytes); | |
| 326 | − clientRandomMessage[0] = (serverKeyBytes & 0xff00) >>> 8; | |
| 327 | − clientRandomMessage[1] = serverKeyBytes & 0xff; | |
| 328 | − clientRandomMessage.set(clientEncryptedRandom, 2); | |
| 329 | − this._sock.sQpushBytes(clientRandomMessage); | |
| 330 | − this._sock.flush(); | |
| 331 | − | |
| 332 | − // 4: Receive server random | |
| 333 | − _context4.next = 59; | |
| 334 | − return this._waitSockAsync(2); | |
| 335 | − case 59: | |
| 336 | − if (!(this._sock.rQshift16() !== clientKeyBytes)) { | |
| 337 | − _context4.next = 61; | |
| 338 | − break; | |
| 339 | − } | |
| 340 | − throw new Error("RA2: wrong encrypted message length"); | |
| 341 | − case 61: | |
| 342 | − serverEncryptedRandom = this._sock.rQshiftBytes(clientKeyBytes); | |
| 343 | − _context4.next = 64; | |
| 344 | − return _crypto["default"].decrypt({ | |
| 345 | − name: "RSA-PKCS1-v1_5" | |
| 346 | − }, clientRSACipher, serverEncryptedRandom); | |
| 347 | − case 64: | |
| 348 | − serverRandom = _context4.sent; | |
| 349 | − if (!(serverRandom === null || serverRandom.length !== 16)) { | |
| 350 | − _context4.next = 67; | |
| 351 | − break; | |
| 352 | − } | |
| 353 | − throw new Error("RA2: corrupted server encrypted random"); | |
| 354 | − case 67: | |
| 355 | − // 5: Compute session keys and set ciphers | |
| 356 | − clientSessionKey = new Uint8Array(32); | |
| 357 | − serverSessionKey = new Uint8Array(32); | |
| 358 | − clientSessionKey.set(serverRandom); | |
| 359 | − clientSessionKey.set(clientRandom, 16); | |
| 360 | − serverSessionKey.set(clientRandom); | |
| 361 | − serverSessionKey.set(serverRandom, 16); | |
| 362 | − _context4.next = 75; | |
| 363 | − return window.crypto.subtle.digest("SHA-1", clientSessionKey); | |
| 364 | − case 75: | |
| 365 | − clientSessionKey = _context4.sent; | |
| 366 | − clientSessionKey = new Uint8Array(clientSessionKey).slice(0, 16); | |
| 367 | − _context4.next = 79; | |
| 368 | − return window.crypto.subtle.digest("SHA-1", serverSessionKey); | |
| 369 | − case 79: | |
| 370 | − serverSessionKey = _context4.sent; | |
| 371 | − serverSessionKey = new Uint8Array(serverSessionKey).slice(0, 16); | |
| 372 | − clientCipher = new RA2Cipher(); | |
| 373 | − _context4.next = 84; | |
| 374 | − return clientCipher.setKey(clientSessionKey); | |
| 375 | − case 84: | |
| 376 | − serverCipher = new RA2Cipher(); | |
| 377 | − _context4.next = 87; | |
| 378 | − return serverCipher.setKey(serverSessionKey); | |
| 379 | − case 87: | |
| 380 | − // 6: Compute and exchange hashes | |
| 381 | − serverHash = new Uint8Array(8 + serverKeyBytes * 2 + clientKeyBytes * 2); | |
| 382 | − clientHash = new Uint8Array(8 + serverKeyBytes * 2 + clientKeyBytes * 2); | |
| 383 | − serverHash.set(serverPublickey); | |
| 384 | − serverHash.set(clientPublicKey, 4 + serverKeyBytes * 2); | |
| 385 | − clientHash.set(clientPublicKey); | |
| 386 | − clientHash.set(serverPublickey, 4 + clientKeyBytes * 2); | |
| 387 | − _context4.next = 95; | |
| 388 | − return window.crypto.subtle.digest("SHA-1", serverHash); | |
| 389 | − case 95: | |
| 390 | − serverHash = _context4.sent; | |
| 391 | − _context4.next = 98; | |
| 392 | − return window.crypto.subtle.digest("SHA-1", clientHash); | |
| 393 | − case 98: | |
| 394 | − clientHash = _context4.sent; | |
| 395 | − serverHash = new Uint8Array(serverHash); | |
| 396 | − clientHash = new Uint8Array(clientHash); | |
| 397 | − _context4.t0 = this._sock; | |
| 398 | − _context4.next = 104; | |
| 399 | − return clientCipher.makeMessage(clientHash); | |
| 400 | − case 104: | |
| 401 | − _context4.t1 = _context4.sent; | |
| 402 | − _context4.t0.sQpushBytes.call(_context4.t0, _context4.t1); | |
| 403 | − this._sock.flush(); | |
| 404 | − _context4.next = 109; | |
| 405 | − return this._waitSockAsync(2 + 20 + 16); | |
| 406 | − case 109: | |
| 407 | − if (!(this._sock.rQshift16() !== 20)) { | |
| 408 | − _context4.next = 111; | |
| 409 | − break; | |
| 410 | − } | |
| 411 | − throw new Error("RA2: wrong server hash"); | |
| 412 | − case 111: | |
| 413 | − _context4.next = 113; | |
| 414 | − return serverCipher.receiveMessage(20, this._sock.rQshiftBytes(20 + 16)); | |
| 415 | − case 113: | |
| 416 | − serverHashReceived = _context4.sent; | |
| 417 | − if (!(serverHashReceived === null)) { | |
| 418 | − _context4.next = 116; | |
| 419 | − break; | |
| 420 | − } | |
| 421 | − throw new Error("RA2: failed to authenticate the message"); | |
| 422 | − case 116: | |
| 423 | − i = 0; | |
| 424 | − case 117: | |
| 425 | − if (!(i < 20)) { | |
| 426 | − _context4.next = 123; | |
| 427 | − break; | |
| 428 | − } | |
| 429 | − if (!(serverHashReceived[i] !== serverHash[i])) { | |
| 430 | − _context4.next = 120; | |
| 431 | − break; | |
| 432 | − } | |
| 433 | − throw new Error("RA2: wrong server hash"); | |
| 434 | − case 120: | |
| 435 | − i++; | |
| 436 | − _context4.next = 117; | |
| 437 | − break; | |
| 438 | − case 123: | |
| 439 | − _context4.next = 125; | |
| 440 | − return this._waitSockAsync(2 + 1 + 16); | |
| 441 | − case 125: | |
| 442 | − if (!(this._sock.rQshift16() !== 1)) { | |
| 443 | − _context4.next = 127; | |
| 444 | − break; | |
| 445 | − } | |
| 446 | − throw new Error("RA2: wrong subtype"); | |
| 447 | − case 127: | |
| 448 | − _context4.next = 129; | |
| 449 | − return serverCipher.receiveMessage(1, this._sock.rQshiftBytes(1 + 16)); | |
| 450 | − case 129: | |
| 451 | − subtype = _context4.sent; | |
| 452 | − if (!(subtype === null)) { | |
| 453 | − _context4.next = 132; | |
| 454 | − break; | |
| 455 | − } | |
| 456 | − throw new Error("RA2: failed to authenticate the message"); | |
| 457 | − case 132: | |
| 458 | − subtype = subtype[0]; | |
| 459 | − waitCredentials = this._waitCredentialsAsync(subtype); | |
| 460 | − if (!(subtype === 1)) { | |
| 461 | − _context4.next = 138; | |
| 462 | − break; | |
| 463 | − } | |
| 464 | − if (this._getCredentials().username === undefined || this._getCredentials().password === undefined) { | |
| 465 | − this.dispatchEvent(new CustomEvent("credentialsrequired", { | |
| 466 | − detail: { | |
| 467 | − types: ["username", "password"] | |
| 468 | − } | |
| 469 | − })); | |
| 470 | − } | |
| 471 | − _context4.next = 143; | |
| 472 | − break; | |
| 473 | − case 138: | |
| 474 | − if (!(subtype === 2)) { | |
| 475 | − _context4.next = 142; | |
| 476 | − break; | |
| 477 | − } | |
| 478 | − if (this._getCredentials().password === undefined) { | |
| 479 | − this.dispatchEvent(new CustomEvent("credentialsrequired", { | |
| 480 | − detail: { | |
| 481 | − types: ["password"] | |
| 482 | − } | |
| 483 | − })); | |
| 484 | − } | |
| 485 | − _context4.next = 143; | |
| 486 | − break; | |
| 487 | − case 142: | |
| 488 | − throw new Error("RA2: wrong subtype"); | |
| 489 | − case 143: | |
| 490 | − _context4.next = 145; | |
| 491 | − return waitCredentials; | |
| 492 | − case 145: | |
| 493 | − if (subtype === 1) { | |
| 494 | − username = (0, _strings.encodeUTF8)(this._getCredentials().username).slice(0, 255); | |
| 495 | − } else { | |
| 496 | − username = ""; | |
| 497 | − } | |
| 498 | − password = (0, _strings.encodeUTF8)(this._getCredentials().password).slice(0, 255); | |
| 499 | − credentials = new Uint8Array(username.length + password.length + 2); | |
| 500 | − credentials[0] = username.length; | |
| 501 | − credentials[username.length + 1] = password.length; | |
| 502 | − for (_i = 0; _i < username.length; _i++) { | |
| 503 | − credentials[_i + 1] = username.charCodeAt(_i); | |
| 504 | − } | |
| 505 | − for (_i2 = 0; _i2 < password.length; _i2++) { | |
| 506 | − credentials[username.length + 2 + _i2] = password.charCodeAt(_i2); | |
| 507 | − } | |
| 508 | − _context4.t2 = this._sock; | |
| 509 | − _context4.next = 155; | |
| 510 | − return clientCipher.makeMessage(credentials); | |
| 511 | − case 155: | |
| 512 | − _context4.t3 = _context4.sent; | |
| 513 | − _context4.t2.sQpushBytes.call(_context4.t2, _context4.t3); | |
| 514 | − this._sock.flush(); | |
| 515 | − case 158: | |
| 516 | − case "end": | |
| 517 | − return _context4.stop(); | |
| 518 | − } | |
| 519 | − }, _callee4, this); | |
| 520 | − })); | |
| 521 | − function negotiateRA2neAuthAsync() { | |
| 522 | − return _negotiateRA2neAuthAsync.apply(this, arguments); | |
| 523 | − } | |
| 524 | − return negotiateRA2neAuthAsync; | |
| 525 | − }() | |
| 526 | − }, { | |
| 527 | − key: "hasStarted", | |
| 528 | − get: function get() { | |
| 529 | − return this._hasStarted; | |
| 530 | − }, | |
| 531 | − set: function set(s) { | |
| 532 | − this._hasStarted = s; | |
| 533 | − } | |
| 534 | − }]); | |
| 535 | −}(_eventtarget["default"]); | |
| \ No newline at end of file | ||
deleted
public/vendor/novnc/rfb.js
+0 −104
@@ -1,3398 +0,0 @@ | ||
| 1 | −"use strict"; | |
| 2 | − | |
| 3 | −function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } | |
| 4 | −Object.defineProperty(exports, "__esModule", { | |
| 5 | − value: true | |
| 6 | −}); | |
| 7 | −exports["default"] = void 0; | |
| 8 | −var _int = require("./util/int.js"); | |
| 9 | −var Log = _interopRequireWildcard(require("./util/logging.js")); | |
| 10 | −var _strings = require("./util/strings.js"); | |
| 11 | −var _browser = require("./util/browser.js"); | |
| 12 | −var _element = require("./util/element.js"); | |
| 13 | −var _events = require("./util/events.js"); | |
| 14 | −var _eventtarget = _interopRequireDefault(require("./util/eventtarget.js")); | |
| 15 | −var _display = _interopRequireDefault(require("./display.js")); | |
| 16 | −var _inflator = _interopRequireDefault(require("./inflator.js")); | |
| 17 | −var _deflator = _interopRequireDefault(require("./deflator.js")); | |
| 18 | −var _keyboard = _interopRequireDefault(require("./input/keyboard.js")); | |
| 19 | −var _gesturehandler = _interopRequireDefault(require("./input/gesturehandler.js")); | |
| 20 | −var _cursor = _interopRequireDefault(require("./util/cursor.js")); | |
| 21 | −var _websock = _interopRequireDefault(require("./websock.js")); | |
| 22 | −var _keysym = _interopRequireDefault(require("./input/keysym.js")); | |
| 23 | −var _xtscancodes = _interopRequireDefault(require("./input/xtscancodes.js")); | |
| 24 | −var _encodings = require("./encodings.js"); | |
| 25 | −var _ra = _interopRequireDefault(require("./ra2.js")); | |
| 26 | −var _crypto = _interopRequireDefault(require("./crypto/crypto.js")); | |
| 27 | −var _raw = _interopRequireDefault(require("./decoders/raw.js")); | |
| 28 | −var _copyrect = _interopRequireDefault(require("./decoders/copyrect.js")); | |
| 29 | −var _rre = _interopRequireDefault(require("./decoders/rre.js")); | |
| 30 | −var _hextile = _interopRequireDefault(require("./decoders/hextile.js")); | |
| 31 | −var _zlib = _interopRequireDefault(require("./decoders/zlib.js")); | |
| 32 | −var _tight = _interopRequireDefault(require("./decoders/tight.js")); | |
| 33 | −var _tightpng = _interopRequireDefault(require("./decoders/tightpng.js")); | |
| 34 | −var _zrle = _interopRequireDefault(require("./decoders/zrle.js")); | |
| 35 | −var _jpeg = _interopRequireDefault(require("./decoders/jpeg.js")); | |
| 36 | −var _h = _interopRequireDefault(require("./decoders/h264.js")); | |
| 37 | −function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } | |
| 38 | −function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } | |
| 39 | −function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } | |
| 40 | −function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } | |
| 41 | −function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } | |
| 42 | −function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } | |
| 43 | −function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } | |
| 44 | −function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } | |
| 45 | −function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } | |
| 46 | −function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } | |
| 47 | −function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } | |
| 48 | −function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } | |
| 49 | −function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } | |
| 50 | −function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } | |
| 51 | −function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } | |
| 52 | −function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } | |
| 53 | −function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } | |
| 54 | −function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } | |
| 55 | −function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); } | |
| 56 | −function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); } | |
| 57 | −function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; } | |
| 58 | −function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } | |
| 59 | −function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); } | |
| 60 | −function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function"); t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); } | |
| 61 | −function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); } /* | |
| 62 | − * noVNC: HTML5 VNC client | |
| 63 | − * Copyright (C) 2020 The noVNC authors | |
| 64 | − * Licensed under MPL 2.0 (see LICENSE.txt) | |
| 65 | − * | |
| 66 | − * See README.md for usage and integration instructions. | |
| 67 | − * | |
| 68 | − */ | |
| 69 | −// How many seconds to wait for a disconnect to finish | |
| 70 | −var DISCONNECT_TIMEOUT = 3; | |
| 71 | −var DEFAULT_BACKGROUND = 'rgb(40, 40, 40)'; | |
| 72 | − | |
| 73 | −// Minimum wait (ms) between two mouse moves | |
| 74 | −var MOUSE_MOVE_DELAY = 17; | |
| 75 | − | |
| 76 | −// Wheel thresholds | |
| 77 | −var WHEEL_STEP = 50; // Pixels needed for one step | |
| 78 | −var WHEEL_LINE_HEIGHT = 19; // Assumed pixels for one line step | |
| 79 | − | |
| 80 | −// Gesture thresholds | |
| 81 | −var GESTURE_ZOOMSENS = 75; | |
| 82 | −var GESTURE_SCRLSENS = 50; | |
| 83 | −var DOUBLE_TAP_TIMEOUT = 1000; | |
| 84 | −var DOUBLE_TAP_THRESHOLD = 50; | |
| 85 | − | |
| 86 | −// Security types | |
| 87 | −var securityTypeNone = 1; | |
| 88 | −var securityTypeVNCAuth = 2; | |
| 89 | −var securityTypeRA2ne = 6; | |
| 90 | −var securityTypeTight = 16; | |
| 91 | −var securityTypeVeNCrypt = 19; | |
| 92 | −var securityTypeXVP = 22; | |
| 93 | −var securityTypeARD = 30; | |
| 94 | −var securityTypeMSLogonII = 113; | |
| 95 | − | |
| 96 | −// Special Tight security types | |
| 97 | −var securityTypeUnixLogon = 129; | |
| 98 | − | |
| 99 | −// VeNCrypt security types | |
| 100 | −var securityTypePlain = 256; | |
| 101 | − | |
| 102 | −// Extended clipboard pseudo-encoding formats | |
| 103 | −var extendedClipboardFormatText = 1; | |
| 104 | −/*eslint-disable no-unused-vars */ | |
Diff truncated — file too large.